@flowselections/floriday-voorraad 1.0.147 → 1.0.150
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/voorraad/EditArtikelPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/EditArtikelPage.js +13 -20
- package/dist-lib/components/voorraad/OrderHistoryCard.d.ts +3 -1
- package/dist-lib/components/voorraad/OrderHistoryCard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/OrderHistoryCard.js +7 -3
- package/dist-lib/components/voorraad/ProductCustomFieldsCard.d.ts +5 -1
- package/dist-lib/components/voorraad/ProductCustomFieldsCard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ProductCustomFieldsCard.js +9 -6
- package/dist-lib/components/voorraad/ProductSalePriceField.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ProductSalePriceField.js +2 -0
- package/dist-lib/components/voorraad/StockMutationHistoryCard.d.ts +3 -1
- package/dist-lib/components/voorraad/StockMutationHistoryCard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/StockMutationHistoryCard.js +16 -10
- package/dist-lib/components/voorraad/VoorraadBeheerCard.d.ts +3 -0
- package/dist-lib/components/voorraad/VoorraadBeheerCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/VoorraadBeheerCard.js +44 -0
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.d.ts +2 -1
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.d.ts.map +1 -1
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.js +60 -10
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.d.ts.map +1 -1
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.js +5 -4
- package/dist-lib/hooks/useVoorraadCustomFields.d.ts +2 -1
- package/dist-lib/hooks/useVoorraadCustomFields.d.ts.map +1 -1
- package/dist-lib/hooks/useVoorraadCustomFields.js +8 -4
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +2 -0
- package/dist-lib/integrations/supabase/types.d.ts +283 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/artikel-gewijzigd.d.ts +4 -0
- package/dist-lib/lib/artikel-gewijzigd.d.ts.map +1 -0
- package/dist-lib/lib/artikel-gewijzigd.js +7 -0
- package/dist-lib/lib/artikel-pagina.d.ts +14 -3
- package/dist-lib/lib/artikel-pagina.d.ts.map +1 -1
- package/dist-lib/lib/artikel-pagina.js +5 -1
- package/dist-lib/lib/floriday-versie-ronde.d.ts +59 -0
- package/dist-lib/lib/floriday-versie-ronde.d.ts.map +1 -0
- package/dist-lib/lib/floriday-versie-ronde.functions.d.ts +10 -0
- package/dist-lib/lib/floriday-versie-ronde.functions.d.ts.map +1 -0
- package/dist-lib/lib/floriday-versie-ronde.functions.js +22 -0
- package/dist-lib/lib/floriday-versie-ronde.js +106 -0
- package/dist-lib/lib/voorraad-lijst.d.ts +3 -2
- package/dist-lib/lib/voorraad-lijst.d.ts.map +1 -1
- package/dist-lib/lib/voorraad-lijst.js +6 -2
- package/dist-lib/server-hooks/floriday-stock-reconcile.d.ts.map +1 -1
- package/dist-lib/server-hooks/floriday-stock-reconcile.js +5 -0
- package/dist-lib/server-hooks/floriday-versieronde.d.ts +2 -0
- package/dist-lib/server-hooks/floriday-versieronde.d.ts.map +1 -0
- package/dist-lib/server-hooks/floriday-versieronde.js +29 -0
- package/dist-lib/server-hooks/guard.js +1 -1
- package/package.json +1 -1
- package/sql/AGENTS.md +2 -0
- package/sql/floriday-voorraad-schema.sql +638 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditArtikelPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/EditArtikelPage.tsx"],"names":[],"mappings":"AAYA,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,WAAW,GACZ,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,+
|
|
1
|
+
{"version":3,"file":"EditArtikelPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/EditArtikelPage.tsx"],"names":[],"mappings":"AAYA,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,WAAW,GACZ,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,+BAqEA"}
|
|
@@ -1,29 +1,22 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
3
|
import { Card } from "@flowselections/core";
|
|
4
4
|
import { Loader2 } from "lucide-react";
|
|
5
5
|
import { ArtikelWizard } from "./ArtikelWizard.js";
|
|
6
6
|
import { ArtikelPagina } from "./artikel/ArtikelPagina.js";
|
|
7
7
|
import { supabase } from "../../integrations/supabase/client.js";
|
|
8
8
|
export function EditArtikelPage({ id, resumeJobId, }) {
|
|
9
|
-
|
|
9
|
+
// Eerst direct de artikelpagina (één aanvraag); alleen als het id geen artikel is, zoeken we verder.
|
|
10
|
+
const [resolved, setResolved] = useState({ kind: "product", id });
|
|
11
|
+
const [zoekVerder, setZoekVerder] = useState(false);
|
|
12
|
+
useEffect(() => { setResolved({ kind: "product", id }); setZoekVerder(false); }, [id]);
|
|
13
|
+
const nietGevonden = useCallback(() => { setResolved(null); setZoekVerder(true); }, []);
|
|
10
14
|
useEffect(() => {
|
|
15
|
+
if (!zoekVerder)
|
|
16
|
+
return;
|
|
11
17
|
let cancelled = false;
|
|
12
|
-
setResolved(null);
|
|
13
18
|
(async () => {
|
|
14
|
-
//
|
|
15
|
-
const prodRes = await supabase
|
|
16
|
-
.from("products")
|
|
17
|
-
.select("id")
|
|
18
|
-
.eq("id", id)
|
|
19
|
-
.maybeSingle();
|
|
20
|
-
if (cancelled)
|
|
21
|
-
return;
|
|
22
|
-
if (prodRes.data) {
|
|
23
|
-
setResolved({ kind: "product", id });
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
// 2. Product met dit Floriday-artikel-ID.
|
|
19
|
+
// Product met dit Floriday-artikel-ID.
|
|
27
20
|
const byFloriday = await supabase
|
|
28
21
|
.from("products")
|
|
29
22
|
.select("id")
|
|
@@ -31,11 +24,11 @@ export function EditArtikelPage({ id, resumeJobId, }) {
|
|
|
31
24
|
.maybeSingle();
|
|
32
25
|
if (cancelled)
|
|
33
26
|
return;
|
|
34
|
-
if (byFloriday.data?.id) {
|
|
27
|
+
if (byFloriday.data?.id && byFloriday.data.id !== id) {
|
|
35
28
|
setResolved({ kind: "product", id: byFloriday.data.id });
|
|
36
29
|
return;
|
|
37
30
|
}
|
|
38
|
-
//
|
|
31
|
+
// Alleen nog in de Floriday-cache aanwezig (nog niet lokaal gespiegeld).
|
|
39
32
|
const pubRes = await supabase
|
|
40
33
|
.from("floriday_trade_items_cache")
|
|
41
34
|
.select("floriday_id")
|
|
@@ -55,7 +48,7 @@ export function EditArtikelPage({ id, resumeJobId, }) {
|
|
|
55
48
|
return () => {
|
|
56
49
|
cancelled = true;
|
|
57
50
|
};
|
|
58
|
-
}, [id]);
|
|
51
|
+
}, [id, zoekVerder]);
|
|
59
52
|
if (!resolved) {
|
|
60
53
|
return (_jsx("main", { className: "p-6", children: _jsxs(Card, { className: "p-6 flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), "Artikel laden\u2026"] }) }));
|
|
61
54
|
}
|
|
@@ -63,7 +56,7 @@ export function EditArtikelPage({ id, resumeJobId, }) {
|
|
|
63
56
|
return (_jsx("main", { className: "p-6", children: _jsxs(Card, { className: "p-6 text-sm space-y-1", children: [_jsx("div", { children: "Artikel niet gevonden." }), resolved.reason && (_jsx("div", { className: "text-muted-foreground", children: resolved.reason }))] }) }));
|
|
64
57
|
}
|
|
65
58
|
if (resolved.kind === "product") {
|
|
66
|
-
return _jsx(ArtikelPagina, { id: resolved.id, resumeJobId: resumeJobId });
|
|
59
|
+
return _jsx(ArtikelPagina, { id: resolved.id, resumeJobId: resumeJobId, onNietGevonden: resolved.id === id && !zoekVerder ? nietGevonden : undefined }, resolved.id);
|
|
67
60
|
}
|
|
68
61
|
return _jsx(ArtikelWizard, { tradeItemId: resolved.id, resumeJobId: resumeJobId });
|
|
69
62
|
}
|
|
@@ -2,7 +2,9 @@ interface Props {
|
|
|
2
2
|
tradeItemKey: string | null;
|
|
3
3
|
productName: string | null;
|
|
4
4
|
productId?: string | null;
|
|
5
|
+
/** Artikelen met dezelfde voorraadsleutel, uit voorraad_artikel_detail. */
|
|
6
|
+
productIds?: string[];
|
|
5
7
|
}
|
|
6
|
-
export declare function OrderHistoryCard({ tradeItemKey, productName, productId }: Props): import("react").JSX.Element;
|
|
8
|
+
export declare function OrderHistoryCard({ tradeItemKey, productName, productId, productIds: bekendeIds }: Props): import("react").JSX.Element;
|
|
7
9
|
export {};
|
|
8
10
|
//# sourceMappingURL=OrderHistoryCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrderHistoryCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/OrderHistoryCard.tsx"],"names":[],"mappings":"AAKA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"OrderHistoryCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/OrderHistoryCard.tsx"],"names":[],"mappings":"AAKA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAgDD,wBAAgB,gBAAgB,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,KAAK,+BAsKvG"}
|
|
@@ -43,7 +43,7 @@ function formatDate(v) {
|
|
|
43
43
|
return v;
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
export function OrderHistoryCard({ tradeItemKey, productName, productId }) {
|
|
46
|
+
export function OrderHistoryCard({ tradeItemKey, productName, productId, productIds: bekendeIds }) {
|
|
47
47
|
const [rows, setRows] = useState(null);
|
|
48
48
|
const [error, setError] = useState(null);
|
|
49
49
|
useEffect(() => {
|
|
@@ -55,7 +55,11 @@ export function OrderHistoryCard({ tradeItemKey, productName, productId }) {
|
|
|
55
55
|
const productIds = new Set();
|
|
56
56
|
if (productId)
|
|
57
57
|
productIds.add(productId);
|
|
58
|
-
if (
|
|
58
|
+
if (bekendeIds) {
|
|
59
|
+
for (const p of bekendeIds)
|
|
60
|
+
productIds.add(p);
|
|
61
|
+
}
|
|
62
|
+
else if (tradeItemKey) {
|
|
59
63
|
const { data: prods } = await supabase
|
|
60
64
|
.from("products")
|
|
61
65
|
.select("id")
|
|
@@ -122,7 +126,7 @@ export function OrderHistoryCard({ tradeItemKey, productName, productId }) {
|
|
|
122
126
|
cancelled = true;
|
|
123
127
|
supabase.removeChannel(channel);
|
|
124
128
|
};
|
|
125
|
-
}, [tradeItemKey, productName, productId]);
|
|
129
|
+
}, [tradeItemKey, productName, productId, bekendeIds?.join("|")]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
126
130
|
return (_jsxs(Card, { children: [_jsxs("div", { className: "grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 px-6 py-4", children: [_jsx("span", { className: "flex h-7 w-7 items-center justify-center rounded-full border border-primary/40 bg-primary/10 text-primary", children: _jsx(ClipboardList, { className: "h-4 w-4" }) }), _jsx("span", { className: "font-medium", children: "Bestelgeschiedenis" }), _jsx("span", { className: "text-xs text-muted-foreground tabular-nums", children: rows ? `${rows.length} bestelling${rows.length === 1 ? "" : "en"}` : "" })] }), _jsxs(CardContent, { className: "pt-0", children: [error && (_jsxs("div", { className: "text-sm text-destructive", children: ["Kon bestelgeschiedenis niet laden: ", error] })), !rows && !error && (_jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Bestellingen laden\u2026"] })), rows && rows.length === 0 && !error && (_jsx("div", { className: "text-sm text-muted-foreground", children: "Nog geen bestellingen voor dit artikel." })), rows && rows.length > 0 && (_jsx("div", { className: "overflow-x-auto rounded-md border", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-muted/50 text-xs uppercase text-muted-foreground", children: _jsxs("tr", { children: [_jsx("th", { className: "px-3 py-2 text-left", children: "Ordernummer" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Klant" }), _jsx("th", { className: "px-3 py-2 text-right", children: "Fusten" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Besteldatum" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Status" }), _jsx("th", { className: "px-3 py-2" })] }) }), _jsx("tbody", { children: rows.map((r, i) => {
|
|
127
131
|
const label = normalizeStatus(r.status);
|
|
128
132
|
const tone = STATUS_TONE[label.toLowerCase()] ??
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { type VoorraadCustomField } from "../../lib/voorraad-custom-fields.js";
|
|
1
2
|
/** Eigen voorraadvelden met `show_in_detail`, tonen en bewerken op de productpagina. */
|
|
2
|
-
export declare function ProductCustomFieldsCard({ productId }: {
|
|
3
|
+
export declare function ProductCustomFieldsCard({ productId, beginVelden, beginWaarden, }: {
|
|
3
4
|
productId: string;
|
|
5
|
+
/** Uit voorraad_artikel_detail: scheelt twee aanvragen bij het openen. */
|
|
6
|
+
beginVelden?: VoorraadCustomField[];
|
|
7
|
+
beginWaarden?: Record<string, unknown>;
|
|
4
8
|
}): import("react").JSX.Element | null;
|
|
5
9
|
//# sourceMappingURL=ProductCustomFieldsCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductCustomFieldsCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ProductCustomFieldsCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductCustomFieldsCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ProductCustomFieldsCard.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,kCAAkC,CAAC;AAE1C,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,WAAW,EACX,YAAY,GACb,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,sCAmJA"}
|
|
@@ -5,13 +5,16 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle, Checkbox, In
|
|
|
5
5
|
import { useVoorraadCustomFields } from "../../hooks/useVoorraadCustomFields.js";
|
|
6
6
|
import { fetchProductCustomValues, saveProductCustomValues, } from "../../lib/voorraad-custom-fields.js";
|
|
7
7
|
/** Eigen voorraadvelden met `show_in_detail`, tonen en bewerken op de productpagina. */
|
|
8
|
-
export function ProductCustomFieldsCard({ productId }) {
|
|
9
|
-
const { fields, loading } = useVoorraadCustomFields();
|
|
10
|
-
const [values, setValues] = useState({});
|
|
11
|
-
const [opened, setOpened] = useState({});
|
|
12
|
-
const [loadingValues, setLoadingValues] = useState(
|
|
8
|
+
export function ProductCustomFieldsCard({ productId, beginVelden, beginWaarden, }) {
|
|
9
|
+
const { fields, loading } = useVoorraadCustomFields(beginVelden?.map((f) => ({ ...f, options: Array.isArray(f.options) ? f.options : [] })));
|
|
10
|
+
const [values, setValues] = useState(beginWaarden ?? {});
|
|
11
|
+
const [opened, setOpened] = useState(beginWaarden ?? {});
|
|
12
|
+
const [loadingValues, setLoadingValues] = useState(!beginWaarden);
|
|
13
|
+
const heeftBegin = Boolean(beginWaarden);
|
|
13
14
|
const [saving, setSaving] = useState(false);
|
|
14
15
|
useEffect(() => {
|
|
16
|
+
if (heeftBegin)
|
|
17
|
+
return;
|
|
15
18
|
let cancelled = false;
|
|
16
19
|
setLoadingValues(true);
|
|
17
20
|
fetchProductCustomValues(productId)
|
|
@@ -34,7 +37,7 @@ export function ProductCustomFieldsCard({ productId }) {
|
|
|
34
37
|
return () => {
|
|
35
38
|
cancelled = true;
|
|
36
39
|
};
|
|
37
|
-
}, [productId]);
|
|
40
|
+
}, [productId, heeftBegin]);
|
|
38
41
|
const detailFields = fields.filter((f) => f.show_in_detail);
|
|
39
42
|
const set = (key, value) => setValues((prev) => ({ ...prev, [key]: value }));
|
|
40
43
|
const gewijzigd = detailFields.filter((f) => JSON.stringify(values[f.field_key] ?? null) !== JSON.stringify(opened[f.field_key] ?? null));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductSalePriceField.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ProductSalePriceField.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductSalePriceField.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ProductSalePriceField.tsx"],"names":[],"mappings":"AAoBA,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,sCAqGA;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,sCAqCtE"}
|
|
@@ -12,6 +12,7 @@ import { Button, Input, Label, toast } from "@flowselections/core";
|
|
|
12
12
|
import { AlertTriangle, Loader2 } from "lucide-react";
|
|
13
13
|
import { supabase } from "../../integrations/supabase/client.js";
|
|
14
14
|
import { priceProblem } from "../../lib/floriday-base-supply.js";
|
|
15
|
+
import { meldArtikelGewijzigd } from "../../lib/artikel-gewijzigd.js";
|
|
15
16
|
function isPieceUnit(unit) {
|
|
16
17
|
const u = String(unit ?? "").trim().toLowerCase();
|
|
17
18
|
return u === "" || u === "stuks" || u === "stuk";
|
|
@@ -70,6 +71,7 @@ export function ProductSalePriceField({ productId, onSaved, }) {
|
|
|
70
71
|
}
|
|
71
72
|
setSaved(parsed);
|
|
72
73
|
onSaved?.(parsed);
|
|
74
|
+
meldArtikelGewijzigd(productId);
|
|
73
75
|
toast.success("Prijs opgeslagen (alleen lokaal).");
|
|
74
76
|
}
|
|
75
77
|
catch (e) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
interface Props {
|
|
2
2
|
tradeItemKey: string | null;
|
|
3
3
|
productId?: string | null;
|
|
4
|
+
/** Sleutels uit voorraad_artikel_detail; scheelt een aparte aanvraag bij het openen. */
|
|
5
|
+
sleutels?: string[];
|
|
4
6
|
}
|
|
5
|
-
export declare function StockMutationHistoryCard({ tradeItemKey, productId }: Props): import("react").JSX.Element;
|
|
7
|
+
export declare function StockMutationHistoryCard({ tradeItemKey, productId, sleutels }: Props): import("react").JSX.Element;
|
|
6
8
|
export {};
|
|
7
9
|
//# sourceMappingURL=StockMutationHistoryCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StockMutationHistoryCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/StockMutationHistoryCard.tsx"],"names":[],"mappings":"AAYA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"StockMutationHistoryCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/StockMutationHistoryCard.tsx"],"names":[],"mappings":"AAYA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAiDD,wBAAgB,wBAAwB,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,KAAK,+BAgPpF"}
|
|
@@ -42,7 +42,7 @@ function formatMoment(v) {
|
|
|
42
42
|
return v;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
export function StockMutationHistoryCard({ tradeItemKey, productId }) {
|
|
45
|
+
export function StockMutationHistoryCard({ tradeItemKey, productId, sleutels }) {
|
|
46
46
|
const [rows, setRows] = useState(null);
|
|
47
47
|
const [error, setError] = useState(null);
|
|
48
48
|
const [expanded, setExpanded] = useState(false);
|
|
@@ -60,14 +60,20 @@ export function StockMutationHistoryCard({ tradeItemKey, productId }) {
|
|
|
60
60
|
keys.add(tradeItemKey);
|
|
61
61
|
if (productId)
|
|
62
62
|
keys.add(productId);
|
|
63
|
-
// Groepssleutels waaronder dit artikel ook afgeboekt kan worden.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
// Groepssleutels waaronder dit artikel ook afgeboekt kan worden (meestal al meegeleverd).
|
|
64
|
+
if (sleutels) {
|
|
65
|
+
for (const k of sleutels)
|
|
66
|
+
keys.add(k);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const { data: groups } = await supabase
|
|
70
|
+
.from("product_group_items")
|
|
71
|
+
.select("product_group_id")
|
|
72
|
+
.in("trade_item_id", [...keys])
|
|
73
|
+
.limit(20);
|
|
74
|
+
for (const g of (groups ?? [])) {
|
|
75
|
+
keys.add(`group:${g.product_group_id}`);
|
|
76
|
+
}
|
|
71
77
|
}
|
|
72
78
|
const { data, error } = await supabase
|
|
73
79
|
.from("stock_mutation_log")
|
|
@@ -135,7 +141,7 @@ export function StockMutationHistoryCard({ tradeItemKey, productId }) {
|
|
|
135
141
|
cancelled = true;
|
|
136
142
|
supabase.removeChannel(channel);
|
|
137
143
|
};
|
|
138
|
-
}, [tradeItemKey, productId]);
|
|
144
|
+
}, [tradeItemKey, productId, sleutels?.join("|")]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
139
145
|
return (_jsxs(Card, { children: [_jsxs("div", { className: "grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 px-6 py-4", children: [_jsx("span", { className: "flex h-7 w-7 items-center justify-center rounded-full border border-primary/40 bg-primary/10 text-primary", children: _jsx(History, { className: "h-4 w-4" }) }), _jsx("span", { className: "font-medium", children: "Afboekgeschiedenis" }), _jsx("span", { className: "text-xs text-muted-foreground tabular-nums", children: rows ? `${rows.length} mutatie${rows.length === 1 ? "" : "s"}` : "" })] }), _jsxs(CardContent, { className: "pt-0", children: [error && (_jsx("div", { className: "text-sm text-destructive", children: error })), !rows && !error && (_jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Mutaties laden\u2026"] })), rows && rows.length === 0 && !error && (_jsx("div", { className: "text-sm text-muted-foreground", children: "Nog geen voorraadmutaties voor dit artikel." })), rows && rows.length > 0 && (_jsxs("div", { className: "overflow-x-auto rounded-md border", children: [_jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-muted/50 text-xs uppercase text-muted-foreground", children: _jsxs("tr", { children: [_jsx("th", { className: "px-3 py-2 text-left", children: "Wanneer" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Soort" }), _jsx("th", { className: "px-3 py-2 text-right", children: "Aantal" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Van \u2192 naar" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Order" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Door" }), _jsx("th", { className: "px-3 py-2 text-left", children: "Reden" })] }) }), _jsx("tbody", { children: (expanded ? rows : rows.slice(0, 5)).map((r) => {
|
|
140
146
|
const meta = TYPE_LABEL[r.mutation_type] ?? {
|
|
141
147
|
label: r.mutation_type || "Onbekend",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoorraadBeheerCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadBeheerCard.tsx"],"names":[],"mappings":"AAuBA,mGAAmG;AACnG,wBAAgB,kBAAkB,uCAwDjC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { Button, Card, CardContent, CardHeader, CardTitle, toast } from "@flowselections/core";
|
|
4
|
+
import { supabase } from "../../integrations/supabase/client.js";
|
|
5
|
+
import { dbFoutTekst } from "../../lib/db-error-message.js";
|
|
6
|
+
import { toonVersieBeheer } from "../../lib/floriday-versie-ronde.js";
|
|
7
|
+
import { floridayVersiesControleren } from "../../lib/floriday-versie-ronde.functions.js";
|
|
8
|
+
const STATUS_TEKST = {
|
|
9
|
+
geslaagd: "geslaagd",
|
|
10
|
+
onvolledig: "nog niet compleet (wordt automatisch opnieuw geprobeerd)",
|
|
11
|
+
mislukt: "mislukt (wordt automatisch opnieuw geprobeerd)",
|
|
12
|
+
};
|
|
13
|
+
/** Inklapbaar blok "Beheer": alleen zichtbaar voor beheerders, alleen informatie plus één knop. */
|
|
14
|
+
export function VoorraadBeheerCard() {
|
|
15
|
+
const [status, setStatus] = useState(null);
|
|
16
|
+
const [bezig, setBezig] = useState(false);
|
|
17
|
+
const laad = useCallback(async () => {
|
|
18
|
+
const { data, error } = await supabase.rpc("voorraad_floriday_versieronde_status");
|
|
19
|
+
if (error) {
|
|
20
|
+
setStatus(null);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
setStatus(data);
|
|
24
|
+
}, []);
|
|
25
|
+
useEffect(() => { void laad(); }, [laad]);
|
|
26
|
+
if (!toonVersieBeheer(status) || !status?.heeft_koppeling)
|
|
27
|
+
return null;
|
|
28
|
+
const start = async () => {
|
|
29
|
+
setBezig(true);
|
|
30
|
+
try {
|
|
31
|
+
await floridayVersiesControleren();
|
|
32
|
+
toast.success("Controle gestart. Dit loopt op de achtergrond.");
|
|
33
|
+
await laad();
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
toast.error(dbFoutTekst(e));
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
setBezig(false);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const l = status.laatste;
|
|
43
|
+
return (_jsx(Card, { children: _jsxs("details", { children: [_jsx("summary", { className: "cursor-pointer list-none", children: _jsx(CardHeader, { children: _jsx(CardTitle, { children: "Beheer" }) }) }), _jsxs(CardContent, { className: "space-y-2 text-sm", children: [_jsx("p", { className: "font-medium", children: "Controle van Floriday-artikelen" }), _jsx("p", { className: "text-muted-foreground", children: "Loopt vanzelf elke nacht. Oude versies van Floriday-artikelen worden geen zichtbaar artikel." }), _jsxs("p", { children: ["Laatste controle:", " ", l ? `${new Date(l.uitgevoerd_at).toLocaleString("nl-NL")} — ${STATUS_TEKST[l.status] ?? l.status}` : "nog niet uitgevoerd", status.bezig && " · nu bezig"] }), l?.melding && l.status !== "geslaagd" && _jsx("p", { className: "text-muted-foreground", children: l.melding }), _jsxs("p", { children: ["Vervangen in Floriday: ", status.vervangen ?? 0, " \u00B7 Vervallen: ", status.vervallen ?? 0, " \u00B7 Apart gezet (geen antwoord van Floriday): ", status.onbekend ?? 0] }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => void start(), disabled: bezig || status.bezig, children: bezig ? "Bezig…" : "Nu opnieuw controleren" })] })] }) }));
|
|
44
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export declare function ArtikelPagina({ id, resumeJobId }: {
|
|
1
|
+
export declare function ArtikelPagina({ id, resumeJobId, onNietGevonden }: {
|
|
2
2
|
id: string;
|
|
3
3
|
resumeJobId?: string;
|
|
4
|
+
onNietGevonden?: () => void;
|
|
4
5
|
}): import("react").JSX.Element;
|
|
5
6
|
//# sourceMappingURL=ArtikelPagina.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArtikelPagina.d.ts","sourceRoot":"","sources":["../../../../src/components/voorraad/artikel/ArtikelPagina.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ArtikelPagina.d.ts","sourceRoot":"","sources":["../../../../src/components/voorraad/artikel/ArtikelPagina.tsx"],"names":[],"mappings":"AAwFA,wBAAgB,aAAa,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,+BA+bnI"}
|
|
@@ -5,6 +5,7 @@ import { Badge, Button, Card, Dialog, DialogContent, DialogDescription, DialogFo
|
|
|
5
5
|
import { AlertTriangle, ArrowLeft, Loader2, MoreHorizontal, Package, Send } from "lucide-react";
|
|
6
6
|
import { supabase } from "../../../integrations/supabase/client.js";
|
|
7
7
|
import { dbFoutTekst } from "../../../lib/db-error-message.js";
|
|
8
|
+
import { ARTIKEL_GEWIJZIGD } from "../../../lib/artikel-gewijzigd.js";
|
|
8
9
|
import { ARTIKEL_VELDEN, VELD_LABEL, VOORRAAD_LABEL, VOORRAAD_VELDEN, aantalUitInvoer, gewijzigdeVoorraad, alsLijstRij, artikelStatus, artikelTabs, floridayActie, gewijzigdeVelden, prijsUitInvoer, } from "../../../lib/artikel-pagina.js";
|
|
9
10
|
import { STATUS_INFO, aantal, geld } from "../../../lib/voorraad-lijst.js";
|
|
10
11
|
import { AanpassenDialog, AfboekenDialog } from "../lijst/SnelActieDialogen.js";
|
|
@@ -34,7 +35,11 @@ function toon(v) {
|
|
|
34
35
|
return "(leeg)";
|
|
35
36
|
return String(v);
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
function gelijk(a, b) {
|
|
39
|
+
const n = (v) => (v === null || v === undefined ? "" : String(v).trim());
|
|
40
|
+
return n(a) === n(b);
|
|
41
|
+
}
|
|
42
|
+
export function ArtikelPagina({ id, resumeJobId, onNietGevonden }) {
|
|
38
43
|
const [detail, setDetail] = useState(null);
|
|
39
44
|
const [fout, setFout] = useState(null);
|
|
40
45
|
const [bijOpenen, setBijOpenen] = useState(null);
|
|
@@ -50,6 +55,7 @@ export function ArtikelPagina({ id, resumeJobId }) {
|
|
|
50
55
|
const [archiefKeuze, setArchiefKeuze] = useState("hier");
|
|
51
56
|
const [bezig, setBezig] = useState(false);
|
|
52
57
|
const geladen = useRef(false);
|
|
58
|
+
const invoerRef = useRef({});
|
|
53
59
|
// Onderdelen (eigen velden, traysticker) die meedoen met de ene knop "Opslaan".
|
|
54
60
|
const [deelnemers, setDeelnemers] = useState({});
|
|
55
61
|
const register = useMemo(() => ({
|
|
@@ -76,7 +82,10 @@ export function ArtikelPagina({ id, resumeJobId }) {
|
|
|
76
82
|
}
|
|
77
83
|
const d = data;
|
|
78
84
|
if (!d?.gevonden) {
|
|
79
|
-
|
|
85
|
+
if (onNietGevonden)
|
|
86
|
+
onNietGevonden();
|
|
87
|
+
else
|
|
88
|
+
setFout("Dit artikel bestaat niet (meer) in de voorraad.");
|
|
80
89
|
return;
|
|
81
90
|
}
|
|
82
91
|
setDetail(d);
|
|
@@ -91,24 +100,63 @@ export function ArtikelPagina({ id, resumeJobId }) {
|
|
|
91
100
|
...Object.fromEntries(VOORRAAD_VELDEN.map((k) => [k, vb[k] === null ? "" : String(vb[k])])),
|
|
92
101
|
});
|
|
93
102
|
}
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
else {
|
|
104
|
+
// Velden die je niet zelf aan het wijzigen bent, volgen de nieuwe stand (ook na opslaan in een ander tabblad).
|
|
105
|
+
const inv = invoerRef.current;
|
|
106
|
+
const vb = { minimum_stock: d.minimum, incoming_stock: d.inkomend, notes: d.notitie ?? null };
|
|
107
|
+
const volg = {};
|
|
108
|
+
setBijOpenen((b) => {
|
|
109
|
+
if (!b)
|
|
110
|
+
return b;
|
|
111
|
+
const n = { ...b };
|
|
112
|
+
for (const k of ARTIKEL_VELDEN)
|
|
113
|
+
if (gelijk(inv[k], b[k]) && !gelijk(b[k], d.velden[k])) {
|
|
114
|
+
n[k] = d.velden[k];
|
|
115
|
+
volg[k] = d.velden[k] === null ? "" : String(d.velden[k]);
|
|
116
|
+
}
|
|
117
|
+
return n;
|
|
118
|
+
});
|
|
119
|
+
setVoorraadBij((b) => {
|
|
120
|
+
if (!b)
|
|
121
|
+
return b;
|
|
122
|
+
const n = { ...b };
|
|
123
|
+
for (const k of VOORRAAD_VELDEN)
|
|
124
|
+
if (gelijk(inv[k], b[k]) && !gelijk(b[k], vb[k])) {
|
|
125
|
+
n[k] = vb[k];
|
|
126
|
+
volg[k] = vb[k] === null ? "" : String(vb[k]);
|
|
127
|
+
}
|
|
128
|
+
return n;
|
|
129
|
+
});
|
|
130
|
+
setInvoer((s) => ({ ...s, ...volg }));
|
|
131
|
+
}
|
|
132
|
+
}, [id, onNietGevonden]);
|
|
133
|
+
useEffect(() => { invoerRef.current = invoer; }, [invoer]);
|
|
134
|
+
useEffect(() => { geladen.current = false; void laad(); }, [id]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
135
|
+
// Opslag in een ander tabblad van deze pagina (prijs in het Floriday-formulier, samenstelling): kop direct bijwerken.
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
const h = (e) => { if (e.detail?.id === id)
|
|
138
|
+
void laad(); };
|
|
139
|
+
window.addEventListener(ARTIKEL_GEWIJZIGD, h);
|
|
140
|
+
return () => window.removeEventListener(ARTIKEL_GEWIJZIGD, h);
|
|
141
|
+
}, [id, laad]);
|
|
96
142
|
// Live bijwerken alleen voor dit artikel (voorraadregel en artikelrij), gebundeld.
|
|
143
|
+
const heeftDetail = Boolean(detail);
|
|
144
|
+
const voorraadSleutel = detail?.voorraad_sleutel ?? null;
|
|
97
145
|
useEffect(() => {
|
|
98
|
-
if (!
|
|
146
|
+
if (!heeftDetail)
|
|
99
147
|
return;
|
|
100
148
|
let t = null;
|
|
101
149
|
const later = () => { if (t)
|
|
102
150
|
clearTimeout(t); t = setTimeout(() => void laad(), 1500); };
|
|
103
151
|
let ch = supabase.channel(`artikel-${id}`)
|
|
104
152
|
.on("postgres_changes", { event: "*", schema: "public", table: "products", filter: `id=eq.${id}` }, later);
|
|
105
|
-
if (
|
|
106
|
-
ch = ch.on("postgres_changes", { event: "*", schema: "public", table: "trade_item_stock", filter: `trade_item_key=eq.${
|
|
153
|
+
if (voorraadSleutel) {
|
|
154
|
+
ch = ch.on("postgres_changes", { event: "*", schema: "public", table: "trade_item_stock", filter: `trade_item_key=eq.${voorraadSleutel}` }, later);
|
|
107
155
|
}
|
|
108
156
|
ch.subscribe();
|
|
109
157
|
return () => { if (t)
|
|
110
158
|
clearTimeout(t); supabase.removeChannel(ch); };
|
|
111
|
-
}, [id,
|
|
159
|
+
}, [id, voorraadSleutel, laad, heeftDetail]);
|
|
112
160
|
const nieuw = useMemo(() => {
|
|
113
161
|
if (!bijOpenen)
|
|
114
162
|
return null;
|
|
@@ -249,7 +297,7 @@ export function ArtikelPagina({ id, resumeJobId }) {
|
|
|
249
297
|
if (floridayOpen && !tabs.includes("floriday") && actie === "op_floriday")
|
|
250
298
|
tabs.push("floriday");
|
|
251
299
|
const rij = alsLijstRij(detail);
|
|
252
|
-
return (_jsxs("main", { className: "p-6 space-y-4", children: [_jsxs(Link, { to: "/voorraad", className: "inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground", children: [_jsx(ArrowLeft, { className: "h-4 w-4" }), " Terug naar voorraad"] }), _jsx(Card, { className: "p-4", children: _jsxs("div", { className: "flex flex-wrap items-start gap-4", children: [_jsx("div", { className: "h-20 w-20 shrink-0 overflow-hidden rounded-md border bg-muted flex items-center justify-center", children: detail.foto ? _jsx("img", { src: detail.foto, alt: detail.naam, className: "h-full w-full object-cover" }) : _jsx(Package, { className: "h-8 w-8 text-muted-foreground" }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h1", { className: "text-xl font-semibold
|
|
300
|
+
return (_jsxs("main", { className: "p-6 space-y-4", children: [_jsxs(Link, { to: "/voorraad", className: "inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground", children: [_jsx(ArrowLeft, { className: "h-4 w-4" }), " Terug naar voorraad"] }), _jsx(Card, { className: "p-4", children: _jsxs("div", { className: "flex flex-wrap items-start gap-4", children: [_jsx("div", { className: "h-20 w-20 shrink-0 overflow-hidden rounded-md border bg-muted flex items-center justify-center", children: detail.foto ? _jsx("img", { src: detail.foto, alt: detail.naam, className: "h-full w-full object-cover" }) : _jsx(Package, { className: "h-8 w-8 text-muted-foreground" }) }), _jsxs("div", { className: "min-w-0 flex-1 basis-64", children: [_jsx("h1", { className: "text-xl font-semibold leading-tight break-words", children: detail.naam }), _jsx("div", { className: "mt-1 text-sm text-muted-foreground break-words", children: detail.artikelnummer ?? "Geen artikelnummer" }), _jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-sm", children: [_jsx(Badge, { variant: status === "ok" ? "secondary" : status === "gearchiveerd" ? "outline" : "destructive", children: info.label }), info.actie && info.tab && tabs.includes(info.tab) && (_jsx("button", { type: "button", className: "underline text-muted-foreground", onClick: () => setTab(info.tab), children: info.actie })), vuil && _jsx("span", { className: "text-muted-foreground", children: "\u00B7 Niet-opgeslagen wijzigingen" })] })] }), _jsx("dl", { className: "grid grid-cols-3 gap-4 text-center sm:grid-cols-5", children: [
|
|
253
301
|
["Liggend", aantal(detail.liggend)],
|
|
254
302
|
["Gereserveerd", aantal(detail.gereserveerd)],
|
|
255
303
|
["Inkomend", aantal(detail.inkomend)],
|
|
@@ -257,7 +305,9 @@ export function ArtikelPagina({ id, resumeJobId }) {
|
|
|
257
305
|
["Prijs per stuk", geld(detail.velden.sale_price === null ? null : Number(detail.velden.sale_price))],
|
|
258
306
|
].map(([l, v], i) => (_jsxs("div", { children: [_jsx("dt", { className: "text-xs text-muted-foreground", children: l }), _jsx("dd", { className: `text-lg font-semibold tabular-nums ${i === 3 && rij.onder_minimum ? "text-destructive" : ""}`, children: v })] }, l))) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { onClick: doeOpslaan, disabled: !vuil || opslaan || Boolean(prijsFout) || Boolean(aantalFout), children: [opslaan && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Opslaan"] }), actie && (_jsxs(Button, { variant: "outline", onClick: () => { setFloridayOpen(true); setTab("floriday"); }, children: [_jsx(Send, { className: "mr-2 h-4 w-4" }), actie === "sturen" ? "Naar Floriday sturen" : "Op Floriday zetten"] })), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": "Meer acties", children: _jsx(MoreHorizontal, { className: "h-4 w-4" }) }) }), _jsx(DropdownMenuContent, { align: "end", children: detail.gearchiveerd_at
|
|
259
307
|
? _jsx(DropdownMenuItem, { onClick: terugzetten, children: "Terugzetten in voorraad" })
|
|
260
|
-
: _jsx(DropdownMenuItem, { onClick: () => { setArchiefKeuze("hier"); setArchief({}); }, children: "Archiveren\u2026" }) })] })] })] }) }), detail.gearchiveerd_at && (detail.orders_gearchiveerd ?? 0) > 0 && (_jsxs("div", { role: "alert", className: "flex flex-wrap items-center gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm", children: [_jsx(AlertTriangle, { className: "h-4 w-4 text-destructive" }), _jsxs("span", { children: ["Dit artikel is gearchiveerd, maar er ", detail.orders_gearchiveerd === 1 ? "is 1 open orderregel" : `zijn ${detail.orders_gearchiveerd} open orderregels`, " binnengekomen. De orders zijn gewoon gekoppeld."] }), _jsx(Button, { size: "sm", variant: "outline", onClick: terugzetten, children: "Terugzetten in voorraad" })] })), _jsx(OpslaanContext.Provider, { value: register, children: _jsxs(Tabs, { value: tab, onValueChange: setTab, children: [_jsx(TabsList, { children: tabs.map((t) => _jsx(TabsTrigger, { value: t, children: TAB_LABEL[t] }, t)) }), _jsxs(TabsContent, { value: "voorraad", forceMount: bezocht.has("voorraad") ? true : undefined, className: "space-y-4 data-[state=inactive]:hidden", children: [_jsxs(Card, { className: "p-4 space-y-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsx("h2", { className: "font-medium", children: "Artikelgegevens" }), _jsx("span", { className: "text-xs text-muted-foreground", children: "Opslaan is alleen lokaal; er gaat niets automatisch naar Floriday." })] }), _jsx("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-5", children: ARTIKEL_VELDEN.map((k) => (_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { htmlFor: `veld-${k}`, children: VELD_LABEL[k] }), _jsx(Input, { id: `veld-${k}`, value: invoer[k] ?? "", inputMode: k === "sale_price" ? "decimal" : undefined, onChange: (e) => setInvoer((s) => ({ ...s, [k]: e.target.value })) }), k === "sale_price" && prijsFout && _jsx("p", { className: "text-xs text-destructive", children: prijsFout })] }, k))) })] }), _jsxs(Card, { className: "p-4 flex flex-wrap items-center justify-between gap-2", children: [_jsxs("div", { className: "grid w-full gap-3 sm:grid-cols-3", children: [VOORRAAD_VELDEN.map((k) => (_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { htmlFor: `voorraad-${k}`, children: VOORRAAD_LABEL[k] }), _jsx(Input, { id: `voorraad-${k}`, value: invoer[k] ?? "", inputMode: k === "notes" ? undefined : "numeric", onChange: (e) => setInvoer((s) => ({ ...s, [k]: e.target.value })) })] }, k))), aantalFout && _jsx("p", { className: "text-xs text-destructive sm:col-span-3", children: aantalFout })] }), _jsxs("div", { className: "text-sm", children: [_jsx("div", { className: "font-medium", children: "Voorraad" }), _jsxs("div", { className: "text-muted-foreground", children: ["Liggend wijzig je met Aanpassen of Afboeken \u00B7 Telmoment ", detail.telmoment ? new Date(detail.telmoment).toLocaleString("nl-NL") : _jsx("span", { className: "text-destructive", children: "ontbreekt" })] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => setAanpassen(true), disabled: Boolean(detail.gearchiveerd_at), children: "Aanpassen" }), _jsx(Button, { variant: "outline", onClick: () => setAfboeken(true), disabled: Boolean(detail.gearchiveerd_at), children: "Afboeken" })] })] }), _jsxs(Suspense, { fallback: _jsx(Laden, {}), children: [_jsx(StockMutationHistoryCard, { tradeItemKey: detail.voorraad_sleutel, productId: detail.id }), _jsx(OrderHistoryCard, { tradeItemKey: detail.voorraad_sleutel, productName: detail.naam, productId: detail.id }), _jsx(ProductCustomFieldsCard, { productId: detail.id })] })] }), _jsx(TabsContent, { value: "verpakking", forceMount: bezocht.has("verpakking") ? true : undefined, className: "space-y-4 data-[state=inactive]:hidden", children: _jsxs(Suspense, { fallback: _jsx(Laden, {}), children: [_jsx(ProductStructureCard, { productId: detail.id }), _jsx(ArtikelCompositionCard, { productId: detail.id, floridayId: detail.floriday_id }), _jsx(TrayStickerCard, { productId: detail.id })] }) }), _jsxs(TabsContent, { value: "koppelingen", className: "space-y-4", children: [_jsx(TwijfelKiezen, { productId: detail.id, onGekozen: () => void laad() }), _jsxs(Suspense, { fallback: _jsx(Laden, {}), children: [detail.floriday_id && detail.heeft_koppeling ? (_jsx(FloridayInfoCard, { floridayTradeItemId: detail.floriday_id, local: { name: detail.naam, articleNumber: detail.artikelnummer, gtin: detail.velden.barcode ?? null } })) : (_jsx(Card, { className: "p-4 text-sm text-muted-foreground", children: detail.heeft_koppeling ? "Dit artikel is niet aan Floriday gekoppeld." : "Er is geen Floriday-koppeling in deze omgeving; het artikel werkt volledig lokaal." })), _jsx(ProductLinkCard, { tradeItemKey: detail.voorraad_sleutel, productName: detail.naam })] })] }), tabs.includes("floriday") && (_jsx(TabsContent, { value: "floriday", children: _jsx(Suspense, { fallback: _jsx(Laden, {}), children: _jsx(ArtikelWizard, { productId: detail.id, resumeJobId: resumeJobId, embedded: true }) }) }))] }) }), _jsx(AanpassenDialog, { rij: aanpassen ? rij : null, onClose: () => setAanpassen(false), onDone: () => { setAanpassen(false); void laad(); } }), _jsx(AfboekenDialog, { rij: afboeken ? rij : null, connectionId: null, onClose: () => setAfboeken(false), onDone: () => { setAfboeken(false); void laad(); } }), _jsx(Dialog, { open: Boolean(conflicten && conflicten.length), onOpenChange: (o) => !o && setConflicten(null), children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Iemand anders heeft dit ook gewijzigd" }), _jsx(DialogDescription, { children: "Er is niets opgeslagen. Kies per veld welke waarde blijft." })] }), _jsx("div", { className: "space-y-3", children: (conflicten ?? []).map((c) => (_jsxs("div", { className: "rounded-md border p-3 text-sm space-y-2", children: [_jsx("div", { className: "font-medium", children: VELD_LABEL[c.veld] ?? VOORRAAD_LABEL[c.veld] }), _jsxs("div", { className: "grid grid-cols-2 gap-2", children: [_jsxs("div", { children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Jouw wijziging" }), toon(c.jouw)] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Hun wijziging" }), toon(c.hun)] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { size: "sm", variant: "outline", onClick: () => houdJouw(c), children: "Mijn waarde houden" }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => neemHunOver(c), children: "Hun waarde overnemen" })] })] }, c.veld))) })] }) }), _jsx(Dialog, { open: archief !== null, onOpenChange: (o) => !o && setArchief(null), children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Artikel archiveren" }), _jsx(DialogDescription, { children: "Het artikel wordt nooit verwijderd. Je kunt het later terugzetten." })] }), archief?.waarschuwing && (_jsxs("div", { className: "flex gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm", children: [_jsx(AlertTriangle, { className: "h-4 w-4 shrink-0 text-destructive" }), _jsxs("span", { children: ["Let op: er ", archief.waarschuwing.open_orders === 1 ? "is 1 open order" : `zijn ${archief.waarschuwing.open_orders} open orders`, " en ", aantal(archief.waarschuwing.gereserveerd), " gereserveerd. Die blijven bestaan."] })] })), _jsxs("div", { className: "space-y-2 text-sm", children: [_jsxs("label", { className: "flex gap-2 items-start", children: [_jsx("input", { type: "radio", checked: archiefKeuze === "hier", onChange: () => setArchiefKeuze("hier") }), _jsxs("span", { children: [_jsx("strong", { children:
|
|
308
|
+
: _jsx(DropdownMenuItem, { onClick: () => { setArchiefKeuze("hier"); setArchief({}); }, children: "Archiveren\u2026" }) })] })] })] }) }), detail.gearchiveerd_at && (detail.orders_gearchiveerd ?? 0) > 0 && (_jsxs("div", { role: "alert", className: "flex flex-wrap items-center gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm", children: [_jsx(AlertTriangle, { className: "h-4 w-4 text-destructive" }), _jsxs("span", { children: ["Dit artikel is gearchiveerd, maar er ", detail.orders_gearchiveerd === 1 ? "is 1 open orderregel" : `zijn ${detail.orders_gearchiveerd} open orderregels`, " binnengekomen. De orders zijn gewoon gekoppeld."] }), _jsx(Button, { size: "sm", variant: "outline", onClick: terugzetten, children: "Terugzetten in voorraad" })] })), _jsx(OpslaanContext.Provider, { value: register, children: _jsxs(Tabs, { value: tab, onValueChange: setTab, children: [_jsx(TabsList, { children: tabs.map((t) => _jsx(TabsTrigger, { value: t, children: TAB_LABEL[t] }, t)) }), _jsxs(TabsContent, { value: "voorraad", forceMount: bezocht.has("voorraad") ? true : undefined, className: "space-y-4 data-[state=inactive]:hidden", children: [_jsxs(Card, { className: "p-4 space-y-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsx("h2", { className: "font-medium", children: "Artikelgegevens" }), _jsx("span", { className: "text-xs text-muted-foreground", children: "Opslaan is alleen lokaal; er gaat niets automatisch naar Floriday." })] }), _jsx("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-5", children: ARTIKEL_VELDEN.map((k) => (_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { htmlFor: `veld-${k}`, children: VELD_LABEL[k] }), _jsx(Input, { id: `veld-${k}`, value: invoer[k] ?? "", inputMode: k === "sale_price" ? "decimal" : undefined, onChange: (e) => setInvoer((s) => ({ ...s, [k]: e.target.value })) }), k === "sale_price" && prijsFout && _jsx("p", { className: "text-xs text-destructive", children: prijsFout })] }, k))) })] }), _jsxs(Card, { className: "p-4 flex flex-wrap items-center justify-between gap-2", children: [_jsxs("div", { className: "grid w-full gap-3 sm:grid-cols-3", children: [VOORRAAD_VELDEN.map((k) => (_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { htmlFor: `voorraad-${k}`, children: VOORRAAD_LABEL[k] }), _jsx(Input, { id: `voorraad-${k}`, value: invoer[k] ?? "", inputMode: k === "notes" ? undefined : "numeric", onChange: (e) => setInvoer((s) => ({ ...s, [k]: e.target.value })) })] }, k))), aantalFout && _jsx("p", { className: "text-xs text-destructive sm:col-span-3", children: aantalFout })] }), _jsxs("div", { className: "text-sm", children: [_jsx("div", { className: "font-medium", children: "Voorraad" }), _jsxs("div", { className: "text-muted-foreground", children: ["Liggend wijzig je met Aanpassen of Afboeken \u00B7 Telmoment ", detail.telmoment ? new Date(detail.telmoment).toLocaleString("nl-NL") : _jsx("span", { className: "text-destructive", children: "ontbreekt" })] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => setAanpassen(true), disabled: Boolean(detail.gearchiveerd_at), children: "Aanpassen" }), _jsx(Button, { variant: "outline", onClick: () => setAfboeken(true), disabled: Boolean(detail.gearchiveerd_at), children: "Afboeken" })] })] }), _jsxs(Suspense, { fallback: _jsx(Laden, {}), children: [_jsx(StockMutationHistoryCard, { tradeItemKey: detail.voorraad_sleutel, productId: detail.id, sleutels: detail.controle?.mutatie_sleutels ?? undefined }), _jsx(OrderHistoryCard, { tradeItemKey: detail.voorraad_sleutel, productName: detail.naam, productId: detail.id, productIds: detail.controle?.zelfde_sleutel_ids }), _jsx(ProductCustomFieldsCard, { productId: detail.id, beginVelden: detail.eigen_velden?.definities, beginWaarden: detail.eigen_velden?.waarden })] })] }), _jsx(TabsContent, { value: "verpakking", forceMount: bezocht.has("verpakking") ? true : undefined, className: "space-y-4 data-[state=inactive]:hidden", children: _jsxs(Suspense, { fallback: _jsx(Laden, {}), children: [_jsx(ProductStructureCard, { productId: detail.id }), _jsx(ArtikelCompositionCard, { productId: detail.id, floridayId: detail.floriday_id }), _jsx(TrayStickerCard, { productId: detail.id })] }) }), _jsxs(TabsContent, { value: "koppelingen", className: "space-y-4", children: [_jsx(TwijfelKiezen, { productId: detail.id, onGekozen: () => void laad() }), _jsxs(Suspense, { fallback: _jsx(Laden, {}), children: [detail.floriday_id && detail.heeft_koppeling ? (_jsx(FloridayInfoCard, { floridayTradeItemId: detail.floriday_id, local: { name: detail.naam, articleNumber: detail.artikelnummer, gtin: detail.velden.barcode ?? null } })) : (_jsx(Card, { className: "p-4 text-sm text-muted-foreground", children: detail.heeft_koppeling ? (detail.floriday_verwijderd_at ? "Dit artikel is in Floriday verwijderd." : "Dit artikel is niet aan Floriday gekoppeld.") : "Er is geen Floriday-koppeling in deze omgeving; het artikel werkt volledig lokaal." })), _jsx(ProductLinkCard, { tradeItemKey: detail.voorraad_sleutel, productName: detail.naam })] })] }), tabs.includes("floriday") && (_jsx(TabsContent, { value: "floriday", children: _jsx(Suspense, { fallback: _jsx(Laden, {}), children: _jsx(ArtikelWizard, { productId: detail.id, resumeJobId: resumeJobId, embedded: true }) }) }))] }) }), _jsx(AanpassenDialog, { rij: aanpassen ? rij : null, onClose: () => setAanpassen(false), onDone: () => { setAanpassen(false); void laad(); } }), _jsx(AfboekenDialog, { rij: afboeken ? rij : null, connectionId: null, onClose: () => setAfboeken(false), onDone: () => { setAfboeken(false); void laad(); } }), _jsx(Dialog, { open: Boolean(conflicten && conflicten.length), onOpenChange: (o) => !o && setConflicten(null), children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Iemand anders heeft dit ook gewijzigd" }), _jsx(DialogDescription, { children: "Er is niets opgeslagen. Kies per veld welke waarde blijft." })] }), _jsx("div", { className: "space-y-3", children: (conflicten ?? []).map((c) => (_jsxs("div", { className: "rounded-md border p-3 text-sm space-y-2", children: [_jsx("div", { className: "font-medium", children: VELD_LABEL[c.veld] ?? VOORRAAD_LABEL[c.veld] }), _jsxs("div", { className: "grid grid-cols-2 gap-2", children: [_jsxs("div", { children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Jouw wijziging" }), toon(c.jouw)] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Hun wijziging" }), toon(c.hun)] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { size: "sm", variant: "outline", onClick: () => houdJouw(c), children: "Mijn waarde houden" }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => neemHunOver(c), children: "Hun waarde overnemen" })] })] }, c.veld))) })] }) }), _jsx(Dialog, { open: archief !== null, onOpenChange: (o) => !o && setArchief(null), children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Artikel archiveren" }), _jsx(DialogDescription, { children: "Het artikel wordt nooit verwijderd. Je kunt het later terugzetten." })] }), archief?.waarschuwing && (_jsxs("div", { className: "flex gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm", children: [_jsx(AlertTriangle, { className: "h-4 w-4 shrink-0 text-destructive" }), _jsxs("span", { children: ["Let op: er ", archief.waarschuwing.open_orders === 1 ? "is 1 open order" : `zijn ${archief.waarschuwing.open_orders} open orders`, " en ", aantal(archief.waarschuwing.gereserveerd), " gereserveerd. Die blijven bestaan."] })] })), _jsxs("div", { className: "space-y-2 text-sm", children: [_jsxs("label", { className: "flex gap-2 items-start", children: [_jsx("input", { type: "radio", checked: archiefKeuze === "hier", onChange: () => setArchiefKeuze("hier") }), _jsxs("span", { children: [_jsx("strong", { children: detail.floriday_id && detail.heeft_koppeling ? "Alleen hier." : "Archiveren." }), " ", detail.floriday_id && detail.heeft_koppeling && !detail.floriday_verwijderd_at
|
|
309
|
+
? "Floriday blijft ongewijzigd: het artikel blijft op Floriday te koop."
|
|
310
|
+
: "Het artikel verdwijnt uit de voorraadlijst en de tellers."] })] }), detail.floriday_id && detail.heeft_koppeling && !detail.floriday_verwijderd_at && (_jsxs("label", { className: "flex gap-2 items-start", children: [_jsx("input", { type: "radio", checked: archiefKeuze === "floriday", onChange: () => setArchiefKeuze("floriday") }), _jsxs("span", { children: [_jsx("strong", { children: "Ook in Floriday." }), " De voorraad op Floriday wordt 0."] })] })), archiefKeuze === "floriday" && (_jsxs("div", { className: "rounded-md border p-3 space-y-1", children: [_jsx("div", { className: "font-medium", children: "Overzicht vooraf" }), _jsx("div", { children: "Voorraad op Floriday: wordt 0 (niet meer te koop)." }), _jsxs("div", { children: ["Je eigen voorraad blijft ", aantal(detail.liggend), " liggend."] }), _jsx("div", { className: "text-muted-foreground", children: detail.floriday_stuurt
|
|
261
311
|
? "Gaat via de gewone Floriday-wachtrij, met de bestaande schrijfstop."
|
|
262
312
|
: "Floriday is voor dit artikel leidend: er wordt niets verstuurd tot het systeem de voorraad stuurt." })] }))] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "ghost", onClick: () => setArchief(null), children: "Annuleren" }), _jsx(Button, { variant: "destructive", disabled: bezig, onClick: () => archiveren(Boolean(archief?.waarschuwing)), children: archief?.waarschuwing ? "Toch archiveren" : "Archiveren" })] })] }) })] }));
|
|
263
313
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoorraadLijstTabel.d.ts","sourceRoot":"","sources":["../../../../src/components/voorraad/lijst/VoorraadLijstTabel.tsx"],"names":[],"mappings":"AAeA,OAAO,EAML,KAAK,QAAQ,EACb,KAAK,SAAS,EAEf,MAAM,6BAA6B,CAAC;AAErC,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAChF,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAK5E,CAAC;
|
|
1
|
+
{"version":3,"file":"VoorraadLijstTabel.d.ts","sourceRoot":"","sources":["../../../../src/components/voorraad/lijst/VoorraadLijstTabel.tsx"],"names":[],"mappings":"AAeA,OAAO,EAML,KAAK,QAAQ,EACb,KAAK,SAAS,EAEf,MAAM,6BAA6B,CAAC;AAErC,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAChF,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAK5E,CAAC;AA+CF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,WAAW,EACX,WAAW,EACX,UAAU,EACV,cAAsB,GACvB,EAAE;IACD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,WAAW,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;IACnC,UAAU,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;CACnC,+BAyFA"}
|
|
@@ -15,10 +15,11 @@ function StatusIcoon({ status }) {
|
|
|
15
15
|
const titel = info.actie ? `${info.label} — ${info.actie}` : info.label;
|
|
16
16
|
const cls = "h-4 w-4";
|
|
17
17
|
const icon = status === "verpakking" ? _jsx(PackageX, { className: `${cls} text-destructive` }) :
|
|
18
|
-
status === "
|
|
19
|
-
status === "
|
|
20
|
-
status === "
|
|
21
|
-
_jsx(
|
|
18
|
+
status === "verwijderd_floriday" ? _jsx(Link2Off, { className: `${cls} text-destructive` }) :
|
|
19
|
+
status === "niet_gekoppeld" ? _jsx(Link2Off, { className: `${cls} text-muted-foreground` }) :
|
|
20
|
+
status === "prijs" ? _jsx(Euro, { className: `${cls} text-destructive` }) :
|
|
21
|
+
status === "gearchiveerd" ? _jsx(Minus, { className: `${cls} text-muted-foreground` }) :
|
|
22
|
+
_jsx(CheckCircle2, { className: `${cls} text-primary` });
|
|
22
23
|
return (_jsxs("span", { title: titel, "aria-label": titel, className: "inline-flex items-center gap-1.5", children: [icon, status !== "ok" && _jsx("span", { className: "text-xs text-muted-foreground hidden xl:inline", children: info.label })] }));
|
|
23
24
|
}
|
|
24
25
|
function Kop({ kolom, label, sort, oplopend, onSort, rechts, }) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type VoorraadCustomField } from "../lib/voorraad-custom-fields.js";
|
|
2
2
|
/** Laadt de door de gebruiker gedefinieerde voorraadvelden. */
|
|
3
|
-
|
|
3
|
+
/** `begin`: velden die al bekend zijn (uit voorraad_artikel_detail); dan geen eigen aanvraag. */
|
|
4
|
+
export declare function useVoorraadCustomFields(begin?: VoorraadCustomField[]): {
|
|
4
5
|
fields: VoorraadCustomField[];
|
|
5
6
|
loading: boolean;
|
|
6
7
|
error: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVoorraadCustomFields.d.ts","sourceRoot":"","sources":["../../src/hooks/useVoorraadCustomFields.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,+BAA+B,CAAC;AAEvC,+DAA+D;AAC/D,wBAAgB,uBAAuB;;;;;
|
|
1
|
+
{"version":3,"file":"useVoorraadCustomFields.d.ts","sourceRoot":"","sources":["../../src/hooks/useVoorraadCustomFields.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,+BAA+B,CAAC;AAEvC,+DAA+D;AAC/D,iGAAiG;AACjG,wBAAgB,uBAAuB,CAAC,KAAK,CAAC,EAAE,mBAAmB,EAAE;;;;;EAyBpE"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { useCallback, useEffect, useState } from "react";
|
|
2
2
|
import { fetchVoorraadCustomFields, } from "../lib/voorraad-custom-fields.js";
|
|
3
3
|
/** Laadt de door de gebruiker gedefinieerde voorraadvelden. */
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const [
|
|
4
|
+
/** `begin`: velden die al bekend zijn (uit voorraad_artikel_detail); dan geen eigen aanvraag. */
|
|
5
|
+
export function useVoorraadCustomFields(begin) {
|
|
6
|
+
const [fields, setFields] = useState(begin ?? []);
|
|
7
|
+
const [loading, setLoading] = useState(!begin);
|
|
7
8
|
const [error, setError] = useState(null);
|
|
8
9
|
const reload = useCallback(async () => {
|
|
9
10
|
setLoading(true);
|
|
@@ -19,8 +20,11 @@ export function useVoorraadCustomFields() {
|
|
|
19
20
|
setLoading(false);
|
|
20
21
|
}
|
|
21
22
|
}, []);
|
|
23
|
+
const heeftBegin = Boolean(begin);
|
|
22
24
|
useEffect(() => {
|
|
25
|
+
if (heeftBegin)
|
|
26
|
+
return;
|
|
23
27
|
void reload();
|
|
24
|
-
}, [reload]);
|
|
28
|
+
}, [reload, heeftBegin]);
|
|
25
29
|
return { fields, loading, error, reload };
|
|
26
30
|
}
|
package/dist-lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAMpE,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAExE,eAAO,MAAM,sBAAsB,EAAE,UAkBpC,CAAC"}
|