@flowselections/layout-maker 1.8.3 → 1.13.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 (68) hide show
  1. package/README.md +139 -132
  2. package/dist-lib/components/ComputersLijst.d.ts +2 -1
  3. package/dist-lib/components/ComputersLijst.d.ts.map +1 -1
  4. package/dist-lib/components/ComputersLijst.js +2 -2
  5. package/dist-lib/components/DocumentRouteringPage.d.ts +2 -0
  6. package/dist-lib/components/DocumentRouteringPage.d.ts.map +1 -0
  7. package/dist-lib/components/DocumentRouteringPage.js +115 -0
  8. package/dist-lib/components/LayoutsPage.d.ts.map +1 -1
  9. package/dist-lib/components/LayoutsPage.js +13 -8
  10. package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
  11. package/dist-lib/components/PrintQueuePage.js +16 -1
  12. package/dist-lib/components/PrintStatusBanner.d.ts +8 -0
  13. package/dist-lib/components/PrintStatusBanner.d.ts.map +1 -0
  14. package/dist-lib/components/PrintStatusBanner.js +15 -0
  15. package/dist-lib/components/PrinterSetupWizard.js +1 -1
  16. package/dist-lib/components/PrintersPage.d.ts.map +1 -1
  17. package/dist-lib/components/PrintersPage.js +7 -23
  18. package/dist-lib/components/WerkplekConfiguratiePage.d.ts.map +1 -1
  19. package/dist-lib/components/WerkplekConfiguratiePage.js +35 -24
  20. package/dist-lib/components/WerkplekkenTabel.d.ts +2 -2
  21. package/dist-lib/components/WerkplekkenTabel.d.ts.map +1 -1
  22. package/dist-lib/components/WerkplekkenTabel.js +4 -3
  23. package/dist-lib/index.d.ts +8 -3
  24. package/dist-lib/index.d.ts.map +1 -1
  25. package/dist-lib/index.js +9 -5
  26. package/dist-lib/integrations/supabase/auth-middleware.d.ts +491 -145
  27. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  28. package/dist-lib/integrations/supabase/client.server.d.ts +491 -145
  29. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  30. package/dist-lib/integrations/supabase/types.d.ts +505 -150
  31. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  32. package/dist-lib/lib/aiLayout.functions.d.ts +491 -145
  33. package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
  34. package/dist-lib/lib/aiLayout.server.js +9 -9
  35. package/dist-lib/lib/browserPrint.js +5 -5
  36. package/dist-lib/lib/documentBron.d.ts +35 -0
  37. package/dist-lib/lib/documentBron.d.ts.map +1 -0
  38. package/dist-lib/lib/documentBron.js +62 -0
  39. package/dist-lib/lib/documentRoutering.d.ts +23 -0
  40. package/dist-lib/lib/documentRoutering.d.ts.map +1 -0
  41. package/dist-lib/lib/documentRoutering.js +58 -0
  42. package/dist-lib/lib/documentTypes.d.ts +61 -0
  43. package/dist-lib/lib/documentTypes.d.ts.map +1 -1
  44. package/dist-lib/lib/documentTypes.js +64 -0
  45. package/dist-lib/lib/formaatPrinters.d.ts +5 -0
  46. package/dist-lib/lib/formaatPrinters.d.ts.map +1 -1
  47. package/dist-lib/lib/formaatPrinters.js +12 -0
  48. package/dist-lib/lib/layoutPreview.js +7 -7
  49. package/dist-lib/lib/pakbonHtml.js +50 -50
  50. package/dist-lib/lib/printApi.d.ts +20 -5
  51. package/dist-lib/lib/printApi.d.ts.map +1 -1
  52. package/dist-lib/lib/printApi.js +93 -32
  53. package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
  54. package/dist-lib/lib/printQueue.server.js +72 -1
  55. package/dist-lib/lib/printService.functions.d.ts +1964 -580
  56. package/dist-lib/lib/printService.functions.d.ts.map +1 -1
  57. package/dist-lib/lib/printerTelling.d.ts +24 -0
  58. package/dist-lib/lib/printerTelling.d.ts.map +1 -0
  59. package/dist-lib/lib/printerTelling.js +41 -0
  60. package/dist-lib/lib/productiebonHtml.js +15 -15
  61. package/dist-lib/lib/profielHtml.js +18 -18
  62. package/dist-lib/lib/supabaseAdmin.server.d.ts +5 -5
  63. package/dist-lib/lib/supabaseAdmin.server.js +43 -43
  64. package/dist-lib/lib/testpagina.js +1 -1
  65. package/dist-lib/lib/useDocumentData.d.ts +4 -0
  66. package/dist-lib/lib/useDocumentData.d.ts.map +1 -1
  67. package/dist-lib/lib/useDocumentData.js +130 -1
  68. package/package.json +6 -1
@@ -0,0 +1,24 @@
1
+ export interface PrinterTelling {
2
+ /** Printers die het printprogramma op die computer ziet. */
3
+ gevonden: number;
4
+ /** Printers die hier zijn ingesteld en dus gebruikt kunnen worden. */
5
+ ingesteld: number;
6
+ /** Ingestelde printers met minstens één gekoppeld ontwerp. */
7
+ gekoppeld: number;
8
+ locaties: string[];
9
+ }
10
+ interface IngesteldePrinter {
11
+ id: string;
12
+ locatie?: string | null;
13
+ extern_printer_id?: string | null;
14
+ }
15
+ interface GevondenPrinter {
16
+ id: string;
17
+ computer?: string | null;
18
+ }
19
+ /** Telt per computernaam hoeveel printers gevonden en ingesteld zijn. */
20
+ export declare function telPrintersPerComputer(ingestelde: IngesteldePrinter[], gevondenPrinters: GevondenPrinter[], metKoppeling?: Set<string>): Map<string, PrinterTelling>;
21
+ /** Korte, overal identieke omschrijving van de telling. */
22
+ export declare function printerTellingTekst(t?: PrinterTelling | null): string;
23
+ export {};
24
+ //# sourceMappingURL=printerTelling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"printerTelling.d.ts","sourceRoot":"","sources":["../../src/lib/printerTelling.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,gBAAgB,EAAE,eAAe,EAAE,EACnC,YAAY,GAAE,GAAG,CAAC,MAAM,CAAa,GACpC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CA0B7B;AAED,2DAA2D;AAC3D,wBAAgB,mBAAmB,CAAC,CAAC,CAAC,EAAE,cAAc,GAAG,IAAI,GAAG,MAAM,CAKrE"}
@@ -0,0 +1,41 @@
1
+ // ============================================================================
2
+ // src/lib/printerTelling.ts — één plek waar printers geteld worden, zodat elk
3
+ // scherm dezelfde getallen laat zien: gevonden op de computer vs. ingesteld
4
+ // in deze module.
5
+ // ============================================================================
6
+ /** Telt per computernaam hoeveel printers gevonden en ingesteld zijn. */
7
+ export function telPrintersPerComputer(ingestelde, gevondenPrinters, metKoppeling = new Set()) {
8
+ const map = new Map();
9
+ const leeg = () => ({ gevonden: 0, ingesteld: 0, gekoppeld: 0, locaties: [] });
10
+ const externNaarComputer = new Map();
11
+ for (const g of gevondenPrinters) {
12
+ const naam = g.computer ?? "";
13
+ if (!naam)
14
+ continue;
15
+ externNaarComputer.set(g.id, naam);
16
+ const rij = map.get(naam) ?? leeg();
17
+ rij.gevonden += 1;
18
+ map.set(naam, rij);
19
+ }
20
+ for (const p of ingestelde) {
21
+ const extern = p.extern_printer_id ?? null;
22
+ const naam = extern ? externNaarComputer.get(extern) : undefined;
23
+ if (!naam)
24
+ continue;
25
+ const rij = map.get(naam) ?? leeg();
26
+ rij.ingesteld += 1;
27
+ if (metKoppeling.has(p.id))
28
+ rij.gekoppeld += 1;
29
+ if (p.locatie && !rij.locaties.includes(p.locatie))
30
+ rij.locaties.push(p.locatie);
31
+ map.set(naam, rij);
32
+ }
33
+ return map;
34
+ }
35
+ /** Korte, overal identieke omschrijving van de telling. */
36
+ export function printerTellingTekst(t) {
37
+ const ingesteld = t?.ingesteld ?? 0;
38
+ const beschikbaar = Math.max((t?.gevonden ?? 0) - ingesteld, 0);
39
+ const eerste = `${ingesteld} ingesteld`;
40
+ return beschikbaar > 0 ? `${eerste} · ${beschikbaar} nog beschikbaar` : eerste;
41
+ }
@@ -147,20 +147,20 @@ export function renderProductiebonDocument(config, gegevens, opties = {}) {
147
147
  return inhoud ? `<div class="blok">${inhoud}</div>` : "";
148
148
  })
149
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; }
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
165
  </style></head><body>${body}</body></html>`;
166
166
  }
@@ -110,8 +110,8 @@ function regeltabel(regels) {
110
110
  const eenheid = r["eenheid"] ?? "";
111
111
  return `<tr><td>${esc(code)}</td><td>${esc(omschrijving)}</td><td style="text-align:right">${esc(aantal)}</td><td>${esc(eenheid)}</td></tr>`;
112
112
  };
113
- return `<table class="tabel"><colgroup><col style="width:20%" /><col style="width:52%" /><col style="width:16%" /><col style="width:12%" /></colgroup>
114
- <thead><tr class="onder"><th>Code</th><th>Omschrijving</th><th style="text-align:right">Aantal</th><th>Eenheid</th></tr></thead>
113
+ return `<table class="tabel"><colgroup><col style="width:20%" /><col style="width:52%" /><col style="width:16%" /><col style="width:12%" /></colgroup>
114
+ <thead><tr class="onder"><th>Code</th><th>Omschrijving</th><th style="text-align:right">Aantal</th><th>Eenheid</th></tr></thead>
115
115
  <tbody>${regels.map(rij).join("")}</tbody></table>`;
116
116
  }
117
117
  function totalenBlok(regels, velden) {
@@ -236,21 +236,21 @@ export function renderProfielDocument(documenttype, config, gegevens, opties = {
236
236
  .map((groep) => groepHtml(groep, cfg, velden, data, opties))
237
237
  .filter(Boolean)
238
238
  .join("");
239
- return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
240
- <title>${esc(opties.titel ?? profiel.label)}</title>
241
- <style>
242
- @page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
243
- * { box-sizing: border-box; }
244
- html, body { margin: 0; padding: 0; }
245
- body { font-family: Arial, Helvetica, sans-serif; font-size: 9pt; color: #111827; line-height: 1.35; }
246
- .blok { margin-bottom: 2.5mm; }
247
- .kop { border-bottom: 0.3mm solid #d1d5db; padding-bottom: 1mm; }
248
- .sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
249
- .vet { font-weight: 600; }
250
- .klein { font-size: 85%; color: #6b7280; }
251
- .kv { display: flex; justify-content: space-between; gap: 3mm; }
252
- .kv .k { color: #6b7280; }
253
- .tabel { width: 100%; border-collapse: collapse; table-layout: fixed; }
254
- .tabel th { text-align: left; font-weight: 600; }
239
+ return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
240
+ <title>${esc(opties.titel ?? profiel.label)}</title>
241
+ <style>
242
+ @page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
243
+ * { box-sizing: border-box; }
244
+ html, body { margin: 0; padding: 0; }
245
+ body { font-family: Arial, Helvetica, sans-serif; font-size: 9pt; color: #111827; line-height: 1.35; }
246
+ .blok { margin-bottom: 2.5mm; }
247
+ .kop { border-bottom: 0.3mm solid #d1d5db; padding-bottom: 1mm; }
248
+ .sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
249
+ .vet { font-weight: 600; }
250
+ .klein { font-size: 85%; color: #6b7280; }
251
+ .kv { display: flex; justify-content: space-between; gap: 3mm; }
252
+ .kv .k { color: #6b7280; }
253
+ .tabel { width: 100%; border-collapse: collapse; table-layout: fixed; }
254
+ .tabel th { text-align: left; font-weight: 600; }
255
255
  </style></head><body>${kop}${body}</body></html>`;
256
256
  }
@@ -1,6 +1,6 @@
1
- import { type SupabaseClient } from "@supabase/supabase-js";
2
- /** Uitleg voor de gebruiker als de serverinstellingen ontbreken. */
3
- export declare function adminConfiguratieFout(): string | null;
4
- /** Lazy adminclient: pas bij het eerste gebruik worden de instellingen gelezen. */
5
- export declare const adminDb: SupabaseClient<any, any, any, any, any>;
1
+ import { type SupabaseClient } from "@supabase/supabase-js";
2
+ /** Uitleg voor de gebruiker als de serverinstellingen ontbreken. */
3
+ export declare function adminConfiguratieFout(): string | null;
4
+ /** Lazy adminclient: pas bij het eerste gebruik worden de instellingen gelezen. */
5
+ export declare const adminDb: SupabaseClient<any, any, any, any, any>;
6
6
  //# sourceMappingURL=supabaseAdmin.server.d.ts.map
@@ -1,43 +1,43 @@
1
- // ============================================================================
2
- // src/lib/supabaseAdmin.server.ts — adminclient die in elke shell werkt.
3
- // Leest de service-role sleutel uit meerdere mogelijke namen, zodat de module
4
- // niet afhankelijk is van hoe een shell zijn omgeving heeft ingericht.
5
- // ============================================================================
6
- import { createClient } from "@supabase/supabase-js";
7
- function lees(...namen) {
8
- for (const naam of namen) {
9
- const waarde = process.env[naam];
10
- if (waarde && waarde.trim().length > 0)
11
- return waarde.trim();
12
- }
13
- return undefined;
14
- }
15
- /** Uitleg voor de gebruiker als de serverinstellingen ontbreken. */
16
- export function adminConfiguratieFout() {
17
- const url = lees("SUPABASE_URL", "VITE_SUPABASE_URL");
18
- const key = lees("SERVICE_ROLE_KEY", "SUPABASE_SERVICE_ROLE_KEY");
19
- if (url && key)
20
- return null;
21
- const mist = [!url ? "SUPABASE_URL" : null, !key ? "SERVICE_ROLE_KEY" : null]
22
- .filter(Boolean)
23
- .join(" en ");
24
- return `Achtergrondprinten is niet ingesteld: ${mist} ontbreekt in deze omgeving.`;
25
- }
26
- function maakClient() {
27
- const url = lees("SUPABASE_URL", "VITE_SUPABASE_URL");
28
- const key = lees("SERVICE_ROLE_KEY", "SUPABASE_SERVICE_ROLE_KEY");
29
- if (!url || !key)
30
- throw new Error(adminConfiguratieFout() ?? "Serverinstellingen ontbreken.");
31
- return createClient(url, key, {
32
- auth: { storage: undefined, persistSession: false, autoRefreshToken: false },
33
- });
34
- }
35
- let _client;
36
- /** Lazy adminclient: pas bij het eerste gebruik worden de instellingen gelezen. */
37
- export const adminDb = new Proxy({}, {
38
- get(_t, prop, receiver) {
39
- if (!_client)
40
- _client = maakClient();
41
- return Reflect.get(_client, prop, receiver);
42
- },
43
- });
1
+ // ============================================================================
2
+ // src/lib/supabaseAdmin.server.ts — adminclient die in elke shell werkt.
3
+ // Leest de service-role sleutel uit meerdere mogelijke namen, zodat de module
4
+ // niet afhankelijk is van hoe een shell zijn omgeving heeft ingericht.
5
+ // ============================================================================
6
+ import { createClient } from "@supabase/supabase-js";
7
+ function lees(...namen) {
8
+ for (const naam of namen) {
9
+ const waarde = process.env[naam];
10
+ if (waarde && waarde.trim().length > 0)
11
+ return waarde.trim();
12
+ }
13
+ return undefined;
14
+ }
15
+ /** Uitleg voor de gebruiker als de serverinstellingen ontbreken. */
16
+ export function adminConfiguratieFout() {
17
+ const url = lees("SUPABASE_URL", "VITE_SUPABASE_URL");
18
+ const key = lees("SERVICE_ROLE_KEY", "SUPABASE_SERVICE_ROLE_KEY");
19
+ if (url && key)
20
+ return null;
21
+ const mist = [!url ? "SUPABASE_URL" : null, !key ? "SERVICE_ROLE_KEY" : null]
22
+ .filter(Boolean)
23
+ .join(" en ");
24
+ return `Achtergrondprinten is niet ingesteld: ${mist} ontbreekt in deze omgeving.`;
25
+ }
26
+ function maakClient() {
27
+ const url = lees("SUPABASE_URL", "VITE_SUPABASE_URL");
28
+ const key = lees("SERVICE_ROLE_KEY", "SUPABASE_SERVICE_ROLE_KEY");
29
+ if (!url || !key)
30
+ throw new Error(adminConfiguratieFout() ?? "Serverinstellingen ontbreken.");
31
+ return createClient(url, key, {
32
+ auth: { storage: undefined, persistSession: false, autoRefreshToken: false },
33
+ });
34
+ }
35
+ let _client;
36
+ /** Lazy adminclient: pas bij het eerste gebruik worden de instellingen gelezen. */
37
+ export const adminDb = new Proxy({}, {
38
+ get(_t, prop, receiver) {
39
+ if (!_client)
40
+ _client = maakClient();
41
+ return Reflect.get(_client, prop, receiver);
42
+ },
43
+ });
@@ -5,7 +5,7 @@ import { toast } from "@flowselections/core";
5
5
  import { drukAf } from "./browserPrint.js";
6
6
  import { printDirect } from "./directPrint.js";
7
7
  export async function drukTestpaginaAf(printerId, naam) {
8
- const html = `<div style="padding:20mm;font-size:14pt"><h1 style="font-size:20pt">Testpagina</h1>
8
+ const html = `<div style="padding:20mm;font-size:14pt"><h1 style="font-size:20pt">Testpagina</h1>
9
9
  <p>Deze pagina hoort uit: <strong>${naam}</strong></p></div>`;
10
10
  const opdracht = {
11
11
  documenttype: "pakbon",
@@ -30,7 +30,11 @@ export interface PrintJobModel {
30
30
  created_at: string;
31
31
  voltooid_op: string | null;
32
32
  extern_job_id?: string | null;
33
+ /** Vrije gegevens van de aanleverende module (o.a. het orderkenmerk). */
34
+ payload?: Record<string, unknown> | null;
33
35
  }
36
+ export declare function zorgVoorFloridayLayouts(): Promise<boolean>;
37
+ export declare function zorgVoorStandaardLayouts(): Promise<boolean>;
34
38
  export declare function useLayouts(): {
35
39
  layouts: LayoutModel[];
36
40
  loading: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"useDocumentData.d.ts","sourceRoot":"","sources":["../../src/lib/useDocumentData.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIrF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAE/B;AAID,wBAAgB,UAAU;;;;EAoBzB;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,UAAU,GAAG,WAAW,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,mBAQA;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,mBA2B/C;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,iBAG/C;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,iBAM5E;AAwBD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM;;;;;;;EAkD/C;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,kBAAkB,EAAE,EAC/B,YAAY,CAAC,EAAE,YAAY,iBA+C5B;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,UAAU,EAAE,MAAM,mBAmBvG;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM;;YAEjC,MAAM;sBAAgB,MAAM;oBAAc,MAAM,GAAG,IAAI;oBAAc,MAAM;kBAAY,OAAO;;;EAcvG;AAID,wBAAgB,WAAW;;;mBAEmC,MAAM;oBAAc,MAAM;;;;EAmBvF;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,iBAS9E;AAED,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,iBAGhD;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,iBAMtF;AAID,wBAAgB,YAAY;;;;EAoB3B;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAS/D;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,iBAGA"}
1
+ {"version":3,"file":"useDocumentData.d.ts","sourceRoot":"","sources":["../../src/lib/useDocumentData.ts"],"names":[],"mappings":"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"}
@@ -4,19 +4,148 @@
4
4
  import { useCallback, useEffect, useState } from "react";
5
5
  import { toast } from "@flowselections/core";
6
6
  import { supabase } from "./supabaseClient.js";
7
+ import { FLORIDAY_LAYOUT_TOELICHTING, FLORIDAY_SYSTEEM_LAYOUTS, STANDAARD_LAYOUTS } from "./documentTypes.js";
8
+ import { standaardProductiebonConfig } from "./productiebonBuilder.js";
7
9
  const arr = (v) => (Array.isArray(v) ? v : []);
8
10
  // --- Layouts ---------------------------------------------------------------
11
+ /**
12
+ * Zorgt dat de vaste Floriday-layouts altijd bestaan, ook in een verse shell
13
+ * waar de seed-SQL nog niet is gedraaid. Idempotent en stil bij fouten.
14
+ */
15
+ let floridaySeedGedaan = false;
16
+ export async function zorgVoorFloridayLayouts() {
17
+ if (floridaySeedGedaan)
18
+ return false;
19
+ try {
20
+ const namen = FLORIDAY_SYSTEEM_LAYOUTS.map((l) => l.naam);
21
+ const { data, error } = await supabase
22
+ .from("document_layouts")
23
+ .select("naam")
24
+ .in("naam", namen);
25
+ if (error)
26
+ return false;
27
+ const bestaand = new Set(arr(data).map((r) => r.naam));
28
+ const ontbreekt = FLORIDAY_SYSTEEM_LAYOUTS.filter((l) => !bestaand.has(l.naam));
29
+ floridaySeedGedaan = true;
30
+ if (!ontbreekt.length)
31
+ return false;
32
+ const rijen = ontbreekt.map((l) => ({
33
+ naam: l.naam,
34
+ documenttype: l.documenttype,
35
+ omschrijving: FLORIDAY_LAYOUT_TOELICHTING,
36
+ papierformaat: l.papierformaat,
37
+ breedte_mm: l.breedte_mm,
38
+ hoogte_mm: l.hoogte_mm,
39
+ orientatie: "portrait",
40
+ bron: "floriday",
41
+ systeem: true,
42
+ actief: true,
43
+ }));
44
+ const { error: insertError } = await supabase.from("document_layouts").insert(rijen);
45
+ return !insertError;
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
51
+ /**
52
+ * Zorgt dat de eigen standaardlayouts (Pakbon, Afleverbrief (BVO)) bij een
53
+ * verse shell worden aangemaakt. In tegenstelling tot de Floriday-layouts
54
+ * gebeurt dit slechts één keer per shell, bijgehouden in public.app_settings
55
+ * (key = "standaard_layouts_geseed"). Verwijdert de gebruiker een layout, dan
56
+ * wordt deze niet opnieuw aangemaakt.
57
+ */
58
+ let standaardSeedGedaan = false;
59
+ const STANDAARD_SEED_KEY = "standaard_layouts_geseed";
60
+ /**
61
+ * Versie van de standaardset. Komt er een standaarddocument bij, dan gaat dit
62
+ * getal omhoog en wordt in bestaande shells alleen het nieuwe document alsnog
63
+ * eenmalig aangemaakt. Eerder verwijderde documenten komen niet terug, want
64
+ * per versie wordt maar één keer gekeken.
65
+ */
66
+ const STANDAARD_SEED_VERSIE = "2";
67
+ export async function zorgVoorStandaardLayouts() {
68
+ if (standaardSeedGedaan)
69
+ return false;
70
+ try {
71
+ const { data: vlag } = await supabase
72
+ .from("app_settings")
73
+ .select("value")
74
+ .eq("key", STANDAARD_SEED_KEY)
75
+ .maybeSingle();
76
+ const huidig = String(vlag?.value ?? "");
77
+ if (huidig === STANDAARD_SEED_VERSIE) {
78
+ standaardSeedGedaan = true;
79
+ return false;
80
+ }
81
+ const namen = STANDAARD_LAYOUTS.map((l) => l.naam);
82
+ const { data, error } = await supabase
83
+ .from("document_layouts")
84
+ .select("naam")
85
+ .in("naam", namen);
86
+ if (error)
87
+ return false;
88
+ const bestaand = new Set(arr(data).map((r) => r.naam));
89
+ const ontbreekt = STANDAARD_LAYOUTS.filter((l) => !bestaand.has(l.naam));
90
+ standaardSeedGedaan = true;
91
+ let gelukt = true;
92
+ if (ontbreekt.length > 0) {
93
+ const rijen = ontbreekt.map((l) => ({
94
+ naam: l.naam,
95
+ documenttype: l.documenttype,
96
+ omschrijving: l.omschrijving,
97
+ papierformaat: l.papierformaat,
98
+ breedte_mm: l.breedte_mm,
99
+ hoogte_mm: l.hoogte_mm,
100
+ orientatie: "portrait",
101
+ bron: "eigen",
102
+ systeem: false,
103
+ actief: true,
104
+ // De productiebon start met de vaste blokindeling van deze module,
105
+ // zodat hij in een verse shell niet leeg is.
106
+ config: l.documenttype === "productiebon"
107
+ ? { productiebon: standaardProductiebonConfig() }
108
+ : {},
109
+ }));
110
+ const { error: insertError } = await supabase
111
+ .from("document_layouts")
112
+ .insert(rijen);
113
+ if (insertError) {
114
+ // Niet afvinken: bij een volgende poging (bijv. na het bijwerken van
115
+ // de database) wordt het opnieuw geprobeerd.
116
+ standaardSeedGedaan = false;
117
+ gelukt = false;
118
+ }
119
+ }
120
+ if (gelukt) {
121
+ await supabase
122
+ .from("app_settings")
123
+ .upsert({ key: STANDAARD_SEED_KEY, value: STANDAARD_SEED_VERSIE }, {
124
+ onConflict: "key",
125
+ });
126
+ }
127
+ return gelukt && ontbreekt.length > 0;
128
+ }
129
+ catch {
130
+ return false;
131
+ }
132
+ }
9
133
  export function useLayouts() {
10
134
  const [layouts, setLayouts] = useState([]);
11
135
  const [loading, setLoading] = useState(true);
12
136
  const load = useCallback(async (stil = false) => {
13
137
  if (!stil)
14
138
  setLoading(true);
139
+ const [geseedStd, geseedFlo] = await Promise.all([
140
+ zorgVoorStandaardLayouts(),
141
+ zorgVoorFloridayLayouts(),
142
+ ]);
143
+ const geseed = geseedStd || geseedFlo;
15
144
  const { data, error } = await supabase
16
145
  .from("document_layouts")
17
146
  .select("*")
18
147
  .order("updated_at", { ascending: false });
19
- if (error && !stil)
148
+ if (error && !stil && !geseed)
20
149
  toast.error("Layouts laden mislukt");
21
150
  setLayouts(arr(data));
22
151
  setLoading(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/layout-maker",
3
- "version": "1.8.3",
3
+ "version": "1.13.2",
4
4
  "flowselections": {
5
5
  "moduleId": "layout-maker",
6
6
  "pages": [
@@ -19,6 +19,11 @@
19
19
  "route": "layouts-printers/printers/$computerId",
20
20
  "title": "Werkplek configureren"
21
21
  },
22
+ {
23
+ "export": "DocumentRouteringPage",
24
+ "route": "layouts-printers/routering",
25
+ "title": "Routering"
26
+ },
22
27
  {
23
28
  "export": "PrintQueuePage",
24
29
  "route": "layouts-printers/wachtrij",