From b2d69b369638ed5a398bb5b6760c17b777bb8954 Mon Sep 17 00:00:00 2001 From: pyphilia Date: Thu, 10 Feb 2022 14:29:54 +0100 Subject: [PATCH 1/6] refactor: update app item data --- package.json | 2 +- src/components/item/ItemContent.js | 11 ++++++----- src/components/main/ItemScreen.js | 15 ++++++++++++--- src/utils/membership.js | 30 ++++++++++++++++++++++++------ yarn.lock | 8 ++++---- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 53140ccd1..7979bcfe8 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "dependencies": { "@graasp/chatbox": "github:graasp/graasp-chatbox.git", "@graasp/query-client": "github:graasp/graasp-query-client.git", - "@graasp/ui": "github:graasp/graasp-ui.git", + "@graasp/ui": "github:graasp/graasp-ui.git#80/context", "@graasp/utils": "github:graasp/graasp-utils.git", "@material-ui/core": "4.12.3", "@material-ui/icons": "5.0.0-beta.4", diff --git a/src/components/item/ItemContent.js b/src/components/item/ItemContent.js index a3e5b1e84..e1c4b3ff9 100644 --- a/src/components/item/ItemContent.js +++ b/src/components/item/ItemContent.js @@ -12,7 +12,7 @@ import { DOCUMENT_ITEM_TEXT_EDITOR_ID, ITEM_SCREEN_ERROR_ALERT_ID, } from '../../config/selectors'; -import { ITEM_KEYS, ITEM_TYPES, APP_MODES } from '../../enums'; +import { ITEM_KEYS, ITEM_TYPES } from '../../enums'; import Loader from '../common/Loader'; import ErrorAlert from '../common/ErrorAlert'; import { API_HOST, ITEM_DEFAULT_HEIGHT } from '../../config/constants'; @@ -33,7 +33,7 @@ const useStyles = makeStyles(() => ({ }, })); -const ItemContent = ({ item, enableEdition }) => { +const ItemContent = ({ item, enableEdition, permission }) => { const classes = useStyles(); const itemId = item.get(ITEM_KEYS.ID); const itemType = item?.get(ITEM_KEYS.TYPE); @@ -43,7 +43,7 @@ const ItemContent = ({ item, enableEdition }) => { const { editingItemId, setEditingItemId } = useContext(LayoutContext); // provide user to app - const { data: user, isLoading: isLoadingUser } = + const { data: member, isLoading: isLoadingUser } = useContext(CurrentUserContext); // display children @@ -137,9 +137,9 @@ const ItemContent = ({ item, enableEdition }) => { onSaveCaption={onSaveCaption} saveButtonId={saveButtonId} onSettingsUpdate={editItemAsync} - user={user} + member={member} height={ITEM_DEFAULT_HEIGHT} - mode={enableEdition ? APP_MODES.TEACHER : APP_MODES.STUDENT} + permission={permission} requestApiAccessToken={Api.requestApiAccessToken} /> ); @@ -171,6 +171,7 @@ const ItemContent = ({ item, enableEdition }) => { ItemContent.propTypes = { item: PropTypes.instanceOf(Map).isRequired, enableEdition: PropTypes.bool, + permission: PropTypes.string.isRequired, }; ItemContent.defaultProps = { diff --git a/src/components/main/ItemScreen.js b/src/components/main/ItemScreen.js index fe5297dca..ecb67c3e8 100644 --- a/src/components/main/ItemScreen.js +++ b/src/components/main/ItemScreen.js @@ -4,7 +4,7 @@ import { ItemLoginAuthorization } from '@graasp/ui'; import { useParams } from 'react-router'; import { getMembership, - isItemUpdateAllowedForUser, + getBestPermissionForMemberFromMemberships, } from '../../utils/membership'; import ErrorAlert from '../common/ErrorAlert'; import { CurrentUserContext } from '../context/CurrentUserContext'; @@ -24,6 +24,7 @@ import { ITEM_LOGIN_SIGN_IN_PASSWORD_ID, ITEM_LOGIN_SIGN_IN_USERNAME_ID, } from '../../config/selectors'; +import { PERMISSIONS_EDITION_ALLOWED } from '../../config/constants'; const { useItem, useItemMemberships, useCurrentMember, useItemLogin } = hooks; @@ -53,10 +54,12 @@ const ItemScreen = () => { return ; } - const enableEdition = isItemUpdateAllowedForUser({ + const itemMembership = getBestPermissionForMemberFromMemberships({ memberships: getMembership(memberships), memberId: currentMember?.get('id'), }); + const permission = itemMembership?.permission; + const enableEdition = PERMISSIONS_EDITION_ALLOWED.includes(permission); const content = (() => { if (enableEdition && isItemSettingsOpen) { @@ -70,7 +73,13 @@ const ItemScreen = () => { if (isDashboardOpen) { return ; } - return ; + return ( + + ); })(); return ( diff --git a/src/utils/membership.js b/src/utils/membership.js index 907a912a7..476c7f645 100644 --- a/src/utils/membership.js +++ b/src/utils/membership.js @@ -4,12 +4,6 @@ import { PERMISSION_LEVELS } from '../enums'; // todo: better check with typescript export const isError = (memberships) => memberships?.statusCode; -export const isSettingsEditionAllowedForUser = ({ memberships, memberId }) => - memberships?.find( - ({ memberId: mId, permission }) => - mId === memberId && PERMISSION_LEVELS.ADMIN === permission, - ); - export const isItemUpdateAllowedForUser = ({ memberships, memberId }) => Boolean( memberships?.find( @@ -18,6 +12,30 @@ export const isItemUpdateAllowedForUser = ({ memberships, memberId }) => ), ); +export const getBestPermissionForMemberFromMemberships = ({ + memberships, + memberId, +}) => { + const itemMemberships = memberships?.filter( + ({ memberId: mId }) => mId === memberId, + ); + if (!itemMemberships) { + return null; + } + + const sorted = itemMemberships?.sort( + (a, b) => a.itemPath.length > b.itemPath.length, + ); + + return sorted[0]; +}; + +export const isSettingsEditionAllowedForUser = ({ memberships, memberId }) => + memberships?.find( + ({ memberId: mId, permission }) => + mId === memberId && PERMISSION_LEVELS.ADMIN === permission, + ); + export const membershipsWithoutUser = (memberships, userId) => memberships?.filter(({ memberId }) => memberId !== userId); diff --git a/yarn.lock b/yarn.lock index b8afb5761..3f7e58865 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1909,9 +1909,9 @@ __metadata: languageName: node linkType: hard -"@graasp/ui@github:graasp/graasp-ui.git": +"@graasp/ui@github:graasp/graasp-ui.git#80/context": version: 0.2.0 - resolution: "@graasp/ui@https://github.com/graasp/graasp-ui.git#commit=f4067389a0868cd84d5417fb02d564cc3a2d2637" + resolution: "@graasp/ui@https://github.com/graasp/graasp-ui.git#commit=9b528e750a68dd7520849a0562613a66aaaf6a98" dependencies: "@graasp/utils": "github:graasp/graasp-utils.git" clsx: 1.1.1 @@ -1930,7 +1930,7 @@ __metadata: i18next: 21.3.1 react: ^16.13.1 react-dom: 16.13.1 - checksum: f24aec035b70b465f4f833dc28a30b5da6eda05392a81f9204eddb5b59b0767fcc735f2dcede980223beaa0b7ae0dfab47a09072378432d9d8d744883fc86865 + checksum: 80ae854fab74942592a4801d56cdaed359b2e4a6ed08b862a1bf3cfe4caa38855e9096f7a86d293160aa2a7add02287ca8899a8ff69b6fcad3c6d70313558ad3 languageName: node linkType: hard @@ -9805,7 +9805,7 @@ __metadata: "@cypress/instrument-cra": 1.4.0 "@graasp/chatbox": "github:graasp/graasp-chatbox.git" "@graasp/query-client": "github:graasp/graasp-query-client.git" - "@graasp/ui": "github:graasp/graasp-ui.git" + "@graasp/ui": "github:graasp/graasp-ui.git#80/context" "@graasp/utils": "github:graasp/graasp-utils.git" "@graasp/websockets": "github:graasp/graasp-websockets.git#master" "@material-ui/core": 4.12.3 From 44ae4f2df4ceea19d26682905f72a30d7199cf86 Mon Sep 17 00:00:00 2001 From: pyphilia Date: Fri, 11 Feb 2022 16:12:54 +0100 Subject: [PATCH 2/6] refactor: fix tests --- cypress/fixtures/apps/app.html | 5 ++--- src/components/main/ItemScreen.js | 4 ++-- src/utils/membership.js | 4 +++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cypress/fixtures/apps/app.html b/cypress/fixtures/apps/app.html index 403b0ae3c..149ead604 100644 --- a/cypress/fixtures/apps/app.html +++ b/cypress/fixtures/apps/app.html @@ -76,9 +76,8 @@ port2 = e.ports[0]; port2.onmessage = onMessage; console.log(e.data); - itemId = e.data.payload.itemId; - document.getElementById('requestContext-message').innerHTML = - e.data.payload.itemId; + itemId = JSON.parse(e.data).payload.itemId; + document.getElementById('requestContext-message').innerHTML = itemId; } // Handle messages received on port2 diff --git a/src/components/main/ItemScreen.js b/src/components/main/ItemScreen.js index ecb67c3e8..36979e13d 100644 --- a/src/components/main/ItemScreen.js +++ b/src/components/main/ItemScreen.js @@ -4,7 +4,7 @@ import { ItemLoginAuthorization } from '@graasp/ui'; import { useParams } from 'react-router'; import { getMembership, - getBestPermissionForMemberFromMemberships, + getHighestPermissionForMemberFromMemberships, } from '../../utils/membership'; import ErrorAlert from '../common/ErrorAlert'; import { CurrentUserContext } from '../context/CurrentUserContext'; @@ -54,7 +54,7 @@ const ItemScreen = () => { return ; } - const itemMembership = getBestPermissionForMemberFromMemberships({ + const itemMembership = getHighestPermissionForMemberFromMemberships({ memberships: getMembership(memberships), memberId: currentMember?.get('id'), }); diff --git a/src/utils/membership.js b/src/utils/membership.js index 476c7f645..25f9762d9 100644 --- a/src/utils/membership.js +++ b/src/utils/membership.js @@ -12,7 +12,9 @@ export const isItemUpdateAllowedForUser = ({ memberships, memberId }) => ), ); -export const getBestPermissionForMemberFromMemberships = ({ +// get highest permission a member have over an item, +// longer the itemPath, deeper is the permission, thus highested +export const getHighestPermissionForMemberFromMemberships = ({ memberships, memberId, }) => { From df968596981f4647a2693291e65d5cd296c0a36d Mon Sep 17 00:00:00 2001 From: pyphilia Date: Fri, 11 Feb 2022 18:35:59 +0100 Subject: [PATCH 3/6] refactor: fix tests --- cypress/integration/item/copy/listCopyItem.spec.js | 11 ++++++++--- cypress/integration/item/share/itemLogin.spec.js | 2 -- src/components/Root.js | 2 +- src/components/common/HideButton.js | 3 +-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cypress/integration/item/copy/listCopyItem.spec.js b/cypress/integration/item/copy/listCopyItem.spec.js index 725ef8053..bdc293119 100644 --- a/cypress/integration/item/copy/listCopyItem.spec.js +++ b/cypress/integration/item/copy/listCopyItem.spec.js @@ -10,6 +10,8 @@ import { buildItemMenu, ITEM_MENU_COPY_BUTTON_CLASS, buildItemMenuButtonId, + buildItemsTableId, + EDIT_ITEM_BUTTON_CLASS, } from '../../../../src/config/selectors'; import { SAMPLE_ITEMS } from '../../../fixtures/items'; import { TABLE_ITEM_RENDER_TIME } from '../../../support/constants'; @@ -93,7 +95,7 @@ describe('Copy Item in List', () => { describe('Error handling', () => { it('error while copying item does not create in interface', () => { - cy.setUpApi({ ...SAMPLE_ITEMS, copyItemError: true }); + cy.setUpApi({ ...SAMPLE_ITEMS, copyItemsError: true }); const { id } = SAMPLE_ITEMS.items[0]; // go to children item @@ -107,10 +109,13 @@ describe('Copy Item in List', () => { const { path: toItemPath } = SAMPLE_ITEMS.items[0]; copyItem({ id: copyItemId, toItemPath }); - cy.wait('@copyItems').then(({ response: { body } }) => { + cy.wait('@copyItems').then(() => { // check item is still existing in parent cy.get(buildItemsTableRowIdAttribute(copyItemId)).should('exist'); - cy.get(buildItemsTableRowIdAttribute(body[0].id)).should('not.exist'); + cy.get(`#${buildItemsTableId(id)} .${EDIT_ITEM_BUTTON_CLASS}`).should( + 'have.length', + 3, + ); }); }); }); diff --git a/cypress/integration/item/share/itemLogin.spec.js b/cypress/integration/item/share/itemLogin.spec.js index dd8f9959c..5ace908c3 100644 --- a/cypress/integration/item/share/itemLogin.spec.js +++ b/cypress/integration/item/share/itemLogin.spec.js @@ -160,7 +160,6 @@ describe('Item Login', () => { describe('Display Item Login Setting', () => { it('edit item login setting', () => { cy.setUpApi(ITEM_LOGIN_ITEMS); - cy.log('item with item login'); const item = ITEM_LOGIN_ITEMS.items[0]; // check item with item login enabled cy.visit(buildItemPath(item.id)); @@ -173,7 +172,6 @@ describe('Item Login', () => { editItemLoginSetting(SETTINGS.ITEM_LOGIN.OPTIONS.USERNAME_AND_PASSWORD); // disabled at child level - cy.log('child of item with item login'); const item2 = ITEM_LOGIN_ITEMS.items[5]; cy.visit(buildItemPath(item2.id)); cy.get(`#${buildShareButtonId(item2.id)}`).click(); diff --git a/src/components/Root.js b/src/components/Root.js index e11e37e35..dbe26458d 100644 --- a/src/components/Root.js +++ b/src/components/Root.js @@ -43,7 +43,7 @@ const Root = () => ( - {NODE_ENV === ENV.DEVELOPMENT && } + {NODE_ENV === ENV.DEVELOPMENT && } ); diff --git a/src/components/common/HideButton.js b/src/components/common/HideButton.js index fdeaac93d..9ca344639 100644 --- a/src/components/common/HideButton.js +++ b/src/components/common/HideButton.js @@ -6,8 +6,7 @@ import VisibilityOff from '@material-ui/icons/VisibilityOff'; import { useTranslation } from 'react-i18next'; import Tooltip from '@material-ui/core/Tooltip'; import { MUTATION_KEYS } from '@graasp/query-client'; -import { useMutation } from 'react-query'; -import { hooks } from '../../config/queryClient'; +import { hooks, useMutation } from '../../config/queryClient'; import { HIDDEN_ITEM_BUTTON_CLASS } from '../../config/selectors'; import { HIDDEN_ITEM_TAG_ID } from '../../config/constants'; From 746a5b6b9c89392533623848417b5ab4a4aa04f0 Mon Sep 17 00:00:00 2001 From: pyphilia Date: Mon, 14 Feb 2022 15:21:32 +0100 Subject: [PATCH 4/6] refactor: update yarn lock --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3f7e58865..68c0ee12e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1911,7 +1911,7 @@ __metadata: "@graasp/ui@github:graasp/graasp-ui.git#80/context": version: 0.2.0 - resolution: "@graasp/ui@https://github.com/graasp/graasp-ui.git#commit=9b528e750a68dd7520849a0562613a66aaaf6a98" + resolution: "@graasp/ui@https://github.com/graasp/graasp-ui.git#commit=c11e4ffd7c3b58818068e43a75e78f8ecb4b948f" dependencies: "@graasp/utils": "github:graasp/graasp-utils.git" clsx: 1.1.1 @@ -1930,7 +1930,7 @@ __metadata: i18next: 21.3.1 react: ^16.13.1 react-dom: 16.13.1 - checksum: 80ae854fab74942592a4801d56cdaed359b2e4a6ed08b862a1bf3cfe4caa38855e9096f7a86d293160aa2a7add02287ca8899a8ff69b6fcad3c6d70313558ad3 + checksum: eeb0a24128b59d96422ac103dc738f0663396f9ab39113b9d68faf79cee323fe793a5d80404968d0b72f35656a135fcd1c662dee618b0e8b162d71aeceb8a1e9 languageName: node linkType: hard From 0d209c99bb95e97077c2548c3bb1b50fa8eef21f Mon Sep 17 00:00:00 2001 From: pyphilia Date: Fri, 18 Feb 2022 11:19:34 +0100 Subject: [PATCH 5/6] refactor: use graasp ui main branch --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7979bcfe8..53140ccd1 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "dependencies": { "@graasp/chatbox": "github:graasp/graasp-chatbox.git", "@graasp/query-client": "github:graasp/graasp-query-client.git", - "@graasp/ui": "github:graasp/graasp-ui.git#80/context", + "@graasp/ui": "github:graasp/graasp-ui.git", "@graasp/utils": "github:graasp/graasp-utils.git", "@material-ui/core": "4.12.3", "@material-ui/icons": "5.0.0-beta.4", diff --git a/yarn.lock b/yarn.lock index 68c0ee12e..57c591f19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1909,9 +1909,9 @@ __metadata: languageName: node linkType: hard -"@graasp/ui@github:graasp/graasp-ui.git#80/context": +"@graasp/ui@github:graasp/graasp-ui.git": version: 0.2.0 - resolution: "@graasp/ui@https://github.com/graasp/graasp-ui.git#commit=c11e4ffd7c3b58818068e43a75e78f8ecb4b948f" + resolution: "@graasp/ui@https://github.com/graasp/graasp-ui.git#commit=9effce6baad8cda6cef5095032a0502395a94a75" dependencies: "@graasp/utils": "github:graasp/graasp-utils.git" clsx: 1.1.1 @@ -1930,7 +1930,7 @@ __metadata: i18next: 21.3.1 react: ^16.13.1 react-dom: 16.13.1 - checksum: eeb0a24128b59d96422ac103dc738f0663396f9ab39113b9d68faf79cee323fe793a5d80404968d0b72f35656a135fcd1c662dee618b0e8b162d71aeceb8a1e9 + checksum: 392c15ef8e0d210de475483606cdcc214de9eddc88522e1cd795a63d4fcbcbf579d8dc84f34e4af01a34d30b0ef20686a3cec0a4e9b92e352f514cbca71b65fa languageName: node linkType: hard @@ -9805,7 +9805,7 @@ __metadata: "@cypress/instrument-cra": 1.4.0 "@graasp/chatbox": "github:graasp/graasp-chatbox.git" "@graasp/query-client": "github:graasp/graasp-query-client.git" - "@graasp/ui": "github:graasp/graasp-ui.git#80/context" + "@graasp/ui": "github:graasp/graasp-ui.git" "@graasp/utils": "github:graasp/graasp-utils.git" "@graasp/websockets": "github:graasp/graasp-websockets.git#master" "@material-ui/core": 4.12.3 From 72d8ef70043f90ac84d27e827b956a23de21c5f7 Mon Sep 17 00:00:00 2001 From: pyphilia Date: Fri, 18 Feb 2022 12:09:04 +0100 Subject: [PATCH 6/6] refactor: fix apps test --- cypress/integration/item/apps/apps.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/integration/item/apps/apps.spec.js b/cypress/integration/item/apps/apps.spec.js index 2f497cd27..6b706c6de 100644 --- a/cypress/integration/item/apps/apps.spec.js +++ b/cypress/integration/item/apps/apps.spec.js @@ -24,7 +24,7 @@ describe('Apps', () => { cy.checkContentInElementInIframe( iframeSelector, 'ul', - 'GET_AUTH_TOKEN_SUCCEEDED', + 'GET_AUTH_TOKEN_SUCCESS', ); // check app can get app-data