Recoded label printing settings to store in DB instead of in browser

This commit is contained in:
Donkie
2024-06-15 14:07:48 +02:00
parent 4d0e76b64f
commit 426496b4e5
7 changed files with 337 additions and 120 deletions

View File

@@ -0,0 +1,58 @@
import { useGetSetting, useSetSetting } from "../../utils/querySettings";
export interface PrintSettings {
name?: string;
margin?: { top: number; bottom: number; left: number; right: number };
printerMargin?: { top: number; bottom: number; left: number; right: number };
spacing?: { horizontal: number; vertical: number };
columns?: number;
rows?: number;
skipItems?: number;
itemCopies?: number;
paperSize?: string;
customPaperSize?: { width: number; height: number };
borderShowMode?: "none" | "border" | "grid";
}
export interface QRCodePrintSettings {
showContent?: boolean;
textSize?: number;
showSpoolmanIcon?: boolean;
printSettings: PrintSettings;
}
export interface SpoolQRCodePrintSettings {
showVendor?: boolean;
showLotNr?: boolean;
showSpoolWeight?: boolean;
showTemperatures?: boolean;
showSpoolComment?: boolean;
showFilamentComment?: boolean;
showVendorComment?: boolean;
labelSettings: QRCodePrintSettings;
}
function defaultSpoolQRCodePrintSettings(): SpoolQRCodePrintSettings {
return {
labelSettings: {
printSettings: {},
},
};
}
export function useGetPrintSettings(): SpoolQRCodePrintSettings[] {
const { data } = useGetSetting("print_settings");
const parsed = data && data.value ? JSON.parse(data.value) : ([] as SpoolQRCodePrintSettings[]);
if (parsed.length === 0) {
parsed.push(defaultSpoolQRCodePrintSettings());
}
return parsed;
}
export function useSetPrintSettings(): (spoolQRCodePrintSettings: SpoolQRCodePrintSettings[]) => void {
const mut = useSetSetting("print_settings");
return (spoolQRCodePrintSettings: SpoolQRCodePrintSettings[]) => {
mut.mutate(spoolQRCodePrintSettings);
};
}

View File

@@ -16,9 +16,12 @@ import {
import ReactToPrint from "react-to-print"; import ReactToPrint from "react-to-print";
import { useSavedState } from "../../utils/saveload"; import { useSavedState } from "../../utils/saveload";
import { useTranslate } from "@refinedev/core"; import { useTranslate } from "@refinedev/core";
import { PrintSettings } from "./printing";
interface PrintingDialogProps { interface PrintingDialogProps {
items: JSX.Element[]; items: JSX.Element[];
printSettings: PrintSettings;
setPrintSettings: (setPrintSettings: PrintSettings) => void;
style?: string; style?: string;
extraSettings?: JSX.Element; extraSettings?: JSX.Element;
visible: boolean; visible: boolean;
@@ -58,37 +61,39 @@ const paperDimensions: { [key: string]: PaperDimensions } = {
}, },
}; };
const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSettings, visible, onCancel, title }) => { const PrintingDialog: React.FC<PrintingDialogProps> = ({
items,
printSettings,
setPrintSettings,
style,
extraSettings,
visible,
onCancel,
title,
}) => {
const t = useTranslate(); const t = useTranslate();
const [collapseState, setCollapseState] = useSavedState<string[]>("print-collapseState", []); const [collapseState, setCollapseState] = useSavedState<string[]>("print-collapseState", []);
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 [horizontalSpacing, setHorizontalSpacing] = useSavedState("print-horizontalSpacing", 0);
const [verticalSpacing, setVerticalSpacing] = useSavedState("print-verticalSpacing", 0);
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 [skipItems, setSkipItems] = useSavedState("print-skipItems", 0);
const [itemCopies, setItemCopies] = useSavedState("print-itemCopies", 1);
const [paperSize, setPaperSize] = useSavedState("print-paperSize", "A4");
const [customPaperWidth, setCustomPaperWidth] = useSavedState("print-customPaperWidth", 210);
const [customPaperHeight, setCustomPaperHeight] = useSavedState("print-customPaperHeight", 297);
const [previewScale, setPreviewScale] = useSavedState("print-previewScale", 0.6); const [previewScale, setPreviewScale] = useSavedState("print-previewScale", 0.6);
const [borderShowMode, setBorderShowMode] = useSavedState<"none" | "border" | "grid">("print-borderShowMode", "grid");
const paperWidth = paperSize === "custom" ? customPaperWidth : paperDimensions[paperSize].width; const margin = printSettings?.margin || { top: 10, bottom: 10, left: 10, right: 10 };
const paperHeight = paperSize === "custom" ? customPaperHeight : paperDimensions[paperSize].height; const printerMargin = printSettings?.printerMargin || { top: 5, bottom: 5, left: 5, right: 5 };
const spacing = printSettings?.spacing || { horizontal: 0, vertical: 0 };
const paperColumns = printSettings?.columns || 3;
const paperRows = printSettings?.rows || 8;
const skipItems = printSettings?.skipItems || 0;
const itemCopies = printSettings?.itemCopies || 1;
const paperSize = printSettings?.paperSize || "A4";
const customPaperSize = printSettings?.customPaperSize || { width: 210, height: 297 };
const borderShowMode = printSettings?.borderShowMode || "grid";
const paperWidth = paperSize === "custom" ? customPaperSize.width : paperDimensions[paperSize].width;
const paperHeight = paperSize === "custom" ? customPaperSize.height : paperDimensions[paperSize].height;
const printRef = useRef<HTMLDivElement>(null); const printRef = useRef<HTMLDivElement>(null);
const itemWidth = (paperWidth - marginLeft - marginRight - horizontalSpacing) / paperColumns - horizontalSpacing; const itemWidth = (paperWidth - margin.left - margin.right - spacing.horizontal) / paperColumns - spacing.horizontal;
const itemHeight = (paperHeight - marginTop - marginBottom - verticalSpacing) / paperRows - verticalSpacing; const itemHeight = (paperHeight - margin.top - margin.bottom - spacing.vertical) / paperRows - spacing.vertical;
const itemsPerRow = paperColumns; const itemsPerRow = paperColumns;
const rowsPerPage = paperRows; const rowsPerPage = paperRows;
@@ -123,12 +128,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
width: `${itemWidth}mm`, width: `${itemWidth}mm`,
height: `${itemHeight}mm`, height: `${itemHeight}mm`,
border: borderShowMode === "grid" ? "1px solid #000" : "none", border: borderShowMode === "grid" ? "1px solid #000" : "none",
paddingLeft: colIdx === 0 ? `${Math.max(printerMarginLeft - marginLeft, 0)}mm` : 0, paddingLeft: colIdx === 0 ? `${Math.max(printerMargin.left - margin.left, 0)}mm` : 0,
paddingRight: paddingRight:
colIdx === paperColumns - 1 ? `${Math.max(printerMarginRight - marginRight, 0)}mm` : 0, colIdx === paperColumns - 1 ? `${Math.max(printerMargin.right - margin.right, 0)}mm` : 0,
paddingTop: rowIdx === 0 ? `${Math.max(printerMarginTop - marginTop, 0)}mm` : 0, paddingTop: rowIdx === 0 ? `${Math.max(printerMargin.top - margin.top, 0)}mm` : 0,
paddingBottom: paddingBottom:
rowIdx === paperRows - 1 ? `${Math.max(printerMarginBottom - marginBottom, 0)}mm` : 0, rowIdx === paperRows - 1 ? `${Math.max(printerMargin.bottom - margin.bottom, 0)}mm` : 0,
}} }}
> >
{item} {item}
@@ -155,12 +160,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
className="print-page-area" className="print-page-area"
style={{ style={{
border: borderShowMode !== "none" ? "1px solid #000" : "none", border: borderShowMode !== "none" ? "1px solid #000" : "none",
height: `${paperHeight - marginTop - marginBottom}mm`, height: `${paperHeight - margin.top - margin.bottom}mm`,
width: `${paperWidth - marginLeft - marginRight}mm`, width: `${paperWidth - margin.left - margin.right}mm`,
marginTop: `calc(${marginTop}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`, marginTop: `calc(${margin.top}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`,
marginLeft: `calc(${marginLeft}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`, marginLeft: `calc(${margin.left}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`,
marginRight: `calc(${marginRight}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`, marginRight: `calc(${margin.right}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`,
marginBottom: `calc(${marginBottom}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`, marginBottom: `calc(${margin.bottom}mm - ${borderShowMode !== "none" ? "1px" : "0px"})`,
}} }}
> >
<table <table
@@ -238,7 +243,7 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
} }
.print-page table { .print-page table {
border-spacing: ${horizontalSpacing}mm ${verticalSpacing}mm; border-spacing: ${spacing.horizontal}mm ${spacing.vertical}mm;
border-collapse: separate; border-collapse: separate;
} }
@@ -262,7 +267,8 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={30} max={30}
value={skipItems} value={skipItems}
onChange={(value) => { onChange={(value) => {
setSkipItems(value); printSettings.skipItems = value;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -272,7 +278,8 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={skipItems} value={skipItems}
onChange={(value) => { onChange={(value) => {
setSkipItems(value ?? 1); printSettings.skipItems = value ?? 1;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -286,7 +293,8 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={3} max={3}
value={itemCopies} value={itemCopies}
onChange={(value) => { onChange={(value) => {
setItemCopies(value); printSettings.itemCopies = value;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -296,7 +304,8 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={itemCopies} value={itemCopies}
onChange={(value) => { onChange={(value) => {
setItemCopies(value ?? 1); printSettings.itemCopies = value ?? 1;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -313,7 +322,8 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
{ label: t("printing.generic.borders.grid"), value: "grid" }, { label: t("printing.generic.borders.grid"), value: "grid" },
]} ]}
onChange={(e: RadioChangeEvent) => { onChange={(e: RadioChangeEvent) => {
setBorderShowMode(e.target.value); printSettings.borderShowMode = e.target.value;
setPrintSettings(printSettings);
}} }}
value={borderShowMode} value={borderShowMode}
optionType="button" optionType="button"
@@ -363,7 +373,13 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
</Collapse.Panel> </Collapse.Panel>
<Collapse.Panel header={t("printing.generic.layoutSettings")} key="2"> <Collapse.Panel header={t("printing.generic.layoutSettings")} key="2">
<Form.Item label={t("printing.generic.paperSize")}> <Form.Item label={t("printing.generic.paperSize")}>
<Select value={paperSize} onChange={(value) => setPaperSize(value)}> <Select
value={paperSize}
onChange={(value) => {
printSettings.paperSize = value;
setPrintSettings(printSettings);
}}
>
{Object.keys(paperDimensions).map((key) => ( {Object.keys(paperDimensions).map((key) => (
<Select.Option key={key} value={key}> <Select.Option key={key} value={key}>
{key} {key}
@@ -376,10 +392,14 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<Row align="middle"> <Row align="middle">
<Col span={11}> <Col span={11}>
<InputNumber <InputNumber
value={customPaperWidth} value={customPaperSize.width}
min={0.1} min={0.1}
addonAfter="mm" addonAfter="mm"
onChange={(value) => setCustomPaperWidth(value ?? 0)} onChange={(value) => {
customPaperSize.width = value ?? 0;
printSettings.customPaperSize = customPaperSize;
setPrintSettings(printSettings);
}}
/> />
</Col> </Col>
<Col span={2} style={{ textAlign: "center" }}> <Col span={2} style={{ textAlign: "center" }}>
@@ -387,10 +407,14 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
</Col> </Col>
<Col span={11}> <Col span={11}>
<InputNumber <InputNumber
value={customPaperHeight} value={customPaperSize.height}
min={0.1} min={0.1}
addonAfter="mm" addonAfter="mm"
onChange={(value) => setCustomPaperHeight(value ?? 0)} onChange={(value) => {
customPaperSize.height = value ?? 0;
printSettings.customPaperSize = customPaperSize;
setPrintSettings(printSettings);
}}
/> />
</Col> </Col>
</Row> </Row>
@@ -403,7 +427,8 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={5} max={5}
value={paperColumns} value={paperColumns}
onChange={(value) => { onChange={(value) => {
setPaperColumns(value); printSettings.columns = value;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -413,7 +438,8 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={paperColumns} value={paperColumns}
onChange={(value) => { onChange={(value) => {
setPaperColumns(value ?? 1); printSettings.columns = value ?? 1;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -427,7 +453,8 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={15} max={15}
value={paperRows} value={paperRows}
onChange={(value) => { onChange={(value) => {
setPaperRows(value); printSettings.rows = value;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -437,7 +464,8 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={paperRows} value={paperRows}
onChange={(value) => { onChange={(value) => {
setPaperRows(value ?? 1); printSettings.rows = value ?? 1;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -453,9 +481,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={50} max={50}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={marginLeft} value={margin.left}
onChange={(value) => { onChange={(value) => {
setMarginLeft(value); margin.left = value;
printSettings.margin = margin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -463,10 +493,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={marginLeft} value={margin.left}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setMarginLeft(value ?? 0); margin.left = value ?? 0;
printSettings.margin = margin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -480,9 +512,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={50} max={50}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={marginTop} value={margin.top}
onChange={(value) => { onChange={(value) => {
setMarginTop(value); margin.top = value;
printSettings.margin = margin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -490,10 +524,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={marginTop} value={margin.top}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setMarginTop(value ?? 0); margin.top = value ?? 0;
printSettings.margin = margin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -507,9 +543,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={50} max={50}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={marginRight} value={margin.right}
onChange={(value) => { onChange={(value) => {
setMarginRight(value); margin.right = value;
printSettings.margin = margin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -517,10 +555,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={marginRight} value={margin.right}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setMarginRight(value ?? 0); margin.right = value ?? 0;
printSettings.margin = margin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -534,9 +574,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={50} max={50}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={marginBottom} value={margin.bottom}
onChange={(value) => { onChange={(value) => {
setMarginBottom(value); margin.bottom = value;
printSettings.margin = margin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -544,10 +586,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={marginBottom} value={margin.bottom}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setMarginBottom(value ?? 0); margin.bottom = value ?? 0;
printSettings.margin = margin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -563,9 +607,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={50} max={50}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={printerMarginLeft} value={printerMargin.left}
onChange={(value) => { onChange={(value) => {
setPrinterMarginLeft(value); printerMargin.left = value;
printSettings.printerMargin = printerMargin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -573,10 +619,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={printerMarginLeft} value={printerMargin.left}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setPrinterMarginLeft(value ?? 0); printerMargin.left = value ?? 0;
printSettings.printerMargin = printerMargin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -590,9 +638,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={50} max={50}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={printerMarginTop} value={printerMargin.top}
onChange={(value) => { onChange={(value) => {
setPrinterMarginTop(value); printerMargin.top = value;
printSettings.printerMargin = printerMargin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -600,10 +650,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={printerMarginTop} value={printerMargin.top}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setPrinterMarginTop(value ?? 0); printerMargin.top = value ?? 0;
printSettings.printerMargin = printerMargin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -617,9 +669,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={50} max={50}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={printerMarginRight} value={printerMargin.right}
onChange={(value) => { onChange={(value) => {
setPrinterMarginRight(value); printerMargin.right = value;
printSettings.printerMargin = printerMargin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -627,10 +681,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={printerMarginRight} value={printerMargin.right}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setPrinterMarginRight(value ?? 0); printerMargin.right = value ?? 0;
printSettings.printerMargin = printerMargin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -644,9 +700,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={50} max={50}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={printerMarginBottom} value={printerMargin.bottom}
onChange={(value) => { onChange={(value) => {
setPrinterMarginBottom(value); printerMargin.bottom = value;
printSettings.printerMargin = printerMargin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -654,10 +712,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={printerMarginBottom} value={printerMargin.bottom}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setPrinterMarginBottom(value ?? 0); printerMargin.bottom = value ?? 0;
printSettings.printerMargin = printerMargin;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -672,9 +732,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={20} max={20}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={horizontalSpacing} value={spacing.horizontal}
onChange={(value) => { onChange={(value) => {
setHorizontalSpacing(value); spacing.horizontal = value;
printSettings.spacing = spacing;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -682,10 +744,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={horizontalSpacing} value={spacing.horizontal}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setHorizontalSpacing(value ?? 0); spacing.horizontal = value ?? 0;
printSettings.spacing = spacing;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -699,9 +763,11 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
max={20} max={20}
step={0.1} step={0.1}
tooltip={{ formatter: (value) => `${value} mm` }} tooltip={{ formatter: (value) => `${value} mm` }}
value={verticalSpacing} value={spacing.vertical}
onChange={(value) => { onChange={(value) => {
setVerticalSpacing(value); spacing.vertical = value;
printSettings.spacing = spacing;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -709,10 +775,12 @@ const PrintingDialog: React.FC<PrintingDialogProps> = ({ items, style, extraSett
<InputNumber <InputNumber
step={0.1} step={0.1}
style={{ margin: "0 16px" }} style={{ margin: "0 16px" }}
value={verticalSpacing} value={spacing.vertical}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setVerticalSpacing(value ?? 0); spacing.vertical = value ?? 0;
printSettings.spacing = spacing;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>

View File

@@ -2,6 +2,7 @@ import { Col, Form, InputNumber, QRCode, Row, Slider, Switch } from "antd";
import { useSavedState } from "../../utils/saveload"; import { useSavedState } from "../../utils/saveload";
import PrintingDialog from "./printingDialog"; import PrintingDialog from "./printingDialog";
import { useTranslate } from "@refinedev/core"; import { useTranslate } from "@refinedev/core";
import { QRCodePrintSettings } from "./printing";
interface QRCodeData { interface QRCodeData {
value: string; value: string;
@@ -12,16 +13,25 @@ interface QRCodeData {
interface QRCodePrintingDialogProps { interface QRCodePrintingDialogProps {
visible: boolean; visible: boolean;
items: QRCodeData[]; items: QRCodeData[];
printSettings: QRCodePrintSettings;
setPrintSettings: (setPrintSettings: QRCodePrintSettings) => void;
onCancel: () => void; onCancel: () => void;
extraSettings?: JSX.Element; extraSettings?: JSX.Element;
} }
const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({ visible, items, onCancel, extraSettings }) => { const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({
visible,
items,
printSettings,
setPrintSettings,
onCancel,
extraSettings,
}) => {
const t = useTranslate(); const t = useTranslate();
const [showContent, setShowContent] = useSavedState("print-showContent", true); const showContent = printSettings?.showContent;
const [textSize, setTextSize] = useSavedState("print-textSize", 3); const textSize = printSettings?.textSize || 5;
const [showSpoolmanIcon, setShowSpoolmanIcon] = useSavedState("print-showSpoolmanIcon", true); const showSpoolmanIcon = printSettings?.showSpoolmanIcon;
const elements = items.map((item) => { const elements = items.map((item) => {
return ( return (
@@ -46,10 +56,21 @@ const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({ visible, it
visible={visible} visible={visible}
title={t("printing.qrcode.title")} title={t("printing.qrcode.title")}
items={elements} items={elements}
printSettings={printSettings.printSettings}
setPrintSettings={(newSettings) => {
printSettings.printSettings = newSettings;
setPrintSettings(printSettings);
}}
extraSettings={ extraSettings={
<> <>
<Form.Item label={t("printing.qrcode.showContent")}> <Form.Item label={t("printing.qrcode.showContent")}>
<Switch checked={showContent} onChange={(checked) => setShowContent(checked)} /> <Switch
checked={showContent}
onChange={(checked) => {
printSettings.showContent = checked;
setPrintSettings(printSettings);
}}
/>
</Form.Item> </Form.Item>
<Form.Item label={t("printing.qrcode.textSize")}> <Form.Item label={t("printing.qrcode.textSize")}>
<Row> <Row>
@@ -62,7 +83,8 @@ const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({ visible, it
value={textSize} value={textSize}
step={0.1} step={0.1}
onChange={(value) => { onChange={(value) => {
setTextSize(value); printSettings.textSize = value;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
@@ -75,14 +97,21 @@ const QRCodePrintingDialog: React.FC<QRCodePrintingDialogProps> = ({ visible, it
value={textSize} value={textSize}
addonAfter="mm" addonAfter="mm"
onChange={(value) => { onChange={(value) => {
setTextSize(value ?? 5); printSettings.textSize = value ?? 5;
setPrintSettings(printSettings);
}} }}
/> />
</Col> </Col>
</Row> </Row>
</Form.Item> </Form.Item>
<Form.Item label={t("printing.qrcode.showSpoolmanIcon")}> <Form.Item label={t("printing.qrcode.showSpoolmanIcon")}>
<Switch checked={showSpoolmanIcon} onChange={(checked) => setShowSpoolmanIcon(checked)} /> <Switch
checked={showSpoolmanIcon}
onChange={(checked) => {
printSettings.showSpoolmanIcon = checked;
setPrintSettings(printSettings);
}}
/>
</Form.Item> </Form.Item>
{extraSettings} {extraSettings}
</> </>

View File

@@ -4,6 +4,7 @@ import { ISpool } from "../../pages/spools/model";
import QRCodePrintingDialog from "./qrCodePrintingDialog"; import QRCodePrintingDialog from "./qrCodePrintingDialog";
import { useSavedState } from "../../utils/saveload"; import { useSavedState } from "../../utils/saveload";
import { useTranslate } from "@refinedev/core"; import { useTranslate } from "@refinedev/core";
import { useGetPrintSettings, useSetPrintSettings } from "./printing";
interface SpoolQRCodePrintingDialog { interface SpoolQRCodePrintingDialog {
visible: boolean; visible: boolean;
@@ -13,14 +14,16 @@ interface SpoolQRCodePrintingDialog {
const SpoolQRCodePrintingDialog: React.FC<SpoolQRCodePrintingDialog> = ({ visible, items, onCancel }) => { const SpoolQRCodePrintingDialog: React.FC<SpoolQRCodePrintingDialog> = ({ visible, items, onCancel }) => {
const t = useTranslate(); const t = useTranslate();
const printSettings = useGetPrintSettings()[0];
const setPrintSettings = useSetPrintSettings();
const [showVendor, setShowVendor] = useSavedState("print-showVendor", true); const showVendor = printSettings?.showVendor;
const [showLotNr, setShowLotNr] = useSavedState("print-showLotNr", true); const showLotNr = printSettings?.showLotNr;
const [showSpoolWeight, setShowSpoolWeight] = useSavedState("print-showSpoolWeight", true); const showSpoolWeight = printSettings?.showSpoolWeight;
const [showTemperatures, setShowTemperatures] = useSavedState("print-showTemperatures", true); const showTemperatures = printSettings?.showTemperatures;
const [showSpoolComment, setShowSpoolComment] = useSavedState("print-showSpoolComment", false); const showSpoolComment = printSettings?.showSpoolComment;
const [showFilamentComment, setShowFilamentComment] = useSavedState("print-showFilamentComment", false); const showFilamentComment = printSettings?.showFilamentComment;
const [showVendorComment, setShowVendorComment] = useSavedState("print-showVendorComment", false); const showVendorComment = printSettings?.showVendorComment;
const formatFilament = (filament: IFilament) => { const formatFilament = (filament: IFilament) => {
let vendorPrefix = ""; let vendorPrefix = "";
@@ -38,6 +41,11 @@ const SpoolQRCodePrintingDialog: React.FC<SpoolQRCodePrintingDialog> = ({ visibl
<QRCodePrintingDialog <QRCodePrintingDialog
visible={visible} visible={visible}
onCancel={onCancel} onCancel={onCancel}
printSettings={printSettings.labelSettings}
setPrintSettings={(newSettings) => {
printSettings.labelSettings = newSettings;
setPrintSettings([printSettings]);
}}
items={items.map(function (spool) { items={items.map(function (spool) {
const temps = []; const temps = [];
if (spool.filament.settings_extruder_temp) { if (spool.filament.settings_extruder_temp) {
@@ -106,25 +114,67 @@ const SpoolQRCodePrintingDialog: React.FC<SpoolQRCodePrintingDialog> = ({ visibl
extraSettings={ extraSettings={
<> <>
<Form.Item label={t("printing.qrcode.showVendor")}> <Form.Item label={t("printing.qrcode.showVendor")}>
<Switch checked={showVendor} onChange={(checked) => setShowVendor(checked)} /> <Switch
checked={showVendor}
onChange={(checked) => {
printSettings.showVendor = checked;
setPrintSettings([printSettings]);
}}
/>
</Form.Item> </Form.Item>
<Form.Item label={t("printing.qrcode.showSpoolWeight")}> <Form.Item label={t("printing.qrcode.showSpoolWeight")}>
<Switch checked={showSpoolWeight} onChange={(checked) => setShowSpoolWeight(checked)} /> <Switch
checked={showSpoolWeight}
onChange={(checked) => {
printSettings.showSpoolWeight = checked;
setPrintSettings([printSettings]);
}}
/>
</Form.Item> </Form.Item>
<Form.Item label={t("printing.qrcode.showTemperatures")}> <Form.Item label={t("printing.qrcode.showTemperatures")}>
<Switch checked={showTemperatures} onChange={(checked) => setShowTemperatures(checked)} /> <Switch
checked={showTemperatures}
onChange={(checked) => {
printSettings.showTemperatures = checked;
setPrintSettings([printSettings]);
}}
/>
</Form.Item> </Form.Item>
<Form.Item label={t("printing.qrcode.showLotNr")}> <Form.Item label={t("printing.qrcode.showLotNr")}>
<Switch checked={showLotNr} onChange={(checked) => setShowLotNr(checked)} /> <Switch
checked={showLotNr}
onChange={(checked) => {
printSettings.showLotNr = checked;
setPrintSettings([printSettings]);
}}
/>
</Form.Item> </Form.Item>
<Form.Item label={t("printing.qrcode.showSpoolComment")}> <Form.Item label={t("printing.qrcode.showSpoolComment")}>
<Switch checked={showSpoolComment} onChange={(checked) => setShowSpoolComment(checked)} /> <Switch
checked={showSpoolComment}
onChange={(checked) => {
printSettings.showSpoolComment = checked;
setPrintSettings([printSettings]);
}}
/>
</Form.Item> </Form.Item>
<Form.Item label={t("printing.qrcode.showFilamentComment")}> <Form.Item label={t("printing.qrcode.showFilamentComment")}>
<Switch checked={showFilamentComment} onChange={(checked) => setShowFilamentComment(checked)} /> <Switch
checked={showFilamentComment}
onChange={(checked) => {
printSettings.showFilamentComment = checked;
setPrintSettings([printSettings]);
}}
/>
</Form.Item> </Form.Item>
<Form.Item label={t("printing.qrcode.showVendorComment")}> <Form.Item label={t("printing.qrcode.showVendorComment")}>
<Switch checked={showVendorComment} onChange={(checked) => setShowVendorComment(checked)} /> <Switch
checked={showVendorComment}
onChange={(checked) => {
printSettings.showVendorComment = checked;
setPrintSettings([printSettings]);
}}
/>
</Form.Item> </Form.Item>
</> </>
} }

View File

@@ -5,7 +5,7 @@ import { useGetSettings, useSetSetting } from "../../utils/querySettings";
export function GeneralSettings() { export function GeneralSettings() {
const settings = useGetSettings(); const settings = useGetSettings();
const setSetting = useSetSetting(); const setCurrency = useSetSetting("currency");
const [form] = Form.useForm(); const [form] = Form.useForm();
const [messageApi, contextHolder] = message.useMessage(); const [messageApi, contextHolder] = message.useMessage();
const t = useTranslate(); const t = useTranslate();
@@ -21,16 +21,16 @@ export function GeneralSettings() {
// Popup message if setSetting is successful // Popup message if setSetting is successful
React.useEffect(() => { React.useEffect(() => {
if (setSetting.isSuccess) { if (setCurrency.isSuccess) {
messageApi.success(t("notifications.saveSuccessful")); messageApi.success(t("notifications.saveSuccessful"));
} }
}, [setSetting.isSuccess, messageApi, t]); }, [setCurrency.isSuccess, messageApi, t]);
// Handle form submit // Handle form submit
const onFinish = (values: { currency: string }) => { const onFinish = (values: { currency: string }) => {
// Check if the currency has changed // Check if the currency has changed
if (settings.data?.currency.value !== JSON.stringify(values.currency)) { if (settings.data?.currency.value !== JSON.stringify(values.currency)) {
setSetting.mutate({ setCurrency.mutate({
key: "currency", key: "currency",
value: JSON.stringify(values.currency), value: JSON.stringify(values.currency),
}); });
@@ -68,7 +68,7 @@ export function GeneralSettings() {
</Form.Item> </Form.Item>
<Form.Item wrapperCol={{ offset: 8, span: 16 }}> <Form.Item wrapperCol={{ offset: 8, span: 16 }}>
<Button type="primary" htmlType="submit" loading={settings.isFetching || setSetting.isLoading}> <Button type="primary" htmlType="submit" loading={settings.isFetching || setCurrency.isLoading}>
{t("buttons.save")} {t("buttons.save")}
</Button> </Button>
</Form.Item> </Form.Item>

View File

@@ -31,17 +31,17 @@ export function useGetSetting(key: string) {
}); });
} }
export function useSetSetting() { export function useSetSetting<T>(key: string) {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation<SettingResponseValue, unknown, { key: string; value: unknown }>({ return useMutation<SettingResponseValue, unknown, T, SettingResponseValue | undefined>({
mutationFn: async ({ key, value }) => { mutationFn: async (value) => {
const response = await fetch(`${getAPIURL()}/setting/${key}`, { const response = await fetch(`${getAPIURL()}/setting/${key}`, {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify(value), body: JSON.stringify(JSON.stringify(value)),
}); });
// Throw error if response is not ok // Throw error if response is not ok
@@ -51,7 +51,18 @@ export function useSetSetting() {
return response.json(); return response.json();
}, },
onSuccess: (_data, { key }) => { onMutate: async (value) => {
await queryClient.cancelQueries(["settings", key]);
const previousValue = queryClient.getQueryData<SettingResponseValue>(["settings", key]);
queryClient.setQueryData<SettingResponseValue>(["settings", key], (old) =>
old ? { ...old, value: JSON.stringify(value) } : undefined
);
return previousValue;
},
onError: (_error, _value, context) => {
queryClient.setQueryData<SettingResponseValue>(["settings", key], context);
},
onSuccess: (_data, _value) => {
// Invalidate and refetch // Invalidate and refetch
queryClient.invalidateQueries(["settings", key]); queryClient.invalidateQueries(["settings", key]);
}, },

View File

@@ -62,6 +62,7 @@ def parse_setting(key: str) -> SettingDefinition:
register_setting("currency", SettingType.STRING, json.dumps("EUR")) register_setting("currency", SettingType.STRING, json.dumps("EUR"))
register_setting("print_settings", SettingType.ARRAY, json.dumps([]))
register_setting("extra_fields_vendor", SettingType.ARRAY, json.dumps([])) register_setting("extra_fields_vendor", SettingType.ARRAY, json.dumps([]))
register_setting("extra_fields_filament", SettingType.ARRAY, json.dumps([])) register_setting("extra_fields_filament", SettingType.ARRAY, json.dumps([]))