Files
spoolman2/client/src/pages/printing/printing.tsx
2024-08-07 13:09:43 +02:00

103 lines
3.2 KiB
TypeScript

import { v4 as uuidv4 } from "uuid";
import { useGetSetting, useSetSetting } from "../../utils/querySettings";
import { ISpool } from "../spools/model";
export interface PrintSettings {
id: string;
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;
showQRCodeMode?: "no" | "simple" | "withIcon";
textSize?: number;
printSettings: PrintSettings;
}
export interface SpoolQRCodePrintSettings {
template?: string;
labelSettings: QRCodePrintSettings;
}
export function useGetPrintSettings(): SpoolQRCodePrintSettings[] | undefined {
const { data } = useGetSetting("print_presets");
if (!data) return;
const parsed: SpoolQRCodePrintSettings[] =
data && data.value ? JSON.parse(data.value) : ([] as SpoolQRCodePrintSettings[]);
// Loop through all parsed and generate a new ID field if it's not set
return parsed.map((settings) => {
if (!settings.labelSettings.printSettings.id) {
settings.labelSettings.printSettings.id = uuidv4();
}
return settings;
});
}
export function useSetPrintSettings(): (spoolQRCodePrintSettings: SpoolQRCodePrintSettings[]) => void {
const mut = useSetSetting("print_presets");
return (spoolQRCodePrintSettings: SpoolQRCodePrintSettings[]) => {
mut.mutate(spoolQRCodePrintSettings);
};
}
interface GenericObject {
[key: string]: any;
extra: { [key: string]: string };
}
function getTagValue(tag: string, obj: GenericObject): any {
// Split tag by .
const tagParts = tag.split(".");
if (tagParts[0] === "extra") {
return JSON.parse(obj.extra[tagParts[1]]);
}
const value = obj[tagParts[0]] ?? "?";
// check if value is itself an object. If so, recursively call this and remove the first part of the tag
if (typeof value === "object") {
return getTagValue(tagParts.slice(1).join("."), value);
}
return value;
}
function applyNewline(text: string): JSX.Element[] {
return text.split("\n").map((line, idx, arr) => (
<span key={idx}>
{line}
{idx < arr.length - 1 && <br />}
</span>
));
}
function applyTextFormatting(text: string): JSX.Element[] {
const regex = /\*\*([\w\W]*?)\*\*/g;
const parts = text.split(regex);
// Map over the parts and wrap matched text with <b> tags
const elements = parts.map((part, index) => {
// Even index: outside asterisks, odd index: inside asterisks (to be bolded)
const node = applyNewline(part);
return index % 2 === 0 ? <span key={index}>{node}</span> : <b key={index}>{node}</b>;
});
return elements;
}
export function renderLabelContents(template: string, spool: ISpool): JSX.Element {
// Find all {tags} in the template string and loop over them
let result = template.replace(/\{(.*?)\}/g, function (_, tag) {
return getTagValue(tag, spool);
});
// Split string on \n into individual lines
return <>{applyTextFormatting(result)}</>;
}