mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: extract global feature search (#7372)
We need global search for command menu, so extracting into separate hook.
This commit is contained in:
parent
9b23442b1c
commit
ffe1305934
@ -31,23 +31,7 @@ import { focusable } from 'themes/themeStyles';
|
|||||||
import { FeatureEnvironmentSeenCell } from 'component/common/Table/cells/FeatureSeenCell/FeatureEnvironmentSeenCell';
|
import { FeatureEnvironmentSeenCell } from 'component/common/Table/cells/FeatureSeenCell/FeatureEnvironmentSeenCell';
|
||||||
import useToast from 'hooks/useToast';
|
import useToast from 'hooks/useToast';
|
||||||
import { FeatureToggleFilters } from './FeatureToggleFilters/FeatureToggleFilters';
|
import { FeatureToggleFilters } from './FeatureToggleFilters/FeatureToggleFilters';
|
||||||
import {
|
|
||||||
DEFAULT_PAGE_LIMIT,
|
|
||||||
useFeatureSearch,
|
|
||||||
} from 'hooks/api/getters/useFeatureSearch/useFeatureSearch';
|
|
||||||
import mapValues from 'lodash.mapvalues';
|
|
||||||
import {
|
|
||||||
BooleansStringParam,
|
|
||||||
FilterItemParam,
|
|
||||||
} from 'utils/serializeQueryParams';
|
|
||||||
import {
|
|
||||||
encodeQueryParams,
|
|
||||||
NumberParam,
|
|
||||||
StringParam,
|
|
||||||
withDefault,
|
|
||||||
} from 'use-query-params';
|
|
||||||
import { withTableState } from 'utils/withTableState';
|
import { withTableState } from 'utils/withTableState';
|
||||||
import { usePersistentTableState } from 'hooks/usePersistentTableState';
|
|
||||||
import { FeatureTagCell } from 'component/common/Table/cells/FeatureTagCell/FeatureTagCell';
|
import { FeatureTagCell } from 'component/common/Table/cells/FeatureTagCell/FeatureTagCell';
|
||||||
import { FeatureSegmentCell } from 'component/common/Table/cells/FeatureSegmentCell/FeatureSegmentCell';
|
import { FeatureSegmentCell } from 'component/common/Table/cells/FeatureSegmentCell/FeatureSegmentCell';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
@ -56,6 +40,7 @@ import useLoading from 'hooks/useLoading';
|
|||||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
|
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
|
||||||
import { useFeedback } from '../../feedbackNew/useFeedback';
|
import { useFeedback } from '../../feedbackNew/useFeedback';
|
||||||
import ReviewsOutlined from '@mui/icons-material/ReviewsOutlined';
|
import ReviewsOutlined from '@mui/icons-material/ReviewsOutlined';
|
||||||
|
import { useGlobalFeatureSearch } from './useGlobalFeatureSearch';
|
||||||
|
|
||||||
export const featuresPlaceholder = Array(15).fill({
|
export const featuresPlaceholder = Array(15).fill({
|
||||||
name: 'Name of the feature',
|
name: 'Name of the feature',
|
||||||
@ -94,45 +79,16 @@ export const FeatureToggleListTable: VFC = () => {
|
|||||||
variant,
|
variant,
|
||||||
);
|
);
|
||||||
|
|
||||||
const stateConfig = {
|
|
||||||
offset: withDefault(NumberParam, 0),
|
|
||||||
limit: withDefault(NumberParam, DEFAULT_PAGE_LIMIT),
|
|
||||||
query: StringParam,
|
|
||||||
favoritesFirst: withDefault(BooleansStringParam, true),
|
|
||||||
sortBy: withDefault(StringParam, 'createdAt'),
|
|
||||||
sortOrder: withDefault(StringParam, 'desc'),
|
|
||||||
project: FilterItemParam,
|
|
||||||
tag: FilterItemParam,
|
|
||||||
state: FilterItemParam,
|
|
||||||
segment: FilterItemParam,
|
|
||||||
createdAt: FilterItemParam,
|
|
||||||
type: FilterItemParam,
|
|
||||||
};
|
|
||||||
const [tableState, setTableState] = usePersistentTableState(
|
|
||||||
'features-list-table',
|
|
||||||
stateConfig,
|
|
||||||
);
|
|
||||||
const {
|
const {
|
||||||
offset,
|
features,
|
||||||
limit,
|
|
||||||
query,
|
|
||||||
favoritesFirst,
|
|
||||||
sortBy,
|
|
||||||
sortOrder,
|
|
||||||
...filterState
|
|
||||||
} = tableState;
|
|
||||||
|
|
||||||
const {
|
|
||||||
features = [],
|
|
||||||
total,
|
total,
|
||||||
loading,
|
|
||||||
refetch: refetchFeatures,
|
refetch: refetchFeatures,
|
||||||
|
loading,
|
||||||
initialLoad,
|
initialLoad,
|
||||||
} = useFeatureSearch(
|
tableState,
|
||||||
mapValues(encodeQueryParams(stateConfig, tableState), (value) =>
|
setTableState,
|
||||||
value ? `${value}` : undefined,
|
filterState,
|
||||||
),
|
} = useGlobalFeatureSearch();
|
||||||
);
|
|
||||||
const bodyLoadingRef = useLoading(loading);
|
const bodyLoadingRef = useLoading(loading);
|
||||||
const { favorite, unfavorite } = useFavoriteFeaturesApi();
|
const { favorite, unfavorite } = useFavoriteFeaturesApi();
|
||||||
const onFavorite = useCallback(
|
const onFavorite = useCallback(
|
||||||
@ -158,10 +114,10 @@ export const FeatureToggleListTable: VFC = () => {
|
|||||||
columnHelper.accessor('favorite', {
|
columnHelper.accessor('favorite', {
|
||||||
header: () => (
|
header: () => (
|
||||||
<FavoriteIconHeader
|
<FavoriteIconHeader
|
||||||
isActive={favoritesFirst}
|
isActive={tableState.favoritesFirst}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setTableState({
|
setTableState({
|
||||||
favoritesFirst: !favoritesFirst,
|
favoritesFirst: !tableState.favoritesFirst,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -262,7 +218,7 @@ export const FeatureToggleListTable: VFC = () => {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
[favoritesFirst],
|
[tableState.favoritesFirst],
|
||||||
);
|
);
|
||||||
|
|
||||||
const data = useMemo(
|
const data = useMemo(
|
||||||
@ -338,7 +294,9 @@ export const FeatureToggleListTable: VFC = () => {
|
|||||||
<Search
|
<Search
|
||||||
placeholder='Search'
|
placeholder='Search'
|
||||||
expandable
|
expandable
|
||||||
initialValue={query || ''}
|
initialValue={
|
||||||
|
tableState.query || ''
|
||||||
|
}
|
||||||
onChange={setSearchValue}
|
onChange={setSearchValue}
|
||||||
id='globalFeatureFlags'
|
id='globalFeatureFlags'
|
||||||
/>
|
/>
|
||||||
@ -429,7 +387,7 @@ export const FeatureToggleListTable: VFC = () => {
|
|||||||
condition={isSmallScreen}
|
condition={isSmallScreen}
|
||||||
show={
|
show={
|
||||||
<Search
|
<Search
|
||||||
initialValue={query || ''}
|
initialValue={tableState.query || ''}
|
||||||
onChange={setSearchValue}
|
onChange={setSearchValue}
|
||||||
id='globalFeatureFlags'
|
id='globalFeatureFlags'
|
||||||
/>
|
/>
|
||||||
@ -442,7 +400,7 @@ export const FeatureToggleListTable: VFC = () => {
|
|||||||
onChange={setTableState}
|
onChange={setTableState}
|
||||||
state={filterState}
|
state={filterState}
|
||||||
/>
|
/>
|
||||||
<SearchHighlightProvider value={query || ''}>
|
<SearchHighlightProvider value={tableState.query || ''}>
|
||||||
<div ref={bodyLoadingRef}>
|
<div ref={bodyLoadingRef}>
|
||||||
<PaginatedTable tableInstance={table} totalItems={total} />
|
<PaginatedTable tableInstance={table} totalItems={total} />
|
||||||
</div>
|
</div>
|
||||||
@ -452,11 +410,11 @@ export const FeatureToggleListTable: VFC = () => {
|
|||||||
show={
|
show={
|
||||||
<Box sx={(theme) => ({ padding: theme.spacing(0, 2, 2) })}>
|
<Box sx={(theme) => ({ padding: theme.spacing(0, 2, 2) })}>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={(query || '')?.length > 0}
|
condition={(tableState.query || '')?.length > 0}
|
||||||
show={
|
show={
|
||||||
<TablePlaceholder>
|
<TablePlaceholder>
|
||||||
No feature flags found matching “
|
No feature flags found matching “
|
||||||
{query}
|
{tableState.query}
|
||||||
”
|
”
|
||||||
</TablePlaceholder>
|
</TablePlaceholder>
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
import {
|
||||||
|
encodeQueryParams,
|
||||||
|
NumberParam,
|
||||||
|
StringParam,
|
||||||
|
withDefault,
|
||||||
|
} from 'use-query-params';
|
||||||
|
import {
|
||||||
|
DEFAULT_PAGE_LIMIT,
|
||||||
|
useFeatureSearch,
|
||||||
|
} from 'hooks/api/getters/useFeatureSearch/useFeatureSearch';
|
||||||
|
import {
|
||||||
|
BooleansStringParam,
|
||||||
|
FilterItemParam,
|
||||||
|
} from 'utils/serializeQueryParams';
|
||||||
|
import { usePersistentTableState } from 'hooks/usePersistentTableState';
|
||||||
|
import mapValues from 'lodash.mapvalues';
|
||||||
|
|
||||||
|
export const useGlobalFeatureSearch = (storageKey = 'features-list-table') => {
|
||||||
|
const stateConfig = {
|
||||||
|
offset: withDefault(NumberParam, 0),
|
||||||
|
limit: withDefault(NumberParam, DEFAULT_PAGE_LIMIT),
|
||||||
|
query: StringParam,
|
||||||
|
favoritesFirst: withDefault(BooleansStringParam, true),
|
||||||
|
sortBy: withDefault(StringParam, 'createdAt'),
|
||||||
|
sortOrder: withDefault(StringParam, 'desc'),
|
||||||
|
project: FilterItemParam,
|
||||||
|
tag: FilterItemParam,
|
||||||
|
state: FilterItemParam,
|
||||||
|
segment: FilterItemParam,
|
||||||
|
createdAt: FilterItemParam,
|
||||||
|
type: FilterItemParam,
|
||||||
|
};
|
||||||
|
const [tableState, setTableState] = usePersistentTableState(
|
||||||
|
`${storageKey}`,
|
||||||
|
stateConfig,
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
offset,
|
||||||
|
limit,
|
||||||
|
query,
|
||||||
|
favoritesFirst,
|
||||||
|
sortBy,
|
||||||
|
sortOrder,
|
||||||
|
...filterState
|
||||||
|
} = tableState;
|
||||||
|
|
||||||
|
const {
|
||||||
|
features = [],
|
||||||
|
total,
|
||||||
|
loading,
|
||||||
|
refetch,
|
||||||
|
initialLoad,
|
||||||
|
} = useFeatureSearch(
|
||||||
|
mapValues(encodeQueryParams(stateConfig, tableState), (value) =>
|
||||||
|
value ? `${value}` : undefined,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
features,
|
||||||
|
total,
|
||||||
|
refetch,
|
||||||
|
loading,
|
||||||
|
initialLoad,
|
||||||
|
tableState,
|
||||||
|
setTableState,
|
||||||
|
filterState,
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user