1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-10-18 20:09:08 +02:00
unleash.unleash/frontend/src/component/feature/FeatureStrategy/FeatureStrategyRemove/FeatureStrategyRemove.tsx
2022-11-30 12:04:29 +01:00

241 lines
7.8 KiB
TypeScript

import React, { FC, useState } from 'react';
import useFeatureStrategyApi from 'hooks/api/actions/useFeatureStrategyApi/useFeatureStrategyApi';
import { formatUnknownError } from 'utils/formatUnknownError';
import { useNavigate } from 'react-router-dom';
import useToast from 'hooks/useToast';
import { formatFeaturePath } from '../FeatureStrategyEdit/FeatureStrategyEdit';
import { Dialogue } from 'component/common/Dialogue/Dialogue';
import { Alert, styled, Typography } from '@mui/material';
import PermissionButton from 'component/common/PermissionButton/PermissionButton';
import { DELETE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { STRATEGY_FORM_REMOVE_ID } from 'utils/testIds';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
import { Delete } from '@mui/icons-material';
import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests';
interface IFeatureStrategyRemoveProps {
projectId: string;
featureId: string;
environmentId: string;
strategyId: string;
disabled?: boolean;
icon?: boolean;
}
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,
featureId,
environmentId,
strategyId,
}: IRemoveProps) => {
const { deleteStrategyFromFeature } = useFeatureStrategyApi();
const { setToastData, setToastApiError } = useToast();
const navigate = useNavigate();
const { refetchFeature } = useFeature(projectId, featureId);
const onRemove = async (event: React.FormEvent) => {
try {
event.preventDefault();
await deleteStrategyFromFeature(
projectId,
featureId,
environmentId,
strategyId
);
setToastData({
title: 'Strategy deleted',
type: 'success',
});
refetchFeature();
navigate(formatFeaturePath(projectId, featureId));
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
};
return onRemove;
};
const useOnSuggestRemove = ({
projectId,
featureId,
environmentId,
strategyId,
}: IRemoveProps) => {
const { addChange } = useChangeRequestApi();
const { refetch: refetchChangeRequests } =
usePendingChangeRequests(projectId);
const { setToastData, setToastApiError } = useToast();
const onSuggestRemove = async (event: React.FormEvent) => {
try {
event.preventDefault();
await addChange(projectId, environmentId, {
action: 'deleteStrategy',
feature: featureId,
payload: {
id: strategyId,
},
});
setToastData({
title: 'Changes added to the draft!',
type: 'success',
});
await refetchChangeRequests();
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
};
return onSuggestRemove;
};
export const FeatureStrategyRemove = ({
projectId,
featureId,
environmentId,
strategyId,
disabled,
icon,
}: IFeatureStrategyRemoveProps) => {
const [openDialogue, setOpenDialogue] = useState(false);
const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId);
const onRemove = useOnRemove({
featureId,
projectId,
strategyId,
environmentId,
});
const onSuggestRemove = useOnSuggestRemove({
featureId,
projectId,
strategyId,
environmentId,
});
return (
<>
<ConditionallyRender
condition={Boolean(icon)}
show={
<PermissionIconButton
onClick={() => setOpenDialogue(true)}
projectId={projectId}
environmentId={environmentId}
disabled={disabled}
permission={DELETE_FEATURE_STRATEGY}
data-testid={STRATEGY_FORM_REMOVE_ID}
tooltipProps={{ title: 'Remove strategy' }}
type="button"
>
<Delete />
</PermissionIconButton>
}
elseShow={
<PermissionButton
onClick={() => setOpenDialogue(true)}
projectId={projectId}
environmentId={environmentId}
disabled={disabled}
permission={DELETE_FEATURE_STRATEGY}
data-testid={STRATEGY_FORM_REMOVE_ID}
color="secondary"
variant="text"
type="button"
>
Remove strategy
</PermissionButton>
}
/>
<ConditionallyRender
condition={isChangeRequestConfigured(environmentId)}
show={
<SuggestFeatureStrategyRemoveDialogue
isOpen={openDialogue}
onClose={() => setOpenDialogue(false)}
onRemove={async e => {
await onSuggestRemove(e);
setOpenDialogue(false);
}}
/>
}
elseShow={
<FeatureStrategyRemoveDialogue
isOpen={openDialogue}
onClose={() => setOpenDialogue(false)}
onRemove={onRemove}
/>
}
/>
</>
);
};