@flowselections/layout-maker 1.46.1 → 1.51.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/components/ComputerVerwijderenDialog.d.ts +16 -0
- package/dist-lib/components/ComputerVerwijderenDialog.d.ts.map +1 -0
- package/dist-lib/components/ComputerVerwijderenDialog.js +38 -0
- package/dist-lib/components/ComputersLijst.d.ts.map +1 -1
- package/dist-lib/components/ComputersLijst.js +5 -2
- package/dist-lib/components/LayoutPrinterSelect.d.ts +3 -5
- package/dist-lib/components/LayoutPrinterSelect.d.ts.map +1 -1
- package/dist-lib/components/LayoutPrinterSelect.js +40 -17
- package/dist-lib/components/LayoutsPage.d.ts.map +1 -1
- package/dist-lib/components/LayoutsPage.js +28 -18
- package/dist-lib/components/PrinterSetupWizard.d.ts +3 -1
- package/dist-lib/components/PrinterSetupWizard.d.ts.map +1 -1
- package/dist-lib/components/PrinterSetupWizard.js +13 -4
- package/dist-lib/components/PrinterVervangenDialog.d.ts +14 -0
- package/dist-lib/components/PrinterVervangenDialog.d.ts.map +1 -0
- package/dist-lib/components/PrinterVervangenDialog.js +44 -0
- package/dist-lib/components/PrintersPage.d.ts.map +1 -1
- package/dist-lib/components/PrintersPage.js +2 -2
- package/dist-lib/components/PrintplekDetailPage.d.ts.map +1 -1
- package/dist-lib/components/PrintplekDetailPage.js +175 -48
- package/dist-lib/components/PrintplekVerwijderenDialog.d.ts +9 -0
- package/dist-lib/components/PrintplekVerwijderenDialog.d.ts.map +1 -0
- package/dist-lib/components/PrintplekVerwijderenDialog.js +34 -0
- package/dist-lib/components/PrintplekkenPage.d.ts.map +1 -1
- package/dist-lib/components/PrintplekkenPage.js +28 -6
- package/dist-lib/components/WerkplekConfiguratiePage.d.ts.map +1 -1
- package/dist-lib/components/WerkplekConfiguratiePage.js +67 -25
- package/dist-lib/index.d.ts +9 -4
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +7 -3
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +511 -6
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +511 -6
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/moduleClient.d.ts +511 -6
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +527 -6
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/aiLayout.functions.d.ts +511 -6
- package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
- package/dist-lib/lib/documentRoutering.d.ts +2 -1
- package/dist-lib/lib/documentRoutering.d.ts.map +1 -1
- package/dist-lib/lib/documentRoutering.js +5 -8
- package/dist-lib/lib/foutTekst.d.ts +3 -0
- package/dist-lib/lib/foutTekst.d.ts.map +1 -0
- package/dist-lib/lib/foutTekst.js +25 -0
- package/dist-lib/lib/printApi.d.ts.map +1 -1
- package/dist-lib/lib/printApi.js +13 -39
- package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/printQueue.server.js +19 -66
- package/dist-lib/lib/printRoutering.d.ts +34 -0
- package/dist-lib/lib/printRoutering.d.ts.map +1 -0
- package/dist-lib/lib/printRoutering.js +69 -0
- package/dist-lib/lib/printService.functions.d.ts +2555 -30
- package/dist-lib/lib/printService.functions.d.ts.map +1 -1
- package/dist-lib/lib/printplekken.d.ts +67 -2
- package/dist-lib/lib/printplekken.d.ts.map +1 -1
- package/dist-lib/lib/printplekken.js +141 -10
- package/dist-lib/lib/useDocumentData.d.ts +15 -10
- package/dist-lib/lib/useDocumentData.d.ts.map +1 -1
- package/dist-lib/lib/useDocumentData.js +43 -34
- package/package.json +2 -2
|
@@ -1,57 +1,136 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
// ============================================================================
|
|
3
|
-
// src/components/PrintplekDetailPage.tsx — één printplek
|
|
4
|
-
// computers
|
|
5
|
-
//
|
|
3
|
+
// src/components/PrintplekDetailPage.tsx — de centrale plek voor één printplek:
|
|
4
|
+
// computers, printers (per computer) en welk document naar welke printer gaat.
|
|
5
|
+
// Alles is hier direct bewerkbaar; de wizard is alleen voor een nieuwe plek.
|
|
6
6
|
// ============================================================================
|
|
7
|
-
import { useMemo, useState } from "react";
|
|
7
|
+
import { useEffect, useMemo, useState } from "react";
|
|
8
8
|
import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, toast, } from "@flowselections/core";
|
|
9
|
-
import { Link, useParams } from "@tanstack/react-router";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
|
10
|
+
import { PrintplekVerwijderenDialog } from "./PrintplekVerwijderenDialog.js";
|
|
11
|
+
import { AlertTriangle, ArrowLeft, Check, Link2, Monitor, Plus, Printer, Trash2, X, } from "lucide-react";
|
|
12
|
+
import { bewerkPrintplek, koppelComputerAanPrintplek, koppelPrinterLosVanPrintplek, ontkoppelBron, usePrintplekken, verplaatsPrinterNaarPrintplek, wijsPrinterToeAanPrintplek, zetPrintplekPrinter, } from "../lib/printplekken.js";
|
|
13
|
+
import { PrinterVervangenDialog } from "./PrinterVervangenDialog.js";
|
|
14
|
+
import { ComputerVerwijderenDialog } from "./ComputerVerwijderenDialog.js";
|
|
12
15
|
import { usePrinters } from "../lib/useDocumentData.js";
|
|
13
16
|
import { useNetwerkPrinters } from "../lib/useNetwerkPrinters.js";
|
|
14
17
|
import { useComputers } from "./ComputersLijst.js";
|
|
15
18
|
import { DOCUMENT_TYPES, documentTypeLabel } from "../lib/documentTypes.js";
|
|
16
19
|
import { drukTestpaginaAf } from "../lib/testpagina.js";
|
|
17
|
-
import { PrintplekWizard } from "./PrintplekWizard.js";
|
|
18
20
|
import { TestprintDialog } from "./TestprintDialog.js";
|
|
21
|
+
import { leesbareFout } from "../lib/foutTekst.js";
|
|
22
|
+
import { useRouteringOverzicht } from "../lib/printRoutering.js";
|
|
23
|
+
const BRON_LABEL = {
|
|
24
|
+
printplek: "Printplek-eigen",
|
|
25
|
+
werkplek: "Werkplek-uitzondering",
|
|
26
|
+
layout: "Standaardprinter (layout)",
|
|
27
|
+
standaard: "Bedrijfsstandaard",
|
|
28
|
+
geen: "Geen regel",
|
|
29
|
+
};
|
|
30
|
+
const selectKlasse = "border-input bg-background rounded-md border px-2 py-1 text-sm";
|
|
19
31
|
export function PrintplekDetailPage() {
|
|
20
32
|
const params = useParams({ strict: false });
|
|
21
33
|
const plekId = params.printplekId ?? "";
|
|
22
|
-
const
|
|
23
|
-
const
|
|
34
|
+
const navigate = useNavigate();
|
|
35
|
+
const [verwijderOpen, setVerwijderOpen] = useState(false);
|
|
36
|
+
const { plekken, computers: plekComputers, regels, koppelingen, toegewezen, reload } = usePrintplekken();
|
|
37
|
+
const { computers, reload: herlaadComputers } = useComputers();
|
|
24
38
|
const { printers } = usePrinters();
|
|
25
39
|
const { gevonden } = useNetwerkPrinters();
|
|
26
40
|
const [naamBewerken, setNaamBewerken] = useState(false);
|
|
27
41
|
const [naam, setNaam] = useState("");
|
|
28
42
|
const [alleDocumenten, setAlleDocumenten] = useState(false);
|
|
29
|
-
const [wizardOpen, setWizardOpen] = useState(false);
|
|
30
43
|
const [testprintOpen, setTestprintOpen] = useState(false);
|
|
44
|
+
const [vervangen, setVervangen] = useState(null);
|
|
45
|
+
const [toevoegen, setToevoegen] = useState("");
|
|
46
|
+
const [computerToevoegen, setComputerToevoegen] = useState("");
|
|
47
|
+
const [teVerwijderen, setTeVerwijderen] = useState(null);
|
|
31
48
|
const plek = plekken.find((p) => p.id === plekId) ?? null;
|
|
32
49
|
const eigenComputers = plekComputers.filter((c) => c.print_plek_id === plekId);
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
50
|
+
const vrijeComputers = computers.filter((c) => !plekComputers.some((pc) => pc.computer_naam === c.naam));
|
|
51
|
+
const andereplekken = plekken.filter((p) => p.id !== plekId);
|
|
52
|
+
// De live scan bepaalt alleen online-status en op welke computer een printer hangt.
|
|
53
|
+
const computerVanExtern = useMemo(() => {
|
|
54
|
+
const m = new Map();
|
|
55
|
+
for (const g of Array.isArray(gevonden) ? gevonden : [])
|
|
56
|
+
if (g.id)
|
|
57
|
+
m.set(String(g.id), g.computer);
|
|
58
|
+
return m;
|
|
41
59
|
}, [gevonden]);
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
return
|
|
60
|
+
const externVan = (p) => p.extern_printer_id ?? null;
|
|
61
|
+
const isOnline = (p) => {
|
|
62
|
+
const e = externVan(p);
|
|
63
|
+
return e ? computerVanExtern.has(String(e)) : false;
|
|
64
|
+
};
|
|
65
|
+
const computerVan = (p) => {
|
|
66
|
+
const e = externVan(p);
|
|
67
|
+
return e ? computerVanExtern.get(String(e)) ?? null : null;
|
|
68
|
+
};
|
|
69
|
+
const toegewezenIds = new Set((Array.isArray(toegewezen) ? toegewezen : [])
|
|
70
|
+
.filter((t) => t.print_plek_id === plekId)
|
|
71
|
+
.map((t) => t.printer_id));
|
|
72
|
+
const eigenPrinters = printers.filter((p) => toegewezenIds.has(p.id));
|
|
73
|
+
const nietToegewezen = printers.filter((p) => !toegewezenIds.has(p.id));
|
|
74
|
+
const eigenNamen = new Set(eigenComputers.map((c) => c.computer_naam));
|
|
75
|
+
const printersPerComputer = eigenComputers.map((c) => ({
|
|
76
|
+
naam: c.computer_naam,
|
|
77
|
+
printers: eigenPrinters.filter((p) => computerVan(p) === c.computer_naam),
|
|
78
|
+
}));
|
|
79
|
+
const nietGevonden = eigenPrinters.filter((p) => {
|
|
80
|
+
const c = computerVan(p);
|
|
81
|
+
return !c || !eigenNamen.has(c);
|
|
46
82
|
});
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
const
|
|
83
|
+
const pcNamen = eigenComputers.map((c) => c.computer_naam).sort();
|
|
84
|
+
const { uitkomsten, laden: routeringLaden, reload: reloadRoutering } = useRouteringOverzicht(plekId, DOCUMENT_TYPES.map((d) => d.value), pcNamen);
|
|
85
|
+
const uitkomstVoor = (t, pc) => uitkomsten[`${t}::${pc ?? ""}`] ?? null;
|
|
86
|
+
const routeringZichtbaar = DOCUMENT_TYPES.filter((d) => alleDocumenten ||
|
|
87
|
+
(pcNamen.length ? pcNamen : [null]).some((pc) => {
|
|
88
|
+
const u = uitkomstVoor(d.value, pc);
|
|
89
|
+
return !!u && (u.bron !== "geen" || u.overgeslagen.length > 0);
|
|
90
|
+
}));
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
void reloadRoutering();
|
|
93
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
94
|
+
}, [regels, toegewezen]);
|
|
95
|
+
const printerNaam = (id) => printers.find((p) => p.id === id)?.naam ?? null;
|
|
96
|
+
const printerOnline = (id) => {
|
|
97
|
+
const p = printers.find((x) => x.id === id);
|
|
98
|
+
return p ? isOnline(p) : false;
|
|
99
|
+
};
|
|
100
|
+
const computerId = (n) => computers.find((k) => k.naam === n)?.id ?? null;
|
|
101
|
+
const eigenRegel = (t) => regels.find((r) => r.print_plek_id === plekId && r.documenttype === t) ?? null;
|
|
102
|
+
const vernieuw = async () => {
|
|
103
|
+
await reload(true);
|
|
104
|
+
await reloadRoutering();
|
|
105
|
+
};
|
|
106
|
+
const zetRegel = async (documenttype, waarde) => {
|
|
107
|
+
try {
|
|
108
|
+
await zetPrintplekPrinter(plekId, documenttype, waarde === "standaard" ? null : waarde);
|
|
109
|
+
await vernieuw();
|
|
110
|
+
toast.success("Printer opgeslagen");
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
toast.error(leesbareFout(err));
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
function BronLink({ u }) {
|
|
117
|
+
const pcId = computerId(u.werkplek);
|
|
118
|
+
if (u.bron === "werkplek" && pcId)
|
|
119
|
+
return (_jsx(Link, { to: "/layouts-printers/printplekken/computers/$computerId", params: { computerId: pcId }, className: "text-primary text-xs underline", children: "Werkplek-uitzondering" }));
|
|
120
|
+
if (u.bron === "standaard")
|
|
121
|
+
return (_jsx(Link, { to: "/layouts-printers/printplekken", className: "text-primary text-xs underline", children: "Standaard bewerken" }));
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
function RouteringCellen({ u }) {
|
|
125
|
+
if (!u)
|
|
126
|
+
return _jsx("td", { colSpan: 3 });
|
|
127
|
+
const n = printerNaam(u.printer_id);
|
|
128
|
+
const status = !u.printer_id ? "geen" : n ? (printerOnline(u.printer_id) ? "online" : "offline") : "ontbreekt";
|
|
129
|
+
return (_jsxs(_Fragment, { children: [_jsx("td", { className: "py-2 pr-3 text-xs text-muted-foreground", children: u.papierformaat ?? "—" }), _jsxs("td", { className: "py-2 pr-3", children: [_jsxs(Badge, { variant: u.bron === "geen" ? "destructive" : "secondary", "data-bron": u.bron, children: [BRON_LABEL[u.bron], u.bron === "werkplek" && u.werkplek ? ` (${u.werkplek})` : ""] }), u.overgeslagen.map((o) => (_jsxs("div", { className: "text-destructive mt-1 flex items-center gap-1 text-xs", children: [_jsx(AlertTriangle, { className: "h-3.5 w-3.5" }), " ", BRON_LABEL[o.bron], " overgeslagen: printer", " ", o.reden === "ontbreekt" ? "ontbreekt" : o.reden === "inactief" ? "inactief" : "niet (meer) aan deze plek gekoppeld"] }, o.regel_id)))] }), _jsxs("td", { className: "py-2 pr-3", children: [u.printer_id ? (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx("span", { className: `h-2 w-2 rounded-full ${status === "online" ? "bg-emerald-500" : status === "offline" ? "bg-muted-foreground" : "bg-destructive"}` }), n ?? "Onbekende printer", _jsx("span", { className: "text-muted-foreground text-xs", children: status })] })) : (_jsx("span", { className: "text-destructive text-xs", children: "geen printer \u2014 opdrachten blijven wachten" })), _jsx("div", { children: _jsx(BronLink, { u: u }) })] })] }));
|
|
130
|
+
}
|
|
51
131
|
const bronnen = koppelingen.filter((k) => k.print_plek_id === plekId);
|
|
52
132
|
const bestaandePlekIds = new Set(plekken.map((p) => p.id));
|
|
53
133
|
const weeskoppelingen = koppelingen.filter((k) => !bestaandePlekIds.has(k.print_plek_id));
|
|
54
|
-
const onvolledig = eigenComputers.length === 0 || !regels.some((r) => r.print_plek_id === plekId && r.printer_id);
|
|
55
134
|
const ontkoppel = async (bron, bronId) => {
|
|
56
135
|
try {
|
|
57
136
|
await ontkoppelBron(bron, bronId);
|
|
@@ -62,9 +141,44 @@ export function PrintplekDetailPage() {
|
|
|
62
141
|
toast.error("Ontkoppelen mislukt");
|
|
63
142
|
}
|
|
64
143
|
};
|
|
144
|
+
const loskoppelen = async (p) => {
|
|
145
|
+
const n = regels.filter((r) => r.print_plek_id === plekId && r.printer_id === p.id).length;
|
|
146
|
+
if (n > 0 && !window.confirm(`${n} regel(s) wijzen naar ${p.naam}. Die worden leeg en gemarkeerd. Doorgaan?`))
|
|
147
|
+
return;
|
|
148
|
+
try {
|
|
149
|
+
await koppelPrinterLosVanPrintplek(plekId, p.id);
|
|
150
|
+
await vernieuw();
|
|
151
|
+
toast.success("Printer verwijderd van deze plek");
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
toast.error("Verwijderen mislukt");
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const verplaats = async (p, naarPlek) => {
|
|
158
|
+
try {
|
|
159
|
+
await verplaatsPrinterNaarPrintplek(p.id, plekId, naarPlek);
|
|
160
|
+
await vernieuw();
|
|
161
|
+
toast.success(`${p.naam} verplaatst`);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
toast.error("Verplaatsen mislukt");
|
|
165
|
+
}
|
|
166
|
+
};
|
|
65
167
|
if (!plek) {
|
|
66
168
|
return (_jsxs("main", { className: "space-y-4 p-6", children: [_jsx(Button, { variant: "ghost", asChild: true, children: _jsxs(Link, { to: "/layouts-printers/printplekken", children: [_jsx(ArrowLeft, { className: "mr-2 h-4 w-4" }), " Terug"] }) }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Deze printplek bestaat niet (meer)." })] }));
|
|
67
169
|
}
|
|
170
|
+
const PrinterRij = ({ p }) => (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 rounded-lg border p-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx("span", { className: `h-2 w-2 rounded-full ${isOnline(p) ? "bg-emerald-500" : "bg-muted-foreground"}` }), _jsx("span", { className: "font-medium", children: p.naam }), p.papierformaat ? _jsx(Badge, { variant: "secondary", children: p.papierformaat }) : null, !isOnline(p) ? _jsx("span", { className: "text-muted-foreground text-xs", children: "offline" }) : null] }), _jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [_jsx(Button, { size: "sm", variant: "ghost", onClick: async () => {
|
|
171
|
+
try {
|
|
172
|
+
await drukTestpaginaAf(p.id, p.naam);
|
|
173
|
+
toast.success("Testpagina verstuurd");
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
toast.error("Testpagina versturen is niet gelukt.");
|
|
177
|
+
}
|
|
178
|
+
}, children: "Testpagina" }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => setVervangen({ id: p.id, naam: p.naam }), children: "Vervangen" }), andereplekken.length > 0 ? (_jsxs("select", { className: selectKlasse, value: "", "aria-label": `${p.naam} verplaatsen`, onChange: (e) => e.target.value && void verplaats(p, e.target.value), children: [_jsx("option", { value: "", children: "Verplaatsen\u2026" }), andereplekken.map((o) => (_jsxs("option", { value: o.id, children: ["naar ", o.naam] }, o.id)))] })) : null, _jsx(Button, { size: "sm", variant: "ghost", className: "text-destructive", onClick: () => void loskoppelen(p), children: "Verwijderen" })] })] }));
|
|
179
|
+
const teVerwijderenPrinters = teVerwijderen
|
|
180
|
+
? eigenPrinters.filter((p) => computerVan(p) === teVerwijderen).map((p) => ({ id: p.id, naam: p.naam }))
|
|
181
|
+
: [];
|
|
68
182
|
return (_jsxs("main", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(Button, { variant: "ghost", size: "sm", asChild: true, className: "-ml-2", children: _jsxs(Link, { to: "/layouts-printers/printplekken", children: [_jsx(ArrowLeft, { className: "mr-2 h-4 w-4" }), " Alle printplekken"] }) }), naamBewerken ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { value: naam, onChange: (e) => setNaam(e.target.value), className: "w-64" }), _jsx(Button, { size: "icon", onClick: async () => {
|
|
69
183
|
await bewerkPrintplek(plek.id, { naam: naam.trim() });
|
|
70
184
|
setNaamBewerken(false);
|
|
@@ -72,28 +186,41 @@ export function PrintplekDetailPage() {
|
|
|
72
186
|
}, children: _jsx(Check, { className: "h-4 w-4" }) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: () => setNaamBewerken(false), children: _jsx(X, { className: "h-4 w-4" }) })] })) : (_jsx("h1", { className: "cursor-pointer text-xl font-semibold", onClick: () => {
|
|
73
187
|
setNaam(plek.naam);
|
|
74
188
|
setNaamBewerken(true);
|
|
75
|
-
}, children: plek.naam })), _jsx("p", { className: "text-muted-foreground text-sm", children: plek.omschrijving ?? "
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
189
|
+
}, children: plek.naam })), _jsx("p", { className: "text-muted-foreground text-sm", children: plek.omschrijving ?? "Hier stel je alles in wat er op deze plek wordt afgedrukt." })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { variant: "outline", onClick: () => setTestprintOpen(true), children: [_jsx(Printer, { className: "mr-2 h-4 w-4" }), " Testprint controleren"] }), _jsxs(Button, { variant: "ghost", className: "text-destructive", onClick: () => setVerwijderOpen(true), children: [_jsx(Trash2, { className: "mr-2 h-4 w-4" }), " Verwijderen"] })] })] }), _jsx(PrintplekVerwijderenDialog, { plek: verwijderOpen ? { id: plek.id, naam: plek.naam } : null, onOpenChange: setVerwijderOpen, onKlaar: () => void navigate({ to: "/layouts-printers/printplekken" }) }), _jsx(TestprintDialog, { open: testprintOpen, onOpenChange: setTestprintOpen, printplekId: plekId, printplekNaam: plek.naam }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [_jsx(Monitor, { className: "h-4 w-4" }), " Computers op deze plek"] }), _jsx(CardDescription, { children: "Het bolletje laat zien of de computer nu aan staat." })] }), vrijeComputers.length > 0 ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("select", { className: selectKlasse, value: computerToevoegen, onChange: (e) => setComputerToevoegen(e.target.value), "aria-label": "Computer kiezen", children: [_jsx("option", { value: "", children: "Computer kiezen\u2026" }), vrijeComputers.map((c) => (_jsx("option", { value: c.naam, children: c.naam }, c.id)))] }), _jsxs(Button, { size: "sm", disabled: !computerToevoegen, onClick: async () => {
|
|
190
|
+
try {
|
|
191
|
+
await koppelComputerAanPrintplek(plekId, computerToevoegen);
|
|
192
|
+
setComputerToevoegen("");
|
|
193
|
+
await vernieuw();
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
toast.error("Toevoegen mislukt");
|
|
197
|
+
}
|
|
198
|
+
}, children: [_jsx(Plus, { className: "mr-1 h-4 w-4" }), " Computer toevoegen"] })] })) : null] }), _jsx(CardContent, { className: "space-y-2", children: eigenComputers.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-sm", children: "Nog geen computers gekoppeld." })) : (eigenComputers.map((c) => {
|
|
199
|
+
const aan = computers.find((k) => k.naam === c.computer_naam)?.online ?? false;
|
|
200
|
+
return (_jsxs("div", { className: "flex items-center gap-3 rounded-lg border px-3 py-2 text-sm", children: [_jsx("span", { className: `h-2 w-2 rounded-full ${aan ? "bg-emerald-500" : "bg-muted-foreground"}` }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: c.computer_naam }), _jsx("span", { className: "text-muted-foreground text-xs", children: aan ? "Aan" : "Uit" }), _jsxs(Button, { size: "sm", variant: "ghost", className: "text-destructive", onClick: () => setTeVerwijderen(c.computer_naam), children: [_jsx(Trash2, { className: "mr-1 h-3.5 w-3.5" }), " Verwijderen"] })] }, c.id));
|
|
201
|
+
})) })] }), _jsx(ComputerVerwijderenDialog, { open: !!teVerwijderen, onOpenChange: (v) => !v && setTeVerwijderen(null), computerNaam: teVerwijderen, printplekId: plekId, printers: teVerwijderenPrinters, andereplekken: andereplekken, onKlaar: () => {
|
|
202
|
+
void herlaadComputers(true);
|
|
203
|
+
void vernieuw();
|
|
204
|
+
} }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [_jsx(Printer, { className: "h-4 w-4" }), " Printers op deze plek"] }), _jsx(CardDescription, { children: "Gegroepeerd per computer waaraan de printer volgens de live scan hangt." })] }), _jsxs(CardContent, { className: "space-y-4", children: [eigenPrinters.length === 0 ? (_jsxs("div", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(AlertTriangle, { className: "text-destructive h-4 w-4" }), "Nog geen printers gekoppeld aan deze plek."] })) : null, printersPerComputer.map((g) => g.printers.length ? (_jsxs("div", { className: "space-y-2", children: [_jsxs("p", { className: "text-muted-foreground flex items-center gap-2 text-xs font-medium", children: [_jsx(Monitor, { className: "h-3.5 w-3.5" }), " ", g.naam] }), g.printers.map((p) => _jsx(PrinterRij, { p: p }, p.id))] }, g.naam)) : null), nietGevonden.length > 0 ? (_jsxs("div", { className: "space-y-2", children: [_jsxs("p", { className: "text-muted-foreground flex items-center gap-2 text-xs font-medium", children: [_jsx(AlertTriangle, { className: "h-3.5 w-3.5" }), " Niet gevonden op een computer van deze plek"] }), nietGevonden.map((p) => _jsx(PrinterRij, { p: p }, p.id))] })) : null, nietToegewezen.length > 0 ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("select", { className: selectKlasse, value: toevoegen, onChange: (e) => setToevoegen(e.target.value), children: [_jsx("option", { value: "", children: "Printer toevoegen\u2026" }), nietToegewezen.map((p) => (_jsx("option", { value: p.id, children: p.naam }, p.id)))] }), _jsxs(Button, { size: "sm", disabled: !toevoegen, onClick: async () => {
|
|
83
205
|
try {
|
|
84
|
-
await
|
|
85
|
-
|
|
206
|
+
await wijsPrinterToeAanPrintplek(plekId, toevoegen);
|
|
207
|
+
setToevoegen("");
|
|
208
|
+
await vernieuw();
|
|
86
209
|
}
|
|
87
210
|
catch {
|
|
88
|
-
toast.error("
|
|
211
|
+
toast.error("Toevoegen mislukt");
|
|
89
212
|
}
|
|
90
|
-
}, children: "
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
213
|
+
}, children: [_jsx(Plus, { className: "mr-1 h-4 w-4" }), " Toevoegen"] })] })) : null, _jsx(PrinterVervangenDialog, { open: !!vervangen, onOpenChange: (v) => !v && setVervangen(null), printer: vervangen, printers: printers, onKlaar: () => void vernieuw() })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx(CardTitle, { className: "text-base", children: "Welk document gaat naar welke printer?" }), _jsx(CardDescription, { children: "Berekend met dezelfde routering als het echte printen. Kies een printer om voor deze plek een eigen regel te maken, of \"Standaard gebruiken\"." })] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setAlleDocumenten((v) => !v), children: alleDocumenten ? "Alleen met printer" : (_jsxs(_Fragment, { children: [_jsx(Plus, { className: "mr-1 h-4 w-4" }), " Alle documenten"] })) })] }), _jsxs(CardContent, { children: [routeringLaden ? _jsx("p", { className: "text-muted-foreground text-sm", children: "Routering berekenen\u2026" }) : null, !routeringLaden && routeringZichtbaar.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-sm", children: "Voor geen enkel document is een printer gevonden. Klik op \"Alle documenten\" om er een in te stellen." })) : null, routeringZichtbaar.length > 0 ? (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "text-muted-foreground border-b text-left text-xs", children: [_jsx("th", { className: "py-2 pr-3", children: "Document" }), _jsx("th", { className: "py-2 pr-3", children: "Formaat" }), _jsx("th", { className: "py-2 pr-3", children: "Winnende regel" }), _jsx("th", { className: "py-2 pr-3", children: "Printer" }), _jsx("th", { className: "py-2", children: "Printer op deze plek" })] }) }), _jsx("tbody", { children: routeringZichtbaar.flatMap((d) => {
|
|
214
|
+
const rijen = pcNamen.length ? pcNamen : [null];
|
|
215
|
+
const hoofd = uitkomstVoor(d.value, rijen[0]);
|
|
216
|
+
const afwijkend = rijen
|
|
217
|
+
.slice(1)
|
|
218
|
+
.map((pc) => ({ pc, u: uitkomstVoor(d.value, pc) }))
|
|
219
|
+
.filter((x) => x.u && (x.u.bron !== hoofd?.bron || x.u.printer_id !== hoofd?.printer_id));
|
|
220
|
+
const regel = eigenRegel(d.value);
|
|
221
|
+
return [
|
|
222
|
+
_jsxs("tr", { className: "border-b align-top", children: [_jsxs("td", { className: "py-2 pr-3 font-medium", children: [documentTypeLabel(d.value), pcNamen.length > 1 ? (_jsxs("div", { className: "text-muted-foreground text-xs font-normal", children: ["op ", rijen[0]] })) : null] }), _jsx(RouteringCellen, { u: hoofd }), _jsx("td", { className: "py-2", children: _jsxs("select", { className: selectKlasse, "aria-label": `Printer voor ${documentTypeLabel(d.value)}`, value: regel?.printer_id ?? "standaard", onChange: (e) => void zetRegel(d.value, e.target.value), children: [_jsx("option", { value: "standaard", children: "Standaard gebruiken" }), eigenPrinters.filter((p) => p.actief).map((p) => (_jsx("option", { value: p.id, children: p.naam }, p.id)))] }) })] }, d.value),
|
|
223
|
+
...afwijkend.map((x) => (_jsxs("tr", { className: "border-b align-top", children: [_jsxs("td", { className: "text-muted-foreground py-2 pr-3 pl-4 text-xs", children: ["op ", x.pc] }), _jsx(RouteringCellen, { u: x.u }), _jsx("td", {})] }, `${d.value}-${x.pc}`))),
|
|
224
|
+
];
|
|
225
|
+
}) })] }) })) : null] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [_jsx(Link2, { className: "h-4 w-4" }), " Gekoppeld aan"] }), _jsx(CardDescription, { children: "Andere modules (bijvoorbeeld pickstations) kunnen zich aan deze printplek koppelen." })] }), _jsxs(CardContent, { className: "space-y-4", children: [bronnen.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-sm", children: "Nog niets gekoppeld. Kies deze printplek in de andere module (bijvoorbeeld bij een pickstation); de koppeling verschijnt hier vanzelf." })) : (_jsx("div", { className: "space-y-2", children: bronnen.map((b) => (_jsxs("div", { className: "flex flex-wrap items-center gap-3 rounded-lg border px-3 py-2 text-sm", children: [_jsx(Badge, { variant: "secondary", children: b.bron }), _jsxs("span", { className: "min-w-0 flex-1 truncate", children: [b.label ?? b.bron_id, _jsx("span", { className: "text-muted-foreground ml-2 text-xs", children: b.bron_id })] }), _jsxs(Button, { variant: "ghost", size: "sm", onClick: () => void ontkoppel(b.bron, b.bron_id), children: [_jsx(X, { className: "mr-1 h-3.5 w-3.5" }), " Ontkoppelen"] })] }, b.id))) })), weeskoppelingen.length > 0 ? (_jsxs("div", { className: "space-y-2 rounded-lg border border-dashed p-3", children: [_jsxs("p", { className: "text-muted-foreground flex items-center gap-2 text-xs", children: [_jsx(AlertTriangle, { className: "h-3.5 w-3.5" }), " Koppelingen zonder bestaande printplek:"] }), weeskoppelingen.map((b) => (_jsxs("div", { className: "flex flex-wrap items-center gap-3 text-sm", children: [_jsx("span", { className: "min-w-0 flex-1 truncate", children: b.label ?? `${b.bron} ${b.bron_id}` }), _jsxs(Button, { variant: "ghost", size: "sm", onClick: () => void ontkoppel(b.bron, b.bron_id), children: [_jsx(Trash2, { className: "mr-1 h-3.5 w-3.5" }), " Opruimen"] })] }, b.id)))] })) : null] })] })] }));
|
|
99
226
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function PrintplekVerwijderenDialog({ plek, onOpenChange, onKlaar, }: {
|
|
2
|
+
plek: {
|
|
3
|
+
id: string;
|
|
4
|
+
naam: string;
|
|
5
|
+
} | null;
|
|
6
|
+
onOpenChange: (v: boolean) => void;
|
|
7
|
+
onKlaar: () => void;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=PrintplekVerwijderenDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrintplekVerwijderenDialog.d.ts","sourceRoot":"","sources":["../../src/components/PrintplekVerwijderenDialog.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,0BAA0B,CAAC,EACzC,IAAI,EACJ,YAAY,EACZ,OAAO,GACR,EAAE;IACD,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1C,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,+BAmEA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Bevestiging vóór het verwijderen van een hele printplek, met wat er verdwijnt.
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, toast, } from "@flowselections/core";
|
|
5
|
+
import { printplekVerwijderImpact, verwijderPrintplek, } from "../lib/printplekken.js";
|
|
6
|
+
export function PrintplekVerwijderenDialog({ plek, onOpenChange, onKlaar, }) {
|
|
7
|
+
const [impact, setImpact] = useState(null);
|
|
8
|
+
const [bezig, setBezig] = useState(false);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
setImpact(null);
|
|
11
|
+
if (plek)
|
|
12
|
+
void printplekVerwijderImpact(plek.id).then(setImpact).catch(() => setImpact(null));
|
|
13
|
+
}, [plek]);
|
|
14
|
+
const bevestig = async () => {
|
|
15
|
+
if (!plek)
|
|
16
|
+
return;
|
|
17
|
+
setBezig(true);
|
|
18
|
+
try {
|
|
19
|
+
await verwijderPrintplek(plek.id);
|
|
20
|
+
toast.success(`Printplek ${plek.naam} verwijderd`);
|
|
21
|
+
onOpenChange(false);
|
|
22
|
+
onKlaar();
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
toast.error("Verwijderen mislukt");
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
setBezig(false);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const pcs = impact?.computers ?? [];
|
|
32
|
+
const kop = impact?.koppelingen ?? [];
|
|
33
|
+
return (_jsx(Dialog, { open: plek !== null, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: ["Printplek ", plek?.naam, " verwijderen?"] }), _jsx(DialogDescription, { children: "Dit kan niet ongedaan worden gemaakt." })] }), !impact ? (_jsx("p", { className: "text-muted-foreground text-sm", children: "Laden\u2026" })) : (_jsxs("ul", { className: "list-disc space-y-1 pl-5 text-sm", children: [_jsxs("li", { children: [pcs.length, " computer", pcs.length === 1 ? "" : "s", " losgekoppeld", pcs.length ? ` (${pcs.join(", ")})` : "", " \u2014 ze komen terug onder \"Computers zonder printplek\"."] }), _jsxs("li", { children: [impact.regels, " documentregel", impact.regels === 1 ? "" : "s", " van deze plek verwijderd \u2014 die documenten gebruiken voortaan de bedrijfsbrede standaard."] }), _jsxs("li", { children: [impact.printers, " printer", impact.printers === 1 ? "" : "s", " ontkoppeld (de printers zelf blijven bestaan)."] }), kop.length > 0 && (_jsxs("li", { className: "text-destructive", children: ["Gekoppeld aan ", kop.join(", "), ": die schermen weten daarna niet meer naar welke plek ze printen."] }))] })), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Annuleren" }), _jsx(Button, { variant: "destructive", disabled: !impact || bezig, onClick: () => void bevestig(), children: "Definitief verwijderen" })] })] }) }));
|
|
34
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrintplekkenPage.d.ts","sourceRoot":"","sources":["../../src/components/PrintplekkenPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PrintplekkenPage.d.ts","sourceRoot":"","sources":["../../src/components/PrintplekkenPage.tsx"],"names":[],"mappings":"AAsDA,wBAAgB,gBAAgB,CAAC,EAAE,OAAe,EAAE,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,+BA6d/E"}
|
|
@@ -5,16 +5,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
// zodat instellen en monitoren op dezelfde plek gebeuren.
|
|
6
6
|
// ============================================================================
|
|
7
7
|
import { useMemo, useState } from "react";
|
|
8
|
-
import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@flowselections/core";
|
|
8
|
+
import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, toast, } from "@flowselections/core";
|
|
9
9
|
import { Link, useNavigate } from "@tanstack/react-router";
|
|
10
|
-
import { ChevronRight, MapPin, Monitor, Plus, Printer, Search, Wand2 } from "lucide-react";
|
|
11
|
-
import { koppelComputerAanPrintplek, usePrintplekken } from "../lib/printplekken.js";
|
|
10
|
+
import { ChevronRight, MapPin, Monitor, Plus, Printer, RotateCcw, Search, Trash2, Wand2, } from "lucide-react";
|
|
11
|
+
import { koppelComputerAanPrintplek, negeerComputer, useGenegeerdeComputers, usePrintplekken, zetComputerTerug, } from "../lib/printplekken.js";
|
|
12
12
|
import { usePrinters } from "../lib/useDocumentData.js";
|
|
13
13
|
import { useNetwerkPrinters } from "../lib/useNetwerkPrinters.js";
|
|
14
14
|
import { useComputers } from "./ComputersLijst.js";
|
|
15
15
|
import { ComputersLijst } from "./ComputersLijst.js";
|
|
16
16
|
import { telPrintersPerComputer } from "../lib/printerTelling.js";
|
|
17
17
|
import { PrintplekWizard } from "./PrintplekWizard.js";
|
|
18
|
+
import { PrintplekVerwijderenDialog } from "./PrintplekVerwijderenDialog.js";
|
|
18
19
|
import { TestprintDialog } from "./TestprintDialog.js";
|
|
19
20
|
import { PrintStatusBanner } from "./PrintStatusBanner.js";
|
|
20
21
|
import { bijgewerktTekst, useAutoRefresh } from "../lib/useAutoRefresh.js";
|
|
@@ -24,11 +25,14 @@ export function PrintplekkenPage({ ingebed = false } = {}) {
|
|
|
24
25
|
const { computers, loading: computersLaden, fout: computersFout, reload: herlaadComputers, } = useComputers();
|
|
25
26
|
const { printers, reload: herlaadPrinters } = usePrinters();
|
|
26
27
|
const { gevonden, zoek } = useNetwerkPrinters();
|
|
28
|
+
const { genegeerd, reload: herlaadGenegeerd } = useGenegeerdeComputers();
|
|
27
29
|
const navigate = useNavigate();
|
|
30
|
+
const [teVerwijderen, setTeVerwijderen] = useState(null);
|
|
28
31
|
const [zoekterm, setZoekterm] = useState("");
|
|
29
32
|
const [wizardOpen, setWizardOpen] = useState(false);
|
|
30
33
|
const [testprint, setTestprint] = useState(null);
|
|
31
34
|
const [computerToevoegen, setComputerToevoegen] = useState(false);
|
|
35
|
+
const [toonGenegeerd, setToonGenegeerd] = useState(false);
|
|
32
36
|
const bijgewerkt = useAutoRefresh(async () => {
|
|
33
37
|
await Promise.all([reload(true), herlaadComputers(true), herlaadPrinters(true), zoek()]);
|
|
34
38
|
}, 10000, computerToevoegen || wizardOpen);
|
|
@@ -97,14 +101,32 @@ export function PrintplekkenPage({ ingebed = false } = {}) {
|
|
|
97
101
|
const Wrapper = ingebed ? "div" : "main";
|
|
98
102
|
return (_jsxs(Wrapper, { className: ingebed ? "space-y-6" : "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-end justify-between gap-4", children: [!ingebed && (_jsxs("div", { children: [_jsx("h1", { className: "text-xl font-semibold", children: "Printplekken" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Een printplek is een fysieke plek in het bedrijf, bijvoorbeeld een pickstation. Alle computers en printers op die plek horen bij elkaar." })] })), _jsxs("div", { className: "ml-auto flex items-center gap-2", children: [_jsxs(Button, { variant: "outline", onClick: () => setComputerToevoegen(true), children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), " Computer aanmelden"] }), _jsxs(Button, { onClick: () => setWizardOpen(true), children: [_jsx(Wand2, { className: "mr-2 h-4 w-4" }), " Printplek instellen"] })] })] }), _jsx(PrintStatusBanner, { fout: computersFout, offlineWerkplekken: computers.filter((c) => !c.online).map((c) => c.naam), toonWerkplekLink: false }), fout ? (_jsx("div", { className: "border-destructive/40 bg-destructive/10 text-destructive rounded-xl border p-3 text-sm", children: fout })) : null, _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 printplek of computer\u2026", value: zoekterm, onChange: (e) => setZoekterm(e.target.value) })] }), _jsxs("span", { className: "text-muted-foreground text-sm", children: [plekken.length, " plek", plekken.length === 1 ? "" : "ken", " \u00B7 ", computers.length, " computer", computers.length === 1 ? "" : "s", " (", computersOnline, " aan) \u00B7 ", totaalPrinters, " printer", totaalPrinters === 1 ? "" : "s"] }), _jsx("span", { className: "text-muted-foreground ml-auto text-xs", children: bijgewerktTekst(bijgewerkt) })] }), kaarten.length === 0 ? (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: plekken.length === 0 ? "Nog geen printplekken" : "Geen resultaten" }), _jsx(CardDescription, { children: plekken.length === 0
|
|
99
103
|
? 'Maak er één aan per plek waar geprint wordt, bijvoorbeeld "Pickstation 1".'
|
|
100
|
-
: "Geen printplek of computer gevonden met deze zoekterm." })] }), _jsx(CardContent, { className: "flex flex-wrap gap-2", children: _jsxs(Button, { onClick: () => setWizardOpen(true), children: [_jsx(Wand2, { className: "mr-2 h-4 w-4" }), " Printplek instellen"] }) })] })) : (_jsx("div", { className: "grid gap-4 xl:grid-cols-2", children: kaarten.map((k) => (_jsxs("div", { className: "rounded-xl border p-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(MapPin, { className: "text-muted-foreground h-4 w-4" }), _jsx("span", { className: "truncate font-medium", children: k.plek.naam }), _jsx("span", { className: `h-2.5 w-2.5 shrink-0 rounded-full ${k.klaar ? "bg-emerald-500" : "bg-destructive"}`, "aria-label": k.klaar ? "Klaar om te printen" : "Nog niet compleet" })] }), k.plek.omschrijving ? (_jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: k.plek.omschrijving })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-3", children: [_jsxs("button", { type: "button", className: "text-primary flex items-center text-xs", onClick: () => setTestprint({ id: k.plek.id, naam: k.plek.naam }), children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), " Testprint"] }), _jsxs(Link, { to: "/layouts-printers/printplekken/$printplekId", params: { printplekId: k.plek.id }, className: "text-primary flex items-center text-xs", children: ["Instellen ", _jsx(ChevronRight, { className: "ml-1 h-3.5 w-3.5" })] })] })] }), _jsx("div", { className: "mt-3 space-y-2", children: k.computerLijst.length === 0 ? (_jsxs("div", { className: "text-muted-foreground flex flex-wrap items-center gap-2 rounded-lg border border-dashed p-3 text-sm", children: ["Nog geen computer gekoppeld", nietGekoppeld.length > 0 ? (_jsxs(Select, { onValueChange: (naam) => void koppel(k.plek.id, naam), children: [_jsx(SelectTrigger, { className: "h-8 w-[190px]", children: _jsx(SelectValue, { placeholder: "Computer koppelen" }) }), _jsx(SelectContent, { children: nietGekoppeld.map((c) => (_jsx(SelectItem, { value: c.naam, children: c.naam }, c.id))) })] })) : (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setComputerToevoegen(true), children: "Computer aanmelden" }))] })) : (k.computerLijst.map((c) => (_jsxs("div", { className: "bg-muted/40 flex flex-wrap items-center gap-3 rounded-lg px-3 py-2 text-sm", children: [_jsx(Monitor, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: c.naam }), _jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${c.online ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground"}`, children: c.aangemeld ? (c.online ? "Aan" : "Uit") : "Niet aangemeld" }), _jsxs("span", { className: "text-muted-foreground text-xs", children: [c.ingesteld, " printer", c.ingesteld === 1 ? "" : "s", " \u00B7 ", c.gevonden, " gevonden"] }), _jsx(Button, { variant: "ghost", size: "sm", disabled: !c.id, onClick: () => naarComputer(c.id), children: "Printers toevoegen" })] }, c.koppelingId)))) }), _jsxs("div", { className: "text-muted-foreground mt-3 flex items-start gap-2 text-xs", children: [_jsx(Printer, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }), _jsx("span", { children: k.documentRegels.length === 0
|
|
104
|
+
: "Geen printplek of computer gevonden met deze zoekterm." })] }), _jsx(CardContent, { className: "flex flex-wrap gap-2", children: _jsxs(Button, { onClick: () => setWizardOpen(true), children: [_jsx(Wand2, { className: "mr-2 h-4 w-4" }), " Printplek instellen"] }) })] })) : (_jsx("div", { className: "grid gap-4 xl:grid-cols-2", children: kaarten.map((k) => (_jsxs("div", { className: "rounded-xl border p-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(MapPin, { className: "text-muted-foreground h-4 w-4" }), _jsx("span", { className: "truncate font-medium", children: k.plek.naam }), _jsx("span", { className: `h-2.5 w-2.5 shrink-0 rounded-full ${k.klaar ? "bg-emerald-500" : "bg-destructive"}`, "aria-label": k.klaar ? "Klaar om te printen" : "Nog niet compleet" })] }), k.plek.omschrijving ? (_jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: k.plek.omschrijving })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-3", children: [_jsxs("button", { type: "button", className: "text-primary flex items-center text-xs", onClick: () => setTestprint({ id: k.plek.id, naam: k.plek.naam }), children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), " Testprint"] }), _jsxs("button", { type: "button", className: "text-destructive flex items-center text-xs", onClick: () => setTeVerwijderen({ id: k.plek.id, naam: k.plek.naam }), children: [_jsx(Trash2, { className: "mr-1 h-3.5 w-3.5" }), " Verwijderen"] }), _jsxs(Link, { to: "/layouts-printers/printplekken/$printplekId", params: { printplekId: k.plek.id }, className: "text-primary flex items-center text-xs", children: ["Instellen ", _jsx(ChevronRight, { className: "ml-1 h-3.5 w-3.5" })] })] })] }), _jsx("div", { className: "mt-3 space-y-2", children: k.computerLijst.length === 0 ? (_jsxs("div", { className: "text-muted-foreground flex flex-wrap items-center gap-2 rounded-lg border border-dashed p-3 text-sm", children: ["Nog geen computer gekoppeld", nietGekoppeld.length > 0 ? (_jsxs(Select, { onValueChange: (naam) => void koppel(k.plek.id, naam), children: [_jsx(SelectTrigger, { className: "h-8 w-[190px]", children: _jsx(SelectValue, { placeholder: "Computer koppelen" }) }), _jsx(SelectContent, { children: nietGekoppeld.map((c) => (_jsx(SelectItem, { value: c.naam, children: c.naam }, c.id))) })] })) : (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setComputerToevoegen(true), children: "Computer aanmelden" }))] })) : (k.computerLijst.map((c) => (_jsxs("div", { className: "bg-muted/40 flex flex-wrap items-center gap-3 rounded-lg px-3 py-2 text-sm", children: [_jsx(Monitor, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: c.naam }), _jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${c.online ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground"}`, children: c.aangemeld ? (c.online ? "Aan" : "Uit") : "Niet aangemeld" }), _jsxs("span", { className: "text-muted-foreground text-xs", children: [c.ingesteld, " printer", c.ingesteld === 1 ? "" : "s", " \u00B7 ", c.gevonden, " gevonden"] }), _jsx(Button, { variant: "ghost", size: "sm", disabled: !c.id, onClick: () => naarComputer(c.id), children: "Printers toevoegen" })] }, c.koppelingId)))) }), _jsxs("div", { className: "text-muted-foreground mt-3 flex items-start gap-2 text-xs", children: [_jsx(Printer, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }), _jsx("span", { children: k.documentRegels.length === 0
|
|
101
105
|
? "Nog geen document aan een printer gekoppeld"
|
|
102
106
|
: k.documentRegels
|
|
103
107
|
.map((r) => `${documentTypeLabel(r.documenttype)} → ${printerNaam.get(r.printer_id ?? "") ?? "onbekende printer"}`)
|
|
104
108
|
.join(" · ") })] }), k.bronnen.length > 0 ? (_jsx("div", { className: "mt-3 flex flex-wrap gap-1", children: Array.from(new Set(k.bronnen.map((b) => b.bron))).map((bron) => (_jsxs(Badge, { variant: "secondary", children: [k.bronnen.filter((b) => b.bron === bron).length, "\u00D7 ", bron] }, bron))) })) : null] }, k.plek.id))) })), nietGekoppeld.length > 0 ? (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs(CardTitle, { className: "text-base", children: ["Computers zonder printplek (", nietGekoppeld.length, ")"] }), _jsx(CardDescription, { children: "Deze computers zijn aangemeld maar horen nog nergens bij. Kies hieronder waar ze staan." })] }), _jsx(CardContent, { className: "space-y-2", children: nietGekoppeld.map((c) => {
|
|
105
109
|
const info = perComputer.get(c.naam);
|
|
106
|
-
return (_jsxs("div", { className: "flex flex-wrap items-center gap-3 rounded-lg border px-3 py-2 text-sm", children: [_jsx(Monitor, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: c.naam }), _jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${c.online ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground"}`, children: c.online ? "Aan" : "Uit" }), _jsxs("span", { className: "text-muted-foreground text-xs", children: [info?.gevonden ?? c.aantalGevonden, " printers gevonden"] }), plekken.length > 0 ? (_jsxs(Select, { onValueChange: (plekId) => void koppel(plekId, c.naam), children: [_jsx(SelectTrigger, { className: "h-8 w-[170px]", children: _jsx(SelectValue, { placeholder: "Plek kiezen" }) }), _jsx(SelectContent, { children: plekken.map((p) => (_jsx(SelectItem, { value: p.id, children: p.naam }, p.id))) })] })) : (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setWizardOpen(true), children: "Printplek maken" }))
|
|
107
|
-
|
|
110
|
+
return (_jsxs("div", { className: "flex flex-wrap items-center gap-3 rounded-lg border px-3 py-2 text-sm", children: [_jsx(Monitor, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: c.naam }), _jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${c.online ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground"}`, children: c.online ? "Aan" : "Uit" }), _jsxs("span", { className: "text-muted-foreground text-xs", children: [info?.gevonden ?? c.aantalGevonden, " printers gevonden"] }), plekken.length > 0 ? (_jsxs(Select, { onValueChange: (plekId) => void koppel(plekId, c.naam), children: [_jsx(SelectTrigger, { className: "h-8 w-[170px]", children: _jsx(SelectValue, { placeholder: "Plek kiezen" }) }), _jsx(SelectContent, { children: plekken.map((p) => (_jsx(SelectItem, { value: p.id, children: p.naam }, p.id))) })] })) : (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setWizardOpen(true), children: "Printplek maken" })), _jsxs(Button, { variant: "ghost", size: "sm", className: "text-destructive", onClick: async () => {
|
|
111
|
+
try {
|
|
112
|
+
await negeerComputer(c.naam, null);
|
|
113
|
+
await Promise.all([herlaadComputers(true), herlaadGenegeerd()]);
|
|
114
|
+
toast.success(`${c.naam} verwijderd`);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
toast.error("Verwijderen mislukt");
|
|
118
|
+
}
|
|
119
|
+
}, children: [_jsx(Trash2, { className: "mr-1 h-3.5 w-3.5" }), " Verwijderen"] })] }, c.id));
|
|
120
|
+
}) })] })) : null, genegeerd.length > 0 ? (_jsxs("div", { className: "space-y-2", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setToonGenegeerd((v) => !v), children: [toonGenegeerd ? "Verberg" : "Toon", " genegeerde computers (", genegeerd.length, ")"] }), toonGenegeerd ? (_jsx(Card, { children: _jsx(CardContent, { className: "space-y-2 py-4", children: genegeerd.map((g) => (_jsxs("div", { className: "flex flex-wrap items-center gap-3 rounded-lg border px-3 py-2 text-sm", children: [_jsx(Monitor, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: g.computer_naam }), _jsxs("span", { className: "text-muted-foreground text-xs", children: ["verwijderd op ", new Date(g.genegeerd_op).toLocaleString("nl-NL")] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: async () => {
|
|
121
|
+
try {
|
|
122
|
+
await zetComputerTerug(g.computer_naam);
|
|
123
|
+
await Promise.all([herlaadComputers(true), herlaadGenegeerd()]);
|
|
124
|
+
toast.success(`${g.computer_naam} teruggezet`);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
toast.error("Terugzetten mislukt");
|
|
128
|
+
}
|
|
129
|
+
}, children: [_jsx(RotateCcw, { className: "mr-1 h-3.5 w-3.5" }), " Terugzetten"] })] }, g.id))) }) })) : null] })) : null, !computersLaden && computers.length === 0 && plekken.length === 0 ? (_jsx(Card, { children: _jsxs(CardContent, { className: "space-y-3 py-6 text-sm", children: [_jsx("p", { className: "font-medium", children: "Nog geen computer aangemeld" }), _jsx("p", { className: "text-muted-foreground", children: "Installeer het printprogramma op de computer waar de printers aan hangen. Zodra die zich meldt, verschijnt hij hier." }), _jsxs(Button, { onClick: () => setComputerToevoegen(true), children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), " Computer aanmelden"] })] }) })) : null, _jsx(PrintplekVerwijderenDialog, { plek: teVerwijderen, onOpenChange: (v) => !v && setTeVerwijderen(null), onKlaar: () => vernieuwAlles() }), _jsx(PrintplekWizard, { open: wizardOpen, onOpenChange: setWizardOpen, onKlaar: () => vernieuwAlles() }), _jsx(TestprintDialog, { open: testprint !== null, onOpenChange: (v) => !v && setTestprint(null), printplekId: testprint?.id ?? null, printplekNaam: testprint?.naam ?? null }), _jsx(ComputersLijst, { computers: computers, loading: false, fout: null, onVernieuw: () => {
|
|
108
130
|
void herlaadComputers();
|
|
109
131
|
void zoek();
|
|
110
132
|
}, onPrintersToevoegen: (naam) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WerkplekConfiguratiePage.d.ts","sourceRoot":"","sources":["../../src/components/WerkplekConfiguratiePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WerkplekConfiguratiePage.d.ts","sourceRoot":"","sources":["../../src/components/WerkplekConfiguratiePage.tsx"],"names":[],"mappings":"AA2CA,wBAAgB,wBAAwB,gCAkXvC"}
|