[CLAUDE] Docs: chốt Session phase 2 wrap-up — B12-B14 PE detail polish iterate

Tổng hợp 3 commit từ `378c993` → `d2306b8` (B12-B14) sau wrap-up `6e7a6db`.
KHÔNG cắt narrative cũ — thêm row STATUS, TL;DR HANDOFF, block migration-todos,
append session log (rule §6.5).

Files:
  ~ docs/STATUS.md
    - Last updated phase 2 + Phase summary cập nhật 8→9 PE phase enum
    + Recently Done: 1 row B12-B14 polish (commit SHA + chi tiết narrative
      đầy đủ context)
  ~ docs/HANDOFF.md
    - Last updated phase 2 + TL;DR Session phase 2 prepend với 3 batch
    + 4 cảnh báo Session 12+ bổ sung (8-11): isSelected per-quote BE field
      legacy, winner column logic, loading overlay scope, useEffect deps risk
  ~ docs/changelog/migration-todos.md
    + Session phase 2 done block với 3 task tick (B12-B14 commit SHA)
  ~ docs/changelog/sessions/2026-05-07-2359-pe-workspace-ux-overhaul.md
    + Append "Session phase 2" section với 3 batch chi tiết (B12-B14) + bug
      log + stats cumulative phase 2

Skill: KHÔNG update (no skill-relevant changes — pure FE polish).
Memory: KHÔNG add mới (rule UAT skip-verify đã update mid-session).
Tests: 83 pass (no test changes — UAT iter mode rule §7).

Verify: dotnet test 83 pass · git status clean · push pending.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-05-07 17:04:07 +07:00
parent d2306b88d1
commit edc66602c1
4 changed files with 105 additions and 3 deletions

View File

@ -217,3 +217,60 @@ Cron audit kế: 2026-06-01 (~25 ngày). Lúc đó sẽ:
- Update `contract-workflow/SKILL.md` TraLai phase note (nếu wire workflow xong)
- Update `schema-diagram.md` §15 Mig 17 +4 columns
- Update gotchas count (nếu phát sinh thêm)
---
## 📌 Session phase 2 (2026-05-08 00:30) — B12-B14 PE detail polish iterate
User UAT live tiếp sau wrap-up `6e7a6db`. 3 batch nhỏ FE-only:
### B12 — PE detail polish (`378c993`)
User feedback annotation 5 changes:
- "Lưu" thay "Lưu (đóng)" — chỉ toast + invalidate sync, KHÔNG đóng workspace (user vẫn xem/sửa tiếp)
- Thêm nút "Xóa phiếu" red bottom — CHỈ Bản nháp (DangSoanThao), KHÔNG xóa Trả lại. Soft-delete `IsDeleted=true` qua AuditableEntity + HasQueryFilter (không xóa hoàn toàn DB).
- Bỏ nút "Sửa header" + "Đóng" + "Xóa" header bar workspace mode (chuyển hết xuống bottom action bar). "Đóng" giữ chỉ cho readOnly + non-workspace view (Danh sách/Duyệt).
- Section 4 column header dùng `s.supplierName` (master NCC) thay `displayName` (custom). `displayName` fallback sang `title` tooltip.
- Section 3 row Xóa NCC: `hasQuotes` computed (= `ev.details.some(d => d.quotes.some(q => q.purchaseEvaluationSupplierId === s.id))`). `canDelete = !isWinner && !hasQuotes`. Render Trash button enabled vs disabled span với tooltip "xóa báo giá trước rồi mới xóa NCC".
Bug giữa B12: TS6133 `navigate` declared but never read sau khi remove "Sửa header" button. Fix: bỏ `useNavigate()` ở scope main PeDetailTabs (vẫn còn dùng ở CreateContractDialog scope local).
### B13 — InfoTab auto re-edit + pencil active visual (`e320027`)
User report: bấm pencil cho phiếu khác KHÔNG sáng + KHÔNG vào edit mode (do `useState(autoEdit && canEdit)` mount-time only, ev.id thay đổi không re-trigger).
- InfoTab: `useEffect` watch `[autoEdit, canEdit, ev.id, ev.tenGoiThau, ev.diaDiem, ev.moTa, ev.paymentTerms]`. Khi autoEdit && canEdit → `setEditing(true)` + sync 4 values từ ev mới (tránh stale state khi switch giữa 2 phiếu).
- PeListPanel: Prop `editingRowId?: string | null`. Pencil icon thêm `isEditingThis = editable && editingRowId === p.id` state → `bg-brand-100 + text-brand-700 + ring-brand-300 + shadow-sm` khi active. Tooltip "✎ Đang sửa phiếu này — click để toggle / xem khác".
- PurchaseEvaluationWorkspacePage: Pass `editingRowId={autoEditHeader ? selectedId : null}` xuống PeListPanel.
- Verify: Dự án trong InfoTab editing mode vẫn `<Input value={ev.projectName} disabled className="bg-slate-100" />` — locked không cho đổi (đã có sẵn).
### B14 — QuoteDialog + winner column + loading feedback (`d2306b8`)
User annotation 3 changes:
- **Bỏ checkbox** "Chọn NCC này cho hạng mục" trong QuoteDialog. Form state bỏ `isSelected`. API payload vẫn gửi `isSelected: existing?.isSelected ?? false` để giữ nguyên trạng thái legacy data (BE không thay đổi). Consolidate winner selection chỉ ở Section 2.a NccSelectorRow (single source of truth).
- **Winner column highlight** Section 4 matrix:
- Header `<th>`: thêm `isWinner` check → `bg-emerald-50 + text-emerald-700` + prefix `✓ ` trước tên NCC.
- Cell `<td>`: thay `q?.isSelected` highlight → `isWinnerColumn` (`ev.selectedSupplierId === s.supplierId`). Cells của winner column LUÔN xanh bất kể quote đã nhập hay chưa (visual trace winner rõ ràng).
- **Loading feedback** khi save có delay:
- QuoteDialog: full overlay `absolute z-10 + bg-white/70 backdrop-blur-sm` + spinner ring brand-600 + status text "Đang lưu báo giá…" / "Đang xóa…". Disable Hủy/Xóa/Lưu khi `isSaving = mut.isPending || del.isPending`. Button text cũng đổi.
- NccSelectorRow: inline spinner + text "Đang chọn NCC + sync cột giá Section 4…" khi `setWinner.isPending`.
## Stats sau phase 2 (cumulative)
| | Trước phase 2 | Sau phase 2 |
|---|---:|---:|
| BE LOC | ~14850 | ~14850 (không đổi — FE-only) |
| Migrations | 17 | 17 |
| FE pages | 32 | 32 |
| FE components mới | +5 | +5 |
| Tests | 83 | 83 |
| Docs | ~55 | ~55 (extends session log này) |
| Commits S10→phase 2 | 24 (incl wrap-up) | **+3 = 27 total** |
## Bug + Fix log phase 2
| # | Issue | Fix | Commit |
|---|---|---|---|
| 1 | TS6133 `navigate` unused sau remove "Sửa header" button | Bỏ `useNavigate()` ở main PeDetailTabs scope | `378c993` |
| 2 | InfoTab editing không re-trigger khi pencil click phiếu khác (useState mount-time only) | useEffect watch ev.id + autoEdit | `e320027` |