@object-ui/plugin-report 17.5.0 → 17.7.0

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/index.js CHANGED
@@ -1,56 +1,56 @@
1
- import { ComponentRegistry as e, buildDatasetDrillFilter as t, buildDatasetFieldHelpers as n, formatDimensionValue as r, formatMeasure as i, mergeFilters as a, pivotBucketId as o, pivotCellKey as s, pivotDimensionValue as c, relabelDimensions as l } from "@object-ui/core";
2
- import * as u from "react";
3
- import d from "react";
4
- import { isSpecReport as f, specReportToPresentation as p } from "@object-ui/types";
5
- import { SchemaRenderer as m, SchemaRendererContext as h, toRenderableSchema as g, useDatasetDimensionLabels as _ } from "@object-ui/react";
6
- import { Badge as v, Button as y, Card as b, CardContent as x, CardDescription as S, CardHeader as C, CardTitle as w, Skeleton as T } from "@object-ui/components";
7
- import { jsx as E, jsxs as D } from "react/jsx-runtime";
8
- import { AlertTriangle as O, Download as k, Loader2 as A, Printer as j, RefreshCw as M, Table2 as N } from "lucide-react";
9
- import { getCellRenderer as ee, resolveCellRendererType as P } from "@object-ui/fields";
10
- import { useDisplayLocale as F, useSafeFieldLabel as I, useSafeTranslate as L } from "@object-ui/i18n";
1
+ import { ComponentRegistry as e, FilterOperatorError as t, buildCategoryOrder as n, buildChartSeries as r, buildDatasetDrillFilter as i, buildDatasetFieldHelpers as a, buildOptionColorMap as o, chartConfigPresentation as s, deriveDimensionLabelMaps as c, dimensionOptionTranslator as l, formatDimensionValue as u, formatMeasure as d, localizeFieldOptions as f, mergeAuthoredSeries as p, mergeFilters as m, pivotBucketId as h, pivotCellKey as g, pivotDimensionValue as _, relabelDimensions as v, toDisplayDate as y } from "@object-ui/core";
2
+ import * as b from "react";
3
+ import x from "react";
4
+ import { isSpecReport as S, specReportToPresentation as C } from "@object-ui/types";
5
+ import { SchemaRenderer as w, SchemaRendererContext as T, toRenderableSchema as E, useDataInvalidation as D, useDatasetDimensionLabels as O, useDatasetDimensionMeta as k } from "@object-ui/react";
6
+ import { Badge as A, Button as j, Card as M, CardContent as N, CardDescription as P, CardHeader as F, CardTitle as I, Skeleton as L, renderNodeSlot as ee } from "@object-ui/components";
7
+ import { jsx as R, jsxs as z } from "react/jsx-runtime";
8
+ import { AlertTriangle as te, Download as B, Loader2 as ne, Printer as re, RefreshCw as ie, Table2 as ae } from "lucide-react";
9
+ import { getCellRenderer as oe, resolveCellRendererType as se } from "@object-ui/fields";
10
+ import { builtinAggregateLabels as V, pickLocalized as ce, useDisplayLocale as H, useObjectTranslation as le, useSafeFieldLabel as U, useSafeTranslate as W } from "@object-ui/i18n";
11
11
  //#region src/LegacyReportRenderer.tsx
12
- var R = ({ schema: t }) => {
12
+ var ue = ({ schema: t }) => {
13
13
  let { title: n, description: r, data: i, columns: a } = t;
14
14
  t.chart?.type;
15
15
  let o = !!t.chart;
16
- return /* @__PURE__ */ D(b, {
16
+ return /* @__PURE__ */ z(M, {
17
17
  className: `h-full flex flex-col ${t.className || ""}`,
18
- children: [/* @__PURE__ */ D(C, { children: [n && /* @__PURE__ */ E(w, { children: n }), r && /* @__PURE__ */ E(S, { children: r })] }), /* @__PURE__ */ D(x, {
18
+ children: [/* @__PURE__ */ z(F, { children: [n && /* @__PURE__ */ R(I, { children: n }), r && /* @__PURE__ */ R(P, { children: r })] }), /* @__PURE__ */ z(N, {
19
19
  className: "flex-1 overflow-auto space-y-4",
20
20
  children: [o && (() => {
21
21
  let n = t.chart?.type, r = n ? e.get(n) : null;
22
- return r ||= e.get("chart"), r ? /* @__PURE__ */ E("div", {
22
+ return r ||= e.get("chart"), r ? /* @__PURE__ */ R("div", {
23
23
  className: "min-h-[300px] border rounded-lg p-4 bg-background/50",
24
- children: /* @__PURE__ */ E(r, { schema: {
24
+ children: /* @__PURE__ */ R(r, { schema: {
25
25
  ...t.chart,
26
26
  data: t.chart.data || i
27
27
  } })
28
- }) : /* @__PURE__ */ D("div", {
28
+ }) : /* @__PURE__ */ z("div", {
29
29
  className: "min-h-[100px] border rounded-md p-4 bg-muted/20 text-muted-foreground flex items-center justify-center",
30
30
  children: ["Unknown component type: ", n || "chart"]
31
31
  });
32
- })(), i && i.length > 0 && /* @__PURE__ */ E("div", {
32
+ })(), i && i.length > 0 && /* @__PURE__ */ R("div", {
33
33
  className: "border rounded-lg",
34
34
  children: (() => {
35
35
  let t = e.get("grid") || e.get("table");
36
- return t ? /* @__PURE__ */ E(t, { schema: {
36
+ return t ? /* @__PURE__ */ R(t, { schema: {
37
37
  type: "grid",
38
38
  rowData: i,
39
39
  columnDefs: a,
40
40
  domLayout: "autoHeight"
41
- } }) : /* @__PURE__ */ E("div", {
41
+ } }) : /* @__PURE__ */ R("div", {
42
42
  className: "overflow-x-auto",
43
- children: /* @__PURE__ */ D("table", {
43
+ children: /* @__PURE__ */ z("table", {
44
44
  className: "w-full text-sm text-left",
45
- children: [/* @__PURE__ */ E("thead", {
45
+ children: [/* @__PURE__ */ R("thead", {
46
46
  className: "text-xs uppercase bg-muted",
47
- children: /* @__PURE__ */ E("tr", { children: a?.map((e) => /* @__PURE__ */ E("th", {
47
+ children: /* @__PURE__ */ R("tr", { children: a?.map((e) => /* @__PURE__ */ R("th", {
48
48
  className: "px-6 py-3",
49
49
  children: e.headerName || e.label || e.field
50
50
  }, e.field)) })
51
- }), /* @__PURE__ */ E("tbody", { children: i.map((e, t) => /* @__PURE__ */ E("tr", {
51
+ }), /* @__PURE__ */ R("tbody", { children: i.map((e, t) => /* @__PURE__ */ R("tr", {
52
52
  className: "bg-background border-b",
53
- children: a?.map((t) => /* @__PURE__ */ E("td", {
53
+ children: a?.map((t) => /* @__PURE__ */ R("td", {
54
54
  className: "px-6 py-4",
55
55
  children: e[t.field]
56
56
  }, t.field))
@@ -62,33 +62,40 @@ var R = ({ schema: t }) => {
62
62
  })]
63
63
  });
64
64
  };
65
+ function G(e, t, n) {
66
+ try {
67
+ return e.toLocaleString(t, n);
68
+ } catch {
69
+ return e.toLocaleString("en", n);
70
+ }
71
+ }
65
72
  //#endregion
66
73
  //#region src/ReportExportEngine.ts
67
- function te(e, t, n) {
74
+ function de(e, t, n) {
68
75
  let r = e.fields || [], i = r.map((e) => e.label || e.name), a = t.map((e) => r.map((t) => {
69
76
  let n = e[t.name];
70
- return n = ie(n), typeof n == "string" && (n.includes(",") || n.includes("\"") || n.includes("\n")) ? `"${n.replace(/"/g, "\"\"")}"` : n ?? "";
77
+ return n = ge(n), typeof n == "string" && (n.includes(",") || n.includes("\"") || n.includes("\n")) ? `"${n.replace(/"/g, "\"\"")}"` : n ?? "";
71
78
  }));
72
- U([...n?.includeHeaders === !1 ? [] : [i.join(",")], ...a.map((e) => e.join(","))].join("\n"), n?.filename || `${e.title || "report"}.csv`, "text/csv");
79
+ J([...n?.includeHeaders === !1 ? [] : [i.join(",")], ...a.map((e) => e.join(","))].join("\n"), n?.filename || `${e.title || "report"}.csv`, "text/csv");
73
80
  }
74
- function ne(e, t, n) {
81
+ function fe(e, t, n) {
75
82
  let r = {
76
83
  title: e.title,
77
84
  description: e.description,
78
85
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
79
86
  data: t
80
87
  };
81
- U(JSON.stringify(r, null, 2), n?.filename || `${e.title || "report"}.json`, "application/json");
88
+ J(JSON.stringify(r, null, 2), n?.filename || `${e.title || "report"}.json`, "application/json");
82
89
  }
83
- function z(e, t, n) {
84
- let r = e.fields || [], i = oe(n?.orientation), a = ae(n?.pageSize);
85
- U(`<!DOCTYPE html>
90
+ function K(e, t, n, r = "en") {
91
+ let i = e.fields || [], a = ve(n?.orientation), o = _e(n?.pageSize);
92
+ J(`<!DOCTYPE html>
86
93
  <html>
87
94
  <head>
88
95
  <meta charset="utf-8">
89
- <title>${H(e.title || "Report")}</title>
96
+ <title>${q(e.title || "Report")}</title>
90
97
  <style>
91
- @page { size: ${a} ${i}; margin: 20mm; }
98
+ @page { size: ${o} ${a}; margin: 20mm; }
92
99
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #333; }
93
100
  h1 { font-size: 24px; margin-bottom: 8px; }
94
101
  .description { color: #666; margin-bottom: 24px; }
@@ -100,33 +107,33 @@ function z(e, t, n) {
100
107
  </style>
101
108
  </head>
102
109
  <body>
103
- <h1>${H(e.title || "Report")}</h1>
104
- ${e.description ? `<p class="description">${H(e.description)}</p>` : ""}
105
- <p class="meta">Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}</p>
110
+ <h1>${q(e.title || "Report")}</h1>
111
+ ${e.description ? `<p class="description">${q(e.description)}</p>` : ""}
112
+ <p class="meta">Generated: ${(/* @__PURE__ */ new Date()).toLocaleString(r)}</p>
106
113
  <table>
107
- <thead><tr>${r.map((e) => `<th>${H(e.label || e.name)}</th>`).join("")}</tr></thead>
108
- <tbody>${t.map((e) => `<tr>${r.map((t) => `<td>${H(String(e[t.name] ?? ""))}</td>`).join("")}</tr>`).join("")}</tbody>
114
+ <thead><tr>${i.map((e) => `<th>${q(e.label || e.name)}</th>`).join("")}</tr></thead>
115
+ <tbody>${t.map((e) => `<tr>${i.map((t) => `<td>${q(String(e[t.name] ?? ""))}</td>`).join("")}</tr>`).join("")}</tbody>
109
116
  </table>
110
117
  </body>
111
118
  </html>`, n?.filename || `${e.title || "report"}.html`, "text/html");
112
119
  }
113
- function re(e, t, n) {
114
- let r = e.fields || [], i = oe(n?.orientation), a = ae(n?.pageSize), o = window.open("", "_blank");
115
- if (!o) {
116
- z(e, t, {
120
+ function pe(e, t, n, r = "en") {
121
+ let i = e.fields || [], a = ve(n?.orientation), o = _e(n?.pageSize), s = window.open("", "_blank");
122
+ if (!s) {
123
+ K(e, t, {
117
124
  ...n,
118
125
  format: "html",
119
126
  filename: n?.filename?.replace(/\.pdf$/, ".html") || `${e.title || "report"}.html`
120
- });
127
+ }, r);
121
128
  return;
122
129
  }
123
- o.document.write(`<!DOCTYPE html>
130
+ s.document.write(`<!DOCTYPE html>
124
131
  <html>
125
132
  <head>
126
133
  <meta charset="utf-8">
127
- <title>${H(e.title || "Report")}</title>
134
+ <title>${q(e.title || "Report")}</title>
128
135
  <style>
129
- @page { size: ${a} ${i}; margin: 20mm; }
136
+ @page { size: ${o} ${a}; margin: 20mm; }
130
137
  @media print { .no-print { display: none; } }
131
138
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #333; }
132
139
  h1 { font-size: 24px; margin-bottom: 8px; }
@@ -139,56 +146,56 @@ function re(e, t, n) {
139
146
  </style>
140
147
  </head>
141
148
  <body>
142
- <h1>${H(e.title || "Report")}</h1>
143
- ${e.description ? `<p class="description">${H(e.description)}</p>` : ""}
144
- <p class="meta">Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}</p>
149
+ <h1>${q(e.title || "Report")}</h1>
150
+ ${e.description ? `<p class="description">${q(e.description)}</p>` : ""}
151
+ <p class="meta">Generated: ${(/* @__PURE__ */ new Date()).toLocaleString(r)}</p>
145
152
  <table>
146
- <thead><tr>${r.map((e) => `<th>${H(e.label || e.name)}</th>`).join("")}</tr></thead>
147
- <tbody>${t.map((e) => `<tr>${r.map((t) => `<td>${H(String(e[t.name] ?? ""))}</td>`).join("")}</tr>`).join("")}</tbody>
153
+ <thead><tr>${i.map((e) => `<th>${q(e.label || e.name)}</th>`).join("")}</tr></thead>
154
+ <tbody>${t.map((e) => `<tr>${i.map((t) => `<td>${q(String(e[t.name] ?? ""))}</td>`).join("")}</tr>`).join("")}</tbody>
148
155
  </table>
149
156
  </body>
150
- </html>`), o.document.close(), o.onload = () => {
151
- o.print();
157
+ </html>`), s.document.close(), s.onload = () => {
158
+ s.print();
152
159
  };
153
160
  }
154
- function B(e, t, n) {
161
+ function me(e, t, n) {
155
162
  let r = e.fields || [], i = r.map((e) => e.label || e.name), a = t.map((e) => r.map((t) => {
156
163
  let n = e[t.name];
157
- return n = ie(n), typeof n == "string" && (n.includes(",") || n.includes("\"") || n.includes("\n") || n.includes(" ")) ? `"${n.replace(/"/g, "\"\"")}"` : n ?? "";
164
+ return n = ge(n), typeof n == "string" && (n.includes(",") || n.includes("\"") || n.includes("\n") || n.includes(" ")) ? `"${n.replace(/"/g, "\"\"")}"` : n ?? "";
158
165
  }));
159
- U("" + [...n?.includeHeaders === !1 ? [] : [i.join(" ")], ...a.map((e) => e.join(" "))].join("\n"), n?.filename || `${e.title || "report"}.tsv`, "text/tab-separated-values");
166
+ J("" + [...n?.includeHeaders === !1 ? [] : [i.join(" ")], ...a.map((e) => e.join(" "))].join("\n"), n?.filename || `${e.title || "report"}.tsv`, "text/tab-separated-values");
160
167
  }
161
- function V(e, t, n, r) {
168
+ function he(e, t, n, r, i = "en") {
162
169
  switch (e) {
163
170
  case "csv":
164
- te(t, n, r);
171
+ de(t, n, r);
165
172
  break;
166
173
  case "json":
167
- ne(t, n, r);
174
+ fe(t, n, r);
168
175
  break;
169
176
  case "html":
170
- z(t, n, r);
177
+ K(t, n, r, i);
171
178
  break;
172
179
  case "pdf":
173
- re(t, n, r);
180
+ pe(t, n, r, i);
174
181
  break;
175
182
  case "excel":
176
- B(t, n, r);
183
+ me(t, n, r);
177
184
  break;
178
185
  default: console.warn(`Unsupported export format: ${e}`);
179
186
  }
180
187
  }
181
- function H(e) {
188
+ function q(e) {
182
189
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
183
190
  }
184
- function ie(e) {
191
+ function ge(e) {
185
192
  if (typeof e == "string" && e.length > 0) {
186
193
  let t = e.charAt(0);
187
194
  if (t === "=" || t === "+" || t === "-" || t === "@" || t === "|") return `\t${e}`;
188
195
  }
189
196
  return e;
190
197
  }
191
- function ae(e) {
198
+ function _e(e) {
192
199
  return [
193
200
  "A4",
194
201
  "A3",
@@ -196,40 +203,40 @@ function ae(e) {
196
203
  "Legal"
197
204
  ].includes(e || "") ? e : "A4";
198
205
  }
199
- function oe(e) {
206
+ function ve(e) {
200
207
  return e === "landscape" ? "landscape" : "portrait";
201
208
  }
202
- function U(e, t, n) {
209
+ function J(e, t, n) {
203
210
  let r = new Blob([e], { type: `${n};charset=utf-8` }), i = URL.createObjectURL(r), a = document.createElement("a");
204
211
  a.href = i, a.download = t, document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(i);
205
212
  }
206
213
  //#endregion
207
214
  //#region src/formatValue.ts
208
- function W(e, t) {
215
+ function Y(e, t, n = "en") {
209
216
  if (e == null || e === "") return "";
210
- let n = t?.type, r = t?.format;
211
- if (n === "date" || r === "date" || se(e)) return ce(e);
212
- if (n === "number" || typeof e == "number") {
217
+ let r = t?.type, i = t?.format;
218
+ if (r === "date" || i === "date" || ye(e)) return be(e);
219
+ if (r === "number" || typeof e == "number") {
213
220
  let t = typeof e == "number" ? e : Number(e);
214
- return isNaN(t) ? String(e) : r === "currency" || r === "currency_cny" ? `¥${t.toLocaleString("en-US", {
221
+ return isNaN(t) ? String(e) : i === "currency" || i === "currency_cny" ? `¥${G(t, n, {
215
222
  minimumFractionDigits: 0,
216
223
  maximumFractionDigits: 0
217
- })}` : r === "currency_usd" ? `$${t.toLocaleString("en-US", {
224
+ })}` : i === "currency_usd" ? `$${G(t, n, {
218
225
  minimumFractionDigits: 0,
219
226
  maximumFractionDigits: 0
220
- })}` : r === "percent" ? `${t.toLocaleString("en-US", {
227
+ })}` : i === "percent" ? `${G(t, n, {
221
228
  minimumFractionDigits: 1,
222
229
  maximumFractionDigits: 1
223
- })}%` : t.toLocaleString("en-US");
230
+ })}%` : G(t, n);
224
231
  }
225
232
  return String(e);
226
233
  }
227
- function se(e) {
234
+ function ye(e) {
228
235
  return typeof e == "string" && /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?/.test(e);
229
236
  }
230
- function ce(e) {
237
+ function be(e) {
231
238
  try {
232
- let t = new Date(e);
239
+ let t = y(e);
233
240
  return isNaN(t.getTime()) ? String(e) : `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, "0")}-${String(t.getDate()).padStart(2, "0")}`;
234
241
  } catch {
235
242
  return String(e);
@@ -237,7 +244,7 @@ function ce(e) {
237
244
  }
238
245
  //#endregion
239
246
  //#region src/ReportViewer.tsx
240
- function le(e, t) {
247
+ function xe(e, t) {
241
248
  if (!t || t.length === 0 || !e || e.length === 0) return null;
242
249
  let n = t[0], r = n.field, i = /* @__PURE__ */ new Map();
243
250
  for (let t of e) {
@@ -253,7 +260,7 @@ function le(e, t) {
253
260
  let o = n.sort === "desc" ? -1 : 1;
254
261
  return a.sort((e, t) => e.key.localeCompare(t.key) * o), a;
255
262
  }
256
- function ue(e, t, n) {
263
+ function Se(e, t, n) {
257
264
  if (!e) return 0;
258
265
  let r = e.map((e) => Number(e[t]) || 0);
259
266
  switch (n) {
@@ -266,20 +273,20 @@ function ue(e, t, n) {
266
273
  default: return "";
267
274
  }
268
275
  }
269
- var G = ({ schema: e, onRefresh: t }) => {
270
- let { report: n, data: r, showToolbar: i = !0, allowExport: a = !0, allowPrint: o = !0, loading: s = !1 } = e, c = L(), l = (e) => {
276
+ var Ce = ({ schema: e, onRefresh: t }) => {
277
+ let { report: n, data: r, showToolbar: i = !0, allowExport: a = !0, allowPrint: o = !0, loading: s = !1 } = e, c = W(), l = H(), u = (e) => {
271
278
  if (!n) {
272
279
  console.warn("ReportViewer: Cannot export, no report defined");
273
280
  return;
274
281
  }
275
- V(e, n, r || [], n.exportConfigs?.[e]);
276
- }, u = c("common.printDialogHint", "Opens your browser’s print dialog (not a PDF export)"), f = () => {
282
+ he(e, n, r || [], n.exportConfigs?.[e], l);
283
+ }, d = c("common.printDialogHint", "Opens your browser’s print dialog (not a PDF export)"), f = () => {
277
284
  window.print();
278
285
  }, p = () => {
279
286
  t?.();
280
- }, h = (e, t) => ue(r, e, t), _ = (e, t) => {
287
+ }, m = (e, t) => Se(r, e, t), h = (e, t) => {
281
288
  let r = n?.conditionalFormatting;
282
- if (!(!r || !Array.isArray(r))) for (let n of r) {
289
+ if (r && Array.isArray(r)) for (let n of r) {
283
290
  if (n.field !== e) continue;
284
291
  let r = String(t ?? ""), i = String(n.value ?? ""), a = !1;
285
292
  switch (n.operator) {
@@ -302,16 +309,16 @@ var G = ({ schema: e, onRefresh: t }) => {
302
309
  return n.backgroundColor && (e.backgroundColor = n.backgroundColor), n.textColor && (e.color = n.textColor), e;
303
310
  }
304
311
  }
305
- }, O = (e, t) => {
312
+ }, g = (e, t) => {
306
313
  if (e == null || e === "") return "";
307
314
  if (t.renderAs === "badge" && (!t.type || t.type === "string" || t.type === "text")) {
308
315
  let n = t.colorMap?.[String(e)] || "";
309
- return /* @__PURE__ */ E(v, {
316
+ return /* @__PURE__ */ R(A, {
310
317
  className: n,
311
318
  children: String(e)
312
319
  });
313
320
  }
314
- if (t.aggregation) return W(e, t);
321
+ if (t.aggregation) return Y(e, t, l);
315
322
  if (t.type) {
316
323
  let n = { ...t };
317
324
  t.colorMap && !n.options && (n.options = Object.entries(t.colorMap).map(([e, t]) => ({
@@ -319,132 +326,132 @@ var G = ({ schema: e, onRefresh: t }) => {
319
326
  label: e,
320
327
  color: t
321
328
  })));
322
- let r = ee(P(n));
323
- return /* @__PURE__ */ E(r, {
329
+ let r = oe(se(n));
330
+ return /* @__PURE__ */ R(r, {
324
331
  value: e,
325
332
  field: n
326
333
  });
327
334
  }
328
- return W(e, t);
335
+ return Y(e, t, l);
329
336
  };
330
- return n ? /* @__PURE__ */ D("div", {
337
+ return n ? /* @__PURE__ */ z("div", {
331
338
  className: "space-y-4",
332
- children: [i && /* @__PURE__ */ D("div", {
339
+ children: [i && /* @__PURE__ */ z("div", {
333
340
  className: "flex items-center justify-between gap-2 p-4 bg-card rounded-lg border",
334
- children: [/* @__PURE__ */ D("div", { children: [/* @__PURE__ */ E("h2", {
341
+ children: [/* @__PURE__ */ z("div", { children: [/* @__PURE__ */ R("h2", {
335
342
  className: "text-lg font-semibold",
336
343
  children: n.title
337
- }), n.description && /* @__PURE__ */ E("p", {
344
+ }), n.description && /* @__PURE__ */ R("p", {
338
345
  className: "text-sm text-muted-foreground",
339
346
  children: n.description
340
- })] }), /* @__PURE__ */ D("div", {
347
+ })] }), /* @__PURE__ */ z("div", {
341
348
  className: "flex items-center gap-2",
342
349
  "data-print-hide": !0,
343
350
  children: [
344
- n.refreshInterval && /* @__PURE__ */ D(y, {
351
+ n.refreshInterval && /* @__PURE__ */ z(j, {
345
352
  variant: "outline",
346
353
  size: "sm",
347
354
  onClick: p,
348
- children: [/* @__PURE__ */ E(M, { className: "h-4 w-4 mr-2" }), "Refresh"]
355
+ children: [/* @__PURE__ */ R(ie, { className: "h-4 w-4 mr-2" }), "Refresh"]
349
356
  }),
350
- o && /* @__PURE__ */ D(y, {
357
+ o && /* @__PURE__ */ z(j, {
351
358
  variant: "outline",
352
359
  size: "sm",
353
360
  onClick: f,
354
- "aria-label": `Print: ${u}`,
355
- title: u,
356
- children: [/* @__PURE__ */ E(j, { className: "h-4 w-4 mr-2" }), "Print"]
361
+ "aria-label": `Print: ${d}`,
362
+ title: d,
363
+ children: [/* @__PURE__ */ R(re, { className: "h-4 w-4 mr-2" }), "Print"]
357
364
  }),
358
- a && n.showExportButtons && /* @__PURE__ */ D("div", {
365
+ a && n.showExportButtons && /* @__PURE__ */ z("div", {
359
366
  className: "flex items-center gap-1",
360
367
  children: [
361
- /* @__PURE__ */ D(y, {
368
+ /* @__PURE__ */ z(j, {
362
369
  variant: "outline",
363
370
  size: "sm",
364
- onClick: () => l("pdf"),
365
- children: [/* @__PURE__ */ E(k, { className: "h-4 w-4 mr-2" }), "PDF"]
371
+ onClick: () => u("pdf"),
372
+ children: [/* @__PURE__ */ R(B, { className: "h-4 w-4 mr-2" }), "PDF"]
366
373
  }),
367
- /* @__PURE__ */ D(y, {
374
+ /* @__PURE__ */ z(j, {
368
375
  variant: "outline",
369
376
  size: "sm",
370
- onClick: () => l("excel"),
371
- children: [/* @__PURE__ */ E(k, { className: "h-4 w-4 mr-2" }), "Excel"]
377
+ onClick: () => u("excel"),
378
+ children: [/* @__PURE__ */ R(B, { className: "h-4 w-4 mr-2" }), "Excel"]
372
379
  }),
373
- /* @__PURE__ */ D(y, {
380
+ /* @__PURE__ */ z(j, {
374
381
  variant: "outline",
375
382
  size: "sm",
376
- onClick: () => l("csv"),
377
- children: [/* @__PURE__ */ E(k, { className: "h-4 w-4 mr-2" }), "CSV"]
383
+ onClick: () => u("csv"),
384
+ children: [/* @__PURE__ */ R(B, { className: "h-4 w-4 mr-2" }), "CSV"]
378
385
  })
379
386
  ]
380
387
  })
381
388
  ]
382
389
  })]
383
- }), /* @__PURE__ */ D(b, { children: [/* @__PURE__ */ D(C, { children: [!i && n.title && /* @__PURE__ */ E(w, { children: n.title }), !i && n.description && /* @__PURE__ */ E(S, { children: n.description })] }), /* @__PURE__ */ D(x, {
390
+ }), /* @__PURE__ */ z(M, { children: [/* @__PURE__ */ z(F, { children: [!i && n.title && /* @__PURE__ */ R(I, { children: n.title }), !i && n.description && /* @__PURE__ */ R(P, { children: n.description })] }), /* @__PURE__ */ z(N, {
384
391
  className: "space-y-6",
385
392
  children: [
386
- s && /* @__PURE__ */ D("div", {
393
+ s && /* @__PURE__ */ z("div", {
387
394
  className: "space-y-6",
388
- children: [/* @__PURE__ */ E("div", {
395
+ children: [/* @__PURE__ */ R("div", {
389
396
  className: "grid grid-cols-1 md:grid-cols-3 gap-4",
390
397
  children: [
391
398
  1,
392
399
  2,
393
400
  3
394
- ].map((e) => /* @__PURE__ */ E(b, { children: /* @__PURE__ */ D(x, {
401
+ ].map((e) => /* @__PURE__ */ R(M, { children: /* @__PURE__ */ z(N, {
395
402
  className: "p-4 space-y-2",
396
- children: [/* @__PURE__ */ E(T, { className: "h-4 w-20" }), /* @__PURE__ */ E(T, { className: "h-8 w-28" })]
403
+ children: [/* @__PURE__ */ R(L, { className: "h-4 w-20" }), /* @__PURE__ */ R(L, { className: "h-8 w-28" })]
397
404
  }) }, e))
398
- }), /* @__PURE__ */ D("div", {
405
+ }), /* @__PURE__ */ z("div", {
399
406
  className: "space-y-2",
400
- children: [/* @__PURE__ */ E(T, { className: "h-10 w-full" }), [
407
+ children: [/* @__PURE__ */ R(L, { className: "h-10 w-full" }), [
401
408
  1,
402
409
  2,
403
410
  3,
404
411
  4,
405
412
  5
406
- ].map((e) => /* @__PURE__ */ E(T, { className: "h-8 w-full" }, e))]
413
+ ].map((e) => /* @__PURE__ */ R(L, { className: "h-8 w-full" }, e))]
407
414
  })]
408
415
  }),
409
- !s && n.sections?.map((e, t) => e.visible === !1 ? null : /* @__PURE__ */ D("div", {
416
+ !s && n.sections?.map((e, t) => e.visible === !1 ? null : /* @__PURE__ */ z("div", {
410
417
  className: "space-y-2",
411
418
  children: [
412
- e.title && e.type !== "header" && /* @__PURE__ */ E("h3", {
419
+ e.title && e.type !== "header" && /* @__PURE__ */ R("h3", {
413
420
  className: "text-lg font-semibold border-b pb-2",
414
421
  children: e.title
415
422
  }),
416
- e.type === "header" && e.title && /* @__PURE__ */ E("div", {
423
+ e.type === "header" && e.title && /* @__PURE__ */ R("div", {
417
424
  className: "text-2xl font-bold py-4",
418
425
  children: e.title
419
426
  }),
420
- e.type === "summary" && /* @__PURE__ */ E("div", {
427
+ e.type === "summary" && /* @__PURE__ */ R("div", {
421
428
  className: "grid grid-cols-1 md:grid-cols-3 gap-4",
422
- children: n.fields?.filter((e) => e.showInSummary).map((e, t) => /* @__PURE__ */ E(b, { children: /* @__PURE__ */ D(x, {
429
+ children: n.fields?.filter((e) => e.showInSummary).map((e, t) => /* @__PURE__ */ R(M, { children: /* @__PURE__ */ z(N, {
423
430
  className: "p-4",
424
- children: [/* @__PURE__ */ E("div", {
431
+ children: [/* @__PURE__ */ R("div", {
425
432
  className: "text-sm text-muted-foreground",
426
433
  children: e.label || e.name
427
- }), /* @__PURE__ */ E("div", {
434
+ }), /* @__PURE__ */ R("div", {
428
435
  className: "text-2xl font-bold",
429
- children: W(h(e.name, e.aggregation), e)
436
+ children: Y(m(e.name, e.aggregation), e, l)
430
437
  })]
431
438
  }) }, t))
432
439
  }),
433
- e.type === "table" && /* @__PURE__ */ E("div", {
440
+ e.type === "table" && /* @__PURE__ */ R("div", {
434
441
  className: "border rounded-lg overflow-x-auto",
435
- children: /* @__PURE__ */ D("table", {
442
+ children: /* @__PURE__ */ z("table", {
436
443
  className: "w-full text-sm min-w-[600px]",
437
- children: [/* @__PURE__ */ E("thead", {
444
+ children: [/* @__PURE__ */ R("thead", {
438
445
  className: "bg-muted",
439
- children: /* @__PURE__ */ E("tr", { children: e.columns?.map((e, t) => /* @__PURE__ */ E("th", {
446
+ children: /* @__PURE__ */ R("tr", { children: e.columns?.map((e, t) => /* @__PURE__ */ R("th", {
440
447
  className: `px-4 py-2 font-medium ${e.type === "number" ? "text-right" : "text-left"}`,
441
448
  children: e.label || e.name
442
449
  }, t)) })
443
- }), /* @__PURE__ */ E("tbody", { children: (() => {
444
- let t = le(r || [], n.groupBy || []);
445
- return t ? t.map((t) => /* @__PURE__ */ D(d.Fragment, { children: [/* @__PURE__ */ E("tr", {
450
+ }), /* @__PURE__ */ R("tbody", { children: (() => {
451
+ let t = xe(r || [], n.groupBy || []);
452
+ return t ? t.map((t) => /* @__PURE__ */ z(x.Fragment, { children: [/* @__PURE__ */ R("tr", {
446
453
  className: "bg-muted/60",
447
- children: /* @__PURE__ */ D("td", {
454
+ children: /* @__PURE__ */ z("td", {
448
455
  colSpan: e.columns?.length || 1,
449
456
  className: "px-4 py-2 font-semibold text-sm",
450
457
  children: [
@@ -454,96 +461,107 @@ var G = ({ schema: e, onRefresh: t }) => {
454
461
  ")"
455
462
  ]
456
463
  })
457
- }), t.rows.map((t, n) => /* @__PURE__ */ E("tr", {
464
+ }), t.rows.map((t, n) => /* @__PURE__ */ R("tr", {
458
465
  className: "border-t hover:bg-muted/50 even:bg-muted/20",
459
- children: e.columns?.map((e, n) => /* @__PURE__ */ E("td", {
466
+ children: e.columns?.map((e, n) => /* @__PURE__ */ R("td", {
460
467
  className: `px-4 py-2 ${e.type === "number" ? "text-right tabular-nums" : ""}`,
461
- style: _(e.name, t[e.name]),
462
- children: O(t[e.name], e)
468
+ style: h(e.name, t[e.name]),
469
+ children: g(t[e.name], e)
463
470
  }, n))
464
- }, n))] }, t.key)) : r?.map((t, n) => /* @__PURE__ */ E("tr", {
471
+ }, n))] }, t.key)) : r?.map((t, n) => /* @__PURE__ */ R("tr", {
465
472
  className: "border-t hover:bg-muted/50 even:bg-muted/20",
466
- children: e.columns?.map((e, n) => /* @__PURE__ */ E("td", {
473
+ children: e.columns?.map((e, n) => /* @__PURE__ */ R("td", {
467
474
  className: `px-4 py-2 ${e.type === "number" ? "text-right tabular-nums" : ""}`,
468
- style: _(e.name, t[e.name]),
469
- children: O(t[e.name], e)
475
+ style: h(e.name, t[e.name]),
476
+ children: g(t[e.name], e)
470
477
  }, n))
471
478
  }, n));
472
479
  })() })]
473
480
  })
474
481
  }),
475
- e.type === "text" && e.text && /* @__PURE__ */ E("div", {
482
+ e.type === "text" && e.text && /* @__PURE__ */ R("div", {
476
483
  className: "prose max-w-none",
477
- children: /* @__PURE__ */ E("p", { children: e.text })
484
+ children: /* @__PURE__ */ R("p", { children: e.text })
478
485
  }),
479
- e.type === "page-break" && /* @__PURE__ */ E("div", { className: "border-t-2 border-dashed my-8 print:page-break-after-always" }),
480
- Array.isArray(e.content) ? e.content.map((e, t) => /* @__PURE__ */ E(m, { schema: g(e) }, t)) : e.content && /* @__PURE__ */ E(m, { schema: g(e.content) })
486
+ e.type === "page-break" && /* @__PURE__ */ R("div", { className: "border-t-2 border-dashed my-8 print:page-break-after-always" }),
487
+ Array.isArray(e.content) ? e.content.map((e, t) => /* @__PURE__ */ R(w, { schema: E(e) }, t)) : ee(e.content, (e) => /* @__PURE__ */ R(w, { schema: E(e) }))
481
488
  ]
482
489
  }, t)),
483
- !n.sections && r && r.length > 0 && /* @__PURE__ */ E("div", {
490
+ !n.sections && r && r.length > 0 && /* @__PURE__ */ R("div", {
484
491
  className: "border rounded-lg overflow-x-auto",
485
- children: /* @__PURE__ */ D("table", {
492
+ children: /* @__PURE__ */ z("table", {
486
493
  className: "w-full text-sm min-w-[600px]",
487
- children: [/* @__PURE__ */ E("thead", {
494
+ children: [/* @__PURE__ */ R("thead", {
488
495
  className: "bg-muted",
489
- children: /* @__PURE__ */ E("tr", { children: n.fields?.map((e, t) => /* @__PURE__ */ E("th", {
496
+ children: /* @__PURE__ */ R("tr", { children: n.fields?.map((e, t) => /* @__PURE__ */ R("th", {
490
497
  className: `px-4 py-2 font-medium ${e.type === "number" ? "text-right" : "text-left"}`,
491
498
  children: e.label || e.name
492
499
  }, t)) })
493
- }), /* @__PURE__ */ E("tbody", { children: r.map((e, t) => /* @__PURE__ */ E("tr", {
500
+ }), /* @__PURE__ */ R("tbody", { children: r.map((e, t) => /* @__PURE__ */ R("tr", {
494
501
  className: "border-t hover:bg-muted/50 even:bg-muted/20",
495
- children: n.fields?.map((t, n) => /* @__PURE__ */ E("td", {
502
+ children: n.fields?.map((t, n) => /* @__PURE__ */ R("td", {
496
503
  className: `px-4 py-2 ${t.type === "number" ? "text-right tabular-nums" : ""}`,
497
- style: _(t.name, e[t.name]),
498
- children: O(e[t.name], t)
504
+ style: h(t.name, e[t.name]),
505
+ children: g(e[t.name], t)
499
506
  }, n))
500
507
  }, t)) })]
501
508
  })
502
509
  })
503
510
  ]
504
511
  })] })]
505
- }) : /* @__PURE__ */ E(b, { children: /* @__PURE__ */ E(x, {
512
+ }) : /* @__PURE__ */ R(M, { children: /* @__PURE__ */ R(N, {
506
513
  className: "p-8 text-center text-muted-foreground",
507
514
  children: "No report to display"
508
515
  }) });
509
516
  };
510
517
  //#endregion
511
518
  //#region src/DatasetReportRenderer.tsx
512
- function K(e) {
519
+ function we(e) {
513
520
  if (!e || typeof e != "object") return !1;
514
521
  let t = e;
515
522
  return typeof t.dataset == "string" && t.dataset.length > 0 || t.type === "joined" && Array.isArray(t.blocks) && t.blocks.some((e) => typeof e?.dataset == "string");
516
523
  }
517
- function de(e, t) {
524
+ var Te = /* @__PURE__ */ new Set(), Ee = () => globalThis.process?.env?.NODE_ENV !== "production";
525
+ function De(e, t) {
526
+ if (!Ee()) return;
527
+ let n = e.filter;
528
+ if (n === void 0) return;
529
+ let r = `${t}:${n && typeof n == "object" ? Object.keys(n).sort().join(",") : String(n)}`;
530
+ Te.has(r) || (Te.add(r), console.warn(`[ObjectUI] ${t} carries \`filter\`, which is not an authorable key. Did you mean \`filter\` → \`runtimeFilter\`? NO filter was applied — it renders UNFILTERED, showing rows the report was scoped to exclude. \`ReportSchema\` (\`@objectstack/spec\`) is strict and rejects \`filter\`, so this document did not come through the validated path; the renderer no longer reads it either. Fix the producer: rename \`filter\` to \`runtimeFilter\`. (objectui#5137)`));
531
+ }
532
+ function Oe(e) {
533
+ return `Report \`${e.name ?? "(unnamed)"}\``;
534
+ }
535
+ function ke(e, t) {
518
536
  return e ? typeof e == "string" ? e : typeof e == "object" && typeof e.default == "string" ? e.default : t : t;
519
537
  }
520
- function q(e) {
538
+ function X(e) {
521
539
  return Array.isArray(e) ? e.filter((e) => typeof e == "string" && !!e) : [];
522
540
  }
523
- function fe(e) {
541
+ function Ae(e) {
524
542
  if (!Array.isArray(e)) return;
525
543
  let t = {};
526
544
  for (let n of e) {
527
545
  let e = n && typeof n == "object" ? n.by : void 0;
528
- typeof e != "string" || !e || (t[e] = n.direction === "desc" ? "desc" : "asc");
546
+ typeof e == "string" && e && (t[e] = n.direction === "desc" ? "desc" : "asc");
529
547
  }
530
548
  return Object.keys(t).length > 0 ? t : void 0;
531
549
  }
532
- function pe(e, t, n) {
550
+ function je(e, t, n) {
533
551
  if (!e) return;
534
552
  let r = /* @__PURE__ */ new Set([...t, ...n]), i = {};
535
553
  for (let [t, n] of Object.entries(e)) r.has(t) && (i[t] = n);
536
554
  return Object.keys(i).length > 0 ? i : void 0;
537
555
  }
538
- function J(e, t, n, r, i, a, o) {
539
- let [s, c] = u.useState({
556
+ function Z(e, t, n, r, i, a, o) {
557
+ let [s, c] = b.useState({
540
558
  status: "idle",
541
559
  rows: []
542
- }), l = pe(o, t, n), d = JSON.stringify(r ?? null), f = JSON.stringify(a ?? null), p = JSON.stringify(l ?? null), m = `${e}|${t.join(",")}|${n.join(",")}|${d}|${f}|${p}`;
543
- return u.useEffect(() => {
560
+ }), l = je(o, t, n), u = JSON.stringify(r ?? null), d = JSON.stringify(a ?? null), f = JSON.stringify(l ?? null), p = `${e}|${t.join(",")}|${n.join(",")}|${u}|${d}|${f}`, [m, h] = b.useState(void 0), g = D(m), _ = b.useRef(null);
561
+ return b.useEffect(() => {
544
562
  let o = i;
545
563
  if (!o || typeof o.queryDataset != "function") {
546
- c({
564
+ _.current = null, h(void 0), c({
547
565
  status: "error",
548
566
  rows: [],
549
567
  error: "This data source does not support dataset queries."
@@ -551,24 +569,24 @@ function J(e, t, n, r, i, a, o) {
551
569
  return;
552
570
  }
553
571
  if (!e || n.length === 0) {
554
- c({
572
+ _.current = null, h(void 0), c({
555
573
  status: "idle",
556
574
  rows: []
557
575
  });
558
576
  return;
559
577
  }
560
- let s = !1;
561
- return c({
578
+ let s = !1, u = _.current === p;
579
+ return _.current = p, u || (h(void 0), c({
562
580
  status: "loading",
563
581
  rows: []
564
- }), o.queryDataset(e, {
582
+ })), o.queryDataset(e, {
565
583
  dimensions: t,
566
584
  measures: n,
567
585
  ...r && Object.keys(r).length > 0 ? { runtimeFilter: r } : {},
568
586
  ...a ? { totals: { groupings: a } } : {},
569
587
  ...l ? { order: l } : {}
570
588
  }).then((e) => {
571
- s || c({
589
+ s || (h(typeof e?.object == "string" && e.object ? e.object : void 0), c({
572
590
  status: "ok",
573
591
  rows: Array.isArray(e?.rows) ? e.rows : [],
574
592
  fields: Array.isArray(e?.fields) ? e.fields : [],
@@ -577,7 +595,7 @@ function J(e, t, n, r, i, a, o) {
577
595
  drillRawRows: Array.isArray(e?.drillRawRows) ? e.drillRawRows : void 0,
578
596
  drillRanges: Array.isArray(e?.drillRanges) ? e.drillRanges : void 0,
579
597
  totals: Array.isArray(e?.totals) ? e.totals : void 0
580
- });
598
+ }));
581
599
  }).catch((e) => {
582
600
  s || c({
583
601
  status: "error",
@@ -587,10 +605,18 @@ function J(e, t, n, r, i, a, o) {
587
605
  }), () => {
588
606
  s = !0;
589
607
  };
590
- }, [m]), s;
608
+ }, [p, g]), s;
609
+ }
610
+ function Me(...e) {
611
+ try {
612
+ return i(...e);
613
+ } catch (e) {
614
+ if (!(e instanceof t)) throw e;
615
+ return console.warn(`[DatasetReportRenderer] drill-down refused — the drilled list cannot be scoped: ${e.message}`), null;
616
+ }
591
617
  }
592
- function me({ dataset: e }) {
593
- return /* @__PURE__ */ D("div", {
618
+ function Ne({ dataset: e }) {
619
+ return /* @__PURE__ */ z("div", {
594
620
  className: "flex items-center justify-center rounded-md border border-dashed bg-muted/20 p-4 text-xs text-muted-foreground",
595
621
  children: [
596
622
  "This report binds the “",
@@ -599,81 +625,86 @@ function me({ dataset: e }) {
599
625
  ]
600
626
  });
601
627
  }
602
- function Y({ status: e, error: t }) {
603
- return e === "error" ? /* @__PURE__ */ D("div", {
628
+ function Q({ status: e, error: t }) {
629
+ return e === "error" ? /* @__PURE__ */ z("div", {
604
630
  role: "alert",
605
631
  className: "flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive",
606
- children: [/* @__PURE__ */ E(O, { className: "h-3.5 w-3.5 mt-0.5 shrink-0" }), /* @__PURE__ */ E("span", {
632
+ children: [/* @__PURE__ */ R(te, { className: "h-3.5 w-3.5 mt-0.5 shrink-0" }), /* @__PURE__ */ R("span", {
607
633
  className: "break-words",
608
634
  children: t
609
635
  })]
610
- }) : /* @__PURE__ */ D("div", {
636
+ }) : /* @__PURE__ */ z("div", {
611
637
  className: "flex items-center gap-2 p-4 text-xs text-muted-foreground",
612
- children: [/* @__PURE__ */ E(A, { className: "h-4 w-4 animate-spin" }), " Running report…"]
638
+ children: [/* @__PURE__ */ R(ne, { className: "h-4 w-4 animate-spin" }), " Running report…"]
613
639
  });
614
640
  }
615
- function he() {
616
- return /* @__PURE__ */ D("div", {
641
+ function Pe() {
642
+ return /* @__PURE__ */ z("div", {
617
643
  className: "flex flex-col items-center justify-center gap-2 rounded-md border border-dashed bg-muted/20 p-6 text-xs text-muted-foreground",
618
- children: [/* @__PURE__ */ E(N, { className: "h-6 w-6" }), " The dataset returned no rows for this report’s scope."]
644
+ children: [/* @__PURE__ */ R(ae, { className: "h-6 w-6" }), " The dataset returned no rows for this report’s scope."]
619
645
  });
620
646
  }
621
- var ge = "cursor-pointer hover:bg-accent/40";
622
- function _e({ dataset: e, rows: a, values: o, runtimeFilter: s, dataSource: c, onDrill: u, order: d, withTotals: f }) {
623
- let p = J(e, a, o, s, c, f && a.length > 0 ? [[]] : void 0, d), { fieldLabel: m } = I(), h = L(), g = F(), v = _(p.object, p.dimensionFields, a);
624
- if (o.length === 0) return /* @__PURE__ */ E(me, { dataset: e });
625
- if (p.status === "loading" || p.status === "idle") return /* @__PURE__ */ E(Y, { status: p.status });
626
- if (p.status === "error") return /* @__PURE__ */ E(Y, {
647
+ var Fe = "cursor-pointer hover:bg-accent/40";
648
+ function Ie({ dataset: e, rows: t, values: n, runtimeFilter: r, dataSource: i, onDrill: o, order: s, withTotals: c }) {
649
+ let l = Z(e, t, n, r, i, c && t.length > 0 ? [[]] : void 0, s), { fieldLabel: f } = U(), p = W(), m = H(), h = O(l.object, l.dimensionFields, t);
650
+ if (n.length === 0) return /* @__PURE__ */ R(Ne, { dataset: e });
651
+ if (l.status === "loading" || l.status === "idle") return /* @__PURE__ */ R(Q, { status: l.status });
652
+ if (l.status === "error") return /* @__PURE__ */ R(Q, {
627
653
  status: "error",
628
- error: p.error
654
+ error: l.error
629
655
  });
630
- if (p.rows.length === 0) return /* @__PURE__ */ E(he, {});
631
- let y = !!u && a.length > 0, b = p.dimensionFields ? a.filter((e) => e in p.dimensionFields) : [], x = (n, r) => {
632
- let i = {};
633
- for (let e of a) i[e] = n[e];
634
- let o = p.drillRanges?.[r], c = !!o && Object.keys(o).length > 0, l = p.object && (b.length > 0 || c) ? t(p.drillRawRows?.[r], b, p.dimensionFields ?? {}, s, o) : void 0;
635
- u({
656
+ if (l.rows.length === 0) return /* @__PURE__ */ R(Pe, {});
657
+ let g = !!o && t.length > 0, _ = l.dimensionFields ? t.filter((e) => e in l.dimensionFields) : [], y = (n, i) => {
658
+ let a = {};
659
+ for (let e of t) a[e] = n[e];
660
+ let s = l.drillRanges?.[i], c = !!s && Object.keys(s).length > 0, u;
661
+ if (l.object && (_.length > 0 || c)) {
662
+ let e = Me(l.drillRawRows?.[i], _, l.dimensionFields ?? {}, r, s);
663
+ if (e === null) return;
664
+ u = e;
665
+ }
666
+ o({
636
667
  dataset: e,
637
- groupKey: i,
638
- runtimeFilter: s,
639
- object: p.object,
640
- objectFilter: l
668
+ groupKey: a,
669
+ runtimeFilter: r,
670
+ object: l.object,
671
+ objectFilter: u
641
672
  });
642
- }, { measureField: S, headerLabel: C } = n(p.fields, p.object, m), w = [...a, ...o], T = l(p.rows, v), O = f ? p.totals?.find((e) => Array.isArray(e.dimensions) && e.dimensions.length === 0)?.rows?.[0] : void 0, k = h("report.total", "Total");
643
- return /* @__PURE__ */ E("div", {
673
+ }, { measureField: b, headerLabel: x } = a(l.fields, l.object, f, V(p)), S = [...t, ...n], C = v(l.rows, h), w = c ? l.totals?.find((e) => Array.isArray(e.dimensions) && e.dimensions.length === 0)?.rows?.[0] : void 0, T = p("report.total", "Total");
674
+ return /* @__PURE__ */ R("div", {
644
675
  className: "overflow-auto max-h-[70vh] rounded-md border",
645
- children: /* @__PURE__ */ D("table", {
676
+ children: /* @__PURE__ */ z("table", {
646
677
  className: "w-full text-xs",
647
- children: [/* @__PURE__ */ E("thead", {
678
+ children: [/* @__PURE__ */ R("thead", {
648
679
  className: "bg-muted/40",
649
- children: /* @__PURE__ */ E("tr", { children: w.map((e) => /* @__PURE__ */ E("th", {
680
+ children: /* @__PURE__ */ R("tr", { children: S.map((e) => /* @__PURE__ */ R("th", {
650
681
  className: "px-2 py-1.5 text-left font-medium whitespace-nowrap",
651
- children: C(e)
682
+ children: x(e)
652
683
  }, e)) })
653
- }), /* @__PURE__ */ D("tbody", { children: [T.map((e, t) => /* @__PURE__ */ E("tr", {
654
- className: `border-t${y ? ` ${ge}` : ""}`,
655
- "data-testid": y ? "dataset-drill-row" : void 0,
656
- onClick: y ? () => x(p.rows[t], t) : void 0,
657
- children: w.map((t) => /* @__PURE__ */ E("td", {
684
+ }), /* @__PURE__ */ z("tbody", { children: [C.map((e, t) => /* @__PURE__ */ R("tr", {
685
+ className: `border-t${g ? ` ${Fe}` : ""}`,
686
+ "data-testid": g ? "dataset-drill-row" : void 0,
687
+ onClick: g ? () => y(l.rows[t], t) : void 0,
688
+ children: S.map((t) => /* @__PURE__ */ R("td", {
658
689
  className: "px-2 py-1 tabular-nums whitespace-nowrap",
659
- children: o.includes(t) ? i(e[t], S(t)?.format, S(t)?.currency, S(t)?.percentScale, g) : r(e[t], g)
690
+ children: n.includes(t) ? d(e[t], b(t)?.format, b(t)?.currency, b(t)?.percentScale, m) : u(e[t], m)
660
691
  }, t))
661
- }, t)), O && /* @__PURE__ */ D("tr", {
692
+ }, t)), w && /* @__PURE__ */ z("tr", {
662
693
  className: "border-t bg-muted/30 font-medium",
663
694
  "data-testid": "dataset-report-total-row",
664
- children: [a.length > 0 && /* @__PURE__ */ E("td", {
665
- colSpan: a.length,
695
+ children: [t.length > 0 && /* @__PURE__ */ R("td", {
696
+ colSpan: t.length,
666
697
  className: "px-2 py-1 whitespace-nowrap",
667
- children: k
668
- }), o.map((e) => /* @__PURE__ */ E("td", {
698
+ children: T
699
+ }), n.map((e) => /* @__PURE__ */ R("td", {
669
700
  className: "px-2 py-1 tabular-nums whitespace-nowrap",
670
- children: i(O[e], S(e)?.format, S(e)?.currency, S(e)?.percentScale, g)
701
+ children: d(w[e], b(e)?.format, b(e)?.currency, b(e)?.percentScale, m)
671
702
  }, e))]
672
703
  })] })]
673
704
  })
674
705
  });
675
706
  }
676
- function ve(e) {
707
+ function Le(e) {
677
708
  switch (e) {
678
709
  case "summary": return "summary";
679
710
  case "matrix": return "matrix";
@@ -681,7 +712,7 @@ function ve(e) {
681
712
  default: return "tabular";
682
713
  }
683
714
  }
684
- function ye(e) {
715
+ function Re(e) {
685
716
  switch (e) {
686
717
  case "bar":
687
718
  case "column":
@@ -712,9 +743,9 @@ function ye(e) {
712
743
  };
713
744
  }
714
745
  }
715
- function be(t) {
716
- let [, n] = u.useReducer((e) => e + 1, 0);
717
- return u.useEffect(() => {
746
+ function ze(t) {
747
+ let [, n] = b.useReducer((e) => e + 1, 0);
748
+ return b.useEffect(() => {
718
749
  if (e.get(t)) return;
719
750
  let r = typeof e.subscribe == "function" ? e.subscribe(() => {
720
751
  e.get(t) && n();
@@ -722,215 +753,252 @@ function be(t) {
722
753
  return i && typeof i.then == "function" && i.then(() => n()).catch(() => {}), r;
723
754
  }, [t]), e.get(t);
724
755
  }
725
- function xe({ dataset: e, chart: t, runtimeFilter: r, dataSource: a, order: o }) {
726
- let s = typeof t.xAxis == "string" ? t.xAxis : "", c = typeof t.yAxis == "string" ? t.yAxis : "", d = ye(t.type), f = d.kind === "series" || d.kind === "single_value", p = J(e, d.kind === "series" && s ? [s] : [], f && c ? [c] : [], r, a, void 0, o), m = be("chart"), { fieldLabel: h } = I(), g = F(), v = u.useMemo(() => s ? [s] : [], [s]), y = _(p.object, p.dimensionFields, v), b = typeof t.title == "string" ? t.title : void 0;
727
- if (d.kind === "tabular") return null;
728
- if (d.kind === "unsupported") return /* @__PURE__ */ D("div", {
756
+ function Be(e, t, n) {
757
+ if (Array.isArray(e) && t) for (let r of e) {
758
+ if (!r || typeof r != "object") continue;
759
+ let { name: e, label: i } = r;
760
+ if (e === t) return ce(i, n) || void 0;
761
+ }
762
+ }
763
+ function Ve({ dataset: e, chart: t, runtimeFilter: i, dataSource: u, order: m }) {
764
+ let h = typeof t.xAxis == "string" ? t.xAxis : "", g = typeof t.yAxis == "string" ? t.yAxis : "", _ = Re(t.type), y = _.kind === "series" || _.kind === "single_value", x = Z(e, _.kind === "series" && h ? [h] : [], y && g ? [g] : [], i, u, void 0, m), S = ze("chart"), { fieldLabel: C, fieldOptionLabel: w } = U(), T = W(), E = H(), { language: D } = le(), O = b.useMemo(() => h ? [h] : [], [h]), A = k(x.object, x.dimensionFields, O), { categoryColors: j, dimensionLabels: M, categoryOrder: N } = b.useMemo(() => {
765
+ if (!A) return {
766
+ categoryColors: null,
767
+ dimensionLabels: null,
768
+ categoryOrder: null
769
+ };
770
+ let { metaByPath: e, relabel: t } = A, r = t[0]?.path, i = r ? e[r] : void 0, a = r ? f(i?.options, l(i, w)) : void 0;
771
+ return {
772
+ categoryColors: o(a),
773
+ dimensionLabels: c(e, t, w),
774
+ categoryOrder: n(a)
775
+ };
776
+ }, [A, w]), P = ce(t.title, D) || void 0;
777
+ if (_.kind === "tabular") return null;
778
+ if (_.kind === "unsupported") return /* @__PURE__ */ z("div", {
729
779
  className: "rounded-md border border-dashed bg-muted/20 px-3 py-2 text-xs text-muted-foreground",
730
780
  "data-testid": "dataset-report-chart-unsupported",
731
781
  children: [
732
782
  "Chart type “",
733
- d.type,
734
- "” is not a spec chart type — the grouped table below carries this report’s numbers."
783
+ _.type,
784
+ "” is not a spec chart type — the report’s table carries its numbers."
735
785
  ]
736
786
  });
737
- if (d.kind === "series" && !s || !c) return null;
738
- if (p.status === "loading" || p.status === "idle") return /* @__PURE__ */ D("div", {
787
+ if (_.kind === "series" && !h || !g) return null;
788
+ if (x.status === "loading" || x.status === "idle") return /* @__PURE__ */ z("div", {
739
789
  className: "flex items-center gap-2 p-4 text-xs text-muted-foreground",
740
- children: [/* @__PURE__ */ E(A, { className: "h-4 w-4 animate-spin" }), " Loading chart…"]
790
+ children: [/* @__PURE__ */ R(ne, { className: "h-4 w-4 animate-spin" }), " Loading chart…"]
741
791
  });
742
- if (p.status === "error" || p.rows.length === 0) return null;
743
- if (d.kind === "single_value") {
744
- let { measureField: e, headerLabel: t } = n(p.fields, p.object, h), r = e(c);
745
- return /* @__PURE__ */ D("div", {
792
+ if (x.status === "error" || x.rows.length === 0) return null;
793
+ let { measureField: F, headerLabel: I } = a(x.fields, x.object, C, V(T)), L = Be(t.series, g, D) ?? I(g);
794
+ if (_.kind === "single_value") {
795
+ let e = F(g);
796
+ return /* @__PURE__ */ z("div", {
746
797
  className: "rounded-md border bg-card p-3",
747
798
  "data-testid": "dataset-report-metric",
748
- children: [b ? /* @__PURE__ */ E("h3", {
799
+ children: [P ? /* @__PURE__ */ R("h3", {
749
800
  className: "mb-2 text-sm font-semibold",
750
- children: b
751
- }) : null, /* @__PURE__ */ D("div", {
801
+ children: P
802
+ }) : null, /* @__PURE__ */ z("div", {
752
803
  className: "flex flex-col gap-0.5 py-2",
753
- children: [/* @__PURE__ */ E("span", {
804
+ children: [/* @__PURE__ */ R("span", {
754
805
  className: "text-2xl font-semibold tabular-nums",
755
- children: i(p.rows[0]?.[c], r?.format, r?.currency, r?.percentScale, g)
756
- }), /* @__PURE__ */ E("span", {
806
+ children: d(x.rows[0]?.[g], e?.format, e?.currency, e?.percentScale, E)
807
+ }), /* @__PURE__ */ R("span", {
757
808
  className: "text-xs text-muted-foreground",
758
- children: t(c)
809
+ children: L
759
810
  })]
760
811
  })]
761
812
  });
762
813
  }
763
- return m ? /* @__PURE__ */ D("div", {
814
+ if (!S) return null;
815
+ let { data: ee, xAxisKey: te, series: B } = r(v(x.rows, M), [h], [g], x.fields, {
816
+ nullCategoryLabel: T("chart.nullCategory", "(None)"),
817
+ builtinAggregateLabels: V(T)
818
+ }), re = p(B, t.series).map((e) => e.dataKey === g ? {
819
+ ...e,
820
+ label: L
821
+ } : e), { title: ie, ...ae } = s(t, j);
822
+ return /* @__PURE__ */ z("div", {
764
823
  className: "rounded-md border bg-card p-3",
765
824
  "data-testid": "dataset-report-chart",
766
- children: [b ? /* @__PURE__ */ E("h3", {
825
+ children: [P ? /* @__PURE__ */ R("h3", {
767
826
  className: "mb-2 text-sm font-semibold",
768
- children: b
769
- }) : null, /* @__PURE__ */ E(m, { schema: {
770
- chartType: d.chartType,
771
- data: l(p.rows, y),
772
- xAxisKey: s,
773
- series: [{ dataKey: c }],
774
- height: typeof t.height == "number" ? t.height : 280,
775
- isAnimationActive: !1
827
+ children: P
828
+ }) : null, /* @__PURE__ */ R(S, { schema: {
829
+ chartType: _.chartType,
830
+ data: ee,
831
+ xAxisKey: te,
832
+ series: re,
833
+ height: 280,
834
+ isAnimationActive: !1,
835
+ ...ae,
836
+ ...N ? { categoryOrder: N } : {}
776
837
  } })]
777
- }) : null;
838
+ });
778
839
  }
779
- function X(e, t) {
780
- return o(e.map((e) => c(t[e])));
840
+ function $(e, t) {
841
+ return h(e.map((e) => _(t[e])));
781
842
  }
782
- function Se(e, t, n) {
783
- return e.map((e) => r(t[e], n)).join(" / ");
843
+ function He(e, t, n) {
844
+ return e.map((e) => u(t[e], n)).join(" / ");
784
845
  }
785
- function Z({ dataset: e, rows: a, columnsAcross: o, values: c, runtimeFilter: d, dataSource: f, onDrill: p, order: m }) {
786
- let h = J(e, [...a, ...o], c, d, f, [
787
- a,
788
- o,
846
+ function Ue({ dataset: e, rows: t, columnsAcross: n, values: r, runtimeFilter: i, dataSource: o, onDrill: s, order: c }) {
847
+ let l = Z(e, [...t, ...n], r, i, o, [
848
+ t,
849
+ n,
789
850
  []
790
- ], m), g = L(), { fieldLabel: v } = I(), y = F(), b = _(h.object, h.dimensionFields, [...a, ...o]), x = u.useMemo(() => {
791
- if (h.status !== "ok") return null;
792
- let e = [], t = [], n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Map();
793
- return l(h.rows, b).forEach((c, l) => {
794
- let u = h.rows[l], d = X(a, c), f = X(o, c);
795
- if (!n.has(d)) {
796
- n.add(d);
797
- let t = {}, r = {};
798
- for (let e of a) t[e] = u[e], r[e] = c[e];
851
+ ], c), f = W(), { fieldLabel: p } = U(), m = H(), h = O(l.object, l.dimensionFields, [...t, ...n]), _ = b.useMemo(() => {
852
+ if (l.status !== "ok") return null;
853
+ let e = [], r = [], i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map();
854
+ return v(l.rows, h).forEach((s, c) => {
855
+ let u = l.rows[c], d = $(t, s), f = $(n, s);
856
+ if (!i.has(d)) {
857
+ i.add(d);
858
+ let n = {}, r = {};
859
+ for (let e of t) n[e] = u[e], r[e] = s[e];
799
860
  e.push({
800
861
  id: d,
801
- label: Se(a, c, y),
802
- key: t,
862
+ label: He(t, s, m),
863
+ key: n,
803
864
  display: r
804
865
  });
805
866
  }
806
- if (!r.has(f)) {
807
- r.add(f);
808
- let e = {}, n = {};
809
- for (let t of o) e[t] = u[t], n[t] = c[t];
810
- t.push({
867
+ if (!a.has(f)) {
868
+ a.add(f);
869
+ let e = {}, t = {};
870
+ for (let r of n) e[r] = u[r], t[r] = s[r];
871
+ r.push({
811
872
  id: f,
812
- label: Se(o, c, y),
873
+ label: He(n, s, m),
813
874
  key: e,
814
- display: n
875
+ display: t
815
876
  });
816
877
  }
817
- i.set(s(d, f), {
878
+ o.set(g(d, f), {
818
879
  row: u,
819
- index: l
880
+ index: c
820
881
  });
821
882
  }), {
822
883
  rowHeaders: e,
823
- colHeaders: t,
824
- cells: i
884
+ colHeaders: r,
885
+ cells: o
825
886
  };
826
887
  }, [
888
+ l,
889
+ t,
890
+ n,
827
891
  h,
828
- a,
829
- o,
830
- b,
831
- y
892
+ m
832
893
  ]);
833
- if (c.length === 0) return /* @__PURE__ */ E(me, { dataset: e });
834
- if (h.status === "loading" || h.status === "idle") return /* @__PURE__ */ E(Y, { status: h.status });
835
- if (h.status === "error") return /* @__PURE__ */ E(Y, {
894
+ if (r.length === 0) return /* @__PURE__ */ R(Ne, { dataset: e });
895
+ if (l.status === "loading" || l.status === "idle") return /* @__PURE__ */ R(Q, { status: l.status });
896
+ if (l.status === "error") return /* @__PURE__ */ R(Q, {
836
897
  status: "error",
837
- error: h.error
898
+ error: l.error
838
899
  });
839
- if (!x || x.rowHeaders.length === 0) return /* @__PURE__ */ E(he, {});
840
- let { measureField: S, headerLabel: C } = n(h.fields, h.object, v), w = g("report.total", "Total"), T = !!p, O = h.dimensionFields ? [...a, ...o].filter((e) => e in h.dimensionFields) : [], k = (n, r, i) => {
841
- let a = h.drillRanges?.[i], o = !!a && Object.keys(a).length > 0, s = h.object && (O.length > 0 || o) ? t(h.drillRawRows?.[i], O, h.dimensionFields ?? {}, d, a) : void 0;
842
- p({
900
+ if (!_ || _.rowHeaders.length === 0) return /* @__PURE__ */ R(Pe, {});
901
+ let { measureField: y, headerLabel: x } = a(l.fields, l.object, p, V(f)), S = f("report.total", "Total"), C = !!s, w = l.dimensionFields ? [...t, ...n].filter((e) => e in l.dimensionFields) : [], T = (t, n, r) => {
902
+ let a = l.drillRanges?.[r], o = !!a && Object.keys(a).length > 0, c;
903
+ if (l.object && (w.length > 0 || o)) {
904
+ let e = Me(l.drillRawRows?.[r], w, l.dimensionFields ?? {}, i, a);
905
+ if (e === null) return;
906
+ c = e;
907
+ }
908
+ s({
843
909
  dataset: e,
844
910
  groupKey: {
845
- ...n,
846
- ...r
911
+ ...t,
912
+ ...n
847
913
  },
848
- runtimeFilter: d,
849
- object: h.object,
850
- objectFilter: s
914
+ runtimeFilter: i,
915
+ object: l.object,
916
+ objectFilter: c
851
917
  });
852
- }, A = x.colHeaders.flatMap((e) => c.map((t) => ({
918
+ }, E = _.colHeaders.flatMap((e) => r.map((t) => ({
853
919
  col: e,
854
920
  measure: t,
855
- header: c.length === 1 ? e.label : `${e.label} · ${C(t)}`
856
- }))), j = (e) => {
857
- let t = h.totals?.find((t) => Array.isArray(t.dimensions) && t.dimensions.join(",") === e.join(","))?.rows;
858
- return t && l(t, b);
859
- }, M = /* @__PURE__ */ new Map();
860
- for (let e of j(a) ?? []) M.set(X(a, e), e);
861
- let N = /* @__PURE__ */ new Map();
862
- for (let e of j(o) ?? []) N.set(X(o, e), e);
863
- let ee = j([])?.[0], P = M.size > 0, R = N.size > 0;
864
- return /* @__PURE__ */ E("div", {
921
+ header: r.length === 1 ? e.label : `${e.label} · ${x(t)}`
922
+ }))), D = (e) => {
923
+ let t = l.totals?.find((t) => Array.isArray(t.dimensions) && t.dimensions.join(",") === e.join(","))?.rows;
924
+ return t && v(t, h);
925
+ }, k = /* @__PURE__ */ new Map();
926
+ for (let e of D(t) ?? []) k.set($(t, e), e);
927
+ let A = /* @__PURE__ */ new Map();
928
+ for (let e of D(n) ?? []) A.set($(n, e), e);
929
+ let j = D([])?.[0], M = k.size > 0, N = A.size > 0;
930
+ return /* @__PURE__ */ R("div", {
865
931
  className: "overflow-auto max-h-[70vh] rounded-md border",
866
932
  "data-testid": "dataset-matrix",
867
- children: /* @__PURE__ */ D("table", {
933
+ children: /* @__PURE__ */ z("table", {
868
934
  className: "w-full text-xs",
869
- children: [/* @__PURE__ */ E("thead", {
935
+ children: [/* @__PURE__ */ R("thead", {
870
936
  className: "bg-muted/40",
871
- children: /* @__PURE__ */ D("tr", { children: [
872
- a.map((e) => /* @__PURE__ */ E("th", {
937
+ children: /* @__PURE__ */ z("tr", { children: [
938
+ t.map((e) => /* @__PURE__ */ R("th", {
873
939
  className: "px-2 py-1.5 text-left font-medium whitespace-nowrap",
874
- children: C(e)
940
+ children: x(e)
875
941
  }, e)),
876
- A.map((e) => /* @__PURE__ */ E("th", {
942
+ E.map((e) => /* @__PURE__ */ R("th", {
877
943
  className: "px-2 py-1.5 text-right font-medium whitespace-nowrap",
878
944
  children: e.header
879
945
  }, `${e.col.id}-${e.measure}`)),
880
- P && c.map((e) => /* @__PURE__ */ E("th", {
946
+ M && r.map((e) => /* @__PURE__ */ R("th", {
881
947
  className: "px-2 py-1.5 text-right font-medium whitespace-nowrap",
882
948
  "data-testid": "matrix-total-col-header",
883
- children: c.length === 1 ? w : `${w} · ${C(e)}`
949
+ children: r.length === 1 ? S : `${S} · ${x(e)}`
884
950
  }, `total-${e}`))
885
951
  ] })
886
- }), /* @__PURE__ */ D("tbody", { children: [x.rowHeaders.map((e) => /* @__PURE__ */ D("tr", {
952
+ }), /* @__PURE__ */ z("tbody", { children: [_.rowHeaders.map((e) => /* @__PURE__ */ z("tr", {
887
953
  className: "border-t",
888
954
  children: [
889
- a.map((t) => /* @__PURE__ */ E("td", {
955
+ t.map((t) => /* @__PURE__ */ R("td", {
890
956
  className: "px-2 py-1 whitespace-nowrap font-medium",
891
- children: r(e.display[t], y)
957
+ children: u(e.display[t], m)
892
958
  }, t)),
893
- A.map((t) => {
894
- let n = x.cells.get(s(e.id, t.col.id)), r = n?.row[t.measure], a = T && n != null;
895
- return /* @__PURE__ */ E("td", {
896
- className: `px-2 py-1 text-right tabular-nums whitespace-nowrap${a ? ` ${ge}` : ""}`,
897
- "data-testid": a ? "dataset-drill-cell" : void 0,
898
- onClick: a ? () => k(e.key, t.col.key, n.index) : void 0,
899
- children: i(r, S(t.measure)?.format, S(t.measure)?.currency, S(t.measure)?.percentScale, y)
959
+ E.map((t) => {
960
+ let n = _.cells.get(g(e.id, t.col.id)), r = n?.row[t.measure], i = C && n != null;
961
+ return /* @__PURE__ */ R("td", {
962
+ className: `px-2 py-1 text-right tabular-nums whitespace-nowrap${i ? ` ${Fe}` : ""}`,
963
+ "data-testid": i ? "dataset-drill-cell" : void 0,
964
+ onClick: i ? () => T(e.key, t.col.key, n.index) : void 0,
965
+ children: d(r, y(t.measure)?.format, y(t.measure)?.currency, y(t.measure)?.percentScale, m)
900
966
  }, `${t.col.id}-${t.measure}`);
901
967
  }),
902
- P && c.map((t) => /* @__PURE__ */ E("td", {
968
+ M && r.map((t) => /* @__PURE__ */ R("td", {
903
969
  className: "px-2 py-1 text-right tabular-nums whitespace-nowrap font-medium",
904
970
  "data-testid": "matrix-row-total",
905
- children: i(M.get(e.id)?.[t], S(t)?.format, S(t)?.currency, S(t)?.percentScale, y)
971
+ children: d(k.get(e.id)?.[t], y(t)?.format, y(t)?.currency, y(t)?.percentScale, m)
906
972
  }, `total-${t}`))
907
973
  ]
908
- }, e.id)), R && /* @__PURE__ */ D("tr", {
974
+ }, e.id)), N && /* @__PURE__ */ z("tr", {
909
975
  className: "border-t bg-muted/30 font-medium",
910
976
  "data-testid": "matrix-total-row",
911
977
  children: [
912
- a.length > 0 && /* @__PURE__ */ E("td", {
913
- colSpan: a.length,
978
+ t.length > 0 && /* @__PURE__ */ R("td", {
979
+ colSpan: t.length,
914
980
  className: "px-2 py-1 whitespace-nowrap",
915
- children: w
981
+ children: S
916
982
  }),
917
- A.map((e) => /* @__PURE__ */ E("td", {
983
+ E.map((e) => /* @__PURE__ */ R("td", {
918
984
  className: "px-2 py-1 text-right tabular-nums whitespace-nowrap",
919
- children: i(N.get(e.col.id)?.[e.measure], S(e.measure)?.format, S(e.measure)?.currency, S(e.measure)?.percentScale, y)
985
+ children: d(A.get(e.col.id)?.[e.measure], y(e.measure)?.format, y(e.measure)?.currency, y(e.measure)?.percentScale, m)
920
986
  }, `${e.col.id}-${e.measure}`)),
921
- P && c.map((e) => /* @__PURE__ */ E("td", {
987
+ M && r.map((e) => /* @__PURE__ */ R("td", {
922
988
  className: "px-2 py-1 text-right tabular-nums whitespace-nowrap",
923
989
  "data-testid": "matrix-grand-total",
924
- children: i(ee?.[e], S(e)?.format, S(e)?.currency, S(e)?.percentScale, y)
990
+ children: d(j?.[e], y(e)?.format, y(e)?.currency, y(e)?.percentScale, m)
925
991
  }, `grand-${e}`))
926
992
  ]
927
993
  })] })]
928
994
  })
929
995
  });
930
996
  }
931
- var Ce = ({ report: e, dataSource: t, runtimeFilter: n, onDrill: r, className: i }) => {
932
- let o = a(e.runtimeFilter ?? e.filter, n), s = e.drilldown === !1 ? void 0 : r, c = ve(e.type);
933
- if (c === "joined" && Array.isArray(e.blocks)) return /* @__PURE__ */ E("div", {
997
+ var We = ({ report: e, dataSource: t, runtimeFilter: n, onDrill: r, className: i }) => {
998
+ let a = Oe(e);
999
+ De(e, a);
1000
+ let o = m(e.runtimeFilter, n), s = e.drilldown === !1 ? void 0 : r, c = Le(e.type);
1001
+ if (c === "joined" && Array.isArray(e.blocks)) return /* @__PURE__ */ R("div", {
934
1002
  className: i,
935
1003
  "data-testid": "dataset-joined-report",
936
1004
  "data-report-name": e.name,
@@ -940,140 +1008,134 @@ var Ce = ({ report: e, dataSource: t, runtimeFilter: n, onDrill: r, className: i
940
1008
  gap: 24
941
1009
  },
942
1010
  children: e.blocks.map((e, n) => {
943
- let r = a(o, e.runtimeFilter ?? e.filter), i = q(e.columns), c = fe(e.order), l = ve(e.type), u = l === "matrix" && i.length > 0 ? /* @__PURE__ */ E(Z, {
1011
+ De(e, `${a} block \`${e.name ?? n}\``);
1012
+ let r = m(o, e.runtimeFilter), i = X(e.columns), c = Ae(e.order), l = Le(e.type), u = l === "matrix" && i.length > 0 ? /* @__PURE__ */ R(Ue, {
944
1013
  dataset: String(e.dataset ?? ""),
945
- rows: q(e.rows),
1014
+ rows: X(e.rows),
946
1015
  columnsAcross: i,
947
- values: q(e.values),
1016
+ values: X(e.values),
948
1017
  runtimeFilter: r,
949
1018
  dataSource: t,
950
1019
  onDrill: s,
951
1020
  order: c
952
- }) : /* @__PURE__ */ E(_e, {
1021
+ }) : /* @__PURE__ */ R(Ie, {
953
1022
  dataset: String(e.dataset ?? ""),
954
- rows: q(e.rows),
955
- values: q(e.values),
1023
+ rows: X(e.rows),
1024
+ values: X(e.values),
956
1025
  runtimeFilter: r,
957
1026
  dataSource: t,
958
1027
  onDrill: s,
959
1028
  order: c,
960
1029
  withTotals: l === "summary" || l === "matrix"
961
1030
  });
962
- return /* @__PURE__ */ D("section", {
1031
+ return /* @__PURE__ */ z("section", {
963
1032
  "data-testid": "dataset-report-block",
964
1033
  "data-block-id": e.name ?? `block-${n}`,
965
1034
  className: "flex flex-col gap-2 rounded-lg border bg-card p-4",
966
- children: [/* @__PURE__ */ D("header", {
1035
+ children: [/* @__PURE__ */ z("header", {
967
1036
  className: "flex flex-col gap-0.5",
968
- children: [/* @__PURE__ */ E("h3", {
1037
+ children: [/* @__PURE__ */ R("h3", {
969
1038
  className: "text-sm font-semibold",
970
- children: de(e.label, e.name ?? `Block ${n + 1}`)
971
- }), e.description ? /* @__PURE__ */ E("p", {
1039
+ children: ke(e.label, e.name ?? `Block ${n + 1}`)
1040
+ }), e.description ? /* @__PURE__ */ R("p", {
972
1041
  className: "text-xs text-muted-foreground",
973
- children: de(e.description, "")
1042
+ children: ke(e.description, "")
974
1043
  }) : null]
975
1044
  }), u]
976
1045
  }, e.name ?? `block-${n}`);
977
1046
  })
978
1047
  });
979
- let l = q(e.columns), u = fe(e.order);
980
- if (c === "matrix" && l.length > 0) return /* @__PURE__ */ E("div", {
981
- className: i,
982
- "data-testid": "dataset-report",
983
- "data-report-name": e.name,
984
- children: /* @__PURE__ */ E(Z, {
985
- dataset: String(e.dataset ?? ""),
986
- rows: q(e.rows),
987
- columnsAcross: l,
988
- values: q(e.values),
989
- runtimeFilter: o,
990
- dataSource: t,
991
- onDrill: s,
992
- order: u
993
- })
1048
+ let l = X(e.columns), u = Ae(e.order), d = c === "matrix" && l.length > 0, f = e.chart && typeof e.chart == "object" && e.chart.type ? e.chart : null, p = f ? /* @__PURE__ */ R(Ve, {
1049
+ dataset: String(e.dataset ?? ""),
1050
+ chart: f,
1051
+ runtimeFilter: o,
1052
+ dataSource: t,
1053
+ order: u
1054
+ }) : null, h = d ? /* @__PURE__ */ R(Ue, {
1055
+ dataset: String(e.dataset ?? ""),
1056
+ rows: X(e.rows),
1057
+ columnsAcross: l,
1058
+ values: X(e.values),
1059
+ runtimeFilter: o,
1060
+ dataSource: t,
1061
+ onDrill: s,
1062
+ order: u
1063
+ }) : /* @__PURE__ */ R(Ie, {
1064
+ dataset: String(e.dataset ?? ""),
1065
+ rows: X(e.rows),
1066
+ values: X(e.values),
1067
+ runtimeFilter: o,
1068
+ dataSource: t,
1069
+ onDrill: s,
1070
+ order: u,
1071
+ withTotals: c === "summary" || c === "matrix"
994
1072
  });
995
- let d = e.chart && typeof e.chart == "object" && e.chart.type ? e.chart : null;
996
- return /* @__PURE__ */ D("div", {
1073
+ return /* @__PURE__ */ z("div", {
997
1074
  className: `${i ?? ""} flex flex-col gap-3`,
998
1075
  "data-testid": "dataset-report",
999
1076
  "data-report-name": e.name,
1000
1077
  "data-report-presentation": c,
1001
- children: [d ? /* @__PURE__ */ E(xe, {
1002
- dataset: String(e.dataset ?? ""),
1003
- chart: d,
1004
- runtimeFilter: o,
1005
- dataSource: t,
1006
- order: u
1007
- }) : null, /* @__PURE__ */ E(_e, {
1008
- dataset: String(e.dataset ?? ""),
1009
- rows: q(e.rows),
1010
- values: q(e.values),
1011
- runtimeFilter: o,
1012
- dataSource: t,
1013
- onDrill: s,
1014
- order: u,
1015
- withTotals: c === "summary" || c === "matrix"
1016
- })]
1078
+ children: [d ? h : p, d ? p : h]
1017
1079
  });
1018
- }, Q = (e) => {
1019
- let { dataSource: t, rows: n, runtimeFilter: r, onDrill: i, className: a } = e, o = u.useContext(h), s = t ?? o?.dataSource, c = e.schema;
1020
- if (c && typeof c == "object" && c.type === "spec-report" && c.report && typeof c.report == "object" && (c = c.report), K(c)) return /* @__PURE__ */ E(Ce, {
1080
+ }, Ge = (e) => {
1081
+ let { dataSource: t, rows: n, runtimeFilter: r, onDrill: i, className: a } = e, o = b.useContext(T), s = t ?? o?.dataSource, c = e.schema;
1082
+ if (c && typeof c == "object" && c.type === "report" && c.report && typeof c.report == "object" && (c = c.report), we(c)) return /* @__PURE__ */ R(We, {
1021
1083
  report: c,
1022
1084
  dataSource: s,
1023
1085
  runtimeFilter: r,
1024
1086
  onDrill: i,
1025
1087
  className: a
1026
1088
  });
1027
- if (f(c)) {
1089
+ if (S(c)) {
1028
1090
  let e = {
1029
1091
  type: "report-viewer",
1030
- report: p(c),
1092
+ report: C(c),
1031
1093
  data: n ?? [],
1032
1094
  showToolbar: !1
1033
1095
  };
1034
- return /* @__PURE__ */ E("div", {
1096
+ return /* @__PURE__ */ R("div", {
1035
1097
  className: a,
1036
1098
  "data-testid": "report-presentation-bridge",
1037
- children: /* @__PURE__ */ E(G, { schema: e })
1099
+ children: /* @__PURE__ */ R(Ce, { schema: e })
1038
1100
  });
1039
1101
  }
1040
- return /* @__PURE__ */ E(R, { schema: c });
1102
+ return /* @__PURE__ */ R(ue, { schema: c });
1041
1103
  };
1042
1104
  //#endregion
1043
1105
  //#region src/LiveReportExporter.ts
1044
- async function $(e, t) {
1045
- let { dataSource: n, resource: r, queryParams: i, format: a, exportConfig: o } = t, s = a || e.defaultExportFormat || "pdf";
1106
+ async function Ke(e, t) {
1107
+ let { dataSource: n, resource: r, queryParams: i, format: a, exportConfig: o, locale: s } = t, c = a || e.defaultExportFormat || "pdf";
1046
1108
  try {
1047
1109
  let t = (await n.find(r, i)).data || [];
1048
- return V(s, e, t, {
1049
- format: s,
1050
- ...e.exportConfigs?.[s],
1110
+ return he(c, e, t, {
1111
+ format: c,
1112
+ ...e.exportConfigs?.[c],
1051
1113
  ...o
1052
- }), {
1114
+ }, s), {
1053
1115
  success: !0,
1054
1116
  recordCount: t.length,
1055
- format: s
1117
+ format: c
1056
1118
  };
1057
1119
  } catch (e) {
1058
1120
  return {
1059
1121
  success: !1,
1060
1122
  recordCount: 0,
1061
- format: s,
1123
+ format: c,
1062
1124
  error: e.message
1063
1125
  };
1064
1126
  }
1065
1127
  }
1066
- function we(e, t, n = {}) {
1067
- let { columns: r, filename: i, includeAggregationRow: a = !1 } = n, o = r || (e.fields || []).map(Ee), s = o.map((e) => e.header), c = t.map((e, t) => o.map((n) => {
1128
+ function qe(e, t, n = {}) {
1129
+ let { columns: r, filename: i, includeAggregationRow: a = !1, locale: o = "en" } = n, s = r || (e.fields || []).map(Ye), c = s.map((e) => e.header), l = t.map((e, t) => s.map((n) => {
1068
1130
  if (n.formula) return n.formula.replace(/\{ROW\}/g, String(t + 2));
1069
1131
  let r = e[n.name];
1070
- return De(r, n.numberFormat);
1132
+ return Xe(r, n.numberFormat, o);
1071
1133
  }));
1072
1134
  if (a && t.length > 0) {
1073
- let n = o.map((n, r) => {
1135
+ let n = s.map((n, r) => {
1074
1136
  let i = (e.fields || []).find((e) => e.name === n.name);
1075
1137
  if (i?.aggregation) {
1076
- let e = ke(r), n = t.length + 1;
1138
+ let e = Qe(r), n = t.length + 1;
1077
1139
  switch (i.aggregation) {
1078
1140
  case "sum": return `=SUM(${e}2:${e}${n})`;
1079
1141
  case "avg": return `=AVERAGE(${e}2:${e}${n})`;
@@ -1085,17 +1147,17 @@ function we(e, t, n = {}) {
1085
1147
  }
1086
1148
  return "";
1087
1149
  });
1088
- c.push(n);
1150
+ l.push(n);
1089
1151
  }
1090
- je("" + [s.join(" "), ...c.map((e) => e.join(" "))].join("\n"), i || `${e.title || "report"}.tsv`, "text/tab-separated-values");
1152
+ et("" + [c.join(" "), ...l.map((e) => e.join(" "))].join("\n"), i || `${e.title || "report"}.tsv`, "text/tab-separated-values");
1091
1153
  }
1092
- function Te(e, t, n, r) {
1154
+ function Je(e, t, n, r) {
1093
1155
  return async () => {
1094
1156
  let i = e.schedule;
1095
1157
  if (!i?.enabled) return [];
1096
1158
  let a = i.formats || [e.defaultExportFormat || "pdf"], o = [];
1097
1159
  for (let r of a) {
1098
- let i = await $(e, {
1160
+ let i = await Ke(e, {
1099
1161
  dataSource: t,
1100
1162
  resource: n,
1101
1163
  format: r
@@ -1105,16 +1167,16 @@ function Te(e, t, n, r) {
1105
1167
  return r(e, i), o;
1106
1168
  };
1107
1169
  }
1108
- function Ee(e) {
1170
+ function Ye(e) {
1109
1171
  return {
1110
1172
  name: e.name,
1111
1173
  header: e.label || e.name
1112
1174
  };
1113
1175
  }
1114
- function De(e, t) {
1115
- return e == null ? "" : typeof e == "number" && t ? e.toLocaleString("en-US", Oe(t)) : Ae(String(e));
1176
+ function Xe(e, t, n = "en") {
1177
+ return e == null ? "" : typeof e == "number" && t ? G(e, n, Ze(t)) : $e(String(e));
1116
1178
  }
1117
- function Oe(e) {
1179
+ function Ze(e) {
1118
1180
  if (e.includes("%")) return {
1119
1181
  style: "percent",
1120
1182
  minimumFractionDigits: 0
@@ -1125,69 +1187,56 @@ function Oe(e) {
1125
1187
  maximumFractionDigits: Math.max(0, t - 1)
1126
1188
  };
1127
1189
  }
1128
- function ke(e) {
1190
+ function Qe(e) {
1129
1191
  let t = "", n = e;
1130
1192
  for (; n >= 0;) t = String.fromCharCode(n % 26 + 65) + t, n = Math.floor(n / 26) - 1;
1131
1193
  return t;
1132
1194
  }
1133
- function Ae(e) {
1195
+ function $e(e) {
1134
1196
  if (e.length > 0) {
1135
1197
  let t = e.charAt(0);
1136
1198
  if (t === "=" || t === "+" || t === "-" || t === "@" || t === "|") return `'${e}`;
1137
1199
  }
1138
1200
  return e;
1139
1201
  }
1140
- function je(e, t, n) {
1202
+ function et(e, t, n) {
1141
1203
  let r = new Blob([e], { type: `${n};charset=utf-8` }), i = URL.createObjectURL(r), a = document.createElement("a");
1142
1204
  a.href = i, a.download = t, document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(i);
1143
1205
  }
1144
- e.register("report", Q, {
1145
- namespace: "report",
1206
+ e.register("report", Ge, {
1207
+ namespace: "plugin-report",
1146
1208
  label: "Report",
1147
1209
  category: "Report",
1148
1210
  inputs: [
1149
1211
  {
1150
1212
  name: "title",
1151
- type: "string",
1152
- label: "Title"
1213
+ type: "string"
1153
1214
  },
1154
1215
  {
1155
1216
  name: "description",
1156
- type: "string",
1157
- label: "Description"
1217
+ type: "string"
1158
1218
  },
1159
1219
  {
1160
1220
  name: "chart",
1161
- type: "code",
1162
- label: "Chart Configuration"
1221
+ type: "code"
1222
+ },
1223
+ {
1224
+ name: "report",
1225
+ type: "object",
1226
+ description: "The report to render, as `@objectstack/spec` declares it (`ReportSchema`: `name`, `label`, `type`, `dataset`, `rows`, `values`, …). When present, the block renders this report and reads none of its own presentation inputs."
1163
1227
  }
1164
1228
  ]
1165
- }), e.register("spec-report", Q, {
1166
- namespace: "report",
1167
- label: "Spec Report",
1168
- category: "Report",
1169
- inputs: [{
1170
- name: "dataset",
1171
- type: "string",
1172
- label: "Dataset"
1173
- }, {
1174
- name: "type",
1175
- type: "string",
1176
- label: "Report Type"
1177
- }]
1178
- }), e.register("report-viewer", G, {
1179
- namespace: "report",
1229
+ }), e.register("report-viewer", Ce, {
1230
+ namespace: "plugin-report",
1180
1231
  label: "Report Viewer",
1181
1232
  category: "Report",
1182
1233
  inputs: [{
1183
1234
  name: "report",
1184
- type: "code",
1185
- label: "Report Definition"
1235
+ type: "code"
1186
1236
  }, {
1187
1237
  name: "showToolbar",
1188
- type: "boolean",
1189
- label: "Show Toolbar"
1238
+ type: "boolean"
1190
1239
  }]
1191
1240
  });
1192
1241
  //#endregion
1193
- export { Ce as DatasetReportRenderer, R as LegacyReportRenderer, Q as ReportRenderer, G as ReportViewer, Te as createScheduleTrigger, te as exportAsCSV, B as exportAsExcel, z as exportAsHTML, ne as exportAsJSON, re as exportAsPDF, we as exportExcelWithFormulas, V as exportReport, $ as exportWithLiveData, W as formatValue, K as isDatasetReport, a as mergeFilters };
1242
+ export { We as DatasetReportRenderer, ue as LegacyReportRenderer, Ge as ReportRenderer, Ce as ReportViewer, Je as createScheduleTrigger, de as exportAsCSV, me as exportAsExcel, K as exportAsHTML, fe as exportAsJSON, pe as exportAsPDF, qe as exportExcelWithFormulas, he as exportReport, Ke as exportWithLiveData, Y as formatValue, we as isDatasetReport, m as mergeFilters };