@flowselections/layout-maker 1.69.15 → 1.69.21

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 (36) hide show
  1. package/dist-lib/components/PrintplekDetailPage.d.ts.map +1 -1
  2. package/dist-lib/components/PrintplekDetailPage.js +3 -8
  3. package/dist-lib/integrations/supabase/types.d.ts +633 -120
  4. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  5. package/dist-lib/lib/etiketRollen.d.ts +41 -0
  6. package/dist-lib/lib/etiketRollen.d.ts.map +1 -0
  7. package/dist-lib/lib/etiketRollen.js +64 -0
  8. package/dist-lib/lib/formaatWeergave.d.ts +24 -0
  9. package/dist-lib/lib/formaatWeergave.d.ts.map +1 -0
  10. package/dist-lib/lib/formaatWeergave.js +24 -0
  11. package/dist-lib/lib/foutTekst.d.ts +3 -0
  12. package/dist-lib/lib/foutTekst.d.ts.map +1 -1
  13. package/dist-lib/lib/foutTekst.js +9 -0
  14. package/dist-lib/lib/ontwerpKeuze.d.ts +80 -0
  15. package/dist-lib/lib/ontwerpKeuze.d.ts.map +1 -0
  16. package/dist-lib/lib/ontwerpKeuze.js +193 -0
  17. package/dist-lib/lib/printQueue.server.d.ts +4 -0
  18. package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
  19. package/dist-lib/lib/printQueue.server.js +237 -5
  20. package/dist-lib/lib/stickerOntwerp.d.ts +67 -0
  21. package/dist-lib/lib/stickerOntwerp.d.ts.map +1 -0
  22. package/dist-lib/lib/stickerOntwerp.js +109 -0
  23. package/dist-lib/lib/stickerUitwijk.d.ts +5 -0
  24. package/dist-lib/lib/stickerUitwijk.d.ts.map +1 -1
  25. package/dist-lib/lib/stickerUitwijk.js +12 -1
  26. package/dist-lib/lib/testpagina.d.ts +7 -1
  27. package/dist-lib/lib/testpagina.d.ts.map +1 -1
  28. package/dist-lib/lib/testpagina.js +39 -5
  29. package/dist-lib/lib/versie.generated.d.ts +1 -1
  30. package/dist-lib/lib/versie.generated.js +1 -1
  31. package/dist-lib/lib/voorbeeldPrint.d.ts.map +1 -1
  32. package/dist-lib/lib/voorbeeldPrint.js +53 -3
  33. package/package.json +1 -1
  34. package/sql/print-schema.aanvulling.sql +5 -0
  35. package/sql/print-schema.sql +4234 -2884
  36. package/sql/print-schema.verslag.md +405 -0
@@ -2,23 +2,55 @@
2
2
  // src/lib/testpagina.ts — een testpagina naar een printer sturen.
3
3
  // Loopt via de printwachtrij, net als echte documenten, zodat ook het
4
4
  // papierformaat en de stand worden getest.
5
+ // 1.69.20: op een labelprinter met ingestelde rol is de testpagina zo groot
6
+ // als de rol (printernaam, rol, datum, randkader, Code128-testbarcode). Zonder
7
+ // rol: A4 (gewone printer).
5
8
  // ============================================================================
6
9
  import { toast } from "@flowselections/core";
7
10
  import { printHtml, volgJobStatus } from "./printApi.js";
11
+ import { supabase } from "./supabaseClient.js";
12
+ import { code128BarsHtml } from "./code128.js";
13
+ import { leesGeladenEtiket } from "./etiketControle.js";
14
+ const esc = (v) => v.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
15
+ const nl = (n) => String(Math.round(n * 10) / 10).replace(".", ",");
16
+ /** HTML van de testpagina op een rol van b × h mm (puur, voor tests). */
17
+ export function testpaginaRolHtml(printerNaam, rol, datum) {
18
+ const b = rol.breedte_mm;
19
+ const h = rol.hoogte_mm;
20
+ const kort = Math.min(b, h);
21
+ const pt = kort <= 30 ? 6 : kort <= 45 ? 7 : 9;
22
+ const bc = Math.max(4, Math.min(12, h * 0.3));
23
+ return `<!doctype html><html><head><meta charset="utf-8"><style>@page{size:${b}mm ${h}mm;margin:0}html,body{margin:0;padding:0}body{width:${b}mm;height:${h}mm;box-sizing:border-box;border:0.4mm solid #000;padding:1mm 1.5mm;font:${pt}pt Arial,sans-serif;overflow:hidden;display:flex;flex-direction:column}.t{font-weight:bold}.bc{display:flex;height:${bc}mm;margin-top:auto}</style></head><body><div class="t">Testpagina · ${esc(printerNaam)}</div><div>Rol: ${esc(rol.naam)} (${nl(b)} × ${nl(h)} mm)</div><div>${esc(datum)}</div><div class="bc">${code128BarsHtml("TEST-128")}</div></body></html>`;
24
+ }
8
25
  export async function drukTestpaginaAf(printerId, naam) {
9
- const html = `<div style="padding:15mm;font-family:Arial,Helvetica,sans-serif;font-size:12pt">
26
+ let rol = null;
27
+ try {
28
+ const { data } = await supabase.from("printers").select("geladen_etiket").eq("id", printerId).maybeSingle();
29
+ rol = leesGeladenEtiket(data?.geladen_etiket);
30
+ }
31
+ catch {
32
+ rol = null;
33
+ }
34
+ const datum = new Date().toLocaleString("nl-NL");
35
+ const html = rol
36
+ ? testpaginaRolHtml(naam, rol, datum)
37
+ : `<div style="padding:15mm;font-family:Arial,Helvetica,sans-serif;font-size:12pt">
10
38
  <h1 style="font-size:20pt;margin:0 0 6mm">Testpagina</h1>
11
- <p style="margin:0 0 3mm">Deze pagina hoort uit: <strong>${naam}</strong></p>
12
- <p style="margin:0">${new Date().toLocaleString("nl-NL")}</p></div>`;
39
+ <p style="margin:0 0 3mm">Deze pagina hoort uit: <strong>${esc(naam)}</strong></p>
40
+ <p style="margin:0">${datum}</p></div>`;
13
41
  try {
14
42
  const { jobId } = await printHtml({
15
43
  documenttype: "vrij",
16
44
  documentnaam: "Testpagina",
17
45
  html,
18
46
  printerId,
19
- payload: { is_testpagina: true, test_id: `testpagina-${Date.now()}` },
47
+ payload: {
48
+ is_testpagina: true,
49
+ test_id: `testpagina-${Date.now()}`,
50
+ ...(rol ? { voorbeeld_formaat: { breedte_mm: rol.breedte_mm, hoogte_mm: rol.hoogte_mm, orientatie: "portrait", marge_boven: 0 } } : {}),
51
+ },
20
52
  });
21
- toast.success(`Testpagina verstuurd naar ${naam}`);
53
+ toast.success(`Testpagina in de wachtrij gezet voor ${naam}${rol ? ` (rol ${nl(rol.breedte_mm)} × ${nl(rol.hoogte_mm)} mm)` : " (A4)"}`);
22
54
  const stop = volgJobStatus(jobId, (st) => {
23
55
  if (st.status === "mislukt") {
24
56
  toast.error(st.foutmelding ?? `De testpagina op ${naam} is mislukt`);
@@ -29,8 +61,10 @@ export async function drukTestpaginaAf(printerId, naam) {
29
61
  }
30
62
  });
31
63
  setTimeout(() => stop(), 60000);
64
+ return true;
32
65
  }
33
66
  catch (e) {
34
67
  toast.error(e instanceof Error ? e.message : "De testpagina kon niet worden afgedrukt");
68
+ return false;
35
69
  }
36
70
  }
@@ -1,2 +1,2 @@
1
- export declare const PAKKET_VERSIE = "1.69.15";
1
+ export declare const PAKKET_VERSIE = "1.69.21";
2
2
  //# sourceMappingURL=versie.generated.d.ts.map
@@ -1,2 +1,2 @@
1
1
  // Gegenereerd door scripts/schrijf-versie.cjs uit package.json. Niet met de hand wijzigen.
2
- export const PAKKET_VERSIE = "1.69.15";
2
+ export const PAKKET_VERSIE = "1.69.21";
@@ -1 +1 @@
1
- {"version":3,"file":"voorbeeldPrint.d.ts","sourceRoot":"","sources":["../../src/lib/voorbeeldPrint.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wFAAwF;AACxF,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,cAAc,CAwBhB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCzF"}
1
+ {"version":3,"file":"voorbeeldPrint.d.ts","sourceRoot":"","sources":["../../src/lib/voorbeeldPrint.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAQpB,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wFAAwF;AACxF,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,cAAc,CAwBhB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFzF"}
@@ -6,6 +6,11 @@
6
6
  // ============================================================================
7
7
  import { toast } from "@flowselections/core";
8
8
  import { printHtml, printerVoorLayout, volgJobStatus, } from "./printApi.js";
9
+ import { supabase } from "./supabaseClient.js";
10
+ import { leesGeladenEtiket } from "./etiketControle.js";
11
+ import { afdrukMaat } from "./formaatWeergave.js";
12
+ import { kiesOntwerpEnPrinter, maatNl } from "./ontwerpKeuze.js";
13
+ const STICKER_ACHTIG = new Set(["sticker", "traysticker", "eigen_sticker", "verzendlabel"]);
9
14
  /** Pure opbouw van de opdracht, zodat printplekdoorgifte regressiegetest kan worden. */
10
15
  export function bouwVoorbeeldPrintInvoer(layout, html, printerId, printplekId) {
11
16
  const documenttype = String(layout.documenttype ?? "pakbon");
@@ -39,14 +44,59 @@ export function bouwVoorbeeldPrintInvoer(layout, html, printerId, printplekId) {
39
44
  export async function voorbeeldPrint(layout, html) {
40
45
  const documenttype = String(layout.documenttype ?? "pakbon");
41
46
  const naam = layout.naam ?? documenttype;
42
- const printerId = await printerVoorLayout(layout);
47
+ let printerId = await printerVoorLayout(layout);
48
+ // 1.69.20: een sticker-achtig ontwerp gaat naar een printer waarop het past
49
+ // (zelfde keuzeregel als de wachtrij). Past het nergens, dan zegt de melding dat.
50
+ if (STICKER_ACHTIG.has(documenttype)) {
51
+ const { data } = await supabase
52
+ .from("printers")
53
+ .select("id, naam, weergavenaam, actief, extern_printer_id, geladen_etiket")
54
+ .not("geladen_etiket", "is", null);
55
+ const rijen = (Array.isArray(data) ? data : []);
56
+ const printers = rijen
57
+ .filter((p) => p["actief"] !== false && p["extern_printer_id"])
58
+ .map((p) => {
59
+ const e = leesGeladenEtiket(p["geladen_etiket"]);
60
+ return { id: String(p["id"]), naam: String(p["weergavenaam"] || p["naam"] || "Printer"), breedte_mm: e?.breedte_mm ?? null, hoogte_mm: e?.hoogte_mm ?? null };
61
+ })
62
+ .sort((a, b) => (a.id === printerId ? -1 : b.id === printerId ? 1 : a.naam.localeCompare(b.naam)));
63
+ const m = afdrukMaat(layout);
64
+ const k = kiesOntwerpEnPrinter({
65
+ documentLabel: naam,
66
+ klant: { id: layout.id ?? null, naam, breedte_mm: m.breedte_mm, hoogte_mm: m.hoogte_mm, herkomst: "klant" },
67
+ kweker: [],
68
+ standaard: [],
69
+ printers,
70
+ a4Printer: null,
71
+ a4Terugval: false,
72
+ vastFormaat: true,
73
+ });
74
+ if (!k.printer) {
75
+ toast.error(`Voorbeeld niet geprint: ${naam} (${maatNl(m.breedte_mm, m.hoogte_mm)}) past op geen labelprinter. Rollen: ${printers.filter((p) => p.breedte_mm && p.hoogte_mm).map((p) => `${p.naam} (${maatNl(p.breedte_mm, p.hoogte_mm)})`).join(", ") || "geen ingesteld"}.`);
76
+ return;
77
+ }
78
+ printerId = k.printer.id;
79
+ }
43
80
  if (!printerId) {
44
81
  toast.error(`Nog geen printer gekoppeld aan ${naam} — stel dit in bij Printen > Standaardregels.`);
45
82
  return;
46
83
  }
47
84
  const printplekId = undefined;
48
- const { jobId } = await printHtml(bouwVoorbeeldPrintInvoer(layout, html, printerId, printplekId));
49
- toast.success("Voorbeeld naar de printer verstuurd");
85
+ let jobId;
86
+ try {
87
+ ({ jobId } = await printHtml(bouwVoorbeeldPrintInvoer(layout, html, printerId, printplekId)));
88
+ }
89
+ catch (e) {
90
+ toast.error(`Voorbeeld niet geprint: ${e instanceof Error ? e.message : "er is geen printopdracht gemaakt"}`);
91
+ return;
92
+ }
93
+ // Nooit "verstuurd" zonder opdracht: lees de opdracht terug.
94
+ const { data: rij } = await supabase.from("print_jobs").select("id").eq("id", jobId).maybeSingle();
95
+ if (!rij) {
96
+ toast.error("Voorbeeld niet geprint: er is geen printopdracht gemaakt. Probeer het opnieuw of kijk in de printwachtrij.");
97
+ return;
98
+ }
99
+ toast.success("Voorbeeld in de printwachtrij gezet");
50
100
  let afgerond = false;
51
101
  const stop = volgJobStatus(jobId, (s) => {
52
102
  if (s.status === "klaar" || s.status === "voltooid") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/layout-maker",
3
- "version": "1.69.15",
3
+ "version": "1.69.21",
4
4
  "flowselections": {
5
5
  "moduleId": "layout-maker",
6
6
  "pages": [
@@ -0,0 +1,5 @@
1
+ -- Objecten die in zeta bestaan maar in geen enkele migratie van deze module
2
+ -- staan (gevonden bij de vergelijking van 1.69.16). Alleen additief.
3
+ ALTER TABLE public.print_agents ADD COLUMN IF NOT EXISTS pairing_code_hash text;
4
+ ALTER TABLE public.print_agents ADD COLUMN IF NOT EXISTS pairing_expires_at timestamptz;
5
+ ALTER TABLE public.print_agents ADD COLUMN IF NOT EXISTS pairing_used_at timestamptz;