@datatechsolutions/ui 2.11.83 → 2.11.84

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 (101) hide show
  1. package/dist/astrlabe/index.d.mts +3 -52
  2. package/dist/astrlabe/index.d.ts +3 -52
  3. package/dist/astrlabe/index.js +107 -107
  4. package/dist/astrlabe/index.mjs +4 -4
  5. package/dist/astrlabe/workflow-canvas.js +4 -4
  6. package/dist/astrlabe/workflow-canvas.mjs +3 -3
  7. package/dist/chunk-3T2WGL47.js +44 -0
  8. package/dist/chunk-3T2WGL47.js.map +1 -0
  9. package/dist/{chunk-UVGMKHWH.mjs → chunk-63AL2RN5.mjs} +4 -4
  10. package/dist/{chunk-UVGMKHWH.mjs.map → chunk-63AL2RN5.mjs.map} +1 -1
  11. package/dist/chunk-64G2HBRQ.mjs +481 -0
  12. package/dist/chunk-64G2HBRQ.mjs.map +1 -0
  13. package/dist/{chunk-J3OYJ44D.mjs → chunk-BH2AU3LG.mjs} +3 -3
  14. package/dist/{chunk-J3OYJ44D.mjs.map → chunk-BH2AU3LG.mjs.map} +1 -1
  15. package/dist/chunk-CCRBT7TA.mjs +941 -0
  16. package/dist/chunk-CCRBT7TA.mjs.map +1 -0
  17. package/dist/chunk-CHLJUSXX.mjs +128 -0
  18. package/dist/chunk-CHLJUSXX.mjs.map +1 -0
  19. package/dist/chunk-CXIQWPBH.js +214 -0
  20. package/dist/chunk-CXIQWPBH.js.map +1 -0
  21. package/dist/chunk-EDE36MKE.mjs +412 -0
  22. package/dist/chunk-EDE36MKE.mjs.map +1 -0
  23. package/dist/{chunk-M7P2TQ6X.js → chunk-EFREXNZB.js} +64 -64
  24. package/dist/{chunk-M7P2TQ6X.js.map → chunk-EFREXNZB.js.map} +1 -1
  25. package/dist/chunk-FAGDZEKM.js +23 -0
  26. package/dist/chunk-FAGDZEKM.js.map +1 -0
  27. package/dist/{chunk-TUEYBNWL.js → chunk-GV6WJCEB.js} +3 -3
  28. package/dist/{chunk-TUEYBNWL.js.map → chunk-GV6WJCEB.js.map} +1 -1
  29. package/dist/chunk-HU3EAHFO.mjs +20 -0
  30. package/dist/chunk-HU3EAHFO.mjs.map +1 -0
  31. package/dist/{chunk-LLFU42KC.mjs → chunk-I6WYV2AN.mjs} +3 -3
  32. package/dist/{chunk-LLFU42KC.mjs.map → chunk-I6WYV2AN.mjs.map} +1 -1
  33. package/dist/chunk-JJWFMKZY.js +132 -0
  34. package/dist/chunk-JJWFMKZY.js.map +1 -0
  35. package/dist/{chunk-JFWZHROG.js → chunk-L6FVIWAJ.js} +128 -128
  36. package/dist/{chunk-JFWZHROG.js.map → chunk-L6FVIWAJ.js.map} +1 -1
  37. package/dist/chunk-MNQEZL7B.mjs +210 -0
  38. package/dist/chunk-MNQEZL7B.mjs.map +1 -0
  39. package/dist/chunk-SGJ24J2Q.js +943 -0
  40. package/dist/chunk-SGJ24J2Q.js.map +1 -0
  41. package/dist/chunk-SW6TVAIJ.js +418 -0
  42. package/dist/chunk-SW6TVAIJ.js.map +1 -0
  43. package/dist/chunk-SYNVNTLJ.mjs +20 -0
  44. package/dist/chunk-SYNVNTLJ.mjs.map +1 -0
  45. package/dist/chunk-UQXVCVAN.mjs +41 -0
  46. package/dist/chunk-UQXVCVAN.mjs.map +1 -0
  47. package/dist/chunk-WGELLCOZ.js +22 -0
  48. package/dist/chunk-WGELLCOZ.js.map +1 -0
  49. package/dist/chunk-YXPHJ2BQ.js +541 -0
  50. package/dist/chunk-YXPHJ2BQ.js.map +1 -0
  51. package/dist/index.d.mts +3 -47
  52. package/dist/index.d.ts +3 -47
  53. package/dist/index.js +765 -765
  54. package/dist/index.mjs +2 -2
  55. package/dist/navigation-BiWVffAN.d.mts +49 -0
  56. package/dist/navigation-BiWVffAN.d.ts +49 -0
  57. package/dist/platform/agents-workspace.d.mts +19 -0
  58. package/dist/platform/agents-workspace.d.ts +19 -0
  59. package/dist/platform/agents-workspace.js +26 -0
  60. package/dist/platform/agents-workspace.js.map +1 -0
  61. package/dist/platform/agents-workspace.mjs +17 -0
  62. package/dist/platform/agents-workspace.mjs.map +1 -0
  63. package/dist/platform/app-shell.d.mts +58 -0
  64. package/dist/platform/app-shell.d.ts +58 -0
  65. package/dist/platform/app-shell.js +17 -0
  66. package/dist/platform/app-shell.js.map +1 -0
  67. package/dist/platform/app-shell.mjs +8 -0
  68. package/dist/platform/app-shell.mjs.map +1 -0
  69. package/dist/platform/index.d.mts +100 -3
  70. package/dist/platform/index.d.ts +100 -3
  71. package/dist/platform/index.js +499 -28
  72. package/dist/platform/index.js.map +1 -1
  73. package/dist/platform/index.mjs +472 -27
  74. package/dist/platform/index.mjs.map +1 -1
  75. package/dist/platform/pages/index.d.mts +243 -82
  76. package/dist/platform/pages/index.d.ts +243 -82
  77. package/dist/platform/pages/index.js +886 -614
  78. package/dist/platform/pages/index.js.map +1 -1
  79. package/dist/platform/pages/index.mjs +756 -511
  80. package/dist/platform/pages/index.mjs.map +1 -1
  81. package/dist/platform/utils/index.js +18 -56
  82. package/dist/platform/utils/index.js.map +1 -1
  83. package/dist/platform/utils/index.mjs +3 -53
  84. package/dist/platform/utils/index.mjs.map +1 -1
  85. package/dist/platform/workflow-api-client.d.mts +6 -0
  86. package/dist/platform/workflow-api-client.d.ts +6 -0
  87. package/dist/platform/workflow-api-client.js +246 -0
  88. package/dist/platform/workflow-api-client.js.map +1 -0
  89. package/dist/platform/workflow-api-client.mjs +5 -0
  90. package/dist/platform/workflow-api-client.mjs.map +1 -0
  91. package/dist/platform/workflow-canvas-shell.d.mts +18 -0
  92. package/dist/platform/workflow-canvas-shell.d.ts +18 -0
  93. package/dist/platform/workflow-canvas-shell.js +20 -0
  94. package/dist/platform/workflow-canvas-shell.js.map +1 -0
  95. package/dist/platform/workflow-canvas-shell.mjs +11 -0
  96. package/dist/platform/workflow-canvas-shell.mjs.map +1 -0
  97. package/dist/{rule-form-F5jBOeqk.d.mts → rule-form-BYJzyork.d.mts} +50 -1
  98. package/dist/{rule-form-F5jBOeqk.d.ts → rule-form-BYJzyork.d.ts} +50 -1
  99. package/dist/workflow-api-client-C8gPn_D1.d.mts +386 -0
  100. package/dist/workflow-api-client-Dy1Ph8W-.d.ts +386 -0
  101. package/package.json +21 -1
@@ -1,118 +1,23 @@
1
1
  "use client";
2
- import { defaultRuleForm, RuleForm } from '../../chunk-UVGMKHWH.mjs';
2
+ import { adaptWorkflowGraphToUi, formatDurationMs } from '../../chunk-UQXVCVAN.mjs';
3
+ import { WorkflowWorkspace } from '../../chunk-MNQEZL7B.mjs';
4
+ export { RolesPageView, UsersPageView } from '../../chunk-MNQEZL7B.mjs';
5
+ import { DatasourceModal, findCategory, DIALECT_CATEGORIES } from '../../chunk-EDE36MKE.mjs';
6
+ export { DIALECT_CATEGORIES, DatasourceFormModal, DatasourceModal, findCategory, findDialect } from '../../chunk-EDE36MKE.mjs';
7
+ import { defaultRuleForm, RuleForm, ExecutionTimelinePanel } from '../../chunk-63AL2RN5.mjs';
3
8
  import '../../chunk-JB6RNAD2.mjs';
4
9
  import '../../chunk-53SRKVKQ.mjs';
5
- import '../../chunk-J3OYJ44D.mjs';
6
- import { HeroSection, CreateActionButton, EntityCard, InlineForm, FormSelect, Button, GlassModal, FormGrid, FormInput, PageLoadingState, PageEmptyState, Badge, ManagementPageLayout, FormTextarea } from '../../chunk-LLFU42KC.mjs';
7
- import '../../chunk-7VJ7CMMT.mjs';
8
- import '../../chunk-QWG2FMUN.mjs';
10
+ import '../../chunk-BH2AU3LG.mjs';
11
+ import { HeroSection, PageLoadingState, PageEmptyState, EntityCard, Badge, ManagementPageLayout, CreateActionButton, Button, GlassModal, FormGrid, FormSelect, FormInput, FormTextarea, SectionHeader, Text, Form, FormActionsRow, Table, TableHead, TableRow, TableHeader, TableBody, TableCell, InlineForm, CopyableId } from '../../chunk-I6WYV2AN.mjs';
12
+ import { useLink } from '../../chunk-QWG2FMUN.mjs';
9
13
  import '../../chunk-D2JF6C3E.mjs';
14
+ import '../../chunk-7VJ7CMMT.mjs';
10
15
  import '../../chunk-OZNTQROP.mjs';
11
16
  import '../../chunk-WNCPAWLC.mjs';
12
- import { useState, useMemo } from 'react';
13
- import { CircleStackIcon, ServerStackIcon, CloudIcon, ClockIcon, ShareIcon, KeyIcon, MagnifyingGlassIcon, UserGroupIcon, CubeTransparentIcon, CpuChipIcon, ChatBubbleLeftEllipsisIcon, WrenchScrewdriverIcon, AdjustmentsHorizontalIcon, ArrowLeftIcon, CheckCircleIcon, XCircleIcon } from '@heroicons/react/24/outline';
14
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
17
+ import { CubeTransparentIcon, CpuChipIcon, ChatBubbleLeftEllipsisIcon, WrenchScrewdriverIcon, AdjustmentsHorizontalIcon, CircleStackIcon, RectangleStackIcon, ClockIcon, LinkIcon, KeyIcon, ArrowPathIcon, TrashIcon } from '@heroicons/react/24/outline';
18
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
19
+ import { useState, useMemo, useEffect } from 'react';
15
20
 
16
- var ROLE_OPTIONS = [
17
- { value: "admin", label: "Admin" },
18
- { value: "manager", label: "Manager" },
19
- { value: "analyst", label: "Analyst" },
20
- { value: "viewer", label: "Viewer" }
21
- ];
22
- function UsersPageView({ labels, users, onCreateUser, onUpdateRole }) {
23
- const [createOpen, setCreateOpen] = useState(false);
24
- return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
25
- /* @__PURE__ */ jsx(
26
- HeroSection,
27
- {
28
- icon: /* @__PURE__ */ jsx(UserGroupIcon, { className: "h-5 w-5" }),
29
- label: labels.title,
30
- title: labels.title,
31
- subtitle: labels.subtitle,
32
- gradient: "from-violet-500 to-indigo-600",
33
- toolbar: /* @__PURE__ */ jsx(
34
- CreateActionButton,
35
- {
36
- mode: "desktop",
37
- label: labels.create,
38
- onClick: () => setCreateOpen(true),
39
- accent: "violet"
40
- }
41
- )
42
- }
43
- ),
44
- /* @__PURE__ */ jsx(
45
- CreateActionButton,
46
- {
47
- mode: "mobile",
48
- label: labels.create,
49
- onClick: () => setCreateOpen(true),
50
- accent: "violet"
51
- }
52
- ),
53
- /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
54
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: labels.list }),
55
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: users.map((user) => /* @__PURE__ */ jsx(
56
- EntityCard,
57
- {
58
- accentGradient: "from-violet-500 to-indigo-700",
59
- icon: /* @__PURE__ */ jsx("div", { className: "flex h-11 w-11 items-center justify-center rounded-lg bg-violet-500/10 text-violet-600 dark:bg-violet-500/20 dark:text-violet-400", children: /* @__PURE__ */ jsx(UserGroupIcon, { className: "h-6 w-6" }) }),
60
- title: user.name,
61
- subtitle: user.email,
62
- status: /* @__PURE__ */ jsx(
63
- "span",
64
- {
65
- className: `shrink-0 rounded-full px-2 py-0.5 text-[10px] font-semibold ${user.active ? "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300" : "bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-300"}`,
66
- children: user.active ? labels.statusActive : labels.statusInactive
67
- }
68
- ),
69
- footer: /* @__PURE__ */ jsx(
70
- "form",
71
- {
72
- onSubmit: (event) => {
73
- event.preventDefault();
74
- const formData = new FormData(event.currentTarget);
75
- const role = String(formData.get("role") ?? "viewer");
76
- onUpdateRole({ email: user.email, role });
77
- },
78
- children: /* @__PURE__ */ jsxs(InlineForm, { children: [
79
- /* @__PURE__ */ jsx(FormSelect, { name: "role", options: ROLE_OPTIONS, defaultValue: user.role }),
80
- /* @__PURE__ */ jsx(Button, { type: "submit", outline: true, size: "sm", children: labels.save })
81
- ] })
82
- }
83
- )
84
- },
85
- user.email
86
- )) })
87
- ] }),
88
- /* @__PURE__ */ jsx(
89
- GlassModal,
90
- {
91
- open: createOpen,
92
- onClose: () => setCreateOpen(false),
93
- title: labels.create,
94
- maxWidth: "lg",
95
- showFormFooter: true,
96
- cancelLabel: labels.list,
97
- submitLabel: labels.add,
98
- onSubmit: (event) => {
99
- const formData = new FormData(event.currentTarget);
100
- const name = String(formData.get("name") ?? "").trim();
101
- const email = String(formData.get("email") ?? "").trim().toLowerCase();
102
- const role = String(formData.get("role") ?? "viewer");
103
- if (!name || !email) return;
104
- onCreateUser({ name, email, role });
105
- setCreateOpen(false);
106
- },
107
- children: /* @__PURE__ */ jsxs(FormGrid, { children: [
108
- /* @__PURE__ */ jsx(FormInput, { name: "name", label: labels.name, placeholder: labels.userNamePlaceholder, required: true }),
109
- /* @__PURE__ */ jsx(FormInput, { name: "email", label: labels.email, placeholder: labels.userEmailPlaceholder, required: true, type: "email" }),
110
- /* @__PURE__ */ jsx(FormSelect, { name: "role", label: labels.role, options: ROLE_OPTIONS })
111
- ] })
112
- }
113
- )
114
- ] });
115
- }
116
21
  function AgentsModelsPageView({ labels, models, loading }) {
117
22
  const hero = /* @__PURE__ */ jsx(
118
23
  HeroSection,
@@ -1106,408 +1011,6 @@ function pickAction(rule) {
1106
1011
  }
1107
1012
  return void 0;
1108
1013
  }
1109
- var DIALECT_CATEGORIES = [
1110
- {
1111
- id: "relational",
1112
- labelKey: "categoryRelational",
1113
- icon: CircleStackIcon,
1114
- gradient: "from-blue-500 to-indigo-600",
1115
- dialects: [
1116
- { value: "postgres", label: "PostgreSQL", defaultPort: 5432, formType: "standard" },
1117
- { value: "mysql", label: "MySQL", defaultPort: 3306, formType: "standard" },
1118
- { value: "mariadb", label: "MariaDB", defaultPort: 3306, formType: "standard" },
1119
- { value: "mssql", label: "SQL Server", defaultPort: 1433, formType: "standard" },
1120
- { value: "oracle", label: "Oracle", defaultPort: 1521, formType: "standard" },
1121
- { value: "db2", label: "IBM Db2", defaultPort: 5e4, formType: "standard" },
1122
- { value: "cockroachdb", label: "CockroachDB", defaultPort: 26257, formType: "standard" },
1123
- { value: "timescaledb", label: "TimescaleDB", defaultPort: 5432, formType: "standard" },
1124
- { value: "sqlite", label: "SQLite", formType: "connection-string" },
1125
- { value: "duckdb", label: "DuckDB", formType: "connection-string" }
1126
- ]
1127
- },
1128
- {
1129
- id: "nosql",
1130
- labelKey: "categoryNoSql",
1131
- icon: ServerStackIcon,
1132
- gradient: "from-emerald-500 to-teal-600",
1133
- dialects: [
1134
- { value: "mongodb", label: "MongoDB", defaultPort: 27017, formType: "connection-string" },
1135
- { value: "cassandra", label: "Cassandra", defaultPort: 9042, formType: "standard" },
1136
- { value: "scylladb", label: "ScyllaDB", defaultPort: 9042, formType: "standard" },
1137
- { value: "dynamodb", label: "DynamoDB", formType: "cloud-key" },
1138
- { value: "cosmosdb", label: "CosmosDB", formType: "connection-string" },
1139
- { value: "arangodb", label: "ArangoDB", defaultPort: 8529, formType: "standard" }
1140
- ]
1141
- },
1142
- {
1143
- id: "warehouse",
1144
- labelKey: "categoryWarehouse",
1145
- icon: CloudIcon,
1146
- gradient: "from-purple-500 to-violet-600",
1147
- dialects: [
1148
- { value: "bigquery", label: "BigQuery", formType: "cloud-bigquery" },
1149
- { value: "snowflake", label: "Snowflake", formType: "cloud-snowflake" },
1150
- { value: "clickhouse", label: "ClickHouse", defaultPort: 8123, formType: "standard" }
1151
- ]
1152
- },
1153
- {
1154
- id: "timeseries",
1155
- labelKey: "categoryTimeSeries",
1156
- icon: ClockIcon,
1157
- gradient: "from-sky-500 to-cyan-600",
1158
- dialects: [
1159
- { value: "influxdb", label: "InfluxDB", formType: "cloud-key" },
1160
- { value: "timestream", label: "Timestream", formType: "cloud-key" }
1161
- ]
1162
- },
1163
- {
1164
- id: "graph",
1165
- labelKey: "categoryGraph",
1166
- icon: ShareIcon,
1167
- gradient: "from-pink-500 to-rose-600",
1168
- dialects: [
1169
- { value: "neo4j", label: "Neo4j", defaultPort: 7687, formType: "standard" },
1170
- { value: "neptune", label: "Neptune", formType: "connection-string" }
1171
- ]
1172
- },
1173
- {
1174
- id: "keyvalue",
1175
- labelKey: "categoryKeyValue",
1176
- icon: KeyIcon,
1177
- gradient: "from-red-500 to-orange-600",
1178
- dialects: [
1179
- { value: "redis", label: "Redis", defaultPort: 6379, formType: "standard" }
1180
- ]
1181
- },
1182
- {
1183
- id: "search",
1184
- labelKey: "categorySearch",
1185
- icon: MagnifyingGlassIcon,
1186
- gradient: "from-amber-500 to-yellow-600",
1187
- dialects: [
1188
- { value: "elasticsearch", label: "Elasticsearch", defaultPort: 9200, formType: "standard" },
1189
- { value: "opensearch", label: "OpenSearch", defaultPort: 9200, formType: "standard" },
1190
- { value: "pinecone", label: "Pinecone", formType: "vector-key" },
1191
- { value: "qdrant", label: "Qdrant", defaultPort: 6333, formType: "standard" },
1192
- { value: "weaviate", label: "Weaviate", defaultPort: 8080, formType: "standard" },
1193
- { value: "milvus", label: "Milvus", defaultPort: 19530, formType: "standard" },
1194
- { value: "chromadb", label: "ChromaDB", defaultPort: 8e3, formType: "standard" }
1195
- ]
1196
- }
1197
- ];
1198
- function findDialect(value) {
1199
- for (const category of DIALECT_CATEGORIES) {
1200
- const found = category.dialects.find((d) => d.value === value);
1201
- if (found) return found;
1202
- }
1203
- return void 0;
1204
- }
1205
- function findCategory(dialectValue) {
1206
- return DIALECT_CATEGORIES.find((c) => c.dialects.some((d) => d.value === dialectValue));
1207
- }
1208
- function DialectPicker({
1209
- labels,
1210
- onSelect
1211
- }) {
1212
- return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
1213
- /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: labels.stepSelectType }),
1214
- DIALECT_CATEGORIES.map((category) => /* @__PURE__ */ jsxs("div", { children: [
1215
- /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2", children: [
1216
- /* @__PURE__ */ jsx("div", { className: `flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br ${category.gradient}`, children: /* @__PURE__ */ jsx(category.icon, { className: "h-4 w-4 text-white" }) }),
1217
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-gray-700 dark:text-gray-200", children: labels[category.labelKey] ?? category.id })
1218
- ] }),
1219
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-2 sm:grid-cols-3", children: category.dialects.map((dialect) => /* @__PURE__ */ jsxs(
1220
- "button",
1221
- {
1222
- type: "button",
1223
- onClick: () => onSelect(dialect.value),
1224
- className: "group flex items-center gap-2 rounded-xl border border-gray-200/60 bg-white/60 px-3 py-2.5 text-left text-sm font-medium text-gray-700 transition-all hover:border-amber-400/60 hover:bg-amber-50/50 hover:text-amber-700 active:scale-[0.97] dark:border-white/10 dark:bg-white/5 dark:text-gray-300 dark:hover:border-amber-400/40 dark:hover:bg-amber-500/10 dark:hover:text-amber-300",
1225
- children: [
1226
- /* @__PURE__ */ jsx(CircleStackIcon, { className: "h-4 w-4 shrink-0 text-gray-400 transition-colors group-hover:text-amber-500 dark:text-gray-500" }),
1227
- dialect.label
1228
- ]
1229
- },
1230
- dialect.value
1231
- )) })
1232
- ] }, category.id))
1233
- ] });
1234
- }
1235
- function ConnectionForm({
1236
- dialect,
1237
- labels,
1238
- onBack,
1239
- onSubmit
1240
- }) {
1241
- const [testStatus, setTestStatus] = useState("idle");
1242
- const category = findCategory(dialect.value);
1243
- function handleSubmit(event) {
1244
- event.preventDefault();
1245
- const formData = new FormData(event.currentTarget);
1246
- const data = {
1247
- name: String(formData.get("name") ?? "").trim(),
1248
- dialect: dialect.value
1249
- };
1250
- for (const key of ["host", "database", "username", "password", "schema", "connectionString", "projectId", "dataset", "keyFile", "account", "warehouse", "region", "bucket", "token", "apiKey", "environment", "index", "url"]) {
1251
- const val = String(formData.get(key) ?? "").trim();
1252
- if (val) data[key] = val;
1253
- }
1254
- const port = String(formData.get("port") ?? "").trim();
1255
- if (port) data.port = Number(port);
1256
- data.ssl = formData.get("ssl") === "on";
1257
- data.readOnly = formData.get("readOnly") === "on";
1258
- const maxPoolSize = String(formData.get("maxPoolSize") ?? "").trim();
1259
- if (maxPoolSize) {
1260
- const parsed = Number(maxPoolSize);
1261
- if (Number.isFinite(parsed) && parsed > 0) data.maxPoolSize = parsed;
1262
- }
1263
- const timeoutMs = String(formData.get("timeoutMs") ?? "").trim();
1264
- if (timeoutMs) {
1265
- const parsed = Number(timeoutMs);
1266
- if (Number.isFinite(parsed) && parsed > 0) data.timeoutMs = parsed;
1267
- }
1268
- const allowedTables = splitList(String(formData.get("allowedTables") ?? ""));
1269
- if (allowedTables.length > 0) data.allowedTables = allowedTables;
1270
- const blockedColumns = splitList(String(formData.get("blockedColumns") ?? ""));
1271
- if (blockedColumns.length > 0) data.blockedColumns = blockedColumns;
1272
- onSubmit(data);
1273
- }
1274
- function handleTestConnection() {
1275
- setTestStatus("testing");
1276
- setTimeout(() => {
1277
- setTestStatus("success");
1278
- setTimeout(() => setTestStatus("idle"), 3e3);
1279
- }, 1500);
1280
- }
1281
- function renderFields() {
1282
- switch (dialect.formType) {
1283
- case "standard":
1284
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1285
- /* @__PURE__ */ jsx(FormInput, { name: "host", label: labels.fieldHost, placeholder: labels.fieldHostPlaceholder, required: true }),
1286
- /* @__PURE__ */ jsx(FormInput, { name: "port", label: labels.fieldPort, type: "number", defaultValue: dialect.defaultPort }),
1287
- /* @__PURE__ */ jsx(FormInput, { name: "database", label: labels.fieldDatabase, placeholder: labels.fieldDatabasePlaceholder, required: true }),
1288
- /* @__PURE__ */ jsx(FormInput, { name: "username", label: labels.fieldUsername, placeholder: labels.fieldUsernamePlaceholder }),
1289
- /* @__PURE__ */ jsx(FormInput, { name: "password", label: labels.fieldPassword, type: "password", placeholder: labels.fieldPasswordPlaceholder }),
1290
- /* @__PURE__ */ jsx(FormInput, { name: "schema", label: labels.fieldSchema, placeholder: labels.fieldSchemaPlaceholder })
1291
- ] });
1292
- case "connection-string":
1293
- return /* @__PURE__ */ jsx("div", { className: "col-span-full", children: /* @__PURE__ */ jsx(FormInput, { name: "connectionString", label: labels.fieldConnectionString, placeholder: labels.fieldConnectionStringPlaceholder, required: true }) });
1294
- case "cloud-bigquery":
1295
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1296
- /* @__PURE__ */ jsx(FormInput, { name: "projectId", label: labels.fieldProjectId, placeholder: labels.fieldProjectIdPlaceholder, required: true }),
1297
- /* @__PURE__ */ jsx(FormInput, { name: "dataset", label: labels.fieldDataset, placeholder: labels.fieldDatasetPlaceholder, required: true }),
1298
- /* @__PURE__ */ jsx("div", { className: "col-span-full", children: /* @__PURE__ */ jsx(FormInput, { name: "keyFile", label: labels.fieldKeyFile, placeholder: labels.fieldKeyFilePlaceholder }) })
1299
- ] });
1300
- case "cloud-snowflake":
1301
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1302
- /* @__PURE__ */ jsx(FormInput, { name: "account", label: labels.fieldAccount, placeholder: labels.fieldAccountPlaceholder, required: true }),
1303
- /* @__PURE__ */ jsx(FormInput, { name: "warehouse", label: labels.fieldWarehouse, placeholder: labels.fieldWarehousePlaceholder, required: true }),
1304
- /* @__PURE__ */ jsx(FormInput, { name: "database", label: labels.fieldDatabase, placeholder: labels.fieldDatabasePlaceholder, required: true }),
1305
- /* @__PURE__ */ jsx(FormInput, { name: "username", label: labels.fieldUsername, placeholder: labels.fieldUsernamePlaceholder, required: true }),
1306
- /* @__PURE__ */ jsx(FormInput, { name: "password", label: labels.fieldPassword, type: "password", placeholder: labels.fieldPasswordPlaceholder }),
1307
- /* @__PURE__ */ jsx(FormInput, { name: "schema", label: labels.fieldSchema, placeholder: labels.fieldSchemaPlaceholder })
1308
- ] });
1309
- case "cloud-key":
1310
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1311
- /* @__PURE__ */ jsx(FormInput, { name: "region", label: labels.fieldRegion, placeholder: labels.fieldRegionPlaceholder, required: true }),
1312
- /* @__PURE__ */ jsx(FormInput, { name: "token", label: labels.fieldToken, type: "password", placeholder: labels.fieldTokenPlaceholder, required: true }),
1313
- /* @__PURE__ */ jsx(FormInput, { name: "bucket", label: labels.fieldBucket, placeholder: labels.fieldBucketPlaceholder })
1314
- ] });
1315
- case "vector-key":
1316
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1317
- /* @__PURE__ */ jsx(FormInput, { name: "apiKey", label: labels.fieldApiKey, type: "password", placeholder: labels.fieldApiKeyPlaceholder, required: true }),
1318
- /* @__PURE__ */ jsx(FormInput, { name: "environment", label: labels.fieldEnvironment, placeholder: labels.fieldEnvironmentPlaceholder, required: true }),
1319
- /* @__PURE__ */ jsx(FormInput, { name: "index", label: labels.fieldIndex, placeholder: labels.fieldIndexPlaceholder })
1320
- ] });
1321
- }
1322
- }
1323
- return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [
1324
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1325
- /* @__PURE__ */ jsx(
1326
- "button",
1327
- {
1328
- type: "button",
1329
- onClick: onBack,
1330
- className: "flex h-8 w-8 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 dark:hover:bg-white/10 dark:hover:text-gray-300",
1331
- children: /* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-4 w-4" })
1332
- }
1333
- ),
1334
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1335
- /* @__PURE__ */ jsx("div", { className: `flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br ${category?.gradient ?? "from-gray-400 to-gray-500"}`, children: category ? /* @__PURE__ */ jsx(category.icon, { className: "h-4 w-4 text-white" }) : /* @__PURE__ */ jsx(CircleStackIcon, { className: "h-4 w-4 text-white" }) }),
1336
- /* @__PURE__ */ jsxs("div", { children: [
1337
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-white", children: dialect.label }),
1338
- /* @__PURE__ */ jsx("span", { className: "ml-2 text-xs text-gray-400", children: labels[category?.labelKey ?? ""] ?? "" })
1339
- ] })
1340
- ] })
1341
- ] }),
1342
- /* @__PURE__ */ jsx(FormInput, { name: "name", label: labels.fieldName, placeholder: labels.fieldNamePlaceholder, required: true }),
1343
- /* @__PURE__ */ jsx(FormGrid, { children: renderFields() }),
1344
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-6 pt-2", children: [
1345
- /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300", children: [
1346
- /* @__PURE__ */ jsx(
1347
- "input",
1348
- {
1349
- type: "checkbox",
1350
- name: "ssl",
1351
- defaultChecked: true,
1352
- className: "h-4 w-4 rounded border-gray-300 text-amber-600 focus:ring-amber-500 dark:border-gray-600 dark:bg-gray-800"
1353
- }
1354
- ),
1355
- labels.fieldSsl
1356
- ] }),
1357
- /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300", children: [
1358
- /* @__PURE__ */ jsx(
1359
- "input",
1360
- {
1361
- type: "checkbox",
1362
- name: "readOnly",
1363
- defaultChecked: true,
1364
- className: "h-4 w-4 rounded border-gray-300 text-amber-600 focus:ring-amber-500 dark:border-gray-600 dark:bg-gray-800"
1365
- }
1366
- ),
1367
- labels.fieldReadOnly
1368
- ] })
1369
- ] }),
1370
- /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500", children: labels.fieldReadOnlyHelp }),
1371
- /* @__PURE__ */ jsxs("details", { className: "rounded-xl border border-gray-200/60 bg-white/40 p-3 dark:border-white/10 dark:bg-white/5", children: [
1372
- /* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.advancedToggle ?? "Governance & performance" }),
1373
- /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-3", children: [
1374
- /* @__PURE__ */ jsxs(FormGrid, { children: [
1375
- /* @__PURE__ */ jsx(
1376
- FormInput,
1377
- {
1378
- name: "maxPoolSize",
1379
- label: labels.fieldMaxPoolSize ?? "Max pool size",
1380
- type: "number",
1381
- min: 1,
1382
- max: 100,
1383
- placeholder: "5"
1384
- }
1385
- ),
1386
- /* @__PURE__ */ jsx(
1387
- FormInput,
1388
- {
1389
- name: "timeoutMs",
1390
- label: labels.fieldTimeoutMs ?? "Timeout (ms)",
1391
- type: "number",
1392
- min: 100,
1393
- placeholder: "5000"
1394
- }
1395
- )
1396
- ] }),
1397
- /* @__PURE__ */ jsx(
1398
- FormInput,
1399
- {
1400
- name: "allowedTables",
1401
- label: labels.fieldAllowedTables ?? "Allowed tables (comma-separated)",
1402
- placeholder: "stations, current_prices, competitor_prices"
1403
- }
1404
- ),
1405
- /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500", children: labels.fieldAllowedTablesHelp ?? "Leave blank to allow every table the credential can see. Otherwise only the listed tables are queryable from workflows." }),
1406
- /* @__PURE__ */ jsx(
1407
- FormInput,
1408
- {
1409
- name: "blockedColumns",
1410
- label: labels.fieldBlockedColumns ?? "Blocked columns (comma-separated)",
1411
- placeholder: "customers.ssn, employees.salary"
1412
- }
1413
- ),
1414
- /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500", children: labels.fieldBlockedColumnsHelp ?? "Columns the driver must never surface, even if referenced by a workflow. Use table.column notation for specificity." })
1415
- ] })
1416
- ] }),
1417
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 border-t border-gray-200/60 pt-5 dark:border-white/10", children: [
1418
- /* @__PURE__ */ jsx(
1419
- Button,
1420
- {
1421
- type: "button",
1422
- size: "sm",
1423
- color: "zinc",
1424
- onClick: handleTestConnection,
1425
- disabled: testStatus === "testing",
1426
- children: testStatus === "testing" ? labels.testing : labels.testConnection
1427
- }
1428
- ),
1429
- testStatus === "success" && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-xs font-medium text-emerald-600 dark:text-emerald-400", children: [
1430
- /* @__PURE__ */ jsx(CheckCircleIcon, { className: "h-4 w-4" }),
1431
- labels.connectionSuccess
1432
- ] }),
1433
- testStatus === "failed" && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-xs font-medium text-red-600 dark:text-red-400", children: [
1434
- /* @__PURE__ */ jsx(XCircleIcon, { className: "h-4 w-4" }),
1435
- labels.connectionFailed
1436
- ] }),
1437
- /* @__PURE__ */ jsx("div", { className: "flex-1" }),
1438
- /* @__PURE__ */ jsx(Button, { type: "submit", size: "sm", color: "amber", children: labels.save })
1439
- ] })
1440
- ] });
1441
- }
1442
- function DatasourceFormModal({ open, onClose, labels, onSave }) {
1443
- const [selectedDialect, setSelectedDialect] = useState(null);
1444
- const dialect = selectedDialect ? findDialect(selectedDialect) : null;
1445
- function handleClose() {
1446
- setSelectedDialect(null);
1447
- onClose();
1448
- }
1449
- function handleSave(data) {
1450
- onSave(data);
1451
- handleClose();
1452
- }
1453
- return /* @__PURE__ */ jsx(
1454
- GlassModal,
1455
- {
1456
- open,
1457
- onClose: handleClose,
1458
- title: labels.createTitle,
1459
- subtitle: dialect ? labels.stepConfigure : labels.stepSelectType,
1460
- icon: /* @__PURE__ */ jsx(CircleStackIcon, { className: "h-5 w-5" }),
1461
- gradient: "from-amber-500 to-orange-600",
1462
- maxWidth: "3xl",
1463
- children: dialect ? /* @__PURE__ */ jsx(
1464
- ConnectionForm,
1465
- {
1466
- dialect,
1467
- labels,
1468
- onBack: () => setSelectedDialect(null),
1469
- onSubmit: handleSave
1470
- }
1471
- ) : /* @__PURE__ */ jsx(DialectPicker, { labels, onSelect: setSelectedDialect })
1472
- }
1473
- );
1474
- }
1475
- function DatasourceModal({ open, onClose, labels, onSave }) {
1476
- const [selectedDialect, setSelectedDialect] = useState(null);
1477
- const dialect = selectedDialect ? findDialect(selectedDialect) : null;
1478
- function handleClose() {
1479
- setSelectedDialect(null);
1480
- onClose();
1481
- }
1482
- function handleSave(data) {
1483
- onSave(data);
1484
- handleClose();
1485
- }
1486
- return /* @__PURE__ */ jsx(
1487
- GlassModal,
1488
- {
1489
- open,
1490
- onClose: handleClose,
1491
- title: labels.createTitle,
1492
- subtitle: dialect ? labels.stepConfigure : labels.stepSelectType,
1493
- icon: /* @__PURE__ */ jsx(CircleStackIcon, { className: "h-5 w-5" }),
1494
- gradient: "from-amber-500 to-orange-600",
1495
- maxWidth: "3xl",
1496
- children: dialect ? /* @__PURE__ */ jsx(
1497
- ConnectionForm,
1498
- {
1499
- dialect,
1500
- labels,
1501
- onBack: () => setSelectedDialect(null),
1502
- onSubmit: handleSave
1503
- }
1504
- ) : /* @__PURE__ */ jsx(DialectPicker, { labels, onSelect: setSelectedDialect })
1505
- }
1506
- );
1507
- }
1508
- function splitList(raw) {
1509
- return raw.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
1510
- }
1511
1014
  var SAMPLE_DATASOURCES = [
1512
1015
  {
1513
1016
  id: "ds_bigquery_analytics",
@@ -1771,7 +1274,749 @@ function DatasourcesPageView({
1771
1274
  )
1772
1275
  ] });
1773
1276
  }
1277
+ function DashboardPageView({ labels, appLogo }) {
1278
+ const hero = /* @__PURE__ */ jsxs("div", { className: "w-full text-center", children: [
1279
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center mb-6", children: appLogo }),
1280
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-base text-gray-500 dark:text-gray-400", children: labels.subtitle })
1281
+ ] });
1282
+ return /* @__PURE__ */ jsx(ManagementPageLayout, { hero, content: null });
1283
+ }
1284
+ function AgentsIndexPageView({ labels }) {
1285
+ const Link = useLink();
1286
+ const tiles = [
1287
+ { id: "config", title: labels.configTitle, subtitle: labels.configSubtitle, href: "/agents/config", gradient: "from-violet-500 to-indigo-700", icon: CpuChipIcon },
1288
+ { id: "tools", title: labels.toolDefinitionsTitle, subtitle: labels.toolDefinitionsSubtitle, href: "/agents/tool-definitions", gradient: "from-amber-500 to-orange-700", icon: WrenchScrewdriverIcon },
1289
+ { id: "models", title: labels.modelsTitle, subtitle: labels.modelsSubtitle, href: "/agents/models", gradient: "from-emerald-500 to-teal-700", icon: CubeTransparentIcon },
1290
+ { id: "prompts", title: labels.promptsTitle, subtitle: labels.promptsSubtitle, href: "/agents/prompts", gradient: "from-sky-500 to-blue-700", icon: ChatBubbleLeftEllipsisIcon }
1291
+ ];
1292
+ const hero = /* @__PURE__ */ jsx(
1293
+ HeroSection,
1294
+ {
1295
+ icon: /* @__PURE__ */ jsx(CpuChipIcon, { className: "h-5 w-5" }),
1296
+ label: labels.title,
1297
+ title: labels.title,
1298
+ subtitle: labels.subtitle,
1299
+ gradient: "from-violet-500 to-indigo-700"
1300
+ }
1301
+ );
1302
+ const content = /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4", children: tiles.map((tile) => {
1303
+ const Icon = tile.icon;
1304
+ return /* @__PURE__ */ jsx(Link, { href: tile.href, className: "block focus:outline-none", children: /* @__PURE__ */ jsx(
1305
+ EntityCard,
1306
+ {
1307
+ accentGradient: tile.gradient,
1308
+ icon: /* @__PURE__ */ jsx("div", { className: `flex h-11 w-11 items-center justify-center rounded-lg bg-gradient-to-br ${tile.gradient} shadow-lg`, children: /* @__PURE__ */ jsx(Icon, { className: "h-6 w-6 text-white" }) }),
1309
+ title: tile.title,
1310
+ children: /* @__PURE__ */ jsx("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: tile.subtitle })
1311
+ }
1312
+ ) }, tile.id);
1313
+ }) });
1314
+ return /* @__PURE__ */ jsx(ManagementPageLayout, { hero, content });
1315
+ }
1316
+ function WorkflowsPageView({ labels, workflows, onCreate, onUpdateMeta, onPublish }) {
1317
+ const selectedWorkflow = workflows[0] ?? null;
1318
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
1319
+ /* @__PURE__ */ jsx(
1320
+ SectionHeader,
1321
+ {
1322
+ icon: /* @__PURE__ */ jsx(RectangleStackIcon, { className: "h-5 w-5 text-white" }),
1323
+ title: labels.title,
1324
+ subtitle: labels.subtitle,
1325
+ gradient: "from-sky-500 to-indigo-600"
1326
+ }
1327
+ ),
1328
+ /* @__PURE__ */ jsxs("section", { className: "liquid-surface rounded-2xl p-4 space-y-3", children: [
1329
+ /* @__PURE__ */ jsx(Text, { className: "font-semibold text-slate-900 dark:text-slate-100", children: labels.add }),
1330
+ /* @__PURE__ */ jsx(
1331
+ Form,
1332
+ {
1333
+ onSubmit: (event) => {
1334
+ event.preventDefault();
1335
+ const formData = new FormData(event.currentTarget);
1336
+ const name = String(formData.get("name") ?? "").trim();
1337
+ const description = String(formData.get("description") ?? "").trim();
1338
+ if (!name) return;
1339
+ onCreate({ name, description });
1340
+ event.currentTarget.reset();
1341
+ },
1342
+ children: /* @__PURE__ */ jsxs(FormGrid, { children: [
1343
+ /* @__PURE__ */ jsx(FormInput, { name: "name", label: labels.workflowName, placeholder: labels.workflowNamePlaceholder, required: true }),
1344
+ /* @__PURE__ */ jsx(FormTextarea, { name: "description", label: labels.description, placeholder: labels.workflowDescriptionPlaceholder, rows: 3 }),
1345
+ /* @__PURE__ */ jsx(FormActionsRow, { children: /* @__PURE__ */ jsx(Button, { type: "submit", children: labels.create }) })
1346
+ ] })
1347
+ }
1348
+ )
1349
+ ] }),
1350
+ /* @__PURE__ */ jsxs("section", { className: "liquid-surface rounded-2xl p-4 space-y-3", children: [
1351
+ /* @__PURE__ */ jsx(Text, { className: "font-semibold text-slate-900 dark:text-slate-100", children: labels.registry }),
1352
+ /* @__PURE__ */ jsxs(Table, { children: [
1353
+ /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
1354
+ /* @__PURE__ */ jsx(TableHeader, { children: labels.name }),
1355
+ /* @__PURE__ */ jsx(TableHeader, { children: labels.description }),
1356
+ /* @__PURE__ */ jsx(TableHeader, { children: labels.version }),
1357
+ /* @__PURE__ */ jsx(TableHeader, { children: labels.status }),
1358
+ /* @__PURE__ */ jsx(TableHeader, { children: labels.actions })
1359
+ ] }) }),
1360
+ /* @__PURE__ */ jsx(TableBody, { children: workflows.map((workflow) => /* @__PURE__ */ jsxs(TableRow, { children: [
1361
+ /* @__PURE__ */ jsx(TableCell, { children: workflow.name }),
1362
+ /* @__PURE__ */ jsx(TableCell, { children: workflow.description }),
1363
+ /* @__PURE__ */ jsx(TableCell, { children: String(workflow.version) }),
1364
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Badge, { children: workflow.isDraft ? labels.statusDraft : labels.statusPublished }) }),
1365
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
1366
+ /* @__PURE__ */ jsx(
1367
+ Form,
1368
+ {
1369
+ onSubmit: (event) => {
1370
+ event.preventDefault();
1371
+ onUpdateMeta({
1372
+ workflowId: workflow.id,
1373
+ name: workflow.name ?? "",
1374
+ description: workflow.description ?? ""
1375
+ });
1376
+ },
1377
+ children: /* @__PURE__ */ jsx(InlineForm, { children: /* @__PURE__ */ jsx(Button, { type: "submit", outline: true, children: labels.saveMeta }) })
1378
+ }
1379
+ ),
1380
+ /* @__PURE__ */ jsx(Button, { type: "button", color: "sky", onClick: () => onPublish(workflow.id), children: labels.publish })
1381
+ ] }) })
1382
+ ] }, workflow.id)) })
1383
+ ] })
1384
+ ] }),
1385
+ /* @__PURE__ */ jsxs("section", { className: "liquid-surface rounded-2xl p-4 space-y-3", children: [
1386
+ /* @__PURE__ */ jsx(Text, { className: "font-semibold text-slate-900 dark:text-slate-100", children: labels.workspace }),
1387
+ selectedWorkflow ? /* @__PURE__ */ jsx("div", { className: "min-h-[680px] rounded-2xl border border-white/65 dark:border-white/12 overflow-hidden", children: /* @__PURE__ */ jsx(WorkflowWorkspace, { graph: adaptWorkflowGraphToUi(selectedWorkflow.graph) }) }) : /* @__PURE__ */ jsx(Text, { children: labels.empty })
1388
+ ] })
1389
+ ] });
1390
+ }
1391
+ var BADGE_COLOR = {
1392
+ completed: "emerald",
1393
+ failed: "rose",
1394
+ running: "sky",
1395
+ pending: "amber",
1396
+ cancelled: "zinc"
1397
+ };
1398
+ function WorkflowRunsPageView({ labels, runs, loading, onCancel, onReplay, onView, onViewTimeline }) {
1399
+ const [statusFilter, setStatusFilter] = useState("all");
1400
+ const statusOptions = useMemo(() => [
1401
+ { value: "all", label: labels.filterAll },
1402
+ { value: "pending", label: labels.statusPending },
1403
+ { value: "running", label: labels.statusRunning },
1404
+ { value: "completed", label: labels.statusCompleted },
1405
+ { value: "failed", label: labels.statusFailed },
1406
+ { value: "cancelled", label: labels.statusCancelled }
1407
+ ], [labels]);
1408
+ const statusLabelFor = (status) => {
1409
+ switch (status) {
1410
+ case "pending":
1411
+ return labels.statusPending;
1412
+ case "running":
1413
+ return labels.statusRunning;
1414
+ case "completed":
1415
+ return labels.statusCompleted;
1416
+ case "failed":
1417
+ return labels.statusFailed;
1418
+ case "cancelled":
1419
+ return labels.statusCancelled;
1420
+ default:
1421
+ return status;
1422
+ }
1423
+ };
1424
+ const filteredRuns = statusFilter === "all" ? runs : runs.filter((run) => run.status === statusFilter);
1425
+ const hero = /* @__PURE__ */ jsx(
1426
+ HeroSection,
1427
+ {
1428
+ icon: /* @__PURE__ */ jsx(ClockIcon, { className: "h-5 w-5" }),
1429
+ label: labels.title,
1430
+ title: labels.title,
1431
+ subtitle: labels.subtitle,
1432
+ gradient: "from-indigo-500 to-sky-700",
1433
+ toolbar: /* @__PURE__ */ jsx("div", { className: "w-48", children: /* @__PURE__ */ jsx(
1434
+ FormSelect,
1435
+ {
1436
+ name: "statusFilter",
1437
+ label: labels.filterStatus,
1438
+ options: statusOptions,
1439
+ value: statusFilter,
1440
+ onValueChange: setStatusFilter
1441
+ }
1442
+ ) })
1443
+ }
1444
+ );
1445
+ const content = loading ? /* @__PURE__ */ jsx(PageLoadingState, {}) : filteredRuns.length === 0 ? /* @__PURE__ */ jsx(PageEmptyState, { title: labels.empty, message: labels.subtitle, iconName: "folder-open" }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filteredRuns.map((run) => /* @__PURE__ */ jsxs(
1446
+ EntityCard,
1447
+ {
1448
+ accentGradient: "from-indigo-500 to-sky-700",
1449
+ icon: /* @__PURE__ */ jsx("div", { className: "flex h-11 w-11 items-center justify-center rounded-lg bg-indigo-500/10 text-indigo-600 dark:bg-indigo-500/20 dark:text-indigo-400", children: /* @__PURE__ */ jsx(ClockIcon, { className: "h-6 w-6" }) }),
1450
+ title: run.id.slice(0, 8),
1451
+ subtitle: `${labels.startedAt}: ${new Date(run.createdAt).toLocaleString()}`,
1452
+ status: /* @__PURE__ */ jsx(Badge, { color: BADGE_COLOR[run.status] ?? "zinc", children: statusLabelFor(run.status) }),
1453
+ footer: /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
1454
+ onView && /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", outline: true, onClick: () => onView(run), children: labels.view }),
1455
+ onViewTimeline && labels.timeline && /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", outline: true, onClick: () => onViewTimeline(run), children: labels.timeline }),
1456
+ /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", outline: true, onClick: () => onReplay(run), children: labels.replay }),
1457
+ run.status === "running" && /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", color: "rose", onClick: () => onCancel(run), children: labels.cancel })
1458
+ ] }),
1459
+ children: [
1460
+ /* @__PURE__ */ jsxs("dl", { className: "mt-1 grid grid-cols-2 gap-1 text-xs text-slate-500 dark:text-slate-400", children: [
1461
+ /* @__PURE__ */ jsx("dt", { children: labels.duration }),
1462
+ /* @__PURE__ */ jsx("dd", { className: "text-right", children: formatDurationMs(run.totalDurationMs) }),
1463
+ /* @__PURE__ */ jsx("dt", { children: labels.triggeredBy }),
1464
+ /* @__PURE__ */ jsx("dd", { className: "text-right truncate", children: run.triggeredBy || "\u2014" })
1465
+ ] }),
1466
+ run.error && /* @__PURE__ */ jsx("p", { className: "mt-1 line-clamp-2 text-xs text-rose-600 dark:text-rose-400", children: run.error })
1467
+ ]
1468
+ },
1469
+ run.id
1470
+ )) });
1471
+ return /* @__PURE__ */ jsx(ManagementPageLayout, { hero, content });
1472
+ }
1473
+ function RunTimelinePageView({ labels, entries, loading, runId }) {
1474
+ const hero = /* @__PURE__ */ jsx(
1475
+ HeroSection,
1476
+ {
1477
+ icon: /* @__PURE__ */ jsx(ClockIcon, { className: "h-5 w-5" }),
1478
+ label: labels.title,
1479
+ title: labels.title,
1480
+ subtitle: `${labels.subtitle} \u2014 ${runId.slice(0, 8)}`,
1481
+ gradient: "from-indigo-500 to-violet-700"
1482
+ }
1483
+ );
1484
+ if (loading) {
1485
+ return /* @__PURE__ */ jsx(ManagementPageLayout, { hero, content: /* @__PURE__ */ jsx(PageLoadingState, {}) });
1486
+ }
1487
+ if (entries.length === 0) {
1488
+ return /* @__PURE__ */ jsx(
1489
+ ManagementPageLayout,
1490
+ {
1491
+ hero,
1492
+ content: /* @__PURE__ */ jsx(PageEmptyState, { title: labels.empty ?? "", message: "", iconName: "folder-open" })
1493
+ }
1494
+ );
1495
+ }
1496
+ return /* @__PURE__ */ jsx(
1497
+ ManagementPageLayout,
1498
+ {
1499
+ hero,
1500
+ content: /* @__PURE__ */ jsx(
1501
+ ExecutionTimelinePanel,
1502
+ {
1503
+ entries,
1504
+ labels
1505
+ }
1506
+ )
1507
+ }
1508
+ );
1509
+ }
1510
+ var PROVIDER_PRESETS = {
1511
+ anthropic_api: {
1512
+ label: "Anthropic API",
1513
+ description: "Claude Opus, Sonnet, Haiku via api.anthropic.com",
1514
+ exampleModels: ["claude-opus-4-7", "claude-sonnet-4-6"]
1515
+ },
1516
+ openai_api: {
1517
+ label: "OpenAI API",
1518
+ description: "GPT-4o, o3, o4-mini via api.openai.com",
1519
+ exampleModels: ["gpt-4o", "gpt-4o-mini"]
1520
+ },
1521
+ aws_bedrock: {
1522
+ label: "AWS Bedrock",
1523
+ description: "Anthropic / Meta / Mistral / Nova served through Bedrock",
1524
+ needsRegion: true,
1525
+ defaultRegion: "us-east-1",
1526
+ exampleModels: ["amazon.nova-lite-v1:0", "anthropic.claude-3-5-sonnet-20241022-v2:0"]
1527
+ },
1528
+ google_vertex: {
1529
+ label: "Google Vertex AI",
1530
+ description: "Gemini + third-party models on Vertex",
1531
+ needsRegion: true,
1532
+ defaultRegion: "us-central1",
1533
+ exampleModels: ["gemini-2.0-flash-exp", "gemini-1.5-pro"]
1534
+ },
1535
+ azure_openai: {
1536
+ label: "Azure OpenAI",
1537
+ description: "OpenAI deployments hosted on Azure",
1538
+ needsRegion: true,
1539
+ needsEndpoint: true,
1540
+ defaultRegion: "eastus"
1541
+ },
1542
+ groq: {
1543
+ label: "Groq",
1544
+ description: "Low-latency Llama / Mixtral inference via api.groq.com"
1545
+ },
1546
+ mistral: {
1547
+ label: "Mistral API",
1548
+ description: "mistral.ai hosted open-weight + commercial models"
1549
+ },
1550
+ huggingface: {
1551
+ label: "Hugging Face",
1552
+ description: "Inference endpoints + serverless inference API",
1553
+ needsEndpoint: true
1554
+ },
1555
+ ollama: {
1556
+ label: "Ollama",
1557
+ description: "Self-hosted Ollama server \u2014 provide the base URL",
1558
+ needsEndpoint: true
1559
+ },
1560
+ custom: {
1561
+ label: "Custom / OpenAI-compatible",
1562
+ description: "Any OpenAI-API-compatible HTTP endpoint",
1563
+ needsEndpoint: true
1564
+ }
1565
+ };
1566
+ var PROVIDER_OPTIONS = Object.keys(PROVIDER_PRESETS).map((slug) => ({
1567
+ value: slug,
1568
+ label: PROVIDER_PRESETS[slug].label
1569
+ }));
1570
+ function ConnectionsPageView({
1571
+ labels,
1572
+ connections,
1573
+ loading,
1574
+ onCreate,
1575
+ onUpdate,
1576
+ onDelete,
1577
+ onCreateSecret,
1578
+ secretNamePrefix = "platform"
1579
+ }) {
1580
+ const [createOpen, setCreateOpen] = useState(false);
1581
+ const [editing, setEditing] = useState(null);
1582
+ const hero = /* @__PURE__ */ jsx(
1583
+ HeroSection,
1584
+ {
1585
+ icon: /* @__PURE__ */ jsx(LinkIcon, { className: "h-5 w-5" }),
1586
+ label: labels.title,
1587
+ title: labels.title,
1588
+ subtitle: labels.subtitle,
1589
+ gradient: "from-sky-500 to-indigo-600",
1590
+ toolbar: /* @__PURE__ */ jsx(
1591
+ CreateActionButton,
1592
+ {
1593
+ mode: "desktop",
1594
+ label: labels.add,
1595
+ onClick: () => setCreateOpen(true),
1596
+ accent: "sky"
1597
+ }
1598
+ )
1599
+ }
1600
+ );
1601
+ const mobileAction = /* @__PURE__ */ jsx(
1602
+ CreateActionButton,
1603
+ {
1604
+ mode: "mobile",
1605
+ label: labels.add,
1606
+ onClick: () => setCreateOpen(true),
1607
+ accent: "sky"
1608
+ }
1609
+ );
1610
+ const content = loading ? /* @__PURE__ */ jsx(PageLoadingState, {}) : connections.length === 0 ? /* @__PURE__ */ jsx(PageEmptyState, { title: labels.empty, message: labels.subtitle, iconName: "folder-open" }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: connections.map((conn) => /* @__PURE__ */ jsx(
1611
+ EntityCard,
1612
+ {
1613
+ accentGradient: "from-sky-500 to-indigo-600",
1614
+ icon: /* @__PURE__ */ jsx("div", { className: "flex h-11 w-11 items-center justify-center rounded-lg bg-sky-500/10 text-sky-600 dark:bg-sky-500/20 dark:text-sky-400", children: /* @__PURE__ */ jsx(LinkIcon, { className: "h-6 w-6" }) }),
1615
+ title: conn.name,
1616
+ subtitle: providerLabel(conn.providerSlug),
1617
+ status: /* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
1618
+ /* @__PURE__ */ jsx(Badge, { color: conn.enabled ? "emerald" : "zinc", children: conn.enabled ? labels.enable : labels.disable }),
1619
+ conn.credentialRef ? /* @__PURE__ */ jsx(Badge, { color: "indigo", children: "Secret set" }) : /* @__PURE__ */ jsx(Badge, { color: "amber", children: "No secret" })
1620
+ ] }),
1621
+ footer: /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
1622
+ /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", outline: true, onClick: () => setEditing(conn), children: labels.edit }),
1623
+ /* @__PURE__ */ jsx(
1624
+ Button,
1625
+ {
1626
+ type: "button",
1627
+ size: "sm",
1628
+ color: "rose",
1629
+ onClick: async () => {
1630
+ if (window.confirm(labels.deleteConfirm)) await onDelete(conn);
1631
+ },
1632
+ children: labels.delete
1633
+ }
1634
+ )
1635
+ ] }),
1636
+ children: /* @__PURE__ */ jsxs("dl", { className: "mt-1 space-y-0.5 text-xs text-slate-500 dark:text-slate-400", children: [
1637
+ conn.region && /* @__PURE__ */ jsx(Row, { label: "Region", value: conn.region }),
1638
+ conn.endpoint && /* @__PURE__ */ jsx(Row, { label: "Endpoint", value: conn.endpoint }),
1639
+ conn.modelFilter && conn.modelFilter.length > 0 && /* @__PURE__ */ jsx(Row, { label: "Models", value: conn.modelFilter.join(", ") })
1640
+ ] })
1641
+ },
1642
+ conn.id
1643
+ )) });
1644
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1645
+ /* @__PURE__ */ jsx(ManagementPageLayout, { hero, content, mobileAction }),
1646
+ createOpen && /* @__PURE__ */ jsx(
1647
+ ConnectionEditor,
1648
+ {
1649
+ title: labels.createTitle,
1650
+ saveLabel: labels.save,
1651
+ initial: defaultConnectionFormValue(),
1652
+ mode: "create",
1653
+ onClose: () => setCreateOpen(false),
1654
+ onCreateSecret,
1655
+ secretNamePrefix,
1656
+ onSubmit: async (wire) => {
1657
+ await onCreate(wire);
1658
+ setCreateOpen(false);
1659
+ }
1660
+ }
1661
+ ),
1662
+ editing && /* @__PURE__ */ jsx(
1663
+ ConnectionEditor,
1664
+ {
1665
+ title: labels.editTitle,
1666
+ saveLabel: labels.save,
1667
+ initial: modelToFormValue(editing),
1668
+ mode: "edit",
1669
+ onClose: () => setEditing(null),
1670
+ onCreateSecret,
1671
+ secretNamePrefix,
1672
+ onSubmit: async (wire) => {
1673
+ await onUpdate(editing.id, wire);
1674
+ setEditing(null);
1675
+ }
1676
+ }
1677
+ )
1678
+ ] });
1679
+ }
1680
+ function ConnectionEditor({
1681
+ title,
1682
+ saveLabel,
1683
+ initial,
1684
+ mode,
1685
+ onClose,
1686
+ onSubmit,
1687
+ onCreateSecret,
1688
+ secretNamePrefix
1689
+ }) {
1690
+ const [value, setValue] = useState(initial);
1691
+ const [submitting, setSubmitting] = useState(false);
1692
+ const [error, setError] = useState(null);
1693
+ const preset = PROVIDER_PRESETS[value.providerSlug];
1694
+ const handleSubmit = async () => {
1695
+ setError(null);
1696
+ setSubmitting(true);
1697
+ try {
1698
+ let credentialRef = value.credentialRef;
1699
+ if (value.apiKey.trim().length > 0) {
1700
+ const secret = await onCreateSecret(`${secretNamePrefix}-${value.providerSlug}-${Date.now()}`, value.apiKey.trim());
1701
+ credentialRef = secret.id;
1702
+ }
1703
+ const modelFilter = parseCsv(value.modelFilter);
1704
+ let config;
1705
+ const trimmed = value.configJson.trim();
1706
+ if (trimmed.length > 0) {
1707
+ try {
1708
+ const parsed = JSON.parse(trimmed);
1709
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1710
+ throw new Error("config must be a JSON object");
1711
+ }
1712
+ config = parsed;
1713
+ } catch (e) {
1714
+ throw new Error(`Invalid config JSON: ${e.message}`);
1715
+ }
1716
+ }
1717
+ if (mode === "create") {
1718
+ const wire = {
1719
+ providerSlug: value.providerSlug,
1720
+ name: value.name.trim(),
1721
+ ...value.region.trim() && { region: value.region.trim() },
1722
+ ...value.endpoint.trim() && { endpoint: value.endpoint.trim() },
1723
+ ...credentialRef && { credentialRef },
1724
+ ...modelFilter.length > 0 && { modelFilter },
1725
+ ...config && { config }
1726
+ };
1727
+ await onSubmit(wire);
1728
+ } else {
1729
+ const wire = {
1730
+ name: value.name.trim() || void 0,
1731
+ region: value.region.trim() || void 0,
1732
+ endpoint: value.endpoint.trim() || void 0,
1733
+ ...credentialRef && { credentialRef },
1734
+ ...modelFilter.length > 0 ? { modelFilter } : {},
1735
+ ...config && { config }
1736
+ };
1737
+ await onSubmit(wire);
1738
+ }
1739
+ } catch (e) {
1740
+ setError(e.message);
1741
+ } finally {
1742
+ setSubmitting(false);
1743
+ }
1744
+ };
1745
+ useEffect(() => {
1746
+ if (mode === "create" && preset.needsRegion && !value.region && preset.defaultRegion) {
1747
+ setValue((v) => ({ ...v, region: preset.defaultRegion ?? "" }));
1748
+ }
1749
+ }, [mode, preset, value.region]);
1750
+ const placeholderModels = useMemo(() => {
1751
+ return preset.exampleModels?.join(", ") ?? "";
1752
+ }, [preset]);
1753
+ return /* @__PURE__ */ jsx(
1754
+ GlassModal,
1755
+ {
1756
+ open: true,
1757
+ onClose,
1758
+ title,
1759
+ maxWidth: "2xl",
1760
+ showFormFooter: true,
1761
+ submitLabel: submitting ? "\u2026" : saveLabel,
1762
+ onSubmit: (event) => {
1763
+ event.preventDefault();
1764
+ void handleSubmit();
1765
+ },
1766
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1767
+ /* @__PURE__ */ jsxs(FormGrid, { children: [
1768
+ /* @__PURE__ */ jsx(
1769
+ FormSelect,
1770
+ {
1771
+ label: "Provider",
1772
+ value: value.providerSlug,
1773
+ options: PROVIDER_OPTIONS,
1774
+ onValueChange: (slug) => setValue((v) => ({ ...v, providerSlug: slug })),
1775
+ disabled: mode === "edit",
1776
+ hint: preset.description
1777
+ }
1778
+ ),
1779
+ /* @__PURE__ */ jsx(
1780
+ FormInput,
1781
+ {
1782
+ label: "Display name",
1783
+ required: true,
1784
+ value: value.name,
1785
+ onValueChange: (name) => setValue((v) => ({ ...v, name })),
1786
+ placeholder: "Production Bedrock, Claude dev, \u2026"
1787
+ }
1788
+ ),
1789
+ preset.needsRegion && /* @__PURE__ */ jsx(
1790
+ FormInput,
1791
+ {
1792
+ label: "Region",
1793
+ value: value.region,
1794
+ onValueChange: (region) => setValue((v) => ({ ...v, region })),
1795
+ placeholder: preset.defaultRegion
1796
+ }
1797
+ ),
1798
+ preset.needsEndpoint && /* @__PURE__ */ jsx(
1799
+ FormInput,
1800
+ {
1801
+ label: "Endpoint URL",
1802
+ value: value.endpoint,
1803
+ onValueChange: (endpoint) => setValue((v) => ({ ...v, endpoint })),
1804
+ placeholder: "https://..."
1805
+ }
1806
+ )
1807
+ ] }),
1808
+ /* @__PURE__ */ jsx(
1809
+ FormInput,
1810
+ {
1811
+ label: value.credentialRef ? "Rotate API key (leave blank to keep current)" : "API key",
1812
+ type: "password",
1813
+ value: value.apiKey,
1814
+ onValueChange: (apiKey) => setValue((v) => ({ ...v, apiKey })),
1815
+ placeholder: value.credentialRef ? "\u2022\u2022\u2022 stored in vault" : "sk-...",
1816
+ hint: value.credentialRef ? `Stored secret: ${value.credentialRef.slice(0, 8)}\u2026` : "Plaintext \u2014 pushed to windsock vault on save, never persisted here."
1817
+ }
1818
+ ),
1819
+ /* @__PURE__ */ jsx(
1820
+ FormInput,
1821
+ {
1822
+ label: "Model filter (comma-separated, optional)",
1823
+ value: value.modelFilter,
1824
+ onValueChange: (modelFilter) => setValue((v) => ({ ...v, modelFilter })),
1825
+ placeholder: placeholderModels,
1826
+ hint: "Leave blank to allow all models the provider exposes."
1827
+ }
1828
+ ),
1829
+ /* @__PURE__ */ jsxs("details", { className: "rounded-xl border border-slate-200 bg-slate-50/60 p-3 text-sm dark:border-slate-700 dark:bg-slate-900/40", children: [
1830
+ /* @__PURE__ */ jsx("summary", { className: "cursor-pointer font-medium text-slate-700 dark:text-slate-200", children: "Advanced config (JSON)" }),
1831
+ /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(
1832
+ FormTextarea,
1833
+ {
1834
+ rows: 4,
1835
+ value: value.configJson,
1836
+ onValueChange: (configJson) => setValue((v) => ({ ...v, configJson })),
1837
+ placeholder: '{\n "temperature": 0.2\n}',
1838
+ hint: "Free-form JSON passed to the runtime provider \u2014 e.g. Bedrock guardrail ids, Azure deployment overrides."
1839
+ }
1840
+ ) })
1841
+ ] }),
1842
+ error && /* @__PURE__ */ jsx("p", { className: "rounded-lg border border-red-400/40 bg-red-500/10 p-2 text-xs text-red-600 dark:text-red-300", children: error })
1843
+ ] })
1844
+ }
1845
+ );
1846
+ }
1847
+ function Row({ label, value }) {
1848
+ return /* @__PURE__ */ jsxs("div", { className: "flex gap-1 truncate", children: [
1849
+ /* @__PURE__ */ jsxs("dt", { className: "font-medium", children: [
1850
+ label,
1851
+ ":"
1852
+ ] }),
1853
+ /* @__PURE__ */ jsx("dd", { className: "truncate", children: value })
1854
+ ] });
1855
+ }
1856
+ function providerLabel(slug) {
1857
+ if (!slug) return "Unknown provider";
1858
+ const key = slug;
1859
+ return PROVIDER_PRESETS[key]?.label ?? slug;
1860
+ }
1861
+ function parseCsv(raw) {
1862
+ return raw.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
1863
+ }
1864
+ function defaultConnectionFormValue() {
1865
+ return {
1866
+ providerSlug: "anthropic_api",
1867
+ name: "",
1868
+ region: "",
1869
+ endpoint: "",
1870
+ apiKey: "",
1871
+ credentialRef: "",
1872
+ modelFilter: "",
1873
+ configJson: ""
1874
+ };
1875
+ }
1876
+ function modelToFormValue(conn) {
1877
+ return {
1878
+ providerSlug: conn.providerSlug ?? "custom",
1879
+ name: conn.name,
1880
+ region: conn.region ?? "",
1881
+ endpoint: conn.endpoint ?? "",
1882
+ apiKey: "",
1883
+ credentialRef: conn.credentialRef ?? "",
1884
+ modelFilter: (conn.modelFilter ?? []).join(", "),
1885
+ configJson: conn.config ? JSON.stringify(conn.config, null, 2) : ""
1886
+ };
1887
+ }
1888
+ function CredentialsPageView({ labels, credentials, loading, onCreate, onRotate, onDisable }) {
1889
+ const [createOpen, setCreateOpen] = useState(false);
1890
+ const [rotateFor, setRotateFor] = useState(null);
1891
+ const typeOptions = [
1892
+ { value: "generic", label: labels.typeGeneric },
1893
+ { value: "api_key", label: labels.typeApiKey },
1894
+ { value: "oauth", label: labels.typeOAuth },
1895
+ { value: "password", label: labels.typePassword }
1896
+ ];
1897
+ const hero = /* @__PURE__ */ jsx(
1898
+ HeroSection,
1899
+ {
1900
+ icon: /* @__PURE__ */ jsx(KeyIcon, { className: "h-5 w-5" }),
1901
+ label: labels.title,
1902
+ title: labels.title,
1903
+ subtitle: labels.subtitle,
1904
+ gradient: "from-rose-500 to-orange-600",
1905
+ toolbar: /* @__PURE__ */ jsx(
1906
+ CreateActionButton,
1907
+ {
1908
+ mode: "desktop",
1909
+ label: labels.addCredential,
1910
+ onClick: () => setCreateOpen(true),
1911
+ accent: "rose"
1912
+ }
1913
+ )
1914
+ }
1915
+ );
1916
+ const mobileAction = /* @__PURE__ */ jsx(
1917
+ CreateActionButton,
1918
+ {
1919
+ mode: "mobile",
1920
+ label: labels.addCredential,
1921
+ onClick: () => setCreateOpen(true),
1922
+ accent: "rose"
1923
+ }
1924
+ );
1925
+ const content = loading ? /* @__PURE__ */ jsx(PageLoadingState, {}) : credentials.length === 0 ? /* @__PURE__ */ jsx(PageEmptyState, { title: labels.empty, message: labels.subtitle, iconName: "folder-open" }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: credentials.map((secret) => /* @__PURE__ */ jsxs(
1926
+ EntityCard,
1927
+ {
1928
+ accentGradient: "from-rose-500 to-orange-700",
1929
+ icon: /* @__PURE__ */ jsx("div", { className: "flex h-11 w-11 items-center justify-center rounded-lg bg-rose-500/10 text-rose-600 dark:bg-rose-500/20 dark:text-rose-400", children: /* @__PURE__ */ jsx(KeyIcon, { className: "h-6 w-6" }) }),
1930
+ title: secret.name,
1931
+ subtitle: secret.secretType,
1932
+ status: /* @__PURE__ */ jsx(Badge, { color: secret.disabled ? "zinc" : "emerald", children: secret.disabled ? labels.disable : "Active" }),
1933
+ footer: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1934
+ /* @__PURE__ */ jsx(CopyableId, { id: secret.secretId }),
1935
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
1936
+ /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", outline: true, onClick: () => setRotateFor(secret), children: [
1937
+ /* @__PURE__ */ jsx(ArrowPathIcon, { className: "mr-1 h-3.5 w-3.5" }),
1938
+ labels.rotate
1939
+ ] }),
1940
+ !secret.disabled && /* @__PURE__ */ jsxs(
1941
+ Button,
1942
+ {
1943
+ type: "button",
1944
+ size: "sm",
1945
+ color: "rose",
1946
+ onClick: () => {
1947
+ if (window.confirm(labels.disableConfirm)) onDisable(secret);
1948
+ },
1949
+ children: [
1950
+ /* @__PURE__ */ jsx(TrashIcon, { className: "mr-1 h-3.5 w-3.5" }),
1951
+ labels.disable
1952
+ ]
1953
+ }
1954
+ )
1955
+ ] })
1956
+ ] }),
1957
+ children: [
1958
+ secret.description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: secret.description }),
1959
+ /* @__PURE__ */ jsxs("dl", { className: "mt-2 grid grid-cols-2 gap-1 text-xs text-slate-500 dark:text-slate-400", children: [
1960
+ /* @__PURE__ */ jsx("dt", { children: labels.createdAt }),
1961
+ /* @__PURE__ */ jsx("dd", { className: "text-right", children: new Date(secret.createdAt).toLocaleDateString() }),
1962
+ /* @__PURE__ */ jsx("dt", { children: labels.expiresAt }),
1963
+ /* @__PURE__ */ jsx("dd", { className: "text-right", children: secret.expiresAt ? new Date(secret.expiresAt).toLocaleDateString() : labels.neverExpires })
1964
+ ] })
1965
+ ]
1966
+ },
1967
+ secret.secretId
1968
+ )) });
1969
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1970
+ /* @__PURE__ */ jsx(ManagementPageLayout, { hero, content, mobileAction }),
1971
+ /* @__PURE__ */ jsx(
1972
+ GlassModal,
1973
+ {
1974
+ open: createOpen,
1975
+ onClose: () => setCreateOpen(false),
1976
+ title: labels.createTitle,
1977
+ maxWidth: "lg",
1978
+ showFormFooter: true,
1979
+ submitLabel: labels.save,
1980
+ onSubmit: (event) => {
1981
+ const formData = new FormData(event.currentTarget);
1982
+ const name = String(formData.get("name") ?? "").trim();
1983
+ const value = String(formData.get("value") ?? "");
1984
+ const secretType = String(formData.get("secretType") ?? "generic");
1985
+ const description = String(formData.get("description") ?? "").trim() || void 0;
1986
+ if (!name || !value) return;
1987
+ onCreate({ name, value, secretType, description });
1988
+ setCreateOpen(false);
1989
+ },
1990
+ children: /* @__PURE__ */ jsxs(FormGrid, { children: [
1991
+ /* @__PURE__ */ jsx(FormInput, { name: "name", label: labels.name, placeholder: labels.namePlaceholder, required: true }),
1992
+ /* @__PURE__ */ jsx(FormSelect, { name: "secretType", label: labels.type, options: typeOptions, defaultValue: "generic" }),
1993
+ /* @__PURE__ */ jsx(FormInput, { name: "value", label: labels.value, placeholder: labels.valuePlaceholder, required: true, type: "password" }),
1994
+ /* @__PURE__ */ jsx(FormTextarea, { name: "description", label: labels.description, placeholder: labels.descriptionPlaceholder, rows: 2 })
1995
+ ] })
1996
+ }
1997
+ ),
1998
+ /* @__PURE__ */ jsx(
1999
+ GlassModal,
2000
+ {
2001
+ open: rotateFor !== null,
2002
+ onClose: () => setRotateFor(null),
2003
+ title: `${labels.rotate}: ${rotateFor?.name ?? ""}`,
2004
+ maxWidth: "md",
2005
+ showFormFooter: true,
2006
+ submitLabel: labels.rotate,
2007
+ onSubmit: (event) => {
2008
+ const formData = new FormData(event.currentTarget);
2009
+ const value = String(formData.get("value") ?? "");
2010
+ if (!value || !rotateFor) return;
2011
+ onRotate(rotateFor, value);
2012
+ setRotateFor(null);
2013
+ },
2014
+ children: /* @__PURE__ */ jsx(FormGrid, { children: /* @__PURE__ */ jsx(FormInput, { name: "value", label: labels.value, placeholder: labels.valuePlaceholder, required: true, type: "password" }) })
2015
+ }
2016
+ )
2017
+ ] });
2018
+ }
1774
2019
 
1775
- export { AgentsConfigPageView, AgentsModelsPageView, AgentsPromptsPageView, AgentsToolDefinitionsPageView, DIALECT_CATEGORIES, DatasourceFormModal, DatasourceModal, DatasourcesPageView, RulesPageView, TOOL_TYPES, UsersPageView, findCategory, findDialect, jsonSchemaToParameters, parametersToJsonSchema };
2020
+ export { AgentsConfigPageView, AgentsIndexPageView, AgentsModelsPageView, AgentsPromptsPageView, AgentsToolDefinitionsPageView, ConnectionsPageView, CredentialsPageView, DashboardPageView, DatasourcesPageView, RulesPageView, RunTimelinePageView, TOOL_TYPES, WorkflowRunsPageView, WorkflowsPageView, jsonSchemaToParameters, parametersToJsonSchema };
1776
2021
  //# sourceMappingURL=index.mjs.map
1777
2022
  //# sourceMappingURL=index.mjs.map