1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-12 13:48:35 +02:00

feat: suggest remove strategy UI (#2321)

* feat: suggest remove strategy UI

* add delete strategy to draft

* refactor: extract hooks

* refactor: consistent fn usage
This commit is contained in:
Mateusz Kwasniewski 2022-11-03 12:26:35 +01:00 committed by GitHub
parent 4937b23e16
commit 147408045b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 152 additions and 24 deletions

View File

@ -1,11 +1,11 @@
import React, { useState } from 'react'; import React, { FC, useState } from 'react';
import useFeatureStrategyApi from 'hooks/api/actions/useFeatureStrategyApi/useFeatureStrategyApi'; import useFeatureStrategyApi from 'hooks/api/actions/useFeatureStrategyApi/useFeatureStrategyApi';
import { formatUnknownError } from 'utils/formatUnknownError'; import { formatUnknownError } from 'utils/formatUnknownError';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import useToast from 'hooks/useToast'; import useToast from 'hooks/useToast';
import { formatFeaturePath } from '../FeatureStrategyEdit/FeatureStrategyEdit'; import { formatFeaturePath } from '../FeatureStrategyEdit/FeatureStrategyEdit';
import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { Dialogue } from 'component/common/Dialogue/Dialogue';
import { Alert } from '@mui/material'; import { Alert, styled, Typography } from '@mui/material';
import PermissionButton from 'component/common/PermissionButton/PermissionButton'; import PermissionButton from 'component/common/PermissionButton/PermissionButton';
import { DELETE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions'; import { DELETE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
@ -13,6 +13,8 @@ import { STRATEGY_FORM_REMOVE_ID } from 'utils/testIds';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
import { Delete } from '@mui/icons-material'; import { Delete } from '@mui/icons-material';
import useUiConfig from '../../../../hooks/api/getters/useUiConfig/useUiConfig';
import { useChangeRequestApi } from '../../../../hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
interface IFeatureStrategyRemoveProps { interface IFeatureStrategyRemoveProps {
projectId: string; projectId: string;
@ -23,19 +25,81 @@ interface IFeatureStrategyRemoveProps {
icon?: boolean; icon?: boolean;
} }
export const FeatureStrategyRemove = ({ interface IFeatureStrategyRemoveDialogueProps {
onRemove: (event: React.FormEvent) => Promise<void>;
onClose: () => void;
isOpen: boolean;
}
const RemoveAlert: FC = () => (
<Alert severity="error">
Removing the strategy will change which users receive access to the
feature.
</Alert>
);
const FeatureStrategyRemoveDialogue: FC<
IFeatureStrategyRemoveDialogueProps
> = ({ onRemove, onClose, isOpen }) => {
return (
<Dialogue
title="Are you sure you want to delete this strategy?"
open={isOpen}
primaryButtonText="Remove strategy"
secondaryButtonText="Cancel"
onClick={onRemove}
onClose={onClose}
>
<RemoveAlert />
</Dialogue>
);
};
const MsgContainer = styled('div')(({ theme }) => ({
marginTop: theme.spacing(3),
marginBottom: theme.spacing(1),
}));
const SuggestFeatureStrategyRemoveDialogue: FC<
IFeatureStrategyRemoveDialogueProps
> = ({ onRemove, onClose, isOpen }) => {
return (
<Dialogue
title="Suggest changes"
open={isOpen}
primaryButtonText="Add suggestion to draft"
secondaryButtonText="Cancel"
onClick={onRemove}
onClose={onClose}
>
<RemoveAlert />
<MsgContainer>
<Typography variant="body2" color="text.secondary">
Your suggestion:
</Typography>
</MsgContainer>
<Typography fontWeight="bold">Remove strategy</Typography>
</Dialogue>
);
};
interface IRemoveProps {
projectId: string;
featureId: string;
environmentId: string;
strategyId: string;
}
const useOnRemove = ({
projectId, projectId,
featureId, featureId,
environmentId, environmentId,
strategyId, strategyId,
disabled, }: IRemoveProps) => {
icon,
}: IFeatureStrategyRemoveProps) => {
const [openDialogue, setOpenDialogue] = useState(false);
const { deleteStrategyFromFeature } = useFeatureStrategyApi(); const { deleteStrategyFromFeature } = useFeatureStrategyApi();
const { refetchFeature } = useFeature(projectId, featureId);
const { setToastData, setToastApiError } = useToast(); const { setToastData, setToastApiError } = useToast();
const navigate = useNavigate(); const navigate = useNavigate();
const { refetchFeature } = useFeature(projectId, featureId);
const onRemove = async (event: React.FormEvent) => { const onRemove = async (event: React.FormEvent) => {
try { try {
@ -56,6 +120,63 @@ export const FeatureStrategyRemove = ({
setToastApiError(formatUnknownError(error)); setToastApiError(formatUnknownError(error));
} }
}; };
return onRemove;
};
const useOnSuggestRemove = ({
projectId,
featureId,
environmentId,
strategyId,
}: IRemoveProps) => {
const { addChangeRequest } = useChangeRequestApi();
const { setToastData, setToastApiError } = useToast();
const onSuggestRemove = async (event: React.FormEvent) => {
try {
event.preventDefault();
await addChangeRequest(projectId, environmentId, {
action: 'deleteStrategy',
feature: featureId,
payload: {
id: strategyId,
},
});
setToastData({
title: 'Changes added to the draft!',
type: 'success',
});
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
};
return onSuggestRemove;
};
export const FeatureStrategyRemove = ({
projectId,
featureId,
environmentId,
strategyId,
disabled,
icon,
}: IFeatureStrategyRemoveProps) => {
const [openDialogue, setOpenDialogue] = useState(false);
const { uiConfig } = useUiConfig();
const suggestChangesEnabled = Boolean(uiConfig?.flags?.changeRequests);
const onRemove = useOnRemove({
featureId,
projectId,
strategyId,
environmentId,
});
const onSuggestRemove = useOnSuggestRemove({
featureId,
projectId,
strategyId,
environmentId,
});
return ( return (
<> <>
@ -91,19 +212,26 @@ export const FeatureStrategyRemove = ({
</PermissionButton> </PermissionButton>
} }
/> />
<Dialogue <ConditionallyRender
title="Are you sure you want to delete this strategy?" condition={suggestChangesEnabled}
open={openDialogue} show={
primaryButtonText="Remove strategy" <SuggestFeatureStrategyRemoveDialogue
secondaryButtonText="Cancel" isOpen={openDialogue}
onClick={onRemove} onClose={() => setOpenDialogue(false)}
onClose={() => setOpenDialogue(false)} onRemove={async e => {
> await onSuggestRemove(e);
<Alert severity="error"> setOpenDialogue(false);
Removing the strategy will change which users receive access }}
to the feature. />
</Alert> }
</Dialogue> elseShow={
<FeatureStrategyRemoveDialogue
isOpen={openDialogue}
onClose={() => setOpenDialogue(false)}
onRemove={onRemove}
/>
}
/>
</> </>
); );
}; };

View File

@ -4,9 +4,9 @@ interface IChangeRequestsSchema {
feature: string; feature: string;
action: action:
| 'updateEnabled' | 'updateEnabled'
| 'strategyAdd' | 'addStrategy'
| 'strategyUpdate' | 'updateStrategy'
| 'strategyDelete'; | 'deleteStrategy';
payload: string | boolean | object | number; payload: string | boolean | object | number;
} }