Table Hook Updates (#6093)

* Update useTable hook

- Storage for "selected rows"
- Aim is to make row selection available outside table component

* Use updated hook to manage row selection

* Add more table data to useTable:

- hidden column selection
- search terms

* Remove unused import

* Remove unused function

* Cleanup
This commit is contained in:
Oliver 2023-12-15 13:53:46 +11:00 committed by GitHub
parent 72167630ac
commit 64671dce20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 40 deletions

View File

@ -1,12 +1,11 @@
import { t } from '@lingui/macro';
import { ActionIcon, Indicator, Space, Stack, Tooltip } from '@mantine/core';
import { Group } from '@mantine/core';
import { useLocalStorage } from '@mantine/hooks';
import { IconFilter, IconRefresh } from '@tabler/icons-react';
import { IconBarcode, IconPrinter } from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query';
import { DataTable, DataTableSortStatus } from 'mantine-datatable';
import { Fragment, useEffect, useMemo, useState } from 'react';
import { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
import { api } from '../../App';
import { TableState } from '../../hooks/UseTable';
@ -100,12 +99,6 @@ export function InvenTreeTable<T = any>({
columns: TableColumn<T>[];
props: InvenTreeTableProps<T>;
}) {
// Use the first part of the table key as the table name
const tableName: string = useMemo(() => {
let key = tableState?.tableKey ?? 'table';
return key.split('-')[0];
}, []);
// Build table properties based on provided props (and default props)
const tableProps: InvenTreeTableProps<T> = useMemo(() => {
return {
@ -119,18 +112,9 @@ export function InvenTreeTable<T = any>({
(col: TableColumn) => col.switchable ?? true
);
// A list of hidden columns, saved to local storage
const [hiddenColumns, setHiddenColumns] = useLocalStorage<string[]>({
key: `inventree-hidden-table-columns-${tableName}`,
defaultValue: []
});
// Data selection
const [selectedRecords, setSelectedRecords] = useState<any[]>([]);
function onSelectedRecordsChange(records: any[]) {
setSelectedRecords(records);
}
const onSelectedRecordsChange = useCallback((records: any[]) => {
tableState.setSelectedRecords(records);
}, []);
// Update column visibility when hiddenColumns change
const dataColumns: any = useMemo(() => {
@ -138,7 +122,7 @@ export function InvenTreeTable<T = any>({
let hidden: boolean = col.hidden ?? false;
if (col.switchable ?? true) {
hidden = hiddenColumns.includes(col.accessor);
hidden = tableState.hiddenColumns.includes(col.accessor);
}
return {
@ -159,7 +143,7 @@ export function InvenTreeTable<T = any>({
return (
<RowActions
actions={tableProps.rowActions?.(record) ?? []}
disabled={selectedRecords.length > 0}
disabled={tableState.selectedRecords.length > 0}
/>
);
}
@ -169,10 +153,10 @@ export function InvenTreeTable<T = any>({
return cols;
}, [
columns,
hiddenColumns,
tableProps.rowActions,
tableProps.enableSelection,
selectedRecords
tableState.hiddenColumns,
tableState.selectedRecords
]);
// Callback when column visibility is toggled
@ -185,7 +169,7 @@ export function InvenTreeTable<T = any>({
newColumns[colIdx].hidden = !newColumns[colIdx].hidden;
}
setHiddenColumns(
tableState.setHiddenColumns(
newColumns.filter((col) => col.hidden).map((col) => col.accessor)
);
}
@ -196,13 +180,10 @@ export function InvenTreeTable<T = any>({
// Filter list visibility
const [filtersVisible, setFiltersVisible] = useState<boolean>(false);
// Search term
const [searchTerm, setSearchTerm] = useState<string>('');
// Reset the pagination state when the search term changes
useEffect(() => {
setPage(1);
}, [searchTerm]);
}, [tableState.searchTerm]);
/*
* Construct query filters for the current table
@ -218,8 +199,8 @@ export function InvenTreeTable<T = any>({
);
// Add custom search term
if (searchTerm) {
queryParams.search = searchTerm;
if (tableState.searchTerm) {
queryParams.search = tableState.searchTerm;
}
// Pagination
@ -340,7 +321,7 @@ export function InvenTreeTable<T = any>({
default:
setMissingRecordsText(
t`Unknown error` + ': ' + response.statusText
); // TODO: Translate
);
break;
}
@ -352,15 +333,15 @@ export function InvenTreeTable<T = any>({
});
};
const { data, isError, isFetching, isLoading, refetch } = useQuery({
const { data, isFetching, refetch } = useQuery({
queryKey: [
tableState.tableKey,
page,
props.params,
sortStatus.columnAccessor,
sortStatus.direction,
page,
tableState.tableKey,
tableState.activeFilters,
searchTerm
tableState.searchTerm
],
queryFn: fetchTableData,
refetchOnWindowFocus: false,
@ -409,7 +390,9 @@ export function InvenTreeTable<T = any>({
<Group position="right" spacing={5}>
{tableProps.enableSearch && (
<TableSearchInput
searchCallback={(term: string) => setSearchTerm(term)}
searchCallback={(term: string) =>
tableState.setSearchTerm(term)
}
/>
)}
{tableProps.enableRefresh && (
@ -464,7 +447,7 @@ export function InvenTreeTable<T = any>({
sortStatus={sortStatus}
onSortStatusChange={handleSortStatusChange}
selectedRecords={
tableProps.enableSelection ? selectedRecords : undefined
tableProps.enableSelection ? tableState.selectedRecords : undefined
}
onSelectedRecordsChange={
tableProps.enableSelection ? onSelectedRecordsChange : undefined

View File

@ -9,13 +9,23 @@ import { TableFilter } from '../components/tables/Filter';
* tableKey: A unique key for the table. When this key changes, the table will be refreshed.
* refreshTable: A callback function to externally refresh the table.
* activeFilters: An array of active filters (saved to local storage)
* selectedRecords: An array of selected records (rows) in the table
* hiddenColumns: An array of hidden column names
* searchTerm: The current search term for the table
*/
export type TableState = {
tableKey: string;
refreshTable: () => void;
activeFilters: TableFilter[];
setActiveFilters: (filters: TableFilter[]) => void;
clearActiveFilters: () => void;
refreshTable: () => void;
selectedRecords: any[];
setSelectedRecords: (records: any[]) => void;
clearSelectedRecords: () => void;
hiddenColumns: string[];
setHiddenColumns: (columns: string[]) => void;
searchTerm: string;
setSearchTerm: (term: string) => void;
};
/**
@ -49,11 +59,34 @@ export function useTable(tableName: string): TableState {
setActiveFilters([]);
}, []);
// Array of selected records
const [selectedRecords, setSelectedRecords] = useState<any[]>([]);
const clearSelectedRecords = useCallback(() => {
setSelectedRecords([]);
}, []);
// A list of hidden columns, saved to local storage
const [hiddenColumns, setHiddenColumns] = useLocalStorage<string[]>({
key: `inventree-hidden-table-columns-${tableName}`,
defaultValue: []
});
// Search term
const [searchTerm, setSearchTerm] = useState<string>('');
return {
tableKey,
refreshTable,
activeFilters,
setActiveFilters,
clearActiveFilters,
refreshTable
selectedRecords,
setSelectedRecords,
clearSelectedRecords,
hiddenColumns,
setHiddenColumns,
searchTerm,
setSearchTerm
};
}