2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-02 03:30:54 +00:00

Fix for caching table options (#9898)

- The sync: false option does not perform properly
- Sometimes, the data is simply not loaded from localStorage at all
This commit is contained in:
Oliver
2025-06-29 20:18:34 +10:00
committed by GitHub
parent 4c11f8c911
commit 741efd78af
2 changed files with 75 additions and 28 deletions

View File

@ -6,6 +6,12 @@ import type { FilterSetState } from '@lib/types/Filters';
import type { TableState } from '@lib/types/Tables'; import type { TableState } from '@lib/types/Tables';
import { useFilterSet } from './UseFilterSet'; import { useFilterSet } from './UseFilterSet';
// Interface for the stored table data in local storage
interface StoredTableData {
pageSize: number;
hiddenColumns: string[] | null;
}
/** /**
* A custom hook for managing the state of an <InvenTreeTable> component. * A custom hook for managing the state of an <InvenTreeTable> component.
* *
@ -65,37 +71,71 @@ export function useTable(tableName: string, idAccessor = 'pk'): TableState {
// Total record count // Total record count
const [recordCount, setRecordCount] = useState<number>(0); const [recordCount, setRecordCount] = useState<number>(0);
const [pageSizeLoaded, setPageSizeLoaded] = useState<boolean>(false);
// Pagination data
const [page, setPage] = useState<number>(1); const [page, setPage] = useState<number>(1);
const [pageSize, setPageSize] = useLocalStorage<number>({
key: 'inventree-table-page-size', const [storedDataLoaded, setStoredDataLoaded] = useState<boolean>(false);
defaultValue: 25,
sync: false, const [tableData, setTableData] = useState<StoredTableData>({
deserialize: (value: string | undefined) => { pageSize: 25,
setPageSizeLoaded(true); hiddenColumns: null
return value === undefined ? 25 : JSON.parse(value);
}
}); });
const [hiddenColumnsLoaded, setHiddenColumnsLoaded] = const [storedTableData, setStoredTableData] =
useState<boolean>(false); useLocalStorage<StoredTableData>({
key: `inventree-table-data-${tableName}`,
getInitialValueInEffect: true,
// sync: false, // Do not use this option - see below
defaultValue: {
pageSize: 25,
hiddenColumns: null
},
deserialize: (value: any) => {
const tableData =
value === undefined
? {
pageSize: 25,
hiddenColumns: null
}
: JSON.parse(value);
// A list of hidden columns, saved to local storage if (!storedDataLoaded) {
const [hiddenColumns, setHiddenColumns] = useLocalStorage<string[] | null>({ setStoredDataLoaded((wasLoaded: boolean) => {
key: `inventree-hidden-table-columns-${tableName}`, if (!wasLoaded) {
defaultValue: null, // First load of stored table data - copy to local state
sync: false, // We only do this on first load, to avoid live syncing between tabs
deserialize: (value) => { // Note: The 'sync: false' option is not used, it does not perform as expected
setHiddenColumnsLoaded(true); setTableData(tableData);
return value === undefined ? null : JSON.parse(value); }
} return true;
}); });
}
return tableData;
}
});
const storedDataLoaded = useMemo(() => { const setPageSize = useCallback((size: number) => {
return pageSizeLoaded && hiddenColumnsLoaded; setStoredTableData((prev) => ({
}, [pageSizeLoaded, hiddenColumnsLoaded]); ...prev,
pageSize: size
}));
setTableData((prev) => ({
...prev,
pageSize: size
}));
}, []);
const setHiddenColumns = useCallback((columns: string[] | null) => {
setStoredTableData((prev) => {
return {
...prev,
hiddenColumns: columns
};
});
setTableData((prev) => ({
...prev,
hiddenColumns: columns
}));
}, []);
// Search term // Search term
const [searchTerm, setSearchTerm] = useState<string>(''); const [searchTerm, setSearchTerm] = useState<string>('');
@ -146,7 +186,8 @@ export function useTable(tableName: string, idAccessor = 'pk'): TableState {
setSelectedRecords, setSelectedRecords,
clearSelectedRecords, clearSelectedRecords,
hasSelectedRecords, hasSelectedRecords,
hiddenColumns, pageSize: tableData.pageSize,
hiddenColumns: tableData.hiddenColumns,
setHiddenColumns, setHiddenColumns,
searchTerm, searchTerm,
setSearchTerm, setSearchTerm,
@ -154,7 +195,6 @@ export function useTable(tableName: string, idAccessor = 'pk'): TableState {
setRecordCount, setRecordCount,
page, page,
setPage, setPage,
pageSize,
setPageSize, setPageSize,
storedDataLoaded, storedDataLoaded,
records, records,

View File

@ -547,6 +547,11 @@ export function InvenTreeTable<T extends Record<string, any>>({
return []; return [];
} }
if (!tableState.storedDataLoaded) {
// Table data not yet loaded - do not load!
return [];
}
return api return api
.get(url, { .get(url, {
params: queryParams, params: queryParams,
@ -610,6 +615,7 @@ export function InvenTreeTable<T extends Record<string, any>>({
queryKey: [ queryKey: [
'tabledata', 'tabledata',
url, url,
tableState.tableKey,
tableState.page, tableState.page,
props.params, props.params,
sortingLoaded, sortingLoaded,
@ -617,6 +623,7 @@ export function InvenTreeTable<T extends Record<string, any>>({
sortStatus.direction, sortStatus.direction,
tableState.tableKey, tableState.tableKey,
tableState.filterSet.activeFilters, tableState.filterSet.activeFilters,
tableState.storedDataLoaded,
tableState.searchTerm tableState.searchTerm
], ],
enabled: !!url && !tableData && tableState.storedDataLoaded, enabled: !!url && !tableData && tableState.storedDataLoaded,