1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-08 01:15:49 +02:00

Change request - edit strategy (#2334)

* feat: request change - add strategy

* refactor: use change request is-enabled hook

* feat: edit strategy

* fix: prettier formatting

* fix: refetch change request draft after adding
This commit is contained in:
Tymoteusz Czech 2022-11-04 11:55:45 +01:00 committed by GitHub
parent d2000f2848
commit 4b281d9513
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 62 deletions

View File

@ -19,7 +19,7 @@ import {
import { import {
formatStrategyName, formatStrategyName,
GetFeatureStrategyIcon, GetFeatureStrategyIcon,
} from '../../../utils/strategyNames'; } from 'utils/strategyNames';
import { IChangeRequestEnabled } from '../changeRequest.types'; import { IChangeRequestEnabled } from '../changeRequest.types';
interface IChangeRequestProps { interface IChangeRequestProps {

View File

@ -29,6 +29,7 @@ import { IFeatureToggle } from 'interfaces/featureToggle';
import { comparisonModerator } from '../featureStrategy.utils'; import { comparisonModerator } from '../featureStrategy.utils';
import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { useChangeRequestOpen } from 'hooks/api/getters/useChangeRequestOpen/useChangeRequestOpen';
export const FeatureStrategyCreate = () => { export const FeatureStrategyCreate = () => {
const projectId = useRequiredPathParam('projectId'); const projectId = useRequiredPathParam('projectId');
@ -51,6 +52,7 @@ export const FeatureStrategyCreate = () => {
const { feature, refetchFeature } = useFeature(projectId, featureId); const { feature, refetchFeature } = useFeature(projectId, featureId);
const ref = useRef<IFeatureToggle>(feature); const ref = useRef<IFeatureToggle>(feature);
const isChangeRequestEnabled = useChangeRequestsEnabled(); const isChangeRequestEnabled = useChangeRequestsEnabled();
const { refetch: refetchChangeRequests } = useChangeRequestOpen(projectId);
const isChangeRequest = const isChangeRequest =
isChangeRequestEnabled && environmentId === 'production'; // FIXME: get from API - is it enabled isChangeRequestEnabled && environmentId === 'production'; // FIXME: get from API - is it enabled
@ -106,20 +108,19 @@ export const FeatureStrategyCreate = () => {
}); });
}; };
const onAddStrategySuggestion = async ( const onStrategyRequestAdd = async (payload: IFeatureStrategyPayload) => {
payload: IFeatureStrategyPayload
) => {
await addChangeRequest(projectId, environmentId, { await addChangeRequest(projectId, environmentId, {
action: 'addStrategy', action: 'addStrategy',
feature: featureId, feature: featureId,
payload, payload,
}); });
// TODO: segments in change requests // FIXME: segments in change requests
setToastData({ setToastData({
title: 'Strategy added to draft', title: 'Strategy added to draft',
type: 'success', type: 'success',
confetti: true, confetti: true,
}); });
refetchChangeRequests();
}; };
const onSubmit = async () => { const onSubmit = async () => {
@ -127,7 +128,7 @@ export const FeatureStrategyCreate = () => {
try { try {
if (isChangeRequest) { if (isChangeRequest) {
await onAddStrategySuggestion(payload); await onStrategyRequestAdd(payload);
} else { } else {
await onAddStrategy(payload); await onAddStrategy(payload);
} }

View File

@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { FeatureStrategyForm } from 'component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm'; import { FeatureStrategyForm } from 'component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm';
import FormTemplate from 'component/common/FormTemplate/FormTemplate'; import FormTemplate from 'component/common/FormTemplate/FormTemplate';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
@ -25,6 +25,9 @@ import { useCollaborateData } from 'hooks/useCollaborateData';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { IFeatureToggle } from 'interfaces/featureToggle'; import { IFeatureToggle } from 'interfaces/featureToggle';
import { comparisonModerator } from '../featureStrategy.utils'; import { comparisonModerator } from '../featureStrategy.utils';
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
import { useChangeRequestOpen } from 'hooks/api/getters/useChangeRequestOpen/useChangeRequestOpen';
export const FeatureStrategyEdit = () => { export const FeatureStrategyEdit = () => {
const projectId = useRequiredPathParam('projectId'); const projectId = useRequiredPathParam('projectId');
@ -42,6 +45,12 @@ export const FeatureStrategyEdit = () => {
const { uiConfig } = useUiConfig(); const { uiConfig } = useUiConfig();
const { unleashUrl } = uiConfig; const { unleashUrl } = uiConfig;
const navigate = useNavigate(); const navigate = useNavigate();
const { addChangeRequest } = useChangeRequestApi();
const isChangeRequestEnabled = useChangeRequestsEnabled();
const { refetch: refetchChangeRequests } = useChangeRequestOpen(projectId);
const isChangeRequest =
isChangeRequestEnabled && environmentId === 'production'; // FIXME: get from API - is it enabled
const { feature, refetchFeature } = useFeature(projectId, featureId); const { feature, refetchFeature } = useFeature(projectId, featureId);
@ -87,29 +96,54 @@ export const FeatureStrategyEdit = () => {
savedStrategySegments && setSegments(savedStrategySegments); savedStrategySegments && setSegments(savedStrategySegments);
}, [savedStrategySegments]); }, [savedStrategySegments]);
const onSubmit = async () => { const onStrategyEdit = async (payload: IFeatureStrategyPayload) => {
try { await updateStrategyOnFeature(
await updateStrategyOnFeature( projectId,
projectId, featureId,
featureId, environmentId,
strategyId,
payload
);
if (uiConfig.flags.SE) {
await setStrategySegments({
environmentId, environmentId,
projectId,
strategyId, strategyId,
createStrategyPayload(strategy) segmentIds: segments.map(s => s.id),
);
if (uiConfig.flags.SE) {
await setStrategySegments({
environmentId,
projectId,
strategyId,
segmentIds: segments.map(s => s.id),
});
await refetchSavedStrategySegments();
}
setToastData({
title: 'Strategy updated',
type: 'success',
confetti: true,
}); });
await refetchSavedStrategySegments();
}
setToastData({
title: 'Strategy updated',
type: 'success',
confetti: true,
});
};
const onStrategyRequestEdit = async (payload: IFeatureStrategyPayload) => {
await addChangeRequest(projectId, environmentId, {
action: 'updateStrategy',
feature: featureId,
payload: { ...payload, id: strategyId },
});
// FIXME: segments in change requests
setToastData({
title: 'Change added to draft',
type: 'success',
confetti: true,
});
refetchChangeRequests();
};
const onSubmit = async () => {
const payload = createStrategyPayload(strategy);
try {
if (isChangeRequest) {
await onStrategyRequestEdit(payload);
} else {
await onStrategyEdit(payload);
}
refetchFeature(); refetchFeature();
navigate(formatFeaturePath(projectId, featureId)); navigate(formatFeaturePath(projectId, featureId));
} catch (error: unknown) { } catch (error: unknown) {
@ -152,6 +186,7 @@ export const FeatureStrategyEdit = () => {
loading={loading} loading={loading}
permission={UPDATE_FEATURE_STRATEGY} permission={UPDATE_FEATURE_STRATEGY}
errors={errors} errors={errors}
isChangeRequest={isChangeRequest}
/> />
{staleDataNotification} {staleDataNotification}
</FormTemplate> </FormTemplate>
@ -160,13 +195,11 @@ export const FeatureStrategyEdit = () => {
export const createStrategyPayload = ( export const createStrategyPayload = (
strategy: Partial<IFeatureStrategy> strategy: Partial<IFeatureStrategy>
): IFeatureStrategyPayload => { ): IFeatureStrategyPayload => ({
return { name: strategy.name,
name: strategy.name, constraints: strategy.constraints ?? [],
constraints: strategy.constraints ?? [], parameters: strategy.parameters ?? {},
parameters: strategy.parameters ?? {}, });
};
};
export const formatFeaturePath = ( export const formatFeaturePath = (
projectId: string, projectId: string,

View File

@ -9,9 +9,9 @@ export const FeatureStrategyChangeRequestAlert: VFC<
IFeatureStrategyChangeRequestAlertProps IFeatureStrategyChangeRequestAlertProps
> = ({ environment }) => ( > = ({ environment }) => (
<Alert severity="info"> <Alert severity="info">
Change requests are enabled{environment ? ` for ${environment}` : ''}. <strong>Change requests</strong> are enabled
Your changes needs to be approved before they will be live. All the {environment ? ` for ${environment}` : ''}. Your changes needs to be
changes you do now will be added into a draft that you can submit for approved before they will be live. All the changes you do now will be
review. added into a draft that you can submit for review.
</Alert> </Alert>
); );

View File

@ -1,4 +1,6 @@
import React, { useState, useContext } from 'react'; import React, { useState, useContext } from 'react';
import { useNavigate } from 'react-router-dom';
import { Button } from '@mui/material';
import { import {
IFeatureStrategy, IFeatureStrategy,
IFeatureStrategyParameters, IFeatureStrategyParameters,
@ -7,15 +9,8 @@ import {
import { FeatureStrategyType } from '../FeatureStrategyType/FeatureStrategyType'; import { FeatureStrategyType } from '../FeatureStrategyType/FeatureStrategyType';
import { FeatureStrategyEnabled } from './FeatureStrategyEnabled/FeatureStrategyEnabled'; import { FeatureStrategyEnabled } from './FeatureStrategyEnabled/FeatureStrategyEnabled';
import { FeatureStrategyConstraints } from '../FeatureStrategyConstraints/FeatureStrategyConstraints'; import { FeatureStrategyConstraints } from '../FeatureStrategyConstraints/FeatureStrategyConstraints';
import { Button } from '@mui/material';
import {
FeatureStrategyProdGuard,
useFeatureStrategyProdGuard,
} from '../FeatureStrategyProdGuard/FeatureStrategyProdGuard';
import { IFeatureToggle } from 'interfaces/featureToggle'; import { IFeatureToggle } from 'interfaces/featureToggle';
import { useStyles } from './FeatureStrategyForm.styles'; import { useStyles } from './FeatureStrategyForm.styles';
import { formatFeaturePath } from '../FeatureStrategyEdit/FeatureStrategyEdit';
import { useNavigate } from 'react-router-dom';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { STRATEGY_FORM_SUBMIT_ID } from 'utils/testIds'; import { STRATEGY_FORM_SUBMIT_ID } from 'utils/testIds';
@ -28,6 +23,11 @@ import { IFormErrors } from 'hooks/useFormErrors';
import { validateParameterValue } from 'utils/validateParameterValue'; import { validateParameterValue } from 'utils/validateParameterValue';
import { useStrategy } from 'hooks/api/getters/useStrategy/useStrategy'; import { useStrategy } from 'hooks/api/getters/useStrategy/useStrategy';
import { FeatureStrategyChangeRequestAlert } from './FeatureStrategyChangeRequestAlert/FeatureStrategyChangeRequestAlert'; import { FeatureStrategyChangeRequestAlert } from './FeatureStrategyChangeRequestAlert/FeatureStrategyChangeRequestAlert';
import {
FeatureStrategyProdGuard,
useFeatureStrategyProdGuard,
} from '../FeatureStrategyProdGuard/FeatureStrategyProdGuard';
import { formatFeaturePath } from '../FeatureStrategyEdit/FeatureStrategyEdit';
interface IFeatureStrategyFormProps { interface IFeatureStrategyFormProps {
feature: IFeatureToggle; feature: IFeatureToggle;
@ -129,23 +129,19 @@ export const FeatureStrategyForm = ({
return ( return (
<form className={styles.form} onSubmit={onSubmitWithValidation}> <form className={styles.form} onSubmit={onSubmitWithValidation}>
<div> <ConditionallyRender
<ConditionallyRender condition={Boolean(isChangeRequest)}
condition={Boolean(isChangeRequest)} show={
show={ <FeatureStrategyChangeRequestAlert
<FeatureStrategyChangeRequestAlert environment={environmentId}
environment={environmentId} />
/> }
} />
elseShow={ <FeatureStrategyEnabled
<FeatureStrategyEnabled projectId={feature.project}
projectId={feature.project} featureId={feature.name}
featureId={feature.name} environmentId={environmentId}
environmentId={environmentId} />
/>
}
/>
</div>
<hr className={styles.hr} /> <hr className={styles.hr} />
<ConditionallyRender <ConditionallyRender
condition={Boolean(uiConfig.flags.SE)} condition={Boolean(uiConfig.flags.SE)}