Add webhook delete

This commit is contained in:
Krzysztof Bialoglowicz 2019-10-10 07:38:21 +02:00
parent 2fd01ec3c5
commit 834addf3c0
14 changed files with 358 additions and 131 deletions

View file

@ -12,14 +12,13 @@ import { UserError } from "@saleor/types";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { ServiceList_serviceAccounts_edges_node } from "../../types/ServiceList"; import { ServiceList_serviceAccounts_edges_node } from "../../types/ServiceList";
import { Webhook_webhook, Webhook_webhook_events } from "../../types/Webhook";
import WebhookEvents from "../WebhookEvents"; import WebhookEvents from "../WebhookEvents";
import WebhookInfo from "../WebhookInfo"; import WebhookInfo from "../WebhookInfo";
import WebhookStatus from "../WebhookStatus"; import WebhookStatus from "../WebhookStatus";
export interface FormData { export interface FormData {
id: string; id: string;
events: Webhook_webhook_events[]; events: string[];
isActive: boolean; isActive: boolean;
name: string; name: string;
secretKey: string | null; secretKey: string | null;
@ -30,7 +29,6 @@ export interface FormData {
export interface WebhookCreatePageProps { export interface WebhookCreatePageProps {
disabled: boolean; disabled: boolean;
errors: UserError[]; errors: UserError[];
webhook: Webhook_webhook;
services: ServiceList_serviceAccounts_edges_node[]; services: ServiceList_serviceAccounts_edges_node[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
onBack: () => void; onBack: () => void;
@ -40,7 +38,6 @@ export interface WebhookCreatePageProps {
const WebhookCreatePage: React.StatelessComponent<WebhookCreatePageProps> = ({ const WebhookCreatePage: React.StatelessComponent<WebhookCreatePageProps> = ({
disabled, disabled,
errors, errors,
webhook,
saveButtonBarState, saveButtonBarState,
services, services,
onBack, onBack,
@ -48,13 +45,13 @@ const WebhookCreatePage: React.StatelessComponent<WebhookCreatePageProps> = ({
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const initialForm: FormData = { const initialForm: FormData = {
events: maybe(() => webhook.events, []), events: [],
id: maybe(() => webhook.id, null), id: null,
isActive: maybe(() => webhook.isActive, false), isActive: false,
name: maybe(() => webhook.name, null), name: null,
secretKey: maybe(() => webhook.secretKey, ""), secretKey: "",
serviceAccount: maybe(() => webhook.serviceAccount, ""), serviceAccount: "",
targetUrl: maybe(() => webhook.targetUrl, "") targetUrl: ""
}; };
return ( return (
@ -66,15 +63,10 @@ const WebhookCreatePage: React.StatelessComponent<WebhookCreatePageProps> = ({
{intl.formatMessage(sectionNames.plugins)} {intl.formatMessage(sectionNames.plugins)}
</AppHeader> </AppHeader>
<PageHeader <PageHeader
title={intl.formatMessage( title={intl.formatMessage({
{
defaultMessage: "Create Webhook", defaultMessage: "Create Webhook",
description: "header" description: "header"
}, })}
{
pluginName: maybe(() => webhook.name, "...")
}
)}
/> />
<Grid> <Grid>
<div> <div>

View file

@ -0,0 +1,19 @@
import { storiesOf } from "@storybook/react";
import React from "react";
import Decorator from "@saleor/storybook/Decorator";
import WebhookDeleteDialog, {
WebhookDeleteDialogProps
} from "./WebhookDeleteDialog";
const props: WebhookDeleteDialogProps = {
confirmButtonState: "default",
name: "Magento Importer",
onClose: () => undefined,
onConfirm: () => undefined,
open: true
};
storiesOf("Views / Services / Delete service", module)
.addDecorator(Decorator)
.add("default", () => <WebhookDeleteDialog {...props} />);

View file

@ -0,0 +1,50 @@
import DialogContentText from "@material-ui/core/DialogContentText";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import ActionDialog from "@saleor/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
export interface WebhookDeleteDialogProps {
confirmButtonState: ConfirmButtonTransitionState;
open: boolean;
name: string;
onClose: () => void;
onConfirm: () => void;
}
const WebhookDeleteDialog: React.FC<WebhookDeleteDialogProps> = ({
confirmButtonState,
open,
name,
onClose,
onConfirm
}) => {
const intl = useIntl();
return (
<ActionDialog
confirmButtonState={confirmButtonState}
open={open}
onClose={onClose}
onConfirm={onConfirm}
title={intl.formatMessage({
defaultMessage: "Delete Webhook",
description: "dialog header"
})}
variant="delete"
>
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to delete {name}?"
description="delete webhook"
values={{
name: <strong>{name}</strong>
}}
/>
</DialogContentText>
</ActionDialog>
);
};
WebhookDeleteDialog.displayName = "WebhookDeleteDialog";
export default WebhookDeleteDialog;

View file

@ -0,0 +1,2 @@
export { default } from "./WebhookDeleteDialog";
export * from "./WebhookDeleteDialog";

View file

@ -28,7 +28,7 @@ const WebhookEvents: React.StatelessComponent<WebhookEventsProps> = ({
onChange onChange
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const [events, setEvents] = React.useState(); const [events, setEvents] = React.useState(data.events);
const eventsEnum = Object.values(WebhookEventTypeEnum); const eventsEnum = Object.values(WebhookEventTypeEnum);
@ -42,10 +42,13 @@ const WebhookEvents: React.StatelessComponent<WebhookEventsProps> = ({
} }
}; };
console.log(data.events);
const eventsOnChange = event => { const eventsOnChange = event => {
const newData = [events]; const newData = events;
addOrRemove(newData, event.name); addOrRemove(newData, event.target.name);
setEvents(newData); setEvents(newData);
console.log(events.indexOf(event.target.name));
}; };
return ( return (
@ -69,7 +72,7 @@ const WebhookEvents: React.StatelessComponent<WebhookEventsProps> = ({
<ControlledCheckbox <ControlledCheckbox
name={event} name={event}
label={event} label={event}
checked={data.events[event]} checked={events.includes(WebhookEventTypeEnum[event])}
onChange={eventsOnChange} onChange={eventsOnChange}
disabled={disabled} disabled={disabled}
/> />

View file

@ -3,7 +3,6 @@ import CardContent from "@material-ui/core/CardContent";
import Typography from "@material-ui/core/Typography"; import Typography from "@material-ui/core/Typography";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import ControlledCheckbox from "@saleor/components/ControlledCheckbox"; import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
import { FormErrors } from "@saleor/types";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";

View file

@ -13,14 +13,14 @@ import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { ServiceList_serviceAccounts_edges_node } from "../../types/ServiceList"; import { ServiceList_serviceAccounts_edges_node } from "../../types/ServiceList";
import { Webhook_webhook, Webhook_webhook_events } from "../../types/Webhook"; import { Webhook_webhook } from "../../types/Webhook";
import WebhookEvents from "../WebhookEvents"; import WebhookEvents from "../WebhookEvents";
import WebhookInfo from "../WebhookInfo"; import WebhookInfo from "../WebhookInfo";
import WebhookStatus from "../WebhookStatus"; import WebhookStatus from "../WebhookStatus";
export interface FormData { export interface FormData {
id: string; id: string;
events: Webhook_webhook_events[]; events: string[];
isActive: boolean; isActive: boolean;
name: string; name: string;
secretKey: string | null; secretKey: string | null;
@ -35,6 +35,7 @@ export interface WebhooksDetailsPageProps {
services: ServiceList_serviceAccounts_edges_node[]; services: ServiceList_serviceAccounts_edges_node[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
onBack: () => void; onBack: () => void;
onDelete: () => void;
onSubmit: (data: FormData) => void; onSubmit: (data: FormData) => void;
} }
@ -47,11 +48,12 @@ const WebhooksDetailsPage: React.StatelessComponent<
saveButtonBarState, saveButtonBarState,
services, services,
onBack, onBack,
onDelete,
onSubmit onSubmit
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const initialForm: FormData = { const initialForm: FormData = {
events: maybe(() => webhook.events, []), events: maybe(() => webhook.events, []).map(event => event.eventType),
id: maybe(() => webhook.id, null), id: maybe(() => webhook.id, null),
isActive: maybe(() => webhook.isActive, false), isActive: maybe(() => webhook.isActive, false),
name: maybe(() => webhook.name, ""), name: maybe(() => webhook.name, ""),
@ -107,6 +109,7 @@ const WebhooksDetailsPage: React.StatelessComponent<
state={saveButtonBarState} state={saveButtonBarState}
onCancel={onBack} onCancel={onBack}
onSave={submit} onSave={submit}
onDelete={onDelete}
/> />
</Container> </Container>
); );

View file

@ -1,4 +1,5 @@
import Card from "@material-ui/core/Card"; import Card from "@material-ui/core/Card";
import IconButton from "@material-ui/core/IconButton";
import { import {
createStyles, createStyles,
Theme, Theme,
@ -12,6 +13,7 @@ import TableFooter from "@material-ui/core/TableFooter";
import TableHead from "@material-ui/core/TableHead"; import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow"; import TableRow from "@material-ui/core/TableRow";
import EditIcon from "@material-ui/icons/Edit"; import EditIcon from "@material-ui/icons/Edit";
import DeleteIcon from "@material-ui/icons/Delete";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
@ -23,6 +25,7 @@ import { Webhooks_webhooks_edges_node } from "../../types/Webhooks";
export interface WebhooksListProps extends ListProps { export interface WebhooksListProps extends ListProps {
webhooks: Webhooks_webhooks_edges_node[]; webhooks: Webhooks_webhooks_edges_node[];
onRemove: (id: string) => void;
} }
const styles = (theme: Theme) => const styles = (theme: Theme) =>
@ -56,6 +59,7 @@ const WebhooksList = withStyles(styles, { name: "PluginList" })(
onNextPage, onNextPage,
pageInfo, pageInfo,
onRowClick, onRowClick,
onRemove,
onUpdateListSettings, onUpdateListSettings,
onPreviousPage onPreviousPage
}: WebhooksListProps & WithStyles<typeof styles>) => { }: WebhooksListProps & WithStyles<typeof styles>) => {
@ -126,6 +130,14 @@ const WebhooksList = withStyles(styles, { name: "PluginList" })(
> >
<EditIcon /> <EditIcon />
</div> </div>
<IconButton
color="primary"
onClick={
webhook ? () => onRemove(webhook.id) : undefined
}
>
<DeleteIcon />
</IconButton>
</TableCell> </TableCell>
</TableRow> </TableRow>
); );

View file

@ -13,6 +13,7 @@ import WebhooksList from "../WebhooksList/WebhooksList";
export interface WebhooksListPageProps extends PageListProps { export interface WebhooksListPageProps extends PageListProps {
webhooks: Webhooks_webhooks_edges_node[]; webhooks: Webhooks_webhooks_edges_node[];
onBack: () => void; onBack: () => void;
onRemove: () => void;
} }
const WebhooksListPage: React.StatelessComponent<WebhooksListPageProps> = ({ const WebhooksListPage: React.StatelessComponent<WebhooksListPageProps> = ({
@ -23,6 +24,7 @@ const WebhooksListPage: React.StatelessComponent<WebhooksListPageProps> = ({
onNextPage, onNextPage,
onPreviousPage, onPreviousPage,
onRowClick, onRowClick,
onRemove,
onUpdateListSettings, onUpdateListSettings,
pageInfo, pageInfo,
webhooks webhooks
@ -47,6 +49,7 @@ const WebhooksListPage: React.StatelessComponent<WebhooksListPageProps> = ({
webhooks={webhooks} webhooks={webhooks}
onNextPage={onNextPage} onNextPage={onNextPage}
onPreviousPage={onPreviousPage} onPreviousPage={onPreviousPage}
onRemove={onRemove}
onUpdateListSettings={onUpdateListSettings} onUpdateListSettings={onUpdateListSettings}
onRowClick={onRowClick} onRowClick={onRowClick}
pageInfo={pageInfo} pageInfo={pageInfo}

View file

@ -57,4 +57,4 @@ const webhookDelete = gql`
export const TypedWebhookDelete = TypedMutation< export const TypedWebhookDelete = TypedMutation<
WebhookDelete, WebhookDelete,
WebhookDeleteVariables WebhookDeleteVariables
>(WebhookDelete); >(webhookDelete);

View file

@ -1,17 +1,21 @@
import { stringify as stringifyQs } from "qs"; import { stringify as stringifyQs } from "qs";
import urlJoin from "url-join"; import urlJoin from "url-join";
import { Pagination, SingleAction } from "../types"; import { Dialog, Pagination, SingleAction } from "../types";
export const webhooksSection = "/webhooks/"; export const webhooksSection = "/webhooks/";
export const webhooksListPath = webhooksSection; export const webhooksListPath = webhooksSection;
export type WebhooksListUrlQueryParams = Pagination & SingleAction; export type WebhookListUrlDialog = "remove";
export type WebhooksListUrlQueryParams = Dialog<WebhookListUrlDialog> &
Pagination &
SingleAction;
export const webhooksListUrl = (params?: WebhooksListUrlQueryParams) => export const webhooksListUrl = (params?: WebhooksListUrlQueryParams) =>
webhooksListPath + "?" + stringifyQs(params); webhooksListPath + "?" + stringifyQs(params);
export const webhooksPath = (id: string) => urlJoin(webhooksSection, id); export const webhooksPath = (id: string) => urlJoin(webhooksSection, id);
export type WebhooksUrlQueryParams = SingleAction; export type WebhookUrlDialog = "remove";
export type WebhooksUrlQueryParams = Dialog<WebhookUrlDialog> & SingleAction;
export const webhooksUrl = (id: string, params?: WebhooksUrlQueryParams) => export const webhooksUrl = (id: string, params?: WebhooksUrlQueryParams) =>
webhooksPath(encodeURIComponent(id)) + "?" + stringifyQs(params); webhooksPath(encodeURIComponent(id)) + "?" + stringifyQs(params);

View file

@ -1,9 +1,9 @@
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { WebhookCreate as WebhookCreateData } from "@saleor/webhooks/types/WebhookCreate"; import { WebhookCreate as WebhookCreateData } from "@saleor/webhooks/types/WebhookCreate";
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
@ -28,7 +28,6 @@ export const WebhooksCreate: React.StatelessComponent<
const navigate = useNavigator(); const navigate = useNavigator();
const notify = useNotifier(); const notify = useNotifier();
const intl = useIntl(); const intl = useIntl();
const shop = useShop();
const onSubmit = (data: WebhookCreateData) => { const onSubmit = (data: WebhookCreateData) => {
if (data.webhookCreate.errors.length === 0) { if (data.webhookCreate.errors.length === 0) {
@ -48,7 +47,7 @@ export const WebhooksCreate: React.StatelessComponent<
WebhookCreate({ WebhookCreate({
variables: { variables: {
input: { input: {
events: data.events, events: [WebhookEventTypeEnum.ALL_EVENTS],
isActive: data.isActive, isActive: data.isActive,
name: data.name, name: data.name,
secretKey: data.secretKey, secretKey: data.secretKey,
@ -66,7 +65,7 @@ export const WebhooksCreate: React.StatelessComponent<
return ( return (
<TypedServiceListQuery displayLoader variables={{ first: 99 }}> <TypedServiceListQuery displayLoader variables={{ first: 99 }}>
{({ data, loading }) => { {({ data }) => {
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -84,10 +83,8 @@ export const WebhooksCreate: React.StatelessComponent<
services={maybe(() => services={maybe(() =>
data.serviceAccounts.edges.map(edge => edge.node) data.serviceAccounts.edges.map(edge => edge.node)
)} )}
loading={loading}
onBack={handleBack} onBack={handleBack}
onSubmit={handleSubmit} onSubmit={handleSubmit}
permissions={maybe(() => shop.permissions)}
saveButtonBarState={formTransitionState} saveButtonBarState={formTransitionState}
/> />
</> </>

View file

@ -1,14 +1,22 @@
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl";
import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog";
import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { getMutationState, maybe } from "../../misc"; import { getMutationState, maybe } from "../../misc";
import WebhooksDetailsPage from "../components/WebhooksDetailsPage"; import WebhooksDetailsPage from "../components/WebhooksDetailsPage";
import { TypedWebhookUpdate } from "../mutations"; import { TypedWebhookDelete, TypedWebhookUpdate } from "../mutations";
import { TypedServiceListQuery, TypedWebhooksDetailsQuery } from "../queries"; import { TypedServiceListQuery, TypedWebhooksDetailsQuery } from "../queries";
import { webhooksListUrl, WebhooksListUrlQueryParams } from "../urls"; import {
webhooksListUrl,
WebhooksListUrlQueryParams,
webhooksUrl,
WebhookUrlDialog
} from "../urls";
export interface WebhooksDetailsProps { export interface WebhooksDetailsProps {
id: string; id: string;
@ -17,14 +25,44 @@ export interface WebhooksDetailsProps {
export const WebhooksDetails: React.StatelessComponent< export const WebhooksDetails: React.StatelessComponent<
WebhooksDetailsProps WebhooksDetailsProps
> = ({ id }) => { > = ({ id, params }) => {
const navigate = useNavigator(); const navigate = useNavigator();
const notify = useNotifier(); const notify = useNotifier();
const intl = useIntl(); const intl = useIntl();
const closeModal = () =>
navigate(
webhooksUrl(id, {
...params,
action: undefined,
id: undefined
}),
true
);
const openModal = (action: WebhookUrlDialog, tokenId?: string) =>
navigate(
webhooksUrl(id, {
...params,
action,
id: tokenId
})
);
const onWebhookDelete = (data: WebhookDelete) => {
if (data.webhookDelete.errors.length === 0) {
notify({
text: intl.formatMessage(commonMessages.savedChanges)
});
navigate(webhooksListUrl());
}
};
return ( return (
<TypedWebhookUpdate> <TypedWebhookUpdate>
{(webhookUpdate, webhookUpdateOpts) => ( {(webhookUpdate, webhookUpdateOpts) => (
<TypedWebhookDelete onCompleted={onWebhookDelete}>
{(webhookDelete, webhookDeleteOpts) => (
<TypedWebhooksDetailsQuery variables={{ id }}> <TypedWebhooksDetailsQuery variables={{ id }}>
{WebhookDetails => { {WebhookDetails => {
const formTransitionState = getMutationState( const formTransitionState = getMutationState(
@ -33,6 +71,13 @@ export const WebhooksDetails: React.StatelessComponent<
maybe(() => webhookUpdateOpts.data.webhookUpdate.errors) maybe(() => webhookUpdateOpts.data.webhookUpdate.errors)
); );
const handleRemoveConfirm = () =>
webhookDelete({
variables: {
id
}
});
const formErrors = maybe( const formErrors = maybe(
() => webhookUpdateOpts.data.webhookUpdate.errors, () => webhookUpdateOpts.data.webhookUpdate.errors,
[] []
@ -55,6 +100,12 @@ export const WebhooksDetails: React.StatelessComponent<
} }
} }
const deleteTransitionState = getMutationState(
webhookDeleteOpts.called,
webhookDeleteOpts.loading,
maybe(() => webhookDeleteOpts.data.webhookDelete.errors)
);
return ( return (
<TypedServiceListQuery variables={{ first: 99 }}> <TypedServiceListQuery variables={{ first: 99 }}>
{({ data }) => ( {({ data }) => (
@ -71,6 +122,7 @@ export const WebhooksDetails: React.StatelessComponent<
data.serviceAccounts.edges.map(edge => edge.node) data.serviceAccounts.edges.map(edge => edge.node)
)} )}
onBack={() => navigate(webhooksListUrl())} onBack={() => navigate(webhooksListUrl())}
onDelete={() => openModal("remove")}
onSubmit={data => { onSubmit={data => {
webhookUpdate({ webhookUpdate({
variables: { variables: {
@ -87,6 +139,16 @@ export const WebhooksDetails: React.StatelessComponent<
}); });
}} }}
/> />
<WebhookDeleteDialog
confirmButtonState={deleteTransitionState}
name={maybe(
() => WebhookDetails.data.webhook.name,
"..."
)}
onClose={closeModal}
onConfirm={handleRemoveConfirm}
open={params.action === "remove"}
/>
</> </>
)} )}
</TypedServiceListQuery> </TypedServiceListQuery>
@ -94,6 +156,8 @@ export const WebhooksDetails: React.StatelessComponent<
}} }}
</TypedWebhooksDetailsQuery> </TypedWebhooksDetailsQuery>
)} )}
</TypedWebhookDelete>
)}
</TypedWebhookUpdate> </TypedWebhookUpdate>
); );
}; };

View file

@ -1,19 +1,27 @@
import { configurationMenuUrl } from "@saleor/configuration"; import { configurationMenuUrl } from "@saleor/configuration";
import useListSettings from "@saleor/hooks/useListSettings"; import useListSettings from "@saleor/hooks/useListSettings";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import usePaginator, { import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { maybe } from "@saleor/misc"; import { commonMessages } from "@saleor/intl";
import { getMutationState, maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog";
import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete";
import React from "react"; import React from "react";
import { useIntl } from "react-intl";
import WebhooksListPage from "../components/WebhooksListPage/WebhooksListPage"; import WebhooksListPage from "../components/WebhooksListPage/WebhooksListPage";
import { TypedWebhookDelete } from "../mutations";
import { TypedWebhooksListQuery } from "../queries"; import { TypedWebhooksListQuery } from "../queries";
import { import {
webhooksAddUrl, webhooksAddUrl,
webhooksListUrl,
WebhooksListUrlQueryParams, WebhooksListUrlQueryParams,
webhooksUrl webhooksUrl,
WebhookUrlDialog
} from "../urls"; } from "../urls";
interface WebhooksListProps { interface WebhooksListProps {
@ -25,36 +33,107 @@ export const WebhooksList: React.StatelessComponent<WebhooksListProps> = ({
}) => { }) => {
const navigate = useNavigator(); const navigate = useNavigator();
const paginate = usePaginator(); const paginate = usePaginator();
const notify = useNotifier();
const intl = useIntl();
const { updateListSettings, settings } = useListSettings( const { updateListSettings, settings } = useListSettings(
ListViews.WEBHOOK_LIST ListViews.WEBHOOK_LIST
); );
const paginationState = createPaginationState(settings.rowNumber, params); const paginationState = createPaginationState(settings.rowNumber, params);
const closeModal = () =>
navigate(
webhooksListUrl({
...params,
action: undefined,
id: undefined
}),
true
);
const openModal = (action: WebhookUrlDialog, id?: string) =>
navigate(
webhooksListUrl({
...params,
action,
id
})
);
const onWebhookDelete = (data: WebhookDelete) => {
if (data.webhookDelete.errors.length === 0) {
notify({
text: intl.formatMessage(commonMessages.savedChanges)
});
navigate(webhooksListUrl());
}
};
return ( return (
<TypedWebhooksListQuery displayLoader variables={paginationState}> <TypedWebhooksListQuery displayLoader variables={paginationState}>
{({ data, loading }) => { {({ data, loading }) => (
<TypedWebhookDelete onCompleted={onWebhookDelete}>
{(webhookDelete, webhookDeleteOpts) => {
const { loadNextPage, loadPreviousPage, pageInfo } = paginate( const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
maybe(() => data.webhooks.pageInfo), maybe(() => data.webhooks.pageInfo),
paginationState, paginationState,
params params
); );
const handleRemove = (id: string) =>
navigate(
webhooksListUrl({
...params,
action: "remove",
id
})
);
const handleRemoveConfirm = () =>
webhookDelete({
variables: {
id
}
});
const deleteTransitionState = getMutationState(
webhookDeleteOpts.called,
webhookDeleteOpts.loading,
maybe(() => webhookDeleteOpts.data.webhookDelete.errors)
);
return ( return (
<> <>
<WebhooksListPage <WebhooksListPage
disabled={loading} disabled={loading}
settings={settings} settings={settings}
webhooks={maybe(() => data.webhooks.edges.map(edge => edge.node))} webhooks={maybe(() =>
data.webhooks.edges.map(edge => edge.node)
)}
pageInfo={pageInfo} pageInfo={pageInfo}
onAdd={() => navigate(webhooksAddUrl)} onAdd={() => navigate(webhooksAddUrl)}
onBack={() => navigate(configurationMenuUrl)} onBack={() => navigate(configurationMenuUrl)}
onNextPage={loadNextPage} onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage} onPreviousPage={loadPreviousPage}
onRemove={handleRemove}
onUpdateListSettings={updateListSettings} onUpdateListSettings={updateListSettings}
onRowClick={id => () => navigate(webhooksUrl(id))} onRowClick={id => () => navigate(webhooksUrl(id))}
/> />
<WebhookDeleteDialog
confirmButtonState={deleteTransitionState}
name={maybe(
() =>
data.webhooks.edges.find(
edge => edge.node.id === params.id
).node.name,
"..."
)}
onClose={closeModal}
onConfirm={handleRemoveConfirm}
open={params.action === "remove"}
/>
</> </>
); );
}} }}
</TypedWebhookDelete>
)}
</TypedWebhooksListQuery> </TypedWebhooksListQuery>
); );
}; };