Resolved bulk printing & status for printing items. IO-690
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>,
|
||||
]}
|
||||
|
||||
@@ -50,7 +50,7 @@ export function ShopTemplateTestRender({
|
||||
view: inlineHtml.data,
|
||||
context: { ...contextData, bodyshop: bodyshop },
|
||||
});
|
||||
displayTemplateInWindowNoprint(renderResponse.data);
|
||||
// displayTemplateInWindowNoprint(renderResponse.data);
|
||||
|
||||
setLoading(false);
|
||||
} catch (error) {
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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);
|
||||
// }
|
||||
// };
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
Reference in New Issue
Block a user