Skip to content

Commit

Permalink
feat: create a dialog to downgrade own membership (#822)
Browse files Browse the repository at this point in the history
* feat: create a dialog to downgrade own membership

* fix: check member exist for invitation instance

* fix: remove console.log

* feat: add a button to change permission in downgrade popup

* build: update graasp/ui dependancy

* build: versions update
  • Loading branch information
LinaYahya authored Oct 24, 2023
1 parent 3f9d792 commit 7baf7b8
Show file tree
Hide file tree
Showing 9 changed files with 744 additions and 1,027 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@graasp/query-client": "1.11.0",
"@graasp/sdk": "1.8.0",
"@graasp/translations": "1.19.2",
"@graasp/ui": "3.5.4",
"@graasp/ui": "3.6.0",
"@mui/icons-material": "5.14.13",
"@mui/lab": "5.0.0-alpha.148",
"@mui/material": "5.14.13",
Expand Down Expand Up @@ -115,7 +115,7 @@
"@types/node": "18.17.12",
"@types/papaparse": "5.3.8",
"@types/qs": "6.9.7",
"@types/react": "18.2.23",
"@types/react": "18.2.31",
"@types/react-csv": "1.1.3",
"@types/react-dom": "18.2.7",
"@types/uuid": "9.0.2",
Expand Down
1 change: 1 addition & 0 deletions src/components/item/sharing/ItemMembershipSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const ItemMembershipSelect = ({
text: enumT(v),
}))}
buildOptionId={buildPermissionOptionId}
value={permission}
defaultValue={permission}
onChange={onChange}
displayEmpty={displayEmpty}
Expand Down
4 changes: 4 additions & 0 deletions src/components/item/sharing/ItemMembershipsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ const ItemMembershipsTable = ({
});
const PermissionRenderer = TableRowPermissionRenderer({
item,
hasOnlyOneAdmin:
memberships.filter((per) => per.permission === PermissionLevel.Admin)
.length === 1,

editFunction: ({
value,
instance,
Expand Down
100 changes: 91 additions & 9 deletions src/components/item/sharing/TableRowPermissionRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
import { useState } from 'react';

import {
Alert,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
} from '@mui/material';
import Typography from '@mui/material/Typography';

import { Item, PermissionLevel } from '@graasp/sdk';
import { Item, Member, PermissionLevel } from '@graasp/sdk';
import { ItemRecord } from '@graasp/sdk/frontend';
import { COMMON } from '@graasp/translations';

import { useBuilderTranslation, useCommonTranslation } from '@/config/i18n';
import { hooks } from '@/config/queryClient';
import {
DOWNGRADE_OWN_PERMISSION_DIALOG_DESC_ID,
DOWNGRADE_OWN_PERMISSION_DIALOG_TITLE_ID,
} from '@/config/selectors';
import { BUILDER } from '@/langs/constants';

import { useIsParentInstance } from '../../../utils/item';
import ItemMembershipSelect from './ItemMembershipSelect';
Expand All @@ -12,39 +31,102 @@ type TableRowPermissionRendererProps<T> = {
editFunction: (args: { value: PermissionLevel; instance: T }) => void;
createFunction: (args: { value: PermissionLevel; instance: T }) => void;
readOnly?: boolean;
hasOnlyOneAdmin?: boolean;
};

function TableRowPermissionRenderer<
T extends { permission: PermissionLevel; item: Item },
T extends { permission: PermissionLevel; item: Item; member?: Member },
>({
item,
editFunction,
createFunction,
readOnly = false,
hasOnlyOneAdmin,
}: TableRowPermissionRendererProps<T>): ({ data }: { data: T }) => JSX.Element {
const ChildComponent = ({ data: instance }: { data: T }) => {
const [open, setOpen] = useState(false);
const [selectedPermission, setSelectedPermission] = useState(
instance.permission,
);

const { t: translateBuilder } = useBuilderTranslation();
const { t: translateCommon } = useCommonTranslation();
const { data: currentMember } = hooks.useCurrentMember();

const handleClose = () => {
setOpen(false);
};

const isParentMembership = useIsParentInstance({
instance,
item,
});
const onChangePermission: ItemMembershipSelectProps['onChange'] = (e) => {
const value = e.target.value as PermissionLevel;
const changePermission = (value: PermissionLevel) => {
// editing a parent's instance from a child should create a new instance
if (isParentMembership) {
createFunction({ value, instance });
} else {
editFunction({ value, instance });
}
};
const onChangePermission: ItemMembershipSelectProps['onChange'] = (e) => {
const value = e.target.value as PermissionLevel;
setSelectedPermission(value);
if (
(value === PermissionLevel.Read || value === PermissionLevel.Write) &&
instance.permission === PermissionLevel.Admin &&
instance?.member &&
instance?.member?.id === currentMember?.id
) {
setOpen(true);
} else {
changePermission(value);
}
};

return readOnly ? (
<Typography noWrap>{instance.permission}</Typography>
) : (
<ItemMembershipSelect
value={instance.permission}
showLabel={false}
onChange={onChangePermission}
/>
<>
<ItemMembershipSelect
value={instance.permission}
showLabel={false}
onChange={onChangePermission}
/>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby={DOWNGRADE_OWN_PERMISSION_DIALOG_TITLE_ID}
aria-describedby={DOWNGRADE_OWN_PERMISSION_DIALOG_DESC_ID}
>
<DialogTitle id={DOWNGRADE_OWN_PERMISSION_DIALOG_TITLE_ID}>
{translateBuilder(BUILDER.DOWNGRADE_PERMISSION_TITLE)}
</DialogTitle>
<DialogContent>
{hasOnlyOneAdmin ? (
<Alert severity="error">
{translateBuilder(BUILDER.DELETE_LAST_ADMIN_ALERT_MESSAGE)}
</Alert>
) : (
translateBuilder(BUILDER.DOWNGRADE_PERMISSION_DESCRIPTION)
)}
</DialogContent>
<DialogActions>
<Button onClick={handleClose} autoFocus variant="text">
{translateCommon(COMMON.CLOSE_BUTTON)}
</Button>
{!hasOnlyOneAdmin && (
<Button
onClick={() => changePermission(selectedPermission)}
autoFocus
variant="text"
>
{translateBuilder(BUILDER.APPROVE_BUTTON_TEXT)}
</Button>
)}
</DialogActions>
</Dialog>
</>
);
};

Expand Down
3 changes: 3 additions & 0 deletions src/config/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,6 @@ export const CONFIRM_MEMBERSHIP_DELETE_BUTTON_ID =
export const buildDownloadButtonId = (itemId: string): string =>
`download-button-id-${itemId}`;
export const CUSTOM_APP_URL_ID = 'customAppURLId';

export const DOWNGRADE_OWN_PERMISSION_DIALOG_TITLE_ID = 'downgradeTitleID';
export const DOWNGRADE_OWN_PERMISSION_DIALOG_DESC_ID = 'downgradeDescID';
3 changes: 3 additions & 0 deletions src/langs/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,8 @@
"SETTINGS_FILE_SETTINGS_TITLE": "إعدادات الملف",
"APP_URL": "رابط التطبيق",
"CREATE_CUSTOM_APP": "أنشيء تطبيقاً خاصاً",
"BACK_TO_APP_LIST": "الرجوع إلى قائمة التطبيقات",
"DOWNGRADE_PERMISSION_TITLE": "خفض مستوى الإذن الخاص بك",
"DOWNGRADE_PERMISSION_DESCRIPTION": "هل أنت متأكد من خفض الإذن الخاص بك؟ لا يمكنك التراجع عن هذه العملية",
"CREATE_NEW_APP_BACK_TO_APP_LIST_BUTTON": "الرجوع إلى قائمة التطبيقات"
}
3 changes: 3 additions & 0 deletions src/langs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ export const BUILDER = {
APP_URL: 'APP_URL',
CREATE_CUSTOM_APP: 'CREATE_CUSTOM_APP',
CREATE_CUSTOM_APP_DESCRIPTION: 'CREATE_CUSTOM_APP_DESCRIPTION',
BACK_TO_APP_LIST: 'BACK_TO_APP_LIST',
DOWNGRADE_PERMISSION_TITLE: 'DOWNGRADE_PERMISSION_TITLE',
DOWNGRADE_PERMISSION_DESCRIPTION: 'DOWNGRADE_PERMISSION_DESCRIPTION',
CREATE_CUSTOM_APP_HELPER_TEXT: 'CREATE_CUSTOM_APP_HELPER_TEXT',
CREATE_NEW_APP_BACK_TO_APP_LIST_BUTTON:
'CREATE_NEW_APP_BACK_TO_APP_LIST_BUTTON',
Expand Down
3 changes: 3 additions & 0 deletions src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@
"APP_URL": "App Url",
"CREATE_CUSTOM_APP": "Add Your Custom App",
"CREATE_CUSTOM_APP_DESCRIPTION": "Advanced option to create a custom app",
"BACK_TO_APP_LIST": "Back To App's List",
"DOWNGRADE_PERMISSION_TITLE": "Downgrade Your Own Permission",
"DOWNGRADE_PERMISSION_DESCRIPTION": "Are you sure you want to downgrade your own permission? Once it's done you can't undo.",
"CREATE_CUSTOM_APP_HELPER_TEXT": "If you know the URL of an interactive app that can leverage Graasp's API you can input it here.",
"CREATE_NEW_APP_BACK_TO_APP_LIST_BUTTON": "Back To App's List",
"APP_LIST_LOADING_FAILED": "There was an error getting the app list. Please try again later."
Expand Down
Loading

0 comments on commit 7baf7b8

Please sign in to comment.