@flowselections/layout-maker 1.45.8 → 1.45.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -139
- package/dist-lib/components/AfdrukKnop.d.ts +19 -19
- package/dist-lib/components/NetwerkPrintersDialog.d.ts +7 -7
- package/dist-lib/components/PdfMapToestemmingBanner.d.ts.map +1 -1
- package/dist-lib/components/PdfMapToestemmingBanner.js +55 -8
- package/dist-lib/components/PrinterSetupWizard.js +3 -3
- package/dist-lib/components/PrintersRedirectPage.d.ts +1 -1
- package/dist-lib/components/PrintersRedirectPage.js +14 -14
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +192 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +192 -0
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts +192 -0
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +192 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/aiLayout.functions.d.ts +192 -0
- package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
- package/dist-lib/lib/aiLayout.server.js +9 -9
- package/dist-lib/lib/browserPrint.js +1 -1
- package/dist-lib/lib/layoutPreview.js +7 -7
- package/dist-lib/lib/pakbonHtml.js +58 -58
- package/dist-lib/lib/printService.functions.d.ts +768 -0
- package/dist-lib/lib/printService.functions.d.ts.map +1 -1
- package/dist-lib/lib/productiebonHtml.js +15 -15
- package/dist-lib/lib/profielHtml.js +18 -18
- package/dist-lib/lib/supabaseAdmin.server.d.ts +5 -5
- package/dist-lib/lib/supabaseAdmin.server.js +43 -43
- package/dist-lib/lib/testpagina.js +3 -3
- package/dist-lib/lib/testprint.js +4 -4
- package/package.json +158 -158
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
// src/lib/aiLayout.server.ts — hulpfuncties voor de AI-layoutgenerator
|
|
3
3
|
// ============================================================================
|
|
4
4
|
const GATEWAY = "https://ai.gateway.lovable.dev/v1/chat/completions";
|
|
5
|
-
const SYSTEM_PROMPT = `Je bent een documentontwerper voor een Nederlands ERP-systeem.
|
|
6
|
-
Je analyseert een bestaand document (PDF of afbeelding) en zet het om naar een herbruikbare layout.
|
|
7
|
-
Herken logo's, adresblokken, koppen, tabellen met kolommen, totalen, barcodes en voetteksten.
|
|
8
|
-
Vervang concrete gegevens door veldcodes zoals {{order.nummer}}, {{klant.naam}}, {{klant.adres}},
|
|
9
|
-
{{factuur.totaal}}, {{systeem.datum}}. Coördinaten en afmetingen zijn in millimeters, linksboven is 0,0.
|
|
10
|
-
Herken logo's als element van het type "logo". Je krijgt een lijst met logo's die al in de centrale
|
|
11
|
-
Logo Bibliotheek staan; als het herkende logo daar duidelijk bij past, zet dan die exacte naam in
|
|
12
|
-
"logo_naam". Past het bij geen enkel bekend logo, laat "logo_naam" dan leeg zodat het als nieuw logo
|
|
13
|
-
kan worden voorgesteld.
|
|
5
|
+
const SYSTEM_PROMPT = `Je bent een documentontwerper voor een Nederlands ERP-systeem.
|
|
6
|
+
Je analyseert een bestaand document (PDF of afbeelding) en zet het om naar een herbruikbare layout.
|
|
7
|
+
Herken logo's, adresblokken, koppen, tabellen met kolommen, totalen, barcodes en voetteksten.
|
|
8
|
+
Vervang concrete gegevens door veldcodes zoals {{order.nummer}}, {{klant.naam}}, {{klant.adres}},
|
|
9
|
+
{{factuur.totaal}}, {{systeem.datum}}. Coördinaten en afmetingen zijn in millimeters, linksboven is 0,0.
|
|
10
|
+
Herken logo's als element van het type "logo". Je krijgt een lijst met logo's die al in de centrale
|
|
11
|
+
Logo Bibliotheek staan; als het herkende logo daar duidelijk bij past, zet dan die exacte naam in
|
|
12
|
+
"logo_naam". Past het bij geen enkel bekend logo, laat "logo_naam" dan leeg zodat het als nieuw logo
|
|
13
|
+
kan worden voorgesteld.
|
|
14
14
|
Antwoord uitsluitend met JSON.`;
|
|
15
15
|
const SCHEMA = {
|
|
16
16
|
type: "object",
|
|
@@ -26,7 +26,7 @@ export function paginaCss(formaat, orientatie, margeMm = 0) {
|
|
|
26
26
|
const gedraaid = formaat && orientatie === "landscape"
|
|
27
27
|
? `${formaat.hoogte}mm ${formaat.breedte}mm`
|
|
28
28
|
: size;
|
|
29
|
-
return `@page { size: ${gedraaid}; margin: ${margeMm}mm; }
|
|
29
|
+
return `@page { size: ${gedraaid}; margin: ${margeMm}mm; }
|
|
30
30
|
@media print { html, body { margin: 0; padding: 0; } }`;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
@@ -81,8 +81,8 @@ function elementHtml(el, ctx) {
|
|
|
81
81
|
return `<div style="${base};border-radius:50%;border:${s.randbreedte || 0.3}mm solid ${s.randkleur ?? "#111827"}"></div>`;
|
|
82
82
|
case "barcode":
|
|
83
83
|
return inhoud
|
|
84
|
-
? `<div style="${base};display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:monospace">
|
|
85
|
-
<div class="barcode-bars" data-barcode="${esc(inhoud)}" style="width:100%;height:70%;display:flex;background:#fff">${code128BarsHtml(inhoud)}</div>
|
|
84
|
+
? `<div style="${base};display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:monospace">
|
|
85
|
+
<div class="barcode-bars" data-barcode="${esc(inhoud)}" style="width:100%;height:70%;display:flex;background:#fff">${code128BarsHtml(inhoud)}</div>
|
|
86
86
|
<div style="font-size:7pt">${esc(inhoud)}</div></div>`
|
|
87
87
|
: "";
|
|
88
88
|
case "qrcode":
|
|
@@ -128,10 +128,10 @@ export function bouwDocumentHtml(layout, elementen, gegevens) {
|
|
|
128
128
|
const body = zichtbaar.map((e) => elementHtml(e, ctx)).join("");
|
|
129
129
|
const b = layout.orientatie === "landscape" ? layout.hoogte_mm : layout.breedte_mm;
|
|
130
130
|
const h = layout.orientatie === "landscape" ? layout.breedte_mm : layout.hoogte_mm;
|
|
131
|
-
return `<!doctype html><html lang="nl"><head><meta charset="utf-8"><title>${esc(layout.naam)}</title>
|
|
132
|
-
<style>@page{size:${b}mm ${h}mm;margin:0}
|
|
133
|
-
body{margin:0;background:#e5e7eb}
|
|
134
|
-
.pagina{position:relative;width:${b}mm;height:${h}mm;background:#fff;margin:0 auto;overflow:hidden}
|
|
135
|
-
@media print{body{background:#fff}}</style></head>
|
|
131
|
+
return `<!doctype html><html lang="nl"><head><meta charset="utf-8"><title>${esc(layout.naam)}</title>
|
|
132
|
+
<style>@page{size:${b}mm ${h}mm;margin:0}
|
|
133
|
+
body{margin:0;background:#e5e7eb}
|
|
134
|
+
.pagina{position:relative;width:${b}mm;height:${h}mm;background:#fff;margin:0 auto;overflow:hidden}
|
|
135
|
+
@media print{body{background:#fff}}</style></head>
|
|
136
136
|
<body><div class="pagina">${body}</div></body></html>`;
|
|
137
137
|
}
|
|
@@ -751,64 +751,64 @@ export function renderPakbonDocument(config, order, opties = {}) {
|
|
|
751
751
|
// leest dit uit de meta, zodat de wachtrij niets extra hoeft door te geven.
|
|
752
752
|
const totalen = arr(leesPakbonConfig(config).secties).find((s) => s.type === "totalen");
|
|
753
753
|
const paginanummers = !!totalen && opt(totalen, "toon_paginanummer", false) === true;
|
|
754
|
-
return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
|
|
755
|
-
<meta name="pdf-paginanummers" content="${paginanummers ? "ja" : "nee"}" />
|
|
756
|
-
<title>${esc(opties.titel ?? "Pakbon")}</title>
|
|
757
|
-
|
|
758
|
-
<style>
|
|
759
|
-
@page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
|
|
760
|
-
* { box-sizing: border-box; }
|
|
761
|
-
html, body { margin: 0; padding: 0; }
|
|
762
|
-
body { font-family: ${font}; font-size: ${grootte}pt; color: #111827; line-height: 1.35; }
|
|
763
|
-
.pakbonvariant { border-top: 0.6mm solid #111827; border-bottom: 0.6mm solid #111827; padding: 2mm 1mm; margin-bottom: 2mm; text-align: center; font-size: 15pt; font-weight: 800; line-height: 1.1; }
|
|
764
|
-
.blok { margin-bottom: 2mm; }
|
|
765
|
-
.sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
|
|
766
|
-
.fustgroepkop { display: flex; justify-content: space-between; font-weight: 600; color: #111827; border-bottom: 0.45mm solid #111827; padding-bottom: 0.5mm; margin-bottom: 0.6mm; }
|
|
767
|
-
|
|
768
|
-
.vet { font-weight: 600; }
|
|
769
|
-
.kv { display: flex; justify-content: space-between; gap: 3mm; }
|
|
770
|
-
.kv .k { color: #6b7280; }
|
|
771
|
-
.kv .v { font-weight: 500; }
|
|
772
|
-
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6mm; }
|
|
773
|
-
.kader { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
|
|
774
|
-
table.regels { width: 100%; border-collapse: collapse; }
|
|
775
|
-
table.regels.vast { table-layout: fixed; }
|
|
776
|
-
table.regels.vast td, table.regels.vast th { overflow-wrap: anywhere; }
|
|
777
|
-
table.regels th, table.regels td { padding: 0.7mm 1mm; vertical-align: top; }
|
|
778
|
-
table.regels th { font-size: 90%; text-transform: uppercase; color: #6b7280; font-weight: 600; text-align: left; }
|
|
779
|
-
.rand { border: 0.2mm solid #d1d5db; }
|
|
780
|
-
.onder { border-bottom: 0.2mm solid #d1d5db; }
|
|
781
|
-
table.regels.compact th, table.regels.compact td { padding: 0.3mm 0.8mm; }
|
|
782
|
-
tr.zebra td { background: #f3f4f6; }
|
|
783
|
-
.plijst { margin: 0; padding-left: 4mm; }
|
|
784
|
-
.groep { margin-bottom: 1.5mm; }
|
|
785
|
-
.regelrij { display: flex; gap: 2mm; }
|
|
786
|
-
.tweekolom { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm; }
|
|
787
|
-
.karblok { margin-bottom: 2mm; }
|
|
788
|
-
.karblok.omkaderd { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
|
|
789
|
-
.karkop { display: block; padding: 0.8mm 1.5mm; border-radius: 1mm; margin-bottom: 1mm; overflow-wrap: anywhere; }
|
|
790
|
-
.karkop-titel { font-weight: 700; }
|
|
791
|
-
.karkop-meta { margin-top: 0.4mm; font-size: 78%; font-weight: 400; color: #4b5563; overflow-wrap: anywhere; }
|
|
792
|
-
.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%; }
|
|
793
|
-
.laag { margin-bottom: 1.5mm; }
|
|
794
|
-
.laagkop { display: block; font-weight: 500; border-bottom: 0.2mm solid #d1d5db; padding-bottom: 0.4mm; margin-bottom: 0.6mm; overflow-wrap: anywhere; }
|
|
795
|
-
.laagkop-meta { margin-top: 0.25mm; font-size: 82%; font-weight: 400; color: #4b5563; overflow-wrap: anywhere; }
|
|
796
|
-
.laagkop.compact { border-bottom: none; }
|
|
797
|
-
.meta { display: flex; gap: 3mm; font-size: 88%; font-weight: 400; color: #4b5563; }
|
|
798
|
-
.totalen { display: flex; flex-wrap: wrap; gap: 5mm; border-top: 0.25mm solid #d1d5db; padding-top: 1.2mm; font-weight: 500; }
|
|
799
|
-
.paginavoet { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; border-top: 0.35mm solid #9ca3af; padding-top: 1mm; }
|
|
800
|
-
.handtekening { margin-top: 3mm; }
|
|
801
|
-
.lijnveld { margin-top: 4mm; border-bottom: 0.25mm solid #6b7280; padding-bottom: 3mm; }
|
|
802
|
-
.lijnveld.hoog { padding-bottom: 10mm; }
|
|
803
|
-
.lijn { border-top: 0.25mm solid #d1d5db; margin: 1.5mm 0; }
|
|
804
|
-
.balk { height: 1mm; background: #374151; margin: 1.5mm 0; }
|
|
805
|
-
.qr { border: 0.25mm dashed #9ca3af; }
|
|
806
|
-
.barcode { display:flex; flex-direction:column; align-items:center; gap:0.8mm; } .barcode-bars { width:45mm; display:flex; background:#fff; }
|
|
807
|
-
.klein { font-size: 85%; color: #6b7280; }
|
|
808
|
-
.breekvoor { break-before: page; page-break-before: always; }
|
|
809
|
-
.heelhouden { break-inside: avoid; page-break-inside: avoid; }
|
|
810
|
-
img { max-width: 100%; }
|
|
811
|
-
</style></head>
|
|
754
|
+
return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
|
|
755
|
+
<meta name="pdf-paginanummers" content="${paginanummers ? "ja" : "nee"}" />
|
|
756
|
+
<title>${esc(opties.titel ?? "Pakbon")}</title>
|
|
757
|
+
|
|
758
|
+
<style>
|
|
759
|
+
@page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
|
|
760
|
+
* { box-sizing: border-box; }
|
|
761
|
+
html, body { margin: 0; padding: 0; }
|
|
762
|
+
body { font-family: ${font}; font-size: ${grootte}pt; color: #111827; line-height: 1.35; }
|
|
763
|
+
.pakbonvariant { border-top: 0.6mm solid #111827; border-bottom: 0.6mm solid #111827; padding: 2mm 1mm; margin-bottom: 2mm; text-align: center; font-size: 15pt; font-weight: 800; line-height: 1.1; }
|
|
764
|
+
.blok { margin-bottom: 2mm; }
|
|
765
|
+
.sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
|
|
766
|
+
.fustgroepkop { display: flex; justify-content: space-between; font-weight: 600; color: #111827; border-bottom: 0.45mm solid #111827; padding-bottom: 0.5mm; margin-bottom: 0.6mm; }
|
|
767
|
+
|
|
768
|
+
.vet { font-weight: 600; }
|
|
769
|
+
.kv { display: flex; justify-content: space-between; gap: 3mm; }
|
|
770
|
+
.kv .k { color: #6b7280; }
|
|
771
|
+
.kv .v { font-weight: 500; }
|
|
772
|
+
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6mm; }
|
|
773
|
+
.kader { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
|
|
774
|
+
table.regels { width: 100%; border-collapse: collapse; }
|
|
775
|
+
table.regels.vast { table-layout: fixed; }
|
|
776
|
+
table.regels.vast td, table.regels.vast th { overflow-wrap: anywhere; }
|
|
777
|
+
table.regels th, table.regels td { padding: 0.7mm 1mm; vertical-align: top; }
|
|
778
|
+
table.regels th { font-size: 90%; text-transform: uppercase; color: #6b7280; font-weight: 600; text-align: left; }
|
|
779
|
+
.rand { border: 0.2mm solid #d1d5db; }
|
|
780
|
+
.onder { border-bottom: 0.2mm solid #d1d5db; }
|
|
781
|
+
table.regels.compact th, table.regels.compact td { padding: 0.3mm 0.8mm; }
|
|
782
|
+
tr.zebra td { background: #f3f4f6; }
|
|
783
|
+
.plijst { margin: 0; padding-left: 4mm; }
|
|
784
|
+
.groep { margin-bottom: 1.5mm; }
|
|
785
|
+
.regelrij { display: flex; gap: 2mm; }
|
|
786
|
+
.tweekolom { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm; }
|
|
787
|
+
.karblok { margin-bottom: 2mm; }
|
|
788
|
+
.karblok.omkaderd { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
|
|
789
|
+
.karkop { display: block; padding: 0.8mm 1.5mm; border-radius: 1mm; margin-bottom: 1mm; overflow-wrap: anywhere; }
|
|
790
|
+
.karkop-titel { font-weight: 700; }
|
|
791
|
+
.karkop-meta { margin-top: 0.4mm; font-size: 78%; font-weight: 400; color: #4b5563; overflow-wrap: anywhere; }
|
|
792
|
+
.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%; }
|
|
793
|
+
.laag { margin-bottom: 1.5mm; }
|
|
794
|
+
.laagkop { display: block; font-weight: 500; border-bottom: 0.2mm solid #d1d5db; padding-bottom: 0.4mm; margin-bottom: 0.6mm; overflow-wrap: anywhere; }
|
|
795
|
+
.laagkop-meta { margin-top: 0.25mm; font-size: 82%; font-weight: 400; color: #4b5563; overflow-wrap: anywhere; }
|
|
796
|
+
.laagkop.compact { border-bottom: none; }
|
|
797
|
+
.meta { display: flex; gap: 3mm; font-size: 88%; font-weight: 400; color: #4b5563; }
|
|
798
|
+
.totalen { display: flex; flex-wrap: wrap; gap: 5mm; border-top: 0.25mm solid #d1d5db; padding-top: 1.2mm; font-weight: 500; }
|
|
799
|
+
.paginavoet { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; border-top: 0.35mm solid #9ca3af; padding-top: 1mm; }
|
|
800
|
+
.handtekening { margin-top: 3mm; }
|
|
801
|
+
.lijnveld { margin-top: 4mm; border-bottom: 0.25mm solid #6b7280; padding-bottom: 3mm; }
|
|
802
|
+
.lijnveld.hoog { padding-bottom: 10mm; }
|
|
803
|
+
.lijn { border-top: 0.25mm solid #d1d5db; margin: 1.5mm 0; }
|
|
804
|
+
.balk { height: 1mm; background: #374151; margin: 1.5mm 0; }
|
|
805
|
+
.qr { border: 0.25mm dashed #9ca3af; }
|
|
806
|
+
.barcode { display:flex; flex-direction:column; align-items:center; gap:0.8mm; } .barcode-bars { width:45mm; display:flex; background:#fff; }
|
|
807
|
+
.klein { font-size: 85%; color: #6b7280; }
|
|
808
|
+
.breekvoor { break-before: page; page-break-before: always; }
|
|
809
|
+
.heelhouden { break-inside: avoid; page-break-inside: avoid; }
|
|
810
|
+
img { max-width: 100%; }
|
|
811
|
+
</style></head>
|
|
812
812
|
<body>${body}</body></html>`;
|
|
813
813
|
}
|
|
814
814
|
/** Handig voor testen: het document met de voorbeeldgegevens. */
|