From 1cf5e125fc2821d4336c58d3e57b127a9f81f633 Mon Sep 17 00:00:00 2001 From: Vladimir Nebolsin Date: Wed, 29 Jan 2025 19:42:11 +0400 Subject: [PATCH] Implement dataset removal functionality --- .../ConfirmPopover/ConfirmPopover.module.scss | 28 ++++++ .../ConfirmPopover/ConfirmPopover.tsx | 91 +++++++++++++++++++ .../RoleSelector/RoleSelector.module.scss | 9 -- .../RoleSelector/RoleSelector.tsx | 68 +++----------- .../DatasetHeader/DatasetHeader.tsx | 34 ++++++- .../DatasetHeader/datasetHeader.module.scss | 9 +- ui/src/store/datasets/datasets.actions.ts | 2 + ui/src/store/datasets/datasets.thunks.ts | 7 ++ 8 files changed, 176 insertions(+), 72 deletions(-) create mode 100644 ui/src/common/components/ConfirmPopover/ConfirmPopover.module.scss create mode 100644 ui/src/common/components/ConfirmPopover/ConfirmPopover.tsx diff --git a/ui/src/common/components/ConfirmPopover/ConfirmPopover.module.scss b/ui/src/common/components/ConfirmPopover/ConfirmPopover.module.scss new file mode 100644 index 0000000..8e0f86c --- /dev/null +++ b/ui/src/common/components/ConfirmPopover/ConfirmPopover.module.scss @@ -0,0 +1,28 @@ +/* + * Copyright 2024 Open Reaction Database Project Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.dropdown { + border: none; + box-shadow: 0 4px 24px 0 #00000014; +} + +.alertIcon { + color: #e4626f; +} + +.popoverButton { + padding: 6px 12px; + font-weight: 400; +} diff --git a/ui/src/common/components/ConfirmPopover/ConfirmPopover.tsx b/ui/src/common/components/ConfirmPopover/ConfirmPopover.tsx new file mode 100644 index 0000000..0dfd97a --- /dev/null +++ b/ui/src/common/components/ConfirmPopover/ConfirmPopover.tsx @@ -0,0 +1,91 @@ +/* + * Copyright 2024 Open Reaction Database Project Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Button, Flex, Popover, type PopoverProps, Text } from '@mantine/core'; +import { AlertCircleIcon } from 'common/icons'; +import classes from './ConfirmPopover.module.scss'; + +interface ConfirmPopoverProps extends PopoverProps { + target: JSX.Element; + title: string; + text: string; + onConfirm: () => void; + onCancel: () => void; +} + +export default function ConfirmPopover({ + target, + title, + text, + onConfirm, + onCancel, + ...rest +}: Readonly) { + return ( + + {target} + + + + + + + {title} + + {text} + + + + + + + + + + ); +} diff --git a/ui/src/pages/ContributePage/GroupsSidebar/GroupsDrawer/RoleSelector/RoleSelector.module.scss b/ui/src/pages/ContributePage/GroupsSidebar/GroupsDrawer/RoleSelector/RoleSelector.module.scss index 2c91bb4..0617ff6 100644 --- a/ui/src/pages/ContributePage/GroupsSidebar/GroupsDrawer/RoleSelector/RoleSelector.module.scss +++ b/ui/src/pages/ContributePage/GroupsSidebar/GroupsDrawer/RoleSelector/RoleSelector.module.scss @@ -44,12 +44,3 @@ text-transform: capitalize; width: 140px; } - -.alertIcon { - color: #e4626f; -} - -.popoverButton { - padding: 6px 12px; - font-weight: 400; -} diff --git a/ui/src/pages/ContributePage/GroupsSidebar/GroupsDrawer/RoleSelector/RoleSelector.tsx b/ui/src/pages/ContributePage/GroupsSidebar/GroupsDrawer/RoleSelector/RoleSelector.tsx index 344955b..e88df1e 100644 --- a/ui/src/pages/ContributePage/GroupsSidebar/GroupsDrawer/RoleSelector/RoleSelector.tsx +++ b/ui/src/pages/ContributePage/GroupsSidebar/GroupsDrawer/RoleSelector/RoleSelector.tsx @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Menu, Button, Popover, Flex, Text } from '@mantine/core'; -import { AlertCircleIcon, CheckIcon, ChevronDownIcon, RemoveIcon } from 'common/icons'; -import classes from './RoleSelector.module.scss'; +import { Menu, Button } from '@mantine/core'; +import { CheckIcon, ChevronDownIcon, RemoveIcon } from 'common/icons'; import { USER_ROLES } from 'common/types/roles'; import { useDisclosure } from '@mantine/hooks'; +import ConfirmPopover from 'common/components/ConfirmPopover/ConfirmPopover'; +import classes from './RoleSelector.module.scss'; interface RoleSelectorProps { value: USER_ROLES; @@ -89,16 +90,14 @@ export function RoleSelector({ value, onChange, onRemove, disabled }: Readonly - - + title="Remove user" + text="Are you sure to remove this user?" + onConfirm={handleConfirm} + onCancel={closeConfirm} + target={ } @@ -106,51 +105,8 @@ export function RoleSelector({ value, onChange, onRemove, disabled }: Readonly Remove - - - - - - - - Remove user - - Are you sure to remove this user? - - - - - - - - - + } + /> ); diff --git a/ui/src/pages/DatasetPage/DatasetHeader/DatasetHeader.tsx b/ui/src/pages/DatasetPage/DatasetHeader/DatasetHeader.tsx index b1dc63c..eee80d8 100644 --- a/ui/src/pages/DatasetPage/DatasetHeader/DatasetHeader.tsx +++ b/ui/src/pages/DatasetPage/DatasetHeader/DatasetHeader.tsx @@ -13,14 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import classes from './datasetHeader.module.scss'; import { DataField } from 'common/components/DataField/DataField'; import { UserField } from 'common/components/UserField/UserField'; import { ActionIcon, Button, Flex, Paper, Title } from '@mantine/core'; import { CopyButton, type CopyButtonOptions } from 'common/components/CopyButton/CopyButton'; import { formatDate } from 'common/utils'; import { DownloadMenu } from 'common/components/DownloadMenu/DownloadMenu'; -import { ChevronDownIcon, EditIcon } from 'common/icons'; +import { ChevronDownIcon, EditIcon, TrashIcon } from 'common/icons'; import type { Dataset } from 'store/datasets/datasets.types'; import { useCallback, useMemo } from 'react'; import { useLocation } from 'wouter'; @@ -30,6 +29,10 @@ import { selectIsDatasetOpened } from 'store/datasets/datasets.selectors'; import { setDatasetEditOpenedAction } from 'store/datasets/datasets.actions'; import { useAppDispatch } from 'store/useAppDispatch'; import { domain, fileDownloadOptions } from 'common/constants'; +import ConfirmPopover from 'common/components/ConfirmPopover/ConfirmPopover'; +import { useDisclosure } from '@mantine/hooks'; +import { removeDataset } from 'store/datasets/datasets.thunks'; +import classes from './datasetHeader.module.scss'; interface DatasetHeaderProps { dataset: Dataset; @@ -39,6 +42,7 @@ export function DatasetHeader({ dataset }: Readonly) { const [location] = useLocation(); const dispatch = useAppDispatch(); const isEditOpened = useSelector(selectIsDatasetOpened); + const [removeConfirmOpened, { open: openRemoveConfirm, close: closeRemoveConfirm }] = useDisclosure(false); const openEdit = useCallback(() => { dispatch(setDatasetEditOpenedAction(true)); @@ -56,6 +60,11 @@ export function DatasetHeader({ dataset }: Readonly) { [dataset.id, location], ); + const handleDatasetRemove = useCallback(() => { + dispatch(removeDataset(dataset.id)); + closeRemoveConfirm(); + }, [dispatch, closeRemoveConfirm, dataset.id]); + return ( ) {
+ } + onClick={openRemoveConfirm} + > + Remove + + } + /> + ('set_edit_opened'); export const updateDatasetActions = createAsyncAction, Dataset>('update'); + +export const removeDatasetActions = createAsyncAction('remove_dataset'); diff --git a/ui/src/store/datasets/datasets.thunks.ts b/ui/src/store/datasets/datasets.thunks.ts index 5d75d1e..09d7434 100644 --- a/ui/src/store/datasets/datasets.thunks.ts +++ b/ui/src/store/datasets/datasets.thunks.ts @@ -19,6 +19,7 @@ import { getDatasetActions, getDatasetPageActions, getGroupsInitialDatasetListActions, + removeDatasetActions, updateDatasetActions, } from './datasets.actions'; import type { Dataset } from './datasets.types'; @@ -79,3 +80,9 @@ export const updateDataset = createThunk(updateDatasetActions, async (_d, _g, { const updatedDataset = (await axiosInstance.patch(`datasets/${id}`, payload)).data; return updateDatasetActions.success(updatedDataset); }); + +export const removeDataset = createThunkWithExplicitResult(removeDatasetActions, async (dispatch, _g, datasetId) => { + await axiosInstance.delete(`/datasets/${datasetId}`); + dispatch(removeDatasetActions.success()); + navigate(`/`); +});