Skip to content

Commit

Permalink
feat: handle automatic publication after validation (#1265)
Browse files Browse the repository at this point in the history
* feat: update frontend to handle automatic publication
- warn the user that the item will set it to publish after the validation

* chore(refactor): extract PublicationButton in individual components

* feat: improve code from code review

* feat: update query-client to 3.13.0
  • Loading branch information
ReidyT authored Jun 10, 2024
1 parent 4a0786f commit 565bbcc
Show file tree
Hide file tree
Showing 17 changed files with 540 additions and 225 deletions.
4 changes: 4 additions & 0 deletions cypress/e2e/item/publish/publishedItem.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
Expand Down Expand Up @@ -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);
});
});
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
7 changes: 5 additions & 2 deletions src/components/item/publish/ItemPublishTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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<number> };

Expand Down Expand Up @@ -110,7 +110,10 @@ const ItemPublishTab = (): JSX.Element => {
notifyCoEditors={notifyCoEditors}
onNotificationChanged={(enabled) => setNotifyCoEditors(enabled)}
/>
<PublicationButton item={item} notifyCoEditors={notifyCoEditors} />
<PublicationButtonSelector
item={item}
notifyCoEditors={notifyCoEditors}
/>
</Stack>
);

Expand Down
13 changes: 10 additions & 3 deletions src/components/item/publish/PublicVisibilityModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,28 @@ 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 => {
const { t } = useBuilderTranslation();
const { updateVisibility } = useVisibility(item);

const handleValidate = async () => {
await updateVisibility(SETTINGS.ITEM_PUBLIC.name);
onValidate();
if (shouldUpdateVisibility) {
await updateVisibility(SETTINGS.ITEM_PUBLIC.name);
}
onValidate?.();
};

return (
Expand Down
214 changes: 0 additions & 214 deletions src/components/item/publish/PublicationButton.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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 <Typography>{description}</Typography>;
}

return description;
};

export default DescriptionElement;
73 changes: 73 additions & 0 deletions src/components/item/publish/publicationButtons/InvalidButton.tsx
Original file line number Diff line number Diff line change
@@ -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 && (
<PublicVisibilityModal
item={item}
isOpen={isOpen}
shouldUpdateVisibility={false}
onClose={closeModal}
onValidate={handleModalValidate}
/>
)}
<PublicationButton isLoading={isLoading} description={description}>
<LoadingButton
variant="contained"
onClick={handleValidateItem}
loading={isValidating}
data-cy={buildItemPublicationButton(PublicationStatus.Invalid)}
>
{t(BUILDER.LIBRARY_SETTINGS_RETRY_BUTTON)}
</LoadingButton>
</PublicationButton>
</>
);
};

export default InvalidButton;
Loading

0 comments on commit 565bbcc

Please sign in to comment.