From 14a6330114aaeca088cee5d0b258c4e2f0799eb6 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 9 Sep 2023 08:34:27 +1000 Subject: [PATCH] Refactor table columns (#5519) - Improve show/hide - Refactor "actions" colum --- .../src/components/tables/InvenTreeTable.tsx | 46 ++++++++++---- .../src/components/tables/RowActions.tsx | 42 +++++++------ .../src/components/tables/part/PartTable.tsx | 61 +++++++++---------- .../tables/stock/StockItemTable.tsx | 43 +++++-------- 4 files changed, 101 insertions(+), 91 deletions(-) diff --git a/src/frontend/src/components/tables/InvenTreeTable.tsx b/src/frontend/src/components/tables/InvenTreeTable.tsx index bab614cacf..06355fc1bb 100644 --- a/src/frontend/src/components/tables/InvenTreeTable.tsx +++ b/src/frontend/src/components/tables/InvenTreeTable.tsx @@ -15,6 +15,7 @@ import { DownloadAction } from './DownloadAction'; import { TableFilter } from './Filter'; import { FilterGroup } from './FilterGroup'; import { FilterSelectModal } from './FilterSelectModal'; +import { RowAction, RowActions } from './RowActions'; import { TableSearchInput } from './Search'; /* @@ -96,7 +97,8 @@ export function InvenTreeTable({ printingActions = [], barcodeActions = [], customActionGroups = [], - customFilters = [] + customFilters = [], + rowActions }: { url: string; params: any; @@ -115,12 +117,15 @@ export function InvenTreeTable({ barcodeActions?: any[]; customActionGroups?: any[]; customFilters?: TableFilter[]; + rowActions?: (record: any) => RowAction[]; }) { // Data columns const [dataColumns, setDataColumns] = useState(columns); // Check if any columns are switchable (can be hidden) - const hasSwitchableColumns = columns.some((col: any) => col.switchable); + const hasSwitchableColumns = columns.some( + (col: TableColumn) => col.switchable + ); // Manage state for switchable columns (initially load from local storage) let [hiddenColumns, setHiddenColumns] = useState(() => @@ -129,15 +134,34 @@ export function InvenTreeTable({ // Update column visibility when hiddenColumns change useEffect(() => { - setDataColumns( - dataColumns.map((col) => { - return { - ...col, - hidden: hiddenColumns.includes(col.accessor) - }; - }) - ); - }, [hiddenColumns]); + let cols = dataColumns.map((col) => { + let hidden: boolean = col.hidden; + + if (col.switchable) { + hidden = hiddenColumns.includes(col.accessor); + } + + return { + ...col, + hidden: hidden + }; + }); + + // If row actions are available, add a column for them + if (rowActions) { + cols.push({ + accessor: 'actions', + title: '', + hidden: false, + switchable: false, + render: function (record: any) { + return ; + } + }); + } + + setDataColumns(cols); + }, [columns, hiddenColumns, rowActions]); // Callback when column visibility is toggled function toggleColumn(columnName: string) { diff --git a/src/frontend/src/components/tables/RowActions.tsx b/src/frontend/src/components/tables/RowActions.tsx index f65d7fd22c..1476092805 100644 --- a/src/frontend/src/components/tables/RowActions.tsx +++ b/src/frontend/src/components/tables/RowActions.tsx @@ -24,25 +24,27 @@ export function RowActions({ actions: RowAction[]; }): ReactNode { return ( - - - - - - - - {title || t`Actions`} - {actions.map((action, idx) => ( - - {action.title} - - ))} - - + actions.length > 0 && ( + + + + + + + + {title || t`Actions`} + {actions.map((action, idx) => ( + + {action.title} + + ))} + + + ) ); } diff --git a/src/frontend/src/components/tables/part/PartTable.tsx b/src/frontend/src/components/tables/part/PartTable.tsx index f32a31880e..98d547ba28 100644 --- a/src/frontend/src/components/tables/part/PartTable.tsx +++ b/src/frontend/src/components/tables/part/PartTable.tsx @@ -10,7 +10,7 @@ import { ThumbnailHoverCard } from '../../items/Thumbnail'; import { TableColumn } from '../Column'; import { TableFilter } from '../Filter'; import { InvenTreeTable } from '../InvenTreeTable'; -import { RowActions } from '../RowActions'; +import { RowAction } from '../RowActions'; /** * Construct a list of columns for the part table @@ -82,38 +82,6 @@ function partTableColumns(): TableColumn[] { accessor: 'link', title: t`Link`, switchable: true - }, - { - accessor: 'actions', - title: '', - switchable: false, - render: function (record: any) { - return ( - , - onClick: () => - editPart({ - part_id: record.pk, - callback: () => { - // TODO: Reload the table, somehow? - // TODO: Insert / update a single row in the table? - // TODO: We need to have a hook back into the table - } - }) - }, - { - title: t`Delete`, - onClick: notYetImplemented, - icon: - } - ]} - /> - ); - } } ]; } @@ -229,6 +197,32 @@ export function PartListTable({ params = {} }: { params?: any }) { // Add required query parameters tableParams.category_detail = true; + function partTableRowActions(record: any): RowAction[] { + let actions: RowAction[] = []; + + actions.push({ + title: t`Edit`, + onClick: () => { + editPart({ + part_id: record.pk, + callback: () => { + // TODO: Reload the table, somehow? + notYetImplemented(); + } + }); + } + }); + + if (record.IPN) { + actions.push({ + title: t`View IPN`, + onClick: () => {} + }); + } + + return actions; + } + return ( ); } diff --git a/src/frontend/src/components/tables/stock/StockItemTable.tsx b/src/frontend/src/components/tables/stock/StockItemTable.tsx index c8d4f3baab..dae52dea19 100644 --- a/src/frontend/src/components/tables/stock/StockItemTable.tsx +++ b/src/frontend/src/components/tables/stock/StockItemTable.tsx @@ -8,7 +8,7 @@ import { ActionButton } from '../../items/ActionButton'; import { ThumbnailHoverCard } from '../../items/Thumbnail'; import { TableColumn } from '../Column'; import { TableFilter } from '../Filter'; -import { RowActions } from '../RowActions'; +import { RowAction } from '../RowActions'; import { InvenTreeTable } from './../InvenTreeTable'; /** @@ -66,7 +66,7 @@ function stockItemTableColumns(): TableColumn[] { // TODO: Custom renderer for location return record.location; } - }, + } // TODO: stocktake column // TODO: expiry date // TODO: last updated @@ -76,31 +76,6 @@ function stockItemTableColumns(): TableColumn[] { // TODO: stock value // TODO: packaging // TODO: notes - { - accessor: 'actions', - title: '', - sortable: false, - switchable: false, - render: function (record: any) { - return ( - , - onClick: notYetImplemented - }, - { - title: t`Delete`, - icon: , - onClick: notYetImplemented - } - ]} - /> - ); - } - } ]; } @@ -142,6 +117,19 @@ export function StockItemTable({ params = {} }: { params?: any }) { let tableColumns = useMemo(() => stockItemTableColumns(), []); let tableFilters = useMemo(() => stockItemTableFilters(), []); + function stockItemRowActions(record: any): RowAction[] { + let actions: RowAction[] = []; + + actions.push({ + title: t`Edit`, + onClick: () => { + notYetImplemented(); + } + }); + + return actions; + } + return ( ); }