deepspotscreen-sdk 0.0.3 → 0.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.
@@ -1,10 +1,10 @@
1
- class F {
1
+ class ae {
2
2
  constructor(e, t) {
3
3
  this.tokenCache = /* @__PURE__ */ new Map(), this.baseUrl = e.replace(/\/$/, ""), this.apiKey = t;
4
4
  }
5
5
  // ── Embed Token ─────────────────────────────────────────────────────────────
6
6
  async getEmbedToken(e) {
7
- var i, a, o, d;
7
+ var i, a, o, l;
8
8
  const t = [
9
9
  e.dashboardId,
10
10
  e.embedType,
@@ -18,7 +18,7 @@ class F {
18
18
  {
19
19
  dashboardId: e.dashboardId,
20
20
  embedType: e.embedType,
21
- embedLevel: (d = e.embedLevel) != null ? d : "dashboard",
21
+ embedLevel: (l = e.embedLevel) != null ? l : "dashboard",
22
22
  componentId: e.componentId,
23
23
  userId: e.userId,
24
24
  tenantId: e.tenantId,
@@ -146,7 +146,7 @@ class F {
146
146
  return (t == null ? void 0 : t.data) !== void 0 ? t.data : t;
147
147
  }
148
148
  }
149
- class $ {
149
+ class Q {
150
150
  constructor(e) {
151
151
  var t, s;
152
152
  this.destroyed = !1, this.refreshTimer = null, this.opts = e, this.filters = { ...e.activeFilters }, this.activePageId = (t = e.activePageId) != null ? t : "", this.activeTabId = (s = e.activeTabId) != null ? s : "";
@@ -163,6 +163,14 @@ class $ {
163
163
  setFilters(e) {
164
164
  Object.assign(this.filters, e), this.scheduleRefresh();
165
165
  }
166
+ /** v2 alias for setFilter — sets a global filter and re-fetches data */
167
+ setGlobalFilter(e, t) {
168
+ this.setFilter(e, t);
169
+ }
170
+ /** v2: clear all active filters and re-fetch data */
171
+ clearFilters() {
172
+ this.filters = {}, this.scheduleRefresh();
173
+ }
166
174
  /** Navigate to a different page (dashboard embed only) */
167
175
  goToPage(e) {
168
176
  this.opts.embedType === "dashboard" && (this.activePageId = e, this.opts.renderer.goToPage(e));
@@ -206,8 +214,8 @@ class $ {
206
214
  });
207
215
  }
208
216
  }
209
- const A = 24, w = 10, T = 12;
210
- class S {
217
+ const oe = 24, E = 10, D = 12;
218
+ class V {
211
219
  /**
212
220
  * @param containerWidth Actual pixel width of the grid container.
213
221
  * @param minY Minimum y value across all components (normalises
@@ -218,23 +226,23 @@ class S {
218
226
  }
219
227
  /** Pixel width of one column unit */
220
228
  get colWidth() {
221
- return this.containerWidth / A;
229
+ return this.containerWidth / oe;
222
230
  }
223
231
  /** Convert grid position {x,y,w,h} → CSS absolute pixel values */
224
232
  toPx(e) {
225
- const t = this.colWidth, s = T / 2;
233
+ const t = this.colWidth, s = D / 2;
226
234
  return {
227
235
  left: e.x * t + s,
228
- top: (e.y - this.minY) * w + s,
229
- width: e.w * t - T,
230
- height: e.h * w - T
236
+ top: (e.y - this.minY) * E + s,
237
+ width: e.w * t - D,
238
+ height: e.h * E - D
231
239
  };
232
240
  }
233
241
  /** Total pixel height required to fit all positioned components */
234
242
  static totalHeight(e) {
235
243
  if (!e.length) return 400;
236
244
  const t = Math.min(...e.map((r) => r.y));
237
- return (Math.max(...e.map((r) => r.y + r.h)) - t) * w + 40;
245
+ return (Math.max(...e.map((r) => r.y + r.h)) - t) * E + 40;
238
246
  }
239
247
  /** Apply absolute positioning styles directly to a DOM element */
240
248
  applyStyles(e, t) {
@@ -242,11 +250,11 @@ class S {
242
250
  e.style.position = "absolute", e.style.left = `${s.left}px`, e.style.top = `${s.top}px`, e.style.width = `${s.width}px`, e.style.height = `${s.height}px`;
243
251
  }
244
252
  }
245
- let k = null;
246
- function E() {
247
- return k || (k = import("./apexcharts.common-k3hLWpB8.js").then((u) => u.a)), k;
253
+ let j = null;
254
+ function de() {
255
+ return j || (j = import("./apexcharts.common-k3hLWpB8.js").then((w) => w.a)), j;
248
256
  }
249
- class R {
257
+ class se {
250
258
  constructor(e) {
251
259
  this.chart = null, this.container = e;
252
260
  }
@@ -270,7 +278,7 @@ class R {
270
278
  if (a)
271
279
  try {
272
280
  this.chart && this.chart.destroy();
273
- const { default: o } = await E();
281
+ const { default: o } = await de();
274
282
  this.chart = new o(a, i), this.chart.render();
275
283
  } catch (o) {
276
284
  console.error("[Deepspot SDK] ChartRenderer error:", o), a.innerHTML = '<div class="ds-chart-empty">Chart render error</div>';
@@ -307,7 +315,7 @@ class R {
307
315
  }
308
316
  buildCartesianOptions(e, t, s, r) {
309
317
  var n;
310
- const { series: i, categories: a, xAxisLabel: o, yAxisLabel: d } = this.extractSeriesAndCategories(e, t), c = e.properties || {}, h = c.colors ? Object.values(c.colors) : ["#6366f1", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#3b82f6"], l = s === "dark";
318
+ const { series: i, categories: a, xAxisLabel: o, yAxisLabel: l } = this.extractSeriesAndCategories(e, t), d = e.properties || {}, f = d.colors ? Object.values(d.colors) : ["#6366f1", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#3b82f6"], h = s === "dark";
311
319
  return {
312
320
  chart: {
313
321
  type: e.type === "area" ? "area" : e.type === "line" ? "line" : "bar",
@@ -326,23 +334,23 @@ class R {
326
334
  title: { text: o },
327
335
  labels: {
328
336
  rotate: a.length > 8 ? -45 : 0,
329
- style: { colors: l ? "#94a3b8" : "#6b7280", fontSize: "11px" }
337
+ style: { colors: h ? "#94a3b8" : "#6b7280", fontSize: "11px" }
330
338
  },
331
- axisBorder: { color: l ? "#334155" : "#e5e7eb" },
332
- axisTicks: { color: l ? "#334155" : "#e5e7eb" }
339
+ axisBorder: { color: h ? "#334155" : "#e5e7eb" },
340
+ axisTicks: { color: h ? "#334155" : "#e5e7eb" }
333
341
  },
334
342
  yaxis: {
335
- title: { text: d },
336
- labels: { style: { colors: l ? "#94a3b8" : "#6b7280", fontSize: "11px" } }
343
+ title: { text: l },
344
+ labels: { style: { colors: h ? "#94a3b8" : "#6b7280", fontSize: "11px" } }
337
345
  },
338
- colors: h,
346
+ colors: f,
339
347
  legend: {
340
- show: i.length > 1 || ((n = c.showLegend) != null ? n : !1),
348
+ show: i.length > 1 || ((n = d.showLegend) != null ? n : !1),
341
349
  position: "bottom",
342
- labels: { colors: l ? "#94a3b8" : "#6b7280" }
350
+ labels: { colors: h ? "#94a3b8" : "#6b7280" }
343
351
  },
344
352
  grid: {
345
- borderColor: l ? "#1e293b" : "#f3f4f6",
353
+ borderColor: h ? "#1e293b" : "#f3f4f6",
346
354
  strokeDashArray: 4,
347
355
  padding: {
348
356
  bottom: a.length > 8 ? 60 : 10
@@ -364,10 +372,10 @@ class R {
364
372
  };
365
373
  }
366
374
  buildPieOptions(e, t, s, r) {
367
- const i = e.properties || {}, a = t.length > 0 ? Object.keys(t[0]) : [], o = a[0] || "label", d = a[1] || "value", c = t.map((b) => {
368
- var p;
369
- return String((p = b[o]) != null ? p : "");
370
- }), h = t.map((b) => Number(b[d]) || 0), l = s === "dark", n = i.colors ? Object.values(i.colors) : ["#6366f1", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#3b82f6"];
375
+ const i = e.properties || {}, a = t.length > 0 ? Object.keys(t[0]) : [], o = a[0] || "label", l = a[1] || "value", d = t.map((p) => {
376
+ var b;
377
+ return String((b = p[o]) != null ? b : "");
378
+ }), f = t.map((p) => Number(p[l]) || 0), h = s === "dark", n = i.colors ? Object.values(i.colors) : ["#6366f1", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#3b82f6"];
371
379
  return {
372
380
  chart: {
373
381
  type: e.type,
@@ -377,15 +385,15 @@ class R {
377
385
  height: r != null ? r : "100%"
378
386
  },
379
387
  theme: { mode: s },
380
- series: h,
381
- labels: c,
388
+ series: f,
389
+ labels: d,
382
390
  colors: n,
383
391
  legend: {
384
392
  position: "bottom",
385
- labels: { colors: l ? "#94a3b8" : "#6b7280" }
393
+ labels: { colors: h ? "#94a3b8" : "#6b7280" }
386
394
  },
387
395
  tooltip: { theme: s },
388
- dataLabels: { enabled: c.length <= 8 },
396
+ dataLabels: { enabled: d.length <= 8 },
389
397
  plotOptions: {
390
398
  pie: {
391
399
  donut: { size: e.type === "donut" ? "65%" : "0%" }
@@ -400,32 +408,32 @@ class R {
400
408
  try {
401
409
  const n = typeof s.selectedYAxisColumn == "string" ? JSON.parse(s.selectedYAxisColumn) : s.selectedYAxisColumn;
402
410
  Array.isArray(n) && (a = n.map(
403
- (b) => typeof b == "string" ? { column: b } : b
411
+ (p) => typeof p == "string" ? { column: p } : p
404
412
  ));
405
413
  } catch (n) {
406
414
  }
407
415
  if (!a.length && s.yAxis) {
408
416
  const n = s.yAxis;
409
- a = (Array.isArray(n) ? n : [n]).map((p) => ({ column: String(p) }));
417
+ a = (Array.isArray(n) ? n : [n]).map((b) => ({ column: String(b) }));
410
418
  }
411
419
  !a.length && r.length > 1 && (a = r.slice(1).map((n) => ({ column: n })));
412
420
  const o = t.map((n) => {
413
- var b;
414
- return String((b = n[i]) != null ? b : "");
415
- }), d = t.length > 0 ? Object.keys(t[0]) : [], c = a.map((n) => {
416
- const b = d.includes(n.column) ? n.column : null, p = b ? null : d.find((g) => g.includes(n.column) || n.column.includes(g)), m = !b && !p ? d.find((g) => {
421
+ var p;
422
+ return String((p = n[i]) != null ? p : "");
423
+ }), l = t.length > 0 ? Object.keys(t[0]) : [], d = a.map((n) => {
424
+ const p = l.includes(n.column) ? n.column : null, b = p ? null : l.find((u) => u.includes(n.column) || n.column.includes(u)), x = !p && !b ? l.find((u) => {
417
425
  var y;
418
- return g !== i && !isNaN(Number((y = t[0]) == null ? void 0 : y[g]));
419
- }) : null, f = b || p || m || n.column;
426
+ return u !== i && !isNaN(Number((y = t[0]) == null ? void 0 : y[u]));
427
+ }) : null, c = p || b || x || n.column;
420
428
  return {
421
429
  name: n.label || n.column.replace(/_/g, " "),
422
- data: t.map((g) => {
423
- const y = g[f];
430
+ data: t.map((u) => {
431
+ const y = u[c];
424
432
  return y != null ? Number(y) : null;
425
433
  })
426
434
  };
427
- }), h = s.xAxisLabel || i.replace(/_/g, " "), l = s.yAxisLabel || (c.length === 1 ? c[0].name : "Values");
428
- return { series: c, categories: o, xAxisLabel: h, yAxisLabel: l };
435
+ }), f = s.xAxisLabel || i.replace(/_/g, " "), h = s.yAxisLabel || (d.length === 1 ? d[0].name : "Values");
436
+ return { series: d, categories: o, xAxisLabel: f, yAxisLabel: h };
429
437
  }
430
438
  renderEmpty(e) {
431
439
  this.container.innerHTML = `
@@ -436,18 +444,18 @@ class R {
436
444
  `;
437
445
  }
438
446
  }
439
- class L {
447
+ class re {
440
448
  constructor() {
441
449
  this.columns = [], this.allData = [], this.currentRows = [], this.totalRows = 0, this.currentPage = 1, this.currentPageSize = 10, this.searchTerm = "", this.isLoading = !1;
442
450
  }
443
451
  // ── Public API ─────────────────────────────────────────────────────────────
444
452
  render(e, t, s, r) {
445
- var h;
453
+ var f;
446
454
  this.container = e, this.component = t, this.fetchPage = r, this.searchTerm = "", this.currentPage = 1, this.currentPageSize = 10;
447
455
  const i = s && !Array.isArray(s) && "rows" in s;
448
456
  if (i) {
449
- const l = s;
450
- this.currentRows = l.rows, this.allData = [], this.totalRows = l.total, this.currentPage = l.page, this.currentPageSize = l.pageSize;
457
+ const h = s;
458
+ this.currentRows = h.rows, this.allData = [], this.totalRows = h.total, this.currentPage = h.page, this.currentPageSize = h.pageSize;
451
459
  } else
452
460
  this.allData = s || [], this.currentRows = [], this.totalRows = this.allData.length, this.currentPage = 1;
453
461
  if (i && s.rows.length === 0 && s.total === 0 || !i && this.allData.length === 0) {
@@ -462,18 +470,18 @@ class L {
462
470
  `;
463
471
  return;
464
472
  }
465
- const a = i ? s.rows[0] : this.allData[0], o = a ? Object.keys(a) : [], d = ((h = t.properties) == null ? void 0 : h.columns) || [], c = d.length ? d.filter((l) => o.includes(l)) : [];
466
- this.columns = c.length ? c : o, this.paint();
473
+ const a = i ? s.rows[0] : this.allData[0], o = a ? Object.keys(a) : [], l = ((f = t.properties) == null ? void 0 : f.columns) || [], d = l.length ? l.filter((h) => o.includes(h)) : [];
474
+ this.columns = d.length ? d : o, this.paint();
467
475
  }
468
476
  // ── Rendering ──────────────────────────────────────────────────────────────
469
477
  paint() {
470
- const { rows: e, startNum: t } = this.getPageRows(), s = Math.max(1, Math.ceil(this.totalRows / this.currentPageSize)), r = (this.currentPage - 1) * this.currentPageSize + 1, i = this.fetchPage ? Math.min(r - 1 + (this.isLoading ? this.currentPageSize : e.length), this.totalRows) : Math.min(this.currentPage * this.currentPageSize, this.totalRows), a = this.columns.map((n) => `<th>${this.escape(this.formatHeader(n))}</th>`).join(""), o = e.length === 0 ? `<tr><td colspan="${this.columns.length + 1}" style="text-align:center;padding:20px;color:#9ca3af">No results found</td></tr>` : e.map((n, b) => {
471
- const p = this.columns.map((m) => {
472
- const f = n[m];
473
- return `<td title="${this.escape(String(f != null ? f : ""))}">${this.escape(this.formatValue(f))}</td>`;
478
+ const { rows: e, startNum: t } = this.getPageRows(), s = Math.max(1, Math.ceil(this.totalRows / this.currentPageSize)), r = (this.currentPage - 1) * this.currentPageSize + 1, i = this.fetchPage ? Math.min(r - 1 + (this.isLoading ? this.currentPageSize : e.length), this.totalRows) : Math.min(this.currentPage * this.currentPageSize, this.totalRows), a = this.columns.map((n) => `<th>${this.escape(this.formatHeader(n))}</th>`).join(""), o = e.length === 0 ? `<tr><td colspan="${this.columns.length + 1}" style="text-align:center;padding:20px;color:#9ca3af">No results found</td></tr>` : e.map((n, p) => {
479
+ const b = this.columns.map((x) => {
480
+ const c = n[x];
481
+ return `<td title="${this.escape(String(c != null ? c : ""))}">${this.escape(this.formatValue(c))}</td>`;
474
482
  }).join("");
475
- return `<tr><td class="ds-table-sno">${t + b}</td>${p}</tr>`;
476
- }).join(""), d = this.currentPageSize, c = [10, 25, 50, 100].map((n) => `<option value="${n}"${n === d ? " selected" : ""}>${n}</option>`).join(""), h = this.currentPage <= 1, l = this.currentPage >= s;
483
+ return `<tr><td class="ds-table-sno">${t + p}</td>${b}</tr>`;
484
+ }).join(""), l = this.currentPageSize, d = [10, 25, 50, 100].map((n) => `<option value="${n}"${n === l ? " selected" : ""}>${n}</option>`).join(""), f = this.currentPage <= 1, h = this.currentPage >= s;
477
485
  this.container.innerHTML = `
478
486
  <div class="ds-table-card">
479
487
  <div class="ds-table-header-row">
@@ -492,14 +500,14 @@ class L {
492
500
  <div class="ds-table-info">
493
501
  <span>${r.toLocaleString()}–${i.toLocaleString()} of ${this.totalRows.toLocaleString()}</span>
494
502
  <span class="ds-table-rows-label">Rows:</span>
495
- <select class="ds-table-page-size">${c}</select>
503
+ <select class="ds-table-page-size">${d}</select>
496
504
  </div>
497
505
  <div class="ds-table-pagination">
498
- <button class="ds-table-pg-btn" data-action="first" ${h ? "disabled" : ""}>&#171;</button>
499
- <button class="ds-table-pg-btn" data-action="prev" ${h ? "disabled" : ""}>Previous</button>
506
+ <button class="ds-table-pg-btn" data-action="first" ${f ? "disabled" : ""}>&#171;</button>
507
+ <button class="ds-table-pg-btn" data-action="prev" ${f ? "disabled" : ""}>Previous</button>
500
508
  <span class="ds-table-pg-info">Page ${this.currentPage} of ${s}</span>
501
- <button class="ds-table-pg-btn" data-action="next" ${l ? "disabled" : ""}>Next</button>
502
- <button class="ds-table-pg-btn" data-action="last" ${l ? "disabled" : ""}>&#187;</button>
509
+ <button class="ds-table-pg-btn" data-action="next" ${h ? "disabled" : ""}>Next</button>
510
+ <button class="ds-table-pg-btn" data-action="last" ${h ? "disabled" : ""}>&#187;</button>
503
511
  </div>
504
512
  </div>
505
513
  ${this.isLoading ? '<div class="ds-table-loading-overlay"><div class="ds-embed-spinner"></div></div>' : ""}
@@ -566,26 +574,26 @@ class L {
566
574
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
567
575
  }
568
576
  }
569
- class C {
577
+ class ie {
570
578
  render(e, t, s) {
571
579
  const r = t.properties || {};
572
580
  let i = null;
573
581
  if (s && s.length > 0) {
574
- const b = s[0], p = r.metric || Object.keys(b)[0], m = b[p];
575
- if (m !== void 0)
576
- i = m;
582
+ const b = s[0], x = r.metric || Object.keys(b)[0], c = b[x];
583
+ if (c !== void 0)
584
+ i = c;
577
585
  else {
578
- const f = Object.keys(b).find(
579
- (g) => g.includes(p) || p.includes(g)
586
+ const u = Object.keys(b).find(
587
+ (y) => y.includes(x) || x.includes(y)
580
588
  );
581
- i = b[f != null ? f : Object.keys(b)[0]];
589
+ i = b[u != null ? u : Object.keys(b)[0]];
582
590
  }
583
591
  }
584
- const a = this.formatValue(i, r), o = r.backgroundColor || "", d = r.textColor || "", c = t.title || "", h = o ? `background:${o};border-color:${o};` : "", l = d ? `color:${d};` : "", n = d ? `color:${d};opacity:0.7;` : "";
592
+ const a = this.formatValue(i, r), o = r.styleConfig || {}, l = o.backgroundColor || r.backgroundColor || "", d = o.color || o.textColor || r.textColor || "", f = t.title || "", h = l ? `background:${l};border-color:${l};` : "", n = d ? `color:${d};` : "", p = d ? `color:${d};opacity:0.7;` : "";
585
593
  e.innerHTML = `
586
594
  <div class="ds-card"${h ? ` style="${h}"` : ""}>
587
- <div class="ds-card-label"${n ? ` style="${n}"` : ""}>${c}</div>
588
- <div class="ds-card-value"${l ? ` style="${l}"` : ""}>${a}</div>
595
+ <div class="ds-card-label"${p ? ` style="${p}"` : ""}>${f}</div>
596
+ <div class="ds-card-value"${n ? ` style="${n}"` : ""}>${a}</div>
589
597
  </div>
590
598
  `;
591
599
  }
@@ -598,7 +606,7 @@ class C {
598
606
  return Math.abs(s) >= 1e6 ? a = (s / 1e6).toFixed(1) + "M" : Math.abs(s) >= 1e3 ? a = (s / 1e3).toFixed(1) + "K" : a = s % 1 === 0 ? s.toLocaleString() : s.toFixed(2), `${r}${a}${i}`;
599
607
  }
600
608
  }
601
- class D {
609
+ class ne {
602
610
  constructor(e, t) {
603
611
  this.currentValues = {}, this.container = e, this.onFilterChange = t;
604
612
  }
@@ -696,16 +704,16 @@ class D {
696
704
  attachListeners(e) {
697
705
  const t = {};
698
706
  this.container.querySelectorAll("[data-filter-id]").forEach((s) => {
699
- const r = s.dataset.filterId, i = s.dataset.datePart, a = e.find((d) => d.filterId === r), o = () => {
700
- let d;
707
+ const r = s.dataset.filterId, i = s.dataset.datePart, a = e.find((l) => l.filterId === r), o = () => {
708
+ let l;
701
709
  if ((a == null ? void 0 : a.type) === "date-range" && i)
702
- t[r] = t[r] || {}, t[r][i] = s.value, d = { ...t[r] };
710
+ t[r] = t[r] || {}, t[r][i] = s.value, l = { ...t[r] };
703
711
  else if ((a == null ? void 0 : a.type) === "multi-select") {
704
- const c = s;
705
- d = Array.from(c.selectedOptions).map((h) => h.value).filter(Boolean);
712
+ const d = s;
713
+ l = Array.from(d.selectedOptions).map((f) => f.value).filter(Boolean);
706
714
  } else
707
- d = s.value;
708
- this.currentValues[r] = d, this.onFilterChange(r, d);
715
+ l = s.value;
716
+ this.currentValues[r] = l, this.onFilterChange(r, l);
709
717
  };
710
718
  s.addEventListener(
711
719
  (a == null ? void 0 : a.type) === "text-input" ? "input" : "change",
@@ -714,15 +722,15 @@ class D {
714
722
  });
715
723
  }
716
724
  escAttr(e) {
717
- return e.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
725
+ return String(e != null ? e : "").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
718
726
  }
719
727
  escText(e) {
720
- return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
728
+ return String(e != null ? e : "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
721
729
  }
722
730
  }
723
- class z {
731
+ const A = class A {
724
732
  constructor(e, t) {
725
- this.activePageId = "", this.activeTabId = "", this.activeFilters = {}, this.chartRenderers = /* @__PURE__ */ new Map(), this.tableRenderer = new L(), this.cardRenderer = new C(), this.isLoadingTab = !1, this.root = e, this.opts = t, this.activeFilters = { ...t.initialFilters };
733
+ this.activePageId = "", this.activeTabId = "", this.activeFilters = {}, this.chartRenderers = /* @__PURE__ */ new Map(), this.tableRenderer = new re(), this.cardRenderer = new ie(), this.isLoadingTab = !1, this.root = e, this.opts = t, this.activeFilters = { ...t.initialFilters };
726
734
  }
727
735
  // ── Initial full render ───────────────────────────────────────────────────
728
736
  render(e) {
@@ -744,45 +752,45 @@ class z {
744
752
  this.chartRenderers.forEach((e) => e.destroy()), this.chartRenderers.clear(), this.root.innerHTML = "";
745
753
  }
746
754
  exportPDF() {
747
- var n, b;
755
+ var n, p;
748
756
  const e = this.root.querySelector("#ds-grid");
749
757
  if (!e) return;
750
758
  const t = this.root.style.height, s = this.root.style.overflow;
751
759
  this.root.style.height = "auto", this.root.style.overflow = "visible";
752
- const r = this.root.querySelector("#ds-canvas"), i = (n = r == null ? void 0 : r.style.height) != null ? n : "", a = (b = r == null ? void 0 : r.style.overflow) != null ? b : "";
760
+ const r = this.root.querySelector("#ds-canvas"), i = (n = r == null ? void 0 : r.style.height) != null ? n : "", a = (p = r == null ? void 0 : r.style.overflow) != null ? p : "";
753
761
  r && (r.style.height = "auto", r.style.overflow = "visible");
754
- const o = Array.from(e.querySelectorAll(".ds-table-scroll")), d = o.map((p) => ({
755
- el: p,
756
- overflow: p.style.overflow,
757
- maxHeight: p.style.maxHeight,
758
- height: p.style.height
762
+ const o = Array.from(e.querySelectorAll(".ds-table-scroll")), l = o.map((b) => ({
763
+ el: b,
764
+ overflow: b.style.overflow,
765
+ maxHeight: b.style.maxHeight,
766
+ height: b.style.height
759
767
  }));
760
- o.forEach((p) => {
761
- p.style.overflow = "visible", p.style.maxHeight = "none", p.style.height = "auto";
768
+ o.forEach((b) => {
769
+ b.style.overflow = "visible", b.style.maxHeight = "none", b.style.height = "auto";
762
770
  });
763
- const c = e.offsetWidth, h = parseInt(e.style.height, 10) || e.offsetHeight, l = e.getBoundingClientRect().top + window.scrollY;
771
+ const d = e.offsetWidth, f = parseInt(e.style.height, 10) || e.offsetHeight, h = e.getBoundingClientRect().top + window.scrollY;
764
772
  import("./html2canvas.esm-CzwMv54K.js").then(
765
- ({ default: p }) => p(e, {
773
+ ({ default: b }) => b(e, {
766
774
  scale: 2,
767
775
  useCORS: !0,
768
776
  allowTaint: !0,
769
777
  logging: !1,
770
- width: c,
771
- height: h,
772
- windowWidth: c,
773
- windowHeight: h,
778
+ width: d,
779
+ height: f,
780
+ windowWidth: d,
781
+ windowHeight: f,
774
782
  scrollX: 0,
775
- scrollY: -l
776
- }).then((m) => {
777
- this.root.style.height = t, this.root.style.overflow = s, r && (r.style.height = i, r.style.overflow = a), d.forEach(({ el: f, overflow: g, maxHeight: y, height: v }) => {
778
- f.style.overflow = g, f.style.maxHeight = y, f.style.height = v;
779
- }), import("./jspdf.es.min-Ge0fRUwj.js").then((f) => f.j).then(({ jsPDF: f }) => {
780
- const g = m.width / 2, y = m.height / 2, v = new f({
781
- orientation: g >= y ? "landscape" : "portrait",
783
+ scrollY: -h
784
+ }).then((x) => {
785
+ this.root.style.height = t, this.root.style.overflow = s, r && (r.style.height = i, r.style.overflow = a), l.forEach(({ el: c, overflow: u, maxHeight: y, height: T }) => {
786
+ c.style.overflow = u, c.style.maxHeight = y, c.style.height = T;
787
+ }), import("./jspdf.es.min-Ge0fRUwj.js").then((c) => c.j).then(({ jsPDF: c }) => {
788
+ const u = x.width / 2, y = x.height / 2, T = new c({
789
+ orientation: u >= y ? "landscape" : "portrait",
782
790
  unit: "px",
783
- format: [g, y]
791
+ format: [u, y]
784
792
  });
785
- v.addImage(m.toDataURL("image/png"), "PNG", 0, 0, g, y), v.save(`${this.renderData.dashboard.name || "dashboard"}.pdf`);
793
+ T.addImage(x.toDataURL("image/png"), "PNG", 0, 0, u, y), T.save(`${this.renderData.dashboard.name || "dashboard"}.pdf`);
786
794
  });
787
795
  })
788
796
  );
@@ -793,8 +801,8 @@ class z {
793
801
  if (!(t != null && t.length) || !["table", "bar", "line", "area"].includes(e.type)) return;
794
802
  const s = Object.keys(t[0]), r = [s.join(","), ...t.map(
795
803
  (a) => s.map((o) => {
796
- var d;
797
- return JSON.stringify((d = a[o]) != null ? d : "");
804
+ var l;
805
+ return JSON.stringify((l = a[o]) != null ? l : "");
798
806
  }).join(",")
799
807
  )].join(`
800
808
  `);
@@ -825,10 +833,12 @@ class z {
825
833
  </div>
826
834
  `, this.root.style.position = "relative", this.opts.hideExport || this.buildExportToolbar();
827
835
  const i = this.root.querySelector("#ds-filter-container");
828
- this.filterRenderer = new D(i, (a, o) => {
829
- var h, l;
830
- const d = this.renderData.filters.find((n) => n.filterId === a), c = (d == null ? void 0 : d.applyToField) || a;
831
- this.activeFilters[c] = o, (l = (h = this.opts).onFilterChange) == null || l.call(h, this.activeFilters), this.opts.onTabSwitch(this.activePageId, this.activeTabId);
836
+ this.filterRenderer = new ne(i, (a, o) => {
837
+ var h, n, p, b, x;
838
+ const l = (h = this.renderData.filters) == null ? void 0 : h.find((c) => c.filterId === a), d = (n = this.renderData.components) == null ? void 0 : n.find(
839
+ (c) => c.type === "inline-filter" && c.id === a
840
+ ), f = (l == null ? void 0 : l.applyToField) || ((p = d == null ? void 0 : d.properties) == null ? void 0 : p.applyToField) || a;
841
+ this.activeFilters[f] = o, (x = (b = this.opts).onFilterChange) == null || x.call(b, this.activeFilters), this.opts.onTabSwitch(this.activePageId, this.activeTabId);
832
842
  });
833
843
  }
834
844
  buildExportToolbar() {
@@ -876,7 +886,6 @@ class z {
876
886
  });
877
887
  });
878
888
  }
879
- /** Optimistically highlight new tab + show spinner, then fire callback */
880
889
  triggerTabSwitch(e, t) {
881
890
  this.isLoadingTab || !e || !t || (this.isLoadingTab = !0, this.activePageId = e, this.activeTabId = t, this.syncNavHighlight(), this.showTabSpinner(), this.opts.onTabSwitch(e, t));
882
891
  }
@@ -887,18 +896,42 @@ class z {
887
896
  const e = this.root.querySelector("#ds-tab-nav");
888
897
  e && this.buildTabButtons(e, this.activePageId);
889
898
  }
890
- // ── Filter bar ────────────────────────────────────────────────────────────
899
+ // ── Global Filter bar ─────────────────────────────────────────────────────
900
+ // Merges global filters (from renderData.filters[]) with inline-filter
901
+ // components (type='inline-filter' in renderData.components[]).
902
+ // Inline-filter components are NOT rendered in the grid — they appear here.
891
903
  renderFilterBar() {
892
- this.opts.hideFilters || (this.filterRenderer.render(this.renderData.filters, this.activeFilters), this.fetchFilterOptions());
904
+ if (this.opts.hideGlobalFilters) return;
905
+ const e = [
906
+ ...this.renderData.filters || [],
907
+ ...this.inlineFiltersAsDefinitions()
908
+ ];
909
+ this.filterRenderer.render(e, this.activeFilters), this.fetchFilterOptions();
893
910
  }
894
911
  updateFilterBar() {
895
- this.opts.hideFilters || (this.filterRenderer.render(this.renderData.filters, this.activeFilters), this.fetchFilterOptions());
912
+ if (this.opts.hideGlobalFilters) return;
913
+ const e = [
914
+ ...this.renderData.filters || [],
915
+ ...this.inlineFiltersAsDefinitions()
916
+ ];
917
+ this.filterRenderer.render(e, this.activeFilters), this.fetchFilterOptions();
918
+ }
919
+ /** Convert inline-filter ComponentConfig entries to FilterDefinition shape */
920
+ inlineFiltersAsDefinitions() {
921
+ return this.opts.hideInlineFilters ? [] : (this.renderData.components || []).filter((e) => e.type === "inline-filter").map((e) => {
922
+ var t, s, r, i, a, o, l, d;
923
+ return {
924
+ filterId: e.id,
925
+ label: ((t = e.properties) == null ? void 0 : t.filterLabel) || e.title || "",
926
+ type: ((s = e.properties) == null ? void 0 : s.filterType) || "dropdown",
927
+ options: ((r = e.properties) == null ? void 0 : r.filterOptions) || ((i = e.properties) == null ? void 0 : i.options) || [],
928
+ defaultValue: (a = e.properties) == null ? void 0 : a.defaultValue,
929
+ targetComponents: ((o = e.properties) == null ? void 0 : o.targetComponents) || [],
930
+ filterOperator: (l = e.properties) == null ? void 0 : l.filterOperator,
931
+ applyToField: ((d = e.properties) == null ? void 0 : d.applyToField) || e.id
932
+ };
933
+ });
896
934
  }
897
- /**
898
- * For every dropdown / multi-select filter whose options array is empty,
899
- * call onFetchFilterOptions(filterId) and populate the select element.
900
- * Mirrors: GET /dashboard-builder/{dashboardId}/filters/{filterId}/options
901
- */
902
935
  async fetchFilterOptions() {
903
936
  if (this.opts.onFetchFilterOptions)
904
937
  for (const e of this.renderData.filters) {
@@ -912,47 +945,124 @@ class z {
912
945
  this.hideTabSpinner();
913
946
  const e = this.root.querySelector("#ds-grid");
914
947
  if (!e) return;
915
- this.chartRenderers.forEach((c) => c.destroy()), this.chartRenderers.clear();
916
- const t = this.renderData.components;
948
+ if (!this.opts.hideBackground) {
949
+ const d = this.root.querySelector("#ds-canvas"), f = this.renderData.dashboard.pages.find(
950
+ (n) => n.pageId === this.activePageId
951
+ ), h = (f == null ? void 0 : f.backgroundColor) || "";
952
+ d && (d.style.background = h), this.root.style.background = h;
953
+ }
954
+ this.chartRenderers.forEach((d) => d.destroy()), this.chartRenderers.clear();
955
+ const t = (this.renderData.components || []).filter(
956
+ (d) => d.type !== "inline-filter"
957
+ );
917
958
  if (!t.length) {
918
959
  e.style.height = "200px", e.innerHTML = '<div class="ds-chart-empty" style="padding-top:80px;">No components on this tab.</div>';
919
960
  return;
920
961
  }
921
- const s = e.clientWidth || this.root.clientWidth || 800, r = t.map((c) => c.position), i = r.length ? Math.min(...r.map((c) => c.y)) : 0, a = new S(s, i);
922
- e.style.height = `${S.totalHeight(r)}px`, e.innerHTML = "";
923
- const o = 36, d = [];
924
- t.forEach((c) => {
925
- const h = document.createElement("div");
926
- h.className = "ds-component-wrapper", h.dataset.componentId = c.id, a.applyStyles(h, c.position), e.appendChild(h);
927
- const l = a.toPx(c.position), n = Math.max(50, l.height - o);
928
- d.push(this.renderComponent(h, c, n));
929
- }), Promise.all(d).catch(() => {
962
+ const s = e.clientWidth || this.root.clientWidth || 800, r = t.map((d) => d.position), i = r.length ? Math.min(...r.map((d) => d.y)) : 0, a = new V(s, i);
963
+ e.style.height = `${V.totalHeight(r)}px`, e.innerHTML = "";
964
+ const o = 36, l = [];
965
+ t.forEach((d) => {
966
+ var p, b, x;
967
+ const f = document.createElement("div");
968
+ if (f.className = "ds-component-wrapper", f.dataset.componentId = d.id, a.applyStyles(f, d.position), !this.opts.hideBackground) {
969
+ const c = ((b = (p = d.properties) == null ? void 0 : p.styleConfig) == null ? void 0 : b.backgroundColor) || ((x = d.properties) == null ? void 0 : x.backgroundColor);
970
+ c && (f.style.background = c);
971
+ }
972
+ e.appendChild(f);
973
+ const h = a.toPx(d.position), n = Math.max(50, h.height - o);
974
+ l.push(
975
+ this.renderComponent(f, d, n).catch((c) => {
976
+ console.error(`[Deepspot SDK] Failed to render component ${d.id} (${d.type}):`, c), f.innerHTML = `<div style="padding:8px;color:#ef4444;font-size:12px;">⚠ ${d.type} render error</div>`;
977
+ })
978
+ );
979
+ }), Promise.all(l).catch(() => {
930
980
  });
931
981
  }
982
+ // ── Component renderer switch ─────────────────────────────────────────────
932
983
  async renderComponent(e, t, s) {
933
- var a, o;
984
+ var a, o, l, d, f, h, n, p, b, x, c, u, y, T, $, I, C, R, L, P, O, H, M, N, K, q, B, G, W, U, Y, _, J, X, Z;
934
985
  const r = this.renderData.data[t.id] || [], i = this.opts.theme;
935
986
  switch (t.type) {
936
987
  case "bar":
937
988
  case "line":
938
989
  case "pie":
939
990
  case "donut":
940
- case "area": {
941
- const d = new R(e);
942
- await d.render(t, r, i, s), this.chartRenderers.set(t.id, d);
991
+ case "area":
992
+ case "scatter":
993
+ case "stacked-bar": {
994
+ const v = new se(e);
995
+ await v.render(t, r, i, s), this.chartRenderers.set(t.id, v);
943
996
  break;
944
997
  }
945
998
  case "table": {
946
- const d = this.opts.onFetchTablePage ? (c, h) => this.opts.onFetchTablePage(t.id, c, h) : void 0;
947
- this.tableRenderer.render(e, t, r, d);
999
+ const v = this.opts.onFetchTablePage ? (m, k) => this.opts.onFetchTablePage(t.id, m, k) : void 0;
1000
+ this.tableRenderer.render(e, t, r, v);
948
1001
  break;
949
1002
  }
950
1003
  case "number-card":
951
1004
  this.cardRenderer.render(e, t, r);
952
1005
  break;
1006
+ case "text-heading": {
1007
+ if (this.opts.hideText) break;
1008
+ const v = ((o = (a = t.properties) == null ? void 0 : a.data) == null ? void 0 : o.dataContent) || ((l = t.properties) == null ? void 0 : l.content) || t.title || "", m = ((d = t.properties) == null ? void 0 : d.styleConfig) || {}, k = this.scToInlineStyle(m), g = this.opts.hideBackground ? {} : this.parseTwColor((h = (f = t.properties) == null ? void 0 : f.color) != null ? h : ""), S = [[
1009
+ g.bg ? `background:${g.bg}` : "",
1010
+ g.text ? `color:${g.text}` : ""
1011
+ ].filter(Boolean).join(";"), k].filter(Boolean).join(";");
1012
+ e.innerHTML = `<div class="ds-text-heading" style="${S}">${v}</div>`;
1013
+ break;
1014
+ }
1015
+ case "text-subheading": {
1016
+ if (this.opts.hideText) break;
1017
+ const v = ((p = (n = t.properties) == null ? void 0 : n.data) == null ? void 0 : p.dataContent) || ((b = t.properties) == null ? void 0 : b.content) || t.title || "", m = ((x = t.properties) == null ? void 0 : x.styleConfig) || {}, k = this.scToInlineStyle(m), g = this.opts.hideBackground ? {} : this.parseTwColor((u = (c = t.properties) == null ? void 0 : c.color) != null ? u : ""), S = [[
1018
+ g.bg ? `background:${g.bg}` : "",
1019
+ g.text ? `color:${g.text}` : ""
1020
+ ].filter(Boolean).join(";"), k].filter(Boolean).join(";");
1021
+ e.innerHTML = `<div class="ds-text-subheading" style="${S}">${v}</div>`;
1022
+ break;
1023
+ }
1024
+ case "text-body": {
1025
+ if (this.opts.hideText) break;
1026
+ const v = ((T = (y = t.properties) == null ? void 0 : y.data) == null ? void 0 : T.dataContent) || (($ = t.properties) == null ? void 0 : $.content) || "", m = ((I = t.properties) == null ? void 0 : I.styleConfig) || {}, k = this.scToInlineStyle(m), g = this.opts.hideBackground ? {} : this.parseTwColor((R = (C = t.properties) == null ? void 0 : C.color) != null ? R : ""), S = [[
1027
+ g.bg ? `background:${g.bg}` : "",
1028
+ g.text ? `color:${g.text}` : ""
1029
+ ].filter(Boolean).join(";"), k].filter(Boolean).join(";");
1030
+ e.innerHTML = `<div class="ds-text-body" style="${S}">${v}</div>`;
1031
+ break;
1032
+ }
1033
+ case "text-box": {
1034
+ if (this.opts.hideText) break;
1035
+ const v = ((P = (L = t.properties) == null ? void 0 : L.data) == null ? void 0 : P.dataContent) || ((O = t.properties) == null ? void 0 : O.content) || "", m = ((H = t.properties) == null ? void 0 : H.styleConfig) || {}, k = this.scToInlineStyle(m), g = this.opts.hideBackground ? {} : this.parseTwColor((N = (M = t.properties) == null ? void 0 : M.color) != null ? N : ""), S = [[
1036
+ g.bg ? `background:${g.bg}` : "",
1037
+ g.text ? `color:${g.text}` : ""
1038
+ ].filter(Boolean).join(";"), k].filter(Boolean).join(";");
1039
+ e.innerHTML = `<div class="ds-text-box" style="${S}">${v}</div>`;
1040
+ break;
1041
+ }
953
1042
  case "text": {
954
- const d = Object.entries(((a = t.properties) == null ? void 0 : a.style) || {}).map(([c, h]) => `${c}:${h}`).join(";");
955
- e.innerHTML = `<div style="${d};padding:8px;">${((o = t.properties) == null ? void 0 : o.content) || ""}</div>`;
1043
+ if (this.opts.hideText) break;
1044
+ const v = ((q = (K = t.properties) == null ? void 0 : K.data) == null ? void 0 : q.dataContent) || ((B = t.properties) == null ? void 0 : B.content) || "", m = ((G = t.properties) == null ? void 0 : G.styleConfig) || {}, k = this.scToInlineStyle(m), g = this.opts.hideBackground ? {} : this.parseTwColor((U = (W = t.properties) == null ? void 0 : W.color) != null ? U : ""), S = [[
1045
+ g.bg ? `background:${g.bg}` : "",
1046
+ g.text ? `color:${g.text}` : ""
1047
+ ].filter(Boolean).join(";"), k].filter(Boolean).join(";");
1048
+ e.innerHTML = `<div class="ds-text-body" style="${S}">${v}</div>`;
1049
+ break;
1050
+ }
1051
+ case "header": {
1052
+ if (this.opts.hideHeader) break;
1053
+ const v = ((_ = (Y = t.properties) == null ? void 0 : Y.data) == null ? void 0 : _.dataContent) || ((J = t.properties) == null ? void 0 : J.content) || t.title || "", m = ((X = t.properties) == null ? void 0 : X.styleConfig) || {}, k = !this.opts.hideBackground && m.backgroundColor ? `background:${m.backgroundColor};` : "", g = m.color ? `color:${m.color};` : m.textColor ? `color:${m.textColor};` : "";
1054
+ e.innerHTML = `
1055
+ <div class="ds-header-component" style="${k}${g}">
1056
+ <div class="ds-header-content">${v}</div>
1057
+ </div>`;
1058
+ break;
1059
+ }
1060
+ case "section": {
1061
+ const v = ((Z = t.properties) == null ? void 0 : Z.styleConfig) || {}, m = !this.opts.hideBackground && v.backgroundColor ? `background:${v.backgroundColor};` : "";
1062
+ e.innerHTML = `
1063
+ <div class="ds-section-wrapper" style="${m}">
1064
+ ${t.title ? `<div class="ds-section-title">${t.title}</div>` : ""}
1065
+ </div>`;
956
1066
  break;
957
1067
  }
958
1068
  }
@@ -967,14 +1077,86 @@ class z {
967
1077
  e && (e.style.display = "none"), t && (t.style.opacity = "1");
968
1078
  }
969
1079
  // ── Helpers ───────────────────────────────────────────────────────────────
1080
+ /**
1081
+ * Convert a styleConfig object to an inline CSS string.
1082
+ * Maps camelCase keys (e.g. fontSize) to kebab-case CSS properties.
1083
+ * Skips backgroundColor — that is applied to the wrapper div separately
1084
+ * (so it can support CSS gradients via `background` shorthand).
1085
+ */
1086
+ scToInlineStyle(e) {
1087
+ const t = /* @__PURE__ */ new Set(["backgroundColor"]), s = (r) => r.replace(/([A-Z])/g, "-$1").toLowerCase();
1088
+ return Object.entries(e).filter(([r, i]) => !t.has(r) && i != null && i !== "").map(([r, i]) => `${s(r)}:${i}`).join(";");
1089
+ }
1090
+ /**
1091
+ * Parse a Tailwind utility class string (e.g. "bg-violet-100 text-violet-600")
1092
+ * into plain CSS hex values. Used for text components whose builder color
1093
+ * is stored as Tailwind class names rather than raw CSS.
1094
+ */
1095
+ parseTwColor(e) {
1096
+ if (!e) return {};
1097
+ const t = {};
1098
+ for (const s of e.split(/\s+/)) {
1099
+ if (!s) continue;
1100
+ if (s === "bg-white") {
1101
+ t.bg = "#ffffff";
1102
+ continue;
1103
+ }
1104
+ if (s === "bg-black") {
1105
+ t.bg = "#000000";
1106
+ continue;
1107
+ }
1108
+ if (s === "bg-transparent") {
1109
+ t.bg = "transparent";
1110
+ continue;
1111
+ }
1112
+ if (s === "text-white") {
1113
+ t.text = "#ffffff";
1114
+ continue;
1115
+ }
1116
+ if (s === "text-black") {
1117
+ t.text = "#000000";
1118
+ continue;
1119
+ }
1120
+ const r = /^(bg|text)-([a-z]+)-(\d+)$/.exec(s);
1121
+ if (!r) continue;
1122
+ const i = A.TW_PALETTE[r[2]], a = i == null ? void 0 : i[Number(r[3])];
1123
+ a && (r[1] === "bg" && (t.bg = a), r[1] === "text" && (t.text = a));
1124
+ }
1125
+ return t;
1126
+ }
970
1127
  getTabsForPage(e) {
971
1128
  var t, s;
972
1129
  return (s = (t = this.renderData.dashboard.pages.find((r) => r.pageId === e)) == null ? void 0 : t.tabs) != null ? s : [];
973
1130
  }
974
- }
975
- class O {
1131
+ };
1132
+ A.TW_PALETTE = {
1133
+ slate: { 50: "#f8fafc", 100: "#f1f5f9", 200: "#e2e8f0", 300: "#cbd5e1", 400: "#94a3b8", 500: "#64748b", 600: "#475569", 700: "#334155", 800: "#1e293b", 900: "#0f172a" },
1134
+ gray: { 50: "#f9fafb", 100: "#f3f4f6", 200: "#e5e7eb", 300: "#d1d5db", 400: "#9ca3af", 500: "#6b7280", 600: "#4b5563", 700: "#374151", 800: "#1f2937", 900: "#111827" },
1135
+ zinc: { 50: "#fafafa", 100: "#f4f4f5", 200: "#e4e4e7", 300: "#d4d4d8", 400: "#a1a1aa", 500: "#71717a", 600: "#52525b", 700: "#3f3f46", 800: "#27272a", 900: "#18181b" },
1136
+ neutral: { 50: "#fafafa", 100: "#f5f5f5", 200: "#e5e5e5", 300: "#d4d4d4", 400: "#a3a3a3", 500: "#737373", 600: "#525252", 700: "#404040", 800: "#262626", 900: "#171717" },
1137
+ stone: { 50: "#fafaf9", 100: "#f5f5f4", 200: "#e7e5e4", 300: "#d6d3d1", 400: "#a8a29e", 500: "#78716c", 600: "#57534e", 700: "#44403c", 800: "#292524", 900: "#1c1917" },
1138
+ red: { 50: "#fef2f2", 100: "#fee2e2", 200: "#fecaca", 300: "#fca5a5", 400: "#f87171", 500: "#ef4444", 600: "#dc2626", 700: "#b91c1c", 800: "#991b1b", 900: "#7f1d1d" },
1139
+ orange: { 50: "#fff7ed", 100: "#ffedd5", 200: "#fed7aa", 300: "#fdba74", 400: "#fb923c", 500: "#f97316", 600: "#ea580c", 700: "#c2410c", 800: "#9a3412", 900: "#7c2d12" },
1140
+ amber: { 50: "#fffbeb", 100: "#fef3c7", 200: "#fde68a", 300: "#fcd34d", 400: "#fbbf24", 500: "#f59e0b", 600: "#d97706", 700: "#b45309", 800: "#92400e", 900: "#78350f" },
1141
+ yellow: { 50: "#fefce8", 100: "#fef9c3", 200: "#fef08a", 300: "#fde047", 400: "#facc15", 500: "#eab308", 600: "#ca8a04", 700: "#a16207", 800: "#854d0e", 900: "#713f12" },
1142
+ lime: { 50: "#f7fee7", 100: "#ecfccb", 200: "#d9f99d", 300: "#bef264", 400: "#a3e635", 500: "#84cc16", 600: "#65a30d", 700: "#4d7c0f", 800: "#3f6212", 900: "#365314" },
1143
+ green: { 50: "#f0fdf4", 100: "#dcfce7", 200: "#bbf7d0", 300: "#86efac", 400: "#4ade80", 500: "#22c55e", 600: "#16a34a", 700: "#15803d", 800: "#166534", 900: "#14532d" },
1144
+ emerald: { 50: "#ecfdf5", 100: "#d1fae5", 200: "#a7f3d0", 300: "#6ee7b7", 400: "#34d399", 500: "#10b981", 600: "#059669", 700: "#047857", 800: "#065f46", 900: "#064e3b" },
1145
+ teal: { 50: "#f0fdfa", 100: "#ccfbf1", 200: "#99f6e4", 300: "#5eead4", 400: "#2dd4bf", 500: "#14b8a6", 600: "#0d9488", 700: "#0f766e", 800: "#115e59", 900: "#134e4a" },
1146
+ cyan: { 50: "#ecfeff", 100: "#cffafe", 200: "#a5f3fc", 300: "#67e8f9", 400: "#22d3ee", 500: "#06b6d4", 600: "#0891b2", 700: "#0e7490", 800: "#155e75", 900: "#164e63" },
1147
+ sky: { 50: "#f0f9ff", 100: "#e0f2fe", 200: "#bae6fd", 300: "#7dd3fc", 400: "#38bdf8", 500: "#0ea5e9", 600: "#0284c7", 700: "#0369a1", 800: "#075985", 900: "#0c4a6e" },
1148
+ blue: { 50: "#eff6ff", 100: "#dbeafe", 200: "#bfdbfe", 300: "#93c5fd", 400: "#60a5fa", 500: "#3b82f6", 600: "#2563eb", 700: "#1d4ed8", 800: "#1e40af", 900: "#1e3a8a" },
1149
+ indigo: { 50: "#eef2ff", 100: "#e0e7ff", 200: "#c7d2fe", 300: "#a5b4fc", 400: "#818cf8", 500: "#6366f1", 600: "#4f46e5", 700: "#4338ca", 800: "#3730a3", 900: "#312e81" },
1150
+ violet: { 50: "#f5f3ff", 100: "#ede9fe", 200: "#ddd6fe", 300: "#c4b5fd", 400: "#a78bfa", 500: "#8b5cf6", 600: "#7c3aed", 700: "#6d28d9", 800: "#5b21b6", 900: "#4c1d95" },
1151
+ purple: { 50: "#faf5ff", 100: "#f3e8ff", 200: "#e9d5ff", 300: "#d8b4fe", 400: "#c084fc", 500: "#a855f7", 600: "#9333ea", 700: "#7e22ce", 800: "#6b21a8", 900: "#581c87" },
1152
+ fuchsia: { 50: "#fdf4ff", 100: "#fae8ff", 200: "#f5d0fe", 300: "#f0abfc", 400: "#e879f9", 500: "#d946ef", 600: "#c026d3", 700: "#a21caf", 800: "#86198f", 900: "#701a75" },
1153
+ pink: { 50: "#fdf2f8", 100: "#fce7f3", 200: "#fbcfe8", 300: "#f9a8d4", 400: "#f472b6", 500: "#ec4899", 600: "#db2777", 700: "#be185d", 800: "#9d174d", 900: "#831843" },
1154
+ rose: { 50: "#fff1f2", 100: "#ffe4e6", 200: "#fecdd3", 300: "#fda4af", 400: "#fb7185", 500: "#f43f5e", 600: "#e11d48", 700: "#be123c", 800: "#9f1239", 900: "#881337" }
1155
+ };
1156
+ let z = A;
1157
+ class le {
976
1158
  constructor(e, t) {
977
- this.chartRenderer = null, this.tableRenderer = new L(), this.cardRenderer = new C(), this.root = e, this.theme = t;
1159
+ this.chartRenderer = null, this.tableRenderer = new re(), this.cardRenderer = new ie(), this.root = e, this.theme = t;
978
1160
  }
979
1161
  render(e, t) {
980
1162
  const s = e.components[0];
@@ -1020,7 +1202,7 @@ class O {
1020
1202
  case "pie":
1021
1203
  case "donut":
1022
1204
  case "area":
1023
- (s = this.chartRenderer) == null || s.destroy(), this.chartRenderer = new R(this.root), this.chartRenderer.render(e, t, this.theme);
1205
+ (s = this.chartRenderer) == null || s.destroy(), this.chartRenderer = new se(this.root), this.chartRenderer.render(e, t, this.theme);
1024
1206
  break;
1025
1207
  case "table":
1026
1208
  this.tableRenderer.render(this.root, e, t);
@@ -1033,12 +1215,12 @@ class O {
1033
1215
  }
1034
1216
  }
1035
1217
  }
1036
- let I = !1;
1037
- function j() {
1038
- if (!(I || typeof document == "undefined")) {
1039
- I = !0;
1218
+ let ee = !1;
1219
+ function ce() {
1220
+ if (!(ee || typeof document == "undefined")) {
1221
+ ee = !0;
1040
1222
  try {
1041
- const u = `/* ─────────────────────────────────────────────────────────────────────────────
1223
+ const w = `/* ─────────────────────────────────────────────────────────────────────────────
1042
1224
  Deepspot SDK — Base Embed Styles
1043
1225
  Injected once into the host page's <head> by the SDK.
1044
1226
  All selectors are scoped under .ds-embed-* to avoid leaking into host styles.
@@ -1063,15 +1245,18 @@ function j() {
1063
1245
  height: 100%;
1064
1246
  overflow: auto;
1065
1247
  position: relative;
1248
+ /* Default white background — overridden by page backgroundColor from publish page */
1249
+ background: #ffffff;
1250
+ color: #111827;
1066
1251
  }
1067
1252
 
1068
1253
  .ds-embed-root.ds-theme-light {
1069
- background: #ffffff;
1254
+ /* No forced background — let component styleConfig backgrounds show through */
1070
1255
  color: #111827;
1071
1256
  }
1072
1257
 
1073
1258
  .ds-embed-root.ds-theme-dark {
1074
- background: #0f172a;
1259
+ /* No forced background — let component styleConfig backgrounds show through */
1075
1260
  color: #f1f5f9;
1076
1261
  }
1077
1262
 
@@ -1646,6 +1831,179 @@ function j() {
1646
1831
  color: #f1f5f9;
1647
1832
  }
1648
1833
 
1834
+ /* ── v2: Text / content components ────────────────────────────────────────── */
1835
+
1836
+ .ds-text-heading {
1837
+ width: 100%;
1838
+ height: 100%;
1839
+ display: flex;
1840
+ flex-direction: column;
1841
+ justify-content: center;
1842
+ padding: 8px 12px;
1843
+ font-size: 20px;
1844
+ font-weight: 700;
1845
+ color: #111827;
1846
+ line-height: 1.3;
1847
+ overflow: hidden;
1848
+ }
1849
+
1850
+ .ds-theme-dark .ds-text-heading {
1851
+ color: #f1f5f9;
1852
+ }
1853
+
1854
+ .ds-text-subheading {
1855
+ width: 100%;
1856
+ height: 100%;
1857
+ display: flex;
1858
+ flex-direction: column;
1859
+ justify-content: center;
1860
+ padding: 6px 12px;
1861
+ font-size: 15px;
1862
+ font-weight: 600;
1863
+ color: #374151;
1864
+ line-height: 1.4;
1865
+ overflow: hidden;
1866
+ }
1867
+
1868
+ .ds-theme-dark .ds-text-subheading {
1869
+ color: #cbd5e1;
1870
+ }
1871
+
1872
+ .ds-text-body {
1873
+ width: 100%;
1874
+ height: 100%;
1875
+ padding: 8px 12px;
1876
+ font-size: 14px;
1877
+ color: #374151;
1878
+ line-height: 1.6;
1879
+ overflow: auto;
1880
+ }
1881
+
1882
+ .ds-theme-dark .ds-text-body {
1883
+ color: #94a3b8;
1884
+ }
1885
+
1886
+ .ds-text-box {
1887
+ width: 100%;
1888
+ height: 100%;
1889
+ padding: 10px 14px;
1890
+ font-size: 13px;
1891
+ color: #374151;
1892
+ line-height: 1.6;
1893
+ border: 1px solid #e5e7eb;
1894
+ border-radius: 8px;
1895
+ background: #f9fafb;
1896
+ overflow: auto;
1897
+ }
1898
+
1899
+ .ds-theme-dark .ds-text-box {
1900
+ color: #cbd5e1;
1901
+ border-color: #334155;
1902
+ background: #1e293b;
1903
+ }
1904
+
1905
+ /* ── v2: Header component ──────────────────────────────────────────────────── */
1906
+
1907
+ .ds-header-component {
1908
+ width: 100%;
1909
+ height: 100%;
1910
+ display: flex;
1911
+ align-items: center;
1912
+ padding: 12px 20px;
1913
+ background: #f3f4f6;
1914
+ border-bottom: 1px solid #e5e7eb;
1915
+ overflow: hidden;
1916
+ }
1917
+
1918
+ .ds-theme-dark .ds-header-component {
1919
+ background: #1e293b;
1920
+ border-bottom-color: #334155;
1921
+ }
1922
+
1923
+ .ds-header-content {
1924
+ font-size: 18px;
1925
+ font-weight: 700;
1926
+ color: #111827;
1927
+ white-space: nowrap;
1928
+ overflow: hidden;
1929
+ text-overflow: ellipsis;
1930
+ }
1931
+
1932
+ .ds-theme-dark .ds-header-content {
1933
+ color: #f1f5f9;
1934
+ }
1935
+
1936
+ /* ── v2: Section container ─────────────────────────────────────────────────── */
1937
+
1938
+ .ds-section-wrapper {
1939
+ width: 100%;
1940
+ height: 100%;
1941
+ border: 1px solid #e5e7eb;
1942
+ border-radius: 10px;
1943
+ background: #f9fafb;
1944
+ overflow: hidden;
1945
+ }
1946
+
1947
+ .ds-theme-dark .ds-section-wrapper {
1948
+ border-color: #334155;
1949
+ background: #1e293b;
1950
+ }
1951
+
1952
+ .ds-section-title {
1953
+ padding: 8px 14px;
1954
+ font-size: 12px;
1955
+ font-weight: 600;
1956
+ text-transform: uppercase;
1957
+ letter-spacing: 0.05em;
1958
+ color: #6b7280;
1959
+ border-bottom: 1px solid #e5e7eb;
1960
+ }
1961
+
1962
+ .ds-theme-dark .ds-section-title {
1963
+ color: #94a3b8;
1964
+ border-bottom-color: #334155;
1965
+ }
1966
+
1967
+ /* ── v2: Inline filter (selection-filter placed in-grid) ───────────────────── */
1968
+
1969
+ .ds-inline-filter {
1970
+ width: 100%;
1971
+ height: 100%;
1972
+ display: flex;
1973
+ flex-direction: column;
1974
+ justify-content: center;
1975
+ gap: 4px;
1976
+ padding: 6px 10px;
1977
+ }
1978
+
1979
+ .ds-inline-filter-select,
1980
+ .ds-inline-filter-input {
1981
+ width: 100%;
1982
+ height: 34px;
1983
+ padding: 0 10px;
1984
+ border: 1px solid #d1d5db;
1985
+ border-radius: 6px;
1986
+ font-size: 13px;
1987
+ background: #ffffff;
1988
+ color: #111827;
1989
+ cursor: pointer;
1990
+ outline: none;
1991
+ transition: border-color 0.15s, box-shadow 0.15s;
1992
+ }
1993
+
1994
+ .ds-inline-filter-select:focus,
1995
+ .ds-inline-filter-input:focus {
1996
+ border-color: #6366f1;
1997
+ box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
1998
+ }
1999
+
2000
+ .ds-theme-dark .ds-inline-filter-select,
2001
+ .ds-theme-dark .ds-inline-filter-input {
2002
+ background: #1e293b;
2003
+ border-color: #334155;
2004
+ color: #f1f5f9;
2005
+ }
2006
+
1649
2007
  /* ── Export toolbar ────────────────────────────────────────────────────────── */
1650
2008
  .ds-toolbar {
1651
2009
  display: flex;
@@ -1685,42 +2043,42 @@ function j() {
1685
2043
  background: #0f172a;
1686
2044
  }
1687
2045
  `, e = document.createElement("style");
1688
- e.id = "deepspot-sdk-styles", e.textContent = u, document.head.appendChild(e);
1689
- } catch (u) {
2046
+ e.id = "deepspot-sdk-styles", e.textContent = w, document.head.appendChild(e);
2047
+ } catch (w) {
1690
2048
  }
1691
2049
  }
1692
2050
  }
1693
- function P(u) {
1694
- if (typeof u == "string") {
1695
- const e = document.querySelector(u);
1696
- if (!e) throw new Error(`Deepspot SDK: container "${u}" not found in DOM`);
2051
+ function te(w) {
2052
+ if (typeof w == "string") {
2053
+ const e = document.querySelector(w);
2054
+ if (!e) throw new Error(`Deepspot SDK: container "${w}" not found in DOM`);
1697
2055
  return e;
1698
2056
  }
1699
- return u;
2057
+ return w;
1700
2058
  }
1701
- class M {
2059
+ class he {
1702
2060
  constructor(e) {
1703
2061
  if (!e.apiKey) throw new Error("Deepspot SDK: apiKey is required");
1704
2062
  if (!e.baseUrl) throw new Error("Deepspot SDK: baseUrl is required");
1705
- this.apiClient = new F(e.baseUrl, e.apiKey), j();
2063
+ this.apiClient = new ae(e.baseUrl, e.apiKey), ce();
1706
2064
  }
1707
2065
  // ── Embed full dashboard ────────────────────────────────────────────────────
1708
2066
  async embedDashboard(e) {
1709
- var a, o, d, c, h;
1710
- const t = P(e.container), s = (a = e.embedLevel) != null ? a : "dashboard", r = (o = e.theme) != null ? o : "light";
2067
+ var a, o, l, d, f, h, n, p, b, x;
2068
+ const t = te(e.container), s = (a = e.embedLevel) != null ? a : "dashboard", r = (o = e.theme) != null ? o : "light";
1711
2069
  t.style.height = e.height || "600px", t.style.display = "block";
1712
2070
  const i = this.createRoot(t, r);
1713
2071
  this.showLoading(i);
1714
2072
  try {
1715
- const l = await this.apiClient.getEmbedToken({
2073
+ const c = await this.apiClient.getEmbedToken({
1716
2074
  dashboardId: e.dashboardId,
1717
2075
  embedType: "dashboard",
1718
2076
  embedLevel: s,
1719
2077
  userId: e.userId,
1720
2078
  tenantId: e.tenantId
1721
- }), n = await this.apiClient.getDashboardRender(
2079
+ }), u = await this.apiClient.getDashboardRender(
1722
2080
  e.dashboardId,
1723
- l,
2081
+ c,
1724
2082
  {
1725
2083
  embedLevel: s,
1726
2084
  pageId: e.pageId,
@@ -1728,57 +2086,64 @@ class M {
1728
2086
  filters: e.filters || {}
1729
2087
  }
1730
2088
  );
1731
- let b;
1732
- const p = new z(i, {
2089
+ let y;
2090
+ const T = new z(i, {
1733
2091
  embedLevel: s,
1734
2092
  theme: r,
1735
- hideFilters: (d = e.hideFilters) != null ? d : !1,
1736
- hideExport: (c = e.hideExport) != null ? c : !1,
2093
+ // v1 backward compat (hideFilters hideGlobalFilters)
2094
+ hideFilters: (l = e.hideGlobalFilters) != null ? l : !1,
2095
+ hideExport: (d = e.hideExport) != null ? d : !1,
2096
+ // v2 visibility
2097
+ hideGlobalFilters: (f = e.hideGlobalFilters) != null ? f : !1,
2098
+ hideInlineFilters: (h = e.hideInlineFilters) != null ? h : !1,
2099
+ hideText: (n = e.hideText) != null ? n : !1,
2100
+ hideHeader: (p = e.hideHeader) != null ? p : !1,
2101
+ hideBackground: (b = e.hideBackground) != null ? b : !1,
1737
2102
  initialFilters: e.filters || {},
1738
2103
  onFilterChange: e.onFilterChange,
1739
2104
  onReady: e.onReady,
1740
- onFetchFilterOptions: (m) => this.apiClient.getFilterOptions(e.dashboardId, m, l),
1741
- onFetchTablePage: (m, f, g) => this.apiClient.getTablePage(e.dashboardId, m, f, g, l),
1742
- onTabSwitch: async (m, f) => {
1743
- var g, y, v;
1744
- (g = e.onTabSwitch) == null || g.call(e, m, f);
2105
+ onFetchFilterOptions: ($) => this.apiClient.getFilterOptions(e.dashboardId, $, c),
2106
+ onFetchTablePage: ($, I, C) => this.apiClient.getTablePage(e.dashboardId, $, I, C, c),
2107
+ onTabSwitch: async ($, I) => {
2108
+ var C, R, L;
2109
+ (C = e.onTabSwitch) == null || C.call(e, $, I);
1745
2110
  try {
1746
- const x = await this.apiClient.getDashboardRender(
2111
+ const P = await this.apiClient.getDashboardRender(
1747
2112
  e.dashboardId,
1748
- l,
2113
+ c,
1749
2114
  {
1750
2115
  embedLevel: s,
1751
- pageId: m,
1752
- tabId: f,
1753
- filters: (v = (y = b == null ? void 0 : b.getActiveFilters()) != null ? y : e.filters) != null ? v : {}
2116
+ pageId: $,
2117
+ tabId: I,
2118
+ filters: (L = (R = y == null ? void 0 : y.getActiveFilters()) != null ? R : e.filters) != null ? L : {}
1754
2119
  }
1755
2120
  );
1756
- p.update(x);
1757
- } catch (x) {
1758
- console.error("Deepspot SDK: tab fetch failed", x);
2121
+ T.update(P);
2122
+ } catch (P) {
2123
+ console.error("Deepspot SDK: tab fetch failed", P);
1759
2124
  }
1760
2125
  }
1761
2126
  });
1762
- return p.render(n), b = new $({
2127
+ return T.render(u), y = new Q({
1763
2128
  dashboardId: e.dashboardId,
1764
- token: l,
2129
+ token: c,
1765
2130
  embedType: "dashboard",
1766
2131
  embedLevel: s,
1767
- activePageId: n.activePage,
1768
- activeTabId: n.activeTab,
2132
+ activePageId: u.activePage,
2133
+ activeTabId: u.activeTab,
1769
2134
  activeFilters: e.filters || {},
1770
2135
  apiClient: this.apiClient,
1771
- renderer: p,
2136
+ renderer: T,
1772
2137
  onFilterChange: e.onFilterChange
1773
- }), b;
1774
- } catch (l) {
1775
- throw this.showError(i, (l == null ? void 0 : l.message) || "Failed to load dashboard"), (h = e.onError) == null || h.call(e, (l == null ? void 0 : l.message) || "Failed to load dashboard"), l;
2138
+ }), y;
2139
+ } catch (c) {
2140
+ throw this.showError(i, (c == null ? void 0 : c.message) || "Failed to load dashboard"), (x = e.onError) == null || x.call(e, (c == null ? void 0 : c.message) || "Failed to load dashboard"), c;
1776
2141
  }
1777
2142
  }
1778
2143
  // ── Embed single report (component) ────────────────────────────────────────
1779
2144
  async embedReport(e) {
1780
2145
  var r;
1781
- const t = P(e.container);
2146
+ const t = te(e.container);
1782
2147
  t.style.height = e.height || "400px", t.style.display = "block";
1783
2148
  const s = this.createRoot(t, e.theme || "light");
1784
2149
  this.showLoading(s);
@@ -1794,8 +2159,8 @@ class M {
1794
2159
  e.componentId,
1795
2160
  i,
1796
2161
  { filters: e.filters || {} }
1797
- ), o = new O(s, e.theme || "light");
1798
- return o.render(a, e.onReady), new $({
2162
+ ), o = new le(s, e.theme || "light");
2163
+ return o.render(a, e.onReady), new Q({
1799
2164
  dashboardId: e.dashboardId,
1800
2165
  componentId: e.componentId,
1801
2166
  token: i,
@@ -1833,5 +2198,5 @@ class M {
1833
2198
  }
1834
2199
  }
1835
2200
  export {
1836
- M as DeepspotSDK
2201
+ he as DeepspotSDK
1837
2202
  };