fix(data-table): preserve prior rows when multi-selecting
onRowSelectionChange computed the next selection from the render-time `rowSelection` closure, which could be stale by the time a second row was toggled. The updater then produced a selection containing only the latest row, and the persistedMap sync deleted the earlier one — so checking a second part unchecked the first, making multi-select behave as single-select. Track the latest selection in a ref and derive the updater from it, so each toggle builds on the current selection. Fixes adding multiple parts/services/ expense items in invoices, estimates, and job cards. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
29d90b5e71
commit
75e44f5b26
@ -39,8 +39,13 @@ export function DataTable<TData>({
|
||||
// Persisted map of id → original row data across all pages
|
||||
const persistedMap = useRef<Map<string, TData>>(new Map())
|
||||
|
||||
// Current-page selection state that TanStack Table controls
|
||||
// Current-page selection state that TanStack Table controls.
|
||||
// A ref mirrors the latest value so onRowSelectionChange never derives the
|
||||
// next selection from a stale closure (which would drop previously-checked
|
||||
// rows and make multi-select behave like single-select).
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
|
||||
const rowSelectionRef = useRef<RowSelectionState>({})
|
||||
rowSelectionRef.current = rowSelection
|
||||
|
||||
// When the page/data changes, restore selection state for the new page from the map
|
||||
useEffect(() => {
|
||||
@ -50,6 +55,7 @@ export function DataTable<TData>({
|
||||
const id = String((row as Record<string, unknown>)[rowKeyStr])
|
||||
if (persistedMap.current.has(id)) restored[id] = true
|
||||
})
|
||||
rowSelectionRef.current = restored
|
||||
setRowSelection(restored)
|
||||
}, [data]) // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
@ -128,7 +134,10 @@ export function DataTable<TData>({
|
||||
})
|
||||
},
|
||||
onRowSelectionChange: (updater) => {
|
||||
const next = typeof updater === "function" ? updater(rowSelection) : updater
|
||||
// Derive from the ref (always current), not the render-time closure,
|
||||
// so toggling a second row preserves earlier selections.
|
||||
const next = typeof updater === "function" ? updater(rowSelectionRef.current) : updater
|
||||
rowSelectionRef.current = next
|
||||
setRowSelection(next)
|
||||
if (selection) {
|
||||
// Sync current page into the persisted map
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user