@flowselections/layout-maker 1.3.3 → 1.6.6
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 +24 -24
- package/dist-lib/components/AfdrukKnop.d.ts +3 -1
- package/dist-lib/components/AfdrukKnop.d.ts.map +1 -1
- package/dist-lib/components/AfdrukKnop.js +24 -3
- package/dist-lib/components/ComputersLijst.d.ts +23 -0
- package/dist-lib/components/ComputersLijst.d.ts.map +1 -0
- package/dist-lib/components/ComputersLijst.js +75 -0
- package/dist-lib/components/LayoutsPage.d.ts.map +1 -1
- package/dist-lib/components/LayoutsPage.js +2 -0
- package/dist-lib/components/LogosPage.d.ts.map +1 -1
- package/dist-lib/components/LogosPage.js +2 -0
- package/dist-lib/components/NetwerkPrintersDialog.d.ts +8 -0
- package/dist-lib/components/NetwerkPrintersDialog.d.ts.map +1 -0
- package/dist-lib/components/NetwerkPrintersDialog.js +79 -0
- package/dist-lib/components/PrintProgrammaUitleg.d.ts +5 -0
- package/dist-lib/components/PrintProgrammaUitleg.d.ts.map +1 -0
- package/dist-lib/components/PrintProgrammaUitleg.js +19 -0
- package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
- package/dist-lib/components/PrintQueuePage.js +37 -3
- package/dist-lib/components/PrinterKaart.d.ts +17 -0
- package/dist-lib/components/PrinterKaart.d.ts.map +1 -0
- package/dist-lib/components/PrinterKaart.js +14 -0
- package/dist-lib/components/PrinterSetupWizard.d.ts +11 -1
- package/dist-lib/components/PrinterSetupWizard.d.ts.map +1 -1
- package/dist-lib/components/PrinterSetupWizard.js +134 -64
- package/dist-lib/components/PrinterStatsKaarten.d.ts +11 -0
- package/dist-lib/components/PrinterStatsKaarten.d.ts.map +1 -0
- package/dist-lib/components/PrinterStatsKaarten.js +8 -0
- package/dist-lib/components/PrintersPage.d.ts.map +1 -1
- package/dist-lib/components/PrintersPage.js +120 -49
- package/dist-lib/components/WerkplekConfiguratiePage.d.ts +2 -0
- package/dist-lib/components/WerkplekConfiguratiePage.d.ts.map +1 -0
- package/dist-lib/components/WerkplekConfiguratiePage.js +101 -0
- package/dist-lib/components/WerkplekkenTabel.d.ts +14 -0
- package/dist-lib/components/WerkplekkenTabel.d.ts.map +1 -0
- package/dist-lib/components/WerkplekkenTabel.js +16 -0
- package/dist-lib/index.d.ts +11 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +11 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +925 -34
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +925 -34
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +920 -29
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +12 -1
- package/dist-lib/lib/aiLayout.functions.d.ts +925 -34
- 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.d.ts +1 -0
- package/dist-lib/lib/browserPrint.d.ts.map +1 -1
- package/dist-lib/lib/browserPrint.js +6 -6
- package/dist-lib/lib/centralAuth.server.d.ts +13 -0
- package/dist-lib/lib/centralAuth.server.d.ts.map +1 -0
- package/dist-lib/lib/centralAuth.server.js +60 -0
- package/dist-lib/lib/directPrint.d.ts +26 -0
- package/dist-lib/lib/directPrint.d.ts.map +1 -0
- package/dist-lib/lib/directPrint.js +65 -0
- package/dist-lib/lib/documentPdf.d.ts +11 -0
- package/dist-lib/lib/documentPdf.d.ts.map +1 -0
- package/dist-lib/lib/documentPdf.js +62 -0
- package/dist-lib/lib/htmlNaarPdf.server.d.ts +14 -0
- package/dist-lib/lib/htmlNaarPdf.server.d.ts.map +1 -0
- package/dist-lib/lib/htmlNaarPdf.server.js +34 -0
- package/dist-lib/lib/htmlPdf.server.d.ts +29 -0
- package/dist-lib/lib/htmlPdf.server.d.ts.map +1 -0
- package/dist-lib/lib/htmlPdf.server.js +1009 -0
- package/dist-lib/lib/layoutPreview.d.ts +1 -1
- package/dist-lib/lib/layoutPreview.d.ts.map +1 -1
- package/dist-lib/lib/layoutPreview.js +9 -9
- package/dist-lib/lib/logoLibrary.d.ts +1 -1
- package/dist-lib/lib/logoLibrary.js +5 -3
- package/dist-lib/lib/orderData.server.d.ts +15 -0
- package/dist-lib/lib/orderData.server.d.ts.map +1 -0
- package/dist-lib/lib/orderData.server.js +194 -0
- package/dist-lib/lib/pakbonBuilder.d.ts.map +1 -1
- package/dist-lib/lib/pakbonBuilder.js +22 -2
- package/dist-lib/lib/pakbonHtml.js +50 -50
- package/dist-lib/lib/printQueue.server.d.ts +31 -0
- package/dist-lib/lib/printQueue.server.d.ts.map +1 -0
- package/dist-lib/lib/printQueue.server.js +435 -0
- package/dist-lib/lib/printService.functions.d.ts +103742 -0
- package/dist-lib/lib/printService.functions.d.ts.map +1 -0
- package/dist-lib/lib/printService.functions.js +94 -0
- package/dist-lib/lib/printService.server.d.ts +31 -0
- package/dist-lib/lib/printService.server.d.ts.map +1 -0
- package/dist-lib/lib/printService.server.js +110 -0
- package/dist-lib/lib/productiebonHtml.d.ts +18 -0
- package/dist-lib/lib/productiebonHtml.d.ts.map +1 -0
- package/dist-lib/lib/productiebonHtml.js +166 -0
- package/dist-lib/lib/profielHtml.d.ts +14 -0
- package/dist-lib/lib/profielHtml.d.ts.map +1 -0
- package/dist-lib/lib/profielHtml.js +256 -0
- package/dist-lib/lib/runnerRegistry.server.d.ts +10 -0
- package/dist-lib/lib/runnerRegistry.server.d.ts.map +1 -0
- package/dist-lib/lib/runnerRegistry.server.js +79 -0
- package/dist-lib/lib/supabaseAdmin.server.d.ts +6 -0
- package/dist-lib/lib/supabaseAdmin.server.d.ts.map +1 -0
- package/dist-lib/lib/supabaseAdmin.server.js +43 -0
- package/dist-lib/lib/testpagina.d.ts +2 -0
- package/dist-lib/lib/testpagina.d.ts.map +1 -0
- package/dist-lib/lib/testpagina.js +31 -0
- package/dist-lib/lib/useAutoRefresh.d.ts +8 -0
- package/dist-lib/lib/useAutoRefresh.d.ts.map +1 -0
- package/dist-lib/lib/useAutoRefresh.js +44 -0
- package/dist-lib/lib/useDocumentData.d.ts +4 -3
- package/dist-lib/lib/useDocumentData.d.ts.map +1 -1
- package/dist-lib/lib/useDocumentData.js +10 -7
- package/dist-lib/lib/useNetwerkPrinters.d.ts +12 -0
- package/dist-lib/lib/useNetwerkPrinters.d.ts.map +1 -0
- package/dist-lib/lib/useNetwerkPrinters.js +26 -0
- package/package.json +11 -3
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// ============================================================================
|
|
3
|
-
// src/components/PrinterSetupWizard.tsx —
|
|
3
|
+
// src/components/PrinterSetupWizard.tsx — printer toevoegen in drie stappen:
|
|
4
|
+
// kiezen uit het netwerk, naam en locatie geven, testpagina afdrukken.
|
|
4
5
|
// ============================================================================
|
|
5
|
-
import { useEffect, useState } from "react";
|
|
6
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
6
7
|
import { Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Input, Label, toast, } from "@flowselections/core";
|
|
7
|
-
import { Check, CheckCircle2, FileText, Tag } from "lucide-react";
|
|
8
|
+
import { Check, CheckCircle2, FileText, Loader2, Printer, RefreshCw, Search, Tag, } from "lucide-react";
|
|
8
9
|
import { supabase } from "../lib/supabaseClient";
|
|
9
|
-
import { DOCUMENT_PROFIELEN } from "../lib/documentProfiles";
|
|
10
|
-
import { zetFormaatPrinter } from "../lib/formaatPrinters";
|
|
11
10
|
import { drukAf } from "../lib/browserPrint";
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
import { printDirect } from "../lib/directPrint";
|
|
12
|
+
import { netwerkPrinters } from "../lib/printService.functions";
|
|
13
|
+
import { PrintProgrammaUitleg, WerktHetNiet } from "./PrintProgrammaUitleg";
|
|
14
|
+
const STAPPEN = ["Printer kiezen", "Naam en locatie", "Klaar"];
|
|
14
15
|
function instellingenVoor(gebruik) {
|
|
15
16
|
return gebruik === "etiket"
|
|
16
17
|
? { soort: "labelprinter", papierformaat: "label" }
|
|
@@ -21,42 +22,109 @@ function Stappenbalk({ stap }) {
|
|
|
21
22
|
? "bg-primary text-primary-foreground"
|
|
22
23
|
: i === stap
|
|
23
24
|
? "border-primary text-primary border-2"
|
|
24
|
-
: "bg-muted text-muted-foreground"}`, children: i < stap ? _jsx(Check, { className: "h-4 w-4" }) : i + 1 }), _jsx("span", { className: `text-sm ${i === stap ? "text-foreground font-medium" : "text-muted-foreground"}`, children: s }), i < STAPPEN.length - 1 && _jsx("div", { className: "bg-border h-px flex-1" })] }, s))) }));
|
|
25
|
+
: "bg-muted text-muted-foreground"}`, children: i < stap ? _jsx(Check, { className: "h-4 w-4" }) : i + 1 }), _jsx("span", { className: `hidden text-sm sm:inline ${i === stap ? "text-foreground font-medium" : "text-muted-foreground"}`, children: s }), i < STAPPEN.length - 1 && _jsx("div", { className: "bg-border h-px flex-1" })] }, s))) }));
|
|
25
26
|
}
|
|
26
|
-
export function PrinterSetupWizard({ open, onOpenChange, onKlaar, }) {
|
|
27
|
+
export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter, bekendeExterneIds = [], bekendeLocaties = [], bewerken, }) {
|
|
27
28
|
const [stap, setStap] = useState(0);
|
|
28
29
|
const [bezig, setBezig] = useState(false);
|
|
29
|
-
const [
|
|
30
|
-
const [
|
|
30
|
+
const [zoekt, setZoekt] = useState(false);
|
|
31
|
+
const [fout, setFout] = useState(null);
|
|
32
|
+
const [lijst, setLijst] = useState([]);
|
|
33
|
+
const [zoekterm, setZoekterm] = useState("");
|
|
34
|
+
const [uitlegOpen, setUitlegOpen] = useState(false);
|
|
35
|
+
const [gekozen, setGekozen] = useState(null);
|
|
36
|
+
const [naam, setNaam] = useState("");
|
|
37
|
+
const [locatie, setLocatie] = useState("");
|
|
31
38
|
const [gebruik, setGebruik] = useState("papier");
|
|
32
39
|
const [printerId, setPrinterId] = useState(null);
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const zoeken = useCallback(async () => {
|
|
41
|
+
setZoekt(true);
|
|
42
|
+
setFout(null);
|
|
43
|
+
try {
|
|
44
|
+
const res = await netwerkPrinters({ data: undefined });
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
setFout(res.fout);
|
|
47
|
+
setLijst([]);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
setLijst(Array.isArray(res.printers) ? res.printers : []);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
setFout("Er kon niet in het netwerk worden gezocht. Probeer het zo opnieuw.");
|
|
55
|
+
setLijst([]);
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
setZoekt(false);
|
|
59
|
+
}
|
|
60
|
+
}, []);
|
|
42
61
|
useEffect(() => {
|
|
43
|
-
if (!open)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
if (!open) {
|
|
63
|
+
setStap(0);
|
|
64
|
+
setGekozen(null);
|
|
65
|
+
setNaam("");
|
|
66
|
+
setLocatie("");
|
|
67
|
+
setGebruik("papier");
|
|
68
|
+
setPrinterId(null);
|
|
69
|
+
setZoekterm("");
|
|
70
|
+
setUitlegOpen(false);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (bewerken) {
|
|
74
|
+
setStap(1);
|
|
75
|
+
setPrinterId(bewerken.id);
|
|
76
|
+
setNaam(bewerken.naam);
|
|
77
|
+
setLocatie(bewerken.locatie ?? "");
|
|
78
|
+
setGebruik(bewerken.papierformaat === "label" ? "etiket" : "papier");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
void zoeken();
|
|
82
|
+
}, [open, bewerken, zoeken]);
|
|
83
|
+
const zichtbaar = useMemo(() => {
|
|
84
|
+
const term = zoekterm.trim().toLowerCase();
|
|
85
|
+
return lijst
|
|
86
|
+
.filter((p) => (computerFilter ? p.computer === computerFilter : true))
|
|
87
|
+
.filter((p) => (term ? `${p.naam} ${p.computer}`.toLowerCase().includes(term) : true));
|
|
88
|
+
}, [lijst, zoekterm, computerFilter]);
|
|
89
|
+
const kiesPrinter = (p) => {
|
|
90
|
+
setGekozen(p);
|
|
91
|
+
setNaam(p.naam);
|
|
92
|
+
setLocatie(p.computer ?? "");
|
|
93
|
+
setStap(1);
|
|
94
|
+
};
|
|
95
|
+
const opslaan = async () => {
|
|
96
|
+
const eindnaam = naam.trim() || gekozen?.naam || "";
|
|
97
|
+
if (!eindnaam) {
|
|
49
98
|
toast.error("Geef de printer een naam");
|
|
50
99
|
return;
|
|
51
100
|
}
|
|
52
101
|
setBezig(true);
|
|
53
102
|
try {
|
|
103
|
+
if (bewerken) {
|
|
104
|
+
const { error } = await supabase
|
|
105
|
+
.from("printers")
|
|
106
|
+
.update({
|
|
107
|
+
naam: eindnaam,
|
|
108
|
+
locatie: locatie.trim() || null,
|
|
109
|
+
...instellingenVoor(gebruik),
|
|
110
|
+
})
|
|
111
|
+
.eq("id", bewerken.id);
|
|
112
|
+
if (error)
|
|
113
|
+
throw error;
|
|
114
|
+
toast.success("Printer bijgewerkt");
|
|
115
|
+
onKlaar?.();
|
|
116
|
+
onOpenChange(false);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
54
119
|
const { data, error } = await supabase
|
|
55
120
|
.from("printers")
|
|
56
121
|
.insert({
|
|
57
|
-
naam,
|
|
122
|
+
naam: eindnaam,
|
|
58
123
|
actief: true,
|
|
59
|
-
|
|
124
|
+
online: gekozen?.online ?? false,
|
|
125
|
+
systeemnaam: gekozen?.naam ?? eindnaam,
|
|
126
|
+
locatie: locatie.trim() || null,
|
|
127
|
+
extern_printer_id: gekozen?.id ?? null,
|
|
60
128
|
...instellingenVoor(gebruik),
|
|
61
129
|
})
|
|
62
130
|
.select("id")
|
|
@@ -64,7 +132,7 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, }) {
|
|
|
64
132
|
if (error)
|
|
65
133
|
throw error;
|
|
66
134
|
setPrinterId(data?.id ?? null);
|
|
67
|
-
setStap(
|
|
135
|
+
setStap(2);
|
|
68
136
|
onKlaar?.();
|
|
69
137
|
}
|
|
70
138
|
catch {
|
|
@@ -74,46 +142,48 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, }) {
|
|
|
74
142
|
setBezig(false);
|
|
75
143
|
}
|
|
76
144
|
};
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
145
|
+
const [testStatus, setTestStatus] = useState("leeg");
|
|
146
|
+
const testpagina = async () => {
|
|
147
|
+
setTestStatus("bezig");
|
|
148
|
+
const html = `<div style="padding:20mm;font-size:14pt"><h1 style="font-size:20pt">Testpagina</h1>
|
|
149
|
+
<p>Deze pagina hoort uit: <strong>${naam}</strong></p></div>`;
|
|
150
|
+
const opdracht = {
|
|
151
|
+
documenttype: "pakbon",
|
|
152
|
+
formaatCode: gebruik === "etiket" ? "label" : "A4",
|
|
153
|
+
orientatie: "portrait",
|
|
154
|
+
documentnaam: "Testpagina",
|
|
155
|
+
html,
|
|
156
|
+
printerId: printerId ?? undefined,
|
|
157
|
+
};
|
|
81
158
|
try {
|
|
82
|
-
|
|
83
|
-
|
|
159
|
+
const direct = await printDirect(opdracht);
|
|
160
|
+
if (direct.gelukt) {
|
|
161
|
+
setTestStatus("gelukt");
|
|
162
|
+
return;
|
|
84
163
|
}
|
|
85
|
-
|
|
164
|
+
await drukAf(opdracht);
|
|
165
|
+
setTestStatus("gelukt");
|
|
86
166
|
}
|
|
87
167
|
catch {
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
finally {
|
|
91
|
-
setBezig(false);
|
|
168
|
+
setTestStatus("fout");
|
|
92
169
|
}
|
|
93
170
|
};
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
<p>Deze pagina hoort uit: <strong>${naam}</strong></p></div>`,
|
|
103
|
-
});
|
|
171
|
+
const opnieuw = () => {
|
|
172
|
+
setStap(0);
|
|
173
|
+
setGekozen(null);
|
|
174
|
+
setNaam("");
|
|
175
|
+
setLocatie("");
|
|
176
|
+
setPrinterId(null);
|
|
177
|
+
setTestStatus("leeg");
|
|
178
|
+
void zoeken();
|
|
104
179
|
};
|
|
105
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-h-[85vh] overflow-y-auto sm:max-w-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
else
|
|
115
|
-
n[profiel.id] = f.code;
|
|
116
|
-
return n;
|
|
117
|
-
}), className: `hover:bg-accent rounded-md border px-3 py-1.5 text-xs transition ${gekozen === f.code ? "border-primary bg-accent" : ""}`, children: f.label }, f.code))) })] }, profiel.id));
|
|
118
|
-
}) }), _jsxs("div", { className: "flex justify-between", children: [_jsx(Button, { variant: "ghost", onClick: () => setStap(2), children: "Overslaan" }), _jsx(Button, { disabled: bezig, onClick: () => void koppelingenOpslaan(), children: "Opslaan en verder" })] })] })), stap === 2 && (_jsxs("div", { className: "space-y-4 text-center", children: [_jsx(CheckCircle2, { className: "text-primary mx-auto h-10 w-10" }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: "De printer is klaar voor gebruik" }), _jsxs("p", { className: "text-muted-foreground text-sm", children: [printernaam || systeemnaam, " staat klaar. Papierformaat en stand worden voortaan automatisch ingesteld bij het afdrukken."] })] }), _jsxs("div", { className: "flex flex-wrap justify-center gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => void testpaginaAfdrukken(), children: "Testpagina afdrukken" }), _jsx(Button, { variant: "ghost", onClick: resetAlles, children: "Nog een printer instellen" }), _jsx(Button, { onClick: () => onOpenChange(false), children: "Klaar" })] })] }))] }) }));
|
|
180
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-h-[85vh] overflow-y-auto sm:max-w-xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: bewerken ? "Naam en locatie wijzigen" : "Printer toevoegen" }), _jsx(DialogDescription, { children: bewerken
|
|
181
|
+
? "Pas de naam, de locatie en het soort papier aan."
|
|
182
|
+
: "Kies uw printer, geef hem een herkenbare naam en druk een testpagina af." })] }), !bewerken && _jsx(Stappenbalk, { stap: stap }), stap === 0 && (_jsxs("div", { className: "space-y-4", children: [lijst.length > 6 && (_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground absolute top-2.5 left-3 h-4 w-4" }), _jsx(Input, { className: "pl-9", value: zoekterm, placeholder: "Zoek op printer of computer", onChange: (e) => setZoekterm(e.target.value) })] })), zoekt && (_jsxs("p", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Printers zoeken\u2026"] })), !zoekt && fout && _jsx("p", { className: "text-destructive text-sm", children: fout }), !zoekt && zichtbaar.length > 0 && (_jsx("div", { className: "grid gap-2 sm:grid-cols-2", children: zichtbaar.map((p) => {
|
|
183
|
+
const al = bekendeExterneIds.includes(p.id);
|
|
184
|
+
return (_jsx("button", { type: "button", disabled: al, onClick: () => kiesPrinter(p), className: `rounded-xl border p-4 text-left transition ${al ? "opacity-60" : "hover:border-primary/50 hover:bg-accent/40"}`, children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Printer, { className: "text-muted-foreground mt-0.5 h-5 w-5 shrink-0" }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "truncate text-sm font-medium", children: p.naam }), _jsx("p", { className: "text-muted-foreground truncate text-xs", children: p.computer }), _jsxs("span", { className: "mt-2 flex items-center gap-1.5 text-xs", children: [_jsx("span", { className: `h-2 w-2 rounded-full ${p.online ? "bg-primary" : "bg-muted-foreground/40"}` }), al ? "Al toegevoegd" : p.online ? "Beschikbaar" : "Niet aan"] })] })] }) }, p.id));
|
|
185
|
+
}) })), !zoekt && zichtbaar.length === 0 && _jsx(PrintProgrammaUitleg, {}), !zoekt && zichtbaar.length > 0 && (_jsxs("div", { className: "space-y-3", children: [_jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground text-sm underline", onClick: () => setUitlegOpen((v) => !v), children: "Ik zie mijn printer niet" }), uitlegOpen && _jsx(PrintProgrammaUitleg, { compact: true })] })), _jsx("div", { className: "flex justify-between", children: _jsxs(Button, { variant: "ghost", onClick: () => void zoeken(), disabled: zoekt, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), " Opnieuw zoeken"] }) })] })), stap === 1 && (_jsxs("div", { className: "grid gap-5 sm:grid-cols-[1fr_200px]", children: [_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Weergavenaam" }), _jsx(Input, { value: naam, placeholder: "Bijvoorbeeld: pakbonprinter voorin", onChange: (e) => setNaam(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Locatie" }), _jsx(Input, { value: locatie, placeholder: "Bijvoorbeeld: magazijn", onChange: (e) => setLocatie(e.target.value) }), bekendeLocaties.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 pt-1", children: bekendeLocaties.slice(0, 6).map((l) => (_jsx("button", { type: "button", onClick: () => setLocatie(l), className: "hover:bg-accent rounded-full border px-3 py-1 text-xs", children: l }, l))) }))] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Wat gaat deze printer afdrukken?" }), _jsx("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
186
|
+
{ code: "papier", label: "Papier (A4)", sub: "Gewone documenten", Icon: FileText },
|
|
187
|
+
{ code: "etiket", label: "Etiketten", sub: "Stickers en labels", Icon: Tag },
|
|
188
|
+
].map((o) => (_jsxs("button", { type: "button", onClick: () => setGebruik(o.code), className: `hover:bg-accent rounded-lg border p-4 text-left transition ${gebruik === o.code ? "border-primary bg-accent" : ""}`, children: [_jsx(o.Icon, { className: "text-muted-foreground mb-2 h-5 w-5" }), _jsx("p", { className: "text-sm font-medium", children: o.label }), _jsx("p", { className: "text-muted-foreground text-xs", children: o.sub })] }, o.code))) })] }), _jsxs("div", { className: "flex justify-between", children: [!bewerken ? (_jsx(Button, { variant: "ghost", onClick: () => setStap(0), children: "Terug" })) : (_jsx("span", {})), _jsx(Button, { disabled: bezig, onClick: () => void opslaan(), children: bewerken ? "Opslaan" : "Opslaan en verder" })] })] }), _jsxs("div", { className: "hidden sm:block", children: [_jsx("p", { className: "text-muted-foreground mb-2 text-xs", children: "Zo komt hij in de lijst:" }), _jsxs("div", { className: "bg-card rounded-xl border p-3", children: [_jsx(Printer, { className: "text-muted-foreground mb-2 h-4 w-4" }), _jsx("p", { className: "truncate text-sm font-medium", children: naam || "Naam van de printer" }), _jsx("p", { className: "text-muted-foreground truncate text-xs", children: locatie || "Geen locatie" })] })] })] })), stap === 2 && (_jsxs("div", { className: "space-y-4 text-center", children: [_jsx(CheckCircle2, { className: "text-primary mx-auto h-10 w-10" }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: "De printer is klaar voor gebruik" }), _jsxs("p", { className: "text-muted-foreground text-sm", children: [naam, " ", locatie ? `bij ${locatie}` : "", " drukt voortaan automatisch af."] })] }), testStatus !== "leeg" && (_jsxs("p", { className: "text-muted-foreground text-sm", children: [testStatus === "bezig" && "Onderweg naar de printer…", testStatus === "gelukt" && "De testpagina is verstuurd.", testStatus === "fout" && "De testpagina kon niet worden afgedrukt."] })), _jsxs("div", { className: "flex flex-wrap justify-center gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => void testpagina(), children: "Testpagina afdrukken" }), _jsx(Button, { variant: "ghost", onClick: opnieuw, children: "Nog een printer toevoegen" }), _jsx(Button, { onClick: () => onOpenChange(false), children: "Klaar" })] }), _jsx(WerktHetNiet, {})] }))] }) }));
|
|
119
189
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { LucideIcon } from "lucide-react";
|
|
2
|
+
export interface StatKaart {
|
|
3
|
+
label: string;
|
|
4
|
+
waarde: string;
|
|
5
|
+
toelichting: string;
|
|
6
|
+
icon: LucideIcon;
|
|
7
|
+
}
|
|
8
|
+
export declare function PrinterStatsKaarten({ kaarten }: {
|
|
9
|
+
kaarten: StatKaart[];
|
|
10
|
+
}): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=PrinterStatsKaarten.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrinterStatsKaarten.d.ts","sourceRoot":"","sources":["../../src/components/PrinterStatsKaarten.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,SAAS,EAAE,CAAA;CAAE,+BAmBxE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// src/components/PrinterStatsKaarten.tsx — vier kerncijfers bovenaan de pagina
|
|
4
|
+
// ============================================================================
|
|
5
|
+
import { Card, CardContent } from "@flowselections/core";
|
|
6
|
+
export function PrinterStatsKaarten({ kaarten }) {
|
|
7
|
+
return (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4", children: kaarten.map((k) => (_jsx(Card, { children: _jsxs(CardContent, { className: "flex items-center gap-4 py-5", children: [_jsx("div", { className: "bg-muted rounded-lg p-3", children: _jsx(k.icon, { className: "text-muted-foreground h-5 w-5" }) }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-muted-foreground truncate text-sm", children: k.label }), _jsx("p", { className: "text-2xl font-semibold leading-tight", children: k.waarde }), _jsx("p", { className: "text-muted-foreground truncate text-xs", children: k.toelichting })] })] }) }, k.label))) }));
|
|
8
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrintersPage.d.ts","sourceRoot":"","sources":["../../src/components/PrintersPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PrintersPage.d.ts","sourceRoot":"","sources":["../../src/components/PrintersPage.tsx"],"names":[],"mappings":"AAyBA,wBAAgB,YAAY,gCA6O3B"}
|
|
@@ -1,60 +1,131 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// src/components/PrintersPage.tsx — overzicht van werkplekken (computers) met
|
|
4
|
+
// hun printers, status en snelkoppelingen naar het configuratiescherm.
|
|
5
|
+
// ============================================================================
|
|
2
6
|
import { useMemo, useState } from "react";
|
|
3
|
-
import { Button,
|
|
7
|
+
import { Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@flowselections/core";
|
|
4
8
|
import { Link } from "@tanstack/react-router";
|
|
5
|
-
import { ListChecks, Plus, Printer,
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
9
|
+
import { CheckCircle2, FileText, ListChecks, Monitor, Plus, Printer, Search } from "lucide-react";
|
|
10
|
+
import { bijgewerktTekst, useAutoRefresh } from "../lib/useAutoRefresh";
|
|
11
|
+
import { useLayouts, usePrinters } from "../lib/useDocumentData";
|
|
12
|
+
import { useNetwerkPrinters } from "../lib/useNetwerkPrinters";
|
|
8
13
|
import { PrinterSetupWizard } from "./PrinterSetupWizard";
|
|
14
|
+
import { ComputersLijst, useComputers } from "./ComputersLijst";
|
|
15
|
+
import { PrinterStatsKaarten } from "./PrinterStatsKaarten";
|
|
16
|
+
import { WerkplekkenTabel } from "./WerkplekkenTabel";
|
|
9
17
|
export function PrintersPage() {
|
|
10
|
-
const { printers, koppelingen,
|
|
18
|
+
const { printers, koppelingen, reload } = usePrinters();
|
|
11
19
|
const { layouts } = useLayouts();
|
|
20
|
+
const { computers, loading: computersLaden, fout: computersFout, reload: herlaadComputers, } = useComputers();
|
|
21
|
+
const { gevonden, zoek } = useNetwerkPrinters();
|
|
12
22
|
const [wizard, setWizard] = useState(false);
|
|
13
|
-
const [
|
|
14
|
-
const
|
|
23
|
+
const [computerToevoegen, setComputerToevoegen] = useState(false);
|
|
24
|
+
const [computerFilter, setComputerFilter] = useState(null);
|
|
25
|
+
const [bewerken] = useState(null);
|
|
26
|
+
const [zoekterm, setZoekterm] = useState("");
|
|
27
|
+
const [status, setStatus] = useState("alle");
|
|
28
|
+
const [locatie, setLocatie] = useState("alle");
|
|
29
|
+
const bijgewerkt = useAutoRefresh(async () => {
|
|
30
|
+
await Promise.all([reload(true), herlaadComputers(true), zoek()]);
|
|
31
|
+
}, 10000, wizard || computerToevoegen);
|
|
32
|
+
const gekoppeldePrinters = useMemo(() => new Set(koppelingen.map((k) => k.printer_id)), [koppelingen]);
|
|
33
|
+
const printersPerComputer = useMemo(() => {
|
|
34
|
+
const externNaarComputer = new Map(gevonden.map((g) => [g.id, g.computer]));
|
|
15
35
|
const map = new Map();
|
|
16
|
-
for (const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
36
|
+
for (const p of printers) {
|
|
37
|
+
const extern = p.extern_printer_id ?? null;
|
|
38
|
+
const naam = extern ? externNaarComputer.get(extern) : undefined;
|
|
39
|
+
if (!naam)
|
|
40
|
+
continue;
|
|
41
|
+
const rij = map.get(naam) ?? { totaal: 0, gekoppeld: 0, locaties: [] };
|
|
42
|
+
rij.totaal += 1;
|
|
43
|
+
if (gekoppeldePrinters.has(p.id))
|
|
44
|
+
rij.gekoppeld += 1;
|
|
45
|
+
if (p.locatie && !rij.locaties.includes(p.locatie))
|
|
46
|
+
rij.locaties.push(p.locatie);
|
|
47
|
+
map.set(naam, rij);
|
|
20
48
|
}
|
|
21
49
|
return map;
|
|
22
|
-
}, [
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
50
|
+
}, [printers, gevonden, gekoppeldePrinters]);
|
|
51
|
+
const alleRijen = computers.map((c) => {
|
|
52
|
+
const info = printersPerComputer.get(c.naam);
|
|
53
|
+
return {
|
|
54
|
+
id: c.id,
|
|
55
|
+
naam: c.naam,
|
|
56
|
+
online: c.online,
|
|
57
|
+
locatie: info?.locaties.join(" · ") || "Geen locatie",
|
|
58
|
+
aantalPrinters: info?.totaal ?? c.aantalPrinters,
|
|
59
|
+
aantalGekoppeld: info?.gekoppeld ?? 0,
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
const locaties = Array.from(new Set(alleRijen.map((r) => r.locatie))).filter((l) => l !== "Geen locatie");
|
|
63
|
+
const rijen = alleRijen.filter((r) => {
|
|
64
|
+
const term = zoekterm.trim().toLowerCase();
|
|
65
|
+
if (term && !r.naam.toLowerCase().includes(term) && !r.locatie.toLowerCase().includes(term))
|
|
66
|
+
return false;
|
|
67
|
+
if (status === "aan" && !r.online)
|
|
68
|
+
return false;
|
|
69
|
+
if (status === "uit" && r.online)
|
|
70
|
+
return false;
|
|
71
|
+
if (locatie !== "alle" && r.locatie !== locatie)
|
|
72
|
+
return false;
|
|
73
|
+
return true;
|
|
74
|
+
});
|
|
75
|
+
const computersOnline = computers.filter((c) => c.online).length;
|
|
76
|
+
const bekendeExterneIds = printers
|
|
77
|
+
.map((p) => p.extern_printer_id ?? null)
|
|
78
|
+
.filter((e) => !!e);
|
|
79
|
+
const bekendeLocaties = Array.from(new Set(printers.map((p) => p.locatie).filter((l) => !!l)));
|
|
80
|
+
return (_jsxs("main", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-end justify-between gap-4", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl font-semibold", children: "Printers" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Beheer per werkplek welke computer is aangemeld en welke printers worden gebruikt." })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "ghost", asChild: true, children: _jsxs(Link, { to: "/layouts-printers/wachtrij", children: [_jsx(ListChecks, { className: "mr-2 h-4 w-4" }), " Printwachtrij"] }) }), _jsxs(Button, { onClick: () => setComputerToevoegen(true), children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), " Computer toevoegen"] })] })] }), _jsx(PrinterStatsKaarten, { kaarten: [
|
|
81
|
+
{
|
|
82
|
+
label: "Werkplekken",
|
|
83
|
+
waarde: String(computers.length),
|
|
84
|
+
toelichting: "Aangemelde computers",
|
|
85
|
+
icon: Monitor,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
label: "Totaal printers",
|
|
89
|
+
waarde: String(printers.length),
|
|
90
|
+
toelichting: "Ingestelde printers",
|
|
91
|
+
icon: Printer,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
label: "Documenten",
|
|
95
|
+
waarde: String(layouts.length),
|
|
96
|
+
toelichting: "Beschikbare ontwerpen",
|
|
97
|
+
icon: FileText,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
label: "Status",
|
|
101
|
+
waarde: `${computersOnline} / ${computers.length}`,
|
|
102
|
+
toelichting: "Werkplekken aan",
|
|
103
|
+
icon: CheckCircle2,
|
|
104
|
+
},
|
|
105
|
+
] }), _jsxs("div", { className: "flex flex-wrap items-center gap-3 rounded-xl border p-3", children: [_jsxs("div", { className: "relative min-w-[220px] flex-1", children: [_jsx(Search, { className: "text-muted-foreground absolute top-2.5 left-3 h-4 w-4" }), _jsx(Input, { className: "pl-9", placeholder: "Zoek werkplek of locatie\u2026", value: zoekterm, onChange: (e) => setZoekterm(e.target.value) })] }), _jsxs(Select, { value: status, onValueChange: setStatus, children: [_jsx(SelectTrigger, { className: "w-[170px]", children: _jsx(SelectValue, { placeholder: "Status" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "alle", children: "Status: alle" }), _jsx(SelectItem, { value: "aan", children: "Alleen aan" }), _jsx(SelectItem, { value: "uit", children: "Alleen uit" })] })] }), _jsxs(Select, { value: locatie, onValueChange: setLocatie, children: [_jsx(SelectTrigger, { className: "w-[190px]", children: _jsx(SelectValue, { placeholder: "Locatie" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "alle", children: "Locatie: alle" }), locaties.map((l) => (_jsx(SelectItem, { value: l, children: l }, l)))] })] }), _jsx("span", { className: "text-muted-foreground ml-auto text-xs", children: bijgewerktTekst(bijgewerkt) })] }), rijen.length > 0 ? (_jsx(WerkplekkenTabel, { rijen: rijen, onPrinterToevoegen: (computer) => {
|
|
106
|
+
setComputerFilter(computer);
|
|
107
|
+
setWizard(true);
|
|
108
|
+
}, onVernieuw: () => {
|
|
109
|
+
void herlaadComputers();
|
|
110
|
+
void zoek();
|
|
111
|
+
} })) : (_jsx(ComputersLijst, { computers: computers, loading: computersLaden, fout: computersFout, onVernieuw: () => {
|
|
112
|
+
void herlaadComputers();
|
|
113
|
+
void zoek();
|
|
114
|
+
}, onPrintersToevoegen: (computer) => {
|
|
115
|
+
setComputerFilter(computer);
|
|
116
|
+
setWizard(true);
|
|
117
|
+
}, toevoegenOpen: false, onToevoegenOpenChange: setComputerToevoegen })), _jsx(ComputersLijst, { computers: computers, loading: false, fout: null, onVernieuw: () => {
|
|
118
|
+
void herlaadComputers();
|
|
119
|
+
void zoek();
|
|
120
|
+
}, onPrintersToevoegen: (computer) => {
|
|
121
|
+
setComputerFilter(computer);
|
|
122
|
+
setWizard(true);
|
|
123
|
+
}, toevoegenOpen: computerToevoegen, onToevoegenOpenChange: setComputerToevoegen, alleenDialog: true }), _jsx(PrinterSetupWizard, { open: wizard, onOpenChange: (v) => {
|
|
124
|
+
setWizard(v);
|
|
125
|
+
if (!v)
|
|
126
|
+
setComputerFilter(null);
|
|
127
|
+
}, computerFilter: computerFilter, bekendeExterneIds: bekendeExterneIds, bekendeLocaties: bekendeLocaties, bewerken: bewerken, onKlaar: () => {
|
|
128
|
+
void reload();
|
|
129
|
+
void zoek();
|
|
130
|
+
} })] }));
|
|
60
131
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WerkplekConfiguratiePage.d.ts","sourceRoot":"","sources":["../../src/components/WerkplekConfiguratiePage.tsx"],"names":[],"mappings":"AA2BA,wBAAgB,wBAAwB,gCA6QvC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// src/components/WerkplekConfiguratiePage.tsx — één computer configureren:
|
|
4
|
+
// printers op deze computer en welke ontwerpen er worden afgedrukt.
|
|
5
|
+
// ============================================================================
|
|
6
|
+
import { useMemo, useState } from "react";
|
|
7
|
+
import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Checkbox, Input, toast, } from "@flowselections/core";
|
|
8
|
+
import { Link, useParams } from "@tanstack/react-router";
|
|
9
|
+
import { ChevronRight, Monitor, Plus, Printer, Search } from "lucide-react";
|
|
10
|
+
import { bijgewerktTekst, useAutoRefresh } from "../lib/useAutoRefresh";
|
|
11
|
+
import { toggleKoppeling, useLayouts, usePrinters, verwijderPrinter } from "../lib/useDocumentData";
|
|
12
|
+
import { useNetwerkPrinters } from "../lib/useNetwerkPrinters";
|
|
13
|
+
import { drukTestpaginaAf } from "../lib/testpagina";
|
|
14
|
+
import { useComputers } from "./ComputersLijst";
|
|
15
|
+
import { PrinterKaart } from "./PrinterKaart";
|
|
16
|
+
import { PrinterSetupWizard } from "./PrinterSetupWizard";
|
|
17
|
+
export function WerkplekConfiguratiePage() {
|
|
18
|
+
const params = useParams({ strict: false });
|
|
19
|
+
const computerId = params.computerId ?? "";
|
|
20
|
+
const { printers, koppelingen, reload } = usePrinters();
|
|
21
|
+
const { layouts } = useLayouts();
|
|
22
|
+
const { computers, reload: herlaadComputers } = useComputers();
|
|
23
|
+
const { gevonden, zoek } = useNetwerkPrinters();
|
|
24
|
+
const [wizard, setWizard] = useState(false);
|
|
25
|
+
const [bewerken, setBewerken] = useState(null);
|
|
26
|
+
const [gekozenPrinter, setGekozenPrinter] = useState(null);
|
|
27
|
+
const [zoekComputer, setZoekComputer] = useState("");
|
|
28
|
+
const [layoutZoek, setLayoutZoek] = useState("");
|
|
29
|
+
const bijgewerkt = useAutoRefresh(async () => {
|
|
30
|
+
await Promise.all([reload(true), herlaadComputers(true), zoek()]);
|
|
31
|
+
}, 10000, wizard);
|
|
32
|
+
const computer = computers.find((c) => c.id === computerId) ?? null;
|
|
33
|
+
const beschikbaarheid = useMemo(() => {
|
|
34
|
+
const map = new Map();
|
|
35
|
+
for (const g of gevonden)
|
|
36
|
+
map.set(g.id, g);
|
|
37
|
+
return map;
|
|
38
|
+
}, [gevonden]);
|
|
39
|
+
const gekoppeld = useMemo(() => {
|
|
40
|
+
const map = new Map();
|
|
41
|
+
for (const k of koppelingen) {
|
|
42
|
+
if (!map.has(k.printer_id))
|
|
43
|
+
map.set(k.printer_id, new Set());
|
|
44
|
+
map.get(k.printer_id).add(k.layout_id);
|
|
45
|
+
}
|
|
46
|
+
return map;
|
|
47
|
+
}, [koppelingen]);
|
|
48
|
+
const rijen = printers
|
|
49
|
+
.map((p) => {
|
|
50
|
+
const extern = p.extern_printer_id ?? null;
|
|
51
|
+
const net = extern ? beschikbaarheid.get(extern) : undefined;
|
|
52
|
+
return { printer: p, extern, computer: net?.computer ?? null, online: !!net?.online };
|
|
53
|
+
})
|
|
54
|
+
.filter((r) => (computer ? r.computer === computer.naam : false));
|
|
55
|
+
const actievePrinter = printers.find((p) => p.id === gekozenPrinter) ?? null;
|
|
56
|
+
const zichtbareComputers = computers.filter((c) => zoekComputer.trim() ? c.naam.toLowerCase().includes(zoekComputer.trim().toLowerCase()) : true);
|
|
57
|
+
const zichtbareLayouts = layouts.filter((l) => layoutZoek.trim() ? l.naam.toLowerCase().includes(layoutZoek.trim().toLowerCase()) : true);
|
|
58
|
+
const bekendeExterneIds = printers
|
|
59
|
+
.map((p) => p.extern_printer_id ?? null)
|
|
60
|
+
.filter((e) => !!e);
|
|
61
|
+
const bekendeLocaties = Array.from(new Set(printers.map((p) => p.locatie).filter((l) => !!l)));
|
|
62
|
+
return (_jsxs("main", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "text-muted-foreground flex items-center gap-1 text-sm", children: [_jsx(Link, { to: "/layouts-printers/printers", className: "hover:text-foreground", children: "Printers" }), _jsx(ChevronRight, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-foreground", children: computer?.naam ?? "Werkplek" })] }), _jsxs("div", { className: "flex flex-wrap items-end justify-between gap-4", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl font-semibold", children: "Werkplek configureren" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Kies welke printers op deze computer welke ontwerpen afdrukken." })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground text-xs", children: bijgewerktTekst(bijgewerkt) }), _jsxs(Button, { onClick: () => {
|
|
63
|
+
setBewerken(null);
|
|
64
|
+
setWizard(true);
|
|
65
|
+
}, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), " Printer toevoegen"] })] })] }), _jsxs("div", { className: "grid gap-6 lg:grid-cols-[300px_1fr]", children: [_jsxs(Card, { className: "h-fit", children: [_jsx(CardHeader, { className: "pb-3", children: _jsx(CardTitle, { className: "text-base", children: "Werkplekken" }) }), _jsxs(CardContent, { className: "space-y-2", children: [_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground absolute top-2.5 left-3 h-4 w-4" }), _jsx(Input, { className: "pl-9", placeholder: "Zoek werkplek", value: zoekComputer, onChange: (e) => setZoekComputer(e.target.value) })] }), zichtbareComputers.map((c) => (_jsxs(Link, { to: "/layouts-printers/printers/$computerId", params: { computerId: c.id }, className: `flex items-center gap-3 rounded-lg border p-3 text-sm transition ${c.id === computerId ? "border-primary ring-primary/20 ring-2" : "hover:bg-muted/50"}`, children: [_jsx("span", { className: `h-2 w-2 shrink-0 rounded-full ${c.online ? "bg-primary" : "bg-muted-foreground/40"}` }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate font-medium", children: c.naam }), _jsxs("span", { className: "text-muted-foreground block text-xs", children: [c.aantalPrinters, " ", c.aantalPrinters === 1 ? "printer" : "printers"] })] }), _jsx(ChevronRight, { className: "text-muted-foreground h-4 w-4" })] }, c.id))), zichtbareComputers.length === 0 && (_jsx("p", { className: "text-muted-foreground text-sm", children: "Geen werkplekken gevonden." }))] })] }), _jsxs("div", { className: "space-y-6", children: [_jsx(Card, { children: _jsxs(CardHeader, { className: "pb-3", children: [_jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [_jsx(Monitor, { className: "h-4 w-4" }), " ", computer?.naam ?? "Onbekende werkplek"] }), _jsx(CardDescription, { children: computer
|
|
66
|
+
? `${computer.online ? "Aan" : "Uit"} · ${rijen.length} ${rijen.length === 1 ? "printer" : "printers"}`
|
|
67
|
+
: "Deze computer is niet gevonden. Staat hij aan?" })] }) }), _jsxs("div", { className: "grid gap-6 xl:grid-cols-[1fr_340px]", children: [_jsxs("div", { className: "space-y-3", children: [rijen.length === 0 && (_jsx(Card, { children: _jsxs(CardContent, { className: "space-y-4 py-10 text-center", children: [_jsx(Printer, { className: "text-muted-foreground mx-auto h-8 w-8" }), _jsx("p", { className: "text-sm font-medium", children: "Nog geen printers op deze werkplek" }), _jsx(Button, { onClick: () => {
|
|
68
|
+
setBewerken(null);
|
|
69
|
+
setWizard(true);
|
|
70
|
+
}, children: "Printer toevoegen" })] }) })), rijen.map(({ printer, online }) => (_jsx(PrinterKaart, { printer: printer, computer: computer?.naam ?? null, beschikbaar: online, gekozen: printer.id === gekozenPrinter, onKies: () => setGekozenPrinter(printer.id), onTest: () => void drukTestpaginaAf(printer.id, printer.naam), onBewerk: () => {
|
|
71
|
+
setBewerken({
|
|
72
|
+
id: printer.id,
|
|
73
|
+
naam: printer.naam,
|
|
74
|
+
locatie: printer.locatie,
|
|
75
|
+
papierformaat: printer.papierformaat,
|
|
76
|
+
});
|
|
77
|
+
setWizard(true);
|
|
78
|
+
}, onVerwijder: async () => {
|
|
79
|
+
try {
|
|
80
|
+
await verwijderPrinter(printer.id);
|
|
81
|
+
toast.success("Printer verwijderd");
|
|
82
|
+
void reload();
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
toast.error("Verwijderen mislukt");
|
|
86
|
+
}
|
|
87
|
+
} }, printer.id)))] }), actievePrinter && (_jsxs(Card, { className: "h-fit", children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsx(CardTitle, { className: "text-base", children: "Wat wordt hier afgedrukt?" }), _jsx(CardDescription, { children: actievePrinter.naam })] }), _jsxs(CardContent, { className: "space-y-3", children: [layouts.length > 8 && (_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground absolute top-2.5 left-3 h-4 w-4" }), _jsx(Input, { className: "pl-9", value: layoutZoek, placeholder: "Zoek een ontwerp", onChange: (e) => setLayoutZoek(e.target.value) })] })), zichtbareLayouts.map((l) => {
|
|
88
|
+
const aan = gekoppeld.get(actievePrinter.id)?.has(l.id) ?? false;
|
|
89
|
+
return (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Checkbox, { checked: aan, onCheckedChange: async (v) => {
|
|
90
|
+
await toggleKoppeling(l.id, actievePrinter.id, !!v);
|
|
91
|
+
void reload();
|
|
92
|
+
} }), _jsxs("div", { className: "min-w-0", children: [_jsx("span", { className: "block truncate text-sm", children: l.naam }), _jsx("span", { className: "text-muted-foreground text-xs", children: l.papierformaat })] })] }, l.id));
|
|
93
|
+
}), zichtbareLayouts.length === 0 && (_jsx("p", { className: "text-muted-foreground text-sm", children: "Er zijn nog geen ontwerpen." }))] })] }))] })] })] }), _jsx(PrinterSetupWizard, { open: wizard, onOpenChange: (v) => {
|
|
94
|
+
setWizard(v);
|
|
95
|
+
if (!v)
|
|
96
|
+
setBewerken(null);
|
|
97
|
+
}, computerFilter: computer?.naam ?? null, bekendeExterneIds: bekendeExterneIds, bekendeLocaties: bekendeLocaties, bewerken: bewerken, onKlaar: () => {
|
|
98
|
+
void reload();
|
|
99
|
+
void zoek();
|
|
100
|
+
} })] }));
|
|
101
|
+
}
|