diff --git a/src/collections/components/CollectionCreatePage/CollectionCreatePage.tsx b/src/collections/components/CollectionCreatePage/CollectionCreatePage.tsx index c7680bbcc..c6a3acabb 100644 --- a/src/collections/components/CollectionCreatePage/CollectionCreatePage.tsx +++ b/src/collections/components/CollectionCreatePage/CollectionCreatePage.tsx @@ -17,7 +17,7 @@ import SeoForm from "@saleor/components/SeoForm"; import VisibilityCard from "@saleor/components/VisibilityCard"; import useDateLocalize from "@saleor/hooks/useDateLocalize"; import { commonMessages, sectionNames } from "@saleor/intl"; -import { UserError } from "../../../types"; +import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment"; import CollectionDetails from "../CollectionDetails/CollectionDetails"; import { CollectionImage } from "../CollectionImage/CollectionImage"; @@ -37,7 +37,7 @@ export interface CollectionCreatePageFormData { export interface CollectionCreatePageProps { disabled: boolean; - errors: UserError[]; + errors: ProductErrorFragment[]; saveButtonBarState: ConfirmButtonTransitionState; onBack: () => void; onSubmit: (data: CollectionCreatePageFormData) => void; diff --git a/src/collections/components/CollectionDetails/CollectionDetails.tsx b/src/collections/components/CollectionDetails/CollectionDetails.tsx index 5c219335c..c63bc1dea 100644 --- a/src/collections/components/CollectionDetails/CollectionDetails.tsx +++ b/src/collections/components/CollectionDetails/CollectionDetails.tsx @@ -10,8 +10,8 @@ import FormSpacer from "@saleor/components/FormSpacer"; import RichTextEditor from "@saleor/components/RichTextEditor"; import { commonMessages } from "@saleor/intl"; import { maybe } from "@saleor/misc"; -import { UserError } from "@saleor/types"; -import { getFieldError } from "@saleor/utils/errors"; +import { getProductErrorMessage, getFormErrors } from "@saleor/utils/errors"; +import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment"; import { CollectionDetails_collection } from "../../types/CollectionDetails"; export interface CollectionDetailsProps { @@ -21,7 +21,7 @@ export interface CollectionDetailsProps { name: string; }; disabled: boolean; - errors: UserError[]; + errors: ProductErrorFragment[]; onChange: (event: React.ChangeEvent) => void; } @@ -34,6 +34,8 @@ const CollectionDetails: React.FC = ({ }) => { const intl = useIntl(); + const formErrors = getFormErrors(["name", "descriptionJson"], errors); + return ( = ({ disabled={disabled} value={data.name} onChange={onChange} - error={!!getFieldError(errors, "name")} - helperText={getFieldError(errors, "name")?.message} + error={!!formErrors.name} + helperText={getProductErrorMessage(formErrors.name, intl)} fullWidth /> JSON.parse(collection.descriptionJson))} label={intl.formatMessage(commonMessages.description)} name="description" diff --git a/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx b/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx index 3d81c31e4..106ba3463 100644 --- a/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx +++ b/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx @@ -17,8 +17,9 @@ import SeoForm from "@saleor/components/SeoForm"; import VisibilityCard from "@saleor/components/VisibilityCard"; import useDateLocalize from "@saleor/hooks/useDateLocalize"; import { sectionNames } from "@saleor/intl"; +import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment"; import { maybe } from "../../../misc"; -import { ListActions, PageListProps, UserError } from "../../../types"; +import { ListActions, PageListProps } from "../../../types"; import { CollectionDetails_collection } from "../../types/CollectionDetails"; import CollectionDetails from "../CollectionDetails/CollectionDetails"; import { CollectionImage } from "../CollectionImage/CollectionImage"; @@ -37,7 +38,7 @@ export interface CollectionDetailsPageFormData { export interface CollectionDetailsPageProps extends PageListProps, ListActions { collection: CollectionDetails_collection; - errors: UserError[]; + errors: ProductErrorFragment[]; isFeatured: boolean; saveButtonBarState: ConfirmButtonTransitionState; onBack: () => void; diff --git a/src/collections/mutations.ts b/src/collections/mutations.ts index 94623492f..b339d1a04 100644 --- a/src/collections/mutations.ts +++ b/src/collections/mutations.ts @@ -1,5 +1,6 @@ import gql from "graphql-tag"; +import { productErrorFragment } from "@saleor/attributes/mutations"; import { TypedMutation } from "../mutations"; import { collectionDetailsFragment, @@ -38,17 +39,24 @@ import { UnassignCollectionProductVariables } from "./types/UnassignCollectionProduct"; +export const ShopErrorFragment = gql` + fragment ShopErrorFragment on ShopError { + code + field + } +`; + const collectionUpdate = gql` ${collectionDetailsFragment} + ${productErrorFragment} mutation CollectionUpdate($id: ID!, $input: CollectionInput!) { collectionUpdate(id: $id, input: $input) { - errors { - field - message - } collection { ...CollectionDetailsFragment } + errors: productErrors { + ...ProductErrorFragment + } } } `; @@ -59,15 +67,16 @@ export const TypedCollectionUpdateMutation = TypedMutation< const collectionUpdateWithHomepage = gql` ${collectionDetailsFragment} + ${productErrorFragment} + ${ShopErrorFragment} mutation CollectionUpdateWithHomepage( $id: ID! $input: CollectionInput! $homepageId: ID ) { homepageCollectionUpdate(collection: $homepageId) { - errors { - field - message + errors: shopErrors { + ...ShopErrorFragment } shop { homepageCollection { @@ -76,13 +85,12 @@ const collectionUpdateWithHomepage = gql` } } collectionUpdate(id: $id, input: $input) { - errors { - field - message - } collection { ...CollectionDetailsFragment } + errors: productErrors { + ...ProductErrorFragment + } } } `; @@ -93,6 +101,7 @@ export const TypedCollectionUpdateWithHomepageMutation = TypedMutation< const assignCollectionProduct = gql` ${collectionProductFragment} + ${productErrorFragment} mutation CollectionAssignProduct( $collectionId: ID! $productIds: [ID!]! @@ -102,10 +111,6 @@ const assignCollectionProduct = gql` $before: String ) { collectionAddProducts(collectionId: $collectionId, products: $productIds) { - errors { - field - message - } collection { id products(first: $first, after: $after, before: $before, last: $last) { @@ -122,6 +127,9 @@ const assignCollectionProduct = gql` } } } + errors: productErrors { + ...ProductErrorFragment + } } } `; @@ -132,15 +140,15 @@ export const TypedCollectionAssignProductMutation = TypedMutation< const createCollection = gql` ${collectionDetailsFragment} + ${productErrorFragment} mutation CreateCollection($input: CollectionCreateInput!) { collectionCreate(input: $input) { - errors { - field - message - } collection { ...CollectionDetailsFragment } + errors: productErrors { + ...ProductErrorFragment + } } } `; @@ -150,11 +158,11 @@ export const TypedCollectionCreateMutation = TypedMutation< >(createCollection); const removeCollection = gql` + ${productErrorFragment} mutation RemoveCollection($id: ID!) { collectionDelete(id: $id) { - errors { - field - message + errors: productErrors { + ...ProductErrorFragment } } } @@ -165,6 +173,7 @@ export const TypedCollectionRemoveMutation = TypedMutation< >(removeCollection); const unassignCollectionProduct = gql` + ${productErrorFragment} mutation UnassignCollectionProduct( $collectionId: ID! $productIds: [ID]! @@ -177,10 +186,6 @@ const unassignCollectionProduct = gql` collectionId: $collectionId products: $productIds ) { - errors { - field - message - } collection { id products(first: $first, after: $after, before: $before, last: $last) { @@ -206,6 +211,9 @@ const unassignCollectionProduct = gql` } } } + errors: productErrors { + ...ProductErrorFragment + } } } `; @@ -215,11 +223,11 @@ export const TypedUnassignCollectionProductMutation = TypedMutation< >(unassignCollectionProduct); const collectionBulkDelete = gql` + ${productErrorFragment} mutation CollectionBulkDelete($ids: [ID]!) { collectionBulkDelete(ids: $ids) { - errors { - field - message + errors: productErrors { + ...ProductErrorFragment } } } @@ -230,11 +238,11 @@ export const TypedCollectionBulkDelete = TypedMutation< >(collectionBulkDelete); const collectionBulkPublish = gql` + ${productErrorFragment} mutation CollectionBulkPublish($ids: [ID]!, $isPublished: Boolean!) { collectionBulkPublish(ids: $ids, isPublished: $isPublished) { - errors { - field - message + errors: productErrors { + ...ProductErrorFragment } } } diff --git a/src/collections/types/CollectionAssignProduct.ts b/src/collections/types/CollectionAssignProduct.ts index 0fbfa3103..a2f5dce38 100644 --- a/src/collections/types/CollectionAssignProduct.ts +++ b/src/collections/types/CollectionAssignProduct.ts @@ -2,16 +2,12 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. +import { ProductErrorCode } from "./../../types/globalTypes"; + // ==================================================== // GraphQL mutation operation: CollectionAssignProduct // ==================================================== -export interface CollectionAssignProduct_collectionAddProducts_errors { - __typename: "Error"; - field: string | null; - message: string | null; -} - export interface CollectionAssignProduct_collectionAddProducts_collection_products_edges_node_productType { __typename: "ProductType"; id: string; @@ -57,10 +53,16 @@ export interface CollectionAssignProduct_collectionAddProducts_collection { products: CollectionAssignProduct_collectionAddProducts_collection_products | null; } +export interface CollectionAssignProduct_collectionAddProducts_errors { + __typename: "ProductError"; + code: ProductErrorCode; + field: string | null; +} + export interface CollectionAssignProduct_collectionAddProducts { __typename: "CollectionAddProducts"; - errors: CollectionAssignProduct_collectionAddProducts_errors[]; collection: CollectionAssignProduct_collectionAddProducts_collection | null; + errors: CollectionAssignProduct_collectionAddProducts_errors[]; } export interface CollectionAssignProduct { diff --git a/src/collections/types/CollectionBulkDelete.ts b/src/collections/types/CollectionBulkDelete.ts index 84254bc4f..0214b943f 100644 --- a/src/collections/types/CollectionBulkDelete.ts +++ b/src/collections/types/CollectionBulkDelete.ts @@ -2,14 +2,16 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. +import { ProductErrorCode } from "./../../types/globalTypes"; + // ==================================================== // GraphQL mutation operation: CollectionBulkDelete // ==================================================== export interface CollectionBulkDelete_collectionBulkDelete_errors { - __typename: "Error"; + __typename: "ProductError"; + code: ProductErrorCode; field: string | null; - message: string | null; } export interface CollectionBulkDelete_collectionBulkDelete { diff --git a/src/collections/types/CollectionBulkPublish.ts b/src/collections/types/CollectionBulkPublish.ts index 24739b592..542a2eaa5 100644 --- a/src/collections/types/CollectionBulkPublish.ts +++ b/src/collections/types/CollectionBulkPublish.ts @@ -2,14 +2,16 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. +import { ProductErrorCode } from "./../../types/globalTypes"; + // ==================================================== // GraphQL mutation operation: CollectionBulkPublish // ==================================================== export interface CollectionBulkPublish_collectionBulkPublish_errors { - __typename: "Error"; + __typename: "ProductError"; + code: ProductErrorCode; field: string | null; - message: string | null; } export interface CollectionBulkPublish_collectionBulkPublish { diff --git a/src/collections/types/CollectionUpdate.ts b/src/collections/types/CollectionUpdate.ts index 95f216696..42f43cfd5 100644 --- a/src/collections/types/CollectionUpdate.ts +++ b/src/collections/types/CollectionUpdate.ts @@ -2,18 +2,12 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { CollectionInput } from "./../../types/globalTypes"; +import { CollectionInput, ProductErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: CollectionUpdate // ==================================================== -export interface CollectionUpdate_collectionUpdate_errors { - __typename: "Error"; - field: string | null; - message: string | null; -} - export interface CollectionUpdate_collectionUpdate_collection_backgroundImage { __typename: "Image"; alt: string | null; @@ -32,10 +26,16 @@ export interface CollectionUpdate_collectionUpdate_collection { seoTitle: string | null; } +export interface CollectionUpdate_collectionUpdate_errors { + __typename: "ProductError"; + code: ProductErrorCode; + field: string | null; +} + export interface CollectionUpdate_collectionUpdate { __typename: "CollectionUpdate"; - errors: CollectionUpdate_collectionUpdate_errors[]; collection: CollectionUpdate_collectionUpdate_collection | null; + errors: CollectionUpdate_collectionUpdate_errors[]; } export interface CollectionUpdate { diff --git a/src/collections/types/CollectionUpdateWithHomepage.ts b/src/collections/types/CollectionUpdateWithHomepage.ts index 71c2fd396..a51f43b1e 100644 --- a/src/collections/types/CollectionUpdateWithHomepage.ts +++ b/src/collections/types/CollectionUpdateWithHomepage.ts @@ -2,16 +2,16 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { CollectionInput } from "./../../types/globalTypes"; +import { CollectionInput, ShopErrorCode, ProductErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: CollectionUpdateWithHomepage // ==================================================== export interface CollectionUpdateWithHomepage_homepageCollectionUpdate_errors { - __typename: "Error"; + __typename: "ShopError"; + code: ShopErrorCode; field: string | null; - message: string | null; } export interface CollectionUpdateWithHomepage_homepageCollectionUpdate_shop_homepageCollection { @@ -30,12 +30,6 @@ export interface CollectionUpdateWithHomepage_homepageCollectionUpdate { shop: CollectionUpdateWithHomepage_homepageCollectionUpdate_shop | null; } -export interface CollectionUpdateWithHomepage_collectionUpdate_errors { - __typename: "Error"; - field: string | null; - message: string | null; -} - export interface CollectionUpdateWithHomepage_collectionUpdate_collection_backgroundImage { __typename: "Image"; alt: string | null; @@ -54,10 +48,16 @@ export interface CollectionUpdateWithHomepage_collectionUpdate_collection { seoTitle: string | null; } +export interface CollectionUpdateWithHomepage_collectionUpdate_errors { + __typename: "ProductError"; + code: ProductErrorCode; + field: string | null; +} + export interface CollectionUpdateWithHomepage_collectionUpdate { __typename: "CollectionUpdate"; - errors: CollectionUpdateWithHomepage_collectionUpdate_errors[]; collection: CollectionUpdateWithHomepage_collectionUpdate_collection | null; + errors: CollectionUpdateWithHomepage_collectionUpdate_errors[]; } export interface CollectionUpdateWithHomepage { diff --git a/src/collections/types/CreateCollection.ts b/src/collections/types/CreateCollection.ts index de5dc26e9..2a5ea5d9d 100644 --- a/src/collections/types/CreateCollection.ts +++ b/src/collections/types/CreateCollection.ts @@ -2,18 +2,12 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { CollectionCreateInput } from "./../../types/globalTypes"; +import { CollectionCreateInput, ProductErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: CreateCollection // ==================================================== -export interface CreateCollection_collectionCreate_errors { - __typename: "Error"; - field: string | null; - message: string | null; -} - export interface CreateCollection_collectionCreate_collection_backgroundImage { __typename: "Image"; alt: string | null; @@ -32,10 +26,16 @@ export interface CreateCollection_collectionCreate_collection { seoTitle: string | null; } +export interface CreateCollection_collectionCreate_errors { + __typename: "ProductError"; + code: ProductErrorCode; + field: string | null; +} + export interface CreateCollection_collectionCreate { __typename: "CollectionCreate"; - errors: CreateCollection_collectionCreate_errors[]; collection: CreateCollection_collectionCreate_collection | null; + errors: CreateCollection_collectionCreate_errors[]; } export interface CreateCollection { diff --git a/src/collections/types/RemoveCollection.ts b/src/collections/types/RemoveCollection.ts index 878406a25..588349acb 100644 --- a/src/collections/types/RemoveCollection.ts +++ b/src/collections/types/RemoveCollection.ts @@ -2,14 +2,16 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. +import { ProductErrorCode } from "./../../types/globalTypes"; + // ==================================================== // GraphQL mutation operation: RemoveCollection // ==================================================== export interface RemoveCollection_collectionDelete_errors { - __typename: "Error"; + __typename: "ProductError"; + code: ProductErrorCode; field: string | null; - message: string | null; } export interface RemoveCollection_collectionDelete { diff --git a/src/collections/types/ShopErrorFragment.ts b/src/collections/types/ShopErrorFragment.ts new file mode 100644 index 000000000..ae705f05f --- /dev/null +++ b/src/collections/types/ShopErrorFragment.ts @@ -0,0 +1,15 @@ +/* tslint:disable */ +/* eslint-disable */ +// This file was automatically generated and should not be edited. + +import { ShopErrorCode } from "./../../types/globalTypes"; + +// ==================================================== +// GraphQL fragment: ShopErrorFragment +// ==================================================== + +export interface ShopErrorFragment { + __typename: "ShopError"; + code: ShopErrorCode; + field: string | null; +} diff --git a/src/collections/types/UnassignCollectionProduct.ts b/src/collections/types/UnassignCollectionProduct.ts index 054ca97f3..7104a9c85 100644 --- a/src/collections/types/UnassignCollectionProduct.ts +++ b/src/collections/types/UnassignCollectionProduct.ts @@ -2,16 +2,12 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. +import { ProductErrorCode } from "./../../types/globalTypes"; + // ==================================================== // GraphQL mutation operation: UnassignCollectionProduct // ==================================================== -export interface UnassignCollectionProduct_collectionRemoveProducts_errors { - __typename: "Error"; - field: string | null; - message: string | null; -} - export interface UnassignCollectionProduct_collectionRemoveProducts_collection_products_edges_node_productType { __typename: "ProductType"; id: string; @@ -57,10 +53,16 @@ export interface UnassignCollectionProduct_collectionRemoveProducts_collection { products: UnassignCollectionProduct_collectionRemoveProducts_collection_products | null; } +export interface UnassignCollectionProduct_collectionRemoveProducts_errors { + __typename: "ProductError"; + code: ProductErrorCode; + field: string | null; +} + export interface UnassignCollectionProduct_collectionRemoveProducts { __typename: "CollectionRemoveProducts"; - errors: UnassignCollectionProduct_collectionRemoveProducts_errors[]; collection: UnassignCollectionProduct_collectionRemoveProducts_collection | null; + errors: UnassignCollectionProduct_collectionRemoveProducts_errors[]; } export interface UnassignCollectionProduct { diff --git a/src/collections/views/CollectionCreate.tsx b/src/collections/views/CollectionCreate.tsx index 8db1fcda5..345243306 100644 --- a/src/collections/views/CollectionCreate.tsx +++ b/src/collections/views/CollectionCreate.tsx @@ -4,7 +4,7 @@ import { useIntl } from "react-intl"; import { WindowTitle } from "@saleor/components/WindowTitle"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; -import { maybe } from "../../misc"; +import { commonMessages } from "@saleor/intl"; import { CollectionCreateInput } from "../../types/globalTypes"; import CollectionCreatePage from "../components/CollectionCreatePage/CollectionCreatePage"; import { TypedCollectionCreateMutation } from "../mutations"; @@ -19,9 +19,7 @@ export const CollectionCreate: React.FC = () => { const handleCollectionCreateSuccess = (data: CreateCollection) => { if (data.collectionCreate.errors.length === 0) { notify({ - text: intl.formatMessage({ - defaultMessage: "Created collection" - }) + text: intl.formatMessage(commonMessages.savedChanges) }); navigate(collectionUrl(data.collectionCreate.collection.id)); } else { @@ -31,7 +29,7 @@ export const CollectionCreate: React.FC = () => { ); if (backgroundImageError) { notify({ - text: backgroundImageError.message + text: intl.formatMessage(commonMessages.somethingWentWrong) }); } } @@ -47,10 +45,7 @@ export const CollectionCreate: React.FC = () => { })} /> createCollectionOpts.data.collectionCreate.errors, - [] - )} + errors={createCollectionOpts.data?.collectionCreate.errors || []} onBack={() => navigate(collectionListUrl())} disabled={createCollectionOpts.loading} onSubmit={formData => diff --git a/src/collections/views/CollectionDetails.tsx b/src/collections/views/CollectionDetails.tsx index ed11232cb..74075e85e 100644 --- a/src/collections/views/CollectionDetails.tsx +++ b/src/collections/views/CollectionDetails.tsx @@ -88,7 +88,7 @@ export const CollectionDetails: React.FC = ({ ); if (backgroundImageError) { notify({ - text: backgroundImageError.message + text: intl.formatMessage(commonMessages.somethingWentWrong) }); } } @@ -204,7 +204,7 @@ export const CollectionDetails: React.FC = ({ onAdd={() => openModal("assign")} onBack={handleBack} disabled={loading} - collection={maybe(() => data.collection)} + collection={data?.collection} errors={ updateCollection.opts?.data?.collectionUpdate.errors || [] } diff --git a/src/types/globalTypes.ts b/src/types/globalTypes.ts index 2ad3dc59b..cdee80d75 100644 --- a/src/types/globalTypes.ts +++ b/src/types/globalTypes.ts @@ -563,6 +563,16 @@ export enum ShippingMethodTypeEnum { WEIGHT = "WEIGHT", } +export enum ShopErrorCode { + ALREADY_EXISTS = "ALREADY_EXISTS", + CANNOT_FETCH_TAX_RATES = "CANNOT_FETCH_TAX_RATES", + GRAPHQL_ERROR = "GRAPHQL_ERROR", + INVALID = "INVALID", + NOT_FOUND = "NOT_FOUND", + REQUIRED = "REQUIRED", + UNIQUE = "UNIQUE", +} + export enum StaffMemberStatus { ACTIVE = "ACTIVE", DEACTIVATED = "DEACTIVATED",