update: webhooks

This commit is contained in:
anik-ghosh-au7 2022-07-16 15:24:50 +05:30
parent 301bde4da2
commit d3260f4f32
4 changed files with 135 additions and 25 deletions

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import { import {
Button, Button,
Center, Center,
@ -6,6 +6,7 @@ import {
Input, Input,
InputGroup, InputGroup,
InputRightElement, InputRightElement,
MenuItem,
Modal, Modal,
ModalBody, ModalBody,
ModalCloseButton, ModalCloseButton,
@ -24,13 +25,14 @@ import {
ArrayInputOperations, ArrayInputOperations,
WebhookInputDataFields, WebhookInputDataFields,
WebhookInputHeaderFields, WebhookInputHeaderFields,
UpdateWebhookModalViews,
} from '../constants'; } from '../constants';
import { import {
capitalizeFirstLetter, capitalizeFirstLetter,
validateEventName, validateEventName,
validateURI, validateURI,
} from '../utils'; } from '../utils';
import { AddWebhook } from '../graphql/mutation'; import { AddWebhook, EditWebhook } from '../graphql/mutation';
interface headersDataType { interface headersDataType {
[WebhookInputHeaderFields.KEY]: string; [WebhookInputHeaderFields.KEY]: string;
@ -42,6 +44,20 @@ interface headersValidatorDataType {
[WebhookInputHeaderFields.VALUE]: boolean; [WebhookInputHeaderFields.VALUE]: boolean;
} }
interface selecetdWebhookDataTypes {
[WebhookInputDataFields.ID]: string;
[WebhookInputDataFields.EVENT_NAME]: string;
[WebhookInputDataFields.ENDPOINT]: string;
[WebhookInputDataFields.ENABLED]: boolean;
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
}
interface UpdateWebhookModalInputPropTypes {
view: UpdateWebhookModalViews;
selectedWebhook?: selecetdWebhookDataTypes;
fetchWebookData: Function;
}
const initHeadersData: headersDataType = { const initHeadersData: headersDataType = {
[WebhookInputHeaderFields.KEY]: '', [WebhookInputHeaderFields.KEY]: '',
[WebhookInputHeaderFields.VALUE]: '', [WebhookInputHeaderFields.VALUE]: '',
@ -78,7 +94,11 @@ const initWebhookValidatorData: validatorDataType = {
[WebhookInputDataFields.HEADERS]: [{ ...initHeadersValidatorData }], [WebhookInputDataFields.HEADERS]: [{ ...initHeadersValidatorData }],
}; };
const AddWebhookModal = () => { const UpdateWebhookModal = ({
view,
selectedWebhook,
fetchWebookData,
}: UpdateWebhookModalInputPropTypes) => {
const client = useClient(); const client = useClient();
const toast = useToast(); const toast = useToast();
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
@ -201,7 +221,13 @@ const AddWebhookModal = () => {
const saveData = async () => { const saveData = async () => {
if (!validateData()) return; if (!validateData()) return;
setLoading(true); setLoading(true);
let { [WebhookInputDataFields.HEADERS]: _, ...params }: any = webhook; let params: any = {
[WebhookInputDataFields.EVENT_NAME]:
webhook[WebhookInputDataFields.EVENT_NAME],
[WebhookInputDataFields.ENDPOINT]:
webhook[WebhookInputDataFields.ENDPOINT],
[WebhookInputDataFields.ENABLED]: webhook[WebhookInputDataFields.ENABLED],
};
if (webhook[WebhookInputDataFields.HEADERS].length) { if (webhook[WebhookInputDataFields.HEADERS].length) {
const headers = webhook[WebhookInputDataFields.HEADERS].reduce( const headers = webhook[WebhookInputDataFields.HEADERS].reduce(
(acc, data) => { (acc, data) => {
@ -213,7 +239,22 @@ const AddWebhookModal = () => {
params[WebhookInputDataFields.HEADERS] = headers; params[WebhookInputDataFields.HEADERS] = headers;
} }
} }
const res = await client.mutation(AddWebhook, { params }).toPromise(); let res: any = {};
if (
view === UpdateWebhookModalViews.Edit &&
selectedWebhook?.[WebhookInputDataFields.ID]
) {
res = await client
.mutation(EditWebhook, {
params: {
...params,
id: selectedWebhook[WebhookInputDataFields.ID],
},
})
.toPromise();
} else {
res = await client.mutation(AddWebhook, { params }).toPromise();
}
if (res.error) { if (res.error) {
toast({ toast({
title: capitalizeFirstLetter(res.error.message), title: capitalizeFirstLetter(res.error.message),
@ -223,9 +264,11 @@ const AddWebhookModal = () => {
}); });
setLoading(false); setLoading(false);
return; return;
} else if (res.data?._add_webhook) { } else if (res.data?._add_webhook || res.data?._update_webhook) {
toast({ toast({
title: capitalizeFirstLetter(res.data?._add_webhook.message), title: capitalizeFirstLetter(
res.data?._add_webhook?.message || res.data?._update_webhook?.message
),
isClosable: true, isClosable: true,
status: 'success', status: 'success',
position: 'bottom-right', position: 'bottom-right',
@ -236,11 +279,45 @@ const AddWebhookModal = () => {
}); });
setValidator({ ...initWebhookValidatorData }); setValidator({ ...initWebhookValidatorData });
onClose(); onClose();
fetchWebookData();
} }
setLoading(false); setLoading(false);
}; };
useEffect(() => {
if (
view === UpdateWebhookModalViews.Edit &&
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 {
setWebhook({ ...rest, [WebhookInputDataFields.HEADERS]: [] });
}
}
}, [view]);
return ( return (
<> <>
{view === UpdateWebhookModalViews.ADD ? (
<Button <Button
leftIcon={<FaPlus />} leftIcon={<FaPlus />}
colorScheme="blue" colorScheme="blue"
@ -251,10 +328,17 @@ const AddWebhookModal = () => {
> >
<Center h="100%">Add Webhook</Center>{' '} <Center h="100%">Add Webhook</Center>{' '}
</Button> </Button>
) : (
<MenuItem onClick={onOpen}>Edit</MenuItem>
)}
<Modal isOpen={isOpen} onClose={onClose} size="3xl"> <Modal isOpen={isOpen} onClose={onClose} size="3xl">
<ModalOverlay /> <ModalOverlay />
<ModalContent> <ModalContent>
<ModalHeader>Add New Webhook</ModalHeader> <ModalHeader>
{view === UpdateWebhookModalViews.ADD
? 'Add New Webhook'
: 'Edit Webhook'}
</ModalHeader>
<ModalCloseButton /> <ModalCloseButton />
<ModalBody> <ModalBody>
<Flex <Flex
@ -450,4 +534,4 @@ const AddWebhookModal = () => {
); );
}; };
export default AddWebhookModal; export default UpdateWebhookModal;

View File

@ -167,4 +167,9 @@ export enum WebhookInputHeaderFields {
VALUE = 'value', VALUE = 'value',
} }
export enum UpdateWebhookModalViews {
ADD = 'add',
Edit = 'edit',
}
export const pageLimits: number[] = [5, 10, 15]; export const pageLimits: number[] = [5, 10, 15];

View File

@ -87,3 +87,11 @@ export const AddWebhook = `
} }
} }
`; `;
export const EditWebhook = `
mutation editWebhook($params: UpdateWebhookRequest!) {
_update_webhook(params: $params) {
message
}
}
`;

View File

@ -36,8 +36,12 @@ import {
FaAngleRight, FaAngleRight,
FaExclamationCircle, FaExclamationCircle,
} from 'react-icons/fa'; } from 'react-icons/fa';
import AddWebhookModal from '../components/AddWebhookModal'; import UpdateWebhookModal from '../components/UpdateWebhookModal';
import { pageLimits, WebhookInputDataFields } from '../constants'; import {
pageLimits,
WebhookInputDataFields,
UpdateWebhookModalViews,
} from '../constants';
import { WebhooksDataQuery } from '../graphql/queries'; import { WebhooksDataQuery } from '../graphql/queries';
interface paginationPropTypes { interface paginationPropTypes {
@ -115,14 +119,16 @@ const Webhooks = () => {
React.useEffect(() => { React.useEffect(() => {
fetchWebookData(); fetchWebookData();
}, [paginationProps.page, paginationProps.limit]); }, [paginationProps.page, paginationProps.limit]);
console.log('webhookData ==>> ', webhookData);
return ( return (
<Box m="5" py="5" px="10" bg="white" rounded="md"> <Box m="5" py="5" px="10" bg="white" rounded="md">
<Flex margin="2% 0" justifyContent="space-between" alignItems="center"> <Flex margin="2% 0" justifyContent="space-between" alignItems="center">
<Text fontSize="md" fontWeight="bold"> <Text fontSize="md" fontWeight="bold">
Webhooks Webhooks
</Text> </Text>
<AddWebhookModal /> <UpdateWebhookModal
view={UpdateWebhookModalViews.ADD}
fetchWebookData={fetchWebookData}
/>
</Flex> </Flex>
{!loading ? ( {!loading ? (
webhookData.length ? ( webhookData.length ? (
@ -161,10 +167,13 @@ const Webhooks = () => {
</Td> </Td>
<Td> <Td>
<Tooltip <Tooltip
as="span"
bg="gray.300" bg="gray.300"
color="black" color="black"
label={JSON.stringify( label={JSON.stringify(
webhook[WebhookInputDataFields.HEADERS] webhook[WebhookInputDataFields.HEADERS],
null,
' '
)} )}
> >
<Center <Center
@ -195,7 +204,11 @@ const Webhooks = () => {
</Flex> </Flex>
</MenuButton> </MenuButton>
<MenuList> <MenuList>
<MenuItem onClick={() => {}}>Edit</MenuItem> <UpdateWebhookModal
view={UpdateWebhookModalViews.Edit}
selectedWebhook={webhook}
fetchWebookData={fetchWebookData}
/>
<MenuItem onClick={() => {}}>Delete</MenuItem> <MenuItem onClick={() => {}}>Delete</MenuItem>
<MenuItem onClick={() => {}}>View Logs</MenuItem> <MenuItem onClick={() => {}}>View Logs</MenuItem>
</MenuList> </MenuList>