2022-07-16 09:54:50 +00:00
|
|
|
import React, { useEffect, useState } from 'react';
|
2022-07-14 18:11:44 +00:00
|
|
|
import {
|
|
|
|
Button,
|
|
|
|
Center,
|
2022-08-01 19:26:21 +00:00
|
|
|
Code,
|
|
|
|
Collapse,
|
2022-07-14 18:11:44 +00:00
|
|
|
Flex,
|
|
|
|
Input,
|
|
|
|
InputGroup,
|
|
|
|
InputRightElement,
|
2022-07-16 09:54:50 +00:00
|
|
|
MenuItem,
|
2022-07-14 18:11:44 +00:00
|
|
|
Modal,
|
|
|
|
ModalBody,
|
|
|
|
ModalCloseButton,
|
|
|
|
ModalContent,
|
|
|
|
ModalFooter,
|
|
|
|
ModalHeader,
|
|
|
|
ModalOverlay,
|
2022-07-17 09:12:46 +00:00
|
|
|
Select,
|
2022-07-14 18:11:44 +00:00
|
|
|
Switch,
|
|
|
|
Text,
|
|
|
|
useDisclosure,
|
|
|
|
useToast,
|
|
|
|
} from '@chakra-ui/react';
|
2022-08-01 19:26:21 +00:00
|
|
|
import {
|
|
|
|
FaAngleDown,
|
|
|
|
FaAngleUp,
|
|
|
|
FaMinusCircle,
|
|
|
|
FaPlus,
|
|
|
|
FaRegClone,
|
|
|
|
} from 'react-icons/fa';
|
2022-07-14 18:11:44 +00:00
|
|
|
import { useClient } from 'urql';
|
2022-07-15 16:42:08 +00:00
|
|
|
import {
|
2022-07-17 09:12:46 +00:00
|
|
|
webhookEventNames,
|
2022-07-15 16:42:08 +00:00
|
|
|
ArrayInputOperations,
|
|
|
|
WebhookInputDataFields,
|
|
|
|
WebhookInputHeaderFields,
|
2022-07-30 10:35:35 +00:00
|
|
|
UpdateModalViews,
|
2022-07-17 10:33:07 +00:00
|
|
|
webhookVerifiedStatus,
|
2022-08-01 19:26:21 +00:00
|
|
|
webhookPayloadExample,
|
2022-07-15 16:42:08 +00:00
|
|
|
} from '../constants';
|
2022-08-01 19:26:21 +00:00
|
|
|
import {
|
|
|
|
capitalizeFirstLetter,
|
|
|
|
copyTextToClipboard,
|
|
|
|
validateURI,
|
|
|
|
} from '../utils';
|
2022-07-17 11:20:58 +00:00
|
|
|
import { AddWebhook, EditWebhook, TestEndpoint } from '../graphql/mutation';
|
2022-07-17 10:33:07 +00:00
|
|
|
import { BiCheckCircle, BiError, BiErrorCircle } from 'react-icons/bi';
|
2022-07-14 18:11:44 +00:00
|
|
|
|
|
|
|
interface headersDataType {
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputHeaderFields.KEY]: string;
|
|
|
|
[WebhookInputHeaderFields.VALUE]: string;
|
2022-07-14 18:11:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
interface headersValidatorDataType {
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputHeaderFields.KEY]: boolean;
|
|
|
|
[WebhookInputHeaderFields.VALUE]: boolean;
|
2022-07-14 18:11:44 +00:00
|
|
|
}
|
|
|
|
|
2022-07-16 09:54:50 +00:00
|
|
|
interface selecetdWebhookDataTypes {
|
|
|
|
[WebhookInputDataFields.ID]: string;
|
|
|
|
[WebhookInputDataFields.EVENT_NAME]: string;
|
|
|
|
[WebhookInputDataFields.ENDPOINT]: string;
|
|
|
|
[WebhookInputDataFields.ENABLED]: boolean;
|
|
|
|
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface UpdateWebhookModalInputPropTypes {
|
2022-07-30 10:35:35 +00:00
|
|
|
view: UpdateModalViews;
|
2022-07-16 09:54:50 +00:00
|
|
|
selectedWebhook?: selecetdWebhookDataTypes;
|
|
|
|
fetchWebookData: Function;
|
|
|
|
}
|
|
|
|
|
2022-07-14 18:11:44 +00:00
|
|
|
const initHeadersData: headersDataType = {
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputHeaderFields.KEY]: '',
|
|
|
|
[WebhookInputHeaderFields.VALUE]: '',
|
2022-07-14 18:11:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const initHeadersValidatorData: headersValidatorDataType = {
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputHeaderFields.KEY]: true,
|
|
|
|
[WebhookInputHeaderFields.VALUE]: true,
|
2022-07-14 18:11:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
interface webhookDataType {
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.EVENT_NAME]: string;
|
|
|
|
[WebhookInputDataFields.ENDPOINT]: string;
|
|
|
|
[WebhookInputDataFields.ENABLED]: boolean;
|
|
|
|
[WebhookInputDataFields.HEADERS]: headersDataType[];
|
2022-07-14 18:11:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
interface validatorDataType {
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.ENDPOINT]: boolean;
|
|
|
|
[WebhookInputDataFields.HEADERS]: headersValidatorDataType[];
|
2022-07-14 18:11:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const initWebhookData: webhookDataType = {
|
2022-07-17 09:12:46 +00:00
|
|
|
[WebhookInputDataFields.EVENT_NAME]: webhookEventNames.USER_LOGIN,
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.ENDPOINT]: '',
|
2022-07-17 11:48:45 +00:00
|
|
|
[WebhookInputDataFields.ENABLED]: true,
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.HEADERS]: [{ ...initHeadersData }],
|
2022-07-14 18:11:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const initWebhookValidatorData: validatorDataType = {
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.ENDPOINT]: true,
|
|
|
|
[WebhookInputDataFields.HEADERS]: [{ ...initHeadersValidatorData }],
|
2022-07-14 18:11:44 +00:00
|
|
|
};
|
|
|
|
|
2022-07-16 09:54:50 +00:00
|
|
|
const UpdateWebhookModal = ({
|
|
|
|
view,
|
|
|
|
selectedWebhook,
|
|
|
|
fetchWebookData,
|
|
|
|
}: UpdateWebhookModalInputPropTypes) => {
|
2022-07-14 18:11:44 +00:00
|
|
|
const client = useClient();
|
|
|
|
const toast = useToast();
|
|
|
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
|
|
|
const [loading, setLoading] = useState<boolean>(false);
|
2022-07-17 10:33:07 +00:00
|
|
|
const [verifyingEndpoint, setVerifyingEndpoint] = useState<boolean>(false);
|
2022-08-01 19:26:21 +00:00
|
|
|
const [isShowingPayload, setIsShowingPayload] = useState<boolean>(false);
|
2022-07-14 18:11:44 +00:00
|
|
|
const [webhook, setWebhook] = useState<webhookDataType>({
|
|
|
|
...initWebhookData,
|
|
|
|
});
|
|
|
|
const [validator, setValidator] = useState<validatorDataType>({
|
|
|
|
...initWebhookValidatorData,
|
|
|
|
});
|
2022-07-17 10:33:07 +00:00
|
|
|
const [verifiedStatus, setVerifiedStatus] = useState<webhookVerifiedStatus>(
|
|
|
|
webhookVerifiedStatus.PENDING
|
|
|
|
);
|
2022-07-14 18:11:44 +00:00
|
|
|
const inputChangehandler = (
|
|
|
|
inputType: string,
|
|
|
|
value: any,
|
2022-07-15 16:42:08 +00:00
|
|
|
headerInputType: string = WebhookInputHeaderFields.KEY,
|
2022-07-14 18:11:44 +00:00
|
|
|
headerIndex: number = 0
|
|
|
|
) => {
|
2022-07-17 11:20:58 +00:00
|
|
|
if (
|
|
|
|
verifiedStatus !== webhookVerifiedStatus.PENDING &&
|
|
|
|
inputType !== WebhookInputDataFields.ENABLED
|
|
|
|
) {
|
|
|
|
setVerifiedStatus(webhookVerifiedStatus.PENDING);
|
|
|
|
}
|
2022-07-14 18:11:44 +00:00
|
|
|
switch (inputType) {
|
2022-07-15 16:42:08 +00:00
|
|
|
case WebhookInputDataFields.EVENT_NAME:
|
2022-07-14 18:11:44 +00:00
|
|
|
setWebhook({ ...webhook, [inputType]: value });
|
|
|
|
break;
|
2022-07-15 16:42:08 +00:00
|
|
|
case WebhookInputDataFields.ENDPOINT:
|
2022-07-14 18:11:44 +00:00
|
|
|
setWebhook({ ...webhook, [inputType]: value });
|
|
|
|
setValidator({
|
|
|
|
...validator,
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.ENDPOINT]: validateURI(value),
|
2022-07-14 18:11:44 +00:00
|
|
|
});
|
|
|
|
break;
|
2022-07-15 16:42:08 +00:00
|
|
|
case WebhookInputDataFields.ENABLED:
|
2022-07-14 18:11:44 +00:00
|
|
|
setWebhook({ ...webhook, [inputType]: value });
|
|
|
|
break;
|
2022-07-15 16:42:08 +00:00
|
|
|
case WebhookInputDataFields.HEADERS:
|
|
|
|
const updatedHeaders: any = [
|
|
|
|
...webhook[WebhookInputDataFields.HEADERS],
|
|
|
|
];
|
2022-07-14 18:11:44 +00:00
|
|
|
const updatedHeadersValidatorData: any = [
|
2022-07-15 16:42:08 +00:00
|
|
|
...validator[WebhookInputDataFields.HEADERS],
|
2022-07-14 18:11:44 +00:00
|
|
|
];
|
|
|
|
const otherHeaderInputType =
|
2022-07-15 16:42:08 +00:00
|
|
|
headerInputType === WebhookInputHeaderFields.KEY
|
|
|
|
? WebhookInputHeaderFields.VALUE
|
|
|
|
: WebhookInputHeaderFields.KEY;
|
2022-07-14 18:11:44 +00:00
|
|
|
updatedHeaders[headerIndex][headerInputType] = value;
|
|
|
|
updatedHeadersValidatorData[headerIndex][headerInputType] =
|
|
|
|
value.length > 0
|
|
|
|
? updatedHeaders[headerIndex][otherHeaderInputType].length > 0
|
|
|
|
: updatedHeaders[headerIndex][otherHeaderInputType].length === 0;
|
|
|
|
updatedHeadersValidatorData[headerIndex][otherHeaderInputType] =
|
|
|
|
value.length > 0
|
|
|
|
? updatedHeaders[headerIndex][otherHeaderInputType].length > 0
|
|
|
|
: updatedHeaders[headerIndex][otherHeaderInputType].length === 0;
|
|
|
|
setWebhook({ ...webhook, [inputType]: updatedHeaders });
|
|
|
|
setValidator({
|
|
|
|
...validator,
|
|
|
|
[inputType]: updatedHeadersValidatorData,
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
2022-07-15 06:50:51 +00:00
|
|
|
const updateHeaders = (operation: string, index: number = 0) => {
|
2022-07-17 11:20:58 +00:00
|
|
|
if (verifiedStatus !== webhookVerifiedStatus.PENDING) {
|
|
|
|
setVerifiedStatus(webhookVerifiedStatus.PENDING);
|
|
|
|
}
|
2022-07-14 18:11:44 +00:00
|
|
|
switch (operation) {
|
|
|
|
case ArrayInputOperations.APPEND:
|
|
|
|
setWebhook({
|
|
|
|
...webhook,
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.HEADERS]: [
|
|
|
|
...(webhook?.[WebhookInputDataFields.HEADERS] || []),
|
2022-07-14 18:11:44 +00:00
|
|
|
{ ...initHeadersData },
|
|
|
|
],
|
|
|
|
});
|
|
|
|
setValidator({
|
|
|
|
...validator,
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.HEADERS]: [
|
|
|
|
...(validator?.[WebhookInputDataFields.HEADERS] || []),
|
2022-07-14 18:11:44 +00:00
|
|
|
{ ...initHeadersValidatorData },
|
|
|
|
],
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case ArrayInputOperations.REMOVE:
|
2022-07-15 16:42:08 +00:00
|
|
|
if (webhook?.[WebhookInputDataFields.HEADERS]?.length) {
|
|
|
|
const updatedHeaders = [...webhook[WebhookInputDataFields.HEADERS]];
|
2022-07-14 18:11:44 +00:00
|
|
|
updatedHeaders.splice(index, 1);
|
|
|
|
setWebhook({
|
|
|
|
...webhook,
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.HEADERS]: updatedHeaders,
|
2022-07-14 18:11:44 +00:00
|
|
|
});
|
|
|
|
}
|
2022-07-15 16:42:08 +00:00
|
|
|
if (validator?.[WebhookInputDataFields.HEADERS]?.length) {
|
|
|
|
const updatedHeadersData = [
|
|
|
|
...validator[WebhookInputDataFields.HEADERS],
|
|
|
|
];
|
2022-07-14 18:11:44 +00:00
|
|
|
updatedHeadersData.splice(index, 1);
|
|
|
|
setValidator({
|
|
|
|
...validator,
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.HEADERS]: updatedHeadersData,
|
2022-07-14 18:11:44 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
2022-07-15 06:50:51 +00:00
|
|
|
const validateData = () => {
|
|
|
|
return (
|
|
|
|
!loading &&
|
2022-07-17 10:33:07 +00:00
|
|
|
!verifyingEndpoint &&
|
2022-07-15 16:42:08 +00:00
|
|
|
webhook[WebhookInputDataFields.EVENT_NAME].length > 0 &&
|
|
|
|
webhook[WebhookInputDataFields.ENDPOINT].length > 0 &&
|
|
|
|
validator[WebhookInputDataFields.ENDPOINT] &&
|
|
|
|
!validator[WebhookInputDataFields.HEADERS].some(
|
2022-07-15 06:50:51 +00:00
|
|
|
(headerData: headersValidatorDataType) =>
|
|
|
|
!headerData.key || !headerData.value
|
|
|
|
)
|
|
|
|
);
|
|
|
|
};
|
2022-07-17 11:20:58 +00:00
|
|
|
const getParams = () => {
|
2022-07-16 09:54:50 +00:00
|
|
|
let params: any = {
|
|
|
|
[WebhookInputDataFields.EVENT_NAME]:
|
|
|
|
webhook[WebhookInputDataFields.EVENT_NAME],
|
|
|
|
[WebhookInputDataFields.ENDPOINT]:
|
|
|
|
webhook[WebhookInputDataFields.ENDPOINT],
|
|
|
|
[WebhookInputDataFields.ENABLED]: webhook[WebhookInputDataFields.ENABLED],
|
2022-07-17 08:08:18 +00:00
|
|
|
[WebhookInputDataFields.HEADERS]: {},
|
2022-07-16 09:54:50 +00:00
|
|
|
};
|
2022-07-15 16:42:08 +00:00
|
|
|
if (webhook[WebhookInputDataFields.HEADERS].length) {
|
|
|
|
const headers = webhook[WebhookInputDataFields.HEADERS].reduce(
|
|
|
|
(acc, data) => {
|
|
|
|
return data.key ? { ...acc, [data.key]: data.value } : acc;
|
|
|
|
},
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
if (Object.keys(headers).length) {
|
|
|
|
params[WebhookInputDataFields.HEADERS] = headers;
|
|
|
|
}
|
2022-07-15 06:50:51 +00:00
|
|
|
}
|
2022-07-17 11:20:58 +00:00
|
|
|
return params;
|
|
|
|
};
|
|
|
|
const saveData = async () => {
|
|
|
|
if (!validateData()) return;
|
|
|
|
setLoading(true);
|
|
|
|
const params = getParams();
|
2022-07-16 09:54:50 +00:00
|
|
|
let res: any = {};
|
|
|
|
if (
|
2022-07-30 10:35:35 +00:00
|
|
|
view === UpdateModalViews.Edit &&
|
2022-07-16 09:54:50 +00:00
|
|
|
selectedWebhook?.[WebhookInputDataFields.ID]
|
|
|
|
) {
|
|
|
|
res = await client
|
|
|
|
.mutation(EditWebhook, {
|
|
|
|
params: {
|
|
|
|
...params,
|
|
|
|
id: selectedWebhook[WebhookInputDataFields.ID],
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.toPromise();
|
|
|
|
} else {
|
|
|
|
res = await client.mutation(AddWebhook, { params }).toPromise();
|
|
|
|
}
|
2022-07-17 09:12:46 +00:00
|
|
|
setLoading(false);
|
2022-07-15 06:50:51 +00:00
|
|
|
if (res.error) {
|
|
|
|
toast({
|
|
|
|
title: capitalizeFirstLetter(res.error.message),
|
|
|
|
isClosable: true,
|
|
|
|
status: 'error',
|
|
|
|
position: 'bottom-right',
|
|
|
|
});
|
2022-07-16 09:54:50 +00:00
|
|
|
} else if (res.data?._add_webhook || res.data?._update_webhook) {
|
2022-07-15 06:50:51 +00:00
|
|
|
toast({
|
2022-07-16 09:54:50 +00:00
|
|
|
title: capitalizeFirstLetter(
|
|
|
|
res.data?._add_webhook?.message || res.data?._update_webhook?.message
|
|
|
|
),
|
2022-07-15 06:50:51 +00:00
|
|
|
isClosable: true,
|
|
|
|
status: 'success',
|
|
|
|
position: 'bottom-right',
|
|
|
|
});
|
2022-07-15 07:34:32 +00:00
|
|
|
setWebhook({
|
|
|
|
...initWebhookData,
|
2022-07-15 16:42:08 +00:00
|
|
|
[WebhookInputDataFields.HEADERS]: [{ ...initHeadersData }],
|
2022-07-15 07:34:32 +00:00
|
|
|
});
|
|
|
|
setValidator({ ...initWebhookValidatorData });
|
2022-07-16 09:54:50 +00:00
|
|
|
fetchWebookData();
|
2022-07-15 06:50:51 +00:00
|
|
|
}
|
2022-07-30 10:35:35 +00:00
|
|
|
view === UpdateModalViews.ADD && onClose();
|
2022-07-15 06:50:51 +00:00
|
|
|
};
|
2022-07-16 09:54:50 +00:00
|
|
|
useEffect(() => {
|
|
|
|
if (
|
2022-07-17 08:22:31 +00:00
|
|
|
isOpen &&
|
2022-07-30 10:35:35 +00:00
|
|
|
view === UpdateModalViews.Edit &&
|
2022-07-16 09:54:50 +00:00
|
|
|
selectedWebhook &&
|
|
|
|
Object.keys(selectedWebhook || {}).length
|
|
|
|
) {
|
|
|
|
const { headers, ...rest } = selectedWebhook;
|
|
|
|
const headerItems = Object.entries(headers || {});
|
|
|
|
if (headerItems.length) {
|
|
|
|
let formattedHeadersData = headerItems.map((headerData) => {
|
|
|
|
return {
|
|
|
|
[WebhookInputHeaderFields.KEY]: headerData[0],
|
|
|
|
[WebhookInputHeaderFields.VALUE]: headerData[1],
|
|
|
|
};
|
|
|
|
});
|
|
|
|
setWebhook({
|
|
|
|
...rest,
|
|
|
|
[WebhookInputDataFields.HEADERS]: formattedHeadersData,
|
|
|
|
});
|
|
|
|
setValidator({
|
|
|
|
...validator,
|
|
|
|
[WebhookInputDataFields.HEADERS]: new Array(
|
|
|
|
formattedHeadersData.length
|
|
|
|
)
|
|
|
|
.fill({})
|
|
|
|
.map(() => ({ ...initHeadersValidatorData })),
|
|
|
|
});
|
|
|
|
} else {
|
2022-07-17 08:08:18 +00:00
|
|
|
setWebhook({
|
|
|
|
...rest,
|
|
|
|
[WebhookInputDataFields.HEADERS]: [{ ...initHeadersData }],
|
|
|
|
});
|
2022-07-16 09:54:50 +00:00
|
|
|
}
|
|
|
|
}
|
2022-07-17 08:22:31 +00:00
|
|
|
}, [isOpen]);
|
2022-07-17 11:20:58 +00:00
|
|
|
const verifyEndpoint = async () => {
|
|
|
|
if (!validateData()) return;
|
|
|
|
setVerifyingEndpoint(true);
|
|
|
|
const { [WebhookInputDataFields.ENABLED]: _, ...params } = getParams();
|
|
|
|
const res = await client.mutation(TestEndpoint, { params }).toPromise();
|
2022-07-17 11:48:45 +00:00
|
|
|
if (
|
|
|
|
res.data?._test_endpoint?.http_status >= 200 &&
|
|
|
|
res.data?._test_endpoint?.http_status < 400
|
|
|
|
) {
|
2022-07-17 11:20:58 +00:00
|
|
|
setVerifiedStatus(webhookVerifiedStatus.VERIFIED);
|
|
|
|
} else {
|
|
|
|
setVerifiedStatus(webhookVerifiedStatus.NOT_VERIFIED);
|
|
|
|
}
|
|
|
|
setVerifyingEndpoint(false);
|
|
|
|
};
|
2022-07-14 18:11:44 +00:00
|
|
|
return (
|
|
|
|
<>
|
2022-07-30 10:35:35 +00:00
|
|
|
{view === UpdateModalViews.ADD ? (
|
2022-07-16 09:54:50 +00:00
|
|
|
<Button
|
|
|
|
leftIcon={<FaPlus />}
|
|
|
|
colorScheme="blue"
|
|
|
|
variant="solid"
|
|
|
|
onClick={onOpen}
|
|
|
|
isDisabled={false}
|
|
|
|
size="sm"
|
|
|
|
>
|
|
|
|
<Center h="100%">Add Webhook</Center>{' '}
|
|
|
|
</Button>
|
|
|
|
) : (
|
|
|
|
<MenuItem onClick={onOpen}>Edit</MenuItem>
|
|
|
|
)}
|
2022-07-14 18:11:44 +00:00
|
|
|
<Modal isOpen={isOpen} onClose={onClose} size="3xl">
|
|
|
|
<ModalOverlay />
|
|
|
|
<ModalContent>
|
2022-07-16 09:54:50 +00:00
|
|
|
<ModalHeader>
|
2022-07-30 10:35:35 +00:00
|
|
|
{view === UpdateModalViews.ADD ? 'Add New Webhook' : 'Edit Webhook'}
|
2022-07-16 09:54:50 +00:00
|
|
|
</ModalHeader>
|
2022-07-14 18:11:44 +00:00
|
|
|
<ModalCloseButton />
|
|
|
|
<ModalBody>
|
|
|
|
<Flex
|
|
|
|
flexDirection="column"
|
|
|
|
border="1px"
|
|
|
|
borderRadius="md"
|
|
|
|
borderColor="gray.200"
|
|
|
|
p="5"
|
|
|
|
>
|
|
|
|
<Flex
|
|
|
|
width="100%"
|
|
|
|
justifyContent="space-between"
|
|
|
|
alignItems="center"
|
|
|
|
marginBottom="2%"
|
|
|
|
>
|
|
|
|
<Flex flex="1">Event Name</Flex>
|
|
|
|
<Flex flex="3">
|
2022-07-17 09:12:46 +00:00
|
|
|
<Select
|
|
|
|
size="md"
|
|
|
|
value={webhook[WebhookInputDataFields.EVENT_NAME]}
|
|
|
|
onChange={(e) =>
|
|
|
|
inputChangehandler(
|
|
|
|
WebhookInputDataFields.EVENT_NAME,
|
|
|
|
e.currentTarget.value
|
|
|
|
)
|
|
|
|
}
|
|
|
|
>
|
|
|
|
{Object.entries(webhookEventNames).map(
|
|
|
|
([key, value]: any) => (
|
|
|
|
<option value={value} key={key}>
|
|
|
|
{key}
|
|
|
|
</option>
|
|
|
|
)
|
|
|
|
)}
|
|
|
|
</Select>
|
2022-07-14 18:11:44 +00:00
|
|
|
</Flex>
|
|
|
|
</Flex>
|
|
|
|
<Flex
|
|
|
|
width="100%"
|
|
|
|
justifyContent="start"
|
|
|
|
alignItems="center"
|
|
|
|
marginBottom="5%"
|
|
|
|
>
|
|
|
|
<Flex flex="1">Endpoint</Flex>
|
|
|
|
<Flex flex="3">
|
|
|
|
<InputGroup size="md">
|
|
|
|
<Input
|
|
|
|
pr="4.5rem"
|
|
|
|
type="text"
|
|
|
|
placeholder="https://domain.com/webhook"
|
2022-07-15 16:42:08 +00:00
|
|
|
value={webhook[WebhookInputDataFields.ENDPOINT]}
|
|
|
|
isInvalid={!validator[WebhookInputDataFields.ENDPOINT]}
|
2022-07-14 18:11:44 +00:00
|
|
|
onChange={(e) =>
|
|
|
|
inputChangehandler(
|
2022-07-15 16:42:08 +00:00
|
|
|
WebhookInputDataFields.ENDPOINT,
|
2022-07-14 18:11:44 +00:00
|
|
|
e.currentTarget.value
|
|
|
|
)
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</InputGroup>
|
|
|
|
</Flex>
|
|
|
|
</Flex>
|
|
|
|
<Flex
|
|
|
|
width="100%"
|
|
|
|
justifyContent="space-between"
|
|
|
|
alignItems="center"
|
|
|
|
marginBottom="5%"
|
|
|
|
>
|
|
|
|
<Flex flex="1">Enabled</Flex>
|
|
|
|
<Flex w="25%" justifyContent="space-between">
|
|
|
|
<Text h="75%" fontWeight="bold" marginRight="2">
|
|
|
|
Off
|
|
|
|
</Text>
|
|
|
|
<Switch
|
|
|
|
size="md"
|
2022-07-15 16:42:08 +00:00
|
|
|
isChecked={webhook[WebhookInputDataFields.ENABLED]}
|
2022-07-14 18:11:44 +00:00
|
|
|
onChange={() =>
|
|
|
|
inputChangehandler(
|
2022-07-15 16:42:08 +00:00
|
|
|
WebhookInputDataFields.ENABLED,
|
|
|
|
!webhook[WebhookInputDataFields.ENABLED]
|
2022-07-14 18:11:44 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
<Text h="75%" fontWeight="bold" marginLeft="2">
|
|
|
|
On
|
|
|
|
</Text>
|
|
|
|
</Flex>
|
|
|
|
</Flex>
|
2022-08-01 19:26:21 +00:00
|
|
|
<Flex
|
|
|
|
width="100%"
|
|
|
|
justifyContent="center"
|
|
|
|
alignItems="center"
|
|
|
|
marginBottom="5%"
|
|
|
|
flexDirection="column"
|
|
|
|
>
|
|
|
|
<Flex
|
|
|
|
width="100%"
|
|
|
|
justifyContent="space-between"
|
|
|
|
alignItems="center"
|
|
|
|
>
|
|
|
|
<Flex>
|
|
|
|
Payload
|
|
|
|
<Text color="gray.500" ml={1}>
|
|
|
|
(example)
|
|
|
|
</Text>
|
|
|
|
</Flex>
|
|
|
|
<Button
|
|
|
|
onClick={() => setIsShowingPayload(!isShowingPayload)}
|
|
|
|
variant="ghost"
|
|
|
|
>
|
|
|
|
{isShowingPayload ? <FaAngleUp /> : <FaAngleDown />}
|
|
|
|
</Button>
|
|
|
|
</Flex>
|
|
|
|
<Collapse
|
|
|
|
style={{
|
|
|
|
marginTop: 10,
|
|
|
|
width: '100%',
|
|
|
|
}}
|
|
|
|
in={isShowingPayload}
|
|
|
|
>
|
|
|
|
<Code
|
|
|
|
width="inherit"
|
|
|
|
borderRadius={5}
|
|
|
|
padding={2}
|
|
|
|
position="relative"
|
|
|
|
>
|
|
|
|
<pre style={{ overflow: 'auto' }}>
|
|
|
|
{webhookPayloadExample}
|
|
|
|
</pre>
|
|
|
|
{isShowingPayload && (
|
|
|
|
<Flex
|
|
|
|
position="absolute"
|
|
|
|
top={4}
|
|
|
|
right={4}
|
|
|
|
cursor="pointer"
|
|
|
|
onClick={() =>
|
|
|
|
copyTextToClipboard(webhookPayloadExample)
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<FaRegClone color="#bfbfbf" />
|
|
|
|
</Flex>
|
|
|
|
)}
|
|
|
|
</Code>
|
|
|
|
</Collapse>
|
|
|
|
</Flex>
|
2022-07-14 18:11:44 +00:00
|
|
|
<Flex
|
|
|
|
width="100%"
|
|
|
|
justifyContent="space-between"
|
|
|
|
alignItems="center"
|
|
|
|
marginBottom="2%"
|
|
|
|
>
|
|
|
|
<Flex>Headers</Flex>
|
|
|
|
<Flex>
|
|
|
|
<Button
|
|
|
|
leftIcon={<FaPlus />}
|
|
|
|
colorScheme="blue"
|
|
|
|
h="1.75rem"
|
|
|
|
size="sm"
|
|
|
|
variant="ghost"
|
|
|
|
paddingRight="0"
|
2022-07-15 06:50:51 +00:00
|
|
|
onClick={() => updateHeaders(ArrayInputOperations.APPEND)}
|
2022-07-14 18:11:44 +00:00
|
|
|
>
|
|
|
|
Add more Headers
|
|
|
|
</Button>
|
|
|
|
</Flex>
|
|
|
|
</Flex>
|
|
|
|
<Flex flexDirection="column" maxH={220} overflowY="scroll">
|
2022-07-15 16:42:08 +00:00
|
|
|
{webhook[WebhookInputDataFields.HEADERS]?.map(
|
|
|
|
(headerData, index) => (
|
|
|
|
<Flex
|
|
|
|
key={`header-data-${index}`}
|
|
|
|
justifyContent="center"
|
|
|
|
alignItems="center"
|
|
|
|
>
|
|
|
|
<InputGroup size="md" marginBottom="2.5%">
|
|
|
|
<Input
|
|
|
|
type="text"
|
|
|
|
placeholder="key"
|
|
|
|
value={headerData[WebhookInputHeaderFields.KEY]}
|
|
|
|
isInvalid={
|
|
|
|
!validator[WebhookInputDataFields.HEADERS][index]?.[
|
|
|
|
WebhookInputHeaderFields.KEY
|
|
|
|
]
|
|
|
|
}
|
|
|
|
onChange={(e) =>
|
|
|
|
inputChangehandler(
|
|
|
|
WebhookInputDataFields.HEADERS,
|
|
|
|
e.target.value,
|
|
|
|
WebhookInputHeaderFields.KEY,
|
|
|
|
index
|
|
|
|
)
|
|
|
|
}
|
|
|
|
width="30%"
|
|
|
|
marginRight="2%"
|
|
|
|
/>
|
|
|
|
<Center marginRight="2%">
|
|
|
|
<Text fontWeight="bold">:</Text>
|
|
|
|
</Center>
|
|
|
|
<Input
|
|
|
|
type="text"
|
|
|
|
placeholder="value"
|
|
|
|
value={headerData[WebhookInputHeaderFields.VALUE]}
|
|
|
|
isInvalid={
|
|
|
|
!validator[WebhookInputDataFields.HEADERS][index]?.[
|
|
|
|
WebhookInputHeaderFields.VALUE
|
|
|
|
]
|
|
|
|
}
|
|
|
|
onChange={(e) =>
|
|
|
|
inputChangehandler(
|
|
|
|
WebhookInputDataFields.HEADERS,
|
|
|
|
e.target.value,
|
|
|
|
WebhookInputHeaderFields.VALUE,
|
|
|
|
index
|
|
|
|
)
|
2022-07-14 18:11:44 +00:00
|
|
|
}
|
2022-07-15 16:42:08 +00:00
|
|
|
width="65%"
|
|
|
|
/>
|
|
|
|
<InputRightElement width="3rem">
|
|
|
|
<Button
|
|
|
|
width="6rem"
|
|
|
|
colorScheme="blackAlpha"
|
|
|
|
variant="ghost"
|
|
|
|
padding="0"
|
|
|
|
onClick={() =>
|
|
|
|
updateHeaders(ArrayInputOperations.REMOVE, index)
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<FaMinusCircle />
|
|
|
|
</Button>
|
|
|
|
</InputRightElement>
|
|
|
|
</InputGroup>
|
|
|
|
</Flex>
|
|
|
|
)
|
|
|
|
)}
|
2022-07-14 18:11:44 +00:00
|
|
|
</Flex>
|
|
|
|
</Flex>
|
|
|
|
</ModalBody>
|
|
|
|
<ModalFooter>
|
2022-07-17 10:33:07 +00:00
|
|
|
<Button
|
|
|
|
colorScheme={
|
|
|
|
verifiedStatus === webhookVerifiedStatus.VERIFIED
|
|
|
|
? 'green'
|
|
|
|
: verifiedStatus === webhookVerifiedStatus.PENDING
|
|
|
|
? 'yellow'
|
|
|
|
: 'red'
|
|
|
|
}
|
|
|
|
variant="outline"
|
2022-07-17 11:20:58 +00:00
|
|
|
onClick={verifyEndpoint}
|
2022-07-17 10:33:07 +00:00
|
|
|
isLoading={verifyingEndpoint}
|
|
|
|
isDisabled={!validateData()}
|
|
|
|
marginRight="5"
|
|
|
|
leftIcon={
|
|
|
|
verifiedStatus === webhookVerifiedStatus.VERIFIED ? (
|
|
|
|
<BiCheckCircle />
|
|
|
|
) : verifiedStatus === webhookVerifiedStatus.PENDING ? (
|
|
|
|
<BiErrorCircle />
|
|
|
|
) : (
|
|
|
|
<BiError />
|
|
|
|
)
|
|
|
|
}
|
|
|
|
>
|
2022-07-17 11:20:58 +00:00
|
|
|
{verifiedStatus === webhookVerifiedStatus.VERIFIED
|
|
|
|
? 'Endpoint Verified'
|
|
|
|
: verifiedStatus === webhookVerifiedStatus.PENDING
|
|
|
|
? 'Test Endpoint'
|
|
|
|
: 'Endpoint Not Verified'}
|
2022-07-17 10:33:07 +00:00
|
|
|
</Button>
|
2022-07-14 18:11:44 +00:00
|
|
|
<Button
|
|
|
|
colorScheme="blue"
|
|
|
|
variant="solid"
|
2022-07-15 06:50:51 +00:00
|
|
|
onClick={saveData}
|
|
|
|
isDisabled={!validateData()}
|
2022-07-14 18:11:44 +00:00
|
|
|
>
|
|
|
|
<Center h="100%" pt="5%">
|
|
|
|
Save
|
|
|
|
</Center>
|
|
|
|
</Button>
|
|
|
|
</ModalFooter>
|
|
|
|
</ModalContent>
|
|
|
|
</Modal>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2022-07-16 09:54:50 +00:00
|
|
|
export default UpdateWebhookModal;
|