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

feat: delete features FE (#3350)

This commit is contained in:
Jaanus Sellin 2023-03-21 10:45:02 +02:00 committed by GitHub
parent 8a03e5526c
commit 076768215e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 19 deletions

View File

@ -1,12 +1,16 @@
import { FC } from 'react';
import { FC, useState } from 'react';
import { Button } from '@mui/material';
import { Undo } from '@mui/icons-material';
import { UPDATE_FEATURE } from 'component/providers/AccessProvider/permissions';
import {
DELETE_FEATURE,
UPDATE_FEATURE,
} from 'component/providers/AccessProvider/permissions';
import { PermissionHOC } from 'component/common/PermissionHOC/PermissionHOC';
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
import { formatUnknownError } from 'utils/formatUnknownError';
import { useFeaturesArchive } from 'hooks/api/getters/useFeaturesArchive/useFeaturesArchive';
import useToast from 'hooks/useToast';
import { ArchivedFeatureDeleteConfirm } from './ArchivedFeatureActionCell/ArchivedFeatureDeleteConfirm/ArchivedFeatureDeleteConfirm';
interface IArchiveBatchActionsProps {
selectedIds: string[];
@ -20,6 +24,7 @@ export const ArchiveBatchActions: FC<IArchiveBatchActionsProps> = ({
const { reviveFeatures } = useProjectApi();
const { setToastData, setToastApiError } = useToast();
const { refetchArchived } = useFeaturesArchive(projectId);
const [deleteModalOpen, setDeleteModalOpen] = useState(false);
const onRevive = async () => {
try {
@ -34,6 +39,10 @@ export const ArchiveBatchActions: FC<IArchiveBatchActionsProps> = ({
setToastApiError(formatUnknownError(error));
}
};
const onDelete = async () => {
setDeleteModalOpen(true);
};
return (
<>
<PermissionHOC projectId={projectId} permission={UPDATE_FEATURE}>
@ -49,6 +58,26 @@ export const ArchiveBatchActions: FC<IArchiveBatchActionsProps> = ({
</Button>
)}
</PermissionHOC>
<PermissionHOC projectId={projectId} permission={DELETE_FEATURE}>
{({ hasAccess }) => (
<Button
disabled={!hasAccess}
startIcon={<Undo />}
variant="outlined"
size="small"
onClick={onDelete}
>
Delete
</Button>
)}
</PermissionHOC>
<ArchivedFeatureDeleteConfirm
deletedFeatures={selectedIds}
projectId={projectId}
open={deleteModalOpen}
setOpen={setDeleteModalOpen}
refetch={refetchArchived}
/>
</>
);
};

View File

@ -341,7 +341,8 @@ export const ArchiveTable = ({
)}
/>
<ArchivedFeatureDeleteConfirm
deletedFeature={deletedFeature}
deletedFeatures={[deletedFeature?.name!]}
projectId={projectId!}
open={deleteModalOpen}
setOpen={setDeleteModalOpen}
refetch={refetch}

View File

@ -2,13 +2,13 @@ import { Alert, styled } from '@mui/material';
import React, { useState } from 'react';
import { Dialogue } from 'component/common/Dialogue/Dialogue';
import Input from 'component/common/Input/Input';
import { IFeatureToggle } from 'interfaces/featureToggle';
import { formatUnknownError } from 'utils/formatUnknownError';
import { useFeatureArchiveApi } from 'hooks/api/actions/useFeatureArchiveApi/useReviveFeatureApi';
import useToast from 'hooks/useToast';
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
interface IArchivedFeatureDeleteConfirmProps {
deletedFeature?: IFeatureToggle;
deletedFeatures: string[];
projectId: string;
open: boolean;
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
refetch: () => void;
@ -23,27 +23,32 @@ const StyledFormInput = styled(Input)(({ theme }) => ({
width: '100%',
}));
const confirmationText = 'I want to delete';
export const ArchivedFeatureDeleteConfirm = ({
deletedFeature,
deletedFeatures,
projectId,
open,
setOpen,
refetch,
}: IArchivedFeatureDeleteConfirmProps) => {
const [confirmName, setConfirmName] = useState('');
const { setToastData, setToastApiError } = useToast();
const { deleteFeature } = useFeatureArchiveApi();
const { deleteFeatures } = useProjectApi();
const onDeleteFeatureToggle = async () => {
try {
if (!deletedFeature) {
if (deletedFeatures.length === 0) {
return;
}
await deleteFeature(deletedFeature.name);
await deleteFeatures(projectId, deletedFeatures);
await refetch();
setToastData({
type: 'success',
title: 'Feature toggle deleted',
text: `You have successfully deleted the ${deletedFeature.name} feature toggle.`,
title: 'Feature toggles deleted',
text: `You have successfully deleted following features toggles: ${deletedFeatures.join(
', '
)}.`,
});
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
@ -61,13 +66,13 @@ export const ArchivedFeatureDeleteConfirm = ({
return (
<Dialogue
title="Delete feature toggle?"
title="Delete feature toggles?"
open={open}
primaryButtonText="Delete feature toggle"
primaryButtonText="Delete feature toggles"
secondaryButtonText="Cancel"
onClick={onDeleteFeatureToggle}
onClose={clearModal}
disabledPrimaryButton={deletedFeature?.name !== confirmName}
disabledPrimaryButton={confirmationText !== confirmName}
formId={formId}
>
<Alert severity="warning">
@ -78,8 +83,9 @@ export const ArchivedFeatureDeleteConfirm = ({
</Alert>
<StyledDeleteParagraph>
In order to delete this feature toggle, please enter its name in
the text field below: <strong>{deletedFeature?.name}</strong>
In order to delete feature toggles, please enter the following
confirmation text in the text field below:{' '}
<strong>I want to delete</strong>
</StyledDeleteParagraph>
<form id={formId}>
@ -89,8 +95,8 @@ export const ArchivedFeatureDeleteConfirm = ({
setConfirmName(e.currentTarget.value);
}}
value={confirmName}
placeholder="<feature toggle name>"
label="Feature toggle name"
placeholder="<deletion confirmation>"
label="Deletetion confirmation"
/>
</form>
</Dialogue>

View File

@ -223,6 +223,16 @@ const useProjectApi = () => {
return makeRequest(req.caller, req.id);
};
const deleteFeatures = async (projectId: string, featureIds: string[]) => {
const path = `api/admin/projects/${projectId}/delete`;
const req = createRequest(path, {
method: 'POST',
body: JSON.stringify({ features: featureIds }),
});
return makeRequest(req.caller, req.id);
};
const staleFeatures = async (
projectId: string,
featureIds: string[],
@ -257,6 +267,7 @@ const useProjectApi = () => {
archiveFeatures,
reviveFeatures,
staleFeatures,
deleteFeatures,
searchProjectUser,
errors,
loading,