[CLAUDE] Contract: KHKK UAT S175 dot-F — gom nut thao tac + hang muc du an + loc nhom (0-mig)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 6m11s

Anh review truc tiep tren prod, khoanh do tung cho. Land tron cum:

=== 1. GOM NUT THAO TAC (anh: "Bo het di" + "phia duoi them cac nut thao tac"
       + "cho menu dang duyet -> Duyet/Tra lai vay thoi") ===
· THANH NUT DAY moi o `KhkkDetailContent` (sticky bottom-0, khuon PE workspace):
  [Xoa phieu] · dong "Cac thay doi da tu dong luu" · [Luu & Gui duyet ->]
· Panel 3 GO "Gui duyet" + "Xoa phieu" => nay CHI con **Duyet / Tra lai**.
· GO nut "+ Lap ke hoach" (header) · nut "Sua" (muc 1) · dai banner "Dang xem ke hoach".
🔴 THU TU CO CHU DICH: KHONG go "Gui duyet" o panel 3 TRUOC khi thanh day co mat — go truoc
  la nguoi soan mat duong trinh duyet, phieu ket o Nhap. Vi vay ca cum di CHUNG 1 commit.
🔴 Thanh day chi om nhanh **Submit** — nhanh Approve/Return (o-tich level-finalize + upload
  file sau transition) O LAI panel 3. Nhan ban nhanh do sang day la de su-that thu hai cho
  duong DUYET.
🔸 KHONG lam nut "Luu" roi: moi o o man nay luu NGAY khi roi o. Them nut khong lam gi la
  hua hao — noi thang bang dong chu ben canh thay vi ve nut gia.
🔸 Giu lai dung 1 dong nho "Ve form tao" — bo han thi mo 1 phieu la ket, khong co duong lui.
· `onDeleted` noi vao ca 3 host (List / Create / Detail) de xoa xong khong dung o phieu ma.

=== 2. HANG MUC CUA DU AN (anh: "hang muc cua Du an -. Duyet NCC ay") ===
🔴 Lead bay NHAM o luot truoc: bay `line.tenHangMuc` = danh-muc **SP-002** (86 dong, dung
  phan loai HOP DONG). Anh muon **hang muc CONG VIEC cua du an** tu phieu Duyet NCC
  (`PE.WorkItemId`). Hai thu trung ten tieng Viet nhung KHAC TRUC — tron la chi sai goi thau.
· BE: `ContractSigningPlanDetailDto` +`PeWorkItemName`; handler join `WorkItems` (loose-Guid
  Mig 49, KHONG FK vat ly => join tay null-safe).
· FE: o "Hang muc (du an)" doc `plan.peWorkItemName`; go het khoi liet-ke SP-002 khoi muc 1.

=== 3. MUC 2 RUT VE "HANG MUC + GIA -> TONG" ===
Anh: "Cho nay doi lai la hang muc la dc roi, chon hang muc tien -> thanh tong con lai bo het"
 + "cho chon nhieu dong nhap gia thanh gia tong, ko can so sanh j voi so duyet PRO hay CCM".
· Tieu de: "2. Gia de xuat theo NCC trung thau" -> "2. Hang muc".
· Cot: 6 -> 3 (HANG MUC | GIA | thao-tac). GO **Nha cung cap · Gia tham chieu · Gia duyet**.
· Ghi chu xuong DONG PHU duoi o hang muc (van nhap duoc, khong chiem cot).
· +hang TONG = Sigma gia cac dong.
🔸 Du-lieu 2 cot go di VAN trong DTO; `peReferenceAmount` con dung lam DAU phan biet
  dong-goc / dong-them-tay o nut xoa.

=== 4. LOC THEO NHOM (anh: "Loc theo quy trinh luon") ===
Tang duoi man Thao tac hien phieu N1/N7 trong khi dang dung o leaf N2 => doc nham "nhom nay
dang co viec". Nay loc theo `approvalGroup` cua leaf menu. `group == null` => khong loc
(giu duong cu cho host khong truyen).

=== 5. GO DAI ACCENT + 2 O LINK HO SO/GHI CHU ===
· `card-accent` boc `KhkkDetailContent` GO HAN (dai xanh doc man Thao tac). GO CLASS chu
  KHONG de `border-0` — class nay ngoai `@layer` nen thang utility (gotcha #66).
· Khoi "Link ho so + Ghi chu" GO TRON ca 2 nhanh ternary. Luot truoc lead moi go o luoi tren
  nen 2 o van hien o khoi duoi — anh chup lai dung cho do.

=== CON NO ===
🔴 Cay man Thao tac: anh muon **Nam > Du an > Hang muc > 4 giai doan** (giong cay o man Danh
  sach). Hien moi co Du an > Hang muc (gap/mo duoc). Chua land.
🔴 CHUA soi mat prod 375/1366/1440.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-08-05 21:47:12 +07:00
parent 95f72dc278
commit 99cabd8ebe
15 changed files with 430 additions and 471 deletions

View File

@ -33,7 +33,7 @@
import { useMemo, useRef, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { Download, Eye, History, Paperclip, Send, Trash2 } from 'lucide-react'
import { Download, Eye, History, Paperclip } from 'lucide-react'
import { AttachmentPreviewDialog, isPreviewable } from '@/components/pe/AttachmentPreviewDialog'
import { Button } from '@/components/ui/Button'
import { Dialog } from '@/components/ui/Dialog'
@ -114,8 +114,8 @@ export function KhkkWorkflowPanel({
const isWaiting = phase === KhkkPhase.ChoDuyet
const isApproved = phase === KhkkPhase.DaDuyet
const isDraftLike = phase === KhkkPhase.DangSoanThao || phase === KhkkPhase.TraLai
const canDeletePlan = phase === KhkkPhase.DangSoanThao || phase === KhkkPhase.TuChoi
// 🧊 [S175] `isDraftLike` / `canSubmit` / `canDeletePlan` ĐÃ GỠ cùng 2 nút "Gửi duyệt" +
// "Xóa phiếu" — panel này nay chỉ lo màn ĐANG DUYỆT (Duyệt / Trả lại).
const curStepIdx = plan.currentWorkflowStepIndex
const curLevelOrder = plan.currentApprovalLevelOrder
@ -172,7 +172,6 @@ export function KhkkWorkflowPanel({
// Nút "Gửi duyệt": guard THẬT ở BE (`CreatedBy DeptManager Admin`). FE KHÔNG suy được
// vế DeptManager ⇒ CỐ Ý không ẩn nút theo vai (ẩn = giấu nút với đúng người có quyền, im
// lặng — bug-class gotcha #44). Chỉ chặn ca chắc-chắn-hỏng: chưa pin quy trình.
const canSubmit = isDraftLike && !!plan.approvalWorkflowId
const approvalFiles: KhkkAttachmentDto[] =
(plan.attachments ?? []).filter(a => a.purpose === KhkkAttachmentPurpose.ApprovalAttachment)
@ -434,24 +433,15 @@ export function KhkkWorkflowPanel({
)}
{/* ── 4. Hành động + nút Xóa ─────────────────────────────────────────── */}
{(canSubmit || isWaiting || canDeletePlan) && (
{/* 🧊 [S175 — anh: "Bỏ hết đi" + "chỗ menu đang duyệt → Duyệt/Trả lại vậy thôi"]
"Gửi duyệt" và "Xóa phiếu" ĐÃ RỜI khỏi đây → nay nằm ở THANH NÚT ĐÁY của
`KhkkDetailContent`. Panel này từ nay CHỈ còn **Duyệt / Trả lại** — đúng phạm vi
"màn đang duyệt". Máy `KhkkTransitionAction.Submit` vẫn nguyên ở BE và ở thanh đáy;
gỡ ở đây chỉ là gỡ ĐƯỜNG BẤM TRÙNG, không phải bỏ chức năng. */}
{isWaiting && (
<div>
<Label className="text-xs">Hành đng:</Label>
<div className="mt-1 flex flex-wrap gap-1.5">
{canSubmit && (
<button
type="button"
onClick={() => { setComment(''); setPendingFiles([]); setAction(KhkkTransitionAction.Submit) }}
className="inline-flex items-center gap-1 rounded border border-brand-300 px-2 py-1 text-[11px] font-bold text-brand-700 transition hover:bg-brand-50"
>
<Send className="h-3 w-3" /> Gửi duyệt
</button>
)}
{isDraftLike && !plan.approvalWorkflowId && (
<span className="rounded border border-dashed border-slate-300 px-2 py-1 text-[11px] text-slate-500">
Chưa pin quy trình duyệt không gửi duyệt đưc.
</span>
)}
{isWaiting && (
<>
<button
@ -494,16 +484,6 @@ export function KhkkWorkflowPanel({
và mở lại sau này chỉ là thêm nút. Gỡ cả máy = mất dữ-liệu lịch sử. */}
</>
)}
{canDeletePlan && (
<button
type="button"
onClick={() => setConfirmDelete(true)}
title="Xóa phiếu này (phiếu chuyển sang mục &ldquo;Đã xóa&rdquo;)"
className="inline-flex items-center gap-1 rounded border border-red-300 bg-white px-2 py-1 text-[11px] font-bold text-red-700 transition hover:bg-red-50"
>
<Trash2 className="h-3 w-3" /> Xóa phiếu
</button>
)}
</div>
</div>
)}