diff --git a/frontend/src/component/common/FeatureArchiveDialog/FeatureArchiveDialog.tsx b/frontend/src/component/common/FeatureArchiveDialog/FeatureArchiveDialog.tsx index e64c8fb1db..13610fc663 100644 --- a/frontend/src/component/common/FeatureArchiveDialog/FeatureArchiveDialog.tsx +++ b/frontend/src/component/common/FeatureArchiveDialog/FeatureArchiveDialog.tsx @@ -11,10 +11,8 @@ import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests'; import { useHighestPermissionChangeRequestEnvironment } from 'hooks/useHighestPermissionChangeRequestEnvironment'; -import { - ChangeRequestIdentityData, - useScheduledChangeRequestsWithFlags, -} from 'hooks/api/getters/useScheduledChangeRequestsWithFlags/useScheduledChangeRequestsWithFlags'; +import { useScheduledChangeRequestsWithFlags } from 'hooks/api/getters/useScheduledChangeRequestsWithFlags/useScheduledChangeRequestsWithFlags'; +import { ScheduledChangeRequestViewModel } from 'hooks/api/getters/useScheduledChangeRequestsWithStrategy/useScheduledChangeRequestsWithStrategy'; interface IFeatureArchiveDialogProps { isOpen: boolean; @@ -128,7 +126,7 @@ const ArchiveParentError = ({ }; const ScheduledChangeRequestAlert: VFC<{ - changeRequests?: ChangeRequestIdentityData[]; + changeRequests?: ScheduledChangeRequestViewModel[]; projectId: string; }> = ({ changeRequests, projectId }) => { if (changeRequests && changeRequests.length > 0) { diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyDraggableItem.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyDraggableItem.tsx index a3a83cde5c..d91182c573 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyDraggableItem.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyDraggableItem.tsx @@ -14,7 +14,7 @@ import { ChangesScheduledBadge } from 'component/changeRequest/ModifiedInChangeR import { IFeatureChange } from 'component/changeRequest/changeRequest.types'; import { Badge } from 'component/common/Badge/Badge'; import { - ChangeRequestIdentityData, + ScheduledChangeRequestViewModel, useScheduledChangeRequestsWithStrategy, } from 'hooks/api/getters/useScheduledChangeRequestsWithStrategy/useScheduledChangeRequestsWithStrategy'; @@ -114,7 +114,7 @@ const ChangeRequestStatusBadge = ({ const renderHeaderChildren = ( changes?: UseStrategyChangeFromRequestResult, - scheduledChanges?: ChangeRequestIdentityData[], + scheduledChanges?: ScheduledChangeRequestViewModel[], ): JSX.Element[] => { const badges: JSX.Element[] = []; if (changes?.length === 0 && scheduledChanges?.length === 0) { diff --git a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsCard.test.tsx b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsCard.test.tsx index 8ab488802a..583086a6ff 100644 --- a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsCard.test.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsCard.test.tsx @@ -136,6 +136,25 @@ const changeRequestConfig = () => 'get', ); +const disableChangeRequests = () => + testServerRoute( + server, + '/api/admin/projects/default/change-requests/config', + [ + { + environment: 'development', + type: 'development', + changeRequestEnabled: false, + }, + { + environment: 'production', + type: 'production', + changeRequestEnabled: false, + }, + ], + 'get', + ); + const feature = () => { testServerRoute(server, '/api/admin/projects/default/features/feature1', { environments: [ @@ -246,7 +265,28 @@ describe('Change request badges for variants', () => { testServerRoute( server, - '/api/admin/projects/default/change-requests/pending/feature1', + '/api/admin/projects/default/change-requests/scheduled', + [changeRequest], + ); + + render(, { + route: '/projects/default/features/feature1/variants', + permissions: [ + { + permission: ADMIN, + }, + ], + }); + await screen.findByText('Changes Scheduled'); + }); + + test('should render the badge when scheduled request with "patchVariant" action when change requests are disabled', async () => { + disableChangeRequests(); + const changeRequest = scheduledRequest('patchVariant', 1); + + testServerRoute( + server, + '/api/admin/projects/default/change-requests/scheduled', [changeRequest], ); diff --git a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/useVariantsFromScheduledRequests.ts b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/useVariantsFromScheduledRequests.ts index 325e088773..e47cd6ef31 100644 --- a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/useVariantsFromScheduledRequests.ts +++ b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/useVariantsFromScheduledRequests.ts @@ -1,39 +1,25 @@ -import { usePendingChangeRequestsForFeature } from 'hooks/api/getters/usePendingChangeRequestsForFeature/usePendingChangeRequestsForFeature'; +import { useScheduledChangeRequestsWithVariant } from 'hooks/api/getters/useScheduledChangeRequestsWithVariants/useScheduledChangeRequestsWithVariant'; export const useVariantsFromScheduledRequests = ( projectId: string, featureId: string, environment: string, ): number[] => { - const { changeRequests } = usePendingChangeRequestsForFeature( + const { changeRequests } = useScheduledChangeRequestsWithVariant( projectId, featureId, ); - const scheduledEnvironmentRequests = - changeRequests?.filter( - (request) => - request.environment === environment && - request.state === 'Scheduled', - ) || []; + const filtered = changeRequests?.filter( + (changeRequestIdentity) => + changeRequestIdentity.environment === environment, + ); - const result: number[] = []; - if (scheduledEnvironmentRequests.length === 0) { - return result; + if (filtered) { + return filtered.map( + (changeRequestIdentity) => changeRequestIdentity.id, + ); } - scheduledEnvironmentRequests.forEach((scheduledRequest) => { - const feature = scheduledRequest?.features.find( - (feature) => feature.name === featureId, - ); - const change = feature?.changes.find((change) => { - return change.action === 'patchVariant'; - }); - - if (change) { - result.push(scheduledRequest.id); - } - }); - - return result; + return []; }; diff --git a/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithFlags/useScheduledChangeRequestsWithFlags.ts b/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithFlags/useScheduledChangeRequestsWithFlags.ts index 678e547b4f..d5b96cc9c8 100644 --- a/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithFlags/useScheduledChangeRequestsWithFlags.ts +++ b/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithFlags/useScheduledChangeRequestsWithFlags.ts @@ -1,6 +1,7 @@ import { formatApiPath } from 'utils/formatPath'; import handleErrorResponses from '../httpErrorResponseHandler'; import { useEnterpriseSWR } from '../useEnterpriseSWR/useEnterpriseSWR'; +import { ScheduledChangeRequestViewModel } from '../useScheduledChangeRequestsWithStrategy/useScheduledChangeRequestsWithStrategy'; const fetcher = (path: string) => { return fetch(path) @@ -8,11 +9,6 @@ const fetcher = (path: string) => { .then((res) => res.json()); }; -export type ChangeRequestIdentityData = { - id: number; - title?: string; -}; - export const useScheduledChangeRequestsWithFlags = ( project: string, flags: string[], @@ -20,7 +16,7 @@ export const useScheduledChangeRequestsWithFlags = ( const queryString = flags.map((flag) => `feature=${flag}`).join('&'); const { data, error, mutate } = useEnterpriseSWR< - ChangeRequestIdentityData[] + ScheduledChangeRequestViewModel[] >( [], formatApiPath( diff --git a/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithStrategy/useScheduledChangeRequestsWithStrategy.ts b/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithStrategy/useScheduledChangeRequestsWithStrategy.ts index 02f498ceb4..35d97341e4 100644 --- a/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithStrategy/useScheduledChangeRequestsWithStrategy.ts +++ b/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithStrategy/useScheduledChangeRequestsWithStrategy.ts @@ -8,8 +8,9 @@ const fetcher = (path: string) => { .then((res) => res.json()); }; -export type ChangeRequestIdentityData = { +export type ScheduledChangeRequestViewModel = { id: number; + environment: string; title?: string; }; @@ -18,7 +19,7 @@ export const useScheduledChangeRequestsWithStrategy = ( strategyId: string, ) => { const { data, error, mutate } = useEnterpriseSWR< - ChangeRequestIdentityData[] + ScheduledChangeRequestViewModel[] >( [], formatApiPath( diff --git a/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithVariants/useScheduledChangeRequestsWithVariant.ts b/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithVariants/useScheduledChangeRequestsWithVariant.ts new file mode 100644 index 0000000000..619e36571f --- /dev/null +++ b/frontend/src/hooks/api/getters/useScheduledChangeRequestsWithVariants/useScheduledChangeRequestsWithVariant.ts @@ -0,0 +1,32 @@ +import { formatApiPath } from 'utils/formatPath'; +import handleErrorResponses from '../httpErrorResponseHandler'; +import { useEnterpriseSWR } from '../useEnterpriseSWR/useEnterpriseSWR'; +import { ScheduledChangeRequestViewModel } from '../useScheduledChangeRequestsWithStrategy/useScheduledChangeRequestsWithStrategy'; + +const fetcher = (path: string) => { + return fetch(path) + .then(handleErrorResponses('ChangeRequest')) + .then((res) => res.json()); +}; + +export const useScheduledChangeRequestsWithVariant = ( + project: string, + feature: string, +) => { + const { data, error, mutate } = useEnterpriseSWR< + ScheduledChangeRequestViewModel[] + >( + [], + formatApiPath( + `api/admin/projects/${project}/change-requests/scheduled?variantForFlag=${feature}`, + ), + fetcher, + ); + + return { + changeRequests: data, + loading: !error && !data, + refetch: mutate, + error, + }; +};