@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.
@@ -1,7 +1,7 @@
1
1
  import { clsx } from 'clsx';
2
2
  import { twMerge } from 'tailwind-merge';
3
3
  import * as React110 from 'react';
4
- import React110__default, { createContext, useContext, useRef, useEffect, useCallback, useState, Suspense, useMemo, lazy, useSyncExternalStore, useLayoutEffect, useId } from 'react';
4
+ import React110__default, { useContext, useRef, useEffect, useCallback, createContext, useState, Suspense, useMemo, lazy, useSyncExternalStore, useLayoutEffect, useId } from 'react';
5
5
  import { EventBusContext, SelectionContext } from '@almadar/ui/providers';
6
6
  import * as LucideIcons from 'lucide-react';
7
7
  import { Loader2, X, AlertTriangle, Info, AlertCircle, CheckCircle, ChevronDown, List, Printer, ChevronRight, ChevronLeft, XCircle, Wrench, RotateCcw, Send, Code, FileText, WrapText, Check, Copy, Zap, Sword, Move, Heart, Shield, Trash2, Settings, Menu as Menu$1, Search, Bell, LogOut, ChevronUp, MoreHorizontal, Bug, ZoomOut, ZoomIn, Download, Pause, Play, Package, Calendar, Pencil, Eye, Image as Image$1, Upload, ArrowRight, ArrowLeft, Eraser, SkipForward, TrendingUp, TrendingDown, Minus, ArrowUp, ArrowDown, MoreVertical, Circle, Clock, CheckCircle2, HelpCircle, FileQuestion, Inbox, Plus, User, Filter, Star, FileWarning, Tag, DollarSign, Sun, Moon } from 'lucide-react';
@@ -35,7 +35,7 @@ import langGo from 'react-syntax-highlighter/dist/esm/languages/prism/go.js';
35
35
  import langGraphql from 'react-syntax-highlighter/dist/esm/languages/prism/graphql.js';
36
36
  import { isInlineTrait } from '@almadar/core';
37
37
  import { useUISlots } from '@almadar/ui/context';
38
- import { useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
38
+ import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
39
39
 
40
40
  var __defProp = Object.defineProperty;
41
41
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -6241,13 +6241,13 @@ var init_MapView = __esm({
6241
6241
  shadowSize: [41, 41]
6242
6242
  });
6243
6243
  L.Marker.prototype.options.icon = defaultIcon;
6244
- const { useEffect: useEffect67, useRef: useRef64, useCallback: useCallback114, useState: useState100 } = React110__default;
6244
+ const { useEffect: useEffect66, useRef: useRef64, useCallback: useCallback114, useState: useState99 } = React110__default;
6245
6245
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
6246
6246
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
6247
6247
  function MapUpdater({ centerLat, centerLng, zoom }) {
6248
6248
  const map = useMap();
6249
6249
  const prevRef = useRef64({ centerLat, centerLng, zoom });
6250
- useEffect67(() => {
6250
+ useEffect66(() => {
6251
6251
  const prev = prevRef.current;
6252
6252
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
6253
6253
  map.setView([centerLat, centerLng], zoom);
@@ -6258,7 +6258,7 @@ var init_MapView = __esm({
6258
6258
  }
6259
6259
  function MapClickHandler({ onMapClick }) {
6260
6260
  const map = useMap();
6261
- useEffect67(() => {
6261
+ useEffect66(() => {
6262
6262
  if (!onMapClick) return;
6263
6263
  const handler = (e) => {
6264
6264
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -6285,7 +6285,7 @@ var init_MapView = __esm({
6285
6285
  showAttribution = true
6286
6286
  }) {
6287
6287
  const eventBus = useEventBus2();
6288
- const [clickedPosition, setClickedPosition] = useState100(null);
6288
+ const [clickedPosition, setClickedPosition] = useState99(null);
6289
6289
  const handleMapClick = useCallback114((lat, lng) => {
6290
6290
  if (showClickedPin) {
6291
6291
  setClickedPosition({ lat, lng });
@@ -17244,7 +17244,290 @@ function formatValue(value, format) {
17244
17244
  return String(value);
17245
17245
  }
17246
17246
  }
17247
- var gapStyles6, DataGrid;
17247
+ function DataGrid({
17248
+ entity,
17249
+ fields: fieldsProp,
17250
+ columns: columnsProp,
17251
+ itemActions,
17252
+ cols,
17253
+ gap = "md",
17254
+ minCardWidth = 280,
17255
+ className,
17256
+ isLoading = false,
17257
+ error = null,
17258
+ imageField,
17259
+ selectable = false,
17260
+ selectionEvent,
17261
+ infiniteScroll,
17262
+ loadMoreEvent,
17263
+ hasMore,
17264
+ children,
17265
+ pageSize = 0
17266
+ }) {
17267
+ const eventBus = useEventBus();
17268
+ const { t } = useTranslate();
17269
+ const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
17270
+ const [visibleCount, setVisibleCount] = useState(pageSize || Infinity);
17271
+ const fields = fieldsProp ?? columnsProp ?? [];
17272
+ const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
17273
+ const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
17274
+ const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
17275
+ const toggleSelection = useCallback((id) => {
17276
+ setSelectedIds((prev) => {
17277
+ const next = new Set(prev);
17278
+ if (next.has(id)) next.delete(id);
17279
+ else next.add(id);
17280
+ if (selectionEvent) {
17281
+ const payload = { selectedIds: Array.from(next) };
17282
+ eventBus.emit(`UI:${selectionEvent}`, payload);
17283
+ }
17284
+ return next;
17285
+ });
17286
+ }, [selectionEvent, eventBus]);
17287
+ const toggleAll = useCallback(() => {
17288
+ setSelectedIds((prev) => {
17289
+ const allIds2 = data.map((item, i) => item.id || String(i));
17290
+ const allSelected2 = allIds2.length > 0 && allIds2.every((id) => prev.has(id));
17291
+ const next = allSelected2 ? /* @__PURE__ */ new Set() : new Set(allIds2);
17292
+ if (selectionEvent) {
17293
+ const payload = { selectedIds: Array.from(next) };
17294
+ eventBus.emit(`UI:${selectionEvent}`, payload);
17295
+ }
17296
+ return next;
17297
+ });
17298
+ }, [data, selectionEvent, eventBus]);
17299
+ const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
17300
+ const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
17301
+ const bodyFields = fields.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
17302
+ const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
17303
+ const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
17304
+ const handleActionClick = (action, itemData) => (e) => {
17305
+ e.stopPropagation();
17306
+ const payload = {
17307
+ id: itemData.id,
17308
+ row: itemData
17309
+ };
17310
+ eventBus.emit(`UI:${action.event}`, payload);
17311
+ };
17312
+ const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
17313
+ const colsClass = cols ? {
17314
+ 1: "grid-cols-1",
17315
+ 2: "sm:grid-cols-2",
17316
+ 3: "sm:grid-cols-2 lg:grid-cols-3",
17317
+ 4: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
17318
+ 5: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5",
17319
+ 6: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6"
17320
+ }[cols] : void 0;
17321
+ if (isLoading) {
17322
+ return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
17323
+ }
17324
+ if (error) {
17325
+ return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
17326
+ }
17327
+ if (data.length === 0) {
17328
+ return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
17329
+ }
17330
+ const hasRenderProp = typeof children === "function";
17331
+ const allIds = data.map((item, i) => item.id || String(i));
17332
+ const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.has(id));
17333
+ const someSelected = selectedIds.size > 0;
17334
+ return /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
17335
+ selectable && someSelected && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "items-center px-2 py-2 bg-muted rounded-sm", children: [
17336
+ /* @__PURE__ */ jsx(
17337
+ "input",
17338
+ {
17339
+ type: "checkbox",
17340
+ checked: allSelected,
17341
+ onChange: toggleAll,
17342
+ className: "w-4 h-4 accent-primary",
17343
+ "aria-label": "Select all"
17344
+ }
17345
+ ),
17346
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "font-semibold", children: [
17347
+ selectedIds.size,
17348
+ " ",
17349
+ t("common.selected") || "selected"
17350
+ ] })
17351
+ ] }),
17352
+ /* @__PURE__ */ jsx(
17353
+ Box,
17354
+ {
17355
+ className: cn("grid", gapStyles6[gap], colsClass, className),
17356
+ style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
17357
+ children: data.map((item, index) => {
17358
+ const itemData = item;
17359
+ const id = itemData.id || String(index);
17360
+ const isSelected = selectedIds.has(id);
17361
+ if (hasRenderProp) {
17362
+ return /* @__PURE__ */ jsx(
17363
+ Box,
17364
+ {
17365
+ "data-entity-row": true,
17366
+ "data-entity-id": id,
17367
+ className: cn(
17368
+ "bg-card rounded-lg",
17369
+ "border border-border",
17370
+ "shadow-sm hover:shadow-lg",
17371
+ "hover:border-primary transition-all",
17372
+ "p-4",
17373
+ isSelected && "ring-2 ring-primary border-primary"
17374
+ ),
17375
+ children: children(itemData, index)
17376
+ },
17377
+ id
17378
+ );
17379
+ }
17380
+ const titleValue = getNestedValue(itemData, titleField?.name ?? "");
17381
+ return /* @__PURE__ */ jsxs(
17382
+ Box,
17383
+ {
17384
+ "data-entity-row": true,
17385
+ "data-entity-id": id,
17386
+ className: cn(
17387
+ "bg-card rounded-lg",
17388
+ "border border-border",
17389
+ "shadow-sm hover:shadow-lg",
17390
+ "hover:border-primary transition-all",
17391
+ "flex flex-col",
17392
+ isSelected && "ring-2 ring-primary border-primary"
17393
+ ),
17394
+ children: [
17395
+ imageField && (() => {
17396
+ const imgUrl = getNestedValue(itemData, imageField);
17397
+ if (!imgUrl || typeof imgUrl !== "string") return null;
17398
+ return /* @__PURE__ */ jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-lg", children: /* @__PURE__ */ jsx(
17399
+ "img",
17400
+ {
17401
+ src: imgUrl,
17402
+ alt: titleValue !== void 0 ? String(titleValue) : "",
17403
+ className: "w-full h-full object-cover",
17404
+ loading: "lazy"
17405
+ }
17406
+ ) });
17407
+ })(),
17408
+ /* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
17409
+ selectable && /* @__PURE__ */ jsx(
17410
+ "input",
17411
+ {
17412
+ type: "checkbox",
17413
+ checked: isSelected,
17414
+ onChange: () => toggleSelection(id),
17415
+ onClick: (e) => e.stopPropagation(),
17416
+ className: "w-4 h-4 mt-1 flex-shrink-0 accent-primary",
17417
+ "aria-label": `Select ${titleValue !== void 0 ? String(titleValue) : "item"}`
17418
+ }
17419
+ ),
17420
+ /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
17421
+ titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17422
+ titleField?.icon && /* @__PURE__ */ jsx(Icon, { name: titleField.icon, size: "sm", className: "text-primary flex-shrink-0" }),
17423
+ /* @__PURE__ */ jsx(
17424
+ Typography,
17425
+ {
17426
+ variant: titleField?.variant === "h3" ? "h3" : "h4",
17427
+ className: "font-semibold truncate",
17428
+ children: String(titleValue)
17429
+ }
17430
+ )
17431
+ ] }),
17432
+ badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
17433
+ const val = getNestedValue(itemData, field.name);
17434
+ if (val === void 0 || val === null) return null;
17435
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17436
+ field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
17437
+ /* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
17438
+ ] }, field.name);
17439
+ }) })
17440
+ ] }),
17441
+ dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxs(
17442
+ Button,
17443
+ {
17444
+ variant: "ghost",
17445
+ size: "sm",
17446
+ onClick: handleActionClick(action, itemData),
17447
+ "data-testid": `action-${action.event}`,
17448
+ className: "text-error hover:bg-error/10 px-2",
17449
+ children: [
17450
+ action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs" }),
17451
+ action.label
17452
+ ]
17453
+ },
17454
+ idx
17455
+ )) })
17456
+ ] }) }),
17457
+ bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
17458
+ const value = getNestedValue(itemData, field.name);
17459
+ if (value === void 0 || value === null || value === "") return null;
17460
+ if (field.format === "boolean") {
17461
+ return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
17462
+ /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17463
+ field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
17464
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
17465
+ ] }),
17466
+ /* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
17467
+ ] }, field.name);
17468
+ }
17469
+ return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
17470
+ /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17471
+ field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
17472
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
17473
+ ] }),
17474
+ /* @__PURE__ */ jsx(
17475
+ Typography,
17476
+ {
17477
+ variant: field.variant === "caption" ? "caption" : "small",
17478
+ className: "text-right truncate max-w-[60%]",
17479
+ children: formatValue(value, field.format)
17480
+ }
17481
+ )
17482
+ ] }, field.name);
17483
+ }) }) }),
17484
+ 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(
17485
+ Button,
17486
+ {
17487
+ variant: action.variant === "primary" ? "primary" : "ghost",
17488
+ size: "sm",
17489
+ onClick: handleActionClick(action, itemData),
17490
+ "data-testid": `action-${action.event}`,
17491
+ children: [
17492
+ action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
17493
+ action.label
17494
+ ]
17495
+ },
17496
+ idx
17497
+ )) }) })
17498
+ ]
17499
+ },
17500
+ id
17501
+ );
17502
+ })
17503
+ }
17504
+ ),
17505
+ hasMoreLocal && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(
17506
+ Button,
17507
+ {
17508
+ variant: "ghost",
17509
+ size: "sm",
17510
+ onClick: () => setVisibleCount((prev) => prev + (pageSize || 5)),
17511
+ children: [
17512
+ /* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
17513
+ t("common.showMore"),
17514
+ " (",
17515
+ allData.length - visibleCount,
17516
+ " remaining)"
17517
+ ]
17518
+ }
17519
+ ) }),
17520
+ infiniteScroll && loadMoreEvent && /* @__PURE__ */ jsx(
17521
+ InfiniteScrollSentinel,
17522
+ {
17523
+ loadMoreEvent,
17524
+ isLoading,
17525
+ hasMore
17526
+ }
17527
+ )
17528
+ ] });
17529
+ }
17530
+ var gapStyles6;
17248
17531
  var init_DataGrid = __esm({
17249
17532
  "components/molecules/DataGrid.tsx"() {
17250
17533
  "use client";
@@ -17266,289 +17549,6 @@ var init_DataGrid = __esm({
17266
17549
  lg: "gap-6",
17267
17550
  xl: "gap-8"
17268
17551
  };
17269
- DataGrid = ({
17270
- entity,
17271
- fields: fieldsProp,
17272
- columns: columnsProp,
17273
- itemActions,
17274
- cols,
17275
- gap = "md",
17276
- minCardWidth = 280,
17277
- className,
17278
- isLoading = false,
17279
- error = null,
17280
- imageField,
17281
- selectable = false,
17282
- selectionEvent,
17283
- infiniteScroll,
17284
- loadMoreEvent,
17285
- hasMore,
17286
- children,
17287
- pageSize = 0
17288
- }) => {
17289
- const eventBus = useEventBus();
17290
- const { t } = useTranslate();
17291
- const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
17292
- const [visibleCount, setVisibleCount] = useState(pageSize || Infinity);
17293
- const fields = fieldsProp ?? columnsProp ?? [];
17294
- const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
17295
- const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
17296
- const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
17297
- const toggleSelection = useCallback((id) => {
17298
- setSelectedIds((prev) => {
17299
- const next = new Set(prev);
17300
- if (next.has(id)) next.delete(id);
17301
- else next.add(id);
17302
- if (selectionEvent) {
17303
- const payload = { selectedIds: Array.from(next) };
17304
- eventBus.emit(`UI:${selectionEvent}`, payload);
17305
- }
17306
- return next;
17307
- });
17308
- }, [selectionEvent, eventBus]);
17309
- const toggleAll = useCallback(() => {
17310
- setSelectedIds((prev) => {
17311
- const allIds2 = data.map((item, i) => item.id || String(i));
17312
- const allSelected2 = allIds2.length > 0 && allIds2.every((id) => prev.has(id));
17313
- const next = allSelected2 ? /* @__PURE__ */ new Set() : new Set(allIds2);
17314
- if (selectionEvent) {
17315
- const payload = { selectedIds: Array.from(next) };
17316
- eventBus.emit(`UI:${selectionEvent}`, payload);
17317
- }
17318
- return next;
17319
- });
17320
- }, [data, selectionEvent, eventBus]);
17321
- const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
17322
- const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
17323
- const bodyFields = fields.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
17324
- const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
17325
- const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
17326
- const handleActionClick = (action, itemData) => (e) => {
17327
- e.stopPropagation();
17328
- const payload = {
17329
- id: itemData.id,
17330
- row: itemData
17331
- };
17332
- eventBus.emit(`UI:${action.event}`, payload);
17333
- };
17334
- const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
17335
- const colsClass = cols ? {
17336
- 1: "grid-cols-1",
17337
- 2: "sm:grid-cols-2",
17338
- 3: "sm:grid-cols-2 lg:grid-cols-3",
17339
- 4: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
17340
- 5: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5",
17341
- 6: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6"
17342
- }[cols] : void 0;
17343
- if (isLoading) {
17344
- return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
17345
- }
17346
- if (error) {
17347
- return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
17348
- }
17349
- if (data.length === 0) {
17350
- return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
17351
- }
17352
- const hasRenderProp = typeof children === "function";
17353
- const allIds = data.map((item, i) => item.id || String(i));
17354
- const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.has(id));
17355
- const someSelected = selectedIds.size > 0;
17356
- return /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
17357
- selectable && someSelected && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "items-center px-2 py-2 bg-muted rounded-sm", children: [
17358
- /* @__PURE__ */ jsx(
17359
- "input",
17360
- {
17361
- type: "checkbox",
17362
- checked: allSelected,
17363
- onChange: toggleAll,
17364
- className: "w-4 h-4 accent-primary",
17365
- "aria-label": "Select all"
17366
- }
17367
- ),
17368
- /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "font-semibold", children: [
17369
- selectedIds.size,
17370
- " ",
17371
- t("common.selected") || "selected"
17372
- ] })
17373
- ] }),
17374
- /* @__PURE__ */ jsx(
17375
- Box,
17376
- {
17377
- className: cn("grid", gapStyles6[gap], colsClass, className),
17378
- style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
17379
- children: data.map((item, index) => {
17380
- const itemData = item;
17381
- const id = itemData.id || String(index);
17382
- const isSelected = selectedIds.has(id);
17383
- if (hasRenderProp) {
17384
- return /* @__PURE__ */ jsx(
17385
- Box,
17386
- {
17387
- "data-entity-row": true,
17388
- "data-entity-id": id,
17389
- className: cn(
17390
- "bg-card rounded-lg",
17391
- "border border-border",
17392
- "shadow-sm hover:shadow-lg",
17393
- "hover:border-primary transition-all",
17394
- "p-4",
17395
- isSelected && "ring-2 ring-primary border-primary"
17396
- ),
17397
- children: children(itemData, index)
17398
- },
17399
- id
17400
- );
17401
- }
17402
- const titleValue = getNestedValue(itemData, titleField?.name ?? "");
17403
- return /* @__PURE__ */ jsxs(
17404
- Box,
17405
- {
17406
- "data-entity-row": true,
17407
- "data-entity-id": id,
17408
- className: cn(
17409
- "bg-card rounded-lg",
17410
- "border border-border",
17411
- "shadow-sm hover:shadow-lg",
17412
- "hover:border-primary transition-all",
17413
- "flex flex-col",
17414
- isSelected && "ring-2 ring-primary border-primary"
17415
- ),
17416
- children: [
17417
- imageField && (() => {
17418
- const imgUrl = getNestedValue(itemData, imageField);
17419
- if (!imgUrl || typeof imgUrl !== "string") return null;
17420
- return /* @__PURE__ */ jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-lg", children: /* @__PURE__ */ jsx(
17421
- "img",
17422
- {
17423
- src: imgUrl,
17424
- alt: titleValue !== void 0 ? String(titleValue) : "",
17425
- className: "w-full h-full object-cover",
17426
- loading: "lazy"
17427
- }
17428
- ) });
17429
- })(),
17430
- /* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
17431
- selectable && /* @__PURE__ */ jsx(
17432
- "input",
17433
- {
17434
- type: "checkbox",
17435
- checked: isSelected,
17436
- onChange: () => toggleSelection(id),
17437
- onClick: (e) => e.stopPropagation(),
17438
- className: "w-4 h-4 mt-1 flex-shrink-0 accent-primary",
17439
- "aria-label": `Select ${titleValue !== void 0 ? String(titleValue) : "item"}`
17440
- }
17441
- ),
17442
- /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
17443
- titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17444
- titleField?.icon && /* @__PURE__ */ jsx(Icon, { name: titleField.icon, size: "sm", className: "text-primary flex-shrink-0" }),
17445
- /* @__PURE__ */ jsx(
17446
- Typography,
17447
- {
17448
- variant: titleField?.variant === "h3" ? "h3" : "h4",
17449
- className: "font-semibold truncate",
17450
- children: String(titleValue)
17451
- }
17452
- )
17453
- ] }),
17454
- badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
17455
- const val = getNestedValue(itemData, field.name);
17456
- if (val === void 0 || val === null) return null;
17457
- return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17458
- field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
17459
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
17460
- ] }, field.name);
17461
- }) })
17462
- ] }),
17463
- dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxs(
17464
- Button,
17465
- {
17466
- variant: "ghost",
17467
- size: "sm",
17468
- onClick: handleActionClick(action, itemData),
17469
- "data-testid": `action-${action.event}`,
17470
- className: "text-error hover:bg-error/10 px-2",
17471
- children: [
17472
- action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs" }),
17473
- action.label
17474
- ]
17475
- },
17476
- idx
17477
- )) })
17478
- ] }) }),
17479
- bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
17480
- const value = getNestedValue(itemData, field.name);
17481
- if (value === void 0 || value === null || value === "") return null;
17482
- if (field.format === "boolean") {
17483
- return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
17484
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17485
- field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
17486
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
17487
- ] }),
17488
- /* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
17489
- ] }, field.name);
17490
- }
17491
- return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
17492
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17493
- field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
17494
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
17495
- ] }),
17496
- /* @__PURE__ */ jsx(
17497
- Typography,
17498
- {
17499
- variant: field.variant === "caption" ? "caption" : "small",
17500
- className: "text-right truncate max-w-[60%]",
17501
- children: formatValue(value, field.format)
17502
- }
17503
- )
17504
- ] }, field.name);
17505
- }) }) }),
17506
- 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(
17507
- Button,
17508
- {
17509
- variant: action.variant === "primary" ? "primary" : "ghost",
17510
- size: "sm",
17511
- onClick: handleActionClick(action, itemData),
17512
- "data-testid": `action-${action.event}`,
17513
- children: [
17514
- action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
17515
- action.label
17516
- ]
17517
- },
17518
- idx
17519
- )) }) })
17520
- ]
17521
- },
17522
- id
17523
- );
17524
- })
17525
- }
17526
- ),
17527
- hasMoreLocal && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(
17528
- Button,
17529
- {
17530
- variant: "ghost",
17531
- size: "sm",
17532
- onClick: () => setVisibleCount((prev) => prev + (pageSize || 5)),
17533
- children: [
17534
- /* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
17535
- t("common.showMore"),
17536
- " (",
17537
- allData.length - visibleCount,
17538
- " remaining)"
17539
- ]
17540
- }
17541
- ) }),
17542
- infiniteScroll && loadMoreEvent && /* @__PURE__ */ jsx(
17543
- InfiniteScrollSentinel,
17544
- {
17545
- loadMoreEvent,
17546
- isLoading,
17547
- hasMore
17548
- }
17549
- )
17550
- ] });
17551
- };
17552
17552
  DataGrid.displayName = "DataGrid";
17553
17553
  }
17554
17554
  });
@@ -17596,318 +17596,317 @@ function groupData(items, field) {
17596
17596
  }
17597
17597
  return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
17598
17598
  }
17599
- var DataList;
17600
- var init_DataList = __esm({
17601
- "components/molecules/DataList.tsx"() {
17602
- "use client";
17603
- init_cn();
17604
- init_getNestedValue();
17605
- init_useEventBus();
17606
- init_useTranslate();
17607
- init_Box();
17608
- init_Stack();
17609
- init_Typography();
17610
- init_Badge();
17611
- init_Button();
17612
- init_Icon();
17613
- init_ProgressBar();
17614
- init_Divider();
17615
- init_InfiniteScrollSentinel();
17616
- DataList = ({
17617
- entity,
17618
- fields: fieldsProp,
17619
- columns: columnsProp,
17620
- itemActions,
17621
- gap = "none",
17622
- variant = "default",
17623
- groupBy,
17624
- senderField,
17625
- currentUser,
17626
- className,
17627
- isLoading = false,
17628
- error = null,
17629
- // Gesture props: reorderable, swipeLeftEvent, swipeRightEvent, longPressEvent
17630
- // are consumed by the compiler to wrap items in SwipeableRow/SortableList.
17631
- // DataList destructures them here to prevent DOM passthrough.
17632
- reorderable: _reorderable,
17633
- reorderEvent: _reorderEvent,
17634
- swipeLeftEvent: _swipeLeftEvent,
17635
- swipeLeftActions: _swipeLeftActions,
17636
- swipeRightEvent: _swipeRightEvent,
17637
- swipeRightActions: _swipeRightActions,
17638
- longPressEvent: _longPressEvent,
17639
- infiniteScroll,
17640
- loadMoreEvent,
17641
- hasMore,
17642
- children,
17643
- pageSize = 5
17644
- }) => {
17645
- const eventBus = useEventBus();
17646
- const { t } = useTranslate();
17647
- const [visibleCount, setVisibleCount] = React110__default.useState(pageSize || Infinity);
17648
- const fields = fieldsProp ?? columnsProp ?? [];
17649
- const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
17650
- const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
17651
- const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
17652
- const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
17653
- const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
17654
- const progressFields = fields.filter((f3) => f3.variant === "progress");
17655
- const bodyFields = fields.filter(
17656
- (f3) => f3 !== titleField && !badgeFields.includes(f3) && !progressFields.includes(f3)
17657
- );
17658
- const handleActionClick = (action, itemData) => (e) => {
17659
- e.stopPropagation();
17660
- const payload = {
17661
- id: itemData.id,
17662
- row: itemData
17663
- };
17664
- eventBus.emit(`UI:${action.event}`, payload);
17665
- };
17666
- if (isLoading) {
17667
- return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
17668
- }
17669
- if (error) {
17670
- return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
17671
- }
17672
- if (data.length === 0) {
17673
- return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
17674
- }
17675
- const gapClass = {
17676
- none: "",
17677
- sm: "gap-1",
17678
- md: "gap-2",
17679
- lg: "gap-4"
17680
- }[gap];
17681
- const isCard = variant === "card";
17682
- const isCompact = variant === "compact";
17683
- const isMessage = variant === "message";
17684
- if (isMessage) {
17685
- const items2 = data.map((item) => item);
17686
- const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
17687
- const contentField = titleField?.name ?? fields[0]?.name ?? "";
17688
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React110__default.Fragment, { children: [
17689
- group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
17690
- group.items.map((itemData, index) => {
17691
- const id = itemData.id || `${gi}-${index}`;
17692
- const sender = senderField ? String(getNestedValue(itemData, senderField) ?? "") : "";
17693
- const isSent = Boolean(currentUser && sender === currentUser);
17694
- const content = getNestedValue(itemData, contentField);
17695
- const timestampField = fields.find((f3) => f3.format === "date");
17696
- const timestamp = timestampField ? getNestedValue(itemData, timestampField.name) : null;
17697
- return /* @__PURE__ */ jsx(
17698
- Box,
17699
- {
17700
- className: cn(
17701
- "flex px-4",
17702
- isSent ? "justify-end" : "justify-start"
17703
- ),
17704
- children: /* @__PURE__ */ jsxs(
17705
- Box,
17706
- {
17707
- className: cn(
17708
- "max-w-[75%] px-4 py-2",
17709
- isSent ? "bg-primary text-primary-foreground rounded-2xl rounded-br-sm" : "bg-muted text-foreground rounded-2xl rounded-bl-sm"
17710
- ),
17711
- children: [
17712
- !isSent && senderField && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-semibold mb-0.5", children: sender }),
17713
- /* @__PURE__ */ jsx(Typography, { variant: "body", children: content !== void 0 && content !== null ? String(content) : "" }),
17714
- timestamp != null ? /* @__PURE__ */ jsx(
17715
- Typography,
17716
- {
17717
- variant: "caption",
17718
- className: cn(
17719
- "mt-1 text-[0.65rem]",
17720
- isSent ? "opacity-70" : "text-muted-foreground"
17721
- ),
17722
- children: formatDate3(timestamp)
17723
- }
17724
- ) : null
17725
- ]
17726
- }
17727
- )
17728
- },
17729
- id
17730
- );
17731
- })
17732
- ] }, gi)) });
17733
- }
17734
- const hasRenderProp = typeof children === "function";
17735
- const items = data.map((item) => item);
17736
- const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
17737
- const renderItem = (itemData, index, isLast) => {
17738
- if (hasRenderProp) {
17739
- const id2 = itemData.id || String(index);
17740
- return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, children: [
17741
- /* @__PURE__ */ jsxs(
17599
+ function DataList({
17600
+ entity,
17601
+ fields: fieldsProp,
17602
+ columns: columnsProp,
17603
+ itemActions,
17604
+ gap = "none",
17605
+ variant = "default",
17606
+ groupBy,
17607
+ senderField,
17608
+ currentUser,
17609
+ className,
17610
+ isLoading = false,
17611
+ error = null,
17612
+ // Gesture props: reorderable, swipeLeftEvent, swipeRightEvent, longPressEvent
17613
+ // are consumed by the compiler to wrap items in SwipeableRow/SortableList.
17614
+ // DataList destructures them here to prevent DOM passthrough.
17615
+ reorderable: _reorderable,
17616
+ reorderEvent: _reorderEvent,
17617
+ swipeLeftEvent: _swipeLeftEvent,
17618
+ swipeLeftActions: _swipeLeftActions,
17619
+ swipeRightEvent: _swipeRightEvent,
17620
+ swipeRightActions: _swipeRightActions,
17621
+ longPressEvent: _longPressEvent,
17622
+ infiniteScroll,
17623
+ loadMoreEvent,
17624
+ hasMore,
17625
+ children,
17626
+ pageSize = 5
17627
+ }) {
17628
+ const eventBus = useEventBus();
17629
+ const { t } = useTranslate();
17630
+ const [visibleCount, setVisibleCount] = React110__default.useState(pageSize || Infinity);
17631
+ const fields = fieldsProp ?? columnsProp ?? [];
17632
+ const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
17633
+ const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
17634
+ const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
17635
+ const titleField = fields.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fields[0];
17636
+ const badgeFields = fields.filter((f3) => f3.variant === "badge" && f3 !== titleField);
17637
+ const progressFields = fields.filter((f3) => f3.variant === "progress");
17638
+ const bodyFields = fields.filter(
17639
+ (f3) => f3 !== titleField && !badgeFields.includes(f3) && !progressFields.includes(f3)
17640
+ );
17641
+ const handleActionClick = (action, itemData) => (e) => {
17642
+ e.stopPropagation();
17643
+ const payload = {
17644
+ id: itemData.id,
17645
+ row: itemData
17646
+ };
17647
+ eventBus.emit(`UI:${action.event}`, payload);
17648
+ };
17649
+ if (isLoading) {
17650
+ return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
17651
+ }
17652
+ if (error) {
17653
+ return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
17654
+ }
17655
+ if (data.length === 0) {
17656
+ return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
17657
+ }
17658
+ const gapClass = {
17659
+ none: "",
17660
+ sm: "gap-1",
17661
+ md: "gap-2",
17662
+ lg: "gap-4"
17663
+ }[gap];
17664
+ const isCard = variant === "card";
17665
+ const isCompact = variant === "compact";
17666
+ const isMessage = variant === "message";
17667
+ if (isMessage) {
17668
+ const items2 = data.map((item) => item);
17669
+ const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
17670
+ const contentField = titleField?.name ?? fields[0]?.name ?? "";
17671
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React110__default.Fragment, { children: [
17672
+ group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
17673
+ group.items.map((itemData, index) => {
17674
+ const id = itemData.id || `${gi}-${index}`;
17675
+ const sender = senderField ? String(getNestedValue(itemData, senderField) ?? "") : "";
17676
+ const isSent = Boolean(currentUser && sender === currentUser);
17677
+ const content = getNestedValue(itemData, contentField);
17678
+ const timestampField = fields.find((f3) => f3.format === "date");
17679
+ const timestamp = timestampField ? getNestedValue(itemData, timestampField.name) : null;
17680
+ return /* @__PURE__ */ jsx(
17681
+ Box,
17682
+ {
17683
+ className: cn(
17684
+ "flex px-4",
17685
+ isSent ? "justify-end" : "justify-start"
17686
+ ),
17687
+ children: /* @__PURE__ */ jsxs(
17742
17688
  Box,
17743
17689
  {
17744
17690
  className: cn(
17745
- "group flex items-center gap-4 transition-all duration-200",
17746
- isCompact ? "px-4 py-2" : "px-6 py-4",
17747
- "hover:bg-muted/80",
17748
- !isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
17691
+ "max-w-[75%] px-4 py-2",
17692
+ isSent ? "bg-primary text-primary-foreground rounded-2xl rounded-br-sm" : "bg-muted text-foreground rounded-2xl rounded-bl-sm"
17749
17693
  ),
17750
17694
  children: [
17751
- /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
17752
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(
17753
- HStack,
17695
+ !isSent && senderField && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-semibold mb-0.5", children: sender }),
17696
+ /* @__PURE__ */ jsx(Typography, { variant: "body", children: content !== void 0 && content !== null ? String(content) : "" }),
17697
+ timestamp != null ? /* @__PURE__ */ jsx(
17698
+ Typography,
17754
17699
  {
17755
- gap: "xs",
17756
- className: "flex-shrink-0",
17757
- children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
17758
- Button,
17759
- {
17760
- variant: action.variant ?? "ghost",
17761
- size: "sm",
17762
- onClick: handleActionClick(action, itemData),
17763
- "data-testid": `action-${action.event}`,
17764
- className: cn(
17765
- action.variant === "danger" && "text-error hover:bg-error/10"
17766
- ),
17767
- children: [
17768
- action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
17769
- action.label
17770
- ]
17771
- },
17772
- idx
17773
- ))
17700
+ variant: "caption",
17701
+ className: cn(
17702
+ "mt-1 text-[0.65rem]",
17703
+ isSent ? "opacity-70" : "text-muted-foreground"
17704
+ ),
17705
+ children: formatDate3(timestamp)
17774
17706
  }
17775
- )
17707
+ ) : null
17776
17708
  ]
17777
17709
  }
17710
+ )
17711
+ },
17712
+ id
17713
+ );
17714
+ })
17715
+ ] }, gi)) });
17716
+ }
17717
+ const hasRenderProp = typeof children === "function";
17718
+ const items = data.map((item) => item);
17719
+ const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
17720
+ const renderItem = (itemData, index, isLast) => {
17721
+ if (hasRenderProp) {
17722
+ const id2 = itemData.id || String(index);
17723
+ return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, children: [
17724
+ /* @__PURE__ */ jsxs(
17725
+ Box,
17726
+ {
17727
+ className: cn(
17728
+ "group flex items-center gap-4 transition-all duration-200",
17729
+ isCompact ? "px-4 py-2" : "px-6 py-4",
17730
+ "hover:bg-muted/80",
17731
+ !isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
17778
17732
  ),
17779
- isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
17780
- ] }, id2);
17781
- }
17782
- const id = itemData.id || String(index);
17783
- const titleValue = getNestedValue(itemData, titleField?.name ?? "");
17784
- return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id, children: [
17785
- /* @__PURE__ */ jsxs(
17786
- Box,
17787
- {
17788
- className: cn(
17789
- "group flex items-center gap-4 transition-all duration-200",
17790
- isCompact ? "px-4 py-2" : "px-6 py-4",
17791
- "hover:bg-muted/80",
17792
- !isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
17793
- ),
17794
- children: [
17795
- /* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
17796
- /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "items-center", children: [
17797
- titleField?.icon && /* @__PURE__ */ jsx(
17798
- Icon,
17799
- {
17800
- name: titleField.icon,
17801
- size: isCompact ? "xs" : "sm",
17802
- className: "text-primary flex-shrink-0"
17803
- }
17804
- ),
17805
- titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsx(
17806
- Typography,
17807
- {
17808
- variant: titleField?.variant === "h3" ? "h3" : "h4",
17809
- className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
17810
- children: String(titleValue)
17811
- }
17812
- ),
17813
- badgeFields.map((field) => {
17814
- const val = getNestedValue(itemData, field.name);
17815
- if (val === void 0 || val === null) return null;
17816
- return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
17817
- field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
17818
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: String(val) })
17819
- ] }, field.name);
17820
- })
17821
- ] }),
17822
- bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
17823
- const value = getNestedValue(itemData, field.name);
17824
- if (value === void 0 || value === null || value === "") return null;
17825
- return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17826
- field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
17827
- /* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "secondary", children: [
17828
- field.label ?? fieldLabel3(field.name),
17829
- ":"
17830
- ] }),
17831
- /* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue2(value, field.format) })
17832
- ] }, field.name);
17833
- }) }),
17834
- progressFields.map((field) => {
17835
- const value = getNestedValue(itemData, field.name);
17836
- if (typeof value !== "number") return null;
17837
- return /* @__PURE__ */ jsxs(Box, { className: "mt-2 max-w-xs", children: [
17838
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center mb-1", children: [
17839
- field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
17840
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel3(field.name) })
17841
- ] }),
17842
- /* @__PURE__ */ jsx(ProgressBar, { value, max: 100 })
17843
- ] }, field.name);
17844
- })
17845
- ] }),
17846
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
17847
- Button,
17848
- {
17849
- variant: action.variant ?? "ghost",
17850
- size: "sm",
17851
- onClick: handleActionClick(action, itemData),
17852
- "data-testid": `action-${action.event}`,
17853
- className: cn(
17854
- action.variant === "danger" && "text-error hover:bg-error/10"
17855
- ),
17856
- children: [
17857
- action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
17858
- action.label
17859
- ]
17860
- },
17861
- idx
17862
- )) })
17863
- ]
17864
- }
17865
- ),
17866
- isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
17867
- ] }, id);
17868
- };
17869
- return /* @__PURE__ */ jsxs(
17733
+ children: [
17734
+ /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
17735
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(
17736
+ HStack,
17737
+ {
17738
+ gap: "xs",
17739
+ className: "flex-shrink-0",
17740
+ children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
17741
+ Button,
17742
+ {
17743
+ variant: action.variant ?? "ghost",
17744
+ size: "sm",
17745
+ onClick: handleActionClick(action, itemData),
17746
+ "data-testid": `action-${action.event}`,
17747
+ className: cn(
17748
+ action.variant === "danger" && "text-error hover:bg-error/10"
17749
+ ),
17750
+ children: [
17751
+ action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
17752
+ action.label
17753
+ ]
17754
+ },
17755
+ idx
17756
+ ))
17757
+ }
17758
+ )
17759
+ ]
17760
+ }
17761
+ ),
17762
+ isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
17763
+ ] }, id2);
17764
+ }
17765
+ const id = itemData.id || String(index);
17766
+ const titleValue = getNestedValue(itemData, titleField?.name ?? "");
17767
+ return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id, children: [
17768
+ /* @__PURE__ */ jsxs(
17870
17769
  Box,
17871
17770
  {
17872
17771
  className: cn(
17873
- isCard && "bg-card rounded-xl border border-border shadow-lg overflow-hidden",
17874
- !isCard && gapClass,
17875
- className
17772
+ "group flex items-center gap-4 transition-all duration-200",
17773
+ isCompact ? "px-4 py-2" : "px-6 py-4",
17774
+ "hover:bg-muted/80",
17775
+ !isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
17876
17776
  ),
17877
17777
  children: [
17878
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React110__default.Fragment, { children: [
17879
- group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
17880
- group.items.map(
17881
- (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
17882
- )
17883
- ] }, gi)),
17884
- hasMoreLocal && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(
17778
+ /* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
17779
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "items-center", children: [
17780
+ titleField?.icon && /* @__PURE__ */ jsx(
17781
+ Icon,
17782
+ {
17783
+ name: titleField.icon,
17784
+ size: isCompact ? "xs" : "sm",
17785
+ className: "text-primary flex-shrink-0"
17786
+ }
17787
+ ),
17788
+ titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsx(
17789
+ Typography,
17790
+ {
17791
+ variant: titleField?.variant === "h3" ? "h3" : "h4",
17792
+ className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
17793
+ children: String(titleValue)
17794
+ }
17795
+ ),
17796
+ badgeFields.map((field) => {
17797
+ const val = getNestedValue(itemData, field.name);
17798
+ if (val === void 0 || val === null) return null;
17799
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
17800
+ field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
17801
+ /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: String(val) })
17802
+ ] }, field.name);
17803
+ })
17804
+ ] }),
17805
+ bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
17806
+ const value = getNestedValue(itemData, field.name);
17807
+ if (value === void 0 || value === null || value === "") return null;
17808
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
17809
+ field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
17810
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "secondary", children: [
17811
+ field.label ?? fieldLabel3(field.name),
17812
+ ":"
17813
+ ] }),
17814
+ /* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue2(value, field.format) })
17815
+ ] }, field.name);
17816
+ }) }),
17817
+ progressFields.map((field) => {
17818
+ const value = getNestedValue(itemData, field.name);
17819
+ if (typeof value !== "number") return null;
17820
+ return /* @__PURE__ */ jsxs(Box, { className: "mt-2 max-w-xs", children: [
17821
+ /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center mb-1", children: [
17822
+ field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-muted-foreground" }),
17823
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel3(field.name) })
17824
+ ] }),
17825
+ /* @__PURE__ */ jsx(ProgressBar, { value, max: 100 })
17826
+ ] }, field.name);
17827
+ })
17828
+ ] }),
17829
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
17885
17830
  Button,
17886
17831
  {
17887
- variant: "ghost",
17832
+ variant: action.variant ?? "ghost",
17888
17833
  size: "sm",
17889
- onClick: () => setVisibleCount((prev) => prev + (pageSize || 5)),
17834
+ onClick: handleActionClick(action, itemData),
17835
+ "data-testid": `action-${action.event}`,
17836
+ className: cn(
17837
+ action.variant === "danger" && "text-error hover:bg-error/10"
17838
+ ),
17890
17839
  children: [
17891
- /* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
17892
- t("common.showMore"),
17893
- " (",
17894
- allData.length - visibleCount,
17895
- " remaining)"
17840
+ action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
17841
+ action.label
17896
17842
  ]
17897
- }
17898
- ) }),
17899
- infiniteScroll && loadMoreEvent && /* @__PURE__ */ jsx(
17900
- InfiniteScrollSentinel,
17901
- {
17902
- loadMoreEvent,
17903
- isLoading,
17904
- hasMore
17905
- }
17906
- )
17843
+ },
17844
+ idx
17845
+ )) })
17907
17846
  ]
17908
17847
  }
17909
- );
17910
- };
17848
+ ),
17849
+ isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
17850
+ ] }, id);
17851
+ };
17852
+ return /* @__PURE__ */ jsxs(
17853
+ Box,
17854
+ {
17855
+ className: cn(
17856
+ isCard && "bg-card rounded-xl border border-border shadow-lg overflow-hidden",
17857
+ !isCard && gapClass,
17858
+ className
17859
+ ),
17860
+ children: [
17861
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React110__default.Fragment, { children: [
17862
+ group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
17863
+ group.items.map(
17864
+ (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
17865
+ )
17866
+ ] }, gi)),
17867
+ hasMoreLocal && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(
17868
+ Button,
17869
+ {
17870
+ variant: "ghost",
17871
+ size: "sm",
17872
+ onClick: () => setVisibleCount((prev) => prev + (pageSize || 5)),
17873
+ children: [
17874
+ /* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
17875
+ t("common.showMore"),
17876
+ " (",
17877
+ allData.length - visibleCount,
17878
+ " remaining)"
17879
+ ]
17880
+ }
17881
+ ) }),
17882
+ infiniteScroll && loadMoreEvent && /* @__PURE__ */ jsx(
17883
+ InfiniteScrollSentinel,
17884
+ {
17885
+ loadMoreEvent,
17886
+ isLoading,
17887
+ hasMore
17888
+ }
17889
+ )
17890
+ ]
17891
+ }
17892
+ );
17893
+ }
17894
+ var init_DataList = __esm({
17895
+ "components/molecules/DataList.tsx"() {
17896
+ "use client";
17897
+ init_cn();
17898
+ init_getNestedValue();
17899
+ init_useEventBus();
17900
+ init_useTranslate();
17901
+ init_Box();
17902
+ init_Stack();
17903
+ init_Typography();
17904
+ init_Badge();
17905
+ init_Button();
17906
+ init_Icon();
17907
+ init_ProgressBar();
17908
+ init_Divider();
17909
+ init_InfiniteScrollSentinel();
17911
17910
  DataList.displayName = "DataList";
17912
17911
  }
17913
17912
  });
@@ -19116,7 +19115,10 @@ var init_WizardProgress = __esm({
19116
19115
  stepClickEvent
19117
19116
  }) => {
19118
19117
  const eventBus = useEventBus();
19119
- const totalSteps = steps.length;
19118
+ const normalizedSteps = steps.map(
19119
+ (s, i) => typeof s === "string" ? { id: `step-${i}`, title: s } : s
19120
+ );
19121
+ const totalSteps = normalizedSteps.length;
19120
19122
  const handleStepClick = (index) => {
19121
19123
  const isCompleted = index < currentStep;
19122
19124
  if (isCompleted && allowNavigation) {
@@ -19133,7 +19135,7 @@ var init_WizardProgress = __esm({
19133
19135
  compact ? "px-4 py-2" : "px-6 py-4",
19134
19136
  className
19135
19137
  ),
19136
- children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: steps.map((step, index) => {
19138
+ children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
19137
19139
  const isActive = index === currentStep;
19138
19140
  const isCompleted = index < currentStep;
19139
19141
  return /* @__PURE__ */ jsxs(React110__default.Fragment, { children: [
@@ -39734,7 +39736,7 @@ AboutPageTemplate.displayName = "AboutPageTemplate";
39734
39736
  init_cn();
39735
39737
  function useOrbitalHistory(options) {
39736
39738
  const { appId, authToken, userId, onHistoryChange, onRevertSuccess } = options;
39737
- const getHeaders2 = useCallback(() => {
39739
+ const getHeaders = useCallback(() => {
39738
39740
  const headers = {
39739
39741
  "Content-Type": "application/json"
39740
39742
  };
@@ -39755,7 +39757,7 @@ function useOrbitalHistory(options) {
39755
39757
  setIsLoading(true);
39756
39758
  setError(null);
39757
39759
  try {
39758
- const headers = getHeaders2();
39760
+ const headers = getHeaders();
39759
39761
  const [changesetsRes, snapshotsRes] = await Promise.all([
39760
39762
  fetch(`/api/graphs/${appId}/history/changesets`, { headers }),
39761
39763
  fetch(`/api/graphs/${appId}/history/snapshots`, { headers })
@@ -39798,7 +39800,7 @@ function useOrbitalHistory(options) {
39798
39800
  } finally {
39799
39801
  setIsLoading(false);
39800
39802
  }
39801
- }, [appId, getHeaders2]);
39803
+ }, [appId, getHeaders]);
39802
39804
  const revertToSnapshot = useCallback(async (snapshotId) => {
39803
39805
  if (!appId) {
39804
39806
  return { success: false, error: "No app ID provided" };
@@ -39806,7 +39808,7 @@ function useOrbitalHistory(options) {
39806
39808
  try {
39807
39809
  const response = await fetch(`/api/graphs/${appId}/history/revert/${snapshotId}`, {
39808
39810
  method: "POST",
39809
- headers: getHeaders2()
39811
+ headers: getHeaders()
39810
39812
  });
39811
39813
  if (!response.ok) {
39812
39814
  const errorData = await response.json().catch(() => ({}));
@@ -39832,7 +39834,7 @@ function useOrbitalHistory(options) {
39832
39834
  error: err instanceof Error ? err.message : "Failed to revert"
39833
39835
  };
39834
39836
  }
39835
- }, [appId, getHeaders2, refresh, onRevertSuccess]);
39837
+ }, [appId, getHeaders, refresh, onRevertSuccess]);
39836
39838
  useEffect(() => {
39837
39839
  if (appId && authToken && userId) {
39838
39840
  refresh();
@@ -40896,591 +40898,10 @@ function useSelectionContext() {
40896
40898
  const context = useContext(SelectionContext);
40897
40899
  return context;
40898
40900
  }
40899
- var EntityDataContext = createContext(null);
40900
- function EntityDataProvider({
40901
- adapter,
40902
- children
40903
- }) {
40904
- return React110__default.createElement(
40905
- EntityDataContext.Provider,
40906
- { value: adapter },
40907
- children
40908
- );
40909
- }
40910
- function useEntityDataAdapter() {
40911
- return useContext(EntityDataContext);
40912
- }
40913
- var entityDataKeys = {
40914
- all: ["entities"],
40915
- lists: () => [...entityDataKeys.all, "list"],
40916
- list: (entity, filters) => [...entityDataKeys.lists(), entity, filters],
40917
- details: () => [...entityDataKeys.all, "detail"],
40918
- detail: (entity, id) => [...entityDataKeys.details(), entity, id]
40919
- };
40920
- function useEntityList(entity, options = {}) {
40921
- const { skip = false } = options;
40922
- const adapter = useContext(EntityDataContext);
40923
- const adapterData = useMemo(() => {
40924
- if (!adapter || !entity || skip) return [];
40925
- return adapter.getData(entity);
40926
- }, [adapter, entity, skip, adapter?.isLoading]);
40927
- const [stubData, setStubData] = useState([]);
40928
- const [stubLoading, setStubLoading] = useState(!skip && !!entity && !adapter);
40929
- const [stubError, setStubError] = useState(null);
40930
- useEffect(() => {
40931
- if (adapter || skip || !entity) {
40932
- setStubLoading(false);
40933
- return;
40934
- }
40935
- setStubLoading(true);
40936
- const t = setTimeout(() => {
40937
- setStubData([]);
40938
- setStubLoading(false);
40939
- }, 100);
40940
- return () => clearTimeout(t);
40941
- }, [entity, skip, adapter]);
40942
- if (adapter) {
40943
- return {
40944
- data: adapterData,
40945
- isLoading: adapter.isLoading,
40946
- error: adapter.error ? new Error(adapter.error) : null,
40947
- refetch: () => {
40948
- }
40949
- };
40950
- }
40951
- return { data: stubData, isLoading: stubLoading, error: stubError, refetch: () => {
40952
- } };
40953
- }
40954
- function useEntity(entity, id) {
40955
- const adapter = useContext(EntityDataContext);
40956
- const adapterData = useMemo(() => {
40957
- if (!adapter || !entity || !id) return null;
40958
- return adapter.getById(entity, id) ?? null;
40959
- }, [adapter, entity, id, adapter?.isLoading]);
40960
- const [stubData, setStubData] = useState(null);
40961
- const [stubLoading, setStubLoading] = useState(!!entity && !!id && !adapter);
40962
- const [stubError, setStubError] = useState(null);
40963
- useEffect(() => {
40964
- if (adapter || !entity || !id) {
40965
- setStubLoading(false);
40966
- return;
40967
- }
40968
- setStubLoading(true);
40969
- const t = setTimeout(() => {
40970
- setStubData(null);
40971
- setStubLoading(false);
40972
- }, 100);
40973
- return () => clearTimeout(t);
40974
- }, [entity, id, adapter]);
40975
- if (adapter) {
40976
- return {
40977
- data: adapterData,
40978
- isLoading: adapter.isLoading,
40979
- error: adapter.error ? new Error(adapter.error) : null
40980
- };
40981
- }
40982
- return { data: stubData, isLoading: stubLoading, error: stubError };
40983
- }
40984
- function useEntityDetail(entity, id) {
40985
- const result = useEntity(entity, id);
40986
- return { ...result, refetch: () => {
40987
- } };
40988
- }
40989
- var suspenseCache = /* @__PURE__ */ new Map();
40990
- function getSuspenseCacheKey(entity, type, id) {
40991
- return id ? `${type}:${entity}:${id}` : `${type}:${entity}`;
40992
- }
40993
- function useEntityListSuspense(entity) {
40994
- const adapter = useContext(EntityDataContext);
40995
- if (adapter) {
40996
- if (adapter.isLoading) {
40997
- const cacheKey2 = getSuspenseCacheKey(entity, "list");
40998
- let entry2 = suspenseCache.get(cacheKey2);
40999
- if (!entry2 || entry2.status === "resolved") {
41000
- let resolve;
41001
- const promise = new Promise((r) => {
41002
- resolve = r;
41003
- });
41004
- entry2 = { promise, status: "pending" };
41005
- suspenseCache.set(cacheKey2, entry2);
41006
- const check = setInterval(() => {
41007
- if (!adapter.isLoading) {
41008
- clearInterval(check);
41009
- entry2.status = "resolved";
41010
- resolve();
41011
- }
41012
- }, 50);
41013
- }
41014
- if (entry2.status === "pending") {
41015
- throw entry2.promise;
41016
- }
41017
- }
41018
- if (adapter.error) {
41019
- throw new Error(adapter.error);
41020
- }
41021
- return {
41022
- data: adapter.getData(entity),
41023
- refetch: () => {
41024
- }
41025
- };
41026
- }
41027
- const cacheKey = getSuspenseCacheKey(entity, "list");
41028
- let entry = suspenseCache.get(cacheKey);
41029
- if (!entry) {
41030
- let resolve;
41031
- const promise = new Promise((r) => {
41032
- resolve = r;
41033
- setTimeout(() => {
41034
- entry.status = "resolved";
41035
- resolve();
41036
- }, 100);
41037
- });
41038
- entry = { promise, status: "pending" };
41039
- suspenseCache.set(cacheKey, entry);
41040
- }
41041
- if (entry.status === "pending") {
41042
- throw entry.promise;
41043
- }
41044
- return { data: [], refetch: () => {
41045
- } };
41046
- }
41047
- function useEntitySuspense(entity, id) {
41048
- const adapter = useContext(EntityDataContext);
41049
- if (adapter) {
41050
- if (adapter.isLoading) {
41051
- const cacheKey2 = getSuspenseCacheKey(entity, "detail", id);
41052
- let entry2 = suspenseCache.get(cacheKey2);
41053
- if (!entry2 || entry2.status === "resolved") {
41054
- let resolve;
41055
- const promise = new Promise((r) => {
41056
- resolve = r;
41057
- });
41058
- entry2 = { promise, status: "pending" };
41059
- suspenseCache.set(cacheKey2, entry2);
41060
- const check = setInterval(() => {
41061
- if (!adapter.isLoading) {
41062
- clearInterval(check);
41063
- entry2.status = "resolved";
41064
- resolve();
41065
- }
41066
- }, 50);
41067
- }
41068
- if (entry2.status === "pending") {
41069
- throw entry2.promise;
41070
- }
41071
- }
41072
- if (adapter.error) {
41073
- throw new Error(adapter.error);
41074
- }
41075
- return {
41076
- data: adapter.getById(entity, id) ?? null,
41077
- refetch: () => {
41078
- }
41079
- };
41080
- }
41081
- const cacheKey = getSuspenseCacheKey(entity, "detail", id);
41082
- let entry = suspenseCache.get(cacheKey);
41083
- if (!entry) {
41084
- let resolve;
41085
- const promise = new Promise((r) => {
41086
- resolve = r;
41087
- setTimeout(() => {
41088
- entry.status = "resolved";
41089
- resolve();
41090
- }, 100);
41091
- });
41092
- entry = { promise, status: "pending" };
41093
- suspenseCache.set(cacheKey, entry);
41094
- }
41095
- if (entry.status === "pending") {
41096
- throw entry.promise;
41097
- }
41098
- return { data: null, refetch: () => {
41099
- } };
41100
- }
41101
40901
 
41102
40902
  // hooks/index.ts
41103
40903
  init_useQuerySingleton();
41104
40904
 
41105
- // lib/api-client.ts
41106
- var API_BASE_URL = typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "/api";
41107
- var ApiError = class extends Error {
41108
- constructor(status, statusText, message) {
41109
- super(message || `API Error: ${status} ${statusText}`);
41110
- __publicField(this, "status", status);
41111
- __publicField(this, "statusText", statusText);
41112
- this.name = "ApiError";
41113
- }
41114
- };
41115
- async function handleResponse(response) {
41116
- if (!response.ok) {
41117
- let message;
41118
- try {
41119
- const errorData = await response.json();
41120
- message = errorData.message || errorData.error;
41121
- } catch {
41122
- }
41123
- throw new ApiError(response.status, response.statusText, message);
41124
- }
41125
- const text = await response.text();
41126
- if (!text) {
41127
- return void 0;
41128
- }
41129
- return JSON.parse(text);
41130
- }
41131
- function getHeaders() {
41132
- const headers = {
41133
- "Content-Type": "application/json"
41134
- };
41135
- const token = typeof localStorage !== "undefined" ? localStorage.getItem("authToken") : null;
41136
- if (token) {
41137
- headers["Authorization"] = `Bearer ${token}`;
41138
- }
41139
- return headers;
41140
- }
41141
- var apiClient = {
41142
- /**
41143
- * GET request
41144
- */
41145
- async get(endpoint) {
41146
- const response = await fetch(`${API_BASE_URL}${endpoint}`, {
41147
- method: "GET",
41148
- headers: getHeaders()
41149
- });
41150
- return handleResponse(response);
41151
- },
41152
- /**
41153
- * POST request
41154
- */
41155
- async post(endpoint, data) {
41156
- const response = await fetch(`${API_BASE_URL}${endpoint}`, {
41157
- method: "POST",
41158
- headers: getHeaders(),
41159
- body: data ? JSON.stringify(data) : void 0
41160
- });
41161
- return handleResponse(response);
41162
- },
41163
- /**
41164
- * PUT request
41165
- */
41166
- async put(endpoint, data) {
41167
- const response = await fetch(`${API_BASE_URL}${endpoint}`, {
41168
- method: "PUT",
41169
- headers: getHeaders(),
41170
- body: data ? JSON.stringify(data) : void 0
41171
- });
41172
- return handleResponse(response);
41173
- },
41174
- /**
41175
- * PATCH request
41176
- */
41177
- async patch(endpoint, data) {
41178
- const response = await fetch(`${API_BASE_URL}${endpoint}`, {
41179
- method: "PATCH",
41180
- headers: getHeaders(),
41181
- body: data ? JSON.stringify(data) : void 0
41182
- });
41183
- return handleResponse(response);
41184
- },
41185
- /**
41186
- * DELETE request
41187
- */
41188
- async delete(endpoint) {
41189
- const response = await fetch(`${API_BASE_URL}${endpoint}`, {
41190
- method: "DELETE",
41191
- headers: getHeaders()
41192
- });
41193
- return handleResponse(response);
41194
- }
41195
- };
41196
- var ENTITY_EVENTS = {
41197
- CREATE: "ENTITY_CREATE",
41198
- UPDATE: "ENTITY_UPDATE",
41199
- DELETE: "ENTITY_DELETE"
41200
- };
41201
- async function sendOrbitalEvent(orbitalName, eventPayload) {
41202
- const response = await apiClient.post(
41203
- `/orbitals/${orbitalName}/events`,
41204
- eventPayload
41205
- );
41206
- return response;
41207
- }
41208
- function useOrbitalMutations(entityName, orbitalName, options) {
41209
- const queryClient = useQueryClient();
41210
- const events2 = {
41211
- create: options?.events?.create || ENTITY_EVENTS.CREATE,
41212
- update: options?.events?.update || ENTITY_EVENTS.UPDATE,
41213
- delete: options?.events?.delete || ENTITY_EVENTS.DELETE
41214
- };
41215
- const log3 = (message, data) => {
41216
- if (options?.debug) {
41217
- console.log(`[useOrbitalMutations:${orbitalName}] ${message}`, data ?? "");
41218
- }
41219
- };
41220
- const createMutation = useMutation({
41221
- mutationFn: async (data) => {
41222
- log3("Creating entity", data);
41223
- return sendOrbitalEvent(orbitalName, {
41224
- event: events2.create,
41225
- payload: { data, entityType: entityName }
41226
- });
41227
- },
41228
- onSuccess: (response) => {
41229
- log3("Create succeeded", response);
41230
- queryClient.invalidateQueries({ queryKey: entityDataKeys.list(entityName) });
41231
- },
41232
- onError: (error) => {
41233
- console.error(`[useOrbitalMutations] Create failed:`, error);
41234
- }
41235
- });
41236
- const updateMutation = useMutation({
41237
- mutationFn: async ({
41238
- id,
41239
- data
41240
- }) => {
41241
- log3(`Updating entity ${id}`, data);
41242
- return sendOrbitalEvent(orbitalName, {
41243
- event: events2.update,
41244
- entityId: id,
41245
- payload: { data, entityType: entityName }
41246
- });
41247
- },
41248
- onSuccess: (response, variables) => {
41249
- log3("Update succeeded", response);
41250
- queryClient.invalidateQueries({ queryKey: entityDataKeys.list(entityName) });
41251
- queryClient.invalidateQueries({
41252
- queryKey: entityDataKeys.detail(entityName, variables.id)
41253
- });
41254
- },
41255
- onError: (error) => {
41256
- console.error(`[useOrbitalMutations] Update failed:`, error);
41257
- }
41258
- });
41259
- const deleteMutation = useMutation({
41260
- mutationFn: async (id) => {
41261
- log3(`Deleting entity ${id}`);
41262
- return sendOrbitalEvent(orbitalName, {
41263
- event: events2.delete,
41264
- entityId: id,
41265
- payload: { entityType: entityName }
41266
- });
41267
- },
41268
- onSuccess: (response, id) => {
41269
- log3("Delete succeeded", response);
41270
- queryClient.invalidateQueries({ queryKey: entityDataKeys.list(entityName) });
41271
- queryClient.removeQueries({ queryKey: entityDataKeys.detail(entityName, id) });
41272
- },
41273
- onError: (error) => {
41274
- console.error(`[useOrbitalMutations] Delete failed:`, error);
41275
- }
41276
- });
41277
- return {
41278
- // Async functions
41279
- createEntity: async (data) => {
41280
- return createMutation.mutateAsync(data);
41281
- },
41282
- updateEntity: async (id, data) => {
41283
- if (!id) {
41284
- console.warn("[useOrbitalMutations] Cannot update without ID");
41285
- return;
41286
- }
41287
- return updateMutation.mutateAsync({ id, data });
41288
- },
41289
- deleteEntity: async (id) => {
41290
- if (!id) {
41291
- console.warn("[useOrbitalMutations] Cannot delete without ID");
41292
- return;
41293
- }
41294
- return deleteMutation.mutateAsync(id);
41295
- },
41296
- // Mutation objects for fine-grained control
41297
- createMutation,
41298
- updateMutation,
41299
- deleteMutation,
41300
- // Aggregate states
41301
- isCreating: createMutation.isPending,
41302
- isUpdating: updateMutation.isPending,
41303
- isDeleting: deleteMutation.isPending,
41304
- isMutating: createMutation.isPending || updateMutation.isPending || deleteMutation.isPending,
41305
- // Errors
41306
- createError: createMutation.error,
41307
- updateError: updateMutation.error,
41308
- deleteError: deleteMutation.error
41309
- };
41310
- }
41311
- function useSendOrbitalEvent(orbitalName) {
41312
- const mutation = useMutation({
41313
- mutationFn: async (payload) => {
41314
- return sendOrbitalEvent(orbitalName, payload);
41315
- }
41316
- });
41317
- return {
41318
- sendEvent: async (event, payload, entityId) => {
41319
- return mutation.mutateAsync({ event, payload, entityId });
41320
- },
41321
- isPending: mutation.isPending,
41322
- error: mutation.error,
41323
- data: mutation.data
41324
- };
41325
- }
41326
-
41327
- // hooks/useEntityMutations.ts
41328
- function entityToCollection(entityName) {
41329
- return entityName.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase() + "-list";
41330
- }
41331
- function useCreateEntity(entityName) {
41332
- const queryClient = useQueryClient();
41333
- const collection = entityToCollection(entityName);
41334
- return useMutation({
41335
- mutationFn: async (data) => {
41336
- console.log(`[useCreateEntity] Creating ${entityName}:`, data);
41337
- const response = await apiClient.post(
41338
- `/${collection}`,
41339
- data
41340
- );
41341
- return response.data;
41342
- },
41343
- onSuccess: () => {
41344
- queryClient.invalidateQueries({ queryKey: entityDataKeys.list(entityName) });
41345
- },
41346
- onError: (error) => {
41347
- console.error(`[useCreateEntity] Failed to create ${entityName}:`, error);
41348
- }
41349
- });
41350
- }
41351
- function useUpdateEntity(entityName) {
41352
- const queryClient = useQueryClient();
41353
- const collection = entityToCollection(entityName);
41354
- return useMutation({
41355
- mutationFn: async ({ id, data }) => {
41356
- console.log(`[useUpdateEntity] Updating ${entityName} ${id}:`, data);
41357
- const response = await apiClient.patch(
41358
- `/${collection}/${id}`,
41359
- data
41360
- );
41361
- return response.data;
41362
- },
41363
- onSuccess: (_, variables) => {
41364
- queryClient.invalidateQueries({ queryKey: entityDataKeys.list(entityName) });
41365
- queryClient.invalidateQueries({ queryKey: entityDataKeys.detail(entityName, variables.id) });
41366
- },
41367
- onError: (error) => {
41368
- console.error(`[useUpdateEntity] Failed to update ${entityName}:`, error);
41369
- }
41370
- });
41371
- }
41372
- function useDeleteEntity(entityName) {
41373
- const queryClient = useQueryClient();
41374
- const collection = entityToCollection(entityName);
41375
- return useMutation({
41376
- mutationFn: async (id) => {
41377
- console.log(`[useDeleteEntity] Deleting ${entityName} ${id}`);
41378
- await apiClient.delete(`/${collection}/${id}`);
41379
- return { id };
41380
- },
41381
- onSuccess: (_, id) => {
41382
- queryClient.invalidateQueries({ queryKey: entityDataKeys.list(entityName) });
41383
- queryClient.removeQueries({ queryKey: entityDataKeys.detail(entityName, id) });
41384
- },
41385
- onError: (error) => {
41386
- console.error(`[useDeleteEntity] Failed to delete ${entityName}:`, error);
41387
- }
41388
- });
41389
- }
41390
- async function sendOrbitalMutation(orbitalName, event, entityId, payload) {
41391
- const response = await apiClient.post(
41392
- `/orbitals/${orbitalName}/events`,
41393
- { event, entityId, payload }
41394
- );
41395
- return response;
41396
- }
41397
- function useEntityMutations(entityName, options) {
41398
- const queryClient = useQueryClient();
41399
- const useOrbitalRoute = !!options?.orbitalName;
41400
- const events2 = {
41401
- create: options?.events?.create || ENTITY_EVENTS.CREATE,
41402
- update: options?.events?.update || ENTITY_EVENTS.UPDATE,
41403
- delete: options?.events?.delete || ENTITY_EVENTS.DELETE
41404
- };
41405
- const createMutation = useCreateEntity(entityName);
41406
- const updateMutation = useUpdateEntity(entityName);
41407
- const deleteMutation = useDeleteEntity(entityName);
41408
- const orbitalCreateMutation = useMutation({
41409
- mutationFn: async (data) => {
41410
- return sendOrbitalMutation(options.orbitalName, events2.create, void 0, {
41411
- data,
41412
- entityType: entityName
41413
- });
41414
- },
41415
- onSuccess: () => {
41416
- queryClient.invalidateQueries({ queryKey: entityDataKeys.list(entityName) });
41417
- }
41418
- });
41419
- const orbitalUpdateMutation = useMutation({
41420
- mutationFn: async ({ id, data }) => {
41421
- return sendOrbitalMutation(options.orbitalName, events2.update, id, {
41422
- data,
41423
- entityType: entityName
41424
- });
41425
- },
41426
- onSuccess: (_, variables) => {
41427
- queryClient.invalidateQueries({ queryKey: entityDataKeys.list(entityName) });
41428
- queryClient.invalidateQueries({
41429
- queryKey: entityDataKeys.detail(entityName, variables.id)
41430
- });
41431
- }
41432
- });
41433
- const orbitalDeleteMutation = useMutation({
41434
- mutationFn: async (id) => {
41435
- return sendOrbitalMutation(options.orbitalName, events2.delete, id, {
41436
- entityType: entityName
41437
- });
41438
- },
41439
- onSuccess: (_, id) => {
41440
- queryClient.invalidateQueries({ queryKey: entityDataKeys.list(entityName) });
41441
- queryClient.removeQueries({ queryKey: entityDataKeys.detail(entityName, id) });
41442
- }
41443
- });
41444
- const activeMutations = {
41445
- create: useOrbitalRoute ? orbitalCreateMutation : createMutation,
41446
- update: useOrbitalRoute ? orbitalUpdateMutation : updateMutation,
41447
- delete: useOrbitalRoute ? orbitalDeleteMutation : deleteMutation
41448
- };
41449
- return {
41450
- // Async functions that can be called directly
41451
- // Accepts either (data) or (entityName, data) for compiler compatibility
41452
- createEntity: async (entityOrData, data) => {
41453
- const actualData = typeof entityOrData === "string" ? data : entityOrData;
41454
- if (!actualData) {
41455
- console.warn("[useEntityMutations] Cannot create entity without data");
41456
- return;
41457
- }
41458
- return activeMutations.create.mutateAsync(actualData);
41459
- },
41460
- updateEntity: async (id, data) => {
41461
- if (!id) {
41462
- console.warn("[useEntityMutations] Cannot update entity without ID");
41463
- return;
41464
- }
41465
- return activeMutations.update.mutateAsync({ id, data });
41466
- },
41467
- deleteEntity: async (id) => {
41468
- if (!id) {
41469
- console.warn("[useEntityMutations] Cannot delete entity without ID");
41470
- return;
41471
- }
41472
- return activeMutations.delete.mutateAsync(id);
41473
- },
41474
- // Mutation states for UI feedback
41475
- isCreating: activeMutations.create.isPending,
41476
- isUpdating: activeMutations.update.isPending,
41477
- isDeleting: activeMutations.delete.isPending,
41478
- createError: activeMutations.create.error,
41479
- updateError: activeMutations.update.error,
41480
- deleteError: activeMutations.delete.error
41481
- };
41482
- }
41483
-
41484
40905
  // stores/entityStore.ts
41485
40906
  var entities = /* @__PURE__ */ new Map();
41486
40907
  var listeners6 = /* @__PURE__ */ new Set();
@@ -41558,7 +40979,7 @@ function useEntities() {
41558
40979
  clearEntities
41559
40980
  };
41560
40981
  }
41561
- function useEntity2(id) {
40982
+ function useEntity(id) {
41562
40983
  const entities2 = useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2);
41563
40984
  return entities2.get(id);
41564
40985
  }
@@ -41594,28 +41015,6 @@ function useInput() {
41594
41015
 
41595
41016
  // hooks/index.ts
41596
41017
  init_useTranslate();
41597
- function useResolvedEntity(entity, data) {
41598
- const shouldFetch = !data && !!entity;
41599
- const fetched = useEntityList(entity, { skip: !shouldFetch });
41600
- return useMemo(() => {
41601
- if (data) {
41602
- return {
41603
- data,
41604
- isLocal: true,
41605
- isLoading: false,
41606
- error: null
41607
- };
41608
- }
41609
- return {
41610
- data: fetched.data,
41611
- isLocal: false,
41612
- isLoading: fetched.isLoading,
41613
- error: fetched.error
41614
- };
41615
- }, [data, fetched.data, fetched.isLoading, fetched.error]);
41616
- }
41617
-
41618
- // hooks/index.ts
41619
41018
  init_useAuthContext();
41620
41019
  init_useSwipeGesture();
41621
41020
  init_useLongPress();
@@ -41839,4 +41238,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
41839
41238
  });
41840
41239
  }
41841
41240
 
41842
- export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, ActionPalette, ActionTile, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, CanvasEffect, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, Checkbox, ChoiceButton, ClassifierBoard, CodeBlock, CodeExample, CodeView, CodeViewer, CollapsibleSection, CombatLog, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, Container, ContentRenderer, ContentSection, ControlButton, CounterTemplate, CraftingRecipe, DEFAULT_SLOTS, DIAMOND_TOP_Y, DPad, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, DialogueBox, DialogueBubble, Divider, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ENTITY_EVENTS, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EnemyPlate, EntityDataProvider, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCanvas2D, GameHud, GameMenu, GameOverScreen, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GraphCanvas, GraphView, Grid, HStack, Header, Heading, HealthBar, HealthPanel, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, InventoryPanel, IsometricCanvas, ItemSlot, JazariStateMachine, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LineChart2 as LineChart, List2 as List, LoadingState, MapView, MarkdownContent, MarketingStatCard, MasterDetail2 as MasterDetail, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, Navigation, NegotiatorBoard, NotifyListener, NumberStepper, ObjectRulePanel, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsManager, PlatformerCanvas, Popover, PowerupSlots, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PullToRefresh, QuestTracker, QuizBlock, Radio, RangeSlider, RelationSelect, RepeatableFormSection, ResourceBar, ResourceCounter, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreBoard, ScoreDisplay, SearchInput, Section, SectionHeader, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, Table, Tabs, TagCloud, TeamCard, TeamOrganism, TerrainPalette, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TurnPanel, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UnitCommandBar, UploadDropZone, VStack, VariablePanel, ViolationAlert, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, XPBar, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, clearEntities, cn, combatAnimations, combatClasses, combatEffects, createInitialGameState, createTranslate, createUnitAnimationState, drawSprite, entityDataKeys, generateCombatMessage, getAllEntities, getByType, getCurrentFrame, getEntity, getSingleton, getTileDimensions, inferDirection, isoToScreen, mapBookData, parseQueryBinding, pendulum, projectileMotion, removeEntity, resolveFieldMap, resolveFrame, resolveSheetDirection, screenToIso, spawnEntity, springOscillator, tickAnimationState, transitionAnimation, updateEntity, updateSingleton, useAgentChat, useAuthContext, useBattleState, useCamera, useCompile, useConnectGitHub, useCreateEntity, useDeepAgentGeneration, useDeleteEntity, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEntities, useEntitiesByType, useEntity, useEntity2 as useEntityById, useEntityDataAdapter, useEntityDetail, useEntityList, useEntityListSuspense, useEntityMutations, useEntitySuspense, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useInput, useLongPress, useOrbitalHistory, useOrbitalMutations, usePhysics, usePhysics2D, usePinchZoom, usePlayer, usePreview, usePullToRefresh, useQuerySingleton, useResolvedEntity, useSelectedEntity, useSendOrbitalEvent, useSingletonEntity, useSpriteAnimations, useSwipeGesture, useTranslate, useUIEvents, useUISlotManager, useUpdateEntity, useValidation };
41241
+ export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, ActionPalette, ActionTile, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, CanvasEffect, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, Checkbox, ChoiceButton, ClassifierBoard, CodeBlock, CodeExample, CodeView, CodeViewer, CollapsibleSection, CombatLog, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, Container, ContentRenderer, ContentSection, ControlButton, CounterTemplate, CraftingRecipe, DEFAULT_SLOTS, DIAMOND_TOP_Y, DPad, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, DialogueBox, DialogueBubble, Divider, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EnemyPlate, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCanvas2D, GameHud, GameMenu, GameOverScreen, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GraphCanvas, GraphView, Grid, HStack, Header, Heading, HealthBar, HealthPanel, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, InventoryPanel, IsometricCanvas, ItemSlot, JazariStateMachine, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LineChart2 as LineChart, List2 as List, LoadingState, MapView, MarkdownContent, MarketingStatCard, MasterDetail2 as MasterDetail, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, Navigation, NegotiatorBoard, NotifyListener, NumberStepper, ObjectRulePanel, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsManager, PlatformerCanvas, Popover, PowerupSlots, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PullToRefresh, QuestTracker, QuizBlock, Radio, RangeSlider, RelationSelect, RepeatableFormSection, ResourceBar, ResourceCounter, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreBoard, ScoreDisplay, SearchInput, Section, SectionHeader, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, Table, Tabs, TagCloud, TeamCard, TeamOrganism, TerrainPalette, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TurnPanel, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UnitCommandBar, UploadDropZone, VStack, VariablePanel, ViolationAlert, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, XPBar, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, clearEntities, cn, combatAnimations, combatClasses, combatEffects, createInitialGameState, createTranslate, createUnitAnimationState, drawSprite, generateCombatMessage, getAllEntities, getByType, getCurrentFrame, getEntity, getSingleton, getTileDimensions, inferDirection, isoToScreen, mapBookData, parseQueryBinding, pendulum, projectileMotion, removeEntity, resolveFieldMap, resolveFrame, resolveSheetDirection, screenToIso, spawnEntity, springOscillator, tickAnimationState, transitionAnimation, updateEntity, updateSingleton, useAgentChat, useAuthContext, useBattleState, useCamera, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEntities, useEntitiesByType, useEntity as useEntityById, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useInput, useLongPress, useOrbitalHistory, usePhysics, usePhysics2D, usePinchZoom, usePlayer, usePreview, usePullToRefresh, useQuerySingleton, useSelectedEntity, useSingletonEntity, useSpriteAnimations, useSwipeGesture, useTranslate, useUIEvents, useUISlotManager, useValidation };