From a90f608b1612ea906372041a533582aa13aded0a Mon Sep 17 00:00:00 2001 From: Oleksandr Dubenko Date: Mon, 9 Dec 2024 11:13:33 +0100 Subject: [PATCH] frontend Table: Add support for column selection Co-authored-by: farodin91 Signed-off-by: Oleksandr Dubenko --- ...ttings.DefaultSaveEnable.stories.storyshot | 17 ++- ...tings.EmptyHomepageItems.stories.storyshot | 17 ++- .../PluginSettings.FewItems.stories.storyshot | 17 ++- ...PluginSettings.ManyItems.stories.storyshot | 47 ++++--- ...PluginSettings.MoreItems.stories.storyshot | 47 ++++--- ...ListView.OneHiddenColumn.stories.storyshot | 17 ++- ...ResourceTable.NameSearch.stories.storyshot | 14 ++- .../ResourceTable.NoFilter.stories.storyshot | 14 ++- ...urceTable.WithHiddenCols.stories.storyshot | 14 ++- .../src/components/common/Table/Table.tsx | 118 +++++++++++++----- .../Table.Datum.stories.storyshot | 11 +- .../Table.Getter.stories.storyshot | 11 +- .../Table.LabelSearch.stories.storyshot | 14 ++- .../Table.NameSearch.stories.storyshot | 14 ++- .../Table.NamespaceSearch.stories.storyshot | 14 ++- .../Table.NamespaceSelect.stories.storyshot | 8 +- .../Table.NotFoundMessage.stories.storyshot | 14 ++- .../Table.NumberSearch.stories.storyshot | 14 ++- .../Table.ReflectInURL.stories.storyshot | 17 ++- ...e.ReflectInURLWithPrefix.stories.storyshot | 17 ++- .../Table.UIDSearch.stories.storyshot | 14 ++- ...le.WithFilterMultiSelect.stories.storyshot | 14 ++- .../Table.WithGlobalFilter.stories.storyshot | 2 +- .../Table.WithSorting.stories.storyshot | 14 ++- .../List.Items.stories.storyshot | 8 +- ...sourceDefinition.Details.stories.storyshot | 8 +- ...mResourceDefinition.List.stories.storyshot | 5 +- .../CustomResourceList.List.stories.storyshot | 8 +- .../List.DaemonSets.stories.storyshot | 5 +- .../EndpointList.Items.stories.storyshot | 5 +- .../HPAList.Items.stories.storyshot | 5 +- .../ClassList.Items.stories.storyshot | 8 +- .../List.Items.stories.storyshot | 8 +- .../JobList.Items.stories.storyshot | 14 ++- .../List.Items.stories.storyshot | 5 +- .../List.Items.stories.storyshot | 5 +- .../NamespaceList.Regular.stories.storyshot | 5 +- .../List.Nodes.stories.storyshot | 8 +- .../PodList.Items.stories.storyshot | 26 ++-- .../pdbList.Items.stories.storyshot | 5 +- .../priorityClassList.Items.stories.storyshot | 5 +- .../List.ReplicaSets.stories.storyshot | 8 +- .../resourceQuotaList.Items.stories.storyshot | 5 +- .../List.Items.stories.storyshot | 5 +- .../List.Items.stories.storyshot | 8 +- .../ClaimList.Items.stories.storyshot | 11 +- .../ClassList.Items.stories.storyshot | 5 +- .../VolumeList.Items.stories.storyshot | 5 +- .../VPAList.List.stories.storyshot | 5 +- ...gWebhookConfigList.Items.stories.storyshot | 20 +-- ...gWebhookConfigList.Items.stories.storyshot | 20 +-- 51 files changed, 477 insertions(+), 248 deletions(-) diff --git a/frontend/src/components/App/PluginSettings/__snapshots__/PluginSettings.DefaultSaveEnable.stories.storyshot b/frontend/src/components/App/PluginSettings/__snapshots__/PluginSettings.DefaultSaveEnable.stories.storyshot index 6a73a92441..7702abea12 100644 --- a/frontend/src/components/App/PluginSettings/__snapshots__/PluginSettings.DefaultSaveEnable.stories.storyshot +++ b/frontend/src/components/App/PluginSettings/__snapshots__/PluginSettings.DefaultSaveEnable.stories.storyshot @@ -27,7 +27,7 @@ class="MuiBox-root css-1txv3mw" >
> = Omit< * Whether to show a loading spinner */ loading?: boolean; + renderRowSelectionToolbar?: (props: { table: MRT_TableInstance }) => ReactNode; }; // Use a zero-indexed "useURLState" hook, so pages are shown in the URL as 1-indexed @@ -136,7 +137,12 @@ const StyledHeadRow = styled('tr')(({ theme }) => ({ display: 'contents', background: theme.palette.tables.head.background, })); -const StyledRow = styled('tr')({ display: 'contents' }); +const StyledRow = styled('tr')(({ theme }) => ({ + display: 'contents', + '&[data-selected=true]': { + background: alpha(theme.palette.primary.main, 0.2), + }, +})); const StyledBody = styled('tbody')({ display: 'contents' }); /** @@ -185,18 +191,33 @@ export default function Table>({ return (tableProps.data ?? []).filter(it => filterFunction(it)); }, [tableProps.data, filterFunction]); - const gridTemplateColumns = tableProps.columns - .filter(it => { - const isHidden = tableProps.state?.columnVisibility?.[it.id!] === false; - return !isHidden; - }) - .map(it => { - if (typeof it.gridTemplate === 'number') { - return `${it.gridTemplate}fr`; - } - return it.gridTemplate ?? '1fr'; - }) - .join(' '); + const gridTemplateColumns = useMemo(() => { + let preGridTemplateColumns = tableProps.columns + .filter(it => { + const isHidden = tableProps.state?.columnVisibility?.[it.id!] === false; + return !isHidden; + }) + .map(it => { + if (typeof it.gridTemplate === 'number') { + return `${it.gridTemplate}fr`; + } + return it.gridTemplate ?? '1fr'; + }) + .join(' '); + if (tableProps.enableRowActions) { + preGridTemplateColumns = `${preGridTemplateColumns} 0.05fr`; + } + if (tableProps.enableRowSelection) { + preGridTemplateColumns = `0.05fr ${preGridTemplateColumns}`; + } + + return preGridTemplateColumns; + }, [ + tableProps.columns, + tableProps.state?.columnVisibility, + tableProps.enableRowActions, + tableProps.enableRowSelection, + ]); const paginationSelectProps = import.meta.env.UNDER_TEST ? { @@ -224,6 +245,17 @@ export default function Table>({ setPage(pagination.pageIndex + 1); setPageSize(pagination.pageSize); }, + renderToolbarInternalActions: props => { + const isSomeRowsSelected = + tableProps.enableRowSelection && props.table.getSelectedRowModel().rows.length !== 0; + if (isSomeRowsSelected) { + const renderRowSelectionToolbar = tableProps.renderRowSelectionToolbar; + if (renderRowSelectionToolbar !== undefined) { + return renderRowSelectionToolbar(props); + } + } + return null; + }, initialState: { density: 'compact', ...(tableProps.initialState ?? {}), @@ -266,6 +298,7 @@ export default function Table>({ }, muiTopToolbarProps: { sx: { + height: '3.5rem', backgroundColor: undefined, }, }, @@ -315,10 +348,7 @@ export default function Table>({ borderRadius: 1, borderBottom: 'none', overflow: 'hidden', - gridTemplateColumns: - tableProps.enableRowActions === true - ? `${gridTemplateColumns} 0.05fr` - : gridTemplateColumns, + gridTemplateColumns, }} > @@ -331,13 +361,20 @@ export default function Table>({ isFiltered={header.column.getIsFiltered()} sorting={header.column.getIsSorted()} showColumnFilters={table.getState().showColumnFilters} + selected={ + table.getIsAllRowsSelected() + ? 'all' + : table.getIsSomeRowsSelected() + ? 'some' + : 'none' + } /> ))} {rows.map(row => ( - + ))} @@ -355,6 +392,7 @@ const MemoHeadCell = memo( header: MRT_Header; sorting: string | false; isFiltered: boolean; + selected: any; showColumnFilters: boolean; }) => { return ( @@ -365,19 +403,37 @@ const MemoHeadCell = memo( a.header.column.id === b.header.column.id && a.sorting === b.sorting && a.isFiltered === b.isFiltered && - a.showColumnFilters === b.showColumnFilters + a.showColumnFilters === b.showColumnFilters && + a.header.column.id === 'mrt-row-select' + ? a.selected === b.selected + : true ); -const Row = memo(({ row, table }: { table: MRT_TableInstance; row: MRT_Row }) => ( - - {row.getVisibleCells().map(cell => ( - - ))} - -)); +const Row = memo( + ({ + row, + table, + isSelected, + }: { + table: MRT_TableInstance; + row: MRT_Row; + isSelected: boolean; + }) => ( + + {row.getVisibleCells().map(cell => ( + + ))} + + ) +); const MemoCell = memo( - ({ cell, table }: { cell: MRT_Cell; table: any }) => { + ({ cell, table }: { cell: MRT_Cell; table: any; isRowSelected: boolean }) => { return ( ); }, - (a, b) => a.cell.getValue() === b.cell.getValue() + (a, b) => + a.cell.getValue() === b.cell.getValue() && + (a.cell.column.id === 'mrt-row-select' && b.cell.column.id === 'mrt-row-select' + ? a.isRowSelected === b.isRowSelected + : true) ); diff --git a/frontend/src/components/common/Table/__snapshots__/Table.Datum.stories.storyshot b/frontend/src/components/common/Table/__snapshots__/Table.Datum.stories.storyshot index d1d4e820cf..77da383f4e 100644 --- a/frontend/src/components/common/Table/__snapshots__/Table.Datum.stories.storyshot +++ b/frontend/src/components/common/Table/__snapshots__/Table.Datum.stories.storyshot @@ -1,7 +1,7 @@