mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-01 19:20:55 +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:
@ -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 [hiddenColumnsLoaded, setHiddenColumnsLoaded] =
|
||||
useState<boolean>(false);
|
||||
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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
});
|
||||
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 storedDataLoaded = useMemo(() => {
|
||||
return pageSizeLoaded && hiddenColumnsLoaded;
|
||||
}, [pageSizeLoaded, hiddenColumnsLoaded]);
|
||||
const setPageSize = useCallback((size: number) => {
|
||||
setStoredTableData((prev) => ({
|
||||
...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
|
||||
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,
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user