@flowselections/layout-maker 1.3.3 → 1.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/dist-lib/components/AfdrukKnop.d.ts +3 -1
- package/dist-lib/components/AfdrukKnop.d.ts.map +1 -1
- package/dist-lib/components/AfdrukKnop.js +24 -3
- package/dist-lib/components/ComputersLijst.d.ts +23 -0
- package/dist-lib/components/ComputersLijst.d.ts.map +1 -0
- package/dist-lib/components/ComputersLijst.js +75 -0
- package/dist-lib/components/LayoutsPage.d.ts.map +1 -1
- package/dist-lib/components/LayoutsPage.js +2 -0
- package/dist-lib/components/LogosPage.d.ts.map +1 -1
- package/dist-lib/components/LogosPage.js +2 -0
- package/dist-lib/components/NetwerkPrintersDialog.d.ts +8 -0
- package/dist-lib/components/NetwerkPrintersDialog.d.ts.map +1 -0
- package/dist-lib/components/NetwerkPrintersDialog.js +79 -0
- package/dist-lib/components/PrintProgrammaUitleg.d.ts +5 -0
- package/dist-lib/components/PrintProgrammaUitleg.d.ts.map +1 -0
- package/dist-lib/components/PrintProgrammaUitleg.js +19 -0
- package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
- package/dist-lib/components/PrintQueuePage.js +37 -3
- package/dist-lib/components/PrinterKaart.d.ts +17 -0
- package/dist-lib/components/PrinterKaart.d.ts.map +1 -0
- package/dist-lib/components/PrinterKaart.js +14 -0
- package/dist-lib/components/PrinterSetupWizard.d.ts +11 -1
- package/dist-lib/components/PrinterSetupWizard.d.ts.map +1 -1
- package/dist-lib/components/PrinterSetupWizard.js +134 -64
- package/dist-lib/components/PrinterStatsKaarten.d.ts +11 -0
- package/dist-lib/components/PrinterStatsKaarten.d.ts.map +1 -0
- package/dist-lib/components/PrinterStatsKaarten.js +8 -0
- package/dist-lib/components/PrintersPage.d.ts.map +1 -1
- package/dist-lib/components/PrintersPage.js +120 -49
- package/dist-lib/components/WerkplekConfiguratiePage.d.ts +2 -0
- package/dist-lib/components/WerkplekConfiguratiePage.d.ts.map +1 -0
- package/dist-lib/components/WerkplekConfiguratiePage.js +101 -0
- package/dist-lib/components/WerkplekkenTabel.d.ts +14 -0
- package/dist-lib/components/WerkplekkenTabel.d.ts.map +1 -0
- package/dist-lib/components/WerkplekkenTabel.js +16 -0
- package/dist-lib/index.d.ts +11 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +11 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +925 -34
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +925 -34
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +920 -29
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +12 -1
- package/dist-lib/lib/aiLayout.functions.d.ts +925 -34
- package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
- package/dist-lib/lib/aiLayout.server.js +9 -9
- package/dist-lib/lib/browserPrint.d.ts +1 -0
- package/dist-lib/lib/browserPrint.d.ts.map +1 -1
- package/dist-lib/lib/browserPrint.js +6 -6
- package/dist-lib/lib/centralAuth.server.d.ts +13 -0
- package/dist-lib/lib/centralAuth.server.d.ts.map +1 -0
- package/dist-lib/lib/centralAuth.server.js +60 -0
- package/dist-lib/lib/directPrint.d.ts +26 -0
- package/dist-lib/lib/directPrint.d.ts.map +1 -0
- package/dist-lib/lib/directPrint.js +65 -0
- package/dist-lib/lib/documentPdf.d.ts +11 -0
- package/dist-lib/lib/documentPdf.d.ts.map +1 -0
- package/dist-lib/lib/documentPdf.js +62 -0
- package/dist-lib/lib/htmlNaarPdf.server.d.ts +14 -0
- package/dist-lib/lib/htmlNaarPdf.server.d.ts.map +1 -0
- package/dist-lib/lib/htmlNaarPdf.server.js +34 -0
- package/dist-lib/lib/htmlPdf.server.d.ts +29 -0
- package/dist-lib/lib/htmlPdf.server.d.ts.map +1 -0
- package/dist-lib/lib/htmlPdf.server.js +1009 -0
- package/dist-lib/lib/layoutPreview.d.ts +1 -1
- package/dist-lib/lib/layoutPreview.d.ts.map +1 -1
- package/dist-lib/lib/layoutPreview.js +9 -9
- package/dist-lib/lib/logoLibrary.d.ts +1 -1
- package/dist-lib/lib/logoLibrary.js +5 -3
- package/dist-lib/lib/orderData.server.d.ts +15 -0
- package/dist-lib/lib/orderData.server.d.ts.map +1 -0
- package/dist-lib/lib/orderData.server.js +194 -0
- package/dist-lib/lib/pakbonBuilder.d.ts.map +1 -1
- package/dist-lib/lib/pakbonBuilder.js +22 -2
- package/dist-lib/lib/pakbonHtml.js +50 -50
- package/dist-lib/lib/printQueue.server.d.ts +31 -0
- package/dist-lib/lib/printQueue.server.d.ts.map +1 -0
- package/dist-lib/lib/printQueue.server.js +435 -0
- package/dist-lib/lib/printService.functions.d.ts +103742 -0
- package/dist-lib/lib/printService.functions.d.ts.map +1 -0
- package/dist-lib/lib/printService.functions.js +94 -0
- package/dist-lib/lib/printService.server.d.ts +31 -0
- package/dist-lib/lib/printService.server.d.ts.map +1 -0
- package/dist-lib/lib/printService.server.js +110 -0
- package/dist-lib/lib/productiebonHtml.d.ts +18 -0
- package/dist-lib/lib/productiebonHtml.d.ts.map +1 -0
- package/dist-lib/lib/productiebonHtml.js +166 -0
- package/dist-lib/lib/profielHtml.d.ts +14 -0
- package/dist-lib/lib/profielHtml.d.ts.map +1 -0
- package/dist-lib/lib/profielHtml.js +256 -0
- package/dist-lib/lib/runnerRegistry.server.d.ts +10 -0
- package/dist-lib/lib/runnerRegistry.server.d.ts.map +1 -0
- package/dist-lib/lib/runnerRegistry.server.js +79 -0
- package/dist-lib/lib/supabaseAdmin.server.d.ts +6 -0
- package/dist-lib/lib/supabaseAdmin.server.d.ts.map +1 -0
- package/dist-lib/lib/supabaseAdmin.server.js +43 -0
- package/dist-lib/lib/testpagina.d.ts +2 -0
- package/dist-lib/lib/testpagina.d.ts.map +1 -0
- package/dist-lib/lib/testpagina.js +31 -0
- package/dist-lib/lib/useAutoRefresh.d.ts +8 -0
- package/dist-lib/lib/useAutoRefresh.d.ts.map +1 -0
- package/dist-lib/lib/useAutoRefresh.js +44 -0
- package/dist-lib/lib/useDocumentData.d.ts +4 -3
- package/dist-lib/lib/useDocumentData.d.ts.map +1 -1
- package/dist-lib/lib/useDocumentData.js +10 -7
- package/dist-lib/lib/useNetwerkPrinters.d.ts +12 -0
- package/dist-lib/lib/useNetwerkPrinters.d.ts.map +1 -0
- package/dist-lib/lib/useNetwerkPrinters.js +26 -0
- package/package.json +11 -3
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// src/lib/printService.functions.ts — server functions voor achtergrondprinten
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
5
|
+
import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware";
|
|
6
|
+
export const netwerkPrinters = createServerFn({ method: "POST" })
|
|
7
|
+
.middleware([requireSupabaseAuth])
|
|
8
|
+
.handler(async () => {
|
|
9
|
+
const { meldRunnerAan } = await import("./runnerRegistry.server");
|
|
10
|
+
void meldRunnerAan();
|
|
11
|
+
const { haalNetwerkPrinters } = await import("./printService.server");
|
|
12
|
+
try {
|
|
13
|
+
return { ok: true, printers: await haalNetwerkPrinters() };
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
return { ok: false, fout: e instanceof Error ? e.message : "Printers ophalen mislukt" };
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
export const verstuurPrintOpdracht = createServerFn({ method: "POST" })
|
|
20
|
+
.middleware([requireSupabaseAuth])
|
|
21
|
+
.inputValidator((input) => {
|
|
22
|
+
if (!input?.externPrinterId)
|
|
23
|
+
throw new Error("Geen printer gekozen");
|
|
24
|
+
if (!input?.pdfBase64 || input.pdfBase64.length > 20000000) {
|
|
25
|
+
throw new Error("Het document kan niet worden verstuurd");
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
externPrinterId: String(input.externPrinterId).slice(0, 40),
|
|
29
|
+
documentnaam: String(input.documentnaam ?? "Document").slice(0, 120),
|
|
30
|
+
pdfBase64: input.pdfBase64,
|
|
31
|
+
kopieen: Number(input.kopieen ?? 1),
|
|
32
|
+
};
|
|
33
|
+
})
|
|
34
|
+
.handler(async ({ data }) => {
|
|
35
|
+
const { stuurPdfNaarPrinter } = await import("./printService.server");
|
|
36
|
+
try {
|
|
37
|
+
return { ok: true, externJobId: await stuurPdfNaarPrinter(data) };
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
return { ok: false, fout: e instanceof Error ? e.message : "Afdrukken mislukt" };
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
export const printStatus = createServerFn({ method: "POST" })
|
|
44
|
+
.middleware([requireSupabaseAuth])
|
|
45
|
+
.inputValidator((input) => ({
|
|
46
|
+
externJobId: String(input?.externJobId ?? "").slice(0, 40),
|
|
47
|
+
}))
|
|
48
|
+
.handler(async ({ data }) => {
|
|
49
|
+
const { opdrachtStatus } = await import("./printService.server");
|
|
50
|
+
try {
|
|
51
|
+
return { ok: true, status: await opdrachtStatus(data.externJobId) };
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
return { ok: false, fout: e instanceof Error ? e.message : "Status ophalen mislukt" };
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
export const netwerkComputers = createServerFn({ method: "POST" })
|
|
58
|
+
.middleware([requireSupabaseAuth])
|
|
59
|
+
.handler(async () => {
|
|
60
|
+
const { meldRunnerAan } = await import("./runnerRegistry.server");
|
|
61
|
+
void meldRunnerAan();
|
|
62
|
+
const { haalComputers } = await import("./printService.server");
|
|
63
|
+
try {
|
|
64
|
+
return { ok: true, computers: await haalComputers() };
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
fout: e instanceof Error ? e.message : "Computers ophalen mislukt",
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
/**
|
|
74
|
+
* Vangnet: verwerkt direct een paar wachtende opdrachten. Wordt aangeroepen
|
|
75
|
+
* zolang de printwachtrij-pagina openstaat, zodat een verse installatie meteen
|
|
76
|
+
* print — ook voor de eerste cron-ronde.
|
|
77
|
+
*/
|
|
78
|
+
export const wachtrijTick = createServerFn({ method: "POST" })
|
|
79
|
+
.middleware([requireSupabaseAuth])
|
|
80
|
+
.handler(async () => {
|
|
81
|
+
try {
|
|
82
|
+
const { adminConfiguratieFout } = await import("./supabaseAdmin.server");
|
|
83
|
+
const configFout = adminConfiguratieFout();
|
|
84
|
+
if (configFout)
|
|
85
|
+
return { ok: false, fout: configFout };
|
|
86
|
+
const { meldRunnerAan } = await import("./runnerRegistry.server");
|
|
87
|
+
await meldRunnerAan();
|
|
88
|
+
const { verwerkWachtrij } = await import("./printQueue.server");
|
|
89
|
+
return { ok: true, ...(await verwerkWachtrij(3)) };
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
return { ok: false, fout: e instanceof Error ? e.message : "Verwerken mislukt" };
|
|
93
|
+
}
|
|
94
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface NetwerkPrinter {
|
|
2
|
+
id: string;
|
|
3
|
+
naam: string;
|
|
4
|
+
computer: string;
|
|
5
|
+
online: boolean;
|
|
6
|
+
omschrijving: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PrintOpdrachtInput {
|
|
9
|
+
externPrinterId: string;
|
|
10
|
+
documentnaam: string;
|
|
11
|
+
pdfBase64: string;
|
|
12
|
+
kopieen?: number;
|
|
13
|
+
}
|
|
14
|
+
/** Alle printers die via de printclients in het netwerk beschikbaar zijn. */
|
|
15
|
+
export declare function haalNetwerkPrinters(): Promise<NetwerkPrinter[]>;
|
|
16
|
+
/** Stuurt een PDF rechtstreeks naar de printer. Geeft het externe opdrachtnummer terug. */
|
|
17
|
+
export declare function stuurPdfNaarPrinter(input: PrintOpdrachtInput): Promise<string>;
|
|
18
|
+
export type OpdrachtStatus = "wachtend" | "bezig" | "voltooid" | "mislukt";
|
|
19
|
+
/** Vraagt de status van een verstuurde opdracht op. */
|
|
20
|
+
export declare function opdrachtStatus(externJobId: string): Promise<OpdrachtStatus>;
|
|
21
|
+
/** Controleert of de koppeling werkt. */
|
|
22
|
+
export declare function toegangTest(): Promise<boolean>;
|
|
23
|
+
export interface NetwerkComputer {
|
|
24
|
+
id: string;
|
|
25
|
+
naam: string;
|
|
26
|
+
online: boolean;
|
|
27
|
+
laatstGezien: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** Alle computers die het printprogramma draaien. */
|
|
30
|
+
export declare function haalComputers(): Promise<NetwerkComputer[]>;
|
|
31
|
+
//# sourceMappingURL=printService.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"printService.server.d.ts","sourceRoot":"","sources":["../../src/lib/printService.server.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkDD,6EAA6E;AAC7E,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAgBrE;AAED,2FAA2F;AAC3F,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAapF;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;AAE3E,uDAAuD;AACvD,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAUjF;AAED,yCAAyC;AACzC,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAGpD;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,qDAAqD;AACrD,wBAAsB,aAAa,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAchE"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// src/lib/printService.server.ts — communicatie met de externe printdienst.
|
|
3
|
+
// Alleen server-side. Fouten worden vertaald naar begrijpelijke meldingen.
|
|
4
|
+
//
|
|
5
|
+
// De wachtrij levert hier altijd een kant-en-klare PDF aan. Die komt in deze
|
|
6
|
+
// volgorde tot stand (zie printQueue.server.ts):
|
|
7
|
+
// 1. pdf_base64 / pdf_url op de opdracht -> ongewijzigd doorsturen
|
|
8
|
+
// (klantstickers, standaard Floriday-documenten)
|
|
9
|
+
// 2. layout_id op de opdracht -> vers renderen uit de layout
|
|
10
|
+
// 3. meegestuurde render_html -> die opmaak printen
|
|
11
|
+
// 4. actieve layout van het documenttype -> vers renderen
|
|
12
|
+
// ============================================================================
|
|
13
|
+
import { printToegang, PrintToegangFout, vergeetPrintToegang } from "./centralAuth.server";
|
|
14
|
+
const BASIS = "https://api.printnode.com";
|
|
15
|
+
const arr = (v) => (Array.isArray(v) ? v : []);
|
|
16
|
+
function b64(tekst) {
|
|
17
|
+
if (typeof btoa === "function")
|
|
18
|
+
return btoa(tekst);
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
+
return globalThis.Buffer.from(tekst, "utf-8").toString("base64");
|
|
21
|
+
}
|
|
22
|
+
async function vraag(pad, init) {
|
|
23
|
+
const toegang = await printToegang();
|
|
24
|
+
const headers = new Headers(init?.headers);
|
|
25
|
+
headers.set("Authorization", `Basic ${b64(`${toegang.accessToken}:`)}`);
|
|
26
|
+
headers.set("Content-Type", "application/json");
|
|
27
|
+
const ref = toegang.childAccountRef?.trim();
|
|
28
|
+
if (ref) {
|
|
29
|
+
// De centrale auth-module kan de sub-account-verwijzing als nummer,
|
|
30
|
+
// e-mailadres of naam leveren. Kies de bijbehorende koppelingsmethode.
|
|
31
|
+
if (/^\d+$/.test(ref))
|
|
32
|
+
headers.set("X-Child-Account-By-Id", ref);
|
|
33
|
+
else if (ref.includes("@"))
|
|
34
|
+
headers.set("X-Child-Account-By-Email", ref);
|
|
35
|
+
else
|
|
36
|
+
headers.set("X-Child-Account-By-CreatorRef", ref);
|
|
37
|
+
}
|
|
38
|
+
let res;
|
|
39
|
+
try {
|
|
40
|
+
res = await fetch(`${BASIS}${pad}`, { ...init, headers });
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
throw new PrintToegangFout("niet_bereikbaar", "De printdienst is tijdelijk niet bereikbaar. Probeer het zo opnieuw.");
|
|
44
|
+
}
|
|
45
|
+
if (res.status === 401 || res.status === 403) {
|
|
46
|
+
vergeetPrintToegang();
|
|
47
|
+
throw new PrintToegangFout("niet_ingesteld", "De printkoppeling is niet goed ingesteld. Neem contact op met de beheerder.");
|
|
48
|
+
}
|
|
49
|
+
if (!res.ok) {
|
|
50
|
+
throw new PrintToegangFout("niet_bereikbaar", "De printdienst is tijdelijk niet bereikbaar. Probeer het zo opnieuw.");
|
|
51
|
+
}
|
|
52
|
+
return (await res.json());
|
|
53
|
+
}
|
|
54
|
+
/** Alle printers die via de printclients in het netwerk beschikbaar zijn. */
|
|
55
|
+
export async function haalNetwerkPrinters() {
|
|
56
|
+
const data = await vraag("/printers");
|
|
57
|
+
return arr(data).map((p) => ({
|
|
58
|
+
id: String(p.id),
|
|
59
|
+
naam: p.name ?? "Printer",
|
|
60
|
+
computer: p.computer?.name ?? "",
|
|
61
|
+
online: (p.state ?? "").toLowerCase() === "online" &&
|
|
62
|
+
(p.computer?.state ?? "connected").toLowerCase() === "connected",
|
|
63
|
+
omschrijving: p.description ?? "",
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
/** Stuurt een PDF rechtstreeks naar de printer. Geeft het externe opdrachtnummer terug. */
|
|
67
|
+
export async function stuurPdfNaarPrinter(input) {
|
|
68
|
+
const data = await vraag("/printjobs", {
|
|
69
|
+
method: "POST",
|
|
70
|
+
body: JSON.stringify({
|
|
71
|
+
printerId: Number(input.externPrinterId),
|
|
72
|
+
title: input.documentnaam.slice(0, 120),
|
|
73
|
+
contentType: "pdf_base64",
|
|
74
|
+
content: input.pdfBase64,
|
|
75
|
+
source: "Layouts en printers",
|
|
76
|
+
qty: Math.max(1, Math.min(50, input.kopieen ?? 1)),
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
return String(data);
|
|
80
|
+
}
|
|
81
|
+
/** Vraagt de status van een verstuurde opdracht op. */
|
|
82
|
+
export async function opdrachtStatus(externJobId) {
|
|
83
|
+
const data = await vraag(`/printjobs/${encodeURIComponent(externJobId)}/states`);
|
|
84
|
+
const groepen = arr(data);
|
|
85
|
+
const laatste = arr(groepen[groepen.length - 1] ?? [])
|
|
86
|
+
.slice(-1)[0]?.state ?? "";
|
|
87
|
+
const s = laatste.toLowerCase();
|
|
88
|
+
if (s === "done" || s === "sent")
|
|
89
|
+
return "voltooid";
|
|
90
|
+
if (s === "error" || s === "deleted" || s === "expired")
|
|
91
|
+
return "mislukt";
|
|
92
|
+
if (s === "queued" || s === "new")
|
|
93
|
+
return "wachtend";
|
|
94
|
+
return "bezig";
|
|
95
|
+
}
|
|
96
|
+
/** Controleert of de koppeling werkt. */
|
|
97
|
+
export async function toegangTest() {
|
|
98
|
+
await vraag("/whoami");
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
/** Alle computers die het printprogramma draaien. */
|
|
102
|
+
export async function haalComputers() {
|
|
103
|
+
const data = await vraag("/computers");
|
|
104
|
+
return arr(data).map((c) => ({
|
|
105
|
+
id: String(c.id),
|
|
106
|
+
naam: c.name ?? c.hostname ?? "Computer",
|
|
107
|
+
online: (c.state ?? "").toLowerCase() === "connected",
|
|
108
|
+
laatstGezien: c.createTimestamp ?? null,
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type Rij = Record<string, any>;
|
|
2
|
+
export interface ProductiebonRenderOpties {
|
|
3
|
+
breedteMm?: number;
|
|
4
|
+
hoogteMm?: number;
|
|
5
|
+
margeMm?: number;
|
|
6
|
+
titel?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Vult ontbrekende onderdelen aan, zodat een module die maar een deel van de
|
|
10
|
+
* gegevens meestuurt toch een bruikbare bon krijgt.
|
|
11
|
+
*/
|
|
12
|
+
export declare function maakProductiebonData(input: unknown): Rij;
|
|
13
|
+
/** Heeft de bon eigen (niet-voorbeeld) gegevens meegekregen? */
|
|
14
|
+
export declare function heeftProductiebonInhoud(bron: unknown): boolean;
|
|
15
|
+
/** Bouwt de complete print-HTML van een productiebon. */
|
|
16
|
+
export declare function renderProductiebonDocument(config: unknown, gegevens: unknown, opties?: ProductiebonRenderOpties): string;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=productiebonHtml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"productiebonHtml.d.ts","sourceRoot":"","sources":["../../src/lib/productiebonHtml.ts"],"names":[],"mappings":"AAwBA,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAI/B,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAgBxD;AAED,gEAAgE;AAChE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAG9D;AA6HD,yDAAyD;AACzD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,OAAO,EACjB,MAAM,GAAE,wBAA6B,GACpC,MAAM,CAgCR"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// src/lib/productiebonHtml.ts — print-HTML van een productiebon.
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// Zelfde rol als pakbonHtml.ts, maar dan voor productiebon-layouts
|
|
5
|
+
// (config.productiebon.blokken). Wordt gebruikt door de printwachtrij zodat een
|
|
6
|
+
// productiebon nooit als blanco vel bij de printer belandt.
|
|
7
|
+
// ============================================================================
|
|
8
|
+
import { DEMO_PRODUCTIEBON, ONDERDEEL_LABELS, FUST_LABELS, BELADING_LABELS, EXTRA_LABELS, leesProductiebonConfig, pbBlokZichtbaar, pbConditieContext, splitsLijst, vulPbVeldcodes, } from "./productiebonBuilder";
|
|
9
|
+
import { esc } from "./pakbonHtml";
|
|
10
|
+
const arr = (v) => (Array.isArray(v) ? v : []);
|
|
11
|
+
/**
|
|
12
|
+
* Vult ontbrekende onderdelen aan, zodat een module die maar een deel van de
|
|
13
|
+
* gegevens meestuurt toch een bruikbare bon krijgt.
|
|
14
|
+
*/
|
|
15
|
+
export function maakProductiebonData(input) {
|
|
16
|
+
const bron = (input && typeof input === "object" ? input : {});
|
|
17
|
+
const demo = DEMO_PRODUCTIEBON;
|
|
18
|
+
const samen = (naam) => ({
|
|
19
|
+
...demo[naam],
|
|
20
|
+
...(bron[naam] && typeof bron[naam] === "object" ? bron[naam] : {}),
|
|
21
|
+
});
|
|
22
|
+
const onderdelen = arr(bron["onderdelen"]);
|
|
23
|
+
return {
|
|
24
|
+
product: samen("product"),
|
|
25
|
+
fust: samen("fust"),
|
|
26
|
+
belading: samen("belading"),
|
|
27
|
+
instructies: samen("instructies"),
|
|
28
|
+
extra: samen("extra"),
|
|
29
|
+
onderdelen: onderdelen.length ? onderdelen : arr(demo["onderdelen"]),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** Heeft de bon eigen (niet-voorbeeld) gegevens meegekregen? */
|
|
33
|
+
export function heeftProductiebonInhoud(bron) {
|
|
34
|
+
const b = (bron && typeof bron === "object" ? bron : {});
|
|
35
|
+
return Boolean(b["product"] || b["onderdelen"] || b["instructies"]);
|
|
36
|
+
}
|
|
37
|
+
// --- blokken ----------------------------------------------------------------
|
|
38
|
+
const titel = (b) => b.opties?.["toonTitel"] === false ? "" : `<div class="sectitel">${esc(b.titel)}</div>`;
|
|
39
|
+
function kv(label, waarde) {
|
|
40
|
+
return `<div class="kv"><span class="k">${esc(label)}</span><span class="v">${esc(waarde === undefined || waarde === null || waarde === "" ? "—" : waarde)}</span></div>`;
|
|
41
|
+
}
|
|
42
|
+
function tabel(kolommen, rijen, toonKoppen) {
|
|
43
|
+
const kols = kolommen.length ? kolommen : [{ key: "artikelnaam", label: "Omschrijving", breedte: 100, uitlijning: "left" }];
|
|
44
|
+
const cols = kols.map((k) => `<col style="width:${Number(k.breedte ?? 100 / kols.length)}%" />`).join("");
|
|
45
|
+
const kop = toonKoppen
|
|
46
|
+
? `<thead><tr class="onder">${kols
|
|
47
|
+
.map((k) => `<th style="text-align:${k.uitlijning ?? "left"}">${esc(k.label)}</th>`)
|
|
48
|
+
.join("")}</tr></thead>`
|
|
49
|
+
: "";
|
|
50
|
+
const body = rijen
|
|
51
|
+
.map((r) => `<tr>${kols
|
|
52
|
+
.map((k) => {
|
|
53
|
+
const w = r[k.key];
|
|
54
|
+
return `<td style="text-align:${k.uitlijning ?? "left"}">${esc(w === undefined || w === null || w === "" ? "—" : w)}</td>`;
|
|
55
|
+
})
|
|
56
|
+
.join("")}</tr>`)
|
|
57
|
+
.join("");
|
|
58
|
+
return `<table class="tabel compact"><colgroup>${cols}</colgroup>${kop}<tbody>${body}</tbody></table>`;
|
|
59
|
+
}
|
|
60
|
+
function gegevensblok(b, bron, labels) {
|
|
61
|
+
const velden = arr(b.opties?.["velden"]);
|
|
62
|
+
const keys = velden.length ? velden : Object.keys(bron ?? {});
|
|
63
|
+
return keys.map((k) => kv(labels[k] ?? k, bron?.[k])).join("");
|
|
64
|
+
}
|
|
65
|
+
function blokHtml(b, data) {
|
|
66
|
+
const product = (data["product"] ?? {});
|
|
67
|
+
switch (b.type) {
|
|
68
|
+
case "productinfo": {
|
|
69
|
+
const velden = arr(b.velden).filter((v) => v["tonen"]);
|
|
70
|
+
const regels = velden.length
|
|
71
|
+
? velden.map((v) => kv(String(v["label"] ?? v["key"]), product[String(v["key"])])).join("")
|
|
72
|
+
: Object.entries(product)
|
|
73
|
+
.slice(0, 10)
|
|
74
|
+
.map(([k, v]) => kv(k, v))
|
|
75
|
+
.join("");
|
|
76
|
+
return titel(b) + regels;
|
|
77
|
+
}
|
|
78
|
+
case "samenstelling": {
|
|
79
|
+
const soorten = arr(b.opties?.["onderdelen"]);
|
|
80
|
+
const alles = arr(data["onderdelen"]);
|
|
81
|
+
const rijen = soorten.length ? alles.filter((r) => soorten.includes(String(r["soort"]))) : alles;
|
|
82
|
+
const groeperen = b.opties?.["groepeerPerSoort"] !== false && soorten.length > 1;
|
|
83
|
+
const koppen = b.opties?.["toonKoppen"] !== false;
|
|
84
|
+
if (!groeperen)
|
|
85
|
+
return titel(b) + tabel(arr(b.kolommen), rijen, koppen);
|
|
86
|
+
return (titel(b) +
|
|
87
|
+
soorten
|
|
88
|
+
.filter((s) => rijen.some((r) => String(r["soort"]) === s))
|
|
89
|
+
.map((s) => `<div class="groep"><div class="vet">${esc(ONDERDEEL_LABELS[s] ?? s)}</div>${tabel(arr(b.kolommen), rijen.filter((r) => String(r["soort"]) === s), koppen)}</div>`)
|
|
90
|
+
.join(""));
|
|
91
|
+
}
|
|
92
|
+
case "materialen":
|
|
93
|
+
return titel(b) + tabel(arr(b.kolommen), arr(data["onderdelen"]), b.opties?.["toonKoppen"] !== false);
|
|
94
|
+
case "instructies": {
|
|
95
|
+
const instructies = (data["instructies"] ?? {});
|
|
96
|
+
const keys = arr(b.opties?.["onderdelen"]);
|
|
97
|
+
const stukken = (keys.length ? keys : Object.keys(instructies)).map((k) => {
|
|
98
|
+
const tekst = k === "eigentekst"
|
|
99
|
+
? vulPbVeldcodes(String(b.opties?.["eigenTekst"] ?? ""), data)
|
|
100
|
+
: String(instructies[k] ?? "");
|
|
101
|
+
return tekst ? `<div class="vet">${esc(k)}</div><div>${esc(tekst)}</div>` : "";
|
|
102
|
+
});
|
|
103
|
+
return titel(b) + stukken.join("");
|
|
104
|
+
}
|
|
105
|
+
case "productiestappen": {
|
|
106
|
+
const stappen = splitsLijst(b.opties?.["stappen"]);
|
|
107
|
+
const nummeren = b.opties?.["nummeren"] !== false;
|
|
108
|
+
return (titel(b) +
|
|
109
|
+
stappen
|
|
110
|
+
.map((s, i) => `<div class="regel">${esc(nummeren ? `${i + 1}. ${s}` : s)}</div>`)
|
|
111
|
+
.join(""));
|
|
112
|
+
}
|
|
113
|
+
case "fustinformatie":
|
|
114
|
+
return titel(b) + gegevensblok(b, (data["fust"] ?? {}), FUST_LABELS);
|
|
115
|
+
case "belading":
|
|
116
|
+
return titel(b) + gegevensblok(b, (data["belading"] ?? {}), BELADING_LABELS);
|
|
117
|
+
case "extrainfo":
|
|
118
|
+
return titel(b) + gegevensblok(b, (data["extra"] ?? {}), EXTRA_LABELS);
|
|
119
|
+
case "controlepunten": {
|
|
120
|
+
const punten = splitsLijst(b.opties?.["punten"] ?? b.opties?.["controlepunten"]);
|
|
121
|
+
const lijst = punten.length ? punten : ["Kwaliteit gecontroleerd", "Aantal gecontroleerd"];
|
|
122
|
+
return titel(b) + lijst.map((p) => `<div class="regel">☐ ${esc(p)}</div>`).join("");
|
|
123
|
+
}
|
|
124
|
+
case "tekstblok":
|
|
125
|
+
return titel(b) + `<div>${esc(vulPbVeldcodes(String(b.opties?.["tekst"] ?? ""), data))}</div>`;
|
|
126
|
+
case "qrblok":
|
|
127
|
+
return titel(b) + `<div class="qr" style="width:25mm;height:25mm"></div>`;
|
|
128
|
+
case "productfotos":
|
|
129
|
+
case "visueleopbouw":
|
|
130
|
+
return "";
|
|
131
|
+
default:
|
|
132
|
+
return titel(b);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** Bouwt de complete print-HTML van een productiebon. */
|
|
136
|
+
export function renderProductiebonDocument(config, gegevens, opties = {}) {
|
|
137
|
+
const cfg = leesProductiebonConfig(config);
|
|
138
|
+
const data = maakProductiebonData(gegevens);
|
|
139
|
+
const ctx = pbConditieContext(data);
|
|
140
|
+
const b = opties.breedteMm ?? 210;
|
|
141
|
+
const h = opties.hoogteMm ?? 297;
|
|
142
|
+
const marge = opties.margeMm ?? 12;
|
|
143
|
+
const body = arr(cfg.blokken)
|
|
144
|
+
.filter((blok) => pbBlokZichtbaar(blok, ctx))
|
|
145
|
+
.map((blok) => {
|
|
146
|
+
const inhoud = blokHtml(blok, data);
|
|
147
|
+
return inhoud ? `<div class="blok">${inhoud}</div>` : "";
|
|
148
|
+
})
|
|
149
|
+
.join("");
|
|
150
|
+
return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
|
|
151
|
+
<title>${esc(opties.titel ?? "Productiebon")}</title>
|
|
152
|
+
<style>
|
|
153
|
+
@page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
|
|
154
|
+
* { box-sizing: border-box; }
|
|
155
|
+
html, body { margin: 0; padding: 0; }
|
|
156
|
+
body { font-family: Arial, Helvetica, sans-serif; font-size: 9pt; color: #111827; line-height: 1.35; }
|
|
157
|
+
.blok { margin-bottom: 2.5mm; }
|
|
158
|
+
.sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
|
|
159
|
+
.vet { font-weight: 600; }
|
|
160
|
+
.kv { display: flex; justify-content: space-between; gap: 3mm; }
|
|
161
|
+
.kv .k { color: #6b7280; }
|
|
162
|
+
.tabel { width: 100%; border-collapse: collapse; table-layout: fixed; }
|
|
163
|
+
.tabel th { text-align: left; font-weight: 600; }
|
|
164
|
+
.regel { padding: 0.4mm 0; }
|
|
165
|
+
</style></head><body>${body}</body></html>`;
|
|
166
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ProfielRenderOpties {
|
|
2
|
+
breedteMm?: number;
|
|
3
|
+
hoogteMm?: number;
|
|
4
|
+
margeMm?: number;
|
|
5
|
+
titel?: string;
|
|
6
|
+
/** Documenttitel bovenaan (bijv. "Verzendlabel"). */
|
|
7
|
+
kop?: string;
|
|
8
|
+
logoUrl?: string | null;
|
|
9
|
+
}
|
|
10
|
+
/** Heeft deze layout überhaupt iets aanstaan om af te drukken? */
|
|
11
|
+
export declare function profielHeeftInhoud(documenttype: string, config: unknown): boolean;
|
|
12
|
+
/** Bouwt de complete print-HTML van een profielgestuurde layout. */
|
|
13
|
+
export declare function renderProfielDocument(documenttype: string, config: unknown, gegevens: unknown, opties?: ProfielRenderOpties): string;
|
|
14
|
+
//# sourceMappingURL=profielHtml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profielHtml.d.ts","sourceRoot":"","sources":["../../src/lib/profielHtml.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAiND,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAWjF;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,OAAO,EACjB,MAAM,GAAE,mBAAwB,GAC/B,MAAM,CAwCR"}
|