Skip to content

Commit 3c65994

Browse files
committed
feat: refactor component structure
1 parent a977c1c commit 3c65994

File tree

9 files changed

+272
-349
lines changed

9 files changed

+272
-349
lines changed

packages/payload/src/admin/views/treeViewList.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export type TreeViewClientProps = {
2727
enableRowSelections?: boolean
2828
expandedItemKeys?: TreeViewItemKey[]
2929
items: TreeViewItem[]
30+
noResults: boolean
3031
parentFieldName: string
3132
search?: string
3233
sort?: FolderSortKeys

packages/ui/src/elements/TreeView/NestedSectionsTable/Row/index.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ interface DivTableRowProps {
2727
firstCellXOffset: number
2828
focusedRowIndex?: number
2929
hasSelectedAncestor: boolean
30-
hoveredRowID: null | number | string
30+
hoveredRowItemKey: ItemKey | null
3131
isDragging: boolean
3232
isFirstRowAtRootLevel: boolean
3333
isInvalidTarget: boolean
3434
isLastRow: boolean
3535
isRowAtRootLevel: boolean
3636
isRowSelected: boolean
3737
level: number
38-
loadingRowIDs?: Set<number | string>
38+
loadingRowItemKeys?: Set<ItemKey>
3939
onDroppableHover: (params: {
40-
hoveredRowID?: number | string
40+
hoveredRowID?: ItemKey
4141
placement?: string
4242
targetItem: null | SectionRow
4343
}) => void
@@ -71,13 +71,13 @@ export const Row: React.FC<DivTableRowProps> = ({
7171
firstCellXOffset,
7272
focusedRowIndex,
7373
hasSelectedAncestor,
74-
hoveredRowID,
74+
hoveredRowItemKey,
7575
isDragging,
7676
isFirstRowAtRootLevel,
7777
isInvalidTarget,
7878
isRowSelected,
7979
level,
80-
loadingRowIDs,
80+
loadingRowItemKeys: loadingRowIDs,
8181
onDroppableHover,
8282
onFocusChange,
8383
onRowDrag,
@@ -301,7 +301,7 @@ export const Row: React.FC<DivTableRowProps> = ({
301301
</div>
302302

303303
{/* Render placeholder row below the hovered row */}
304-
{isDragging && hoveredRowID === rowItem.rowID && (
304+
{isDragging && hoveredRowItemKey === rowItem.rowID && (
305305
<div className={`${baseClass}__placeholder-section`}>
306306
<div className={`${baseClass}__placeholder-row`}>
307307
{columns.map((col) => (

packages/ui/src/elements/TreeView/NestedSectionsTable/TableSection/index.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ interface RenderTableSectionProps {
1212
firstCellXOffset: number
1313
focusedRowIndex?: number
1414
hasSelectedAncestor?: boolean
15-
hoveredRowID: null | number | string
15+
hoveredRowItemKey: ItemKey | null
1616
isDragging: boolean
1717
isLastRowOfRoot?: boolean
1818
level?: number
19-
loadingRowIDs?: Set<number | string>
19+
loadingRowItemKeys?: Set<ItemKey>
2020
onDroppableHover: (params: {
21-
hoveredRowID?: number | string
21+
hoveredRowID?: ItemKey
2222
placement?: string
2323
targetItem: null | SectionRow
2424
}) => void
@@ -54,11 +54,11 @@ export const TableSection: React.FC<RenderTableSectionProps> = ({
5454
firstCellXOffset,
5555
focusedRowIndex,
5656
hasSelectedAncestor = false,
57-
hoveredRowID,
57+
hoveredRowItemKey,
5858
isDragging,
5959
isLastRowOfRoot = false,
6060
level = 0,
61-
loadingRowIDs,
61+
loadingRowItemKeys,
6262
onDroppableHover,
6363
onFocusChange,
6464
onRowDrag,
@@ -144,15 +144,15 @@ export const TableSection: React.FC<RenderTableSectionProps> = ({
144144
firstCellXOffset={firstCellXOffset}
145145
focusedRowIndex={focusedRowIndex}
146146
hasSelectedAncestor={hasSelectedAncestor}
147-
hoveredRowID={hoveredRowID}
147+
hoveredRowItemKey={hoveredRowItemKey}
148148
isDragging={isDragging}
149149
isFirstRowAtRootLevel={isFirstRowAtRootLevel}
150150
isInvalidTarget={isInvalidTarget}
151151
isLastRow={isLastRow}
152152
isRowAtRootLevel={isRowAtRootLevel}
153153
isRowSelected={isRowSelected}
154154
level={level}
155-
loadingRowIDs={loadingRowIDs}
155+
loadingRowItemKeys={loadingRowItemKeys}
156156
onDroppableHover={onDroppableHover}
157157
onFocusChange={onFocusChange}
158158
onRowDrag={onRowDrag}
@@ -176,11 +176,11 @@ export const TableSection: React.FC<RenderTableSectionProps> = ({
176176
firstCellXOffset={firstCellXOffset}
177177
focusedRowIndex={focusedRowIndex}
178178
hasSelectedAncestor={hasSelectedAncestor || isRowSelected}
179-
hoveredRowID={hoveredRowID}
179+
hoveredRowItemKey={hoveredRowItemKey}
180180
isDragging={isDragging}
181181
isLastRowOfRoot={isRowAtRootLevel}
182182
level={level + 1}
183-
loadingRowIDs={loadingRowIDs}
183+
loadingRowItemKeys={loadingRowItemKeys}
184184
onDroppableHover={onDroppableHover}
185185
onFocusChange={onFocusChange}
186186
onRowDrag={onRowDrag}

packages/ui/src/elements/TreeView/NestedSectionsTable/index.tsx

Lines changed: 94 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
'use client'
2+
3+
import { useDndMonitor } from '@dnd-kit/core'
14
import React from 'react'
25

3-
import type { NestedSectionsTableProps, SectionRow } from './types.js'
6+
import type { ItemKey, NestedSectionsTableProps, SectionRow } from './types.js'
47

58
import { Header } from './Header/index.js'
69
import { TableSection } from './TableSection/index.js'
@@ -13,20 +16,17 @@ export const NestedSectionsTable: React.FC<NestedSectionsTableProps> = ({
1316
className = '',
1417
columns = [{ name: 'name', label: 'Name' }],
1518
dropContextName,
16-
hoveredRowID,
17-
isDragging = false,
1819
isRowFocusable,
19-
loadingRowIDs,
20-
onDroppableHover,
21-
onEnter,
20+
loadingRowItemKeys,
21+
onDrop,
22+
// onEnter,
2223
onEscape,
23-
onRowDrag,
24+
onItemSelection,
2425
onSelectAll,
2526
openItemKeys,
2627
sections,
2728
segmentWidth = DEFAULT_SEGMENT_WIDTH,
2829
selectedItemKeys,
29-
targetParentID,
3030
toggleRowExpand,
3131
updateSelections,
3232
}) => {
@@ -36,9 +36,12 @@ export const NestedSectionsTable: React.FC<NestedSectionsTableProps> = ({
3636
const [firstCellWidth, setFirstCellWidth] = React.useState(0)
3737
const firstCellRef = React.useRef<HTMLDivElement>(null)
3838

39-
// Helper to count all visible rows (including nested)
40-
const countVisibleRows = React.useCallback(
41-
(rows: SectionRow[]): number => {
39+
const totalVisibleRows = React.useMemo(() => {
40+
if (!sections) {
41+
return 0
42+
}
43+
44+
const countVisibleRows = (rows: SectionRow[]): number => {
4245
let count = 0
4346
for (const row of rows) {
4447
count++
@@ -47,14 +50,10 @@ export const NestedSectionsTable: React.FC<NestedSectionsTableProps> = ({
4750
}
4851
}
4952
return count
50-
},
51-
[openItemKeys],
52-
)
53+
}
5354

54-
const totalVisibleRows = React.useMemo(
55-
() => (sections ? countVisibleRows(sections) : 0),
56-
[sections, countVisibleRows],
57-
)
55+
return countVisibleRows(sections)
56+
}, [sections, openItemKeys])
5857

5958
// Get row at a specific visible index
6059
const getRowAtVisibleIndex = React.useCallback(
@@ -241,11 +240,11 @@ export const NestedSectionsTable: React.FC<NestedSectionsTableProps> = ({
241240
break
242241
}
243242

244-
case 'Enter': {
245-
event.preventDefault()
246-
onEnter?.(row)
247-
break
248-
}
243+
// case 'Enter': {
244+
// event.preventDefault()
245+
// onEnter?.(row)
246+
// break
247+
// }
249248

250249
case 'Escape': {
251250
event.preventDefault()
@@ -277,14 +276,83 @@ export const NestedSectionsTable: React.FC<NestedSectionsTableProps> = ({
277276
totalVisibleRows,
278277
getRowAtVisibleIndex,
279278
isRowFocusable,
280-
onEnter,
279+
// onEnter,
281280
onEscape,
282281
onSelectAll,
283282
toggleRowExpand,
284283
onSelectionChange,
285284
],
286285
)
287286

287+
const onRowDrag = React.useCallback(
288+
({ event, item: dragItem }: { event: PointerEvent; item: null | SectionRow }) => {
289+
if (!dragItem) {
290+
return
291+
}
292+
293+
const isCurrentlySelected = selectedItemKeys.has(dragItem.itemKey)
294+
295+
if (!isCurrentlySelected) {
296+
onItemSelection({
297+
eventOptions: {
298+
ctrlKey: event.ctrlKey || event.metaKey,
299+
metaKey: event.ctrlKey || event.metaKey,
300+
shiftKey: event.shiftKey,
301+
},
302+
itemKey: dragItem.itemKey,
303+
})
304+
}
305+
},
306+
[selectedItemKeys, onItemSelection],
307+
)
308+
309+
const [isDragging, setIsDragging] = React.useState(false)
310+
const [hoveredRowItemKey, setHoveredRowItemKey] = React.useState<ItemKey | null>(null)
311+
const [targetParentID, setTargetParentID] = React.useState<null | number | string>(null)
312+
313+
const onDroppableHover = React.useCallback(
314+
({
315+
hoveredRowItemKey: newHoveredRowItemKey,
316+
targetItem,
317+
}: {
318+
hoveredRowItemKey?: ItemKey
319+
targetItem: null | SectionRow
320+
}) => {
321+
setHoveredRowItemKey(newHoveredRowItemKey || null)
322+
setTargetParentID(targetItem?.rowID || null)
323+
},
324+
[],
325+
)
326+
327+
useDndMonitor({
328+
onDragCancel() {
329+
setIsDragging(false)
330+
setHoveredRowItemKey(null)
331+
setTargetParentID(null)
332+
document.body.style.cursor = ''
333+
},
334+
onDragEnd(event) {
335+
setIsDragging(false)
336+
setHoveredRowItemKey(null)
337+
setTargetParentID(null)
338+
document.body.style.cursor = ''
339+
if (!event.over) {
340+
return
341+
}
342+
343+
if (
344+
event.over.data.current.type === 'tree-view-table' &&
345+
'targetItem' in event.over.data.current
346+
) {
347+
void onDrop({ targetItemKey: event.over.data.current.targetItem?.rowID })
348+
}
349+
},
350+
onDragStart() {
351+
setIsDragging(true)
352+
document.body.style.cursor = 'grabbing'
353+
},
354+
})
355+
288356
React.useEffect(() => {
289357
if (isDragging && firstCellRef.current) {
290358
const rect = firstCellRef.current.getBoundingClientRect()
@@ -328,9 +396,9 @@ export const NestedSectionsTable: React.FC<NestedSectionsTableProps> = ({
328396
firstCellWidth={firstCellWidth}
329397
firstCellXOffset={firstCellXOffset}
330398
focusedRowIndex={focusedRowIndex}
331-
hoveredRowID={hoveredRowID}
399+
hoveredRowItemKey={hoveredRowItemKey}
332400
isDragging={isDragging}
333-
loadingRowIDs={loadingRowIDs}
401+
loadingRowItemKeys={loadingRowItemKeys}
334402
onDroppableHover={onDroppableHover}
335403
onFocusChange={(index) => {
336404
// Convert index back to row ID

packages/ui/src/elements/TreeView/NestedSectionsTable/types.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,26 @@ export type NestedSectionsTableProps = {
1414
className?: string
1515
columns?: Column[]
1616
dropContextName: string
17-
hoveredRowID?: null | number | string
1817
initialOffset?: number
19-
isDragging?: boolean
2018
isRowFocusable: (row: SectionRow) => boolean
21-
loadingRowIDs?: Set<number | string>
22-
onDroppableHover: (params: {
23-
hoveredRowID?: number | string
24-
placement?: string
25-
targetItem: null | SectionRow
26-
}) => void
27-
onEnter: (row: SectionRow) => void
19+
loadingRowItemKeys?: Set<ItemKey>
20+
onDrop?: (params: { targetItemKey: ItemKey | null }) => Promise<void>
21+
// onEnter: (row: SectionRow) => void
2822
onEscape: () => void
23+
onItemSelection?: (args: {
24+
eventOptions: {
25+
ctrlKey: boolean
26+
metaKey: boolean
27+
shiftKey: boolean
28+
}
29+
itemKey: ItemKey
30+
}) => void
2931
onRowDrag?: (params: { event: PointerEvent; item: null | SectionRow }) => void
3032
onSelectAll: () => void
3133
openItemKeys?: Set<ItemKey>
3234
sections: SectionRow[]
3335
segmentWidth?: number
3436
selectedItemKeys: Set<ItemKey>
35-
targetParentID?: null | number | string
3637
toggleRowExpand: (docID: number | string) => void
3738
updateSelections: (args: { itemKeys: ItemKey[] | Set<ItemKey> }) => void
3839
}

0 commit comments

Comments
 (0)