Skip to content

Commit

Permalink
Implement dataset removal functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
mnmsvlw committed Jan 29, 2025
1 parent 86823f3 commit 1cf5e12
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 72 deletions.
28 changes: 28 additions & 0 deletions ui/src/common/components/ConfirmPopover/ConfirmPopover.module.scss
Original file line number Diff line number Diff line change
@@ -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;
}
91 changes: 91 additions & 0 deletions ui/src/common/components/ConfirmPopover/ConfirmPopover.tsx
Original file line number Diff line number Diff line change
@@ -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<ConfirmPopoverProps>) {
return (
<Popover
classNames={{
dropdown: classes.dropdown,
}}
offset={16}
withArrow
{...rest}
>
<Popover.Target>{target}</Popover.Target>

<Popover.Dropdown>
<Flex
direction="column"
gap="16px"
>
<Flex
direction="column"
gap="4px"
>
<Flex
align="center"
gap="4px"
>
<AlertCircleIcon className={classes.alertIcon} />
<Text fw={700}>{title}</Text>
</Flex>
<Text>{text}</Text>
</Flex>

<Flex
justify="flex-end"
align="center"
gap="8px"
>
<Button
className={classes.popoverButton}
variant="default"
size="xs"
onClick={onCancel}
>
Cancel
</Button>
<Button
className={classes.popoverButton}
size="xs"
onClick={onConfirm}
>
OK
</Button>
</Flex>
</Flex>
</Popover.Dropdown>
</Popover>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,3 @@
text-transform: capitalize;
width: 140px;
}

.alertIcon {
color: #e4626f;
}

.popoverButton {
padding: 6px 12px;
font-weight: 400;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -89,68 +90,23 @@ export function RoleSelector({ value, onChange, onRemove, disabled }: Readonly<R

<Menu.Divider />

<Popover
<ConfirmPopover
opened={openedConfirm}
classNames={{
dropdown: classes.dropdown,
}}
position="right"
offset={16}
withArrow
>
<Popover.Target>
title="Remove user"
text="Are you sure to remove this user?"
onConfirm={handleConfirm}
onCancel={closeConfirm}
target={
<Menu.Item
color="red"
leftSection={<RemoveIcon />}
onClick={openConfirm}
>
Remove
</Menu.Item>
</Popover.Target>

<Popover.Dropdown>
<Flex
direction="column"
gap="16px"
>
<Flex
direction="column"
gap="4px"
>
<Flex
align="center"
gap="4px"
>
<AlertCircleIcon className={classes.alertIcon} />
<Text fw={700}>Remove user</Text>
</Flex>
<Text>Are you sure to remove this user?</Text>
</Flex>

<Flex
justify="flex-end"
align="center"
gap="8px"
>
<Button
className={classes.popoverButton}
variant="default"
size="xs"
onClick={closeConfirm}
>
Cancel
</Button>
<Button
className={classes.popoverButton}
size="xs"
onClick={handleConfirm}
>
OK
</Button>
</Flex>
</Flex>
</Popover.Dropdown>
</Popover>
}
/>
</Menu.Dropdown>
</Menu>
);
Expand Down
34 changes: 32 additions & 2 deletions ui/src/pages/DatasetPage/DatasetHeader/DatasetHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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;
Expand All @@ -39,6 +42,7 @@ export function DatasetHeader({ dataset }: Readonly<DatasetHeaderProps>) {
const [location] = useLocation();
const dispatch = useAppDispatch();
const isEditOpened = useSelector(selectIsDatasetOpened);
const [removeConfirmOpened, { open: openRemoveConfirm, close: closeRemoveConfirm }] = useDisclosure(false);

const openEdit = useCallback(() => {
dispatch(setDatasetEditOpenedAction(true));
Expand All @@ -56,6 +60,11 @@ export function DatasetHeader({ dataset }: Readonly<DatasetHeaderProps>) {
[dataset.id, location],
);

const handleDatasetRemove = useCallback(() => {
dispatch(removeDataset(dataset.id));
closeRemoveConfirm();
}, [dispatch, closeRemoveConfirm, dataset.id]);

return (
<Paper
className={classes.header}
Expand Down Expand Up @@ -101,6 +110,27 @@ export function DatasetHeader({ dataset }: Readonly<DatasetHeaderProps>) {
</div>

<div className={classes.buttonContainer}>
<ConfirmPopover
opened={removeConfirmOpened}
position="right"
offset={8}
title="Remove dataset"
text="Are you sure to remove this dataset?"
onConfirm={handleDatasetRemove}
onCancel={closeRemoveConfirm}
target={
<Button
classNames={{ section: classes.removeIcon }}
variant="transparent"
color="red"
leftSection={<TrashIcon />}
onClick={openRemoveConfirm}
>
Remove
</Button>
}
/>

<DownloadMenu
options={fileDownloadOptions}
url={`/datasets/${dataset.id}/download`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,16 @@

.buttonContainer {
display: flex;
flex-direction: row-reverse;
min-width: 20%;
justify-content: space-between;

button {
border-radius: 8px;
font-weight: 400;
}
}

path {
fill: var(--mantine-color-white);
}
.removeIcon {
margin-inline-end: 6px;
}

.target {
Expand Down
2 changes: 2 additions & 0 deletions ui/src/store/datasets/datasets.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ export const createDatasetFromFileActions = createAsyncAction<CreateDatasetFromF
export const setDatasetEditOpenedAction = createAction<boolean>('set_edit_opened');

export const updateDatasetActions = createAsyncAction<Pick<Dataset, 'id' | 'name' | 'description'>, Dataset>('update');

export const removeDatasetActions = createAsyncAction<number>('remove_dataset');
7 changes: 7 additions & 0 deletions ui/src/store/datasets/datasets.thunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
getDatasetActions,
getDatasetPageActions,
getGroupsInitialDatasetListActions,
removeDatasetActions,
updateDatasetActions,
} from './datasets.actions';
import type { Dataset } from './datasets.types';
Expand Down Expand Up @@ -79,3 +80,9 @@ export const updateDataset = createThunk(updateDatasetActions, async (_d, _g, {
const updatedDataset = (await axiosInstance.patch<Dataset>(`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(`/`);
});

0 comments on commit 1cf5e12

Please sign in to comment.