1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-06 00:07:44 +01:00
unleash.unleash/frontend/src/hooks/usePersistentTableState.ts

92 lines
3.1 KiB
TypeScript
Raw Normal View History

2023-12-19 15:35:39 +01:00
import { useEffect, useCallback, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { createLocalStorage } from 'utils/createLocalStorage';
import { encodeQueryParams, useQueryParams } from 'use-query-params';
import type { QueryParamConfigMap } from 'serialize-query-params/src/types';
2023-12-19 15:35:39 +01:00
import { reorderObject } from '../utils/reorderObject';
2023-12-05 17:31:23 +01:00
const usePersistentSearchParams = <T extends QueryParamConfigMap>(
key: string,
queryParamsDefinition: T,
) => {
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 },
);
}, []);
return setValue;
};
2023-12-05 17:31:23 +01:00
export const usePersistentTableState = <T extends QueryParamConfigMap>(
key: string,
queryParamsDefinition: T,
) => {
2023-12-05 17:31:23 +01:00
const updateStoredParams = usePersistentSearchParams(
key,
queryParamsDefinition,
);
const [tableState, setTableStateInternal] = useQueryParams(
queryParamsDefinition,
{ updateType: 'replaceIn' },
);
2023-12-19 15:35:39 +01:00
const [searchParams] = useSearchParams();
const orderedTableState = useMemo(() => {
return reorderObject(tableState, [...searchParams.keys()]);
}, [searchParams, tableState, reorderObject]);
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],
);
useEffect(() => {
2023-12-19 15:35:39 +01:00
const { offset, ...rest } = orderedTableState;
updateStoredParams(rest);
2023-12-19 15:35:39 +01:00
}, [JSON.stringify(orderedTableState)]);
2023-12-19 15:35:39 +01:00
return [orderedTableState, setTableState] as const;
};