@fusedashlabs/widgets 0.4.2 → 0.4.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/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAyC5E,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE5D;AAgFD,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAqBrE"}
|
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
import { isAdvancedKpiItem, extractCardsFromKpi } from "./extract.js";
|
|
2
2
|
const EMPTY = { layout: "empty", cards: [], supporting: [] };
|
|
3
3
|
function isRawKpiItem(input) {
|
|
4
|
-
|
|
4
|
+
if (input == null || typeof input !== "object" || Array.isArray(input)) return false;
|
|
5
|
+
const obj = input;
|
|
6
|
+
if (Array.isArray(obj.items) || Array.isArray(obj.kpis)) return false;
|
|
7
|
+
const nested = obj.data;
|
|
8
|
+
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
9
|
+
const inner = nested;
|
|
10
|
+
if (Array.isArray(inner.items) || Array.isArray(inner.kpis)) return false;
|
|
11
|
+
}
|
|
12
|
+
return "column" in obj || "type" in obj || Array.isArray(obj.data);
|
|
13
|
+
}
|
|
14
|
+
function asItemList(input) {
|
|
15
|
+
const obj = input;
|
|
16
|
+
if (Array.isArray(obj.items) && obj.items.every((row) => row && typeof row === "object")) {
|
|
17
|
+
return obj.items;
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(obj.kpis) && obj.kpis.every((row) => row && typeof row === "object")) {
|
|
20
|
+
return obj.kpis;
|
|
21
|
+
}
|
|
22
|
+
for (const candidate of [obj.data, obj.config]) {
|
|
23
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
|
|
24
|
+
const nested = asItemList(candidate);
|
|
25
|
+
if (nested) return nested;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
5
28
|
}
|
|
6
29
|
function isNormalizedModel(input) {
|
|
7
30
|
return Array.isArray(input.cards) && "layout" in input;
|
|
@@ -76,12 +99,8 @@ function normalizeKpiData(input) {
|
|
|
76
99
|
if (typeof input === "object") {
|
|
77
100
|
if (isNormalizedModel(input)) return input;
|
|
78
101
|
const topName = typeof input.name === "string" ? input.name : void 0;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
if (Array.isArray(input.kpis)) {
|
|
83
|
-
return buildFromItems(input.kpis, topName);
|
|
84
|
-
}
|
|
102
|
+
const items = asItemList(input);
|
|
103
|
+
if (items) return buildFromItems(items, topName);
|
|
85
104
|
if (isRawKpiItem(input)) {
|
|
86
105
|
return buildFromItems([input], topName);
|
|
87
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"sourcesContent":["import { extractCardsFromKpi, isAdvancedKpiItem } from './extract.js';\nimport type { KpiWidgetData, KpiWidgetModel, RawKpiItem } from './types.js';\n\nconst EMPTY: KpiWidgetModel = { layout: 'empty', cards: [], supporting: [] };\n\nfunction isRawKpiItem(input: unknown): input is RawKpiItem {\n
|
|
1
|
+
{"version":3,"file":"normalize.js","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"sourcesContent":["import { extractCardsFromKpi, isAdvancedKpiItem } from './extract.js';\nimport type { KpiWidgetData, KpiWidgetModel, RawKpiItem } from './types.js';\n\nconst EMPTY: KpiWidgetModel = { layout: 'empty', cards: [], supporting: [] };\n\nfunction isRawKpiItem(input: unknown): input is RawKpiItem {\n if (input == null || typeof input !== 'object' || Array.isArray(input)) return false;\n const obj = input as Record<string, unknown>;\n if (Array.isArray(obj.items) || Array.isArray(obj.kpis)) return false;\n const nested = obj.data;\n if (nested && typeof nested === 'object' && !Array.isArray(nested)) {\n const inner = nested as Record<string, unknown>;\n if (Array.isArray(inner.items) || Array.isArray(inner.kpis)) return false;\n }\n return 'column' in obj || 'type' in obj || Array.isArray(obj.data);\n}\n\nfunction asItemList(input: object): RawKpiItem[] | null {\n const obj = input as {\n items?: unknown;\n kpis?: unknown;\n data?: unknown;\n config?: unknown;\n };\n if (Array.isArray(obj.items) && obj.items.every((row) => row && typeof row === 'object')) {\n return obj.items as RawKpiItem[];\n }\n if (Array.isArray(obj.kpis) && obj.kpis.every((row) => row && typeof row === 'object')) {\n return obj.kpis as RawKpiItem[];\n }\n for (const candidate of [obj.data, obj.config]) {\n if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) continue;\n const nested = asItemList(candidate);\n if (nested) return nested;\n }\n return null;\n}\n\nfunction isNormalizedModel(input: object): input is KpiWidgetModel {\n return Array.isArray((input as KpiWidgetModel).cards) && 'layout' in input;\n}\n\n/** Client `extractGroupId` — groupName is `{label}-group-kpi-ids-{id}`. */\nexport function extractGroupId(value?: string | null): string {\n return value?.split('-group-kpi-ids-')?.[0] ?? '';\n}\n\nfunction sortItems(items: RawKpiItem[]): RawKpiItem[] {\n return [...items].sort((a, b) => {\n if (isAdvancedKpiItem(a) && !isAdvancedKpiItem(b)) return -1;\n if (!isAdvancedKpiItem(a) && isAdvancedKpiItem(b)) return 1;\n return 0;\n });\n}\n\nfunction footerFrom(items: RawKpiItem[]): Pick<\n KpiWidgetModel,\n 'target' | 'showTimestamp' | 'updatedAt'\n> {\n const first = items[0];\n return {\n target: first?.target,\n showTimestamp: first?.showTimestamp,\n updatedAt: first?.updatedAt,\n };\n}\n\nfunction sectionTitle(\n items: RawKpiItem[],\n advanced: boolean,\n topName?: string,\n): string | undefined {\n if (advanced) return undefined;\n if (items.length === 1) return items[0]?.name;\n const grouped = extractGroupId(items[0]?.groupName);\n if (grouped) return grouped;\n return topName?.trim() || undefined;\n}\n\nfunction buildFromItems(items: RawKpiItem[], topName?: string): KpiWidgetModel {\n if (!items.length) return EMPTY;\n const sorted = sortItems(items);\n const advancedIndex = sorted.findIndex(isAdvancedKpiItem);\n const advanced = advancedIndex >= 0;\n const footer = footerFrom(sorted);\n\n if (advanced) {\n const mainItem = sorted[advancedIndex]!;\n const mainCards = extractCardsFromKpi(mainItem);\n const main = mainCards[0];\n const supporting = sorted\n .filter((_, i) => i !== advancedIndex)\n .flatMap((item) => extractCardsFromKpi(item));\n const viz =\n mainItem.visualisation && typeof mainItem.visualisation === 'object'\n ? (mainItem.visualisation as Record<string, unknown>)\n : null;\n return {\n layout: 'advanced',\n title: sectionTitle(sorted, true, topName),\n cards: main ? [main, ...supporting] : supporting,\n main,\n supporting,\n visualisation: viz,\n ...footer,\n };\n }\n\n const cards = sorted.flatMap((item) => extractCardsFromKpi(item));\n const hideNames = sorted.length === 1 && cards.length >= 1;\n const titledCards = hideNames\n ? cards.map((card) => ({ ...card, hideName: true }))\n : cards;\n const layout: KpiWidgetModel['layout'] =\n titledCards.length === 0 ? 'empty' : titledCards.length === 1 ? 'single' : 'grid';\n\n return {\n layout,\n title: sectionTitle(sorted, false, topName),\n cards: titledCards,\n supporting: [],\n ...footer,\n };\n}\n\n/** Normalize chat / FuseDash KPI payloads into display cards. */\nexport function normalizeKpiData(input: KpiWidgetData): KpiWidgetModel {\n if (!input) return EMPTY;\n\n if (Array.isArray(input)) {\n if (!input.length) return EMPTY;\n return buildFromItems(input);\n }\n\n if (typeof input === 'object') {\n if (isNormalizedModel(input)) return input;\n const topName = typeof (input as { name?: unknown }).name === 'string'\n ? (input as { name: string }).name\n : undefined;\n const items = asItemList(input);\n if (items) return buildFromItems(items, topName);\n if (isRawKpiItem(input)) {\n return buildFromItems([input], topName);\n }\n }\n\n return EMPTY;\n}\n"],"names":[],"mappings":";AAGA,MAAM,QAAwB,EAAE,QAAQ,SAAS,OAAO,CAAA,GAAI,YAAY,GAAC;AAEzE,SAAS,aAAa,OAAqC;AACzD,MAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AAC/E,QAAM,MAAM;AACZ,MAAI,MAAM,QAAQ,IAAI,KAAK,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAG,QAAO;AAChE,QAAM,SAAS,IAAI;AACnB,MAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,GAAG;AAClE,UAAM,QAAQ;AACd,QAAI,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,QAAQ,MAAM,IAAI,EAAG,QAAO;AAAA,EACtE;AACA,SAAO,YAAY,OAAO,UAAU,OAAO,MAAM,QAAQ,IAAI,IAAI;AACnE;AAEA,SAAS,WAAW,OAAoC;AACtD,QAAM,MAAM;AAMZ,MAAI,MAAM,QAAQ,IAAI,KAAK,KAAK,IAAI,MAAM,MAAM,CAAC,QAAQ,OAAO,OAAO,QAAQ,QAAQ,GAAG;AACxF,WAAO,IAAI;AAAA,EACb;AACA,MAAI,MAAM,QAAQ,IAAI,IAAI,KAAK,IAAI,KAAK,MAAM,CAAC,QAAQ,OAAO,OAAO,QAAQ,QAAQ,GAAG;AACtF,WAAO,IAAI;AAAA,EACb;AACA,aAAW,aAAa,CAAC,IAAI,MAAM,IAAI,MAAM,GAAG;AAC9C,QAAI,CAAC,aAAa,OAAO,cAAc,YAAY,MAAM,QAAQ,SAAS,EAAG;AAC7E,UAAM,SAAS,WAAW,SAAS;AACnC,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAwC;AACjE,SAAO,MAAM,QAAS,MAAyB,KAAK,KAAK,YAAY;AACvE;AAGO,SAAS,eAAe,OAA+B;;AAC5D,WAAO,oCAAO,MAAM,uBAAb,mBAAkC,OAAM;AACjD;AAEA,SAAS,UAAU,OAAmC;AACpD,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM;AAC/B,QAAI,kBAAkB,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAG,QAAO;AAC1D,QAAI,CAAC,kBAAkB,CAAC,KAAK,kBAAkB,CAAC,EAAG,QAAO;AAC1D,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,WAAW,OAGlB;AACA,QAAM,QAAQ,MAAM,CAAC;AACrB,SAAO;AAAA,IACL,QAAQ,+BAAO;AAAA,IACf,eAAe,+BAAO;AAAA,IACtB,WAAW,+BAAO;AAAA,EAAA;AAEtB;AAEA,SAAS,aACP,OACA,UACA,SACoB;;AACpB,MAAI,SAAU,QAAO;AACrB,MAAI,MAAM,WAAW,EAAG,SAAO,WAAM,CAAC,MAAP,mBAAU;AACzC,QAAM,UAAU,gBAAe,WAAM,CAAC,MAAP,mBAAU,SAAS;AAClD,MAAI,QAAS,QAAO;AACpB,UAAO,mCAAS,WAAU;AAC5B;AAEA,SAAS,eAAe,OAAqB,SAAkC;AAC7E,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,QAAM,SAAS,UAAU,KAAK;AAC9B,QAAM,gBAAgB,OAAO,UAAU,iBAAiB;AACxD,QAAM,WAAW,iBAAiB;AAClC,QAAM,SAAS,WAAW,MAAM;AAEhC,MAAI,UAAU;AACZ,UAAM,WAAW,OAAO,aAAa;AACrC,UAAM,YAAY,oBAAoB,QAAQ;AAC9C,UAAM,OAAO,UAAU,CAAC;AACxB,UAAM,aAAa,OAChB,OAAO,CAAC,GAAG,MAAM,MAAM,aAAa,EACpC,QAAQ,CAAC,SAAS,oBAAoB,IAAI,CAAC;AAC9C,UAAM,MACJ,SAAS,iBAAiB,OAAO,SAAS,kBAAkB,WACvD,SAAS,gBACV;AACN,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO,aAAa,QAAQ,MAAM,OAAO;AAAA,MACzC,OAAO,OAAO,CAAC,MAAM,GAAG,UAAU,IAAI;AAAA,MACtC;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,GAAG;AAAA,IAAA;AAAA,EAEP;AAEA,QAAM,QAAQ,OAAO,QAAQ,CAAC,SAAS,oBAAoB,IAAI,CAAC;AAChE,QAAM,YAAY,OAAO,WAAW,KAAK,MAAM,UAAU;AACzD,QAAM,cAAc,YAChB,MAAM,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,UAAU,KAAA,EAAO,IACjD;AACJ,QAAM,SACJ,YAAY,WAAW,IAAI,UAAU,YAAY,WAAW,IAAI,WAAW;AAE7E,SAAO;AAAA,IACL;AAAA,IACA,OAAO,aAAa,QAAQ,OAAO,OAAO;AAAA,IAC1C,OAAO;AAAA,IACP,YAAY,CAAA;AAAA,IACZ,GAAG;AAAA,EAAA;AAEP;AAGO,SAAS,iBAAiB,OAAsC;AACrE,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,QAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,WAAO,eAAe,KAAK;AAAA,EAC7B;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,kBAAkB,KAAK,EAAG,QAAO;AACrC,UAAM,UAAU,OAAQ,MAA6B,SAAS,WACzD,MAA2B,OAC5B;AACJ,UAAM,QAAQ,WAAW,KAAK;AAC9B,QAAI,MAAO,QAAO,eAAe,OAAO,OAAO;AAC/C,QAAI,aAAa,KAAK,GAAG;AACvB,aAAO,eAAe,CAAC,KAAK,GAAG,OAAO;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;"}
|