diff --git a/fe-admin/src/components/pe/PeDetailTabs.tsx b/fe-admin/src/components/pe/PeDetailTabs.tsx index 1ccdd26..668df84 100644 --- a/fe-admin/src/components/pe/PeDetailTabs.tsx +++ b/fe-admin/src/components/pe/PeDetailTabs.tsx @@ -2,7 +2,7 @@ // NCC + Hạng mục + Báo giá stack vertically trong 1 màn hình. // Duyệt history + Lịch sử thay đổi → moved to Panel 3 (xem PeWorkflowPanel // → PeApprovalsSection + PeHistorySection). -import { useRef, useState } from 'react' +import { useEffect, useRef, useState } from 'react' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useNavigate } from 'react-router-dom' import { toast } from 'sonner' @@ -399,6 +399,20 @@ function InfoTab({ ev, readOnly, autoEdit }: { ev: PeDetailBundle; readOnly: boo const [moTa, setMoTa] = useState(ev.moTa ?? '') const [paymentTerms, setPaymentTerms] = useState(ev.paymentTerms ?? '') + // User 2026-05-07: re-trigger editing mode khi click pencil ở Panel 1 cho + // PHIẾU KHÁC (ev.id thay đổi) hoặc autoEdit prop change. useState init chỉ + // chạy mount-time → cần useEffect sync khi parent re-render với props mới. + useEffect(() => { + if (autoEdit && canEdit) { + setEditing(true) + // Sync values từ ev mới (tránh stale state khi switch giữa 2 phiếu) + setTenGoiThau(ev.tenGoiThau) + setDiaDiem(ev.diaDiem ?? '') + setMoTa(ev.moTa ?? '') + setPaymentTerms(ev.paymentTerms ?? '') + } + }, [autoEdit, canEdit, ev.id, ev.tenGoiThau, ev.diaDiem, ev.moTa, ev.paymentTerms]) + const dirty = tenGoiThau !== ev.tenGoiThau || diaDiem !== (ev.diaDiem ?? '') || moTa !== (ev.moTa ?? '') diff --git a/fe-admin/src/components/pe/PeListPanel.tsx b/fe-admin/src/components/pe/PeListPanel.tsx index f7bea17..14c3c9d 100644 --- a/fe-admin/src/components/pe/PeListPanel.tsx +++ b/fe-admin/src/components/pe/PeListPanel.tsx @@ -39,6 +39,7 @@ export function PeListPanel({ onCreate, onEditClick, editableOnly = false, + editingRowId = null, }: { typeFilter: number | null pendingMe?: boolean @@ -55,6 +56,9 @@ export function PeListPanel({ /** Workspace mode: chỉ list phiếu editable (DangSoanThao + TraLai). Filter * client-side sau khi fetch — BE chưa hỗ trợ multi-phase param. */ editableOnly?: boolean + /** Row đang được edit (URL editHeader=1) — pencil icon "sáng lên" active state. + * User 2026-05-07: visual feedback khi click pencil. */ + editingRowId?: string | null }) { const list = useQuery({ queryKey: ['pe-list', { typeFilter, pendingMe, search, phase }], @@ -185,20 +189,27 @@ export function PeListPanel({ {/* Edit pencil — LUÔN visible (user 2026-05-07). Bright/active khi phase editable (DangSoanThao + TraLai). Dim/disabled khi phase không edit được (Đã gửi duyệt / Đã duyệt - / Từ chối) — click không có tác dụng. */} + / Từ chối) — click không có tác dụng. + "Sáng lên" active state khi row.id === editingRowId (user + vừa click pencil + đang edit) — bg-brand-100 + ring. */} {onEditClick && (() => { const editable = isEditablePhase(p.phase) + const isEditingThis = editable && editingRowId === p.id return (