Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redux for experiments table drag and drop #2097

Merged
merged 10 commits into from
Jul 26, 2022
9 changes: 3 additions & 6 deletions webview/src/experiments/components/Experiments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import buildDynamicColumns from '../util/buildDynamicColumns'
import { sendMessage } from '../../shared/vscode'
import { WebviewWrapper } from '../../shared/components/webviewWrapper/WebviewWrapper'
import { GetStarted } from '../../shared/components/getStarted/GetStarted'
import { DragDropProvider } from '../../shared/components/dragDrop/DragDropContext'
import { EmptyState } from '../../shared/components/emptyState/EmptyState'

const DEFAULT_COLUMN_WIDTH = 90
Expand Down Expand Up @@ -224,11 +223,9 @@ export const ExperimentsTable: React.FC<{
}

return (
<DragDropProvider>
<RowSelectionProvider>
<Table instance={instance} tableData={tableData} />
</RowSelectionProvider>
</DragDropProvider>
<RowSelectionProvider>
<Table instance={instance} tableData={tableData} />
</RowSelectionProvider>
)
}

Expand Down
27 changes: 21 additions & 6 deletions webview/src/experiments/components/table/Table.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
*/
/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "expectHeaders"] }] */
import '@testing-library/jest-dom/extend-expect'
import { configureStore } from '@reduxjs/toolkit'
import {
cleanup,
fireEvent,
queries,
render,
screen
} from '@testing-library/react'
import { Provider } from 'react-redux'
import { Experiment, TableData } from 'dvc/src/experiments/webview/contract'
import { MessageFromWebviewType } from 'dvc/src/webview/contract'
import React from 'react'
Expand All @@ -20,7 +22,6 @@ import { Table } from './Table'
import styles from './styles.module.scss'
import { ExperimentsTable } from '../Experiments'
import * as ColumnOrder from '../../hooks/useColumnOrder'

import { vsCodeApi } from '../../../shared/api'
import {
expectHeaders,
Expand All @@ -29,6 +30,7 @@ import {
} from '../../../test/sort'
import { dragAndDrop } from '../../../test/dragDrop'
import { DragEnterDirection } from '../../../shared/components/dragDrop/util'
import { experimentsReducers } from '../../store'
import { customQueries } from '../../../test/queries'

jest.mock('../../../shared/api')
Expand Down Expand Up @@ -123,14 +125,23 @@ describe('Table', () => {
}
const renderTable = (testData = {}, tableInstance = instance) => {
const tableData = { ...dummyTableData, ...testData }
return render(<Table instance={tableInstance} tableData={tableData} />)
return render(
<Provider store={configureStore({ reducer: experimentsReducers })}>
<Table instance={tableInstance} tableData={tableData} />
</Provider>
)
}
const renderExperimentsTable = (
data: TableData = sortingTableDataFixture
) => {
return render(<ExperimentsTable tableData={data} />, {
queries: { ...queries, ...customQueries }
})
return render(
<Provider store={configureStore({ reducer: experimentsReducers })}>
<ExperimentsTable tableData={data} />
</Provider>,
{
queries: { ...queries, ...customQueries }
}
)
}

beforeAll(() => {
Expand Down Expand Up @@ -335,7 +346,11 @@ describe('Table', () => {
...sortingTableDataFixture,
columnWidths
}
render(<ExperimentsTable tableData={tableDataWithColumnSetting} />)
render(
<Provider store={configureStore({ reducer: experimentsReducers })}>
<ExperimentsTable tableData={tableDataWithColumnSetting} />
</Provider>
)
const [experimentColumnResizeHandle] = await screen.findAllByRole(
'separator'
)
Expand Down
8 changes: 7 additions & 1 deletion webview/src/experiments/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import { Provider } from 'react-redux'
import '../shared/style.scss'
import { App } from './components/App'
import { experimentsStore } from './store'

const root = ReactDOM.createRoot(document.querySelector('#root') as HTMLElement)
root.render(<App />)
root.render(
<Provider store={experimentsStore}>
<App />
</Provider>
)
13 changes: 13 additions & 0 deletions webview/src/experiments/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { configureStore } from '@reduxjs/toolkit'
import dragAndDropReducer from '../shared/components/dragDrop/dragDropSlice'

export const experimentsReducers = {
dragAndDrop: dragAndDropReducer
}

export const experimentsStore = configureStore({
reducer: experimentsReducers
})

export type ExperimentsState = ReturnType<typeof experimentsStore.getState>
export type ExperimentsDispatch = typeof experimentsStore.dispatch
4 changes: 2 additions & 2 deletions webview/src/plots/components/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { act } from 'react-dom/test-utils'
import { App } from './App'
import { NewSectionBlock } from './templatePlots/TemplatePlots'
import { SectionDescription } from './PlotsContainer'
import { storeReducers } from '../store'
import { plotsReducers } from '../store'
import { vsCodeApi } from '../../shared/api'
import { createBubbledEvent, dragAndDrop, dragEnter } from '../../test/dragDrop'
import { DragEnterDirection } from '../../shared/components/dragDrop/util'
Expand Down Expand Up @@ -113,7 +113,7 @@ describe('App', () => {
}

const renderAppWithOptionalData = (data?: PlotsData) => {
const store = configureStore({ reducer: storeReducers })
const store = configureStore({ reducer: plotsReducers })
render(
<Provider store={store}>
<App />
Expand Down
6 changes: 3 additions & 3 deletions webview/src/plots/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ import {
updateHasSelectedPlots,
updateSelectedRevisions
} from './webviewSlice'
import { AppDispatch } from '../store'
import { PlotsDispatch } from '../store'
import { useVsCodeMessaging } from '../../shared/hooks/useVsCodeMessaging'

const dispatchCollapsedSections = (
sections: SectionCollapsed,
dispatch: AppDispatch
dispatch: PlotsDispatch
) => {
if (sections) {
dispatch(setCheckpointPlotsCollapsed(sections[Section.CHECKPOINT_PLOTS]))
Expand All @@ -46,7 +46,7 @@ const dispatchCollapsedSections = (

export const feedStore = (
data: MessageToWebview<PlotsData>,
dispatch: AppDispatch
dispatch: PlotsDispatch
// eslint-disable-next-line sonarjs/cognitive-complexity
) => {
if (data.data) {
Expand Down
10 changes: 5 additions & 5 deletions webview/src/plots/components/Plots.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { EmptyState } from '../../shared/components/emptyState/EmptyState'
import { Modal } from '../../shared/components/modal/Modal'
import { WebviewWrapper } from '../../shared/components/webviewWrapper/WebviewWrapper'
import { GetStarted } from '../../shared/components/getStarted/GetStarted'
import { RootState } from '../store'
import { PlotsState } from '../store'

// eslint-disable-next-line sonarjs/cognitive-complexity
const PlotsContent = () => {
Expand All @@ -22,15 +22,15 @@ const PlotsContent = () => {
hasSelectedPlots,
selectedRevisions,
zoomedInPlot
} = useSelector((state: RootState) => state.webview)
} = useSelector((state: PlotsState) => state.webview)
const hasCheckpointData = useSelector(
(state: RootState) => state.checkpoint.hasData
(state: PlotsState) => state.checkpoint.hasData
)
const hasComparisonData = useSelector(
(state: RootState) => state.comparison.hasData
(state: PlotsState) => state.comparison.hasData
)
const hasTemplateData = useSelector(
(state: RootState) => state.template.hasData
(state: PlotsState) => state.template.hasData
)

if (!hasData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ZoomablePlot } from '../ZoomablePlot'
import styles from '../styles.module.scss'
import { withScale } from '../../../util/styles'
import { plotDataStore } from '../plotDataStore'
import { RootState } from '../../store'
import { PlotsState } from '../../store'

interface CheckpointPlotProps {
id: string
Expand All @@ -18,7 +18,7 @@ export const CheckpointPlot: React.FC<CheckpointPlotProps> = ({
colors
}) => {
const plotSnapshot = useSelector(
(state: RootState) => state.checkpoint.plotsSnapshots[id]
(state: PlotsState) => state.checkpoint.plotsSnapshots[id]
)
const [plot, setPlot] = useState(plotDataStore.checkpoint[id])
const spec = useMemo(() => (id && createSpec(id, colors)) || {}, [id, colors])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { DropTarget } from '../DropTarget'
import { VirtualizedGrid } from '../../../shared/components/virtualizedGrid/VirtualizedGrid'
import { shouldUseVirtualizedGrid } from '../util'
import { useNbItemsPerRow } from '../../hooks/useNbItemsPerRow'
import { RootState } from '../../store'
import { PlotsState } from '../../store'

interface CheckpointPlotsProps {
plotsIds: string[]
Expand All @@ -28,7 +28,7 @@ export const CheckpointPlots: React.FC<CheckpointPlotsProps> = ({
colors
}) => {
const [order, setOrder] = useState(plotsIds)
const { size } = useSelector((state: RootState) => state.checkpoint)
const { size } = useSelector((state: PlotsState) => state.checkpoint)
const nbItemsPerRow = useNbItemsPerRow(size)

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { CheckpointPlots } from './CheckpointPlots'
import { changeSize } from './checkpointPlotsSlice'
import { PlotsContainer } from '../PlotsContainer'
import { sendMessage } from '../../../shared/vscode'
import { RootState } from '../../store'
import { PlotsState } from '../../store'

export const CheckpointPlotsWrapper: React.FC = () => {
const dispatch = useDispatch()
const { plotsIds, size, selectedMetrics, isCollapsed, colors } = useSelector(
(state: RootState) => state.checkpoint
(state: PlotsState) => state.checkpoint
)
const [metrics, setMetrics] = useState<string[]>([])
const [selectedPlots, setSelectedPlots] = useState<string[]>([])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
} from '../../../test/dragDrop'
import { vsCodeApi } from '../../../shared/api'
import { DragEnterDirection } from '../../../shared/components/dragDrop/util'
import { storeReducers } from '../../store'
import { plotsReducers } from '../../store'
import { webviewInitialState } from '../webviewSlice'

const getHeaders = () => screen.getAllByRole('columnheader')
Expand Down Expand Up @@ -70,7 +70,7 @@ describe('ComparisonTable', () => {
zoomedInPlot: undefined
}
},
reducer: storeReducers
reducer: plotsReducers
})}
>
<ComparisonTable />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import {
import plotsStyles from '../styles.module.scss'
import { withScale } from '../../../util/styles'
import { sendMessage } from '../../../shared/vscode'
import { RootState } from '../../store'
import { PlotsState } from '../../store'

export const ComparisonTable: React.FC = () => {
const { plots } = useSelector((state: RootState) => state.comparison)
const { plots } = useSelector((state: PlotsState) => state.comparison)

const { selectedRevisions: revisions } = useSelector(
(state: RootState) => state.webview
(state: PlotsState) => state.webview
)

const pinnedColumn = useRef('')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import styles from './styles.module.scss'
import { DropTarget } from './DropTarget'
import { ComparisonTableHeader } from './ComparisonTableHeader'
import { DragDropContainer } from '../../../shared/components/dragDrop/DragDropContainer'
import { RootState } from '../../store'
import { PlotsState } from '../../store'

export type ComparisonTableColumn = Revision

Expand All @@ -24,7 +24,7 @@ export const ComparisonTableHead: React.FC<ComparisonTableHeadProps> = ({
setPinnedColumn
}) => {
const draggedId = useSelector(
(state: RootState) => state.dragAndDrop.draggedRef?.itemId
(state: PlotsState) => state.dragAndDrop.draggedRef?.itemId
)

const items = columns.map(({ revision, displayColor, group }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
ComparisonTableRowProps
} from './ComparisonTableRow'
import styles from '../styles.module.scss'
import { storeReducers } from '../../store'
import { plotsReducers } from '../../store'

jest.mock('../../../shared/api')

Expand All @@ -37,7 +37,7 @@ describe('ComparisonTableRow', () => {
render(
<Provider
store={configureStore({
reducer: storeReducers
reducer: plotsReducers
})}
>
<table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Icon } from '../../../shared/components/Icon'
import { RefreshButton } from '../../../shared/components/button/RefreshButton'
import { sendMessage } from '../../../shared/vscode'
import { ChevronDown, ChevronRight } from '../../../shared/components/icons'
import { RootState } from '../../store'
import { PlotsState } from '../../store'

export interface ComparisonTableRowProps {
path: string
Expand All @@ -24,7 +24,7 @@ export const ComparisonTableRow: React.FC<ComparisonTableRowProps> = ({
pinnedColumn
}) => {
const draggedId = useSelector(
(state: RootState) => state.dragAndDrop.draggedRef?.itemId
(state: PlotsState) => state.dragAndDrop.draggedRef?.itemId
)
const [isShown, setIsShown] = useState(true)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { useSelector, useDispatch } from 'react-redux'
import { ComparisonTable } from './ComparisonTable'
import { changeSize } from './comparisonTableSlice'
import { PlotsContainer } from '../PlotsContainer'
import { RootState } from '../../store'
import { PlotsState } from '../../store'

export const ComparisonTableWrapper: React.FC = () => {
const dispatch = useDispatch()
const { size, isCollapsed } = useSelector(
(state: RootState) => state.comparison
(state: PlotsState) => state.comparison
)
const handleResize = (size: PlotSize) => {
dispatch(changeSize(size))
Expand Down
4 changes: 2 additions & 2 deletions webview/src/plots/components/ribbon/Ribbon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { RibbonBlock } from './RibbonBlock'
import { sendMessage } from '../../../shared/vscode'
import { IconButton } from '../../../shared/components/button/IconButton'
import { performOrderedUpdate } from '../../../util/objects'
import { RootState } from '../../store'
import { PlotsState } from '../../store'
import { Lines, Refresh } from '../../../shared/components/icons'

const MAX_NB_EXP = 7

export const Ribbon: React.FC = () => {
const revisions = useSelector(
(state: RootState) => state.webview.selectedRevisions
(state: PlotsState) => state.webview.selectedRevisions
)
const [order, setOrder] = useState<string[]>([])
const reorderId = 'id'
Expand Down
4 changes: 2 additions & 2 deletions webview/src/plots/components/templatePlots/AddedSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import cx from 'classnames'
import { TemplatePlotSection } from 'dvc/src/plots/webview/contract'
import styles from '../styles.module.scss'
import { getIDWithoutIndex } from '../../../util/ids'
import { RootState } from '../../store'
import { PlotsState } from '../../store'
import { Icon } from '../../../shared/components/Icon'
import { GraphLine } from '../../../shared/components/icons'

Expand All @@ -25,7 +25,7 @@ export const AddedSection: React.FC<AddedSectionProps> = ({
closestSection,
acceptedGroups
}) => {
const { draggedRef } = useSelector((state: RootState) => state.dragAndDrop)
const { draggedRef } = useSelector((state: PlotsState) => state.dragAndDrop)
const handleDragLeave = () => {
setHoveredSection('')
}
Expand Down
Loading