@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.
Files changed (45) hide show
  1. package/README.md +4 -1
  2. package/dist/docs/index.js +2 -1
  3. package/dist/docs/integration-hub.docblock.js +2 -1
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +669 -177
  6. package/dist/integration-hub.feature.js +202 -0
  7. package/dist/node/docs/index.js +2 -1
  8. package/dist/node/docs/integration-hub.docblock.js +2 -1
  9. package/dist/node/index.js +669 -177
  10. package/dist/node/integration-hub.feature.js +202 -0
  11. package/dist/node/ui/IntegrationDashboard.js +646 -172
  12. package/dist/node/ui/IntegrationDashboard.visualizations.js +250 -0
  13. package/dist/node/ui/index.js +661 -177
  14. package/dist/node/ui/renderers/index.js +216 -5
  15. package/dist/node/ui/renderers/integration.markdown.js +216 -5
  16. package/dist/node/ui/tables/ConnectionsTable.js +211 -0
  17. package/dist/node/ui/tables/IntegrationTables.js +361 -0
  18. package/dist/node/ui/tables/SyncConfigsTable.js +230 -0
  19. package/dist/node/ui/tables/integration-table.shared.js +84 -0
  20. package/dist/node/visualizations/catalog.js +137 -0
  21. package/dist/node/visualizations/index.js +211 -0
  22. package/dist/node/visualizations/selectors.js +204 -0
  23. package/dist/ui/IntegrationDashboard.js +646 -172
  24. package/dist/ui/IntegrationDashboard.visualizations.d.ts +6 -0
  25. package/dist/ui/IntegrationDashboard.visualizations.js +251 -0
  26. package/dist/ui/index.js +661 -177
  27. package/dist/ui/renderers/index.js +216 -5
  28. package/dist/ui/renderers/integration.markdown.js +216 -5
  29. package/dist/ui/tables/ConnectionsTable.d.ts +4 -0
  30. package/dist/ui/tables/ConnectionsTable.js +212 -0
  31. package/dist/ui/tables/IntegrationTables.d.ts +2 -0
  32. package/dist/ui/tables/IntegrationTables.js +362 -0
  33. package/dist/ui/tables/IntegrationTables.smoke.test.d.ts +1 -0
  34. package/dist/ui/tables/SyncConfigsTable.d.ts +4 -0
  35. package/dist/ui/tables/SyncConfigsTable.js +231 -0
  36. package/dist/ui/tables/integration-table.shared.d.ts +18 -0
  37. package/dist/ui/tables/integration-table.shared.js +85 -0
  38. package/dist/visualizations/catalog.d.ts +11 -0
  39. package/dist/visualizations/catalog.js +138 -0
  40. package/dist/visualizations/index.d.ts +2 -0
  41. package/dist/visualizations/index.js +212 -0
  42. package/dist/visualizations/selectors.d.ts +10 -0
  43. package/dist/visualizations/selectors.js +205 -0
  44. package/dist/visualizations/selectors.test.d.ts +1 -0
  45. package/package.json +108 -10
package/dist/index.js CHANGED
@@ -1198,9 +1198,257 @@ function useIntegrationData(projectId = "local-project") {
1198
1198
  // src/ui/hooks/index.ts
1199
1199
  "use client";
1200
1200
 
1201
+ // src/visualizations/catalog.ts
1202
+ import {
1203
+ defineVisualization,
1204
+ VisualizationRegistry
1205
+ } from "@contractspec/lib.contracts-spec/visualizations";
1206
+ var INTEGRATION_LIST_REF = {
1207
+ key: "integration.list",
1208
+ version: "1.0.0"
1209
+ };
1210
+ var CONNECTION_LIST_REF = {
1211
+ key: "integration.connection.list",
1212
+ version: "1.0.0"
1213
+ };
1214
+ var SYNC_CONFIG_REF = {
1215
+ key: "integration.syncConfig.list",
1216
+ version: "1.0.0"
1217
+ };
1218
+ var META = {
1219
+ version: "1.0.0",
1220
+ domain: "integration",
1221
+ stability: "experimental",
1222
+ owners: ["@example.integration-hub"],
1223
+ tags: ["integration", "visualization", "sync"]
1224
+ };
1225
+ var IntegrationTypeVisualization = defineVisualization({
1226
+ meta: {
1227
+ ...META,
1228
+ key: "integration-hub.visualization.integration-types",
1229
+ title: "Integration Types",
1230
+ description: "Distribution of configured integration categories.",
1231
+ goal: "Show where integration coverage is concentrated.",
1232
+ context: "Integration overview."
1233
+ },
1234
+ source: { primary: INTEGRATION_LIST_REF, resultPath: "data" },
1235
+ visualization: {
1236
+ kind: "pie",
1237
+ nameDimension: "type",
1238
+ valueMeasure: "count",
1239
+ dimensions: [
1240
+ { key: "type", label: "Type", dataPath: "type", type: "category" }
1241
+ ],
1242
+ measures: [
1243
+ { key: "count", label: "Count", dataPath: "count", format: "number" }
1244
+ ],
1245
+ table: { caption: "Integration counts by type." }
1246
+ }
1247
+ });
1248
+ var ConnectionStatusVisualization = defineVisualization({
1249
+ meta: {
1250
+ ...META,
1251
+ key: "integration-hub.visualization.connection-status",
1252
+ title: "Connection Status",
1253
+ description: "Status distribution across configured connections.",
1254
+ goal: "Highlight connection health and instability.",
1255
+ context: "Connection monitoring."
1256
+ },
1257
+ source: { primary: CONNECTION_LIST_REF, resultPath: "data" },
1258
+ visualization: {
1259
+ kind: "cartesian",
1260
+ variant: "bar",
1261
+ xDimension: "status",
1262
+ yMeasures: ["count"],
1263
+ dimensions: [
1264
+ { key: "status", label: "Status", dataPath: "status", type: "category" }
1265
+ ],
1266
+ measures: [
1267
+ {
1268
+ key: "count",
1269
+ label: "Connections",
1270
+ dataPath: "count",
1271
+ format: "number",
1272
+ color: "#1d4ed8"
1273
+ }
1274
+ ],
1275
+ table: { caption: "Connection counts by status." }
1276
+ }
1277
+ });
1278
+ var HealthySyncMetricVisualization = defineVisualization({
1279
+ meta: {
1280
+ ...META,
1281
+ key: "integration-hub.visualization.sync-healthy",
1282
+ title: "Healthy Syncs",
1283
+ description: "Sync configurations currently healthy or recently successful.",
1284
+ goal: "Summarize healthy synchronization capacity.",
1285
+ context: "Sync-state comparison."
1286
+ },
1287
+ source: { primary: SYNC_CONFIG_REF, resultPath: "data" },
1288
+ visualization: {
1289
+ kind: "metric",
1290
+ measure: "value",
1291
+ measures: [
1292
+ { key: "value", label: "Syncs", dataPath: "value", format: "number" }
1293
+ ],
1294
+ table: { caption: "Healthy sync count." }
1295
+ }
1296
+ });
1297
+ var AttentionSyncMetricVisualization = defineVisualization({
1298
+ meta: {
1299
+ ...META,
1300
+ key: "integration-hub.visualization.sync-attention",
1301
+ title: "Attention Needed",
1302
+ description: "Sync configurations paused, failing, or otherwise needing review.",
1303
+ goal: "Summarize syncs needing action.",
1304
+ context: "Sync-state comparison."
1305
+ },
1306
+ source: { primary: SYNC_CONFIG_REF, resultPath: "data" },
1307
+ visualization: {
1308
+ kind: "metric",
1309
+ measure: "value",
1310
+ measures: [
1311
+ { key: "value", label: "Syncs", dataPath: "value", format: "number" }
1312
+ ],
1313
+ table: { caption: "Syncs requiring attention." }
1314
+ }
1315
+ });
1316
+ var IntegrationVisualizationSpecs = [
1317
+ IntegrationTypeVisualization,
1318
+ ConnectionStatusVisualization,
1319
+ HealthySyncMetricVisualization,
1320
+ AttentionSyncMetricVisualization
1321
+ ];
1322
+ var IntegrationVisualizationRegistry = new VisualizationRegistry([
1323
+ ...IntegrationVisualizationSpecs
1324
+ ]);
1325
+ var IntegrationVisualizationRefs = IntegrationVisualizationSpecs.map((spec) => ({
1326
+ key: spec.meta.key,
1327
+ version: spec.meta.version
1328
+ }));
1329
+
1330
+ // src/visualizations/selectors.ts
1331
+ function isHealthySync(status) {
1332
+ return status === "ACTIVE" || status === "SUCCESS";
1333
+ }
1334
+ function createIntegrationVisualizationSections(integrations, connections, syncConfigs) {
1335
+ const integrationTypes = new Map;
1336
+ const connectionStatuses = new Map;
1337
+ let healthySyncs = 0;
1338
+ let attentionSyncs = 0;
1339
+ for (const integration of integrations) {
1340
+ integrationTypes.set(integration.type, (integrationTypes.get(integration.type) ?? 0) + 1);
1341
+ }
1342
+ for (const connection of connections) {
1343
+ connectionStatuses.set(connection.status, (connectionStatuses.get(connection.status) ?? 0) + 1);
1344
+ }
1345
+ for (const syncConfig of syncConfigs) {
1346
+ if (isHealthySync(syncConfig.status)) {
1347
+ healthySyncs += 1;
1348
+ } else {
1349
+ attentionSyncs += 1;
1350
+ }
1351
+ }
1352
+ const primaryItems = [
1353
+ {
1354
+ key: "integration-types",
1355
+ spec: IntegrationTypeVisualization,
1356
+ data: {
1357
+ data: Array.from(integrationTypes.entries()).map(([type, count]) => ({
1358
+ type,
1359
+ count
1360
+ }))
1361
+ },
1362
+ title: "Integration Types",
1363
+ description: "Configured integrations grouped by category.",
1364
+ height: 260
1365
+ },
1366
+ {
1367
+ key: "connection-status",
1368
+ spec: ConnectionStatusVisualization,
1369
+ data: {
1370
+ data: Array.from(connectionStatuses.entries()).map(([status, count]) => ({
1371
+ status,
1372
+ count
1373
+ }))
1374
+ },
1375
+ title: "Connection Status",
1376
+ description: "Operational health across current connections."
1377
+ }
1378
+ ];
1379
+ const comparisonItems = [
1380
+ {
1381
+ key: "healthy-syncs",
1382
+ spec: HealthySyncMetricVisualization,
1383
+ data: { data: [{ value: healthySyncs }] },
1384
+ title: "Healthy Syncs",
1385
+ description: "Active or recently successful sync configurations.",
1386
+ height: 200
1387
+ },
1388
+ {
1389
+ key: "attention-syncs",
1390
+ spec: AttentionSyncMetricVisualization,
1391
+ data: { data: [{ value: attentionSyncs }] },
1392
+ title: "Attention Needed",
1393
+ description: "Paused, failed, or degraded sync configurations.",
1394
+ height: 200
1395
+ }
1396
+ ];
1397
+ return {
1398
+ primaryItems,
1399
+ comparisonItems
1400
+ };
1401
+ }
1402
+ // src/ui/IntegrationDashboard.visualizations.tsx
1403
+ import {
1404
+ ComparisonView,
1405
+ VisualizationCard,
1406
+ VisualizationGrid
1407
+ } from "@contractspec/lib.design-system";
1408
+ import { jsxDEV } from "react/jsx-dev-runtime";
1409
+ "use client";
1410
+ function IntegrationVisualizationOverview({
1411
+ integrations,
1412
+ connections,
1413
+ syncConfigs
1414
+ }) {
1415
+ const { primaryItems, comparisonItems } = createIntegrationVisualizationSections(integrations, connections, syncConfigs);
1416
+ return /* @__PURE__ */ jsxDEV("section", {
1417
+ className: "space-y-4",
1418
+ children: [
1419
+ /* @__PURE__ */ jsxDEV("div", {
1420
+ children: [
1421
+ /* @__PURE__ */ jsxDEV("h3", {
1422
+ className: "font-semibold text-lg",
1423
+ children: "Integration Visualizations"
1424
+ }, undefined, false, undefined, this),
1425
+ /* @__PURE__ */ jsxDEV("p", {
1426
+ className: "text-muted-foreground text-sm",
1427
+ children: "Contract-backed charts for integration coverage and sync health."
1428
+ }, undefined, false, undefined, this)
1429
+ ]
1430
+ }, undefined, true, undefined, this),
1431
+ /* @__PURE__ */ jsxDEV(VisualizationGrid, {
1432
+ children: primaryItems.map((item) => /* @__PURE__ */ jsxDEV(VisualizationCard, {
1433
+ data: item.data,
1434
+ description: item.description,
1435
+ height: item.height,
1436
+ spec: item.spec,
1437
+ title: item.title
1438
+ }, item.key, false, undefined, this))
1439
+ }, undefined, false, undefined, this),
1440
+ /* @__PURE__ */ jsxDEV(ComparisonView, {
1441
+ description: "Comparison surface for healthy versus attention-needed syncs.",
1442
+ items: comparisonItems,
1443
+ title: "Sync-State Comparison"
1444
+ }, undefined, false, undefined, this)
1445
+ ]
1446
+ }, undefined, true, undefined, this);
1447
+ }
1448
+
1201
1449
  // src/ui/IntegrationHubChat.tsx
1202
1450
  import { ChatWithSidebar } from "@contractspec/module.ai-chat";
1203
- import { jsxDEV } from "react/jsx-dev-runtime";
1451
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
1204
1452
  "use client";
1205
1453
  var DEFAULT_SUGGESTIONS = [
1206
1454
  "List my integrations",
@@ -1216,9 +1464,9 @@ function IntegrationHubChat({
1216
1464
  systemPrompt = DEFAULT_SYSTEM_PROMPT,
1217
1465
  className
1218
1466
  }) {
1219
- return /* @__PURE__ */ jsxDEV("div", {
1467
+ return /* @__PURE__ */ jsxDEV2("div", {
1220
1468
  className: className ?? "flex h-[500px] flex-col",
1221
- children: /* @__PURE__ */ jsxDEV(ChatWithSidebar, {
1469
+ children: /* @__PURE__ */ jsxDEV2(ChatWithSidebar, {
1222
1470
  className: "flex-1",
1223
1471
  systemPrompt,
1224
1472
  proxyUrl,
@@ -1230,16 +1478,373 @@ function IntegrationHubChat({
1230
1478
  }, undefined, false, undefined, this);
1231
1479
  }
1232
1480
 
1481
+ // src/ui/tables/integration-table.shared.tsx
1482
+ import { Button } from "@contractspec/lib.design-system";
1483
+ import { Badge } from "@contractspec/lib.ui-kit-web/ui/badge";
1484
+ import { HStack } from "@contractspec/lib.ui-kit-web/ui/stack";
1485
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
1486
+ "use client";
1487
+ var STATUS_VARIANTS = {
1488
+ ACTIVE: "default",
1489
+ CONNECTED: "default",
1490
+ SUCCESS: "default",
1491
+ PENDING: "secondary",
1492
+ PAUSED: "secondary",
1493
+ ERROR: "destructive",
1494
+ DISCONNECTED: "outline"
1495
+ };
1496
+ function formatDateTime(value) {
1497
+ return value ? value.toLocaleString() : "Never";
1498
+ }
1499
+ function formatJson(value) {
1500
+ return value ? JSON.stringify(value, null, 2) : "No configuration";
1501
+ }
1502
+ function StatusBadge({ status }) {
1503
+ return /* @__PURE__ */ jsxDEV3(Badge, {
1504
+ variant: STATUS_VARIANTS[status] ?? "outline",
1505
+ children: status
1506
+ }, undefined, false, undefined, this);
1507
+ }
1508
+ function IntegrationTableToolbar({
1509
+ controller,
1510
+ label,
1511
+ toggleColumnId,
1512
+ toggleVisibleLabel,
1513
+ toggleHiddenLabel,
1514
+ pinColumnId,
1515
+ pinLabel,
1516
+ resizeColumnId,
1517
+ resizeLabel
1518
+ }) {
1519
+ const firstRow = controller.rows[0];
1520
+ const toggleColumn = controller.columns.find((column) => column.id === toggleColumnId);
1521
+ const pinColumn = controller.columns.find((column) => column.id === pinColumnId);
1522
+ const resizeColumn = controller.columns.find((column) => column.id === resizeColumnId);
1523
+ const pinTarget = pinColumn?.pinState === "left" ? false : "left";
1524
+ return /* @__PURE__ */ jsxDEV3(HStack, {
1525
+ gap: "sm",
1526
+ className: "flex-wrap",
1527
+ children: [
1528
+ /* @__PURE__ */ jsxDEV3(Badge, {
1529
+ variant: "outline",
1530
+ children: label
1531
+ }, undefined, false, undefined, this),
1532
+ /* @__PURE__ */ jsxDEV3(Button, {
1533
+ variant: "outline",
1534
+ size: "sm",
1535
+ onPress: () => firstRow?.toggleExpanded?.(!firstRow?.isExpanded),
1536
+ children: "Expand First Row"
1537
+ }, undefined, false, undefined, this),
1538
+ /* @__PURE__ */ jsxDEV3(Button, {
1539
+ variant: "outline",
1540
+ size: "sm",
1541
+ onPress: () => toggleColumn?.toggleVisibility?.(!toggleColumn?.visible),
1542
+ children: toggleColumn?.visible ? toggleVisibleLabel : toggleHiddenLabel
1543
+ }, undefined, false, undefined, this),
1544
+ /* @__PURE__ */ jsxDEV3(Button, {
1545
+ variant: "outline",
1546
+ size: "sm",
1547
+ onPress: () => pinColumn?.pin?.(pinTarget),
1548
+ children: pinColumn?.pinState === "left" ? `Unpin ${pinLabel}` : `Pin ${pinLabel}`
1549
+ }, undefined, false, undefined, this),
1550
+ /* @__PURE__ */ jsxDEV3(Button, {
1551
+ variant: "outline",
1552
+ size: "sm",
1553
+ onPress: () => resizeColumn?.resizeBy?.(40),
1554
+ children: resizeLabel
1555
+ }, undefined, false, undefined, this)
1556
+ ]
1557
+ }, undefined, true, undefined, this);
1558
+ }
1559
+
1560
+ // src/ui/tables/ConnectionsTable.tsx
1561
+ import { DataTable } from "@contractspec/lib.design-system";
1562
+ import { useContractTable } from "@contractspec/lib.presentation-runtime-react";
1563
+ import { VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
1564
+ import { Text } from "@contractspec/lib.ui-kit-web/ui/text";
1565
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
1566
+ "use client";
1567
+ function ConnectionsTable({
1568
+ connections
1569
+ }) {
1570
+ const controller = useContractTable({
1571
+ data: connections,
1572
+ columns: [
1573
+ {
1574
+ id: "connection",
1575
+ header: "Connection",
1576
+ label: "Connection",
1577
+ accessor: (connection) => connection.name,
1578
+ cell: ({ item }) => /* @__PURE__ */ jsxDEV4(VStack, {
1579
+ gap: "xs",
1580
+ children: [
1581
+ /* @__PURE__ */ jsxDEV4(Text, {
1582
+ className: "font-medium text-sm",
1583
+ children: item.name
1584
+ }, undefined, false, undefined, this),
1585
+ /* @__PURE__ */ jsxDEV4(Text, {
1586
+ className: "text-muted-foreground text-xs",
1587
+ children: [
1588
+ "Created ",
1589
+ item.createdAt.toLocaleDateString()
1590
+ ]
1591
+ }, undefined, true, undefined, this)
1592
+ ]
1593
+ }, undefined, true, undefined, this),
1594
+ size: 240,
1595
+ minSize: 180,
1596
+ canSort: true,
1597
+ canPin: true,
1598
+ canResize: true
1599
+ },
1600
+ {
1601
+ id: "status",
1602
+ header: "Status",
1603
+ label: "Status",
1604
+ accessorKey: "status",
1605
+ cell: ({ value }) => /* @__PURE__ */ jsxDEV4(StatusBadge, {
1606
+ status: String(value)
1607
+ }, undefined, false, undefined, this),
1608
+ size: 150,
1609
+ canSort: true,
1610
+ canPin: true,
1611
+ canResize: true
1612
+ },
1613
+ {
1614
+ id: "lastSyncAt",
1615
+ header: "Last Sync",
1616
+ label: "Last Sync",
1617
+ accessor: (connection) => connection.lastSyncAt?.getTime() ?? 0,
1618
+ cell: ({ item }) => formatDateTime(item.lastSyncAt),
1619
+ size: 200,
1620
+ canSort: true,
1621
+ canHide: true,
1622
+ canResize: true
1623
+ },
1624
+ {
1625
+ id: "errorMessage",
1626
+ header: "Errors",
1627
+ label: "Errors",
1628
+ accessor: (connection) => connection.errorMessage ?? "",
1629
+ cell: ({ value }) => String(value || "No errors"),
1630
+ size: 240,
1631
+ canHide: true,
1632
+ canResize: true
1633
+ }
1634
+ ],
1635
+ initialState: {
1636
+ pagination: { pageIndex: 0, pageSize: 3 },
1637
+ columnVisibility: { errorMessage: false },
1638
+ columnPinning: { left: ["connection"], right: [] }
1639
+ },
1640
+ renderExpandedContent: (connection) => /* @__PURE__ */ jsxDEV4(VStack, {
1641
+ gap: "sm",
1642
+ className: "py-2",
1643
+ children: [
1644
+ /* @__PURE__ */ jsxDEV4(Text, {
1645
+ className: "font-medium text-sm",
1646
+ children: "Credentials"
1647
+ }, undefined, false, undefined, this),
1648
+ /* @__PURE__ */ jsxDEV4("pre", {
1649
+ className: "overflow-auto rounded-md bg-muted/40 p-3 text-xs",
1650
+ children: formatJson(connection.credentials)
1651
+ }, undefined, false, undefined, this),
1652
+ /* @__PURE__ */ jsxDEV4(Text, {
1653
+ className: "font-medium text-sm",
1654
+ children: "Config"
1655
+ }, undefined, false, undefined, this),
1656
+ /* @__PURE__ */ jsxDEV4("pre", {
1657
+ className: "overflow-auto rounded-md bg-muted/40 p-3 text-xs",
1658
+ children: formatJson(connection.config)
1659
+ }, undefined, false, undefined, this),
1660
+ /* @__PURE__ */ jsxDEV4(Text, {
1661
+ className: "text-muted-foreground text-sm",
1662
+ children: connection.errorMessage ?? "No sync errors recorded."
1663
+ }, undefined, false, undefined, this)
1664
+ ]
1665
+ }, undefined, true, undefined, this),
1666
+ getCanExpand: () => true
1667
+ });
1668
+ return /* @__PURE__ */ jsxDEV4(DataTable, {
1669
+ controller,
1670
+ title: "Connections",
1671
+ description: "Client-mode ContractSpec table with visibility, pinning, resizing, and expanded diagnostics.",
1672
+ toolbar: /* @__PURE__ */ jsxDEV4(IntegrationTableToolbar, {
1673
+ controller,
1674
+ label: `${connections.length} total connections`,
1675
+ toggleColumnId: "errorMessage",
1676
+ toggleVisibleLabel: "Hide Error Column",
1677
+ toggleHiddenLabel: "Show Error Column",
1678
+ pinColumnId: "status",
1679
+ pinLabel: "Status",
1680
+ resizeColumnId: "connection",
1681
+ resizeLabel: "Widen Connection"
1682
+ }, undefined, false, undefined, this),
1683
+ emptyState: /* @__PURE__ */ jsxDEV4("div", {
1684
+ className: "rounded-md border border-dashed p-8 text-center text-muted-foreground text-sm",
1685
+ children: "No connections found"
1686
+ }, undefined, false, undefined, this)
1687
+ }, undefined, false, undefined, this);
1688
+ }
1689
+
1690
+ // src/ui/tables/SyncConfigsTable.tsx
1691
+ import { DataTable as DataTable2 } from "@contractspec/lib.design-system";
1692
+ import { useContractTable as useContractTable2 } from "@contractspec/lib.presentation-runtime-react";
1693
+ import { VStack as VStack2 } from "@contractspec/lib.ui-kit-web/ui/stack";
1694
+ import { Text as Text2 } from "@contractspec/lib.ui-kit-web/ui/text";
1695
+ import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
1696
+ "use client";
1697
+ function SyncConfigsTable({
1698
+ syncConfigs
1699
+ }) {
1700
+ const controller = useContractTable2({
1701
+ data: syncConfigs,
1702
+ columns: [
1703
+ {
1704
+ id: "sync",
1705
+ header: "Sync Config",
1706
+ label: "Sync Config",
1707
+ accessor: (sync) => sync.name,
1708
+ cell: ({ item }) => /* @__PURE__ */ jsxDEV5(VStack2, {
1709
+ gap: "xs",
1710
+ children: [
1711
+ /* @__PURE__ */ jsxDEV5(Text2, {
1712
+ className: "font-medium text-sm",
1713
+ children: item.name
1714
+ }, undefined, false, undefined, this),
1715
+ /* @__PURE__ */ jsxDEV5(Text2, {
1716
+ className: "text-muted-foreground text-xs",
1717
+ children: [
1718
+ item.sourceEntity,
1719
+ " \u2192 ",
1720
+ item.targetEntity
1721
+ ]
1722
+ }, undefined, true, undefined, this)
1723
+ ]
1724
+ }, undefined, true, undefined, this),
1725
+ size: 260,
1726
+ minSize: 200,
1727
+ canSort: true,
1728
+ canPin: true,
1729
+ canResize: true
1730
+ },
1731
+ {
1732
+ id: "frequency",
1733
+ header: "Frequency",
1734
+ label: "Frequency",
1735
+ accessorKey: "frequency",
1736
+ size: 160,
1737
+ canSort: true,
1738
+ canHide: true,
1739
+ canResize: true
1740
+ },
1741
+ {
1742
+ id: "status",
1743
+ header: "Status",
1744
+ label: "Status",
1745
+ accessorKey: "status",
1746
+ cell: ({ value }) => /* @__PURE__ */ jsxDEV5(StatusBadge, {
1747
+ status: String(value)
1748
+ }, undefined, false, undefined, this),
1749
+ size: 150,
1750
+ canSort: true,
1751
+ canPin: true,
1752
+ canResize: true
1753
+ },
1754
+ {
1755
+ id: "recordsSynced",
1756
+ header: "Records",
1757
+ label: "Records",
1758
+ accessorKey: "recordsSynced",
1759
+ align: "right",
1760
+ size: 140,
1761
+ canSort: true,
1762
+ canResize: true
1763
+ },
1764
+ {
1765
+ id: "lastRunAt",
1766
+ header: "Last Run",
1767
+ label: "Last Run",
1768
+ accessor: (sync) => sync.lastRunAt?.getTime() ?? 0,
1769
+ cell: ({ item }) => formatDateTime(item.lastRunAt),
1770
+ size: 200,
1771
+ canSort: true,
1772
+ canHide: true,
1773
+ canResize: true
1774
+ }
1775
+ ],
1776
+ initialState: {
1777
+ pagination: { pageIndex: 0, pageSize: 3 },
1778
+ columnVisibility: { lastRunAt: false },
1779
+ columnPinning: { left: ["sync"], right: [] }
1780
+ },
1781
+ renderExpandedContent: (sync) => /* @__PURE__ */ jsxDEV5(VStack2, {
1782
+ gap: "sm",
1783
+ className: "py-2",
1784
+ children: [
1785
+ /* @__PURE__ */ jsxDEV5(Text2, {
1786
+ className: "text-muted-foreground text-sm",
1787
+ children: [
1788
+ "Connection ",
1789
+ sync.connectionId
1790
+ ]
1791
+ }, undefined, true, undefined, this),
1792
+ /* @__PURE__ */ jsxDEV5(Text2, {
1793
+ className: "text-muted-foreground text-sm",
1794
+ children: [
1795
+ "Last run: ",
1796
+ formatDateTime(sync.lastRunAt)
1797
+ ]
1798
+ }, undefined, true, undefined, this),
1799
+ /* @__PURE__ */ jsxDEV5(Text2, {
1800
+ className: "text-muted-foreground text-sm",
1801
+ children: [
1802
+ "Last status: ",
1803
+ sync.lastRunStatus ?? "No runs recorded"
1804
+ ]
1805
+ }, undefined, true, undefined, this),
1806
+ /* @__PURE__ */ jsxDEV5(Text2, {
1807
+ className: "text-muted-foreground text-sm",
1808
+ children: [
1809
+ "Updated ",
1810
+ sync.updatedAt.toLocaleString()
1811
+ ]
1812
+ }, undefined, true, undefined, this)
1813
+ ]
1814
+ }, undefined, true, undefined, this),
1815
+ getCanExpand: () => true
1816
+ });
1817
+ return /* @__PURE__ */ jsxDEV5(DataTable2, {
1818
+ controller,
1819
+ title: "Sync Configs",
1820
+ description: "Shared table primitives applied to sync monitoring without changing the surrounding dashboard layout.",
1821
+ toolbar: /* @__PURE__ */ jsxDEV5(IntegrationTableToolbar, {
1822
+ controller,
1823
+ label: `${syncConfigs.length} syncs`,
1824
+ toggleColumnId: "lastRunAt",
1825
+ toggleVisibleLabel: "Hide Last Run",
1826
+ toggleHiddenLabel: "Show Last Run",
1827
+ pinColumnId: "status",
1828
+ pinLabel: "Status",
1829
+ resizeColumnId: "sync",
1830
+ resizeLabel: "Widen Sync"
1831
+ }, undefined, false, undefined, this),
1832
+ emptyState: /* @__PURE__ */ jsxDEV5("div", {
1833
+ className: "rounded-md border border-dashed p-8 text-center text-muted-foreground text-sm",
1834
+ children: "No sync configurations found"
1835
+ }, undefined, false, undefined, this)
1836
+ }, undefined, false, undefined, this);
1837
+ }
1233
1838
  // src/ui/IntegrationDashboard.tsx
1234
1839
  import {
1235
- Button,
1840
+ Button as Button2,
1236
1841
  ErrorState,
1237
1842
  LoaderBlock,
1238
1843
  StatCard,
1239
1844
  StatCardGroup
1240
1845
  } from "@contractspec/lib.design-system";
1241
1846
  import { useState as useState2 } from "react";
1242
- import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
1847
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
1243
1848
  "use client";
1244
1849
  var STATUS_COLORS = {
1245
1850
  ACTIVE: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
@@ -1276,32 +1881,32 @@ function IntegrationDashboard() {
1276
1881
  { id: "chat", label: "Chat", icon: "\uD83D\uDCAC" }
1277
1882
  ];
1278
1883
  if (loading) {
1279
- return /* @__PURE__ */ jsxDEV2(LoaderBlock, {
1884
+ return /* @__PURE__ */ jsxDEV6(LoaderBlock, {
1280
1885
  label: "Loading Integrations..."
1281
1886
  }, undefined, false, undefined, this);
1282
1887
  }
1283
1888
  if (error) {
1284
- return /* @__PURE__ */ jsxDEV2(ErrorState, {
1889
+ return /* @__PURE__ */ jsxDEV6(ErrorState, {
1285
1890
  title: "Failed to load Integrations",
1286
1891
  description: error.message,
1287
1892
  onRetry: refetch,
1288
1893
  retryLabel: "Retry"
1289
1894
  }, undefined, false, undefined, this);
1290
1895
  }
1291
- return /* @__PURE__ */ jsxDEV2("div", {
1896
+ return /* @__PURE__ */ jsxDEV6("div", {
1292
1897
  className: "space-y-6",
1293
1898
  children: [
1294
- /* @__PURE__ */ jsxDEV2("div", {
1899
+ /* @__PURE__ */ jsxDEV6("div", {
1295
1900
  className: "flex items-center justify-between",
1296
1901
  children: [
1297
- /* @__PURE__ */ jsxDEV2("h2", {
1902
+ /* @__PURE__ */ jsxDEV6("h2", {
1298
1903
  className: "font-bold text-2xl",
1299
1904
  children: "Integration Hub"
1300
1905
  }, undefined, false, undefined, this),
1301
- /* @__PURE__ */ jsxDEV2(Button, {
1906
+ /* @__PURE__ */ jsxDEV6(Button2, {
1302
1907
  onClick: () => alert("Add integration modal"),
1303
1908
  children: [
1304
- /* @__PURE__ */ jsxDEV2("span", {
1909
+ /* @__PURE__ */ jsxDEV6("span", {
1305
1910
  className: "mr-2",
1306
1911
  children: "+"
1307
1912
  }, undefined, false, undefined, this),
@@ -1310,66 +1915,71 @@ function IntegrationDashboard() {
1310
1915
  }, undefined, true, undefined, this)
1311
1916
  ]
1312
1917
  }, undefined, true, undefined, this),
1313
- /* @__PURE__ */ jsxDEV2(StatCardGroup, {
1918
+ /* @__PURE__ */ jsxDEV6(StatCardGroup, {
1314
1919
  children: [
1315
- /* @__PURE__ */ jsxDEV2(StatCard, {
1920
+ /* @__PURE__ */ jsxDEV6(StatCard, {
1316
1921
  label: "Integrations",
1317
1922
  value: stats.totalIntegrations,
1318
1923
  hint: `${stats.activeIntegrations} active`
1319
1924
  }, undefined, false, undefined, this),
1320
- /* @__PURE__ */ jsxDEV2(StatCard, {
1925
+ /* @__PURE__ */ jsxDEV6(StatCard, {
1321
1926
  label: "Connections",
1322
1927
  value: stats.totalConnections,
1323
1928
  hint: `${stats.connectedCount} connected`
1324
1929
  }, undefined, false, undefined, this),
1325
- /* @__PURE__ */ jsxDEV2(StatCard, {
1930
+ /* @__PURE__ */ jsxDEV6(StatCard, {
1326
1931
  label: "Syncs",
1327
1932
  value: stats.totalSyncs,
1328
1933
  hint: `${stats.activeSyncs} active`
1329
1934
  }, undefined, false, undefined, this)
1330
1935
  ]
1331
1936
  }, undefined, true, undefined, this),
1332
- /* @__PURE__ */ jsxDEV2("nav", {
1937
+ /* @__PURE__ */ jsxDEV6(IntegrationVisualizationOverview, {
1938
+ connections,
1939
+ integrations,
1940
+ syncConfigs
1941
+ }, undefined, false, undefined, this),
1942
+ /* @__PURE__ */ jsxDEV6("nav", {
1333
1943
  className: "flex gap-1 rounded-lg bg-muted p-1",
1334
1944
  role: "tablist",
1335
- children: tabs.map((tab) => /* @__PURE__ */ jsxDEV2(Button, {
1945
+ children: tabs.map((tab) => /* @__PURE__ */ jsxDEV6(Button2, {
1336
1946
  type: "button",
1337
1947
  role: "tab",
1338
1948
  "aria-selected": activeTab === tab.id,
1339
1949
  onClick: () => setActiveTab(tab.id),
1340
1950
  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"}`,
1341
1951
  children: [
1342
- /* @__PURE__ */ jsxDEV2("span", {
1952
+ /* @__PURE__ */ jsxDEV6("span", {
1343
1953
  children: tab.icon
1344
1954
  }, undefined, false, undefined, this),
1345
1955
  tab.label
1346
1956
  ]
1347
1957
  }, tab.id, true, undefined, this))
1348
1958
  }, undefined, false, undefined, this),
1349
- /* @__PURE__ */ jsxDEV2("div", {
1959
+ /* @__PURE__ */ jsxDEV6("div", {
1350
1960
  className: "min-h-[400px]",
1351
1961
  role: "tabpanel",
1352
1962
  children: [
1353
- activeTab === "integrations" && /* @__PURE__ */ jsxDEV2("div", {
1963
+ activeTab === "integrations" && /* @__PURE__ */ jsxDEV6("div", {
1354
1964
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
1355
1965
  children: [
1356
- integrations.map((integration) => /* @__PURE__ */ jsxDEV2("div", {
1966
+ integrations.map((integration) => /* @__PURE__ */ jsxDEV6("div", {
1357
1967
  className: "cursor-pointer rounded-lg border border-border bg-card p-4 transition-colors hover:bg-muted/50",
1358
1968
  children: [
1359
- /* @__PURE__ */ jsxDEV2("div", {
1969
+ /* @__PURE__ */ jsxDEV6("div", {
1360
1970
  className: "mb-3 flex items-center gap-3",
1361
1971
  children: [
1362
- /* @__PURE__ */ jsxDEV2("span", {
1972
+ /* @__PURE__ */ jsxDEV6("span", {
1363
1973
  className: "text-2xl",
1364
1974
  children: TYPE_ICONS[integration.type] ?? "\u2699\uFE0F"
1365
1975
  }, undefined, false, undefined, this),
1366
- /* @__PURE__ */ jsxDEV2("div", {
1976
+ /* @__PURE__ */ jsxDEV6("div", {
1367
1977
  children: [
1368
- /* @__PURE__ */ jsxDEV2("h3", {
1978
+ /* @__PURE__ */ jsxDEV6("h3", {
1369
1979
  className: "font-medium",
1370
1980
  children: integration.name
1371
1981
  }, undefined, false, undefined, this),
1372
- /* @__PURE__ */ jsxDEV2("p", {
1982
+ /* @__PURE__ */ jsxDEV6("p", {
1373
1983
  className: "text-muted-foreground text-sm",
1374
1984
  children: integration.type
1375
1985
  }, undefined, false, undefined, this)
@@ -1377,14 +1987,14 @@ function IntegrationDashboard() {
1377
1987
  }, undefined, true, undefined, this)
1378
1988
  ]
1379
1989
  }, undefined, true, undefined, this),
1380
- /* @__PURE__ */ jsxDEV2("div", {
1990
+ /* @__PURE__ */ jsxDEV6("div", {
1381
1991
  className: "flex items-center justify-between",
1382
1992
  children: [
1383
- /* @__PURE__ */ jsxDEV2("span", {
1993
+ /* @__PURE__ */ jsxDEV6("span", {
1384
1994
  className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[integration.status] ?? ""}`,
1385
1995
  children: integration.status
1386
1996
  }, undefined, false, undefined, this),
1387
- /* @__PURE__ */ jsxDEV2("span", {
1997
+ /* @__PURE__ */ jsxDEV6("span", {
1388
1998
  className: "text-muted-foreground text-xs",
1389
1999
  children: integration.createdAt.toLocaleDateString()
1390
2000
  }, undefined, false, undefined, this)
@@ -1392,75 +2002,16 @@ function IntegrationDashboard() {
1392
2002
  }, undefined, true, undefined, this)
1393
2003
  ]
1394
2004
  }, integration.id, true, undefined, this)),
1395
- integrations.length === 0 && /* @__PURE__ */ jsxDEV2("div", {
2005
+ integrations.length === 0 && /* @__PURE__ */ jsxDEV6("div", {
1396
2006
  className: "col-span-full flex h-64 items-center justify-center text-muted-foreground",
1397
2007
  children: "No integrations configured"
1398
2008
  }, undefined, false, undefined, this)
1399
2009
  ]
1400
2010
  }, undefined, true, undefined, this),
1401
- activeTab === "connections" && /* @__PURE__ */ jsxDEV2("div", {
1402
- className: "rounded-lg border border-border",
1403
- children: /* @__PURE__ */ jsxDEV2("table", {
1404
- className: "w-full",
1405
- children: [
1406
- /* @__PURE__ */ jsxDEV2("thead", {
1407
- className: "border-border border-b bg-muted/30",
1408
- children: /* @__PURE__ */ jsxDEV2("tr", {
1409
- children: [
1410
- /* @__PURE__ */ jsxDEV2("th", {
1411
- className: "px-4 py-3 text-left font-medium text-sm",
1412
- children: "Connection"
1413
- }, undefined, false, undefined, this),
1414
- /* @__PURE__ */ jsxDEV2("th", {
1415
- className: "px-4 py-3 text-left font-medium text-sm",
1416
- children: "Status"
1417
- }, undefined, false, undefined, this),
1418
- /* @__PURE__ */ jsxDEV2("th", {
1419
- className: "px-4 py-3 text-left font-medium text-sm",
1420
- children: "Last Sync"
1421
- }, undefined, false, undefined, this)
1422
- ]
1423
- }, undefined, true, undefined, this)
1424
- }, undefined, false, undefined, this),
1425
- /* @__PURE__ */ jsxDEV2("tbody", {
1426
- className: "divide-y divide-border",
1427
- children: [
1428
- connections.map((conn) => /* @__PURE__ */ jsxDEV2("tr", {
1429
- className: "hover:bg-muted/50",
1430
- children: [
1431
- /* @__PURE__ */ jsxDEV2("td", {
1432
- className: "px-4 py-3",
1433
- children: /* @__PURE__ */ jsxDEV2("div", {
1434
- className: "font-medium",
1435
- children: conn.name
1436
- }, undefined, false, undefined, this)
1437
- }, undefined, false, undefined, this),
1438
- /* @__PURE__ */ jsxDEV2("td", {
1439
- className: "px-4 py-3",
1440
- children: /* @__PURE__ */ jsxDEV2("span", {
1441
- className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[conn.status] ?? ""}`,
1442
- children: conn.status
1443
- }, undefined, false, undefined, this)
1444
- }, undefined, false, undefined, this),
1445
- /* @__PURE__ */ jsxDEV2("td", {
1446
- className: "px-4 py-3 text-muted-foreground text-sm",
1447
- children: conn.lastSyncAt?.toLocaleString() ?? "Never"
1448
- }, undefined, false, undefined, this)
1449
- ]
1450
- }, conn.id, true, undefined, this)),
1451
- connections.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
1452
- children: /* @__PURE__ */ jsxDEV2("td", {
1453
- colSpan: 3,
1454
- className: "px-4 py-8 text-center text-muted-foreground",
1455
- children: "No connections found"
1456
- }, undefined, false, undefined, this)
1457
- }, undefined, false, undefined, this)
1458
- ]
1459
- }, undefined, true, undefined, this)
1460
- ]
1461
- }, undefined, true, undefined, this)
2011
+ activeTab === "connections" && /* @__PURE__ */ jsxDEV6(ConnectionsTable, {
2012
+ connections
1462
2013
  }, undefined, false, undefined, this),
1463
- activeTab === "chat" && /* @__PURE__ */ jsxDEV2(IntegrationHubChat, {
2014
+ activeTab === "chat" && /* @__PURE__ */ jsxDEV6(IntegrationHubChat, {
1464
2015
  proxyUrl: "/api/chat",
1465
2016
  thinkingLevel: "thinking",
1466
2017
  suggestions: [
@@ -1470,85 +2021,8 @@ function IntegrationDashboard() {
1470
2021
  ],
1471
2022
  className: "min-h-[400px]"
1472
2023
  }, undefined, false, undefined, this),
1473
- activeTab === "syncs" && /* @__PURE__ */ jsxDEV2("div", {
1474
- className: "rounded-lg border border-border",
1475
- children: /* @__PURE__ */ jsxDEV2("table", {
1476
- className: "w-full",
1477
- children: [
1478
- /* @__PURE__ */ jsxDEV2("thead", {
1479
- className: "border-border border-b bg-muted/30",
1480
- children: /* @__PURE__ */ jsxDEV2("tr", {
1481
- children: [
1482
- /* @__PURE__ */ jsxDEV2("th", {
1483
- className: "px-4 py-3 text-left font-medium text-sm",
1484
- children: "Sync Config"
1485
- }, undefined, false, undefined, this),
1486
- /* @__PURE__ */ jsxDEV2("th", {
1487
- className: "px-4 py-3 text-left font-medium text-sm",
1488
- children: "Frequency"
1489
- }, undefined, false, undefined, this),
1490
- /* @__PURE__ */ jsxDEV2("th", {
1491
- className: "px-4 py-3 text-left font-medium text-sm",
1492
- children: "Status"
1493
- }, undefined, false, undefined, this),
1494
- /* @__PURE__ */ jsxDEV2("th", {
1495
- className: "px-4 py-3 text-left font-medium text-sm",
1496
- children: "Records"
1497
- }, undefined, false, undefined, this)
1498
- ]
1499
- }, undefined, true, undefined, this)
1500
- }, undefined, false, undefined, this),
1501
- /* @__PURE__ */ jsxDEV2("tbody", {
1502
- className: "divide-y divide-border",
1503
- children: [
1504
- syncConfigs.map((sync) => /* @__PURE__ */ jsxDEV2("tr", {
1505
- className: "hover:bg-muted/50",
1506
- children: [
1507
- /* @__PURE__ */ jsxDEV2("td", {
1508
- className: "px-4 py-3",
1509
- children: [
1510
- /* @__PURE__ */ jsxDEV2("div", {
1511
- className: "font-medium",
1512
- children: sync.name
1513
- }, undefined, false, undefined, this),
1514
- /* @__PURE__ */ jsxDEV2("div", {
1515
- className: "text-muted-foreground text-sm",
1516
- children: [
1517
- sync.sourceEntity,
1518
- " \u2192 ",
1519
- sync.targetEntity
1520
- ]
1521
- }, undefined, true, undefined, this)
1522
- ]
1523
- }, undefined, true, undefined, this),
1524
- /* @__PURE__ */ jsxDEV2("td", {
1525
- className: "px-4 py-3 text-sm",
1526
- children: sync.frequency
1527
- }, undefined, false, undefined, this),
1528
- /* @__PURE__ */ jsxDEV2("td", {
1529
- className: "px-4 py-3",
1530
- children: /* @__PURE__ */ jsxDEV2("span", {
1531
- className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[sync.status] ?? ""}`,
1532
- children: sync.status
1533
- }, undefined, false, undefined, this)
1534
- }, undefined, false, undefined, this),
1535
- /* @__PURE__ */ jsxDEV2("td", {
1536
- className: "px-4 py-3 text-muted-foreground text-sm",
1537
- children: sync.recordsSynced.toLocaleString()
1538
- }, undefined, false, undefined, this)
1539
- ]
1540
- }, sync.id, true, undefined, this)),
1541
- syncConfigs.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
1542
- children: /* @__PURE__ */ jsxDEV2("td", {
1543
- colSpan: 4,
1544
- className: "px-4 py-8 text-center text-muted-foreground",
1545
- children: "No sync configurations found"
1546
- }, undefined, false, undefined, this)
1547
- }, undefined, false, undefined, this)
1548
- ]
1549
- }, undefined, true, undefined, this)
1550
- ]
1551
- }, undefined, true, undefined, this)
2024
+ activeTab === "syncs" && /* @__PURE__ */ jsxDEV6(SyncConfigsTable, {
2025
+ syncConfigs
1552
2026
  }, undefined, false, undefined, this)
1553
2027
  ]
1554
2028
  }, undefined, true, undefined, this)
@@ -1693,6 +2167,7 @@ var integrationDashboardMarkdownRenderer = {
1693
2167
  const integrations = mockIntegrations;
1694
2168
  const connections = mockConnections;
1695
2169
  const syncs = mockSyncConfigs;
2170
+ const visualizations = createIntegrationVisualizationSections(integrations, connections, syncs);
1696
2171
  const activeIntegrations = integrations.filter((i) => i.status === "ACTIVE");
1697
2172
  const connectedConnections = connections.filter((c) => c.status === "CONNECTED");
1698
2173
  const errorConnections = connections.filter((c) => c.status === "ERROR");
@@ -1712,12 +2187,21 @@ var integrationDashboardMarkdownRenderer = {
1712
2187
  `| Error Connections | ${errorConnections.length} |`,
1713
2188
  `| Sync Configs | ${syncs.length} |`,
1714
2189
  `| Records Synced (24h) | ${totalRecordsSynced.toLocaleString()} |`,
1715
- "",
1716
- "## Integrations",
1717
- "",
1718
- "| Name | Type | Connections | Status |",
1719
- "|------|------|-------------|--------|"
2190
+ ""
1720
2191
  ];
2192
+ lines.push("## Visualization Overview");
2193
+ lines.push("");
2194
+ for (const item of [
2195
+ ...visualizations.primaryItems,
2196
+ ...visualizations.comparisonItems
2197
+ ]) {
2198
+ lines.push(`- **${item.title}** via \`${item.spec.meta.key}\``);
2199
+ }
2200
+ lines.push("");
2201
+ lines.push("## Integrations");
2202
+ lines.push("");
2203
+ lines.push("| Name | Type | Connections | Status |");
2204
+ lines.push("|------|------|-------------|--------|");
1721
2205
  for (const integration of integrations) {
1722
2206
  const statusIcon = integration.status === "ACTIVE" ? "\uD83D\uDFE2" : "\u26AB";
1723
2207
  lines.push(`| ${integration.name} | ${integration.type} | ${integration.connectionCount} | ${statusIcon} ${integration.status} |`);
@@ -1831,6 +2315,7 @@ export {
1831
2315
  integrationDashboardMarkdownRenderer,
1832
2316
  hasChanges,
1833
2317
  createSyncEngine,
2318
+ createIntegrationVisualizationSections,
1834
2319
  createIntegrationHandlers,
1835
2320
  connectionListMarkdownRenderer,
1836
2321
  computeChecksum,
@@ -1844,10 +2329,15 @@ export {
1844
2329
  ListSyncRunsOutputModel,
1845
2330
  ListSyncRunsInputModel,
1846
2331
  ListSyncRunsContract,
2332
+ IntegrationVisualizationSpecs,
2333
+ IntegrationVisualizationRegistry,
2334
+ IntegrationVisualizationRefs,
2335
+ IntegrationTypeVisualization,
1847
2336
  IntegrationStatusEnum,
1848
2337
  IntegrationModel,
1849
2338
  IntegrationHubChat,
1850
2339
  IntegrationDashboard,
2340
+ HealthySyncMetricVisualization,
1851
2341
  FieldMappingModel,
1852
2342
  CreateSyncConfigInputModel,
1853
2343
  CreateSyncConfigContract,
@@ -1855,10 +2345,12 @@ export {
1855
2345
  CreateIntegrationContract,
1856
2346
  CreateConnectionInputModel,
1857
2347
  CreateConnectionContract,
2348
+ ConnectionStatusVisualization,
1858
2349
  ConnectionStatusEnum,
1859
2350
  ConnectionModel,
1860
2351
  BasicSyncEngine,
1861
2352
  BasicFieldTransformer,
2353
+ AttentionSyncMetricVisualization,
1862
2354
  AddFieldMappingInputModel,
1863
2355
  AddFieldMappingContract
1864
2356
  };