[CLAUDE] FE: PE che do tap trung duyet phieu (overlay truot phai, an menu+list) + responsive laptop nho
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m40s

Bam phieu -> focus overlay (fixed inset-0 z-50) truot tu phai, che menu+TopBar+list rail; phieu full-width tu cuon + panel duyet ben canh (stack xuong duoi tren man nho). Thu gon/Esc/backdrop HOAC Duyet (chi forward-approve; Tra lai/Tu choi giu overlay) -> dong ve danh sach. List state = panel giua mx-auto max-w-5xl, giu cay 4 tang + PeUrgentChips + search/filter/SLA. Responsive lg-pivot (flex-col stack <lg, flex-row >=lg), compact laptop nho, KHONG dong cham man hinh to (anh: 'man to OK roi'). PeWorkflowPanel +onApproved (wasReject byte-mirror isReject). 2 app SHA256-identical. a11y role=dialog/Esc/focus-trap/scroll-lock/reduced-motion. FE-only, 0 BE, 0 migration. Build PASS x2. Note: backend down luc design -> live authed verify sau deploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-06-19 13:28:26 +07:00
parent 8e68ed1892
commit 398b01d0a6
4 changed files with 402 additions and 90 deletions

View File

@ -27,10 +27,15 @@ import { PeApprovalsSection, PeHistorySection } from './PeDetailTabs'
export function PeWorkflowPanel({
evaluation,
readOnly = false,
onApproved,
}: {
evaluation: PeDetailBundle
/** true = ẩn Chuyển tiếp + Dialog transition (dùng cho Danh sách, không dùng Duyệt). */
readOnly?: boolean
/** S78 — gọi sau khi DUYỆT (forward approve) thành công, để caller đóng focus
* overlay về danh sách (anh: "chọn duyệt thì nó đóng lại như ban đầu").
* KHÔNG gọi khi Trả lại / Từ chối (caller giữ overlay để xem kết quả). */
onApproved?: () => void
}) {
const [target, setTarget] = useState<number | null>(null)
const [comment, setComment] = useState('')
@ -158,6 +163,11 @@ export function PeWorkflowPanel({
qc.invalidateQueries({ queryKey: ['pe-detail', evaluation.id] })
qc.invalidateQueries({ queryKey: ['pe-list'] })
qc.invalidateQueries({ queryKey: ['pe-dept-approvals', evaluation.id] })
// S78 — chỉ DUYỆT (forward approve) mới auto-đóng focus overlay. Trả lại /
// Từ chối giữ overlay (mirror isReject/isSendBack trong mutationFn).
const wasReject = target === PurchaseEvaluationPhase.TuChoi
|| (target === PurchaseEvaluationPhase.DangSoanThao && evaluation.phase !== PurchaseEvaluationPhase.DangSoanThao)
|| (target === PurchaseEvaluationPhase.TraLai && evaluation.phase !== PurchaseEvaluationPhase.TraLai)
setTarget(null)
setComment('')
setReturnMode(WorkflowReturnMode.Drafter)
@ -165,6 +175,7 @@ export function PeWorkflowPanel({
setSkipToFinalApprover(false)
setFinalizeByCcm(false)
setApprovedPriceSource(null)
if (!wasReject) onApproved?.()
},
onError: e => toast.error(getErrorMessage(e)),
})