BOD-35 Refactored email screen to use TinyMCE + added templates schema + base level email generation

This commit is contained in:
Patrick Fic
2020-04-16 15:50:07 -07:00
parent 248665aa65
commit c9cafa7ab7
27 changed files with 650 additions and 1639 deletions

View File

@@ -1,12 +1,10 @@
import React from "react";
import { Editor } from "@tinymce/tinymce-react";
import { Input } from "antd";
import CKEditor from "@ckeditor/ckeditor5-react";
import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
import React from "react";
export default function EmailOverlayComponent({
messageOptions,
handleConfigChange,
handleHtmlChange
handleHtmlChange,
}) {
return (
<div>
@@ -27,17 +25,24 @@ export default function EmailOverlayComponent({
onChange={handleConfigChange}
name="subject"
/>
<CKEditor
editor={ClassicEditor}
data={messageOptions.html}
onChange={(event, editor) => {
// handleHtmlChange(editor.getData());
//TODO Ensure that removing onchange never introduces a race condition
}}
onBlur={(event, editor) => {
console.log("Blur.");
handleHtmlChange(editor.getData());
<Editor
value={messageOptions.html}
apiKey="f3s2mjsd77ya5qvqkee9vgh612cm6h41e85efqakn2d0kknk"
init={{
height: 500,
//menubar: false,
encoding: "raw",
extended_valid_elements: "span",
//entity_encoding: "raw",
plugins: [
"advlist autolink lists link image charmap print preview anchor",
"searchreplace visualblocks code fullscreen",
"insertdatetime media table paste code help wordcount",
],
toolbar:
"undo redo | formatselect | bold italic backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | help",
}}
onEditorChange={handleHtmlChange}
/>
</div>
);

View File

@@ -1,104 +1,127 @@
import { useApolloClient } from "@apollo/react-hooks";
import { Modal, notification } from "antd";
import { gql } from "apollo-boost";
import axios from "axios";
import React, { useEffect, useState } from "react";
import { useLazyQuery } from "@apollo/react-hooks";
import ReactDOMServer from "react-dom/server";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { QUERY_TEMPLATES_BY_NAME } from "../../graphql/templates.queries";
import { toggleEmailOverlayVisible } from "../../redux/email/email.actions";
import {
selectEmailConfig,
selectEmailVisible
selectEmailVisible,
} from "../../redux/email/email.selectors.js";
import { selectBodyshop } from "../../redux/user/user.selectors";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import EmailOverlayComponent from "./email-overlay.component";
const mapStateToProps = createStructuredSelector({
modalVisible: selectEmailVisible,
emailConfig: selectEmailConfig
emailConfig: selectEmailConfig,
bodyshop: selectBodyshop,
});
const mapDispatchToProps = dispatch => ({
toggleEmailOverlayVisible: () => dispatch(toggleEmailOverlayVisible())
const mapDispatchToProps = (dispatch) => ({
toggleEmailOverlayVisible: () => dispatch(toggleEmailOverlayVisible()),
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(function EmailOverlayContainer({
export function EmailOverlayContainer({
emailConfig,
modalVisible,
toggleEmailOverlayVisible
toggleEmailOverlayVisible,
bodyshop,
}) {
const { t } = useTranslation();
const [messageOptions, setMessageOptions] = useState(
emailConfig.messageOptions
);
const client = useApolloClient();
useEffect(() => {
setMessageOptions(emailConfig.messageOptions);
}, [setMessageOptions, emailConfig.messageOptions]);
const renderEmail = () => {
client
.query({
query: QUERY_TEMPLATES_BY_NAME,
variables: { name: emailConfig.template.name },
fetchPolicy: "network-only",
})
.then(({ data: templateRecords }) => {
let templateToUse;
if (templateRecords.templates.length === 1) {
console.log("Only 1 Template found.");
templateToUse = templateRecords.templates[0];
} else if (templateRecords.templates.length === 2) {
console.log("2 Templates found..");
templateToUse = templateRecords.templates.filter(
(t) => !!t.bodyshopid
);
} else {
//No template found.Uh oh.
alert("Templating Error!");
}
const [executeQuery, { called, loading, data }] = useLazyQuery(
emailConfig.queryConfig[0],
{
...emailConfig.queryConfig[1],
fetchPolicy: "network-only"
}
);
client
.query({
query: gql(templateToUse.query),
variables: { ...emailConfig.template.variables },
fetchPolicy: "network-only",
})
.then(({ data: contextData }) => {
handleRender(contextData, templateToUse.html);
});
});
};
if (
emailConfig.queryConfig[0] &&
emailConfig.queryConfig[1] &&
modalVisible &&
!called
) {
executeQuery();
}
if (data && !messageOptions.html && emailConfig.template) {
setMessageOptions({
...messageOptions,
html: ReactDOMServer.renderToStaticMarkup(
<emailConfig.template data={data} />
)
});
}
const handleRender = (contextData, html) => {
axios
.post("/render", {
view: html,
context: { ...contextData, bodyshop: bodyshop },
})
.then((r) => {
setMessageOptions({ ...messageOptions, html: r.data });
});
};
const handleOk = () => {
//sendEmail(messageOptions);
axios
.post("/sendemail", messageOptions)
.then(response => {
.then((response) => {
console.log(JSON.stringify(response));
notification["success"]({ message: t("emails.successes.sent") });
toggleEmailOverlayVisible();
})
.catch(error => {
.catch((error) => {
console.log(JSON.stringify(error));
notification["error"]({
message: t("emails.errors.notsent", { message: error.message })
message: t("emails.errors.notsent", { message: error.message }),
});
});
};
const handleConfigChange = event => {
const handleConfigChange = (event) => {
const { name, value } = event.target;
setMessageOptions({ ...messageOptions, [name]: value });
};
const handleHtmlChange = text => {
const handleHtmlChange = (text) => {
setMessageOptions({ ...messageOptions, html: text });
};
useEffect(() => {
if (modalVisible) renderEmail();
}, [modalVisible]); // eslint-disable-line react-hooks/exhaustive-deps
return (
<Modal
destroyOnClose={true}
visible={modalVisible}
width={"80%"}
onOk={handleOk}
onCancel={() => toggleEmailOverlayVisible()}
onCancel={() => {
toggleEmailOverlayVisible();
}}
>
<LoadingSpinner loading={loading}>
<LoadingSpinner loading={false}>
<EmailOverlayComponent
handleConfigChange={handleConfigChange}
messageOptions={messageOptions}
@@ -115,4 +138,8 @@ export default connect(
</LoadingSpinner>
</Modal>
);
});
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(EmailOverlayContainer);