From 61c3eb51fd5ce266394e5b0e771d722f62799cfa Mon Sep 17 00:00:00 2001 From: dominik-zeglen Date: Wed, 11 Mar 2020 14:03:31 +0100 Subject: [PATCH] Use error codes in navigation section --- .../MenuCreateDialog/MenuCreateDialog.tsx | 13 +++++---- .../MenuDetailsPage/MenuDetailsPage.tsx | 4 +++ .../MenuItemDialog/MenuItemDialog.tsx | 27 +++++++++--------- .../MenuProperties/MenuProperties.tsx | 9 ++++++ src/navigation/views/MenuDetails/index.tsx | 5 ++++ .../stories/navigation/MenuCreateDialog.tsx | 11 ++++++-- .../stories/navigation/MenuDetailsPage.tsx | 12 ++++++++ .../stories/navigation/MenuItemDialog.tsx | 8 ++++-- src/utils/errors/menu.ts | 28 +++++++++++++++++++ 9 files changed, 95 insertions(+), 22 deletions(-) create mode 100644 src/utils/errors/menu.ts diff --git a/src/navigation/components/MenuCreateDialog/MenuCreateDialog.tsx b/src/navigation/components/MenuCreateDialog/MenuCreateDialog.tsx index c9e2ea9f8..41c0f9f25 100644 --- a/src/navigation/components/MenuCreateDialog/MenuCreateDialog.tsx +++ b/src/navigation/components/MenuCreateDialog/MenuCreateDialog.tsx @@ -12,8 +12,9 @@ import ConfirmButton, { } from "@saleor/components/ConfirmButton"; import Form from "@saleor/components/Form"; import { buttonMessages } from "@saleor/intl"; -import { getFieldError } from "@saleor/utils/errors"; -import { UserError } from "@saleor/types"; +import { MenuErrorFragment } from "@saleor/navigation/types/MenuErrorFragment"; +import { getFormErrors } from "@saleor/utils/errors"; +import getMenuErrorMessage from "@saleor/utils/errors/menu"; export interface MenuCreateDialogFormData { name: string; @@ -22,7 +23,7 @@ export interface MenuCreateDialogFormData { export interface MenuCreateDialogProps { confirmButtonState: ConfirmButtonTransitionState; disabled: boolean; - errors: UserError[]; + errors: MenuErrorFragment[]; open: boolean; onClose: () => void; onConfirm: (data: MenuCreateDialogFormData) => void; @@ -42,6 +43,8 @@ const MenuCreateDialog: React.FC = ({ }) => { const intl = useIntl(); + const formErrors = getFormErrors(["name"], errors); + return ( @@ -57,9 +60,9 @@ const MenuCreateDialog: React.FC = ({ void; onDelete: () => void; @@ -39,6 +41,7 @@ export interface MenuDetailsPageProps { const MenuDetailsPage: React.FC = ({ disabled, + errors, menu, saveButtonState, onBack, @@ -98,6 +101,7 @@ const MenuDetailsPage: React.FC = ({ diff --git a/src/navigation/components/MenuItemDialog/MenuItemDialog.tsx b/src/navigation/components/MenuItemDialog/MenuItemDialog.tsx index 9ee41d517..93f31776d 100644 --- a/src/navigation/components/MenuItemDialog/MenuItemDialog.tsx +++ b/src/navigation/components/MenuItemDialog/MenuItemDialog.tsx @@ -21,9 +21,10 @@ import { buttonMessages, sectionNames } from "@saleor/intl"; import { SearchCategories_search_edges_node } from "@saleor/searches/types/SearchCategories"; import { SearchCollections_search_edges_node } from "@saleor/searches/types/SearchCollections"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; -import { UserError } from "@saleor/types"; -import { getErrors, getFieldError } from "@saleor/utils/errors"; import { getMenuItemByValue, IMenu } from "@saleor/utils/menu"; +import { MenuErrorFragment } from "@saleor/navigation/types/MenuErrorFragment"; +import { getFieldError, getFormErrors } from "@saleor/utils/errors"; +import getMenuErrorMessage from "@saleor/utils/errors/menu"; export type MenuItemType = "category" | "collection" | "link" | "page"; export interface MenuItemData { @@ -38,7 +39,7 @@ export interface MenuItemDialogFormData extends MenuItemData { export interface MenuItemDialogProps { confirmButtonState: ConfirmButtonTransitionState; disabled: boolean; - errors: UserError[]; + errors: MenuErrorFragment[]; initial?: MenuItemDialogFormData; initialDisplayValue?: string; loading: boolean; @@ -112,7 +113,11 @@ const MenuItemDialog: React.FC = ({ initialDisplayValue ]); - const mutationErrors = getErrors(errors); + const mutationErrors = errors.filter(err => err.field === null); + const formErrors = getFormErrors(["name"], errors); + const idError = ["category", "collection", "page", "url"] + .map(field => getFieldError(errors, field)) + .reduce((acc, err) => acc || err); let options: IMenu = []; @@ -208,10 +213,6 @@ const MenuItemDialog: React.FC = ({ const handleSubmit = () => onSubmit(data); - const idError = ["category", "collection", "page", "url"] - .map(field => getFieldError(errors, field)) - .reduce((acc, err) => acc || err); - return ( = ({ })) } name="name" - error={!!getFieldError(errors, "name")} - helperText={getFieldError(errors, "name")?.message} + error={!!formErrors.name} + helperText={getMenuErrorMessage(formErrors.name, intl)} /> = ({ loading={loading} options={options} error={!!idError} - helperText={idError?.message} + helperText={getMenuErrorMessage(idError, intl)} placeholder={intl.formatMessage({ defaultMessage: "Start typing to begin search...", id: "menuItemDialogLinkPlaceholder" @@ -280,8 +281,8 @@ const MenuItemDialog: React.FC = ({ <> {mutationErrors.map(err => ( - - {err} + + {getMenuErrorMessage(err, intl)} ))} diff --git a/src/navigation/components/MenuProperties/MenuProperties.tsx b/src/navigation/components/MenuProperties/MenuProperties.tsx index cb84dea90..d798a4cad 100644 --- a/src/navigation/components/MenuProperties/MenuProperties.tsx +++ b/src/navigation/components/MenuProperties/MenuProperties.tsx @@ -6,21 +6,28 @@ import { useIntl } from "react-intl"; import CardTitle from "@saleor/components/CardTitle"; import { commonMessages } from "@saleor/intl"; +import { MenuErrorFragment } from "@saleor/navigation/types/MenuErrorFragment"; +import { getFormErrors } from "@saleor/utils/errors"; +import getMenuErrorMessage from "@saleor/utils/errors/menu"; import { MenuDetailsFormData } from "../MenuDetailsPage"; export interface MenuPropertiesProps { data: MenuDetailsFormData; disabled: boolean; + errors: MenuErrorFragment[]; onChange: (event: React.ChangeEvent) => void; } const MenuProperties: React.FC = ({ data, disabled, + errors, onChange }) => { const intl = useIntl(); + const formErrors = getFormErrors(["name"], errors); + return ( = ({ diff --git a/src/navigation/views/MenuDetails/index.tsx b/src/navigation/views/MenuDetails/index.tsx index 80b655d48..52d3d7ddd 100644 --- a/src/navigation/views/MenuDetails/index.tsx +++ b/src/navigation/views/MenuDetails/index.tsx @@ -169,6 +169,11 @@ const MenuDetails: React.FC = ({ id, params }) => { <> data.menu)} onBack={() => navigate(menuListUrl())} onDelete={() => diff --git a/src/storybook/stories/navigation/MenuCreateDialog.tsx b/src/storybook/stories/navigation/MenuCreateDialog.tsx index 521bee513..65bb9c896 100644 --- a/src/storybook/stories/navigation/MenuCreateDialog.tsx +++ b/src/storybook/stories/navigation/MenuCreateDialog.tsx @@ -1,7 +1,7 @@ import { storiesOf } from "@storybook/react"; import React from "react"; -import { formError } from "@saleor/storybook/misc"; +import { MenuErrorCode } from "@saleor/types/globalTypes"; import MenuCreateDialog, { MenuCreateDialogProps } from "../../../navigation/components/MenuCreateDialog"; @@ -23,5 +23,12 @@ storiesOf("Navigation / Menu create", module) )) .add("form errors", () => ( - + ({ + __typename: "MenuError", + code: MenuErrorCode.INVALID, + field + }))} + /> )); diff --git a/src/storybook/stories/navigation/MenuDetailsPage.tsx b/src/storybook/stories/navigation/MenuDetailsPage.tsx index 57c8b2cb6..333174a15 100644 --- a/src/storybook/stories/navigation/MenuDetailsPage.tsx +++ b/src/storybook/stories/navigation/MenuDetailsPage.tsx @@ -1,6 +1,7 @@ import { storiesOf } from "@storybook/react"; import React from "react"; +import { MenuErrorCode } from "@saleor/types/globalTypes"; import MenuDetailsPage, { MenuDetailsPageProps } from "../../../navigation/components/MenuDetailsPage"; @@ -9,6 +10,7 @@ import Decorator from "../../Decorator"; const props: MenuDetailsPageProps = { disabled: false, + errors: [], menu, onBack: () => undefined, onDelete: () => undefined, @@ -33,4 +35,14 @@ storiesOf("Views / Navigation / Menu details", module) items: [] }} /> + )) + .add("form errors", () => ( + ({ + __typename: "MenuError", + code: MenuErrorCode.INVALID, + field + }))} + /> )); diff --git a/src/storybook/stories/navigation/MenuItemDialog.tsx b/src/storybook/stories/navigation/MenuItemDialog.tsx index 1c024e945..a380e08e5 100644 --- a/src/storybook/stories/navigation/MenuItemDialog.tsx +++ b/src/storybook/stories/navigation/MenuItemDialog.tsx @@ -1,7 +1,7 @@ import { storiesOf } from "@storybook/react"; import React from "react"; -import { formError } from "@saleor/storybook/misc"; +import { MenuErrorCode } from "@saleor/types/globalTypes"; import MenuItemDialog, { MenuItemDialogProps } from "../../../navigation/components/MenuItemDialog"; @@ -48,6 +48,10 @@ storiesOf("Navigation / Menu item", module) .add("errors", () => ( ({ + __typename: "MenuError", + code: MenuErrorCode.INVALID, + field + }))} /> )); diff --git a/src/utils/errors/menu.ts b/src/utils/errors/menu.ts new file mode 100644 index 000000000..1793282bf --- /dev/null +++ b/src/utils/errors/menu.ts @@ -0,0 +1,28 @@ +import { IntlShape } from "react-intl"; + +import { MenuErrorCode } from "@saleor/types/globalTypes"; +import { commonMessages } from "@saleor/intl"; +import { MenuErrorFragment } from "@saleor/navigation/types/MenuErrorFragment"; +import commonErrorMessages from "./common"; + +function getMenuErrorMessage( + err: Omit | undefined, + intl: IntlShape +): string { + if (err) { + switch (err.code) { + case MenuErrorCode.GRAPHQL_ERROR: + return intl.formatMessage(commonErrorMessages.graphqlError); + case MenuErrorCode.REQUIRED: + return intl.formatMessage(commonMessages.requiredField); + case MenuErrorCode.INVALID: + return intl.formatMessage(commonErrorMessages.invalid); + default: + return intl.formatMessage(commonErrorMessages.unknownError); + } + } + + return undefined; +} + +export default getMenuErrorMessage;