mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
fix: implement persist to storage in useTableFilter
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { useCallback, useMemo, useReducer } from 'react';
|
import { useCallback, useEffect, useMemo, useReducer } from 'react';
|
||||||
|
import { useTableFilterStore } from '@/stores/table/table-filter.store';
|
||||||
|
|
||||||
/** Core filter shape (page + pageSize) extended by your custom fields */
|
/** Core filter shape (page + pageSize) extended by your custom fields */
|
||||||
export type TableFilterState<TExtra extends Record<string, unknown>> = {
|
export type TableFilterState<TExtra extends Record<string, unknown>> = {
|
||||||
@@ -30,6 +31,9 @@ export type UseTableFilterOptions<TExtra extends Record<string, unknown>> = {
|
|||||||
paramMap?: Partial<Record<keyof TableFilterState<TExtra>, string>>;
|
paramMap?: Partial<Record<keyof TableFilterState<TExtra>, string>>;
|
||||||
/** If true, `toSearchParams`/`toQueryString` will omit values equal to defaults */
|
/** If true, `toSearchParams`/`toQueryString` will omit values equal to defaults */
|
||||||
omitDefaultsInUrl?: boolean;
|
omitDefaultsInUrl?: boolean;
|
||||||
|
|
||||||
|
persist?: boolean;
|
||||||
|
storeName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function clampToInt(n: number, min = 1) {
|
function clampToInt(n: number, min = 1) {
|
||||||
@@ -90,9 +94,37 @@ function shallowEqual<T extends Record<string, unknown>>(
|
|||||||
export function useTableFilter<TExtra extends Record<string, unknown>>(
|
export function useTableFilter<TExtra extends Record<string, unknown>>(
|
||||||
options?: UseTableFilterOptions<TExtra>
|
options?: UseTableFilterOptions<TExtra>
|
||||||
) {
|
) {
|
||||||
const defaults = useMemo(
|
if (options?.persist && !options?.storeName) {
|
||||||
() => createInitialState<TExtra>(options),
|
throw new Error(
|
||||||
[options]
|
'storeName is required if persist is true in useTableFilter!'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const storeName = options?.storeName ?? '';
|
||||||
|
const persistedState = useTableFilterStore(
|
||||||
|
useCallback(
|
||||||
|
(storeState) =>
|
||||||
|
storeName
|
||||||
|
? (storeState.data[storeName] as Partial<TableFilterState<TExtra>>)
|
||||||
|
: undefined,
|
||||||
|
[storeName]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const setTableData = useTableFilterStore(
|
||||||
|
(storeState) => storeState.setTableData
|
||||||
|
);
|
||||||
|
|
||||||
|
const defaults = useMemo(() => {
|
||||||
|
return createInitialState<TExtra>(options);
|
||||||
|
}, [options]);
|
||||||
|
|
||||||
|
const initialState = useMemo(
|
||||||
|
() =>
|
||||||
|
({
|
||||||
|
...defaults,
|
||||||
|
...(persistedState as object),
|
||||||
|
}) as TableFilterState<TExtra>,
|
||||||
|
[defaults, persistedState]
|
||||||
);
|
);
|
||||||
|
|
||||||
const [state, dispatch] = useReducer(
|
const [state, dispatch] = useReducer(
|
||||||
@@ -106,15 +138,22 @@ export function useTableFilter<TExtra extends Record<string, unknown>>(
|
|||||||
case 'SET_PAGE_SIZE': {
|
case 'SET_PAGE_SIZE': {
|
||||||
const pageSize = clampToInt(a.pageSize);
|
const pageSize = clampToInt(a.pageSize);
|
||||||
const page = a.resetPage ? 1 : s.page;
|
const page = a.resetPage ? 1 : s.page;
|
||||||
|
|
||||||
return { ...s, pageSize, page };
|
return { ...s, pageSize, page };
|
||||||
}
|
}
|
||||||
case 'SET_FILTERS': {
|
case 'SET_FILTERS': {
|
||||||
const page = a.resetPage ? 1 : s.page;
|
const page = a.resetPage ? 1 : s.page;
|
||||||
|
|
||||||
return { ...s, ...a.filters, page };
|
return { ...s, ...a.filters, page };
|
||||||
}
|
}
|
||||||
case 'UPDATE_FILTER': {
|
case 'UPDATE_FILTER': {
|
||||||
const page = a.resetPage ? 1 : s.page;
|
const page = a.resetPage ? 1 : s.page;
|
||||||
return { ...s, [a.key]: a.value, page } as TableFilterState<TExtra>;
|
|
||||||
|
return {
|
||||||
|
...s,
|
||||||
|
[a.key]: a.value,
|
||||||
|
page,
|
||||||
|
} as TableFilterState<TExtra>;
|
||||||
}
|
}
|
||||||
case 'REPLACE_ALL':
|
case 'REPLACE_ALL':
|
||||||
return {
|
return {
|
||||||
@@ -128,12 +167,19 @@ export function useTableFilter<TExtra extends Record<string, unknown>>(
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
defaults
|
initialState
|
||||||
);
|
);
|
||||||
|
|
||||||
// Notify consumer on change (stable ref)
|
useEffect(() => {
|
||||||
|
if (!options?.persist || !storeName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTableData(storeName, state);
|
||||||
|
}, [options?.persist, setTableData, state, storeName]);
|
||||||
|
|
||||||
const onChange = options?.onChange;
|
const onChange = options?.onChange;
|
||||||
useMemo(() => {
|
useEffect(() => {
|
||||||
if (onChange) onChange(state);
|
if (onChange) onChange(state);
|
||||||
}, [state, onChange]);
|
}, [state, onChange]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user