- Merge client update into test-beta
Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
@@ -1,266 +1,260 @@
|
||||
import { Button, Divider, Form, Modal, notification, Space } from "antd";
|
||||
import {Button, Divider, Form, Modal, notification, Space} from "antd";
|
||||
import axios from "axios";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { toggleEmailOverlayVisible } from "../../redux/email/email.actions";
|
||||
import {
|
||||
selectEmailConfig,
|
||||
selectEmailVisible,
|
||||
} from "../../redux/email/email.selectors.js";
|
||||
import {
|
||||
selectBodyshop,
|
||||
selectCurrentUser,
|
||||
} from "../../redux/user/user.selectors";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {connect} from "react-redux";
|
||||
import {createStructuredSelector} from "reselect";
|
||||
import {logImEXEvent} from "../../firebase/firebase.utils";
|
||||
import {toggleEmailOverlayVisible} from "../../redux/email/email.actions";
|
||||
import {selectEmailConfig, selectEmailVisible,} from "../../redux/email/email.selectors.js";
|
||||
import {selectBodyshop, selectCurrentUser,} from "../../redux/user/user.selectors";
|
||||
import RenderTemplate from "../../utils/RenderTemplate";
|
||||
import { EmailSettings } from "../../utils/TemplateConstants";
|
||||
import {EmailSettings} from "../../utils/TemplateConstants";
|
||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||
import EmailOverlayComponent from "./email-overlay.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
modalVisible: selectEmailVisible,
|
||||
emailConfig: selectEmailConfig,
|
||||
bodyshop: selectBodyshop,
|
||||
currentUser: selectCurrentUser,
|
||||
modalVisible: selectEmailVisible,
|
||||
emailConfig: selectEmailConfig,
|
||||
bodyshop: selectBodyshop,
|
||||
currentUser: selectCurrentUser,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
toggleEmailOverlayVisible: () => dispatch(toggleEmailOverlayVisible()),
|
||||
toggleEmailOverlayVisible: () => dispatch(toggleEmailOverlayVisible()),
|
||||
});
|
||||
|
||||
export function EmailOverlayContainer({
|
||||
emailConfig,
|
||||
modalVisible,
|
||||
toggleEmailOverlayVisible,
|
||||
bodyshop,
|
||||
currentUser,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [sending, setSending] = useState(false);
|
||||
const [rawHtml, setRawHtml] = useState("");
|
||||
const [pdfCopytoAttach, setPdfCopytoAttach] = useState({
|
||||
filename: null,
|
||||
pdf: null,
|
||||
});
|
||||
const [selectedMedia, setSelectedMedia] = useState([]);
|
||||
emailConfig,
|
||||
modalVisible,
|
||||
toggleEmailOverlayVisible,
|
||||
bodyshop,
|
||||
currentUser,
|
||||
}) {
|
||||
const {t} = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [sending, setSending] = useState(false);
|
||||
const [rawHtml, setRawHtml] = useState("");
|
||||
const [pdfCopytoAttach, setPdfCopytoAttach] = useState({
|
||||
filename: null,
|
||||
pdf: null,
|
||||
});
|
||||
const [selectedMedia, setSelectedMedia] = useState([]);
|
||||
|
||||
const defaultEmailFrom = {
|
||||
from: {
|
||||
name: currentUser.displayName
|
||||
? `${currentUser.displayName} @ ${bodyshop.shopname}`
|
||||
: bodyshop.shopname,
|
||||
address: EmailSettings.fromAddress,
|
||||
},
|
||||
};
|
||||
|
||||
const handleFinish = async (allValues) => {
|
||||
logImEXEvent("email_send_from_modal");
|
||||
|
||||
//const attachments = [];
|
||||
|
||||
// if (values.fileList)
|
||||
// await asyncForEach(values.fileList, async (f) => {
|
||||
// const t = {
|
||||
// ContentType: f.type,
|
||||
// Filename: f.name,
|
||||
// Base64Content: (await toBase64(f.originFileObj)).split(",")[1],
|
||||
// };
|
||||
// attachments.push(t);
|
||||
// });
|
||||
|
||||
const { from, ...values } = allValues;
|
||||
setSending(true);
|
||||
try {
|
||||
await axios.post("/sendemail", {
|
||||
bodyshopid: bodyshop.id,
|
||||
jobid: emailConfig.jobid,
|
||||
|
||||
...defaultEmailFrom,
|
||||
ReplyTo: {
|
||||
Email: from,
|
||||
Name: currentUser.displayName,
|
||||
const defaultEmailFrom = {
|
||||
from: {
|
||||
name: currentUser.displayName
|
||||
? `${currentUser.displayName} @ ${bodyshop.shopname}`
|
||||
: bodyshop.shopname,
|
||||
address: EmailSettings.fromAddress,
|
||||
},
|
||||
...values,
|
||||
html: rawHtml,
|
||||
attachments: [
|
||||
...(values.fileList
|
||||
? await Promise.all(
|
||||
values.fileList.map(async (f) => {
|
||||
return {
|
||||
filename: f.name,
|
||||
path: await toBase64(f.originFileObj),
|
||||
};
|
||||
})
|
||||
)
|
||||
: []),
|
||||
...(pdfCopytoAttach.pdf
|
||||
? [
|
||||
{
|
||||
path: pdfCopytoAttach.pdf,
|
||||
filename:
|
||||
pdfCopytoAttach.filename &&
|
||||
`${pdfCopytoAttach.filename}.pdf`,
|
||||
};
|
||||
|
||||
const handleFinish = async (allValues) => {
|
||||
logImEXEvent("email_send_from_modal");
|
||||
|
||||
//const attachments = [];
|
||||
|
||||
// if (values.fileList)
|
||||
// await asyncForEach(values.fileList, async (f) => {
|
||||
// const t = {
|
||||
// ContentType: f.type,
|
||||
// Filename: f.name,
|
||||
// Base64Content: (await toBase64(f.originFileObj)).split(",")[1],
|
||||
// };
|
||||
// attachments.push(t);
|
||||
// });
|
||||
|
||||
const {from, ...values} = allValues;
|
||||
setSending(true);
|
||||
try {
|
||||
await axios.post("/sendemail", {
|
||||
bodyshopid: bodyshop.id,
|
||||
jobid: emailConfig.jobid,
|
||||
|
||||
...defaultEmailFrom,
|
||||
ReplyTo: {
|
||||
Email: from,
|
||||
Name: currentUser.displayName,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
media: selectedMedia.filter((m) => m.isSelected).map((m) => m.fullsize),
|
||||
//attachments,
|
||||
});
|
||||
notification["success"]({ message: t("emails.successes.sent") });
|
||||
toggleEmailOverlayVisible();
|
||||
} catch (error) {
|
||||
notification["error"]({
|
||||
message: t("emails.errors.notsent", { message: error.message }),
|
||||
});
|
||||
}
|
||||
setSending(false);
|
||||
};
|
||||
...values,
|
||||
html: rawHtml,
|
||||
attachments: [
|
||||
...(values.fileList
|
||||
? await Promise.all(
|
||||
values.fileList.map(async (f) => {
|
||||
return {
|
||||
filename: f.name,
|
||||
path: await toBase64(f.originFileObj),
|
||||
};
|
||||
})
|
||||
)
|
||||
: []),
|
||||
...(pdfCopytoAttach.pdf
|
||||
? [
|
||||
{
|
||||
path: pdfCopytoAttach.pdf,
|
||||
filename:
|
||||
pdfCopytoAttach.filename &&
|
||||
`${pdfCopytoAttach.filename}.pdf`,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
media: selectedMedia.filter((m) => m.isSelected).map((m) => m.fullsize),
|
||||
//attachments,
|
||||
});
|
||||
notification["success"]({message: t("emails.successes.sent")});
|
||||
toggleEmailOverlayVisible();
|
||||
} catch (error) {
|
||||
notification["error"]({
|
||||
message: t("emails.errors.notsent", {message: error.message}),
|
||||
});
|
||||
}
|
||||
setSending(false);
|
||||
};
|
||||
|
||||
const render = async () => {
|
||||
logImEXEvent("email_render_template", { template: emailConfig.template });
|
||||
setLoading(true);
|
||||
let { html, pdf, filename } = await RenderTemplate(
|
||||
emailConfig.template,
|
||||
bodyshop,
|
||||
true
|
||||
);
|
||||
const render = async () => {
|
||||
logImEXEvent("email_render_template", {template: emailConfig.template});
|
||||
setLoading(true);
|
||||
let {html, pdf, filename} = await RenderTemplate(
|
||||
emailConfig.template,
|
||||
bodyshop,
|
||||
true
|
||||
);
|
||||
|
||||
const response = await axios.post("/render/inlinecss", {
|
||||
html: html,
|
||||
url: `${window.location.protocol}://${window.location.host}/`,
|
||||
});
|
||||
setRawHtml(response.data);
|
||||
const response = await axios.post("/render/inlinecss", {
|
||||
html: html,
|
||||
url: `${window.location.protocol}://${window.location.host}/`,
|
||||
});
|
||||
setRawHtml(response.data);
|
||||
|
||||
if (pdf) {
|
||||
setPdfCopytoAttach({ pdf, filename });
|
||||
}
|
||||
if (pdf) {
|
||||
setPdfCopytoAttach({pdf, filename});
|
||||
}
|
||||
|
||||
form.setFieldsValue({
|
||||
from: currentUser.validemail ? currentUser.email : bodyshop.email,
|
||||
...emailConfig.messageOptions,
|
||||
cc:
|
||||
emailConfig.messageOptions.cc &&
|
||||
emailConfig.messageOptions.cc.filter((x) => x),
|
||||
to:
|
||||
emailConfig.messageOptions.to &&
|
||||
emailConfig.messageOptions.to.filter((x) => x),
|
||||
html: response.data,
|
||||
fileList: [],
|
||||
});
|
||||
form.setFieldsValue({
|
||||
from: currentUser.validemail ? currentUser.email : bodyshop.email,
|
||||
...emailConfig.messageOptions,
|
||||
cc:
|
||||
emailConfig.messageOptions.cc &&
|
||||
emailConfig.messageOptions.cc.filter((x) => x),
|
||||
to:
|
||||
emailConfig.messageOptions.to &&
|
||||
emailConfig.messageOptions.to.filter((x) => x),
|
||||
html: response.data,
|
||||
fileList: [],
|
||||
});
|
||||
|
||||
if (
|
||||
bodyshop.md_email_cc[emailConfig.template.name] &&
|
||||
bodyshop.md_email_cc[emailConfig.template.name].length > 0
|
||||
) {
|
||||
form.setFieldsValue({
|
||||
cc: [
|
||||
...(form.getFieldValue("cc") || []),
|
||||
...bodyshop.md_email_cc[emailConfig.template.name],
|
||||
],
|
||||
});
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
if (
|
||||
bodyshop.md_email_cc[emailConfig.template.name] &&
|
||||
bodyshop.md_email_cc[emailConfig.template.name].length > 0
|
||||
) {
|
||||
form.setFieldsValue({
|
||||
cc: [
|
||||
...(form.getFieldValue("cc") || []),
|
||||
...bodyshop.md_email_cc[emailConfig.template.name],
|
||||
],
|
||||
});
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (modalVisible) render();
|
||||
}, [modalVisible]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose={true}
|
||||
visible={modalVisible}
|
||||
maskClosable={false}
|
||||
width={"80%"}
|
||||
onOk={() => form.submit()}
|
||||
title={t("emails.labels.emailpreview")}
|
||||
onCancel={() => {
|
||||
toggleEmailOverlayVisible();
|
||||
}}
|
||||
//closeIcon={() => null}
|
||||
okText={t("general.actions.send")}
|
||||
okButtonProps={{
|
||||
loading: sending,
|
||||
|
||||
disabled:
|
||||
selectedMedia &&
|
||||
(selectedMedia
|
||||
.filter((s) => s.isSelected)
|
||||
.reduce((acc, val) => (acc = acc + val.size), 0) >=
|
||||
10485760 - new Blob([form.getFieldValue("html")]).size ||
|
||||
selectedMedia.filter((s) => s.isSelected).length > 10),
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
// marginTop: "3rem",
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
}}
|
||||
>
|
||||
<Space style={{ alignSelf: "flex-end" }} align="right">
|
||||
<Button
|
||||
onClick={() => {
|
||||
useEffect(() => {
|
||||
if (modalVisible) render();
|
||||
}, [modalVisible]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose={true}
|
||||
open={modalVisible}
|
||||
maskClosable={false}
|
||||
width={"80%"}
|
||||
onOk={() => form.submit()}
|
||||
title={t("emails.labels.emailpreview")}
|
||||
onCancel={() => {
|
||||
toggleEmailOverlayVisible();
|
||||
}}
|
||||
>
|
||||
{t("general.actions.cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
loading={sending}
|
||||
onClick={() => form.submit()}
|
||||
disabled={
|
||||
selectedMedia &&
|
||||
(selectedMedia
|
||||
.filter((s) => s.isSelected)
|
||||
.reduce((acc, val) => (acc = acc + val.size), 0) >=
|
||||
10485760 - new Blob([form.getFieldValue("html")]).size ||
|
||||
selectedMedia.filter((s) => s.isSelected).length > 10)
|
||||
}
|
||||
type="primary"
|
||||
>
|
||||
{t("general.actions.send")}
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
<Form layout="vertical" form={form} onFinish={handleFinish}>
|
||||
{loading && (
|
||||
}}
|
||||
//closeIcon={() => null}
|
||||
okText={t("general.actions.send")}
|
||||
okButtonProps={{
|
||||
loading: sending,
|
||||
disabled:
|
||||
selectedMedia &&
|
||||
(selectedMedia
|
||||
.filter((s) => s.isSelected)
|
||||
.reduce((acc, val) => (acc = acc + val.size), 0) >=
|
||||
10485760 - new Blob([form.getFieldValue("html")]).size ||
|
||||
selectedMedia.filter((s) => s.isSelected).length > 10),
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<LoadingSkeleton />
|
||||
<Divider>{t("emails.labels.preview")}</Divider>
|
||||
<LoadingSpinner message={t("emails.labels.generatingemail")} />
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
// marginTop: "3rem",
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
}}
|
||||
>
|
||||
<Space style={{alignSelf: "flex-end"}} align="right">
|
||||
<Button
|
||||
onClick={() => {
|
||||
toggleEmailOverlayVisible();
|
||||
}}
|
||||
>
|
||||
{t("general.actions.cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
loading={sending}
|
||||
onClick={() => form.submit()}
|
||||
disabled={
|
||||
selectedMedia &&
|
||||
(selectedMedia
|
||||
.filter((s) => s.isSelected)
|
||||
.reduce((acc, val) => (acc = acc + val.size), 0) >=
|
||||
10485760 - new Blob([form.getFieldValue("html")]).size ||
|
||||
selectedMedia.filter((s) => s.isSelected).length > 10)
|
||||
}
|
||||
type="primary"
|
||||
>
|
||||
{t("general.actions.send")}
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
<Form layout="vertical" form={form} onFinish={handleFinish}>
|
||||
{loading && (
|
||||
<div>
|
||||
<LoadingSkeleton/>
|
||||
<Divider>{t("emails.labels.preview")}</Divider>
|
||||
<LoadingSpinner message={t("emails.labels.generatingemail")}/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!loading && (
|
||||
<EmailOverlayComponent
|
||||
form={form}
|
||||
selectedMediaState={[selectedMedia, setSelectedMedia]}
|
||||
/>
|
||||
)}
|
||||
</Form>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
{!loading && (
|
||||
<EmailOverlayComponent
|
||||
form={form}
|
||||
selectedMediaState={[selectedMedia, setSelectedMedia]}
|
||||
/>
|
||||
)}
|
||||
</Form>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(EmailOverlayContainer);
|
||||
|
||||
const toBase64 = (file) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.onerror = (error) => reject(error);
|
||||
});
|
||||
new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.onerror = (error) => reject(error);
|
||||
});
|
||||
|
||||
// const asyncForEach = async (array, callback) => {
|
||||
// for (let index = 0; index < array.length; index++) {
|
||||
|
||||
Reference in New Issue
Block a user