- 보류/해제: 현재 결재자가 문서를 보류하고 해제 - 전결: 이후 모든 결재를 건너뛰고 최종 승인 - 회수 강화: 회수 사유 입력, 첫 결재자 미처리 시에만 허용 - 복사 재기안: 완료/반려/회수 문서를 복사하여 새 draft 생성 - 참조 열람 추적: 미열람/열람 필터, mark-read API - ApprovalDelegation 모델 생성 (Phase 3 위임 대결 준비) - 뱃지 카운트에 reference_unread 추가
67 lines
3.9 KiB
PHP
67 lines
3.9 KiB
PHP
{{-- 결재 진행 단계 시각화 --}}
|
|
@props(['steps' => [], 'currentStep' => 0])
|
|
|
|
<div class="flex items-center gap-1 overflow-x-auto py-4">
|
|
@foreach($steps as $index => $step)
|
|
@php
|
|
$isApprover = in_array($step['step_type'] ?? 'approval', ['approval', 'agreement']);
|
|
$isPreDecided = ($step['approval_type'] ?? 'normal') === 'pre_decided';
|
|
$statusConfig = match($step['status'] ?? 'pending') {
|
|
'approved' => $isPreDecided
|
|
? ['icon' => '⚡', 'bg' => 'bg-indigo-500', 'border' => 'border-indigo-500', 'text' => 'text-indigo-700']
|
|
: ['icon' => '✓', 'bg' => 'bg-green-500', 'border' => 'border-green-500', 'text' => 'text-green-700'],
|
|
'rejected' => ['icon' => '✗', 'bg' => 'bg-red-500', 'border' => 'border-red-500', 'text' => 'text-red-700'],
|
|
'on_hold' => ['icon' => '⏸', 'bg' => 'bg-amber-500', 'border' => 'border-amber-500', 'text' => 'text-amber-700'],
|
|
'skipped' => ['icon' => '—', 'bg' => 'bg-gray-400', 'border' => 'border-gray-400', 'text' => 'text-gray-500'],
|
|
default => ['icon' => ($step['step_order'] ?? $index + 1), 'bg' => 'bg-white', 'border' => 'border-gray-300', 'text' => 'text-gray-500'],
|
|
};
|
|
$isCurrent = $isApprover && ($step['status'] ?? 'pending') === 'pending' && ($step['step_order'] ?? 0) == $currentStep;
|
|
if ($isCurrent) {
|
|
$statusConfig['bg'] = 'bg-blue-500';
|
|
$statusConfig['border'] = 'border-blue-500';
|
|
$statusConfig['text'] = 'text-blue-700';
|
|
$statusConfig['icon'] = ($step['step_order'] ?? $index + 1);
|
|
}
|
|
$typeLabel = match($step['step_type'] ?? 'approval') {
|
|
'approval' => '결재',
|
|
'agreement' => '합의',
|
|
'reference' => '참조',
|
|
default => '',
|
|
};
|
|
$isFilledStatus = in_array($step['status'] ?? 'pending', ['approved', 'rejected', 'skipped', 'on_hold']) || $isCurrent;
|
|
@endphp
|
|
|
|
@if($index > 0)
|
|
<div class="shrink-0" style="width: 24px; height: 2px; background-color: {{ in_array($step['status'] ?? 'pending', ['approved']) ? '#22c55e' : '#d1d5db' }};"></div>
|
|
@endif
|
|
|
|
<div class="flex flex-col items-center shrink-0" style="min-width: 70px;">
|
|
{{-- 원형 아이콘 --}}
|
|
<div class="flex items-center justify-center rounded-full border-2 {{ $statusConfig['border'] }} {{ $isFilledStatus ? $statusConfig['bg'] . ' text-white' : $statusConfig['bg'] }}"
|
|
style="width: 36px; height: 36px; font-size: 14px; font-weight: 600;">
|
|
{!! $statusConfig['icon'] !!}
|
|
</div>
|
|
{{-- 결재자명 --}}
|
|
<span class="text-xs mt-1 {{ $statusConfig['text'] }} font-medium whitespace-nowrap {{ ($step['status'] ?? '') === 'skipped' ? 'line-through' : '' }}">
|
|
{{ $step['approver_name'] ?? ($step['approver']['name'] ?? '미지정') }}
|
|
</span>
|
|
{{-- 유형 + 직급 --}}
|
|
<span class="text-xs text-gray-400 whitespace-nowrap">
|
|
{{ $typeLabel }}{{ !empty($step['approver_position']) ? ' · ' . $step['approver_position'] : '' }}
|
|
@if($isPreDecided && ($step['status'] ?? '') === 'approved')
|
|
<span class="text-indigo-500 font-medium">전결</span>
|
|
@endif
|
|
@if(($step['status'] ?? '') === 'on_hold')
|
|
<span class="text-amber-500 font-medium">보류</span>
|
|
@endif
|
|
</span>
|
|
{{-- 처리일시 --}}
|
|
@if(!empty($step['acted_at']))
|
|
<span class="text-xs text-gray-400 whitespace-nowrap">
|
|
{{ \Carbon\Carbon::parse($step['acted_at'])->format('m/d H:i') }}
|
|
</span>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|