@flowselections/layout-maker 1.45.9 → 1.46.1
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/AfdrukKnop.js +64 -64
- package/dist-lib/components/DocumentenPage.d.ts.map +1 -1
- package/dist-lib/components/DocumentenPage.js +2 -3
- package/dist-lib/components/NetwerkPrintersDialog.d.ts +7 -7
- package/dist-lib/components/NetwerkPrintersDialog.js +79 -79
- package/dist-lib/components/PakbonPreview.d.ts.map +1 -1
- package/dist-lib/components/PakbonPreview.js +2 -2
- package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
- package/dist-lib/components/PrintQueuePage.js +45 -74
- package/dist-lib/components/PrintenPage.d.ts.map +1 -1
- package/dist-lib/components/PrintenPage.js +2 -3
- package/dist-lib/components/PrinterSetupWizard.d.ts.map +1 -1
- package/dist-lib/components/PrinterSetupWizard.js +5 -28
- package/dist-lib/components/PrintersRedirectPage.d.ts +1 -1
- package/dist-lib/components/PrintersRedirectPage.js +14 -14
- package/dist-lib/components/PrintplekDetailPage.d.ts.map +1 -1
- package/dist-lib/components/PrintplekDetailPage.js +3 -25
- package/dist-lib/components/PrintplekWizard.d.ts.map +1 -1
- package/dist-lib/components/PrintplekWizard.js +3 -85
- package/dist-lib/index.d.ts +1 -8
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +1 -10
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +5386 -289
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +5386 -289
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.js +1 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts +5386 -289
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +5404 -243
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/aiLayout.functions.d.ts +5386 -289
- 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/fieldRegistry.js +1 -0
- package/dist-lib/lib/layoutPreview.js +7 -7
- package/dist-lib/lib/logoLibrary.d.ts +2 -1
- package/dist-lib/lib/logoLibrary.d.ts.map +1 -1
- package/dist-lib/lib/logoLibrary.js +42 -2
- package/dist-lib/lib/orderData.server.d.ts.map +1 -1
- package/dist-lib/lib/orderData.server.js +13 -0
- package/dist-lib/lib/pakbonBuilder.d.ts +26 -0
- package/dist-lib/lib/pakbonBuilder.d.ts.map +1 -1
- package/dist-lib/lib/pakbonBuilder.js +37 -0
- package/dist-lib/lib/pakbonContent.d.ts.map +1 -1
- package/dist-lib/lib/pakbonContent.js +2 -2
- package/dist-lib/lib/pakbonHtml.d.ts.map +1 -1
- package/dist-lib/lib/pakbonHtml.js +60 -60
- package/dist-lib/lib/pakbonPresentation.d.ts.map +1 -1
- package/dist-lib/lib/pakbonPresentation.js +2 -4
- package/dist-lib/lib/printApi.d.ts +0 -2
- package/dist-lib/lib/printApi.d.ts.map +1 -1
- package/dist-lib/lib/printApi.js +0 -21
- package/dist-lib/lib/printQueue.server.d.ts +8 -0
- package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/printQueue.server.js +162 -66
- package/dist-lib/lib/printService.functions.d.ts +51639 -52
- package/dist-lib/lib/printService.functions.d.ts.map +1 -1
- package/dist-lib/lib/printService.functions.js +69 -0
- package/dist-lib/lib/printService.server.d.ts +2 -0
- package/dist-lib/lib/printService.server.d.ts.map +1 -1
- package/dist-lib/lib/printService.server.js +10 -0
- package/dist-lib/lib/productiebonHtml.js +15 -15
- package/dist-lib/lib/profielHtml.d.ts.map +1 -1
- package/dist-lib/lib/profielHtml.js +22 -19
- 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/dist-lib/lib/voorbeeldPrint.d.ts.map +1 -1
- package/dist-lib/lib/voorbeeldPrint.js +7 -39
- package/package.json +3 -3
- package/dist-lib/components/PdfMapAutoSaver.d.ts +0 -6
- package/dist-lib/components/PdfMapAutoSaver.d.ts.map +0 -1
- package/dist-lib/components/PdfMapAutoSaver.js +0 -12
- package/dist-lib/components/PdfMapGlobaleBanner.d.ts +0 -12
- package/dist-lib/components/PdfMapGlobaleBanner.d.ts.map +0 -1
- package/dist-lib/components/PdfMapGlobaleBanner.js +0 -30
- package/dist-lib/components/PdfMapToestemmingBanner.d.ts +0 -8
- package/dist-lib/components/PdfMapToestemmingBanner.d.ts.map +0 -1
- package/dist-lib/components/PdfMapToestemmingBanner.js +0 -245
- package/dist-lib/lib/pdfJobSaver.d.ts +0 -24
- package/dist-lib/lib/pdfJobSaver.d.ts.map +0 -1
- package/dist-lib/lib/pdfJobSaver.js +0 -376
- package/dist-lib/lib/pdfMap.d.ts +0 -83
- package/dist-lib/lib/pdfMap.d.ts.map +0 -1
- package/dist-lib/lib/pdfMap.js +0 -332
- package/dist-lib/lib/pdfOpslagStatus.d.ts +0 -23
- package/dist-lib/lib/pdfOpslagStatus.d.ts.map +0 -1
- package/dist-lib/lib/pdfOpslagStatus.js +0 -74
- package/dist-lib/lib/pdfPrinter.d.ts +0 -9
- package/dist-lib/lib/pdfPrinter.d.ts.map +0 -1
- package/dist-lib/lib/pdfPrinter.js +0 -34
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// ============================================================================
|
|
3
|
-
// src/components/PdfMapToestemmingBanner.tsx — permanente, zichtbare controle om
|
|
4
|
-
// de maptoestemming voor de virtuele "Opslaan als PDF"-printer te beheren.
|
|
5
|
-
// Getoond op de Printplek-detailpagina en de Printwachtrij, zodat een gebruiker
|
|
6
|
-
// altijd proactief toestemming kan (her)geven zonder op een toast te wachten.
|
|
7
|
-
// ============================================================================
|
|
8
|
-
import { useCallback, useEffect, useState } from "react";
|
|
9
|
-
import { Button, toast } from "@flowselections/core";
|
|
10
|
-
import { FolderCheck, FolderOpen, ShieldAlert, ShieldCheck } from "lucide-react";
|
|
11
|
-
import { usePrinters } from "../lib/useDocumentData.js";
|
|
12
|
-
import { zorgVoorPdfPrinter } from "../lib/pdfPrinter.js";
|
|
13
|
-
import { supabase } from "../lib/supabaseClient.js";
|
|
14
|
-
import { draaitInIframe, herstelPdfMapToestemming, kiesPdfMap, mapKiezenMogelijk, openInEigenTabblad, lokalePdfPrintplek, pdfMapKoppeling, pdfMapNaam, pdfMapToestemming, } from "../lib/pdfMap.js";
|
|
15
|
-
export function PdfMapToestemmingBanner({ alleenActieNodig = false, zwevend = false, printplekId, } = {}) {
|
|
16
|
-
const { printers, reload } = usePrinters();
|
|
17
|
-
const pdfPrinter = printers.find((p) => p.afdrukmethode === "pdf");
|
|
18
|
-
// De balk is alleen nuttig als "Opslaan als PDF" nog ergens als
|
|
19
|
-
// afdrukmethode is ingesteld (printplek-regel, layoutkoppeling of
|
|
20
|
-
// formaatregel). Zodra nergens meer een PDF-printer is gekozen, verdwijnt
|
|
21
|
-
// de balk en wordt de virtuele printer ook niet meer vanzelf aangemaakt.
|
|
22
|
-
const [inGebruik, setInGebruik] = useState(null);
|
|
23
|
-
const meetGebruik = useCallback(async (printerId) => {
|
|
24
|
-
const tabellen = [
|
|
25
|
-
supabase.from("document_printplek_printers").select("print_plek_id").eq("printer_id", printerId).limit(1),
|
|
26
|
-
supabase.from("printer_mappings").select("layout_id").eq("printer_id", printerId).limit(1),
|
|
27
|
-
supabase.from("document_formaat_printers").select("documenttype").eq("printer_id", printerId).limit(1),
|
|
28
|
-
];
|
|
29
|
-
try {
|
|
30
|
-
const resultaten = await Promise.all(tabellen);
|
|
31
|
-
return resultaten.some((r) => Array.isArray(r.data) && r.data.length > 0);
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
// Bij een leesfout liever tonen dan stil verbergen.
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
}, []);
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (!pdfPrinter) {
|
|
40
|
-
setInGebruik(null);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
let actief = true;
|
|
44
|
-
void meetGebruik(pdfPrinter.id).then((gebruikt) => {
|
|
45
|
-
if (actief)
|
|
46
|
-
setInGebruik(gebruikt);
|
|
47
|
-
});
|
|
48
|
-
return () => {
|
|
49
|
-
actief = false;
|
|
50
|
-
};
|
|
51
|
-
}, [pdfPrinter?.id, meetGebruik]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
52
|
-
const [naam, setNaam] = useState(null);
|
|
53
|
-
const [toestand, setToestand] = useState("laden");
|
|
54
|
-
const [gekoppeldePrintplek, setGekoppeldePrintplek] = useState(null);
|
|
55
|
-
const [persistent, setPersistent] = useState(null);
|
|
56
|
-
const [instellingOpen, setInstellingOpen] = useState(false);
|
|
57
|
-
const [aangevraagdePrintplek, setAangevraagdePrintplek] = useState(null);
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
const params = new URLSearchParams(window.location.search);
|
|
60
|
-
const gevraagd = params.get("pdf-printplek")?.trim() || null;
|
|
61
|
-
setInstellingOpen(params.get("pdf-map-instellen") === "1");
|
|
62
|
-
setAangevraagdePrintplek(gevraagd);
|
|
63
|
-
void lokalePdfPrintplek().then((lokaal) => setGekoppeldePrintplek(gevraagd ?? lokaal));
|
|
64
|
-
}, []);
|
|
65
|
-
// Maak de virtuele PDF-printer alleen aan wanneer expliciet om het instellen
|
|
66
|
-
// van de map gevraagd wordt (?pdf-map-instellen=1). Zonder die vraag én
|
|
67
|
-
// zonder bestaande PDF-printer is er niets om toestemming voor te geven.
|
|
68
|
-
useEffect(() => {
|
|
69
|
-
if (pdfPrinter || !instellingOpen)
|
|
70
|
-
return;
|
|
71
|
-
let actief = true;
|
|
72
|
-
void (async () => {
|
|
73
|
-
try {
|
|
74
|
-
await zorgVoorPdfPrinter();
|
|
75
|
-
if (actief)
|
|
76
|
-
await reload(true);
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
// RLS of netwerkfout — stil negeren, banner blijft verborgen.
|
|
80
|
-
}
|
|
81
|
-
})();
|
|
82
|
-
return () => {
|
|
83
|
-
actief = false;
|
|
84
|
-
};
|
|
85
|
-
}, [pdfPrinter, instellingOpen, reload]);
|
|
86
|
-
const laad = useCallback(async () => {
|
|
87
|
-
if (!pdfPrinter) {
|
|
88
|
-
setNaam(null);
|
|
89
|
-
setToestand("ontbreekt");
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
setNaam(await pdfMapNaam(pdfPrinter.id));
|
|
93
|
-
setToestand(await pdfMapToestemming(pdfPrinter.id));
|
|
94
|
-
const koppeling = await pdfMapKoppeling();
|
|
95
|
-
let doelPrintplek = printplekId ?? aangevraagdePrintplek ?? koppeling?.printPlekId ?? null;
|
|
96
|
-
if (!doelPrintplek) {
|
|
97
|
-
const { data } = await supabase
|
|
98
|
-
.from("document_printplek_printers")
|
|
99
|
-
.select("print_plek_id")
|
|
100
|
-
.eq("printer_id", pdfPrinter.id);
|
|
101
|
-
const ids = [
|
|
102
|
-
...new Set((Array.isArray(data) ? data : [])
|
|
103
|
-
.map((rij) => String(rij.print_plek_id ?? "").trim())
|
|
104
|
-
.filter(Boolean)),
|
|
105
|
-
];
|
|
106
|
-
doelPrintplek = ids.length === 1 ? ids[0] ?? null : null;
|
|
107
|
-
}
|
|
108
|
-
setGekoppeldePrintplek(doelPrintplek);
|
|
109
|
-
setPersistent(koppeling?.persistent ?? null);
|
|
110
|
-
// Opnieuw meten of PDF nog ergens is ingesteld: kiest de gebruiker bij
|
|
111
|
-
// alle documenten een echte printer, dan verdwijnt de balk direct.
|
|
112
|
-
setInGebruik(await meetGebruik(pdfPrinter.id));
|
|
113
|
-
}, [aangevraagdePrintplek, meetGebruik, pdfPrinter, printplekId]);
|
|
114
|
-
useEffect(() => {
|
|
115
|
-
void laad();
|
|
116
|
-
}, [laad]);
|
|
117
|
-
// Herverfris na focus zodat een net verleende toestemming meteen zichtbaar is.
|
|
118
|
-
useEffect(() => {
|
|
119
|
-
const h = () => void laad();
|
|
120
|
-
window.addEventListener("focus", h);
|
|
121
|
-
document.addEventListener("visibilitychange", h);
|
|
122
|
-
return () => {
|
|
123
|
-
window.removeEventListener("focus", h);
|
|
124
|
-
document.removeEventListener("visibilitychange", h);
|
|
125
|
-
};
|
|
126
|
-
}, [laad]);
|
|
127
|
-
// In een iframe (o.a. de Lovable-preview) heeft de balk geen nut: de
|
|
128
|
-
// mappenverkenner werkt daar niet en de gebruiker kan alleen via "Open in
|
|
129
|
-
// eigen tabblad" verder. De balk daar niet tonen houdt de preview schoon;
|
|
130
|
-
// in een eigen tabblad blijft hij volledig zichtbaar.
|
|
131
|
-
const inIframe = draaitInIframe();
|
|
132
|
-
if (inIframe)
|
|
133
|
-
return null;
|
|
134
|
-
// Is "Opslaan als PDF" nergens meer ingesteld (geen printplek-, layout- of
|
|
135
|
-
// formaatregel met deze printer), dan is de balk overbodig en verbergen we
|
|
136
|
-
// hem volledig. Alleen bij een expliciete instelvraag blijft hij zichtbaar.
|
|
137
|
-
if (!instellingOpen) {
|
|
138
|
-
if (!pdfPrinter)
|
|
139
|
-
return null;
|
|
140
|
-
if (inGebruik === false)
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
// De balk is op dit punt alleen nog zichtbaar als "Opslaan als PDF"
|
|
144
|
-
// daadwerkelijk ergens is ingesteld (of de gebruiker expliciet aan het
|
|
145
|
-
// instellen is); anders is hierboven al `null` teruggegeven.
|
|
146
|
-
const vereistePrintplek = printplekId ?? aangevraagdePrintplek ?? gekoppeldePrintplek;
|
|
147
|
-
const inOrde = !!pdfPrinter &&
|
|
148
|
-
toestand === "granted" &&
|
|
149
|
-
!!naam &&
|
|
150
|
-
!!gekoppeldePrintplek &&
|
|
151
|
-
(!vereistePrintplek || gekoppeldePrintplek === vereistePrintplek);
|
|
152
|
-
if (alleenActieNodig && !instellingOpen && (!pdfPrinter ? false : toestand === "laden" || inOrde))
|
|
153
|
-
return null;
|
|
154
|
-
const ondersteund = mapKiezenMogelijk();
|
|
155
|
-
const geefToestemming = async () => {
|
|
156
|
-
if (!pdfPrinter)
|
|
157
|
-
return;
|
|
158
|
-
const resultaat = await herstelPdfMapToestemming(pdfPrinter.id);
|
|
159
|
-
if (resultaat === "granted") {
|
|
160
|
-
toast.success("Maptoestemming verleend", {
|
|
161
|
-
description: "Gereedstaande PDF's worden nu naar de map opgeslagen.",
|
|
162
|
-
});
|
|
163
|
-
await laad();
|
|
164
|
-
}
|
|
165
|
-
else if (resultaat === "ontbreekt") {
|
|
166
|
-
// Nog geen map gekozen — open de verkenner.
|
|
167
|
-
await kiesNieuweMap();
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
toast.error("Maptoestemming is niet verleend");
|
|
171
|
-
await laad();
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
const kiesNieuweMap = async () => {
|
|
175
|
-
if (!pdfPrinter)
|
|
176
|
-
return;
|
|
177
|
-
if (inIframe) {
|
|
178
|
-
toast.error("Map kiezen werkt niet in een iframe", {
|
|
179
|
-
description: "Open de app in een eigen tabblad om de mappenverkenner te gebruiken.",
|
|
180
|
-
action: {
|
|
181
|
-
label: "Open in eigen tabblad",
|
|
182
|
-
onClick: () => openInEigenTabblad(printplekId ?? gekoppeldePrintplek ?? undefined),
|
|
183
|
-
},
|
|
184
|
-
duration: 15000,
|
|
185
|
-
});
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
const doelPrintplek = printplekId ?? gekoppeldePrintplek ?? undefined;
|
|
189
|
-
const uitkomst = await kiesPdfMap(pdfPrinter.id, doelPrintplek);
|
|
190
|
-
if (uitkomst.status === "gekozen") {
|
|
191
|
-
toast.success("Map gekozen", { description: `PDF's worden opgeslagen in “${uitkomst.naam}”.` });
|
|
192
|
-
await laad();
|
|
193
|
-
}
|
|
194
|
-
else if (uitkomst.status === "niet-ondersteund") {
|
|
195
|
-
toast.error("Deze browser ondersteunt geen mapkeuze", {
|
|
196
|
-
description: "Gebruik Chrome, Edge of Safari op desktop.",
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
else if (uitkomst.status === "iframe-geblokkeerd") {
|
|
200
|
-
toast.error("Map kiezen werkt niet in een iframe", {
|
|
201
|
-
description: "Open de app in een eigen tabblad.",
|
|
202
|
-
action: {
|
|
203
|
-
label: "Open in eigen tabblad",
|
|
204
|
-
onClick: () => openInEigenTabblad(printplekId ?? gekoppeldePrintplek ?? undefined),
|
|
205
|
-
},
|
|
206
|
-
duration: 15000,
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
else if (uitkomst.status === "fout") {
|
|
210
|
-
toast.error("Map kiezen is mislukt", { description: uitkomst.melding });
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
const icoon = inOrde
|
|
214
|
-
? ShieldCheck
|
|
215
|
-
: toestand === "denied"
|
|
216
|
-
? ShieldAlert
|
|
217
|
-
: FolderOpen;
|
|
218
|
-
const Icoon = icoon;
|
|
219
|
-
if (!pdfPrinter) {
|
|
220
|
-
return (_jsxs("div", { role: "status", "aria-live": "polite", className: `${zwevend ? "fixed inset-x-4 top-4 z-[100] mx-auto max-w-4xl shadow-lg" : ""} flex flex-wrap items-center justify-between gap-3 rounded-lg border border-amber-300/60 bg-amber-50 p-3 dark:border-amber-700/60 dark:bg-amber-950/30`, children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(ShieldAlert, { className: "h-4 w-4 text-amber-600 dark:text-amber-400" }), _jsx("span", { className: "font-medium", children: "PDF-maptoestemming" }), _jsx("span", { className: "text-muted-foreground", children: "De virtuele \u201COpslaan als PDF\u201D-printer wordt aangemaakt of kon nog niet worden geladen." })] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
221
|
-
void (async () => {
|
|
222
|
-
try {
|
|
223
|
-
await zorgVoorPdfPrinter();
|
|
224
|
-
await reload(true);
|
|
225
|
-
}
|
|
226
|
-
catch (fout) {
|
|
227
|
-
toast.error("PDF-printer kon niet worden aangemaakt", {
|
|
228
|
-
description: fout instanceof Error ? fout.message : undefined,
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
})();
|
|
232
|
-
}, children: [_jsx(FolderOpen, { className: "mr-2 h-4 w-4" }), " PDF-printer aanmaken"] })] }));
|
|
233
|
-
}
|
|
234
|
-
return (_jsxs("div", { role: "status", "aria-live": "polite", className: `${inOrde
|
|
235
|
-
? "border-emerald-300/60 bg-emerald-50 dark:border-emerald-700/60 dark:bg-emerald-950/30"
|
|
236
|
-
: "border-amber-300/60 bg-amber-50 dark:border-amber-700/60 dark:bg-amber-950/30"} ${zwevend
|
|
237
|
-
? "fixed inset-x-4 top-4 z-[100] mx-auto max-w-4xl shadow-lg"
|
|
238
|
-
: ""} flex flex-wrap items-center justify-between gap-3 rounded-lg border p-3`, children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(Icoon, { className: inOrde
|
|
239
|
-
? "h-4 w-4 text-emerald-600 dark:text-emerald-400"
|
|
240
|
-
: "h-4 w-4 text-amber-600 dark:text-amber-400" }), _jsx("span", { className: "font-medium", children: "PDF-maptoestemming" }), _jsxs("span", { className: "text-muted-foreground", children: [naam
|
|
241
|
-
? `Map “${naam}” — toestemming ${toestand === "granted" ? "verleend" : "vereist vernieuwen"}`
|
|
242
|
-
: "Nog geen map gekozen op deze computer", !ondersteund ? " (browser ondersteunt geen mapkeuze)" : "", inIframe
|
|
243
|
-
? " — de preview draait in een iframe; de mapkeuze geldt per webadres en moet hier opnieuw worden gezet"
|
|
244
|
-
: "", !inIframe && gekoppeldePrintplek ? " — gekoppeld aan deze printplek" : "", !inIframe && persistent === false ? " — browseropslag is niet permanent gegarandeerd" : ""] })] }), _jsxs("div", { className: "flex gap-2", children: [naam ? (_jsxs(Button, { size: "sm", variant: inOrde ? "outline" : "default", onClick: () => void geefToestemming(), children: [_jsx(FolderCheck, { className: "mr-2 h-4 w-4" }), inOrde ? "Toestemming controleren" : "Maptoestemming geven"] })) : null, _jsxs(Button, { size: "sm", variant: "outline", onClick: () => void kiesNieuweMap(), children: [_jsx(FolderOpen, { className: "mr-2 h-4 w-4" }), " ", naam ? "Andere map kiezen" : "Map kiezen"] }), inIframe ? (_jsx(Button, { size: "sm", variant: "outline", onClick: () => openInEigenTabblad(printplekId ?? gekoppeldePrintplek ?? undefined), children: "Open in eigen tabblad" })) : null] })] }));
|
|
245
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { supabase } from "./supabaseClient.js";
|
|
2
|
-
type PdfServiceState = {
|
|
3
|
-
gestart: boolean;
|
|
4
|
-
bezig: boolean;
|
|
5
|
-
interval: number | null;
|
|
6
|
-
gemeldePrinters: Set<string>;
|
|
7
|
-
writerId: string;
|
|
8
|
-
kanaal?: ReturnType<typeof supabase.channel> | null;
|
|
9
|
-
};
|
|
10
|
-
declare global {
|
|
11
|
-
interface Window {
|
|
12
|
-
__layoutMakerPdfService?: PdfServiceState;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
/** Herstelt uitsluitend de lokale aflevering van een reeds gerenderde PDF. */
|
|
16
|
-
export declare function bewaarPdfJobOpnieuw(jobId: string): Promise<boolean>;
|
|
17
|
-
/** Downloadt exact het opgeslagen artefact; legacy jobs vallen terug op base64. */
|
|
18
|
-
export declare function downloadPdfJob(jobId: string, documentnaam: string): Promise<void>;
|
|
19
|
-
export declare function controleerPdfMap(printerId: string): Promise<"ok" | "map_ontbreekt" | "geen_rechten">;
|
|
20
|
-
export declare function startPdfMapService(): void;
|
|
21
|
-
/** Wacht alleen op het eindresultaat; de singleton met databaseclaim schrijft. */
|
|
22
|
-
export declare function bewaarPdfJobZodraKlaar(jobId: string, _printerId: string): Promise<boolean>;
|
|
23
|
-
export {};
|
|
24
|
-
//# sourceMappingURL=pdfJobSaver.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pdfJobSaver.d.ts","sourceRoot":"","sources":["../../src/lib/pdfJobSaver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAgC5C,KAAK,eAAe,GAAG;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CACrD,CAAC;AAEF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,uBAAuB,CAAC,EAAE,eAAe,CAAC;KAC3C;CACF;AAiND,8EAA8E;AAC9E,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgCzE;AAED,mFAAmF;AACnF,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBvF;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,eAAe,GAAG,cAAc,CAAC,CAI1G;AAoCD,wBAAgB,kBAAkB,IAAI,IAAI,CA+BzC;AAED,kFAAkF;AAClF,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAehG"}
|
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
import { toast } from "@flowselections/core";
|
|
2
|
-
import { supabase } from "./supabaseClient.js";
|
|
3
|
-
import { startPdfMapGlobaleBanner } from "../components/PdfMapGlobaleBanner.js";
|
|
4
|
-
import { bewaarInPdfMap, herstelPdfMapToestemming, koppelPdfMapAanPrintplek, luisterNaarPdfMapWijziging, lokalePdfPrintplek, pdfMapKoppeling, pdfMapToestemming, } from "./pdfMap.js";
|
|
5
|
-
import { PDF_OPSLAG_MELDING } from "./pdfOpslagStatus.js";
|
|
6
|
-
const SERVICE_INTERVAL_MS = 5000;
|
|
7
|
-
const WACHT_INTERVAL_MS = 2000;
|
|
8
|
-
const MAX_WACHTTIJD_MS = 5 * 60 * 1000;
|
|
9
|
-
const WRITER_SLEUTEL = "layout-maker-pdf-writer-id";
|
|
10
|
-
function writerId() {
|
|
11
|
-
try {
|
|
12
|
-
const bestaand = localStorage.getItem(WRITER_SLEUTEL)?.trim();
|
|
13
|
-
if (bestaand)
|
|
14
|
-
return bestaand;
|
|
15
|
-
const nieuw = crypto.randomUUID();
|
|
16
|
-
localStorage.setItem(WRITER_SLEUTEL, nieuw);
|
|
17
|
-
return nieuw;
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
return crypto.randomUUID();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
function veiligeBestandsnaam(naam) {
|
|
24
|
-
return naam.replace(/[\\/:*?"<>|]/g, "-").replace(/\s+/g, " ").trim() || "document";
|
|
25
|
-
}
|
|
26
|
-
function pdfBlob(base64) {
|
|
27
|
-
const bytes = Uint8Array.from(atob(base64), (teken) => teken.charCodeAt(0));
|
|
28
|
-
return new Blob([bytes], { type: "application/pdf" });
|
|
29
|
-
}
|
|
30
|
-
async function laadPdfBlob(job) {
|
|
31
|
-
if (job.artefact_pad) {
|
|
32
|
-
const { data, error } = await supabase.storage.from("print-artifacts").download(job.artefact_pad);
|
|
33
|
-
if (error || !data)
|
|
34
|
-
throw new Error(`PDF-bestand kon niet worden opgehaald: ${error?.message ?? "onbekend"}`);
|
|
35
|
-
return data;
|
|
36
|
-
}
|
|
37
|
-
if (job.resultaat_pdf_base64)
|
|
38
|
-
return pdfBlob(job.resultaat_pdf_base64);
|
|
39
|
-
throw new Error("Voor deze opdracht is geen PDF-bestand beschikbaar.");
|
|
40
|
-
}
|
|
41
|
-
async function rondClaimAf(jobId, schrijver, status, fout = null) {
|
|
42
|
-
const { data, error } = await supabase.rpc("finish_local_pdf_job", {
|
|
43
|
-
_job_id: jobId,
|
|
44
|
-
_writer_id: schrijver,
|
|
45
|
-
_status: status,
|
|
46
|
-
_fout: fout ?? undefined,
|
|
47
|
-
});
|
|
48
|
-
if (error)
|
|
49
|
-
throw new Error(`Lokale PDF-status kon niet worden opgeslagen: ${error.message}`);
|
|
50
|
-
if (data !== true)
|
|
51
|
-
throw new Error("De lokale PDF-claim is verlopen of door een andere werkplek overgenomen.");
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Geeft een geclaimde opdracht terug aan de wachtrij. Een tabblad zonder
|
|
55
|
-
* bruikbare map mag nooit afkeuren wat een andere werkplek wél kan opslaan.
|
|
56
|
-
*/
|
|
57
|
-
async function geefClaimTerug(jobId, schrijver) {
|
|
58
|
-
const { error } = await supabase.rpc("release_local_pdf_job", {
|
|
59
|
-
_job_id: jobId,
|
|
60
|
-
_writer_id: schrijver,
|
|
61
|
-
});
|
|
62
|
-
if (error)
|
|
63
|
-
console.warn("[layout-maker] PDF-opdracht teruggeven mislukt", error.message);
|
|
64
|
-
}
|
|
65
|
-
async function schrijfGeclaimdePdf(job, schrijver) {
|
|
66
|
-
if (!job.printer_id || (!job.artefact_pad && !job.resultaat_pdf_base64))
|
|
67
|
-
return false;
|
|
68
|
-
const toestemming = await pdfMapToestemming(job.printer_id);
|
|
69
|
-
if (toestemming !== "granted") {
|
|
70
|
-
// Geen map of geen schrijfrecht op dít tabblad: terug in de wachtrij.
|
|
71
|
-
await geefClaimTerug(job.id, schrijver);
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
const naam = `${veiligeBestandsnaam(job.documentnaam ?? "document")}-${job.id.slice(0, 8)}.pdf`;
|
|
75
|
-
let geschreven = false;
|
|
76
|
-
try {
|
|
77
|
-
geschreven = await bewaarInPdfMap(job.printer_id, naam, await laadPdfBlob(job));
|
|
78
|
-
}
|
|
79
|
-
catch {
|
|
80
|
-
geschreven = false;
|
|
81
|
-
}
|
|
82
|
-
if (!geschreven) {
|
|
83
|
-
await rondClaimAf(job.id, schrijver, "schrijffout", PDF_OPSLAG_MELDING.schrijffout);
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
// Eerst het bestand sluiten, daarna pas de database bevestigen. Een fout in
|
|
87
|
-
// deze bevestiging wordt nooit meer genegeerd of als succes aan de UI gemeld.
|
|
88
|
-
await rondClaimAf(job.id, schrijver, "opgeslagen");
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
async function bepaalEigenPrintplek() {
|
|
92
|
-
const opgeslagen = await lokalePdfPrintplek();
|
|
93
|
-
if (opgeslagen)
|
|
94
|
-
return opgeslagen;
|
|
95
|
-
// Zonder een in deze browser gekozen map doet dit tabblad niet mee: anders
|
|
96
|
-
// kaapt een preview- of extra tabblad opdrachten die het niet kan opslaan.
|
|
97
|
-
const koppeling = await pdfMapKoppeling();
|
|
98
|
-
if (!koppeling?.handle)
|
|
99
|
-
return null;
|
|
100
|
-
// Wél een map, maar nog geen plek eraan gekoppeld (oude installatie):
|
|
101
|
-
// uitsluitend als deze database exact één printplek met een PDF-printer heeft
|
|
102
|
-
// kan er geen twijfel bestaan over de eigenaar van die map.
|
|
103
|
-
const { data, error } = await supabase
|
|
104
|
-
.from("document_printplek_printers")
|
|
105
|
-
.select("print_plek_id, printers!inner(afdrukmethode)")
|
|
106
|
-
.eq("printers.afdrukmethode", "pdf");
|
|
107
|
-
if (error)
|
|
108
|
-
return null;
|
|
109
|
-
const ids = [...new Set((Array.isArray(data) ? data : []).map((rij) => String(rij.print_plek_id ?? "")).filter(Boolean))];
|
|
110
|
-
if (ids.length !== 1)
|
|
111
|
-
return null;
|
|
112
|
-
const enigePrintplek = ids[0];
|
|
113
|
-
if (!enigePrintplek)
|
|
114
|
-
return null;
|
|
115
|
-
await koppelPdfMapAanPrintplek(enigePrintplek);
|
|
116
|
-
return enigePrintplek;
|
|
117
|
-
}
|
|
118
|
-
/** Heeft dít tabblad een bruikbare map met schrijfrecht voor deze printplek? */
|
|
119
|
-
async function magOpdrachtenClaimen() {
|
|
120
|
-
const koppeling = await pdfMapKoppeling();
|
|
121
|
-
if (!koppeling?.handle)
|
|
122
|
-
return false;
|
|
123
|
-
try {
|
|
124
|
-
const toestemming = await koppeling.handle.queryPermission?.({ mode: "readwrite" });
|
|
125
|
-
return (toestemming ?? "granted") === "granted";
|
|
126
|
-
}
|
|
127
|
-
catch {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
function meldMapProbleem(state, printerId) {
|
|
132
|
-
if (state.gemeldePrinters.has(printerId))
|
|
133
|
-
return;
|
|
134
|
-
state.gemeldePrinters.add(printerId);
|
|
135
|
-
toast.error("De PDF-map van deze werkplek is niet bruikbaar", {
|
|
136
|
-
description: "Bevestig de maptoestemming en kies daarna bij de opdracht ‘Opnieuw opslaan’.",
|
|
137
|
-
action: {
|
|
138
|
-
label: "Maptoestemming regelen",
|
|
139
|
-
onClick: () => {
|
|
140
|
-
void herstelPdfMapToestemming(printerId).then((resultaat) => {
|
|
141
|
-
if (resultaat === "granted")
|
|
142
|
-
state.gemeldePrinters.delete(printerId);
|
|
143
|
-
else
|
|
144
|
-
toast.error("Maptoestemming is niet verleend");
|
|
145
|
-
});
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
duration: 15000,
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
/** Schrijft hooguit dit aantal bestanden tegelijk naar de map. */
|
|
152
|
-
const SCHRIJF_PARALLEL = 2;
|
|
153
|
-
/** Vaste batchlimiet per ronde. */
|
|
154
|
-
const CLAIM_MAX = 6;
|
|
155
|
-
async function metPool(items, max, fn) {
|
|
156
|
-
let volgende = 0;
|
|
157
|
-
const werkers = Array.from({ length: Math.max(1, Math.min(max, items.length)) }, async () => {
|
|
158
|
-
for (;;) {
|
|
159
|
-
const i = volgende++;
|
|
160
|
-
if (i >= items.length)
|
|
161
|
-
return;
|
|
162
|
-
await fn(items[i]);
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
await Promise.all(werkers);
|
|
166
|
-
}
|
|
167
|
-
async function verwerkGereedstaandePdfs(state) {
|
|
168
|
-
if (state.bezig)
|
|
169
|
-
return;
|
|
170
|
-
state.bezig = true;
|
|
171
|
-
try {
|
|
172
|
-
const printPlekId = await bepaalEigenPrintplek();
|
|
173
|
-
if (!printPlekId)
|
|
174
|
-
return;
|
|
175
|
-
// Alleen een tabblad met een bruikbare map pakt werk op.
|
|
176
|
-
if (!(await magOpdrachtenClaimen()))
|
|
177
|
-
return;
|
|
178
|
-
const { data, error } = await supabase.rpc("claim_local_pdf_jobs", {
|
|
179
|
-
_print_plek_id: printPlekId,
|
|
180
|
-
_writer_id: state.writerId,
|
|
181
|
-
_max: CLAIM_MAX,
|
|
182
|
-
});
|
|
183
|
-
if (error)
|
|
184
|
-
throw new Error(`PDF-opdrachten ophalen mislukt: ${error.message}`);
|
|
185
|
-
let opgeslagen = 0;
|
|
186
|
-
const jobs = (Array.isArray(data) ? data : []);
|
|
187
|
-
await metPool(jobs, SCHRIJF_PARALLEL, async (job) => {
|
|
188
|
-
try {
|
|
189
|
-
if (await schrijfGeclaimdePdf(job, state.writerId)) {
|
|
190
|
-
opgeslagen += 1;
|
|
191
|
-
if (job.printer_id)
|
|
192
|
-
state.gemeldePrinters.delete(job.printer_id);
|
|
193
|
-
}
|
|
194
|
-
else if (job.printer_id) {
|
|
195
|
-
meldMapProbleem(state, job.printer_id);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
catch (fout) {
|
|
199
|
-
console.error("[layout-maker] lokale PDF-opslag kon niet worden bevestigd", fout);
|
|
200
|
-
toast.error(fout instanceof Error ? fout.message : "Lokale PDF-opslag mislukt");
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
if (opgeslagen) {
|
|
204
|
-
toast.success(opgeslagen === 1 ? "PDF opgeslagen in de ingestelde map" : `${opgeslagen} PDF's opgeslagen`);
|
|
205
|
-
}
|
|
206
|
-
// Zat de batch vol? Dan staat er mogelijk nog werk klaar.
|
|
207
|
-
if (jobs.length >= CLAIM_MAX) {
|
|
208
|
-
state.bezig = false;
|
|
209
|
-
await verwerkGereedstaandePdfs(state);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
catch (fout) {
|
|
214
|
-
console.error("[layout-maker] lokale PDF-service", fout);
|
|
215
|
-
}
|
|
216
|
-
finally {
|
|
217
|
-
state.bezig = false;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
/** Herstelt uitsluitend de lokale aflevering van een reeds gerenderde PDF. */
|
|
221
|
-
export async function bewaarPdfJobOpnieuw(jobId) {
|
|
222
|
-
const printPlekId = await bepaalEigenPrintplek();
|
|
223
|
-
if (!printPlekId)
|
|
224
|
-
throw new Error("Kies eerst bij deze printplek de lokale PDF-map.");
|
|
225
|
-
const { data: job, error: leesFout } = await supabase
|
|
226
|
-
.from("print_jobs")
|
|
227
|
-
.select("id, resultaat_pdf_base64, artefact_pad, lokale_pdf_print_plek_id")
|
|
228
|
-
.eq("id", jobId)
|
|
229
|
-
.maybeSingle();
|
|
230
|
-
if (leesFout)
|
|
231
|
-
throw leesFout;
|
|
232
|
-
if (!job?.resultaat_pdf_base64 && !job?.artefact_pad)
|
|
233
|
-
throw new Error("Voor deze opdracht is nog geen bestaande PDF beschikbaar.");
|
|
234
|
-
if (job.lokale_pdf_print_plek_id && job.lokale_pdf_print_plek_id !== printPlekId) {
|
|
235
|
-
throw new Error("Deze PDF hoort bij een andere printplek.");
|
|
236
|
-
}
|
|
237
|
-
const { error } = await supabase
|
|
238
|
-
.from("print_jobs")
|
|
239
|
-
.update({
|
|
240
|
-
lokale_pdf_print_plek_id: printPlekId,
|
|
241
|
-
lokale_pdf_status: "gereed",
|
|
242
|
-
lokale_pdf_fout: null,
|
|
243
|
-
lokale_pdf_claim_id: null,
|
|
244
|
-
lokale_pdf_claim_tot: null,
|
|
245
|
-
status: "bezig",
|
|
246
|
-
foutmelding: null,
|
|
247
|
-
voltooid_op: null,
|
|
248
|
-
updated_at: new Date().toISOString(),
|
|
249
|
-
})
|
|
250
|
-
.eq("id", jobId);
|
|
251
|
-
if (error)
|
|
252
|
-
throw error;
|
|
253
|
-
startPdfMapService();
|
|
254
|
-
const state = window.__layoutMakerPdfService;
|
|
255
|
-
if (state)
|
|
256
|
-
await verwerkGereedstaandePdfs(state);
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
/** Downloadt exact het opgeslagen artefact; legacy jobs vallen terug op base64. */
|
|
260
|
-
export async function downloadPdfJob(jobId, documentnaam) {
|
|
261
|
-
const { data, error } = await supabase
|
|
262
|
-
.from("print_jobs")
|
|
263
|
-
.select("id, artefact_pad, resultaat_pdf_base64")
|
|
264
|
-
.eq("id", jobId)
|
|
265
|
-
.maybeSingle();
|
|
266
|
-
if (error)
|
|
267
|
-
throw error;
|
|
268
|
-
if (!data)
|
|
269
|
-
throw new Error("De printopdracht bestaat niet meer.");
|
|
270
|
-
const blob = await laadPdfBlob({
|
|
271
|
-
...data,
|
|
272
|
-
status: "",
|
|
273
|
-
printer_id: null,
|
|
274
|
-
documentnaam,
|
|
275
|
-
lokale_pdf_status: null,
|
|
276
|
-
lokale_pdf_print_plek_id: null,
|
|
277
|
-
artefact_sha256: null,
|
|
278
|
-
artefact_bytes: null,
|
|
279
|
-
});
|
|
280
|
-
const url = URL.createObjectURL(blob);
|
|
281
|
-
const link = document.createElement("a");
|
|
282
|
-
link.href = url;
|
|
283
|
-
link.download = `${veiligeBestandsnaam(documentnaam)}.pdf`;
|
|
284
|
-
link.click();
|
|
285
|
-
URL.revokeObjectURL(url);
|
|
286
|
-
}
|
|
287
|
-
export async function controleerPdfMap(printerId) {
|
|
288
|
-
const toestemming = await pdfMapToestemming(printerId);
|
|
289
|
-
if (toestemming === "ontbreekt")
|
|
290
|
-
return "map_ontbreekt";
|
|
291
|
-
return toestemming === "granted" ? "ok" : "geen_rechten";
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Volgt de printopdrachten van de eigen printplek live. Zodra er een PDF
|
|
295
|
-
* gereed staat begint het wegschrijven direct; mislukt het abonnement, dan
|
|
296
|
-
* blijft de poll het vangnet en wordt dat zichtbaar in de console.
|
|
297
|
-
*/
|
|
298
|
-
async function abonneerOpGereedstaandePdfs(state, controleer) {
|
|
299
|
-
try {
|
|
300
|
-
const printPlekId = await bepaalEigenPrintplek();
|
|
301
|
-
if (!printPlekId)
|
|
302
|
-
return;
|
|
303
|
-
if (state.kanaal)
|
|
304
|
-
return;
|
|
305
|
-
state.kanaal = supabase
|
|
306
|
-
.channel(`layout-maker-lokale-pdf-${printPlekId}`)
|
|
307
|
-
.on("postgres_changes", {
|
|
308
|
-
event: "*",
|
|
309
|
-
schema: "public",
|
|
310
|
-
table: "print_jobs",
|
|
311
|
-
filter: `lokale_pdf_print_plek_id=eq.${printPlekId}`,
|
|
312
|
-
}, (payload) => {
|
|
313
|
-
const rij = (payload.new ?? {});
|
|
314
|
-
if (rij.lokale_pdf_status === "gereed")
|
|
315
|
-
controleer();
|
|
316
|
-
})
|
|
317
|
-
.subscribe();
|
|
318
|
-
}
|
|
319
|
-
catch (fout) {
|
|
320
|
-
console.warn("[layout-maker] live meeluisteren op PDF-opdrachten mislukt", fout);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
export function startPdfMapService() {
|
|
324
|
-
if (typeof window === "undefined")
|
|
325
|
-
return;
|
|
326
|
-
// De zwevende mapmelding hoort bij deze service: zodra de map of toestemming
|
|
327
|
-
// ontbreekt verschijnt hij boven elke pagina, en verdwijnt hij weer zodra de
|
|
328
|
-
// toestemming verleend is.
|
|
329
|
-
startPdfMapGlobaleBanner();
|
|
330
|
-
const bestaand = window.__layoutMakerPdfService;
|
|
331
|
-
if (bestaand?.gestart) {
|
|
332
|
-
void verwerkGereedstaandePdfs(bestaand);
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
const state = {
|
|
336
|
-
gestart: true,
|
|
337
|
-
bezig: false,
|
|
338
|
-
interval: null,
|
|
339
|
-
gemeldePrinters: new Set(),
|
|
340
|
-
writerId: writerId(),
|
|
341
|
-
};
|
|
342
|
-
window.__layoutMakerPdfService = state;
|
|
343
|
-
const controleer = () => void verwerkGereedstaandePdfs(state);
|
|
344
|
-
// Realtime is het snelle pad: zodra een opdracht 'gereed' staat begint het
|
|
345
|
-
// wegschrijven meteen. De vijfsecondenpoll blijft uitsluitend vangnet.
|
|
346
|
-
void abonneerOpGereedstaandePdfs(state, controleer);
|
|
347
|
-
state.interval = window.setInterval(controleer, SERVICE_INTERVAL_MS);
|
|
348
|
-
window.addEventListener("focus", controleer);
|
|
349
|
-
window.addEventListener("online", controleer);
|
|
350
|
-
document.addEventListener("visibilitychange", () => {
|
|
351
|
-
if (document.visibilityState === "visible")
|
|
352
|
-
controleer();
|
|
353
|
-
});
|
|
354
|
-
luisterNaarPdfMapWijziging(controleer);
|
|
355
|
-
controleer();
|
|
356
|
-
}
|
|
357
|
-
/** Wacht alleen op het eindresultaat; de singleton met databaseclaim schrijft. */
|
|
358
|
-
export async function bewaarPdfJobZodraKlaar(jobId, _printerId) {
|
|
359
|
-
startPdfMapService();
|
|
360
|
-
const deadline = Date.now() + MAX_WACHTTIJD_MS;
|
|
361
|
-
while (Date.now() < deadline) {
|
|
362
|
-
const { data, error } = await supabase
|
|
363
|
-
.from("print_jobs")
|
|
364
|
-
.select("status, lokale_pdf_status")
|
|
365
|
-
.eq("id", jobId)
|
|
366
|
-
.maybeSingle();
|
|
367
|
-
if (error)
|
|
368
|
-
return false;
|
|
369
|
-
if (data?.lokale_pdf_status === "opgeslagen")
|
|
370
|
-
return true;
|
|
371
|
-
if (data?.status === "mislukt" || data?.status === "geannuleerd")
|
|
372
|
-
return false;
|
|
373
|
-
await new Promise((resolve) => window.setTimeout(resolve, WACHT_INTERVAL_MS));
|
|
374
|
-
}
|
|
375
|
-
return false;
|
|
376
|
-
}
|