Fix webhook api errors
This commit is contained in:
parent
4f12124b4f
commit
9a5f95b68f
11 changed files with 114 additions and 22 deletions
|
@ -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",
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
}))}
|
||||
/>
|
||||
));
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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
|
||||
}))}
|
||||
/>
|
||||
));
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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,
|
||||
[]
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue