@burdenoff/microfe-bigconsole 2026.805.2 → 2026.805.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +109 -113
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +115 -113
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +71 -62
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +90 -89
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +56 -54
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +126 -125
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +151 -150
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +77 -76
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +97 -96
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +172 -191
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +75 -83
- package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +151 -154
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +181 -190
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
- package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -0
- package/dist/bigconsole/components/dashboard/WidgetPalette.js +110 -108
- package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +102 -103
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +36 -41
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +38 -37
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +113 -117
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +182 -197
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +166 -168
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/DataSinkSelector.js +87 -86
- package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ImportParserDialog.js +196 -211
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +130 -128
- package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +66 -63
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +95 -91
- package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +222 -215
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +149 -145
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +504 -470
- package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +44 -47
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js +143 -142
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +101 -88
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +135 -134
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
- package/dist/bigconsole/components/widgets/form/FormWidget.js +167 -159
- package/dist/bigconsole/components/widgets/form/FormWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +69 -68
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +64 -72
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +60 -59
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListConfig.js +57 -56
- package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +70 -69
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +35 -34
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +20 -19
- package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js.map +1 -1
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +178 -177
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +76 -75
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableConfig.js +183 -168
- package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +187 -180
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +40 -38
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +150 -148
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
- package/dist/bigconsole/pages/DashboardBuilderPage.js +181 -176
- package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js +196 -192
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +223 -219
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataParsersPage.js +167 -170
- package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +204 -189
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +175 -169
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSourcesPage.js +8 -7
- package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
- package/dist/bigconsole/pages/InsightsPage.js +238 -208
- package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.js +464 -412
- package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js +92 -90
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +221 -194
- package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineViewPage.js +181 -184
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelinesPage.js +128 -127
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/SettingsPage.js +177 -172
- package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
- package/dist/bigconsole/pages/WidgetDemoPage.js +121 -83
- package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowViewPage.js +199 -193
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +129 -128
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +111 -109
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +127 -126
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js +103 -103
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,126 +1,118 @@
|
|
|
1
|
-
import { memo as e, useCallback as t } from "react";
|
|
2
|
-
import {
|
|
1
|
+
import { memo as e, useCallback as t, useMemo as n } from "react";
|
|
2
|
+
import { useI18n as r } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
3
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
3
4
|
//#region src/bigconsole/components/widgets/heatmap/HeatmapConfig.tsx
|
|
4
|
-
var
|
|
5
|
-
{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
var o = "\n w-full px-3 py-2\n text-sm text-text-primary\n bg-bg-surface\n border border-border-default\n rounded-md\n focus:outline-none focus:ring-2 focus:ring-action-primary-bg\n", s = e(function({ config: e, onChange: s }) {
|
|
6
|
+
let { t: c } = r(), l = n(() => [
|
|
7
|
+
{
|
|
8
|
+
value: "blue",
|
|
9
|
+
label: c("bigconsole.widget.config.heatmap.colorScheme.blue", "Blue")
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
value: "green",
|
|
13
|
+
label: c("bigconsole.widget.config.heatmap.colorScheme.green", "Green")
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
value: "red",
|
|
17
|
+
label: c("bigconsole.widget.config.heatmap.colorScheme.red", "Red")
|
|
18
|
+
}
|
|
19
|
+
], [c]), u = t((t, n) => {
|
|
20
|
+
s({
|
|
20
21
|
...e,
|
|
21
22
|
[t]: n
|
|
22
23
|
});
|
|
23
|
-
}, [e,
|
|
24
|
-
return /* @__PURE__ */
|
|
24
|
+
}, [e, s]);
|
|
25
|
+
return /* @__PURE__ */ a("div", {
|
|
25
26
|
className: "space-y-4",
|
|
26
27
|
children: [
|
|
27
|
-
/* @__PURE__ */
|
|
28
|
+
/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("label", {
|
|
28
29
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
29
|
-
children: "X-Axis Field"
|
|
30
|
-
}), /* @__PURE__ */
|
|
30
|
+
children: c("bigconsole.widget.config.heatmap.xAxisFieldLabel", "X-Axis Field")
|
|
31
|
+
}), /* @__PURE__ */ i("input", {
|
|
31
32
|
type: "text",
|
|
32
33
|
value: e.xAxisField || "",
|
|
33
|
-
onChange: (e) =>
|
|
34
|
-
placeholder: "e.g., hour, column",
|
|
35
|
-
className:
|
|
34
|
+
onChange: (e) => u("xAxisField", e.target.value),
|
|
35
|
+
placeholder: c("bigconsole.widget.config.heatmap.xAxisFieldPlaceholder", "e.g., hour, column"),
|
|
36
|
+
className: o
|
|
36
37
|
})] }),
|
|
37
|
-
/* @__PURE__ */
|
|
38
|
+
/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("label", {
|
|
38
39
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
39
|
-
children: "Y-Axis Field"
|
|
40
|
-
}), /* @__PURE__ */
|
|
40
|
+
children: c("bigconsole.widget.config.heatmap.yAxisFieldLabel", "Y-Axis Field")
|
|
41
|
+
}), /* @__PURE__ */ i("input", {
|
|
41
42
|
type: "text",
|
|
42
43
|
value: e.yAxisField || "",
|
|
43
|
-
onChange: (e) =>
|
|
44
|
-
placeholder: "e.g., day, row",
|
|
45
|
-
className:
|
|
44
|
+
onChange: (e) => u("yAxisField", e.target.value),
|
|
45
|
+
placeholder: c("bigconsole.widget.config.heatmap.yAxisFieldPlaceholder", "e.g., day, row"),
|
|
46
|
+
className: o
|
|
46
47
|
})] }),
|
|
47
|
-
/* @__PURE__ */
|
|
48
|
-
/* @__PURE__ */
|
|
48
|
+
/* @__PURE__ */ a("div", { children: [
|
|
49
|
+
/* @__PURE__ */ i("label", {
|
|
49
50
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
50
|
-
children: "Value Field"
|
|
51
|
+
children: c("bigconsole.widget.config.heatmap.valueFieldLabel", "Value Field")
|
|
51
52
|
}),
|
|
52
|
-
/* @__PURE__ */
|
|
53
|
+
/* @__PURE__ */ i("input", {
|
|
53
54
|
type: "text",
|
|
54
55
|
value: e.valueField || "",
|
|
55
|
-
onChange: (e) =>
|
|
56
|
-
placeholder: "e.g., tickets, count",
|
|
57
|
-
className:
|
|
56
|
+
onChange: (e) => u("valueField", e.target.value),
|
|
57
|
+
placeholder: c("bigconsole.widget.config.heatmap.valueFieldPlaceholder", "e.g., tickets, count"),
|
|
58
|
+
className: o
|
|
58
59
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ i("p", {
|
|
60
61
|
className: "mt-1 text-xs text-text-secondary",
|
|
61
|
-
children:
|
|
62
|
-
"Left empty, the widget reads the parser's ",
|
|
63
|
-
/* @__PURE__ */ n("code", { children: "rows" }),
|
|
64
|
-
" / ",
|
|
65
|
-
/* @__PURE__ */ n("code", { children: "columns" }),
|
|
66
|
-
" / ",
|
|
67
|
-
/* @__PURE__ */ n("code", { children: "cells" }),
|
|
68
|
-
" ",
|
|
69
|
-
"output directly."
|
|
70
|
-
]
|
|
62
|
+
children: c("bigconsole.widget.config.heatmap.valueFieldHelp", "Left empty, the widget reads the parser's rows / columns / cells output directly.")
|
|
71
63
|
})
|
|
72
64
|
] }),
|
|
73
|
-
/* @__PURE__ */
|
|
65
|
+
/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("label", {
|
|
74
66
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
75
|
-
children: "Color Scheme"
|
|
76
|
-
}), /* @__PURE__ */
|
|
67
|
+
children: c("bigconsole.widget.config.heatmap.colorSchemeLabel", "Color Scheme")
|
|
68
|
+
}), /* @__PURE__ */ i("select", {
|
|
77
69
|
value: e.colorScheme || "blue",
|
|
78
|
-
onChange: (e) =>
|
|
79
|
-
className:
|
|
80
|
-
children:
|
|
70
|
+
onChange: (e) => u("colorScheme", e.target.value),
|
|
71
|
+
className: o,
|
|
72
|
+
children: l.map((e) => /* @__PURE__ */ i("option", {
|
|
81
73
|
value: e.value,
|
|
82
74
|
children: e.label
|
|
83
75
|
}, e.value))
|
|
84
76
|
})] }),
|
|
85
|
-
/* @__PURE__ */
|
|
77
|
+
/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("label", {
|
|
86
78
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
87
|
-
children: "Decimal Places"
|
|
88
|
-
}), /* @__PURE__ */
|
|
79
|
+
children: c("bigconsole.widget.config.heatmap.decimalPlacesLabel", "Decimal Places")
|
|
80
|
+
}), /* @__PURE__ */ i("input", {
|
|
89
81
|
type: "number",
|
|
90
82
|
min: 0,
|
|
91
83
|
max: 6,
|
|
92
84
|
value: e.decimals ?? 0,
|
|
93
|
-
onChange: (e) =>
|
|
94
|
-
className:
|
|
85
|
+
onChange: (e) => u("decimals", Number(e.target.value)),
|
|
86
|
+
className: o
|
|
95
87
|
})] }),
|
|
96
|
-
/* @__PURE__ */
|
|
88
|
+
/* @__PURE__ */ a("label", {
|
|
97
89
|
className: "flex items-center gap-3",
|
|
98
|
-
children: [/* @__PURE__ */
|
|
90
|
+
children: [/* @__PURE__ */ i("input", {
|
|
99
91
|
type: "checkbox",
|
|
100
92
|
checked: e.showValues !== !1,
|
|
101
|
-
onChange: (e) =>
|
|
93
|
+
onChange: (e) => u("showValues", e.target.checked),
|
|
102
94
|
className: "\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n "
|
|
103
|
-
}), /* @__PURE__ */
|
|
95
|
+
}), /* @__PURE__ */ i("span", {
|
|
104
96
|
className: "text-sm text-text-primary",
|
|
105
|
-
children: "Show cell values"
|
|
97
|
+
children: c("bigconsole.widget.config.heatmap.showValues", "Show cell values")
|
|
106
98
|
})]
|
|
107
99
|
}),
|
|
108
|
-
/* @__PURE__ */
|
|
100
|
+
/* @__PURE__ */ a("label", {
|
|
109
101
|
className: "flex items-center gap-3",
|
|
110
|
-
children: [/* @__PURE__ */
|
|
102
|
+
children: [/* @__PURE__ */ i("input", {
|
|
111
103
|
type: "checkbox",
|
|
112
104
|
checked: e.showLegend !== !1,
|
|
113
|
-
onChange: (e) =>
|
|
105
|
+
onChange: (e) => u("showLegend", e.target.checked),
|
|
114
106
|
className: "\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n "
|
|
115
|
-
}), /* @__PURE__ */
|
|
107
|
+
}), /* @__PURE__ */ i("span", {
|
|
116
108
|
className: "text-sm text-text-primary",
|
|
117
|
-
children: "Show color legend"
|
|
109
|
+
children: c("bigconsole.widget.config.heatmap.showLegend", "Show color legend")
|
|
118
110
|
})]
|
|
119
111
|
})
|
|
120
112
|
]
|
|
121
113
|
});
|
|
122
114
|
});
|
|
123
115
|
//#endregion
|
|
124
|
-
export {
|
|
116
|
+
export { s as default };
|
|
125
117
|
|
|
126
118
|
//# sourceMappingURL=HeatmapConfig.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeatmapConfig.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/heatmap/HeatmapConfig.tsx"],"sourcesContent":["/**\n * HeatmapConfig Component\n *\n * Configuration panel for Heatmap widgets.\n */\n\nimport { type FC, memo, useCallback } from 'react';\nimport type { HeatmapConfig as ConfigType } from '../../../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface HeatmapConfigProps {\n /** Current configuration */\n config: ConfigType;\n /** Callback when config changes */\n onChange: (config: ConfigType) => void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst
|
|
1
|
+
{"version":3,"file":"HeatmapConfig.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/heatmap/HeatmapConfig.tsx"],"sourcesContent":["/**\n * HeatmapConfig Component\n *\n * Configuration panel for Heatmap widgets.\n */\n\nimport { type FC, memo, useCallback, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { HeatmapConfig as ConfigType } from '../../../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface HeatmapConfigProps {\n /** Current configuration */\n config: ConfigType;\n /** Callback when config changes */\n onChange: (config: ConfigType) => void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst FIELD_CLASSES = `\n w-full px-3 py-2\n text-sm text-text-primary\n bg-bg-surface\n border border-border-default\n rounded-md\n focus:outline-none focus:ring-2 focus:ring-action-primary-bg\n`;\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const HeatmapConfig: FC<HeatmapConfigProps> = memo(function HeatmapConfig({ config, onChange }) {\n const { t } = useI18n();\n\n const COLOR_SCHEMES = useMemo(\n () => [\n { value: 'blue', label: t('bigconsole.widget.config.heatmap.colorScheme.blue', 'Blue') },\n { value: 'green', label: t('bigconsole.widget.config.heatmap.colorScheme.green', 'Green') },\n { value: 'red', label: t('bigconsole.widget.config.heatmap.colorScheme.red', 'Red') },\n ],\n [t]\n );\n\n const handleChange = useCallback(\n <K extends keyof ConfigType>(key: K, value: ConfigType[K]) => {\n onChange({ ...config, [key]: value });\n },\n [config, onChange]\n );\n\n return (\n <div className=\"space-y-4\">\n {/* Axis + value fields */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {t('bigconsole.widget.config.heatmap.xAxisFieldLabel', 'X-Axis Field')}\n </label>\n <input\n type=\"text\"\n value={config.xAxisField || ''}\n onChange={(e) => handleChange('xAxisField', e.target.value)}\n placeholder={t('bigconsole.widget.config.heatmap.xAxisFieldPlaceholder', 'e.g., hour, column')}\n className={FIELD_CLASSES}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {t('bigconsole.widget.config.heatmap.yAxisFieldLabel', 'Y-Axis Field')}\n </label>\n <input\n type=\"text\"\n value={config.yAxisField || ''}\n onChange={(e) => handleChange('yAxisField', e.target.value)}\n placeholder={t('bigconsole.widget.config.heatmap.yAxisFieldPlaceholder', 'e.g., day, row')}\n className={FIELD_CLASSES}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {t('bigconsole.widget.config.heatmap.valueFieldLabel', 'Value Field')}\n </label>\n <input\n type=\"text\"\n value={config.valueField || ''}\n onChange={(e) => handleChange('valueField', e.target.value)}\n placeholder={t('bigconsole.widget.config.heatmap.valueFieldPlaceholder', 'e.g., tickets, count')}\n className={FIELD_CLASSES}\n />\n <p className=\"mt-1 text-xs text-text-secondary\">\n {t(\n 'bigconsole.widget.config.heatmap.valueFieldHelp',\n \"Left empty, the widget reads the parser's rows / columns / cells output directly.\"\n )}\n </p>\n </div>\n\n {/* Color scheme */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {t('bigconsole.widget.config.heatmap.colorSchemeLabel', 'Color Scheme')}\n </label>\n <select\n value={config.colorScheme || 'blue'}\n onChange={(e) => handleChange('colorScheme', e.target.value)}\n className={FIELD_CLASSES}\n >\n {COLOR_SCHEMES.map((scheme) => (\n <option key={scheme.value} value={scheme.value}>\n {scheme.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Decimals */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {t('bigconsole.widget.config.heatmap.decimalPlacesLabel', 'Decimal Places')}\n </label>\n <input\n type=\"number\"\n min={0}\n max={6}\n value={config.decimals ?? 0}\n onChange={(e) => handleChange('decimals', Number(e.target.value))}\n className={FIELD_CLASSES}\n />\n </div>\n\n {/* Toggles */}\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.showValues !== false}\n onChange={(e) => handleChange('showValues', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">\n {t('bigconsole.widget.config.heatmap.showValues', 'Show cell values')}\n </span>\n </label>\n\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.showLegend !== false}\n onChange={(e) => handleChange('showLegend', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">\n {t('bigconsole.widget.config.heatmap.showLegend', 'Show color legend')}\n </span>\n </label>\n </div>\n );\n});\n\nexport default HeatmapConfig;\n"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { memo as e, useMemo as t } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { useI18n as n } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
3
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
3
4
|
//#region src/bigconsole/components/widgets/kanban/KanbanWidget.tsx
|
|
4
|
-
function
|
|
5
|
+
function a(e) {
|
|
5
6
|
switch (e) {
|
|
6
7
|
case "high": return "bg-status-error-bg/20 text-status-error-text";
|
|
7
8
|
case "medium": return "bg-status-warning-bg/20 text-status-warning-text";
|
|
@@ -9,7 +10,7 @@ function i(e) {
|
|
|
9
10
|
default: return "bg-bg-sunken text-text-secondary";
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
|
-
var
|
|
13
|
+
var o = [
|
|
13
14
|
"status",
|
|
14
15
|
"state",
|
|
15
16
|
"column",
|
|
@@ -17,7 +18,7 @@ var a = [
|
|
|
17
18
|
"category",
|
|
18
19
|
"phase",
|
|
19
20
|
"group"
|
|
20
|
-
],
|
|
21
|
+
], s = [
|
|
21
22
|
"title",
|
|
22
23
|
"name",
|
|
23
24
|
"summary",
|
|
@@ -25,10 +26,10 @@ var a = [
|
|
|
25
26
|
"identifier",
|
|
26
27
|
"id"
|
|
27
28
|
];
|
|
28
|
-
function
|
|
29
|
+
function c(e) {
|
|
29
30
|
return typeof e == "string" && e.length > 0 ? e : void 0;
|
|
30
31
|
}
|
|
31
|
-
function
|
|
32
|
+
function l(e) {
|
|
32
33
|
let t = (e) => e.filter((e) => !!e && typeof e == "object" && !Array.isArray(e));
|
|
33
34
|
if (Array.isArray(e)) return t(e);
|
|
34
35
|
if (e && typeof e == "object") {
|
|
@@ -47,18 +48,18 @@ function c(e) {
|
|
|
47
48
|
}
|
|
48
49
|
return [];
|
|
49
50
|
}
|
|
50
|
-
function
|
|
51
|
+
function u(e, t) {
|
|
51
52
|
for (let n of t) if (n && n in e) return n;
|
|
52
53
|
}
|
|
53
|
-
function
|
|
54
|
-
let t =
|
|
54
|
+
function d(e) {
|
|
55
|
+
let t = c(e)?.toLowerCase();
|
|
55
56
|
if (t) {
|
|
56
57
|
if (t === "urgent" || t === "high") return "high";
|
|
57
58
|
if (t === "medium" || t === "normal") return "medium";
|
|
58
59
|
if (t === "low") return "low";
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
|
-
function
|
|
62
|
+
function f(e, t) {
|
|
62
63
|
if (e && typeof e == "object" && !Array.isArray(e) && Array.isArray(e.columns)) {
|
|
63
64
|
let t = e;
|
|
64
65
|
return {
|
|
@@ -66,39 +67,39 @@ function d(e, t) {
|
|
|
66
67
|
tasks: t.tasks ?? []
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
|
-
let n =
|
|
70
|
+
let n = l(e);
|
|
70
71
|
if (n.length === 0) return {
|
|
71
72
|
columns: [],
|
|
72
73
|
tasks: []
|
|
73
74
|
};
|
|
74
|
-
let r = n[0], i =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
...
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
let r = n[0], i = u(r, [
|
|
76
|
+
c(t?.columnField),
|
|
77
|
+
c(t?.groupField),
|
|
78
|
+
c(t?.statusField),
|
|
79
|
+
...o,
|
|
80
|
+
c(t?.xAxisField),
|
|
81
|
+
c(t?.labelField)
|
|
81
82
|
]);
|
|
82
83
|
if (!i) return {
|
|
83
84
|
columns: [],
|
|
84
85
|
tasks: []
|
|
85
86
|
};
|
|
86
|
-
let
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
...
|
|
90
|
-
|
|
87
|
+
let a = u(r, [
|
|
88
|
+
c(t?.cardTitleField),
|
|
89
|
+
c(t?.titleField),
|
|
90
|
+
...s,
|
|
91
|
+
c(t?.labelField)
|
|
91
92
|
]), f = {}, p = [], m = n.map((e, t) => {
|
|
92
93
|
let n = e[i], r = n == null || n === "" ? "Uncategorized" : String(n);
|
|
93
94
|
r in f || (f[r] = r, p.push(r));
|
|
94
|
-
let
|
|
95
|
+
let o = e.id ?? e.identifier ?? e.key, s = Array.isArray(e.labels) ? e.labels.filter((e) => typeof e == "string") : void 0;
|
|
95
96
|
return {
|
|
96
|
-
id:
|
|
97
|
-
title:
|
|
97
|
+
id: o == null ? `task-${t}` : String(o),
|
|
98
|
+
title: a && e[a] != null ? String(e[a]) : `Item ${t + 1}`,
|
|
98
99
|
column: r,
|
|
99
|
-
assignee:
|
|
100
|
-
priority:
|
|
101
|
-
labels:
|
|
100
|
+
assignee: c(e.assignee),
|
|
101
|
+
priority: d(e.priority ?? e.priorityLabel),
|
|
102
|
+
labels: s && s.length > 0 ? s : void 0
|
|
102
103
|
};
|
|
103
104
|
});
|
|
104
105
|
return {
|
|
@@ -109,84 +110,84 @@ function d(e, t) {
|
|
|
109
110
|
tasks: m
|
|
110
111
|
};
|
|
111
112
|
}
|
|
112
|
-
var
|
|
113
|
-
let
|
|
113
|
+
var p = e(function({ widget: e, data: o, onClick: s }) {
|
|
114
|
+
let { t: c } = n(), l = e.config, { columns: u, tasks: d } = t(() => f(o, l), [o, l]), p = t(() => {
|
|
114
115
|
let e = {};
|
|
115
|
-
return
|
|
116
|
-
e[t.id] =
|
|
116
|
+
return u.forEach((t) => {
|
|
117
|
+
e[t.id] = d.filter((e) => e.column === t.id);
|
|
117
118
|
}), e;
|
|
118
|
-
}, [
|
|
119
|
-
return
|
|
119
|
+
}, [u, d]);
|
|
120
|
+
return u.length ? /* @__PURE__ */ r("div", {
|
|
120
121
|
className: "flex h-full p-2 gap-2 overflow-x-auto",
|
|
121
|
-
children:
|
|
122
|
-
let t =
|
|
123
|
-
return /* @__PURE__ */
|
|
122
|
+
children: u.map((e) => {
|
|
123
|
+
let t = p[e.id] || [];
|
|
124
|
+
return /* @__PURE__ */ i("div", {
|
|
124
125
|
className: "flex-shrink-0 w-48 flex flex-col bg-bg-sunken/50 rounded-lg",
|
|
125
|
-
children: [/* @__PURE__ */
|
|
126
|
+
children: [/* @__PURE__ */ i("div", {
|
|
126
127
|
className: "flex items-center gap-2 p-2 border-b border-border-default",
|
|
127
128
|
children: [
|
|
128
|
-
/* @__PURE__ */
|
|
129
|
+
/* @__PURE__ */ r("div", {
|
|
129
130
|
className: "w-2 h-2 rounded-full",
|
|
130
131
|
style: { backgroundColor: e.color || "var(--color-text-muted)" }
|
|
131
132
|
}),
|
|
132
|
-
/* @__PURE__ */
|
|
133
|
+
/* @__PURE__ */ r("span", {
|
|
133
134
|
className: "text-xs font-medium text-text-primary truncate",
|
|
134
135
|
children: e.title
|
|
135
136
|
}),
|
|
136
|
-
/* @__PURE__ */
|
|
137
|
+
/* @__PURE__ */ r("span", {
|
|
137
138
|
className: "ml-auto text-xs text-text-tertiary",
|
|
138
139
|
children: t.length
|
|
139
140
|
})
|
|
140
141
|
]
|
|
141
|
-
}), /* @__PURE__ */
|
|
142
|
+
}), /* @__PURE__ */ i("div", {
|
|
142
143
|
className: "flex-1 p-2 space-y-2 overflow-y-auto",
|
|
143
|
-
children: [t.map((e) => /* @__PURE__ */
|
|
144
|
+
children: [t.map((e) => /* @__PURE__ */ i("div", {
|
|
144
145
|
className: `
|
|
145
146
|
p-2 bg-bg-surface rounded border border-border-default
|
|
146
|
-
${
|
|
147
|
+
${s ? "cursor-pointer hover:border-action-primary-bg" : ""}
|
|
147
148
|
transition-colors
|
|
148
149
|
`,
|
|
149
|
-
onClick: () =>
|
|
150
|
-
children: [/* @__PURE__ */
|
|
150
|
+
onClick: () => s?.(e),
|
|
151
|
+
children: [/* @__PURE__ */ r("p", {
|
|
151
152
|
className: "text-xs font-medium text-text-primary line-clamp-2",
|
|
152
153
|
children: e.title
|
|
153
|
-
}), /* @__PURE__ */
|
|
154
|
+
}), /* @__PURE__ */ i("div", {
|
|
154
155
|
className: "flex items-center gap-1 mt-2 flex-wrap",
|
|
155
|
-
children: [e.priority && /* @__PURE__ */
|
|
156
|
-
className: `px-1.5 py-0.5 text-[10px] rounded ${
|
|
156
|
+
children: [e.priority && /* @__PURE__ */ r("span", {
|
|
157
|
+
className: `px-1.5 py-0.5 text-[10px] rounded ${a(e.priority)}`,
|
|
157
158
|
children: e.priority
|
|
158
|
-
}), e.assignee && /* @__PURE__ */
|
|
159
|
+
}), e.assignee && /* @__PURE__ */ r("span", {
|
|
159
160
|
className: "px-1.5 py-0.5 text-[10px] rounded bg-action-primary-bg/10 text-action-primary-text",
|
|
160
161
|
children: e.assignee
|
|
161
162
|
})]
|
|
162
163
|
})]
|
|
163
|
-
}, e.id)), t.length === 0 && /* @__PURE__ */
|
|
164
|
+
}, e.id)), t.length === 0 && /* @__PURE__ */ r("p", {
|
|
164
165
|
className: "text-[10px] text-text-tertiary text-center py-4",
|
|
165
|
-
children: "No tasks"
|
|
166
|
+
children: c("bigconsole.widget.kanban.noTasks", "No tasks")
|
|
166
167
|
})]
|
|
167
168
|
})]
|
|
168
169
|
}, e.id);
|
|
169
170
|
})
|
|
170
|
-
}) : /* @__PURE__ */
|
|
171
|
+
}) : /* @__PURE__ */ r("div", {
|
|
171
172
|
className: "flex items-center justify-center h-full text-text-secondary text-sm",
|
|
172
|
-
children: /* @__PURE__ */
|
|
173
|
+
children: /* @__PURE__ */ i("div", {
|
|
173
174
|
className: "text-center",
|
|
174
|
-
children: [/* @__PURE__ */
|
|
175
|
+
children: [/* @__PURE__ */ r("svg", {
|
|
175
176
|
className: "w-12 h-12 mx-auto mb-2 text-text-tertiary",
|
|
176
177
|
fill: "none",
|
|
177
178
|
stroke: "currentColor",
|
|
178
179
|
viewBox: "0 0 24 24",
|
|
179
|
-
children: /* @__PURE__ */
|
|
180
|
+
children: /* @__PURE__ */ r("path", {
|
|
180
181
|
strokeLinecap: "round",
|
|
181
182
|
strokeLinejoin: "round",
|
|
182
183
|
strokeWidth: 1.5,
|
|
183
184
|
d: "M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2"
|
|
184
185
|
})
|
|
185
|
-
}), /* @__PURE__ */
|
|
186
|
+
}), /* @__PURE__ */ r("p", { children: c("bigconsole.widget.kanban.emptyState", "No board data") })]
|
|
186
187
|
})
|
|
187
188
|
});
|
|
188
189
|
});
|
|
189
190
|
//#endregion
|
|
190
|
-
export {
|
|
191
|
+
export { p as default };
|
|
191
192
|
|
|
192
193
|
//# sourceMappingURL=KanbanWidget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KanbanWidget.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/kanban/KanbanWidget.tsx"],"sourcesContent":["/**\n * KanbanWidget Component\n *\n * Simple kanban board view with columns and tasks.\n */\n\nimport { type FC, memo, useMemo } from 'react';\nimport type { Widget } from '../../../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface KanbanWidgetProps {\n widget: Widget;\n data?: KanbanData;\n onClick?: (task: KanbanTask) => void;\n}\n\nexport interface KanbanColumn {\n id: string;\n title: string;\n color?: string;\n}\n\nexport interface KanbanTask {\n id: string;\n title: string;\n column: string;\n priority?: 'high' | 'medium' | 'low';\n assignee?: string;\n labels?: string[];\n dueDate?: string;\n}\n\nexport interface KanbanData {\n columns?: KanbanColumn[];\n tasks?: KanbanTask[];\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction getPriorityColor(priority?: string): string {\n switch (priority) {\n case 'high':\n return 'bg-status-error-bg/20 text-status-error-text';\n case 'medium':\n return 'bg-status-warning-bg/20 text-status-warning-text';\n case 'low':\n return 'bg-status-success-bg/20 text-status-success-text';\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\n// Field names we try, in order, when the widget config doesn't name one\n// explicitly. A DataSink/parser typically emits a flat array of rows (e.g. the\n// Linear \"Kanban board\" parser -> [{ id, title, status, assignee, ... }]), so\n// the board is derived from a status/column field on those rows.\nconst COLUMN_FIELD_CANDIDATES = ['status', 'state', 'column', 'stage', 'category', 'phase', 'group'];\nconst TITLE_FIELD_CANDIDATES = ['title', 'name', 'summary', 'label', 'identifier', 'id'];\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/** Coerce parser output into an array of object rows (handles common envelopes). */\nfunction asRows(data: unknown): Record<string, unknown>[] {\n const onlyObjects = (arr: unknown[]): Record<string, unknown>[] =>\n arr.filter((r): r is Record<string, unknown> => !!r && typeof r === 'object' && !Array.isArray(r));\n\n if (Array.isArray(data)) return onlyObjects(data);\n\n if (data && typeof data === 'object') {\n const obj = data as Record<string, unknown>;\n for (const key of ['tasks', 'rows', 'items', 'data', 'nodes', 'results', 'records']) {\n if (Array.isArray(obj[key])) return onlyObjects(obj[key] as unknown[]);\n }\n const firstArray = Object.values(obj).find((v) => Array.isArray(v));\n if (Array.isArray(firstArray)) return onlyObjects(firstArray);\n }\n return [];\n}\n\n/** First key that actually exists on the sample row. */\nfunction firstPresent(row: Record<string, unknown>, keys: (string | undefined)[]): string | undefined {\n for (const key of keys) {\n if (key && key in row) return key;\n }\n return undefined;\n}\n\nfunction normalizePriority(value: unknown): KanbanTask['priority'] {\n const v = asString(value)?.toLowerCase();\n if (!v) return undefined;\n if (v === 'urgent' || v === 'high') return 'high';\n if (v === 'medium' || v === 'normal') return 'medium';\n if (v === 'low') return 'low';\n return undefined;\n}\n\n/**\n * Normalize widget data into the board's { columns, tasks } shape.\n *\n * KanbanWidget previously required the exact canonical shape and rendered\n * \"No board data\" for any DataSink/parser output that was a plain array of\n * rows (which is what parsers actually emit) — BOFF-4110. This adapts a flat\n * array into columns (distinct values of a status/column field, in first-seen\n * order) plus one card per row, honoring config field mappings with fallbacks.\n */\nfunction normalizeKanban(\n data: unknown,\n config?: Record<string, unknown>\n): { columns: KanbanColumn[]; tasks: KanbanTask[] } {\n // Canonical shape passes through untouched (back-compat).\n if (data && typeof data === 'object' && !Array.isArray(data) && Array.isArray((data as KanbanData).columns)) {\n const d = data as KanbanData;\n return { columns: d.columns ?? [], tasks: d.tasks ?? [] };\n }\n\n const rows = asRows(data);\n if (rows.length === 0) return { columns: [], tasks: [] };\n\n const sample = rows[0];\n const columnField = firstPresent(sample, [\n asString(config?.columnField),\n asString(config?.groupField),\n asString(config?.statusField),\n ...COLUMN_FIELD_CANDIDATES,\n asString(config?.xAxisField),\n asString(config?.labelField),\n ]);\n if (!columnField) return { columns: [], tasks: [] };\n\n const titleField = firstPresent(sample, [\n asString(config?.cardTitleField),\n asString(config?.titleField),\n ...TITLE_FIELD_CANDIDATES,\n asString(config?.labelField),\n ]);\n\n const columnTitles: Record<string, string> = {};\n const columnOrder: string[] = [];\n const tasks: KanbanTask[] = rows.map((row, i) => {\n const columnRaw = row[columnField];\n const column = columnRaw == null || columnRaw === '' ? 'Uncategorized' : String(columnRaw);\n if (!(column in columnTitles)) {\n columnTitles[column] = column;\n columnOrder.push(column);\n }\n const idRaw = row.id ?? row.identifier ?? row.key;\n const labels = Array.isArray(row.labels) ? row.labels.filter((l): l is string => typeof l === 'string') : undefined;\n return {\n id: idRaw != null ? String(idRaw) : `task-${i}`,\n title: titleField && row[titleField] != null ? String(row[titleField]) : `Item ${i + 1}`,\n column,\n assignee: asString(row.assignee),\n priority: normalizePriority(row.priority ?? row.priorityLabel),\n labels: labels && labels.length > 0 ? labels : undefined,\n };\n });\n\n const columns: KanbanColumn[] = columnOrder.map((id) => ({ id, title: columnTitles[id] ?? id }));\n return { columns, tasks };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const KanbanWidget: FC<KanbanWidgetProps> = memo(function KanbanWidget({ widget, data, onClick }) {\n const config = widget.config as Record<string, unknown> | undefined;\n const { columns, tasks } = useMemo(() => normalizeKanban(data, config), [data, config]);\n\n // Group tasks by column\n const tasksByColumn = useMemo(() => {\n const grouped: Record<string, KanbanTask[]> = {};\n columns.forEach((col) => {\n grouped[col.id] = tasks.filter((t) => t.column === col.id);\n });\n return grouped;\n }, [columns, tasks]);\n\n if (!columns.length) {\n return (\n <div className=\"flex items-center justify-center h-full text-text-secondary text-sm\">\n <div className=\"text-center\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2 text-text-tertiary\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2\"\n />\n </svg>\n <p>No board data</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full p-2 gap-2 overflow-x-auto\">\n {columns.map((column) => {\n const columnTasks = tasksByColumn[column.id] || [];\n\n return (\n <div key={column.id} className=\"flex-shrink-0 w-48 flex flex-col bg-bg-sunken/50 rounded-lg\">\n {/* Column Header */}\n <div className=\"flex items-center gap-2 p-2 border-b border-border-default\">\n <div\n className=\"w-2 h-2 rounded-full\"\n style={{ backgroundColor: column.color || 'var(--color-text-muted)' }}\n />\n <span className=\"text-xs font-medium text-text-primary truncate\">{column.title}</span>\n <span className=\"ml-auto text-xs text-text-tertiary\">{columnTasks.length}</span>\n </div>\n\n {/* Tasks */}\n <div className=\"flex-1 p-2 space-y-2 overflow-y-auto\">\n {columnTasks.map((task) => (\n <div\n key={task.id}\n className={`\n p-2 bg-bg-surface rounded border border-border-default\n ${onClick ? 'cursor-pointer hover:border-action-primary-bg' : ''}\n transition-colors\n `}\n onClick={() => onClick?.(task)}\n >\n <p className=\"text-xs font-medium text-text-primary line-clamp-2\">{task.title}</p>\n\n <div className=\"flex items-center gap-1 mt-2 flex-wrap\">\n {task.priority && (\n <span className={`px-1.5 py-0.5 text-[10px] rounded ${getPriorityColor(task.priority)}`}>\n {task.priority}\n </span>\n )}\n {task.assignee && (\n <span className=\"px-1.5 py-0.5 text-[10px] rounded bg-action-primary-bg/10 text-action-primary-text\">\n {task.assignee}\n </span>\n )}\n </div>\n </div>\n ))}\n\n {columnTasks.length === 0 && <p className=\"text-[10px] text-text-tertiary text-center py-4\">No tasks</p>}\n </div>\n </div>\n );\n })}\n </div>\n );\n});\n\nexport default KanbanWidget;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"KanbanWidget.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/kanban/KanbanWidget.tsx"],"sourcesContent":["/**\n * KanbanWidget Component\n *\n * Simple kanban board view with columns and tasks.\n */\n\nimport { type FC, memo, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { Widget } from '../../../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface KanbanWidgetProps {\n widget: Widget;\n data?: KanbanData;\n onClick?: (task: KanbanTask) => void;\n}\n\nexport interface KanbanColumn {\n id: string;\n title: string;\n color?: string;\n}\n\nexport interface KanbanTask {\n id: string;\n title: string;\n column: string;\n priority?: 'high' | 'medium' | 'low';\n assignee?: string;\n labels?: string[];\n dueDate?: string;\n}\n\nexport interface KanbanData {\n columns?: KanbanColumn[];\n tasks?: KanbanTask[];\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction getPriorityColor(priority?: string): string {\n switch (priority) {\n case 'high':\n return 'bg-status-error-bg/20 text-status-error-text';\n case 'medium':\n return 'bg-status-warning-bg/20 text-status-warning-text';\n case 'low':\n return 'bg-status-success-bg/20 text-status-success-text';\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\n// Field names we try, in order, when the widget config doesn't name one\n// explicitly. A DataSink/parser typically emits a flat array of rows (e.g. the\n// Linear \"Kanban board\" parser -> [{ id, title, status, assignee, ... }]), so\n// the board is derived from a status/column field on those rows.\nconst COLUMN_FIELD_CANDIDATES = ['status', 'state', 'column', 'stage', 'category', 'phase', 'group'];\nconst TITLE_FIELD_CANDIDATES = ['title', 'name', 'summary', 'label', 'identifier', 'id'];\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/** Coerce parser output into an array of object rows (handles common envelopes). */\nfunction asRows(data: unknown): Record<string, unknown>[] {\n const onlyObjects = (arr: unknown[]): Record<string, unknown>[] =>\n arr.filter((r): r is Record<string, unknown> => !!r && typeof r === 'object' && !Array.isArray(r));\n\n if (Array.isArray(data)) return onlyObjects(data);\n\n if (data && typeof data === 'object') {\n const obj = data as Record<string, unknown>;\n for (const key of ['tasks', 'rows', 'items', 'data', 'nodes', 'results', 'records']) {\n if (Array.isArray(obj[key])) return onlyObjects(obj[key] as unknown[]);\n }\n const firstArray = Object.values(obj).find((v) => Array.isArray(v));\n if (Array.isArray(firstArray)) return onlyObjects(firstArray);\n }\n return [];\n}\n\n/** First key that actually exists on the sample row. */\nfunction firstPresent(row: Record<string, unknown>, keys: (string | undefined)[]): string | undefined {\n for (const key of keys) {\n if (key && key in row) return key;\n }\n return undefined;\n}\n\nfunction normalizePriority(value: unknown): KanbanTask['priority'] {\n const v = asString(value)?.toLowerCase();\n if (!v) return undefined;\n if (v === 'urgent' || v === 'high') return 'high';\n if (v === 'medium' || v === 'normal') return 'medium';\n if (v === 'low') return 'low';\n return undefined;\n}\n\n/**\n * Normalize widget data into the board's { columns, tasks } shape.\n *\n * KanbanWidget previously required the exact canonical shape and rendered\n * \"No board data\" for any DataSink/parser output that was a plain array of\n * rows (which is what parsers actually emit) — BOFF-4110. This adapts a flat\n * array into columns (distinct values of a status/column field, in first-seen\n * order) plus one card per row, honoring config field mappings with fallbacks.\n */\nfunction normalizeKanban(\n data: unknown,\n config?: Record<string, unknown>\n): { columns: KanbanColumn[]; tasks: KanbanTask[] } {\n // Canonical shape passes through untouched (back-compat).\n if (data && typeof data === 'object' && !Array.isArray(data) && Array.isArray((data as KanbanData).columns)) {\n const d = data as KanbanData;\n return { columns: d.columns ?? [], tasks: d.tasks ?? [] };\n }\n\n const rows = asRows(data);\n if (rows.length === 0) return { columns: [], tasks: [] };\n\n const sample = rows[0];\n const columnField = firstPresent(sample, [\n asString(config?.columnField),\n asString(config?.groupField),\n asString(config?.statusField),\n ...COLUMN_FIELD_CANDIDATES,\n asString(config?.xAxisField),\n asString(config?.labelField),\n ]);\n if (!columnField) return { columns: [], tasks: [] };\n\n const titleField = firstPresent(sample, [\n asString(config?.cardTitleField),\n asString(config?.titleField),\n ...TITLE_FIELD_CANDIDATES,\n asString(config?.labelField),\n ]);\n\n const columnTitles: Record<string, string> = {};\n const columnOrder: string[] = [];\n const tasks: KanbanTask[] = rows.map((row, i) => {\n const columnRaw = row[columnField];\n const column = columnRaw == null || columnRaw === '' ? 'Uncategorized' : String(columnRaw);\n if (!(column in columnTitles)) {\n columnTitles[column] = column;\n columnOrder.push(column);\n }\n const idRaw = row.id ?? row.identifier ?? row.key;\n const labels = Array.isArray(row.labels) ? row.labels.filter((l): l is string => typeof l === 'string') : undefined;\n return {\n id: idRaw != null ? String(idRaw) : `task-${i}`,\n title: titleField && row[titleField] != null ? String(row[titleField]) : `Item ${i + 1}`,\n column,\n assignee: asString(row.assignee),\n priority: normalizePriority(row.priority ?? row.priorityLabel),\n labels: labels && labels.length > 0 ? labels : undefined,\n };\n });\n\n const columns: KanbanColumn[] = columnOrder.map((id) => ({ id, title: columnTitles[id] ?? id }));\n return { columns, tasks };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const KanbanWidget: FC<KanbanWidgetProps> = memo(function KanbanWidget({ widget, data, onClick }) {\n const { t } = useI18n();\n const config = widget.config as Record<string, unknown> | undefined;\n const { columns, tasks } = useMemo(() => normalizeKanban(data, config), [data, config]);\n\n // Group tasks by column\n const tasksByColumn = useMemo(() => {\n const grouped: Record<string, KanbanTask[]> = {};\n columns.forEach((col) => {\n grouped[col.id] = tasks.filter((t) => t.column === col.id);\n });\n return grouped;\n }, [columns, tasks]);\n\n if (!columns.length) {\n return (\n <div className=\"flex items-center justify-center h-full text-text-secondary text-sm\">\n <div className=\"text-center\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2 text-text-tertiary\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2\"\n />\n </svg>\n <p>{t('bigconsole.widget.kanban.emptyState', 'No board data')}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full p-2 gap-2 overflow-x-auto\">\n {columns.map((column) => {\n const columnTasks = tasksByColumn[column.id] || [];\n\n return (\n <div key={column.id} className=\"flex-shrink-0 w-48 flex flex-col bg-bg-sunken/50 rounded-lg\">\n {/* Column Header */}\n <div className=\"flex items-center gap-2 p-2 border-b border-border-default\">\n <div\n className=\"w-2 h-2 rounded-full\"\n style={{ backgroundColor: column.color || 'var(--color-text-muted)' }}\n />\n <span className=\"text-xs font-medium text-text-primary truncate\">{column.title}</span>\n <span className=\"ml-auto text-xs text-text-tertiary\">{columnTasks.length}</span>\n </div>\n\n {/* Tasks */}\n <div className=\"flex-1 p-2 space-y-2 overflow-y-auto\">\n {columnTasks.map((task) => (\n <div\n key={task.id}\n className={`\n p-2 bg-bg-surface rounded border border-border-default\n ${onClick ? 'cursor-pointer hover:border-action-primary-bg' : ''}\n transition-colors\n `}\n onClick={() => onClick?.(task)}\n >\n <p className=\"text-xs font-medium text-text-primary line-clamp-2\">{task.title}</p>\n\n <div className=\"flex items-center gap-1 mt-2 flex-wrap\">\n {task.priority && (\n <span className={`px-1.5 py-0.5 text-[10px] rounded ${getPriorityColor(task.priority)}`}>\n {task.priority}\n </span>\n )}\n {task.assignee && (\n <span className=\"px-1.5 py-0.5 text-[10px] rounded bg-action-primary-bg/10 text-action-primary-text\">\n {task.assignee}\n </span>\n )}\n </div>\n </div>\n ))}\n\n {columnTasks.length === 0 && (\n <p className=\"text-[10px] text-text-tertiary text-center py-4\">\n {t('bigconsole.widget.kanban.noTasks', 'No tasks')}\n </p>\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n});\n\nexport default KanbanWidget;\n"],"mappings":"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"}
|