@datatechsolutions/ui 3.9.0 → 3.10.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.
Files changed (97) hide show
  1. package/dist/astrlabe/index.js +107 -107
  2. package/dist/astrlabe/index.mjs +3 -3
  3. package/dist/astrlabe/workflow-canvas.js +3 -3
  4. package/dist/astrlabe/workflow-canvas.mjs +2 -2
  5. package/dist/{chunk-ZDXEGSCF.js → chunk-2A45ZEK4.js} +45 -45
  6. package/dist/{chunk-ZDXEGSCF.js.map → chunk-2A45ZEK4.js.map} +1 -1
  7. package/dist/{chunk-T4IYOKHR.js → chunk-5AKTDJFR.js} +25 -25
  8. package/dist/{chunk-T4IYOKHR.js.map → chunk-5AKTDJFR.js.map} +1 -1
  9. package/dist/{chunk-ZQRUAXGP.mjs → chunk-5KI7FB3E.mjs} +188 -48
  10. package/dist/chunk-5KI7FB3E.mjs.map +1 -0
  11. package/dist/{chunk-GQWC4EKE.mjs → chunk-5U43K6G3.mjs} +4 -4
  12. package/dist/{chunk-GQWC4EKE.mjs.map → chunk-5U43K6G3.mjs.map} +1 -1
  13. package/dist/{chunk-PD3JLDA5.mjs → chunk-6UX2SRA2.mjs} +3 -3
  14. package/dist/{chunk-PD3JLDA5.mjs.map → chunk-6UX2SRA2.mjs.map} +1 -1
  15. package/dist/{chunk-2ZY3IQ2I.mjs → chunk-6ZYATZS3.mjs} +3 -3
  16. package/dist/{chunk-2ZY3IQ2I.mjs.map → chunk-6ZYATZS3.mjs.map} +1 -1
  17. package/dist/{chunk-AXBD6OAF.mjs → chunk-A256OE5E.mjs} +11 -11
  18. package/dist/{chunk-AXBD6OAF.mjs.map → chunk-A256OE5E.mjs.map} +1 -1
  19. package/dist/{chunk-DQIEVLA3.js → chunk-AMESLEIO.js} +35 -35
  20. package/dist/{chunk-DQIEVLA3.js.map → chunk-AMESLEIO.js.map} +1 -1
  21. package/dist/{chunk-6E2YH67A.js → chunk-B76RTA7D.js} +35 -35
  22. package/dist/{chunk-6E2YH67A.js.map → chunk-B76RTA7D.js.map} +1 -1
  23. package/dist/{chunk-OVQ4MKCV.mjs → chunk-BU4WMSK3.mjs} +3 -3
  24. package/dist/{chunk-OVQ4MKCV.mjs.map → chunk-BU4WMSK3.mjs.map} +1 -1
  25. package/dist/{chunk-WS3IJFPW.mjs → chunk-C4D3EI5L.mjs} +3 -3
  26. package/dist/{chunk-WS3IJFPW.mjs.map → chunk-C4D3EI5L.mjs.map} +1 -1
  27. package/dist/{chunk-EAIE4QGD.mjs → chunk-DA3H7ERQ.mjs} +20 -20
  28. package/dist/{chunk-EAIE4QGD.mjs.map → chunk-DA3H7ERQ.mjs.map} +1 -1
  29. package/dist/{chunk-U6VFS3RD.js → chunk-EC34PGUO.js} +142 -142
  30. package/dist/{chunk-U6VFS3RD.js.map → chunk-EC34PGUO.js.map} +1 -1
  31. package/dist/{chunk-6QJI5YOJ.mjs → chunk-FD376DZ6.mjs} +3 -3
  32. package/dist/{chunk-6QJI5YOJ.mjs.map → chunk-FD376DZ6.mjs.map} +1 -1
  33. package/dist/{chunk-ZQEMKEEH.mjs → chunk-FENA4YGN.mjs} +3 -3
  34. package/dist/{chunk-ZQEMKEEH.mjs.map → chunk-FENA4YGN.mjs.map} +1 -1
  35. package/dist/{chunk-R6GEJBFC.js → chunk-FIJMOTP4.js} +34 -34
  36. package/dist/{chunk-R6GEJBFC.js.map → chunk-FIJMOTP4.js.map} +1 -1
  37. package/dist/{chunk-BWUFLW5W.mjs → chunk-H7X3SXMB.mjs} +6 -6
  38. package/dist/{chunk-BWUFLW5W.mjs.map → chunk-H7X3SXMB.mjs.map} +1 -1
  39. package/dist/{chunk-OEZ7GAJY.mjs → chunk-HEXTU6W3.mjs} +6 -6
  40. package/dist/{chunk-OEZ7GAJY.mjs.map → chunk-HEXTU6W3.mjs.map} +1 -1
  41. package/dist/{chunk-2E7HYTS7.mjs → chunk-JB3U6ORY.mjs} +3 -3
  42. package/dist/{chunk-2E7HYTS7.mjs.map → chunk-JB3U6ORY.mjs.map} +1 -1
  43. package/dist/{chunk-A2RIX2RK.js → chunk-KHUWFL6W.js} +4 -4
  44. package/dist/{chunk-A2RIX2RK.js.map → chunk-KHUWFL6W.js.map} +1 -1
  45. package/dist/{chunk-CRBGZA6Y.js → chunk-L3R425GB.js} +13 -13
  46. package/dist/{chunk-CRBGZA6Y.js.map → chunk-L3R425GB.js.map} +1 -1
  47. package/dist/{chunk-MT66VKLS.js → chunk-LVR4SR65.js} +189 -47
  48. package/dist/chunk-LVR4SR65.js.map +1 -0
  49. package/dist/{chunk-UZIICTIY.js → chunk-MAOZWOA6.js} +55 -55
  50. package/dist/{chunk-UZIICTIY.js.map → chunk-MAOZWOA6.js.map} +1 -1
  51. package/dist/{chunk-WJENX6KB.js → chunk-MSMEECO6.js} +9 -9
  52. package/dist/{chunk-WJENX6KB.js.map → chunk-MSMEECO6.js.map} +1 -1
  53. package/dist/{chunk-SJ6SUS7H.mjs → chunk-NM37GLCL.mjs} +3 -3
  54. package/dist/{chunk-SJ6SUS7H.mjs.map → chunk-NM37GLCL.mjs.map} +1 -1
  55. package/dist/{chunk-CLTNCBSP.js → chunk-NSZN54HW.js} +4 -4
  56. package/dist/{chunk-CLTNCBSP.js.map → chunk-NSZN54HW.js.map} +1 -1
  57. package/dist/{chunk-7AM2SXEF.js → chunk-O4HH77A4.js} +85 -85
  58. package/dist/{chunk-7AM2SXEF.js.map → chunk-O4HH77A4.js.map} +1 -1
  59. package/dist/{chunk-RFUSH7WD.js → chunk-TSNKICPP.js} +10 -10
  60. package/dist/{chunk-RFUSH7WD.js.map → chunk-TSNKICPP.js.map} +1 -1
  61. package/dist/{chunk-ARLYOLSO.mjs → chunk-W6MBDTKF.mjs} +3 -3
  62. package/dist/{chunk-ARLYOLSO.mjs.map → chunk-W6MBDTKF.mjs.map} +1 -1
  63. package/dist/{chunk-IVKFXPLO.js → chunk-YSYEV2Z6.js} +28 -28
  64. package/dist/{chunk-IVKFXPLO.js.map → chunk-YSYEV2Z6.js.map} +1 -1
  65. package/dist/index.d.mts +108 -4
  66. package/dist/index.d.ts +108 -4
  67. package/dist/index.js +670 -662
  68. package/dist/index.mjs +1 -1
  69. package/dist/platform/admin/index.js +9 -9
  70. package/dist/platform/admin/index.mjs +3 -3
  71. package/dist/platform/agents-workspace.js +6 -6
  72. package/dist/platform/agents-workspace.mjs +5 -5
  73. package/dist/platform/app-shell.js +3 -3
  74. package/dist/platform/app-shell.mjs +2 -2
  75. package/dist/platform/auth/index.js +21 -21
  76. package/dist/platform/auth/index.mjs +3 -3
  77. package/dist/platform/billing/index.js +3 -3
  78. package/dist/platform/billing/index.mjs +2 -2
  79. package/dist/platform/impersonation/index.js +3 -3
  80. package/dist/platform/impersonation/index.mjs +2 -2
  81. package/dist/platform/index.d.mts +1 -1
  82. package/dist/platform/index.d.ts +1 -1
  83. package/dist/platform/index.js +74 -74
  84. package/dist/platform/index.mjs +17 -17
  85. package/dist/platform/pages/index.d.mts +235 -3
  86. package/dist/platform/pages/index.d.ts +235 -3
  87. package/dist/platform/pages/index.js +1988 -281
  88. package/dist/platform/pages/index.js.map +1 -1
  89. package/dist/platform/pages/index.mjs +1758 -53
  90. package/dist/platform/pages/index.mjs.map +1 -1
  91. package/dist/platform/settings/index.js +6 -6
  92. package/dist/platform/settings/index.mjs +5 -5
  93. package/dist/platform/workflow-canvas-shell.js +4 -4
  94. package/dist/platform/workflow-canvas-shell.mjs +3 -3
  95. package/package.json +1 -1
  96. package/dist/chunk-MT66VKLS.js.map +0 -1
  97. package/dist/chunk-ZQRUAXGP.mjs.map +0 -1
@@ -1,14 +1,14 @@
1
1
  "use client";
2
2
  import { adaptWorkflowGraphToUi, formatDurationMs } from '../../chunk-UQXVCVAN.mjs';
3
- import { WorkflowWorkspace } from '../../chunk-GQWC4EKE.mjs';
4
- export { RolesPageView, UsersPageView } from '../../chunk-GQWC4EKE.mjs';
5
- import { DatasourceModal, findCategory, DIALECT_CATEGORIES } from '../../chunk-6QJI5YOJ.mjs';
6
- export { DIALECT_CATEGORIES, DatasourceFormModal, DatasourceModal, findCategory, findDialect } from '../../chunk-6QJI5YOJ.mjs';
7
- import { defaultRuleForm, RuleForm, ExecutionTimelinePanel } from '../../chunk-AXBD6OAF.mjs';
3
+ import { WorkflowWorkspace } from '../../chunk-5U43K6G3.mjs';
4
+ export { RolesPageView, UsersPageView } from '../../chunk-5U43K6G3.mjs';
5
+ import { DatasourceModal, findDialect, findCategory, DIALECT_CATEGORIES } from '../../chunk-FD376DZ6.mjs';
6
+ export { DIALECT_CATEGORIES, DatasourceFormModal, DatasourceModal, findCategory, findDialect } from '../../chunk-FD376DZ6.mjs';
7
+ import { defaultRuleForm, RuleForm, ExecutionTimelinePanel, defaultRuleCondition, defaultRuleAction, RuleConditionBuilder, RuleActionBuilder } from '../../chunk-A256OE5E.mjs';
8
8
  import '../../chunk-JB6RNAD2.mjs';
9
9
  import '../../chunk-LEXBTVGM.mjs';
10
- import '../../chunk-EAIE4QGD.mjs';
11
- import { HeroSection, PageLoadingState, PageEmptyState, SearchBar, EntityCard, CreateActionButton, GlassModal, FormGrid, FormSelect, FormInput, FormTextarea, SectionHeader, Text, Form, FormActionsRow, Table, TableHead, TableRow, TableHeader, TableBody, TableCell, InlineForm, CopyableId, ListCard, ListCardItem, Avatar, SectionCard, Tabs, TabsList, TabsTrigger, TabsContent, StepTimeline } from '../../chunk-ZQRUAXGP.mjs';
10
+ import '../../chunk-DA3H7ERQ.mjs';
11
+ import { HeroSection, PageLoadingState, PageEmptyState, SearchBar, EntityCard, CreateActionButton, GlassModal, FormGrid, FormSelect, FormInput, FormTextarea, SectionHeader, Text, Form, FormActionsRow, Table, TableHead, TableRow, TableHeader, TableBody, TableCell, InlineForm, CopyableId, ListCard, ListCardItem, Avatar, SectionCard, Tabs, TabsList, TabsTrigger, TabsContent, StepTimeline, FilterTileButton, FormToggle, Spinner, StatusBadge, FormCheckbox, SegmentedControl, DatePicker, TimePicker } from '../../chunk-5KI7FB3E.mjs';
12
12
  import '../../chunk-7VJ7CMMT.mjs';
13
13
  import '../../chunk-RHRJXK5R.mjs';
14
14
  import '../../chunk-3AY5HIQ6.mjs';
@@ -18,7 +18,7 @@ import '../../chunk-D2JF6C3E.mjs';
18
18
  import { useLink } from '../../chunk-QWG2FMUN.mjs';
19
19
  import '../../chunk-G7JQ4OCE.mjs';
20
20
  import { useState, useMemo, useEffect, useCallback } from 'react';
21
- import { CubeTransparentIcon, CpuChipIcon, ChatBubbleLeftEllipsisIcon, WrenchScrewdriverIcon, AdjustmentsHorizontalIcon, CircleStackIcon, RectangleStackIcon, ClockIcon, LinkIcon, KeyIcon, ArrowPathIcon, TrashIcon, PlusIcon, PencilSquareIcon } from '@heroicons/react/24/outline';
21
+ import { CubeTransparentIcon, CpuChipIcon, ChatBubbleLeftEllipsisIcon, WrenchScrewdriverIcon, AdjustmentsHorizontalIcon, CircleStackIcon, RectangleStackIcon, ClockIcon, LinkIcon, KeyIcon, ArrowPathIcon, TrashIcon, PlusIcon, PencilSquareIcon, BellAlertIcon, GlobeAltIcon, PencilIcon, ArrowUpCircleIcon, SparklesIcon } from '@heroicons/react/24/outline';
22
22
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
23
23
 
24
24
  function AgentsModelsPageView({ labels, models, loading }) {
@@ -944,8 +944,12 @@ function setFromJson(set, key, raw) {
944
944
  set(key, raw);
945
945
  }
946
946
  }
947
- function RulesPageView({ labels, rules, loading, onCreate, onUpdate, onDelete }) {
947
+ function RulesPageView({ labels, rules, loading, onCreate, onUpdate, onDelete, onAddClick }) {
948
948
  const [createOpen, setCreateOpen] = useState(false);
949
+ const openCreate = () => {
950
+ if (onAddClick) onAddClick();
951
+ else setCreateOpen(true);
952
+ };
949
953
  const [editing, setEditing] = useState(null);
950
954
  const [searchTerm, setSearchTerm] = useState("");
951
955
  const allRules = rules;
@@ -964,7 +968,7 @@ function RulesPageView({ labels, rules, loading, onCreate, onUpdate, onDelete })
964
968
  {
965
969
  mode: "desktop",
966
970
  label: labels.addRule,
967
- onClick: () => setCreateOpen(true),
971
+ onClick: openCreate,
968
972
  accent: "fuchsia"
969
973
  }
970
974
  )
@@ -975,7 +979,7 @@ function RulesPageView({ labels, rules, loading, onCreate, onUpdate, onDelete })
975
979
  {
976
980
  mode: "mobile",
977
981
  label: labels.addRule,
978
- onClick: () => setCreateOpen(true),
982
+ onClick: openCreate,
979
983
  accent: "fuchsia"
980
984
  }
981
985
  );
@@ -1259,9 +1263,14 @@ function DatasourcesPageView({
1259
1263
  labels,
1260
1264
  datasources: externalDatasources,
1261
1265
  useSampleData = false,
1262
- onCreate
1266
+ onCreate,
1267
+ onAddClick
1263
1268
  }) {
1264
1269
  const [modalOpen, setModalOpen] = useState(false);
1270
+ const openCreate = () => {
1271
+ if (onAddClick) onAddClick();
1272
+ else setModalOpen(true);
1273
+ };
1265
1274
  const [searchTerm, setSearchTerm] = useState("");
1266
1275
  const [localDatasources, setLocalDatasources] = useState(
1267
1276
  useSampleData ? SAMPLE_DATASOURCES : []
@@ -1306,7 +1315,7 @@ function DatasourcesPageView({
1306
1315
  {
1307
1316
  mode: "desktop",
1308
1317
  label: labels.addDatasource,
1309
- onClick: () => setModalOpen(true),
1318
+ onClick: openCreate,
1310
1319
  accent: "amber"
1311
1320
  }
1312
1321
  )
@@ -1317,7 +1326,7 @@ function DatasourcesPageView({
1317
1326
  {
1318
1327
  mode: "mobile",
1319
1328
  label: labels.addDatasource,
1320
- onClick: () => setModalOpen(true),
1329
+ onClick: openCreate,
1321
1330
  accent: "amber"
1322
1331
  }
1323
1332
  ),
@@ -2796,12 +2805,12 @@ function deriveInitials(name) {
2796
2805
  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
2797
2806
  }
2798
2807
  var AGENT_PRESETS = [
2799
- { id: "sales", emoji: "\u{1F4BC}", name: "Sales Specialist", role: "Lead qualification & CRM", systemPrompt: "You are a sales assistant. Help qualify leads, manage CRM entries, and schedule follow-ups. Always be professional and proactive.", temperature: 0.7, maxTokens: 2048, accent: "from-emerald-500 to-teal-600", framework: "anthropic" },
2800
- { id: "support", emoji: "\u{1F3A7}", name: "Customer Support", role: "Ticket resolution & escalation", systemPrompt: "You are a customer support agent. Resolve tickets, answer questions, and escalate complex issues. Prioritize customer satisfaction.", temperature: 0.3, maxTokens: 2048, accent: "from-sky-500 to-indigo-600", framework: "crewai" },
2801
- { id: "finance", emoji: "\u{1F4CA}", name: "Financial Analyst", role: "Revenue, margins, reports", systemPrompt: "You are a financial analyst. Analyze revenue, calculate margins, generate performance reports, and identify trends. Use data-driven insights for recommendations.", temperature: 0.4, maxTokens: 4096, accent: "from-amber-500 to-orange-600", framework: "langchain" },
2802
- { id: "security", emoji: "\u{1F6E1}\uFE0F", name: "Security Analyst", role: "Threat monitoring & compliance", systemPrompt: "You are a security analyst. Monitor for threats, audit data access, ensure compliance with privacy regulations, and manage incident response.", temperature: 0.3, maxTokens: 2048, accent: "from-rose-500 to-red-600", framework: "anthropic" },
2803
- { id: "data", emoji: "\u{1F52C}", name: "Data Analyst", role: "Pattern detection & cleaning", systemPrompt: "You are a data analyst. Process raw data inputs, identify patterns, clean datasets, and prepare structured analysis for downstream agents.", temperature: 0.5, maxTokens: 4096, accent: "from-violet-500 to-purple-600", framework: "google-adk" },
2804
- { id: "custom", emoji: "\u2728", name: "", role: "", systemPrompt: "", temperature: 0.2, maxTokens: 2048, accent: "from-slate-500 to-slate-700" }
2808
+ { id: "sales", emoji: "\u{1F4BC}", name: "Sales Specialist", role: "Lead qualification & CRM", systemPrompt: "You are a sales assistant. Help qualify leads, manage CRM entries, and schedule follow-ups. Always be professional and proactive.", temperature: 0.7, maxTokens: 2048, accent: "from-emerald-500 to-teal-600", framework: "anthropic", tileColor: "emerald" },
2809
+ { id: "support", emoji: "\u{1F3A7}", name: "Customer Support", role: "Ticket resolution & escalation", systemPrompt: "You are a customer support agent. Resolve tickets, answer questions, and escalate complex issues. Prioritize customer satisfaction.", temperature: 0.3, maxTokens: 2048, accent: "from-sky-500 to-indigo-600", framework: "crewai", tileColor: "sky" },
2810
+ { id: "finance", emoji: "\u{1F4CA}", name: "Financial Analyst", role: "Revenue, margins, reports", systemPrompt: "You are a financial analyst. Analyze revenue, calculate margins, generate performance reports, and identify trends. Use data-driven insights for recommendations.", temperature: 0.4, maxTokens: 4096, accent: "from-amber-500 to-orange-600", framework: "langchain", tileColor: "amber" },
2811
+ { id: "security", emoji: "\u{1F6E1}\uFE0F", name: "Security Analyst", role: "Threat monitoring & compliance", systemPrompt: "You are a security analyst. Monitor for threats, audit data access, ensure compliance with privacy regulations, and manage incident response.", temperature: 0.3, maxTokens: 2048, accent: "from-rose-500 to-red-600", framework: "anthropic", tileColor: "rose" },
2812
+ { id: "data", emoji: "\u{1F52C}", name: "Data Analyst", role: "Pattern detection & cleaning", systemPrompt: "You are a data analyst. Process raw data inputs, identify patterns, clean datasets, and prepare structured analysis for downstream agents.", temperature: 0.5, maxTokens: 4096, accent: "from-violet-500 to-purple-600", framework: "google-adk", tileColor: "violet" },
2813
+ { id: "custom", emoji: "\u2728", name: "", role: "", systemPrompt: "", temperature: 0.2, maxTokens: 2048, accent: "from-slate-500 to-slate-700", tileColor: "slate" }
2805
2814
  ];
2806
2815
  var DIFFICULTY_OPTIONS = [
2807
2816
  { id: "beginner", emoji: "\u{1F331}", accent: "from-emerald-500 to-teal-600" },
@@ -2820,14 +2829,14 @@ function RangeSliderField({
2820
2829
  step,
2821
2830
  zones,
2822
2831
  trackGradient,
2823
- formatValue,
2832
+ formatValue: formatValue2,
2824
2833
  ariaLabel
2825
2834
  }) {
2826
2835
  const percent = (value - min) / (max - min) * 100;
2827
2836
  const activeZone = zones?.find((z) => value <= z.max) ?? zones?.[zones.length - 1];
2828
2837
  const thumbColor = activeZone?.thumbColor ?? "#6366f1";
2829
2838
  const glow = hexToGlow(thumbColor);
2830
- const displayValue = formatValue ? formatValue(value) : value.toString();
2839
+ const displayValue = formatValue2 ? formatValue2(value) : value.toString();
2831
2840
  const ariaText = activeZone ? `${displayValue} \u2014 ${activeZone.label}` : displayValue;
2832
2841
  return /* @__PURE__ */ jsxs("div", { children: [
2833
2842
  /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between", children: [
@@ -3085,35 +3094,29 @@ function AgentNewWizardPageView({
3085
3094
  title: labels.presetTitle,
3086
3095
  subtitle: labels.presetSubtitle
3087
3096
  },
3088
- children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3", children: AGENT_PRESETS.map((preset) => {
3089
- const selected = preset.id === presetId;
3090
- return /* @__PURE__ */ jsxs(
3091
- "button",
3092
- {
3093
- type: "button",
3094
- onClick: () => applyPreset(preset),
3095
- className: [
3096
- "liquid-surface group flex items-center gap-3 rounded-xl px-3 py-2.5 text-left transition-all",
3097
- selected ? "ring-2 ring-indigo-500/70 ring-offset-1 ring-offset-transparent" : "hover:border-indigo-400/40 focus-visible:ring-2 focus-visible:ring-indigo-500/70 focus-visible:ring-offset-1"
3098
- ].join(" "),
3099
- children: [
3100
- /* @__PURE__ */ jsx(
3101
- "span",
3102
- {
3103
- "aria-hidden": "true",
3104
- className: `flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-gradient-to-br ${preset.accent} text-base shadow-sm`,
3105
- children: preset.emoji
3106
- }
3107
- ),
3108
- /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
3109
- /* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-semibold text-slate-900 dark:text-white", children: preset.id === "custom" ? labels.presetCustom : preset.name }),
3110
- /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-slate-500 dark:text-slate-400", children: preset.role || labels.presetCustomHint })
3111
- ] })
3112
- ]
3113
- },
3114
- preset.id
3115
- );
3116
- }) })
3097
+ children: /* @__PURE__ */ jsx(
3098
+ "div",
3099
+ {
3100
+ role: "radiogroup",
3101
+ "aria-label": labels.presetTitle,
3102
+ className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",
3103
+ children: AGENT_PRESETS.map((preset) => {
3104
+ const selected = preset.id === presetId;
3105
+ return /* @__PURE__ */ jsx(
3106
+ FilterTileButton,
3107
+ {
3108
+ isActive: selected,
3109
+ color: preset.tileColor,
3110
+ icon: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-base leading-none", children: preset.emoji }),
3111
+ label: preset.id === "custom" ? labels.presetCustom : preset.name,
3112
+ count: preset.role || labels.presetCustomHint,
3113
+ onClick: () => applyPreset(preset)
3114
+ },
3115
+ preset.id
3116
+ );
3117
+ })
3118
+ }
3119
+ )
3117
3120
  }
3118
3121
  );
3119
3122
  }
@@ -3604,7 +3607,7 @@ function AgentNewWizardPageView({
3604
3607
  }
3605
3608
  }
3606
3609
  ),
3607
- /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-3xl space-y-5", children: [
3610
+ /* @__PURE__ */ jsxs("div", { className: "w-full space-y-5", children: [
3608
3611
  stepBody,
3609
3612
  footer
3610
3613
  ] })
@@ -3622,7 +3625,1709 @@ function ReviewRow({ label, value }) {
3622
3625
  /* @__PURE__ */ jsx("dd", { className: "mt-0.5 truncate text-xs font-semibold text-gray-900 dark:text-white", children: value })
3623
3626
  ] });
3624
3627
  }
3628
+ var DIALECT_LOGO_SRC = {
3629
+ bigquery: "/logos/datasources/bigquery.svg",
3630
+ postgres: "/logos/datasources/postgres.svg",
3631
+ postgresql: "/logos/datasources/postgres.svg",
3632
+ mysql: "/logos/datasources/mysql.svg",
3633
+ mariadb: "/logos/datasources/mariadb.svg",
3634
+ snowflake: "/logos/datasources/snowflake.svg",
3635
+ mongodb: "/logos/datasources/mongodb.svg",
3636
+ redis: "/logos/datasources/redis.svg",
3637
+ clickhouse: "/logos/datasources/clickhouse.svg",
3638
+ elasticsearch: "/logos/datasources/elasticsearch.svg",
3639
+ duckdb: "/logos/datasources/duckdb.svg",
3640
+ sqlite: "/logos/datasources/sqlite.svg",
3641
+ oracle: "/logos/datasources/oracle.svg",
3642
+ mssql: "/logos/datasources/mssql.svg",
3643
+ sqlserver: "/logos/datasources/mssql.svg",
3644
+ cassandra: "/logos/datasources/cassandra.svg",
3645
+ dynamodb: "/logos/datasources/dynamodb.svg",
3646
+ cockroach: "/logos/datasources/cockroachdb.svg",
3647
+ cockroachdb: "/logos/datasources/cockroachdb.svg",
3648
+ supabase: "/logos/datasources/supabase.svg",
3649
+ firebase: "/logos/datasources/firebase.svg",
3650
+ neo4j: "/logos/datasources/neo4j.svg",
3651
+ neptune: "/logos/datasources/neptune.svg",
3652
+ timestream: "/logos/datasources/timestream.svg",
3653
+ opensearch: "/logos/datasources/opensearch.svg"
3654
+ };
3655
+ var CATEGORY_COLOR = {
3656
+ relational: "blue",
3657
+ nosql: "emerald",
3658
+ warehouse: "purple",
3659
+ timeseries: "sky",
3660
+ graph: "pink",
3661
+ keyvalue: "red",
3662
+ search: "amber"
3663
+ };
3664
+ var TOTAL_STEPS2 = 4;
3665
+ function DatasourceNewWizardPageView({
3666
+ labels,
3667
+ initialStep,
3668
+ onStepChange,
3669
+ onSubmit,
3670
+ onCancel,
3671
+ onTestConnection
3672
+ }) {
3673
+ const clampedInitial = Math.min(TOTAL_STEPS2, Math.max(1, initialStep ?? 1));
3674
+ const [step, setStep] = useState(clampedInitial);
3675
+ const [dialect, setDialect] = useState("");
3676
+ const [name, setName] = useState("");
3677
+ const [host, setHost] = useState("");
3678
+ const [port, setPort] = useState("");
3679
+ const [database, setDatabase] = useState("");
3680
+ const [username, setUsername] = useState("");
3681
+ const [password, setPassword] = useState("");
3682
+ const [schema, setSchema] = useState("");
3683
+ const [connectionString, setConnectionString] = useState("");
3684
+ const [projectId, setProjectId] = useState("");
3685
+ const [dataset, setDataset] = useState("");
3686
+ const [keyFile, setKeyFile] = useState("");
3687
+ const [account, setAccount] = useState("");
3688
+ const [warehouseField, setWarehouseField] = useState("");
3689
+ const [region, setRegion] = useState("");
3690
+ const [bucket, setBucket] = useState("");
3691
+ const [token, setToken] = useState("");
3692
+ const [apiKey, setApiKey] = useState("");
3693
+ const [environment, setEnvironment] = useState("");
3694
+ const [index, setIndex] = useState("");
3695
+ const [ssl, setSsl] = useState(true);
3696
+ const [readOnly, setReadOnly] = useState(true);
3697
+ const [maxPoolSize, setMaxPoolSize] = useState("5");
3698
+ const [timeoutMs, setTimeoutMs] = useState("5000");
3699
+ const [allowedTables, setAllowedTables] = useState("");
3700
+ const [blockedColumns, setBlockedColumns] = useState("");
3701
+ const [maskPii, setMaskPii] = useState(false);
3702
+ const [submitting, setSubmitting] = useState(false);
3703
+ const [touched, setTouched] = useState(false);
3704
+ const [testStatus, setTestStatus] = useState("idle");
3705
+ const dialectOption = useMemo(() => dialect ? findDialect(dialect) : null, [dialect]);
3706
+ const category = useMemo(() => dialect ? findCategory(dialect) : null, [dialect]);
3707
+ useEffect(() => {
3708
+ if (dialectOption?.defaultPort && (port === "" || /^[0-9]+$/.test(port))) {
3709
+ setPort(String(dialectOption.defaultPort));
3710
+ }
3711
+ }, [dialect]);
3712
+ useEffect(() => {
3713
+ const next = Math.min(TOTAL_STEPS2, Math.max(1, initialStep ?? 1));
3714
+ if (next !== step) setStep(next);
3715
+ }, [initialStep]);
3716
+ function markTouched() {
3717
+ if (!touched) setTouched(true);
3718
+ }
3719
+ const goToStep = useCallback((next) => {
3720
+ const clamped = Math.min(TOTAL_STEPS2, Math.max(1, next));
3721
+ setStep(clamped);
3722
+ onStepChange?.(clamped);
3723
+ }, [onStepChange]);
3724
+ function canAdvance(from) {
3725
+ if (from === 1) return Boolean(dialect);
3726
+ if (from === 2) return name.trim().length > 0;
3727
+ return true;
3728
+ }
3729
+ const goNext = useCallback(() => {
3730
+ if (!canAdvance(step)) return;
3731
+ if (step < TOTAL_STEPS2) goToStep(step + 1);
3732
+ }, [step, dialect, name]);
3733
+ const goBack = useCallback(() => {
3734
+ if (step > 1) goToStep(step - 1);
3735
+ }, [step, goToStep]);
3736
+ const cancelWithConfirm = useCallback(() => {
3737
+ if (touched && !window.confirm(labels.wizardCancelConfirm)) return;
3738
+ onCancel();
3739
+ }, [touched, labels.wizardCancelConfirm, onCancel]);
3740
+ function buildPayload() {
3741
+ const payload = {
3742
+ name: name.trim(),
3743
+ dialect,
3744
+ ssl,
3745
+ readOnly
3746
+ };
3747
+ if (host.trim()) payload.host = host.trim();
3748
+ const portNum = Number(port);
3749
+ if (Number.isFinite(portNum) && portNum > 0) payload.port = portNum;
3750
+ if (database.trim()) payload.database = database.trim();
3751
+ if (username.trim()) payload.username = username.trim();
3752
+ if (password) payload.password = password;
3753
+ if (schema.trim()) payload.schema = schema.trim();
3754
+ if (connectionString.trim()) payload.connectionString = connectionString.trim();
3755
+ if (projectId.trim()) payload.projectId = projectId.trim();
3756
+ if (dataset.trim()) payload.dataset = dataset.trim();
3757
+ if (keyFile.trim()) payload.keyFile = keyFile.trim();
3758
+ if (account.trim()) payload.account = account.trim();
3759
+ if (warehouseField.trim()) payload.warehouse = warehouseField.trim();
3760
+ if (region.trim()) payload.region = region.trim();
3761
+ if (bucket.trim()) payload.bucket = bucket.trim();
3762
+ if (token) payload.token = token;
3763
+ if (apiKey) payload.apiKey = apiKey;
3764
+ if (environment.trim()) payload.environment = environment.trim();
3765
+ if (index.trim()) payload.index = index.trim();
3766
+ const pool = Number(maxPoolSize);
3767
+ if (Number.isFinite(pool) && pool > 0) payload.maxPoolSize = pool;
3768
+ const timeout = Number(timeoutMs);
3769
+ if (Number.isFinite(timeout) && timeout > 0) payload.timeoutMs = timeout;
3770
+ const allowed = splitList(allowedTables);
3771
+ if (allowed.length > 0) payload.allowedTables = allowed;
3772
+ const blocked = splitList(blockedColumns);
3773
+ if (blocked.length > 0) payload.blockedColumns = blocked;
3774
+ return payload;
3775
+ }
3776
+ async function handleTestConnection() {
3777
+ setTestStatus("testing");
3778
+ try {
3779
+ const ok = onTestConnection ? await onTestConnection(buildPayload()) : await simulateTest();
3780
+ setTestStatus(ok ? "success" : "failed");
3781
+ setTimeout(() => setTestStatus("idle"), 3500);
3782
+ } catch {
3783
+ setTestStatus("failed");
3784
+ setTimeout(() => setTestStatus("idle"), 3500);
3785
+ }
3786
+ }
3787
+ async function submit() {
3788
+ setSubmitting(true);
3789
+ try {
3790
+ const payload = {
3791
+ ...buildPayload(),
3792
+ ...maskPii ? { maskPii: true } : {}
3793
+ };
3794
+ await onSubmit(payload);
3795
+ } finally {
3796
+ setSubmitting(false);
3797
+ }
3798
+ }
3799
+ useEffect(() => {
3800
+ function onKey(e) {
3801
+ if (e.key === "Escape") {
3802
+ e.preventDefault();
3803
+ cancelWithConfirm();
3804
+ return;
3805
+ }
3806
+ if (e.key === "Enter") {
3807
+ const target = e.target;
3808
+ const tag = target?.tagName?.toLowerCase();
3809
+ if (tag === "textarea" || tag === "select" || tag === "input" || tag === "button") return;
3810
+ e.preventDefault();
3811
+ if (step < TOTAL_STEPS2) goNext();
3812
+ else void submit();
3813
+ }
3814
+ }
3815
+ window.addEventListener("keydown", onKey);
3816
+ return () => window.removeEventListener("keydown", onKey);
3817
+ }, [step, dialect, name, touched]);
3818
+ const stepTitles = [
3819
+ labels.wizardStep1Title,
3820
+ labels.wizardStep2Title,
3821
+ labels.wizardStep3Title,
3822
+ labels.wizardStep4Title
3823
+ ];
3824
+ const stepSubtitles = [
3825
+ labels.wizardStep1Subtitle,
3826
+ labels.wizardStep2Subtitle,
3827
+ labels.wizardStep3Subtitle,
3828
+ labels.wizardStep4Subtitle
3829
+ ];
3830
+ const timelineSteps = stepTitles.map((title, idx) => ({
3831
+ id: String(idx + 1),
3832
+ name: title,
3833
+ description: stepSubtitles[idx],
3834
+ status: idx + 1 < step ? "complete" : idx + 1 === step ? "current" : "upcoming"
3835
+ }));
3836
+ const counter = labels.wizardStepCounter.replace("{current}", String(step)).replace("{total}", String(TOTAL_STEPS2));
3837
+ const hero = /* @__PURE__ */ jsx(
3838
+ HeroSection,
3839
+ {
3840
+ icon: /* @__PURE__ */ jsx(CircleStackIcon, { className: "h-5 w-5" }),
3841
+ label: counter,
3842
+ title: labels.pageTitle,
3843
+ subtitle: stepSubtitles[step - 1] ?? labels.pageSubtitle,
3844
+ gradient: category?.gradient ?? "from-amber-500 to-orange-600"
3845
+ }
3846
+ );
3847
+ function renderStep1() {
3848
+ return /* @__PURE__ */ jsx("div", { className: "space-y-6", children: DIALECT_CATEGORIES.map((cat) => {
3849
+ const color = CATEGORY_COLOR[cat.id] ?? "slate";
3850
+ const categoryLabel = labels[cat.labelKey] ?? cat.id;
3851
+ return /* @__PURE__ */ jsx(
3852
+ SectionCard,
3853
+ {
3854
+ variant: "glass",
3855
+ header: {
3856
+ title: categoryLabel,
3857
+ icon: /* @__PURE__ */ jsx(cat.icon, { className: "h-4 w-4" }),
3858
+ gradient: cat.gradient
3859
+ },
3860
+ children: /* @__PURE__ */ jsx(
3861
+ "div",
3862
+ {
3863
+ role: "radiogroup",
3864
+ "aria-label": categoryLabel,
3865
+ className: "grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-4",
3866
+ children: cat.dialects.map((opt) => {
3867
+ const selected = opt.value === dialect;
3868
+ const logoSrc = DIALECT_LOGO_SRC[opt.value.toLowerCase()];
3869
+ return /* @__PURE__ */ jsx(
3870
+ FilterTileButton,
3871
+ {
3872
+ isActive: selected,
3873
+ color,
3874
+ icon: logoSrc ? /* @__PURE__ */ jsx("img", { src: logoSrc, alt: opt.label, className: "h-5 w-5 object-contain" }) : /* @__PURE__ */ jsx(CircleStackIcon, { className: "h-5 w-5" }),
3875
+ label: opt.label,
3876
+ count: opt.formType.replace("-", " "),
3877
+ onClick: () => {
3878
+ setDialect(opt.value);
3879
+ markTouched();
3880
+ }
3881
+ },
3882
+ opt.value
3883
+ );
3884
+ })
3885
+ }
3886
+ )
3887
+ },
3888
+ cat.id
3889
+ );
3890
+ }) });
3891
+ }
3892
+ function renderConnectionFields() {
3893
+ if (!dialectOption) return null;
3894
+ switch (dialectOption.formType) {
3895
+ case "standard":
3896
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3897
+ /* @__PURE__ */ jsx(
3898
+ FormInput,
3899
+ {
3900
+ label: labels.fieldHost,
3901
+ value: host,
3902
+ onValueChange: (v) => {
3903
+ setHost(v);
3904
+ markTouched();
3905
+ },
3906
+ placeholder: labels.fieldHostPlaceholder,
3907
+ required: true
3908
+ }
3909
+ ),
3910
+ /* @__PURE__ */ jsx(
3911
+ FormInput,
3912
+ {
3913
+ label: labels.fieldPort,
3914
+ type: "number",
3915
+ value: port,
3916
+ onValueChange: (v) => {
3917
+ setPort(v);
3918
+ markTouched();
3919
+ }
3920
+ }
3921
+ ),
3922
+ /* @__PURE__ */ jsx(
3923
+ FormInput,
3924
+ {
3925
+ label: labels.fieldDatabase,
3926
+ value: database,
3927
+ onValueChange: (v) => {
3928
+ setDatabase(v);
3929
+ markTouched();
3930
+ },
3931
+ placeholder: labels.fieldDatabasePlaceholder,
3932
+ required: true
3933
+ }
3934
+ ),
3935
+ /* @__PURE__ */ jsx(
3936
+ FormInput,
3937
+ {
3938
+ label: labels.fieldUsername,
3939
+ value: username,
3940
+ onValueChange: (v) => {
3941
+ setUsername(v);
3942
+ markTouched();
3943
+ },
3944
+ placeholder: labels.fieldUsernamePlaceholder
3945
+ }
3946
+ ),
3947
+ /* @__PURE__ */ jsx(
3948
+ FormInput,
3949
+ {
3950
+ label: labels.fieldPassword,
3951
+ type: "password",
3952
+ value: password,
3953
+ onValueChange: (v) => {
3954
+ setPassword(v);
3955
+ markTouched();
3956
+ },
3957
+ placeholder: labels.fieldPasswordPlaceholder
3958
+ }
3959
+ ),
3960
+ /* @__PURE__ */ jsx(
3961
+ FormInput,
3962
+ {
3963
+ label: labels.fieldSchema,
3964
+ value: schema,
3965
+ onValueChange: (v) => {
3966
+ setSchema(v);
3967
+ markTouched();
3968
+ },
3969
+ placeholder: labels.fieldSchemaPlaceholder
3970
+ }
3971
+ )
3972
+ ] });
3973
+ case "connection-string":
3974
+ return /* @__PURE__ */ jsx("div", { className: "col-span-full", children: /* @__PURE__ */ jsx(
3975
+ FormInput,
3976
+ {
3977
+ label: labels.fieldConnectionString,
3978
+ value: connectionString,
3979
+ onValueChange: (v) => {
3980
+ setConnectionString(v);
3981
+ markTouched();
3982
+ },
3983
+ placeholder: labels.fieldConnectionStringPlaceholder,
3984
+ required: true
3985
+ }
3986
+ ) });
3987
+ case "cloud-bigquery":
3988
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3989
+ /* @__PURE__ */ jsx(
3990
+ FormInput,
3991
+ {
3992
+ label: labels.fieldProjectId,
3993
+ value: projectId,
3994
+ onValueChange: (v) => {
3995
+ setProjectId(v);
3996
+ markTouched();
3997
+ },
3998
+ placeholder: labels.fieldProjectIdPlaceholder,
3999
+ required: true
4000
+ }
4001
+ ),
4002
+ /* @__PURE__ */ jsx(
4003
+ FormInput,
4004
+ {
4005
+ label: labels.fieldDataset,
4006
+ value: dataset,
4007
+ onValueChange: (v) => {
4008
+ setDataset(v);
4009
+ markTouched();
4010
+ },
4011
+ placeholder: labels.fieldDatasetPlaceholder,
4012
+ required: true
4013
+ }
4014
+ ),
4015
+ /* @__PURE__ */ jsx("div", { className: "col-span-full", children: /* @__PURE__ */ jsx(
4016
+ FormInput,
4017
+ {
4018
+ label: labels.fieldKeyFile,
4019
+ value: keyFile,
4020
+ onValueChange: (v) => {
4021
+ setKeyFile(v);
4022
+ markTouched();
4023
+ },
4024
+ placeholder: labels.fieldKeyFilePlaceholder
4025
+ }
4026
+ ) })
4027
+ ] });
4028
+ case "cloud-snowflake":
4029
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4030
+ /* @__PURE__ */ jsx(
4031
+ FormInput,
4032
+ {
4033
+ label: labels.fieldAccount,
4034
+ value: account,
4035
+ onValueChange: (v) => {
4036
+ setAccount(v);
4037
+ markTouched();
4038
+ },
4039
+ placeholder: labels.fieldAccountPlaceholder,
4040
+ required: true
4041
+ }
4042
+ ),
4043
+ /* @__PURE__ */ jsx(
4044
+ FormInput,
4045
+ {
4046
+ label: labels.fieldWarehouse,
4047
+ value: warehouseField,
4048
+ onValueChange: (v) => {
4049
+ setWarehouseField(v);
4050
+ markTouched();
4051
+ },
4052
+ placeholder: labels.fieldWarehousePlaceholder,
4053
+ required: true
4054
+ }
4055
+ ),
4056
+ /* @__PURE__ */ jsx(
4057
+ FormInput,
4058
+ {
4059
+ label: labels.fieldDatabase,
4060
+ value: database,
4061
+ onValueChange: (v) => {
4062
+ setDatabase(v);
4063
+ markTouched();
4064
+ },
4065
+ placeholder: labels.fieldDatabasePlaceholder,
4066
+ required: true
4067
+ }
4068
+ ),
4069
+ /* @__PURE__ */ jsx(
4070
+ FormInput,
4071
+ {
4072
+ label: labels.fieldUsername,
4073
+ value: username,
4074
+ onValueChange: (v) => {
4075
+ setUsername(v);
4076
+ markTouched();
4077
+ },
4078
+ placeholder: labels.fieldUsernamePlaceholder,
4079
+ required: true
4080
+ }
4081
+ ),
4082
+ /* @__PURE__ */ jsx(
4083
+ FormInput,
4084
+ {
4085
+ label: labels.fieldPassword,
4086
+ type: "password",
4087
+ value: password,
4088
+ onValueChange: (v) => {
4089
+ setPassword(v);
4090
+ markTouched();
4091
+ },
4092
+ placeholder: labels.fieldPasswordPlaceholder
4093
+ }
4094
+ ),
4095
+ /* @__PURE__ */ jsx(
4096
+ FormInput,
4097
+ {
4098
+ label: labels.fieldSchema,
4099
+ value: schema,
4100
+ onValueChange: (v) => {
4101
+ setSchema(v);
4102
+ markTouched();
4103
+ },
4104
+ placeholder: labels.fieldSchemaPlaceholder
4105
+ }
4106
+ )
4107
+ ] });
4108
+ case "cloud-key":
4109
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4110
+ /* @__PURE__ */ jsx(
4111
+ FormInput,
4112
+ {
4113
+ label: labels.fieldRegion,
4114
+ value: region,
4115
+ onValueChange: (v) => {
4116
+ setRegion(v);
4117
+ markTouched();
4118
+ },
4119
+ placeholder: labels.fieldRegionPlaceholder,
4120
+ required: true
4121
+ }
4122
+ ),
4123
+ /* @__PURE__ */ jsx(
4124
+ FormInput,
4125
+ {
4126
+ label: labels.fieldToken,
4127
+ type: "password",
4128
+ value: token,
4129
+ onValueChange: (v) => {
4130
+ setToken(v);
4131
+ markTouched();
4132
+ },
4133
+ placeholder: labels.fieldTokenPlaceholder,
4134
+ required: true
4135
+ }
4136
+ ),
4137
+ /* @__PURE__ */ jsx(
4138
+ FormInput,
4139
+ {
4140
+ label: labels.fieldBucket,
4141
+ value: bucket,
4142
+ onValueChange: (v) => {
4143
+ setBucket(v);
4144
+ markTouched();
4145
+ },
4146
+ placeholder: labels.fieldBucketPlaceholder
4147
+ }
4148
+ )
4149
+ ] });
4150
+ case "vector-key":
4151
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4152
+ /* @__PURE__ */ jsx(
4153
+ FormInput,
4154
+ {
4155
+ label: labels.fieldApiKey,
4156
+ type: "password",
4157
+ value: apiKey,
4158
+ onValueChange: (v) => {
4159
+ setApiKey(v);
4160
+ markTouched();
4161
+ },
4162
+ placeholder: labels.fieldApiKeyPlaceholder,
4163
+ required: true
4164
+ }
4165
+ ),
4166
+ /* @__PURE__ */ jsx(
4167
+ FormInput,
4168
+ {
4169
+ label: labels.fieldEnvironment,
4170
+ value: environment,
4171
+ onValueChange: (v) => {
4172
+ setEnvironment(v);
4173
+ markTouched();
4174
+ },
4175
+ placeholder: labels.fieldEnvironmentPlaceholder,
4176
+ required: true
4177
+ }
4178
+ ),
4179
+ /* @__PURE__ */ jsx(
4180
+ FormInput,
4181
+ {
4182
+ label: labels.fieldIndex,
4183
+ value: index,
4184
+ onValueChange: (v) => {
4185
+ setIndex(v);
4186
+ markTouched();
4187
+ },
4188
+ placeholder: labels.fieldIndexPlaceholder
4189
+ }
4190
+ )
4191
+ ] });
4192
+ }
4193
+ }
4194
+ function renderStep2() {
4195
+ if (!dialectOption) {
4196
+ return /* @__PURE__ */ jsxs(SectionCard, { variant: "glass", header: { title: labels.wizardStep1Title }, children: [
4197
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-slate-700 dark:text-slate-200", children: labels.wizardStep1Subtitle }),
4198
+ /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(Button, { type: "button", outline: true, onClick: () => goToStep(1), children: labels.wizardBack }) })
4199
+ ] });
4200
+ }
4201
+ return /* @__PURE__ */ jsx(
4202
+ SectionCard,
4203
+ {
4204
+ variant: "glass",
4205
+ header: {
4206
+ title: dialectOption.label,
4207
+ subtitle: labels.wizardStep2Subtitle,
4208
+ icon: category?.icon ? /* @__PURE__ */ jsx(category.icon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(CircleStackIcon, { className: "h-4 w-4" }),
4209
+ gradient: category?.gradient
4210
+ },
4211
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
4212
+ /* @__PURE__ */ jsx(
4213
+ FormInput,
4214
+ {
4215
+ label: labels.fieldName,
4216
+ value: name,
4217
+ onValueChange: (v) => {
4218
+ setName(v);
4219
+ markTouched();
4220
+ },
4221
+ placeholder: labels.fieldNamePlaceholder,
4222
+ required: true
4223
+ }
4224
+ ),
4225
+ /* @__PURE__ */ jsx(FormGrid, { children: renderConnectionFields() }),
4226
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-6 pt-1", children: [
4227
+ /* @__PURE__ */ jsx(
4228
+ FormToggle,
4229
+ {
4230
+ checked: ssl,
4231
+ onChange: (v) => {
4232
+ setSsl(v);
4233
+ markTouched();
4234
+ },
4235
+ label: labels.fieldSsl,
4236
+ variant: "inline"
4237
+ }
4238
+ ),
4239
+ /* @__PURE__ */ jsx(
4240
+ FormToggle,
4241
+ {
4242
+ checked: readOnly,
4243
+ onChange: (v) => {
4244
+ setReadOnly(v);
4245
+ markTouched();
4246
+ },
4247
+ label: labels.fieldReadOnly,
4248
+ variant: "inline"
4249
+ }
4250
+ )
4251
+ ] }),
4252
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: labels.fieldReadOnlyHelp }),
4253
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 border-t border-slate-200/60 pt-4 dark:border-white/10", children: [
4254
+ /* @__PURE__ */ jsx(
4255
+ Button,
4256
+ {
4257
+ type: "button",
4258
+ outline: true,
4259
+ onClick: () => void handleTestConnection(),
4260
+ disabled: testStatus === "testing",
4261
+ children: testStatus === "testing" ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
4262
+ /* @__PURE__ */ jsx(Spinner, { size: "xs" }),
4263
+ labels.testing
4264
+ ] }) : labels.testConnection
4265
+ }
4266
+ ),
4267
+ testStatus === "success" && /* @__PURE__ */ jsx(StatusBadge, { status: "success", label: labels.connectionSuccess }),
4268
+ testStatus === "failed" && /* @__PURE__ */ jsx(StatusBadge, { status: "error", label: labels.connectionFailed })
4269
+ ] })
4270
+ ] })
4271
+ }
4272
+ );
4273
+ }
4274
+ function renderStep3() {
4275
+ return /* @__PURE__ */ jsx(
4276
+ SectionCard,
4277
+ {
4278
+ variant: "glass",
4279
+ header: {
4280
+ title: labels.governanceSectionTitle,
4281
+ subtitle: labels.governanceSectionSubtitle
4282
+ },
4283
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
4284
+ /* @__PURE__ */ jsxs(FormGrid, { children: [
4285
+ /* @__PURE__ */ jsx(
4286
+ FormInput,
4287
+ {
4288
+ label: labels.fieldMaxPoolSize,
4289
+ type: "number",
4290
+ min: 1,
4291
+ max: 100,
4292
+ value: maxPoolSize,
4293
+ onValueChange: (v) => {
4294
+ setMaxPoolSize(v);
4295
+ markTouched();
4296
+ },
4297
+ hint: labels.fieldMaxPoolSizeHint
4298
+ }
4299
+ ),
4300
+ /* @__PURE__ */ jsx(
4301
+ FormInput,
4302
+ {
4303
+ label: labels.fieldTimeoutMs,
4304
+ type: "number",
4305
+ min: 100,
4306
+ value: timeoutMs,
4307
+ onValueChange: (v) => {
4308
+ setTimeoutMs(v);
4309
+ markTouched();
4310
+ },
4311
+ hint: labels.fieldTimeoutMsHint
4312
+ }
4313
+ )
4314
+ ] }),
4315
+ /* @__PURE__ */ jsx(
4316
+ FormInput,
4317
+ {
4318
+ label: labels.fieldAllowedTables,
4319
+ value: allowedTables,
4320
+ onValueChange: (v) => {
4321
+ setAllowedTables(v);
4322
+ markTouched();
4323
+ },
4324
+ placeholder: labels.fieldAllowedTablesPlaceholder,
4325
+ hint: labels.fieldAllowedTablesHint
4326
+ }
4327
+ ),
4328
+ /* @__PURE__ */ jsx(
4329
+ FormInput,
4330
+ {
4331
+ label: labels.fieldBlockedColumns,
4332
+ value: blockedColumns,
4333
+ onValueChange: (v) => {
4334
+ setBlockedColumns(v);
4335
+ markTouched();
4336
+ },
4337
+ placeholder: labels.fieldBlockedColumnsPlaceholder,
4338
+ hint: labels.fieldBlockedColumnsHint
4339
+ }
4340
+ ),
4341
+ /* @__PURE__ */ jsx(
4342
+ FormCheckbox,
4343
+ {
4344
+ checked: maskPii,
4345
+ onChange: (v) => {
4346
+ setMaskPii(v);
4347
+ markTouched();
4348
+ },
4349
+ label: labels.fieldMaskPii,
4350
+ description: labels.fieldMaskPiiDescription
4351
+ }
4352
+ )
4353
+ ] })
4354
+ }
4355
+ );
4356
+ }
4357
+ function renderStep4() {
4358
+ const categoryLabel = category ? labels[category.labelKey] ?? category.id : labels.reviewNoneValue;
4359
+ const dialectLabel = dialectOption?.label ?? labels.reviewNoneValue;
4360
+ const allowed = splitList(allowedTables);
4361
+ const blocked = splitList(blockedColumns);
4362
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
4363
+ /* @__PURE__ */ jsx(
4364
+ SectionCard,
4365
+ {
4366
+ variant: "glass",
4367
+ header: {
4368
+ title: labels.wizardStep1Title,
4369
+ subtitle: labels.wizardStep1Subtitle
4370
+ },
4371
+ actions: /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", outline: true, onClick: () => goToStep(1), children: [
4372
+ /* @__PURE__ */ jsx(PencilSquareIcon, { className: "h-4 w-4" }),
4373
+ /* @__PURE__ */ jsx("span", { className: "ml-1.5", children: labels.wizardReviewEdit })
4374
+ ] }),
4375
+ children: /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: [
4376
+ /* @__PURE__ */ jsx(ReviewRow2, { label: labels.reviewCategoryLabel, value: categoryLabel }),
4377
+ /* @__PURE__ */ jsx(ReviewRow2, { label: labels.reviewDialectLabel, value: dialectLabel })
4378
+ ] })
4379
+ }
4380
+ ),
4381
+ /* @__PURE__ */ jsx(
4382
+ SectionCard,
4383
+ {
4384
+ variant: "glass",
4385
+ header: {
4386
+ title: labels.wizardStep2Title,
4387
+ subtitle: labels.wizardStep2Subtitle
4388
+ },
4389
+ actions: /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", outline: true, onClick: () => goToStep(2), children: [
4390
+ /* @__PURE__ */ jsx(PencilSquareIcon, { className: "h-4 w-4" }),
4391
+ /* @__PURE__ */ jsx("span", { className: "ml-1.5", children: labels.wizardReviewEdit })
4392
+ ] }),
4393
+ children: /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: [
4394
+ /* @__PURE__ */ jsx(ReviewRow2, { label: labels.reviewNameLabel, value: name || labels.reviewNoneValue }),
4395
+ /* @__PURE__ */ jsx(ReviewRow2, { label: labels.reviewCredentialsLabel, value: labels.reviewCredentialsRedacted }),
4396
+ /* @__PURE__ */ jsx(ReviewRow2, { label: labels.reviewSslLabel, value: ssl ? labels.reviewYes : labels.reviewNo }),
4397
+ /* @__PURE__ */ jsx(ReviewRow2, { label: labels.reviewReadOnlyLabel, value: readOnly ? labels.reviewYes : labels.reviewNo })
4398
+ ] })
4399
+ }
4400
+ ),
4401
+ /* @__PURE__ */ jsx(
4402
+ SectionCard,
4403
+ {
4404
+ variant: "glass",
4405
+ header: {
4406
+ title: labels.wizardStep3Title,
4407
+ subtitle: labels.wizardStep3Subtitle
4408
+ },
4409
+ actions: /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", outline: true, onClick: () => goToStep(3), children: [
4410
+ /* @__PURE__ */ jsx(PencilSquareIcon, { className: "h-4 w-4" }),
4411
+ /* @__PURE__ */ jsx("span", { className: "ml-1.5", children: labels.wizardReviewEdit })
4412
+ ] }),
4413
+ children: /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: [
4414
+ /* @__PURE__ */ jsx(ReviewRow2, { label: labels.reviewPoolLabel, value: maxPoolSize || labels.reviewNoneValue }),
4415
+ /* @__PURE__ */ jsx(ReviewRow2, { label: labels.reviewTimeoutLabel, value: timeoutMs ? `${timeoutMs}ms` : labels.reviewNoneValue }),
4416
+ /* @__PURE__ */ jsx(
4417
+ ReviewRow2,
4418
+ {
4419
+ label: labels.reviewAllowedTablesLabel,
4420
+ value: allowed.length > 0 ? allowed.join(", ") : labels.reviewNoneValue
4421
+ }
4422
+ ),
4423
+ /* @__PURE__ */ jsx(
4424
+ ReviewRow2,
4425
+ {
4426
+ label: labels.reviewBlockedColumnsLabel,
4427
+ value: blocked.length > 0 ? blocked.join(", ") : labels.reviewNoneValue
4428
+ }
4429
+ ),
4430
+ /* @__PURE__ */ jsx(ReviewRow2, { label: labels.reviewMaskPiiLabel, value: maskPii ? labels.reviewYes : labels.reviewNo })
4431
+ ] })
4432
+ }
4433
+ )
4434
+ ] });
4435
+ }
4436
+ const stepBody = step === 1 ? renderStep1() : step === 2 ? renderStep2() : step === 3 ? renderStep3() : renderStep4();
4437
+ const advanceDisabled = !canAdvance(step);
4438
+ const footer = /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 border-t border-slate-200/60 pt-4 dark:border-white/10", children: [
4439
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx(Button, { type: "button", outline: true, onClick: goBack, disabled: step === 1 || submitting, children: labels.wizardBack }) }),
4440
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4441
+ /* @__PURE__ */ jsx(Button, { type: "button", outline: true, onClick: cancelWithConfirm, disabled: submitting, children: labels.wizardCancel }),
4442
+ step < TOTAL_STEPS2 ? /* @__PURE__ */ jsx(Button, { type: "button", color: "amber", onClick: goNext, disabled: advanceDisabled || submitting, children: labels.wizardNext }) : /* @__PURE__ */ jsx(Button, { type: "button", color: "amber", onClick: () => void submit(), disabled: submitting || !dialect || !name.trim(), children: submitting ? labels.wizardCreate + "\u2026" : labels.wizardCreate })
4443
+ ] })
4444
+ ] });
4445
+ const content = /* @__PURE__ */ jsxs(
4446
+ "form",
4447
+ {
4448
+ onSubmit: (e) => {
4449
+ e.preventDefault();
4450
+ if (step < TOTAL_STEPS2) goNext();
4451
+ else void submit();
4452
+ },
4453
+ className: "space-y-5",
4454
+ children: [
4455
+ /* @__PURE__ */ jsx(
4456
+ StepTimeline,
4457
+ {
4458
+ steps: timelineSteps,
4459
+ progressLabel: labels.pageTitle,
4460
+ onStepClick: (idx) => goToStep(idx + 1)
4461
+ }
4462
+ ),
4463
+ /* @__PURE__ */ jsxs("div", { className: "w-full space-y-5", children: [
4464
+ stepBody,
4465
+ footer
4466
+ ] })
4467
+ ]
4468
+ }
4469
+ );
4470
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
4471
+ hero,
4472
+ content
4473
+ ] });
4474
+ }
4475
+ function ReviewRow2({ label, value }) {
4476
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-slate-200/60 bg-white/40 px-3 py-2 dark:border-white/10 dark:bg-white/[0.04]", children: [
4477
+ /* @__PURE__ */ jsx("dt", { className: "text-[10px] uppercase tracking-wider text-gray-400 dark:text-gray-500", children: label }),
4478
+ /* @__PURE__ */ jsx("dd", { className: "mt-0.5 truncate text-xs font-semibold text-gray-900 dark:text-white", children: value })
4479
+ ] });
4480
+ }
4481
+ function splitList(raw) {
4482
+ return raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
4483
+ }
4484
+ async function simulateTest() {
4485
+ await new Promise((r) => setTimeout(r, 1500));
4486
+ return true;
4487
+ }
4488
+ function RangeSliderField2({
4489
+ sliderId,
4490
+ label,
4491
+ value,
4492
+ onChange,
4493
+ min,
4494
+ max,
4495
+ step,
4496
+ zones,
4497
+ trackGradient,
4498
+ formatValue: formatValue2,
4499
+ ariaLabel
4500
+ }) {
4501
+ const percent = (value - min) / (max - min) * 100;
4502
+ const activeZone = zones?.find((z) => value <= z.max) ?? zones?.[zones.length - 1];
4503
+ const thumbColor = activeZone?.thumbColor ?? "#6366f1";
4504
+ const glow = hexToGlow2(thumbColor);
4505
+ const displayValue = formatValue2 ? formatValue2(value) : value.toString();
4506
+ const ariaText = activeZone ? `${displayValue} \u2014 ${activeZone.label}` : displayValue;
4507
+ return /* @__PURE__ */ jsxs("div", { children: [
4508
+ /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between", children: [
4509
+ /* @__PURE__ */ jsx("label", { htmlFor: sliderId, className: "text-xs font-medium text-gray-500 dark:text-gray-400", children: label }),
4510
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-bold tabular-nums text-gray-900 dark:text-white", children: displayValue })
4511
+ ] }),
4512
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
4513
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-x-0 top-1/2 h-2 -translate-y-1/2 overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700", children: /* @__PURE__ */ jsx(
4514
+ "div",
4515
+ {
4516
+ className: "h-full rounded-full transition-all duration-300 ease-out motion-reduce:transition-none",
4517
+ style: {
4518
+ width: `${Math.max(0, Math.min(100, percent))}%`,
4519
+ background: trackGradient ?? `linear-gradient(90deg, ${thumbColor}, ${thumbColor})`
4520
+ }
4521
+ }
4522
+ ) }),
4523
+ /* @__PURE__ */ jsx(
4524
+ "input",
4525
+ {
4526
+ id: sliderId,
4527
+ "data-slider-id": sliderId,
4528
+ type: "range",
4529
+ min,
4530
+ max,
4531
+ step,
4532
+ value,
4533
+ onChange: (e) => onChange(parseFloat(e.target.value)),
4534
+ "aria-label": ariaLabel ?? label,
4535
+ "aria-valuemin": min,
4536
+ "aria-valuemax": max,
4537
+ "aria-valuenow": value,
4538
+ "aria-valuetext": ariaText,
4539
+ className: "relative z-10 h-5 w-full cursor-pointer appearance-none bg-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-white [&::-webkit-slider-thumb]:shadow-lg dark:[&::-webkit-slider-thumb]:border-gray-900"
4540
+ }
4541
+ ),
4542
+ /* @__PURE__ */ jsx("style", { children: `[data-slider-id="${sliderId}"]::-webkit-slider-thumb { background: ${thumbColor}; box-shadow: 0 0 8px ${glow}; } [data-slider-id="${sliderId}"]::-moz-range-thumb { background: ${thumbColor}; border: 2px solid white; box-shadow: 0 0 8px ${glow}; }` })
4543
+ ] }),
4544
+ zones && zones.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-1 flex items-center justify-between", children: zones.map((z) => {
4545
+ const isActive = z.label === activeZone?.label;
4546
+ return /* @__PURE__ */ jsx(
4547
+ "span",
4548
+ {
4549
+ className: `text-[10px] font-medium transition-colors motion-reduce:transition-none ${isActive ? z.color : "text-gray-400 dark:text-gray-500"}`,
4550
+ children: z.label
4551
+ },
4552
+ z.label
4553
+ );
4554
+ }) })
4555
+ ] });
4556
+ }
4557
+ function hexToGlow2(hex) {
4558
+ const m = /^#?([0-9a-f]{6})$/i.exec(hex);
4559
+ if (!m) return "rgba(99,102,241,0.5)";
4560
+ const int = parseInt(m[1], 16);
4561
+ const r = int >> 16 & 255;
4562
+ const g = int >> 8 & 255;
4563
+ const b = int & 255;
4564
+ return `rgba(${r},${g},${b},0.5)`;
4565
+ }
4566
+ var ACTION_TILES = [
4567
+ { id: "notify", color: "sky", icon: BellAlertIcon, labelKey: "actionNotifyLabel", descriptionKey: "actionNotifyDescription" },
4568
+ { id: "call-webhook", color: "indigo", icon: GlobeAltIcon, labelKey: "actionWebhookLabel", descriptionKey: "actionWebhookDescription" },
4569
+ { id: "mutate", color: "amber", icon: PencilIcon, labelKey: "actionMutateLabel", descriptionKey: "actionMutateDescription" },
4570
+ { id: "escalate", color: "rose", icon: ArrowUpCircleIcon, labelKey: "actionEscalateLabel", descriptionKey: "actionEscalateDescription" },
4571
+ { id: "route-to-agent", color: "violet", icon: SparklesIcon, labelKey: "actionRouteLabel", descriptionKey: "actionRouteDescription" }
4572
+ ];
4573
+ var WEEKDAYS = [
4574
+ { id: "mon", labelKey: "weekdayMon" },
4575
+ { id: "tue", labelKey: "weekdayTue" },
4576
+ { id: "wed", labelKey: "weekdayWed" },
4577
+ { id: "thu", labelKey: "weekdayThu" },
4578
+ { id: "fri", labelKey: "weekdayFri" },
4579
+ { id: "sat", labelKey: "weekdaySat" },
4580
+ { id: "sun", labelKey: "weekdaySun" }
4581
+ ];
4582
+ var TOTAL_STEPS3 = 5;
4583
+ function RuleNewWizardPageView({
4584
+ labels,
4585
+ initialStep,
4586
+ onStepChange,
4587
+ onSubmit,
4588
+ onCancel
4589
+ }) {
4590
+ const clampedInitial = Math.min(TOTAL_STEPS3, Math.max(1, initialStep ?? 1));
4591
+ const [step, setStep] = useState(clampedInitial);
4592
+ const [name, setName] = useState("");
4593
+ const [description, setDescription] = useState("");
4594
+ const [priority, setPriority] = useState(50);
4595
+ const [enabled, setEnabled] = useState(true);
4596
+ const [status, setStatus] = useState("active");
4597
+ const [tagsInput, setTagsInput] = useState("");
4598
+ const [combinator, setCombinator] = useState("and");
4599
+ const [condition, setCondition] = useState(defaultRuleCondition());
4600
+ const [actionTileId, setActionTileId] = useState("");
4601
+ const [action, setAction] = useState(defaultRuleAction());
4602
+ const [validFromDate, setValidFromDate] = useState(null);
4603
+ const [validFromTime, setValidFromTime] = useState(null);
4604
+ const [validUntilDate, setValidUntilDate] = useState(null);
4605
+ const [validUntilTime, setValidUntilTime] = useState(null);
4606
+ const [noExpiry, setNoExpiry] = useState(true);
4607
+ const [recurrence, setRecurrence] = useState("one-off");
4608
+ const [cronExpression, setCronExpression] = useState("");
4609
+ const [weekdays, setWeekdays] = useState([]);
4610
+ const [recurringTime, setRecurringTime] = useState(null);
4611
+ const [submitting, setSubmitting] = useState(false);
4612
+ const [touched, setTouched] = useState(false);
4613
+ function markTouched() {
4614
+ if (!touched) setTouched(true);
4615
+ }
4616
+ useEffect(() => {
4617
+ const next = Math.min(TOTAL_STEPS3, Math.max(1, initialStep ?? 1));
4618
+ if (next !== step) setStep(next);
4619
+ }, [initialStep]);
4620
+ const goToStep = useCallback((next) => {
4621
+ const clamped = Math.min(TOTAL_STEPS3, Math.max(1, next));
4622
+ setStep(clamped);
4623
+ onStepChange?.(clamped);
4624
+ }, [onStepChange]);
4625
+ function canAdvance(from) {
4626
+ if (from === 1) return name.trim().length > 0;
4627
+ if (from === 3) return actionTileId.length > 0;
4628
+ return true;
4629
+ }
4630
+ const goNext = useCallback(() => {
4631
+ if (!canAdvance(step)) return;
4632
+ if (step < TOTAL_STEPS3) goToStep(step + 1);
4633
+ }, [step, name, actionTileId]);
4634
+ const goBack = useCallback(() => {
4635
+ if (step > 1) goToStep(step - 1);
4636
+ }, [step, goToStep]);
4637
+ const cancelWithConfirm = useCallback(() => {
4638
+ if (touched && !window.confirm(labels.wizardCancelConfirm)) return;
4639
+ onCancel();
4640
+ }, [touched, labels.wizardCancelConfirm, onCancel]);
4641
+ function combineDateTime(date, time) {
4642
+ if (!date) return null;
4643
+ const next = new Date(date);
4644
+ next.setHours(time?.hours ?? 0, time?.minutes ?? 0, 0, 0);
4645
+ return next.toISOString();
4646
+ }
4647
+ const tags = useMemo(
4648
+ () => tagsInput.split(",").map((t) => t.trim()).filter((t) => t.length > 0),
4649
+ [tagsInput]
4650
+ );
4651
+ function buildPayload() {
4652
+ const validFrom = combineDateTime(validFromDate, validFromTime);
4653
+ const validUntil = noExpiry ? null : combineDateTime(validUntilDate, validUntilTime);
4654
+ const conditionWithCombinator = combinator === "not" ? {
4655
+ operator: "boolean_expression",
4656
+ combinator: "and",
4657
+ operands: [condition],
4658
+ // The engine ignores extra fields, so this is forward-compat.
4659
+ ...{ notFlag: true }
4660
+ } : combinator === "or" ? {
4661
+ operator: "boolean_expression",
4662
+ combinator: "or",
4663
+ operands: [condition]
4664
+ } : condition;
4665
+ const finalAction = {
4666
+ type: action.type,
4667
+ params: {
4668
+ ...action.params ?? {},
4669
+ actionVariant: actionTileId,
4670
+ recurrence,
4671
+ ...recurrence === "cron" && cronExpression ? { cronExpression } : {},
4672
+ ...recurrence === "recurring" ? {
4673
+ weekdays,
4674
+ ...recurringTime ? { timeOfDay: `${pad(recurringTime.hours)}:${pad(recurringTime.minutes)}` } : {}
4675
+ } : {}
4676
+ }
4677
+ };
4678
+ const wireStatus = status === "paused" ? "draft" : status;
4679
+ return {
4680
+ name: name.trim() || "Untitled Rule",
4681
+ description: description.trim() || void 0,
4682
+ enabled,
4683
+ priority,
4684
+ status: wireStatus,
4685
+ validFrom,
4686
+ validUntil,
4687
+ tags,
4688
+ condition: conditionWithCombinator,
4689
+ action: finalAction
4690
+ };
4691
+ }
4692
+ async function submit() {
4693
+ setSubmitting(true);
4694
+ try {
4695
+ await onSubmit(buildPayload());
4696
+ } finally {
4697
+ setSubmitting(false);
4698
+ }
4699
+ }
4700
+ useEffect(() => {
4701
+ function onKey(e) {
4702
+ if (e.key === "Escape") {
4703
+ e.preventDefault();
4704
+ cancelWithConfirm();
4705
+ return;
4706
+ }
4707
+ if (e.key === "Enter") {
4708
+ const target = e.target;
4709
+ const tag = target?.tagName?.toLowerCase();
4710
+ if (tag === "textarea" || tag === "select" || tag === "input" || tag === "button") return;
4711
+ e.preventDefault();
4712
+ if (step < TOTAL_STEPS3) goNext();
4713
+ else void submit();
4714
+ }
4715
+ }
4716
+ window.addEventListener("keydown", onKey);
4717
+ return () => window.removeEventListener("keydown", onKey);
4718
+ }, [step, name, actionTileId, touched]);
4719
+ const stepTitles = [
4720
+ labels.wizardStep1Title,
4721
+ labels.wizardStep2Title,
4722
+ labels.wizardStep3Title,
4723
+ labels.wizardStep4Title,
4724
+ labels.wizardStep5Title
4725
+ ];
4726
+ const stepSubtitles = [
4727
+ labels.wizardStep1Subtitle,
4728
+ labels.wizardStep2Subtitle,
4729
+ labels.wizardStep3Subtitle,
4730
+ labels.wizardStep4Subtitle,
4731
+ labels.wizardStep5Subtitle
4732
+ ];
4733
+ const timelineSteps = stepTitles.map((title, idx) => ({
4734
+ id: String(idx + 1),
4735
+ name: title,
4736
+ description: stepSubtitles[idx],
4737
+ status: idx + 1 < step ? "complete" : idx + 1 === step ? "current" : "upcoming"
4738
+ }));
4739
+ const counter = labels.wizardStepCounter.replace("{current}", String(step)).replace("{total}", String(TOTAL_STEPS3));
4740
+ const hero = /* @__PURE__ */ jsx(
4741
+ HeroSection,
4742
+ {
4743
+ icon: /* @__PURE__ */ jsx(AdjustmentsHorizontalIcon, { className: "h-5 w-5" }),
4744
+ label: counter,
4745
+ title: labels.pageTitle,
4746
+ subtitle: stepSubtitles[step - 1] ?? labels.pageSubtitle,
4747
+ gradient: "from-fuchsia-500 to-purple-700"
4748
+ }
4749
+ );
4750
+ function renderStep1() {
4751
+ return /* @__PURE__ */ jsx(
4752
+ SectionCard,
4753
+ {
4754
+ variant: "glass",
4755
+ header: {
4756
+ title: labels.wizardStep1Title,
4757
+ subtitle: labels.wizardStep1Subtitle
4758
+ },
4759
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
4760
+ /* @__PURE__ */ jsx(
4761
+ FormInput,
4762
+ {
4763
+ label: labels.nameLabel,
4764
+ value: name,
4765
+ onValueChange: (v) => {
4766
+ setName(v);
4767
+ markTouched();
4768
+ },
4769
+ placeholder: labels.namePlaceholder,
4770
+ required: true
4771
+ }
4772
+ ),
4773
+ /* @__PURE__ */ jsx(
4774
+ FormTextarea,
4775
+ {
4776
+ label: labels.descriptionLabel,
4777
+ value: description,
4778
+ onValueChange: (v) => {
4779
+ setDescription(v);
4780
+ markTouched();
4781
+ },
4782
+ placeholder: labels.descriptionPlaceholder,
4783
+ rows: 3
4784
+ }
4785
+ ),
4786
+ /* @__PURE__ */ jsx(
4787
+ RangeSliderField2,
4788
+ {
4789
+ sliderId: "wizard-rule-priority",
4790
+ label: labels.priorityLabel,
4791
+ value: priority,
4792
+ onChange: (v) => {
4793
+ setPriority(Math.round(v));
4794
+ markTouched();
4795
+ },
4796
+ min: 0,
4797
+ max: 100,
4798
+ step: 1,
4799
+ trackGradient: "linear-gradient(90deg, #10b981, #38bdf8 33%, #f59e0b 66%, #f43f5e)",
4800
+ formatValue: (v) => String(Math.round(v)),
4801
+ zones: [
4802
+ { label: labels.priorityLow, max: 25, color: "text-emerald-500", thumbColor: "#10b981" },
4803
+ { label: labels.priorityNormal, max: 50, color: "text-sky-500", thumbColor: "#38bdf8" },
4804
+ { label: labels.priorityHigh, max: 75, color: "text-amber-500", thumbColor: "#f59e0b" },
4805
+ { label: labels.priorityCritical, max: 100, color: "text-rose-500", thumbColor: "#f43f5e" }
4806
+ ]
4807
+ }
4808
+ ),
4809
+ /* @__PURE__ */ jsx(
4810
+ FormToggle,
4811
+ {
4812
+ checked: enabled,
4813
+ onChange: (v) => {
4814
+ setEnabled(v);
4815
+ markTouched();
4816
+ },
4817
+ label: labels.enabledLabel,
4818
+ variant: "card"
4819
+ }
4820
+ )
4821
+ ] })
4822
+ }
4823
+ );
4824
+ }
4825
+ function renderStep2() {
4826
+ return /* @__PURE__ */ jsx(
4827
+ SectionCard,
4828
+ {
4829
+ variant: "glass",
4830
+ header: {
4831
+ title: labels.conditionSectionTitle,
4832
+ subtitle: labels.conditionSectionSubtitle
4833
+ },
4834
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
4835
+ /* @__PURE__ */ jsxs("div", { children: [
4836
+ /* @__PURE__ */ jsx("span", { className: "mb-2 block text-xs font-semibold uppercase tracking-wider text-slate-600 dark:text-slate-400", children: labels.combinatorLabel }),
4837
+ /* @__PURE__ */ jsx(
4838
+ SegmentedControl,
4839
+ {
4840
+ segments: [
4841
+ { value: "and", label: labels.combinatorAnd },
4842
+ { value: "or", label: labels.combinatorOr },
4843
+ { value: "not", label: labels.combinatorNot }
4844
+ ],
4845
+ value: combinator,
4846
+ onChange: (v) => {
4847
+ setCombinator(v);
4848
+ markTouched();
4849
+ },
4850
+ size: "sm"
4851
+ }
4852
+ )
4853
+ ] }),
4854
+ /* @__PURE__ */ jsx(
4855
+ RuleConditionBuilder,
4856
+ {
4857
+ value: condition,
4858
+ onChange: (next) => {
4859
+ setCondition(next);
4860
+ markTouched();
4861
+ }
4862
+ }
4863
+ )
4864
+ ] })
4865
+ }
4866
+ );
4867
+ }
4868
+ function renderStep3() {
4869
+ const selectedTile = ACTION_TILES.find((t) => t.id === actionTileId) ?? null;
4870
+ return /* @__PURE__ */ jsx(
4871
+ SectionCard,
4872
+ {
4873
+ variant: "glass",
4874
+ header: {
4875
+ title: labels.actionSectionTitle,
4876
+ subtitle: labels.actionSectionSubtitle
4877
+ },
4878
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
4879
+ /* @__PURE__ */ jsx(
4880
+ "div",
4881
+ {
4882
+ role: "radiogroup",
4883
+ "aria-label": labels.actionSectionTitle,
4884
+ className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",
4885
+ children: ACTION_TILES.map((tile) => {
4886
+ const Icon = tile.icon;
4887
+ const selected = tile.id === actionTileId;
4888
+ const label = labels[tile.labelKey] ?? tile.id;
4889
+ const description2 = labels[tile.descriptionKey] ?? "";
4890
+ return /* @__PURE__ */ jsx(
4891
+ FilterTileButton,
4892
+ {
4893
+ isActive: selected,
4894
+ color: tile.color,
4895
+ icon: /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5" }),
4896
+ label,
4897
+ count: description2,
4898
+ onClick: () => {
4899
+ setActionTileId(tile.id);
4900
+ markTouched();
4901
+ }
4902
+ },
4903
+ tile.id
4904
+ );
4905
+ })
4906
+ }
4907
+ ),
4908
+ selectedTile && /* @__PURE__ */ jsx(
4909
+ SectionCard,
4910
+ {
4911
+ variant: "glass",
4912
+ header: {
4913
+ title: labels[selectedTile.labelKey] ?? selectedTile.id,
4914
+ subtitle: labels.actionConfigSubtitle
4915
+ },
4916
+ children: /* @__PURE__ */ jsx(
4917
+ RuleActionBuilder,
4918
+ {
4919
+ value: action,
4920
+ onChange: (next) => {
4921
+ setAction(next);
4922
+ markTouched();
4923
+ }
4924
+ }
4925
+ )
4926
+ }
4927
+ )
4928
+ ] })
4929
+ }
4930
+ );
4931
+ }
4932
+ function renderStep4() {
4933
+ return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsx(
4934
+ SectionCard,
4935
+ {
4936
+ variant: "glass",
4937
+ header: {
4938
+ title: labels.scheduleSectionTitle,
4939
+ subtitle: labels.scheduleSectionSubtitle
4940
+ },
4941
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
4942
+ /* @__PURE__ */ jsxs(FormGrid, { children: [
4943
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
4944
+ /* @__PURE__ */ jsx("span", { className: "block text-xs font-semibold uppercase tracking-wider text-slate-600 dark:text-slate-400", children: labels.validFromLabel }),
4945
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
4946
+ /* @__PURE__ */ jsx(
4947
+ DatePicker,
4948
+ {
4949
+ value: validFromDate,
4950
+ onChange: (d) => {
4951
+ setValidFromDate(d);
4952
+ markTouched();
4953
+ },
4954
+ placeholder: labels.validFromDateLabel
4955
+ }
4956
+ ),
4957
+ /* @__PURE__ */ jsx(
4958
+ TimePicker,
4959
+ {
4960
+ value: validFromTime,
4961
+ onChange: (t) => {
4962
+ setValidFromTime(t);
4963
+ markTouched();
4964
+ },
4965
+ placeholder: labels.validFromTimeLabel
4966
+ }
4967
+ )
4968
+ ] })
4969
+ ] }),
4970
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
4971
+ /* @__PURE__ */ jsx("span", { className: "block text-xs font-semibold uppercase tracking-wider text-slate-600 dark:text-slate-400", children: labels.validUntilLabel }),
4972
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
4973
+ /* @__PURE__ */ jsx(
4974
+ DatePicker,
4975
+ {
4976
+ value: validUntilDate,
4977
+ onChange: (d) => {
4978
+ setValidUntilDate(d);
4979
+ markTouched();
4980
+ },
4981
+ placeholder: labels.validUntilDateLabel
4982
+ }
4983
+ ),
4984
+ /* @__PURE__ */ jsx(
4985
+ TimePicker,
4986
+ {
4987
+ value: validUntilTime,
4988
+ onChange: (t) => {
4989
+ setValidUntilTime(t);
4990
+ markTouched();
4991
+ },
4992
+ placeholder: labels.validUntilTimeLabel
4993
+ }
4994
+ )
4995
+ ] })
4996
+ ] })
4997
+ ] }),
4998
+ /* @__PURE__ */ jsx(
4999
+ FormCheckbox,
5000
+ {
5001
+ checked: noExpiry,
5002
+ onChange: (v) => {
5003
+ setNoExpiry(v);
5004
+ markTouched();
5005
+ },
5006
+ label: labels.noExpiryLabel,
5007
+ description: labels.noExpiryDescription
5008
+ }
5009
+ ),
5010
+ /* @__PURE__ */ jsxs("div", { children: [
5011
+ /* @__PURE__ */ jsx("span", { className: "mb-2 block text-xs font-semibold uppercase tracking-wider text-slate-600 dark:text-slate-400", children: labels.statusLabel }),
5012
+ /* @__PURE__ */ jsx(
5013
+ SegmentedControl,
5014
+ {
5015
+ segments: [
5016
+ { value: "active", label: labels.statusActive },
5017
+ { value: "paused", label: labels.statusPaused },
5018
+ { value: "archived", label: labels.statusArchived }
5019
+ ],
5020
+ value: status,
5021
+ onChange: (v) => {
5022
+ setStatus(v);
5023
+ markTouched();
5024
+ },
5025
+ size: "sm"
5026
+ }
5027
+ )
5028
+ ] }),
5029
+ /* @__PURE__ */ jsx(
5030
+ FormInput,
5031
+ {
5032
+ label: labels.tagsLabel,
5033
+ value: tagsInput,
5034
+ onValueChange: (v) => {
5035
+ setTagsInput(v);
5036
+ markTouched();
5037
+ },
5038
+ placeholder: labels.tagsPlaceholder,
5039
+ hint: labels.tagsHint
5040
+ }
5041
+ ),
5042
+ /* @__PURE__ */ jsxs("div", { children: [
5043
+ /* @__PURE__ */ jsx("span", { className: "mb-2 block text-xs font-semibold uppercase tracking-wider text-slate-600 dark:text-slate-400", children: labels.recurrenceLabel }),
5044
+ /* @__PURE__ */ jsx(
5045
+ SegmentedControl,
5046
+ {
5047
+ segments: [
5048
+ { value: "one-off", label: labels.recurrenceOneOff },
5049
+ { value: "cron", label: labels.recurrenceCron },
5050
+ { value: "recurring", label: labels.recurrenceRecurring }
5051
+ ],
5052
+ value: recurrence,
5053
+ onChange: (v) => {
5054
+ setRecurrence(v);
5055
+ markTouched();
5056
+ },
5057
+ size: "sm"
5058
+ }
5059
+ )
5060
+ ] }),
5061
+ recurrence === "cron" && /* @__PURE__ */ jsx(
5062
+ FormInput,
5063
+ {
5064
+ label: labels.cronExpressionLabel,
5065
+ value: cronExpression,
5066
+ onValueChange: (v) => {
5067
+ setCronExpression(v);
5068
+ markTouched();
5069
+ },
5070
+ placeholder: labels.cronExpressionPlaceholder,
5071
+ hint: labels.cronExpressionHint
5072
+ }
5073
+ ),
5074
+ recurrence === "recurring" && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
5075
+ /* @__PURE__ */ jsxs("div", { children: [
5076
+ /* @__PURE__ */ jsx("span", { className: "mb-2 block text-xs font-semibold uppercase tracking-wider text-slate-600 dark:text-slate-400", children: labels.weekdaysLabel }),
5077
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: WEEKDAYS.map((d) => {
5078
+ const selected = weekdays.includes(d.id);
5079
+ const label = labels[d.labelKey] ?? d.id;
5080
+ return /* @__PURE__ */ jsx(
5081
+ "button",
5082
+ {
5083
+ type: "button",
5084
+ "aria-pressed": selected,
5085
+ onClick: () => {
5086
+ setWeekdays(
5087
+ (current) => current.includes(d.id) ? current.filter((id) => id !== d.id) : [...current, d.id]
5088
+ );
5089
+ markTouched();
5090
+ },
5091
+ className: [
5092
+ "inline-flex h-9 min-w-9 items-center justify-center rounded-full px-3 text-xs font-semibold transition",
5093
+ selected ? "bg-fuchsia-500 text-white shadow ring-2 ring-fuchsia-300/70" : "liquid-surface text-slate-700 dark:text-slate-300 hover:bg-fuchsia-500/10"
5094
+ ].join(" "),
5095
+ children: label
5096
+ },
5097
+ d.id
5098
+ );
5099
+ }) })
5100
+ ] }),
5101
+ /* @__PURE__ */ jsxs("div", { children: [
5102
+ /* @__PURE__ */ jsx("span", { className: "mb-2 block text-xs font-semibold uppercase tracking-wider text-slate-600 dark:text-slate-400", children: labels.timeOfDayLabel }),
5103
+ /* @__PURE__ */ jsx(
5104
+ TimePicker,
5105
+ {
5106
+ value: recurringTime,
5107
+ onChange: (t) => {
5108
+ setRecurringTime(t);
5109
+ markTouched();
5110
+ },
5111
+ placeholder: labels.timeOfDayLabel
5112
+ }
5113
+ )
5114
+ ] })
5115
+ ] })
5116
+ ] })
5117
+ }
5118
+ ) });
5119
+ }
5120
+ function renderStep5() {
5121
+ const payload = buildPayload();
5122
+ const conditionSentence = humanReadableCondition(payload.condition, labels);
5123
+ const actionSentence = humanReadableAction(payload.action, labels, ACTION_TILES, actionTileId);
5124
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
5125
+ /* @__PURE__ */ jsx(
5126
+ SectionCard,
5127
+ {
5128
+ variant: "glass",
5129
+ header: {
5130
+ title: labels.wizardStep1Title,
5131
+ subtitle: labels.wizardStep1Subtitle
5132
+ },
5133
+ actions: /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", outline: true, onClick: () => goToStep(1), children: [
5134
+ /* @__PURE__ */ jsx(PencilSquareIcon, { className: "h-4 w-4" }),
5135
+ /* @__PURE__ */ jsx("span", { className: "ml-1.5", children: labels.wizardReviewEdit })
5136
+ ] }),
5137
+ children: /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: [
5138
+ /* @__PURE__ */ jsx(ReviewRow3, { label: labels.reviewNameLabel, value: payload.name }),
5139
+ /* @__PURE__ */ jsx(ReviewRow3, { label: labels.reviewPriorityLabel, value: String(payload.priority) }),
5140
+ /* @__PURE__ */ jsx(ReviewRow3, { label: labels.reviewEnabledLabel, value: payload.enabled ? labels.reviewYes : labels.reviewNo }),
5141
+ /* @__PURE__ */ jsx(
5142
+ ReviewRow3,
5143
+ {
5144
+ label: labels.reviewDescriptionLabel,
5145
+ value: payload.description ?? labels.reviewNoneValue
5146
+ }
5147
+ )
5148
+ ] })
5149
+ }
5150
+ ),
5151
+ /* @__PURE__ */ jsxs(
5152
+ SectionCard,
5153
+ {
5154
+ variant: "glass",
5155
+ header: {
5156
+ title: labels.wizardStep2Title,
5157
+ subtitle: labels.wizardStep2Subtitle
5158
+ },
5159
+ actions: /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", outline: true, onClick: () => goToStep(2), children: [
5160
+ /* @__PURE__ */ jsx(PencilSquareIcon, { className: "h-4 w-4" }),
5161
+ /* @__PURE__ */ jsx("span", { className: "ml-1.5", children: labels.wizardReviewEdit })
5162
+ ] }),
5163
+ children: [
5164
+ /* @__PURE__ */ jsx("p", { className: "mb-2 text-sm text-slate-700 dark:text-slate-200", children: conditionSentence }),
5165
+ /* @__PURE__ */ jsx(ReviewRow3, { label: labels.reviewCombinatorLabel, value: combinator.toUpperCase() }),
5166
+ /* @__PURE__ */ jsx("pre", { className: "mt-3 max-h-48 overflow-auto rounded-lg border border-slate-200/70 bg-slate-50/60 p-2 text-xs text-slate-700 dark:border-slate-700 dark:bg-slate-900/40 dark:text-slate-200", children: JSON.stringify(payload.condition, null, 2) })
5167
+ ]
5168
+ }
5169
+ ),
5170
+ /* @__PURE__ */ jsxs(
5171
+ SectionCard,
5172
+ {
5173
+ variant: "glass",
5174
+ header: {
5175
+ title: labels.wizardStep3Title,
5176
+ subtitle: labels.wizardStep3Subtitle
5177
+ },
5178
+ actions: /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", outline: true, onClick: () => goToStep(3), children: [
5179
+ /* @__PURE__ */ jsx(PencilSquareIcon, { className: "h-4 w-4" }),
5180
+ /* @__PURE__ */ jsx("span", { className: "ml-1.5", children: labels.wizardReviewEdit })
5181
+ ] }),
5182
+ children: [
5183
+ /* @__PURE__ */ jsx("p", { className: "mb-2 text-sm text-slate-700 dark:text-slate-200", children: actionSentence }),
5184
+ /* @__PURE__ */ jsx("pre", { className: "mt-3 max-h-48 overflow-auto rounded-lg border border-slate-200/70 bg-slate-50/60 p-2 text-xs text-slate-700 dark:border-slate-700 dark:bg-slate-900/40 dark:text-slate-200", children: JSON.stringify(payload.action, null, 2) })
5185
+ ]
5186
+ }
5187
+ ),
5188
+ /* @__PURE__ */ jsx(
5189
+ SectionCard,
5190
+ {
5191
+ variant: "glass",
5192
+ header: {
5193
+ title: labels.wizardStep4Title,
5194
+ subtitle: labels.wizardStep4Subtitle
5195
+ },
5196
+ actions: /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", outline: true, onClick: () => goToStep(4), children: [
5197
+ /* @__PURE__ */ jsx(PencilSquareIcon, { className: "h-4 w-4" }),
5198
+ /* @__PURE__ */ jsx("span", { className: "ml-1.5", children: labels.wizardReviewEdit })
5199
+ ] }),
5200
+ children: /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: [
5201
+ /* @__PURE__ */ jsx(
5202
+ ReviewRow3,
5203
+ {
5204
+ label: labels.reviewValidFromLabel,
5205
+ value: payload.validFrom ?? labels.reviewNoneValue
5206
+ }
5207
+ ),
5208
+ /* @__PURE__ */ jsx(
5209
+ ReviewRow3,
5210
+ {
5211
+ label: labels.reviewValidUntilLabel,
5212
+ value: payload.validUntil ?? (noExpiry ? labels.noExpiryLabel : labels.reviewNoneValue)
5213
+ }
5214
+ ),
5215
+ /* @__PURE__ */ jsx(ReviewRow3, { label: labels.reviewStatusLabel, value: payload.status ?? "active" }),
5216
+ /* @__PURE__ */ jsx(
5217
+ ReviewRow3,
5218
+ {
5219
+ label: labels.reviewTagsLabel,
5220
+ value: payload.tags && payload.tags.length > 0 ? payload.tags.join(", ") : labels.reviewNoneValue
5221
+ }
5222
+ ),
5223
+ /* @__PURE__ */ jsx(ReviewRow3, { label: labels.reviewRecurrenceLabel, value: recurrence })
5224
+ ] })
5225
+ }
5226
+ )
5227
+ ] });
5228
+ }
5229
+ const stepBody = step === 1 ? renderStep1() : step === 2 ? renderStep2() : step === 3 ? renderStep3() : step === 4 ? renderStep4() : renderStep5();
5230
+ const advanceDisabled = !canAdvance(step);
5231
+ const footer = /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 border-t border-slate-200/60 pt-4 dark:border-white/10", children: [
5232
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx(Button, { type: "button", outline: true, onClick: goBack, disabled: step === 1 || submitting, children: labels.wizardBack }) }),
5233
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
5234
+ /* @__PURE__ */ jsx(Button, { type: "button", outline: true, onClick: cancelWithConfirm, disabled: submitting, children: labels.wizardCancel }),
5235
+ step < TOTAL_STEPS3 ? /* @__PURE__ */ jsx(Button, { type: "button", color: "fuchsia", onClick: goNext, disabled: advanceDisabled || submitting, children: labels.wizardNext }) : /* @__PURE__ */ jsx(
5236
+ Button,
5237
+ {
5238
+ type: "button",
5239
+ color: "fuchsia",
5240
+ onClick: () => void submit(),
5241
+ disabled: submitting || !name.trim() || !actionTileId,
5242
+ children: submitting ? labels.wizardCreate + "\u2026" : labels.wizardCreate
5243
+ }
5244
+ )
5245
+ ] })
5246
+ ] });
5247
+ const content = /* @__PURE__ */ jsxs(
5248
+ "form",
5249
+ {
5250
+ onSubmit: (e) => {
5251
+ e.preventDefault();
5252
+ if (step < TOTAL_STEPS3) goNext();
5253
+ else void submit();
5254
+ },
5255
+ className: "space-y-5",
5256
+ children: [
5257
+ /* @__PURE__ */ jsx(
5258
+ StepTimeline,
5259
+ {
5260
+ steps: timelineSteps,
5261
+ progressLabel: labels.pageTitle,
5262
+ onStepClick: (idx) => goToStep(idx + 1)
5263
+ }
5264
+ ),
5265
+ /* @__PURE__ */ jsxs("div", { className: "w-full space-y-5", children: [
5266
+ stepBody,
5267
+ footer
5268
+ ] })
5269
+ ]
5270
+ }
5271
+ );
5272
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
5273
+ hero,
5274
+ content
5275
+ ] });
5276
+ }
5277
+ function ReviewRow3({ label, value }) {
5278
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-slate-200/60 bg-white/40 px-3 py-2 dark:border-white/10 dark:bg-white/[0.04]", children: [
5279
+ /* @__PURE__ */ jsx("dt", { className: "text-[10px] uppercase tracking-wider text-gray-400 dark:text-gray-500", children: label }),
5280
+ /* @__PURE__ */ jsx("dd", { className: "mt-0.5 whitespace-pre-wrap break-words text-xs font-semibold text-gray-900 dark:text-white", children: value })
5281
+ ] });
5282
+ }
5283
+ function pad(n) {
5284
+ return String(n).padStart(2, "0");
5285
+ }
5286
+ function humanReadableCondition(cond, labels) {
5287
+ if (!cond) return labels.reviewNoneValue;
5288
+ if (cond.operator === "boolean_expression" && Array.isArray(cond.operands)) {
5289
+ const inner = cond.operands.map((o) => humanReadableCondition(o, labels)).join(` ${cond.combinator?.toUpperCase() ?? "AND"} `);
5290
+ return `(${inner})`;
5291
+ }
5292
+ const field = cond.field ?? "?";
5293
+ switch (cond.operator) {
5294
+ case "truthy":
5295
+ return `${field} is set`;
5296
+ case "eq":
5297
+ return `${field} = ${formatValue(cond.value)}`;
5298
+ case "neq":
5299
+ return `${field} \u2260 ${formatValue(cond.value)}`;
5300
+ case "gt":
5301
+ return `${field} > ${formatValue(cond.value)}`;
5302
+ case "gte":
5303
+ return `${field} \u2265 ${formatValue(cond.value)}`;
5304
+ case "lt":
5305
+ return `${field} < ${formatValue(cond.value)}`;
5306
+ case "lte":
5307
+ return `${field} \u2264 ${formatValue(cond.value)}`;
5308
+ case "contains":
5309
+ return `${field} contains "${formatValue(cond.value)}"`;
5310
+ case "regex_match":
5311
+ return `${field} matches /${cond.pattern ?? ""}/`;
5312
+ case "threshold":
5313
+ return `${field} ${cond.comparison ?? "gte"} ${formatValue(cond.value)}`;
5314
+ case "time_window":
5315
+ return `${field} within time-window(${(cond.windows ?? []).length})`;
5316
+ default:
5317
+ return `${cond.operator}(${field})`;
5318
+ }
5319
+ }
5320
+ function formatValue(v) {
5321
+ if (v === null || v === void 0) return "";
5322
+ return String(v);
5323
+ }
5324
+ function humanReadableAction(action, labels, tiles, actionTileId) {
5325
+ const tile = tiles.find((t) => t.id === actionTileId);
5326
+ const tileLabel = tile ? labels[tile.labelKey] ?? tile.id : action.type;
5327
+ const paramSummary = action.params ? Object.entries(action.params).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`).join(", ") : "";
5328
+ return paramSummary ? `${tileLabel} \u2014 ${paramSummary}` : tileLabel;
5329
+ }
3625
5330
 
3626
- export { AgentNewWizardPageView, AgentsConfigPageView, AgentsIndexPageView, AgentsModelsPageView, AgentsPromptsPageView, AgentsToolDefinitionsPageView, AgentsWorkspacePageView, ConnectionsPageView, CredentialsPageView, DashboardPageView, DatasourcesPageView, RulesPageView, RunTimelinePageView, TOOL_TYPES, WorkflowRunsPageView, WorkflowsPageView, jsonSchemaToParameters, parametersToJsonSchema };
5331
+ export { AgentNewWizardPageView, AgentsConfigPageView, AgentsIndexPageView, AgentsModelsPageView, AgentsPromptsPageView, AgentsToolDefinitionsPageView, AgentsWorkspacePageView, ConnectionsPageView, CredentialsPageView, DashboardPageView, DatasourceNewWizardPageView, DatasourcesPageView, RuleNewWizardPageView, RulesPageView, RunTimelinePageView, TOOL_TYPES, WorkflowRunsPageView, WorkflowsPageView, jsonSchemaToParameters, parametersToJsonSchema };
3627
5332
  //# sourceMappingURL=index.mjs.map
3628
5333
  //# sourceMappingURL=index.mjs.map