From d2000f28486695e7675107c56834c1f294e87997 Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Fri, 4 Nov 2022 11:25:06 +0100 Subject: [PATCH] feat: request change - add strategy (#2330) * feat: request change - add strategy * refactor: use change request is-enabled hook --- .../FeatureStrategyCreate.tsx | 74 ++++++++++++++----- .../FeatureStrategyChangeRequestAlert.tsx | 17 +++++ .../FeatureStrategyEnabled.tsx | 2 +- .../FeatureStrategyForm.tsx | 29 ++++++-- 4 files changed, 94 insertions(+), 28 deletions(-) create mode 100644 frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyChangeRequestAlert/FeatureStrategyChangeRequestAlert.tsx rename frontend/src/component/feature/FeatureStrategy/{ => FeatureStrategyForm}/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx (96%) diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate.tsx index 562a8ad6b9..231db097be 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate.tsx @@ -8,7 +8,7 @@ import useFeatureStrategyApi from 'hooks/api/actions/useFeatureStrategyApi/useFe import { formatUnknownError } from 'utils/formatUnknownError'; import { useNavigate } from 'react-router-dom'; import useToast from 'hooks/useToast'; -import { IFeatureStrategy } from 'interfaces/strategy'; +import { IFeatureStrategy, IFeatureStrategyPayload } from 'interfaces/strategy'; import { featureStrategyDocsLink, featureStrategyHelp, @@ -27,6 +27,8 @@ import { useCollaborateData } from 'hooks/useCollaborateData'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import { IFeatureToggle } from 'interfaces/featureToggle'; import { comparisonModerator } from '../featureStrategy.utils'; +import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; +import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; export const FeatureStrategyCreate = () => { const projectId = useRequiredPathParam('projectId'); @@ -39,6 +41,7 @@ export const FeatureStrategyCreate = () => { const errors = useFormErrors(); const { addStrategyToFeature, loading } = useFeatureStrategyApi(); + const { addChangeRequest } = useChangeRequestApi(); const { setStrategySegments } = useSegmentsApi(); const { setToastData, setToastApiError } = useToast(); const { uiConfig } = useUiConfig(); @@ -47,6 +50,10 @@ export const FeatureStrategyCreate = () => { const { feature, refetchFeature } = useFeature(projectId, featureId); const ref = useRef(feature); + const isChangeRequestEnabled = useChangeRequestsEnabled(); + + const isChangeRequest = + isChangeRequestEnabled && environmentId === 'production'; // FIXME: get from API - is it enabled const { data, staleDataNotification, forceRefreshCache } = useCollaborateData( @@ -77,27 +84,53 @@ export const FeatureStrategyCreate = () => { } }, [featureId, strategyDefinition]); - const onSubmit = async () => { - try { - const created = await addStrategyToFeature( - projectId, - featureId, + const onAddStrategy = async (payload: IFeatureStrategyPayload) => { + const created = await addStrategyToFeature( + projectId, + featureId, + environmentId, + payload + ); + if (uiConfig.flags.SE) { + await setStrategySegments({ environmentId, - createStrategyPayload(strategy) - ); - if (uiConfig.flags.SE) { - await setStrategySegments({ - environmentId, - projectId, - strategyId: created.id, - segmentIds: segments.map(s => s.id), - }); - } - setToastData({ - title: 'Strategy created', - type: 'success', - confetti: true, + projectId, + strategyId: created.id, + segmentIds: segments.map(s => s.id), }); + } + setToastData({ + title: 'Strategy created', + type: 'success', + confetti: true, + }); + }; + + const onAddStrategySuggestion = async ( + payload: IFeatureStrategyPayload + ) => { + await addChangeRequest(projectId, environmentId, { + action: 'addStrategy', + feature: featureId, + payload, + }); + // TODO: segments in change requests + setToastData({ + title: 'Strategy added to draft', + type: 'success', + confetti: true, + }); + }; + + const onSubmit = async () => { + const payload = createStrategyPayload(strategy); + + try { + if (isChangeRequest) { + await onAddStrategySuggestion(payload); + } else { + await onAddStrategy(payload); + } refetchFeature(); navigate(formatFeaturePath(projectId, featureId)); } catch (error: unknown) { @@ -135,6 +168,7 @@ export const FeatureStrategyCreate = () => { loading={loading} permission={CREATE_FEATURE_STRATEGY} errors={errors} + isChangeRequest={isChangeRequest} /> {staleDataNotification} diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyChangeRequestAlert/FeatureStrategyChangeRequestAlert.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyChangeRequestAlert/FeatureStrategyChangeRequestAlert.tsx new file mode 100644 index 0000000000..498a54d9cd --- /dev/null +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyChangeRequestAlert/FeatureStrategyChangeRequestAlert.tsx @@ -0,0 +1,17 @@ +import { VFC } from 'react'; +import { Alert } from '@mui/material'; + +interface IFeatureStrategyChangeRequestAlertProps { + environment?: string; +} + +export const FeatureStrategyChangeRequestAlert: VFC< + IFeatureStrategyChangeRequestAlertProps +> = ({ environment }) => ( + + Change requests are enabled{environment ? ` for ${environment}` : ''}. + Your changes needs to be approved before they will be live. All the + changes you do now will be added into a draft that you can submit for + review. + +); diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx similarity index 96% rename from frontend/src/component/feature/FeatureStrategy/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx rename to frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx index 3b373074e3..3ad8820e96 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx @@ -3,7 +3,7 @@ import { Link } from 'react-router-dom'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Alert } from '@mui/material'; import { IFeatureToggle } from 'interfaces/featureToggle'; -import { formatFeaturePath } from '../FeatureStrategyEdit/FeatureStrategyEdit'; +import { formatFeaturePath } from '../../FeatureStrategyEdit/FeatureStrategyEdit'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; interface IFeatureStrategyEnabledProps { diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx index 7e9f6ba9a7..da2d6c0931 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx @@ -5,7 +5,7 @@ import { IStrategyParameter, } from 'interfaces/strategy'; import { FeatureStrategyType } from '../FeatureStrategyType/FeatureStrategyType'; -import { FeatureStrategyEnabled } from '../FeatureStrategyEnabled/FeatureStrategyEnabled'; +import { FeatureStrategyEnabled } from './FeatureStrategyEnabled/FeatureStrategyEnabled'; import { FeatureStrategyConstraints } from '../FeatureStrategyConstraints/FeatureStrategyConstraints'; import { Button } from '@mui/material'; import { @@ -27,6 +27,7 @@ import { ISegment } from 'interfaces/segment'; import { IFormErrors } from 'hooks/useFormErrors'; import { validateParameterValue } from 'utils/validateParameterValue'; import { useStrategy } from 'hooks/api/getters/useStrategy/useStrategy'; +import { FeatureStrategyChangeRequestAlert } from './FeatureStrategyChangeRequestAlert/FeatureStrategyChangeRequestAlert'; interface IFeatureStrategyFormProps { feature: IFeatureToggle; @@ -34,6 +35,7 @@ interface IFeatureStrategyFormProps { permission: string; onSubmit: () => void; loading: boolean; + isChangeRequest?: boolean; strategy: Partial; setStrategy: React.Dispatch< React.SetStateAction> @@ -54,6 +56,7 @@ export const FeatureStrategyForm = ({ segments, setSegments, errors, + isChangeRequest, }: IFeatureStrategyFormProps) => { const { classes: styles } = useStyles(); const [showProdGuard, setShowProdGuard] = useState(false); @@ -115,7 +118,9 @@ export const FeatureStrategyForm = ({ event.preventDefault(); if (!validateAllParameters()) { return; - } else if (enableProdGuard) { + } + + if (enableProdGuard && !isChangeRequest) { setShowProdGuard(true); } else { onSubmit(); @@ -125,10 +130,20 @@ export const FeatureStrategyForm = ({ return (
- + } + elseShow={ + + } />

@@ -176,7 +191,7 @@ export const FeatureStrategyForm = ({ } data-testid={STRATEGY_FORM_SUBMIT_ID} > - Save strategy + {isChangeRequest ? 'Add change to draft' : 'Save strategy'}