Client: Replaced block-system with safe-zone

This commit is contained in:
Donkie
2023-08-10 21:40:30 +02:00
parent ec80973f96
commit 3f18c32c8a
4 changed files with 214 additions and 304 deletions

3
client/.prettierrc Normal file
View File

@@ -0,0 +1,3 @@
{
"printWidth": 120
}

View File

@@ -56,7 +56,7 @@
"printing": {
"generic": {
"title": "Printing",
"description": "Tune in the settings below to get the desired print layout. Keep in mind that printers and your OS may apply it's own margins and scaling, so you may need to adjust the settings accordingly. Test it on a piece of regular paper before printing on the actual labels.",
"description": "Tune in the settings below to get the desired print layout. Keep in mind that printers and your OS may apply it's own margins and scaling, so you may need to perform some trial-and-error before it's all correct. Test it on a piece of regular paper before printing on the actual labels.\nThe \"Margin\" fields should be configured to match your label paper and printer, changing these will affect the size of the entire grid.\nThe \"Safe-Zone\" fields should be set to how close to the paper edge your printer can print, changing these will not affect the entire grid.",
"print": "Print",
"columns": "Columns",
"rows": "Rows",
@@ -67,6 +67,10 @@
"marginRight": "Right Margin",
"marginTop": "Top Margin",
"marginBottom": "Bottom Margin",
"printerMarginLeft": "Safe-Zone Left",
"printerMarginRight": "Safe-Zone Right",
"printerMarginTop": "Safe-Zone Top",
"printerMarginBottom": "Safe-Zone Bottom",
"blockRowsTop": "Block Rows Top",
"blockRowsBottom": "Block Rows Bottom",
"blockColumnsLeft": "Block Columns Left",

View File

@@ -1,17 +1,5 @@
import React, { useRef } from "react";
import {
Modal,
Slider,
Button,
Select,
Row,
Col,
Form,
Divider,
RadioChangeEvent,
Radio,
InputNumber,
} from "antd";
import { Modal, Slider, Button, Select, Row, Col, Form, Divider, RadioChangeEvent, Radio, InputNumber } from "antd";
import ReactToPrint from "react-to-print";
import { useSavedState } from "../../utils/saveload";
import { useTranslate } from "@refinedev/core";
@@ -57,120 +45,69 @@ const paperDimensions: { [key: string]: PaperDimensions } = {
},
};
const PrintingDialog: React.FC<PrintingDialogProps> = ({
items,
style,
extraSettings,
visible,
onCancel,
title,
}) => {
const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSettings, visible, onCancel, title }) => {
const t = useTranslate();
const [marginLeft, setMarginLeft] = useSavedState("print-marginLeft", 10);
const [marginTop, setMarginTop] = useSavedState("print-marginTop", 10);
const [marginRight, setMarginRight] = useSavedState("print-marginRight", 10);
const [marginBottom, setMarginBottom] = useSavedState(
"print-marginBottom",
10
);
const [blockRowsTop, setBlockRowsTop] = useSavedState(
"print-blockRowsTop",
0
);
const [blockRowsBottom, setBlockRowsBottom] = useSavedState(
"print-blockRowsBottom",
0
);
const [blockColumnsLeft, setBlockColumnsLeft] = useSavedState(
"print-blockColumnsLeft",
0
);
const [blockColumnsRight, setBlockColumnsRight] = useSavedState(
"print-blockColumnsRight",
0
);
const [marginBottom, setMarginBottom] = useSavedState("print-marginBottom", 10);
const [printerMarginLeft, setPrinterMarginLeft] = useSavedState("print-printerMarginLeft", 5);
const [printerMarginTop, setPrinterMarginTop] = useSavedState("print-printerMarginTop", 5);
const [printerMarginRight, setPrinterMarginRight] = useSavedState("print-printerMarginRight", 5);
const [printerMarginBottom, setPrinterMarginBottom] = useSavedState("print-printerMarginBottom", 5);
const [paperColumns, setPaperColumns] = useSavedState("print-itemsPerRow", 3);
const [paperRows, setPaperRows] = useSavedState("print-rowsPerPage", 8);
const [paperSize, setPaperSize] = useSavedState("print-paperSize", "A4");
const [previewScale, setPreviewScale] = useSavedState(
"print-previewScale",
0.6
);
const [borderShowMode, setBorderShowMode] = useSavedState<
"none" | "border" | "grid"
>("print-borderShowMode", "grid");
const [previewScale, setPreviewScale] = useSavedState("print-previewScale", 0.6);
const [borderShowMode, setBorderShowMode] = useSavedState<"none" | "border" | "grid">("print-borderShowMode", "grid");
const paperWidth = paperDimensions[paperSize].width;
const paperHeight = paperDimensions[paperSize].height;
const printRef = useRef<HTMLDivElement>(null);
const calculatedRowHeight =
(paperHeight - marginTop - marginBottom) / paperRows;
const calculatedRowHeight = (paperHeight - marginTop - marginBottom) / paperRows;
const itemsPerRow = paperColumns - blockColumnsLeft - blockColumnsRight;
const rowsPerPage = paperRows - blockRowsTop - blockRowsBottom;
const itemsPerRow = paperColumns;
const rowsPerPage = paperRows;
const rowsOfItems = [];
for (let row_idx = 0; row_idx <= items.length / itemsPerRow; row_idx += 1) {
rowsOfItems.push(
items.slice(row_idx * itemsPerRow, (row_idx + 1) * itemsPerRow)
);
rowsOfItems.push(items.slice(row_idx * itemsPerRow, (row_idx + 1) * itemsPerRow));
}
const pageBlocks = [];
for (
let page_idx = 0;
page_idx <= rowsOfItems.length / rowsPerPage;
page_idx += 1
) {
pageBlocks.push(
rowsOfItems.slice(page_idx * rowsPerPage, (page_idx + 1) * rowsPerPage)
);
for (let page_idx = 0; page_idx <= rowsOfItems.length / rowsPerPage; page_idx += 1) {
pageBlocks.push(rowsOfItems.slice(page_idx * rowsPerPage, (page_idx + 1) * rowsPerPage));
}
const pages = pageBlocks.map(function (rows, idx) {
const itemRowsBlockTop = [...Array(blockRowsTop).keys()].map((row) => (
<tr key={row}>
<td>
<div style={{ height: `${calculatedRowHeight}mm` }}></div>
</td>
</tr>
));
const itemRows = rows.map((row, idx) => {
const itemColumnsBlockLeft = [...Array(blockColumnsLeft).keys()].map(
(col) => (
<td key={col}>
<div
style={{
width: `${
(paperWidth - marginLeft - marginRight) / paperColumns
}mm`,
}}
></div>
</td>
)
);
const pages = pageBlocks.map(function (rows, pageIdx) {
const itemRows = rows.map((row, rowIdx) => {
return (
<tr key={idx}>
{itemColumnsBlockLeft}
{row.map((item, index) => (
<td>
<div
key={index}
style={{
width: `${
(paperWidth - marginLeft - marginRight) / paperColumns
}mm`,
height: `${calculatedRowHeight}mm`,
border: borderShowMode === "grid" ? "1px solid #000" : "none",
}}
>
{item}
</div>
</td>
))}
<tr key={rowIdx}>
{row.map(function (item, colIdx) {
return (
<td>
<div
key={colIdx}
style={{
width: `${(paperWidth - marginLeft - marginRight) / paperColumns}mm`,
height: `${calculatedRowHeight}mm`,
border: borderShowMode === "grid" ? "1px solid #000" : "none",
paddingLeft: colIdx === 0 ? `${Math.max(printerMarginLeft - marginLeft, 0)}mm` : 0,
paddingRight:
colIdx === paperColumns - 1 ? `${Math.max(printerMarginRight - marginRight, 0)}mm` : 0,
paddingTop: rowIdx === 0 ? `${Math.max(printerMarginTop - marginTop, 0)}mm` : 0,
paddingBottom:
rowIdx === paperRows - 1 ? `${Math.max(printerMarginBottom - marginBottom, 0)}mm` : 0,
}}
>
{item}
</div>
</td>
);
})}
</tr>
);
});
@@ -178,7 +115,7 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
return (
<div
className="print-page"
key={idx}
key={pageIdx}
style={{
width: `${paperWidth}mm`,
height: `${paperHeight}mm`,
@@ -192,18 +129,10 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
border: borderShowMode !== "none" ? "1px solid #000" : "none",
height: `${paperHeight - marginTop - marginBottom}mm`,
width: `${paperWidth - marginLeft - marginRight}mm`,
marginTop: `calc(${marginTop}mm - ${
borderShowMode !== "none" ? "1px" : "0px"
})`,
marginLeft: `calc(${marginLeft}mm - ${
borderShowMode !== "none" ? "1px" : "0px"
})`,
marginRight: `calc(${marginRight}mm - ${
borderShowMode !== "none" ? "1px" : "0px"
})`,
marginBottom: `calc(${marginBottom}mm - ${
borderShowMode !== "none" ? "1px" : "0px"
})`,
marginTop: `calc(${marginTop}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`,
marginLeft: `calc(${marginLeft}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`,
marginRight: `calc(${marginRight}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`,
marginBottom: `calc(${marginBottom}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`,
}}
>
<table
@@ -211,7 +140,6 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
alignContent: "flex-start",
}}
>
{itemRowsBlockTop}
{itemRows}
</table>
</div>
@@ -227,16 +155,22 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
footer={[
<ReactToPrint
key="print-button"
trigger={() => (
<Button type="primary">{t("printing.generic.print")}</Button>
)}
trigger={() => <Button type="primary">{t("printing.generic.print")}</Button>}
content={() => printRef.current}
/>,
]}
width={1200} // Set the modal width to accommodate the preview
>
<Row gutter={16}>
<Col span={24}>{t("printing.generic.description")}</Col>
<Col
span={24}
style={{
whiteSpace: "pre-line",
marginBottom: "1em",
}}
>
{t("printing.generic.description")}
</Col>
<Col span={14}>
<div
style={{
@@ -286,13 +220,7 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
</div>
</Col>
<Col span={10}>
<Form
labelAlign="left"
colon={false}
labelWrap={true}
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
>
<Form labelAlign="left" colon={false} labelWrap={true} labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
<Form.Item label={t("printing.generic.marginLeft")}>
<Row>
<Col span={12}>
@@ -401,6 +329,114 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
</Col>
</Row>
</Form.Item>
<Form.Item label={t("printing.generic.printerMarginLeft")}>
<Row>
<Col span={12}>
<Slider
min={0}
max={50}
step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }}
value={printerMarginLeft}
onChange={(value) => {
setPrinterMarginLeft(value);
}}
/>
</Col>
<Col span={12}>
<InputNumber
step={0.1}
style={{ margin: "0 16px" }}
value={printerMarginLeft}
addonAfter="mm"
onChange={(value) => {
setPrinterMarginLeft(value ?? 0);
}}
/>
</Col>
</Row>
</Form.Item>
<Form.Item label={t("printing.generic.printerMarginTop")}>
<Row>
<Col span={12}>
<Slider
min={0}
max={50}
step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }}
value={printerMarginTop}
onChange={(value) => {
setPrinterMarginTop(value);
}}
/>
</Col>
<Col span={12}>
<InputNumber
step={0.1}
style={{ margin: "0 16px" }}
value={printerMarginTop}
addonAfter="mm"
onChange={(value) => {
setPrinterMarginTop(value ?? 0);
}}
/>
</Col>
</Row>
</Form.Item>
<Form.Item label={t("printing.generic.printerMarginRight")}>
<Row>
<Col span={12}>
<Slider
min={0}
max={50}
step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }}
value={printerMarginRight}
onChange={(value) => {
setPrinterMarginRight(value);
}}
/>
</Col>
<Col span={12}>
<InputNumber
step={0.1}
style={{ margin: "0 16px" }}
value={printerMarginRight}
addonAfter="mm"
onChange={(value) => {
setPrinterMarginRight(value ?? 0);
}}
/>
</Col>
</Row>
</Form.Item>
<Form.Item label={t("printing.generic.printerMarginBottom")}>
<Row>
<Col span={12}>
<Slider
min={0}
max={50}
step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }}
value={printerMarginBottom}
onChange={(value) => {
setPrinterMarginBottom(value);
}}
/>
</Col>
<Col span={12}>
<InputNumber
step={0.1}
style={{ margin: "0 16px" }}
value={printerMarginBottom}
addonAfter="mm"
onChange={(value) => {
setPrinterMarginBottom(value ?? 0);
}}
/>
</Col>
</Row>
</Form.Item>
<Form.Item label={t("printing.generic.columns")}>
<Row>
<Col span={12}>
@@ -409,8 +445,6 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
max={5}
value={paperColumns}
onChange={(value) => {
if (value - blockColumnsLeft - blockColumnsRight < 1)
return;
setPaperColumns(value);
}}
/>
@@ -421,11 +455,6 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
style={{ margin: "0 16px" }}
value={paperColumns}
onChange={(value) => {
if (
(value ?? 1) - blockColumnsLeft - blockColumnsRight <
1
)
return;
setPaperColumns(value ?? 1);
}}
/>
@@ -440,7 +469,6 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
max={15}
value={paperRows}
onChange={(value) => {
if (value - blockRowsTop - blockRowsBottom < 1) return;
setPaperRows(value);
}}
/>
@@ -451,8 +479,6 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
style={{ margin: "0 16px" }}
value={paperRows}
onChange={(value) => {
if ((value ?? 1) - blockRowsTop - blockRowsBottom < 1)
return;
setPaperRows(value ?? 1);
}}
/>
@@ -460,10 +486,7 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
</Row>
</Form.Item>
<Form.Item label={t("printing.generic.paperSize")}>
<Select
value={paperSize}
onChange={(value) => setPaperSize(value)}
>
<Select value={paperSize} onChange={(value) => setPaperSize(value)}>
{Object.keys(paperDimensions).map((key) => (
<Select.Option key={key} value={key}>
{key}
@@ -489,113 +512,6 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({
buttonStyle="solid"
/>
</Form.Item>
<Form.Item label={t("printing.generic.blockRowsTop")}>
<Row>
<Col span={12}>
<Slider
min={0}
max={3}
value={blockRowsTop}
onChange={(value) => {
if (paperRows - value - blockRowsBottom < 1) return;
setBlockRowsTop(value);
}}
/>
</Col>
<Col span={12}>
<InputNumber
min={0}
style={{ margin: "0 16px" }}
value={blockRowsTop}
onChange={(value) => {
if (paperRows - (value ?? 0) - blockRowsBottom < 1)
return;
setBlockRowsTop(value ?? 0);
}}
/>
</Col>
</Row>
</Form.Item>
<Form.Item label={t("printing.generic.blockRowsBottom")}>
<Row>
<Col span={12}>
<Slider
min={0}
max={3}
value={blockRowsBottom}
onChange={(value) => {
if (paperRows - value - blockRowsTop < 1) return;
setBlockRowsBottom(value);
}}
/>
</Col>
<Col span={12}>
<InputNumber
min={0}
style={{ margin: "0 16px" }}
value={blockRowsBottom}
onChange={(value) => {
if (paperRows - (value ?? 0) - blockRowsTop < 1) return;
setBlockRowsBottom(value ?? 0);
}}
/>
</Col>
</Row>
</Form.Item>
<Form.Item label={t("printing.generic.blockColumnsLeft")}>
<Row>
<Col span={12}>
<Slider
min={0}
max={3}
value={blockColumnsLeft}
onChange={(value) => {
if (paperColumns - value - blockColumnsRight < 1) return;
setBlockColumnsLeft(value);
}}
/>
</Col>
<Col span={12}>
<InputNumber
min={0}
style={{ margin: "0 16px" }}
value={blockColumnsLeft}
onChange={(value) => {
if (paperColumns - (value ?? 0) - blockColumnsRight < 1)
return;
setBlockColumnsLeft(value ?? 0);
}}
/>
</Col>
</Row>
</Form.Item>
<Form.Item label={t("printing.generic.blockColumnsRight")}>
<Row>
<Col span={12}>
<Slider
min={0}
max={3}
value={blockColumnsRight}
onChange={(value) => {
if (paperColumns - value - blockColumnsLeft < 1) return;
setBlockColumnsRight(value);
}}
/>
</Col>
<Col span={12}>
<InputNumber
min={0}
style={{ margin: "0 16px" }}
value={blockColumnsRight}
onChange={(value) => {
if (paperColumns - (value ?? 0) - blockColumnsLeft < 1)
return;
setBlockColumnsRight(value ?? 0);
}}
/>
</Col>
</Row>
</Form.Item>
{extraSettings && <Divider />}
{extraSettings}
<Divider />

View File

@@ -15,50 +15,27 @@ interface QRCodePrintingDialogProps {
onCancel: () => void;
}
const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({
visible,
items,
onCancel,
}) => {
const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({ visible, items, onCancel }) => {
const t = useTranslate();
const [showContent, setShowContent] = useSavedState(
"print-showContent",
true
);
const [showContent, setShowContent] = useSavedState("print-showContent", true);
const [textSize, setTextSize] = useSavedState("print-textSize", 3);
const [showSpoolmanIcon, setShowSpoolmanIcon] = useSavedState(
"print-showSpoolmanIcon",
true
);
const [showSpoolmanIcon, setShowSpoolmanIcon] = useSavedState("print-showSpoolmanIcon", true);
const elements = items.map((item) => {
return (
<div
style={{
display: "flex",
justifyContent: "center",
width: "100%",
maxHeight: "100%",
flexDirection: "row",
}}
>
<QRCode
className="print-qrcode"
icon={showSpoolmanIcon ? "/favicon.ico" : undefined}
value={item.value}
errorLevel={item.errorLevel}
type="svg"
color="#000"
/>
{showContent && (
<div
className="print-qrcode-title"
style={{ textAlign: "left", color: "#000", overflow: "hidden" }}
>
{item.label ?? item.value}
</div>
)}
<div className="print-qrcode-item">
<div className="print-qrcode-container">
<QRCode
className="print-qrcode"
icon={showSpoolmanIcon ? "/favicon.ico" : undefined}
value={item.value}
errorLevel={item.errorLevel}
type="svg"
color="#000"
/>
</div>
{showContent && <div className="print-qrcode-title">{item.label ?? item.value}</div>}
</div>
);
});
@@ -71,10 +48,7 @@ const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({
extraSettings={
<>
<Form.Item label={t("printing.qrcode.showContent")}>
<Switch
checked={showContent}
onChange={(checked) => setShowContent(checked)}
/>
<Switch checked={showContent} onChange={(checked) => setShowContent(checked)} />
</Form.Item>
<Form.Item label={t("printing.qrcode.textSize")}>
<Row>
@@ -107,28 +81,41 @@ const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({
</Row>
</Form.Item>
<Form.Item label={t("printing.qrcode.showSpoolmanIcon")}>
<Switch
checked={showSpoolmanIcon}
onChange={(checked) => setShowSpoolmanIcon(checked)}
/>
<Switch checked={showSpoolmanIcon} onChange={(checked) => setShowSpoolmanIcon(checked)} />
</Form.Item>
</>
}
style={`
.print-page .print-qrcode-item {
display: flex;
width: 100%;
max-height: 100%;
}
.print-page .print-qrcode-container {
max-width: 50%;
display: flex;
}
.print-page .print-qrcode {
height: 100% !important;
width: 100% !important;
width: auto !important;
height: auto !important;
}
.print-page .print-qrcode-title {
width: 100%;
font-size: ${textSize}mm;
flex: 1 1 auto;
font-size: ${textSize}mm;
color: #000;
overflow: hidden;
}
.print-page svg {
display: block;
height: 100%;
width: auto;
.print-page canvas, .print-page svg {
/* display: block; */
object-fit: contain;
height: 100% !important;
width: 100% !important;
max-height: 100%;
max-width: 100%;
}
`}
onCancel={onCancel}