Use error formatting in site settings view

This commit is contained in:
dominik-zeglen 2020-03-17 19:49:01 +01:00
parent 96c98077d8
commit 63ff52349d
12 changed files with 203 additions and 120 deletions

View file

@ -3,7 +3,7 @@ import CardContent from "@material-ui/core/CardContent";
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField"; import TextField from "@material-ui/core/TextField";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl, IntlShape } from "react-intl";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import FormSpacer from "@saleor/components/FormSpacer"; import FormSpacer from "@saleor/components/FormSpacer";
@ -12,15 +12,18 @@ import SingleAutocompleteSelectField, {
SingleAutocompleteChoiceType SingleAutocompleteChoiceType
} from "@saleor/components/SingleAutocompleteSelectField"; } from "@saleor/components/SingleAutocompleteSelectField";
import { ChangeEvent } from "@saleor/hooks/useForm"; import { ChangeEvent } from "@saleor/hooks/useForm";
import { UserError } from "@saleor/types"; import { getFormErrors } from "@saleor/utils/errors";
import { getFieldError } from "@saleor/utils/errors"; import { ShopErrorFragment } from "@saleor/siteSettings/types/ShopErrorFragment";
import getShopErrorMessage from "@saleor/utils/errors/shop";
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
import getAccountErrorMessage from "@saleor/utils/errors/account";
import { SiteSettingsPageFormData } from "../SiteSettingsPage"; import { SiteSettingsPageFormData } from "../SiteSettingsPage";
interface SiteSettingsAddressProps { interface SiteSettingsAddressProps {
countries: SingleAutocompleteChoiceType[]; countries: SingleAutocompleteChoiceType[];
data: SiteSettingsPageFormData; data: SiteSettingsPageFormData;
displayCountry: string; displayCountry: string;
errors: UserError[]; errors: Array<AccountErrorFragment | ShopErrorFragment>;
disabled: boolean; disabled: boolean;
onChange: (event: ChangeEvent) => void; onChange: (event: ChangeEvent) => void;
onCountryChange: (event: ChangeEvent) => void; onCountryChange: (event: ChangeEvent) => void;
@ -35,6 +38,17 @@ const useStyles = makeStyles(
{ name: "SiteSettingsAddress" } { name: "SiteSettingsAddress" }
); );
function getErrorMessage(
err: AccountErrorFragment | ShopErrorFragment,
intl: IntlShape
): string {
if (err?.__typename === "AccountError") {
return getAccountErrorMessage(err, intl);
}
return getShopErrorMessage(err, intl);
}
const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => { const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
const { const {
countries, countries,
@ -45,10 +59,22 @@ const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
onChange, onChange,
onCountryChange onCountryChange
} = props; } = props;
const classes = useStyles(props);
const classes = useStyles(props);
const intl = useIntl(); const intl = useIntl();
const formFields = [
"companyName",
"streetAddress1",
"streetAddress2",
"city",
"postalCode",
"country",
"companyArea",
"phone"
];
const formErrors = getFormErrors(formFields, errors);
return ( return (
<Card className={classes.root}> <Card className={classes.root}>
<CardTitle <CardTitle
@ -60,8 +86,8 @@ const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
<CardContent> <CardContent>
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "companyName")} error={!!formErrors.companyName}
helperText={getFieldError(errors, "companyName")?.message} helperText={getErrorMessage(formErrors.companyName, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Company" defaultMessage: "Company"
})} })}
@ -73,8 +99,8 @@ const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "streetAddress1")} error={!!formErrors.streetAddress1}
helperText={getFieldError(errors, "streetAddress1")?.message} helperText={getErrorMessage(formErrors.streetAddress1, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Address line 1" defaultMessage: "Address line 1"
})} })}
@ -86,8 +112,8 @@ const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "streetAddress2")} error={!!formErrors.streetAddress2}
helperText={getFieldError(errors, "streetAddress2")?.message} helperText={getErrorMessage(formErrors.streetAddress2, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Address line 2" defaultMessage: "Address line 2"
})} })}
@ -100,8 +126,8 @@ const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
<Grid> <Grid>
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "city")} error={!!formErrors.city}
helperText={getFieldError(errors, "city")?.message} helperText={getErrorMessage(formErrors.city, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "City" defaultMessage: "City"
})} })}
@ -112,8 +138,8 @@ const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
/> />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "postalCode")} error={!!formErrors.postalCode}
helperText={getFieldError(errors, "postalCode")?.message} helperText={getErrorMessage(formErrors.postalCode, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "ZIP / Postal code" defaultMessage: "ZIP / Postal code"
})} })}
@ -128,8 +154,8 @@ const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
<SingleAutocompleteSelectField <SingleAutocompleteSelectField
disabled={disabled} disabled={disabled}
displayValue={displayCountry} displayValue={displayCountry}
error={!!getFieldError(errors, "country")} error={!!formErrors.country}
helperText={getFieldError(errors, "country")?.message} helperText={getErrorMessage(formErrors.country, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Country" defaultMessage: "Country"
})} })}
@ -143,8 +169,8 @@ const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
/> />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "companyArea")} error={!!formErrors.countryArea}
helperText={getFieldError(errors, "companyArea")?.message} helperText={getErrorMessage(formErrors.countryArea, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Country area" defaultMessage: "Country area"
})} })}
@ -157,9 +183,9 @@ const SiteSettingsAddress: React.FC<SiteSettingsAddressProps> = props => {
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "phone")} error={!!formErrors.phone}
fullWidth fullWidth
helperText={getFieldError(errors, "phone")?.message} helperText={getErrorMessage(formErrors.phone, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Phone" defaultMessage: "Phone"
})} })}

View file

@ -7,13 +7,14 @@ import { useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import FormSpacer from "@saleor/components/FormSpacer"; import FormSpacer from "@saleor/components/FormSpacer";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { UserError } from "@saleor/types"; import { getFormErrors } from "@saleor/utils/errors";
import { getFieldError } from "@saleor/utils/errors"; import { ShopErrorFragment } from "@saleor/siteSettings/types/ShopErrorFragment";
import getShopErrorMessage from "@saleor/utils/errors/shop";
import { SiteSettingsPageFormData } from "../SiteSettingsPage"; import { SiteSettingsPageFormData } from "../SiteSettingsPage";
interface SiteSettingsDetailsProps { interface SiteSettingsDetailsProps {
data: SiteSettingsPageFormData; data: SiteSettingsPageFormData;
errors: UserError[]; errors: ShopErrorFragment[];
disabled: boolean; disabled: boolean;
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
} }
@ -26,6 +27,8 @@ const SiteSettingsDetails: React.FC<SiteSettingsDetailsProps> = ({
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const formErrors = getFormErrors(["name", "domain", "description"], errors);
return ( return (
<Card> <Card>
<CardTitle <CardTitle
@ -34,14 +37,14 @@ const SiteSettingsDetails: React.FC<SiteSettingsDetailsProps> = ({
<CardContent> <CardContent>
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "name")} error={!!formErrors.name}
fullWidth fullWidth
name="name" name="name"
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Name of your store" defaultMessage: "Name of your store"
})} })}
helperText={ helperText={
getFieldError(errors, "name")?.message || getShopErrorMessage(formErrors.name, intl) ||
intl.formatMessage({ intl.formatMessage({
defaultMessage: defaultMessage:
"Name of your store is shown on tab in web browser" "Name of your store is shown on tab in web browser"
@ -53,27 +56,27 @@ const SiteSettingsDetails: React.FC<SiteSettingsDetailsProps> = ({
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "domain")} error={!!formErrors.domain}
fullWidth fullWidth
name="domain" name="domain"
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "URL of your online store" defaultMessage: "URL of your online store"
})} })}
helperText={getFieldError(errors, "domain")?.message} helperText={getShopErrorMessage(formErrors.domain, intl)}
value={data.domain} value={data.domain}
onChange={onChange} onChange={onChange}
/> />
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "description")} error={!!formErrors.description}
fullWidth fullWidth
name="description" name="description"
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Store Description" defaultMessage: "Store Description"
})} })}
helperText={ helperText={
getFieldError(errors, "description")?.message || getShopErrorMessage(formErrors.description, intl) ||
intl.formatMessage({ intl.formatMessage({
defaultMessage: defaultMessage:
"Store description is shown on taskbar after your store name" "Store description is shown on taskbar after your store name"

View file

@ -11,8 +11,10 @@ import Form from "@saleor/components/Form";
import { FormSpacer } from "@saleor/components/FormSpacer"; import { FormSpacer } from "@saleor/components/FormSpacer";
import SingleSelectField from "@saleor/components/SingleSelectField"; import SingleSelectField from "@saleor/components/SingleSelectField";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import { UserError, DialogProps } from "@saleor/types"; import { DialogProps } from "@saleor/types";
import { getFieldError } from "@saleor/utils/errors"; import { getFieldError, getFormErrors } from "@saleor/utils/errors";
import { ShopErrorFragment } from "@saleor/siteSettings/types/ShopErrorFragment";
import getShopErrorMessage from "@saleor/utils/errors/shop";
import { authorizationKeyTypes } from "../../../misc"; import { authorizationKeyTypes } from "../../../misc";
import { AuthorizationKeyType } from "../../../types/globalTypes"; import { AuthorizationKeyType } from "../../../types/globalTypes";
@ -23,7 +25,7 @@ export interface SiteSettingsKeyDialogForm {
} }
export interface SiteSettingsKeyDialogProps extends DialogProps { export interface SiteSettingsKeyDialogProps extends DialogProps {
errors: UserError[]; errors: ShopErrorFragment[];
initial: SiteSettingsKeyDialogForm; initial: SiteSettingsKeyDialogForm;
onSubmit: (data: SiteSettingsKeyDialogForm) => void; onSubmit: (data: SiteSettingsKeyDialogForm) => void;
} }
@ -37,8 +39,10 @@ const SiteSettingsKeyDialog: React.FC<SiteSettingsKeyDialogProps> = ({
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const formErrors = getFormErrors(["keyType", "key", "password"], errors);
return ( return (
<Dialog onClose={onClose} maxWidth="xs" open={open}> <Dialog onClose={onClose} maxWidth="xs" fullWidth open={open}>
<Form initial={initial} onSubmit={onSubmit}> <Form initial={initial} onSubmit={onSubmit}>
{({ change, data }) => ( {({ change, data }) => (
<> <>
@ -54,37 +58,37 @@ const SiteSettingsKeyDialog: React.FC<SiteSettingsKeyDialogProps> = ({
label: authorizationKeyTypes[key], label: authorizationKeyTypes[key],
value: key value: key
}))} }))}
error={!!getFieldError(errors, "keyType")} error={!!formErrors.keyType}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Authentication type", defaultMessage: "Authentication type",
description: "authentication provider name" description: "authentication provider name"
})} })}
hint={getFieldError(errors, "keyType")?.message} hint={getShopErrorMessage(formErrors.keyType, intl)}
name="type" name="type"
onChange={change} onChange={change}
value={data.type} value={data.type}
/> />
<FormSpacer /> <FormSpacer />
<TextField <TextField
error={!!getFieldError(errors, "key")} error={!!formErrors.key}
fullWidth fullWidth
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Key", defaultMessage: "Key",
description: "authentication provider API key" description: "authentication provider API key"
})} })}
helperText={getFieldError(errors, "key")?.message} helperText={getShopErrorMessage(formErrors.key, intl)}
name="key" name="key"
onChange={change} onChange={change}
value={data.key} value={data.key}
/> />
<FormSpacer /> <FormSpacer />
<TextField <TextField
error={!!getFieldError(errors, "password")} error={!!formErrors.password}
fullWidth fullWidth
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Password" defaultMessage: "Password"
})} })}
helperText={getFieldError(errors, "password")?.message} helperText={getShopErrorMessage(formErrors.password, intl)}
name="password" name="password"
onChange={change} onChange={change}
value={data.password} value={data.password}

View file

@ -9,8 +9,9 @@ import { FormattedMessage, useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import FormSpacer from "@saleor/components/FormSpacer"; import FormSpacer from "@saleor/components/FormSpacer";
import Hr from "@saleor/components/Hr"; import Hr from "@saleor/components/Hr";
import { UserError } from "@saleor/types"; import { getFormErrors } from "@saleor/utils/errors";
import { getFieldError } from "@saleor/utils/errors"; import { ShopErrorFragment } from "@saleor/siteSettings/types/ShopErrorFragment";
import getShopErrorMessage from "@saleor/utils/errors/shop";
export interface SiteSettingsMailingFormData { export interface SiteSettingsMailingFormData {
defaultMailSenderName: string; defaultMailSenderName: string;
@ -19,7 +20,7 @@ export interface SiteSettingsMailingFormData {
} }
interface SiteSettingsMailingProps { interface SiteSettingsMailingProps {
data: SiteSettingsMailingFormData; data: SiteSettingsMailingFormData;
errors: UserError[]; errors: ShopErrorFragment[];
disabled: boolean; disabled: boolean;
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
} }
@ -41,9 +42,19 @@ const useStyles = makeStyles(
const SiteSettingsMailing: React.FC<SiteSettingsMailingProps> = props => { const SiteSettingsMailing: React.FC<SiteSettingsMailingProps> = props => {
const { data, disabled, errors, onChange } = props; const { data, disabled, errors, onChange } = props;
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl(); const intl = useIntl();
const formErrors = getFormErrors(
[
"defaultMailSenderAddress",
"defaultMailSenderName",
"customerSetPasswordUrl"
],
errors
);
return ( return (
<Card> <Card>
<CardTitle <CardTitle
@ -65,29 +76,30 @@ const SiteSettingsMailing: React.FC<SiteSettingsMailingProps> = props => {
</Typography> </Typography>
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "defaultMailSenderAddress")} error={!!formErrors.defaultMailSenderAddress}
fullWidth fullWidth
name="defaultMailSenderAddress" name="defaultMailSenderAddress"
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Mailing email address" defaultMessage: "Mailing email address"
})} })}
helperText={ helperText={getShopErrorMessage(
getFieldError(errors, "defaultMailSenderAddress")?.message formErrors.defaultMailSenderAddress,
} intl
)}
value={data.defaultMailSenderAddress} value={data.defaultMailSenderAddress}
onChange={onChange} onChange={onChange}
/> />
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "defaultMailSenderName")} error={!!formErrors.defaultMailSenderName}
fullWidth fullWidth
name="defaultMailSenderName" name="defaultMailSenderName"
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Mailing email sender" defaultMessage: "Mailing email sender"
})} })}
helperText={ helperText={
getFieldError(errors, "defaultMailSenderName")?.message || getShopErrorMessage(formErrors.defaultMailSenderName, intl) ||
intl.formatMessage({ intl.formatMessage({
defaultMessage: 'This will be visible as "from" name', defaultMessage: 'This will be visible as "from" name',
description: "email sender" description: "email sender"
@ -101,7 +113,7 @@ const SiteSettingsMailing: React.FC<SiteSettingsMailingProps> = props => {
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "customerSetPasswordUrl")} error={!!formErrors.customerSetPasswordUrl}
fullWidth fullWidth
name="customerSetPasswordUrl" name="customerSetPasswordUrl"
label={intl.formatMessage({ label={intl.formatMessage({
@ -111,7 +123,7 @@ const SiteSettingsMailing: React.FC<SiteSettingsMailingProps> = props => {
defaultMessage: "URL address" defaultMessage: "URL address"
})} })}
helperText={ helperText={
getFieldError(errors, "customerSetPasswordUrl")?.message || getShopErrorMessage(formErrors.customerSetPasswordUrl, intl) ||
intl.formatMessage({ intl.formatMessage({
defaultMessage: defaultMessage:
"This URL will be used as a main URL for password resets. It will be sent via email." "This URL will be used as a main URL for password resets. It will be sent via email."

View file

@ -14,9 +14,9 @@ import SaveButtonBar from "@saleor/components/SaveButtonBar";
import useAddressValidation from "@saleor/hooks/useAddressValidation"; import useAddressValidation from "@saleor/hooks/useAddressValidation";
import useStateFromProps from "@saleor/hooks/useStateFromProps"; import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { commonMessages, sectionNames } from "@saleor/intl"; import { commonMessages, sectionNames } from "@saleor/intl";
import { UserError } from "@saleor/types";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler"; import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import { mapCountriesToChoices } from "@saleor/utils/maps"; import { mapCountriesToChoices } from "@saleor/utils/maps";
import { ShopErrorFragment } from "@saleor/siteSettings/types/ShopErrorFragment";
import { maybe } from "../../../misc"; import { maybe } from "../../../misc";
import { AuthorizationKeyType } from "../../../types/globalTypes"; import { AuthorizationKeyType } from "../../../types/globalTypes";
import { SiteSettings_shop } from "../../types/SiteSettings"; import { SiteSettings_shop } from "../../types/SiteSettings";
@ -48,7 +48,7 @@ export interface SiteSettingsPageFormData
export interface SiteSettingsPageProps { export interface SiteSettingsPageProps {
disabled: boolean; disabled: boolean;
errors: UserError[]; errors: ShopErrorFragment[];
shop: SiteSettings_shop; shop: SiteSettings_shop;
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
onBack: () => void; onBack: () => void;
@ -127,8 +127,6 @@ const SiteSettingsPage: React.FC<SiteSettingsPageProps> = props => {
name: maybe(() => shop.name, "") name: maybe(() => shop.name, "")
}; };
const formErrors = [...errors, ...validationErrors];
return ( return (
<Form <Form
initial={initialForm} initial={initialForm}
@ -141,9 +139,7 @@ const SiteSettingsPage: React.FC<SiteSettingsPageProps> = props => {
confirmLeave confirmLeave
> >
{({ change, data, hasChanged, submit }) => { {({ change, data, hasChanged, submit }) => {
const countryChoices = mapCountriesToChoices( const countryChoices = mapCountriesToChoices(shop?.countries || []);
maybe(() => shop.countries, [])
);
const handleCountryChange = createSingleAutocompleteSelectHandler( const handleCountryChange = createSingleAutocompleteSelectHandler(
change, change,
setDisplayCountry, setDisplayCountry,
@ -169,7 +165,7 @@ const SiteSettingsPage: React.FC<SiteSettingsPageProps> = props => {
</div> </div>
<SiteSettingsDetails <SiteSettingsDetails
data={data} data={data}
errors={formErrors} errors={errors}
disabled={disabled} disabled={disabled}
onChange={change} onChange={change}
/> />
@ -187,7 +183,7 @@ const SiteSettingsPage: React.FC<SiteSettingsPageProps> = props => {
</div> </div>
<SiteSettingsMailing <SiteSettingsMailing
data={data} data={data}
errors={formErrors} errors={errors}
disabled={disabled} disabled={disabled}
onChange={change} onChange={change}
/> />
@ -208,7 +204,7 @@ const SiteSettingsPage: React.FC<SiteSettingsPageProps> = props => {
data={data} data={data}
displayCountry={displayCountry} displayCountry={displayCountry}
countries={countryChoices} countries={countryChoices}
errors={formErrors} errors={[...errors, ...validationErrors]}
disabled={disabled} disabled={disabled}
onChange={change} onChange={change}
onCountryChange={handleCountryChange} onCountryChange={handleCountryChange}

View file

@ -16,16 +16,22 @@ import {
ShopSettingsUpdateVariables ShopSettingsUpdateVariables
} from "./types/ShopSettingsUpdate"; } from "./types/ShopSettingsUpdate";
const shopErrorFragment = gql`
fragment ShopErrorFragment on ShopError {
code
field
}
`;
const authorizationKeyAdd = gql` const authorizationKeyAdd = gql`
${shopErrorFragment}
${shopFragment} ${shopFragment}
mutation AuthorizationKeyAdd( mutation AuthorizationKeyAdd(
$input: AuthorizationKeyInput! $input: AuthorizationKeyInput!
$keyType: AuthorizationKeyType! $keyType: AuthorizationKeyType!
) { ) {
authorizationKeyAdd(input: $input, keyType: $keyType) { authorizationKeyAdd(input: $input, keyType: $keyType) {
errors { errors: shopErrors {
field ...ShopErrorFragment
message
} }
shop { shop {
...ShopFragment ...ShopFragment
@ -39,12 +45,12 @@ export const TypedAuthorizationKeyAdd = TypedMutation<
>(authorizationKeyAdd); >(authorizationKeyAdd);
const authorizationKeyDelete = gql` const authorizationKeyDelete = gql`
${shopErrorFragment}
${shopFragment} ${shopFragment}
mutation AuthorizationKeyDelete($keyType: AuthorizationKeyType!) { mutation AuthorizationKeyDelete($keyType: AuthorizationKeyType!) {
authorizationKeyDelete(keyType: $keyType) { authorizationKeyDelete(keyType: $keyType) {
errors { errors: shopErrors {
field ...ShopErrorFragment
message
} }
shop { shop {
...ShopFragment ...ShopFragment
@ -58,6 +64,7 @@ export const TypedAuthorizationKeyDelete = TypedMutation<
>(authorizationKeyDelete); >(authorizationKeyDelete);
const shopSettingsUpdate = gql` const shopSettingsUpdate = gql`
${shopErrorFragment}
${shopFragment} ${shopFragment}
${fragmentAddress} ${fragmentAddress}
mutation ShopSettingsUpdate( mutation ShopSettingsUpdate(
@ -66,18 +73,16 @@ const shopSettingsUpdate = gql`
$addressInput: AddressInput $addressInput: AddressInput
) { ) {
shopSettingsUpdate(input: $shopSettingsInput) { shopSettingsUpdate(input: $shopSettingsInput) {
errors { errors: shopErrors {
field ...ShopErrorFragment
message
} }
shop { shop {
...ShopFragment ...ShopFragment
} }
} }
shopDomainUpdate(input: $shopDomainInput) { shopDomainUpdate(input: $shopDomainInput) {
errors { errors: shopErrors {
field ...ShopErrorFragment
message
} }
shop { shop {
domain { domain {
@ -87,9 +92,8 @@ const shopSettingsUpdate = gql`
} }
} }
shopAddressUpdate(input: $addressInput) { shopAddressUpdate(input: $addressInput) {
errors { errors: shopErrors {
field ...ShopErrorFragment
message
} }
shop { shop {
companyAddress { companyAddress {

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 { AuthorizationKeyInput, AuthorizationKeyType } from "./../../types/globalTypes"; import { AuthorizationKeyInput, AuthorizationKeyType, ShopErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: AuthorizationKeyAdd // GraphQL mutation operation: AuthorizationKeyAdd
// ==================================================== // ====================================================
export interface AuthorizationKeyAdd_authorizationKeyAdd_errors { export interface AuthorizationKeyAdd_authorizationKeyAdd_errors {
__typename: "Error"; __typename: "ShopError";
code: ShopErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface AuthorizationKeyAdd_authorizationKeyAdd_shop_authorizationKeys { export interface AuthorizationKeyAdd_authorizationKeyAdd_shop_authorizationKeys {

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 { AuthorizationKeyType } from "./../../types/globalTypes"; import { AuthorizationKeyType, ShopErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: AuthorizationKeyDelete // GraphQL mutation operation: AuthorizationKeyDelete
// ==================================================== // ====================================================
export interface AuthorizationKeyDelete_authorizationKeyDelete_errors { export interface AuthorizationKeyDelete_authorizationKeyDelete_errors {
__typename: "Error"; __typename: "ShopError";
code: ShopErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface AuthorizationKeyDelete_authorizationKeyDelete_shop_authorizationKeys { export interface AuthorizationKeyDelete_authorizationKeyDelete_shop_authorizationKeys {

View file

@ -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;
}

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 { SiteDomainInput, ShopSettingsInput, AddressInput, AuthorizationKeyType } from "./../../types/globalTypes"; import { SiteDomainInput, ShopSettingsInput, AddressInput, ShopErrorCode, AuthorizationKeyType } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: ShopSettingsUpdate // GraphQL mutation operation: ShopSettingsUpdate
// ==================================================== // ====================================================
export interface ShopSettingsUpdate_shopSettingsUpdate_errors { export interface ShopSettingsUpdate_shopSettingsUpdate_errors {
__typename: "Error"; __typename: "ShopError";
code: ShopErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface ShopSettingsUpdate_shopSettingsUpdate_shop_authorizationKeys { export interface ShopSettingsUpdate_shopSettingsUpdate_shop_authorizationKeys {
@ -73,9 +73,9 @@ export interface ShopSettingsUpdate_shopSettingsUpdate {
} }
export interface ShopSettingsUpdate_shopDomainUpdate_errors { export interface ShopSettingsUpdate_shopDomainUpdate_errors {
__typename: "Error"; __typename: "ShopError";
code: ShopErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface ShopSettingsUpdate_shopDomainUpdate_shop_domain { export interface ShopSettingsUpdate_shopDomainUpdate_shop_domain {
@ -96,9 +96,9 @@ export interface ShopSettingsUpdate_shopDomainUpdate {
} }
export interface ShopSettingsUpdate_shopAddressUpdate_errors { export interface ShopSettingsUpdate_shopAddressUpdate_errors {
__typename: "Error"; __typename: "ShopError";
code: ShopErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface ShopSettingsUpdate_shopAddressUpdate_shop_companyAddress_country { export interface ShopSettingsUpdate_shopAddressUpdate_shop_companyAddress_country {

View file

@ -7,7 +7,7 @@ import { commonMessages, sectionNames } from "@saleor/intl";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { configurationMenuUrl } from "../../configuration"; import { configurationMenuUrl } from "../../configuration";
import { findInEnum, maybe } from "../../misc"; import { findInEnum } from "../../misc";
import { AuthorizationKeyType, CountryCode } from "../../types/globalTypes"; import { AuthorizationKeyType, CountryCode } from "../../types/globalTypes";
import SiteSettingsKeyDialog, { import SiteSettingsKeyDialog, {
SiteSettingsKeyDialogForm SiteSettingsKeyDialogForm
@ -37,7 +37,7 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
const intl = useIntl(); const intl = useIntl();
const handleAddKeySuccess = (data: AuthorizationKeyAdd) => { const handleAddKeySuccess = (data: AuthorizationKeyAdd) => {
if (!maybe(() => data.authorizationKeyAdd.errors.length)) { if (data.authorizationKeyAdd.errors.length === 0) {
notify({ notify({
text: intl.formatMessage(commonMessages.savedChanges) text: intl.formatMessage(commonMessages.savedChanges)
}); });
@ -45,7 +45,7 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
} }
}; };
const handleDeleteKeySuccess = (data: AuthorizationKeyDelete) => { const handleDeleteKeySuccess = (data: AuthorizationKeyDelete) => {
if (!maybe(() => data.authorizationKeyDelete.errors.length)) { if (data.authorizationKeyDelete.errors.length === 0) {
notify({ notify({
text: intl.formatMessage(commonMessages.savedChanges) text: intl.formatMessage(commonMessages.savedChanges)
}); });
@ -64,12 +64,9 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
}; };
const handleSiteSettingsSuccess = (data: ShopSettingsUpdate) => { const handleSiteSettingsSuccess = (data: ShopSettingsUpdate) => {
if ( if (
(!data.shopDomainUpdate.errors || data.shopDomainUpdate.errors.length === 0 &&
data.shopDomainUpdate.errors.length === 0) && data.shopSettingsUpdate.errors.length === 0 &&
(!data.shopSettingsUpdate.errors || data.shopAddressUpdate.errors.length === 0
data.shopSettingsUpdate.errors.length === 0) &&
(!data.shopAddressUpdate.errors ||
data.shopAddressUpdate.errors.length === 0)
) { ) {
notify({ notify({
text: intl.formatMessage(commonMessages.savedChanges) text: intl.formatMessage(commonMessages.savedChanges)
@ -89,21 +86,12 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
> >
{(updateShopSettings, updateShopSettingsOpts) => { {(updateShopSettings, updateShopSettingsOpts) => {
const errors = [ const errors = [
...maybe( ...(updateShopSettingsOpts.data?.shopDomainUpdate
() => .errors || []),
updateShopSettingsOpts.data.shopDomainUpdate.errors, ...(updateShopSettingsOpts.data?.shopSettingsUpdate
[] .errors || []),
), ...(updateShopSettingsOpts.data?.shopAddressUpdate
...maybe( .errors || [])
() =>
updateShopSettingsOpts.data.shopSettingsUpdate.errors,
[]
),
...maybe(
() =>
updateShopSettingsOpts.data.shopAddressUpdate.errors,
[]
)
]; ];
const loading = const loading =
siteSettings.loading || siteSettings.loading ||
@ -165,7 +153,7 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
<SiteSettingsPage <SiteSettingsPage
disabled={loading} disabled={loading}
errors={errors} errors={errors}
shop={maybe(() => siteSettings.data.shop)} shop={siteSettings.data?.shop}
onBack={() => navigate(configurationMenuUrl)} onBack={() => navigate(configurationMenuUrl)}
onKeyAdd={() => onKeyAdd={() =>
navigate( navigate(
@ -183,12 +171,10 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
saveButtonBarState={updateShopSettingsOpts.status} saveButtonBarState={updateShopSettingsOpts.status}
/> />
<SiteSettingsKeyDialog <SiteSettingsKeyDialog
errors={maybe( errors={
() => addAuthorizationKeyOpts.data?.authorizationKeyAdd
addAuthorizationKeyOpts.data.authorizationKeyAdd .errors || []
.errors, }
[]
)}
initial={{ initial={{
key: "", key: "",
password: "", password: "",

37
src/utils/errors/shop.ts Normal file
View file

@ -0,0 +1,37 @@
import { IntlShape, defineMessages } from "react-intl";
import { ShopErrorFragment } from "@saleor/siteSettings/types/ShopErrorFragment";
import { ShopErrorCode } from "@saleor/types/globalTypes";
import { commonMessages } from "@saleor/intl";
import commonErrorMessages from "./common";
const messages = defineMessages({
alreadyExists: {
defaultMessage: "Authorization key with this type already exists",
description: "add authorization key error"
}
});
function getShopErrorMessage(
err: Omit<ShopErrorFragment, "__typename"> | undefined,
intl: IntlShape
): string {
if (err) {
switch (err.code) {
case ShopErrorCode.ALREADY_EXISTS:
return intl.formatMessage(messages.alreadyExists);
case ShopErrorCode.GRAPHQL_ERROR:
return intl.formatMessage(commonErrorMessages.graphqlError);
case ShopErrorCode.REQUIRED:
return intl.formatMessage(commonMessages.requiredField);
case ShopErrorCode.INVALID:
return intl.formatMessage(commonErrorMessages.invalid);
default:
return intl.formatMessage(commonErrorMessages.unknownError);
}
}
return undefined;
}
export default getShopErrorMessage;