@burdenoff/microfe-bigconsole 2026.925.2 → 2026.928.2
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/embed/EmbedWidgetRenderer.js +43 -13
- package/dist/bigconsole/components/embed/EmbedWidgetRenderer.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/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/package.json +1 -1
|
@@ -68,7 +68,19 @@ function l(e) {
|
|
|
68
68
|
function u(e) {
|
|
69
69
|
return typeof e == "number" && Number.isFinite(e);
|
|
70
70
|
}
|
|
71
|
+
var d = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i, f = /^(?:rgb|rgba|hsl|hsla)\(\s*[0-9.%\s,/deg-]+\)$/i, p = /^var\(--[a-z0-9-]+\)$/i;
|
|
72
|
+
function m(e) {
|
|
73
|
+
if (typeof e != "string") return;
|
|
74
|
+
let t = e.trim();
|
|
75
|
+
if (!(t.length === 0 || t.length > 64)) return d.test(t) || f.test(t) || p.test(t) ? t : void 0;
|
|
76
|
+
}
|
|
77
|
+
function h(e, t = 500) {
|
|
78
|
+
return typeof e == "string" && e.length > 0 ? e.slice(0, t) : void 0;
|
|
79
|
+
}
|
|
80
|
+
function g(e, t = 5e3) {
|
|
81
|
+
return n(e).slice(0, t).filter((e) => !!e && typeof e == "object" && !Array.isArray(e));
|
|
82
|
+
}
|
|
71
83
|
//#endregion
|
|
72
|
-
export { n as asArray, t as asFiniteNumber, r as asRecord, e as asString, l as formatCell, a as formatNumber, u as isNumeric };
|
|
84
|
+
export { n as asArray, t as asFiniteNumber, h as asOptionalString, r as asRecord, g as asRecordArray, e as asString, i as displayValue, l as formatCell, a as formatNumber, u as isNumeric, m as safeColor };
|
|
73
85
|
|
|
74
86
|
//# sourceMappingURL=shared.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","names":[],"sources":["../../../../../src/bigconsole/components/embed/widgets/shared.ts"],"sourcesContent":["/**\n * Defensive value coercion for embed widget renderers (BOFF-2986).\n *\n * The render model is sanitized by the publication builder, but the renderer\n * re-narrows every value it reads: an embedded widget is anonymous, untrusted\n * customer-facing surface, so we never assume a field is the type we expect.\n */\n\nexport function asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nexport function asFiniteNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim() !== '') {\n const n = Number(value);\n if (Number.isFinite(n)) return n;\n }\n return null;\n}\n\nexport function asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\n/**\n * Render an arbitrary cell value as a display string. Objects/arrays collapse to\n * an empty string rather than `[object Object]`, so no internal structure leaks.\n */\nexport function displayValue(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number') return Number.isFinite(value) ? String(value) : '';\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n return '';\n}\n\n/**\n * Format a number with the widget's optional format hints, safely — mirrors the\n * in-app MetricCardWidget `formatValue` so embedded numbers read identically\n * (thousands separators, currency, percentage, compact notation) instead of a\n * bare `1284530.5`. `config.format` is the same enum the in-app widgets use.\n */\nexport function formatNumber(value: number, config: Record<string, unknown>): string {\n const format = asString(config.format, 'number');\n const decimals = asFiniteNumber(config.decimals);\n const prefix = asString(config.prefix);\n const suffix = asString(config.suffix);\n\n let formatted: string;\n switch (format) {\n case 'currency': {\n // `Intl.NumberFormat` throws `RangeError` on a currency code that isn't a\n // well-formed ISO 4217 string (e.g. '', 'US', 'ABCD'). This is untrusted\n // customer-facing config, so validate the shape and fall back to USD;\n // a defensive try/catch keeps a malformed value from crashing the widget.\n const currency = resolveCurrencyCode(config.currency);\n const maximumFractionDigits = decimals !== null ? clampDecimals(decimals) : 2;\n try {\n formatted = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency,\n minimumFractionDigits: 0,\n maximumFractionDigits,\n }).format(value);\n } catch {\n formatted = new Intl.NumberFormat('en-US', { maximumFractionDigits }).format(value);\n }\n break;\n }\n case 'percentage': {\n const pctDecimals = decimals !== null ? clampDecimals(decimals) : 1;\n formatted = `${new Intl.NumberFormat('en-US', {\n minimumFractionDigits: pctDecimals,\n maximumFractionDigits: pctDecimals,\n }).format(value * 100)}%`;\n break;\n }\n case 'compact':\n formatted = new Intl.NumberFormat('en-US', {\n notation: 'compact',\n maximumFractionDigits: decimals !== null ? clampDecimals(decimals) : 1,\n }).format(value);\n break;\n case 'number':\n default:\n formatted = new Intl.NumberFormat('en-US', {\n maximumFractionDigits: decimals !== null ? clampDecimals(decimals) : 2,\n }).format(value);\n }\n\n // `currency` already carries its own symbol; only apply an explicit prefix to\n // the other formats so we never render e.g. \"$$1,284,530\".\n if (prefix && format !== 'currency') formatted = `${prefix}${formatted}`;\n if (suffix) formatted = `${formatted}${suffix}`;\n return formatted;\n}\n\nfunction clampDecimals(decimals: number): number {\n return Math.min(Math.max(Math.trunc(decimals), 0), 10);\n}\n\n/**\n * Narrow an untrusted `currency` config value to a well-formed ISO 4217 alpha\n * code (three letters), defaulting to USD. Prevents the `RangeError` that\n * `Intl.NumberFormat({ style: 'currency' })` throws on a malformed code.\n */\nfunction resolveCurrencyCode(value: unknown): string {\n const code = asString(value, 'USD').toUpperCase();\n return /^[A-Z]{3}$/.test(code) ? code : 'USD';\n}\n\n/**\n * Shared cell number formatter — constructed once (a table can render hundreds of\n * cells, and `new Intl.NumberFormat` per call is a measurable hot-path cost).\n *\n * `maximumFractionDigits: 20` (the API max) is LOSSLESS for JS doubles (~17\n * significant digits), so this only adds grouping separators — it never rounds\n * away precision. A blanket round (e.g. 4 dp) would corrupt customer-facing\n * high-precision ratios/coordinates/measurements (`0.0000123` → `0`), whereas\n * embed cells with no explicit column format must preserve the raw value.\n */\nconst CELL_NUMBER_FORMAT = new Intl.NumberFormat('en-US', { maximumFractionDigits: 20 });\n\n/**\n * Format an arbitrary table cell: finite numbers get thousands separators\n * (matching the in-app TableCell) at full precision, everything else falls back\n * to the safe string coercion that never leaks internal object structure.\n */\nexport function formatCell(value: unknown): string {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return CELL_NUMBER_FORMAT.format(value);\n }\n return displayValue(value);\n}\n\n/** True when a value is a finite number — used for right-aligning numeric columns. */\nexport function isNumeric(value: unknown): boolean {\n return typeof value === 'number' && Number.isFinite(value);\n}\n"],"mappings":";AAQA,SAAgB,EAAS,GAAgB,IAAW,IAAY;AAC9D,QAAO,OAAO,KAAU,WAAW,IAAQ;;AAG7C,SAAgB,EAAe,GAA+B;AAC5D,KAAI,OAAO,KAAU,YAAY,OAAO,SAAS,EAAM,CAAE,QAAO;AAChE,KAAI,OAAO,KAAU,YAAY,EAAM,MAAM,KAAK,IAAI;EACpD,IAAM,IAAI,OAAO,EAAM;AACvB,MAAI,OAAO,SAAS,EAAE,CAAE,QAAO;;AAEjC,QAAO;;AAGT,SAAgB,EAAQ,GAA2B;AACjD,QAAO,MAAM,QAAQ,EAAM,GAAG,IAAQ,EAAE;;AAG1C,SAAgB,EAAS,GAAyC;AAChE,QAAO,KAAS,OAAO,KAAU,YAAY,CAAC,MAAM,QAAQ,EAAM,GAAI,IAAoC,EAAE;;AAO9G,SAAgB,EAAa,GAAwB;AAKnD,QAJI,KAAU,OAAoC,KAC9C,OAAO,KAAU,WAAiB,IAClC,OAAO,KAAU,WAAiB,OAAO,SAAS,EAAM,GAAG,OAAO,EAAM,GAAG,KAC3E,OAAO,KAAU,YAAkB,IAAQ,SAAS,UACjD;;AAST,SAAgB,EAAa,GAAe,GAAyC;CACnF,IAAM,IAAS,EAAS,EAAO,QAAQ,SAAS,EAC1C,IAAW,EAAe,EAAO,SAAS,EAC1C,IAAS,EAAS,EAAO,OAAO,EAChC,IAAS,EAAS,EAAO,OAAO,EAElC;AACJ,SAAQ,GAAR;EACE,KAAK,YAAY;GAKf,IAAM,IAAW,EAAoB,EAAO,SAAS,EAC/C,IAAwB,MAAa,OAAiC,IAA1B,EAAc,EAAS;AACzE,OAAI;AACF,QAAY,IAAI,KAAK,aAAa,SAAS;KACzC,OAAO;KACP;KACA,uBAAuB;KACvB;KACD,CAAC,CAAC,OAAO,EAAM;WACV;AACN,QAAY,IAAI,KAAK,aAAa,SAAS,EAAE,0BAAuB,CAAC,CAAC,OAAO,EAAM;;AAErF;;EAEF,KAAK,cAAc;GACjB,IAAM,IAAc,MAAa,OAAiC,IAA1B,EAAc,EAAS;AAC/D,OAAY,GAAG,IAAI,KAAK,aAAa,SAAS;IAC5C,uBAAuB;IACvB,uBAAuB;IACxB,CAAC,CAAC,OAAO,IAAQ,IAAI,CAAC;AACvB;;EAEF,KAAK;AACH,OAAY,IAAI,KAAK,aAAa,SAAS;IACzC,UAAU;IACV,uBAAuB,MAAa,OAAiC,IAA1B,EAAc,EAAS;IACnE,CAAC,CAAC,OAAO,EAAM;AAChB;EAEF,QACE,KAAY,IAAI,KAAK,aAAa,SAAS,EACzC,uBAAuB,MAAa,OAAiC,IAA1B,EAAc,EAAS,EACnE,CAAC,CAAC,OAAO,EAAM;;AAOpB,QAFI,KAAU,MAAW,eAAY,IAAY,GAAG,IAAS,MACzD,MAAQ,IAAY,GAAG,IAAY,MAChC;;AAGT,SAAS,EAAc,GAA0B;AAC/C,QAAO,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,EAAS,EAAE,EAAE,EAAE,GAAG;;AAQxD,SAAS,EAAoB,GAAwB;CACnD,IAAM,IAAO,EAAS,GAAO,MAAM,CAAC,aAAa;AACjD,QAAO,aAAa,KAAK,EAAK,GAAG,IAAO;;AAa1C,IAAM,IAAqB,IAAI,KAAK,aAAa,SAAS,EAAE,uBAAuB,IAAI,CAAC;AAOxF,SAAgB,EAAW,GAAwB;AAIjD,QAHI,OAAO,KAAU,YAAY,OAAO,SAAS,EAAM,GAC9C,EAAmB,OAAO,EAAM,GAElC,EAAa,EAAM;;AAI5B,SAAgB,EAAU,GAAyB;AACjD,QAAO,OAAO,KAAU,YAAY,OAAO,SAAS,EAAM"}
|
|
1
|
+
{"version":3,"file":"shared.js","names":[],"sources":["../../../../../src/bigconsole/components/embed/widgets/shared.ts"],"sourcesContent":["/**\n * Defensive value coercion for embed widget renderers (BOFF-2986).\n *\n * The render model is sanitized by the publication builder, but the renderer\n * re-narrows every value it reads: an embedded widget is anonymous, untrusted\n * customer-facing surface, so we never assume a field is the type we expect.\n */\n\nexport function asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nexport function asFiniteNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim() !== '') {\n const n = Number(value);\n if (Number.isFinite(n)) return n;\n }\n return null;\n}\n\nexport function asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\n/**\n * Render an arbitrary cell value as a display string. Objects/arrays collapse to\n * an empty string rather than `[object Object]`, so no internal structure leaks.\n */\nexport function displayValue(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number') return Number.isFinite(value) ? String(value) : '';\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n return '';\n}\n\n/**\n * Format a number with the widget's optional format hints, safely — mirrors the\n * in-app MetricCardWidget `formatValue` so embedded numbers read identically\n * (thousands separators, currency, percentage, compact notation) instead of a\n * bare `1284530.5`. `config.format` is the same enum the in-app widgets use.\n */\nexport function formatNumber(value: number, config: Record<string, unknown>): string {\n const format = asString(config.format, 'number');\n const decimals = asFiniteNumber(config.decimals);\n const prefix = asString(config.prefix);\n const suffix = asString(config.suffix);\n\n let formatted: string;\n switch (format) {\n case 'currency': {\n // `Intl.NumberFormat` throws `RangeError` on a currency code that isn't a\n // well-formed ISO 4217 string (e.g. '', 'US', 'ABCD'). This is untrusted\n // customer-facing config, so validate the shape and fall back to USD;\n // a defensive try/catch keeps a malformed value from crashing the widget.\n const currency = resolveCurrencyCode(config.currency);\n const maximumFractionDigits = decimals !== null ? clampDecimals(decimals) : 2;\n try {\n formatted = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency,\n minimumFractionDigits: 0,\n maximumFractionDigits,\n }).format(value);\n } catch {\n formatted = new Intl.NumberFormat('en-US', { maximumFractionDigits }).format(value);\n }\n break;\n }\n case 'percentage': {\n const pctDecimals = decimals !== null ? clampDecimals(decimals) : 1;\n formatted = `${new Intl.NumberFormat('en-US', {\n minimumFractionDigits: pctDecimals,\n maximumFractionDigits: pctDecimals,\n }).format(value * 100)}%`;\n break;\n }\n case 'compact':\n formatted = new Intl.NumberFormat('en-US', {\n notation: 'compact',\n maximumFractionDigits: decimals !== null ? clampDecimals(decimals) : 1,\n }).format(value);\n break;\n case 'number':\n default:\n formatted = new Intl.NumberFormat('en-US', {\n maximumFractionDigits: decimals !== null ? clampDecimals(decimals) : 2,\n }).format(value);\n }\n\n // `currency` already carries its own symbol; only apply an explicit prefix to\n // the other formats so we never render e.g. \"$$1,284,530\".\n if (prefix && format !== 'currency') formatted = `${prefix}${formatted}`;\n if (suffix) formatted = `${formatted}${suffix}`;\n return formatted;\n}\n\nfunction clampDecimals(decimals: number): number {\n return Math.min(Math.max(Math.trunc(decimals), 0), 10);\n}\n\n/**\n * Narrow an untrusted `currency` config value to a well-formed ISO 4217 alpha\n * code (three letters), defaulting to USD. Prevents the `RangeError` that\n * `Intl.NumberFormat({ style: 'currency' })` throws on a malformed code.\n */\nfunction resolveCurrencyCode(value: unknown): string {\n const code = asString(value, 'USD').toUpperCase();\n return /^[A-Z]{3}$/.test(code) ? code : 'USD';\n}\n\n/**\n * Shared cell number formatter — constructed once (a table can render hundreds of\n * cells, and `new Intl.NumberFormat` per call is a measurable hot-path cost).\n *\n * `maximumFractionDigits: 20` (the API max) is LOSSLESS for JS doubles (~17\n * significant digits), so this only adds grouping separators — it never rounds\n * away precision. A blanket round (e.g. 4 dp) would corrupt customer-facing\n * high-precision ratios/coordinates/measurements (`0.0000123` → `0`), whereas\n * embed cells with no explicit column format must preserve the raw value.\n */\nconst CELL_NUMBER_FORMAT = new Intl.NumberFormat('en-US', { maximumFractionDigits: 20 });\n\n/**\n * Format an arbitrary table cell: finite numbers get thousands separators\n * (matching the in-app TableCell) at full precision, everything else falls back\n * to the safe string coercion that never leaks internal object structure.\n */\nexport function formatCell(value: unknown): string {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return CELL_NUMBER_FORMAT.format(value);\n }\n return displayValue(value);\n}\n\n/** True when a value is a finite number — used for right-aligning numeric columns. */\nexport function isNumeric(value: unknown): boolean {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\n/**\n * Allow only inert CSS color values (defense in depth — the service already runs\n * its own safeColor): hex, rgb/rgba/hsl/hsla with numeric arguments, or a\n * `var(--token)` reference. Anything else (`url(...)`, `expression(...)`, named\n * colors carrying odd payloads) is dropped so it can never reach an SVG `fill`\n * or a style attribute.\n */\nconst HEX_COLOR = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;\nconst FUNC_COLOR = /^(?:rgb|rgba|hsl|hsla)\\(\\s*[0-9.%\\s,/deg-]+\\)$/i;\nconst VAR_COLOR = /^var\\(--[a-z0-9-]+\\)$/i;\n\nexport function safeColor(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const v = value.trim();\n if (v.length === 0 || v.length > 64) return undefined;\n return HEX_COLOR.test(v) || FUNC_COLOR.test(v) || VAR_COLOR.test(v) ? v : undefined;\n}\n\n/** A string, trimmed and length-capped, or undefined. */\nexport function asOptionalString(value: unknown, max = 500): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value.slice(0, max) : undefined;\n}\n\n/** Array of records only (drops scalars/arrays), capped. */\nexport function asRecordArray(value: unknown, max = 5000): Record<string, unknown>[] {\n return asArray(value)\n .slice(0, max)\n .filter((v): v is Record<string, unknown> => !!v && typeof v === 'object' && !Array.isArray(v));\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
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/calendar/CalendarView.tsx
|
|
4
|
+
function i(e, t) {
|
|
5
|
+
for (let n of t) if (e[n] !== void 0 && e[n] !== null) return e[n];
|
|
6
|
+
}
|
|
7
|
+
function a(e) {
|
|
8
|
+
let t = Array.isArray(e) ? e : Array.isArray(e?.events) ? e.events : Array.isArray(e?.items) ? e.items : Array.isArray(e?.data) ? e.data : void 0;
|
|
9
|
+
return Array.isArray(t) ? t.map((e, t) => {
|
|
10
|
+
if (!e || typeof e != "object") return null;
|
|
11
|
+
let n = e, r = i(n, [
|
|
12
|
+
"start",
|
|
13
|
+
"startDate",
|
|
14
|
+
"date",
|
|
15
|
+
"startTime"
|
|
16
|
+
]);
|
|
17
|
+
if (!r) return null;
|
|
18
|
+
let a = i(n, [
|
|
19
|
+
"end",
|
|
20
|
+
"endDate",
|
|
21
|
+
"endTime"
|
|
22
|
+
]) ?? r, o = i(n, [
|
|
23
|
+
"title",
|
|
24
|
+
"name",
|
|
25
|
+
"label",
|
|
26
|
+
"summary"
|
|
27
|
+
]) ?? "Untitled event", s = i(n, [
|
|
28
|
+
"id",
|
|
29
|
+
"eventId",
|
|
30
|
+
"_id"
|
|
31
|
+
]) ?? `${o}-${r}-${t}`;
|
|
32
|
+
return {
|
|
33
|
+
id: String(s),
|
|
34
|
+
title: String(o),
|
|
35
|
+
start: String(r),
|
|
36
|
+
end: String(a),
|
|
37
|
+
color: typeof n.color == "string" ? n.color : void 0,
|
|
38
|
+
allDay: typeof n.allDay == "boolean" ? n.allDay : void 0,
|
|
39
|
+
category: i(n, [
|
|
40
|
+
"category",
|
|
41
|
+
"group",
|
|
42
|
+
"type"
|
|
43
|
+
])
|
|
44
|
+
};
|
|
45
|
+
}).filter((e) => e !== null) : [];
|
|
46
|
+
}
|
|
47
|
+
var o = e(function({ widget: e, data: i, onClick: o, t: s }) {
|
|
48
|
+
let c = t(() => a(i), [i]), l = i && !Array.isArray(i) && typeof i.eventCount == "number" ? i.eventCount : void 0, u = Math.max(l ?? 0, c.length), d = t(() => {
|
|
49
|
+
let e = /* @__PURE__ */ new Date(), t = new Date(e.getTime() + 10080 * 60 * 1e3);
|
|
50
|
+
return c.filter((n) => {
|
|
51
|
+
let r = new Date(n.start);
|
|
52
|
+
return r >= e && r <= t;
|
|
53
|
+
}).sort((e, t) => new Date(e.start).getTime() - new Date(t.start).getTime()).slice(0, 8);
|
|
54
|
+
}, [c]);
|
|
55
|
+
return c.length ? /* @__PURE__ */ r("div", {
|
|
56
|
+
className: "flex flex-col h-full p-4 overflow-auto",
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ r("div", {
|
|
59
|
+
className: "flex items-center justify-between mb-4",
|
|
60
|
+
children: [/* @__PURE__ */ n("h3", {
|
|
61
|
+
className: "text-sm font-medium text-text-primary",
|
|
62
|
+
children: s("bigconsole.widget.calendar.upcomingEvents", "Upcoming Events")
|
|
63
|
+
}), /* @__PURE__ */ n("span", {
|
|
64
|
+
className: "text-xs text-text-secondary",
|
|
65
|
+
children: s("bigconsole.widget.calendar.eventCount", "{{count}} events", { count: u })
|
|
66
|
+
})]
|
|
67
|
+
}),
|
|
68
|
+
/* @__PURE__ */ n("div", {
|
|
69
|
+
className: "flex-1 space-y-2 overflow-auto",
|
|
70
|
+
children: d.map((e) => {
|
|
71
|
+
let t = new Date(e.start), i = t.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
72
|
+
return /* @__PURE__ */ n("div", {
|
|
73
|
+
className: `
|
|
74
|
+
p-3 rounded-lg border border-border-default
|
|
75
|
+
${o ? "cursor-pointer hover:border-action-primary-bg" : ""}
|
|
76
|
+
transition-colors
|
|
77
|
+
`,
|
|
78
|
+
onClick: () => o?.(e),
|
|
79
|
+
children: /* @__PURE__ */ r("div", {
|
|
80
|
+
className: "flex items-start gap-3",
|
|
81
|
+
children: [/* @__PURE__ */ n("div", {
|
|
82
|
+
className: "w-1 h-full min-h-[40px] rounded-full flex-shrink-0",
|
|
83
|
+
style: { backgroundColor: e.color || "var(--color-action-primary-bg)" }
|
|
84
|
+
}), /* @__PURE__ */ r("div", {
|
|
85
|
+
className: "flex-1 min-w-0",
|
|
86
|
+
children: [
|
|
87
|
+
/* @__PURE__ */ n("p", {
|
|
88
|
+
className: "text-sm font-medium text-text-primary truncate",
|
|
89
|
+
children: e.title
|
|
90
|
+
}),
|
|
91
|
+
/* @__PURE__ */ r("p", {
|
|
92
|
+
className: "text-xs text-text-secondary mt-1",
|
|
93
|
+
children: [
|
|
94
|
+
i ? /* @__PURE__ */ n("span", {
|
|
95
|
+
className: "text-status-success-text font-medium",
|
|
96
|
+
children: s("bigconsole.widget.calendar.today", "Today")
|
|
97
|
+
}) : t.toLocaleDateString("en-US", {
|
|
98
|
+
weekday: "short",
|
|
99
|
+
month: "short",
|
|
100
|
+
day: "numeric"
|
|
101
|
+
}),
|
|
102
|
+
!e.allDay && /* @__PURE__ */ n("span", {
|
|
103
|
+
className: "ml-2",
|
|
104
|
+
children: t.toLocaleTimeString("en-US", {
|
|
105
|
+
hour: "numeric",
|
|
106
|
+
minute: "2-digit"
|
|
107
|
+
})
|
|
108
|
+
}),
|
|
109
|
+
e.allDay && /* @__PURE__ */ n("span", {
|
|
110
|
+
className: "ml-2",
|
|
111
|
+
children: s("bigconsole.widget.calendar.allDay", "All day")
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
}),
|
|
115
|
+
e.category && /* @__PURE__ */ n("span", {
|
|
116
|
+
className: "inline-block mt-1 px-2 py-0.5 text-[10px] rounded bg-bg-sunken text-text-secondary",
|
|
117
|
+
children: e.category
|
|
118
|
+
})
|
|
119
|
+
]
|
|
120
|
+
})]
|
|
121
|
+
})
|
|
122
|
+
}, e.id);
|
|
123
|
+
})
|
|
124
|
+
}),
|
|
125
|
+
u > d.length && /* @__PURE__ */ n("p", {
|
|
126
|
+
className: "text-xs text-text-muted text-center mt-3",
|
|
127
|
+
children: s("bigconsole.widget.calendar.moreEvents", "+{{count}} more events", { count: u - d.length })
|
|
128
|
+
})
|
|
129
|
+
]
|
|
130
|
+
}) : /* @__PURE__ */ n("div", {
|
|
131
|
+
className: "flex items-center justify-center h-full text-text-secondary text-sm",
|
|
132
|
+
children: /* @__PURE__ */ r("div", {
|
|
133
|
+
className: "text-center",
|
|
134
|
+
children: [/* @__PURE__ */ n("svg", {
|
|
135
|
+
className: "w-12 h-12 mx-auto mb-2 text-text-muted",
|
|
136
|
+
fill: "none",
|
|
137
|
+
stroke: "currentColor",
|
|
138
|
+
viewBox: "0 0 24 24",
|
|
139
|
+
children: /* @__PURE__ */ n("path", {
|
|
140
|
+
strokeLinecap: "round",
|
|
141
|
+
strokeLinejoin: "round",
|
|
142
|
+
strokeWidth: 1.5,
|
|
143
|
+
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"
|
|
144
|
+
})
|
|
145
|
+
}), /* @__PURE__ */ n("p", { children: s("bigconsole.widget.calendar.emptyState", "No events to display") })]
|
|
146
|
+
})
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
//#endregion
|
|
150
|
+
export { o as default, a as normalizeCalendarEvents };
|
|
151
|
+
|
|
152
|
+
//# sourceMappingURL=CalendarView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CalendarView.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/calendar/CalendarView.tsx"],"sourcesContent":["/**\n * CalendarWidget Component\n *\n * Simple calendar view showing events.\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 CalendarViewProps extends CalendarWidgetProps {\n /** Translator — the app passes useI18n().t; the public embed passes a static fallback translator. */\n t: WidgetTranslateFn;\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 /** Total event count when `events` is a capped subset (public embeds). */\n eventCount?: number;\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 CalendarView: FC<CalendarViewProps> = memo(function CalendarView({ widget: _widget, data, onClick, t }) {\n const events = useMemo(() => normalizeCalendarEvents(data), [data]);\n const declaredCount =\n data && !Array.isArray(data) && typeof (data as CalendarData).eventCount === 'number'\n ? (data as CalendarData).eventCount\n : undefined;\n const totalCount = Math.max(declaredCount ?? 0, events.length);\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: totalCount })}\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 {totalCount > 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: totalCount - upcomingEvents.length,\n })}\n </p>\n )}\n </div>\n );\n});\n\nexport default CalendarView;\n"],"mappings":"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"}
|
|
@@ -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";
|