import React, { useState } from 'react'; import { Button, Center, Flex, Input, InputGroup, InputRightElement, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Switch, Text, useDisclosure, useToast, } from '@chakra-ui/react'; import { FaMinusCircle, FaPlus } from 'react-icons/fa'; import { useClient } from 'urql'; import { ArrayInputOperations } from '../constants'; import { capitalizeFirstLetter, validateEventName, validateURI, } from '../utils'; import { AddWebhook } from '../graphql/mutation'; enum INPUT_FIELDS { EVENT_NAME = 'event_name', ENDPOINT = 'endpoint', ENABLED = 'enabled', HEADERS = 'headers', } enum HEADER_FIELDS { KEY = 'key', VALUE = 'value', } interface headersDataType { [HEADER_FIELDS.KEY]: string; [HEADER_FIELDS.VALUE]: string; } interface headersValidatorDataType { [HEADER_FIELDS.KEY]: boolean; [HEADER_FIELDS.VALUE]: boolean; } const initHeadersData: headersDataType = { [HEADER_FIELDS.KEY]: '', [HEADER_FIELDS.VALUE]: '', }; const initHeadersValidatorData: headersValidatorDataType = { [HEADER_FIELDS.KEY]: true, [HEADER_FIELDS.VALUE]: true, }; interface webhookDataType { [INPUT_FIELDS.EVENT_NAME]: string; [INPUT_FIELDS.ENDPOINT]: string; [INPUT_FIELDS.ENABLED]: boolean; [INPUT_FIELDS.HEADERS]: headersDataType[]; } interface validatorDataType { [INPUT_FIELDS.EVENT_NAME]: boolean; [INPUT_FIELDS.ENDPOINT]: boolean; [INPUT_FIELDS.HEADERS]: headersValidatorDataType[]; } const initWebhookData: webhookDataType = { [INPUT_FIELDS.EVENT_NAME]: '', [INPUT_FIELDS.ENDPOINT]: '', [INPUT_FIELDS.ENABLED]: false, [INPUT_FIELDS.HEADERS]: [{ ...initHeadersData }], }; const initWebhookValidatorData: validatorDataType = { [INPUT_FIELDS.EVENT_NAME]: true, [INPUT_FIELDS.ENDPOINT]: true, [INPUT_FIELDS.HEADERS]: [{ ...initHeadersValidatorData }], }; const AddWebhookModal = () => { const client = useClient(); const toast = useToast(); const { isOpen, onOpen, onClose } = useDisclosure(); const [loading, setLoading] = useState(false); const [webhook, setWebhook] = useState({ ...initWebhookData, }); const [validator, setValidator] = useState({ ...initWebhookValidatorData, }); const inputChangehandler = ( inputType: string, value: any, headerInputType: string = HEADER_FIELDS.KEY, headerIndex: number = 0 ) => { switch (inputType) { case INPUT_FIELDS.EVENT_NAME: setWebhook({ ...webhook, [inputType]: value }); setValidator({ ...validator, [INPUT_FIELDS.EVENT_NAME]: validateEventName(value), }); break; case INPUT_FIELDS.ENDPOINT: setWebhook({ ...webhook, [inputType]: value }); setValidator({ ...validator, [INPUT_FIELDS.ENDPOINT]: validateURI(value), }); break; case INPUT_FIELDS.ENABLED: setWebhook({ ...webhook, [inputType]: value }); break; case INPUT_FIELDS.HEADERS: const updatedHeaders: any = [...webhook[INPUT_FIELDS.HEADERS]]; const updatedHeadersValidatorData: any = [ ...validator[INPUT_FIELDS.HEADERS], ]; const otherHeaderInputType = headerInputType === HEADER_FIELDS.KEY ? HEADER_FIELDS.VALUE : HEADER_FIELDS.KEY; 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; } }; const updateHeaders = (operation: string, index: number = 0) => { switch (operation) { case ArrayInputOperations.APPEND: setWebhook({ ...webhook, [INPUT_FIELDS.HEADERS]: [ ...(webhook?.[INPUT_FIELDS.HEADERS] || []), { ...initHeadersData }, ], }); setValidator({ ...validator, [INPUT_FIELDS.HEADERS]: [ ...(validator?.[INPUT_FIELDS.HEADERS] || []), { ...initHeadersValidatorData }, ], }); break; case ArrayInputOperations.REMOVE: if (webhook?.[INPUT_FIELDS.HEADERS]?.length) { const updatedHeaders = [...webhook[INPUT_FIELDS.HEADERS]]; updatedHeaders.splice(index, 1); setWebhook({ ...webhook, [INPUT_FIELDS.HEADERS]: updatedHeaders, }); } if (validator?.[INPUT_FIELDS.HEADERS]?.length) { const updatedHeadersData = [...validator[INPUT_FIELDS.HEADERS]]; updatedHeadersData.splice(index, 1); setValidator({ ...validator, [INPUT_FIELDS.HEADERS]: updatedHeadersData, }); } break; default: break; } }; const validateData = () => { return ( !loading && webhook[INPUT_FIELDS.EVENT_NAME].length > 0 && webhook[INPUT_FIELDS.ENDPOINT].length > 0 && validator[INPUT_FIELDS.EVENT_NAME] && validator[INPUT_FIELDS.ENDPOINT] && !validator[INPUT_FIELDS.HEADERS].some( (headerData: headersValidatorDataType) => !headerData.key || !headerData.value ) ); }; const saveData = async () => { if (!validateData()) return; setLoading(true); let params: any = { [INPUT_FIELDS.EVENT_NAME]: webhook[INPUT_FIELDS.EVENT_NAME], [INPUT_FIELDS.ENDPOINT]: webhook[INPUT_FIELDS.ENDPOINT], [INPUT_FIELDS.ENABLED]: webhook[INPUT_FIELDS.ENABLED], }; if (webhook[INPUT_FIELDS.HEADERS].length > 0) { const headers = webhook[INPUT_FIELDS.HEADERS].reduce((acc, data) => { return { ...acc, [data.key]: data.value }; }, {}); params[INPUT_FIELDS.HEADERS] = headers; } const res = await client.mutation(AddWebhook, { params }).toPromise(); if (res.error) { toast({ title: capitalizeFirstLetter(res.error.message), isClosable: true, status: 'error', position: 'bottom-right', }); setLoading(false); return; } else if (res.data?._add_webhook) { toast({ title: capitalizeFirstLetter(res.data?._add_webhook.message), isClosable: true, status: 'success', position: 'bottom-right', }); setWebhook({ ...initWebhookData }); onClose(); } setLoading(false); }; return ( <> Add New Webhook Event Name inputChangehandler( INPUT_FIELDS.EVENT_NAME, e.currentTarget.value ) } /> Endpoint inputChangehandler( INPUT_FIELDS.ENDPOINT, e.currentTarget.value ) } /> Enabled Off inputChangehandler( INPUT_FIELDS.ENABLED, !webhook[INPUT_FIELDS.ENABLED] ) } /> On Headers {webhook[INPUT_FIELDS.HEADERS]?.map((headerData, index) => ( inputChangehandler( INPUT_FIELDS.HEADERS, e.target.value, HEADER_FIELDS.KEY, index ) } width="30%" marginRight="2%" />
:
inputChangehandler( INPUT_FIELDS.HEADERS, e.target.value, HEADER_FIELDS.VALUE, index ) } width="65%" />
))}
); }; export default AddWebhookModal;