[CLAUDE] Contract: UAT S174 dot-B — be style PE sang KHKK (FE-only, 0-mig)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 6m37s

Nguon: spec runs/2026-08-05-S174-khkk-style-audit/spec-khkk-style-dong-bo-05-08-2026.md
(ensemble /fable-clone frontend-designer 5 lane). Owner S175: "KHKK theo khuon PE".
Mirror 7 CAP file, sha256 khop 7/7. Build XANH ca 2 app, 0 error TS.

=== B1 panel Quy trinh duyet (KhkkWorkflowPanel) ===
X2 GO card-accent -> panel TRAN khuon PE (:345).
  🔴 GO HAN CLASS, khong de border-0/shadow-none: .card-accent (index.css:112) nam NGOAI
  @layer nen thang utility Tailwind v4 (gotcha #66).
- Tieu de h3 tran + bo icon-chip; so hieu WF padStart(2,'0') => v01 (PE :350).
- Banner ket-thuc-som violet -> EMERALD (PE :360-377). PE danh violet RIENG cho
  "Duyet thay CEO"; dung violet ca 2 cho la tron 2 nghia vao mot mau.
- Chip PHONG vien-xam-nen-trang -> emerald dac (PE :406-410).
- Nut lucide -> glyph '✓ Duyet' / '← Tra lai' (PE :540); nut Xoa xam -> DO (PE :574).
- File dinh kem: +border-t pt-4 +h3 +nut <Eye> xem truoc. Route BE DA CO
  ContractSigningPlansController.cs:231 (/view, cung hinh PE :317).
  Nhan "Tai xuong" chuyen vao title= chu KHONG bo — giu chuoi do trong bundle
  de phep verify prod con control-duong soi duoc.
- Lich su duyet: bo pill dem -> (n) trong ngoac; the bg-slate-50/60 -> bg-white p-3 text-sm;
  moc-gio day phai bang justify-between.
  🔴 Badge 2-nga -> 3-NGA: truoc day MOI thu khong phai Reject deu to emerald => "Tra lai"
  (amber o PE) bi ve xanh nhu da-duyet, doc NGUOC nghia. toPhase da co san (khkk.ts:307).
- Lich su thay doi: BO GAP, render thang (PE PeDetailTabs.tsx:787-794).
  🔴 BAT BUOC bo luon `enabled: showChangelog` cua useQuery: giu lai thi khoi luon hien
  nhung query KHONG BAO GIO chay, va no hong duoi dang "Chua co thay doi nao duoc ghi."
  — tuc trong y het phieu chua tung sua, KHONG phai trong nhu loi. Doi lay +1 request/phieu,
  dung gia PE dang tra.
- Micro-copy: Huy / tuy chon; nhan O NHAP -> "Ghi chu" (PE :869).
  🔴 CHI doi ten TRUONG — chuoi "Y kien cap duyet" o dong tro-giup la TEN THAT cua muc dich
  den trong phieu (Section 5, Mig 26), doi no la tro nguoi dung toi mot muc khong ton tai.
- KHONG be chip "NS PRO"/"NS CCM" (2 co do mo quyen sua ngan sach per-goi-thau, khai niem
  KHKK khong co). GIU moc chu-ky KHKK (cho KHKK tot hon PE).

=== B2 noi dung phieu (KhkkDetailContent) — 6 P0 ===
- 2 bang: table-fixed + <colgroup> + min-w-[880px] trong overflow-x-auto. Bang co gian
  tu-do truoc day de cot tien nhay be rong theo do dai ten NCC => 3 cot so khong thang hang.
- O RONG -> em-dash MO (text-slate-300) gom vao helper orDash/moneyOrDash: truoc day em-dash
  thua-huong dung mau chu that => luot bang thi "—" trong y nhu mot GIA-TRI.
  moneyOrDash rieng vi formatVnd tra CHUOI "—" nen khong to mo duoc.
- empty-block -> text-sm italic text-slate-400 (3 cho).
- emoji 🔒 -> icon lucide <Lock>: emoji render khac nhau theo font he dieu-hanh va KHONG an
  currentColor nen luon lech tong voi chu amber ben canh.
- thong nhat text-xs ca hang bang; +hover:bg-slate-50/60 cho <tr>.

=== B3 panel danh sach (KhkkListPanel + KhkkWorkListPanel + PipelineTreePanel) ===
- DAU COT: che-do CAY truoc day di thang vao than, khong tieu-de/so dem => cot "cut dau",
  lech ca voi man Thao tac (Tier header) LAN voi chinh che-do phang (co dem o chan).
  Mirror khuon Tier.
- Gop 2 o tim chong nhau: +prop hideSearch cho PipelineTreePanel (MAC DINH giu nguyen —
  4/6 host kia khong truyen, 0 doi hanh vi). O trong cay KHONG bao gio dung toi vi o ngoai
  di server-side va go vao la chuyen han sang flatMode => cay bien mat.
- Thang chu 4 nac (13/11/10/9) -> 3 nac chuan 13/11/10.
- 🔴 WCAG: text-slate-400 = 2.56:1 tren nen trang, DUOI nguong AA 4.5:1 — nang len
  slate-500 (4.76:1) cho 7 dong MANG THONG TIN (6 note/empty-state + 1 so dem).
  GIU slate-400 cho 2 cho TRANG TRI (icon Search, dau cham phan cach) — WCAG khong doi
  tuong phan cho noi dung trang tri.
- Nut phan trang ky-tu tran ←/→ -> icon ChevronLeft/Right + aria-label: mui ten dang chu
  doi hinh theo font he dieu-hanh va KHONG co ten cho trinh doc man hinh.
- Chip nhom: inline + co chu khac dong chua => hop chip cao khac chu ben canh nen tut
  baseline; inline-flex items-center leading-none ghim thang hang.

=== B4 host (KhkkCreatePage) ===
- Grid 260/320 DA land tu dot A — chi con COMMENT stale ghi 300px, da va.
- 🔴 Va comment SAI SU THAT (L3 H-5): comment khai Panel 1 co "nut hanh-dong dinh day"
  nhung grep -c Button KhkkWorkListPanel = 0 (control-duong PeListPanel = 8). Do la mo ta
  CUA PE be nguyen sang => tu khai mot thu chua dung.

=== 2 component DUNG CHUNG — mo rong kieu MAC-DINH-GIU-NGUYEN ===
AttachmentPreviewDialog +basePath? (mac dinh /purchase-evaluations) => 6 call-site PE
KHONG phai sua dong nao (module da golive; bat sua het call-site cu = tu de rui-ro o cho
dang chay tot). PipelineTreePanel +hideSearch? y het. Da verify: 0 call-site PE bi dong.

=== CON NO ===
🔴 CHUA soi mat tren prod 375/1366/1440 — ca 5 lane deu NO-SCREENSHOT (dev-rig chan:
chi :8080 LISTENING, API :5443 khong co, trang sau ProtectedRoute — gotcha #3). Moi ket
luan la DOC MA, khong phai da nhin.
Dot C3 (Field to brand cho MOI value) + dot D (O3/O4/O6/O7/O8) chua lam. O3 con cho owner
xac nhan cach doc "sum tong" — do la tien.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-08-05 19:30:13 +07:00
parent c61e28f833
commit 43e1bd7bc2
14 changed files with 570 additions and 324 deletions

View File

@ -89,6 +89,7 @@ export function PipelineTreePanel({
bodyMaxHClass,
stage2Options,
hideHeader,
hideSearch,
}: {
currentStage: PipelineStageNo
className?: string
@ -107,6 +108,12 @@ export function PipelineTreePanel({
// 🔴 Nút "Hiện/Ẩn cây" (mobile) sống TRONG thanh này và là đường DUY NHẤT mở thân cây khi
// `<lg`. Vì vậy ẩn thanh ⇒ PHẢI ép thân cây hiện luôn, nếu không mobile mất trắng cây.
hideHeader?: boolean
// [S175 · B3] Ẩn ô lọc RIÊNG của cây. CHỈ dùng ở host đã có ô tìm của chính nó ngay trên
// (KHKK GĐ2) — ở đó 2 ô tìm xếp chồng nhau mà nghĩa lại khác: ô ngoài đi SERVER-SIDE và
// gõ vào là chuyển hẳn sang danh-sách phẳng (`flatMode`), nên ô trong cây KHÔNG bao giờ
// dùng tới — người dùng gõ phát nào là cây biến mất phát đó.
// 6 host còn lại KHÔNG truyền ⇒ giữ nguyên ô lọc cây như cũ.
hideSearch?: boolean
}) {
const { canPe, buildStages } = usePipelineStages()
const [search, setSearch] = useState('')
@ -232,16 +239,18 @@ export function PipelineTreePanel({
{/* [S174] `hideHeader` ⇒ không còn nút toggle ⇒ ép `flex` để `<lg` vẫn thấy cây. */}
<div className={cn('min-h-0 flex-col', hideHeader || mobileOpen ? 'flex' : 'hidden', 'lg:flex')}>
<div className="relative border-b border-slate-200 p-2">
<Search className="pointer-events-none absolute left-4 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-slate-400" />
<input
value={search}
onChange={e => setSearch(e.target.value)}
placeholder="Lọc dự án / hạng mục / mã phiếu…"
aria-label="Lọc cây toàn trình"
className="h-8 w-full rounded-md border border-slate-200 bg-white pl-7 pr-2 text-[12px] text-slate-700 placeholder:text-slate-400 focus-visible:border-brand-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500/30"
/>
</div>
{!hideSearch && (
<div className="relative border-b border-slate-200 p-2">
<Search className="pointer-events-none absolute left-4 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-slate-400" />
<input
value={search}
onChange={e => setSearch(e.target.value)}
placeholder="Lọc dự án / hạng mục / mã phiếu…"
aria-label="Lọc cây toàn trình"
className="h-8 w-full rounded-md border border-slate-200 bg-white pl-7 pr-2 text-[12px] text-slate-700 placeholder:text-slate-400 focus-visible:border-brand-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500/30"
/>
</div>
)}
<div className={cn('overflow-y-auto', bodyMaxHClass ?? 'max-h-[28rem] lg:max-h-[calc(100vh-16rem)]')}>
{!canPe && (