@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.js
CHANGED
|
@@ -7872,7 +7872,7 @@ var init_MapView = __esm({
|
|
|
7872
7872
|
shadowSize: [41, 41]
|
|
7873
7873
|
});
|
|
7874
7874
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
7875
|
-
const { useEffect: useEffect62, useRef: useRef62, useCallback:
|
|
7875
|
+
const { useEffect: useEffect62, useRef: useRef62, useCallback: useCallback94, useState: useState86 } = React115__default;
|
|
7876
7876
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
7877
7877
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
7878
7878
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -7916,8 +7916,8 @@ var init_MapView = __esm({
|
|
|
7916
7916
|
showAttribution = true
|
|
7917
7917
|
}) {
|
|
7918
7918
|
const eventBus = useEventBus2();
|
|
7919
|
-
const [clickedPosition, setClickedPosition] =
|
|
7920
|
-
const handleMapClick =
|
|
7919
|
+
const [clickedPosition, setClickedPosition] = useState86(null);
|
|
7920
|
+
const handleMapClick = useCallback94((lat, lng) => {
|
|
7921
7921
|
if (showClickedPin) {
|
|
7922
7922
|
setClickedPosition({ lat, lng });
|
|
7923
7923
|
}
|
|
@@ -7926,7 +7926,7 @@ var init_MapView = __esm({
|
|
|
7926
7926
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
7927
7927
|
}
|
|
7928
7928
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
7929
|
-
const handleMarkerClick =
|
|
7929
|
+
const handleMarkerClick = useCallback94((marker) => {
|
|
7930
7930
|
onMarkerClick?.(marker);
|
|
7931
7931
|
if (markerClickEvent) {
|
|
7932
7932
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -18556,7 +18556,290 @@ function formatValue(value, format) {
|
|
|
18556
18556
|
return String(value);
|
|
18557
18557
|
}
|
|
18558
18558
|
}
|
|
18559
|
-
|
|
18559
|
+
function DataGrid({
|
|
18560
|
+
entity,
|
|
18561
|
+
fields: fieldsProp,
|
|
18562
|
+
columns: columnsProp,
|
|
18563
|
+
itemActions,
|
|
18564
|
+
cols,
|
|
18565
|
+
gap = "md",
|
|
18566
|
+
minCardWidth = 280,
|
|
18567
|
+
className,
|
|
18568
|
+
isLoading = false,
|
|
18569
|
+
error = null,
|
|
18570
|
+
imageField,
|
|
18571
|
+
selectable = false,
|
|
18572
|
+
selectionEvent,
|
|
18573
|
+
infiniteScroll,
|
|
18574
|
+
loadMoreEvent,
|
|
18575
|
+
hasMore,
|
|
18576
|
+
children,
|
|
18577
|
+
pageSize = 0
|
|
18578
|
+
}) {
|
|
18579
|
+
const eventBus = useEventBus();
|
|
18580
|
+
const { t } = useTranslate();
|
|
18581
|
+
const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
|
|
18582
|
+
const [visibleCount, setVisibleCount] = useState(pageSize || Infinity);
|
|
18583
|
+
const fields = fieldsProp ?? columnsProp ?? [];
|
|
18584
|
+
const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
18585
|
+
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
18586
|
+
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
18587
|
+
const toggleSelection = useCallback((id) => {
|
|
18588
|
+
setSelectedIds((prev) => {
|
|
18589
|
+
const next = new Set(prev);
|
|
18590
|
+
if (next.has(id)) next.delete(id);
|
|
18591
|
+
else next.add(id);
|
|
18592
|
+
if (selectionEvent) {
|
|
18593
|
+
const payload = { selectedIds: Array.from(next) };
|
|
18594
|
+
eventBus.emit(`UI:${selectionEvent}`, payload);
|
|
18595
|
+
}
|
|
18596
|
+
return next;
|
|
18597
|
+
});
|
|
18598
|
+
}, [selectionEvent, eventBus]);
|
|
18599
|
+
const toggleAll = useCallback(() => {
|
|
18600
|
+
setSelectedIds((prev) => {
|
|
18601
|
+
const allIds2 = data.map((item, i) => item.id || String(i));
|
|
18602
|
+
const allSelected2 = allIds2.length > 0 && allIds2.every((id) => prev.has(id));
|
|
18603
|
+
const next = allSelected2 ? /* @__PURE__ */ new Set() : new Set(allIds2);
|
|
18604
|
+
if (selectionEvent) {
|
|
18605
|
+
const payload = { selectedIds: Array.from(next) };
|
|
18606
|
+
eventBus.emit(`UI:${selectionEvent}`, payload);
|
|
18607
|
+
}
|
|
18608
|
+
return next;
|
|
18609
|
+
});
|
|
18610
|
+
}, [data, selectionEvent, eventBus]);
|
|
18611
|
+
const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
|
|
18612
|
+
const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
|
|
18613
|
+
const bodyFields = fields.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
|
|
18614
|
+
const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
|
|
18615
|
+
const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
|
|
18616
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
18617
|
+
e.stopPropagation();
|
|
18618
|
+
const payload = {
|
|
18619
|
+
id: itemData.id,
|
|
18620
|
+
row: itemData
|
|
18621
|
+
};
|
|
18622
|
+
eventBus.emit(`UI:${action.event}`, payload);
|
|
18623
|
+
};
|
|
18624
|
+
const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
|
|
18625
|
+
const colsClass = cols ? {
|
|
18626
|
+
1: "grid-cols-1",
|
|
18627
|
+
2: "sm:grid-cols-2",
|
|
18628
|
+
3: "sm:grid-cols-2 lg:grid-cols-3",
|
|
18629
|
+
4: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
|
|
18630
|
+
5: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5",
|
|
18631
|
+
6: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6"
|
|
18632
|
+
}[cols] : void 0;
|
|
18633
|
+
if (isLoading) {
|
|
18634
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
18635
|
+
}
|
|
18636
|
+
if (error) {
|
|
18637
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
18638
|
+
}
|
|
18639
|
+
if (data.length === 0) {
|
|
18640
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
18641
|
+
}
|
|
18642
|
+
const hasRenderProp = typeof children === "function";
|
|
18643
|
+
const allIds = data.map((item, i) => item.id || String(i));
|
|
18644
|
+
const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.has(id));
|
|
18645
|
+
const someSelected = selectedIds.size > 0;
|
|
18646
|
+
return /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
18647
|
+
selectable && someSelected && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "items-center px-2 py-2 bg-muted rounded-sm", children: [
|
|
18648
|
+
/* @__PURE__ */ jsx(
|
|
18649
|
+
"input",
|
|
18650
|
+
{
|
|
18651
|
+
type: "checkbox",
|
|
18652
|
+
checked: allSelected,
|
|
18653
|
+
onChange: toggleAll,
|
|
18654
|
+
className: "w-4 h-4 accent-primary",
|
|
18655
|
+
"aria-label": "Select all"
|
|
18656
|
+
}
|
|
18657
|
+
),
|
|
18658
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "font-semibold", children: [
|
|
18659
|
+
selectedIds.size,
|
|
18660
|
+
" ",
|
|
18661
|
+
t("common.selected") || "selected"
|
|
18662
|
+
] })
|
|
18663
|
+
] }),
|
|
18664
|
+
/* @__PURE__ */ jsx(
|
|
18665
|
+
Box,
|
|
18666
|
+
{
|
|
18667
|
+
className: cn("grid", gapStyles6[gap], colsClass, className),
|
|
18668
|
+
style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
|
|
18669
|
+
children: data.map((item, index) => {
|
|
18670
|
+
const itemData = item;
|
|
18671
|
+
const id = itemData.id || String(index);
|
|
18672
|
+
const isSelected = selectedIds.has(id);
|
|
18673
|
+
if (hasRenderProp) {
|
|
18674
|
+
return /* @__PURE__ */ jsx(
|
|
18675
|
+
Box,
|
|
18676
|
+
{
|
|
18677
|
+
"data-entity-row": true,
|
|
18678
|
+
"data-entity-id": id,
|
|
18679
|
+
className: cn(
|
|
18680
|
+
"bg-card rounded-lg",
|
|
18681
|
+
"border border-border",
|
|
18682
|
+
"shadow-sm hover:shadow-lg",
|
|
18683
|
+
"hover:border-primary transition-all",
|
|
18684
|
+
"p-4",
|
|
18685
|
+
isSelected && "ring-2 ring-primary border-primary"
|
|
18686
|
+
),
|
|
18687
|
+
children: children(itemData, index)
|
|
18688
|
+
},
|
|
18689
|
+
id
|
|
18690
|
+
);
|
|
18691
|
+
}
|
|
18692
|
+
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
18693
|
+
return /* @__PURE__ */ jsxs(
|
|
18694
|
+
Box,
|
|
18695
|
+
{
|
|
18696
|
+
"data-entity-row": true,
|
|
18697
|
+
"data-entity-id": id,
|
|
18698
|
+
className: cn(
|
|
18699
|
+
"bg-card rounded-lg",
|
|
18700
|
+
"border border-border",
|
|
18701
|
+
"shadow-sm hover:shadow-lg",
|
|
18702
|
+
"hover:border-primary transition-all",
|
|
18703
|
+
"flex flex-col",
|
|
18704
|
+
isSelected && "ring-2 ring-primary border-primary"
|
|
18705
|
+
),
|
|
18706
|
+
children: [
|
|
18707
|
+
imageField && (() => {
|
|
18708
|
+
const imgUrl = getNestedValue(itemData, imageField);
|
|
18709
|
+
if (!imgUrl || typeof imgUrl !== "string") return null;
|
|
18710
|
+
return /* @__PURE__ */ jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-lg", children: /* @__PURE__ */ jsx(
|
|
18711
|
+
"img",
|
|
18712
|
+
{
|
|
18713
|
+
src: imgUrl,
|
|
18714
|
+
alt: titleValue !== void 0 ? String(titleValue) : "",
|
|
18715
|
+
className: "w-full h-full object-cover",
|
|
18716
|
+
loading: "lazy"
|
|
18717
|
+
}
|
|
18718
|
+
) });
|
|
18719
|
+
})(),
|
|
18720
|
+
/* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
18721
|
+
selectable && /* @__PURE__ */ jsx(
|
|
18722
|
+
"input",
|
|
18723
|
+
{
|
|
18724
|
+
type: "checkbox",
|
|
18725
|
+
checked: isSelected,
|
|
18726
|
+
onChange: () => toggleSelection(id),
|
|
18727
|
+
onClick: (e) => e.stopPropagation(),
|
|
18728
|
+
className: "w-4 h-4 mt-1 flex-shrink-0 accent-primary",
|
|
18729
|
+
"aria-label": `Select ${titleValue !== void 0 ? String(titleValue) : "item"}`
|
|
18730
|
+
}
|
|
18731
|
+
),
|
|
18732
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
|
|
18733
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18734
|
+
titleField?.icon && /* @__PURE__ */ jsx(Icon, { name: titleField.icon, size: "sm", className: "text-primary flex-shrink-0" }),
|
|
18735
|
+
/* @__PURE__ */ jsx(
|
|
18736
|
+
Typography,
|
|
18737
|
+
{
|
|
18738
|
+
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
18739
|
+
className: "font-semibold truncate",
|
|
18740
|
+
children: String(titleValue)
|
|
18741
|
+
}
|
|
18742
|
+
)
|
|
18743
|
+
] }),
|
|
18744
|
+
badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
18745
|
+
const val = getNestedValue(itemData, field.name);
|
|
18746
|
+
if (val === void 0 || val === null) return null;
|
|
18747
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18748
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
|
|
18749
|
+
/* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
|
|
18750
|
+
] }, field.name);
|
|
18751
|
+
}) })
|
|
18752
|
+
] }),
|
|
18753
|
+
dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
18754
|
+
Button,
|
|
18755
|
+
{
|
|
18756
|
+
variant: "ghost",
|
|
18757
|
+
size: "sm",
|
|
18758
|
+
onClick: handleActionClick(action, itemData),
|
|
18759
|
+
"data-testid": `action-${action.event}`,
|
|
18760
|
+
className: "text-error hover:bg-error/10 px-2",
|
|
18761
|
+
children: [
|
|
18762
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs" }),
|
|
18763
|
+
action.label
|
|
18764
|
+
]
|
|
18765
|
+
},
|
|
18766
|
+
idx
|
|
18767
|
+
)) })
|
|
18768
|
+
] }) }),
|
|
18769
|
+
bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
|
|
18770
|
+
const value = getNestedValue(itemData, field.name);
|
|
18771
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
18772
|
+
if (field.format === "boolean") {
|
|
18773
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
18774
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18775
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
18776
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
18777
|
+
] }),
|
|
18778
|
+
/* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
|
|
18779
|
+
] }, field.name);
|
|
18780
|
+
}
|
|
18781
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
18782
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18783
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
18784
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
18785
|
+
] }),
|
|
18786
|
+
/* @__PURE__ */ jsx(
|
|
18787
|
+
Typography,
|
|
18788
|
+
{
|
|
18789
|
+
variant: field.variant === "caption" ? "caption" : "small",
|
|
18790
|
+
className: "text-right truncate max-w-[60%]",
|
|
18791
|
+
children: formatValue(value, field.format)
|
|
18792
|
+
}
|
|
18793
|
+
)
|
|
18794
|
+
] }, field.name);
|
|
18795
|
+
}) }) }),
|
|
18796
|
+
primaryActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
18797
|
+
Button,
|
|
18798
|
+
{
|
|
18799
|
+
variant: action.variant === "primary" ? "primary" : "ghost",
|
|
18800
|
+
size: "sm",
|
|
18801
|
+
onClick: handleActionClick(action, itemData),
|
|
18802
|
+
"data-testid": `action-${action.event}`,
|
|
18803
|
+
children: [
|
|
18804
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
18805
|
+
action.label
|
|
18806
|
+
]
|
|
18807
|
+
},
|
|
18808
|
+
idx
|
|
18809
|
+
)) }) })
|
|
18810
|
+
]
|
|
18811
|
+
},
|
|
18812
|
+
id
|
|
18813
|
+
);
|
|
18814
|
+
})
|
|
18815
|
+
}
|
|
18816
|
+
),
|
|
18817
|
+
hasMoreLocal && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(
|
|
18818
|
+
Button,
|
|
18819
|
+
{
|
|
18820
|
+
variant: "ghost",
|
|
18821
|
+
size: "sm",
|
|
18822
|
+
onClick: () => setVisibleCount((prev) => prev + (pageSize || 5)),
|
|
18823
|
+
children: [
|
|
18824
|
+
/* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
18825
|
+
t("common.showMore"),
|
|
18826
|
+
" (",
|
|
18827
|
+
allData.length - visibleCount,
|
|
18828
|
+
" remaining)"
|
|
18829
|
+
]
|
|
18830
|
+
}
|
|
18831
|
+
) }),
|
|
18832
|
+
infiniteScroll && loadMoreEvent && /* @__PURE__ */ jsx(
|
|
18833
|
+
InfiniteScrollSentinel,
|
|
18834
|
+
{
|
|
18835
|
+
loadMoreEvent,
|
|
18836
|
+
isLoading,
|
|
18837
|
+
hasMore
|
|
18838
|
+
}
|
|
18839
|
+
)
|
|
18840
|
+
] });
|
|
18841
|
+
}
|
|
18842
|
+
var gapStyles6;
|
|
18560
18843
|
var init_DataGrid = __esm({
|
|
18561
18844
|
"components/molecules/DataGrid.tsx"() {
|
|
18562
18845
|
"use client";
|
|
@@ -18578,264 +18861,321 @@ var init_DataGrid = __esm({
|
|
|
18578
18861
|
lg: "gap-6",
|
|
18579
18862
|
xl: "gap-8"
|
|
18580
18863
|
};
|
|
18581
|
-
DataGrid =
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
18585
|
-
|
|
18586
|
-
|
|
18587
|
-
|
|
18588
|
-
|
|
18589
|
-
|
|
18590
|
-
|
|
18591
|
-
|
|
18592
|
-
|
|
18593
|
-
|
|
18594
|
-
|
|
18595
|
-
|
|
18596
|
-
|
|
18597
|
-
|
|
18598
|
-
|
|
18599
|
-
|
|
18600
|
-
|
|
18601
|
-
|
|
18602
|
-
|
|
18603
|
-
|
|
18604
|
-
|
|
18605
|
-
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
18620
|
-
|
|
18621
|
-
|
|
18622
|
-
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
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
|
-
|
|
18864
|
+
DataGrid.displayName = "DataGrid";
|
|
18865
|
+
}
|
|
18866
|
+
});
|
|
18867
|
+
function fieldLabel3(key) {
|
|
18868
|
+
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
18869
|
+
}
|
|
18870
|
+
function statusVariant3(value) {
|
|
18871
|
+
const v = value.toLowerCase();
|
|
18872
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online"].includes(v)) return "success";
|
|
18873
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warning"].includes(v)) return "warning";
|
|
18874
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
18875
|
+
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
18876
|
+
return "default";
|
|
18877
|
+
}
|
|
18878
|
+
function formatDate3(value) {
|
|
18879
|
+
if (!value) return "";
|
|
18880
|
+
const d = new Date(String(value));
|
|
18881
|
+
if (isNaN(d.getTime())) return String(value);
|
|
18882
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
18883
|
+
}
|
|
18884
|
+
function formatValue2(value, format) {
|
|
18885
|
+
if (value === void 0 || value === null) return "";
|
|
18886
|
+
switch (format) {
|
|
18887
|
+
case "date":
|
|
18888
|
+
return formatDate3(value);
|
|
18889
|
+
case "currency":
|
|
18890
|
+
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
18891
|
+
case "number":
|
|
18892
|
+
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
18893
|
+
case "percent":
|
|
18894
|
+
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
18895
|
+
case "boolean":
|
|
18896
|
+
return value ? "Yes" : "No";
|
|
18897
|
+
default:
|
|
18898
|
+
return String(value);
|
|
18899
|
+
}
|
|
18900
|
+
}
|
|
18901
|
+
function groupData(items, field) {
|
|
18902
|
+
const groups = /* @__PURE__ */ new Map();
|
|
18903
|
+
for (const item of items) {
|
|
18904
|
+
const key = String(getNestedValue(item, field) ?? "");
|
|
18905
|
+
const group = groups.get(key);
|
|
18906
|
+
if (group) group.push(item);
|
|
18907
|
+
else groups.set(key, [item]);
|
|
18908
|
+
}
|
|
18909
|
+
return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
|
|
18910
|
+
}
|
|
18911
|
+
function DataList({
|
|
18912
|
+
entity,
|
|
18913
|
+
fields: fieldsProp,
|
|
18914
|
+
columns: columnsProp,
|
|
18915
|
+
itemActions,
|
|
18916
|
+
gap = "none",
|
|
18917
|
+
variant = "default",
|
|
18918
|
+
groupBy,
|
|
18919
|
+
senderField,
|
|
18920
|
+
currentUser,
|
|
18921
|
+
className,
|
|
18922
|
+
isLoading = false,
|
|
18923
|
+
error = null,
|
|
18924
|
+
// Gesture props: reorderable, swipeLeftEvent, swipeRightEvent, longPressEvent
|
|
18925
|
+
// are consumed by the compiler to wrap items in SwipeableRow/SortableList.
|
|
18926
|
+
// DataList destructures them here to prevent DOM passthrough.
|
|
18927
|
+
reorderable: _reorderable,
|
|
18928
|
+
reorderEvent: _reorderEvent,
|
|
18929
|
+
swipeLeftEvent: _swipeLeftEvent,
|
|
18930
|
+
swipeLeftActions: _swipeLeftActions,
|
|
18931
|
+
swipeRightEvent: _swipeRightEvent,
|
|
18932
|
+
swipeRightActions: _swipeRightActions,
|
|
18933
|
+
longPressEvent: _longPressEvent,
|
|
18934
|
+
infiniteScroll,
|
|
18935
|
+
loadMoreEvent,
|
|
18936
|
+
hasMore,
|
|
18937
|
+
children,
|
|
18938
|
+
pageSize = 5
|
|
18939
|
+
}) {
|
|
18940
|
+
const eventBus = useEventBus();
|
|
18941
|
+
const { t } = useTranslate();
|
|
18942
|
+
const [visibleCount, setVisibleCount] = React115__default.useState(pageSize || Infinity);
|
|
18943
|
+
const fields = fieldsProp ?? columnsProp ?? [];
|
|
18944
|
+
const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
18945
|
+
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
18946
|
+
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
18947
|
+
const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
|
|
18948
|
+
const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
|
|
18949
|
+
const progressFields = fields.filter((f3) => f3.variant === "progress");
|
|
18950
|
+
const bodyFields = fields.filter(
|
|
18951
|
+
(f3) => f3 !== titleField && !badgeFields.includes(f3) && !progressFields.includes(f3)
|
|
18952
|
+
);
|
|
18953
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
18954
|
+
e.stopPropagation();
|
|
18955
|
+
const payload = {
|
|
18956
|
+
id: itemData.id,
|
|
18957
|
+
row: itemData
|
|
18958
|
+
};
|
|
18959
|
+
eventBus.emit(`UI:${action.event}`, payload);
|
|
18960
|
+
};
|
|
18961
|
+
if (isLoading) {
|
|
18962
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
18963
|
+
}
|
|
18964
|
+
if (error) {
|
|
18965
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
18966
|
+
}
|
|
18967
|
+
if (data.length === 0) {
|
|
18968
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
18969
|
+
}
|
|
18970
|
+
const gapClass = {
|
|
18971
|
+
none: "",
|
|
18972
|
+
sm: "gap-1",
|
|
18973
|
+
md: "gap-2",
|
|
18974
|
+
lg: "gap-4"
|
|
18975
|
+
}[gap];
|
|
18976
|
+
const isCard = variant === "card";
|
|
18977
|
+
const isCompact = variant === "compact";
|
|
18978
|
+
const isMessage = variant === "message";
|
|
18979
|
+
if (isMessage) {
|
|
18980
|
+
const items2 = data.map((item) => item);
|
|
18981
|
+
const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
|
|
18982
|
+
const contentField = titleField?.name ?? fields[0]?.name ?? "";
|
|
18983
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React115__default.Fragment, { children: [
|
|
18984
|
+
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
|
|
18985
|
+
group.items.map((itemData, index) => {
|
|
18986
|
+
const id = itemData.id || `${gi}-${index}`;
|
|
18987
|
+
const sender = senderField ? String(getNestedValue(itemData, senderField) ?? "") : "";
|
|
18988
|
+
const isSent = Boolean(currentUser && sender === currentUser);
|
|
18989
|
+
const content = getNestedValue(itemData, contentField);
|
|
18990
|
+
const timestampField = fields.find((f3) => f3.format === "date");
|
|
18991
|
+
const timestamp = timestampField ? getNestedValue(itemData, timestampField.name) : null;
|
|
18992
|
+
return /* @__PURE__ */ jsx(
|
|
18687
18993
|
Box,
|
|
18688
18994
|
{
|
|
18689
|
-
className: cn(
|
|
18690
|
-
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
|
|
18694
|
-
|
|
18695
|
-
|
|
18696
|
-
|
|
18697
|
-
|
|
18698
|
-
|
|
18699
|
-
|
|
18700
|
-
|
|
18701
|
-
|
|
18702
|
-
|
|
18703
|
-
|
|
18704
|
-
|
|
18705
|
-
|
|
18706
|
-
"
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
|
|
18710
|
-
|
|
18711
|
-
|
|
18712
|
-
|
|
18995
|
+
className: cn(
|
|
18996
|
+
"flex px-4",
|
|
18997
|
+
isSent ? "justify-end" : "justify-start"
|
|
18998
|
+
),
|
|
18999
|
+
children: /* @__PURE__ */ jsxs(
|
|
19000
|
+
Box,
|
|
19001
|
+
{
|
|
19002
|
+
className: cn(
|
|
19003
|
+
"max-w-[75%] px-4 py-2",
|
|
19004
|
+
isSent ? "bg-primary text-primary-foreground rounded-2xl rounded-br-sm" : "bg-muted text-foreground rounded-2xl rounded-bl-sm"
|
|
19005
|
+
),
|
|
19006
|
+
children: [
|
|
19007
|
+
!isSent && senderField && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-semibold mb-0.5", children: sender }),
|
|
19008
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: content !== void 0 && content !== null ? String(content) : "" }),
|
|
19009
|
+
timestamp != null ? /* @__PURE__ */ jsx(
|
|
19010
|
+
Typography,
|
|
19011
|
+
{
|
|
19012
|
+
variant: "caption",
|
|
19013
|
+
className: cn(
|
|
19014
|
+
"mt-1 text-[0.65rem]",
|
|
19015
|
+
isSent ? "opacity-70" : "text-muted-foreground"
|
|
19016
|
+
),
|
|
19017
|
+
children: formatDate3(timestamp)
|
|
19018
|
+
}
|
|
19019
|
+
) : null
|
|
19020
|
+
]
|
|
18713
19021
|
}
|
|
18714
|
-
|
|
18715
|
-
|
|
18716
|
-
|
|
19022
|
+
)
|
|
19023
|
+
},
|
|
19024
|
+
id
|
|
19025
|
+
);
|
|
19026
|
+
})
|
|
19027
|
+
] }, gi)) });
|
|
19028
|
+
}
|
|
19029
|
+
const hasRenderProp = typeof children === "function";
|
|
19030
|
+
const items = data.map((item) => item);
|
|
19031
|
+
const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
|
|
19032
|
+
const renderItem = (itemData, index, isLast) => {
|
|
19033
|
+
if (hasRenderProp) {
|
|
19034
|
+
const id2 = itemData.id || String(index);
|
|
19035
|
+
return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, children: [
|
|
19036
|
+
/* @__PURE__ */ jsxs(
|
|
19037
|
+
Box,
|
|
19038
|
+
{
|
|
19039
|
+
className: cn(
|
|
19040
|
+
"group flex items-center gap-4 transition-all duration-200",
|
|
19041
|
+
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
19042
|
+
"hover:bg-muted/80",
|
|
19043
|
+
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
19044
|
+
),
|
|
19045
|
+
children: [
|
|
19046
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
|
|
19047
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(
|
|
19048
|
+
HStack,
|
|
18717
19049
|
{
|
|
18718
|
-
"
|
|
18719
|
-
"
|
|
18720
|
-
|
|
18721
|
-
|
|
18722
|
-
|
|
18723
|
-
|
|
18724
|
-
|
|
18725
|
-
|
|
18726
|
-
|
|
18727
|
-
|
|
18728
|
-
|
|
18729
|
-
imageField && (() => {
|
|
18730
|
-
const imgUrl = getNestedValue(itemData, imageField);
|
|
18731
|
-
if (!imgUrl || typeof imgUrl !== "string") return null;
|
|
18732
|
-
return /* @__PURE__ */ jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-lg", children: /* @__PURE__ */ jsx(
|
|
18733
|
-
"img",
|
|
18734
|
-
{
|
|
18735
|
-
src: imgUrl,
|
|
18736
|
-
alt: titleValue !== void 0 ? String(titleValue) : "",
|
|
18737
|
-
className: "w-full h-full object-cover",
|
|
18738
|
-
loading: "lazy"
|
|
18739
|
-
}
|
|
18740
|
-
) });
|
|
18741
|
-
})(),
|
|
18742
|
-
/* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
18743
|
-
selectable && /* @__PURE__ */ jsx(
|
|
18744
|
-
"input",
|
|
18745
|
-
{
|
|
18746
|
-
type: "checkbox",
|
|
18747
|
-
checked: isSelected,
|
|
18748
|
-
onChange: () => toggleSelection(id),
|
|
18749
|
-
onClick: (e) => e.stopPropagation(),
|
|
18750
|
-
className: "w-4 h-4 mt-1 flex-shrink-0 accent-primary",
|
|
18751
|
-
"aria-label": `Select ${titleValue !== void 0 ? String(titleValue) : "item"}`
|
|
18752
|
-
}
|
|
19050
|
+
gap: "xs",
|
|
19051
|
+
className: "flex-shrink-0",
|
|
19052
|
+
children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
19053
|
+
Button,
|
|
19054
|
+
{
|
|
19055
|
+
variant: action.variant ?? "ghost",
|
|
19056
|
+
size: "sm",
|
|
19057
|
+
onClick: handleActionClick(action, itemData),
|
|
19058
|
+
"data-testid": `action-${action.event}`,
|
|
19059
|
+
className: cn(
|
|
19060
|
+
action.variant === "danger" && "text-error hover:bg-error/10"
|
|
18753
19061
|
),
|
|
18754
|
-
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
|
|
18760
|
-
|
|
18761
|
-
|
|
18762
|
-
|
|
18763
|
-
|
|
18764
|
-
)
|
|
18765
|
-
] }),
|
|
18766
|
-
badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
18767
|
-
const val = getNestedValue(itemData, field.name);
|
|
18768
|
-
if (val === void 0 || val === null) return null;
|
|
18769
|
-
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18770
|
-
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
|
|
18771
|
-
/* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
|
|
18772
|
-
] }, field.name);
|
|
18773
|
-
}) })
|
|
18774
|
-
] }),
|
|
18775
|
-
dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
18776
|
-
Button,
|
|
18777
|
-
{
|
|
18778
|
-
variant: "ghost",
|
|
18779
|
-
size: "sm",
|
|
18780
|
-
onClick: handleActionClick(action, itemData),
|
|
18781
|
-
"data-testid": `action-${action.event}`,
|
|
18782
|
-
className: "text-error hover:bg-error/10 px-2",
|
|
18783
|
-
children: [
|
|
18784
|
-
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs" }),
|
|
18785
|
-
action.label
|
|
18786
|
-
]
|
|
18787
|
-
},
|
|
18788
|
-
idx
|
|
18789
|
-
)) })
|
|
18790
|
-
] }) }),
|
|
18791
|
-
bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
|
|
18792
|
-
const value = getNestedValue(itemData, field.name);
|
|
18793
|
-
if (value === void 0 || value === null || value === "") return null;
|
|
18794
|
-
if (field.format === "boolean") {
|
|
18795
|
-
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
18796
|
-
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18797
|
-
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
18798
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
18799
|
-
] }),
|
|
18800
|
-
/* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
|
|
18801
|
-
] }, field.name);
|
|
18802
|
-
}
|
|
18803
|
-
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
18804
|
-
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
18805
|
-
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
18806
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
18807
|
-
] }),
|
|
18808
|
-
/* @__PURE__ */ jsx(
|
|
18809
|
-
Typography,
|
|
18810
|
-
{
|
|
18811
|
-
variant: field.variant === "caption" ? "caption" : "small",
|
|
18812
|
-
className: "text-right truncate max-w-[60%]",
|
|
18813
|
-
children: formatValue(value, field.format)
|
|
18814
|
-
}
|
|
18815
|
-
)
|
|
18816
|
-
] }, field.name);
|
|
18817
|
-
}) }) }),
|
|
18818
|
-
primaryActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
18819
|
-
Button,
|
|
18820
|
-
{
|
|
18821
|
-
variant: action.variant === "primary" ? "primary" : "ghost",
|
|
18822
|
-
size: "sm",
|
|
18823
|
-
onClick: handleActionClick(action, itemData),
|
|
18824
|
-
"data-testid": `action-${action.event}`,
|
|
18825
|
-
children: [
|
|
18826
|
-
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
18827
|
-
action.label
|
|
18828
|
-
]
|
|
18829
|
-
},
|
|
18830
|
-
idx
|
|
18831
|
-
)) }) })
|
|
18832
|
-
]
|
|
18833
|
-
},
|
|
18834
|
-
id
|
|
18835
|
-
);
|
|
18836
|
-
})
|
|
19062
|
+
children: [
|
|
19063
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
19064
|
+
action.label
|
|
19065
|
+
]
|
|
19066
|
+
},
|
|
19067
|
+
idx
|
|
19068
|
+
))
|
|
19069
|
+
}
|
|
19070
|
+
)
|
|
19071
|
+
]
|
|
18837
19072
|
}
|
|
18838
19073
|
),
|
|
19074
|
+
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
|
|
19075
|
+
] }, id2);
|
|
19076
|
+
}
|
|
19077
|
+
const id = itemData.id || String(index);
|
|
19078
|
+
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
19079
|
+
return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id, children: [
|
|
19080
|
+
/* @__PURE__ */ jsxs(
|
|
19081
|
+
Box,
|
|
19082
|
+
{
|
|
19083
|
+
className: cn(
|
|
19084
|
+
"group flex items-center gap-4 transition-all duration-200",
|
|
19085
|
+
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
19086
|
+
"hover:bg-muted/80",
|
|
19087
|
+
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
19088
|
+
),
|
|
19089
|
+
children: [
|
|
19090
|
+
/* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
|
|
19091
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "items-center", children: [
|
|
19092
|
+
titleField?.icon && /* @__PURE__ */ jsx(
|
|
19093
|
+
Icon,
|
|
19094
|
+
{
|
|
19095
|
+
name: titleField.icon,
|
|
19096
|
+
size: isCompact ? "xs" : "sm",
|
|
19097
|
+
className: "text-primary flex-shrink-0"
|
|
19098
|
+
}
|
|
19099
|
+
),
|
|
19100
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsx(
|
|
19101
|
+
Typography,
|
|
19102
|
+
{
|
|
19103
|
+
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
19104
|
+
className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
|
|
19105
|
+
children: String(titleValue)
|
|
19106
|
+
}
|
|
19107
|
+
),
|
|
19108
|
+
badgeFields.map((field) => {
|
|
19109
|
+
const val = getNestedValue(itemData, field.name);
|
|
19110
|
+
if (val === void 0 || val === null) return null;
|
|
19111
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
19112
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
|
|
19113
|
+
/* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: String(val) })
|
|
19114
|
+
] }, field.name);
|
|
19115
|
+
})
|
|
19116
|
+
] }),
|
|
19117
|
+
bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
|
|
19118
|
+
const value = getNestedValue(itemData, field.name);
|
|
19119
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
19120
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
19121
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
19122
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "secondary", children: [
|
|
19123
|
+
field.label ?? fieldLabel3(field.name),
|
|
19124
|
+
":"
|
|
19125
|
+
] }),
|
|
19126
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue2(value, field.format) })
|
|
19127
|
+
] }, field.name);
|
|
19128
|
+
}) }),
|
|
19129
|
+
progressFields.map((field) => {
|
|
19130
|
+
const value = getNestedValue(itemData, field.name);
|
|
19131
|
+
if (typeof value !== "number") return null;
|
|
19132
|
+
return /* @__PURE__ */ jsxs(Box, { className: "mt-2 max-w-xs", children: [
|
|
19133
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center mb-1", children: [
|
|
19134
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
19135
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel3(field.name) })
|
|
19136
|
+
] }),
|
|
19137
|
+
/* @__PURE__ */ jsx(ProgressBar, { value, max: 100 })
|
|
19138
|
+
] }, field.name);
|
|
19139
|
+
})
|
|
19140
|
+
] }),
|
|
19141
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
19142
|
+
Button,
|
|
19143
|
+
{
|
|
19144
|
+
variant: action.variant ?? "ghost",
|
|
19145
|
+
size: "sm",
|
|
19146
|
+
onClick: handleActionClick(action, itemData),
|
|
19147
|
+
"data-testid": `action-${action.event}`,
|
|
19148
|
+
className: cn(
|
|
19149
|
+
action.variant === "danger" && "text-error hover:bg-error/10"
|
|
19150
|
+
),
|
|
19151
|
+
children: [
|
|
19152
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
19153
|
+
action.label
|
|
19154
|
+
]
|
|
19155
|
+
},
|
|
19156
|
+
idx
|
|
19157
|
+
)) })
|
|
19158
|
+
]
|
|
19159
|
+
}
|
|
19160
|
+
),
|
|
19161
|
+
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
|
|
19162
|
+
] }, id);
|
|
19163
|
+
};
|
|
19164
|
+
return /* @__PURE__ */ jsxs(
|
|
19165
|
+
Box,
|
|
19166
|
+
{
|
|
19167
|
+
className: cn(
|
|
19168
|
+
isCard && "bg-card rounded-xl border border-border shadow-lg overflow-hidden",
|
|
19169
|
+
!isCard && gapClass,
|
|
19170
|
+
className
|
|
19171
|
+
),
|
|
19172
|
+
children: [
|
|
19173
|
+
groups.map((group, gi) => /* @__PURE__ */ jsxs(React115__default.Fragment, { children: [
|
|
19174
|
+
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
|
|
19175
|
+
group.items.map(
|
|
19176
|
+
(itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
|
|
19177
|
+
)
|
|
19178
|
+
] }, gi)),
|
|
18839
19179
|
hasMoreLocal && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(
|
|
18840
19180
|
Button,
|
|
18841
19181
|
{
|
|
@@ -18859,56 +19199,10 @@ var init_DataGrid = __esm({
|
|
|
18859
19199
|
hasMore
|
|
18860
19200
|
}
|
|
18861
19201
|
)
|
|
18862
|
-
]
|
|
18863
|
-
}
|
|
18864
|
-
|
|
18865
|
-
}
|
|
18866
|
-
});
|
|
18867
|
-
function fieldLabel3(key) {
|
|
18868
|
-
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
18869
|
-
}
|
|
18870
|
-
function statusVariant3(value) {
|
|
18871
|
-
const v = value.toLowerCase();
|
|
18872
|
-
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online"].includes(v)) return "success";
|
|
18873
|
-
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warning"].includes(v)) return "warning";
|
|
18874
|
-
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
18875
|
-
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
18876
|
-
return "default";
|
|
18877
|
-
}
|
|
18878
|
-
function formatDate3(value) {
|
|
18879
|
-
if (!value) return "";
|
|
18880
|
-
const d = new Date(String(value));
|
|
18881
|
-
if (isNaN(d.getTime())) return String(value);
|
|
18882
|
-
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
18883
|
-
}
|
|
18884
|
-
function formatValue2(value, format) {
|
|
18885
|
-
if (value === void 0 || value === null) return "";
|
|
18886
|
-
switch (format) {
|
|
18887
|
-
case "date":
|
|
18888
|
-
return formatDate3(value);
|
|
18889
|
-
case "currency":
|
|
18890
|
-
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
18891
|
-
case "number":
|
|
18892
|
-
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
18893
|
-
case "percent":
|
|
18894
|
-
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
18895
|
-
case "boolean":
|
|
18896
|
-
return value ? "Yes" : "No";
|
|
18897
|
-
default:
|
|
18898
|
-
return String(value);
|
|
18899
|
-
}
|
|
18900
|
-
}
|
|
18901
|
-
function groupData(items, field) {
|
|
18902
|
-
const groups = /* @__PURE__ */ new Map();
|
|
18903
|
-
for (const item of items) {
|
|
18904
|
-
const key = String(getNestedValue(item, field) ?? "");
|
|
18905
|
-
const group = groups.get(key);
|
|
18906
|
-
if (group) group.push(item);
|
|
18907
|
-
else groups.set(key, [item]);
|
|
18908
|
-
}
|
|
18909
|
-
return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
|
|
19202
|
+
]
|
|
19203
|
+
}
|
|
19204
|
+
);
|
|
18910
19205
|
}
|
|
18911
|
-
var DataList;
|
|
18912
19206
|
var init_DataList = __esm({
|
|
18913
19207
|
"components/molecules/DataList.tsx"() {
|
|
18914
19208
|
"use client";
|
|
@@ -18925,301 +19219,6 @@ var init_DataList = __esm({
|
|
|
18925
19219
|
init_ProgressBar();
|
|
18926
19220
|
init_Divider();
|
|
18927
19221
|
init_InfiniteScrollSentinel();
|
|
18928
|
-
DataList = ({
|
|
18929
|
-
entity,
|
|
18930
|
-
fields: fieldsProp,
|
|
18931
|
-
columns: columnsProp,
|
|
18932
|
-
itemActions,
|
|
18933
|
-
gap = "none",
|
|
18934
|
-
variant = "default",
|
|
18935
|
-
groupBy,
|
|
18936
|
-
senderField,
|
|
18937
|
-
currentUser,
|
|
18938
|
-
className,
|
|
18939
|
-
isLoading = false,
|
|
18940
|
-
error = null,
|
|
18941
|
-
// Gesture props: reorderable, swipeLeftEvent, swipeRightEvent, longPressEvent
|
|
18942
|
-
// are consumed by the compiler to wrap items in SwipeableRow/SortableList.
|
|
18943
|
-
// DataList destructures them here to prevent DOM passthrough.
|
|
18944
|
-
reorderable: _reorderable,
|
|
18945
|
-
reorderEvent: _reorderEvent,
|
|
18946
|
-
swipeLeftEvent: _swipeLeftEvent,
|
|
18947
|
-
swipeLeftActions: _swipeLeftActions,
|
|
18948
|
-
swipeRightEvent: _swipeRightEvent,
|
|
18949
|
-
swipeRightActions: _swipeRightActions,
|
|
18950
|
-
longPressEvent: _longPressEvent,
|
|
18951
|
-
infiniteScroll,
|
|
18952
|
-
loadMoreEvent,
|
|
18953
|
-
hasMore,
|
|
18954
|
-
children,
|
|
18955
|
-
pageSize = 5
|
|
18956
|
-
}) => {
|
|
18957
|
-
const eventBus = useEventBus();
|
|
18958
|
-
const { t } = useTranslate();
|
|
18959
|
-
const [visibleCount, setVisibleCount] = React115__default.useState(pageSize || Infinity);
|
|
18960
|
-
const fields = fieldsProp ?? columnsProp ?? [];
|
|
18961
|
-
const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
18962
|
-
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
18963
|
-
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
18964
|
-
const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
|
|
18965
|
-
const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
|
|
18966
|
-
const progressFields = fields.filter((f3) => f3.variant === "progress");
|
|
18967
|
-
const bodyFields = fields.filter(
|
|
18968
|
-
(f3) => f3 !== titleField && !badgeFields.includes(f3) && !progressFields.includes(f3)
|
|
18969
|
-
);
|
|
18970
|
-
const handleActionClick = (action, itemData) => (e) => {
|
|
18971
|
-
e.stopPropagation();
|
|
18972
|
-
const payload = {
|
|
18973
|
-
id: itemData.id,
|
|
18974
|
-
row: itemData
|
|
18975
|
-
};
|
|
18976
|
-
eventBus.emit(`UI:${action.event}`, payload);
|
|
18977
|
-
};
|
|
18978
|
-
if (isLoading) {
|
|
18979
|
-
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
18980
|
-
}
|
|
18981
|
-
if (error) {
|
|
18982
|
-
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
18983
|
-
}
|
|
18984
|
-
if (data.length === 0) {
|
|
18985
|
-
return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
18986
|
-
}
|
|
18987
|
-
const gapClass = {
|
|
18988
|
-
none: "",
|
|
18989
|
-
sm: "gap-1",
|
|
18990
|
-
md: "gap-2",
|
|
18991
|
-
lg: "gap-4"
|
|
18992
|
-
}[gap];
|
|
18993
|
-
const isCard = variant === "card";
|
|
18994
|
-
const isCompact = variant === "compact";
|
|
18995
|
-
const isMessage = variant === "message";
|
|
18996
|
-
if (isMessage) {
|
|
18997
|
-
const items2 = data.map((item) => item);
|
|
18998
|
-
const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
|
|
18999
|
-
const contentField = titleField?.name ?? fields[0]?.name ?? "";
|
|
19000
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React115__default.Fragment, { children: [
|
|
19001
|
-
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
|
|
19002
|
-
group.items.map((itemData, index) => {
|
|
19003
|
-
const id = itemData.id || `${gi}-${index}`;
|
|
19004
|
-
const sender = senderField ? String(getNestedValue(itemData, senderField) ?? "") : "";
|
|
19005
|
-
const isSent = Boolean(currentUser && sender === currentUser);
|
|
19006
|
-
const content = getNestedValue(itemData, contentField);
|
|
19007
|
-
const timestampField = fields.find((f3) => f3.format === "date");
|
|
19008
|
-
const timestamp = timestampField ? getNestedValue(itemData, timestampField.name) : null;
|
|
19009
|
-
return /* @__PURE__ */ jsx(
|
|
19010
|
-
Box,
|
|
19011
|
-
{
|
|
19012
|
-
className: cn(
|
|
19013
|
-
"flex px-4",
|
|
19014
|
-
isSent ? "justify-end" : "justify-start"
|
|
19015
|
-
),
|
|
19016
|
-
children: /* @__PURE__ */ jsxs(
|
|
19017
|
-
Box,
|
|
19018
|
-
{
|
|
19019
|
-
className: cn(
|
|
19020
|
-
"max-w-[75%] px-4 py-2",
|
|
19021
|
-
isSent ? "bg-primary text-primary-foreground rounded-2xl rounded-br-sm" : "bg-muted text-foreground rounded-2xl rounded-bl-sm"
|
|
19022
|
-
),
|
|
19023
|
-
children: [
|
|
19024
|
-
!isSent && senderField && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-semibold mb-0.5", children: sender }),
|
|
19025
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: content !== void 0 && content !== null ? String(content) : "" }),
|
|
19026
|
-
timestamp != null ? /* @__PURE__ */ jsx(
|
|
19027
|
-
Typography,
|
|
19028
|
-
{
|
|
19029
|
-
variant: "caption",
|
|
19030
|
-
className: cn(
|
|
19031
|
-
"mt-1 text-[0.65rem]",
|
|
19032
|
-
isSent ? "opacity-70" : "text-muted-foreground"
|
|
19033
|
-
),
|
|
19034
|
-
children: formatDate3(timestamp)
|
|
19035
|
-
}
|
|
19036
|
-
) : null
|
|
19037
|
-
]
|
|
19038
|
-
}
|
|
19039
|
-
)
|
|
19040
|
-
},
|
|
19041
|
-
id
|
|
19042
|
-
);
|
|
19043
|
-
})
|
|
19044
|
-
] }, gi)) });
|
|
19045
|
-
}
|
|
19046
|
-
const hasRenderProp = typeof children === "function";
|
|
19047
|
-
const items = data.map((item) => item);
|
|
19048
|
-
const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
|
|
19049
|
-
const renderItem = (itemData, index, isLast) => {
|
|
19050
|
-
if (hasRenderProp) {
|
|
19051
|
-
const id2 = itemData.id || String(index);
|
|
19052
|
-
return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, children: [
|
|
19053
|
-
/* @__PURE__ */ jsxs(
|
|
19054
|
-
Box,
|
|
19055
|
-
{
|
|
19056
|
-
className: cn(
|
|
19057
|
-
"group flex items-center gap-4 transition-all duration-200",
|
|
19058
|
-
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
19059
|
-
"hover:bg-muted/80",
|
|
19060
|
-
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
19061
|
-
),
|
|
19062
|
-
children: [
|
|
19063
|
-
/* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
|
|
19064
|
-
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(
|
|
19065
|
-
HStack,
|
|
19066
|
-
{
|
|
19067
|
-
gap: "xs",
|
|
19068
|
-
className: "flex-shrink-0",
|
|
19069
|
-
children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
19070
|
-
Button,
|
|
19071
|
-
{
|
|
19072
|
-
variant: action.variant ?? "ghost",
|
|
19073
|
-
size: "sm",
|
|
19074
|
-
onClick: handleActionClick(action, itemData),
|
|
19075
|
-
"data-testid": `action-${action.event}`,
|
|
19076
|
-
className: cn(
|
|
19077
|
-
action.variant === "danger" && "text-error hover:bg-error/10"
|
|
19078
|
-
),
|
|
19079
|
-
children: [
|
|
19080
|
-
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
19081
|
-
action.label
|
|
19082
|
-
]
|
|
19083
|
-
},
|
|
19084
|
-
idx
|
|
19085
|
-
))
|
|
19086
|
-
}
|
|
19087
|
-
)
|
|
19088
|
-
]
|
|
19089
|
-
}
|
|
19090
|
-
),
|
|
19091
|
-
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
|
|
19092
|
-
] }, id2);
|
|
19093
|
-
}
|
|
19094
|
-
const id = itemData.id || String(index);
|
|
19095
|
-
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
19096
|
-
return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id, children: [
|
|
19097
|
-
/* @__PURE__ */ jsxs(
|
|
19098
|
-
Box,
|
|
19099
|
-
{
|
|
19100
|
-
className: cn(
|
|
19101
|
-
"group flex items-center gap-4 transition-all duration-200",
|
|
19102
|
-
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
19103
|
-
"hover:bg-muted/80",
|
|
19104
|
-
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
19105
|
-
),
|
|
19106
|
-
children: [
|
|
19107
|
-
/* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
|
|
19108
|
-
/* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "items-center", children: [
|
|
19109
|
-
titleField?.icon && /* @__PURE__ */ jsx(
|
|
19110
|
-
Icon,
|
|
19111
|
-
{
|
|
19112
|
-
name: titleField.icon,
|
|
19113
|
-
size: isCompact ? "xs" : "sm",
|
|
19114
|
-
className: "text-primary flex-shrink-0"
|
|
19115
|
-
}
|
|
19116
|
-
),
|
|
19117
|
-
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsx(
|
|
19118
|
-
Typography,
|
|
19119
|
-
{
|
|
19120
|
-
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
19121
|
-
className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
|
|
19122
|
-
children: String(titleValue)
|
|
19123
|
-
}
|
|
19124
|
-
),
|
|
19125
|
-
badgeFields.map((field) => {
|
|
19126
|
-
const val = getNestedValue(itemData, field.name);
|
|
19127
|
-
if (val === void 0 || val === null) return null;
|
|
19128
|
-
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
19129
|
-
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
|
|
19130
|
-
/* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: String(val) })
|
|
19131
|
-
] }, field.name);
|
|
19132
|
-
})
|
|
19133
|
-
] }),
|
|
19134
|
-
bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
|
|
19135
|
-
const value = getNestedValue(itemData, field.name);
|
|
19136
|
-
if (value === void 0 || value === null || value === "") return null;
|
|
19137
|
-
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
19138
|
-
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
19139
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "secondary", children: [
|
|
19140
|
-
field.label ?? fieldLabel3(field.name),
|
|
19141
|
-
":"
|
|
19142
|
-
] }),
|
|
19143
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue2(value, field.format) })
|
|
19144
|
-
] }, field.name);
|
|
19145
|
-
}) }),
|
|
19146
|
-
progressFields.map((field) => {
|
|
19147
|
-
const value = getNestedValue(itemData, field.name);
|
|
19148
|
-
if (typeof value !== "number") return null;
|
|
19149
|
-
return /* @__PURE__ */ jsxs(Box, { className: "mt-2 max-w-xs", children: [
|
|
19150
|
-
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center mb-1", children: [
|
|
19151
|
-
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
|
|
19152
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel3(field.name) })
|
|
19153
|
-
] }),
|
|
19154
|
-
/* @__PURE__ */ jsx(ProgressBar, { value, max: 100 })
|
|
19155
|
-
] }, field.name);
|
|
19156
|
-
})
|
|
19157
|
-
] }),
|
|
19158
|
-
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
19159
|
-
Button,
|
|
19160
|
-
{
|
|
19161
|
-
variant: action.variant ?? "ghost",
|
|
19162
|
-
size: "sm",
|
|
19163
|
-
onClick: handleActionClick(action, itemData),
|
|
19164
|
-
"data-testid": `action-${action.event}`,
|
|
19165
|
-
className: cn(
|
|
19166
|
-
action.variant === "danger" && "text-error hover:bg-error/10"
|
|
19167
|
-
),
|
|
19168
|
-
children: [
|
|
19169
|
-
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
19170
|
-
action.label
|
|
19171
|
-
]
|
|
19172
|
-
},
|
|
19173
|
-
idx
|
|
19174
|
-
)) })
|
|
19175
|
-
]
|
|
19176
|
-
}
|
|
19177
|
-
),
|
|
19178
|
-
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
|
|
19179
|
-
] }, id);
|
|
19180
|
-
};
|
|
19181
|
-
return /* @__PURE__ */ jsxs(
|
|
19182
|
-
Box,
|
|
19183
|
-
{
|
|
19184
|
-
className: cn(
|
|
19185
|
-
isCard && "bg-card rounded-xl border border-border shadow-lg overflow-hidden",
|
|
19186
|
-
!isCard && gapClass,
|
|
19187
|
-
className
|
|
19188
|
-
),
|
|
19189
|
-
children: [
|
|
19190
|
-
groups.map((group, gi) => /* @__PURE__ */ jsxs(React115__default.Fragment, { children: [
|
|
19191
|
-
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
|
|
19192
|
-
group.items.map(
|
|
19193
|
-
(itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
|
|
19194
|
-
)
|
|
19195
|
-
] }, gi)),
|
|
19196
|
-
hasMoreLocal && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(
|
|
19197
|
-
Button,
|
|
19198
|
-
{
|
|
19199
|
-
variant: "ghost",
|
|
19200
|
-
size: "sm",
|
|
19201
|
-
onClick: () => setVisibleCount((prev) => prev + (pageSize || 5)),
|
|
19202
|
-
children: [
|
|
19203
|
-
/* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
19204
|
-
t("common.showMore"),
|
|
19205
|
-
" (",
|
|
19206
|
-
allData.length - visibleCount,
|
|
19207
|
-
" remaining)"
|
|
19208
|
-
]
|
|
19209
|
-
}
|
|
19210
|
-
) }),
|
|
19211
|
-
infiniteScroll && loadMoreEvent && /* @__PURE__ */ jsx(
|
|
19212
|
-
InfiniteScrollSentinel,
|
|
19213
|
-
{
|
|
19214
|
-
loadMoreEvent,
|
|
19215
|
-
isLoading,
|
|
19216
|
-
hasMore
|
|
19217
|
-
}
|
|
19218
|
-
)
|
|
19219
|
-
]
|
|
19220
|
-
}
|
|
19221
|
-
);
|
|
19222
|
-
};
|
|
19223
19222
|
DataList.displayName = "DataList";
|
|
19224
19223
|
}
|
|
19225
19224
|
});
|
|
@@ -20420,7 +20419,10 @@ var init_WizardProgress = __esm({
|
|
|
20420
20419
|
stepClickEvent
|
|
20421
20420
|
}) => {
|
|
20422
20421
|
const eventBus = useEventBus();
|
|
20423
|
-
const
|
|
20422
|
+
const normalizedSteps = steps.map(
|
|
20423
|
+
(s, i) => typeof s === "string" ? { id: `step-${i}`, title: s } : s
|
|
20424
|
+
);
|
|
20425
|
+
const totalSteps = normalizedSteps.length;
|
|
20424
20426
|
const handleStepClick = (index) => {
|
|
20425
20427
|
const isCompleted = index < currentStep;
|
|
20426
20428
|
if (isCompleted && allowNavigation) {
|
|
@@ -20437,7 +20439,7 @@ var init_WizardProgress = __esm({
|
|
|
20437
20439
|
compact ? "px-4 py-2" : "px-6 py-4",
|
|
20438
20440
|
className
|
|
20439
20441
|
),
|
|
20440
|
-
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children:
|
|
20442
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
|
|
20441
20443
|
const isActive = index === currentStep;
|
|
20442
20444
|
const isCompleted = index < currentStep;
|
|
20443
20445
|
return /* @__PURE__ */ jsxs(React115__default.Fragment, { children: [
|
|
@@ -38633,161 +38635,6 @@ function OrbitalProvider({
|
|
|
38633
38635
|
);
|
|
38634
38636
|
}
|
|
38635
38637
|
OrbitalProvider.displayName = "OrbitalProvider";
|
|
38636
|
-
var FetchedDataContext = createContext(null);
|
|
38637
|
-
function FetchedDataProvider({
|
|
38638
|
-
initialData,
|
|
38639
|
-
children
|
|
38640
|
-
}) {
|
|
38641
|
-
const [state, setState] = useState(() => ({
|
|
38642
|
-
data: initialData || {},
|
|
38643
|
-
fetchedAt: {},
|
|
38644
|
-
loading: false,
|
|
38645
|
-
error: null
|
|
38646
|
-
}));
|
|
38647
|
-
const getData = useCallback(
|
|
38648
|
-
(entityName) => {
|
|
38649
|
-
return state.data[entityName] || [];
|
|
38650
|
-
},
|
|
38651
|
-
[state.data]
|
|
38652
|
-
);
|
|
38653
|
-
const getById = useCallback(
|
|
38654
|
-
(entityName, id) => {
|
|
38655
|
-
const records = state.data[entityName];
|
|
38656
|
-
return records?.find((r) => r.id === id);
|
|
38657
|
-
},
|
|
38658
|
-
[state.data]
|
|
38659
|
-
);
|
|
38660
|
-
const hasData = useCallback(
|
|
38661
|
-
(entityName) => {
|
|
38662
|
-
return entityName in state.data && state.data[entityName].length > 0;
|
|
38663
|
-
},
|
|
38664
|
-
[state.data]
|
|
38665
|
-
);
|
|
38666
|
-
const getFetchedAt = useCallback(
|
|
38667
|
-
(entityName) => {
|
|
38668
|
-
return state.fetchedAt[entityName];
|
|
38669
|
-
},
|
|
38670
|
-
[state.fetchedAt]
|
|
38671
|
-
);
|
|
38672
|
-
const setData = useCallback((data) => {
|
|
38673
|
-
const now = Date.now();
|
|
38674
|
-
setState((prev) => ({
|
|
38675
|
-
...prev,
|
|
38676
|
-
data: {
|
|
38677
|
-
...prev.data,
|
|
38678
|
-
...data
|
|
38679
|
-
},
|
|
38680
|
-
fetchedAt: {
|
|
38681
|
-
...prev.fetchedAt,
|
|
38682
|
-
...Object.keys(data).reduce(
|
|
38683
|
-
(acc, key) => ({ ...acc, [key]: now }),
|
|
38684
|
-
{}
|
|
38685
|
-
)
|
|
38686
|
-
},
|
|
38687
|
-
loading: false,
|
|
38688
|
-
error: null
|
|
38689
|
-
}));
|
|
38690
|
-
}, []);
|
|
38691
|
-
const clearData = useCallback(() => {
|
|
38692
|
-
setState((prev) => ({
|
|
38693
|
-
...prev,
|
|
38694
|
-
data: {},
|
|
38695
|
-
fetchedAt: {}
|
|
38696
|
-
}));
|
|
38697
|
-
}, []);
|
|
38698
|
-
const clearEntity = useCallback((entityName) => {
|
|
38699
|
-
setState((prev) => {
|
|
38700
|
-
const newData = { ...prev.data };
|
|
38701
|
-
const newFetchedAt = { ...prev.fetchedAt };
|
|
38702
|
-
delete newData[entityName];
|
|
38703
|
-
delete newFetchedAt[entityName];
|
|
38704
|
-
return {
|
|
38705
|
-
...prev,
|
|
38706
|
-
data: newData,
|
|
38707
|
-
fetchedAt: newFetchedAt
|
|
38708
|
-
};
|
|
38709
|
-
});
|
|
38710
|
-
}, []);
|
|
38711
|
-
const setLoading = useCallback((loading) => {
|
|
38712
|
-
setState((prev) => ({ ...prev, loading }));
|
|
38713
|
-
}, []);
|
|
38714
|
-
const setError = useCallback((error) => {
|
|
38715
|
-
setState((prev) => ({ ...prev, error, loading: false }));
|
|
38716
|
-
}, []);
|
|
38717
|
-
const contextValue = useMemo(
|
|
38718
|
-
() => ({
|
|
38719
|
-
getData,
|
|
38720
|
-
getById,
|
|
38721
|
-
hasData,
|
|
38722
|
-
getFetchedAt,
|
|
38723
|
-
setData,
|
|
38724
|
-
clearData,
|
|
38725
|
-
clearEntity,
|
|
38726
|
-
loading: state.loading,
|
|
38727
|
-
setLoading,
|
|
38728
|
-
error: state.error,
|
|
38729
|
-
setError
|
|
38730
|
-
}),
|
|
38731
|
-
[
|
|
38732
|
-
getData,
|
|
38733
|
-
getById,
|
|
38734
|
-
hasData,
|
|
38735
|
-
getFetchedAt,
|
|
38736
|
-
setData,
|
|
38737
|
-
clearData,
|
|
38738
|
-
clearEntity,
|
|
38739
|
-
state.loading,
|
|
38740
|
-
setLoading,
|
|
38741
|
-
state.error,
|
|
38742
|
-
setError
|
|
38743
|
-
]
|
|
38744
|
-
);
|
|
38745
|
-
return /* @__PURE__ */ jsx(FetchedDataContext.Provider, { value: contextValue, children });
|
|
38746
|
-
}
|
|
38747
|
-
function useFetchedDataContext() {
|
|
38748
|
-
return useContext(FetchedDataContext);
|
|
38749
|
-
}
|
|
38750
|
-
function useFetchedData() {
|
|
38751
|
-
const context = useContext(FetchedDataContext);
|
|
38752
|
-
if (!context) {
|
|
38753
|
-
return {
|
|
38754
|
-
getData: () => [],
|
|
38755
|
-
getById: () => void 0,
|
|
38756
|
-
hasData: () => false,
|
|
38757
|
-
getFetchedAt: () => void 0,
|
|
38758
|
-
setData: () => {
|
|
38759
|
-
},
|
|
38760
|
-
clearData: () => {
|
|
38761
|
-
},
|
|
38762
|
-
clearEntity: () => {
|
|
38763
|
-
},
|
|
38764
|
-
loading: false,
|
|
38765
|
-
setLoading: () => {
|
|
38766
|
-
},
|
|
38767
|
-
error: null,
|
|
38768
|
-
setError: () => {
|
|
38769
|
-
}
|
|
38770
|
-
};
|
|
38771
|
-
}
|
|
38772
|
-
return context;
|
|
38773
|
-
}
|
|
38774
|
-
function useFetchedEntity(entityName) {
|
|
38775
|
-
const context = useFetchedData();
|
|
38776
|
-
return {
|
|
38777
|
-
/** All fetched records for this entity */
|
|
38778
|
-
records: context.getData(entityName),
|
|
38779
|
-
/** Get a record by ID */
|
|
38780
|
-
getById: (id) => context.getById(entityName, id),
|
|
38781
|
-
/** Whether data has been fetched for this entity */
|
|
38782
|
-
hasData: context.hasData(entityName),
|
|
38783
|
-
/** When data was last fetched */
|
|
38784
|
-
fetchedAt: context.getFetchedAt(entityName),
|
|
38785
|
-
/** Whether data is loading */
|
|
38786
|
-
loading: context.loading,
|
|
38787
|
-
/** Current error */
|
|
38788
|
-
error: context.error
|
|
38789
|
-
};
|
|
38790
|
-
}
|
|
38791
38638
|
|
|
38792
38639
|
// providers/OfflineModeProvider.tsx
|
|
38793
38640
|
init_offline_executor();
|
|
@@ -38821,4 +38668,4 @@ function useOptionalOfflineMode() {
|
|
|
38821
38668
|
return useContext(OfflineModeContext);
|
|
38822
38669
|
}
|
|
38823
38670
|
|
|
38824
|
-
export { EventBusContext2 as EventBusContext, EventBusProvider,
|
|
38671
|
+
export { EventBusContext2 as EventBusContext, EventBusProvider, OfflineModeProvider, OrbitalProvider, SelectionContext, SelectionProvider, VerificationProvider, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional };
|