@flowselections/layout-maker 1.22.2 → 1.23.2

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.
Files changed (46) hide show
  1. package/README.md +139 -139
  2. package/dist-lib/components/AfdrukKnop.d.ts +19 -19
  3. package/dist-lib/components/AfdrukKnop.d.ts.map +1 -1
  4. package/dist-lib/components/NetwerkPrintersDialog.d.ts +7 -7
  5. package/dist-lib/components/NetwerkPrintersDialog.d.ts.map +1 -1
  6. package/dist-lib/components/PrinterSetupWizard.d.ts.map +1 -1
  7. package/dist-lib/components/PrinterSetupWizard.js +77 -30
  8. package/dist-lib/components/PrintersRedirectPage.d.ts +1 -1
  9. package/dist-lib/components/PrintersRedirectPage.js +14 -14
  10. package/dist-lib/index.d.ts +2 -5
  11. package/dist-lib/index.d.ts.map +1 -1
  12. package/dist-lib/index.js +1 -3
  13. package/dist-lib/integrations/supabase/auth-middleware.d.ts +233 -0
  14. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  15. package/dist-lib/integrations/supabase/client.server.d.ts +233 -0
  16. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  17. package/dist-lib/integrations/supabase/types.d.ts +236 -0
  18. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  19. package/dist-lib/lib/aiLayout.functions.d.ts +233 -0
  20. package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
  21. package/dist-lib/lib/aiLayout.server.js +9 -9
  22. package/dist-lib/lib/browserPrint.d.ts +0 -23
  23. package/dist-lib/lib/browserPrint.d.ts.map +1 -1
  24. package/dist-lib/lib/browserPrint.js +4 -49
  25. package/dist-lib/lib/layoutPreview.js +7 -7
  26. package/dist-lib/lib/pakbonHtml.js +50 -50
  27. package/dist-lib/lib/papierFormaten.d.ts +30 -0
  28. package/dist-lib/lib/papierFormaten.d.ts.map +1 -0
  29. package/dist-lib/lib/papierFormaten.js +106 -0
  30. package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
  31. package/dist-lib/lib/printQueue.server.js +44 -2
  32. package/dist-lib/lib/printService.functions.d.ts +932 -0
  33. package/dist-lib/lib/printService.functions.d.ts.map +1 -1
  34. package/dist-lib/lib/printService.server.d.ts +20 -0
  35. package/dist-lib/lib/printService.server.d.ts.map +1 -1
  36. package/dist-lib/lib/printService.server.js +24 -0
  37. package/dist-lib/lib/productiebonHtml.js +15 -15
  38. package/dist-lib/lib/profielHtml.js +18 -18
  39. package/dist-lib/lib/supabaseAdmin.server.d.ts +5 -5
  40. package/dist-lib/lib/supabaseAdmin.server.js +43 -43
  41. package/dist-lib/lib/testpagina.d.ts.map +1 -1
  42. package/dist-lib/lib/testpagina.js +27 -22
  43. package/dist-lib/lib/testprint.js +4 -4
  44. package/dist-lib/lib/useDocumentData.d.ts +1 -6
  45. package/dist-lib/lib/useDocumentData.d.ts.map +1 -1
  46. package/package.json +139 -139
@@ -17,27 +17,4 @@ export interface PrinterKeuze {
17
17
  * ingesteld in de printerinstellingen van deze module.
18
18
  */
19
19
  export declare function bedoeldePrinter(documenttype: string, formaatCode: string | null): Promise<PrinterKeuze | null>;
20
- export interface AfdrukOpdracht {
21
- documenttype: string;
22
- formaatCode: string | null;
23
- orientatie: Orientatie;
24
- /** Volledige HTML van het document (zonder <html>-wrapper). */
25
- html: string;
26
- /** Extra stijl die bij het document hoort. */
27
- css?: string;
28
- documentnaam?: string;
29
- margeMm?: number;
30
- }
31
- export interface AfdrukResultaat {
32
- printer: PrinterKeuze | null;
33
- }
34
- /**
35
- * Opent het printvenster met het juiste papierformaat en de juiste stand.
36
- * Geeft terug welke printer volgens de instellingen gekozen moet worden.
37
- *
38
- * @deprecated Verouderd — alle afdrukken lopen via PrintNode. Gebruik
39
- * `printHtml()` of `printPdf()` uit `printApi`. Deze functie blijft nog één
40
- * versie beschikbaar zodat bestaande shells niet breken.
41
- */
42
- export declare function drukAf(opdracht: AfdrukOpdracht): Promise<AfdrukResultaat>;
43
20
  //# sourceMappingURL=browserPrint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browserPrint.d.ts","sourceRoot":"","sources":["../../src/lib/browserPrint.ts"],"names":[],"mappings":"AAWA,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExE,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;AAIlD,yDAAyD;AACzD,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAKtF;AAED,kFAAkF;AAClF,wBAAgB,SAAS,CACvB,OAAO,EAAE,gBAAgB,GAAG,IAAI,EAChC,UAAU,EAAE,UAAU,EACtB,OAAO,SAAI,GACV,MAAM,CAaR;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAGD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA+B9B;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAsB,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAsC/E"}
1
+ {"version":3,"file":"browserPrint.d.ts","sourceRoot":"","sources":["../../src/lib/browserPrint.ts"],"names":[],"mappings":"AAQA,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExE,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;AAIlD,yDAAyD;AACzD,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAKtF;AAED,kFAAkF;AAClF,wBAAgB,SAAS,CACvB,OAAO,EAAE,gBAAgB,GAAG,IAAI,EAChC,UAAU,EAAE,UAAU,EACtB,OAAO,SAAI,GACV,MAAM,CAaR;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAGD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA+B9B"}
@@ -1,10 +1,7 @@
1
1
  // ============================================================================
2
- // src/lib/browserPrint.ts — afdrukken via het printvenster met de juiste
3
- // papierinstellingen (formaat + oriëntatie) en de bedoelde printer erbij.
4
- //
5
- // De browser mag zelf geen printer kiezen; wel zetten we papierformaat en
6
- // oriëntatie vooraf goed, zodat de gebruiker in het printvenster niets meer
7
- // hoeft aan te passen behalve — indien nodig — de printernaam.
2
+ // src/lib/browserPrint.ts — hulpfuncties rond papierformaat en de bedoelde
3
+ // printer. Afdrukken zelf gebeurt altijd via PrintNode (zie printApi); het
4
+ // browser-printvenster wordt niet meer gebruikt.
8
5
  // ============================================================================
9
6
  import { supabase } from "./supabaseClient.js";
10
7
  import { documentProfiel } from "./documentProfiles.js";
@@ -29,7 +26,7 @@ export function paginaCss(formaat, orientatie, margeMm = 0) {
29
26
  const gedraaid = formaat && orientatie === "landscape"
30
27
  ? `${formaat.hoogte}mm ${formaat.breedte}mm`
31
28
  : size;
32
- return `@page { size: ${gedraaid}; margin: ${margeMm}mm; }
29
+ return `@page { size: ${gedraaid}; margin: ${margeMm}mm; }
33
30
  @media print { html, body { margin: 0; padding: 0; } }`;
34
31
  }
35
32
  /**
@@ -64,45 +61,3 @@ export async function bedoeldePrinter(documenttype, formaatCode) {
64
61
  .maybeSingle();
65
62
  return data ?? null;
66
63
  }
67
- /**
68
- * Opent het printvenster met het juiste papierformaat en de juiste stand.
69
- * Geeft terug welke printer volgens de instellingen gekozen moet worden.
70
- *
71
- * @deprecated Verouderd — alle afdrukken lopen via PrintNode. Gebruik
72
- * `printHtml()` of `printPdf()` uit `printApi`. Deze functie blijft nog één
73
- * versie beschikbaar zodat bestaande shells niet breken.
74
- */
75
- export async function drukAf(opdracht) {
76
- const printer = await bedoeldePrinter(opdracht.documenttype, opdracht.formaatCode);
77
- const formaat = opdracht.formaatCode
78
- ? formaatDef(opdracht.documenttype, opdracht.formaatCode)
79
- : null;
80
- if (typeof window === "undefined")
81
- return { printer };
82
- const frame = document.createElement("iframe");
83
- frame.setAttribute("aria-hidden", "true");
84
- frame.style.position = "fixed";
85
- frame.style.right = "0";
86
- frame.style.bottom = "0";
87
- frame.style.width = "0";
88
- frame.style.height = "0";
89
- frame.style.border = "0";
90
- document.body.appendChild(frame);
91
- const doc = frame.contentDocument;
92
- if (!doc) {
93
- frame.remove();
94
- return { printer };
95
- }
96
- doc.open();
97
- doc.write(`<!doctype html><html><head><meta charset="utf-8" />
98
- <title>${opdracht.documentnaam ?? "Document"}</title>
99
- <style>${paginaCss(formaat, opdracht.orientatie, opdracht.margeMm ?? 0)}
100
- body { font-family: system-ui, -apple-system, "Segoe UI", sans-serif; }
101
- ${opdracht.css ?? ""}</style></head><body>${opdracht.html}</body></html>`);
102
- doc.close();
103
- await new Promise((r) => setTimeout(r, 250));
104
- frame.contentWindow?.focus();
105
- frame.contentWindow?.print();
106
- setTimeout(() => frame.remove(), 60000);
107
- return { printer };
108
- }
@@ -79,8 +79,8 @@ function elementHtml(el, ctx) {
79
79
  case "cirkel":
80
80
  return `<div style="${base};border-radius:50%;border:${s.randbreedte || 0.3}mm solid ${s.randkleur ?? "#111827"}"></div>`;
81
81
  case "barcode":
82
- return `<div style="${base};display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:monospace">
83
- <div style="width:100%;height:70%;background:repeating-linear-gradient(90deg,#111 0 1.2px,#fff 1.2px 3px)"></div>
82
+ return `<div style="${base};display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:monospace">
83
+ <div style="width:100%;height:70%;background:repeating-linear-gradient(90deg,#111 0 1.2px,#fff 1.2px 3px)"></div>
84
84
  <div style="font-size:7pt">${esc(inhoud)}</div></div>`;
85
85
  case "qrcode":
86
86
  return `<div style="${base};background:repeating-conic-gradient(#111 0% 25%, #fff 0% 50%) 0 0/22% 22%"></div>`;
@@ -125,10 +125,10 @@ export function bouwDocumentHtml(layout, elementen, gegevens) {
125
125
  const body = zichtbaar.map((e) => elementHtml(e, ctx)).join("");
126
126
  const b = layout.orientatie === "landscape" ? layout.hoogte_mm : layout.breedte_mm;
127
127
  const h = layout.orientatie === "landscape" ? layout.breedte_mm : layout.hoogte_mm;
128
- return `<!doctype html><html lang="nl"><head><meta charset="utf-8"><title>${esc(layout.naam)}</title>
129
- <style>@page{size:${b}mm ${h}mm;margin:0}
130
- body{margin:0;background:#e5e7eb}
131
- .pagina{position:relative;width:${b}mm;height:${h}mm;background:#fff;margin:0 auto;overflow:hidden}
132
- @media print{body{background:#fff}}</style></head>
128
+ return `<!doctype html><html lang="nl"><head><meta charset="utf-8"><title>${esc(layout.naam)}</title>
129
+ <style>@page{size:${b}mm ${h}mm;margin:0}
130
+ body{margin:0;background:#e5e7eb}
131
+ .pagina{position:relative;width:${b}mm;height:${h}mm;background:#fff;margin:0 auto;overflow:hidden}
132
+ @media print{body{background:#fff}}</style></head>
133
133
  <body><div class="pagina">${body}</div></body></html>`;
134
134
  }
@@ -640,56 +640,56 @@ export function renderPakbonDocument(config, order, opties = {}) {
640
640
  const font = opties.lettertype ?? 'Arial, Helvetica, "Segoe UI", sans-serif';
641
641
  const grootte = opties.lettergrootte ?? 8.5;
642
642
  const body = renderPakbonBody(config, order, opties);
643
- return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
644
- <title>${esc(opties.titel ?? "Pakbon")}</title>
645
- <style>
646
- @page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
647
- * { box-sizing: border-box; }
648
- html, body { margin: 0; padding: 0; }
649
- body { font-family: ${font}; font-size: ${grootte}pt; color: #111827; line-height: 1.35; }
650
- .blok { margin-bottom: 2mm; }
651
- .sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
652
- .vet { font-weight: 600; }
653
- .kv { display: flex; justify-content: space-between; gap: 3mm; }
654
- .kv .k { color: #6b7280; }
655
- .kv .v { font-weight: 500; }
656
- .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6mm; }
657
- .kader { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
658
- table.regels { width: 100%; border-collapse: collapse; }
659
- table.regels.vast { table-layout: fixed; }
660
- table.regels.vast td, table.regels.vast th { overflow-wrap: anywhere; }
661
- table.regels th, table.regels td { padding: 0.7mm 1mm; vertical-align: top; }
662
- table.regels th { font-size: 90%; text-transform: uppercase; color: #6b7280; font-weight: 600; text-align: left; }
663
- .rand { border: 0.2mm solid #d1d5db; }
664
- .onder { border-bottom: 0.2mm solid #d1d5db; }
665
- table.regels.compact th, table.regels.compact td { padding: 0.3mm 0.8mm; }
666
- tr.zebra td { background: #f3f4f6; }
667
- .plijst { margin: 0; padding-left: 4mm; }
668
- .groep { margin-bottom: 1.5mm; }
669
- .regelrij { display: flex; gap: 2mm; }
670
- .tweekolom { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm; }
671
- .karblok { margin-bottom: 2mm; }
672
- .karblok.omkaderd { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
673
- .karkop { display: flex; justify-content: space-between; align-items: center; padding: 0.8mm 1.5mm; border-radius: 1mm; margin-bottom: 1mm; }
674
- .bundel { display: inline-block; border: 0.3mm dashed #6b7280; border-radius: 1mm; padding: 0.4mm 1.5mm; margin-bottom: 1mm; font-weight: 700; text-transform: uppercase; letter-spacing: 0.2mm; font-size: 90%; }
675
- .laag { margin-bottom: 1.5mm; }
676
- .laagkop { display: flex; justify-content: space-between; font-weight: 500; border-bottom: 0.2mm solid #d1d5db; padding-bottom: 0.4mm; margin-bottom: 0.6mm; }
677
- .laagkop.compact { border-bottom: none; }
678
- .meta { display: flex; gap: 3mm; font-size: 88%; font-weight: 400; color: #4b5563; }
679
- .totalen { display: flex; flex-wrap: wrap; gap: 5mm; border-top: 0.25mm solid #d1d5db; padding-top: 1.2mm; font-weight: 500; }
680
- .paginavoet { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; }
681
- .handtekening { margin-top: 3mm; }
682
- .lijnveld { margin-top: 4mm; border-bottom: 0.25mm solid #6b7280; padding-bottom: 3mm; }
683
- .lijnveld.hoog { padding-bottom: 10mm; }
684
- .lijn { border-top: 0.25mm solid #d1d5db; margin: 1.5mm 0; }
685
- .balk { height: 1mm; background: #374151; margin: 1.5mm 0; }
686
- .qr { border: 0.25mm dashed #9ca3af; }
687
- .streepjes { width: 45mm; background: repeating-linear-gradient(to right, #111827 0 2px, transparent 2px 5px); }
688
- .klein { font-size: 85%; color: #6b7280; }
689
- .breekvoor { break-before: page; page-break-before: always; }
690
- .heelhouden { break-inside: avoid; page-break-inside: avoid; }
691
- img { max-width: 100%; }
692
- </style></head>
643
+ return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
644
+ <title>${esc(opties.titel ?? "Pakbon")}</title>
645
+ <style>
646
+ @page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
647
+ * { box-sizing: border-box; }
648
+ html, body { margin: 0; padding: 0; }
649
+ body { font-family: ${font}; font-size: ${grootte}pt; color: #111827; line-height: 1.35; }
650
+ .blok { margin-bottom: 2mm; }
651
+ .sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
652
+ .vet { font-weight: 600; }
653
+ .kv { display: flex; justify-content: space-between; gap: 3mm; }
654
+ .kv .k { color: #6b7280; }
655
+ .kv .v { font-weight: 500; }
656
+ .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6mm; }
657
+ .kader { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
658
+ table.regels { width: 100%; border-collapse: collapse; }
659
+ table.regels.vast { table-layout: fixed; }
660
+ table.regels.vast td, table.regels.vast th { overflow-wrap: anywhere; }
661
+ table.regels th, table.regels td { padding: 0.7mm 1mm; vertical-align: top; }
662
+ table.regels th { font-size: 90%; text-transform: uppercase; color: #6b7280; font-weight: 600; text-align: left; }
663
+ .rand { border: 0.2mm solid #d1d5db; }
664
+ .onder { border-bottom: 0.2mm solid #d1d5db; }
665
+ table.regels.compact th, table.regels.compact td { padding: 0.3mm 0.8mm; }
666
+ tr.zebra td { background: #f3f4f6; }
667
+ .plijst { margin: 0; padding-left: 4mm; }
668
+ .groep { margin-bottom: 1.5mm; }
669
+ .regelrij { display: flex; gap: 2mm; }
670
+ .tweekolom { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm; }
671
+ .karblok { margin-bottom: 2mm; }
672
+ .karblok.omkaderd { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
673
+ .karkop { display: flex; justify-content: space-between; align-items: center; padding: 0.8mm 1.5mm; border-radius: 1mm; margin-bottom: 1mm; }
674
+ .bundel { display: inline-block; border: 0.3mm dashed #6b7280; border-radius: 1mm; padding: 0.4mm 1.5mm; margin-bottom: 1mm; font-weight: 700; text-transform: uppercase; letter-spacing: 0.2mm; font-size: 90%; }
675
+ .laag { margin-bottom: 1.5mm; }
676
+ .laagkop { display: flex; justify-content: space-between; font-weight: 500; border-bottom: 0.2mm solid #d1d5db; padding-bottom: 0.4mm; margin-bottom: 0.6mm; }
677
+ .laagkop.compact { border-bottom: none; }
678
+ .meta { display: flex; gap: 3mm; font-size: 88%; font-weight: 400; color: #4b5563; }
679
+ .totalen { display: flex; flex-wrap: wrap; gap: 5mm; border-top: 0.25mm solid #d1d5db; padding-top: 1.2mm; font-weight: 500; }
680
+ .paginavoet { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; }
681
+ .handtekening { margin-top: 3mm; }
682
+ .lijnveld { margin-top: 4mm; border-bottom: 0.25mm solid #6b7280; padding-bottom: 3mm; }
683
+ .lijnveld.hoog { padding-bottom: 10mm; }
684
+ .lijn { border-top: 0.25mm solid #d1d5db; margin: 1.5mm 0; }
685
+ .balk { height: 1mm; background: #374151; margin: 1.5mm 0; }
686
+ .qr { border: 0.25mm dashed #9ca3af; }
687
+ .streepjes { width: 45mm; background: repeating-linear-gradient(to right, #111827 0 2px, transparent 2px 5px); }
688
+ .klein { font-size: 85%; color: #6b7280; }
689
+ .breekvoor { break-before: page; page-break-before: always; }
690
+ .heelhouden { break-inside: avoid; page-break-inside: avoid; }
691
+ img { max-width: 100%; }
692
+ </style></head>
693
693
  <body>${body}</body></html>`;
694
694
  }
695
695
  /** Handig voor testen: het document met de voorbeeldgegevens. */
@@ -0,0 +1,30 @@
1
+ /** Papierformaten van een printer: naam -> [breedte, hoogte] in 0,01 mm. */
2
+ export type PrinterFormaten = Record<string, [number, number] | number[]>;
3
+ export interface FormaatKeuze {
4
+ /** Naam zoals de printer die kent, of null als er geen match is. */
5
+ paper: string | null;
6
+ /** Draaihoek: 0 voor staand, 90 voor liggend. */
7
+ rotate: 0 | 90;
8
+ /** Leesbare uitleg (voor de wachtrij en de testprint). */
9
+ uitleg: string;
10
+ }
11
+ /**
12
+ * Zoekt de papiernaam die het dichtst bij de gevraagde maat ligt.
13
+ * Marge: 2 mm per zijde. Draaiing telt mee (liggend papier mag ook).
14
+ */
15
+ export declare function kiesPapier(formaten: PrinterFormaten | null | undefined, breedteMm: number, hoogteMm: number, margeMm?: number): FormaatKeuze;
16
+ export interface PrinterFormaatOptie {
17
+ /** Naam zoals de printer die kent. */
18
+ naam: string;
19
+ breedte: number;
20
+ hoogte: number;
21
+ /** Formaatcode van de module (A4, LABEL_100x62, …) of een vrije code. */
22
+ code: string;
23
+ /** Leesbare omschrijving voor in de lijst. */
24
+ label: string;
25
+ }
26
+ /** Formaatcode van de module die het dichtst bij deze maat ligt. */
27
+ export declare function formaatCodeVoorMaat(breedteMm: number, hoogteMm: number, margeMm?: number): string;
28
+ /** De formaten van een printer als nette, gesorteerde keuzelijst. */
29
+ export declare function printerFormaatOpties(formaten: PrinterFormaten | null | undefined): PrinterFormaatOptie[];
30
+ //# sourceMappingURL=papierFormaten.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"papierFormaten.d.ts","sourceRoot":"","sources":["../../src/lib/papierFormaten.ts"],"names":[],"mappings":"AAWA,4EAA4E;AAC5E,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;AAE1E,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iDAAiD;IACjD,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;IACf,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;CAChB;AAUD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAC5C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,SAAI,GACV,YAAY,CAyCd;AAQD,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,MAAM,CAe5F;AAED,qEAAqE;AACrE,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GAC3C,mBAAmB,EAAE,CAuBvB"}
@@ -0,0 +1,106 @@
1
+ // ============================================================================
2
+ // src/lib/papierFormaten.ts — het juiste papierformaat van de printer kiezen.
3
+ //
4
+ // De printdienst levert per printer een lijst met papierformaten die die
5
+ // printer aankan, met naam en afmeting in honderdsten van een millimeter
6
+ // (A4 = [2100, 2970]). Hier zoeken we de naam die past bij de maat van onze
7
+ // layout, zodat de opdracht op het juiste papier uitkomt.
8
+ // ============================================================================
9
+ import { PAPIERFORMATEN } from "./documentTypes.js";
10
+ const arrGetal = (v) => Array.isArray(v) ? v.map((n) => Number(n)).filter((n) => Number.isFinite(n)) : [];
11
+ /** Zet een waarde uit de printerlijst om naar millimeters. */
12
+ function naarMm(waarde) {
13
+ return waarde / 100;
14
+ }
15
+ /**
16
+ * Zoekt de papiernaam die het dichtst bij de gevraagde maat ligt.
17
+ * Marge: 2 mm per zijde. Draaiing telt mee (liggend papier mag ook).
18
+ */
19
+ export function kiesPapier(formaten, breedteMm, hoogteMm, margeMm = 2) {
20
+ const liggend = breedteMm > hoogteMm;
21
+ const rotate = liggend ? 90 : 0;
22
+ if (!formaten || typeof formaten !== "object" || Array.isArray(formaten)) {
23
+ return {
24
+ paper: null,
25
+ rotate,
26
+ uitleg: "Papierformaten van deze printer zijn niet bekend; de printer gebruikt zijn eigen standaardpapier.",
27
+ };
28
+ }
29
+ // Bij liggend werk vragen we het staande papier op; de draaiing regelt de rest.
30
+ const doelKort = Math.min(breedteMm, hoogteMm);
31
+ const doelLang = Math.max(breedteMm, hoogteMm);
32
+ let beste = null;
33
+ for (const [naam, maat] of Object.entries(formaten)) {
34
+ const m = arrGetal(maat);
35
+ if (m.length < 2)
36
+ continue;
37
+ const kort = Math.min(naarMm(m[0]), naarMm(m[1]));
38
+ const lang = Math.max(naarMm(m[0]), naarMm(m[1]));
39
+ const afwijking = Math.abs(kort - doelKort) + Math.abs(lang - doelLang);
40
+ if (afwijking <= margeMm * 2 && (!beste || afwijking < beste.afwijking)) {
41
+ beste = { naam, afwijking };
42
+ }
43
+ }
44
+ const maat = `${Math.round(breedteMm)} × ${Math.round(hoogteMm)} mm`;
45
+ if (!beste) {
46
+ return {
47
+ paper: null,
48
+ rotate,
49
+ uitleg: `Deze printer kent geen papierformaat van ${maat}. Er wordt op het standaardpapier van de printer gedrukt; controleer of dat klopt.`,
50
+ };
51
+ }
52
+ return {
53
+ paper: beste.naam,
54
+ rotate,
55
+ uitleg: `Papier "${beste.naam}" (${maat})${liggend ? ", liggend" : ""}.`,
56
+ };
57
+ }
58
+ /** Formaatcode van de module die het dichtst bij deze maat ligt. */
59
+ export function formaatCodeVoorMaat(breedteMm, hoogteMm, margeMm = 2) {
60
+ const kort = Math.min(breedteMm, hoogteMm);
61
+ const lang = Math.max(breedteMm, hoogteMm);
62
+ let beste = null;
63
+ for (const p of PAPIERFORMATEN) {
64
+ if (p.code === "VRIJ")
65
+ continue;
66
+ const pKort = Math.min(p.breedte, p.hoogte);
67
+ const pLang = Math.max(p.breedte, p.hoogte);
68
+ const afwijking = Math.abs(pKort - kort) + Math.abs(pLang - lang);
69
+ if (afwijking <= margeMm * 2 && (!beste || afwijking < beste.afwijking)) {
70
+ beste = { code: p.code, afwijking };
71
+ }
72
+ }
73
+ if (beste)
74
+ return beste.code;
75
+ return `MAAT_${Math.round(breedteMm)}x${Math.round(hoogteMm)}`;
76
+ }
77
+ /** De formaten van een printer als nette, gesorteerde keuzelijst. */
78
+ export function printerFormaatOpties(formaten) {
79
+ if (!formaten || typeof formaten !== "object" || Array.isArray(formaten))
80
+ return [];
81
+ const opties = [];
82
+ for (const [naam, maat] of Object.entries(formaten)) {
83
+ const m = arrGetal(maat);
84
+ if (m.length < 2)
85
+ continue;
86
+ const breedte = Math.round(naarMm(Math.min(m[0], m[1])));
87
+ const hoogte = Math.round(naarMm(Math.max(m[0], m[1])));
88
+ if (!breedte || !hoogte)
89
+ continue;
90
+ const code = formaatCodeVoorMaat(breedte, hoogte);
91
+ const bekend = PAPIERFORMATEN.find((p) => p.code === code);
92
+ opties.push({
93
+ naam,
94
+ breedte,
95
+ hoogte,
96
+ code,
97
+ label: bekend ? `${bekend.label.split(" (")[0]} (${breedte} × ${hoogte} mm)` : `${naam} (${breedte} × ${hoogte} mm)`,
98
+ });
99
+ }
100
+ // Dubbele maten (dezelfde code) maar één keer tonen.
101
+ const uniek = new Map();
102
+ for (const o of opties)
103
+ if (!uniek.has(o.code))
104
+ uniek.set(o.code, o);
105
+ return [...uniek.values()].sort((a, b) => a.breedte * a.hoogte - b.breedte * b.hoogte);
106
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"printQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/printQueue.server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAc5D,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE/B,mFAAmF;AACnF,MAAM,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAEpD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAW1E;AAeD,KAAK,WAAW,GAAG;IAAE,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAqF9D;;;GAGG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BnF;AA2MD;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAoHzF;AAGD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAY1D;AAiLD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wEAAwE;AACxE,wBAAsB,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,SAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmBtF"}
1
+ {"version":3,"file":"printQueue.server.d.ts","sourceRoot":"","sources":["../../src/lib/printQueue.server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAiB5D,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE/B,mFAAmF;AACnF,MAAM,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAEpD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAW1E;AAeD,KAAK,WAAW,GAAG;IAAE,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAqF9D;;;GAGG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BnF;AAgPD;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAoHzF;AAGD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAY1D;AAwLD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wEAAwE;AACxE,wBAAsB,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,SAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmBtF"}
@@ -10,6 +10,8 @@ import { profielHeeftInhoud, renderProfielDocument } from "./profielHtml.js";
10
10
  import { bouwDocumentHtml } from "./layoutPreview.js";
11
11
  import { htmlNaarPdfServer, PdfRenderFout } from "./htmlNaarPdf.server.js";
12
12
  import { stuurPdfNaarPrinter, opdrachtStatus } from "./printService.server.js";
13
+ import { kiesPapier } from "./papierFormaten.js";
14
+ import { PAPIERFORMATEN } from "./documentTypes.js";
13
15
  const MAX_POGINGEN = 3;
14
16
  const arr = (v) => (Array.isArray(v) ? v : []);
15
17
  /**
@@ -233,6 +235,41 @@ async function printplekNaamVoorJob(db, job) {
233
235
  const { data } = await db.from("print_plekken").select("naam").eq("id", plekId).maybeSingle();
234
236
  return String(data?.naam ?? "") || werkplek || null;
235
237
  }
238
+ /** Afmeting die we aanhouden als de opdracht geen eigen layout heeft. */
239
+ function standaardMaat(printer) {
240
+ const code = String(printer?.papierformaat ?? "A4");
241
+ const def = PAPIERFORMATEN.find((p) => p.code === code);
242
+ return { breedte: def?.breedte ?? 210, hoogte: def?.hoogte ?? 297 };
243
+ }
244
+ /**
245
+ * Haalt de papierformaten van de printer op zodra we die nog niet kennen of
246
+ * ze ouder zijn dan een dag, en bewaart ze bij de printer.
247
+ */
248
+ async function zorgVoorFormaten(db, printer) {
249
+ const bestaand = printer?.ondersteunde_formaten ?? null;
250
+ const bijgewerkt = printer?.formaten_bijgewerkt_op
251
+ ? Date.parse(String(printer.formaten_bijgewerkt_op))
252
+ : 0;
253
+ const vers = bijgewerkt > Date.now() - 24 * 60 * 60 * 1000;
254
+ if (bestaand && vers)
255
+ return bestaand;
256
+ try {
257
+ const { haalPrinterFormaten } = await import("./printService.server.js");
258
+ const info = await haalPrinterFormaten(String(printer.extern_printer_id));
259
+ await db
260
+ .from("printers")
261
+ .update({
262
+ ondersteunde_formaten: info.formaten,
263
+ ondersteunde_laden: info.laden,
264
+ formaten_bijgewerkt_op: new Date().toISOString(),
265
+ })
266
+ .eq("id", printer.id);
267
+ return info.formaten;
268
+ }
269
+ catch {
270
+ return bestaand ?? null;
271
+ }
272
+ }
236
273
  /** Bepaalt op welke printer de opdracht moet uitkomen. */
237
274
  async function zoekPrinter(db, job, layout) {
238
275
  const pak = async (id) => {
@@ -240,7 +277,7 @@ async function zoekPrinter(db, job, layout) {
240
277
  return null;
241
278
  const { data } = await db
242
279
  .from("printers")
243
- .select("id, naam, extern_printer_id, actief")
280
+ .select("id, naam, extern_printer_id, actief, papierformaat, ondersteunde_formaten, ondersteunde_laden, formaten_bijgewerkt_op")
244
281
  .eq("id", id)
245
282
  .maybeSingle();
246
283
  return data && data.actief !== false ? data : null;
@@ -563,11 +600,16 @@ async function verwerkJob(db, job) {
563
600
  landschap: liggend,
564
601
  });
565
602
  }
603
+ const formaten = await zorgVoorFormaten(db, printer);
604
+ const breedteMm = Number(layout?.breedte_mm ?? standaardMaat(printer).breedte);
605
+ const hoogteMm = Number(layout?.hoogte_mm ?? standaardMaat(printer).hoogte);
606
+ const papier = kiesPapier(formaten, breedteMm, hoogteMm);
566
607
  const externJobId = await stuurPdfNaarPrinter({
567
608
  externPrinterId: String(printer.extern_printer_id),
568
609
  documentnaam: String(job.documentnaam ?? "Document"),
569
610
  pdfBase64,
570
611
  kopieen: Number(job.kopieen ?? 1),
612
+ opties: { paper: papier.paper, rotate: papier.rotate, fitToPage: false },
571
613
  });
572
614
  await db
573
615
  .from("print_jobs")
@@ -580,7 +622,7 @@ async function verwerkJob(db, job) {
580
622
  updated_at: new Date().toISOString(),
581
623
  })
582
624
  .eq("id", job.id);
583
- await log(db, job.id, "verstuurd", `Naar printer ${printer.naam ?? ""}`);
625
+ await log(db, job.id, "verstuurd", `Naar printer ${printer.naam ?? ""}. ${papier.uitleg}`);
584
626
  return "verstuurd";
585
627
  }
586
628
  catch (e) {