@burdenoff/microfe-bigconsole 2026.925.1 → 2026.928.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.
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +142 -145
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
- package/dist/bigconsole/components/embed/EmbedWidgetRenderer.js +43 -13
- package/dist/bigconsole/components/embed/EmbedWidgetRenderer.js.map +1 -1
- package/dist/bigconsole/components/embed/ReadOnlyDashboardRenderer.js +5 -5
- package/dist/bigconsole/components/embed/ReadOnlyDashboardRenderer.js.map +1 -1
- package/dist/bigconsole/components/embed/renderer-manifest.js +14 -47
- package/dist/bigconsole/components/embed/renderer-manifest.js.map +1 -1
- package/dist/bigconsole/components/embed/types.js.map +1 -1
- package/dist/bigconsole/components/embed/widgetShim.js +28 -0
- package/dist/bigconsole/components/embed/widgetShim.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/CalendarEmbed.js +38 -0
- package/dist/bigconsole/components/embed/widgets/CalendarEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/ChartEmbed.js +225 -0
- package/dist/bigconsole/components/embed/widgets/ChartEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/EmbedFrame.js +18 -0
- package/dist/bigconsole/components/embed/widgets/EmbedFrame.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/FormEmbed.js +147 -0
- package/dist/bigconsole/components/embed/widgets/FormEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/GaugeEmbed.js +44 -0
- package/dist/bigconsole/components/embed/widgets/GaugeEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/HeatmapEmbed.js +35 -0
- package/dist/bigconsole/components/embed/widgets/HeatmapEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/KanbanEmbed.js +50 -0
- package/dist/bigconsole/components/embed/widgets/KanbanEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/PivotEmbed.js +146 -0
- package/dist/bigconsole/components/embed/widgets/PivotEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/ProgressEmbed.js +30 -0
- package/dist/bigconsole/components/embed/widgets/ProgressEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/RetentionEmbed.js +41 -0
- package/dist/bigconsole/components/embed/widgets/RetentionEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/TimelineEmbed.js +40 -0
- package/dist/bigconsole/components/embed/widgets/TimelineEmbed.js.map +1 -0
- package/dist/bigconsole/components/embed/widgets/shared.js +13 -1
- package/dist/bigconsole/components/embed/widgets/shared.js.map +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarView.js +152 -0
- package/dist/bigconsole/components/widgets/calendar/CalendarView.js.map +1 -0
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +10 -147
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/chart/ChartWidget.js +19 -19
- package/dist/bigconsole/components/widgets/chart/index.js +8 -8
- package/dist/bigconsole/components/widgets/index.js +5 -5
- package/dist/bigconsole/components/widgets/kanban/KanbanView.js +192 -0
- package/dist/bigconsole/components/widgets/kanban/KanbanView.js.map +1 -0
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +10 -187
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +20 -20
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +23 -22
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/utils/translate.js +9 -0
- package/dist/bigconsole/components/widgets/utils/translate.js.map +1 -0
- package/dist/bigconsole/hooks/useDashboardEmbedPolicy.js +2 -4
- package/dist/bigconsole/hooks/useDashboardEmbedPolicy.js.map +1 -1
- package/dist/generated/wspace-operations.js +0 -1
- package/dist/generated/wspace-operations.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,153 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import e from "./CalendarView.js";
|
|
2
|
+
import { memo as t } from "react";
|
|
3
|
+
import { jsx as n } from "react/jsx-runtime";
|
|
4
|
+
import { useI18n as r } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
4
5
|
//#region src/bigconsole/components/widgets/calendar/CalendarWidget.tsx
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return Array.isArray(t) ? t.map((e, t) => {
|
|
11
|
-
if (!e || typeof e != "object") return null;
|
|
12
|
-
let n = e, r = a(n, [
|
|
13
|
-
"start",
|
|
14
|
-
"startDate",
|
|
15
|
-
"date",
|
|
16
|
-
"startTime"
|
|
17
|
-
]);
|
|
18
|
-
if (!r) return null;
|
|
19
|
-
let i = a(n, [
|
|
20
|
-
"end",
|
|
21
|
-
"endDate",
|
|
22
|
-
"endTime"
|
|
23
|
-
]) ?? r, o = a(n, [
|
|
24
|
-
"title",
|
|
25
|
-
"name",
|
|
26
|
-
"label",
|
|
27
|
-
"summary"
|
|
28
|
-
]) ?? "Untitled event", s = a(n, [
|
|
29
|
-
"id",
|
|
30
|
-
"eventId",
|
|
31
|
-
"_id"
|
|
32
|
-
]) ?? `${o}-${r}-${t}`;
|
|
33
|
-
return {
|
|
34
|
-
id: String(s),
|
|
35
|
-
title: String(o),
|
|
36
|
-
start: String(r),
|
|
37
|
-
end: String(i),
|
|
38
|
-
color: typeof n.color == "string" ? n.color : void 0,
|
|
39
|
-
allDay: typeof n.allDay == "boolean" ? n.allDay : void 0,
|
|
40
|
-
category: a(n, [
|
|
41
|
-
"category",
|
|
42
|
-
"group",
|
|
43
|
-
"type"
|
|
44
|
-
])
|
|
45
|
-
};
|
|
46
|
-
}).filter((e) => e !== null) : [];
|
|
47
|
-
}
|
|
48
|
-
var s = e(function({ widget: e, data: a, onClick: s }) {
|
|
49
|
-
let { t: c } = i(), l = t(() => o(a), [a]), u = t(() => {
|
|
50
|
-
let e = /* @__PURE__ */ new Date(), t = new Date(e.getTime() + 10080 * 60 * 1e3);
|
|
51
|
-
return l.filter((n) => {
|
|
52
|
-
let r = new Date(n.start);
|
|
53
|
-
return r >= e && r <= t;
|
|
54
|
-
}).sort((e, t) => new Date(e.start).getTime() - new Date(t.start).getTime()).slice(0, 8);
|
|
55
|
-
}, [l]);
|
|
56
|
-
return l.length ? /* @__PURE__ */ r("div", {
|
|
57
|
-
className: "flex flex-col h-full p-4 overflow-auto",
|
|
58
|
-
children: [
|
|
59
|
-
/* @__PURE__ */ r("div", {
|
|
60
|
-
className: "flex items-center justify-between mb-4",
|
|
61
|
-
children: [/* @__PURE__ */ n("h3", {
|
|
62
|
-
className: "text-sm font-medium text-text-primary",
|
|
63
|
-
children: c("bigconsole.widget.calendar.upcomingEvents", "Upcoming Events")
|
|
64
|
-
}), /* @__PURE__ */ n("span", {
|
|
65
|
-
className: "text-xs text-text-secondary",
|
|
66
|
-
children: c("bigconsole.widget.calendar.eventCount", "{{count}} events", { count: l.length })
|
|
67
|
-
})]
|
|
68
|
-
}),
|
|
69
|
-
/* @__PURE__ */ n("div", {
|
|
70
|
-
className: "flex-1 space-y-2 overflow-auto",
|
|
71
|
-
children: u.map((e) => {
|
|
72
|
-
let t = new Date(e.start), i = t.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
73
|
-
return /* @__PURE__ */ n("div", {
|
|
74
|
-
className: `
|
|
75
|
-
p-3 rounded-lg border border-border-default
|
|
76
|
-
${s ? "cursor-pointer hover:border-action-primary-bg" : ""}
|
|
77
|
-
transition-colors
|
|
78
|
-
`,
|
|
79
|
-
onClick: () => s?.(e),
|
|
80
|
-
children: /* @__PURE__ */ r("div", {
|
|
81
|
-
className: "flex items-start gap-3",
|
|
82
|
-
children: [/* @__PURE__ */ n("div", {
|
|
83
|
-
className: "w-1 h-full min-h-[40px] rounded-full flex-shrink-0",
|
|
84
|
-
style: { backgroundColor: e.color || "var(--color-action-primary-bg)" }
|
|
85
|
-
}), /* @__PURE__ */ r("div", {
|
|
86
|
-
className: "flex-1 min-w-0",
|
|
87
|
-
children: [
|
|
88
|
-
/* @__PURE__ */ n("p", {
|
|
89
|
-
className: "text-sm font-medium text-text-primary truncate",
|
|
90
|
-
children: e.title
|
|
91
|
-
}),
|
|
92
|
-
/* @__PURE__ */ r("p", {
|
|
93
|
-
className: "text-xs text-text-secondary mt-1",
|
|
94
|
-
children: [
|
|
95
|
-
i ? /* @__PURE__ */ n("span", {
|
|
96
|
-
className: "text-status-success-text font-medium",
|
|
97
|
-
children: c("bigconsole.widget.calendar.today", "Today")
|
|
98
|
-
}) : t.toLocaleDateString("en-US", {
|
|
99
|
-
weekday: "short",
|
|
100
|
-
month: "short",
|
|
101
|
-
day: "numeric"
|
|
102
|
-
}),
|
|
103
|
-
!e.allDay && /* @__PURE__ */ n("span", {
|
|
104
|
-
className: "ml-2",
|
|
105
|
-
children: t.toLocaleTimeString("en-US", {
|
|
106
|
-
hour: "numeric",
|
|
107
|
-
minute: "2-digit"
|
|
108
|
-
})
|
|
109
|
-
}),
|
|
110
|
-
e.allDay && /* @__PURE__ */ n("span", {
|
|
111
|
-
className: "ml-2",
|
|
112
|
-
children: c("bigconsole.widget.calendar.allDay", "All day")
|
|
113
|
-
})
|
|
114
|
-
]
|
|
115
|
-
}),
|
|
116
|
-
e.category && /* @__PURE__ */ n("span", {
|
|
117
|
-
className: "inline-block mt-1 px-2 py-0.5 text-[10px] rounded bg-bg-sunken text-text-secondary",
|
|
118
|
-
children: e.category
|
|
119
|
-
})
|
|
120
|
-
]
|
|
121
|
-
})]
|
|
122
|
-
})
|
|
123
|
-
}, e.id);
|
|
124
|
-
})
|
|
125
|
-
}),
|
|
126
|
-
l.length > u.length && /* @__PURE__ */ n("p", {
|
|
127
|
-
className: "text-xs text-text-muted text-center mt-3",
|
|
128
|
-
children: c("bigconsole.widget.calendar.moreEvents", "+{{count}} more events", { count: l.length - u.length })
|
|
129
|
-
})
|
|
130
|
-
]
|
|
131
|
-
}) : /* @__PURE__ */ n("div", {
|
|
132
|
-
className: "flex items-center justify-center h-full text-text-secondary text-sm",
|
|
133
|
-
children: /* @__PURE__ */ r("div", {
|
|
134
|
-
className: "text-center",
|
|
135
|
-
children: [/* @__PURE__ */ n("svg", {
|
|
136
|
-
className: "w-12 h-12 mx-auto mb-2 text-text-muted",
|
|
137
|
-
fill: "none",
|
|
138
|
-
stroke: "currentColor",
|
|
139
|
-
viewBox: "0 0 24 24",
|
|
140
|
-
children: /* @__PURE__ */ n("path", {
|
|
141
|
-
strokeLinecap: "round",
|
|
142
|
-
strokeLinejoin: "round",
|
|
143
|
-
strokeWidth: 1.5,
|
|
144
|
-
d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
|
|
145
|
-
})
|
|
146
|
-
}), /* @__PURE__ */ n("p", { children: c("bigconsole.widget.calendar.emptyState", "No events to display") })]
|
|
147
|
-
})
|
|
6
|
+
var i = t(function(t) {
|
|
7
|
+
let { t: i } = r();
|
|
8
|
+
return /* @__PURE__ */ n(e, {
|
|
9
|
+
...t,
|
|
10
|
+
t: i
|
|
148
11
|
});
|
|
149
12
|
});
|
|
150
13
|
//#endregion
|
|
151
|
-
export {
|
|
14
|
+
export { i as default };
|
|
152
15
|
|
|
153
16
|
//# sourceMappingURL=CalendarWidget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalendarWidget.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/calendar/CalendarWidget.tsx"],"sourcesContent":["/**\n * CalendarWidget Component\n *\n * Simple calendar view showing events.\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 CalendarWidgetProps {\n widget: Widget;\n data?: CalendarData;\n onClick?: (event: CalendarEvent) => void;\n}\n\nexport interface CalendarEvent {\n id: string;\n title: string;\n start: string;\n end: string;\n color?: string;\n allDay?: boolean;\n category?: string;\n}\n\nexport interface CalendarData {\n events?: CalendarEvent[];\n currentDate?: string;\n view?: 'month' | 'week' | 'day';\n}\n\n// ============================================================================\n// Normalization\n// ============================================================================\n\nfunction firstDefined<T = unknown>(obj: Record<string, unknown>, keys: string[]): T | undefined {\n for (const key of keys) {\n if (obj[key] !== undefined && obj[key] !== null) return obj[key] as T;\n }\n return undefined;\n}\n\n/**\n * Normalize whatever the widget is bound to into `CalendarEvent[]`. Accepts the\n * documented `{ events, ... }` shape, an events array under a different common\n * key, or a bare array of event-like records — a DataSink parser naturally\n * outputs a bare array, and WidgetWrapper has no calendar-specific reshaping\n * step (unlike table/list/chart), so this widget has to tolerate it itself, the\n * same way MapWidget tolerates a bare marker array instead of requiring\n * `{ markers }`. Field names are matched against common aliases so a parser\n * doesn't have to emit the exact `title`/`start`/`end` keys.\n */\nexport function normalizeCalendarEvents(\n data: CalendarData | CalendarEvent[] | Record<string, unknown> | undefined\n): CalendarEvent[] {\n const rawEvents: unknown = Array.isArray(data)\n ? data\n : Array.isArray((data as CalendarData | undefined)?.events)\n ? (data as CalendarData).events\n : Array.isArray((data as Record<string, unknown> | undefined)?.items)\n ? (data as Record<string, unknown>).items\n : Array.isArray((data as Record<string, unknown> | undefined)?.data)\n ? (data as Record<string, unknown>).data\n : undefined;\n\n if (!Array.isArray(rawEvents)) return [];\n\n return rawEvents\n .map((raw, i): CalendarEvent | null => {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Record<string, unknown>;\n const start = firstDefined<string>(r, ['start', 'startDate', 'date', 'startTime']);\n if (!start) return null;\n const end = firstDefined<string>(r, ['end', 'endDate', 'endTime']) ?? start;\n const title = firstDefined<string>(r, ['title', 'name', 'label', 'summary']) ?? 'Untitled event';\n const id = firstDefined<string>(r, ['id', 'eventId', '_id']) ?? `${title}-${start}-${i}`;\n return {\n id: String(id),\n title: String(title),\n start: String(start),\n end: String(end),\n color: typeof r.color === 'string' ? r.color : undefined,\n allDay: typeof r.allDay === 'boolean' ? r.allDay : undefined,\n category: firstDefined<string>(r, ['category', 'group', 'type']),\n };\n })\n .filter((e): e is CalendarEvent => e !== null);\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const CalendarWidget: FC<CalendarWidgetProps> = memo(function CalendarWidget({\n widget: _widget,\n data,\n onClick,\n}) {\n const { t } = useI18n();\n const events = useMemo(() => normalizeCalendarEvents(data), [data]);\n\n // Get upcoming events (next 7 days)\n const upcomingEvents = useMemo(() => {\n const now = new Date();\n const weekFromNow = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);\n return events\n .filter((e) => {\n const eventDate = new Date(e.start);\n return eventDate >= now && eventDate <= weekFromNow;\n })\n .sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime())\n .slice(0, 8);\n }, [events]);\n\n if (!events.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 className=\"w-12 h-12 mx-auto mb-2 text-text-muted\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n <p>{t('bigconsole.widget.calendar.emptyState', 'No events to display')}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full p-4 overflow-auto\">\n {/* Header */}\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-sm font-medium text-text-primary\">\n {t('bigconsole.widget.calendar.upcomingEvents', 'Upcoming Events')}\n </h3>\n <span className=\"text-xs text-text-secondary\">\n {t('bigconsole.widget.calendar.eventCount', '{{count}} events', { count: events.length })}\n </span>\n </div>\n\n {/* Event List */}\n <div className=\"flex-1 space-y-2 overflow-auto\">\n {upcomingEvents.map((event) => {\n const eventDate = new Date(event.start);\n const isToday = eventDate.toDateString() === new Date().toDateString();\n\n return (\n <div\n key={event.id}\n className={`\n p-3 rounded-lg border border-border-default\n ${onClick ? 'cursor-pointer hover:border-action-primary-bg' : ''}\n transition-colors\n `}\n onClick={() => onClick?.(event)}\n >\n <div className=\"flex items-start gap-3\">\n {/* Color indicator */}\n <div\n className=\"w-1 h-full min-h-[40px] rounded-full flex-shrink-0\"\n style={{ backgroundColor: event.color || 'var(--color-action-primary-bg)' }}\n />\n\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">{event.title}</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n {isToday ? (\n <span className=\"text-status-success-text font-medium\">\n {t('bigconsole.widget.calendar.today', 'Today')}\n </span>\n ) : (\n eventDate.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' })\n )}\n {!event.allDay && (\n <span className=\"ml-2\">\n {eventDate.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' })}\n </span>\n )}\n {event.allDay && <span className=\"ml-2\">{t('bigconsole.widget.calendar.allDay', 'All day')}</span>}\n </p>\n {event.category && (\n <span className=\"inline-block mt-1 px-2 py-0.5 text-[10px] rounded bg-bg-sunken text-text-secondary\">\n {event.category}\n </span>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n\n {events.length > upcomingEvents.length && (\n <p className=\"text-xs text-text-muted text-center mt-3\">\n {t('bigconsole.widget.calendar.moreEvents', '+{{count}} more events', {\n count: events.length - upcomingEvents.length,\n })}\n </p>\n )}\n </div>\n );\n});\n\nexport default CalendarWidget;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CalendarWidget.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/calendar/CalendarWidget.tsx"],"sourcesContent":["/**\n * CalendarWidget — in-app wrapper around the pure CalendarView (BOFF-7926).\n *\n * The view is i18n-provider-free so the public embed bundle can render it with a\n * static translator (the fe-libs I18nProvider touches localStorage, which throws\n * in third-party iframes when the visitor blocks third-party storage).\n */\n\nimport { type FC, memo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { CalendarView, type CalendarWidgetProps } from './CalendarView';\n\nexport * from './CalendarView';\n\nexport const CalendarWidget: FC<CalendarWidgetProps> = memo(function CalendarWidget(props) {\n const { t } = useI18n();\n return <CalendarView {...props} t={t} />;\n});\n\nexport default CalendarWidget;\n"],"mappings":";;;;;AAcA,IAAa,IAA0C,EAAK,SAAwB,GAAO;CACzF,IAAM,EAAE,SAAM,GAAS;AACvB,QAAO,kBAAC,GAAD;EAAc,GAAI;EAAU;EAAK,CAAA;EACxC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { useCrossFilterContext as e, useWidgetCrossFilter as t } from "../../../contexts/CrossFilterContext.js";
|
|
2
2
|
import "../../../contexts/index.js";
|
|
3
|
-
import n from "./
|
|
4
|
-
import r from "./charts/
|
|
5
|
-
import i from "./charts/
|
|
6
|
-
import a from "./charts/
|
|
7
|
-
import o from "./charts/
|
|
8
|
-
import s from "./charts/
|
|
9
|
-
import c from "./charts/
|
|
10
|
-
import l from "./charts/
|
|
11
|
-
import u from "./
|
|
3
|
+
import n from "./ChartLegend.js";
|
|
4
|
+
import r from "./charts/LineChart.js";
|
|
5
|
+
import i from "./charts/BarChart.js";
|
|
6
|
+
import a from "./charts/AreaChart.js";
|
|
7
|
+
import o from "./charts/PieChart.js";
|
|
8
|
+
import s from "./charts/FunnelChart.js";
|
|
9
|
+
import c from "./charts/ComboChart.js";
|
|
10
|
+
import l from "./charts/WaterfallChart.js";
|
|
11
|
+
import u from "./charts/ScatterChart.js";
|
|
12
12
|
import { memo as d, useCallback as f, useMemo as p, useState as m } from "react";
|
|
13
13
|
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
14
14
|
//#region src/bigconsole/components/widgets/chart/ChartWidget.tsx
|
|
@@ -109,7 +109,7 @@ var _ = [
|
|
|
109
109
|
}), "Clear Filter"]
|
|
110
110
|
})
|
|
111
111
|
}),
|
|
112
|
-
O.legendPosition === "top" && k.length > 0 && /* @__PURE__ */ h(
|
|
112
|
+
O.legendPosition === "top" && k.length > 0 && /* @__PURE__ */ h(n, {
|
|
113
113
|
items: k,
|
|
114
114
|
position: "top",
|
|
115
115
|
onItemClick: A
|
|
@@ -117,50 +117,50 @@ var _ = [
|
|
|
117
117
|
/* @__PURE__ */ h("div", {
|
|
118
118
|
className: "flex-1 min-h-0",
|
|
119
119
|
children: (() => {
|
|
120
|
-
if (M) return /* @__PURE__ */ h(
|
|
120
|
+
if (M) return /* @__PURE__ */ h(c, {
|
|
121
121
|
data: v,
|
|
122
122
|
config: O,
|
|
123
123
|
hiddenSeries: S,
|
|
124
124
|
onDataClick: j
|
|
125
125
|
});
|
|
126
126
|
switch (O.type) {
|
|
127
|
-
case "waterfall": return /* @__PURE__ */ h(
|
|
127
|
+
case "waterfall": return /* @__PURE__ */ h(l, {
|
|
128
128
|
data: v,
|
|
129
129
|
config: O,
|
|
130
130
|
onDataClick: j
|
|
131
131
|
});
|
|
132
|
-
case "scatter": return /* @__PURE__ */ h(
|
|
132
|
+
case "scatter": return /* @__PURE__ */ h(u, {
|
|
133
133
|
data: v,
|
|
134
134
|
config: O,
|
|
135
135
|
onDataClick: j
|
|
136
136
|
});
|
|
137
|
-
case "bar": return /* @__PURE__ */ h(
|
|
137
|
+
case "bar": return /* @__PURE__ */ h(i, {
|
|
138
138
|
data: v,
|
|
139
139
|
config: O,
|
|
140
140
|
hiddenSeries: S,
|
|
141
141
|
onDataClick: j
|
|
142
142
|
});
|
|
143
|
-
case "area": return /* @__PURE__ */ h(
|
|
143
|
+
case "area": return /* @__PURE__ */ h(a, {
|
|
144
144
|
data: v,
|
|
145
145
|
config: O,
|
|
146
146
|
hiddenSeries: S,
|
|
147
147
|
onDataClick: j
|
|
148
148
|
});
|
|
149
|
-
case "pie": return /* @__PURE__ */ h(
|
|
149
|
+
case "pie": return /* @__PURE__ */ h(o, {
|
|
150
150
|
data: v,
|
|
151
151
|
config: O,
|
|
152
152
|
dataKey: x?.valueField || "value",
|
|
153
153
|
nameKey: x?.labelField || "name",
|
|
154
154
|
onDataClick: j
|
|
155
155
|
});
|
|
156
|
-
case "funnel": return /* @__PURE__ */ h(
|
|
156
|
+
case "funnel": return /* @__PURE__ */ h(s, {
|
|
157
157
|
data: v,
|
|
158
158
|
config: O,
|
|
159
159
|
dataKey: x?.valueField || "value",
|
|
160
160
|
nameKey: x?.labelField || "name",
|
|
161
161
|
onDataClick: j
|
|
162
162
|
});
|
|
163
|
-
default: return /* @__PURE__ */ h(
|
|
163
|
+
default: return /* @__PURE__ */ h(r, {
|
|
164
164
|
data: v,
|
|
165
165
|
config: O,
|
|
166
166
|
hiddenSeries: S,
|
|
@@ -169,7 +169,7 @@ var _ = [
|
|
|
169
169
|
}
|
|
170
170
|
})()
|
|
171
171
|
}),
|
|
172
|
-
O.legendPosition === "bottom" && k.length > 0 && /* @__PURE__ */ h(
|
|
172
|
+
O.legendPosition === "bottom" && k.length > 0 && /* @__PURE__ */ h(n, {
|
|
173
173
|
items: k,
|
|
174
174
|
position: "bottom",
|
|
175
175
|
onItemClick: A
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import e from "./
|
|
2
|
-
import t from "./
|
|
3
|
-
import n from "./charts/
|
|
4
|
-
import r from "./charts/
|
|
5
|
-
import i from "./charts/
|
|
6
|
-
import a from "./charts/
|
|
7
|
-
import o from "./
|
|
1
|
+
import e from "./ChartLegend.js";
|
|
2
|
+
import t from "./ChartTooltip.js";
|
|
3
|
+
import n from "./charts/LineChart.js";
|
|
4
|
+
import r from "./charts/BarChart.js";
|
|
5
|
+
import i from "./charts/AreaChart.js";
|
|
6
|
+
import a from "./charts/PieChart.js";
|
|
7
|
+
import o from "./charts/FunnelChart.js";
|
|
8
8
|
import s from "./ChartWidget.js";
|
|
9
9
|
import c from "./ChartConfig.js";
|
|
10
10
|
import "./charts/index.js";
|
|
11
|
-
export {
|
|
11
|
+
export { i as AreaChart, r as BarChart, c as ChartConfig, e as ChartLegend, t as ChartTooltip, s as ChartWidget, o as FunnelChart, n as LineChart, a as PieChart };
|
|
@@ -8,6 +8,11 @@ import "./WidgetErrorBoundary.js";
|
|
|
8
8
|
import "./widget-actions/WidgetActions.js";
|
|
9
9
|
import "./widget-actions/index.js";
|
|
10
10
|
import "./WidgetWrapper.js";
|
|
11
|
+
import "./gauge/GaugeWidget.js";
|
|
12
|
+
import "./progress/ProgressWidget.js";
|
|
13
|
+
import "./heatmap/HeatmapWidget.js";
|
|
14
|
+
import "./retention/RetentionWidget.js";
|
|
15
|
+
import "./timeline/TimelineWidget.js";
|
|
11
16
|
import "./adaptive-card/AdaptiveCardWidget.js";
|
|
12
17
|
import "./adaptive-card/index.js";
|
|
13
18
|
import "./calendar/CalendarWidget.js";
|
|
@@ -18,9 +23,7 @@ import "./custom/CustomWidget.js";
|
|
|
18
23
|
import "./custom/index.js";
|
|
19
24
|
import "./form/FormWidget.js";
|
|
20
25
|
import "./form/index.js";
|
|
21
|
-
import "./gauge/GaugeWidget.js";
|
|
22
26
|
import "./gauge/index.js";
|
|
23
|
-
import "./heatmap/HeatmapWidget.js";
|
|
24
27
|
import "./heatmap/index.js";
|
|
25
28
|
import "./iframe-widget/IframeWidget.js";
|
|
26
29
|
import "./iframe-widget/index.js";
|
|
@@ -34,15 +37,12 @@ import "./map-widget/MapWidget.js";
|
|
|
34
37
|
import "./map-widget/index.js";
|
|
35
38
|
import "./metric-card/MetricCardWidget.js";
|
|
36
39
|
import "./metric-card/index.js";
|
|
37
|
-
import "./progress/ProgressWidget.js";
|
|
38
40
|
import "./progress/index.js";
|
|
39
|
-
import "./retention/RetentionWidget.js";
|
|
40
41
|
import "./retention/index.js";
|
|
41
42
|
import "./table/TableWidget.js";
|
|
42
43
|
import "./table/index.js";
|
|
43
44
|
import "./text-widget/TextWidget.js";
|
|
44
45
|
import "./text-widget/index.js";
|
|
45
|
-
import "./timeline/TimelineWidget.js";
|
|
46
46
|
import "./timeline/index.js";
|
|
47
47
|
import "./webhook-config/WebhookConfigPanel.js";
|
|
48
48
|
import "./webhook-config/index.js";
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { memo as e, useMemo as t } from "react";
|
|
2
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
3
|
+
//#region src/bigconsole/components/widgets/kanban/KanbanView.tsx
|
|
4
|
+
function i(e) {
|
|
5
|
+
switch (e) {
|
|
6
|
+
case "high": return "bg-status-error-bg/20 text-status-error-text";
|
|
7
|
+
case "medium": return "bg-status-warning-bg/20 text-[var(--color-status-warning-text)]";
|
|
8
|
+
case "low": return "bg-status-success-bg/20 text-status-success-text";
|
|
9
|
+
default: return "bg-bg-sunken text-text-secondary";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
var a = [
|
|
13
|
+
"status",
|
|
14
|
+
"state",
|
|
15
|
+
"column",
|
|
16
|
+
"stage",
|
|
17
|
+
"category",
|
|
18
|
+
"phase",
|
|
19
|
+
"group"
|
|
20
|
+
], o = [
|
|
21
|
+
"title",
|
|
22
|
+
"name",
|
|
23
|
+
"summary",
|
|
24
|
+
"label",
|
|
25
|
+
"identifier",
|
|
26
|
+
"id"
|
|
27
|
+
];
|
|
28
|
+
function s(e) {
|
|
29
|
+
return typeof e == "string" && e.length > 0 ? e : void 0;
|
|
30
|
+
}
|
|
31
|
+
function c(e) {
|
|
32
|
+
let t = (e) => e.filter((e) => !!e && typeof e == "object" && !Array.isArray(e));
|
|
33
|
+
if (Array.isArray(e)) return t(e);
|
|
34
|
+
if (e && typeof e == "object") {
|
|
35
|
+
let n = e;
|
|
36
|
+
for (let e of [
|
|
37
|
+
"tasks",
|
|
38
|
+
"rows",
|
|
39
|
+
"items",
|
|
40
|
+
"data",
|
|
41
|
+
"nodes",
|
|
42
|
+
"results",
|
|
43
|
+
"records"
|
|
44
|
+
]) if (Array.isArray(n[e])) return t(n[e]);
|
|
45
|
+
let r = Object.values(n).find((e) => Array.isArray(e));
|
|
46
|
+
if (Array.isArray(r)) return t(r);
|
|
47
|
+
}
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
function l(e, t) {
|
|
51
|
+
for (let n of t) if (n && n in e) return n;
|
|
52
|
+
}
|
|
53
|
+
function u(e) {
|
|
54
|
+
let t = s(e)?.toLowerCase();
|
|
55
|
+
if (t) {
|
|
56
|
+
if (t === "urgent" || t === "high") return "high";
|
|
57
|
+
if (t === "medium" || t === "normal") return "medium";
|
|
58
|
+
if (t === "low") return "low";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function d(e, t) {
|
|
62
|
+
if (e && typeof e == "object" && !Array.isArray(e) && Array.isArray(e.columns)) {
|
|
63
|
+
let t = e;
|
|
64
|
+
return {
|
|
65
|
+
columns: t.columns ?? [],
|
|
66
|
+
tasks: t.tasks ?? []
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
let n = c(e);
|
|
70
|
+
if (n.length === 0) return {
|
|
71
|
+
columns: [],
|
|
72
|
+
tasks: []
|
|
73
|
+
};
|
|
74
|
+
let r = n[0], i = l(r, [
|
|
75
|
+
s(t?.columnField),
|
|
76
|
+
s(t?.groupField),
|
|
77
|
+
s(t?.statusField),
|
|
78
|
+
...a,
|
|
79
|
+
s(t?.xAxisField),
|
|
80
|
+
s(t?.labelField)
|
|
81
|
+
]);
|
|
82
|
+
if (!i) return {
|
|
83
|
+
columns: [],
|
|
84
|
+
tasks: []
|
|
85
|
+
};
|
|
86
|
+
let d = l(r, [
|
|
87
|
+
s(t?.cardTitleField),
|
|
88
|
+
s(t?.titleField),
|
|
89
|
+
...o,
|
|
90
|
+
s(t?.labelField)
|
|
91
|
+
]), f = {}, p = [], m = n.map((e, t) => {
|
|
92
|
+
let n = e[i], r = n == null || n === "" ? "Uncategorized" : String(n);
|
|
93
|
+
r in f || (f[r] = r, p.push(r));
|
|
94
|
+
let a = e.id ?? e.identifier ?? e.key, o = Array.isArray(e.labels) ? e.labels.filter((e) => typeof e == "string") : void 0;
|
|
95
|
+
return {
|
|
96
|
+
id: a == null ? `task-${t}` : String(a),
|
|
97
|
+
title: d && e[d] != null ? String(e[d]) : `Item ${t + 1}`,
|
|
98
|
+
column: r,
|
|
99
|
+
assignee: s(e.assignee),
|
|
100
|
+
priority: u(e.priority ?? e.priorityLabel),
|
|
101
|
+
labels: o && o.length > 0 ? o : void 0
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
columns: p.map((e) => ({
|
|
106
|
+
id: e,
|
|
107
|
+
title: f[e] ?? e
|
|
108
|
+
})),
|
|
109
|
+
tasks: m
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
var f = e(function({ widget: e, data: a, onClick: o, t: s }) {
|
|
113
|
+
let c = e.config, { columns: l, tasks: u } = t(() => d(a, c), [a, c]), f = t(() => {
|
|
114
|
+
let e = {};
|
|
115
|
+
return l.forEach((t) => {
|
|
116
|
+
e[t.id] = u.filter((e) => e.column === t.id);
|
|
117
|
+
}), e;
|
|
118
|
+
}, [l, u]);
|
|
119
|
+
return l.length ? /* @__PURE__ */ n("div", {
|
|
120
|
+
className: "flex h-full p-2 gap-2 overflow-x-auto",
|
|
121
|
+
children: l.map((e) => {
|
|
122
|
+
let t = f[e.id] || [];
|
|
123
|
+
return /* @__PURE__ */ r("div", {
|
|
124
|
+
className: "flex-shrink-0 w-48 flex flex-col bg-bg-sunken/50 rounded-lg",
|
|
125
|
+
children: [/* @__PURE__ */ r("div", {
|
|
126
|
+
className: "flex items-center gap-2 p-2 border-b border-border-default",
|
|
127
|
+
children: [
|
|
128
|
+
/* @__PURE__ */ n("div", {
|
|
129
|
+
className: "w-2 h-2 rounded-full",
|
|
130
|
+
style: { backgroundColor: e.color || "var(--color-text-muted)" }
|
|
131
|
+
}),
|
|
132
|
+
/* @__PURE__ */ n("span", {
|
|
133
|
+
className: "text-xs font-medium text-text-primary truncate",
|
|
134
|
+
children: e.title
|
|
135
|
+
}),
|
|
136
|
+
/* @__PURE__ */ n("span", {
|
|
137
|
+
className: "ml-auto text-xs text-text-muted",
|
|
138
|
+
children: t.length
|
|
139
|
+
})
|
|
140
|
+
]
|
|
141
|
+
}), /* @__PURE__ */ r("div", {
|
|
142
|
+
className: "flex-1 p-2 space-y-2 overflow-y-auto",
|
|
143
|
+
children: [t.map((e) => /* @__PURE__ */ r("div", {
|
|
144
|
+
className: `
|
|
145
|
+
p-2 bg-bg-surface rounded border border-border-default
|
|
146
|
+
${o ? "cursor-pointer hover:border-action-primary-bg" : ""}
|
|
147
|
+
transition-colors
|
|
148
|
+
`,
|
|
149
|
+
onClick: () => o?.(e),
|
|
150
|
+
children: [/* @__PURE__ */ n("p", {
|
|
151
|
+
className: "text-xs font-medium text-text-primary line-clamp-2",
|
|
152
|
+
children: e.title
|
|
153
|
+
}), /* @__PURE__ */ r("div", {
|
|
154
|
+
className: "flex items-center gap-1 mt-2 flex-wrap",
|
|
155
|
+
children: [e.priority && /* @__PURE__ */ n("span", {
|
|
156
|
+
className: `px-1.5 py-0.5 text-[10px] rounded ${i(e.priority)}`,
|
|
157
|
+
children: e.priority
|
|
158
|
+
}), e.assignee && /* @__PURE__ */ n("span", {
|
|
159
|
+
className: "px-1.5 py-0.5 text-[10px] rounded bg-action-primary-bg/10 text-action-primary-text",
|
|
160
|
+
children: e.assignee
|
|
161
|
+
})]
|
|
162
|
+
})]
|
|
163
|
+
}, e.id)), t.length === 0 && /* @__PURE__ */ n("p", {
|
|
164
|
+
className: "text-[10px] text-text-muted text-center py-4",
|
|
165
|
+
children: s("bigconsole.widget.kanban.noTasks", "No tasks")
|
|
166
|
+
})]
|
|
167
|
+
})]
|
|
168
|
+
}, e.id);
|
|
169
|
+
})
|
|
170
|
+
}) : /* @__PURE__ */ n("div", {
|
|
171
|
+
className: "flex items-center justify-center h-full text-text-secondary text-sm",
|
|
172
|
+
children: /* @__PURE__ */ r("div", {
|
|
173
|
+
className: "text-center",
|
|
174
|
+
children: [/* @__PURE__ */ n("svg", {
|
|
175
|
+
className: "w-12 h-12 mx-auto mb-2 text-text-muted",
|
|
176
|
+
fill: "none",
|
|
177
|
+
stroke: "currentColor",
|
|
178
|
+
viewBox: "0 0 24 24",
|
|
179
|
+
children: /* @__PURE__ */ n("path", {
|
|
180
|
+
strokeLinecap: "round",
|
|
181
|
+
strokeLinejoin: "round",
|
|
182
|
+
strokeWidth: 1.5,
|
|
183
|
+
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
|
+
}), /* @__PURE__ */ n("p", { children: s("bigconsole.widget.kanban.emptyState", "No board data") })]
|
|
186
|
+
})
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
//#endregion
|
|
190
|
+
export { f as default };
|
|
191
|
+
|
|
192
|
+
//# sourceMappingURL=KanbanView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KanbanView.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/kanban/KanbanView.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';\nimport type { WidgetTranslateFn } from '../utils/translate';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface KanbanViewProps extends KanbanWidgetProps {\n /** Translator — the app passes useI18n().t; the public embed passes a static fallback translator. */\n t: WidgetTranslateFn;\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-[var(--color-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 KanbanView: FC<KanbanViewProps> = memo(function KanbanView({ widget, data, onClick, t }) {\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 className=\"w-12 h-12 mx-auto mb-2 text-text-muted\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\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-muted\">{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-muted 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 KanbanView;\n"],"mappings":"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"}
|