@burdenoff/microfe-bigconsole 2026.812.2 → 2026.827.1

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 (40) hide show
  1. package/dist/bigconsole/components/builder/inspector/LayoutSection.js +71 -0
  2. package/dist/bigconsole/components/builder/inspector/LayoutSection.js.map +1 -0
  3. package/dist/bigconsole/components/builder/inspector/index.js +1 -0
  4. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +137 -121
  5. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  6. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js +204 -93
  7. package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js.map +1 -1
  8. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +259 -133
  9. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
  10. package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js +87 -39
  11. package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js.map +1 -1
  12. package/dist/bigconsole/components/datasink/DataSinkCard.js +88 -68
  13. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  14. package/dist/bigconsole/components/widgets/PropertiesPanel.js +213 -199
  15. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  16. package/dist/bigconsole/components/workflow/WorkflowCard.js +46 -27
  17. package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
  18. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +44 -47
  19. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
  20. package/dist/bigconsole/customWidget/proposalSource.js +31 -24
  21. package/dist/bigconsole/customWidget/proposalSource.js.map +1 -1
  22. package/dist/bigconsole/hooks/useDashboardOperations.js +74 -64
  23. package/dist/bigconsole/hooks/useDashboardOperations.js.map +1 -1
  24. package/dist/bigconsole/hooks/useDataSinkOperations.js +2 -2
  25. package/dist/bigconsole/hooks/useDataSinkOperations.js.map +1 -1
  26. package/dist/bigconsole/pages/DashboardBuilderPage.js +1 -1
  27. package/dist/bigconsole/pages/DashboardsPage.js +386 -316
  28. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  29. package/dist/bigconsole/pages/DataSinksPage.js +251 -206
  30. package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
  31. package/dist/bigconsole/pages/InsightsPage.js +646 -378
  32. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  33. package/dist/bigconsole/pages/WorkflowsPage.js +153 -108
  34. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  35. package/dist/bigconsole/utils/format.js +18 -0
  36. package/dist/bigconsole/utils/format.js.map +1 -0
  37. package/dist/bigconsole/utils/widgetPositioning.js +1 -1
  38. package/dist/generated/wspace-operations.js +1 -0
  39. package/dist/generated/wspace-operations.js.map +1 -1
  40. package/package.json +1 -1
@@ -1,128 +1,148 @@
1
1
  import { SECTION_FOCUS_RING as e } from "../common/sectionStyles.js";
2
2
  import "../common/index.js";
3
3
  import t from "./DataSinkStatusBadge.js";
4
- import { memo as n, useCallback as r } from "react";
5
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
6
- import { formatDistanceToNow as o } from "date-fns";
4
+ import { formatByteSize as n } from "../../utils/format.js";
5
+ import { memo as r, useCallback as i } from "react";
6
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
+ import { formatDistanceToNow as s } from "date-fns";
7
8
  //#region src/bigconsole/components/datasink/DataSinkCard.tsx
8
- var s = `inline-flex min-h-[var(--size-controlHeight-md)] items-center justify-center rounded-button px-3 py-1.5 text-xs font-medium motion-safe:transition-colors ${e}`, c = n(function({ dataSink: e, setupState: n, onView: c, onEdit: l, onRefresh: u, onExport: d, onDelete: f, onContinueSetup: p, canEdit: m = !0, canRefresh: h = !0, canDelete: g = !0 }) {
9
- let _ = r((t) => {
10
- t.stopPropagation(), c?.(e.id);
11
- }, [e.id, c]), v = r((t) => {
9
+ var c = `inline-flex min-h-[var(--size-controlHeight-md)] items-center justify-center rounded-button px-3 py-1.5 text-xs font-medium motion-safe:transition-colors ${e}`, l = r(function({ dataSink: e, setupState: r, onView: l, onEdit: u, onRefresh: d, onExport: f, onDelete: p, onContinueSetup: m, canEdit: h = !0, canRefresh: g = !0, canDelete: _ = !0 }) {
10
+ let v = i((t) => {
12
11
  t.stopPropagation(), l?.(e.id);
13
- }, [e.id, l]), y = r((t) => {
12
+ }, [e.id, l]), y = i((t) => {
14
13
  t.stopPropagation(), u?.(e.id);
15
- }, [e.id, u]), b = r((t) => {
14
+ }, [e.id, u]), b = i((t) => {
16
15
  t.stopPropagation(), d?.(e.id);
17
- }, [e.id, d]), x = r((t) => {
16
+ }, [e.id, d]), x = i((t) => {
18
17
  t.stopPropagation(), f?.(e.id);
19
- }, [e.id, f]), S = r((t) => {
18
+ }, [e.id, f]), S = i((t) => {
20
19
  t.stopPropagation(), p?.(e.id);
21
- }, [e.id, p]), C = (n ?? e.setupState) === "completed", w = e.lastRefreshedAt ? o(new Date(e.lastRefreshedAt), { addSuffix: !0 }) : "Never";
22
- return /* @__PURE__ */ a("article", {
20
+ }, [e.id, p]), C = i((t) => {
21
+ t.stopPropagation(), m?.(e.id);
22
+ }, [e.id, m]), w = (r ?? e.setupState) === "completed", T = e.lastRefreshedAt ? s(new Date(e.lastRefreshedAt), { addSuffix: !0 }) : "Never";
23
+ return /* @__PURE__ */ o("article", {
23
24
  className: "\n min-w-0\n cursor-pointer\n rounded-card\n border border-transparent\n bg-bg-sunken\n p-card-padding\n hover:border-[var(--color-action-primary-bg)]\n motion-safe:transition-colors\n ",
24
- onClick: _,
25
+ onClick: v,
25
26
  children: [
26
- /* @__PURE__ */ a("div", {
27
+ /* @__PURE__ */ o("div", {
27
28
  className: "mb-3 flex items-start justify-between gap-icon-gap",
28
- children: [/* @__PURE__ */ a("div", {
29
+ children: [/* @__PURE__ */ o("div", {
29
30
  className: "min-w-0 flex-1",
30
- children: [/* @__PURE__ */ i("h3", {
31
+ children: [/* @__PURE__ */ a("h3", {
31
32
  className: "truncate text-sm font-semibold text-text-primary",
32
33
  children: e.name || "Untitled data sink"
33
- }), /* @__PURE__ */ i("p", {
34
+ }), /* @__PURE__ */ a("p", {
34
35
  className: "mt-0.5 truncate font-mono text-xs text-text-secondary",
35
36
  children: e.key
36
37
  })]
37
- }), /* @__PURE__ */ i(t, {
38
+ }), /* @__PURE__ */ a(t, {
38
39
  status: e.status,
39
40
  size: "sm"
40
41
  })]
41
42
  }),
42
- e.description && /* @__PURE__ */ i("p", {
43
+ e.description && /* @__PURE__ */ a("p", {
43
44
  className: "mb-3 line-clamp-2 text-xs text-text-secondary",
44
45
  children: e.description
45
46
  }),
46
- /* @__PURE__ */ a("div", {
47
+ /* @__PURE__ */ o("div", {
47
48
  className: "mb-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary",
48
- children: [/* @__PURE__ */ a("span", {
49
- className: "flex items-center gap-1",
50
- children: [/* @__PURE__ */ i("svg", {
51
- className: "w-3.5 h-3.5",
52
- fill: "none",
53
- stroke: "currentColor",
54
- viewBox: "0 0 24 24",
55
- children: /* @__PURE__ */ i("path", {
56
- strokeLinecap: "round",
57
- strokeLinejoin: "round",
58
- strokeWidth: 2,
59
- d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
60
- })
61
- }), w]
62
- }), e.linkedWorkflowCount !== void 0 && e.linkedWorkflowCount > 0 && /* @__PURE__ */ a("span", {
63
- className: "flex items-center gap-1",
64
- children: [
65
- /* @__PURE__ */ i("svg", {
49
+ children: [
50
+ /* @__PURE__ */ o("span", {
51
+ className: "flex items-center gap-1",
52
+ children: [/* @__PURE__ */ a("svg", {
66
53
  className: "w-3.5 h-3.5",
67
54
  fill: "none",
68
55
  stroke: "currentColor",
69
56
  viewBox: "0 0 24 24",
70
- children: /* @__PURE__ */ i("path", {
57
+ children: /* @__PURE__ */ a("path", {
71
58
  strokeLinecap: "round",
72
59
  strokeLinejoin: "round",
73
60
  strokeWidth: 2,
74
- d: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
61
+ d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
75
62
  })
76
- }),
77
- e.linkedWorkflowCount,
78
- " workflow",
79
- e.linkedWorkflowCount === 1 ? "" : "s"
80
- ]
81
- })]
63
+ }), T]
64
+ }),
65
+ /* @__PURE__ */ o("span", {
66
+ className: "flex items-center gap-1",
67
+ title: "Stored payload size",
68
+ children: [/* @__PURE__ */ a("svg", {
69
+ className: "w-3.5 h-3.5",
70
+ fill: "none",
71
+ stroke: "currentColor",
72
+ viewBox: "0 0 24 24",
73
+ children: /* @__PURE__ */ a("path", {
74
+ strokeLinecap: "round",
75
+ strokeLinejoin: "round",
76
+ strokeWidth: 2,
77
+ d: "M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4"
78
+ })
79
+ }), n(e.sizeBytes)]
80
+ }),
81
+ e.linkedWorkflowCount !== void 0 && e.linkedWorkflowCount > 0 && /* @__PURE__ */ o("span", {
82
+ className: "flex items-center gap-1",
83
+ children: [
84
+ /* @__PURE__ */ a("svg", {
85
+ className: "w-3.5 h-3.5",
86
+ fill: "none",
87
+ stroke: "currentColor",
88
+ viewBox: "0 0 24 24",
89
+ children: /* @__PURE__ */ a("path", {
90
+ strokeLinecap: "round",
91
+ strokeLinejoin: "round",
92
+ strokeWidth: 2,
93
+ d: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
94
+ })
95
+ }),
96
+ e.linkedWorkflowCount,
97
+ " workflow",
98
+ e.linkedWorkflowCount === 1 ? "" : "s"
99
+ ]
100
+ })
101
+ ]
82
102
  }),
83
- !C && /* @__PURE__ */ a("div", {
103
+ !w && /* @__PURE__ */ o("div", {
84
104
  className: "mb-3 flex items-center justify-between gap-icon-gap rounded-input border border-[var(--color-status-warning-border)] bg-[var(--color-status-warning-bgSubtle)] p-2",
85
- children: [/* @__PURE__ */ i("span", {
105
+ children: [/* @__PURE__ */ a("span", {
86
106
  className: "text-xs text-[var(--color-status-warning-text)]",
87
107
  children: "Setup incomplete"
88
- }), /* @__PURE__ */ i("button", {
108
+ }), /* @__PURE__ */ a("button", {
89
109
  type: "button",
90
- onClick: S,
110
+ onClick: C,
91
111
  className: "rounded-button px-1 text-xs font-medium text-text-link hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface",
92
112
  children: "Continue"
93
113
  })]
94
114
  }),
95
- /* @__PURE__ */ a("div", {
115
+ /* @__PURE__ */ o("div", {
96
116
  className: "flex flex-wrap items-center gap-2 border-t border-[var(--color-border-subtle)] pt-2",
97
117
  children: [
98
- /* @__PURE__ */ i("button", {
118
+ /* @__PURE__ */ a("button", {
99
119
  type: "button",
100
- onClick: _,
101
- className: `${s} flex-1 bg-bg-surface text-text-primary hover:bg-bg-elevated`,
120
+ onClick: v,
121
+ className: `${c} flex-1 bg-bg-surface text-text-primary hover:bg-bg-elevated`,
102
122
  children: "View"
103
123
  }),
104
- m && /* @__PURE__ */ i("button", {
124
+ h && /* @__PURE__ */ a("button", {
105
125
  type: "button",
106
- onClick: v,
107
- className: `${s} text-text-secondary hover:bg-bg-surface hover:text-text-primary`,
126
+ onClick: y,
127
+ className: `${c} text-text-secondary hover:bg-bg-surface hover:text-text-primary`,
108
128
  children: "Edit"
109
129
  }),
110
- h && /* @__PURE__ */ i("button", {
130
+ g && /* @__PURE__ */ a("button", {
111
131
  type: "button",
112
- onClick: y,
113
- className: `${s} text-text-secondary hover:bg-bg-surface hover:text-text-primary`,
132
+ onClick: b,
133
+ className: `${c} text-text-secondary hover:bg-bg-surface hover:text-text-primary`,
114
134
  children: "Refresh"
115
135
  }),
116
- d && /* @__PURE__ */ i("button", {
136
+ f && /* @__PURE__ */ a("button", {
117
137
  type: "button",
118
- onClick: b,
119
- className: `${s} text-text-secondary hover:bg-bg-surface hover:text-text-primary`,
138
+ onClick: x,
139
+ className: `${c} text-text-secondary hover:bg-bg-surface hover:text-text-primary`,
120
140
  children: "Export"
121
141
  }),
122
- g && /* @__PURE__ */ i("button", {
142
+ _ && /* @__PURE__ */ a("button", {
123
143
  type: "button",
124
- onClick: x,
125
- className: `${s} text-status-error-text hover:bg-[var(--color-status-error-bgSubtle)]`,
144
+ onClick: S,
145
+ className: `${c} text-status-error-text hover:bg-[var(--color-status-error-bgSubtle)]`,
126
146
  children: "Delete"
127
147
  })
128
148
  ]
@@ -131,6 +151,6 @@ var s = `inline-flex min-h-[var(--size-controlHeight-md)] items-center justify-c
131
151
  });
132
152
  });
133
153
  //#endregion
134
- export { c as default };
154
+ export { l as default };
135
155
 
136
156
  //# sourceMappingURL=DataSinkCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataSinkCard.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/DataSinkCard.tsx"],"sourcesContent":["/**\n * DataSink Card\n *\n * Card component for displaying DataSink information in a list/grid view.\n */\n\nimport { memo, useCallback } from 'react';\nimport { formatDistanceToNow } from 'date-fns';\nimport { DataSinkStatusBadge } from './DataSinkStatusBadge';\nimport { SECTION_FOCUS_RING } from '../common';\nimport type { DataSink, DataSinkSetupState } from '../../types';\n\n/**\n * Shared class recipe for the card's five action buttons. `min-h-[var(--size-controlHeight-md)]`\n * keeps every one at the 40px touch minimum once the row wraps on mobile.\n */\nconst CARD_ACTION =\n `inline-flex min-h-[var(--size-controlHeight-md)] items-center justify-center rounded-button px-3 py-1.5 text-xs font-medium motion-safe:transition-colors ${SECTION_FOCUS_RING}` as const;\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface DataSinkCardProps {\n /** DataSink data */\n dataSink: DataSink;\n /** Setup state override */\n setupState?: DataSinkSetupState;\n /** Callback when view is clicked */\n onView?: (id: string) => void;\n /** Callback when edit is clicked */\n onEdit?: (id: string) => void;\n /** Callback when refresh is clicked */\n onRefresh?: (id: string) => void;\n /** Callback when export is clicked */\n onExport?: (id: string) => void;\n /** Callback when delete is clicked */\n onDelete?: (id: string) => void;\n /** Callback to continue setup */\n onContinueSetup?: (id: string) => void;\n /** Whether the current actor may edit this DataSink (gates the Edit action). Defaults to true. */\n canEdit?: boolean;\n /** Whether the current actor may refresh this DataSink (gates the Refresh action). Defaults to true. */\n canRefresh?: boolean;\n /** Whether the current actor may delete this DataSink (gates the Delete action). Defaults to true. */\n canDelete?: boolean;\n}\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const DataSinkCard = memo(function DataSinkCard({\n dataSink,\n setupState,\n onView,\n onEdit,\n onRefresh,\n onExport,\n onDelete,\n onContinueSetup,\n canEdit = true,\n canRefresh = true,\n canDelete = true,\n}: DataSinkCardProps) {\n // Event handlers\n const handleView = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onView?.(dataSink.id);\n },\n [dataSink.id, onView]\n );\n\n const handleEdit = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onEdit?.(dataSink.id);\n },\n [dataSink.id, onEdit]\n );\n\n const handleRefresh = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onRefresh?.(dataSink.id);\n },\n [dataSink.id, onRefresh]\n );\n\n const handleExport = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onExport?.(dataSink.id);\n },\n [dataSink.id, onExport]\n );\n\n const handleDelete = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onDelete?.(dataSink.id);\n },\n [dataSink.id, onDelete]\n );\n\n const handleContinueSetup = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onContinueSetup?.(dataSink.id);\n },\n [dataSink.id, onContinueSetup]\n );\n\n const currentSetupState = setupState ?? dataSink.setupState;\n const isSetupComplete = currentSetupState === 'completed';\n\n // Format last refreshed time\n const lastRefreshedText = dataSink.lastRefreshedAt\n ? formatDistanceToNow(new Date(dataSink.lastRefreshedAt), { addSuffix: true })\n : 'Never';\n\n return (\n // A card is a tile inside the page's `primary` results section, so it steps\n // down to the `muted` recipe (recessed surface, transparent border) instead\n // of competing with the panel that contains it.\n <article\n className={`\n min-w-0\n cursor-pointer\n rounded-card\n border border-transparent\n bg-bg-sunken\n p-card-padding\n hover:border-[var(--color-action-primary-bg)]\n motion-safe:transition-colors\n `}\n onClick={handleView}\n >\n {/* Identity */}\n <div className=\"mb-3 flex items-start justify-between gap-icon-gap\">\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-sm font-semibold text-text-primary\">{dataSink.name || 'Untitled data sink'}</h3>\n <p className=\"mt-0.5 truncate font-mono text-xs text-text-secondary\">{dataSink.key}</p>\n </div>\n <DataSinkStatusBadge status={dataSink.status} size=\"sm\" />\n </div>\n\n {/* Description */}\n {dataSink.description && <p className=\"mb-3 line-clamp-2 text-xs text-text-secondary\">{dataSink.description}</p>}\n\n {/* Stats */}\n <div className=\"mb-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <svg className=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n {lastRefreshedText}\n </span>\n {dataSink.linkedWorkflowCount !== undefined && dataSink.linkedWorkflowCount > 0 && (\n <span className=\"flex items-center gap-1\">\n <svg className=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"\n />\n </svg>\n {dataSink.linkedWorkflowCount} workflow{dataSink.linkedWorkflowCount !== 1 ? 's' : ''}\n </span>\n )}\n </div>\n\n {/* Setup state — a warning strip, so it carries the warning tone. */}\n {!isSetupComplete && (\n <div className=\"mb-3 flex items-center justify-between gap-icon-gap rounded-input border border-[var(--color-status-warning-border)] bg-[var(--color-status-warning-bgSubtle)] p-2\">\n <span className=\"text-xs text-[var(--color-status-warning-text)]\">Setup incomplete</span>\n <button\n type=\"button\"\n onClick={handleContinueSetup}\n className={`rounded-button px-1 text-xs font-medium text-text-link hover:underline ${SECTION_FOCUS_RING}`}\n >\n Continue\n </button>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex flex-wrap items-center gap-2 border-t border-[var(--color-border-subtle)] pt-2\">\n <button\n type=\"button\"\n onClick={handleView}\n className={`${CARD_ACTION} flex-1 bg-bg-surface text-text-primary hover:bg-bg-elevated`}\n >\n View\n </button>\n {canEdit && (\n <button\n type=\"button\"\n onClick={handleEdit}\n className={`${CARD_ACTION} text-text-secondary hover:bg-bg-surface hover:text-text-primary`}\n >\n Edit\n </button>\n )}\n {canRefresh && (\n <button\n type=\"button\"\n onClick={handleRefresh}\n className={`${CARD_ACTION} text-text-secondary hover:bg-bg-surface hover:text-text-primary`}\n >\n Refresh\n </button>\n )}\n {onExport && (\n <button\n type=\"button\"\n onClick={handleExport}\n className={`${CARD_ACTION} text-text-secondary hover:bg-bg-surface hover:text-text-primary`}\n >\n Export\n </button>\n )}\n {canDelete && (\n <button\n type=\"button\"\n onClick={handleDelete}\n className={`${CARD_ACTION} text-status-error-text hover:bg-[var(--color-status-error-bgSubtle)]`}\n >\n Delete\n </button>\n )}\n </div>\n </article>\n );\n});\n\nexport default DataSinkCard;\n"],"mappings":"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"}
1
+ {"version":3,"file":"DataSinkCard.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/DataSinkCard.tsx"],"sourcesContent":["/**\n * DataSink Card\n *\n * Card component for displaying DataSink information in a list/grid view.\n */\n\nimport { memo, useCallback } from 'react';\nimport { formatDistanceToNow } from 'date-fns';\nimport { DataSinkStatusBadge } from './DataSinkStatusBadge';\nimport { SECTION_FOCUS_RING } from '../common';\nimport { formatByteSize } from '../../utils';\nimport type { DataSink, DataSinkSetupState } from '../../types';\n\n/**\n * Shared class recipe for the card's five action buttons. `min-h-[var(--size-controlHeight-md)]`\n * keeps every one at the 40px touch minimum once the row wraps on mobile.\n */\nconst CARD_ACTION =\n `inline-flex min-h-[var(--size-controlHeight-md)] items-center justify-center rounded-button px-3 py-1.5 text-xs font-medium motion-safe:transition-colors ${SECTION_FOCUS_RING}` as const;\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface DataSinkCardProps {\n /** DataSink data */\n dataSink: DataSink;\n /** Setup state override */\n setupState?: DataSinkSetupState;\n /** Callback when view is clicked */\n onView?: (id: string) => void;\n /** Callback when edit is clicked */\n onEdit?: (id: string) => void;\n /** Callback when refresh is clicked */\n onRefresh?: (id: string) => void;\n /** Callback when export is clicked */\n onExport?: (id: string) => void;\n /** Callback when delete is clicked */\n onDelete?: (id: string) => void;\n /** Callback to continue setup */\n onContinueSetup?: (id: string) => void;\n /** Whether the current actor may edit this DataSink (gates the Edit action). Defaults to true. */\n canEdit?: boolean;\n /** Whether the current actor may refresh this DataSink (gates the Refresh action). Defaults to true. */\n canRefresh?: boolean;\n /** Whether the current actor may delete this DataSink (gates the Delete action). Defaults to true. */\n canDelete?: boolean;\n}\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const DataSinkCard = memo(function DataSinkCard({\n dataSink,\n setupState,\n onView,\n onEdit,\n onRefresh,\n onExport,\n onDelete,\n onContinueSetup,\n canEdit = true,\n canRefresh = true,\n canDelete = true,\n}: DataSinkCardProps) {\n // Event handlers\n const handleView = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onView?.(dataSink.id);\n },\n [dataSink.id, onView]\n );\n\n const handleEdit = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onEdit?.(dataSink.id);\n },\n [dataSink.id, onEdit]\n );\n\n const handleRefresh = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onRefresh?.(dataSink.id);\n },\n [dataSink.id, onRefresh]\n );\n\n const handleExport = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onExport?.(dataSink.id);\n },\n [dataSink.id, onExport]\n );\n\n const handleDelete = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onDelete?.(dataSink.id);\n },\n [dataSink.id, onDelete]\n );\n\n const handleContinueSetup = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onContinueSetup?.(dataSink.id);\n },\n [dataSink.id, onContinueSetup]\n );\n\n const currentSetupState = setupState ?? dataSink.setupState;\n const isSetupComplete = currentSetupState === 'completed';\n\n // Format last refreshed time\n const lastRefreshedText = dataSink.lastRefreshedAt\n ? formatDistanceToNow(new Date(dataSink.lastRefreshedAt), { addSuffix: true })\n : 'Never';\n\n return (\n // A card is a tile inside the page's `primary` results section, so it steps\n // down to the `muted` recipe (recessed surface, transparent border) instead\n // of competing with the panel that contains it.\n <article\n className={`\n min-w-0\n cursor-pointer\n rounded-card\n border border-transparent\n bg-bg-sunken\n p-card-padding\n hover:border-[var(--color-action-primary-bg)]\n motion-safe:transition-colors\n `}\n onClick={handleView}\n >\n {/* Identity */}\n <div className=\"mb-3 flex items-start justify-between gap-icon-gap\">\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-sm font-semibold text-text-primary\">{dataSink.name || 'Untitled data sink'}</h3>\n <p className=\"mt-0.5 truncate font-mono text-xs text-text-secondary\">{dataSink.key}</p>\n </div>\n <DataSinkStatusBadge status={dataSink.status} size=\"sm\" />\n </div>\n\n {/* Description */}\n {dataSink.description && <p className=\"mb-3 line-clamp-2 text-xs text-text-secondary\">{dataSink.description}</p>}\n\n {/* Stats */}\n <div className=\"mb-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <svg className=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n {lastRefreshedText}\n </span>\n {/* `sizeBytes` ships in DataSinkListItem on every list query but was\n never shown here — it is how you tell a populated sink from an empty\n one without opening it. */}\n <span className=\"flex items-center gap-1\" title=\"Stored payload size\">\n <svg className=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4\"\n />\n </svg>\n {formatByteSize(dataSink.sizeBytes)}\n </span>\n {dataSink.linkedWorkflowCount !== undefined && dataSink.linkedWorkflowCount > 0 && (\n <span className=\"flex items-center gap-1\">\n <svg className=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"\n />\n </svg>\n {dataSink.linkedWorkflowCount} workflow{dataSink.linkedWorkflowCount !== 1 ? 's' : ''}\n </span>\n )}\n </div>\n\n {/* Setup state — a warning strip, so it carries the warning tone. */}\n {!isSetupComplete && (\n <div className=\"mb-3 flex items-center justify-between gap-icon-gap rounded-input border border-[var(--color-status-warning-border)] bg-[var(--color-status-warning-bgSubtle)] p-2\">\n <span className=\"text-xs text-[var(--color-status-warning-text)]\">Setup incomplete</span>\n <button\n type=\"button\"\n onClick={handleContinueSetup}\n className={`rounded-button px-1 text-xs font-medium text-text-link hover:underline ${SECTION_FOCUS_RING}`}\n >\n Continue\n </button>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex flex-wrap items-center gap-2 border-t border-[var(--color-border-subtle)] pt-2\">\n <button\n type=\"button\"\n onClick={handleView}\n className={`${CARD_ACTION} flex-1 bg-bg-surface text-text-primary hover:bg-bg-elevated`}\n >\n View\n </button>\n {canEdit && (\n <button\n type=\"button\"\n onClick={handleEdit}\n className={`${CARD_ACTION} text-text-secondary hover:bg-bg-surface hover:text-text-primary`}\n >\n Edit\n </button>\n )}\n {canRefresh && (\n <button\n type=\"button\"\n onClick={handleRefresh}\n className={`${CARD_ACTION} text-text-secondary hover:bg-bg-surface hover:text-text-primary`}\n >\n Refresh\n </button>\n )}\n {onExport && (\n <button\n type=\"button\"\n onClick={handleExport}\n className={`${CARD_ACTION} text-text-secondary hover:bg-bg-surface hover:text-text-primary`}\n >\n Export\n </button>\n )}\n {canDelete && (\n <button\n type=\"button\"\n onClick={handleDelete}\n className={`${CARD_ACTION} text-status-error-text hover:bg-[var(--color-status-error-bgSubtle)]`}\n >\n Delete\n </button>\n )}\n </div>\n </article>\n );\n});\n\nexport default DataSinkCard;\n"],"mappings":"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"}