drizzle-cube
Version:
Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.
15,832 lines • 582 kB
JavaScript
import { jsxs as o, jsx as e, Fragment as Oe } from "react/jsx-runtime";
import * as Wt from "react";
import wt, { useState as V, useRef as Ce, useEffect as ve, Component as zs, forwardRef as Hr, useMemo as ye, useImperativeHandle as zr, useCallback as F, memo as Ot, Suspense as Gs, lazy as Ws } from "react";
import { useCubeQuery as ts, useDebounce as rs, useFilterValues as ns, useResponsiveDashboard as Ys } from "../hooks.js";
import { u as Qt, l as Q, L as Js, v as Xt, y as wr, M as Vt, O as Ks, Q as Xs, U as Zs, V as ea, W as ta, X as ra, Y as na, Z as sa, _ as aa, $ as oa, a0 as ca, a1 as la, a2 as ia, a3 as da, a4 as ua, a5 as ma } from "./charts-BvLb1eub.js";
import { useScrollContainer as fa, ScrollContainerProvider as ss } from "../providers.js";
import { u as ha, i as as, L as Vr, b as Dr } from "./charts-BsXrHSCm.js";
import pa, { verticalCompactor as ga } from "react-grid-layout";
import { createPortal as ba } from "react-dom";
var Qr = /* @__PURE__ */ new Map(), ir = /* @__PURE__ */ new WeakMap(), ln = 0, xa;
function ya(t) {
return t ? (ir.has(t) || (ln += 1, ir.set(t, ln.toString())), ir.get(t)) : "0";
}
function va(t) {
return Object.keys(t).sort().filter(
(r) => t[r] !== void 0
).map((r) => `${r}_${r === "root" ? ya(t.root) : t[r]}`).toString();
}
function wa(t) {
const r = va(t);
let n = Qr.get(r);
if (!n) {
const s = /* @__PURE__ */ new Map();
let a;
const c = new IntersectionObserver((l) => {
l.forEach((u) => {
var d;
const f = u.isIntersecting && a.some((h) => u.intersectionRatio >= h);
t.trackVisibility && typeof u.isVisible > "u" && (u.isVisible = f), (d = s.get(u.target)) == null || d.forEach((h) => {
h(f, u);
});
});
}, t);
a = c.thresholds || (Array.isArray(t.threshold) ? t.threshold : [t.threshold || 0]), n = {
id: r,
observer: c,
elements: s
}, Qr.set(r, n);
}
return n;
}
function Na(t, r, n = {}, s = xa) {
if (typeof window.IntersectionObserver > "u" && s !== void 0) {
const d = t.getBoundingClientRect();
return r(s, {
isIntersecting: s,
target: t,
intersectionRatio: typeof n.threshold == "number" ? n.threshold : 0,
time: 0,
boundingClientRect: d,
intersectionRect: d,
rootBounds: d
}), () => {
};
}
const { id: a, observer: c, elements: l } = wa(n), u = l.get(t) || [];
return l.has(t) || l.set(t, u), u.push(r), c.observe(t), function() {
u.splice(u.indexOf(r), 1), u.length === 0 && (l.delete(t), c.unobserve(t)), l.size === 0 && (c.disconnect(), Qr.delete(a));
};
}
function Ca({
threshold: t,
delay: r,
trackVisibility: n,
rootMargin: s,
root: a,
triggerOnce: c,
skip: l,
initialInView: u,
fallbackInView: d,
onChange: f
} = {}) {
var h;
const [p, m] = Wt.useState(null), v = Wt.useRef(f), C = Wt.useRef(u), [_, b] = Wt.useState({
inView: !!u,
entry: void 0
});
v.current = f, Wt.useEffect(
() => {
if (C.current === void 0 && (C.current = u), l || !p) return;
let A;
return A = Na(
p,
(w, i) => {
const g = C.current;
C.current = w, !(g === void 0 && !w) && (b({
inView: w,
entry: i
}), v.current && v.current(w, i), i.isIntersecting && c && A && (A(), A = void 0));
},
{
root: a,
rootMargin: s,
threshold: t,
// @ts-expect-error
trackVisibility: n,
delay: r
},
d
), () => {
A && A();
};
},
// We break the rule here, because we aren't including the actual `threshold` variable
// eslint-disable-next-line react-hooks/exhaustive-deps
[
// If the threshold is an array, convert it to a string, so it won't change between renders.
Array.isArray(t) ? t.toString() : t,
p,
a,
s,
c,
l,
n,
d,
r
]
);
const R = (h = _.entry) == null ? void 0 : h.target, D = Wt.useRef(void 0);
!p && R && !c && !l && D.current !== R && (D.current = R, b({
inView: !!u,
entry: void 0
}), C.current = u);
const $ = [m, _.inView, _.entry];
return $.ref = $[0], $.inView = $[1], $.entry = $[2], $;
}
function os(t) {
return t.length > 0 && typeof t[0] == "object" && t[0] !== null && "__queryIndex" in t[0];
}
function ql(t) {
if (!os(t)) return [];
const r = /* @__PURE__ */ new Set();
for (const n of t) {
const s = n.__queryLabel;
typeof s == "string" && r.add(s);
}
return Array.from(r);
}
function Pl(t) {
if (!os(t)) return [];
const r = /* @__PURE__ */ new Set();
for (const n of t) {
const s = n.__queryIndex;
typeof s == "number" && r.add(s);
}
return Array.from(r).sort((n, s) => n - s);
}
function ka(t, r, n) {
const s = [];
return t.forEach((a, c) => {
const l = a.rawData(), u = n?.[c] || `Query ${c + 1}`;
l.forEach((d) => {
s.push({
...d,
__queryIndex: c,
__queryLabel: u
});
});
}), s;
}
function Da(t, r, n, s) {
const a = /* @__PURE__ */ new Map();
return t.forEach((c, l) => {
const u = c.rawData(), d = r[l].measures || [];
u.forEach((f) => {
const h = n.map((m) => String(f[m] ?? "")).join("|");
if (!a.has(h)) {
const m = {};
n.forEach((v) => {
m[v] = f[v];
}), a.set(h, m);
}
const p = a.get(h);
d.forEach((m) => {
m in p || (p[m] = f[m]);
}), l === 0 && Object.keys(f).forEach((m) => {
!n.includes(m) && !d.includes(m) && (m in p || (p[m] = f[m]));
});
});
}), Array.from(a.values()).sort((c, l) => {
const u = String(c[n[0]] ?? ""), d = String(l[n[0]] ?? "");
return u.localeCompare(d);
});
}
function Ta(t, r, n, s, a) {
return t.length === 0 ? [] : t.length === 1 ? t[0].rawData() : n === "merge" && s && s.length > 0 ? Da(t, r, s) : ka(t, r, a);
}
function jl(t, r) {
const n = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set();
return t.forEach((c) => {
c.measures?.forEach((l) => n.add(l)), c.dimensions?.forEach((l) => s.add(l)), c.timeDimensions?.forEach((l) => a.add(l.dimension));
}), {
measures: Array.from(n),
dimensions: Array.from(s),
timeDimensions: Array.from(a)
};
}
function Bl(t, r) {
if (t.measures && t.measures.length > 0) {
const n = t.measures[0], s = n.split(".");
return s.length > 1 ? s[s.length - 1] : n;
}
return `Query ${r + 1}`;
}
function Vl(t, r) {
const n = [];
return t.forEach((s, a) => {
[
...s.dimensions || [],
...s.timeDimensions?.map((l) => l.dimension) || []
].includes(r) || n.push(a);
}), {
isValid: n.length === 0,
missingInQueries: n
};
}
function cs(t, r = {}) {
const { cubeApi: n, batchCoordinator: s, enableBatching: a } = Qt(), [c, l] = V({
data: null,
resultSets: null,
isLoading: !1,
error: null,
errors: [],
queryId: null
}), u = Ce("");
return ve(() => {
if (!t || r.skip || t.queries.length === 0)
return;
const d = JSON.stringify(t);
if (d === u.current && !r.resetResultSetOnChange)
return;
u.current = d;
const f = `multi_${Date.now()}_${Math.random().toString(36).substring(7)}`;
l((p) => ({
data: r.resetResultSetOnChange ? null : p.data,
resultSets: r.resetResultSetOnChange ? null : p.resultSets,
isLoading: !0,
error: null,
errors: t.queries.map(() => null),
queryId: f
})), (a && s ? Promise.all(
t.queries.map((p) => s.register(p))
) : n.batchLoad(t.queries)).then((p) => {
l((m) => {
if (m.queryId !== f) return m;
const v = p.map((D) => D && "error" in D && D.error ? new Error(D.error) : null), C = v.find((D) => D !== null) || null, _ = p.filter((D, $) => !v[$]), b = t.queries.filter((D, $) => !v[$]);
return {
data: _.length > 0 ? Ta(
_,
b,
t.mergeStrategy,
t.mergeKeys,
t.queryLabels
) : [],
resultSets: p,
isLoading: !1,
error: C,
errors: v,
queryId: f
};
});
}).catch((p) => {
l((m) => {
if (m.queryId !== f) return m;
const v = p instanceof Error ? p : new Error(String(p));
return {
data: null,
resultSets: null,
isLoading: !1,
error: v,
// All queries failed with the same error
errors: t.queries.map(() => v),
queryId: f
};
});
});
}, [t, n, s, a, r.skip, r.resetResultSetOnChange]), c;
}
const Sa = Q("refresh");
class Aa extends zs {
constructor(r) {
super(r), this.state = {
hasError: !1,
error: null,
errorInfo: null
};
}
static getDerivedStateFromError(r) {
return {
hasError: !0,
error: r,
errorInfo: null
};
}
componentDidCatch(r, n) {
this.setState({
error: r,
errorInfo: n.componentStack || null
}), console.error("Chart Error Boundary caught a rendering error:", r, n);
}
handleReset = () => {
this.setState({
hasError: !1,
error: null,
errorInfo: null
});
};
render() {
return this.state.hasError ? this.props.fallback ? this.props.fallback : /* @__PURE__ */ o(
"div",
{
className: "flex flex-col items-center justify-center w-full h-full p-6 text-center border border-dashed rounded-lg",
style: { borderColor: "var(--dc-border)", backgroundColor: "var(--dc-surface)" },
children: [
/* @__PURE__ */ e("div", { className: "h-12 w-12 mb-4 text-dc-text-muted", children: "⚠️" }),
/* @__PURE__ */ e("h3", { className: "text-lg font-semibold mb-2 text-dc-text", children: this.props.portletTitle ? `Unable to render ${this.props.portletTitle}` : "Unable to render chart" }),
/* @__PURE__ */ e("p", { className: "text-sm text-dc-text-secondary mb-4 max-w-md", children: "There was an error rendering this chart component. The error details are shown below." }),
/* @__PURE__ */ e("div", { className: "w-full max-w-2xl mb-4", children: /* @__PURE__ */ o("div", { className: "bg-dc-surface-secondary rounded-lg p-3 text-left", children: [
/* @__PURE__ */ o("div", { className: "text-xs font-mono mb-2 text-dc-text", children: [
/* @__PURE__ */ e("strong", { children: "Error:" }),
" ",
this.state.error?.message
] }),
this.state.error?.name && /* @__PURE__ */ o("div", { className: "text-xs font-mono text-dc-text-secondary mb-2", children: [
/* @__PURE__ */ e("strong", { children: "Type:" }),
" ",
this.state.error.name
] }),
this.props.portletConfig && /* @__PURE__ */ o("details", { className: "text-xs font-mono text-dc-text-secondary mb-2", children: [
/* @__PURE__ */ e("summary", { className: "cursor-pointer", children: "Portlet Configuration" }),
/* @__PURE__ */ e(
"pre",
{
className: "mt-2 whitespace-pre-wrap p-2 rounded-sm overflow-auto max-h-32",
style: { backgroundColor: "rgba(var(--dc-primary-rgb), 0.1)" },
children: JSON.stringify(this.props.portletConfig, null, 2)
}
)
] }),
this.props.cubeQuery && /* @__PURE__ */ o("details", { className: "text-xs font-mono text-dc-text-secondary mb-2", children: [
/* @__PURE__ */ e("summary", { className: "cursor-pointer", children: "Cube Query" }),
/* @__PURE__ */ e(
"pre",
{
className: "mt-2 whitespace-pre-wrap p-2 rounded-sm overflow-auto max-h-32",
style: { backgroundColor: "#d1fae5" },
children: typeof this.props.cubeQuery == "string" ? JSON.stringify(JSON.parse(this.props.cubeQuery), null, 2) : JSON.stringify(this.props.cubeQuery, null, 2)
}
)
] }),
this.state.errorInfo && /* @__PURE__ */ o("details", { className: "text-xs font-mono text-dc-text-secondary", children: [
/* @__PURE__ */ e("summary", { className: "cursor-pointer", children: "Component Stack" }),
/* @__PURE__ */ e("pre", { className: "mt-2 whitespace-pre-wrap", children: this.state.errorInfo })
] })
] }) }),
/* @__PURE__ */ o(
"button",
{
onClick: this.handleReset,
className: "px-3 py-1 text-white rounded-sm text-sm hover:opacity-90 transition-opacity",
style: {
backgroundColor: "var(--dc-primary)"
},
children: [
/* @__PURE__ */ e(Sa, { style: { width: "16px", height: "16px", display: "inline", marginRight: "4px" } }),
"Try Again"
]
}
)
]
}
) : this.props.children;
}
}
function yr(t) {
return typeof t == "object" && t !== null && "queries" in t && Array.isArray(t.queries) && t.queries.length > 0;
}
const dn = [];
class Gr {
cache = /* @__PURE__ */ new Map();
maxSize = 100;
// Prevent unbounded growth
get(r) {
try {
const n = JSON.stringify(r);
return this.cache.get(n);
} catch {
return;
}
}
set(r, n) {
try {
const s = JSON.stringify(r);
if (this.cache.size >= this.maxSize) {
const a = this.cache.keys().next().value;
a && this.cache.delete(a);
}
this.cache.set(s, n);
} catch {
}
}
clear() {
this.cache.clear();
}
}
const un = new Gr(), mn = new Gr(), fn = new Gr();
function ls(t) {
if ("member" in t && "operator" in t) {
const r = t;
return ["set", "notSet", "isEmpty", "isNotEmpty"].includes(r.operator) || r.operator === "inDateRange" && r.dateRange ? !0 : !!(r.values && r.values.length > 0);
}
return "type" in t && "filters" in t ? t.filters.filter((s) => ls(s)).length > 0 : !1;
}
function Ea(t, r) {
if (!t || !t.length || !r || !r.length)
return dn;
const n = { dashboardFilters: t, filterMapping: r }, s = un.get(n);
if (s)
return s;
const a = t.filter((l) => r.includes(l.id)).filter((l) => ls(l.filter)).map((l) => l.filter), c = Object.freeze(a);
return un.set(n, c), c;
}
function is(t) {
if ("type" in t && "filters" in t) {
const r = t, n = r.filters.map(is);
return r.type === "and" ? { and: n } : { or: n };
}
return t;
}
function hn(t, r) {
if (!t || t.length === 0)
return r;
if (!r || r.length === 0)
return Object.freeze([...t]);
const n = { dashboardFilters: t, portletFilters: r }, s = mn.get(n);
if (s)
return s;
const c = [{
and: [...t, ...r].map(is)
}], l = Object.freeze(c);
return mn.set(n, l), l;
}
function _a(t) {
const r = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set();
return t.portlets.forEach((a) => {
try {
const c = JSON.parse(a.query);
c.measures && Array.isArray(c.measures) && c.measures.forEach((l) => r.add(l)), c.dimensions && Array.isArray(c.dimensions) && c.dimensions.forEach((l) => n.add(l)), c.timeDimensions && Array.isArray(c.timeDimensions) && c.timeDimensions.forEach((l) => {
l.dimension && s.add(l.dimension);
}), c.filters && ds(c.filters).forEach((l) => {
n.add(l);
});
} catch (c) {
console.warn("Failed to parse portlet query:", a.id, c);
}
}), { measures: r, dimensions: n, timeDimensions: s };
}
function ds(t) {
const r = [];
return t.forEach((n) => {
"member" in n ? r.push(n.member) : "type" in n && "filters" in n && r.push(...ds(n.filters));
}), [...new Set(r)];
}
function pn(t) {
if (t.dateRange)
return t.dateRange;
if (t.values && t.values.length > 0)
return t.values.length === 1 ? t.values[0] : t.values;
}
function gn(t, r, n) {
if (!n || n.length === 0 || !r || r.length === 0)
return n;
const s = { dashboardFilters: t, filterMapping: r, portletTimeDimensions: n }, a = fn.get(s);
if (a)
return a;
const c = t?.filter((p) => p.isUniversalTime && r.includes(p.id))?.filter((p) => {
if (!("member" in p.filter)) return !1;
const m = p.filter;
return pn(m) !== void 0;
});
if (!c || c.length === 0)
return n;
const u = c[0].filter, d = pn(u), f = n.map((p) => ({
...p,
dateRange: d
})), h = Object.freeze(f);
return fn.set(s, h), h;
}
const Tr = wt.memo(Hr(({
query: t,
chartType: r,
chartConfig: n,
displayConfig: s,
dashboardFilters: a,
dashboardFilterMapping: c,
eagerLoad: l = !1,
isVisible: u,
// Deprecated - visibility now handled internally via useInView
height: d = 300,
title: f,
colorPalette: h,
loadingComponent: p,
onDebugDataReady: m
}, v) => {
const [C, _] = V(0), b = Ce(m), R = fa(), { ref: D, inView: $ } = Ca({
root: R,
rootMargin: "500px",
// Start loading 500px before entering viewport (about half screen)
triggerOnce: !0,
// Once visible, stay "visible" (don't unload data)
initialInView: !1,
// Start as not visible, let observer determine actual state
skip: l
// Skip observation entirely if eagerLoad is true
}), A = l || $;
ve(() => {
b.current = m;
}, [m]);
const { config: w } = ha(r), i = w.skipQuery === !0, g = ye(() => a?.filter((B) => !B.isUniversalTime), [a]), { queryObject: x, multiQueryConfig: N } = ye(() => {
if (i)
return { queryObject: null, multiQueryConfig: null };
try {
const B = JSON.parse(t), se = Ea(g, c);
if (yr(B))
return { queryObject: null, multiQueryConfig: {
...B,
queries: B.queries.map((le) => ({
...le,
filters: hn(se, le.filters),
timeDimensions: gn(a, c, le.timeDimensions),
__refresh_counter: C
}))
} };
const Te = hn(se, B.filters), H = gn(
a,
c,
B.timeDimensions
);
return {
queryObject: {
...B,
filters: Te,
timeDimensions: H,
__refresh_counter: C
},
multiQueryConfig: null
};
} catch (B) {
return console.error("AnalyticsPortlet: Invalid query JSON:", B), { queryObject: null, multiQueryConfig: null };
}
}, [t, C, i, g, a, c]), S = N !== null, y = !x || i || !l && !A || S, M = !N || i || !l && !A, E = ts(x, {
skip: y,
resetResultSetOnChange: !0
}), T = cs(N, {
skip: M,
resetResultSetOnChange: !0
}), j = S ? null : E.resultSet, q = S ? T.isLoading : E.isLoading, I = S ? T.error : E.error, K = S ? T.data : null;
zr(v, () => ({
refresh: () => {
_((B) => B + 1);
}
}), []), ve(() => {
if (b.current && n && x && j && !I) {
const se = (() => {
switch (r) {
case "pie":
case "table":
return j.tablePivot();
default:
return j.rawData();
}
})();
se && b.current({
chartConfig: n || {},
displayConfig: s || {},
queryObject: x,
data: se,
chartType: r,
cacheInfo: j.cacheInfo?.()
});
}
}, [n, s, x, j, r, I]);
const U = !i && w.dropZones.some((B) => B.mandatory === !0);
if (!n && U)
return /* @__PURE__ */ e("div", { ref: D, className: "flex items-center justify-center w-full text-dc-text-muted", style: { height: d }, children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e("div", { className: "text-sm font-semibold mb-1", children: "Configuration Required" }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-secondary", children: "Please configure this chart" })
] }) });
if (!i && !l && !A)
return /* @__PURE__ */ e("div", { ref: D, className: "w-full h-full", style: { height: d }, children: /* @__PURE__ */ e("div", { className: "w-full h-full animate-pulse bg-dc-surface-secondary rounded", style: { minHeight: "100px" } }) });
if (!i) {
if (q || x && !j && !I)
return /* @__PURE__ */ e("div", { ref: D, className: "flex items-center justify-center w-full", style: { height: d }, children: p || /* @__PURE__ */ e(Js, { size: "md" }) });
if (I)
return /* @__PURE__ */ o("div", { ref: D, className: "p-4 border rounded-sm", style: { height: d, borderColor: "var(--dc-border)", backgroundColor: "var(--dc-surface)" }, children: [
/* @__PURE__ */ e("div", { className: "mb-2", children: /* @__PURE__ */ o("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ e("span", { className: "font-medium text-sm", style: { color: "var(--dc-text)" }, children: "⚠️ Query Error" }),
/* @__PURE__ */ e(
"button",
{
onClick: () => _((se) => se + 1),
className: "px-2 py-1 text-white rounded-sm text-xs",
style: { backgroundColor: "var(--dc-primary)" },
children: "Retry"
}
)
] }) }),
/* @__PURE__ */ e("div", { className: "mb-3", children: /* @__PURE__ */ e("div", { className: "text-xs p-2 rounded-sm border", style: { color: "var(--dc-text-secondary)", backgroundColor: "var(--dc-surface)", borderColor: "var(--dc-border)" }, children: I.message || I.toString() }) }),
/* @__PURE__ */ o("div", { className: "space-y-2 text-xs", children: [
/* @__PURE__ */ o("details", { children: [
/* @__PURE__ */ e("summary", { className: "cursor-pointer font-medium", style: { color: "var(--dc-text-secondary)" }, children: "Query (with filters applied)" }),
/* @__PURE__ */ e("pre", { className: "mt-1 p-2 rounded-sm text-xs overflow-auto max-h-20", style: { backgroundColor: "rgba(var(--dc-primary-rgb), 0.1)" }, children: x ? JSON.stringify(x, null, 2) : t })
] }),
/* @__PURE__ */ o("details", { children: [
/* @__PURE__ */ e("summary", { className: "cursor-pointer font-medium", style: { color: "var(--dc-text-secondary)" }, children: "Chart Config" }),
/* @__PURE__ */ e("pre", { className: "mt-1 p-2 rounded-sm text-xs overflow-auto max-h-20", style: { backgroundColor: "rgba(var(--dc-primary-rgb), 0.05)" }, children: JSON.stringify({
chartType: r,
chartConfig: n,
displayConfig: s
}, null, 2) })
] })
] })
] });
if (!(S ? K !== null && N !== null : j !== null && x !== null))
return /* @__PURE__ */ e("div", { ref: D, className: "flex items-center justify-center w-full text-dc-text-muted", style: { height: d }, children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e("div", { className: "text-sm font-semibold mb-1", children: "No data available" }),
/* @__PURE__ */ e("div", { className: "text-xs", children: "Invalid query or no results" })
] }) });
}
const De = (() => {
if (i)
return [];
if (S)
return K || [];
if (!j)
return [];
switch (r) {
case "pie":
case "table":
return j.tablePivot();
default:
return j.rawData();
}
})();
return /* @__PURE__ */ e("div", { ref: D, className: "w-full h-full", children: /* @__PURE__ */ e(
Aa,
{
portletTitle: f,
portletConfig: {
chartType: r,
chartConfig: n,
displayConfig: s,
height: d
},
cubeQuery: t,
children: /* @__PURE__ */ e("div", { className: "w-full h-full flex flex-col flex-1", style: { minHeight: "200px" }, children: (() => {
try {
const B = d;
return as(r) ? /* @__PURE__ */ e(
Vr,
{
chartType: r,
data: r === "markdown" ? [] : De,
chartConfig: n,
displayConfig: s,
queryObject: x ?? void 0,
height: B,
colorPalette: h,
fallback: /* @__PURE__ */ e(
"div",
{
className: "flex items-center justify-center w-full",
style: { height: typeof B == "number" ? `${B}px` : B },
children: /* @__PURE__ */ e("div", { className: "animate-pulse bg-dc-surface-secondary rounded w-full h-full min-h-[100px]" })
}
)
}
) : /* @__PURE__ */ e("div", { className: "flex items-center justify-center w-full", style: { height: d }, children: /* @__PURE__ */ o("div", { className: "text-center text-dc-text-muted", children: [
/* @__PURE__ */ e("div", { className: "text-sm font-semibold mb-1", children: "Unsupported chart type" }),
/* @__PURE__ */ e("div", { className: "text-xs", children: r })
] }) });
} catch (B) {
return console.error("Chart rendering error:", B), /* @__PURE__ */ e("div", { className: "flex items-center justify-center w-full text-dc-text-muted p-4", style: { height: d }, children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e("div", { className: "text-sm font-semibold mb-1", children: "Unable to render chart" }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-secondary", children: B instanceof Error ? B.message : "Unknown error" })
] }) });
}
})() })
}
) });
}));
Tr.displayName = "AnalyticsPortlet";
function Ra(t, { threshold: r = 20, debounceMs: n = 150, container: s } = {}) {
const [a, c] = V(!1), l = Ce();
return ve(() => {
const u = t.current;
if (!u) return;
const d = () => {
l.current && clearTimeout(l.current), l.current = window.setTimeout(() => {
const h = u.scrollTop > r;
c((p) => p !== h ? h : p);
}, n);
};
return u.addEventListener("scroll", d, { passive: !0 }), d(), () => {
u.removeEventListener("scroll", d), l.current && clearTimeout(l.current);
};
}, [r, n, s]), a;
}
function Ma(t, { threshold: r = 80, debounceMs: n = 100, containerRef: s, container: a } = {}) {
const [c, l] = V(!0), u = Ce(), d = Ce(!1);
return ve(() => {
const f = s?.current, h = () => {
const v = t.current;
v && (u.current && clearTimeout(u.current), u.current = window.setTimeout(() => {
const C = v.getBoundingClientRect();
if (f) {
const _ = f.getBoundingClientRect(), b = C.bottom > _.top + r;
b && (d.current = !0), l((R) => R !== b ? b : R);
} else {
const _ = C.bottom > r;
_ && (d.current = !0), l((b) => b !== _ ? _ : b);
}
}, n));
}, p = f || window;
p.addEventListener("scroll", h, { passive: !0 }), window.addEventListener("resize", h, { passive: !0 }), h();
const m = requestAnimationFrame(() => {
h();
});
return () => {
p.removeEventListener("scroll", h), window.removeEventListener("resize", h), cancelAnimationFrame(m), u.current && clearTimeout(u.current);
};
}, [t, s, r, n, a]), c;
}
let Nr = null, Zt = null;
async function Oa() {
if (!Nr)
return Zt || (Zt = (async () => {
try {
const t = await import("./core-CX7kEAYO.js"), r = await import("./javascript-DII1YQGr.js"), n = await Promise.resolve().then(() => yo), s = await Promise.resolve().then(() => xo);
t.default.registerLanguage("javascript", r.default), t.default.registerLanguage("sql", n.default), t.default.registerLanguage("json", s.default), Nr = t.default;
} catch (t) {
console.error("Failed to load syntax highlighter:", t), Zt = null;
}
})(), Zt);
}
async function $a() {
await Oa(), Nr && document.querySelectorAll("pre code").forEach((t) => {
t.classList.contains("hljs") || Nr.highlightElement(t);
});
}
function us({
chartConfig: t,
displayConfig: r,
queryObject: n,
data: s,
chartType: a,
cacheInfo: c
}) {
const [l, u] = V(!1);
return ve(() => {
const d = (f) => {
f.key === "Escape" && l && u(!1);
};
return document.addEventListener("keydown", d), () => document.removeEventListener("keydown", d);
}, [l]), ve(() => {
if (l) {
const d = setTimeout(() => {
$a().catch((f) => {
console.debug("Syntax highlighting not available:", f);
});
}, 10);
return () => clearTimeout(d);
}
}, [l]), l ? /* @__PURE__ */ e(
"div",
{
className: "absolute inset-0 bg-dc-surface border border-dc-border rounded-lg z-50 overflow-auto",
onClick: (d) => d.stopPropagation(),
children: /* @__PURE__ */ o("div", { className: "p-4 h-full flex flex-col", children: [
/* @__PURE__ */ o("div", { className: "flex justify-between items-center mb-4 shrink-0", children: [
/* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-dc-text", children: "Chart Debug Information" }),
/* @__PURE__ */ e(
"button",
{
onClick: () => u(!1),
className: "p-2 text-dc-text-muted hover:text-dc-text-secondary hover:bg-dc-surface-secondary rounded-sm",
children: /* @__PURE__ */ o(
"svg",
{
width: "16",
height: "16",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
children: [
/* @__PURE__ */ e("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
/* @__PURE__ */ e("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
]
}
)
}
)
] }),
/* @__PURE__ */ o("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-4 flex-1 overflow-auto", children: [
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Chart Type" }),
/* @__PURE__ */ e("div", { className: "bg-dc-surface-secondary p-2 rounded-sm text-sm font-mono border border-dc-border", children: a })
] }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Field Analysis" }),
/* @__PURE__ */ o("div", { className: "bg-dc-surface-secondary p-2 rounded-sm text-xs space-y-1 border border-dc-border", children: [
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("strong", { children: "xAxis:" }),
" ",
Array.isArray(t?.xAxis) ? `Array: [${t.xAxis.join(", ")}]` : `String: "${t?.xAxis}"`
] }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("strong", { children: "yAxis:" }),
" ",
Array.isArray(t?.yAxis) ? `Array: [${t.yAxis.join(", ")}]` : `String: "${t?.yAxis}"`
] }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("strong", { children: "series:" }),
" ",
Array.isArray(t?.series) ? `Array: [${t.series.join(", ")}]` : `String: "${t?.series}"`
] }),
t?.sizeField && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("strong", { children: "sizeField:" }),
" ",
Array.isArray(t?.sizeField) ? `Array: [${t.sizeField.join(", ")}]` : `String: "${t?.sizeField}"`
] }),
t?.colorField && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("strong", { children: "colorField:" }),
" ",
Array.isArray(t?.colorField) ? `Array: [${t.colorField.join(", ")}]` : `String: "${t?.colorField}"`
] })
] })
] }),
/* @__PURE__ */ o("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ e("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Chart Config" }),
/* @__PURE__ */ e("pre", { className: "text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border", style: { fontSize: "10px", lineHeight: "1.4" }, children: /* @__PURE__ */ e("code", { className: "language-json", children: JSON.stringify(t, null, 2) }) })
] }),
/* @__PURE__ */ o("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ e("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Display Config" }),
/* @__PURE__ */ e("pre", { className: "text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border", style: { fontSize: "10px", lineHeight: "1.4" }, children: /* @__PURE__ */ e("code", { className: "language-json", children: JSON.stringify(r, null, 2) }) })
] }),
/* @__PURE__ */ o("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ e("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Query Object" }),
/* @__PURE__ */ e("pre", { className: "text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border", style: { fontSize: "10px", lineHeight: "1.4" }, children: /* @__PURE__ */ e("code", { className: "language-json", children: JSON.stringify(n, null, 2) }) })
] }),
/* @__PURE__ */ o("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ e("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Data Sample (first 3 rows)" }),
/* @__PURE__ */ e("pre", { className: "text-dc-text-secondary overflow-x-auto font-mono p-2 rounded-sm border border-dc-border", style: { fontSize: "10px", lineHeight: "1.4" }, children: /* @__PURE__ */ e("code", { className: "language-json", children: JSON.stringify(s?.slice(0, 3) || [], null, 2) }) })
] }),
/* @__PURE__ */ o("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ e("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Cache Status" }),
/* @__PURE__ */ e("div", { className: "bg-dc-surface-secondary p-2 rounded-sm text-xs border border-dc-border", children: c ? /* @__PURE__ */ o("div", { className: "flex items-center gap-4 flex-wrap", children: [
/* @__PURE__ */ e("span", { className: "inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-dc-success-bg text-dc-success", children: "Cache Hit" }),
/* @__PURE__ */ o("span", { children: [
/* @__PURE__ */ e("strong", { children: "Cached At:" }),
" ",
new Date(c.cachedAt).toLocaleString()
] }),
/* @__PURE__ */ o("span", { children: [
/* @__PURE__ */ e("strong", { children: "TTL:" }),
" ",
Math.round(c.ttlMs / 1e3),
"s"
] }),
/* @__PURE__ */ o("span", { children: [
/* @__PURE__ */ e("strong", { children: "TTL Remaining:" }),
" ",
Math.round(c.ttlRemainingMs / 1e3),
"s"
] })
] }) : /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e("span", { className: "inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-dc-surface text-dc-text-muted border border-dc-border", children: "Fresh Query" }),
/* @__PURE__ */ e("span", { className: "text-dc-text-muted", children: "Result not served from cache" })
] }) })
] })
] }),
/* @__PURE__ */ o("div", { className: "mt-4 pt-2 border-t border-dc-border text-xs text-dc-text-muted shrink-0", children: [
"Press ",
/* @__PURE__ */ e("kbd", { className: "px-1 py-0.5 bg-dc-surface-secondary rounded-sm text-xs", children: "ESC" }),
" to close"
] })
] })
}
) : /* @__PURE__ */ e(
"button",
{
onClick: () => u(!0),
className: "p-1 text-dc-text-muted hover:text-dc-text-secondary transition-colors",
title: "Debug chart configuration",
children: /* @__PURE__ */ o(
"svg",
{
width: "16",
height: "16",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
children: [
/* @__PURE__ */ e("circle", { cx: "12", cy: "12", r: "10" }),
/* @__PURE__ */ e("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
/* @__PURE__ */ e("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
]
}
)
}
);
}
const er = { width: "16px", height: "16px", color: "currentColor" };
function Ia(t, r) {
if (t === r) return !0;
if (t.editable !== r.editable || t.isEditMode !== r.isEditMode || t.selectedFilterId !== r.selectedFilterId || t.configEagerLoad !== r.configEagerLoad || t.portlet !== r.portlet || t.debugData !== r.debugData || t.dashboardFilters !== r.dashboardFilters || t.colorPalette !== r.colorPalette || t.loadingComponent !== r.loadingComponent || t.icons !== r.icons || t.onToggleFilter !== r.onToggleFilter || t.onRefresh !== r.onRefresh || t.onDuplicate !== r.onDuplicate || t.onEdit !== r.onEdit || t.onDelete !== r.onDelete || t.onOpenFilterConfig !== r.onOpenFilterConfig || t.onDebugDataReady !== r.onDebugDataReady || t.setPortletRef !== r.setPortletRef || t.setPortletComponentRef !== r.setPortletComponentRef)
return !1;
const n = bn(t.containerProps, r.containerProps), s = bn(t.headerProps, r.headerProps);
return n && s;
}
function bn(t, r) {
if (t === r) return !0;
if (!t || !r) return t === r;
const n = Object.keys(t), s = Object.keys(r);
if (n.length !== s.length) return !1;
for (const a of n)
if (t[a] !== r[a]) return !1;
return !0;
}
const La = wt.memo(function({
portlet: r,
editable: n,
isEditMode: s,
selectedFilterId: a,
debugData: c,
dashboardFilters: l,
configEagerLoad: u,
loadingComponent: d,
colorPalette: f,
containerProps: h,
headerProps: p,
onToggleFilter: m,
onRefresh: v,
onDuplicate: C,
onEdit: _,
onDelete: b,
onOpenFilterConfig: R,
onDebugDataReady: D,
setPortletRef: $,
setPortletComponentRef: A,
icons: w
}) {
const i = a ? (r.dashboardFilterMapping || []).includes(a) : !1, g = !!a, x = [
"bg-dc-surface border rounded-lg flex flex-col h-full transition-all",
g ? "cursor-pointer" : "",
h?.className
].filter(Boolean).join(" "), N = [
"flex items-center justify-between px-3 py-1.5 md:px-4 md:py-1 border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg portlet-drag-handle",
s ? "cursor-move" : "cursor-default",
p?.className
].filter(Boolean).join(" "), {
onClick: S,
className: y,
style: M,
...E
} = h ?? {}, {
onClick: T,
className: j,
style: q,
...I
} = p ?? {}, K = F((U) => {
D(r.id, U);
}, [r.id, D]);
return /* @__PURE__ */ o(
"div",
{
"data-portlet-id": r.id,
ref: (U) => $(r.id, U),
className: x,
style: {
boxShadow: "var(--dc-shadow-sm)",
borderColor: g && i ? "var(--dc-primary)" : "var(--dc-border)",
borderWidth: g && i ? "2px" : "1px",
backgroundColor: g && i ? "rgba(var(--dc-primary-rgb), 0.05)" : "var(--dc-surface)",
opacity: g && !i ? "0.5" : "1",
...M
},
onClick: (U) => {
g && a && (U.stopPropagation(), m(r.id, a)), S?.(U);
},
...E,
children: [
(!r.displayConfig?.hideHeader || s) && /* @__PURE__ */ o(
"div",
{
className: N,
style: q,
onClick: (U) => {
T?.(U);
},
...I,
children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
/* @__PURE__ */ e("h3", { className: "font-semibold text-sm text-dc-text truncate", children: r.title }),
n && s && c && /* @__PURE__ */ e(
"div",
{
onMouseDown: (U) => U.stopPropagation(),
onClick: (U) => U.stopPropagation(),
onTouchStart: (U) => U.stopPropagation(),
onTouchEnd: (U) => U.stopPropagation(),
children: /* @__PURE__ */ e(
us,
{
chartConfig: c.chartConfig,
displayConfig: c.displayConfig,
queryObject: c.queryObject,
data: c.data,
chartType: c.chartType,
cacheInfo: c.cacheInfo
}
)
}
)
] }),
/* @__PURE__ */ o(
"div",
{
className: "flex items-center gap-1 shrink-0 ml-4 -mr-2",
onMouseDown: (U) => U.stopPropagation(),
onClick: (U) => U.stopPropagation(),
onTouchStart: (U) => U.stopPropagation(),
onTouchEnd: (U) => U.stopPropagation(),
children: [
c?.cacheInfo && /* @__PURE__ */ e(
"span",
{
className: "p-1 text-dc-text-muted opacity-40",
title: `Cached ${Math.round((Date.now() - new Date(c.cacheInfo.cachedAt).getTime()) / 1e3)}s ago`,
children: /* @__PURE__ */ o(
"svg",
{
width: "12",
height: "12",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
children: [
/* @__PURE__ */ e("ellipse", { cx: "12", cy: "5", rx: "9", ry: "3" }),
/* @__PURE__ */ e("path", { d: "M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" }),
/* @__PURE__ */ e("path", { d: "M3 12c0 1.66 4 3 9 3s9-1.34 9-3" })
]
}
)
}
),
/* @__PURE__ */ e(
"button",
{
onClick: (U) => {
U.stopPropagation(), v(r.id);
},
onTouchEnd: (U) => {
U.stopPropagation(), U.preventDefault(), v(r.id);
},
disabled: g,
className: `p-1 bg-transparent border-none rounded-sm text-dc-text-secondary transition-colors ${g ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-dc-surface-hover"}`,
title: "Refresh portlet data",
children: /* @__PURE__ */ e(w.RefreshIcon, { style: er })
}
),
n && s && !g && /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"button",
{
onClick: (U) => {
U.stopPropagation(), R(r);
},
onTouchEnd: (U) => {
U.stopPropagation(), U.preventDefault(), R(r);
},
className: "p-1 bg-transparent border-none rounded-sm cursor-pointer hover:bg-dc-surface-hover transition-colors relative",
title: `Configure dashboard filters${r.dashboardFilterMapping && r.dashboardFilterMapping.length > 0 ? ` (${r.dashboardFilterMapping.length} active)` : ""}`,
style: {
color: r.dashboardFilterMapping && r.dashboardFilterMapping.length > 0 ? "var(--dc-primary)" : "var(--dc-text-secondary)"
},
children: /* @__PURE__ */ e(w.FilterIcon, { style: er })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: (U) => {
U.stopPropagation(), C(r.id);
},
onTouchEnd: (U) => {
U.stopPropagation(), U.preventDefault(), C(r.id);
},
className: "p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors",
title: "Duplicate portlet",
children: /* @__PURE__ */ e(w.CopyIcon, { style: er })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: (U) => {
U.stopPropagation(), _(r);
},
onTouchEnd: (U) => {
U.stopPropagation(), U.preventDefault(), _(r);
},
className: "p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors",
title: "Edit portlet",
children: /* @__PURE__ */ e(w.EditIcon, { style: er })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: (U) => {
U.stopPropagation(), b(r.id);
},
onTouchEnd: (U) => {
U.stopPropagation(), U.preventDefault(), b(r.id);
},
className: "p-1 mr-0.5 bg-transparent border-none rounded-sm cursor-pointer hover:bg-dc-danger-bg text-dc-danger transition-colors",
title: "Delete portlet",
children: /* @__PURE__ */ e(w.DeleteIcon, { style: er })
}
)
] })
]
}
)
]
}
),
/* @__PURE__ */ e("div", { className: "flex-1 px-2 py-3 md:px-4 md:py-4 min-h-0 overflow-visible flex flex-col", children: /* @__PURE__ */ e(
Tr,
{
ref: (U) => A(r.id, U),
query: r.query,
chartType: r.chartType,
chartConfig: r.chartConfig,
displayConfig: r.displayConfig,
dashboardFilters: l,
dashboardFilterMapping: r.dashboardFilterMapping,
eagerLoad: r.eagerLoad ?? u ?? !1,
title: r.title,
height: "100%",
colorPalette: f,
loadingComponent: d,
onDebugDataReady: K
}
) })
]
}
);
}, Ia), dr = 16;
function Fa({
rows: t,
portlets: r,
gridSettings: n,
gridWidth: s,
canEdit: a,
isDragging: c,
onRowResize: l,
onColumnResize: u,
onPortletDragStart: d,
onPortletDragEnd: f,
onRowDrop: h,
onNewRowDrop: p,
renderPortlet: m
}) {
const v = new Map(r.map((i) => [i.id, i])), [C, _] = V(null), b = (i) => {
_(i);
}, R = c || C !== null, D = F((i) => {
const g = parseInt(i.currentTarget.dataset.rowIndex || "0", 10), x = parseInt(i.currentTarget.dataset.columnIndex || "0", 10), N = i.currentTarget.dataset.portletId || "";
d(g, x, N, i);
}, [d]), $ = F(() => {
b(null), f();
}, [f]), A = C === "row-insert-0", w = C === "row-bottom";
return /* @__PURE__ */ o(
"div",
{
className: `dc-row-layout${a ? " dc-row-layout-editable" : ""}${R ? " dc-row-layout-dragging" : ""}`,
style: {
"--dc-row-gap": "24px",
"--dc-column-gap": `${dr}px`,
"--dc-top-drop-space": A ? "24px" : "0px",
"--dc-bottom-drop-space": w ? "24px" : "0px"
},
children: [
a && /* @__PURE__ */ e(
"div",
{
className: `dc-row-boundary-drop dc-row-boundary-drop-top dc-split-handle${C === "row-insert-0" ? " dc-drop-zone-active" : ""}`,
onDragOver: (i) => {
i.preventDefault(), b("row-insert-0");
},
onDragLeave: () => b(null),
onDrop: (i) => {
i.preventDefault(), b(null), p(0);
}
}
),
t.map((i, g) => {
const x = i.h * n.rowHeight, N = s || n.cols * n.rowHeight, S = C === `row-${g}-insert-0` ? dr : 0, y = C === `row-${g}-insert-${i.columns.length}` ? dr : 0, E = (N - (i.columns.length - 1) * dr - S - y) / n.cols;
return /* @__PURE__ */ o("div", { className: "dc-row-layout-row-wrapper", children: [
/* @__PURE__ */ e(
"div",
{
className: "dc-row-layout-row",
style: { height: x, paddingLeft: S, paddingRight: y },
children: i.columns.map((T, j) => {
const q = v.get(T.portletId);
if (!q) return null;
const I = T.w * E, K = {
draggable: a,
"data-row-index": g.toString(),
"data-column-index": j.toString(),
"data-portlet-id": q.id,
onDragStart: D,
onDragEnd: $,
className: "dc-row-layout-column"
};
return /* @__PURE__ */ o(
"div",
{
className: "dc-row-layout-column-wrapper",
style: {
flex: `0 0 ${I}px`,
maxWidth: `${I}px`
},
children: [
m(q, K),
j < i.columns.length - 1 && /* @__PURE__ */ e(
"div",
{
className: `dc-column-resize-handle dc-split-handle${C === `row-${g}-insert-${j + 1}` ? " dc-drop-zone-active" : ""}`,
onMouseDown: (U) => u(g, j, U),
onDragOver: (U) => {
a && (U.preventDefault(), b(`row-${g}-insert-${j + 1}`));
},
onDragLeave: () => b(null),
onDrop: (U) => {
a && (U.preventDefault(), U.stopPropagation(), b(null), h(g, j + 1));
}
}
)
]
},
q.id
);
})
}
),
a && /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"div",
{
className: `dc-row-edge-drop dc-row-edge-drop-left dc-split-handle${C === `row-${g}-insert-0` ? " dc-drop-zone-active" : ""}`,
onDragOver: (T) => {
T.preventDefault(), b(`row-${g}-insert-0`);
},
onDragLeave: () => {
b(null);
},
onDrop: (T) => {
T.preventDefault(), b(null), h(g, 0);
}
}
),
/* @__PURE__ */ e(
"div",
{
className: `dc-row-edge-drop dc-row-edge-drop-right dc-split-handle${C === `row-${g}-insert-${i.columns.length}` ? " dc-drop-zone-active" : ""}`,
onDragOver: (T) => {
T.preventDefault(), b(`row-${g}-insert-${i.columns.length}`);
},
onDragLeave: () => {
b(null);
},
onDrop: (T) => {
T.preventDefault(), b(null), h(g, i.columns.length);
}
}
)
] }),
a && /* @__PURE__ */ e(
"div",
{
className: `dc-row-resize-handle dc-split-handle${C === `row-insert-${g + 1}` ? " dc-drop-zone-active" : ""}`,
onMouseDown: (T) => l(g, T),
onDragOver: (T) => {
T.preventDefault(), b(`row-insert-${g + 1}`);
},
onDragLeave: () => b(null),
onDrop: (T) => {
T.preventDefault(), b(null), p(g + 1);
}
}
)
] }, i.id);
}),
a && /* @__PURE__ */ e(
"div",
{
className: `dc-row-boundary-drop dc-row-boundary-drop-bottom dc-split-handle${C === "row-bottom" ? " dc-drop-zone-active" : ""}`,
onDragOver: (i) => {
i.preventDefault(), b("row-bottom");
},
onDragLeave: () => b(null),
onDrop: (i) => {
i.preventDefault(), b(null), p(t.length);
}
}
)
]
}
);
}
const nr = [
{
name: "default",
label: "Default",
colors: [
"#3b82f6",
// blue
"#10b981",
// green
"#f59e0b",
// yellow
"#ef4444",
// red
"#8b5cf6",
// purple
"#f97316",
// orange
"#06b6d4",
// cyan
"#84cc16"
// lime
],
gradient: [
"#440154",
// dark purple
"#414487",
// purple-blue
"#2a788e",
// teal
"#22a884",
// green-teal
"#7ad151",
// green
"#fde725"
// yellow
]
},
{
name: "ocean",
label: "Ocean",
colors: [
"#1e3a8a",
// deep blue
"#1e40af",
// blue
"#2563eb",
// bright blue
"#3b82f6",
// light blue
"#06b6d4",
// cyan
"#0891b2",
// dark cyan
"#0e7490",
// teal
"#0f766e"
// dark teal
],
gradient: [
"#0c4a6e",
// very dark blue
"#075985",
// dark blue
"#0369a1",
// medium blue
"#0284c7",
// bright blue
"#0ea5e9",
// light blue
"#38bdf8"
// cyan blue
]
},
{
name: "sunset",
label: "Sunset",
colors: [
"#dc2626",
// red
"#ea580c",
// orange-red
"#f59e0b",
// orange
"#eab308",
// yellow-orange
"#d97706",
// amber
"#b45309",
// dark amber
"#92400e",
// brown
"#7c2d12"
// dark brown
],
gradient: [
"#7c2d12",
// dark brown
"#92400e",
// brown
"#b45309",
// dark amber
"#d97706",
// amber
"#f59e0b",
// orange
"#fbbf24"
// light orange
]
},
{
name: "forest",
label: "Forest",
colors: [
"#166534",
// dark green
"#15803d",
// green
"#16a34a",
// bright green
"#22c55e",
// light green
"#4ade80",
// lighter green
"#65a30d",
// lime green
"#84cc16",
// lime
"#a3e635"
// light lime
],
gradient: [
"#14532d",
// very dark green
"#166534",
// dark green
"#15803d",
// green
"#16a34a",
// bright green
"#22c55e",
// light green
"#4ade80"
// lighter green
]
},
{
name: "purple",
label: "Purple",
colors: [
"#581c87",
// dark purple
"#7c3aed",
// purple
"#8b5cf6",
// bright purple
"#a855f7",
// light purple
"#c084fc",
// lighter purple
"#e879f9",
// magenta
"#f0abfc",
// light magenta
"#fbbf24"
// accent yellow
],
gradient: [
"#4c1d95",
// very dark purple
"#581c87",
// dark purple
"#6d28d9",
// medium purple
"#7c3aed",
// purple
"#8b5cf6",
// bright purple
"#a855f7"
// light purple
]
},
{
name: "monochrome",
label: "Monochrome",
colors: [
"#1f2937",
// very dark gray
"#374151",
// dark gray
"#4b5563",
// medium gray
"#6b7280",
// gray
"#9ca3af",
// light gray
"#d1d5db",
// lighter gray
"#e5e7eb",
// very light gray
"#f3f4f6"
// almost white
],
gradient: [
"#111827",
// black
"#1f2937",
// very dark gray
"#374151",
// dark gray
"#4b5563",
// medium gray
"#6b7280",
// gray
"#9ca3af"
// light gray
]
},
{
name: "pastel",
label: "Pastel",
colors: [
"#93c5fd",
// light blue
"#86efac",
// light green
"#fde047",
// light yellow
"#fca5a5",
// light red
"#c4b5fd",
// light purple
"#fdba74",
// light orange
"#67e8f9",
// light cyan
"#bef264"
// light lime
],
gradient: [
"#bfdbfe",
// very light blue
"#a7f3d0",
// very light green
"#fef08a",
// very light yellow
"#fecaca",
// very light red
"#ddd6fe",
// very light purple
"#fed7aa"
// very light orange
]
},
{
name: "vibrant",
label: "Vibrant",
colors: [
"#0000ff",
// pure blue
"#00ff00",
// pure green
"#ffff00",
// pure yellow
"#ff0000",
// pure red
"#ff00ff",
// pure magenta
"#ff8000",
// pure orange
"#00ffff",
// pure cyan
"#8000ff"
// pure violet
],
gradient: [
"#4000ff",
// blue-violet
"#0080ff",
// blue
"#00ffff",
// cyan
"#00ff80",
// green
"#80ff00",
// lime
"#ffff00"
// yellow
]
},
{
name: "d3Category10",
label: "D3 Category 10",
colors: [
"#1f77b4",
// blue
"#ff7f0e",
// orange
"#2ca02c",
// green
"#d62728",
// red
"#9467bd",
// purple
"#8c564b",
// brown
"#e377c2",
// pink
"#7f7f7f",
// gray
"#bcbd22",
// olive
"#17becf"
// cyan
],
gradient: [
"#1f77b4",
// blue
"#2ca02c",
// green
"#bcbd22",
// olive
"#ff7f0e",
// orange
"#d62728",
// red
"#9467bd"
// purple
]
},
{
name: "d3Tableau10",
label: "D3 Tableau 10",
colors: [
"#4e79a7",
// blue
"#f28e2c",
// orange
"#e15759",
// red
"#76b7b2",
// teal
"#59a14f",
// green
"#edc949",
// yellow
"#af7aa1",
// purple
"#ff9da7",
// pink
"#9c755f",
// brown
"#bab0ab"
// gray
],
gradient: [
"#4e79a7",
// blue
"#76b7b2",
// teal
"#59a14f",
// green
"#edc949",
// yellow
"#f28e2c",
// orange
"#e15759"
// red
]
},
{
name: "colorBrewerSet1",
label: "ColorBrewer Set 1",
colors: [
"#e41a1c",
// red
"#377eb8",
// blue
"#4daf4a",
// green
"#984ea3",
// purple
"#ff7f00",
// orange
"#ffff33",
// yellow
"#a65628",
// brown
"#f781bf",
// pink
"#999999"
// gray
],
gradient: [
"#377eb8",
// blue
"#4daf4a",
// green
"#ffff33",
// yellow
"#ff7f00",
// orange
"#e41a1c",
// red
"#984ea3"
// purple
]
},
{
name: "colorBrewerSet2",
label: "ColorBrewer Set 2",
colors: [
"#66c2a5",
// teal
"#fc8d62",
// orange
"#8da0cb",
// blue
"#e78ac3",
// pink
"#a6d854",
// lime
"#ffd92f",
// yellow
"#e5c494",
// tan
"#b3b3b3"
// gray
],
gradient: [
"#8da0cb",
// blue
"#66c2a5",
// teal
"#a6d854",
// lime
"#ffd92f",
// yellow
"#fc8d62",
// orange
"#e78ac3"
// pink
]
},
{
name: "colorBrewerDark2",
label: "ColorBrewer Dark 2",
colors: [
"#1b9e77",
// dark teal
"#d95f02",
// dark orange
"#7570b3",
// dark blue
"#e7298a",
// dark pink
"#66a61e",
// dark green
"#e6ab02",
// dark yellow
"#a6761d",
// dark brown
"#666666"
// dark gray
],
gradient: [
"#7570b3",
// dark blue
"#1b9e77",
// dark teal
"#66a61e",
// dark green
"#e6ab02",
// dark yellow
"#d95f02",
// dark orange
"#e7298a"
// dark pink
]
},
{
name: "colorBrewerPaired",
label: "ColorBrewer Paired",
colors: [
"#a6cee3",
// light blue
"#1f78b4",
// blue
"#b2df8a",
// light green
"#33a02c",
// green
"#fb9a99",
// light red
"#e31a1c",
// red
"#fdbf6f",
// light orange
"#ff7f00",
// orange
"#cab2d6",
// light purple
"#6a3d9a",
// purple
"#ffff99",
// light yellow
"#b15928"
// brown
],
gradient: [
"#1f78b4",
// blue
"#33a02c",
// green
"#ffff99",
// light yellow
"#ff7f00",
// orange
"#e31a1c",
// red
"#6a3d9a"
// purple
]
},
{
name: "viridis",
label: "Viridis",
colors: [
"#440154",
// dark purple
"#482677",
// purple
"#3f4a8a",
// blue-purple
"#31678e",
// blue
"#26838f",
// teal
"#1f9d8a",
// green-teal
"#6cce5a",
// green
"#b6de2b"
// yellow-green
],
gradient: [
"#440154",
// dark purple
"#482677",
// purple
"#3f4a8a",
// blue-purple
"#31678e",
// blue
"#26838f",
// teal
"#1f9d8a",
// green-teal
"#6cce5a",
// green
"#b6de2b"
// yellow-green
]
},
{
name: "plasma",
label: "Plasma",
colors: [
"#0c0786",
// dark blue
"#5c01a6",
// purple
"#900da4",
// magenta
"#bf3984",
// pink
"#e16462",
// coral
"#f99b45",
// orange
"#fcce25",
// yellow
"#f0f921"
// bright yellow
],
gradient: [
"#0c0786",
// dark blue
"#5c01a6",
// purple
"#900da4",
// magenta
"#bf3984",
// pink
"#e16462",
// coral
"#f99b45",
// orange
"#fcce25",
// yellow
"#f0f921"
// bright yellow
]
},
{
name: "inferno",
label: "Inferno",
colors: [
"#000003",
// black
"#1f0c47",
// dark blue
"#550f6d",
// purple
"#88226a",
// magenta
"#a83655",
// red
"#cc4f39",
// orange-red
"#e6862a",
// orange
"#fec228"
// yellow
],
gradient: [
"#000003",
// black
"#1f0c47",
// dark blue
"#550f6d",
// purple
"#88226a",
// magenta
"#a83655",
// red
"#cc4f39",
// orange-red
"#e6862a",
// orange
"#fec228"
// yellow
]
},
{
name: "magma",
label: "Magma",
colors: [
"#000003",
// black
"#140b34",
// dark purple
"#3b0f6f",
// purple
"#641a80",
// magenta
"#8b2981",
// pink
"#b63679",
// coral
"#de4968",
// red
"#fd9f6c"
// orange
],
gradient: [
"#000003",
// black
"#140b34",
// dark purple
"#3b0f6f",
// purple
"#641a80",
// magenta
"#8b2981",
// pink
"#b63679",
// coral
"#de4968",
// red
"#fd9f6c"
// orange
]
},
{
name: "cividis",
label: "Cividis",
colors: [
"#00204c",
// dark blue
"#003f5c",
// blue
"#2c4b7a",
// blue
"#51576f",
// blue-gray
"#7f6874",
// gray
"#a8786e",
// brown
"#d2906d",
// orange
"#ffb570"
// yellow
],
gradient: [
"#00204c",
// dark blue
"#003f5c",
// blue
"#2c4b7a",
// blue
"#51576f",
// blue-gray
"#7f6874",
// gray
"#a8786e",
// brown
"#d2906d",
// orange
"#ffb570"
// yellow
]
},
{
name: "turbo",
label: "Turbo",
colors: [
"#30123b",
// purple
"#4454c4",
// blue
"#1dd3c0",
// cyan
"#42f465",
// green
"#b2df22",
// lime
"#faba39",
// yellow
"#f66c19",
// orange
"#c42e02"
// red
],
gradient: [
"#30123b",
// purple
"#4454c4",
// blue
"#1dd3c0",
// cyan
"#42f465",
// green
"#b2df22",
// lime
"#faba39",
// yellow
"#f66c19",
// orange
"#c42e02"
// red
]
},
{
name: "warm",
label: "Warm",
colors: [
"#8b0000",
// dark red
"#b22222",
// red
"#cd5c5c",
// light red
"#ff6347",
// tomato
"#ff8c00",
// dark orange
"#ffa500",
// orange
"#ffd700",
// gold
"#ffff00"
// yellow
],
gradient: [
"#8b0000",
// dark red
"#b22222",
// red
"#ff6347",
// tomato
"#ff8c00",
// dark orange
"#ffa500",
// orange
"#ffd700"
// gold
]
},
{
name: "cool",
label: "Cool",
colors: [
"#000080",
// navy
"#0000ff",
// blue
"#4169e1",
// royal blue
"#00bfff",
// deep sky blue
"#00ffff",
// cyan
"#40e0d0",
// turquoise
"#20b2aa",
// light sea green
"#008b8b"
// dark cyan
],
gradient: [
"#000080",
// navy
"#0000ff",
// blue
"#4169e1",
// royal blue
"#00bfff",
// deep sky blue
"#00ffff",
// cyan
"#40e0d0"
// turquoise
]
},
{
name: "earth",
label: "Earth",
colors: [
"#8b4513",
// saddle brown
"#a0522d",
// sienna
"#cd853f",
// peru
"#daa520",
// goldenrod
"#d2691e",
// chocolate
"#bc8f8f",
// rosy brown
"#f4a460",
// sandy brown
"#deb887"
// burlywood
],
gradient: [
"#8b4513",
// saddle brown
"#a0522d",
// sienna
"#cd853f",
// peru
"#daa520",
// goldenrod
"#d2691e",
// chocolate
"#f4a460"
// sandy brown
]
},
{
name: "autumn",
label: "Autumn",
colors: [
"#8b0000",
// dark red
"#a0522d",
// sienna
"#cd853f",
// peru
"#daa520",
// goldenrod
"#ff8c00",
// dark orange
"#ff4500",
// orange red
"#dc143c",
// crimson
"#b22222"
// fire brick
],
gradient: [
"#8b0000",
// dark red
"#a0522d",
// sienna
"#cd853f",
// peru
"#daa520",
// goldenrod
"#ff8c00",
// dark orange
"#ff4500"
// orange red
]
},
{
name: "spring",
label: "Spring",
colors: [
"#32cd32",
// lime green
"#98fb98",
// pale green
"#90ee90",
// light green
"#ffb6c1",
// light pink
"#ffc0cb",
// pink
"#ffffe0",
// light yellow
"#f0fff0",
// honeydew
"#e0ffff"
// light cyan
],
gradient: [
"#32cd32",
// lime green
"#98fb98",
// pale green
"#ffffe0",
// light yellow
"#ffb6c1",
// light pink
"#ffc0cb",
// pink
"#e0ffff"
// light cyan
]
},
{
name: "winter",
label: "Winter",
colors: [
"#191970",
// midnight blue
"#4682b4",
// steel blue
"#87ceeb",
// sky blue
"#b0e0e6",
// powder blue
"#e0ffff",
// light cyan
"#f0f8ff",
// alice blue
"#c0c0c0",
// silver
"#708090"
// slate gray
],
gradient: [
"#191970",
// midnight blue
"#4682b4",
// steel blue
"#87ceeb",
// sky blue
"#b0e0e6",
// powder blue
"#e0ffff",
// light cyan
"#f0f8ff"
// alice blue
]
},
{
name: "neon",
label: "Neon",
colors: [
"#ff0080",
// neon pink
"#00ff80",
// neon green
"#8000ff",
// neon purple
"#ff8000",
// neon orange
"#0080ff",
// neon blue
"#80ff00",
// neon lime
"#ff0040",
// neon red
"#40ff00"
// bright green
],
gradient: [
"#8000ff",
// neon purple
"#0080ff",
// neon blue
"#00ff80",
// neon green
"#80ff00",
// neon lime
"#ff8000",
// neon orange
"#ff0080"
// neon pink
]
},
{
name: "retro",
label: "Retro",
colors: [
"#ff69b4",
// hot pink
"#ffd700",
// gold
"#32cd32",
// lime green
"#00ced1",
// dark turquoise
"#ff6347",
// tomato
"#9370db",
// medium purple
"#ffa500",
// orange
"#20b2aa"
// light sea green
],
gradient: [
"#9370db",
// medium purple
"#ff69b4",
// hot pink
"#ff6347",
// tomato
"#ffd700",
// gold
"#32cd32",
// lime green
"#00ced1"
// dark turquoise
]
},
{
name: "corporate",
label: "Corporate",
colors: [
"#003366",
// dark blue
"#0066cc",
// blue
"#336699",
// steel blue
"#6699cc",
// light blue
"#4d4d4d",
// dark gray
"#808080",
// gray
"#b3b3b3",
// light gray
"#cccccc"
// very light gray
],
gradient: [
"#003366",
// dark blue
"#0066cc",
// blue
"#336699",
// steel blue
"#6699cc",
// light blue
"#808080",
// gray
"#b3b3b3"
// light gray
]
},
{
name: "material",
label: "Material Design",
colors: [
"#f44336",
// red
"#e91e63",
// pink
"#9c27b0",
// purple
"#673ab7",
// deep purple
"#3f51b5",
// indigo
"#2196f3",
// blue
"#03a9f4",
// light blue
"#00bcd4"
// cyan
],
gradient: [
"#673ab7",
// deep purple
"#3f51b5",
// indigo
"#2196f3",
// blue
"#00bcd4",
// cyan
"#03a9f4",
// light blue
"#e91e63"
// pink
]
}
];
function Wr(t) {
return t && nr.find((n) => n.name === t) || nr[0];
}
const qa = Q("edit"), Pa = Q("check"), ja = Q("segment"), Ba = Q("table"), Va = Q("add"), Qa = Q("swatch");
function Ua({
isEditBarVisible: t,
position: r,
isEditMode: n,
onEditModeToggle: s,
layoutMode: a,
onLayoutModeChange: c,
allowedModes: l,
canChangeLayoutMode: u,
currentPalette: d,
onPaletteChange: f,
onAddPortlet: h
}) {
const [p, m] = V(!1), v = Ce(null);
ve(() => {
if (!p) return;
const D = ($) => {
v.current && !v.current.contains($.target) && m(!1);
};
return document.addEventListener("mousedown", D), () => document.removeEventListener("mousedown", D);
}, [p]), ve(() => {
t && m(!1);
}, [t]);
const C = r === "left" ? "left-4" : "right-4", _ = t, R = /* @__PURE__ */ o(
"div",
{
className: `fixed top-1/2 -translate-y-1/2 z-50 flex flex-col gap-1.5 p-2
bg-dc-surface-tertiary border border-dc-border rounded-lg
transition-all duration-300 ease-in-out
${C} ${r === "left" ? _ ? "-translate-x-16 opacity-0 pointer-events-none" : "translate-x-0 opacity-100" : _ ? "translate-x-16 opacity-0 pointer-events-none" : "translate-x-0 opacity-100"}`,
style: {
boxShadow: "var(--dc-shadow-lg)"
},
children: [
/* @__PURE__ */ e(
tr,
{
icon: n ? Pa : qa,
tooltip: n ? "Finish Editing" : "Edit Dashboard",
isActive: n,
onClick: s
}
),
n && l.length > 1 && /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("div", { className: "w-full h-px bg-dc-border my-0.5" }),
/* @__PURE__ */ e(
tr,
{
icon: ja,
tooltip: "Grid Layout",
isActive: a === "grid",
disabled: !u,
onClick: () => c("grid")
}
),
/* @__PURE__ */ e(
tr,
{
icon: Ba,
tooltip: "Rows Layout",
isActive: a === "rows",
disabled: !u,
onClick: () => c("rows")
}
)
] }),
n && /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("div", { className: "w-full h-px bg-dc-border my-0.5" }),
/* @__PURE__ */ o("div", { ref: v, className: "relative", children: [
/* @__PURE__ */ e(
tr,
{
icon: Qa,
tooltip: "Color Palette",
isActive: p,
onClick: () => m(!p)
}
),
p && /* @__PURE__ */ e(
Ha,
{
position: r,
currentPalette: d,
onPaletteChange: (D) => {
f(D), m(!1);
}
}
)
] })
] }),
n && /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("div", { className: "w-full h-px bg-dc-border my-0.5" }),
/* @__PURE__ */ e(
tr,
{
icon: Va,
tooltip: "Add Portlet",
onClick: h
}
)
] })
]
}
);
return typeof document > "u" ? null : ba(R, document.body);
}
function tr({ icon: t, tooltip: r, isActive: n, disabled: s, onClick: a }) {
return /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: a,
disabled: s,
title: r,
className: `p-2 rounded-md transition-colors focus:outline-hidden focus:ring-2 focus:ring-dc-accent
${s ? "opacity-50 cursor-not-allowed bg-dc-surface-secondary" : n ? "bg-dc-surface-secondary" : "bg-dc-surface hover:bg-dc-surface-hover"}`,
style: {
color: s ? "var(--dc-text-muted)" : n ? "var(--dc-primary)" : "var(--dc-text-secondary)",
borderColor: n ? "var(--dc-primary)" : "transparent"
},
children: /* @__PURE__ */ e(t, { className: "w-5 h-5" })
}
);
}
function Ha({ position: t, currentPalette: r, onPaletteChange: n }) {
return /* @__PURE__ */ e(
"div",
{
className: `absolute top-0 ${t === "left" ? "left-full ml-2" : "right-full mr-2"} w-52 bg-dc-surface border border-dc-border rounded-md z-50 max-h-72 overflow-y-auto`,
style: {
boxShadow: "var(--dc-shadow-lg)"
},
children: /* @__PURE__ */ e("div", { className: "py-1", children: nr.slice().sort((a, c) => a.label.localeCompare(c.label)).map((a) => /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => n(a.name),
className: `w-full px-3 py-2 text-left text-sm hover:bg-dc-surface-hover transition-colors ${a.name === r ? "bg-dc-surface-secondary text-dc-primary" : "text-dc-text-secondary"}`,
children: /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e("div", { className: "flex gap-0.5 shrink-0", children: a.colors.slice(0, 4).map((c, l) => /* @__PURE__ */ e(
"div",
{
className: "w-2.5 h-2.5 rounded-xs border border-dc-border",
style: { backgroundColor: c }
},
l
)) }),
/* @__PURE__ */ e("span", { className: "text-xs font-medium truncate text-dc-text", children: a.label }),
a.name === r && /* @__PURE__ */ e("div", { className: "ml-auto w-1.5 h-1.5 rounded-full shrink-0 bg-dc-primary" })
] })
},
a.name
)) })
}
);
}
const Yr = ({
isOpen: t,
onClose: r,
title: n,
size: s = "md",
closeOnBackdropClick: a = !0,
closeOnEscape: c = !0,
showCloseButton: l = !0,
children: u,
footer: d,
noPadding: f = !1
}) => {
const h = F((m) => {
m.key === "Escape" && c && r();
}, [c, r]);
return ve(() => (t ? (c && document.addEventListener("keydown", h), document.body.style.overflow = "hidden") : document.body.style.overflow = "unset", () => {
document.removeEventListener("keydown", h), document.body.style.overflow = "unset";
}), [t, c, h]), t ? /* @__PURE__ */ e(
"div",
{
className: `fixed inset-0 z-50 backdrop-blur-md ${s === "fullscreen-mobile" ? "flex md:flex md:items-center md:justify-center" : "flex items-center justify-center"}`,
style: { backgroundColor: "var(--dc-overlay)" },
onClick: a ? r : void 0,
children: /* @__PURE__ */ o(
"div",
{
className: `relative bg-dc-surface border border-dc-border ${s === "fullscreen-mobile" ? "rounded-none md:rounded-lg" : "rounded-lg"} ${s === "fullscreen" || s === "fullscreen-mobile" ? "" : "mx-4"} ${(() => {
switch (s) {
case "sm":
return "max-w-md";
case "md":
return "max-w-lg";
case "lg":
return "max-w-2xl";
case "xl":
return "max-w-6xl";
case "xxl":
return "max-w-[1400px]";
// Good for retina/mac displays
case "full":
return "max-w-7xl";
case "fullscreen":
return "w-[90vw] h-[90vh] max-w-none";
case "fullscreen-mobile":
return "w-full h-full md:w-[min(90vw,1400px)] md:h-[90vh]";
default:
return "max-w-lg";
}
})()} ${s === "fullscreen" || s === "fullscreen-mobile" ? "" : "max-h-[90vh]"} flex flex-col`,
style: { boxShadow: "var(--dc-shadow-2xl)" },
onClick: (m) => m.stopPropagation(),
role: "dialog",
"aria-modal": "true",
"aria-labelledby": n ? "modal-title" : void 0,
children: [
(n || l) && /* @__PURE__ */ o("div", { className: "flex items-center justify-between px-6 py-4 border-b border-dc-border", children: [
n && /* @__PURE__ */ e("h2", { id: "modal-title", className: "text-xl font-semibold text-dc-text", children: n }),
l && /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: r,
className: "text-dc-text-muted hover:text-dc-text-secondary transition-colors p-2 -mr-2",
"aria-label": "Close modal",
children: /* @__PURE__ */ e("svg", { width: "24", height: "24", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
}
)
] }),
/* @__PURE__ */ e("div", { className: `flex-1 overflow-y-auto ${f ? "" : "px-6 py-4"}`, children: u }),
d && /* @__PURE__ */ e("div", { className: "flex items-center justify-end space-x-3 px-6 py-4 border-t border-dc-border bg-dc-surface-secondary", children: wt.Children.toArray(d) })
]
}
)
}
) : null;
};
function za(t) {
const r = /* @__PURE__ */ new Date(), n = t.toLowerCase().trim(), s = r.getUTCFullYear(), a = r.getUTCMonth(), c = r.getUTCDate(), l = r.getUTCDay();
if (n === "today") {
const p = new Date(r);
p.setUTCHours(0, 0, 0, 0);
const m = new Date(r);
return m.setUTCHours(23, 59, 59, 999), { start: p, end: m };
}
if (n === "yesterday") {
const p = new Date(r);
p.setUTCDate(c - 1), p.setUTCHours(0, 0, 0, 0);
const m = new Date(r);
return m.setUTCDate(c - 1), m.setUTCHours(23, 59, 59, 999), { start: p, end: m };
}
if (n === "this week") {
const p = l === 0 ? -6 : 1 - l, m = new Date(r);
m.setUTCDate(c + p), m.setUTCHours(0, 0, 0, 0);
const v = new Date(m);
return v.setUTCDate(m.getUTCDate() + 6), v.setUTCHours(23, 59, 59, 999), { start: m, end: v };
}
if (n === "this month") {
const p = new Date(Date.UTC(s, a, 1, 0, 0, 0, 0)), m = new Date(Date.UTC(s, a + 1, 0, 23, 59, 59, 999));
return { start: p, end: m };
}
if (n === "this quarter") {
const p = Math.floor(a / 3), m = new Date(Date.UTC(s, p * 3, 1, 0, 0, 0, 0)), v = new Date(Date.UTC(s, p * 3 + 3, 0, 23, 59, 59, 999));
return { start: m, end: v };
}
if (n === "this year") {
const p = new Date(Date.UTC(s, 0, 1, 0, 0, 0, 0)), m = new Date(Date.UTC(s, 11, 31, 23, 59, 59, 999));
return { start: p, end: m };
}
const u = n.match(/^last\s+(\d+)\s+days?$/);
if (u) {
const p = parseInt(u[1], 10), m = new Date(r);
m.setUTCDate(c - p + 1), m.setUTCHours(0, 0, 0, 0);
const v = new Date(r);
return v.setUTCHours(23, 59, 59, 999), { start: m, end: v };
}
const d = n.match(/^last\s+(\d+)\s+weeks?$/);
if (d) {
const m = parseInt(d[1], 10) * 7, v = new Date(r);
v.setUTCDate(c - m + 1), v.setUTCHours(0, 0, 0, 0);
const C = new Date(r);
return C.setUTCHours(23, 59, 59, 999), { start: v, end: C };
}
if (n === "last week") {
const p = l === 0 ? -13 : -6 - l, m = new Date(r);
m.setUTCDate(c + p), m.setUTCHours(0, 0, 0, 0);
const v = new Date(m);
return v.setUTCDate(m.getUTCDate() + 6), v.setUTCHours(23, 59, 59, 999), { start: m, end: v };
}
if (n === "last month") {
const p = new Date(Date.UTC(s, a - 1, 1, 0, 0, 0, 0)), m = new Date(Date.UTC(s, a, 0, 23, 59, 59, 999));
return { start: p, end: m };
}
if (n === "last quarter") {
const p = Math.floor(a / 3), m = p === 0 ? 3 : p - 1, v = p === 0 ? s - 1 : s, C = new Date(Date.UTC(v, m * 3, 1, 0, 0, 0, 0)), _ = new Date(Date.UTC(v, m * 3 + 3, 0, 23, 59, 59, 999));
return { start: C, end: _ };
}
if (n === "last year") {
const p = new Date(Date.UTC(s - 1, 0, 1, 0, 0, 0, 0)), m = new Date(Date.UTC(s - 1, 11, 31, 23, 59, 59, 999));
return { start: p, end: m };
}
if (n === "last 12 months") {
const p = new Date(Date.UTC(s, a - 11, 1, 0, 0, 0, 0)), m = new Date(r);
return m.setUTCHours(23, 59, 59, 999), { start: p, end: m };
}
const f = n.match(/^last\s+(\d+)\s+months?$/);
if (f) {
const p = parseInt(f[1], 10), m = new Date(Date.UTC(s, a - p + 1, 1, 0, 0, 0, 0)), v = new Date(r);
return v.setUTCHours(23, 59, 59, 999), { start: m, end: v };
}
const h = n.match(/^last\s+(\d+)\s+years?$/);
if (h) {
const p = parseInt(h[1], 10), m = new Date(Date.UTC(s - p, 0, 1, 0, 0, 0, 0)), v = new Date(r);
return v.setUTCHours(23, 59, 59, 999), { start: m, end: v };
}
return null;
}
function Ga(t) {
if (Array.isArray(t)) {
if (t.length < 2) return null;
const r = new Date(t[0]), n = new Date(t[1]);
return isNaN(r.getTime()) || isNaN(n.getTime()) ? null : (n.setUTCHours(23, 59, 59, 999), { start: r, end: n });
}
return za(t);
}
function ur(t) {
return t.toISOString().split("T")[0];
}
function Wa(t, r) {
const n = r.getTime() - t.getTime(), s = Math.ceil(n / (1e3 * 60 * 60 * 24)), a = new Date(t);
a.setUTCDate(a.getUTCDate() - 1), a.setUTCHours(23, 59, 59, 999);
const c = new Date(a);
return c.setUTCDate(c.getUTCDate() - s + 1), c.setUTCHours(0, 0, 0, 0), { start: c, end: a };
}
function Jr(t, r) {
if (!r) return null;
for (const n of r.cubes) {
const s = n.measures.find((c) => c.name === t);
if (s)
return { field: s, cubeName: n.name, fieldType: "measure" };
const a = n.dimensions.find((c) => c.name === t);
if (a)
return {
field: a,
cubeName: n.name,
fieldType: a.type === "time" ? "timeDimension" : "dimension"
};
}
return null;
}
function ms(t, r) {
const n = Jr(t, r);
return n && (n.field.title || n.field.shortTitle) || t;
}
function fs(t, r) {
if (!t) return [];
const n = [];
for (const s of t.cubes)
if (r === "metrics")
for (const a of s.measures)
n.push({
name: a.name,
title: a.title || a.shortTitle || a.name,
shortTitle: a.shortTitle || a.title || a.name,
type: a.type,
description: a.description,
cubeName: s.name,
fieldType: "measure"
});
else if (r === "breakdown")
for (const a of s.dimensions) {
const c = a.type === "time";
n.push({
name: a.name,
title: a.title || a.shortTitle || a.name,
shortTitle: a.shortTitle || a.title || a.name,
type: a.type,
description: a.description,
cubeName: s.name,
fieldType: c ? "timeDimension" : "dimension"
});
}
else {
for (const a of s.measures)
n.push({
name: a.name,
title: a.title || a.shortTitle || a.name,
shortTitle: a.shortTitle || a.title || a.name,
type: a.type,
description: a.description,
cubeName: s.name,
fieldType: "measure"
});
for (const a of s.dimensions) {
const c = a.type === "time";
n.push({
name: a.name,
title: a.title || a.shortTitle || a.name,
shortTitle: a.shortTitle || a.title || a.name,
type: a.type,
description: a.description,
cubeName: s.name,
fieldType: c ? "timeDimension" : "dimension"
});
}
}
return n;
}
function Ya(t, r, n) {
let s = t;
if (n && n !== "all" && (s = s.filter((a) => a.cubeName === n)), r.trim()) {
const a = r.toLowerCase();
s = s.filter(
(c) => c.name.toLowerCase().includes(a) || c.title.toLowerCase().includes(a) || (c.description?.toLowerCase().includes(a) ?? !1)
);
}
return s;
}
function Ja(t) {
const r = /* @__PURE__ */ new Map();
for (const n of t) {
const s = r.get(n.cubeName) || [];
s.push(n), r.set(n.cubeName, s);
}
return r;
}
const hs = "drizzle-cube-recent-fields", Ka = 10;
function ps() {
try {
const t = localStorage.getItem(hs);
if (t)
return JSON.parse(t);
} catch {
}
return { metrics: [], breakdowns: [] };
}
function Xa(t, r) {
try {
const n = ps(), a = n[r].filter((c) => c !== t);
a.unshift(t), n[r] = a.slice(0, Ka), localStorage.setItem(hs, JSON.stringify(n));
} catch {
}
}
function Za(t, r, n) {
if (!t || n.length === 0) return [];
const s = fs(t, r), a = [];
for (const c of n) {
const l = s.find((u) => u.name === c);
l && a.push(l);
}
return a;
}
function eo(t) {
return t ? t.cubes.map((r) => r.name) : [];
}
function mr(t, r) {
return r && r.cubes.find((s) => s.name === t)?.title || t;
}
const to = Q("check");
function ro({
field: t,
isSelected: r,
isFocused: n,
onClick: s,
onMouseEnter: a,
...c
}) {
const l = () => {
if (t.fieldType === "measure") {
const f = Xt(t.type);
return f ? /* @__PURE__ */ e(f, { className: "w-4 h-4" }) : null;
} else if (t.fieldType === "timeDimension") {
const f = wr("time");
return f ? /* @__PURE__ */ e(f, { className: "w-4 h-4" }) : null;
} else {
const f = wr("dimension");
return f ? /* @__PURE__ */ e(f, { className: "w-4 h-4" }) : null;
}
}, u = () => t.fieldType === "measure" ? "bg-dc-measure text-dc-measure-text" : t.fieldType === "timeDimension" ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text", d = () => t.fieldType === "measure" ? t.type.charAt(0).toUpperCase() + t.type.slice(1) : t.fieldType === "timeDimension" ? "Time" : "Dim";
return /* @__PURE__ */ o(
"button",
{
onClick: s,
onMouseEnter: a,
className: `w-full text-left px-3 py-2 rounded-lg flex items-center gap-3 transition-colors group ${n ? "bg-dc-primary/10 ring-1 ring-dc-primary" : r ? "bg-dc-success/10" : "hover:bg-dc-surface-hover"}`,
...c,
children: [
/* @__PURE__ */ e(
"span",
{
className: `shrink-0 w-8 h-8 flex items-center justify-center rounded-md ${t.fieldType === "measure" ? "bg-dc-measure text-dc-measure-text" : t.fieldType === "timeDimension" ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text"}`,
children: l()
}
),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ e("div", { className: "text-sm font-medium text-dc-text truncate", children: t.title }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: t.name })
] }),
/* @__PURE__ */ e(
"span",
{
className: `shrink-0 px-2 py-0.5 rounded text-xs font-medium ${u()}`,
children: d()
}
),
r && /* @__PURE__ */ e("span", { className: "shrink-0 w-5 h-5 flex items-center justify-center rounded-full bg-dc-success text-white", children: /* @__PURE__ */ e(to, { className: "w-3 h-3" }) })
]
}
);
}
const xn = Ot(ro);
function no({ field: t }) {
if (!t)
return /* @__PURE__ */ e("div", { className: "p-6 text-center text-dc-text-muted", children: /* @__PURE__ */ e("p", { className: "text-sm", children: "Hover over a field to see details" }) });
const r = () => {
if (t.fieldType === "measure") {
const a = Xt(t.type);
return a ? /* @__PURE__ */ e(a, { className: "w-6 h-6" }) : null;
} else if (t.fieldType === "timeDimension") {
const a = wr("time");
return a ? /* @__PURE__ */ e(a, { className: "w-6 h-6" }) : null;
} else {
const a = wr("dimension");
return a ? /* @__PURE__ */ e(a, { className: "w-6 h-6" }) : null;
}
}, n = () => t.fieldType === "measure" ? "bg-dc-measure text-dc-measure-text" : t.fieldType === "timeDimension" ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text", s = () => t.fieldType === "measure" ? {
count: "Count",
countDistinct: "Count Distinct",
countDistinctApprox: "Count Distinct (Approx)",
sum: "Sum",
avg: "Average",
min: "Minimum",
max: "Maximum",
runningTotal: "Running Total",
number: "Number"
}[t.type] || t.type : t.fieldType === "timeDimension" ? "Time Dimension" : {
string: "Text",
number: "Number",
boolean: "Boolean",
geo: "Geographic"
}[t.type] || "Dimension";
return /* @__PURE__ */ o("div", { className: "p-4", children: [
/* @__PURE__ */ o("div", { className: "flex items-start gap-3 mb-4", children: [
/* @__PURE__ */ e(
"span",
{
className: `shrink-0 w-12 h-12 flex items-center justify-center rounded-lg ${n()}`,
children: r()
}
),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ e("h3", { className: "text-base font-semibold text-dc-text leading-tight", children: t.title }),
/* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted mt-0.5 truncate", children: t.name })
] })
] }),
t.description && /* @__PURE__ */ e("div", { className: "mb-4", children: /* @__PURE__ */ e("p", { className: "text-sm text-dc-text-secondary leading-relaxed", children: t.description }) }),
/* @__PURE__ */ o("div", { className: "space-y-3 pt-4 border-t border-dc-border", children: [
/* @__PURE__ */ o("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ e("span", { className: "text-xs text-dc-text-muted", children: "Type" }),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text font-medium", children: s() })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ e("span", { className: "text-xs text-dc-text-muted", children: "Cube" }),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text font-medium", children: t.cubeName })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ e("span", { className: "text-xs text-dc-text-muted", children: "Category" }),
/* @__PURE__ */ e(
"span",
{
className: `text-xs px-2 py-0.5 rounded font-medium ${t.fieldType === "measure" ? "bg-dc-measure text-dc-measure-text" : t.fieldType === "timeDimension" ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text"}`,
children: t.fieldType === "measure" ? "Measure" : t.fieldType === "timeDimension" ? "Time Dimension" : "Dimension"
}
)
] })
] }),
/* @__PURE__ */ e("div", { className: "mt-6 p-3 bg-dc-surface rounded-lg", children: /* @__PURE__ */ o("p", { className: "text-xs text-dc-text-muted", children: [
"Press ",
/* @__PURE__ */ e("kbd", { className: "px-1 py-0.5 bg-dc-surface-tertiary rounded text-xs", children: "Enter" }),
" or click to add this field to your query."
] }) })
] });
}
const so = Ot(no), ao = Q("search"), oo = Q("close");
function gs({
isOpen: t,
onClose: r,
onSelect: n,
mode: s,
schema: a,
selectedFields: c,
recentFields: l
}) {
const [u, d] = V(""), [f, h] = V(null), [p, m] = V(null), [v, C] = V(-1), [_, b] = V(null), R = Ce(null), D = Ce(null), $ = ye(() => {
if (l) return l;
const I = ps();
return s === "metrics" ? I.metrics : I.breakdowns;
}, [l, s]), A = s, w = ye(() => fs(a, A), [a, A]), i = ye(() => eo(a), [a]), g = ye(() => Ya(w, u, f), [w, u, f]), x = ye(() => Ja(g), [g]), N = ye(() => u.trim() ? [] : Za(a, A, $).filter(
(I) => !f || I.cubeName === f
), [a, A, $, u, f]), S = ye(() => {
const I = [...N];
return x.forEach((K) => {
I.push(...K);
}), I;
}, [N, x]);
ve(() => {
t && R.current && R.current.focus();
}, [t]), ve(() => {
t || (d(""), h(null), m(null), C(-1), b(null));
}, [t]);
const y = F(
(I, K = !1) => {
Xa(I.name, s === "metrics" ? "metrics" : "breakdowns");
const U = {
name: I.name,
title: I.title,
shortTitle: I.shortTitle,
type: I.type,
description: I.description
};
n(U, I.fieldType, I.cubeName, K);
},
[s, n]
), M = F(
(I, K, U = !1) => {
if (U && _ !== null && _ !== K) {
const ke = Math.min(_, K), De = Math.max(_, K);
for (let Pe = ke; Pe <= De; Pe++) {
const B = S[Pe];
B && !c.includes(B.name) && y(B, !0);
}
} else U ? y(I, !0) : y(I, !1);
b(K);
},
[S, _, y, c]
), E = F(
(I) => {
if (S.length !== 0)
switch (I.key) {
case "ArrowDown":
I.preventDefault(), C((K) => {
const U = Math.min(K + 1, S.length - 1);
return m(S[U]), U;
});
break;
case "ArrowUp":
I.preventDefault(), C((K) => {
const U = Math.max(K - 1, 0);
return m(S[U]), U;
});
break;
case "Enter":
I.preventDefault(), v >= 0 && S[v] && M(S[v], v, I.shiftKey);
break;
case "Escape":
I.preventDefault(), r();
break;
}
},
[S, v, M, r]
);
if (ve(() => {
if (v >= 0 && D.current) {
const I = D.current.querySelector(
`[data-field-index="${v}"]`
);
I && I.scrollIntoView({ block: "nearest", behavior: "smooth" });
}
}, [v]), !t) return null;
const T = s === "metrics" ? "Search metrics..." : s === "filter" ? "Search fields to filter..." : "Search dimensions...", j = s === "metrics" ? "Select a Metric" : s === "filter" ? "Select a Field to Filter" : "Select a Dimension", q = v >= 0 && S[v] ? `field-option-${S[v].name.replace(/\./g, "-")}` : void 0;
return /* @__PURE__ */ e(
"div",
{
className: "fixed inset-0 z-50 flex items-center justify-center",
style: { backgroundColor: "var(--dc-overlay)" },
onClick: r,
role: "presentation",
children: /* @__PURE__ */ o(
"div",
{
role: "dialog",
"aria-modal": "true",
"aria-label": j,
className: "bg-dc-surface shadow-xl w-full h-full md:rounded-lg md:w-[900px] md:max-w-[900px] md:h-[80vh] md:max-h-[700px] flex flex-col overflow-hidden",
onClick: (I) => I.stopPropagation(),
onKeyDown: E,
children: [
/* @__PURE__ */ o("div", { className: "shrink-0 border-b border-dc-border", children: [
/* @__PURE__ */ o("div", { className: "flex items-center px-4 py-3 gap-3", children: [
/* @__PURE__ */ e(ao, { className: "w-5 h-5 text-dc-text-muted", "aria-hidden": !0 }),
/* @__PURE__ */ e(
"input",
{
ref: R,
type: "text",
value: u,
onChange: (I) => {
d(I.target.value), C(-1);
},
placeholder: T,
className: "flex-1 bg-transparent border-none outline-none text-dc-text placeholder-dc-text-muted text-lg",
"aria-label": T,
"aria-controls": "field-search-results",
"aria-activedescendant": q,
role: "combobox",
"aria-expanded": "true",
"aria-autocomplete": "list"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: r,
className: "p-1 text-dc-text-secondary hover:text-dc-text rounded",
"aria-label": "Close dialog",
children: /* @__PURE__ */ e(oo, { className: "w-5 h-5", "aria-hidden": !0 })
}
)
] }),
i.length > 1 && /* @__PURE__ */ e("div", { className: "md:hidden px-4 pb-3", children: /* @__PURE__ */ o(
"select",
{
value: f || "",
onChange: (I) => h(I.target.value || null),
className: "w-full px-3 py-2 bg-dc-surface border border-dc-border rounded-lg text-sm text-dc-text focus:outline-none focus:ring-1 focus:ring-dc-primary",
"aria-label": "Filter by cube",
children: [
/* @__PURE__ */ e("option", { value: "", children: "All Cubes" }),
i.map((I) => /* @__PURE__ */ e("option", { value: I, children: mr(I, a) }, I))
]
}
) })
] }),
/* @__PURE__ */ o("div", { className: "flex-1 flex overflow-hidden", children: [
/* @__PURE__ */ e(
"nav",
{
className: "hidden md:block w-48 shrink-0 border-r border-dc-border overflow-y-auto bg-dc-surface-secondary",
"aria-label": "Filter by cube",
children: /* @__PURE__ */ o("div", { className: "p-2", role: "group", "aria-label": "Cube categories", children: [
/* @__PURE__ */ e(
"button",
{
onClick: () => h(null),
className: `w-full text-left px-3 py-2 rounded-md text-sm transition-colors ${f === null ? "bg-dc-primary/10 text-dc-primary font-medium" : "text-dc-text hover:bg-dc-surface-hover"}`,
"aria-pressed": f === null,
children: "All"
}
),
i.map((I) => /* @__PURE__ */ e(
"button",
{
onClick: () => h(I),
className: `w-full text-left px-3 py-2 rounded-md text-sm transition-colors truncate ${f === I ? "bg-dc-primary/10 text-dc-primary font-medium" : "text-dc-text hover:bg-dc-surface-hover"}`,
title: mr(I, a),
"aria-pressed": f === I,
children: mr(I, a)
},
I
))
] })
}
),
/* @__PURE__ */ e(
"div",
{
id: "field-search-results",
ref: D,
className: "flex-1 overflow-y-auto p-4",
role: "listbox",
"aria-label": "Available fields",
children: g.length === 0 && N.length === 0 ? /* @__PURE__ */ o("div", { className: "text-center py-12 text-dc-text-muted", children: [
/* @__PURE__ */ e("p", { className: "text-lg mb-2", children: "No fields found" }),
/* @__PURE__ */ e("p", { className: "text-sm", children: u ? `No ${s === "metrics" ? "metrics" : "dimensions"} match "${u}"` : `No ${s === "metrics" ? "metrics" : "dimensions"} available` })
] }) : /* @__PURE__ */ o("div", { className: "space-y-6", children: [
N.length > 0 && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("h3", { className: "text-xs font-semibold text-dc-text-muted uppercase tracking-wider mb-2", children: "Recents" }),
/* @__PURE__ */ e("div", { className: "space-y-1", children: N.map((I, K) => /* @__PURE__ */ e(
xn,
{
field: I,
isSelected: c.includes(I.name),
isFocused: v === K,
onClick: (U) => M(I, K, U.shiftKey),
onMouseEnter: () => {
m(I), C(K);
},
"data-field-index": K
},
`recent-${I.name}`
)) })
] }),
Array.from(x.entries()).map(([I, K]) => /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("h3", { className: "text-xs font-semibold text-dc-text-muted uppercase tracking-wider mb-2", children: mr(I, a) }),
/* @__PURE__ */ e("div", { className: "space-y-1", children: K.map((U) => {
const ke = N.length + Array.from(x.entries()).slice(
0,
Array.from(x.keys()).indexOf(I)
).reduce((De, [, Pe]) => De + Pe.length, 0) + K.indexOf(U);
return /* @__PURE__ */ e(
xn,
{
field: U,
isSelected: c.includes(U.name),
isFocused: v === ke,
onClick: (De) => M(U, ke, De.shiftKey),
onMouseEnter: () => {
m(U), C(ke);
},
"data-field-index": ke
},
U.name
);
}) })
] }, I))
] })
}
),
/* @__PURE__ */ e("div", { className: "hidden md:block w-72 shrink-0 border-l border-dc-border bg-dc-surface-secondary overflow-y-auto", children: /* @__PURE__ */ e(so, { field: p }) })
] }),
/* @__PURE__ */ o("div", { className: "shrink-0 border-t border-dc-border px-4 py-3 flex items-center justify-between text-sm text-dc-text-muted", children: [
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("span", { className: "text-dc-text-secondary", children: g.length }),
" ",
s === "metrics" ? "metrics" : s === "filter" ? "fields" : "dimensions",
" available"
] }),
/* @__PURE__ */ o("div", { className: "hidden md:flex items-center gap-4", children: [
/* @__PURE__ */ o("span", { children: [
/* @__PURE__ */ e("kbd", { className: "px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs", children: "↑↓" }),
" Navigate"
] }),
/* @__PURE__ */ o("span", { children: [
/* @__PURE__ */ e("kbd", { className: "px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs", children: "Enter" }),
" Select"
] }),
/* @__PURE__ */ o("span", { children: [
/* @__PURE__ */ e("kbd", { className: "px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs", children: "Shift" }),
"+Click Multi-select"
] }),
/* @__PURE__ */ o("span", { children: [
/* @__PURE__ */ e("kbd", { className: "px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs", children: "Esc" }),
" Close"
] })
] })
] })
]
}
)
}
);
}
const ar = {
// String operators
equals: {
label: "equals",
description: "Exact match",
requiresValues: !0,
supportsMultipleValues: !0,
valueType: "any",
fieldTypes: ["string", "number", "boolean", "time"]
},
notEquals: {
label: "not equals",
description: "Does not match",
requiresValues: !0,
supportsMultipleValues: !0,
valueType: "any",
fieldTypes: ["string", "number", "boolean", "time"]
},
contains: {
label: "contains",
description: "Contains text (case insensitive)",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
notContains: {
label: "not contains",
description: "Does not contain text",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
startsWith: {
label: "starts with",
description: "Starts with text",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
notStartsWith: {
label: "not starts with",
description: "Does not start with text",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
endsWith: {
label: "ends with",
description: "Ends with text",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
notEndsWith: {
label: "not ends with",
description: "Does not end with text",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
like: {
label: "like",
description: "SQL LIKE pattern matching (case sensitive)",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
notLike: {
label: "not like",
description: "SQL NOT LIKE pattern matching (case sensitive)",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
ilike: {
label: "ilike",
description: "SQL ILIKE pattern matching (case insensitive)",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
// Numeric operators
gt: {
label: "greater than",
description: "Greater than value",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "number",
fieldTypes: ["number", "count", "sum", "avg", "min", "max"]
},
gte: {
label: "greater than or equal",
description: "Greater than or equal to value",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "number",
fieldTypes: ["number", "count", "sum", "avg", "min", "max"]
},
lt: {
label: "less than",
description: "Less than value",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "number",
fieldTypes: ["number", "count", "sum", "avg", "min", "max"]
},
lte: {
label: "less than or equal",
description: "Less than or equal to value",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "number",
fieldTypes: ["number", "count", "sum", "avg", "min", "max"]
},
between: {
label: "between",
description: "Between two values (inclusive)",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "number",
fieldTypes: ["number", "count", "sum", "avg", "min", "max"]
},
notBetween: {
label: "not between",
description: "Not between two values",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "number",
fieldTypes: ["number", "count", "sum", "avg", "min", "max"]
},
// Array operators
in: {
label: "in",
description: "Matches any of the provided values",
requiresValues: !0,
supportsMultipleValues: !0,
valueType: "any",
fieldTypes: ["string", "number", "boolean"]
},
notIn: {
label: "not in",
description: "Does not match any of the provided values",
requiresValues: !0,
supportsMultipleValues: !0,
valueType: "any",
fieldTypes: ["string", "number", "boolean"]
},
// Null/Empty operators
set: {
label: "is set",
description: "Is not null/empty",
requiresValues: !1,
supportsMultipleValues: !1,
valueType: "any",
fieldTypes: ["string", "number", "time", "boolean"]
},
notSet: {
label: "is not set",
description: "Is null/empty",
requiresValues: !1,
supportsMultipleValues: !1,
valueType: "any",
fieldTypes: ["string", "number", "time", "boolean"]
},
isEmpty: {
label: "is empty",
description: "Is empty string or null",
requiresValues: !1,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
isNotEmpty: {
label: "is not empty",
description: "Is not empty string and not null",
requiresValues: !1,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
// Date operators
inDateRange: {
label: "in date range",
description: "Between two dates",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "date",
fieldTypes: ["time"]
},
beforeDate: {
label: "before date",
description: "Before specified date",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "date",
fieldTypes: ["time"]
},
afterDate: {
label: "after date",
description: "After specified date",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "date",
fieldTypes: ["time"]
},
// Regex operators
regex: {
label: "matches regex",
description: "Matches regular expression pattern",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
notRegex: {
label: "not matches regex",
description: "Does not match regular expression pattern",
requiresValues: !0,
supportsMultipleValues: !1,
valueType: "string",
fieldTypes: ["string"]
},
// PostgreSQL array operators
arrayContains: {
label: "array contains all",
description: "Array field contains all specified values (PostgreSQL only)",
requiresValues: !0,
supportsMultipleValues: !0,
valueType: "string",
fieldTypes: ["string"]
},
arrayOverlaps: {
label: "array contains any",
description: "Array field contains any of the specified values (PostgreSQL only)",
requiresValues: !0,
supportsMultipleValues: !0,
valueType: "string",
fieldTypes: ["string"]
},
arrayContained: {
label: "array values in",
description: "All array field values are within specified values (PostgreSQL only)",
requiresValues: !0,
supportsMultipleValues: !0,
valueType: "string",
fieldTypes: ["string"]
}
}, Mt = [
{ value: "custom", label: "Custom" },
{ value: "today", label: "Today" },
{ value: "yesterday", label: "Yesterday" },
{ value: "this_week", label: "This week" },
{ value: "this_month", label: "This month" },
{ value: "this_quarter", label: "This quarter" },
{ value: "this_year", label: "This year" },
{ value: "last_7_days", label: "Last 7 days" },
{ value: "last_30_days", label: "Last 30 days" },
{ value: "last_n_days", label: "Last N days" },
{ value: "last_week", label: "Last week" },
{ value: "last_n_weeks", label: "Last N weeks" },
{ value: "last_month", label: "Last month" },
{ value: "last_12_months", label: "Last 12 months" },
{ value: "last_n_months", label: "Last N months" },
{ value: "last_quarter", label: "Last quarter" },
{ value: "last_n_quarters", label: "Last N quarters" },
{ value: "last_year", label: "Last year" },
{ value: "last_n_years", label: "Last N years" }
];
function co(t) {
return "member" in t && "operator" in t && "values" in t;
}
function lo(t) {
return "type" in t && "filters" in t;
}
function io(t) {
const r = (n) => {
if (co(n))
return n;
if (lo(n)) {
const s = n.filters.map(r);
return n.type === "and" ? { and: s } : { or: s };
}
return n;
};
return t.map(r);
}
function uo(t) {
const r = {};
return t.measures && t.measures.length > 0 && (r.measures = t.measures), t.dimensions && t.dimensions.length > 0 && (r.dimensions = t.dimensions), t.timeDimensions && t.timeDimensions.length > 0 && (r.timeDimensions = t.timeDimensions), t.filters && t.filters.length > 0 && (r.filters = t.filters), t.order && (r.order = t.order), t.limit && (r.limit = t.limit), t.offset && (r.offset = t.offset), t.segments && t.segments.length > 0 && (r.segments = t.segments), r;
}
function yn(t) {
const r = uo(t);
return r.filters && r.filters.length > 0 && (r.filters = io(r.filters)), r;
}
function mo(t) {
const r = [];
for (const [n, s] of Object.entries(ar))
s.fieldTypes.includes(t) && r.push({
operator: n,
label: s.label
});
return r;
}
function Yt(t, r) {
const n = {
today: "today",
yesterday: "yesterday",
this_week: "this week",
this_month: "this month",
this_quarter: "this quarter",
this_year: "this year",
last_7_days: "last 7 days",
last_30_days: "last 30 days",
last_week: "last week",
last_month: "last month",
last_quarter: "last quarter",
last_year: "last year",
last_12_months: "last 12 months"
};
if (t.startsWith("last_n_") && r !== void 0 && r > 0) {
const s = t.replace("last_n_", ""), a = s.slice(0, -1);
return r === 1 ? `last ${a}` : `last ${r} ${s}`;
}
return n[t] || t;
}
function fr(t) {
return t.startsWith("last_n_");
}
function vn(t) {
return t.replace(/_/g, " ");
}
function fo(t) {
switch (t) {
case "most_dimensions":
return "bg-dc-info-bg text-dc-info";
case "most_connected":
return "bg-dc-accent-bg text-dc-accent";
case "alphabetical_fallback":
return "bg-dc-warning-bg text-dc-warning";
case "single_cube":
return "bg-dc-success-bg text-dc-success";
default:
return "bg-dc-muted-bg text-dc-muted";
}
}
const ho = ({ analysis: t }) => {
const r = Q("info"), n = Q("chevronRight"), s = Q("warning"), a = Q("table"), c = Q("link"), l = Q("success"), u = Q("error");
return /* @__PURE__ */ o("div", { className: "bg-dc-surface-secondary border border-dc-border rounded-lg p-4 space-y-4", children: [
/* @__PURE__ */ o("div", { className: "border-b border-dc-border pb-3", children: [
/* @__PURE__ */ o("h4", { className: "text-sm font-semibold text-dc-text mb-2 flex items-center", children: [
/* @__PURE__ */ e(r, { className: "w-4 h-4 mr-2" }),
"Query Summary"
] }),
/* @__PURE__ */ o("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-2 text-xs", children: [
/* @__PURE__ */ o("div", { className: "bg-dc-surface p-2 rounded", children: [
/* @__PURE__ */ e("span", { className: "text-dc-text-muted", children: "Type:" }),
/* @__PURE__ */ e("span", { className: "ml-1 font-medium text-dc-text", children: vn(t.querySummary.queryType) })
] }),
/* @__PURE__ */ o("div", { className: "bg-dc-surface p-2 rounded", children: [
/* @__PURE__ */ e("span", { className: "text-dc-text-muted", children: "Cubes:" }),
/* @__PURE__ */ e("span", { className: "ml-1 font-medium text-dc-text", children: t.cubeCount })
] }),
/* @__PURE__ */ o("div", { className: "bg-dc-surface p-2 rounded", children: [
/* @__PURE__ */ e("span", { className: "text-dc-text-muted", children: "Joins:" }),
/* @__PURE__ */ e("span", { className: "ml-1 font-medium text-dc-text", children: t.querySummary.joinCount })
] }),
/* @__PURE__ */ o("div", { className: "bg-dc-surface p-2 rounded", children: [
/* @__PURE__ */ e("span", { className: "text-dc-text-muted", children: "CTEs:" }),
/* @__PURE__ */ e("span", { className: "ml-1 font-medium text-dc-text", children: t.querySummary.cteCount })
] })
] })
] }),
/* @__PURE__ */ o("div", { className: "border-b border-dc-border pb-3", children: [
/* @__PURE__ */ o("h4", { className: "text-sm font-semibold text-dc-text mb-2 flex items-center", children: [
/* @__PURE__ */ e(a, { className: "w-4 h-4 mr-2" }),
"Primary Cube (FROM table)"
] }),
/* @__PURE__ */ o("div", { className: "bg-dc-surface p-3 rounded text-sm", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 mb-2 flex-wrap", children: [
/* @__PURE__ */ e("span", { className: "font-mono font-medium text-dc-primary", children: t.primaryCube.selectedCube }),
/* @__PURE__ */ e("span", { className: `text-xs px-2 py-0.5 rounded ${fo(t.primaryCube.reason)}`, children: vn(t.primaryCube.reason) })
] }),
/* @__PURE__ */ e("p", { className: "text-dc-text-secondary text-xs", children: t.primaryCube.explanation }),
t.primaryCube.candidates && t.primaryCube.candidates.length > 1 && /* @__PURE__ */ o("details", { className: "mt-2", children: [
/* @__PURE__ */ o("summary", { className: "text-xs text-dc-text-muted cursor-pointer hover:text-dc-text", children: [
"Show candidates (",
t.primaryCube.candidates.length,
")"
] }),
/* @__PURE__ */ e("div", { className: "mt-2 space-y-1 ml-2", children: t.primaryCube.candidates.map((d, f) => /* @__PURE__ */ o("div", { className: "text-xs flex items-center gap-2 flex-wrap", children: [
/* @__PURE__ */ e("span", { className: `font-mono ${d.cubeName === t.primaryCube.selectedCube ? "font-bold text-dc-primary" : "text-dc-text-muted"}`, children: d.cubeName }),
/* @__PURE__ */ o("span", { className: "text-dc-text-muted", children: [
"dims: ",
d.dimensionCount,
", joins: ",
d.joinCount
] }),
d.canReachAll ? /* @__PURE__ */ o("span", { className: "text-dc-success flex items-center gap-0.5", children: [
/* @__PURE__ */ e(l, { className: "w-3 h-3" }),
"reachable"
] }) : /* @__PURE__ */ o("span", { className: "text-dc-error flex items-center gap-0.5", children: [
/* @__PURE__ */ e(u, { className: "w-3 h-3" }),
"cannot reach all"
] })
] }, f)) })
] })
] })
] }),
t.joinPaths.length > 0 && /* @__PURE__ */ o("div", { className: "border-b border-dc-border pb-3", children: [
/* @__PURE__ */ o("h4", { className: "text-sm font-semibold text-dc-text mb-2 flex items-center", children: [
/* @__PURE__ */ e(c, { className: "w-4 h-4 mr-2" }),
"Join Paths"
] }),
/* @__PURE__ */ e("div", { className: "space-y-2", children: t.joinPaths.map((d, f) => /* @__PURE__ */ o("div", { className: "bg-dc-surface p-3 rounded text-sm", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 mb-2 flex-wrap", children: [
/* @__PURE__ */ e("span", { className: "font-mono text-dc-text-secondary", children: t.primaryCube.selectedCube }),
/* @__PURE__ */ e(n, { className: "w-4 h-4 text-dc-text-muted" }),
/* @__PURE__ */ e("span", { className: "font-mono font-medium text-dc-text", children: d.targetCube }),
d.pathFound ? /* @__PURE__ */ o("span", { className: "text-xs px-2 py-0.5 bg-dc-success-bg text-dc-success rounded", children: [
d.pathLength,
" step",
d.pathLength !== 1 ? "s" : ""
] }) : /* @__PURE__ */ e("span", { className: "text-xs px-2 py-0.5 bg-dc-error-bg text-dc-error rounded", children: "No path" })
] }),
d.pathFound && d.path && d.path.length > 0 && /* @__PURE__ */ e("div", { className: "space-y-1 ml-2", children: d.path.map((h, p) => /* @__PURE__ */ o("div", { className: "flex items-center gap-1 text-xs flex-wrap", children: [
/* @__PURE__ */ e("span", { className: "font-mono text-dc-text-secondary", children: h.fromCube }),
/* @__PURE__ */ e(n, { className: "w-3 h-3 text-dc-text-muted" }),
/* @__PURE__ */ e("span", { className: "font-mono text-dc-text", children: h.toCube }),
/* @__PURE__ */ o("span", { className: "text-dc-text-muted", children: [
"(",
h.relationship,
", ",
h.joinType,
" join)"
] }),
h.joinColumns.length > 0 && /* @__PURE__ */ o("span", { className: "text-dc-text-muted", children: [
"on ",
h.joinColumns.map((m) => `${m.sourceColumn}=${m.targetColumn}`).join(", ")
] })
] }, p)) }),
!d.pathFound && d.error && /* @__PURE__ */ e("p", { className: "text-xs text-dc-error mt-1", children: d.error }),
d.visitedCubes && d.visitedCubes.length > 0 && !d.pathFound && /* @__PURE__ */ o("details", { className: "mt-1", children: [
/* @__PURE__ */ o("summary", { className: "text-xs text-dc-text-muted cursor-pointer hover:text-dc-text", children: [
"Cubes visited during search (",
d.visitedCubes.length,
")"
] }),
/* @__PURE__ */ e("div", { className: "mt-1 text-xs text-dc-text-muted ml-2", children: d.visitedCubes.join(" → ") })
] })
] }, f)) })
] }),
t.preAggregations.length > 0 && /* @__PURE__ */ o("div", { className: "border-b border-dc-border pb-3", children: [
/* @__PURE__ */ o("h4", { className: "text-sm font-semibold text-dc-text mb-2 flex items-center", children: [
/* @__PURE__ */ e(a, { className: "w-4 h-4 mr-2" }),
"Pre-Aggregation CTEs"
] }),
/* @__PURE__ */ e("div", { className: "space-y-2", children: t.preAggregations.map((d, f) => /* @__PURE__ */ o("div", { className: "bg-dc-surface p-3 rounded text-sm", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 mb-1 flex-wrap", children: [
/* @__PURE__ */ e("span", { className: "font-mono font-medium text-dc-text", children: d.cubeName }),
/* @__PURE__ */ e("span", { className: "text-xs text-dc-text-muted", children: "as" }),
/* @__PURE__ */ e("code", { className: "text-xs bg-dc-surface-secondary px-1 rounded font-mono", children: d.cteAlias })
] }),
/* @__PURE__ */ e("p", { className: "text-xs text-dc-text-secondary", children: d.reason }),
/* @__PURE__ */ o("div", { className: "mt-1 text-xs text-dc-text-muted", children: [
/* @__PURE__ */ e("span", { className: "font-medium", children: "Measures:" }),
" ",
d.measures.join(", ")
] }),
d.joinKeys.length > 0 && /* @__PURE__ */ o("div", { className: "mt-1 text-xs text-dc-text-muted", children: [
/* @__PURE__ */ e("span", { className: "font-medium", children: "Join keys:" }),
" ",
d.joinKeys.map((h) => `${h.sourceColumn}=${h.targetColumn}`).join(", ")
] })
] }, f)) })
] }),
t.warnings && t.warnings.length > 0 && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ o("h4", { className: "text-sm font-semibold text-dc-warning mb-2 flex items-center", children: [
/* @__PURE__ */ e(s, { className: "w-4 h-4 mr-2" }),
"Warnings"
] }),
/* @__PURE__ */ e("ul", { className: "list-disc list-inside text-xs text-dc-warning space-y-1", children: t.warnings.map((d, f) => /* @__PURE__ */ e("li", { children: d }, f)) })
] }),
t.cubesInvolved.length > 0 && /* @__PURE__ */ o("div", { className: "text-xs text-dc-text-muted pt-2 border-t border-dc-border", children: [
/* @__PURE__ */ e("span", { className: "font-medium", children: "Cubes involved:" }),
" ",
t.cubesInvolved.join(", ")
] })
] });
};
function po(t) {
return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
}
var Rr, wn;
function go() {
if (wn) return Rr;
wn = 1;
function t(k) {
return k instanceof Map ? k.clear = k.delete = k.set = function() {
throw new Error("map is read-only");
} : k instanceof Set && (k.add = k.clear = k.delete = function() {
throw new Error("set is read-only");
}), Object.freeze(k), Object.getOwnPropertyNames(k).forEach((z) => {
const ne = k[z], Ee = typeof ne;
(Ee === "object" || Ee === "function") && !Object.isFrozen(ne) && t(ne);
}), k;
}
class r {
/**
* @param {CompiledMode} mode
*/
constructor(z) {
z.data === void 0 && (z.data = {}), this.data = z.data, this.isMatchIgnored = !1;
}
ignoreMatch() {
this.isMatchIgnored = !0;
}
}
function n(k) {
return k.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}
function s(k, ...z) {
const ne = /* @__PURE__ */ Object.create(null);
for (const Ee in k)
ne[Ee] = k[Ee];
return z.forEach(function(Ee) {
for (const ze in Ee)
ne[ze] = Ee[ze];
}), /** @type {T} */
ne;
}
const a = "</span>", c = (k) => !!k.scope, l = (k, { prefix: z }) => {
if (k.startsWith("language:"))
return k.replace("language:", "language-");
if (k.includes(".")) {
const ne = k.split(".");
return [
`${z}${ne.shift()}`,
...ne.map((Ee, ze) => `${Ee}${"_".repeat(ze + 1)}`)
].join(" ");
}
return `${z}${k}`;
};
class u {
/**
* Creates a new HTMLRenderer
*
* @param {Tree} parseTree - the parse tree (must support `walk` API)
* @param {{classPrefix: string}} options
*/
constructor(z, ne) {
this.buffer = "", this.classPrefix = ne.classPrefix, z.walk(this);
}
/**
* Adds texts to the output stream
*
* @param {string} text */
addText(z) {
this.buffer += n(z);
}
/**
* Adds a node open to the output stream (if needed)
*
* @param {Node} node */
openNode(z) {
if (!c(z)) return;
const ne = l(
z.scope,
{ prefix: this.classPrefix }
);
this.span(ne);
}
/**
* Adds a node close to the output stream (if needed)
*
* @param {Node} node */
closeNode(z) {
c(z) && (this.buffer += a);
}
/**
* returns the accumulated buffer
*/
value() {
return this.buffer;
}
// helpers
/**
* Builds a span element
*
* @param {string} className */
span(z) {
this.buffer += `<span class="${z}">`;
}
}
const d = (k = {}) => {
const z = { children: [] };
return Object.assign(z, k), z;
};
class f {
constructor() {
this.rootNode = d(), this.stack = [this.rootNode];
}
get top() {
return this.stack[this.stack.length - 1];
}
get root() {
return this.rootNode;
}
/** @param {Node} node */
add(z) {
this.top.children.push(z);
}
/** @param {string} scope */
openNode(z) {
const ne = d({ scope: z });
this.add(ne), this.stack.push(ne);
}
closeNode() {
if (this.stack.length > 1)
return this.stack.pop();
}
closeAllNodes() {
for (; this.closeNode(); ) ;
}
toJSON() {
return JSON.stringify(this.rootNode, null, 4);
}
/**
* @typedef { import("./html_renderer").Renderer } Renderer
* @param {Renderer} builder
*/
walk(z) {
return this.constructor._walk(z, this.rootNode);
}
/**
* @param {Renderer} builder
* @param {Node} node
*/
static _walk(z, ne) {
return typeof ne == "string" ? z.addText(ne) : ne.children && (z.openNode(ne), ne.children.forEach((Ee) => this._walk(z, Ee)), z.closeNode(ne)), z;
}
/**
* @param {Node} node
*/
static _collapse(z) {
typeof z != "string" && z.children && (z.children.every((ne) => typeof ne == "string") ? z.children = [z.children.join("")] : z.children.forEach((ne) => {
f._collapse(ne);
}));
}
}
class h extends f {
/**
* @param {*} options
*/
constructor(z) {
super(), this.options = z;
}
/**
* @param {string} text
*/
addText(z) {
z !== "" && this.add(z);
}
/** @param {string} scope */
startScope(z) {
this.openNode(z);
}
endScope() {
this.closeNode();
}
/**
* @param {Emitter & {root: DataNode}} emitter
* @param {string} name
*/
__addSublanguage(z, ne) {
const Ee = z.root;
ne && (Ee.scope = `language:${ne}`), this.add(Ee);
}
toHTML() {
return new u(this, this.options).value();
}
finalize() {
return this.closeAllNodes(), !0;
}
}
function p(k) {
return k ? typeof k == "string" ? k : k.source : null;
}
function m(k) {
return _("(?=", k, ")");
}
function v(k) {
return _("(?:", k, ")*");
}
function C(k) {
return _("(?:", k, ")?");
}
function _(...k) {
return k.map((ne) => p(ne)).join("");
}
function b(k) {
const z = k[k.length - 1];
return typeof z == "object" && z.constructor === Object ? (k.splice(k.length - 1, 1), z) : {};
}
function R(...k) {
return "(" + (b(k).capture ? "" : "?:") + k.map((Ee) => p(Ee)).join("|") + ")";
}
function D(k) {
return new RegExp(k.toString() + "|").exec("").length - 1;
}
function $(k, z) {
const ne = k && k.exec(z);
return ne && ne.index === 0;
}
const A = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
function w(k, { joinWith: z }) {
let ne = 0;
return k.map((Ee) => {
ne += 1;
const ze = ne;
let Ge = p(Ee), he = "";
for (; Ge.length > 0; ) {
const me = A.exec(Ge);
if (!me) {
he += Ge;
break;
}
he += Ge.substring(0, me.index), Ge = Ge.substring(me.index + me[0].length), me[0][0] === "\\" && me[1] ? he += "\\" + String(Number(me[1]) + ze) : (he += me[0], me[0] === "(" && ne++);
}
return he;
}).map((Ee) => `(${Ee})`).join(z);
}
const i = /\b\B/, g = "[a-zA-Z]\\w*", x = "[a-zA-Z_]\\w*", N = "\\b\\d+(\\.\\d+)?", S = "(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)", y = "\\b(0b[01]+)", M = "!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", E = (k = {}) => {
const z = /^#![ ]*\//;
return k.binary && (k.begin = _(
z,
/.*\b/,
k.binary,
/\b.*/
)), s({
scope: "meta",
begin: z,
end: /$/,
relevance: 0,
/** @type {ModeCallback} */
"on:begin": (ne, Ee) => {
ne.index !== 0 && Ee.ignoreMatch();
}
}, k);
}, T = {
begin: "\\\\[\\s\\S]",
relevance: 0
}, j = {
scope: "string",
begin: "'",
end: "'",
illegal: "\\n",
contains: [T]
}, q = {
scope: "string",
begin: '"',
end: '"',
illegal: "\\n",
contains: [T]
}, I = {
begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
}, K = function(k, z, ne = {}) {
const Ee = s(
{
scope: "comment",
begin: k,
end: z,
contains: []
},
ne
);
Ee.contains.push({
scope: "doctag",
// hack to avoid the space from being included. the space is necessary to
// match here to prevent the plain text rule below from gobbling up doctags
begin: "[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",
end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,
excludeBegin: !0,
relevance: 0
});
const ze = R(
// list of common 1 and 2 letter words in English
"I",
"a",
"is",
"so",
"us",
"to",
"at",
"if",
"in",
"it",
"on",
// note: this is not an exhaustive list of contractions, just popular ones
/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,
// contractions - can't we'd they're let's, etc
/[A-Za-z]+[-][a-z]+/,
// `no-way`, etc.
/[A-Za-z][a-z]{2,}/
// allow capitalized words at beginning of sentences
);
return Ee.contains.push(
{
// TODO: how to include ", (, ) without breaking grammars that use these for
// comment delimiters?
// begin: /[ ]+([()"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()":]?([.][ ]|[ ]|\))){3}/
// ---
// this tries to find sequences of 3 english words in a row (without any
// "programming" type syntax) this gives us a strong signal that we've
// TRULY found a comment - vs perhaps scanning with the wrong language.
// It's possible to find something that LOOKS like the start of the
// comment - but then if there is no readable text - good chance it is a
// false match and not a comment.
//
// for a visual example please see:
// https://github.com/highlightjs/highlight.js/issues/2827
begin: _(
/[ ]+/,
// necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */
"(",
ze,
/[.]?[:]?([.][ ]|[ ])/,
"){3}"
)
// look for 3 words in a row
}
), Ee;
}, U = K("//", "$"), ke = K("/\\*", "\\*/"), De = K("#", "$"), Pe = {
scope: "number",
begin: N,
relevance: 0
}, B = {
scope: "number",
begin: S,
relevance: 0
}, se = {
scope: "number",
begin: y,
relevance: 0
}, Te = {
scope: "regexp",
begin: /\/(?=[^/\n]*\/)/,
end: /\/[gimuy]*/,
contains: [
T,
{
begin: /\[/,
end: /\]/,
relevance: 0,
contains: [T]
}
]
}, H = {
scope: "title",
begin: g,
relevance: 0
}, ee = {
scope: "title",
begin: x,
relevance: 0
}, le = {
// excludes method names from keyword processing
begin: "\\.\\s*" + x,
relevance: 0
};
var L = /* @__PURE__ */ Object.freeze({
__proto__: null,
APOS_STRING_MODE: j,
BACKSLASH_ESCAPE: T,
BINARY_NUMBER_MODE: se,
BINARY_NUMBER_RE: y,
COMMENT: K,
C_BLOCK_COMMENT_MODE: ke,
C_LINE_COMMENT_MODE: U,
C_NUMBER_MODE: B,
C_NUMBER_RE: S,
END_SAME_AS_BEGIN: function(k) {
return Object.assign(
k,
{
/** @type {ModeCallback} */
"on:begin": (z, ne) => {
ne.data._beginMatch = z[1];
},
/** @type {ModeCallback} */
"on:end": (z, ne) => {
ne.data._beginMatch !== z[1] && ne.ignoreMatch();
}
}
);
},
HASH_COMMENT_MODE: De,
IDENT_RE: g,
MATCH_NOTHING_RE: i,
METHOD_GUARD: le,
NUMBER_MODE: Pe,
NUMBER_RE: N,
PHRASAL_WORDS_MODE: I,
QUOTE_STRING_MODE: q,
REGEXP_MODE: Te,
RE_STARTERS_RE: M,
SHEBANG: E,
TITLE_MODE: H,
UNDERSCORE_IDENT_RE: x,
UNDERSCORE_TITLE_MODE: ee
});
function te(k, z) {
k.input[k.index - 1] === "." && z.ignoreMatch();
}
function Ne(k, z) {
k.className !== void 0 && (k.scope = k.className, delete k.className);
}
function Ve(k, z) {
z && k.beginKeywords && (k.begin = "\\b(" + k.beginKeywords.split(" ").join("|") + ")(?!\\.)(?=\\b|\\s)", k.__beforeBegin = te, k.keywords = k.keywords || k.beginKeywords, delete k.beginKeywords, k.relevance === void 0 && (k.relevance = 0));
}
function rt(k, z) {
Array.isArray(k.illegal) && (k.illegal = R(...k.illegal));
}
function Fe(k, z) {
if (k.match) {
if (k.begin || k.end) throw new Error("begin & end are not supported with match");
k.begin = k.match, delete k.match;
}
}
function ue(k, z) {
k.relevance === void 0 && (k.relevance = 1);
}
const _e = (k, z) => {
if (!k.beforeMatch) return;
if (k.starts) throw new Error("beforeMatch cannot be used with starts");
const ne = Object.assign({}, k);
Object.keys(k).forEach((Ee) => {
delete k[Ee];
}), k.keywords = ne.keywords, k.begin = _(ne.beforeMatch, m(ne.begin)), k.starts = {
relevance: 0,
contains: [
Object.assign(ne, { endsParent: !0 })
]
}, k.relevance = 0, delete ne.beforeMatch;
}, G = [
"of",
"and",
"for",
"in",
"not",
"or",
"if",
"then",
"parent",
// common variable name
"list",
// common variable name
"value"
// common variable name
], X = "keyword";
function ae(k, z, ne = X) {
const Ee = /* @__PURE__ */ Object.create(null);
return typeof k == "string" ? ze(ne, k.split(" ")) : Array.isArray(k) ? ze(ne, k) : Object.keys(k).forEach(function(Ge) {
Object.assign(
Ee,
ae(k[Ge], z, Ge)
);
}), Ee;
function ze(Ge, he) {
z && (he = he.map((me) => me.toLowerCase())), he.forEach(function(me) {
const Se = me.split("|");
Ee[Se[0]] = [Ge, qe(Se[0], Se[1])];
});
}
}
function qe(k, z) {
return z ? Number(z) : je(k) ? 0 : 1;
}
function je(k) {
return G.includes(k.toLowerCase());
}
const nt = {}, Ie = (k) => {
console.error(k);
}, Be = (k, ...z) => {
console.log(`WARN: ${k}`, ...z);
}, ot = (k, z) => {
nt[`${k}/${z}`] || (console.log(`Deprecated as of ${k}. ${z}`), nt[`${k}/${z}`] = !0);
}, at = new Error();
function bt(k, z, { key: ne }) {
let Ee = 0;
const ze = k[ne], Ge = {}, he = {};
for (let me = 1; me <= z.length; me++)
he[me + Ee] = ze[me], Ge[me + Ee] = !0, Ee += D(z[me - 1]);
k[ne] = he, k[ne]._emit = Ge, k[ne]._multi = !0;
}
function ft(k) {
if (Array.isArray(k.begin)) {
if (k.skip || k.excludeBegin || k.returnBegin)
throw Ie("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), at;
if (typeof k.beginScope != "object" || k.beginScope === null)
throw Ie("beginScope must be object"), at;
bt(k, k.begin, { key: "beginScope" }), k.begin = w(k.begin, { joinWith: "" });
}
}
function Dt(k) {
if (Array.isArray(k.end)) {
if (k.skip || k.excludeEnd || k.returnEnd)
throw Ie("skip, excludeEnd, returnEnd not compatible with endScope: {}"), at;
if (typeof k.endScope != "object" || k.endScope === null)
throw Ie("endScope must be object"), at;
bt(k, k.end, { key: "endScope" }), k.end = w(k.end, { joinWith: "" });
}
}
function Qe(k) {
k.scope && typeof k.scope == "object" && k.scope !== null && (k.beginScope = k.scope, delete k.scope);
}
function Ze(k) {
Qe(k), typeof k.beginScope == "string" && (k.beginScope = { _wrap: k.beginScope }), typeof k.endScope == "string" && (k.endScope = { _wrap: k.endScope }), ft(k), Dt(k);
}
function et(k) {
function z(he, me) {
return new RegExp(
p(he),
"m" + (k.case_insensitive ? "i" : "") + (k.unicodeRegex ? "u" : "") + (me ? "g" : "")
);
}
class ne {
constructor() {
this.matchIndexes = {}, this.regexes = [], this.matchAt = 1, this.position = 0;
}
// @ts-ignore
addRule(me, Se) {
Se.position = this.position++, this.matchIndexes[this.matchAt] = Se, this.regexes.push([Se, me]), this.matchAt += D(me) + 1;
}
compile() {
this.regexes.length === 0 && (this.exec = () => null);
const me = this.regexes.map((Se) => Se[1]);
this.matcherRe = z(w(me, { joinWith: "|" }), !0), this.lastIndex = 0;
}
/** @param {string} s */
exec(me) {
this.matcherRe.lastIndex = this.lastIndex;
const Se = this.matcherRe.exec(me);
if (!Se)
return null;
const tt = Se.findIndex((At, Ut) => Ut > 0 && At !== void 0), Ye = this.matchIndexes[tt];
return Se.splice(0, tt), Object.assign(Se, Ye);
}
}
class Ee {
constructor() {
this.rules = [], this.multiRegexes = [], this.count = 0, this.lastIndex = 0, this.regexIndex = 0;
}
// @ts-ignore
getMatcher(me) {
if (this.multiRegexes[me]) return this.multiRegexes[me];
const Se = new ne();
return this.rules.slice(me).forEach(([tt, Ye]) => Se.addRule(tt, Ye)), Se.compile(), this.multiRegexes[me] = Se, Se;
}
resumingScanAtSamePosition() {
return this.regexIndex !== 0;
}
considerAll() {
this.regexIndex = 0;
}
// @ts-ignore
addRule(me, Se) {
this.rules.push([me, Se]), Se.type === "begin" && this.count++;
}
/** @param {string} s */
exec(me) {
const Se = this.getMatcher(this.regexIndex);
Se.lastIndex = this.lastIndex;
let tt = Se.exec(me);
if (this.resumingScanAtSamePosition() && !(tt && tt.index === this.lastIndex)) {
const Ye = this.getMatcher(0);
Ye.lastIndex = this.lastIndex + 1, tt = Ye.exec(me);
}
return tt && (this.regexIndex += tt.position + 1, this.regexIndex === this.count && this.considerAll()), tt;
}
}
function ze(he) {
const me = new Ee();
return he.contains.forEach((Se) => me.addRule(Se.begin, { rule: Se, type: "begin" })), he.terminatorEnd && me.addRule(he.terminatorEnd, { type: "end" }), he.illegal && me.addRule(he.illegal, { type: "illegal" }), me;
}
function Ge(he, me) {
const Se = (
/** @type CompiledMode */
he
);
if (he.isCompiled) return Se;
[
Ne,
// do this early so compiler extensions generally don't have to worry about
// the distinction between match/begin
Fe,
Ze,
_e
].forEach((Ye) => Ye(he, me)), k.compilerExtensions.forEach((Ye) => Ye(he, me)), he.__beforeBegin = null, [
Ve,
// do this later so compiler extensions that come earlier have access to the
// raw array if they wanted to perhaps manipulate it, etc.
rt,
// default to 1 relevance if not specified
ue
].forEach((Ye) => Ye(he, me)), he.isCompiled = !0;
let tt = null;
return typeof he.keywords == "object" && he.keywords.$pattern && (he.keywords = Object.assign({}, he.keywords), tt = he.keywords.$pattern, delete he.keywords.$pattern), tt = tt || /\w+/, he.keywords && (he.keywords = ae(he.keywords, k.case_insensitive)), Se.keywordPatternRe = z(tt, !0), me && (he.begin || (he.begin = /\B|\b/), Se.beginRe = z(Se.begin), !he.end && !he.endsWithParent && (he.end = /\B|\b/), he.end && (Se.endRe = z(Se.end)), Se.terminatorEnd = p(Se.end) || "", he.endsWithParent && me.terminatorEnd && (Se.terminatorEnd += (he.end ? "|" : "") + me.terminatorEnd)), he.illegal && (Se.illegalRe = z(
/** @type {RegExp | string} */
he.illegal
)), he.contains || (he.contains = []), he.contains = [].concat(...he.contains.map(function(Ye) {
return Tt(Ye === "self" ? he : Ye);
})), he.contains.forEach(function(Ye) {
Ge(
/** @type Mode */
Ye,
Se
);
}), he.starts && Ge(he.starts, me), Se.matcher = ze(Se), Se;
}
if (k.compilerExtensions || (k.compilerExtensions = []), k.contains && k.contains.includes("self"))
throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");
return k.classNameAliases = s(k.classNameAliases || {}), Ge(
/** @type Mode */
k
);
}
function xt(k) {
return k ? k.endsWithParent || xt(k.starts) : !1;
}
function Tt(k) {
return k.variants && !k.cachedVariants && (k.cachedVariants = k.variants.map(function(z) {
return s(k, { variants: null }, z);
})), k.cachedVariants ? k.cachedVariants : xt(k) ? s(k, { starts: k.starts ? s(k.starts) : null }) : Object.isFrozen(k) ? s(k) : k;
}
var $t = "11.11.1";
class St extends Error {
constructor(z, ne) {
super(z), this.name = "HTMLInjectionError", this.html = ne;
}
}
const st = n, dt = s, ht = /* @__PURE__ */ Symbol("nomatch"), It = 7, Pt = function(k) {
const z = /* @__PURE__ */ Object.create(null), ne = /* @__PURE__ */ Object.create(null), Ee = [];
let ze = !0;
const Ge = "Could not find the language '{}', did you forget to load/include a language module?", he = { disableAutodetect: !0, name: "Plain text", contains: [] };
let me = {
ignoreUnescapedHTML: !1,
throwUnescapedHTML: !1,
noHighlightRe: /^(no-?highlight)$/i,
languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i,
classPrefix: "hljs-",
cssSelector: "pre code",
languages: null,
// beta configuration options, subject to change, welcome to discuss
// https://github.com/highlightjs/highlight.js/issues/1086
__emitter: h
};
function Se(J) {
return me.noHighlightRe.test(J);
}
function tt(J) {
let ge = J.className + " ";
ge += J.parentNode ? J.parentNode.className : "";
const O = me.languageDetectRe.exec(ge);
if (O) {
const P = Ue(O[1]);
return P || (Be(Ge.replace("{}", O[1])), Be("Falling back to no-highlight mode for this block.", J)), P ? O[1] : "no-highlight";
}
return ge.split(/\s+/).find((P) => Se(P) || Ue(P));
}
function Ye(J, ge, O) {
let P = "", W = "";
typeof ge == "object" ? (P = J, O = ge.ignoreIllegals, W = ge.language) : (ot("10.7.0", "highlight(lang, code, ...args) has been deprecated."), ot("10.7.0", `Please use highlight(code, options) instead.
https://github.com/highlightjs/highlight.js/issues/2277`), W = J, P = ge), O === void 0 && (O = !0);
const Z = {
code: P,
language: W
};
Nt("before:highlight", Z);
const ie = Z.result ? Z.result : At(Z.language, Z.code, O);
return ie.code = Z.code, Nt("after:highlight", ie), ie;
}
function At(J, ge, O, P) {
const W = /* @__PURE__ */ Object.create(null);
function Z(ce, we) {
return ce.keywords[we];
}
function ie() {
if (!Me.keywords) {
ct.addText(We);
return;
}
let ce = 0;
Me.keywordPatternRe.lastIndex = 0;
let we = Me.keywordPatternRe.exec(We), Le = "";
for (; we; ) {
Le += We.substring(ce, we.index);
const He = Ct.case_insensitive ? we[0].toLowerCase() : we[0], lt = Z(Me, He);
if (lt) {
const [Et, Us] = lt;
if (ct.addText(Le), Le = "", W[He] = (W[He] || 0) + 1, W[He] <= It && (lr += Us), Et.startsWith("_"))
Le += we[0];
else {
const Hs = Ct.classNameAliases[Et] || Et;
Xe(we[0], Hs);
}
} else
Le += we[0];
ce = Me.keywordPatternRe.lastIndex, we = Me.keywordPatternRe.exec(We);
}
Le += We.substring(ce), ct.addText(Le);
}
function xe() {
if (We === "") return;
let ce = null;
if (typeof Me.subLanguage == "string") {
if (!z[Me.subLanguage]) {
ct.addText(We);
return;
}
ce = At(Me.subLanguage, We, !0, cn[Me.subLanguage]), cn[Me.subLanguage] = /** @type {CompiledMode} */
ce._top;
} else
ce = Ht(We, Me.subLanguage.length ? Me.subLanguage : null);
Me.relevance > 0 && (lr += ce.relevance), ct.__addSublanguage(ce._emitter, ce.language);
}
function Re() {
Me.subLanguage != null ? xe() : ie(), We = "";
}
function Xe(ce, we) {
ce !== "" && (ct.startScope(we), ct.addText(ce), ct.endScope());
}
function it(ce, we) {
let Le = 1;
const He = we.length - 1;
for (; Le <= He; ) {
if (!ce._emit[Le]) {
Le++;
continue;
}
const lt = Ct.classNameAliases[ce[Le]] || ce[Le], Et = we[Le];
lt ? Xe(Et, lt) : (We = Et, ie(), We = ""), Le++;
}
}
function yt(ce, we) {
return ce.scope && typeof ce.scope == "string" && ct.openNode(Ct.classNameAliases[ce.scope] || ce.scope), ce.beginScope && (ce.beginScope._wrap ? (Xe(We, Ct.classNameAliases[ce.beginScope._wrap] || ce.beginScope._wrap), We = "") : ce.beginScope._multi && (it(ce.beginScope, we), We = "")), Me = Object.create(ce, { parent: { value: Me } }), Me;
}
function an(ce, we, Le) {
let He = $(ce.endRe, Le);
if (He) {
if (ce["on:end"]) {
const lt = new r(ce);
ce["on:end"](we, lt), lt.isMatchIgnored && (He = !1);
}
if (He) {
for (; ce.endsParent && ce.parent; )
ce = ce.parent;
return ce;
}
}
if (ce.endsWithParent)
return an(ce.parent, we, Le);
}
function Ps(ce) {
return Me.matcher.regexIndex === 0 ? (We += ce[0], 1) : (_r = !0, 0);
}
function js(ce) {
const we = ce[0], Le = ce.rule, He = new r(Le), lt = [Le.__beforeBegin, Le["on:begin"]];
for (const Et of lt)
if (Et && (Et(ce, He), He.isMatchIgnored))
return Ps(we);
return Le.skip ? We += we : (Le.excludeBegin && (We += we), Re(), !Le.returnBegin && !Le.excludeBegin && (We = we)), yt(Le, ce), Le.returnBegin ? 0 : we.length;
}
function Bs(ce) {
const we = ce[0], Le = ge.substring(ce.index), He = an(Me, ce, Le);
if (!He)
return ht;
const lt = Me;
Me.endScope && Me.endScope._wrap ? (Re(), Xe(we, Me.endScope._wrap)) : Me.endScope && Me.endScope._multi ? (Re(), it(Me.endScope, ce)) : lt.skip ? We += we : (lt.returnEnd || lt.excludeEnd || (We += we), Re(), lt.excludeEnd && (We = we));
do
Me.scope && ct.closeNode(), !Me.skip && !Me.subLanguage && (lr += Me.relevance), Me = Me.parent;
while (Me !== He.parent);
return He.starts && yt(He.starts, ce), lt.returnEnd ? 0 : we.length;
}
function Vs() {
const ce = [];
for (let we = Me; we !== Ct; we = we.parent)
we.scope && ce.unshift(we.scope);
ce.forEach((we) => ct.openNode(we));
}
let cr = {};
function on(ce, we) {
const Le = we && we[0];
if (We += ce, Le == null)
return Re(), 0;
if (cr.type === "begin" && we.type === "end" && cr.index === we.index && Le === "") {
if (We += ge.slice(we.index, we.index + 1), !ze) {
const He = new Error(`0 width match regex (${J})`);
throw He.languageName = J, He.badRule = cr.rule, He;
}
return 1;
}
if (cr = we, we.type === "begin")
return js(we);
if (we.type === "illegal" && !O) {
const He = new Error('Illegal lexeme "' + Le + '" for mode "' + (Me.scope || "<unnamed>") + '"');
throw He.mode = Me, He;
} else if (we.type === "end") {
const He = Bs(we);
if (He !== ht)
return He;
}
if (we.type === "illegal" && Le === "")
return We += `
`, 1;
if (Er > 1e5 && Er > we.index * 3)
throw new Error("potential infinite loop, way more iterations than matches");
return We += Le, Le.length;
}
const Ct = Ue(J);
if (!Ct)
throw Ie(Ge.replace("{}", J)), new Error('Unknown language: "' + J + '"');
const Qs = et(Ct);
let Ar = "", Me = P || Qs;
const cn = {}, ct = new me.__emitter(me);
Vs();
let We = "", lr = 0, Bt = 0, Er = 0, _r = !1;
try {
if (Ct.__emitTokens)
Ct.__emitTokens(ge, ct);
else {
for (Me.matcher.considerAll(); ; ) {
Er++, _r ? _r = !1 : Me.matcher.considerAll(), Me.matcher.lastIndex = Bt;
const ce = Me.matcher.exec(ge);
if (!ce) break;
const we = ge.substring(Bt, ce.index), Le = on(we, ce);
Bt = ce.index + Le;
}
on(ge.substring(Bt));
}
return ct.finalize(), Ar = ct.toHTML(), {
language: J,
value: Ar,
relevance: lr,
illegal: !1,
_emitter: ct,
_top: Me
};
} catch (ce) {
if (ce.message && ce.message.includes("Illegal"))
return {
language: J,
value: st(ge),
illegal: !0,
relevance: 0,
_illegalBy: {
message: ce.message,
index: Bt,
context: ge.slice(Bt - 100, Bt + 100),
mode: ce.mode,
resultSoFar: Ar
},
_emitter: ct
};
if (ze)
return {
language: J,
value: st(ge),
illegal: !1,
relevance: 0,
errorRaised: ce,
_emitter: ct,
_top: Me
};
throw ce;
}
}
function Ut(J) {
const ge = {
value: st(J),
illegal: !1,
relevance: 0,
_top: he,
_emitter: new me.__emitter(me)
};
return ge._emitter.addText(J), ge;
}
function Ht(J, ge) {
ge = ge || me.languages || Object.keys(z);
const O = Ut(J), P = ge.filter(Ue).filter(Ke).map(
(Re) => At(Re, J, !1)
);
P.unshift(O);
const W = P.sort((Re, Xe) => {
if (Re.relevance !== Xe.relevance) return Xe.relevance - Re.relevance;
if (Re.language && Xe.language) {
if (Ue(Re.language).supersetOf === Xe.language)
return 1;
if (Ue(Xe.language).supersetOf === Re.language)
return -1;
}
return 0;
}), [Z, ie] = W, xe = Z;
return xe.secondBest = ie, xe;
}
function zt(J, ge, O) {
const P = ge && ne[ge] || O;
J.classList.add("hljs"), J.classList.add(`language-${P}`);
}
function Gt(J) {
let ge = null;
const O = tt(J);
if (Se(O)) return;
if (Nt(
"before:highlightElement",
{ el: J, language: O }
), J.dataset.highlighted) {
console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.", J);
return;
}
if (J.children.length > 0 && (me.ignoreUnescapedHTML || (console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), console.warn("The element with unescaped HTML:"), console.warn(J)), me.throwUnescapedHTML))
throw new St(
"One of your code blocks includes unescaped HTML.",
J.innerHTML
);
ge = J;
const P = ge.textContent, W = O ? Ye(P, { language: O, ignoreIllegals: !0 }) : Ht(P);
J.innerHTML = W.value, J.dataset.highlighted = "yes", zt(J, O, W.language), J.result = {
language: W.language,
// TODO: remove with version 11.0
re: W.relevance,
relevance: W.relevance
}, W.secondBest && (J.secondBest = {
language: W.secondBest.language,
relevance: W.secondBest.relevance
}), Nt("after:highlightElement", { el: J, result: W, text: P });
}
function Y(J) {
me = dt(me, J);
}
const re = () => {
fe(), ot("10.6.0", "initHighlighting() deprecated. Use highlightAll() now.");
};
function de() {
fe(), ot("10.6.0", "initHighlightingOnLoad() deprecated. Use highlightAll() now.");
}
let oe = !1;
function fe() {
function J() {
fe();
}
if (document.readyState === "loading") {
oe || window.addEventListener("DOMContentLoaded", J, !1), oe = !0;
return;
}
document.querySelectorAll(me.cssSelector).forEach(Gt);
}
function $e(J, ge) {
let O = null;
try {
O = ge(k);
} catch (P) {
if (Ie("Language definition for '{}' could not be registered.".replace("{}", J)), ze)
Ie(P);
else
throw P;
O = he;
}
O.name || (O.name = J), z[J] = O, O.rawDefinition = ge.bind(null, k), O.aliases && Je(O.aliases, { languageName: J });
}
function pe(J) {
delete z[J];
for (const ge of Object.keys(ne))
ne[ge] === J && delete ne[ge];
}
function Ae() {
return Object.keys(z);
}
function Ue(J) {
return J = (J || "").toLowerCase(), z[J] || z[ne[J]];
}
function Je(J, { languageName: ge }) {
typeof J == "string" && (J = [J]), J.forEach((O) => {
ne[O.toLowerCase()] = ge;
});
}
function Ke(J) {
const ge = Ue(J);
return ge && !ge.disableAutodetect;
}
function ut(J) {
J["before:highlightBlock"] && !J["before:highlightElement"] && (J["before:highlightElement"] = (ge) => {
J["before:highlightBlock"](
Object.assign({ block: ge.el }, ge)
);
}), J["after:highlightBlock"] && !J["after:highlightElement"] && (J["after:highlightElement"] = (ge) => {
J["after:highlightBlock"](
Object.assign({ block: ge.el }, ge)
);
});
}
function mt(J) {
ut(J), Ee.push(J);
}
function gt(J) {
const ge = Ee.indexOf(J);
ge !== -1 && Ee.splice(ge, 1);
}
function Nt(J, ge) {
const O = J;
Ee.forEach(function(P) {
P[O] && P[O](ge);
});
}
function jt(J) {
return ot("10.7.0", "highlightBlock will be removed entirely in v12.0"), ot("10.7.0", "Please use highlightElement now."), Gt(J);
}
Object.assign(k, {
highlight: Ye,
highlightAuto: Ht,
highlightAll: fe,
highlightElement: Gt,
// TODO: Remove with v12 API
highlightBlock: jt,
configure: Y,
initHighlighting: re,
initHighlightingOnLoad: de,
registerLanguage: $e,
unregisterLanguage: pe,
listLanguages: Ae,
getLanguage: Ue,
registerAliases: Je,
autoDetection: Ke,
inherit: dt,
addPlugin: mt,
removePlugin: gt
}), k.debugMode = function() {
ze = !1;
}, k.safeMode = function() {
ze = !0;
}, k.versionString = $t, k.regex = {
concat: _,
lookahead: m,
either: R,
optional: C,
anyNumberOfTimes: v
};
for (const J in L)
typeof L[J] == "object" && t(L[J]);
return Object.assign(k, L), k;
}, pt = Pt({});
return pt.newInstance = () => Pt({}), Rr = pt, pt.HighlightJS = pt, pt.default = pt, Rr;
}
var bo = /* @__PURE__ */ go();
const Kr = /* @__PURE__ */ po(bo);
function bs(t) {
const r = {
className: "attr",
begin: /"(\\.|[^\\"\r\n])*"(?=\s*:)/,
relevance: 1.01
}, n = {
match: /[{}[\],:]/,
className: "punctuation",
relevance: 0
}, s = [
"true",
"false",
"null"
], a = {
scope: "literal",
beginKeywords: s.join(" ")
};
return {
name: "JSON",
aliases: ["jsonc"],
keywords: {
literal: s
},
contains: [
r,
n,
t.QUOTE_STRING_MODE,
a,
t.C_NUMBER_MODE,
t.C_LINE_COMMENT_MODE,
t.C_BLOCK_COMMENT_MODE
],
illegal: "\\S"
};
}
const xo = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
default: bs
}, Symbol.toStringTag, { value: "Module" }));
function xs(t) {
const r = t.regex, n = t.COMMENT("--", "$"), s = {
scope: "string",
variants: [
{
begin: /'/,
end: /'/,
contains: [{ match: /''/ }]
}
]
}, a = {
begin: /"/,
end: /"/,
contains: [{ match: /""/ }]
}, c = [
"true",
"false",
// Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way.
// "null",
"unknown"
], l = [
"double precision",
"large object",
"with timezone",
"without timezone"
], u = [
"bigint",
"binary",
"blob",
"boolean",
"char",
"character",
"clob",
"date",
"dec",
"decfloat",
"decimal",
"float",
"int",
"integer",
"interval",
"nchar",
"nclob",
"national",
"numeric",
"real",
"row",
"smallint",
"time",
"timestamp",
"varchar",
"varying",
// modifier (character varying)
"varbinary"
], d = [
"add",
"asc",
"collation",
"desc",
"final",
"first",
"last",
"view"
], f = [
"abs",
"acos",
"all",
"allocate",
"alter",
"and",
"any",
"are",
"array",
"array_agg",
"array_max_cardinality",
"as",
"asensitive",
"asin",
"asymmetric",
"at",
"atan",
"atomic",
"authorization",
"avg",
"begin",
"begin_frame",
"begin_partition",
"between",
"bigint",
"binary",
"blob",
"boolean",
"both",
"by",
"call",
"called",
"cardinality",
"cascaded",
"case",
"cast",
"ceil",
"ceiling",
"char",
"char_length",
"character",
"character_length",
"check",
"classifier",
"clob",
"close",
"coalesce",
"collate",
"collect",
"column",
"commit",
"condition",
"connect",
"constraint",
"contains",
"convert",
"copy",
"corr",
"corresponding",
"cos",
"cosh",
"count",
"covar_pop",
"covar_samp",
"create",
"cross",
"cube",
"cume_dist",
"current",
"current_catalog",
"current_date",
"current_default_transform_group",
"current_path",
"current_role",
"current_row",
"current_schema",
"current_time",
"current_timestamp",
"current_path",
"current_role",
"current_transform_group_for_type",
"current_user",
"cursor",
"cycle",
"date",
"day",
"deallocate",
"dec",
"decimal",
"decfloat",
"declare",
"default",
"define",
"delete",
"dense_rank",
"deref",
"describe",
"deterministic",
"disconnect",
"distinct",
"double",
"drop",
"dynamic",
"each",
"element",
"else",
"empty",
"end",
"end_frame",
"end_partition",
"end-exec",
"equals",
"escape",
"every",
"except",
"exec",
"execute",
"exists",
"exp",
"external",
"extract",
"false",
"fetch",
"filter",
"first_value",
"float",
"floor",
"for",
"foreign",
"frame_row",
"free",
"from",
"full",
"function",
"fusion",
"get",
"global",
"grant",
"group",
"grouping",
"groups",
"having",
"hold",
"hour",
"identity",
"in",
"indicator",
"initial",
"inner",
"inout",
"insensitive",
"insert",
"int",
"integer",
"intersect",
"intersection",
"interval",
"into",
"is",
"join",
"json_array",
"json_arrayagg",
"json_exists",
"json_object",
"json_objectagg",
"json_query",
"json_table",
"json_table_primitive",
"json_value",
"lag",
"language",
"large",
"last_value",
"lateral",
"lead",
"leading",
"left",
"like",
"like_regex",
"listagg",
"ln",
"local",
"localtime",
"localtimestamp",
"log",
"log10",
"lower",
"match",
"match_number",
"match_recognize",
"matches",
"max",
"member",
"merge",
"method",
"min",
"minute",
"mod",
"modifies",
"module",
"month",
"multiset",
"national",
"natural",
"nchar",
"nclob",
"new",
"no",
"none",
"normalize",
"not",
"nth_value",
"ntile",
"null",
"nullif",
"numeric",
"octet_length",
"occurrences_regex",
"of",
"offset",
"old",
"omit",
"on",
"one",
"only",
"open",
"or",
"order",
"out",
"outer",
"over",
"overlaps",
"overlay",
"parameter",
"partition",
"pattern",
"per",
"percent",
"percent_rank",
"percentile_cont",
"percentile_disc",
"period",
"portion",
"position",
"position_regex",
"power",
"precedes",
"precision",
"prepare",
"primary",
"procedure",
"ptf",
"range",
"rank",
"reads",
"real",
"recursive",
"ref",
"references",
"referencing",
"regr_avgx",
"regr_avgy",
"regr_count",
"regr_intercept",
"regr_r2",
"regr_slope",
"regr_sxx",
"regr_sxy",
"regr_syy",
"release",
"result",
"return",
"returns",
"revoke",
"right",
"rollback",
"rollup",
"row",
"row_number",
"rows",
"running",
"savepoint",
"scope",
"scroll",
"search",
"second",
"seek",
"select",
"sensitive",
"session_user",
"set",
"show",
"similar",
"sin",
"sinh",
"skip",
"smallint",
"some",
"specific",
"specifictype",
"sql",
"sqlexception",
"sqlstate",
"sqlwarning",
"sqrt",
"start",
"static",
"stddev_pop",
"stddev_samp",
"submultiset",
"subset",
"substring",
"substring_regex",
"succeeds",
"sum",
"symmetric",
"system",
"system_time",
"system_user",
"table",
"tablesample",
"tan",
"tanh",
"then",
"time",
"timestamp",
"timezone_hour",
"timezone_minute",
"to",
"trailing",
"translate",
"translate_regex",
"translation",
"treat",
"trigger",
"trim",
"trim_array",
"true",
"truncate",
"uescape",
"union",
"unique",
"unknown",
"unnest",
"update",
"upper",
"user",
"using",
"value",
"values",
"value_of",
"var_pop",
"var_samp",
"varbinary",
"varchar",
"varying",
"versioning",
"when",
"whenever",
"where",
"width_bucket",
"window",
"with",
"within",
"without",
"year"
], h = [
"abs",
"acos",
"array_agg",
"asin",
"atan",
"avg",
"cast",
"ceil",
"ceiling",
"coalesce",
"corr",
"cos",
"cosh",
"count",
"covar_pop",
"covar_samp",
"cume_dist",
"dense_rank",
"deref",
"element",
"exp",
"extract",
"first_value",
"floor",
"json_array",
"json_arrayagg",
"json_exists",
"json_object",
"json_objectagg",
"json_query",
"json_table",
"json_table_primitive",
"json_value",
"lag",
"last_value",
"lead",
"listagg",
"ln",
"log",
"log10",
"lower",
"max",
"min",
"mod",
"nth_value",
"ntile",
"nullif",
"percent_rank",
"percentile_cont",
"percentile_disc",
"position",
"position_regex",
"power",
"rank",
"regr_avgx",
"regr_avgy",
"regr_count",
"regr_intercept",
"regr_r2",
"regr_slope",
"regr_sxx",
"regr_sxy",
"regr_syy",
"row_number",
"sin",
"sinh",
"sqrt",
"stddev_pop",
"stddev_samp",
"substring",
"substring_regex",
"sum",
"tan",
"tanh",
"translate",
"translate_regex",
"treat",
"trim",
"trim_array",
"unnest",
"upper",
"value_of",
"var_pop",
"var_samp",
"width_bucket"
], p = [
"current_catalog",
"current_date",
"current_default_transform_group",
"current_path",
"current_role",
"current_schema",
"current_transform_group_for_type",
"current_user",
"session_user",
"system_time",
"system_user",
"current_time",
"localtime",
"current_timestamp",
"localtimestamp"
], m = [
"create table",
"insert into",
"primary key",
"foreign key",
"not null",
"alter table",
"add constraint",
"grouping sets",
"on overflow",
"character set",
"respect nulls",
"ignore nulls",
"nulls first",
"nulls last",
"depth first",
"breadth first"
], v = h, C = [
...f,
...d
].filter((w) => !h.includes(w)), _ = {
scope: "variable",
match: /@[a-z0-9][a-z0-9_]*/
}, b = {
scope: "operator",
match: /[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,
relevance: 0
}, R = {
match: r.concat(/\b/, r.either(...v), /\s*\(/),
relevance: 0,
keywords: { built_in: v }
};
function D(w) {
return r.concat(
/\b/,
r.either(...w.map((i) => i.replace(/\s+/, "\\s+"))),
/\b/
);
}
const $ = {
scope: "keyword",
match: D(m),
relevance: 0
};
function A(w, {
exceptions: i,
when: g
} = {}) {
const x = g;
return i = i || [], w.map((N) => N.match(/\|\d+$/) || i.includes(N) ? N : x(N) ? `${N}|0` : N);
}
return {
name: "SQL",
case_insensitive: !0,
// does not include {} or HTML tags `</`
illegal: /[{}]|<\//,
keywords: {
$pattern: /\b[\w\.]+/,
keyword: A(C, { when: (w) => w.length < 3 }),
literal: c,
type: u,
built_in: p
},
contains: [
{
scope: "type",
match: D(l)
},
$,
R,
_,
s,
a,
t.C_NUMBER_MODE,
t.C_BLOCK_COMMENT_MODE,
n,
b
]
};
}
const yo = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
default: xs
}, Symbol.toStringTag, { value: "Module" }));
Kr.registerLanguage("json", bs);
Kr.registerLanguage("sql", xs);
const rr = ({
code: t,
language: r,
title: n,
maxHeight: s = "16rem",
height: a,
className: c = ""
}) => {
const [l, u] = V(!1), d = Ce(null), f = Q("copy"), h = Q("check");
ve(() => {
d.current && t && (d.current.innerHTML = Kr.highlight(t, { language: r }).value);
}, [t, r]);
const p = async () => {
try {
await navigator.clipboard.writeText(t), u(!0), setTimeout(() => u(!1), 2e3);
} catch {
const m = document.createElement("textarea");
m.value = t, m.style.position = "fixed", m.style.left = "-999999px", document.body.appendChild(m), m.select(), document.execCommand("copy"), document.body.removeChild(m), u(!0), setTimeout(() => u(!1), 2e3);
}
};
return /* @__PURE__ */ o("div", { className: `relative ${c}`, children: [
/* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-2", children: [
n && /* @__PURE__ */ e("h4", { className: "text-sm font-semibold text-dc-text", children: n }),
/* @__PURE__ */ e(
"button",
{
onClick: p,
className: "ml-auto px-2 py-1 text-xs rounded hover:bg-dc-surface-secondary border border-dc-border transition-colors flex items-center gap-1.5",
title: l ? "Copied!" : "Copy to clipboard",
children: l ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(h, { className: "w-3.5 h-3.5 text-dc-success" }),
/* @__PURE__ */ e("span", { className: "text-dc-success", children: "Copied" })
] }) : /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(f, { className: "w-3.5 h-3.5 text-dc-text-secondary" }),
/* @__PURE__ */ e("span", { className: "text-dc-text-secondary", children: "Copy" })
] })
}
)
] }),
/* @__PURE__ */ e(
"div",
{
className: "bg-dc-surface-secondary border border-dc-border rounded overflow-auto",
style: a ? { height: a, minHeight: a, maxHeight: a } : { maxHeight: s },
children: /* @__PURE__ */ e("pre", { className: "p-3 text-xs m-0", children: /* @__PURE__ */ e(
"code",
{
ref: d,
className: `hljs language-${r}`,
children: t
}
) })
}
)
] });
};
function ys(t) {
return t.isTimeDimension;
}
function vo(t) {
return t.find(ys);
}
function wo(t) {
return t.find((r) => !r.isTimeDimension);
}
function Xr(t) {
return t.filter((r) => !r.isTimeDimension);
}
function vs(t) {
return t.filter(ys);
}
function Zr(t, r, n) {
const s = r.length, a = Xr(n).length, c = vs(n).length, l = n.length;
switch (t) {
// Always available charts
case "table":
case "markdown":
return { available: !0 };
// Measure-only charts (KPI Number, KPI Text)
case "kpiNumber":
case "kpiText":
return s < 1 ? { available: !1, reason: "Requires at least 1 measure" } : { available: !0 };
// Bar chart - needs dimension for categories + measure for values
case "bar":
return s < 1 ? { available: !1, reason: "Requires at least 1 measure" } : l < 1 ? { available: !1, reason: "Requires at least 1 breakdown for categories" } : { available: !0 };
// KPI Delta - needs dimension for ordering + measure for values
case "kpiDelta":
return s < 1 ? { available: !1, reason: "Requires at least 1 measure" } : l < 1 ? { available: !1, reason: "Requires at least 1 breakdown for ordering" } : { available: !0 };
// Line and area charts - need dimension/time + measure
case "line":
case "area":
return s < 1 ? { available: !1, reason: "Requires at least 1 measure" } : l < 1 ? { available: !1, reason: "Requires a breakdown (dimension or time)" } : { available: !0 };
// Pie chart - needs dimension (not time) + measure
case "pie":
return s < 1 ? { available: !1, reason: "Requires 1 measure" } : a < 1 ? { available: !1, reason: "Requires 1 dimension (not time dimension)" } : { available: !0 };
// Scatter - needs measure + any breakdown
case "scatter":
return s < 1 ? { available: !1, reason: "Requires at least 1 measure" } : s < 2 && l < 1 ? { available: !1, reason: "Requires 2 measures or 1 measure + 1 breakdown" } : { available: !0 };
// Bubble - needs 2+ measures and 1+ breakdown (dimension or time dimension for series)
case "bubble":
return s < 2 ? { available: !1, reason: "Requires at least 2 measures" } : l < 1 ? { available: !1, reason: "Requires at least 1 breakdown for series grouping" } : { available: !0 };
// Radar - needs dimension + measure
case "radar":
return s < 1 ? { available: !1, reason: "Requires at least 1 measure" } : a < 1 ? { available: !1, reason: "Requires at least 1 dimension" } : { available: !0 };
// Radial Bar - needs dimension + measure
case "radialBar":
return s < 1 ? { available: !1, reason: "Requires at least 1 measure" } : a < 1 ? { available: !1, reason: "Requires at least 1 dimension" } : { available: !0 };
// Treemap - needs dimension + measure
case "treemap":
return s < 1 ? { available: !1, reason: "Requires at least 1 measure" } : a < 1 ? { available: !1, reason: "Requires at least 1 dimension" } : { available: !0 };
// Activity Grid - needs time dimension + measure
case "activityGrid":
return s < 1 ? { available: !1, reason: "Requires at least 1 measure" } : c < 1 ? { available: !1, reason: "Requires a time dimension" } : { available: !0 };
default:
return { available: !0 };
}
}
function No(t, r) {
const n = [
"activityGrid",
"area",
"bar",
"bubble",
"kpiDelta",
"kpiNumber",
"kpiText",
"line",
"markdown",
"pie",
"radar",
"radialBar",
"scatter",
"table",
"treemap"
], s = {};
for (const a of n)
s[a] = Zr(a, t, r);
return s;
}
function ws(t, r, n) {
if (Zr(n, t, r).available || t.length === 0 && r.length === 0)
return n;
const a = vs(r).length > 0, c = Xr(r).length > 0, l = t.length > 0;
return a && l ? "line" : c && l ? "bar" : l && !c && !a ? "kpiNumber" : "table";
}
function hr(t, r, n) {
const s = ws(t, r, n), a = Co(s, t, r);
return { chartType: s, chartConfig: a };
}
function Co(t, r, n) {
const s = vo(n), a = wo(n), c = Xr(n), l = n;
switch (t) {
case "line":
case "area":
return {
xAxis: s ? [s.field] : a ? [a.field] : [],
yAxis: r.map((u) => u.field),
series: c.length > 1 ? [c[1].field] : a && s ? [a.field] : []
};
case "bar":
return {
xAxis: a ? [a.field] : s ? [s.field] : [],
yAxis: r.map((u) => u.field),
series: c.length > 1 ? [c[1].field] : s && a ? [s.field] : []
};
case "pie":
return {
xAxis: a ? [a.field] : [],
yAxis: r.length > 0 ? [r[0].field] : []
};
case "scatter":
return r.length >= 2 ? {
xAxis: [r[0].field],
yAxis: [r[1].field],
series: a ? [a.field] : []
} : {
xAxis: l.length > 0 ? [l[0].field] : [],
yAxis: r.length > 0 ? [r[0].field] : [],
series: c.length > 1 ? [c[1].field] : []
};
case "bubble":
return {
xAxis: r.length > 0 ? [r[0].field] : [],
yAxis: r.length > 1 ? [r[1].field] : [],
sizeField: r.length > 2 ? r[2].field : r.length > 1 ? r[1].field : void 0,
series: a ? [a.field] : s ? [s.field] : []
};
case "radar":
case "radialBar":
case "treemap":
return {
xAxis: a ? [a.field] : [],
yAxis: r.length > 0 ? [r[0].field] : []
};
case "activityGrid":
return {
dateField: s ? [s.field] : [],
valueField: r.length > 0 ? [r[0].field] : []
};
case "kpiNumber":
case "kpiDelta":
case "kpiText":
return {
yAxis: r.length > 0 ? [r[0].field] : []
};
case "table":
return {
xAxis: [
...n.map((u) => u.field),
...r.map((u) => u.field)
]
};
case "markdown":
return {};
default:
return {
xAxis: l.length > 0 ? [l[0].field] : [],
yAxis: r.map((u) => u.field)
};
}
}
function ko(t, r, n, s) {
if (s && Zr(n, t, r).available)
return null;
const a = ws(t, r, n);
return a !== n ? a : null;
}
const Do = Q("chevronDown");
function Ns({
currentPalette: t = "default",
onPaletteChange: r,
className: n = ""
}) {
const [s, a] = V(!1), c = Ce(null), l = Wr(t);
ve(() => {
function d(f) {
c.current && !c.current.contains(f.target) && a(!1);
}
if (s)
return document.addEventListener("mousedown", d), () => document.removeEventListener("mousedown", d);
}, [s]);
const u = (d) => {
r(d), a(!1);
};
return /* @__PURE__ */ o("div", { className: `relative ${n}`, ref: c, children: [
/* @__PURE__ */ o(
"button",
{
type: "button",
onClick: () => a(!s),
className: "inline-flex items-center gap-2 px-3 py-1.5 bg-dc-surface border border-dc-border rounded-md shadow-xs text-sm font-medium text-dc-text-secondary hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-dc-accent",
children: [
/* @__PURE__ */ o("div", { className: "hidden md:flex items-center gap-1.5", children: [
/* @__PURE__ */ e("div", { className: "flex gap-0.5", children: l.colors.slice(0, 4).map((d, f) => /* @__PURE__ */ e(
"div",
{
className: "w-3 h-3 rounded-xs border border-dc-border",
style: { backgroundColor: d },
title: `Series Color ${f + 1}`
},
f
)) }),
/* @__PURE__ */ e("span", { className: "text-xs text-dc-text-secondary", children: "|" }),
/* @__PURE__ */ e("div", { className: "flex gap-0.5", children: l.gradient.slice(0, 3).map((d, f) => /* @__PURE__ */ e(
"div",
{
className: "w-2 h-3 border-r first:rounded-l-sm last:rounded-r-sm last:border-r-0",
style: {
backgroundColor: d,
borderColor: "var(--dc-border)"
},
title: `Gradient Color ${f + 1}`
},
f
)) })
] }),
/* @__PURE__ */ e("span", { children: l.label }),
/* @__PURE__ */ e(
Do,
{
className: `w-4 h-4 transition-transform ${s ? "rotate-180" : ""}`
}
)
]
}
),
s && /* @__PURE__ */ e("div", { className: "absolute top-full left-0 mt-1 w-72 md:w-80 lg:w-96 bg-dc-surface border border-dc-border rounded-md shadow-lg z-50 max-h-80 overflow-y-auto", children: /* @__PURE__ */ e("div", { className: "py-1", children: nr.slice().sort((d, f) => d.label.localeCompare(f.label)).map((d) => /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => u(d.name),
className: `w-full px-3 py-2 text-left text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${d.name === t ? "bg-dc-surface-secondary" : "text-dc-text-secondary"}`,
style: d.name === t ? { color: "var(--dc-primary)" } : void 0,
children: /* @__PURE__ */ o("div", { className: "flex items-center gap-3", children: [
/* @__PURE__ */ o("div", { className: "hidden md:flex items-center gap-2", children: [
/* @__PURE__ */ e("div", { className: "flex gap-0.5", children: d.colors.slice(0, 6).map((f, h) => /* @__PURE__ */ e(
"div",
{
className: "w-3 h-3 rounded-xs border border-dc-border",
style: { backgroundColor: f }
},
`series-${h}`
)) }),
/* @__PURE__ */ e("div", { className: "w-px h-4 bg-dc-border" }),
/* @__PURE__ */ e("div", { className: "flex", children: d.gradient.map((f, h) => /* @__PURE__ */ e(
"div",
{
className: "w-2 h-4 first:rounded-l-sm last:rounded-r-sm",
style: { backgroundColor: f }
},
`gradient-${h}`
)) })
] }),
/* @__PURE__ */ e("span", { className: "font-medium", children: d.label }),
d.name === t && /* @__PURE__ */ e("div", { className: "ml-auto", children: /* @__PURE__ */ e("div", { className: "w-2 h-2 rounded-full", style: { backgroundColor: "var(--dc-primary)" } }) })
] })
},
d.name
)) }) })
] });
}
const To = Ot(function({
executionStatus: r,
executionResults: n,
executionError: s,
totalRowCount: a,
resultsStale: c = !1,
chartType: l = "line",
chartConfig: u = {},
displayConfig: d = {},
colorPalette: f,
currentPaletteName: h,
onColorPaletteChange: p,
allQueries: m,
activeView: v = "chart",
onActiveViewChange: C,
displayLimit: _ = 100,
onDisplayLimitChange: b,
hasMetrics: R = !1,
// Debug props - per-query for multi-query mode
debugDataPerQuery: D = [],
// Share props
onShareClick: $,
canShare: A = !1,
shareButtonState: w = "idle",
// Clear functionality
onClearClick: i,
canClear: g = !1,
// AI functionality
enableAI: x = !1,
isAIOpen: N = !1,
onAIToggle: S,
// Multi-query props
queryCount: y = 1,
perQueryResults: M,
activeTableIndex: E = 0,
onActiveTableChange: T
}) {
const [j, q] = V(!1), [I, K] = V(0);
ve(() => {
D.length > 0 && I >= D.length && K(D.length - 1);
}, [D.length, I]);
const U = D[I] || {
sql: null,
analysis: null,
loading: !1,
error: null
}, ke = U.sql, De = U.analysis, Pe = U.loading, B = U.error, se = m?.[I] || null;
ve(() => {
!R && v === "chart" && C("table");
}, [R, v, C]);
const Te = ye(() => {
if (!m || m.length === 0) return;
if (m.length === 1) return m[0];
const Qe = m.flatMap((Ze) => Ze?.measures || []);
return {
...m[0],
measures: Qe
};
}, [m]), H = Q("success"), ee = Q("error"), le = Q("warning"), be = Q("table"), L = Q("measure"), te = Q("codeBracket"), Ne = Q("share"), Ve = Q("check"), rt = Q("delete"), Fe = Q("sparkles"), ue = () => /* @__PURE__ */ e("div", { className: "h-full flex items-center justify-center", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e(
"div",
{
className: "animate-spin rounded-full h-12 w-12 border-b-2 mx-auto mb-4",
style: { borderBottomColor: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold text-dc-text-secondary mb-1", children: "Executing Query..." }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted", children: "Running your query against the cube API" })
] }) }), _e = () => /* @__PURE__ */ o("div", { className: "h-full flex flex-col", children: [
at(),
/* @__PURE__ */ e("div", { className: "flex-1 flex items-center justify-center p-4", children: j ? /* @__PURE__ */ e("div", { className: "w-full h-full overflow-auto", children: nt() }) : /* @__PURE__ */ o("div", { className: "text-center max-w-md", children: [
/* @__PURE__ */ e(ee, { className: "w-12 h-12 mx-auto text-dc-error mb-4" }),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold text-dc-text mb-2", children: "Query Execution Failed" }),
/* @__PURE__ */ e("div", { className: "text-sm text-dc-text-secondary mb-4", children: "There was an error executing your query. Please check the query and try again." }),
s && /* @__PURE__ */ e("div", { className: "bg-dc-danger-bg border border-dc-error rounded-lg p-3 text-left", children: /* @__PURE__ */ e("div", { className: "text-xs font-mono text-dc-error break-words", children: s }) })
] }) })
] }), G = !!m?.some(
(Qe) => Qe?.measures && Qe.measures.length > 0 || Qe?.dimensions && Qe.dimensions.length > 0 || Qe?.timeDimensions && Qe.timeDimensions.length > 0
), X = () => /* @__PURE__ */ e("div", { className: "h-full flex items-center justify-center", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e(
"div",
{
className: "animate-spin rounded-full h-12 w-12 border-b-2 mx-auto mb-4",
style: { borderBottomColor: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold text-dc-text-secondary mb-1", children: "Preparing Query..." }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted", children: "Your query will execute shortly" })
] }) }), ae = () => /* @__PURE__ */ e("div", { className: "h-full flex items-center justify-center pt-6", children: /* @__PURE__ */ o("div", { className: "text-center mb-16", children: [
/* @__PURE__ */ e(L, { className: "w-12 h-12 mx-auto text-dc-text-muted mb-3" }),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold text-dc-text-secondary mb-1", children: "No Results Yet" }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted mb-4", children: "Add metrics or breakdowns from the panel on the right to see results" }),
x && S && /* @__PURE__ */ o(
"button",
{
onClick: S,
className: "inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-dc-accent hover:bg-dc-accent rounded-lg transition-colors shadow-sm",
children: [
/* @__PURE__ */ e(Fe, { className: "w-4 h-4" }),
"Analyse with AI"
]
}
)
] }) }), qe = () => /* @__PURE__ */ e("div", { className: "h-full flex items-center justify-center", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e(H, { className: "w-12 h-12 mx-auto text-dc-success mb-3" }),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold text-dc-text mb-1", children: "Query Successful" }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted", children: "No data returned from the query" })
] }) }), je = () => !n || n.length === 0 ? /* @__PURE__ */ e("div", { className: "flex items-center justify-center h-full text-dc-text-muted", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e(L, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold mb-1", children: "No data to display" }),
/* @__PURE__ */ e("div", { className: "text-xs", children: "Run a query to see chart visualization" })
] }) }) : as(l) ? /* @__PURE__ */ e(
Vr,
{
chartType: l,
data: n,
chartConfig: u,
displayConfig: d,
colorPalette: f,
queryObject: Te,
height: "100%",
fallback: /* @__PURE__ */ e("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ e("div", { className: "animate-pulse bg-dc-surface-secondary rounded w-full h-full" }) })
}
) : /* @__PURE__ */ e("div", { className: "flex items-center justify-center h-full text-dc-text-muted", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e(le, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold mb-1", children: "Unsupported chart type" }),
/* @__PURE__ */ e("div", { className: "text-xs", children: l })
] }) }), nt = () => /* @__PURE__ */ o("div", { className: "p-4 space-y-4 overflow-auto h-full", children: [
D.length > 1 && /* @__PURE__ */ o("div", { className: "flex items-center gap-1 mb-4", children: [
/* @__PURE__ */ e("span", { className: "text-xs font-medium text-dc-text-muted mr-2", children: "Query:" }),
/* @__PURE__ */ e("div", { className: "flex border border-dc-border rounded-md overflow-hidden", children: D.map((Qe, Ze) => /* @__PURE__ */ o(
"button",
{
onClick: () => K(Ze),
className: `px-3 py-1 text-xs font-medium transition-colors border-r last:border-r-0 border-dc-border ${I === Ze ? "bg-dc-accent text-white" : "bg-dc-bg text-dc-text-secondary hover:bg-dc-bg-secondary"}`,
children: [
"Q",
Ze + 1,
Qe.loading && /* @__PURE__ */ e("span", { className: "ml-1 opacity-70", children: "•" }),
Qe.error && /* @__PURE__ */ e("span", { className: "ml-1 text-dc-error", children: "!" })
]
},
Ze
)) })
] }),
s && /* @__PURE__ */ o("div", { className: "bg-dc-danger-bg dark:bg-dc-danger-bg border border-dc-error dark:border-dc-error rounded p-3", children: [
/* @__PURE__ */ e("h4", { className: "text-sm font-semibold text-dc-error dark:text-dc-error mb-1", children: "Execution Error" }),
/* @__PURE__ */ e("p", { className: "text-sm text-dc-error dark:text-dc-error", children: s })
] }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Query Analysis" }),
Pe ? /* @__PURE__ */ e("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm", children: "Loading..." }) : De ? /* @__PURE__ */ e("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3", children: /* @__PURE__ */ e(ho, { analysis: De }) }) : /* @__PURE__ */ e("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm", children: B ? "Analysis unavailable due to error" : "Add metrics to see analysis" })
] }),
/* @__PURE__ */ o("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
/* @__PURE__ */ e("div", { children: se ? /* @__PURE__ */ e(
rr,
{
code: JSON.stringify(se, null, 2),
language: "json",
title: "Cube Query",
height: "16rem"
}
) : /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Cube Query" }),
/* @__PURE__ */ e("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm h-64 overflow-auto", children: "No query" })
] }) }),
/* @__PURE__ */ e("div", { children: Pe ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Generated SQL" }),
/* @__PURE__ */ e("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm h-64 overflow-auto", children: "Loading..." })
] }) : B ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Generated SQL" }),
/* @__PURE__ */ e("div", { className: "text-dc-error text-sm bg-dc-danger-bg dark:bg-dc-danger-bg p-3 rounded border border-dc-error dark:border-dc-error h-64 overflow-auto", children: B })
] }) : ke ? /* @__PURE__ */ e(
rr,
{
code: ke.sql + (ke.params && ke.params.length > 0 ? `
-- Parameters:
` + JSON.stringify(ke.params, null, 2) : ""),
language: "sql",
title: "Generated SQL",
height: "16rem"
}
) : /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Generated SQL" }),
/* @__PURE__ */ e("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm h-64 overflow-auto", children: "Add metrics to generate SQL" })
] }) })
] }),
/* @__PURE__ */ o("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
/* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(
rr,
{
code: JSON.stringify(u, null, 2),
language: "json",
title: "Chart Config",
height: "16rem"
}
) }),
/* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(
rr,
{
code: JSON.stringify(d, null, 2),
language: "json",
title: "Display Config",
height: "16rem"
}
) })
] }),
/* @__PURE__ */ e("div", { children: n ? /* @__PURE__ */ e(
rr,
{
code: JSON.stringify(n, null, 2),
language: "json",
title: `Server Response (${n.length} rows)`,
maxHeight: "24rem"
}
) : /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Server Response" }),
/* @__PURE__ */ e("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm", children: "No results yet" })
] }) })
] }), Ie = y > 1 && M && M.length > 1, Be = (Qe) => {
let Ze = null, et = m?.[0];
if (Ie && Qe !== void 0 && Qe >= 0 && M ? (Ze = M[Qe] || null, et = m?.[Qe]) : (Ze = n, Ie && (et = Te)), !Ze || Ze.length === 0)
return /* @__PURE__ */ e("div", { className: "flex items-center justify-center h-full text-dc-text-muted", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e(be, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold mb-1", children: "No data to display" }),
/* @__PURE__ */ e("div", { className: "text-xs", children: "Run a query to see table data" })
] }) });
const xt = Ze.slice(0, _);
return /* @__PURE__ */ e(
Vr,
{
chartType: "table",
data: xt,
colorPalette: f,
queryObject: et,
height: "100%",
fallback: /* @__PURE__ */ e("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ e("div", { className: "animate-pulse bg-dc-surface-secondary rounded w-full h-full" }) })
}
);
}, ot = () => /* @__PURE__ */ e("div", { className: "absolute inset-0 flex items-center justify-center bg-dc-surface bg-opacity-75 z-10", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e(
"div",
{
className: "animate-spin rounded-full h-10 w-10 border-b-2 mx-auto mb-2",
style: { borderBottomColor: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-secondary", children: "Refreshing results..." })
] }) }), at = () => {
const Qe = n && n.length > 0;
return /* @__PURE__ */ o("div", { className: "px-4 py-2 border-b border-dc-border bg-dc-surface-secondary flex-shrink-0", children: [
/* @__PURE__ */ o("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ o("div", { className: "flex items-center", children: [
r === "refreshing" ? /* @__PURE__ */ e(
"div",
{
className: "w-4 h-4 mr-2 rounded-full border-b-2 animate-spin",
style: { borderBottomColor: "var(--dc-primary)" }
}
) : Qe ? /* @__PURE__ */ e(H, { className: "w-4 h-4 text-dc-success mr-2" }) : r === "error" ? /* @__PURE__ */ e(ee, { className: "w-4 h-4 text-dc-error mr-2" }) : /* @__PURE__ */ e(le, { className: "w-4 h-4 text-dc-text-muted mr-2" }),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text-secondary", children: Qe ? /* @__PURE__ */ o(Oe, { children: [
n.length,
" row",
n.length !== 1 ? "s" : "",
a !== null && a > n.length && /* @__PURE__ */ o("span", { className: "text-dc-text-muted", children: [
" of ",
a.toLocaleString()
] }),
c && /* @__PURE__ */ e("span", { className: "text-dc-warning ml-2", children: "• Results may be outdated" })
] }) : r === "error" ? "Query failed" : r === "loading" ? "Executing..." : "No results" })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
Qe && v === "table" && !j && b && /* @__PURE__ */ o(
"select",
{
value: _,
onChange: (Ze) => b(Number(Ze.target.value)),
className: "text-xs border border-dc-border rounded px-2 py-1 bg-dc-surface text-dc-text focus:outline-none focus:ring-1 focus:ring-dc-primary",
children: [
/* @__PURE__ */ e("option", { value: 50, children: "50 rows" }),
/* @__PURE__ */ e("option", { value: 100, children: "100 rows" }),
/* @__PURE__ */ e("option", { value: 250, children: "250 rows" }),
/* @__PURE__ */ e("option", { value: 500, children: "500 rows" })
]
}
),
x && S && /* @__PURE__ */ o(
"button",
{
onClick: S,
className: `flex items-center gap-1 px-2 py-1.5 text-xs font-medium rounded transition-colors ${N ? "text-white bg-dc-accent border border-dc-accent" : "text-dc-accent dark:text-dc-accent bg-dc-accent-bg dark:bg-dc-accent-bg border border-dc-accent dark:border-dc-accent hover:bg-dc-accent-bg dark:hover:bg-dc-accent-bg"}`,
title: N ? "Close AI assistant" : "Analyse with AI",
children: [
/* @__PURE__ */ e(Fe, { className: "w-3 h-3" }),
/* @__PURE__ */ e("span", { className: "hidden sm:inline", children: "Analyse with AI" })
]
}
),
p && Qe && /* @__PURE__ */ e(
Ns,
{
currentPalette: h || "default",
onPaletteChange: p
}
),
$ && /* @__PURE__ */ e(
"button",
{
onClick: $,
className: `flex items-center gap-1 px-2 py-1.5 text-xs font-medium rounded transition-colors ${w === "idle" && A ? "text-dc-accent dark:text-dc-accent bg-dc-accent-bg dark:bg-dc-accent-bg border border-dc-accent dark:border-dc-accent hover:bg-dc-accent-bg dark:hover:bg-dc-accent-bg" : w !== "idle" ? "text-dc-success dark:text-dc-success bg-dc-success-bg dark:bg-dc-success-bg border border-dc-success dark:border-dc-success" : "text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed"}`,
title: w === "idle" ? "Share this analysis" : "Link copied!",
disabled: !A || w !== "idle",
children: w === "idle" ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(Ne, { className: "w-3 h-3" }),
/* @__PURE__ */ e("span", { className: "hidden sm:inline", children: "Share" })
] }) : w === "copied" ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(Ve, { className: "w-3 h-3" }),
/* @__PURE__ */ e("span", { className: "hidden sm:inline", children: "Copied!" })
] }) : /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(Ve, { className: "w-3 h-3" }),
/* @__PURE__ */ e("span", { className: "hidden sm:inline", children: "Copied!" }),
/* @__PURE__ */ e("span", { className: "hidden lg:inline text-[10px] opacity-75", children: "(no chart)" })
] })
}
),
i && g && /* @__PURE__ */ o(
"button",
{
onClick: i,
className: "flex items-center gap-1 px-2 py-1.5 text-xs font-medium text-dc-text-secondary hover:text-dc-text bg-dc-surface hover:bg-dc-surface-hover border border-dc-border rounded transition-colors",
title: "Clear all query data",
children: [
/* @__PURE__ */ e(rt, { className: "w-3 h-3" }),
/* @__PURE__ */ e("span", { className: "hidden sm:inline", children: "Clear" })
]
}
),
/* @__PURE__ */ o(
"button",
{
onClick: () => q(!j),
className: `p-1.5 rounded transition-colors relative ${j ? "bg-dc-primary text-white" : "text-dc-text-secondary hover:text-dc-text hover:bg-dc-surface-hover"}`,
title: j ? "Hide debug info" : "Show debug info",
children: [
/* @__PURE__ */ e(te, { className: "w-4 h-4" }),
(s || D.some((Ze) => Ze.error)) && !j && /* @__PURE__ */ e("span", { className: "absolute -top-0.5 -right-0.5 w-2 h-2 bg-dc-danger-bg0 rounded-full" })
]
}
)
] })
] }),
Qe && a !== null && a > 1e3 && /* @__PURE__ */ o("div", { className: "mt-2 bg-dc-warning-bg border border-dc-warning rounded-lg p-2 flex items-start", children: [
/* @__PURE__ */ e(le, { className: "w-4 h-4 text-dc-warning mr-2 shrink-0 mt-0.5" }),
/* @__PURE__ */ o("div", { className: "text-xs text-dc-warning", children: [
/* @__PURE__ */ e("span", { className: "font-semibold", children: "Large dataset:" }),
" ",
a.toLocaleString(),
" rows. Consider adding filters to improve performance."
] })
] })
] });
}, bt = () => n && n.length > 0 ? /* @__PURE__ */ o("div", { className: "h-full flex flex-col", children: [
at(),
/* @__PURE__ */ e("div", { className: "flex-1 min-h-0 relative overflow-auto", children: j ? nt() : v === "chart" ? /* @__PURE__ */ e("div", { className: "p-4 h-full", children: je() }) : Ie ? /* @__PURE__ */ e("div", { className: "h-full", children: Be(E) }) : /* @__PURE__ */ e("div", { className: "h-full", children: Be() }) }),
!j && /* @__PURE__ */ e("div", { className: "px-4 py-3 border-t border-dc-border bg-dc-surface flex justify-center flex-shrink-0", children: /* @__PURE__ */ o("div", { className: "flex items-center bg-dc-surface-secondary border border-dc-border rounded-md overflow-hidden", children: [
/* @__PURE__ */ o(
"button",
{
onClick: () => R && C("chart"),
disabled: !R,
className: `flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium transition-colors ${v === "chart" ? "bg-dc-primary text-white" : R ? "text-dc-text-secondary hover:bg-dc-surface-hover" : "text-dc-text-disabled bg-dc-surface-tertiary cursor-not-allowed"}`,
title: R ? "Chart view" : "Add metrics to enable chart view",
children: [
/* @__PURE__ */ e(L, { className: "w-4 h-4" }),
"Chart"
]
}
),
Ie ? /* @__PURE__ */ o(Oe, { children: [
Array.from({ length: y }).map((Ze, et) => /* @__PURE__ */ o(
"button",
{
onClick: () => {
C("table"), T?.(et);
},
className: `flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium transition-colors ${v === "table" && E === et ? "bg-dc-primary text-white" : "text-dc-text-secondary hover:bg-dc-surface-hover"}`,
title: `Table Q${et + 1}`,
children: [
/* @__PURE__ */ e(be, { className: "w-4 h-4" }),
"Q",
et + 1
]
},
`table-${et}`
)),
/* @__PURE__ */ o(
"button",
{
onClick: () => {
C("table"), T?.(-1);
},
className: `flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium transition-colors ${v === "table" && E === -1 ? "bg-dc-primary text-white" : "text-dc-text-secondary hover:bg-dc-surface-hover"}`,
title: "Merged table view",
children: [
/* @__PURE__ */ e(be, { className: "w-4 h-4" }),
"Merged"
]
}
)
] }) : /* @__PURE__ */ o(
"button",
{
onClick: () => C("table"),
className: `flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium transition-colors ${v === "table" ? "bg-dc-primary text-white" : "text-dc-text-secondary hover:bg-dc-surface-hover"}`,
title: "Table view",
children: [
/* @__PURE__ */ e(be, { className: "w-4 h-4" }),
"Table"
]
}
)
] }) })
] }) : /* @__PURE__ */ o("div", { className: "h-full flex flex-col", children: [
at(),
/* @__PURE__ */ e("div", { className: "flex-1 min-h-0 relative overflow-auto", children: j ? nt() : qe() })
] }), ft = n !== null, Dt = ft && (r !== "idle" || G);
return /* @__PURE__ */ o("div", { className: "h-full min-h-[400px] flex flex-col bg-dc-surface relative", children: [
r === "idle" && !G && ae(),
r === "idle" && G && !ft && X(),
r === "loading" && !ft && ue(),
r === "error" && !ft && _e(),
(r === "success" || Dt) && bt(),
(r === "loading" || r === "refreshing") && ft && ot()
] });
}), So = Ot(function({
metric: r,
fieldMeta: n,
onRemove: s,
sortDirection: a,
sortPriority: c,
onToggleSort: l,
index: u,
isDragging: d,
onDragStart: f,
onDragEnd: h
}) {
const p = Q("close"), m = Q("chevronUp"), v = Q("chevronDown"), C = Q("chevronUpDown"), _ = n?.type || "count", b = Xt(_) || Q("measure"), R = n?.shortTitle || n?.title || r.field.split(".").pop() || r.field, D = r.field.split(".")[0], $ = () => {
switch (a) {
case "asc":
return m ? /* @__PURE__ */ e(m, { className: "w-4 h-4" }) : "↑";
case "desc":
return v ? /* @__PURE__ */ e(v, { className: "w-4 h-4" }) : "↓";
default:
return C ? /* @__PURE__ */ e(C, { className: "w-4 h-4" }) : "⇅";
}
}, A = () => {
switch (a) {
case "asc":
return "Sorted ascending (click for descending)";
case "desc":
return "Sorted descending (click to remove)";
default:
return "Click to sort ascending";
}
}, w = typeof u == "number" && f && h;
return /* @__PURE__ */ o(
"div",
{
className: `flex items-center gap-2 p-2 bg-dc-surface-secondary rounded-lg group hover:bg-dc-surface-tertiary transition-all duration-150 ${w ? "cursor-grab active:cursor-grabbing" : ""} ${d ? "opacity-30" : ""}`,
draggable: w ? !0 : void 0,
onDragStart: w ? (i) => f(i, u) : void 0,
onDragEnd: w ? h : void 0,
children: [
/* @__PURE__ */ e("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-measure text-dc-measure-text flex-shrink-0", children: b && /* @__PURE__ */ e(b, { className: "w-4 h-4" }) }),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ e("div", { className: "text-sm text-dc-text truncate", title: r.field, children: R }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: D })
] }),
l && /* @__PURE__ */ o(
"button",
{
onClick: l,
className: `p-1 transition-opacity flex-shrink-0 flex items-center gap-0.5 ${a ? "opacity-100 text-dc-primary" : "opacity-100 sm:opacity-0 sm:group-hover:opacity-100 text-dc-text-muted hover:text-dc-primary"}`,
title: A(),
children: [
$(),
a && c && /* @__PURE__ */ o("span", { className: "text-xs font-medium", children: [
"(",
c,
")"
] })
]
}
),
/* @__PURE__ */ e(
"button",
{
onClick: s,
className: "p-1 text-dc-text-muted hover:text-dc-danger opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity flex-shrink-0",
title: "Remove metric",
children: /* @__PURE__ */ e(p, { className: "w-4 h-4" })
}
)
]
}
);
}), Ao = Q("add");
function Eo(t, r) {
if (!r?.cubes) return null;
const [n] = t.split("."), s = r.cubes.find((a) => a.name === n);
return s && s.measures?.find((a) => a.name === t) || null;
}
function _o(t) {
switch (t) {
case null:
return "asc";
case "asc":
return "desc";
case "desc":
return null;
default:
return "asc";
}
}
const Ro = Ot(function({
metrics: r,
schema: n,
onAdd: s,
onRemove: a,
order: c,
onOrderChange: l,
onReorder: u
}) {
const [d, f] = V(null), [h, p] = V(null), m = Ce(null), v = Ce(null), C = ye(() => c ? Object.keys(c) : [], [c]), _ = ye(() => r.map((x, N) => {
const S = c?.[x.field] || null, y = S ? C.indexOf(x.field) + 1 : void 0;
return {
metric: x,
fieldMeta: Eo(x.field, n),
sortDirection: S,
sortPriority: y,
index: N
};
}), [r, n, c, C]), b = Ce(null), R = F((x, N) => {
f(N), m.current = N, x.dataTransfer.effectAllowed = "move", x.dataTransfer.setData("text/plain", JSON.stringify({ type: "metric", index: N, field: r[N].field }));
const S = x.currentTarget, y = S.cloneNode(!0);
y.style.cssText = `
position: absolute;
top: -9999px;
left: -9999px;
width: ${S.offsetWidth}px;
opacity: 0.7;
transform: rotate(2deg);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
pointer-events: none;
`, document.body.appendChild(y), b.current = y;
const M = S.getBoundingClientRect(), E = x.clientX - M.left, T = x.clientY - M.top;
x.dataTransfer.setDragImage(y, E, T);
}, [r]), D = F(() => {
f(null), p(null), m.current = null, v.current = null, b.current && (document.body.removeChild(b.current), b.current = null);
}, []), $ = F((x, N) => {
x.preventDefault(), x.stopPropagation();
const S = m.current;
if (S === null) return;
const y = x.currentTarget.getBoundingClientRect();
let T = x.clientY - y.top < y.height / 2 ? N : N + 1;
T === S || T === S + 1 ? (p(null), v.current = null) : (p(T), v.current = T);
}, []), A = F((x) => {
x.preventDefault(), x.stopPropagation();
const N = m.current, S = v.current;
if (f(null), p(null), m.current = null, v.current = null, N === null || S === null || !u)
return;
const y = S > N ? S - 1 : S;
y !== N && u(N, y);
}, [u]), w = F((x) => {
const N = x.relatedTarget;
(!N || !x.currentTarget.contains(N)) && p(null);
}, []), i = F((x) => {
if (d === null || h === null) return "";
const N = 40;
if (x === d) return "";
if (d < h) {
if (x > d && x < h)
return "";
if (x === h - 1)
return `translateY(-${N / 2}px)`;
if (x >= h)
return `translateY(${N / 2}px)`;
} else if (x >= h && x < d)
return `translateY(${N / 2}px)`;
return "";
}, [d, h]), g = F((x) => d === null || h === null ? !1 : x === h, [d, h]);
return /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ o(
"button",
{
onClick: s,
className: "flex items-center justify-between mb-3 w-full py-1 px-2 -ml-2 rounded-lg hover:bg-dc-primary/10 transition-colors group",
title: "Add metric",
children: [
/* @__PURE__ */ e(Vt, { children: "Metrics" }),
/* @__PURE__ */ e(Ao, { className: "w-5 h-5 text-dc-text-secondary group-hover:text-dc-primary transition-colors" })
]
}
),
/* @__PURE__ */ o(
"div",
{
className: "space-y-2",
onDragLeave: u ? w : void 0,
onDragOver: u ? (x) => x.preventDefault() : void 0,
onDrop: u ? A : void 0,
children: [
_.map(({ metric: x, fieldMeta: N, sortDirection: S, sortPriority: y, index: M }) => {
const E = i(M), T = g(M);
return /* @__PURE__ */ o(
"div",
{
className: "relative",
style: {
transform: E,
transition: d !== null ? "transform 0.15s ease-out" : "none"
},
onDragOver: u ? (j) => $(j, M) : void 0,
onDrop: u ? A : void 0,
children: [
T && /* @__PURE__ */ e("div", { className: "absolute -top-5 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ e("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }),
/* @__PURE__ */ e(
So,
{
metric: x,
fieldMeta: N,
onRemove: () => a(x.id),
sortDirection: S,
sortPriority: y,
onToggleSort: l ? () => {
const j = _o(S);
l(x.field, j);
} : void 0,
index: M,
isDragging: d === M,
onDragStart: u ? R : void 0,
onDragEnd: u ? D : void 0
}
)
]
},
x.id
);
}),
u && d !== null && h === r.length && /* @__PURE__ */ e("div", { className: "relative h-2", children: /* @__PURE__ */ e("div", { className: "absolute top-0 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ e("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }) }),
u && r.length > 0 && d !== null && /* @__PURE__ */ e(
"div",
{
className: "h-8",
onDragOver: (x) => {
x.preventDefault();
const N = r.length, S = m.current;
v.current !== N && S !== N - 1 && (p(N), v.current = N);
},
onDrop: A
}
)
]
}
)
] });
}), Mo = [
{ value: "hour", label: "Hour" },
{ value: "day", label: "Day" },
{ value: "week", label: "Week" },
{ value: "month", label: "Month" },
{ value: "quarter", label: "Quarter" },
{ value: "year", label: "Year" }
], Cs = Ot(function({
breakdown: r,
fieldMeta: n,
onRemove: s,
onGranularityChange: a,
onComparisonToggle: c,
comparisonDisabled: l,
sortDirection: u,
sortPriority: d,
onToggleSort: f,
index: h,
isDragging: p,
onDragStart: m,
onDragEnd: v
}) {
const C = Q("dimension"), _ = Q("timeDimension"), b = Q("close"), R = Q("chevronUp"), D = Q("chevronDown"), $ = Q("chevronUpDown"), A = n?.shortTitle || n?.title || r.field.split(".").pop() || r.field, w = r.field.split(".")[0], i = r.isTimeDimension ? _ : C, g = () => {
switch (u) {
case "asc":
return R ? /* @__PURE__ */ e(R, { className: "w-4 h-4" }) : "↑";
case "desc":
return D ? /* @__PURE__ */ e(D, { className: "w-4 h-4" }) : "↓";
default:
return $ ? /* @__PURE__ */ e($, { className: "w-4 h-4" }) : "⇅";
}
}, x = () => {
switch (u) {
case "asc":
return "Sorted ascending (click for descending)";
case "desc":
return "Sorted descending (click to remove)";
default:
return "Click to sort ascending";
}
}, N = typeof h == "number" && m && v;
return /* @__PURE__ */ o(
"div",
{
className: `flex items-center gap-2 p-2 bg-dc-surface-secondary rounded-lg group hover:bg-dc-surface-tertiary transition-all duration-150 ${N ? "cursor-grab active:cursor-grabbing" : ""} ${p ? "opacity-30" : ""}`,
draggable: N ? !0 : void 0,
onDragStart: N ? (S) => m(S, h) : void 0,
onDragEnd: N ? v : void 0,
children: [
/* @__PURE__ */ e("span", { className: `w-6 h-6 flex items-center justify-center rounded flex-shrink-0 ${r.isTimeDimension ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text"}`, children: /* @__PURE__ */ e(i, { className: "w-4 h-4" }) }),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ e("div", { className: "text-sm text-dc-text truncate", title: r.field, children: A }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: w })
] }),
r.isTimeDimension && a && /* @__PURE__ */ e(
"select",
{
value: r.granularity || "day",
onChange: (S) => a(S.target.value),
onClick: (S) => S.stopPropagation(),
className: "text-xs bg-dc-surface border border-dc-border rounded px-2 py-1 text-dc-text focus:outline-none focus:ring-1 focus:ring-dc-primary flex-shrink-0",
children: Mo.map((S) => /* @__PURE__ */ e("option", { value: S.value, children: S.label }, S.value))
}
),
r.isTimeDimension && c && /* @__PURE__ */ e(
"button",
{
onClick: (S) => {
S.stopPropagation(), c();
},
disabled: l && !r.enableComparison,
className: `text-xs px-2 py-1 rounded flex-shrink-0 transition-colors ${r.enableComparison ? "bg-dc-accent text-white" : "bg-dc-surface border border-dc-border text-dc-text-muted hover:text-dc-text hover:bg-dc-surface-hover"} ${l && !r.enableComparison ? "opacity-50 cursor-not-allowed" : ""}`,
title: l && !r.enableComparison ? "Another time dimension already has comparison enabled" : r.enableComparison ? "Click to disable comparison" : "Compare with previous period",
children: "vs prior"
}
),
f && /* @__PURE__ */ o(
"button",
{
onClick: f,
className: `p-1 transition-opacity flex-shrink-0 flex items-center gap-0.5 ${u ? "opacity-100 text-dc-primary" : "opacity-100 sm:opacity-0 sm:group-hover:opacity-100 text-dc-text-muted hover:text-dc-primary"}`,
title: x(),
children: [
g(),
u && d && /* @__PURE__ */ o("span", { className: "text-xs font-medium", children: [
"(",
d,
")"
] })
]
}
),
/* @__PURE__ */ e(
"button",
{
onClick: s,
className: "p-1 text-dc-text-muted hover:text-dc-danger opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity flex-shrink-0",
title: "Remove breakdown",
children: /* @__PURE__ */ e(b, { className: "w-4 h-4" })
}
)
]
}
);
}), Oo = Q("add");
function $o(t, r) {
if (!r?.cubes) return null;
const [n] = t.split("."), s = r.cubes.find((a) => a.name === n);
return s && s.dimensions?.find((a) => a.name === t) || null;
}
function Io(t) {
switch (t) {
case null:
return "asc";
case "asc":
return "desc";
case "desc":
return null;
default:
return "asc";
}
}
const Lo = Ot(function({
breakdowns: r,
schema: n,
onAdd: s,
onRemove: a,
onGranularityChange: c,
onComparisonToggle: l,
order: u,
onOrderChange: d,
onReorder: f
}) {
const [h, p] = V(null), [m, v] = V(null), C = Ce(null), _ = Ce(null), b = ye(() => u ? Object.keys(u) : [], [u]), R = ye(() => r.find((M) => M.isTimeDimension && M.enableComparison)?.id || null, [r]), D = ye(() => r.map((y, M) => {
const E = u?.[y.field] || null, T = E ? b.indexOf(y.field) + 1 : void 0;
return {
breakdown: y,
fieldMeta: $o(y.field, n),
sortDirection: E,
sortPriority: T,
index: M
};
}), [r, n, u, b]), $ = Ce(null), A = F((y, M) => {
p(M), C.current = M, y.dataTransfer.effectAllowed = "move", y.dataTransfer.setData("text/plain", JSON.stringify({ type: "breakdown", index: M, field: r[M].field }));
const E = y.currentTarget, T = E.cloneNode(!0);
T.style.cssText = `
position: absolute;
top: -9999px;
left: -9999px;
width: ${E.offsetWidth}px;
opacity: 0.7;
transform: rotate(2deg);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
pointer-events: none;
`, document.body.appendChild(T), $.current = T;
const j = E.getBoundingClientRect(), q = y.clientX - j.left, I = y.clientY - j.top;
y.dataTransfer.setDragImage(T, q, I);
}, [r]), w = F(() => {
p(null), v(null), C.current = null, _.current = null, $.current && (document.body.removeChild($.current), $.current = null);
}, []), i = F((y, M) => {
y.preventDefault(), y.stopPropagation();
const E = C.current;
if (E === null) return;
const T = y.currentTarget.getBoundingClientRect();
let I = y.clientY - T.top < T.height / 2 ? M : M + 1;
I === E || I === E + 1 ? (v(null), _.current = null) : (v(I), _.current = I);
}, []), g = F((y) => {
y.preventDefault(), y.stopPropagation();
const M = C.current, E = _.current;
if (p(null), v(null), C.current = null, _.current = null, M === null || E === null || !f)
return;
const T = E > M ? E - 1 : E;
T !== M && f(M, T);
}, [f]), x = F((y) => {
const M = y.relatedTarget;
(!M || !y.currentTarget.contains(M)) && v(null);
}, []), N = F((y) => {
if (h === null || m === null) return "";
const M = 40;
if (y === h) return "";
if (h < m) {
if (y > h && y < m)
return "";
if (y === m - 1)
return `translateY(-${M / 2}px)`;
if (y >= m)
return `translateY(${M / 2}px)`;
} else if (y >= m && y < h)
return `translateY(${M / 2}px)`;
return "";
}, [h, m]), S = F((y) => h === null || m === null ? !1 : y === m, [h, m]);
return /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ o(
"button",
{
onClick: s,
className: "flex items-center justify-between mb-3 w-full py-1 px-2 -ml-2 rounded-lg hover:bg-dc-primary/10 transition-colors group",
title: "Add breakdown",
children: [
/* @__PURE__ */ e(Vt, { children: "Breakdown" }),
/* @__PURE__ */ e(Oo, { className: "w-5 h-5 text-dc-text-secondary group-hover:text-dc-primary transition-colors" })
]
}
),
/* @__PURE__ */ o(
"div",
{
className: "space-y-2",
onDragLeave: f ? x : void 0,
onDragOver: f ? (y) => y.preventDefault() : void 0,
onDrop: f ? g : void 0,
children: [
D.map(({ breakdown: y, fieldMeta: M, sortDirection: E, sortPriority: T, index: j }) => {
const q = N(j), I = S(j);
return /* @__PURE__ */ o(
"div",
{
className: "relative",
style: {
transform: q,
transition: h !== null ? "transform 0.15s ease-out" : "none"
},
onDragOver: f ? (K) => i(K, j) : void 0,
onDrop: f ? g : void 0,
children: [
I && /* @__PURE__ */ e("div", { className: "absolute -top-5 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ e("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }),
/* @__PURE__ */ e(
Cs,
{
breakdown: y,
fieldMeta: M,
onRemove: () => a(y.id),
onGranularityChange: y.isTimeDimension ? (K) => c(y.id, K) : void 0,
onComparisonToggle: y.isTimeDimension && l ? () => l(y.id) : void 0,
comparisonDisabled: R !== null && R !== y.id,
sortDirection: E,
sortPriority: T,
onToggleSort: d ? () => {
const K = Io(E);
d(y.field, K);
} : void 0,
index: j,
isDragging: h === j,
onDragStart: f ? A : void 0,
onDragEnd: f ? w : void 0
}
)
]
},
y.id
);
}),
f && h !== null && m === r.length && /* @__PURE__ */ e("div", { className: "relative h-2", children: /* @__PURE__ */ e("div", { className: "absolute top-0 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ e("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }) }),
f && r.length > 0 && h !== null && /* @__PURE__ */ e(
"div",
{
className: "h-8",
onDragOver: (y) => {
y.preventDefault();
const M = r.length, E = C.current;
_.current !== M && E !== M - 1 && (v(M), _.current = M);
},
onDrop: g
}
)
]
}
)
] });
}), Nn = Q("close"), Mr = Q("chevronDown"), Fo = Q("dimension"), qo = Q("timeDimension"), Po = Q("measure");
function jo({
filter: t,
schema: r,
onSave: n,
onCancel: s,
anchorElement: a
}) {
const [c, l] = V(t), [u, d] = V(!1), [f, h] = V(!1), [p, m] = V(!1), [v, C] = V("this_month"), [_, b] = V(1), [R, D] = V(""), [$, A] = V(null), w = Ce(null), i = rs(R, 300), g = Jr(c.member, r), x = g?.field.type || "string", N = x === "time", S = g?.fieldType === "measure", y = g?.fieldType === "dimension", M = ms(c.member, r), E = ar[c.operator], T = mo(x), j = N && c.operator === "inDateRange", q = F(() => ["equals", "notEquals", "in", "notIn"].includes(c.operator) && y && !N, [c.operator, y, N])(), {
values: I,
loading: K,
error: U,
searchValues: ke
} = ns(c.member, q);
ve(() => {
if (!a) {
A(null);
return;
}
const G = a.getBoundingClientRect(), X = 500, ae = G.top, qe = window.innerHeight - G.bottom, je = 400, nt = ae > X || ae > qe, Ie = Math.max(16, Math.min(G.left, window.innerWidth - je - 16));
A(nt ? {
bottom: window.innerHeight - G.top + 8,
left: Ie
} : {
top: G.bottom + 8,
left: Ie
});
}, [a]), ve(() => {
const G = (X) => {
w.current && !w.current.contains(X.target) && (d(!1), h(!1), m(!1));
};
return document.addEventListener("mousedown", G), () => document.removeEventListener("mousedown", G);
}, []), ve(() => {
f && q && ke && ke("", !0);
}, [f, q, ke]), ve(() => {
f && q && ke && i !== void 0 && ke(i);
}, [i, f, q, ke]), ve(() => {
if (!(!j || !c.dateRange))
if (Array.isArray(c.dateRange))
C("custom");
else {
const G = c.dateRange.match(/^last (\d+) (days|weeks|months|quarters|years)$/), X = !G && c.dateRange.match(/^last (day|week|month|quarter|year)$/);
if (G) {
const [, ae, qe] = G;
C(`last_n_${qe}`), b(parseInt(ae) || 1);
} else if (X) {
const [, ae] = X;
C(`last_n_${ae === "day" ? "days" : ae === "week" ? "weeks" : ae === "month" ? "months" : ae === "quarter" ? "quarters" : "years"}`), b(1);
} else {
let ae = !1;
for (const qe of Mt)
if (qe.value !== "custom" && !fr(qe.value) && Yt(qe.value) === c.dateRange) {
C(qe.value), ae = !0;
break;
}
ae || C("custom");
}
}
}, [c.dateRange, j]);
const De = F((G) => {
l({
member: c.member,
operator: G,
values: []
}), d(!1);
}, [c.member]), Pe = F((G) => {
const X = c.values || [];
E?.supportsMultipleValues ? X.includes(G) || l({ ...c, values: [...X, G] }) : (l({ ...c, values: [G] }), h(!1)), D("");
}, [c, E?.supportsMultipleValues]), B = F((G) => {
const X = (c.values || []).filter((ae) => ae !== G);
l({ ...c, values: X });
}, [c]), se = F((G) => {
const X = G.target.value;
if (E?.valueType === "number") {
const ae = parseFloat(X);
isNaN(ae) ? (X === "" || X === "-") && l({ ...c, values: [] }) : l({ ...c, values: [ae] });
} else
l({ ...c, values: X ? [X] : [] });
}, [c, E?.valueType]), Te = F((G) => {
const X = parseFloat(G.target.value), ae = c.values?.length >= 2 ? c.values : ["", ""], qe = [isNaN(X) ? "" : X, ae[1]].filter((je) => je !== "");
l({ ...c, values: qe });
}, [c]), H = F((G) => {
const X = parseFloat(G.target.value), qe = [(c.values?.length >= 2 ? c.values : ["", ""])[0], isNaN(X) ? "" : X].filter((je) => je !== "");
l({ ...c, values: qe });
}, [c]), ee = F((G) => {
const X = G.target.value;
l({ ...c, values: X ? [X] : [] });
}, [c]), le = F((G) => {
C(G), m(!1);
let X;
if (G === "custom") {
const ae = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
X = [ae, ae];
} else fr(G) ? X = Yt(G, _) : X = Yt(G);
l({ ...c, dateRange: X });
}, [c, _]), be = F((G) => {
if (b(G), fr(v)) {
const X = Yt(v, G);
l({ ...c, dateRange: X });
}
}, [c, v]), L = F((G) => {
const X = G.target.value, qe = (Array.isArray(c.dateRange) ? c.dateRange : [c.dateRange || "", ""])[1] || X;
l({ ...c, dateRange: [X, qe] });
}, [c]), te = F((G) => {
const X = G.target.value, qe = (Array.isArray(c.dateRange) ? c.dateRange : ["", c.dateRange || ""])[0] || X;
l({ ...c, dateRange: [qe, X] });
}, [c]), Ne = T.find((G) => G.operator === c.operator)?.label || c.operator, Ve = Mt.find((G) => G.value === v)?.label || "Select range", rt = N ? qo : S ? Po : Fo, Fe = () => E?.requiresValues ? j ? /* @__PURE__ */ o("div", { className: "space-y-2", children: [
/* @__PURE__ */ o("div", { className: "relative", children: [
/* @__PURE__ */ o(
"button",
{
onClick: () => {
d(!1), h(!1), m(!p);
},
className: "w-full flex items-center justify-between text-left text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text hover:bg-dc-surface-hover",
children: [
/* @__PURE__ */ e("span", { className: "truncate", children: Ve }),
/* @__PURE__ */ e(Mr, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-2 transition-transform ${p ? "rotate-180" : ""}` })
]
}
),
p && /* @__PURE__ */ e("div", { className: "absolute z-[60] left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded shadow-lg max-h-48 overflow-y-auto", children: Mt.map((G) => /* @__PURE__ */ e(
"button",
{
onClick: () => le(G.value),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover ${G.value === v ? "bg-dc-primary/10 text-dc-primary" : "text-dc-text"}`,
children: G.label
},
G.value
)) })
] }),
fr(v) && /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "number",
min: "1",
max: "1000",
value: _,
onChange: (G) => be(Math.max(1, parseInt(G.target.value) || 1)),
className: "flex-1 text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text w-20"
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text-muted", children: v.replace("last_n_", "") })
] }),
v === "custom" && /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "date",
value: Array.isArray(c.dateRange) ? c.dateRange[0] : "",
onChange: L,
className: "flex-1 text-sm border border-dc-border rounded px-2 py-2 bg-dc-surface text-dc-text"
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ e(
"input",
{
type: "date",
value: Array.isArray(c.dateRange) ? c.dateRange[1] : "",
onChange: te,
className: "flex-1 text-sm border border-dc-border rounded px-2 py-2 bg-dc-surface text-dc-text"
}
)
] })
] }) : c.operator === "between" || c.operator === "notBetween" ? /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "number",
value: c.values?.[0] ?? "",
onChange: Te,
placeholder: "Min",
className: "flex-1 text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ e(
"input",
{
type: "number",
value: c.values?.[1] ?? "",
onChange: H,
placeholder: "Max",
className: "flex-1 text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
)
] }) : E?.valueType === "date" ? /* @__PURE__ */ e(
"input",
{
type: "date",
value: c.values?.[0] || "",
onChange: ee,
className: "w-full text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
) : E?.valueType === "number" ? /* @__PURE__ */ e(
"input",
{
type: "number",
value: c.values?.[0] ?? "",
onChange: se,
placeholder: "Enter number",
className: "w-full text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
) : q ? /* @__PURE__ */ o("div", { className: "space-y-2", children: [
c.values && c.values.length > 0 && /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1.5", children: c.values.map((G, X) => /* @__PURE__ */ o(
"span",
{
className: "inline-flex items-center gap-1 bg-dc-primary/10 text-dc-primary text-sm px-2 py-1 rounded",
children: [
/* @__PURE__ */ e("span", { className: "max-w-[150px] truncate", children: String(G) }),
/* @__PURE__ */ e(
"button",
{
onClick: () => B(G),
className: "hover:text-dc-danger",
children: /* @__PURE__ */ e(Nn, { className: "w-3.5 h-3.5" })
}
)
]
},
X
)) }),
/* @__PURE__ */ o("div", { className: "relative", children: [
/* @__PURE__ */ o(
"button",
{
onClick: () => {
d(!1), m(!1), h(!f);
},
className: "w-full flex items-center justify-between text-left text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text hover:bg-dc-surface-hover",
children: [
/* @__PURE__ */ e("span", { className: "text-dc-text-muted truncate", children: K ? "Loading..." : "Select value..." }),
/* @__PURE__ */ e(Mr, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-2 transition-transform ${f ? "rotate-180" : ""}` })
]
}
),
f && /* @__PURE__ */ o("div", { className: "absolute z-[60] left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded shadow-lg max-h-56 overflow-hidden", children: [
/* @__PURE__ */ e("div", { className: "p-2 border-b border-dc-border", children: /* @__PURE__ */ e(
"input",
{
type: "text",
value: R,
onChange: (G) => D(G.target.value),
placeholder: "Search...",
className: "w-full text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text",
autoFocus: !0
}
) }),
/* @__PURE__ */ e("div", { className: "max-h-40 overflow-y-auto", children: K ? /* @__PURE__ */ e("div", { className: "px-3 py-2 text-sm text-dc-text-muted", children: "Loading..." }) : U ? /* @__PURE__ */ o("div", { className: "px-3 py-2 text-sm text-dc-error", children: [
"Error: ",
U
] }) : I.length === 0 ? /* @__PURE__ */ e("div", { className: "px-3 py-2 text-sm text-dc-text-muted", children: "No values found" }) : I.map((G, X) => {
const ae = c.values?.includes(G);
return /* @__PURE__ */ o(
"button",
{
onClick: () => Pe(G),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover ${ae ? "bg-dc-primary/10 text-dc-primary" : "text-dc-text"}`,
children: [
String(G),
ae && /* @__PURE__ */ e("span", { className: "float-right", children: "✓" })
]
},
`${G}-${X}`
);
}) })
] })
] })
] }) : /* @__PURE__ */ e(
"input",
{
type: "text",
value: c.values?.[0] ?? "",
onChange: se,
placeholder: "Enter value...",
className: "w-full text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text placeholder-dc-text-muted"
}
) : /* @__PURE__ */ e("div", { className: "text-sm text-dc-text-muted italic py-2", children: "No value required" });
return /* @__PURE__ */ e(Oe, { children: /* @__PURE__ */ e(
"div",
{
className: `fixed inset-0 bg-dc-overlay z-50 ${$ ? "" : "flex items-center justify-center p-4"}`,
onClick: s,
children: /* @__PURE__ */ o(
"div",
{
ref: w,
className: $ ? "bg-dc-surface rounded-lg shadow-xl" : "bg-dc-surface rounded-lg shadow-xl max-w-md w-full",
style: $ ? {
position: "fixed",
...$,
maxWidth: "400px",
width: "100%"
} : {},
onClick: (G) => G.stopPropagation(),
children: [
/* @__PURE__ */ o("div", { className: "flex items-center justify-between p-4 border-b border-dc-border", children: [
/* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-dc-text", children: "Edit Filter" }),
/* @__PURE__ */ e(
"button",
{
onClick: s,
className: "p-1 text-dc-text-muted hover:text-dc-text transition-colors",
children: /* @__PURE__ */ e(Nn, { className: "w-5 h-5" })
}
)
] }),
/* @__PURE__ */ o("div", { className: "p-4 space-y-4", children: [
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("label", { className: "block text-sm font-medium text-dc-text-secondary mb-2", children: "Field" }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 p-3 bg-dc-surface-secondary rounded", children: [
/* @__PURE__ */ e(rt, { className: "w-5 h-5 text-dc-filter-text" }),
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-dc-text", children: M })
] })
] }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("label", { className: "block text-sm font-medium text-dc-text-secondary mb-2", children: "Operator" }),
/* @__PURE__ */ o("div", { className: "relative", children: [
/* @__PURE__ */ o(
"button",
{
onClick: () => {
h(!1), m(!1), d(!u);
},
className: "w-full flex items-center justify-between text-left text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text hover:bg-dc-surface-hover",
children: [
/* @__PURE__ */ e("span", { className: "truncate", children: Ne }),
/* @__PURE__ */ e(Mr, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-2 transition-transform ${u ? "rotate-180" : ""}` })
]
}
),
u && /* @__PURE__ */ e("div", { className: "absolute z-[60] left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded shadow-lg max-h-48 overflow-y-auto", children: T.map((G) => /* @__PURE__ */ e(
"button",
{
onClick: () => De(G.operator),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover ${G.operator === c.operator ? "bg-dc-primary/10 text-dc-primary" : "text-dc-text"}`,
children: G.label
},
G.operator
)) })
] })
] }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("label", { className: "block text-sm font-medium text-dc-text-secondary mb-2", children: "Value" }),
Fe()
] })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center justify-end gap-2 p-4 border-t border-dc-border", children: [
/* @__PURE__ */ e(
"button",
{
onClick: s,
className: "px-4 py-2 text-sm font-medium text-dc-text-secondary hover:text-dc-text transition-colors",
children: "Cancel"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: () => n(c),
className: "px-4 py-2 text-sm font-medium text-dc-primary-content bg-dc-primary hover:bg-dc-primary-hover rounded transition-colors",
children: "Save"
}
)
] })
]
}
)
}
) });
}
const Cn = Q("close"), Bo = Q("dimension"), Vo = Q("timeDimension"), Qo = Q("measure");
function ks({
filter: t,
schema: r,
onRemove: n,
onUpdate: s
}) {
const [a, c] = V(!1), l = Ce(null), u = Jr(t.member, r), f = (u?.field.type || "string") === "time", h = u?.fieldType === "measure", p = ms(t.member, r), m = ar[t.operator], v = m?.label || t.operator, C = Uo(t, m), _ = f ? Vo : h ? Qo : Bo;
return /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ o(
"div",
{
className: "flex items-start gap-2 px-2 py-1.5 bg-dc-surface-secondary rounded-lg group hover:bg-dc-surface-tertiary transition-all duration-150 w-full",
children: [
/* @__PURE__ */ e("span", { className: `w-6 h-6 flex items-center justify-center rounded ${f ? "bg-dc-time-dimension" : h ? "bg-dc-measure" : "bg-dc-dimension"} ${f ? "text-dc-time-dimension-text" : h ? "text-dc-measure-text" : "text-dc-dimension-text"} flex-shrink-0 mt-0.5`, children: _ && /* @__PURE__ */ e(_, { className: "w-4 h-4" }) }),
/* @__PURE__ */ e(
"button",
{
ref: l,
onClick: () => c(!0),
className: "flex-1 min-w-0 text-left",
title: `${p} ${v} ${C}`,
children: /* @__PURE__ */ o("div", { className: "text-sm text-dc-text break-words", children: [
/* @__PURE__ */ e("span", { className: "font-medium", children: p }),
/* @__PURE__ */ e("span", { className: "text-dc-text-muted mx-1", children: v }),
/* @__PURE__ */ e("span", { className: "text-dc-primary", children: C })
] })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: n,
className: "p-1 text-dc-text-muted hover:text-dc-danger opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity flex-shrink-0 mt-0.5",
title: "Remove filter",
children: Cn && /* @__PURE__ */ e(Cn, { className: "w-4 h-4" })
}
)
]
}
),
a && /* @__PURE__ */ e(
jo,
{
filter: t,
schema: r,
onSave: (D) => {
s(D), c(!1);
},
onCancel: () => c(!1),
anchorElement: l.current
}
)
] });
}
function Uo(t, r) {
if (!r?.requiresValues)
return "";
if (t.dateRange)
return Array.isArray(t.dateRange) ? `${t.dateRange[0]} to ${t.dateRange[1]}` : t.dateRange;
const n = t.values || [];
return n.length === 0 ? "(empty)" : n.length === 1 ? String(n[0]) : n.length === 2 ? `${n[0]}, ${n[1]}` : `${n[0]}, ${n[1]}, +${n.length - 2} more`;
}
const Ho = Q("add"), zo = Q("close");
function Go(t) {
return "member" in t && typeof t.member == "string";
}
function Wo(t) {
return "type" in t && (t.type === "and" || t.type === "or");
}
function Ds({
group: t,
schema: r,
onUpdate: n,
onRemove: s,
onAddFilter: a,
depth: c = 0,
hideRemoveButton: l = !1
}) {
const [u, d] = V(!1), f = Ce(null);
ve(() => {
const A = (w) => {
f.current && !f.current.contains(w.target) && d(!1);
};
return document.addEventListener("mousedown", A), () => document.removeEventListener("mousedown", A);
}, []);
const h = F(() => {
const A = t.type === "and" ? "or" : "and";
n({ ...t, type: A });
}, [t, n]), p = F((A, w) => {
const i = [...t.filters];
i[A] = w, n({ ...t, filters: i });
}, [t, n]), m = F((A) => {
const w = t.filters.filter((i, g) => g !== A);
w.length === 0 ? s() : w.length === 1 && c > 0 ? n({ ...t, filters: w }) : n({ ...t, filters: w });
}, [t, n, s, c]), v = F((A) => {
const w = { type: A, filters: [] };
n({ ...t, filters: [...t.filters, w] }), d(!1);
}, [t, n]), C = F(() => {
a([]), d(!1);
}, [a]), _ = F((A) => (w = []) => {
a([A, ...w]);
}, [a]), b = () => c % 2 === 0 ? "border-dc-border" : "border-dc-border dark:border-dc-border", R = () => t.type === "and" ? "bg-dc-info-bg/50" : "bg-dc-warning-bg/50", D = t.filters.length, $ = D === 1 ? "condition" : "conditions";
return /* @__PURE__ */ o("div", { className: `border ${b()} rounded-lg bg-dc-surface w-full`, children: [
/* @__PURE__ */ o("div", { className: `flex items-center justify-between px-2 py-1.5 border-b border-dc-border/50 rounded-t-lg ${R()}`, children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e(
"button",
{
onClick: h,
className: `px-2 py-0.5 text-xs font-semibold rounded transition-colors ${t.type === "and" ? "bg-dc-info-bg text-dc-info hover:opacity-80" : "bg-dc-warning-bg text-dc-warning hover:opacity-80"}`,
title: `Click to switch to ${t.type === "and" ? "OR" : "AND"}`,
children: t.type.toUpperCase()
}
),
/* @__PURE__ */ o("span", { className: "text-xs text-dc-text-muted", children: [
D,
" ",
$
] })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-1", children: [
/* @__PURE__ */ o("div", { className: "relative", ref: f, children: [
/* @__PURE__ */ e(
"button",
{
onClick: () => d(!u),
className: "p-1 text-dc-text-secondary hover:text-dc-primary hover:bg-dc-surface-hover rounded transition-colors",
title: "Add condition",
children: /* @__PURE__ */ e(Ho, { className: "w-4 h-4" })
}
),
u && /* @__PURE__ */ o("div", { className: "absolute right-0 mt-1 z-40 bg-dc-surface border border-dc-border rounded shadow-lg py-1 min-w-[120px]", children: [
/* @__PURE__ */ e(
"button",
{
onClick: C,
className: "w-full text-left px-3 py-1.5 text-xs text-dc-text hover:bg-dc-surface-hover",
children: "Add Filter"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: () => v("and"),
className: "w-full text-left px-3 py-1.5 text-xs text-dc-text hover:bg-dc-surface-hover",
children: "Add AND Group"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: () => v("or"),
className: "w-full text-left px-3 py-1.5 text-xs text-dc-text hover:bg-dc-surface-hover",
children: "Add OR Group"
}
)
] })
] }),
!l && /* @__PURE__ */ e(
"button",
{
onClick: s,
className: "p-1 text-dc-text-muted hover:text-dc-danger transition-colors",
title: "Remove group",
children: /* @__PURE__ */ e(zo, { className: "w-4 h-4" })
}
)
] })
] }),
/* @__PURE__ */ e("div", { className: "p-1.5 flex flex-wrap gap-2", children: t.filters.length === 0 ? /* @__PURE__ */ o("div", { className: "text-center py-3", children: [
/* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted mb-1", children: "No conditions in this group" }),
/* @__PURE__ */ e(
"button",
{
onClick: () => a([]),
className: "text-xs text-dc-primary hover:underline",
children: "Add a filter"
}
)
] }) : t.filters.map((A, w) => Go(A) ? /* @__PURE__ */ e(
ks,
{
filter: A,
schema: r,
onUpdate: (i) => p(w, i),
onRemove: () => m(w)
},
`filter-${w}`
) : Wo(A) ? /* @__PURE__ */ e(
Ds,
{
group: A,
schema: r,
onUpdate: (i) => p(w, i),
onRemove: () => m(w),
onAddFilter: _(w),
depth: c + 1
},
`group-${w}`
) : null) })
] });
}
const Yo = Q("add");
function Sr(t) {
return "member" in t && typeof t.member == "string";
}
function Jt(t) {
return "type" in t && (t.type === "and" || t.type === "or");
}
function Ts(t) {
let r = 0;
for (const n of t)
Sr(n) ? r++ : Jt(n) && (r += Ts(n.filters));
return r;
}
function Ss(t) {
const r = [];
for (const n of t)
Sr(n) ? r.push(n.member) : Jt(n) && r.push(...Ss(n.filters));
return r;
}
function As(t, r, n) {
if (r.length === 0)
return t.length === 0 ? [n] : t.length === 1 && Sr(t[0]) ? [{ type: "and", filters: [t[0], n] }] : t.length === 1 && Jt(t[0]) ? [{
...t[0],
filters: [...t[0].filters, n]
}] : [{ type: "and", filters: [...t, n] }];
const [s, ...a] = r, c = [...t], l = c[s];
return Jt(l) && (a.length === 0 ? c[s] = {
...l,
filters: [...l.filters, n]
} : c[s] = {
...l,
filters: As(l.filters, a, n)
}), c;
}
function Jo({
filters: t,
schema: r,
onFiltersChange: n,
onFieldDropped: s
}) {
const [a, c] = V(!1), [l, u] = V(!1), d = Ce([]), f = Ts(t), h = F((w) => {
w.preventDefault(), w.stopPropagation(), u(!0);
}, []), p = F((w) => {
w.preventDefault(), w.stopPropagation(), u(!1);
}, []), m = F((w) => {
w.preventDefault(), w.stopPropagation(), u(!1);
try {
const i = JSON.parse(w.dataTransfer.getData("text/plain"));
i.field && s && s(i.field);
} catch {
}
}, [s]), v = Ss(t), C = F(
(w, i, g) => {
const x = w.type === "time", N = x ? "inDateRange" : "equals", S = {
member: w.name,
operator: N,
values: []
};
x && N === "inDateRange" && (S.dateRange = Yt("this_month"));
const y = As(t, d.current, S);
n(y), c(!1), d.current = [];
},
[t, n]
), _ = F(
(w, i) => {
const g = [...t];
g[w] = i, n(g);
},
[t, n]
), b = F(
(w) => {
const i = t.filter((g, x) => x !== w);
if (i.length === 1 && Jt(i[0])) {
const g = i[0];
if (g.filters.length === 1) {
n([g.filters[0]]);
return;
}
}
n(i);
},
[t, n]
), R = F(() => {
n([]);
}, [n]), D = F(() => {
d.current = [], c(!0);
}, []), $ = F((w) => (i = []) => {
d.current = [...w, ...i], c(!0);
}, []), A = (w, i, g = []) => {
const x = [...g, i];
return Sr(w) ? /* @__PURE__ */ e(
ks,
{
filter: w,
schema: r,
onUpdate: (N) => _(i, N),
onRemove: () => b(i)
},
`filter-${x.join("-")}`
) : Jt(w) ? /* @__PURE__ */ e(
Ds,
{
group: w,
schema: r,
onUpdate: (N) => _(i, N),
onRemove: () => b(i),
onAddFilter: $(x),
hideRemoveButton: t.length === 1
},
`group-${x.join("-")}`
) : null;
};
return /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ o(
"button",
{
onClick: D,
className: "flex items-center justify-between mb-3 w-full py-1 px-2 -ml-2 rounded-lg hover:bg-dc-primary/10 transition-colors group",
title: "Add filter",
children: [
/* @__PURE__ */ o(Vt, { children: [
"Filter",
f > 0 && /* @__PURE__ */ o("span", { className: "ml-1.5 text-xs font-normal text-dc-text-muted normal-case tracking-normal", children: [
"(",
f,
")"
] })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
f > 0 && /* @__PURE__ */ e(
"span",
{
role: "button",
tabIndex: 0,
onClick: (w) => {
w.stopPropagation(), R();
},
onKeyDown: (w) => {
(w.key === "Enter" || w.key === " ") && (w.stopPropagation(), R());
},
className: "text-xs text-dc-text-muted hover:text-dc-error underline cursor-pointer",
children: "Clear all"
}
),
/* @__PURE__ */ e(Yo, { className: "w-5 h-5 text-dc-text-secondary group-hover:text-dc-primary transition-colors" })
] })
]
}
),
/* @__PURE__ */ e(
"div",
{
onDragOver: s ? h : void 0,
onDragLeave: s ? p : void 0,
onDrop: s ? m : void 0,
className: `p-2 -mx-2 rounded-lg border-2 border-dashed transition-all ${l ? "border-dc-primary bg-dc-primary/5" : "border-transparent"}`,
children: t.length === 0 ? /* @__PURE__ */ e("p", { className: `text-sm ${l ? "text-dc-primary font-medium" : "text-dc-text-muted"}`, children: l ? "Drop to add filter" : "No filters applied" }) : /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-2", children: t.map((w, i) => A(w, i)) })
}
),
/* @__PURE__ */ e(
gs,
{
isOpen: a,
onClose: () => {
c(!1), d.current = [];
},
onSelect: C,
mode: "filter",
schema: r,
selectedFields: v
}
)
] });
}
const Ko = Q("close"), Xo = Q("dimension"), Zo = Q("timeDimension"), ec = Q("measure");
function tc({
config: t,
fields: r,
onDrop: n,
onRemove: s,
onDragStart: a,
onDragEnd: c,
onDragOver: l,
onReorder: u,
draggedItem: d,
getFieldMeta: f,
yAxisAssignment: h,
onYAxisAssignmentChange: p
}) {
const { key: m, label: v, description: C, mandatory: _, maxItems: b, emptyText: R } = t, [D, $] = V(null), [A, w] = V(!1), [i, g] = V(!1), x = Ce(null), N = Ce(null), S = Ce(r);
S.current = r;
const y = Ce(null), M = () => {
let B = r.length;
return d && d.fromAxis === m && (B = Math.max(0, r.length - 1)), !b || B < b;
}, E = () => {
let B = r.length;
return d && d.fromAxis === m && (B = Math.max(0, r.length - 1)), b && B >= b;
}, T = M(), j = E();
ve(() => {
const B = () => {
$(null), y.current = null, w(!1), g(!1), x.current = null;
};
return document.addEventListener("dragend", B), () => {
document.removeEventListener("dragend", B);
};
}, []), ve(() => {
d ? d.fromAxis !== m ? (g(!1), $(null), y.current = null) : d.fromAxis === m && d.fromIndex !== void 0 && w(!1) : ($(null), y.current = null, w(!1), g(!1));
}, [d, m]);
const q = F((B, se) => {
if (!d || d.fromAxis !== m || d.fromIndex === void 0) return;
B.preventDefault(), B.stopPropagation();
const Te = B.currentTarget.getBoundingClientRect(), ee = B.clientY - Te.top < Te.height / 2, le = d.fromIndex;
let be = ee ? se : se + 1;
be === le || be === le + 1 ? ($(null), y.current = null) : ($(be), y.current = be, g(!0));
}, [d, m]), I = F((B) => {
B.preventDefault();
const se = y.current;
if (!(d && d.fromAxis === m && d.fromIndex !== void 0 && se !== null)) {
$(null), y.current = null, g(!1);
return;
}
B.stopPropagation();
const H = d.fromIndex, ee = se > H ? se - 1 : se;
u && ee !== H && u(H, ee, m), $(null), y.current = null, g(!1);
}, [d, m, u]), K = F((B, se) => {
const Te = N.current;
if (Te && x.current === se) {
const H = Te.getBoundingClientRect();
B.clientX >= H.left && B.clientX <= H.right && B.clientY >= H.top && B.clientY <= H.bottom || setTimeout(() => {
S.current.includes(se) && s(se, m);
}, 0);
}
x.current = null, $(null), y.current = null, g(!1), c?.(B);
}, [m, s, c]), U = F((B) => {
if (!d || d.fromAxis !== m || d.fromIndex === void 0 || D === null)
return "";
const se = d.fromIndex, Te = 40;
if (B === se) return "";
if (se < D) {
if (B >= D)
return `translateY(${Te / 2}px)`;
} else if (B >= D && B < se)
return `translateY(${Te / 2}px)`;
return "";
}, [d, m, D]), ke = F((B) => !d || d.fromAxis !== m || D === null ? !1 : B === D, [d, m, D]), De = (B) => {
const se = B.split("."), Te = se[0] || B, H = se[1] || B;
return {
title: H,
shortTitle: H,
cubeName: Te,
type: "dimension"
// Default assumption
};
}, Pe = (B) => {
if (B.type === "measure") {
const se = Xt(B.measureType || "count") || ec;
return /* @__PURE__ */ e("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-measure text-dc-measure-text flex-shrink-0", children: /* @__PURE__ */ e(se, { className: "w-4 h-4" }) });
} else return B.type === "timeDimension" ? /* @__PURE__ */ e("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-time-dimension text-dc-time-dimension-text flex-shrink-0", children: /* @__PURE__ */ e(Zo, { className: "w-4 h-4" }) }) : /* @__PURE__ */ e("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-dimension text-dc-dimension-text flex-shrink-0", children: /* @__PURE__ */ e(Xo, { className: "w-4 h-4" }) });
};
return /* @__PURE__ */ o("div", { className: "mb-3", children: [
/* @__PURE__ */ o("div", { className: "mb-2", children: [
/* @__PURE__ */ o("h4", { className: "text-sm font-medium text-dc-text flex items-center", children: [
v,
_ && /* @__PURE__ */ e("span", { className: "text-dc-error ml-1", children: "*" })
] }),
C && /* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted mt-0.5", children: C })
] }),
/* @__PURE__ */ e(
"div",
{
ref: N,
"data-axis-container": m,
className: `min-h-[48px] border-2 border-dashed rounded-lg p-2 transition-all duration-200 ${A && (T || b === 1) || i ? "shadow-sm border-solid" : j ? "bg-dc-surface-secondary" : "bg-dc-surface-secondary hover:bg-dc-surface-hover"}`,
style: {
borderColor: A && (T || b === 1) || i ? "var(--dc-primary)" : "var(--dc-border)",
backgroundColor: A && (T || b === 1) || i ? "rgba(var(--dc-primary-rgb), 0.1)" : void 0
},
onDragOver: (B) => {
if (d && d.fromAxis === m && d.fromIndex !== void 0)
return;
T || b === 1 ? (w(!0), l(B)) : (B.preventDefault(), B.dataTransfer.dropEffect = "none");
},
onDragLeave: (B) => {
const se = B.currentTarget.getBoundingClientRect(), Te = B.clientX < se.left || B.clientX > se.right || B.clientY < se.top || B.clientY > se.bottom, H = B.relatedTarget, ee = H && !B.currentTarget.contains(H);
(Te || ee || B.currentTarget === B.target) && (w(!1), g(!1));
},
onDrop: (B) => {
if (d && d.fromAxis === m && d.fromIndex !== void 0)
return;
T || b === 1 ? n(B, m) : B.preventDefault(), w(!1), g(!1);
},
children: r.length === 0 ? /* @__PURE__ */ e("div", { className: "text-sm text-dc-text-muted text-center py-2", children: j ? "Maximum items reached" : R || "Drop fields here" }) : /* @__PURE__ */ o(
"div",
{
className: "space-y-2",
onDragOver: (B) => {
d && d.fromAxis === m && B.preventDefault();
},
onDrop: (B) => {
d && d.fromAxis === m && d.fromIndex !== void 0 && I(B);
},
children: [
r.map((B, se) => {
const Te = f ? f(B) : De(B), H = d && d.field === B && d.fromAxis === m, ee = U(se), le = ke(se);
return /* @__PURE__ */ o(
"div",
{
className: "relative",
style: {
transform: ee,
transition: d && d.fromAxis === m ? "transform 0.15s ease-out" : "none"
},
children: [
le && /* @__PURE__ */ e("div", { className: "absolute -top-5 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ e("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }),
/* @__PURE__ */ o(
"div",
{
draggable: !0,
onDragStart: (be) => {
x.current = B, a(be, B, m, se);
},
onDragEnd: (be) => K(be, B),
onDragOver: (be) => q(be, se),
onDrop: I,
className: `flex items-center gap-2 p-2 bg-dc-surface rounded-lg group hover:bg-dc-surface-tertiary transition-colors cursor-move ${H ? "opacity-30 cursor-grabbing" : ""}`,
children: [
Pe(Te),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ e("div", { className: "text-sm text-dc-text truncate", title: B, children: Te.shortTitle || Te.title || B.split(".").pop() }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: Te.cubeName })
] }),
t.enableDualAxis && p && /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: (be) => {
be.stopPropagation();
const L = h?.[B] || "left";
p(B, L === "left" ? "right" : "left");
},
className: `px-1.5 py-0.5 text-xs font-medium rounded transition-colors flex-shrink-0 ${(h?.[B] || "left") === "left" ? "bg-dc-info-bg text-dc-info hover:opacity-80" : "bg-dc-accent-bg text-dc-accent hover:opacity-80"}`,
title: `Y-Axis: ${(h?.[B] || "left") === "left" ? "Left" : "Right"} (click to toggle)`,
children: (h?.[B] || "left") === "left" ? "L" : "R"
}
),
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => s(B, m),
className: "p-1 text-dc-text-muted hover:text-dc-danger opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0",
title: `Remove from ${v}`,
children: /* @__PURE__ */ e(Ko, { className: "w-4 h-4" })
}
)
]
}
)
]
},
`${B}-${se}`
);
}),
d && d.fromAxis === m && D === r.length && /* @__PURE__ */ e("div", { className: "relative h-2", children: /* @__PURE__ */ e("div", { className: "absolute top-0 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ e("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }) }),
d && d.fromAxis === m && r.length > 1 && /* @__PURE__ */ e(
"div",
{
className: "h-6",
onDragOver: (B) => {
if (d.fromIndex !== void 0) {
B.preventDefault();
const se = r.length;
y.current !== se && d.fromIndex !== se - 1 && ($(se), y.current = se, g(!0));
}
},
onDrop: I
}
)
]
}
)
}
),
_ && r.length === 0 && /* @__PURE__ */ e("div", { className: "text-xs text-dc-error mt-1", children: "This field is required" })
] });
}
const Kt = {
bar: ua,
line: da,
area: ia,
pie: la,
scatter: ca,
bubble: oa,
radar: aa,
radialBar: sa,
treemap: na,
table: ra,
activityGrid: ta,
kpiNumber: ea,
kpiDelta: Zs,
kpiText: Xs,
markdown: Ks
}, pr = {
activityGrid: "Activity Grid",
area: "Area Chart",
bar: "Bar Chart",
bubble: "Bubble Chart",
kpiDelta: "KPI Delta",
kpiNumber: "KPI Number",
kpiText: "KPI Text",
line: "Line Chart",
markdown: "Markdown",
pie: "Pie Chart",
radar: "Radar Chart",
radialBar: "Radial Bar Chart",
scatter: "Scatter Plot",
table: "Data Table",
treemap: "TreeMap"
};
function Es({
selectedType: t,
onTypeChange: r,
className: n = "",
compact: s = !1,
availability: a
}) {
const [c, l] = V(!1), u = Object.entries(Kt).sort((p, m) => {
const v = pr[p[0]] || p[0], C = pr[m[0]] || m[0];
return v.localeCompare(C);
}), f = Kt[t]?.icon, h = pr[t];
return /* @__PURE__ */ o("div", { className: `${n} relative`, children: [
/* @__PURE__ */ o(
"button",
{
type: "button",
onClick: () => l(!c),
className: "w-full flex items-center justify-between px-3 py-2 border border-dc-border rounded-md bg-dc-surface hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-dc-accent focus:border-dc-accent",
children: [
/* @__PURE__ */ o("div", { className: "flex items-center space-x-2", children: [
f && /* @__PURE__ */ e(f, { className: "h-5 w-5 text-dc-text-secondary" }),
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-dc-text", children: h })
] }),
/* @__PURE__ */ e(
"svg",
{
className: `h-4 w-4 text-dc-text-muted transform transition-transform ${c ? "rotate-180" : ""}`,
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor",
children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
}
)
]
}
),
c && /* @__PURE__ */ e("div", { className: `absolute z-10 mt-1 w-full bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-80 overflow-auto ${s ? "" : "min-w-max"}`, children: /* @__PURE__ */ e("div", { className: "p-2", children: /* @__PURE__ */ e("div", { className: `grid gap-1.5 ${s ? "grid-cols-2" : "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4"}`, children: u.map(([p, m]) => {
const v = m.icon, C = pr[p], _ = t === p, b = m.description, R = m.useCase, D = a?.[p], $ = D?.available ?? !0, A = D?.reason, w = !$ && A ? A : [b, R].filter(Boolean).join(". ");
return /* @__PURE__ */ o(
"button",
{
type: "button",
onClick: () => {
$ && (r(p), l(!1));
},
disabled: !$,
className: `
relative p-1.5 rounded border transition-colors duration-150
text-left group min-h-[30px] flex items-center justify-start
${$ ? _ ? "bg-dc-surface-secondary" : "bg-dc-surface hover:bg-dc-surface-hover" : "opacity-50 cursor-not-allowed bg-dc-surface"}
`,
style: {
borderColor: _ && $ ? "var(--dc-primary)" : "var(--dc-border)"
},
title: w,
children: [
/* @__PURE__ */ o("div", { className: "flex items-center space-x-1.5", children: [
v && /* @__PURE__ */ e(
v,
{
className: `h-4 w-4 shrink-0 ${$ ? _ ? "text-dc-text" : "text-dc-text-secondary" : "text-dc-text-muted"}`
}
),
/* @__PURE__ */ e(
"span",
{
className: `text-xs font-medium leading-tight truncate ${$ ? _ ? "" : "text-dc-text" : "text-dc-text-muted"}`,
style: _ && $ ? { color: "var(--dc-primary)" } : void 0,
children: C
}
)
] }),
_ && $ && /* @__PURE__ */ e("div", { className: "absolute top-0.5 right-0.5", children: /* @__PURE__ */ e("div", { className: "w-1.5 h-1.5 rounded-full", style: { backgroundColor: "var(--dc-primary)" } }) })
]
},
p
);
}) }) }) })
] });
}
const rc = Q("measure"), nc = Q("dimension"), sc = Q("timeDimension");
function ac({
chartType: t,
chartConfig: r,
metrics: n,
breakdowns: s,
schema: a,
chartAvailability: c,
onChartTypeChange: l,
onChartConfigChange: u
}) {
const [d, f] = V(null), h = ye(
() => ({
measures: n.map((y) => y.field),
dimensions: s.filter((y) => !y.isTimeDimension).map((y) => y.field),
timeDimensions: s.filter((y) => y.isTimeDimension).map((y) => y.field)
}),
[n, s]
), p = ye(
() => Dr(t, Kt),
[t]
), m = p.skipQuery === !0, v = (y) => {
const M = r[y];
return Array.isArray(M) ? M : typeof M == "string" ? [M] : [];
};
ve(() => {
const y = [
...h.dimensions,
...h.timeDimensions,
...h.measures
];
let M = !1;
const E = { ...r };
p.dropZones.forEach((T) => {
const j = v(T.key), q = j.filter((I) => y.includes(I));
q.length !== j.length && (M = !0, q.length === 0 ? delete E[T.key] : T.maxItems === 1 ? E[T.key] = q[0] : E[T.key] = q);
}), M && u(E);
}, [h, r, p.dropZones, u]);
const C = (y) => h.measures.includes(y) ? "measure" : h.timeDimensions.includes(y) ? "timeDimension" : "dimension", _ = (y) => {
if (!a?.cubes) return null;
const [M] = y.split("."), E = a.cubes.find((q) => q.name === M);
if (!E) return null;
const T = E.measures?.find((q) => q.name === y);
if (T) return { ...T, fieldType: "measure" };
const j = E.dimensions?.find((q) => q.name === y);
return j ? { ...j, fieldType: j.type === "time" ? "timeDimension" : "dimension" } : null;
}, b = (y) => {
const M = C(y), E = y.split("."), T = E[0] || y, j = E[1] || y, q = _(y), I = s.find((K) => K.field === y);
return q ? {
title: q.title || j,
shortTitle: q.shortTitle || q.title || j,
cubeName: T,
type: q.fieldType,
measureType: q.fieldType === "measure" ? q.type : void 0
} : I ? {
title: j,
shortTitle: j,
cubeName: T,
type: I.isTimeDimension ? "timeDimension" : "dimension"
} : {
title: j,
shortTitle: j,
cubeName: T,
type: M
};
}, R = (y, M, E, T) => {
y.dataTransfer.setData("text/plain", JSON.stringify({ field: M, fromAxis: E, fromIndex: T })), f({ field: M, fromAxis: E, fromIndex: T });
}, D = (y) => {
y.preventDefault();
}, $ = () => {
f(null);
}, A = (y, M) => {
y.preventDefault();
const E = JSON.parse(y.dataTransfer.getData("text/plain")), { field: T, fromAxis: j } = E, q = { ...r };
if (j !== "available" && j !== M) {
const U = q[j];
if (Array.isArray(U)) {
const ke = U.filter((De) => De !== T);
ke.length === 0 ? delete q[j] : q[j] = ke;
} else U === T && delete q[j];
}
const I = q[M], K = p.dropZones.find((U) => U.key === M);
if (K?.maxItems === 1 ? q[M] = T : Array.isArray(I) ? I.includes(T) || (q[M] = [...I, T]) : q[M] = [T], M === "yAxis" && K?.enableDualAxis) {
const ke = (Array.isArray(q.yAxis) ? q.yAxis : [T]).indexOf(T);
q.yAxisAssignment?.[T] || (q.yAxisAssignment = {
...q.yAxisAssignment,
[T]: ke === 1 ? "right" : "left"
});
}
f(null), u(q);
}, w = (y, M) => {
const E = { ...r }, T = E[M];
if (Array.isArray(T)) {
const j = T.filter((q) => q !== y);
j.length === 0 ? delete E[M] : E[M] = j;
} else T === y && delete E[M];
if (M === "yAxis" && E.yAxisAssignment?.[y]) {
const { [y]: j, ...q } = E.yAxisAssignment;
E.yAxisAssignment = Object.keys(q).length > 0 ? q : void 0;
}
u(E);
}, i = (y, M, E) => {
const T = { ...r }, j = T[E];
if (Array.isArray(j) && j.length > 1 && y !== M) {
const q = [...j], [I] = q.splice(y, 1);
q.splice(M, 0, I), T[E] = q, f(null), u(T);
}
}, g = F(
(y, M) => {
u({
...r,
yAxisAssignment: {
...r.yAxisAssignment,
[y]: M
}
});
},
[r, u]
), N = (() => {
const y = /* @__PURE__ */ new Set();
return p.dropZones.forEach((M) => {
v(M.key).forEach((E) => y.add(E));
}), d && d.fromAxis !== "available" && y.add(d.field), {
dimensions: h.dimensions.filter((M) => !y.has(M)),
timeDimensions: h.timeDimensions.filter((M) => !y.has(M)),
measures: h.measures.filter((M) => !y.has(M))
};
})(), S = N.dimensions.length > 0 || N.timeDimensions.length > 0 || N.measures.length > 0;
return /* @__PURE__ */ o("div", { className: "space-y-6", children: [
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e(Vt, { className: "mb-2", children: "Chart Type" }),
/* @__PURE__ */ e(
Es,
{
selectedType: t,
onTypeChange: l,
availability: c,
compact: !0
}
)
] }),
!m && p.dropZones.length > 0 && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e(Vt, { className: "mb-2", children: "Chart Configuration" }),
/* @__PURE__ */ e("div", { className: "space-y-1", children: p.dropZones.map((y) => /* @__PURE__ */ e(
tc,
{
config: y,
fields: v(y.key),
onDrop: A,
onRemove: w,
onDragStart: R,
onDragEnd: $,
onDragOver: D,
onReorder: i,
draggedItem: d,
getFieldMeta: b,
yAxisAssignment: r.yAxisAssignment,
onYAxisAssignmentChange: y.enableDualAxis ? g : void 0
},
y.key
)) })
] }),
!m && S && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ o("div", { className: "mb-2", children: [
/* @__PURE__ */ e(Vt, { children: "Unassigned Fields" }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted mt-0.5", children: "Drag fields to chart axes above" })
] }),
/* @__PURE__ */ e("div", { className: "border-2 border-dashed border-dc-border rounded-lg p-2 bg-dc-surface-secondary", children: /* @__PURE__ */ o("div", { className: "space-y-2", children: [
N.measures.map((y) => {
const M = b(y), E = d && d.field === y && d.fromAxis === "available", T = Xt(M.measureType || "count") || rc;
return /* @__PURE__ */ o(
"div",
{
draggable: !0,
onDragStart: (j) => R(j, y, "available"),
onDragEnd: $,
className: `flex items-center gap-2 p-2 bg-dc-surface rounded-lg hover:bg-dc-surface-tertiary transition-colors cursor-move ${E ? "opacity-50 cursor-grabbing" : ""}`,
title: y,
children: [
/* @__PURE__ */ e("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-measure text-dc-measure-text flex-shrink-0", children: /* @__PURE__ */ e(T, { className: "w-4 h-4" }) }),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ e("div", { className: "text-sm text-dc-text truncate", children: M.shortTitle }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: M.cubeName })
] })
]
},
y
);
}),
N.dimensions.map((y) => {
const M = b(y), E = d && d.field === y && d.fromAxis === "available";
return /* @__PURE__ */ o(
"div",
{
draggable: !0,
onDragStart: (T) => R(T, y, "available"),
onDragEnd: $,
className: `flex items-center gap-2 p-2 bg-dc-surface rounded-lg hover:bg-dc-surface-tertiary transition-colors cursor-move ${E ? "opacity-50 cursor-grabbing" : ""}`,
title: y,
children: [
/* @__PURE__ */ e("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-dimension text-dc-dimension-text flex-shrink-0", children: /* @__PURE__ */ e(nc, { className: "w-4 h-4" }) }),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ e("div", { className: "text-sm text-dc-text truncate", children: M.shortTitle }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: M.cubeName })
] })
]
},
y
);
}),
N.timeDimensions.map((y) => {
const M = b(y), E = d && d.field === y && d.fromAxis === "available";
return /* @__PURE__ */ o(
"div",
{
draggable: !0,
onDragStart: (T) => R(T, y, "available"),
onDragEnd: $,
className: `flex items-center gap-2 p-2 bg-dc-surface rounded-lg hover:bg-dc-surface-tertiary transition-colors cursor-move ${E ? "opacity-50 cursor-grabbing" : ""}`,
title: y,
children: [
/* @__PURE__ */ e("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-time-dimension text-dc-time-dimension-text flex-shrink-0", children: /* @__PURE__ */ e(sc, { className: "w-4 h-4" }) }),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ e("div", { className: "text-sm text-dc-text truncate", children: M.shortTitle }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: M.cubeName })
] })
]
},
y
);
})
] }) })
] }),
!m && h.measures.length === 0 && h.dimensions.length === 0 && h.timeDimensions.length === 0 && /* @__PURE__ */ e("div", { className: "text-center text-dc-text-muted text-sm py-4", children: /* @__PURE__ */ e("p", { children: "Add metrics and breakdowns in the Query tab to configure your chart." }) })
] });
}
function oc({
chartType: t,
displayConfig: r,
colorPalette: n,
onDisplayConfigChange: s
}) {
const a = ye(
() => Dr(t, Kt),
[t]
);
return a.displayOptions && a.displayOptions.length > 0 || a.displayOptionsConfig && a.displayOptionsConfig.length > 0 ? /* @__PURE__ */ e("div", { className: "space-y-6", children: /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e(Vt, { className: "mb-2", children: "Display Options" }),
/* @__PURE__ */ o("div", { className: "space-y-2", children: [
a.displayOptions?.includes("showLegend") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: r.showLegend ?? !0,
onChange: (l) => s({
...r,
showLegend: l.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Show Legend" })
] }),
a.displayOptions?.includes("showGrid") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: r.showGrid ?? !0,
onChange: (l) => s({
...r,
showGrid: l.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Show Grid" })
] }),
a.displayOptions?.includes("showTooltip") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: r.showTooltip ?? !0,
onChange: (l) => s({
...r,
showTooltip: l.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Show Tooltip" })
] }),
a.displayOptions?.includes("stacked") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: r.stacked ?? !1,
onChange: (l) => s({
...r,
stacked: l.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Stacked" })
] }),
a.displayOptions?.includes("hideHeader") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: r.hideHeader ?? !1,
onChange: (l) => s({
...r,
hideHeader: l.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Hide Header" })
] }),
a.displayOptionsConfig?.map((l) => /* @__PURE__ */ o("div", { className: `space-y-1 ${l.type === "axisFormat" ? "mt-6 pt-2" : ""}`, children: [
l.type === "boolean" && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: r[l.key] ?? l.defaultValue ?? !1,
onChange: (u) => s({
...r,
[l.key]: u.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: l.label })
] }),
l.type === "string" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ o("label", { className: "text-sm text-dc-text-secondary", children: [
l.label,
l.key === "content" && /* @__PURE__ */ e("span", { className: "text-xs text-dc-text-muted ml-1", children: "(only headers, lists and links)" })
] }),
l.key === "content" ? /* @__PURE__ */ e(
"textarea",
{
value: r[l.key] ?? l.defaultValue ?? "",
onChange: (u) => s({
...r,
[l.key]: u.target.value
}),
placeholder: l.placeholder,
rows: 8,
className: "w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent font-mono resize-y bg-dc-surface text-dc-text"
}
) : /* @__PURE__ */ e(
"input",
{
type: "text",
value: r[l.key] ?? l.defaultValue ?? "",
onChange: (u) => s({
...r,
[l.key]: u.target.value
}),
placeholder: l.placeholder,
className: "w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text"
}
),
l.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: l.description })
] }),
l.type === "paletteColor" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ e("label", { className: "text-sm text-dc-text-secondary", children: l.label }),
/* @__PURE__ */ e("div", { className: "flex flex-wrap gap-2", children: n?.colors.map((u, d) => {
const f = (r[l.key] ?? l.defaultValue ?? 0) === d;
return /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => s({
...r,
[l.key]: d
}),
className: `w-8 h-8 rounded border-2 transition-all duration-200 hover:scale-110 focus:outline-hidden focus:ring-2 focus:ring-dc-accent focus:ring-offset-1 ${f ? "ring-2 ring-offset-1 scale-110" : "hover:border-dc-text-muted"}`,
style: {
backgroundColor: u,
borderColor: f ? "var(--dc-primary)" : "var(--dc-border)"
},
title: `Color ${d + 1}: ${u}`
},
d
);
}) || [
// Fallback if no palette available
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => s({
...r,
[l.key]: 0
}),
className: "w-8 h-8 rounded-sm border-2 ring-2 ring-offset-1",
style: {
backgroundColor: "#8884d8",
borderColor: "var(--dc-primary)",
boxShadow: "0 0 0 2px var(--dc-primary)"
},
title: "Default Color"
},
0
)
] }),
l.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: l.description })
] }),
l.type === "number" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ e("label", { className: "text-sm text-dc-text-secondary", children: l.label }),
/* @__PURE__ */ e(
"input",
{
type: "number",
value: r[l.key] ?? l.defaultValue ?? 0,
onChange: (u) => s({
...r,
[l.key]: u.target.value === "" ? void 0 : Number(u.target.value)
}),
placeholder: l.placeholder,
min: l.min,
max: l.max,
step: l.step,
className: "w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text"
}
),
l.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: l.description })
] }),
l.type === "select" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ e("label", { className: "text-sm text-dc-text-secondary", children: l.label }),
/* @__PURE__ */ e(
"select",
{
value: r[l.key] ?? l.defaultValue ?? "",
onChange: (u) => s({
...r,
[l.key]: u.target.value
}),
className: "w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text",
children: l.options?.map((u) => /* @__PURE__ */ e("option", { value: u.value, children: u.label }, u.value))
}
),
l.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: l.description })
] }),
l.type === "color" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ e("label", { className: "text-sm text-dc-text-secondary", children: l.label }),
/* @__PURE__ */ o("div", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "color",
value: r[l.key] ?? l.defaultValue ?? "#8884d8",
onChange: (u) => s({
...r,
[l.key]: u.target.value
}),
className: "w-12 h-8 border border-dc-border rounded-sm cursor-pointer"
}
),
/* @__PURE__ */ e(
"input",
{
type: "text",
value: r[l.key] ?? l.defaultValue ?? "#8884d8",
onChange: (u) => s({
...r,
[l.key]: u.target.value
}),
placeholder: l.placeholder || "#8884d8",
className: "flex-1 px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text"
}
)
] }),
l.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: l.description })
] }),
l.type === "axisFormat" && /* @__PURE__ */ e(
ma,
{
axisLabel: l.label,
value: r[l.key] || {},
onChange: (u) => s({
...r,
[l.key]: Object.keys(u).length > 0 ? u : void 0
})
}
)
] }, l.key))
] })
] }) }) : /* @__PURE__ */ e("div", { className: "text-center text-dc-text-muted text-sm py-4", children: /* @__PURE__ */ e("p", { children: "No display options available for this chart type." }) });
}
const kn = Q("add"), cc = Q("close"), Dn = Q("info"), Tn = Q("warning"), lc = Ot(function({
metrics: r,
breakdowns: n,
filters: s,
schema: a,
activeTab: c,
onActiveTabChange: l,
onAddMetric: u,
onRemoveMetric: d,
onReorderMetrics: f,
onAddBreakdown: h,
onRemoveBreakdown: p,
onBreakdownGranularityChange: m,
onBreakdownComparisonToggle: v,
onReorderBreakdowns: C,
onFiltersChange: _,
onDropFieldToFilter: b,
// Sorting
order: R,
onOrderChange: D,
// Chart configuration
chartType: $,
chartConfig: A,
displayConfig: w,
colorPalette: i,
chartAvailability: g,
onChartTypeChange: x,
onChartConfigChange: N,
onDisplayConfigChange: S,
// Validation
validationStatus: y,
validationError: M,
// Multi-query props
queryCount: E = 1,
activeQueryIndex: T = 0,
mergeStrategy: j = "concat",
onActiveQueryChange: q,
onAddQuery: I,
onRemoveQuery: K,
onMergeStrategyChange: U,
breakdownsLocked: ke = !1,
combinedMetrics: De,
combinedBreakdowns: Pe,
multiQueryValidation: B
}) {
const se = E > 1, Te = F((L) => {
if (!a?.cubes) return null;
const [te] = L.field.split("."), Ne = a.cubes.find((Ve) => Ve.name === te);
return Ne && Ne.dimensions?.find((Ve) => Ve.name === L.field) || null;
}, [a]), H = ye(() => n.find((L) => L.isTimeDimension && L.enableComparison), [n]);
ve(() => {
r.length === 0 && (c === "chart" || c === "display") && l("query");
}, [r.length, c, l]);
const ee = F((L) => {
q?.(L), c !== "query" && l("query");
}, [q, c, l]), le = F((L, te) => {
L.stopPropagation(), K?.(te);
}, [K]), be = (L) => se ? `Q${L + 1}` : "Query";
return /* @__PURE__ */ o("div", { className: "h-full flex flex-col bg-dc-surface", children: [
/* @__PURE__ */ o("div", { className: "flex border-b border-dc-border flex-shrink-0", children: [
se ? /* @__PURE__ */ o(Oe, { children: [
Array.from({ length: E }).map((L, te) => /* @__PURE__ */ o(
"button",
{
onClick: () => ee(te),
className: `flex items-center gap-1 px-3 py-3 text-sm font-medium transition-colors ${te === T && c === "query" ? "text-dc-primary border-b-2 border-dc-primary" : "text-dc-text-secondary hover:text-dc-text"}`,
children: [
be(te),
/* @__PURE__ */ e(
"span",
{
role: "button",
tabIndex: 0,
onClick: (Ve) => le(Ve, te),
onKeyDown: (Ve) => Ve.key === "Enter" && le(Ve, te),
className: "p-0.5 rounded hover:bg-dc-danger-bg hover:text-dc-error transition-colors ml-0.5",
title: "Remove query",
"aria-label": `Remove ${be(te)}`,
children: /* @__PURE__ */ e(cc, { className: "w-3 h-3" })
}
)
]
},
`q${te}`
)),
/* @__PURE__ */ e(
"button",
{
onClick: I,
className: "flex items-center justify-center px-2 py-3 text-dc-text-secondary hover:text-dc-text transition-colors",
title: "Add query",
"aria-label": "Add new query",
children: /* @__PURE__ */ e(kn, { className: "w-4 h-4" })
}
)
] }) : /* @__PURE__ */ o(
"button",
{
onClick: () => l("query"),
className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${c === "query" ? "text-dc-primary border-b-2 border-dc-primary" : "text-dc-text-secondary hover:text-dc-text"}`,
children: [
"Query",
I && /* @__PURE__ */ e(
"span",
{
role: "button",
tabIndex: 0,
onClick: (L) => {
L.stopPropagation(), I();
},
onKeyDown: (L) => {
L.key === "Enter" && (L.stopPropagation(), I());
},
className: "ml-2 p-0.5 rounded hover:bg-dc-surface-hover transition-colors inline-flex items-center",
title: "Add another query",
"aria-label": "Add another query",
children: /* @__PURE__ */ e(kn, { className: "w-3 h-3" })
}
)
]
}
),
/* @__PURE__ */ e(
"button",
{
onClick: () => r.length > 0 && l("chart"),
disabled: r.length === 0,
className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${c === "chart" ? "text-dc-primary border-b-2 border-dc-primary" : r.length === 0 ? "text-dc-text-muted cursor-not-allowed opacity-50" : "text-dc-text-secondary hover:text-dc-text"}`,
title: r.length === 0 ? "Add metrics to configure chart" : "Chart configuration",
children: "Chart"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: () => r.length > 0 && l("display"),
disabled: r.length === 0,
className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${c === "display" ? "text-dc-primary border-b-2 border-dc-primary" : r.length === 0 ? "text-dc-text-muted cursor-not-allowed opacity-50" : "text-dc-text-secondary hover:text-dc-text"}`,
title: r.length === 0 ? "Add metrics to configure display" : "Display options",
children: "Display"
}
)
] }),
se && c === "query" && /* @__PURE__ */ e("div", { className: "flex items-center gap-3 px-4 py-2 text-sm bg-dc-surface-secondary border-b border-dc-border", children: /* @__PURE__ */ o("label", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e("span", { className: "text-dc-text-secondary text-xs", children: "Combine:" }),
/* @__PURE__ */ o(
"select",
{
value: j,
onChange: (L) => U?.(L.target.value),
className: "px-2 py-1 text-xs bg-dc-surface border border-dc-border rounded text-dc-text focus:outline-none focus:ring-1 focus:ring-dc-primary",
children: [
/* @__PURE__ */ e("option", { value: "concat", children: "Separate series" }),
/* @__PURE__ */ e("option", { value: "merge", children: "Merge by dimension" })
]
}
)
] }) }),
B && (B.warnings.length > 0 || B.errors.length > 0) && c === "query" && /* @__PURE__ */ o("div", { className: "px-4 py-2 border-b border-dc-border bg-dc-warning-bg", children: [
B.errors.map((L, te) => /* @__PURE__ */ o("div", { className: "flex items-start gap-2 text-xs text-dc-error", children: [
/* @__PURE__ */ e(Tn, { className: "w-3.5 h-3.5 mt-0.5 flex-shrink-0" }),
/* @__PURE__ */ e("span", { children: L.message })
] }, `error-${te}`)),
B.warnings.map((L, te) => /* @__PURE__ */ o("div", { className: "flex items-start gap-2 text-xs text-dc-warning", children: [
/* @__PURE__ */ e(Tn, { className: "w-3.5 h-3.5 mt-0.5 flex-shrink-0" }),
/* @__PURE__ */ e("span", { children: L.message })
] }, `warning-${te}`))
] }),
/* @__PURE__ */ e("div", { className: "flex-1 overflow-auto p-4", children: c === "query" ? /* @__PURE__ */ o("div", { className: "space-y-6", children: [
/* @__PURE__ */ e(
Ro,
{
metrics: r,
schema: a,
onAdd: u,
onRemove: d,
order: R,
onOrderChange: D,
onReorder: f
}
),
ke ? /* @__PURE__ */ o("div", { className: "mb-4", children: [
/* @__PURE__ */ e("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ e("h4", { className: "text-sm font-medium text-dc-text", children: "Dimensions" }) }),
/* @__PURE__ */ o("div", { className: "flex items-start gap-2 px-3 py-2 mb-3 bg-dc-surface-secondary rounded border border-dc-border text-xs", children: [
Dn && /* @__PURE__ */ e(Dn, { className: "w-4 h-4 text-dc-text-muted flex-shrink-0 mt-0.5" }),
/* @__PURE__ */ o("span", { className: "text-dc-text-muted", children: [
"In merge mode, dimensions are shared from Q1.",
U && /* @__PURE__ */ e(
"button",
{
onClick: () => U("concat"),
className: "text-dc-primary hover:underline ml-1",
children: "Switch to separate series"
}
)
] })
] }),
n.length > 0 && /* @__PURE__ */ e("div", { className: "space-y-1", children: n.map((L) => /* @__PURE__ */ e(
Cs,
{
breakdown: L,
fieldMeta: Te(L),
onRemove: () => {
},
onGranularityChange: L.isTimeDimension ? (te) => m(L.id, te) : void 0,
onComparisonToggle: L.isTimeDimension && v ? () => v(L.id) : void 0,
comparisonDisabled: !!H && H.id !== L.id
},
L.id
)) })
] }) : /* @__PURE__ */ e(
Lo,
{
breakdowns: n,
schema: a,
onAdd: h,
onRemove: p,
onGranularityChange: m,
onComparisonToggle: v,
order: R,
onOrderChange: D,
onReorder: C
}
),
/* @__PURE__ */ e(
Jo,
{
filters: s,
schema: a,
onFiltersChange: _,
onFieldDropped: b
}
)
] }) : c === "chart" ? (
/* Chart Tab Content - use combined metrics/breakdowns in multi-query mode */
/* @__PURE__ */ e(
ac,
{
chartType: $,
chartConfig: A,
metrics: se && De ? De : r,
breakdowns: se && Pe ? Pe : n,
schema: a,
chartAvailability: g,
onChartTypeChange: x,
onChartConfigChange: N
}
)
) : c === "display" ? (
/* Display Tab Content */
/* @__PURE__ */ e(
oc,
{
chartType: $,
displayConfig: w,
colorPalette: i,
onDisplayConfigChange: S
}
)
) : null })
] });
});
var Or = { exports: {} }, Sn;
function ic() {
return Sn || (Sn = 1, (function(t) {
var r = (function() {
var n = String.fromCharCode, s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$", c = {};
function l(d, f) {
if (!c[d]) {
c[d] = {};
for (var h = 0; h < d.length; h++)
c[d][d.charAt(h)] = h;
}
return c[d][f];
}
var u = {
compressToBase64: function(d) {
if (d == null) return "";
var f = u._compress(d, 6, function(h) {
return s.charAt(h);
});
switch (f.length % 4) {
// To produce valid Base64
default:
// When could this happen ?
case 0:
return f;
case 1:
return f + "===";
case 2:
return f + "==";
case 3:
return f + "=";
}
},
decompressFromBase64: function(d) {
return d == null ? "" : d == "" ? null : u._decompress(d.length, 32, function(f) {
return l(s, d.charAt(f));
});
},
compressToUTF16: function(d) {
return d == null ? "" : u._compress(d, 15, function(f) {
return n(f + 32);
}) + " ";
},
decompressFromUTF16: function(d) {
return d == null ? "" : d == "" ? null : u._decompress(d.length, 16384, function(f) {
return d.charCodeAt(f) - 32;
});
},
//compress into uint8array (UCS-2 big endian format)
compressToUint8Array: function(d) {
for (var f = u.compress(d), h = new Uint8Array(f.length * 2), p = 0, m = f.length; p < m; p++) {
var v = f.charCodeAt(p);
h[p * 2] = v >>> 8, h[p * 2 + 1] = v % 256;
}
return h;
},
//decompress from uint8array (UCS-2 big endian format)
decompressFromUint8Array: function(d) {
if (d == null)
return u.decompress(d);
for (var f = new Array(d.length / 2), h = 0, p = f.length; h < p; h++)
f[h] = d[h * 2] * 256 + d[h * 2 + 1];
var m = [];
return f.forEach(function(v) {
m.push(n(v));
}), u.decompress(m.join(""));
},
//compress into a string that is already URI encoded
compressToEncodedURIComponent: function(d) {
return d == null ? "" : u._compress(d, 6, function(f) {
return a.charAt(f);
});
},
//decompress from an output of compressToEncodedURIComponent
decompressFromEncodedURIComponent: function(d) {
return d == null ? "" : d == "" ? null : (d = d.replace(/ /g, "+"), u._decompress(d.length, 32, function(f) {
return l(a, d.charAt(f));
}));
},
compress: function(d) {
return u._compress(d, 16, function(f) {
return n(f);
});
},
_compress: function(d, f, h) {
if (d == null) return "";
var p, m, v = {}, C = {}, _ = "", b = "", R = "", D = 2, $ = 3, A = 2, w = [], i = 0, g = 0, x;
for (x = 0; x < d.length; x += 1)
if (_ = d.charAt(x), Object.prototype.hasOwnProperty.call(v, _) || (v[_] = $++, C[_] = !0), b = R + _, Object.prototype.hasOwnProperty.call(v, b))
R = b;
else {
if (Object.prototype.hasOwnProperty.call(C, R)) {
if (R.charCodeAt(0) < 256) {
for (p = 0; p < A; p++)
i = i << 1, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++;
for (m = R.charCodeAt(0), p = 0; p < 8; p++)
i = i << 1 | m & 1, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++, m = m >> 1;
} else {
for (m = 1, p = 0; p < A; p++)
i = i << 1 | m, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++, m = 0;
for (m = R.charCodeAt(0), p = 0; p < 16; p++)
i = i << 1 | m & 1, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++, m = m >> 1;
}
D--, D == 0 && (D = Math.pow(2, A), A++), delete C[R];
} else
for (m = v[R], p = 0; p < A; p++)
i = i << 1 | m & 1, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++, m = m >> 1;
D--, D == 0 && (D = Math.pow(2, A), A++), v[b] = $++, R = String(_);
}
if (R !== "") {
if (Object.prototype.hasOwnProperty.call(C, R)) {
if (R.charCodeAt(0) < 256) {
for (p = 0; p < A; p++)
i = i << 1, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++;
for (m = R.charCodeAt(0), p = 0; p < 8; p++)
i = i << 1 | m & 1, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++, m = m >> 1;
} else {
for (m = 1, p = 0; p < A; p++)
i = i << 1 | m, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++, m = 0;
for (m = R.charCodeAt(0), p = 0; p < 16; p++)
i = i << 1 | m & 1, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++, m = m >> 1;
}
D--, D == 0 && (D = Math.pow(2, A), A++), delete C[R];
} else
for (m = v[R], p = 0; p < A; p++)
i = i << 1 | m & 1, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++, m = m >> 1;
D--, D == 0 && (D = Math.pow(2, A), A++);
}
for (m = 2, p = 0; p < A; p++)
i = i << 1 | m & 1, g == f - 1 ? (g = 0, w.push(h(i)), i = 0) : g++, m = m >> 1;
for (; ; )
if (i = i << 1, g == f - 1) {
w.push(h(i));
break;
} else g++;
return w.join("");
},
decompress: function(d) {
return d == null ? "" : d == "" ? null : u._decompress(d.length, 32768, function(f) {
return d.charCodeAt(f);
});
},
_decompress: function(d, f, h) {
var p = [], m = 4, v = 4, C = 3, _ = "", b = [], R, D, $, A, w, i, g, x = { val: h(0), position: f, index: 1 };
for (R = 0; R < 3; R += 1)
p[R] = R;
for ($ = 0, w = Math.pow(2, 2), i = 1; i != w; )
A = x.val & x.position, x.position >>= 1, x.position == 0 && (x.position = f, x.val = h(x.index++)), $ |= (A > 0 ? 1 : 0) * i, i <<= 1;
switch ($) {
case 0:
for ($ = 0, w = Math.pow(2, 8), i = 1; i != w; )
A = x.val & x.position, x.position >>= 1, x.position == 0 && (x.position = f, x.val = h(x.index++)), $ |= (A > 0 ? 1 : 0) * i, i <<= 1;
g = n($);
break;
case 1:
for ($ = 0, w = Math.pow(2, 16), i = 1; i != w; )
A = x.val & x.position, x.position >>= 1, x.position == 0 && (x.position = f, x.val = h(x.index++)), $ |= (A > 0 ? 1 : 0) * i, i <<= 1;
g = n($);
break;
case 2:
return "";
}
for (p[3] = g, D = g, b.push(g); ; ) {
if (x.index > d)
return "";
for ($ = 0, w = Math.pow(2, C), i = 1; i != w; )
A = x.val & x.position, x.position >>= 1, x.position == 0 && (x.position = f, x.val = h(x.index++)), $ |= (A > 0 ? 1 : 0) * i, i <<= 1;
switch (g = $) {
case 0:
for ($ = 0, w = Math.pow(2, 8), i = 1; i != w; )
A = x.val & x.position, x.position >>= 1, x.position == 0 && (x.position = f, x.val = h(x.index++)), $ |= (A > 0 ? 1 : 0) * i, i <<= 1;
p[v++] = n($), g = v - 1, m--;
break;
case 1:
for ($ = 0, w = Math.pow(2, 16), i = 1; i != w; )
A = x.val & x.position, x.position >>= 1, x.position == 0 && (x.position = f, x.val = h(x.index++)), $ |= (A > 0 ? 1 : 0) * i, i <<= 1;
p[v++] = n($), g = v - 1, m--;
break;
case 2:
return b.join("");
}
if (m == 0 && (m = Math.pow(2, C), C++), p[g])
_ = p[g];
else if (g === v)
_ = D + D.charAt(0);
else
return null;
b.push(_), p[v++] = D + _.charAt(0), m--, D = _, m == 0 && (m = Math.pow(2, C), C++);
}
}
};
return u;
})();
t != null ? t.exports = r : typeof angular < "u" && angular != null && angular.module("LZString", []).factory("LZString", function() {
return r;
});
})(Or)), Or.exports;
}
var _s = /* @__PURE__ */ ic();
const An = 1800, En = "share=";
function _n(t) {
const r = JSON.stringify(t);
return _s.compressToEncodedURIComponent(r);
}
function dc(t) {
try {
const r = _s.decompressFromEncodedURIComponent(t);
if (!r) return null;
const n = JSON.parse(r);
return !n.query || typeof n.query != "object" ? null : n;
} catch {
return null;
}
}
function uc(t) {
const r = _n(t);
if (r.length <= An)
return { encoded: r, queryOnly: !1 };
const n = { query: t.query }, s = _n(n);
return s.length <= An ? { encoded: s, queryOnly: !0 } : { encoded: null, queryOnly: !0 };
}
function mc() {
if (typeof window > "u") return null;
const t = window.location.hash;
return !t || !t.startsWith(`#${En}`) ? null : t.slice(En.length + 1);
}
function fc() {
if (typeof window > "u") return;
const t = new URL(window.location.href);
t.hash = "", window.history.replaceState(null, "", t.toString());
}
async function hc(t, r, n = "/api/ai/generate") {
const s = {
text: r
// Send only the user's prompt, server handles system prompt
}, a = {
"Content-Type": "application/json"
};
console.log("🤖 Client: Sending user prompt to AI proxy"), console.log(" URL:", n), console.log(" Headers:", a), console.log(" User prompt length:", r.length);
const c = await fetch(n, {
method: "POST",
headers: a,
body: JSON.stringify(s)
});
if (console.log("📥 Client: Proxy response"), console.log(" Status:", c.status), console.log(" Status Text:", c.statusText), !c.ok) {
let u = `Failed to generate content: ${c.status} ${c.statusText}`;
try {
const d = await c.json();
if (console.error("❌ Client: Proxy error:", d), c.status === 429 && d.error === "Daily quota exceeded")
throw new Error(
`${d.message}
${d.suggestion || "Add your own Gemini API key for unlimited access."}`
);
d.error && (u = d.message || d.error, d.suggestion && (u += `
💡 ${d.suggestion}`));
} catch {
try {
const d = await c.text();
console.error("❌ Client: Proxy text error:", d), u = d || u;
} catch {
console.error("❌ Client: Could not parse error response");
}
}
throw new Error(u);
}
const l = await c.json();
return console.log("✅ Client: Successfully generated content"), l;
}
function pc(t) {
return (t.query || "").replace(/```json\s*/g, "").replace(/```\s*/g, "").replace(/^\s*```.*\n/gm, "").trim();
}
function Rn(t) {
return t.timeDimensions || [];
}
function gc(t) {
const r = [];
if (t.length < 2) return r;
const n = Rn(t[0]);
if (n.length === 0) return r;
for (let s = 1; s < t.length; s++) {
const a = Rn(t[s]);
if (a.length === 0 && n.length > 0) {
r.push({
type: "missing_time_dimension",
queryIndex: s,
message: `Query ${s + 1} is missing time dimension "${n[0].dimension}"`,
details: { field: n[0].dimension }
});
continue;
}
for (const c of n) {
const l = a.find((u) => u.dimension === c.dimension);
l && l.granularity !== c.granularity && r.push({
type: "granularity_mismatch",
queryIndex: s,
message: `Query ${s + 1} uses "${l.granularity}" granularity but Query 1 uses "${c.granularity}"`,
details: {
field: c.dimension,
expectedGranularity: c.granularity,
actualGranularity: l.granularity
}
});
}
}
return r;
}
function bc(t, r) {
const n = [];
if (t.length < 2 || r.length === 0) return n;
for (let s = 0; s < t.length; s++) {
const a = t[s], c = /* @__PURE__ */ new Set([
...a.dimensions || [],
...a.timeDimensions?.map((l) => l.dimension) || []
]);
for (const l of r)
c.has(l) || n.push({
type: "missing_merge_key",
queryIndex: s,
message: `Query ${s + 1} is missing merge dimension "${l}"`,
details: { field: l }
});
}
return n;
}
function xc(t) {
const r = [];
if (t.length < 2) return r;
const n = /* @__PURE__ */ new Map();
t.forEach((c, l) => {
c.measures?.forEach((u) => {
n.has(u) || n.set(u, []), n.get(u).push(l);
});
});
const s = [], a = /* @__PURE__ */ new Set();
return n.forEach((c, l) => {
c.length > 1 && (s.push(l), c.forEach((u) => a.add(u)));
}), s.length > 0 && r.push({
type: "measure_collision",
queryIndices: Array.from(a).sort(),
message: `Measure${s.length > 1 ? "s" : ""} "${s.join('", "')}" appear${s.length === 1 ? "s" : ""} in multiple queries - first value will be used`,
affectedMeasures: s
}), r;
}
function yc(t) {
const r = [];
if (t.length < 2) return r;
const n = t.map((a) => a.timeDimensions?.[0]?.dateRange);
return new Set(n.map((a) => JSON.stringify(a))).size > 1 && r.push({
type: "asymmetric_date_range",
queryIndices: t.map((a, c) => c),
message: "Queries have different date ranges - some data points may be missing in merged results"
}), r;
}
function vc(t, r, n = []) {
const s = [], a = [];
return t.length < 2 ? { isValid: !0, errors: s, warnings: a } : (a.push(...xc(t)), a.push(...yc(t)), r === "merge" && (s.push(...gc(t)), n.length > 0 && s.push(...bc(t, n))), {
isValid: s.length === 0,
errors: s,
warnings: a
});
}
function Ql(t) {
return t.filter(
(r) => (r.measures?.length || 0) + (r.dimensions?.length || 0) + (r.timeDimensions?.length || 0) > 0
).length >= 2;
}
function Ul(t) {
if (t.isValid && t.warnings.length === 0)
return "Configuration is valid";
const r = [];
return t.errors.length > 0 && r.push(`${t.errors.length} error${t.errors.length > 1 ? "s" : ""}`), t.warnings.length > 0 && r.push(`${t.warnings.length} warning${t.warnings.length > 1 ? "s" : ""}`), r.join(", ");
}
const Mn = Q("sparkles"), wc = Q("error");
function Nc({
userPrompt: t,
onPromptChange: r,
isGenerating: n,
error: s,
hasGeneratedQuery: a,
onGenerate: c,
onAccept: l,
onCancel: u
}) {
const d = F(
(f) => {
f.key === "Enter" && !f.shiftKey && (f.preventDefault(), c());
},
[c]
);
return /* @__PURE__ */ o(
"div",
{
className: "border-b border-dc-border",
style: { background: "linear-gradient(to right, var(--dc-ai-gradient-start), var(--dc-ai-gradient-end))" },
children: [
/* @__PURE__ */ o("div", { className: "px-4 py-2 flex items-center justify-between border-b border-dc-border bg-dc-surface-secondary", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e(Mn, { className: "w-4 h-4 text-dc-accent" }),
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-dc-text", children: "AI Query Generator" }),
n && /* @__PURE__ */ e("span", { className: "text-xs text-dc-accent animate-pulse", children: "Generating..." })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
a && /* @__PURE__ */ e(
"button",
{
onClick: l,
className: "px-3 py-1 text-xs font-medium text-white bg-dc-success hover:opacity-80 rounded transition-colors",
children: "Accept"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: u,
className: "px-3 py-1 text-xs font-medium text-dc-text-secondary hover:text-dc-text bg-dc-surface hover:bg-dc-surface-hover border border-dc-border rounded transition-colors",
children: a ? "Cancel" : "Close"
}
)
] })
] }),
/* @__PURE__ */ o("div", { className: "p-4", children: [
/* @__PURE__ */ o("div", { className: "flex gap-3", children: [
/* @__PURE__ */ o("div", { className: "flex-1", children: [
/* @__PURE__ */ e(
"textarea",
{
value: t,
onChange: (f) => r(f.target.value),
onKeyDown: d,
placeholder: "Describe your query in natural language... (e.g., 'Show total sales by month for the last year')",
className: "w-full px-3 py-2 text-sm border border-dc-border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-dc-accent focus:border-dc-accent resize-none bg-dc-surface text-dc-text placeholder-dc-text-muted",
rows: 2,
disabled: n
}
),
/* @__PURE__ */ e("div", { className: "mt-1 text-xs text-dc-text-muted", children: "Press Enter to generate, Shift+Enter for new line" })
] }),
/* @__PURE__ */ e("div", { className: "flex-shrink-0", children: /* @__PURE__ */ e(
"button",
{
onClick: c,
disabled: n || !t.trim(),
className: `px-4 py-2 text-sm font-medium rounded-md transition-colors flex items-center gap-2 ${n || !t.trim() ? "bg-dc-surface-tertiary text-dc-text-disabled cursor-not-allowed" : "bg-dc-accent hover:bg-dc-accent-hover text-white"}`,
children: n ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("div", { className: "w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" }),
/* @__PURE__ */ e("span", { children: "Generating..." })
] }) : /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(Mn, { className: "w-4 h-4" }),
/* @__PURE__ */ e("span", { children: "Generate" })
] })
}
) })
] }),
s && /* @__PURE__ */ o("div", { className: "mt-3 flex items-start gap-2 p-3 bg-dc-error-bg border border-dc-error-border rounded-md", children: [
/* @__PURE__ */ e(wc, { className: "w-4 h-4 text-dc-error mt-0.5 flex-shrink-0" }),
/* @__PURE__ */ e("div", { className: "text-sm text-dc-error", children: s })
] }),
a && !s && /* @__PURE__ */ e("div", { className: "mt-3 p-3 bg-dc-success-bg border border-dc-success-border rounded-md", children: /* @__PURE__ */ o("div", { className: "text-sm text-dc-success", children: [
"Query generated and loaded! Check the results below, then click",
" ",
/* @__PURE__ */ e("strong", { children: "Accept" }),
" to keep or ",
/* @__PURE__ */ e("strong", { children: "Cancel" }),
" to revert."
] }) })
] })
]
}
);
}
const Rs = "drizzle-cube-analysis-builder-state", Cc = 300;
function Lt() {
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
function $r(t) {
let r = "", n = t;
do
r = String.fromCharCode(65 + n % 26) + r, n = Math.floor(n / 26) - 1;
while (n >= 0);
return r;
}
function en(t, r) {
for (const n of t)
if ("type" in n && "filters" in n) {
const a = en(n.filters, r);
if (a) return a;
} else if ("member" in n) {
const s = n;
if (s.member === r && s.operator === "inDateRange" && s.dateRange)
return { dateRange: s.dateRange };
}
}
function kc(t, r) {
const n = en(r, t);
if (!n?.dateRange) return;
const s = Ga(n.dateRange);
if (!s) return;
const a = Wa(s.start, s.end);
return [
[ur(s.start), ur(s.end)],
[ur(a.start), ur(a.end)]
];
}
function Ms(t, r) {
return t.reduce((n, s) => {
if ("type" in s && "filters" in s) {
const a = s, c = Ms(a.filters, r);
c.length > 0 && n.push({ type: a.type, filters: c });
} else if ("member" in s) {
const a = s;
a.member === r && a.operator === "inDateRange" || n.push(s);
} else
n.push(s);
return n;
}, []);
}
function On(t, r, n, s) {
const a = r.filter((u) => u.isTimeDimension && u.enableComparison).map((u) => u.field);
let c = n;
for (const u of a)
c = Ms(c, u);
const l = {
measures: t.map((u) => u.field),
dimensions: r.filter((u) => !u.isTimeDimension).map((u) => u.field),
timeDimensions: r.filter((u) => u.isTimeDimension).map((u) => {
const d = {
dimension: u.field,
granularity: u.granularity || "day"
};
if (u.enableComparison) {
const f = kc(u.field, n);
f && (d.compareDateRange = f);
}
return d;
}),
filters: c.length > 0 ? c : void 0,
order: s && Object.keys(s).length > 0 ? s : void 0
};
return l.measures?.length === 0 && delete l.measures, l.dimensions?.length === 0 && delete l.dimensions, l.timeDimensions?.length === 0 && delete l.timeDimensions, l;
}
function _t() {
return {
metrics: [],
breakdowns: [],
filters: [],
order: void 0,
validationStatus: "idle",
validationError: null,
executionStatus: "idle",
executionResults: null,
executionError: null,
totalRowCount: null,
resultsStale: !1
};
}
function Dc(t) {
if (t) return null;
try {
const r = localStorage.getItem(Rs);
if (r)
return JSON.parse(r);
} catch {
}
return null;
}
const tn = Hr(
({
className: t = "",
maxHeight: r,
initialQuery: n,
initialChartConfig: s,
initialData: a,
colorPalette: c,
disableLocalStorage: l = !1,
hideSettings: u = !1,
onQueryChange: d,
onChartConfigChange: f
}, h) => {
const p = l || !!n, { meta: m, cubeApi: v } = Qt(), C = ye(
() => Dc(l),
[]
// Only run once on mount
), _ = (O) => ({
..._t(),
metrics: (O.measures || []).map((P, W) => ({
id: Lt(),
field: P,
label: $r(W)
})),
breakdowns: [
...(O.dimensions || []).map((P) => ({
id: Lt(),
field: P,
isTimeDimension: !1
})),
...(O.timeDimensions || []).map((P) => ({
id: Lt(),
field: P.dimension,
granularity: P.granularity,
isTimeDimension: !0
}))
],
filters: O.filters || [],
order: O.order
}), [b, R] = V(() => n ? yr(n) ? n.queries.map(_) : [_(n)] : C ? C.queryStates || [{
..._t(),
metrics: C.metrics || [],
breakdowns: C.breakdowns || [],
filters: C.filters || [],
order: C.order
}] : [_t()]), [D, $] = V(() => C?.activeQueryIndex !== void 0 ? C.activeQueryIndex : 0), [A, w] = V(() => {
if (n && yr(n)) {
const O = n;
if (O.mergeStrategy)
return O.mergeStrategy;
}
return C?.mergeStrategy ? C.mergeStrategy : "concat";
}), i = ye(() => {
if (A !== "merge" || b.length === 0) return;
const O = b[0].breakdowns;
if (O.length !== 0)
return O.map((P) => P.field);
}, [A, b]), g = b[D] || _t(), x = F((O) => {
R((P) => {
const W = [...P];
return typeof O == "function" ? W[D] = O(P[D] || _t()) : W[D] = O, W;
});
}, [D]);
ve(() => {
if (A !== "merge" || b.length <= 1) return;
const O = b[0].breakdowns;
let P = !1;
for (let W = 1; W < b.length; W++)
if (JSON.stringify(b[W].breakdowns) !== JSON.stringify(O)) {
P = !0;
break;
}
P && R((W) => W.map(
(Z, ie) => ie === 0 ? Z : { ...Z, breakdowns: [...O] }
));
}, [A, b]);
const [N, S] = V(() => s?.chartType ? s.chartType : !n && C?.chartType ? C.chartType : "line"), [y, M] = V(() => s?.chartConfig ? s.chartConfig : !n && C?.chartConfig ? C.chartConfig : {}), [E, T] = V(() => s?.displayConfig ? s.displayConfig : !n && C?.displayConfig ? C.displayConfig : { showLegend: !0, showGrid: !0, showTooltip: !0 }), [j, q] = V("default"), I = ye(() => c || Wr(j), [c, j]), [K, U] = V("query"), [ke, De] = V(() => !n && C?.activeView ? C.activeView : "chart"), [Pe, B] = V(100), [se, Te] = V(
() => !!s?.chartType
), [H, ee] = V([]), [le, be] = V(!1), [L, te] = V("metrics"), [Ne, Ve] = V("idle"), { features: rt } = Qt(), [Fe, ue] = V({
isOpen: !1,
userPrompt: "",
isGenerating: !1,
error: null,
hasGeneratedQuery: !1,
previousState: null
});
ve(() => {
if (n) return;
const O = mc();
if (!O) return;
const P = dc(O);
if (!P || !P.query) return;
const W = P.query;
if (yr(W)) {
const Z = W;
R(Z.queries.map(_)), $(0), Z.mergeStrategy && w(Z.mergeStrategy);
} else
R([_(W)]), $(0);
P.chartType && (S(P.chartType), Te(!0)), P.chartConfig && M(P.chartConfig), P.displayConfig && T(P.displayConfig), P.activeView && De(P.activeView), fc();
}, []);
const _e = ye(
() => On(g.metrics, g.breakdowns, g.filters, g.order),
[g.metrics, g.breakdowns, g.filters, g.order]
), G = ye(() => b.map((O) => On(O.metrics, O.breakdowns, O.filters, O.order)), [b]), X = ye(() => b.length <= 1 ? !1 : b.filter(
(P) => P.metrics.length > 0 || P.breakdowns.length > 0
).length > 1, [b]), ae = ye(() => X ? vc(G, A, i || []) : null, [X, G, A, i]), qe = ye(() => X ? b.flatMap((O) => O.metrics) : g.metrics, [X, b, g.metrics]), je = ye(() => X ? b[0]?.breakdowns || [] : g.breakdowns, [X, b, g.breakdowns]), nt = ye(() => {
if (!X) return null;
const O = G.filter(
(P) => P.measures && P.measures.length > 0 || P.dimensions && P.dimensions.length > 0 || P.timeDimensions && P.timeDimensions.length > 0
);
return O.length < 2 ? null : {
queries: O.map((P) => yn(P)),
mergeStrategy: A,
mergeKeys: i,
queryLabels: O.map((P, W) => `Q${W + 1}`)
};
}, [G, X, A, i]), Ie = ye(() => JSON.stringify(X ? { queries: G, mergeStrategy: A, mergeKeys: i } : _e), [_e, G, X, A, i]), [Be, ot] = V(null), at = Ce(null), bt = Ce(""), ft = Ce(!!a && a.length > 0), Dt = Ce(n ? JSON.stringify(n) : ""), Qe = Ce(""), Ze = Ce(y), et = _e.measures && _e.measures.length > 0 || _e.dimensions && _e.dimensions.length > 0 || _e.timeDimensions && _e.timeDimensions.length > 0, xt = ye(() => X ? G.filter(
(P) => P.measures && P.measures.length > 0 || P.dimensions && P.dimensions.length > 0 || P.timeDimensions && P.timeDimensions.length > 0
).length >= 2 : !1, [X, G]);
ve(() => {
if (Ie === bt.current) {
console.log("[DEBUG] Debounce: skipped - query unchanged");
return;
}
if (console.log("[DEBUG] Debounce: query changed, will execute", { isMultiQueryMode: X, hasValidMultiQuery: xt }), ft.current && Ie === Dt.current) {
bt.current = Ie, ft.current = !1;
return;
}
return at.current && clearTimeout(at.current), et || xt ? at.current = setTimeout(() => {
bt.current = Ie, ot(xt ? G[0] : _e);
}, Cc) : (bt.current = Ie, ot(null)), () => {
at.current && clearTimeout(at.current);
};
}, [Ie, et, xt, G]);
const Tt = ye(() => Be ? yn(Be) : null, [Be]), $t = ye(() => !X || !nt || !Be ? null : nt, [X, nt, Be]), St = ts(Tt, {
skip: !Tt || X,
resetResultSetOnChange: !0
}), st = cs($t, {
skip: !$t || !X,
resetResultSetOnChange: !0
}), dt = X ? null : St.resultSet, ht = X ? st.isLoading : St.isLoading, It = X ? st.error : St.error, Pt = ye(() => {
const O = X ? st.data : dt;
return a && a.length > 0 && !Be && !O ? "success" : !Be && !$t ? "idle" : !X && g.resultsStale && O ? "refreshing" : ht && !O ? "loading" : ht && O ? "refreshing" : It ? "error" : O ? "success" : "idle";
}, [Be, $t, ht, It, dt, st.data, a, g.resultsStale, X]), pt = ye(() => {
if (X && st.data)
return console.log("[DEBUG] executionResults: multi-query", st.data?.length), st.data;
if (dt)
try {
const O = dt.rawData();
return console.log("[DEBUG] executionResults: single-query", O?.length), O;
} catch {
return null;
}
return a && a.length > 0 ? a : (console.log("[DEBUG] executionResults: null"), null);
}, [dt, a, X, st.data]), k = ye(() => {
if (!X || !st.resultSets) {
console.log("[DEBUG] perQueryResults: no results", { isMultiQueryMode: X, resultSets: st.resultSets });
return;
}
const O = st.resultSets.map((P) => {
if (!P) return null;
try {
return P.rawData();
} catch {
return null;
}
});
return console.log("[DEBUG] perQueryResults:", O.map((P) => P?.length || 0)), O;
}, [X, st.resultSets]), [z, ne] = V(0);
ve(() => {
dt && g.resultsStale && x((O) => ({ ...O, resultsStale: !1 }));
}, [dt, g.resultsStale]);
const Ee = ye(
() => No(qe, je),
[qe, je]
), ze = F((O) => ["xAxis", "yAxis", "series", "sizeField", "colorField", "dateField", "valueField"].every((W) => {
const Z = O[W];
return Z == null ? !0 : Array.isArray(Z) ? Z.length === 0 : typeof Z == "string" ? Z === "" : !1;
}), []);
Ze.current = y, ve(() => {
if (!Be || qe.length === 0 && je.length === 0)
return;
const O = JSON.stringify({
metrics: qe.map((W) => W.field),
breakdowns: je.map((W) => ({ field: W.field, isTime: W.isTimeDimension }))
});
if (O === Qe.current)
return;
Qe.current = O;
const P = ko(
qe,
je,
N,
se
);
if (P) {
const { chartConfig: W } = hr(
qe,
je,
P
);
S(P), M(W), Te(!1);
} else if ((qe.length > 0 || je.length > 0) && ze(Ze.current)) {
const { chartConfig: W } = hr(
qe,
je,
N
);
M(W);
}
}, [Be, qe, je, N, se, ze]), ve(() => {
if (p) return;
const O = setTimeout(() => {
try {
const P = b[D] || _t(), W = {
// Legacy format (for backward compatibility with single-query)
metrics: P.metrics,
breakdowns: P.breakdowns,
filters: P.filters,
order: P.order,
chartType: N,
chartConfig: y,
displayConfig: E,
activeView: ke,
// Multi-query format (mergeKeys is computed from Q1 breakdowns, not stored)
// queryStates already includes order per query
queryStates: b.length > 1 ? b : void 0,
activeQueryIndex: b.length > 1 ? D : void 0,
mergeStrategy: b.length > 1 ? A : void 0
};
localStorage.setItem(Rs, JSON.stringify(W));
} catch {
}
}, 0);
return () => clearTimeout(O);
}, [
b,
D,
A,
N,
y,
E,
ke,
p
]), ve(() => {
d && et && d(_e);
}, [_e, et, d]), ve(() => {
f && f({ chartType: N, chartConfig: y, displayConfig: E });
}, [N, y, E, f]), ve(() => {
const O = X && nt ? nt.queries : et && Tt ? [Tt] : [];
if (O.length === 0) {
ee([]);
return;
}
let P = !1;
return (async () => {
ee(O.map(() => ({
sql: null,
analysis: null,
loading: !0,
error: null
})));
const Z = await Promise.all(
O.map(async (ie) => {
try {
const xe = await v.dryRun(ie);
return {
sql: xe.sql,
analysis: xe.analysis,
loading: !1,
error: null
};
} catch (xe) {
return {
sql: null,
analysis: null,
loading: !1,
error: xe instanceof Error ? xe.message : "Failed to fetch debug info"
};
}
})
);
P || ee(Z);
})(), () => {
P = !0;
};
}, [Tt, nt, v, et, X]);
const Ge = F(() => {
te("metrics"), be(!0);
}, []), he = F((O) => {
x((P) => {
const W = P.metrics.find((xe) => xe.id === O)?.field, Z = P.metrics.filter((xe) => xe.id !== O);
let ie = P.order;
return W && ie && ie[W] && (ie = { ...ie }, delete ie[W], Object.keys(ie).length === 0 && (ie = void 0)), {
...P,
metrics: Z,
order: ie,
resultsStale: !0
};
});
}, [x]), me = F(
(O, P, W, Z) => {
if (L === "metrics" && P === "measure")
x((ie) => {
const xe = ie.metrics.findIndex((Xe) => Xe.field === O.name);
if (xe >= 0)
return {
...ie,
metrics: ie.metrics.filter((Xe, it) => it !== xe),
resultsStale: !0
};
const Re = {
id: Lt(),
field: O.name,
label: $r(ie.metrics.length)
};
return {
...ie,
metrics: [...ie.metrics, Re],
resultsStale: !0
};
});
else if (L === "breakdown") {
const ie = P === "timeDimension";
x((xe) => {
const Re = xe.breakdowns.findIndex((it) => it.field === O.name);
if (Re >= 0)
return {
...xe,
breakdowns: xe.breakdowns.filter((it, yt) => yt !== Re),
resultsStale: !0
};
if (ie && xe.breakdowns.some((yt) => yt.isTimeDimension))
return xe;
const Xe = {
id: Lt(),
field: O.name,
isTimeDimension: ie,
granularity: ie ? "month" : void 0
};
return {
...xe,
breakdowns: [...xe.breakdowns, Xe],
resultsStale: !0
};
});
}
Z || be(!1);
},
[L, x]
), Se = F(() => {
te("breakdown"), be(!0);
}, []), tt = F((O) => {
x((P) => {
const W = P.breakdowns.find((xe) => xe.id === O)?.field, Z = P.breakdowns.filter((xe) => xe.id !== O);
let ie = P.order;
return W && ie && ie[W] && (ie = { ...ie }, delete ie[W], Object.keys(ie).length === 0 && (ie = void 0)), {
...P,
breakdowns: Z,
order: ie,
resultsStale: !0
};
});
}, [x]), Ye = F(
(O, P) => {
A === "merge" && D > 0 ? R((W) => {
const Z = [...W];
return Z[0] = {
...Z[0],
breakdowns: Z[0].breakdowns.map(
(ie) => ie.id === O ? { ...ie, granularity: P } : ie
),
resultsStale: !0
}, Z;
}) : x((W) => ({
...W,
breakdowns: W.breakdowns.map(
(Z) => Z.id === O ? { ...Z, granularity: P } : Z
),
resultsStale: !0
}));
},
[A, D, x]
), At = F(
(O) => {
const W = (A === "merge" && D > 0 ? b[0]?.breakdowns || [] : g.breakdowns).find((xe) => xe.id === O), Z = W && !W.enableComparison;
if (Z && W) {
const xe = A === "merge" && D > 0 ? b[0]?.filters || [] : g.filters;
if (!en(xe, W.field)) {
const Xe = {
member: W.field,
operator: "inDateRange",
values: [],
dateRange: Yt("last_30_days")
};
A === "merge" && D > 0 ? R((it) => {
const yt = [...it];
return yt[0] = {
...yt[0],
filters: [...yt[0].filters, Xe]
}, yt;
}) : x((it) => ({
...it,
filters: [...it.filters, Xe]
}));
}
}
if (Z && N !== "line") {
S("line");
const { chartConfig: xe } = hr(
g.metrics,
g.breakdowns,
"line"
);
M(xe);
}
const ie = (xe) => xe.map((Re) => Re.id === O ? { ...Re, enableComparison: !Re.enableComparison } : Re.isTimeDimension && Re.enableComparison ? { ...Re, enableComparison: !1 } : Re);
A === "merge" && D > 0 ? R((xe) => {
const Re = [...xe];
return Re[0] = {
...Re[0],
breakdowns: ie(Re[0].breakdowns),
resultsStale: !0
}, Re;
}) : x((xe) => ({
...xe,
breakdowns: ie(xe.breakdowns),
resultsStale: !0
}));
},
[N, g.breakdowns, g.filters, g.metrics, A, D, b, x]
), Ut = F(
(O, P) => {
x((W) => {
const Z = [...W.metrics], [ie] = Z.splice(O, 1);
return Z.splice(P, 0, ie), {
...W,
metrics: Z,
resultsStale: !0
};
});
},
[x]
), Ht = F(
(O, P) => {
x((W) => {
const Z = [...W.breakdowns], [ie] = Z.splice(O, 1);
return Z.splice(P, 0, ie), {
...W,
breakdowns: Z,
resultsStale: !0
};
});
},
[x]
), zt = F((O) => {
x((P) => ({
...P,
filters: O,
resultsStale: !0
}));
}, [x]), Gt = F((O) => {
const P = {
member: O,
operator: "set",
values: []
};
x((W) => {
const Z = W.filters || [];
if (Z.some(
(Re) => "member" in Re && Re.member === O
))
return W;
let xe;
if (Z.length === 0)
xe = [P];
else if (Z.length === 1 && "type" in Z[0]) {
const Re = Z[0];
xe = [{
...Re,
filters: [...Re.filters, P]
}];
} else
xe = [{
type: "and",
filters: [...Z, P]
}];
return {
...W,
filters: xe,
resultsStale: !0
};
});
}, [x]), Y = F(
(O, P) => {
x((W) => {
const Z = { ...W.order || {} };
return P === null ? delete Z[O] : Z[O] = P, {
...W,
order: Object.keys(Z).length > 0 ? Z : void 0,
resultsStale: !0
};
});
},
[x]
), re = F(() => {
const O = b[D] || _t(), P = {
..._t(),
metrics: [...O.metrics],
breakdowns: [...O.breakdowns],
filters: [...O.filters]
};
R((W) => [...W, P]), $(b.length);
}, [b, D]), de = F((O) => {
R((P) => P.length <= 1 ? P : P.filter((W, Z) => Z !== O)), O === D ? $(Math.max(0, D - 1)) : O < D && $(D - 1);
}, [D]), oe = F((O) => {
$(O);
}, []), fe = F((O) => {
w(O);
}, []), $e = ye(() => {
if (!X) return g.metrics;
const O = /* @__PURE__ */ new Set(), P = [];
for (let W = 0; W < b.length; W++) {
const Z = b[W];
for (const ie of Z.metrics) {
const xe = `Q${W + 1}:${ie.field}`;
O.has(xe) || (O.add(xe), P.push({
...ie,
// Keep original field but update label to show query source
label: `${ie.label} (Q${W + 1})`
}));
}
}
return P;
}, [X, b, g.metrics]), pe = ye(() => {
if (!X) return g.breakdowns;
const O = /* @__PURE__ */ new Set(), P = [];
for (const W of b)
for (const Z of W.breakdowns)
O.has(Z.field) || (O.add(Z.field), P.push(Z));
return P;
}, [X, b, g.breakdowns]), Ae = F(() => {
x(_t()), Te(!1), S("line"), M({}), T({ showLegend: !0, showGrid: !0, showTooltip: !0 }), ot(null), at.current && (clearTimeout(at.current), at.current = null);
}, [x]), Ue = F(() => {
ue({
isOpen: !0,
userPrompt: "",
isGenerating: !1,
error: null,
hasGeneratedQuery: !1,
previousState: {
metrics: [...g.metrics],
breakdowns: [...g.breakdowns],
filters: [...g.filters],
chartType: N,
chartConfig: { ...y },
displayConfig: { ...E }
}
});
}, [g.metrics, g.breakdowns, g.filters, N, y, E]), Je = F(() => {
ue((O) => ({
...O,
isOpen: !1,
userPrompt: "",
error: null,
hasGeneratedQuery: !1
}));
}, []), Ke = F((O) => {
ue((P) => ({ ...P, userPrompt: O }));
}, []), ut = F(async () => {
if (Fe.userPrompt.trim()) {
ue((O) => ({ ...O, isGenerating: !0, error: null }));
try {
const O = await hc(
"",
// API key not needed for server-side AI
Fe.userPrompt,
rt?.aiEndpoint || "/api/ai"
), P = pc(O), W = JSON.parse(P), Z = "query" in W && W.query ? W.query : W, ie = "chartType" in W ? W.chartType : void 0, xe = "chartConfig" in W ? W.chartConfig : void 0;
x((Re) => ({
...Re,
metrics: (Z.measures || []).map((Xe, it) => ({
id: Lt(),
field: Xe,
label: $r(it)
})),
breakdowns: [
...(Z.dimensions || []).map((Xe) => ({
id: Lt(),
field: Xe,
isTimeDimension: !1
})),
...(Z.timeDimensions || []).map((Xe) => ({
id: Lt(),
field: Xe.dimension,
granularity: Xe.granularity,
isTimeDimension: !0
}))
],
filters: Z.filters || []
})), ie && (S(ie), Te(!0)), xe && M(xe), De("chart"), ue((Re) => ({
...Re,
isGenerating: !1,
hasGeneratedQuery: !0
}));
} catch (O) {
ue((P) => ({
...P,
isGenerating: !1,
error: O instanceof Error ? O.message : "Failed to generate query"
}));
}
}
}, [Fe.userPrompt, rt?.aiEndpoint]), mt = F(() => {
ue({
isOpen: !1,
userPrompt: "",
isGenerating: !1,
error: null,
hasGeneratedQuery: !1,
previousState: null
});
}, []), gt = F(() => {
Fe.previousState && (x((O) => ({
...O,
metrics: Fe.previousState.metrics,
breakdowns: Fe.previousState.breakdowns,
filters: Fe.previousState.filters
})), S(Fe.previousState.chartType), M(Fe.previousState.chartConfig), T(Fe.previousState.displayConfig)), ue({
isOpen: !1,
userPrompt: "",
isGenerating: !1,
error: null,
hasGeneratedQuery: !1,
previousState: null
});
}, [Fe.previousState]), Nt = F((O) => {
O !== "line" && g.breakdowns.some((Z) => Z.isTimeDimension && Z.enableComparison) && x((Z) => ({
...Z,
breakdowns: Z.breakdowns.map(
(ie) => ie.isTimeDimension && ie.enableComparison ? { ...ie, enableComparison: !1 } : ie
),
resultsStale: !0
})), S(O), Te(!0);
const { chartConfig: P } = hr(
g.metrics,
g.breakdowns,
O
);
M(P), De("chart");
}, [g.metrics, g.breakdowns]), jt = F((O) => {
M(O), De("chart");
}, []), J = F((O) => {
T(O), De("chart");
}, []), ge = F(async () => {
if (!et) return;
const P = {
query: b.length > 1 ? {
queries: G,
mergeStrategy: A,
mergeKeys: i,
queryLabels: b.map((xe, Re) => `Q${Re + 1}`)
} : _e,
chartType: N,
chartConfig: y,
displayConfig: E,
activeView: ke
}, { encoded: W, queryOnly: Z } = uc(P);
if (!W)
return;
const ie = `${window.location.origin}${window.location.pathname}#share=${W}`;
try {
await navigator.clipboard.writeText(ie);
} catch {
const xe = document.createElement("textarea");
xe.value = ie, document.body.appendChild(xe), xe.select(), document.execCommand("copy"), document.body.removeChild(xe);
}
Ve(Z ? "copied-no-chart" : "copied"), setTimeout(() => {
Ve("idle");
}, 2e3);
}, [et, b.length, G, A, i, _e, N, y, E, ke]);
return zr(
h,
() => ({
getQueryConfig: () => b.length > 1 ? {
queries: G,
mergeStrategy: A,
mergeKeys: i,
queryLabels: b.map((O, P) => `Q${P + 1}`)
} : _e,
getChartConfig: () => ({ chartType: N, chartConfig: y, displayConfig: E }),
executeQuery: () => {
},
clearQuery: Ae
}),
[_e, G, b.length, A, i, N, y, E, Ae]
), /* @__PURE__ */ o(
"div",
{
className: `flex flex-col lg:flex-row bg-dc-surface border-x border-b border-dc-border ${r ? "lg:h-[var(--dc-max-h)] lg:max-h-[var(--dc-max-h)] lg:overflow-hidden" : "lg:h-full"} ${t}`,
style: r ? { "--dc-max-h": r } : void 0,
children: [
/* @__PURE__ */ o("div", { className: "h-[60vh] lg:h-auto lg:flex-1 min-w-0 border-b lg:border-b-0 lg:border-r border-dc-border overflow-auto flex flex-col", children: [
Fe.isOpen && /* @__PURE__ */ e(
Nc,
{
userPrompt: Fe.userPrompt,
onPromptChange: Ke,
isGenerating: Fe.isGenerating,
error: Fe.error,
hasGeneratedQuery: Fe.hasGeneratedQuery,
onGenerate: ut,
onAccept: mt,
onCancel: gt
}
),
/* @__PURE__ */ e("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ e(
To,
{
executionStatus: Pt,
executionResults: pt,
executionError: It?.message || null,
totalRowCount: null,
resultsStale: ht && pt !== null,
chartType: N,
chartConfig: y,
displayConfig: E,
colorPalette: I,
currentPaletteName: c ? void 0 : j,
onColorPaletteChange: c ? void 0 : q,
allQueries: G,
schema: m,
activeView: ke,
onActiveViewChange: De,
displayLimit: Pe,
onDisplayLimitChange: B,
hasMetrics: g.metrics.length > 0,
debugDataPerQuery: H,
onShareClick: ge,
canShare: et,
shareButtonState: Ne,
onClearClick: Ae,
canClear: g.metrics.length > 0 || g.breakdowns.length > 0 || g.filters.length > 0,
enableAI: rt?.enableAI !== !1,
isAIOpen: Fe.isOpen,
onAIToggle: Fe.isOpen ? Je : Ue,
queryCount: b.length,
perQueryResults: k,
activeTableIndex: z,
onActiveTableChange: ne
}
) })
] }),
/* @__PURE__ */ e("div", { className: "w-full lg:w-96 flex-shrink-0 lg:h-full overflow-auto lg:overflow-hidden", children: /* @__PURE__ */ e(
lc,
{
metrics: g.metrics,
breakdowns: g.breakdowns,
filters: g.filters,
schema: m,
activeTab: K,
onActiveTabChange: U,
onAddMetric: Ge,
onRemoveMetric: he,
onReorderMetrics: Ut,
onAddBreakdown: Se,
onRemoveBreakdown: tt,
onBreakdownGranularityChange: Ye,
onBreakdownComparisonToggle: At,
onReorderBreakdowns: Ht,
onFiltersChange: zt,
onDropFieldToFilter: Gt,
order: g.order,
onOrderChange: Y,
chartType: N,
chartConfig: y,
displayConfig: E,
colorPalette: I,
chartAvailability: Ee,
onChartTypeChange: Nt,
onChartConfigChange: jt,
onDisplayConfigChange: J,
validationStatus: g.validationStatus,
validationError: g.validationError,
queryCount: b.length,
activeQueryIndex: D,
mergeStrategy: A,
onActiveQueryChange: oe,
onAddQuery: re,
onRemoveQuery: de,
onMergeStrategyChange: fe,
breakdownsLocked: A === "merge" && D > 0,
combinedMetrics: $e,
combinedBreakdowns: pe,
multiQueryValidation: ae
}
) }),
/* @__PURE__ */ e(
gs,
{
isOpen: le,
onClose: () => be(!1),
onSelect: me,
mode: L,
schema: m,
selectedFields: [
...g.metrics.map((O) => O.field),
...g.breakdowns.map((O) => O.field)
]
}
)
]
}
);
}
);
tn.displayName = "AnalysisBuilder";
const Os = Hr(
(t, r) => {
const n = Ce(null);
return zr(r, () => ({
getCurrentQuery: () => {
const s = n.current?.getQueryConfig();
return s ? "queries" in s ? s.queries[0] || { measures: [], dimensions: [] } : s : { measures: [], dimensions: [] };
},
getValidationState: () => ({
status: "valid"
}),
getValidationResult: () => null
}), []), /* @__PURE__ */ e(
tn,
{
ref: n,
className: t.className,
initialQuery: t.initialQuery,
disableLocalStorage: t.disableLocalStorage,
hideSettings: t.hideSettings
}
);
}
);
Os.displayName = "QueryBuilder";
const Tc = Q("close");
function Sc({
config: t,
fields: r,
onDrop: n,
onRemove: s,
onDragStart: a,
onDragEnd: c,
onDragOver: l,
getFieldStyling: u,
onReorder: d,
draggedItem: f
}) {
const { key: h, label: p, description: m, mandatory: v, maxItems: C, emptyText: _, icon: b } = t, [R, D] = V(null), [$, A] = V(!1), [w, i] = V(!1), g = () => {
let T = r.length;
return f && f.fromAxis === h && (T = Math.max(0, r.length - 1)), !C || T < C;
}, x = () => {
let T = r.length;
return f && f.fromAxis === h && (T = Math.max(0, r.length - 1)), C && T >= C;
}, N = g(), S = x();
wt.useEffect(() => {
const T = () => {
D(null), A(!1), i(!1);
};
return document.addEventListener("dragend", T), () => {
document.removeEventListener("dragend", T);
};
}, []), wt.useEffect(() => {
f ? f.fromAxis !== h ? (i(!1), D(null)) : f.fromAxis === h && f.fromIndex !== void 0 && A(!1) : (D(null), A(!1), i(!1));
}, [f, h]);
const y = (T, j) => {
f && f.fromAxis === h && f.fromIndex !== void 0 && (T.preventDefault(), T.stopPropagation(), D(j), i(!0));
}, M = () => {
D(null);
}, E = (T, j) => {
if (T.preventDefault(), T.stopPropagation(), D(null), i(!1), f && f.fromAxis === h && f.fromIndex !== void 0 && d) {
d(f.fromIndex, j, h);
return;
}
try {
const q = JSON.parse(T.dataTransfer.getData("text/plain"));
q.fromAxis === h && d && q.fromIndex !== void 0 && d(q.fromIndex, j, h);
} catch {
}
};
return /* @__PURE__ */ o("div", { className: "mb-2", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 mb-1", children: [
/* @__PURE__ */ o("h4", { className: "text-xs font-semibold text-dc-text-secondary flex items-center", children: [
b && /* @__PURE__ */ e(b, { className: "w-3 h-3 mr-1 text-dc-text-muted" }),
p,
v && /* @__PURE__ */ e("span", { className: "text-dc-error ml-1", children: "*" }),
C && /* @__PURE__ */ o("span", { className: "text-dc-text-muted ml-1 font-normal", children: [
"(",
r.length,
"/",
C,
")"
] })
] }),
m && /* @__PURE__ */ e("span", { className: "text-xs text-dc-text-muted", children: m })
] }),
/* @__PURE__ */ e(
"div",
{
"data-axis-container": h,
className: `min-h-[40px] sm:min-h-[32px] border-2 border-dashed rounded-lg p-3 sm:p-1.5 transition-all duration-300 flex items-center ${$ && (N || C === 1) || w ? "shadow-lg scale-110 border-solid animate-pulse" : S ? "bg-dc-surface-secondary" : "bg-dc-surface-secondary hover:bg-dc-surface-hover"}`,
style: {
borderColor: $ && (N || C === 1) || w ? "var(--dc-primary)" : "var(--dc-border)",
backgroundColor: $ && (N || C === 1) || w ? "rgba(var(--dc-primary-rgb), 0.1)" : void 0
},
onDragOver: (T) => {
if (f && f.fromAxis === h && f.fromIndex !== void 0)
return;
N || C === 1 ? (A(!0), l(T)) : (T.preventDefault(), T.dataTransfer.dropEffect = "none");
},
onDragLeave: (T) => {
const j = T.currentTarget.getBoundingClientRect(), q = T.clientX < j.left || T.clientX > j.right || T.clientY < j.top || T.clientY > j.bottom, I = T.relatedTarget, K = I && !T.currentTarget.contains(I);
(q || K || T.currentTarget === T.target) && (A(!1), i(!1));
},
onDrop: (T) => {
if (f && f.fromAxis === h && f.fromIndex !== void 0)
return;
N || C === 1 ? n(T, h) : T.preventDefault(), A(!1), i(!1);
},
children: r.length === 0 ? /* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted text-center w-full", children: S ? "Maximum items reached" : _ || "Drop fields here" }) : /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1", children: r.map((T, j) => {
const { IconComponent: q, baseClasses: I, hoverClasses: K } = u(T), U = R === j, ke = f && f.field === T && f.fromAxis === h;
return /* @__PURE__ */ o(
"div",
{
className: `relative ${U ? "transform scale-105" : ""}`,
children: [
U && /* @__PURE__ */ e("div", { className: "absolute -left-1 top-0 bottom-0 w-1 rounded-full z-10", style: { backgroundColor: "var(--dc-primary)" } }),
/* @__PURE__ */ o(
"div",
{
draggable: !0,
onDragStart: (De) => {
a(De, T, h, j);
},
onDragEnd: c,
onDragOver: (De) => y(De, j),
onDragLeave: M,
onDrop: (De) => E(De, j),
className: `rounded text-xs cursor-move px-3 py-0.5 sm:px-2 sm:py-1 flex items-center transition-transform h-[28px] sm:h-auto ${I} ${K} ${U ? "bg-opacity-75" : ""} ${ke ? "opacity-50 cursor-grabbing" : ""}`,
children: [
/* @__PURE__ */ e(q, { className: "w-3 h-3 mr-1 shrink-0" }),
/* @__PURE__ */ e("span", { className: "leading-none", children: T }),
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => s(T, h),
className: "text-dc-text-secondary hover:text-dc-danger ml-1.5 leading-none",
title: `Remove from ${p}`,
children: /* @__PURE__ */ e(Tc, { className: "w-3 h-3" })
}
)
]
}
)
]
},
`${T}-${j}`
);
}) })
}
),
v && r.length === 0 && /* @__PURE__ */ e("div", { className: "text-xs text-dc-error mt-0.5", children: "This field is required" })
] });
}
const $n = Q("measure"), In = Q("dimension"), Ln = Q("timeDimension");
function Fn({
chartType: t,
chartConfig: r,
displayConfig: n,
availableFields: s,
colorPalette: a,
onChartConfigChange: c,
onDisplayConfigChange: l
}) {
const [u, d] = V(null), f = ye(
() => Dr(t, Kt),
[t]
), h = f.skipQuery === !0, p = (i) => {
const g = r[i];
return Array.isArray(g) ? g : typeof g == "string" ? [g] : [];
};
ve(() => {
if (!s) return;
const i = [
...s.dimensions,
...s.timeDimensions,
...s.measures
];
let g = !1;
const x = { ...r };
f.dropZones.forEach((N) => {
const S = p(N.key), y = S.filter((M) => i.includes(M));
y.length !== S.length && (g = !0, y.length === 0 ? delete x[N.key] : N.maxItems === 1 ? x[N.key] = y[0] : x[N.key] = y);
}), g && c(x);
}, [s, r, f.dropZones, c]);
const m = (i) => s ? s.measures.includes(i) ? "measure" : s.timeDimensions.includes(i) ? "timeDimension" : "dimension" : "dimension", v = (i) => {
switch (m(i)) {
case "measure":
return {
IconComponent: $n,
baseClasses: "bg-dc-measure text-dc-measure border border-dc-measure",
hoverClasses: "hover:opacity-80"
};
case "timeDimension":
return {
IconComponent: Ln,
baseClasses: "bg-dc-time-dimension text-dc-time-dimension border border-dc-time-dimension",
hoverClasses: "hover:opacity-80"
};
default:
return {
IconComponent: In,
baseClasses: "bg-dc-dimension text-dc-dimension border border-dc-dimension",
hoverClasses: "hover:opacity-80"
};
}
}, C = (i, g, x, N) => {
i.dataTransfer.setData("text/plain", JSON.stringify({ field: g, fromAxis: x, fromIndex: N })), d({ field: g, fromAxis: x, fromIndex: N });
}, _ = (i) => {
i.preventDefault();
}, b = () => {
d(null);
}, R = (i, g) => {
i.preventDefault();
const x = JSON.parse(i.dataTransfer.getData("text/plain")), { field: N, fromAxis: S } = x, y = { ...r };
if (S !== "available" && S !== g) {
const T = y[S];
if (Array.isArray(T)) {
const j = T.filter((q) => q !== N);
j.length === 0 ? delete y[S] : y[S] = j;
} else T === N && delete y[S];
}
const M = y[g];
f.dropZones.find((T) => T.key === g)?.maxItems === 1 ? y[g] = N : Array.isArray(M) ? M.includes(N) || (y[g] = [...M, N]) : y[g] = [N], d(null), c(y);
}, D = (i, g) => {
const x = { ...r }, N = x[g];
if (Array.isArray(N)) {
const S = N.filter((y) => y !== i);
S.length === 0 ? delete x[g] : x[g] = S;
} else N === i && delete x[g];
c(x);
}, $ = (i, g, x) => {
const N = { ...r }, S = N[x];
if (Array.isArray(S) && S.length > 1 && i !== g) {
const y = [...S], [M] = y.splice(i, 1);
y.splice(g, 0, M), N[x] = y, d(null), c(N);
}
}, w = (() => {
if (!s) return { dimensions: [], timeDimensions: [], measures: [] };
const i = /* @__PURE__ */ new Set();
return f.dropZones.forEach((g) => {
p(g.key).forEach((x) => i.add(x));
}), u && u.fromAxis !== "available" && i.add(u.field), {
dimensions: s.dimensions.filter((g) => !i.has(g)),
timeDimensions: s.timeDimensions.filter((g) => !i.has(g)),
measures: s.measures.filter((g) => !i.has(g))
};
})();
return /* @__PURE__ */ o("div", { children: [
!h && s && /* @__PURE__ */ o("div", { className: "mb-4", children: [
/* @__PURE__ */ e("h4", { className: "text-xs font-semibold text-dc-text-secondary mb-2", children: "Available Fields" }),
/* @__PURE__ */ e("div", { className: "border border-dc-border rounded-lg p-2 bg-dc-surface-secondary", children: w.dimensions.length > 0 || w.timeDimensions.length > 0 || w.measures.length > 0 ? /* @__PURE__ */ o("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-2 sm:gap-2 gap-y-4 sm:gap-y-2", children: [
/* @__PURE__ */ o("div", { className: "pb-2 sm:pb-0", children: [
/* @__PURE__ */ o("div", { className: "text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center", children: [
/* @__PURE__ */ e(In, { className: "w-3 h-3 mr-1 text-dc-text-muted" }),
"Dimensions"
] }),
/* @__PURE__ */ o("div", { className: "space-y-1", children: [
w.dimensions.map((i) => {
const g = u && u.field === i && u.fromAxis === "available";
return /* @__PURE__ */ e(
"div",
{
draggable: !0,
onDragStart: (x) => C(x, i, "available"),
onDragEnd: b,
className: `bg-dc-dimension text-dc-dimension border border-dc-dimension hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${g ? "opacity-50 cursor-grabbing" : ""}`,
title: i,
children: i
},
i
);
}),
w.dimensions.length === 0 && /* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted italic", children: "None" })
] })
] }),
/* @__PURE__ */ o("div", { className: "pb-2 sm:pb-0", children: [
/* @__PURE__ */ o("div", { className: "text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center", children: [
/* @__PURE__ */ e(Ln, { className: "w-3 h-3 mr-1 text-dc-text-muted" }),
"Time Dimensions"
] }),
/* @__PURE__ */ o("div", { className: "space-y-1", children: [
w.timeDimensions.map((i) => {
const g = u && u.field === i && u.fromAxis === "available";
return /* @__PURE__ */ e(
"div",
{
draggable: !0,
onDragStart: (x) => C(x, i, "available"),
onDragEnd: b,
className: `bg-dc-time-dimension text-dc-time-dimension border border-dc-time-dimension hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${g ? "opacity-50 cursor-grabbing" : ""}`,
title: i,
children: i
},
i
);
}),
w.timeDimensions.length === 0 && /* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted italic", children: "None" })
] })
] }),
/* @__PURE__ */ o("div", { className: "pb-2 sm:pb-0", children: [
/* @__PURE__ */ o("div", { className: "text-xs text-dc-text-secondary mb-2 sm:mb-1 flex items-center", children: [
/* @__PURE__ */ e($n, { className: "w-3 h-3 mr-1 text-dc-text-muted" }),
"Measures"
] }),
/* @__PURE__ */ o("div", { className: "space-y-1", children: [
w.measures.map((i) => {
const g = u && u.field === i && u.fromAxis === "available";
return /* @__PURE__ */ e(
"div",
{
draggable: !0,
onDragStart: (x) => C(x, i, "available"),
onDragEnd: b,
className: `bg-dc-measure text-dc-measure border border-dc-measure hover:opacity-80 rounded-sm text-xs cursor-move px-3 py-2 sm:px-2 sm:py-1 truncate ${g ? "opacity-50 cursor-grabbing" : ""}`,
title: i,
children: i
},
i
);
}),
w.measures.length === 0 && /* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted italic", children: "None" })
] })
] })
] }) : /* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted text-center py-2", children: "All fields have been assigned" }) })
] }),
!h && /* @__PURE__ */ o("div", { className: "mb-4", children: [
/* @__PURE__ */ e("h4", { className: "text-xs font-semibold text-dc-text-secondary mb-2", children: "Chart Configuration" }),
/* @__PURE__ */ e("div", { className: "space-y-1", children: f.dropZones.map((i) => /* @__PURE__ */ e(
Sc,
{
config: i,
fields: p(i.key),
onDrop: R,
onRemove: D,
onDragStart: C,
onDragEnd: b,
onDragOver: _,
getFieldStyling: v,
onReorder: $,
draggedItem: u
},
i.key
)) })
] }),
(f.displayOptions && f.displayOptions.length > 0 || f.displayOptionsConfig && f.displayOptionsConfig.length > 0) && /* @__PURE__ */ o("div", { className: "mb-4", children: [
/* @__PURE__ */ e("h4", { className: "text-xs font-semibold text-dc-text-secondary mb-2", children: "Display Options" }),
/* @__PURE__ */ o("div", { className: "space-y-2", children: [
f.displayOptions?.includes("showLegend") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: n.showLegend ?? !0,
onChange: (i) => l({
...n,
showLegend: i.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Show Legend" })
] }),
f.displayOptions?.includes("showGrid") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: n.showGrid ?? !0,
onChange: (i) => l({
...n,
showGrid: i.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Show Grid" })
] }),
f.displayOptions?.includes("showTooltip") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: n.showTooltip ?? !0,
onChange: (i) => l({
...n,
showTooltip: i.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Show Tooltip" })
] }),
f.displayOptions?.includes("stacked") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: n.stacked ?? !1,
onChange: (i) => l({
...n,
stacked: i.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Stacked" })
] }),
f.displayOptions?.includes("hideHeader") && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: n.hideHeader ?? !1,
onChange: (i) => l({
...n,
hideHeader: i.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: "Hide Header" })
] }),
f.displayOptionsConfig?.map((i) => /* @__PURE__ */ o("div", { className: "space-y-1", children: [
i.type === "boolean" && /* @__PURE__ */ o("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: n[i.key] ?? i.defaultValue ?? !1,
onChange: (g) => l({
...n,
[i.key]: g.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text", children: i.label })
] }),
i.type === "string" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ o("label", { className: "text-sm text-dc-text-secondary", children: [
i.label,
i.key === "content" && /* @__PURE__ */ e("span", { className: "text-xs text-dc-text-muted ml-1", children: "(only headers, lists and links)" })
] }),
i.key === "content" ? /* @__PURE__ */ e(
"textarea",
{
value: n[i.key] ?? i.defaultValue ?? "",
onChange: (g) => l({
...n,
[i.key]: g.target.value
}),
placeholder: i.placeholder,
rows: 8,
className: "w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent font-mono resize-y bg-dc-surface text-dc-text"
}
) : /* @__PURE__ */ e(
"input",
{
type: "text",
value: n[i.key] ?? i.defaultValue ?? "",
onChange: (g) => l({
...n,
[i.key]: g.target.value
}),
placeholder: i.placeholder,
className: "w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text"
}
),
i.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: i.description })
] }),
i.type === "paletteColor" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ e("label", { className: "text-sm text-dc-text-secondary", children: i.label }),
/* @__PURE__ */ e("div", { className: "flex flex-wrap gap-2", children: a?.colors.map((g, x) => {
const N = (n[i.key] ?? i.defaultValue ?? 0) === x;
return /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => l({
...n,
[i.key]: x
}),
className: `w-8 h-8 rounded border-2 transition-all duration-200 hover:scale-110 focus:outline-hidden focus:ring-2 focus:ring-dc-accent focus:ring-offset-1 ${N ? "ring-2 ring-offset-1 scale-110" : "hover:border-dc-text-muted"}`,
style: {
backgroundColor: g,
borderColor: N ? "var(--dc-primary)" : "var(--dc-border)"
},
title: `Color ${x + 1}: ${g}`
},
x
);
}) || [
// Fallback if no palette available
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => l({
...n,
[i.key]: 0
}),
className: "w-8 h-8 rounded-sm border-2 ring-2 ring-offset-1",
style: {
backgroundColor: "#8884d8",
borderColor: "var(--dc-primary)",
boxShadow: "0 0 0 2px var(--dc-primary)"
},
title: "Default Color"
},
0
)
] }),
i.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: i.description })
] }),
i.type === "number" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ e("label", { className: "text-sm text-dc-text-secondary", children: i.label }),
/* @__PURE__ */ e(
"input",
{
type: "number",
value: n[i.key] ?? i.defaultValue ?? 0,
onChange: (g) => l({
...n,
[i.key]: g.target.value === "" ? void 0 : Number(g.target.value)
}),
placeholder: i.placeholder,
min: i.min,
max: i.max,
step: i.step,
className: "w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text"
}
),
i.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: i.description })
] }),
i.type === "select" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ e("label", { className: "text-sm text-dc-text-secondary", children: i.label }),
/* @__PURE__ */ e(
"select",
{
value: n[i.key] ?? i.defaultValue ?? "",
onChange: (g) => l({
...n,
[i.key]: g.target.value
}),
className: "w-full px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text",
children: i.options?.map((g) => /* @__PURE__ */ e("option", { value: g.value, children: g.label }, g.value))
}
),
i.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: i.description })
] }),
i.type === "color" && /* @__PURE__ */ o("div", { className: "space-y-1", children: [
/* @__PURE__ */ e("label", { className: "text-sm text-dc-text-secondary", children: i.label }),
/* @__PURE__ */ o("div", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "color",
value: n[i.key] ?? i.defaultValue ?? "#8884d8",
onChange: (g) => l({
...n,
[i.key]: g.target.value
}),
className: "w-12 h-8 border border-dc-border rounded-sm cursor-pointer"
}
),
/* @__PURE__ */ e(
"input",
{
type: "text",
value: n[i.key] ?? i.defaultValue ?? "#8884d8",
onChange: (g) => l({
...n,
[i.key]: g.target.value
}),
placeholder: i.placeholder || "#8884d8",
className: "flex-1 px-2 py-1 text-sm border border-dc-border rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text"
}
)
] }),
i.description && /* @__PURE__ */ e("p", { className: "text-xs text-dc-text-muted", children: i.description })
] })
] }, i.key))
] })
] })
] });
}
const Ac = [
{
name: "Employee Count by Department",
query: JSON.stringify({
measures: ["Employees.count"],
dimensions: ["Departments.name"],
order: { "Employees.count": "desc" }
}, null, 2)
},
{
name: "Employee Hiring Trends",
query: JSON.stringify({
measures: ["Employees.count"],
timeDimensions: [{
dimension: "Employees.createdAt",
granularity: "month"
}],
order: { "Employees.createdAt": "asc" }
}, null, 2)
},
{
name: "Department Budget Analysis",
query: JSON.stringify({
measures: ["Departments.totalBudget", "Departments.avgBudget"],
dimensions: ["Departments.name"],
order: { "Departments.totalBudget": "desc" }
}, null, 2)
},
{
name: "Daily Productivity Trends",
query: JSON.stringify({
measures: ["Productivity.avgLinesOfCode", "Productivity.totalPullRequests"],
timeDimensions: [{
dimension: "Productivity.date",
granularity: "day"
}],
order: { "Productivity.date": "asc" }
}, null, 2)
},
{
name: "Happiness by Department",
query: JSON.stringify({
measures: ["Productivity.avgHappinessIndex", "Productivity.workingDaysCount"],
dimensions: ["Departments.name"],
order: { "Productivity.avgHappinessIndex": "desc" }
}, null, 2)
},
{
name: "Employee Salary Overview",
query: JSON.stringify({
measures: ["Employees.count", "Employees.avgSalary", "Employees.totalSalary"],
dimensions: ["Employees.isActive"],
order: { "Employees.avgSalary": "desc" }
}, null, 2)
}
];
function qn({
isOpen: t,
onClose: r,
onSave: n,
portlet: s,
title: a,
submitText: c,
colorPalette: l
}) {
const { cubeApi: u } = Qt(), [d, f] = V(""), [h, p] = V(""), [m, v] = V("bar"), [C, _] = V([]), [b, R] = V(!1), [D, $] = V(null), [A, w] = V(""), [i, g] = V(null), [x, N] = V({ xAxis: [], yAxis: [], series: [] }), [S, y] = V({ showLegend: !0, showGrid: !0, showTooltip: !0, stacked: !1 }), [M, E] = V(!1), [T, j] = V(null), q = Ce(null), K = Dr(m, Kt).skipQuery === !0, U = (ue) => {
}, ke = 5, De = 4;
ve(() => {
if (t) {
if (s) {
f(s.title);
const ue = (() => {
try {
return JSON.stringify(JSON.parse(s.query), null, 2);
} catch {
return s.query;
}
})();
p(ue), v(s.chartType), N(s.chartConfig || { xAxis: [], yAxis: [], series: [] }), y(s.displayConfig || {}), _(s.dashboardFilterMapping || []), w(ue), $({ isValid: !0, message: "Loaded query (assumed valid)" }), g(null), K || setTimeout(() => {
Te(ue, !0, !0);
}, 100);
} else
f(""), p(""), v("bar"), N({ xAxis: [], yAxis: [], series: [] }), y({ showLegend: !0, showGrid: !0, showTooltip: !0, stacked: !1 }), _([]), w(""), $(null), g(null);
R(!1);
}
}, [t, s]);
const Pe = (ue) => {
if (ue.preventDefault(), K) {
if (!d.trim())
return;
} else {
if (!d.trim() || !h.trim())
return;
if (Ne || A === "" && h.trim() !== "") {
alert("Please validate your query before saving.");
return;
}
try {
JSON.parse(h);
} catch {
alert("Invalid JSON in query. Please check your syntax.");
return;
}
}
const _e = K ? '{"measures":[]}' : h.trim();
n(s ? {
...s,
title: d.trim(),
query: _e,
chartType: m,
chartConfig: Object.keys(x).length > 0 ? x : void 0,
displayConfig: S,
dashboardFilterMapping: C.length > 0 ? C : void 0,
w: s.w || ke,
h: s.h || De
} : {
title: d.trim(),
query: _e,
chartType: m,
chartConfig: Object.keys(x).length > 0 ? x : void 0,
displayConfig: S,
dashboardFilterMapping: C.length > 0 ? C : void 0,
w: ke,
h: De
});
}, B = (ue) => {
p(ue), $(null), w(""), g(null), N({ xAxis: [], yAxis: [], series: [] });
}, se = (ue) => {
p(ue), $(null), g(null), s || N({ xAxis: [], yAxis: [], series: [] });
}, Te = async (ue, _e = !1, G = !1) => {
if (!ue.trim()) {
_e || $({ isValid: !1, message: "Query cannot be empty" });
return;
}
let X;
try {
X = JSON.parse(ue);
} catch {
_e || $({ isValid: !1, message: "Invalid JSON syntax" });
return;
}
_e || (R(!0), $(null));
try {
const ae = await u.dryRun(X);
if (!ae.error && ae.queryType) {
if (g(ae), !_e) {
const je = [];
ae.pivotQuery?.query && (ae.pivotQuery.query.measures?.length > 0 && je.push(`${ae.pivotQuery.query.measures.length} measure${ae.pivotQuery.query.measures.length > 1 ? "s" : ""}`), ae.pivotQuery.query.dimensions?.length > 0 && je.push(`${ae.pivotQuery.query.dimensions.length} dimension${ae.pivotQuery.query.dimensions.length > 1 ? "s" : ""}`), ae.pivotQuery.query.filters?.length > 0 && je.push(`${ae.pivotQuery.query.filters.length} filter${ae.pivotQuery.query.filters.length > 1 ? "s" : ""}`), ae.pivotQuery.query.timeDimensions?.length > 0 && je.push(`${ae.pivotQuery.query.timeDimensions.length} time dimension${ae.pivotQuery.query.timeDimensions.length > 1 ? "s" : ""}`)), ae.complexity && je.push(`${ae.complexity} complexity`), ae.sql?.sql && je.push("SQL generated"), ae.cubesUsed?.length > 0 && je.push(`Cubes: ${ae.cubesUsed.join(", ")}`);
const nt = je.length > 0 ? `Query validated successfully (${je.join(", ")})` : "Query validated successfully";
$({ isValid: !0, message: nt }), w(ue);
}
G || U(ae);
} else if (!_e) {
const je = ae.error || "Query validation failed", nt = ae.details ? ` - ${Array.isArray(ae.details) ? ae.details.join(", ") : ae.details}` : "";
$({
isValid: !1,
message: je + nt
}), w(ue);
}
} catch (ae) {
_e || ($({
isValid: !1,
message: ae instanceof Error ? ae.message : "Network error during validation"
}), w(ue));
} finally {
_e || R(!1);
}
}, H = async () => {
await Te(h);
}, ee = () => {
const ue = h ? (() => {
try {
return JSON.parse(h);
} catch {
return {};
}
})() : {};
j(ue), E(!0);
}, le = (ue) => {
if (ue?.preventDefault(), ue?.stopPropagation(), !q.current) return;
const _e = q.current.getCurrentQuery(), G = q.current.getValidationState(), X = q.current.getValidationResult(), ae = JSON.stringify(_e, null, 2);
p(ae), G?.status === "valid" && X ? ($({
isValid: !0,
message: "Query validated in Query Builder"
}), w(ae), g(X)) : ($(null), w(""), g(null)), E(!1);
}, be = () => {
E(!1), j(null);
}, L = () => {
f(""), p(""), v("bar"), N({ xAxis: [], yAxis: [], series: [] }), y({ showLegend: !0, showGrid: !0, showTooltip: !0, stacked: !1 }), $(null), R(!1), w(""), g(null), E(!1), j(null), r();
}, te = !!s, Ne = h.trim() !== A.trim() && A !== "", Ve = D?.isValid && h.trim() === A.trim(), rt = i?.pivotQuery?.query ? {
dimensions: i.pivotQuery.query.dimensions || [],
timeDimensions: i.pivotQuery.query.timeDimensions?.map((ue) => ue.dimension) || [],
measures: i.pivotQuery.query.measures || []
} : null, Fe = M ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: be,
className: "px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-none focus:ring-2 focus:ring-dc-primary",
children: "Back to Form"
}
),
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: le,
className: "px-4 py-2 text-sm font-medium border border-transparent rounded-md focus:outline-none focus:ring-2 focus:ring-dc-accent",
style: { backgroundColor: "var(--dc-primary)", color: "#ffffff" },
title: "Apply query to form",
onMouseEnter: (ue) => ue.currentTarget.style.backgroundColor = "var(--dc-primary-hover)",
onMouseLeave: (ue) => ue.currentTarget.style.backgroundColor = "var(--dc-primary)",
children: "Apply Query"
}
)
] }) : /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: L,
className: "px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-none focus:ring-2 focus:ring-dc-primary",
children: "Cancel"
}
),
/* @__PURE__ */ e(
"button",
{
type: "submit",
form: "portlet-form",
className: "px-4 py-2 text-sm font-medium border border-transparent rounded-md disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-dc-accent",
style: { backgroundColor: "var(--dc-primary)", color: "#ffffff" },
disabled: K ? !d.trim() : !d.trim() || !h.trim() || Ne || A === "" && h.trim() !== "",
title: !K && (Ne || A === "" && h.trim() !== "") ? "Please validate your query before saving" : "",
onMouseEnter: (ue) => ue.currentTarget.style.backgroundColor = "var(--dc-primary-hover)",
onMouseLeave: (ue) => ue.currentTarget.style.backgroundColor = "var(--dc-primary)",
children: c
}
)
] });
return /* @__PURE__ */ e(
Yr,
{
isOpen: t,
onClose: L,
title: M ? "Query Builder" : a,
size: "fullscreen-mobile",
footer: Fe,
noPadding: M,
children: M ? /* @__PURE__ */ e(
Os,
{
ref: q,
initialQuery: T,
disableLocalStorage: !0,
hideSettings: !0,
className: "flex-1 w-full"
}
) : /* @__PURE__ */ o("form", { id: "portlet-form", onSubmit: Pe, className: "space-y-4", children: [
/* @__PURE__ */ o("div", { className: "flex flex-col lg:flex-row gap-4", children: [
/* @__PURE__ */ o("div", { className: "flex-1 flex flex-col gap-4", children: [
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("label", { className: "block text-sm font-semibold text-dc-text-secondary mb-1", children: "Title" }),
/* @__PURE__ */ e(
"input",
{
type: "text",
value: d,
onChange: (ue) => f(ue.target.value),
className: "w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary",
placeholder: "Enter portlet title...",
required: !0
}
)
] }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("label", { className: "block text-sm font-semibold text-dc-text-secondary mb-3", children: "Chart Type" }),
/* @__PURE__ */ e(
Es,
{
selectedType: m,
onTypeChange: v
}
)
] }),
!K && /* @__PURE__ */ o("div", { className: "flex-1 flex flex-col", children: [
/* @__PURE__ */ o("div", { className: "flex justify-between items-center mb-1", children: [
/* @__PURE__ */ e("label", { className: "block text-sm font-semibold text-dc-text-secondary", children: "Cube.js Query (JSON)" }),
/* @__PURE__ */ e("div", { className: "flex items-center space-x-2", children: /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: ee,
className: "text-xs px-2 py-1 text-dc-accent bg-dc-surface hover:bg-dc-accent-bg rounded-sm border border-dc-accent hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-dc-accent",
children: "Edit in Query Builder"
}
) })
] }),
/* @__PURE__ */ e(
"textarea",
{
value: h,
onChange: (ue) => se(ue.target.value),
className: "flex-1 w-full min-h-64 px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary font-mono text-xs resize-y",
placeholder: `{
"measures": ["People.count"],
"dimensions": ["People.active"]
}`,
required: !0
}
)
] })
] }),
/* @__PURE__ */ o("div", { className: "flex-1 flex flex-col", children: [
/* @__PURE__ */ e("label", { className: "block text-sm font-semibold text-dc-text-secondary mb-1", children: K ? "Chart Configuration" : "Chart Axis Configuration" }),
K ? /* @__PURE__ */ e("div", { className: "rounded-lg bg-dc-surface p-3 border border-dc-border", children: /* @__PURE__ */ e(
Fn,
{
chartType: m,
chartConfig: x,
displayConfig: S,
availableFields: null,
colorPalette: l,
onChartConfigChange: N,
onDisplayConfigChange: y
}
) }) : !i || !Ve ? /* @__PURE__ */ e("div", { className: "flex-1 flex items-center justify-center border-2 border-dashed border-dc-border rounded-lg bg-dc-surface-secondary", children: /* @__PURE__ */ o("div", { className: "text-center text-dc-text-muted", children: [
/* @__PURE__ */ e("svg", { className: "h-8 w-8 mx-auto mb-2", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) }),
/* @__PURE__ */ e("p", { className: "text-sm", children: "Validate query first to configure chart axes" })
] }) }) : /* @__PURE__ */ e("div", { className: "rounded-lg bg-dc-surface p-3 border border-dc-border", children: /* @__PURE__ */ e(
Fn,
{
chartType: m,
chartConfig: x,
displayConfig: S,
availableFields: rt,
colorPalette: l,
onChartConfigChange: N,
onDisplayConfigChange: y
}
) })
] })
] }),
!K && (Ne || A === "" && h.trim() !== "" || D && h.trim() === A.trim() && D.message !== "Loaded query (assumed valid)") && /* @__PURE__ */ e("div", { className: `rounded-lg p-4 ${D?.isValid && h.trim() === A.trim() ? "bg-dc-success-bg" : D && !D.isValid ? "bg-dc-error-bg" : Ne ? "bg-dc-warning-bg" : "bg-dc-surface-secondary"}`, children: /* @__PURE__ */ o("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ o("div", { className: "flex items-center space-x-3", children: [
/* @__PURE__ */ e("div", { className: `w-2 h-2 rounded-full ${D?.isValid && h.trim() === A.trim() ? "bg-dc-success" : D && !D.isValid ? "bg-dc-error" : Ne ? "bg-dc-warning" : "bg-dc-muted"}` }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("h3", { className: `text-sm font-medium ${D?.isValid && h.trim() === A.trim() ? "text-dc-success" : D && !D.isValid ? "text-dc-error" : Ne ? "text-dc-warning" : "text-dc-text-secondary"}`, children: D?.isValid && h.trim() === A.trim() ? "Query validated successfully" : D && !D.isValid ? "Query validation failed" : Ne ? "Query modified - validation required" : "Query validation required" }),
D && /* @__PURE__ */ e("p", { className: `text-xs mt-1 ${D.isValid ? "text-dc-success" : "text-dc-error"}`, children: D.message })
] })
] }),
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: H,
disabled: b || !h.trim(),
className: `px-3 py-1.5 text-sm font-medium rounded-md transition-colors flex items-center space-x-1.5 ${D?.isValid && h.trim() === A.trim() ? "bg-dc-success text-white hover:opacity-80" : D && !D.isValid ? "bg-dc-error text-white hover:opacity-80" : "bg-dc-primary text-white hover:bg-dc-primary-hover"} disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-dc-primary`,
children: b ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ o("svg", { className: "animate-spin h-4 w-4", fill: "none", viewBox: "0 0 24 24", children: [
/* @__PURE__ */ e("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
/* @__PURE__ */ e("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
] }),
/* @__PURE__ */ e("span", { children: "Validating" })
] }) : D?.isValid && h.trim() === A.trim() ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
/* @__PURE__ */ e("span", { children: "Validated" })
] }) : /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
/* @__PURE__ */ e("span", { children: "Validate" })
] })
}
)
] }) }),
!te && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("label", { className: "block text-sm text-dc-text-muted mb-2", children: "Sample Queries (click to use)" }),
/* @__PURE__ */ e("div", { className: "flex flex-wrap gap-2 mb-2", children: Ac.map((ue, _e) => /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => B(ue.query),
className: "px-2 py-1 text-xs text-dc-text-secondary bg-dc-surface-secondary border border-dc-border rounded-sm cursor-pointer transition-all duration-200 ease-in-out hover:bg-dc-surface-hover hover:border-dc-border m-0.5",
children: ue.name
},
_e
)) })
] })
] })
}
);
}
function Pn({
isOpen: t,
onClose: r,
onSave: n,
portlet: s,
initialData: a,
title: c,
submitText: l,
colorPalette: u
}) {
const d = Ce(null), [f, h] = V(""), p = wt.useMemo(() => {
if (s?.query)
try {
return JSON.parse(s.query);
} catch {
return;
}
}, [s?.query]), m = wt.useMemo(() => {
if (s)
return {
chartType: s.chartType,
chartConfig: s.chartConfig,
displayConfig: s.displayConfig
};
}, [s]);
ve(() => {
t && h(s?.title || "");
}, [t, s]);
const v = F(() => {
if (!f.trim()) {
alert("Please enter a title for the portlet.");
return;
}
const b = d.current?.getQueryConfig(), R = d.current?.getChartConfig();
if (!b) {
alert("Please configure a query before saving.");
return;
}
const D = "queries" in b ? b.queries[0] : b;
if (!(D?.measures && D.measures.length > 0 || D?.dimensions && D.dimensions.length > 0 || D?.timeDimensions && D.timeDimensions.length > 0)) {
alert("Please add at least one metric or breakdown to your query.");
return;
}
const A = {
...s || {},
title: f.trim(),
query: JSON.stringify(b),
chartType: R?.chartType || "line",
chartConfig: R?.chartConfig || {},
displayConfig: R?.displayConfig || {},
// Preserve existing position or use defaults for new portlets
w: s?.w || 5,
h: s?.h || 4
};
n(A), r();
}, [f, s, n, r]), C = F(() => {
r();
}, [r]);
return /* @__PURE__ */ e(
Yr,
{
isOpen: t,
onClose: r,
title: c,
size: "fullscreen-mobile",
showCloseButton: !0,
closeOnBackdropClick: !1,
closeOnEscape: !0,
noPadding: !0,
footer: /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: C,
className: "px-4 py-2 text-sm font-medium text-dc-text-secondary hover:text-dc-text bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover transition-colors",
children: "Cancel"
}
),
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: v,
className: "px-4 py-2 text-sm font-medium text-white bg-dc-accent hover:bg-dc-accent-hover rounded-md transition-colors",
children: l
}
)
] }),
children: /* @__PURE__ */ o("div", { className: "flex flex-col h-full", children: [
/* @__PURE__ */ e("div", { className: "shrink-0 px-4 py-3 border-b border-dc-border bg-dc-surface-secondary", children: /* @__PURE__ */ o("div", { className: "flex items-center gap-3", children: [
/* @__PURE__ */ e("label", { htmlFor: "portlet-title", className: "text-sm font-medium text-dc-text-secondary shrink-0", children: "Title" }),
/* @__PURE__ */ e(
"input",
{
id: "portlet-title",
type: "text",
value: f,
onChange: (b) => h(b.target.value),
placeholder: "Enter portlet title...",
autoComplete: "off",
className: "flex-1 px-3 py-1.5 text-sm bg-dc-surface border border-dc-border rounded-md text-dc-text placeholder-dc-text-muted focus:outline-none focus:ring-2 focus:ring-dc-accent focus:border-transparent",
autoFocus: !0
}
)
] }) }),
/* @__PURE__ */ e("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ e(
tn,
{
ref: d,
maxHeight: "100%",
initialQuery: p,
initialChartConfig: m,
initialData: a,
colorPalette: u,
disableLocalStorage: !0,
className: "h-full"
}
) })
] })
}
);
}
function Ec({
isOpen: t,
onClose: r,
dashboardFilters: n = [],
currentMapping: s = [],
onSave: a,
portletTitle: c
}) {
const [l, u] = V(s);
ve(() => {
u(s);
}, [s, t]);
const d = (m) => {
u((v) => v.includes(m) ? v.filter((C) => C !== m) : [...v, m]);
}, f = () => {
a(l), r();
}, h = () => {
u(s), r();
}, p = (m) => {
if (!m.filter) return "";
if ("member" in m.filter && m.filter.member) {
const v = m.filter.values || [], C = v.length > 0 ? v.join(", ") : "no value";
return `${m.filter.member} ${m.filter.operator} ${C}`;
}
if ("type" in m.filter && m.filter.type) {
const v = m.filter.filters?.length || 0;
return `${m.filter.type.toUpperCase()} group with ${v} filter${v !== 1 ? "s" : ""}`;
}
return "Complex filter";
};
return t ? /* @__PURE__ */ e("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50", onClick: h, children: /* @__PURE__ */ o(
"div",
{
className: "bg-dc-surface border border-dc-border rounded-lg max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col",
style: { boxShadow: "var(--dc-shadow-lg)" },
onClick: (m) => m.stopPropagation(),
children: [
/* @__PURE__ */ o("div", { className: "px-6 py-4 border-b border-dc-border bg-dc-surface-secondary rounded-t-lg", children: [
/* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-dc-text", children: "Configure Dashboard Filters" }),
/* @__PURE__ */ o("p", { className: "text-sm text-dc-text-secondary mt-1", children: [
'Choose which dashboard filters apply to "',
c,
'"'
] })
] }),
/* @__PURE__ */ e("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: n.length === 0 ? /* @__PURE__ */ o("div", { className: "text-center py-8 text-dc-text-muted", children: [
/* @__PURE__ */ e(
"svg",
{
className: "mx-auto h-12 w-12 mb-3",
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor",
children: /* @__PURE__ */ e(
"path",
{
strokeLinecap: "round",
strokeLinejoin: "round",
strokeWidth: 1.5,
d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
}
)
}
),
/* @__PURE__ */ e("p", { className: "text-sm font-medium", children: "No dashboard filters available" }),
/* @__PURE__ */ e("p", { className: "text-xs mt-1", children: "Add filters at the dashboard level first" })
] }) : /* @__PURE__ */ o("div", { className: "space-y-3", children: [
/* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-4 pb-2 border-b border-dc-border", children: [
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-dc-text", children: "Available Filters" }),
/* @__PURE__ */ o("span", { className: "text-xs text-dc-text-secondary", children: [
l.length,
" of ",
n.length,
" selected"
] })
] }),
n.map((m) => {
const v = l.includes(m.id);
return /* @__PURE__ */ o(
"label",
{
className: `flex items-start p-3 rounded-md border cursor-pointer transition-colors ${v ? "border-dc-primary bg-dc-surface-secondary" : "border-dc-border hover:bg-dc-surface-hover"}`,
children: [
/* @__PURE__ */ e(
"input",
{
type: "checkbox",
checked: v,
onChange: () => d(m.id),
className: "mt-0.5 mr-3 h-4 w-4 rounded border-dc-border focus:ring-2 focus:ring-dc-primary",
style: {
accentColor: "var(--dc-primary)"
}
}
),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e("span", { className: "font-medium text-sm text-dc-text truncate", children: m.label }),
v && /* @__PURE__ */ e(
"span",
{
className: "px-2 py-0.5 text-xs rounded-full",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: "Applied"
}
)
] }),
/* @__PURE__ */ e("div", { className: "mt-1 text-xs text-dc-text-secondary break-words", children: p(m) })
] })
]
},
m.id
);
})
] }) }),
/* @__PURE__ */ o("div", { className: "px-6 py-4 border-t border-dc-border bg-dc-surface-secondary rounded-b-lg flex justify-end gap-3", children: [
/* @__PURE__ */ e(
"button",
{
onClick: h,
className: "px-4 py-2 text-sm font-medium rounded-md border border-dc-border bg-dc-surface hover:bg-dc-surface-hover transition-colors text-dc-text",
children: "Cancel"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: f,
className: "px-4 py-2 text-sm font-medium rounded-md text-white transition-colors",
style: {
backgroundColor: "var(--dc-primary)"
},
children: "Apply Filters"
}
)
] })
]
}
) }) : null;
}
const _c = Q("chevronDown"), Ir = Q("close"), $s = ({
fieldName: t,
operator: r,
values: n,
onValuesChange: s,
schema: a
}) => {
const c = ar[r], [l, u] = V(!1), [d, f] = V(""), [h, p] = V(!1), m = Ce(null), v = Ce(""), C = rs(d, 300), _ = ye(() => a ? a.cubes.some(
(q) => q.dimensions.some((I) => I.name === t)
) : !1, [a, t]), b = ye(() => a ? a.cubes.some(
(q) => q.dimensions.some((I) => I.name === t && I.type === "time")
) : !1, [a, t]), R = ye(
() => ["equals", "notEquals", "in", "notIn"].includes(r) && _ && !b,
[r, _, b]
), D = R, {
values: $,
loading: A,
error: w,
searchValues: i
} = ns(t, R);
ve(() => {
const q = (I) => {
m.current && !m.current.contains(I.target) && u(!1);
};
return document.addEventListener("mousedown", q), () => document.removeEventListener("mousedown", q);
}, []), ve(() => {
l && R && i && (i("", !0), p(!0), v.current = "");
}, [l, R, i]), ve(() => {
h && R && i && C !== v.current && (v.current = C, i(C));
}, [C, h, R, i]);
const g = F(() => {
const q = !l;
u(q), q || (f(""), v.current = "");
}, [l]), x = F((q) => {
const I = q.target.value;
f(I);
}, []), N = F((q) => {
c.supportsMultipleValues ? n.includes(q) || s([...n, q]) : (s([q]), u(!1)), f("");
}, [c.supportsMultipleValues, n, s]), S = F((q) => {
s(n.filter((I) => I !== q));
}, [n, s]), y = F((q) => {
const I = q.target.value;
if (c.valueType === "number") {
const K = parseFloat(I);
isNaN(K) ? (I === "" || I === "-") && s([]) : s([K]);
} else
s(I ? [I] : []);
}, [c.valueType, s]), M = F((q) => {
const I = q.target.value;
if (r === "inDateRange") {
const K = n.length >= 2 ? n : ["", ""];
s([I, K[1]]);
} else
s(I ? [I] : []);
}, [r, n, s]), E = F((q) => {
const I = q.target.value, K = n.length >= 2 ? n : ["", ""];
s([K[0], I]);
}, [n, s]), T = F((q) => {
const I = parseFloat(q.target.value), K = n.length >= 2 ? n : ["", ""], U = [isNaN(I) ? q.target.value === "" ? "" : K[0] : I, K[1]];
s(U.filter((ke) => ke !== ""));
}, [n, s]), j = F((q) => {
const I = parseFloat(q.target.value), K = n.length >= 2 ? n : ["", ""], U = [K[0], isNaN(I) ? q.target.value === "" ? "" : K[1] : I];
s(U.filter((ke) => ke !== ""));
}, [n, s]);
return c.requiresValues ? r === "inDateRange" ? /* @__PURE__ */ o("div", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "date",
value: n[0] || "",
onChange: M,
className: "text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ e(
"input",
{
type: "date",
value: n[1] || "",
onChange: E,
className: "text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
)
] }) : r === "between" || r === "notBetween" ? /* @__PURE__ */ o("div", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"input",
{
type: "number",
value: n[0] !== void 0 && n[0] !== null ? n[0] : "",
onChange: T,
placeholder: "Min",
className: "text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
),
/* @__PURE__ */ e("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ e(
"input",
{
type: "number",
value: n[1] !== void 0 && n[1] !== null ? n[1] : "",
onChange: j,
placeholder: "Max",
className: "text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
)
] }) : c.valueType === "date" ? /* @__PURE__ */ e(
"input",
{
type: "date",
value: n[0] || "",
onChange: M,
className: "text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
) : c.valueType === "number" ? /* @__PURE__ */ e(
"input",
{
type: "number",
value: n[0] !== void 0 && n[0] !== null ? n[0] : "",
onChange: y,
placeholder: "Enter number",
className: "text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
) : b && ["equals", "notEquals", "in", "notIn"].includes(r) ? c.supportsMultipleValues ? /* @__PURE__ */ o("div", { className: "space-y-2 min-w-0 max-w-full", children: [
n.length > 0 && /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1 max-w-full", children: n.map((q, I) => /* @__PURE__ */ o(
"div",
{
className: "inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension",
children: [
/* @__PURE__ */ e("span", { className: "mr-1", children: String(q) }),
/* @__PURE__ */ e(
"button",
{
onClick: () => S(q),
className: "text-dc-accent hover:text-dc-accent focus:outline-hidden",
children: /* @__PURE__ */ e(Ir, { className: "w-3 h-3" })
}
)
]
},
I
)) }),
/* @__PURE__ */ e(
"input",
{
type: "date",
onChange: (q) => {
q.target.value && !n.includes(q.target.value) && (s([...n, q.target.value]), q.target.value = "");
},
className: "text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent",
placeholder: "Add date..."
}
)
] }) : /* @__PURE__ */ e(
"input",
{
type: "date",
value: n[0] || "",
onChange: M,
className: "text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
) : D ? /* @__PURE__ */ o("div", { className: "relative min-w-0 max-w-full", ref: m, children: [
c.supportsMultipleValues && n.length > 0 && /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1 mb-2 max-w-full", children: n.map((q, I) => /* @__PURE__ */ o(
"div",
{
className: "inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension",
children: [
/* @__PURE__ */ e("span", { className: "mr-1", children: String(q) }),
/* @__PURE__ */ e(
"button",
{
onClick: () => S(q),
className: "text-dc-accent hover:text-dc-accent focus:outline-hidden",
children: /* @__PURE__ */ e(Ir, { className: "w-3 h-3" })
}
)
]
},
I
)) }),
!c.supportsMultipleValues && n.length > 0 && /* @__PURE__ */ e("div", { className: "mb-2", children: /* @__PURE__ */ o("div", { className: "inline-flex items-center bg-dc-time-dimension text-dc-time-dimension text-xs px-2 py-1 rounded-sm border border-dc-time-dimension", children: [
/* @__PURE__ */ e("span", { className: "mr-1", children: String(n[0]) }),
/* @__PURE__ */ e(
"button",
{
onClick: () => s([]),
className: "text-dc-accent hover:text-dc-accent focus:outline-hidden",
children: /* @__PURE__ */ e(Ir, { className: "w-3 h-3" })
}
)
] }) }),
/* @__PURE__ */ o(
"button",
{
onClick: g,
className: "w-full text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent flex items-center justify-between min-w-0",
children: [
/* @__PURE__ */ e("span", { className: "text-dc-text-muted truncate", children: A && !h ? "Loading values..." : "Select value..." }),
/* @__PURE__ */ e(_c, { className: "w-4 h-4 text-dc-text-muted" })
]
}
),
l && /* @__PURE__ */ o("div", { className: "absolute z-30 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto", children: [
/* @__PURE__ */ e("div", { className: "p-2 border-b border-dc-border", children: /* @__PURE__ */ e(
"input",
{
type: "text",
value: d,
onChange: x,
placeholder: "Search values...",
className: "w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent",
autoFocus: !0
}
) }),
/* @__PURE__ */ e("div", { className: "max-h-48 overflow-y-auto", children: A ? /* @__PURE__ */ e("div", { className: "p-2 text-sm text-dc-text-muted", children: d ? "Searching..." : "Loading values..." }) : w ? /* @__PURE__ */ o("div", { className: "p-2 text-sm text-dc-error", children: [
"Error loading values: ",
w
] }) : $.length === 0 ? /* @__PURE__ */ e("div", { className: "p-2 text-sm text-dc-text-muted", children: d ? "No matching values" : "No values available" }) : $.map((q, I) => {
const K = n.includes(q);
return /* @__PURE__ */ o(
"button",
{
onClick: () => N(q),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${K ? "bg-dc-accent-bg text-dc-accent" : "text-dc-text-secondary"}`,
children: [
String(q),
K && /* @__PURE__ */ e("span", { className: "float-right text-dc-accent", children: "✓" })
]
},
`${q}-${I}`
);
}) })
] })
] }) : /* @__PURE__ */ e(
"input",
{
type: "text",
value: n[0] !== void 0 && n[0] !== null ? n[0] : "",
onChange: y,
placeholder: `Enter ${c.valueType} value`,
className: "text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
) : /* @__PURE__ */ e("div", { className: "text-sm text-dc-text-muted italic", children: "No value required" });
};
function sr(t) {
return "member" in t && "operator" in t && "values" in t;
}
function or(t) {
return "type" in t && "filters" in t;
}
function Rc(t) {
return or(t) && t.type === "and";
}
function Mc(t) {
return or(t) && t.type === "or";
}
function Lr(t, r) {
const n = [];
if (t.cubes.forEach((c) => {
n.push(...c.measures), n.push(...c.dimensions);
}), !r)
return n.sort((c, l) => c.name.localeCompare(l.name));
const s = /* @__PURE__ */ new Set();
return r.measures && r.measures.forEach((c) => s.add(c)), r.dimensions && r.dimensions.forEach((c) => s.add(c)), r.timeDimensions && r.timeDimensions.forEach((c) => s.add(c.dimension)), n.filter((c) => s.has(c.name)).sort((c, l) => c.name.localeCompare(l.name));
}
function rn(t) {
const r = [];
return t.cubes.forEach((n) => {
r.push(...n.measures), r.push(...n.dimensions);
}), r.sort((n, s) => n.name.localeCompare(s.name));
}
function Oc(t, r) {
const n = rn(t);
if (!r)
return {
queryFields: [],
allFields: n
};
const s = /* @__PURE__ */ new Set();
return r.measures && r.measures.forEach((c) => s.add(c)), r.dimensions && r.dimensions.forEach((c) => s.add(c)), r.timeDimensions && r.timeDimensions.forEach((c) => s.add(c.dimension)), {
queryFields: n.filter((c) => s.has(c.name)),
allFields: n
};
}
function jn(t) {
const r = [];
for (const [n, s] of Object.entries(ar))
s.fieldTypes.includes(t) && r.push({
operator: n,
label: s.label
});
return r;
}
function $c(t, r) {
for (const n of r.cubes) {
const s = n.measures.find((c) => c.name === t);
if (s) return s.type;
const a = n.dimensions.find((c) => c.name === t);
if (a) return a.type;
}
return "string";
}
function Ic(t) {
let r = 0;
const n = (s) => {
sr(s) ? r++ : or(s) && s.filters.forEach(n);
};
return t.forEach(n), r;
}
function vr(t, r = "equals", n = []) {
return {
member: t,
operator: r,
values: n
};
}
function vt(t = []) {
return {
type: "and",
filters: t
};
}
function kt(t = []) {
return {
type: "or",
filters: t
};
}
function Rt(t, r) {
const n = {
today: "today",
yesterday: "yesterday",
this_week: "this week",
this_month: "this month",
this_quarter: "this quarter",
this_year: "this year",
last_7_days: "last 7 days",
last_30_days: "last 30 days",
last_week: "last week",
last_month: "last month",
last_quarter: "last quarter",
last_year: "last year",
last_12_months: "last 12 months"
};
if (t.startsWith("last_n_") && r !== void 0 && r > 0) {
const s = t.replace("last_n_", ""), a = s.slice(0, -1);
return r === 1 ? `last ${a}` : `last ${r} ${s}`;
}
return n[t] || t;
}
function qt(t) {
return t.startsWith("last_n_");
}
function Cr(t) {
return t.toISOString().split("T")[0];
}
const Ur = [
{ id: "today", label: "Today", value: "today" },
{ id: "yesterday", label: "Yesterday", value: "yesterday" },
{ id: "7d", label: "7D", value: "last 7 days" },
{ id: "30d", label: "30D", value: "last 30 days" },
{ id: "3m", label: "3M", value: "last 3 months" },
{ id: "6m", label: "6M", value: "last 6 months" },
{ id: "12m", label: "12M", value: "last 12 months" }
], nn = [
{ id: "wtd", label: "Week to Date", value: "this week" },
{ id: "mtd", label: "Month to Date", value: "this month" },
{ id: "qtd", label: "Quarter to Date", value: "this quarter" },
{ id: "ytd", label: "Year to Date", value: "this year" }
];
function sn(t) {
const r = /* @__PURE__ */ new Date();
r.setHours(0, 0, 0, 0);
const n = new Date(r);
switch (n.setHours(23, 59, 59, 999), t.toLowerCase()) {
case "today":
return { start: r, end: n };
case "yesterday": {
const s = new Date(r);
s.setDate(s.getDate() - 1);
const a = new Date(s);
return a.setHours(23, 59, 59, 999), { start: s, end: a };
}
case "this week": {
const s = new Date(r), a = s.getDay(), c = a === 0 ? 6 : a - 1;
return s.setDate(s.getDate() - c), { start: s, end: n };
}
case "this month":
return { start: new Date(r.getFullYear(), r.getMonth(), 1), end: n };
case "this quarter": {
const s = Math.floor(r.getMonth() / 3);
return { start: new Date(r.getFullYear(), s * 3, 1), end: n };
}
case "this year":
return { start: new Date(r.getFullYear(), 0, 1), end: n };
default: {
const s = t.match(/^last\s+(\d+)\s+(day|days|week|weeks|month|months|quarter|quarters|year|years)$/i);
if (s) {
const c = parseInt(s[1], 10), l = s[2].toLowerCase(), u = new Date(r);
return l === "day" || l === "days" ? u.setDate(u.getDate() - c + 1) : l === "week" || l === "weeks" ? u.setDate(u.getDate() - c * 7 + 1) : l === "month" || l === "months" ? (u.setMonth(u.getMonth() - c), u.setDate(u.getDate() + 1)) : l === "quarter" || l === "quarters" ? (u.setMonth(u.getMonth() - c * 3), u.setDate(u.getDate() + 1)) : (l === "year" || l === "years") && (u.setFullYear(u.getFullYear() - c), u.setDate(u.getDate() + 1)), { start: u, end: n };
}
const a = t.match(/^last\s+(week|month|quarter|year)$/i);
if (a) {
const c = a[1].toLowerCase();
if (c === "week") {
const l = new Date(r), u = l.getDay(), d = u === 0 ? 6 : u - 1;
l.setDate(l.getDate() - d - 1), l.setHours(23, 59, 59, 999);
const f = new Date(l);
return f.setDate(f.getDate() - 6), f.setHours(0, 0, 0, 0), { start: f, end: l };
} else if (c === "month") {
const l = new Date(r.getFullYear(), r.getMonth() - 1, 1), u = new Date(r.getFullYear(), r.getMonth(), 0);
return u.setHours(23, 59, 59, 999), { start: l, end: u };
} else if (c === "quarter") {
const l = Math.floor(r.getMonth() / 3), u = l === 0 ? 3 : l - 1, d = l === 0 ? r.getFullYear() - 1 : r.getFullYear(), f = new Date(d, u * 3, 1), h = new Date(d, u * 3 + 3, 0);
return h.setHours(23, 59, 59, 999), { start: f, end: h };
} else if (c === "year") {
const l = new Date(r.getFullYear() - 1, 0, 1), u = new Date(r.getFullYear() - 1, 11, 31);
return u.setHours(23, 59, 59, 999), { start: l, end: u };
}
}
return null;
}
}
}
function kr(t, r) {
const n = {
month: "short",
day: "numeric",
year: "numeric"
}, s = t.toLocaleDateString("en-US", n), a = r.toLocaleDateString("en-US", n);
if (s === a)
return s;
if (t.getFullYear() === r.getFullYear()) {
const c = { month: "short", day: "numeric" };
return `${t.toLocaleDateString("en-US", c)} - ${a}`;
}
return `${s} - ${a}`;
}
function Bn(t) {
if (!t) return null;
if (Array.isArray(t))
return "custom";
const r = t.toLowerCase().trim();
for (const s of Ur)
if (s.value.toLowerCase() === r)
return s.id;
for (const s of nn)
if (s.value.toLowerCase() === r)
return s.id;
return r.match(/^last\s+(\d+)\s+(day|days|week|weeks|month|months|quarter|quarters|year|years)$/i), "custom";
}
function Lc(t, r) {
if (!t || t.length === 0)
return r === "set" ? "is set" : r === "notSet" ? "is not set" : r === "isEmpty" ? "is empty" : r === "isNotEmpty" ? "is not empty" : "";
const n = t.map((s) => s === !0 ? "true" : s === !1 ? "false" : s == null ? "null" : String(s));
switch (r) {
case "equals":
return n.length === 1 ? `= ${n[0]}` : `in (${n.join(", ")})`;
case "notEquals":
return n.length === 1 ? `!= ${n[0]}` : `not in (${n.join(", ")})`;
case "contains":
return `contains "${n[0]}"`;
case "notContains":
return `!contains "${n[0]}"`;
case "startsWith":
return `starts with "${n[0]}"`;
case "endsWith":
return `ends with "${n[0]}"`;
case "gt":
return `> ${n[0]}`;
case "gte":
return `>= ${n[0]}`;
case "lt":
return `< ${n[0]}`;
case "lte":
return `<= ${n[0]}`;
case "between":
return `${n[0]} - ${n[1] || "?"}`;
case "in":
return `in (${n.join(", ")})`;
case "notIn":
return `not in (${n.join(", ")})`;
case "set":
return "is set";
case "notSet":
return "is not set";
default:
return n.join(", ");
}
}
function Is(t, r = "w-4 h-4") {
const n = Xt(t);
return /* @__PURE__ */ e(n, { className: r });
}
const Fc = Q("close"), qc = Q("filter"), Fr = Q("chevronDown"), Pc = Q("search"), jc = Q("dimension"), Bc = Q("timeDimension"), Ls = ({
filter: t,
index: r,
onFilterChange: n,
onFilterRemove: s,
schema: a,
query: c,
hideFieldSelector: l = !1,
hideOperatorSelector: u = !1,
hideRemoveButton: d = !1
}) => {
const [f, h] = V(!1), [p, m] = V(!1), [v, C] = V(!1), [_, b] = V(""), R = Ce(null), D = Ce(null), [$, A] = V("this_month"), [w, i] = V({
startDate: Cr(/* @__PURE__ */ new Date()),
endDate: Cr(/* @__PURE__ */ new Date())
}), [g, x] = V(1);
ve(() => {
const L = (te) => {
R.current && !R.current.contains(te.target) && (h(!1), m(!1));
};
return document.addEventListener("mousedown", L), () => document.removeEventListener("mousedown", L);
}, []);
const N = () => {
m(!1);
const L = !f;
h(L), b(""), L && setTimeout(() => D.current?.focus(), 50);
}, S = () => {
h(!1), m(!p);
}, y = a ? rn(a) : [], { queryFields: M } = a ? Oc(a, c) : { queryFields: [] }, E = y.find((L) => L.name === t.member), T = E ? E.type : "string", j = jn(T), q = T === "time" && t.operator === "inDateRange";
if (ve(() => {
if (!(!q || !t.dateRange))
if (Array.isArray(t.dateRange))
A("custom"), i({
startDate: t.dateRange[0] || "",
endDate: t.dateRange[1] || t.dateRange[0] || ""
});
else {
const L = t.dateRange.match(/^last (\d+) (days|weeks|months|quarters|years)$/);
if (L) {
const [, te, Ne] = L;
A(`last_n_${Ne === "days" ? "days" : Ne === "weeks" ? "weeks" : Ne === "months" ? "months" : Ne === "quarters" ? "quarters" : "years"}`), x(parseInt(te) || 1);
} else {
let te = !1;
for (const Ne of Mt)
if (Ne.value !== "custom" && !qt(Ne.value) && Rt(Ne.value) === t.dateRange) {
A(Ne.value), te = !0;
break;
}
te || A("custom");
}
}
}, [t.dateRange, q]), !a)
return /* @__PURE__ */ e("div", { className: "text-sm text-dc-text-muted", children: "Schema not loaded" });
const I = (L) => {
if (!_) return L;
const te = _.toLowerCase();
return L.filter(
(Ne) => Ne.name.toLowerCase().includes(te) || Ne.title.toLowerCase().includes(te) || Ne.shortTitle.toLowerCase().includes(te)
);
}, K = I(M), U = I(y), ke = (L) => L.type === "time" ? /* @__PURE__ */ e(Bc, { className: "w-3 h-3 text-dc-accent" }) : ["count", "sum", "avg", "min", "max", "countDistinct", "countDistinctApprox", "runningTotal", "calculated", "number"].includes(L.type) ? Is(L.type, "w-3 h-3 text-dc-warning") : /* @__PURE__ */ e(jc, { className: "w-3 h-3 text-dc-success" }), De = (L) => L.type === "time" ? /* @__PURE__ */ e("span", { className: "text-xs bg-dc-time-dimension text-dc-time-dimension px-1.5 py-0.5 rounded-sm", children: "T" }) : ["count", "sum", "avg", "min", "max", "countDistinct", "number"].includes(L.type) ? /* @__PURE__ */ e("span", { className: "text-xs bg-dc-measure text-dc-measure px-1.5 py-0.5 rounded-sm", children: "M" }) : /* @__PURE__ */ e("span", { className: "text-xs bg-dc-dimension text-dc-dimension px-1.5 py-0.5 rounded-sm", children: "D" }), Pe = (L) => {
const te = $c(L, a), Ve = jn(te)[0]?.operator || "equals";
n(r, {
member: L,
operator: Ve,
values: [],
dateRange: void 0
// Reset dateRange when field changes
}), h(!1);
}, B = (L) => {
n(r, {
...t,
operator: L,
values: [],
// Reset values when operator changes
dateRange: void 0
// Reset dateRange when operator changes
}), m(!1);
}, se = (L) => {
n(r, {
...t,
values: L
});
}, Te = (L) => {
n(r, {
...t,
dateRange: L
});
}, H = (L) => {
if (C(!1), L === "custom") {
if (w.startDate && w.endDate) {
const te = w.startDate === w.endDate ? w.startDate : [w.startDate, w.endDate];
Te(te);
}
} else if (qt(L)) {
const te = Rt(L, g);
Te(te);
} else {
const te = Rt(L);
Te(te);
}
A(L);
}, ee = (L, te) => {
const Ne = { ...w, [L]: te };
if (i(Ne), $ === "custom" && Ne.startDate) {
const Ve = !Ne.endDate || Ne.startDate === Ne.endDate ? Ne.startDate : [Ne.startDate, Ne.endDate];
Te(Ve);
}
}, le = (L) => {
if (x(L), qt($)) {
const te = Rt($, L);
Te(te);
}
}, be = Mt.find((L) => L.value === $)?.label || "Custom";
return /* @__PURE__ */ e("div", { ref: R, className: "bg-dc-surface border border-dc-border rounded-lg p-3", children: /* @__PURE__ */ o("div", { className: "flex flex-col sm:flex-row sm:items-center gap-3 min-w-0 max-w-full", children: [
!l && /* @__PURE__ */ o("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
/* @__PURE__ */ e(qc, { className: "w-4 h-4 text-dc-text-muted shrink-0" }),
/* @__PURE__ */ o("div", { className: "relative flex-1 min-w-0", children: [
/* @__PURE__ */ o(
"button",
{
onClick: N,
className: "w-full flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent min-w-0",
children: [
/* @__PURE__ */ e("span", { className: "truncate", children: E ? /* @__PURE__ */ e("span", { className: "font-medium", children: E.name }) : /* @__PURE__ */ e("span", { className: "text-dc-text-muted", children: "Select field..." }) }),
/* @__PURE__ */ e(Fr, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${f ? "transform rotate-180" : ""}` })
]
}
),
f && /* @__PURE__ */ o("div", { className: "absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-80 overflow-hidden", children: [
/* @__PURE__ */ e("div", { className: "p-2 border-b border-dc-border", children: /* @__PURE__ */ o("div", { className: "relative", children: [
/* @__PURE__ */ e(Pc, { className: "w-4 h-4 absolute left-2 top-1/2 transform -translate-y-1/2 text-dc-text-muted" }),
/* @__PURE__ */ e(
"input",
{
ref: D,
type: "text",
placeholder: "Search fields...",
value: _,
onChange: (L) => b(L.target.value),
className: "w-full pl-8 pr-3 py-1.5 text-sm border border-dc-border rounded-sm bg-dc-surface text-dc-text focus:ring-1 focus:ring-dc-accent focus:border-dc-accent"
}
)
] }) }),
/* @__PURE__ */ o("div", { className: "max-h-60 overflow-y-auto", children: [
K.length > 0 && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ o("div", { className: "px-3 py-1.5 text-xs font-medium text-dc-text-muted bg-dc-surface-secondary border-b border-dc-border", children: [
"Fields in Query (",
K.length,
")"
] }),
K.map((L) => /* @__PURE__ */ e(
"button",
{
onClick: () => Pe(L.name),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${L.name === t.member ? "bg-dc-accent-bg text-dc-accent" : "text-dc-text-secondary"}`,
children: /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
ke(L),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e("span", { className: "font-medium truncate", children: L.name }),
De(L)
] }),
L.title !== L.name && /* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: L.title })
] })
] })
},
`query-${L.name}`
))
] }),
/* @__PURE__ */ o("div", { children: [
K.length > 0 && /* @__PURE__ */ o("div", { className: "px-3 py-1.5 text-xs font-medium text-dc-text-muted bg-dc-surface-secondary border-b border-dc-border", children: [
"All Available Fields (",
U.length,
")"
] }),
U.map((L) => /* @__PURE__ */ e(
"button",
{
onClick: () => Pe(L.name),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${L.name === t.member ? "bg-dc-accent-bg text-dc-accent" : "text-dc-text-secondary"}`,
children: /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
ke(L),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e("span", { className: "font-medium truncate", children: L.name }),
De(L)
] }),
L.title !== L.name && /* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: L.title })
] })
] })
},
`all-${L.name}`
))
] }),
U.length === 0 && /* @__PURE__ */ o("div", { className: "px-3 py-4 text-sm text-dc-text-muted text-center", children: [
'No fields found matching "',
_,
'"'
] })
] })
] })
] })
] }),
E && /* @__PURE__ */ o("div", { className: "flex items-center gap-2 flex-1 sm:flex-initial min-w-0", children: [
!u && /* @__PURE__ */ o("div", { className: "relative shrink-0", children: [
/* @__PURE__ */ o(
"button",
{
onClick: S,
className: "w-full sm:w-32 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent",
children: [
/* @__PURE__ */ e("span", { className: "truncate", children: j.find((L) => L.operator === t.operator)?.label || t.operator }),
/* @__PURE__ */ e(Fr, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${p ? "transform rotate-180" : ""}` })
]
}
),
p && /* @__PURE__ */ e("div", { className: "absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto", children: j.map((L) => /* @__PURE__ */ e(
"button",
{
onClick: () => B(L.operator),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${L.operator === t.operator ? "bg-dc-accent-bg text-dc-accent" : "text-dc-text-secondary"}`,
children: L.label
},
L.operator
)) })
] }),
/* @__PURE__ */ e("div", { className: "flex-1 min-w-0", children: q ? (
/* Date Range Selector for time dimensions with inDateRange */
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ o("div", { className: "relative shrink-0", children: [
/* @__PURE__ */ o(
"button",
{
onClick: () => {
m(!1), C(!v);
},
className: "w-full sm:w-40 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent",
children: [
/* @__PURE__ */ e("span", { className: "truncate", children: be }),
/* @__PURE__ */ e(Fr, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${v ? "transform rotate-180" : ""}` })
]
}
),
v && /* @__PURE__ */ e("div", { className: "absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto", children: Mt.map((L) => /* @__PURE__ */ e(
"button",
{
onClick: () => H(L.value),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-none focus:bg-dc-surface-hover ${L.value === $ ? "bg-dc-accent-bg text-dc-accent" : "text-dc-text-secondary"}`,
children: L.label
},
L.value
)) })
] }),
$ === "custom" ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"input",
{
type: "date",
value: w.startDate,
onChange: (L) => ee("startDate", L.target.value),
placeholder: "Start date",
className: "flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
),
/* @__PURE__ */ e(
"input",
{
type: "date",
value: w.endDate,
onChange: (L) => ee("endDate", L.target.value),
placeholder: "End date",
className: "flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
)
] }) : qt($) ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"input",
{
type: "number",
min: "1",
max: "1000",
value: g,
onChange: (L) => le(Math.max(1, parseInt(L.target.value) || 1)),
placeholder: "Number",
className: "flex-1 min-w-0 text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
),
/* @__PURE__ */ e("div", { className: "shrink-0 text-sm text-dc-text-secondary", children: $.replace("last_n_", "").replace("_", " ") })
] }) : null
] })
) : (
/* Regular FilterValueSelector for non-dateRange filters */
/* @__PURE__ */ e(
$s,
{
fieldName: t.member,
operator: t.operator,
values: t.values,
onValuesChange: se,
schema: a
}
)
) })
] }),
!d && /* @__PURE__ */ e("div", { className: "flex justify-end sm:justify-start", children: /* @__PURE__ */ e(
"button",
{
onClick: () => s(r),
className: "text-dc-text-muted hover:text-dc-error focus:outline-none shrink-0",
title: "Remove filter",
children: /* @__PURE__ */ e(Fc, { className: "w-4 h-4" })
}
) })
] }) });
}, Vc = Q("close"), Qc = Q("add"), Fs = ({
group: t,
index: r,
onGroupChange: n,
onGroupChangeWithUnwrap: s,
onGroupRemove: a,
schema: c,
query: l,
depth: u = 0
}) => {
const [d, f] = V(!1), h = t.type === "and", p = h ? "AND" : "OR", m = t.filters, v = u > 0 ? `ml-${Math.min(u * 4, 16)}` : "", C = "border-dc-border", _ = "bg-dc-bg-secondary", b = "text-dc-text-secondary", R = () => {
if (h) {
const N = kt(m);
n(r, N);
} else {
const N = vt(m);
n(r, N);
}
}, D = () => {
if (!c) return;
const S = Lr(c, l)[0]?.name || "", y = vr(S, "equals", []), M = [...m, y];
h ? n(r, vt(M)) : n(r, kt(M)), f(!1);
}, $ = () => {
if (!c) return;
const S = Lr(c, l)[0]?.name || "", y = vt([vr(S, "equals", [])]), M = [...m, y];
h ? n(r, vt(M)) : n(r, kt(M)), f(!1);
}, A = () => {
if (!c) return;
const S = Lr(c, l)[0]?.name || "", y = kt([vr(S, "equals", [])]), M = [...m, y];
h ? n(r, vt(M)) : n(r, kt(M)), f(!1);
}, w = (N, S) => {
const y = [...m];
y[N] = S, h ? n(r, vt(y)) : n(r, kt(y));
}, i = (N) => {
const S = m.filter((M, E) => E !== N);
if (S.length === 0) {
a(r);
return;
}
if (S.length === 1) {
const M = t.type === "and" ? vt(S) : kt(S);
s ? s(r, M) : n(r, M);
return;
}
const y = t.type === "and" ? vt(S) : kt(S);
n(r, y);
}, g = (N, S) => {
const y = [...m];
y[N] = S, h ? n(r, vt(y)) : n(r, kt(y));
}, x = (N) => {
i(N);
};
return /* @__PURE__ */ o("div", { className: `${v} ${C} border-2 ${_} rounded-lg py-3 pr-3 pl-2 space-y-3`, children: [
/* @__PURE__ */ o("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ o("div", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ e(
"button",
{
onClick: R,
className: `px-3 py-1 rounded-sm text-sm font-semibold ${b} border border-current hover:bg-dc-surface hover:bg-opacity-20 focus:outline-hidden focus:ring-2 focus:ring-current focus:ring-opacity-50`,
children: p
}
),
/* @__PURE__ */ o("span", { className: "text-sm text-dc-text-secondary", children: [
m.length,
" condition",
m.length !== 1 ? "s" : ""
] })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ o("div", { className: "relative", children: [
/* @__PURE__ */ e(
"button",
{
onClick: () => f(!d),
className: "text-dc-text-muted hover:text-dc-text-secondary focus:outline-hidden",
title: "Add condition",
children: /* @__PURE__ */ e(Qc, { className: "w-4 h-4" })
}
),
d && /* @__PURE__ */ o("div", { className: "absolute right-0 mt-1 w-48 bg-dc-surface border border-dc-border rounded-md shadow-lg z-30", children: [
/* @__PURE__ */ e(
"button",
{
onClick: D,
className: "w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover",
children: "Add Filter"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: $,
className: "w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover",
children: "Add AND Group"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: A,
className: "w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover",
children: "Add OR Group"
}
)
] })
] }),
/* @__PURE__ */ e(
"button",
{
onClick: () => a(r),
className: "text-dc-text-muted hover:text-dc-error focus:outline-hidden",
title: "Remove group",
children: /* @__PURE__ */ e(Vc, { className: "w-4 h-4" })
}
)
] })
] }),
/* @__PURE__ */ o("div", { className: "space-y-3", children: [
m.map((N, S) => sr(N) ? /* @__PURE__ */ e(
Ls,
{
filter: N,
index: S,
onFilterChange: w,
onFilterRemove: i,
schema: c,
query: l
},
S
) : or(N) ? /* @__PURE__ */ e(
Fs,
{
group: N,
index: S,
onGroupChange: g,
onGroupRemove: x,
schema: c,
query: l,
depth: u + 1
},
S
) : null),
m.length === 0 && /* @__PURE__ */ o("div", { className: "text-center py-4 text-dc-text-muted text-sm", children: [
"No conditions in this group.",
/* @__PURE__ */ e(
"button",
{
onClick: D,
className: "ml-2 text-dc-accent hover:text-dc-accent focus:outline-hidden underline",
children: "Add a filter"
}
)
] })
] })
] });
}, Uc = Q("add"), Hc = Q("filter"), zc = ({
filters: t,
schema: r,
query: n,
onFiltersChange: s,
hideFieldSelector: a = !1
}) => {
const c = Ic(t), l = r ? rn(r) : [], u = l.length > 0, d = () => {
if (!u) return;
const _ = l[0]?.name || "", b = vr(_, "equals", []);
if (t.length === 0)
s([b]);
else if (t.length === 1 && sr(t[0])) {
const R = vt([t[0], b]);
s([R]);
} else if (t.length === 1 && Rc(t[0])) {
const R = t[0], D = vt([...R.filters, b]);
s([D]);
} else if (t.length === 1 && Mc(t[0])) {
const R = t[0], D = kt([...R.filters, b]);
s([D]);
} else
s([...t, b]);
}, f = (_, b) => {
const R = [...t];
R[_] = b, s(R);
}, h = (_) => {
const b = t.filter((R, D) => D !== _);
s(b);
}, p = (_, b) => {
const R = [...t];
R[_] = b, s(R);
}, m = (_, b) => {
const R = [...t];
b.filters.length === 1 && sr(b.filters[0]) ? R[_] = b.filters[0] : R[_] = b, s(R);
}, v = () => {
s([]);
}, C = () => {
s([]);
};
return /* @__PURE__ */ o("div", { className: "space-y-4 bg-dc-surface-secondary rounded-lg p-4", children: [
!a && /* @__PURE__ */ o("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ o("div", { className: "flex items-center", children: [
/* @__PURE__ */ e(Hc, { className: "w-4 h-4 text-dc-text-muted mr-2" }),
/* @__PURE__ */ o("h4", { className: "text-sm font-semibold text-dc-text-secondary", children: [
"Filters (",
c,
")"
] })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center space-x-2", children: [
t.length > 0 && /* @__PURE__ */ e(
"button",
{
onClick: C,
className: "text-xs text-dc-text-muted hover:text-dc-error focus:outline-hidden underline",
children: "Clear all"
}
),
/* @__PURE__ */ o(
"button",
{
onClick: d,
disabled: !u,
className: `flex items-center space-x-1 px-2 py-1 text-xs font-medium rounded focus:outline-hidden focus:ring-2 ${u ? "text-dc-accent bg-dc-accent-bg border border-dc-accent hover:bg-dc-accent-bg focus:ring-dc-accent" : "text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-not-allowed"}`,
children: [
/* @__PURE__ */ e(Uc, { className: "w-3 h-3" }),
/* @__PURE__ */ e("span", { children: "Add Filter" })
]
}
)
] })
] }),
t.length > 0 && /* @__PURE__ */ e("div", { className: "space-y-3", children: t.map((_, b) => sr(_) ? /* @__PURE__ */ e(
Ls,
{
filter: _,
index: b,
onFilterChange: f,
onFilterRemove: h,
schema: r,
query: n,
hideFieldSelector: a,
hideRemoveButton: a
},
b
) : or(_) ? /* @__PURE__ */ e(
Fs,
{
group: _,
index: b,
onGroupChange: p,
onGroupChangeWithUnwrap: m,
onGroupRemove: v,
schema: r,
query: n,
depth: 0
},
b
) : null) })
] });
}, Gc = Q("close"), Wc = Q("timeDimension"), Vn = Q("chevronDown"), Yc = ({
timeDimension: t,
availableTimeDimensions: r,
currentDateRange: n,
onDateRangeChange: s,
onTimeDimensionChange: a,
onRemove: c,
hideFieldSelector: l = !1,
hideRemoveButton: u = !1
}) => {
const d = () => {
if (!n) return "this_month";
if (Array.isArray(n))
return "custom";
const E = n.match(/^last (\d+) (days|weeks|months|quarters|years)$/);
if (E) {
const [, , T] = E;
return `last_n_${T === "days" ? "days" : T === "weeks" ? "weeks" : T === "months" ? "months" : T === "quarters" ? "quarters" : "years"}`;
}
for (const T of Mt)
if (T.value !== "custom" && !qt(T.value) && Rt(T.value) === n)
return T.value;
return "custom";
}, f = () => {
if (Array.isArray(n) && n.length >= 1)
return {
startDate: n[0] || "",
endDate: n[1] || n[0] || ""
};
const E = Cr(/* @__PURE__ */ new Date());
return { startDate: E, endDate: E };
}, h = () => {
if (!n || Array.isArray(n)) return 1;
const E = n.match(/^last (\d+) (days|weeks|months|quarters|years)$/);
return E && parseInt(E[1]) || 1;
}, [p, m] = V(d()), [v, C] = V(f()), [_, b] = V(h()), [R, D] = V(!1), [$, A] = V(!1), w = Ce(null);
ve(() => {
const E = (T) => {
w.current && !w.current.contains(T.target) && (D(!1), A(!1));
};
return document.addEventListener("mousedown", E), () => document.removeEventListener("mousedown", E);
}, []);
const i = () => {
D(!1), A(!$);
}, g = () => {
A(!1), D(!R);
}, x = (E) => {
if (m(E), D(!1), E === "custom") {
if (v.startDate && v.endDate) {
const T = v.startDate === v.endDate ? v.startDate : [v.startDate, v.endDate];
s(t, T);
}
} else if (qt(E)) {
const T = Rt(E, _);
s(t, T);
} else {
const T = Rt(E);
s(t, T);
}
}, N = (E, T) => {
const j = { ...v, [E]: T };
if (C(j), p === "custom" && j.startDate) {
const q = !j.endDate || j.startDate === j.endDate ? j.startDate : [j.startDate, j.endDate];
s(t, q);
}
}, S = (E) => {
if (b(E), qt(p)) {
const T = Rt(p, E);
s(t, T);
}
}, y = (E) => {
A(!1), a(t, E);
}, M = Mt.find((E) => E.value === p)?.label || "Custom";
return /* @__PURE__ */ e("div", { ref: w, className: "bg-dc-surface border border-dc-border rounded-lg p-3", children: /* @__PURE__ */ o("div", { className: "flex flex-col sm:flex-row sm:items-center gap-3 min-w-0", children: [
!l && /* @__PURE__ */ o("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
/* @__PURE__ */ e(Wc, { className: "w-4 h-4 text-dc-text-muted shrink-0" }),
/* @__PURE__ */ o("div", { className: "relative flex-1 min-w-0", children: [
/* @__PURE__ */ o(
"button",
{
onClick: i,
className: "w-full flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent min-w-0",
children: [
/* @__PURE__ */ e("span", { className: "truncate", children: t }),
/* @__PURE__ */ e(Vn, { className: `w-4 h-4 text-dc-text-muted shrink-0 transition-transform ${$ ? "transform rotate-180" : ""}` })
]
}
),
$ && /* @__PURE__ */ e("div", { className: "absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto", children: r.map((E) => /* @__PURE__ */ e(
"button",
{
onClick: () => y(E),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${E === t ? "bg-dc-accent-bg dark:bg-dc-accent-bg text-dc-accent dark:text-dc-accent" : "text-dc-text-secondary"}`,
children: E
},
E
)) })
] })
] }),
/* @__PURE__ */ e("div", { className: "flex items-center gap-2 flex-1 sm:flex-initial min-w-0", children: /* @__PURE__ */ o("div", { className: "relative shrink-0", children: [
/* @__PURE__ */ o(
"button",
{
onClick: g,
className: "w-full sm:w-40 flex items-center justify-between text-left text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent",
children: [
/* @__PURE__ */ e("span", { className: "truncate", children: M }),
/* @__PURE__ */ e(Vn, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-1 transition-transform ${R ? "transform rotate-180" : ""}` })
]
}
),
R && /* @__PURE__ */ e("div", { className: "absolute z-20 left-0 right-0 mt-1 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-60 overflow-y-auto", children: Mt.map((E) => /* @__PURE__ */ e(
"button",
{
onClick: () => x(E.value),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${E.value === p ? "bg-dc-accent-bg dark:bg-dc-accent-bg text-dc-accent dark:text-dc-accent" : "text-dc-text-secondary"}`,
children: E.label
},
E.value
)) })
] }) }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
p === "custom" ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ e(
"input",
{
type: "date",
value: v.startDate,
onChange: (E) => N("startDate", E.target.value),
placeholder: "dd/mm/yyyy",
className: "w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
) }),
/* @__PURE__ */ e("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ e(
"input",
{
type: "date",
value: v.endDate,
onChange: (E) => N("endDate", E.target.value),
placeholder: "dd/mm/yyyy",
className: "w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
) })
] }) : qt(p) ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ e(
"input",
{
type: "number",
min: "1",
max: "1000",
value: _,
onChange: (E) => S(Math.max(1, parseInt(E.target.value) || 1)),
placeholder: "Number",
className: "w-full text-sm border border-dc-border rounded-sm px-2 py-1 bg-dc-surface text-dc-text hover:bg-dc-surface-hover focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
) }),
/* @__PURE__ */ e("div", { className: "shrink-0 text-sm text-dc-text-secondary", children: p.replace("last_n_", "").replace("_", " ") })
] }) : (
// Empty placeholder to maintain layout consistency
/* @__PURE__ */ e("div", { className: "flex-1" })
),
!u && /* @__PURE__ */ e(
"button",
{
onClick: () => c(t),
className: "text-dc-text-muted hover:text-dc-error focus:outline-hidden shrink-0 p-1",
title: "Remove date range",
children: /* @__PURE__ */ e(Gc, { className: "w-4 h-4" })
}
)
] })
] }) });
}, Jc = Ws(
() => import("./index-9x0R-Fme.js").then((t) => ({ default: t.CubeRelationshipDiagram }))
), Kc = ({
schema: t,
schemaStatus: r,
schemaError: n,
selectedFields: s,
onFieldSelect: a,
onFieldDeselect: c,
onRetrySchema: l,
onOpenSettings: u,
onViewTypeChange: d,
isExpanded: f = !1
}) => {
const h = Q("chevronDown"), p = Q("chevronRight"), m = Q("warning"), v = Q("refresh"), C = Q("settings"), _ = Q("measure"), b = Q("dimension"), R = Q("timeDimension"), D = Q("segment"), $ = Q("menu"), { features: A } = Qt(), w = A?.showSchemaDiagram === !0, [i, g] = V(/* @__PURE__ */ new Set()), [x, N] = V(/* @__PURE__ */ new Set()), [S, y] = V(""), [M, E] = V("tree"), [T, j] = V(null), [q, I] = V(null);
if (wt.useEffect(() => {
f && w && E("diagram");
}, [f, w]), wt.useEffect(() => {
if (!t)
return;
if (S.trim().length > 0) {
T === null && (j(new Set(i)), I(new Set(x)));
const ee = /* @__PURE__ */ new Set(), le = /* @__PURE__ */ new Set();
t.cubes.forEach((te) => {
let Ne = !1;
te.measures.filter(
(G) => G.name.toLowerCase().includes(S.toLowerCase()) || G.title.toLowerCase().includes(S.toLowerCase())
).length > 0 && (Ne = !0, le.add(`${te.name}-measures`)), te.dimensions.filter((G) => G.type !== "time").filter(
(G) => G.name.toLowerCase().includes(S.toLowerCase()) || G.title.toLowerCase().includes(S.toLowerCase())
).length > 0 && (Ne = !0, le.add(`${te.name}-dimensions`)), te.dimensions.filter((G) => G.type === "time").filter(
(G) => G.name.toLowerCase().includes(S.toLowerCase()) || G.title.toLowerCase().includes(S.toLowerCase())
).length > 0 && (Ne = !0, le.add(`${te.name}-timeDimensions`)), Ne && ee.add(te.name);
});
const be = /* @__PURE__ */ new Set([...T || [], ...ee]), L = /* @__PURE__ */ new Set([...q || [], ...le]);
g(be), N(L);
} else
T !== null && q !== null && (g(T), N(q), j(null), I(null));
}, [t, S, T, q]), r === "loading")
return /* @__PURE__ */ e("div", { className: "h-full flex items-center justify-center text-dc-text-muted", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 mx-auto mb-3", style: { borderBottomColor: "var(--dc-primary)" } }),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold mb-1", children: "Loading Schema..." }),
/* @__PURE__ */ e("div", { className: "text-xs", children: "Fetching cube metadata" })
] }) });
if (r === "error") {
const H = n?.toLowerCase().includes("cors") || n?.toLowerCase().includes("fetch");
return /* @__PURE__ */ e("div", { className: "h-full flex items-center justify-center", children: /* @__PURE__ */ o("div", { className: "text-center max-w-sm p-6", children: [
/* @__PURE__ */ e(m, { className: "w-12 h-12 mx-auto text-dc-error mb-4" }),
/* @__PURE__ */ e("div", { className: "text-sm font-semibold text-dc-text mb-2", children: "Failed to Load Schema" }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-secondary mb-4", children: H ? /* @__PURE__ */ e(Oe, { children: "CORS error detected. The API endpoint may be incorrect or not accessible." }) : /* @__PURE__ */ e(Oe, { children: n || "Unable to connect to the Cube.js API" }) }),
/* @__PURE__ */ o("div", { className: "space-y-2", children: [
l && /* @__PURE__ */ o(
"button",
{
onClick: l,
className: "w-full flex items-center justify-center space-x-2 px-3 py-2 text-sm font-medium text-dc-accent bg-dc-accent-bg border border-dc-accent rounded-md hover:bg-dc-accent-bg focus:outline-hidden focus:ring-2 focus:ring-dc-accent",
children: [
/* @__PURE__ */ e(v, { className: "w-4 h-4" }),
/* @__PURE__ */ e("span", { children: "Retry" })
]
}
),
u && /* @__PURE__ */ o(
"button",
{
onClick: u,
className: "w-full flex items-center justify-center space-x-2 px-3 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover focus:outline-hidden focus:ring-2 focus:ring-dc-accent",
children: [
/* @__PURE__ */ e(C, { className: "w-4 h-4" }),
/* @__PURE__ */ e("span", { children: "Check API Settings" })
]
}
)
] }),
H && /* @__PURE__ */ e("div", { className: "mt-4 p-3 bg-dc-warning-bg border border-dc-warning rounded-md", children: /* @__PURE__ */ o("div", { className: "text-xs text-dc-warning", children: [
/* @__PURE__ */ e("div", { className: "font-medium mb-1", children: "Common solutions:" }),
/* @__PURE__ */ o("ul", { className: "list-disc list-inside space-y-1", children: [
/* @__PURE__ */ e("li", { children: "Verify the Base API URL is correct" }),
/* @__PURE__ */ e("li", { children: "Ensure the server supports CORS" }),
/* @__PURE__ */ e("li", { children: "Check if authentication is required" })
] })
] }) })
] }) });
}
if (!t)
return /* @__PURE__ */ e("div", { className: "h-full flex items-center justify-center text-dc-text-muted", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e("div", { className: "text-sm font-semibold mb-1", children: "No Schema" }),
/* @__PURE__ */ e("div", { className: "text-xs", children: "Schema not loaded" })
] }) });
const K = (H) => {
const ee = new Set(i);
if (ee.has(H) ? ee.delete(H) : ee.add(H), g(ee), T !== null) {
const le = new Set(T);
le.has(H) ? le.delete(H) : le.add(H), j(le);
}
}, U = (H) => {
const ee = new Set(x);
if (ee.has(H) ? ee.delete(H) : ee.add(H), N(ee), q !== null) {
const le = new Set(q);
le.has(H) ? le.delete(H) : le.add(H), I(le);
}
}, ke = (H, ee) => {
(() => {
switch (ee) {
case "measures":
return s.measures.includes(H.name);
case "dimensions":
return s.dimensions.includes(H.name);
case "timeDimensions":
return s.timeDimensions.includes(H.name);
default:
return !1;
}
})() ? c(H.name, ee) : a(H.name, ee);
}, De = (H) => S ? H.filter(
(ee) => ee.name.toLowerCase().includes(S.toLowerCase()) || ee.title.toLowerCase().includes(S.toLowerCase())
) : H, Pe = (H) => {
if (!S.trim()) return !0;
const ee = H.measures.some(
(be) => be.name.toLowerCase().includes(S.toLowerCase()) || be.title.toLowerCase().includes(S.toLowerCase())
), le = H.dimensions.some(
(be) => be.name.toLowerCase().includes(S.toLowerCase()) || be.title.toLowerCase().includes(S.toLowerCase())
);
return ee || le;
}, B = ({ field: H, fieldType: ee, icon: le }) => {
const be = (() => {
switch (ee) {
case "measures":
return s.measures.includes(H.name);
case "dimensions":
return s.dimensions.includes(H.name);
case "timeDimensions":
return s.timeDimensions.includes(H.name);
default:
return !1;
}
})(), L = () => {
if (!be) return "hover:bg-dc-surface-hover text-dc-text-secondary";
switch (ee) {
case "measures":
return "bg-dc-warning-bg text-dc-warning border border-dc-warning";
case "dimensions":
return "bg-dc-success-bg text-dc-success border border-dc-success";
case "timeDimensions":
return "bg-dc-accent-bg text-dc-accent border border-dc-accent";
default:
return "bg-dc-accent-bg text-dc-accent border border-dc-accent";
}
}, te = () => {
if (!be) return "text-dc-text-muted";
switch (ee) {
case "measures":
return "text-dc-warning";
case "dimensions":
return "text-dc-success";
case "timeDimensions":
return "text-dc-accent";
default:
return "text-dc-accent";
}
}, Ne = () => {
switch (ee) {
case "measures":
return "text-dc-warning";
case "dimensions":
return "text-dc-success";
case "timeDimensions":
return "text-dc-accent";
default:
return "text-dc-accent";
}
};
return /* @__PURE__ */ o(
"div",
{
className: `flex items-center px-2 py-1.5 text-xs cursor-pointer rounded-md transition-colors ${L()}`,
onClick: () => ke(H, ee),
title: H.description || H.title,
children: [
/* @__PURE__ */ e("div", { className: `mr-1.5 ${te()}`, children: wt.cloneElement(le, { className: "w-4 h-4" }) }),
/* @__PURE__ */ o("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ e("div", { className: "font-medium truncate text-xs", children: H.shortTitle }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted truncate", children: H.name })
] }),
be && /* @__PURE__ */ e("div", { className: `ml-1.5 ${Ne()}`, children: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ e("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }) })
]
}
);
}, se = ({ title: H, count: ee, sectionKey: le, icon: be }) => {
const L = x.has(le), te = () => le.includes("-dimensions") && !le.includes("-timeDimensions") ? "dimensions" : le.includes("-timeDimensions") ? "timeDimensions" : "measures";
return /* @__PURE__ */ o(
"div",
{
className: `flex items-center px-2 py-1 text-sm font-semibold cursor-pointer hover:bg-dc-surface-hover rounded-md ${(() => {
switch (te()) {
case "dimensions":
return "text-dc-success";
case "timeDimensions":
return "text-dc-accent";
case "measures":
return "text-dc-warning";
default:
return "text-dc-text-secondary";
}
})()}`,
onClick: () => U(le),
children: [
/* @__PURE__ */ e("div", { className: "mr-1.5", children: L ? /* @__PURE__ */ e(h, { className: "w-3 h-3" }) : /* @__PURE__ */ e(p, { className: "w-3 h-3" }) }),
/* @__PURE__ */ e("div", { className: "mr-1.5", children: be }),
/* @__PURE__ */ e("span", { className: "flex-1", children: H }),
/* @__PURE__ */ e("span", { className: "text-xs text-dc-text-muted bg-dc-surface-secondary px-1.5 py-0.5 rounded-full", children: ee })
]
}
);
}, Te = () => /* @__PURE__ */ e("div", { className: "flex items-center justify-center py-8 text-center", children: /* @__PURE__ */ o("div", { className: "max-w-sm", children: [
/* @__PURE__ */ e("div", { className: "text-dc-text-muted mb-2", children: /* @__PURE__ */ e("svg", { className: "w-12 h-12 mx-auto", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) }),
/* @__PURE__ */ e("div", { className: "text-sm font-medium text-dc-text mb-1", children: "No matches found" }),
/* @__PURE__ */ o("div", { className: "text-xs text-dc-text-muted mb-3", children: [
'No fields match your search term "',
S,
'"'
] }),
/* @__PURE__ */ e(
"button",
{
onClick: () => y(""),
className: "inline-flex items-center px-3 py-1.5 text-xs font-medium text-dc-accent bg-dc-accent-bg border border-dc-accent rounded-md hover:bg-dc-accent-bg focus:outline-hidden focus:ring-2 focus:ring-dc-accent",
children: "Clear search"
}
)
] }) });
return /* @__PURE__ */ o("div", { className: "flex-1 flex flex-col bg-dc-surface border border-dc-border rounded-lg min-h-0", children: [
/* @__PURE__ */ e("div", { className: "border-b border-dc-border", children: /* @__PURE__ */ o("div", { className: "p-3 pb-0", children: [
/* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-3", children: [
/* @__PURE__ */ e("div", { children: /* @__PURE__ */ e("h3", { className: "text-base font-semibold text-dc-text", children: M === "diagram" ? "Schema Diagram" : "Schema Explorer" }) }),
/* @__PURE__ */ e("div", { className: "flex items-center space-x-2", children: u && /* @__PURE__ */ e(
"button",
{
onClick: u,
className: "p-1 text-dc-text-muted hover:text-dc-text-secondary transition-colors",
title: "Open settings",
children: /* @__PURE__ */ e(C, { className: "w-4 h-4" })
}
) })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-3 mb-3", children: [
w ? /* @__PURE__ */ o("div", { className: "flex space-x-1 bg-dc-surface-secondary p-1 rounded-md", children: [
/* @__PURE__ */ o(
"button",
{
onClick: () => {
E("tree"), d?.("tree");
},
className: `
flex items-center px-3 py-1.5 rounded text-xs font-medium transition-colors
${M === "tree" ? "bg-dc-surface text-dc-text shadow-xs" : "text-dc-text-secondary hover:text-dc-text"}
`,
children: [
/* @__PURE__ */ e($, { className: "w-3 h-3 mr-1.5" }),
"Fields"
]
}
),
/* @__PURE__ */ o(
"button",
{
onClick: () => {
E("diagram"), d?.("diagram");
},
className: `
flex items-center px-3 py-1.5 rounded text-xs font-medium transition-colors
${M === "diagram" ? "bg-dc-surface text-dc-text shadow-xs" : "text-dc-text-secondary hover:text-dc-text"}
`,
children: [
/* @__PURE__ */ e(D, { className: "w-3 h-3 mr-1.5" }),
"Schema"
]
}
)
] }) : null,
/* @__PURE__ */ o("div", { className: "flex-1 relative min-w-0", children: [
/* @__PURE__ */ e(
"input",
{
type: "text",
placeholder: "Search fields...",
value: S,
onChange: (H) => y(H.target.value),
className: "w-full px-2 py-1.5 border border-dc-border rounded-md text-sm bg-dc-surface text-dc-text focus:ring-2 focus:ring-dc-accent focus:border-dc-accent"
}
),
/* @__PURE__ */ e("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none", children: /* @__PURE__ */ e("svg", { className: "h-4 w-4 text-dc-text-muted", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) })
] })
] })
] }) }),
/* @__PURE__ */ e("div", { className: "flex-1 min-h-0 overflow-hidden", children: M === "diagram" && w ? (
/* Diagram View - schema relationship diagram (only when enabled) */
/* @__PURE__ */ e("div", { className: "h-full", children: /* @__PURE__ */ e(Gs, { fallback: /* @__PURE__ */ e("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ e("div", { className: "animate-pulse text-dc-text-muted", children: "Loading diagram..." }) }), children: /* @__PURE__ */ e(
Jc,
{
className: "h-full",
onCubeClick: (H) => {
f || (g((ee) => /* @__PURE__ */ new Set([...ee, H])), E("tree"));
},
onFieldClick: (H, ee, le) => {
let be;
le === "measure" ? be = "measures" : be = t?.cubes.find((rt) => rt.name === H)?.dimensions.find(
(rt) => rt.name === `${H}.${ee}` || rt.name === ee
)?.type === "time" ? "timeDimensions" : "dimensions";
const L = `${H}.${ee}`;
s[be].includes(L) ? c(L, be) : a(L, be);
},
highlightedCubes: [
...s.measures.map((H) => H.split(".")[0]),
...s.dimensions.map((H) => H.split(".")[0]),
...s.timeDimensions.map((H) => H.split(".")[0])
].filter((H, ee, le) => le.indexOf(H) === ee),
highlightedFields: [
...s.measures,
...s.dimensions,
...s.timeDimensions
],
searchTerm: S
}
) }) })
) : (
/* Tree View - existing field list */
/* @__PURE__ */ e("div", { className: "h-full p-3 space-y-2 overflow-y-auto", children: (() => {
const H = t.cubes.filter(Pe);
return S.trim() && H.length === 0 ? /* @__PURE__ */ e(Te, {}) : H.map((ee) => {
const le = i.has(ee.name), be = ee.dimensions.filter((te) => te.type === "time"), L = ee.dimensions.filter((te) => te.type !== "time");
return /* @__PURE__ */ o("div", { className: "border border-dc-border rounded-lg", children: [
/* @__PURE__ */ o(
"div",
{
className: "flex items-center px-3 py-2 cursor-pointer hover:bg-dc-surface-hover rounded-t-lg",
onClick: () => K(ee.name),
children: [
/* @__PURE__ */ e("div", { className: "mr-2", children: le ? /* @__PURE__ */ e(h, { className: "w-4 h-4 text-dc-text-secondary" }) : /* @__PURE__ */ e(p, { className: "w-4 h-4 text-dc-text-secondary" }) }),
/* @__PURE__ */ o("div", { className: "flex-1", children: [
/* @__PURE__ */ e("div", { className: "font-medium text-sm text-dc-text", children: ee.title }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-muted", children: ee.description })
] })
]
}
),
le && /* @__PURE__ */ o("div", { className: "border-t border-dc-border p-2 space-y-1", children: [
L.length > 0 && De(L).length > 0 && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e(
se,
{
title: "Dimensions",
count: De(L).length,
sectionKey: `${ee.name}-dimensions`,
icon: /* @__PURE__ */ e(b, { className: "w-4 h-4 text-dc-success" })
}
),
x.has(`${ee.name}-dimensions`) && /* @__PURE__ */ e("div", { className: "ml-5 space-y-1 mt-1", children: De(L).map((te) => /* @__PURE__ */ e(
B,
{
field: te,
fieldType: "dimensions",
icon: /* @__PURE__ */ e(b, { className: "w-4 h-4" })
},
te.name
)) })
] }),
be.length > 0 && De(be).length > 0 && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e(
se,
{
title: "Time Dimensions",
count: De(be).length,
sectionKey: `${ee.name}-timeDimensions`,
icon: /* @__PURE__ */ e(R, { className: "w-4 h-4 text-dc-accent" })
}
),
x.has(`${ee.name}-timeDimensions`) && /* @__PURE__ */ e("div", { className: "ml-5 space-y-1 mt-1", children: De(be).map((te) => /* @__PURE__ */ e(
B,
{
field: te,
fieldType: "timeDimensions",
icon: /* @__PURE__ */ e(R, { className: "w-4 h-4" })
},
te.name
)) })
] }),
ee.measures.length > 0 && De(ee.measures).length > 0 && /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e(
se,
{
title: "Measures",
count: De(ee.measures).length,
sectionKey: `${ee.name}-measures`,
icon: /* @__PURE__ */ e(_, { className: "w-4 h-4 text-dc-warning" })
}
),
x.has(`${ee.name}-measures`) && /* @__PURE__ */ e("div", { className: "ml-5 space-y-1 mt-1", children: De(ee.measures).map((te) => /* @__PURE__ */ e(
B,
{
field: te,
fieldType: "measures",
icon: Is(te.type, "w-4 h-4")
},
te.name
)) })
] })
] })
] }, ee.name);
});
})() })
) })
] });
}, Xc = Ot(Kc), Zc = Q("close"), el = Q("eye"), tl = Q("eyeOff"), rl = ({
filter: t,
schema: r,
dashboardConfig: n,
isOpen: s,
onSave: a,
onClose: c,
onDelete: l,
convertToMetaResponse: u
}) => {
const [d, f] = V(t.label), [h, p] = V(t.filter), [m, v] = V(!1);
ve(() => {
s && (f(t.label), p(t.filter));
}, [t, s]);
const C = ye(() => _a(n), [n]), _ = ye(() => {
if (!r) return null;
if (m)
return u(r);
const x = r.cubes.map((S) => {
const y = S.name, M = S.measures.filter((T) => {
const j = T.name.includes(".") ? T.name : `${y}.${T.name}`;
return C.measures.has(j);
}), E = S.dimensions.filter((T) => {
const j = T.name.includes(".") ? T.name : `${y}.${T.name}`;
return C.dimensions.has(j) || C.timeDimensions.has(j);
});
return M.length > 0 || E.length > 0 ? {
...S,
measures: M,
dimensions: E
} : null;
}).filter((S) => S !== null), N = {
...r,
cubes: x
};
return u(N);
}, [r, C, m, u]), b = ye(() => "member" in h && h.member ? h.member : null, [h]), R = F((x) => {
f(x);
}, []), D = F((x) => {
p(x[0] || h);
}, [h]), $ = F((x) => {
"member" in h && p({
...h,
member: x,
values: []
// Reset values when changing field
});
}, [h]), A = F((x, N) => {
"member" in h && p({
...h,
values: Array.isArray(N) ? N : [N]
});
}, [h]), w = F(() => d.trim() ? !t.isUniversalTime && "member" in h && !h.member ? { isValid: !1, message: "Please select a field for the filter" } : { isValid: !0 } : { isValid: !1, message: "Filter label is required" }, [d, h, t.isUniversalTime]), i = F(async () => {
const x = w();
if (!x.isValid) {
alert(x.message);
return;
}
const N = {
id: t.id,
label: d,
filter: h,
// Preserve isUniversalTime flag if present
...t.isUniversalTime && { isUniversalTime: !0 }
};
try {
await a(N), c();
} catch (S) {
console.error("Failed to save filter:", S), alert("Failed to save filter. Please try again.");
}
}, [t.id, t.isUniversalTime, d, h, w, a, c]), g = F(() => {
f(t.label), p(t.filter), c();
}, [t, c]);
return /* @__PURE__ */ e(
"div",
{
className: "fixed inset-0 z-50 backdrop-blur-md flex items-center justify-center p-2",
style: { backgroundColor: "var(--dc-overlay)" },
children: /* @__PURE__ */ o(
"div",
{
className: "rounded-lg max-w-7xl w-full h-[95vh] overflow-hidden flex flex-col bg-dc-surface border border-dc-border",
style: { boxShadow: "var(--dc-shadow-2xl)" },
children: [
/* @__PURE__ */ o("div", { className: "px-6 py-4 border-b border-dc-border flex items-center justify-between", children: [
/* @__PURE__ */ o("div", { className: "flex-1", children: [
/* @__PURE__ */ e("label", { className: "block text-sm font-medium mb-2 text-dc-text", children: "Filter Label" }),
/* @__PURE__ */ e(
"input",
{
type: "text",
value: d,
onChange: (x) => R(x.target.value),
className: "w-full px-3 py-2 border border-dc-border rounded-md text-sm bg-dc-surface-secondary text-dc-text",
placeholder: "Enter filter label"
}
)
] }),
/* @__PURE__ */ e(
"button",
{
onClick: g,
className: "ml-4 p-2 hover:bg-dc-surface-hover rounded-md transition-colors text-dc-text-secondary",
children: /* @__PURE__ */ e(Zc, { className: "w-5 h-5" })
}
)
] }),
/* @__PURE__ */ o("div", { className: "flex-1 flex", children: [
!t.isUniversalTime && /* @__PURE__ */ e("div", { className: "w-80 border-r border-dc-border bg-dc-surface overflow-auto", children: /* @__PURE__ */ o("div", { className: "p-4", children: [
/* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-3", children: [
/* @__PURE__ */ e("h3", { className: "text-sm font-semibold text-dc-text", children: "Available Fields" }),
/* @__PURE__ */ e(
"button",
{
onClick: () => v(!m),
className: "flex items-center gap-1 text-xs px-2 py-1 rounded hover:bg-dc-surface-hover text-dc-text-muted",
title: m ? "Show dashboard fields only" : "Show all fields",
children: m ? /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(tl, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ e("span", { children: "Dashboard" })
] }) : /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(el, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ e("span", { children: "All" })
] })
}
)
] }),
!m && /* @__PURE__ */ e("div", { className: "text-xs text-dc-info mb-3 p-2 bg-dc-info-bg rounded border border-dc-info-border", children: "Showing only fields used in this dashboard" }),
_ && _.cubes.length > 0 ? /* @__PURE__ */ e(
Xc,
{
schema: _,
schemaStatus: "success",
schemaError: null,
selectedFields: {
measures: b ? [b] : [],
dimensions: b ? [b] : [],
timeDimensions: b ? [b] : []
},
onFieldSelect: (x) => $(x),
onFieldDeselect: () => {
}
}
) : /* @__PURE__ */ e("div", { className: "text-center py-8 text-dc-text-muted text-sm", children: m ? /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("p", { className: "mb-2", children: "No schema available" }),
/* @__PURE__ */ e("p", { className: "text-xs", children: "Check your API connection" })
] }) : /* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("p", { className: "mb-2", children: "No fields used in dashboard" }),
/* @__PURE__ */ e("p", { className: "text-xs", children: "Add portlets to the dashboard first, or toggle to show all fields" })
] }) })
] }) }),
/* @__PURE__ */ e("div", { className: "flex-1 overflow-auto px-6 py-4 bg-dc-surface-secondary", children: t.isUniversalTime ? (
/* Universal time filter - show DateRangeSelector */
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ o("div", { className: "mb-4 p-3 rounded-md bg-dc-info-bg border border-dc-info-border", children: [
/* @__PURE__ */ e("div", { className: "text-sm font-medium text-dc-info mb-1", children: "Universal Time Filter" }),
/* @__PURE__ */ e("div", { className: "text-xs text-dc-text-secondary", children: "This filter applies to all time dimensions in portlets it's mapped to. Select a date range below to filter data across all time-based charts." })
] }),
/* @__PURE__ */ e("div", { className: "mt-4", children: /* @__PURE__ */ e(
Yc,
{
timeDimension: "__universal_time__",
availableTimeDimensions: ["__universal_time__"],
currentDateRange: (() => {
const x = h;
if (x.dateRange) return x.dateRange;
if (x.values)
return Array.isArray(x.values) && x.values.length === 1 && typeof x.values[0] == "string" ? x.values[0] : x.values;
})(),
onDateRangeChange: A,
onTimeDimensionChange: () => {
},
onRemove: () => {
},
hideFieldSelector: !0,
hideRemoveButton: !0
}
) })
] })
) : (
/* Regular filter - show FilterBuilder */
/* @__PURE__ */ e(
zc,
{
filters: [h],
schema: u(r),
query: {},
onFiltersChange: D
}
)
) })
] }),
/* @__PURE__ */ o("div", { className: "px-6 py-4 border-t border-dc-border flex items-center justify-between bg-dc-surface", children: [
/* @__PURE__ */ e(
"button",
{
onClick: l,
className: "px-4 py-2 text-sm font-medium text-dc-danger hover:bg-dc-danger-bg rounded-md transition-colors",
children: "Delete Filter"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: i,
className: "px-4 py-2 text-sm font-medium rounded-md transition-colors bg-dc-primary hover:bg-dc-primary-hover text-dc-primary-content",
children: "Done"
}
)
] })
]
}
)
}
);
}, qr = Q("filter"), gr = Q("add"), nl = Q("close"), sl = Q("edit"), al = Q("chevronDown"), Qn = Q("timeDimension"), ol = ({
dashboardFilters: t,
onAddFilter: r,
onAddTimeFilter: n,
onEditFilter: s,
onRemoveFilter: a,
selectedFilterId: c,
onFilterSelect: l
}) => {
const [u, d] = wt.useState(!1), f = (h) => {
const { id: p, label: m, isUniversalTime: v } = h, C = c === p;
return /* @__PURE__ */ o(
"div",
{
className: "inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md border text-xs transition-all cursor-pointer hover:shadow-md",
style: {
backgroundColor: C ? "var(--dc-primary)" : "var(--dc-surface)",
borderColor: C ? "var(--dc-primary)" : "var(--dc-border)",
borderWidth: C ? "2px" : "1px",
color: C ? "white" : "var(--dc-text)",
boxShadow: C ? "0 0 0 3px rgba(var(--dc-primary-rgb), 0.1)" : "none"
},
onClick: () => {
l && l(p);
},
children: [
/* @__PURE__ */ e(
v ? Qn : qr,
{
className: "w-3.5 h-3.5 shrink-0",
style: { color: C ? "white" : "var(--dc-primary)" }
}
),
/* @__PURE__ */ e("span", { className: "font-medium truncate", children: m }),
!C && /* @__PURE__ */ o("div", { className: "flex items-center gap-0.5 ml-1", onClick: (b) => b.stopPropagation(), children: [
/* @__PURE__ */ e(
"button",
{
onClick: () => s(p),
className: "p-0.5 hover:bg-dc-hover rounded transition-colors",
title: "Edit filter",
children: /* @__PURE__ */ e(sl, { className: "w-3 h-3" })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: () => a(p),
className: "p-0.5 hover:bg-dc-danger-bg hover:text-dc-danger rounded transition-colors",
title: "Remove filter",
children: /* @__PURE__ */ e(nl, { className: "w-3 h-3" })
}
)
] })
]
},
p
);
};
return /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ o("div", { className: "md:hidden", children: [
/* @__PURE__ */ o(
"div",
{
className: "px-4 py-2 flex items-center justify-between cursor-pointer",
onClick: () => d(!u),
children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e(qr, { className: "w-4 h-4 shrink-0", style: { color: "var(--dc-primary)" } }),
/* @__PURE__ */ e("h3", { className: "text-sm font-semibold", style: { color: "var(--dc-text)" }, children: "Filters" }),
t.length > 0 && /* @__PURE__ */ e(
"span",
{
className: "px-1.5 py-0.5 rounded-full text-xs font-medium",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: t.length
}
),
/* @__PURE__ */ e(
al,
{
className: `w-4 h-4 transition-transform ${u ? "" : "rotate-180"}`,
style: { color: "var(--dc-text-secondary)" }
}
)
] }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-1", children: [
!t.some((h) => h.isUniversalTime) && /* @__PURE__ */ o(
"button",
{
onClick: (h) => {
h.stopPropagation(), n();
},
className: "inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80",
style: {
backgroundColor: "var(--dc-surface)",
color: "var(--dc-primary)",
border: "1px solid var(--dc-border)"
},
title: "Add date range filter (applies to all time dimensions)",
children: [
/* @__PURE__ */ e(gr, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ e(Qn, { className: "w-3.5 h-3.5" })
]
}
),
/* @__PURE__ */ e(
"button",
{
onClick: (h) => {
h.stopPropagation(), r();
},
className: "inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: /* @__PURE__ */ e(gr, { className: "w-3.5 h-3.5" })
}
)
] })
]
}
),
t.length > 0 && !u && /* @__PURE__ */ e("div", { className: "px-4 pb-2 flex flex-col gap-2", children: t.map(f) }),
t.length === 0 && !u && /* @__PURE__ */ e("div", { className: "px-4 pb-2", children: /* @__PURE__ */ e(
"div",
{
className: "text-xs p-2 rounded-md text-center",
style: {
backgroundColor: "var(--dc-surface-secondary)",
color: "var(--dc-text-secondary)"
},
children: 'No filters configured. Click "Add" to create one.'
}
) })
] }),
/* @__PURE__ */ o("div", { className: "hidden md:flex md:items-center md:gap-3 px-4 py-2", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 shrink-0", children: [
/* @__PURE__ */ e(qr, { className: "w-4 h-4 shrink-0", style: { color: "var(--dc-primary)" } }),
/* @__PURE__ */ e("h3", { className: "text-sm font-semibold whitespace-nowrap", style: { color: "var(--dc-text)" }, children: "Filters" }),
t.length > 0 && /* @__PURE__ */ e(
"span",
{
className: "px-1.5 py-0.5 rounded-full text-xs font-medium",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: t.length
}
)
] }),
t.length > 0 ? /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-2 flex-1 min-w-0", children: t.map(f) }) : /* @__PURE__ */ e("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ e(
"div",
{
className: "text-xs px-3 py-1 rounded-md inline-block",
style: {
backgroundColor: "var(--dc-surface-secondary)",
color: "var(--dc-text-secondary)"
},
children: 'No filters configured. Click "Add" to create one.'
}
) }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-1 shrink-0", children: [
!t.some((h) => h.isUniversalTime) && /* @__PURE__ */ o(
"button",
{
onClick: n,
className: "inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80",
style: {
backgroundColor: "var(--dc-surface)",
color: "var(--dc-primary)",
border: "1px solid var(--dc-border)"
},
title: "Add date range filter (applies to all time dimensions)",
children: [
/* @__PURE__ */ e(gr, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ e("span", { children: "Date Range" })
]
}
),
/* @__PURE__ */ o(
"button",
{
onClick: r,
className: "inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors hover:opacity-80",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: [
/* @__PURE__ */ e(gr, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ e("span", { children: "Filter" })
]
}
)
] })
] })
] });
}, Un = ({
activePreset: t,
onPresetSelect: r,
disabled: n = !1
}) => {
const s = ye(() => {
const a = {};
for (const c of Ur) {
const l = sn(c.value);
l && (a[c.id] = kr(l.start, l.end));
}
return a;
}, []);
return /* @__PURE__ */ e("div", { className: "flex items-center gap-1", children: Ur.map((a) => {
const c = t === a.id, l = s[a.id];
return /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => r(a.value),
disabled: n,
title: l,
className: `
px-2.5 py-1 rounded text-xs font-medium transition-colors
focus:outline-none focus:ring-2 focus:ring-offset-1
disabled:opacity-50 disabled:cursor-not-allowed
${c ? "shadow-sm" : "border"}
`,
style: {
backgroundColor: c ? "var(--dc-primary)" : "var(--dc-surface)",
color: c ? "white" : "var(--dc-text)",
borderColor: c ? "transparent" : "var(--dc-border)",
...n ? {} : {
cursor: "pointer"
}
},
onMouseEnter: (u) => {
!c && !n && (u.currentTarget.style.backgroundColor = "var(--dc-surface-hover)");
},
onMouseLeave: (u) => {
!c && !n && (u.currentTarget.style.backgroundColor = "var(--dc-surface)");
},
children: a.label
},
a.id
);
}) });
}, cl = [
{ value: "days", label: "Days" },
{ value: "weeks", label: "Weeks" },
{ value: "months", label: "Months" },
{ value: "quarters", label: "Quarters" },
{ value: "years", label: "Years" }
], Hn = ({
isOpen: t,
onClose: r,
onDateRangeChange: n,
currentDateRange: s
}) => {
const a = Ce(null), [c, l] = V("fixed"), [u, d] = V(""), [f, h] = V(""), [p, m] = V(""), [v, C] = V(7), [_, b] = V("days");
ve(() => {
if (s)
if (Array.isArray(s))
l("fixed"), d(s[0] || ""), h(s[1] || s[0] || "");
else {
const i = s.match(/^last\s+(\d+)\s+(day|days|week|weeks|month|months|quarter|quarters|year|years)$/i);
if (i) {
l("last"), C(parseInt(i[1], 10));
const g = i[2].toLowerCase();
b(g === "day" ? "days" : g === "week" ? "weeks" : g === "month" ? "months" : g === "quarter" ? "quarters" : g === "year" ? "years" : g.endsWith("s") ? g : `${g}s`);
}
}
}, [s]), ve(() => {
if (!t) return;
const i = (N) => {
a.current && !a.current.contains(N.target) && r();
}, g = (N) => {
N.key === "Escape" && r();
}, x = setTimeout(() => {
document.addEventListener("mousedown", i), document.addEventListener("keydown", g);
}, 0);
return () => {
clearTimeout(x), document.removeEventListener("mousedown", i), document.removeEventListener("keydown", g);
};
}, [t, r]);
const R = F(() => {
u && f ? n([u, f]) : u && n([u, u]);
}, [u, f, n]), D = F(() => {
if (p) {
const i = Cr(/* @__PURE__ */ new Date());
n([p, i]);
}
}, [p, n]), $ = F(() => {
if (v > 0) {
const i = `last_n_${_}`, g = Rt(i, v);
n(g);
}
}, [v, _, n]);
if (!t) return null;
const A = (i) => ({
backgroundColor: i ? "var(--dc-primary)" : "transparent",
color: i ? "white" : "var(--dc-text)",
borderBottom: i ? "none" : "2px solid var(--dc-border)"
}), w = (i) => {
i.stopPropagation();
};
return /* @__PURE__ */ o(
"div",
{
ref: a,
className: "absolute top-full left-0 mt-1 z-50 border rounded-lg shadow-lg min-w-[280px]",
style: {
backgroundColor: "var(--dc-surface)",
borderColor: "var(--dc-border)",
boxShadow: "0 10px 25px rgba(0, 0, 0, 0.15)"
},
onClick: w,
onMouseDown: w,
children: [
/* @__PURE__ */ e(
"div",
{
className: "flex border-b",
style: { borderColor: "var(--dc-border)" },
children: ["fixed", "since", "last"].map((i) => /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: () => l(i),
className: "flex-1 px-4 py-2 text-sm font-medium capitalize transition-colors",
style: A(c === i),
children: i
},
i
))
}
),
/* @__PURE__ */ o("div", { className: "p-4", children: [
c === "fixed" && /* @__PURE__ */ o("div", { className: "space-y-3", children: [
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "Start Date"
}
),
/* @__PURE__ */ e(
"input",
{
type: "date",
value: u,
onChange: (i) => d(i.target.value),
className: "w-full px-3 py-2 text-sm border rounded focus:outline-none focus:ring-2",
style: {
borderColor: "var(--dc-border)",
backgroundColor: "var(--dc-bg)",
color: "var(--dc-text)"
}
}
)
] }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "End Date"
}
),
/* @__PURE__ */ e(
"input",
{
type: "date",
value: f,
onChange: (i) => h(i.target.value),
className: "w-full px-3 py-2 text-sm border rounded focus:outline-none focus:ring-2",
style: {
borderColor: "var(--dc-border)",
backgroundColor: "var(--dc-bg)",
color: "var(--dc-text)"
}
}
)
] }),
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: R,
disabled: !u,
className: "w-full py-2 text-sm font-medium rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: "Apply"
}
)
] }),
c === "since" && /* @__PURE__ */ o("div", { className: "space-y-3", children: [
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "Since Date"
}
),
/* @__PURE__ */ e(
"input",
{
type: "date",
value: p,
onChange: (i) => m(i.target.value),
className: "w-full px-3 py-2 text-sm border rounded focus:outline-none focus:ring-2",
style: {
borderColor: "var(--dc-border)",
backgroundColor: "var(--dc-bg)",
color: "var(--dc-text)"
}
}
)
] }),
/* @__PURE__ */ e(
"p",
{
className: "text-xs",
style: { color: "var(--dc-text-secondary)" },
children: "From selected date to today"
}
),
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: D,
disabled: !p,
className: "w-full py-2 text-sm font-medium rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: "Apply"
}
)
] }),
c === "last" && /* @__PURE__ */ o("div", { className: "space-y-3", children: [
/* @__PURE__ */ o("div", { className: "flex gap-2", children: [
/* @__PURE__ */ o("div", { className: "flex-1", children: [
/* @__PURE__ */ e(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "Number"
}
),
/* @__PURE__ */ e(
"input",
{
type: "number",
min: "1",
max: "999",
value: v,
onChange: (i) => C(Math.max(1, parseInt(i.target.value, 10) || 1)),
className: "w-full px-3 py-2 text-sm border rounded focus:outline-none focus:ring-2",
style: {
borderColor: "var(--dc-border)",
backgroundColor: "var(--dc-bg)",
color: "var(--dc-text)"
}
}
)
] }),
/* @__PURE__ */ o("div", { className: "flex-1", children: [
/* @__PURE__ */ e(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "Unit"
}
),
/* @__PURE__ */ e(
"select",
{
value: _,
onChange: (i) => b(i.target.value),
className: "w-full px-3 py-2 text-sm border rounded focus:outline-none focus:ring-2",
style: {
borderColor: "var(--dc-border)",
backgroundColor: "var(--dc-bg)",
color: "var(--dc-text)"
},
children: cl.map((i) => /* @__PURE__ */ e("option", { value: i.value, children: i.label }, i.value))
}
)
] })
] }),
/* @__PURE__ */ o(
"p",
{
className: "text-xs",
style: { color: "var(--dc-text-secondary)" },
children: [
"Last ",
v,
" ",
v === 1 ? _.slice(0, -1) : _
]
}
),
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: $,
disabled: v < 1,
className: "w-full py-2 text-sm font-medium rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: "Apply"
}
)
] })
] }),
/* @__PURE__ */ e(
"div",
{
className: "px-4 pb-4",
children: /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: r,
className: "w-full py-2 text-sm font-medium rounded border transition-colors",
style: {
borderColor: "var(--dc-border)",
color: "var(--dc-text-secondary)",
backgroundColor: "transparent"
},
children: "Cancel"
}
)
}
)
]
}
);
}, ll = Q("check"), zn = ({
isOpen: t,
onClose: r,
onSelect: n,
currentXTD: s
}) => {
const a = Ce(null);
if (ve(() => {
if (!t) return;
const l = (f) => {
a.current && !a.current.contains(f.target) && r();
}, u = (f) => {
f.key === "Escape" && r();
}, d = setTimeout(() => {
document.addEventListener("mousedown", l), document.addEventListener("keydown", u);
}, 0);
return () => {
clearTimeout(d), document.removeEventListener("mousedown", l), document.removeEventListener("keydown", u);
};
}, [t, r]), !t) return null;
const c = (l) => {
l.stopPropagation();
};
return /* @__PURE__ */ e(
"div",
{
ref: a,
className: "absolute top-full left-0 mt-1 z-50 border rounded-lg shadow-lg min-w-[180px] py-1",
style: {
backgroundColor: "var(--dc-surface)",
borderColor: "var(--dc-border)",
boxShadow: "0 10px 25px rgba(0, 0, 0, 0.15)"
},
onClick: c,
onMouseDown: c,
children: nn.map((l) => {
const u = s === l.id, d = sn(l.value), f = d ? kr(d.start, d.end) : "";
return /* @__PURE__ */ o(
"button",
{
type: "button",
onClick: () => n(l.value),
className: "w-full px-3 py-2 text-left text-sm transition-colors flex items-center justify-between gap-2",
style: {
backgroundColor: u ? "var(--dc-primary-bg)" : "transparent",
color: "var(--dc-text)"
},
onMouseEnter: (h) => {
u || (h.currentTarget.style.backgroundColor = "var(--dc-surface-hover)");
},
onMouseLeave: (h) => {
u || (h.currentTarget.style.backgroundColor = "transparent");
},
children: [
/* @__PURE__ */ o("div", { className: "flex flex-col", children: [
/* @__PURE__ */ e("span", { className: "font-medium", children: l.label }),
f && /* @__PURE__ */ e(
"span",
{
className: "text-xs mt-0.5",
style: { color: "var(--dc-text-secondary)" },
children: f
}
)
] }),
u && /* @__PURE__ */ e(
ll,
{
className: "w-4 h-4 shrink-0",
style: { color: "var(--dc-primary)" }
}
)
]
},
l.id
);
})
}
);
};
function il(t) {
return t ? {
cubes: t.cubes.map((r) => ({
name: r.name,
title: r.title || r.name,
description: r.description || "",
measures: r.measures.map((n) => ({
name: n.name,
title: n.title || n.name,
type: n.type,
description: "",
shortTitle: n.shortTitle || n.title || n.name
})),
dimensions: r.dimensions.map((n) => ({
name: n.name,
title: n.title || n.name,
type: n.type,
description: "",
shortTitle: n.shortTitle || n.title || n.name
})),
segments: r.segments?.map((n) => ({
name: n.name,
title: n.title || n.name,
type: n.type,
description: "",
shortTitle: n.shortTitle || n.title || n.name
})) || []
}))
} : null;
}
const dl = ({
filter: t,
schema: r,
onValuesChange: n,
onClose: s,
anchorRef: a
}) => {
const c = Ce(null);
ve(() => {
const d = (p) => {
c.current && !c.current.contains(p.target) && a.current && !a.current.contains(p.target) && s();
}, f = (p) => {
p.key === "Escape" && s();
}, h = setTimeout(() => {
document.addEventListener("mousedown", d), document.addEventListener("keydown", f);
}, 0);
return () => {
clearTimeout(h), document.removeEventListener("mousedown", d), document.removeEventListener("keydown", f);
};
}, [s, a]);
const l = F((d) => {
n(d);
}, [n]), u = il(r);
return /* @__PURE__ */ o(
"div",
{
ref: c,
className: "absolute top-full left-0 mt-1 z-50 border rounded-lg shadow-lg p-3 min-w-[220px]",
style: {
backgroundColor: "var(--dc-surface)",
borderColor: "var(--dc-border)",
boxShadow: "var(--dc-shadow-lg)"
},
children: [
/* @__PURE__ */ e(
"div",
{
className: "text-xs font-medium mb-2",
style: { color: "var(--dc-text-secondary)" },
children: "Edit value"
}
),
/* @__PURE__ */ e("div", { className: "min-w-[180px]", children: /* @__PURE__ */ e(
$s,
{
fieldName: t.member,
operator: t.operator,
values: t.values || [],
onValuesChange: l,
schema: u
}
) }),
/* @__PURE__ */ e("div", { className: "flex justify-end gap-2 mt-3 pt-2 border-t", style: { borderColor: "var(--dc-border)" }, children: /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: s,
className: "px-3 py-1 text-xs font-medium rounded border transition-colors",
style: {
borderColor: "var(--dc-border)",
color: "var(--dc-text-secondary)",
backgroundColor: "transparent"
},
children: "Close"
}
) })
]
}
);
}, ul = Q("close"), ml = Q("edit"), Gn = ({
filter: t,
schema: r,
isEditMode: n,
onChange: s,
onEdit: a,
onRemove: c
}) => {
const [l, u] = V(!1), d = Ce(null), f = t.filter, { label: h } = t, { operator: p, values: m } = f, v = Lc(m || [], p), C = F((b) => {
s({
...t,
filter: {
...f,
values: b
}
});
}, [t, f, s]), _ = F(() => {
n ? a?.() : u(!0);
}, [n, a]);
return "member" in t.filter ? /* @__PURE__ */ o("div", { ref: d, className: "relative inline-flex", children: [
/* @__PURE__ */ o(
"div",
{
className: `
inline-flex items-center gap-1 px-2 py-1 rounded text-xs
border transition-colors cursor-pointer
${n ? "pr-1" : ""}
`,
style: {
backgroundColor: "var(--dc-surface)",
borderColor: "var(--dc-border)",
color: "var(--dc-text)"
},
onClick: _,
onMouseEnter: (b) => {
b.currentTarget.style.backgroundColor = "var(--dc-surface-hover)";
},
onMouseLeave: (b) => {
b.currentTarget.style.backgroundColor = "var(--dc-surface)";
},
title: `${h} ${v}`,
children: [
/* @__PURE__ */ e("span", { className: "font-medium truncate max-w-[100px]", children: h }),
v && /* @__PURE__ */ e(Oe, { children: /* @__PURE__ */ e("span", { style: { color: "var(--dc-text-secondary)" }, children: v }) }),
n && /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: (b) => {
b.stopPropagation(), a?.();
},
className: "p-0.5 rounded transition-colors",
style: { color: "var(--dc-text-secondary)" },
onMouseEnter: (b) => {
b.currentTarget.style.color = "var(--dc-text)";
},
onMouseLeave: (b) => {
b.currentTarget.style.color = "var(--dc-text-secondary)";
},
children: /* @__PURE__ */ e(ml, { className: "w-3 h-3" })
}
),
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: (b) => {
b.stopPropagation(), c?.();
},
className: "p-0.5 rounded transition-colors",
style: { color: "var(--dc-text-secondary)" },
onMouseEnter: (b) => {
b.currentTarget.style.color = "var(--dc-error)";
},
onMouseLeave: (b) => {
b.currentTarget.style.color = "var(--dc-text-secondary)";
},
children: /* @__PURE__ */ e(ul, { className: "w-3 h-3" })
}
)
] })
]
}
),
l && !n && /* @__PURE__ */ e(
dl,
{
filter: f,
schema: r,
onValuesChange: C,
onClose: () => u(!1),
anchorRef: d
}
)
] }) : null;
}, Wn = Q("add"), Yn = Q("timeDimension"), Pr = Q("chevronDown"), Jn = Q("filter"), fl = ({
dashboardFilters: t,
schema: r,
isEditMode: n,
onDashboardFiltersChange: s,
onAddFilter: a,
onEditFilter: c,
onRemoveFilter: l
}) => {
const [u, d] = V(!1), [f, h] = V(!1), p = Ce(null), m = Ce(null), v = ye(() => t.find((N) => N.isUniversalTime), [t]), C = ye(() => {
if (!v) return null;
const N = v.filter;
return N.dateRange ? N.dateRange : N.values && N.values.length > 0 ? N.values.length === 1 && typeof N.values[0] == "string" ? N.values[0] : N.values : null;
}, [v]), _ = ye(() => Bn(C), [C]), b = ye(() => {
if (!C || Array.isArray(C)) return null;
const N = Bn(C);
return nn.find((S) => S.id === N)?.id || null;
}, [C]), R = ye(() => t.filter((N) => !N.isUniversalTime), [t]), D = F(() => `df_${Date.now()}_${Math.random().toString(36).substring(7)}`, []), $ = F((N) => {
if (v) {
const S = t.map((y) => y.id === v.id ? {
...y,
filter: {
...y.filter,
values: Array.isArray(N) ? N : [N],
dateRange: N
}
} : y);
s(S);
} else {
const S = {
id: D(),
label: "Date Range",
isUniversalTime: !0,
filter: {
member: "__universal_time__",
operator: "inDateRange",
values: Array.isArray(N) ? N : [N],
dateRange: N
}
};
s([...t, S]);
}
}, [t, v, s, D]), A = F((N) => {
$(N);
}, [$]), w = F((N) => {
$(N), h(!1);
}, [$]), i = F((N) => {
$(N), d(!1);
}, [$]), g = F((N, S) => {
const y = t.map(
(M) => M.id === N ? S : M
);
s(y);
}, [t, s]), x = ye(() => {
if (!C) return null;
if (Array.isArray(C)) {
const S = new Date(C[0]), y = new Date(C[1] || C[0]);
return kr(S, y);
}
const N = sn(C);
return N ? kr(N.start, N.end) : C;
}, [C]);
return !n && t.length === 0 ? null : /* @__PURE__ */ o(
"div",
{
className: "border rounded-lg",
style: {
borderColor: "var(--dc-border)",
backgroundColor: "var(--dc-surface)"
},
children: [
/* @__PURE__ */ o("div", { className: "hidden md:flex items-center gap-2 px-3 py-2", children: [
/* @__PURE__ */ e(
Jn,
{
className: "w-4 h-4 shrink-0",
style: { color: "var(--dc-text-secondary)" }
}
),
/* @__PURE__ */ e(
Un,
{
activePreset: _ !== "custom" && !b ? _ : null,
onPresetSelect: A
}
),
/* @__PURE__ */ o("div", { className: "relative", children: [
/* @__PURE__ */ o(
"button",
{
ref: p,
type: "button",
onClick: () => {
d(!u), h(!1);
},
title: _ === "custom" && x ? x : "Custom date range",
className: `
flex items-center gap-1 px-2.5 py-1 rounded text-xs font-medium border
transition-colors focus:outline-none focus:ring-2 focus:ring-offset-1
`,
style: {
backgroundColor: _ === "custom" ? "var(--dc-primary)" : "var(--dc-surface)",
color: _ === "custom" ? "white" : "var(--dc-text)",
borderColor: _ === "custom" ? "transparent" : "var(--dc-border)"
},
children: [
/* @__PURE__ */ e(Yn, { className: "w-3 h-3" }),
/* @__PURE__ */ e("span", { children: "Custom" }),
/* @__PURE__ */ e(Pr, { className: "w-3 h-3" })
]
}
),
u && /* @__PURE__ */ e(
Hn,
{
isOpen: u,
onClose: () => d(!1),
onDateRangeChange: i,
currentDateRange: C,
anchorRef: p
}
)
] }),
/* @__PURE__ */ o("div", { className: "relative", children: [
/* @__PURE__ */ o(
"button",
{
ref: m,
type: "button",
onClick: () => {
h(!f), d(!1);
},
title: b && x ? x : "X to Date options",
className: `
flex items-center gap-1 px-2.5 py-1 rounded text-xs font-medium border
transition-colors focus:outline-none focus:ring-2 focus:ring-offset-1
`,
style: {
backgroundColor: b ? "var(--dc-primary)" : "var(--dc-surface)",
color: b ? "white" : "var(--dc-text)",
borderColor: b ? "transparent" : "var(--dc-border)"
},
children: [
/* @__PURE__ */ e("span", { children: "XTD" }),
/* @__PURE__ */ e(Pr, { className: "w-3 h-3" })
]
}
),
f && /* @__PURE__ */ e(
zn,
{
isOpen: f,
onClose: () => h(!1),
onSelect: w,
currentXTD: b,
anchorRef: m
}
)
] }),
R.length > 0 && /* @__PURE__ */ e(
"div",
{
className: "h-5 w-px mx-1",
style: { backgroundColor: "var(--dc-border)" }
}
),
/* @__PURE__ */ e("div", { className: "flex items-center gap-1.5 flex-wrap", children: R.map((N) => /* @__PURE__ */ e(
Gn,
{
filter: N,
schema: r,
isEditMode: n,
onChange: (S) => g(N.id, S),
onEdit: () => c?.(N.id),
onRemove: () => l?.(N.id)
},
N.id
)) }),
n && a && /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: a,
className: "flex items-center gap-1 px-2 py-1 rounded text-xs font-medium border transition-colors",
style: {
borderColor: "var(--dc-border)",
color: "var(--dc-text-secondary)",
backgroundColor: "transparent"
},
onMouseEnter: (N) => {
N.currentTarget.style.backgroundColor = "var(--dc-surface-hover)";
},
onMouseLeave: (N) => {
N.currentTarget.style.backgroundColor = "transparent";
},
children: /* @__PURE__ */ e(Wn, { className: "w-3.5 h-3.5" })
}
)
] }),
/* @__PURE__ */ o("div", { className: "md:hidden", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 overflow-x-auto px-3 py-2 scrollbar-thin", children: [
/* @__PURE__ */ e(
Jn,
{
className: "w-4 h-4 shrink-0",
style: { color: "var(--dc-text-secondary)" }
}
),
/* @__PURE__ */ e(
Un,
{
activePreset: _ !== "custom" && !b ? _ : null,
onPresetSelect: A
}
)
] }),
/* @__PURE__ */ o(
"div",
{
className: "flex items-center justify-between px-3 py-2 border-t",
style: { borderColor: "var(--dc-border)" },
children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ o("div", { className: "relative", children: [
/* @__PURE__ */ o(
"button",
{
ref: p,
type: "button",
onClick: () => {
d(!u), h(!1);
},
className: `
flex items-center gap-1 px-2.5 py-1 rounded text-xs font-medium border
transition-colors
`,
style: {
backgroundColor: _ === "custom" ? "var(--dc-primary)" : "var(--dc-surface)",
color: _ === "custom" ? "white" : "var(--dc-text)",
borderColor: _ === "custom" ? "transparent" : "var(--dc-border)"
},
children: [
/* @__PURE__ */ e(Yn, { className: "w-3 h-3" }),
/* @__PURE__ */ e("span", { children: "Custom" })
]
}
),
u && /* @__PURE__ */ e(
Hn,
{
isOpen: u,
onClose: () => d(!1),
onDateRangeChange: i,
currentDateRange: C,
anchorRef: p
}
)
] }),
/* @__PURE__ */ o("div", { className: "relative", children: [
/* @__PURE__ */ o(
"button",
{
ref: m,
type: "button",
onClick: () => {
h(!f), d(!1);
},
className: `
flex items-center gap-1 px-2.5 py-1 rounded text-xs font-medium border
transition-colors
`,
style: {
backgroundColor: b ? "var(--dc-primary)" : "var(--dc-surface)",
color: b ? "white" : "var(--dc-text)",
borderColor: b ? "transparent" : "var(--dc-border)"
},
children: [
/* @__PURE__ */ e("span", { children: "XTD" }),
/* @__PURE__ */ e(Pr, { className: "w-3 h-3" })
]
}
),
f && /* @__PURE__ */ e(
zn,
{
isOpen: f,
onClose: () => h(!1),
onSelect: w,
currentXTD: b,
anchorRef: m
}
)
] })
] }),
n && a && /* @__PURE__ */ e(
"button",
{
type: "button",
onClick: a,
className: "flex items-center gap-1 px-2 py-1 rounded text-xs font-medium border transition-colors",
style: {
borderColor: "var(--dc-border)",
color: "var(--dc-text-secondary)",
backgroundColor: "transparent"
},
children: /* @__PURE__ */ e(Wn, { className: "w-3.5 h-3.5" })
}
)
]
}
),
R.length > 0 && /* @__PURE__ */ e(
"div",
{
className: "px-3 py-2 border-t",
style: { borderColor: "var(--dc-border)" },
children: /* @__PURE__ */ e("div", { className: "flex items-center gap-1.5 flex-wrap", children: R.map((N) => /* @__PURE__ */ e(
Gn,
{
filter: N,
schema: r,
isEditMode: n,
onChange: (S) => g(N.id, S),
onEdit: () => c?.(N.id),
onRemove: () => l?.(N.id)
},
N.id
)) })
}
)
] })
]
}
);
}, hl = ({
dashboardFilters: t,
editable: r,
schema: n,
dashboardConfig: s,
onDashboardFiltersChange: a,
onSaveFilters: c,
selectedFilterId: l,
onFilterSelect: u,
isEditMode: d = !1
}) => {
const [f, h] = V(null), [p, m] = V(!1), v = F((w) => w ? {
cubes: w.cubes.map((i) => ({
name: i.name,
title: i.title || i.name,
description: i.description || "",
measures: i.measures.map((g) => ({
name: g.name,
title: g.title,
type: g.type,
description: "",
shortTitle: g.shortTitle
})),
dimensions: i.dimensions.map((g) => ({
name: g.name,
title: g.title,
type: g.type,
description: "",
shortTitle: g.shortTitle
})),
segments: i.segments?.map((g) => ({
name: g.name,
title: g.title,
type: g.type,
description: "",
shortTitle: g.shortTitle
})) || []
}))
} : null, []), C = F(() => `df_${Date.now()}_${Math.random().toString(36).substring(7)}`, []), _ = F(() => {
const w = {
id: C(),
label: `Filter ${t.length + 1}`,
filter: {
member: "",
operator: "equals",
values: []
}
};
h(w), m(!0);
}, [t.length, C]), b = F(() => {
const w = {
id: C(),
label: "Date Range Filter",
isUniversalTime: !0,
filter: {
member: "__universal_time__",
// Placeholder, not used in merge logic
operator: "inDateRange",
values: ["last 30 days"]
}
}, i = [...t, w];
a(i);
}, [C, t, a]), R = F((w) => {
const i = t.find((g) => g.id === w);
i && (h(i), m(!0));
}, [t]), D = F((w) => {
const i = t.filter((g) => g.id !== w);
a(i), f?.id === w && (h(null), m(!1));
}, [t, f, a]), $ = F(async (w) => {
const i = t.findIndex((x) => x.id === w.id);
let g;
if (i >= 0 ? g = t.map(
(x) => x.id === w.id ? w : x
) : g = [...t, w], a(g), c)
try {
await c(g);
} catch (x) {
throw console.error("Failed to save filters:", x), x;
}
}, [t, a, c]), A = F(() => {
h(null), m(!1);
}, []);
return !r || !d && t.length === 0 ? null : /* @__PURE__ */ o("div", { className: "mb-4", children: [
d ? /* @__PURE__ */ e(
"div",
{
className: "border rounded-lg",
style: {
borderColor: "var(--dc-border)",
backgroundColor: "var(--dc-surface)",
boxShadow: "var(--dc-shadow-sm)"
},
children: /* @__PURE__ */ e(
ol,
{
dashboardFilters: t,
onAddFilter: _,
onAddTimeFilter: b,
onEditFilter: R,
onRemoveFilter: D,
selectedFilterId: l,
onFilterSelect: u
}
)
}
) : (
/* View Mode - Compact Mixpanel-style filter bar */
/* @__PURE__ */ e(
fl,
{
dashboardFilters: t,
schema: n,
isEditMode: !1,
onDashboardFiltersChange: a,
onAddFilter: _,
onEditFilter: R,
onRemoveFilter: D
}
)
),
r && p && f && /* @__PURE__ */ e(
rl,
{
filter: f,
schema: n,
dashboardConfig: s,
isOpen: p,
onSave: $,
onClose: A,
onDelete: () => D(f.id),
convertToMetaResponse: v
}
)
] });
};
function pl({
scaleFactor: t,
designWidth: r,
children: n
}) {
const [s, a] = V(0), c = Ce(null);
ve(() => {
if (!c.current) return;
const u = new ResizeObserver((d) => {
a(d[0]?.contentRect.height ?? 0);
});
return u.observe(c.current), a(c.current.offsetHeight || 0), () => u.disconnect();
}, []);
const l = s * t;
return /* @__PURE__ */ e(
"div",
{
className: "scaled-grid-container",
style: {
height: l > 0 ? l : "auto",
overflow: "hidden",
width: "100%"
},
children: /* @__PURE__ */ e(
"div",
{
ref: c,
className: "scaled-grid-inner",
style: {
transform: `scale(${t})`,
transformOrigin: "top left",
width: r
},
children: n
}
)
}
);
}
const gl = Q("refresh");
function bl(t) {
if (!t) return null;
let r = t.parentElement;
for (; r; ) {
const n = window.getComputedStyle(r), s = n.overflowY, a = n.overflowX, c = s === "auto" || s === "scroll" || a === "auto" || a === "scroll", l = r.scrollHeight > r.clientHeight || r.scrollWidth > r.clientWidth;
if (c && l)
return r;
if (r === document.body) break;
r = r.parentElement;
}
return null;
}
function xl({
config: t,
colorPalette: r,
dashboardFilters: n,
onPortletRefresh: s
}) {
const a = Ce({}), [c, l] = V(null), u = Ce(null), d = F((p) => {
u.current = p, p && l(bl(p));
}, []), f = ye(() => [...t.portlets].sort((p, m) => p.y !== m.y ? p.y - m.y : p.x - m.x), [t.portlets]), h = (p) => {
a.current[p]?.refresh(), s?.(p);
};
return /* @__PURE__ */ e(ss, { value: c, children: /* @__PURE__ */ e("div", { ref: d, className: "mobile-stacked-layout space-y-4 px-2", children: f.map((p) => {
const m = Math.max(300, p.h * 80), v = p.displayConfig?.hideHeader ? 0 : 40, C = m - v - 24;
return /* @__PURE__ */ o(
"div",
{
"data-portlet-id": p.id,
className: "bg-dc-surface border border-dc-border rounded-lg flex flex-col",
style: {
height: m,
boxShadow: "var(--dc-shadow-sm)"
},
children: [
!p.displayConfig?.hideHeader && /* @__PURE__ */ o("div", { className: "flex items-center justify-between px-3 py-2 border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg", children: [
/* @__PURE__ */ e("h3", { className: "font-semibold text-sm text-dc-text truncate flex-1", children: p.title }),
/* @__PURE__ */ e("div", { className: "flex items-center gap-1 shrink-0 ml-2", children: /* @__PURE__ */ e(
"button",
{
onClick: () => h(p.id),
className: "p-1 bg-transparent border-none rounded-sm text-dc-text-secondary cursor-pointer hover:bg-dc-surface-hover transition-colors",
title: "Refresh portlet data",
children: /* @__PURE__ */ e(gl, { style: { width: "16px", height: "16px", color: "currentColor" } })
}
) })
] }),
/* @__PURE__ */ e(
"div",
{
className: "px-2 py-3 overflow-visible flex flex-col",
style: { height: C },
children: /* @__PURE__ */ e(
Tr,
{
ref: (_) => {
a.current[p.id] = _;
},
query: p.query,
chartType: p.chartType,
chartConfig: p.chartConfig,
displayConfig: p.displayConfig,
dashboardFilters: n,
dashboardFilterMapping: p.dashboardFilterMapping,
eagerLoad: p.eagerLoad ?? t.eagerLoad ?? !1,
title: p.title,
height: C,
colorPalette: r
}
)
}
)
]
},
p.id
);
}) }) });
}
const yl = Q("measure"), vl = Q("refresh"), Kn = Q("edit"), wl = Q("check"), Nl = Q("delete"), Xn = Q("add"), Cl = Q("copy"), Zn = Q("filter"), kl = Q("desktop"), Dl = Q("segment"), Tl = Q("table");
function Sl(t) {
if (!t) return null;
let r = t.parentElement;
for (; r; ) {
const n = window.getComputedStyle(r), s = n.overflowY, a = n.overflowX, c = s === "auto" || s === "scroll" || a === "auto" || a === "scroll", l = r.scrollHeight > r.clientHeight || r.scrollWidth > r.clientWidth;
if (c && l)
return r;
if (r === document.body) break;
r = r.parentElement;
}
return null;
}
const br = {
cols: 12,
rowHeight: 80,
minW: 2,
minH: 2
}, jr = () => `row-${Date.now()}`, Al = (t) => ({
cols: t.grid?.cols ?? br.cols,
rowHeight: t.grid?.rowHeight ?? br.rowHeight,
minW: t.grid?.minW ?? br.minW,
minH: t.grid?.minH ?? br.minH
}), Ft = (t, r) => {
const n = t.length;
if (n === 0) return [];
const { cols: s, minW: a } = r, c = a * n;
if (c > s) {
const f = Math.floor(s / n), h = s % n;
return t.map((p, m) => ({
portletId: p,
w: f + (m < h ? 1 : 0)
}));
}
const l = s - c, u = Math.floor(l / n), d = l % n;
return t.map((f, h) => ({
portletId: f,
w: a + u + (h < d ? 1 : 0)
}));
}, qs = (t, r) => {
if (t.length === 0) return [];
const { cols: n, minW: s } = r, a = t.map((u) => ({
...u,
w: Math.max(s, u.w)
}));
let c = a.reduce((u, d) => u + d.w, 0);
if (c === n) return a;
if (c < n) {
let u = n - c, d = 0;
for (; u > 0; )
a[d % a.length].w += 1, u -= 1, d += 1;
return a;
}
let l = c - n;
for (let u = a.length - 1; u >= 0 && l > 0; u -= 1) {
const d = a[u], f = Math.max(0, d.w - s);
if (f === 0) continue;
const h = Math.min(f, l);
d.w -= h, l -= h;
}
return a;
}, Br = (t, r) => {
if (t.length === 0) return [];
const n = [...t].sort((a, c) => a.y !== c.y ? a.y - c.y : a.x - c.x), s = /* @__PURE__ */ new Map();
return n.forEach((a) => {
const c = s.get(a.y) ?? [];
c.push(a), s.set(a.y, c);
}), Array.from(s.entries()).sort(([a], [c]) => a - c).map(([a, c]) => {
const l = Math.max(
r.minH,
...c.map((d) => d.h)
), u = c.map((d) => d.id);
return {
id: `row-${a}`,
h: l,
columns: Ft(u, r)
};
});
}, xr = (t, r, n) => {
const s = new Set(r.map((a) => a.id));
return t.map((a) => ({
...a,
h: Math.max(n.minH, a.h),
columns: qs(
a.columns.filter((c) => s.has(c.portletId)),
n
)
})).filter((a) => a.columns.length > 0);
}, es = (t, r) => {
const n = new Map(r.map((l) => [l.id, l]));
let s = 0;
const a = [];
t.forEach((l) => {
let u = 0;
l.columns.forEach((d) => {
const f = n.get(d.portletId);
f && (a.push({
...f,
x: u,
y: s,
w: d.w,
h: l.h
}), u += d.w);
}), s += l.h;
});
const c = new Set(a.map((l) => l.id));
return r.forEach((l) => {
c.has(l.id) || a.push(l);
}), a;
};
function El({
config: t,
editable: r = !1,
dashboardFilters: n,
loadingComponent: s,
onConfigChange: a,
onPortletRefresh: c,
onSave: l,
colorPalette: u,
schema: d,
onDashboardFiltersChange: f,
dashboardModes: h
}) {
const { features: p } = Qt(), {
containerRef: m,
containerWidth: v,
displayMode: C,
scaleFactor: _,
isEditable: b,
designWidth: R
} = Ys(), D = h && h.length > 0 ? h : ["rows", "grid"], $ = D.includes("rows") ? "rows" : D[0] ?? "grid", A = t.layoutMode ?? "grid", w = D.includes(A) ? A : $, i = ye(() => Al(t), [t]), [g, x] = V(null), N = Ce(null), S = Ce(null), y = Ce(null), M = F((Y) => {
if (N.current = Y, m(Y), Y) {
const re = Sl(Y);
x(re), S.current = re;
}
}, [m]), E = C === "desktop" ? v : R, [T, j] = V(null), q = Ce(null), I = Ce(null), [K, U] = V(!1), ke = Ce({}), De = Ce({}), [Pe, B] = V(!1), [se, Te] = V([]), [H, ee] = V(!1), [le, be] = V(null), L = r && H && b && !le, te = r && H && b && !le && D.length > 1;
ve(() => {
(!H || !b) && le && be(null);
}, [H, b, le]), ve(() => {
!b && H && ee(!1);
}, [b, H]);
const Ne = Ra(S, {
threshold: 20,
debounceMs: 150,
container: g
// State dependency to trigger re-init when container found
}), Ve = Ma(y, {
threshold: 80,
debounceMs: 100,
containerRef: S,
container: g
// State dependency to trigger re-init when container found
}), [rt, Fe] = V(!1), [ue, _e] = V(null), [G, X] = V(!1), [ae, qe] = V(null), [je, nt] = V({});
ve(() => {
q.current = T;
}, [T]);
const Ie = ye(() => {
if (w !== "rows") return [];
const Y = T ?? t.rows ?? Br(t.portlets, i);
return xr(Y, t.portlets, i);
}, [w, T, t.rows, t.portlets, i]), Be = F(async (Y, re = !0, de) => {
if (!a) return;
const oe = de ?? t.portlets, fe = xr(Y, oe, i), $e = es(fe, oe), pe = {
...t,
layoutMode: "rows",
rows: fe,
portlets: $e
};
if (j(null), a(pe), re && l)
try {
await l(pe);
} catch (Ae) {
console.error("Auto-save failed after row layout change:", Ae);
}
}, [t, i, a, l]);
ve(() => {
const Y = setTimeout(() => {
B(!0);
const re = t.portlets.map((de) => ({
i: de.id,
x: de.x,
y: de.y,
w: de.w,
h: de.h
}));
Te(re);
}, 200);
return () => clearTimeout(Y);
}, [t.portlets]), ve(() => {
const Y = (re) => {
re.key === "Escape" && le && be(null);
};
return window.addEventListener("keydown", Y), () => {
window.removeEventListener("keydown", Y);
};
}, [le]);
const ot = F((Y) => {
if (!Pe || se.length === 0) return !1;
for (const re of Y) {
const de = se.find((oe) => oe.i === re.i);
if (de && (de.x !== re.x || de.y !== re.y || de.w !== re.w || de.h !== re.h))
return !0;
}
return !1;
}, [Pe, se]), at = F((Y) => {
}, []), bt = F(async (Y, re, de, oe, fe, $e) => {
if (!r || !H || !l || !Pe) return;
const pe = [...Y];
if (!ot(pe))
return;
const Ae = t.portlets.map((Je) => {
const Ke = pe.find((ut) => ut.i === Je.id);
return Ke ? {
...Je,
x: Ke.x,
y: Ke.y,
w: Ke.w,
h: Ke.h
} : Je;
}), Ue = {
...t,
portlets: Ae,
layouts: {
...t.layouts,
lg: pe
// Only save the large layout, let RGL handle responsive adjustments
}
};
Te(pe), a?.(Ue);
try {
await l(Ue);
} catch (Je) {
console.error("Auto-save failed after drag:", Je);
}
}, [t.portlets, t.layouts, r, H, a, l, Pe, ot]), ft = F(async (Y, re, de, oe, fe, $e) => {
if (!r || !H || !a || !Pe) return;
const pe = [...Y];
if (!ot(pe))
return;
const Ae = t.portlets.map((Je) => {
const Ke = pe.find((ut) => ut.i === Je.id);
return Ke ? {
...Je,
x: Ke.x,
y: Ke.y,
w: Ke.w,
h: Ke.h
} : Je;
}), Ue = {
...t,
portlets: Ae,
layouts: {
...t.layouts,
lg: pe
// Only save the large layout, let RGL handle responsive adjustments
}
};
if (Te(pe), a(Ue), l)
try {
await l(Ue);
} catch (Je) {
console.error("Auto-save failed after resize:", Je);
}
}, [t.portlets, t.layouts, r, H, a, l, Pe, ot]), Dt = F(async (Y) => {
if (!a || Y === w || !te || !D.includes(Y)) return;
const re = xr(
t.rows && t.rows.length > 0 ? t.rows : Br(t.portlets, i),
t.portlets,
i
), de = es(re, t.portlets), oe = {
...t,
layoutMode: Y,
rows: re,
portlets: de
};
if (j(null), a(oe), l)
try {
await l(oe);
} catch (fe) {
console.error("Auto-save failed after layout mode switch:", fe);
}
}, [D, te, t, i, w, a, l]), Qe = F((Y, re) => {
if (!L) return;
re.preventDefault();
const de = re.clientY, oe = Ie.map((pe) => ({
...pe,
columns: pe.columns.map((Ae) => ({ ...Ae }))
})), fe = (pe) => {
const Ae = pe.clientY - de, Ue = Math.round(Ae / i.rowHeight), Je = oe.map((Ke, ut) => ut !== Y ? Ke : {
...Ke,
h: Math.max(i.minH, Ke.h + Ue)
});
j(Je);
}, $e = () => {
document.removeEventListener("mousemove", fe), document.removeEventListener("mouseup", $e);
const pe = q.current ?? oe;
Be(pe);
};
document.addEventListener("mousemove", fe), document.addEventListener("mouseup", $e);
}, [L, i, Ie, Be]), Ze = F((Y, re, de) => {
if (!L) return;
de.preventDefault();
const oe = de.clientX, fe = Ie.map((gt) => ({
...gt,
columns: gt.columns.map((Nt) => ({ ...Nt }))
})), $e = fe[Y], pe = $e?.columns[re], Ae = $e?.columns[re + 1];
if (!$e || !pe || !Ae) return;
const Ke = (E - ($e.columns.length - 1) * 16) / i.cols, ut = (gt) => {
const Nt = gt.clientX - oe, jt = Math.round(Nt / Ke);
if (jt === 0) {
j(fe);
return;
}
let J = pe.w + jt, ge = Ae.w - jt;
if (J < i.minW) {
const P = i.minW - J;
J = i.minW, ge -= P;
}
if (ge < i.minW) {
const P = i.minW - ge;
ge = i.minW, J -= P;
}
if (J < i.minW || ge < i.minW) return;
const O = fe.map((P, W) => {
if (W !== Y) return P;
const Z = P.columns.map((ie, xe) => xe === re ? { ...ie, w: J } : xe === re + 1 ? { ...ie, w: ge } : ie);
return {
...P,
columns: qs(Z, i)
};
});
j(O);
}, mt = () => {
document.removeEventListener("mousemove", ut), document.removeEventListener("mouseup", mt);
const gt = q.current ?? fe;
Be(gt);
};
document.addEventListener("mousemove", ut), document.addEventListener("mouseup", mt);
}, [L, i, E, Ie, Be]), et = F((Y, re, de, oe) => {
L && (I.current = { rowIndex: Y, colIndex: re, portletId: de }, U(!0), oe.dataTransfer.effectAllowed = "move", oe.dataTransfer.setData("text/plain", de));
}, [L]), xt = F(() => {
I.current = null, U(!1);
}, []), Tt = F((Y, re) => {
const de = I.current;
if (!de) return;
const oe = Ie.map((mt) => ({
...mt,
columns: mt.columns.map((gt) => ({ ...gt }))
})), fe = de.rowIndex, $e = oe[fe];
if (!$e) return;
const [pe] = $e.columns.splice(de.colIndex, 1);
let Ae = !1;
$e.columns.length === 0 && (oe.splice(fe, 1), Ae = !0);
let Ue = Y;
Ae && fe < Y && (Ue -= 1);
const Je = oe[Ue];
if (!Je) return;
let Ke = re ?? Je.columns.length;
!Ae && fe === Ue && re !== null && re > de.colIndex && (Ke -= 1), Je.columns.splice(Ke, 0, pe), (fe !== Ue || Ae) && (Ae || (oe[fe] = {
...oe[fe],
columns: Ft(
oe[fe].columns.map((mt) => mt.portletId),
i
)
}), oe[Ue] = {
...oe[Ue],
columns: Ft(
oe[Ue].columns.map((mt) => mt.portletId),
i
)
}), Be(oe);
}, [i, Ie, Be]), $t = F((Y) => {
const re = I.current;
if (!re) return;
const de = Ie.map((pe) => ({
...pe,
columns: pe.columns.map((Ae) => ({ ...Ae }))
})), oe = de[re.rowIndex];
if (!oe) return;
const [fe] = oe.columns.splice(re.colIndex, 1);
oe.columns.length === 0 ? de.splice(re.rowIndex, 1) : oe.columns = Ft(
oe.columns.map((pe) => pe.portletId),
i
);
const $e = {
id: jr(),
h: Math.max(i.minH, 5),
columns: Ft([fe.portletId], i)
};
de.splice(Y, 0, $e), Be(de);
}, [i, Ie, Be]), St = F((Y) => {
const re = De.current[Y];
re && re.refresh && re.refresh(), c && c(Y);
}, [c]), st = F(() => {
_e(null), Fe(!0);
}, []), dt = F((Y) => {
_e(Y), Fe(!0);
}, []), ht = F(async (Y) => {
if (!a) return;
let re = [...t.portlets], de = !1, oe = null;
if (ue) {
const fe = re.findIndex(($e) => $e.id === ue.id);
fe !== -1 && (re[fe] = Y);
} else {
de = !0;
const fe = {
...Y,
id: `portlet-${Date.now()}`,
x: 0,
y: 0
};
oe = fe.id;
const $e = re.map((Ae) => ({ i: Ae.id, x: Ae.x, y: Ae.y, w: Ae.w, h: Ae.h }));
let pe = 0;
$e.forEach((Ae) => {
Ae.y + Ae.h > pe && (pe = Ae.y + Ae.h);
}), fe.y = pe, re.push(fe);
}
if (w === "rows") {
const fe = Ie.length > 0 ? Ie.map((pe) => ({
...pe,
columns: pe.columns.map((Ae) => ({ ...Ae }))
})) : xr(
t.rows ?? Br(t.portlets, i),
re,
i
), $e = de && oe ? [
...fe,
{
id: jr(),
h: Math.max(i.minH, 5),
columns: Ft([oe], i)
}
] : fe;
await Be($e, !0, re);
} else {
const fe = {
...t,
portlets: re
};
if (a(fe), l)
try {
await l(fe);
} catch ($e) {
console.error("Auto-save failed:", $e);
}
}
Fe(!1), _e(null), de && oe && setTimeout(() => {
const fe = () => {
let $e = ke.current[oe];
return $e || ($e = document.querySelector(`[data-portlet-id="${oe}"]`)), $e ? ($e.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "nearest"
}), !0) : !1;
};
fe() || setTimeout(() => {
fe() || setTimeout(() => {
fe();
}, 300);
}, 200);
}, 200);
}, [t, ue, i, w, a, l, Ie, Be]), It = F(async (Y) => {
if (a && window.confirm("Are you sure you want to delete this portlet?")) {
const re = t.portlets.filter((de) => de.id !== Y);
if (w === "rows") {
const de = Ie.map((oe) => ({
...oe,
columns: oe.columns.filter((fe) => fe.portletId !== Y)
})).filter((oe) => oe.columns.length > 0).map((oe) => ({
...oe,
columns: Ft(
oe.columns.map((fe) => fe.portletId),
i
)
}));
await Be(de, !0, re);
} else {
const de = {
...t,
portlets: re
};
if (a(de), l)
try {
await l(de);
} catch (oe) {
console.error("Auto-save failed:", oe);
}
}
}
}, [t, i, w, a, l, Ie, Be]), Pt = F(async (Y) => {
if (!a) return;
const re = t.portlets.find((pe) => pe.id === Y);
if (!re) return;
const de = {
...re,
id: `portlet-${Date.now()}`,
title: `${re.title} Duplicated`,
x: 0,
y: 0
}, oe = t.portlets.map((pe) => ({ i: pe.id, x: pe.x, y: pe.y, w: pe.w, h: pe.h }));
let fe = 0;
oe.forEach((pe) => {
pe.y + pe.h > fe && (fe = pe.y + pe.h);
}), de.y = fe;
const $e = [...t.portlets, de];
if (w === "rows") {
const Ae = [
...Ie.map((Ue) => ({
...Ue,
columns: Ue.columns.map((Je) => ({ ...Je }))
})),
{
id: jr(),
h: Math.max(i.minH, 5),
columns: Ft([de.id], i)
}
];
await Be(Ae, !0, $e);
} else {
const pe = {
...t,
portlets: $e
};
if (a(pe), l)
try {
await l(pe);
} catch (Ae) {
console.error("Auto-save failed:", Ae);
}
}
setTimeout(() => {
const pe = () => {
let Ae = ke.current[de.id];
return Ae || (Ae = document.querySelector(`[data-portlet-id="${de.id}"]`)), Ae ? (Ae.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "nearest"
}), !0) : !1;
};
pe() || setTimeout(() => {
pe() || setTimeout(() => {
pe();
}, 300);
}, 200);
}, 200);
}, [t, i, w, a, l, Ie, Be]), pt = F(async (Y) => {
if (!a) return;
const re = {
...t,
colorPalette: Y
};
if (a(re), l)
try {
await l(re);
} catch (de) {
console.error("Auto-save failed:", de);
}
}, [t, a, l]), k = F((Y) => {
qe(Y), X(!0);
}, []), z = F(async (Y) => {
if (!a || !ae) return;
const re = t.portlets.map((oe) => oe.id === ae.id ? {
...oe,
dashboardFilterMapping: Y
} : oe), de = {
...t,
portlets: re
};
if (a(de), l)
try {
await l(de);
} catch (oe) {
console.error("Auto-save failed:", oe);
}
}, [t, ae, a, l]), ne = F((Y, re) => {
nt((de) => ({
...de,
[Y]: re
}));
}, []), Ee = F((Y, re) => {
ke.current[Y] = re;
}, []), ze = F((Y, re) => {
De.current[Y] = re;
}, []), Ge = ye(() => ({
RefreshIcon: vl,
EditIcon: Kn,
DeleteIcon: Nl,
CopyIcon: Cl,
FilterIcon: Zn
}), []), he = F(async (Y, re) => {
if (!a) return;
const de = t.portlets.map((fe) => {
if (fe.id === Y) {
const $e = fe.dashboardFilterMapping || [], pe = $e.includes(re);
return {
...fe,
dashboardFilterMapping: pe ? $e.filter((Ae) => Ae !== re) : [...$e, re]
};
}
return fe;
}), oe = {
...t,
portlets: de
};
if (a(oe), l)
try {
await l(oe);
} catch (fe) {
console.error("Auto-save failed:", fe);
}
}, [t, a, l]), me = F((Y) => {
be((re) => re === Y ? null : Y);
}, []), Se = F(async (Y) => {
if (!a) return;
const re = t.portlets.map((oe) => {
const fe = oe.dashboardFilterMapping || [];
return fe.includes(Y) ? oe : {
...oe,
dashboardFilterMapping: [...fe, Y]
};
}), de = {
...t,
portlets: re
};
if (a(de), l)
try {
await l(de);
} catch (oe) {
console.error("Auto-save failed:", oe);
}
}, [t, a, l]), tt = le ? n?.find((Y) => Y.id === le) : null, Ye = F((Y, re, de) => /* @__PURE__ */ e(
La,
{
portlet: Y,
editable: r,
isEditMode: H,
selectedFilterId: le,
debugData: je[Y.id],
dashboardFilters: n,
configEagerLoad: t.eagerLoad,
loadingComponent: s,
colorPalette: u,
containerProps: re,
headerProps: de,
onToggleFilter: he,
onRefresh: St,
onDuplicate: Pt,
onEdit: dt,
onDelete: It,
onOpenFilterConfig: k,
onDebugDataReady: ne,
setPortletRef: Ee,
setPortletComponentRef: ze,
icons: Ge
}
), [
r,
H,
le,
je,
n,
t.eagerLoad,
s,
u,
he,
St,
Pt,
dt,
It,
k,
ne,
Ee,
ze,
Ge
]);
if (!t.portlets || t.portlets.length === 0)
return /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e("div", { className: "flex justify-center items-center min-h-[50vh]", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
/* @__PURE__ */ e(yl, { style: { width: "64px", height: "64px", color: "var(--dc-text-muted)", margin: "0 auto 16px auto" } }),
/* @__PURE__ */ e("h3", { className: "text-lg font-semibold mb-2 text-dc-text", children: "No Portlets" }),
/* @__PURE__ */ e("p", { className: "text-sm text-dc-text-secondary mb-4", children: "Add your first portlet to start visualizing your data" }),
r && /* @__PURE__ */ o(
"button",
{
onClick: st,
className: "inline-flex items-center px-4 py-2 border border-dc-border bg-dc-surface rounded-md focus:outline-hidden focus:ring-2",
style: {
color: "var(--dc-primary)",
borderColor: "var(--dc-primary)"
},
onMouseEnter: (Y) => Y.currentTarget.style.backgroundColor = "var(--dc-surface-hover)",
onMouseLeave: (Y) => Y.currentTarget.style.backgroundColor = "var(--dc-surface)",
children: [
/* @__PURE__ */ e(Xn, { className: "w-5 h-5 mr-2" }),
"Add Portlet"
]
}
)
] }) }),
p.useAnalysisBuilder ? /* @__PURE__ */ e(
Pn,
{
isOpen: rt,
onClose: () => {
Fe(!1), _e(null);
},
onSave: ht,
portlet: ue,
title: ue ? "Edit Portlet" : "Add New Portlet",
submitText: ue ? "Update Portlet" : "Add Portlet",
colorPalette: u
}
) : /* @__PURE__ */ e(
qn,
{
isOpen: rt,
onClose: () => {
Fe(!1), _e(null);
},
onSave: ht,
portlet: ue,
title: ue ? "Edit Portlet" : "Add New Portlet",
submitText: ue ? "Update Portlet" : "Add Portlet",
colorPalette: u
}
)
] });
const At = t.portlets.map((Y) => ({
i: Y.id,
x: Y.x,
y: Y.y,
w: Y.w,
h: Y.h,
minW: i.minW,
minH: i.minH,
// 2 rows at 80px = 160px minimum
// Only enable drag/resize in edit mode
isDraggable: L,
isResizable: L,
...L ? { resizeHandles: ["s", "w", "e", "n", "se", "sw", "ne", "nw"] } : {}
})), zt = w === "rows" ? /* @__PURE__ */ e(
Fa,
{
rows: Ie,
portlets: t.portlets,
gridSettings: i,
gridWidth: E,
canEdit: L,
isDragging: K,
onRowResize: Qe,
onColumnResize: Ze,
onPortletDragStart: et,
onPortletDragEnd: xt,
onRowDrop: Tt,
onNewRowDrop: $t,
renderPortlet: Ye
}
) : /* @__PURE__ */ e(
pa,
{
className: "layout",
layout: At,
onLayoutChange: at,
onDragStop: bt,
onResizeStop: ft,
width: E,
gridConfig: {
cols: i.cols,
rowHeight: i.rowHeight,
margin: [16, 16],
containerPadding: [0, 0]
},
dragConfig: {
enabled: L,
handle: ".portlet-drag-handle"
},
resizeConfig: {
enabled: L,
handles: ["s", "w", "e", "n", "se", "sw", "ne", "nw"],
// Invisible but functional resize handles
handleComponent: (Y, re) => /* @__PURE__ */ e(
"div",
{
ref: re,
className: `react-resizable-handle react-resizable-handle-${Y}`,
style: { opacity: 0 }
}
)
},
compactor: ga,
children: t.portlets.filter((Y) => Y && Y.id).map((Y) => /* @__PURE__ */ e("div", { children: Ye(Y) }, Y.id))
}
);
return /* @__PURE__ */ e(ss, { value: g, children: /* @__PURE__ */ o("div", { ref: M, className: "dashboard-grid-container w-full", style: { maxWidth: "100%", overflow: "hidden" }, children: [
r && p.editToolbar !== "floating" && /* @__PURE__ */ o(
"div",
{
ref: y,
className: `mb-4 flex justify-between items-center sticky top-0 z-10 px-4 py-4 bg-dc-surface-tertiary border border-dc-border rounded-lg transition-all duration-200 ${Ne ? "border-b" : ""}`,
style: {
boxShadow: Ne ? "var(--dc-shadow-md)" : "var(--dc-shadow-sm)"
},
children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-4", children: [
/* @__PURE__ */ o(
"button",
{
onClick: () => b && ee(!H),
disabled: !b,
className: `inline-flex items-center px-4 py-2 text-sm font-medium rounded-md transition-colors focus:outline-hidden focus:ring-2 focus:ring-offset-2 ${b ? H ? "bg-dc-surface-secondary border border-dc-border hover:bg-dc-surface-hover" : "bg-dc-surface border border-dc-border hover:bg-dc-surface-hover" : "opacity-50 cursor-not-allowed bg-dc-surface-secondary border border-dc-border"}`,
style: {
color: b ? "var(--dc-primary)" : "var(--dc-text-muted)",
borderColor: b ? H ? "var(--dc-border)" : "var(--dc-primary)" : "var(--dc-border)"
},
children: [
H ? /* @__PURE__ */ e(wl, { className: "w-4 h-4 mr-1.5" }) : /* @__PURE__ */ e(Kn, { className: "w-4 h-4 mr-1.5" }),
H ? "Finish Editing" : "Edit"
]
}
),
H && D.length > 1 && /* @__PURE__ */ o("div", { className: "inline-flex rounded-md border border-dc-border overflow-hidden whitespace-nowrap", children: [
/* @__PURE__ */ o(
"button",
{
onClick: () => Dt("grid"),
disabled: !te,
className: `inline-flex items-center gap-2 whitespace-nowrap px-3 py-1.5 text-sm font-medium transition-colors ${w === "grid" ? "bg-dc-surface-secondary text-dc-text shadow-inner" : "bg-dc-surface text-dc-text-secondary hover:bg-dc-surface-hover"} ${te ? "" : "cursor-not-allowed opacity-50"}`,
children: [
/* @__PURE__ */ e(Dl, { className: "w-4 h-4 shrink-0" }),
"Grid"
]
}
),
/* @__PURE__ */ o(
"button",
{
onClick: () => Dt("rows"),
disabled: !te,
className: `inline-flex items-center gap-2 whitespace-nowrap px-3 py-1.5 text-sm font-medium transition-colors ${w === "rows" ? "bg-dc-surface-secondary text-dc-text shadow-inner" : "bg-dc-surface text-dc-text-secondary hover:bg-dc-surface-hover"} ${te ? "" : "cursor-not-allowed opacity-50"}`,
children: [
/* @__PURE__ */ e(Tl, { className: "w-4 h-4 shrink-0" }),
"Rows"
]
}
)
] }),
!b && /* @__PURE__ */ o("div", { className: "flex items-center gap-2 text-sm text-dc-text-secondary", children: [
/* @__PURE__ */ e(kl, { className: "w-4 h-4" }),
/* @__PURE__ */ e("span", { children: "Desktop view required for editing" })
] }),
H && b && /* @__PURE__ */ e("p", { className: "hidden md:block text-sm text-dc-text-secondary", children: "Drag • Resize • Auto-save" })
] }),
H && /* @__PURE__ */ o("div", { className: "flex items-center gap-3", children: [
/* @__PURE__ */ e(
Ns,
{
currentPalette: t.colorPalette,
onPaletteChange: pt,
className: "shrink-0"
}
),
/* @__PURE__ */ o(
"button",
{
onClick: st,
className: "inline-flex items-center px-4 py-2 text-sm font-medium border rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 border-dc-border bg-dc-surface hover:bg-dc-surface-hover",
style: {
color: "var(--dc-primary)",
borderColor: "var(--dc-primary)"
},
children: [
/* @__PURE__ */ e(Xn, { className: "w-5 h-5 mr-2" }),
"Add Portlet"
]
}
)
] })
]
}
),
r && p.editToolbar !== "top" && C === "desktop" && /* @__PURE__ */ e(
Ua,
{
isEditBarVisible: p.editToolbar === "floating" ? !1 : Ve,
position: p.floatingToolbarPosition || "right",
isEditMode: H,
onEditModeToggle: () => b && ee(!H),
layoutMode: w,
onLayoutModeChange: Dt,
allowedModes: D,
canChangeLayoutMode: te,
currentPalette: t.colorPalette || "default",
onPaletteChange: pt,
onAddPortlet: st
}
),
/* @__PURE__ */ e(
hl,
{
dashboardFilters: n || [],
editable: r,
schema: d || null,
dashboardConfig: t,
onDashboardFiltersChange: f || (() => {
}),
onSaveFilters: l ? async (Y) => {
const re = {
...t,
filters: Y
};
await l(re);
} : void 0,
selectedFilterId: le,
onFilterSelect: me,
isEditMode: H
}
),
le && tt && /* @__PURE__ */ e(
"div",
{
className: "mb-4 px-4 py-3 rounded-md border-2 transition-all",
style: {
backgroundColor: "var(--dc-primary)",
borderColor: "var(--dc-primary)",
color: "white"
},
children: /* @__PURE__ */ o("div", { className: "flex items-center justify-between flex-wrap gap-2", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 flex-wrap", children: [
/* @__PURE__ */ e(Zn, { className: "w-5 h-5 shrink-0" }),
/* @__PURE__ */ o("span", { className: "font-medium", children: [
"Filter Selection Mode - Click portlets to toggle '",
tt.label,
"'"
] }),
/* @__PURE__ */ e("span", { className: "text-sm opacity-90 hidden sm:inline", children: "• Press ESC to exit" })
] }),
/* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ e(
"button",
{
onClick: () => Se(le),
className: "px-3 py-1 rounded-md transition-colors text-sm font-medium",
style: {
backgroundColor: "rgba(255, 255, 255, 0.2)",
color: "white"
},
onMouseEnter: (Y) => Y.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.3)",
onMouseLeave: (Y) => Y.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)",
children: "Select All"
}
),
/* @__PURE__ */ e(
"button",
{
onClick: () => be(null),
className: "px-3 py-1 rounded-md transition-colors text-sm font-medium",
style: {
backgroundColor: "rgba(255, 255, 255, 0.2)",
color: "white"
},
onMouseEnter: (Y) => Y.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.3)",
onMouseLeave: (Y) => Y.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)",
children: "Exit"
}
)
] })
] })
}
),
C === "mobile" ? /* @__PURE__ */ e(
xl,
{
config: t,
colorPalette: u,
dashboardFilters: n,
onPortletRefresh: St
}
) : C === "scaled" ? /* @__PURE__ */ e(pl, { scaleFactor: _, designWidth: R, children: zt }) : zt,
p.useAnalysisBuilder ? /* @__PURE__ */ e(
Pn,
{
isOpen: rt,
onClose: () => {
Fe(!1), _e(null);
},
onSave: ht,
portlet: ue,
title: ue ? "Edit Portlet" : "Add New Portlet",
submitText: ue ? "Update Portlet" : "Add Portlet",
colorPalette: u
}
) : /* @__PURE__ */ e(
qn,
{
isOpen: rt,
onClose: () => {
Fe(!1), _e(null);
},
onSave: ht,
portlet: ue,
title: ue ? "Edit Portlet" : "Add New Portlet",
submitText: ue ? "Update Portlet" : "Add Portlet",
colorPalette: u
}
),
/* @__PURE__ */ e(
Ec,
{
isOpen: G,
onClose: () => {
X(!1), qe(null);
},
dashboardFilters: n || [],
currentMapping: ae?.dashboardFilterMapping || [],
onSave: z,
portletTitle: ae?.title || ""
}
)
] }) });
}
function Hl({
config: t,
editable: r = !1,
dashboardFilters: n,
loadingComponent: s,
onConfigChange: a,
onSave: c,
onDirtyStateChange: l
}) {
const { meta: u, dashboardModes: d } = Qt(), f = Ce(t), h = Ce(!1), p = ye(() => {
const b = t.filters || [], R = n || [];
if (R.length === 0)
return b;
if (b.length === 0)
return R;
const D = b.map((w) => {
const i = R.find((g) => g.id === w.id);
return i ? {
...w,
// Preserve id, label, isUniversalTime from config
filter: i.filter
// Use filter values from prop override
} : w;
}), $ = new Set(b.map((w) => w.id)), A = R.filter((w) => !$.has(w.id));
return [...D, ...A];
}, [t.filters, n]), m = F(async (b) => {
if (h.current) {
l && l(!0);
try {
c && await c(b), f.current = b, l && l(!1);
} catch (R) {
throw console.error("Save failed:", R), R;
}
}
}, [c, l]), v = F((b) => {
a && a(b);
const R = JSON.stringify(b), D = JSON.stringify(f.current);
R !== D && (h.current = !0, l && l(!0));
}, [a, l]), C = F((b) => {
if (!n || n.length === 0) {
const R = {
...t,
filters: b
};
v(R);
} else
console.warn("Dashboard filters are controlled via props - config changes ignored");
}, [t, n, v]), _ = ye(() => {
const b = t.colorPalette;
return Wr(b);
}, [t.colorPalette]);
return /* @__PURE__ */ e("div", { className: "w-full", children: /* @__PURE__ */ e(
El,
{
config: t,
editable: r,
dashboardFilters: p,
loadingComponent: s,
onConfigChange: v,
onSave: m,
colorPalette: _,
schema: u,
dashboardModes: d,
onDashboardFiltersChange: C
}
) });
}
function zl({
portlet: t,
editable: r = !1,
onEdit: n,
onDelete: s,
onRefresh: a
}) {
const [c, l] = V(null), u = F((d) => {
l(d);
}, []);
return /* @__PURE__ */ o("div", { className: "bg-dc-surface border border-dc-border rounded-lg flex flex-col h-full", style: { boxShadow: "var(--dc-shadow-sm)" }, children: [
/* @__PURE__ */ o("div", { className: "flex items-center justify-between border-b border-dc-border shrink-0 bg-dc-surface-secondary rounded-t-lg px-3 py-2 md:px-6 md:py-3", children: [
/* @__PURE__ */ o("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
/* @__PURE__ */ e("h3", { className: "font-semibold text-sm truncate text-dc-text", children: t.title }),
c && /* @__PURE__ */ e(
us,
{
chartConfig: c.chartConfig,
displayConfig: c.displayConfig,
queryObject: c.queryObject,
data: c.data,
chartType: c.chartType,
cacheInfo: c.cacheInfo
}
)
] }),
/* @__PURE__ */ e("div", { className: "flex items-center gap-2 ml-4", children: r && /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"button",
{
onClick: () => a?.(t.id),
className: "p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary",
title: "Refresh",
children: /* @__PURE__ */ e("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: () => n?.(t),
className: "p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary",
title: "Edit",
children: /* @__PURE__ */ e("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: () => s?.(t.id),
className: "p-1.5 rounded-sm text-dc-danger",
style: { backgroundColor: "transparent" },
onMouseEnter: (d) => d.currentTarget.style.backgroundColor = "var(--dc-danger-bg)",
onMouseLeave: (d) => d.currentTarget.style.backgroundColor = "transparent",
title: "Delete",
children: /* @__PURE__ */ e("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })
}
)
] }) })
] }),
/* @__PURE__ */ e("div", { className: "px-2 py-3 md:px-4 md:pt-6 md:pb-4 flex-1 min-h-0", children: /* @__PURE__ */ e(
Tr,
{
query: t.query,
chartType: t.chartType,
chartConfig: t.chartConfig,
displayConfig: t.displayConfig,
title: t.title,
height: "100%",
onDebugDataReady: u
}
) })
] });
}
function Gl({
isOpen: t,
onClose: r,
onSave: n,
title: s,
submitText: a,
initialName: c = "",
initialDescription: l = ""
}) {
const [u, d] = V(""), [f, h] = V(""), [p, m] = V(!1);
ve(() => {
t && (d(c), h(l));
}, [t, c, l]);
const v = async (b) => {
if (b.preventDefault(), !!u.trim()) {
m(!0);
try {
await n({
name: u.trim(),
description: f.trim() || void 0
}), C();
} catch {
} finally {
m(!1);
}
}
}, C = () => {
d(""), h(""), m(!1), r();
}, _ = /* @__PURE__ */ o(Oe, { children: [
/* @__PURE__ */ e(
"button",
{
type: "button",
onClick: C,
disabled: p,
className: "px-4 py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border border-dc-border rounded-md hover:bg-dc-surface-hover disabled:opacity-50",
children: "Cancel"
}
),
/* @__PURE__ */ e(
"button",
{
type: "submit",
form: "dashboard-form",
disabled: p || !u.trim(),
className: "px-4 py-2 text-sm font-medium text-white bg-dc-primary border border-transparent rounded-md hover:bg-dc-primary-hover disabled:opacity-50 disabled:cursor-not-allowed",
children: p ? "Saving..." : a
}
)
] });
return /* @__PURE__ */ e(
Yr,
{
isOpen: t,
onClose: C,
title: s,
size: "fullscreen-mobile",
footer: _,
children: /* @__PURE__ */ o("form", { id: "dashboard-form", onSubmit: v, className: "space-y-4 w-full", children: [
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("label", { htmlFor: "dashboard-name", className: "block text-sm font-medium text-dc-text-secondary mb-1", children: "Dashboard Name" }),
/* @__PURE__ */ e(
"input",
{
type: "text",
id: "dashboard-name",
value: u,
onChange: (b) => d(b.target.value),
className: "w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary",
placeholder: "Enter dashboard name...",
required: !0,
autoFocus: !0
}
)
] }),
/* @__PURE__ */ o("div", { children: [
/* @__PURE__ */ e("label", { htmlFor: "dashboard-description", className: "block text-sm font-medium text-dc-text-secondary mb-1", children: "Description (optional)" }),
/* @__PURE__ */ e(
"textarea",
{
id: "dashboard-description",
rows: 3,
value: f,
onChange: (b) => h(b.target.value),
className: "w-full px-3 py-2 border border-dc-border rounded-md bg-dc-surface text-dc-text focus:outline-none focus:ring-2 focus:ring-dc-primary focus:border-dc-primary",
placeholder: "Enter description..."
}
)
] })
] })
}
);
}
export {
Tr as A,
El as D,
Kr as H,
Yr as M,
zl as P,
Os as Q,
Hl as a,
qn as b,
Pn as c,
Gl as d,
tn as e,
gc as f,
bc as g,
xc as h,
yc as i,
Ql as j,
Ul as k,
Ra as l,
Ma as m,
yr as n,
$a as o,
os as p,
Ta as q,
ka as r,
Da as s,
jl as t,
cs as u,
vc as v,
ql as w,
Pl as x,
Bl as y,
Vl as z
};
//# sourceMappingURL=components-BGWiuXqQ.js.map