Webhook query dry run (#2960)
This commit is contained in:
parent
7b8ececc3d
commit
6dbb8e4ecc
30 changed files with 3262 additions and 3158 deletions
3763
introspection.json
3763
introspection.json
File diff suppressed because it is too large
Load diff
|
@ -51,6 +51,10 @@
|
||||||
"context": "tabel column header",
|
"context": "tabel column header",
|
||||||
"string": "Total"
|
"string": "Total"
|
||||||
},
|
},
|
||||||
|
"+RffqY": {
|
||||||
|
"context": "Dry run dialog object title",
|
||||||
|
"string": "Select object type to perform dry run on provided query"
|
||||||
|
},
|
||||||
"+RjQjs": {
|
"+RjQjs": {
|
||||||
"context": "return button",
|
"context": "return button",
|
||||||
"string": "Return / Replace order"
|
"string": "Return / Replace order"
|
||||||
|
@ -390,6 +394,10 @@
|
||||||
"context": "selected customer channel subtitle",
|
"context": "selected customer channel subtitle",
|
||||||
"string": "Customer will be sent the gift card code via this channels email address"
|
"string": "Customer will be sent the gift card code via this channels email address"
|
||||||
},
|
},
|
||||||
|
"0u9Ng0": {
|
||||||
|
"context": "Dry run no objects found",
|
||||||
|
"string": "No objects found in the provided query"
|
||||||
|
},
|
||||||
"0vsMRq": {
|
"0vsMRq": {
|
||||||
"context": "delete custom app",
|
"context": "delete custom app",
|
||||||
"string": "Deleting this app, you will delete all the data and webhooks regarding this app."
|
"string": "Deleting this app, you will delete all the data and webhooks regarding this app."
|
||||||
|
@ -800,6 +808,10 @@
|
||||||
"context": "open full-screen",
|
"context": "open full-screen",
|
||||||
"string": "Open"
|
"string": "Open"
|
||||||
},
|
},
|
||||||
|
"48dMqY": {
|
||||||
|
"context": "Dry run trigger button",
|
||||||
|
"string": "Run"
|
||||||
|
},
|
||||||
"4B32Ba": {
|
"4B32Ba": {
|
||||||
"context": "delete page",
|
"context": "delete page",
|
||||||
"string": "Are you sure you want to delete {title}?"
|
"string": "Are you sure you want to delete {title}?"
|
||||||
|
@ -993,6 +1005,10 @@
|
||||||
"context": "tabel column header",
|
"context": "tabel column header",
|
||||||
"string": "Price"
|
"string": "Price"
|
||||||
},
|
},
|
||||||
|
"5b0Boq": {
|
||||||
|
"context": "Dry run items list default message",
|
||||||
|
"string": "Choose the object"
|
||||||
|
},
|
||||||
"5bJ26s": {
|
"5bJ26s": {
|
||||||
"string": "Successfully created page type"
|
"string": "Successfully created page type"
|
||||||
},
|
},
|
||||||
|
@ -1591,6 +1607,10 @@
|
||||||
"context": "sale status",
|
"context": "sale status",
|
||||||
"string": "Active"
|
"string": "Active"
|
||||||
},
|
},
|
||||||
|
"ApNw0L": {
|
||||||
|
"context": "Dry run objects unavailable",
|
||||||
|
"string": "The following objects are currently not available for dry run:"
|
||||||
|
},
|
||||||
"AqHafs": {
|
"AqHafs": {
|
||||||
"context": "provided email input placeholder",
|
"context": "provided email input placeholder",
|
||||||
"string": "Provided email address"
|
"string": "Provided email address"
|
||||||
|
@ -3651,6 +3671,10 @@
|
||||||
"context": "modal button url upload",
|
"context": "modal button url upload",
|
||||||
"string": "Upload URL"
|
"string": "Upload URL"
|
||||||
},
|
},
|
||||||
|
"Q2us5X": {
|
||||||
|
"context": "Dry run icon label",
|
||||||
|
"string": "Dry run"
|
||||||
|
},
|
||||||
"Q47ovw": {
|
"Q47ovw": {
|
||||||
"context": "activate app",
|
"context": "activate app",
|
||||||
"string": "Are you sure you want to activate this app? Activating will start gathering events."
|
"string": "Are you sure you want to activate this app? Activating will start gathering events."
|
||||||
|
@ -4767,6 +4791,10 @@
|
||||||
"context": "header",
|
"context": "header",
|
||||||
"string": "Edit Authorization Field"
|
"string": "Edit Authorization Field"
|
||||||
},
|
},
|
||||||
|
"Xz/sDf": {
|
||||||
|
"context": "Dry run items list item",
|
||||||
|
"string": "Item:"
|
||||||
|
},
|
||||||
"Y1B0PN": {
|
"Y1B0PN": {
|
||||||
"context": "error message",
|
"context": "error message",
|
||||||
"string": "There's no payment associated with the order"
|
"string": "There's no payment associated with the order"
|
||||||
|
@ -4962,6 +4990,10 @@
|
||||||
"context": "subsection header",
|
"context": "subsection header",
|
||||||
"string": "Shipping Address"
|
"string": "Shipping Address"
|
||||||
},
|
},
|
||||||
|
"ZepEWY": {
|
||||||
|
"context": "Dry run item",
|
||||||
|
"string": "Item"
|
||||||
|
},
|
||||||
"Zg0dRo": {
|
"Zg0dRo": {
|
||||||
"context": "dialog description",
|
"context": "dialog description",
|
||||||
"string": "You have changed customer assigned to this order. What would you like to do with the shipping address?"
|
"string": "You have changed customer assigned to this order. What would you like to do with the shipping address?"
|
||||||
|
@ -5647,6 +5679,10 @@
|
||||||
"fhksPD": {
|
"fhksPD": {
|
||||||
"string": "Number of Orders"
|
"string": "Number of Orders"
|
||||||
},
|
},
|
||||||
|
"fi9Qa/": {
|
||||||
|
"context": "Dry run dialog header",
|
||||||
|
"string": "Dry run"
|
||||||
|
},
|
||||||
"fjPWOA": {
|
"fjPWOA": {
|
||||||
"context": "header",
|
"context": "header",
|
||||||
"string": "Customer Overview"
|
"string": "Customer Overview"
|
||||||
|
@ -7472,6 +7508,10 @@
|
||||||
"ubmFc8": {
|
"ubmFc8": {
|
||||||
"string": "Install"
|
"string": "Install"
|
||||||
},
|
},
|
||||||
|
"uccjUM": {
|
||||||
|
"context": "Dry run objects",
|
||||||
|
"string": "Objects"
|
||||||
|
},
|
||||||
"ud0w8h": {
|
"ud0w8h": {
|
||||||
"context": "number of postal code ranges",
|
"context": "number of postal code ranges",
|
||||||
"string": "{number} postal code ranges"
|
"string": "{number} postal code ranges"
|
||||||
|
|
804
schema.graphql
804
schema.graphql
File diff suppressed because it is too large
Load diff
42
src/components/DryRun/DryRun.test.tsx
Normal file
42
src/components/DryRun/DryRun.test.tsx
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import { MockedProvider, MockedResponse } from "@apollo/client/testing";
|
||||||
|
import { WebhookEventTypeAsyncEnum } from "@dashboard/graphql";
|
||||||
|
import { ThemeProvider } from "@saleor/macaw-ui";
|
||||||
|
import productsMocks from "@test/mocks/products";
|
||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import DryRun from "./DryRun";
|
||||||
|
|
||||||
|
const mocks: MockedResponse[] = [...productsMocks];
|
||||||
|
|
||||||
|
jest.mock("react-intl", () => ({
|
||||||
|
useIntl: jest.fn(() => ({
|
||||||
|
formatMessage: jest.fn(x => x.defaultMessage),
|
||||||
|
})),
|
||||||
|
defineMessages: jest.fn(x => x),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("DryRun", () => {
|
||||||
|
it("Dialog is available on the webhook page", async () => {
|
||||||
|
// Arrange
|
||||||
|
const props = {
|
||||||
|
query: "",
|
||||||
|
showDialog: true,
|
||||||
|
setShowDialog: jest.fn(),
|
||||||
|
asyncEvents: [] as WebhookEventTypeAsyncEnum[],
|
||||||
|
setResult: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(
|
||||||
|
<MockedProvider mocks={mocks} addTypename={false}>
|
||||||
|
<ThemeProvider>
|
||||||
|
<DryRun {...props} />
|
||||||
|
</ThemeProvider>
|
||||||
|
</MockedProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(screen.queryByTestId("dry-run")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
171
src/components/DryRun/DryRun.tsx
Normal file
171
src/components/DryRun/DryRun.tsx
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
import Grid from "@dashboard/components/Grid";
|
||||||
|
import { useStyles } from "@dashboard/custom-apps/components/WebhookEvents/styles";
|
||||||
|
import {
|
||||||
|
useTriggerWebhookDryRunMutation,
|
||||||
|
WebhookEventTypeAsyncEnum,
|
||||||
|
} from "@dashboard/graphql";
|
||||||
|
import {
|
||||||
|
capitalize,
|
||||||
|
Dialog,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogContentText,
|
||||||
|
Typography,
|
||||||
|
} from "@material-ui/core";
|
||||||
|
import {
|
||||||
|
Alert,
|
||||||
|
Button,
|
||||||
|
DialogHeader,
|
||||||
|
List,
|
||||||
|
ListBody,
|
||||||
|
ListHeader,
|
||||||
|
ListItem,
|
||||||
|
ListItemCell,
|
||||||
|
} from "@saleor/macaw-ui";
|
||||||
|
import React, { Dispatch, SetStateAction, useState } from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import DryRunItemsList from "../DryRunItemsList/DryRunItemsList";
|
||||||
|
import { messages } from "./messages";
|
||||||
|
import { getObjects } from "./utils";
|
||||||
|
|
||||||
|
interface DryRunProps {
|
||||||
|
query: string;
|
||||||
|
showDialog: boolean;
|
||||||
|
setShowDialog: Dispatch<SetStateAction<boolean>>;
|
||||||
|
asyncEvents: WebhookEventTypeAsyncEnum[];
|
||||||
|
setResult: Dispatch<SetStateAction<string>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DryRun: React.FC<DryRunProps> = ({
|
||||||
|
setResult,
|
||||||
|
showDialog,
|
||||||
|
setShowDialog,
|
||||||
|
query,
|
||||||
|
}: DryRunProps) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const classes = useStyles();
|
||||||
|
const [objectId, setObjectId] = useState<string | null>(null);
|
||||||
|
const [triggerWebhookDryRun] = useTriggerWebhookDryRunMutation();
|
||||||
|
const availableObjects = getObjects(query);
|
||||||
|
const unavailableObjects = getObjects(query, false);
|
||||||
|
|
||||||
|
const [object, setObject] = useState<string | null>(null);
|
||||||
|
|
||||||
|
const dryRun = async () => {
|
||||||
|
const { data } = await triggerWebhookDryRun({
|
||||||
|
variables: { objectId, query },
|
||||||
|
});
|
||||||
|
setResult(JSON.stringify(JSON.parse(data.webhookDryRun.payload), null, 2));
|
||||||
|
closeDialog();
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
setShowDialog(false);
|
||||||
|
setObjectId(null);
|
||||||
|
setObject(null);
|
||||||
|
setShowDialog(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!showDialog) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={showDialog} fullWidth maxWidth="md" data-test-id="dry-run">
|
||||||
|
<DialogHeader onClose={closeDialog}>
|
||||||
|
{intl.formatMessage(messages.header)}
|
||||||
|
</DialogHeader>
|
||||||
|
<DialogContent style={{ overflow: "scroll" }}>
|
||||||
|
<DialogContentText>
|
||||||
|
{intl.formatMessage(messages.selectObject)}
|
||||||
|
</DialogContentText>
|
||||||
|
|
||||||
|
{!!unavailableObjects.length && (
|
||||||
|
<Alert variant="warning" close={false}>
|
||||||
|
<Typography>
|
||||||
|
{intl.formatMessage(messages.unavailableObjects)}
|
||||||
|
|
||||||
|
<strong>{unavailableObjects.join(", ")}</strong>
|
||||||
|
</Typography>
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Grid variant="uniform">
|
||||||
|
<div className={classes.objectsWrapper}>
|
||||||
|
<List gridTemplate={["1fr 50px"]}>
|
||||||
|
<ListHeader>
|
||||||
|
<ListItem className={classes.listHeader}>
|
||||||
|
<ListItemCell className={classes.listItemCell}>
|
||||||
|
{intl.formatMessage(messages.objects)}
|
||||||
|
</ListItemCell>
|
||||||
|
<ListItemCell></ListItemCell>
|
||||||
|
</ListItem>
|
||||||
|
</ListHeader>
|
||||||
|
<ListBody className={classes.listBody}>
|
||||||
|
{!availableObjects.length && (
|
||||||
|
<Typography>
|
||||||
|
{intl.formatMessage(messages.noObjects)}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
{availableObjects.map((object, idx) => (
|
||||||
|
<ListItem
|
||||||
|
key={idx}
|
||||||
|
className={classes.listItem}
|
||||||
|
onClick={() =>
|
||||||
|
setObject(object.split(" ").join("_").toUpperCase())
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ListItemCell className={classes.listItemCell}>
|
||||||
|
<strong>
|
||||||
|
{capitalize(object.replaceAll("_", " ").toLowerCase())}
|
||||||
|
</strong>
|
||||||
|
</ListItemCell>
|
||||||
|
<ListItemCell></ListItemCell>
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</ListBody>
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
|
<div className={classes.eventsWrapper}>
|
||||||
|
{object ? (
|
||||||
|
<DryRunItemsList
|
||||||
|
setObjectId={setObjectId}
|
||||||
|
objectId={objectId}
|
||||||
|
object={object}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<ListHeader>
|
||||||
|
<ListItem className={classes.listHeader}>
|
||||||
|
<ListItemCell className={classes.listItemCell}>
|
||||||
|
{intl.formatMessage(messages.item)}
|
||||||
|
</ListItemCell>
|
||||||
|
</ListItem>
|
||||||
|
</ListHeader>
|
||||||
|
<ListBody className={classes.listBody}>
|
||||||
|
<Typography>
|
||||||
|
{intl.formatMessage(messages.itemsDefaultMessage)}
|
||||||
|
</Typography>
|
||||||
|
</ListBody>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
variant="primary"
|
||||||
|
onClick={dryRun}
|
||||||
|
disabled={!availableObjects.length}
|
||||||
|
>
|
||||||
|
{intl.formatMessage(messages.run)}
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
DryRun.displayName = "DryRun";
|
||||||
|
export default DryRun;
|
2
src/components/DryRun/index.ts
Normal file
2
src/components/DryRun/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export { default } from "./DryRun";
|
||||||
|
export * from "./DryRun";
|
45
src/components/DryRun/messages.ts
Normal file
45
src/components/DryRun/messages.ts
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import { defineMessages } from "react-intl";
|
||||||
|
|
||||||
|
export const messages = defineMessages({
|
||||||
|
header: {
|
||||||
|
id: "fi9Qa/",
|
||||||
|
defaultMessage: "Dry run",
|
||||||
|
description: "Dry run dialog header",
|
||||||
|
},
|
||||||
|
selectObject: {
|
||||||
|
id: "+RffqY",
|
||||||
|
defaultMessage: "Select object type to perform dry run on provided query",
|
||||||
|
description: "Dry run dialog object title",
|
||||||
|
},
|
||||||
|
unavailableObjects: {
|
||||||
|
id: "ApNw0L",
|
||||||
|
defaultMessage:
|
||||||
|
"The following objects are currently not available for dry run:",
|
||||||
|
description: "Dry run objects unavailable",
|
||||||
|
},
|
||||||
|
objects: {
|
||||||
|
id: "uccjUM",
|
||||||
|
defaultMessage: "Objects",
|
||||||
|
description: "Dry run objects",
|
||||||
|
},
|
||||||
|
noObjects: {
|
||||||
|
id: "0u9Ng0",
|
||||||
|
defaultMessage: "No objects found in the provided query",
|
||||||
|
description: "Dry run no objects found",
|
||||||
|
},
|
||||||
|
item: {
|
||||||
|
id: "ZepEWY",
|
||||||
|
defaultMessage: "Item",
|
||||||
|
description: "Dry run item",
|
||||||
|
},
|
||||||
|
itemsDefaultMessage: {
|
||||||
|
id: "5b0Boq",
|
||||||
|
defaultMessage: "Choose the object",
|
||||||
|
description: "Dry run items list default message",
|
||||||
|
},
|
||||||
|
run: {
|
||||||
|
id: "48dMqY",
|
||||||
|
defaultMessage: "Run",
|
||||||
|
description: "Dry run trigger button",
|
||||||
|
},
|
||||||
|
});
|
13
src/components/DryRun/mutations.ts
Normal file
13
src/components/DryRun/mutations.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { gql } from "@apollo/client";
|
||||||
|
|
||||||
|
export const triggerWebhookDryRun = gql`
|
||||||
|
mutation TriggerWebhookDryRun($objectId: ID!, $query: String!) {
|
||||||
|
webhookDryRun(objectId: $objectId, query: $query) {
|
||||||
|
payload
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
59
src/components/DryRun/utils.ts
Normal file
59
src/components/DryRun/utils.ts
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import { AsyncWebhookTypes } from "@dashboard/custom-apps/components/WebhookEvents";
|
||||||
|
import { InlineFragmentNode, ObjectFieldNode, parse, visit } from "graphql";
|
||||||
|
import uniq from "lodash/uniq";
|
||||||
|
|
||||||
|
import { ExcludedDocumentMap } from "../DryRunItemsList/utils";
|
||||||
|
|
||||||
|
const getEventsFromQuery = (query: string) => {
|
||||||
|
if (query.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ast = parse(query);
|
||||||
|
const events: string[] = [];
|
||||||
|
|
||||||
|
visit(ast, {
|
||||||
|
SelectionSet(node, _key, parent) {
|
||||||
|
if ((parent as ObjectFieldNode).name?.value === "event") {
|
||||||
|
const queryEvents = node.selections.map(
|
||||||
|
selection =>
|
||||||
|
(selection as InlineFragmentNode).typeCondition.name.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
queryEvents.map(event => events.push(event));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return events;
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getObjects = (query: string, available = true) => {
|
||||||
|
const queryEvents = getEventsFromQuery(query);
|
||||||
|
|
||||||
|
return uniq(
|
||||||
|
queryEvents.map(event => {
|
||||||
|
const object = event.split(/(?=[A-Z])/).slice(0, -1);
|
||||||
|
if (
|
||||||
|
Object.keys(AsyncWebhookTypes)
|
||||||
|
.filter(object =>
|
||||||
|
available
|
||||||
|
? !Object.keys(ExcludedDocumentMap).includes(object.toUpperCase())
|
||||||
|
: Object.keys(ExcludedDocumentMap).includes(object.toUpperCase()),
|
||||||
|
)
|
||||||
|
.includes(object.join("_").toUpperCase())
|
||||||
|
) {
|
||||||
|
return object.join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return event
|
||||||
|
.split(/(?=[A-Z])/)
|
||||||
|
.slice(0, -2)
|
||||||
|
.join(" ");
|
||||||
|
}),
|
||||||
|
).filter(object => object.length > 0);
|
||||||
|
};
|
39
src/components/DryRunItemsList/DryRunItemsList.test.tsx
Normal file
39
src/components/DryRunItemsList/DryRunItemsList.test.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import { MockedProvider, MockedResponse } from "@apollo/client/testing";
|
||||||
|
import { ThemeProvider } from "@saleor/macaw-ui";
|
||||||
|
import { productsMocks } from "@test/mocks/products";
|
||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import DryRunItemsList from "./DryRunItemsList";
|
||||||
|
|
||||||
|
const mocks: MockedResponse[] = [...productsMocks];
|
||||||
|
|
||||||
|
jest.mock("react-intl", () => ({
|
||||||
|
useIntl: jest.fn(() => ({
|
||||||
|
formatMessage: jest.fn(x => x.defaultMessage),
|
||||||
|
})),
|
||||||
|
defineMessages: jest.fn(x => x),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("DryRunItemsList", () => {
|
||||||
|
it("is available on the webhook page", async () => {
|
||||||
|
// Arrange
|
||||||
|
const props = {
|
||||||
|
objectId: null,
|
||||||
|
setObjectId: jest.fn(),
|
||||||
|
object: "PRODUCT",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(
|
||||||
|
<MockedProvider mocks={mocks} addTypename={false}>
|
||||||
|
<ThemeProvider>
|
||||||
|
<DryRunItemsList {...props} />
|
||||||
|
</ThemeProvider>
|
||||||
|
</MockedProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(screen.queryByTestId("dry-run-items-list")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
106
src/components/DryRunItemsList/DryRunItemsList.tsx
Normal file
106
src/components/DryRunItemsList/DryRunItemsList.tsx
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
import Skeleton from "@dashboard/components/Skeleton";
|
||||||
|
import { useStyles } from "@dashboard/custom-apps/components/WebhookEvents/styles";
|
||||||
|
import { useQuery } from "@dashboard/hooks/graphql";
|
||||||
|
import { mapEdgesToItems } from "@dashboard/utils/maps";
|
||||||
|
import { Radio } from "@material-ui/core";
|
||||||
|
import {
|
||||||
|
List,
|
||||||
|
ListBody,
|
||||||
|
ListHeader,
|
||||||
|
ListItem,
|
||||||
|
ListItemCell,
|
||||||
|
useListWidths,
|
||||||
|
} from "@saleor/macaw-ui";
|
||||||
|
import camelCase from "lodash/camelCase";
|
||||||
|
import React from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import Avatar from "../TableCellAvatar/Avatar";
|
||||||
|
import { messages } from "./messages";
|
||||||
|
import { DocumentMap, TData, TVariables } from "./utils";
|
||||||
|
interface DryRunItemsListProps {
|
||||||
|
objectId: string;
|
||||||
|
setObjectId: React.Dispatch<any>;
|
||||||
|
object: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DryRunItemsList = (props: DryRunItemsListProps) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const classes = useStyles();
|
||||||
|
const { checkbox } = useListWidths();
|
||||||
|
const { object, objectId, setObjectId } = props;
|
||||||
|
const objectDocument = DocumentMap[object];
|
||||||
|
const objectCollection =
|
||||||
|
objectDocument.collection ?? camelCase(`${object.toLowerCase()}s`);
|
||||||
|
|
||||||
|
const { data, loading } = useQuery<TData, TVariables>(
|
||||||
|
objectDocument.document,
|
||||||
|
{
|
||||||
|
displayLoader: true,
|
||||||
|
variables: objectDocument.variables,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<List
|
||||||
|
gridTemplate={["1fr", checkbox, checkbox]}
|
||||||
|
data-test-id="dry-run-items-list"
|
||||||
|
>
|
||||||
|
<ListHeader>
|
||||||
|
<ListItem className={classes.listHeader}>
|
||||||
|
<ListItemCell className={classes.listItemCell}>
|
||||||
|
{intl.formatMessage(messages.item)}
|
||||||
|
|
||||||
|
{objectDocument.collection
|
||||||
|
?.split(/(?=[A-Z])/)
|
||||||
|
.map(item => item.toLowerCase())
|
||||||
|
.join(" ")}
|
||||||
|
|
||||||
|
{objectDocument.displayedAttribute}
|
||||||
|
</ListItemCell>
|
||||||
|
</ListItem>
|
||||||
|
</ListHeader>
|
||||||
|
<ListBody className={classes.listBody}>
|
||||||
|
{loading ? (
|
||||||
|
<ListItem className={classes.listItem}>
|
||||||
|
<ListItemCell className={classes.listItemCell}>
|
||||||
|
<Skeleton />
|
||||||
|
</ListItemCell>
|
||||||
|
<ListItemCell>
|
||||||
|
<Skeleton />
|
||||||
|
</ListItemCell>
|
||||||
|
<ListItemCell>
|
||||||
|
<Skeleton />
|
||||||
|
</ListItemCell>
|
||||||
|
</ListItem>
|
||||||
|
) : (
|
||||||
|
(mapEdgesToItems<any>(data[objectCollection]) || []).map(
|
||||||
|
(item, idx) => (
|
||||||
|
<ListItem
|
||||||
|
className={classes.listItem}
|
||||||
|
key={idx}
|
||||||
|
onClick={() => setObjectId(item.id)}
|
||||||
|
>
|
||||||
|
<ListItemCell className={classes.listItemCell}>
|
||||||
|
{item.name ||
|
||||||
|
item[objectDocument.displayedAttribute] ||
|
||||||
|
item.id ||
|
||||||
|
item.__typename}
|
||||||
|
</ListItemCell>
|
||||||
|
<ListItemCell>
|
||||||
|
{item.thumbnail && <Avatar thumbnail={item.thumbnail?.url} />}
|
||||||
|
</ListItemCell>
|
||||||
|
<ListItemCell>
|
||||||
|
<Radio checked={item.id === objectId} />
|
||||||
|
</ListItemCell>
|
||||||
|
</ListItem>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</ListBody>
|
||||||
|
</List>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
DryRunItemsList.displayName = "DryRunItemsList";
|
||||||
|
export default DryRunItemsList;
|
2
src/components/DryRunItemsList/index.ts
Normal file
2
src/components/DryRunItemsList/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export { default } from "./DryRunItemsList";
|
||||||
|
export * from "./DryRunItemsList";
|
9
src/components/DryRunItemsList/messages.ts
Normal file
9
src/components/DryRunItemsList/messages.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { defineMessages } from "react-intl";
|
||||||
|
|
||||||
|
export const messages = defineMessages({
|
||||||
|
item: {
|
||||||
|
id: "Xz/sDf",
|
||||||
|
defaultMessage: "Item:",
|
||||||
|
description: "Dry run items list item",
|
||||||
|
},
|
||||||
|
});
|
30
src/components/DryRunItemsList/queries.ts
Normal file
30
src/components/DryRunItemsList/queries.ts
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { gql } from "@apollo/client";
|
||||||
|
|
||||||
|
export const checkouts = gql`
|
||||||
|
query CheckoutList($first: Int, $after: String, $last: Int, $before: String) {
|
||||||
|
checkouts(before: $before, after: $after, first: $first, last: $last) {
|
||||||
|
edges {
|
||||||
|
cursor
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
created
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
hasPreviousPage
|
||||||
|
hasNextPage
|
||||||
|
startCursor
|
||||||
|
endCursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const channels = gql`
|
||||||
|
query ChannelList {
|
||||||
|
channels {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
262
src/components/DryRunItemsList/utils.ts
Normal file
262
src/components/DryRunItemsList/utils.ts
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
import {
|
||||||
|
AppsListDocument,
|
||||||
|
AppsListQuery,
|
||||||
|
AppsListQueryVariables,
|
||||||
|
AttributeListDocument,
|
||||||
|
AttributeListQuery,
|
||||||
|
AttributeListQueryVariables,
|
||||||
|
CategoryDetailsQuery,
|
||||||
|
CategoryDetailsQueryVariables,
|
||||||
|
ChannelListDocument,
|
||||||
|
CheckoutListDocument,
|
||||||
|
CheckoutListQuery,
|
||||||
|
CheckoutListQueryVariables,
|
||||||
|
CollectionListDocument,
|
||||||
|
CollectionListQuery,
|
||||||
|
CollectionListQueryVariables,
|
||||||
|
CustomerAddressesDocument,
|
||||||
|
CustomerAddressesQuery,
|
||||||
|
CustomerAddressesQueryVariables,
|
||||||
|
CustomerDetailsQuery,
|
||||||
|
CustomerDetailsQueryVariables,
|
||||||
|
GiftCardListDocument,
|
||||||
|
GiftCardListQuery,
|
||||||
|
GiftCardListQueryVariables,
|
||||||
|
ListCustomersDocument,
|
||||||
|
ListCustomersQuery,
|
||||||
|
ListCustomersQueryVariables,
|
||||||
|
MenuListDocument,
|
||||||
|
MenuListQuery,
|
||||||
|
MenuListQueryVariables,
|
||||||
|
OrderFulfillDataDocument,
|
||||||
|
OrderFulfillDataQuery,
|
||||||
|
OrderFulfillDataQueryVariables,
|
||||||
|
OrderListDocument,
|
||||||
|
OrderListQuery,
|
||||||
|
OrderListQueryVariables,
|
||||||
|
PageListDocument,
|
||||||
|
PageListQuery,
|
||||||
|
PageListQueryVariables,
|
||||||
|
ProductListDocument,
|
||||||
|
ProductListQuery,
|
||||||
|
ProductListQueryVariables,
|
||||||
|
ProductVariantListDocument,
|
||||||
|
ProductVariantListQuery,
|
||||||
|
ProductVariantListQueryVariables,
|
||||||
|
RootCategoriesDocument,
|
||||||
|
RootCategoriesQuery,
|
||||||
|
RootCategoriesQueryVariables,
|
||||||
|
SaleListDocument,
|
||||||
|
SaleListQuery,
|
||||||
|
SaleListQueryVariables,
|
||||||
|
ShippingZonesDocument,
|
||||||
|
StaffListDocument,
|
||||||
|
StaffListQuery,
|
||||||
|
StaffListQueryVariables,
|
||||||
|
VoucherListDocument,
|
||||||
|
VoucherListQuery,
|
||||||
|
VoucherListQueryVariables,
|
||||||
|
WarehouseListDocument,
|
||||||
|
WarehouseListQuery,
|
||||||
|
WarehouseListQueryVariables,
|
||||||
|
} from "@dashboard/graphql";
|
||||||
|
import { DocumentNode } from "graphql";
|
||||||
|
|
||||||
|
const DefaultVariables = {
|
||||||
|
first: 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TData =
|
||||||
|
| ProductListQuery
|
||||||
|
| OrderListQuery
|
||||||
|
| GiftCardListQuery
|
||||||
|
| CustomerAddressesQuery
|
||||||
|
| AppsListQuery
|
||||||
|
| AttributeListQuery
|
||||||
|
| CategoryDetailsQuery
|
||||||
|
| CheckoutListQuery
|
||||||
|
| GiftCardListQuery
|
||||||
|
| CollectionListQuery
|
||||||
|
| CustomerDetailsQuery
|
||||||
|
| OrderFulfillDataQuery
|
||||||
|
| ListCustomersQuery
|
||||||
|
| MenuListQuery
|
||||||
|
| OrderListQuery
|
||||||
|
| PageListQuery
|
||||||
|
| ProductListQuery
|
||||||
|
| ProductVariantListQuery
|
||||||
|
| RootCategoriesQuery
|
||||||
|
| SaleListQuery
|
||||||
|
| StaffListQuery
|
||||||
|
| VoucherListQuery
|
||||||
|
| WarehouseListQuery;
|
||||||
|
|
||||||
|
export type TVariables =
|
||||||
|
| ProductListQueryVariables
|
||||||
|
| OrderListQueryVariables
|
||||||
|
| GiftCardListQueryVariables
|
||||||
|
| CustomerAddressesQueryVariables
|
||||||
|
| AppsListQueryVariables
|
||||||
|
| AttributeListQueryVariables
|
||||||
|
| CategoryDetailsQueryVariables
|
||||||
|
| ListCustomersQueryVariables
|
||||||
|
| CheckoutListQueryVariables
|
||||||
|
| GiftCardListQueryVariables
|
||||||
|
| CollectionListQueryVariables
|
||||||
|
| CustomerDetailsQueryVariables
|
||||||
|
| OrderFulfillDataQueryVariables
|
||||||
|
| MenuListQueryVariables
|
||||||
|
| OrderListQueryVariables
|
||||||
|
| PageListQueryVariables
|
||||||
|
| ProductListQueryVariables
|
||||||
|
| ProductVariantListQueryVariables
|
||||||
|
| RootCategoriesQueryVariables
|
||||||
|
| SaleListQueryVariables
|
||||||
|
| StaffListQueryVariables
|
||||||
|
| VoucherListQueryVariables
|
||||||
|
| WarehouseListQueryVariables;
|
||||||
|
|
||||||
|
interface Document {
|
||||||
|
document: DocumentNode;
|
||||||
|
variables: TVariables;
|
||||||
|
collection?: string;
|
||||||
|
displayedAttribute?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DocumentMap: Record<string, Document> = {
|
||||||
|
APP: {
|
||||||
|
document: AppsListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
ATTRIBUTE: {
|
||||||
|
document: AttributeListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
CATEGORY: {
|
||||||
|
document: RootCategoriesDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
collection: "categories",
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
GIFT_CARD: {
|
||||||
|
document: GiftCardListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "last4CodeChars",
|
||||||
|
},
|
||||||
|
CHECKOUT: {
|
||||||
|
document: CheckoutListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "id",
|
||||||
|
},
|
||||||
|
COLLECTION: {
|
||||||
|
document: CollectionListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
CUSTOMER: {
|
||||||
|
document: ListCustomersDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "email",
|
||||||
|
// TODO inverted name
|
||||||
|
},
|
||||||
|
|
||||||
|
INVOICE: {
|
||||||
|
document: OrderListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
collection: "orders",
|
||||||
|
displayedAttribute: "number",
|
||||||
|
},
|
||||||
|
MENU: {
|
||||||
|
document: MenuListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
ORDER: {
|
||||||
|
document: OrderListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "number",
|
||||||
|
},
|
||||||
|
PAGE: {
|
||||||
|
document: PageListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "title",
|
||||||
|
},
|
||||||
|
PRODUCT: {
|
||||||
|
document: ProductListDocument,
|
||||||
|
variables: {
|
||||||
|
first: 100,
|
||||||
|
hasChannel: true,
|
||||||
|
hasSelectedAttributes: true,
|
||||||
|
},
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
SALE: {
|
||||||
|
document: SaleListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
SHIPPING_PRICE: {
|
||||||
|
document: ShippingZonesDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
collection: "shippingZones",
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
SHIPPING_ZONE: {
|
||||||
|
document: ShippingZonesDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
STAFF: {
|
||||||
|
document: StaffListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
collection: "staffUsers",
|
||||||
|
displayedAttribute: "email",
|
||||||
|
},
|
||||||
|
VOUCHER: {
|
||||||
|
document: VoucherListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "code",
|
||||||
|
},
|
||||||
|
WAREHOUSE: {
|
||||||
|
document: WarehouseListDocument,
|
||||||
|
variables: DefaultVariables,
|
||||||
|
displayedAttribute: "name",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Documents which require parent object or can't be handled ATM
|
||||||
|
//
|
||||||
|
export const ExcludedDocumentMap: Record<string, Document> = {
|
||||||
|
ADDRESS: {
|
||||||
|
document: CustomerAddressesDocument,
|
||||||
|
variables: {
|
||||||
|
// USER ID REQUIRED
|
||||||
|
first: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// it's not a countable collection
|
||||||
|
CHANNEL: {
|
||||||
|
document: ChannelListDocument,
|
||||||
|
variables: {},
|
||||||
|
},
|
||||||
|
FULFILLMENT: {
|
||||||
|
document: OrderFulfillDataDocument,
|
||||||
|
variables: {
|
||||||
|
// ORDER ID REQUIRED
|
||||||
|
first: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PRODUCT_VARIANT: {
|
||||||
|
document: ProductVariantListDocument,
|
||||||
|
variables: {
|
||||||
|
// PRODUCT ID REQUIRED
|
||||||
|
first: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TRANSLATION: {
|
||||||
|
document: null,
|
||||||
|
variables: {},
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,7 +1,9 @@
|
||||||
|
import { WebhookEventTypeAsyncEnum } from "@dashboard/graphql";
|
||||||
import {
|
import {
|
||||||
CopyIcon,
|
CopyIcon,
|
||||||
GraphiQLProvider,
|
GraphiQLProvider,
|
||||||
GraphiQLProviderProps,
|
GraphiQLProviderProps,
|
||||||
|
PlayIcon,
|
||||||
PrettifyIcon,
|
PrettifyIcon,
|
||||||
QueryEditor,
|
QueryEditor,
|
||||||
ToolbarButton,
|
ToolbarButton,
|
||||||
|
@ -18,8 +20,16 @@ import {
|
||||||
WriteableEditorProps,
|
WriteableEditorProps,
|
||||||
} from "@graphiql/react";
|
} from "@graphiql/react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import React, { ComponentType, PropsWithChildren, ReactNode } from "react";
|
import React, {
|
||||||
|
ComponentType,
|
||||||
|
PropsWithChildren,
|
||||||
|
ReactNode,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import DryRun from "../DryRun";
|
||||||
|
import { messages } from "./messages";
|
||||||
import {
|
import {
|
||||||
useDashboardTheme,
|
useDashboardTheme,
|
||||||
useEditorStyles,
|
useEditorStyles,
|
||||||
|
@ -68,7 +78,7 @@ export function GraphiQL({
|
||||||
visiblePlugin,
|
visiblePlugin,
|
||||||
defaultHeaders,
|
defaultHeaders,
|
||||||
...props
|
...props
|
||||||
}: GraphiQLProps) {
|
}: GraphiQLProps & { asyncEvents: WebhookEventTypeAsyncEnum[] }) {
|
||||||
// Ensure props are correct
|
// Ensure props are correct
|
||||||
if (typeof fetcher !== "function") {
|
if (typeof fetcher !== "function") {
|
||||||
throw new TypeError(
|
throw new TypeError(
|
||||||
|
@ -76,6 +86,9 @@ export function GraphiQL({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [showDialog, setShowDialog] = useState(false);
|
||||||
|
const [result, setResult] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GraphiQLProvider
|
<GraphiQLProvider
|
||||||
getDefaultFieldNames={getDefaultFieldNames}
|
getDefaultFieldNames={getDefaultFieldNames}
|
||||||
|
@ -106,7 +119,19 @@ export function GraphiQL({
|
||||||
validationRules={validationRules}
|
validationRules={validationRules}
|
||||||
variables={variables}
|
variables={variables}
|
||||||
>
|
>
|
||||||
<GraphiQLInterface {...props} />
|
<GraphiQLInterface
|
||||||
|
{...props}
|
||||||
|
showDialog={showDialog}
|
||||||
|
setShowDialog={setShowDialog}
|
||||||
|
result={result}
|
||||||
|
/>
|
||||||
|
<DryRun
|
||||||
|
showDialog={showDialog}
|
||||||
|
setShowDialog={setShowDialog}
|
||||||
|
query={query}
|
||||||
|
setResult={setResult}
|
||||||
|
asyncEvents={props.asyncEvents}
|
||||||
|
/>
|
||||||
</GraphiQLProvider>
|
</GraphiQLProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -127,9 +152,13 @@ export type GraphiQLInterfaceProps = WriteableEditorProps &
|
||||||
defaultEditorToolsVisibility?: boolean | "variables" | "headers";
|
defaultEditorToolsVisibility?: boolean | "variables" | "headers";
|
||||||
isHeadersEditorEnabled?: boolean;
|
isHeadersEditorEnabled?: boolean;
|
||||||
toolbar?: GraphiQLToolbarConfig;
|
toolbar?: GraphiQLToolbarConfig;
|
||||||
|
showDialog?: boolean;
|
||||||
|
setShowDialog?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
result?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
|
export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
|
||||||
|
const intl = useIntl();
|
||||||
const editorContext = useEditorContext({ nonNull: true });
|
const editorContext = useEditorContext({ nonNull: true });
|
||||||
const pluginContext = usePluginContext();
|
const pluginContext = usePluginContext();
|
||||||
|
|
||||||
|
@ -150,6 +179,13 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
|
||||||
isChildComponentType(child, GraphiQL.Toolbar),
|
isChildComponentType(child, GraphiQL.Toolbar),
|
||||||
) || (
|
) || (
|
||||||
<>
|
<>
|
||||||
|
<ToolbarButton
|
||||||
|
onClick={() => props.setShowDialog(true)}
|
||||||
|
label={intl.formatMessage(messages.toolbarButonLabel)}
|
||||||
|
>
|
||||||
|
<PlayIcon className="graphiql-toolbar-icon" aria-hidden="true" />
|
||||||
|
</ToolbarButton>
|
||||||
|
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
onClick={() => prettify()}
|
onClick={() => prettify()}
|
||||||
label="Prettify query (Shift-Ctrl-P)"
|
label="Prettify query (Shift-Ctrl-P)"
|
||||||
|
@ -266,6 +302,14 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div ref={editorResize.dragBarRef}>
|
||||||
|
<div className="graphiql-horizontal-drag-bar" />
|
||||||
|
</div>
|
||||||
|
<div ref={editorResize.secondRef}>
|
||||||
|
<div className="graphiql-response">
|
||||||
|
<pre className={classes.pre}>{props.result}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
9
src/components/GraphiQL/messages.ts
Normal file
9
src/components/GraphiQL/messages.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { defineMessages } from "react-intl";
|
||||||
|
|
||||||
|
export const messages = defineMessages({
|
||||||
|
toolbarButonLabel: {
|
||||||
|
id: "Q2us5X",
|
||||||
|
defaultMessage: "Dry run",
|
||||||
|
description: "Dry run icon label",
|
||||||
|
},
|
||||||
|
});
|
|
@ -8,6 +8,9 @@ import { useEffect } from "react";
|
||||||
|
|
||||||
export const useStyles = makeStyles(
|
export const useStyles = makeStyles(
|
||||||
() => ({
|
() => ({
|
||||||
|
pre: {
|
||||||
|
whiteSpace: "break-spaces",
|
||||||
|
},
|
||||||
scrollable: {
|
scrollable: {
|
||||||
// Overrides inline styling which breaks scroll
|
// Overrides inline styling which breaks scroll
|
||||||
// on doc explorer plugin
|
// on doc explorer plugin
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { capitalize } from "@dashboard/misc";
|
||||||
import { Card, CardContent, Checkbox, Typography } from "@material-ui/core";
|
import { Card, CardContent, Checkbox, Typography } from "@material-ui/core";
|
||||||
import {
|
import {
|
||||||
List,
|
List,
|
||||||
|
ListBody,
|
||||||
ListHeader,
|
ListHeader,
|
||||||
ListItem,
|
ListItem,
|
||||||
ListItemCell,
|
ListItemCell,
|
||||||
|
@ -105,7 +106,7 @@ const WebhookEvents: React.FC<WebhookEventsProps> = ({
|
||||||
<ListItemCell></ListItemCell>
|
<ListItemCell></ListItemCell>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</ListHeader>
|
</ListHeader>
|
||||||
<div className={classes.listItems}>
|
<ListBody className={classes.listBody}>
|
||||||
{Object.keys(EventTypes[tab]).map((object, idx) => (
|
{Object.keys(EventTypes[tab]).map((object, idx) => (
|
||||||
<ListItem
|
<ListItem
|
||||||
key={idx}
|
key={idx}
|
||||||
|
@ -130,7 +131,7 @@ const WebhookEvents: React.FC<WebhookEventsProps> = ({
|
||||||
</ListItemCell>
|
</ListItemCell>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
))}
|
))}
|
||||||
</div>
|
</ListBody>
|
||||||
</List>
|
</List>
|
||||||
</PageTabPanel>
|
</PageTabPanel>
|
||||||
</div>
|
</div>
|
||||||
|
@ -143,6 +144,7 @@ const WebhookEvents: React.FC<WebhookEventsProps> = ({
|
||||||
</ListItemCell>
|
</ListItemCell>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</ListHeader>
|
</ListHeader>
|
||||||
|
<ListBody className={classes.listBody}>
|
||||||
{object &&
|
{object &&
|
||||||
EventTypes[tab][object] &&
|
EventTypes[tab][object] &&
|
||||||
EventTypes[tab][object].map((event, idx) => (
|
EventTypes[tab][object].map((event, idx) => (
|
||||||
|
@ -165,6 +167,7 @@ const WebhookEvents: React.FC<WebhookEventsProps> = ({
|
||||||
</ListItemCell>
|
</ListItemCell>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
))}
|
))}
|
||||||
|
</ListBody>
|
||||||
</List>
|
</List>
|
||||||
</div>
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -177,7 +180,7 @@ export default WebhookEvents;
|
||||||
|
|
||||||
type Actions = string[];
|
type Actions = string[];
|
||||||
|
|
||||||
const AsyncWebhookTypes: Record<string, Actions> = {
|
export const AsyncWebhookTypes: Record<string, Actions> = {
|
||||||
ADDRESS: ["CREATED", "UPDATED", "DELETED"],
|
ADDRESS: ["CREATED", "UPDATED", "DELETED"],
|
||||||
APP: ["INSTALLED", "UPDATED", "DELETED"],
|
APP: ["INSTALLED", "UPDATED", "DELETED"],
|
||||||
ATTRIBUTE: ["CREATED", "UPDATED", "DELETED"],
|
ATTRIBUTE: ["CREATED", "UPDATED", "DELETED"],
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { makeStyles } from "@saleor/macaw-ui";
|
||||||
export const useStyles = makeStyles(
|
export const useStyles = makeStyles(
|
||||||
theme => ({
|
theme => ({
|
||||||
eventsWrapper: {
|
eventsWrapper: {
|
||||||
overflow: "scroll",
|
|
||||||
padding: theme.spacing(4),
|
padding: theme.spacing(4),
|
||||||
paddingLeft: 0,
|
paddingLeft: 0,
|
||||||
},
|
},
|
||||||
|
@ -17,6 +16,10 @@ export const useStyles = makeStyles(
|
||||||
padding: theme.spacing(1),
|
padding: theme.spacing(1),
|
||||||
minHeight: 0,
|
minHeight: 0,
|
||||||
},
|
},
|
||||||
|
listBody: {
|
||||||
|
height: 300,
|
||||||
|
overflow: "scroll",
|
||||||
|
},
|
||||||
listItem: {
|
listItem: {
|
||||||
minHeight: 0,
|
minHeight: 0,
|
||||||
gap: 0,
|
gap: 0,
|
||||||
|
@ -24,10 +27,7 @@ export const useStyles = makeStyles(
|
||||||
},
|
},
|
||||||
listItemCell: {
|
listItemCell: {
|
||||||
paddingLeft: "0 !important",
|
paddingLeft: "0 !important",
|
||||||
},
|
wordBreak: "break-all",
|
||||||
listItems: {
|
|
||||||
height: 300,
|
|
||||||
overflow: "scroll",
|
|
||||||
},
|
},
|
||||||
checkbox: {
|
checkbox: {
|
||||||
padding: 0,
|
padding: 0,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
WebhookEventTypeSyncEnum,
|
WebhookEventTypeSyncEnum,
|
||||||
} from "@dashboard/graphql";
|
} from "@dashboard/graphql";
|
||||||
import { Fetcher } from "@graphiql/toolkit";
|
import { Fetcher } from "@graphiql/toolkit";
|
||||||
|
import { ApolloMockedProvider } from "@test/ApolloMockedProvider";
|
||||||
import { render, screen } from "@testing-library/react";
|
import { render, screen } from "@testing-library/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
@ -51,7 +52,11 @@ describe("WebhookSubscriptionQuery", () => {
|
||||||
// const user = userEvent.setup();
|
// const user = userEvent.setup();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
render(<WebhookSubscriptionQuery {...props} />);
|
render(
|
||||||
|
<ApolloMockedProvider>
|
||||||
|
<WebhookSubscriptionQuery {...props} />
|
||||||
|
</ApolloMockedProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(screen.queryByTestId("graphiql-container")).toBeInTheDocument();
|
expect(screen.queryByTestId("graphiql-container")).toBeInTheDocument();
|
||||||
|
|
|
@ -59,6 +59,7 @@ const WebhookSubscriptionQuery: React.FC<WebhookSubscriptionQueryProps> = ({
|
||||||
onEditQuery={setQuery}
|
onEditQuery={setQuery}
|
||||||
plugins={[explorerPlugin]}
|
plugins={[explorerPlugin]}
|
||||||
isHeadersEditorEnabled={false}
|
isHeadersEditorEnabled={false}
|
||||||
|
asyncEvents={data.asyncEvents}
|
||||||
/>
|
/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -1,88 +1,6 @@
|
||||||
import { MultiAutocompleteChoiceType } from "@dashboard/components/MultiAutocompleteSelectField";
|
|
||||||
import { WebhookEventTypeAsyncEnum } from "@dashboard/graphql";
|
import { WebhookEventTypeAsyncEnum } from "@dashboard/graphql";
|
||||||
|
|
||||||
import { filterSelectedAsyncEvents, mapAsyncEventsToChoices } from "./utils";
|
import { filterSelectedAsyncEvents } from "./utils";
|
||||||
|
|
||||||
describe("Custom Apps mapping events", () => {
|
|
||||||
it("should return enabled async events choices when not any event selected", () => {
|
|
||||||
// Arrange
|
|
||||||
const events: WebhookEventTypeAsyncEnum[] = [
|
|
||||||
WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
|
||||||
WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
|
||||||
WebhookEventTypeAsyncEnum.PRODUCT_CREATED,
|
|
||||||
];
|
|
||||||
const selectedEvents: WebhookEventTypeAsyncEnum[] = [
|
|
||||||
WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const asyncEvents = mapAsyncEventsToChoices(events, selectedEvents);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
const expectedAsyncEvents: MultiAutocompleteChoiceType[] = [
|
|
||||||
{
|
|
||||||
label: WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
|
||||||
value: WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
|
||||||
badge: undefined,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
|
||||||
value: WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
|
||||||
badge: undefined,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: WebhookEventTypeAsyncEnum.PRODUCT_CREATED,
|
|
||||||
value: WebhookEventTypeAsyncEnum.PRODUCT_CREATED,
|
|
||||||
badge: undefined,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
expect(asyncEvents).toHaveLength(3);
|
|
||||||
expect(asyncEvents).toEqual(expectedAsyncEvents);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return disabled async events choices when any event selected", () => {
|
|
||||||
// Arrange
|
|
||||||
const events: WebhookEventTypeAsyncEnum[] = [
|
|
||||||
WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
|
||||||
WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
|
||||||
WebhookEventTypeAsyncEnum.PRODUCT_CREATED,
|
|
||||||
];
|
|
||||||
const selectedEvents: WebhookEventTypeAsyncEnum[] = [
|
|
||||||
WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
|
||||||
WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const asyncEvents = mapAsyncEventsToChoices(events, selectedEvents);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
const expectedAsyncEvents: MultiAutocompleteChoiceType[] = [
|
|
||||||
{
|
|
||||||
label: WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
|
||||||
value: WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
|
||||||
badge: undefined,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
|
||||||
value: WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
|
||||||
badge: undefined,
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: WebhookEventTypeAsyncEnum.PRODUCT_CREATED,
|
|
||||||
value: WebhookEventTypeAsyncEnum.PRODUCT_CREATED,
|
|
||||||
badge: undefined,
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
expect(asyncEvents).toHaveLength(3);
|
|
||||||
expect(asyncEvents).toEqual(expectedAsyncEvents);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Custom Apps filtering events", () => {
|
describe("Custom Apps filtering events", () => {
|
||||||
it("should return selected async event types when not any event selected", () => {
|
it("should return selected async event types when not any event selected", () => {
|
||||||
|
|
|
@ -1,71 +1,9 @@
|
||||||
import { MultiAutocompleteChoiceType } from "@dashboard/components/MultiAutocompleteSelectField";
|
import { WebhookEventTypeAsyncEnum, WebhookFragment } from "@dashboard/graphql";
|
||||||
import PreviewPill from "@dashboard/components/PreviewPill";
|
|
||||||
import {
|
|
||||||
WebhookEventTypeAsyncEnum,
|
|
||||||
WebhookEventTypeSyncEnum,
|
|
||||||
WebhookFragment,
|
|
||||||
} from "@dashboard/graphql";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
export function isUnnamed(webhook: WebhookFragment | undefined): boolean {
|
export function isUnnamed(webhook: WebhookFragment | undefined): boolean {
|
||||||
return !webhook?.name;
|
return !webhook?.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebhookEventType = WebhookEventTypeSyncEnum | WebhookEventTypeAsyncEnum;
|
|
||||||
|
|
||||||
const isWebhookInPreview = (webhook: WebhookEventType) =>
|
|
||||||
(
|
|
||||||
[
|
|
||||||
WebhookEventTypeSyncEnum.CHECKOUT_CALCULATE_TAXES,
|
|
||||||
WebhookEventTypeSyncEnum.ORDER_CALCULATE_TAXES,
|
|
||||||
] as WebhookEventType[]
|
|
||||||
).includes(webhook);
|
|
||||||
|
|
||||||
const isAsyncWebhookInPreview = (webhook: WebhookEventType) =>
|
|
||||||
(
|
|
||||||
[
|
|
||||||
WebhookEventTypeAsyncEnum.GIFT_CARD_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.ORDER_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.CUSTOMER_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.COLLECTION_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.PRODUCT_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.PRODUCT_VARIANT_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.CHECKOUT_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.FULFILLMENT_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.SHIPPING_ZONE_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.TRANSACTION_ITEM_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.WAREHOUSE_METADATA_UPDATED,
|
|
||||||
WebhookEventTypeAsyncEnum.VOUCHER_METADATA_UPDATED,
|
|
||||||
] as WebhookEventType[]
|
|
||||||
).includes(webhook);
|
|
||||||
|
|
||||||
export function mapSyncEventsToChoices(
|
|
||||||
events: WebhookEventTypeSyncEnum[],
|
|
||||||
): MultiAutocompleteChoiceType[] {
|
|
||||||
return events.map(event => ({
|
|
||||||
label: event,
|
|
||||||
value: event,
|
|
||||||
badge: isWebhookInPreview(event) ? <PreviewPill /> : undefined,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapAsyncEventsToChoices(
|
|
||||||
events: WebhookEventTypeAsyncEnum[],
|
|
||||||
selectedEvents: WebhookEventTypeAsyncEnum[],
|
|
||||||
): MultiAutocompleteChoiceType[] {
|
|
||||||
const isAnyAsyncEventSelected = selectedEvents.includes(
|
|
||||||
WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
|
||||||
);
|
|
||||||
|
|
||||||
return events.map(event => ({
|
|
||||||
label: event,
|
|
||||||
value: event,
|
|
||||||
badge: isAsyncWebhookInPreview(event) ? <PreviewPill /> : undefined,
|
|
||||||
disabled:
|
|
||||||
event !== WebhookEventTypeAsyncEnum.ANY_EVENTS && isAnyAsyncEventSelected,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
export const filterSelectedAsyncEvents = (
|
export const filterSelectedAsyncEvents = (
|
||||||
asyncEvents: WebhookEventTypeAsyncEnum[],
|
asyncEvents: WebhookEventTypeAsyncEnum[],
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -297,9 +297,9 @@
|
||||||
"ProductVariant",
|
"ProductVariant",
|
||||||
"Product",
|
"Product",
|
||||||
"ProductType",
|
"ProductType",
|
||||||
"Collection",
|
|
||||||
"Category",
|
|
||||||
"ProductMedia",
|
"ProductMedia",
|
||||||
|
"Category",
|
||||||
|
"Collection",
|
||||||
"PageType"
|
"PageType"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5095,6 +5095,129 @@ export function useAddressValidationRulesLazyQuery(baseOptions?: ApolloReactHook
|
||||||
export type AddressValidationRulesQueryHookResult = ReturnType<typeof useAddressValidationRulesQuery>;
|
export type AddressValidationRulesQueryHookResult = ReturnType<typeof useAddressValidationRulesQuery>;
|
||||||
export type AddressValidationRulesLazyQueryHookResult = ReturnType<typeof useAddressValidationRulesLazyQuery>;
|
export type AddressValidationRulesLazyQueryHookResult = ReturnType<typeof useAddressValidationRulesLazyQuery>;
|
||||||
export type AddressValidationRulesQueryResult = Apollo.QueryResult<Types.AddressValidationRulesQuery, Types.AddressValidationRulesQueryVariables>;
|
export type AddressValidationRulesQueryResult = Apollo.QueryResult<Types.AddressValidationRulesQuery, Types.AddressValidationRulesQueryVariables>;
|
||||||
|
export const TriggerWebhookDryRunDocument = gql`
|
||||||
|
mutation TriggerWebhookDryRun($objectId: ID!, $query: String!) {
|
||||||
|
webhookDryRun(objectId: $objectId, query: $query) {
|
||||||
|
payload
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export type TriggerWebhookDryRunMutationFn = Apollo.MutationFunction<Types.TriggerWebhookDryRunMutation, Types.TriggerWebhookDryRunMutationVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useTriggerWebhookDryRunMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useTriggerWebhookDryRunMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useTriggerWebhookDryRunMutation` returns a tuple that includes:
|
||||||
|
* - A mutate function that you can call at any time to execute the mutation
|
||||||
|
* - An object with fields that represent the current status of the mutation's execution
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const [triggerWebhookDryRunMutation, { data, loading, error }] = useTriggerWebhookDryRunMutation({
|
||||||
|
* variables: {
|
||||||
|
* objectId: // value for 'objectId'
|
||||||
|
* query: // value for 'query'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useTriggerWebhookDryRunMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.TriggerWebhookDryRunMutation, Types.TriggerWebhookDryRunMutationVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useMutation<Types.TriggerWebhookDryRunMutation, Types.TriggerWebhookDryRunMutationVariables>(TriggerWebhookDryRunDocument, options);
|
||||||
|
}
|
||||||
|
export type TriggerWebhookDryRunMutationHookResult = ReturnType<typeof useTriggerWebhookDryRunMutation>;
|
||||||
|
export type TriggerWebhookDryRunMutationResult = Apollo.MutationResult<Types.TriggerWebhookDryRunMutation>;
|
||||||
|
export type TriggerWebhookDryRunMutationOptions = Apollo.BaseMutationOptions<Types.TriggerWebhookDryRunMutation, Types.TriggerWebhookDryRunMutationVariables>;
|
||||||
|
export const CheckoutListDocument = gql`
|
||||||
|
query CheckoutList($first: Int, $after: String, $last: Int, $before: String) {
|
||||||
|
checkouts(before: $before, after: $after, first: $first, last: $last) {
|
||||||
|
edges {
|
||||||
|
cursor
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
created
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
hasPreviousPage
|
||||||
|
hasNextPage
|
||||||
|
startCursor
|
||||||
|
endCursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useCheckoutListQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useCheckoutListQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useCheckoutListQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useCheckoutListQuery({
|
||||||
|
* variables: {
|
||||||
|
* first: // value for 'first'
|
||||||
|
* after: // value for 'after'
|
||||||
|
* last: // value for 'last'
|
||||||
|
* before: // value for 'before'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useCheckoutListQuery(baseOptions?: ApolloReactHooks.QueryHookOptions<Types.CheckoutListQuery, Types.CheckoutListQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useQuery<Types.CheckoutListQuery, Types.CheckoutListQueryVariables>(CheckoutListDocument, options);
|
||||||
|
}
|
||||||
|
export function useCheckoutListLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<Types.CheckoutListQuery, Types.CheckoutListQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useLazyQuery<Types.CheckoutListQuery, Types.CheckoutListQueryVariables>(CheckoutListDocument, options);
|
||||||
|
}
|
||||||
|
export type CheckoutListQueryHookResult = ReturnType<typeof useCheckoutListQuery>;
|
||||||
|
export type CheckoutListLazyQueryHookResult = ReturnType<typeof useCheckoutListLazyQuery>;
|
||||||
|
export type CheckoutListQueryResult = Apollo.QueryResult<Types.CheckoutListQuery, Types.CheckoutListQueryVariables>;
|
||||||
|
export const ChannelListDocument = gql`
|
||||||
|
query ChannelList {
|
||||||
|
channels {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useChannelListQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useChannelListQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useChannelListQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useChannelListQuery({
|
||||||
|
* variables: {
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useChannelListQuery(baseOptions?: ApolloReactHooks.QueryHookOptions<Types.ChannelListQuery, Types.ChannelListQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useQuery<Types.ChannelListQuery, Types.ChannelListQueryVariables>(ChannelListDocument, options);
|
||||||
|
}
|
||||||
|
export function useChannelListLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<Types.ChannelListQuery, Types.ChannelListQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useLazyQuery<Types.ChannelListQuery, Types.ChannelListQueryVariables>(ChannelListDocument, options);
|
||||||
|
}
|
||||||
|
export type ChannelListQueryHookResult = ReturnType<typeof useChannelListQuery>;
|
||||||
|
export type ChannelListLazyQueryHookResult = ReturnType<typeof useChannelListLazyQuery>;
|
||||||
|
export type ChannelListQueryResult = Apollo.QueryResult<Types.ChannelListQuery, Types.ChannelListQueryVariables>;
|
||||||
export const CheckIfOrderExistsDocument = gql`
|
export const CheckIfOrderExistsDocument = gql`
|
||||||
query CheckIfOrderExists($id: ID!) {
|
query CheckIfOrderExists($id: ID!) {
|
||||||
order(id: $id) {
|
order(id: $id) {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -329,6 +329,12 @@ export type AttributeCreateInput = {
|
||||||
storefrontSearchPosition?: InputMaybe<Scalars['Int']>;
|
storefrontSearchPosition?: InputMaybe<Scalars['Int']>;
|
||||||
/** Whether the attribute can be displayed in the admin product list. */
|
/** Whether the attribute can be displayed in the admin product list. */
|
||||||
availableInGrid?: InputMaybe<Scalars['Boolean']>;
|
availableInGrid?: InputMaybe<Scalars['Boolean']>;
|
||||||
|
/**
|
||||||
|
* External ID of this attribute.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An enumeration. */
|
/** An enumeration. */
|
||||||
|
@ -459,6 +465,12 @@ export type AttributeUpdateInput = {
|
||||||
storefrontSearchPosition?: InputMaybe<Scalars['Int']>;
|
storefrontSearchPosition?: InputMaybe<Scalars['Int']>;
|
||||||
/** Whether the attribute can be displayed in the admin product list. */
|
/** Whether the attribute can be displayed in the admin product list. */
|
||||||
availableInGrid?: InputMaybe<Scalars['Boolean']>;
|
availableInGrid?: InputMaybe<Scalars['Boolean']>;
|
||||||
|
/**
|
||||||
|
* External ID of this product.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AttributeValueCreateInput = {
|
export type AttributeValueCreateInput = {
|
||||||
|
@ -482,6 +494,12 @@ export type AttributeValueCreateInput = {
|
||||||
fileUrl?: InputMaybe<Scalars['String']>;
|
fileUrl?: InputMaybe<Scalars['String']>;
|
||||||
/** File content type. */
|
/** File content type. */
|
||||||
contentType?: InputMaybe<Scalars['String']>;
|
contentType?: InputMaybe<Scalars['String']>;
|
||||||
|
/**
|
||||||
|
* External ID of this attribute value.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
/** Name of a value displayed in the interface. */
|
/** Name of a value displayed in the interface. */
|
||||||
name: Scalars['String'];
|
name: Scalars['String'];
|
||||||
};
|
};
|
||||||
|
@ -494,8 +512,26 @@ export type AttributeValueFilterInput = {
|
||||||
export type AttributeValueInput = {
|
export type AttributeValueInput = {
|
||||||
/** ID of the selected attribute. */
|
/** ID of the selected attribute. */
|
||||||
id?: InputMaybe<Scalars['ID']>;
|
id?: InputMaybe<Scalars['ID']>;
|
||||||
/** The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. */
|
/** The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. This field will be removed in Saleor 4.0. */
|
||||||
values?: InputMaybe<Array<Scalars['String']>>;
|
values?: InputMaybe<Array<Scalars['String']>>;
|
||||||
|
/**
|
||||||
|
* Attribute value ID.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.9.
|
||||||
|
*/
|
||||||
|
dropdown?: InputMaybe<AttributeValueSelectableTypeInput>;
|
||||||
|
/**
|
||||||
|
* List of attribute value IDs.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.9.
|
||||||
|
*/
|
||||||
|
multiselect?: InputMaybe<Array<AttributeValueSelectableTypeInput>>;
|
||||||
|
/**
|
||||||
|
* Numeric value of an attribute.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.9.
|
||||||
|
*/
|
||||||
|
numeric?: InputMaybe<Scalars['String']>;
|
||||||
/** URL of the file attribute. Every time, a new value is created. */
|
/** URL of the file attribute. Every time, a new value is created. */
|
||||||
file?: InputMaybe<Scalars['String']>;
|
file?: InputMaybe<Scalars['String']>;
|
||||||
/** File content type. */
|
/** File content type. */
|
||||||
|
@ -514,6 +550,18 @@ export type AttributeValueInput = {
|
||||||
dateTime?: InputMaybe<Scalars['DateTime']>;
|
dateTime?: InputMaybe<Scalars['DateTime']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents attribute value. If no ID provided, value will be resolved.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.9.
|
||||||
|
*/
|
||||||
|
export type AttributeValueSelectableTypeInput = {
|
||||||
|
/** ID of an attribute value. */
|
||||||
|
id?: InputMaybe<Scalars['ID']>;
|
||||||
|
/** The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. */
|
||||||
|
value?: InputMaybe<Scalars['String']>;
|
||||||
|
};
|
||||||
|
|
||||||
export type AttributeValueTranslationInput = {
|
export type AttributeValueTranslationInput = {
|
||||||
name?: InputMaybe<Scalars['String']>;
|
name?: InputMaybe<Scalars['String']>;
|
||||||
/**
|
/**
|
||||||
|
@ -547,6 +595,12 @@ export type AttributeValueUpdateInput = {
|
||||||
fileUrl?: InputMaybe<Scalars['String']>;
|
fileUrl?: InputMaybe<Scalars['String']>;
|
||||||
/** File content type. */
|
/** File content type. */
|
||||||
contentType?: InputMaybe<Scalars['String']>;
|
contentType?: InputMaybe<Scalars['String']>;
|
||||||
|
/**
|
||||||
|
* External ID of this attribute value.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
/** Name of a value displayed in the interface. */
|
/** Name of a value displayed in the interface. */
|
||||||
name?: InputMaybe<Scalars['String']>;
|
name?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
@ -1388,6 +1442,12 @@ export type CustomerInput = {
|
||||||
note?: InputMaybe<Scalars['String']>;
|
note?: InputMaybe<Scalars['String']>;
|
||||||
/** User language code. */
|
/** User language code. */
|
||||||
languageCode?: InputMaybe<LanguageCodeEnum>;
|
languageCode?: InputMaybe<LanguageCodeEnum>;
|
||||||
|
/**
|
||||||
|
* External ID of the customer.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DateRangeInput = {
|
export type DateRangeInput = {
|
||||||
|
@ -1511,6 +1571,12 @@ export type DraftOrderCreateInput = {
|
||||||
channelId?: InputMaybe<Scalars['ID']>;
|
channelId?: InputMaybe<Scalars['ID']>;
|
||||||
/** URL of a view where users should be redirected to see the order details. URL in RFC 1808 format. */
|
/** URL of a view where users should be redirected to see the order details. URL in RFC 1808 format. */
|
||||||
redirectUrl?: InputMaybe<Scalars['String']>;
|
redirectUrl?: InputMaybe<Scalars['String']>;
|
||||||
|
/**
|
||||||
|
* External ID of this order.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
/** Variant line input consisting of variant ID and quantity of products. */
|
/** Variant line input consisting of variant ID and quantity of products. */
|
||||||
lines?: InputMaybe<Array<OrderLineCreateInput>>;
|
lines?: InputMaybe<Array<OrderLineCreateInput>>;
|
||||||
};
|
};
|
||||||
|
@ -1536,6 +1602,12 @@ export type DraftOrderInput = {
|
||||||
channelId?: InputMaybe<Scalars['ID']>;
|
channelId?: InputMaybe<Scalars['ID']>;
|
||||||
/** URL of a view where users should be redirected to see the order details. URL in RFC 1808 format. */
|
/** URL of a view where users should be redirected to see the order details. URL in RFC 1808 format. */
|
||||||
redirectUrl?: InputMaybe<Scalars['String']>;
|
redirectUrl?: InputMaybe<Scalars['String']>;
|
||||||
|
/**
|
||||||
|
* External ID of this order.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum EventDeliveryAttemptSortField {
|
export enum EventDeliveryAttemptSortField {
|
||||||
|
@ -2785,6 +2857,18 @@ export enum MeasurementUnitsEnum {
|
||||||
TONNE = 'TONNE'
|
TONNE = 'TONNE'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum MediaChoicesSortField {
|
||||||
|
/** Sort media by ID. */
|
||||||
|
ID = 'ID'
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MediaSortingInput = {
|
||||||
|
/** Specifies the direction in which to sort products. */
|
||||||
|
direction: OrderDirection;
|
||||||
|
/** Sort media by the selected field. */
|
||||||
|
field: MediaChoicesSortField;
|
||||||
|
};
|
||||||
|
|
||||||
export type MenuCreateInput = {
|
export type MenuCreateInput = {
|
||||||
/** Name of the menu. */
|
/** Name of the menu. */
|
||||||
name: Scalars['String'];
|
name: Scalars['String'];
|
||||||
|
@ -3351,6 +3435,12 @@ export type OrderUpdateInput = {
|
||||||
userEmail?: InputMaybe<Scalars['String']>;
|
userEmail?: InputMaybe<Scalars['String']>;
|
||||||
/** Shipping address of the customer. */
|
/** Shipping address of the customer. */
|
||||||
shippingAddress?: InputMaybe<AddressInput>;
|
shippingAddress?: InputMaybe<AddressInput>;
|
||||||
|
/**
|
||||||
|
* External ID of this order.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OrderUpdateShippingInput = {
|
export type OrderUpdateShippingInput = {
|
||||||
|
@ -3883,6 +3973,12 @@ export type ProductCreateInput = {
|
||||||
* Added in Saleor 3.8.
|
* Added in Saleor 3.8.
|
||||||
*/
|
*/
|
||||||
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
||||||
|
/**
|
||||||
|
* External ID of this product.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
/** ID of the type that product belongs to. */
|
/** ID of the type that product belongs to. */
|
||||||
productType: Scalars['ID'];
|
productType: Scalars['ID'];
|
||||||
};
|
};
|
||||||
|
@ -4028,6 +4124,12 @@ export type ProductInput = {
|
||||||
* Added in Saleor 3.8.
|
* Added in Saleor 3.8.
|
||||||
*/
|
*/
|
||||||
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
||||||
|
/**
|
||||||
|
* External ID of this product.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ProductMediaCreateInput = {
|
export type ProductMediaCreateInput = {
|
||||||
|
@ -4244,6 +4346,12 @@ export type ProductVariantBulkCreateInput = {
|
||||||
* Added in Saleor 3.8.
|
* Added in Saleor 3.8.
|
||||||
*/
|
*/
|
||||||
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
||||||
|
/**
|
||||||
|
* External ID of this product variant.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
/** Stocks of a product available for sale. */
|
/** Stocks of a product available for sale. */
|
||||||
stocks?: InputMaybe<Array<StockInput>>;
|
stocks?: InputMaybe<Array<StockInput>>;
|
||||||
/** List of prices assigned to channels. */
|
/** List of prices assigned to channels. */
|
||||||
|
@ -4306,6 +4414,12 @@ export type ProductVariantCreateInput = {
|
||||||
* Added in Saleor 3.8.
|
* Added in Saleor 3.8.
|
||||||
*/
|
*/
|
||||||
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
||||||
|
/**
|
||||||
|
* External ID of this product variant.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
/** Product ID of which type is the variant. */
|
/** Product ID of which type is the variant. */
|
||||||
product: Scalars['ID'];
|
product: Scalars['ID'];
|
||||||
/** Stocks of a product available for sale. */
|
/** Stocks of a product available for sale. */
|
||||||
|
@ -4359,6 +4473,12 @@ export type ProductVariantInput = {
|
||||||
* Added in Saleor 3.8.
|
* Added in Saleor 3.8.
|
||||||
*/
|
*/
|
||||||
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
privateMetadata?: InputMaybe<Array<MetadataInput>>;
|
||||||
|
/**
|
||||||
|
* External ID of this product variant.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum ProductVariantSortField {
|
export enum ProductVariantSortField {
|
||||||
|
@ -5142,6 +5262,12 @@ export type UserCreateInput = {
|
||||||
note?: InputMaybe<Scalars['String']>;
|
note?: InputMaybe<Scalars['String']>;
|
||||||
/** User language code. */
|
/** User language code. */
|
||||||
languageCode?: InputMaybe<LanguageCodeEnum>;
|
languageCode?: InputMaybe<LanguageCodeEnum>;
|
||||||
|
/**
|
||||||
|
* External ID of the customer.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
/** URL of a view where users should be redirected to set the password. URL in RFC 1808 format. */
|
/** URL of a view where users should be redirected to set the password. URL in RFC 1808 format. */
|
||||||
redirectUrl?: InputMaybe<Scalars['String']>;
|
redirectUrl?: InputMaybe<Scalars['String']>;
|
||||||
/** Slug of a channel which will be used for notify user. Optional when only one channel exists. */
|
/** Slug of a channel which will be used for notify user. Optional when only one channel exists. */
|
||||||
|
@ -5320,6 +5446,12 @@ export type WarehouseCreateInput = {
|
||||||
slug?: InputMaybe<Scalars['String']>;
|
slug?: InputMaybe<Scalars['String']>;
|
||||||
/** The email address of the warehouse. */
|
/** The email address of the warehouse. */
|
||||||
email?: InputMaybe<Scalars['String']>;
|
email?: InputMaybe<Scalars['String']>;
|
||||||
|
/**
|
||||||
|
* External ID of the warehouse.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
/** Warehouse name. */
|
/** Warehouse name. */
|
||||||
name: Scalars['String'];
|
name: Scalars['String'];
|
||||||
/** Address of the warehouse. */
|
/** Address of the warehouse. */
|
||||||
|
@ -5368,6 +5500,12 @@ export type WarehouseUpdateInput = {
|
||||||
slug?: InputMaybe<Scalars['String']>;
|
slug?: InputMaybe<Scalars['String']>;
|
||||||
/** The email address of the warehouse. */
|
/** The email address of the warehouse. */
|
||||||
email?: InputMaybe<Scalars['String']>;
|
email?: InputMaybe<Scalars['String']>;
|
||||||
|
/**
|
||||||
|
* External ID of the warehouse.
|
||||||
|
*
|
||||||
|
* Added in Saleor 3.10.
|
||||||
|
*/
|
||||||
|
externalReference?: InputMaybe<Scalars['String']>;
|
||||||
/** Warehouse name. */
|
/** Warehouse name. */
|
||||||
name?: InputMaybe<Scalars['String']>;
|
name?: InputMaybe<Scalars['String']>;
|
||||||
/** Address of the warehouse. */
|
/** Address of the warehouse. */
|
||||||
|
@ -5425,13 +5563,22 @@ export type WebhookCreateInput = {
|
||||||
query?: InputMaybe<Scalars['String']>;
|
query?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** An enumeration. */
|
||||||
|
export enum WebhookDryRunErrorCode {
|
||||||
|
GRAPHQL_ERROR = 'GRAPHQL_ERROR',
|
||||||
|
NOT_FOUND = 'NOT_FOUND',
|
||||||
|
INVALID_ID = 'INVALID_ID',
|
||||||
|
MISSING_PERMISSION = 'MISSING_PERMISSION'
|
||||||
|
}
|
||||||
|
|
||||||
/** An enumeration. */
|
/** An enumeration. */
|
||||||
export enum WebhookErrorCode {
|
export enum WebhookErrorCode {
|
||||||
GRAPHQL_ERROR = 'GRAPHQL_ERROR',
|
GRAPHQL_ERROR = 'GRAPHQL_ERROR',
|
||||||
INVALID = 'INVALID',
|
INVALID = 'INVALID',
|
||||||
NOT_FOUND = 'NOT_FOUND',
|
NOT_FOUND = 'NOT_FOUND',
|
||||||
REQUIRED = 'REQUIRED',
|
REQUIRED = 'REQUIRED',
|
||||||
UNIQUE = 'UNIQUE'
|
UNIQUE = 'UNIQUE',
|
||||||
|
DELETE_FAILED = 'DELETE_FAILED'
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Enum determining type of webhook. */
|
/** Enum determining type of webhook. */
|
||||||
|
@ -6200,6 +6347,15 @@ export enum WebhookSampleEventTypeEnum {
|
||||||
OBSERVABILITY = 'OBSERVABILITY'
|
OBSERVABILITY = 'OBSERVABILITY'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** An enumeration. */
|
||||||
|
export enum WebhookTriggerErrorCode {
|
||||||
|
GRAPHQL_ERROR = 'GRAPHQL_ERROR',
|
||||||
|
NOT_FOUND = 'NOT_FOUND',
|
||||||
|
INVALID_ID = 'INVALID_ID',
|
||||||
|
MISSING_PERMISSION = 'MISSING_PERMISSION',
|
||||||
|
MISSING_QUERY = 'MISSING_QUERY'
|
||||||
|
}
|
||||||
|
|
||||||
export type WebhookUpdateInput = {
|
export type WebhookUpdateInput = {
|
||||||
/** The new name of the webhook. */
|
/** The new name of the webhook. */
|
||||||
name?: InputMaybe<Scalars['String']>;
|
name?: InputMaybe<Scalars['String']>;
|
||||||
|
@ -6677,6 +6833,29 @@ export type AddressValidationRulesQueryVariables = Exact<{
|
||||||
|
|
||||||
export type AddressValidationRulesQuery = { __typename: 'Query', addressValidationRules: { __typename: 'AddressValidationData', allowedFields: Array<string>, countryAreaChoices: Array<{ __typename: 'ChoiceValue', raw: string | null, verbose: string | null }> } | null };
|
export type AddressValidationRulesQuery = { __typename: 'Query', addressValidationRules: { __typename: 'AddressValidationData', allowedFields: Array<string>, countryAreaChoices: Array<{ __typename: 'ChoiceValue', raw: string | null, verbose: string | null }> } | null };
|
||||||
|
|
||||||
|
export type TriggerWebhookDryRunMutationVariables = Exact<{
|
||||||
|
objectId: Scalars['ID'];
|
||||||
|
query: Scalars['String'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type TriggerWebhookDryRunMutation = { __typename: 'Mutation', webhookDryRun: { __typename: 'WebhookDryRun', payload: any | null, errors: Array<{ __typename: 'WebhookDryRunError', field: string | null, message: string | null }> } | null };
|
||||||
|
|
||||||
|
export type CheckoutListQueryVariables = Exact<{
|
||||||
|
first?: InputMaybe<Scalars['Int']>;
|
||||||
|
after?: InputMaybe<Scalars['String']>;
|
||||||
|
last?: InputMaybe<Scalars['Int']>;
|
||||||
|
before?: InputMaybe<Scalars['String']>;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type CheckoutListQuery = { __typename: 'Query', checkouts: { __typename: 'CheckoutCountableConnection', edges: Array<{ __typename: 'CheckoutCountableEdge', cursor: string, node: { __typename: 'Checkout', id: string, created: any } }>, pageInfo: { __typename: 'PageInfo', hasPreviousPage: boolean, hasNextPage: boolean, startCursor: string | null, endCursor: string | null } } | null };
|
||||||
|
|
||||||
|
export type ChannelListQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
|
export type ChannelListQuery = { __typename: 'Query', channels: Array<{ __typename: 'Channel', id: string, name: string }> | null };
|
||||||
|
|
||||||
export type CheckIfOrderExistsQueryVariables = Exact<{
|
export type CheckIfOrderExistsQueryVariables = Exact<{
|
||||||
id: Scalars['ID'];
|
id: Scalars['ID'];
|
||||||
}>;
|
}>;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export * from "./address";
|
export * from "./address";
|
||||||
export * from "./apps";
|
export * from "./apps";
|
||||||
export * from "./pageTypes";
|
export * from "./pageTypes";
|
||||||
|
export * from "./products";
|
||||||
export * from "./warehouses";
|
export * from "./warehouses";
|
||||||
|
|
277
testUtils/mocks/products.ts
Normal file
277
testUtils/mocks/products.ts
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
import { MockedResponse } from "@apollo/client/testing";
|
||||||
|
import { productListQuery } from "@dashboard/products/queries";
|
||||||
|
|
||||||
|
export const productsMocks: MockedResponse[] = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: productListQuery,
|
||||||
|
variables: {
|
||||||
|
first: 3,
|
||||||
|
hasChannel: true,
|
||||||
|
hasSelectedAttributes: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
data: {
|
||||||
|
products: {
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
node: {
|
||||||
|
id: "UHJvZHVjdDo3Mg==",
|
||||||
|
name: "Apple Juice",
|
||||||
|
thumbnail: {
|
||||||
|
url: "https://wb-t-3-4-6.staging.saleor.cloud/media/thumbnails/products/saleordemoproduct_fd_juice_06_XO6p2Xu_thumbnail_256.png",
|
||||||
|
__typename: "Image",
|
||||||
|
},
|
||||||
|
productType: {
|
||||||
|
id: "UHJvZHVjdFR5cGU6OQ==",
|
||||||
|
name: "Juice",
|
||||||
|
hasVariants: true,
|
||||||
|
__typename: "ProductType",
|
||||||
|
},
|
||||||
|
channelListings: [
|
||||||
|
{
|
||||||
|
isPublished: true,
|
||||||
|
publicationDate: "2020-01-01",
|
||||||
|
isAvailableForPurchase: true,
|
||||||
|
availableForPurchase: "2020-08-31",
|
||||||
|
visibleInListings: true,
|
||||||
|
channel: {
|
||||||
|
id: "Q2hhbm5lbDox",
|
||||||
|
name: "Default channel",
|
||||||
|
currencyCode: "USD",
|
||||||
|
__typename: "Channel",
|
||||||
|
},
|
||||||
|
__typename: "ProductChannelListing",
|
||||||
|
pricing: {
|
||||||
|
priceRange: {
|
||||||
|
start: {
|
||||||
|
net: {
|
||||||
|
amount: 5.0,
|
||||||
|
currency: "USD",
|
||||||
|
__typename: "Money",
|
||||||
|
},
|
||||||
|
__typename: "TaxedMoney",
|
||||||
|
},
|
||||||
|
stop: {
|
||||||
|
net: {
|
||||||
|
amount: 7.0,
|
||||||
|
currency: "USD",
|
||||||
|
__typename: "Money",
|
||||||
|
},
|
||||||
|
__typename: "TaxedMoney",
|
||||||
|
},
|
||||||
|
__typename: "TaxedMoneyRange",
|
||||||
|
},
|
||||||
|
__typename: "ProductPricingInfo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
__typename: "Product",
|
||||||
|
updatedAt: "2021-03-10T12:31:34.521213+00:00",
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
attribute: {
|
||||||
|
id: "QXR0cmlidXRlOjE2",
|
||||||
|
__typename: "Attribute",
|
||||||
|
},
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
id: "QXR0cmlidXRlVmFsdWU6Mw==",
|
||||||
|
name: "Apple",
|
||||||
|
slug: "apple",
|
||||||
|
file: null,
|
||||||
|
reference: null,
|
||||||
|
boolean: null,
|
||||||
|
date: null,
|
||||||
|
dateTime: null,
|
||||||
|
value: "",
|
||||||
|
__typename: "AttributeValue",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
__typename: "SelectedAttribute",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
__typename: "ProductCountableEdge",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: {
|
||||||
|
id: "UHJvZHVjdDo3NA==",
|
||||||
|
name: "Banana Juice",
|
||||||
|
thumbnail: {
|
||||||
|
url: "https://wb-t-3-4-6.staging.saleor.cloud/media/thumbnails/products/saleordemoproduct_fd_juice_01_thumbnail_256.png",
|
||||||
|
__typename: "Image",
|
||||||
|
},
|
||||||
|
productType: {
|
||||||
|
id: "UHJvZHVjdFR5cGU6OQ==",
|
||||||
|
name: "Juice",
|
||||||
|
hasVariants: true,
|
||||||
|
__typename: "ProductType",
|
||||||
|
},
|
||||||
|
channelListings: [
|
||||||
|
{
|
||||||
|
isPublished: true,
|
||||||
|
publicationDate: "2020-01-01",
|
||||||
|
isAvailableForPurchase: true,
|
||||||
|
availableForPurchase: "2020-08-31",
|
||||||
|
visibleInListings: true,
|
||||||
|
channel: {
|
||||||
|
id: "Q2hhbm5lbDox",
|
||||||
|
name: "Default channel",
|
||||||
|
currencyCode: "USD",
|
||||||
|
__typename: "Channel",
|
||||||
|
},
|
||||||
|
__typename: "ProductChannelListing",
|
||||||
|
pricing: {
|
||||||
|
priceRange: {
|
||||||
|
start: {
|
||||||
|
net: {
|
||||||
|
amount: 5.0,
|
||||||
|
currency: "USD",
|
||||||
|
__typename: "Money",
|
||||||
|
},
|
||||||
|
__typename: "TaxedMoney",
|
||||||
|
},
|
||||||
|
stop: {
|
||||||
|
net: {
|
||||||
|
amount: 7.0,
|
||||||
|
currency: "USD",
|
||||||
|
__typename: "Money",
|
||||||
|
},
|
||||||
|
__typename: "TaxedMoney",
|
||||||
|
},
|
||||||
|
__typename: "TaxedMoneyRange",
|
||||||
|
},
|
||||||
|
__typename: "ProductPricingInfo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
__typename: "Product",
|
||||||
|
updatedAt: "2021-03-10T12:31:34.897799+00:00",
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
attribute: {
|
||||||
|
id: "QXR0cmlidXRlOjE2",
|
||||||
|
__typename: "Attribute",
|
||||||
|
},
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
id: "QXR0cmlidXRlVmFsdWU6NTA=",
|
||||||
|
name: "Banana",
|
||||||
|
slug: "banana",
|
||||||
|
file: null,
|
||||||
|
reference: null,
|
||||||
|
boolean: null,
|
||||||
|
date: null,
|
||||||
|
dateTime: null,
|
||||||
|
value: "",
|
||||||
|
__typename: "AttributeValue",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
__typename: "SelectedAttribute",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
__typename: "ProductCountableEdge",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: {
|
||||||
|
id: "UHJvZHVjdDoxMjI=",
|
||||||
|
name: "Bathroom Songs",
|
||||||
|
thumbnail: {
|
||||||
|
url: "https://wb-t-3-4-6.staging.saleor.cloud/media/thumbnails/products/saleor-digital-03_4_thumbnail_256.png",
|
||||||
|
__typename: "Image",
|
||||||
|
},
|
||||||
|
productType: {
|
||||||
|
id: "UHJvZHVjdFR5cGU6MTU=",
|
||||||
|
name: "Audiobook",
|
||||||
|
hasVariants: true,
|
||||||
|
__typename: "ProductType",
|
||||||
|
},
|
||||||
|
channelListings: [
|
||||||
|
{
|
||||||
|
isPublished: true,
|
||||||
|
publicationDate: "2020-01-01",
|
||||||
|
isAvailableForPurchase: true,
|
||||||
|
availableForPurchase: "2020-08-31",
|
||||||
|
visibleInListings: false,
|
||||||
|
channel: {
|
||||||
|
id: "Q2hhbm5lbDox",
|
||||||
|
name: "Default channel",
|
||||||
|
currencyCode: "USD",
|
||||||
|
__typename: "Channel",
|
||||||
|
},
|
||||||
|
__typename: "ProductChannelListing",
|
||||||
|
pricing: {
|
||||||
|
priceRange: {
|
||||||
|
start: {
|
||||||
|
net: {
|
||||||
|
amount: 6.0,
|
||||||
|
currency: "USD",
|
||||||
|
__typename: "Money",
|
||||||
|
},
|
||||||
|
__typename: "TaxedMoney",
|
||||||
|
},
|
||||||
|
stop: {
|
||||||
|
net: {
|
||||||
|
amount: 6.0,
|
||||||
|
currency: "USD",
|
||||||
|
__typename: "Money",
|
||||||
|
},
|
||||||
|
__typename: "TaxedMoney",
|
||||||
|
},
|
||||||
|
__typename: "TaxedMoneyRange",
|
||||||
|
},
|
||||||
|
__typename: "ProductPricingInfo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
__typename: "Product",
|
||||||
|
updatedAt: "2021-03-10T12:31:40.785454+00:00",
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
attribute: {
|
||||||
|
id: "QXR0cmlidXRlOjI2",
|
||||||
|
__typename: "Attribute",
|
||||||
|
},
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
id: "QXR0cmlidXRlVmFsdWU6ODY=",
|
||||||
|
name: "Digital Audio",
|
||||||
|
slug: "digital-audio",
|
||||||
|
file: null,
|
||||||
|
reference: null,
|
||||||
|
boolean: null,
|
||||||
|
date: null,
|
||||||
|
dateTime: null,
|
||||||
|
value: "",
|
||||||
|
__typename: "AttributeValue",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
__typename: "SelectedAttribute",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
__typename: "ProductCountableEdge",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pageInfo: {
|
||||||
|
hasPreviousPage: false,
|
||||||
|
hasNextPage: true,
|
||||||
|
startCursor: "WyJhcHBsZS1qdWljZSJd",
|
||||||
|
endCursor: "WyJiYXRocm9vbS1zb25ncyJd",
|
||||||
|
__typename: "PageInfo",
|
||||||
|
},
|
||||||
|
totalCount: 41,
|
||||||
|
__typename: "ProductCountableConnection",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extensions: {
|
||||||
|
cost: { requestedQueryCost: 13, maximumAvailable: 50000 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default productsMocks;
|
Loading…
Reference in a new issue