mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 05:22:02 +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 */
|
||||
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>>;
|
||||
/** If true, `toSearchParams`/`toQueryString` will omit values equal to defaults */
|
||||
omitDefaultsInUrl?: boolean;
|
||||
|
||||
persist?: boolean;
|
||||
storeName?: string;
|
||||
};
|
||||
|
||||
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>>(
|
||||
options?: UseTableFilterOptions<TExtra>
|
||||
) {
|
||||
const defaults = useMemo(
|
||||
() => createInitialState<TExtra>(options),
|
||||
[options]
|
||||
if (options?.persist && !options?.storeName) {
|
||||
throw new Error(
|
||||
'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(
|
||||
@@ -106,15 +138,22 @@ export function useTableFilter<TExtra extends Record<string, unknown>>(
|
||||
case 'SET_PAGE_SIZE': {
|
||||
const pageSize = clampToInt(a.pageSize);
|
||||
const page = a.resetPage ? 1 : s.page;
|
||||
|
||||
return { ...s, pageSize, page };
|
||||
}
|
||||
case 'SET_FILTERS': {
|
||||
const page = a.resetPage ? 1 : s.page;
|
||||
|
||||
return { ...s, ...a.filters, page };
|
||||
}
|
||||
case 'UPDATE_FILTER': {
|
||||
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':
|
||||
return {
|
||||
@@ -128,12 +167,19 @@ export function useTableFilter<TExtra extends Record<string, unknown>>(
|
||||
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;
|
||||
useMemo(() => {
|
||||
useEffect(() => {
|
||||
if (onChange) onChange(state);
|
||||
}, [state, onChange]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user