diff --git a/src/components/CompanyAddressInput/CompanyAddressForm.tsx b/src/components/CompanyAddressInput/CompanyAddressForm.tsx index b94b87aac..a3b58f8a0 100644 --- a/src/components/CompanyAddressInput/CompanyAddressForm.tsx +++ b/src/components/CompanyAddressInput/CompanyAddressForm.tsx @@ -15,12 +15,16 @@ import { getFormErrors } from "@saleor/utils/errors"; import { ShopErrorFragment } from "@saleor/siteSettings/types/ShopErrorFragment"; import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment"; import getAccountErrorMessage from "@saleor/utils/errors/account"; +import getWarehouseErrorMessage from "@saleor/utils/errors/warehouse"; +import { WarehouseErrorFragment } from "@saleor/warehouses/types/WarehouseErrorFragment"; export interface CompanyAddressFormProps { countries: SingleAutocompleteChoiceType[]; data: AddressTypeInput; displayCountry: string; - errors: Array; + errors: Array< + AccountErrorFragment | ShopErrorFragment | WarehouseErrorFragment + >; disabled: boolean; onChange: (event: ChangeEvent) => void; onCountryChange: (event: ChangeEvent) => void; @@ -34,14 +38,17 @@ const useStyles = makeStyles( ); function getErrorMessage( - err: AccountErrorFragment | ShopErrorFragment, + err: AccountErrorFragment | ShopErrorFragment | WarehouseErrorFragment, intl: IntlShape ): string { - if (err?.__typename === "AccountError") { - return getAccountErrorMessage(err, intl); + switch (err?.__typename) { + case "AccountError": + return getAccountErrorMessage(err, intl); + case "WarehouseError": + return getWarehouseErrorMessage(err, intl); + default: + return getShopErrorMessage(err, intl); } - - return getShopErrorMessage(err, intl); } const CompanyAddressForm: React.FC = props => { diff --git a/src/products/components/ProductWarehousesDialog/ProductWarehousesDialog.tsx b/src/products/components/ProductWarehousesDialog/ProductWarehousesDialog.tsx index a975f31bb..f027fcad9 100644 --- a/src/products/components/ProductWarehousesDialog/ProductWarehousesDialog.tsx +++ b/src/products/components/ProductWarehousesDialog/ProductWarehousesDialog.tsx @@ -5,7 +5,7 @@ import DialogContent from "@material-ui/core/DialogContent"; import DialogTitle from "@material-ui/core/DialogTitle"; import Typography from "@material-ui/core/Typography"; import React from "react"; -import { FormattedMessage, useIntl } from "react-intl"; +import { FormattedMessage, useIntl, IntlShape } from "react-intl"; import makeStyles from "@material-ui/core/styles/makeStyles"; import { diff, DiffData } from "fast-array-diff"; @@ -20,6 +20,9 @@ import { isSelected, toggle } from "@saleor/utils/lists"; import useStateFromProps from "@saleor/hooks/useStateFromProps"; import { BulkStockErrorFragment } from "@saleor/products/types/BulkStockErrorFragment"; import { StockErrorFragment } from "@saleor/products/types/StockErrorFragment"; +import getStockErrorMessage, { + getBulkStockErrorMessage +} from "@saleor/utils/errors/stock"; const useStyles = makeStyles( theme => ({ @@ -49,6 +52,18 @@ export interface ProductWarehousesDialogProps { onConfirm: (data: DiffData) => void; } +function getErrorMessage( + err: BulkStockErrorFragment | StockErrorFragment, + intl: IntlShape +): string { + switch (err?.__typename) { + case "BulkStockError": + return getBulkStockErrorMessage(err, intl); + default: + getStockErrorMessage(err, intl); + } +} + const ProductWarehousesDialog: React.FC = ({ confirmButtonState, disabled, @@ -112,7 +127,9 @@ const ProductWarehousesDialog: React.FC = ({ {errors.length > 0 && ( - {errors[0]?.message} + + {getErrorMessage(errors[0], intl)} + )} diff --git a/src/utils/errors/stock.ts b/src/utils/errors/stock.ts new file mode 100644 index 000000000..6bf4d1da9 --- /dev/null +++ b/src/utils/errors/stock.ts @@ -0,0 +1,47 @@ +import { IntlShape, defineMessages } from "react-intl"; + +import { StockErrorFragment } from "@saleor/products/types/StockErrorFragment"; +import { StockErrorCode } from "@saleor/types/globalTypes"; +import { commonMessages } from "@saleor/intl"; +import { BulkStockErrorFragment } from "@saleor/products/types/BulkStockErrorFragment"; +import commonErrorMessages from "./common"; +import getProductErrorMessage from "./product"; + +const messages = defineMessages({ + slugUnique: { + defaultMessage: + "Stock for this warehouse already exists for this product variant", + description: "error message" + } +}); + +function getStockErrorMessage( + err: Omit | undefined, + intl: IntlShape +): string { + if (err) { + switch (err.code) { + case StockErrorCode.UNIQUE: + return intl.formatMessage(messages.slugUnique); + case StockErrorCode.GRAPHQL_ERROR: + return intl.formatMessage(commonErrorMessages.graphqlError); + case StockErrorCode.REQUIRED: + return intl.formatMessage(commonMessages.requiredField); + case StockErrorCode.INVALID: + return intl.formatMessage(commonErrorMessages.invalid); + default: + return intl.formatMessage(commonErrorMessages.unknownError); + } + } + + return undefined; +} + +export function getBulkStockErrorMessage( + err: Omit | undefined, + intl: IntlShape +): string { + return getProductErrorMessage(err, intl); +} + +export default getStockErrorMessage; diff --git a/src/utils/errors/warehouse.ts b/src/utils/errors/warehouse.ts new file mode 100644 index 000000000..ee45e04a3 --- /dev/null +++ b/src/utils/errors/warehouse.ts @@ -0,0 +1,51 @@ +import { IntlShape, defineMessages } from "react-intl"; + +import { WarehouseErrorFragment } from "@saleor/warehouses/types/WarehouseErrorFragment"; +import { WarehouseErrorCode } from "@saleor/types/globalTypes"; +import { commonMessages } from "@saleor/intl"; +import commonErrorMessages from "./common"; + +const messages = defineMessages({ + slugUnique: { + defaultMessage: "Slug must be unique for each warehouse", + description: "error message" + } +}); + +function getWarehouseErrorMessage( + err: Omit | undefined, + intl: IntlShape +): string { + if (err) { + switch (err.code) { + case WarehouseErrorCode.GRAPHQL_ERROR: + return intl.formatMessage(commonErrorMessages.graphqlError); + case WarehouseErrorCode.REQUIRED: + return intl.formatMessage(commonMessages.requiredField); + case WarehouseErrorCode.INVALID: + return intl.formatMessage(commonErrorMessages.invalid); + default: + return intl.formatMessage(commonErrorMessages.unknownError); + } + } + + return undefined; +} + +export function getWarehouseSlugErrorMessage( + err: Omit | undefined, + intl: IntlShape +): string { + if (err) { + switch (err.code) { + case WarehouseErrorCode.UNIQUE: + return intl.formatMessage(messages.slugUnique); + default: + return getWarehouseErrorMessage(err, intl); + } + } + + return undefined; +} + +export default getWarehouseErrorMessage; diff --git a/src/warehouses/components/WarehouseCreatePage/WarehouseCreatePage.tsx b/src/warehouses/components/WarehouseCreatePage/WarehouseCreatePage.tsx index 61a25f254..b49e010f2 100644 --- a/src/warehouses/components/WarehouseCreatePage/WarehouseCreatePage.tsx +++ b/src/warehouses/components/WarehouseCreatePage/WarehouseCreatePage.tsx @@ -5,7 +5,6 @@ import Container from "@saleor/components/Container"; import Form from "@saleor/components/Form"; import SaveButtonBar from "@saleor/components/SaveButtonBar"; import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton"; -import { UserError } from "@saleor/types"; import Grid from "@saleor/components/Grid"; import CardSpacer from "@saleor/components/CardSpacer"; import CompanyAddressInput from "@saleor/components/CompanyAddressInput"; @@ -18,6 +17,7 @@ import { ShopInfo_shop_countries } from "@saleor/components/Shop/types/ShopInfo" import AppHeader from "@saleor/components/AppHeader"; import PageHeader from "@saleor/components/PageHeader"; import { sectionNames } from "@saleor/intl"; +import { WarehouseErrorFragment } from "@saleor/warehouses/types/WarehouseErrorFragment"; import WarehouseInfo from "../WarehouseInfo"; export interface WarehouseCreatePageFormData extends AddressTypeInput { @@ -26,7 +26,7 @@ export interface WarehouseCreatePageFormData extends AddressTypeInput { export interface WarehouseCreatePageProps { countries: ShopInfo_shop_countries[]; disabled: boolean; - errors: UserError[]; + errors: WarehouseErrorFragment[]; saveButtonBarState: ConfirmButtonTransitionState; onBack: () => void; onSubmit: (data: WarehouseCreatePageFormData) => void; diff --git a/src/warehouses/components/WarehouseDetailsPage/WarehouseDetailsPage.tsx b/src/warehouses/components/WarehouseDetailsPage/WarehouseDetailsPage.tsx index d15bf3836..c4c53c811 100644 --- a/src/warehouses/components/WarehouseDetailsPage/WarehouseDetailsPage.tsx +++ b/src/warehouses/components/WarehouseDetailsPage/WarehouseDetailsPage.tsx @@ -5,7 +5,6 @@ import Container from "@saleor/components/Container"; import Form from "@saleor/components/Form"; import SaveButtonBar from "@saleor/components/SaveButtonBar"; import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton"; -import { UserError } from "@saleor/types"; import Grid from "@saleor/components/Grid"; import CardSpacer from "@saleor/components/CardSpacer"; import CompanyAddressInput from "@saleor/components/CompanyAddressInput"; @@ -20,6 +19,7 @@ import AppHeader from "@saleor/components/AppHeader"; import PageHeader from "@saleor/components/PageHeader"; import { sectionNames } from "@saleor/intl"; import { CountryCode } from "@saleor/types/globalTypes"; +import { WarehouseErrorFragment } from "@saleor/warehouses/types/WarehouseErrorFragment"; import WarehouseInfo from "../WarehouseInfo"; import WarehouseZones from "../WarehouseZones"; import { WarehouseDetails_warehouse } from "../../types/WarehouseDetails"; @@ -30,7 +30,7 @@ export interface WarehouseDetailsPageFormData extends AddressTypeInput { export interface WarehouseDetailsPageProps { countries: ShopInfo_shop_countries[]; disabled: boolean; - errors: UserError[]; + errors: WarehouseErrorFragment[]; saveButtonBarState: ConfirmButtonTransitionState; warehouse: WarehouseDetails_warehouse; onBack: () => void; diff --git a/src/warehouses/components/WarehouseInfo/WarehouseInfo.tsx b/src/warehouses/components/WarehouseInfo/WarehouseInfo.tsx index fdc51a261..1dde8858a 100644 --- a/src/warehouses/components/WarehouseInfo/WarehouseInfo.tsx +++ b/src/warehouses/components/WarehouseInfo/WarehouseInfo.tsx @@ -7,13 +7,14 @@ import { useIntl } from "react-intl"; import CardTitle from "@saleor/components/CardTitle"; import { commonMessages } from "@saleor/intl"; import { FormChange } from "@saleor/hooks/useForm"; -import { UserError } from "@saleor/types"; -import { getFieldError } from "@saleor/utils/errors"; +import { getFormErrors } from "@saleor/utils/errors"; +import { WarehouseErrorFragment } from "@saleor/warehouses/types/WarehouseErrorFragment"; +import getWarehouseErrorMessage from "@saleor/utils/errors/warehouse"; export interface WarehouseInfoProps { data: Record<"name", string>; disabled: boolean; - errors: UserError[]; + errors: WarehouseErrorFragment[]; onChange: FormChange; } @@ -25,6 +26,8 @@ const WarehouseInfo: React.FC = ({ }) => { const intl = useIntl(); + const formErrors = getFormErrors(["name"], errors); + return ( = ({