Resolved bulk printing & status for printing items. IO-690

This commit is contained in:
Patrick Fic
2021-02-23 10:34:31 -08:00
parent fad4ee4ef5
commit 666931aacd
6 changed files with 197 additions and 120 deletions

View File

@@ -1,5 +1,6 @@
import { MailOutlined, PrinterOutlined } from "@ant-design/icons";
import React from "react";
import { Spin } from "antd";
import React, { useState } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { setEmailOptions } from "../../redux/email/email.actions";
@@ -22,8 +23,10 @@ export function PrintCenterItemComponent({
bodyshop,
disabled,
}) {
const [loading, setLoading] = useState(false);
const { context } = printCenterModal;
const renderToNewWindow = async () => {
setLoading(true);
await GenerateDocument(
{
name: item.key,
@@ -32,6 +35,7 @@ export function PrintCenterItemComponent({
{},
"p"
);
setLoading(false);
};
if (disabled) return <li className="print-center-item">{item.title} </li>;
@@ -51,6 +55,7 @@ export function PrintCenterItemComponent({
);
}}
/>
{loading && <Spin size="small" />}
</li>
);
}

View File

@@ -1,11 +1,11 @@
import { Button, List, Typography } from "antd";
import React from "react";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { GenerateDocuments } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
const mapStateToProps = createStructuredSelector({
@@ -16,26 +16,19 @@ const mapDispatchToProps = (dispatch) => ({
});
export function PrintCenterSpeedPrint({ bodyshop, jobId }) {
const [loading, setLoading] = useState(false);
const { speedprint } = bodyshop;
const { t } = useTranslation();
const renderTemplate = async (templateKey) => {
logImEXEvent("speed_print_template_render");
GenerateDocument(
{
name: templateKey,
variables: { id: jobId },
},
{},
"p"
);
};
const renderAllTemplates = (templateKeys) => {
const renderAllTemplates = async (templateKeys) => {
logImEXEvent("speed_print_render_all_templates");
templateKeys.forEach((templateKey) => renderTemplate(templateKey));
setLoading(true);
await GenerateDocuments(
templateKeys.map((key) => {
return { name: key, variables: { id: jobId } };
})
);
setLoading(false);
};
return (
@@ -50,7 +43,10 @@ export function PrintCenterSpeedPrint({ bodyshop, jobId }) {
renderItem={(sp) => (
<List.Item
actions={[
<Button onClick={() => renderAllTemplates(sp.templates)}>
<Button
loading={loading}
onClick={() => renderAllTemplates(sp.templates)}
>
Print All
</Button>,
]}

View File

@@ -50,7 +50,7 @@ export function ShopTemplateTestRender({
view: inlineHtml.data,
context: { ...contextData, bodyshop: bodyshop },
});
displayTemplateInWindowNoprint(renderResponse.data);
// displayTemplateInWindowNoprint(renderResponse.data);
setLoading(false);
} catch (error) {

View File

@@ -1,16 +1,14 @@
import React from "react";
import { Statistic, Space, List, Button, Typography } from "antd";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
import { useTranslation } from "react-i18next";
import { Button, List, Space, Statistic, Typography } from "antd";
import moment from "moment";
import RenderTemplate, {
displayTemplateInWindow,
} from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { onlyUnique } from "../../utils/arrayHelper";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -68,15 +66,14 @@ export function TimeTicketsSummaryEmployees({
});
const handlePrintEmployeeTicket = async (empId) => {
alert("Missing Key!");
const html = await RenderTemplate(
GenerateDocument(
{
name: TemplateList().time_tickets_by_employee.key,
variables: { id: empId, start: startDate, end: endDate },
},
bodyshop
{},
"p"
);
displayTemplateInWindow(html);
};
return (

View File

@@ -1,3 +1,4 @@
import { notification } from "antd";
import axios from "axios";
import gql from "graphql-tag";
import jsreport from "jsreport-browser-client-dist";
@@ -5,16 +6,149 @@ import { auth } from "../firebase/firebase.utils";
import { setEmailOptions } from "../redux/email/email.actions";
import { store } from "../redux/store";
import client from "../utils/GraphQLClient";
import { TemplateList } from "./TemplateConstants";
const server = process.env.REACT_APP_REPORTS_SERVER_URL;
jsreport.serverUrl = server;
const Templates = TemplateList();
export default async function RenderTemplate(
templateObject,
bodyshop,
renderAsHtml = false
) {
//Query assets that match the template name. Must be in format <<templateName>>.query
let { contextData, useShopSpecificTemplate } = await fetchContextData(
templateObject
);
let reportRequest = {
template: {
name: useShopSpecificTemplate
? `/${bodyshop.imexshopid}/${templateObject.name}`
: `/${templateObject.name}`,
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
},
data: {
...contextData,
...templateObject.variables,
...templateObject.context,
headerpath: `/${bodyshop.imexshopid}/header.html`,
bodyshop: bodyshop,
},
};
try {
const render = await jsreport.renderAsync(reportRequest);
if (!renderAsHtml) {
render.download(Templates[templateObject.name].title || "");
} else {
return new Promise((resolve, reject) => {
resolve(render.toString());
});
}
} catch (error) {
notification["error"]({ message: JSON.stringify(error) });
}
}
export async function RenderTemplates(
templateObjects,
bodyshop,
renderAsHtml = false
) {
//Query assets that match the template name. Must be in format <<templateName>>.query
let templateAndData = [];
let proms = [];
templateObjects.forEach((template) => {
proms.push(
(async () => {
let { contextData, useShopSpecificTemplate } = await fetchContextData(
template
);
templateAndData.push({
templateObject: template,
contextData,
useShopSpecificTemplate,
});
})()
);
});
await Promise.all(proms);
let rootTemplate = templateAndData.shift();
let reportRequest = {
template: {
name: rootTemplate.useShopSpecificTemplate
? `/${bodyshop.imexshopid}/${rootTemplate.templateObject.name}`
: `/${rootTemplate.templateObject.name}`,
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
pdfOperations: templateAndData.map((template) => {
return {
template: {
name: template.useShopSpecificTemplate
? `/${bodyshop.imexshopid}/${template.templateObject.name}`
: `/${template.templateObject.name}`,
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
},
data: {
...template.contextData,
...template.templateObject.variables,
...template.templateObject.context,
headerpath: `/${bodyshop.imexshopid}/header.html`,
bodyshop: bodyshop,
},
type: "append",
mergeWholeDocument: true,
renderForEveryPage: true,
};
}),
},
data: {
...rootTemplate.contextData,
...rootTemplate.templateObject.variables,
...rootTemplate.templateObject.context,
headerpath: `/${bodyshop.imexshopid}/header.html`,
bodyshop: bodyshop,
},
};
console.log("reportRequest", reportRequest);
try {
const render = await jsreport.renderAsync(reportRequest);
if (!renderAsHtml) {
render.download("Speed Print");
} else {
return new Promise((resolve, reject) => {
resolve(render.toString());
});
}
} catch (error) {
notification["error"]({ message: JSON.stringify(error) });
}
}
export const GenerateDocument = async (template, messageOptions, sendType) => {
const bodyshop = store.getState().user.bodyshop;
if (sendType === "e") {
store.dispatch(
setEmailOptions({
messageOptions,
template,
})
);
} else {
await RenderTemplate(template, bodyshop);
}
};
export const GenerateDocuments = async (templates) => {
const bodyshop = store.getState().user.bodyshop;
await RenderTemplates(templates, bodyshop);
};
const fetchContextData = async (templateObject) => {
jsreport.headers["Authorization"] =
"Bearer " + (await auth.currentUser.getIdToken());
@@ -44,7 +178,7 @@ export default async function RenderTemplate(
"There are too many queries to choose from. Please ensure there are no conflicting keys."
);
}
let contextData;
let contextData = {};
if (templateQueryToExecute) {
const { data } = await client.query({
query: gql(templateQueryToExecute),
@@ -54,83 +188,37 @@ export default async function RenderTemplate(
contextData = data;
}
let reportRequest = {
template: {
name: useShopSpecificTemplate
? `/${bodyshop.imexshopid}/${templateObject.name}`
: `/${templateObject.name}`,
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
},
data: {
...(templateQueryToExecute ? contextData : {}),
...templateObject.variables,
...templateObject.context,
headerpath: `/${bodyshop.imexshopid}/header.html`,
bodyshop: bodyshop,
},
};
const render = await jsreport.renderAsync(reportRequest);
if (!renderAsHtml) {
render.download();
// var html =
// "<html>" +
// "<style>html,body {padding:0;margin:0;} iframe {width:100%;height:100%;border:0}</style>" +
// "<body>" +
// '<iframe type="application/pdf" src="' +
// render.toDataURI() +
// '"></iframe>' +
// "</body></html>";
// displayTemplateInWindowNoprint(html);
} else {
return new Promise((resolve, reject) => {
resolve(render.toString());
});
}
}
export const displayTemplateInWindow = (html) => {
try {
var newWin = window.open("", "_blank", "toolbar=0,location=0,menubar=0");
newWin.document.write(html);
setTimeout(function () {
newWin.document.close();
newWin.focus();
newWin.print();
newWin.close();
}, 500);
} catch (error) {
console.log("Unable to write to new window.", error);
}
return { contextData, useShopSpecificTemplate };
};
export const displayTemplateInWindowNoprint = (html) => {
try {
var newWin = window.open("", "_blank", "toolbar=0,location=0,menubar=0");
newWin.document.write(html);
//export const displayTemplateInWindow = (html) => {
// try {
// var newWin = window.open("", "_blank", "toolbar=0,location=0,menubar=0");
// newWin.document.write(html);
setTimeout(function () {
newWin.document.close();
newWin.focus();
//newWin.print();
//newWin.close();
}, 500);
} catch (error) {
console.log("Unable to write to new window.", error);
}
};
// setTimeout(function () {
// newWin.document.close();
// newWin.focus();
// newWin.print();
// newWin.close();
// }, 500);
// } catch (error) {
// console.log("Unable to write to new window.", error);
// }
// };
export const GenerateDocument = async (template, messageOptions, sendType) => {
const bodyshop = store.getState().user.bodyshop;
if (sendType === "e") {
store.dispatch(
setEmailOptions({
messageOptions,
template,
})
);
} else {
await RenderTemplate(template, bodyshop);
}
};
// export const displayTemplateInWindowNoprint = (html) => {
// try {
// var newWin = window.open("", "_blank", "toolbar=0,location=0,menubar=0");
// newWin.document.write(html);
// setTimeout(function () {
// newWin.document.close();
// newWin.focus();
// //newWin.print();
// //newWin.close();
// }, 500);
// } catch (error) {
// console.log("Unable to write to new window.", error);
// }
// };

View File

@@ -12,15 +12,6 @@ export const TemplateList = (type, context) => {
//If there's no type or the type is job, send it back.
...(!type || type === "job"
? {
estimate_detail: {
title: i18n.t("printcenter.jobs.estimate_detail"),
description: "Est Detail",
subject: `${i18n.t("printcenter.jobs.estimate_detail")} - ${
context && context.job && context.job.ro_number
}`,
key: "estimate_detail",
disabled: false,
},
casl_authorization: {
title: i18n.t("printcenter.jobs.casl_authorization"),
description: "CASL Authorization",
@@ -209,7 +200,7 @@ export const TemplateList = (type, context) => {
title: i18n.t("printcenter.jobs.parts_order"),
description: "Parts Order",
key: "parts_order",
subject: `${bodyshop.shopname} Parts Order ${
subject: `${bodyshop && bodyshop.shopname} Parts Order ${
(context &&
context &&
context.job &&