@flowselections/floriday-voorraad 1.0.150 → 1.0.154
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/fs-ui/DataTable.d.ts +42 -0
- package/dist-lib/components/fs-ui/DataTable.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/DataTable.js +68 -0
- package/dist-lib/components/fs-ui/EmptyState.d.ts +9 -0
- package/dist-lib/components/fs-ui/EmptyState.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/EmptyState.js +5 -0
- package/dist-lib/components/fs-ui/FilterChips.d.ts +13 -0
- package/dist-lib/components/fs-ui/FilterChips.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/FilterChips.js +8 -0
- package/dist-lib/components/fs-ui/FilterPanel.d.ts +19 -0
- package/dist-lib/components/fs-ui/FilterPanel.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/FilterPanel.js +10 -0
- package/dist-lib/components/fs-ui/FiltersButton.d.ts +6 -0
- package/dist-lib/components/fs-ui/FiltersButton.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/FiltersButton.js +7 -0
- package/dist-lib/components/fs-ui/HeaderButton.d.ts +16 -0
- package/dist-lib/components/fs-ui/HeaderButton.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/HeaderButton.js +10 -0
- package/dist-lib/components/fs-ui/HoverTip.d.ts +15 -0
- package/dist-lib/components/fs-ui/HoverTip.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/HoverTip.js +24 -0
- package/dist-lib/components/fs-ui/InlineAlert.d.ts +12 -0
- package/dist-lib/components/fs-ui/InlineAlert.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/InlineAlert.js +15 -0
- package/dist-lib/components/fs-ui/KpiRow.d.ts +10 -0
- package/dist-lib/components/fs-ui/KpiRow.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/KpiRow.js +8 -0
- package/dist-lib/components/fs-ui/KpiTile.d.ts +21 -0
- package/dist-lib/components/fs-ui/KpiTile.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/KpiTile.js +40 -0
- package/dist-lib/components/fs-ui/MobilePrimaryAction.d.ts +13 -0
- package/dist-lib/components/fs-ui/MobilePrimaryAction.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/MobilePrimaryAction.js +10 -0
- package/dist-lib/components/fs-ui/NoticeBar.d.ts +10 -0
- package/dist-lib/components/fs-ui/NoticeBar.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/NoticeBar.js +16 -0
- package/dist-lib/components/fs-ui/PageHeader.d.ts +19 -0
- package/dist-lib/components/fs-ui/PageHeader.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/PageHeader.js +9 -0
- package/dist-lib/components/fs-ui/Pagination.d.ts +10 -0
- package/dist-lib/components/fs-ui/Pagination.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/Pagination.js +10 -0
- package/dist-lib/components/fs-ui/PillTabs.d.ts +17 -0
- package/dist-lib/components/fs-ui/PillTabs.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/PillTabs.js +28 -0
- package/dist-lib/components/fs-ui/RowMenu.d.ts +13 -0
- package/dist-lib/components/fs-ui/RowMenu.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/RowMenu.js +7 -0
- package/dist-lib/components/fs-ui/SearchInput.d.ts +11 -0
- package/dist-lib/components/fs-ui/SearchInput.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/SearchInput.js +55 -0
- package/dist-lib/components/fs-ui/ShortcutHelp.d.ts +8 -0
- package/dist-lib/components/fs-ui/ShortcutHelp.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/ShortcutHelp.js +6 -0
- package/dist-lib/components/fs-ui/StatusIcon.d.ts +13 -0
- package/dist-lib/components/fs-ui/StatusIcon.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/StatusIcon.js +15 -0
- package/dist-lib/components/fs-ui/TableSkeleton.d.ts +7 -0
- package/dist-lib/components/fs-ui/TableSkeleton.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/TableSkeleton.js +6 -0
- package/dist-lib/components/fs-ui/Toolbar.d.ts +12 -0
- package/dist-lib/components/fs-ui/Toolbar.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/Toolbar.js +8 -0
- package/dist-lib/components/fs-ui/UpdatedAt.d.ts +10 -0
- package/dist-lib/components/fs-ui/UpdatedAt.d.ts.map +1 -0
- package/dist-lib/components/fs-ui/UpdatedAt.js +18 -0
- package/dist-lib/components/voorraad/ArtikelCompositionCard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ArtikelCompositionCard.js +46 -15
- package/dist-lib/components/voorraad/ArtikelWizard.js +4 -4
- package/dist-lib/components/voorraad/FloridayConnectionNotice.d.ts +7 -6
- package/dist-lib/components/voorraad/FloridayConnectionNotice.d.ts.map +1 -1
- package/dist-lib/components/voorraad/FloridayConnectionNotice.js +15 -12
- package/dist-lib/components/voorraad/FustenPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/FustenPage.js +92 -26
- package/dist-lib/components/voorraad/NieuwArtikelPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/NieuwArtikelPage.js +2 -1
- 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 +26 -50
- package/dist-lib/components/voorraad/PublicatiesPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/PublicatiesPage.js +42 -36
- package/dist-lib/components/voorraad/Sneltoetsen.d.ts +14 -0
- package/dist-lib/components/voorraad/Sneltoetsen.d.ts.map +1 -0
- package/dist-lib/components/voorraad/Sneltoetsen.js +44 -0
- package/dist-lib/components/voorraad/StockIntegrityAlert.d.ts +42 -1
- package/dist-lib/components/voorraad/StockIntegrityAlert.d.ts.map +1 -1
- package/dist-lib/components/voorraad/StockIntegrityAlert.js +38 -7
- package/dist-lib/components/voorraad/StockMutationHistoryCard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/StockMutationHistoryCard.js +10 -46
- package/dist-lib/components/voorraad/StockPushMonitor.js +2 -2
- package/dist-lib/components/voorraad/TelmomentButton.d.ts +5 -1
- package/dist-lib/components/voorraad/TelmomentButton.d.ts.map +1 -1
- package/dist-lib/components/voorraad/TelmomentButton.js +13 -6
- package/dist-lib/components/voorraad/ValidationOverviewTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ValidationOverviewTable.js +11 -40
- package/dist-lib/components/voorraad/ValidationPage.d.ts +1 -0
- package/dist-lib/components/voorraad/ValidationPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ValidationPage.js +33 -5
- package/dist-lib/components/voorraad/VoorraadBeheerCard.d.ts +4 -1
- package/dist-lib/components/voorraad/VoorraadBeheerCard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadBeheerCard.js +26 -5
- package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadPage.js +67 -38
- package/dist-lib/components/voorraad/VoorraadSturingCard.js +1 -1
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.d.ts.map +1 -1
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.js +42 -19
- package/dist-lib/components/voorraad/lijst/ImporteerKnop.d.ts.map +1 -1
- package/dist-lib/components/voorraad/lijst/ImporteerKnop.js +1 -1
- package/dist-lib/components/voorraad/lijst/LijstExportKnop.d.ts.map +1 -1
- package/dist-lib/components/voorraad/lijst/LijstExportKnop.js +1 -1
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.d.ts +8 -2
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.d.ts.map +1 -1
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.js +62 -27
- package/dist-lib/hooks/useLocalTradeItems.d.ts +14 -0
- package/dist-lib/hooks/useLocalTradeItems.d.ts.map +1 -1
- package/dist-lib/hooks/useLocalTradeItems.js +5 -3
- package/dist-lib/hooks/useTradeItemStock.d.ts.map +1 -1
- package/dist-lib/hooks/useTradeItemStock.js +6 -3
- package/dist-lib/hooks/useVoorraadData.d.ts.map +1 -1
- package/dist-lib/hooks/useVoorraadData.js +16 -8
- package/dist-lib/hooks/useVoorraadLijst.d.ts +10 -0
- package/dist-lib/hooks/useVoorraadLijst.d.ts.map +1 -1
- package/dist-lib/hooks/useVoorraadLijst.js +22 -4
- package/dist-lib/integrations/supabase/types.d.ts +85 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/alle-rijen.d.ts +15 -0
- package/dist-lib/lib/alle-rijen.d.ts.map +1 -0
- package/dist-lib/lib/alle-rijen.js +17 -0
- package/dist-lib/lib/db-error-message.d.ts.map +1 -1
- package/dist-lib/lib/db-error-message.js +3 -1
- package/dist-lib/lib/labels.d.ts +42 -0
- package/dist-lib/lib/labels.d.ts.map +1 -0
- package/dist-lib/lib/labels.js +152 -0
- package/dist-lib/lib/notatie.d.ts +4 -0
- package/dist-lib/lib/notatie.d.ts.map +1 -0
- package/dist-lib/lib/notatie.js +18 -0
- package/dist-lib/lib/voorraad-lijst.d.ts +2 -0
- package/dist-lib/lib/voorraad-lijst.d.ts.map +1 -1
- package/dist-lib/lib/voorraad-lijst.js +14 -3
- package/package.json +2 -1
- package/sql/floriday-voorraad-schema.sql +315 -39
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PillTabs.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/PillTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEhE,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAChD,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,EACzC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,KAAkB,GACnB,EAAE;IACD,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACnB,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,+BAwDA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect, useRef } from "react";
|
|
3
|
+
/** StatusTabs exact naar Verkooporders: altijd één regel, scrollt horizontaal met vervaging. */
|
|
4
|
+
export function PillTabs({ tabs, value, onChange, label = "Weergave", }) {
|
|
5
|
+
const listRef = useRef(null);
|
|
6
|
+
useLayoutEffect(() => {
|
|
7
|
+
const measure = () => {
|
|
8
|
+
const list = listRef.current;
|
|
9
|
+
const el = list?.querySelector(`[data-tab="${value}"]`);
|
|
10
|
+
if (el && list && (el.offsetLeft < list.scrollLeft || el.offsetLeft + el.offsetWidth > list.scrollLeft + list.clientWidth)) {
|
|
11
|
+
list.scrollLeft = el.offsetLeft - 8;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
measure();
|
|
15
|
+
window.addEventListener("resize", measure);
|
|
16
|
+
return () => window.removeEventListener("resize", measure);
|
|
17
|
+
}, [value]);
|
|
18
|
+
return (_jsx("div", { className: "shrink-0", children: _jsx("div", { ref: listRef, role: "tablist", "aria-label": label, className: "relative -mx-4 flex items-center gap-2 overflow-x-auto px-4 pb-1 [scrollbar-width:none] [mask-image:linear-gradient(to_right,black_85%,transparent)] [&::-webkit-scrollbar]:hidden sm:mx-0 sm:px-0 sm:[mask-image:none]", children: tabs.map((t) => {
|
|
19
|
+
const active = t.value === value;
|
|
20
|
+
return (_jsxs("button", { "data-tab": t.value, type: "button", role: "tab", "aria-selected": active, onClick: () => onChange(t.value), title: t.hint, style: { transitionProperty: "color, background-color, border-color", transitionDuration: "150ms" }, className: "relative flex h-9 shrink-0 items-center gap-2 whitespace-nowrap rounded-lg border px-3 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&_svg]:h-4 [&_svg]:w-4 [&_svg]:shrink-0 " +
|
|
21
|
+
(active
|
|
22
|
+
? "border-primary/30 bg-primary/10 font-semibold text-foreground"
|
|
23
|
+
: t.count === 0
|
|
24
|
+
? "border-border bg-card text-muted-foreground/70 hover:text-foreground"
|
|
25
|
+
: "border-border bg-card text-foreground/80 hover:bg-muted hover:text-foreground"), children: [t.icon, _jsx("span", { children: t.label }), t.count !== undefined && (_jsx("span", { className: "inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-[11px] font-semibold tabular-nums " +
|
|
26
|
+
(active ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"), children: t.count === null ? "…" : t.count.toLocaleString("nl-NL") }))] }, t.value));
|
|
27
|
+
}) }) }));
|
|
28
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface RowMenuItem {
|
|
2
|
+
label: string;
|
|
3
|
+
onClick: () => void;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
title?: string;
|
|
6
|
+
destructive?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** Rijmenu exact naar Verkooporders; de acties komen van de pagina. */
|
|
9
|
+
export declare function RowMenu({ label, items }: {
|
|
10
|
+
label: string;
|
|
11
|
+
items: RowMenuItem[];
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=RowMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RowMenu.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/RowMenu.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,+BAyBhF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { MoreVertical } from "lucide-react";
|
|
3
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@flowselections/core";
|
|
4
|
+
/** Rijmenu exact naar Verkooporders; de acties komen van de pagina. */
|
|
5
|
+
export function RowMenu({ label, items }) {
|
|
6
|
+
return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { "aria-label": `Acties voor ${label}`, onClick: (e) => e.stopPropagation(), className: "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(MoreVertical, { className: "h-4 w-4" }) }), _jsx(DropdownMenuContent, { align: "end", onClick: (e) => e.stopPropagation(), children: items.map((it) => (_jsx(DropdownMenuItem, { disabled: it.disabled, title: it.title, onClick: () => !it.disabled && it.onClick(), className: it.destructive ? "text-destructive focus:text-destructive" : undefined, children: it.label }, it.label))) })] }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** True als de gebruiker in een invoerveld typt (sneltoetsen doen dan niets). */
|
|
2
|
+
export declare function isTypen(t: EventTarget | null): boolean;
|
|
3
|
+
/** Zoekveld exact naar Verkooporders: h-9 (mobiel h-10), sm:w-80, breder bij focus; "/" focust, Esc wist. */
|
|
4
|
+
export declare function SearchInput({ value, onChange, placeholder, label, delay, }: {
|
|
5
|
+
value: string;
|
|
6
|
+
onChange: (v: string) => void;
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
label?: string;
|
|
9
|
+
delay?: number;
|
|
10
|
+
}): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=SearchInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchInput.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/SearchInput.tsx"],"names":[],"mappings":"AAGA,iFAAiF;AACjF,wBAAgB,OAAO,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAItD;AAED,6GAA6G;AAC7G,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,WAAsB,EACtB,KAAgB,EAChB,KAAW,GACZ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,+BA4EA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { Search, X } from "lucide-react";
|
|
4
|
+
/** True als de gebruiker in een invoerveld typt (sneltoetsen doen dan niets). */
|
|
5
|
+
export function isTypen(t) {
|
|
6
|
+
const el = t;
|
|
7
|
+
if (!el)
|
|
8
|
+
return false;
|
|
9
|
+
return el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT" || el.isContentEditable;
|
|
10
|
+
}
|
|
11
|
+
/** Zoekveld exact naar Verkooporders: h-9 (mobiel h-10), sm:w-80, breder bij focus; "/" focust, Esc wist. */
|
|
12
|
+
export function SearchInput({ value, onChange, placeholder = "Zoeken", label = "Zoeken", delay = 250, }) {
|
|
13
|
+
const [search, setSearch] = useState(value);
|
|
14
|
+
const inputRef = useRef(null);
|
|
15
|
+
const laatst = useRef(value);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (value !== laatst.current) {
|
|
18
|
+
laatst.current = value;
|
|
19
|
+
setSearch(value);
|
|
20
|
+
}
|
|
21
|
+
}, [value]);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (search === laatst.current)
|
|
24
|
+
return;
|
|
25
|
+
const t = setTimeout(() => { laatst.current = search; onChange(search); }, delay);
|
|
26
|
+
return () => clearTimeout(t);
|
|
27
|
+
}, [search, delay, onChange]);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const h = (e) => {
|
|
30
|
+
if (e.key === "/" && !e.metaKey && !e.ctrlKey && !e.altKey && !isTypen(e.target)) {
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
inputRef.current?.focus();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
window.addEventListener("keydown", h);
|
|
36
|
+
return () => window.removeEventListener("keydown", h);
|
|
37
|
+
}, []);
|
|
38
|
+
const clearSearch = () => { setSearch(""); laatst.current = ""; onChange(""); inputRef.current?.focus(); };
|
|
39
|
+
return (_jsxs("div", { className: "group relative flex h-10 sm:h-9 w-full items-center overflow-hidden rounded-md border border-border bg-card " +
|
|
40
|
+
"transition-[box-shadow,border-color,width] duration-[180ms] ease-out motion-reduce:transition-none " +
|
|
41
|
+
"focus-within:border-primary focus-within:ring-[3px] focus-within:ring-ring/20 " +
|
|
42
|
+
"sm:w-80 sm:focus-within:w-[400px]", children: [_jsx(Search, { className: "ml-3 h-4 w-4 shrink-0 text-muted-foreground transition-colors duration-[120ms] group-focus-within:text-primary", "aria-hidden": true }), _jsx("input", { ref: inputRef, type: "search", placeholder: placeholder, "aria-label": label, value: search, maxLength: 100, autoComplete: "off", spellCheck: false, onChange: (e) => setSearch(e.target.value), onKeyDown: (e) => {
|
|
43
|
+
if (e.key === "Escape") {
|
|
44
|
+
if (search) {
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
e.stopPropagation();
|
|
47
|
+
clearSearch();
|
|
48
|
+
}
|
|
49
|
+
else
|
|
50
|
+
inputRef.current?.blur();
|
|
51
|
+
}
|
|
52
|
+
}, className: "h-full min-w-0 flex-1 appearance-none border-0 bg-transparent px-2 text-base sm:text-sm text-foreground outline-none ring-0 shadow-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 placeholder:text-muted-foreground [&::-webkit-search-cancel-button]:hidden" }), _jsxs("span", { className: "relative mr-1.5 flex h-7 w-7 shrink-0 items-center justify-center", children: [_jsx("kbd", { className: "pointer-events-none absolute rounded border border-border px-1.5 font-mono text-[11px] leading-5 text-muted-foreground transition-opacity duration-[120ms] " +
|
|
53
|
+
(search ? "opacity-0" : "opacity-100 group-focus-within:opacity-0"), "aria-hidden": true, children: "/" }), _jsx("button", { type: "button", onClick: clearSearch, tabIndex: search ? 0 : -1, "aria-label": "Zoekopdracht wissen", className: "absolute inline-flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-[opacity,transform,background-color] duration-[120ms] ease-out hover:bg-muted hover:text-foreground " +
|
|
54
|
+
(search ? "scale-100 opacity-100" : "pointer-events-none scale-90 opacity-0"), children: _jsx(X, { className: "h-4 w-4" }) })] })] }));
|
|
55
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type Shortcut = [string[], string];
|
|
2
|
+
/** Sneltoetsenoverzicht exact naar Verkooporders; de lijst komt van de pagina. */
|
|
3
|
+
export declare function ShortcutHelp({ open, onOpenChange, shortcuts }: {
|
|
4
|
+
open: boolean;
|
|
5
|
+
onOpenChange: (o: boolean) => void;
|
|
6
|
+
shortcuts: Shortcut[];
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=ShortcutHelp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShortcutHelp.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/ShortcutHelp.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;AAE1C,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAAC,SAAS,EAAE,QAAQ,EAAE,CAAA;CAAE,+BAwB3I"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@flowselections/core";
|
|
3
|
+
/** Sneltoetsenoverzicht exact naar Verkooporders; de lijst komt van de pagina. */
|
|
4
|
+
export function ShortcutHelp({ open, onOpenChange, shortcuts }) {
|
|
5
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-w-sm", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Sneltoetsen" }) }), _jsx("ul", { className: "divide-y divide-border text-sm", children: shortcuts.map(([keys, label]) => (_jsxs("li", { className: "flex items-center justify-between py-2", children: [_jsx("span", { className: "text-foreground", children: label }), _jsx("span", { className: "flex gap-1", children: keys.map((k) => (_jsx("kbd", { className: "inline-flex h-6 min-w-6 items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-[11px] text-muted-foreground", children: k }, k))) })] }, label))) })] }) }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type StatusTone = "klaar" | "open" | "bezig" | "fout";
|
|
3
|
+
/**
|
|
4
|
+
* Klein rond statusicoon met tooltip: groen klaar, grijs open, oker bezig, rood fout.
|
|
5
|
+
* Geen gekleurde vlakjes eromheen. Het label is de toegankelijke naam.
|
|
6
|
+
*/
|
|
7
|
+
export declare function StatusIcon({ tone, icon, label, detail }: {
|
|
8
|
+
tone: StatusTone;
|
|
9
|
+
icon: ReactNode;
|
|
10
|
+
label: string;
|
|
11
|
+
detail?: ReactNode;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=StatusIcon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusIcon.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/StatusIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAS7D;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAAE,+BAejI"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { HoverTip } from "./HoverTip.js";
|
|
3
|
+
const TONE = {
|
|
4
|
+
klaar: "text-primary",
|
|
5
|
+
open: "text-muted-foreground",
|
|
6
|
+
bezig: "text-warning-soft-foreground",
|
|
7
|
+
fout: "text-destructive",
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Klein rond statusicoon met tooltip: groen klaar, grijs open, oker bezig, rood fout.
|
|
11
|
+
* Geen gekleurde vlakjes eromheen. Het label is de toegankelijke naam.
|
|
12
|
+
*/
|
|
13
|
+
export function StatusIcon({ tone, icon, label, detail }) {
|
|
14
|
+
return (_jsx(HoverTip, { label: label, className: "h-6 w-6 [&_svg]:h-4 [&_svg]:w-4 " + TONE[tone], content: _jsxs("div", { className: "space-y-1", children: [_jsx("div", { className: "text-[13px] font-semibold text-foreground", children: label }), detail && _jsx("div", { className: "text-muted-foreground", children: detail })] }), children: icon }));
|
|
15
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Skeletrijen in de echte vorm van de tabel (60 px hoog, zelfde kolombreedtes). */
|
|
2
|
+
export declare function TableSkeleton({ columns, rows, media }: {
|
|
3
|
+
columns: Array<string | undefined>;
|
|
4
|
+
rows?: number;
|
|
5
|
+
media?: boolean;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=TableSkeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableSkeleton.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/TableSkeleton.tsx"],"names":[],"mappings":"AAEA,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,IAAQ,EAAE,KAAY,EAAE,EAAE;IAAE,OAAO,EAAE,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,+BAwBxI"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Skeleton } from "@flowselections/core";
|
|
3
|
+
/** Skeletrijen in de echte vorm van de tabel (60 px hoog, zelfde kolombreedtes). */
|
|
4
|
+
export function TableSkeleton({ columns, rows = 8, media = true }) {
|
|
5
|
+
return (_jsx(_Fragment, { children: Array.from({ length: rows }).map((_, r) => (_jsx("tr", { className: "h-[60px] border-b border-border last:border-0", "aria-hidden": true, children: columns.map((w, c) => (_jsx("td", { className: "px-3", style: w ? { width: w } : undefined, children: c === 0 && media ? (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Skeleton, { className: "h-9 w-9 rounded-lg" }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Skeleton, { className: "h-3.5 w-40" }), _jsx(Skeleton, { className: "h-3 w-24" })] })] })) : (_jsx(Skeleton, { className: "h-3.5 w-14" })) }, c))) }, r))) }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Werkbalk exact naar Verkooporders: zoekveld, direct rechts "Filters", dan de
|
|
4
|
+
* actieve chips op dezelfde regel; uiterst rechts alleen "Kolommen".
|
|
5
|
+
*/
|
|
6
|
+
export declare function Toolbar({ children, filters, chips, right }: {
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
filters?: ReactNode;
|
|
9
|
+
chips?: ReactNode;
|
|
10
|
+
right?: ReactNode;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=Toolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/Toolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,+BAS/I"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Werkbalk exact naar Verkooporders: zoekveld, direct rechts "Filters", dan de
|
|
4
|
+
* actieve chips op dezelfde regel; uiterst rechts alleen "Kolommen".
|
|
5
|
+
*/
|
|
6
|
+
export function Toolbar({ children, filters, chips, right }) {
|
|
7
|
+
return (_jsxs("div", { className: "shrink-0 flex flex-wrap items-center gap-2", children: [_jsx("div", { className: "min-w-0 flex-1 sm:flex-none", children: children }), filters, chips, right && _jsx("div", { className: "ml-auto hidden items-center gap-2 md:flex", children: right })] }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** "Bijgewerkt hh:mm" met klokicoon (12 px tekst); extra uitleg alleen in de infoballon. */
|
|
3
|
+
export declare function UpdatedAt({ at, prefix, info, stale, }: {
|
|
4
|
+
at: string | Date | null | undefined;
|
|
5
|
+
prefix?: string;
|
|
6
|
+
/** Extra informatie, alleen zichtbaar in de infoballon. */
|
|
7
|
+
info?: ReactNode;
|
|
8
|
+
stale?: boolean;
|
|
9
|
+
}): import("react").JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=UpdatedAt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UpdatedAt.d.ts","sourceRoot":"","sources":["../../../src/components/fs-ui/UpdatedAt.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,EACxB,EAAE,EACF,MAAqB,EACrB,IAAI,EACJ,KAAK,GACN,EAAE;IACD,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,sCAgBA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Clock } from "lucide-react";
|
|
3
|
+
import { HoverTip } from "./HoverTip.js";
|
|
4
|
+
/** "Bijgewerkt hh:mm" met klokicoon (12 px tekst); extra uitleg alleen in de infoballon. */
|
|
5
|
+
export function UpdatedAt({ at, prefix = "Bijgewerkt", info, stale, }) {
|
|
6
|
+
let tekst = "Laden…";
|
|
7
|
+
if (at) {
|
|
8
|
+
const d = typeof at === "string" ? new Date(at) : at;
|
|
9
|
+
if (Number.isNaN(d.getTime()))
|
|
10
|
+
return null;
|
|
11
|
+
const t = d.toLocaleTimeString("nl-NL", { hour: "2-digit", minute: "2-digit" });
|
|
12
|
+
tekst = stale ? `Niet bijgewerkt sinds ${t}` : `${prefix} ${t}`;
|
|
13
|
+
}
|
|
14
|
+
const inhoud = (_jsxs("span", { className: "inline-flex items-center gap-1 tabular-nums " + (stale ? "text-warning" : ""), children: [_jsx(Clock, { className: "h-3.5 w-3.5", "aria-hidden": true }), tekst] }));
|
|
15
|
+
if (!info)
|
|
16
|
+
return inhoud;
|
|
17
|
+
return _jsx(HoverTip, { label: tekst, content: _jsx("div", { className: "max-w-xs text-xs", children: info }), align: "start", children: inhoud });
|
|
18
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArtikelCompositionCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ArtikelCompositionCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ArtikelCompositionCard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ArtikelCompositionCard.tsx"],"names":[],"mappings":"AAOA,UAAU,KAAK;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAkHD,wBAAgB,sBAAsB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,KAAK,sCA0TtE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useEffect, useState } from "react";
|
|
3
|
-
import {
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
import { useOpslagDeelnemer } from "./artikel/opslaan-context.js";
|
|
4
|
+
import { dbFoutTekst } from "../../lib/db-error-message.js";
|
|
4
5
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle, Badge } from "@flowselections/core";
|
|
5
6
|
import { ArrowDown, ArrowUp, Loader2, Package } from "lucide-react";
|
|
6
7
|
import { supabase } from "../../integrations/supabase/client.js";
|
|
@@ -89,7 +90,12 @@ export function ArtikelCompositionCard({ productId, floridayId }) {
|
|
|
89
90
|
const [loading, setLoading] = useState(true);
|
|
90
91
|
const [sections, setSections] = useState([]);
|
|
91
92
|
const [reloadTick, setReloadTick] = useState(0);
|
|
92
|
-
const [savingOrder
|
|
93
|
+
const [savingOrder] = useState(false);
|
|
94
|
+
// Volgorde van de groepsleden bij openen (D1): pas bij "Opslaan" bewaard, met controle tegen deze stand.
|
|
95
|
+
const [volgordeBij, setVolgordeBij] = useState(null);
|
|
96
|
+
const volgordeBijRef = useRef(null);
|
|
97
|
+
volgordeBijRef.current = volgordeBij;
|
|
98
|
+
const lokaleVolgorde = useRef(null);
|
|
93
99
|
useEffect(() => {
|
|
94
100
|
let cancelled = false;
|
|
95
101
|
(async () => {
|
|
@@ -218,6 +224,20 @@ export function ArtikelCompositionCard({ productId, floridayId }) {
|
|
|
218
224
|
});
|
|
219
225
|
}
|
|
220
226
|
if (!cancelled) {
|
|
227
|
+
const grp = out.find((x) => x.kind === "productgroep");
|
|
228
|
+
const nieuwIds = grp ? grp.rows.map((r) => r.key) : null;
|
|
229
|
+
const lokaal = lokaleVolgorde.current;
|
|
230
|
+
const vuilNu = lokaal && volgordeBijRef.current && lokaal.join("|") !== volgordeBijRef.current.join("|");
|
|
231
|
+
if (grp && vuilNu) {
|
|
232
|
+
// Niet-opgeslagen volgorde houden; nieuwe leden achteraan.
|
|
233
|
+
const pos = new Map(lokaal.map((id, i) => [id, i]));
|
|
234
|
+
grp.rows = [...grp.rows].sort((a, b) => (pos.get(a.key) ?? 1e9) - (pos.get(b.key) ?? 1e9));
|
|
235
|
+
lokaleVolgorde.current = grp.rows.map((r) => r.key);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
setVolgordeBij(nieuwIds);
|
|
239
|
+
lokaleVolgorde.current = nieuwIds;
|
|
240
|
+
}
|
|
221
241
|
setSections(out);
|
|
222
242
|
setLoading(false);
|
|
223
243
|
}
|
|
@@ -238,32 +258,43 @@ export function ArtikelCompositionCard({ productId, floridayId }) {
|
|
|
238
258
|
supabase.removeChannel(channel);
|
|
239
259
|
};
|
|
240
260
|
}, [groupId]);
|
|
241
|
-
const move = useCallback(
|
|
261
|
+
const move = useCallback((index, dir) => {
|
|
242
262
|
const sec = sections.find((x) => x.kind === "productgroep");
|
|
243
263
|
if (!sec)
|
|
244
264
|
return;
|
|
245
265
|
const target = index + dir;
|
|
246
266
|
if (target < 0 || target >= sec.rows.length)
|
|
247
267
|
return;
|
|
248
|
-
const prev = sections;
|
|
249
268
|
const rows = [...sec.rows];
|
|
250
269
|
[rows[index], rows[target]] = [rows[target], rows[index]];
|
|
270
|
+
lokaleVolgorde.current = rows.map((r) => r.key);
|
|
251
271
|
setSections(sections.map((x) => (x === sec ? { ...x, rows } : x)));
|
|
252
|
-
setSavingOrder(true);
|
|
253
|
-
const results = await Promise.all(rows.map((r, i) => supabase.from("product_group_items").update({ sort_order: i }).eq("id", r.key)));
|
|
254
|
-
setSavingOrder(false);
|
|
255
|
-
const failed = results.find((r) => r.error);
|
|
256
|
-
if (failed?.error) {
|
|
257
|
-
setSections(prev);
|
|
258
|
-
toast.error(`Volgorde opslaan mislukt: ${failed.error.message}`);
|
|
259
|
-
}
|
|
260
272
|
}, [sections]);
|
|
273
|
+
const huidigeVolgorde = sections.find((x) => x.kind === "productgroep")?.rows.map((r) => r.key) ?? null;
|
|
274
|
+
const volgordeVuil = Boolean(groupId && volgordeBij && huidigeVolgorde && huidigeVolgorde.join("|") !== volgordeBij.join("|"));
|
|
275
|
+
useOpslagDeelnemer("groepsvolgorde", volgordeVuil, async () => {
|
|
276
|
+
if (!groupId || !volgordeBij || !huidigeVolgorde)
|
|
277
|
+
return { ok: true };
|
|
278
|
+
const { data, error } = await supabase.rpc("voorraad_groep_volgorde_opslaan", { p_group_id: groupId, p_oud: volgordeBij, p_nieuw: huidigeVolgorde });
|
|
279
|
+
if (error)
|
|
280
|
+
return { ok: false, melding: dbFoutTekst(error, "Opslaan") };
|
|
281
|
+
const r = data;
|
|
282
|
+
if (!r.ok) {
|
|
283
|
+
// Conflict: de volgorde van de ander overnemen en opnieuw laten kiezen.
|
|
284
|
+
lokaleVolgorde.current = null;
|
|
285
|
+
setReloadTick((t) => t + 1);
|
|
286
|
+
return { ok: false, melding: r.melding ?? "Iemand anders heeft de volgorde intussen gewijzigd. Er is niets opgeslagen." };
|
|
287
|
+
}
|
|
288
|
+
setVolgordeBij(huidigeVolgorde);
|
|
289
|
+
lokaleVolgorde.current = huidigeVolgorde;
|
|
290
|
+
return { ok: true };
|
|
291
|
+
});
|
|
261
292
|
if (loading) {
|
|
262
293
|
return (_jsx(Card, { children: _jsxs(CardContent, { className: "flex items-center gap-2 py-4 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Samenstelling laden\u2026"] }) }));
|
|
263
294
|
}
|
|
264
295
|
if (sections.length === 0)
|
|
265
296
|
return null;
|
|
266
297
|
return (_jsx(_Fragment, { children: sections.map((s) => (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx(CardTitle, { children: s.title }), _jsx(Badge, { className: s.kind === "productgroep"
|
|
267
|
-
? "
|
|
268
|
-
: "
|
|
298
|
+
? "rounded-full border-border bg-muted text-muted-foreground"
|
|
299
|
+
: "rounded-full border-primary/30 bg-primary/10 text-primary", children: s.kind === "productgroep" ? "Productgroep" : "Samenstelling" })] }), _jsxs(CardDescription, { children: [s.description, s.kind === "productgroep" && volgordeVuil && _jsx("span", { className: "ml-2 font-medium text-warning-soft-foreground", children: "\u00B7 Volgorde nog niet opgeslagen" })] })] }), _jsx(CardContent, { children: s.rows.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground py-4 text-center", children: "Nog geen onderdelen toegevoegd." })) : (_jsx("ul", { className: "divide-y", children: s.rows.map((r, idx) => (_jsxs("li", { className: "flex items-center gap-3 py-2", children: [s.kind === "productgroep" && (_jsxs("div", { className: "flex flex-col shrink-0", children: [_jsx("button", { type: "button", "aria-label": "Omhoog", disabled: idx === 0 || savingOrder, onClick: () => move(idx, -1), className: "p-0.5 text-muted-foreground hover:text-foreground disabled:opacity-30", children: _jsx(ArrowUp, { className: "h-3.5 w-3.5" }) }), _jsx("button", { type: "button", "aria-label": "Omlaag", disabled: idx === s.rows.length - 1 || savingOrder, onClick: () => move(idx, 1), className: "p-0.5 text-muted-foreground hover:text-foreground disabled:opacity-30", children: _jsx(ArrowDown, { className: "h-3.5 w-3.5" }) })] })), _jsx("div", { className: "h-8 w-8 rounded bg-muted flex items-center justify-center shrink-0", children: _jsx(Package, { className: "h-4 w-4 text-muted-foreground" }) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "font-medium text-sm truncate", children: r.name }), r.code && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: r.code })), r.detail && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: r.detail }))] }), s.kind === "productgroep" && (_jsx("div", { className: "text-right shrink-0 w-40", children: r.stock ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-sm font-medium tabular-nums", children: ["Beschikbaar: ", r.stock.available] }), _jsxs("div", { className: "text-xs text-muted-foreground tabular-nums", children: ["fysiek ", r.stock.physical, " \u00B7 gereserveerd ", r.stock.reserved] })] })) : (_jsx("div", { className: "text-xs text-muted-foreground", children: "Nog geen voorraad" })) })), r.quantity !== undefined && r.quantity !== null && (_jsxs("div", { className: "text-sm tabular-nums text-muted-foreground shrink-0", title: s.kind === "productgroep" ? "Aantal in groep" : undefined, children: [r.quantity, r.unit ? ` ${r.unit}` : ""] }))] }, r.key))) })) })] }, s.kind))) }));
|
|
269
300
|
}
|
|
@@ -634,7 +634,7 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
|
|
|
634
634
|
return;
|
|
635
635
|
}
|
|
636
636
|
if (!row) {
|
|
637
|
-
toast.error("Artikel niet gevonden
|
|
637
|
+
toast.error("Artikel niet gevonden bij de Floriday-artikelen");
|
|
638
638
|
return;
|
|
639
639
|
}
|
|
640
640
|
// Lokale rij met nog niet doorgegeven wijzigingen? Die is leidend.
|
|
@@ -916,7 +916,7 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
|
|
|
916
916
|
if (hasRegulatoryLookup && regulatoryQuery.isLoading) {
|
|
917
917
|
return {
|
|
918
918
|
ok: false,
|
|
919
|
-
errors: ["Verplichte
|
|
919
|
+
errors: ["Verplichte kenmerken worden nog geladen"],
|
|
920
920
|
};
|
|
921
921
|
}
|
|
922
922
|
if (hasRegulatoryLookup && regulatoryQuery.isError) {
|
|
@@ -1852,7 +1852,7 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
|
|
|
1852
1852
|
const payload = buildUpdateTradeItemPayload(snapshot);
|
|
1853
1853
|
const res = await floriday.updateTradeItem(activeId, pushTargetId, payload);
|
|
1854
1854
|
if (!res?.attemptId) {
|
|
1855
|
-
throw new Error("
|
|
1855
|
+
throw new Error("Floriday gaf geen bevestiging terug");
|
|
1856
1856
|
}
|
|
1857
1857
|
// Geen eigen kopie in floriday_trade_items_cache: Floriday-auth vult die.
|
|
1858
1858
|
if (localId) {
|
|
@@ -2916,7 +2916,7 @@ function PackingConfigDialog({ open, onOpenChange, initial, isFirst, packagingTy
|
|
|
2916
2916
|
packagingSupplierId: v,
|
|
2917
2917
|
packagingSupplierName: sup?.name,
|
|
2918
2918
|
}));
|
|
2919
|
-
}, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Kies leverancier..." }) }), _jsx(SelectContent, { children: PACKAGING_SUPPLIERS.map((s) => (_jsx(SelectItem, { value: s.id, children: s.name }, s.id))) })] }))] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "
|
|
2919
|
+
}, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Kies leverancier..." }) }), _jsx(SelectContent, { children: PACKAGING_SUPPLIERS.map((s) => (_jsx(SelectItem, { value: s.id, children: s.name }, s.id))) })] }))] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Materiaalcode (optioneel)" }), _jsx(Input, { value: draft.packagingMaterialId ?? "", onChange: (e) => patch("packagingMaterialId", e.target.value.trim()), placeholder: "00000000-0000-0000-0000-000000000000", className: materialInvalid ? "border-destructive" : "" }), materialInvalid ? (_jsx("p", { className: "text-xs text-destructive", children: "Deze code klopt niet. Laat het veld leeg of kopieer de materiaalcode uit Floricode." })) : (_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Wanneer ingevuld gaat het als ", _jsx("code", { children: "customPackageId" }), "naar Floriday en vervangt het de VBN-fust."] }))] })] }), hasCustomPkg && (_jsx("div", { className: "rounded-md border border-primary/30 bg-primary/5 px-3 py-2 text-xs", children: "Eigen verpakking gekozen; het VBN-fust hieronder wordt niet naar Floriday gestuurd." }))] })), _jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: hasCustomPkg
|
|
2920
2920
|
? "VBN-fust (genegeerd — custom package actief)"
|
|
2921
2921
|
: draft.source === "SUPPLIER"
|
|
2922
2922
|
? "Fallback VBN-fust"
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ConnectionStatus } from "../../lib/stock-scope.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Werkpagina's tonen geen uitnodiging om een koppeling in te stellen (dat hoort bij Instellingen).
|
|
4
|
+
* Alleen als een bestaande koppeling niet geladen kan worden: één rustige meldingsregel.
|
|
5
|
+
* De technische reden gaat naar de console.
|
|
6
6
|
*/
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function floridayConnectionNotice(status: ConnectionStatus, error: string | null): string | null;
|
|
8
|
+
export declare function FloridayConnectionNotice({ status, error, }: {
|
|
8
9
|
status: ConnectionStatus;
|
|
9
|
-
environment
|
|
10
|
+
environment?: string | null;
|
|
10
11
|
error: string | null;
|
|
11
12
|
}): import("react").JSX.Element | null;
|
|
12
13
|
//# sourceMappingURL=FloridayConnectionNotice.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloridayConnectionNotice.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/FloridayConnectionNotice.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FloridayConnectionNotice.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/FloridayConnectionNotice.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAItG;AAED,wBAAgB,wBAAwB,CAAC,EACvC,MAAM,EACN,KAAK,GACN,EAAE;IACD,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,sCAMA"}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import { AlertTriangle } from "lucide-react";
|
|
3
|
-
import { noConnectionText } from "../../lib/stock-scope.js";
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
2
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
3
|
+
* Werkpagina's tonen geen uitnodiging om een koppeling in te stellen (dat hoort bij Instellingen).
|
|
4
|
+
* Alleen als een bestaande koppeling niet geladen kan worden: één rustige meldingsregel.
|
|
5
|
+
* De technische reden gaat naar de console.
|
|
8
6
|
*/
|
|
9
|
-
export function
|
|
10
|
-
if (status
|
|
11
|
-
return (_jsxs("div", { role: "alert", className: "flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: "Floriday-koppeling laden mislukt \u2013 alleen eigen artikelen mogelijk." }), _jsxs("p", { className: "mt-1 break-words", children: ["Melding: ", error] })] })] }));
|
|
12
|
-
}
|
|
13
|
-
if (status !== "geen_koppeling")
|
|
7
|
+
export function floridayConnectionNotice(status, error) {
|
|
8
|
+
if (status !== "fout")
|
|
14
9
|
return null;
|
|
15
|
-
|
|
10
|
+
if (error)
|
|
11
|
+
console.warn("Floriday-koppeling laden mislukt:", error);
|
|
12
|
+
return "De koppeling met Floriday kon niet geladen worden. Je eigen artikelen werken gewoon; probeer het later opnieuw.";
|
|
13
|
+
}
|
|
14
|
+
export function FloridayConnectionNotice({ status, error, }) {
|
|
15
|
+
const t = floridayConnectionNotice(status, error);
|
|
16
|
+
if (!t)
|
|
17
|
+
return null;
|
|
18
|
+
return (_jsx("div", { role: "status", className: "shrink-0 rounded-lg border border-border bg-warning-soft px-3 py-2 text-sm text-warning-soft-foreground", children: t }));
|
|
16
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FustenPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/FustenPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FustenPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/FustenPage.tsx"],"names":[],"mappings":"AAmMA,wBAAgB,UAAU,gCAiNzB"}
|