[CLAUDE] FE-Admin: PE InfoTab inline edit Section 1 + PeListPanel pencil edit hover
User feedback 2026-05-07: muốn thêm nút edit kế bên row trong Panel 1, click →
Panel 2 sáng nội dung Section 1 lên cho user sửa header inline (KHÔNG cần đi
"Sửa header" page). Cũng muốn create new interface gần giống detail view
sectioned (defer cho chunk sau, hoặc keep PeHeaderForm nếu user OK).
Implementation:
~ PeDetailTabs.tsx
- InfoTab thêm prop `readOnly` + `autoEdit` (trigger edit mode tự động khi
mount nếu URL ?editHeader=1)
- canEdit = !readOnly && isDraft (DangSoanThao):
→ display mode: hiển thị FormRow + button "✎ Sửa" góc trên phải Section 1
→ editing mode (click Sửa hoặc autoEdit): card border brand-200 + 4 input
(Tên * / Dự án disabled / Địa điểm / Mô tả / Payment) + nút Lưu/Hủy
- Save: PUT /pe/:id full payload (current ev values + new editable fields).
onSuccess: invalidate ['pe-detail', 'pe-list'] + setEditing(false)
- PeDetailTabs prop `autoEditHeader` mới — pass-through xuống InfoTab
~ PeListPanel.tsx
- Thêm prop `onEditClick?: (id) => void`
- Pencil icon (lucide) absolute right-2 top-2 trong mỗi <li>, opacity-0
group-hover:opacity-100 — chỉ hiện khi user hover row + onEditClick set
- Click → trigger onEditClick(id) callback (different from row click)
~ PurchaseEvaluationWorkspacePage.tsx
- Đọc URL ?editHeader=1 → pass autoEditHeader xuống PeDetailTabs
- PeListPanel onEditClick → setParams({ id, mode: null, editHeader: '1' })
- onSelect (click row thường) → editHeader: null (clear flag)
- onBack → clear editHeader
Verify: npm run build fe-admin pass · 0 TS error.
Pending: workspace "new" mode wrap PeHeaderForm trong sectioned layout giống
detail view (defer — user có thể chấp nhận PeHeaderForm hiện tại nếu OK).
Next: Chunk 2 fe-user mirror.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
// chỉ render + invoke callbacks. Pendingme vẫn truyền được nếu cần dùng cho
|
||||
// inbox view khác (hiện chỉ workspace dùng pendingMe=false).
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { ClipboardCheck, Plus, Search } from 'lucide-react'
|
||||
import { ClipboardCheck, Pencil, Plus, Search } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Input } from '@/components/ui/Input'
|
||||
import { Select } from '@/components/ui/Select'
|
||||
@ -34,6 +34,7 @@ export function PeListPanel({
|
||||
onPhaseChange,
|
||||
showCreateButton = false,
|
||||
onCreate,
|
||||
onEditClick,
|
||||
}: {
|
||||
typeFilter: number | null
|
||||
pendingMe?: boolean
|
||||
@ -45,6 +46,8 @@ export function PeListPanel({
|
||||
onPhaseChange: (p: string) => void
|
||||
showCreateButton?: boolean
|
||||
onCreate?: () => void
|
||||
/** Pencil edit icon hover next-to-row — click → select + auto-open Section 1 edit mode (URL ?editHeader=1). */
|
||||
onEditClick?: (id: string) => void
|
||||
}) {
|
||||
const list = useQuery({
|
||||
queryKey: ['pe-list', { typeFilter, pendingMe, search, phase }],
|
||||
@ -122,11 +125,11 @@ export function PeListPanel({
|
||||
)}
|
||||
<ul className="divide-y divide-slate-100">
|
||||
{rows.map(p => (
|
||||
<li key={p.id}>
|
||||
<li key={p.id} className="group relative">
|
||||
<button
|
||||
onClick={() => onSelect(p.id)}
|
||||
className={cn(
|
||||
'block w-full px-3 py-2.5 text-left transition hover:bg-slate-50',
|
||||
'block w-full px-3 py-2.5 pr-9 text-left transition hover:bg-slate-50',
|
||||
selectedId === p.id && 'bg-brand-50 ring-1 ring-inset ring-brand-200',
|
||||
)}
|
||||
>
|
||||
@ -163,6 +166,16 @@ export function PeListPanel({
|
||||
<div className="mt-1 text-[10px] text-brand-600">✓ Đã tạo HĐ</div>
|
||||
)}
|
||||
</button>
|
||||
{/* Edit pencil — visible on hover (chỉ khi onEditClick được truyền) */}
|
||||
{onEditClick && (
|
||||
<button
|
||||
onClick={() => onEditClick(p.id)}
|
||||
className="absolute right-2 top-2 rounded p-1.5 text-slate-400 opacity-0 transition group-hover:opacity-100 hover:bg-white hover:text-brand-600 hover:shadow-sm"
|
||||
title="Sửa thông tin gói thầu"
|
||||
>
|
||||
<Pencil className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user