diff --git a/webview/src/experiments/components/App.test.tsx b/webview/src/experiments/components/App.test.tsx index 61f0b917c2..836844c996 100644 --- a/webview/src/experiments/components/App.test.tsx +++ b/webview/src/experiments/components/App.test.tsx @@ -1584,136 +1584,178 @@ describe('App', () => { expect(sortIndicator).toHaveTextContent('2') jest.useRealTimers() }) - }) - it('should show an indicator with the amount of applied filters', () => { - renderTable({ - ...tableDataFixture, - filters: [] - }) - jest.useFakeTimers() - const filterIndicator = screen.getByLabelText('filters') - expect(filterIndicator).toHaveTextContent('') + it('should show an indicator with the amount of applied filters', () => { + renderTable({ + ...tableDataFixture, + filters: [] + }) + jest.useFakeTimers() + const filterIndicator = screen.getByLabelText('filters') + expect(filterIndicator).toHaveTextContent('') - expect(screen.queryByRole('tooltip')).not.toBeInTheDocument() + expect(screen.queryByRole('tooltip')).not.toBeInTheDocument() - fireEvent.mouseEnter(filterIndicator) - advanceTimersByTime(1000) + fireEvent.mouseEnter(filterIndicator) + advanceTimersByTime(1000) - const tooltip = screen.getByRole('tooltip') + const tooltip = screen.getByRole('tooltip') - expect(tooltip).toHaveTextContent('Show Filters') + expect(tooltip).toHaveTextContent('Show Filters') - const { columns } = tableDataFixture - const firstFilterPath = columns[columns.length - 1].path - const secondFilterPath = columns[columns.length - 2].path - setTableData({ - ...tableDataFixture, - filters: [firstFilterPath] - }) - expect(filterIndicator).toHaveTextContent('1') + const { columns } = tableDataFixture + const firstFilterPath = columns[columns.length - 1].path + const secondFilterPath = columns[columns.length - 2].path + setTableData({ + ...tableDataFixture, + filters: [firstFilterPath] + }) + expect(filterIndicator).toHaveTextContent('1') - setTableData({ - ...tableDataFixture, - filters: [firstFilterPath, secondFilterPath] - }) - expect(filterIndicator).toHaveTextContent('2') + setTableData({ + ...tableDataFixture, + filters: [firstFilterPath, secondFilterPath] + }) + expect(filterIndicator).toHaveTextContent('2') - setTableData({ - ...tableDataFixture, - filters: [firstFilterPath, secondFilterPath] - }) - expect(filterIndicator).toHaveTextContent('2') + setTableData({ + ...tableDataFixture, + filters: [firstFilterPath, secondFilterPath] + }) + expect(filterIndicator).toHaveTextContent('2') - setTableData({ - ...tableDataFixture, - filters: [] + setTableData({ + ...tableDataFixture, + filters: [] + }) + expect(filterIndicator).toHaveTextContent('') + expect(tooltip).not.toHaveTextContent('Experiment') + jest.useRealTimers() }) - expect(filterIndicator).toHaveTextContent('') - expect(tooltip).not.toHaveTextContent('Experiment') - jest.useRealTimers() - }) - it('should show a tooltip for the branches indicator', () => { - renderTable({ - ...tableDataFixture - }) - jest.useFakeTimers() - const branchesIndicator = screen.getByLabelText('branches') - expect(branchesIndicator).toHaveTextContent('') + it('should show a tooltip for the branches indicator', () => { + renderTable({ + ...tableDataFixture + }) + jest.useFakeTimers() + const branchesIndicator = screen.getByLabelText('branches') + expect(branchesIndicator).toHaveTextContent('') - expect(screen.queryByRole('tooltip')).not.toBeInTheDocument() + expect(screen.queryByRole('tooltip')).not.toBeInTheDocument() - fireEvent.mouseEnter(branchesIndicator) - advanceTimersByTime(1000) + fireEvent.mouseEnter(branchesIndicator) + advanceTimersByTime(1000) - const tooltip = screen.getByRole('tooltip') + const tooltip = screen.getByRole('tooltip') - expect(tooltip).toHaveTextContent('Select Branches') - jest.useRealTimers() - }) + expect(tooltip).toHaveTextContent('Select Branches') + jest.useRealTimers() + }) - it('should show an indicator for the number of branches selected', () => { - const branches = ['main', 'other', 'third'] + it('should show an indicator for the number of branches selected', () => { + const branches = ['main', 'other', 'third'] - let workspace - const rowsWithoutWorkspace = [] - for (const row of tableDataFixture.rows) { - if (row.id !== EXPERIMENT_WORKSPACE_ID) { - rowsWithoutWorkspace.push(row) - continue + let workspace + const rowsWithoutWorkspace = [] + for (const row of tableDataFixture.rows) { + if (row.id !== EXPERIMENT_WORKSPACE_ID) { + rowsWithoutWorkspace.push(row) + continue + } + workspace = row } - workspace = row - } - const multipleBranches = { - ...tableDataFixture, - branches, - hasData: true, - rows: [ - workspace as Commit, - ...rowsWithoutWorkspace.map(row => ({ - ...row, - branch: branches[0], - subRows: undefined - })), - ...rowsWithoutWorkspace.map(row => ({ - ...row, - branch: branches[1], - subRows: undefined - })), - ...rowsWithoutWorkspace.map(row => ({ - ...row, - branch: branches[2], - subRows: undefined - })) - ] - } + const multipleBranches = { + ...tableDataFixture, + branches, + hasData: true, + rows: [ + workspace as Commit, + ...rowsWithoutWorkspace.map(row => ({ + ...row, + branch: branches[0], + subRows: undefined + })), + ...rowsWithoutWorkspace.map(row => ({ + ...row, + branch: branches[1], + subRows: undefined + })), + ...rowsWithoutWorkspace.map(row => ({ + ...row, + branch: branches[2], + subRows: undefined + })) + ] + } - renderTable(multipleBranches) + renderTable(multipleBranches) - const [indicator] = screen.getAllByLabelText('branches') + const [indicator] = screen.getAllByLabelText('branches') - expect(indicator).toHaveTextContent(`${branches.length - 1}`) - }) + expect(indicator).toHaveTextContent(`${branches.length - 1}`) + }) - it('should send a message to focus the relevant tree when clicked', () => { - renderTable() - mockPostMessage.mockClear() - fireEvent.click(screen.getByLabelText('sorts')) - expect(mockPostMessage).toHaveBeenCalledWith({ - type: MessageFromWebviewType.FOCUS_SORTS_TREE + it('should send a message to focus the relevant tree when clicked', () => { + renderTable() + mockPostMessage.mockClear() + fireEvent.click(screen.getByLabelText('sorts')) + expect(mockPostMessage).toHaveBeenCalledWith({ + type: MessageFromWebviewType.FOCUS_SORTS_TREE + }) + mockPostMessage.mockClear() + fireEvent.click(screen.getByLabelText('filters')) + expect(mockPostMessage).toHaveBeenCalledWith({ + type: MessageFromWebviewType.FOCUS_FILTERS_TREE + }) + + mockPostMessage.mockClear() + fireEvent.click(screen.getByLabelText('selected for plots')) + expect(mockPostMessage).toHaveBeenCalledWith({ + type: MessageFromWebviewType.OPEN_PLOTS_WEBVIEW + }) }) - mockPostMessage.mockClear() - fireEvent.click(screen.getByLabelText('filters')) - expect(mockPostMessage).toHaveBeenCalledWith({ - type: MessageFromWebviewType.FOCUS_FILTERS_TREE + + it('should show an indicator with the amount of displayed columns', () => { + renderTable({ + ...tableDataFixture + }) + jest.useFakeTimers() + const columnsIndicator = screen.getByLabelText('columns') + expect(columnsIndicator).toHaveTextContent('22') + + expect(screen.queryByRole('tooltip')).not.toBeInTheDocument() + + fireEvent.mouseEnter(columnsIndicator) + advanceTimersByTime(1000) + const tooltip = screen.getByRole('tooltip') + + expect(tooltip).toHaveTextContent('Select Columns') + + setTableData({ + ...tableDataFixture, + columns: tableDataFixture.columns.slice(1) + }) + + expect(columnsIndicator).toHaveTextContent('21') + + setTableData({ + ...tableDataFixture, + columns: [] + }) + + expect(columnsIndicator).toHaveTextContent('') + + jest.useRealTimers() }) - mockPostMessage.mockClear() - fireEvent.click(screen.getByLabelText('selected for plots')) - expect(mockPostMessage).toHaveBeenCalledWith({ - type: MessageFromWebviewType.OPEN_PLOTS_WEBVIEW + it('should send a message to select columns when the select columns icon is clicked', () => { + renderTable() + mockPostMessage.mockClear() + fireEvent.click(screen.getByLabelText('columns')) + expect(mockPostMessage).toHaveBeenCalledWith({ + type: MessageFromWebviewType.SELECT_COLUMNS + }) }) }) diff --git a/webview/src/experiments/components/table/Indicators.tsx b/webview/src/experiments/components/table/Indicators.tsx index e0e3e26159..60c312d481 100644 --- a/webview/src/experiments/components/table/Indicators.tsx +++ b/webview/src/experiments/components/table/Indicators.tsx @@ -6,13 +6,15 @@ import { focusFiltersTree, focusSortsTree, openPlotsWebview, - selectBranches + selectBranches, + selectColumns } from '../../util/messages' import { Icon } from '../../../shared/components/Icon' import { Filter, GitMerge, GraphScatter, + ListFilter, SortPrecedence } from '../../../shared/components/icons' import { ExperimentsState } from '../../store' @@ -72,21 +74,30 @@ export const Indicators = () => { const filters = useSelector( (state: ExperimentsState) => state.tableData.filters ) + const filtersCount = filters?.length + const sorts = useSelector((state: ExperimentsState) => state.tableData.sorts) + const sortsCount = sorts?.length + const selectedForPlotsCount = useSelector( (state: ExperimentsState) => state.tableData.selectedForPlotsCount ) + const branchesSelected = useSelector( (state: ExperimentsState) => Math.max(state.tableData.branches.filter(Boolean).length - 1, 0) // We always have one branch by default (the current one which is not selected) and undefined for the workspace ) - const { hasBranchesToSelect } = useSelector( (state: ExperimentsState) => state.tableData ) - const sortsCount = sorts?.length - const filtersCount = filters?.length + const columnsSelected = useSelector( + (state: ExperimentsState) => + state.tableData.columns.filter(({ hasChildren }) => !hasChildren).length + ) + const hasColumns = useSelector( + (state: ExperimentsState) => state.tableData.hasColumns + ) return (
@@ -123,6 +134,15 @@ export const Indicators = () => { > + + +
) }