mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +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