From 29f9a4e330303f26dee341a14cee94013545c58e Mon Sep 17 00:00:00 2001 From: Alexandre Chau Date: Mon, 12 Jul 2021 18:45:54 +0200 Subject: [PATCH] fix: pass member as prop to MenuItem in ItemsTable to avoid render loop --- .../item/copy/listCopyItem.spec.js | 2 ++ .../item/delete/listDeleteItem.spec.js | 2 ++ .../item/delete/listDeleteItems.spec.js | 2 ++ .../item/move/listMoveItem.spec.js | 2 ++ .../item/order/reorderItems.spec.js | 3 ++- cypress/support/constants.js | 1 + src/components/main/CustomCardHeader.js | 16 ++++++------- src/components/main/ItemMenu.js | 23 +++++++++---------- src/components/main/ItemsTable.js | 8 ++++++- 9 files changed, 37 insertions(+), 22 deletions(-) diff --git a/cypress/integration/item/copy/listCopyItem.spec.js b/cypress/integration/item/copy/listCopyItem.spec.js index 757b1c29b..89e1e76c0 100644 --- a/cypress/integration/item/copy/listCopyItem.spec.js +++ b/cypress/integration/item/copy/listCopyItem.spec.js @@ -12,11 +12,13 @@ import { ITEM_MENU_COPY_BUTTON_CLASS, } from '../../../../src/config/selectors'; import { SAMPLE_ITEMS } from '../../../fixtures/items'; +import { MENU_ITEM_RENDER_TIME } from '../../../support/constants'; const copyItem = ({ id, toItemPath }) => { const menuSelector = `#${buildItemsTableRowId( id, )} .${ITEM_MENU_BUTTON_CLASS}`; + cy.wait(MENU_ITEM_RENDER_TIME); cy.get(menuSelector).click(); cy.get(`#${buildItemMenu(id)} .${ITEM_MENU_COPY_BUTTON_CLASS}`).click(); cy.fillTreeModal(toItemPath); diff --git a/cypress/integration/item/delete/listDeleteItem.spec.js b/cypress/integration/item/delete/listDeleteItem.spec.js index 67bbed2e4..bf1263f41 100644 --- a/cypress/integration/item/delete/listDeleteItem.spec.js +++ b/cypress/integration/item/delete/listDeleteItem.spec.js @@ -7,8 +7,10 @@ import { ITEM_DELETE_BUTTON_CLASS, } from '../../../../src/config/selectors'; import { SAMPLE_ITEMS } from '../../../fixtures/items'; +import { MENU_ITEM_RENDER_TIME } from '../../../support/constants'; const deleteItem = (id) => { + cy.wait(MENU_ITEM_RENDER_TIME); cy.get(`#${buildItemsTableRowId(id)} .${ITEM_DELETE_BUTTON_CLASS}`).click(); cy.get(`#${CONFIRM_DELETE_BUTTON_ID}`).click(); }; diff --git a/cypress/integration/item/delete/listDeleteItems.spec.js b/cypress/integration/item/delete/listDeleteItems.spec.js index cb2b9bb1d..1b818d5e4 100644 --- a/cypress/integration/item/delete/listDeleteItems.spec.js +++ b/cypress/integration/item/delete/listDeleteItems.spec.js @@ -8,10 +8,12 @@ import { ITEMS_TABLE_ROW_CHECKBOX_CLASS, } from '../../../../src/config/selectors'; import { SAMPLE_ITEMS } from '../../../fixtures/items'; +import { MENU_ITEM_RENDER_TIME } from '../../../support/constants'; const deleteItems = (itemIds) => { // check selected ids itemIds.forEach((id) => { + cy.wait(MENU_ITEM_RENDER_TIME); cy.get( `#${buildItemsTableRowId(id)} .${ITEMS_TABLE_ROW_CHECKBOX_CLASS}`, ).click(); diff --git a/cypress/integration/item/move/listMoveItem.spec.js b/cypress/integration/item/move/listMoveItem.spec.js index 94d5dada6..c96c41b0f 100644 --- a/cypress/integration/item/move/listMoveItem.spec.js +++ b/cypress/integration/item/move/listMoveItem.spec.js @@ -11,11 +11,13 @@ import { ITEM_MENU_MOVE_BUTTON_CLASS, } from '../../../../src/config/selectors'; import { SAMPLE_ITEMS } from '../../../fixtures/items'; +import { MENU_ITEM_RENDER_TIME } from '../../../support/constants'; const moveItem = ({ id: movedItemId, toItemPath }) => { const menuSelector = `#${buildItemsTableRowId( movedItemId, )} .${ITEM_MENU_BUTTON_CLASS}`; + cy.wait(MENU_ITEM_RENDER_TIME); cy.get(menuSelector).click(); cy.get( `#${buildItemMenu(movedItemId)} .${ITEM_MENU_MOVE_BUTTON_CLASS}`, diff --git a/cypress/integration/item/order/reorderItems.spec.js b/cypress/integration/item/order/reorderItems.spec.js index b580e8911..835a1401d 100644 --- a/cypress/integration/item/order/reorderItems.spec.js +++ b/cypress/integration/item/order/reorderItems.spec.js @@ -4,11 +4,12 @@ import { buildItemsTableRowId, ITEMS_TABLE_BODY, } from '../../../../src/config/selectors'; -import { ROW_HEIGHT } from '../../../support/constants'; +import { MENU_ITEM_RENDER_TIME, ROW_HEIGHT } from '../../../support/constants'; const reorderAndCheckItem = (id, currentPosition, newPosition) => { const childEl = `#${buildItemsTableRowId(id)}`; + cy.wait(MENU_ITEM_RENDER_TIME); cy.dragAndDrop(childEl, 0, (newPosition - currentPosition) * ROW_HEIGHT); cy.wait('@editItem').then( diff --git a/cypress/support/constants.js b/cypress/support/constants.js index 4506335c6..1f96a1dda 100644 --- a/cypress/support/constants.js +++ b/cypress/support/constants.js @@ -13,3 +13,4 @@ export const REDIRECTION_TIME = 500; export const CAPTION_EDIT_PAUSE = 2000; export const ROW_HEIGHT = 93; +export const MENU_ITEM_RENDER_TIME = 2000; diff --git a/src/components/main/CustomCardHeader.js b/src/components/main/CustomCardHeader.js index 86261dd4d..fa0add512 100644 --- a/src/components/main/CustomCardHeader.js +++ b/src/components/main/CustomCardHeader.js @@ -1,14 +1,14 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Link } from 'react-router-dom'; -import { useTranslation } from 'react-i18next'; -import { makeStyles } from '@material-ui/core/styles'; import Avatar from '@material-ui/core/Avatar'; +import { makeStyles } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; +import PropTypes from 'prop-types'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { Link } from 'react-router-dom'; import { buildItemPath } from '../../config/paths'; -import ItemMenu from './ItemMenu'; -import { buildItemLink } from '../../config/selectors'; import { hooks } from '../../config/queryClient'; +import { buildItemLink } from '../../config/selectors'; +import ItemMenu from './ItemMenu'; const { useMember } = hooks; @@ -66,7 +66,7 @@ const CustomCardHeader = ({ item }) => { - + ); }; diff --git a/src/components/main/ItemMenu.js b/src/components/main/ItemMenu.js index 647a6a3e9..75f51578b 100644 --- a/src/components/main/ItemMenu.js +++ b/src/components/main/ItemMenu.js @@ -1,11 +1,13 @@ -import React, { useContext } from 'react'; -import PropTypes from 'prop-types'; -import { useTranslation } from 'react-i18next'; +import { MUTATION_KEYS } from '@graasp/query-client'; +import IconButton from '@material-ui/core/IconButton'; import Menu from '@material-ui/core/Menu'; import MenuItem from '@material-ui/core/MenuItem'; -import IconButton from '@material-ui/core/IconButton'; import MoreVertIcon from '@material-ui/icons/MoreVert'; -import { MUTATION_KEYS } from '@graasp/query-client'; +import { Map } from 'immutable'; +import PropTypes from 'prop-types'; +import React, { useContext } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useMutation } from '../../config/queryClient'; import { buildItemMenu, ITEM_MENU_BUTTON_CLASS, @@ -14,18 +16,14 @@ import { ITEM_MENU_MOVE_BUTTON_CLASS, ITEM_MENU_SHORTCUT_BUTTON_CLASS, } from '../../config/selectors'; +import { isItemFavorite } from '../../utils/item'; import { CopyItemModalContext } from '../context/CopyItemModalContext'; -import { MoveItemModalContext } from '../context/MoveItemModalContext'; import { CreateShortcutModalContext } from '../context/CreateShortcutModalContext'; -import { hooks, useMutation } from '../../config/queryClient'; -import { isItemFavorite } from '../../utils/item'; - -const { useCurrentMember } = hooks; +import { MoveItemModalContext } from '../context/MoveItemModalContext'; -const ItemMenu = ({ item }) => { +const ItemMenu = ({ item, member }) => { const [anchorEl, setAnchorEl] = React.useState(null); const { t } = useTranslation(); - const { data: member } = useCurrentMember(); const { openModal: openCopyModal } = useContext(CopyItemModalContext); const { openModal: openMoveModal } = useContext(MoveItemModalContext); const { openModal: openCreateShortcutModal } = useContext( @@ -122,6 +120,7 @@ const ItemMenu = ({ item }) => { ItemMenu.propTypes = { item: PropTypes.shape({ id: PropTypes.string.isRequired }).isRequired, + member: PropTypes.instanceOf(Map).isRequired, }; export default ItemMenu; diff --git a/src/components/main/ItemsTable.js b/src/components/main/ItemsTable.js index c7ca1bcf8..36c41710f 100644 --- a/src/components/main/ItemsTable.js +++ b/src/components/main/ItemsTable.js @@ -1,4 +1,5 @@ import { MUTATION_KEYS } from '@graasp/query-client'; +import { Loader } from '@graasp/ui'; import Checkbox from '@material-ui/core/Checkbox'; import Paper from '@material-ui/core/Paper'; import { lighten, makeStyles } from '@material-ui/core/styles'; @@ -85,6 +86,7 @@ const computeReorderedIdList = (list, startIndex, endIndex) => { const ItemsTable = ({ items: rows, tableTitle, id: tableId, itemSearch }) => { const { itemId } = useParams(); const { data: parentItem } = useItem(itemId); + const { data: member, isLoading: isMemberLoading } = hooks.useCurrentMember(); const classes = useStyles(); const { t } = useTranslation(); @@ -162,6 +164,10 @@ const ItemsTable = ({ items: rows, tableTitle, id: tableId, itemSearch }) => { { page, rowsPerPage }, ); + if (isMemberLoading) { + return ; + } + // transform rows' information into displayable information const mappedRows = rowsToDisplay.map((item) => { const { id, updatedAt, name, createdAt, type, extra } = item; @@ -184,7 +190,7 @@ const ItemsTable = ({ items: rows, tableTitle, id: tableId, itemSearch }) => { - + ), };