@burdenoff/microfe-bigconsole 2026.1012.3 → 2026.1012.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/bigconsole/assistant/assistantApi.js +5 -5
  2. package/dist/bigconsole/components/builder/inspector/AppearanceSection.js +33 -18
  3. package/dist/bigconsole/components/dashboard/WidgetPalette.js +154 -150
  4. package/dist/bigconsole/components/embed/renderer-manifest.js +12 -0
  5. package/dist/bigconsole/components/widgets/WidgetRegistry.js +122 -1
  6. package/dist/bigconsole/components/widgets/WidgetWrapper.js +227 -224
  7. package/dist/bigconsole/components/widgets/advanced/AdvancedWidgetConfig.d.ts +10 -0
  8. package/dist/bigconsole/components/widgets/advanced/AdvancedWidgetConfig.js +113 -0
  9. package/dist/bigconsole/components/widgets/advanced/AdvancedWidgets.d.ts +10 -0
  10. package/dist/bigconsole/components/widgets/advanced/AdvancedWidgets.js +186 -0
  11. package/dist/bigconsole/components/widgets/advanced/data.d.ts +36 -0
  12. package/dist/bigconsole/components/widgets/advanced/data.js +113 -0
  13. package/dist/bigconsole/components/widgets/advanced/mapData.d.ts +10 -0
  14. package/dist/bigconsole/components/widgets/advanced/mapData.js +22 -0
  15. package/dist/bigconsole/components/widgets/advanced/waterfallData.d.ts +15 -0
  16. package/dist/bigconsole/components/widgets/advanced/waterfallData.js +28 -0
  17. package/dist/bigconsole/components/widgets/chart/charts/WaterfallChart.js +34 -37
  18. package/dist/bigconsole/components/widgets/index.js +1 -1
  19. package/dist/bigconsole/components/widgets/map-widget/MapWidget.d.ts +2 -0
  20. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +64 -63
  21. package/dist/bigconsole/graphql/widgetCapabilities.d.ts +7 -0
  22. package/dist/bigconsole/graphql/widgetCapabilities.js +37 -0
  23. package/dist/bigconsole/hooks/useWidgetCatalog.js +46 -41
  24. package/dist/bigconsole/hooks/useWidgetOperations.js +113 -88
  25. package/dist/bigconsole/renderers/adapters/BigConsoleRenderer.js +8 -5
  26. package/dist/bigconsole/types/index.d.ts +1 -1
  27. package/dist/bigconsole/utils/advancedWidgetCapabilities.d.ts +14 -0
  28. package/dist/bigconsole/utils/advancedWidgetCapabilities.js +36 -0
  29. package/dist/bigconsole/utils/widgetTypeMapping.d.ts +1 -1
  30. package/dist/bigconsole/utils/widgetTypeMapping.js +13 -2
  31. package/dist/generated/wspace-operations.d.ts +61 -2
  32. package/dist/generated/wspace-operations.js +44 -18
  33. package/dist/generated/wspace-types.d.ts +34 -3
  34. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ import { WidgetType } from '../../../types';
2
+
3
+ interface Props {
4
+ type: WidgetType;
5
+ config: Record<string, unknown>;
6
+ onChange: (config: Record<string, unknown>) => void;
7
+ }
8
+ /** Field mappings are data contracts, not source fetches or transform expressions. */
9
+ export declare function AdvancedWidgetConfig({ type, config, onChange }: Props): import("react").JSX.Element;
10
+ export {};
@@ -0,0 +1,113 @@
1
+ import { Fragment as e, jsx as t, jsxs as n } from "react/jsx-runtime";
2
+ import { useI18n as r } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
3
+ //#region src/bigconsole/components/widgets/advanced/AdvancedWidgetConfig.tsx
4
+ function i({ type: i, config: a, onChange: o }) {
5
+ let { t: s } = r();
6
+ return /* @__PURE__ */ n("div", {
7
+ className: "space-y-form-gap",
8
+ children: [
9
+ (i === "map" ? [
10
+ [
11
+ "latitudeField",
12
+ "Latitude field",
13
+ "lat"
14
+ ],
15
+ [
16
+ "longitudeField",
17
+ "Longitude field",
18
+ "lng"
19
+ ],
20
+ [
21
+ "labelField",
22
+ "Label field",
23
+ "name"
24
+ ],
25
+ [
26
+ "valueField",
27
+ "Value field",
28
+ "value"
29
+ ]
30
+ ] : i === "sankey" ? [
31
+ [
32
+ "sourceField",
33
+ "Source field",
34
+ "source"
35
+ ],
36
+ [
37
+ "targetField",
38
+ "Target field",
39
+ "target"
40
+ ],
41
+ [
42
+ "valueField",
43
+ "Value field",
44
+ "value"
45
+ ]
46
+ ] : i === "waterfall" ? [[
47
+ "labelField",
48
+ "Label field",
49
+ "name"
50
+ ], [
51
+ "valueField",
52
+ "Value field",
53
+ "value"
54
+ ]] : [[
55
+ "groupField",
56
+ "Group field",
57
+ "group"
58
+ ], [
59
+ "valueField",
60
+ "Value field",
61
+ "value"
62
+ ]]).map(([e = "", r = "", i = ""]) => /* @__PURE__ */ n("label", {
63
+ className: "block text-sm text-text-primary",
64
+ children: [s(`bigconsole.widget.advanced.${e}`, r), /* @__PURE__ */ t("input", {
65
+ className: "mt-1 w-full rounded-md border border-border-default bg-bg-base px-3 py-2",
66
+ value: typeof a[e] == "string" ? a[e] : i,
67
+ onChange: (t) => o({
68
+ ...a,
69
+ [e]: t.target.value
70
+ })
71
+ })]
72
+ }, e)),
73
+ i === "box_plot" && /* @__PURE__ */ n(e, { children: [/* @__PURE__ */ n("label", {
74
+ className: "block text-sm text-text-primary",
75
+ children: [s("bigconsole.widget.boxPlot.mode", "Input format"), /* @__PURE__ */ n("select", {
76
+ className: "mt-1 w-full rounded-md border border-border-default bg-bg-base px-3 py-2",
77
+ value: a.mode === "summary" ? "summary" : "observations",
78
+ onChange: (e) => o({
79
+ ...a,
80
+ mode: e.target.value
81
+ }),
82
+ children: [/* @__PURE__ */ t("option", {
83
+ value: "observations",
84
+ children: s("bigconsole.widget.boxPlot.observations", "Individual observations")
85
+ }), /* @__PURE__ */ t("option", {
86
+ value: "summary",
87
+ children: s("bigconsole.widget.boxPlot.summary", "Five-number summaries")
88
+ })]
89
+ })]
90
+ }), /* @__PURE__ */ t("p", {
91
+ className: "text-xs text-text-secondary",
92
+ children: s("bigconsole.widget.boxPlot.summaryHelp", "Summary rows require min, q1, median, q3 and max. Observation rows require the configured group and numeric value fields.")
93
+ })] }),
94
+ i === "waterfall" && /* @__PURE__ */ n("label", {
95
+ className: "flex items-center gap-2 text-sm text-text-primary",
96
+ children: [/* @__PURE__ */ t("input", {
97
+ type: "checkbox",
98
+ checked: a.showTotal !== !1,
99
+ onChange: (e) => o({
100
+ ...a,
101
+ showTotal: e.target.checked
102
+ })
103
+ }), s("bigconsole.widget.waterfall.showTotal", "Show cumulative total")]
104
+ }),
105
+ i === "sankey" && /* @__PURE__ */ t("p", {
106
+ className: "text-xs text-text-secondary",
107
+ children: s("bigconsole.widget.sankey.inputHelp", "Each row connects a source to a target with a nonnegative numeric value. Circular flows cannot be displayed.")
108
+ })
109
+ ]
110
+ });
111
+ }
112
+ //#endregion
113
+ export { i as AdvancedWidgetConfig };
@@ -0,0 +1,10 @@
1
+ import { Widget } from '../../../types';
2
+
3
+ interface Props {
4
+ widget: Widget;
5
+ data?: unknown;
6
+ }
7
+ export declare const SankeyWidget: import('react').NamedExoticComponent<Props>;
8
+ export declare const BoxPlotWidget: import('react').NamedExoticComponent<Props>;
9
+ export declare const WaterfallWidget: import('react').NamedExoticComponent<Props>;
10
+ export {};
@@ -0,0 +1,186 @@
1
+ import e from "../chart/ChartWidget.js";
2
+ import { normalizeBoxPlot as t, normalizeSankey as n } from "./data.js";
3
+ import { memo as r, useMemo as i } from "react";
4
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
5
+ import { useI18n as s } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
6
+ import { ResponsiveContainer as c, Sankey as l, Tooltip as u } from "recharts";
7
+ //#region src/bigconsole/components/widgets/advanced/AdvancedWidgets.tsx
8
+ function d(e) {
9
+ try {
10
+ return { data: e() };
11
+ } catch (e) {
12
+ return { error: e instanceof Error ? e.message : "Invalid chart data." };
13
+ }
14
+ }
15
+ function f({ message: e, error: t = !1 }) {
16
+ return /* @__PURE__ */ a("div", {
17
+ role: t ? "alert" : "status",
18
+ className: "h-full flex items-center justify-center p-4 text-sm text-secondary",
19
+ children: e
20
+ });
21
+ }
22
+ function p({ x: e, y: t, width: n, height: r, payload: i }) {
23
+ return /* @__PURE__ */ o("g", { children: [/* @__PURE__ */ a("rect", {
24
+ x: e,
25
+ y: t,
26
+ width: n,
27
+ height: r,
28
+ fill: "var(--color-chart-1)"
29
+ }), /* @__PURE__ */ o("text", {
30
+ x: e + n + 6,
31
+ y: t + r / 2,
32
+ dominantBaseline: "middle",
33
+ fill: "var(--color-text-primary)",
34
+ fontSize: 12,
35
+ children: [i.name.length > 24 ? i.name.slice(0, 23) + "…" : i.name, /* @__PURE__ */ a("title", { children: i.name })]
36
+ })] });
37
+ }
38
+ var m = r(function({ widget: e, data: t = [] }) {
39
+ let { t: r } = s(), m = e.config, h = i(() => d(() => n(t, m)), [t, m]);
40
+ return h.error ? /* @__PURE__ */ a(f, {
41
+ message: h.error,
42
+ error: !0
43
+ }) : h.data?.links.length ? /* @__PURE__ */ o("div", {
44
+ role: "img",
45
+ "aria-label": `${r("bigconsole.widget.sankey.label", "Sankey flow chart")}: ${e.title}`,
46
+ className: "h-full w-full",
47
+ children: [/* @__PURE__ */ a(c, {
48
+ width: "100%",
49
+ height: "100%",
50
+ children: /* @__PURE__ */ a(l, {
51
+ data: h.data,
52
+ nodePadding: 24,
53
+ nodeWidth: 12,
54
+ margin: {
55
+ top: 20,
56
+ bottom: 20,
57
+ left: 100,
58
+ right: 100
59
+ },
60
+ link: {
61
+ stroke: "var(--color-chart-1)",
62
+ strokeOpacity: .35
63
+ },
64
+ node: p,
65
+ children: /* @__PURE__ */ a(u, {})
66
+ })
67
+ }), /* @__PURE__ */ a("span", {
68
+ className: "sr-only",
69
+ children: h.data.links.map((e) => `${h.data.nodes[e.source]?.name} to ${h.data.nodes[e.target]?.name}: ${e.value}`).join("; ")
70
+ })]
71
+ }) : /* @__PURE__ */ a(f, { message: r("bigconsole.widget.sankey.empty", "No positive flows to display.") });
72
+ }), h = r(function({ widget: e, data: n = [] }) {
73
+ let { t: r } = s(), c = e.config, l = i(() => d(() => t(n, c)), [n, c]);
74
+ if (l.error) return /* @__PURE__ */ a(f, {
75
+ message: l.error,
76
+ error: !0
77
+ });
78
+ if (!l.data?.length) return /* @__PURE__ */ a(f, { message: r("bigconsole.widget.boxPlot.empty", "No observations to display.") });
79
+ let u = l.data, p = u.flatMap((e) => [
80
+ e.min,
81
+ e.max,
82
+ ...e.outliers
83
+ ]), m = p.reduce((e, t) => Math.min(e, t), Infinity), h = p.reduce((e, t) => Math.max(e, t), -Infinity), g = h / 2 - m / 2 || 1, _ = (e) => 140 + (e / 2 - m / 2) / g * 610, v = Math.max(160, u.length * 65 + 55);
84
+ return /* @__PURE__ */ o("svg", {
85
+ role: "img",
86
+ "aria-label": `${r("bigconsole.widget.boxPlot.label", "Box plot")}: ${e.title}`,
87
+ viewBox: `0 0 800 ${v}`,
88
+ className: "h-full w-full",
89
+ preserveAspectRatio: "xMidYMid meet",
90
+ children: [
91
+ /* @__PURE__ */ a("title", { children: e.title }),
92
+ /* @__PURE__ */ a("desc", { children: r("bigconsole.widget.boxPlot.description", "Boxes show the first and third quartiles with the median. Whiskers use the 1.5 interquartile-range rule; circles show outliers.") }),
93
+ u.map((e, t) => {
94
+ let n = t * 65 + 40;
95
+ return /* @__PURE__ */ o("g", { children: [
96
+ /* @__PURE__ */ a("title", { children: `${e.label}: min ${e.min}, Q1 ${e.q1}, median ${e.median}, Q3 ${e.q3}, max ${e.max}${e.count === void 0 ? "" : `; ${e.count} observations`}` }),
97
+ /* @__PURE__ */ a("text", {
98
+ x: 130,
99
+ y: n + 5,
100
+ textAnchor: "end",
101
+ fill: "var(--color-text-secondary)",
102
+ fontSize: 13,
103
+ children: e.label
104
+ }),
105
+ /* @__PURE__ */ a("line", {
106
+ x1: _(e.min),
107
+ x2: _(e.max),
108
+ y1: n,
109
+ y2: n,
110
+ stroke: "var(--color-chart-1)"
111
+ }),
112
+ /* @__PURE__ */ a("line", {
113
+ x1: _(e.min),
114
+ x2: _(e.min),
115
+ y1: n - 10,
116
+ y2: n + 10,
117
+ stroke: "var(--color-chart-1)"
118
+ }),
119
+ /* @__PURE__ */ a("line", {
120
+ x1: _(e.max),
121
+ x2: _(e.max),
122
+ y1: n - 10,
123
+ y2: n + 10,
124
+ stroke: "var(--color-chart-1)"
125
+ }),
126
+ /* @__PURE__ */ a("rect", {
127
+ x: _(e.q1),
128
+ y: n - 16,
129
+ width: Math.max(1, _(e.q3) - _(e.q1)),
130
+ height: 32,
131
+ fill: "var(--color-chart-1)",
132
+ fillOpacity: .25,
133
+ stroke: "var(--color-chart-1)"
134
+ }),
135
+ /* @__PURE__ */ a("line", {
136
+ x1: _(e.median),
137
+ x2: _(e.median),
138
+ y1: n - 16,
139
+ y2: n + 16,
140
+ stroke: "var(--color-text-primary)",
141
+ strokeWidth: 2
142
+ }),
143
+ e.outliers.map((e, t) => /* @__PURE__ */ a("circle", {
144
+ cx: _(e),
145
+ cy: n,
146
+ r: 3,
147
+ fill: "var(--color-chart-2)",
148
+ children: /* @__PURE__ */ a("title", { children: `${r("bigconsole.widget.boxPlot.outlier", "Outlier")}: ${e}` })
149
+ }, t))
150
+ ] }, `${e.label}-${t}`);
151
+ }),
152
+ /* @__PURE__ */ a("text", {
153
+ x: 140,
154
+ y: v - 12,
155
+ fill: "var(--color-text-secondary)",
156
+ fontSize: 12,
157
+ children: m
158
+ }),
159
+ /* @__PURE__ */ a("text", {
160
+ x: 750,
161
+ y: v - 12,
162
+ textAnchor: "end",
163
+ fill: "var(--color-text-secondary)",
164
+ fontSize: 12,
165
+ children: h
166
+ })
167
+ ]
168
+ });
169
+ }), g = r(function({ widget: t, data: n = [] }) {
170
+ let { t: r } = s(), o = i(() => ({
171
+ ...t,
172
+ config: {
173
+ ...t.config,
174
+ chartType: "waterfall"
175
+ }
176
+ }), [t]), c = n && typeof n == "object" && !Array.isArray(n) && "rows" in n ? n.rows : n;
177
+ return Array.isArray(c) ? /* @__PURE__ */ a(e, {
178
+ widget: o,
179
+ data: c
180
+ }) : /* @__PURE__ */ a(f, {
181
+ message: r("bigconsole.widget.waterfall.invalidData", "Waterfall data must be an array of rows."),
182
+ error: !0
183
+ });
184
+ });
185
+ //#endregion
186
+ export { h as BoxPlotWidget, m as SankeyWidget, g as WaterfallWidget };
@@ -0,0 +1,36 @@
1
+ /** Normalizers operate only on rows already supplied by the governed widget data hub. */
2
+ export interface SankeyNode {
3
+ name: string;
4
+ }
5
+ export interface SankeyLink {
6
+ source: number;
7
+ target: number;
8
+ value: number;
9
+ }
10
+ export interface SankeyData {
11
+ nodes: SankeyNode[];
12
+ links: SankeyLink[];
13
+ }
14
+ export interface SankeyFields {
15
+ sourceField?: string;
16
+ targetField?: string;
17
+ valueField?: string;
18
+ }
19
+ export interface BoxPlotFields {
20
+ groupField?: string;
21
+ valueField?: string;
22
+ mode?: 'observations' | 'summary';
23
+ }
24
+ export interface BoxPlotRow {
25
+ label: string;
26
+ min: number;
27
+ q1: number;
28
+ median: number;
29
+ q3: number;
30
+ max: number;
31
+ outliers: number[];
32
+ count?: number;
33
+ }
34
+ /** Recharts Sankey requires a directed acyclic graph, so reject cycles before layout. */
35
+ export declare function normalizeSankey(data: unknown, fields?: SankeyFields): SankeyData;
36
+ export declare function normalizeBoxPlot(data: unknown, fields?: BoxPlotFields): BoxPlotRow[];
@@ -0,0 +1,113 @@
1
+ //#region src/bigconsole/components/widgets/advanced/data.ts
2
+ function e(e) {
3
+ if (e && typeof e == "object" && !Array.isArray(e) && "rows" in e && (e = e.rows), !Array.isArray(e)) throw Error("Expected an array of data rows.");
4
+ if (e.length > 1e5) throw Error("Too many chart rows; aggregate the source before displaying it.");
5
+ if (!e.every((e) => typeof e == "object" && !!e && !Array.isArray(e))) throw Error("Every data row must be an object.");
6
+ return e;
7
+ }
8
+ function t(e) {
9
+ return typeof e == "number" && Number.isFinite(e);
10
+ }
11
+ function n(e) {
12
+ if (typeof e != "string" && typeof e != "number") throw Error("Labels must be text or numbers.");
13
+ let t = String(e).trim();
14
+ if (!t) throw Error("Labels cannot be empty.");
15
+ return t;
16
+ }
17
+ function r(r, i = {}) {
18
+ let a = i.sourceField || "source", o = i.targetField || "target", s = i.valueField || "value", c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map();
19
+ function u(e) {
20
+ let t = c.get(e);
21
+ if (t !== void 0) return t;
22
+ let n = c.size;
23
+ if (n >= 200) throw Error("Too many Sankey nodes; aggregate categories before displaying them.");
24
+ return c.set(e, n), n;
25
+ }
26
+ for (let i of e(r)) {
27
+ let e = u(n(i[a])), r = u(n(i[o])), c = i[s];
28
+ if (!t(c) || c < 0) throw Error("Flow values must be finite nonnegative numbers.");
29
+ if (e === r) throw Error("A flow cannot connect a node to itself.");
30
+ let d = `${e}:${r}`, f = l.get(d), p = (f?.value ?? 0) + c;
31
+ if (!Number.isFinite(p)) throw Error("Combined flow value is too large.");
32
+ if (!f && l.size >= 1e3) throw Error("Too many Sankey links; aggregate flows before displaying them.");
33
+ l.set(d, {
34
+ source: e,
35
+ target: r,
36
+ value: p
37
+ });
38
+ }
39
+ let d = [...l.values()].filter((e) => e.value > 0), f = /* @__PURE__ */ new Map();
40
+ for (let e of d) for (let t of [`${e.source}:out`, `${e.target}:in`]) {
41
+ let n = (f.get(t) ?? 0) + e.value;
42
+ if (!Number.isFinite(n)) throw Error("Total flow value is too large.");
43
+ f.set(t, n);
44
+ }
45
+ let p = Array.from({ length: c.size }, () => /* @__PURE__ */ new Set()), m = Array.from({ length: c.size }, () => 0);
46
+ for (let e of d) p[e.source]?.add(e.target), m[e.target] = (m[e.target] ?? 0) + 1;
47
+ let h = m.flatMap((e, t) => e === 0 ? [t] : []), g = 0;
48
+ for (let e = 0; e < h.length; e++) {
49
+ let t = h[e];
50
+ if (t !== void 0) {
51
+ g++;
52
+ for (let e of p[t] ?? []) m[e] = (m[e] ?? 0) - 1, m[e] === 0 && h.push(e);
53
+ }
54
+ }
55
+ if (g !== c.size) throw Error("Sankey data must not contain cycles.");
56
+ return {
57
+ nodes: [...c.keys()].map((e) => ({ name: e })),
58
+ links: d
59
+ };
60
+ }
61
+ function i(e, t) {
62
+ let n = (e.length - 1) * t, r = Math.floor(n), i = e[r] ?? 0, a = n - r;
63
+ return i * (1 - a) + (e[r + 1] ?? i) * a;
64
+ }
65
+ function a(r, a = {}) {
66
+ let o = a.groupField || "group", s = a.valueField || "value", c = e(r);
67
+ if (a.mode === "summary" && c.length > 50) throw Error("Too many box plot groups; filter to 50 groups or fewer.");
68
+ if (a.mode === "summary") return c.map((e) => {
69
+ let r = [
70
+ e.min,
71
+ e.q1,
72
+ e.median,
73
+ e.q3,
74
+ e.max
75
+ ];
76
+ if (!r.every(t)) throw Error("Box plot summaries require five finite numeric values.");
77
+ if (r.some((e, t) => t > 0 && e < (r[t - 1] ?? e))) throw Error("Box plot summary values must satisfy min ≤ q1 ≤ median ≤ q3 ≤ max.");
78
+ let [i = 0, a = 0, s = 0, c = 0, l = 0] = r;
79
+ return {
80
+ label: n(e[o]),
81
+ min: i,
82
+ q1: a,
83
+ median: s,
84
+ q3: c,
85
+ max: l,
86
+ outliers: []
87
+ };
88
+ });
89
+ let l = /* @__PURE__ */ new Map();
90
+ for (let e of c) {
91
+ let r = n(e[o]), i = e[s];
92
+ if (!t(i)) throw Error("Box plot observations must be finite numbers.");
93
+ let a = l.get(r) ?? [];
94
+ if (a.push(i), !l.has(r) && l.size >= 50) throw Error("Too many box plot groups; filter to 50 groups or fewer.");
95
+ l.set(r, a);
96
+ }
97
+ return [...l].map(([e, t]) => {
98
+ t.sort((e, t) => e - t);
99
+ let n = i(t, .25), r = i(t, .5), a = i(t, .75), o = a - n, s = t.filter((e) => e >= n - 1.5 * o && e <= a + 1.5 * o);
100
+ return {
101
+ label: e,
102
+ min: s[0] ?? n,
103
+ q1: n,
104
+ median: r,
105
+ q3: a,
106
+ max: s[s.length - 1] ?? a,
107
+ outliers: t.filter((e) => e < n - 1.5 * o || e > a + 1.5 * o),
108
+ count: t.length
109
+ };
110
+ });
111
+ }
112
+ //#endregion
113
+ export { a as normalizeBoxPlot, r as normalizeSankey };
@@ -0,0 +1,10 @@
1
+ export interface BoundMapMarker {
2
+ name: string;
3
+ lat: number;
4
+ lng: number;
5
+ value?: number;
6
+ popup?: string;
7
+ color?: string;
8
+ }
9
+ /** Accept standard marker rows or configured raw source fields, without inventing coordinates. */
10
+ export declare function normalizeMapMarkers(input: unknown, config?: Record<string, unknown>): BoundMapMarker[];
@@ -0,0 +1,22 @@
1
+ //#region src/bigconsole/components/widgets/advanced/mapData.ts
2
+ function e(e, t = {}) {
3
+ if (!Array.isArray(e)) return [];
4
+ let n = typeof t.latitudeField == "string" ? t.latitudeField : "lat", r = typeof t.longitudeField == "string" ? t.longitudeField : "lng", i = typeof t.labelField == "string" ? t.labelField : "name", a = typeof t.valueField == "string" ? t.valueField : "value", o = [];
5
+ for (let t of e) {
6
+ if (!t || typeof t != "object" || Array.isArray(t)) continue;
7
+ let e = t[n], s = t[r];
8
+ if (typeof e != "number" || typeof s != "number" || !Number.isFinite(e) || !Number.isFinite(s) || Math.abs(e) > 90 || Math.abs(s) > 180) continue;
9
+ let c = t[i], l = t[a];
10
+ o.push({
11
+ name: typeof c == "string" || typeof c == "number" ? String(c) : "",
12
+ lat: e,
13
+ lng: s,
14
+ value: typeof l == "number" && Number.isFinite(l) ? l : void 0,
15
+ popup: typeof t.popup == "string" ? t.popup : void 0,
16
+ color: typeof t.color == "string" ? t.color : void 0
17
+ });
18
+ }
19
+ return o;
20
+ }
21
+ //#endregion
22
+ export { e as normalizeMapMarkers };
@@ -0,0 +1,15 @@
1
+ export interface WaterfallRow {
2
+ name: string;
3
+ range: [number, number];
4
+ delta: number;
5
+ cumulative: number;
6
+ isTotal: boolean;
7
+ sign: 'up' | 'down' | 'total';
8
+ original?: Record<string, unknown>;
9
+ }
10
+ export declare function buildWaterfallRows(data: Record<string, unknown>[], options?: {
11
+ labelField?: string;
12
+ valueField?: string;
13
+ showTotal?: boolean;
14
+ totalLabel?: string;
15
+ }): WaterfallRow[];
@@ -0,0 +1,28 @@
1
+ //#region src/bigconsole/components/widgets/advanced/waterfallData.ts
2
+ function e(e, t = {}) {
3
+ let n = t.labelField || "name", r = t.valueField || "value", i = 0, a = e.map((e) => {
4
+ let t = e[r], a = typeof t == "number" ? t : typeof t == "string" && t.trim() ? Number(t) : NaN;
5
+ if (!Number.isFinite(a)) throw Error("Waterfall changes must be finite numbers.");
6
+ let o = i;
7
+ if (i += a, !Number.isFinite(i)) throw Error("The cumulative waterfall value is too large.");
8
+ return {
9
+ name: String(e[n] ?? ""),
10
+ range: [Math.min(o, i), Math.max(o, i)],
11
+ delta: a,
12
+ cumulative: i,
13
+ isTotal: !1,
14
+ sign: a >= 0 ? "up" : "down",
15
+ original: e
16
+ };
17
+ });
18
+ return t.showTotal && a.length && a.push({
19
+ name: t.totalLabel || "Total",
20
+ range: [Math.min(0, i), Math.max(0, i)],
21
+ delta: i,
22
+ cumulative: i,
23
+ isTotal: !0,
24
+ sign: "total"
25
+ }), a;
26
+ }
27
+ //#endregion
28
+ export { e as buildWaterfallRows };
@@ -1,46 +1,46 @@
1
- import e from "../ChartTooltip.js";
2
- import { buildReferenceElements as t } from "./referenceElements.js";
1
+ import { buildReferenceElements as e } from "./referenceElements.js";
2
+ import { buildWaterfallRows as t } from "../../advanced/waterfallData.js";
3
3
  import { memo as n, useMemo as r } from "react";
4
4
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
5
  import { Bar as o, BarChart as s, CartesianGrid as c, Cell as l, ResponsiveContainer as u, Tooltip as d, XAxis as f, YAxis as p } from "recharts";
6
6
  //#region src/bigconsole/components/widgets/chart/charts/WaterfallChart.tsx
7
7
  var m = "var(--color-status-success)", h = "var(--color-status-error)", g = "var(--color-chart-1)", _ = n(function({ data: n = [], config: _, onDataClick: v }) {
8
8
  let y = _.labelField || _.xAxisKey || "name", b = _.valueField || "value", x = r(() => {
9
- if (!n.length) return [];
10
- let e = 0, t = n.map((t) => {
11
- let n = typeof t[b] == "number" ? t[b] : Number(t[b]) || 0, r = n >= 0 ? e : e + n;
12
- return e += n, {
13
- name: String(t[y] ?? ""),
14
- base: r,
15
- delta: Math.abs(n),
16
- cumulative: e,
17
- isTotal: !1,
18
- sign: n >= 0 ? "up" : "down"
9
+ try {
10
+ return {
11
+ rows: t(n, {
12
+ labelField: y,
13
+ valueField: b,
14
+ showTotal: _.showTotal,
15
+ totalLabel: _.totalLabel
16
+ }),
17
+ error: void 0
18
+ };
19
+ } catch (e) {
20
+ return {
21
+ rows: [],
22
+ error: e instanceof Error ? e.message : "Invalid waterfall data."
19
23
  };
20
- });
21
- return _.showTotal && t.push({
22
- name: _.totalLabel || "Total",
23
- base: 0,
24
- delta: e,
25
- cumulative: e,
26
- isTotal: !0,
27
- sign: "total"
28
- }), t;
24
+ }
29
25
  }, [
30
26
  n,
31
27
  y,
32
28
  b,
33
29
  _.showTotal,
34
30
  _.totalLabel
35
- ]), S = (e) => typeof e == "number" ? new Intl.NumberFormat("en-US", {
31
+ ]), S = x.rows, C = (e) => typeof e == "number" ? new Intl.NumberFormat("en-US", {
36
32
  notation: Math.abs(e) >= 1e4 ? "compact" : "standard",
37
33
  maximumFractionDigits: 2
38
34
  }).format(e) : String(e);
39
- return x.length ? /* @__PURE__ */ i(u, {
35
+ return x.error ? /* @__PURE__ */ i("div", {
36
+ role: "alert",
37
+ className: "p-4 text-sm text-secondary",
38
+ children: x.error
39
+ }) : S.length ? /* @__PURE__ */ i(u, {
40
40
  width: "100%",
41
41
  height: "100%",
42
42
  children: /* @__PURE__ */ a(s, {
43
- data: x,
43
+ data: S,
44
44
  margin: {
45
45
  top: 10,
46
46
  right: 10,
@@ -48,7 +48,10 @@ var m = "var(--color-status-success)", h = "var(--color-status-error)", g = "var
48
48
  bottom: 0
49
49
  },
50
50
  onClick: (e) => {
51
- e?.activePayload?.[0] && v && v(e.activePayload[0].payload, e.activeTooltipIndex || 0);
51
+ if (e?.activePayload?.[0] && v) {
52
+ let t = e.activePayload[0].payload;
53
+ t.original && v(t.original, e.activeTooltipIndex || 0);
54
+ }
52
55
  },
53
56
  children: [
54
57
  _.showGrid !== !1 && /* @__PURE__ */ i(c, {
@@ -73,25 +76,18 @@ var m = "var(--color-status-success)", h = "var(--color-status-error)", g = "var
73
76
  },
74
77
  tickLine: { stroke: "var(--color-border-default)" },
75
78
  axisLine: { stroke: "var(--color-border-default)" },
76
- tickFormatter: S
79
+ tickFormatter: C
77
80
  }),
78
81
  /* @__PURE__ */ i(d, {
79
- content: /* @__PURE__ */ i(e, { valueFormatter: S }),
82
+ formatter: (e, t, n) => C(typeof n.payload?.delta == "number" ? n.payload.delta : 0),
80
83
  cursor: {
81
84
  fill: "var(--color-bg-muted)",
82
85
  opacity: .5
83
86
  }
84
87
  }),
85
- t(_.referenceLines),
86
- /* @__PURE__ */ i(o, {
87
- dataKey: "base",
88
- stackId: "wf",
89
- fill: "transparent",
90
- isAnimationActive: !1
91
- }),
88
+ e(_.referenceLines),
92
89
  /* @__PURE__ */ i(o, {
93
- dataKey: "delta",
94
- stackId: "wf",
90
+ dataKey: "range",
95
91
  radius: [
96
92
  4,
97
93
  4,
@@ -99,7 +95,8 @@ var m = "var(--color-status-success)", h = "var(--color-status-error)", g = "var
99
95
  0
100
96
  ],
101
97
  name: "Change",
102
- children: x.map((e, t) => /* @__PURE__ */ i(l, { fill: e.sign === "total" ? g : e.sign === "up" ? m : h }, t))
98
+ isAnimationActive: !1,
99
+ children: S.map((e, t) => /* @__PURE__ */ i(l, { fill: e.sign === "total" ? g : e.sign === "up" ? m : h }, t))
103
100
  })
104
101
  ]
105
102
  })