diff --git a/cypress/e2e/item/publish/publishedItem.cy.ts b/cypress/e2e/item/publish/publishedItem.cy.ts index 1f89664cc..dfb157dbc 100644 --- a/cypress/e2e/item/publish/publishedItem.cy.ts +++ b/cypress/e2e/item/publish/publishedItem.cy.ts @@ -133,6 +133,8 @@ describe('Private Item', () => { it('Item can be validated', () => { getPublicationButton(status).click(); // Click on validate + // confirming the modal will not send to the backend until the validation is done + confirmSetItemToPublic(); waitOnItemValidation(privateItem); }); }); @@ -206,6 +208,8 @@ describe('Private Item', () => { it('Item can be validated again', () => { getPublicationButton(status).click(); // click on retry + // confirming the modal will not send to the backend until the validation is done + confirmSetItemToPublic(); waitOnItemValidation(privateItem); }); }); diff --git a/package.json b/package.json index e6dabd92a..8c9b7efa7 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "@emotion/styled": "11.11.5", "@graasp/chatbox": "3.1.0", "@graasp/map": "1.15.0", - "@graasp/query-client": "3.11.0", + "@graasp/query-client": "3.13.0", "@graasp/sdk": "4.12.1", "@graasp/translations": "1.28.0", "@graasp/ui": "4.19.2", diff --git a/src/components/item/publish/ItemPublishTab.tsx b/src/components/item/publish/ItemPublishTab.tsx index 101764269..f0e5e3db5 100644 --- a/src/components/item/publish/ItemPublishTab.tsx +++ b/src/components/item/publish/ItemPublishTab.tsx @@ -16,7 +16,6 @@ import CoEditorsContainer from '@/components/item/publish/CoEditorsContainer'; import EditItemDescription from '@/components/item/publish/EditItemDescription'; import LanguagesContainer from '@/components/item/publish/LanguagesContainer'; import LicenseContainer from '@/components/item/publish/LicenseContainer'; -import PublicationButton from '@/components/item/publish/PublicationButton'; import PublicationStatusComponent from '@/components/item/publish/PublicationStatusComponent'; import PublicationThumbnail from '@/components/item/publish/PublicationThumbnail'; import { OutletType } from '@/components/pages/item/type'; @@ -26,6 +25,7 @@ import { SomeBreakPoints } from '@/types/breakpoint'; import EditItemName from './EditItemName'; import CustomizedTags from './customizedTags/CustomizedTags'; +import PublicationButtonSelector from './publicationButtons/PublicationButtonSelector'; type StackOrder = { order?: number | SomeBreakPoints }; @@ -110,7 +110,10 @@ const ItemPublishTab = (): JSX.Element => { notifyCoEditors={notifyCoEditors} onNotificationChanged={(enabled) => setNotifyCoEditors(enabled)} /> - + ); diff --git a/src/components/item/publish/PublicVisibilityModal.tsx b/src/components/item/publish/PublicVisibilityModal.tsx index c6dab8a93..761cf6a06 100644 --- a/src/components/item/publish/PublicVisibilityModal.tsx +++ b/src/components/item/publish/PublicVisibilityModal.tsx @@ -19,12 +19,17 @@ import useVisibility from '../../hooks/useVisibility'; type Props = { item: PackedItem; isOpen: boolean; + // if set to false, the item will not be public after validating the modal. + // this allows to set the item to public only after the validation on the backend side. + shouldUpdateVisibility?: boolean; onClose: () => void; - onValidate: () => void; + onValidate?: () => void; }; + export const PublicVisibilityModal = ({ item, isOpen, + shouldUpdateVisibility = true, onClose, onValidate, }: Props): JSX.Element => { @@ -32,8 +37,10 @@ export const PublicVisibilityModal = ({ const { updateVisibility } = useVisibility(item); const handleValidate = async () => { - await updateVisibility(SETTINGS.ITEM_PUBLIC.name); - onValidate(); + if (shouldUpdateVisibility) { + await updateVisibility(SETTINGS.ITEM_PUBLIC.name); + } + onValidate?.(); }; return ( diff --git a/src/components/item/publish/PublicationButton.tsx b/src/components/item/publish/PublicationButton.tsx deleted file mode 100644 index f97668c46..000000000 --- a/src/components/item/publish/PublicationButton.tsx +++ /dev/null @@ -1,214 +0,0 @@ -import LinkIcon from '@mui/icons-material/Link'; -import { LoadingButton } from '@mui/lab'; -import { Alert, Button, Stack, Typography } from '@mui/material'; - -import { ClientHostManager, PackedItem, ShortLinkPlatform } from '@graasp/sdk'; - -import { CheckIcon } from 'lucide-react'; - -import { ADMIN_CONTACT } from '@/config/constants'; -import { useBuilderTranslation } from '@/config/i18n'; -import { mutations } from '@/config/queryClient'; -import { buildItemPublicationButton } from '@/config/selectors'; -import { BUILDER } from '@/langs/constants'; -import { PublicationStatus, PublicationStatusMap } from '@/types/publication'; - -import ContentLoader from '../../common/ContentLoader'; -import useModalStatus from '../../hooks/useModalStatus'; -import usePublicationStatus from '../../hooks/usePublicationStatus'; -import PublicVisibilityModal from './PublicVisibilityModal'; - -type Props = { - item: PackedItem; - notifyCoEditors: boolean; -}; - -type PublicationButtonMap = PublicationStatusMap<{ - description: JSX.Element | string; - elements: JSX.Element | JSX.Element[]; -}>; - -const { useUnpublishItem, usePublishItem, usePostItemValidation } = mutations; - -export const PublicationButton = ({ - item, - notifyCoEditors, -}: Props): JSX.Element => { - const { t } = useBuilderTranslation(); - const { id: itemId, public: isPublic } = item; - const { status, isinitialLoading: isStatusFirstLoading } = - usePublicationStatus({ item }); - const { isOpen, openModal, closeModal } = useModalStatus(); - - const { mutate: validateItem, isLoading: isValidating } = - usePostItemValidation(); - const { mutate: unpublish, isLoading: isUnPublishing } = useUnpublishItem(); - const { mutate: publish, isLoading: isPublishing } = usePublishItem(); - - const publishItem = () => - publish({ id: itemId, notification: notifyCoEditors }); - - const handlePublishItem = () => { - if (isPublic) { - publishItem(); - } else { - openModal(); - } - }; - - const handleValidateItem = () => validateItem({ itemId }); - const handleUnPublishItem = () => unpublish({ id: itemId }); - - const handleModalValidate = () => { - publishItem(); - closeModal(); - }; - - const getLibraryLink = () => { - const clientHostManager = ClientHostManager.getInstance(); - return clientHostManager.getItemLink(ShortLinkPlatform.library, itemId); - }; - - const publicationButtonMap: PublicationButtonMap = { - [PublicationStatus.Unpublished]: { - description: t(BUILDER.LIBRARY_SETTINGS_VALIDATION_INFORMATIONS), - elements: ( - - {t(BUILDER.LIBRARY_SETTINGS_VALIDATION_VALIDATE_BUTTON)} - - ), - }, - [PublicationStatus.Pending]: { - description: t( - BUILDER.LIBRARY_SETTINGS_VALIDATION_STATUS_PENDING_AUTOMATIC, - ), - elements: [], - }, - [PublicationStatus.ReadyToPublish]: { - description: ( - } severity="info"> - {t(BUILDER.LIBRARY_SETTINGS_VALIDATION_STATUS_READY_TO_PUBLISH)} - - ), - elements: ( - - {t(BUILDER.LIBRARY_SETTINGS_PUBLISH_BUTTON)} - - ), - }, - [PublicationStatus.NotPublic]: { - description: t(BUILDER.LIBRARY_SETTINGS_VISIBILITY_INFORMATIONS), - elements: ( - - {t(BUILDER.LIBRARY_SETTINGS_VISIBILITY_CHANGE_BUTTON)} - - ), - }, - [PublicationStatus.Published]: { - description: t(BUILDER.LIBRARY_SETTINGS_PUBLISHED_STATUS), - elements: [ - - {t(BUILDER.LIBRARY_SETTINGS_UNPUBLISH_BUTTON)} - , - , - ], - }, - [PublicationStatus.PublishedChildren]: { - description: t(BUILDER.LIBRARY_SETTINGS_CHILD_PUBLISHED_STATUS), - elements: [], - }, - [PublicationStatus.Invalid]: { - description: t(BUILDER.LIBRARY_SETTINGS_VALIDATION_STATUS_FAILURE, { - contact: ADMIN_CONTACT, - }), - elements: ( - - {t(BUILDER.LIBRARY_SETTINGS_RETRY_BUTTON)} - - ), - }, - [PublicationStatus.Outdated]: { - description: t(BUILDER.LIBRARY_SETTINGS_VALIDATION_STATUS_OUTDATED), - elements: ( - - {t(BUILDER.LIBRARY_SETTINGS_VALIDATION_VALIDATE_BUTTON)} - - ), - }, - }; - - const getDescriptionElement = ( - description: string | JSX.Element, - ): JSX.Element => { - if (typeof description === 'string') { - return {description}; - } - - return description; - }; - - const { description, elements } = publicationButtonMap[status]; - - return ( - <> - {!isPublic && ( - - )} - - - {getDescriptionElement(description)} - - - {elements} - - - - - ); -}; - -export default PublicationButton; diff --git a/src/components/item/publish/publicationButtons/DescriptionElement.tsx b/src/components/item/publish/publicationButtons/DescriptionElement.tsx new file mode 100644 index 000000000..2d73f005d --- /dev/null +++ b/src/components/item/publish/publicationButtons/DescriptionElement.tsx @@ -0,0 +1,17 @@ +import { ReactNode } from 'react'; + +import { Typography } from '@mui/material'; + +type Props = { + description: ReactNode; +}; + +export const DescriptionElement = ({ description }: Props): ReactNode => { + if (typeof description === 'string') { + return {description}; + } + + return description; +}; + +export default DescriptionElement; diff --git a/src/components/item/publish/publicationButtons/InvalidButton.tsx b/src/components/item/publish/publicationButtons/InvalidButton.tsx new file mode 100644 index 000000000..99222408b --- /dev/null +++ b/src/components/item/publish/publicationButtons/InvalidButton.tsx @@ -0,0 +1,73 @@ +import { LoadingButton } from '@mui/lab'; + +import { PackedItem } from '@graasp/sdk'; + +import useModalStatus from '@/components/hooks/useModalStatus'; +import { ADMIN_CONTACT } from '@/config/constants'; +import { useBuilderTranslation } from '@/config/i18n'; +import { mutations } from '@/config/queryClient'; +import { buildItemPublicationButton } from '@/config/selectors'; +import { BUILDER } from '@/langs/constants'; +import { PublicationStatus } from '@/types/publication'; + +import PublicVisibilityModal from '../PublicVisibilityModal'; +import PublicationButton from './PublicationButton'; + +type Props = { + item: PackedItem; + isLoading: boolean; +}; + +const { usePostItemValidation } = mutations; + +export const InvalidButton = ({ item, isLoading }: Props): JSX.Element => { + const { t } = useBuilderTranslation(); + const { id: itemId, public: isPublic } = item; + const { isOpen, openModal, closeModal } = useModalStatus(); + + const { mutate: validateItem, isLoading: isValidating } = + usePostItemValidation(); + + const handleValidateItem = () => { + if (isPublic) { + validateItem({ itemId }); + } else { + openModal(); + } + }; + + const handleModalValidate = () => { + validateItem({ itemId }); + closeModal(); + }; + + const description = t(BUILDER.LIBRARY_SETTINGS_VALIDATION_STATUS_FAILURE, { + contact: ADMIN_CONTACT, + }); + + return ( + <> + {!isPublic && ( + + )} + + + {t(BUILDER.LIBRARY_SETTINGS_RETRY_BUTTON)} + + + + ); +}; + +export default InvalidButton; diff --git a/src/components/item/publish/publicationButtons/NotPublicButton.tsx b/src/components/item/publish/publicationButtons/NotPublicButton.tsx new file mode 100644 index 000000000..37e32be36 --- /dev/null +++ b/src/components/item/publish/publicationButtons/NotPublicButton.tsx @@ -0,0 +1,41 @@ +import { LoadingButton } from '@mui/lab'; + +import { PackedItem } from '@graasp/sdk'; + +import useModalStatus from '@/components/hooks/useModalStatus'; +import { useBuilderTranslation } from '@/config/i18n'; +import { buildItemPublicationButton } from '@/config/selectors'; +import { BUILDER } from '@/langs/constants'; +import { PublicationStatus } from '@/types/publication'; + +import PublicVisibilityModal from '../PublicVisibilityModal'; +import PublicationButton from './PublicationButton'; + +type Props = { + item: PackedItem; +}; + +export const NotPublicButton = ({ item }: Props): JSX.Element => { + const { t } = useBuilderTranslation(); + const { isOpen, openModal, closeModal } = useModalStatus(); + + const description = t(BUILDER.LIBRARY_SETTINGS_VISIBILITY_INFORMATIONS); + + return ( + <> + + + + + {t(BUILDER.LIBRARY_SETTINGS_VISIBILITY_CHANGE_BUTTON)} + + + + ); +}; + +export default NotPublicButton; diff --git a/src/components/item/publish/publicationButtons/OutdatedButton.tsx b/src/components/item/publish/publicationButtons/OutdatedButton.tsx new file mode 100644 index 000000000..511515709 --- /dev/null +++ b/src/components/item/publish/publicationButtons/OutdatedButton.tsx @@ -0,0 +1,45 @@ +import { LoadingButton } from '@mui/lab'; + +import { PackedItem } from '@graasp/sdk'; + +import { useBuilderTranslation } from '@/config/i18n'; +import { mutations } from '@/config/queryClient'; +import { buildItemPublicationButton } from '@/config/selectors'; +import { BUILDER } from '@/langs/constants'; +import { PublicationStatus } from '@/types/publication'; + +import PublicationButton from './PublicationButton'; + +type Props = { + item: PackedItem; + isLoading: boolean; +}; + +const { usePostItemValidation } = mutations; + +export const OutdatedButton = ({ item, isLoading }: Props): JSX.Element => { + const { t } = useBuilderTranslation(); + const { id: itemId } = item; + + const { mutate: validateItem, isLoading: isValidating } = + usePostItemValidation(); + + const handleValidateItem = () => validateItem({ itemId }); + + const description = t(BUILDER.LIBRARY_SETTINGS_VALIDATION_STATUS_OUTDATED); + + return ( + + + {t(BUILDER.LIBRARY_SETTINGS_VALIDATION_VALIDATE_BUTTON)} + + + ); +}; + +export default OutdatedButton; diff --git a/src/components/item/publish/publicationButtons/PendingButton.tsx b/src/components/item/publish/publicationButtons/PendingButton.tsx new file mode 100644 index 000000000..7e91b18e7 --- /dev/null +++ b/src/components/item/publish/publicationButtons/PendingButton.tsx @@ -0,0 +1,19 @@ +import { useBuilderTranslation } from '@/config/i18n'; +import { BUILDER } from '@/langs/constants'; + +import PublicationButton from './PublicationButton'; + +export const PendingButton = (): JSX.Element => { + const { t } = useBuilderTranslation(); + + return ( + + ); +}; + +export default PendingButton; diff --git a/src/components/item/publish/publicationButtons/PublicationButton.tsx b/src/components/item/publish/publicationButtons/PublicationButton.tsx new file mode 100644 index 000000000..a306186c2 --- /dev/null +++ b/src/components/item/publish/publicationButtons/PublicationButton.tsx @@ -0,0 +1,31 @@ +import { ReactNode } from 'react'; + +import { Stack } from '@mui/material'; + +import ContentLoader from '@/components/common/ContentLoader'; + +import DescriptionElement from './DescriptionElement'; + +type Props = { + isLoading: boolean; + description: ReactNode; + children?: ReactNode; +}; + +export const PublicationButton = ({ + isLoading, + description, + children = [], +}: Props): JSX.Element => ( + + + + + + {children} + + + +); + +export default PublicationButton; diff --git a/src/components/item/publish/publicationButtons/PublicationButtonSelector.tsx b/src/components/item/publish/publicationButtons/PublicationButtonSelector.tsx new file mode 100644 index 000000000..d43cd67c4 --- /dev/null +++ b/src/components/item/publish/publicationButtons/PublicationButtonSelector.tsx @@ -0,0 +1,58 @@ +import { ReactNode } from 'react'; + +import { PackedItem } from '@graasp/sdk'; + +import { usePublicationStatus } from '@/components/hooks/usePublicationStatus'; +import { PublicationStatus } from '@/types/publication'; + +import InvalidButton from './InvalidButton'; +import NotPublicButton from './NotPublicButton'; +import OutdatedButton from './OutdatedButton'; +import PendingButton from './PendingButton'; +import PublishedButton from './PublishedButton'; +import PublishedChildrenButton from './PublishedChildrenButton'; +import ReadyToPublishButton from './ReadyToPublishButton'; +import UnpublishedButton from './UnpublishedButton'; + +type Props = { + item: PackedItem; + notifyCoEditors: boolean; +}; + +export const PublicationButtonSelector = ({ + item, + notifyCoEditors, +}: Props): ReactNode | undefined => { + const { status, isinitialLoading: isStatusFirstLoading } = + usePublicationStatus({ item }); + + switch (status) { + case PublicationStatus.Unpublished: + return ; + case PublicationStatus.Pending: + return ; + case PublicationStatus.ReadyToPublish: + return ( + + ); + case PublicationStatus.NotPublic: + return ; + case PublicationStatus.Published: + return ; + case PublicationStatus.PublishedChildren: + return ; + case PublicationStatus.Invalid: + return ; + case PublicationStatus.Outdated: + return ; + default: + console.error(`The status "${status}" is unknown.`); + return undefined; + } +}; + +export default PublicationButtonSelector; diff --git a/src/components/item/publish/publicationButtons/PublishedButton.tsx b/src/components/item/publish/publicationButtons/PublishedButton.tsx new file mode 100644 index 000000000..10a632bc1 --- /dev/null +++ b/src/components/item/publish/publicationButtons/PublishedButton.tsx @@ -0,0 +1,61 @@ +import LinkIcon from '@mui/icons-material/Link'; +import { LoadingButton } from '@mui/lab'; +import { Button } from '@mui/material'; + +import { ClientHostManager, PackedItem, ShortLinkPlatform } from '@graasp/sdk'; + +import { useBuilderTranslation } from '@/config/i18n'; +import { mutations } from '@/config/queryClient'; +import { buildItemPublicationButton } from '@/config/selectors'; +import { BUILDER } from '@/langs/constants'; +import { PublicationStatus } from '@/types/publication'; + +import PublicationButton from './PublicationButton'; + +type Props = { + item: PackedItem; + isLoading: boolean; +}; + +const { useUnpublishItem } = mutations; + +export const PublishedButton = ({ item, isLoading }: Props): JSX.Element => { + const { t } = useBuilderTranslation(); + const { id: itemId } = item; + + const { mutate: unpublish, isLoading: isUnPublishing } = useUnpublishItem(); + + const handleUnPublishItem = () => unpublish({ id: itemId }); + + const getLibraryLink = () => { + const clientHostManager = ClientHostManager.getInstance(); + return clientHostManager.getItemLink(ShortLinkPlatform.library, itemId); + }; + + const description = t(BUILDER.LIBRARY_SETTINGS_PUBLISHED_STATUS); + + return ( + + + {t(BUILDER.LIBRARY_SETTINGS_UNPUBLISH_BUTTON)} + + + + ); +}; + +export default PublishedButton; diff --git a/src/components/item/publish/publicationButtons/PublishedChildrenButton.tsx b/src/components/item/publish/publicationButtons/PublishedChildrenButton.tsx new file mode 100644 index 000000000..f05528bda --- /dev/null +++ b/src/components/item/publish/publicationButtons/PublishedChildrenButton.tsx @@ -0,0 +1,17 @@ +import { useBuilderTranslation } from '@/config/i18n'; +import { BUILDER } from '@/langs/constants'; + +import PublicationButton from './PublicationButton'; + +export const PublishedChildrenButton = (): JSX.Element => { + const { t } = useBuilderTranslation(); + + return ( + + ); +}; + +export default PublishedChildrenButton; diff --git a/src/components/item/publish/publicationButtons/ReadyToPublishButton.tsx b/src/components/item/publish/publicationButtons/ReadyToPublishButton.tsx new file mode 100644 index 000000000..017e5138e --- /dev/null +++ b/src/components/item/publish/publicationButtons/ReadyToPublishButton.tsx @@ -0,0 +1,83 @@ +import { LoadingButton } from '@mui/lab'; +import { Alert } from '@mui/material'; + +import { PackedItem } from '@graasp/sdk'; + +import { CheckIcon } from 'lucide-react'; + +import useModalStatus from '@/components/hooks/useModalStatus'; +import { useBuilderTranslation } from '@/config/i18n'; +import { mutations } from '@/config/queryClient'; +import { buildItemPublicationButton } from '@/config/selectors'; +import { BUILDER } from '@/langs/constants'; +import { PublicationStatus } from '@/types/publication'; + +import PublicVisibilityModal from '../PublicVisibilityModal'; +import PublicationButton from './PublicationButton'; + +type Props = { + item: PackedItem; + isLoading: boolean; + notifyCoEditors: boolean; +}; + +const { usePublishItem } = mutations; + +export const ReadyToPublishButton = ({ + item, + isLoading, + notifyCoEditors, +}: Props): JSX.Element => { + const { t } = useBuilderTranslation(); + const { id: itemId, public: isPublic } = item; + const { isOpen, openModal, closeModal } = useModalStatus(); + + const { mutate: publish, isLoading: isPublishing } = usePublishItem(); + + const publishItem = () => + publish({ id: itemId, notification: notifyCoEditors }); + + const handlePublishItem = () => { + if (isPublic) { + publishItem(); + } else { + openModal(); + } + }; + + const handleModalValidate = () => { + publishItem(); + closeModal(); + }; + + const description = ( + } severity="success"> + {t(BUILDER.LIBRARY_SETTINGS_VALIDATION_STATUS_READY_TO_PUBLISH)} + + ); + + return ( + <> + {!isPublic && ( + + )} + + + {t(BUILDER.LIBRARY_SETTINGS_PUBLISH_BUTTON)} + + + + ); +}; + +export default ReadyToPublishButton; diff --git a/src/components/item/publish/publicationButtons/UnpublishedButton.tsx b/src/components/item/publish/publicationButtons/UnpublishedButton.tsx new file mode 100644 index 000000000..05cea4583 --- /dev/null +++ b/src/components/item/publish/publicationButtons/UnpublishedButton.tsx @@ -0,0 +1,70 @@ +import { LoadingButton } from '@mui/lab'; + +import { PackedItem } from '@graasp/sdk'; + +import useModalStatus from '@/components/hooks/useModalStatus'; +import { useBuilderTranslation } from '@/config/i18n'; +import { mutations } from '@/config/queryClient'; +import { buildItemPublicationButton } from '@/config/selectors'; +import { BUILDER } from '@/langs/constants'; +import { PublicationStatus } from '@/types/publication'; + +import PublicVisibilityModal from '../PublicVisibilityModal'; +import PublicationButton from './PublicationButton'; + +type Props = { + item: PackedItem; + isLoading: boolean; +}; + +const { usePostItemValidation } = mutations; + +export const UnpublishedButton = ({ item, isLoading }: Props): JSX.Element => { + const { t } = useBuilderTranslation(); + const { id: itemId, public: isPublic } = item; + const { isOpen, openModal, closeModal } = useModalStatus(); + + const { mutate: validateItem, isLoading: isValidating } = + usePostItemValidation(); + + const handleValidateItem = () => { + if (isPublic) { + validateItem({ itemId }); + } else { + openModal(); + } + }; + + const handleModalValidate = () => { + validateItem({ itemId }); + closeModal(); + }; + + const description = t(BUILDER.LIBRARY_SETTINGS_VALIDATION_INFORMATIONS); + + return ( + <> + {!isPublic && ( + + )} + + + {t(BUILDER.LIBRARY_SETTINGS_VALIDATION_VALIDATE_BUTTON)} + + + + ); +}; + +export default UnpublishedButton; diff --git a/yarn.lock b/yarn.lock index 46e299909..ba5205d5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1751,9 +1751,9 @@ __metadata: languageName: node linkType: hard -"@graasp/query-client@npm:3.11.0": - version: 3.11.0 - resolution: "@graasp/query-client@npm:3.11.0" +"@graasp/query-client@npm:3.13.0": + version: 3.13.0 + resolution: "@graasp/query-client@npm:3.13.0" dependencies: "@tanstack/react-query": "npm:4.36.1" "@tanstack/react-query-devtools": "npm:4.36.1" @@ -1764,7 +1764,7 @@ __metadata: "@graasp/sdk": ^4.0.0 "@graasp/translations": ^1.23.0 react: ^18.0.0 - checksum: 10/08e2b56136e2e1ae48dc2c619a0eff9d5594eb277572c8a3ae85953932fec94be5b97bec78817402a5c833dbd2d709cce556549af0e47b13a360ebdbeb85e0ec + checksum: 10/c8ebd83962dcad8478806ed946fde35657b6bdea13c693aff5494d8dc67bb2a10c05d82bcd6bbd785694c601f2e56de96ac58040fcee976bd3fcb2234b3b80d1 languageName: node linkType: hard @@ -8084,7 +8084,7 @@ __metadata: "@emotion/styled": "npm:11.11.5" "@graasp/chatbox": "npm:3.1.0" "@graasp/map": "npm:1.15.0" - "@graasp/query-client": "npm:3.11.0" + "@graasp/query-client": "npm:3.13.0" "@graasp/sdk": "npm:4.12.1" "@graasp/translations": "npm:1.28.0" "@graasp/ui": "npm:4.19.2"