Fix webhook api errors

This commit is contained in:
Krzysztof Bialoglowicz 2019-10-18 14:01:26 +02:00
parent 4f12124b4f
commit 9a5f95b68f
11 changed files with 114 additions and 22 deletions

View file

@ -286,6 +286,14 @@ export enum VoucherTypeEnum {
SPECIFIC_PRODUCT = "SPECIFIC_PRODUCT",
}
export enum WebhookErrorCode {
GRAPHQL_ERROR = "GRAPHQL_ERROR",
INVALID = "INVALID",
NOT_FOUND = "NOT_FOUND",
REQUIRED = "REQUIRED",
UNIQUE = "UNIQUE",
}
export enum WebhookEventTypeEnum {
ANY_EVENTS = "ANY_EVENTS",
CUSTOMER_CREATED = "CUSTOMER_CREATED",

View file

@ -9,12 +9,12 @@ import SaveButtonBar from "@saleor/components/SaveButtonBar";
import { SearchServiceAccount_search_edges_node } from "@saleor/containers/SearchServiceAccount/types/SearchServiceAccount";
import { sectionNames } from "@saleor/intl";
import { maybe } from "@saleor/misc";
import { UserError } from "@saleor/types";
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
import WebhookInfo from "@saleor/webhooks/components/WebhookInfo";
import WebhookStatus from "@saleor/webhooks/components/WebhookStatus";
import { WebhookCreate_webhookCreate_webhookErrors } from "@saleor/webhooks/types/WebhookCreate";
import React from "react";
import { useIntl } from "react-intl";
@ -31,7 +31,7 @@ export interface FormData {
export interface WebhookCreatePageProps {
disabled: boolean;
errors: UserError[];
errors: WebhookCreate_webhookCreate_webhookErrors[];
services?: SearchServiceAccount_search_edges_node[];
saveButtonBarState: ConfirmButtonTransitionState;
fetchServiceAccounts: (data: string) => void;
@ -39,9 +39,9 @@ export interface WebhookCreatePageProps {
onSubmit: (data: FormData) => void;
}
const WebhookCreatePage: React.StatelessComponent<WebhookCreatePageProps> = ({
const WebhookCreatePage: React.FC<WebhookCreatePageProps> = ({
disabled,
errors,
errors: apiErrors,
saveButtonBarState,
services,
fetchServiceAccounts,
@ -72,7 +72,7 @@ const WebhookCreatePage: React.StatelessComponent<WebhookCreatePageProps> = ({
);
return (
<Form errors={errors} initial={initialForm} onSubmit={onSubmit}>
<Form errors={apiErrors} initial={initialForm} onSubmit={onSubmit}>
{({ data, errors, hasChanged, submit, change }) => {
const handleServiceSelect = createSingleAutocompleteSelectHandler(
change,
@ -98,6 +98,7 @@ const WebhookCreatePage: React.StatelessComponent<WebhookCreatePageProps> = ({
serviceDisplayValue={selectedServiceAcccount}
services={servicesChoiceList}
fetchServiceAccounts={fetchServiceAccounts}
apiErrors={apiErrors}
errors={errors}
serviceOnChange={handleServiceSelect}
onChange={change}

View file

@ -2,7 +2,7 @@ import { storiesOf } from "@storybook/react";
import React from "react";
import Decorator from "@saleor/storybook/Decorator";
import { formError } from "@saleor/storybook/misc";
import { WebhookErrorCode } from "@saleor/types/globalTypes";
import WebhookCreatePage, { WebhookCreatePageProps } from "./WebhookCreatePage";
const props: WebhookCreatePageProps = {
@ -21,6 +21,15 @@ storiesOf("Views / Webhooks / Create webhook", module)
.add("form errors", () => (
<WebhookCreatePage
{...props}
errors={["name"].map(field => formError(field))}
errors={[
{
code: WebhookErrorCode.INVALID,
field: null
}
].map(error => ({
__typename: "WebhookError",
message: "Generic form error",
...error
}))}
/>
));

View file

@ -4,7 +4,7 @@ import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography";
import makeStyles from "@material-ui/styles/makeStyles";
import React from "react";
import { useIntl } from "react-intl";
import { IntlShape, useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle";
import FormSpacer from "@saleor/components/FormSpacer";
@ -15,9 +15,12 @@ import SingleAutocompleteSelectField, {
import { ChangeEvent } from "@saleor/hooks/useForm";
import { commonMessages } from "@saleor/intl";
import { FormErrors } from "@saleor/types";
import { WebhookErrorCode } from "@saleor/types/globalTypes";
import { WebhookCreate_webhookCreate_webhookErrors } from "@saleor/webhooks/types/WebhookCreate";
import { FormData } from "../WebhooksDetailsPage";
interface WebhookInfoProps {
apiErrors: WebhookCreate_webhookCreate_webhookErrors[];
data: FormData;
disabled: boolean;
serviceDisplayValue: string;
@ -40,6 +43,7 @@ const useStyles = makeStyles(() => ({
}));
const WebhookInfo: React.StatelessComponent<WebhookInfoProps> = ({
apiErrors,
data,
disabled,
services,
@ -51,6 +55,18 @@ const WebhookInfo: React.StatelessComponent<WebhookInfoProps> = ({
}) => {
const classes = useStyles({});
const intl = useIntl();
const translatedErrors = translateErrors(intl);
const serviceAccountsError =
apiErrors.filter(error => error.field === null).length > 0;
function translateErrors(intl: IntlShape) {
return {
[WebhookErrorCode.INVALID]: intl.formatMessage({
defaultMessage: "Missing token or serviceAccount",
description: "webhook service account error"
})
};
}
return (
<Card>
@ -92,6 +108,14 @@ const WebhookInfo: React.StatelessComponent<WebhookInfoProps> = ({
label={intl.formatMessage({
defaultMessage: "Assign to Service Account"
})}
error={serviceAccountsError}
helperText={
serviceAccountsError &&
intl.formatMessage({
defaultMessage: "Missing token or serviceAccount",
description: "webhook service account error"
})
}
name="serviceAccount"
onChange={serviceOnChange}
value={data.serviceAccount}
@ -136,6 +160,18 @@ const WebhookInfo: React.StatelessComponent<WebhookInfoProps> = ({
value={data.secretKey}
onChange={onChange}
/>
{apiErrors.length > 0 && (
<>
<FormSpacer />
{apiErrors
.filter(error => error.field === null)
.map(error => (
<Typography color="error" key={error.code}>
{translatedErrors[error.code]}
</Typography>
))}
</>
)}
</CardContent>
</Card>
);

View file

@ -2,7 +2,7 @@ import { storiesOf } from "@storybook/react";
import React from "react";
import Decorator from "@saleor/storybook/Decorator";
import { formError } from "@saleor/storybook/misc";
import { WebhookErrorCode } from "@saleor/types/globalTypes";
import WebhooksDetailsPage, {
WebhooksDetailsPageProps
} from "./WebhooksDetailsPage";
@ -32,6 +32,15 @@ storiesOf("Views / Webhooks / Webhook details", module)
.add("form errors", () => (
<WebhooksDetailsPage
{...props}
errors={["name"].map(field => formError(field))}
errors={[
{
code: WebhookErrorCode.INVALID,
field: null
}
].map(error => ({
__typename: "WebhookError",
message: "Generic form error",
...error
}))}
/>
));

View file

@ -10,12 +10,12 @@ import { SearchServiceAccount_search_edges_node } from "@saleor/containers/Searc
import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { sectionNames } from "@saleor/intl";
import { maybe } from "@saleor/misc";
import { UserError } from "@saleor/types";
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
import WebhookInfo from "@saleor/webhooks/components/WebhookInfo";
import WebhookStatus from "@saleor/webhooks/components/WebhookStatus";
import { WebhookCreate_webhookCreate_webhookErrors } from "@saleor/webhooks/types/WebhookCreate";
import { WebhookDetails_webhook } from "@saleor/webhooks/types/WebhookDetails";
import React from "react";
@ -34,7 +34,7 @@ export interface FormData {
export interface WebhooksDetailsPageProps {
disabled: boolean;
errors: UserError[];
errors: WebhookCreate_webhookCreate_webhookErrors[];
webhook: WebhookDetails_webhook;
services?: SearchServiceAccount_search_edges_node[];
saveButtonBarState: ConfirmButtonTransitionState;
@ -46,7 +46,7 @@ export interface WebhooksDetailsPageProps {
const WebhooksDetailsPage: React.FC<WebhooksDetailsPageProps> = ({
disabled,
errors,
errors: apiErrors,
webhook,
saveButtonBarState,
services,
@ -83,7 +83,7 @@ const WebhooksDetailsPage: React.FC<WebhooksDetailsPageProps> = ({
[]
);
return (
<Form errors={errors} initial={initialForm} onSubmit={onSubmit}>
<Form errors={apiErrors} initial={initialForm} onSubmit={onSubmit}>
{({ data, errors, hasChanged, submit, change }) => {
const handleServiceSelect = createSingleAutocompleteSelectHandler(
change,
@ -109,6 +109,7 @@ const WebhooksDetailsPage: React.FC<WebhooksDetailsPageProps> = ({
<Grid>
<div>
<WebhookInfo
apiErrors={apiErrors}
data={data}
disabled={disabled}
serviceDisplayValue={selectedServiceAcccounts}

View file

@ -14,6 +14,11 @@ const webhookCreate = gql`
field
message
}
webhookErrors {
code
message
field
}
webhook {
...WebhooksDetailsFragment
}
@ -33,6 +38,11 @@ const webhookUpdate = gql`
field
message
}
webhookErrors {
code
message
field
}
webhook {
...WebhooksDetailsFragment
}

View file

@ -2,7 +2,7 @@
/* eslint-disable */
// This file was automatically generated and should not be edited.
import { WebhookCreateInput } from "./../../types/globalTypes";
import { WebhookCreateInput, WebhookErrorCode } from "./../../types/globalTypes";
// ====================================================
// GraphQL mutation operation: WebhookCreate
@ -14,6 +14,13 @@ export interface WebhookCreate_webhookCreate_errors {
message: string | null;
}
export interface WebhookCreate_webhookCreate_webhookErrors {
__typename: "WebhookError";
code: WebhookErrorCode | null;
message: string | null;
field: string | null;
}
export interface WebhookCreate_webhookCreate_webhook_serviceAccount {
__typename: "ServiceAccount";
id: string;
@ -31,6 +38,7 @@ export interface WebhookCreate_webhookCreate_webhook {
export interface WebhookCreate_webhookCreate {
__typename: "WebhookCreate";
errors: WebhookCreate_webhookCreate_errors[] | null;
webhookErrors: WebhookCreate_webhookCreate_webhookErrors[] | null;
webhook: WebhookCreate_webhookCreate_webhook | null;
}

View file

@ -2,7 +2,7 @@
/* eslint-disable */
// This file was automatically generated and should not be edited.
import { WebhookUpdateInput } from "./../../types/globalTypes";
import { WebhookUpdateInput, WebhookErrorCode } from "./../../types/globalTypes";
// ====================================================
// GraphQL mutation operation: WebhookUpdate
@ -14,6 +14,13 @@ export interface WebhookUpdate_webhookUpdate_errors {
message: string | null;
}
export interface WebhookUpdate_webhookUpdate_webhookErrors {
__typename: "WebhookError";
code: WebhookErrorCode | null;
message: string | null;
field: string | null;
}
export interface WebhookUpdate_webhookUpdate_webhook_serviceAccount {
__typename: "ServiceAccount";
id: string;
@ -31,6 +38,7 @@ export interface WebhookUpdate_webhookUpdate_webhook {
export interface WebhookUpdate_webhookUpdate {
__typename: "WebhookUpdate";
errors: WebhookUpdate_webhookUpdate_errors[] | null;
webhookErrors: WebhookUpdate_webhookUpdate_webhookErrors[] | null;
webhook: WebhookUpdate_webhookUpdate_webhook | null;
}

View file

@ -30,7 +30,7 @@ export const WebhooksCreate: React.StatelessComponent<
const intl = useIntl();
const onSubmit = (data: WebhookCreateData) => {
if (data.webhookCreate.errors.length === 0) {
if (data.webhookCreate.webhookErrors.length === 0) {
notify({
text: intl.formatMessage(commonMessages.savedChanges)
});
@ -64,7 +64,7 @@ export const WebhooksCreate: React.StatelessComponent<
const formTransitionState = getMutationState(
webhookCreateOpts.called,
webhookCreateOpts.loading,
maybe(() => webhookCreateOpts.data.webhookCreate.errors)
maybe(() => webhookCreateOpts.data.webhookCreate.webhookErrors)
);
return (
@ -78,7 +78,7 @@ export const WebhooksCreate: React.StatelessComponent<
<WebhookCreatePage
disabled={false}
errors={maybe(
() => webhookCreateOpts.data.webhookCreate.errors,
() => webhookCreateOpts.data.webhookCreate.webhookErrors,
[]
)}
fetchServiceAccounts={searchServiceAccount}

View file

@ -63,7 +63,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
};
const onWebhookUpdate = (data: WebhookUpdate) => {
if (data.webhookUpdate.errors.length === 0) {
if (data.webhookUpdate.webhookErrors.length === 0) {
notify({
text: intl.formatMessage(commonMessages.savedChanges)
});
@ -83,7 +83,9 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
const formTransitionState = getMutationState(
webhookUpdateOpts.called,
webhookUpdateOpts.loading,
maybe(() => webhookUpdateOpts.data.webhookUpdate.errors)
maybe(
() => webhookUpdateOpts.data.webhookUpdate.webhookErrors
)
);
const handleRemoveConfirm = () =>
@ -94,7 +96,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
});
const formErrors = maybe(
() => webhookUpdateOpts.data.webhookUpdate.errors,
() => webhookUpdateOpts.data.webhookUpdate.webhookErrors,
[]
);