mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
feat: connect project overview table to search api (#5237)
This commit is contained in:
parent
598d022a5a
commit
d074254b61
@ -72,6 +72,7 @@ interface IProjectFeatureTogglesProps {
|
||||
features: IProject['features'];
|
||||
environments: IProject['environments'];
|
||||
loading: boolean;
|
||||
onChange: () => void;
|
||||
}
|
||||
|
||||
const staticColumns = ['Select', 'Actions', 'name', 'favorite'];
|
||||
@ -84,6 +85,7 @@ export const ProjectFeatureToggles = ({
|
||||
features,
|
||||
loading,
|
||||
environments: newEnvironments = [],
|
||||
onChange,
|
||||
}: IProjectFeatureTogglesProps) => {
|
||||
const { classes: styles } = useStyles();
|
||||
const theme = useTheme();
|
||||
@ -118,7 +120,6 @@ export const ProjectFeatureToggles = ({
|
||||
? [{ environment: 'a' }, { environment: 'b' }, { environment: 'c' }]
|
||||
: newEnvironments,
|
||||
);
|
||||
const { refetch } = useProject(projectId);
|
||||
const { isFavoritesPinned, sortTypes, onChangeIsFavoritePinned } =
|
||||
usePinnedFavorites(
|
||||
searchParams.has('favorites')
|
||||
@ -140,9 +141,9 @@ export const ProjectFeatureToggles = ({
|
||||
} else {
|
||||
await favorite(projectId, feature.name);
|
||||
}
|
||||
refetch();
|
||||
onChange();
|
||||
},
|
||||
[projectId, refetch],
|
||||
[projectId, onChange],
|
||||
);
|
||||
|
||||
const showTagsColumn = useMemo(
|
||||
@ -263,7 +264,7 @@ export const ProjectFeatureToggles = ({
|
||||
projectId,
|
||||
name,
|
||||
isChangeRequestEnabled,
|
||||
refetch,
|
||||
onChange,
|
||||
onFeatureToggle,
|
||||
);
|
||||
|
||||
@ -617,16 +618,14 @@ export const ProjectFeatureToggles = ({
|
||||
isOpen={Boolean(featureStaleDialogState.featureId)}
|
||||
onClose={() => {
|
||||
setFeatureStaleDialogState({});
|
||||
refetch();
|
||||
onChange();
|
||||
}}
|
||||
featureId={featureStaleDialogState.featureId || ''}
|
||||
projectId={projectId}
|
||||
/>
|
||||
<FeatureArchiveDialog
|
||||
isOpen={Boolean(featureArchiveState)}
|
||||
onConfirm={() => {
|
||||
refetch();
|
||||
}}
|
||||
onConfirm={onChange}
|
||||
onClose={() => {
|
||||
setFeatureArchiveState(undefined);
|
||||
}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import useProject, {
|
||||
useProjectNameOrId,
|
||||
} from 'hooks/api/getters/useProject/useProject';
|
||||
@ -12,6 +12,7 @@ import { useLastViewedProject } from 'hooks/useLastViewedProject';
|
||||
import { ProjectStats } from './ProjectStats/ProjectStats';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
import { useFeatureSearch } from '../../../hooks/api/getters/useFeatureSearch/useFeatureSearch';
|
||||
|
||||
const refreshInterval = 15 * 1000;
|
||||
|
||||
@ -34,10 +35,50 @@ const StyledContentContainer = styled(Box)(() => ({
|
||||
minWidth: 0,
|
||||
}));
|
||||
|
||||
const InfiniteProjectOverview = () => {
|
||||
const projectId = useRequiredPathParam('projectId');
|
||||
const { project, loading: projectLoading } = useProject(projectId, {
|
||||
refreshInterval,
|
||||
});
|
||||
const [nextCursor, setNextCursor] = useState('');
|
||||
const {
|
||||
features: searchFeatures,
|
||||
refetch,
|
||||
loading,
|
||||
} = useFeatureSearch(nextCursor, projectId, { refreshInterval });
|
||||
const { members, features, health, description, environments, stats } =
|
||||
project;
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<ProjectInfo
|
||||
id={projectId}
|
||||
description={description}
|
||||
memberCount={members}
|
||||
health={health}
|
||||
features={features}
|
||||
stats={stats}
|
||||
/>
|
||||
<StyledContentContainer>
|
||||
<ProjectStats stats={project.stats} />
|
||||
<StyledProjectToggles>
|
||||
<ProjectFeatureToggles
|
||||
key={loading ? 'loading' : 'ready'}
|
||||
features={searchFeatures.features}
|
||||
environments={environments}
|
||||
loading={loading}
|
||||
onChange={refetch}
|
||||
/>
|
||||
</StyledProjectToggles>
|
||||
</StyledContentContainer>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const ProjectOverview = () => {
|
||||
const projectId = useRequiredPathParam('projectId');
|
||||
const projectName = useProjectNameOrId(projectId);
|
||||
const { project, loading } = useProject(projectId, {
|
||||
const { project, loading, refetch } = useProject(projectId, {
|
||||
refreshInterval,
|
||||
});
|
||||
const { members, features, health, description, environments, stats } =
|
||||
@ -45,11 +86,14 @@ const ProjectOverview = () => {
|
||||
usePageTitle(`Project overview – ${projectName}`);
|
||||
const { setLastViewed } = useLastViewedProject();
|
||||
const featureSwitchRefactor = useUiFlag('featureSwitchRefactor');
|
||||
const featureSearchFrontend = useUiFlag('featureSearchFrontend');
|
||||
|
||||
useEffect(() => {
|
||||
setLastViewed(projectId);
|
||||
}, [projectId, setLastViewed]);
|
||||
|
||||
if (featureSearchFrontend) return <InfiniteProjectOverview />;
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<ProjectInfo
|
||||
@ -71,6 +115,7 @@ const ProjectOverview = () => {
|
||||
features={features}
|
||||
environments={environments}
|
||||
loading={loading}
|
||||
onChange={refetch}
|
||||
/>
|
||||
)}
|
||||
elseShow={() => (
|
||||
|
@ -13,14 +13,18 @@ interface IUseFeatureSearchOutput {
|
||||
refetch: () => void;
|
||||
}
|
||||
|
||||
const fallbackFeatures: { features: IFeatureToggleListItem[] } = {
|
||||
const fallbackFeatures: { features: IFeatureToggleListItem[]; total: number } =
|
||||
{
|
||||
features: [],
|
||||
total: 0,
|
||||
};
|
||||
|
||||
export const useFeatureSearch = (
|
||||
cursor: string,
|
||||
projectId = '',
|
||||
options: SWRConfiguration = {},
|
||||
): IUseFeatureSearchOutput => {
|
||||
const { KEY, fetcher } = getFeatureSearchFetcher();
|
||||
const { KEY, fetcher } = getFeatureSearchFetcher(projectId, cursor);
|
||||
const { data, error, mutate } = useSWR<IFeatureSearchResponse>(
|
||||
KEY,
|
||||
fetcher,
|
||||
@ -39,9 +43,11 @@ export const useFeatureSearch = (
|
||||
};
|
||||
};
|
||||
|
||||
const getFeatureSearchFetcher = () => {
|
||||
const getFeatureSearchFetcher = (projectId: string, cursor: string) => {
|
||||
const KEY = `api/admin/search/features?projectId=${projectId}&cursor=${cursor}`;
|
||||
|
||||
const fetcher = () => {
|
||||
const path = formatApiPath(`api/admin/search/features`);
|
||||
const path = formatApiPath(KEY);
|
||||
return fetch(path, {
|
||||
method: 'GET',
|
||||
})
|
||||
@ -49,8 +55,6 @@ const getFeatureSearchFetcher = () => {
|
||||
.then((res) => res.json());
|
||||
};
|
||||
|
||||
const KEY = `api/admin/search/features`;
|
||||
|
||||
return {
|
||||
fetcher,
|
||||
KEY,
|
||||
|
@ -71,6 +71,8 @@ export type UiFlags = {
|
||||
playgroundImprovements?: boolean;
|
||||
featureSwitchRefactor?: boolean;
|
||||
scheduledConfigurationChanges?: boolean;
|
||||
featureSearchAPI?: boolean;
|
||||
featureSearchFrontend?: boolean;
|
||||
};
|
||||
|
||||
export interface IVersionInfo {
|
||||
|
@ -86,6 +86,7 @@ exports[`should create default config 1`] = `
|
||||
"embedProxyFrontend": true,
|
||||
"featureNamingPattern": false,
|
||||
"featureSearchAPI": false,
|
||||
"featureSearchFrontend": false,
|
||||
"featureSwitchRefactor": false,
|
||||
"featuresExportImport": true,
|
||||
"filterInvalidClientMetrics": false,
|
||||
|
@ -36,6 +36,7 @@ export type IFlagKey =
|
||||
| 'playgroundImprovements'
|
||||
| 'featureSwitchRefactor'
|
||||
| 'featureSearchAPI'
|
||||
| 'featureSearchFrontend'
|
||||
| 'scheduledConfigurationChanges';
|
||||
|
||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||
@ -168,6 +169,10 @@ const flags: IFlags = {
|
||||
process.env.UNLEASH_EXPERIMENTAL_FEATURE_SEARCH_API,
|
||||
false,
|
||||
),
|
||||
featureSearchFrontend: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_EXPERIMENTAL_FEATURE_SEARCH_FRONTEND,
|
||||
false,
|
||||
),
|
||||
scheduledConfigurationChanges: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_EXPERIMENTAL_SCHEDULED_CONFIGURATION_CHANGES,
|
||||
false,
|
||||
|
@ -49,6 +49,7 @@ process.nextTick(async () => {
|
||||
playgroundImprovements: true,
|
||||
featureSwitchRefactor: true,
|
||||
featureSearchAPI: true,
|
||||
featureSearchFrontend: false,
|
||||
},
|
||||
},
|
||||
authentication: {
|
||||
|
Loading…
Reference in New Issue
Block a user