@almadar/ui 2.1.11 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7NEWMNNU.js → chunk-3JGAROCW.js} +2 -0
- package/dist/{chunk-6OACETQB.js → chunk-42WRQA7T.js} +2 -2
- package/dist/{chunk-BTXQJGFB.js → chunk-DKQN5FVU.js} +1 -1
- package/dist/{chunk-JLEMVREZ.js → chunk-GOZKH7QW.js} +6 -3
- package/dist/{chunk-CTNDYHXY.js → chunk-HWZL7IZG.js} +1981 -640
- package/dist/chunk-K2D5D3WK.js +1033 -0
- package/dist/chunk-TSETXL2E.js +103 -0
- package/dist/components/index.d.ts +454 -34
- package/dist/components/index.js +227 -148
- package/dist/components/organisms/game/three/index.d.ts +7 -1
- package/dist/context/index.d.ts +2 -2
- package/dist/context/index.js +3 -3
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +4 -3
- package/dist/locales/index.js +1 -102
- package/dist/providers/index.js +7 -6
- package/dist/renderer/index.d.ts +1 -1
- package/dist/renderer/index.js +1 -613
- package/dist/{useUISlots-D0mttBSP.d.ts → useUISlots-BBjNvQtb.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-PL7MD6GF.js +0 -426
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { useTheme, useUISlots } from './chunk-
|
|
2
|
-
import { useTranslate, useQuerySingleton } from './chunk-
|
|
1
|
+
import { useTheme, useUISlots } from './chunk-DKQN5FVU.js';
|
|
2
|
+
import { useTranslate, useQuerySingleton } from './chunk-GOZKH7QW.js';
|
|
3
3
|
import { useEventBus } from './chunk-YXZM3WCF.js';
|
|
4
4
|
import { cn, debugGroup, debug, debugGroupEnd, getNestedValue, isDebugEnabled } from './chunk-KKCVDUK7.js';
|
|
5
|
+
import { isPortalSlot } from './chunk-K2D5D3WK.js';
|
|
5
6
|
import { __publicField } from './chunk-PKBMQBKP.js';
|
|
6
|
-
import * as React41 from 'react';
|
|
7
|
-
import React41__default, { useCallback, useRef, useState, useLayoutEffect, useEffect, createContext, useMemo, useContext, Suspense } from 'react';
|
|
8
7
|
import * as LucideIcons from 'lucide-react';
|
|
9
8
|
import { Loader2, ChevronDown, X, Check, Copy, AlertCircle, User, Sun, Moon, FileQuestion, Inbox, Search, Info, XCircle, CheckCircle, AlertTriangle, ChevronRight, Filter, Plus, ChevronLeft, HelpCircle, ChevronUp, MoreHorizontal, TrendingUp, TrendingDown, Minus, ArrowLeft, Calendar, Tag, Clock, CheckCircle2, DollarSign, FileText, Package } from 'lucide-react';
|
|
10
9
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
10
|
+
import * as React47 from 'react';
|
|
11
|
+
import React47__default, { useCallback, useRef, useState, useLayoutEffect, useEffect, lazy, createContext, useMemo, useId, useContext, Suspense } from 'react';
|
|
11
12
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
12
13
|
import { createPortal } from 'react-dom';
|
|
13
14
|
import ReactMarkdown from 'react-markdown';
|
|
@@ -17,6 +18,84 @@ import rehypeKatex from 'rehype-katex';
|
|
|
17
18
|
import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism';
|
|
18
19
|
import dark from 'react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus';
|
|
19
20
|
|
|
21
|
+
var iconAliases = {
|
|
22
|
+
"close": LucideIcons.X,
|
|
23
|
+
"trash": LucideIcons.Trash2,
|
|
24
|
+
"loader": LucideIcons.Loader2,
|
|
25
|
+
"stop": LucideIcons.Square,
|
|
26
|
+
"volume": LucideIcons.Volume2,
|
|
27
|
+
"volume-off": LucideIcons.VolumeX,
|
|
28
|
+
"refresh": LucideIcons.RefreshCw,
|
|
29
|
+
"share": LucideIcons.Share2,
|
|
30
|
+
"sort-asc": LucideIcons.ArrowUpNarrowWide,
|
|
31
|
+
"sort-desc": LucideIcons.ArrowDownNarrowWide
|
|
32
|
+
};
|
|
33
|
+
function kebabToPascal(name) {
|
|
34
|
+
return name.split("-").map((part) => {
|
|
35
|
+
if (/^\d+$/.test(part)) return part;
|
|
36
|
+
return part.charAt(0).toUpperCase() + part.slice(1);
|
|
37
|
+
}).join("");
|
|
38
|
+
}
|
|
39
|
+
var resolvedCache = /* @__PURE__ */ new Map();
|
|
40
|
+
function resolveIcon(name) {
|
|
41
|
+
const cached = resolvedCache.get(name);
|
|
42
|
+
if (cached) return cached;
|
|
43
|
+
const resolved = doResolve(name);
|
|
44
|
+
resolvedCache.set(name, resolved);
|
|
45
|
+
return resolved;
|
|
46
|
+
}
|
|
47
|
+
function doResolve(name) {
|
|
48
|
+
if (iconAliases[name]) return iconAliases[name];
|
|
49
|
+
const pascalName = kebabToPascal(name);
|
|
50
|
+
const directLookup = LucideIcons[pascalName];
|
|
51
|
+
if (directLookup && typeof directLookup === "object") return directLookup;
|
|
52
|
+
const asIs = LucideIcons[name];
|
|
53
|
+
if (asIs && typeof asIs === "object") return asIs;
|
|
54
|
+
return LucideIcons.HelpCircle;
|
|
55
|
+
}
|
|
56
|
+
var sizeClasses = {
|
|
57
|
+
xs: "w-3 h-3",
|
|
58
|
+
sm: "w-4 h-4",
|
|
59
|
+
md: "w-5 h-5",
|
|
60
|
+
lg: "w-6 h-6",
|
|
61
|
+
xl: "w-8 h-8"
|
|
62
|
+
};
|
|
63
|
+
var animationClasses = {
|
|
64
|
+
none: "",
|
|
65
|
+
spin: "animate-spin",
|
|
66
|
+
pulse: "animate-pulse"
|
|
67
|
+
};
|
|
68
|
+
var Icon = ({
|
|
69
|
+
icon,
|
|
70
|
+
name,
|
|
71
|
+
size = "md",
|
|
72
|
+
color,
|
|
73
|
+
animation = "none",
|
|
74
|
+
className,
|
|
75
|
+
strokeWidth,
|
|
76
|
+
style
|
|
77
|
+
}) => {
|
|
78
|
+
const IconComponent = icon ?? (name ? resolveIcon(name) : LucideIcons.HelpCircle);
|
|
79
|
+
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
80
|
+
return /* @__PURE__ */ jsx(
|
|
81
|
+
IconComponent,
|
|
82
|
+
{
|
|
83
|
+
className: cn(
|
|
84
|
+
sizeClasses[size],
|
|
85
|
+
animationClasses[animation],
|
|
86
|
+
// Use theme's icon color or provided color
|
|
87
|
+
color ? color : "text-[var(--icon-color,currentColor)]",
|
|
88
|
+
className
|
|
89
|
+
),
|
|
90
|
+
strokeWidth: effectiveStrokeWidth,
|
|
91
|
+
style: {
|
|
92
|
+
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
93
|
+
...style
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
Icon.displayName = "Icon";
|
|
20
99
|
var variantStyles = {
|
|
21
100
|
primary: [
|
|
22
101
|
"bg-[var(--color-primary)] text-[var(--color-primary-foreground)]",
|
|
@@ -75,7 +154,7 @@ var iconSizeStyles = {
|
|
|
75
154
|
md: "h-4 w-4",
|
|
76
155
|
lg: "h-5 w-5"
|
|
77
156
|
};
|
|
78
|
-
var Button =
|
|
157
|
+
var Button = React47__default.forwardRef(
|
|
79
158
|
({
|
|
80
159
|
className,
|
|
81
160
|
variant = "primary",
|
|
@@ -84,8 +163,8 @@ var Button = React41__default.forwardRef(
|
|
|
84
163
|
disabled,
|
|
85
164
|
leftIcon,
|
|
86
165
|
rightIcon,
|
|
87
|
-
icon:
|
|
88
|
-
iconRight:
|
|
166
|
+
icon: iconProp,
|
|
167
|
+
iconRight: iconRightProp,
|
|
89
168
|
action,
|
|
90
169
|
actionPayload,
|
|
91
170
|
label,
|
|
@@ -94,6 +173,8 @@ var Button = React41__default.forwardRef(
|
|
|
94
173
|
...props
|
|
95
174
|
}, ref) => {
|
|
96
175
|
const eventBus = useEventBus();
|
|
176
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
177
|
+
const IconRightComponent = typeof iconRightProp === "string" ? resolveIcon(iconRightProp) : iconRightProp;
|
|
97
178
|
const resolvedLeftIcon = leftIcon || IconComponent && /* @__PURE__ */ jsx(IconComponent, { className: iconSizeStyles[size] });
|
|
98
179
|
const resolvedRightIcon = rightIcon || IconRightComponent && /* @__PURE__ */ jsx(IconRightComponent, { className: iconSizeStyles[size] });
|
|
99
180
|
const handleClick = (e) => {
|
|
@@ -120,6 +201,7 @@ var Button = React41__default.forwardRef(
|
|
|
120
201
|
),
|
|
121
202
|
onClick: handleClick,
|
|
122
203
|
...props,
|
|
204
|
+
"data-testid": props["data-testid"] ?? (action ? `action-${action}` : void 0),
|
|
123
205
|
children: [
|
|
124
206
|
isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
|
|
125
207
|
children || label,
|
|
@@ -130,7 +212,7 @@ var Button = React41__default.forwardRef(
|
|
|
130
212
|
}
|
|
131
213
|
);
|
|
132
214
|
Button.displayName = "Button";
|
|
133
|
-
var Input =
|
|
215
|
+
var Input = React47__default.forwardRef(
|
|
134
216
|
({
|
|
135
217
|
className,
|
|
136
218
|
inputType,
|
|
@@ -242,7 +324,7 @@ var Input = React41__default.forwardRef(
|
|
|
242
324
|
}
|
|
243
325
|
);
|
|
244
326
|
Input.displayName = "Input";
|
|
245
|
-
var Label =
|
|
327
|
+
var Label = React47__default.forwardRef(
|
|
246
328
|
({ className, required, children, ...props }, ref) => {
|
|
247
329
|
return /* @__PURE__ */ jsxs(
|
|
248
330
|
"label",
|
|
@@ -262,7 +344,7 @@ var Label = React41__default.forwardRef(
|
|
|
262
344
|
}
|
|
263
345
|
);
|
|
264
346
|
Label.displayName = "Label";
|
|
265
|
-
var Textarea =
|
|
347
|
+
var Textarea = React47__default.forwardRef(
|
|
266
348
|
({ className, error, ...props }, ref) => {
|
|
267
349
|
return /* @__PURE__ */ jsx(
|
|
268
350
|
"textarea",
|
|
@@ -285,7 +367,7 @@ var Textarea = React41__default.forwardRef(
|
|
|
285
367
|
}
|
|
286
368
|
);
|
|
287
369
|
Textarea.displayName = "Textarea";
|
|
288
|
-
var Select =
|
|
370
|
+
var Select = React47__default.forwardRef(
|
|
289
371
|
({ className, options, placeholder, error, ...props }, ref) => {
|
|
290
372
|
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
291
373
|
/* @__PURE__ */ jsxs(
|
|
@@ -321,7 +403,7 @@ var Select = React41__default.forwardRef(
|
|
|
321
403
|
}
|
|
322
404
|
);
|
|
323
405
|
Select.displayName = "Select";
|
|
324
|
-
var Checkbox =
|
|
406
|
+
var Checkbox = React47__default.forwardRef(
|
|
325
407
|
({ className, label, id, ...props }, ref) => {
|
|
326
408
|
const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
327
409
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
@@ -387,7 +469,7 @@ var shadowStyles = {
|
|
|
387
469
|
md: "shadow-[var(--shadow-main)]",
|
|
388
470
|
lg: "shadow-[var(--shadow-lg)]"
|
|
389
471
|
};
|
|
390
|
-
var Card =
|
|
472
|
+
var Card = React47__default.forwardRef(
|
|
391
473
|
({
|
|
392
474
|
className,
|
|
393
475
|
variant = "bordered",
|
|
@@ -423,9 +505,9 @@ var Card = React41__default.forwardRef(
|
|
|
423
505
|
}
|
|
424
506
|
);
|
|
425
507
|
Card.displayName = "Card";
|
|
426
|
-
var CardHeader =
|
|
508
|
+
var CardHeader = React47__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
|
|
427
509
|
CardHeader.displayName = "CardHeader";
|
|
428
|
-
var CardTitle =
|
|
510
|
+
var CardTitle = React47__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
429
511
|
"h3",
|
|
430
512
|
{
|
|
431
513
|
ref,
|
|
@@ -438,11 +520,11 @@ var CardTitle = React41__default.forwardRef(({ className, ...props }, ref) => /*
|
|
|
438
520
|
}
|
|
439
521
|
));
|
|
440
522
|
CardTitle.displayName = "CardTitle";
|
|
441
|
-
var CardContent =
|
|
523
|
+
var CardContent = React47__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
|
|
442
524
|
CardContent.displayName = "CardContent";
|
|
443
525
|
var CardBody = CardContent;
|
|
444
526
|
CardBody.displayName = "CardBody";
|
|
445
|
-
var CardFooter =
|
|
527
|
+
var CardFooter = React47__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
446
528
|
"div",
|
|
447
529
|
{
|
|
448
530
|
ref,
|
|
@@ -488,8 +570,8 @@ var sizeStyles2 = {
|
|
|
488
570
|
md: "px-2.5 py-1 text-sm",
|
|
489
571
|
lg: "px-3 py-1.5 text-base"
|
|
490
572
|
};
|
|
491
|
-
var Badge =
|
|
492
|
-
({ className, variant = "default", size = "sm", ...props }, ref) => {
|
|
573
|
+
var Badge = React47__default.forwardRef(
|
|
574
|
+
({ className, variant = "default", size = "sm", label, children, ...props }, ref) => {
|
|
493
575
|
return /* @__PURE__ */ jsx(
|
|
494
576
|
"span",
|
|
495
577
|
{
|
|
@@ -500,7 +582,8 @@ var Badge = React41__default.forwardRef(
|
|
|
500
582
|
sizeStyles2[size],
|
|
501
583
|
className
|
|
502
584
|
),
|
|
503
|
-
...props
|
|
585
|
+
...props,
|
|
586
|
+
children: children || label
|
|
504
587
|
}
|
|
505
588
|
);
|
|
506
589
|
}
|
|
@@ -512,7 +595,7 @@ var sizeStyles3 = {
|
|
|
512
595
|
md: "h-6 w-6",
|
|
513
596
|
lg: "h-8 w-8"
|
|
514
597
|
};
|
|
515
|
-
var Spinner =
|
|
598
|
+
var Spinner = React47__default.forwardRef(
|
|
516
599
|
({ className, size = "md", ...props }, ref) => {
|
|
517
600
|
return /* @__PURE__ */ jsx(
|
|
518
601
|
"div",
|
|
@@ -526,7 +609,7 @@ var Spinner = React41__default.forwardRef(
|
|
|
526
609
|
}
|
|
527
610
|
);
|
|
528
611
|
Spinner.displayName = "Spinner";
|
|
529
|
-
var
|
|
612
|
+
var sizeClasses2 = {
|
|
530
613
|
xs: "w-6 h-6 text-xs",
|
|
531
614
|
sm: "w-8 h-8 text-sm",
|
|
532
615
|
md: "w-10 h-10 text-base",
|
|
@@ -602,7 +685,7 @@ var Avatar = ({
|
|
|
602
685
|
"relative inline-flex items-center justify-center",
|
|
603
686
|
"bg-[var(--color-muted)] border-[length:var(--border-width)] border-[var(--color-border)]",
|
|
604
687
|
"overflow-hidden",
|
|
605
|
-
|
|
688
|
+
sizeClasses2[size],
|
|
606
689
|
isClickable && "cursor-pointer hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
607
690
|
className
|
|
608
691
|
),
|
|
@@ -777,7 +860,7 @@ var positionStyles = {
|
|
|
777
860
|
fixed: "fixed",
|
|
778
861
|
sticky: "sticky"
|
|
779
862
|
};
|
|
780
|
-
var Box =
|
|
863
|
+
var Box = React47__default.forwardRef(
|
|
781
864
|
({
|
|
782
865
|
padding,
|
|
783
866
|
paddingX,
|
|
@@ -969,157 +1052,6 @@ var Divider = ({
|
|
|
969
1052
|
);
|
|
970
1053
|
};
|
|
971
1054
|
Divider.displayName = "Divider";
|
|
972
|
-
var iconMap = {
|
|
973
|
-
// Navigation & Actions
|
|
974
|
-
"chevron-right": LucideIcons.ChevronRight,
|
|
975
|
-
"chevron-left": LucideIcons.ChevronLeft,
|
|
976
|
-
"chevron-down": LucideIcons.ChevronDown,
|
|
977
|
-
"chevron-up": LucideIcons.ChevronUp,
|
|
978
|
-
"arrow-right": LucideIcons.ArrowRight,
|
|
979
|
-
"arrow-left": LucideIcons.ArrowLeft,
|
|
980
|
-
"arrow-up": LucideIcons.ArrowUp,
|
|
981
|
-
"arrow-down": LucideIcons.ArrowDown,
|
|
982
|
-
"x": LucideIcons.X,
|
|
983
|
-
"close": LucideIcons.X,
|
|
984
|
-
"menu": LucideIcons.Menu,
|
|
985
|
-
"more-vertical": LucideIcons.MoreVertical,
|
|
986
|
-
"more-horizontal": LucideIcons.MoreHorizontal,
|
|
987
|
-
// Status & Feedback
|
|
988
|
-
"check": LucideIcons.Check,
|
|
989
|
-
"check-circle": LucideIcons.CheckCircle,
|
|
990
|
-
"alert-circle": LucideIcons.AlertCircle,
|
|
991
|
-
"alert-triangle": LucideIcons.AlertTriangle,
|
|
992
|
-
"info": LucideIcons.Info,
|
|
993
|
-
"help-circle": LucideIcons.HelpCircle,
|
|
994
|
-
"loader": LucideIcons.Loader2,
|
|
995
|
-
// CRUD Operations
|
|
996
|
-
"plus": LucideIcons.Plus,
|
|
997
|
-
"minus": LucideIcons.Minus,
|
|
998
|
-
"edit": LucideIcons.Edit,
|
|
999
|
-
"pencil": LucideIcons.Pencil,
|
|
1000
|
-
"trash": LucideIcons.Trash2,
|
|
1001
|
-
"trash-2": LucideIcons.Trash2,
|
|
1002
|
-
"save": LucideIcons.Save,
|
|
1003
|
-
"copy": LucideIcons.Copy,
|
|
1004
|
-
"clipboard": LucideIcons.Clipboard,
|
|
1005
|
-
// Files & Documents
|
|
1006
|
-
"file": LucideIcons.File,
|
|
1007
|
-
"file-text": LucideIcons.FileText,
|
|
1008
|
-
"folder": LucideIcons.Folder,
|
|
1009
|
-
"folder-open": LucideIcons.FolderOpen,
|
|
1010
|
-
"download": LucideIcons.Download,
|
|
1011
|
-
"upload": LucideIcons.Upload,
|
|
1012
|
-
"image": LucideIcons.Image,
|
|
1013
|
-
// Communication
|
|
1014
|
-
"mail": LucideIcons.Mail,
|
|
1015
|
-
"message-circle": LucideIcons.MessageCircle,
|
|
1016
|
-
"send": LucideIcons.Send,
|
|
1017
|
-
"phone": LucideIcons.Phone,
|
|
1018
|
-
// User & Profile
|
|
1019
|
-
"user": LucideIcons.User,
|
|
1020
|
-
"users": LucideIcons.Users,
|
|
1021
|
-
"user-plus": LucideIcons.UserPlus,
|
|
1022
|
-
"settings": LucideIcons.Settings,
|
|
1023
|
-
"log-out": LucideIcons.LogOut,
|
|
1024
|
-
"log-in": LucideIcons.LogIn,
|
|
1025
|
-
// Search & Filter
|
|
1026
|
-
"search": LucideIcons.Search,
|
|
1027
|
-
"filter": LucideIcons.Filter,
|
|
1028
|
-
"sort-asc": LucideIcons.ArrowUpNarrowWide,
|
|
1029
|
-
"sort-desc": LucideIcons.ArrowDownNarrowWide,
|
|
1030
|
-
// Layout & View
|
|
1031
|
-
"grid": LucideIcons.Grid,
|
|
1032
|
-
"list": LucideIcons.List,
|
|
1033
|
-
"layout": LucideIcons.Layout,
|
|
1034
|
-
"maximize": LucideIcons.Maximize,
|
|
1035
|
-
"minimize": LucideIcons.Minimize,
|
|
1036
|
-
"eye": LucideIcons.Eye,
|
|
1037
|
-
"eye-off": LucideIcons.EyeOff,
|
|
1038
|
-
// Media & Playback
|
|
1039
|
-
"play": LucideIcons.Play,
|
|
1040
|
-
"pause": LucideIcons.Pause,
|
|
1041
|
-
"stop": LucideIcons.Square,
|
|
1042
|
-
"volume": LucideIcons.Volume2,
|
|
1043
|
-
"volume-off": LucideIcons.VolumeX,
|
|
1044
|
-
// Time & Calendar
|
|
1045
|
-
"calendar": LucideIcons.Calendar,
|
|
1046
|
-
"clock": LucideIcons.Clock,
|
|
1047
|
-
// Misc
|
|
1048
|
-
"star": LucideIcons.Star,
|
|
1049
|
-
"heart": LucideIcons.Heart,
|
|
1050
|
-
"home": LucideIcons.Home,
|
|
1051
|
-
"link": LucideIcons.Link,
|
|
1052
|
-
"external-link": LucideIcons.ExternalLink,
|
|
1053
|
-
"refresh": LucideIcons.RefreshCw,
|
|
1054
|
-
"refresh-cw": LucideIcons.RefreshCw,
|
|
1055
|
-
"zap": LucideIcons.Zap,
|
|
1056
|
-
"bell": LucideIcons.Bell,
|
|
1057
|
-
"bookmark": LucideIcons.Bookmark,
|
|
1058
|
-
"share": LucideIcons.Share2,
|
|
1059
|
-
"lock": LucideIcons.Lock,
|
|
1060
|
-
"unlock": LucideIcons.Unlock,
|
|
1061
|
-
"globe": LucideIcons.Globe,
|
|
1062
|
-
"database": LucideIcons.Database,
|
|
1063
|
-
"code": LucideIcons.Code,
|
|
1064
|
-
"terminal": LucideIcons.Terminal
|
|
1065
|
-
};
|
|
1066
|
-
function resolveIcon(name) {
|
|
1067
|
-
if (iconMap[name]) {
|
|
1068
|
-
return iconMap[name];
|
|
1069
|
-
}
|
|
1070
|
-
const lowerName = name.toLowerCase();
|
|
1071
|
-
if (iconMap[lowerName]) {
|
|
1072
|
-
return iconMap[lowerName];
|
|
1073
|
-
}
|
|
1074
|
-
const kebabName = name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1075
|
-
if (iconMap[kebabName]) {
|
|
1076
|
-
return iconMap[kebabName];
|
|
1077
|
-
}
|
|
1078
|
-
return LucideIcons.HelpCircle;
|
|
1079
|
-
}
|
|
1080
|
-
var sizeClasses2 = {
|
|
1081
|
-
xs: "w-3 h-3",
|
|
1082
|
-
sm: "w-4 h-4",
|
|
1083
|
-
md: "w-5 h-5",
|
|
1084
|
-
lg: "w-6 h-6",
|
|
1085
|
-
xl: "w-8 h-8"
|
|
1086
|
-
};
|
|
1087
|
-
var animationClasses = {
|
|
1088
|
-
none: "",
|
|
1089
|
-
spin: "animate-spin",
|
|
1090
|
-
pulse: "animate-pulse"
|
|
1091
|
-
};
|
|
1092
|
-
var Icon = ({
|
|
1093
|
-
icon,
|
|
1094
|
-
name,
|
|
1095
|
-
size = "md",
|
|
1096
|
-
color,
|
|
1097
|
-
animation = "none",
|
|
1098
|
-
className,
|
|
1099
|
-
strokeWidth,
|
|
1100
|
-
style
|
|
1101
|
-
}) => {
|
|
1102
|
-
const IconComponent = icon ?? (name ? resolveIcon(name) : LucideIcons.HelpCircle);
|
|
1103
|
-
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
1104
|
-
return /* @__PURE__ */ jsx(
|
|
1105
|
-
IconComponent,
|
|
1106
|
-
{
|
|
1107
|
-
className: cn(
|
|
1108
|
-
sizeClasses2[size],
|
|
1109
|
-
animationClasses[animation],
|
|
1110
|
-
// Use theme's icon color or provided color
|
|
1111
|
-
color ? color : "text-[var(--icon-color,currentColor)]",
|
|
1112
|
-
className
|
|
1113
|
-
),
|
|
1114
|
-
strokeWidth: effectiveStrokeWidth,
|
|
1115
|
-
style: {
|
|
1116
|
-
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
1117
|
-
...style
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
);
|
|
1121
|
-
};
|
|
1122
|
-
Icon.displayName = "Icon";
|
|
1123
1055
|
var colorClasses = {
|
|
1124
1056
|
default: "bg-[var(--color-primary)]",
|
|
1125
1057
|
primary: "bg-[var(--color-primary)]",
|
|
@@ -1273,7 +1205,7 @@ var ProgressBar = ({
|
|
|
1273
1205
|
return null;
|
|
1274
1206
|
};
|
|
1275
1207
|
ProgressBar.displayName = "ProgressBar";
|
|
1276
|
-
var Radio =
|
|
1208
|
+
var Radio = React47__default.forwardRef(
|
|
1277
1209
|
({
|
|
1278
1210
|
label,
|
|
1279
1211
|
helperText,
|
|
@@ -1377,7 +1309,7 @@ var Radio = React41__default.forwardRef(
|
|
|
1377
1309
|
}
|
|
1378
1310
|
);
|
|
1379
1311
|
Radio.displayName = "Radio";
|
|
1380
|
-
var Switch =
|
|
1312
|
+
var Switch = React47.forwardRef(
|
|
1381
1313
|
({
|
|
1382
1314
|
checked,
|
|
1383
1315
|
defaultChecked = false,
|
|
@@ -1388,10 +1320,10 @@ var Switch = React41.forwardRef(
|
|
|
1388
1320
|
name,
|
|
1389
1321
|
className
|
|
1390
1322
|
}, ref) => {
|
|
1391
|
-
const [isChecked, setIsChecked] =
|
|
1323
|
+
const [isChecked, setIsChecked] = React47.useState(
|
|
1392
1324
|
checked !== void 0 ? checked : defaultChecked
|
|
1393
1325
|
);
|
|
1394
|
-
|
|
1326
|
+
React47.useEffect(() => {
|
|
1395
1327
|
if (checked !== void 0) {
|
|
1396
1328
|
setIsChecked(checked);
|
|
1397
1329
|
}
|
|
@@ -1626,6 +1558,8 @@ var variantStyles5 = {
|
|
|
1626
1558
|
h4: "text-xl font-bold text-[var(--color-foreground)]",
|
|
1627
1559
|
h5: "text-lg font-bold text-[var(--color-foreground)]",
|
|
1628
1560
|
h6: "text-base font-bold text-[var(--color-foreground)]",
|
|
1561
|
+
heading: "text-2xl font-bold text-[var(--color-foreground)]",
|
|
1562
|
+
subheading: "text-lg font-semibold text-[var(--color-foreground)]",
|
|
1629
1563
|
body1: "text-base font-normal text-[var(--color-foreground)]",
|
|
1630
1564
|
body2: "text-sm font-normal text-[var(--color-foreground)]",
|
|
1631
1565
|
body: "text-base font-normal text-[var(--color-foreground)]",
|
|
@@ -1658,6 +1592,8 @@ var defaultElements = {
|
|
|
1658
1592
|
h4: "h4",
|
|
1659
1593
|
h5: "h5",
|
|
1660
1594
|
h6: "h6",
|
|
1595
|
+
heading: "h2",
|
|
1596
|
+
subheading: "h3",
|
|
1661
1597
|
body1: "p",
|
|
1662
1598
|
body2: "p",
|
|
1663
1599
|
body: "p",
|
|
@@ -1951,7 +1887,7 @@ var Overlay = ({
|
|
|
1951
1887
|
isVisible = true,
|
|
1952
1888
|
onClick,
|
|
1953
1889
|
className,
|
|
1954
|
-
blur =
|
|
1890
|
+
blur = false,
|
|
1955
1891
|
action
|
|
1956
1892
|
}) => {
|
|
1957
1893
|
const eventBus = useEventBus();
|
|
@@ -1966,7 +1902,7 @@ var Overlay = ({
|
|
|
1966
1902
|
"div",
|
|
1967
1903
|
{
|
|
1968
1904
|
className: cn(
|
|
1969
|
-
"fixed inset-0 z-40 bg-
|
|
1905
|
+
"fixed inset-0 z-40 bg-black/50",
|
|
1970
1906
|
blur && "backdrop-blur-sm",
|
|
1971
1907
|
className
|
|
1972
1908
|
),
|
|
@@ -1975,6 +1911,33 @@ var Overlay = ({
|
|
|
1975
1911
|
}
|
|
1976
1912
|
);
|
|
1977
1913
|
};
|
|
1914
|
+
var FlipContainer = ({
|
|
1915
|
+
flipped,
|
|
1916
|
+
className,
|
|
1917
|
+
children,
|
|
1918
|
+
onClick
|
|
1919
|
+
}) => {
|
|
1920
|
+
return /* @__PURE__ */ jsx(
|
|
1921
|
+
Box,
|
|
1922
|
+
{
|
|
1923
|
+
className: cn("relative w-full cursor-pointer", className),
|
|
1924
|
+
style: { perspective: "1000px" },
|
|
1925
|
+
onClick,
|
|
1926
|
+
children: /* @__PURE__ */ jsx(
|
|
1927
|
+
Box,
|
|
1928
|
+
{
|
|
1929
|
+
className: "relative w-full h-full transition-transform duration-500",
|
|
1930
|
+
style: {
|
|
1931
|
+
transformStyle: "preserve-3d",
|
|
1932
|
+
transform: flipped ? "rotateY(180deg)" : "rotateY(0deg)"
|
|
1933
|
+
},
|
|
1934
|
+
children
|
|
1935
|
+
}
|
|
1936
|
+
)
|
|
1937
|
+
}
|
|
1938
|
+
);
|
|
1939
|
+
};
|
|
1940
|
+
FlipContainer.displayName = "FlipContainer";
|
|
1978
1941
|
function toSharedContext(ctx) {
|
|
1979
1942
|
return createMinimalContext(
|
|
1980
1943
|
{
|
|
@@ -2031,8 +1994,8 @@ var LawReferenceTooltip = ({
|
|
|
2031
1994
|
position = "top",
|
|
2032
1995
|
className
|
|
2033
1996
|
}) => {
|
|
2034
|
-
const [isVisible, setIsVisible] =
|
|
2035
|
-
const timeoutRef =
|
|
1997
|
+
const [isVisible, setIsVisible] = React47__default.useState(false);
|
|
1998
|
+
const timeoutRef = React47__default.useRef(null);
|
|
2036
1999
|
const handleMouseEnter = () => {
|
|
2037
2000
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2038
2001
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -2041,7 +2004,7 @@ var LawReferenceTooltip = ({
|
|
|
2041
2004
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2042
2005
|
setIsVisible(false);
|
|
2043
2006
|
};
|
|
2044
|
-
|
|
2007
|
+
React47__default.useEffect(() => {
|
|
2045
2008
|
return () => {
|
|
2046
2009
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2047
2010
|
};
|
|
@@ -2135,6 +2098,79 @@ var LawReferenceTooltip = ({
|
|
|
2135
2098
|
);
|
|
2136
2099
|
};
|
|
2137
2100
|
LawReferenceTooltip.displayName = "LawReferenceTooltip";
|
|
2101
|
+
var DAY_ABBREVIATIONS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2102
|
+
function DayCell({
|
|
2103
|
+
date,
|
|
2104
|
+
isToday = false,
|
|
2105
|
+
onClick,
|
|
2106
|
+
className
|
|
2107
|
+
}) {
|
|
2108
|
+
const handleClick = useCallback(() => {
|
|
2109
|
+
onClick?.(date);
|
|
2110
|
+
}, [onClick, date]);
|
|
2111
|
+
const dayAbbr = DAY_ABBREVIATIONS[date.getDay()];
|
|
2112
|
+
return /* @__PURE__ */ jsxs(
|
|
2113
|
+
Box,
|
|
2114
|
+
{
|
|
2115
|
+
className: cn(
|
|
2116
|
+
"p-2 text-center cursor-pointer hover:bg-[var(--color-muted)] transition-colors",
|
|
2117
|
+
isToday && "bg-blue-500/10",
|
|
2118
|
+
className
|
|
2119
|
+
),
|
|
2120
|
+
onClick: handleClick,
|
|
2121
|
+
children: [
|
|
2122
|
+
/* @__PURE__ */ jsx(
|
|
2123
|
+
Typography,
|
|
2124
|
+
{
|
|
2125
|
+
variant: "small",
|
|
2126
|
+
className: cn(
|
|
2127
|
+
"font-medium",
|
|
2128
|
+
isToday ? "text-blue-600" : "text-[var(--color-muted-foreground)]"
|
|
2129
|
+
),
|
|
2130
|
+
children: dayAbbr
|
|
2131
|
+
}
|
|
2132
|
+
),
|
|
2133
|
+
/* @__PURE__ */ jsx(
|
|
2134
|
+
Box,
|
|
2135
|
+
{
|
|
2136
|
+
display: "flex",
|
|
2137
|
+
rounded: "full",
|
|
2138
|
+
className: cn(
|
|
2139
|
+
"h-8 w-8 mx-auto items-center justify-center",
|
|
2140
|
+
isToday && "bg-blue-600 text-white"
|
|
2141
|
+
),
|
|
2142
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "font-semibold", children: date.getDate() })
|
|
2143
|
+
}
|
|
2144
|
+
)
|
|
2145
|
+
]
|
|
2146
|
+
}
|
|
2147
|
+
);
|
|
2148
|
+
}
|
|
2149
|
+
DayCell.displayName = "DayCell";
|
|
2150
|
+
function TimeSlotCell({
|
|
2151
|
+
time,
|
|
2152
|
+
onClick,
|
|
2153
|
+
className,
|
|
2154
|
+
children,
|
|
2155
|
+
isOccupied = false
|
|
2156
|
+
}) {
|
|
2157
|
+
const handleClick = useCallback(() => {
|
|
2158
|
+
onClick?.(time);
|
|
2159
|
+
}, [onClick, time]);
|
|
2160
|
+
return /* @__PURE__ */ jsx(
|
|
2161
|
+
Box,
|
|
2162
|
+
{
|
|
2163
|
+
className: cn(
|
|
2164
|
+
"p-1 min-h-[60px] cursor-pointer hover:bg-[var(--color-muted)] transition-colors",
|
|
2165
|
+
isOccupied && "bg-[var(--color-muted)]/30",
|
|
2166
|
+
className
|
|
2167
|
+
),
|
|
2168
|
+
onClick: handleClick,
|
|
2169
|
+
children
|
|
2170
|
+
}
|
|
2171
|
+
);
|
|
2172
|
+
}
|
|
2173
|
+
TimeSlotCell.displayName = "TimeSlotCell";
|
|
2138
2174
|
var heartIcon = (filled, size) => /* @__PURE__ */ jsx(
|
|
2139
2175
|
"svg",
|
|
2140
2176
|
{
|
|
@@ -2217,9 +2253,9 @@ function ScoreDisplay({
|
|
|
2217
2253
|
animated = true,
|
|
2218
2254
|
locale = "en-US"
|
|
2219
2255
|
}) {
|
|
2220
|
-
const [displayValue, setDisplayValue] =
|
|
2221
|
-
const [isAnimating, setIsAnimating] =
|
|
2222
|
-
|
|
2256
|
+
const [displayValue, setDisplayValue] = React47.useState(value);
|
|
2257
|
+
const [isAnimating, setIsAnimating] = React47.useState(false);
|
|
2258
|
+
React47.useEffect(() => {
|
|
2223
2259
|
if (!animated || displayValue === value) {
|
|
2224
2260
|
setDisplayValue(value);
|
|
2225
2261
|
return;
|
|
@@ -2292,9 +2328,9 @@ function ControlButton({
|
|
|
2292
2328
|
className
|
|
2293
2329
|
}) {
|
|
2294
2330
|
const eventBus = useEventBus();
|
|
2295
|
-
const [isPressed, setIsPressed] =
|
|
2331
|
+
const [isPressed, setIsPressed] = React47.useState(false);
|
|
2296
2332
|
const actualPressed = pressed ?? isPressed;
|
|
2297
|
-
const handlePointerDown =
|
|
2333
|
+
const handlePointerDown = React47.useCallback(
|
|
2298
2334
|
(e) => {
|
|
2299
2335
|
e.preventDefault();
|
|
2300
2336
|
if (disabled) return;
|
|
@@ -2304,7 +2340,7 @@ function ControlButton({
|
|
|
2304
2340
|
},
|
|
2305
2341
|
[disabled, pressEvent, eventBus, onPress]
|
|
2306
2342
|
);
|
|
2307
|
-
const handlePointerUp =
|
|
2343
|
+
const handlePointerUp = React47.useCallback(
|
|
2308
2344
|
(e) => {
|
|
2309
2345
|
e.preventDefault();
|
|
2310
2346
|
if (disabled) return;
|
|
@@ -2314,7 +2350,7 @@ function ControlButton({
|
|
|
2314
2350
|
},
|
|
2315
2351
|
[disabled, releaseEvent, eventBus, onRelease]
|
|
2316
2352
|
);
|
|
2317
|
-
const handlePointerLeave =
|
|
2353
|
+
const handlePointerLeave = React47.useCallback(
|
|
2318
2354
|
(e) => {
|
|
2319
2355
|
if (isPressed) {
|
|
2320
2356
|
setIsPressed(false);
|
|
@@ -2542,7 +2578,7 @@ var ErrorState = ({
|
|
|
2542
2578
|
);
|
|
2543
2579
|
};
|
|
2544
2580
|
ErrorState.displayName = "ErrorState";
|
|
2545
|
-
var ErrorBoundary = class extends
|
|
2581
|
+
var ErrorBoundary = class extends React47__default.Component {
|
|
2546
2582
|
constructor(props) {
|
|
2547
2583
|
super(props);
|
|
2548
2584
|
__publicField(this, "reset", () => {
|
|
@@ -2946,7 +2982,7 @@ var variantIconColors = {
|
|
|
2946
2982
|
warning: "text-[var(--color-warning)]",
|
|
2947
2983
|
error: "text-[var(--color-error)]"
|
|
2948
2984
|
};
|
|
2949
|
-
var
|
|
2985
|
+
var iconMap = {
|
|
2950
2986
|
info: Info,
|
|
2951
2987
|
success: CheckCircle,
|
|
2952
2988
|
warning: AlertTriangle,
|
|
@@ -2985,7 +3021,7 @@ var Alert = ({
|
|
|
2985
3021
|
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx(
|
|
2986
3022
|
Icon,
|
|
2987
3023
|
{
|
|
2988
|
-
icon:
|
|
3024
|
+
icon: iconMap[variant],
|
|
2989
3025
|
size: "md",
|
|
2990
3026
|
className: variantIconColors[variant]
|
|
2991
3027
|
}
|
|
@@ -3997,7 +4033,7 @@ function getColsClass(cols) {
|
|
|
3997
4033
|
}
|
|
3998
4034
|
return classes.join(" ");
|
|
3999
4035
|
}
|
|
4000
|
-
var
|
|
4036
|
+
var Grid = ({
|
|
4001
4037
|
cols = 1,
|
|
4002
4038
|
rows,
|
|
4003
4039
|
gap = "md",
|
|
@@ -4034,7 +4070,7 @@ var Grid2 = ({
|
|
|
4034
4070
|
}
|
|
4035
4071
|
);
|
|
4036
4072
|
};
|
|
4037
|
-
|
|
4073
|
+
Grid.displayName = "Grid";
|
|
4038
4074
|
var InputGroup = ({
|
|
4039
4075
|
leftAddon,
|
|
4040
4076
|
rightAddon,
|
|
@@ -4089,7 +4125,7 @@ var InputGroup = ({
|
|
|
4089
4125
|
] });
|
|
4090
4126
|
};
|
|
4091
4127
|
InputGroup.displayName = "InputGroup";
|
|
4092
|
-
var
|
|
4128
|
+
var Menu = ({
|
|
4093
4129
|
trigger,
|
|
4094
4130
|
items,
|
|
4095
4131
|
position = "bottom-left",
|
|
@@ -4150,8 +4186,8 @@ var Menu2 = ({
|
|
|
4150
4186
|
"bottom-start": "top-full left-0 mt-2",
|
|
4151
4187
|
"bottom-end": "top-full right-0 mt-2"
|
|
4152
4188
|
};
|
|
4153
|
-
const triggerChild =
|
|
4154
|
-
const triggerElement =
|
|
4189
|
+
const triggerChild = React47__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx("span", { children: trigger });
|
|
4190
|
+
const triggerElement = React47__default.cloneElement(
|
|
4155
4191
|
triggerChild,
|
|
4156
4192
|
{
|
|
4157
4193
|
ref: triggerRef,
|
|
@@ -4247,7 +4283,7 @@ var Menu2 = ({
|
|
|
4247
4283
|
)
|
|
4248
4284
|
] });
|
|
4249
4285
|
};
|
|
4250
|
-
|
|
4286
|
+
Menu.displayName = "Menu";
|
|
4251
4287
|
var sizeClasses4 = {
|
|
4252
4288
|
sm: "max-w-md",
|
|
4253
4289
|
md: "max-w-lg",
|
|
@@ -4355,6 +4391,7 @@ var Modal = ({
|
|
|
4355
4391
|
{
|
|
4356
4392
|
type: "button",
|
|
4357
4393
|
onClick: handleClose,
|
|
4394
|
+
"data-event": "CLOSE",
|
|
4358
4395
|
className: cn(
|
|
4359
4396
|
"p-1 transition-colors rounded-[var(--radius-sm)]",
|
|
4360
4397
|
"hover:bg-[var(--color-muted)]"
|
|
@@ -4612,8 +4649,8 @@ var Popover = ({
|
|
|
4612
4649
|
onMouseEnter: handleOpen,
|
|
4613
4650
|
onMouseLeave: handleClose
|
|
4614
4651
|
};
|
|
4615
|
-
const childElement =
|
|
4616
|
-
const triggerElement =
|
|
4652
|
+
const childElement = React47__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
4653
|
+
const triggerElement = React47__default.cloneElement(
|
|
4617
4654
|
childElement,
|
|
4618
4655
|
{
|
|
4619
4656
|
ref: triggerRef,
|
|
@@ -5193,7 +5230,7 @@ var variantClasses = {
|
|
|
5193
5230
|
info: "bg-[var(--color-card)] border-[length:var(--border-width)] border-[var(--color-info)]",
|
|
5194
5231
|
warning: "bg-[var(--color-card)] border-[length:var(--border-width)] border-[var(--color-warning)]"
|
|
5195
5232
|
};
|
|
5196
|
-
var
|
|
5233
|
+
var iconMap2 = {
|
|
5197
5234
|
success: CheckCircle,
|
|
5198
5235
|
error: AlertCircle,
|
|
5199
5236
|
info: Info,
|
|
@@ -5251,7 +5288,7 @@ var Toast = ({
|
|
|
5251
5288
|
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx(
|
|
5252
5289
|
Icon,
|
|
5253
5290
|
{
|
|
5254
|
-
icon:
|
|
5291
|
+
icon: iconMap2[variant],
|
|
5255
5292
|
size: "md",
|
|
5256
5293
|
className: iconColors[variant]
|
|
5257
5294
|
}
|
|
@@ -5343,8 +5380,8 @@ var Tooltip = ({
|
|
|
5343
5380
|
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
|
5344
5381
|
};
|
|
5345
5382
|
}, []);
|
|
5346
|
-
const triggerElement =
|
|
5347
|
-
const trigger =
|
|
5383
|
+
const triggerElement = React47__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
5384
|
+
const trigger = React47__default.cloneElement(triggerElement, {
|
|
5348
5385
|
ref: triggerRef,
|
|
5349
5386
|
onMouseEnter: handleMouseEnter,
|
|
5350
5387
|
onMouseLeave: handleMouseLeave,
|
|
@@ -5593,7 +5630,7 @@ var WizardProgress = ({
|
|
|
5593
5630
|
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: steps.map((step, index) => {
|
|
5594
5631
|
const isActive = index === currentStep;
|
|
5595
5632
|
const isCompleted = index < currentStep;
|
|
5596
|
-
return /* @__PURE__ */ jsxs(
|
|
5633
|
+
return /* @__PURE__ */ jsxs(React47__default.Fragment, { children: [
|
|
5597
5634
|
/* @__PURE__ */ jsx(
|
|
5598
5635
|
"button",
|
|
5599
5636
|
{
|
|
@@ -5723,7 +5760,7 @@ var WizardNavigation = ({
|
|
|
5723
5760
|
);
|
|
5724
5761
|
};
|
|
5725
5762
|
WizardNavigation.displayName = "WizardNavigation";
|
|
5726
|
-
var MarkdownContent =
|
|
5763
|
+
var MarkdownContent = React47__default.memo(
|
|
5727
5764
|
({ content, direction, className }) => {
|
|
5728
5765
|
const { t: _t } = useTranslate();
|
|
5729
5766
|
return /* @__PURE__ */ jsx(
|
|
@@ -5824,7 +5861,7 @@ var MarkdownContent = React41__default.memo(
|
|
|
5824
5861
|
(prev, next) => prev.content === next.content && prev.className === next.className && prev.direction === next.direction
|
|
5825
5862
|
);
|
|
5826
5863
|
MarkdownContent.displayName = "MarkdownContent";
|
|
5827
|
-
var CodeBlock =
|
|
5864
|
+
var CodeBlock = React47__default.memo(
|
|
5828
5865
|
({
|
|
5829
5866
|
code,
|
|
5830
5867
|
language = "text",
|
|
@@ -6049,6 +6086,156 @@ var ScaledDiagram = ({
|
|
|
6049
6086
|
);
|
|
6050
6087
|
};
|
|
6051
6088
|
ScaledDiagram.displayName = "ScaledDiagram";
|
|
6089
|
+
function getStartOfWeek(date) {
|
|
6090
|
+
const d = new Date(date);
|
|
6091
|
+
const day = d.getDay();
|
|
6092
|
+
const diff = d.getDate() - day + (day === 0 ? -6 : 1);
|
|
6093
|
+
d.setDate(diff);
|
|
6094
|
+
d.setHours(0, 0, 0, 0);
|
|
6095
|
+
return d;
|
|
6096
|
+
}
|
|
6097
|
+
function getWeekDays(start) {
|
|
6098
|
+
const days = [];
|
|
6099
|
+
for (let i = 0; i < 7; i++) {
|
|
6100
|
+
const day = new Date(start);
|
|
6101
|
+
day.setDate(start.getDate() + i);
|
|
6102
|
+
days.push(day);
|
|
6103
|
+
}
|
|
6104
|
+
return days;
|
|
6105
|
+
}
|
|
6106
|
+
function generateDefaultTimeSlots() {
|
|
6107
|
+
const slots = [];
|
|
6108
|
+
for (let hour = 9; hour <= 17; hour++) {
|
|
6109
|
+
slots.push(`${hour.toString().padStart(2, "0")}:00`);
|
|
6110
|
+
}
|
|
6111
|
+
return slots;
|
|
6112
|
+
}
|
|
6113
|
+
function eventInSlot(event, day, slotTime) {
|
|
6114
|
+
const eventStart = new Date(event.startTime);
|
|
6115
|
+
const [slotHour, slotMinute] = slotTime.split(":").map(Number);
|
|
6116
|
+
return eventStart.toDateString() === day.toDateString() && eventStart.getHours() === slotHour && eventStart.getMinutes() === slotMinute;
|
|
6117
|
+
}
|
|
6118
|
+
function CalendarGrid({
|
|
6119
|
+
weekStart,
|
|
6120
|
+
timeSlots,
|
|
6121
|
+
events = [],
|
|
6122
|
+
onSlotClick,
|
|
6123
|
+
onDayClick,
|
|
6124
|
+
onEventClick,
|
|
6125
|
+
className
|
|
6126
|
+
}) {
|
|
6127
|
+
const resolvedWeekStart = useMemo(
|
|
6128
|
+
() => weekStart ? getStartOfWeek(weekStart) : getStartOfWeek(/* @__PURE__ */ new Date()),
|
|
6129
|
+
[weekStart]
|
|
6130
|
+
);
|
|
6131
|
+
const weekDays = useMemo(
|
|
6132
|
+
() => getWeekDays(resolvedWeekStart),
|
|
6133
|
+
[resolvedWeekStart]
|
|
6134
|
+
);
|
|
6135
|
+
const resolvedTimeSlots = useMemo(
|
|
6136
|
+
() => timeSlots ?? generateDefaultTimeSlots(),
|
|
6137
|
+
[timeSlots]
|
|
6138
|
+
);
|
|
6139
|
+
const handleSlotClick = useCallback(
|
|
6140
|
+
(day, time) => {
|
|
6141
|
+
onSlotClick?.(day, time);
|
|
6142
|
+
},
|
|
6143
|
+
[onSlotClick]
|
|
6144
|
+
);
|
|
6145
|
+
const handleEventClick = useCallback(
|
|
6146
|
+
(event, e) => {
|
|
6147
|
+
e.stopPropagation();
|
|
6148
|
+
onEventClick?.(event);
|
|
6149
|
+
},
|
|
6150
|
+
[onEventClick]
|
|
6151
|
+
);
|
|
6152
|
+
const eventsForDayCount = useCallback(
|
|
6153
|
+
(day) => events.filter(
|
|
6154
|
+
(ev) => new Date(ev.startTime).toDateString() === day.toDateString()
|
|
6155
|
+
).length,
|
|
6156
|
+
[events]
|
|
6157
|
+
);
|
|
6158
|
+
const renderEvent = (event) => /* @__PURE__ */ jsx(
|
|
6159
|
+
Box,
|
|
6160
|
+
{
|
|
6161
|
+
rounded: "md",
|
|
6162
|
+
padding: "xs",
|
|
6163
|
+
border: true,
|
|
6164
|
+
className: cn(
|
|
6165
|
+
"cursor-pointer hover:shadow-sm transition-shadow text-xs truncate",
|
|
6166
|
+
event.color ? event.color : "bg-blue-500/15 border-blue-500/30 text-blue-600"
|
|
6167
|
+
),
|
|
6168
|
+
onClick: (e) => handleEventClick(event, e),
|
|
6169
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "truncate font-medium", children: event.title })
|
|
6170
|
+
},
|
|
6171
|
+
event.id
|
|
6172
|
+
);
|
|
6173
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("overflow-x-auto", className), children: /* @__PURE__ */ jsxs(Box, { className: "min-w-[800px]", children: [
|
|
6174
|
+
/* @__PURE__ */ jsxs(Box, { className: "grid grid-cols-8 border-b border-[var(--color-border)]", children: [
|
|
6175
|
+
/* @__PURE__ */ jsx(Box, { className: "p-2" }),
|
|
6176
|
+
weekDays.map((day) => {
|
|
6177
|
+
const isToday = day.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
6178
|
+
const count = eventsForDayCount(day);
|
|
6179
|
+
return /* @__PURE__ */ jsxs(
|
|
6180
|
+
Box,
|
|
6181
|
+
{
|
|
6182
|
+
className: "border-l border-[var(--color-border)]",
|
|
6183
|
+
children: [
|
|
6184
|
+
/* @__PURE__ */ jsx(
|
|
6185
|
+
DayCell,
|
|
6186
|
+
{
|
|
6187
|
+
date: day,
|
|
6188
|
+
isToday,
|
|
6189
|
+
onClick: onDayClick
|
|
6190
|
+
}
|
|
6191
|
+
),
|
|
6192
|
+
count > 0 && /* @__PURE__ */ jsx(Box, { className: "text-center pb-1", children: /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: count }) })
|
|
6193
|
+
]
|
|
6194
|
+
},
|
|
6195
|
+
day.toISOString()
|
|
6196
|
+
);
|
|
6197
|
+
})
|
|
6198
|
+
] }),
|
|
6199
|
+
/* @__PURE__ */ jsx(Box, { className: "max-h-[500px] overflow-y-auto", children: resolvedTimeSlots.map((time) => /* @__PURE__ */ jsxs(
|
|
6200
|
+
Box,
|
|
6201
|
+
{
|
|
6202
|
+
className: "grid grid-cols-8 border-b border-[var(--color-border)]",
|
|
6203
|
+
children: [
|
|
6204
|
+
/* @__PURE__ */ jsx(Box, { className: "p-2 text-right pr-3", children: /* @__PURE__ */ jsx(
|
|
6205
|
+
Typography,
|
|
6206
|
+
{
|
|
6207
|
+
variant: "small",
|
|
6208
|
+
className: "text-[var(--color-muted-foreground)]",
|
|
6209
|
+
children: time
|
|
6210
|
+
}
|
|
6211
|
+
) }),
|
|
6212
|
+
weekDays.map((day) => {
|
|
6213
|
+
const slotEvents = events.filter(
|
|
6214
|
+
(ev) => eventInSlot(ev, day, time)
|
|
6215
|
+
);
|
|
6216
|
+
const isToday = day.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
6217
|
+
return /* @__PURE__ */ jsx(
|
|
6218
|
+
TimeSlotCell,
|
|
6219
|
+
{
|
|
6220
|
+
time,
|
|
6221
|
+
isOccupied: slotEvents.length > 0,
|
|
6222
|
+
onClick: () => handleSlotClick(day, time),
|
|
6223
|
+
className: cn(
|
|
6224
|
+
"border-l border-[var(--color-border)]",
|
|
6225
|
+
isToday && "bg-blue-50/30"
|
|
6226
|
+
),
|
|
6227
|
+
children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: slotEvents.map(renderEvent) })
|
|
6228
|
+
},
|
|
6229
|
+
`${day.toISOString()}-${time}`
|
|
6230
|
+
);
|
|
6231
|
+
})
|
|
6232
|
+
]
|
|
6233
|
+
},
|
|
6234
|
+
time
|
|
6235
|
+
)) })
|
|
6236
|
+
] }) });
|
|
6237
|
+
}
|
|
6238
|
+
CalendarGrid.displayName = "CalendarGrid";
|
|
6052
6239
|
var RepeatableFormSection = ({
|
|
6053
6240
|
sectionType,
|
|
6054
6241
|
title,
|
|
@@ -6423,26 +6610,983 @@ var FormSectionHeader = ({
|
|
|
6423
6610
|
);
|
|
6424
6611
|
};
|
|
6425
6612
|
FormSectionHeader.displayName = "FormSectionHeader";
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6613
|
+
var FlipCard = ({
|
|
6614
|
+
front,
|
|
6615
|
+
back,
|
|
6616
|
+
flipped = false,
|
|
6617
|
+
onFlip,
|
|
6618
|
+
className,
|
|
6619
|
+
height = "h-64"
|
|
6620
|
+
}) => {
|
|
6621
|
+
return /* @__PURE__ */ jsxs(
|
|
6622
|
+
FlipContainer,
|
|
6623
|
+
{
|
|
6624
|
+
flipped,
|
|
6625
|
+
className: cn(height, className),
|
|
6626
|
+
onClick: onFlip,
|
|
6627
|
+
children: [
|
|
6628
|
+
/* @__PURE__ */ jsx(
|
|
6629
|
+
Box,
|
|
6630
|
+
{
|
|
6631
|
+
className: "absolute inset-0 w-full h-full rounded-lg shadow-lg flex items-center justify-center p-6",
|
|
6632
|
+
style: { backfaceVisibility: "hidden", transform: "rotateY(0deg)" },
|
|
6633
|
+
children: front
|
|
6634
|
+
}
|
|
6635
|
+
),
|
|
6636
|
+
/* @__PURE__ */ jsx(
|
|
6637
|
+
Box,
|
|
6638
|
+
{
|
|
6639
|
+
className: "absolute inset-0 w-full h-full rounded-lg shadow-lg flex items-center justify-center p-6",
|
|
6640
|
+
style: { backfaceVisibility: "hidden", transform: "rotateY(180deg)" },
|
|
6641
|
+
children: back
|
|
6642
|
+
}
|
|
6643
|
+
)
|
|
6644
|
+
]
|
|
6645
|
+
}
|
|
6646
|
+
);
|
|
6647
|
+
};
|
|
6648
|
+
FlipCard.displayName = "FlipCard";
|
|
6649
|
+
var DEFAULT_OPTIONS = [
|
|
6650
|
+
{ label: "1W", value: "week" },
|
|
6651
|
+
{ label: "1M", value: "month" },
|
|
6652
|
+
{ label: "3M", value: "3months" },
|
|
6653
|
+
{ label: "1Y", value: "year" }
|
|
6654
|
+
];
|
|
6655
|
+
var DateRangeSelector = ({
|
|
6656
|
+
options = DEFAULT_OPTIONS,
|
|
6657
|
+
selected = "month",
|
|
6658
|
+
onSelect,
|
|
6659
|
+
className
|
|
6660
|
+
}) => {
|
|
6661
|
+
return /* @__PURE__ */ jsx(HStack, { gap: "xs", className: cn(className), children: options.map((option) => /* @__PURE__ */ jsx(
|
|
6662
|
+
Button,
|
|
6663
|
+
{
|
|
6664
|
+
variant: selected === option.value ? "primary" : "ghost",
|
|
6665
|
+
size: "sm",
|
|
6666
|
+
onClick: () => onSelect?.(option.value),
|
|
6667
|
+
children: option.label
|
|
6668
|
+
},
|
|
6669
|
+
option.value
|
|
6670
|
+
)) });
|
|
6671
|
+
};
|
|
6672
|
+
DateRangeSelector.displayName = "DateRangeSelector";
|
|
6673
|
+
var ChartLegend = ({
|
|
6674
|
+
items,
|
|
6675
|
+
className,
|
|
6676
|
+
direction = "horizontal"
|
|
6677
|
+
}) => {
|
|
6678
|
+
const Wrapper = direction === "horizontal" ? HStack : VStack;
|
|
6679
|
+
return /* @__PURE__ */ jsx(Wrapper, { gap: "md", className: cn("flex-wrap", className), children: items.map((item) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
6680
|
+
/* @__PURE__ */ jsx(
|
|
6681
|
+
Box,
|
|
6682
|
+
{
|
|
6683
|
+
className: "rounded-full shrink-0",
|
|
6684
|
+
style: {
|
|
6685
|
+
width: 10,
|
|
6686
|
+
height: 10,
|
|
6687
|
+
backgroundColor: item.color
|
|
6688
|
+
}
|
|
6689
|
+
}
|
|
6690
|
+
),
|
|
6691
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-[var(--color-muted-foreground)]", children: item.label })
|
|
6692
|
+
] }, item.label)) });
|
|
6693
|
+
};
|
|
6694
|
+
ChartLegend.displayName = "ChartLegend";
|
|
6695
|
+
var LineChart = ({
|
|
6696
|
+
data,
|
|
6697
|
+
width = 400,
|
|
6698
|
+
height = 200,
|
|
6699
|
+
showGrid = true,
|
|
6700
|
+
showValues = false,
|
|
6701
|
+
showArea = true,
|
|
6702
|
+
lineColor = "var(--color-primary)",
|
|
6703
|
+
areaColor = "var(--color-primary)",
|
|
6704
|
+
className
|
|
6705
|
+
}) => {
|
|
6706
|
+
const gradientId = useId();
|
|
6707
|
+
const sortedData = useMemo(() => {
|
|
6708
|
+
return [...data].sort(
|
|
6709
|
+
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
|
|
6710
|
+
);
|
|
6711
|
+
}, [data]);
|
|
6712
|
+
const points = useMemo(() => {
|
|
6713
|
+
if (sortedData.length === 0) return [];
|
|
6714
|
+
const values = sortedData.map((d) => d.value);
|
|
6715
|
+
const minVal = Math.min(...values);
|
|
6716
|
+
const maxVal = Math.max(...values);
|
|
6717
|
+
const range = maxVal - minVal || 1;
|
|
6718
|
+
const padding = 20;
|
|
6719
|
+
const chartWidth = width - padding * 2;
|
|
6720
|
+
const chartHeight = height - padding * 2;
|
|
6721
|
+
return sortedData.map((point, index) => ({
|
|
6722
|
+
x: padding + index / (sortedData.length - 1 || 1) * chartWidth,
|
|
6723
|
+
y: padding + chartHeight - (point.value - minVal) / range * chartHeight,
|
|
6724
|
+
value: point.value,
|
|
6725
|
+
label: point.label
|
|
6726
|
+
}));
|
|
6727
|
+
}, [sortedData, width, height]);
|
|
6728
|
+
const linePath = useMemo(() => {
|
|
6729
|
+
if (points.length === 0) return "";
|
|
6730
|
+
return points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
|
|
6731
|
+
}, [points]);
|
|
6732
|
+
const areaPath = useMemo(() => {
|
|
6733
|
+
if (points.length === 0 || !showArea) return "";
|
|
6734
|
+
const bottom = height - 20;
|
|
6735
|
+
const first = points[0];
|
|
6736
|
+
const last = points[points.length - 1];
|
|
6737
|
+
return `${linePath} L ${last.x} ${bottom} L ${first.x} ${bottom} Z`;
|
|
6738
|
+
}, [linePath, points, height, showArea]);
|
|
6739
|
+
if (data.length === 0) {
|
|
6740
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center text-[var(--color-muted-foreground)]", className), style: { width, height }, children: "No data" });
|
|
6741
|
+
}
|
|
6742
|
+
return /* @__PURE__ */ jsx(Box, { className: cn(className), children: /* @__PURE__ */ jsxs(
|
|
6743
|
+
"svg",
|
|
6744
|
+
{
|
|
6745
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
6746
|
+
width: "100%",
|
|
6747
|
+
height: "100%",
|
|
6748
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
6749
|
+
children: [
|
|
6750
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
6751
|
+
/* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.3" }),
|
|
6752
|
+
/* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0" })
|
|
6753
|
+
] }) }),
|
|
6754
|
+
showGrid && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6755
|
+
/* @__PURE__ */ jsx("line", { x1: "20", y1: height * 0.25, x2: width - 20, y2: height * 0.25, stroke: "var(--color-border, #e5e7eb)", strokeWidth: "1" }),
|
|
6756
|
+
/* @__PURE__ */ jsx("line", { x1: "20", y1: height * 0.5, x2: width - 20, y2: height * 0.5, stroke: "var(--color-border, #e5e7eb)", strokeWidth: "1" }),
|
|
6757
|
+
/* @__PURE__ */ jsx("line", { x1: "20", y1: height * 0.75, x2: width - 20, y2: height * 0.75, stroke: "var(--color-border, #e5e7eb)", strokeWidth: "1" })
|
|
6758
|
+
] }),
|
|
6759
|
+
showArea && areaPath && /* @__PURE__ */ jsx("path", { d: areaPath, fill: `url(#${gradientId})` }),
|
|
6760
|
+
linePath && /* @__PURE__ */ jsx(
|
|
6761
|
+
"path",
|
|
6762
|
+
{
|
|
6763
|
+
d: linePath,
|
|
6764
|
+
fill: "none",
|
|
6765
|
+
stroke: lineColor,
|
|
6766
|
+
strokeWidth: "2",
|
|
6767
|
+
strokeLinejoin: "round",
|
|
6768
|
+
strokeLinecap: "round"
|
|
6769
|
+
}
|
|
6770
|
+
),
|
|
6771
|
+
points.map((point, index) => /* @__PURE__ */ jsx(
|
|
6772
|
+
"circle",
|
|
6773
|
+
{
|
|
6774
|
+
cx: point.x,
|
|
6775
|
+
cy: point.y,
|
|
6776
|
+
r: "4",
|
|
6777
|
+
fill: lineColor,
|
|
6778
|
+
stroke: "var(--color-background, white)",
|
|
6779
|
+
strokeWidth: "2"
|
|
6780
|
+
},
|
|
6781
|
+
index
|
|
6782
|
+
)),
|
|
6783
|
+
showValues && points.map((point, index) => /* @__PURE__ */ jsx(
|
|
6784
|
+
"text",
|
|
6785
|
+
{
|
|
6786
|
+
x: point.x,
|
|
6787
|
+
y: point.y - 10,
|
|
6788
|
+
textAnchor: "middle",
|
|
6789
|
+
fontSize: "11",
|
|
6790
|
+
fill: "var(--color-foreground, currentColor)",
|
|
6791
|
+
children: point.label ?? point.value
|
|
6792
|
+
},
|
|
6793
|
+
`label-${index}`
|
|
6794
|
+
))
|
|
6795
|
+
]
|
|
6796
|
+
}
|
|
6797
|
+
) });
|
|
6798
|
+
};
|
|
6799
|
+
LineChart.displayName = "LineChart";
|
|
6800
|
+
var sizeMap4 = {
|
|
6801
|
+
sm: { dot: 6, active: 8 },
|
|
6802
|
+
md: { dot: 8, active: 10 },
|
|
6803
|
+
lg: { dot: 10, active: 14 }
|
|
6804
|
+
};
|
|
6805
|
+
var stateColors = {
|
|
6806
|
+
active: "var(--color-primary)",
|
|
6807
|
+
complete: "var(--color-success, #22c55e)",
|
|
6808
|
+
pending: "var(--color-muted, #d4d4d8)"
|
|
6809
|
+
};
|
|
6810
|
+
var ProgressDots = ({
|
|
6811
|
+
count,
|
|
6812
|
+
currentIndex,
|
|
6813
|
+
getState,
|
|
6814
|
+
onDotClick,
|
|
6815
|
+
className,
|
|
6816
|
+
size = "md"
|
|
6817
|
+
}) => {
|
|
6818
|
+
const defaultGetState = useCallback(
|
|
6819
|
+
(index) => {
|
|
6820
|
+
if (index === currentIndex) return "active";
|
|
6821
|
+
return "pending";
|
|
6822
|
+
},
|
|
6823
|
+
[currentIndex]
|
|
6824
|
+
);
|
|
6825
|
+
const resolveState = getState ?? defaultGetState;
|
|
6826
|
+
const dims = sizeMap4[size];
|
|
6827
|
+
return /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", className: cn(className), children: Array.from({ length: count }, (_, index) => {
|
|
6828
|
+
const state = resolveState(index);
|
|
6829
|
+
const isActive = state === "active";
|
|
6830
|
+
const dotSize = isActive ? dims.active : dims.dot;
|
|
6831
|
+
return /* @__PURE__ */ jsx(
|
|
6832
|
+
Box,
|
|
6833
|
+
{
|
|
6834
|
+
className: cn(
|
|
6835
|
+
"rounded-full transition-all duration-200",
|
|
6836
|
+
onDotClick && "cursor-pointer"
|
|
6837
|
+
),
|
|
6838
|
+
style: {
|
|
6839
|
+
width: dotSize,
|
|
6840
|
+
height: dotSize,
|
|
6841
|
+
backgroundColor: stateColors[state],
|
|
6842
|
+
transform: isActive ? "scale(1.2)" : "scale(1)"
|
|
6843
|
+
},
|
|
6844
|
+
onClick: onDotClick ? () => onDotClick(index) : void 0
|
|
6845
|
+
},
|
|
6846
|
+
index
|
|
6847
|
+
);
|
|
6848
|
+
}) });
|
|
6849
|
+
};
|
|
6850
|
+
ProgressDots.displayName = "ProgressDots";
|
|
6851
|
+
var GROUP_COLORS = [
|
|
6852
|
+
"#3b82f6",
|
|
6853
|
+
// blue-500
|
|
6854
|
+
"#10b981",
|
|
6855
|
+
// emerald-500
|
|
6856
|
+
"#f59e0b",
|
|
6857
|
+
// amber-500
|
|
6858
|
+
"#ef4444",
|
|
6859
|
+
// red-500
|
|
6860
|
+
"#8b5cf6",
|
|
6861
|
+
// violet-500
|
|
6862
|
+
"#ec4899",
|
|
6863
|
+
// pink-500
|
|
6864
|
+
"#06b6d4",
|
|
6865
|
+
// cyan-500
|
|
6866
|
+
"#84cc16"
|
|
6867
|
+
// lime-500
|
|
6868
|
+
];
|
|
6869
|
+
var DEFAULT_NODE_COLOR = "#3b82f6";
|
|
6870
|
+
var DEFAULT_EDGE_COLOR = "#9ca3af";
|
|
6871
|
+
var DEFAULT_NODE_SIZE = 8;
|
|
6872
|
+
function resolveNodeColor(node, groups) {
|
|
6873
|
+
if (node.color) return node.color;
|
|
6874
|
+
if (node.group) {
|
|
6875
|
+
const idx = groups.indexOf(node.group);
|
|
6876
|
+
return GROUP_COLORS[idx % GROUP_COLORS.length];
|
|
6877
|
+
}
|
|
6878
|
+
return DEFAULT_NODE_COLOR;
|
|
6879
|
+
}
|
|
6880
|
+
var GraphView = ({
|
|
6881
|
+
nodes,
|
|
6882
|
+
edges,
|
|
6883
|
+
onNodeClick,
|
|
6884
|
+
onNodeHover,
|
|
6885
|
+
width: propWidth,
|
|
6886
|
+
height: propHeight,
|
|
6887
|
+
className,
|
|
6888
|
+
showLabels = true,
|
|
6889
|
+
zoomToFit = true
|
|
6890
|
+
}) => {
|
|
6891
|
+
const containerRef = useRef(null);
|
|
6892
|
+
const animRef = useRef(0);
|
|
6893
|
+
const [simNodes, setSimNodes] = useState([]);
|
|
6894
|
+
const [settled, setSettled] = useState(false);
|
|
6895
|
+
const [hoveredId, setHoveredId] = useState(null);
|
|
6896
|
+
const [dimensions, setDimensions] = useState({ width: propWidth ?? 600, height: propHeight ?? 400 });
|
|
6897
|
+
const w = propWidth ?? dimensions.width;
|
|
6898
|
+
const h = propHeight ?? dimensions.height;
|
|
6899
|
+
const groups = useMemo(
|
|
6900
|
+
() => [...new Set(nodes.map((n) => n.group).filter((g) => Boolean(g)))],
|
|
6901
|
+
[nodes]
|
|
6902
|
+
);
|
|
6903
|
+
const connectedIds = useMemo(() => {
|
|
6904
|
+
if (!hoveredId) return /* @__PURE__ */ new Set();
|
|
6905
|
+
const connected = /* @__PURE__ */ new Set([hoveredId]);
|
|
6906
|
+
for (const edge of edges) {
|
|
6907
|
+
if (edge.source === hoveredId) connected.add(edge.target);
|
|
6908
|
+
if (edge.target === hoveredId) connected.add(edge.source);
|
|
6909
|
+
}
|
|
6910
|
+
return connected;
|
|
6911
|
+
}, [hoveredId, edges]);
|
|
6912
|
+
useEffect(() => {
|
|
6913
|
+
if (propWidth && propHeight) return;
|
|
6914
|
+
const el = containerRef.current;
|
|
6915
|
+
if (!el) return;
|
|
6916
|
+
const update = () => {
|
|
6917
|
+
setDimensions({
|
|
6918
|
+
width: el.clientWidth || 600,
|
|
6919
|
+
height: el.clientHeight || 400
|
|
6920
|
+
});
|
|
6921
|
+
};
|
|
6922
|
+
update();
|
|
6923
|
+
window.addEventListener("resize", update);
|
|
6924
|
+
return () => window.removeEventListener("resize", update);
|
|
6925
|
+
}, [propWidth, propHeight]);
|
|
6926
|
+
useEffect(() => {
|
|
6927
|
+
if (nodes.length === 0) {
|
|
6928
|
+
setSimNodes([]);
|
|
6929
|
+
setSettled(true);
|
|
6930
|
+
return;
|
|
6931
|
+
}
|
|
6932
|
+
const initialNodes = nodes.map((n, idx) => {
|
|
6933
|
+
const angle = idx / nodes.length * 2 * Math.PI;
|
|
6934
|
+
const radius = Math.min(w, h) * 0.3;
|
|
6935
|
+
return {
|
|
6936
|
+
id: n.id,
|
|
6937
|
+
label: n.label,
|
|
6938
|
+
color: resolveNodeColor(n, groups),
|
|
6939
|
+
size: n.size ?? DEFAULT_NODE_SIZE,
|
|
6940
|
+
group: n.group,
|
|
6941
|
+
x: w / 2 + radius * Math.cos(angle) + (Math.random() - 0.5) * 20,
|
|
6942
|
+
y: h / 2 + radius * Math.sin(angle) + (Math.random() - 0.5) * 20,
|
|
6943
|
+
vx: 0,
|
|
6944
|
+
vy: 0,
|
|
6945
|
+
fx: 0,
|
|
6946
|
+
fy: 0
|
|
6947
|
+
};
|
|
6948
|
+
});
|
|
6949
|
+
let iterations = 0;
|
|
6950
|
+
const maxIterations = 120;
|
|
6951
|
+
let currentNodes = initialNodes;
|
|
6952
|
+
const tick = () => {
|
|
6953
|
+
const centerX = w / 2;
|
|
6954
|
+
const centerY = h / 2;
|
|
6955
|
+
for (const node of currentNodes) {
|
|
6956
|
+
node.fx = 0;
|
|
6957
|
+
node.fy = 0;
|
|
6958
|
+
}
|
|
6959
|
+
for (let i = 0; i < currentNodes.length; i++) {
|
|
6960
|
+
for (let j = i + 1; j < currentNodes.length; j++) {
|
|
6961
|
+
const a = currentNodes[i];
|
|
6962
|
+
const b = currentNodes[j];
|
|
6963
|
+
const dx = b.x - a.x;
|
|
6964
|
+
const dy = b.y - a.y;
|
|
6965
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
6966
|
+
const force = 800 / (dist * dist);
|
|
6967
|
+
const fx = dx / dist * force;
|
|
6968
|
+
const fy = dy / dist * force;
|
|
6969
|
+
a.fx -= fx;
|
|
6970
|
+
a.fy -= fy;
|
|
6971
|
+
b.fx += fx;
|
|
6972
|
+
b.fy += fy;
|
|
6973
|
+
}
|
|
6974
|
+
}
|
|
6975
|
+
for (const edge of edges) {
|
|
6976
|
+
const source = currentNodes.find((n) => n.id === edge.source);
|
|
6977
|
+
const target = currentNodes.find((n) => n.id === edge.target);
|
|
6978
|
+
if (!source || !target) continue;
|
|
6979
|
+
const dx = target.x - source.x;
|
|
6980
|
+
const dy = target.y - source.y;
|
|
6981
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
6982
|
+
const force = (dist - 100) * 0.05;
|
|
6983
|
+
const fx = dx / dist * force;
|
|
6984
|
+
const fy = dy / dist * force;
|
|
6985
|
+
source.fx += fx;
|
|
6986
|
+
source.fy += fy;
|
|
6987
|
+
target.fx -= fx;
|
|
6988
|
+
target.fy -= fy;
|
|
6989
|
+
}
|
|
6990
|
+
for (const node of currentNodes) {
|
|
6991
|
+
node.fx += (centerX - node.x) * 0.01;
|
|
6992
|
+
node.fy += (centerY - node.y) * 0.01;
|
|
6993
|
+
}
|
|
6994
|
+
const damping = 0.85;
|
|
6995
|
+
const margin = 40;
|
|
6996
|
+
for (const node of currentNodes) {
|
|
6997
|
+
node.vx = (node.vx + node.fx) * damping;
|
|
6998
|
+
node.vy = (node.vy + node.fy) * damping;
|
|
6999
|
+
node.x += node.vx;
|
|
7000
|
+
node.y += node.vy;
|
|
7001
|
+
node.x = Math.max(margin, Math.min(w - margin, node.x));
|
|
7002
|
+
node.y = Math.max(margin, Math.min(h - margin, node.y));
|
|
7003
|
+
}
|
|
7004
|
+
iterations++;
|
|
7005
|
+
setSimNodes([...currentNodes]);
|
|
7006
|
+
if (iterations < maxIterations) {
|
|
7007
|
+
animRef.current = requestAnimationFrame(tick);
|
|
7008
|
+
} else {
|
|
7009
|
+
setSettled(true);
|
|
7010
|
+
}
|
|
7011
|
+
};
|
|
7012
|
+
setSettled(false);
|
|
7013
|
+
animRef.current = requestAnimationFrame(tick);
|
|
7014
|
+
return () => {
|
|
7015
|
+
cancelAnimationFrame(animRef.current);
|
|
7016
|
+
};
|
|
7017
|
+
}, [nodes, edges, w, h, groups]);
|
|
7018
|
+
const viewBox = useMemo(() => {
|
|
7019
|
+
if (!zoomToFit || !settled || simNodes.length === 0) {
|
|
7020
|
+
return `0 0 ${w} ${h}`;
|
|
7021
|
+
}
|
|
7022
|
+
const pad = 60;
|
|
7023
|
+
let minX = Infinity;
|
|
7024
|
+
let minY = Infinity;
|
|
7025
|
+
let maxX = -Infinity;
|
|
7026
|
+
let maxY = -Infinity;
|
|
7027
|
+
for (const node of simNodes) {
|
|
7028
|
+
minX = Math.min(minX, node.x - node.size);
|
|
7029
|
+
minY = Math.min(minY, node.y - node.size);
|
|
7030
|
+
maxX = Math.max(maxX, node.x + node.size);
|
|
7031
|
+
maxY = Math.max(maxY, node.y + node.size);
|
|
7032
|
+
}
|
|
7033
|
+
const fitW = maxX - minX + pad * 2;
|
|
7034
|
+
const fitH = maxY - minY + pad * 2;
|
|
7035
|
+
return `${minX - pad} ${minY - pad} ${fitW} ${fitH}`;
|
|
7036
|
+
}, [zoomToFit, settled, simNodes, w, h]);
|
|
7037
|
+
const nodeMap = useMemo(() => {
|
|
7038
|
+
const map = /* @__PURE__ */ new Map();
|
|
7039
|
+
for (const n of simNodes) {
|
|
7040
|
+
map.set(n.id, n);
|
|
7041
|
+
}
|
|
7042
|
+
return map;
|
|
7043
|
+
}, [simNodes]);
|
|
7044
|
+
const handleNodeMouseEnter = useCallback(
|
|
7045
|
+
(node) => {
|
|
7046
|
+
setHoveredId(node.id);
|
|
7047
|
+
if (onNodeHover) {
|
|
7048
|
+
onNodeHover({ id: node.id, label: node.label, color: node.color, size: node.size, group: node.group });
|
|
7049
|
+
}
|
|
7050
|
+
},
|
|
7051
|
+
[onNodeHover]
|
|
7052
|
+
);
|
|
7053
|
+
const handleNodeMouseLeave = useCallback(() => {
|
|
7054
|
+
setHoveredId(null);
|
|
7055
|
+
if (onNodeHover) {
|
|
7056
|
+
onNodeHover(null);
|
|
7057
|
+
}
|
|
7058
|
+
}, [onNodeHover]);
|
|
7059
|
+
const handleNodeClickInternal = useCallback(
|
|
7060
|
+
(node) => {
|
|
7061
|
+
if (onNodeClick) {
|
|
7062
|
+
onNodeClick({ id: node.id, label: node.label, color: node.color, size: node.size, group: node.group });
|
|
7063
|
+
}
|
|
7064
|
+
},
|
|
7065
|
+
[onNodeClick]
|
|
7066
|
+
);
|
|
7067
|
+
if (nodes.length === 0) {
|
|
7068
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center", className), style: { width: w, height: h }, children: /* @__PURE__ */ jsx(Box, { className: "text-[var(--color-muted-foreground)] text-sm", children: "No graph data" }) });
|
|
7069
|
+
}
|
|
7070
|
+
return /* @__PURE__ */ jsx(
|
|
7071
|
+
Box,
|
|
7072
|
+
{
|
|
7073
|
+
ref: containerRef,
|
|
7074
|
+
className: cn("relative overflow-hidden rounded-lg border border-[var(--color-border)] bg-[var(--color-card)]", className),
|
|
7075
|
+
style: { width: propWidth ?? "100%", height: h },
|
|
7076
|
+
children: /* @__PURE__ */ jsxs(
|
|
7077
|
+
"svg",
|
|
7078
|
+
{
|
|
7079
|
+
width: "100%",
|
|
7080
|
+
height: "100%",
|
|
7081
|
+
viewBox,
|
|
7082
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
7083
|
+
children: [
|
|
7084
|
+
edges.map((edge, idx) => {
|
|
7085
|
+
const source = nodeMap.get(edge.source);
|
|
7086
|
+
const target = nodeMap.get(edge.target);
|
|
7087
|
+
if (!source || !target) return null;
|
|
7088
|
+
const isHighlighted = hoveredId ? connectedIds.has(edge.source) && connectedIds.has(edge.target) : true;
|
|
7089
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
7090
|
+
/* @__PURE__ */ jsx(
|
|
7091
|
+
"line",
|
|
7092
|
+
{
|
|
7093
|
+
x1: source.x,
|
|
7094
|
+
y1: source.y,
|
|
7095
|
+
x2: target.x,
|
|
7096
|
+
y2: target.y,
|
|
7097
|
+
stroke: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
7098
|
+
strokeWidth: 1.5,
|
|
7099
|
+
opacity: isHighlighted ? 0.8 : 0.15
|
|
7100
|
+
}
|
|
7101
|
+
),
|
|
7102
|
+
showLabels && edge.label && /* @__PURE__ */ jsx(
|
|
7103
|
+
"text",
|
|
7104
|
+
{
|
|
7105
|
+
x: (source.x + target.x) / 2,
|
|
7106
|
+
y: (source.y + target.y) / 2 - 6,
|
|
7107
|
+
textAnchor: "middle",
|
|
7108
|
+
fill: "var(--color-muted-foreground)",
|
|
7109
|
+
fontSize: 9,
|
|
7110
|
+
opacity: isHighlighted ? 0.9 : 0.2,
|
|
7111
|
+
children: edge.label
|
|
7112
|
+
}
|
|
7113
|
+
)
|
|
7114
|
+
] }, `edge-${idx}`);
|
|
7115
|
+
}),
|
|
7116
|
+
simNodes.map((node) => {
|
|
7117
|
+
const isHighlighted = hoveredId ? connectedIds.has(node.id) : true;
|
|
7118
|
+
const isHovered = hoveredId === node.id;
|
|
7119
|
+
return /* @__PURE__ */ jsxs(
|
|
7120
|
+
"g",
|
|
7121
|
+
{
|
|
7122
|
+
style: { cursor: onNodeClick ? "pointer" : "default" },
|
|
7123
|
+
onMouseEnter: () => handleNodeMouseEnter(node),
|
|
7124
|
+
onMouseLeave: handleNodeMouseLeave,
|
|
7125
|
+
onClick: () => handleNodeClickInternal(node),
|
|
7126
|
+
children: [
|
|
7127
|
+
/* @__PURE__ */ jsx(
|
|
7128
|
+
"circle",
|
|
7129
|
+
{
|
|
7130
|
+
cx: node.x,
|
|
7131
|
+
cy: node.y,
|
|
7132
|
+
r: isHovered ? node.size * 1.4 : node.size,
|
|
7133
|
+
fill: node.color,
|
|
7134
|
+
opacity: isHighlighted ? 1 : 0.3,
|
|
7135
|
+
stroke: isHovered ? "#ffffff" : "none",
|
|
7136
|
+
strokeWidth: isHovered ? 2 : 0
|
|
7137
|
+
}
|
|
7138
|
+
),
|
|
7139
|
+
showLabels && /* @__PURE__ */ jsx(
|
|
7140
|
+
"text",
|
|
7141
|
+
{
|
|
7142
|
+
x: node.x,
|
|
7143
|
+
y: node.y + node.size + 12,
|
|
7144
|
+
textAnchor: "middle",
|
|
7145
|
+
fill: "var(--color-foreground)",
|
|
7146
|
+
fontSize: 11,
|
|
7147
|
+
fontWeight: isHovered ? "bold" : "normal",
|
|
7148
|
+
opacity: isHighlighted ? 0.9 : 0.2,
|
|
7149
|
+
children: node.label ?? node.id
|
|
7150
|
+
}
|
|
7151
|
+
)
|
|
7152
|
+
]
|
|
7153
|
+
},
|
|
7154
|
+
node.id
|
|
7155
|
+
);
|
|
7156
|
+
})
|
|
7157
|
+
]
|
|
7158
|
+
}
|
|
7159
|
+
)
|
|
7160
|
+
}
|
|
7161
|
+
);
|
|
7162
|
+
};
|
|
7163
|
+
GraphView.displayName = "GraphView";
|
|
7164
|
+
function fieldLabel(key) {
|
|
7165
|
+
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
7166
|
+
}
|
|
7167
|
+
function statusVariant(value) {
|
|
7168
|
+
const v = value.toLowerCase();
|
|
7169
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online"].includes(v)) return "success";
|
|
7170
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warning"].includes(v)) return "warning";
|
|
7171
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
7172
|
+
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
7173
|
+
return "default";
|
|
7174
|
+
}
|
|
7175
|
+
function formatDate(value) {
|
|
7176
|
+
if (!value) return "";
|
|
7177
|
+
const d = new Date(String(value));
|
|
7178
|
+
if (isNaN(d.getTime())) return String(value);
|
|
7179
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
7180
|
+
}
|
|
7181
|
+
function formatValue(value, format) {
|
|
7182
|
+
if (value === void 0 || value === null) return "";
|
|
7183
|
+
switch (format) {
|
|
7184
|
+
case "date":
|
|
7185
|
+
return formatDate(value);
|
|
7186
|
+
case "currency":
|
|
7187
|
+
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
7188
|
+
case "number":
|
|
7189
|
+
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
7190
|
+
case "percent":
|
|
7191
|
+
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
7192
|
+
case "boolean":
|
|
7193
|
+
return value ? "Yes" : "No";
|
|
7194
|
+
default:
|
|
7195
|
+
return String(value);
|
|
7196
|
+
}
|
|
7197
|
+
}
|
|
7198
|
+
var gapStyles5 = {
|
|
7199
|
+
none: "gap-0",
|
|
7200
|
+
sm: "gap-2",
|
|
7201
|
+
md: "gap-4",
|
|
7202
|
+
lg: "gap-6",
|
|
7203
|
+
xl: "gap-8"
|
|
7204
|
+
};
|
|
7205
|
+
var DataGrid = ({
|
|
7206
|
+
entity,
|
|
7207
|
+
fields: fieldsProp,
|
|
7208
|
+
columns: columnsProp,
|
|
7209
|
+
itemActions,
|
|
7210
|
+
cols,
|
|
7211
|
+
gap = "md",
|
|
7212
|
+
minCardWidth = 280,
|
|
7213
|
+
className,
|
|
7214
|
+
isLoading = false,
|
|
7215
|
+
error = null,
|
|
7216
|
+
imageField
|
|
7217
|
+
}) => {
|
|
7218
|
+
const eventBus = useEventBus();
|
|
7219
|
+
const { t } = useTranslate();
|
|
7220
|
+
const fields = fieldsProp ?? columnsProp ?? [];
|
|
7221
|
+
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
7222
|
+
const titleField = fields.find((f) => f.variant === "h3" || f.variant === "h4") ?? fields[0];
|
|
7223
|
+
const badgeFields = fields.filter((f) => f.variant === "badge" && f !== titleField);
|
|
7224
|
+
const bodyFields = fields.filter((f) => f !== titleField && !badgeFields.includes(f));
|
|
7225
|
+
const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
|
|
7226
|
+
const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
|
|
7227
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
7228
|
+
e.stopPropagation();
|
|
7229
|
+
eventBus.emit(`UI:${action.event}`, { row: itemData });
|
|
7230
|
+
};
|
|
7231
|
+
const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
|
|
7232
|
+
const colsClass = cols ? {
|
|
7233
|
+
1: "grid-cols-1",
|
|
7234
|
+
2: "sm:grid-cols-2",
|
|
7235
|
+
3: "sm:grid-cols-2 lg:grid-cols-3",
|
|
7236
|
+
4: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
|
|
7237
|
+
5: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5",
|
|
7238
|
+
6: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6"
|
|
7239
|
+
}[cols] : void 0;
|
|
7240
|
+
if (isLoading) {
|
|
7241
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
7242
|
+
}
|
|
7243
|
+
if (error) {
|
|
7244
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
7245
|
+
}
|
|
7246
|
+
if (data.length === 0) {
|
|
7247
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
7248
|
+
}
|
|
7249
|
+
return /* @__PURE__ */ jsx(
|
|
7250
|
+
Box,
|
|
7251
|
+
{
|
|
7252
|
+
className: cn("grid", gapStyles5[gap], colsClass, className),
|
|
7253
|
+
style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
|
|
7254
|
+
children: data.map((item, index) => {
|
|
7255
|
+
const itemData = item;
|
|
7256
|
+
const id = itemData.id || String(index);
|
|
7257
|
+
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
7258
|
+
return /* @__PURE__ */ jsxs(
|
|
7259
|
+
Box,
|
|
7260
|
+
{
|
|
7261
|
+
"data-entity-row": true,
|
|
7262
|
+
className: cn(
|
|
7263
|
+
"bg-[var(--color-card)] rounded-[var(--radius-lg)]",
|
|
7264
|
+
"border border-[var(--color-border)]",
|
|
7265
|
+
"shadow-[var(--shadow-sm)] hover:shadow-[var(--shadow-hover)]",
|
|
7266
|
+
"hover:border-[var(--color-primary)] transition-all",
|
|
7267
|
+
"flex flex-col"
|
|
7268
|
+
),
|
|
7269
|
+
children: [
|
|
7270
|
+
imageField && (() => {
|
|
7271
|
+
const imgUrl = getNestedValue(itemData, imageField);
|
|
7272
|
+
if (!imgUrl || typeof imgUrl !== "string") return null;
|
|
7273
|
+
return /* @__PURE__ */ jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-[var(--radius-lg)]", children: /* @__PURE__ */ jsx(
|
|
7274
|
+
"img",
|
|
7275
|
+
{
|
|
7276
|
+
src: imgUrl,
|
|
7277
|
+
alt: titleValue !== void 0 ? String(titleValue) : "",
|
|
7278
|
+
className: "w-full h-full object-cover",
|
|
7279
|
+
loading: "lazy"
|
|
7280
|
+
}
|
|
7281
|
+
) });
|
|
7282
|
+
})(),
|
|
7283
|
+
/* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
7284
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
|
|
7285
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7286
|
+
titleField?.icon && /* @__PURE__ */ jsx(Icon, { name: titleField.icon, size: "sm", className: "text-[var(--color-primary)] flex-shrink-0" }),
|
|
7287
|
+
/* @__PURE__ */ jsx(
|
|
7288
|
+
Typography,
|
|
7289
|
+
{
|
|
7290
|
+
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
7291
|
+
className: "font-semibold truncate",
|
|
7292
|
+
children: String(titleValue)
|
|
7293
|
+
}
|
|
7294
|
+
)
|
|
7295
|
+
] }),
|
|
7296
|
+
badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
7297
|
+
const val = getNestedValue(itemData, field.name);
|
|
7298
|
+
if (val === void 0 || val === null) return null;
|
|
7299
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7300
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
|
|
7301
|
+
/* @__PURE__ */ jsx(Badge, { variant: statusVariant(String(val)), children: String(val) })
|
|
7302
|
+
] }, field.name);
|
|
7303
|
+
}) })
|
|
7304
|
+
] }),
|
|
7305
|
+
dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
7306
|
+
Button,
|
|
7307
|
+
{
|
|
7308
|
+
variant: "ghost",
|
|
7309
|
+
size: "sm",
|
|
7310
|
+
onClick: handleActionClick(action, itemData),
|
|
7311
|
+
"data-testid": `action-${action.event}`,
|
|
7312
|
+
className: "text-[var(--color-error)] hover:bg-[var(--color-error)]/10 px-2",
|
|
7313
|
+
children: [
|
|
7314
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs" }),
|
|
7315
|
+
action.label
|
|
7316
|
+
]
|
|
7317
|
+
},
|
|
7318
|
+
idx
|
|
7319
|
+
)) })
|
|
7320
|
+
] }) }),
|
|
7321
|
+
bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
|
|
7322
|
+
const value = getNestedValue(itemData, field.name);
|
|
7323
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
7324
|
+
if (field.format === "boolean") {
|
|
7325
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
7326
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7327
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-[var(--color-muted-foreground)]" }),
|
|
7328
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel(field.name) })
|
|
7329
|
+
] }),
|
|
7330
|
+
/* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
|
|
7331
|
+
] }, field.name);
|
|
7332
|
+
}
|
|
7333
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
7334
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7335
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-[var(--color-muted-foreground)]" }),
|
|
7336
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel(field.name) })
|
|
7337
|
+
] }),
|
|
7338
|
+
/* @__PURE__ */ jsx(
|
|
7339
|
+
Typography,
|
|
7340
|
+
{
|
|
7341
|
+
variant: field.variant === "caption" ? "caption" : "small",
|
|
7342
|
+
className: "text-right truncate max-w-[60%]",
|
|
7343
|
+
children: formatValue(value, field.format)
|
|
7344
|
+
}
|
|
7345
|
+
)
|
|
7346
|
+
] }, field.name);
|
|
7347
|
+
}) }) }),
|
|
7348
|
+
primaryActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 mt-auto border-t border-[var(--color-border)]", children: /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
7349
|
+
Button,
|
|
7350
|
+
{
|
|
7351
|
+
variant: action.variant === "primary" ? "primary" : "ghost",
|
|
7352
|
+
size: "sm",
|
|
7353
|
+
onClick: handleActionClick(action, itemData),
|
|
7354
|
+
"data-testid": `action-${action.event}`,
|
|
7355
|
+
children: [
|
|
7356
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
7357
|
+
action.label
|
|
7358
|
+
]
|
|
7359
|
+
},
|
|
7360
|
+
idx
|
|
7361
|
+
)) }) })
|
|
7362
|
+
]
|
|
7363
|
+
},
|
|
7364
|
+
id
|
|
7365
|
+
);
|
|
7366
|
+
})
|
|
7367
|
+
}
|
|
7368
|
+
);
|
|
7369
|
+
};
|
|
7370
|
+
DataGrid.displayName = "DataGrid";
|
|
7371
|
+
function fieldLabel2(key) {
|
|
7372
|
+
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
7373
|
+
}
|
|
7374
|
+
function statusVariant2(value) {
|
|
7375
|
+
const v = value.toLowerCase();
|
|
7376
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online"].includes(v)) return "success";
|
|
7377
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warning"].includes(v)) return "warning";
|
|
7378
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
7379
|
+
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
7380
|
+
return "default";
|
|
7381
|
+
}
|
|
7382
|
+
function formatDate2(value) {
|
|
7383
|
+
if (!value) return "";
|
|
7384
|
+
const d = new Date(String(value));
|
|
7385
|
+
if (isNaN(d.getTime())) return String(value);
|
|
7386
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
7387
|
+
}
|
|
7388
|
+
function formatValue2(value, format) {
|
|
7389
|
+
if (value === void 0 || value === null) return "";
|
|
7390
|
+
switch (format) {
|
|
7391
|
+
case "date":
|
|
7392
|
+
return formatDate2(value);
|
|
7393
|
+
case "currency":
|
|
7394
|
+
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
7395
|
+
case "number":
|
|
7396
|
+
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
7397
|
+
case "percent":
|
|
7398
|
+
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
7399
|
+
case "boolean":
|
|
7400
|
+
return value ? "Yes" : "No";
|
|
7401
|
+
default:
|
|
7402
|
+
return String(value);
|
|
7403
|
+
}
|
|
7404
|
+
}
|
|
7405
|
+
var DataList = ({
|
|
7406
|
+
entity,
|
|
7407
|
+
fields: fieldsProp,
|
|
7408
|
+
columns: columnsProp,
|
|
7409
|
+
itemActions,
|
|
7410
|
+
gap = "none",
|
|
7411
|
+
variant = "default",
|
|
7412
|
+
className,
|
|
7413
|
+
isLoading = false,
|
|
7414
|
+
error = null
|
|
7415
|
+
}) => {
|
|
7416
|
+
const eventBus = useEventBus();
|
|
7417
|
+
const { t } = useTranslate();
|
|
7418
|
+
const fields = fieldsProp ?? columnsProp ?? [];
|
|
7419
|
+
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
7420
|
+
const titleField = fields.find((f) => f.variant === "h3" || f.variant === "h4") ?? fields[0];
|
|
7421
|
+
const badgeFields = fields.filter((f) => f.variant === "badge" && f !== titleField);
|
|
7422
|
+
const progressFields = fields.filter((f) => f.variant === "progress");
|
|
7423
|
+
const bodyFields = fields.filter(
|
|
7424
|
+
(f) => f !== titleField && !badgeFields.includes(f) && !progressFields.includes(f)
|
|
7425
|
+
);
|
|
7426
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
7427
|
+
e.stopPropagation();
|
|
7428
|
+
eventBus.emit(`UI:${action.event}`, { row: itemData });
|
|
7429
|
+
};
|
|
7430
|
+
if (isLoading) {
|
|
7431
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
7432
|
+
}
|
|
7433
|
+
if (error) {
|
|
7434
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
7435
|
+
}
|
|
7436
|
+
if (data.length === 0) {
|
|
7437
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
7438
|
+
}
|
|
7439
|
+
const gapClass = {
|
|
7440
|
+
none: "",
|
|
7441
|
+
sm: "gap-1",
|
|
7442
|
+
md: "gap-2",
|
|
7443
|
+
lg: "gap-4"
|
|
7444
|
+
}[gap];
|
|
7445
|
+
const isCard = variant === "card";
|
|
7446
|
+
const isCompact = variant === "compact";
|
|
7447
|
+
return /* @__PURE__ */ jsx(
|
|
7448
|
+
Box,
|
|
7449
|
+
{
|
|
7450
|
+
className: cn(
|
|
7451
|
+
isCard && "bg-[var(--color-card)] rounded-[var(--radius-xl)] border border-[var(--color-border)] shadow-[var(--shadow-lg)] overflow-hidden",
|
|
7452
|
+
!isCard && gapClass,
|
|
7453
|
+
className
|
|
7454
|
+
),
|
|
7455
|
+
children: data.map((item, index) => {
|
|
7456
|
+
const itemData = item;
|
|
7457
|
+
const id = itemData.id || String(index);
|
|
7458
|
+
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
7459
|
+
const isLast = index === data.length - 1;
|
|
7460
|
+
return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, children: [
|
|
7461
|
+
/* @__PURE__ */ jsxs(
|
|
7462
|
+
Box,
|
|
7463
|
+
{
|
|
7464
|
+
className: cn(
|
|
7465
|
+
"group flex items-center gap-4 transition-all duration-200",
|
|
7466
|
+
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
7467
|
+
"hover:bg-[var(--color-muted)]/80",
|
|
7468
|
+
!isCard && !isCompact && "rounded-[var(--radius-lg)] border border-transparent hover:border-[var(--color-border)]"
|
|
7469
|
+
),
|
|
7470
|
+
children: [
|
|
7471
|
+
/* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
|
|
7472
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "items-center", children: [
|
|
7473
|
+
titleField?.icon && /* @__PURE__ */ jsx(
|
|
7474
|
+
Icon,
|
|
7475
|
+
{
|
|
7476
|
+
name: titleField.icon,
|
|
7477
|
+
size: isCompact ? "xs" : "sm",
|
|
7478
|
+
className: "text-[var(--color-primary)] flex-shrink-0"
|
|
7479
|
+
}
|
|
7480
|
+
),
|
|
7481
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsx(
|
|
7482
|
+
Typography,
|
|
7483
|
+
{
|
|
7484
|
+
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
7485
|
+
className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
|
|
7486
|
+
children: String(titleValue)
|
|
7487
|
+
}
|
|
7488
|
+
),
|
|
7489
|
+
badgeFields.map((field) => {
|
|
7490
|
+
const val = getNestedValue(itemData, field.name);
|
|
7491
|
+
if (val === void 0 || val === null) return null;
|
|
7492
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
7493
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
|
|
7494
|
+
/* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
|
|
7495
|
+
] }, field.name);
|
|
7496
|
+
})
|
|
7497
|
+
] }),
|
|
7498
|
+
bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
|
|
7499
|
+
const value = getNestedValue(itemData, field.name);
|
|
7500
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
7501
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7502
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-[var(--color-muted-foreground)]" }),
|
|
7503
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "secondary", children: [
|
|
7504
|
+
field.label ?? fieldLabel2(field.name),
|
|
7505
|
+
":"
|
|
7506
|
+
] }),
|
|
7507
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue2(value, field.format) })
|
|
7508
|
+
] }, field.name);
|
|
7509
|
+
}) }),
|
|
7510
|
+
progressFields.map((field) => {
|
|
7511
|
+
const value = getNestedValue(itemData, field.name);
|
|
7512
|
+
if (typeof value !== "number") return null;
|
|
7513
|
+
return /* @__PURE__ */ jsxs(Box, { className: "mt-2 max-w-xs", children: [
|
|
7514
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center mb-1", children: [
|
|
7515
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-[var(--color-muted-foreground)]" }),
|
|
7516
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
7517
|
+
] }),
|
|
7518
|
+
/* @__PURE__ */ jsx(ProgressBar, { value, max: 100 })
|
|
7519
|
+
] }, field.name);
|
|
7520
|
+
})
|
|
7521
|
+
] }),
|
|
7522
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(
|
|
7523
|
+
HStack,
|
|
7524
|
+
{
|
|
7525
|
+
gap: "xs",
|
|
7526
|
+
className: cn(
|
|
7527
|
+
"flex-shrink-0 transition-opacity duration-200",
|
|
7528
|
+
"opacity-0 group-hover:opacity-100"
|
|
7529
|
+
),
|
|
7530
|
+
children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
7531
|
+
Button,
|
|
7532
|
+
{
|
|
7533
|
+
variant: action.variant ?? "ghost",
|
|
7534
|
+
size: "sm",
|
|
7535
|
+
onClick: handleActionClick(action, itemData),
|
|
7536
|
+
"data-testid": `action-${action.event}`,
|
|
7537
|
+
className: cn(
|
|
7538
|
+
action.variant === "danger" && "text-[var(--color-error)] hover:bg-[var(--color-error)]/10"
|
|
7539
|
+
),
|
|
7540
|
+
children: [
|
|
7541
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
7542
|
+
action.label
|
|
7543
|
+
]
|
|
7544
|
+
},
|
|
7545
|
+
idx
|
|
7546
|
+
))
|
|
7547
|
+
}
|
|
7548
|
+
)
|
|
7549
|
+
]
|
|
7550
|
+
}
|
|
7551
|
+
),
|
|
7552
|
+
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-[var(--color-border)]/40" })
|
|
7553
|
+
] }, id);
|
|
7554
|
+
})
|
|
7555
|
+
}
|
|
7556
|
+
);
|
|
7557
|
+
};
|
|
7558
|
+
DataList.displayName = "DataList";
|
|
7559
|
+
|
|
7560
|
+
// components/organisms/types.ts
|
|
7561
|
+
var EntityDisplayEvents = {
|
|
7562
|
+
SORT: "SORT",
|
|
7563
|
+
PAGINATE: "PAGINATE",
|
|
7564
|
+
SEARCH: "SEARCH",
|
|
7565
|
+
FILTER: "FILTER",
|
|
7566
|
+
CLEAR_FILTERS: "CLEAR_FILTERS",
|
|
7567
|
+
SELECT: "SELECT",
|
|
7568
|
+
DESELECT: "DESELECT"
|
|
7569
|
+
};
|
|
7570
|
+
function humanizeFieldName(name) {
|
|
7571
|
+
return name.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).replace(/\b([A-Z])([A-Z]+)\b/g, (_, first, rest) => first + rest.toLowerCase()).trim();
|
|
7572
|
+
}
|
|
7573
|
+
function normalizeColumns(columns) {
|
|
7574
|
+
return columns.map((col) => {
|
|
6439
7575
|
if (typeof col === "string") {
|
|
6440
|
-
const
|
|
6441
|
-
return { key: col, header };
|
|
7576
|
+
const header2 = humanizeFieldName(col);
|
|
7577
|
+
return { key: col, header: header2 };
|
|
6442
7578
|
}
|
|
6443
|
-
|
|
7579
|
+
const key = col.key ?? col.name ?? "";
|
|
7580
|
+
const header = col.header ?? col.label ?? humanizeFieldName(String(key));
|
|
7581
|
+
return { ...col, key, header };
|
|
6444
7582
|
});
|
|
6445
7583
|
}
|
|
7584
|
+
function asBooleanValue(value) {
|
|
7585
|
+
if (typeof value === "boolean") return value;
|
|
7586
|
+
if (value === "true") return true;
|
|
7587
|
+
if (value === "false") return false;
|
|
7588
|
+
return null;
|
|
7589
|
+
}
|
|
6446
7590
|
function DataTable({
|
|
6447
7591
|
fields,
|
|
6448
7592
|
columns,
|
|
@@ -6641,8 +7785,7 @@ function DataTable({
|
|
|
6641
7785
|
] }),
|
|
6642
7786
|
/* @__PURE__ */ jsx(Box, { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full", children: [
|
|
6643
7787
|
/* @__PURE__ */ jsx("thead", { className: "bg-[var(--color-table-header)] border-b-2 border-[var(--color-border)]", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
6644
|
-
selectable &&
|
|
6645
|
-
/* @__PURE__ */ jsx("th", { className: "w-12 px-4 py-3", children: /* @__PURE__ */ jsx(
|
|
7788
|
+
selectable && /* @__PURE__ */ jsx("th", { className: "w-12 px-4 py-3", children: /* @__PURE__ */ jsx(
|
|
6646
7789
|
Checkbox,
|
|
6647
7790
|
{
|
|
6648
7791
|
checked: allSelected,
|
|
@@ -6650,176 +7793,162 @@ function DataTable({
|
|
|
6650
7793
|
onChange: handleSelectAll
|
|
6651
7794
|
}
|
|
6652
7795
|
) }),
|
|
6653
|
-
normalizedColumns.map((col) => (
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
"
|
|
6657
|
-
|
|
6658
|
-
"
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
},
|
|
6670
|
-
String(col.key)
|
|
6671
|
-
)
|
|
7796
|
+
normalizedColumns.map((col) => /* @__PURE__ */ jsx(
|
|
7797
|
+
"th",
|
|
7798
|
+
{
|
|
7799
|
+
"data-column": String(col.key),
|
|
7800
|
+
className: cn(
|
|
7801
|
+
"px-4 py-3 text-left text-xs font-bold text-[var(--color-foreground)] uppercase tracking-wider whitespace-nowrap",
|
|
7802
|
+
col.sortable && "cursor-pointer select-none hover:bg-[var(--color-table-row-hover)]"
|
|
7803
|
+
),
|
|
7804
|
+
style: { width: col.width },
|
|
7805
|
+
onClick: () => col.sortable && handleSort(String(col.key)),
|
|
7806
|
+
children: /* @__PURE__ */ jsxs(HStack, { className: "items-center gap-1", children: [
|
|
7807
|
+
col.header,
|
|
7808
|
+
col.sortable && sortBy === col.key && (sortDirection === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }))
|
|
7809
|
+
] })
|
|
7810
|
+
},
|
|
7811
|
+
String(col.key)
|
|
6672
7812
|
)),
|
|
6673
7813
|
rowActions && /* @__PURE__ */ jsx("th", { className: "w-12 px-4 py-3" })
|
|
6674
7814
|
] }) }),
|
|
6675
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-700", children: isLoading ? (
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
/* @__PURE__ */ jsx(
|
|
6685
|
-
Typography,
|
|
6686
|
-
{
|
|
6687
|
-
variant: "small",
|
|
6688
|
-
className: "text-[var(--color-muted-foreground)]",
|
|
6689
|
-
children: t("common.loading")
|
|
6690
|
-
}
|
|
6691
|
-
)
|
|
6692
|
-
] })
|
|
6693
|
-
}
|
|
6694
|
-
) })
|
|
6695
|
-
) : error ? (
|
|
6696
|
-
// eslint-disable-next-line almadar/no-raw-dom-elements -- native table elements in DataTable
|
|
6697
|
-
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs(
|
|
6698
|
-
"td",
|
|
6699
|
-
{
|
|
6700
|
-
colSpan: normalizedColumns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0),
|
|
6701
|
-
className: "px-4 py-12 text-center text-[var(--color-error)]",
|
|
6702
|
-
children: [
|
|
6703
|
-
t("error.generic") + ": ",
|
|
6704
|
-
error.message
|
|
6705
|
-
]
|
|
6706
|
-
}
|
|
6707
|
-
) })
|
|
6708
|
-
) : items.length === 0 ? (
|
|
6709
|
-
// eslint-disable-next-line almadar/no-raw-dom-elements -- native table elements in DataTable
|
|
6710
|
-
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
6711
|
-
"td",
|
|
6712
|
-
{
|
|
6713
|
-
colSpan: normalizedColumns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0),
|
|
6714
|
-
className: "px-4 py-12",
|
|
6715
|
-
children: /* @__PURE__ */ jsx(
|
|
6716
|
-
EmptyState,
|
|
7815
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-700", children: isLoading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
7816
|
+
"td",
|
|
7817
|
+
{
|
|
7818
|
+
colSpan: normalizedColumns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0),
|
|
7819
|
+
className: "px-4 py-12 text-center",
|
|
7820
|
+
children: /* @__PURE__ */ jsxs(VStack, { className: "items-center gap-2", children: [
|
|
7821
|
+
/* @__PURE__ */ jsx(Spinner, { size: "lg" }),
|
|
7822
|
+
/* @__PURE__ */ jsx(
|
|
7823
|
+
Typography,
|
|
6717
7824
|
{
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
actionLabel: emptyAction?.label,
|
|
6722
|
-
actionEvent: emptyAction?.event
|
|
7825
|
+
variant: "small",
|
|
7826
|
+
className: "text-[var(--color-muted-foreground)]",
|
|
7827
|
+
children: t("common.loading")
|
|
6723
7828
|
}
|
|
6724
7829
|
)
|
|
6725
|
-
}
|
|
6726
|
-
|
|
6727
|
-
) :
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
7830
|
+
] })
|
|
7831
|
+
}
|
|
7832
|
+
) }) : error ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs(
|
|
7833
|
+
"td",
|
|
7834
|
+
{
|
|
7835
|
+
colSpan: normalizedColumns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0),
|
|
7836
|
+
className: "px-4 py-12 text-center text-[var(--color-error)]",
|
|
7837
|
+
children: [
|
|
7838
|
+
t("error.generic") + ": ",
|
|
7839
|
+
error.message
|
|
7840
|
+
]
|
|
7841
|
+
}
|
|
7842
|
+
) }) : items.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
7843
|
+
"td",
|
|
7844
|
+
{
|
|
7845
|
+
colSpan: normalizedColumns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0),
|
|
7846
|
+
className: "px-4 py-12",
|
|
7847
|
+
children: /* @__PURE__ */ jsx(
|
|
7848
|
+
EmptyState,
|
|
7849
|
+
{
|
|
7850
|
+
icon: emptyIcon,
|
|
7851
|
+
title: resolvedEmptyTitle,
|
|
7852
|
+
description: resolvedEmptyDescription,
|
|
7853
|
+
actionLabel: emptyAction?.label,
|
|
7854
|
+
actionEvent: emptyAction?.event
|
|
7855
|
+
}
|
|
7856
|
+
)
|
|
7857
|
+
}
|
|
7858
|
+
) }) : items.map((row, rowIndex) => /* @__PURE__ */ jsxs(
|
|
7859
|
+
"tr",
|
|
7860
|
+
{
|
|
7861
|
+
"data-entity-row": true,
|
|
7862
|
+
className: cn(
|
|
7863
|
+
"border-b border-[var(--color-table-border)] last:border-0 hover:bg-[var(--color-table-row-hover)] transition-colors",
|
|
7864
|
+
selectedIds.includes(row.id) && "bg-[var(--color-primary)]/10 font-medium",
|
|
7865
|
+
isRowClickable && "cursor-pointer"
|
|
7866
|
+
),
|
|
7867
|
+
onClick: () => isRowClickable && handleRowClick(row),
|
|
7868
|
+
children: [
|
|
7869
|
+
selectable && /* @__PURE__ */ jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx(
|
|
7870
|
+
Checkbox,
|
|
7871
|
+
{
|
|
7872
|
+
checked: selectedIds.includes(row.id),
|
|
7873
|
+
onChange: () => handleSelectRow(row.id)
|
|
7874
|
+
}
|
|
7875
|
+
) }),
|
|
7876
|
+
normalizedColumns.map((col) => {
|
|
7877
|
+
const cellValue = getNestedValue(
|
|
7878
|
+
row,
|
|
7879
|
+
String(col.key)
|
|
7880
|
+
);
|
|
7881
|
+
return /* @__PURE__ */ jsx(
|
|
7882
|
+
"td",
|
|
7883
|
+
{
|
|
7884
|
+
"data-column": String(col.key),
|
|
7885
|
+
className: "px-4 py-3 text-sm text-[var(--color-foreground)] whitespace-nowrap sm:whitespace-normal",
|
|
7886
|
+
children: col.render ? col.render(cellValue, row, rowIndex) : (() => {
|
|
7887
|
+
const boolVal = asBooleanValue(cellValue);
|
|
7888
|
+
if (boolVal !== null) {
|
|
7889
|
+
return boolVal ? /* @__PURE__ */ jsx(Badge, { variant: "success", children: t("common.yes") }) : /* @__PURE__ */ jsx(Badge, { variant: "neutral", children: t("common.no") });
|
|
7890
|
+
}
|
|
7891
|
+
return String(cellValue ?? "");
|
|
7892
|
+
})()
|
|
7893
|
+
},
|
|
7894
|
+
String(col.key)
|
|
7895
|
+
);
|
|
7896
|
+
}),
|
|
7897
|
+
rowActions && /* @__PURE__ */ jsxs("td", { className: "px-4 py-3 relative", children: [
|
|
7898
|
+
/* @__PURE__ */ jsx(
|
|
7899
|
+
Button,
|
|
6743
7900
|
{
|
|
6744
|
-
|
|
6745
|
-
|
|
7901
|
+
variant: "ghost",
|
|
7902
|
+
className: "p-1 rounded hover:bg-[var(--color-muted)]",
|
|
7903
|
+
onClick: (e) => {
|
|
7904
|
+
e.stopPropagation();
|
|
7905
|
+
setOpenActionMenu(
|
|
7906
|
+
openActionMenu === row.id ? null : row.id
|
|
7907
|
+
);
|
|
7908
|
+
},
|
|
7909
|
+
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4 text-[var(--color-muted-foreground)]" })
|
|
6746
7910
|
}
|
|
6747
|
-
)
|
|
6748
|
-
|
|
6749
|
-
const cellValue = getNestedValue(
|
|
6750
|
-
row,
|
|
6751
|
-
String(col.key)
|
|
6752
|
-
);
|
|
6753
|
-
return (
|
|
6754
|
-
// eslint-disable-next-line almadar/no-raw-dom-elements -- native table elements in DataTable
|
|
6755
|
-
/* @__PURE__ */ jsx(
|
|
6756
|
-
"td",
|
|
6757
|
-
{
|
|
6758
|
-
"data-column": String(col.key),
|
|
6759
|
-
className: "px-4 py-3 text-sm text-[var(--color-foreground)] whitespace-nowrap sm:whitespace-normal",
|
|
6760
|
-
children: col.render ? col.render(cellValue, row, rowIndex) : String(cellValue ?? "")
|
|
6761
|
-
},
|
|
6762
|
-
String(col.key)
|
|
6763
|
-
)
|
|
6764
|
-
);
|
|
6765
|
-
}),
|
|
6766
|
-
rowActions && // eslint-disable-next-line almadar/no-raw-dom-elements -- native table elements in DataTable
|
|
6767
|
-
/* @__PURE__ */ jsxs("td", { className: "px-4 py-3 relative", children: [
|
|
7911
|
+
),
|
|
7912
|
+
openActionMenu === row.id && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6768
7913
|
/* @__PURE__ */ jsx(
|
|
6769
|
-
|
|
7914
|
+
Box,
|
|
6770
7915
|
{
|
|
6771
|
-
|
|
6772
|
-
className: "p-1 rounded hover:bg-[var(--color-muted)]",
|
|
7916
|
+
className: "fixed inset-0 z-40",
|
|
6773
7917
|
onClick: (e) => {
|
|
6774
7918
|
e.stopPropagation();
|
|
6775
|
-
setOpenActionMenu(
|
|
6776
|
-
|
|
6777
|
-
);
|
|
6778
|
-
},
|
|
6779
|
-
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4 text-[var(--color-muted-foreground)]" })
|
|
7919
|
+
setOpenActionMenu(null);
|
|
7920
|
+
}
|
|
6780
7921
|
}
|
|
6781
7922
|
),
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
(
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
variant: "ghost",
|
|
6799
|
-
"data-event": action.event,
|
|
6800
|
-
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
6801
|
-
className: cn(
|
|
6802
|
-
"w-full flex items-center gap-2 px-4 py-2 text-sm",
|
|
6803
|
-
action.variant === "danger" ? "text-[var(--color-error)] hover:bg-[var(--color-error)]/10" : "text-[var(--color-foreground)] hover:bg-[var(--color-muted)]"
|
|
6804
|
-
),
|
|
6805
|
-
onClick: (e) => {
|
|
6806
|
-
e.stopPropagation();
|
|
6807
|
-
action.onClick(row);
|
|
6808
|
-
setOpenActionMenu(null);
|
|
6809
|
-
},
|
|
6810
|
-
children: [
|
|
6811
|
-
action.icon && /* @__PURE__ */ jsx(action.icon, { className: "h-4 w-4" }),
|
|
6812
|
-
action.label
|
|
6813
|
-
]
|
|
7923
|
+
/* @__PURE__ */ jsx(VStack, { className: "absolute right-0 mt-1 w-48 bg-[var(--color-card)] rounded-[var(--radius-lg)] shadow-[var(--shadow-lg)] border border-[var(--color-border)] py-1 z-50", children: (rowActions ?? []).filter(
|
|
7924
|
+
(action) => !action.show || action.show(row)
|
|
7925
|
+
).map((action, idx) => /* @__PURE__ */ jsxs(
|
|
7926
|
+
Button,
|
|
7927
|
+
{
|
|
7928
|
+
variant: "ghost",
|
|
7929
|
+
"data-event": action.event,
|
|
7930
|
+
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
7931
|
+
className: cn(
|
|
7932
|
+
"w-full flex items-center gap-2 px-4 py-2 text-sm",
|
|
7933
|
+
action.variant === "danger" ? "text-[var(--color-error)] hover:bg-[var(--color-error)]/10" : "text-[var(--color-foreground)] hover:bg-[var(--color-muted)]"
|
|
7934
|
+
),
|
|
7935
|
+
onClick: (e) => {
|
|
7936
|
+
e.stopPropagation();
|
|
7937
|
+
action.onClick(row);
|
|
7938
|
+
setOpenActionMenu(null);
|
|
6814
7939
|
},
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
7940
|
+
children: [
|
|
7941
|
+
action.icon && /* @__PURE__ */ jsx(action.icon, { className: "h-4 w-4" }),
|
|
7942
|
+
action.label
|
|
7943
|
+
]
|
|
7944
|
+
},
|
|
7945
|
+
idx
|
|
7946
|
+
)) })
|
|
6818
7947
|
] })
|
|
6819
|
-
]
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
7948
|
+
] })
|
|
7949
|
+
]
|
|
7950
|
+
},
|
|
7951
|
+
row.id
|
|
6823
7952
|
)) })
|
|
6824
7953
|
] }) }),
|
|
6825
7954
|
totalCount !== void 0 && totalPages > 1 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 border-t-2 border-[var(--color-border)]", children: /* @__PURE__ */ jsx(
|
|
@@ -6861,7 +7990,7 @@ var StatCard = ({
|
|
|
6861
7990
|
const labelToUse = propLabel ?? propTitle;
|
|
6862
7991
|
const eventBus = useEventBus();
|
|
6863
7992
|
const { t } = useTranslate();
|
|
6864
|
-
const handleActionClick =
|
|
7993
|
+
const handleActionClick = React47__default.useCallback(() => {
|
|
6865
7994
|
if (action?.event) {
|
|
6866
7995
|
eventBus.emit(`UI:${action.event}`, {});
|
|
6867
7996
|
}
|
|
@@ -6872,7 +8001,7 @@ var StatCard = ({
|
|
|
6872
8001
|
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
6873
8002
|
const isLoading = externalLoading ?? false;
|
|
6874
8003
|
const error = externalError;
|
|
6875
|
-
const computeMetricValue =
|
|
8004
|
+
const computeMetricValue = React47__default.useCallback(
|
|
6876
8005
|
(metric, items) => {
|
|
6877
8006
|
if (metric.value !== void 0) {
|
|
6878
8007
|
return metric.value;
|
|
@@ -6911,7 +8040,7 @@ var StatCard = ({
|
|
|
6911
8040
|
},
|
|
6912
8041
|
[]
|
|
6913
8042
|
);
|
|
6914
|
-
const schemaStats =
|
|
8043
|
+
const schemaStats = React47__default.useMemo(() => {
|
|
6915
8044
|
if (!metrics || metrics.length === 0) return null;
|
|
6916
8045
|
return metrics.map((metric) => ({
|
|
6917
8046
|
label: metric.label,
|
|
@@ -6919,7 +8048,7 @@ var StatCard = ({
|
|
|
6919
8048
|
format: metric.format
|
|
6920
8049
|
}));
|
|
6921
8050
|
}, [metrics, data, computeMetricValue]);
|
|
6922
|
-
const calculatedTrend =
|
|
8051
|
+
const calculatedTrend = React47__default.useMemo(() => {
|
|
6923
8052
|
if (manualTrend !== void 0) return manualTrend;
|
|
6924
8053
|
if (previousValue === void 0 || currentValue === void 0)
|
|
6925
8054
|
return void 0;
|
|
@@ -7055,18 +8184,15 @@ var PageHeader = ({
|
|
|
7055
8184
|
info: "bg-[var(--color-info)]/10 text-[var(--color-info)]"
|
|
7056
8185
|
};
|
|
7057
8186
|
return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
|
|
7058
|
-
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(
|
|
8187
|
+
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React47__default.Fragment, { children: [
|
|
7059
8188
|
idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
|
|
7060
|
-
crumb.href ? (
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
children: crumb.label
|
|
7068
|
-
}
|
|
7069
|
-
)
|
|
8189
|
+
crumb.href ? /* @__PURE__ */ jsx(
|
|
8190
|
+
"a",
|
|
8191
|
+
{
|
|
8192
|
+
href: crumb.href,
|
|
8193
|
+
className: "text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)]",
|
|
8194
|
+
children: crumb.label
|
|
8195
|
+
}
|
|
7070
8196
|
) : /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-[var(--color-foreground)] font-medium", children: crumb.label })
|
|
7071
8197
|
] }, idx)) }) }),
|
|
7072
8198
|
/* @__PURE__ */ jsxs(Box, { className: "flex items-start justify-between gap-4", children: [
|
|
@@ -7194,9 +8320,68 @@ function formatFieldValue(value, fieldName) {
|
|
|
7194
8320
|
}
|
|
7195
8321
|
return String(value);
|
|
7196
8322
|
}
|
|
8323
|
+
var ReactMarkdown2 = lazy(() => import('react-markdown'));
|
|
8324
|
+
function renderRichFieldValue(value, fieldName, fieldType) {
|
|
8325
|
+
if (value === void 0 || value === null) return "\u2014";
|
|
8326
|
+
const str = String(value);
|
|
8327
|
+
switch (fieldType) {
|
|
8328
|
+
case "image":
|
|
8329
|
+
case "url": {
|
|
8330
|
+
if (str.match(/\.(png|jpe?g|gif|svg|webp|avif)(\?|$)/i) || str.startsWith("data:image/")) {
|
|
8331
|
+
return /* @__PURE__ */ jsx(Box, { className: "mt-1 max-w-full", children: /* @__PURE__ */ jsx(
|
|
8332
|
+
"img",
|
|
8333
|
+
{
|
|
8334
|
+
src: str,
|
|
8335
|
+
alt: formatFieldLabel(fieldName),
|
|
8336
|
+
className: "max-w-full max-h-64 rounded-[var(--radius-md)] object-contain",
|
|
8337
|
+
loading: "lazy"
|
|
8338
|
+
}
|
|
8339
|
+
) });
|
|
8340
|
+
}
|
|
8341
|
+
return str;
|
|
8342
|
+
}
|
|
8343
|
+
case "markdown":
|
|
8344
|
+
case "richtext":
|
|
8345
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: str }), children: /* @__PURE__ */ jsx(Box, { className: "prose prose-sm max-w-none dark:prose-invert", children: /* @__PURE__ */ jsx(ReactMarkdown2, { children: str }) }) });
|
|
8346
|
+
case "code":
|
|
8347
|
+
return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-[var(--radius-md)] bg-[var(--color-muted)] p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children: str }) }) });
|
|
8348
|
+
case "html":
|
|
8349
|
+
return /* @__PURE__ */ jsx(Box, { className: "mt-1 prose prose-sm max-w-none dark:prose-invert break-words", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: str }) });
|
|
8350
|
+
case "date":
|
|
8351
|
+
case "datetime": {
|
|
8352
|
+
const d = new Date(str);
|
|
8353
|
+
if (!isNaN(d.getTime())) {
|
|
8354
|
+
return d.toLocaleDateString(void 0, {
|
|
8355
|
+
year: "numeric",
|
|
8356
|
+
month: "long",
|
|
8357
|
+
day: "numeric",
|
|
8358
|
+
...fieldType === "datetime" ? { hour: "2-digit", minute: "2-digit" } : {}
|
|
8359
|
+
});
|
|
8360
|
+
}
|
|
8361
|
+
return str;
|
|
8362
|
+
}
|
|
8363
|
+
default:
|
|
8364
|
+
return formatFieldValue(value, fieldName);
|
|
8365
|
+
}
|
|
8366
|
+
}
|
|
7197
8367
|
function normalizeFieldDefs(fields) {
|
|
7198
8368
|
if (!fields) return [];
|
|
7199
|
-
return fields.map((f) =>
|
|
8369
|
+
return fields.map((f) => {
|
|
8370
|
+
if (typeof f === "string") return f;
|
|
8371
|
+
if ("key" in f) return f.key;
|
|
8372
|
+
if ("name" in f) return f.name;
|
|
8373
|
+
return String(f);
|
|
8374
|
+
});
|
|
8375
|
+
}
|
|
8376
|
+
function buildFieldTypeMap(fields) {
|
|
8377
|
+
const map = {};
|
|
8378
|
+
if (!fields) return map;
|
|
8379
|
+
for (const f of fields) {
|
|
8380
|
+
if (typeof f === "object" && "name" in f && "type" in f) {
|
|
8381
|
+
map[f.name] = f.type;
|
|
8382
|
+
}
|
|
8383
|
+
}
|
|
8384
|
+
return map;
|
|
7200
8385
|
}
|
|
7201
8386
|
var DetailPanel = ({
|
|
7202
8387
|
title: propTitle,
|
|
@@ -7220,9 +8405,10 @@ var DetailPanel = ({
|
|
|
7220
8405
|
const isFieldDefArray = (arr) => {
|
|
7221
8406
|
if (!arr || arr.length === 0) return false;
|
|
7222
8407
|
const first = arr[0];
|
|
7223
|
-
return typeof first === "string" || typeof first === "object" && first !== null && "key" in first;
|
|
8408
|
+
return typeof first === "string" || typeof first === "object" && first !== null && ("key" in first || "name" in first);
|
|
7224
8409
|
};
|
|
7225
8410
|
const effectiveFieldNames = isFieldDefArray(propFields) ? normalizeFieldDefs(propFields) : fieldNames;
|
|
8411
|
+
const fieldTypeMap = isFieldDefArray(propFields) ? buildFieldTypeMap(propFields) : {};
|
|
7226
8412
|
useCallback(
|
|
7227
8413
|
(action, data2) => {
|
|
7228
8414
|
if (action.navigatesTo) {
|
|
@@ -7297,7 +8483,7 @@ var DetailPanel = ({
|
|
|
7297
8483
|
if (value !== void 0 && value !== null) {
|
|
7298
8484
|
overviewFields.push({
|
|
7299
8485
|
label: formatFieldLabel(field),
|
|
7300
|
-
value:
|
|
8486
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
7301
8487
|
icon: getFieldIcon(field)
|
|
7302
8488
|
});
|
|
7303
8489
|
}
|
|
@@ -7313,7 +8499,7 @@ var DetailPanel = ({
|
|
|
7313
8499
|
if (value !== void 0 && value !== null) {
|
|
7314
8500
|
metricsFields.push({
|
|
7315
8501
|
label: formatFieldLabel(field),
|
|
7316
|
-
value:
|
|
8502
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
7317
8503
|
icon: getFieldIcon(field)
|
|
7318
8504
|
});
|
|
7319
8505
|
}
|
|
@@ -7329,7 +8515,7 @@ var DetailPanel = ({
|
|
|
7329
8515
|
if (value !== void 0 && value !== null) {
|
|
7330
8516
|
timelineFields.push({
|
|
7331
8517
|
label: formatFieldLabel(field),
|
|
7332
|
-
value:
|
|
8518
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
7333
8519
|
icon: getFieldIcon(field)
|
|
7334
8520
|
});
|
|
7335
8521
|
}
|
|
@@ -7345,7 +8531,7 @@ var DetailPanel = ({
|
|
|
7345
8531
|
if (value !== void 0 && value !== null) {
|
|
7346
8532
|
descFields.push({
|
|
7347
8533
|
label: formatFieldLabel(field),
|
|
7348
|
-
value:
|
|
8534
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
7349
8535
|
icon: getFieldIcon(field)
|
|
7350
8536
|
});
|
|
7351
8537
|
}
|
|
@@ -7385,96 +8571,123 @@ var DetailPanel = ({
|
|
|
7385
8571
|
}
|
|
7386
8572
|
);
|
|
7387
8573
|
}
|
|
7388
|
-
const
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
8574
|
+
const allFields = [];
|
|
8575
|
+
if (sections) {
|
|
8576
|
+
for (const section of sections) {
|
|
8577
|
+
for (const field of section.fields) {
|
|
8578
|
+
if (typeof field === "string") {
|
|
8579
|
+
const value = normalizedData ? getNestedValue(normalizedData, field) : void 0;
|
|
8580
|
+
allFields.push({
|
|
8581
|
+
label: formatFieldLabel(field),
|
|
8582
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
8583
|
+
icon: getFieldIcon(field)
|
|
8584
|
+
});
|
|
8585
|
+
} else {
|
|
8586
|
+
allFields.push(field);
|
|
8587
|
+
}
|
|
8588
|
+
}
|
|
8589
|
+
}
|
|
8590
|
+
}
|
|
8591
|
+
const closeAction = actions?.find(
|
|
8592
|
+
(a) => a.event === "CLOSE" || a.event === "CANCEL" || a.label?.toLowerCase() === "close"
|
|
8593
|
+
);
|
|
8594
|
+
const otherActions = actions?.filter((a) => a !== closeAction) ?? [];
|
|
8595
|
+
const effectiveCloseAction = closeAction ?? { event: void 0};
|
|
8596
|
+
const content = /* @__PURE__ */ jsx(Card, { variant: "elevated", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", className: "p-6", children: [
|
|
8597
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "end", align: "center", gap: "xs", children: [
|
|
8598
|
+
otherActions.map((action, idx) => /* @__PURE__ */ jsx(
|
|
8599
|
+
Button,
|
|
8600
|
+
{
|
|
8601
|
+
variant: action.variant || "secondary",
|
|
8602
|
+
size: "sm",
|
|
8603
|
+
action: action.event,
|
|
8604
|
+
actionPayload: { row: normalizedData },
|
|
8605
|
+
icon: action.icon,
|
|
8606
|
+
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
8607
|
+
children: action.label
|
|
8608
|
+
},
|
|
8609
|
+
idx
|
|
8610
|
+
)),
|
|
8611
|
+
/* @__PURE__ */ jsx(
|
|
8612
|
+
Button,
|
|
8613
|
+
{
|
|
8614
|
+
variant: "ghost",
|
|
8615
|
+
size: "sm",
|
|
8616
|
+
action: effectiveCloseAction.event,
|
|
8617
|
+
actionPayload: { row: normalizedData },
|
|
8618
|
+
onClick: effectiveCloseAction.event ? void 0 : handleClose,
|
|
8619
|
+
icon: X,
|
|
8620
|
+
"data-testid": effectiveCloseAction.event ? `action-${effectiveCloseAction.event}` : "action-close"
|
|
8621
|
+
}
|
|
8622
|
+
)
|
|
8623
|
+
] }),
|
|
8624
|
+
avatar,
|
|
8625
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" }),
|
|
8626
|
+
subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: subtitle }),
|
|
8627
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", wrap: true, children: [
|
|
7413
8628
|
normalizedData && effectiveFieldNames && effectiveFieldNames.filter(
|
|
7414
|
-
(f) => f.toLowerCase().includes("
|
|
8629
|
+
(f) => f.toLowerCase().includes("status") || f.toLowerCase().includes("priority")
|
|
7415
8630
|
).map((field) => {
|
|
7416
8631
|
const value = getNestedValue(normalizedData, field);
|
|
7417
|
-
if (value
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
7421
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatFieldLabel(field) }),
|
|
7422
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "medium", children: [
|
|
7423
|
-
value,
|
|
7424
|
-
"%"
|
|
7425
|
-
] })
|
|
7426
|
-
] }),
|
|
7427
|
-
/* @__PURE__ */ jsx(ProgressBar, { value })
|
|
7428
|
-
] }, field);
|
|
7429
|
-
}),
|
|
7430
|
-
actions && actions.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7431
|
-
/* @__PURE__ */ jsx(Divider, {}),
|
|
7432
|
-
/* @__PURE__ */ jsx(HStack, { gap: "sm", children: actions.map((action, idx) => /* @__PURE__ */ jsx(
|
|
7433
|
-
Button,
|
|
8632
|
+
if (!value) return null;
|
|
8633
|
+
return /* @__PURE__ */ jsx(
|
|
8634
|
+
Badge,
|
|
7434
8635
|
{
|
|
7435
|
-
variant:
|
|
7436
|
-
|
|
7437
|
-
actionPayload: { row: normalizedData },
|
|
7438
|
-
icon: action.icon,
|
|
7439
|
-
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
7440
|
-
children: action.label
|
|
8636
|
+
variant: getBadgeVariant(field, String(value)),
|
|
8637
|
+
children: String(value)
|
|
7441
8638
|
},
|
|
7442
|
-
|
|
7443
|
-
)
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
8639
|
+
field
|
|
8640
|
+
);
|
|
8641
|
+
}),
|
|
8642
|
+
status && /* @__PURE__ */ jsx(Badge, { variant: status.variant ?? "default", children: status.label })
|
|
8643
|
+
] }),
|
|
8644
|
+
normalizedData && effectiveFieldNames && effectiveFieldNames.filter(
|
|
8645
|
+
(f) => f.toLowerCase().includes("progress") || f.toLowerCase().includes("percent")
|
|
8646
|
+
).map((field) => {
|
|
8647
|
+
const value = getNestedValue(normalizedData, field);
|
|
8648
|
+
if (value === void 0 || value === null || typeof value !== "number")
|
|
8649
|
+
return null;
|
|
8650
|
+
return /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "w-full", children: [
|
|
8651
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
8652
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatFieldLabel(field) }),
|
|
8653
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "medium", children: [
|
|
8654
|
+
value,
|
|
8655
|
+
"%"
|
|
8656
|
+
] })
|
|
8657
|
+
] }),
|
|
8658
|
+
/* @__PURE__ */ jsx(ProgressBar, { value })
|
|
8659
|
+
] }, field);
|
|
8660
|
+
}),
|
|
8661
|
+
allFields.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7448
8662
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
7449
|
-
/* @__PURE__ */ jsx(SimpleGrid, { minChildWidth: "250px", maxCols: 2, gap: "lg", children:
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
8663
|
+
/* @__PURE__ */ jsx(SimpleGrid, { minChildWidth: "250px", maxCols: 2, gap: "lg", children: allFields.map((field, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "start", children: [
|
|
8664
|
+
field.icon && /* @__PURE__ */ jsx(
|
|
8665
|
+
Icon,
|
|
8666
|
+
{
|
|
8667
|
+
icon: field.icon,
|
|
8668
|
+
size: "md",
|
|
8669
|
+
className: "text-[var(--color-muted-foreground)] mt-1"
|
|
8670
|
+
}
|
|
8671
|
+
),
|
|
8672
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", flex: true, className: "min-w-0", children: [
|
|
8673
|
+
/* @__PURE__ */ jsx(
|
|
8674
|
+
Typography,
|
|
7455
8675
|
{
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
8676
|
+
variant: "small",
|
|
8677
|
+
color: "secondary",
|
|
8678
|
+
weight: "medium",
|
|
8679
|
+
children: field.label
|
|
7459
8680
|
}
|
|
7460
8681
|
),
|
|
7461
|
-
/* @__PURE__ */
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
),
|
|
7471
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: resolved.value || "\u2014" })
|
|
7472
|
-
] })
|
|
7473
|
-
] }, fieldIdx);
|
|
7474
|
-
}) })
|
|
7475
|
-
] }) }, sectionIdx)),
|
|
7476
|
-
footer && /* @__PURE__ */ jsx(Card, { variant: "bordered", children: footer })
|
|
7477
|
-
] });
|
|
8682
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: field.value || "\u2014" })
|
|
8683
|
+
] })
|
|
8684
|
+
] }, idx)) })
|
|
8685
|
+
] }),
|
|
8686
|
+
footer && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8687
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
8688
|
+
footer
|
|
8689
|
+
] })
|
|
8690
|
+
] }) });
|
|
7478
8691
|
return /* @__PURE__ */ jsx(
|
|
7479
8692
|
Box,
|
|
7480
8693
|
{
|
|
@@ -7508,7 +8721,7 @@ var layoutStyles = {
|
|
|
7508
8721
|
horizontal: "flex flex-row flex-wrap items-end",
|
|
7509
8722
|
inline: "flex flex-row flex-wrap items-center"
|
|
7510
8723
|
};
|
|
7511
|
-
var
|
|
8724
|
+
var gapStyles6 = {
|
|
7512
8725
|
sm: "gap-2",
|
|
7513
8726
|
md: "gap-4",
|
|
7514
8727
|
lg: "gap-6"
|
|
@@ -7602,11 +8815,12 @@ var Form = ({
|
|
|
7602
8815
|
const resolvedSubmitLabel = submitLabel ?? t("common.save");
|
|
7603
8816
|
const resolvedCancelLabel = cancelLabel ?? t("common.cancel");
|
|
7604
8817
|
const normalizedInitialData = initialData ?? {};
|
|
7605
|
-
const
|
|
7606
|
-
const
|
|
8818
|
+
const resolvedEntity = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
8819
|
+
const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
|
|
8820
|
+
const entityDerivedFields = React47__default.useMemo(() => {
|
|
7607
8821
|
if (fields && fields.length > 0) return void 0;
|
|
7608
|
-
if (!
|
|
7609
|
-
return
|
|
8822
|
+
if (!resolvedEntity) return void 0;
|
|
8823
|
+
return resolvedEntity.fields.map(
|
|
7610
8824
|
(f) => ({
|
|
7611
8825
|
name: f.name,
|
|
7612
8826
|
type: f.type,
|
|
@@ -7622,14 +8836,14 @@ var Form = ({
|
|
|
7622
8836
|
const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
|
|
7623
8837
|
const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
|
|
7624
8838
|
const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
|
|
7625
|
-
const [formData, setFormData] =
|
|
8839
|
+
const [formData, setFormData] = React47__default.useState(
|
|
7626
8840
|
normalizedInitialData
|
|
7627
8841
|
);
|
|
7628
|
-
const [collapsedSections, setCollapsedSections] =
|
|
8842
|
+
const [collapsedSections, setCollapsedSections] = React47__default.useState(
|
|
7629
8843
|
/* @__PURE__ */ new Set()
|
|
7630
8844
|
);
|
|
7631
8845
|
const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
|
|
7632
|
-
const evalContext =
|
|
8846
|
+
const evalContext = React47__default.useMemo(
|
|
7633
8847
|
() => ({
|
|
7634
8848
|
formValues: formData,
|
|
7635
8849
|
globalVariables: externalContext?.globalVariables ?? {},
|
|
@@ -7638,13 +8852,13 @@ var Form = ({
|
|
|
7638
8852
|
}),
|
|
7639
8853
|
[formData, externalContext]
|
|
7640
8854
|
);
|
|
7641
|
-
|
|
8855
|
+
React47__default.useEffect(() => {
|
|
7642
8856
|
const data = initialData;
|
|
7643
8857
|
if (data && Object.keys(data).length > 0) {
|
|
7644
8858
|
setFormData(data);
|
|
7645
8859
|
}
|
|
7646
8860
|
}, [initialData]);
|
|
7647
|
-
const processCalculations =
|
|
8861
|
+
const processCalculations = React47__default.useCallback(
|
|
7648
8862
|
(changedFieldId, newFormData) => {
|
|
7649
8863
|
if (!hiddenCalculations.length) return;
|
|
7650
8864
|
const context = {
|
|
@@ -7669,7 +8883,7 @@ var Form = ({
|
|
|
7669
8883
|
},
|
|
7670
8884
|
[hiddenCalculations, externalContext, eventBus]
|
|
7671
8885
|
);
|
|
7672
|
-
const checkViolations =
|
|
8886
|
+
const checkViolations = React47__default.useCallback(
|
|
7673
8887
|
(changedFieldId, newFormData) => {
|
|
7674
8888
|
if (!violationTriggers.length) return;
|
|
7675
8889
|
const context = {
|
|
@@ -7706,7 +8920,7 @@ var Form = ({
|
|
|
7706
8920
|
processCalculations(name, newFormData);
|
|
7707
8921
|
checkViolations(name, newFormData);
|
|
7708
8922
|
};
|
|
7709
|
-
const isFieldVisible =
|
|
8923
|
+
const isFieldVisible = React47__default.useCallback(
|
|
7710
8924
|
(fieldName) => {
|
|
7711
8925
|
const condition = conditionalFields[fieldName];
|
|
7712
8926
|
if (!condition) return true;
|
|
@@ -7714,7 +8928,7 @@ var Form = ({
|
|
|
7714
8928
|
},
|
|
7715
8929
|
[conditionalFields, evalContext]
|
|
7716
8930
|
);
|
|
7717
|
-
const isSectionVisible =
|
|
8931
|
+
const isSectionVisible = React47__default.useCallback(
|
|
7718
8932
|
(section) => {
|
|
7719
8933
|
if (!section.condition) return true;
|
|
7720
8934
|
return Boolean(evaluateFormExpression(section.condition, evalContext));
|
|
@@ -7746,7 +8960,7 @@ var Form = ({
|
|
|
7746
8960
|
eventBus.emit(`UI:${onCancel}`);
|
|
7747
8961
|
}
|
|
7748
8962
|
};
|
|
7749
|
-
const renderField =
|
|
8963
|
+
const renderField = React47__default.useCallback(
|
|
7750
8964
|
(field) => {
|
|
7751
8965
|
const fieldName = field.name || field.field;
|
|
7752
8966
|
if (!fieldName) return null;
|
|
@@ -7767,7 +8981,7 @@ var Form = ({
|
|
|
7767
8981
|
[formData, isFieldVisible, relationsData, relationsLoading, isLoading]
|
|
7768
8982
|
);
|
|
7769
8983
|
const effectiveFields = entityDerivedFields ?? fields;
|
|
7770
|
-
const normalizedFields =
|
|
8984
|
+
const normalizedFields = React47__default.useMemo(() => {
|
|
7771
8985
|
if (!effectiveFields || effectiveFields.length === 0) return [];
|
|
7772
8986
|
return effectiveFields.map((field) => {
|
|
7773
8987
|
if (typeof field === "string") {
|
|
@@ -7776,7 +8990,7 @@ var Form = ({
|
|
|
7776
8990
|
return field;
|
|
7777
8991
|
});
|
|
7778
8992
|
}, [effectiveFields]);
|
|
7779
|
-
const schemaFields =
|
|
8993
|
+
const schemaFields = React47__default.useMemo(() => {
|
|
7780
8994
|
if (normalizedFields.length === 0) return null;
|
|
7781
8995
|
if (isDebugEnabled()) {
|
|
7782
8996
|
debugGroup(`Form: ${entityName || "unknown"}`);
|
|
@@ -7786,7 +9000,7 @@ var Form = ({
|
|
|
7786
9000
|
}
|
|
7787
9001
|
return normalizedFields.map(renderField).filter(Boolean);
|
|
7788
9002
|
}, [normalizedFields, renderField, entityName, conditionalFields]);
|
|
7789
|
-
const sectionElements =
|
|
9003
|
+
const sectionElements = React47__default.useMemo(() => {
|
|
7790
9004
|
if (!sections || sections.length === 0) return null;
|
|
7791
9005
|
return sections.map((section) => {
|
|
7792
9006
|
if (!isSectionVisible(section)) {
|
|
@@ -7963,47 +9177,44 @@ var Form = ({
|
|
|
7963
9177
|
);
|
|
7964
9178
|
}
|
|
7965
9179
|
}
|
|
7966
|
-
return (
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
children:
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
]
|
|
8005
|
-
}
|
|
8006
|
-
)
|
|
9180
|
+
return /* @__PURE__ */ jsxs(
|
|
9181
|
+
"form",
|
|
9182
|
+
{
|
|
9183
|
+
className: cn(layoutStyles[layout], gapStyles6[gap], className),
|
|
9184
|
+
onSubmit: handleSubmit,
|
|
9185
|
+
...props,
|
|
9186
|
+
children: [
|
|
9187
|
+
error && /* @__PURE__ */ jsx(Alert, { variant: "error", className: "mb-4", children: error.message || t("error.occurred") }),
|
|
9188
|
+
sectionElements && sectionElements.length > 0 && /* @__PURE__ */ jsx(VStack, { gap: gap === "sm" ? "sm" : gap === "lg" ? "lg" : "md", children: sectionElements }),
|
|
9189
|
+
schemaFields,
|
|
9190
|
+
children,
|
|
9191
|
+
(schemaFields && schemaFields.length > 0 || sectionElements && sectionElements.length > 0) && /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "pt-4", children: [
|
|
9192
|
+
/* @__PURE__ */ jsx(
|
|
9193
|
+
Button,
|
|
9194
|
+
{
|
|
9195
|
+
type: "submit",
|
|
9196
|
+
variant: "primary",
|
|
9197
|
+
disabled: isLoading,
|
|
9198
|
+
"data-event": submitEvent,
|
|
9199
|
+
"data-testid": `action-${submitEvent}`,
|
|
9200
|
+
children: isLoading ? t("form.saving") : resolvedSubmitLabel
|
|
9201
|
+
}
|
|
9202
|
+
),
|
|
9203
|
+
shouldShowCancel && /* @__PURE__ */ jsx(
|
|
9204
|
+
Button,
|
|
9205
|
+
{
|
|
9206
|
+
type: "button",
|
|
9207
|
+
variant: "secondary",
|
|
9208
|
+
onClick: handleCancel,
|
|
9209
|
+
disabled: isLoading,
|
|
9210
|
+
"data-event": cancelEvent,
|
|
9211
|
+
"data-testid": `action-${cancelEvent}`,
|
|
9212
|
+
children: resolvedCancelLabel
|
|
9213
|
+
}
|
|
9214
|
+
)
|
|
9215
|
+
] })
|
|
9216
|
+
]
|
|
9217
|
+
}
|
|
8007
9218
|
);
|
|
8008
9219
|
};
|
|
8009
9220
|
function formatDateValue(value) {
|
|
@@ -8037,9 +9248,37 @@ function formatDateTimeValue(value) {
|
|
|
8037
9248
|
Form.displayName = "Form";
|
|
8038
9249
|
function normalizeFields(fields) {
|
|
8039
9250
|
if (!fields) return [];
|
|
8040
|
-
return fields.map((f) => typeof f === "string" ? f : f.key);
|
|
9251
|
+
return fields.map((f) => typeof f === "string" ? f : f.key ?? f.name ?? "");
|
|
8041
9252
|
}
|
|
8042
|
-
|
|
9253
|
+
function fieldLabel3(key) {
|
|
9254
|
+
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
9255
|
+
}
|
|
9256
|
+
function asBooleanValue2(value) {
|
|
9257
|
+
if (typeof value === "boolean") return value;
|
|
9258
|
+
if (value === "true") return true;
|
|
9259
|
+
if (value === "false") return false;
|
|
9260
|
+
return null;
|
|
9261
|
+
}
|
|
9262
|
+
var STATUS_FIELDS = /* @__PURE__ */ new Set(["status", "state", "priority", "type", "category", "role", "level", "tier"]);
|
|
9263
|
+
function isDateField(key) {
|
|
9264
|
+
const lower = key.toLowerCase();
|
|
9265
|
+
return lower.includes("date") || lower.includes("time") || lower.endsWith("at") || lower.endsWith("_at");
|
|
9266
|
+
}
|
|
9267
|
+
function formatDate3(value) {
|
|
9268
|
+
if (!value) return "";
|
|
9269
|
+
const d = new Date(String(value));
|
|
9270
|
+
if (isNaN(d.getTime())) return String(value);
|
|
9271
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
9272
|
+
}
|
|
9273
|
+
function statusVariant3(value) {
|
|
9274
|
+
const v = value.toLowerCase();
|
|
9275
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open"].includes(v)) return "success";
|
|
9276
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing"].includes(v)) return "warning";
|
|
9277
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed"].includes(v)) return "error";
|
|
9278
|
+
if (["new", "created", "scheduled", "queued"].includes(v)) return "info";
|
|
9279
|
+
return "default";
|
|
9280
|
+
}
|
|
9281
|
+
var gapStyles7 = {
|
|
8043
9282
|
none: "gap-0",
|
|
8044
9283
|
sm: "gap-2",
|
|
8045
9284
|
md: "gap-4",
|
|
@@ -8071,7 +9310,8 @@ var CardGrid = ({
|
|
|
8071
9310
|
fieldNames,
|
|
8072
9311
|
columns,
|
|
8073
9312
|
itemActions,
|
|
8074
|
-
showTotal = true
|
|
9313
|
+
showTotal = true,
|
|
9314
|
+
imageField
|
|
8075
9315
|
}) => {
|
|
8076
9316
|
const eventBus = useEventBus();
|
|
8077
9317
|
const { t } = useTranslate();
|
|
@@ -8083,6 +9323,28 @@ var CardGrid = ({
|
|
|
8083
9323
|
const handlePageChange = (newPage) => {
|
|
8084
9324
|
eventBus.emit("UI:PAGINATE", { page: newPage, pageSize });
|
|
8085
9325
|
};
|
|
9326
|
+
const titleField = effectiveFieldNames?.[0];
|
|
9327
|
+
const statusField = effectiveFieldNames?.find((f) => STATUS_FIELDS.has(f.toLowerCase()));
|
|
9328
|
+
const bodyFields = effectiveFieldNames?.filter((f) => f !== titleField && f !== statusField) ?? [];
|
|
9329
|
+
const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
|
|
9330
|
+
const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
|
|
9331
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
9332
|
+
e.stopPropagation();
|
|
9333
|
+
if (action.navigatesTo) {
|
|
9334
|
+
const url = action.navigatesTo.replace(/\{\{row\.(\w+(?:\.\w+)*)\}\}/g, (_, field) => {
|
|
9335
|
+
const value = getNestedValue(itemData, field);
|
|
9336
|
+
return value !== void 0 && value !== null ? String(value) : "";
|
|
9337
|
+
});
|
|
9338
|
+
eventBus.emit("UI:NAVIGATE", { url, row: itemData });
|
|
9339
|
+
return;
|
|
9340
|
+
}
|
|
9341
|
+
if (action.event) {
|
|
9342
|
+
eventBus.emit(`UI:${action.event}`, { row: itemData });
|
|
9343
|
+
}
|
|
9344
|
+
if (action.onClick) {
|
|
9345
|
+
action.onClick(itemData);
|
|
9346
|
+
}
|
|
9347
|
+
};
|
|
8086
9348
|
const renderContent = () => {
|
|
8087
9349
|
if (children) {
|
|
8088
9350
|
return children;
|
|
@@ -8097,62 +9359,85 @@ var CardGrid = ({
|
|
|
8097
9359
|
] }) });
|
|
8098
9360
|
}
|
|
8099
9361
|
if (normalizedData.length === 0) {
|
|
8100
|
-
return /* @__PURE__ */ jsx(Box, { className: "col-span-full text-center py-
|
|
9362
|
+
return /* @__PURE__ */ jsx(Box, { className: "col-span-full text-center py-12 text-[var(--color-muted-foreground)]", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
8101
9363
|
}
|
|
8102
9364
|
return normalizedData.map((item, index) => {
|
|
8103
9365
|
const itemData = item;
|
|
8104
9366
|
const id = itemData.id || String(index);
|
|
8105
|
-
const
|
|
8106
|
-
const
|
|
8107
|
-
e.stopPropagation();
|
|
8108
|
-
if (action.navigatesTo) {
|
|
8109
|
-
const url = action.navigatesTo.replace(/\{\{row\.(\w+(?:\.\w+)*)\}\}/g, (_, field) => {
|
|
8110
|
-
const value = getNestedValue(itemData, field);
|
|
8111
|
-
return value !== void 0 && value !== null ? String(value) : "";
|
|
8112
|
-
});
|
|
8113
|
-
eventBus.emit("UI:NAVIGATE", { url, row: itemData });
|
|
8114
|
-
return;
|
|
8115
|
-
}
|
|
8116
|
-
if (action.event) {
|
|
8117
|
-
eventBus.emit(`UI:${action.event}`, { row: itemData });
|
|
8118
|
-
}
|
|
8119
|
-
if (action.onClick) {
|
|
8120
|
-
action.onClick(itemData);
|
|
8121
|
-
}
|
|
8122
|
-
};
|
|
9367
|
+
const titleValue = titleField ? getNestedValue(itemData, titleField) : void 0;
|
|
9368
|
+
const statusValue = statusField ? getNestedValue(itemData, statusField) : void 0;
|
|
8123
9369
|
return /* @__PURE__ */ jsxs(
|
|
8124
9370
|
Box,
|
|
8125
9371
|
{
|
|
8126
9372
|
"data-entity-row": true,
|
|
8127
9373
|
className: cn(
|
|
8128
|
-
"bg-[var(--color-card)] rounded-[var(--radius-lg)] border border-[var(--color-border)]
|
|
8129
|
-
"
|
|
9374
|
+
"bg-[var(--color-card)] rounded-[var(--radius-lg)] border border-[var(--color-border)]",
|
|
9375
|
+
"shadow-[var(--shadow-sm)] hover:shadow-[var(--shadow-hover)]",
|
|
9376
|
+
"cursor-pointer hover:border-[var(--color-primary)] transition-all",
|
|
9377
|
+
"flex flex-col"
|
|
8130
9378
|
),
|
|
8131
9379
|
action: "VIEW",
|
|
8132
9380
|
actionPayload: { row: itemData },
|
|
8133
9381
|
children: [
|
|
8134
|
-
|
|
8135
|
-
const
|
|
8136
|
-
if (
|
|
8137
|
-
return /* @__PURE__ */
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
9382
|
+
imageField && (() => {
|
|
9383
|
+
const imgUrl = getNestedValue(itemData, imageField);
|
|
9384
|
+
if (!imgUrl || typeof imgUrl !== "string") return null;
|
|
9385
|
+
return /* @__PURE__ */ jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-[var(--radius-lg)]", children: /* @__PURE__ */ jsx(
|
|
9386
|
+
"img",
|
|
9387
|
+
{
|
|
9388
|
+
src: imgUrl,
|
|
9389
|
+
alt: titleValue !== void 0 ? String(titleValue) : "",
|
|
9390
|
+
className: "w-full h-full object-cover",
|
|
9391
|
+
loading: "lazy"
|
|
9392
|
+
}
|
|
9393
|
+
) });
|
|
9394
|
+
})(),
|
|
9395
|
+
/* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
9396
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
|
|
9397
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "font-semibold truncate", children: String(titleValue) }),
|
|
9398
|
+
statusValue !== void 0 && statusValue !== null && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(statusValue)), children: String(statusValue) }) })
|
|
9399
|
+
] }),
|
|
9400
|
+
dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, actionIdx) => /* @__PURE__ */ jsx(
|
|
8145
9401
|
Button,
|
|
8146
9402
|
{
|
|
8147
|
-
variant:
|
|
9403
|
+
variant: "ghost",
|
|
8148
9404
|
size: "sm",
|
|
8149
|
-
onClick: handleActionClick(action),
|
|
9405
|
+
onClick: handleActionClick(action, itemData),
|
|
8150
9406
|
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
9407
|
+
className: "text-[var(--color-error)] hover:bg-[var(--color-error)]/10 px-2",
|
|
8151
9408
|
children: action.label
|
|
8152
9409
|
},
|
|
8153
9410
|
actionIdx
|
|
8154
|
-
)
|
|
8155
|
-
}) })
|
|
9411
|
+
)) })
|
|
9412
|
+
] }) }),
|
|
9413
|
+
bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
|
|
9414
|
+
const value = getNestedValue(itemData, field);
|
|
9415
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
9416
|
+
const boolVal = asBooleanValue2(value);
|
|
9417
|
+
if (boolVal !== null) {
|
|
9418
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between", children: [
|
|
9419
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: fieldLabel3(field) }),
|
|
9420
|
+
boolVal ? /* @__PURE__ */ jsx(Badge, { variant: "success", children: t("common.yes") || "Yes" }) : /* @__PURE__ */ jsx(Badge, { variant: "neutral", children: t("common.no") || "No" })
|
|
9421
|
+
] }, field);
|
|
9422
|
+
}
|
|
9423
|
+
const displayValue = isDateField(field) ? formatDate3(value) : STATUS_FIELDS.has(field.toLowerCase()) ? void 0 : String(value);
|
|
9424
|
+
if (!displayValue) return null;
|
|
9425
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between", children: [
|
|
9426
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: fieldLabel3(field) }),
|
|
9427
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-right truncate max-w-[60%]", children: displayValue })
|
|
9428
|
+
] }, field);
|
|
9429
|
+
}) }) }),
|
|
9430
|
+
primaryActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 mt-auto border-t border-[var(--color-border)]", children: /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, actionIdx) => /* @__PURE__ */ jsx(
|
|
9431
|
+
Button,
|
|
9432
|
+
{
|
|
9433
|
+
variant: action.variant === "primary" ? "primary" : "ghost",
|
|
9434
|
+
size: "sm",
|
|
9435
|
+
onClick: handleActionClick(action, itemData),
|
|
9436
|
+
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
9437
|
+
children: action.label
|
|
9438
|
+
},
|
|
9439
|
+
actionIdx
|
|
9440
|
+
)) }) })
|
|
8156
9441
|
]
|
|
8157
9442
|
},
|
|
8158
9443
|
id
|
|
@@ -8165,7 +9450,7 @@ var CardGrid = ({
|
|
|
8165
9450
|
{
|
|
8166
9451
|
className: cn(
|
|
8167
9452
|
"grid",
|
|
8168
|
-
|
|
9453
|
+
gapStyles7[gap],
|
|
8169
9454
|
alignStyles4[alignItems],
|
|
8170
9455
|
maxCols === 1 && "grid-cols-1",
|
|
8171
9456
|
maxCols === 2 && "sm:grid-cols-2",
|
|
@@ -8194,7 +9479,7 @@ var CardGrid = ({
|
|
|
8194
9479
|
CardGrid.displayName = "CardGrid";
|
|
8195
9480
|
function MasterDetail({
|
|
8196
9481
|
entity,
|
|
8197
|
-
masterFields
|
|
9482
|
+
masterFields,
|
|
8198
9483
|
detailFields: _detailFields,
|
|
8199
9484
|
// Captured but not used here - detail handled separately
|
|
8200
9485
|
loading: externalLoading,
|
|
@@ -8209,6 +9494,7 @@ function MasterDetail({
|
|
|
8209
9494
|
return /* @__PURE__ */ jsx(
|
|
8210
9495
|
DataTable,
|
|
8211
9496
|
{
|
|
9497
|
+
fields: masterFields,
|
|
8212
9498
|
columns: masterFields,
|
|
8213
9499
|
entity,
|
|
8214
9500
|
isLoading: loading || isLoading,
|
|
@@ -8280,7 +9566,7 @@ function GridPattern({
|
|
|
8280
9566
|
style,
|
|
8281
9567
|
children
|
|
8282
9568
|
}) {
|
|
8283
|
-
return /* @__PURE__ */ jsx(
|
|
9569
|
+
return /* @__PURE__ */ jsx(Grid, { cols, gap, rowGap, colGap, className, style, children });
|
|
8284
9570
|
}
|
|
8285
9571
|
GridPattern.displayName = "GridPattern";
|
|
8286
9572
|
function CenterPattern({
|
|
@@ -8297,14 +9583,14 @@ function SpacerPattern({ size = "flex" }) {
|
|
|
8297
9583
|
if (size === "flex") {
|
|
8298
9584
|
return /* @__PURE__ */ jsx(Spacer, {});
|
|
8299
9585
|
}
|
|
8300
|
-
const
|
|
9586
|
+
const sizeMap5 = {
|
|
8301
9587
|
xs: "0.25rem",
|
|
8302
9588
|
sm: "0.5rem",
|
|
8303
9589
|
md: "1rem",
|
|
8304
9590
|
lg: "1.5rem",
|
|
8305
9591
|
xl: "2rem"
|
|
8306
9592
|
};
|
|
8307
|
-
return /* @__PURE__ */ jsx(Box, { style: { width:
|
|
9593
|
+
return /* @__PURE__ */ jsx(Box, { style: { width: sizeMap5[size], height: sizeMap5[size], flexShrink: 0 } });
|
|
8308
9594
|
}
|
|
8309
9595
|
SpacerPattern.displayName = "SpacerPattern";
|
|
8310
9596
|
function DividerPattern({
|
|
@@ -8408,19 +9694,16 @@ function LinkPattern({
|
|
|
8408
9694
|
emit(`UI:${onClick}`, { href });
|
|
8409
9695
|
}
|
|
8410
9696
|
};
|
|
8411
|
-
return (
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
"
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
children: label
|
|
8422
|
-
}
|
|
8423
|
-
)
|
|
9697
|
+
return /* @__PURE__ */ jsx(
|
|
9698
|
+
"a",
|
|
9699
|
+
{
|
|
9700
|
+
href: href ?? "#",
|
|
9701
|
+
target: external ? "_blank" : void 0,
|
|
9702
|
+
rel: external ? "noopener noreferrer" : void 0,
|
|
9703
|
+
onClick: onClick ? handleClick : void 0,
|
|
9704
|
+
className,
|
|
9705
|
+
children: label
|
|
9706
|
+
}
|
|
8424
9707
|
);
|
|
8425
9708
|
}
|
|
8426
9709
|
LinkPattern.displayName = "LinkPattern";
|
|
@@ -8491,19 +9774,16 @@ function ImagePattern({
|
|
|
8491
9774
|
objectFit = "cover",
|
|
8492
9775
|
className
|
|
8493
9776
|
}) {
|
|
8494
|
-
return (
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
style: { objectFit }
|
|
8505
|
-
}
|
|
8506
|
-
)
|
|
9777
|
+
return /* @__PURE__ */ jsx(
|
|
9778
|
+
"img",
|
|
9779
|
+
{
|
|
9780
|
+
src,
|
|
9781
|
+
alt,
|
|
9782
|
+
width,
|
|
9783
|
+
height,
|
|
9784
|
+
className,
|
|
9785
|
+
style: { objectFit }
|
|
9786
|
+
}
|
|
8507
9787
|
);
|
|
8508
9788
|
}
|
|
8509
9789
|
ImagePattern.displayName = "ImagePattern";
|
|
@@ -8571,7 +9851,7 @@ function InputPattern({
|
|
|
8571
9851
|
className
|
|
8572
9852
|
}) {
|
|
8573
9853
|
const { emit } = useEventBus();
|
|
8574
|
-
const [localValue, setLocalValue] =
|
|
9854
|
+
const [localValue, setLocalValue] = React47__default.useState(value);
|
|
8575
9855
|
const handleChange = (e) => {
|
|
8576
9856
|
setLocalValue(e.target.value);
|
|
8577
9857
|
if (onChange) {
|
|
@@ -8608,7 +9888,7 @@ function TextareaPattern({
|
|
|
8608
9888
|
className
|
|
8609
9889
|
}) {
|
|
8610
9890
|
const { emit } = useEventBus();
|
|
8611
|
-
const [localValue, setLocalValue] =
|
|
9891
|
+
const [localValue, setLocalValue] = React47__default.useState(value);
|
|
8612
9892
|
const handleChange = (e) => {
|
|
8613
9893
|
setLocalValue(e.target.value);
|
|
8614
9894
|
if (onChange) {
|
|
@@ -8639,7 +9919,7 @@ function SelectPattern({
|
|
|
8639
9919
|
className
|
|
8640
9920
|
}) {
|
|
8641
9921
|
const { emit } = useEventBus();
|
|
8642
|
-
const [localValue, setLocalValue] =
|
|
9922
|
+
const [localValue, setLocalValue] = React47__default.useState(value);
|
|
8643
9923
|
const handleChange = (e) => {
|
|
8644
9924
|
setLocalValue(e.target.value);
|
|
8645
9925
|
if (onChange) {
|
|
@@ -8668,7 +9948,7 @@ function CheckboxPattern({
|
|
|
8668
9948
|
className
|
|
8669
9949
|
}) {
|
|
8670
9950
|
const { emit } = useEventBus();
|
|
8671
|
-
const [localChecked, setLocalChecked] =
|
|
9951
|
+
const [localChecked, setLocalChecked] = React47__default.useState(checked);
|
|
8672
9952
|
const handleChange = (e) => {
|
|
8673
9953
|
setLocalChecked(e.target.checked);
|
|
8674
9954
|
if (onChange) {
|
|
@@ -8782,7 +10062,7 @@ function MenuPattern({
|
|
|
8782
10062
|
...item,
|
|
8783
10063
|
onClick: () => emit(`UI:${item.event}`, {})
|
|
8784
10064
|
}));
|
|
8785
|
-
return /* @__PURE__ */ jsx(
|
|
10065
|
+
return /* @__PURE__ */ jsx(Menu, { items: menuItems, trigger, position, className });
|
|
8786
10066
|
}
|
|
8787
10067
|
MenuPattern.displayName = "MenuPattern";
|
|
8788
10068
|
function AccordionPattern({
|
|
@@ -8961,30 +10241,24 @@ function CustomPattern({
|
|
|
8961
10241
|
}
|
|
8962
10242
|
);
|
|
8963
10243
|
case "a":
|
|
8964
|
-
return (
|
|
8965
|
-
|
|
8966
|
-
|
|
8967
|
-
"
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
children: renderContent
|
|
8974
|
-
}
|
|
8975
|
-
)
|
|
10244
|
+
return /* @__PURE__ */ jsx(
|
|
10245
|
+
"a",
|
|
10246
|
+
{
|
|
10247
|
+
href: href ?? "#",
|
|
10248
|
+
target: external ? "_blank" : void 0,
|
|
10249
|
+
rel: external ? "noopener noreferrer" : void 0,
|
|
10250
|
+
...commonProps,
|
|
10251
|
+
children: renderContent
|
|
10252
|
+
}
|
|
8976
10253
|
);
|
|
8977
10254
|
case "img":
|
|
8978
|
-
return (
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
...commonProps
|
|
8986
|
-
}
|
|
8987
|
-
)
|
|
10255
|
+
return /* @__PURE__ */ jsx(
|
|
10256
|
+
"img",
|
|
10257
|
+
{
|
|
10258
|
+
src,
|
|
10259
|
+
alt: alt ?? "",
|
|
10260
|
+
...commonProps
|
|
10261
|
+
}
|
|
8988
10262
|
);
|
|
8989
10263
|
case "input":
|
|
8990
10264
|
return /* @__PURE__ */ jsx(
|
|
@@ -9075,7 +10349,7 @@ function SuspenseConfigProvider({
|
|
|
9075
10349
|
config,
|
|
9076
10350
|
children
|
|
9077
10351
|
}) {
|
|
9078
|
-
return
|
|
10352
|
+
return React47__default.createElement(
|
|
9079
10353
|
SuspenseConfigContext.Provider,
|
|
9080
10354
|
{ value: config },
|
|
9081
10355
|
children
|
|
@@ -9252,6 +10526,9 @@ function UISlotComponent({
|
|
|
9252
10526
|
if (pattern === "clear") {
|
|
9253
10527
|
return null;
|
|
9254
10528
|
}
|
|
10529
|
+
if (isPortalSlot(slot)) {
|
|
10530
|
+
return /* @__PURE__ */ jsx(CompiledPortal, { slot, className, pattern, sourceTrait, children });
|
|
10531
|
+
}
|
|
9255
10532
|
return /* @__PURE__ */ jsx(
|
|
9256
10533
|
Box,
|
|
9257
10534
|
{
|
|
@@ -9302,6 +10579,70 @@ function UISlotComponent({
|
|
|
9302
10579
|
}
|
|
9303
10580
|
);
|
|
9304
10581
|
}
|
|
10582
|
+
function CompiledPortal({ slot, className, pattern, sourceTrait, children }) {
|
|
10583
|
+
const [portalRoot, setPortalRoot] = useState(null);
|
|
10584
|
+
const eventBus = useUISlots();
|
|
10585
|
+
useEffect(() => {
|
|
10586
|
+
let root = document.getElementById("ui-slot-portal-root");
|
|
10587
|
+
if (!root) {
|
|
10588
|
+
root = document.createElement("div");
|
|
10589
|
+
root.id = "ui-slot-portal-root";
|
|
10590
|
+
document.body.appendChild(root);
|
|
10591
|
+
}
|
|
10592
|
+
setPortalRoot(root);
|
|
10593
|
+
}, []);
|
|
10594
|
+
const handleDismiss = () => {
|
|
10595
|
+
eventBus.clear(slot);
|
|
10596
|
+
};
|
|
10597
|
+
if (!portalRoot) return null;
|
|
10598
|
+
let wrapper;
|
|
10599
|
+
switch (slot) {
|
|
10600
|
+
case "modal":
|
|
10601
|
+
wrapper = /* @__PURE__ */ jsx(Modal, { isOpen: true, onClose: handleDismiss, showCloseButton: true, children: /* @__PURE__ */ jsx(
|
|
10602
|
+
Box,
|
|
10603
|
+
{
|
|
10604
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
10605
|
+
"data-pattern": pattern,
|
|
10606
|
+
"data-source-trait": sourceTrait,
|
|
10607
|
+
children
|
|
10608
|
+
}
|
|
10609
|
+
) });
|
|
10610
|
+
break;
|
|
10611
|
+
case "drawer":
|
|
10612
|
+
wrapper = /* @__PURE__ */ jsx(Drawer, { isOpen: true, onClose: handleDismiss, position: "right", children: /* @__PURE__ */ jsx(
|
|
10613
|
+
Box,
|
|
10614
|
+
{
|
|
10615
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
10616
|
+
"data-pattern": pattern,
|
|
10617
|
+
"data-source-trait": sourceTrait,
|
|
10618
|
+
children
|
|
10619
|
+
}
|
|
10620
|
+
) });
|
|
10621
|
+
break;
|
|
10622
|
+
case "toast":
|
|
10623
|
+
wrapper = /* @__PURE__ */ jsx(Box, { className: "fixed top-4 right-4 z-50", children: /* @__PURE__ */ jsx(
|
|
10624
|
+
Box,
|
|
10625
|
+
{
|
|
10626
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
10627
|
+
"data-pattern": pattern,
|
|
10628
|
+
"data-source-trait": sourceTrait,
|
|
10629
|
+
children
|
|
10630
|
+
}
|
|
10631
|
+
) });
|
|
10632
|
+
break;
|
|
10633
|
+
default:
|
|
10634
|
+
wrapper = /* @__PURE__ */ jsx(
|
|
10635
|
+
Box,
|
|
10636
|
+
{
|
|
10637
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
10638
|
+
"data-pattern": pattern,
|
|
10639
|
+
"data-source-trait": sourceTrait,
|
|
10640
|
+
children
|
|
10641
|
+
}
|
|
10642
|
+
);
|
|
10643
|
+
}
|
|
10644
|
+
return createPortal(wrapper, portalRoot);
|
|
10645
|
+
}
|
|
9305
10646
|
function SlotPortal({
|
|
9306
10647
|
slot,
|
|
9307
10648
|
content,
|
|
@@ -9489,4 +10830,4 @@ function UISlotRenderer({
|
|
|
9489
10830
|
}
|
|
9490
10831
|
UISlotRenderer.displayName = "UISlotRenderer";
|
|
9491
10832
|
|
|
9492
|
-
export { Accordion, Alert, Avatar, Badge, Box, Breadcrumb, Button, ButtonGroup, Card, Card2, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Center, Checkbox, CodeBlock, ConditionalWrapper, Container, ControlButton, DataTable, DetailPanel, Divider, Drawer, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FilterGroup, Flex, FloatingActionButton, Form, FormField, FormSectionHeader,
|
|
10833
|
+
export { Accordion, Alert, Avatar, Badge, Box, Breadcrumb, Button, ButtonGroup, CalendarGrid, Card, Card2, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Center, ChartLegend, Checkbox, CodeBlock, ConditionalWrapper, Container, ControlButton, DataGrid, DataList, DataTable, DateRangeSelector, DayCell, DetailPanel, Divider, Drawer, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FilterGroup, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormField, FormSectionHeader, GraphView, Grid, HStack, Heading, HealthBar, Icon, Input, InputGroup, Label, LawReferenceTooltip, LineChart, LoadingState, MarkdownContent, MasterDetail, Menu, Modal, Overlay, PageHeader, Pagination, Popover, ProgressBar, ProgressDots, QuizBlock, Radio, RelationSelect, RepeatableFormSection, ScaledDiagram, ScoreDisplay, SearchInput, Select, SidePanel, SimpleGrid, Skeleton, SlotContentRenderer, Spacer, Spinner, Sprite, Stack, StatCard, StateIndicator, SuspenseConfigProvider, Switch, Tabs, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Toast, Tooltip, Typography, UISlotComponent, UISlotRenderer, VStack, ViolationAlert, WizardNavigation, WizardProgress, drawSprite };
|