diff --git a/frontend/src/component/segments/EditSegment/EditSegment.tsx b/frontend/src/component/segments/EditSegment/EditSegment.tsx index 22f65d1c3b..30d0734496 100644 --- a/frontend/src/component/segments/EditSegment/EditSegment.tsx +++ b/frontend/src/component/segments/EditSegment/EditSegment.tsx @@ -20,6 +20,8 @@ import { SEGMENT_SAVE_BTN_ID } from 'utils/testIds'; import { useSegmentLimits } from 'hooks/api/getters/useSegmentLimits/useSegmentLimits'; import { useOptionalPathParam } from 'hooks/useOptionalPathParam'; import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; +import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; +import { useHighestPermissionChangeRequestEnvironment } from 'hooks/useHighestPermissionChangeRequestEnvironment'; interface IEditSegmentProps { modal?: boolean; @@ -58,13 +60,6 @@ export const EditSegment = ({ modal }: IEditSegmentProps) => { const segmentValuesCount = useSegmentValuesCount(constraints); const { segmentValuesLimit } = useSegmentLimits(); - const { isChangeRequestConfiguredInAnyEnv } = useChangeRequestsEnabled( - segment?.project || '' - ); - const activateSegmentChangeRequests = - uiConfig?.flags?.segmentChangeRequests && - isChangeRequestConfiguredInAnyEnv(); - const overSegmentValuesLimit: boolean = Boolean( segmentValuesLimit && segmentValuesCount > segmentValuesLimit ); @@ -78,28 +73,41 @@ export const EditSegment = ({ modal }: IEditSegmentProps) => { --data-raw '${JSON.stringify(getSegmentPayload(), undefined, 2)}'`; }; + const highestPermissionChangeRequestEnv = + useHighestPermissionChangeRequestEnvironment(segment?.project); + const changeRequestEnv = highestPermissionChangeRequestEnv(); + const activateSegmentChangeRequests = + uiConfig?.flags?.segmentChangeRequests && changeRequestEnv; + const { addChange } = useChangeRequestApi(); + const handleSubmit = async (e: React.FormEvent) => { if (segment) { e.preventDefault(); clearErrors(); try { if (activateSegmentChangeRequests) { - throw new Error( - "You can't add segments to change requests just yet." - ); + await addChange(segment.project || '', changeRequestEnv, { + action: 'updateSegment', + feature: null, + payload: { id: segment.id, ...getSegmentPayload() }, + }); } else { await updateSegment(segment.id, getSegmentPayload()); - refetchSegments(); - if (projectId) { - navigate(`/projects/${projectId}/settings/segments/`); - } else { - navigate('/segments/'); - } - setToastData({ - title: 'Segment updated', - type: 'success', - }); } + refetchSegments(); + if (projectId) { + navigate(`/projects/${projectId}/settings/segments/`); + } else { + navigate('/segments/'); + } + setToastData({ + title: `Segment ${ + activateSegmentChangeRequests + ? 'change added to draft' + : 'updated' + }`, + type: 'success', + }); } catch (error: unknown) { setToastApiError(formatUnknownError(error)); } diff --git a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts index baafb8c2d0..d247a30cdc 100644 --- a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts +++ b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts @@ -2,14 +2,15 @@ import useAPI from '../useApi/useApi'; import { usePlausibleTracker } from '../../../usePlausibleTracker'; export interface IChangeSchema { - feature: string; + feature: string | null; action: | 'updateEnabled' | 'addStrategy' | 'updateStrategy' | 'deleteStrategy' | 'patchVariant' - | 'reorderStrategy'; + | 'reorderStrategy' + | 'updateSegment'; payload: string | boolean | object | number; } diff --git a/frontend/src/hooks/useHighestPermissionChangeRequestEnvironment.test.ts b/frontend/src/hooks/useHighestPermissionChangeRequestEnvironment.test.ts new file mode 100644 index 0000000000..f3f26b1d63 --- /dev/null +++ b/frontend/src/hooks/useHighestPermissionChangeRequestEnvironment.test.ts @@ -0,0 +1,66 @@ +import { getHighestChangeRequestEnv } from './useHighestPermissionChangeRequestEnvironment'; + +describe('Get the right change request env', () => { + it('gets a production env if present', () => { + const data = [ + { + environment: 'x', + type: 'development', + changeRequestEnabled: true, + requiredApprovals: 1, + }, + { + environment: 'y', + type: 'production', + changeRequestEnabled: true, + requiredApprovals: 1, + }, + ]; + + const result = getHighestChangeRequestEnv(data)(); + + expect(result).toBe('y'); + }); + + it('gets a non-production env if no production envs have change requests enabled', () => { + const data = [ + { + environment: 'x', + type: 'development', + changeRequestEnabled: true, + requiredApprovals: 1, + }, + { + environment: 'y', + type: 'production', + changeRequestEnabled: false, + requiredApprovals: 1, + }, + ]; + + const result = getHighestChangeRequestEnv(data)(); + + expect(result).toBe('x'); + }); + + it('returns undefined if no envs have change requests enabled', () => { + const data = [ + { + environment: 'x', + type: 'development', + changeRequestEnabled: false, + requiredApprovals: 1, + }, + { + environment: 'y', + type: 'production', + changeRequestEnabled: false, + requiredApprovals: 1, + }, + ]; + + const result = getHighestChangeRequestEnv(data)(); + + expect(result).toBe(undefined); + }); +}); diff --git a/frontend/src/hooks/useHighestPermissionChangeRequestEnvironment.ts b/frontend/src/hooks/useHighestPermissionChangeRequestEnvironment.ts new file mode 100644 index 0000000000..b649961b35 --- /dev/null +++ b/frontend/src/hooks/useHighestPermissionChangeRequestEnvironment.ts @@ -0,0 +1,24 @@ +import { IChangeRequestEnvironmentConfig } from 'component/changeRequest/changeRequest.types'; +import React from 'react'; +import { useChangeRequestConfig } from './api/getters/useChangeRequestConfig/useChangeRequestConfig'; + +export const getHighestChangeRequestEnv = + (data: IChangeRequestEnvironmentConfig[]) => (): string | undefined => { + const changeRequestEnvs = data.filter(env => env.changeRequestEnabled); + + const env = + changeRequestEnvs.find(env => env.type === 'production') ?? + changeRequestEnvs[0]; + + return env?.environment; + }; + +export const useHighestPermissionChangeRequestEnvironment = ( + projectId?: string +) => { + const { data } = useChangeRequestConfig(projectId || ''); + + return React.useCallback(getHighestChangeRequestEnv(data), [ + JSON.stringify(data), + ]); +};