@almadar/ui 3.9.1 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +688 -607
- package/dist/avl/index.js +688 -607
- package/dist/components/index.cjs +595 -1210
- package/dist/components/index.js +591 -1192
- package/dist/components/molecules/DataGrid.d.ts +19 -8
- package/dist/components/molecules/DataList.d.ts +22 -7
- package/dist/components/molecules/WizardProgress.d.ts +2 -2
- package/dist/components/organisms/DetailPanel.d.ts +0 -2
- package/dist/components/organisms/Form.d.ts +0 -2
- package/dist/components/organisms/FormSection.d.ts +0 -2
- package/dist/hooks/index.cjs +222 -846
- package/dist/hooks/index.d.ts +0 -4
- package/dist/hooks/index.js +9 -613
- package/dist/providers/index.cjs +604 -762
- package/dist/providers/index.d.ts +0 -2
- package/dist/providers/index.js +605 -758
- package/dist/runtime/EntitySchemaContext.d.ts +7 -3
- package/dist/runtime/index.cjs +1599 -1518
- package/dist/runtime/index.js +830 -749
- package/dist/runtime/ui/SlotsContext.d.ts +57 -17
- package/package.json +1 -1
- package/dist/hooks/useEntityData.d.ts +0 -155
- package/dist/hooks/useEntityMutations.d.ts +0 -80
- package/dist/hooks/useOrbitalMutations.d.ts +0 -95
- package/dist/hooks/useResolvedEntity.d.ts +0 -32
- package/dist/providers/FetchedDataProvider.d.ts +0 -105
package/dist/providers/index.cjs
CHANGED
|
@@ -7917,7 +7917,7 @@ var init_MapView = __esm({
|
|
|
7917
7917
|
shadowSize: [41, 41]
|
|
7918
7918
|
});
|
|
7919
7919
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
7920
|
-
const { useEffect: useEffect62, useRef: useRef62, useCallback:
|
|
7920
|
+
const { useEffect: useEffect62, useRef: useRef62, useCallback: useCallback94, useState: useState86 } = React115__namespace.default;
|
|
7921
7921
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
7922
7922
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
7923
7923
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -7961,8 +7961,8 @@ var init_MapView = __esm({
|
|
|
7961
7961
|
showAttribution = true
|
|
7962
7962
|
}) {
|
|
7963
7963
|
const eventBus = useEventBus2();
|
|
7964
|
-
const [clickedPosition, setClickedPosition] =
|
|
7965
|
-
const handleMapClick =
|
|
7964
|
+
const [clickedPosition, setClickedPosition] = useState86(null);
|
|
7965
|
+
const handleMapClick = useCallback94((lat, lng) => {
|
|
7966
7966
|
if (showClickedPin) {
|
|
7967
7967
|
setClickedPosition({ lat, lng });
|
|
7968
7968
|
}
|
|
@@ -7971,7 +7971,7 @@ var init_MapView = __esm({
|
|
|
7971
7971
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
7972
7972
|
}
|
|
7973
7973
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
7974
|
-
const handleMarkerClick =
|
|
7974
|
+
const handleMarkerClick = useCallback94((marker) => {
|
|
7975
7975
|
onMarkerClick?.(marker);
|
|
7976
7976
|
if (markerClickEvent) {
|
|
7977
7977
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -18601,7 +18601,290 @@ function formatValue(value, format) {
|
|
|
18601
18601
|
return String(value);
|
|
18602
18602
|
}
|
|
18603
18603
|
}
|
|
18604
|
-
|
|
18604
|
+
function DataGrid({
|
|
18605
|
+
entity,
|
|
18606
|
+
fields: fieldsProp,
|
|
18607
|
+
columns: columnsProp,
|
|
18608
|
+
itemActions,
|
|
18609
|
+
cols,
|
|
18610
|
+
gap = "md",
|
|
18611
|
+
minCardWidth = 280,
|
|
18612
|
+
className,
|
|
18613
|
+
isLoading = false,
|
|
18614
|
+
error = null,
|
|
18615
|
+
imageField,
|
|
18616
|
+
selectable = false,
|
|
18617
|
+
selectionEvent,
|
|
18618
|
+
infiniteScroll,
|
|
18619
|
+
loadMoreEvent,
|
|
18620
|
+
hasMore,
|
|
18621
|
+
children,
|
|
18622
|
+
pageSize = 0
|
|
18623
|
+
}) {
|
|
18624
|
+
const eventBus = useEventBus();
|
|
18625
|
+
const { t } = useTranslate();
|
|
18626
|
+
const [selectedIds, setSelectedIds] = React115.useState(/* @__PURE__ */ new Set());
|
|
18627
|
+
const [visibleCount, setVisibleCount] = React115.useState(pageSize || Infinity);
|
|
18628
|
+
const fields = fieldsProp ?? columnsProp ?? [];
|
|
18629
|
+
const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
18630
|
+
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
18631
|
+
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
18632
|
+
const toggleSelection = React115.useCallback((id) => {
|
|
18633
|
+
setSelectedIds((prev) => {
|
|
18634
|
+
const next = new Set(prev);
|
|
18635
|
+
if (next.has(id)) next.delete(id);
|
|
18636
|
+
else next.add(id);
|
|
18637
|
+
if (selectionEvent) {
|
|
18638
|
+
const payload = { selectedIds: Array.from(next) };
|
|
18639
|
+
eventBus.emit(`UI:${selectionEvent}`, payload);
|
|
18640
|
+
}
|
|
18641
|
+
return next;
|
|
18642
|
+
});
|
|
18643
|
+
}, [selectionEvent, eventBus]);
|
|
18644
|
+
const toggleAll = React115.useCallback(() => {
|
|
18645
|
+
setSelectedIds((prev) => {
|
|
18646
|
+
const allIds2 = data.map((item, i) => item.id || String(i));
|
|
18647
|
+
const allSelected2 = allIds2.length > 0 && allIds2.every((id) => prev.has(id));
|
|
18648
|
+
const next = allSelected2 ? /* @__PURE__ */ new Set() : new Set(allIds2);
|
|
18649
|
+
if (selectionEvent) {
|
|
18650
|
+
const payload = { selectedIds: Array.from(next) };
|
|
18651
|
+
eventBus.emit(`UI:${selectionEvent}`, payload);
|
|
18652
|
+
}
|
|
18653
|
+
return next;
|
|
18654
|
+
});
|
|
18655
|
+
}, [data, selectionEvent, eventBus]);
|
|
18656
|
+
const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
|
|
18657
|
+
const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
|
|
18658
|
+
const bodyFields = fields.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
|
|
18659
|
+
const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
|
|
18660
|
+
const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
|
|
18661
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
18662
|
+
e.stopPropagation();
|
|
18663
|
+
const payload = {
|
|
18664
|
+
id: itemData.id,
|
|
18665
|
+
row: itemData
|
|
18666
|
+
};
|
|
18667
|
+
eventBus.emit(`UI:${action.event}`, payload);
|
|
18668
|
+
};
|
|
18669
|
+
const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
|
|
18670
|
+
const colsClass = cols ? {
|
|
18671
|
+
1: "grid-cols-1",
|
|
18672
|
+
2: "sm:grid-cols-2",
|
|
18673
|
+
3: "sm:grid-cols-2 lg:grid-cols-3",
|
|
18674
|
+
4: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
|
|
18675
|
+
5: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5",
|
|
18676
|
+
6: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6"
|
|
18677
|
+
}[cols] : void 0;
|
|
18678
|
+
if (isLoading) {
|
|
18679
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
18680
|
+
}
|
|
18681
|
+
if (error) {
|
|
18682
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
18683
|
+
}
|
|
18684
|
+
if (data.length === 0) {
|
|
18685
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
18686
|
+
}
|
|
18687
|
+
const hasRenderProp = typeof children === "function";
|
|
18688
|
+
const allIds = data.map((item, i) => item.id || String(i));
|
|
18689
|
+
const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.has(id));
|
|
18690
|
+
const someSelected = selectedIds.size > 0;
|
|
18691
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
18692
|
+
selectable && someSelected && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "items-center px-2 py-2 bg-muted rounded-sm", children: [
|
|
18693
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18694
|
+
"input",
|
|
18695
|
+
{
|
|
18696
|
+
type: "checkbox",
|
|
18697
|
+
checked: allSelected,
|
|
18698
|
+
onChange: toggleAll,
|
|
18699
|
+
className: "w-4 h-4 accent-primary",
|
|
18700
|
+
"aria-label": "Select all"
|
|
18701
|
+
}
|
|
18702
|
+
),
|
|
18703
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "font-semibold", children: [
|
|
18704
|
+
selectedIds.size,
|
|
18705
|
+
" ",
|
|
18706
|
+
t("common.selected") || "selected"
|
|
18707
|
+
] })
|
|
18708
|
+
] }),
|
|
18709
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18710
|
+
Box,
|
|
18711
|
+
{
|
|
18712
|
+
className: cn("grid", gapStyles6[gap], colsClass, className),
|
|
18713
|
+
style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
|
|
18714
|
+
children: data.map((item, index) => {
|
|
18715
|
+
const itemData = item;
|
|
18716
|
+
const id = itemData.id || String(index);
|
|
18717
|
+
const isSelected = selectedIds.has(id);
|
|
18718
|
+
if (hasRenderProp) {
|
|
18719
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18720
|
+
Box,
|
|
18721
|
+
{
|
|
18722
|
+
"data-entity-row": true,
|
|
18723
|
+
"data-entity-id": id,
|
|
18724
|
+
className: cn(
|
|
18725
|
+
"bg-card rounded-lg",
|
|
18726
|
+
"border border-border",
|
|
18727
|
+
"shadow-sm hover:shadow-lg",
|
|
18728
|
+
"hover:border-primary transition-all",
|
|
18729
|
+
"p-4",
|
|
18730
|
+
isSelected && "ring-2 ring-primary border-primary"
|
|
18731
|
+
),
|
|
18732
|
+
children: children(itemData, index)
|
|
18733
|
+
},
|
|
18734
|
+
id
|
|
18735
|
+
);
|
|
18736
|
+
}
|
|
18737
|
+
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
18738
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18739
|
+
Box,
|
|
18740
|
+
{
|
|
18741
|
+
"data-entity-row": true,
|
|
18742
|
+
"data-entity-id": id,
|
|
18743
|
+
className: cn(
|
|
18744
|
+
"bg-card rounded-lg",
|
|
18745
|
+
"border border-border",
|
|
18746
|
+
"shadow-sm hover:shadow-lg",
|
|
18747
|
+
"hover:border-primary transition-all",
|
|
18748
|
+
"flex flex-col",
|
|
18749
|
+
isSelected && "ring-2 ring-primary border-primary"
|
|
18750
|
+
),
|
|
18751
|
+
children: [
|
|
18752
|
+
imageField && (() => {
|
|
18753
|
+
const imgUrl = getNestedValue(itemData, imageField);
|
|
18754
|
+
if (!imgUrl || typeof imgUrl !== "string") return null;
|
|
18755
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-lg", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
18756
|
+
"img",
|
|
18757
|
+
{
|
|
18758
|
+
src: imgUrl,
|
|
18759
|
+
alt: titleValue !== void 0 ? String(titleValue) : "",
|
|
18760
|
+
className: "w-full h-full object-cover",
|
|
18761
|
+
loading: "lazy"
|
|
18762
|
+
}
|
|
18763
|
+
) });
|
|
18764
|
+
})(),
|
|
18765
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
18766
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18767
|
+
"input",
|
|
18768
|
+
{
|
|
18769
|
+
type: "checkbox",
|
|
18770
|
+
checked: isSelected,
|
|
18771
|
+
onChange: () => toggleSelection(id),
|
|
18772
|
+
onClick: (e) => e.stopPropagation(),
|
|
18773
|
+
className: "w-4 h-4 mt-1 flex-shrink-0 accent-primary",
|
|
18774
|
+
"aria-label": `Select ${titleValue !== void 0 ? String(titleValue) : "item"}`
|
|
18775
|
+
}
|
|
18776
|
+
),
|
|
18777
|
+
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
|
|
18778
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18779
|
+
titleField?.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: titleField.icon, size: "sm", className: "text-primary flex-shrink-0" }),
|
|
18780
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18781
|
+
Typography,
|
|
18782
|
+
{
|
|
18783
|
+
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
18784
|
+
className: "font-semibold truncate",
|
|
18785
|
+
children: String(titleValue)
|
|
18786
|
+
}
|
|
18787
|
+
)
|
|
18788
|
+
] }),
|
|
18789
|
+
badgeFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
18790
|
+
const val = getNestedValue(itemData, field.name);
|
|
18791
|
+
if (val === void 0 || val === null) return null;
|
|
18792
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18793
|
+
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs" }),
|
|
18794
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
|
|
18795
|
+
] }, field.name);
|
|
18796
|
+
}) })
|
|
18797
|
+
] }),
|
|
18798
|
+
dangerActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18799
|
+
Button,
|
|
18800
|
+
{
|
|
18801
|
+
variant: "ghost",
|
|
18802
|
+
size: "sm",
|
|
18803
|
+
onClick: handleActionClick(action, itemData),
|
|
18804
|
+
"data-testid": `action-${action.event}`,
|
|
18805
|
+
className: "text-error hover:bg-error/10 px-2",
|
|
18806
|
+
children: [
|
|
18807
|
+
action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs" }),
|
|
18808
|
+
action.label
|
|
18809
|
+
]
|
|
18810
|
+
},
|
|
18811
|
+
idx
|
|
18812
|
+
)) })
|
|
18813
|
+
] }) }),
|
|
18814
|
+
bodyFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
|
|
18815
|
+
const value = getNestedValue(itemData, field.name);
|
|
18816
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
18817
|
+
if (field.format === "boolean") {
|
|
18818
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
18819
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18820
|
+
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
18821
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
18822
|
+
] }),
|
|
18823
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
|
|
18824
|
+
] }, field.name);
|
|
18825
|
+
}
|
|
18826
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
18827
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18828
|
+
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
18829
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
18830
|
+
] }),
|
|
18831
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18832
|
+
Typography,
|
|
18833
|
+
{
|
|
18834
|
+
variant: field.variant === "caption" ? "caption" : "small",
|
|
18835
|
+
className: "text-right truncate max-w-[60%]",
|
|
18836
|
+
children: formatValue(value, field.format)
|
|
18837
|
+
}
|
|
18838
|
+
)
|
|
18839
|
+
] }, field.name);
|
|
18840
|
+
}) }) }),
|
|
18841
|
+
primaryActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18842
|
+
Button,
|
|
18843
|
+
{
|
|
18844
|
+
variant: action.variant === "primary" ? "primary" : "ghost",
|
|
18845
|
+
size: "sm",
|
|
18846
|
+
onClick: handleActionClick(action, itemData),
|
|
18847
|
+
"data-testid": `action-${action.event}`,
|
|
18848
|
+
children: [
|
|
18849
|
+
action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
18850
|
+
action.label
|
|
18851
|
+
]
|
|
18852
|
+
},
|
|
18853
|
+
idx
|
|
18854
|
+
)) }) })
|
|
18855
|
+
]
|
|
18856
|
+
},
|
|
18857
|
+
id
|
|
18858
|
+
);
|
|
18859
|
+
})
|
|
18860
|
+
}
|
|
18861
|
+
),
|
|
18862
|
+
hasMoreLocal && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18863
|
+
Button,
|
|
18864
|
+
{
|
|
18865
|
+
variant: "ghost",
|
|
18866
|
+
size: "sm",
|
|
18867
|
+
onClick: () => setVisibleCount((prev) => prev + (pageSize || 5)),
|
|
18868
|
+
children: [
|
|
18869
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
18870
|
+
t("common.showMore"),
|
|
18871
|
+
" (",
|
|
18872
|
+
allData.length - visibleCount,
|
|
18873
|
+
" remaining)"
|
|
18874
|
+
]
|
|
18875
|
+
}
|
|
18876
|
+
) }),
|
|
18877
|
+
infiniteScroll && loadMoreEvent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18878
|
+
InfiniteScrollSentinel,
|
|
18879
|
+
{
|
|
18880
|
+
loadMoreEvent,
|
|
18881
|
+
isLoading,
|
|
18882
|
+
hasMore
|
|
18883
|
+
}
|
|
18884
|
+
)
|
|
18885
|
+
] });
|
|
18886
|
+
}
|
|
18887
|
+
var gapStyles6;
|
|
18605
18888
|
var init_DataGrid = __esm({
|
|
18606
18889
|
"components/molecules/DataGrid.tsx"() {
|
|
18607
18890
|
"use client";
|
|
@@ -18623,264 +18906,321 @@ var init_DataGrid = __esm({
|
|
|
18623
18906
|
lg: "gap-6",
|
|
18624
18907
|
xl: "gap-8"
|
|
18625
18908
|
};
|
|
18626
|
-
DataGrid =
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
|
|
18632
|
-
|
|
18633
|
-
|
|
18634
|
-
|
|
18635
|
-
|
|
18636
|
-
|
|
18637
|
-
|
|
18638
|
-
|
|
18639
|
-
|
|
18640
|
-
|
|
18641
|
-
|
|
18642
|
-
|
|
18643
|
-
|
|
18644
|
-
|
|
18645
|
-
|
|
18646
|
-
|
|
18647
|
-
|
|
18648
|
-
|
|
18649
|
-
|
|
18650
|
-
|
|
18651
|
-
|
|
18652
|
-
|
|
18653
|
-
|
|
18654
|
-
|
|
18655
|
-
|
|
18656
|
-
|
|
18657
|
-
|
|
18658
|
-
|
|
18659
|
-
|
|
18660
|
-
|
|
18661
|
-
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
18665
|
-
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
|
|
18670
|
-
|
|
18671
|
-
|
|
18672
|
-
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18680
|
-
|
|
18681
|
-
|
|
18682
|
-
|
|
18683
|
-
|
|
18684
|
-
|
|
18685
|
-
|
|
18686
|
-
|
|
18687
|
-
|
|
18688
|
-
|
|
18689
|
-
|
|
18690
|
-
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
|
|
18694
|
-
|
|
18695
|
-
|
|
18696
|
-
|
|
18697
|
-
|
|
18698
|
-
|
|
18699
|
-
|
|
18700
|
-
|
|
18701
|
-
|
|
18702
|
-
|
|
18703
|
-
|
|
18704
|
-
|
|
18705
|
-
|
|
18706
|
-
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
|
|
18710
|
-
|
|
18711
|
-
|
|
18712
|
-
|
|
18713
|
-
|
|
18714
|
-
|
|
18715
|
-
|
|
18716
|
-
|
|
18717
|
-
|
|
18718
|
-
|
|
18719
|
-
|
|
18720
|
-
|
|
18721
|
-
|
|
18722
|
-
|
|
18723
|
-
|
|
18724
|
-
|
|
18725
|
-
|
|
18726
|
-
|
|
18727
|
-
|
|
18728
|
-
|
|
18729
|
-
|
|
18730
|
-
|
|
18731
|
-
|
|
18909
|
+
DataGrid.displayName = "DataGrid";
|
|
18910
|
+
}
|
|
18911
|
+
});
|
|
18912
|
+
function fieldLabel3(key) {
|
|
18913
|
+
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
18914
|
+
}
|
|
18915
|
+
function statusVariant3(value) {
|
|
18916
|
+
const v = value.toLowerCase();
|
|
18917
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online"].includes(v)) return "success";
|
|
18918
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warning"].includes(v)) return "warning";
|
|
18919
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
18920
|
+
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
18921
|
+
return "default";
|
|
18922
|
+
}
|
|
18923
|
+
function formatDate3(value) {
|
|
18924
|
+
if (!value) return "";
|
|
18925
|
+
const d = new Date(String(value));
|
|
18926
|
+
if (isNaN(d.getTime())) return String(value);
|
|
18927
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
18928
|
+
}
|
|
18929
|
+
function formatValue2(value, format) {
|
|
18930
|
+
if (value === void 0 || value === null) return "";
|
|
18931
|
+
switch (format) {
|
|
18932
|
+
case "date":
|
|
18933
|
+
return formatDate3(value);
|
|
18934
|
+
case "currency":
|
|
18935
|
+
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
18936
|
+
case "number":
|
|
18937
|
+
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
18938
|
+
case "percent":
|
|
18939
|
+
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
18940
|
+
case "boolean":
|
|
18941
|
+
return value ? "Yes" : "No";
|
|
18942
|
+
default:
|
|
18943
|
+
return String(value);
|
|
18944
|
+
}
|
|
18945
|
+
}
|
|
18946
|
+
function groupData(items, field) {
|
|
18947
|
+
const groups = /* @__PURE__ */ new Map();
|
|
18948
|
+
for (const item of items) {
|
|
18949
|
+
const key = String(getNestedValue(item, field) ?? "");
|
|
18950
|
+
const group = groups.get(key);
|
|
18951
|
+
if (group) group.push(item);
|
|
18952
|
+
else groups.set(key, [item]);
|
|
18953
|
+
}
|
|
18954
|
+
return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
|
|
18955
|
+
}
|
|
18956
|
+
function DataList({
|
|
18957
|
+
entity,
|
|
18958
|
+
fields: fieldsProp,
|
|
18959
|
+
columns: columnsProp,
|
|
18960
|
+
itemActions,
|
|
18961
|
+
gap = "none",
|
|
18962
|
+
variant = "default",
|
|
18963
|
+
groupBy,
|
|
18964
|
+
senderField,
|
|
18965
|
+
currentUser,
|
|
18966
|
+
className,
|
|
18967
|
+
isLoading = false,
|
|
18968
|
+
error = null,
|
|
18969
|
+
// Gesture props: reorderable, swipeLeftEvent, swipeRightEvent, longPressEvent
|
|
18970
|
+
// are consumed by the compiler to wrap items in SwipeableRow/SortableList.
|
|
18971
|
+
// DataList destructures them here to prevent DOM passthrough.
|
|
18972
|
+
reorderable: _reorderable,
|
|
18973
|
+
reorderEvent: _reorderEvent,
|
|
18974
|
+
swipeLeftEvent: _swipeLeftEvent,
|
|
18975
|
+
swipeLeftActions: _swipeLeftActions,
|
|
18976
|
+
swipeRightEvent: _swipeRightEvent,
|
|
18977
|
+
swipeRightActions: _swipeRightActions,
|
|
18978
|
+
longPressEvent: _longPressEvent,
|
|
18979
|
+
infiniteScroll,
|
|
18980
|
+
loadMoreEvent,
|
|
18981
|
+
hasMore,
|
|
18982
|
+
children,
|
|
18983
|
+
pageSize = 5
|
|
18984
|
+
}) {
|
|
18985
|
+
const eventBus = useEventBus();
|
|
18986
|
+
const { t } = useTranslate();
|
|
18987
|
+
const [visibleCount, setVisibleCount] = React115__namespace.default.useState(pageSize || Infinity);
|
|
18988
|
+
const fields = fieldsProp ?? columnsProp ?? [];
|
|
18989
|
+
const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
18990
|
+
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
18991
|
+
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
18992
|
+
const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
|
|
18993
|
+
const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
|
|
18994
|
+
const progressFields = fields.filter((f3) => f3.variant === "progress");
|
|
18995
|
+
const bodyFields = fields.filter(
|
|
18996
|
+
(f3) => f3 !== titleField && !badgeFields.includes(f3) && !progressFields.includes(f3)
|
|
18997
|
+
);
|
|
18998
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
18999
|
+
e.stopPropagation();
|
|
19000
|
+
const payload = {
|
|
19001
|
+
id: itemData.id,
|
|
19002
|
+
row: itemData
|
|
19003
|
+
};
|
|
19004
|
+
eventBus.emit(`UI:${action.event}`, payload);
|
|
19005
|
+
};
|
|
19006
|
+
if (isLoading) {
|
|
19007
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
19008
|
+
}
|
|
19009
|
+
if (error) {
|
|
19010
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
19011
|
+
}
|
|
19012
|
+
if (data.length === 0) {
|
|
19013
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
19014
|
+
}
|
|
19015
|
+
const gapClass = {
|
|
19016
|
+
none: "",
|
|
19017
|
+
sm: "gap-1",
|
|
19018
|
+
md: "gap-2",
|
|
19019
|
+
lg: "gap-4"
|
|
19020
|
+
}[gap];
|
|
19021
|
+
const isCard = variant === "card";
|
|
19022
|
+
const isCompact = variant === "compact";
|
|
19023
|
+
const isMessage = variant === "message";
|
|
19024
|
+
if (isMessage) {
|
|
19025
|
+
const items2 = data.map((item) => item);
|
|
19026
|
+
const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
|
|
19027
|
+
const contentField = titleField?.name ?? fields[0]?.name ?? "";
|
|
19028
|
+
return /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React115__namespace.default.Fragment, { children: [
|
|
19029
|
+
group.label && /* @__PURE__ */ jsxRuntime.jsx(Divider, { label: group.label, className: "my-2" }),
|
|
19030
|
+
group.items.map((itemData, index) => {
|
|
19031
|
+
const id = itemData.id || `${gi}-${index}`;
|
|
19032
|
+
const sender = senderField ? String(getNestedValue(itemData, senderField) ?? "") : "";
|
|
19033
|
+
const isSent = Boolean(currentUser && sender === currentUser);
|
|
19034
|
+
const content = getNestedValue(itemData, contentField);
|
|
19035
|
+
const timestampField = fields.find((f3) => f3.format === "date");
|
|
19036
|
+
const timestamp = timestampField ? getNestedValue(itemData, timestampField.name) : null;
|
|
19037
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18732
19038
|
Box,
|
|
18733
19039
|
{
|
|
18734
|
-
className: cn(
|
|
18735
|
-
|
|
18736
|
-
|
|
18737
|
-
|
|
18738
|
-
|
|
18739
|
-
|
|
18740
|
-
|
|
18741
|
-
|
|
18742
|
-
|
|
18743
|
-
|
|
18744
|
-
|
|
18745
|
-
|
|
18746
|
-
|
|
18747
|
-
|
|
18748
|
-
|
|
18749
|
-
|
|
18750
|
-
|
|
18751
|
-
"
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
19040
|
+
className: cn(
|
|
19041
|
+
"flex px-4",
|
|
19042
|
+
isSent ? "justify-end" : "justify-start"
|
|
19043
|
+
),
|
|
19044
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19045
|
+
Box,
|
|
19046
|
+
{
|
|
19047
|
+
className: cn(
|
|
19048
|
+
"max-w-[75%] px-4 py-2",
|
|
19049
|
+
isSent ? "bg-primary text-primary-foreground rounded-2xl rounded-br-sm" : "bg-muted text-foreground rounded-2xl rounded-bl-sm"
|
|
19050
|
+
),
|
|
19051
|
+
children: [
|
|
19052
|
+
!isSent && senderField && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "font-semibold mb-0.5", children: sender }),
|
|
19053
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: content !== void 0 && content !== null ? String(content) : "" }),
|
|
19054
|
+
timestamp != null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
19055
|
+
Typography,
|
|
19056
|
+
{
|
|
19057
|
+
variant: "caption",
|
|
19058
|
+
className: cn(
|
|
19059
|
+
"mt-1 text-[0.65rem]",
|
|
19060
|
+
isSent ? "opacity-70" : "text-muted-foreground"
|
|
19061
|
+
),
|
|
19062
|
+
children: formatDate3(timestamp)
|
|
19063
|
+
}
|
|
19064
|
+
) : null
|
|
19065
|
+
]
|
|
18758
19066
|
}
|
|
18759
|
-
|
|
18760
|
-
|
|
18761
|
-
|
|
19067
|
+
)
|
|
19068
|
+
},
|
|
19069
|
+
id
|
|
19070
|
+
);
|
|
19071
|
+
})
|
|
19072
|
+
] }, gi)) });
|
|
19073
|
+
}
|
|
19074
|
+
const hasRenderProp = typeof children === "function";
|
|
19075
|
+
const items = data.map((item) => item);
|
|
19076
|
+
const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
|
|
19077
|
+
const renderItem = (itemData, index, isLast) => {
|
|
19078
|
+
if (hasRenderProp) {
|
|
19079
|
+
const id2 = itemData.id || String(index);
|
|
19080
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, children: [
|
|
19081
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
19082
|
+
Box,
|
|
19083
|
+
{
|
|
19084
|
+
className: cn(
|
|
19085
|
+
"group flex items-center gap-4 transition-all duration-200",
|
|
19086
|
+
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
19087
|
+
"hover:bg-muted/80",
|
|
19088
|
+
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
19089
|
+
),
|
|
19090
|
+
children: [
|
|
19091
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
|
|
19092
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
19093
|
+
HStack,
|
|
18762
19094
|
{
|
|
18763
|
-
"
|
|
18764
|
-
"
|
|
18765
|
-
|
|
18766
|
-
|
|
18767
|
-
|
|
18768
|
-
|
|
18769
|
-
|
|
18770
|
-
|
|
18771
|
-
|
|
18772
|
-
|
|
18773
|
-
|
|
18774
|
-
imageField && (() => {
|
|
18775
|
-
const imgUrl = getNestedValue(itemData, imageField);
|
|
18776
|
-
if (!imgUrl || typeof imgUrl !== "string") return null;
|
|
18777
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-lg", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
18778
|
-
"img",
|
|
18779
|
-
{
|
|
18780
|
-
src: imgUrl,
|
|
18781
|
-
alt: titleValue !== void 0 ? String(titleValue) : "",
|
|
18782
|
-
className: "w-full h-full object-cover",
|
|
18783
|
-
loading: "lazy"
|
|
18784
|
-
}
|
|
18785
|
-
) });
|
|
18786
|
-
})(),
|
|
18787
|
-
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
18788
|
-
selectable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18789
|
-
"input",
|
|
18790
|
-
{
|
|
18791
|
-
type: "checkbox",
|
|
18792
|
-
checked: isSelected,
|
|
18793
|
-
onChange: () => toggleSelection(id),
|
|
18794
|
-
onClick: (e) => e.stopPropagation(),
|
|
18795
|
-
className: "w-4 h-4 mt-1 flex-shrink-0 accent-primary",
|
|
18796
|
-
"aria-label": `Select ${titleValue !== void 0 ? String(titleValue) : "item"}`
|
|
18797
|
-
}
|
|
19095
|
+
gap: "xs",
|
|
19096
|
+
className: "flex-shrink-0",
|
|
19097
|
+
children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19098
|
+
Button,
|
|
19099
|
+
{
|
|
19100
|
+
variant: action.variant ?? "ghost",
|
|
19101
|
+
size: "sm",
|
|
19102
|
+
onClick: handleActionClick(action, itemData),
|
|
19103
|
+
"data-testid": `action-${action.event}`,
|
|
19104
|
+
className: cn(
|
|
19105
|
+
action.variant === "danger" && "text-error hover:bg-error/10"
|
|
18798
19106
|
),
|
|
18799
|
-
|
|
18800
|
-
|
|
18801
|
-
|
|
18802
|
-
|
|
18803
|
-
|
|
18804
|
-
|
|
18805
|
-
|
|
18806
|
-
|
|
18807
|
-
|
|
18808
|
-
|
|
18809
|
-
)
|
|
18810
|
-
] }),
|
|
18811
|
-
badgeFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
18812
|
-
const val = getNestedValue(itemData, field.name);
|
|
18813
|
-
if (val === void 0 || val === null) return null;
|
|
18814
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18815
|
-
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs" }),
|
|
18816
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
|
|
18817
|
-
] }, field.name);
|
|
18818
|
-
}) })
|
|
18819
|
-
] }),
|
|
18820
|
-
dangerActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18821
|
-
Button,
|
|
18822
|
-
{
|
|
18823
|
-
variant: "ghost",
|
|
18824
|
-
size: "sm",
|
|
18825
|
-
onClick: handleActionClick(action, itemData),
|
|
18826
|
-
"data-testid": `action-${action.event}`,
|
|
18827
|
-
className: "text-error hover:bg-error/10 px-2",
|
|
18828
|
-
children: [
|
|
18829
|
-
action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs" }),
|
|
18830
|
-
action.label
|
|
18831
|
-
]
|
|
18832
|
-
},
|
|
18833
|
-
idx
|
|
18834
|
-
)) })
|
|
18835
|
-
] }) }),
|
|
18836
|
-
bodyFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
|
|
18837
|
-
const value = getNestedValue(itemData, field.name);
|
|
18838
|
-
if (value === void 0 || value === null || value === "") return null;
|
|
18839
|
-
if (field.format === "boolean") {
|
|
18840
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
18841
|
-
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18842
|
-
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
18843
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
18844
|
-
] }),
|
|
18845
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
|
|
18846
|
-
] }, field.name);
|
|
18847
|
-
}
|
|
18848
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
18849
|
-
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18850
|
-
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
18851
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
18852
|
-
] }),
|
|
18853
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18854
|
-
Typography,
|
|
18855
|
-
{
|
|
18856
|
-
variant: field.variant === "caption" ? "caption" : "small",
|
|
18857
|
-
className: "text-right truncate max-w-[60%]",
|
|
18858
|
-
children: formatValue(value, field.format)
|
|
18859
|
-
}
|
|
18860
|
-
)
|
|
18861
|
-
] }, field.name);
|
|
18862
|
-
}) }) }),
|
|
18863
|
-
primaryActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18864
|
-
Button,
|
|
18865
|
-
{
|
|
18866
|
-
variant: action.variant === "primary" ? "primary" : "ghost",
|
|
18867
|
-
size: "sm",
|
|
18868
|
-
onClick: handleActionClick(action, itemData),
|
|
18869
|
-
"data-testid": `action-${action.event}`,
|
|
18870
|
-
children: [
|
|
18871
|
-
action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
18872
|
-
action.label
|
|
18873
|
-
]
|
|
18874
|
-
},
|
|
18875
|
-
idx
|
|
18876
|
-
)) }) })
|
|
18877
|
-
]
|
|
18878
|
-
},
|
|
18879
|
-
id
|
|
18880
|
-
);
|
|
18881
|
-
})
|
|
19107
|
+
children: [
|
|
19108
|
+
action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
19109
|
+
action.label
|
|
19110
|
+
]
|
|
19111
|
+
},
|
|
19112
|
+
idx
|
|
19113
|
+
))
|
|
19114
|
+
}
|
|
19115
|
+
)
|
|
19116
|
+
]
|
|
18882
19117
|
}
|
|
18883
19118
|
),
|
|
19119
|
+
isCard && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mx-6 border-b border-border/40" })
|
|
19120
|
+
] }, id2);
|
|
19121
|
+
}
|
|
19122
|
+
const id = itemData.id || String(index);
|
|
19123
|
+
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
19124
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id, children: [
|
|
19125
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
19126
|
+
Box,
|
|
19127
|
+
{
|
|
19128
|
+
className: cn(
|
|
19129
|
+
"group flex items-center gap-4 transition-all duration-200",
|
|
19130
|
+
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
19131
|
+
"hover:bg-muted/80",
|
|
19132
|
+
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
19133
|
+
),
|
|
19134
|
+
children: [
|
|
19135
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex-1 min-w-0", children: [
|
|
19136
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "items-center", children: [
|
|
19137
|
+
titleField?.icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
19138
|
+
Icon,
|
|
19139
|
+
{
|
|
19140
|
+
name: titleField.icon,
|
|
19141
|
+
size: isCompact ? "xs" : "sm",
|
|
19142
|
+
className: "text-primary flex-shrink-0"
|
|
19143
|
+
}
|
|
19144
|
+
),
|
|
19145
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
19146
|
+
Typography,
|
|
19147
|
+
{
|
|
19148
|
+
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
19149
|
+
className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
|
|
19150
|
+
children: String(titleValue)
|
|
19151
|
+
}
|
|
19152
|
+
),
|
|
19153
|
+
badgeFields.map((field) => {
|
|
19154
|
+
const val = getNestedValue(itemData, field.name);
|
|
19155
|
+
if (val === void 0 || val === null) return null;
|
|
19156
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
19157
|
+
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs" }),
|
|
19158
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children: String(val) })
|
|
19159
|
+
] }, field.name);
|
|
19160
|
+
})
|
|
19161
|
+
] }),
|
|
19162
|
+
bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
|
|
19163
|
+
const value = getNestedValue(itemData, field.name);
|
|
19164
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
19165
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
19166
|
+
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
19167
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", color: "secondary", children: [
|
|
19168
|
+
field.label ?? fieldLabel3(field.name),
|
|
19169
|
+
":"
|
|
19170
|
+
] }),
|
|
19171
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", children: formatValue2(value, field.format) })
|
|
19172
|
+
] }, field.name);
|
|
19173
|
+
}) }),
|
|
19174
|
+
progressFields.map((field) => {
|
|
19175
|
+
const value = getNestedValue(itemData, field.name);
|
|
19176
|
+
if (typeof value !== "number") return null;
|
|
19177
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "mt-2 max-w-xs", children: [
|
|
19178
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center mb-1", children: [
|
|
19179
|
+
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
19180
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel3(field.name) })
|
|
19181
|
+
] }),
|
|
19182
|
+
/* @__PURE__ */ jsxRuntime.jsx(ProgressBar, { value, max: 100 })
|
|
19183
|
+
] }, field.name);
|
|
19184
|
+
})
|
|
19185
|
+
] }),
|
|
19186
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19187
|
+
Button,
|
|
19188
|
+
{
|
|
19189
|
+
variant: action.variant ?? "ghost",
|
|
19190
|
+
size: "sm",
|
|
19191
|
+
onClick: handleActionClick(action, itemData),
|
|
19192
|
+
"data-testid": `action-${action.event}`,
|
|
19193
|
+
className: cn(
|
|
19194
|
+
action.variant === "danger" && "text-error hover:bg-error/10"
|
|
19195
|
+
),
|
|
19196
|
+
children: [
|
|
19197
|
+
action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
19198
|
+
action.label
|
|
19199
|
+
]
|
|
19200
|
+
},
|
|
19201
|
+
idx
|
|
19202
|
+
)) })
|
|
19203
|
+
]
|
|
19204
|
+
}
|
|
19205
|
+
),
|
|
19206
|
+
isCard && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mx-6 border-b border-border/40" })
|
|
19207
|
+
] }, id);
|
|
19208
|
+
};
|
|
19209
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19210
|
+
Box,
|
|
19211
|
+
{
|
|
19212
|
+
className: cn(
|
|
19213
|
+
isCard && "bg-card rounded-xl border border-border shadow-lg overflow-hidden",
|
|
19214
|
+
!isCard && gapClass,
|
|
19215
|
+
className
|
|
19216
|
+
),
|
|
19217
|
+
children: [
|
|
19218
|
+
groups.map((group, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React115__namespace.default.Fragment, { children: [
|
|
19219
|
+
group.label && /* @__PURE__ */ jsxRuntime.jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
|
|
19220
|
+
group.items.map(
|
|
19221
|
+
(itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
|
|
19222
|
+
)
|
|
19223
|
+
] }, gi)),
|
|
18884
19224
|
hasMoreLocal && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18885
19225
|
Button,
|
|
18886
19226
|
{
|
|
@@ -18904,56 +19244,10 @@ var init_DataGrid = __esm({
|
|
|
18904
19244
|
hasMore
|
|
18905
19245
|
}
|
|
18906
19246
|
)
|
|
18907
|
-
]
|
|
18908
|
-
}
|
|
18909
|
-
|
|
18910
|
-
}
|
|
18911
|
-
});
|
|
18912
|
-
function fieldLabel3(key) {
|
|
18913
|
-
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
18914
|
-
}
|
|
18915
|
-
function statusVariant3(value) {
|
|
18916
|
-
const v = value.toLowerCase();
|
|
18917
|
-
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online"].includes(v)) return "success";
|
|
18918
|
-
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warning"].includes(v)) return "warning";
|
|
18919
|
-
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
18920
|
-
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
18921
|
-
return "default";
|
|
18922
|
-
}
|
|
18923
|
-
function formatDate3(value) {
|
|
18924
|
-
if (!value) return "";
|
|
18925
|
-
const d = new Date(String(value));
|
|
18926
|
-
if (isNaN(d.getTime())) return String(value);
|
|
18927
|
-
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
18928
|
-
}
|
|
18929
|
-
function formatValue2(value, format) {
|
|
18930
|
-
if (value === void 0 || value === null) return "";
|
|
18931
|
-
switch (format) {
|
|
18932
|
-
case "date":
|
|
18933
|
-
return formatDate3(value);
|
|
18934
|
-
case "currency":
|
|
18935
|
-
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
18936
|
-
case "number":
|
|
18937
|
-
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
18938
|
-
case "percent":
|
|
18939
|
-
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
18940
|
-
case "boolean":
|
|
18941
|
-
return value ? "Yes" : "No";
|
|
18942
|
-
default:
|
|
18943
|
-
return String(value);
|
|
18944
|
-
}
|
|
18945
|
-
}
|
|
18946
|
-
function groupData(items, field) {
|
|
18947
|
-
const groups = /* @__PURE__ */ new Map();
|
|
18948
|
-
for (const item of items) {
|
|
18949
|
-
const key = String(getNestedValue(item, field) ?? "");
|
|
18950
|
-
const group = groups.get(key);
|
|
18951
|
-
if (group) group.push(item);
|
|
18952
|
-
else groups.set(key, [item]);
|
|
18953
|
-
}
|
|
18954
|
-
return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
|
|
19247
|
+
]
|
|
19248
|
+
}
|
|
19249
|
+
);
|
|
18955
19250
|
}
|
|
18956
|
-
var DataList;
|
|
18957
19251
|
var init_DataList = __esm({
|
|
18958
19252
|
"components/molecules/DataList.tsx"() {
|
|
18959
19253
|
"use client";
|
|
@@ -18970,301 +19264,6 @@ var init_DataList = __esm({
|
|
|
18970
19264
|
init_ProgressBar();
|
|
18971
19265
|
init_Divider();
|
|
18972
19266
|
init_InfiniteScrollSentinel();
|
|
18973
|
-
DataList = ({
|
|
18974
|
-
entity,
|
|
18975
|
-
fields: fieldsProp,
|
|
18976
|
-
columns: columnsProp,
|
|
18977
|
-
itemActions,
|
|
18978
|
-
gap = "none",
|
|
18979
|
-
variant = "default",
|
|
18980
|
-
groupBy,
|
|
18981
|
-
senderField,
|
|
18982
|
-
currentUser,
|
|
18983
|
-
className,
|
|
18984
|
-
isLoading = false,
|
|
18985
|
-
error = null,
|
|
18986
|
-
// Gesture props: reorderable, swipeLeftEvent, swipeRightEvent, longPressEvent
|
|
18987
|
-
// are consumed by the compiler to wrap items in SwipeableRow/SortableList.
|
|
18988
|
-
// DataList destructures them here to prevent DOM passthrough.
|
|
18989
|
-
reorderable: _reorderable,
|
|
18990
|
-
reorderEvent: _reorderEvent,
|
|
18991
|
-
swipeLeftEvent: _swipeLeftEvent,
|
|
18992
|
-
swipeLeftActions: _swipeLeftActions,
|
|
18993
|
-
swipeRightEvent: _swipeRightEvent,
|
|
18994
|
-
swipeRightActions: _swipeRightActions,
|
|
18995
|
-
longPressEvent: _longPressEvent,
|
|
18996
|
-
infiniteScroll,
|
|
18997
|
-
loadMoreEvent,
|
|
18998
|
-
hasMore,
|
|
18999
|
-
children,
|
|
19000
|
-
pageSize = 5
|
|
19001
|
-
}) => {
|
|
19002
|
-
const eventBus = useEventBus();
|
|
19003
|
-
const { t } = useTranslate();
|
|
19004
|
-
const [visibleCount, setVisibleCount] = React115__namespace.default.useState(pageSize || Infinity);
|
|
19005
|
-
const fields = fieldsProp ?? columnsProp ?? [];
|
|
19006
|
-
const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
19007
|
-
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
19008
|
-
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
19009
|
-
const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
|
|
19010
|
-
const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
|
|
19011
|
-
const progressFields = fields.filter((f3) => f3.variant === "progress");
|
|
19012
|
-
const bodyFields = fields.filter(
|
|
19013
|
-
(f3) => f3 !== titleField && !badgeFields.includes(f3) && !progressFields.includes(f3)
|
|
19014
|
-
);
|
|
19015
|
-
const handleActionClick = (action, itemData) => (e) => {
|
|
19016
|
-
e.stopPropagation();
|
|
19017
|
-
const payload = {
|
|
19018
|
-
id: itemData.id,
|
|
19019
|
-
row: itemData
|
|
19020
|
-
};
|
|
19021
|
-
eventBus.emit(`UI:${action.event}`, payload);
|
|
19022
|
-
};
|
|
19023
|
-
if (isLoading) {
|
|
19024
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
19025
|
-
}
|
|
19026
|
-
if (error) {
|
|
19027
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
19028
|
-
}
|
|
19029
|
-
if (data.length === 0) {
|
|
19030
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
19031
|
-
}
|
|
19032
|
-
const gapClass = {
|
|
19033
|
-
none: "",
|
|
19034
|
-
sm: "gap-1",
|
|
19035
|
-
md: "gap-2",
|
|
19036
|
-
lg: "gap-4"
|
|
19037
|
-
}[gap];
|
|
19038
|
-
const isCard = variant === "card";
|
|
19039
|
-
const isCompact = variant === "compact";
|
|
19040
|
-
const isMessage = variant === "message";
|
|
19041
|
-
if (isMessage) {
|
|
19042
|
-
const items2 = data.map((item) => item);
|
|
19043
|
-
const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
|
|
19044
|
-
const contentField = titleField?.name ?? fields[0]?.name ?? "";
|
|
19045
|
-
return /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React115__namespace.default.Fragment, { children: [
|
|
19046
|
-
group.label && /* @__PURE__ */ jsxRuntime.jsx(Divider, { label: group.label, className: "my-2" }),
|
|
19047
|
-
group.items.map((itemData, index) => {
|
|
19048
|
-
const id = itemData.id || `${gi}-${index}`;
|
|
19049
|
-
const sender = senderField ? String(getNestedValue(itemData, senderField) ?? "") : "";
|
|
19050
|
-
const isSent = Boolean(currentUser && sender === currentUser);
|
|
19051
|
-
const content = getNestedValue(itemData, contentField);
|
|
19052
|
-
const timestampField = fields.find((f3) => f3.format === "date");
|
|
19053
|
-
const timestamp = timestampField ? getNestedValue(itemData, timestampField.name) : null;
|
|
19054
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19055
|
-
Box,
|
|
19056
|
-
{
|
|
19057
|
-
className: cn(
|
|
19058
|
-
"flex px-4",
|
|
19059
|
-
isSent ? "justify-end" : "justify-start"
|
|
19060
|
-
),
|
|
19061
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19062
|
-
Box,
|
|
19063
|
-
{
|
|
19064
|
-
className: cn(
|
|
19065
|
-
"max-w-[75%] px-4 py-2",
|
|
19066
|
-
isSent ? "bg-primary text-primary-foreground rounded-2xl rounded-br-sm" : "bg-muted text-foreground rounded-2xl rounded-bl-sm"
|
|
19067
|
-
),
|
|
19068
|
-
children: [
|
|
19069
|
-
!isSent && senderField && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "font-semibold mb-0.5", children: sender }),
|
|
19070
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: content !== void 0 && content !== null ? String(content) : "" }),
|
|
19071
|
-
timestamp != null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
19072
|
-
Typography,
|
|
19073
|
-
{
|
|
19074
|
-
variant: "caption",
|
|
19075
|
-
className: cn(
|
|
19076
|
-
"mt-1 text-[0.65rem]",
|
|
19077
|
-
isSent ? "opacity-70" : "text-muted-foreground"
|
|
19078
|
-
),
|
|
19079
|
-
children: formatDate3(timestamp)
|
|
19080
|
-
}
|
|
19081
|
-
) : null
|
|
19082
|
-
]
|
|
19083
|
-
}
|
|
19084
|
-
)
|
|
19085
|
-
},
|
|
19086
|
-
id
|
|
19087
|
-
);
|
|
19088
|
-
})
|
|
19089
|
-
] }, gi)) });
|
|
19090
|
-
}
|
|
19091
|
-
const hasRenderProp = typeof children === "function";
|
|
19092
|
-
const items = data.map((item) => item);
|
|
19093
|
-
const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
|
|
19094
|
-
const renderItem = (itemData, index, isLast) => {
|
|
19095
|
-
if (hasRenderProp) {
|
|
19096
|
-
const id2 = itemData.id || String(index);
|
|
19097
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, children: [
|
|
19098
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
19099
|
-
Box,
|
|
19100
|
-
{
|
|
19101
|
-
className: cn(
|
|
19102
|
-
"group flex items-center gap-4 transition-all duration-200",
|
|
19103
|
-
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
19104
|
-
"hover:bg-muted/80",
|
|
19105
|
-
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
19106
|
-
),
|
|
19107
|
-
children: [
|
|
19108
|
-
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
|
|
19109
|
-
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
19110
|
-
HStack,
|
|
19111
|
-
{
|
|
19112
|
-
gap: "xs",
|
|
19113
|
-
className: "flex-shrink-0",
|
|
19114
|
-
children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19115
|
-
Button,
|
|
19116
|
-
{
|
|
19117
|
-
variant: action.variant ?? "ghost",
|
|
19118
|
-
size: "sm",
|
|
19119
|
-
onClick: handleActionClick(action, itemData),
|
|
19120
|
-
"data-testid": `action-${action.event}`,
|
|
19121
|
-
className: cn(
|
|
19122
|
-
action.variant === "danger" && "text-error hover:bg-error/10"
|
|
19123
|
-
),
|
|
19124
|
-
children: [
|
|
19125
|
-
action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
19126
|
-
action.label
|
|
19127
|
-
]
|
|
19128
|
-
},
|
|
19129
|
-
idx
|
|
19130
|
-
))
|
|
19131
|
-
}
|
|
19132
|
-
)
|
|
19133
|
-
]
|
|
19134
|
-
}
|
|
19135
|
-
),
|
|
19136
|
-
isCard && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mx-6 border-b border-border/40" })
|
|
19137
|
-
] }, id2);
|
|
19138
|
-
}
|
|
19139
|
-
const id = itemData.id || String(index);
|
|
19140
|
-
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
19141
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id, children: [
|
|
19142
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
19143
|
-
Box,
|
|
19144
|
-
{
|
|
19145
|
-
className: cn(
|
|
19146
|
-
"group flex items-center gap-4 transition-all duration-200",
|
|
19147
|
-
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
19148
|
-
"hover:bg-muted/80",
|
|
19149
|
-
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
19150
|
-
),
|
|
19151
|
-
children: [
|
|
19152
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex-1 min-w-0", children: [
|
|
19153
|
-
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "items-center", children: [
|
|
19154
|
-
titleField?.icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
19155
|
-
Icon,
|
|
19156
|
-
{
|
|
19157
|
-
name: titleField.icon,
|
|
19158
|
-
size: isCompact ? "xs" : "sm",
|
|
19159
|
-
className: "text-primary flex-shrink-0"
|
|
19160
|
-
}
|
|
19161
|
-
),
|
|
19162
|
-
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
19163
|
-
Typography,
|
|
19164
|
-
{
|
|
19165
|
-
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
19166
|
-
className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
|
|
19167
|
-
children: String(titleValue)
|
|
19168
|
-
}
|
|
19169
|
-
),
|
|
19170
|
-
badgeFields.map((field) => {
|
|
19171
|
-
const val = getNestedValue(itemData, field.name);
|
|
19172
|
-
if (val === void 0 || val === null) return null;
|
|
19173
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
19174
|
-
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs" }),
|
|
19175
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children: String(val) })
|
|
19176
|
-
] }, field.name);
|
|
19177
|
-
})
|
|
19178
|
-
] }),
|
|
19179
|
-
bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
|
|
19180
|
-
const value = getNestedValue(itemData, field.name);
|
|
19181
|
-
if (value === void 0 || value === null || value === "") return null;
|
|
19182
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
19183
|
-
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
19184
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", color: "secondary", children: [
|
|
19185
|
-
field.label ?? fieldLabel3(field.name),
|
|
19186
|
-
":"
|
|
19187
|
-
] }),
|
|
19188
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", children: formatValue2(value, field.format) })
|
|
19189
|
-
] }, field.name);
|
|
19190
|
-
}) }),
|
|
19191
|
-
progressFields.map((field) => {
|
|
19192
|
-
const value = getNestedValue(itemData, field.name);
|
|
19193
|
-
if (typeof value !== "number") return null;
|
|
19194
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "mt-2 max-w-xs", children: [
|
|
19195
|
-
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center mb-1", children: [
|
|
19196
|
-
field.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
19197
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel3(field.name) })
|
|
19198
|
-
] }),
|
|
19199
|
-
/* @__PURE__ */ jsxRuntime.jsx(ProgressBar, { value, max: 100 })
|
|
19200
|
-
] }, field.name);
|
|
19201
|
-
})
|
|
19202
|
-
] }),
|
|
19203
|
-
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19204
|
-
Button,
|
|
19205
|
-
{
|
|
19206
|
-
variant: action.variant ?? "ghost",
|
|
19207
|
-
size: "sm",
|
|
19208
|
-
onClick: handleActionClick(action, itemData),
|
|
19209
|
-
"data-testid": `action-${action.event}`,
|
|
19210
|
-
className: cn(
|
|
19211
|
-
action.variant === "danger" && "text-error hover:bg-error/10"
|
|
19212
|
-
),
|
|
19213
|
-
children: [
|
|
19214
|
-
action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
19215
|
-
action.label
|
|
19216
|
-
]
|
|
19217
|
-
},
|
|
19218
|
-
idx
|
|
19219
|
-
)) })
|
|
19220
|
-
]
|
|
19221
|
-
}
|
|
19222
|
-
),
|
|
19223
|
-
isCard && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mx-6 border-b border-border/40" })
|
|
19224
|
-
] }, id);
|
|
19225
|
-
};
|
|
19226
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19227
|
-
Box,
|
|
19228
|
-
{
|
|
19229
|
-
className: cn(
|
|
19230
|
-
isCard && "bg-card rounded-xl border border-border shadow-lg overflow-hidden",
|
|
19231
|
-
!isCard && gapClass,
|
|
19232
|
-
className
|
|
19233
|
-
),
|
|
19234
|
-
children: [
|
|
19235
|
-
groups.map((group, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React115__namespace.default.Fragment, { children: [
|
|
19236
|
-
group.label && /* @__PURE__ */ jsxRuntime.jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
|
|
19237
|
-
group.items.map(
|
|
19238
|
-
(itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
|
|
19239
|
-
)
|
|
19240
|
-
] }, gi)),
|
|
19241
|
-
hasMoreLocal && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19242
|
-
Button,
|
|
19243
|
-
{
|
|
19244
|
-
variant: "ghost",
|
|
19245
|
-
size: "sm",
|
|
19246
|
-
onClick: () => setVisibleCount((prev) => prev + (pageSize || 5)),
|
|
19247
|
-
children: [
|
|
19248
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
19249
|
-
t("common.showMore"),
|
|
19250
|
-
" (",
|
|
19251
|
-
allData.length - visibleCount,
|
|
19252
|
-
" remaining)"
|
|
19253
|
-
]
|
|
19254
|
-
}
|
|
19255
|
-
) }),
|
|
19256
|
-
infiniteScroll && loadMoreEvent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
19257
|
-
InfiniteScrollSentinel,
|
|
19258
|
-
{
|
|
19259
|
-
loadMoreEvent,
|
|
19260
|
-
isLoading,
|
|
19261
|
-
hasMore
|
|
19262
|
-
}
|
|
19263
|
-
)
|
|
19264
|
-
]
|
|
19265
|
-
}
|
|
19266
|
-
);
|
|
19267
|
-
};
|
|
19268
19267
|
DataList.displayName = "DataList";
|
|
19269
19268
|
}
|
|
19270
19269
|
});
|
|
@@ -20465,7 +20464,10 @@ var init_WizardProgress = __esm({
|
|
|
20465
20464
|
stepClickEvent
|
|
20466
20465
|
}) => {
|
|
20467
20466
|
const eventBus = useEventBus();
|
|
20468
|
-
const
|
|
20467
|
+
const normalizedSteps = steps.map(
|
|
20468
|
+
(s, i) => typeof s === "string" ? { id: `step-${i}`, title: s } : s
|
|
20469
|
+
);
|
|
20470
|
+
const totalSteps = normalizedSteps.length;
|
|
20469
20471
|
const handleStepClick = (index) => {
|
|
20470
20472
|
const isCompleted = index < currentStep;
|
|
20471
20473
|
if (isCompleted && allowNavigation) {
|
|
@@ -20482,7 +20484,7 @@ var init_WizardProgress = __esm({
|
|
|
20482
20484
|
compact ? "px-4 py-2" : "px-6 py-4",
|
|
20483
20485
|
className
|
|
20484
20486
|
),
|
|
20485
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children:
|
|
20487
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
|
|
20486
20488
|
const isActive = index === currentStep;
|
|
20487
20489
|
const isCompleted = index < currentStep;
|
|
20488
20490
|
return /* @__PURE__ */ jsxRuntime.jsxs(React115__namespace.default.Fragment, { children: [
|
|
@@ -38678,161 +38680,6 @@ function OrbitalProvider({
|
|
|
38678
38680
|
);
|
|
38679
38681
|
}
|
|
38680
38682
|
OrbitalProvider.displayName = "OrbitalProvider";
|
|
38681
|
-
var FetchedDataContext = React115.createContext(null);
|
|
38682
|
-
function FetchedDataProvider({
|
|
38683
|
-
initialData,
|
|
38684
|
-
children
|
|
38685
|
-
}) {
|
|
38686
|
-
const [state, setState] = React115.useState(() => ({
|
|
38687
|
-
data: initialData || {},
|
|
38688
|
-
fetchedAt: {},
|
|
38689
|
-
loading: false,
|
|
38690
|
-
error: null
|
|
38691
|
-
}));
|
|
38692
|
-
const getData = React115.useCallback(
|
|
38693
|
-
(entityName) => {
|
|
38694
|
-
return state.data[entityName] || [];
|
|
38695
|
-
},
|
|
38696
|
-
[state.data]
|
|
38697
|
-
);
|
|
38698
|
-
const getById = React115.useCallback(
|
|
38699
|
-
(entityName, id) => {
|
|
38700
|
-
const records = state.data[entityName];
|
|
38701
|
-
return records?.find((r) => r.id === id);
|
|
38702
|
-
},
|
|
38703
|
-
[state.data]
|
|
38704
|
-
);
|
|
38705
|
-
const hasData = React115.useCallback(
|
|
38706
|
-
(entityName) => {
|
|
38707
|
-
return entityName in state.data && state.data[entityName].length > 0;
|
|
38708
|
-
},
|
|
38709
|
-
[state.data]
|
|
38710
|
-
);
|
|
38711
|
-
const getFetchedAt = React115.useCallback(
|
|
38712
|
-
(entityName) => {
|
|
38713
|
-
return state.fetchedAt[entityName];
|
|
38714
|
-
},
|
|
38715
|
-
[state.fetchedAt]
|
|
38716
|
-
);
|
|
38717
|
-
const setData = React115.useCallback((data) => {
|
|
38718
|
-
const now = Date.now();
|
|
38719
|
-
setState((prev) => ({
|
|
38720
|
-
...prev,
|
|
38721
|
-
data: {
|
|
38722
|
-
...prev.data,
|
|
38723
|
-
...data
|
|
38724
|
-
},
|
|
38725
|
-
fetchedAt: {
|
|
38726
|
-
...prev.fetchedAt,
|
|
38727
|
-
...Object.keys(data).reduce(
|
|
38728
|
-
(acc, key) => ({ ...acc, [key]: now }),
|
|
38729
|
-
{}
|
|
38730
|
-
)
|
|
38731
|
-
},
|
|
38732
|
-
loading: false,
|
|
38733
|
-
error: null
|
|
38734
|
-
}));
|
|
38735
|
-
}, []);
|
|
38736
|
-
const clearData = React115.useCallback(() => {
|
|
38737
|
-
setState((prev) => ({
|
|
38738
|
-
...prev,
|
|
38739
|
-
data: {},
|
|
38740
|
-
fetchedAt: {}
|
|
38741
|
-
}));
|
|
38742
|
-
}, []);
|
|
38743
|
-
const clearEntity = React115.useCallback((entityName) => {
|
|
38744
|
-
setState((prev) => {
|
|
38745
|
-
const newData = { ...prev.data };
|
|
38746
|
-
const newFetchedAt = { ...prev.fetchedAt };
|
|
38747
|
-
delete newData[entityName];
|
|
38748
|
-
delete newFetchedAt[entityName];
|
|
38749
|
-
return {
|
|
38750
|
-
...prev,
|
|
38751
|
-
data: newData,
|
|
38752
|
-
fetchedAt: newFetchedAt
|
|
38753
|
-
};
|
|
38754
|
-
});
|
|
38755
|
-
}, []);
|
|
38756
|
-
const setLoading = React115.useCallback((loading) => {
|
|
38757
|
-
setState((prev) => ({ ...prev, loading }));
|
|
38758
|
-
}, []);
|
|
38759
|
-
const setError = React115.useCallback((error) => {
|
|
38760
|
-
setState((prev) => ({ ...prev, error, loading: false }));
|
|
38761
|
-
}, []);
|
|
38762
|
-
const contextValue = React115.useMemo(
|
|
38763
|
-
() => ({
|
|
38764
|
-
getData,
|
|
38765
|
-
getById,
|
|
38766
|
-
hasData,
|
|
38767
|
-
getFetchedAt,
|
|
38768
|
-
setData,
|
|
38769
|
-
clearData,
|
|
38770
|
-
clearEntity,
|
|
38771
|
-
loading: state.loading,
|
|
38772
|
-
setLoading,
|
|
38773
|
-
error: state.error,
|
|
38774
|
-
setError
|
|
38775
|
-
}),
|
|
38776
|
-
[
|
|
38777
|
-
getData,
|
|
38778
|
-
getById,
|
|
38779
|
-
hasData,
|
|
38780
|
-
getFetchedAt,
|
|
38781
|
-
setData,
|
|
38782
|
-
clearData,
|
|
38783
|
-
clearEntity,
|
|
38784
|
-
state.loading,
|
|
38785
|
-
setLoading,
|
|
38786
|
-
state.error,
|
|
38787
|
-
setError
|
|
38788
|
-
]
|
|
38789
|
-
);
|
|
38790
|
-
return /* @__PURE__ */ jsxRuntime.jsx(FetchedDataContext.Provider, { value: contextValue, children });
|
|
38791
|
-
}
|
|
38792
|
-
function useFetchedDataContext() {
|
|
38793
|
-
return React115.useContext(FetchedDataContext);
|
|
38794
|
-
}
|
|
38795
|
-
function useFetchedData() {
|
|
38796
|
-
const context = React115.useContext(FetchedDataContext);
|
|
38797
|
-
if (!context) {
|
|
38798
|
-
return {
|
|
38799
|
-
getData: () => [],
|
|
38800
|
-
getById: () => void 0,
|
|
38801
|
-
hasData: () => false,
|
|
38802
|
-
getFetchedAt: () => void 0,
|
|
38803
|
-
setData: () => {
|
|
38804
|
-
},
|
|
38805
|
-
clearData: () => {
|
|
38806
|
-
},
|
|
38807
|
-
clearEntity: () => {
|
|
38808
|
-
},
|
|
38809
|
-
loading: false,
|
|
38810
|
-
setLoading: () => {
|
|
38811
|
-
},
|
|
38812
|
-
error: null,
|
|
38813
|
-
setError: () => {
|
|
38814
|
-
}
|
|
38815
|
-
};
|
|
38816
|
-
}
|
|
38817
|
-
return context;
|
|
38818
|
-
}
|
|
38819
|
-
function useFetchedEntity(entityName) {
|
|
38820
|
-
const context = useFetchedData();
|
|
38821
|
-
return {
|
|
38822
|
-
/** All fetched records for this entity */
|
|
38823
|
-
records: context.getData(entityName),
|
|
38824
|
-
/** Get a record by ID */
|
|
38825
|
-
getById: (id) => context.getById(entityName, id),
|
|
38826
|
-
/** Whether data has been fetched for this entity */
|
|
38827
|
-
hasData: context.hasData(entityName),
|
|
38828
|
-
/** When data was last fetched */
|
|
38829
|
-
fetchedAt: context.getFetchedAt(entityName),
|
|
38830
|
-
/** Whether data is loading */
|
|
38831
|
-
loading: context.loading,
|
|
38832
|
-
/** Current error */
|
|
38833
|
-
error: context.error
|
|
38834
|
-
};
|
|
38835
|
-
}
|
|
38836
38683
|
|
|
38837
38684
|
// providers/OfflineModeProvider.tsx
|
|
38838
38685
|
init_offline_executor();
|
|
@@ -38868,16 +38715,11 @@ function useOptionalOfflineMode() {
|
|
|
38868
38715
|
|
|
38869
38716
|
exports.EventBusContext = EventBusContext2;
|
|
38870
38717
|
exports.EventBusProvider = EventBusProvider;
|
|
38871
|
-
exports.FetchedDataContext = FetchedDataContext;
|
|
38872
|
-
exports.FetchedDataProvider = FetchedDataProvider;
|
|
38873
38718
|
exports.OfflineModeProvider = OfflineModeProvider;
|
|
38874
38719
|
exports.OrbitalProvider = OrbitalProvider;
|
|
38875
38720
|
exports.SelectionContext = SelectionContext;
|
|
38876
38721
|
exports.SelectionProvider = SelectionProvider;
|
|
38877
38722
|
exports.VerificationProvider = VerificationProvider;
|
|
38878
|
-
exports.useFetchedData = useFetchedData;
|
|
38879
|
-
exports.useFetchedDataContext = useFetchedDataContext;
|
|
38880
|
-
exports.useFetchedEntity = useFetchedEntity;
|
|
38881
38723
|
exports.useOfflineMode = useOfflineMode;
|
|
38882
38724
|
exports.useOptionalOfflineMode = useOptionalOfflineMode;
|
|
38883
38725
|
exports.useSelection = useSelection;
|