diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8895115f..ef2814a83 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,8 @@ jobs: # NOTE: Netlify uses ubuntu 16.08 but Github Actions does not offer it by default. # Hence, we default to the latest version. runs-on: ubuntu-latest + env: + TIPTAP_PRO_TOKEN: ${{secrets.TIPTAP_PRO_TOKEN}} steps: - uses: actions/checkout@v3 - name: Setup Node.js @@ -32,6 +34,8 @@ jobs: lint: needs: install runs-on: ubuntu-latest + env: + TIPTAP_PRO_TOKEN: ${{secrets.TIPTAP_PRO_TOKEN}} steps: - uses: actions/checkout@v3 - name: Setup Node.js @@ -56,6 +60,7 @@ jobs: needs: lint runs-on: ubuntu-latest env: + TIPTAP_PRO_TOKEN: ${{secrets.TIPTAP_PRO_TOKEN}} CI: false steps: - uses: actions/checkout@v3 @@ -88,6 +93,7 @@ jobs: USERNAME: ${{secrets.USERNAME}} PERSONAL_ACCESS_TOKEN: ${{secrets.PERSONAL_ACCESS_TOKEN}} E2E_COMMIT_HASH: ${{secrets.E2E_COMMIT_HASH}} + TIPTAP_PRO_TOKEN: ${{secrets.TIPTAP_PRO_TOKEN}} steps: - uses: actions/checkout@v3 - name: Setup Node.js diff --git a/.npmrc b/.npmrc index 521a9f7c0..38a663985 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,3 @@ legacy-peer-deps=true +@tiptap-pro:registry=https://registry.tiptap.dev/ +//registry.tiptap.dev/:_authToken=${TIPTAP_PRO_TOKEN} diff --git a/CHANGELOG.md b/CHANGELOG.md index 297d143cd..eed238b93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,34 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v0.63.0](https://github.com/isomerpages/isomercms-frontend/compare/v0.62.0...v0.63.0) + +- fix(embed-views): add a max width [`#1729`](https://github.com/isomerpages/isomercms-frontend/pull/1729) +- fix(blockwrapper): remove padding [`#1728`](https://github.com/isomerpages/isomercms-frontend/pull/1728) +- feat(editor): enhance image bubble menu with more functions [`#1721`](https://github.com/isomerpages/isomercms-frontend/pull/1721) +- feat(editor): feature flag complex blocks [`#1720`](https://github.com/isomerpages/isomercms-frontend/pull/1720) +- fix(tables): update table behaviour [`#1722`](https://github.com/isomerpages/isomercms-frontend/pull/1722) +- refactor(tiptap): change embeds view [`#1723`](https://github.com/isomerpages/isomercms-frontend/pull/1723) +- refactor(tiptap): add placeholder instead of prefill [`#1724`](https://github.com/isomerpages/isomercms-frontend/pull/1724) +- feat(tiptap): add outline blocks [`#1718`](https://github.com/isomerpages/isomercms-frontend/pull/1718) +- feat_background_toggling [`#1713`](https://github.com/isomerpages/isomercms-frontend/pull/1713) +- feat: basic accordion block [`#1709`](https://github.com/isomerpages/isomercms-frontend/pull/1709) +- Feat/select media modal for external media [`#1714`](https://github.com/isomerpages/isomercms-frontend/pull/1714) +- fix(markdowneditpage): fix styling on big screens (1920+) [`#1719`](https://github.com/isomerpages/isomercms-frontend/pull/1719) +- fix(editor): improve embed functionality [`#1717`](https://github.com/isomerpages/isomercms-frontend/pull/1717) +- feat(editor): add trailing node at end of document [`#1716`](https://github.com/isomerpages/isomercms-frontend/pull/1716) +- feat(cards): render preview the same way as template [`#1707`](https://github.com/isomerpages/isomercms-frontend/pull/1707) +- feat(cards): support undo/redo of cards editing [`#1706`](https://github.com/isomerpages/isomercms-frontend/pull/1706) +- feat(cards): allow editing of cards within drawer [`#1705`](https://github.com/isomerpages/isomercms-frontend/pull/1705) +- feat(cards): introduce drawer to support sub-editing [`#1704`](https://github.com/isomerpages/isomercms-frontend/pull/1704) +- feat(tiptap): add card grid block [`#1701`](https://github.com/isomerpages/isomercms-frontend/pull/1701) +- feat(tiptap): allow inserting of complex blocks [`#1697`](https://github.com/isomerpages/isomercms-frontend/pull/1697) +- 0.62.0 to develop [`#1710`](https://github.com/isomerpages/isomercms-frontend/pull/1710) + #### [v0.62.0](https://github.com/isomerpages/isomercms-frontend/compare/v0.61.0...v0.62.0) +> 28 November 2023 + - fix(media): fix logic for disabling button in create media folder modal [`#1712`](https://github.com/isomerpages/isomercms-frontend/pull/1712) - Chore/update regex [`#1703`](https://github.com/isomerpages/isomercms-frontend/pull/1703) - fix(media): allow creating folders in empty folder [`#1702`](https://github.com/isomerpages/isomercms-frontend/pull/1702) diff --git a/package-lock.json b/package-lock.json index eb9ba46cc..5e76a4327 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "isomercms-frontend", - "version": "0.62.0", + "version": "0.63.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "isomercms-frontend", - "version": "0.62.0", + "version": "0.63.0", "hasInstallScript": true, "dependencies": { "@braintree/sanitize-url": "^6.0.1", @@ -29,6 +29,9 @@ "@sentry/react": "^7.12.1", "@sentry/tracing": "^7.12.1", "@tanstack/react-table": "^8.5.13", + "@tiptap-pro/extension-details": "^2.5.0", + "@tiptap-pro/extension-details-content": "^2.5.0", + "@tiptap-pro/extension-details-summary": "^2.5.0", "@tiptap/core": "^2.1.12", "@tiptap/extension-bubble-menu": "^2.1.12", "@tiptap/extension-character-count": "^2.1.12", @@ -10675,6 +10678,47 @@ "react-dom": "^18.0.0" } }, + "node_modules/@tiptap-pro/extension-details": { + "version": "2.5.0", + "resolved": "https://registry.tiptap.dev/@tiptap-pro%2fextension-details/-/extension-details-2.5.0.tgz", + "integrity": "sha512-iZi8We+RcDeetssUha4+h5rxqmobTQxGJFB4C77YEStx5Ae3CZTaiS+8J2uOm4Qbi49iv2aHaRwhi84UnCiROg==", + "license": "SEE LICENSE IN LICENSE.md", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap-pro/extension-details-content": { + "version": "2.5.0", + "resolved": "https://registry.tiptap.dev/@tiptap-pro%2fextension-details-content/-/extension-details-content-2.5.0.tgz", + "integrity": "sha512-WUVROUBjzr8WGk/IEvGUI8F1Zh8y2g5kBpOkOglUGhVak6kbzeXx8TWAyRlMDhAEbAzEhgEa6YxJts3ApdpYwQ==", + "license": "SEE LICENSE IN LICENSE.md", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap-pro/extension-details-summary": { + "version": "2.5.0", + "resolved": "https://registry.tiptap.dev/@tiptap-pro%2fextension-details-summary/-/extension-details-summary-2.5.0.tgz", + "integrity": "sha512-BrgQx2ZBcMDDtAq7Nursa/lRd6ikG+08042dNXMJnyTarnxkMPcfL6nrGhUPJKSogr4MdmsFFkvLhCCuoeZeTA==", + "license": "SEE LICENSE IN LICENSE.md", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, "node_modules/@tiptap/core": { "version": "2.1.12", "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.1.12.tgz", diff --git a/package.json b/package.json index 498ecff1f..64a375eb9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "isomercms-frontend", - "version": "0.62.0", + "version": "0.63.0", "private": true, "engines": { "node": ">=16.0.0" @@ -26,6 +26,9 @@ "@sentry/react": "^7.12.1", "@sentry/tracing": "^7.12.1", "@tanstack/react-table": "^8.5.13", + "@tiptap-pro/extension-details": "^2.5.0", + "@tiptap-pro/extension-details-content": "^2.5.0", + "@tiptap-pro/extension-details-summary": "^2.5.0", "@tiptap/core": "^2.1.12", "@tiptap/extension-bubble-menu": "^2.1.12", "@tiptap/extension-character-count": "^2.1.12", diff --git a/src/assets/images/EditorAccordionImage.tsx b/src/assets/images/EditorAccordionImage.tsx new file mode 100644 index 000000000..f692f552c --- /dev/null +++ b/src/assets/images/EditorAccordionImage.tsx @@ -0,0 +1,31 @@ +export const EditorAccordionImage = ( + props: React.SVGProps +): JSX.Element => { + return ( + + + + + + + + + + ) +} diff --git a/src/assets/images/EditorCardsImage.tsx b/src/assets/images/EditorCardsImage.tsx new file mode 100644 index 000000000..a0dfc4311 --- /dev/null +++ b/src/assets/images/EditorCardsImage.tsx @@ -0,0 +1,22 @@ +export const EditorCardsImage = ( + props: React.SVGProps +): JSX.Element => { + return ( + + + + + + + + + + ) +} diff --git a/src/assets/images/EditorCardsPlaceholderImage.tsx b/src/assets/images/EditorCardsPlaceholderImage.tsx new file mode 100644 index 000000000..898c4a2a8 --- /dev/null +++ b/src/assets/images/EditorCardsPlaceholderImage.tsx @@ -0,0 +1,128 @@ +export const EditorCardsPlaceholderImage = ( + props: React.SVGProps +): JSX.Element => { + return ( + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/assets/images/EditorDividerImage.tsx b/src/assets/images/EditorDividerImage.tsx new file mode 100644 index 000000000..2c3bb35e1 --- /dev/null +++ b/src/assets/images/EditorDividerImage.tsx @@ -0,0 +1,17 @@ +export const EditorDividerImage = ( + props: React.SVGProps +): JSX.Element => { + return ( + + + + + ) +} diff --git a/src/assets/images/index.ts b/src/assets/images/index.ts index 30ca9f72a..53f98f119 100644 --- a/src/assets/images/index.ts +++ b/src/assets/images/index.ts @@ -26,3 +26,7 @@ export * from "./SingpassLogo" export * from "./EmptyAlbumImage" export * from "./EmptyDirectoryImage" export * from "./BulkUploadAnnouncementImage" +export * from "./EditorAccordionImage" +export * from "./EditorCardsImage" +export * from "./EditorDividerImage" +export * from "./EditorCardsPlaceholderImage" diff --git a/src/components/Editable/Editable.tsx b/src/components/Editable/Editable.tsx index cdf39486b..f39a59e87 100644 --- a/src/components/Editable/Editable.tsx +++ b/src/components/Editable/Editable.tsx @@ -177,10 +177,13 @@ type ContactUsDroppableZone = type NavDroppableZone = "link" | `sublink-${number}` +type NormalPageDroppableZone = "cards" + type DroppableZone = | HomepageDroppableZone | ContactUsDroppableZone | NavDroppableZone + | NormalPageDroppableZone type DropInfo = { droppableId: DroppableZone diff --git a/src/components/EditorCardsDrawer/EditorCardItem.tsx b/src/components/EditorCardsDrawer/EditorCardItem.tsx new file mode 100644 index 000000000..dffb83306 --- /dev/null +++ b/src/components/EditorCardsDrawer/EditorCardItem.tsx @@ -0,0 +1,238 @@ +import { + Box, + FormControl, + HStack, + Modal, + ModalBody, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Text, + useDisclosure, + VStack, +} from "@chakra-ui/react" +import { + Button, + FormErrorMessage, + FormHelperText, + FormLabel, + Input, + ModalCloseButton, + Textarea, +} from "@opengovsg/design-system-react" +import _ from "lodash" +import { UseFormReturn } from "react-hook-form" + +import { Editable } from "components/Editable" +import { FormContext } from "components/Form" +import FormFieldMedia from "components/FormFieldMedia" + +import { TIPTAP_CARDS_DESCRIPTION_CHAR_LIMIT } from "constants/tiptap" + +import { useEditableContext } from "contexts/EditableContext" + +import { EditorCardsInfo } from "types/editPage" + +interface EditorCardItemProps { + index: number + methods: UseFormReturn +} + +export const EditorCardItem = ({ + index, + methods, +}: EditorCardItemProps): JSX.Element => { + const { onChange, onDelete } = useEditableContext() + const { + isOpen: isDeleteWarningModalOpen, + onOpen: onDeleteWarningModalOpen, + onClose: onDeleteWarningModalClose, + } = useDisclosure() + const { errors } = methods.formState + + return ( + <> + + + + + + + + Are you sure you want to delete this card? + + + + + + This cannot be undone. + + + + + + + + + + + + + + + {/* Card image */} + {methods.watch("isDisplayImage") && ( + <> + + { + methods.setValue(`cards.${index}.image`, e.target.value) + methods.trigger() + onChange(e) + }} + > + + Image + + + + {errors.cards?.[index]?.image?.message} + + + + + {/* Card image alt text */} + + Alt text + + A short description about the image for accessibility and SEO + + + + {errors.cards?.[index]?.altText?.message} + + + + )} + + {/* Card title */} + + Title + + + {errors.cards?.[index]?.title?.message} + + + + {/* Card description */} + + Description +