From 5c8f9406f63a763486e1a4b7c755e1730332df19 Mon Sep 17 00:00:00 2001 From: anik-ghosh-au7 Date: Tue, 15 Nov 2022 22:12:14 +0530 Subject: [PATCH] fix: email template resolver and for matting changes --- .../components/UpdateEmailTemplateModal.tsx | 1034 ++++++++--------- dashboard/src/constants.ts | 490 ++++---- server/resolvers/add_email_template.go | 3 +- 3 files changed, 764 insertions(+), 763 deletions(-) diff --git a/dashboard/src/components/UpdateEmailTemplateModal.tsx b/dashboard/src/components/UpdateEmailTemplateModal.tsx index 92d0098..f5aba9a 100644 --- a/dashboard/src/components/UpdateEmailTemplateModal.tsx +++ b/dashboard/src/components/UpdateEmailTemplateModal.tsx @@ -1,565 +1,565 @@ import React, { useEffect, useRef, useState } from 'react'; import { - Button, - Center, - Flex, - Input, - InputGroup, - MenuItem, - Modal, - ModalBody, - ModalCloseButton, - ModalContent, - ModalFooter, - ModalHeader, - ModalOverlay, - Select, - Text, - useDisclosure, - useToast, - Alert, - AlertIcon, - Collapse, - Box, - TableContainer, - Table, - Thead, - Tr, - Th, - Tbody, - Td, - Code, - Radio, - RadioGroup, - Stack, - Textarea, + Button, + Center, + Flex, + Input, + InputGroup, + MenuItem, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Select, + Text, + useDisclosure, + useToast, + Alert, + AlertIcon, + Collapse, + Box, + TableContainer, + Table, + Thead, + Tr, + Th, + Tbody, + Td, + Code, + Radio, + RadioGroup, + Stack, + Textarea, } from '@chakra-ui/react'; import { FaPlus, FaAngleDown, FaAngleUp } from 'react-icons/fa'; import { useClient } from 'urql'; import EmailEditor from 'react-email-editor'; import { - UpdateModalViews, - EmailTemplateInputDataFields, - emailTemplateEventNames, - emailTemplateVariables, - EmailTemplateEditors, + UpdateModalViews, + EmailTemplateInputDataFields, + emailTemplateEventNames, + emailTemplateVariables, + EmailTemplateEditors, } from '../constants'; import { capitalizeFirstLetter } from '../utils'; import { AddEmailTemplate, EditEmailTemplate } from '../graphql/mutation'; interface selectedEmailTemplateDataTypes { - [EmailTemplateInputDataFields.ID]: string; - [EmailTemplateInputDataFields.EVENT_NAME]: string; - [EmailTemplateInputDataFields.SUBJECT]: string; - [EmailTemplateInputDataFields.CREATED_AT]: number; - [EmailTemplateInputDataFields.TEMPLATE]: string; - [EmailTemplateInputDataFields.DESIGN]: string; + [EmailTemplateInputDataFields.ID]: string; + [EmailTemplateInputDataFields.EVENT_NAME]: string; + [EmailTemplateInputDataFields.SUBJECT]: string; + [EmailTemplateInputDataFields.CREATED_AT]: number; + [EmailTemplateInputDataFields.TEMPLATE]: string; + [EmailTemplateInputDataFields.DESIGN]: string; } interface UpdateEmailTemplateInputPropTypes { - view: UpdateModalViews; - selectedTemplate?: selectedEmailTemplateDataTypes; - fetchEmailTemplatesData: Function; + view: UpdateModalViews; + selectedTemplate?: selectedEmailTemplateDataTypes; + fetchEmailTemplatesData: Function; } interface templateVariableDataTypes { - text: string; - value: string; - description: string; + text: string; + value: string; + description: string; } interface emailTemplateDataType { - [EmailTemplateInputDataFields.EVENT_NAME]: string; - [EmailTemplateInputDataFields.SUBJECT]: string; - [EmailTemplateInputDataFields.TEMPLATE]: string; - [EmailTemplateInputDataFields.DESIGN]: string; + [EmailTemplateInputDataFields.EVENT_NAME]: string; + [EmailTemplateInputDataFields.SUBJECT]: string; + [EmailTemplateInputDataFields.TEMPLATE]: string; + [EmailTemplateInputDataFields.DESIGN]: string; } interface validatorDataType { - [EmailTemplateInputDataFields.SUBJECT]: boolean; + [EmailTemplateInputDataFields.SUBJECT]: boolean; } const initTemplateData: emailTemplateDataType = { - [EmailTemplateInputDataFields.EVENT_NAME]: emailTemplateEventNames.Signup, - [EmailTemplateInputDataFields.SUBJECT]: '', - [EmailTemplateInputDataFields.TEMPLATE]: '', - [EmailTemplateInputDataFields.DESIGN]: '', + [EmailTemplateInputDataFields.EVENT_NAME]: emailTemplateEventNames.Signup, + [EmailTemplateInputDataFields.SUBJECT]: '', + [EmailTemplateInputDataFields.TEMPLATE]: '', + [EmailTemplateInputDataFields.DESIGN]: '', }; const initTemplateValidatorData: validatorDataType = { - [EmailTemplateInputDataFields.SUBJECT]: true, + [EmailTemplateInputDataFields.SUBJECT]: true, }; const UpdateEmailTemplate = ({ - view, - selectedTemplate, - fetchEmailTemplatesData, + view, + selectedTemplate, + fetchEmailTemplatesData, }: UpdateEmailTemplateInputPropTypes) => { - const client = useClient(); - const toast = useToast(); - const emailEditorRef = useRef(null); - const { isOpen, onOpen, onClose } = useDisclosure(); - const [loading, setLoading] = useState(false); - const [editor, setEditor] = useState( - EmailTemplateEditors.PLAIN_HTML_EDITOR, - ); - const [templateVariables, setTemplateVariables] = useState< - templateVariableDataTypes[] - >([]); - const [templateData, setTemplateData] = useState({ - ...initTemplateData, - }); - const [validator, setValidator] = useState({ - ...initTemplateValidatorData, - }); - const [isDynamicVariableInfoOpen, setIsDynamicVariableInfoOpen] = - useState(false); + const client = useClient(); + const toast = useToast(); + const emailEditorRef = useRef(null); + const { isOpen, onOpen, onClose } = useDisclosure(); + const [loading, setLoading] = useState(false); + const [editor, setEditor] = useState( + EmailTemplateEditors.PLAIN_HTML_EDITOR, + ); + const [templateVariables, setTemplateVariables] = useState< + templateVariableDataTypes[] + >([]); + const [templateData, setTemplateData] = useState({ + ...initTemplateData, + }); + const [validator, setValidator] = useState({ + ...initTemplateValidatorData, + }); + const [isDynamicVariableInfoOpen, setIsDynamicVariableInfoOpen] = + useState(false); - const onReady = () => { - if (selectedTemplate) { - const { design } = selectedTemplate; - try { - if (design) { - const designData = JSON.parse(design); - // @ts-ignore - emailEditorRef.current.editor.loadDesign(designData); - } - } catch (error) { - console.error(error); - onClose(); - } - } - }; + const onReady = () => { + if (selectedTemplate) { + const { design } = selectedTemplate; + try { + if (design) { + const designData = JSON.parse(design); + // @ts-ignore + emailEditorRef.current.editor.loadDesign(designData); + } + } catch (error) { + console.error(error); + onClose(); + } + } + }; - const inputChangehandler = (inputType: string, value: any) => { - if (inputType !== EmailTemplateInputDataFields.EVENT_NAME) { - setValidator({ - ...validator, - [inputType]: value?.trim().length, - }); - } - setTemplateData({ ...templateData, [inputType]: value }); - }; + const inputChangehandler = (inputType: string, value: any) => { + if (inputType !== EmailTemplateInputDataFields.EVENT_NAME) { + setValidator({ + ...validator, + [inputType]: value?.trim().length, + }); + } + setTemplateData({ ...templateData, [inputType]: value }); + }; - const validateData = () => { - return ( - !loading && - templateData[EmailTemplateInputDataFields.EVENT_NAME].length > 0 && - templateData[EmailTemplateInputDataFields.SUBJECT].length > 0 && - validator[EmailTemplateInputDataFields.SUBJECT] - ); - }; + const validateData = () => { + return ( + !loading && + templateData[EmailTemplateInputDataFields.EVENT_NAME].length > 0 && + templateData[EmailTemplateInputDataFields.SUBJECT].length > 0 && + validator[EmailTemplateInputDataFields.SUBJECT] + ); + }; - const updateTemplate = async (params: emailTemplateDataType) => { - let res: any = {}; - if ( - view === UpdateModalViews.Edit && - selectedTemplate?.[EmailTemplateInputDataFields.ID] - ) { - res = await client - .mutation(EditEmailTemplate, { - params: { - ...params, - id: selectedTemplate[EmailTemplateInputDataFields.ID], - }, - }) - .toPromise(); - } else { - res = await client.mutation(AddEmailTemplate, { params }).toPromise(); - } - setLoading(false); - if (res.error) { - toast({ - title: capitalizeFirstLetter(res.error.message), - isClosable: true, - status: 'error', - position: 'bottom-right', - }); - } else if ( - res.data?._add_email_template || - res.data?._update_email_template - ) { - toast({ - title: capitalizeFirstLetter( - res.data?._add_email_template?.message || - res.data?._update_email_template?.message, - ), - isClosable: true, - status: 'success', - position: 'bottom-right', - }); - setTemplateData({ - ...initTemplateData, - }); - setValidator({ ...initTemplateValidatorData }); - fetchEmailTemplatesData(); - } - }; + const updateTemplate = async (params: emailTemplateDataType) => { + let res: any = {}; + if ( + view === UpdateModalViews.Edit && + selectedTemplate?.[EmailTemplateInputDataFields.ID] + ) { + res = await client + .mutation(EditEmailTemplate, { + params: { + ...params, + id: selectedTemplate[EmailTemplateInputDataFields.ID], + }, + }) + .toPromise(); + } else { + res = await client.mutation(AddEmailTemplate, { params }).toPromise(); + } + setLoading(false); + if (res.error) { + toast({ + title: capitalizeFirstLetter(res.error.message), + isClosable: true, + status: 'error', + position: 'bottom-right', + }); + } else if ( + res.data?._add_email_template || + res.data?._update_email_template + ) { + toast({ + title: capitalizeFirstLetter( + res.data?._add_email_template?.message || + res.data?._update_email_template?.message, + ), + isClosable: true, + status: 'success', + position: 'bottom-right', + }); + setTemplateData({ + ...initTemplateData, + }); + setValidator({ ...initTemplateValidatorData }); + fetchEmailTemplatesData(); + } + }; - const saveData = async () => { - if (!validateData()) return; - setLoading(true); - let params: emailTemplateDataType = { - [EmailTemplateInputDataFields.EVENT_NAME]: - templateData[EmailTemplateInputDataFields.EVENT_NAME], - [EmailTemplateInputDataFields.SUBJECT]: - templateData[EmailTemplateInputDataFields.SUBJECT], - [EmailTemplateInputDataFields.TEMPLATE]: - templateData[EmailTemplateInputDataFields.TEMPLATE], - [EmailTemplateInputDataFields.DESIGN]: '', - }; - if (editor === EmailTemplateEditors.UNLAYER_EDITOR) { - // @ts-ignore - await emailEditorRef.current.editor.exportHtml(async (data) => { - const { design, html } = data; - if (!html || !design) { - setLoading(false); - return; - } - params = { - ...params, - [EmailTemplateInputDataFields.TEMPLATE]: html.trim(), - [EmailTemplateInputDataFields.DESIGN]: JSON.stringify(design), - }; - await updateTemplate(params); - }); - } else { - await updateTemplate(params); - } - view === UpdateModalViews.ADD && onClose(); - }; + const saveData = async () => { + if (!validateData()) return; + setLoading(true); + let params: emailTemplateDataType = { + [EmailTemplateInputDataFields.EVENT_NAME]: + templateData[EmailTemplateInputDataFields.EVENT_NAME], + [EmailTemplateInputDataFields.SUBJECT]: + templateData[EmailTemplateInputDataFields.SUBJECT], + [EmailTemplateInputDataFields.TEMPLATE]: + templateData[EmailTemplateInputDataFields.TEMPLATE], + [EmailTemplateInputDataFields.DESIGN]: '', + }; + if (editor === EmailTemplateEditors.UNLAYER_EDITOR) { + // @ts-ignore + await emailEditorRef.current.editor.exportHtml(async (data) => { + const { design, html } = data; + if (!html || !design) { + setLoading(false); + return; + } + params = { + ...params, + [EmailTemplateInputDataFields.TEMPLATE]: html.trim(), + [EmailTemplateInputDataFields.DESIGN]: JSON.stringify(design), + }; + await updateTemplate(params); + }); + } else { + await updateTemplate(params); + } + view === UpdateModalViews.ADD && onClose(); + }; - const resetData = () => { - if (selectedTemplate) { - setTemplateData(selectedTemplate); - } else { - setTemplateData({ ...initTemplateData }); - } - }; + const resetData = () => { + if (selectedTemplate) { + setTemplateData(selectedTemplate); + } else { + setTemplateData({ ...initTemplateData }); + } + }; - // set template data if edit modal is open - useEffect(() => { - if ( - isOpen && - view === UpdateModalViews.Edit && - selectedTemplate && - Object.keys(selectedTemplate || {}).length - ) { - const { id, created_at, ...rest } = selectedTemplate; - setTemplateData(rest); - } - }, [isOpen]); + // set template data if edit modal is open + useEffect(() => { + if ( + isOpen && + view === UpdateModalViews.Edit && + selectedTemplate && + Object.keys(selectedTemplate || {}).length + ) { + const { id, created_at, ...rest } = selectedTemplate; + setTemplateData(rest); + } + }, [isOpen]); - // set template variables - useEffect(() => { - const updatedTemplateVariables = Object.entries( - emailTemplateVariables, - ).reduce((acc, [key, val]): any => { - if ( - (templateData[EmailTemplateInputDataFields.EVENT_NAME] !== - emailTemplateEventNames['Verify Otp'] && - val === emailTemplateVariables.otp) || - (templateData[EmailTemplateInputDataFields.EVENT_NAME] === - emailTemplateEventNames['Verify Otp'] && - val === emailTemplateVariables.verification_url) - ) { - return acc; - } - return [ - ...acc, - { - text: key, - value: val.value, - description: val.description, - }, - ]; - }, []); - setTemplateVariables(updatedTemplateVariables); - }, [templateData[EmailTemplateInputDataFields.EVENT_NAME]]); + // set template variables + useEffect(() => { + const updatedTemplateVariables = Object.entries( + emailTemplateVariables, + ).reduce((acc, [key, val]): any => { + if ( + (templateData[EmailTemplateInputDataFields.EVENT_NAME] !== + emailTemplateEventNames['Verify Otp'] && + val === emailTemplateVariables.otp) || + (templateData[EmailTemplateInputDataFields.EVENT_NAME] === + emailTemplateEventNames['Verify Otp'] && + val === emailTemplateVariables.verification_url) + ) { + return acc; + } + return [ + ...acc, + { + text: key, + value: val.value, + description: val.description, + }, + ]; + }, []); + setTemplateVariables(updatedTemplateVariables); + }, [templateData[EmailTemplateInputDataFields.EVENT_NAME]]); - // change editor - useEffect(() => { - if (isOpen && selectedTemplate) { - const { design } = selectedTemplate; - if (design) { - setEditor(EmailTemplateEditors.UNLAYER_EDITOR); - } else { - setEditor(EmailTemplateEditors.PLAIN_HTML_EDITOR); - } - } - }, [isOpen, selectedTemplate]); + // change editor + useEffect(() => { + if (isOpen && selectedTemplate) { + const { design } = selectedTemplate; + if (design) { + setEditor(EmailTemplateEditors.UNLAYER_EDITOR); + } else { + setEditor(EmailTemplateEditors.PLAIN_HTML_EDITOR); + } + } + }, [isOpen, selectedTemplate]); - // reset fields when editor is changed - useEffect(() => { - if (selectedTemplate?.design) { - if (editor === EmailTemplateEditors.UNLAYER_EDITOR) { - setTemplateData({ - ...templateData, - [EmailTemplateInputDataFields.TEMPLATE]: selectedTemplate.template, - [EmailTemplateInputDataFields.DESIGN]: selectedTemplate.design, - }); - } else { - setTemplateData({ - ...templateData, - [EmailTemplateInputDataFields.TEMPLATE]: '', - [EmailTemplateInputDataFields.DESIGN]: '', - }); - } - } else if (selectedTemplate?.template) { - if (editor === EmailTemplateEditors.UNLAYER_EDITOR) { - setTemplateData({ - ...templateData, - [EmailTemplateInputDataFields.TEMPLATE]: '', - [EmailTemplateInputDataFields.DESIGN]: '', - }); - } else { - setTemplateData({ - ...templateData, - [EmailTemplateInputDataFields.TEMPLATE]: selectedTemplate?.template, - [EmailTemplateInputDataFields.DESIGN]: '', - }); - } - } - }, [editor]); + // reset fields when editor is changed + useEffect(() => { + if (selectedTemplate?.design) { + if (editor === EmailTemplateEditors.UNLAYER_EDITOR) { + setTemplateData({ + ...templateData, + [EmailTemplateInputDataFields.TEMPLATE]: selectedTemplate.template, + [EmailTemplateInputDataFields.DESIGN]: selectedTemplate.design, + }); + } else { + setTemplateData({ + ...templateData, + [EmailTemplateInputDataFields.TEMPLATE]: '', + [EmailTemplateInputDataFields.DESIGN]: '', + }); + } + } else if (selectedTemplate?.template) { + if (editor === EmailTemplateEditors.UNLAYER_EDITOR) { + setTemplateData({ + ...templateData, + [EmailTemplateInputDataFields.TEMPLATE]: '', + [EmailTemplateInputDataFields.DESIGN]: '', + }); + } else { + setTemplateData({ + ...templateData, + [EmailTemplateInputDataFields.TEMPLATE]: selectedTemplate?.template, + [EmailTemplateInputDataFields.DESIGN]: '', + }); + } + } + }, [editor]); - return ( - <> - {view === UpdateModalViews.ADD ? ( - - ) : ( - Edit - )} - { - resetData(); - onClose(); - }} - size="6xl" - > - - - - {view === UpdateModalViews.ADD - ? 'Add New Email Template' - : 'Edit Email Template'} - - - - - - setIsDynamicVariableInfoOpen(!isDynamicVariableInfoOpen) - } - borderRadius="5" - marginBottom={5} - cursor="pointer" - fontSize="sm" - > - - - - Note: You can add set of dynamic variables to subject - and email body. Click here to see the set of dynamic - variables. - - {isDynamicVariableInfoOpen ? : } - - - - - - - - - - - - - {templateVariables.map((i) => ( - - - - - ))} - -
VariableDescription
- {`{{.${i.text}}}`} - - - {i.description} - -
-
-
- - Event Name - - - - - - Subject - - - - inputChangehandler( - EmailTemplateInputDataFields.SUBJECT, - e.currentTarget.value, - ) - } - /> - - - - - Template Body - - setEditor(value)} - value={editor} - > - - - Plain HTML - - - Unlayer Editor - - - - - - - {editor === EmailTemplateEditors.UNLAYER_EDITOR ? ( - - ) : ( -