@contractspec/example.integration-hub 3.7.7 → 3.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/docs/index.js +2 -1
- package/dist/docs/integration-hub.docblock.js +2 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +669 -177
- package/dist/integration-hub.feature.js +202 -0
- package/dist/node/docs/index.js +2 -1
- package/dist/node/docs/integration-hub.docblock.js +2 -1
- package/dist/node/index.js +669 -177
- package/dist/node/integration-hub.feature.js +202 -0
- package/dist/node/ui/IntegrationDashboard.js +646 -172
- package/dist/node/ui/IntegrationDashboard.visualizations.js +250 -0
- package/dist/node/ui/index.js +661 -177
- package/dist/node/ui/renderers/index.js +216 -5
- package/dist/node/ui/renderers/integration.markdown.js +216 -5
- package/dist/node/ui/tables/ConnectionsTable.js +211 -0
- package/dist/node/ui/tables/IntegrationTables.js +361 -0
- package/dist/node/ui/tables/SyncConfigsTable.js +230 -0
- package/dist/node/ui/tables/integration-table.shared.js +84 -0
- package/dist/node/visualizations/catalog.js +137 -0
- package/dist/node/visualizations/index.js +211 -0
- package/dist/node/visualizations/selectors.js +204 -0
- package/dist/ui/IntegrationDashboard.js +646 -172
- package/dist/ui/IntegrationDashboard.visualizations.d.ts +6 -0
- package/dist/ui/IntegrationDashboard.visualizations.js +251 -0
- package/dist/ui/index.js +661 -177
- package/dist/ui/renderers/index.js +216 -5
- package/dist/ui/renderers/integration.markdown.js +216 -5
- package/dist/ui/tables/ConnectionsTable.d.ts +4 -0
- package/dist/ui/tables/ConnectionsTable.js +212 -0
- package/dist/ui/tables/IntegrationTables.d.ts +2 -0
- package/dist/ui/tables/IntegrationTables.js +362 -0
- package/dist/ui/tables/IntegrationTables.smoke.test.d.ts +1 -0
- package/dist/ui/tables/SyncConfigsTable.d.ts +4 -0
- package/dist/ui/tables/SyncConfigsTable.js +231 -0
- package/dist/ui/tables/integration-table.shared.d.ts +18 -0
- package/dist/ui/tables/integration-table.shared.js +85 -0
- package/dist/visualizations/catalog.d.ts +11 -0
- package/dist/visualizations/catalog.js +138 -0
- package/dist/visualizations/index.d.ts +2 -0
- package/dist/visualizations/index.js +212 -0
- package/dist/visualizations/selectors.d.ts +10 -0
- package/dist/visualizations/selectors.js +205 -0
- package/dist/visualizations/selectors.test.d.ts +1 -0
- package/package.json +108 -10
|
@@ -51,9 +51,257 @@ function useIntegrationData(projectId = "local-project") {
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
// src/visualizations/catalog.ts
|
|
55
|
+
import {
|
|
56
|
+
defineVisualization,
|
|
57
|
+
VisualizationRegistry
|
|
58
|
+
} from "@contractspec/lib.contracts-spec/visualizations";
|
|
59
|
+
var INTEGRATION_LIST_REF = {
|
|
60
|
+
key: "integration.list",
|
|
61
|
+
version: "1.0.0"
|
|
62
|
+
};
|
|
63
|
+
var CONNECTION_LIST_REF = {
|
|
64
|
+
key: "integration.connection.list",
|
|
65
|
+
version: "1.0.0"
|
|
66
|
+
};
|
|
67
|
+
var SYNC_CONFIG_REF = {
|
|
68
|
+
key: "integration.syncConfig.list",
|
|
69
|
+
version: "1.0.0"
|
|
70
|
+
};
|
|
71
|
+
var META = {
|
|
72
|
+
version: "1.0.0",
|
|
73
|
+
domain: "integration",
|
|
74
|
+
stability: "experimental",
|
|
75
|
+
owners: ["@example.integration-hub"],
|
|
76
|
+
tags: ["integration", "visualization", "sync"]
|
|
77
|
+
};
|
|
78
|
+
var IntegrationTypeVisualization = defineVisualization({
|
|
79
|
+
meta: {
|
|
80
|
+
...META,
|
|
81
|
+
key: "integration-hub.visualization.integration-types",
|
|
82
|
+
title: "Integration Types",
|
|
83
|
+
description: "Distribution of configured integration categories.",
|
|
84
|
+
goal: "Show where integration coverage is concentrated.",
|
|
85
|
+
context: "Integration overview."
|
|
86
|
+
},
|
|
87
|
+
source: { primary: INTEGRATION_LIST_REF, resultPath: "data" },
|
|
88
|
+
visualization: {
|
|
89
|
+
kind: "pie",
|
|
90
|
+
nameDimension: "type",
|
|
91
|
+
valueMeasure: "count",
|
|
92
|
+
dimensions: [
|
|
93
|
+
{ key: "type", label: "Type", dataPath: "type", type: "category" }
|
|
94
|
+
],
|
|
95
|
+
measures: [
|
|
96
|
+
{ key: "count", label: "Count", dataPath: "count", format: "number" }
|
|
97
|
+
],
|
|
98
|
+
table: { caption: "Integration counts by type." }
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
var ConnectionStatusVisualization = defineVisualization({
|
|
102
|
+
meta: {
|
|
103
|
+
...META,
|
|
104
|
+
key: "integration-hub.visualization.connection-status",
|
|
105
|
+
title: "Connection Status",
|
|
106
|
+
description: "Status distribution across configured connections.",
|
|
107
|
+
goal: "Highlight connection health and instability.",
|
|
108
|
+
context: "Connection monitoring."
|
|
109
|
+
},
|
|
110
|
+
source: { primary: CONNECTION_LIST_REF, resultPath: "data" },
|
|
111
|
+
visualization: {
|
|
112
|
+
kind: "cartesian",
|
|
113
|
+
variant: "bar",
|
|
114
|
+
xDimension: "status",
|
|
115
|
+
yMeasures: ["count"],
|
|
116
|
+
dimensions: [
|
|
117
|
+
{ key: "status", label: "Status", dataPath: "status", type: "category" }
|
|
118
|
+
],
|
|
119
|
+
measures: [
|
|
120
|
+
{
|
|
121
|
+
key: "count",
|
|
122
|
+
label: "Connections",
|
|
123
|
+
dataPath: "count",
|
|
124
|
+
format: "number",
|
|
125
|
+
color: "#1d4ed8"
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
table: { caption: "Connection counts by status." }
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
var HealthySyncMetricVisualization = defineVisualization({
|
|
132
|
+
meta: {
|
|
133
|
+
...META,
|
|
134
|
+
key: "integration-hub.visualization.sync-healthy",
|
|
135
|
+
title: "Healthy Syncs",
|
|
136
|
+
description: "Sync configurations currently healthy or recently successful.",
|
|
137
|
+
goal: "Summarize healthy synchronization capacity.",
|
|
138
|
+
context: "Sync-state comparison."
|
|
139
|
+
},
|
|
140
|
+
source: { primary: SYNC_CONFIG_REF, resultPath: "data" },
|
|
141
|
+
visualization: {
|
|
142
|
+
kind: "metric",
|
|
143
|
+
measure: "value",
|
|
144
|
+
measures: [
|
|
145
|
+
{ key: "value", label: "Syncs", dataPath: "value", format: "number" }
|
|
146
|
+
],
|
|
147
|
+
table: { caption: "Healthy sync count." }
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
var AttentionSyncMetricVisualization = defineVisualization({
|
|
151
|
+
meta: {
|
|
152
|
+
...META,
|
|
153
|
+
key: "integration-hub.visualization.sync-attention",
|
|
154
|
+
title: "Attention Needed",
|
|
155
|
+
description: "Sync configurations paused, failing, or otherwise needing review.",
|
|
156
|
+
goal: "Summarize syncs needing action.",
|
|
157
|
+
context: "Sync-state comparison."
|
|
158
|
+
},
|
|
159
|
+
source: { primary: SYNC_CONFIG_REF, resultPath: "data" },
|
|
160
|
+
visualization: {
|
|
161
|
+
kind: "metric",
|
|
162
|
+
measure: "value",
|
|
163
|
+
measures: [
|
|
164
|
+
{ key: "value", label: "Syncs", dataPath: "value", format: "number" }
|
|
165
|
+
],
|
|
166
|
+
table: { caption: "Syncs requiring attention." }
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
var IntegrationVisualizationSpecs = [
|
|
170
|
+
IntegrationTypeVisualization,
|
|
171
|
+
ConnectionStatusVisualization,
|
|
172
|
+
HealthySyncMetricVisualization,
|
|
173
|
+
AttentionSyncMetricVisualization
|
|
174
|
+
];
|
|
175
|
+
var IntegrationVisualizationRegistry = new VisualizationRegistry([
|
|
176
|
+
...IntegrationVisualizationSpecs
|
|
177
|
+
]);
|
|
178
|
+
var IntegrationVisualizationRefs = IntegrationVisualizationSpecs.map((spec) => ({
|
|
179
|
+
key: spec.meta.key,
|
|
180
|
+
version: spec.meta.version
|
|
181
|
+
}));
|
|
182
|
+
|
|
183
|
+
// src/visualizations/selectors.ts
|
|
184
|
+
function isHealthySync(status) {
|
|
185
|
+
return status === "ACTIVE" || status === "SUCCESS";
|
|
186
|
+
}
|
|
187
|
+
function createIntegrationVisualizationSections(integrations, connections, syncConfigs) {
|
|
188
|
+
const integrationTypes = new Map;
|
|
189
|
+
const connectionStatuses = new Map;
|
|
190
|
+
let healthySyncs = 0;
|
|
191
|
+
let attentionSyncs = 0;
|
|
192
|
+
for (const integration of integrations) {
|
|
193
|
+
integrationTypes.set(integration.type, (integrationTypes.get(integration.type) ?? 0) + 1);
|
|
194
|
+
}
|
|
195
|
+
for (const connection of connections) {
|
|
196
|
+
connectionStatuses.set(connection.status, (connectionStatuses.get(connection.status) ?? 0) + 1);
|
|
197
|
+
}
|
|
198
|
+
for (const syncConfig of syncConfigs) {
|
|
199
|
+
if (isHealthySync(syncConfig.status)) {
|
|
200
|
+
healthySyncs += 1;
|
|
201
|
+
} else {
|
|
202
|
+
attentionSyncs += 1;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const primaryItems = [
|
|
206
|
+
{
|
|
207
|
+
key: "integration-types",
|
|
208
|
+
spec: IntegrationTypeVisualization,
|
|
209
|
+
data: {
|
|
210
|
+
data: Array.from(integrationTypes.entries()).map(([type, count]) => ({
|
|
211
|
+
type,
|
|
212
|
+
count
|
|
213
|
+
}))
|
|
214
|
+
},
|
|
215
|
+
title: "Integration Types",
|
|
216
|
+
description: "Configured integrations grouped by category.",
|
|
217
|
+
height: 260
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
key: "connection-status",
|
|
221
|
+
spec: ConnectionStatusVisualization,
|
|
222
|
+
data: {
|
|
223
|
+
data: Array.from(connectionStatuses.entries()).map(([status, count]) => ({
|
|
224
|
+
status,
|
|
225
|
+
count
|
|
226
|
+
}))
|
|
227
|
+
},
|
|
228
|
+
title: "Connection Status",
|
|
229
|
+
description: "Operational health across current connections."
|
|
230
|
+
}
|
|
231
|
+
];
|
|
232
|
+
const comparisonItems = [
|
|
233
|
+
{
|
|
234
|
+
key: "healthy-syncs",
|
|
235
|
+
spec: HealthySyncMetricVisualization,
|
|
236
|
+
data: { data: [{ value: healthySyncs }] },
|
|
237
|
+
title: "Healthy Syncs",
|
|
238
|
+
description: "Active or recently successful sync configurations.",
|
|
239
|
+
height: 200
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
key: "attention-syncs",
|
|
243
|
+
spec: AttentionSyncMetricVisualization,
|
|
244
|
+
data: { data: [{ value: attentionSyncs }] },
|
|
245
|
+
title: "Attention Needed",
|
|
246
|
+
description: "Paused, failed, or degraded sync configurations.",
|
|
247
|
+
height: 200
|
|
248
|
+
}
|
|
249
|
+
];
|
|
250
|
+
return {
|
|
251
|
+
primaryItems,
|
|
252
|
+
comparisonItems
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
// src/ui/IntegrationDashboard.visualizations.tsx
|
|
256
|
+
import {
|
|
257
|
+
ComparisonView,
|
|
258
|
+
VisualizationCard,
|
|
259
|
+
VisualizationGrid
|
|
260
|
+
} from "@contractspec/lib.design-system";
|
|
261
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
262
|
+
"use client";
|
|
263
|
+
function IntegrationVisualizationOverview({
|
|
264
|
+
integrations,
|
|
265
|
+
connections,
|
|
266
|
+
syncConfigs
|
|
267
|
+
}) {
|
|
268
|
+
const { primaryItems, comparisonItems } = createIntegrationVisualizationSections(integrations, connections, syncConfigs);
|
|
269
|
+
return /* @__PURE__ */ jsxDEV("section", {
|
|
270
|
+
className: "space-y-4",
|
|
271
|
+
children: [
|
|
272
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
273
|
+
children: [
|
|
274
|
+
/* @__PURE__ */ jsxDEV("h3", {
|
|
275
|
+
className: "font-semibold text-lg",
|
|
276
|
+
children: "Integration Visualizations"
|
|
277
|
+
}, undefined, false, undefined, this),
|
|
278
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
279
|
+
className: "text-muted-foreground text-sm",
|
|
280
|
+
children: "Contract-backed charts for integration coverage and sync health."
|
|
281
|
+
}, undefined, false, undefined, this)
|
|
282
|
+
]
|
|
283
|
+
}, undefined, true, undefined, this),
|
|
284
|
+
/* @__PURE__ */ jsxDEV(VisualizationGrid, {
|
|
285
|
+
children: primaryItems.map((item) => /* @__PURE__ */ jsxDEV(VisualizationCard, {
|
|
286
|
+
data: item.data,
|
|
287
|
+
description: item.description,
|
|
288
|
+
height: item.height,
|
|
289
|
+
spec: item.spec,
|
|
290
|
+
title: item.title
|
|
291
|
+
}, item.key, false, undefined, this))
|
|
292
|
+
}, undefined, false, undefined, this),
|
|
293
|
+
/* @__PURE__ */ jsxDEV(ComparisonView, {
|
|
294
|
+
description: "Comparison surface for healthy versus attention-needed syncs.",
|
|
295
|
+
items: comparisonItems,
|
|
296
|
+
title: "Sync-State Comparison"
|
|
297
|
+
}, undefined, false, undefined, this)
|
|
298
|
+
]
|
|
299
|
+
}, undefined, true, undefined, this);
|
|
300
|
+
}
|
|
301
|
+
|
|
54
302
|
// src/ui/IntegrationHubChat.tsx
|
|
55
303
|
import { ChatWithSidebar } from "@contractspec/module.ai-chat";
|
|
56
|
-
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
304
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
57
305
|
"use client";
|
|
58
306
|
var DEFAULT_SUGGESTIONS = [
|
|
59
307
|
"List my integrations",
|
|
@@ -69,9 +317,9 @@ function IntegrationHubChat({
|
|
|
69
317
|
systemPrompt = DEFAULT_SYSTEM_PROMPT,
|
|
70
318
|
className
|
|
71
319
|
}) {
|
|
72
|
-
return /* @__PURE__ */
|
|
320
|
+
return /* @__PURE__ */ jsxDEV2("div", {
|
|
73
321
|
className: className ?? "flex h-[500px] flex-col",
|
|
74
|
-
children: /* @__PURE__ */
|
|
322
|
+
children: /* @__PURE__ */ jsxDEV2(ChatWithSidebar, {
|
|
75
323
|
className: "flex-1",
|
|
76
324
|
systemPrompt,
|
|
77
325
|
proxyUrl,
|
|
@@ -83,16 +331,373 @@ function IntegrationHubChat({
|
|
|
83
331
|
}, undefined, false, undefined, this);
|
|
84
332
|
}
|
|
85
333
|
|
|
334
|
+
// src/ui/tables/integration-table.shared.tsx
|
|
335
|
+
import { Button } from "@contractspec/lib.design-system";
|
|
336
|
+
import { Badge } from "@contractspec/lib.ui-kit-web/ui/badge";
|
|
337
|
+
import { HStack } from "@contractspec/lib.ui-kit-web/ui/stack";
|
|
338
|
+
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
339
|
+
"use client";
|
|
340
|
+
var STATUS_VARIANTS = {
|
|
341
|
+
ACTIVE: "default",
|
|
342
|
+
CONNECTED: "default",
|
|
343
|
+
SUCCESS: "default",
|
|
344
|
+
PENDING: "secondary",
|
|
345
|
+
PAUSED: "secondary",
|
|
346
|
+
ERROR: "destructive",
|
|
347
|
+
DISCONNECTED: "outline"
|
|
348
|
+
};
|
|
349
|
+
function formatDateTime(value) {
|
|
350
|
+
return value ? value.toLocaleString() : "Never";
|
|
351
|
+
}
|
|
352
|
+
function formatJson(value) {
|
|
353
|
+
return value ? JSON.stringify(value, null, 2) : "No configuration";
|
|
354
|
+
}
|
|
355
|
+
function StatusBadge({ status }) {
|
|
356
|
+
return /* @__PURE__ */ jsxDEV3(Badge, {
|
|
357
|
+
variant: STATUS_VARIANTS[status] ?? "outline",
|
|
358
|
+
children: status
|
|
359
|
+
}, undefined, false, undefined, this);
|
|
360
|
+
}
|
|
361
|
+
function IntegrationTableToolbar({
|
|
362
|
+
controller,
|
|
363
|
+
label,
|
|
364
|
+
toggleColumnId,
|
|
365
|
+
toggleVisibleLabel,
|
|
366
|
+
toggleHiddenLabel,
|
|
367
|
+
pinColumnId,
|
|
368
|
+
pinLabel,
|
|
369
|
+
resizeColumnId,
|
|
370
|
+
resizeLabel
|
|
371
|
+
}) {
|
|
372
|
+
const firstRow = controller.rows[0];
|
|
373
|
+
const toggleColumn = controller.columns.find((column) => column.id === toggleColumnId);
|
|
374
|
+
const pinColumn = controller.columns.find((column) => column.id === pinColumnId);
|
|
375
|
+
const resizeColumn = controller.columns.find((column) => column.id === resizeColumnId);
|
|
376
|
+
const pinTarget = pinColumn?.pinState === "left" ? false : "left";
|
|
377
|
+
return /* @__PURE__ */ jsxDEV3(HStack, {
|
|
378
|
+
gap: "sm",
|
|
379
|
+
className: "flex-wrap",
|
|
380
|
+
children: [
|
|
381
|
+
/* @__PURE__ */ jsxDEV3(Badge, {
|
|
382
|
+
variant: "outline",
|
|
383
|
+
children: label
|
|
384
|
+
}, undefined, false, undefined, this),
|
|
385
|
+
/* @__PURE__ */ jsxDEV3(Button, {
|
|
386
|
+
variant: "outline",
|
|
387
|
+
size: "sm",
|
|
388
|
+
onPress: () => firstRow?.toggleExpanded?.(!firstRow?.isExpanded),
|
|
389
|
+
children: "Expand First Row"
|
|
390
|
+
}, undefined, false, undefined, this),
|
|
391
|
+
/* @__PURE__ */ jsxDEV3(Button, {
|
|
392
|
+
variant: "outline",
|
|
393
|
+
size: "sm",
|
|
394
|
+
onPress: () => toggleColumn?.toggleVisibility?.(!toggleColumn?.visible),
|
|
395
|
+
children: toggleColumn?.visible ? toggleVisibleLabel : toggleHiddenLabel
|
|
396
|
+
}, undefined, false, undefined, this),
|
|
397
|
+
/* @__PURE__ */ jsxDEV3(Button, {
|
|
398
|
+
variant: "outline",
|
|
399
|
+
size: "sm",
|
|
400
|
+
onPress: () => pinColumn?.pin?.(pinTarget),
|
|
401
|
+
children: pinColumn?.pinState === "left" ? `Unpin ${pinLabel}` : `Pin ${pinLabel}`
|
|
402
|
+
}, undefined, false, undefined, this),
|
|
403
|
+
/* @__PURE__ */ jsxDEV3(Button, {
|
|
404
|
+
variant: "outline",
|
|
405
|
+
size: "sm",
|
|
406
|
+
onPress: () => resizeColumn?.resizeBy?.(40),
|
|
407
|
+
children: resizeLabel
|
|
408
|
+
}, undefined, false, undefined, this)
|
|
409
|
+
]
|
|
410
|
+
}, undefined, true, undefined, this);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// src/ui/tables/ConnectionsTable.tsx
|
|
414
|
+
import { DataTable } from "@contractspec/lib.design-system";
|
|
415
|
+
import { useContractTable } from "@contractspec/lib.presentation-runtime-react";
|
|
416
|
+
import { VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
|
|
417
|
+
import { Text } from "@contractspec/lib.ui-kit-web/ui/text";
|
|
418
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
419
|
+
"use client";
|
|
420
|
+
function ConnectionsTable({
|
|
421
|
+
connections
|
|
422
|
+
}) {
|
|
423
|
+
const controller = useContractTable({
|
|
424
|
+
data: connections,
|
|
425
|
+
columns: [
|
|
426
|
+
{
|
|
427
|
+
id: "connection",
|
|
428
|
+
header: "Connection",
|
|
429
|
+
label: "Connection",
|
|
430
|
+
accessor: (connection) => connection.name,
|
|
431
|
+
cell: ({ item }) => /* @__PURE__ */ jsxDEV4(VStack, {
|
|
432
|
+
gap: "xs",
|
|
433
|
+
children: [
|
|
434
|
+
/* @__PURE__ */ jsxDEV4(Text, {
|
|
435
|
+
className: "font-medium text-sm",
|
|
436
|
+
children: item.name
|
|
437
|
+
}, undefined, false, undefined, this),
|
|
438
|
+
/* @__PURE__ */ jsxDEV4(Text, {
|
|
439
|
+
className: "text-muted-foreground text-xs",
|
|
440
|
+
children: [
|
|
441
|
+
"Created ",
|
|
442
|
+
item.createdAt.toLocaleDateString()
|
|
443
|
+
]
|
|
444
|
+
}, undefined, true, undefined, this)
|
|
445
|
+
]
|
|
446
|
+
}, undefined, true, undefined, this),
|
|
447
|
+
size: 240,
|
|
448
|
+
minSize: 180,
|
|
449
|
+
canSort: true,
|
|
450
|
+
canPin: true,
|
|
451
|
+
canResize: true
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
id: "status",
|
|
455
|
+
header: "Status",
|
|
456
|
+
label: "Status",
|
|
457
|
+
accessorKey: "status",
|
|
458
|
+
cell: ({ value }) => /* @__PURE__ */ jsxDEV4(StatusBadge, {
|
|
459
|
+
status: String(value)
|
|
460
|
+
}, undefined, false, undefined, this),
|
|
461
|
+
size: 150,
|
|
462
|
+
canSort: true,
|
|
463
|
+
canPin: true,
|
|
464
|
+
canResize: true
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
id: "lastSyncAt",
|
|
468
|
+
header: "Last Sync",
|
|
469
|
+
label: "Last Sync",
|
|
470
|
+
accessor: (connection) => connection.lastSyncAt?.getTime() ?? 0,
|
|
471
|
+
cell: ({ item }) => formatDateTime(item.lastSyncAt),
|
|
472
|
+
size: 200,
|
|
473
|
+
canSort: true,
|
|
474
|
+
canHide: true,
|
|
475
|
+
canResize: true
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
id: "errorMessage",
|
|
479
|
+
header: "Errors",
|
|
480
|
+
label: "Errors",
|
|
481
|
+
accessor: (connection) => connection.errorMessage ?? "",
|
|
482
|
+
cell: ({ value }) => String(value || "No errors"),
|
|
483
|
+
size: 240,
|
|
484
|
+
canHide: true,
|
|
485
|
+
canResize: true
|
|
486
|
+
}
|
|
487
|
+
],
|
|
488
|
+
initialState: {
|
|
489
|
+
pagination: { pageIndex: 0, pageSize: 3 },
|
|
490
|
+
columnVisibility: { errorMessage: false },
|
|
491
|
+
columnPinning: { left: ["connection"], right: [] }
|
|
492
|
+
},
|
|
493
|
+
renderExpandedContent: (connection) => /* @__PURE__ */ jsxDEV4(VStack, {
|
|
494
|
+
gap: "sm",
|
|
495
|
+
className: "py-2",
|
|
496
|
+
children: [
|
|
497
|
+
/* @__PURE__ */ jsxDEV4(Text, {
|
|
498
|
+
className: "font-medium text-sm",
|
|
499
|
+
children: "Credentials"
|
|
500
|
+
}, undefined, false, undefined, this),
|
|
501
|
+
/* @__PURE__ */ jsxDEV4("pre", {
|
|
502
|
+
className: "overflow-auto rounded-md bg-muted/40 p-3 text-xs",
|
|
503
|
+
children: formatJson(connection.credentials)
|
|
504
|
+
}, undefined, false, undefined, this),
|
|
505
|
+
/* @__PURE__ */ jsxDEV4(Text, {
|
|
506
|
+
className: "font-medium text-sm",
|
|
507
|
+
children: "Config"
|
|
508
|
+
}, undefined, false, undefined, this),
|
|
509
|
+
/* @__PURE__ */ jsxDEV4("pre", {
|
|
510
|
+
className: "overflow-auto rounded-md bg-muted/40 p-3 text-xs",
|
|
511
|
+
children: formatJson(connection.config)
|
|
512
|
+
}, undefined, false, undefined, this),
|
|
513
|
+
/* @__PURE__ */ jsxDEV4(Text, {
|
|
514
|
+
className: "text-muted-foreground text-sm",
|
|
515
|
+
children: connection.errorMessage ?? "No sync errors recorded."
|
|
516
|
+
}, undefined, false, undefined, this)
|
|
517
|
+
]
|
|
518
|
+
}, undefined, true, undefined, this),
|
|
519
|
+
getCanExpand: () => true
|
|
520
|
+
});
|
|
521
|
+
return /* @__PURE__ */ jsxDEV4(DataTable, {
|
|
522
|
+
controller,
|
|
523
|
+
title: "Connections",
|
|
524
|
+
description: "Client-mode ContractSpec table with visibility, pinning, resizing, and expanded diagnostics.",
|
|
525
|
+
toolbar: /* @__PURE__ */ jsxDEV4(IntegrationTableToolbar, {
|
|
526
|
+
controller,
|
|
527
|
+
label: `${connections.length} total connections`,
|
|
528
|
+
toggleColumnId: "errorMessage",
|
|
529
|
+
toggleVisibleLabel: "Hide Error Column",
|
|
530
|
+
toggleHiddenLabel: "Show Error Column",
|
|
531
|
+
pinColumnId: "status",
|
|
532
|
+
pinLabel: "Status",
|
|
533
|
+
resizeColumnId: "connection",
|
|
534
|
+
resizeLabel: "Widen Connection"
|
|
535
|
+
}, undefined, false, undefined, this),
|
|
536
|
+
emptyState: /* @__PURE__ */ jsxDEV4("div", {
|
|
537
|
+
className: "rounded-md border border-dashed p-8 text-center text-muted-foreground text-sm",
|
|
538
|
+
children: "No connections found"
|
|
539
|
+
}, undefined, false, undefined, this)
|
|
540
|
+
}, undefined, false, undefined, this);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// src/ui/tables/SyncConfigsTable.tsx
|
|
544
|
+
import { DataTable as DataTable2 } from "@contractspec/lib.design-system";
|
|
545
|
+
import { useContractTable as useContractTable2 } from "@contractspec/lib.presentation-runtime-react";
|
|
546
|
+
import { VStack as VStack2 } from "@contractspec/lib.ui-kit-web/ui/stack";
|
|
547
|
+
import { Text as Text2 } from "@contractspec/lib.ui-kit-web/ui/text";
|
|
548
|
+
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
549
|
+
"use client";
|
|
550
|
+
function SyncConfigsTable({
|
|
551
|
+
syncConfigs
|
|
552
|
+
}) {
|
|
553
|
+
const controller = useContractTable2({
|
|
554
|
+
data: syncConfigs,
|
|
555
|
+
columns: [
|
|
556
|
+
{
|
|
557
|
+
id: "sync",
|
|
558
|
+
header: "Sync Config",
|
|
559
|
+
label: "Sync Config",
|
|
560
|
+
accessor: (sync) => sync.name,
|
|
561
|
+
cell: ({ item }) => /* @__PURE__ */ jsxDEV5(VStack2, {
|
|
562
|
+
gap: "xs",
|
|
563
|
+
children: [
|
|
564
|
+
/* @__PURE__ */ jsxDEV5(Text2, {
|
|
565
|
+
className: "font-medium text-sm",
|
|
566
|
+
children: item.name
|
|
567
|
+
}, undefined, false, undefined, this),
|
|
568
|
+
/* @__PURE__ */ jsxDEV5(Text2, {
|
|
569
|
+
className: "text-muted-foreground text-xs",
|
|
570
|
+
children: [
|
|
571
|
+
item.sourceEntity,
|
|
572
|
+
" \u2192 ",
|
|
573
|
+
item.targetEntity
|
|
574
|
+
]
|
|
575
|
+
}, undefined, true, undefined, this)
|
|
576
|
+
]
|
|
577
|
+
}, undefined, true, undefined, this),
|
|
578
|
+
size: 260,
|
|
579
|
+
minSize: 200,
|
|
580
|
+
canSort: true,
|
|
581
|
+
canPin: true,
|
|
582
|
+
canResize: true
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
id: "frequency",
|
|
586
|
+
header: "Frequency",
|
|
587
|
+
label: "Frequency",
|
|
588
|
+
accessorKey: "frequency",
|
|
589
|
+
size: 160,
|
|
590
|
+
canSort: true,
|
|
591
|
+
canHide: true,
|
|
592
|
+
canResize: true
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
id: "status",
|
|
596
|
+
header: "Status",
|
|
597
|
+
label: "Status",
|
|
598
|
+
accessorKey: "status",
|
|
599
|
+
cell: ({ value }) => /* @__PURE__ */ jsxDEV5(StatusBadge, {
|
|
600
|
+
status: String(value)
|
|
601
|
+
}, undefined, false, undefined, this),
|
|
602
|
+
size: 150,
|
|
603
|
+
canSort: true,
|
|
604
|
+
canPin: true,
|
|
605
|
+
canResize: true
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
id: "recordsSynced",
|
|
609
|
+
header: "Records",
|
|
610
|
+
label: "Records",
|
|
611
|
+
accessorKey: "recordsSynced",
|
|
612
|
+
align: "right",
|
|
613
|
+
size: 140,
|
|
614
|
+
canSort: true,
|
|
615
|
+
canResize: true
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
id: "lastRunAt",
|
|
619
|
+
header: "Last Run",
|
|
620
|
+
label: "Last Run",
|
|
621
|
+
accessor: (sync) => sync.lastRunAt?.getTime() ?? 0,
|
|
622
|
+
cell: ({ item }) => formatDateTime(item.lastRunAt),
|
|
623
|
+
size: 200,
|
|
624
|
+
canSort: true,
|
|
625
|
+
canHide: true,
|
|
626
|
+
canResize: true
|
|
627
|
+
}
|
|
628
|
+
],
|
|
629
|
+
initialState: {
|
|
630
|
+
pagination: { pageIndex: 0, pageSize: 3 },
|
|
631
|
+
columnVisibility: { lastRunAt: false },
|
|
632
|
+
columnPinning: { left: ["sync"], right: [] }
|
|
633
|
+
},
|
|
634
|
+
renderExpandedContent: (sync) => /* @__PURE__ */ jsxDEV5(VStack2, {
|
|
635
|
+
gap: "sm",
|
|
636
|
+
className: "py-2",
|
|
637
|
+
children: [
|
|
638
|
+
/* @__PURE__ */ jsxDEV5(Text2, {
|
|
639
|
+
className: "text-muted-foreground text-sm",
|
|
640
|
+
children: [
|
|
641
|
+
"Connection ",
|
|
642
|
+
sync.connectionId
|
|
643
|
+
]
|
|
644
|
+
}, undefined, true, undefined, this),
|
|
645
|
+
/* @__PURE__ */ jsxDEV5(Text2, {
|
|
646
|
+
className: "text-muted-foreground text-sm",
|
|
647
|
+
children: [
|
|
648
|
+
"Last run: ",
|
|
649
|
+
formatDateTime(sync.lastRunAt)
|
|
650
|
+
]
|
|
651
|
+
}, undefined, true, undefined, this),
|
|
652
|
+
/* @__PURE__ */ jsxDEV5(Text2, {
|
|
653
|
+
className: "text-muted-foreground text-sm",
|
|
654
|
+
children: [
|
|
655
|
+
"Last status: ",
|
|
656
|
+
sync.lastRunStatus ?? "No runs recorded"
|
|
657
|
+
]
|
|
658
|
+
}, undefined, true, undefined, this),
|
|
659
|
+
/* @__PURE__ */ jsxDEV5(Text2, {
|
|
660
|
+
className: "text-muted-foreground text-sm",
|
|
661
|
+
children: [
|
|
662
|
+
"Updated ",
|
|
663
|
+
sync.updatedAt.toLocaleString()
|
|
664
|
+
]
|
|
665
|
+
}, undefined, true, undefined, this)
|
|
666
|
+
]
|
|
667
|
+
}, undefined, true, undefined, this),
|
|
668
|
+
getCanExpand: () => true
|
|
669
|
+
});
|
|
670
|
+
return /* @__PURE__ */ jsxDEV5(DataTable2, {
|
|
671
|
+
controller,
|
|
672
|
+
title: "Sync Configs",
|
|
673
|
+
description: "Shared table primitives applied to sync monitoring without changing the surrounding dashboard layout.",
|
|
674
|
+
toolbar: /* @__PURE__ */ jsxDEV5(IntegrationTableToolbar, {
|
|
675
|
+
controller,
|
|
676
|
+
label: `${syncConfigs.length} syncs`,
|
|
677
|
+
toggleColumnId: "lastRunAt",
|
|
678
|
+
toggleVisibleLabel: "Hide Last Run",
|
|
679
|
+
toggleHiddenLabel: "Show Last Run",
|
|
680
|
+
pinColumnId: "status",
|
|
681
|
+
pinLabel: "Status",
|
|
682
|
+
resizeColumnId: "sync",
|
|
683
|
+
resizeLabel: "Widen Sync"
|
|
684
|
+
}, undefined, false, undefined, this),
|
|
685
|
+
emptyState: /* @__PURE__ */ jsxDEV5("div", {
|
|
686
|
+
className: "rounded-md border border-dashed p-8 text-center text-muted-foreground text-sm",
|
|
687
|
+
children: "No sync configurations found"
|
|
688
|
+
}, undefined, false, undefined, this)
|
|
689
|
+
}, undefined, false, undefined, this);
|
|
690
|
+
}
|
|
86
691
|
// src/ui/IntegrationDashboard.tsx
|
|
87
692
|
import {
|
|
88
|
-
Button,
|
|
693
|
+
Button as Button2,
|
|
89
694
|
ErrorState,
|
|
90
695
|
LoaderBlock,
|
|
91
696
|
StatCard,
|
|
92
697
|
StatCardGroup
|
|
93
698
|
} from "@contractspec/lib.design-system";
|
|
94
699
|
import { useState as useState2 } from "react";
|
|
95
|
-
import { jsxDEV as
|
|
700
|
+
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
96
701
|
"use client";
|
|
97
702
|
var STATUS_COLORS = {
|
|
98
703
|
ACTIVE: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
|
|
@@ -129,32 +734,32 @@ function IntegrationDashboard() {
|
|
|
129
734
|
{ id: "chat", label: "Chat", icon: "\uD83D\uDCAC" }
|
|
130
735
|
];
|
|
131
736
|
if (loading) {
|
|
132
|
-
return /* @__PURE__ */
|
|
737
|
+
return /* @__PURE__ */ jsxDEV6(LoaderBlock, {
|
|
133
738
|
label: "Loading Integrations..."
|
|
134
739
|
}, undefined, false, undefined, this);
|
|
135
740
|
}
|
|
136
741
|
if (error) {
|
|
137
|
-
return /* @__PURE__ */
|
|
742
|
+
return /* @__PURE__ */ jsxDEV6(ErrorState, {
|
|
138
743
|
title: "Failed to load Integrations",
|
|
139
744
|
description: error.message,
|
|
140
745
|
onRetry: refetch,
|
|
141
746
|
retryLabel: "Retry"
|
|
142
747
|
}, undefined, false, undefined, this);
|
|
143
748
|
}
|
|
144
|
-
return /* @__PURE__ */
|
|
749
|
+
return /* @__PURE__ */ jsxDEV6("div", {
|
|
145
750
|
className: "space-y-6",
|
|
146
751
|
children: [
|
|
147
|
-
/* @__PURE__ */
|
|
752
|
+
/* @__PURE__ */ jsxDEV6("div", {
|
|
148
753
|
className: "flex items-center justify-between",
|
|
149
754
|
children: [
|
|
150
|
-
/* @__PURE__ */
|
|
755
|
+
/* @__PURE__ */ jsxDEV6("h2", {
|
|
151
756
|
className: "font-bold text-2xl",
|
|
152
757
|
children: "Integration Hub"
|
|
153
758
|
}, undefined, false, undefined, this),
|
|
154
|
-
/* @__PURE__ */
|
|
759
|
+
/* @__PURE__ */ jsxDEV6(Button2, {
|
|
155
760
|
onClick: () => alert("Add integration modal"),
|
|
156
761
|
children: [
|
|
157
|
-
/* @__PURE__ */
|
|
762
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
158
763
|
className: "mr-2",
|
|
159
764
|
children: "+"
|
|
160
765
|
}, undefined, false, undefined, this),
|
|
@@ -163,66 +768,71 @@ function IntegrationDashboard() {
|
|
|
163
768
|
}, undefined, true, undefined, this)
|
|
164
769
|
]
|
|
165
770
|
}, undefined, true, undefined, this),
|
|
166
|
-
/* @__PURE__ */
|
|
771
|
+
/* @__PURE__ */ jsxDEV6(StatCardGroup, {
|
|
167
772
|
children: [
|
|
168
|
-
/* @__PURE__ */
|
|
773
|
+
/* @__PURE__ */ jsxDEV6(StatCard, {
|
|
169
774
|
label: "Integrations",
|
|
170
775
|
value: stats.totalIntegrations,
|
|
171
776
|
hint: `${stats.activeIntegrations} active`
|
|
172
777
|
}, undefined, false, undefined, this),
|
|
173
|
-
/* @__PURE__ */
|
|
778
|
+
/* @__PURE__ */ jsxDEV6(StatCard, {
|
|
174
779
|
label: "Connections",
|
|
175
780
|
value: stats.totalConnections,
|
|
176
781
|
hint: `${stats.connectedCount} connected`
|
|
177
782
|
}, undefined, false, undefined, this),
|
|
178
|
-
/* @__PURE__ */
|
|
783
|
+
/* @__PURE__ */ jsxDEV6(StatCard, {
|
|
179
784
|
label: "Syncs",
|
|
180
785
|
value: stats.totalSyncs,
|
|
181
786
|
hint: `${stats.activeSyncs} active`
|
|
182
787
|
}, undefined, false, undefined, this)
|
|
183
788
|
]
|
|
184
789
|
}, undefined, true, undefined, this),
|
|
185
|
-
/* @__PURE__ */
|
|
790
|
+
/* @__PURE__ */ jsxDEV6(IntegrationVisualizationOverview, {
|
|
791
|
+
connections,
|
|
792
|
+
integrations,
|
|
793
|
+
syncConfigs
|
|
794
|
+
}, undefined, false, undefined, this),
|
|
795
|
+
/* @__PURE__ */ jsxDEV6("nav", {
|
|
186
796
|
className: "flex gap-1 rounded-lg bg-muted p-1",
|
|
187
797
|
role: "tablist",
|
|
188
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
798
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxDEV6(Button2, {
|
|
189
799
|
type: "button",
|
|
190
800
|
role: "tab",
|
|
191
801
|
"aria-selected": activeTab === tab.id,
|
|
192
802
|
onClick: () => setActiveTab(tab.id),
|
|
193
803
|
className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 font-medium text-sm transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
|
|
194
804
|
children: [
|
|
195
|
-
/* @__PURE__ */
|
|
805
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
196
806
|
children: tab.icon
|
|
197
807
|
}, undefined, false, undefined, this),
|
|
198
808
|
tab.label
|
|
199
809
|
]
|
|
200
810
|
}, tab.id, true, undefined, this))
|
|
201
811
|
}, undefined, false, undefined, this),
|
|
202
|
-
/* @__PURE__ */
|
|
812
|
+
/* @__PURE__ */ jsxDEV6("div", {
|
|
203
813
|
className: "min-h-[400px]",
|
|
204
814
|
role: "tabpanel",
|
|
205
815
|
children: [
|
|
206
|
-
activeTab === "integrations" && /* @__PURE__ */
|
|
816
|
+
activeTab === "integrations" && /* @__PURE__ */ jsxDEV6("div", {
|
|
207
817
|
className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
208
818
|
children: [
|
|
209
|
-
integrations.map((integration) => /* @__PURE__ */
|
|
819
|
+
integrations.map((integration) => /* @__PURE__ */ jsxDEV6("div", {
|
|
210
820
|
className: "cursor-pointer rounded-lg border border-border bg-card p-4 transition-colors hover:bg-muted/50",
|
|
211
821
|
children: [
|
|
212
|
-
/* @__PURE__ */
|
|
822
|
+
/* @__PURE__ */ jsxDEV6("div", {
|
|
213
823
|
className: "mb-3 flex items-center gap-3",
|
|
214
824
|
children: [
|
|
215
|
-
/* @__PURE__ */
|
|
825
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
216
826
|
className: "text-2xl",
|
|
217
827
|
children: TYPE_ICONS[integration.type] ?? "\u2699\uFE0F"
|
|
218
828
|
}, undefined, false, undefined, this),
|
|
219
|
-
/* @__PURE__ */
|
|
829
|
+
/* @__PURE__ */ jsxDEV6("div", {
|
|
220
830
|
children: [
|
|
221
|
-
/* @__PURE__ */
|
|
831
|
+
/* @__PURE__ */ jsxDEV6("h3", {
|
|
222
832
|
className: "font-medium",
|
|
223
833
|
children: integration.name
|
|
224
834
|
}, undefined, false, undefined, this),
|
|
225
|
-
/* @__PURE__ */
|
|
835
|
+
/* @__PURE__ */ jsxDEV6("p", {
|
|
226
836
|
className: "text-muted-foreground text-sm",
|
|
227
837
|
children: integration.type
|
|
228
838
|
}, undefined, false, undefined, this)
|
|
@@ -230,14 +840,14 @@ function IntegrationDashboard() {
|
|
|
230
840
|
}, undefined, true, undefined, this)
|
|
231
841
|
]
|
|
232
842
|
}, undefined, true, undefined, this),
|
|
233
|
-
/* @__PURE__ */
|
|
843
|
+
/* @__PURE__ */ jsxDEV6("div", {
|
|
234
844
|
className: "flex items-center justify-between",
|
|
235
845
|
children: [
|
|
236
|
-
/* @__PURE__ */
|
|
846
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
237
847
|
className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[integration.status] ?? ""}`,
|
|
238
848
|
children: integration.status
|
|
239
849
|
}, undefined, false, undefined, this),
|
|
240
|
-
/* @__PURE__ */
|
|
850
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
241
851
|
className: "text-muted-foreground text-xs",
|
|
242
852
|
children: integration.createdAt.toLocaleDateString()
|
|
243
853
|
}, undefined, false, undefined, this)
|
|
@@ -245,75 +855,16 @@ function IntegrationDashboard() {
|
|
|
245
855
|
}, undefined, true, undefined, this)
|
|
246
856
|
]
|
|
247
857
|
}, integration.id, true, undefined, this)),
|
|
248
|
-
integrations.length === 0 && /* @__PURE__ */
|
|
858
|
+
integrations.length === 0 && /* @__PURE__ */ jsxDEV6("div", {
|
|
249
859
|
className: "col-span-full flex h-64 items-center justify-center text-muted-foreground",
|
|
250
860
|
children: "No integrations configured"
|
|
251
861
|
}, undefined, false, undefined, this)
|
|
252
862
|
]
|
|
253
863
|
}, undefined, true, undefined, this),
|
|
254
|
-
activeTab === "connections" && /* @__PURE__ */
|
|
255
|
-
|
|
256
|
-
children: /* @__PURE__ */ jsxDEV2("table", {
|
|
257
|
-
className: "w-full",
|
|
258
|
-
children: [
|
|
259
|
-
/* @__PURE__ */ jsxDEV2("thead", {
|
|
260
|
-
className: "border-border border-b bg-muted/30",
|
|
261
|
-
children: /* @__PURE__ */ jsxDEV2("tr", {
|
|
262
|
-
children: [
|
|
263
|
-
/* @__PURE__ */ jsxDEV2("th", {
|
|
264
|
-
className: "px-4 py-3 text-left font-medium text-sm",
|
|
265
|
-
children: "Connection"
|
|
266
|
-
}, undefined, false, undefined, this),
|
|
267
|
-
/* @__PURE__ */ jsxDEV2("th", {
|
|
268
|
-
className: "px-4 py-3 text-left font-medium text-sm",
|
|
269
|
-
children: "Status"
|
|
270
|
-
}, undefined, false, undefined, this),
|
|
271
|
-
/* @__PURE__ */ jsxDEV2("th", {
|
|
272
|
-
className: "px-4 py-3 text-left font-medium text-sm",
|
|
273
|
-
children: "Last Sync"
|
|
274
|
-
}, undefined, false, undefined, this)
|
|
275
|
-
]
|
|
276
|
-
}, undefined, true, undefined, this)
|
|
277
|
-
}, undefined, false, undefined, this),
|
|
278
|
-
/* @__PURE__ */ jsxDEV2("tbody", {
|
|
279
|
-
className: "divide-y divide-border",
|
|
280
|
-
children: [
|
|
281
|
-
connections.map((conn) => /* @__PURE__ */ jsxDEV2("tr", {
|
|
282
|
-
className: "hover:bg-muted/50",
|
|
283
|
-
children: [
|
|
284
|
-
/* @__PURE__ */ jsxDEV2("td", {
|
|
285
|
-
className: "px-4 py-3",
|
|
286
|
-
children: /* @__PURE__ */ jsxDEV2("div", {
|
|
287
|
-
className: "font-medium",
|
|
288
|
-
children: conn.name
|
|
289
|
-
}, undefined, false, undefined, this)
|
|
290
|
-
}, undefined, false, undefined, this),
|
|
291
|
-
/* @__PURE__ */ jsxDEV2("td", {
|
|
292
|
-
className: "px-4 py-3",
|
|
293
|
-
children: /* @__PURE__ */ jsxDEV2("span", {
|
|
294
|
-
className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[conn.status] ?? ""}`,
|
|
295
|
-
children: conn.status
|
|
296
|
-
}, undefined, false, undefined, this)
|
|
297
|
-
}, undefined, false, undefined, this),
|
|
298
|
-
/* @__PURE__ */ jsxDEV2("td", {
|
|
299
|
-
className: "px-4 py-3 text-muted-foreground text-sm",
|
|
300
|
-
children: conn.lastSyncAt?.toLocaleString() ?? "Never"
|
|
301
|
-
}, undefined, false, undefined, this)
|
|
302
|
-
]
|
|
303
|
-
}, conn.id, true, undefined, this)),
|
|
304
|
-
connections.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
|
|
305
|
-
children: /* @__PURE__ */ jsxDEV2("td", {
|
|
306
|
-
colSpan: 3,
|
|
307
|
-
className: "px-4 py-8 text-center text-muted-foreground",
|
|
308
|
-
children: "No connections found"
|
|
309
|
-
}, undefined, false, undefined, this)
|
|
310
|
-
}, undefined, false, undefined, this)
|
|
311
|
-
]
|
|
312
|
-
}, undefined, true, undefined, this)
|
|
313
|
-
]
|
|
314
|
-
}, undefined, true, undefined, this)
|
|
864
|
+
activeTab === "connections" && /* @__PURE__ */ jsxDEV6(ConnectionsTable, {
|
|
865
|
+
connections
|
|
315
866
|
}, undefined, false, undefined, this),
|
|
316
|
-
activeTab === "chat" && /* @__PURE__ */
|
|
867
|
+
activeTab === "chat" && /* @__PURE__ */ jsxDEV6(IntegrationHubChat, {
|
|
317
868
|
proxyUrl: "/api/chat",
|
|
318
869
|
thinkingLevel: "thinking",
|
|
319
870
|
suggestions: [
|
|
@@ -323,85 +874,8 @@ function IntegrationDashboard() {
|
|
|
323
874
|
],
|
|
324
875
|
className: "min-h-[400px]"
|
|
325
876
|
}, undefined, false, undefined, this),
|
|
326
|
-
activeTab === "syncs" && /* @__PURE__ */
|
|
327
|
-
|
|
328
|
-
children: /* @__PURE__ */ jsxDEV2("table", {
|
|
329
|
-
className: "w-full",
|
|
330
|
-
children: [
|
|
331
|
-
/* @__PURE__ */ jsxDEV2("thead", {
|
|
332
|
-
className: "border-border border-b bg-muted/30",
|
|
333
|
-
children: /* @__PURE__ */ jsxDEV2("tr", {
|
|
334
|
-
children: [
|
|
335
|
-
/* @__PURE__ */ jsxDEV2("th", {
|
|
336
|
-
className: "px-4 py-3 text-left font-medium text-sm",
|
|
337
|
-
children: "Sync Config"
|
|
338
|
-
}, undefined, false, undefined, this),
|
|
339
|
-
/* @__PURE__ */ jsxDEV2("th", {
|
|
340
|
-
className: "px-4 py-3 text-left font-medium text-sm",
|
|
341
|
-
children: "Frequency"
|
|
342
|
-
}, undefined, false, undefined, this),
|
|
343
|
-
/* @__PURE__ */ jsxDEV2("th", {
|
|
344
|
-
className: "px-4 py-3 text-left font-medium text-sm",
|
|
345
|
-
children: "Status"
|
|
346
|
-
}, undefined, false, undefined, this),
|
|
347
|
-
/* @__PURE__ */ jsxDEV2("th", {
|
|
348
|
-
className: "px-4 py-3 text-left font-medium text-sm",
|
|
349
|
-
children: "Records"
|
|
350
|
-
}, undefined, false, undefined, this)
|
|
351
|
-
]
|
|
352
|
-
}, undefined, true, undefined, this)
|
|
353
|
-
}, undefined, false, undefined, this),
|
|
354
|
-
/* @__PURE__ */ jsxDEV2("tbody", {
|
|
355
|
-
className: "divide-y divide-border",
|
|
356
|
-
children: [
|
|
357
|
-
syncConfigs.map((sync) => /* @__PURE__ */ jsxDEV2("tr", {
|
|
358
|
-
className: "hover:bg-muted/50",
|
|
359
|
-
children: [
|
|
360
|
-
/* @__PURE__ */ jsxDEV2("td", {
|
|
361
|
-
className: "px-4 py-3",
|
|
362
|
-
children: [
|
|
363
|
-
/* @__PURE__ */ jsxDEV2("div", {
|
|
364
|
-
className: "font-medium",
|
|
365
|
-
children: sync.name
|
|
366
|
-
}, undefined, false, undefined, this),
|
|
367
|
-
/* @__PURE__ */ jsxDEV2("div", {
|
|
368
|
-
className: "text-muted-foreground text-sm",
|
|
369
|
-
children: [
|
|
370
|
-
sync.sourceEntity,
|
|
371
|
-
" \u2192 ",
|
|
372
|
-
sync.targetEntity
|
|
373
|
-
]
|
|
374
|
-
}, undefined, true, undefined, this)
|
|
375
|
-
]
|
|
376
|
-
}, undefined, true, undefined, this),
|
|
377
|
-
/* @__PURE__ */ jsxDEV2("td", {
|
|
378
|
-
className: "px-4 py-3 text-sm",
|
|
379
|
-
children: sync.frequency
|
|
380
|
-
}, undefined, false, undefined, this),
|
|
381
|
-
/* @__PURE__ */ jsxDEV2("td", {
|
|
382
|
-
className: "px-4 py-3",
|
|
383
|
-
children: /* @__PURE__ */ jsxDEV2("span", {
|
|
384
|
-
className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[sync.status] ?? ""}`,
|
|
385
|
-
children: sync.status
|
|
386
|
-
}, undefined, false, undefined, this)
|
|
387
|
-
}, undefined, false, undefined, this),
|
|
388
|
-
/* @__PURE__ */ jsxDEV2("td", {
|
|
389
|
-
className: "px-4 py-3 text-muted-foreground text-sm",
|
|
390
|
-
children: sync.recordsSynced.toLocaleString()
|
|
391
|
-
}, undefined, false, undefined, this)
|
|
392
|
-
]
|
|
393
|
-
}, sync.id, true, undefined, this)),
|
|
394
|
-
syncConfigs.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
|
|
395
|
-
children: /* @__PURE__ */ jsxDEV2("td", {
|
|
396
|
-
colSpan: 4,
|
|
397
|
-
className: "px-4 py-8 text-center text-muted-foreground",
|
|
398
|
-
children: "No sync configurations found"
|
|
399
|
-
}, undefined, false, undefined, this)
|
|
400
|
-
}, undefined, false, undefined, this)
|
|
401
|
-
]
|
|
402
|
-
}, undefined, true, undefined, this)
|
|
403
|
-
]
|
|
404
|
-
}, undefined, true, undefined, this)
|
|
877
|
+
activeTab === "syncs" && /* @__PURE__ */ jsxDEV6(SyncConfigsTable, {
|
|
878
|
+
syncConfigs
|
|
405
879
|
}, undefined, false, undefined, this)
|
|
406
880
|
]
|
|
407
881
|
}, undefined, true, undefined, this)
|