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

View File

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