Extract "webhooks & events" to separate page (#2818)
* Extract "webhooks & events" to separate page * Create separate /custom-app/ path for custom apps with webhooks * Change all /webhooks/ paths to /custom-apps/ * Update messages * Update generated graphql types * Create findById util * Refactor consts and resolvers for custom app urls * Fix app graphql fragment * Update Miscellaneous icon for Webhooks and Events * Add tests for custom apps utils * Fix dark-mode Miscellaneous icon for Webhooks and Events * adjustments for autotests Co-authored-by: karolm-saleor <karol.macheta@saleor.io>
This commit is contained in:
parent
ef35e5149b
commit
bba95a8fb4
109 changed files with 1053 additions and 910 deletions
|
@ -11,8 +11,8 @@ module.exports = defineConfig({
|
||||||
viewportWidth: 1400,
|
viewportWidth: 1400,
|
||||||
viewportHeight: 660,
|
viewportHeight: 660,
|
||||||
retries: {
|
retries: {
|
||||||
runMode: 1,
|
runMode: 2,
|
||||||
openMode: 0,
|
openMode: 1,
|
||||||
},
|
},
|
||||||
e2e: {
|
e2e: {
|
||||||
env: {
|
env: {
|
||||||
|
@ -23,7 +23,7 @@ module.exports = defineConfig({
|
||||||
config = require("./cypress/plugins/index.js")(on, config);
|
config = require("./cypress/plugins/index.js")(on, config);
|
||||||
on("after:spec", (spec, results) => {
|
on("after:spec", (spec, results) => {
|
||||||
if (results && results.video) {
|
if (results && results.video) {
|
||||||
return fs.unlink(results.video, function(err) {
|
return fs.unlink(results.video, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.warn(`Could not remove video - ${err}`);
|
console.warn(`Could not remove video - ${err}`);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -98,8 +98,6 @@ describe("As a staff user I want to manage apps", () => {
|
||||||
const randomAppName = `${startsWith}${faker.datatype.number()}`;
|
const randomAppName = `${startsWith}${faker.datatype.number()}`;
|
||||||
|
|
||||||
cy.visit(urlList.apps)
|
cy.visit(urlList.apps)
|
||||||
.get(APPS_LIST.webhookAndEventsTab)
|
|
||||||
.click()
|
|
||||||
.get(APPS_LIST.createLocalAppButton)
|
.get(APPS_LIST.createLocalAppButton)
|
||||||
.click()
|
.click()
|
||||||
.get(APP_DETAILS.nameInput)
|
.get(APP_DETAILS.nameInput)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
export const APPS_LIST = {
|
export const APPS_LIST = {
|
||||||
createLocalAppButton: '[data-test-id="create-app"]',
|
createLocalAppButton: '[data-test-id="create-app"]',
|
||||||
webhookAndEventsTab: '[id="WEBHOOKS_AND_EVENTS"]',
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export const urlList = {
|
export const urlList = {
|
||||||
apiUri: Cypress.env("API_URI"),
|
apiUri: Cypress.env("API_URI"),
|
||||||
addProduct: "products/add",
|
addProduct: "products/add",
|
||||||
apps: "apps/",
|
apps: "custom-apps/",
|
||||||
attributes: "attributes/",
|
attributes: "attributes/",
|
||||||
channels: "channels/",
|
channels: "channels/",
|
||||||
categories: "categories/",
|
categories: "categories/",
|
||||||
|
@ -35,7 +35,7 @@ export const urlList = {
|
||||||
export const addVariantUrl = productId =>
|
export const addVariantUrl = productId =>
|
||||||
`${urlList.products}${productId}/${urlList.variants}add`;
|
`${urlList.products}${productId}/${urlList.variants}add`;
|
||||||
|
|
||||||
export const appDetailsUrl = appId => `${urlList.apps}custom/${appId}`;
|
export const appDetailsUrl = appId => `${urlList.apps}${appId}`;
|
||||||
|
|
||||||
export const attributeDetailsUrl = attributeId =>
|
export const attributeDetailsUrl = attributeId =>
|
||||||
`${urlList.attributes}${attributeId}`;
|
`${urlList.attributes}${attributeId}`;
|
||||||
|
|
|
@ -1105,10 +1105,6 @@
|
||||||
"context": "delete variant dialog title",
|
"context": "delete variant dialog title",
|
||||||
"string": "Delete Product Variants"
|
"string": "Delete Product Variants"
|
||||||
},
|
},
|
||||||
"6nSTuC": {
|
|
||||||
"context": "webhooks section name",
|
|
||||||
"string": "Webhooks"
|
|
||||||
},
|
|
||||||
"6sjBvJ": {
|
"6sjBvJ": {
|
||||||
"context": "input placeholder",
|
"context": "input placeholder",
|
||||||
"string": "Search by name, email, etc..."
|
"string": "Search by name, email, etc..."
|
||||||
|
@ -1612,6 +1608,10 @@
|
||||||
"context": "order history message",
|
"context": "order history message",
|
||||||
"string": "Shipping details was sent to customer"
|
"string": "Shipping details was sent to customer"
|
||||||
},
|
},
|
||||||
|
"BFR6CF": {
|
||||||
|
"context": "webhooks and events section name",
|
||||||
|
"string": "Webhooks & Events"
|
||||||
|
},
|
||||||
"BHQrgz": {
|
"BHQrgz": {
|
||||||
"context": "number of subcategories",
|
"context": "number of subcategories",
|
||||||
"string": "Subcategories"
|
"string": "Subcategories"
|
||||||
|
@ -2290,9 +2290,6 @@
|
||||||
"context": "label",
|
"context": "label",
|
||||||
"string": "Min Delivery Time"
|
"string": "Min Delivery Time"
|
||||||
},
|
},
|
||||||
"GDJHXl": {
|
|
||||||
"string": "Local apps are custom webhooks & token pairs that can be used to connect apps and access Saleor API."
|
|
||||||
},
|
|
||||||
"GFJabu": {
|
"GFJabu": {
|
||||||
"context": "dialog header",
|
"context": "dialog header",
|
||||||
"string": "Delete Variant"
|
"string": "Delete Variant"
|
||||||
|
@ -2969,6 +2966,9 @@
|
||||||
"context": "order refund amount",
|
"context": "order refund amount",
|
||||||
"string": "Authorized Amount"
|
"string": "Authorized Amount"
|
||||||
},
|
},
|
||||||
|
"L/sNGY": {
|
||||||
|
"string": "Local apps are custom webhooks & token pairs that can be used to connect apps and access Saleor API."
|
||||||
|
},
|
||||||
"L5io1l": {
|
"L5io1l": {
|
||||||
"context": "returned products list title",
|
"context": "returned products list title",
|
||||||
"string": "Products returned"
|
"string": "Products returned"
|
||||||
|
@ -4236,9 +4236,6 @@
|
||||||
"context": "attribute values",
|
"context": "attribute values",
|
||||||
"string": "Value {number}"
|
"string": "Value {number}"
|
||||||
},
|
},
|
||||||
"UxTSw7": {
|
|
||||||
"string": "Webhooks & Events"
|
|
||||||
},
|
|
||||||
"UxdBmI": {
|
"UxdBmI": {
|
||||||
"context": "collection availability",
|
"context": "collection availability",
|
||||||
"string": "Availability"
|
"string": "Availability"
|
||||||
|
@ -4929,6 +4926,9 @@
|
||||||
"context": "note input subtitle",
|
"context": "note input subtitle",
|
||||||
"string": "Why was this gift card issued. This note will not be shown to the customer. Note will be stored in gift card history"
|
"string": "Why was this gift card issued. This note will not be shown to the customer. Note will be stored in gift card history"
|
||||||
},
|
},
|
||||||
|
"Zz67wc": {
|
||||||
|
"string": "View and update your webhooks and events."
|
||||||
|
},
|
||||||
"a+iRI1": {
|
"a+iRI1": {
|
||||||
"context": "single gift card title",
|
"context": "single gift card title",
|
||||||
"string": "{selectedItemsCount,plural,one{Delete Gift Card} other{Delete Gift Cards}}"
|
"string": "{selectedItemsCount,plural,one{Delete Gift Card} other{Delete Gift Cards}}"
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { useIntl } from "react-intl";
|
||||||
const TabValue: Record<string, AppPagePathSegment> = {
|
const TabValue: Record<string, AppPagePathSegment> = {
|
||||||
SALEOR_APPS: "saleor-apps",
|
SALEOR_APPS: "saleor-apps",
|
||||||
THIRD_PARTY: "third-party",
|
THIRD_PARTY: "third-party",
|
||||||
WEBHOOKS_AND_EVENTS: "webhooks-and-events",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type AllProps = ComponentProps<typeof PageTabs>;
|
type AllProps = ComponentProps<typeof PageTabs>;
|
||||||
|
@ -23,14 +22,6 @@ export const AppPageTabs = ({ showSaleorApps, ...props }: AvailableProps) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
return (
|
return (
|
||||||
<PageTabs {...props}>
|
<PageTabs {...props}>
|
||||||
<PageTab
|
|
||||||
value={TabValue.WEBHOOKS_AND_EVENTS}
|
|
||||||
id="WEBHOOKS_AND_EVENTS"
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Webhooks & Events",
|
|
||||||
id: "UxTSw7",
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<PageTab
|
<PageTab
|
||||||
value={TabValue.THIRD_PARTY}
|
value={TabValue.THIRD_PARTY}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { PaginatorContextDecorator } from "@saleor/storybook/PaginatorContextDec
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { appsInProgress, appsList, customAppsList } from "../../fixtures";
|
import { appsInProgress, appsList } from "../../fixtures";
|
||||||
import AppsListPage, { AppsListPageProps } from "./AppsListPage";
|
import AppsListPage, { AppsListPageProps } from "./AppsListPage";
|
||||||
|
|
||||||
const props: AppsListPageProps = {
|
const props: AppsListPageProps = {
|
||||||
|
@ -24,13 +24,10 @@ const props: AppsListPageProps = {
|
||||||
__typename: "Query",
|
__typename: "Query",
|
||||||
appsInstallations: appsInProgress,
|
appsInstallations: appsInProgress,
|
||||||
},
|
},
|
||||||
customAppsList,
|
|
||||||
disabled: false,
|
disabled: false,
|
||||||
installedAppsList: appsList,
|
installedAppsList: appsList,
|
||||||
getCustomAppHref: () => "",
|
|
||||||
onAppInProgressRemove: () => undefined,
|
onAppInProgressRemove: () => undefined,
|
||||||
onAppInstallRetry: () => undefined,
|
onAppInstallRetry: () => undefined,
|
||||||
onCustomAppRemove: () => undefined,
|
|
||||||
onInstalledAppRemove: () => undefined,
|
onInstalledAppRemove: () => undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,7 +48,6 @@ storiesOf("Views / Apps / Apps list", module)
|
||||||
appsInProgressList={undefined}
|
appsInProgressList={undefined}
|
||||||
disabled={true}
|
disabled={true}
|
||||||
installedAppsList={undefined}
|
installedAppsList={undefined}
|
||||||
customAppsList={undefined}
|
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("no data", () => (
|
.add("no data", () => (
|
||||||
|
@ -59,6 +55,5 @@ storiesOf("Views / Apps / Apps list", module)
|
||||||
{...props}
|
{...props}
|
||||||
appsInProgressList={undefined}
|
appsInProgressList={undefined}
|
||||||
installedAppsList={[]}
|
installedAppsList={[]}
|
||||||
customAppsList={[]}
|
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useSaleorApps } from "@saleor/apps/hooks/useSaleorApps";
|
||||||
import CardSpacer from "@saleor/components/CardSpacer";
|
import CardSpacer from "@saleor/components/CardSpacer";
|
||||||
import Container from "@saleor/components/Container";
|
import Container from "@saleor/components/Container";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
import { AppsInstallationsQuery, AppsListQuery } from "@saleor/graphql";
|
import { AppListItemFragment, AppsInstallationsQuery } from "@saleor/graphql";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||||
|
@ -14,16 +14,12 @@ import React, { useEffect, useMemo } from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import AppsInProgress from "../AppsInProgress/AppsInProgress";
|
import AppsInProgress from "../AppsInProgress/AppsInProgress";
|
||||||
import CustomApps from "../CustomApps/CustomApps";
|
|
||||||
import InstalledApps from "../InstalledApps/InstalledApps";
|
import InstalledApps from "../InstalledApps/InstalledApps";
|
||||||
|
|
||||||
export interface AppsListPageProps extends ListProps {
|
export interface AppsListPageProps extends ListProps {
|
||||||
installedAppsList: AppsListQuery["apps"]["edges"];
|
installedAppsList: AppListItemFragment[];
|
||||||
customAppsList: AppsListQuery["apps"]["edges"];
|
|
||||||
appsInProgressList?: AppsInstallationsQuery;
|
appsInProgressList?: AppsInstallationsQuery;
|
||||||
getCustomAppHref: (id: string) => string;
|
|
||||||
onInstalledAppRemove: (id: string) => void;
|
onInstalledAppRemove: (id: string) => void;
|
||||||
onCustomAppRemove: (id: string) => void;
|
|
||||||
onAppInProgressRemove: (id: string) => void;
|
onAppInProgressRemove: (id: string) => void;
|
||||||
onAppInstallRetry: (id: string) => void;
|
onAppInstallRetry: (id: string) => void;
|
||||||
}
|
}
|
||||||
|
@ -45,11 +41,8 @@ const useStyles = makeStyles(
|
||||||
|
|
||||||
const AppsListPage: React.FC<AppsListPageProps> = ({
|
const AppsListPage: React.FC<AppsListPageProps> = ({
|
||||||
appsInProgressList,
|
appsInProgressList,
|
||||||
customAppsList,
|
|
||||||
installedAppsList,
|
installedAppsList,
|
||||||
getCustomAppHref,
|
|
||||||
onInstalledAppRemove,
|
onInstalledAppRemove,
|
||||||
onCustomAppRemove,
|
|
||||||
onAppInProgressRemove,
|
onAppInProgressRemove,
|
||||||
onAppInstallRetry,
|
onAppInstallRetry,
|
||||||
...listProps
|
...listProps
|
||||||
|
@ -79,7 +72,7 @@ const AppsListPage: React.FC<AppsListPageProps> = ({
|
||||||
installedAppsList?.filter(
|
installedAppsList?.filter(
|
||||||
app =>
|
app =>
|
||||||
!(fetchedSaleorApps ?? []).find(fetchedApp =>
|
!(fetchedSaleorApps ?? []).find(fetchedApp =>
|
||||||
app.node.manifestUrl?.includes(fetchedApp.hostname),
|
app.manifestUrl?.includes(fetchedApp.hostname),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
[installedAppsList, fetchedSaleorApps],
|
[installedAppsList, fetchedSaleorApps],
|
||||||
|
@ -90,7 +83,7 @@ const AppsListPage: React.FC<AppsListPageProps> = ({
|
||||||
fetchedSaleorApps
|
fetchedSaleorApps
|
||||||
?.map(app =>
|
?.map(app =>
|
||||||
installedAppsList?.find(installedApp =>
|
installedAppsList?.find(installedApp =>
|
||||||
installedApp.node.manifestUrl?.includes(app.hostname),
|
installedApp.manifestUrl?.includes(app.hostname),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.filter(Boolean),
|
.filter(Boolean),
|
||||||
|
@ -135,24 +128,6 @@ const AppsListPage: React.FC<AppsListPageProps> = ({
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "webhooks-and-events": {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<p>
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="Local apps are custom webhooks & token pairs that can be used to
|
|
||||||
connect apps and access Saleor API."
|
|
||||||
id="GDJHXl"
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
<CustomApps
|
|
||||||
appsList={customAppsList}
|
|
||||||
getCustomAppHref={getCustomAppHref}
|
|
||||||
onRemove={onCustomAppRemove}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
case "saleor-apps": {
|
case "saleor-apps": {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
import { Card, TableBody, TableCell, Typography } from "@material-ui/core";
|
|
||||||
import { customAppAddUrl } from "@saleor/apps/urls";
|
|
||||||
import { Button } from "@saleor/components/Button";
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
|
||||||
import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper";
|
|
||||||
import TableRowLink from "@saleor/components/TableRowLink";
|
|
||||||
import { AppsListQuery } from "@saleor/graphql";
|
|
||||||
import { commonMessages } from "@saleor/intl";
|
|
||||||
import { DeleteIcon, IconButton, ResponsiveTable } from "@saleor/macaw-ui";
|
|
||||||
import { renderCollection } from "@saleor/misc";
|
|
||||||
import React from "react";
|
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
|
||||||
|
|
||||||
import { useStyles } from "../../styles";
|
|
||||||
import AppsSkeleton from "../AppsSkeleton";
|
|
||||||
import DeactivatedText from "../DeactivatedText";
|
|
||||||
|
|
||||||
export interface CustomAppsProps {
|
|
||||||
appsList: AppsListQuery["apps"]["edges"];
|
|
||||||
getCustomAppHref: (id: string) => string;
|
|
||||||
onRemove: (id: string) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CustomApps: React.FC<CustomAppsProps> = ({
|
|
||||||
appsList,
|
|
||||||
onRemove,
|
|
||||||
getCustomAppHref,
|
|
||||||
}) => {
|
|
||||||
const intl = useIntl();
|
|
||||||
const classes = useStyles({});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card className={classes.customApps}>
|
|
||||||
<CardTitle
|
|
||||||
toolbar={
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
href={customAppAddUrl}
|
|
||||||
data-test-id="create-app"
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="XB2Jj9"
|
|
||||||
defaultMessage="Create App"
|
|
||||||
description="create app button"
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
title={intl.formatMessage(commonMessages.customApps)}
|
|
||||||
/>
|
|
||||||
<ResponsiveTable>
|
|
||||||
<TableBody>
|
|
||||||
{renderCollection(
|
|
||||||
appsList,
|
|
||||||
(app, index) =>
|
|
||||||
app ? (
|
|
||||||
<TableRowLink
|
|
||||||
key={app.node.id}
|
|
||||||
className={classes.tableRow}
|
|
||||||
href={getCustomAppHref(app.node.id)}
|
|
||||||
>
|
|
||||||
<TableCell className={classes.colName}>
|
|
||||||
<span data-tc="name" className={classes.appName}>
|
|
||||||
{app.node.name}
|
|
||||||
</span>
|
|
||||||
{!app.node.isActive && (
|
|
||||||
<div className={classes.statusWrapper}>
|
|
||||||
<DeactivatedText />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className={classes.colAction}>
|
|
||||||
<TableButtonWrapper>
|
|
||||||
<IconButton
|
|
||||||
variant="secondary"
|
|
||||||
color="primary"
|
|
||||||
onClick={() => onRemove(app.node.id)}
|
|
||||||
>
|
|
||||||
<DeleteIcon />
|
|
||||||
</IconButton>
|
|
||||||
</TableButtonWrapper>
|
|
||||||
</TableCell>
|
|
||||||
</TableRowLink>
|
|
||||||
) : (
|
|
||||||
<AppsSkeleton key={index} />
|
|
||||||
),
|
|
||||||
() => (
|
|
||||||
<TableRowLink className={classes.tableRow}>
|
|
||||||
<TableCell className={classes.colName}>
|
|
||||||
<Typography className={classes.text} variant="body2">
|
|
||||||
<FormattedMessage
|
|
||||||
id="voRaz3"
|
|
||||||
defaultMessage="Your custom-created apps will be shown here."
|
|
||||||
description="custom apps content"
|
|
||||||
/>
|
|
||||||
</Typography>
|
|
||||||
</TableCell>
|
|
||||||
</TableRowLink>
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
</ResponsiveTable>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
CustomApps.displayName = "CustomApps";
|
|
||||||
export default CustomApps;
|
|
|
@ -1,2 +0,0 @@
|
||||||
export * from "./CustomApps";
|
|
||||||
export { default } from "./CustomApps";
|
|
|
@ -14,7 +14,7 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { IconButton } from "@saleor/components/IconButton";
|
import { IconButton } from "@saleor/components/IconButton";
|
||||||
import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper";
|
import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper";
|
||||||
import TableRowLink from "@saleor/components/TableRowLink";
|
import TableRowLink from "@saleor/components/TableRowLink";
|
||||||
import { AppListItemFragment, AppsListQuery } from "@saleor/graphql";
|
import { AppListItemFragment } from "@saleor/graphql";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import { DeleteIcon, ResponsiveTable } from "@saleor/macaw-ui";
|
import { DeleteIcon, ResponsiveTable } from "@saleor/macaw-ui";
|
||||||
import { renderCollection } from "@saleor/misc";
|
import { renderCollection } from "@saleor/misc";
|
||||||
|
@ -27,7 +27,7 @@ import { AppPermissions } from "../AppPermissions/AppPermissions";
|
||||||
import AppsSkeleton from "../AppsSkeleton";
|
import AppsSkeleton from "../AppsSkeleton";
|
||||||
|
|
||||||
export interface InstalledAppsProps extends ListProps {
|
export interface InstalledAppsProps extends ListProps {
|
||||||
appsList: AppsListQuery["apps"]["edges"];
|
appsList: AppListItemFragment[];
|
||||||
onRemove: (id: string) => void;
|
onRemove: (id: string) => void;
|
||||||
displayQuickManifestButton?: boolean;
|
displayQuickManifestButton?: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -80,16 +80,15 @@ const InstalledApps: React.FC<InstalledAppsProps> = ({
|
||||||
(app, index) =>
|
(app, index) =>
|
||||||
app ? (
|
app ? (
|
||||||
<TableRowLink
|
<TableRowLink
|
||||||
key={app.node.id}
|
key={app.id}
|
||||||
className={classes.tableRow}
|
className={classes.tableRow}
|
||||||
href={appUrl(app.node.id)}
|
href={appUrl(app.id)}
|
||||||
>
|
>
|
||||||
<TableCell className={classes.colName}>
|
<TableCell className={classes.colName}>
|
||||||
<span data-tc="name" className={classes.appName}>
|
<span data-tc="name" className={classes.appName}>
|
||||||
{app.node.name}
|
{app.name}
|
||||||
</span>
|
</span>
|
||||||
{app.node.manifestUrl &&
|
{app.manifestUrl && isAppInTunnel(app.manifestUrl) ? (
|
||||||
isAppInTunnel(app.node.manifestUrl) ? (
|
|
||||||
<Typography variant="caption">
|
<Typography variant="caption">
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
defaultMessage="(TUNNEL - DEVELOPMENT)"
|
defaultMessage="(TUNNEL - DEVELOPMENT)"
|
||||||
|
@ -100,23 +99,21 @@ const InstalledApps: React.FC<InstalledAppsProps> = ({
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell className={classes.colAction}>
|
<TableCell className={classes.colAction}>
|
||||||
{app.node.manifestUrl && (
|
{app.manifestUrl && (
|
||||||
<AppManifestTableDisplay
|
<AppManifestTableDisplay manifestUrl={app.manifestUrl} />
|
||||||
manifestUrl={app.node.manifestUrl}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<TableButtonWrapper>
|
<TableButtonWrapper>
|
||||||
<Switch
|
<Switch
|
||||||
checked={app.node.isActive}
|
checked={app.isActive}
|
||||||
onChange={getHandleToggle(app.node)}
|
onChange={getHandleToggle(app)}
|
||||||
/>
|
/>
|
||||||
</TableButtonWrapper>
|
</TableButtonWrapper>
|
||||||
<AppPermissions permissions={app.node.permissions} />
|
<AppPermissions permissions={app.permissions} />
|
||||||
<TableButtonWrapper>
|
<TableButtonWrapper>
|
||||||
<IconButton
|
<IconButton
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => onRemove(app.node.id)}
|
onClick={() => onRemove(app.id)}
|
||||||
>
|
>
|
||||||
<DeleteIcon />
|
<DeleteIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
|
@ -1,83 +1,74 @@
|
||||||
import {
|
import {
|
||||||
AppFetchMutation,
|
AppFetchMutation,
|
||||||
|
AppListItemFragment,
|
||||||
AppQuery,
|
AppQuery,
|
||||||
AppsInstallationsQuery,
|
AppsInstallationsQuery,
|
||||||
AppsListQuery,
|
|
||||||
AppTypeEnum,
|
AppTypeEnum,
|
||||||
JobStatusEnum,
|
JobStatusEnum,
|
||||||
PermissionEnum,
|
PermissionEnum,
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
|
|
||||||
export const appsList: AppsListQuery["apps"]["edges"] = [
|
export const appsList: AppListItemFragment[] = [
|
||||||
{
|
{
|
||||||
__typename: "AppCountableEdge",
|
__typename: "App",
|
||||||
node: {
|
id: "QXBwOjE3Ng==",
|
||||||
__typename: "App",
|
isActive: true,
|
||||||
id: "QXBwOjE3Ng==",
|
name: "app",
|
||||||
isActive: true,
|
type: AppTypeEnum.THIRDPARTY,
|
||||||
name: "app",
|
appUrl: null,
|
||||||
type: AppTypeEnum.THIRDPARTY,
|
manifestUrl: "http://localhost:3000/api/manifest",
|
||||||
appUrl: null,
|
permissions: [
|
||||||
manifestUrl: "http://localhost:3000/api/manifest",
|
{
|
||||||
permissions: [
|
__typename: "Permission",
|
||||||
{
|
code: PermissionEnum.MANAGE_USERS,
|
||||||
__typename: "Permission",
|
name: "Manage customers.",
|
||||||
code: PermissionEnum.MANAGE_USERS,
|
},
|
||||||
name: "Manage customers.",
|
],
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__typename: "AppCountableEdge",
|
__typename: "App",
|
||||||
node: {
|
id: "QXBwOjE3Ng==",
|
||||||
__typename: "App",
|
isActive: false,
|
||||||
id: "QXBwOjE3Ng==",
|
name: "app1",
|
||||||
isActive: false,
|
type: AppTypeEnum.THIRDPARTY,
|
||||||
name: "app1",
|
appUrl: "http://localhost:3000",
|
||||||
type: AppTypeEnum.THIRDPARTY,
|
manifestUrl: "http://localhost:3000/api/manifest",
|
||||||
appUrl: "http://localhost:3000",
|
permissions: [
|
||||||
manifestUrl: "http://localhost:3000/api/manifest",
|
{
|
||||||
permissions: [
|
__typename: "Permission",
|
||||||
{
|
code: PermissionEnum.MANAGE_ORDERS,
|
||||||
__typename: "Permission",
|
name: "Manage orders.",
|
||||||
code: PermissionEnum.MANAGE_ORDERS,
|
},
|
||||||
name: "Manage orders.",
|
{
|
||||||
},
|
__typename: "Permission",
|
||||||
{
|
code: PermissionEnum.MANAGE_USERS,
|
||||||
__typename: "Permission",
|
name: "Manage customers.",
|
||||||
code: PermissionEnum.MANAGE_USERS,
|
},
|
||||||
name: "Manage customers.",
|
],
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const customAppsList: AppsListQuery["apps"]["edges"] = [
|
export const customAppsList: AppListItemFragment[] = [
|
||||||
{
|
{
|
||||||
__typename: "AppCountableEdge",
|
__typename: "App",
|
||||||
node: {
|
id: "QXBwOjE3Ng==",
|
||||||
__typename: "App",
|
isActive: true,
|
||||||
id: "QXBwOjE3Ng==",
|
name: "app custom",
|
||||||
isActive: true,
|
type: AppTypeEnum.LOCAL,
|
||||||
name: "app custom",
|
appUrl: null,
|
||||||
type: AppTypeEnum.LOCAL,
|
manifestUrl: null,
|
||||||
appUrl: null,
|
permissions: [
|
||||||
manifestUrl: null,
|
{
|
||||||
permissions: [
|
__typename: "Permission",
|
||||||
{
|
code: PermissionEnum.MANAGE_ORDERS,
|
||||||
__typename: "Permission",
|
name: "Manage orders.",
|
||||||
code: PermissionEnum.MANAGE_ORDERS,
|
},
|
||||||
name: "Manage orders.",
|
{
|
||||||
},
|
__typename: "Permission",
|
||||||
{
|
code: PermissionEnum.MANAGE_USERS,
|
||||||
__typename: "Permission",
|
name: "Manage customers.",
|
||||||
code: PermissionEnum.MANAGE_USERS,
|
},
|
||||||
name: "Manage customers.",
|
],
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,9 @@ import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import { useCallback, useMemo } from "react";
|
import { useCallback, useMemo } from "react";
|
||||||
import useRouter from "use-react-router";
|
import useRouter from "use-react-router";
|
||||||
|
|
||||||
export type AppPagePathSegment =
|
export type AppPagePathSegment = "third-party" | "saleor-apps";
|
||||||
| "webhooks-and-events"
|
|
||||||
| "third-party"
|
|
||||||
| "saleor-apps";
|
|
||||||
|
|
||||||
const defaultTab: AppPagePathSegment = "webhooks-and-events";
|
const defaultTab: AppPagePathSegment = "third-party";
|
||||||
const appTypeQueryParam = "type";
|
const appTypeQueryParam = "type";
|
||||||
|
|
||||||
export const useAppsPageNavigation = () => {
|
export const useAppsPageNavigation = () => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
import WebhooksRoutes from "@saleor/custom-apps";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import WebhooksRoutes from "@saleor/webhooks";
|
|
||||||
import { parse as parseQs } from "qs";
|
import { parse as parseQs } from "qs";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
@ -14,16 +14,11 @@ import {
|
||||||
AppListUrlQueryParams,
|
AppListUrlQueryParams,
|
||||||
appPath,
|
appPath,
|
||||||
appsListPath,
|
appsListPath,
|
||||||
customAppAddPath,
|
|
||||||
customAppPath,
|
|
||||||
CustomAppUrlQueryParams,
|
|
||||||
} from "./urls";
|
} from "./urls";
|
||||||
import AppView from "./views/App";
|
import AppView from "./views/App";
|
||||||
import AppDetailsView from "./views/AppDetails";
|
import AppDetailsView from "./views/AppDetails";
|
||||||
import AppInstallView from "./views/AppInstall";
|
import AppInstallView from "./views/AppInstall";
|
||||||
import AppsListView from "./views/AppsList";
|
import AppsListView from "./views/AppsList";
|
||||||
import CustomAppCreateView from "./views/CustomAppCreate";
|
|
||||||
import CustomAppDetailsView from "./views/CustomAppDetails";
|
|
||||||
|
|
||||||
const AppDetails: React.FC<RouteComponentProps<{ id: string }>> = ({
|
const AppDetails: React.FC<RouteComponentProps<{ id: string }>> = ({
|
||||||
match,
|
match,
|
||||||
|
@ -47,34 +42,6 @@ const AppInstall: React.FC<RouteComponentProps> = props => {
|
||||||
return <AppInstallView params={params} {...props} />;
|
return <AppInstallView params={params} {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface CustomAppDetailsProps extends RouteComponentProps<{ id?: string }> {
|
|
||||||
token: string;
|
|
||||||
onTokenClose: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CustomAppDetails: React.FC<CustomAppDetailsProps> = ({
|
|
||||||
match,
|
|
||||||
token,
|
|
||||||
onTokenClose,
|
|
||||||
}) => {
|
|
||||||
const qs = parseQs(location.search.substr(1));
|
|
||||||
const params: CustomAppUrlQueryParams = qs;
|
|
||||||
const id = match.params.id;
|
|
||||||
|
|
||||||
if (!id) {
|
|
||||||
throw new Error("No ID provided");
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CustomAppDetailsView
|
|
||||||
id={decodeURIComponent(match.params.id)}
|
|
||||||
params={params}
|
|
||||||
token={token}
|
|
||||||
onTokenClose={onTokenClose}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const AppsList: React.FC<RouteComponentProps> = () => {
|
const AppsList: React.FC<RouteComponentProps> = () => {
|
||||||
const qs = parseQs(location.search.substr(1));
|
const qs = parseQs(location.search.substr(1));
|
||||||
const params: AppListUrlQueryParams = qs;
|
const params: AppListUrlQueryParams = qs;
|
||||||
|
@ -83,32 +50,15 @@ const AppsList: React.FC<RouteComponentProps> = () => {
|
||||||
};
|
};
|
||||||
const Component = () => {
|
const Component = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [token, setToken] = React.useState<string>(null);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<WindowTitle title={intl.formatMessage(sectionNames.apps)} />
|
<WindowTitle title={intl.formatMessage(sectionNames.apps)} />
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path={appsListPath} component={AppsList} />
|
<Route exact path={appsListPath} component={AppsList} />
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path={customAppAddPath}
|
|
||||||
render={() => <CustomAppCreateView setToken={setToken} />}
|
|
||||||
/>
|
|
||||||
<Route exact path={appInstallPath} component={AppInstall} />
|
<Route exact path={appInstallPath} component={AppInstall} />
|
||||||
<Route exact path={appDetailsPath(":id")} component={AppDetails} />
|
<Route exact path={appDetailsPath(":id")} component={AppDetails} />
|
||||||
<Route path={appPath(":id")} component={App} />
|
<Route path={appPath(":id")} component={App} />
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path={customAppPath(":id")}
|
|
||||||
render={props => (
|
|
||||||
<CustomAppDetails
|
|
||||||
{...props}
|
|
||||||
token={token}
|
|
||||||
onTokenClose={() => setToken(null)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<WebhooksRoutes />
|
<WebhooksRoutes />
|
||||||
</Switch>
|
</Switch>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -9,7 +9,6 @@ export const MANIFEST_ATTR = "manifestUrl";
|
||||||
export type AppListUrlDialog =
|
export type AppListUrlDialog =
|
||||||
| "remove"
|
| "remove"
|
||||||
| "remove-app"
|
| "remove-app"
|
||||||
| "remove-custom-app"
|
|
||||||
| "app-activate"
|
| "app-activate"
|
||||||
| "app-deactivate";
|
| "app-deactivate";
|
||||||
|
|
||||||
|
@ -39,24 +38,13 @@ export enum AppListUrlSortField {
|
||||||
active = "active",
|
active = "active",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CustomAppUrlDialog =
|
|
||||||
| "create-token"
|
|
||||||
| "remove-webhook"
|
|
||||||
| "remove-token"
|
|
||||||
| "app-activate"
|
|
||||||
| "app-deactivate";
|
|
||||||
export type CustomAppUrlQueryParams = Dialog<CustomAppUrlDialog> & SingleAction;
|
|
||||||
|
|
||||||
export const appsSection = "/apps/";
|
export const appsSection = "/apps/";
|
||||||
export const appsListPath = appsSection;
|
export const appsListPath = appsSection;
|
||||||
|
|
||||||
export const customAppListPath = "/apps/custom/";
|
|
||||||
|
|
||||||
export const appDetailsPath = (id: string) => urlJoin(appsSection, id);
|
export const appDetailsPath = (id: string) => urlJoin(appsSection, id);
|
||||||
export const appPath = (id: string) => urlJoin(appsSection, id, "app");
|
export const appPath = (id: string) => urlJoin(appsSection, id, "app");
|
||||||
export const appDeepPath = (id: string, subPath: string) =>
|
export const appDeepPath = (id: string, subPath: string) =>
|
||||||
urlJoin(appPath(id), subPath);
|
urlJoin(appPath(id), subPath);
|
||||||
export const customAppPath = (id: string) => urlJoin(customAppListPath, id);
|
|
||||||
export const appInstallPath = urlJoin(appsSection, "install");
|
export const appInstallPath = urlJoin(appsSection, "install");
|
||||||
export const createAppInstallUrl = (manifestUrl: string) =>
|
export const createAppInstallUrl = (manifestUrl: string) =>
|
||||||
`${appInstallPath}?manifestUrl=${manifestUrl}`;
|
`${appInstallPath}?manifestUrl=${manifestUrl}`;
|
||||||
|
@ -110,11 +98,6 @@ export const getDashboardUrFromAppCompleteUrl = (
|
||||||
return dashboardUrl;
|
return dashboardUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const customAppUrl = (id: string, params?: CustomAppUrlQueryParams) =>
|
|
||||||
customAppPath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
|
||||||
export const customAppAddPath = urlJoin(customAppListPath, "add");
|
|
||||||
export const customAppAddUrl = customAppAddPath;
|
|
||||||
|
|
||||||
export const appsListUrl = (params?: AppListUrlQueryParams) =>
|
export const appsListUrl = (params?: AppListUrlQueryParams) =>
|
||||||
appsListPath + "?" + stringifyQs(params);
|
appsListPath + "?" + stringifyQs(params);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import AppDeactivateDialog from "@saleor/apps/components/AppDeactivateDialog";
|
||||||
import { AppListContext, AppListContextValues } from "@saleor/apps/context";
|
import { AppListContext, AppListContextValues } from "@saleor/apps/context";
|
||||||
import {
|
import {
|
||||||
AppsInstallationsQuery,
|
AppsInstallationsQuery,
|
||||||
AppsListQuery,
|
|
||||||
AppSortField,
|
AppSortField,
|
||||||
AppTypeEnum,
|
AppTypeEnum,
|
||||||
JobStatusEnum,
|
JobStatusEnum,
|
||||||
|
@ -25,8 +24,10 @@ import usePaginator, {
|
||||||
createPaginationState,
|
createPaginationState,
|
||||||
PaginatorContext,
|
PaginatorContext,
|
||||||
} from "@saleor/hooks/usePaginator";
|
} from "@saleor/hooks/usePaginator";
|
||||||
|
import { findById } from "@saleor/misc";
|
||||||
import { ListViews } from "@saleor/types";
|
import { ListViews } from "@saleor/types";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
|
import { mapEdgesToItems } from "@saleor/utils/maps";
|
||||||
import React, { useEffect, useRef } from "react";
|
import React, { useEffect, useRef } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -38,15 +39,9 @@ import {
|
||||||
AppListUrlDialog,
|
AppListUrlDialog,
|
||||||
AppListUrlQueryParams,
|
AppListUrlQueryParams,
|
||||||
appsListUrl,
|
appsListUrl,
|
||||||
customAppUrl,
|
|
||||||
} from "../../urls";
|
} from "../../urls";
|
||||||
import { messages } from "./messages";
|
import { messages } from "./messages";
|
||||||
|
|
||||||
const getCurrentAppName = (
|
|
||||||
id: string,
|
|
||||||
collection?: AppsListQuery["apps"]["edges"],
|
|
||||||
) => collection?.find(edge => edge.node.id === id)?.node?.name;
|
|
||||||
|
|
||||||
const getAppInProgressName = (
|
const getAppInProgressName = (
|
||||||
id: string,
|
id: string,
|
||||||
collection?: AppsInstallationsQuery["appsInstallations"],
|
collection?: AppsInstallationsQuery["appsInstallations"],
|
||||||
|
@ -102,21 +97,6 @@ export const AppsList: React.FC<AppsListProps> = ({ params }) => {
|
||||||
queryString: params,
|
queryString: params,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
|
||||||
data: customAppsData,
|
|
||||||
loading: customAppsLoading,
|
|
||||||
refetch: customAppsRefetch,
|
|
||||||
} = useAppsListQuery({
|
|
||||||
displayLoader: true,
|
|
||||||
variables: {
|
|
||||||
first: 100,
|
|
||||||
...queryVariables,
|
|
||||||
filter: {
|
|
||||||
type: AppTypeEnum.LOCAL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const refetchExtensionList = () => {
|
const refetchExtensionList = () => {
|
||||||
client.refetchQueries({
|
client.refetchQueries({
|
||||||
include: [EXTENSION_LIST_QUERY],
|
include: [EXTENSION_LIST_QUERY],
|
||||||
|
@ -173,11 +153,7 @@ export const AppsList: React.FC<AppsListProps> = ({ params }) => {
|
||||||
const [deleteApp, deleteAppOpts] = useAppDeleteMutation({
|
const [deleteApp, deleteAppOpts] = useAppDeleteMutation({
|
||||||
onCompleted: data => {
|
onCompleted: data => {
|
||||||
if (!data?.appDelete?.errors?.length) {
|
if (!data?.appDelete?.errors?.length) {
|
||||||
if (data.appDelete.app.type === AppTypeEnum.LOCAL) {
|
refetch();
|
||||||
customAppsRefetch();
|
|
||||||
} else {
|
|
||||||
refetch();
|
|
||||||
}
|
|
||||||
closeModal();
|
closeModal();
|
||||||
refetchExtensionList();
|
refetchExtensionList();
|
||||||
removeAppNotify();
|
removeAppNotify();
|
||||||
|
@ -277,9 +253,6 @@ export const AppsList: React.FC<AppsListProps> = ({ params }) => {
|
||||||
const onAppInstallRetry = (id: string) =>
|
const onAppInstallRetry = (id: string) =>
|
||||||
retryInstallApp({ variables: { id } });
|
retryInstallApp({ variables: { id } });
|
||||||
|
|
||||||
const installedApps = data?.apps?.edges;
|
|
||||||
const customApps = customAppsData?.apps?.edges;
|
|
||||||
|
|
||||||
const context: AppListContextValues = React.useMemo(
|
const context: AppListContextValues = React.useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
activateApp: id => openModal("app-activate", { id }),
|
activateApp: id => openModal("app-activate", { id }),
|
||||||
|
@ -288,30 +261,30 @@ export const AppsList: React.FC<AppsListProps> = ({ params }) => {
|
||||||
[activateApp, deactivateApp],
|
[activateApp, deactivateApp],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const installedApps = mapEdgesToItems(data?.apps);
|
||||||
|
const currentAppName = findById(params.id, installedApps)?.name;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppListContext.Provider value={context}>
|
<AppListContext.Provider value={context}>
|
||||||
<PaginatorContext.Provider value={paginationValues}>
|
<PaginatorContext.Provider value={paginationValues}>
|
||||||
<AppDeleteDialog
|
<AppDeleteDialog
|
||||||
confirmButtonState={deleteAppOpts.status}
|
confirmButtonState={deleteAppOpts.status}
|
||||||
name={getCurrentAppName(
|
name={currentAppName}
|
||||||
params.id,
|
|
||||||
action === "remove-app" ? installedApps : customApps,
|
|
||||||
)}
|
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onConfirm={handleRemoveConfirm}
|
onConfirm={handleRemoveConfirm}
|
||||||
type={action === "remove-app" ? "EXTERNAL" : "CUSTOM"}
|
type="EXTERNAL"
|
||||||
open={action === "remove-app" || action === "remove-custom-app"}
|
open={action === "remove-app"}
|
||||||
/>
|
/>
|
||||||
<AppActivateDialog
|
<AppActivateDialog
|
||||||
confirmButtonState={activateAppResult.status}
|
confirmButtonState={activateAppResult.status}
|
||||||
name={getCurrentAppName(params.id, installedApps)}
|
name={currentAppName}
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onConfirm={handleActivateAppConfirm}
|
onConfirm={handleActivateAppConfirm}
|
||||||
open={params.action === "app-activate"}
|
open={params.action === "app-activate"}
|
||||||
/>
|
/>
|
||||||
<AppDeactivateDialog
|
<AppDeactivateDialog
|
||||||
confirmButtonState={deactivateAppResult.status}
|
confirmButtonState={deactivateAppResult.status}
|
||||||
name={getCurrentAppName(params.id, installedApps)}
|
name={currentAppName}
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onConfirm={handleDeactivateAppConfirm}
|
onConfirm={handleDeactivateAppConfirm}
|
||||||
open={params.action === "app-deactivate"}
|
open={params.action === "app-deactivate"}
|
||||||
|
@ -328,23 +301,16 @@ export const AppsList: React.FC<AppsListProps> = ({ params }) => {
|
||||||
/>
|
/>
|
||||||
<AppsListPage
|
<AppsListPage
|
||||||
installedAppsList={installedApps}
|
installedAppsList={installedApps}
|
||||||
customAppsList={customApps}
|
|
||||||
appsInProgressList={appsInProgressData}
|
appsInProgressList={appsInProgressData}
|
||||||
disabled={loading || customAppsLoading}
|
disabled={loading}
|
||||||
settings={settings}
|
settings={settings}
|
||||||
onUpdateListSettings={updateListSettings}
|
onUpdateListSettings={updateListSettings}
|
||||||
onAppInstallRetry={onAppInstallRetry}
|
onAppInstallRetry={onAppInstallRetry}
|
||||||
getCustomAppHref={id => customAppUrl(id)}
|
|
||||||
onInstalledAppRemove={id =>
|
onInstalledAppRemove={id =>
|
||||||
openModal("remove-app", {
|
openModal("remove-app", {
|
||||||
id,
|
id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
onCustomAppRemove={id =>
|
|
||||||
openModal("remove-custom-app", {
|
|
||||||
id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onAppInProgressRemove={id =>
|
onAppInProgressRemove={id =>
|
||||||
openModal("remove", {
|
openModal("remove", {
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import { FormData } from "@saleor/channels/components/ChannelForm";
|
import { FormData } from "@saleor/channels/components/ChannelForm";
|
||||||
import { SearchData } from "@saleor/hooks/makeTopLevelSearch";
|
import { SearchData } from "@saleor/hooks/makeTopLevelSearch";
|
||||||
import { getParsedSearchData } from "@saleor/hooks/makeTopLevelSearch/utils";
|
import { getParsedSearchData } from "@saleor/hooks/makeTopLevelSearch/utils";
|
||||||
import {
|
import { getById, getByUnmatchingId } from "@saleor/misc";
|
||||||
getById,
|
|
||||||
getByUnmatchingId,
|
|
||||||
} from "@saleor/orders/components/OrderReturnPage/utils";
|
|
||||||
import { ReorderAction, ReorderEvent } from "@saleor/types";
|
import { ReorderAction, ReorderEvent } from "@saleor/types";
|
||||||
import { move } from "@saleor/utils/lists";
|
import { move } from "@saleor/utils/lists";
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useUser } from "@saleor/auth";
|
import { useUser } from "@saleor/auth";
|
||||||
import { ChannelFragment, useBaseChannelsQuery } from "@saleor/graphql";
|
import { ChannelFragment, useBaseChannelsQuery } from "@saleor/graphql";
|
||||||
import useLocalStorage from "@saleor/hooks/useLocalStorage";
|
import useLocalStorage from "@saleor/hooks/useLocalStorage";
|
||||||
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
|
import { getById } from "@saleor/misc";
|
||||||
import { useSaleorConfig } from "@saleor/sdk";
|
import { useSaleorConfig } from "@saleor/sdk";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
import { SearchProductsQuery } from "@saleor/graphql";
|
import { SearchProductsQuery } from "@saleor/graphql";
|
||||||
import {
|
import { getById, getByUnmatchingId } from "@saleor/misc";
|
||||||
getById,
|
|
||||||
getByUnmatchingId,
|
|
||||||
} from "@saleor/orders/components/OrderReturnPage/utils";
|
|
||||||
import { RelayToFlat } from "@saleor/types";
|
import { RelayToFlat } from "@saleor/types";
|
||||||
|
|
||||||
export type SearchVariant = RelayToFlat<
|
export type SearchVariant = RelayToFlat<
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Card, CardContent, CircularProgress, Modal } from "@material-ui/core";
|
import { Card, CardContent, CircularProgress, Modal } from "@material-ui/core";
|
||||||
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||||
|
import { getById } from "@saleor/misc";
|
||||||
import ModalTitle from "@saleor/orders/components/OrderDiscountCommonModal/ModalTitle";
|
import ModalTitle from "@saleor/orders/components/OrderDiscountCommonModal/ModalTitle";
|
||||||
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,12 @@ import { useUser } from "@saleor/auth";
|
||||||
import { channelsListUrl } from "@saleor/channels/urls";
|
import { channelsListUrl } from "@saleor/channels/urls";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import { APP_VERSION as dashboardVersion } from "@saleor/config";
|
import { APP_VERSION as dashboardVersion } from "@saleor/config";
|
||||||
|
import { CustomAppUrls } from "@saleor/custom-apps/urls";
|
||||||
import { PermissionEnum } from "@saleor/graphql";
|
import { PermissionEnum } from "@saleor/graphql";
|
||||||
import useShop from "@saleor/hooks/useShop";
|
import useShop from "@saleor/hooks/useShop";
|
||||||
import Attributes from "@saleor/icons/Attributes";
|
import Attributes from "@saleor/icons/Attributes";
|
||||||
import Channels from "@saleor/icons/Channels";
|
import Channels from "@saleor/icons/Channels";
|
||||||
|
import Miscellaneous from "@saleor/icons/Miscellaneous";
|
||||||
import Navigation from "@saleor/icons/Navigation";
|
import Navigation from "@saleor/icons/Navigation";
|
||||||
import PageTypes from "@saleor/icons/PageTypes";
|
import PageTypes from "@saleor/icons/PageTypes";
|
||||||
import PermissionGroups from "@saleor/icons/PermissionGroups";
|
import PermissionGroups from "@saleor/icons/PermissionGroups";
|
||||||
|
@ -235,6 +237,16 @@ export function createConfigurationMenu(intl: IntlShape): MenuSection[] {
|
||||||
url: pluginListUrl(),
|
url: pluginListUrl(),
|
||||||
testId: "configuration-plugins-pages",
|
testId: "configuration-plugins-pages",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: intl.formatMessage({
|
||||||
|
id: "Zz67wc",
|
||||||
|
defaultMessage: "View and update your webhooks and events.",
|
||||||
|
}),
|
||||||
|
icon: <Miscellaneous />,
|
||||||
|
title: intl.formatMessage(sectionNames.webhooksAndEvents),
|
||||||
|
url: CustomAppUrls.resolveAppListUrl(),
|
||||||
|
testId: "configuration-menu-webhooks-and-events",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { appsListUrl } from "@saleor/apps/urls";
|
|
||||||
import AccountPermissions from "@saleor/components/AccountPermissions";
|
import AccountPermissions from "@saleor/components/AccountPermissions";
|
||||||
import { Backlink } from "@saleor/components/Backlink";
|
import { Backlink } from "@saleor/components/Backlink";
|
||||||
import Container from "@saleor/components/Container";
|
import Container from "@saleor/components/Container";
|
||||||
|
@ -6,6 +5,7 @@ import Form from "@saleor/components/Form";
|
||||||
import Grid from "@saleor/components/Grid";
|
import Grid from "@saleor/components/Grid";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
import Savebar from "@saleor/components/Savebar";
|
import Savebar from "@saleor/components/Savebar";
|
||||||
|
import { CustomAppUrls } from "@saleor/custom-apps/urls";
|
||||||
import {
|
import {
|
||||||
AppErrorFragment,
|
AppErrorFragment,
|
||||||
PermissionEnum,
|
PermissionEnum,
|
||||||
|
@ -60,7 +60,7 @@ const CustomAppCreatePage: React.FC<CustomAppCreatePageProps> = props => {
|
||||||
>
|
>
|
||||||
{({ data, change, submit, isSaveDisabled }) => (
|
{({ data, change, submit, isSaveDisabled }) => (
|
||||||
<Container>
|
<Container>
|
||||||
<Backlink href={appsListUrl()}>
|
<Backlink href={CustomAppUrls.resolveAppListUrl()}>
|
||||||
{intl.formatMessage(sectionNames.apps)}
|
{intl.formatMessage(sectionNames.apps)}
|
||||||
</Backlink>
|
</Backlink>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
|
@ -102,7 +102,7 @@ const CustomAppCreatePage: React.FC<CustomAppCreatePageProps> = props => {
|
||||||
<Savebar
|
<Savebar
|
||||||
disabled={isSaveDisabled}
|
disabled={isSaveDisabled}
|
||||||
state={saveButtonBarState}
|
state={saveButtonBarState}
|
||||||
onCancel={() => navigate(appsListUrl())}
|
onCancel={() => navigate(CustomAppUrls.resolveAppListUrl())}
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
|
@ -1,4 +1,3 @@
|
||||||
import { appsListUrl } from "@saleor/apps/urls";
|
|
||||||
import AccountPermissions from "@saleor/components/AccountPermissions";
|
import AccountPermissions from "@saleor/components/AccountPermissions";
|
||||||
import { Backlink } from "@saleor/components/Backlink";
|
import { Backlink } from "@saleor/components/Backlink";
|
||||||
import CardSpacer from "@saleor/components/CardSpacer";
|
import CardSpacer from "@saleor/components/CardSpacer";
|
||||||
|
@ -7,6 +6,8 @@ import Form from "@saleor/components/Form";
|
||||||
import Grid from "@saleor/components/Grid";
|
import Grid from "@saleor/components/Grid";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
import Savebar from "@saleor/components/Savebar";
|
import Savebar from "@saleor/components/Savebar";
|
||||||
|
import WebhooksList from "@saleor/custom-apps/components/WebhooksList";
|
||||||
|
import { CustomAppUrls } from "@saleor/custom-apps/urls";
|
||||||
import {
|
import {
|
||||||
AppErrorFragment,
|
AppErrorFragment,
|
||||||
AppUpdateMutation,
|
AppUpdateMutation,
|
||||||
|
@ -19,15 +20,14 @@ import { sectionNames } from "@saleor/intl";
|
||||||
import { Button, ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
import { Button, ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||||
import { getFormErrors } from "@saleor/utils/errors";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import getAppErrorMessage from "@saleor/utils/errors/app";
|
import getAppErrorMessage from "@saleor/utils/errors/app";
|
||||||
import WebhooksList from "@saleor/webhooks/components/WebhooksList";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import activateIcon from "../../../../assets/images/activate-icon.svg";
|
import activateIcon from "../../../../assets/images/activate-icon.svg";
|
||||||
import { useStyles } from "../../styles";
|
|
||||||
import CustomAppDefaultToken from "../CustomAppDefaultToken";
|
import CustomAppDefaultToken from "../CustomAppDefaultToken";
|
||||||
import CustomAppInformation from "../CustomAppInformation";
|
import CustomAppInformation from "../CustomAppInformation";
|
||||||
import CustomAppTokens from "../CustomAppTokens";
|
import CustomAppTokens from "../CustomAppTokens";
|
||||||
|
import { useStyles } from "./styles";
|
||||||
|
|
||||||
export interface CustomAppDetailsPageFormData {
|
export interface CustomAppDetailsPageFormData {
|
||||||
hasFullAccess: boolean;
|
hasFullAccess: boolean;
|
||||||
|
@ -76,7 +76,7 @@ const CustomAppDetailsPage: React.FC<CustomAppDetailsPageProps> = props => {
|
||||||
onAppDeactivateOpen,
|
onAppDeactivateOpen,
|
||||||
} = props;
|
} = props;
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const classes = useStyles({});
|
const classes = useStyles();
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
|
|
||||||
const webhooks = app?.webhooks;
|
const webhooks = app?.webhooks;
|
||||||
|
@ -105,7 +105,7 @@ const CustomAppDetailsPage: React.FC<CustomAppDetailsPageProps> = props => {
|
||||||
>
|
>
|
||||||
{({ data, change, submit, isSaveDisabled }) => (
|
{({ data, change, submit, isSaveDisabled }) => (
|
||||||
<Container>
|
<Container>
|
||||||
<Backlink href={appsListUrl()}>
|
<Backlink href={CustomAppUrls.resolveAppListUrl()}>
|
||||||
{intl.formatMessage(sectionNames.apps)}
|
{intl.formatMessage(sectionNames.apps)}
|
||||||
</Backlink>
|
</Backlink>
|
||||||
<PageHeader title={app?.name}>
|
<PageHeader title={app?.name}>
|
||||||
|
@ -188,7 +188,7 @@ const CustomAppDetailsPage: React.FC<CustomAppDetailsPageProps> = props => {
|
||||||
<Savebar
|
<Savebar
|
||||||
disabled={isSaveDisabled}
|
disabled={isSaveDisabled}
|
||||||
state={saveButtonBarState}
|
state={saveButtonBarState}
|
||||||
onCancel={() => navigate(appsListUrl())}
|
onCancel={() => navigate(CustomAppUrls.resolveAppListUrl())}
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
12
src/custom-apps/components/CustomAppDetailsPage/styles.ts
Normal file
12
src/custom-apps/components/CustomAppDetailsPage/styles.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { makeStyles } from "@saleor/macaw-ui";
|
||||||
|
|
||||||
|
export const useStyles = makeStyles(
|
||||||
|
theme => ({
|
||||||
|
activateButton: {
|
||||||
|
"& img": {
|
||||||
|
marginRight: theme.spacing(1),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{ name: "CustomAppDetailsPage" },
|
||||||
|
);
|
|
@ -0,0 +1,119 @@
|
||||||
|
import { Card, TableBody, TableCell, Typography } from "@material-ui/core";
|
||||||
|
import { Button } from "@saleor/components/Button";
|
||||||
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
|
import Container from "@saleor/components/Container";
|
||||||
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
|
import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper";
|
||||||
|
import TableRowLink from "@saleor/components/TableRowLink";
|
||||||
|
import { CustomAppUrls } from "@saleor/custom-apps/urls";
|
||||||
|
import { AppListItemFragment } from "@saleor/graphql";
|
||||||
|
import { commonMessages, sectionNames } from "@saleor/intl";
|
||||||
|
import { DeleteIcon, IconButton, ResponsiveTable } from "@saleor/macaw-ui";
|
||||||
|
import { renderCollection } from "@saleor/misc";
|
||||||
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import AppsSkeleton from "../../../apps/components/AppsSkeleton";
|
||||||
|
import DeactivatedText from "../../../apps/components/DeactivatedText";
|
||||||
|
import { useStyles } from "../../../apps/styles";
|
||||||
|
|
||||||
|
export interface CustomAppListPageProps {
|
||||||
|
appsList: AppListItemFragment[];
|
||||||
|
getCustomAppHref: (id: string) => string;
|
||||||
|
onRemove: (id: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomAppListPage: React.FC<CustomAppListPageProps> = ({
|
||||||
|
appsList,
|
||||||
|
onRemove,
|
||||||
|
getCustomAppHref,
|
||||||
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const classes = useStyles({});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<PageHeader title={intl.formatMessage(sectionNames.webhooksAndEvents)} />
|
||||||
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Local apps are custom webhooks & token pairs that can be used to
|
||||||
|
connect apps and access Saleor API."
|
||||||
|
id="L/sNGY"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<Card className={classes.customApps}>
|
||||||
|
<CardTitle
|
||||||
|
toolbar={
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
href={CustomAppUrls.appAddUrl}
|
||||||
|
data-test-id="create-app"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id="XB2Jj9"
|
||||||
|
defaultMessage="Create App"
|
||||||
|
description="create app button"
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
title={intl.formatMessage(commonMessages.customApps)}
|
||||||
|
/>
|
||||||
|
<ResponsiveTable>
|
||||||
|
<TableBody>
|
||||||
|
{renderCollection(
|
||||||
|
appsList,
|
||||||
|
(app, index) =>
|
||||||
|
app ? (
|
||||||
|
<TableRowLink
|
||||||
|
key={app.id}
|
||||||
|
className={classes.tableRow}
|
||||||
|
href={getCustomAppHref(app.id)}
|
||||||
|
>
|
||||||
|
<TableCell className={classes.colName}>
|
||||||
|
<span data-tc="name" className={classes.appName}>
|
||||||
|
{app.name}
|
||||||
|
</span>
|
||||||
|
{!app.isActive && (
|
||||||
|
<div className={classes.statusWrapper}>
|
||||||
|
<DeactivatedText />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.colAction}>
|
||||||
|
<TableButtonWrapper>
|
||||||
|
<IconButton
|
||||||
|
variant="secondary"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => onRemove(app.id)}
|
||||||
|
>
|
||||||
|
<DeleteIcon />
|
||||||
|
</IconButton>
|
||||||
|
</TableButtonWrapper>
|
||||||
|
</TableCell>
|
||||||
|
</TableRowLink>
|
||||||
|
) : (
|
||||||
|
<AppsSkeleton key={index} />
|
||||||
|
),
|
||||||
|
() => (
|
||||||
|
<TableRowLink className={classes.tableRow}>
|
||||||
|
<TableCell className={classes.colName}>
|
||||||
|
<Typography className={classes.text} variant="body2">
|
||||||
|
<FormattedMessage
|
||||||
|
id="voRaz3"
|
||||||
|
defaultMessage="Your custom-created apps will be shown here."
|
||||||
|
description="custom apps content"
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRowLink>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</ResponsiveTable>
|
||||||
|
</Card>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
CustomAppListPage.displayName = "CustomAppListPage";
|
||||||
|
export default CustomAppListPage;
|
2
src/custom-apps/components/CustomAppListPage/index.ts
Normal file
2
src/custom-apps/components/CustomAppListPage/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./CustomAppListPage";
|
||||||
|
export { default } from "./CustomAppListPage";
|
|
@ -1,4 +1,3 @@
|
||||||
import { customAppUrl } from "@saleor/apps/urls";
|
|
||||||
import { Backlink } from "@saleor/components/Backlink";
|
import { Backlink } from "@saleor/components/Backlink";
|
||||||
import Container from "@saleor/components/Container";
|
import Container from "@saleor/components/Container";
|
||||||
import Form from "@saleor/components/Form";
|
import Form from "@saleor/components/Form";
|
||||||
|
@ -6,31 +5,33 @@ import FormSpacer from "@saleor/components/FormSpacer";
|
||||||
import Grid from "@saleor/components/Grid";
|
import Grid from "@saleor/components/Grid";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
import Savebar from "@saleor/components/Savebar";
|
import Savebar from "@saleor/components/Savebar";
|
||||||
|
import WebhookEvents from "@saleor/custom-apps/components/WebhookEvents";
|
||||||
|
import WebhookInfo from "@saleor/custom-apps/components/WebhookInfo";
|
||||||
|
import WebhookStatus from "@saleor/custom-apps/components/WebhookStatus";
|
||||||
|
import {
|
||||||
|
createAsyncEventsSelectHandler,
|
||||||
|
createSyncEventsSelectHandler,
|
||||||
|
} from "@saleor/custom-apps/handlers";
|
||||||
|
import { CustomAppUrls } from "@saleor/custom-apps/urls";
|
||||||
|
import {
|
||||||
|
mapAsyncEventsToChoices,
|
||||||
|
mapSyncEventsToChoices,
|
||||||
|
} from "@saleor/custom-apps/utils";
|
||||||
import {
|
import {
|
||||||
WebhookDetailsFragment,
|
WebhookDetailsFragment,
|
||||||
WebhookErrorFragment,
|
WebhookErrorFragment,
|
||||||
WebhookEventTypeAsyncEnum,
|
WebhookEventTypeAsyncEnum,
|
||||||
WebhookEventTypeSyncEnum,
|
WebhookEventTypeSyncEnum,
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
|
import { SubmitPromise } from "@saleor/hooks/useForm";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||||
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
|
|
||||||
import WebhookInfo from "@saleor/webhooks/components/WebhookInfo";
|
|
||||||
import WebhookStatus from "@saleor/webhooks/components/WebhookStatus";
|
|
||||||
import {
|
|
||||||
createAsyncEventsSelectHandler,
|
|
||||||
createSyncEventsSelectHandler,
|
|
||||||
} from "@saleor/webhooks/handlers";
|
|
||||||
import {
|
|
||||||
mapAsyncEventsToChoices,
|
|
||||||
mapSyncEventsToChoices,
|
|
||||||
} from "@saleor/webhooks/utils";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import { getHeaderTitle } from "./messages";
|
import { getHeaderTitle } from "./messages";
|
||||||
|
|
||||||
export interface FormData {
|
export interface WebhookFormData {
|
||||||
syncEvents: WebhookEventTypeSyncEnum[];
|
syncEvents: WebhookEventTypeSyncEnum[];
|
||||||
asyncEvents: WebhookEventTypeAsyncEnum[];
|
asyncEvents: WebhookEventTypeAsyncEnum[];
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
|
@ -40,18 +41,18 @@ export interface FormData {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WebhookDetailsPageProps {
|
export interface WebhookDetailsPageProps {
|
||||||
appName: string;
|
|
||||||
appId: string;
|
appId: string;
|
||||||
|
appName: string;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: WebhookErrorFragment[];
|
errors: WebhookErrorFragment[];
|
||||||
webhook?: WebhookDetailsFragment | null;
|
webhook?: WebhookDetailsFragment | null;
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
onSubmit: (data: FormData) => void;
|
onSubmit: (data: WebhookFormData) => SubmitPromise<any[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WebhookDetailsPage: React.FC<WebhookDetailsPageProps> = ({
|
const WebhookDetailsPage: React.FC<WebhookDetailsPageProps> = ({
|
||||||
appName,
|
|
||||||
appId,
|
appId,
|
||||||
|
appName,
|
||||||
disabled,
|
disabled,
|
||||||
errors,
|
errors,
|
||||||
webhook,
|
webhook,
|
||||||
|
@ -61,17 +62,19 @@ const WebhookDetailsPage: React.FC<WebhookDetailsPageProps> = ({
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
|
|
||||||
const initialForm: FormData = {
|
const initialForm: WebhookFormData = {
|
||||||
syncEvents: webhook?.syncEvents?.map(event => event.eventType) || [],
|
syncEvents: webhook?.syncEvents?.map(event => event.eventType) || [],
|
||||||
asyncEvents: webhook?.asyncEvents?.map(event => event.eventType) || [],
|
asyncEvents: webhook?.asyncEvents?.map(event => event.eventType) || [],
|
||||||
isActive: webhook?.isActive ?? true,
|
isActive: !!webhook?.isActive,
|
||||||
name: webhook?.name || "",
|
name: webhook?.name || "",
|
||||||
secretKey: webhook?.secretKey || "",
|
secretKey: webhook?.secretKey || "",
|
||||||
targetUrl: webhook?.targetUrl || "",
|
targetUrl: webhook?.targetUrl || "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const backUrl = CustomAppUrls.resolveAppUrl(appId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form initial={initialForm} onSubmit={onSubmit}>
|
<Form confirmLeave initial={initialForm} onSubmit={onSubmit}>
|
||||||
{({ data, submit, change }) => {
|
{({ data, submit, change }) => {
|
||||||
const syncEventsChoices = disabled
|
const syncEventsChoices = disabled
|
||||||
? []
|
? []
|
||||||
|
@ -94,7 +97,7 @@ const WebhookDetailsPage: React.FC<WebhookDetailsPageProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Backlink href={customAppUrl(appId)}>{appName}</Backlink>
|
<Backlink href={backUrl}>{appName}</Backlink>
|
||||||
<PageHeader title={getHeaderTitle(intl, webhook)} />
|
<PageHeader title={getHeaderTitle(intl, webhook)} />
|
||||||
<Grid variant="uniform">
|
<Grid variant="uniform">
|
||||||
<div>
|
<div>
|
||||||
|
@ -124,7 +127,7 @@ const WebhookDetailsPage: React.FC<WebhookDetailsPageProps> = ({
|
||||||
<Savebar
|
<Savebar
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
state={saveButtonBarState}
|
state={saveButtonBarState}
|
||||||
onCancel={() => navigate(customAppUrl(appId))}
|
onCancel={() => navigate(backUrl)}
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
|
@ -1,6 +1,6 @@
|
||||||
|
import { isUnnamed } from "@saleor/custom-apps/utils";
|
||||||
import { WebhookDetailsQuery } from "@saleor/graphql";
|
import { WebhookDetailsQuery } from "@saleor/graphql";
|
||||||
import { getStringOrPlaceholder } from "@saleor/misc";
|
import { getStringOrPlaceholder } from "@saleor/misc";
|
||||||
import { isUnnamed } from "@saleor/webhooks/utils";
|
|
||||||
import { defineMessages, IntlShape } from "react-intl";
|
import { defineMessages, IntlShape } from "react-intl";
|
||||||
|
|
||||||
export const messages = defineMessages({
|
export const messages = defineMessages({
|
|
@ -5,15 +5,15 @@ import Hr from "@saleor/components/Hr";
|
||||||
import MultiAutocompleteSelectField, {
|
import MultiAutocompleteSelectField, {
|
||||||
MultiAutocompleteChoiceType,
|
MultiAutocompleteChoiceType,
|
||||||
} from "@saleor/components/MultiAutocompleteSelectField";
|
} from "@saleor/components/MultiAutocompleteSelectField";
|
||||||
|
import {
|
||||||
|
mapAsyncEventsToChoices,
|
||||||
|
mapSyncEventsToChoices,
|
||||||
|
} from "@saleor/custom-apps/utils";
|
||||||
import {
|
import {
|
||||||
WebhookEventTypeAsyncEnum,
|
WebhookEventTypeAsyncEnum,
|
||||||
WebhookEventTypeSyncEnum,
|
WebhookEventTypeSyncEnum,
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
import { ChangeEvent } from "@saleor/hooks/useForm";
|
import { ChangeEvent } from "@saleor/hooks/useForm";
|
||||||
import {
|
|
||||||
mapAsyncEventsToChoices,
|
|
||||||
mapSyncEventsToChoices,
|
|
||||||
} from "@saleor/webhooks/utils";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
|
@ -17,7 +17,7 @@ import getWebhookErrorMessage from "@saleor/utils/errors/webhooks";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import { WebhookFormData } from "../WebhooksDetailsPage/WebhooksDetailsPage";
|
import { WebhookFormData } from "../WebhookDetailsPage";
|
||||||
import { messages } from "./messages";
|
import { messages } from "./messages";
|
||||||
import { useStyles } from "./styles";
|
import { useStyles } from "./styles";
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { ChangeEvent } from "@saleor/hooks/useForm";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import { FormData } from "../WebhookDetailsPage";
|
import { WebhookFormData } from "../WebhookDetailsPage";
|
||||||
import { messages } from "./messages";
|
import { messages } from "./messages";
|
||||||
|
|
||||||
interface WebhookStatusProps {
|
interface WebhookStatusProps {
|
||||||
|
@ -28,7 +28,7 @@ const WebhookStatus: React.FC<WebhookStatusProps> = ({
|
||||||
{intl.formatMessage(messages.webhookActiveDescription)}
|
{intl.formatMessage(messages.webhookActiveDescription)}
|
||||||
</Typography>
|
</Typography>
|
||||||
<ControlledCheckbox
|
<ControlledCheckbox
|
||||||
name={"isActive" as keyof FormData}
|
name={"isActive" as keyof WebhookFormData}
|
||||||
label={intl.formatMessage(messages.webhookActive)}
|
label={intl.formatMessage(messages.webhookActive)}
|
||||||
checked={data}
|
checked={data}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
|
@ -6,6 +6,8 @@ import Skeleton from "@saleor/components/Skeleton";
|
||||||
import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper";
|
import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper";
|
||||||
import TableCellHeader from "@saleor/components/TableCellHeader";
|
import TableCellHeader from "@saleor/components/TableCellHeader";
|
||||||
import TableRowLink from "@saleor/components/TableRowLink";
|
import TableRowLink from "@saleor/components/TableRowLink";
|
||||||
|
import { CustomAppUrls } from "@saleor/custom-apps/urls";
|
||||||
|
import { isUnnamed } from "@saleor/custom-apps/utils";
|
||||||
import { WebhookFragment } from "@saleor/graphql";
|
import { WebhookFragment } from "@saleor/graphql";
|
||||||
import {
|
import {
|
||||||
commonMessages,
|
commonMessages,
|
||||||
|
@ -14,8 +16,6 @@ import {
|
||||||
} from "@saleor/intl";
|
} from "@saleor/intl";
|
||||||
import { DeleteIcon, IconButton, Pill } from "@saleor/macaw-ui";
|
import { DeleteIcon, IconButton, Pill } from "@saleor/macaw-ui";
|
||||||
import { renderCollection, stopPropagation } from "@saleor/misc";
|
import { renderCollection, stopPropagation } from "@saleor/misc";
|
||||||
import { webhookPath } from "@saleor/webhooks/urls";
|
|
||||||
import { isUnnamed } from "@saleor/webhooks/utils";
|
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
@ -41,7 +41,7 @@ const WebhooksList: React.FC<WebhooksListProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={intl.formatMessage(sectionNames.webhooks)}
|
title={intl.formatMessage(sectionNames.webhooksAndEvents)}
|
||||||
toolbar={
|
toolbar={
|
||||||
!!createHref && (
|
!!createHref && (
|
||||||
<Button
|
<Button
|
||||||
|
@ -75,7 +75,10 @@ const WebhooksList: React.FC<WebhooksListProps> = ({
|
||||||
<TableRowLink
|
<TableRowLink
|
||||||
hover={!!webhook}
|
hover={!!webhook}
|
||||||
className={!!webhook ? classes.tableRow : undefined}
|
className={!!webhook ? classes.tableRow : undefined}
|
||||||
href={webhook && webhookPath(webhook.id)}
|
href={
|
||||||
|
webhook &&
|
||||||
|
CustomAppUrls.resolveWebhookUrl(webhook.app.id, webhook.id)
|
||||||
|
}
|
||||||
key={webhook ? webhook.id : "skeleton"}
|
key={webhook ? webhook.id : "skeleton"}
|
||||||
>
|
>
|
||||||
<TableCell
|
<TableCell
|
122
src/custom-apps/index.tsx
Normal file
122
src/custom-apps/index.tsx
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
|
import { sectionNames } from "@saleor/intl";
|
||||||
|
import { parse as parseQs } from "qs";
|
||||||
|
import React from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
import { Route, RouteComponentProps, Switch } from "react-router-dom";
|
||||||
|
|
||||||
|
import {
|
||||||
|
CustomAppDetailsUrlQueryParams,
|
||||||
|
CustomAppListUrlQueryParams,
|
||||||
|
CustomAppPaths,
|
||||||
|
} from "./urls";
|
||||||
|
import CustomAppCreateView from "./views/CustomAppCreate";
|
||||||
|
import CustomAppDetailsView from "./views/CustomAppDetails";
|
||||||
|
import CustomAppListView from "./views/CustomAppList";
|
||||||
|
import CustomAppWebhookCreateView from "./views/CustomAppWebhookCreate";
|
||||||
|
import CustomAppWebhookDetailsView from "./views/CustomAppWebhookDetails";
|
||||||
|
|
||||||
|
const CustomAppList: React.FC<RouteComponentProps> = () => {
|
||||||
|
const qs = parseQs(location.search.substr(1));
|
||||||
|
const params: CustomAppListUrlQueryParams = qs;
|
||||||
|
|
||||||
|
return <CustomAppListView params={params} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface CustomAppDetailsProps extends RouteComponentProps<{ id?: string }> {
|
||||||
|
token: string;
|
||||||
|
onTokenClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomAppDetails: React.FC<CustomAppDetailsProps> = ({
|
||||||
|
match,
|
||||||
|
token,
|
||||||
|
onTokenClose,
|
||||||
|
}) => {
|
||||||
|
const qs = parseQs(location.search.substr(1));
|
||||||
|
const params: CustomAppDetailsUrlQueryParams = qs;
|
||||||
|
const id = match.params.id;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
throw new Error("No ID provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CustomAppDetailsView
|
||||||
|
id={decodeURIComponent(id)}
|
||||||
|
params={params}
|
||||||
|
token={token}
|
||||||
|
onTokenClose={onTokenClose}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CustomAppWebhookCreate: React.FC<RouteComponentProps<any>> = ({
|
||||||
|
match,
|
||||||
|
}) => {
|
||||||
|
const appId = match.params.appId;
|
||||||
|
|
||||||
|
if (!appId) {
|
||||||
|
throw new Error("No App ID provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
return <CustomAppWebhookCreateView appId={decodeURIComponent(appId)} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const CustomAppWebhookDetails: React.FC<RouteComponentProps<any>> = ({
|
||||||
|
match,
|
||||||
|
}) => {
|
||||||
|
const id = match.params.id;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
throw new Error("No ID provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
return <CustomAppWebhookDetailsView id={decodeURIComponent(id)} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Component = () => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const [token, setToken] = React.useState<string>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<WindowTitle title={intl.formatMessage(sectionNames.webhooksAndEvents)} />
|
||||||
|
<Switch>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path={CustomAppPaths.appListPath}
|
||||||
|
component={CustomAppList}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path={CustomAppPaths.appAddPath}
|
||||||
|
render={() => <CustomAppCreateView setToken={setToken} />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path={CustomAppPaths.resolveAppPath(":id")}
|
||||||
|
render={props => (
|
||||||
|
<CustomAppDetails
|
||||||
|
{...props}
|
||||||
|
token={token}
|
||||||
|
onTokenClose={() => setToken(null)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path={CustomAppPaths.resolveWebhookAddPath(":appId")}
|
||||||
|
component={CustomAppWebhookCreate}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path={CustomAppPaths.resolveWebhookPath(":appId", ":id")}
|
||||||
|
component={CustomAppWebhookDetails}
|
||||||
|
/>
|
||||||
|
</Switch>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Component;
|
9
src/custom-apps/messages.ts
Normal file
9
src/custom-apps/messages.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { defineMessages } from "react-intl";
|
||||||
|
|
||||||
|
export const messages = defineMessages({
|
||||||
|
appRemoved: {
|
||||||
|
id: "uIPD1i",
|
||||||
|
defaultMessage: "App successfully removed",
|
||||||
|
description: "app has been removed",
|
||||||
|
},
|
||||||
|
});
|
70
src/custom-apps/urls.ts
Normal file
70
src/custom-apps/urls.ts
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import { stringifyQs } from "@saleor/utils/urls";
|
||||||
|
import urlJoin from "url-join";
|
||||||
|
|
||||||
|
import { Dialog, SingleAction } from "../types";
|
||||||
|
|
||||||
|
export type CustomAppListUrlDialog = "remove-custom-app";
|
||||||
|
export type CustomAppListUrlQueryParams = Dialog<CustomAppListUrlDialog> &
|
||||||
|
SingleAction;
|
||||||
|
|
||||||
|
export type CustomAppDetailsUrlDialog =
|
||||||
|
| "create-token"
|
||||||
|
| "remove-webhook"
|
||||||
|
| "remove-token"
|
||||||
|
| "app-activate"
|
||||||
|
| "app-deactivate";
|
||||||
|
export type CustomAppDetailsUrlQueryParams = Dialog<CustomAppDetailsUrlDialog> &
|
||||||
|
SingleAction;
|
||||||
|
|
||||||
|
export const CustomAppSections = {
|
||||||
|
appsSection: "/custom-apps/",
|
||||||
|
webhooksSection: "/webhooks/",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CustomAppPaths = {
|
||||||
|
resolveAppPath: (id: string) => urlJoin(CustomAppSections.appsSection, id),
|
||||||
|
appAddPath: urlJoin(CustomAppSections.appsSection, "add"),
|
||||||
|
appListPath: CustomAppSections.appsSection,
|
||||||
|
resolveWebhookPath: (appId: string, id: string) =>
|
||||||
|
urlJoin(
|
||||||
|
CustomAppSections.appsSection,
|
||||||
|
appId,
|
||||||
|
CustomAppSections.webhooksSection,
|
||||||
|
id,
|
||||||
|
),
|
||||||
|
resolveWebhookAddPath: (appId: string) =>
|
||||||
|
urlJoin(
|
||||||
|
CustomAppSections.appsSection,
|
||||||
|
appId,
|
||||||
|
CustomAppSections.webhooksSection,
|
||||||
|
"add",
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CustomAppUrls = {
|
||||||
|
appAddUrl: CustomAppPaths.appAddPath,
|
||||||
|
resolveAppUrl: (id: string, params?: CustomAppDetailsUrlQueryParams) =>
|
||||||
|
CustomAppPaths.resolveAppPath(encodeURIComponent(id)) +
|
||||||
|
"?" +
|
||||||
|
stringifyQs(params),
|
||||||
|
resolveAppListUrl: (params?: CustomAppListUrlQueryParams) =>
|
||||||
|
CustomAppPaths.appListPath + "?" + stringifyQs(params),
|
||||||
|
resolveWebhookUrl: (
|
||||||
|
appId: string,
|
||||||
|
id: string,
|
||||||
|
params?: CustomAppDetailsUrlQueryParams,
|
||||||
|
) =>
|
||||||
|
CustomAppPaths.resolveWebhookPath(
|
||||||
|
encodeURIComponent(appId),
|
||||||
|
encodeURIComponent(id),
|
||||||
|
) +
|
||||||
|
"?" +
|
||||||
|
stringifyQs(params),
|
||||||
|
resolveWebhookAddUrl: (
|
||||||
|
appId: string,
|
||||||
|
params?: CustomAppDetailsUrlQueryParams,
|
||||||
|
) =>
|
||||||
|
CustomAppPaths.resolveWebhookAddPath(encodeURIComponent(appId)) +
|
||||||
|
"?" +
|
||||||
|
stringifyQs(params),
|
||||||
|
};
|
121
src/custom-apps/utils.test.ts
Normal file
121
src/custom-apps/utils.test.ts
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
|
||||||
|
import { WebhookEventTypeAsyncEnum } from "@saleor/graphql";
|
||||||
|
|
||||||
|
import { filterSelectedAsyncEvents, mapAsyncEventsToChoices } 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", () => {
|
||||||
|
it("should return selected async event types when not any event selected", () => {
|
||||||
|
// Arrange
|
||||||
|
const selectedEvents: WebhookEventTypeAsyncEnum[] = [
|
||||||
|
WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
||||||
|
WebhookEventTypeAsyncEnum.PRODUCT_CREATED,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const asyncEvents = filterSelectedAsyncEvents(selectedEvents);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(asyncEvents).toHaveLength(2);
|
||||||
|
expect(asyncEvents).toEqual(selectedEvents);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return only any async event type when any event selected", () => {
|
||||||
|
// Arrange
|
||||||
|
const selectedEvents: WebhookEventTypeAsyncEnum[] = [
|
||||||
|
WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
||||||
|
WebhookEventTypeAsyncEnum.PAGE_CREATED,
|
||||||
|
WebhookEventTypeAsyncEnum.PRODUCT_CREATED,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const asyncEvents = filterSelectedAsyncEvents(selectedEvents);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const expectedAsyncEvents: WebhookEventTypeAsyncEnum[] = [
|
||||||
|
WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
||||||
|
];
|
||||||
|
expect(asyncEvents).toHaveLength(1);
|
||||||
|
expect(asyncEvents).toEqual(expectedAsyncEvents);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,4 +1,5 @@
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
|
import { CustomAppUrls } from "@saleor/custom-apps/urls";
|
||||||
import { AppCreateMutation, useAppCreateMutation } from "@saleor/graphql";
|
import { AppCreateMutation, useAppCreateMutation } from "@saleor/graphql";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
|
@ -11,12 +12,12 @@ import { useIntl } from "react-intl";
|
||||||
import CustomAppCreatePage, {
|
import CustomAppCreatePage, {
|
||||||
CustomAppCreatePageFormData,
|
CustomAppCreatePageFormData,
|
||||||
} from "../../components/CustomAppCreatePage";
|
} from "../../components/CustomAppCreatePage";
|
||||||
import { customAppUrl } from "../../urls";
|
|
||||||
import { messages } from "./messages";
|
import { messages } from "./messages";
|
||||||
|
|
||||||
interface CustomAppCreateProps {
|
interface CustomAppCreateProps {
|
||||||
setToken: (token: string) => void;
|
setToken: (token: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CustomAppCreate: React.FC<CustomAppCreateProps> = ({
|
export const CustomAppCreate: React.FC<CustomAppCreateProps> = ({
|
||||||
setToken,
|
setToken,
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -31,7 +32,7 @@ export const CustomAppCreate: React.FC<CustomAppCreateProps> = ({
|
||||||
status: "success",
|
status: "success",
|
||||||
text: intl.formatMessage(commonMessages.savedChanges),
|
text: intl.formatMessage(commonMessages.savedChanges),
|
||||||
});
|
});
|
||||||
navigate(customAppUrl(data.appCreate.app.id));
|
navigate(CustomAppUrls.resolveAppUrl(data.appCreate.app.id));
|
||||||
setToken(data.appCreate.authToken);
|
setToken(data.appCreate.authToken);
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -1,11 +1,13 @@
|
||||||
import AppActivateDialog from "@saleor/apps/components/AppActivateDialog";
|
import AppActivateDialog from "@saleor/apps/components/AppActivateDialog";
|
||||||
import AppDeactivateDialog from "@saleor/apps/components/AppDeactivateDialog";
|
import AppDeactivateDialog from "@saleor/apps/components/AppDeactivateDialog";
|
||||||
import TokenCreateDialog from "@saleor/apps/components/TokenCreateDialog";
|
|
||||||
import TokenDeleteDialog from "@saleor/apps/components/TokenDeleteDialog";
|
|
||||||
import { appMessages } from "@saleor/apps/messages";
|
import { appMessages } from "@saleor/apps/messages";
|
||||||
import NotFoundPage from "@saleor/components/NotFoundPage";
|
import NotFoundPage from "@saleor/components/NotFoundPage";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import { getApiUrl } from "@saleor/config";
|
import { getApiUrl } from "@saleor/config";
|
||||||
|
import TokenCreateDialog from "@saleor/custom-apps/components/TokenCreateDialog";
|
||||||
|
import TokenDeleteDialog from "@saleor/custom-apps/components/TokenDeleteDialog";
|
||||||
|
import WebhookDeleteDialog from "@saleor/custom-apps/components/WebhookDeleteDialog";
|
||||||
|
import { CustomAppUrls } from "@saleor/custom-apps/urls";
|
||||||
import {
|
import {
|
||||||
AppTokenCreateMutation,
|
AppTokenCreateMutation,
|
||||||
AppTokenDeleteMutation,
|
AppTokenDeleteMutation,
|
||||||
|
@ -26,8 +28,6 @@ import { commonMessages } from "@saleor/intl";
|
||||||
import { extractMutationErrors, getStringOrPlaceholder } from "@saleor/misc";
|
import { extractMutationErrors, getStringOrPlaceholder } from "@saleor/misc";
|
||||||
import getAppErrorMessage from "@saleor/utils/errors/app";
|
import getAppErrorMessage from "@saleor/utils/errors/app";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog";
|
|
||||||
import { webhookAddPath } from "@saleor/webhooks/urls";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -35,15 +35,13 @@ import CustomAppDetailsPage, {
|
||||||
CustomAppDetailsPageFormData,
|
CustomAppDetailsPageFormData,
|
||||||
} from "../../components/CustomAppDetailsPage";
|
} from "../../components/CustomAppDetailsPage";
|
||||||
import {
|
import {
|
||||||
appsListUrl,
|
CustomAppDetailsUrlDialog,
|
||||||
customAppUrl,
|
CustomAppDetailsUrlQueryParams,
|
||||||
CustomAppUrlDialog,
|
|
||||||
CustomAppUrlQueryParams,
|
|
||||||
} from "../../urls";
|
} from "../../urls";
|
||||||
|
|
||||||
interface OrderListProps {
|
interface OrderListProps {
|
||||||
id: string;
|
id: string;
|
||||||
params: CustomAppUrlQueryParams;
|
params: CustomAppDetailsUrlQueryParams;
|
||||||
token: string;
|
token: string;
|
||||||
onTokenClose: () => void;
|
onTokenClose: () => void;
|
||||||
}
|
}
|
||||||
|
@ -62,9 +60,9 @@ export const CustomAppDetails: React.FC<OrderListProps> = ({
|
||||||
React.useEffect(() => onTokenClose, []);
|
React.useEffect(() => onTokenClose, []);
|
||||||
|
|
||||||
const [openModal, closeModal] = createDialogActionHandlers<
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
CustomAppUrlDialog,
|
CustomAppDetailsUrlDialog,
|
||||||
CustomAppUrlQueryParams
|
CustomAppDetailsUrlQueryParams
|
||||||
>(navigate, params => customAppUrl(id, params), params);
|
>(navigate, params => CustomAppUrls.resolveAppUrl(id, params), params);
|
||||||
|
|
||||||
const { data, loading, refetch } = useAppQuery({
|
const { data, loading, refetch } = useAppQuery({
|
||||||
displayLoader: true,
|
displayLoader: true,
|
||||||
|
@ -117,7 +115,7 @@ export const CustomAppDetails: React.FC<OrderListProps> = ({
|
||||||
status: "success",
|
status: "success",
|
||||||
text: intl.formatMessage(commonMessages.savedChanges),
|
text: intl.formatMessage(commonMessages.savedChanges),
|
||||||
});
|
});
|
||||||
navigate(customAppUrl(id));
|
navigate(CustomAppUrls.resolveAppUrl(id));
|
||||||
closeModal();
|
closeModal();
|
||||||
refetch();
|
refetch();
|
||||||
}
|
}
|
||||||
|
@ -213,7 +211,7 @@ export const CustomAppDetails: React.FC<OrderListProps> = ({
|
||||||
const currentToken = data?.app?.tokens?.find(token => token.id === params.id);
|
const currentToken = data?.app?.tokens?.find(token => token.id === params.id);
|
||||||
|
|
||||||
if (customApp === null) {
|
if (customApp === null) {
|
||||||
return <NotFoundPage backHref={appsListUrl()} />;
|
return <NotFoundPage backHref={CustomAppUrls.resolveAppListUrl()} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -233,7 +231,7 @@ export const CustomAppDetails: React.FC<OrderListProps> = ({
|
||||||
id,
|
id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
webhookCreateHref={webhookAddPath(id)}
|
webhookCreateHref={CustomAppUrls.resolveWebhookAddUrl(id)}
|
||||||
onWebhookRemove={id =>
|
onWebhookRemove={id =>
|
||||||
openModal("remove-webhook", {
|
openModal("remove-webhook", {
|
||||||
id,
|
id,
|
123
src/custom-apps/views/CustomAppList.tsx
Normal file
123
src/custom-apps/views/CustomAppList.tsx
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
import { useApolloClient } from "@apollo/client";
|
||||||
|
import AppDeleteDialog from "@saleor/apps/components/AppDeleteDialog";
|
||||||
|
import { EXTENSION_LIST_QUERY } from "@saleor/apps/queries";
|
||||||
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
|
import {
|
||||||
|
AppSortField,
|
||||||
|
AppTypeEnum,
|
||||||
|
OrderDirection,
|
||||||
|
useAppDeleteMutation,
|
||||||
|
useAppsListQuery,
|
||||||
|
} from "@saleor/graphql";
|
||||||
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
|
import { sectionNames } from "@saleor/intl";
|
||||||
|
import { findById } from "@saleor/misc";
|
||||||
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
|
import { mapEdgesToItems } from "@saleor/utils/maps";
|
||||||
|
import React from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import CustomAppListPage from "../components/CustomAppListPage";
|
||||||
|
import { messages } from "../messages";
|
||||||
|
import {
|
||||||
|
CustomAppListUrlDialog,
|
||||||
|
CustomAppListUrlQueryParams,
|
||||||
|
CustomAppUrls,
|
||||||
|
} from "../urls";
|
||||||
|
|
||||||
|
interface CustomAppListProps {
|
||||||
|
params: CustomAppListUrlQueryParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CustomAppList: React.FC<CustomAppListProps> = ({ params }) => {
|
||||||
|
const navigate = useNavigator();
|
||||||
|
const notify = useNotifier();
|
||||||
|
const intl = useIntl();
|
||||||
|
const client = useApolloClient();
|
||||||
|
|
||||||
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
|
CustomAppListUrlDialog,
|
||||||
|
CustomAppListUrlQueryParams
|
||||||
|
>(navigate, CustomAppUrls.resolveAppListUrl, params);
|
||||||
|
|
||||||
|
const removeAppNotify = () => {
|
||||||
|
notify({
|
||||||
|
status: "success",
|
||||||
|
text: intl.formatMessage(messages.appRemoved),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const refetchExtensionList = () => {
|
||||||
|
client.refetchQueries({
|
||||||
|
include: [EXTENSION_LIST_QUERY],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const queryVariables = {
|
||||||
|
sort: {
|
||||||
|
direction: OrderDirection.DESC,
|
||||||
|
field: AppSortField.CREATION_DATE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data: customAppsData, refetch: customAppsRefetch } = useAppsListQuery(
|
||||||
|
{
|
||||||
|
displayLoader: true,
|
||||||
|
variables: {
|
||||||
|
first: 100,
|
||||||
|
...queryVariables,
|
||||||
|
filter: {
|
||||||
|
type: AppTypeEnum.LOCAL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const [deleteApp, deleteAppOpts] = useAppDeleteMutation({
|
||||||
|
onCompleted: data => {
|
||||||
|
if (!data?.appDelete?.errors?.length) {
|
||||||
|
customAppsRefetch();
|
||||||
|
closeModal();
|
||||||
|
refetchExtensionList();
|
||||||
|
removeAppNotify();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleRemoveConfirm = () =>
|
||||||
|
deleteApp({
|
||||||
|
variables: {
|
||||||
|
id: params.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const customApps = mapEdgesToItems(customAppsData?.apps);
|
||||||
|
const currentAppName = findById(params.id, customApps)?.name;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<WindowTitle title={intl.formatMessage(sectionNames.webhooksAndEvents)} />
|
||||||
|
<AppDeleteDialog
|
||||||
|
confirmButtonState={deleteAppOpts.status}
|
||||||
|
name={currentAppName}
|
||||||
|
onClose={closeModal}
|
||||||
|
onConfirm={handleRemoveConfirm}
|
||||||
|
type="CUSTOM"
|
||||||
|
open={params.action === "remove-custom-app"}
|
||||||
|
/>
|
||||||
|
<CustomAppListPage
|
||||||
|
appsList={customApps}
|
||||||
|
getCustomAppHref={id => CustomAppUrls.resolveAppUrl(id)}
|
||||||
|
onRemove={id =>
|
||||||
|
openModal("remove-custom-app", {
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
CustomAppList.displayName = "CustomAppList";
|
||||||
|
export default CustomAppList;
|
|
@ -11,19 +11,23 @@ import { extractMutationErrors } from "@saleor/misc";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import WebhookDetailsPage, { FormData } from "../components/WebhookDetailsPage";
|
import WebhookDetailsPage, {
|
||||||
import { webhookUrl } from "../urls";
|
WebhookFormData,
|
||||||
|
} from "../components/WebhookDetailsPage";
|
||||||
|
import { CustomAppUrls } from "../urls";
|
||||||
|
|
||||||
export interface WebhooksCreateProps {
|
export interface CustomAppWebhookCreateProps {
|
||||||
id: string;
|
appId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WebhooksCreate: React.FC<WebhooksCreateProps> = ({ id }) => {
|
export const CustomAppWebhookCreate: React.FC<CustomAppWebhookCreateProps> = ({
|
||||||
|
appId,
|
||||||
|
}) => {
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const { data } = useAppQuery({ variables: { id } });
|
const { data } = useAppQuery({ variables: { id: appId } });
|
||||||
|
|
||||||
const [webhookCreate, webhookCreateOpts] = useWebhookCreateMutation({
|
const [webhookCreate, webhookCreateOpts] = useWebhookCreateMutation({
|
||||||
onCompleted: data => {
|
onCompleted: data => {
|
||||||
|
@ -33,17 +37,17 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = ({ id }) => {
|
||||||
status: "success",
|
status: "success",
|
||||||
text: intl.formatMessage(commonMessages.savedChanges),
|
text: intl.formatMessage(commonMessages.savedChanges),
|
||||||
});
|
});
|
||||||
navigate(webhookUrl(webhook.id));
|
navigate(CustomAppUrls.resolveWebhookUrl(appId, webhook.id));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleSubmit = (data: FormData) =>
|
const handleSubmit = (data: WebhookFormData) =>
|
||||||
extractMutationErrors(
|
extractMutationErrors(
|
||||||
webhookCreate({
|
webhookCreate({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
app: id,
|
app: appId,
|
||||||
syncEvents: data.syncEvents,
|
syncEvents: data.syncEvents,
|
||||||
asyncEvents: data.asyncEvents.includes(
|
asyncEvents: data.asyncEvents.includes(
|
||||||
WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
WebhookEventTypeAsyncEnum.ANY_EVENTS,
|
||||||
|
@ -69,8 +73,8 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = ({ id }) => {
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<WebhookDetailsPage
|
<WebhookDetailsPage
|
||||||
|
appId={appId}
|
||||||
appName={data?.app?.name ?? ""}
|
appName={data?.app?.name ?? ""}
|
||||||
appId={id}
|
|
||||||
disabled={false}
|
disabled={false}
|
||||||
errors={webhookCreateOpts.data?.webhookCreate?.errors ?? []}
|
errors={webhookCreateOpts.data?.webhookCreate?.errors ?? []}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
@ -80,5 +84,5 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = ({ id }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
WebhooksCreate.displayName = "WebhooksCreate";
|
CustomAppWebhookCreate.displayName = "CustomAppWebhookCreate";
|
||||||
export default WebhooksCreate;
|
export default CustomAppWebhookCreate;
|
|
@ -1,4 +1,3 @@
|
||||||
import { appsListUrl } from "@saleor/apps/urls";
|
|
||||||
import NotFoundPage from "@saleor/components/NotFoundPage";
|
import NotFoundPage from "@saleor/components/NotFoundPage";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import {
|
import {
|
||||||
|
@ -12,14 +11,18 @@ import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import { extractMutationErrors, getStringOrPlaceholder } from "../../misc";
|
import { extractMutationErrors, getStringOrPlaceholder } from "../../misc";
|
||||||
import WebhookDetailsPage from "../components/WebhookDetailsPage";
|
import WebhookDetailsPage, {
|
||||||
import { WebhookFormData } from "../components/WebhooksDetailsPage/WebhooksDetailsPage";
|
WebhookFormData,
|
||||||
|
} from "../components/WebhookDetailsPage";
|
||||||
|
import { CustomAppUrls } from "../urls";
|
||||||
|
|
||||||
export interface WebhooksDetailsProps {
|
export interface CustomAppWebhookDetailsProps {
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({ id }) => {
|
export const CustomAppWebhookDetails: React.FC<CustomAppWebhookDetailsProps> = ({
|
||||||
|
id,
|
||||||
|
}) => {
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
@ -64,7 +67,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({ id }) => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
if (!webhook && !loading) {
|
if (!webhook && !loading) {
|
||||||
return <NotFoundPage backHref={appsListUrl()} />;
|
return <NotFoundPage backHref={CustomAppUrls.resolveAppListUrl()} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -85,5 +88,5 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({ id }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
WebhooksDetails.displayName = "WebhooksDetails";
|
CustomAppWebhookDetails.displayName = "CustomAppWebhookDetails";
|
||||||
export default WebhooksDetails;
|
export default CustomAppWebhookDetails;
|
|
@ -10,7 +10,7 @@ import DeleteWarningDialogConsentContent from "@saleor/components/TypeDeleteWarn
|
||||||
import { GiftCardsListConsumerProps } from "@saleor/giftCards/GiftCardsList/providers/GiftCardListProvider";
|
import { GiftCardsListConsumerProps } from "@saleor/giftCards/GiftCardsList/providers/GiftCardListProvider";
|
||||||
import { ExtendedGiftCard } from "@saleor/giftCards/GiftCardUpdate/providers/GiftCardDetailsProvider/types";
|
import { ExtendedGiftCard } from "@saleor/giftCards/GiftCardUpdate/providers/GiftCardDetailsProvider/types";
|
||||||
import { GiftCardDataFragment } from "@saleor/graphql";
|
import { GiftCardDataFragment } from "@saleor/graphql";
|
||||||
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
|
import { getById } from "@saleor/misc";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
|
|
@ -5341,6 +5341,155 @@ export function useCheckOrderInvoicesStatusLazyQuery(baseOptions?: ApolloReactHo
|
||||||
export type CheckOrderInvoicesStatusQueryHookResult = ReturnType<typeof useCheckOrderInvoicesStatusQuery>;
|
export type CheckOrderInvoicesStatusQueryHookResult = ReturnType<typeof useCheckOrderInvoicesStatusQuery>;
|
||||||
export type CheckOrderInvoicesStatusLazyQueryHookResult = ReturnType<typeof useCheckOrderInvoicesStatusLazyQuery>;
|
export type CheckOrderInvoicesStatusLazyQueryHookResult = ReturnType<typeof useCheckOrderInvoicesStatusLazyQuery>;
|
||||||
export type CheckOrderInvoicesStatusQueryResult = Apollo.QueryResult<Types.CheckOrderInvoicesStatusQuery, Types.CheckOrderInvoicesStatusQueryVariables>;
|
export type CheckOrderInvoicesStatusQueryResult = Apollo.QueryResult<Types.CheckOrderInvoicesStatusQuery, Types.CheckOrderInvoicesStatusQueryVariables>;
|
||||||
|
export const WebhookCreateDocument = gql`
|
||||||
|
mutation WebhookCreate($input: WebhookCreateInput!) {
|
||||||
|
webhookCreate(input: $input) {
|
||||||
|
errors {
|
||||||
|
...WebhookError
|
||||||
|
}
|
||||||
|
webhook {
|
||||||
|
...WebhookDetails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${WebhookErrorFragmentDoc}
|
||||||
|
${WebhookDetailsFragmentDoc}`;
|
||||||
|
export type WebhookCreateMutationFn = Apollo.MutationFunction<Types.WebhookCreateMutation, Types.WebhookCreateMutationVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useWebhookCreateMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useWebhookCreateMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useWebhookCreateMutation` 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 [webhookCreateMutation, { data, loading, error }] = useWebhookCreateMutation({
|
||||||
|
* variables: {
|
||||||
|
* input: // value for 'input'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useWebhookCreateMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.WebhookCreateMutation, Types.WebhookCreateMutationVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useMutation<Types.WebhookCreateMutation, Types.WebhookCreateMutationVariables>(WebhookCreateDocument, options);
|
||||||
|
}
|
||||||
|
export type WebhookCreateMutationHookResult = ReturnType<typeof useWebhookCreateMutation>;
|
||||||
|
export type WebhookCreateMutationResult = Apollo.MutationResult<Types.WebhookCreateMutation>;
|
||||||
|
export type WebhookCreateMutationOptions = Apollo.BaseMutationOptions<Types.WebhookCreateMutation, Types.WebhookCreateMutationVariables>;
|
||||||
|
export const WebhookUpdateDocument = gql`
|
||||||
|
mutation WebhookUpdate($id: ID!, $input: WebhookUpdateInput!) {
|
||||||
|
webhookUpdate(id: $id, input: $input) {
|
||||||
|
errors {
|
||||||
|
...WebhookError
|
||||||
|
}
|
||||||
|
webhook {
|
||||||
|
...WebhookDetails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${WebhookErrorFragmentDoc}
|
||||||
|
${WebhookDetailsFragmentDoc}`;
|
||||||
|
export type WebhookUpdateMutationFn = Apollo.MutationFunction<Types.WebhookUpdateMutation, Types.WebhookUpdateMutationVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useWebhookUpdateMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useWebhookUpdateMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useWebhookUpdateMutation` 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 [webhookUpdateMutation, { data, loading, error }] = useWebhookUpdateMutation({
|
||||||
|
* variables: {
|
||||||
|
* id: // value for 'id'
|
||||||
|
* input: // value for 'input'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useWebhookUpdateMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.WebhookUpdateMutation, Types.WebhookUpdateMutationVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useMutation<Types.WebhookUpdateMutation, Types.WebhookUpdateMutationVariables>(WebhookUpdateDocument, options);
|
||||||
|
}
|
||||||
|
export type WebhookUpdateMutationHookResult = ReturnType<typeof useWebhookUpdateMutation>;
|
||||||
|
export type WebhookUpdateMutationResult = Apollo.MutationResult<Types.WebhookUpdateMutation>;
|
||||||
|
export type WebhookUpdateMutationOptions = Apollo.BaseMutationOptions<Types.WebhookUpdateMutation, Types.WebhookUpdateMutationVariables>;
|
||||||
|
export const WebhookDeleteDocument = gql`
|
||||||
|
mutation WebhookDelete($id: ID!) {
|
||||||
|
webhookDelete(id: $id) {
|
||||||
|
errors {
|
||||||
|
...WebhookError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${WebhookErrorFragmentDoc}`;
|
||||||
|
export type WebhookDeleteMutationFn = Apollo.MutationFunction<Types.WebhookDeleteMutation, Types.WebhookDeleteMutationVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useWebhookDeleteMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useWebhookDeleteMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useWebhookDeleteMutation` 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 [webhookDeleteMutation, { data, loading, error }] = useWebhookDeleteMutation({
|
||||||
|
* variables: {
|
||||||
|
* id: // value for 'id'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useWebhookDeleteMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.WebhookDeleteMutation, Types.WebhookDeleteMutationVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useMutation<Types.WebhookDeleteMutation, Types.WebhookDeleteMutationVariables>(WebhookDeleteDocument, options);
|
||||||
|
}
|
||||||
|
export type WebhookDeleteMutationHookResult = ReturnType<typeof useWebhookDeleteMutation>;
|
||||||
|
export type WebhookDeleteMutationResult = Apollo.MutationResult<Types.WebhookDeleteMutation>;
|
||||||
|
export type WebhookDeleteMutationOptions = Apollo.BaseMutationOptions<Types.WebhookDeleteMutation, Types.WebhookDeleteMutationVariables>;
|
||||||
|
export const WebhookDetailsDocument = gql`
|
||||||
|
query WebhookDetails($id: ID!) {
|
||||||
|
webhook(id: $id) {
|
||||||
|
...WebhookDetails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${WebhookDetailsFragmentDoc}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useWebhookDetailsQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useWebhookDetailsQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useWebhookDetailsQuery` 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 } = useWebhookDetailsQuery({
|
||||||
|
* variables: {
|
||||||
|
* id: // value for 'id'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useWebhookDetailsQuery(baseOptions: ApolloReactHooks.QueryHookOptions<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useQuery<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>(WebhookDetailsDocument, options);
|
||||||
|
}
|
||||||
|
export function useWebhookDetailsLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useLazyQuery<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>(WebhookDetailsDocument, options);
|
||||||
|
}
|
||||||
|
export type WebhookDetailsQueryHookResult = ReturnType<typeof useWebhookDetailsQuery>;
|
||||||
|
export type WebhookDetailsLazyQueryHookResult = ReturnType<typeof useWebhookDetailsLazyQuery>;
|
||||||
|
export type WebhookDetailsQueryResult = Apollo.QueryResult<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>;
|
||||||
export const UpdateCustomerDocument = gql`
|
export const UpdateCustomerDocument = gql`
|
||||||
mutation UpdateCustomer($id: ID!, $input: CustomerInput!) {
|
mutation UpdateCustomer($id: ID!, $input: CustomerInput!) {
|
||||||
customerUpdate(id: $id, input: $input) {
|
customerUpdate(id: $id, input: $input) {
|
||||||
|
@ -16970,153 +17119,4 @@ export function useWarehousesCountLazyQuery(baseOptions?: ApolloReactHooks.LazyQ
|
||||||
}
|
}
|
||||||
export type WarehousesCountQueryHookResult = ReturnType<typeof useWarehousesCountQuery>;
|
export type WarehousesCountQueryHookResult = ReturnType<typeof useWarehousesCountQuery>;
|
||||||
export type WarehousesCountLazyQueryHookResult = ReturnType<typeof useWarehousesCountLazyQuery>;
|
export type WarehousesCountLazyQueryHookResult = ReturnType<typeof useWarehousesCountLazyQuery>;
|
||||||
export type WarehousesCountQueryResult = Apollo.QueryResult<Types.WarehousesCountQuery, Types.WarehousesCountQueryVariables>;
|
export type WarehousesCountQueryResult = Apollo.QueryResult<Types.WarehousesCountQuery, Types.WarehousesCountQueryVariables>;
|
||||||
export const WebhookCreateDocument = gql`
|
|
||||||
mutation WebhookCreate($input: WebhookCreateInput!) {
|
|
||||||
webhookCreate(input: $input) {
|
|
||||||
errors {
|
|
||||||
...WebhookError
|
|
||||||
}
|
|
||||||
webhook {
|
|
||||||
...WebhookDetails
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
${WebhookErrorFragmentDoc}
|
|
||||||
${WebhookDetailsFragmentDoc}`;
|
|
||||||
export type WebhookCreateMutationFn = Apollo.MutationFunction<Types.WebhookCreateMutation, Types.WebhookCreateMutationVariables>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __useWebhookCreateMutation__
|
|
||||||
*
|
|
||||||
* To run a mutation, you first call `useWebhookCreateMutation` within a React component and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `useWebhookCreateMutation` 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 [webhookCreateMutation, { data, loading, error }] = useWebhookCreateMutation({
|
|
||||||
* variables: {
|
|
||||||
* input: // value for 'input'
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function useWebhookCreateMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.WebhookCreateMutation, Types.WebhookCreateMutationVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return ApolloReactHooks.useMutation<Types.WebhookCreateMutation, Types.WebhookCreateMutationVariables>(WebhookCreateDocument, options);
|
|
||||||
}
|
|
||||||
export type WebhookCreateMutationHookResult = ReturnType<typeof useWebhookCreateMutation>;
|
|
||||||
export type WebhookCreateMutationResult = Apollo.MutationResult<Types.WebhookCreateMutation>;
|
|
||||||
export type WebhookCreateMutationOptions = Apollo.BaseMutationOptions<Types.WebhookCreateMutation, Types.WebhookCreateMutationVariables>;
|
|
||||||
export const WebhookUpdateDocument = gql`
|
|
||||||
mutation WebhookUpdate($id: ID!, $input: WebhookUpdateInput!) {
|
|
||||||
webhookUpdate(id: $id, input: $input) {
|
|
||||||
errors {
|
|
||||||
...WebhookError
|
|
||||||
}
|
|
||||||
webhook {
|
|
||||||
...WebhookDetails
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
${WebhookErrorFragmentDoc}
|
|
||||||
${WebhookDetailsFragmentDoc}`;
|
|
||||||
export type WebhookUpdateMutationFn = Apollo.MutationFunction<Types.WebhookUpdateMutation, Types.WebhookUpdateMutationVariables>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __useWebhookUpdateMutation__
|
|
||||||
*
|
|
||||||
* To run a mutation, you first call `useWebhookUpdateMutation` within a React component and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `useWebhookUpdateMutation` 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 [webhookUpdateMutation, { data, loading, error }] = useWebhookUpdateMutation({
|
|
||||||
* variables: {
|
|
||||||
* id: // value for 'id'
|
|
||||||
* input: // value for 'input'
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function useWebhookUpdateMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.WebhookUpdateMutation, Types.WebhookUpdateMutationVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return ApolloReactHooks.useMutation<Types.WebhookUpdateMutation, Types.WebhookUpdateMutationVariables>(WebhookUpdateDocument, options);
|
|
||||||
}
|
|
||||||
export type WebhookUpdateMutationHookResult = ReturnType<typeof useWebhookUpdateMutation>;
|
|
||||||
export type WebhookUpdateMutationResult = Apollo.MutationResult<Types.WebhookUpdateMutation>;
|
|
||||||
export type WebhookUpdateMutationOptions = Apollo.BaseMutationOptions<Types.WebhookUpdateMutation, Types.WebhookUpdateMutationVariables>;
|
|
||||||
export const WebhookDeleteDocument = gql`
|
|
||||||
mutation WebhookDelete($id: ID!) {
|
|
||||||
webhookDelete(id: $id) {
|
|
||||||
errors {
|
|
||||||
...WebhookError
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
${WebhookErrorFragmentDoc}`;
|
|
||||||
export type WebhookDeleteMutationFn = Apollo.MutationFunction<Types.WebhookDeleteMutation, Types.WebhookDeleteMutationVariables>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __useWebhookDeleteMutation__
|
|
||||||
*
|
|
||||||
* To run a mutation, you first call `useWebhookDeleteMutation` within a React component and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `useWebhookDeleteMutation` 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 [webhookDeleteMutation, { data, loading, error }] = useWebhookDeleteMutation({
|
|
||||||
* variables: {
|
|
||||||
* id: // value for 'id'
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function useWebhookDeleteMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.WebhookDeleteMutation, Types.WebhookDeleteMutationVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return ApolloReactHooks.useMutation<Types.WebhookDeleteMutation, Types.WebhookDeleteMutationVariables>(WebhookDeleteDocument, options);
|
|
||||||
}
|
|
||||||
export type WebhookDeleteMutationHookResult = ReturnType<typeof useWebhookDeleteMutation>;
|
|
||||||
export type WebhookDeleteMutationResult = Apollo.MutationResult<Types.WebhookDeleteMutation>;
|
|
||||||
export type WebhookDeleteMutationOptions = Apollo.BaseMutationOptions<Types.WebhookDeleteMutation, Types.WebhookDeleteMutationVariables>;
|
|
||||||
export const WebhookDetailsDocument = gql`
|
|
||||||
query WebhookDetails($id: ID!) {
|
|
||||||
webhook(id: $id) {
|
|
||||||
...WebhookDetails
|
|
||||||
}
|
|
||||||
}
|
|
||||||
${WebhookDetailsFragmentDoc}`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __useWebhookDetailsQuery__
|
|
||||||
*
|
|
||||||
* To run a query within a React component, call `useWebhookDetailsQuery` and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `useWebhookDetailsQuery` 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 } = useWebhookDetailsQuery({
|
|
||||||
* variables: {
|
|
||||||
* id: // value for 'id'
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function useWebhookDetailsQuery(baseOptions: ApolloReactHooks.QueryHookOptions<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return ApolloReactHooks.useQuery<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>(WebhookDetailsDocument, options);
|
|
||||||
}
|
|
||||||
export function useWebhookDetailsLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return ApolloReactHooks.useLazyQuery<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>(WebhookDetailsDocument, options);
|
|
||||||
}
|
|
||||||
export type WebhookDetailsQueryHookResult = ReturnType<typeof useWebhookDetailsQuery>;
|
|
||||||
export type WebhookDetailsLazyQueryHookResult = ReturnType<typeof useWebhookDetailsLazyQuery>;
|
|
||||||
export type WebhookDetailsQueryResult = Apollo.QueryResult<Types.WebhookDetailsQuery, Types.WebhookDetailsQueryVariables>;
|
|
|
@ -6722,6 +6722,35 @@ export type CheckOrderInvoicesStatusQueryVariables = Exact<{
|
||||||
|
|
||||||
export type CheckOrderInvoicesStatusQuery = { __typename: 'Query', order: { __typename: 'Order', id: string, invoices: Array<{ __typename: 'Invoice', id: string, number: string | null, createdAt: any, url: string | null, status: JobStatusEnum }> } | null };
|
export type CheckOrderInvoicesStatusQuery = { __typename: 'Query', order: { __typename: 'Order', id: string, invoices: Array<{ __typename: 'Invoice', id: string, number: string | null, createdAt: any, url: string | null, status: JobStatusEnum }> } | null };
|
||||||
|
|
||||||
|
export type WebhookCreateMutationVariables = Exact<{
|
||||||
|
input: WebhookCreateInput;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
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'];
|
||||||
|
input: WebhookUpdateInput;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
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'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type WebhookDeleteMutation = { __typename: 'Mutation', webhookDelete: { __typename: 'WebhookDelete', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }> } | null };
|
||||||
|
|
||||||
|
export type WebhookDetailsQueryVariables = Exact<{
|
||||||
|
id: Scalars['ID'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type WebhookDetailsQuery = { __typename: 'Query', 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 };
|
||||||
|
|
||||||
export type UpdateCustomerMutationVariables = Exact<{
|
export type UpdateCustomerMutationVariables = Exact<{
|
||||||
id: Scalars['ID'];
|
id: Scalars['ID'];
|
||||||
input: CustomerInput;
|
input: CustomerInput;
|
||||||
|
@ -9404,32 +9433,3 @@ export type WarehousesCountQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
export type WarehousesCountQuery = { __typename: 'Query', warehouses: { __typename: 'WarehouseCountableConnection', totalCount: number | null } | null };
|
export type WarehousesCountQuery = { __typename: 'Query', warehouses: { __typename: 'WarehouseCountableConnection', totalCount: number | null } | null };
|
||||||
|
|
||||||
export type WebhookCreateMutationVariables = Exact<{
|
|
||||||
input: WebhookCreateInput;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
|
|
||||||
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'];
|
|
||||||
input: WebhookUpdateInput;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
|
|
||||||
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'];
|
|
||||||
}>;
|
|
||||||
|
|
||||||
|
|
||||||
export type WebhookDeleteMutation = { __typename: 'Mutation', webhookDelete: { __typename: 'WebhookDelete', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }> } | null };
|
|
||||||
|
|
||||||
export type WebhookDetailsQueryVariables = Exact<{
|
|
||||||
id: Scalars['ID'];
|
|
||||||
}>;
|
|
||||||
|
|
||||||
|
|
||||||
export type WebhookDetailsQuery = { __typename: 'Query', 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 };
|
|
||||||
|
|
36
src/icons/Miscellaneous.tsx
Normal file
36
src/icons/Miscellaneous.tsx
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import { createSvgIcon, SvgIconProps } from "@material-ui/core";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const Miscellaneous = createSvgIcon(
|
||||||
|
<>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M4.00037 2.375C3.1029 2.375 2.37537 3.10254 2.37537 4L2.37537 9C2.37537 9.89746 3.1029 10.625 4.00037 10.625H9.00037C9.89783 10.625 10.6254 9.89746 10.6254 9V4C10.6254 3.10254 9.89783 2.375 9.00037 2.375L4.00037 2.375ZM3.62537 4C3.62537 3.79289 3.79326 3.625 4.00037 3.625L9.00037 3.625C9.20747 3.625 9.37537 3.79289 9.37537 4V9C9.37537 9.20711 9.20747 9.375 9.00037 9.375H4.00037C3.79326 9.375 3.62537 9.20711 3.62537 9L3.62537 4Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M15.0004 2.375C14.1029 2.375 13.3754 3.10254 13.3754 4V9C13.3754 9.89746 14.1029 10.625 15.0004 10.625H20.0004C20.8978 10.625 21.6254 9.89746 21.6254 9L21.6254 4C21.6254 3.10254 20.8978 2.375 20.0004 2.375L15.0004 2.375ZM14.6254 4C14.6254 3.79289 14.7933 3.625 15.0004 3.625L20.0004 3.625C20.2075 3.625 20.3754 3.79289 20.3754 4L20.3754 9C20.3754 9.20711 20.2075 9.375 20.0004 9.375H15.0004C14.7933 9.375 14.6254 9.20711 14.6254 9V4Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M2.37537 15C2.37537 14.1025 3.1029 13.375 4.00037 13.375H9.00037C9.89783 13.375 10.6254 14.1025 10.6254 15V20C10.6254 20.8975 9.89783 21.625 9.00037 21.625H4.00037C3.1029 21.625 2.37537 20.8975 2.37537 20L2.37537 15ZM4.00037 14.625C3.79326 14.625 3.62537 14.7929 3.62537 15L3.62537 20C3.62537 20.2071 3.79326 20.375 4.00037 20.375H9.00037C9.20747 20.375 9.37537 20.2071 9.37537 20V15C9.37537 14.7929 9.20747 14.625 9.00037 14.625H4.00037Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M15.0004 13.375C14.1029 13.375 13.3754 14.1025 13.3754 15V20C13.3754 20.8975 14.1029 21.625 15.0004 21.625H20.0004C20.8978 21.625 21.6254 20.8975 21.6254 20L21.6254 15C21.6254 14.1025 20.8978 13.375 20.0004 13.375H15.0004ZM14.6254 15C14.6254 14.7929 14.7933 14.625 15.0004 14.625H20.0004C20.2075 14.625 20.3754 14.7929 20.3754 15L20.3754 20C20.3754 20.2071 20.2075 20.375 20.0004 20.375H15.0004C14.7933 20.375 14.6254 20.2071 14.6254 20V15Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</>,
|
||||||
|
"Miscellaneous",
|
||||||
|
);
|
||||||
|
|
||||||
|
export default (props: SvgIconProps) => (
|
||||||
|
<Miscellaneous {...props} viewBox="0 0 24 24" fill="none" />
|
||||||
|
);
|
|
@ -42,6 +42,8 @@ import { getConfigMenuItemsPermissions } from "./configuration/utils";
|
||||||
import AppStateProvider from "./containers/AppState";
|
import AppStateProvider from "./containers/AppState";
|
||||||
import BackgroundTasksProvider from "./containers/BackgroundTasks";
|
import BackgroundTasksProvider from "./containers/BackgroundTasks";
|
||||||
import ServiceWorker from "./containers/ServiceWorker/ServiceWorker";
|
import ServiceWorker from "./containers/ServiceWorker/ServiceWorker";
|
||||||
|
import CustomAppsSection from "./custom-apps";
|
||||||
|
import { CustomAppSections } from "./custom-apps/urls";
|
||||||
import { CustomerSection } from "./customers";
|
import { CustomerSection } from "./customers";
|
||||||
import DiscountSection from "./discounts";
|
import DiscountSection from "./discounts";
|
||||||
import GiftCardSection from "./giftCards";
|
import GiftCardSection from "./giftCards";
|
||||||
|
@ -281,6 +283,10 @@ const Routes: React.FC = () => {
|
||||||
path="/configuration"
|
path="/configuration"
|
||||||
component={ConfigurationSection}
|
component={ConfigurationSection}
|
||||||
/>
|
/>
|
||||||
|
<SectionRoute
|
||||||
|
path={CustomAppSections.appsSection}
|
||||||
|
component={CustomAppsSection}
|
||||||
|
/>
|
||||||
<Route component={NotFound} />
|
<Route component={NotFound} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
|
|
|
@ -501,10 +501,10 @@ export const sectionNames = defineMessages({
|
||||||
defaultMessage: "Warehouses",
|
defaultMessage: "Warehouses",
|
||||||
description: "warehouses section name",
|
description: "warehouses section name",
|
||||||
},
|
},
|
||||||
webhooks: {
|
webhooksAndEvents: {
|
||||||
id: "6nSTuC",
|
id: "BFR6CF",
|
||||||
defaultMessage: "Webhooks",
|
defaultMessage: "Webhooks & Events",
|
||||||
description: "webhooks section name",
|
description: "webhooks and events section name",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
13
src/misc.ts
13
src/misc.ts
|
@ -7,6 +7,7 @@ import {
|
||||||
PaymentChargeStatusEnum,
|
PaymentChargeStatusEnum,
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
import { ConfirmButtonTransitionState, ThemeType } from "@saleor/macaw-ui";
|
import { ConfirmButtonTransitionState, ThemeType } from "@saleor/macaw-ui";
|
||||||
|
import { Node, SlugNode } from "@saleor/types";
|
||||||
import uniqBy from "lodash/uniqBy";
|
import uniqBy from "lodash/uniqBy";
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
import { IntlShape } from "react-intl";
|
import { IntlShape } from "react-intl";
|
||||||
|
@ -541,5 +542,15 @@ export const isInDevelopment =
|
||||||
export type WithOptional<T, K extends keyof T> = Omit<T, K> &
|
export type WithOptional<T, K extends keyof T> = Omit<T, K> &
|
||||||
Partial<Pick<T, K>>;
|
Partial<Pick<T, K>>;
|
||||||
|
|
||||||
export const getBySlug = (slugToCompare: string) => (obj: { slug: string }) =>
|
export const getBySlug = (slugToCompare: string) => (obj: SlugNode) =>
|
||||||
obj.slug === slugToCompare;
|
obj.slug === slugToCompare;
|
||||||
|
|
||||||
|
export const getById = (idToCompare: string) => (obj: Node) =>
|
||||||
|
obj.id === idToCompare;
|
||||||
|
|
||||||
|
export const getByUnmatchingId = (idToCompare: string) => (obj: {
|
||||||
|
id: string;
|
||||||
|
}) => obj.id !== idToCompare;
|
||||||
|
|
||||||
|
export const findById = <T extends Node>(id: string, list?: T[]) =>
|
||||||
|
list?.find(getById(id));
|
||||||
|
|
|
@ -17,8 +17,7 @@ import usePaginator, {
|
||||||
PaginatorContext,
|
PaginatorContext,
|
||||||
} from "@saleor/hooks/usePaginator";
|
} from "@saleor/hooks/usePaginator";
|
||||||
import { buttonMessages, commonMessages } from "@saleor/intl";
|
import { buttonMessages, commonMessages } from "@saleor/intl";
|
||||||
import { getStringOrPlaceholder, maybe } from "@saleor/misc";
|
import { getById, getStringOrPlaceholder, maybe } from "@saleor/misc";
|
||||||
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
|
|
||||||
import { ListViews } from "@saleor/types";
|
import { ListViews } from "@saleor/types";
|
||||||
import createSortHandler from "@saleor/utils/handlers/sortHandler";
|
import createSortHandler from "@saleor/utils/handlers/sortHandler";
|
||||||
import { mapEdgesToItems } from "@saleor/utils/maps";
|
import { mapEdgesToItems } from "@saleor/utils/maps";
|
||||||
|
|
|
@ -25,13 +25,13 @@ import {
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
useElementScroll,
|
useElementScroll,
|
||||||
} from "@saleor/macaw-ui";
|
} from "@saleor/macaw-ui";
|
||||||
|
import { getById } from "@saleor/misc";
|
||||||
import { getLineAvailableQuantityInWarehouse } from "@saleor/orders/utils/data";
|
import { getLineAvailableQuantityInWarehouse } from "@saleor/orders/utils/data";
|
||||||
import useWarehouseSearch from "@saleor/searches/useWarehouseSearch";
|
import useWarehouseSearch from "@saleor/searches/useWarehouseSearch";
|
||||||
import { mapEdgesToItems } from "@saleor/utils/maps";
|
import { mapEdgesToItems } from "@saleor/utils/maps";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import { getById } from "../OrderReturnPage/utils";
|
|
||||||
import { changeWarehouseDialogMessages as messages } from "./messages";
|
import { changeWarehouseDialogMessages as messages } from "./messages";
|
||||||
import { useStyles } from "./styles";
|
import { useStyles } from "./styles";
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,10 @@ import {
|
||||||
OrderErrorFragment,
|
OrderErrorFragment,
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
import { FormChange } from "@saleor/hooks/useForm";
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
|
import { getById } from "@saleor/misc";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import { getById } from "../OrderReturnPage/utils";
|
|
||||||
import { AddressInputOptionEnum } from "./form";
|
import { AddressInputOptionEnum } from "./form";
|
||||||
import { addressEditMessages } from "./messages";
|
import { addressEditMessages } from "./messages";
|
||||||
import { useStyles } from "./styles";
|
import { useStyles } from "./styles";
|
||||||
|
|
|
@ -24,12 +24,11 @@ import { SubmitPromise } from "@saleor/hooks/useForm";
|
||||||
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
|
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
|
||||||
import { buttonMessages } from "@saleor/intl";
|
import { buttonMessages } from "@saleor/intl";
|
||||||
import { ConfirmButtonTransitionState, DialogHeader } from "@saleor/macaw-ui";
|
import { ConfirmButtonTransitionState, DialogHeader } from "@saleor/macaw-ui";
|
||||||
import { transformAddressToAddressInput } from "@saleor/misc";
|
import { getById, transformAddressToAddressInput } from "@saleor/misc";
|
||||||
import { mapCountriesToChoices } from "@saleor/utils/maps";
|
import { mapCountriesToChoices } from "@saleor/utils/maps";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, MessageDescriptor, useIntl } from "react-intl";
|
import { FormattedMessage, MessageDescriptor, useIntl } from "react-intl";
|
||||||
|
|
||||||
import { getById } from "../OrderReturnPage/utils";
|
|
||||||
import OrderCustomerAddressesEditForm, {
|
import OrderCustomerAddressesEditForm, {
|
||||||
AddressInputOptionEnum,
|
AddressInputOptionEnum,
|
||||||
OrderCustomerAddressesEditFormData,
|
OrderCustomerAddressesEditFormData,
|
||||||
|
|
|
@ -17,10 +17,10 @@ import {
|
||||||
ConfirmButtonTransitionState,
|
ConfirmButtonTransitionState,
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
} from "@saleor/macaw-ui";
|
} from "@saleor/macaw-ui";
|
||||||
|
import { getById } from "@saleor/misc";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import { getById } from "../OrderReturnPage/utils";
|
|
||||||
import { dialogMessages as messages } from "./messages";
|
import { dialogMessages as messages } from "./messages";
|
||||||
import { useStyles } from "./styles";
|
import { useStyles } from "./styles";
|
||||||
import { parseQuery, stringifyAddress } from "./utils";
|
import { parseQuery, stringifyAddress } from "./utils";
|
||||||
|
|
|
@ -8,9 +8,8 @@ import {
|
||||||
OrderErrorFragment,
|
OrderErrorFragment,
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
import { FormChange } from "@saleor/hooks/useForm";
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
import { flatten } from "@saleor/misc";
|
import { flatten, getById } from "@saleor/misc";
|
||||||
|
|
||||||
import { getById } from "../OrderReturnPage/utils";
|
|
||||||
import {
|
import {
|
||||||
OrderCustomerAddressesEditData,
|
OrderCustomerAddressesEditData,
|
||||||
OrderCustomerAddressesEditHandlers,
|
OrderCustomerAddressesEditHandlers,
|
||||||
|
|
|
@ -18,14 +18,13 @@ import {
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
import { FormsetChange } from "@saleor/hooks/useFormset";
|
import { FormsetChange } from "@saleor/hooks/useFormset";
|
||||||
import { makeStyles, ResponsiveTable } from "@saleor/macaw-ui";
|
import { makeStyles, ResponsiveTable } from "@saleor/macaw-ui";
|
||||||
import { renderCollection } from "@saleor/misc";
|
import { getById, renderCollection } from "@saleor/misc";
|
||||||
import React, { CSSProperties } from "react";
|
import React, { CSSProperties } from "react";
|
||||||
import { defineMessages, FormattedMessage, useIntl } from "react-intl";
|
import { defineMessages, FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import OrderCardTitle from "../../OrderCardTitle";
|
import OrderCardTitle from "../../OrderCardTitle";
|
||||||
import { FormsetQuantityData, FormsetReplacementData } from "../form";
|
import { FormsetQuantityData, FormsetReplacementData } from "../form";
|
||||||
import {
|
import {
|
||||||
getById,
|
|
||||||
getQuantityDataFromItems,
|
getQuantityDataFromItems,
|
||||||
getReplacementDataFromItems,
|
getReplacementDataFromItems,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
|
@ -9,11 +9,11 @@ import useFormset, {
|
||||||
FormsetData,
|
FormsetData,
|
||||||
} from "@saleor/hooks/useFormset";
|
} from "@saleor/hooks/useFormset";
|
||||||
import useHandleFormSubmit from "@saleor/hooks/useHandleFormSubmit";
|
import useHandleFormSubmit from "@saleor/hooks/useHandleFormSubmit";
|
||||||
|
import { getById } from "@saleor/misc";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
|
|
||||||
import { OrderRefundAmountCalculationMode } from "../OrderRefundPage/form";
|
import { OrderRefundAmountCalculationMode } from "../OrderRefundPage/form";
|
||||||
import {
|
import {
|
||||||
getById,
|
|
||||||
getLineItem,
|
getLineItem,
|
||||||
getOrderUnfulfilledLines,
|
getOrderUnfulfilledLines,
|
||||||
getParsedLineData,
|
getParsedLineData,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { FulfillmentStatus, OrderDetailsFragment } from "@saleor/graphql";
|
import { FulfillmentStatus, OrderDetailsFragment } from "@saleor/graphql";
|
||||||
|
import { getById } from "@saleor/misc";
|
||||||
import { Node } from "@saleor/types";
|
import { Node } from "@saleor/types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -100,13 +101,6 @@ export const getParsedLines = (
|
||||||
quantity,
|
quantity,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const getById = (idToCompare: string) => (obj: Node) =>
|
|
||||||
obj.id === idToCompare;
|
|
||||||
|
|
||||||
export const getByUnmatchingId = (idToCompare: string) => (obj: {
|
|
||||||
id: string;
|
|
||||||
}) => obj.id !== idToCompare;
|
|
||||||
|
|
||||||
const isIncludedInIds = function<T extends Node>(
|
const isIncludedInIds = function<T extends Node>(
|
||||||
arrayToCompare: string[] | T[],
|
arrayToCompare: string[] | T[],
|
||||||
obj: Node,
|
obj: Node,
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {
|
||||||
WarehouseFragment,
|
WarehouseFragment,
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
import { FormsetData } from "@saleor/hooks/useFormset";
|
import { FormsetData } from "@saleor/hooks/useFormset";
|
||||||
import { findInEnum } from "@saleor/misc";
|
import { findInEnum, getById } from "@saleor/misc";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
LineItemData,
|
LineItemData,
|
||||||
|
@ -23,7 +23,6 @@ import {
|
||||||
import {
|
import {
|
||||||
getAllOrderFulfilledLines,
|
getAllOrderFulfilledLines,
|
||||||
getAllOrderWaitingLines,
|
getAllOrderWaitingLines,
|
||||||
getById,
|
|
||||||
} from "../components/OrderReturnPage/utils";
|
} from "../components/OrderReturnPage/utils";
|
||||||
|
|
||||||
export type OrderWithTotalAndTotalCaptured = Pick<
|
export type OrderWithTotalAndTotalCaptured = Pick<
|
||||||
|
|
|
@ -11,12 +11,17 @@ import {
|
||||||
useWarehouseListQuery,
|
useWarehouseListQuery,
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
|
import {
|
||||||
|
extractMutationErrors,
|
||||||
|
getById,
|
||||||
|
getMutationState,
|
||||||
|
getStringOrPlaceholder,
|
||||||
|
} from "@saleor/misc";
|
||||||
import OrderCannotCancelOrderDialog from "@saleor/orders/components/OrderCannotCancelOrderDialog";
|
import OrderCannotCancelOrderDialog from "@saleor/orders/components/OrderCannotCancelOrderDialog";
|
||||||
import { OrderCustomerAddressesEditDialogOutput } from "@saleor/orders/components/OrderCustomerAddressesEditDialog/types";
|
import { OrderCustomerAddressesEditDialogOutput } from "@saleor/orders/components/OrderCustomerAddressesEditDialog/types";
|
||||||
import OrderFulfillmentApproveDialog from "@saleor/orders/components/OrderFulfillmentApproveDialog";
|
import OrderFulfillmentApproveDialog from "@saleor/orders/components/OrderFulfillmentApproveDialog";
|
||||||
import OrderFulfillStockExceededDialog from "@saleor/orders/components/OrderFulfillStockExceededDialog";
|
import OrderFulfillStockExceededDialog from "@saleor/orders/components/OrderFulfillStockExceededDialog";
|
||||||
import OrderInvoiceEmailSendDialog from "@saleor/orders/components/OrderInvoiceEmailSendDialog";
|
import OrderInvoiceEmailSendDialog from "@saleor/orders/components/OrderInvoiceEmailSendDialog";
|
||||||
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
|
|
||||||
import { transformFuflillmentLinesToStockFormsetData } from "@saleor/orders/utils/data";
|
import { transformFuflillmentLinesToStockFormsetData } from "@saleor/orders/utils/data";
|
||||||
import { PartialMutationProviderOutput } from "@saleor/types";
|
import { PartialMutationProviderOutput } from "@saleor/types";
|
||||||
import { mapEdgesToItems } from "@saleor/utils/maps";
|
import { mapEdgesToItems } from "@saleor/utils/maps";
|
||||||
|
@ -24,11 +29,6 @@ import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import { customerUrl } from "../../../../customers/urls";
|
import { customerUrl } from "../../../../customers/urls";
|
||||||
import {
|
|
||||||
extractMutationErrors,
|
|
||||||
getMutationState,
|
|
||||||
getStringOrPlaceholder,
|
|
||||||
} from "../../../../misc";
|
|
||||||
import { productUrl } from "../../../../products/urls";
|
import { productUrl } from "../../../../products/urls";
|
||||||
import OrderAddressFields from "../../../components/OrderAddressFields/OrderAddressFields";
|
import OrderAddressFields from "../../../components/OrderAddressFields/OrderAddressFields";
|
||||||
import OrderCancelDialog from "../../../components/OrderCancelDialog";
|
import OrderCancelDialog from "../../../components/OrderCancelDialog";
|
||||||
|
|
|
@ -4,12 +4,12 @@ import {
|
||||||
OrderReturnLineInput,
|
OrderReturnLineInput,
|
||||||
OrderReturnProductsInput,
|
OrderReturnProductsInput,
|
||||||
} from "@saleor/graphql";
|
} from "@saleor/graphql";
|
||||||
|
import { getById } from "@saleor/misc";
|
||||||
import { OrderRefundAmountCalculationMode } from "@saleor/orders/components/OrderRefundPage/form";
|
import { OrderRefundAmountCalculationMode } from "@saleor/orders/components/OrderRefundPage/form";
|
||||||
import {
|
import {
|
||||||
FormsetQuantityData,
|
FormsetQuantityData,
|
||||||
OrderReturnFormData,
|
OrderReturnFormData,
|
||||||
} from "@saleor/orders/components/OrderReturnPage/form";
|
} from "@saleor/orders/components/OrderReturnPage/form";
|
||||||
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
|
|
||||||
|
|
||||||
class ReturnFormDataParser {
|
class ReturnFormDataParser {
|
||||||
private order: OrderDetailsFragment;
|
private order: OrderDetailsFragment;
|
||||||
|
|
|
@ -6,8 +6,8 @@ import {
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import { getDefaultNotifierSuccessErrorData } from "@saleor/hooks/useNotifier/utils";
|
import { getDefaultNotifierSuccessErrorData } from "@saleor/hooks/useNotifier/utils";
|
||||||
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||||
|
import { getById } from "@saleor/misc";
|
||||||
import { OrderDiscountCommonInput } from "@saleor/orders/components/OrderDiscountCommonModal/types";
|
import { OrderDiscountCommonInput } from "@saleor/orders/components/OrderDiscountCommonModal/types";
|
||||||
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
|
|
||||||
import React, { createContext, useState } from "react";
|
import React, { createContext, useState } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue