Fix strict null checks in webhooks (#2678)
* Fix strict null errors in webhooks * Disable strict null checks * Update snapshots * Add migration comment in tsconfig * Fix 404 on loading * Fix loading case
This commit is contained in:
parent
c46ec15e14
commit
e900f2e1df
19 changed files with 385 additions and 874 deletions
|
@ -1,6 +1,6 @@
|
|||
import { gql } from "@apollo/client";
|
||||
|
||||
export const webhooksFragment = gql`
|
||||
export const webhookFragment = gql`
|
||||
fragment Webhook on Webhook {
|
||||
id
|
||||
name
|
||||
|
@ -12,8 +12,16 @@ export const webhooksFragment = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
export const webhooksDetailsFragment = gql`
|
||||
fragment WebhooksDetails on Webhook {
|
||||
export const webhookDetailsFragment = gql`
|
||||
fragment WebhookDetails on Webhook {
|
||||
...Webhook
|
||||
syncEvents {
|
||||
eventType
|
||||
}
|
||||
asyncEvents {
|
||||
eventType
|
||||
}
|
||||
secretKey
|
||||
targetUrl
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -2784,9 +2784,17 @@ export const WarehouseDetailsFragmentDoc = gql`
|
|||
}
|
||||
${WarehouseWithShippingFragmentDoc}
|
||||
${AddressFragmentDoc}`;
|
||||
export const WebhooksDetailsFragmentDoc = gql`
|
||||
fragment WebhooksDetails on Webhook {
|
||||
export const WebhookDetailsFragmentDoc = gql`
|
||||
fragment WebhookDetails on Webhook {
|
||||
...Webhook
|
||||
syncEvents {
|
||||
eventType
|
||||
}
|
||||
asyncEvents {
|
||||
eventType
|
||||
}
|
||||
secretKey
|
||||
targetUrl
|
||||
}
|
||||
${WebhookFragmentDoc}`;
|
||||
export const AppCreateDocument = gql`
|
||||
|
@ -16970,12 +16978,12 @@ export const WebhookCreateDocument = gql`
|
|||
...WebhookError
|
||||
}
|
||||
webhook {
|
||||
...WebhooksDetails
|
||||
...WebhookDetails
|
||||
}
|
||||
}
|
||||
}
|
||||
${WebhookErrorFragmentDoc}
|
||||
${WebhooksDetailsFragmentDoc}`;
|
||||
${WebhookDetailsFragmentDoc}`;
|
||||
export type WebhookCreateMutationFn = Apollo.MutationFunction<Types.WebhookCreateMutation, Types.WebhookCreateMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -17009,12 +17017,12 @@ export const WebhookUpdateDocument = gql`
|
|||
...WebhookError
|
||||
}
|
||||
webhook {
|
||||
...WebhooksDetails
|
||||
...WebhookDetails
|
||||
}
|
||||
}
|
||||
}
|
||||
${WebhookErrorFragmentDoc}
|
||||
${WebhooksDetailsFragmentDoc}`;
|
||||
${WebhookDetailsFragmentDoc}`;
|
||||
export type WebhookUpdateMutationFn = Apollo.MutationFunction<Types.WebhookUpdateMutation, Types.WebhookUpdateMutationVariables>;
|
||||
|
||||
/**
|
||||
|
@ -17080,18 +17088,10 @@ export type WebhookDeleteMutationOptions = Apollo.BaseMutationOptions<Types.Webh
|
|||
export const WebhookDetailsDocument = gql`
|
||||
query WebhookDetails($id: ID!) {
|
||||
webhook(id: $id) {
|
||||
...Webhook
|
||||
syncEvents {
|
||||
eventType
|
||||
}
|
||||
asyncEvents {
|
||||
eventType
|
||||
}
|
||||
secretKey
|
||||
targetUrl
|
||||
...WebhookDetails
|
||||
}
|
||||
}
|
||||
${WebhookFragmentDoc}`;
|
||||
${WebhookDetailsFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __useWebhookDetailsQuery__
|
||||
|
|
|
@ -7451,7 +7451,7 @@ export type WarehouseDetailsFragment = { __typename: 'Warehouse', isPrivate: boo
|
|||
|
||||
export type WebhookFragment = { __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } };
|
||||
|
||||
export type WebhooksDetailsFragment = { __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } };
|
||||
export type WebhookDetailsFragment = { __typename: 'Webhook', secretKey: string | null, targetUrl: string, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } };
|
||||
|
||||
export type WeightFragment = { __typename: 'Weight', unit: WeightUnitsEnum, value: number };
|
||||
|
||||
|
@ -9410,7 +9410,7 @@ export type WebhookCreateMutationVariables = Exact<{
|
|||
}>;
|
||||
|
||||
|
||||
export type WebhookCreateMutation = { __typename: 'Mutation', webhookCreate: { __typename: 'WebhookCreate', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }>, webhook: { __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } } | null } | null };
|
||||
export type WebhookCreateMutation = { __typename: 'Mutation', webhookCreate: { __typename: 'WebhookCreate', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }>, webhook: { __typename: 'Webhook', secretKey: string | null, targetUrl: string, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } } | null } | null };
|
||||
|
||||
export type WebhookUpdateMutationVariables = Exact<{
|
||||
id: Scalars['ID'];
|
||||
|
@ -9418,7 +9418,7 @@ export type WebhookUpdateMutationVariables = Exact<{
|
|||
}>;
|
||||
|
||||
|
||||
export type WebhookUpdateMutation = { __typename: 'Mutation', webhookUpdate: { __typename: 'WebhookUpdate', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }>, webhook: { __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } } | null } | null };
|
||||
export type WebhookUpdateMutation = { __typename: 'Mutation', webhookUpdate: { __typename: 'WebhookUpdate', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }>, webhook: { __typename: 'Webhook', secretKey: string | null, targetUrl: string, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } } | null } | null };
|
||||
|
||||
export type WebhookDeleteMutationVariables = Exact<{
|
||||
id: Scalars['ID'];
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,7 +7,7 @@ import { MultiAutocompleteChoiceType } from "./components/MultiAutocompleteSelec
|
|||
|
||||
export interface UserError {
|
||||
field: string | null;
|
||||
message?: string;
|
||||
message?: string | null;
|
||||
}
|
||||
|
||||
export interface DialogProps {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { getAppDefaultUri, getAppMountUri } from "@saleor/config";
|
|||
import isArray from "lodash/isArray";
|
||||
import { stringify } from "qs";
|
||||
|
||||
export function stringifyQs(params: {}, arrayFormat?: string): string {
|
||||
export function stringifyQs(params: unknown, arrayFormat?: string): string {
|
||||
return stringify(params, {
|
||||
arrayFormat: arrayFormat || "indices",
|
||||
});
|
||||
|
|
|
@ -17,4 +17,6 @@ const props: WebhookDeleteDialogProps = {
|
|||
storiesOf("Views / Apps / Webhooks / Delete webhook", module)
|
||||
.addDecorator(Decorator)
|
||||
.add("default", () => <WebhookDeleteDialog {...props} />)
|
||||
.add("unnamed webhook", () => <WebhookDeleteDialog {...props} name={null} />);
|
||||
.add("unnamed webhook", () => (
|
||||
<WebhookDeleteDialog {...props} name={undefined} />
|
||||
));
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import { DialogContentText } from "@material-ui/core";
|
||||
import ActionDialog from "@saleor/components/ActionDialog";
|
||||
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||
import { getStringOrPlaceholder } from "@saleor/misc";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
export interface WebhookDeleteDialogProps {
|
||||
confirmButtonState: ConfirmButtonTransitionState;
|
||||
open: boolean;
|
||||
name: string;
|
||||
name?: string;
|
||||
onClose: () => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
@ -36,7 +35,7 @@ const WebhookDeleteDialog: React.FC<WebhookDeleteDialogProps> = ({
|
|||
variant="delete"
|
||||
>
|
||||
<DialogContentText>
|
||||
{["", null].includes(name) ? (
|
||||
{!name ? (
|
||||
<FormattedMessage
|
||||
id="hS+ZjH"
|
||||
defaultMessage="Are you sure you want to delete this webhook?"
|
||||
|
@ -48,7 +47,7 @@ const WebhookDeleteDialog: React.FC<WebhookDeleteDialogProps> = ({
|
|||
defaultMessage="Are you sure you want to delete {name}?"
|
||||
description="delete webhook"
|
||||
values={{
|
||||
name: <strong>{getStringOrPlaceholder(name)}</strong>,
|
||||
name: <strong>{name}</strong>,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -21,9 +21,6 @@ storiesOf("Views / Apps / Webhooks / Webhook details", module)
|
|||
.addDecorator(Decorator)
|
||||
.add("default", () => <WebhookDetailsPage {...props} />)
|
||||
.add("undefined", () => <WebhookDetailsPage {...props} webhook={undefined} />)
|
||||
.add("unnamed", () => (
|
||||
<WebhookDetailsPage {...props} webhook={{ ...webhook, name: null }} />
|
||||
))
|
||||
.add("loading", () => (
|
||||
<WebhookDetailsPage {...props} webhook={undefined} disabled={true} />
|
||||
))
|
||||
|
|
|
@ -7,7 +7,7 @@ import Grid from "@saleor/components/Grid";
|
|||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import Savebar from "@saleor/components/Savebar";
|
||||
import {
|
||||
WebhookDetailsQuery,
|
||||
WebhookDetailsFragment,
|
||||
WebhookErrorFragment,
|
||||
WebhookEventTypeAsyncEnum,
|
||||
WebhookEventTypeSyncEnum,
|
||||
|
@ -44,7 +44,7 @@ export interface WebhookDetailsPageProps {
|
|||
appId: string;
|
||||
disabled: boolean;
|
||||
errors: WebhookErrorFragment[];
|
||||
webhook?: WebhookDetailsQuery["webhook"];
|
||||
webhook?: WebhookDetailsFragment | null;
|
||||
saveButtonBarState: ConfirmButtonTransitionState;
|
||||
onSubmit: (data: FormData) => void;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { customAppUrl } from "@saleor/apps/urls";
|
||||
import { appsListUrl, customAppUrl } from "@saleor/apps/urls";
|
||||
import { Backlink } from "@saleor/components/Backlink";
|
||||
import Container from "@saleor/components/Container";
|
||||
import Form from "@saleor/components/Form";
|
||||
|
@ -7,7 +7,7 @@ import Grid from "@saleor/components/Grid";
|
|||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import Savebar from "@saleor/components/Savebar";
|
||||
import {
|
||||
WebhookDetailsQuery,
|
||||
WebhookDetailsFragment,
|
||||
WebhookErrorFragment,
|
||||
WebhookEventTypeAsyncEnum,
|
||||
WebhookEventTypeSyncEnum,
|
||||
|
@ -44,7 +44,7 @@ export interface WebhookDetailsPageProps {
|
|||
appName: string;
|
||||
disabled: boolean;
|
||||
errors: WebhookErrorFragment[];
|
||||
webhook?: WebhookDetailsQuery["webhook"];
|
||||
webhook?: WebhookDetailsFragment;
|
||||
saveButtonBarState: ConfirmButtonTransitionState;
|
||||
onSubmit: (data: WebhookFormData) => SubmitPromise<any[]>;
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ const WebhookDetailsPage: React.FC<WebhookDetailsPageProps> = ({
|
|||
targetUrl: webhook?.targetUrl || "",
|
||||
};
|
||||
|
||||
const backUrl = webhook ? customAppUrl(webhook.app.id) : appsListUrl();
|
||||
|
||||
return (
|
||||
<Form confirmLeave initial={initialForm} onSubmit={onSubmit}>
|
||||
{({ data, submit, change }) => {
|
||||
|
@ -93,7 +95,7 @@ const WebhookDetailsPage: React.FC<WebhookDetailsPageProps> = ({
|
|||
|
||||
return (
|
||||
<Container>
|
||||
<Backlink href={customAppUrl(webhook?.app?.id)}>{appName}</Backlink>
|
||||
<Backlink href={backUrl}>{appName}</Backlink>
|
||||
<PageHeader title={getHeaderTitle(intl, webhook)} />
|
||||
<Grid>
|
||||
<div>
|
||||
|
@ -123,7 +125,7 @@ const WebhookDetailsPage: React.FC<WebhookDetailsPageProps> = ({
|
|||
<Savebar
|
||||
disabled={disabled}
|
||||
state={saveButtonBarState}
|
||||
onCancel={() => navigate(customAppUrl(webhook.app.id))}
|
||||
onCancel={() => navigate(backUrl)}
|
||||
onSubmit={submit}
|
||||
/>
|
||||
</Container>
|
||||
|
|
|
@ -6,7 +6,7 @@ import Skeleton from "@saleor/components/Skeleton";
|
|||
import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper";
|
||||
import TableCellHeader from "@saleor/components/TableCellHeader";
|
||||
import TableRowLink from "@saleor/components/TableRowLink";
|
||||
import { AppQuery } from "@saleor/graphql";
|
||||
import { WebhookFragment } from "@saleor/graphql";
|
||||
import {
|
||||
commonMessages,
|
||||
commonStatusMessages,
|
||||
|
@ -24,7 +24,7 @@ import { messages } from "./messages";
|
|||
import { useStyles } from "./styles";
|
||||
|
||||
export interface WebhooksListProps {
|
||||
webhooks: AppQuery["app"]["webhooks"];
|
||||
webhooks: WebhookFragment[];
|
||||
onRemove: (id: string) => void;
|
||||
createHref?: string;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { WebhookDetailsQuery } from "@saleor/graphql";
|
||||
import { WebhookDetailsFragment } from "@saleor/graphql";
|
||||
|
||||
export const webhook: WebhookDetailsQuery["webhook"] = {
|
||||
export const webhook: WebhookDetailsFragment = {
|
||||
__typename: "Webhook",
|
||||
app: {
|
||||
__typename: "App",
|
||||
|
|
|
@ -7,7 +7,7 @@ export const webhookCreate = gql`
|
|||
...WebhookError
|
||||
}
|
||||
webhook {
|
||||
...WebhooksDetails
|
||||
...WebhookDetails
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ export const webhookUpdate = gql`
|
|||
...WebhookError
|
||||
}
|
||||
webhook {
|
||||
...WebhooksDetails
|
||||
...WebhookDetails
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,15 +3,7 @@ import { gql } from "@apollo/client";
|
|||
export const webhooksDetails = gql`
|
||||
query WebhookDetails($id: ID!) {
|
||||
webhook(id: $id) {
|
||||
...Webhook
|
||||
syncEvents {
|
||||
eventType
|
||||
}
|
||||
asyncEvents {
|
||||
eventType
|
||||
}
|
||||
secretKey
|
||||
targetUrl
|
||||
...WebhookDetails
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -7,8 +7,8 @@ import {
|
|||
} from "@saleor/graphql";
|
||||
import React from "react";
|
||||
|
||||
export function isUnnamed(webhook: WebhookFragment): boolean {
|
||||
return ["", null].includes(webhook?.name);
|
||||
export function isUnnamed(webhook: WebhookFragment | undefined): boolean {
|
||||
return !webhook?.name;
|
||||
}
|
||||
|
||||
type WebhookEventType = WebhookEventTypeSyncEnum | WebhookEventTypeAsyncEnum;
|
||||
|
|
|
@ -27,12 +27,13 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = ({ id }) => {
|
|||
|
||||
const [webhookCreate, webhookCreateOpts] = useWebhookCreateMutation({
|
||||
onCompleted: data => {
|
||||
if (data.webhookCreate.errors.length === 0) {
|
||||
const webhook = data.webhookCreate?.webhook;
|
||||
if (webhook && data?.webhookCreate?.errors.length === 0) {
|
||||
notify({
|
||||
status: "success",
|
||||
text: intl.formatMessage(commonMessages.savedChanges),
|
||||
});
|
||||
navigate(webhookUrl(data.webhookCreate.webhook.id));
|
||||
navigate(webhookUrl(webhook.id));
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -68,10 +69,10 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = ({ id }) => {
|
|||
})}
|
||||
/>
|
||||
<WebhookDetailsPage
|
||||
appName={data?.app?.name}
|
||||
appName={data?.app?.name ?? ""}
|
||||
appId={id}
|
||||
disabled={false}
|
||||
errors={webhookCreateOpts.data?.webhookCreate.errors || []}
|
||||
errors={webhookCreateOpts.data?.webhookCreate?.errors ?? []}
|
||||
onSubmit={handleSubmit}
|
||||
saveButtonBarState={webhookCreateOpts.status}
|
||||
/>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { customAppUrl } from "@saleor/apps/urls";
|
||||
import { appsListUrl } from "@saleor/apps/urls";
|
||||
import NotFoundPage from "@saleor/components/NotFoundPage";
|
||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||
import {
|
||||
|
@ -31,7 +31,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({ id }) => {
|
|||
const errors = data.webhookUpdate?.errors;
|
||||
const webhook = data.webhookUpdate?.webhook;
|
||||
|
||||
if (errors.length === 0 && webhook) {
|
||||
if (errors?.length === 0 && webhook) {
|
||||
notify({
|
||||
status: "success",
|
||||
text: intl.formatMessage(commonMessages.savedChanges),
|
||||
|
@ -41,11 +41,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({ id }) => {
|
|||
});
|
||||
|
||||
const webhook = webhookDetails?.webhook;
|
||||
const formErrors = webhookUpdateOpts.data?.webhookUpdate.errors || [];
|
||||
|
||||
if (webhook === null) {
|
||||
return <NotFoundPage backHref={customAppUrl(webhook.app.id)} />;
|
||||
}
|
||||
const formErrors = webhookUpdateOpts.data?.webhookUpdate?.errors || [];
|
||||
|
||||
const handleSubmit = (data: WebhookFormData) =>
|
||||
extractMutationErrors(
|
||||
|
@ -67,6 +63,9 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({ id }) => {
|
|||
},
|
||||
}),
|
||||
);
|
||||
if (!webhook && !loading) {
|
||||
return <NotFoundPage backHref={appsListUrl()} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -74,8 +73,8 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({ id }) => {
|
|||
title={getStringOrPlaceholder(webhookDetails?.webhook?.name)}
|
||||
/>
|
||||
<WebhookDetailsPage
|
||||
appId={webhook?.app?.id}
|
||||
appName={webhook?.app?.name}
|
||||
appId={webhook?.app.id ?? ""}
|
||||
appName={webhook?.app.name ?? ""}
|
||||
disabled={loading}
|
||||
errors={formErrors}
|
||||
saveButtonBarState={webhookUpdateOpts.status}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
// Migration to strict null checks is in progress.
|
||||
// https://github.com/saleor/saleor-dashboard/issues/2584
|
||||
"strictNullChecks": false,
|
||||
"esModuleInterop": true,
|
||||
"jsx": "react",
|
||||
"lib": ["es2017", "dom", "esnext"],
|
||||
|
|
Loading…
Reference in a new issue