1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-06-14 01:16:17 +02:00

refactor: pass feature to feature overview metadata component (#9803)

This commit is contained in:
Mateusz Kwasniewski 2025-04-18 14:24:48 +02:00 committed by GitHub
parent e436cf72e6
commit 916ee157ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 93 additions and 51 deletions

View File

@ -86,6 +86,8 @@ export const FeatureOverview = () => {
onEnvironmentVisibilityChange={ onEnvironmentVisibilityChange={
onEnvironmentVisibilityChange onEnvironmentVisibilityChange
} }
feature={feature}
onChange={refetchFeature}
/> />
</div> </div>
<StyledMainContent> <StyledMainContent>

View File

@ -66,14 +66,6 @@ const setupChangeRequestApi = () => {
); );
}; };
const setupFeatureApi = (feature: IFeatureToggle) => {
testServerRoute(
server,
'/api/admin/projects/default/features/feature',
feature,
);
};
beforeEach(() => { beforeEach(() => {
setupApi(); setupApi();
}); });
@ -81,12 +73,16 @@ beforeEach(() => {
const route = '/projects/default/features/feature'; const route = '/projects/default/features/feature';
test('show dependency dialogue', async () => { test('show dependency dialogue', async () => {
setupFeatureApi(feature);
render( render(
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={feature}
onChange={() => {}}
/>
}
/> />
</Routes>, </Routes>,
{ {
@ -105,18 +101,23 @@ test('show dependency dialogue', async () => {
}); });
test('show dependency dialogue for OSS with dependencies', async () => { test('show dependency dialogue for OSS with dependencies', async () => {
setupOssWithExistingDependencies(); const feature = {
setupFeatureApi({
name: 'feature', name: 'feature',
project: 'default', project: 'default',
dependencies: [] as Array<{ feature: string }>, dependencies: [] as Array<{ feature: string }>,
children: [] as string[], children: [] as string[],
} as IFeatureToggle); } as IFeatureToggle;
setupOssWithExistingDependencies();
render( render(
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={feature}
onChange={() => {}}
/>
}
/> />
</Routes>, </Routes>,
{ {
@ -135,17 +136,22 @@ test('show dependency dialogue for OSS with dependencies', async () => {
}); });
test('show child', async () => { test('show child', async () => {
setupFeatureApi({ const feature = {
name: 'feature', name: 'feature',
project: 'default', project: 'default',
dependencies: [] as Array<{ feature: string }>, dependencies: [] as Array<{ feature: string }>,
children: ['some_child'], children: ['some_child'],
} as IFeatureToggle); } as IFeatureToggle;
render( render(
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={feature}
onChange={() => {}}
/>
}
/> />
</Routes>, </Routes>,
{ route }, { route },
@ -156,17 +162,22 @@ test('show child', async () => {
}); });
test('show children', async () => { test('show children', async () => {
setupFeatureApi({ const feature = {
name: 'feature', name: 'feature',
project: 'default', project: 'default',
dependencies: [] as Array<{ feature: string }>, dependencies: [] as Array<{ feature: string }>,
children: ['some_child', 'some_other_child'], children: ['some_child', 'some_other_child'],
} as IFeatureToggle); } as IFeatureToggle;
render( render(
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={feature}
onChange={() => {}}
/>
}
/> />
</Routes>, </Routes>,
{ route }, { route },
@ -184,17 +195,22 @@ const feature = {
} as IFeatureToggle; } as IFeatureToggle;
test('delete dependency', async () => { test('delete dependency', async () => {
setupFeatureApi({ const featureWithDeps = {
...feature, ...feature,
dependencies: [{ feature: 'some_parent' }], dependencies: [{ feature: 'some_parent' }],
}); };
render( render(
<> <>
<ToastRenderer /> <ToastRenderer />
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={featureWithDeps}
onChange={() => {}}
/>
}
/> />
</Routes> </Routes>
</>, </>,
@ -221,18 +237,23 @@ test('delete dependency', async () => {
}); });
test('delete dependency with change request', async () => { test('delete dependency with change request', async () => {
setupChangeRequestApi(); const featureWithDeps = {
setupFeatureApi({
...feature, ...feature,
dependencies: [{ feature: 'some_parent' }], dependencies: [{ feature: 'some_parent' }],
}); };
setupChangeRequestApi();
render( render(
<> <>
<ToastRenderer /> <ToastRenderer />
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={featureWithDeps}
onChange={() => {}}
/>
}
/> />
</Routes> </Routes>
</>, </>,
@ -259,15 +280,20 @@ test('delete dependency with change request', async () => {
}); });
test('edit dependency', async () => { test('edit dependency', async () => {
setupFeatureApi({ const featureWithDeps = {
...feature, ...feature,
dependencies: [{ feature: 'some_parent', enabled: false }], dependencies: [{ feature: 'some_parent', enabled: false }],
}); };
render( render(
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={featureWithDeps}
onChange={() => {}}
/>
}
/> />
</Routes>, </Routes>,
{ {
@ -295,7 +321,7 @@ test('edit dependency', async () => {
}); });
test('show variant dependencies', async () => { test('show variant dependencies', async () => {
setupFeatureApi({ const featureWithDeps = {
...feature, ...feature,
dependencies: [ dependencies: [
{ {
@ -304,12 +330,17 @@ test('show variant dependencies', async () => {
variants: ['variantA', 'variantB'], variants: ['variantA', 'variantB'],
}, },
], ],
}); };
render( render(
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={featureWithDeps}
onChange={() => {}}
/>
}
/> />
</Routes>, </Routes>,
{ route }, { route },
@ -324,7 +355,7 @@ test('show variant dependencies', async () => {
}); });
test('show variant dependency', async () => { test('show variant dependency', async () => {
setupFeatureApi({ const featureWithDeps = {
...feature, ...feature,
dependencies: [ dependencies: [
{ {
@ -333,12 +364,17 @@ test('show variant dependency', async () => {
variants: ['variantA'], variants: ['variantA'],
}, },
], ],
}); };
render( render(
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={featureWithDeps}
onChange={() => {}}
/>
}
/> />
</Routes>, </Routes>,
{ route }, { route },
@ -348,7 +384,7 @@ test('show variant dependency', async () => {
}); });
test('show disabled dependency', async () => { test('show disabled dependency', async () => {
setupFeatureApi({ const featureWithDeps = {
...feature, ...feature,
dependencies: [ dependencies: [
{ {
@ -356,12 +392,17 @@ test('show disabled dependency', async () => {
enabled: false, enabled: false,
}, },
], ],
}); };
render( render(
<Routes> <Routes>
<Route <Route
path={'/projects/:projectId/features/:featureId'} path={'/projects/:projectId/features/:featureId'}
element={<FeatureOverviewMetaData />} element={
<FeatureOverviewMetaData
feature={featureWithDeps}
onChange={() => {}}
/>
}
/> />
</Routes>, </Routes>,
{ route }, { route },

View File

@ -1,8 +1,6 @@
import { type FC, useState } from 'react'; import { type FC, useState } from 'react';
import { styled } from '@mui/material'; import { styled } from '@mui/material';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveDialog'; import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveDialog';
import { FeatureArchiveNotAllowedDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveNotAllowedDialog'; import { FeatureArchiveNotAllowedDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveNotAllowedDialog';
import { formatDateYMD } from 'utils/formatDate'; import { formatDateYMD } from 'utils/formatDate';
@ -17,6 +15,7 @@ import { capitalizeFirst } from 'utils/capitalizeFirst';
import { Collaborators } from './Collaborators'; import { Collaborators } from './Collaborators';
import { EnvironmentVisibilityMenu } from './EnvironmentVisibilityMenu/EnvironmentVisibilityMenu'; import { EnvironmentVisibilityMenu } from './EnvironmentVisibilityMenu/EnvironmentVisibilityMenu';
import { Truncator } from 'component/common/Truncator/Truncator'; import { Truncator } from 'component/common/Truncator/Truncator';
import type { IFeatureToggle } from '../../../../../interfaces/featureToggle';
const StyledMetaDataContainer = styled('div')(({ theme }) => ({ const StyledMetaDataContainer = styled('div')(({ theme }) => ({
padding: theme.spacing(3), padding: theme.spacing(3),
@ -69,16 +68,16 @@ export const StyledMetaDataItemValue = styled('div')(({ theme }) => ({
type FeatureOverviewMetaDataProps = { type FeatureOverviewMetaDataProps = {
hiddenEnvironments?: string[]; hiddenEnvironments?: string[];
onEnvironmentVisibilityChange?: (environment: string) => void; onEnvironmentVisibilityChange?: (environment: string) => void;
feature: IFeatureToggle;
onChange: () => void;
}; };
const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({ const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
hiddenEnvironments, hiddenEnvironments,
onEnvironmentVisibilityChange, onEnvironmentVisibilityChange,
feature,
onChange,
}) => { }) => {
const projectId = useRequiredPathParam('projectId');
const featureId = useRequiredPathParam('featureId');
const { feature, refetchFeature } = useFeature(projectId, featureId);
const { locationSettings } = useLocationSettings(); const { locationSettings } = useLocationSettings();
const navigate = useNavigate(); const navigate = useNavigate();
@ -125,7 +124,7 @@ const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
onComplete={() => onComplete={() =>
setMarkCompletedDialogueOpen(true) setMarkCompletedDialogueOpen(true)
} }
onUncomplete={refetchFeature} onUncomplete={onChange}
/> />
</StyledMetaDataItem> </StyledMetaDataItem>
) : null} ) : null}
@ -181,7 +180,7 @@ const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
{feature.children.length > 0 ? ( {feature.children.length > 0 ? (
<FeatureArchiveNotAllowedDialog <FeatureArchiveNotAllowedDialog
features={feature.children} features={feature.children}
project={projectId} project={feature.project}
isOpen={archiveDialogOpen} isOpen={archiveDialogOpen}
onClose={() => setArchiveDialogOpen(false)} onClose={() => setArchiveDialogOpen(false)}
/> />
@ -189,11 +188,11 @@ const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
<FeatureArchiveDialog <FeatureArchiveDialog
isOpen={archiveDialogOpen} isOpen={archiveDialogOpen}
onConfirm={() => { onConfirm={() => {
navigate(`/projects/${projectId}`); navigate(`/projects/${feature.project}`);
}} }}
onClose={() => setArchiveDialogOpen(false)} onClose={() => setArchiveDialogOpen(false)}
projectId={projectId} projectId={feature.project}
featureIds={[featureId]} featureIds={[feature.name]}
/> />
)} )}
{feature.project ? ( {feature.project ? (
@ -202,7 +201,7 @@ const FeatureOverviewMetaData: FC<FeatureOverviewMetaDataProps> = ({
setIsOpen={setMarkCompletedDialogueOpen} setIsOpen={setMarkCompletedDialogueOpen}
projectId={feature.project} projectId={feature.project}
featureId={feature.name} featureId={feature.name}
onComplete={refetchFeature} onComplete={onChange}
/> />
) : null} ) : null}
</> </>