From cfdb1044fb18782cd16f9ba22b5264f77031b842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Sat, 28 Feb 2026 14:41:37 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[approvals]=20=EA=B8=B0=EC=95=88=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1/=EC=88=98=EC=A0=95=20=EA=B2=B0=EC=9E=AC?= =?UTF-8?q?=EC=84=A0=EC=9D=84=20=EB=AA=A8=EB=8B=AC=EB=A1=9C=20=EC=A0=84?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 2열 레이아웃(양식 50% + 결재선 50%)을 1열 풀와이드로 변경 - 결재선 편집기를 모달로 이동, 메인 화면에 요약 바만 표시 - ESC 키로 모달 닫기 지원 - edit 페이지 로드 시 기존 결재선 요약 즉시 표시 --- resources/views/approvals/create.blade.php | 186 +++++++++++++------ resources/views/approvals/edit.blade.php | 198 ++++++++++++++------- 2 files changed, 268 insertions(+), 116 deletions(-) diff --git a/resources/views/approvals/create.blade.php b/resources/views/approvals/create.blade.php index dbcb28b8..2797f231 100644 --- a/resources/views/approvals/create.blade.php +++ b/resources/views/approvals/create.blade.php @@ -10,79 +10,109 @@ -
- {{-- 좌측: 양식 --}} -
-
-

문서 내용

+
+
+

문서 내용

- {{-- 양식 선택 --}} -
- - -
+ {{-- 양식 선택 --}} +
+ + +
- {{-- 제목 --}} -
- - -
+ {{-- 제목 --}} +
+ + +
- {{-- 긴급 여부 --}} -
- + + +
- {{-- 본문 --}} -
- - - + {{-- 결재선 요약 바 --}} +
+
+ + +
+
+ 결재선이 설정되지 않았습니다.
-
- - {{-- 우측: 결재선 --}} -
- @php - $defaultLine = collect($lines)->firstWhere('is_default', true); - @endphp - @include('approvals.partials._approval-line-editor', [ - 'lines' => $lines, - 'initialSteps' => $defaultLine?->steps ?? [], - 'selectedLineId' => $defaultLine?->id ?? '', - ]) {{-- 액션 버튼 --}} -
+
+ + {{-- 결재선 모달 --}} + @endsection @push('styles') @@ -152,6 +182,52 @@ function getBodyContent() { return document.getElementById('body').value; } +function openApprovalLineModal() { + document.getElementById('approval-line-modal').style.display = ''; + document.body.style.overflow = 'hidden'; +} + +function closeApprovalLineModal() { + document.getElementById('approval-line-modal').style.display = 'none'; + document.body.style.overflow = ''; + updateApprovalLineSummary(); +} + +function updateApprovalLineSummary() { + const editorEl = document.getElementById('approval-line-editor'); + if (!editorEl || !editorEl._x_dataStack) return; + + const steps = editorEl._x_dataStack[0].steps; + const summaryEl = document.getElementById('approval-line-summary'); + + if (!steps || steps.length === 0) { + summaryEl.innerHTML = '결재선이 설정되지 않았습니다.'; + return; + } + + const typeLabels = { approval: '결재', agreement: '합의', reference: '참조' }; + const parts = steps.map(s => { + const label = typeLabels[s.step_type] || s.step_type; + return '' + s.user_name + ' (' + label + ')'; + }); + + summaryEl.innerHTML = '
' + + parts.join('') + '
'; +} + +document.addEventListener('keydown', function(e) { + if (e.key === 'Escape') { + const modal = document.getElementById('approval-line-modal'); + if (modal && modal.style.display !== 'none') { + closeApprovalLineModal(); + } + } +}); + +document.addEventListener('DOMContentLoaded', function() { + setTimeout(updateApprovalLineSummary, 200); +}); + async function saveApproval(action) { const title = document.getElementById('title').value.trim(); if (!title) { diff --git a/resources/views/approvals/edit.blade.php b/resources/views/approvals/edit.blade.php index ec6d303b..a3eb0d1a 100644 --- a/resources/views/approvals/edit.blade.php +++ b/resources/views/approvals/edit.blade.php @@ -19,7 +19,7 @@
@if($approval->status === 'rejected') -
+
반려됨
@@ -35,87 +35,118 @@
@endif -
- {{-- 좌측: 양식 --}} -
-
-

문서 내용

+
+
+

문서 내용

-
- - -
+
+ + +
-
- - -
+
+ + +
-
- + + +
-
- - - + {{-- 결재선 요약 바 --}} +
+
+ + +
+
+ 결재선이 설정되지 않았습니다.
-
- {{-- 우측: 결재선 --}} -
- @php - $initialSteps = $approval->steps->map(fn($s) => [ - 'user_id' => $s->approver_id, - 'user_name' => $s->approver_name ?? ($s->approver?->name ?? ''), - 'department' => $s->approver_department ?? '', - 'position' => $s->approver_position ?? '', - 'step_type' => $s->step_type, - ])->toArray(); - @endphp - @include('approvals.partials._approval-line-editor', [ - 'lines' => $lines, - 'initialSteps' => $initialSteps, - 'selectedLineId' => $approval->line_id ?? '', - ]) - -
+ {{-- 액션 버튼 --}} +
@if($approval->isDeletable()) @endif
+ + {{-- 결재선 모달 --}} + @endsection @push('styles') @@ -185,13 +216,58 @@ function getBodyContent() { return document.getElementById('body').value; } -// 기존 HTML body 자동 감지 → 편집기 자동 활성화 +function openApprovalLineModal() { + document.getElementById('approval-line-modal').style.display = ''; + document.body.style.overflow = 'hidden'; +} + +function closeApprovalLineModal() { + document.getElementById('approval-line-modal').style.display = 'none'; + document.body.style.overflow = ''; + updateApprovalLineSummary(); +} + +function updateApprovalLineSummary() { + const editorEl = document.getElementById('approval-line-editor'); + if (!editorEl || !editorEl._x_dataStack) return; + + const steps = editorEl._x_dataStack[0].steps; + const summaryEl = document.getElementById('approval-line-summary'); + + if (!steps || steps.length === 0) { + summaryEl.innerHTML = '결재선이 설정되지 않았습니다.'; + return; + } + + const typeLabels = { approval: '결재', agreement: '합의', reference: '참조' }; + const parts = steps.map(s => { + const label = typeLabels[s.step_type] || s.step_type; + return '' + s.user_name + ' (' + label + ')'; + }); + + summaryEl.innerHTML = '
' + + parts.join('') + '
'; +} + +document.addEventListener('keydown', function(e) { + if (e.key === 'Escape') { + const modal = document.getElementById('approval-line-modal'); + if (modal && modal.style.display !== 'none') { + closeApprovalLineModal(); + } + } +}); + +// 기존 HTML body 자동 감지 → 편집기 자동 활성화 + 결재선 요약 초기화 document.addEventListener('DOMContentLoaded', function () { const existingBody = document.getElementById('body').value; if (/<[a-z][\s\S]*>/i.test(existingBody)) { document.getElementById('useEditor').checked = true; toggleEditor(); } + + // Alpine 초기화 후 기존 결재선 요약 표시 + setTimeout(updateApprovalLineSummary, 200); }); async function updateApproval(action) {