@contractspec/example.integration-hub 3.7.6 → 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 (57) hide show
  1. package/README.md +73 -183
  2. package/dist/connection/index.d.ts +1 -1
  3. package/dist/docs/index.js +2 -1
  4. package/dist/docs/integration-hub.docblock.js +2 -1
  5. package/dist/events.js +1 -1
  6. package/dist/index.d.ts +5 -4
  7. package/dist/index.js +1243 -749
  8. package/dist/integration/index.d.ts +1 -1
  9. package/dist/integration-hub.feature.js +202 -0
  10. package/dist/node/docs/index.js +2 -1
  11. package/dist/node/docs/integration-hub.docblock.js +2 -1
  12. package/dist/node/events.js +1 -1
  13. package/dist/node/index.js +1243 -749
  14. package/dist/node/integration-hub.feature.js +202 -0
  15. package/dist/node/ui/IntegrationDashboard.js +654 -180
  16. package/dist/node/ui/IntegrationDashboard.visualizations.js +250 -0
  17. package/dist/node/ui/hooks/index.js +1 -1
  18. package/dist/node/ui/hooks/useIntegrationData.js +1 -1
  19. package/dist/node/ui/index.js +970 -485
  20. package/dist/node/ui/renderers/index.js +216 -5
  21. package/dist/node/ui/renderers/integration.markdown.js +216 -5
  22. package/dist/node/ui/tables/ConnectionsTable.js +211 -0
  23. package/dist/node/ui/tables/IntegrationTables.js +361 -0
  24. package/dist/node/ui/tables/SyncConfigsTable.js +230 -0
  25. package/dist/node/ui/tables/integration-table.shared.js +84 -0
  26. package/dist/node/visualizations/catalog.js +137 -0
  27. package/dist/node/visualizations/index.js +211 -0
  28. package/dist/node/visualizations/selectors.js +204 -0
  29. package/dist/sync/index.d.ts +3 -3
  30. package/dist/ui/IntegrationDashboard.js +654 -180
  31. package/dist/ui/IntegrationDashboard.visualizations.d.ts +6 -0
  32. package/dist/ui/IntegrationDashboard.visualizations.js +251 -0
  33. package/dist/ui/hooks/index.d.ts +1 -1
  34. package/dist/ui/hooks/index.js +1 -1
  35. package/dist/ui/hooks/useIntegrationData.js +1 -1
  36. package/dist/ui/index.d.ts +2 -2
  37. package/dist/ui/index.js +970 -485
  38. package/dist/ui/renderers/index.d.ts +1 -1
  39. package/dist/ui/renderers/index.js +216 -5
  40. package/dist/ui/renderers/integration.markdown.js +216 -5
  41. package/dist/ui/tables/ConnectionsTable.d.ts +4 -0
  42. package/dist/ui/tables/ConnectionsTable.js +212 -0
  43. package/dist/ui/tables/IntegrationTables.d.ts +2 -0
  44. package/dist/ui/tables/IntegrationTables.js +362 -0
  45. package/dist/ui/tables/IntegrationTables.smoke.test.d.ts +1 -0
  46. package/dist/ui/tables/SyncConfigsTable.d.ts +4 -0
  47. package/dist/ui/tables/SyncConfigsTable.js +231 -0
  48. package/dist/ui/tables/integration-table.shared.d.ts +18 -0
  49. package/dist/ui/tables/integration-table.shared.js +85 -0
  50. package/dist/visualizations/catalog.d.ts +11 -0
  51. package/dist/visualizations/catalog.js +138 -0
  52. package/dist/visualizations/index.d.ts +2 -0
  53. package/dist/visualizations/index.js +212 -0
  54. package/dist/visualizations/selectors.d.ts +10 -0
  55. package/dist/visualizations/selectors.js +205 -0
  56. package/dist/visualizations/selectors.test.d.ts +1 -0
  57. package/package.json +110 -12
@@ -0,0 +1,361 @@
1
+ // src/ui/tables/integration-table.shared.tsx
2
+ import { Button } from "@contractspec/lib.design-system";
3
+ import { Badge } from "@contractspec/lib.ui-kit-web/ui/badge";
4
+ import { HStack } from "@contractspec/lib.ui-kit-web/ui/stack";
5
+ import { jsxDEV } from "react/jsx-dev-runtime";
6
+ "use client";
7
+ var STATUS_VARIANTS = {
8
+ ACTIVE: "default",
9
+ CONNECTED: "default",
10
+ SUCCESS: "default",
11
+ PENDING: "secondary",
12
+ PAUSED: "secondary",
13
+ ERROR: "destructive",
14
+ DISCONNECTED: "outline"
15
+ };
16
+ function formatDateTime(value) {
17
+ return value ? value.toLocaleString() : "Never";
18
+ }
19
+ function formatJson(value) {
20
+ return value ? JSON.stringify(value, null, 2) : "No configuration";
21
+ }
22
+ function StatusBadge({ status }) {
23
+ return /* @__PURE__ */ jsxDEV(Badge, {
24
+ variant: STATUS_VARIANTS[status] ?? "outline",
25
+ children: status
26
+ }, undefined, false, undefined, this);
27
+ }
28
+ function IntegrationTableToolbar({
29
+ controller,
30
+ label,
31
+ toggleColumnId,
32
+ toggleVisibleLabel,
33
+ toggleHiddenLabel,
34
+ pinColumnId,
35
+ pinLabel,
36
+ resizeColumnId,
37
+ resizeLabel
38
+ }) {
39
+ const firstRow = controller.rows[0];
40
+ const toggleColumn = controller.columns.find((column) => column.id === toggleColumnId);
41
+ const pinColumn = controller.columns.find((column) => column.id === pinColumnId);
42
+ const resizeColumn = controller.columns.find((column) => column.id === resizeColumnId);
43
+ const pinTarget = pinColumn?.pinState === "left" ? false : "left";
44
+ return /* @__PURE__ */ jsxDEV(HStack, {
45
+ gap: "sm",
46
+ className: "flex-wrap",
47
+ children: [
48
+ /* @__PURE__ */ jsxDEV(Badge, {
49
+ variant: "outline",
50
+ children: label
51
+ }, undefined, false, undefined, this),
52
+ /* @__PURE__ */ jsxDEV(Button, {
53
+ variant: "outline",
54
+ size: "sm",
55
+ onPress: () => firstRow?.toggleExpanded?.(!firstRow?.isExpanded),
56
+ children: "Expand First Row"
57
+ }, undefined, false, undefined, this),
58
+ /* @__PURE__ */ jsxDEV(Button, {
59
+ variant: "outline",
60
+ size: "sm",
61
+ onPress: () => toggleColumn?.toggleVisibility?.(!toggleColumn?.visible),
62
+ children: toggleColumn?.visible ? toggleVisibleLabel : toggleHiddenLabel
63
+ }, undefined, false, undefined, this),
64
+ /* @__PURE__ */ jsxDEV(Button, {
65
+ variant: "outline",
66
+ size: "sm",
67
+ onPress: () => pinColumn?.pin?.(pinTarget),
68
+ children: pinColumn?.pinState === "left" ? `Unpin ${pinLabel}` : `Pin ${pinLabel}`
69
+ }, undefined, false, undefined, this),
70
+ /* @__PURE__ */ jsxDEV(Button, {
71
+ variant: "outline",
72
+ size: "sm",
73
+ onPress: () => resizeColumn?.resizeBy?.(40),
74
+ children: resizeLabel
75
+ }, undefined, false, undefined, this)
76
+ ]
77
+ }, undefined, true, undefined, this);
78
+ }
79
+
80
+ // src/ui/tables/ConnectionsTable.tsx
81
+ import { DataTable } from "@contractspec/lib.design-system";
82
+ import { useContractTable } from "@contractspec/lib.presentation-runtime-react";
83
+ import { VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
84
+ import { Text } from "@contractspec/lib.ui-kit-web/ui/text";
85
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
86
+ "use client";
87
+ function ConnectionsTable({
88
+ connections
89
+ }) {
90
+ const controller = useContractTable({
91
+ data: connections,
92
+ columns: [
93
+ {
94
+ id: "connection",
95
+ header: "Connection",
96
+ label: "Connection",
97
+ accessor: (connection) => connection.name,
98
+ cell: ({ item }) => /* @__PURE__ */ jsxDEV2(VStack, {
99
+ gap: "xs",
100
+ children: [
101
+ /* @__PURE__ */ jsxDEV2(Text, {
102
+ className: "font-medium text-sm",
103
+ children: item.name
104
+ }, undefined, false, undefined, this),
105
+ /* @__PURE__ */ jsxDEV2(Text, {
106
+ className: "text-muted-foreground text-xs",
107
+ children: [
108
+ "Created ",
109
+ item.createdAt.toLocaleDateString()
110
+ ]
111
+ }, undefined, true, undefined, this)
112
+ ]
113
+ }, undefined, true, undefined, this),
114
+ size: 240,
115
+ minSize: 180,
116
+ canSort: true,
117
+ canPin: true,
118
+ canResize: true
119
+ },
120
+ {
121
+ id: "status",
122
+ header: "Status",
123
+ label: "Status",
124
+ accessorKey: "status",
125
+ cell: ({ value }) => /* @__PURE__ */ jsxDEV2(StatusBadge, {
126
+ status: String(value)
127
+ }, undefined, false, undefined, this),
128
+ size: 150,
129
+ canSort: true,
130
+ canPin: true,
131
+ canResize: true
132
+ },
133
+ {
134
+ id: "lastSyncAt",
135
+ header: "Last Sync",
136
+ label: "Last Sync",
137
+ accessor: (connection) => connection.lastSyncAt?.getTime() ?? 0,
138
+ cell: ({ item }) => formatDateTime(item.lastSyncAt),
139
+ size: 200,
140
+ canSort: true,
141
+ canHide: true,
142
+ canResize: true
143
+ },
144
+ {
145
+ id: "errorMessage",
146
+ header: "Errors",
147
+ label: "Errors",
148
+ accessor: (connection) => connection.errorMessage ?? "",
149
+ cell: ({ value }) => String(value || "No errors"),
150
+ size: 240,
151
+ canHide: true,
152
+ canResize: true
153
+ }
154
+ ],
155
+ initialState: {
156
+ pagination: { pageIndex: 0, pageSize: 3 },
157
+ columnVisibility: { errorMessage: false },
158
+ columnPinning: { left: ["connection"], right: [] }
159
+ },
160
+ renderExpandedContent: (connection) => /* @__PURE__ */ jsxDEV2(VStack, {
161
+ gap: "sm",
162
+ className: "py-2",
163
+ children: [
164
+ /* @__PURE__ */ jsxDEV2(Text, {
165
+ className: "font-medium text-sm",
166
+ children: "Credentials"
167
+ }, undefined, false, undefined, this),
168
+ /* @__PURE__ */ jsxDEV2("pre", {
169
+ className: "overflow-auto rounded-md bg-muted/40 p-3 text-xs",
170
+ children: formatJson(connection.credentials)
171
+ }, undefined, false, undefined, this),
172
+ /* @__PURE__ */ jsxDEV2(Text, {
173
+ className: "font-medium text-sm",
174
+ children: "Config"
175
+ }, undefined, false, undefined, this),
176
+ /* @__PURE__ */ jsxDEV2("pre", {
177
+ className: "overflow-auto rounded-md bg-muted/40 p-3 text-xs",
178
+ children: formatJson(connection.config)
179
+ }, undefined, false, undefined, this),
180
+ /* @__PURE__ */ jsxDEV2(Text, {
181
+ className: "text-muted-foreground text-sm",
182
+ children: connection.errorMessage ?? "No sync errors recorded."
183
+ }, undefined, false, undefined, this)
184
+ ]
185
+ }, undefined, true, undefined, this),
186
+ getCanExpand: () => true
187
+ });
188
+ return /* @__PURE__ */ jsxDEV2(DataTable, {
189
+ controller,
190
+ title: "Connections",
191
+ description: "Client-mode ContractSpec table with visibility, pinning, resizing, and expanded diagnostics.",
192
+ toolbar: /* @__PURE__ */ jsxDEV2(IntegrationTableToolbar, {
193
+ controller,
194
+ label: `${connections.length} total connections`,
195
+ toggleColumnId: "errorMessage",
196
+ toggleVisibleLabel: "Hide Error Column",
197
+ toggleHiddenLabel: "Show Error Column",
198
+ pinColumnId: "status",
199
+ pinLabel: "Status",
200
+ resizeColumnId: "connection",
201
+ resizeLabel: "Widen Connection"
202
+ }, undefined, false, undefined, this),
203
+ emptyState: /* @__PURE__ */ jsxDEV2("div", {
204
+ className: "rounded-md border border-dashed p-8 text-center text-muted-foreground text-sm",
205
+ children: "No connections found"
206
+ }, undefined, false, undefined, this)
207
+ }, undefined, false, undefined, this);
208
+ }
209
+
210
+ // src/ui/tables/SyncConfigsTable.tsx
211
+ import { DataTable as DataTable2 } from "@contractspec/lib.design-system";
212
+ import { useContractTable as useContractTable2 } from "@contractspec/lib.presentation-runtime-react";
213
+ import { VStack as VStack2 } from "@contractspec/lib.ui-kit-web/ui/stack";
214
+ import { Text as Text2 } from "@contractspec/lib.ui-kit-web/ui/text";
215
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
216
+ "use client";
217
+ function SyncConfigsTable({
218
+ syncConfigs
219
+ }) {
220
+ const controller = useContractTable2({
221
+ data: syncConfigs,
222
+ columns: [
223
+ {
224
+ id: "sync",
225
+ header: "Sync Config",
226
+ label: "Sync Config",
227
+ accessor: (sync) => sync.name,
228
+ cell: ({ item }) => /* @__PURE__ */ jsxDEV3(VStack2, {
229
+ gap: "xs",
230
+ children: [
231
+ /* @__PURE__ */ jsxDEV3(Text2, {
232
+ className: "font-medium text-sm",
233
+ children: item.name
234
+ }, undefined, false, undefined, this),
235
+ /* @__PURE__ */ jsxDEV3(Text2, {
236
+ className: "text-muted-foreground text-xs",
237
+ children: [
238
+ item.sourceEntity,
239
+ " → ",
240
+ item.targetEntity
241
+ ]
242
+ }, undefined, true, undefined, this)
243
+ ]
244
+ }, undefined, true, undefined, this),
245
+ size: 260,
246
+ minSize: 200,
247
+ canSort: true,
248
+ canPin: true,
249
+ canResize: true
250
+ },
251
+ {
252
+ id: "frequency",
253
+ header: "Frequency",
254
+ label: "Frequency",
255
+ accessorKey: "frequency",
256
+ size: 160,
257
+ canSort: true,
258
+ canHide: true,
259
+ canResize: true
260
+ },
261
+ {
262
+ id: "status",
263
+ header: "Status",
264
+ label: "Status",
265
+ accessorKey: "status",
266
+ cell: ({ value }) => /* @__PURE__ */ jsxDEV3(StatusBadge, {
267
+ status: String(value)
268
+ }, undefined, false, undefined, this),
269
+ size: 150,
270
+ canSort: true,
271
+ canPin: true,
272
+ canResize: true
273
+ },
274
+ {
275
+ id: "recordsSynced",
276
+ header: "Records",
277
+ label: "Records",
278
+ accessorKey: "recordsSynced",
279
+ align: "right",
280
+ size: 140,
281
+ canSort: true,
282
+ canResize: true
283
+ },
284
+ {
285
+ id: "lastRunAt",
286
+ header: "Last Run",
287
+ label: "Last Run",
288
+ accessor: (sync) => sync.lastRunAt?.getTime() ?? 0,
289
+ cell: ({ item }) => formatDateTime(item.lastRunAt),
290
+ size: 200,
291
+ canSort: true,
292
+ canHide: true,
293
+ canResize: true
294
+ }
295
+ ],
296
+ initialState: {
297
+ pagination: { pageIndex: 0, pageSize: 3 },
298
+ columnVisibility: { lastRunAt: false },
299
+ columnPinning: { left: ["sync"], right: [] }
300
+ },
301
+ renderExpandedContent: (sync) => /* @__PURE__ */ jsxDEV3(VStack2, {
302
+ gap: "sm",
303
+ className: "py-2",
304
+ children: [
305
+ /* @__PURE__ */ jsxDEV3(Text2, {
306
+ className: "text-muted-foreground text-sm",
307
+ children: [
308
+ "Connection ",
309
+ sync.connectionId
310
+ ]
311
+ }, undefined, true, undefined, this),
312
+ /* @__PURE__ */ jsxDEV3(Text2, {
313
+ className: "text-muted-foreground text-sm",
314
+ children: [
315
+ "Last run: ",
316
+ formatDateTime(sync.lastRunAt)
317
+ ]
318
+ }, undefined, true, undefined, this),
319
+ /* @__PURE__ */ jsxDEV3(Text2, {
320
+ className: "text-muted-foreground text-sm",
321
+ children: [
322
+ "Last status: ",
323
+ sync.lastRunStatus ?? "No runs recorded"
324
+ ]
325
+ }, undefined, true, undefined, this),
326
+ /* @__PURE__ */ jsxDEV3(Text2, {
327
+ className: "text-muted-foreground text-sm",
328
+ children: [
329
+ "Updated ",
330
+ sync.updatedAt.toLocaleString()
331
+ ]
332
+ }, undefined, true, undefined, this)
333
+ ]
334
+ }, undefined, true, undefined, this),
335
+ getCanExpand: () => true
336
+ });
337
+ return /* @__PURE__ */ jsxDEV3(DataTable2, {
338
+ controller,
339
+ title: "Sync Configs",
340
+ description: "Shared table primitives applied to sync monitoring without changing the surrounding dashboard layout.",
341
+ toolbar: /* @__PURE__ */ jsxDEV3(IntegrationTableToolbar, {
342
+ controller,
343
+ label: `${syncConfigs.length} syncs`,
344
+ toggleColumnId: "lastRunAt",
345
+ toggleVisibleLabel: "Hide Last Run",
346
+ toggleHiddenLabel: "Show Last Run",
347
+ pinColumnId: "status",
348
+ pinLabel: "Status",
349
+ resizeColumnId: "sync",
350
+ resizeLabel: "Widen Sync"
351
+ }, undefined, false, undefined, this),
352
+ emptyState: /* @__PURE__ */ jsxDEV3("div", {
353
+ className: "rounded-md border border-dashed p-8 text-center text-muted-foreground text-sm",
354
+ children: "No sync configurations found"
355
+ }, undefined, false, undefined, this)
356
+ }, undefined, false, undefined, this);
357
+ }
358
+ export {
359
+ SyncConfigsTable,
360
+ ConnectionsTable
361
+ };
@@ -0,0 +1,230 @@
1
+ // src/ui/tables/integration-table.shared.tsx
2
+ import { Button } from "@contractspec/lib.design-system";
3
+ import { Badge } from "@contractspec/lib.ui-kit-web/ui/badge";
4
+ import { HStack } from "@contractspec/lib.ui-kit-web/ui/stack";
5
+ import { jsxDEV } from "react/jsx-dev-runtime";
6
+ "use client";
7
+ var STATUS_VARIANTS = {
8
+ ACTIVE: "default",
9
+ CONNECTED: "default",
10
+ SUCCESS: "default",
11
+ PENDING: "secondary",
12
+ PAUSED: "secondary",
13
+ ERROR: "destructive",
14
+ DISCONNECTED: "outline"
15
+ };
16
+ function formatDateTime(value) {
17
+ return value ? value.toLocaleString() : "Never";
18
+ }
19
+ function formatJson(value) {
20
+ return value ? JSON.stringify(value, null, 2) : "No configuration";
21
+ }
22
+ function StatusBadge({ status }) {
23
+ return /* @__PURE__ */ jsxDEV(Badge, {
24
+ variant: STATUS_VARIANTS[status] ?? "outline",
25
+ children: status
26
+ }, undefined, false, undefined, this);
27
+ }
28
+ function IntegrationTableToolbar({
29
+ controller,
30
+ label,
31
+ toggleColumnId,
32
+ toggleVisibleLabel,
33
+ toggleHiddenLabel,
34
+ pinColumnId,
35
+ pinLabel,
36
+ resizeColumnId,
37
+ resizeLabel
38
+ }) {
39
+ const firstRow = controller.rows[0];
40
+ const toggleColumn = controller.columns.find((column) => column.id === toggleColumnId);
41
+ const pinColumn = controller.columns.find((column) => column.id === pinColumnId);
42
+ const resizeColumn = controller.columns.find((column) => column.id === resizeColumnId);
43
+ const pinTarget = pinColumn?.pinState === "left" ? false : "left";
44
+ return /* @__PURE__ */ jsxDEV(HStack, {
45
+ gap: "sm",
46
+ className: "flex-wrap",
47
+ children: [
48
+ /* @__PURE__ */ jsxDEV(Badge, {
49
+ variant: "outline",
50
+ children: label
51
+ }, undefined, false, undefined, this),
52
+ /* @__PURE__ */ jsxDEV(Button, {
53
+ variant: "outline",
54
+ size: "sm",
55
+ onPress: () => firstRow?.toggleExpanded?.(!firstRow?.isExpanded),
56
+ children: "Expand First Row"
57
+ }, undefined, false, undefined, this),
58
+ /* @__PURE__ */ jsxDEV(Button, {
59
+ variant: "outline",
60
+ size: "sm",
61
+ onPress: () => toggleColumn?.toggleVisibility?.(!toggleColumn?.visible),
62
+ children: toggleColumn?.visible ? toggleVisibleLabel : toggleHiddenLabel
63
+ }, undefined, false, undefined, this),
64
+ /* @__PURE__ */ jsxDEV(Button, {
65
+ variant: "outline",
66
+ size: "sm",
67
+ onPress: () => pinColumn?.pin?.(pinTarget),
68
+ children: pinColumn?.pinState === "left" ? `Unpin ${pinLabel}` : `Pin ${pinLabel}`
69
+ }, undefined, false, undefined, this),
70
+ /* @__PURE__ */ jsxDEV(Button, {
71
+ variant: "outline",
72
+ size: "sm",
73
+ onPress: () => resizeColumn?.resizeBy?.(40),
74
+ children: resizeLabel
75
+ }, undefined, false, undefined, this)
76
+ ]
77
+ }, undefined, true, undefined, this);
78
+ }
79
+
80
+ // src/ui/tables/SyncConfigsTable.tsx
81
+ import { DataTable } from "@contractspec/lib.design-system";
82
+ import { useContractTable } from "@contractspec/lib.presentation-runtime-react";
83
+ import { VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
84
+ import { Text } from "@contractspec/lib.ui-kit-web/ui/text";
85
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
86
+ "use client";
87
+ function SyncConfigsTable({
88
+ syncConfigs
89
+ }) {
90
+ const controller = useContractTable({
91
+ data: syncConfigs,
92
+ columns: [
93
+ {
94
+ id: "sync",
95
+ header: "Sync Config",
96
+ label: "Sync Config",
97
+ accessor: (sync) => sync.name,
98
+ cell: ({ item }) => /* @__PURE__ */ jsxDEV2(VStack, {
99
+ gap: "xs",
100
+ children: [
101
+ /* @__PURE__ */ jsxDEV2(Text, {
102
+ className: "font-medium text-sm",
103
+ children: item.name
104
+ }, undefined, false, undefined, this),
105
+ /* @__PURE__ */ jsxDEV2(Text, {
106
+ className: "text-muted-foreground text-xs",
107
+ children: [
108
+ item.sourceEntity,
109
+ " → ",
110
+ item.targetEntity
111
+ ]
112
+ }, undefined, true, undefined, this)
113
+ ]
114
+ }, undefined, true, undefined, this),
115
+ size: 260,
116
+ minSize: 200,
117
+ canSort: true,
118
+ canPin: true,
119
+ canResize: true
120
+ },
121
+ {
122
+ id: "frequency",
123
+ header: "Frequency",
124
+ label: "Frequency",
125
+ accessorKey: "frequency",
126
+ size: 160,
127
+ canSort: true,
128
+ canHide: true,
129
+ canResize: true
130
+ },
131
+ {
132
+ id: "status",
133
+ header: "Status",
134
+ label: "Status",
135
+ accessorKey: "status",
136
+ cell: ({ value }) => /* @__PURE__ */ jsxDEV2(StatusBadge, {
137
+ status: String(value)
138
+ }, undefined, false, undefined, this),
139
+ size: 150,
140
+ canSort: true,
141
+ canPin: true,
142
+ canResize: true
143
+ },
144
+ {
145
+ id: "recordsSynced",
146
+ header: "Records",
147
+ label: "Records",
148
+ accessorKey: "recordsSynced",
149
+ align: "right",
150
+ size: 140,
151
+ canSort: true,
152
+ canResize: true
153
+ },
154
+ {
155
+ id: "lastRunAt",
156
+ header: "Last Run",
157
+ label: "Last Run",
158
+ accessor: (sync) => sync.lastRunAt?.getTime() ?? 0,
159
+ cell: ({ item }) => formatDateTime(item.lastRunAt),
160
+ size: 200,
161
+ canSort: true,
162
+ canHide: true,
163
+ canResize: true
164
+ }
165
+ ],
166
+ initialState: {
167
+ pagination: { pageIndex: 0, pageSize: 3 },
168
+ columnVisibility: { lastRunAt: false },
169
+ columnPinning: { left: ["sync"], right: [] }
170
+ },
171
+ renderExpandedContent: (sync) => /* @__PURE__ */ jsxDEV2(VStack, {
172
+ gap: "sm",
173
+ className: "py-2",
174
+ children: [
175
+ /* @__PURE__ */ jsxDEV2(Text, {
176
+ className: "text-muted-foreground text-sm",
177
+ children: [
178
+ "Connection ",
179
+ sync.connectionId
180
+ ]
181
+ }, undefined, true, undefined, this),
182
+ /* @__PURE__ */ jsxDEV2(Text, {
183
+ className: "text-muted-foreground text-sm",
184
+ children: [
185
+ "Last run: ",
186
+ formatDateTime(sync.lastRunAt)
187
+ ]
188
+ }, undefined, true, undefined, this),
189
+ /* @__PURE__ */ jsxDEV2(Text, {
190
+ className: "text-muted-foreground text-sm",
191
+ children: [
192
+ "Last status: ",
193
+ sync.lastRunStatus ?? "No runs recorded"
194
+ ]
195
+ }, undefined, true, undefined, this),
196
+ /* @__PURE__ */ jsxDEV2(Text, {
197
+ className: "text-muted-foreground text-sm",
198
+ children: [
199
+ "Updated ",
200
+ sync.updatedAt.toLocaleString()
201
+ ]
202
+ }, undefined, true, undefined, this)
203
+ ]
204
+ }, undefined, true, undefined, this),
205
+ getCanExpand: () => true
206
+ });
207
+ return /* @__PURE__ */ jsxDEV2(DataTable, {
208
+ controller,
209
+ title: "Sync Configs",
210
+ description: "Shared table primitives applied to sync monitoring without changing the surrounding dashboard layout.",
211
+ toolbar: /* @__PURE__ */ jsxDEV2(IntegrationTableToolbar, {
212
+ controller,
213
+ label: `${syncConfigs.length} syncs`,
214
+ toggleColumnId: "lastRunAt",
215
+ toggleVisibleLabel: "Hide Last Run",
216
+ toggleHiddenLabel: "Show Last Run",
217
+ pinColumnId: "status",
218
+ pinLabel: "Status",
219
+ resizeColumnId: "sync",
220
+ resizeLabel: "Widen Sync"
221
+ }, undefined, false, undefined, this),
222
+ emptyState: /* @__PURE__ */ jsxDEV2("div", {
223
+ className: "rounded-md border border-dashed p-8 text-center text-muted-foreground text-sm",
224
+ children: "No sync configurations found"
225
+ }, undefined, false, undefined, this)
226
+ }, undefined, false, undefined, this);
227
+ }
228
+ export {
229
+ SyncConfigsTable
230
+ };
@@ -0,0 +1,84 @@
1
+ // src/ui/tables/integration-table.shared.tsx
2
+ import { Button } from "@contractspec/lib.design-system";
3
+ import { Badge } from "@contractspec/lib.ui-kit-web/ui/badge";
4
+ import { HStack } from "@contractspec/lib.ui-kit-web/ui/stack";
5
+ import { jsxDEV } from "react/jsx-dev-runtime";
6
+ "use client";
7
+ var STATUS_VARIANTS = {
8
+ ACTIVE: "default",
9
+ CONNECTED: "default",
10
+ SUCCESS: "default",
11
+ PENDING: "secondary",
12
+ PAUSED: "secondary",
13
+ ERROR: "destructive",
14
+ DISCONNECTED: "outline"
15
+ };
16
+ function formatDateTime(value) {
17
+ return value ? value.toLocaleString() : "Never";
18
+ }
19
+ function formatJson(value) {
20
+ return value ? JSON.stringify(value, null, 2) : "No configuration";
21
+ }
22
+ function StatusBadge({ status }) {
23
+ return /* @__PURE__ */ jsxDEV(Badge, {
24
+ variant: STATUS_VARIANTS[status] ?? "outline",
25
+ children: status
26
+ }, undefined, false, undefined, this);
27
+ }
28
+ function IntegrationTableToolbar({
29
+ controller,
30
+ label,
31
+ toggleColumnId,
32
+ toggleVisibleLabel,
33
+ toggleHiddenLabel,
34
+ pinColumnId,
35
+ pinLabel,
36
+ resizeColumnId,
37
+ resizeLabel
38
+ }) {
39
+ const firstRow = controller.rows[0];
40
+ const toggleColumn = controller.columns.find((column) => column.id === toggleColumnId);
41
+ const pinColumn = controller.columns.find((column) => column.id === pinColumnId);
42
+ const resizeColumn = controller.columns.find((column) => column.id === resizeColumnId);
43
+ const pinTarget = pinColumn?.pinState === "left" ? false : "left";
44
+ return /* @__PURE__ */ jsxDEV(HStack, {
45
+ gap: "sm",
46
+ className: "flex-wrap",
47
+ children: [
48
+ /* @__PURE__ */ jsxDEV(Badge, {
49
+ variant: "outline",
50
+ children: label
51
+ }, undefined, false, undefined, this),
52
+ /* @__PURE__ */ jsxDEV(Button, {
53
+ variant: "outline",
54
+ size: "sm",
55
+ onPress: () => firstRow?.toggleExpanded?.(!firstRow?.isExpanded),
56
+ children: "Expand First Row"
57
+ }, undefined, false, undefined, this),
58
+ /* @__PURE__ */ jsxDEV(Button, {
59
+ variant: "outline",
60
+ size: "sm",
61
+ onPress: () => toggleColumn?.toggleVisibility?.(!toggleColumn?.visible),
62
+ children: toggleColumn?.visible ? toggleVisibleLabel : toggleHiddenLabel
63
+ }, undefined, false, undefined, this),
64
+ /* @__PURE__ */ jsxDEV(Button, {
65
+ variant: "outline",
66
+ size: "sm",
67
+ onPress: () => pinColumn?.pin?.(pinTarget),
68
+ children: pinColumn?.pinState === "left" ? `Unpin ${pinLabel}` : `Pin ${pinLabel}`
69
+ }, undefined, false, undefined, this),
70
+ /* @__PURE__ */ jsxDEV(Button, {
71
+ variant: "outline",
72
+ size: "sm",
73
+ onPress: () => resizeColumn?.resizeBy?.(40),
74
+ children: resizeLabel
75
+ }, undefined, false, undefined, this)
76
+ ]
77
+ }, undefined, true, undefined, this);
78
+ }
79
+ export {
80
+ formatJson,
81
+ formatDateTime,
82
+ StatusBadge,
83
+ IntegrationTableToolbar
84
+ };