Use error formatting in shipping section

This commit is contained in:
dominik-zeglen 2020-03-17 18:41:47 +01:00
parent 8804de71a3
commit 8f18bd75ce
19 changed files with 254 additions and 114 deletions

View file

@ -11,8 +11,8 @@ import Grid from "@saleor/components/Grid";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar"; import SaveButtonBar from "@saleor/components/SaveButtonBar";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { ShippingErrorFragment } from "@saleor/shipping/types/ShippingErrorFragment";
import { CountryFragment } from "../../../taxes/types/CountryFragment"; import { CountryFragment } from "../../../taxes/types/CountryFragment";
import { UserError } from "../../../types";
import ShippingZoneCountriesAssignDialog from "../ShippingZoneCountriesAssignDialog"; import ShippingZoneCountriesAssignDialog from "../ShippingZoneCountriesAssignDialog";
import ShippingZoneInfo from "../ShippingZoneInfo"; import ShippingZoneInfo from "../ShippingZoneInfo";
@ -25,7 +25,7 @@ export interface FormData {
export interface ShippingZoneCreatePageProps { export interface ShippingZoneCreatePageProps {
countries: CountryFragment[]; countries: CountryFragment[];
disabled: boolean; disabled: boolean;
errors: UserError[]; errors: ShippingErrorFragment[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
onBack: () => void; onBack: () => void;
onSubmit: (data: FormData) => void; onSubmit: (data: FormData) => void;

View file

@ -10,8 +10,8 @@ import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid"; import Grid from "@saleor/components/Grid";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar"; import SaveButtonBar from "@saleor/components/SaveButtonBar";
import { maybe } from "../../../misc"; import { ShippingErrorFragment } from "@saleor/shipping/types/ShippingErrorFragment";
import { UserError } from "../../../types"; import { maybe, getStringOrPlaceholder } from "../../../misc";
import { ShippingMethodTypeEnum } from "../../../types/globalTypes"; import { ShippingMethodTypeEnum } from "../../../types/globalTypes";
import { ShippingZoneDetailsFragment } from "../../types/ShippingZoneDetailsFragment"; import { ShippingZoneDetailsFragment } from "../../types/ShippingZoneDetailsFragment";
import ShippingZoneInfo from "../ShippingZoneInfo"; import ShippingZoneInfo from "../ShippingZoneInfo";
@ -23,7 +23,7 @@ export interface FormData {
export interface ShippingZoneDetailsPageProps { export interface ShippingZoneDetailsPageProps {
disabled: boolean; disabled: boolean;
errors: UserError[]; errors: ShippingErrorFragment[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
shippingZone: ShippingZoneDetailsFragment; shippingZone: ShippingZoneDetailsFragment;
onBack: () => void; onBack: () => void;
@ -66,13 +66,13 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
<AppHeader onBack={onBack}> <AppHeader onBack={onBack}>
<FormattedMessage defaultMessage="Shipping" /> <FormattedMessage defaultMessage="Shipping" />
</AppHeader> </AppHeader>
<PageHeader title={maybe(() => shippingZone.name)} /> <PageHeader title={getStringOrPlaceholder(shippingZone?.name)} />
<Grid> <Grid>
<div> <div>
<ShippingZoneInfo data={data} errors={errors} onChange={change} /> <ShippingZoneInfo data={data} errors={errors} onChange={change} />
<CardSpacer /> <CardSpacer />
<CountryList <CountryList
countries={maybe(() => shippingZone.countries)} countries={shippingZone?.countries}
disabled={disabled} disabled={disabled}
emptyText={maybe( emptyText={maybe(
() => () =>

View file

@ -6,13 +6,14 @@ import { useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { getFieldError } from "@saleor/utils/errors"; import { getFormErrors } from "@saleor/utils/errors";
import { UserError } from "../../../types"; import getShippingErrorMessage from "@saleor/utils/errors/shipping";
import { ShippingErrorFragment } from "@saleor/shipping/types/ShippingErrorFragment";
import { FormData } from "../ShippingZoneDetailsPage"; import { FormData } from "../ShippingZoneDetailsPage";
export interface ShippingZoneInfoProps { export interface ShippingZoneInfoProps {
data: FormData; data: FormData;
errors: UserError[]; errors: ShippingErrorFragment[];
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
} }
@ -23,6 +24,8 @@ const ShippingZoneInfo: React.FC<ShippingZoneInfoProps> = ({
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const formErrors = getFormErrors(["name"], errors);
return ( return (
<Card> <Card>
<CardTitle <CardTitle
@ -30,9 +33,9 @@ const ShippingZoneInfo: React.FC<ShippingZoneInfoProps> = ({
/> />
<CardContent> <CardContent>
<TextField <TextField
error={!!getFieldError(errors, "name")} error={!!formErrors.name}
fullWidth fullWidth
helperText={getFieldError(errors, "name")?.message} helperText={getShippingErrorMessage(formErrors.name, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Shipping Zone Name" defaultMessage: "Shipping Zone Name"
})} })}

View file

@ -18,11 +18,17 @@ import FormSpacer from "@saleor/components/FormSpacer";
import Hr from "@saleor/components/Hr"; import Hr from "@saleor/components/Hr";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import { getFieldError } from "@saleor/utils/errors"; import { getFormErrors } from "@saleor/utils/errors";
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
import getShippingErrorMessage from "@saleor/utils/errors/shipping";
import { ShippingErrorFragment } from "@saleor/shipping/types/ShippingErrorFragment";
import { maybe } from "../../../misc"; import { maybe } from "../../../misc";
import { UserError } from "../../../types";
import { ShippingMethodTypeEnum } from "../../../types/globalTypes"; import { ShippingMethodTypeEnum } from "../../../types/globalTypes";
import { ShippingZoneDetailsFragment_shippingMethods } from "../../types/ShippingZoneDetailsFragment"; import { ShippingZoneDetailsFragment_shippingMethods } from "../../types/ShippingZoneDetailsFragment";
import {
getShippingPriceRateErrorMessage,
getShippingWeightRateErrorMessage
} from "./errors";
export interface FormData { export interface FormData {
name: string; name: string;
@ -38,7 +44,7 @@ export interface ShippingZoneRateDialogProps {
confirmButtonState: ConfirmButtonTransitionState; confirmButtonState: ConfirmButtonTransitionState;
defaultCurrency: string; defaultCurrency: string;
disabled: boolean; disabled: boolean;
errors: UserError[]; errors: ShippingErrorFragment[];
open: boolean; open: boolean;
rate: ShippingZoneDetailsFragment_shippingMethods; rate: ShippingZoneDetailsFragment_shippingMethods;
variant: ShippingMethodTypeEnum; variant: ShippingMethodTypeEnum;
@ -65,11 +71,10 @@ const useStyles = makeStyles(
const ShippingZoneRateDialog: React.FC<ShippingZoneRateDialogProps> = props => { const ShippingZoneRateDialog: React.FC<ShippingZoneRateDialogProps> = props => {
const { const {
action, action,
confirmButtonState, confirmButtonState,
defaultCurrency, defaultCurrency,
disabled, disabled,
errors, errors: apiErrors,
onClose, onClose,
onSubmit, onSubmit,
open, open,
@ -79,6 +84,17 @@ const ShippingZoneRateDialog: React.FC<ShippingZoneRateDialogProps> = props => {
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl(); const intl = useIntl();
const errors = useModalDialogErrors(apiErrors, open);
const formFields = [
"name",
"minimumOrderPrice",
"minimumOrderWeight",
"maximumOrderPrice",
"maximumOrderWeight",
"price"
];
const formErrors = getFormErrors(formFields, errors);
const initialForm: FormData = const initialForm: FormData =
action === "create" action === "create"
@ -108,6 +124,11 @@ const ShippingZoneRateDialog: React.FC<ShippingZoneRateDialogProps> = props => {
initialForm.noLimits = !initialForm.maxValue && !initialForm.minValue; initialForm.noLimits = !initialForm.maxValue && !initialForm.minValue;
} }
const getErrorMessage =
variant === ShippingMethodTypeEnum.PRICE
? getShippingPriceRateErrorMessage
: getShippingWeightRateErrorMessage;
return ( return (
<Dialog onClose={onClose} open={open} fullWidth maxWidth="sm"> <Dialog onClose={onClose} open={open} fullWidth maxWidth="sm">
<Form initial={initialForm} onSubmit={onSubmit}> <Form initial={initialForm} onSubmit={onSubmit}>
@ -139,10 +160,10 @@ const ShippingZoneRateDialog: React.FC<ShippingZoneRateDialogProps> = props => {
<DialogContent> <DialogContent>
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "name")} error={!!formErrors.name}
fullWidth fullWidth
helperText={ helperText={
getFieldError(errors, "name") || getShippingErrorMessage(formErrors.name, intl) ||
intl.formatMessage({ intl.formatMessage({
defaultMessage: defaultMessage:
"This will be shown to customers at checkout" "This will be shown to customers at checkout"
@ -207,24 +228,27 @@ const ShippingZoneRateDialog: React.FC<ShippingZoneRateDialogProps> = props => {
<TextField <TextField
disabled={disabled} disabled={disabled}
error={ error={
variant === ShippingMethodTypeEnum.PRICE !!formErrors.minimumOrderPrice ||
? !!getFieldError(errors, "minimumOrderPrice") !!formErrors.minimumOrderWeight
: !!getFieldError(errors, "minimumOrderWeight")
} }
fullWidth fullWidth
helperText={ helperText={
variant === ShippingMethodTypeEnum.PRICE variant === ShippingMethodTypeEnum.PRICE
? getFieldError(errors, "minimumOrderPrice") ? getErrorMessage(
: getFieldError(errors, "minimumOrderWeight") formErrors.minimumOrderPrice,
intl
)
: getErrorMessage(
formErrors.minimumOrderWeight,
intl
)
} }
label={ label={
variant === ShippingMethodTypeEnum.PRICE variant === ShippingMethodTypeEnum.PRICE
? getFieldError(errors, "minimumOrderPrice") || ? intl.formatMessage({
intl.formatMessage({
defaultMessage: "Minimal Order Value" defaultMessage: "Minimal Order Value"
}) })
: getFieldError(errors, "minimumOrderWeight") || : intl.formatMessage({
intl.formatMessage({
defaultMessage: "Minimal Order Weight" defaultMessage: "Minimal Order Weight"
}) })
} }
@ -236,24 +260,27 @@ const ShippingZoneRateDialog: React.FC<ShippingZoneRateDialogProps> = props => {
<TextField <TextField
disabled={disabled} disabled={disabled}
error={ error={
variant === ShippingMethodTypeEnum.PRICE !!formErrors.maximumOrderPrice ||
? !!getFieldError(errors, "maximumOrderPrice") !!formErrors.maximumOrderWeight
: !!getFieldError(errors, "maximumOrderWeight")
} }
fullWidth fullWidth
helperText={ helperText={
variant === ShippingMethodTypeEnum.PRICE variant === ShippingMethodTypeEnum.PRICE
? getFieldError(errors, "maximumOrderPrice") ? getErrorMessage(
: getFieldError(errors, "maximumOrderWeight") formErrors.maximumOrderPrice,
intl
)
: getErrorMessage(
formErrors.maximumOrderWeight,
intl
)
} }
label={ label={
variant === ShippingMethodTypeEnum.PRICE variant === ShippingMethodTypeEnum.PRICE
? getFieldError(errors, "maximumOrderPrice") || ? intl.formatMessage({
intl.formatMessage({
defaultMessage: "Maximal Order Value" defaultMessage: "Maximal Order Value"
}) })
: getFieldError(errors, "maximumOrderWeight") || : intl.formatMessage({
intl.formatMessage({
defaultMessage: "Maximal Order Weight" defaultMessage: "Maximal Order Weight"
}) })
} }
@ -294,9 +321,9 @@ const ShippingZoneRateDialog: React.FC<ShippingZoneRateDialogProps> = props => {
<div className={classes.grid}> <div className={classes.grid}>
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "price")} error={!!formErrors.price}
fullWidth fullWidth
helperText={getFieldError(errors, "price")?.message} helperText={getErrorMessage(formErrors.price, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Rate Price", defaultMessage: "Rate Price",
description: "shipping method price" description: "shipping method price"

View file

@ -0,0 +1,40 @@
import { IntlShape, defineMessages } from "react-intl";
import { ShippingErrorCode } from "@saleor/types/globalTypes";
import getShippingErrorMessage from "@saleor/utils/errors/shipping";
import { ShippingErrorFragment } from "../../types/ShippingErrorFragment";
const messages = defineMessages({
price: {
defaultMessage: "Maximum price cannot be lower than minimum",
description: "error message"
},
weight: {
defaultMessage: "Maximum weight cannot be lower than minimum",
description: "error message"
}
});
export function getShippingPriceRateErrorMessage(
err: ShippingErrorFragment,
intl: IntlShape
): string {
switch (err?.code) {
case ShippingErrorCode.MAX_LESS_THAN_MIN:
return intl.formatMessage(messages.price);
default:
getShippingErrorMessage(err, intl);
}
}
export function getShippingWeightRateErrorMessage(
err: ShippingErrorFragment,
intl: IntlShape
): string {
switch (err?.code) {
case ShippingErrorCode.MAX_LESS_THAN_MIN:
return intl.formatMessage(messages.weight);
default:
getShippingErrorMessage(err, intl);
}
}

View file

@ -40,12 +40,19 @@ import {
UpdateShippingZoneVariables UpdateShippingZoneVariables
} from "./types/UpdateShippingZone"; } from "./types/UpdateShippingZone";
export const shippingErrorFragment = gql`
fragment ShippingErrorFragment on ShippingError {
code
field
}
`;
const deleteShippingZone = gql` const deleteShippingZone = gql`
${shippingErrorFragment}
mutation DeleteShippingZone($id: ID!) { mutation DeleteShippingZone($id: ID!) {
shippingZoneDelete(id: $id) { shippingZoneDelete(id: $id) {
errors { errors: shippingErrors {
field ...ShippingErrorFragment
message
} }
} }
} }
@ -56,11 +63,11 @@ export const TypedDeleteShippingZone = TypedMutation<
>(deleteShippingZone); >(deleteShippingZone);
const bulkDeleteShippingZone = gql` const bulkDeleteShippingZone = gql`
${shippingErrorFragment}
mutation BulkDeleteShippingZone($ids: [ID]!) { mutation BulkDeleteShippingZone($ids: [ID]!) {
shippingZoneBulkDelete(ids: $ids) { shippingZoneBulkDelete(ids: $ids) {
errors { errors: shippingErrors {
field ...ShippingErrorFragment
message
} }
} }
} }
@ -90,11 +97,11 @@ export const TypedUpdateDefaultWeightUnit = TypedMutation<
const createShippingZone = gql` const createShippingZone = gql`
${countryFragment} ${countryFragment}
${shippingErrorFragment}
mutation CreateShippingZone($input: ShippingZoneInput!) { mutation CreateShippingZone($input: ShippingZoneInput!) {
shippingZoneCreate(input: $input) { shippingZoneCreate(input: $input) {
errors { errors: shippingErrors {
field ...ShippingErrorFragment
message
} }
shippingZone { shippingZone {
countries { countries {
@ -114,11 +121,11 @@ export const TypedCreateShippingZone = TypedMutation<
const updateShippingZone = gql` const updateShippingZone = gql`
${countryFragment} ${countryFragment}
${shippingErrorFragment}
mutation UpdateShippingZone($id: ID!, $input: ShippingZoneInput!) { mutation UpdateShippingZone($id: ID!, $input: ShippingZoneInput!) {
shippingZoneUpdate(id: $id, input: $input) { shippingZoneUpdate(id: $id, input: $input) {
errors { errors: shippingErrors {
field ...ShippingErrorFragment
message
} }
shippingZone { shippingZone {
countries { countries {
@ -137,12 +144,12 @@ export const TypedUpdateShippingZone = TypedMutation<
>(updateShippingZone); >(updateShippingZone);
const updateShippingRate = gql` const updateShippingRate = gql`
${shippingErrorFragment}
${shippingMethodFragment} ${shippingMethodFragment}
mutation UpdateShippingRate($id: ID!, $input: ShippingPriceInput!) { mutation UpdateShippingRate($id: ID!, $input: ShippingPriceInput!) {
shippingPriceUpdate(id: $id, input: $input) { shippingPriceUpdate(id: $id, input: $input) {
errors { errors: shippingErrors {
field ...ShippingErrorFragment
message
} }
shippingMethod { shippingMethod {
...ShippingMethodFragment ...ShippingMethodFragment
@ -156,12 +163,12 @@ export const TypedUpdateShippingRate = TypedMutation<
>(updateShippingRate); >(updateShippingRate);
const createShippingRate = gql` const createShippingRate = gql`
${shippingErrorFragment}
${shippingZoneDetailsFragment} ${shippingZoneDetailsFragment}
mutation CreateShippingRate($input: ShippingPriceInput!) { mutation CreateShippingRate($input: ShippingPriceInput!) {
shippingPriceCreate(input: $input) { shippingPriceCreate(input: $input) {
errors { errors: shippingErrors {
field ...ShippingErrorFragment
message
} }
shippingZone { shippingZone {
...ShippingZoneDetailsFragment ...ShippingZoneDetailsFragment
@ -175,12 +182,12 @@ export const TypedCreateShippingRate = TypedMutation<
>(createShippingRate); >(createShippingRate);
const deleteShippingRate = gql` const deleteShippingRate = gql`
${shippingErrorFragment}
${shippingZoneDetailsFragment} ${shippingZoneDetailsFragment}
mutation DeleteShippingRate($id: ID!) { mutation DeleteShippingRate($id: ID!) {
shippingPriceDelete(id: $id) { shippingPriceDelete(id: $id) {
errors { errors: shippingErrors {
field ...ShippingErrorFragment
message
} }
shippingZone { shippingZone {
...ShippingZoneDetailsFragment ...ShippingZoneDetailsFragment
@ -194,11 +201,11 @@ export const TypedDeleteShippingRate = TypedMutation<
>(deleteShippingRate); >(deleteShippingRate);
const bulkDeleteShippingRate = gql` const bulkDeleteShippingRate = gql`
${shippingErrorFragment}
mutation BulkDeleteShippingRate($ids: [ID]!) { mutation BulkDeleteShippingRate($ids: [ID]!) {
shippingPriceBulkDelete(ids: $ids) { shippingPriceBulkDelete(ids: $ids) {
errors { errors: shippingErrors {
field ...ShippingErrorFragment
message
} }
} }
} }

View file

@ -2,14 +2,16 @@
/* eslint-disable */ /* eslint-disable */
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ShippingErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: BulkDeleteShippingRate // GraphQL mutation operation: BulkDeleteShippingRate
// ==================================================== // ====================================================
export interface BulkDeleteShippingRate_shippingPriceBulkDelete_errors { export interface BulkDeleteShippingRate_shippingPriceBulkDelete_errors {
__typename: "Error"; __typename: "ShippingError";
code: ShippingErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface BulkDeleteShippingRate_shippingPriceBulkDelete { export interface BulkDeleteShippingRate_shippingPriceBulkDelete {

View file

@ -2,14 +2,16 @@
/* eslint-disable */ /* eslint-disable */
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ShippingErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: BulkDeleteShippingZone // GraphQL mutation operation: BulkDeleteShippingZone
// ==================================================== // ====================================================
export interface BulkDeleteShippingZone_shippingZoneBulkDelete_errors { export interface BulkDeleteShippingZone_shippingZoneBulkDelete_errors {
__typename: "Error"; __typename: "ShippingError";
code: ShippingErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface BulkDeleteShippingZone_shippingZoneBulkDelete { export interface BulkDeleteShippingZone_shippingZoneBulkDelete {

View file

@ -2,16 +2,16 @@
/* eslint-disable */ /* eslint-disable */
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ShippingPriceInput, ShippingMethodTypeEnum } from "./../../types/globalTypes"; import { ShippingPriceInput, ShippingErrorCode, ShippingMethodTypeEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: CreateShippingRate // GraphQL mutation operation: CreateShippingRate
// ==================================================== // ====================================================
export interface CreateShippingRate_shippingPriceCreate_errors { export interface CreateShippingRate_shippingPriceCreate_errors {
__typename: "Error"; __typename: "ShippingError";
code: ShippingErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface CreateShippingRate_shippingPriceCreate_shippingZone_countries { export interface CreateShippingRate_shippingPriceCreate_shippingZone_countries {

View file

@ -2,16 +2,16 @@
/* eslint-disable */ /* eslint-disable */
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ShippingZoneInput } from "./../../types/globalTypes"; import { ShippingZoneInput, ShippingErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: CreateShippingZone // GraphQL mutation operation: CreateShippingZone
// ==================================================== // ====================================================
export interface CreateShippingZone_shippingZoneCreate_errors { export interface CreateShippingZone_shippingZoneCreate_errors {
__typename: "Error"; __typename: "ShippingError";
code: ShippingErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface CreateShippingZone_shippingZoneCreate_shippingZone_countries { export interface CreateShippingZone_shippingZoneCreate_shippingZone_countries {

View file

@ -2,16 +2,16 @@
/* eslint-disable */ /* eslint-disable */
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ShippingMethodTypeEnum } from "./../../types/globalTypes"; import { ShippingErrorCode, ShippingMethodTypeEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: DeleteShippingRate // GraphQL mutation operation: DeleteShippingRate
// ==================================================== // ====================================================
export interface DeleteShippingRate_shippingPriceDelete_errors { export interface DeleteShippingRate_shippingPriceDelete_errors {
__typename: "Error"; __typename: "ShippingError";
code: ShippingErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_countries { export interface DeleteShippingRate_shippingPriceDelete_shippingZone_countries {

View file

@ -2,14 +2,16 @@
/* eslint-disable */ /* eslint-disable */
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ShippingErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: DeleteShippingZone // GraphQL mutation operation: DeleteShippingZone
// ==================================================== // ====================================================
export interface DeleteShippingZone_shippingZoneDelete_errors { export interface DeleteShippingZone_shippingZoneDelete_errors {
__typename: "Error"; __typename: "ShippingError";
code: ShippingErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface DeleteShippingZone_shippingZoneDelete { export interface DeleteShippingZone_shippingZoneDelete {

View file

@ -0,0 +1,15 @@
/* tslint:disable */
/* eslint-disable */
// This file was automatically generated and should not be edited.
import { ShippingErrorCode } from "./../../types/globalTypes";
// ====================================================
// GraphQL fragment: ShippingErrorFragment
// ====================================================
export interface ShippingErrorFragment {
__typename: "ShippingError";
code: ShippingErrorCode;
field: string | null;
}

View file

@ -2,16 +2,16 @@
/* eslint-disable */ /* eslint-disable */
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ShippingPriceInput, ShippingMethodTypeEnum } from "./../../types/globalTypes"; import { ShippingPriceInput, ShippingErrorCode, ShippingMethodTypeEnum } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: UpdateShippingRate // GraphQL mutation operation: UpdateShippingRate
// ==================================================== // ====================================================
export interface UpdateShippingRate_shippingPriceUpdate_errors { export interface UpdateShippingRate_shippingPriceUpdate_errors {
__typename: "Error"; __typename: "ShippingError";
code: ShippingErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_minimumOrderPrice { export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_minimumOrderPrice {

View file

@ -2,16 +2,16 @@
/* eslint-disable */ /* eslint-disable */
// This file was automatically generated and should not be edited. // This file was automatically generated and should not be edited.
import { ShippingZoneInput } from "./../../types/globalTypes"; import { ShippingZoneInput, ShippingErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: UpdateShippingZone // GraphQL mutation operation: UpdateShippingZone
// ==================================================== // ====================================================
export interface UpdateShippingZone_shippingZoneUpdate_errors { export interface UpdateShippingZone_shippingZoneUpdate_errors {
__typename: "Error"; __typename: "ShippingError";
code: ShippingErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface UpdateShippingZone_shippingZoneUpdate_shippingZone_countries { export interface UpdateShippingZone_shippingZoneUpdate_shippingZone_countries {

View file

@ -6,7 +6,7 @@ import ActionDialog from "@saleor/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton"; import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { maybe } from "../../../misc"; import { getStringOrPlaceholder } from "../../../misc";
import { ShippingMethodTypeEnum } from "../../../types/globalTypes"; import { ShippingMethodTypeEnum } from "../../../types/globalTypes";
import ShippingZoneCountriesAssignDialog from "../../components/ShippingZoneCountriesAssignDialog"; import ShippingZoneCountriesAssignDialog from "../../components/ShippingZoneCountriesAssignDialog";
import ShippingZoneRateDialog from "../../components/ShippingZoneRateDialog"; import ShippingZoneRateDialog from "../../components/ShippingZoneRateDialog";
@ -45,8 +45,8 @@ const ShippingZoneDetailsDialogs: React.FC<ShippingZoneDetailsDialogsProps> = ({
const closeModal = () => navigate(shippingZoneUrl(id), true); const closeModal = () => navigate(shippingZoneUrl(id), true);
const rate = maybe(() => const rate = shippingZone?.shippingMethods?.find(
shippingZone.shippingMethods.find(rate => rate.id === params.id) rate => rate.id === params.id
); );
return ( return (
@ -54,12 +54,11 @@ const ShippingZoneDetailsDialogs: React.FC<ShippingZoneDetailsDialogsProps> = ({
<ShippingZoneRateDialog <ShippingZoneRateDialog
action="edit" action="edit"
confirmButtonState={updateRateTransitionState} confirmButtonState={updateRateTransitionState}
defaultCurrency={maybe(() => shop.defaultCurrency)} defaultCurrency={shop?.defaultCurrency}
disabled={ops.shippingRateUpdate.opts.loading} disabled={ops.shippingRateUpdate.opts.loading}
errors={maybe( errors={
() => ops.shippingRateUpdate.opts.data.shippingPriceUpdate.errors, ops.shippingRateUpdate.opts.data?.shippingPriceUpdate.errors || []
[] }
)}
onClose={closeModal} onClose={closeModal}
onSubmit={formData => onSubmit={formData =>
ops.shippingRateUpdate.mutate({ ops.shippingRateUpdate.mutate({
@ -74,13 +73,13 @@ const ShippingZoneDetailsDialogs: React.FC<ShippingZoneDetailsDialogsProps> = ({
name: formData.name, name: formData.name,
price: formData.isFree ? 0 : parseFloat(formData.price), price: formData.isFree ? 0 : parseFloat(formData.price),
shippingZone: id, shippingZone: id,
type: maybe(() => rate.type) type: rate?.type
} }
}) })
} }
open={params.action === "edit-rate"} open={params.action === "edit-rate"}
rate={rate} rate={rate}
variant={maybe(() => rate.type)} variant={rate?.type}
/> />
<ActionDialog <ActionDialog
confirmButtonState={deleteRateTransitionState} confirmButtonState={deleteRateTransitionState}
@ -103,7 +102,7 @@ const ShippingZoneDetailsDialogs: React.FC<ShippingZoneDetailsDialogsProps> = ({
description="delete shipping method" description="delete shipping method"
id="shippingZoneDetailsDialogsDeleteShippingMethod" id="shippingZoneDetailsDialogsDeleteShippingMethod"
values={{ values={{
name: maybe(() => rate.name, "...") name: getStringOrPlaceholder(rate?.name)
}} }}
/> />
</DialogContentText> </DialogContentText>
@ -111,12 +110,11 @@ const ShippingZoneDetailsDialogs: React.FC<ShippingZoneDetailsDialogsProps> = ({
<ShippingZoneRateDialog <ShippingZoneRateDialog
action="create" action="create"
confirmButtonState={createRateTransitionState} confirmButtonState={createRateTransitionState}
defaultCurrency={maybe(() => shop.defaultCurrency)} defaultCurrency={shop?.defaultCurrency}
disabled={ops.shippingRateCreate.opts.loading} disabled={ops.shippingRateCreate.opts.loading}
errors={maybe( errors={
() => ops.shippingRateCreate.opts.data.shippingPriceCreate.errors, ops.shippingRateCreate.opts.data?.shippingPriceCreate.errors || []
[] }
)}
onClose={closeModal} onClose={closeModal}
onSubmit={formData => onSubmit={formData =>
ops.shippingRateCreate.mutate({ ops.shippingRateCreate.mutate({
@ -178,19 +176,18 @@ const ShippingZoneDetailsDialogs: React.FC<ShippingZoneDetailsDialogsProps> = ({
description="delete shipping zone" description="delete shipping zone"
id="shippingZoneDetailsDialogsDeleteShippingZone" id="shippingZoneDetailsDialogsDeleteShippingZone"
values={{ values={{
name: <strong>{maybe(() => shippingZone.name, "...")}</strong> name: (
<strong>{getStringOrPlaceholder(shippingZone?.name)}</strong>
)
}} }}
/> />
</DialogContentText> </DialogContentText>
</ActionDialog> </ActionDialog>
<ShippingZoneCountriesAssignDialog <ShippingZoneCountriesAssignDialog
confirmButtonState={assignCountryTransitionState} confirmButtonState={assignCountryTransitionState}
countries={maybe(() => shop.countries, [])} countries={shop?.countries}
initial={maybe( initial={shippingZone?.countries.map(country => country.code) || []}
() => shippingZone.countries.map(country => country.code), isDefault={!!shippingZone?.default}
[]
)}
isDefault={maybe(() => shippingZone.default, false)}
onClose={closeModal} onClose={closeModal}
onConfirm={formData => onConfirm={formData =>
ops.shippingZoneUpdate.mutate({ ops.shippingZoneUpdate.mutate({
@ -230,12 +227,10 @@ const ShippingZoneDetailsDialogs: React.FC<ShippingZoneDetailsDialogsProps> = ({
values={{ values={{
countryName: ( countryName: (
<strong> <strong>
{maybe( {getStringOrPlaceholder(
() => shippingZone?.countries.find(
shippingZone.countries.find( country => country.code === params.id
country => country.code === params.id )?.country
).country,
"..."
)} )}
</strong> </strong>
) )

View file

@ -183,7 +183,7 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
id={id} id={id}
ops={ops} ops={ops}
params={params} params={params}
shippingZone={maybe(() => data.shippingZone)} shippingZone={data?.shippingZone}
unassignCountryTransitionState={ unassignCountryTransitionState={
ops.shippingZoneUpdate.opts.status ops.shippingZoneUpdate.opts.status
} }

View file

@ -623,6 +623,16 @@ export enum ServiceAccountSortField {
NAME = "NAME", NAME = "NAME",
} }
export enum ShippingErrorCode {
ALREADY_EXISTS = "ALREADY_EXISTS",
GRAPHQL_ERROR = "GRAPHQL_ERROR",
INVALID = "INVALID",
MAX_LESS_THAN_MIN = "MAX_LESS_THAN_MIN",
NOT_FOUND = "NOT_FOUND",
REQUIRED = "REQUIRED",
UNIQUE = "UNIQUE",
}
export enum ShippingMethodTypeEnum { export enum ShippingMethodTypeEnum {
PRICE = "PRICE", PRICE = "PRICE",
WEIGHT = "WEIGHT", WEIGHT = "WEIGHT",

View file

@ -0,0 +1,37 @@
import { IntlShape, defineMessages } from "react-intl";
import { ShippingErrorFragment } from "@saleor/shipping/types/ShippingErrorFragment";
import { ShippingErrorCode } from "@saleor/types/globalTypes";
import { commonMessages } from "@saleor/intl";
import commonErrorMessages from "./common";
const messages = defineMessages({
alreadyExists: {
defaultMessage: "Default shipping zone already exists",
description: "error message"
}
});
function getShippingErrorMessage(
err: Omit<ShippingErrorFragment, "__typename"> | undefined,
intl: IntlShape
): string {
if (err) {
switch (err.code) {
case ShippingErrorCode.ALREADY_EXISTS:
return intl.formatMessage(messages.alreadyExists);
case ShippingErrorCode.GRAPHQL_ERROR:
return intl.formatMessage(commonErrorMessages.graphqlError);
case ShippingErrorCode.REQUIRED:
return intl.formatMessage(commonMessages.requiredField);
case ShippingErrorCode.INVALID:
return intl.formatMessage(commonErrorMessages.invalid);
default:
return intl.formatMessage(commonErrorMessages.unknownError);
}
}
return undefined;
}
export default getShippingErrorMessage;