Skip to content

Commit 3fd9370

Browse files
authored
Refactor setting of experiment table column order via drag and drop (#4479)
1 parent 92fcae5 commit 3fd9370

File tree

4 files changed

+65
-46
lines changed

4 files changed

+65
-46
lines changed

webview/src/experiments/components/Experiments.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,6 @@ export const ExperimentsTable: React.FC = () => {
145145
setColumns(getColumns(columnsData))
146146
}, [columnsData])
147147

148-
useEffect(() => {
149-
setColumnOrder(columnOrderData)
150-
}, [columnOrderData])
151-
152148
const getRowId = useCallback(
153149
(experiment: Commit, relativeIndex: number, parent?: TableRow<Commit>) =>
154150
parent ? [parent.id, experiment.id].join('.') : String(relativeIndex),
@@ -166,6 +162,7 @@ export const ExperimentsTable: React.FC = () => {
166162
getExpandedRowModel: getExpandedRowModel(),
167163
getRowId,
168164
getSubRows: row => row.subRows,
165+
onColumnOrderChange: setColumnOrder,
169166
onColumnSizingChange: setColumnSizing,
170167
onExpandedChange: setExpanded,
171168
state: {
@@ -188,7 +185,7 @@ export const ExperimentsTable: React.FC = () => {
188185
}
189186
return (
190187
<RowSelectionProvider>
191-
<Table instance={instance} onColumnOrderChange={setColumnOrder} />
188+
<Table instance={instance} />
192189
{!hasConfig && <AddStage />}
193190
</RowSelectionProvider>
194191
)

webview/src/experiments/components/table/Table.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
import React, { useRef, useState, CSSProperties, useContext } from 'react'
2-
import { ColumnOrderState } from '@tanstack/react-table'
32
import cx from 'classnames'
43
import styles from './styles.module.scss'
54
import { TableHead } from './header/TableHead'
65
import { RowSelectionContext } from './RowSelectionContext'
76
import { TableContent } from './body/TableContent'
87
import { InstanceProp } from '../../util/interfaces'
98

10-
interface TableProps extends InstanceProp {
11-
onColumnOrderChange: (order: ColumnOrderState) => void
12-
}
13-
14-
export const Table: React.FC<TableProps> = ({
15-
instance,
16-
onColumnOrderChange
17-
}) => {
9+
export const Table: React.FC<InstanceProp> = ({ instance }) => {
1810
const { clearSelectedRows } = useContext(RowSelectionContext)
1911
const [expColumnNeedsShadow, setExpColumnNeedsShadow] = useState(false)
2012
const [tableHeadHeight, setTableHeadHeight] = useState(55)
@@ -44,7 +36,6 @@ export const Table: React.FC<TableProps> = ({
4436
root={tableRef.current}
4537
setExpColumnNeedsShadow={setExpColumnNeedsShadow}
4638
setTableHeadHeight={setTableHeadHeight}
47-
onOrderChange={onColumnOrderChange}
4839
/>
4940
<TableContent
5041
instance={instance}

webview/src/experiments/components/table/header/TableHead.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Experiment } from 'dvc/src/experiments/webview/contract'
22
import React, { DragEvent, useRef, useEffect } from 'react'
33
import { useSelector, useDispatch } from 'react-redux'
4-
import { Table, Header, ColumnOrderState } from '@tanstack/react-table'
4+
import { Table, Header } from '@tanstack/react-table'
55
import { MergedHeaderGroups } from './MergeHeaderGroups'
66
import { setDropTarget } from '../../../state/headerDropTargetSlice'
77
import { ExperimentsState } from '../../../store'
@@ -17,15 +17,13 @@ import { reorderColumns } from '../../../util/messages'
1717
interface TableHeadProps {
1818
instance: Table<Experiment>
1919
root: HTMLElement | null
20-
onOrderChange: (order: ColumnOrderState) => void
2120
setExpColumnNeedsShadow: (needsShadow: boolean) => void
2221
setTableHeadHeight: (height: number) => void
2322
}
2423

2524
export const TableHead = ({
2625
instance,
2726
root,
28-
onOrderChange,
2927
setExpColumnNeedsShadow,
3028
setTableHeadHeight
3129
}: TableHeadProps) => {
@@ -110,7 +108,6 @@ export const TableHead = ({
110108
setColumnOrder(newOrder)
111109
reorderColumns(newOrder)
112110
onDragEnd()
113-
onOrderChange(newOrder)
114111
}
115112
}
116113

webview/src/experiments/util/columns.ts

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,78 @@ import { Header } from '@tanstack/react-table'
33

44
export const isFirstLevelHeader = (id: string) => id.split(':').length - 1 === 1
55

6-
export const reorderColumnIds = (
7-
columnIds: string[],
8-
displacer: string[],
6+
type OrderAccumulator = { newOrder: string[]; firstDroppedFound: boolean }
7+
8+
const addDroppedAndDisplaced = (
9+
acc: OrderAccumulator,
10+
dropped: string[],
911
displaced: string[]
1012
) => {
11-
if (columnIds.length === 0 || displacer[0] === displaced[0]) {
12-
return columnIds
13+
const droppedStartedLeftOfDisplaced = acc.firstDroppedFound
14+
const order = droppedStartedLeftOfDisplaced
15+
? [...displaced, ...dropped]
16+
: [...dropped, ...displaced]
17+
acc.newOrder.push(...order)
18+
}
19+
20+
const collectId = (
21+
acc: OrderAccumulator,
22+
columnId: string,
23+
dropped: string[],
24+
displaced: string[]
25+
) => {
26+
if (columnId === displaced[0]) {
27+
addDroppedAndDisplaced(acc, dropped, displaced)
28+
return
29+
}
30+
if (displaced.includes(columnId)) {
31+
return
1332
}
33+
if (dropped.includes(columnId)) {
34+
acc.firstDroppedFound = true
35+
return
36+
}
37+
38+
acc.newOrder.push(columnId)
39+
}
1440

15-
const displacerIndex = columnIds.indexOf(displacer[0])
16-
const displacedIndex = columnIds.indexOf(displaced[0])
17-
18-
if (displacerIndex < displacedIndex) {
19-
return [
20-
...columnIds.slice(0, displacerIndex),
21-
...columnIds.slice(displacerIndex + displacer.length, displacedIndex),
22-
...displaced,
23-
...displacer,
24-
...columnIds.slice(displacedIndex + displaced.length)
25-
]
41+
const collectNewOrder = (
42+
columnIds: string[],
43+
dropped: string[],
44+
displaced: string[]
45+
): string[] => {
46+
const acc: OrderAccumulator = {
47+
firstDroppedFound: false,
48+
newOrder: []
2649
}
50+
for (const columnId of columnIds) {
51+
collectId(acc, columnId, dropped, displaced)
52+
}
53+
return acc.newOrder
54+
}
2755

28-
return [
29-
...columnIds.slice(0, displacedIndex),
30-
...displacer,
31-
...displaced,
32-
...columnIds.slice(displacedIndex + displaced.length, displacerIndex),
33-
...columnIds.slice(displacerIndex + displacer.length)
34-
]
56+
export const reorderColumnIds = (
57+
columnIds: string[],
58+
dropped: string[],
59+
displaced: string[]
60+
) => {
61+
if (columnIds.length === 0 || dropped[0] === displaced[0]) {
62+
return columnIds
63+
}
64+
return collectNewOrder(columnIds, dropped, displaced)
3565
}
3666

3767
export const leafColumnIds = (
3868
header: Header<Experiment, unknown>
3969
): string[] => {
40-
return header
41-
.getLeafHeaders()
42-
.filter(h => h.subHeaders.length === 0)
43-
.map(h => h.column.id)
70+
const leafColumnIds: string[] = []
71+
for (const headers of header.getLeafHeaders()) {
72+
if (headers.subHeaders.length > 0) {
73+
continue
74+
}
75+
leafColumnIds.push(headers.column.id)
76+
}
77+
return leafColumnIds
4478
}
4579

4680
export const EXPERIMENT_COLUMN_ID = 'id'

0 commit comments

Comments
 (0)