[CLAUDE] FE-User+FE-Admin: Plan AG3 — PE List tree consistent (drop single-PE flat branch)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m19s

Anh feedback 2026-05-21: "nếu có 1 thì cũng để tương tự luôn nhé, đừng để khác các thằng kia".
Plan AG2 render single-PE project flat card + UPPERCASE label phía trên — khác phong cách
với multi-PE project (folder <details>). UX inconsistent.

Plan AG3 drop nhánh single-PE flat. Mọi dự án dù 1 hay nhiều PE đều render <details>
folder collapsed với badge count "(N)" — consistent visual.

Diff: -60 LOC (drop entire single-PE flat block).

Verify:
- npm build fe-user PASS 0 TS err
- npm build fe-admin PASS 0 TS err
- 2 file SHA256 IDENTICAL 749FF703... (mirror §3.9)
- KHÔNG BE change, KHÔNG Mig, KHÔNG test (UAT mode)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-05-21 18:35:25 +07:00
parent c5429c0d10
commit fbad4a9251
2 changed files with 6 additions and 116 deletions

View File

@ -251,68 +251,13 @@ export function PurchaseEvaluationsListPage() {
<EmptyState icon={ClipboardCheck} title="Chưa có phiếu" description="Tạo phiếu mới để bắt đầu quy trình." />
</div>
)}
{/* Plan AG2 — Tree view 1-level Project > PE (drop gói thầu per anh 2026-05-21).
<details>/<summary> HTML native. Single-PE project → render flat card no wrapper.
Multi-PE project → <details> tree với toggle expand + localStorage persist.
{/* Plan AG3 — Tree view 1-level Project > PE consistent (anh feedback 2026-05-21:
"nếu có 1 thì cũng để tương tự luôn nhé, đừng để khác các thằng kia").
Mọi dự án dù có 1 hay nhiều PE đều render <details> folder collapsed.
Tailwind v3 named group group/proj + [&::-webkit-details-marker]:hidden. */}
<div className="divide-y divide-slate-100">
{projectGroups.map(pg => {
const projKey = pg.projectId ?? '__no_project__'
// Single-PE project → render flat card (no <details> wrapper) — anh feedback "ko cần treedow"
if (pg.items.length === 1) {
const p = pg.items[0]
return (
<button
key={p.id}
onClick={() => selectRow(p.id)}
className={cn(
'block w-full px-3 py-2.5 text-left transition hover:bg-slate-50',
selectedId === p.id && 'bg-brand-50 ring-1 ring-inset ring-brand-200',
)}
>
<div className="mb-1 flex items-center gap-1.5 text-[10px] uppercase tracking-wide text-slate-400">
<span>📁</span>
<span className="truncate">{pg.projectName}</span>
</div>
<div className="flex items-start justify-between gap-2">
<div className="min-w-0 flex-1">
<div className="truncate text-[13px] font-medium text-slate-900">{p.tenGoiThau}</div>
<div className="mt-0.5 flex items-center gap-1.5 text-[11px] text-slate-500">
<span className="font-mono">{p.maPhieu ?? '—'}</span>
</div>
{p.selectedSupplierName && (
<div className="mt-0.5 truncate text-[11px] text-emerald-600">
{p.selectedSupplierName}
</div>
)}
</div>
<span
className={cn(
'shrink-0 rounded px-1.5 py-0.5 text-[10px] font-medium',
PeDisplayStatusColor[getPeDisplayStatus(p.phase)],
)}
>
{PeDisplayStatusLabel[getPeDisplayStatus(p.phase)]}
</span>
</div>
<div className="mt-1 flex items-center justify-between text-[11px] text-slate-500">
<span className="rounded bg-slate-100 px-1.5 py-0.5 text-slate-600">
{PurchaseEvaluationTypeLabel[p.type]}
</span>
<span className="font-medium text-slate-600" title={`Tạo lúc ${new Date(p.createdAt).toLocaleString('vi-VN')}`}>
{new Date(p.createdAt).toLocaleString('vi-VN', {
day: '2-digit', month: '2-digit', year: 'numeric',
hour: '2-digit', minute: '2-digit',
})}
</span>
</div>
{p.contractId && (
<div className="mt-1 text-[10px] text-brand-600"> Đã tạo </div>
)}
</button>
)
}
// Multi-PE project → render <details> tree
return (
<details
key={projKey}