2023-12-19 15:35:39 +01:00
|
|
|
import { useEffect, useCallback, useMemo } from 'react';
|
2023-12-04 14:21:03 +01:00
|
|
|
import { useSearchParams } from 'react-router-dom';
|
|
|
|
import { createLocalStorage } from 'utils/createLocalStorage';
|
2023-12-15 10:20:55 +01:00
|
|
|
import { encodeQueryParams, useQueryParams } from 'use-query-params';
|
2024-03-18 13:58:05 +01:00
|
|
|
import type { QueryParamConfigMap } from 'serialize-query-params/src/types';
|
2023-12-19 15:35:39 +01:00
|
|
|
import { reorderObject } from '../utils/reorderObject';
|
2023-12-04 14:21:03 +01:00
|
|
|
|
2023-12-05 17:31:23 +01:00
|
|
|
const usePersistentSearchParams = <T extends QueryParamConfigMap>(
|
|
|
|
key: string,
|
|
|
|
queryParamsDefinition: T,
|
|
|
|
) => {
|
2023-12-04 14:21:03 +01:00
|
|
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
|
|
const { value, setValue } = createLocalStorage(key, {});
|
|
|
|
useEffect(() => {
|
|
|
|
const params = Object.fromEntries(searchParams.entries());
|
|
|
|
if (Object.keys(params).length > 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Object.keys(value).length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
2023-12-05 17:31:23 +01:00
|
|
|
setSearchParams(
|
|
|
|
encodeQueryParams(queryParamsDefinition, value) as Record<
|
|
|
|
string,
|
|
|
|
string
|
|
|
|
>,
|
|
|
|
{ replace: true },
|
|
|
|
);
|
2023-12-04 14:21:03 +01:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
return setValue;
|
|
|
|
};
|
|
|
|
|
2023-12-05 17:31:23 +01:00
|
|
|
export const usePersistentTableState = <T extends QueryParamConfigMap>(
|
2023-12-04 14:21:03 +01:00
|
|
|
key: string,
|
|
|
|
queryParamsDefinition: T,
|
|
|
|
) => {
|
2023-12-05 17:31:23 +01:00
|
|
|
const updateStoredParams = usePersistentSearchParams(
|
|
|
|
key,
|
|
|
|
queryParamsDefinition,
|
|
|
|
);
|
2023-12-04 14:21:03 +01:00
|
|
|
|
2023-12-15 10:20:55 +01:00
|
|
|
const [tableState, setTableStateInternal] = useQueryParams(
|
|
|
|
queryParamsDefinition,
|
2024-04-12 10:58:17 +02:00
|
|
|
{ updateType: 'replaceIn' },
|
2023-12-15 10:20:55 +01:00
|
|
|
);
|
|
|
|
|
2023-12-19 15:35:39 +01:00
|
|
|
const [searchParams] = useSearchParams();
|
|
|
|
const orderedTableState = useMemo(() => {
|
|
|
|
return reorderObject(tableState, [...searchParams.keys()]);
|
|
|
|
}, [searchParams, tableState, reorderObject]);
|
|
|
|
|
2023-12-15 10:20:55 +01:00
|
|
|
type SetTableStateInternalParam = Parameters<
|
|
|
|
typeof setTableStateInternal
|
|
|
|
>[0];
|
|
|
|
|
|
|
|
const setTableState = useCallback(
|
|
|
|
(newState: SetTableStateInternalParam) => {
|
|
|
|
if (!queryParamsDefinition.offset) {
|
|
|
|
return setTableStateInternal(newState);
|
|
|
|
}
|
|
|
|
if (typeof newState === 'function') {
|
|
|
|
setTableStateInternal((prevState) => {
|
|
|
|
const updatedState = (newState as Function)(prevState);
|
|
|
|
return queryParamsDefinition.offset
|
|
|
|
? {
|
|
|
|
offset: queryParamsDefinition.offset.decode('0'),
|
|
|
|
...updatedState,
|
|
|
|
}
|
|
|
|
: updatedState;
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
const updatedState = queryParamsDefinition.offset
|
|
|
|
? {
|
|
|
|
offset: queryParamsDefinition.offset.decode('0'),
|
|
|
|
...newState,
|
|
|
|
}
|
|
|
|
: newState;
|
|
|
|
setTableStateInternal(updatedState);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[setTableStateInternal, queryParamsDefinition.offset],
|
|
|
|
);
|
2023-12-04 14:21:03 +01:00
|
|
|
|
|
|
|
useEffect(() => {
|
2023-12-19 15:35:39 +01:00
|
|
|
const { offset, ...rest } = orderedTableState;
|
2023-12-04 14:21:03 +01:00
|
|
|
updateStoredParams(rest);
|
2023-12-19 15:35:39 +01:00
|
|
|
}, [JSON.stringify(orderedTableState)]);
|
2023-12-04 14:21:03 +01:00
|
|
|
|
2023-12-19 15:35:39 +01:00
|
|
|
return [orderedTableState, setTableState] as const;
|
2023-12-04 14:21:03 +01:00
|
|
|
};
|