From 985868a1a90fdbff01b7d4172679a2f5b19bc38b Mon Sep 17 00:00:00 2001 From: Johannes Obermair <48853629+johnnyomair@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:12:08 +0100 Subject: [PATCH 1/5] Automatically assign author and reviewer to PRs (#1527) --- .github/auto_assign.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/auto_assign.yml diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml new file mode 100644 index 0000000000..b0ea7f3183 --- /dev/null +++ b/.github/auto_assign.yml @@ -0,0 +1,6 @@ +addAssignees: author + +addReviewers: true + +reviewers: + - johnnyomair From dcaf750d88552a4d99530d4233610de866f17273 Mon Sep 17 00:00:00 2001 From: Thomas Dax Date: Thu, 21 Dec 2023 14:22:25 +0100 Subject: [PATCH 2/5] Make DAM license fields optional for ROYALTY_FREE (#1526) Make all DAM license fields optional if `LicenseType` is `ROYALTY_FREE` even if `requireLicense` is true in `DamConfig`. Closes COM-250 --- .changeset/tricky-adults-laugh.md | 5 +++ .../cms-admin/src/dam/FileForm/EditFile.tsx | 1 - .../src/dam/FileForm/FileSettingsFields.tsx | 42 +++++++++++++------ 3 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 .changeset/tricky-adults-laugh.md diff --git a/.changeset/tricky-adults-laugh.md b/.changeset/tricky-adults-laugh.md new file mode 100644 index 0000000000..4c34ff0d0e --- /dev/null +++ b/.changeset/tricky-adults-laugh.md @@ -0,0 +1,5 @@ +--- +"@comet/cms-admin": minor +--- + +Make all DAM license fields optional if `LicenseType` is `ROYALTY_FREE` even if `requireLicense` is true in `DamConfig` diff --git a/packages/admin/cms-admin/src/dam/FileForm/EditFile.tsx b/packages/admin/cms-admin/src/dam/FileForm/EditFile.tsx index dfc9ed4b5a..c2f7c8deb0 100644 --- a/packages/admin/cms-admin/src/dam/FileForm/EditFile.tsx +++ b/packages/admin/cms-admin/src/dam/FileForm/EditFile.tsx @@ -195,7 +195,6 @@ const EditFileInner = ({ file, id }: EditFileInnerProps) => { // override default onAfterSubmit because default is stackApi.goBack() // https://github.com/vivid-planet/comet/blob/master/packages/admin/src/FinalForm.tsx#L53 }} - validateOnBlur > {({ pristine, hasValidationErrors, submitting, handleSubmit }) => ( <> diff --git a/packages/admin/cms-admin/src/dam/FileForm/FileSettingsFields.tsx b/packages/admin/cms-admin/src/dam/FileForm/FileSettingsFields.tsx index 08c21addcf..ebdd5c71f7 100644 --- a/packages/admin/cms-admin/src/dam/FileForm/FileSettingsFields.tsx +++ b/packages/admin/cms-admin/src/dam/FileForm/FileSettingsFields.tsx @@ -59,6 +59,18 @@ export const FileSettingsFields = ({ isImage, folderId }: SettingsFormProps): Re [apollo, folderId, scope], ); + const requiredValidator = React.useCallback( + (value: unknown, allValues: object) => { + const type = (allValues as EditFileFormValues).license?.type; + const isRequired = type === "ROYALTY_FREE" ? false : damConfig.requireLicense; + + if (isRequired && !value) { + return ; + } + }, + [damConfig.requireLicense], + ); + return (
@@ -122,10 +134,9 @@ export const FileSettingsFields = ({ isImage, folderId }: SettingsFormProps): Re } }} shouldShowError={() => true} - validateFields={["license.durationTo"]} /> - {({ input: { value } }) => { + {({ input: { value: licenseType } }) => { return ( <> true} /> true} /> } fullWidth - disabled={value === "NO_LICENSE"} - required={damConfig.requireLicense} + disabled={licenseType === "NO_LICENSE"} > } - disabled={value === "NO_LICENSE"} - required={damConfig.requireLicense} + validateFields={["license.durationTo"]} + disabled={licenseType === "NO_LICENSE"} + validate={requiredValidator} shouldShowError={() => true} /> } validate={(value: Date | undefined, allValues) => { - if (value && allValues && value < (allValues as EditFileFormValues).license?.durationFrom) { + const requiredError = requiredValidator(value, allValues); + if (requiredError) { + return requiredError; + } + + const durationFrom = (allValues as EditFileFormValues).license?.durationFrom; + if (value && durationFrom && value < durationFrom) { return ( true} /> From 60a183922d19209325803c66b35bbe03e2074de7 Mon Sep 17 00:00:00 2001 From: jennyvivid <148231586+jennyvivid@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:57:40 +0100 Subject: [PATCH 3/5] Add `Alert` component (#1371) --------- Co-authored-by: Ricky James Smith Co-authored-by: Thomas Dax Co-authored-by: Johannes Obermair <48853629+johnnyomair@users.noreply.github.com> --- .changeset/smart-weeks-behave.md | 23 +++ .../admin-stories/src/admin/alert/Alert.tsx | 152 ++++++++++++++++++ .../src/componentsTheme/MuiAlert.tsx | 45 ++++++ .../src/componentsTheme/getComponentsTheme.ts | 2 + packages/admin/admin/src/alert/Alert.tsx | 116 +++++++++++++ packages/admin/admin/src/index.ts | 1 + packages/eslint-config/nextjs.js | 5 + 7 files changed, 344 insertions(+) create mode 100644 .changeset/smart-weeks-behave.md create mode 100644 packages/admin/admin-stories/src/admin/alert/Alert.tsx create mode 100644 packages/admin/admin-theme/src/componentsTheme/MuiAlert.tsx create mode 100644 packages/admin/admin/src/alert/Alert.tsx diff --git a/.changeset/smart-weeks-behave.md b/.changeset/smart-weeks-behave.md new file mode 100644 index 0000000000..c341c49c13 --- /dev/null +++ b/.changeset/smart-weeks-behave.md @@ -0,0 +1,23 @@ +--- +"@comet/admin": minor +--- + +Add `Alert` component + +**Example:** + +```tsx +import { Alert, OkayButton, SaveButton } from "@comet/admin"; + +}> + Action Text + + } +> + Notification Text + +``` \ No newline at end of file diff --git a/packages/admin/admin-stories/src/admin/alert/Alert.tsx b/packages/admin/admin-stories/src/admin/alert/Alert.tsx new file mode 100644 index 0000000000..fc46057202 --- /dev/null +++ b/packages/admin/admin-stories/src/admin/alert/Alert.tsx @@ -0,0 +1,152 @@ +import { Alert, OkayButton, SaveButton } from "@comet/admin"; +import { ArrowRight } from "@comet/admin-icons"; +import { Button, Card, CardContent, Typography } from "@mui/material"; +import { Stack } from "@mui/system"; +import { storiesOf } from "@storybook/react"; +import React from "react"; + +function Story() { + return ( +
+ + + + With Title + + + }> + Action Text + + } + onClose={() => { + // noop + }} + > + Notification Text + + }> + Action Text + + } + onClose={() => { + // noop + }} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vel vehicula est. Nunc congue velit sem, ac porttitor + massa semper nec. Proin quis volutpat magna. Mauris eget libero et mi imperdiet ultrices. Donec eget interdum odio. + Maecenas blandit ipsum et eros tempus porttitor. Aliquam erat volutpat. + + }> + Action Text + + } + onClose={() => { + // noop + }} + > + Notification Text + + { + // noop + }} + > + Notification Text + + + + + + + + + Without Title + + + { + // noop + }} + > + Notification Text + + { + // noop + }} + > + Notification Text + + { + // noop + }} + > + Notification Text + + }> + Action Text + + } + onClose={() => { + // noop + }} + > + Notification Text + + + + + + + + + Without Close Button + + Notification Text + + + Notification Text + + }> + Action Text + + } + > + Notification Text + + Other Actions + }> + Text + + } /> + + + +
+ ); +} + +storiesOf("@comet/admin/alert/Alert", module).add("Alerts", () => ); diff --git a/packages/admin/admin-theme/src/componentsTheme/MuiAlert.tsx b/packages/admin/admin-theme/src/componentsTheme/MuiAlert.tsx new file mode 100644 index 0000000000..17710c670b --- /dev/null +++ b/packages/admin/admin-theme/src/componentsTheme/MuiAlert.tsx @@ -0,0 +1,45 @@ +import { Check, Error, Info, Warning } from "@comet/admin-icons"; +import React from "react"; + +import { mergeOverrideStyles } from "../utils/mergeOverrideStyles"; +import { GetMuiComponentTheme } from "./getComponentsTheme"; + +export const getMuiAlert: GetMuiComponentTheme<"MuiAlert"> = (component, { palette }) => ({ + ...component, + defaultProps: { + variant: "outlined", + + iconMapping: { + info: , + success: , + error: , + warning: , + }, + ...component?.defaultProps, + }, + styleOverrides: mergeOverrideStyles<"MuiAlert">(component?.styleOverrides, { + root: {}, + outlined: { + borderLeftWidth: 5, + backgroundColor: "#fff", + borderRadius: 4, + color: palette.grey[800], + }, + outlinedSuccess: { + borderColor: "#14CC33", + }, + outlinedInfo: { + borderColor: "#29B6F6", + }, + outlinedWarning: { + borderColor: "#FFB31A", + }, + outlinedError: { + borderColor: "#D11700", + }, + icon: { + marginRight: 0, + padding: 0, + }, + }), +}); diff --git a/packages/admin/admin-theme/src/componentsTheme/getComponentsTheme.ts b/packages/admin/admin-theme/src/componentsTheme/getComponentsTheme.ts index cbb9771a1a..d69840a9b2 100644 --- a/packages/admin/admin-theme/src/componentsTheme/getComponentsTheme.ts +++ b/packages/admin/admin-theme/src/componentsTheme/getComponentsTheme.ts @@ -6,6 +6,7 @@ import { ZIndex } from "@mui/material/styles/zIndex"; import { Spacing } from "@mui/system"; import { getMuiAccordion } from "./MuiAccordion"; +import { getMuiAlert } from "./MuiAlert"; import { getMuiAppBar } from "./MuiAppBar"; import { getMuiAutocomplete } from "./MuiAutocomplete"; import { getMuiButton } from "./MuiButton"; @@ -101,4 +102,5 @@ export const getComponentsTheme = (components: Components, themeData: ThemeData) MuiToggleButtonGroup: getMuiToggleButtonGroup(components.MuiToggleButtonGroup, themeData), MuiTooltip: getMuiTooltip(components.MuiTooltip, themeData), MuiTypography: getMuiTypography(components.MuiTypography, themeData), + MuiAlert: getMuiAlert(components.MuiAlert, themeData), }); diff --git a/packages/admin/admin/src/alert/Alert.tsx b/packages/admin/admin/src/alert/Alert.tsx new file mode 100644 index 0000000000..ec9fff05de --- /dev/null +++ b/packages/admin/admin/src/alert/Alert.tsx @@ -0,0 +1,116 @@ +import { Close } from "@comet/admin-icons"; +import { Alert as MuiAlert, AlertTitle, buttonClasses, IconButton, Theme, Typography } from "@mui/material"; +import { createStyles, WithStyles, withStyles } from "@mui/styles"; +import clsx from "clsx"; +import * as React from "react"; + +export interface AlertProps { + severity?: "info" | "warning" | "error" | "success"; + title?: React.ReactNode; + children?: React.ReactNode; + onClose?: () => void; + action?: React.ReactNode; +} + +export type AlertClassKey = "root" | "message" | "title" | "text" | "action" | "closeIcon" | "hasTitle"; + +const styles = (theme: Theme) => + createStyles({ + root: { + display: "flex", + alignItems: "center", + backgroundColor: theme.palette.background.paper, + borderRadius: 4, + boxShadow: theme.shadows[2], + position: "relative", + padding: theme.spacing(2, "12px", 2, 4), + minHeight: 40, // to ensure consistent height for the content, regardless of the presence of a button or close icon, in order to set the outer padding correctly + }, + message: { + display: "flex", + alignItems: "center", + flexGrow: 1, + padding: 0, + paddingLeft: theme.spacing(2), + marginBottom: 0, + }, + title: { + fontWeight: 600, + marginBottom: theme.spacing(1), + }, + text: { + flexGrow: 1, + marginRight: theme.spacing(4), + }, + action: {}, + closeIcon: {}, + hasTitle: { + alignItems: "flex-start", + + [`& .${buttonClasses.text}`]: { + marginLeft: -15, + }, + + "& $action": { + marginTop: theme.spacing(2), + }, + + "& $closeIcon": { + position: "absolute", + right: 10, + top: 10, + }, + "& $message": { + flexDirection: "column", + alignItems: "flex-start", + }, + "&$root": { + paddingBottom: "6px", + paddingTop: theme.spacing(4), + }, + }, + }); + +function Alert({ severity = "info", title, children, classes, onClose, action }: AlertProps & WithStyles): React.ReactElement { + return ( + + {Boolean(title) && {title}} + + {children} + +
{action}
+ {onClose && ( + + + + )} +
+ ); +} + +const AdminComponentWithStyles = withStyles(styles, { name: "CometAdminAlert" })(Alert); + +export { AdminComponentWithStyles as Alert }; + +declare module "@mui/material/styles" { + interface ComponentsPropsList { + CometAdminAlert: AlertProps; + } + + interface ComponentNameToClassKey { + CometAdminAlert: AlertClassKey; + } + + interface Components { + CometAdminAlert?: { + defaultProps?: ComponentsPropsList["CometAdminAlert"]; + styleOverrides?: ComponentNameToClassKey["CometAdminAlert"]; + }; + } +} diff --git a/packages/admin/admin/src/index.ts b/packages/admin/admin/src/index.ts index efe9813c84..d8e838b870 100644 --- a/packages/admin/admin/src/index.ts +++ b/packages/admin/admin/src/index.ts @@ -1,3 +1,4 @@ +export { Alert, AlertClassKey, AlertProps } from "./alert/Alert"; export { useFocusAwarePolling } from "./apollo/useFocusAwarePolling"; export { AppHeader, AppHeaderClassKey } from "./appHeader/AppHeader"; export { AppHeaderButton, AppHeaderButtonProps } from "./appHeader/button/AppHeaderButton"; diff --git a/packages/eslint-config/nextjs.js b/packages/eslint-config/nextjs.js index a0c3d0ca86..fa79c4338f 100644 --- a/packages/eslint-config/nextjs.js +++ b/packages/eslint-config/nextjs.js @@ -25,6 +25,11 @@ module.exports = { importNames: ["default"], message: "Please use Image from @comet/cms-site instead", }, + { + name: "@mui/material", + importNames: ["Alert"], + message: "Please use Alert from @comet/admin instead", + }, ], }, ], From b658e5b2532316b3b92a161360c6defdebc255c2 Mon Sep 17 00:00:00 2001 From: Thomas Dax Date: Thu, 21 Dec 2023 17:23:15 +0100 Subject: [PATCH 4/5] Fix fixtures (#1515) ## Problem: Our fixtures are currently broken. You always get this error when executing them: Bildschirmfoto 2023-12-14 um 17 02 52 The problem is that a required `userGroup` field is added to `PageTreeNode` in Demo: https://github.com/vivid-planet/comet/blob/99e0c57cc8ef542befd74d5b8ad9cf71058570e1/demo/api/src/page-tree/entities/page-tree-node.entity.ts#L26-L28 https://github.com/vivid-planet/comet/blob/1c098e4d0f23946c0fd543856c8f0aa897b83b82/demo/api/src/page-tree/dto/page-tree-node.input.ts#L7-L12 We don't provide a userGroup in the fixtures and it didn't strike because the typing of `PageTreeService.createNode()` is wrong. The input is typed with `PageTreeNodeBaseCreateInput` https://github.com/vivid-planet/comet/blob/b73eb4c34c70c694fc8b267ce330af5959c50e7b/packages/api/cms-api/src/page-tree/page-tree.service.ts#L33 but the actual input type can be defined in the application and is passed to the resolver via a factory: https://github.com/vivid-planet/comet/blob/46bced34cbb9ec02de6dd462bd9111a6be7898b7/packages/api/cms-api/src/page-tree/createPageTreeResolver.ts#L35 ### -> So actually the typing in the `PageTreeService` is wrong and we need to fix that I now circumvented this by using ts-ignore. But I think we need a solution to get the typing right. I'm however not sure what the best way to do this is. --- demo/api/src/db/fixtures/fixtures.console.ts | 22 ++++++++++++++++++- .../many-images-test-page.generator.ts | 2 ++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/demo/api/src/db/fixtures/fixtures.console.ts b/demo/api/src/db/fixtures/fixtures.console.ts index 667c0f56e9..23d4691f92 100644 --- a/demo/api/src/db/fixtures/fixtures.console.ts +++ b/demo/api/src/db/fixtures/fixtures.console.ts @@ -19,6 +19,7 @@ import { PageTreeNodeCategory } from "@src/page-tree/page-tree-node-category"; import { PageContentBlock } from "@src/pages/blocks/PageContentBlock"; import { PageInput } from "@src/pages/dto/page.input"; import { Page } from "@src/pages/entities/page.entity"; +import { UserGroup } from "@src/user-groups/user-group"; import faker from "faker"; import { Command, Console } from "nestjs-console"; import slugify from "slugify"; @@ -104,6 +105,8 @@ export class FixturesConsole { id: attachedDocumentIds[0], type: "Page", }, + // @ts-expect-error Typing of PageTreeService is wrong https://github.com/vivid-planet/comet/pull/1515#issue-2042001589 + userGroup: UserGroup.All, }, PageTreeNodeCategory.MainNavigation, scope, @@ -113,7 +116,14 @@ export class FixturesConsole { await this.pageTreeService.updateNodeVisibility(node.id, PageTreeNodeVisibility.Published); node = await this.pageTreeService.createNode( - { name: "Sub", slug: "sub", parentId: node.id, attachedDocument: { id: attachedDocumentIds[1], type: "Page" } }, + { + name: "Sub", + slug: "sub", + parentId: node.id, + attachedDocument: { id: attachedDocumentIds[1], type: "Page" }, + // @ts-expect-error Typing of PageTreeService is wrong https://github.com/vivid-planet/comet/pull/1515#issue-2042001589 + userGroup: UserGroup.All, + }, PageTreeNodeCategory.MainNavigation, scope, ); @@ -129,6 +139,8 @@ export class FixturesConsole { id: attachedDocumentIds[2], type: "Page", }, + // @ts-expect-error Typing of PageTreeService is wrong https://github.com/vivid-planet/comet/pull/1515#issue-2042001589 + userGroup: UserGroup.All, }, PageTreeNodeCategory.MainNavigation, scope, @@ -144,6 +156,8 @@ export class FixturesConsole { attachedDocument: { type: "Page", }, + // @ts-expect-error Typing of PageTreeService is wrong https://github.com/vivid-planet/comet/pull/1515#issue-2042001589 + userGroup: UserGroup.All, }, PageTreeNodeCategory.MainNavigation, scope, @@ -160,6 +174,8 @@ export class FixturesConsole { id: attachedDocumentIds[3], type: "Link", }, + // @ts-expect-error Typing of PageTreeService is wrong https://github.com/vivid-planet/comet/pull/1515#issue-2042001589 + userGroup: UserGroup.All, }, PageTreeNodeCategory.MainNavigation, scope, @@ -176,6 +192,8 @@ export class FixturesConsole { id: attachedDocumentIds[4], type: "Page", }, + // @ts-expect-error Typing of PageTreeService is wrong https://github.com/vivid-planet/comet/pull/1515#issue-2042001589 + userGroup: UserGroup.All, }, PageTreeNodeCategory.MainNavigation, scope, @@ -226,6 +244,8 @@ export class FixturesConsole { slug: slugify(name), parentId: level > 0 ? faker.random.arrayElement(pages[level - 1]).id : undefined, attachedDocument: { type: "Page" }, + // @ts-expect-error Typing of PageTreeService is wrong https://github.com/vivid-planet/comet/pull/1515#issue-2042001589 + userGroup: UserGroup.All, }, PageTreeNodeCategory.MainNavigation, { diff --git a/demo/api/src/db/fixtures/generators/many-images-test-page.generator.ts b/demo/api/src/db/fixtures/generators/many-images-test-page.generator.ts index dd5077d3cc..6cdc3f3fb0 100644 --- a/demo/api/src/db/fixtures/generators/many-images-test-page.generator.ts +++ b/demo/api/src/db/fixtures/generators/many-images-test-page.generator.ts @@ -49,6 +49,8 @@ export class ManyImagesTestPageGenerator { id: uuidDocument, type: "Page", }, + // @ts-expect-error Typing of PageTreeService is wrong https://github.com/vivid-planet/comet/pull/1515#issue-2042001589 + userGroup: UserGroup.All, }, PageTreeNodeCategory.MainNavigation, scope, From 02009264e3006d533d7146044e7abf2b60d8b5d9 Mon Sep 17 00:00:00 2001 From: Thomas Dax Date: Fri, 22 Dec 2023 11:03:11 +0100 Subject: [PATCH 5/5] Fix conflicts --- packages/admin/cms-admin/src/dam/FileForm/EditFile.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/admin/cms-admin/src/dam/FileForm/EditFile.tsx b/packages/admin/cms-admin/src/dam/FileForm/EditFile.tsx index b31a6a847c..4523b0d61a 100644 --- a/packages/admin/cms-admin/src/dam/FileForm/EditFile.tsx +++ b/packages/admin/cms-admin/src/dam/FileForm/EditFile.tsx @@ -191,14 +191,6 @@ const EditFileInner = ({ file, id }: EditFileInnerProps) => { }, }} initialValuesEqual={(prevValues, newValues) => isEqual(prevValues, newValues)} -<<<<<<< HEAD - validateOnBlur -======= - onAfterSubmit={() => { - // override default onAfterSubmit because default is stackApi.goBack() - // https://github.com/vivid-planet/comet/blob/master/packages/admin/src/FinalForm.tsx#L53 - }} ->>>>>>> main > {({ pristine, hasValidationErrors, submitting, handleSubmit }) => ( <>