@object-ui/plugin-report 16.0.0 → 17.1.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
@@ -6,10 +6,10 @@ import { SchemaRenderer as u, SchemaRendererContext as d } from "@object-ui/reac
6
6
  import { Badge as f, Button as p, Card as m, CardContent as h, CardDescription as g, CardHeader as _, CardTitle as v, Skeleton as y } from "@object-ui/components";
7
7
  import { jsx as b, jsxs as x } from "react/jsx-runtime";
8
8
  import { AlertTriangle as S, Download as C, Loader2 as w, Printer as T, RefreshCw as E, Table2 as D } from "lucide-react";
9
- import { getCellRenderer as O, resolveCellRendererType as k } from "@object-ui/fields";
10
- import { useSafeFieldLabel as A, useSafeTranslate as j } from "@object-ui/i18n";
9
+ import { getCellRenderer as O, resolveCellRendererType as ee } from "@object-ui/fields";
10
+ import { useSafeFieldLabel as k, useSafeTranslate as A } from "@object-ui/i18n";
11
11
  //#region src/LegacyReportRenderer.tsx
12
- var M = ({ schema: t }) => {
12
+ var j = ({ 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;
@@ -64,29 +64,29 @@ var M = ({ schema: t }) => {
64
64
  };
65
65
  //#endregion
66
66
  //#region src/ReportExportEngine.ts
67
- function N(e, t, n) {
67
+ function M(e, t, n) {
68
68
  let r = e.fields || [], i = r.map((e) => e.label || e.name), a = t.map((e) => r.map((t) => {
69
69
  let n = e[t.name];
70
- return n = z(n), typeof n == "string" && (n.includes(",") || n.includes("\"") || n.includes("\n")) ? `"${n.replace(/"/g, "\"\"")}"` : n ?? "";
70
+ return n = R(n), typeof n == "string" && (n.includes(",") || n.includes("\"") || n.includes("\n")) ? `"${n.replace(/"/g, "\"\"")}"` : n ?? "";
71
71
  }));
72
- V([...n?.includeHeaders === !1 ? [] : [i.join(",")], ...a.map((e) => e.join(","))].join("\n"), n?.filename || `${e.title || "report"}.csv`, "text/csv");
72
+ z([...n?.includeHeaders === !1 ? [] : [i.join(",")], ...a.map((e) => e.join(","))].join("\n"), n?.filename || `${e.title || "report"}.csv`, "text/csv");
73
73
  }
74
- function P(e, t, n) {
74
+ function N(e, t, n) {
75
75
  let r = {
76
76
  title: e.title,
77
77
  description: e.description,
78
78
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
79
79
  data: t
80
80
  };
81
- V(JSON.stringify(r, null, 2), n?.filename || `${e.title || "report"}.json`, "application/json");
81
+ z(JSON.stringify(r, null, 2), n?.filename || `${e.title || "report"}.json`, "application/json");
82
82
  }
83
- function F(e, t, n) {
84
- let r = e.fields || [], i = te(n?.orientation), a = B(n?.pageSize);
85
- V(`<!DOCTYPE html>
83
+ function P(e, t, n) {
84
+ let r = e.fields || [], i = re(n?.orientation), a = ne(n?.pageSize);
85
+ z(`<!DOCTYPE html>
86
86
  <html>
87
87
  <head>
88
88
  <meta charset="utf-8">
89
- <title>${R(e.title || "Report")}</title>
89
+ <title>${L(e.title || "Report")}</title>
90
90
  <style>
91
91
  @page { size: ${a} ${i}; margin: 20mm; }
92
92
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #333; }
@@ -100,20 +100,20 @@ function F(e, t, n) {
100
100
  </style>
101
101
  </head>
102
102
  <body>
103
- <h1>${R(e.title || "Report")}</h1>
104
- ${e.description ? `<p class="description">${R(e.description)}</p>` : ""}
103
+ <h1>${L(e.title || "Report")}</h1>
104
+ ${e.description ? `<p class="description">${L(e.description)}</p>` : ""}
105
105
  <p class="meta">Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}</p>
106
106
  <table>
107
- <thead><tr>${r.map((e) => `<th>${R(e.label || e.name)}</th>`).join("")}</tr></thead>
108
- <tbody>${t.map((e) => `<tr>${r.map((t) => `<td>${R(String(e[t.name] ?? ""))}</td>`).join("")}</tr>`).join("")}</tbody>
107
+ <thead><tr>${r.map((e) => `<th>${L(e.label || e.name)}</th>`).join("")}</tr></thead>
108
+ <tbody>${t.map((e) => `<tr>${r.map((t) => `<td>${L(String(e[t.name] ?? ""))}</td>`).join("")}</tr>`).join("")}</tbody>
109
109
  </table>
110
110
  </body>
111
111
  </html>`, n?.filename || `${e.title || "report"}.html`, "text/html");
112
112
  }
113
- function ee(e, t, n) {
114
- let r = e.fields || [], i = te(n?.orientation), a = B(n?.pageSize), o = window.open("", "_blank");
113
+ function te(e, t, n) {
114
+ let r = e.fields || [], i = re(n?.orientation), a = ne(n?.pageSize), o = window.open("", "_blank");
115
115
  if (!o) {
116
- F(e, t, {
116
+ P(e, t, {
117
117
  ...n,
118
118
  format: "html",
119
119
  filename: n?.filename?.replace(/\.pdf$/, ".html") || `${e.title || "report"}.html`
@@ -124,7 +124,7 @@ function ee(e, t, n) {
124
124
  <html>
125
125
  <head>
126
126
  <meta charset="utf-8">
127
- <title>${R(e.title || "Report")}</title>
127
+ <title>${L(e.title || "Report")}</title>
128
128
  <style>
129
129
  @page { size: ${a} ${i}; margin: 20mm; }
130
130
  @media print { .no-print { display: none; } }
@@ -139,56 +139,56 @@ function ee(e, t, n) {
139
139
  </style>
140
140
  </head>
141
141
  <body>
142
- <h1>${R(e.title || "Report")}</h1>
143
- ${e.description ? `<p class="description">${R(e.description)}</p>` : ""}
142
+ <h1>${L(e.title || "Report")}</h1>
143
+ ${e.description ? `<p class="description">${L(e.description)}</p>` : ""}
144
144
  <p class="meta">Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}</p>
145
145
  <table>
146
- <thead><tr>${r.map((e) => `<th>${R(e.label || e.name)}</th>`).join("")}</tr></thead>
147
- <tbody>${t.map((e) => `<tr>${r.map((t) => `<td>${R(String(e[t.name] ?? ""))}</td>`).join("")}</tr>`).join("")}</tbody>
146
+ <thead><tr>${r.map((e) => `<th>${L(e.label || e.name)}</th>`).join("")}</tr></thead>
147
+ <tbody>${t.map((e) => `<tr>${r.map((t) => `<td>${L(String(e[t.name] ?? ""))}</td>`).join("")}</tr>`).join("")}</tbody>
148
148
  </table>
149
149
  </body>
150
150
  </html>`), o.document.close(), o.onload = () => {
151
151
  o.print();
152
152
  };
153
153
  }
154
- function I(e, t, n) {
154
+ function F(e, t, n) {
155
155
  let r = e.fields || [], i = r.map((e) => e.label || e.name), a = t.map((e) => r.map((t) => {
156
156
  let n = e[t.name];
157
- return n = z(n), typeof n == "string" && (n.includes(",") || n.includes("\"") || n.includes("\n") || n.includes(" ")) ? `"${n.replace(/"/g, "\"\"")}"` : n ?? "";
157
+ return n = R(n), typeof n == "string" && (n.includes(",") || n.includes("\"") || n.includes("\n") || n.includes(" ")) ? `"${n.replace(/"/g, "\"\"")}"` : n ?? "";
158
158
  }));
159
- V("" + [...n?.includeHeaders === !1 ? [] : [i.join(" ")], ...a.map((e) => e.join(" "))].join("\n"), n?.filename || `${e.title || "report"}.tsv`, "text/tab-separated-values");
159
+ z("" + [...n?.includeHeaders === !1 ? [] : [i.join(" ")], ...a.map((e) => e.join(" "))].join("\n"), n?.filename || `${e.title || "report"}.tsv`, "text/tab-separated-values");
160
160
  }
161
- function L(e, t, n, r) {
161
+ function I(e, t, n, r) {
162
162
  switch (e) {
163
163
  case "csv":
164
- N(t, n, r);
164
+ M(t, n, r);
165
165
  break;
166
166
  case "json":
167
- P(t, n, r);
167
+ N(t, n, r);
168
168
  break;
169
169
  case "html":
170
- F(t, n, r);
170
+ P(t, n, r);
171
171
  break;
172
172
  case "pdf":
173
- ee(t, n, r);
173
+ te(t, n, r);
174
174
  break;
175
175
  case "excel":
176
- I(t, n, r);
176
+ F(t, n, r);
177
177
  break;
178
178
  default: console.warn(`Unsupported export format: ${e}`);
179
179
  }
180
180
  }
181
- function R(e) {
181
+ function L(e) {
182
182
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
183
183
  }
184
- function z(e) {
184
+ function R(e) {
185
185
  if (typeof e == "string" && e.length > 0) {
186
186
  let t = e.charAt(0);
187
187
  if (t === "=" || t === "+" || t === "-" || t === "@" || t === "|") return `\t${e}`;
188
188
  }
189
189
  return e;
190
190
  }
191
- function B(e) {
191
+ function ne(e) {
192
192
  return [
193
193
  "A4",
194
194
  "A3",
@@ -196,19 +196,19 @@ function B(e) {
196
196
  "Legal"
197
197
  ].includes(e || "") ? e : "A4";
198
198
  }
199
- function te(e) {
199
+ function re(e) {
200
200
  return e === "landscape" ? "landscape" : "portrait";
201
201
  }
202
- function V(e, t, n) {
202
+ function z(e, t, n) {
203
203
  let r = new Blob([e], { type: `${n};charset=utf-8` }), i = URL.createObjectURL(r), a = document.createElement("a");
204
204
  a.href = i, a.download = t, document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(i);
205
205
  }
206
206
  //#endregion
207
207
  //#region src/formatValue.ts
208
- function H(e, t) {
208
+ function B(e, t) {
209
209
  if (e == null || e === "") return "";
210
210
  let n = t?.type, r = t?.format;
211
- if (n === "date" || r === "date" || ne(e)) return re(e);
211
+ if (n === "date" || r === "date" || ie(e)) return ae(e);
212
212
  if (n === "number" || typeof e == "number") {
213
213
  let t = typeof e == "number" ? e : Number(e);
214
214
  return isNaN(t) ? String(e) : r === "currency" || r === "currency_cny" ? `¥${t.toLocaleString("en-US", {
@@ -224,10 +224,10 @@ function H(e, t) {
224
224
  }
225
225
  return String(e);
226
226
  }
227
- function ne(e) {
227
+ function ie(e) {
228
228
  return typeof e == "string" && /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?/.test(e);
229
229
  }
230
- function re(e) {
230
+ function ae(e) {
231
231
  try {
232
232
  let t = new Date(e);
233
233
  return isNaN(t.getTime()) ? String(e) : `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, "0")}-${String(t.getDate()).padStart(2, "0")}`;
@@ -237,7 +237,7 @@ function re(e) {
237
237
  }
238
238
  //#endregion
239
239
  //#region src/ReportViewer.tsx
240
- function ie(e, t) {
240
+ function oe(e, t) {
241
241
  if (!t || t.length === 0 || !e || e.length === 0) return null;
242
242
  let n = t[0], r = n.field, i = /* @__PURE__ */ new Map();
243
243
  for (let t of e) {
@@ -253,129 +253,131 @@ function ie(e, t) {
253
253
  let o = n.sort === "desc" ? -1 : 1;
254
254
  return a.sort((e, t) => e.key.localeCompare(t.key) * o), a;
255
255
  }
256
- var U = ({ schema: t, onRefresh: n }) => {
257
- let { report: r, data: i, showToolbar: a = !0, allowExport: o = !0, allowPrint: c = !0, loading: l = !1 } = t, d = (e) => {
258
- if (!r) {
256
+ function se(e, t, n) {
257
+ if (!e) return 0;
258
+ let r = e.map((e) => Number(e[t]) || 0);
259
+ switch (n) {
260
+ case "count": return e.length;
261
+ case "sum": return r.reduce((e, t) => e + t, 0);
262
+ case "avg": return r.length > 0 ? (r.reduce((e, t) => e + t, 0) / r.length).toFixed(2) : 0;
263
+ case "min": return r.length > 0 ? Math.min(...r) : 0;
264
+ case "max": return r.length > 0 ? Math.max(...r) : 0;
265
+ case "distinct": return new Set(e.map((e) => e[t])).size;
266
+ default: return "";
267
+ }
268
+ }
269
+ var V = ({ schema: e, onRefresh: t }) => {
270
+ let { report: n, data: r, showToolbar: i = !0, allowExport: a = !0, allowPrint: o = !0, loading: c = !1 } = e, l = (e) => {
271
+ if (!n) {
259
272
  console.warn("ReportViewer: Cannot export, no report defined");
260
273
  return;
261
274
  }
262
- L(e, r, i || [], r.exportConfigs?.[e]);
263
- }, S = () => {
275
+ I(e, n, r || [], n.exportConfigs?.[e]);
276
+ }, d = () => {
264
277
  window.print();
265
- }, w = () => {
266
- n?.();
267
- }, D = (e, t) => {
268
- if (!i) return 0;
269
- let n = i.map((t) => Number(t[e]) || 0);
270
- switch (t) {
271
- case "count": return i.length;
272
- case "sum": return n.reduce((e, t) => e + t, 0);
273
- case "avg": return n.length > 0 ? (n.reduce((e, t) => e + t, 0) / n.length).toFixed(2) : 0;
274
- case "min": return n.length > 0 ? Math.min(...n) : 0;
275
- case "max": return n.length > 0 ? Math.max(...n) : 0;
276
- default: return "";
277
- }
278
- }, A = (e, t) => {
279
- let n = r?.conditionalFormatting;
280
- if (!(!n || !Array.isArray(n))) for (let r of n) {
281
- if (r.field !== e) continue;
282
- let n = String(t ?? ""), i = String(r.value ?? ""), a = !1;
283
- switch (r.operator) {
278
+ }, S = () => {
279
+ t?.();
280
+ }, w = (e, t) => se(r, e, t), D = (e, t) => {
281
+ let r = n?.conditionalFormatting;
282
+ if (!(!r || !Array.isArray(r))) for (let n of r) {
283
+ if (n.field !== e) continue;
284
+ let r = String(t ?? ""), i = String(n.value ?? ""), a = !1;
285
+ switch (n.operator) {
284
286
  case "equals":
285
- a = n === i;
287
+ a = r === i;
286
288
  break;
287
289
  case "not_equals":
288
- a = n !== i;
290
+ a = r !== i;
289
291
  break;
290
292
  case "contains":
291
- a = n.includes(i);
293
+ a = r.includes(i);
292
294
  break;
293
295
  case "greater_than":
294
- a = Number(t) > Number(r.value);
296
+ a = Number(t) > Number(n.value);
295
297
  break;
296
298
  case "less_than":
297
- a = Number(t) < Number(r.value);
299
+ a = Number(t) < Number(n.value);
298
300
  break;
299
301
  }
300
302
  if (a) {
301
303
  let e = {};
302
- return r.backgroundColor && (e.backgroundColor = r.backgroundColor), r.textColor && (e.color = r.textColor), e;
304
+ return n.backgroundColor && (e.backgroundColor = n.backgroundColor), n.textColor && (e.color = n.textColor), e;
303
305
  }
304
306
  }
305
- }, j = (e, t) => {
307
+ }, k = (e, t) => {
306
308
  if (e == null || e === "") return "";
307
309
  if (t.renderAs === "badge" && (!t.type || t.type === "string" || t.type === "text")) return /* @__PURE__ */ b(f, {
308
310
  className: t.colorMap?.[String(e)] || "",
309
311
  children: String(e)
310
312
  });
311
- if (t.aggregation) return H(e, t);
313
+ if (t.aggregation) return B(e, t);
312
314
  if (t.type) {
313
315
  let n = { ...t };
314
316
  return t.colorMap && !n.options && (n.options = Object.entries(t.colorMap).map(([e, t]) => ({
315
317
  value: e,
316
318
  label: e,
317
319
  color: t
318
- }))), /* @__PURE__ */ b(O(k(n)), {
320
+ }))), /* @__PURE__ */ b(O(ee(n)), {
319
321
  value: e,
320
322
  field: n
321
323
  });
322
324
  }
323
- return H(e, t);
325
+ return B(e, t);
324
326
  };
325
- return r ? /* @__PURE__ */ x("div", {
327
+ return n ? /* @__PURE__ */ x("div", {
326
328
  className: "space-y-4",
327
- children: [a && /* @__PURE__ */ x("div", {
329
+ children: [i && /* @__PURE__ */ x("div", {
328
330
  className: "flex items-center justify-between gap-2 p-4 bg-card rounded-lg border",
329
331
  children: [/* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("h2", {
330
332
  className: "text-lg font-semibold",
331
- children: r.title
332
- }), r.description && /* @__PURE__ */ b("p", {
333
+ children: n.title
334
+ }), n.description && /* @__PURE__ */ b("p", {
333
335
  className: "text-sm text-muted-foreground",
334
- children: r.description
336
+ children: n.description
335
337
  })] }), /* @__PURE__ */ x("div", {
336
338
  className: "flex items-center gap-2",
337
339
  children: [
338
- r.refreshInterval && /* @__PURE__ */ x(p, {
340
+ n.refreshInterval && /* @__PURE__ */ x(p, {
339
341
  variant: "outline",
340
342
  size: "sm",
341
- onClick: w,
343
+ onClick: S,
342
344
  children: [/* @__PURE__ */ b(E, { className: "h-4 w-4 mr-2" }), "Refresh"]
343
345
  }),
344
- c && /* @__PURE__ */ x(p, {
346
+ o && /* @__PURE__ */ x(p, {
345
347
  variant: "outline",
346
348
  size: "sm",
347
- onClick: S,
349
+ onClick: d,
348
350
  children: [/* @__PURE__ */ b(T, { className: "h-4 w-4 mr-2" }), "Print"]
349
351
  }),
350
- o && r.showExportButtons && /* @__PURE__ */ x("div", {
352
+ a && n.showExportButtons && /* @__PURE__ */ x("div", {
351
353
  className: "flex items-center gap-1",
352
354
  children: [
353
355
  /* @__PURE__ */ x(p, {
354
356
  variant: "outline",
355
357
  size: "sm",
356
- onClick: () => d("pdf"),
358
+ onClick: () => l("pdf"),
357
359
  children: [/* @__PURE__ */ b(C, { className: "h-4 w-4 mr-2" }), "PDF"]
358
360
  }),
359
361
  /* @__PURE__ */ x(p, {
360
362
  variant: "outline",
361
363
  size: "sm",
362
- onClick: () => d("excel"),
364
+ onClick: () => l("excel"),
363
365
  children: [/* @__PURE__ */ b(C, { className: "h-4 w-4 mr-2" }), "Excel"]
364
366
  }),
365
367
  /* @__PURE__ */ x(p, {
366
368
  variant: "outline",
367
369
  size: "sm",
368
- onClick: () => d("csv"),
370
+ onClick: () => l("csv"),
369
371
  children: [/* @__PURE__ */ b(C, { className: "h-4 w-4 mr-2" }), "CSV"]
370
372
  })
371
373
  ]
372
374
  })
373
375
  ]
374
376
  })]
375
- }), /* @__PURE__ */ x(m, { children: [/* @__PURE__ */ x(_, { children: [!a && r.title && /* @__PURE__ */ b(v, { children: r.title }), !a && r.description && /* @__PURE__ */ b(g, { children: r.description })] }), /* @__PURE__ */ x(h, {
377
+ }), /* @__PURE__ */ x(m, { children: [/* @__PURE__ */ x(_, { children: [!i && n.title && /* @__PURE__ */ b(v, { children: n.title }), !i && n.description && /* @__PURE__ */ b(g, { children: n.description })] }), /* @__PURE__ */ x(h, {
376
378
  className: "space-y-6",
377
379
  children: [
378
- l && /* @__PURE__ */ x("div", {
380
+ c && /* @__PURE__ */ x("div", {
379
381
  className: "space-y-6",
380
382
  children: [/* @__PURE__ */ b("div", {
381
383
  className: "grid grid-cols-1 md:grid-cols-3 gap-4",
@@ -398,115 +400,96 @@ var U = ({ schema: t, onRefresh: n }) => {
398
400
  ].map((e) => /* @__PURE__ */ b(y, { className: "h-8 w-full" }, e))]
399
401
  })]
400
402
  }),
401
- !l && r.sections?.map((t, n) => t.visible === !1 ? null : /* @__PURE__ */ x("div", {
403
+ !c && n.sections?.map((e, t) => e.visible === !1 ? null : /* @__PURE__ */ x("div", {
402
404
  className: "space-y-2",
403
405
  children: [
404
- t.title && t.type !== "header" && /* @__PURE__ */ b("h3", {
406
+ e.title && e.type !== "header" && /* @__PURE__ */ b("h3", {
405
407
  className: "text-lg font-semibold border-b pb-2",
406
- children: t.title
408
+ children: e.title
407
409
  }),
408
- t.type === "header" && t.title && /* @__PURE__ */ b("div", {
410
+ e.type === "header" && e.title && /* @__PURE__ */ b("div", {
409
411
  className: "text-2xl font-bold py-4",
410
- children: t.title
412
+ children: e.title
411
413
  }),
412
- t.type === "summary" && /* @__PURE__ */ b("div", {
414
+ e.type === "summary" && /* @__PURE__ */ b("div", {
413
415
  className: "grid grid-cols-1 md:grid-cols-3 gap-4",
414
- children: r.fields?.filter((e) => e.showInSummary).map((e, t) => /* @__PURE__ */ b(m, { children: /* @__PURE__ */ x(h, {
416
+ children: n.fields?.filter((e) => e.showInSummary).map((e, t) => /* @__PURE__ */ b(m, { children: /* @__PURE__ */ x(h, {
415
417
  className: "p-4",
416
418
  children: [/* @__PURE__ */ b("div", {
417
419
  className: "text-sm text-muted-foreground",
418
420
  children: e.label || e.name
419
421
  }), /* @__PURE__ */ b("div", {
420
422
  className: "text-2xl font-bold",
421
- children: H(D(e.name, e.aggregation), e)
423
+ children: B(w(e.name, e.aggregation), e)
422
424
  })]
423
425
  }) }, t))
424
426
  }),
425
- t.type === "chart" && t.chart && /* @__PURE__ */ b("div", {
426
- className: "min-h-[300px]",
427
- children: (() => {
428
- let n = t.chart.type, r = !!t.chart.chartType;
429
- !n && r && (n = "chart"), n && e.get(n) || (n = "chart");
430
- let a = n === "chart" ? {
431
- xAxisKey: t.chart.xAxisKey || t.chart.xAxisField || "name",
432
- series: t.chart.series || (t.chart.yAxisFields ? t.chart.yAxisFields.map((e) => ({ dataKey: e })) : []),
433
- chartType: t.chart.chartType || "bar"
434
- } : {};
435
- return /* @__PURE__ */ b(u, { schema: {
436
- ...t.chart,
437
- type: n,
438
- ...a,
439
- data: i || t.chart.data,
440
- className: t.chart.className || "w-full h-[350px]"
441
- } });
442
- })()
443
- }),
444
- t.type === "table" && /* @__PURE__ */ b("div", {
427
+ e.type === "table" && /* @__PURE__ */ b("div", {
445
428
  className: "border rounded-lg overflow-x-auto",
446
429
  children: /* @__PURE__ */ x("table", {
447
430
  className: "w-full text-sm min-w-[600px]",
448
431
  children: [/* @__PURE__ */ b("thead", {
449
432
  className: "bg-muted",
450
- children: /* @__PURE__ */ b("tr", { children: t.columns?.map((e, t) => /* @__PURE__ */ b("th", {
433
+ children: /* @__PURE__ */ b("tr", { children: e.columns?.map((e, t) => /* @__PURE__ */ b("th", {
451
434
  className: `px-4 py-2 font-medium ${e.type === "number" ? "text-right" : "text-left"}`,
452
435
  children: e.label || e.name
453
436
  }, t)) })
454
437
  }), /* @__PURE__ */ b("tbody", { children: (() => {
455
- let e = ie(i || [], r.groupBy || []);
456
- return e ? e.map((e) => /* @__PURE__ */ x(s.Fragment, { children: [/* @__PURE__ */ b("tr", {
438
+ let t = oe(r || [], n.groupBy || []);
439
+ return t ? t.map((t) => /* @__PURE__ */ x(s.Fragment, { children: [/* @__PURE__ */ b("tr", {
457
440
  className: "bg-muted/60",
458
441
  children: /* @__PURE__ */ x("td", {
459
- colSpan: t.columns?.length || 1,
442
+ colSpan: e.columns?.length || 1,
460
443
  className: "px-4 py-2 font-semibold text-sm",
461
444
  children: [
462
- e.label,
445
+ t.label,
463
446
  " (",
464
- e.rows.length,
447
+ t.rows.length,
465
448
  ")"
466
449
  ]
467
450
  })
468
- }), e.rows.map((e, n) => /* @__PURE__ */ b("tr", {
451
+ }), t.rows.map((t, n) => /* @__PURE__ */ b("tr", {
469
452
  className: "border-t hover:bg-muted/50 even:bg-muted/20",
470
- children: t.columns?.map((t, n) => /* @__PURE__ */ b("td", {
471
- className: `px-4 py-2 ${t.type === "number" ? "text-right tabular-nums" : ""}`,
472
- style: A(t.name, e[t.name]),
473
- children: j(e[t.name], t)
453
+ children: e.columns?.map((e, n) => /* @__PURE__ */ b("td", {
454
+ className: `px-4 py-2 ${e.type === "number" ? "text-right tabular-nums" : ""}`,
455
+ style: D(e.name, t[e.name]),
456
+ children: k(t[e.name], e)
474
457
  }, n))
475
- }, n))] }, e.key)) : i?.map((e, n) => /* @__PURE__ */ b("tr", {
458
+ }, n))] }, t.key)) : r?.map((t, n) => /* @__PURE__ */ b("tr", {
476
459
  className: "border-t hover:bg-muted/50 even:bg-muted/20",
477
- children: t.columns?.map((t, n) => /* @__PURE__ */ b("td", {
478
- className: `px-4 py-2 ${t.type === "number" ? "text-right tabular-nums" : ""}`,
479
- style: A(t.name, e[t.name]),
480
- children: j(e[t.name], t)
460
+ children: e.columns?.map((e, n) => /* @__PURE__ */ b("td", {
461
+ className: `px-4 py-2 ${e.type === "number" ? "text-right tabular-nums" : ""}`,
462
+ style: D(e.name, t[e.name]),
463
+ children: k(t[e.name], e)
481
464
  }, n))
482
465
  }, n));
483
466
  })() })]
484
467
  })
485
468
  }),
486
- t.type === "text" && t.text && /* @__PURE__ */ b("div", {
469
+ e.type === "text" && e.text && /* @__PURE__ */ b("div", {
487
470
  className: "prose max-w-none",
488
- children: /* @__PURE__ */ b("p", { children: t.text })
471
+ children: /* @__PURE__ */ b("p", { children: e.text })
489
472
  }),
490
- t.type === "page-break" && /* @__PURE__ */ b("div", { className: "border-t-2 border-dashed my-8 print:page-break-after-always" }),
491
- t.content && /* @__PURE__ */ b(u, { schema: t.content })
473
+ e.type === "page-break" && /* @__PURE__ */ b("div", { className: "border-t-2 border-dashed my-8 print:page-break-after-always" }),
474
+ e.content && /* @__PURE__ */ b(u, { schema: e.content })
492
475
  ]
493
- }, n)),
494
- !r.sections && i && i.length > 0 && /* @__PURE__ */ b("div", {
476
+ }, t)),
477
+ !n.sections && r && r.length > 0 && /* @__PURE__ */ b("div", {
495
478
  className: "border rounded-lg overflow-x-auto",
496
479
  children: /* @__PURE__ */ x("table", {
497
480
  className: "w-full text-sm min-w-[600px]",
498
481
  children: [/* @__PURE__ */ b("thead", {
499
482
  className: "bg-muted",
500
- children: /* @__PURE__ */ b("tr", { children: r.fields?.map((e, t) => /* @__PURE__ */ b("th", {
483
+ children: /* @__PURE__ */ b("tr", { children: n.fields?.map((e, t) => /* @__PURE__ */ b("th", {
501
484
  className: `px-4 py-2 font-medium ${e.type === "number" ? "text-right" : "text-left"}`,
502
485
  children: e.label || e.name
503
486
  }, t)) })
504
- }), /* @__PURE__ */ b("tbody", { children: i.map((e, t) => /* @__PURE__ */ b("tr", {
487
+ }), /* @__PURE__ */ b("tbody", { children: r.map((e, t) => /* @__PURE__ */ b("tr", {
505
488
  className: "border-t hover:bg-muted/50 even:bg-muted/20",
506
- children: r.fields?.map((t, n) => /* @__PURE__ */ b("td", {
489
+ children: n.fields?.map((t, n) => /* @__PURE__ */ b("td", {
507
490
  className: `px-4 py-2 ${t.type === "number" ? "text-right tabular-nums" : ""}`,
508
- style: A(t.name, e[t.name]),
509
- children: j(e[t.name], t)
491
+ style: D(t.name, e[t.name]),
492
+ children: k(e[t.name], t)
510
493
  }, n))
511
494
  }, t)) })]
512
495
  })
@@ -520,26 +503,41 @@ var U = ({ schema: t, onRefresh: n }) => {
520
503
  };
521
504
  //#endregion
522
505
  //#region src/DatasetReportRenderer.tsx
523
- function W(e) {
506
+ function H(e) {
524
507
  if (!e || typeof e != "object") return !1;
525
508
  let t = e;
526
509
  return typeof t.dataset == "string" && t.dataset.length > 0 || t.type === "joined" && Array.isArray(t.blocks) && t.blocks.some((e) => typeof e?.dataset == "string");
527
510
  }
528
- function G(e, t) {
511
+ function U(e, t) {
529
512
  return e ? typeof e == "string" ? e : typeof e == "object" && typeof e.default == "string" ? e.default : t : t;
530
513
  }
531
- function K(e) {
514
+ function W(e) {
532
515
  return Array.isArray(e) ? e.filter((e) => typeof e == "string" && !!e) : [];
533
516
  }
534
- function q(e, t, n, r, i, a) {
535
- let [s, c] = o.useState({
517
+ function G(e) {
518
+ if (!Array.isArray(e)) return;
519
+ let t = {};
520
+ for (let n of e) {
521
+ let e = n && typeof n == "object" ? n.by : void 0;
522
+ typeof e != "string" || !e || (t[e] = n.direction === "desc" ? "desc" : "asc");
523
+ }
524
+ return Object.keys(t).length > 0 ? t : void 0;
525
+ }
526
+ function ce(e, t, n) {
527
+ if (!e) return;
528
+ let r = /* @__PURE__ */ new Set([...t, ...n]), i = {};
529
+ for (let [t, n] of Object.entries(e)) r.has(t) && (i[t] = n);
530
+ return Object.keys(i).length > 0 ? i : void 0;
531
+ }
532
+ function K(e, t, n, r, i, a, s) {
533
+ let [c, l] = o.useState({
536
534
  status: "idle",
537
535
  rows: []
538
- }), l = JSON.stringify(r ?? null), u = JSON.stringify(a ?? null), d = `${e}|${t.join(",")}|${n.join(",")}|${l}|${u}`;
536
+ }), u = ce(s, t, n), d = JSON.stringify(r ?? null), f = JSON.stringify(a ?? null), p = JSON.stringify(u ?? null), m = `${e}|${t.join(",")}|${n.join(",")}|${d}|${f}|${p}`;
539
537
  return o.useEffect(() => {
540
538
  let o = i;
541
539
  if (!o || typeof o.queryDataset != "function") {
542
- c({
540
+ l({
543
541
  status: "error",
544
542
  rows: [],
545
543
  error: "This data source does not support dataset queries."
@@ -547,33 +545,35 @@ function q(e, t, n, r, i, a) {
547
545
  return;
548
546
  }
549
547
  if (!e || n.length === 0) {
550
- c({
548
+ l({
551
549
  status: "idle",
552
550
  rows: []
553
551
  });
554
552
  return;
555
553
  }
556
554
  let s = !1;
557
- return c({
555
+ return l({
558
556
  status: "loading",
559
557
  rows: []
560
558
  }), o.queryDataset(e, {
561
559
  dimensions: t,
562
560
  measures: n,
563
561
  ...r && Object.keys(r).length > 0 ? { runtimeFilter: r } : {},
564
- ...a ? { totals: { groupings: a } } : {}
562
+ ...a ? { totals: { groupings: a } } : {},
563
+ ...u ? { order: u } : {}
565
564
  }).then((e) => {
566
- s || c({
565
+ s || l({
567
566
  status: "ok",
568
567
  rows: Array.isArray(e?.rows) ? e.rows : [],
569
568
  fields: Array.isArray(e?.fields) ? e.fields : [],
570
569
  object: e?.object,
571
570
  dimensionFields: e?.dimensionFields,
572
571
  drillRawRows: Array.isArray(e?.drillRawRows) ? e.drillRawRows : void 0,
572
+ drillRanges: Array.isArray(e?.drillRanges) ? e.drillRanges : void 0,
573
573
  totals: Array.isArray(e?.totals) ? e.totals : void 0
574
574
  });
575
575
  }).catch((e) => {
576
- s || c({
576
+ s || l({
577
577
  status: "error",
578
578
  rows: [],
579
579
  error: String(e?.message ?? e)
@@ -581,9 +581,9 @@ function q(e, t, n, r, i, a) {
581
581
  }), () => {
582
582
  s = !0;
583
583
  };
584
- }, [d]), s;
584
+ }, [m]), c;
585
585
  }
586
- function J({ dataset: e }) {
586
+ function q({ dataset: e }) {
587
587
  return /* @__PURE__ */ x("div", {
588
588
  className: "flex items-center justify-center rounded-md border border-dashed bg-muted/20 p-4 text-xs text-muted-foreground",
589
589
  children: [
@@ -593,7 +593,7 @@ function J({ dataset: e }) {
593
593
  ]
594
594
  });
595
595
  }
596
- function Y({ status: e, error: t }) {
596
+ function J({ status: e, error: t }) {
597
597
  return e === "error" ? /* @__PURE__ */ x("div", {
598
598
  role: "alert",
599
599
  className: "flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive",
@@ -606,68 +606,106 @@ function Y({ status: e, error: t }) {
606
606
  children: [/* @__PURE__ */ b(w, { className: "h-4 w-4 animate-spin" }), " Running report…"]
607
607
  });
608
608
  }
609
- function X() {
609
+ function Y() {
610
610
  return /* @__PURE__ */ x("div", {
611
611
  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",
612
612
  children: [/* @__PURE__ */ b(D, { className: "h-6 w-6" }), " The dataset returned no rows for this report’s scope."]
613
613
  });
614
614
  }
615
- var Z = "cursor-pointer hover:bg-accent/40";
616
- function ae({ dataset: e, rows: a, values: o, runtimeFilter: s, dataSource: c, onDrill: l }) {
617
- let u = q(e, a, o, s, c), { fieldLabel: d } = A();
618
- if (o.length === 0) return /* @__PURE__ */ b(J, { dataset: e });
619
- if (u.status === "loading" || u.status === "idle") return /* @__PURE__ */ b(Y, { status: u.status });
620
- if (u.status === "error") return /* @__PURE__ */ b(Y, {
615
+ var le = "cursor-pointer hover:bg-accent/40";
616
+ function ue({ dataset: e, rows: a, values: o, runtimeFilter: s, dataSource: c, onDrill: l, order: u, withTotals: d }) {
617
+ let f = K(e, a, o, s, c, d && a.length > 0 ? [[]] : void 0, u), { fieldLabel: p } = k(), m = A();
618
+ if (o.length === 0) return /* @__PURE__ */ b(q, { dataset: e });
619
+ if (f.status === "loading" || f.status === "idle") return /* @__PURE__ */ b(J, { status: f.status });
620
+ if (f.status === "error") return /* @__PURE__ */ b(J, {
621
621
  status: "error",
622
- error: u.error
622
+ error: f.error
623
623
  });
624
- if (u.rows.length === 0) return /* @__PURE__ */ b(X, {});
625
- let f = !!l && a.length > 0, p = u.dimensionFields ? a.filter((e) => e in u.dimensionFields) : [], m = (n, r) => {
624
+ if (f.rows.length === 0) return /* @__PURE__ */ b(Y, {});
625
+ let h = !!l && a.length > 0, g = f.dimensionFields ? a.filter((e) => e in f.dimensionFields) : [], _ = (n, r) => {
626
626
  let i = {};
627
627
  for (let e of a) i[e] = n[e];
628
- let o = u.object && u.dimensionFields && p.length > 0 ? t(u.drillRawRows?.[r], p, u.dimensionFields, s) : void 0;
628
+ let o = f.drillRanges?.[r], c = !!o && Object.keys(o).length > 0, u = f.object && (g.length > 0 || c) ? t(f.drillRawRows?.[r], g, f.dimensionFields ?? {}, s, o) : void 0;
629
629
  l({
630
630
  dataset: e,
631
631
  groupKey: i,
632
632
  runtimeFilter: s,
633
- object: u.object,
634
- objectFilter: o
633
+ object: f.object,
634
+ objectFilter: u
635
635
  });
636
- }, { measureField: h, headerLabel: g } = n(u.fields, u.object, d), _ = [...a, ...o];
636
+ }, { measureField: v, headerLabel: y } = n(f.fields, f.object, p), S = [...a, ...o], C = d ? f.totals?.find((e) => Array.isArray(e.dimensions) && e.dimensions.length === 0)?.rows?.[0] : void 0, w = m("report.total", "Total");
637
637
  return /* @__PURE__ */ b("div", {
638
638
  className: "overflow-auto max-h-[70vh] rounded-md border",
639
639
  children: /* @__PURE__ */ x("table", {
640
640
  className: "w-full text-xs",
641
641
  children: [/* @__PURE__ */ b("thead", {
642
642
  className: "bg-muted/40",
643
- children: /* @__PURE__ */ b("tr", { children: _.map((e) => /* @__PURE__ */ b("th", {
643
+ children: /* @__PURE__ */ b("tr", { children: S.map((e) => /* @__PURE__ */ b("th", {
644
644
  className: "px-2 py-1.5 text-left font-medium whitespace-nowrap",
645
- children: g(e)
645
+ children: y(e)
646
646
  }, e)) })
647
- }), /* @__PURE__ */ b("tbody", { children: u.rows.map((e, t) => /* @__PURE__ */ b("tr", {
648
- className: `border-t${f ? ` ${Z}` : ""}`,
649
- "data-testid": f ? "dataset-drill-row" : void 0,
650
- onClick: f ? () => m(e, t) : void 0,
651
- children: _.map((t) => /* @__PURE__ */ b("td", {
647
+ }), /* @__PURE__ */ x("tbody", { children: [f.rows.map((e, t) => /* @__PURE__ */ b("tr", {
648
+ className: `border-t${h ? ` ${le}` : ""}`,
649
+ "data-testid": h ? "dataset-drill-row" : void 0,
650
+ onClick: h ? () => _(e, t) : void 0,
651
+ children: S.map((t) => /* @__PURE__ */ b("td", {
652
652
  className: "px-2 py-1 tabular-nums whitespace-nowrap",
653
- children: o.includes(t) ? i(e[t], h(t)?.format, h(t)?.currency) : r(e[t])
653
+ children: o.includes(t) ? i(e[t], v(t)?.format, v(t)?.currency) : r(e[t])
654
654
  }, t))
655
- }, t)) })]
655
+ }, t)), C && /* @__PURE__ */ x("tr", {
656
+ className: "border-t bg-muted/30 font-medium",
657
+ "data-testid": "dataset-report-total-row",
658
+ children: [a.length > 0 && /* @__PURE__ */ b("td", {
659
+ colSpan: a.length,
660
+ className: "px-2 py-1 whitespace-nowrap",
661
+ children: w
662
+ }), o.map((e) => /* @__PURE__ */ b("td", {
663
+ className: "px-2 py-1 tabular-nums whitespace-nowrap",
664
+ children: i(C[e], v(e)?.format, v(e)?.currency)
665
+ }, e))]
666
+ })] })]
656
667
  })
657
668
  });
658
669
  }
659
- function oe(e) {
670
+ function de(e) {
660
671
  switch (e) {
661
- case "line": return "line";
662
- case "area": return "area";
663
- case "pie": return "pie";
664
- case "donut": return "donut";
665
- case "radar": return "radar";
666
- case "scatter": return "scatter";
667
- default: return "bar";
672
+ case "summary": return "summary";
673
+ case "matrix": return "matrix";
674
+ case "joined": return "joined";
675
+ default: return "tabular";
676
+ }
677
+ }
678
+ function fe(e) {
679
+ switch (e) {
680
+ case "bar":
681
+ case "column":
682
+ case "horizontal-bar":
683
+ case "line":
684
+ case "area":
685
+ case "pie":
686
+ case "donut":
687
+ case "funnel":
688
+ case "scatter":
689
+ case "treemap":
690
+ case "sankey":
691
+ case "radar": return {
692
+ kind: "series",
693
+ chartType: e
694
+ };
695
+ case "gauge":
696
+ case "solid-gauge":
697
+ case "metric":
698
+ case "kpi":
699
+ case "bullet": return { kind: "single_value" };
700
+ case "table":
701
+ case "pivot": return { kind: "tabular" };
702
+ default: return {
703
+ kind: "unsupported",
704
+ type: String(e)
705
+ };
668
706
  }
669
707
  }
670
- function se(t) {
708
+ function pe(t) {
671
709
  let [, n] = o.useReducer((e) => e + 1, 0);
672
710
  return o.useEffect(() => {
673
711
  if (e.get(t)) return;
@@ -677,54 +715,83 @@ function se(t) {
677
715
  return i && typeof i.then == "function" && i.then(() => n()).catch(() => {}), r;
678
716
  }, [t]), e.get(t);
679
717
  }
680
- function ce({ dataset: e, chart: t, runtimeFilter: n, dataSource: r }) {
681
- let i = typeof t.xAxis == "string" ? t.xAxis : "", a = typeof t.yAxis == "string" ? t.yAxis : "", o = q(e, i ? [i] : [], a ? [a] : [], n, r), s = se("chart");
682
- if (!i || !a) return null;
683
- if (o.status === "loading" || o.status === "idle") return /* @__PURE__ */ x("div", {
718
+ function me({ dataset: e, chart: t, runtimeFilter: r, dataSource: a, order: o }) {
719
+ let s = typeof t.xAxis == "string" ? t.xAxis : "", c = typeof t.yAxis == "string" ? t.yAxis : "", l = fe(t.type), u = l.kind === "series" || l.kind === "single_value", d = K(e, l.kind === "series" && s ? [s] : [], u && c ? [c] : [], r, a, void 0, o), f = pe("chart"), { fieldLabel: p } = k(), m = typeof t.title == "string" ? t.title : void 0;
720
+ if (l.kind === "tabular") return null;
721
+ if (l.kind === "unsupported") return /* @__PURE__ */ x("div", {
722
+ className: "rounded-md border border-dashed bg-muted/20 px-3 py-2 text-xs text-muted-foreground",
723
+ "data-testid": "dataset-report-chart-unsupported",
724
+ children: [
725
+ "Chart type “",
726
+ l.type,
727
+ "” is not a spec chart type — the grouped table below carries this report’s numbers."
728
+ ]
729
+ });
730
+ if (l.kind === "series" && !s || !c) return null;
731
+ if (d.status === "loading" || d.status === "idle") return /* @__PURE__ */ x("div", {
684
732
  className: "flex items-center gap-2 p-4 text-xs text-muted-foreground",
685
733
  children: [/* @__PURE__ */ b(w, { className: "h-4 w-4 animate-spin" }), " Loading chart…"]
686
734
  });
687
- if (o.status === "error" || o.rows.length === 0 || !s) return null;
688
- let c = typeof t.title == "string" ? t.title : void 0;
689
- return /* @__PURE__ */ x("div", {
735
+ if (d.status === "error" || d.rows.length === 0) return null;
736
+ if (l.kind === "single_value") {
737
+ let { measureField: e, headerLabel: t } = n(d.fields, d.object, p), r = e(c);
738
+ return /* @__PURE__ */ x("div", {
739
+ className: "rounded-md border bg-card p-3",
740
+ "data-testid": "dataset-report-metric",
741
+ children: [m ? /* @__PURE__ */ b("h3", {
742
+ className: "mb-2 text-sm font-semibold",
743
+ children: m
744
+ }) : null, /* @__PURE__ */ x("div", {
745
+ className: "flex flex-col gap-0.5 py-2",
746
+ children: [/* @__PURE__ */ b("span", {
747
+ className: "text-2xl font-semibold tabular-nums",
748
+ children: i(d.rows[0]?.[c], r?.format, r?.currency)
749
+ }), /* @__PURE__ */ b("span", {
750
+ className: "text-xs text-muted-foreground",
751
+ children: t(c)
752
+ })]
753
+ })]
754
+ });
755
+ }
756
+ return f ? /* @__PURE__ */ x("div", {
690
757
  className: "rounded-md border bg-card p-3",
691
758
  "data-testid": "dataset-report-chart",
692
- children: [c ? /* @__PURE__ */ b("h3", {
759
+ children: [m ? /* @__PURE__ */ b("h3", {
693
760
  className: "mb-2 text-sm font-semibold",
694
- children: c
695
- }) : null, /* @__PURE__ */ b(s, { schema: {
696
- chartType: oe(t.type),
697
- data: o.rows,
698
- xAxisKey: i,
699
- series: [{ dataKey: a }],
761
+ children: m
762
+ }) : null, /* @__PURE__ */ b(f, { schema: {
763
+ chartType: l.chartType,
764
+ data: d.rows,
765
+ xAxisKey: s,
766
+ series: [{ dataKey: c }],
700
767
  height: typeof t.height == "number" ? t.height : 280,
701
768
  isAnimationActive: !1
702
769
  } })]
703
- });
770
+ }) : null;
704
771
  }
705
- function Q(e, t) {
772
+ function X(e, t) {
706
773
  return e.map((e) => String(t[e] ?? "∅")).join("");
707
774
  }
708
- function le(e, t) {
775
+ function he(e, t) {
709
776
  return e.map((e) => r(t[e])).join(" / ");
710
777
  }
711
- function ue({ dataset: e, rows: a, columnsAcross: s, values: c, runtimeFilter: l, dataSource: u, onDrill: d }) {
712
- let f = q(e, [...a, ...s], c, l, u, [
778
+ function Z({ dataset: e, rows: a, columnsAcross: s, values: c, runtimeFilter: l, dataSource: u, onDrill: d, order: f }) {
779
+ let p = K(e, [...a, ...s], c, l, u, [
713
780
  a,
714
781
  s,
715
782
  []
716
- ]), p = j(), { fieldLabel: m } = A(), h = o.useMemo(() => {
717
- if (f.status !== "ok") return null;
783
+ ], f), m = A(), { fieldLabel: h } = k(), g = o.useMemo(() => {
784
+ if (p.status !== "ok") return null;
718
785
  let e = [], t = [], n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Map();
719
- return f.rows.forEach((o, c) => {
720
- let l = Q(a, o), u = Q(s, o);
786
+ return p.rows.forEach((o, c) => {
787
+ let l = X(a, o), u = X(s, o);
721
788
  if (!n.has(l)) {
722
789
  n.add(l);
723
790
  let t = {};
724
791
  for (let e of a) t[e] = o[e];
725
792
  e.push({
726
793
  id: l,
727
- label: le(a, o),
794
+ label: he(a, o),
728
795
  key: t
729
796
  });
730
797
  }
@@ -734,7 +801,7 @@ function ue({ dataset: e, rows: a, columnsAcross: s, values: c, runtimeFilter: l
734
801
  for (let t of s) e[t] = o[t];
735
802
  t.push({
736
803
  id: u,
737
- label: le(s, o),
804
+ label: he(s, o),
738
805
  key: e
739
806
  });
740
807
  }
@@ -748,19 +815,19 @@ function ue({ dataset: e, rows: a, columnsAcross: s, values: c, runtimeFilter: l
748
815
  cells: i
749
816
  };
750
817
  }, [
751
- f,
818
+ p,
752
819
  a,
753
820
  s
754
821
  ]);
755
- if (c.length === 0) return /* @__PURE__ */ b(J, { dataset: e });
756
- if (f.status === "loading" || f.status === "idle") return /* @__PURE__ */ b(Y, { status: f.status });
757
- if (f.status === "error") return /* @__PURE__ */ b(Y, {
822
+ if (c.length === 0) return /* @__PURE__ */ b(q, { dataset: e });
823
+ if (p.status === "loading" || p.status === "idle") return /* @__PURE__ */ b(J, { status: p.status });
824
+ if (p.status === "error") return /* @__PURE__ */ b(J, {
758
825
  status: "error",
759
- error: f.error
826
+ error: p.error
760
827
  });
761
- if (!h || h.rowHeaders.length === 0) return /* @__PURE__ */ b(X, {});
762
- let { measureField: g, headerLabel: _ } = n(f.fields, f.object, m), v = p("report.total", "Total"), y = !!d, S = f.dimensionFields ? [...a, ...s].filter((e) => e in f.dimensionFields) : [], C = (n, r, i) => {
763
- let a = f.object && f.dimensionFields && S.length > 0 ? t(f.drillRawRows?.[i], S, f.dimensionFields, l) : void 0;
828
+ if (!g || g.rowHeaders.length === 0) return /* @__PURE__ */ b(Y, {});
829
+ let { measureField: _, headerLabel: v } = n(p.fields, p.object, h), y = m("report.total", "Total"), S = !!d, C = p.dimensionFields ? [...a, ...s].filter((e) => e in p.dimensionFields) : [], w = (n, r, i) => {
830
+ let a = p.drillRanges?.[i], o = !!a && Object.keys(a).length > 0, s = p.object && (C.length > 0 || o) ? t(p.drillRawRows?.[i], C, p.dimensionFields ?? {}, l, a) : void 0;
764
831
  d({
765
832
  dataset: e,
766
833
  groupKey: {
@@ -768,18 +835,18 @@ function ue({ dataset: e, rows: a, columnsAcross: s, values: c, runtimeFilter: l
768
835
  ...r
769
836
  },
770
837
  runtimeFilter: l,
771
- object: f.object,
772
- objectFilter: a
838
+ object: p.object,
839
+ objectFilter: s
773
840
  });
774
- }, w = h.colHeaders.flatMap((e) => c.map((t) => ({
841
+ }, T = g.colHeaders.flatMap((e) => c.map((t) => ({
775
842
  col: e,
776
843
  measure: t,
777
- header: c.length === 1 ? e.label : `${e.label} · ${_(t)}`
778
- }))), T = (e) => f.totals?.find((t) => Array.isArray(t.dimensions) && t.dimensions.join(",") === e.join(","))?.rows, E = /* @__PURE__ */ new Map();
779
- for (let e of T(a) ?? []) E.set(Q(a, e), e);
780
- let D = /* @__PURE__ */ new Map();
781
- for (let e of T(s) ?? []) D.set(Q(s, e), e);
782
- let O = T([])?.[0], k = E.size > 0, M = D.size > 0;
844
+ header: c.length === 1 ? e.label : `${e.label} · ${v(t)}`
845
+ }))), E = (e) => p.totals?.find((t) => Array.isArray(t.dimensions) && t.dimensions.join(",") === e.join(","))?.rows, D = /* @__PURE__ */ new Map();
846
+ for (let e of E(a) ?? []) D.set(X(a, e), e);
847
+ let O = /* @__PURE__ */ new Map();
848
+ for (let e of E(s) ?? []) O.set(X(s, e), e);
849
+ let ee = E([])?.[0], j = D.size > 0, M = O.size > 0;
783
850
  return /* @__PURE__ */ b("div", {
784
851
  className: "overflow-auto max-h-[70vh] rounded-md border",
785
852
  "data-testid": "dataset-matrix",
@@ -790,38 +857,38 @@ function ue({ dataset: e, rows: a, columnsAcross: s, values: c, runtimeFilter: l
790
857
  children: /* @__PURE__ */ x("tr", { children: [
791
858
  a.map((e) => /* @__PURE__ */ b("th", {
792
859
  className: "px-2 py-1.5 text-left font-medium whitespace-nowrap",
793
- children: _(e)
860
+ children: v(e)
794
861
  }, e)),
795
- w.map((e) => /* @__PURE__ */ b("th", {
862
+ T.map((e) => /* @__PURE__ */ b("th", {
796
863
  className: "px-2 py-1.5 text-right font-medium whitespace-nowrap",
797
864
  children: e.header
798
865
  }, `${e.col.id}-${e.measure}`)),
799
- k && c.map((e) => /* @__PURE__ */ b("th", {
866
+ j && c.map((e) => /* @__PURE__ */ b("th", {
800
867
  className: "px-2 py-1.5 text-right font-medium whitespace-nowrap",
801
868
  "data-testid": "matrix-total-col-header",
802
- children: c.length === 1 ? v : `${v} · ${_(e)}`
869
+ children: c.length === 1 ? y : `${y} · ${v(e)}`
803
870
  }, `total-${e}`))
804
871
  ] })
805
- }), /* @__PURE__ */ x("tbody", { children: [h.rowHeaders.map((e) => /* @__PURE__ */ x("tr", {
872
+ }), /* @__PURE__ */ x("tbody", { children: [g.rowHeaders.map((e) => /* @__PURE__ */ x("tr", {
806
873
  className: "border-t",
807
874
  children: [
808
875
  a.map((t) => /* @__PURE__ */ b("td", {
809
876
  className: "px-2 py-1 whitespace-nowrap font-medium",
810
877
  children: r(e.key[t])
811
878
  }, t)),
812
- w.map((t) => {
813
- let n = h.cells.get(`${e.id} ${t.col.id}`), r = n?.row[t.measure], a = y && n != null;
879
+ T.map((t) => {
880
+ let n = g.cells.get(`${e.id} ${t.col.id}`), r = n?.row[t.measure], a = S && n != null;
814
881
  return /* @__PURE__ */ b("td", {
815
- className: `px-2 py-1 text-right tabular-nums whitespace-nowrap${a ? ` ${Z}` : ""}`,
882
+ className: `px-2 py-1 text-right tabular-nums whitespace-nowrap${a ? ` ${le}` : ""}`,
816
883
  "data-testid": a ? "dataset-drill-cell" : void 0,
817
- onClick: a ? () => C(e.key, t.col.key, n.index) : void 0,
818
- children: i(r, g(t.measure)?.format, g(t.measure)?.currency)
884
+ onClick: a ? () => w(e.key, t.col.key, n.index) : void 0,
885
+ children: i(r, _(t.measure)?.format, _(t.measure)?.currency)
819
886
  }, `${t.col.id}-${t.measure}`);
820
887
  }),
821
- k && c.map((t) => /* @__PURE__ */ b("td", {
888
+ j && c.map((t) => /* @__PURE__ */ b("td", {
822
889
  className: "px-2 py-1 text-right tabular-nums whitespace-nowrap font-medium",
823
890
  "data-testid": "matrix-row-total",
824
- children: i(E.get(e.id)?.[t], g(t)?.format, g(t)?.currency)
891
+ children: i(D.get(e.id)?.[t], _(t)?.format, _(t)?.currency)
825
892
  }, `total-${t}`))
826
893
  ]
827
894
  }, e.id)), M && /* @__PURE__ */ x("tr", {
@@ -831,25 +898,25 @@ function ue({ dataset: e, rows: a, columnsAcross: s, values: c, runtimeFilter: l
831
898
  a.length > 0 && /* @__PURE__ */ b("td", {
832
899
  colSpan: a.length,
833
900
  className: "px-2 py-1 whitespace-nowrap",
834
- children: v
901
+ children: y
835
902
  }),
836
- w.map((e) => /* @__PURE__ */ b("td", {
903
+ T.map((e) => /* @__PURE__ */ b("td", {
837
904
  className: "px-2 py-1 text-right tabular-nums whitespace-nowrap",
838
- children: i(D.get(e.col.id)?.[e.measure], g(e.measure)?.format, g(e.measure)?.currency)
905
+ children: i(O.get(e.col.id)?.[e.measure], _(e.measure)?.format, _(e.measure)?.currency)
839
906
  }, `${e.col.id}-${e.measure}`)),
840
- k && c.map((e) => /* @__PURE__ */ b("td", {
907
+ j && c.map((e) => /* @__PURE__ */ b("td", {
841
908
  className: "px-2 py-1 text-right tabular-nums whitespace-nowrap",
842
909
  "data-testid": "matrix-grand-total",
843
- children: i(O?.[e], g(e)?.format, g(e)?.currency)
910
+ children: i(ee?.[e], _(e)?.format, _(e)?.currency)
844
911
  }, `grand-${e}`))
845
912
  ]
846
913
  })] })]
847
914
  })
848
915
  });
849
916
  }
850
- var de = ({ report: e, dataSource: t, runtimeFilter: n, onDrill: r, className: i }) => {
851
- let o = a(e.runtimeFilter ?? e.filter, n), s = e.drilldown === !1 ? void 0 : r;
852
- if (e.type === "joined" && Array.isArray(e.blocks)) return /* @__PURE__ */ b("div", {
917
+ var ge = ({ report: e, dataSource: t, runtimeFilter: n, onDrill: r, className: i }) => {
918
+ let o = a(e.runtimeFilter ?? e.filter, n), s = e.drilldown === !1 ? void 0 : r, c = de(e.type);
919
+ if (c === "joined" && Array.isArray(e.blocks)) return /* @__PURE__ */ b("div", {
853
920
  className: i,
854
921
  "data-testid": "dataset-joined-report",
855
922
  "data-report-name": e.name,
@@ -859,21 +926,24 @@ var de = ({ report: e, dataSource: t, runtimeFilter: n, onDrill: r, className: i
859
926
  gap: 24
860
927
  },
861
928
  children: e.blocks.map((e, n) => {
862
- let r = a(o, e.runtimeFilter ?? e.filter), i = K(e.columns), c = e.type === "matrix" && i.length > 0 ? /* @__PURE__ */ b(ue, {
929
+ let r = a(o, e.runtimeFilter ?? e.filter), i = W(e.columns), c = G(e.order), l = de(e.type), u = l === "matrix" && i.length > 0 ? /* @__PURE__ */ b(Z, {
863
930
  dataset: String(e.dataset ?? ""),
864
- rows: K(e.rows),
931
+ rows: W(e.rows),
865
932
  columnsAcross: i,
866
- values: K(e.values),
933
+ values: W(e.values),
867
934
  runtimeFilter: r,
868
935
  dataSource: t,
869
- onDrill: s
870
- }) : /* @__PURE__ */ b(ae, {
936
+ onDrill: s,
937
+ order: c
938
+ }) : /* @__PURE__ */ b(ue, {
871
939
  dataset: String(e.dataset ?? ""),
872
- rows: K(e.rows),
873
- values: K(e.values),
940
+ rows: W(e.rows),
941
+ values: W(e.values),
874
942
  runtimeFilter: r,
875
943
  dataSource: t,
876
- onDrill: s
944
+ onDrill: s,
945
+ order: c,
946
+ withTotals: l === "summary" || l === "matrix"
877
947
  });
878
948
  return /* @__PURE__ */ x("section", {
879
949
  "data-testid": "dataset-report-block",
@@ -883,52 +953,57 @@ var de = ({ report: e, dataSource: t, runtimeFilter: n, onDrill: r, className: i
883
953
  className: "flex flex-col gap-0.5",
884
954
  children: [/* @__PURE__ */ b("h3", {
885
955
  className: "text-sm font-semibold",
886
- children: G(e.label, e.name ?? `Block ${n + 1}`)
956
+ children: U(e.label, e.name ?? `Block ${n + 1}`)
887
957
  }), e.description ? /* @__PURE__ */ b("p", {
888
958
  className: "text-xs text-muted-foreground",
889
- children: G(e.description, "")
959
+ children: U(e.description, "")
890
960
  }) : null]
891
- }), c]
961
+ }), u]
892
962
  }, e.name ?? `block-${n}`);
893
963
  })
894
964
  });
895
- let c = K(e.columns);
896
- if (e.type === "matrix" && c.length > 0) return /* @__PURE__ */ b("div", {
965
+ let l = W(e.columns), u = G(e.order);
966
+ if (c === "matrix" && l.length > 0) return /* @__PURE__ */ b("div", {
897
967
  className: i,
898
968
  "data-testid": "dataset-report",
899
969
  "data-report-name": e.name,
900
- children: /* @__PURE__ */ b(ue, {
970
+ children: /* @__PURE__ */ b(Z, {
901
971
  dataset: String(e.dataset ?? ""),
902
- rows: K(e.rows),
903
- columnsAcross: c,
904
- values: K(e.values),
972
+ rows: W(e.rows),
973
+ columnsAcross: l,
974
+ values: W(e.values),
905
975
  runtimeFilter: o,
906
976
  dataSource: t,
907
- onDrill: s
977
+ onDrill: s,
978
+ order: u
908
979
  })
909
980
  });
910
- let l = e.chart && typeof e.chart == "object" && e.chart.type ? e.chart : null;
981
+ let d = e.chart && typeof e.chart == "object" && e.chart.type ? e.chart : null;
911
982
  return /* @__PURE__ */ x("div", {
912
983
  className: `${i ?? ""} flex flex-col gap-3`,
913
984
  "data-testid": "dataset-report",
914
985
  "data-report-name": e.name,
915
- children: [l ? /* @__PURE__ */ b(ce, {
986
+ "data-report-presentation": c,
987
+ children: [d ? /* @__PURE__ */ b(me, {
916
988
  dataset: String(e.dataset ?? ""),
917
- chart: l,
989
+ chart: d,
918
990
  runtimeFilter: o,
919
- dataSource: t
920
- }) : null, /* @__PURE__ */ b(ae, {
991
+ dataSource: t,
992
+ order: u
993
+ }) : null, /* @__PURE__ */ b(ue, {
921
994
  dataset: String(e.dataset ?? ""),
922
- rows: K(e.rows),
923
- values: K(e.values),
995
+ rows: W(e.rows),
996
+ values: W(e.values),
924
997
  runtimeFilter: o,
925
998
  dataSource: t,
926
- onDrill: s
999
+ onDrill: s,
1000
+ order: u,
1001
+ withTotals: c === "summary" || c === "matrix"
927
1002
  })]
928
1003
  });
929
- }, $ = (e) => {
1004
+ }, Q = (e) => {
930
1005
  let { dataSource: t, rows: n, runtimeFilter: r, onDrill: i, className: a } = e, s = o.useContext(d), u = t ?? s?.dataSource, f = e.schema;
931
- return f && typeof f == "object" && f.type === "spec-report" && f.report && typeof f.report == "object" && (f = f.report), W(f) ? /* @__PURE__ */ b(de, {
1006
+ return f && typeof f == "object" && f.type === "spec-report" && f.report && typeof f.report == "object" && (f = f.report), H(f) ? /* @__PURE__ */ b(ge, {
932
1007
  report: f,
933
1008
  dataSource: u,
934
1009
  runtimeFilter: r,
@@ -937,21 +1012,21 @@ var de = ({ report: e, dataSource: t, runtimeFilter: n, onDrill: r, className: i
937
1012
  }) : c(f) ? /* @__PURE__ */ b("div", {
938
1013
  className: a,
939
1014
  "data-testid": "report-presentation-bridge",
940
- children: /* @__PURE__ */ b(U, { schema: {
1015
+ children: /* @__PURE__ */ b(V, { schema: {
941
1016
  type: "report-viewer",
942
1017
  report: l(f),
943
1018
  data: n ?? [],
944
1019
  showToolbar: !1
945
1020
  } })
946
- }) : /* @__PURE__ */ b(M, { schema: f });
1021
+ }) : /* @__PURE__ */ b(j, { schema: f });
947
1022
  };
948
1023
  //#endregion
949
1024
  //#region src/LiveReportExporter.ts
950
- async function fe(e, t) {
1025
+ async function $(e, t) {
951
1026
  let { dataSource: n, resource: r, queryParams: i, format: a, exportConfig: o } = t, s = a || e.defaultExportFormat || "pdf";
952
1027
  try {
953
1028
  let t = (await n.find(r, i)).data || [];
954
- return L(s, e, t, {
1029
+ return I(s, e, t, {
955
1030
  format: s,
956
1031
  ...e.exportConfigs?.[s],
957
1032
  ...o
@@ -969,17 +1044,17 @@ async function fe(e, t) {
969
1044
  };
970
1045
  }
971
1046
  }
972
- function pe(e, t, n = {}) {
973
- let { columns: r, filename: i, includeAggregationRow: a = !1 } = n, o = r || (e.fields || []).map(he), s = o.map((e) => e.header), c = t.map((e, t) => o.map((n) => {
1047
+ function _e(e, t, n = {}) {
1048
+ let { columns: r, filename: i, includeAggregationRow: a = !1 } = n, o = r || (e.fields || []).map(ye), s = o.map((e) => e.header), c = t.map((e, t) => o.map((n) => {
974
1049
  if (n.formula) return n.formula.replace(/\{ROW\}/g, String(t + 2));
975
1050
  let r = e[n.name];
976
- return ge(r, n.numberFormat);
1051
+ return be(r, n.numberFormat);
977
1052
  }));
978
1053
  if (a && t.length > 0) {
979
1054
  let n = o.map((n, r) => {
980
1055
  let i = (e.fields || []).find((e) => e.name === n.name);
981
1056
  if (i?.aggregation) {
982
- let e = ve(r), n = t.length + 1;
1057
+ let e = Se(r), n = t.length + 1;
983
1058
  switch (i.aggregation) {
984
1059
  case "sum": return `=SUM(${e}2:${e}${n})`;
985
1060
  case "avg": return `=AVERAGE(${e}2:${e}${n})`;
@@ -993,15 +1068,15 @@ function pe(e, t, n = {}) {
993
1068
  });
994
1069
  c.push(n);
995
1070
  }
996
- be("" + [s.join(" "), ...c.map((e) => e.join(" "))].join("\n"), i || `${e.title || "report"}.tsv`, "text/tab-separated-values");
1071
+ we("" + [s.join(" "), ...c.map((e) => e.join(" "))].join("\n"), i || `${e.title || "report"}.tsv`, "text/tab-separated-values");
997
1072
  }
998
- function me(e, t, n, r) {
1073
+ function ve(e, t, n, r) {
999
1074
  return async () => {
1000
1075
  let i = e.schedule;
1001
1076
  if (!i?.enabled) return [];
1002
1077
  let a = i.formats || [e.defaultExportFormat || "pdf"], o = [];
1003
1078
  for (let r of a) {
1004
- let i = await fe(e, {
1079
+ let i = await $(e, {
1005
1080
  dataSource: t,
1006
1081
  resource: n,
1007
1082
  format: r
@@ -1011,16 +1086,16 @@ function me(e, t, n, r) {
1011
1086
  return r(e, i), o;
1012
1087
  };
1013
1088
  }
1014
- function he(e) {
1089
+ function ye(e) {
1015
1090
  return {
1016
1091
  name: e.name,
1017
1092
  header: e.label || e.name
1018
1093
  };
1019
1094
  }
1020
- function ge(e, t) {
1021
- return e == null ? "" : typeof e == "number" && t ? e.toLocaleString("en-US", _e(t)) : ye(String(e));
1095
+ function be(e, t) {
1096
+ return e == null ? "" : typeof e == "number" && t ? e.toLocaleString("en-US", xe(t)) : Ce(String(e));
1022
1097
  }
1023
- function _e(e) {
1098
+ function xe(e) {
1024
1099
  if (e.includes("%")) return {
1025
1100
  style: "percent",
1026
1101
  minimumFractionDigits: 0
@@ -1031,23 +1106,23 @@ function _e(e) {
1031
1106
  maximumFractionDigits: Math.max(0, t - 1)
1032
1107
  };
1033
1108
  }
1034
- function ve(e) {
1109
+ function Se(e) {
1035
1110
  let t = "", n = e;
1036
1111
  for (; n >= 0;) t = String.fromCharCode(n % 26 + 65) + t, n = Math.floor(n / 26) - 1;
1037
1112
  return t;
1038
1113
  }
1039
- function ye(e) {
1114
+ function Ce(e) {
1040
1115
  if (e.length > 0) {
1041
1116
  let t = e.charAt(0);
1042
1117
  if (t === "=" || t === "+" || t === "-" || t === "@" || t === "|") return `'${e}`;
1043
1118
  }
1044
1119
  return e;
1045
1120
  }
1046
- function be(e, t, n) {
1121
+ function we(e, t, n) {
1047
1122
  let r = new Blob([e], { type: `${n};charset=utf-8` }), i = URL.createObjectURL(r), a = document.createElement("a");
1048
1123
  a.href = i, a.download = t, document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(i);
1049
1124
  }
1050
- e.register("report", $, {
1125
+ e.register("report", Q, {
1051
1126
  namespace: "report",
1052
1127
  label: "Report",
1053
1128
  category: "Report",
@@ -1068,7 +1143,7 @@ e.register("report", $, {
1068
1143
  label: "Chart Configuration"
1069
1144
  }
1070
1145
  ]
1071
- }), e.register("spec-report", $, {
1146
+ }), e.register("spec-report", Q, {
1072
1147
  namespace: "report",
1073
1148
  label: "Spec Report",
1074
1149
  category: "Report",
@@ -1081,7 +1156,7 @@ e.register("report", $, {
1081
1156
  type: "string",
1082
1157
  label: "Report Type"
1083
1158
  }]
1084
- }), e.register("report-viewer", U, {
1159
+ }), e.register("report-viewer", V, {
1085
1160
  namespace: "report",
1086
1161
  label: "Report Viewer",
1087
1162
  category: "Report",
@@ -1096,4 +1171,4 @@ e.register("report", $, {
1096
1171
  }]
1097
1172
  });
1098
1173
  //#endregion
1099
- export { de as DatasetReportRenderer, M as LegacyReportRenderer, $ as ReportRenderer, U as ReportViewer, me as createScheduleTrigger, N as exportAsCSV, I as exportAsExcel, F as exportAsHTML, P as exportAsJSON, ee as exportAsPDF, pe as exportExcelWithFormulas, L as exportReport, fe as exportWithLiveData, H as formatValue, W as isDatasetReport, a as mergeFilters };
1174
+ export { ge as DatasetReportRenderer, j as LegacyReportRenderer, Q as ReportRenderer, V as ReportViewer, ve as createScheduleTrigger, M as exportAsCSV, F as exportAsExcel, P as exportAsHTML, N as exportAsJSON, te as exportAsPDF, _e as exportExcelWithFormulas, I as exportReport, $ as exportWithLiveData, B as formatValue, H as isDatasetReport, a as mergeFilters };