Rebuild printable roast plans and remove machine-based adjustments
Test and deploy / test-and-deploy (push) Successful in 2m28s
Test and deploy / test-and-deploy (push) Successful in 2m28s
This commit is contained in:
1 parent
e9f2393c96
commit
824a964f9d
30 files changed
+1721
-908
No files matched your search
+63
-29
@@ -1,32 +1,66 @@
|
||||
// Bakes live input values into their sibling .pv span before printing (so text doesn't clip
|
||||
// at a fixed .f width the way a raw <input> would), then clears them after. One DOM, one
|
||||
// rendering — see app.css's @media print block for the corresponding display swap.
|
||||
//
|
||||
// Operates on #print-sheet (not the passed-in screen `form`): the print worksheet lives
|
||||
// outside #plan-form on purpose, so its inputs are addressed by container id instead.
|
||||
|
||||
export function initPrint({ beforePrint }) {
|
||||
document.getElementById("btn-print").addEventListener("click", () => window.print());
|
||||
|
||||
import {
|
||||
renderReportBody,
|
||||
renderReportHtml,
|
||||
REPORT_CSS,
|
||||
} from "/shared/report.js?v=__ASSET_VERSION__";
|
||||
export function initPrint({ getPlan, getName }) {
|
||||
const style = document.createElement("style");
|
||||
style.textContent =
|
||||
REPORT_CSS +
|
||||
"\n#report-print{display:none}@media print{body>*:not(#report-print){display:none!important}#report-print{display:block!important}}";
|
||||
document.head.append(style);
|
||||
const mount = document.createElement("div");
|
||||
mount.id = "report-print";
|
||||
document.body.append(mount);
|
||||
window.addEventListener("beforeprint", () => {
|
||||
beforePrint?.(); // re-sync the print worksheet's inputs from state.plan before baking
|
||||
bakeValues();
|
||||
mount.innerHTML = renderReportBody(getPlan(), getName());
|
||||
});
|
||||
window.addEventListener("afterprint", () => mount.replaceChildren());
|
||||
const print = document.getElementById("btn-print");
|
||||
print.addEventListener("click", () => window.print());
|
||||
const download = document.createElement("button");
|
||||
download.type = "button";
|
||||
download.className = "ghost-btn";
|
||||
download.textContent = "Download HTML";
|
||||
download.addEventListener("click", () => {
|
||||
const url = URL.createObjectURL(
|
||||
new Blob([renderReportHtml(getPlan(), getName())], {
|
||||
type: "text/html;charset=utf-8",
|
||||
}),
|
||||
);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download =
|
||||
(getName() || getPlan().fields?.["0.1"] || "roast-plan").replace(
|
||||
/[^a-z0-9_-]+/gi,
|
||||
"-",
|
||||
) + ".html";
|
||||
document.body.append(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
||||
});
|
||||
print.after(download);
|
||||
const preview = document.createElement("button");
|
||||
preview.type = "button";
|
||||
preview.className = "ghost-btn";
|
||||
preview.textContent = "Preview report";
|
||||
download.after(preview);
|
||||
const dialog = document.createElement("dialog");
|
||||
dialog.style.cssText =
|
||||
"width: min(1000px,96vw);height:90vh;padding:12px;border:1px solid #ccc;border-radius:12px";
|
||||
const close = document.createElement("button");
|
||||
close.type = "button";
|
||||
close.textContent = "Close preview";
|
||||
close.addEventListener("click", () => dialog.close());
|
||||
const frame = document.createElement("iframe");
|
||||
frame.title = "Printable roast report";
|
||||
frame.setAttribute("sandbox", "");
|
||||
frame.style.cssText = "width:100%;height:calc(100% - 40px);border:0";
|
||||
dialog.append(close, frame);
|
||||
document.body.append(dialog);
|
||||
preview.addEventListener("click", () => {
|
||||
frame.srcdoc = renderReportHtml(getPlan(), getName());
|
||||
dialog.showModal();
|
||||
});
|
||||
window.addEventListener("afterprint", () => clearBaked());
|
||||
}
|
||||
|
||||
function printSheet() {
|
||||
return document.getElementById("print-sheet");
|
||||
}
|
||||
|
||||
function bakeValues() {
|
||||
for (const el of printSheet().querySelectorAll("input.ws-input, textarea.ws-input")) {
|
||||
if (el.type === "radio" || el.type === "checkbox") continue;
|
||||
const pv = el.nextElementSibling;
|
||||
if (pv && pv.classList.contains("pv")) pv.textContent = el.value || "";
|
||||
}
|
||||
}
|
||||
|
||||
function clearBaked() {
|
||||
for (const pv of printSheet().querySelectorAll(".pv")) pv.textContent = "";
|
||||
}
|
||||
Reference in new issue
Block a user