6
client/package-lock.json
generated
6
client/package-lock.json
generated
@@ -24,6 +24,7 @@
|
|||||||
"antd": "^5.20.0",
|
"antd": "^5.20.0",
|
||||||
"axios": "^1.7.3",
|
"axios": "^1.7.3",
|
||||||
"flag-icons": "^7.2.3",
|
"flag-icons": "^7.2.3",
|
||||||
|
"html-to-image": "^1.11.11",
|
||||||
"i18next": "^23.12.2",
|
"i18next": "^23.12.2",
|
||||||
"i18next-browser-languagedetector": "^8.0.0",
|
"i18next-browser-languagedetector": "^8.0.0",
|
||||||
"i18next-http-backend": "^2.5.2",
|
"i18next-http-backend": "^2.5.2",
|
||||||
@@ -5497,6 +5498,11 @@
|
|||||||
"void-elements": "3.1.0"
|
"void-elements": "3.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/html-to-image": {
|
||||||
|
"version": "1.11.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz",
|
||||||
|
"integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA=="
|
||||||
|
},
|
||||||
"node_modules/htmlparser2": {
|
"node_modules/htmlparser2": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"antd": "^5.20.0",
|
"antd": "^5.20.0",
|
||||||
"axios": "^1.7.3",
|
"axios": "^1.7.3",
|
||||||
"flag-icons": "^7.2.3",
|
"flag-icons": "^7.2.3",
|
||||||
|
"html-to-image": "^1.11.11",
|
||||||
"i18next": "^23.12.2",
|
"i18next": "^23.12.2",
|
||||||
"i18next-browser-languagedetector": "^8.0.0",
|
"i18next-browser-languagedetector": "^8.0.0",
|
||||||
"i18next-http-backend": "^2.5.2",
|
"i18next-http-backend": "^2.5.2",
|
||||||
|
|||||||
@@ -99,7 +99,8 @@
|
|||||||
"deleteSettings": "Delete Current Preset",
|
"deleteSettings": "Delete Current Preset",
|
||||||
"deleteSettingsConfirm": "Are you sure you want to delete this preset?",
|
"deleteSettingsConfirm": "Are you sure you want to delete this preset?",
|
||||||
"settingsName": "Preset Name",
|
"settingsName": "Preset Name",
|
||||||
"saveSetting": "Save Presets"
|
"saveSetting": "Save Presets",
|
||||||
|
"saveAsImage": "Save as Image"
|
||||||
},
|
},
|
||||||
"qrcode": {
|
"qrcode": {
|
||||||
"button": "Print Labels",
|
"button": "Print Labels",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { PrinterOutlined } from "@ant-design/icons";
|
import { FileImageOutlined, PrinterOutlined } from "@ant-design/icons";
|
||||||
import { useTranslate } from "@refinedev/core";
|
import { useTranslate } from "@refinedev/core";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
Slider,
|
Slider,
|
||||||
Space,
|
Space,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
|
import * as htmlToImage from "html-to-image";
|
||||||
import React, { useRef } from "react";
|
import React, { useRef } from "react";
|
||||||
import ReactToPrint from "react-to-print";
|
import ReactToPrint from "react-to-print";
|
||||||
import { useSavedState } from "../../utils/saveload";
|
import { useSavedState } from "../../utils/saveload";
|
||||||
@@ -119,6 +120,7 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={itemIdx}
|
key={itemIdx}
|
||||||
|
className="print-page-item"
|
||||||
style={{
|
style={{
|
||||||
width: `${itemWidth}mm`,
|
width: `${itemWidth}mm`,
|
||||||
height: `${itemHeight}mm`,
|
height: `${itemHeight}mm`,
|
||||||
@@ -175,6 +177,30 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const saveAsImage = () => {
|
||||||
|
const hasPrinted: Element[] = [];
|
||||||
|
|
||||||
|
Array.from(document.getElementsByClassName("print-qrcode-item")).forEach(async (item) => {
|
||||||
|
// Prevent printing copies
|
||||||
|
for (let i = 0; i < hasPrinted.length; i += 1) {
|
||||||
|
if (item.isEqualNode(hasPrinted[i])) return;
|
||||||
|
}
|
||||||
|
hasPrinted.push(item);
|
||||||
|
|
||||||
|
// Generate png image
|
||||||
|
const url = await htmlToImage.toPng(item as HTMLElement, {
|
||||||
|
backgroundColor: "#FFF",
|
||||||
|
cacheBust: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Download image
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = url;
|
||||||
|
link.download = "spoolmanlabel.png";
|
||||||
|
link.click();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
@@ -788,6 +814,9 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
|
|||||||
<Col>
|
<Col>
|
||||||
<Space>
|
<Space>
|
||||||
{extraButtons}
|
{extraButtons}
|
||||||
|
<Button type="primary" icon={<FileImageOutlined />} size="large" onClick={saveAsImage}>
|
||||||
|
{t("printing.generic.saveAsImage")}
|
||||||
|
</Button>
|
||||||
<ReactToPrint
|
<ReactToPrint
|
||||||
key="print-button"
|
key="print-button"
|
||||||
trigger={() => (
|
trigger={() => (
|
||||||
|
|||||||
Reference in New Issue
Block a user