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:
@ -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,
|
||||||
|
@ -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,
|
||||||
|
Reference in New Issue
Block a user