@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.
@@ -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: useCallback95, useState: useState87 } = React115__namespace.default;
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] = useState87(null);
7965
- const handleMapClick = useCallback95((lat, lng) => {
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 = useCallback95((marker) => {
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
- var gapStyles6, DataGrid;
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
- entity,
18628
- fields: fieldsProp,
18629
- columns: columnsProp,
18630
- itemActions,
18631
- cols,
18632
- gap = "md",
18633
- minCardWidth = 280,
18634
- className,
18635
- isLoading = false,
18636
- error = null,
18637
- imageField,
18638
- selectable = false,
18639
- selectionEvent,
18640
- infiniteScroll,
18641
- loadMoreEvent,
18642
- hasMore,
18643
- children,
18644
- pageSize = 0
18645
- }) => {
18646
- const eventBus = useEventBus();
18647
- const { t } = useTranslate();
18648
- const [selectedIds, setSelectedIds] = React115.useState(/* @__PURE__ */ new Set());
18649
- const [visibleCount, setVisibleCount] = React115.useState(pageSize || Infinity);
18650
- const fields = fieldsProp ?? columnsProp ?? [];
18651
- const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
18652
- const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
18653
- const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
18654
- const toggleSelection = React115.useCallback((id) => {
18655
- setSelectedIds((prev) => {
18656
- const next = new Set(prev);
18657
- if (next.has(id)) next.delete(id);
18658
- else next.add(id);
18659
- if (selectionEvent) {
18660
- const payload = { selectedIds: Array.from(next) };
18661
- eventBus.emit(`UI:${selectionEvent}`, payload);
18662
- }
18663
- return next;
18664
- });
18665
- }, [selectionEvent, eventBus]);
18666
- const toggleAll = React115.useCallback(() => {
18667
- setSelectedIds((prev) => {
18668
- const allIds2 = data.map((item, i) => item.id || String(i));
18669
- const allSelected2 = allIds2.length > 0 && allIds2.every((id) => prev.has(id));
18670
- const next = allSelected2 ? /* @__PURE__ */ new Set() : new Set(allIds2);
18671
- if (selectionEvent) {
18672
- const payload = { selectedIds: Array.from(next) };
18673
- eventBus.emit(`UI:${selectionEvent}`, payload);
18674
- }
18675
- return next;
18676
- });
18677
- }, [data, selectionEvent, eventBus]);
18678
- const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
18679
- const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
18680
- const bodyFields = fields.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
18681
- const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
18682
- const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
18683
- const handleActionClick = (action, itemData) => (e) => {
18684
- e.stopPropagation();
18685
- const payload = {
18686
- id: itemData.id,
18687
- row: itemData
18688
- };
18689
- eventBus.emit(`UI:${action.event}`, payload);
18690
- };
18691
- const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
18692
- const colsClass = cols ? {
18693
- 1: "grid-cols-1",
18694
- 2: "sm:grid-cols-2",
18695
- 3: "sm:grid-cols-2 lg:grid-cols-3",
18696
- 4: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
18697
- 5: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5",
18698
- 6: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6"
18699
- }[cols] : void 0;
18700
- if (isLoading) {
18701
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
18702
- }
18703
- if (error) {
18704
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "error", children: error.message }) });
18705
- }
18706
- if (data.length === 0) {
18707
- 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" }) });
18708
- }
18709
- const hasRenderProp = typeof children === "function";
18710
- const allIds = data.map((item, i) => item.id || String(i));
18711
- const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.has(id));
18712
- const someSelected = selectedIds.size > 0;
18713
- return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
18714
- selectable && someSelected && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "items-center px-2 py-2 bg-muted rounded-sm", children: [
18715
- /* @__PURE__ */ jsxRuntime.jsx(
18716
- "input",
18717
- {
18718
- type: "checkbox",
18719
- checked: allSelected,
18720
- onChange: toggleAll,
18721
- className: "w-4 h-4 accent-primary",
18722
- "aria-label": "Select all"
18723
- }
18724
- ),
18725
- /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "font-semibold", children: [
18726
- selectedIds.size,
18727
- " ",
18728
- t("common.selected") || "selected"
18729
- ] })
18730
- ] }),
18731
- /* @__PURE__ */ jsxRuntime.jsx(
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("grid", gapStyles6[gap], colsClass, className),
18735
- style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
18736
- children: data.map((item, index) => {
18737
- const itemData = item;
18738
- const id = itemData.id || String(index);
18739
- const isSelected = selectedIds.has(id);
18740
- if (hasRenderProp) {
18741
- return /* @__PURE__ */ jsxRuntime.jsx(
18742
- Box,
18743
- {
18744
- "data-entity-row": true,
18745
- "data-entity-id": id,
18746
- className: cn(
18747
- "bg-card rounded-lg",
18748
- "border border-border",
18749
- "shadow-sm hover:shadow-lg",
18750
- "hover:border-primary transition-all",
18751
- "p-4",
18752
- isSelected && "ring-2 ring-primary border-primary"
18753
- ),
18754
- children: children(itemData, index)
18755
- },
18756
- id
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
- const titleValue = getNestedValue(itemData, titleField?.name ?? "");
18760
- return /* @__PURE__ */ jsxRuntime.jsxs(
18761
- Box,
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
- "data-entity-row": true,
18764
- "data-entity-id": id,
18765
- className: cn(
18766
- "bg-card rounded-lg",
18767
- "border border-border",
18768
- "shadow-sm hover:shadow-lg",
18769
- "hover:border-primary transition-all",
18770
- "flex flex-col",
18771
- isSelected && "ring-2 ring-primary border-primary"
18772
- ),
18773
- children: [
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
- /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
18800
- titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
18801
- titleField?.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: titleField.icon, size: "sm", className: "text-primary flex-shrink-0" }),
18802
- /* @__PURE__ */ jsxRuntime.jsx(
18803
- Typography,
18804
- {
18805
- variant: titleField?.variant === "h3" ? "h3" : "h4",
18806
- className: "font-semibold truncate",
18807
- children: String(titleValue)
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
- 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 }));
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 totalSteps = steps.length;
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: steps.map((step, index) => {
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;