[CLAUDE] Contract: UAT S174 vong-3 — 5 chinh KHKK theo anh chot (FE-only, 0-mig)
1. Ho thu: GO `PipelineTreePanel` khoi `/inbox` — anh: "cho hop thu vut panel nay vao lam j, tap trung vao KHKK thoi". Ho thu = hang-doi-viec-cua-toi, cay toan trinh = ban-do-toan-he => sai the loai. Cho trong nay tra ve dung vai: cho quy trinh duyet cua HD dang chon. 🔸 HAI trang GD3/GD4 con lai (`MyContractsPage` · `HardCopiesPage`) GIU NGUYEN — anh chi dich danh Ho thu, khong noi go het; khong tu suy rong. (Lineage: panel vao day @S168 GD3-D theo owner slot (63) + "mo rong = ca 3 trang"; nay owner thu lai DUNG trang nay.) 2. Panel KHKK: BO nut "+ Them moi". Man nay KHONG co duong "tao tu so 0" — ke hoach LUON sinh tu mot phieu Duyet NCC, ma cac phieu du dieu kien da nam nguyen o tang tren => nut chi xoa form chu khong tao them duoc gi. Khac CO CHU DICH voi `PeListPanel`. 3. Tang duoi CHI giu ke hoach DANG XU LY — an phieu `DaDuyet` (anh: "da duyet bo di luon"). 🔴 KHAI GIOI-HAN: loc o FE vi endpoint chi nhan `phase` DON, khong co tham so "loai tru" => (a) KHONG dung `total` cua server lam so hien thi (da gom phieu DaDuyet) — dem tu mang da loc; (b) cua-so 30 phieu moi nhat co the TOAN DaDuyet => tang duoi rong du con phieu nhap cu hon. Chap nhan o UAT; muon chuan thi BE them tham so loai-tru. Doi luon dong chu "x/total" -> "Da an ke hoach Da duyet": ti so cu doc thanh "dang cat bot" trong khi that ra la "dang loc bo". 4. Nhom duyet + Quy trinh duyet GAN CUNG theo leaf menu — anh: "gan cung luon theo tung nhom ko cho User dieu chinh cho nay luon". - `approvalGroup` khong con la state, DAN XUAT thang tu `?group=n`. Bo luon khoi dong-bo `lastPresetGroup` + ham `firstFreeGroup()` (chung chi ton tai de tu nhay nhom = dung hanh-vi vua bi cam). - Quy trinh: match theo ma tu NGUON BE, khong suy tu man hinh — `DbInitializer.cs:609` `var code = $"KHKK-N{n}"`. Khong khop => CHAN tao + noi ro thieu ma nao, TUYET DOI khong tu roi ve quy trinh nhom khac (gan nham = phieu di sai duong duyet). - UI: hien gia-tri co dinh, CO Y khong dung `<Select disabled>` (o xam van trong nhu "bam duoc nhung dang khoa" va van trong tab-order). 5. Panel giua: GO Section 5 "Y kien cap duyet" (anh: "bo luon cai nay ra luon"). So-do Buoc/Cap + chu ky da song o Panel 3 => de ca hai la ke mot chuyen hai lan tren cung man. DTO giu nguyen (`levelOpinions`/`workflowSteps` panel 3 van dung) — chi bo cho VE. Verify: build 2 app PASS; mirror SHA256 3/3 cap KHOP. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@ -31,6 +31,7 @@ import { cn } from '@/lib/cn'
|
||||
import {
|
||||
KHKK_PHASE_BADGE,
|
||||
KHKK_PHASE_LABELS,
|
||||
KhkkPhase,
|
||||
type KhkkListItemDto,
|
||||
type KhkkPeCandidateDto,
|
||||
type PagedResult,
|
||||
@ -78,7 +79,6 @@ export function KhkkWorkListPanel({
|
||||
onPickPlan,
|
||||
selectedPeId,
|
||||
selectedPlanId,
|
||||
footer,
|
||||
}: {
|
||||
/** Bấm PE ở tầng trên → host nạp phiếu đó vào form tạo (Ở LẠI màn, không điều hướng). */
|
||||
onPickPe: (peId: string) => void
|
||||
@ -87,8 +87,6 @@ export function KhkkWorkListPanel({
|
||||
onPickPlan: (planId: string) => void
|
||||
selectedPeId?: string | null
|
||||
selectedPlanId?: string | null
|
||||
/** Nút "+ Thêm mới" dính đáy — mirror `PeListPanel` của màn Duyệt NCC — Thao tác. */
|
||||
footer?: React.ReactNode
|
||||
}) {
|
||||
const { can } = usePermission()
|
||||
// 🔴 ĐÚNG key policy của endpoint — KHÔNG dùng `Khkk_*` (đó là key MENU, tầng hiển thị).
|
||||
@ -126,7 +124,14 @@ export function KhkkWorkListPanel({
|
||||
else byProject.set(key, [pe])
|
||||
}
|
||||
|
||||
const planItems = plans.data?.items ?? []
|
||||
// [S174 owner] "đã duyệt bỏ đi luôn" — tầng dưới chỉ giữ kế hoạch CHƯA xong việc
|
||||
// (nháp / chờ duyệt / trả lại / từ chối). Phiếu `DaDuyet` đã hết việc ở màn Thao tác.
|
||||
// 🔴 KHAI GIỚI-HẠN (lọc ở FE): endpoint chỉ nhận `phase` ĐƠN, không có tham số "loại trừ"
|
||||
// ⇒ (1) `plans.data.total` của server ĐÃ GỒM phiếu DaDuyet nên KHÔNG được dùng làm số
|
||||
// hiển thị — đếm từ chính mảng đã lọc; (2) cửa-sổ 30 phiếu mới nhất có thể TOÀN DaDuyet,
|
||||
// khi đó tầng dưới rỗng dù còn phiếu nháp cũ hơn. Chấp nhận ở UAT; muốn chuẩn thì BE thêm
|
||||
// tham số loại-trừ rồi lọc SERVER-SIDE.
|
||||
const planItems = (plans.data?.items ?? []).filter((k) => k.phase !== KhkkPhase.DaDuyet)
|
||||
|
||||
return (
|
||||
<aside className="flex min-h-0 flex-col overflow-hidden border-r border-slate-200 bg-white">
|
||||
@ -209,8 +214,9 @@ export function KhkkWorkListPanel({
|
||||
<div className="shrink-0 border-t-2 border-slate-200" />
|
||||
|
||||
<Tier
|
||||
title="Kế hoạch ký kết đã tạo"
|
||||
count={plans.data?.total ?? null}
|
||||
title="Kế hoạch ký kết đang xử lý"
|
||||
// Đếm từ mảng ĐÃ LỌC, KHÔNG lấy `total` của server (xem khối lọc phía trên).
|
||||
count={plans.data ? planItems.length : null}
|
||||
accent="bg-violet-50 text-violet-600"
|
||||
icon={<FileSignature className="h-3 w-3" />}
|
||||
>
|
||||
@ -228,7 +234,10 @@ export function KhkkWorkListPanel({
|
||||
</div>
|
||||
)}
|
||||
{!plans.isLoading && !plans.isError && planItems.length === 0 && (
|
||||
<p className="p-3 text-[11px] italic text-slate-400">Chưa có kế hoạch ký kết nào.</p>
|
||||
<p className="p-3 text-[11px] italic text-slate-400">
|
||||
Không còn kế hoạch nào đang xử lý. Phiếu đã duyệt không hiện ở đây — xem tại
|
||||
menu Kế hoạch ký kết HĐ.
|
||||
</p>
|
||||
)}
|
||||
<ul className="divide-y divide-slate-100">
|
||||
{planItems.map((k) => (
|
||||
@ -267,19 +276,23 @@ export function KhkkWorkListPanel({
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{plans.data && plans.data.total > planItems.length && (
|
||||
{/* 🔴 KHÔNG in "x/total" nữa: `total` gồm cả phiếu đã duyệt vừa bị lọc ⇒ tỉ số đó
|
||||
sẽ đọc thành "đang cắt bớt" trong khi thật ra là "đang lọc bỏ". Nói đúng việc
|
||||
đang làm, và chỉ nói khi thật sự có cái bị giấu. */}
|
||||
{plans.data && plans.data.items.length > planItems.length && (
|
||||
<p className="border-t border-slate-100 px-3 py-1.5 text-[10px] italic text-slate-400">
|
||||
Hiện {planItems.length}/{plans.data.total} kế hoạch mới nhất — xem đủ ở menu Kế hoạch ký kết HĐ.
|
||||
Đã ẩn kế hoạch ở trạng thái “Đã duyệt” — xem đủ ở menu Kế hoạch ký kết HĐ.
|
||||
</p>
|
||||
)}
|
||||
</Tier>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Nút hành-động dính ĐÁY, ngoài vùng cuộn của 2 tầng — mirror "+ Thêm mới" của
|
||||
`PeListPanel` (màn Duyệt NCC — Thao tác). Hiện KỂ CẢ khi thiếu quyền KHKK: cột
|
||||
không dựng được thì vẫn phải còn đường bấm, không thì màn thành ngõ cụt. */}
|
||||
{footer && <div className="shrink-0 border-t border-slate-200 p-2">{footer}</div>}
|
||||
{/* 🧊 [S174] KHÔNG có nút "+ Thêm mới" ở đáy — anh chốt bỏ. Lý do đứng vững: màn này
|
||||
KHÔNG có đường "tạo từ số 0". Một kế hoạch LUÔN sinh ra từ một phiếu Duyệt NCC, mà
|
||||
các phiếu đủ điều kiện đã nằm nguyên ở tầng trên ⇒ nút chỉ xoá form chứ không tạo
|
||||
thêm được gì. Đây là chỗ khác CÓ CHỦ ĐÍCH với `PeListPanel` (bên đó tạo phiếu PE
|
||||
mới là việc có thật). Ai định thêm lại: phải trả lời được "thêm mới CÁI GÌ". */}
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user