Skip to content

Commit

Permalink
fix: add a confirmation message when deleting membership (#790)
Browse files Browse the repository at this point in the history
  • Loading branch information
LinaYahya authored Oct 10, 2023
1 parent 5aa0a2f commit 1f3ab01
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 15 deletions.
2 changes: 2 additions & 0 deletions cypress/e2e/memberships/deleteItemMembership.cy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { buildItemPath } from '../../../src/config/paths';
import {
CONFIRM_MEMBERSHIP_DELETE_BUTTON_ID,
buildItemMembershipRowDeleteButtonId,
buildShareButtonId,
} from '../../../src/config/selectors';
Expand All @@ -16,6 +17,7 @@ const deleteItemMembership = ({
cy.get(`#${buildShareButtonId(itemId)}`).click();
cy.wait(TABLE_MEMBERSHIP_RENDER_TIME);
cy.get(`#${buildItemMembershipRowDeleteButtonId(id)}`).click();
cy.get(`#${CONFIRM_MEMBERSHIP_DELETE_BUTTON_ID}`).click();
};

describe('Delete Membership', () => {
Expand Down
110 changes: 110 additions & 0 deletions src/components/item/sharing/ConfirmMembership.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import {
Alert,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from '@mui/material';

import { ItemMembership, PermissionLevel } from '@graasp/sdk';
import { ItemRecord } from '@graasp/sdk/frontend';
import { Button } from '@graasp/ui';

import { useCurrentUserContext } from '@/components/context/CurrentUserContext';

import { useBuilderTranslation } from '../../../config/i18n';
import { mutations } from '../../../config/queryClient';
import { CONFIRM_MEMBERSHIP_DELETE_BUTTON_ID } from '../../../config/selectors';
import { BUILDER } from '../../../langs/constants';
import CancelButton from '../../common/CancelButton';

const labelId = 'alert-dialog-title';
const descriptionId = 'alert-dialog-description';

type Props = {
open?: boolean;
handleClose: () => void;
item: ItemRecord;
membershipToDelete: ItemMembership | null;
hasOnlyOneAdmin: boolean;
};

const DeleteItemDialog = ({
item,
open = false,
handleClose,
membershipToDelete,
hasOnlyOneAdmin = false,
}: Props): JSX.Element => {
const { t: translateBuilder } = useBuilderTranslation();
const { data: member } = useCurrentUserContext();

const { mutate: deleteItemMembership } = mutations.useDeleteItemMembership();

const onDelete = () => {
if (membershipToDelete?.id) {
deleteItemMembership({ id: membershipToDelete.id, itemId: item.id });
handleClose();
}
};

let dialogText = '';
const isDeletingLastAdmin =
hasOnlyOneAdmin && membershipToDelete?.permission === PermissionLevel.Admin;
// incase of deleting the only admin
if (isDeletingLastAdmin) {
dialogText = translateBuilder(BUILDER.DELETE_LAST_ADMIN_ALERT_MESSAGE);
} else if (member?.id === membershipToDelete?.member?.id) {
// deleting yourself
dialogText = translateBuilder(BUILDER.DELETE_OWN_MEMBERSHIP_MESSAGE);
} else {
// delete other members
dialogText = translateBuilder(BUILDER.DELETE_MEMBERSHIP_MESSAGE, {
name: membershipToDelete?.member.name,
permissionLevel: membershipToDelete?.permission,
});
}
return (
<Dialog
open={open}
onClose={handleClose}
aria-labelledby={labelId}
aria-describedby={descriptionId}
>
<DialogTitle id={labelId}>
{translateBuilder(BUILDER.DELETE_MEMBERSHIP)}
</DialogTitle>
<DialogContent>
{isDeletingLastAdmin ? (
<Alert severity="error">{dialogText}</Alert>
) : (
<DialogContentText id={descriptionId}>{dialogText}</DialogContentText>
)}
</DialogContent>

<DialogActions>
{isDeletingLastAdmin ? (
<Button onClick={handleClose} autoFocus variant="text">
{translateBuilder(BUILDER.APPROVE_BUTTON_TEXT)}
</Button>
) : (
<>
<CancelButton onClick={handleClose} />
<Button
id={CONFIRM_MEMBERSHIP_DELETE_BUTTON_ID}
onClick={onDelete}
color="error"
autoFocus
variant="text"
>
{translateBuilder(BUILDER.DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON)}
</Button>
</>
)}
</DialogActions>
</Dialog>
);
};

export default DeleteItemDialog;
53 changes: 40 additions & 13 deletions src/components/item/sharing/ItemMembershipsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo } from 'react';
import { useMemo, useState } from 'react';

import { Typography } from '@mui/material';

Expand All @@ -19,6 +19,7 @@ import {
buildItemMembershipRowId,
} from '../../../config/selectors';
import { BUILDER } from '../../../langs/constants';
import DeleteItemDialog from './ConfirmMembership';
import TableRowDeleteButtonRenderer from './TableRowDeleteButtonRenderer';
import TableRowPermissionRenderer from './TableRowPermissionRenderer';

Expand Down Expand Up @@ -69,12 +70,23 @@ const ItemMembershipsTable = ({
}: Props): JSX.Element => {
const { t: translateBuilder } = useBuilderTranslation();

const { mutate: deleteItemMembership } = mutations.useDeleteItemMembership();
const { mutate: editItemMembership } = mutations.useEditItemMembership();
const { mutate: shareItem } = mutations.usePostItemMembership();

const [open, setOpen] = useState(false);
const [membershipToDelete, setMembershipToDelete] =
useState<ItemMembership | null>(null);

const handleClickOpen = () => {
setOpen(true);
};

const handleClose = () => {
setOpen(false);
};
const onDelete = ({ instance }: { instance: ItemMembership }) => {
deleteItemMembership({ id: instance.id, itemId: item.id });
setMembershipToDelete(instance);
handleClickOpen();
};

// never changes, so we can use useMemo
Expand Down Expand Up @@ -196,16 +208,31 @@ const ItemMembershipsTable = ({
});

return (
<GraaspTable
columnDefs={columnDefs}
tableHeight={MEMBERSHIP_TABLE_HEIGHT}
rowData={memberships}
getRowId={getRowId}
rowHeight={MEMBERSHIP_TABLE_ROW_HEIGHT}
isClickable={false}
emptyMessage={emptyMessage}
countTextFunction={countTextFunction}
/>
<>
<GraaspTable
columnDefs={columnDefs}
tableHeight={MEMBERSHIP_TABLE_HEIGHT}
rowData={memberships}
getRowId={getRowId}
rowHeight={MEMBERSHIP_TABLE_ROW_HEIGHT}
isClickable={false}
emptyMessage={emptyMessage}
countTextFunction={countTextFunction}
/>
{open && (
<DeleteItemDialog
open={open}
handleClose={handleClose}
item={item}
membershipToDelete={membershipToDelete}
hasOnlyOneAdmin={
memberships.filter(
(per) => per.permission === PermissionLevel.Admin,
).length === 1
}
/>
)}
</>
);
};

Expand Down
2 changes: 2 additions & 0 deletions src/config/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ export const EDIT_MODAL_ID = 'editModal';
export const EDIT_ITEM_MODAL_CANCEL_BUTTON_ID = 'editModalCancelButton';
export const FILE_SETTING_MAX_WIDTH_ID = 'fileSettingMaxWidth';

export const CONFIRM_MEMBERSHIP_DELETE_BUTTON_ID =
'confirmDeleteMembershipButton';
export const buildDownloadButtonId = (itemId: string): string =>
`download-button-id-${itemId}`;
export const CUSTOM_APP_URL_ID = 'customAppURLId';
6 changes: 6 additions & 0 deletions src/langs/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@
"USER_SWITCH_SIGN_OUT_BUTTON": "خروج",
"USER_SWITCH_SIGNED_OUT_TOOLTIP": "أنت غير مسجل الدخول.",
"USER_SWITCH_SWITCH_USER_TEXT": "تسجيل الدخول بحساب آخر",
"DELETE_MEMBERSHIP": "حذف العضوية",
"DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON": "تأكيد",
"DELETE_OWN_MEMBERSHIP_MESSAGE": "هل أنت متأكد من إلغاء عضويتك على هذا العنصر؟",
"DELETE_MEMBERSHIP_MESSAGE": "هل أنت متأكد من إزالة عضوية {{name}}ك {{permissionLevel}} على هذا العنصر؟",
"DELETE_LAST_ADMIN_ALERT_MESSAGE": "لا يمكنك إلغاء عضوية هذا الأدمن حيث أنه الأدمن الوحيد",
"APPROVE_BUTTON_TEXT": "موافق",
"STATUS_TOOLTIP_IS_PINNED": "مُثبت",
"STATUS_TOOLTIP_IS_HIDDEN": "مخفي",
"STATUS_TOOLTIP_IS_PUBLIC": "عام",
Expand Down
7 changes: 7 additions & 0 deletions src/langs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,13 @@ export const BUILDER = {
STATUS_TOOLTIP_IS_COLLAPSIBLE: 'STATUS_TOOLTIP_IS_COLLAPSIBLE',
STATUS_TOOLTIP_SHOW_CHATBOX: 'STATUS_TOOLTIP_SHOW_CHATBOX',
SETTINGS_FILE_SETTINGS_TITLE: 'SETTINGS_FILE_SETTINGS_TITLE',
DELETE_MEMBERSHIP: 'DELETE_MEMBERSHIP',
DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON:
'DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON',
DELETE_MEMBERSHIP_MESSAGE: 'DELETE_MEMBERSHIP_MESSAGE',
DELETE_OWN_MEMBERSHIP_MESSAGE: 'DELETE_OWN_MEMBERSHIP_MESSAGE',
DELETE_LAST_ADMIN_ALERT_MESSAGE: 'DELETE_LAST_ADMIN_ALERT_MESSAGE',
APPROVE_BUTTON_TEXT: 'APPROVE_BUTTON_TEXT',
APP_URL: 'APP_URL',
CREATE_CUSTOM_APP: 'CREATE_CUSTOM_APP',
};
7 changes: 6 additions & 1 deletion src/langs/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -227,5 +227,10 @@
"USER_SWITCH_PROFILE_BUTTON": "Siehe Profil",
"USER_SWITCH_SIGN_OUT_BUTTON": "Abmelden",
"USER_SWITCH_SIGNED_OUT_TOOLTIP": "Sie sind nicht angemeldet.",
"USER_SWITCH_SWITCH_USER_TEXT": "Melden Sie sich mit einem anderen Konto an"
"USER_SWITCH_SWITCH_USER_TEXT": "Melden Sie sich mit einem anderen Konto an",
"DELETE_MEMBERSHIP": "Mitgliedschaft löschen",
"DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON": "Bestätigen",
"DELETE_OWN_MEMBERSHIP_MESSAGE": "Sind Sie sicher, dass Sie Ihre eigene Berechtigung für dieses Element entfernen möchten? Sie verlieren den Zugriff auf dieses Element, diese Aktion ist irreversibel.",
"DELETE_MEMBERSHIP_MESSAGE": "Sind Sie sicher, dass Sie {{permissionLevel}} Zugang für diesen Artikel für {{name}} entfernen möchten?",
"DELETE_LAST_ADMIN_ALERT_MESSAGE": "Sie dürfen diesen Administrator nicht löschen, da dies der einzige Administrator ist"
}
6 changes: 6 additions & 0 deletions src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@
"STATUS_TOOLTIP_IS_COLLAPSIBLE": "Collapsible",
"STATUS_TOOLTIP_SHOW_CHATBOX": "Chatbox visible",
"SETTINGS_FILE_SETTINGS_TITLE": "File Settings",
"DELETE_MEMBERSHIP": "Delete Membership",
"DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON": "Confirm",
"DELETE_OWN_MEMBERSHIP_MESSAGE": "Are you sure you want to delete your own permission on this item? You will loose access to this item, this action can not be undone.",
"DELETE_MEMBERSHIP_MESSAGE": "Are you sure you want to remove {{permissionLevel}} access on this item for {{name}}? They will loose access to this item.",
"DELETE_LAST_ADMIN_ALERT_MESSAGE": "You are not allowed to delete this admin as this is the only admin",
"APPROVE_BUTTON_TEXT": "OK",
"APP_URL": "App Url",
"CREATE_CUSTOM_APP": "Add Your Custom App"
}
7 changes: 6 additions & 1 deletion src/langs/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,5 +247,10 @@
"STATUS_TOOLTIP_IS_PUBLISHED": "Publié",
"STATUS_TOOLTIP_IS_COLLAPSIBLE": "Minifié",
"STATUS_TOOLTIP_SHOW_CHATBOX": "Chatbox visible",
"SETTINGS_FILE_SETTINGS_TITLE": "Paramètres du fichier"
"SETTINGS_FILE_SETTINGS_TITLE": "Paramètres du fichier",
"DELETE_MEMBERSHIP": "Supprimer l'autorisation",
"DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON": "Confirmer",
"DELETE_OWN_MEMBERSHIP_MESSAGE": "Êtes-vous sûr de vouloir supprimer votre propre autorisation sur cet élément ? Vous perdrez l'accès à cet élément, cette action est irréversible.",
"DELETE_MEMBERSHIP_MESSAGE": "Êtes-vous sûr de vouloir supprimer l'accès en {{permissionLevel}} sur cet élément à {{name}} ? Il leur sera impossible d'accéder à cet élément.",
"DELETE_LAST_ADMIN_ALERT_MESSAGE": "Vous n'êtes pas autorisé à supprimer le dernier administrateur de cet élément."
}

0 comments on commit 1f3ab01

Please sign in to comment.