1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-23 00:22:19 +01:00

feat: Refactor Table State Persistence in Feature Toggle List (#5527)

new custom hook, `usePersistentTableState`

Co-authored-by: Mateusz Kwasniewski <kwasniewski.mateusz@gmail.com>
This commit is contained in:
Tymoteusz Czech 2023-12-04 14:21:03 +01:00 committed by GitHub
parent a0a15416c4
commit a506b92544
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 15 deletions

View File

@ -46,13 +46,9 @@ import {
useFeatureSearch,
} from 'hooks/api/getters/useFeatureSearch/useFeatureSearch';
import mapValues from 'lodash.mapvalues';
import {
BooleanParam,
NumberParam,
StringParam,
useQueryParams,
withDefault,
} from 'use-query-params';
import { NumberParam, StringParam, withDefault } from 'use-query-params';
import { BooleansStringParam } from 'utils/serializeQueryParams';
import { usePersistentTableState } from 'hooks/usePersistentTableState';
export const featuresPlaceholder = Array(15).fill({
name: 'Name of the feature',
@ -76,14 +72,19 @@ export const FeatureToggleListTable: VFC = () => {
const { setToastApiError } = useToast();
const { uiConfig } = useUiConfig();
const [tableState, setTableState] = useQueryParams({
offset: withDefault(NumberParam, 0),
limit: withDefault(NumberParam, DEFAULT_PAGE_LIMIT),
query: StringParam,
favoritesFirst: withDefault(BooleanParam, true),
sortBy: withDefault(StringParam, 'createdAt'),
sortOrder: withDefault(StringParam, 'desc'),
});
const [tableState, setTableState] = usePersistentTableState(
'features-list-table',
{
offset: withDefault(NumberParam, 0),
limit: withDefault(NumberParam, DEFAULT_PAGE_LIMIT),
query: StringParam,
favoritesFirst: withDefault(BooleansStringParam, true),
sortBy: withDefault(StringParam, 'createdAt'),
sortOrder: withDefault(StringParam, 'desc'),
},
);
const {
features = [],
total,

View File

@ -0,0 +1,40 @@
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import { createLocalStorage } from 'utils/createLocalStorage';
import { useQueryParams } from 'use-query-params';
const usePersistentSearchParams = (key: string) => {
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;
}
setSearchParams(value, { replace: true });
}, []);
return setValue;
};
export const usePersistentTableState = <
T extends Parameters<typeof useQueryParams>[0],
>(
key: string,
queryParamsDefinition: T,
) => {
const updateStoredParams = usePersistentSearchParams(key);
const [tableState, setTableState] = useQueryParams(queryParamsDefinition);
useEffect(() => {
const { offset, ...rest } = tableState;
updateStoredParams(rest);
}, [JSON.stringify(tableState)]);
return [tableState, setTableState] as const;
};

View File

@ -0,0 +1,30 @@
// Custom additional serializers for query params library
// used in `useQueryParams` hook
const encodeBoolean = (
bool: boolean | null | undefined,
): string | null | undefined => {
if (bool == null) {
return bool;
}
return bool ? 'true' : 'false';
};
const decodeBoolean = (
input: string | (string | null)[] | null | undefined,
): boolean | null | undefined => {
if (input === 'true') {
return true;
}
if (input === 'false') {
return false;
}
return null;
};
export const BooleansStringParam = {
encode: encodeBoolean,
decode: decodeBoolean,
};