@flowselections/layout-maker 1.7.2 → 1.8.0

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 (99) hide show
  1. package/README.md +78 -1
  2. package/dist-lib/components/AfdrukKnop.d.ts +1 -1
  3. package/dist-lib/components/AfdrukKnop.js +2 -2
  4. package/dist-lib/components/AiLayoutImportDialog.js +4 -4
  5. package/dist-lib/components/BlokOntwerperPage.js +5 -5
  6. package/dist-lib/components/ComputersLijst.js +2 -2
  7. package/dist-lib/components/DocumentSettingsPanel.d.ts +2 -2
  8. package/dist-lib/components/DocumentSettingsPanel.js +3 -3
  9. package/dist-lib/components/FormaatOrientatieBar.d.ts +1 -1
  10. package/dist-lib/components/FormaatOrientatieBar.js +2 -2
  11. package/dist-lib/components/LayoutsPage.js +4 -4
  12. package/dist-lib/components/LogoBibliotheekDialog.d.ts +1 -1
  13. package/dist-lib/components/LogoBibliotheekDialog.js +2 -2
  14. package/dist-lib/components/LogosPage.d.ts +1 -1
  15. package/dist-lib/components/LogosPage.js +2 -2
  16. package/dist-lib/components/NetwerkPrintersDialog.js +2 -2
  17. package/dist-lib/components/PakbonBuilderPage.js +8 -8
  18. package/dist-lib/components/PakbonPreview.d.ts +1 -1
  19. package/dist-lib/components/PakbonPreview.js +3 -3
  20. package/dist-lib/components/PakbonSectiesPanel.d.ts +1 -1
  21. package/dist-lib/components/PakbonSectiesPanel.js +4 -4
  22. package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
  23. package/dist-lib/components/PrintQueuePage.js +7 -6
  24. package/dist-lib/components/PrinterSetupWizard.js +5 -5
  25. package/dist-lib/components/PrintersPage.js +7 -7
  26. package/dist-lib/components/ProductiebonBlokkenPanel.d.ts +1 -1
  27. package/dist-lib/components/ProductiebonBlokkenPanel.js +1 -1
  28. package/dist-lib/components/ProductiebonBuilderPage.js +6 -6
  29. package/dist-lib/components/ProductiebonPreview.d.ts +1 -1
  30. package/dist-lib/components/ProductiebonPreview.js +2 -2
  31. package/dist-lib/components/WerkplekConfiguratiePage.js +7 -7
  32. package/dist-lib/index.d.ts +62 -46
  33. package/dist-lib/index.d.ts.map +1 -1
  34. package/dist-lib/index.js +47 -47
  35. package/dist-lib/integrations/supabase/auth-attacher.js +1 -1
  36. package/dist-lib/integrations/supabase/auth-middleware.d.ts +1600 -780
  37. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  38. package/dist-lib/integrations/supabase/client.d.ts +1 -1
  39. package/dist-lib/integrations/supabase/client.js +1 -1
  40. package/dist-lib/integrations/supabase/client.server.d.ts +1600 -780
  41. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  42. package/dist-lib/integrations/supabase/client.server.js +1 -1
  43. package/dist-lib/integrations/supabase/types.d.ts +1001 -165
  44. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  45. package/dist-lib/integrations/supabase/types.js +3 -0
  46. package/dist-lib/lib/aiLayout.functions.d.ts +1679 -859
  47. package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
  48. package/dist-lib/lib/aiLayout.functions.js +2 -2
  49. package/dist-lib/lib/aiLayout.server.d.ts +1 -1
  50. package/dist-lib/lib/browserPrint.d.ts +1 -1
  51. package/dist-lib/lib/browserPrint.js +3 -3
  52. package/dist-lib/lib/directPrint.d.ts +1 -1
  53. package/dist-lib/lib/directPrint.js +4 -4
  54. package/dist-lib/lib/documentPdf.d.ts +1 -1
  55. package/dist-lib/lib/documentProfiles.d.ts +1 -1
  56. package/dist-lib/lib/documentProfiles.d.ts.map +1 -1
  57. package/dist-lib/lib/documentProfiles.js +3 -0
  58. package/dist-lib/lib/documentTypes.d.ts +1 -1
  59. package/dist-lib/lib/documentTypes.d.ts.map +1 -1
  60. package/dist-lib/lib/documentTypes.js +3 -0
  61. package/dist-lib/lib/formaatPrinters.js +1 -1
  62. package/dist-lib/lib/htmlNaarPdf.server.js +1 -1
  63. package/dist-lib/lib/layoutPreview.d.ts +1 -1
  64. package/dist-lib/lib/layoutPreview.js +1 -1
  65. package/dist-lib/lib/logoLibrary.js +1 -1
  66. package/dist-lib/lib/orderData.server.d.ts +2 -1
  67. package/dist-lib/lib/orderData.server.d.ts.map +1 -1
  68. package/dist-lib/lib/orderData.server.js +7 -8
  69. package/dist-lib/lib/pakbonBuilder.d.ts +1 -1
  70. package/dist-lib/lib/pakbonHtml.d.ts +1 -1
  71. package/dist-lib/lib/pakbonHtml.js +2 -2
  72. package/dist-lib/lib/printApi.d.ts +72 -1
  73. package/dist-lib/lib/printApi.d.ts.map +1 -1
  74. package/dist-lib/lib/printApi.js +155 -15
  75. package/dist-lib/lib/printQueue.server.d.ts +12 -3
  76. package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
  77. package/dist-lib/lib/printQueue.server.js +66 -48
  78. package/dist-lib/lib/printService.functions.d.ts +6628 -24446
  79. package/dist-lib/lib/printService.functions.d.ts.map +1 -1
  80. package/dist-lib/lib/printService.functions.js +5 -31
  81. package/dist-lib/lib/printService.server.js +1 -1
  82. package/dist-lib/lib/productiebonBuilder.d.ts +1 -1
  83. package/dist-lib/lib/productiebonHtml.js +2 -2
  84. package/dist-lib/lib/profielHtml.js +2 -2
  85. package/dist-lib/lib/queueTick.d.ts +11 -3
  86. package/dist-lib/lib/queueTick.d.ts.map +1 -1
  87. package/dist-lib/lib/queueTick.js +68 -21
  88. package/dist-lib/lib/queueTickClient.d.ts +8 -0
  89. package/dist-lib/lib/queueTickClient.d.ts.map +1 -0
  90. package/dist-lib/lib/queueTickClient.js +37 -0
  91. package/dist-lib/lib/runnerRegistry.server.d.ts +3 -2
  92. package/dist-lib/lib/runnerRegistry.server.d.ts.map +1 -1
  93. package/dist-lib/lib/runnerRegistry.server.js +6 -8
  94. package/dist-lib/lib/supabaseClient.d.ts +1 -1
  95. package/dist-lib/lib/testpagina.js +2 -2
  96. package/dist-lib/lib/useDocumentData.d.ts +1 -1
  97. package/dist-lib/lib/useDocumentData.js +1 -1
  98. package/dist-lib/lib/useNetwerkPrinters.js +1 -1
  99. package/package.json +2 -2
@@ -3,18 +3,36 @@
3
3
  // Pakt wachtende opdrachten op, maakt er een PDF van en stuurt die stil naar
4
4
  // de juiste printer. Draait alleen op de server (cron / interne aanroep).
5
5
  // ============================================================================
6
- import { adminDb as supabaseAdmin } from "./supabaseAdmin.server";
7
- import { maakPakbonOrder, renderPakbonDocument } from "./pakbonHtml";
8
- import { renderProductiebonDocument } from "./productiebonHtml";
9
- import { heeftOrderInhoud, laadOrderVanuitDatabase } from "./orderData.server";
10
- import { profielHeeftInhoud, renderProfielDocument } from "./profielHtml";
11
- import { bouwDocumentHtml } from "./layoutPreview";
12
- import { htmlNaarPdfServer, PdfRenderFout } from "./htmlNaarPdf.server";
13
- import { stuurPdfNaarPrinter, opdrachtStatus } from "./printService.server";
6
+ import { maakPakbonOrder, renderPakbonDocument } from "./pakbonHtml.js";
7
+ import { renderProductiebonDocument } from "./productiebonHtml.js";
8
+ import { heeftOrderInhoud, laadOrderVanuitDatabase } from "./orderData.server.js";
9
+ import { profielHeeftInhoud, renderProfielDocument } from "./profielHtml.js";
10
+ import { bouwDocumentHtml } from "./layoutPreview.js";
11
+ import { htmlNaarPdfServer, PdfRenderFout } from "./htmlNaarPdf.server.js";
12
+ import { stuurPdfNaarPrinter, opdrachtStatus } from "./printService.server.js";
14
13
  const MAX_POGINGEN = 3;
15
14
  const arr = (v) => (Array.isArray(v) ? v : []);
16
- async function log(jobId, gebeurtenis, detail) {
17
- await supabaseAdmin.from("print_job_logs").insert({
15
+ /**
16
+ * Goedkope controle of de aangeleverde client de printtabellen kan lezen.
17
+ * Vervangt de oude controle op omgevingsvariabelen: die kende de module niet
18
+ * meer nu de shell de client levert.
19
+ */
20
+ export async function controleerClient(db) {
21
+ if (!db)
22
+ return "Achtergrondprinten is niet ingesteld: de server kreeg geen databaseverbinding.";
23
+ try {
24
+ const { error } = await db.from("print_jobs").select("id", { count: "exact", head: true }).limit(1);
25
+ if (error) {
26
+ return `Achtergrondprinten is niet ingesteld: de server kan niet bij de database (${error.message}).`;
27
+ }
28
+ return null;
29
+ }
30
+ catch (e) {
31
+ return `Achtergrondprinten is niet ingesteld: de server kan niet bij de database (${e instanceof Error ? e.message : "onbekende fout"}).`;
32
+ }
33
+ }
34
+ async function log(db, jobId, gebeurtenis, detail) {
35
+ await db.from("print_job_logs").insert({
18
36
  job_id: jobId,
19
37
  gebeurtenis,
20
38
  ...(detail ? { detail: String(detail).slice(0, 1000) } : {}),
@@ -34,11 +52,11 @@ class GeenDocumentFout extends Error {
34
52
  * mislukt. Alleen zonder layout_id valt de wachtrij terug op de actieve
35
53
  * layout van het documenttype.
36
54
  */
37
- async function zoekLayout(job) {
55
+ async function zoekLayout(db, job) {
38
56
  const uitPayload = job.payload?.layoutId ?? job.payload?.data?.layoutId ?? job.payload?.layout_id ?? null;
39
57
  const id = job.layout_id ?? uitPayload;
40
58
  if (id) {
41
- const { data } = await supabaseAdmin
59
+ const { data } = await db
42
60
  .from("document_layouts")
43
61
  .select("*")
44
62
  .eq("id", id)
@@ -48,7 +66,7 @@ async function zoekLayout(job) {
48
66
  }
49
67
  return { layout: data, expliciet: true };
50
68
  }
51
- const { data } = await supabaseAdmin
69
+ const { data } = await db
52
70
  .from("document_layouts")
53
71
  .select("*")
54
72
  .eq("documenttype", job.documenttype)
@@ -62,7 +80,7 @@ async function zoekLayout(job) {
62
80
  * Haalt een kant-en-klare PDF van de opdracht op (klantstickers, standaard
63
81
  * Floriday-documenten). Die gaat ongewijzigd naar de printer.
64
82
  */
65
- export async function kantEnKlarePdf(job) {
83
+ export async function kantEnKlarePdf(_db, job) {
66
84
  const direct = typeof job.pdf_base64 === "string" ? job.pdf_base64.trim() : "";
67
85
  if (direct.length > 100)
68
86
  return direct.replace(/^data:application\/pdf;base64,/i, "");
@@ -94,11 +112,11 @@ export async function kantEnKlarePdf(job) {
94
112
  return btoa(ruw);
95
113
  }
96
114
  /** Bepaalt op welke printer de opdracht moet uitkomen. */
97
- async function zoekPrinter(job, layout) {
115
+ async function zoekPrinter(db, job, layout) {
98
116
  const pak = async (id) => {
99
117
  if (!id)
100
118
  return null;
101
- const { data } = await supabaseAdmin
119
+ const { data } = await db
102
120
  .from("printers")
103
121
  .select("id, naam, extern_printer_id, actief")
104
122
  .eq("id", id)
@@ -109,7 +127,7 @@ async function zoekPrinter(job, layout) {
109
127
  if (printer)
110
128
  return printer;
111
129
  if (layout?.id) {
112
- const { data } = await supabaseAdmin
130
+ const { data } = await db
113
131
  .from("printer_mappings")
114
132
  .select("printer_id")
115
133
  .eq("layout_id", layout.id)
@@ -120,7 +138,7 @@ async function zoekPrinter(job, layout) {
120
138
  return printer;
121
139
  }
122
140
  const formaat = layout?.papierformaat ?? "A4";
123
- const { data: fm } = await supabaseAdmin
141
+ const { data: fm } = await db
124
142
  .from("document_formaat_printers")
125
143
  .select("printer_id")
126
144
  .eq("documenttype", job.documenttype)
@@ -129,7 +147,7 @@ async function zoekPrinter(job, layout) {
129
147
  printer = await pak(fm?.printer_id);
130
148
  if (printer)
131
149
  return printer;
132
- const { data: enige } = await supabaseAdmin
150
+ const { data: enige } = await db
133
151
  .from("printers")
134
152
  .select("id, naam, extern_printer_id, actief")
135
153
  .eq("actief", true)
@@ -139,11 +157,11 @@ async function zoekPrinter(job, layout) {
139
157
  return kandidaten.length === 1 ? kandidaten[0] : null;
140
158
  }
141
159
  /** Haalt de logo's op die in de layout gebruikt worden, met tijdelijke URL. */
142
- async function logosVoor(layout) {
160
+ async function logosVoor(db, layout) {
143
161
  const logoId = layout?.config?.logo?.logoId ?? null;
144
162
  if (!logoId)
145
163
  return [];
146
- const { data } = await supabaseAdmin
164
+ const { data } = await db
147
165
  .from("layout_logos")
148
166
  .select("id, naam, bestandspad, bestand_url")
149
167
  .eq("id", logoId)
@@ -153,7 +171,7 @@ async function logosVoor(layout) {
153
171
  return [];
154
172
  let viewUrl = logo.bestand_url ?? null;
155
173
  if (logo.bestandspad) {
156
- const { data: sign } = await supabaseAdmin.storage
174
+ const { data: sign } = await db.storage
157
175
  .from("layout-logos")
158
176
  .createSignedUrl(logo.bestandspad, 3600);
159
177
  if (sign?.signedUrl)
@@ -166,7 +184,7 @@ async function logosVoor(layout) {
166
184
  * Volgorde: gekoppelde layout wint > meegestuurde HTML > actieve layout van
167
185
  * het documenttype. Zo werkt een bijgewerkte layout meteen door.
168
186
  */
169
- export async function bouwHtml(job, keuze) {
187
+ export async function bouwHtml(db, job, keuze) {
170
188
  const layout = keuze.layout;
171
189
  const meegestuurd = typeof job.render_html === "string" && job.render_html.trim().length > 40
172
190
  ? job.render_html
@@ -204,14 +222,14 @@ export async function bouwHtml(job, keuze) {
204
222
  : null;
205
223
  if ((pakbonSecties && pakbonSecties.length) || String(layout.documenttype) === "pakbon") {
206
224
  const orderBron = p.order ?? p.data?.order ?? p.data ?? p;
207
- const uitDb = heeftOrderInhoud(orderBron) ? null : await laadOrderVanuitDatabase(p);
225
+ const uitDb = heeftOrderInhoud(orderBron) ? null : await laadOrderVanuitDatabase(db, p);
208
226
  const order = maakPakbonOrder(uitDb ?? orderBron);
209
227
  return renderPakbonDocument(layout.config, order, {
210
228
  breedteMm,
211
229
  hoogteMm,
212
230
  margeMm: Number(layout.marge_boven ?? 12),
213
231
  titel: job.documentnaam ?? "Document",
214
- logos: await logosVoor(layout),
232
+ logos: await logosVoor(db, layout),
215
233
  });
216
234
  }
217
235
  // 2) Productiebon-layouts (blokken onder `productiebon.blokken`).
@@ -225,7 +243,7 @@ export async function bouwHtml(job, keuze) {
225
243
  });
226
244
  }
227
245
  // 3) Vrije layouts met losse elementen (verzendlabel, etiket, vrij, ...)
228
- const { data: elementen } = await supabaseAdmin
246
+ const { data: elementen } = await db
229
247
  .from("document_layout_elements")
230
248
  .select("*")
231
249
  .eq("layout_id", layout.id)
@@ -255,7 +273,7 @@ export async function bouwHtml(job, keuze) {
255
273
  throw new GeenDocumentFout(`De layout "${String(layout.naam ?? "")}" heeft geen onderdelen aanstaan om af te drukken. ` +
256
274
  "Zet in de layoutinstellingen minstens één onderdeel aan.");
257
275
  }
258
- const logos = await logosVoor(layout);
276
+ const logos = await logosVoor(db, layout);
259
277
  return renderProfielDocument(String(layout.documenttype), cfg, p.data ?? p, {
260
278
  breedteMm,
261
279
  hoogteMm,
@@ -302,12 +320,12 @@ function plattePayload(payload) {
302
320
  loop(payload, "", 0);
303
321
  return uit;
304
322
  }
305
- async function mislukt(job, reden, terugNaarWachtend) {
323
+ async function mislukt(db, job, reden, terugNaarWachtend) {
306
324
  const pogingen = Number(job.pogingen ?? 0);
307
325
  const opnieuw = terugNaarWachtend && pogingen < MAX_POGINGEN;
308
326
  // oplopende wachttijd: 1, 4, 9 minuten
309
327
  const wachtMin = Math.min(30, Math.max(1, pogingen * pogingen));
310
- await supabaseAdmin
328
+ await db
311
329
  .from("print_jobs")
312
330
  .update({
313
331
  status: opnieuw ? "wachtend" : "mislukt",
@@ -317,27 +335,27 @@ async function mislukt(job, reden, terugNaarWachtend) {
317
335
  updated_at: new Date().toISOString(),
318
336
  })
319
337
  .eq("id", job.id);
320
- await log(job.id, opnieuw ? "opnieuw_proberen" : "mislukt", reden);
338
+ await log(db, job.id, opnieuw ? "opnieuw_proberen" : "mislukt", reden);
321
339
  }
322
- async function verwerkJob(job) {
340
+ async function verwerkJob(db, job) {
323
341
  try {
324
342
  // Dubbel printen voorkomen: deze opdracht staat al bij de printer.
325
343
  if (job.extern_job_id) {
326
- await log(job.id, "overgeslagen", "Stond al bij de printer.");
344
+ await log(db, job.id, "overgeslagen", "Stond al bij de printer.");
327
345
  return "verstuurd";
328
346
  }
329
347
  // 1) Kant-en-klare PDF (klantsticker, Floriday-document) gaat ongewijzigd door.
330
- const klaar = await kantEnKlarePdf(job);
331
- const keuze = klaar ? { layout: null, expliciet: false } : await zoekLayout(job);
348
+ const klaar = await kantEnKlarePdf(db, job);
349
+ const keuze = klaar ? { layout: null, expliciet: false } : await zoekLayout(db, job);
332
350
  const layout = keuze.layout;
333
- const printer = await zoekPrinter(job, layout);
351
+ const printer = await zoekPrinter(db, job, layout);
334
352
  if (!printer?.extern_printer_id) {
335
- await mislukt(job, "Er is geen printer gekoppeld voor dit document.", true);
353
+ await mislukt(db, job, "Er is geen printer gekoppeld voor dit document.", true);
336
354
  return "mislukt";
337
355
  }
338
356
  let pdfBase64 = klaar;
339
357
  if (!pdfBase64) {
340
- const html = await bouwHtml(job, keuze);
358
+ const html = await bouwHtml(db, job, keuze);
341
359
  if (!heeftZichtbareInhoud(html)) {
342
360
  throw new GeenDocumentFout("Het document was leeg: er zijn geen gegevens gevonden om af te drukken. " +
343
361
  "Controleer of de layout blokken bevat en of de order gegevens heeft.");
@@ -357,7 +375,7 @@ async function verwerkJob(job) {
357
375
  pdfBase64,
358
376
  kopieen: Number(job.kopieen ?? 1),
359
377
  });
360
- await supabaseAdmin
378
+ await db
361
379
  .from("print_jobs")
362
380
  .update({
363
381
  printer_id: printer.id,
@@ -368,20 +386,20 @@ async function verwerkJob(job) {
368
386
  updated_at: new Date().toISOString(),
369
387
  })
370
388
  .eq("id", job.id);
371
- await log(job.id, "verstuurd", `Naar printer ${printer.naam ?? ""}`);
389
+ await log(db, job.id, "verstuurd", `Naar printer ${printer.naam ?? ""}`);
372
390
  return "verstuurd";
373
391
  }
374
392
  catch (e) {
375
393
  // Ontbreekt er een document of layout? Dan heeft opnieuw proberen geen zin.
376
394
  const blijvend = e instanceof GeenDocumentFout;
377
395
  const tijdelijk = !blijvend && (e instanceof PdfRenderFout || e?.name === "PrintToegangFout");
378
- await mislukt(job, e instanceof Error ? e.message : "Afdrukken mislukt", tijdelijk);
396
+ await mislukt(db, job, e instanceof Error ? e.message : "Afdrukken mislukt", tijdelijk);
379
397
  return "mislukt";
380
398
  }
381
399
  }
382
400
  /** Werkt de status bij van opdrachten die al naar een printer zijn gestuurd. */
383
- async function synchroniseerStatussen() {
384
- const { data } = await supabaseAdmin
401
+ async function synchroniseerStatussen(db) {
402
+ const { data } = await db
385
403
  .from("print_jobs")
386
404
  .select("id, extern_job_id")
387
405
  .eq("status", "bezig")
@@ -392,7 +410,7 @@ async function synchroniseerStatussen() {
392
410
  try {
393
411
  const status = await opdrachtStatus(String(job.extern_job_id));
394
412
  if (status === "voltooid" || status === "mislukt") {
395
- await supabaseAdmin
413
+ await db
396
414
  .from("print_jobs")
397
415
  .update({
398
416
  status,
@@ -401,7 +419,7 @@ async function synchroniseerStatussen() {
401
419
  updated_at: new Date().toISOString(),
402
420
  })
403
421
  .eq("id", job.id);
404
- await log(job.id, status);
422
+ await log(db, job.id, status);
405
423
  bijgewerkt++;
406
424
  }
407
425
  }
@@ -412,15 +430,15 @@ async function synchroniseerStatussen() {
412
430
  return bijgewerkt;
413
431
  }
414
432
  /** Eén ronde: wachtende opdrachten afdrukken en statussen bijwerken. */
415
- export async function verwerkWachtrij(max = 5) {
416
- const { data, error } = await supabaseAdmin.rpc("claim_cloud_print_jobs", { _max: max });
433
+ export async function verwerkWachtrij(db, max = 5) {
434
+ const { data, error } = await db.rpc("claim_cloud_print_jobs", { _max: max });
417
435
  if (error)
418
436
  throw new Error(error.message);
419
437
  const jobs = arr(data);
420
438
  let verstuurd = 0;
421
439
  let mislukteJobs = 0;
422
440
  for (const job of jobs) {
423
- const uitkomst = await verwerkJob(job);
441
+ const uitkomst = await verwerkJob(db, job);
424
442
  if (uitkomst === "verstuurd")
425
443
  verstuurd++;
426
444
  else
@@ -430,6 +448,6 @@ export async function verwerkWachtrij(max = 5) {
430
448
  opgepakt: jobs.length,
431
449
  verstuurd,
432
450
  mislukt: mislukteJobs,
433
- bijgewerkt: await synchroniseerStatussen(),
451
+ bijgewerkt: await synchroniseerStatussen(db),
434
452
  };
435
453
  }