drizzle-cube
Version:
Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.
19,212 lines • 688 kB
JavaScript
import { jsxs as d, jsx as r, Fragment as Ce } from "react/jsx-runtime";
import * as Vt from "react";
import bt, { useMemo as V, useCallback as E, useState as ee, Component as aa, forwardRef as Ln, useRef as ge, useEffect as he, useImperativeHandle as Dr, createContext as ia, useContext as sn, memo as Ge } from "react";
import { a as Tr, _ as Pn, m as ti, $ as kr, t as ni, h as ri, c as an, a1 as si, z as q, i as ai, L as ii, a2 as Dn, a3 as Tn, o as oi, H as on, J as kn, a4 as dt, a5 as li, a6 as ci, a7 as di, a8 as ui, a9 as fi, aa as mi, ab as hi, ac as pi, ad as gi, ae as yi, af as bi, ag as xi, ah as vi, ai as wi, aj as Ni, ak as Ci, al as Si, am as Di, an as Ti, k as oa, b as la } from "./charts-DzHumCCp.js";
import { useScrollContainer as ki, ScrollContainerProvider as ca } from "../providers.js";
import { u as Ai, i as da, L as ur, b as ua } from "./charts-DwU4Ekjc.js";
import { l as fa, n as fr, s as Mi, u as ma, a as ha, o as Ii, p as Ei, q as Dt, d as Fi, r as Ri, t as _i, w as Ar, x as mr, y as Mr, D as Ht, z as Ot, F as qn, A as Oi, B as $i, C as Li } from "./hooks-BJbBseyx.js";
import Pi, { verticalCompactor as qi } from "react-grid-layout";
import { createPortal as Bi } from "react-dom";
var hr = /* @__PURE__ */ new Map(), mn = /* @__PURE__ */ new WeakMap(), Xr = 0, Qi;
function ji(e) {
return e ? (mn.has(e) || (Xr += 1, mn.set(e, Xr.toString())), mn.get(e)) : "0";
}
function Ki(e) {
return Object.keys(e).sort().filter(
(t) => e[t] !== void 0
).map((t) => `${t}_${t === "root" ? ji(e.root) : e[t]}`).toString();
}
function Vi(e) {
const t = Ki(e);
let n = hr.get(t);
if (!n) {
const s = /* @__PURE__ */ new Map();
let a;
const i = new IntersectionObserver((o) => {
o.forEach((c) => {
var l;
const u = c.isIntersecting && a.some((h) => c.intersectionRatio >= h);
e.trackVisibility && typeof c.isVisible > "u" && (c.isVisible = u), (l = s.get(c.target)) == null || l.forEach((h) => {
h(u, c);
});
});
}, e);
a = i.thresholds || (Array.isArray(e.threshold) ? e.threshold : [e.threshold || 0]), n = {
id: t,
observer: i,
elements: s
}, hr.set(t, n);
}
return n;
}
function Ui(e, t, n = {}, s = Qi) {
if (typeof window.IntersectionObserver > "u" && s !== void 0) {
const l = e.getBoundingClientRect();
return t(s, {
isIntersecting: s,
target: e,
intersectionRatio: typeof n.threshold == "number" ? n.threshold : 0,
time: 0,
boundingClientRect: l,
intersectionRect: l,
rootBounds: l
}), () => {
};
}
const { id: a, observer: i, elements: o } = Vi(n), c = o.get(e) || [];
return o.has(e) || o.set(e, c), c.push(t), i.observe(e), function() {
c.splice(c.indexOf(t), 1), c.length === 0 && (o.delete(e), i.unobserve(e)), o.size === 0 && (i.disconnect(), hr.delete(a));
};
}
function Hi({
threshold: e,
delay: t,
trackVisibility: n,
rootMargin: s,
root: a,
triggerOnce: i,
skip: o,
initialInView: c,
fallbackInView: l,
onChange: u
} = {}) {
var h;
const [f, m] = Vt.useState(null), g = Vt.useRef(u), b = Vt.useRef(c), [N, x] = Vt.useState({
inView: !!c,
entry: void 0
});
g.current = u, Vt.useEffect(
() => {
if (b.current === void 0 && (b.current = c), o || !f) return;
let C;
return C = Ui(
f,
(T, p) => {
const v = b.current;
b.current = T, !(v === void 0 && !T) && (x({
inView: T,
entry: p
}), g.current && g.current(T, p), p.isIntersecting && i && C && (C(), C = void 0));
},
{
root: a,
rootMargin: s,
threshold: e,
// @ts-expect-error
trackVisibility: n,
delay: t
},
l
), () => {
C && C();
};
},
// 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(e) ? e.toString() : e,
f,
a,
s,
i,
o,
n,
l,
t
]
);
const A = (h = N.entry) == null ? void 0 : h.target, w = Vt.useRef(void 0);
!f && A && !i && !o && w.current !== A && (w.current = A, x({
inView: !!c,
entry: void 0
}), b.current = c);
const y = [m, N.inView, N.entry];
return y.ref = y[0], y.inView = y[1], y.entry = y[2], y;
}
const zi = 300;
function Gi(e) {
if (!e || !e.bindingKey || !e.steps || e.steps.length < 2) return !1;
if (typeof e.bindingKey.dimension == "string") {
if (!e.bindingKey.dimension) return !1;
} else if (Array.isArray(e.bindingKey.dimension) && e.bindingKey.dimension.length === 0)
return !1;
for (const t of e.steps) {
const n = t.query;
if (!(n.measures && n.measures.length > 0 || n.dimensions && n.dimensions.length > 0 || n.timeDimensions && n.timeDimensions.length > 0 || n.filters && n.filters.length > 0)) return !1;
}
return !0;
}
function pa(e, t = {}) {
const {
skip: n = !1,
debounceMs: s = zi,
onComplete: a,
onError: i,
prebuiltServerQuery: o
} = t, { cubeApi: c } = Tr(), l = Pn(), u = Gi(e), { debouncedValue: h, isDebouncing: f } = fa(e, {
isValid: u,
skip: n,
debounceMs: s
}), m = V(() => {
if (o)
return o;
if (!h || !u)
return null;
try {
return ti(
h.steps.map((S) => S.query),
h.bindingKey,
h.steps.map((S) => S.name),
h.steps.map((S) => S.timeToConvert || null),
!0
// includeTimeMetrics
);
} catch (k) {
return console.error("Failed to build server funnel query:", k), null;
}
}, [o, h, u]), g = V(() => m ? ["cube", "funnel", m.funnel?.steps?.length || 0, JSON.stringify(m)] : ["cube", "funnel", null], [m]), b = kr({
queryKey: g,
queryFn: async () => {
if (!m)
throw new Error("No server query available");
const k = performance.now();
try {
const S = await c.load(m), $ = S.rawData(), D = performance.now() - k, F = S.cacheInfo?.();
return {
rawData: $,
executionTime: D,
cacheInfo: F
};
} catch (S) {
const $ = S instanceof Error ? S : new Error(String(S));
throw i?.($, 0), $;
}
},
// Enable when we have a server query (either prebuilt or built from config)
enabled: !n && !!m,
staleTime: 6e4,
// 1 minute cache
gcTime: 300 * 1e3
// 5 minute garbage collection
}), N = V(() => o?.funnel?.steps ? o.funnel.steps.map((k) => k.name) : h?.steps?.map((k) => k.name), [o, h]), x = V(() => o?.funnel?.steps ? o.funnel.steps.length : h?.steps?.length || 0, [o, h]), A = V(() => b.data?.rawData ? b.data.rawData.length !== x ? [] : ni(
b.data.rawData,
N
) : [], [b.data, x, N]), w = V(() => {
if (!A.length) return [];
const k = A[0]?.value || 0;
return A.map((S, $) => ({
stepIndex: $,
stepName: S.name,
// Get step ID from config, or generate one for prebuilt queries
stepId: h?.steps?.[$]?.id || `step-${$}`,
data: [],
// Raw data not available from server funnel
bindingKeyValues: [],
// Not available from server funnel
bindingKeyTotalCount: 0,
count: S.value,
conversionRate: S.conversionRate !== null ? S.conversionRate / 100 : null,
cumulativeConversionRate: k > 0 ? S.value / k : 0,
executionTime: b.data?.executionTime || 0,
error: null
}));
}, [A, h, b.data?.executionTime]), y = V(() => {
if (!A.length || !h && !o) return null;
const k = A[0]?.value || 0, S = A[A.length - 1]?.value || 0, D = {
config: h || {
id: "prebuilt-funnel",
name: "Funnel Analysis",
bindingKey: {
dimension: typeof o?.funnel?.bindingKey == "string" ? o.funnel.bindingKey : o?.funnel?.bindingKey?.[0]?.dimension || ""
},
steps: (o?.funnel?.steps || []).map((F, K) => ({
id: `step-${K}`,
name: F.name,
query: { filters: F.filter ? [F.filter] : [] },
timeToConvert: F.timeToConvert || void 0
}))
},
steps: w,
summary: {
totalEntries: k,
totalCompletions: S,
overallConversionRate: k > 0 ? S / k : 0,
totalExecutionTime: b.data?.executionTime || 0
},
chartData: A,
status: b.isError ? "error" : b.isLoading ? "executing" : b.isSuccess ? "success" : "idle",
error: b.error,
currentStepIndex: null
};
return b.isSuccess && !b.isFetching && a?.(D), D;
}, [h, o, A, w, b, a]), C = b.isError ? "error" : b.isLoading ? "executing" : b.isSuccess ? "success" : "idle", T = E(async () => {
if (!m) return null;
try {
return await b.refetch(), y;
} catch {
return y;
}
}, [m, b, y]), p = E(() => {
}, []), v = E(() => {
l.removeQueries({ queryKey: g });
}, [l, g]);
return {
result: y,
status: C,
isExecuting: b.isLoading || b.isFetching,
isDebouncing: f,
currentStepIndex: null,
// Not applicable for server-side execution
stepLoadingStates: [],
// Not applicable for server-side execution
stepResults: w,
chartData: A,
error: b.error,
execute: T,
cancel: p,
reset: v,
// Not exposing executedQueries - server builds the query internally
executedQueries: [],
// Expose the server query for debug panel display
// This is the actual { funnel: {...} } query sent to the server
serverQuery: m,
cacheInfo: b.data?.cacheInfo ?? null
};
}
function Lu(e) {
return e ? ["cube", "funnel", JSON.stringify(e)] : ["cube", "funnel", null];
}
const Wi = 300;
function Yi(e) {
if (!e?.flow) return !1;
const { flow: t } = e;
return !(!t.bindingKey || !t.timeDimension || !t.eventDimension || !t.startingStep?.filter || t.stepsBefore < 0 || t.stepsBefore > 5 || t.stepsAfter < 0 || t.stepsAfter > 5);
}
function Ji(e) {
if (e.length === 1) {
const t = e[0];
if (t && typeof t == "object" && "nodes" in t && "links" in t)
return t;
}
if (e.length > 0) {
const t = e[0];
if (t && typeof t == "object" && ri(t))
return t;
}
return null;
}
function ga(e, t = {}) {
const {
skip: n = !1,
debounceMs: s = Wi,
onComplete: a,
onError: i
} = t, { cubeApi: o } = Tr(), c = Pn(), l = Yi(e), { debouncedValue: u, isDebouncing: h } = fa(
e,
{
isValid: l,
skip: n,
debounceMs: s
}
), f = V(() => u ? JSON.stringify(u) : null, [u]), m = V(() => e ? JSON.stringify(e) : null, [e]), g = V(() => u ? ["cube", "flow", f] : ["cube", "flow", null], [u, f]), b = kr({
queryKey: g,
queryFn: async () => {
if (!u)
throw new Error("No flow query available");
const y = performance.now();
try {
const C = await o.load(
u
), T = C.rawData(), p = performance.now() - y, v = C.cacheInfo?.();
return {
rawData: T,
executionTime: p,
cacheInfo: v,
// Include query key in result so we can detect stale data
// (data from a different query key, e.g., sankey vs sunburst mode)
// We store the RAW query key so we can compare against the current raw query
queryKeyString: m
};
} catch (C) {
const T = C instanceof Error ? C : new Error(String(C));
throw i?.(T), T;
}
},
enabled: !n && l && !!u,
staleTime: 6e4,
// 1 minute cache
gcTime: 300 * 1e3
// 5 minute garbage collection
}), N = m !== null && b.data?.queryKeyString !== void 0 && b.data.queryKeyString !== m, x = V(() => {
if (N || !b.data?.rawData) return null;
const y = Ji(b.data.rawData);
return y && b.isSuccess && !b.isFetching && a?.(y), y;
}, [b.data, b.isSuccess, b.isFetching, a, N]), A = E(() => {
u && l && b.refetch();
}, [u, l, b]), w = E(() => {
c.removeQueries({ queryKey: g });
}, [c, g]);
return {
data: x,
rawData: N ? null : b.data?.rawData ?? null,
cacheInfo: b.data?.cacheInfo ?? null,
isLoading: b.isLoading || N,
isFetching: b.isFetching,
isDebouncing: h,
isExecuting: b.isLoading || b.isFetching || N,
error: b.error,
refetch: A,
reset: w,
serverQuery: u
};
}
function Pu(e) {
return e ? ["cube", "flow", JSON.stringify(e)] : ["cube", "flow", null];
}
function Xi(e, t) {
return e ? ["cube", "explain", Mi(e), t?.analyze ?? !1] : ["cube", "explain", null, null];
}
function Zi(e) {
return typeof e == "object" && e !== null && "funnel" in e;
}
function eo(e) {
return typeof e == "object" && e !== null && "flow" in e;
}
function Gn(e, t = {}) {
const { skip: n = !1 } = t, { cubeApi: s } = Tr(), [a, i] = ee(null), [o, c] = ee(!1), l = V(() => e ? Zi(e) || eo(e) ? e : fr(e) : null, [e]), u = !!l && !n && o, h = kr({
queryKey: Xi(l, a ?? void 0),
queryFn: async () => {
if (!l) throw new Error("No query provided");
return await s.explain(l, a ?? void 0);
},
enabled: u,
// EXPLAIN queries should never be cached - always fetch fresh data
// This ensures users see the latest execution plan after schema/index changes
staleTime: 0,
gcTime: 0,
// Don't refetch automatically - this is manually triggered
refetchOnWindowFocus: !1,
refetchOnReconnect: !1,
refetchOnMount: !1
}), f = E((g) => {
n || !l || (i(g ?? null), c(!0), o && h.refetch());
}, [n, l, o, h]), m = E(() => {
c(!1), i(null);
}, []);
return {
explainResult: h.data ?? null,
isLoading: h.isLoading || h.isFetching,
hasRun: o,
error: h.error ?? null,
runExplain: f,
clearExplain: m
};
}
const Zr = ["cube", "explain", "ai"];
function to(e = {}) {
const { features: t } = an(), n = t.enableAI ?? !0, s = Pn(), a = e.aiEndpoint ?? "/api/ai/explain/analyze", i = si({
mutationKey: Zr,
mutationFn: async ({ explainResult: l, query: u }) => {
if (!n)
throw new Error("AI features are disabled");
const h = await fetch(a, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
explainResult: l,
query: u
})
});
if (!h.ok) {
const m = await h.json().catch(() => ({}));
throw new Error(
m.error || m.message || `AI analysis failed: ${h.status} ${h.statusText}`
);
}
return await h.json();
},
// No caching - each mutation is independent
gcTime: 0
}), o = E((l, u) => {
i.mutate({ explainResult: l, query: u });
}, [i]), c = E(() => {
i.reset(), s.removeQueries({ queryKey: Zr });
}, [i, s]);
return {
analysis: i.data ?? null,
isAnalyzing: i.isPending,
error: i.error ?? null,
analyze: o,
clearAnalysis: c
};
}
const no = q("refresh");
class ro extends aa {
constructor(t) {
super(t), this.state = {
hasError: !1,
error: null,
errorInfo: null
};
}
static getDerivedStateFromError(t) {
return {
hasError: !0,
error: t,
errorInfo: null
};
}
componentDidCatch(t, n) {
this.setState({
error: t,
errorInfo: n.componentStack || null
}), console.error("Chart Error Boundary caught a rendering error:", t, n);
}
handleReset = () => {
this.setState({
hasError: !1,
error: null,
errorInfo: null
});
};
render() {
return this.state.hasError ? this.props.fallback ? this.props.fallback : /* @__PURE__ */ d(
"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__ */ r("div", { className: "h-12 w-12 mb-4 text-dc-text-muted", children: "⚠️" }),
/* @__PURE__ */ r("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__ */ r("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__ */ r("div", { className: "w-full max-w-2xl mb-4", children: /* @__PURE__ */ d("div", { className: "bg-dc-surface-secondary rounded-lg p-3 text-left", children: [
/* @__PURE__ */ d("div", { className: "text-xs font-mono mb-2 text-dc-text", children: [
/* @__PURE__ */ r("strong", { children: "Error:" }),
" ",
this.state.error?.message
] }),
this.state.error?.name && /* @__PURE__ */ d("div", { className: "text-xs font-mono text-dc-text-secondary mb-2", children: [
/* @__PURE__ */ r("strong", { children: "Type:" }),
" ",
this.state.error.name
] }),
this.props.portletConfig && /* @__PURE__ */ d("details", { className: "text-xs font-mono text-dc-text-secondary mb-2", children: [
/* @__PURE__ */ r("summary", { className: "cursor-pointer", children: "Portlet Configuration" }),
/* @__PURE__ */ r(
"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__ */ d("details", { className: "text-xs font-mono text-dc-text-secondary mb-2", children: [
/* @__PURE__ */ r("summary", { className: "cursor-pointer", children: "Cube Query" }),
/* @__PURE__ */ r(
"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__ */ d("details", { className: "text-xs font-mono text-dc-text-secondary", children: [
/* @__PURE__ */ r("summary", { className: "cursor-pointer", children: "Component Stack" }),
/* @__PURE__ */ r("pre", { className: "mt-2 whitespace-pre-wrap", children: this.state.errorInfo })
] })
] }) }),
/* @__PURE__ */ d(
"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__ */ r(no, { style: { width: "16px", height: "16px", display: "inline", marginRight: "4px" } }),
"Try Again"
]
}
)
]
}
) : this.props.children;
}
}
function so(e) {
return typeof e == "object" && e !== null && "queries" in e && Array.isArray(e.queries) && e.queries.length > 0;
}
function ao(e) {
return typeof e == "object" && e !== null && "funnel" in e && typeof e.funnel == "object";
}
const Ir = (e) => {
if (!e || typeof e != "object") return !1;
const t = e;
return !(t.version !== 1 || t.analysisType !== "query" && t.analysisType !== "funnel" && t.analysisType !== "flow" || !t.query || typeof t.query != "object" || t.activeView !== "table" && t.activeView !== "chart");
}, io = () => ({
version: 1,
analysisType: "query",
activeView: "chart",
charts: {
query: {
chartType: "bar",
chartConfig: {},
displayConfig: {}
}
},
query: {
measures: [],
dimensions: []
}
}), oo = (e) => {
if (!e || typeof e != "object") return !1;
const t = e;
return !(t.version !== 1 || t.activeType !== "query" && t.activeType !== "funnel" && t.activeType !== "flow" || !t.modes || typeof t.modes != "object");
};
function lo(e) {
return typeof e == "object" && e !== null && "queries" in e && Array.isArray(e.queries);
}
function co(e) {
return typeof e == "object" && e !== null && "queries" in e && Array.isArray(e.queries) && "mergeStrategy" in e && e.mergeStrategy === "funnel";
}
function es(e) {
return typeof e == "object" && e !== null && "funnel" in e && typeof e.funnel == "object";
}
function uo(e) {
return typeof e == "object" && e !== null && "flow" in e && typeof e.flow == "object";
}
function Zt(e, t) {
return t === "funnel" ? {
chartType: e.funnelChartType || e.chartType || "funnel",
chartConfig: e.funnelChartConfig || e.chartConfig || {},
displayConfig: e.funnelDisplayConfig || e.displayConfig || {}
} : t === "flow" ? {
chartType: e.chartType || "sankey",
chartConfig: e.chartConfig || {},
displayConfig: e.displayConfig || {}
} : {
chartType: e.chartType || "bar",
chartConfig: e.chartConfig || {},
displayConfig: e.displayConfig || {}
};
}
function fo(e) {
try {
const t = JSON.parse(e.query);
if (uo(t))
return {
version: 1,
analysisType: "flow",
activeView: "chart",
charts: {
flow: Zt(e, "flow")
},
query: t
};
if (es(t))
return {
version: 1,
analysisType: "funnel",
activeView: "chart",
charts: {
funnel: Zt(e, "funnel")
},
query: t
};
if (co(t))
return mo(t, e);
if (e.analysisType === "funnel")
return {
version: 1,
analysisType: "funnel",
activeView: "chart",
charts: {
funnel: Zt(e, "funnel")
},
query: es(t) ? t : {
funnel: {
bindingKey: "",
timeDimension: "",
steps: []
}
}
};
const n = Zt(e, "query");
if (lo(t)) {
const s = t.mergeStrategy === "funnel" ? "concat" : t.mergeStrategy;
return {
version: 1,
analysisType: "query",
activeView: "chart",
charts: {
query: n
},
query: {
queries: t.queries,
mergeStrategy: s,
mergeKeys: t.mergeKeys,
queryLabels: t.queryLabels
}
};
}
return {
version: 1,
analysisType: "query",
activeView: "chart",
charts: {
query: n
},
query: t
};
} catch (t) {
return console.warn("[configMigration] Failed to parse legacy portlet:", t), io();
}
}
function mo(e, t) {
let n = "";
e.funnelBindingKey?.dimension && (typeof e.funnelBindingKey.dimension == "string" ? n = e.funnelBindingKey.dimension : Array.isArray(e.funnelBindingKey.dimension) && (n = e.funnelBindingKey.dimension.map((o) => ({
cube: o.cube,
dimension: o.dimension
}))));
let s = "";
e.queries.length > 0 && e.queries[0].timeDimensions?.length && (s = e.queries[0].timeDimensions[0].dimension);
const a = e.queries.map((o, c) => {
const l = {
name: e.queryLabels?.[c] || `Step ${c + 1}`
};
return o.filters && o.filters.length > 0 && (l.filter = o.filters.length === 1 ? o.filters[0] : { and: o.filters }), e.stepTimeToConvert && e.stepTimeToConvert[c] && (l.timeToConvert = e.stepTimeToConvert[c]), l;
});
return {
version: 1,
analysisType: "funnel",
activeView: "chart",
charts: {
funnel: t ? Zt(t, "funnel") : {
chartType: "funnel",
chartConfig: {},
displayConfig: {}
}
},
query: {
funnel: {
bindingKey: n,
timeDimension: s,
steps: a,
includeTimeMetrics: !0
}
}
};
}
function ho(e) {
return typeof e == "object" && e !== null && "analysisConfig" in e && Ir(e.analysisConfig);
}
function ln(e) {
if (ho(e))
return e;
const t = e.analysisType === "flow" ? void 0 : e.analysisType, n = fo({
query: e.query ?? "{}",
chartType: e.chartType,
chartConfig: e.chartConfig,
displayConfig: e.displayConfig,
analysisType: t,
funnelChartType: e.funnelChartType,
funnelChartConfig: e.funnelChartConfig,
funnelDisplayConfig: e.funnelDisplayConfig
});
return { ...e, analysisConfig: n };
}
function ya(e) {
if ("member" in e && "operator" in e) {
const t = e;
return ["set", "notSet", "isEmpty", "isNotEmpty"].includes(t.operator) || t.operator === "inDateRange" && t.dateRange ? !0 : !!(t.values && t.values.length > 0);
}
return "type" in e && "filters" in e ? e.filters.filter((s) => ya(s)).length > 0 : !1;
}
function po(e, t) {
return !e || !e.length ? [] : !t || !t.length ? [] : e.filter((n) => t.includes(n.id)).filter((n) => ya(n.filter)).map((n) => n.filter);
}
function ba(e) {
if ("type" in e && "filters" in e) {
const t = e, n = t.filters.map(ba);
return t.type === "and" ? { and: n } : { or: n };
}
return e;
}
function en(e, t, n = "server") {
return !e || e.length === 0 ? t : !t || t.length === 0 ? [...e] : n === "server" ? [{
and: [...e, ...t].map(ba)
}] : [{
type: "and",
filters: [...e, ...t]
}];
}
function go(e) {
const t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set();
return e.portlets.forEach((a) => {
try {
const o = ln(a).analysisConfig.query, c = (l) => {
l.measures && Array.isArray(l.measures) && l.measures.forEach((u) => t.add(u)), l.dimensions && Array.isArray(l.dimensions) && l.dimensions.forEach((u) => n.add(u)), l.timeDimensions && Array.isArray(l.timeDimensions) && l.timeDimensions.forEach((u) => {
u.dimension && s.add(u.dimension);
}), l.filters && xa(l.filters).forEach((u) => {
n.add(u);
});
};
if ("funnel" in o) {
const l = o;
l.funnel?.timeDimension && s.add(l.funnel.timeDimension);
} else "queries" in o ? o.queries.forEach((u) => c(u)) : c(o);
} catch (i) {
console.warn("Failed to extract fields from portlet:", a.id, i);
}
}), { measures: t, dimensions: n, timeDimensions: s };
}
function xa(e) {
const t = [];
return e.forEach((n) => {
"member" in n ? t.push(n.member) : "type" in n && "filters" in n && t.push(...xa(n.filters));
}), [...new Set(t)];
}
function ts(e) {
if (e.dateRange)
return e.dateRange;
if (e.values && e.values.length > 0)
return e.values.length === 1 ? e.values[0] : e.values;
}
function An(e, t, n) {
if (!n || n.length === 0 || !t || t.length === 0)
return n;
const s = e?.filter((c) => c.isUniversalTime && t.includes(c.id))?.filter((c) => {
if (!("member" in c.filter)) return !1;
const l = c.filter;
return ts(l) !== void 0;
});
if (!s || s.length === 0)
return n;
const i = s[0].filter, o = ts(i);
return n.map((c) => ({
...c,
dateRange: o
}));
}
const Bn = bt.memo(Ln(({
query: e,
chartType: t,
chartConfig: n,
displayConfig: s,
dashboardFilters: a,
dashboardFilterMapping: i,
eagerLoad: o = !1,
isVisible: c,
// Deprecated - visibility now handled internally via useInView
height: l = 300,
title: u,
colorPalette: h,
loadingComponent: f,
onDebugDataReady: m
}, g) => {
const b = ge(m), N = ki(), { ref: x, inView: A } = Hi({
root: N,
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: o
// Skip observation entirely if eagerLoad is true
}), w = o || A;
he(() => {
b.current = m;
}, [m]);
const { config: y } = Ai(t), C = y.skipQuery === !0, T = V(() => a?.filter((Ne) => !Ne.isUniversalTime), [a]), { queryObject: p, multiQueryConfig: v, serverFunnelQuery: k, serverFlowQuery: S } = V(() => {
if (C)
return { queryObject: null, multiQueryConfig: null, serverFunnelQuery: null, serverFlowQuery: null };
try {
const Ne = JSON.parse(e), _e = po(T, i);
if (ai(Ne))
return {
queryObject: null,
multiQueryConfig: null,
serverFunnelQuery: null,
serverFlowQuery: Ne
};
if (ao(Ne)) {
const Ke = Ne, Oe = { ...Ke, funnel: { ...Ke.funnel, steps: [...Ke.funnel.steps] } };
if (_e.length > 0 && Oe.funnel.steps.length > 0) {
const Qe = { ...Oe.funnel.steps[0] }, J = Qe.filter ? Array.isArray(Qe.filter) ? Qe.filter : [Qe.filter] : [], fe = en(_e, J);
Qe.filter = fe, Oe.funnel.steps[0] = Qe;
}
const Xe = a?.filter(
(Qe) => Qe.isUniversalTime && i?.includes(Qe.id)
);
if (Xe && Xe.length > 0 && Oe.funnel.steps.length > 0) {
const Qe = Xe[0];
if ("member" in Qe.filter) {
const J = Qe.filter, fe = J.dateRange || J.values?.[0];
if (fe) {
const ve = { ...Oe.funnel.steps[0] };
let ke;
if (typeof Oe.funnel.timeDimension == "string")
ke = Oe.funnel.timeDimension;
else if (Array.isArray(Oe.funnel.timeDimension) && Oe.funnel.timeDimension.length > 0) {
const Fe = Oe.funnel.timeDimension[0];
ke = `${Fe.cube}.${Fe.dimension}`;
}
if (ke) {
const Fe = {
member: ke,
operator: "inDateRange",
values: [],
dateRange: fe
}, re = ve.filter ? Array.isArray(ve.filter) ? ve.filter : [ve.filter] : [];
ve.filter = [...re, Fe], Oe.funnel.steps[0] = ve;
}
}
}
}
return { queryObject: null, multiQueryConfig: null, serverFunnelQuery: Oe, serverFlowQuery: null };
}
if (so(Ne))
return { queryObject: null, multiQueryConfig: {
...Ne,
queries: Ne.queries.map((Oe) => ({
...Oe,
filters: en(_e, Oe.filters),
timeDimensions: An(a, i, Oe.timeDimensions)
}))
}, serverFunnelQuery: null, serverFlowQuery: null };
const We = en(_e, Ne.filters), Je = An(
a,
i,
Ne.timeDimensions
);
return {
queryObject: {
...Ne,
filters: We,
timeDimensions: Je
},
multiQueryConfig: null,
serverFunnelQuery: null,
serverFlowQuery: null
};
} catch (Ne) {
return console.error("AnalyticsPortlet: Invalid query JSON:", Ne), { queryObject: null, multiQueryConfig: null, serverFunnelQuery: null, serverFlowQuery: null };
}
}, [e, C, T, a, i]), $ = v !== null, D = k !== null, F = S !== null, K = !p || C || !o && !w || $ || D || F, P = !v || C || !o && !w || D || F, te = !D || C || !o && !w, _ = !F || C || !o && !w, O = Pn(), ie = null, X = ma(p, {
skip: K,
resetResultSetOnChange: !0,
debounceMs: 100
// Lower debounce for portlets (faster response)
}), ce = ha(v, {
skip: P,
debounceMs: 100
// Lower debounce for portlets (faster response)
}), Q = pa(ie, {
skip: te || !k,
debounceMs: 100,
// Pass prebuilt ServerFunnelQuery directly (new dedicated funnel mode)
prebuiltServerQuery: k
}), Se = ga(S, {
skip: _,
debounceMs: 100
}), L = $ ? null : X.resultSet, pe = F ? Se.isLoading || Se.isDebouncing : D ? Q.isExecuting || Q.isDebouncing : $ ? ce.isLoading : X.isLoading, z = F ? Se.isFetching : D ? Q.isExecuting : $ ? ce.isFetching : X.isFetching, H = F ? Se.error : D ? Q.error : $ ? ce.error : X.error, se = F ? null : D ? Q.chartData : $ ? ce.data : null, me = F ? Se.data : null;
Dr(g, () => ({
refresh: () => {
if (F && S) {
const Ne = ["cube", "flow", JSON.stringify(S)];
O.invalidateQueries({ queryKey: Ne });
} else if (D && k) {
const _e = ["cube", "funnel", k.funnel?.steps?.length || 0, JSON.stringify(k)];
O.invalidateQueries({ queryKey: _e });
} else if ($ && v) {
const Ne = {
...v,
queries: v.queries.map((_e) => fr(_e))
};
O.invalidateQueries({ queryKey: Ii(Ne) });
} else if (p) {
const Ne = fr(p);
O.invalidateQueries({ queryKey: Ei(Ne) });
}
}
}), [F, D, $, v, p, O, S, k]);
const le = E(() => {
F ? Se.refetch() : D ? Q.execute() : $ ? ce.refetch() : X.refetch();
}, [F, D, $, Se, Q, ce, X]);
he(() => {
if (!(!b.current || H)) {
if (D && se && se.length > 0) {
b.current({
chartConfig: n || {},
displayConfig: s || {},
queryObject: k,
data: se,
chartType: t,
cacheInfo: Q.cacheInfo ?? void 0
});
return;
}
if (F && S && me) {
b.current({
chartConfig: n || {},
displayConfig: s || {},
queryObject: S,
data: me,
chartType: t,
cacheInfo: Se.cacheInfo
});
return;
}
if (n && p && L) {
const _e = (() => {
switch (t) {
case "pie":
case "table":
return L.tablePivot();
default:
return L.rawData();
}
})();
_e && b.current({
chartConfig: n || {},
displayConfig: s || {},
queryObject: p,
data: _e,
chartType: t,
cacheInfo: L.cacheInfo?.()
});
}
}
}, [n, s, p, L, t, H, D, F, se, k, S, me, Se.cacheInfo, Q.cacheInfo]);
const we = !C && y.dropZones.some((Ne) => Ne.mandatory === !0);
if (!n && we)
return /* @__PURE__ */ r("div", { ref: x, className: "flex items-center justify-center w-full text-dc-text-muted", style: { height: l }, children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r("div", { className: "text-sm font-semibold mb-1", children: "Configuration Required" }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-secondary", children: "Please configure this chart" })
] }) });
if (!C && !o && !w)
return /* @__PURE__ */ r("div", { ref: x, className: "w-full h-full", style: { height: l }, children: /* @__PURE__ */ r("div", { className: "w-full h-full animate-pulse bg-dc-surface-secondary rounded", style: { minHeight: "100px" } }) });
if (!C) {
if (pe || z || p && !L && !H)
return /* @__PURE__ */ r("div", { ref: x, className: "flex items-center justify-center w-full", style: { height: l }, children: f || /* @__PURE__ */ r(ii, { size: "md" }) });
if (H)
return /* @__PURE__ */ d("div", { ref: x, className: "p-4 border rounded-sm", style: { height: l, borderColor: "var(--dc-border)", backgroundColor: "var(--dc-surface)" }, children: [
/* @__PURE__ */ r("div", { className: "mb-2", children: /* @__PURE__ */ d("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ r("span", { className: "font-medium text-sm", style: { color: "var(--dc-text)" }, children: "⚠️ Query Error" }),
/* @__PURE__ */ r(
"button",
{
onClick: le,
className: "px-2 py-1 text-white rounded-sm text-xs",
style: { backgroundColor: "var(--dc-primary)" },
children: "Retry"
}
)
] }) }),
/* @__PURE__ */ r("div", { className: "mb-3", children: /* @__PURE__ */ r("div", { className: "text-xs p-2 rounded-sm border", style: { color: "var(--dc-text-secondary)", backgroundColor: "var(--dc-surface)", borderColor: "var(--dc-border)" }, children: H.message || H.toString() }) }),
/* @__PURE__ */ d("div", { className: "space-y-2 text-xs", children: [
/* @__PURE__ */ d("details", { children: [
/* @__PURE__ */ r("summary", { className: "cursor-pointer font-medium", style: { color: "var(--dc-text-secondary)" }, children: "Query (with filters applied)" }),
/* @__PURE__ */ r("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: p ? JSON.stringify(p, null, 2) : e })
] }),
/* @__PURE__ */ d("details", { children: [
/* @__PURE__ */ r("summary", { className: "cursor-pointer font-medium", style: { color: "var(--dc-text-secondary)" }, children: "Chart Config" }),
/* @__PURE__ */ r("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: t,
chartConfig: n,
displayConfig: s
}, null, 2) })
] })
] })
] });
if (!(F ? me !== null && S !== null : D ? se !== null && k !== null : $ ? se !== null && v !== null : L !== null && p !== null))
return /* @__PURE__ */ r("div", { ref: x, className: "flex items-center justify-center w-full text-dc-text-muted", style: { height: l }, children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r("div", { className: "text-sm font-semibold mb-1", children: "No data available" }),
/* @__PURE__ */ r("div", { className: "text-xs", children: "Invalid query or no results" })
] }) });
}
const Pe = (() => {
if (C)
return [];
if (F)
return me || { nodes: [], links: [] };
if (D)
return se || [];
if ($)
return se || [];
if (!L)
return [];
switch (t) {
case "pie":
case "table":
return L.tablePivot();
default:
return L.rawData();
}
})();
return /* @__PURE__ */ r("div", { ref: x, className: "w-full h-full", children: /* @__PURE__ */ r(
ro,
{
portletTitle: u,
portletConfig: {
chartType: t,
chartConfig: n,
displayConfig: s,
height: l
},
cubeQuery: e,
children: /* @__PURE__ */ r("div", { className: "w-full h-full flex flex-col flex-1", style: { minHeight: "200px" }, children: (() => {
try {
const Ne = l, _e = t === "sankey" && s?.flowVisualization === "sunburst" ? "sunburst" : t;
return da(_e) ? /* @__PURE__ */ r(
ur,
{
chartType: _e,
data: _e === "markdown" ? [] : Pe,
chartConfig: n,
displayConfig: s,
queryObject: p ?? void 0,
height: Ne,
colorPalette: h,
fallback: /* @__PURE__ */ r(
"div",
{
className: "flex items-center justify-center w-full",
style: { height: typeof Ne == "number" ? `${Ne}px` : Ne },
children: /* @__PURE__ */ r("div", { className: "animate-pulse bg-dc-surface-secondary rounded w-full h-full min-h-[100px]" })
}
)
}
) : /* @__PURE__ */ r("div", { className: "flex items-center justify-center w-full", style: { height: l }, children: /* @__PURE__ */ d("div", { className: "text-center text-dc-text-muted", children: [
/* @__PURE__ */ r("div", { className: "text-sm font-semibold mb-1", children: "Unsupported chart type" }),
/* @__PURE__ */ r("div", { className: "text-xs", children: _e })
] }) });
} catch (Ne) {
return console.error("Chart rendering error:", Ne), /* @__PURE__ */ r("div", { className: "flex items-center justify-center w-full text-dc-text-muted p-4", style: { height: l }, children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r("div", { className: "text-sm font-semibold mb-1", children: "Unable to render chart" }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-secondary", children: Ne instanceof Error ? Ne.message : "Unknown error" })
] }) });
}
})() })
}
) });
}));
Bn.displayName = "AnalyticsPortlet";
function yo(e, { threshold: t = 20, debounceMs: n = 150, container: s } = {}) {
const [a, i] = ee(!1), o = ge();
return he(() => {
const c = e.current;
if (!c) return;
const l = () => {
o.current && clearTimeout(o.current), o.current = window.setTimeout(() => {
const h = c.scrollTop > t;
i((f) => f !== h ? h : f);
}, n);
};
return c.addEventListener("scroll", l, { passive: !0 }), l(), () => {
c.removeEventListener("scroll", l), o.current && clearTimeout(o.current);
};
}, [t, n, s]), a;
}
function bo(e, { threshold: t = 80, debounceMs: n = 100, containerRef: s, container: a } = {}) {
const [i, o] = ee(!0), c = ge(), l = ge(!1);
return he(() => {
const u = s?.current, h = () => {
const g = e.current;
g && (c.current && clearTimeout(c.current), c.current = window.setTimeout(() => {
const b = g.getBoundingClientRect();
if (u) {
const N = u.getBoundingClientRect(), x = b.bottom > N.top + t;
x && (l.current = !0), o((A) => A !== x ? x : A);
} else {
const N = b.bottom > t;
N && (l.current = !0), o((x) => x !== N ? N : x);
}
}, n));
}, f = u || window;
f.addEventListener("scroll", h, { passive: !0 }), window.addEventListener("resize", h, { passive: !0 }), h();
const m = requestAnimationFrame(() => {
h();
});
return () => {
f.removeEventListener("scroll", h), window.removeEventListener("resize", h), cancelAnimationFrame(m), c.current && clearTimeout(c.current);
};
}, [e, s, t, n, a]), i;
}
let Mn = null, Yt = null;
async function xo() {
if (!Mn)
return Yt || (Yt = (async () => {
try {
const e = await import("./core-Dpz8VE0a.js"), t = await import("./javascript-DII1YQGr.js"), n = await Promise.resolve().then(() => hc), s = await Promise.resolve().then(() => mc);
e.default.registerLanguage("javascript", t.default), e.default.registerLanguage("sql", n.default), e.default.registerLanguage("json", s.default), Mn = e.default;
} catch (e) {
console.error("Failed to load syntax highlighter:", e), Yt = null;
}
})(), Yt);
}
async function vo() {
await xo(), Mn && document.querySelectorAll("pre code").forEach((e) => {
e.classList.contains("hljs") || Mn.highlightElement(e);
});
}
function va({
chartConfig: e,
displayConfig: t,
queryObject: n,
data: s,
chartType: a,
cacheInfo: i
}) {
const [o, c] = ee(!1);
return he(() => {
const l = (u) => {
u.key === "Escape" && o && c(!1);
};
return document.addEventListener("keydown", l), () => document.removeEventListener("keydown", l);
}, [o]), he(() => {
if (o) {
const l = setTimeout(() => {
vo().catch((u) => {
console.debug("Syntax highlighting not available:", u);
});
}, 10);
return () => clearTimeout(l);
}
}, [o]), o ? /* @__PURE__ */ r(
"div",
{
className: "absolute inset-0 bg-dc-surface border border-dc-border rounded-lg z-50 overflow-auto",
onClick: (l) => l.stopPropagation(),
children: /* @__PURE__ */ d("div", { className: "p-4 h-full flex flex-col", children: [
/* @__PURE__ */ d("div", { className: "flex justify-between items-center mb-4 shrink-0", children: [
/* @__PURE__ */ r("h2", { className: "text-lg font-semibold text-dc-text", children: "Chart Debug Information" }),
/* @__PURE__ */ r(
"button",
{
onClick: () => c(!1),
className: "p-2 text-dc-text-muted hover:text-dc-text-secondary hover:bg-dc-surface-secondary rounded-sm",
children: /* @__PURE__ */ d(
"svg",
{
width: "16",
height: "16",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
children: [
/* @__PURE__ */ r("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
/* @__PURE__ */ r("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
]
}
)
}
)
] }),
/* @__PURE__ */ d("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-4 flex-1 overflow-auto", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Chart Type" }),
/* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary p-2 rounded-sm text-sm font-mono border border-dc-border", children: a })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Field Analysis" }),
/* @__PURE__ */ d("div", { className: "bg-dc-surface-secondary p-2 rounded-sm text-xs space-y-1 border border-dc-border", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("strong", { children: "xAxis:" }),
" ",
Array.isArray(e?.xAxis) ? `Array: [${e.xAxis.join(", ")}]` : `String: "${e?.xAxis}"`
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("strong", { children: "yAxis:" }),
" ",
Array.isArray(e?.yAxis) ? `Array: [${e.yAxis.join(", ")}]` : `String: "${e?.yAxis}"`
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("strong", { children: "series:" }),
" ",
Array.isArray(e?.series) ? `Array: [${e.series.join(", ")}]` : `String: "${e?.series}"`
] }),
e?.sizeField && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("strong", { children: "sizeField:" }),
" ",
Array.isArray(e?.sizeField) ? `Array: [${e.sizeField.join(", ")}]` : `String: "${e?.sizeField}"`
] }),
e?.colorField && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("strong", { children: "colorField:" }),
" ",
Array.isArray(e?.colorField) ? `Array: [${e.colorField.join(", ")}]` : `String: "${e?.colorField}"`
] })
] })
] }),
/* @__PURE__ */ d("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ r("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Chart Config" }),
/* @__PURE__ */ r("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__ */ r("code", { className: "language-json", children: JSON.stringify(e, null, 2) }) })
] }),
/* @__PURE__ */ d("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ r("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Display Config" }),
/* @__PURE__ */ r("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__ */ r("code", { className: "language-json", children: JSON.stringify(t, null, 2) }) })
] }),
/* @__PURE__ */ d("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ r("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Query Object" }),
/* @__PURE__ */ r("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__ */ r("code", { className: "language-json", children: JSON.stringify(n, null, 2) }) })
] }),
/* @__PURE__ */ d("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ r("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Data Sample (first 3 rows)" }),
/* @__PURE__ */ r("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__ */ r("code", { className: "language-json", children: JSON.stringify(Array.isArray(s) ? s.slice(0, 3) : s, null, 2) }) })
] }),
/* @__PURE__ */ d("div", { className: "lg:col-span-2", children: [
/* @__PURE__ */ r("h3", { className: "text-sm font-medium text-dc-text-secondary mb-2", children: "Cache Status" }),
/* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary p-2 rounded-sm text-xs border border-dc-border", children: i ? /* @__PURE__ */ d("div", { className: "flex items-center gap-4 flex-wrap", children: [
/* @__PURE__ */ r("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__ */ d("span", { children: [
/* @__PURE__ */ r("strong", { children: "Cached At:" }),
" ",
new Date(i.cachedAt).toLocaleString()
] }),
/* @__PURE__ */ d("span", { children: [
/* @__PURE__ */ r("strong", { children: "TTL:" }),
" ",
Math.round(i.ttlMs / 1e3),
"s"
] }),
/* @__PURE__ */ d("span", { children: [
/* @__PURE__ */ r("strong", { children: "TTL Remaining:" }),
" ",
Math.round(i.ttlRemainingMs / 1e3),
"s"
] })
] }) : /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r("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__ */ r("span", { className: "text-dc-text-muted", children: "Result not served from cache" })
] }) })
] })
] }),
/* @__PURE__ */ d("div", { className: "mt-4 pt-2 border-t border-dc-border text-xs text-dc-text-muted shrink-0", children: [
"Press ",
/* @__PURE__ */ r("kbd", { className: "px-1 py-0.5 bg-dc-surface-secondary rounded-sm text-xs", children: "ESC" }),
" to close"
] })
] })
}
) : /* @__PURE__ */ r(
"button",
{
onClick: () => c(!0),
className: "p-1 text-dc-text-muted hover:text-dc-text-secondary transition-colors",
title: "Debug chart configuration",
children: /* @__PURE__ */ d(
"svg",
{
width: "16",
height: "16",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
children: [
/* @__PURE__ */ r("circle", { cx: "12", cy: "12", r: "10" }),
/* @__PURE__ */ r("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
/* @__PURE__ */ r("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
]
}
)
}
);
}
const ns = (e) => {
let t;
const n = /* @__PURE__ */ new Set(), s = (u, h) => {
const f = typeof u == "function" ? u(t) : u;
if (!Object.is(f, t)) {
const m = t;
t = h ?? (typeof f != "object" || f === null) ? f : Object.assign({}, t, f), n.forEach((g) => g(t, m));
}
}, a = () => t, c = { setState: s, getState: a, getInitialState: () => l, subscribe: (u) => (n.add(u), () => n.delete(u)) }, l = t = e(s, a, c);
return c;
}, pr = ((e) => e ? ns(e) : ns), wo = (e) => e;
function Er(e, t = wo) {
const n = bt.useSyncExternalStore(
e.subscribe,
bt.useCallback(() => t(e.getState()), [e, t]),
bt.useCallback(() => t(e.getInitialState()), [e, t])
);
return bt.useDebugValue(n), n;
}
const rs = { BASE_URL: "/", DEV: !1, MODE: "production", PROD: !0, SSR: !1 }, nn = /* @__PURE__ */ new Map(), hn = (e) => {
const t = nn.get(e);
return t ? Object.fromEntries(
Object.entries(t.stores).map(([n, s]) => [n, s.getState()])
) : {};
}, No = (e, t, n) => {
if (e === void 0)
return {
type: "untracked",
connection: t.connect(n)
};
const s = nn.get(n.name);
if (s)
return { type: "tracked", store: e, ...s };
const a = {
connection: t.connect(n),
stores: {}
};
return nn.set(n.name, a), { type: "tracked", store: e, ...a };
}, Co = (e, t) => {
if (t === void 0) return;
const n = nn.get(e);
n && (delete n.stores[t], Object.keys(n.stores).length === 0 && nn.delete(e));
}, So = (e) => {
var t, n;
if (!e) return;
const s = e.split(`
`), a = s.findIndex(
(o) => o.includes("api.setState")
);
if (a < 0) return;
const i = ((t = s[a + 1]) == null ? void 0 : t.trim()) || "";
return (n = /.+ (.+) .+/.exec(i)) == null ? void 0 : n[1];
}, Do = (e, t = {}) => (n, s, a) => {
const { enabled: i, anonymousActionType: o, store: c, ...l } = t;
let u;
try {
u = (i ?? (rs ? "production" : void 0) !== "production") && window.__REDUX_DEVTOOLS_EXTENSION__;
} catch {
}
if (!u)
return e(n, s, a);
const { connection: h, ...f } = No(c, u, l);
let m = !0;
a.setState = ((N, x, A) => {
const w = n(N, x);
if (!m) return w;
const y = A === void 0 ? {
type: o || So(new Error().stack) || "anonymous"
} : typeof A == "string" ? { type: A } : A;
return c === void 0 ? (h?.send(y, s()), w) : (h?.send(
{
...y,
type: `${c}/${y.type}`
},
{
...hn(l.name),
[c]: a.getState()
}
), w);
}), a.devtools = {
cleanup: () => {
h && typeof h.unsubscribe == "function" && h.unsubscribe(), Co(l.name, c);
}
};
const g = (...N) => {
const x = m;
m = !1, n(...N), m = x;
}, b = e(a.setState, s, a);
if (f.type === "untracked" ? h?.init(b) : (f.stores[f.store] = a, h?.init(
Object.fromEntries(
Object.entries(f.stores).map(([N, x]) => [
N,
N === f.store ? b : x.getState()
])
)
)), a.dispatchFromDevtools && typeof a.dispatch == "function") {
let N = !1;
const x = a.dispatch;
a.dispatch = (...A) => {
(rs ? "production" : void 0) !== "production" && A[0].type === "__setState" && !N && (console.warn(
'[zustand devtools middleware] "__setState" action type is reserved to set state from the devtools. Avoid using it.'
), N = !0), x(...A);
};
}
return h.subscribe((N) => {
var x;
switch (N.type) {
case "ACTION":
if (typeof N.payload != "string") {
console.error(
"[zustand devtools middleware] Unsupported action format"
);
return;
}
return Wn(
N.payload,
(A) => {
if (A.type === "__setState") {
if (c === void 0) {
g(A.state);
return;
}
Object.keys(A.state).length !== 1 && console.error(
`
[zustand devtools middleware] Unsupported __setState action format.
When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),
and value of this only key should be a state object. Example: { "type": "__setState", "state": { "abc123Store": { "foo": "bar" } } }
`
);
const w = A.state[c];
if (w == null)
return;
JSON.stringify(a.getState()) !== JSON.stringify(w) && g(w);
return;
}
a.dispatchFromDevtools && typeof a.dispatch == "function" && a.dispatch(A);
}
);
case "DISPATCH":
switch (N.payload.type) {
case "RESET":
return g(b), c === void 0 ? h?.init(a.getState()) : h?.init(hn(l.name));
case "COMMIT":
if (c === void 0) {
h?.init(a.getState());
return;
}
return h?.init(hn(l.name));
case "ROLLBACK":
return Wn(N.state, (A) => {
if (c === void 0) {
g(A), h?.init(a.getState());
return;
}
g(A[c]), h?.init(hn(l.name));
});
case "JUMP_TO_STATE":
case "JUMP_TO_ACTION":
return Wn(N.state, (A) => {
if (c === void 0) {
g(A);
return;
}
JSON.stringify(a.getState()) !== JSON.stringify(A[c]) && g(A[c]);
});
case "IMPORT_STATE": {
const { nextLiftedState: A } = N.payload, w = (x = A.computedStates.slice(-1)[0]) == null ? void 0 : x.state;
if (!w) return;
g(c === void 0 ? w : w[c]), h?.send(
null,
// FIXME no-any
A
);
return;
}
case "PAUSE_RECORDING":
return m = !m;
}
return;
}
}), b;
}, gr = Do, Wn = (e, t) => {
let n;
try {
n = JSON.parse(e);
} catch (s) {
console.error(
"[zustand devtools middleware] Could not parse the received json",
s
);
}
n !== void 0 && t(n);
}, To = (e) => (t, n, s) => {
const a = s.subscribe;
return s.subscribe = ((o, c, l) => {
let u = o;
if (c) {
const h = l?.equalityFn || Object.is;
let f = o(s.getState());
u = (m) => {
const g = o(m);
if (!h(f, g)) {
const b = f;
c(f = g, b);
}
}, l?.fireImmediately && c(f, f);
}
return a(u);
}), e(t, n, s);
}, yr = To;
function ko(e, t) {
let n;
try {
n = e();
} catch {
return;
}
return {
getItem: (a) => {
var i;
const o = (l) => l === null ? null : JSON.parse(l, void 0), c = (i = n.getItem(a)) != null ? i : null;
return c instanceof Promise ? c.then(o) : o(c);
},
setItem: (a, i) => n.setItem(a, JSON.stringify(i, void 0)),
removeItem: (a) => n.removeItem(a)
};
}
const br = (e) => (t) => {
try {
const n = e(t);
return n instanceof Promise ? n : {
then(s) {
return br(s)(n);
},
catch(s) {
return this;
}
};
} catch (n) {
return {
then(s) {
return this;
},
catch(s) {
return br(s)(n);
}
};
}
}, Ao = (e, t) => (n, s, a) => {
let i = {
storage: ko(() => localStorage),
partialize: (N) => N,
version: 0,
merge: (N, x) => ({
...x,
...N
}),
...t
}, o = !1;
const c = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set();
let u = i.storage;
if (!u)
return e(
(...N) => {
console.warn(
`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`
), n(...N);
},
s,
a
);
const h = () => {
const N = i.partialize({ ...s() });
return u.setItem(i.name, {
state: N,
version: i.version
});
}, f = a.setState;
a.setState = (N, x) => (f(N, x), h());
const m = e(
(...N) => (n(...N), h()),
s,
a
);
a.getInitialState = () => m;
let g;
const b = () => {
var N, x;
if (!u) return;
o = !1, c.forEach((w) => {
var y;
return w((y = s()) != null ? y : m);
});
const A = ((x = i.onRehydrateStorage) == null ? void 0 : x.call(i, (N = s()) != null ? N : m)) || void 0;
return br(u.getItem.bind(u))(i.name).then((w) => {
if (w)
if (typeof w.version == "number" && w.version !== i.version) {
if (i.migrate) {
const y = i.migrate(
w.state,
w.version
);
return y instanceof Promise ? y.then((C) => [!0, C]) : [!0, y];
}
console.error(
"State loaded from storage couldn't be migrated since no migrate function was provided"
);
} else
return [!1, w.state];
return [!1, void 0];
}).then((w) => {
var y;
const [C, T] = w;
if (g = i.merge(
T,
(y = s()) != null ? y : m
), n(g, !0), C)
return h();
}).then(() => {
A?.(g, void 0), g = s(), o = !0, l.forEach((w) => w(g));
}).catch((w) => {
A?.(void 0, w);
});
};
return a.persist = {
setOptions: (N) => {
i = {
...i,
...N
}, N.storage && (u = N.storage);
},
clearStorage: () => {
u?.removeItem(i.name);
},
getOptions: () => i,
rehydrate: () => b(),
hasHydrated: () => o,
onHydrate: (N) => (c.add(N), () => {
c.delete(N);
}),
onFinishHydration: (N) => (l.add(N), () => {
l.delete(N);
})
}, i.skipHydration || b(), g || m;
}, Mo = Ao, Io = () => ({
// Edit mode
isEditMode: !1,
selectedFilterId: null,
// Modal state
isPortletModalOpen: !1,
editingPortlet: null,
isFilterConfigModalOpen: !1,
filterConfigPortlet: null,
deleteConfirmPortletId: null,
// Layout state
draftRows: null,
isDraggingPortlet: !1,
lastKnownLayout: [],
isInitialized: !1,
dragState: null,
// Debug data
debugData: {}
});
function Eo(e) {
return {
...Io(),
isEditMode: e.initialEditMode ?? !1
};
}
function Fo(e, t, n) {
return {
// =================================================================
// Edit Mode Actions
// =================================================================
setEditMode: (s) => e({
isEditMode: s,
// Exit filter selection mode when leaving edit mode
selectedFilterId: null
}),
toggleEditMode: () => e((s) => ({
isEditMode: !s.isEditMode,
// Exit filter selection mode when toggling
selectedFilterId: null
})),
setSelectedFilterId: (s) => e({ selectedFilterId: s }),
exitFilterSelectionMode: () => e({ selectedFilterId: null }),
// =================================================================
// Modal Actions
// =================================================================
openPortletModal: (s) => e({
isPortletModalOpen: !0,
editingPortlet: s ?? null
}),
closePortletModal: () => e({
isPortletModalOpen: !1,
editingPortlet: null
}),
openFilterConfigModal: (s) => e({
isFilterConfigModalOpen: !0,
filterConfigPortlet: s
}),
closeFilterConfigModal: () => e({
isFilterConfigModalOpen: !1,
filterConfigPortlet: null
}),
openDeleteConfirm: (s) => e({ deleteConfirmPortletId: s }),
closeDeleteConfirm: () => e({ deleteConfirmPortletId: null }),
// =================================================================
// Layout Actions
// =================================================================
setDraftRows: (s) => e({ draftRows: s }),
setIsDraggingPortlet: (s) => e({ isDraggingPortlet: s }),
setLastKnownLayout: (s) => e({ lastKnownLayout: s }),
setIsInitialized: (s) => e({ isInitialized: s }),
setDragState: (s) => e({ dragState: s }),
clearDragState: () => e({
dragState: null,
isDraggingPortlet: !1
}),
// =================================================================
// Debug Data Actions
// =================================================================
setDebugData: (s, a) => e((i) => ({
debugData: {
...i.debugData,
[s]: a
}
})),
clearDebugData: (s) => e((a) => {
if (s) {
const { [s]: i, ...o } = a.debugData;
return { debugData: o };
}
return { debugData: {} };
}),
// =================================================================
// Utility Actions
// =================================================================
reset: () => e(n)
};
}
function wa(e = {}) {
const t = Eo(e);
return pr()(
gr(
yr((n, s) => ({
...t,
...Fo(n, s, t)
})),
{ name: "DashboardStore" }
)
);
}
let Yn = null;
function Ro() {
return Yn || (Yn = wa()), Yn;
}
const Qn = ia(null);
function _o({
children: e,
initialEditMode: t
}) {
const n = ge(null);
return n.current || (n.current = wa({
initialEditMode: t
})), /* @__PURE__ */ r(Qn.Provider, { value: n.current, children: e });
}
function Ut(e) {
const t = sn(Qn);
if (!t)
throw new Error("useDashboardStore must be used within DashboardStoreProvider");
return Er(t, e);
}
function qu() {
const e = sn(Qn);
if (!e)
throw new Error("useDashboardStoreApi must be used within DashboardStoreProvider");
return e;
}
function Bu(e) {
const t = sn(Qn), n = Er(t ?? Ro(), e);
return t ? n : null;
}
const Qu = (e) => ({
isEditMode: e.isEditMode,
selectedFilterId: e.selectedFilterId
}), ju = (e) => ({
isPortletModalOpen: e.isPortletModalOpen,
editingPortlet: e.editingPortlet,
isFilterConfigModalOpen: e.isFilterConfigModalOpen,
filterConfigPortlet: e.filterConfigPortlet
}), Ku = (e) => ({
draftRows: e.draftRows,
isDraggingPortlet: e.isDraggingPortlet,
lastKnownLayout: e.lastKnownLayout,
isInitialized: e.isInitialized,
dragState: e.dragState
}), Vu = (e) => e.debugData, Uu = (e) => (t) => t.debugData[e], Hu = (e) => ({
setEditMode: e.setEditMode,
toggleEditMode: e.toggleEditMode,
setSelectedFilterId: e.setSelectedFilterId,
exitFilterSelectionMode: e.exitFilterSelectionMode
}), zu = (e) => ({
openPortletModal: e.openPortletModal,
closePortletModal: e.closePortletModal,
openFilterConfigModal: e.openFilterConfigModal,
closeFilterConfigModal: e.closeFilterConfigModal,
openDeleteConfirm: e.openDeleteConfirm,
closeDeleteConfirm: e.closeDeleteConfirm
}), Gu = (e) => ({
setDraftRows: e.setDraftRows,
setIsDraggingPortlet: e.setIsDraggingPortlet,
setLastKnownLayout: e.setLastKnownLayout,
setIsInitialized: e.setIsInitialized,
setDragState: e.setDragState,
clearDragState: e.clearDragState
}), Wu = (e) => ({
setDebugData: e.setDebugData,
clearDebugData: e.clearDebugData
}), Yu = (e) => ({
// Edit mode
setEditMode: e.setEditMode,
toggleEditMode: e.toggleEditMode,
setSelectedFilterId: e.setSelectedFilterId,
exitFilterSelectionMode: e.exitFilterSelectionMode,
// Modals
openPortletModal: e.openPortletModal,
closePortletModal: e.closePortletModal,
openFilterConfigModal: e.openFilterConfigModal,
closeFilterConfigModal: e.closeFilterConfigModal,
openDeleteConfirm: e.openDeleteConfirm,
closeDeleteConfirm: e.closeDeleteConfirm,
// Layout
setDraftRows: e.setDraftRows,
setIsDraggingPortlet: e.setIsDraggingPortlet,
setLastKnownLayout: e.setLastKnownLayout,
setIsInitialized: e.setIsInitialized,
setDragState: e.setDragState,
clearDragState: e.clearDragState,
// Debug data
setDebugData: e.setDebugData,
clearDebugData: e.clearDebugData,
// Utility
reset: e.reset
}), Jt = { width: "16px", height: "16px", color: "currentColor" };
function Oo(e, t) {
if (e === t) return !0;
if (e.editable !== t.editable || e.configEagerLoad !== t.configEagerLoad || e.portlet !== t.portlet || e.dashboardFilters !== t.dashboardFilters || e.colorPalette !== t.colorPalette || e.loadingComponent !== t.loadingComponent || e.callbacks !== t.callbacks || e.icons !== t.icons || e.setPortletRef !== t.setPortletRef || e.setPortletComponentRef !== t.setPortletComponentRef)
return !1;
const n = ss(e.containerProps, t.containerProps), s = ss(e.headerProps, t.headerProps);
return n && s;
}
function ss(e, t) {
if (e === t) return !0;
if (!e || !t) return e === t;
const n = Object.keys(e), s = Object.keys(t);
if (n.length !== s.length) return !1;
for (const a of n)
if (e[a] !== t[a]) return !1;
return !0;
}
const $o = bt.memo(function({
portlet: t,
editable: n,
dashboardFilters: s,
configEagerLoad: a,
loadingComponent: i,
colorPalette: o,
containerProps: c,
headerProps: l,
setPortletRef: u,
setPortletComponentRef: h,
callbacks: f,
icons: m
}) {
const g = V(() => ln(t), [t]), { analysisConfig: b } = g, N = b.charts[b.analysisType], x = V(() => JSON.stringify(b.query), [b.query]), A = N?.chartType || "line", w = N?.chartConfig, y = N?.displayConfig, C = Ut((Q) => Q.isEditMode), T = Ut((Q) => Q.selectedFilterId), p = Ut((Q) => Q.debugData[t.id]), v = Ut((Q) => Q.setDebugData), k = T ? (t.dashboardFilterMapping || []).includes(T) : !1, S = !!T, $ = [
"bg-dc-surface border rounded-lg flex flex-col h-full transition-all",
S ? "cursor-pointer" : "",
c?.className
].filter(Boolean).join(" "), D = [
"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",
C ? "cursor-move" : "cursor-default",
l?.className
].filter(Boolean).join(" "), {
onClick: F,
className: K,
style: P,
...te
} = c ?? {}, {
onClick: _,
className: O,
style: ie,
...X
} = l ?? {}, ce = E((Q) => {
v(t.id, Q);
}, [t.id, v]);
return /* @__PURE__ */ d(
"div",
{
"data-portlet-id": t.id,
ref: (Q) => u(t.id, Q),
className: $,
style: {
boxShadow: "var(--dc-shadow-sm)",
borderColor: S && k ? "var(--dc-primary)" : "var(--dc-border)",
borderWidth: S && k ? "2px" : "1px",
backgroundColor: S && k ? "rgba(var(--dc-primary-rgb), 0.05)" : "var(--dc-surface)",
opacity: S && !k ? "0.5" : "1",
...P
},
onClick: (Q) => {
S && T && (Q.stopPropagation(), f.onToggleFilter(t.id, T)), F?.(Q);
},
...te,
children: [
(!y?.hideHeader || C) && /* @__PURE__ */ d(
"div",
{
className: D,
style: ie,
onClick: (Q) => {
_?.(Q);
},
...X,
children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
/* @__PURE__ */ r("h3", { className: "font-semibold text-sm text-dc-text truncate", children: t.title }),
n && C && p && /* @__PURE__ */ r(
"div",
{
onMouseDown: (Q) => {
Q.stopPropagation(), Q.preventDefault();
},
onClick: (Q) => Q.stopPropagation(),
onTouchStart: (Q) => {
Q.stopPropagation(), Q.preventDefault();
},
onTouchEnd: (Q) => Q.stopPropagation(),
children: /* @__PURE__ */ r(
va,
{
chartConfig: p.chartConfig,
displayConfig: p.displayConfig,
queryObject: p.queryObject,
data: p.data,
chartType: p.chartType,
cacheInfo: p.cacheInfo
}
)
}
)
] }),
/* @__PURE__ */ d(
"div",
{
className: "flex items-center gap-1 shrink-0 ml-4 -mr-2",
onMouseDown: (Q) => {
Q.stopPropagation(), Q.preventDefault();
},
onClick: (Q) => Q.stopPropagation(),
onTouchStart: (Q) => {
Q.stopPropagation(), Q.preventDefault();
},
onTouchEnd: (Q) => Q.stopPropagation(),
children: [
p?.cacheInfo && /* @__PURE__ */ r(
"span",
{
className: "p-1 text-dc-text-muted opacity-40",
title: `Cached ${Math.round((Date.now() - new Date(p.cacheInfo.cachedAt).getTime()) / 1e3)}s ago`,
children: /* @__PURE__ */ d(
"svg",
{
width: "12",
height: "12",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
children: [
/* @__PURE__ */ r("ellipse", { cx: "12", cy: "5", rx: "9", ry: "3" }),
/* @__PURE__ */ r("path", { d: "M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" }),
/* @__PURE__ */ r("path", { d: "M3 12c0 1.66 4 3 9 3s9-1.34 9-3" })
]
}
)
}
),
/* @__PURE__ */ r(
"button",
{
onClick: (Q) => {
Q.stopPropagation(), f.onRefresh(t.id);
},
onTouchEnd: (Q) => {
Q.stopPropagation(), Q.preventDefault(), f.onRefresh(t.id);
},
disabled: S,
className: `p-1 bg-transparent border-none rounded-sm text-dc-text-secondary transition-colors ${S ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-dc-surface-hover"}`,
title: "Refresh portlet data",
children: /* @__PURE__ */ r(m.RefreshIcon, { style: Jt })
}
),
n && C && !S && /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(
"button",
{
onClick: (Q) => {
Q.stopPropagation(), f.onOpenFilterConfig(t);
},
onTouchEnd: (Q) => {
Q.stopPropagation(), Q.preventDefault(), f.onOpenFilterConfig(t);
},
className: "p-1 bg-transparent border-none rounded-sm cursor-pointer hover:bg-dc-surface-hover transition-colors relative",
title: `Configure dashboard filters${t.dashboardFilterMapping && t.dashboardFilterMapping.length > 0 ? ` (${t.dashboardFilterMapping.length} active)` : ""}`,
style: {
color: t.dashboardFilterMapping && t.dashboardFilterMapping.length > 0 ? "var(--dc-primary)" : "var(--dc-text-secondary)"
},
children: /* @__PURE__ */ r(m.FilterIcon, { style: Jt })
}
),
/* @__PURE__ */ r(
"button",
{
onClick: (Q) => {
Q.stopPropagation(), f.onDuplicate(t.id);
},
onTouchEnd: (Q) => {
Q.stopPropagation(), Q.preventDefault(), f.onDuplicate(t.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__ */ r(m.CopyIcon, { style: Jt })
}
),
/* @__PURE__ */ r(
"button",
{
onClick: (Q) => {
Q.stopPropagation(), f.onEdit(t);
},
onTouchEnd: (Q) => {
Q.stopPropagation(), Q.preventDefault(), f.onEdit(t);
},
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__ */ r(m.EditIcon, { style: Jt })
}
),
/* @__PURE__ */ r(
"button",
{
onClick: (Q) => {
Q.stopPropagation(), f.onDelete(t.id);
},
onTouchEnd: (Q) => {
Q.stopPropagation(), Q.preventDefault(), f.onDelete(t.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__ */ r(m.DeleteIcon, { style: Jt })
}
)
] })
]
}
)
]
}
),
/* @__PURE__ */ r("div", { className: "flex-1 px-2 py-3 md:px-4 md:py-4 min-h-0 overflow-visible flex flex-col", children: /* @__PURE__ */ r(
Bn,
{
ref: (Q) => h(t.id, Q),
query: x,
chartType: A,
chartConfig: w,
displayConfig: y,
dashboardFilters: s,
dashboardFilterMapping: t.dashboardFilterMapping,
eagerLoad: t.eagerLoad ?? a ?? !1,
title: t.title,
height: "100%",
colorPalette: o,
loadingComponent: i,
onDebugDataReady: ce
}
) })
]
}
);
}, Oo), pn = 16;
function Lo({
rows: e,
portlets: t,
gridSettings: n,
gridWidth: s,
canEdit: a,
isDragging: i,
onRowResize: o,
onColumnResize: c,
onPortletDragStart: l,
onPortletDragEnd: u,
onRowDrop: h,
onNewRowDrop: f,
renderPortlet: m
}) {
const g = new Map(t.map((p) => [p.id, p])), [b, N] = ee(null), x = (p) => {
N(p);
}, A = i || b !== null, w = E((p) => {
const v = parseInt(p.currentTarget.dataset.rowIndex || "0", 10), k = parseInt(p.currentTarget.dataset.columnIndex || "0", 10), S = p.currentTarget.dataset.portletId || "";
l(v, k, S, p);
}, [l]), y = E(() => {
x(null), u();
}, [u]), C = b === "row-insert-0", T = b === "row-bottom";
return /* @__PURE__ */ d(
"div",
{
className: `dc-row-layout${a ? " dc-row-layout-editable" : ""}${A ? " dc-row-layout-dragging" : ""}`,
style: {
"--dc-row-gap": "24px",
"--dc-column-gap": `${pn}px`,
"--dc-top-drop-space": C ? "24px" : "0px",
"--dc-bottom-drop-space": T ? "24px" : "0px"
},
children: [
a && /* @__PURE__ */ r(
"div",
{
className: `dc-row-boundary-drop dc-row-boundary-drop-top dc-split-handle${b === "row-insert-0" ? " dc-drop-zone-active" : ""}`,
onDragOver: (p) => {
p.preventDefault(), x("row-insert-0");
},
onDragLeave: () => x(null),
onDrop: (p) => {
p.preventDefault(), x(null), f(0);
}
}
),
e.map((p, v) => {
const k = p.h * n.rowHeight, S = s || n.cols * n.rowHeight, $ = b === `row-${v}-insert-0` ? pn : 0, D = b === `row-${v}-insert-${p.columns.length}` ? pn : 0, K = (S - (p.columns.length - 1) * pn - $ - D) / n.cols;
return /* @__PURE__ */ d("div", { className: "dc-row-layout-row-wrapper", children: [
/* @__PURE__ */ r(
"div",
{
className: "dc-row-layout-row",
style: { height: k, paddingLeft: $, paddingRight: D },
children: p.columns.map((P, te) => {
const _ = g.get(P.portletId);
if (!_) return null;
const O = P.w * K, ie = {
draggable: a,
"data-row-index": v.toString(),
"data-column-index": te.toString(),
"data-portlet-id": _.id,
onDragStart: w,
onDragEnd: y,
className: "dc-row-layout-column"
};
return /* @__PURE__ */ d(
"div",
{
className: "dc-row-layout-column-wrapper",
style: {
flex: `0 0 ${O}px`,
maxWidth: `${O}px`
},
children: [
m(_, ie),
te < p.columns.length - 1 && /* @__PURE__ */ r(
"div",
{
className: `dc-column-resize-handle dc-split-handle${b === `row-${v}-insert-${te + 1}` ? " dc-drop-zone-active" : ""}`,
onMouseDown: (X) => c(v, te, X),
onDragOver: (X) => {
a && (X.preventDefault(), x(`row-${v}-insert-${te + 1}`));
},
onDragLeave: () => x(null),
onDrop: (X) => {
a && (X.preventDefault(), X.stopPropagation(), x(null), h(v, te + 1));
}
}
)
]
},
_.id
);
})
}
),
a && /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(
"div",
{
className: `dc-row-edge-drop dc-row-edge-drop-left dc-split-handle${b === `row-${v}-insert-0` ? " dc-drop-zone-active" : ""}`,
onDragOver: (P) => {
P.preventDefault(), x(`row-${v}-insert-0`);
},
onDragLeave: () => {
x(null);
},
onDrop: (P) => {
P.preventDefault(), x(null), h(v, 0);
}
}
),
/* @__PURE__ */ r(
"div",
{
className: `dc-row-edge-drop dc-row-edge-drop-right dc-split-handle${b === `row-${v}-insert-${p.columns.length}` ? " dc-drop-zone-active" : ""}`,
onDragOver: (P) => {
P.preventDefault(), x(`row-${v}-insert-${p.columns.length}`);
},
onDragLeave: () => {
x(null);
},
onDrop: (P) => {
P.preventDefault(), x(null), h(v, p.columns.length);
}
}
)
] }),
a && /* @__PURE__ */ r(
"div",
{
className: `dc-row-resize-handle dc-split-handle${b === `row-insert-${v + 1}` ? " dc-drop-zone-active" : ""}`,
onMouseDown: (P) => o(v, P),
onDragOver: (P) => {
P.preventDefault(), x(`row-insert-${v + 1}`);
},
onDragLeave: () => x(null),
onDrop: (P) => {
P.preventDefault(), x(null), f(v + 1);
}
}
)
] }, p.id);
}),
a && /* @__PURE__ */ r(
"div",
{
className: `dc-row-boundary-drop dc-row-boundary-drop-bottom dc-split-handle${b === "row-bottom" ? " dc-drop-zone-active" : ""}`,
onDragOver: (p) => {
p.preventDefault(), x("row-bottom");
},
onDragLeave: () => x(null),
onDrop: (p) => {
p.preventDefault(), x(null), f(e.length);
}
}
)
]
}
);
}
const tn = [
{
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 Fr(e) {
return e && tn.find((n) => n.name === e) || tn[0];
}
const Po = q("edit"), qo = q("check"), Bo = q("segment"), Qo = q("table"), jo = q("add"), Ko = q("swatch");
function Vo({
isEditBarVisible: e,
position: t,
isEditMode: n,
onEditModeToggle: s,
layoutMode: a,
onLayoutModeChange: i,
allowedModes: o,
canChangeLayoutMode: c,
currentPalette: l,
onPaletteChange: u,
onAddPortlet: h
}) {
const [f, m] = ee(!1), g = ge(null);
he(() => {
if (!f) return;
const w = (y) => {
g.current && !g.current.contains(y.target) && m(!1);
};
return document.addEventListener("mousedown", w), () => document.removeEventListener("mousedown", w);
}, [f]), he(() => {
e && m(!1);
}, [e]);
const b = t === "left" ? "left-4" : "right-4", N = e, A = /* @__PURE__ */ d(
"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
${b} ${t === "left" ? N ? "-translate-x-16 opacity-0 pointer-events-none" : "translate-x-0 opacity-100" : N ? "translate-x-16 opacity-0 pointer-events-none" : "translate-x-0 opacity-100"}`,
style: {
boxShadow: "var(--dc-shadow-lg)"
},
children: [
/* @__PURE__ */ r(
Xt,
{
icon: n ? qo : Po,
tooltip: n ? "Finish Editing" : "Edit Dashboard",
isActive: n,
onClick: s
}
),
n && o.length > 1 && /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("div", { className: "w-full h-px bg-dc-border my-0.5" }),
/* @__PURE__ */ r(
Xt,
{
icon: Bo,
tooltip: "Grid Layout",
isActive: a === "grid",
disabled: !c,
onClick: () => i("grid")
}
),
/* @__PURE__ */ r(
Xt,
{
icon: Qo,
tooltip: "Rows Layout",
isActive: a === "rows",
disabled: !c,
onClick: () => i("rows")
}
)
] }),
n && /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("div", { className: "w-full h-px bg-dc-border my-0.5" }),
/* @__PURE__ */ d("div", { ref: g, className: "relative", children: [
/* @__PURE__ */ r(
Xt,
{
icon: Ko,
tooltip: "Color Palette",
isActive: f,
onClick: () => m(!f)
}
),
f && /* @__PURE__ */ r(
Uo,
{
position: t,
currentPalette: l,
onPaletteChange: (w) => {
u(w), m(!1);
}
}
)
] })
] }),
n && /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("div", { className: "w-full h-px bg-dc-border my-0.5" }),
/* @__PURE__ */ r(
Xt,
{
icon: jo,
tooltip: "Add Portlet",
onClick: h
}
)
] })
]
}
);
return typeof document > "u" ? null : Bi(A, document.body);
}
function Xt({ icon: e, tooltip: t, isActive: n, disabled: s, onClick: a }) {
return /* @__PURE__ */ r(
"button",
{
type: "button",
onClick: a,
disabled: s,
title: t,
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__ */ r(e, { className: "w-5 h-5" })
}
);
}
function Uo({ position: e, currentPalette: t, onPaletteChange: n }) {
return /* @__PURE__ */ r(
"div",
{
className: `absolute top-0 ${e === "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__ */ r("div", { className: "py-1", children: tn.slice().sort((a, i) => a.label.localeCompare(i.label)).map((a) => /* @__PURE__ */ r(
"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 === t ? "bg-dc-surface-secondary text-dc-primary" : "text-dc-text-secondary"}`,
children: /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r("div", { className: "flex gap-0.5 shrink-0", children: a.colors.slice(0, 4).map((i, o) => /* @__PURE__ */ r(
"div",
{
className: "w-2.5 h-2.5 rounded-xs border border-dc-border",
style: { backgroundColor: i }
},
o
)) }),
/* @__PURE__ */ r("span", { className: "text-xs font-medium truncate text-dc-text", children: a.label }),
a.name === t && /* @__PURE__ */ r("div", { className: "ml-auto w-1.5 h-1.5 rounded-full shrink-0 bg-dc-primary" })
] })
},
a.name
)) })
}
);
}
const Rr = ({
isOpen: e,
onClose: t,
title: n,
size: s = "md",
closeOnBackdropClick: a = !0,
closeOnEscape: i = !0,
showCloseButton: o = !0,
children: c,
footer: l,
noPadding: u = !1
}) => {
const h = E((m) => {
m.key === "Escape" && i && t();
}, [i, t]);
return he(() => (e ? (i && document.addEventListener("keydown", h), document.body.style.overflow = "hidden") : document.body.style.overflow = "unset", () => {
document.removeEventListener("keydown", h), document.body.style.overflow = "unset";
}), [e, i, h]), e ? /* @__PURE__ */ r(
"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 ? t : void 0,
children: /* @__PURE__ */ d(
"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 || o) && /* @__PURE__ */ d("div", { className: "flex items-center justify-between px-6 py-4 border-b border-dc-border", children: [
n && /* @__PURE__ */ r("h2", { id: "modal-title", className: "text-xl font-semibold text-dc-text", children: n }),
o && /* @__PURE__ */ r(
"button",
{
type: "button",
onClick: t,
className: "text-dc-text-muted hover:text-dc-text-secondary transition-colors p-2 -mr-2",
"aria-label": "Close modal",
children: /* @__PURE__ */ r("svg", { width: "24", height: "24", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ r("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
}
)
] }),
/* @__PURE__ */ r("div", { className: `flex-1 overflow-y-auto ${u ? "" : "px-6 py-4"}`, children: c }),
l && /* @__PURE__ */ r("div", { className: "flex items-center justify-end space-x-3 px-6 py-4 border-t border-dc-border bg-dc-surface-secondary", children: bt.Children.toArray(l) })
]
}
)
}
) : null;
};
function lt() {
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
function rn(e) {
let t = "", n = e;
do
t = String.fromCharCode(65 + n % 26) + t, n = Math.floor(n / 26) - 1;
while (n >= 0);
return t;
}
function Ho(e) {
const t = /* @__PURE__ */ new Date(), n = e.toLowerCase().trim(), s = t.getUTCFullYear(), a = t.getUTCMonth(), i = t.getUTCDate(), o = t.getUTCDay();
if (n === "today") {
const f = new Date(t);
f.setUTCHours(0, 0, 0, 0);
const m = new Date(t);
return m.setUTCHours(23, 59, 59, 999), { start: f, end: m };
}
if (n === "yesterday") {
const f = new Date(t);
f.setUTCDate(i - 1), f.setUTCHours(0, 0, 0, 0);
const m = new Date(t);
return m.setUTCDate(i - 1), m.setUTCHours(23, 59, 59, 999), { start: f, end: m };
}
if (n === "this week") {
const f = o === 0 ? -6 : 1 - o, m = new Date(t);
m.setUTCDate(i + f), m.setUTCHours(0, 0, 0, 0);
const g = new Date(m);
return g.setUTCDate(m.getUTCDate() + 6), g.setUTCHours(23, 59, 59, 999), { start: m, end: g };
}
if (n === "this month") {
const f = 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: f, end: m };
}
if (n === "this quarter") {
const f = Math.floor(a / 3), m = new Date(Date.UTC(s, f * 3, 1, 0, 0, 0, 0)), g = new Date(Date.UTC(s, f * 3 + 3, 0, 23, 59, 59, 999));
return { start: m, end: g };
}
if (n === "this year") {
const f = 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: f, end: m };
}
const c = n.match(/^last\s+(\d+)\s+days?$/);
if (c) {
const f = parseInt(c[1], 10), m = new Date(t);
m.setUTCDate(i - f + 1), m.setUTCHours(0, 0, 0, 0);
const g = new Date(t);
return g.setUTCHours(23, 59, 59, 999), { start: m, end: g };
}
const l = n.match(/^last\s+(\d+)\s+weeks?$/);
if (l) {
const m = parseInt(l[1], 10) * 7, g = new Date(t);
g.setUTCDate(i - m + 1), g.setUTCHours(0, 0, 0, 0);
const b = new Date(t);
return b.setUTCHours(23, 59, 59, 999), { start: g, end: b };
}
if (n === "last week") {
const f = o === 0 ? -13 : -6 - o, m = new Date(t);
m.setUTCDate(i + f), m.setUTCHours(0, 0, 0, 0);
const g = new Date(m);
return g.setUTCDate(m.getUTCDate() + 6), g.setUTCHours(23, 59, 59, 999), { start: m, end: g };
}
if (n === "last month") {
const f = 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: f, end: m };
}
if (n === "last quarter") {
const f = Math.floor(a / 3), m = f === 0 ? 3 : f - 1, g = f === 0 ? s - 1 : s, b = new Date(Date.UTC(g, m * 3, 1, 0, 0, 0, 0)), N = new Date(Date.UTC(g, m * 3 + 3, 0, 23, 59, 59, 999));
return { start: b, end: N };
}
if (n === "last year") {
const f = 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: f, end: m };
}
if (n === "last 12 months") {
const f = new Date(Date.UTC(s, a - 11, 1, 0, 0, 0, 0)), m = new Date(t);
return m.setUTCHours(23, 59, 59, 999), { start: f, end: m };
}
const u = n.match(/^last\s+(\d+)\s+months?$/);
if (u) {
const f = parseInt(u[1], 10), m = new Date(Date.UTC(s, a - f + 1, 1, 0, 0, 0, 0)), g = new Date(t);
return g.setUTCHours(23, 59, 59, 999), { start: m, end: g };
}
const h = n.match(/^last\s+(\d+)\s+years?$/);
if (h) {
const f = parseInt(h[1], 10), m = new Date(Date.UTC(s - f, 0, 1, 0, 0, 0, 0)), g = new Date(t);
return g.setUTCHours(23, 59, 59, 999), { start: m, end: g };
}
return null;
}
function zo(e) {
if (Array.isArray(e)) {
if (e.length < 2) return null;
const t = new Date(e[0]), n = new Date(e[1]);
return isNaN(t.getTime()) || isNaN(n.getTime()) ? null : (n.setUTCHours(23, 59, 59, 999), { start: t, end: n });
}
return Ho(e);
}
function gn(e) {
return e.toISOString().split("T")[0];
}
function Go(e, t) {
const n = t.getTime() - e.getTime(), s = Math.ceil(n / (1e3 * 60 * 60 * 24)), a = new Date(e);
a.setUTCDate(a.getUTCDate() - 1), a.setUTCHours(23, 59, 59, 999);
const i = new Date(a);
return i.setUTCDate(i.getUTCDate() - s + 1), i.setUTCHours(0, 0, 0, 0), { start: i, end: a };
}
function Na(e, t) {
for (const n of e)
if ("type" in n && "filters" in n) {
const a = Na(n.filters, t);
if (a) return a;
} else if ("member" in n) {
const s = n;
if (s.member === t && s.operator === "inDateRange" && s.dateRange)
return { dateRange: s.dateRange };
}
}
function Ca(e, t) {
const n = Na(t, e);
if (!n?.dateRange) return;
const s = zo(n.dateRange);
if (!s) return;
const a = Go(s.start, s.end);
return [
[gn(s.start), gn(s.end)],
[gn(a.start), gn(a.end)]
];
}
function Sa(e, t) {
return e.reduce((n, s) => {
if ("type" in s && "filters" in s) {
const a = s, i = Sa(a.filters, t);
i.length > 0 && n.push({ type: a.type, filters: i });
} else if ("member" in s) {
const a = s;
a.member === t && a.operator === "inDateRange" || n.push(s);
} else
n.push(s);
return n;
}, []);
}
function In(e, t, n, s, a = !1) {
const i = t.filter((l) => l.isTimeDimension && l.enableComparison).map((l) => l.field);
let o = n;
if (!a)
for (const l of i)
o = Sa(o, l);
const c = {
measures: e.map((l) => l.field),
dimensions: t.filter((l) => !l.isTimeDimension).map((l) => l.field),
timeDimensions: t.filter((l) => l.isTimeDimension).map((l) => {
const u = {
dimension: l.field,
granularity: l.granularity || "day"
};
if (l.enableComparison) {
const h = Ca(l.field, n);
h && (u.compareDateRange = h);
}
return u;
}),
filters: o.length > 0 ? o : void 0,
order: s && Object.keys(s).length > 0 ? s : void 0
};
return c.measures?.length === 0 && delete c.measures, c.dimensions?.length === 0 && delete c.dimensions, c.timeDimensions?.length === 0 && delete c.timeDimensions, c;
}
const Wo = "drizzle-cube-analysis-builder-v3";
function Ve() {
return {
metrics: [],
breakdowns: [],
filters: [],
order: void 0,
validationStatus: "idle",
validationError: null
};
}
function jn(e, t) {
if (!t) return null;
for (const n of t.cubes) {
const s = n.measures.find((i) => i.name === e);
if (s)
return { field: s, cubeName: n.name, fieldType: "measure" };
const a = n.dimensions.find((i) => i.name === e);
if (a)
return {
field: a,
cubeName: n.name,
fieldType: a.type === "time" ? "timeDimension" : "dimension"
};
}
return null;
}
function _r(e, t) {
const n = jn(e, t);
return n && (n.field.title || n.field.shortTitle) || e;
}
function Da(e, t) {
if (!e) return [];
const n = [];
for (const s of e.cubes)
if (t === "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 (t === "breakdown" || t === "dimensionFilter")
for (const a of s.dimensions) {
const i = 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: i ? "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 i = 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: i ? "timeDimension" : "dimension"
});
}
}
return n;
}
function Yo(e, t, n) {
let s = e;
if (n && n !== "all" && (s = s.filter((a) => a.cubeName === n)), t.trim()) {
const a = t.toLowerCase();
s = s.filter(
(i) => i.name.toLowerCase().includes(a) || i.title.toLowerCase().includes(a) || (i.description?.toLowerCase().includes(a) ?? !1)
);
}
return s;
}
function Jo(e) {
const t = /* @__PURE__ */ new Map();
for (const n of e) {
const s = t.get(n.cubeName) || [];
s.push(n), t.set(n.cubeName, s);
}
return t;
}
function Xo(e) {
return e ? e.cubes.map((t) => t.name) : [];
}
function yn(e, t) {
return t && t.cubes.find((s) => s.name === e)?.title || e;
}
function Zo(e, t) {
const n = /* @__PURE__ */ new Set();
if (!t) return n;
n.add(e);
const s = t.cubes.find((a) => a.name === e);
if (!s || !s.relationships) return n;
for (const a of s.relationships)
n.add(a.targetCube);
return n;
}
function el(e, t) {
if (!t) return null;
const n = Zo(e, t);
return {
cubes: t.cubes.filter((s) => n.has(s.name)).map((s) => ({
...s,
description: s.description || ""
}))
};
}
const Ta = "drizzle-cube-recent-fields", tl = 10;
function ka() {
try {
const e = localStorage.getItem(Ta);
if (e)
return JSON.parse(e);
} catch {
}
return { metrics: [], breakdowns: [] };
}
function nl(e, t) {
try {
const n = ka(), a = n[t].filter((i) => i !== e);
a.unshift(e), n[t] = a.slice(0, tl), localStorage.setItem(Ta, JSON.stringify(n));
} catch {
}
}
function rl(e, t, n) {
if (!e || n.length === 0) return [];
const s = Da(e, t), a = [];
for (const i of n) {
const o = s.find((c) => c.name === i);
o && a.push(o);
}
return a;
}
function as() {
return {
metrics: [],
breakdowns: [],
filters: [],
order: void 0,
validationStatus: "idle",
validationError: null
};
}
function sl(e) {
return e.map((t) => t.field);
}
function al(e, t) {
const n = [], s = [];
for (const a of e)
if (a.isTimeDimension) {
const i = {
dimension: a.field,
granularity: a.granularity || "day"
};
if (a.enableComparison) {
const o = Ca(a.field, t);
o && (i.compareDateRange = o);
}
s.push(i);
} else
n.push(a.field);
return { dimensions: n, timeDimensions: s };
}
function il(e) {
const { dimensions: t, timeDimensions: n } = al(
e.breakdowns,
e.filters
), s = {
measures: sl(e.metrics),
dimensions: t
};
return n.length > 0 && (s.timeDimensions = n), e.filters.length > 0 && (s.filters = e.filters), e.order && Object.keys(e.order).length > 0 && (s.order = e.order), s;
}
function ol(e) {
return e.map((t, n) => ({
id: lt(),
field: t,
label: rn(n)
}));
}
function ll(e) {
const t = [];
if (e.dimensions)
for (const n of e.dimensions)
t.push({
id: lt(),
field: n,
isTimeDimension: !1
});
if (e.timeDimensions)
for (const n of e.timeDimensions) {
const s = !!(n.compareDateRange && n.compareDateRange.length > 0);
t.push({
id: lt(),
field: n.dimension,
granularity: n.granularity,
isTimeDimension: !0,
enableComparison: s
});
}
return t;
}
function is(e) {
return {
metrics: ol(e.measures || []),
breakdowns: ll(e),
filters: e.filters || [],
order: e.order,
validationStatus: "idle",
validationError: null
};
}
function cl(e) {
return typeof e == "object" && e !== null && "queries" in e && Array.isArray(e.queries);
}
const St = {
type: "query",
createInitial() {
return {
queryStates: [as()],
activeQueryIndex: 0,
mergeStrategy: "concat"
};
},
extractState(e) {
return {
queryStates: e.queryStates,
activeQueryIndex: e.activeQueryIndex,
mergeStrategy: e.mergeStrategy
};
},
canLoad(e) {
if (!e || typeof e != "object") return !1;
const t = e;
return !(t.version !== 1 || t.analysisType !== "query" || !t.query || typeof t.query != "object");
},
load(e) {
if (e.analysisType !== "query")
throw new Error(
`Cannot load ${e.analysisType} config with query adapter`
);
const t = e;
if (cl(t.query)) {
const n = t.query, s = n.queries.map(is);
return s.length === 0 && s.push(as()), {
queryStates: s,
activeQueryIndex: 0,
mergeStrategy: n.mergeStrategy || "concat"
};
}
return {
queryStates: [is(t.query)],
activeQueryIndex: 0,
mergeStrategy: "concat"
};
},
save(e, t, n) {
const s = e.queryStates.map(il), i = s.length === 1 && e.mergeStrategy === "concat" ? s[0] : {
queries: s,
mergeStrategy: e.mergeStrategy
};
return {
version: 1,
analysisType: "query",
activeView: n,
charts: {
query: t.query || this.getDefaultChartConfig()
},
query: i
};
},
validate(e) {
const t = [], n = [];
if (e.queryStates.some((a) => a.metrics.length > 0) || t.push("At least one metric is required"), e.queryStates.forEach((a, i) => {
const o = e.queryStates.length > 1 ? `Query ${i + 1}: ` : "";
a.metrics.length === 0 && a.breakdowns.length === 0 && n.push(`${o}Query is empty`);
}), e.queryStates.length > 1 && e.mergeStrategy === "merge") {
const a = e.queryStates[0].breakdowns.map(
(o) => o.field
);
e.queryStates.every((o) => {
const c = o.breakdowns.map((l) => l.field);
return c.length === a.length && c.every((l) => a.includes(l));
}) || n.push(
"Queries have different breakdowns - merge results may be unexpected"
);
}
return {
isValid: t.length === 0,
errors: t,
warnings: n
};
},
clear(e) {
return this.createInitial();
},
getDefaultChartConfig() {
return {
chartType: "bar",
chartConfig: {},
displayConfig: { showLegend: !0, showGrid: !0, showTooltip: !0 }
};
}
};
function dl(e) {
let t = "";
e.funnelBindingKey && (typeof e.funnelBindingKey.dimension == "string" ? t = e.funnelBindingKey.dimension : Array.isArray(e.funnelBindingKey.dimension) && (t = e.funnelBindingKey.dimension.map((a) => ({
cube: a.cube,
dimension: a.dimension
}))));
let n = e.funnelTimeDimension || "";
const s = e.funnelSteps.map((a) => {
const i = {
name: a.name
};
return a.cube && a.cube !== e.funnelCube && (i.cube = a.cube), a.filters && a.filters.length > 0 && (i.filter = a.filters.length === 1 ? a.filters[0] : { and: a.filters }), a.timeToConvert && (i.timeToConvert = a.timeToConvert), i;
});
return {
funnel: {
bindingKey: t,
timeDimension: n,
steps: s,
includeTimeMetrics: !0
}
};
}
function ul(e) {
const { funnel: t } = e;
let n = null;
if (t.steps.length > 0 && t.steps[0].cube)
n = t.steps[0].cube;
else if (typeof t.bindingKey == "string") {
const o = t.bindingKey.split(".");
o.length > 0 && (n = o[0]);
}
let s = null;
t.bindingKey && (typeof t.bindingKey == "string" ? s = { dimension: t.bindingKey } : Array.isArray(t.bindingKey) && (s = {
dimension: t.bindingKey.map((o) => ({
cube: o.cube,
dimension: o.dimension
}))
}));
let a = null;
t.timeDimension && (typeof t.timeDimension == "string" ? a = t.timeDimension : Array.isArray(t.timeDimension) && t.timeDimension.length > 0 && (a = `${t.timeDimension[0].cube}.${t.timeDimension[0].dimension}`));
const i = t.steps.map((o) => {
let c = [];
return o.filter && (Array.isArray(o.filter) ? c = o.filter : typeof o.filter == "object" && "and" in o.filter ? c = o.filter.and : c = [o.filter]), {
id: lt(),
name: o.name,
cube: o.cube || n || "",
filters: c,
timeToConvert: o.timeToConvert
};
});
return {
funnelCube: n,
funnelSteps: i,
activeFunnelStepIndex: 0,
funnelTimeDimension: a,
funnelBindingKey: s
};
}
function fl(e) {
if (!e || typeof e != "object") return !1;
const t = e;
if (t.version !== 1 || t.analysisType !== "funnel" || !t.query || typeof t.query != "object") return !1;
const n = t.query;
return !(!n.funnel || typeof n.funnel != "object");
}
const Qt = {
type: "funnel",
createInitial() {
return {
funnelCube: null,
funnelSteps: [],
activeFunnelStepIndex: 0,
funnelTimeDimension: null,
funnelBindingKey: null
};
},
extractState(e) {
return {
funnelCube: e.funnelCube,
funnelSteps: e.funnelSteps,
activeFunnelStepIndex: e.activeFunnelStepIndex,
funnelTimeDimension: e.funnelTimeDimension,
funnelBindingKey: e.funnelBindingKey
};
},
canLoad(e) {
return fl(e);
},
load(e) {
if (e.analysisType !== "funnel")
throw new Error(
`Cannot load ${e.analysisType} config with funnel adapter`
);
return ul(e.query);
},
save(e, t, n) {
return {
version: 1,
analysisType: "funnel",
activeView: n,
charts: {
funnel: t.funnel || this.getDefaultChartConfig()
},
query: dl(e)
};
},
validate(e) {
const t = [], n = [];
e.funnelSteps.length < 2 && t.push("A funnel requires at least 2 steps"), e.funnelBindingKey?.dimension || t.push("A binding key is required to link funnel steps"), e.funnelTimeDimension || t.push("A time dimension is required for funnel ordering"), e.funnelSteps.forEach((i, o) => {
(!i.name || i.name.trim() === "") && n.push(`Step ${o + 1} has no name`), i.filters.length === 0 && n.push(
`Step ${o + 1} "${i.name}" has no filter - all events will match`
);
});
const s = e.funnelSteps.map((i) => i.name.toLowerCase()), a = s.filter(
(i, o) => s.indexOf(i) !== o
);
return a.length > 0 && n.push(`Duplicate step names: ${[...new Set(a)].join(", ")}`), {
isValid: t.length === 0,
errors: t,
warnings: n
};
},
clear(e) {
return {
...this.createInitial(),
funnelCube: e.funnelCube
};
},
getDefaultChartConfig() {
return {
chartType: "funnel",
chartConfig: {},
displayConfig: { showLegend: !0, showGrid: !0, showTooltip: !0 }
};
}
};
function ml(e) {
let t = "";
e.flowBindingKey && (typeof e.flowBindingKey.dimension == "string" ? t = e.flowBindingKey.dimension : Array.isArray(e.flowBindingKey.dimension) && (t = e.flowBindingKey.dimension.map((a) => ({
cube: a.cube,
dimension: a.dimension
}))));
const n = e.flowTimeDimension || "", s = {
name: e.startingStep.name || "Starting Step",
filter: e.startingStep.filters.length === 1 ? e.startingStep.filters[0] : e.startingStep.filters.length > 1 ? e.startingStep.filters : void 0
};
return {
flow: {
bindingKey: t,
timeDimension: n,
startingStep: s,
stepsBefore: e.stepsBefore,
stepsAfter: e.stepsAfter,
eventDimension: e.eventDimension || "",
joinStrategy: e.joinStrategy
}
};
}
function hl(e) {
const { flow: t } = e;
let n = null;
if (typeof t.bindingKey == "string") {
const o = t.bindingKey.split(".");
o.length > 0 && (n = o[0]);
} else Array.isArray(t.bindingKey) && t.bindingKey.length > 0 && (n = t.bindingKey[0].cube);
let s = null;
t.bindingKey && (typeof t.bindingKey == "string" ? s = { dimension: t.bindingKey } : Array.isArray(t.bindingKey) && (s = {
dimension: t.bindingKey.map((o) => ({
cube: o.cube,
dimension: o.dimension
}))
}));
let a = null;
t.timeDimension && (typeof t.timeDimension == "string" ? a = t.timeDimension : Array.isArray(t.timeDimension) && t.timeDimension.length > 0 && (a = `${t.timeDimension[0].cube}.${t.timeDimension[0].dimension}`));
let i = [];
return t.startingStep.filter && (Array.isArray(t.startingStep.filter) ? i = t.startingStep.filter : i = [t.startingStep.filter]), {
flowCube: n,
flowBindingKey: s,
flowTimeDimension: a,
startingStep: {
name: t.startingStep.name || "",
filters: i
},
stepsBefore: t.stepsBefore || 3,
stepsAfter: t.stepsAfter || 3,
eventDimension: t.eventDimension || null,
joinStrategy: t.joinStrategy || "auto"
};
}
function pl(e) {
if (!e || typeof e != "object") return !1;
const t = e;
if (t.version !== 1 || t.analysisType !== "flow" || !t.query || typeof t.query != "object") return !1;
const n = t.query;
return !(!n.flow || typeof n.flow != "object");
}
const jt = {
type: "flow",
createInitial() {
return {
flowCube: null,
flowBindingKey: null,
flowTimeDimension: null,
startingStep: {
name: "",
filters: []
},
stepsBefore: 3,
stepsAfter: 3,
eventDimension: null,
joinStrategy: "auto"
};
},
extractState(e) {
return {
flowCube: e.flowCube,
flowBindingKey: e.flowBindingKey,
flowTimeDimension: e.flowTimeDimension,
startingStep: e.startingStep,
stepsBefore: e.stepsBefore,
stepsAfter: e.stepsAfter,
eventDimension: e.eventDimension,
joinStrategy: e.joinStrategy || "auto"
};
},
canLoad(e) {
return pl(e);
},
load(e) {
if (e.analysisType !== "flow")
throw new Error(
`Cannot load ${e.analysisType} config with flow adapter`
);
return hl(e.query);
},
save(e, t, n) {
return {
version: 1,
analysisType: "flow",
activeView: n,
charts: {
flow: t.flow || this.getDefaultChartConfig()
},
query: ml(e)
};
},
validate(e) {
const t = [], n = [];
return e.flowCube || t.push("Select an event stream cube for flow analysis"), e.flowBindingKey?.dimension || t.push("A binding key is required to link events to entities"), e.flowTimeDimension || t.push("A time dimension is required for event ordering"), e.eventDimension || t.push("An event dimension is required to categorize events"), e.startingStep.filters.length === 0 && t.push("The starting step must have at least one filter to identify the anchor event"), (e.stepsBefore < 0 || e.stepsBefore > 5) && t.push("Steps before must be between 0 and 5"), (e.stepsAfter < 0 || e.stepsAfter > 5) && t.push("Steps after must be between 0 and 5"), e.joinStrategy && !["auto", "lateral", "window"].includes(e.joinStrategy) && t.push("Join strategy must be auto, lateral, or window"), e.startingStep.name || n.push("Starting step has no name - using default"), (e.stepsBefore >= 4 || e.stepsAfter >= 4) && n.push("High step depth (4-5) may impact query performance on large datasets"), {
isValid: t.length === 0,
errors: t,
warnings: n
};
},
clear(e) {
return {
...this.createInitial(),
flowCube: e.flowCube
};
},
getDefaultChartConfig() {
return {
chartType: "sankey",
chartConfig: {},
displayConfig: {
showLegend: !0,
showGrid: !1,
showTooltip: !0
}
};
}
}, pt = /* @__PURE__ */ new Map();
let xr = !1;
function Jn() {
xr || (pt.has("query") || pt.set("query", St), pt.has("funnel") || pt.set("funnel", Qt), pt.has("flow") || pt.set("flow", jt), xr = !0);
}
const Ft = {
/**
* Register an adapter for a specific analysis type.
* Should be called once at app initialization.
*
* @param adapter - The adapter to register
*/
register(e) {
pt.has(e.type) && console.warn(
`[adapterRegistry] Overwriting existing adapter for type: ${e.type}`
), pt.set(e.type, e);
},
/**
* Get the adapter for a specific analysis type.
* Built-in adapters (query, funnel) are initialized automatically.
*
* @param type - The analysis type to get adapter for
* @returns The registered adapter
* @throws Error if no adapter is registered for the type
*/
get(e) {
Jn();
const t = pt.get(e);
if (!t)
throw new Error(
`[adapterRegistry] No adapter registered for type: ${e}. Available types: ${Array.from(pt.keys()).join(", ") || "none"}`
);
return t;
},
/**
* Check if an adapter is registered for a specific type.
* Built-in adapters (query, funnel) are initialized automatically.
*
* @param type - The analysis type to check
* @returns True if an adapter is registered
*/
has(e) {
return Jn(), pt.has(e);
},
/**
* Get all registered analysis types.
* Built-in adapters (query, funnel) are initialized automatically.
*
* @returns Array of registered types
*/
getRegisteredTypes() {
return Jn(), Array.from(pt.keys());
},
/**
* Clear all registered adapters.
* Primarily useful for testing.
* Note: Built-in adapters will be re-initialized on next access.
*/
clear() {
pt.clear(), xr = !1;
}
}, Aa = () => ({
analysisType: "query",
// Use adapter defaults as single source of truth for chart configuration
charts: {
query: St.getDefaultChartConfig(),
funnel: Qt.getDefaultChartConfig(),
flow: jt.getDefaultChartConfig()
},
// Per-mode active view preference
activeViews: {
query: "chart",
funnel: "chart",
flow: "chart"
},
userManuallySelectedChart: !1,
localPaletteName: "default"
}), gl = (e, t) => ({
...Aa(),
setAnalysisType: (n) => {
e((s) => {
const a = { ...s.charts };
if (!a[n]) {
const o = Ft.get(n);
a[n] = o.getDefaultChartConfig();
}
const i = { ...s.activeViews };
return i[n] || (i[n] = "chart"), {
analysisType: n,
charts: a,
activeViews: i,
activeView: i[n] ?? "chart"
};
});
},
setChartType: (n) => {
e((s) => {
const a = s.analysisType, i = s.charts[a] || {
chartType: n,
chartConfig: {},
displayConfig: {}
};
return {
charts: {
...s.charts,
[a]: { ...i, chartType: n }
}
};
});
},
setChartTypeManual: (n) => {
e((s) => {
const a = s.analysisType, i = s.charts[a] || {
chartType: n,
chartConfig: {},
displayConfig: {}
};
return {
charts: {
...s.charts,
[a]: { ...i, chartType: n }
},
userManuallySelectedChart: !0,
activeView: "chart",
activeViews: {
...s.activeViews,
[a]: "chart"
}
};
});
},
setChartConfig: (n) => {
e((s) => {
const a = s.analysisType, i = s.charts[a] || {
chartType: "bar",
chartConfig: n,
displayConfig: {}
};
return {
charts: {
...s.charts,
[a]: { ...i, chartConfig: n }
},
activeView: "chart",
activeViews: {
...s.activeViews,
[a]: "chart"
}
};
});
},
setDisplayConfig: (n) => {
e((s) => {
const a = s.analysisType, i = s.charts[a] || {
chartType: "bar",
chartConfig: {},
displayConfig: n
};
return {
charts: {
...s.charts,
[a]: { ...i, displayConfig: n }
},
activeView: "chart",
activeViews: {
...s.activeViews,
[a]: "chart"
}
};
});
},
setLocalPaletteName: (n) => e({ localPaletteName: n }),
setUserManuallySelectedChart: (n) => e({ userManuallySelectedChart: n }),
// @deprecated - Use setChartType() instead
// Kept for backward compatibility
setFunnelChartType: (n) => {
e((s) => {
const a = s.charts.funnel || {
chartType: n,
chartConfig: {},
displayConfig: {}
};
return {
charts: {
...s.charts,
funnel: { ...a, chartType: n }
}
};
});
},
// @deprecated - Use setChartConfig() instead
// Kept for backward compatibility
setFunnelChartConfig: (n) => {
e((s) => {
const a = s.charts.funnel || {
chartType: "funnel",
chartConfig: n,
displayConfig: {}
};
return {
charts: {
...s.charts,
funnel: { ...a, chartConfig: n }
}
};
});
},
// @deprecated - Use setDisplayConfig() instead
// Kept for backward compatibility
setFunnelDisplayConfig: (n) => {
e((s) => {
const a = s.charts.funnel || {
chartType: "funnel",
chartConfig: {},
displayConfig: n
};
return {
charts: {
...s.charts,
funnel: { ...a, displayConfig: n }
}
};
});
},
save: () => {
const n = t(), s = Ft.get(n.analysisType), a = s.extractState(n), i = n.activeViews[n.analysisType] ?? n.activeView ?? "chart";
return s.save(a, n.charts, i);
},
load: (n) => {
const s = Ft.get(n.analysisType);
if (!s.canLoad(n)) {
console.warn("[coreSlice] Invalid config, cannot load");
return;
}
const a = s.load(n), i = t(), o = {
...i.charts,
...n.charts
};
o[n.analysisType] || (o[n.analysisType] = s.getDefaultChartConfig());
const c = {
...i.activeViews,
[n.analysisType]: n.activeView
};
e({
analysisType: n.analysisType,
charts: o,
activeView: n.activeView,
activeViews: c,
// Mode-specific state from adapter
...a
});
},
saveWorkspace: () => {
const n = t(), s = n, a = Ft.get("query"), i = a.extractState(s), o = n.activeViews.query ?? n.activeView ?? "chart", c = a.save(
i,
n.charts,
o
), l = Ft.get("funnel"), u = l.extractState(s), h = n.activeViews.funnel ?? n.activeView ?? "chart", f = l.save(
u,
n.charts,
h
), m = Ft.get("flow"), g = m.extractState(s), b = n.activeViews.flow ?? n.activeView ?? "chart", N = m.save(
g,
n.charts,
b
);
return {
version: 1,
activeType: n.analysisType,
modes: {
query: c,
funnel: f,
flow: N
}
};
},
loadWorkspace: (n) => {
const s = Ft.get("query"), a = Ft.get("funnel"), i = Ft.get("flow");
let o = {}, c = {}, l = {}, u = { ...t().charts }, h = { ...t().activeViews };
n.modes.query && s.canLoad(n.modes.query) && (o = s.load(n.modes.query), u = { ...u, ...n.modes.query.charts }, h.query = n.modes.query.activeView ?? "chart"), n.modes.funnel && a.canLoad(n.modes.funnel) && (c = a.load(n.modes.funnel), u = { ...u, ...n.modes.funnel.charts }, h.funnel = n.modes.funnel.activeView ?? "chart"), n.modes.flow && i.canLoad(n.modes.flow) && (l = i.load(n.modes.flow), u = { ...u, ...n.modes.flow.charts }, h.flow = n.modes.flow.activeView ?? "chart");
const m = n.modes[n.activeType]?.activeView ?? "chart";
e({
analysisType: n.activeType,
charts: u,
activeViews: h,
activeView: m,
...o,
...c,
...l
});
}
}), vr = () => ({
queryStates: [Ve()],
activeQueryIndex: 0,
mergeStrategy: "concat"
}), yl = (e, t) => ({
...vr(),
// ==========================================================================
// Query State Management
// ==========================================================================
setQueryStates: (n) => e({ queryStates: n }),
updateQueryState: (n, s) => e((a) => {
const i = [...a.queryStates];
return i[n] = s(i[n] || Ve()), { queryStates: i };
}),
setActiveQueryIndex: (n) => e({ activeQueryIndex: n }),
setMergeStrategy: (n) => e({ mergeStrategy: n }),
// ==========================================================================
// Multi-Query Actions
// ==========================================================================
addQuery: () => e((n) => {
const s = n.queryStates[n.activeQueryIndex] || Ve(), a = {
...Ve(),
metrics: [...s.metrics],
breakdowns: [...s.breakdowns],
filters: [...s.filters]
};
return {
queryStates: [...n.queryStates, a],
activeQueryIndex: n.queryStates.length
};
}),
removeQuery: (n) => e((s) => {
if (s.queryStates.length <= 1) return s;
const a = s.queryStates.filter((o, c) => c !== n);
let i = s.activeQueryIndex;
return n === s.activeQueryIndex ? i = Math.max(0, s.activeQueryIndex - 1) : n < s.activeQueryIndex && (i = s.activeQueryIndex - 1), { queryStates: a, activeQueryIndex: i };
}),
// ==========================================================================
// Metrics Actions
// ==========================================================================
addMetric: (n, s) => e((a) => {
const i = a.activeQueryIndex, o = [...a.queryStates], c = o[i] || Ve(), l = {
id: lt(),
field: n,
label: s || rn(c.metrics.length)
};
return o[i] = {
...c,
metrics: [...c.metrics, l]
}, { queryStates: o };
}),
removeMetric: (n) => e((s) => {
const a = s.activeQueryIndex, i = [...s.queryStates], o = i[a] || Ve(), c = o.metrics.find((h) => h.id === n)?.field, l = o.metrics.filter((h) => h.id !== n);
let u = o.order;
return c && u && u[c] && (u = { ...u }, delete u[c], Object.keys(u).length === 0 && (u = void 0)), i[a] = {
...o,
metrics: l,
order: u
}, { queryStates: i };
}),
toggleMetric: (n) => e((s) => {
const a = s.activeQueryIndex, i = [...s.queryStates], o = i[a] || Ve(), c = o.metrics.findIndex((l) => l.field === n);
if (c >= 0)
i[a] = {
...o,
metrics: o.metrics.filter((l, u) => u !== c)
};
else {
const l = {
id: lt(),
field: n,
label: rn(o.metrics.length)
};
i[a] = {
...o,
metrics: [...o.metrics, l]
};
}
return { queryStates: i };
}),
reorderMetrics: (n, s) => e((a) => {
const i = a.activeQueryIndex, o = [...a.queryStates], c = o[i] || Ve(), l = [...c.metrics], [u] = l.splice(n, 1);
return l.splice(s, 0, u), o[i] = {
...c,
metrics: l
}, { queryStates: o };
}),
// ==========================================================================
// Breakdowns Actions
// ==========================================================================
addBreakdown: (n, s, a) => e((i) => {
const o = i.activeQueryIndex, c = [...i.queryStates], l = c[o] || Ve();
if (s && l.breakdowns.some((f) => f.isTimeDimension))
return i;
const u = {
id: lt(),
field: n,
isTimeDimension: s,
granularity: s ? a || "month" : void 0
};
return c[o] = {
...l,
breakdowns: [...l.breakdowns, u]
}, { queryStates: c };
}),
removeBreakdown: (n) => e((s) => {
const a = s.activeQueryIndex, i = [...s.queryStates], o = i[a] || Ve(), c = o.breakdowns.find((h) => h.id === n)?.field, l = o.breakdowns.filter((h) => h.id !== n);
let u = o.order;
return c && u && u[c] && (u = { ...u }, delete u[c], Object.keys(u).length === 0 && (u = void 0)), i[a] = {
...o,
breakdowns: l,
order: u
}, { queryStates: i };
}),
toggleBreakdown: (n, s, a) => e((i) => {
const o = i.activeQueryIndex, c = [...i.queryStates], l = c[o] || Ve(), u = l.breakdowns.findIndex((h) => h.field === n);
if (u >= 0)
c[o] = {
...l,
breakdowns: l.breakdowns.filter((h, f) => f !== u)
};
else {
if (s && l.breakdowns.some((m) => m.isTimeDimension))
return i;
const h = {
id: lt(),
field: n,
isTimeDimension: s,
granularity: s ? a || "month" : void 0
};
c[o] = {
...l,
breakdowns: [...l.breakdowns, h]
};
}
return { queryStates: c };
}),
setBreakdownGranularity: (n, s) => e((a) => {
const { mergeStrategy: i, activeQueryIndex: o, queryStates: c } = a, l = [...c], u = i === "merge" && o > 0 ? 0 : o;
return l[u] = {
...l[u],
breakdowns: l[u].breakdowns.map(
(h) => h.id === n ? { ...h, granularity: s } : h
)
}, { queryStates: l };
}),
toggleBreakdownComparison: (n) => e((s) => {
const { mergeStrategy: a, activeQueryIndex: i, queryStates: o, charts: c, analysisType: l } = s, u = [...o], h = a === "merge" && i > 0 ? 0 : i, f = u[h].breakdowns.find((N) => N.id === n), m = f && !f.enableComparison, g = u[h].breakdowns.map((N) => N.id === n ? { ...N, enableComparison: !N.enableComparison } : N.isTimeDimension && N.enableComparison ? { ...N, enableComparison: !1 } : N);
u[h] = {
...u[h],
breakdowns: g
};
const b = { queryStates: u };
if (m && f?.isTimeDimension && f.field) {
const N = u[h].filters || [];
if (!N.some((w) => {
if ("member" in w) {
const y = w;
return y.member === f.field && y.operator === "inDateRange";
}
return !1;
})) {
const w = {
member: f.field,
operator: "inDateRange",
values: [],
dateRange: Dt("last_n_months", 3)
};
u[h] = {
...u[h],
filters: [...N, w]
}, b.queryStates = u;
}
const A = c[l];
A && A.chartType !== "line" && (b.charts = {
...c,
[l]: {
...A,
chartType: "line"
}
}, b.userManuallySelectedChart = !1, b.activeView = "chart", b.activeViews = {
...s.activeViews,
[l]: "chart"
});
}
return b;
}),
reorderBreakdowns: (n, s) => e((a) => {
const i = a.activeQueryIndex, o = [...a.queryStates], c = o[i] || Ve(), l = [...c.breakdowns], [u] = l.splice(n, 1);
return l.splice(s, 0, u), o[i] = {
...c,
breakdowns: l
}, { queryStates: o };
}),
// ==========================================================================
// Filters Actions
// ==========================================================================
setFilters: (n) => e((s) => {
const a = s.activeQueryIndex, i = [...s.queryStates];
return i[a] = {
...i[a],
filters: n
}, { queryStates: i };
}),
dropFieldToFilter: (n) => e((s) => {
const a = s.activeQueryIndex, i = [...s.queryStates], o = i[a] || Ve(), c = o.filters || [];
if (c.some((f) => "member" in f && f.member === n)) return s;
const u = {
member: n,
operator: "set",
values: []
};
let h;
if (c.length === 0)
h = [u];
else if (c.length === 1 && "type" in c[0]) {
const f = c[0];
h = [{ ...f, filters: [...f.filters, u] }];
} else
h = [{ type: "and", filters: [...c, u] }];
return i[a] = {
...o,
filters: h
}, { queryStates: i };
}),
setOrder: (n, s) => e((a) => {
const i = a.activeQueryIndex, o = [...a.queryStates], c = o[i] || Ve(), l = { ...c.order || {} };
return s === null ? delete l[n] : l[n] = s, o[i] = {
...c,
order: Object.keys(l).length > 0 ? l : void 0
}, { queryStates: o };
}),
// ==========================================================================
// Utility Actions
// ==========================================================================
getCurrentState: () => {
const n = t();
return n.queryStates[n.activeQueryIndex] || Ve();
},
getMergeKeys: () => {
const n = t();
if (n.mergeStrategy !== "merge" || n.queryStates.length === 0)
return;
const s = n.queryStates[0].breakdowns;
if (s.length !== 0)
return s.map((a) => a.field);
},
isMultiQueryMode: () => {
const n = t();
return n.queryStates.length <= 1 ? !1 : n.queryStates.filter(
(a) => a.metrics.length > 0 || a.breakdowns.length > 0
).length > 1;
},
buildCurrentQuery: () => {
const n = t(), s = n.queryStates[n.activeQueryIndex] || Ve();
return In(s.metrics, s.breakdowns, s.filters, s.order);
},
buildAllQueries: () => {
const n = t(), s = n.queryStates[0]?.breakdowns || [];
return n.queryStates.map((a, i) => {
const o = n.mergeStrategy === "merge" && i > 0 ? s : a.breakdowns;
return In(a.metrics, o, a.filters, a.order);
});
},
buildMultiQueryConfig: () => {
const n = t();
if (!t().isMultiQueryMode()) return null;
const a = t().buildAllQueries().filter((i) => i.measures && i.measures.length > 0 || i.dimensions && i.dimensions.length > 0 || i.timeDimensions && i.timeDimensions.length > 0);
return a.length < 2 ? null : {
queries: a,
mergeStrategy: n.mergeStrategy,
mergeKeys: t().getMergeKeys(),
queryLabels: a.map((i, o) => `Q${o + 1}`)
};
}
}), wr = () => ({
funnelCube: null,
funnelSteps: [],
activeFunnelStepIndex: 0,
funnelTimeDimension: null,
funnelBindingKey: null,
stepTimeToConvert: []
// Deprecated - kept for backward compat
}), bl = (e, t) => ({
...wr(),
addFunnelStep: () => e((n) => {
const s = n.funnelSteps[n.funnelSteps.length - 1], a = {
id: lt(),
name: `Step ${n.funnelSteps.length + 1}`,
cube: n.funnelCube || "",
// Deep copy filters from previous step, or empty array if first step
filters: s?.filters ? JSON.parse(JSON.stringify(s.filters)) : [],
// Copy timeToConvert from previous step
timeToConvert: s?.timeToConvert
};
return {
funnelSteps: [...n.funnelSteps, a],
activeFunnelStepIndex: n.funnelSteps.length
};
}),
removeFunnelStep: (n) => e((s) => {
if (s.funnelSteps.length <= 1) return s;
const a = s.funnelSteps.filter((o, c) => c !== n), i = Math.min(s.activeFunnelStepIndex, a.length - 1);
return {
funnelSteps: a,
activeFunnelStepIndex: i
};
}),
updateFunnelStep: (n, s) => e((a) => {
const i = [...a.funnelSteps];
return i[n] && (i[n] = { ...i[n], ...s }), { funnelSteps: i };
}),
setActiveFunnelStepIndex: (n) => e({ activeFunnelStepIndex: n }),
reorderFunnelSteps: (n, s) => e((a) => {
const i = [...a.funnelSteps], [o] = i.splice(n, 1);
return i.splice(s, 0, o), { funnelSteps: i };
}),
setFunnelTimeDimension: (n) => e({ funnelTimeDimension: n }),
setFunnelBindingKey: (n) => e({ funnelBindingKey: n }),
setFunnelCube: (n) => e((s) => {
const a = s.funnelSteps.map((i) => ({
...i,
cube: n || ""
}));
return {
funnelCube: n,
// Clear binding key and time dimension since they may not exist in new cube
funnelBindingKey: null,
funnelTimeDimension: null,
funnelSteps: a
};
}),
// Deprecated: no-op - legacy queryStates-based funnels are no longer supported
// Use updateFunnelStep with timeToConvert instead
setStepTimeToConvert: () => {
},
// Deprecated: always returns null - legacy queryStates-based funnels are no longer supported
// Use buildFunnelQueryFromSteps instead
buildFunnelConfig: () => null,
// New: Build ServerFunnelQuery from dedicated funnelSteps
buildFunnelQueryFromSteps: () => {
const n = t();
if (n.analysisType !== "funnel" || !n.funnelBindingKey || !n.funnelTimeDimension || n.funnelSteps.length < 2) return null;
const s = n.funnelSteps.filter((a) => a.cube && a.name);
return s.length < 2 ? null : {
funnel: {
bindingKey: n.funnelBindingKey.dimension,
timeDimension: n.funnelTimeDimension,
steps: s.map((a) => ({
name: a.name,
cube: a.cube,
filter: a.filters.length > 0 ? a.filters : void 0,
timeToConvert: a.timeToConvert
})),
includeTimeMetrics: !0
}
};
},
isFunnelMode: () => t().analysisType === "funnel",
isFunnelModeEnabled: () => {
const n = t();
return n.analysisType !== "funnel" || !n.funnelBindingKey || !n.funnelTimeDimension || n.funnelSteps.length < 2 ? !1 : n.funnelSteps.filter((a) => a.cube && a.name).length >= 2;
}
}), Nr = () => ({
flowCube: null,
flowBindingKey: null,
flowTimeDimension: null,
startingStep: {
name: "",
filters: []
},
stepsBefore: 3,
stepsAfter: 3,
eventDimension: null,
joinStrategy: "auto"
}), xl = (e, t) => ({
...Nr(),
setFlowCube: (n) => e(() => ({
flowCube: n,
// Clear binding key and time dimension since they may not exist in new cube
flowBindingKey: null,
flowTimeDimension: null,
eventDimension: null,
// Reset starting step filters when cube changes
startingStep: {
name: "",
filters: []
}
})),
setFlowBindingKey: (n) => e({ flowBindingKey: n }),
setFlowTimeDimension: (n) => e({ flowTimeDimension: n }),
setEventDimension: (n) => e({ eventDimension: n }),
setStartingStepName: (n) => e((s) => ({
startingStep: {
...s.startingStep,
name: n
}
})),
setStartingStepFilters: (n) => e((s) => ({
startingStep: {
...s.startingStep,
filters: n
}
})),
addStartingStepFilter: (n) => e((s) => ({
startingStep: {
...s.startingStep,
filters: [...s.startingStep.filters, n]
}
})),
removeStartingStepFilter: (n) => e((s) => ({
startingStep: {
...s.startingStep,
filters: s.startingStep.filters.filter((a, i) => i !== n)
}
})),
updateStartingStepFilter: (n, s) => e((a) => {
const i = [...a.startingStep.filters];
return i[n] && (i[n] = s), {
startingStep: {
...a.startingStep,
filters: i
}
};
}),
setStepsBefore: (n) => e({
stepsBefore: Math.max(Dn, Math.min(Tn, n))
}),
setStepsAfter: (n) => e({
stepsAfter: Math.max(Dn, Math.min(Tn, n))
}),
setJoinStrategy: (n) => e(() => ({
joinStrategy: n
})),
isFlowMode: () => t().analysisType === "flow",
isFlowModeEnabled: () => {
const n = t();
return !(n.analysisType !== "flow" || !n.flowCube || !n.flowBindingKey?.dimension || !n.flowTimeDimension || !n.eventDimension || n.startingStep.filters.length === 0);
},
buildFlowQuery: () => {
const n = t();
if (n.analysisType !== "flow" || !n.flowBindingKey?.dimension || !n.flowTimeDimension || !n.eventDimension || n.startingStep.filters.length === 0) return null;
let s;
if (typeof n.flowBindingKey.dimension == "string")
s = n.flowBindingKey.dimension;
else if (Array.isArray(n.flowBindingKey.dimension))
s = n.flowBindingKey.dimension.map((l) => ({
cube: l.cube,
dimension: l.dimension
}));
else
return null;
const a = n.startingStep.filters.length === 1 ? n.startingStep.filters[0] : n.startingStep.filters, o = n.charts?.flow?.chartType === "sunburst" ? "sunburst" : "sankey", c = o === "sunburst" ? 0 : n.stepsBefore;
return {
flow: {
bindingKey: s,
timeDimension: n.flowTimeDimension,
startingStep: {
name: n.startingStep.name || "Starting Step",
filter: a
},
stepsBefore: c,
stepsAfter: n.stepsAfter,
eventDimension: n.eventDimension,
outputMode: o,
joinStrategy: n.joinStrategy
}
};
}
}), Ma = {
isOpen: !1,
userPrompt: "",
isGenerating: !1,
error: null,
hasGeneratedQuery: !1,
previousState: null
}, vl = () => ({
activeTab: "query",
activeView: "chart",
displayLimit: 100,
showFieldModal: !1,
fieldModalMode: "metrics",
aiState: Ma
}), wl = (e, t) => ({
...vl(),
// ==========================================================================
// Tab/View Actions
// ==========================================================================
setActiveTab: (n) => e({ activeTab: n }),
setActiveView: (n) => e((s) => ({
activeView: n,
activeViews: {
...s.activeViews,
[s.analysisType]: n
}
})),
setDisplayLimit: (n) => e({ displayLimit: n }),
// ==========================================================================
// Field Modal Actions
// ==========================================================================
openMetricsModal: () => e({ showFieldModal: !0, fieldModalMode: "metrics" }),
openBreakdownsModal: () => e({ showFieldModal: !0, fieldModalMode: "breakdown" }),
closeFieldModal: () => e({ showFieldModal: !1 }),
// ==========================================================================
// AI Actions
// ==========================================================================
openAI: () => e((n) => ({
aiState: { ...n.aiState, isOpen: !0 }
})),
closeAI: () => e((n) => ({
aiState: { ...n.aiState, isOpen: !1 }
})),
setAIPrompt: (n) => e((s) => ({
aiState: { ...s.aiState, userPrompt: n }
})),
setAIGenerating: (n) => e((s) => ({
aiState: { ...s.aiState, isGenerating: n }
})),
setAIError: (n) => e((s) => ({
aiState: { ...s.aiState, error: n }
})),
setAIHasGeneratedQuery: (n) => e((s) => ({
aiState: { ...s.aiState, hasGeneratedQuery: n }
})),
saveAIPreviousState: () => e((n) => {
const s = n.queryStates[n.activeQueryIndex], a = n.charts[n.analysisType] || {
chartType: "bar",
chartConfig: {},
displayConfig: { showLegend: !0, showGrid: !0, showTooltip: !0 }
};
return {
aiState: {
...n.aiState,
previousState: s ? {
metrics: [...s.metrics],
breakdowns: [...s.breakdowns],
filters: [...s.filters],
chartType: a.chartType,
chartConfig: { ...a.chartConfig },
displayConfig: { ...a.displayConfig }
} : null
}
};
}),
restoreAIPreviousState: () => e((n) => {
const s = n.aiState.previousState;
if (!s) return n;
const a = n.activeQueryIndex, i = [...n.queryStates];
return i[a] = {
...i[a] || Ve(),
metrics: s.metrics,
breakdowns: s.breakdowns,
filters: s.filters
}, {
queryStates: i,
charts: {
...n.charts,
[n.analysisType]: {
chartType: s.chartType,
chartConfig: s.chartConfig,
displayConfig: s.displayConfig
}
},
aiState: { ...Ma }
};
})
});
function os(e) {
const t = e.filters ? [...e.filters] : [], n = e.timeDimensions || [], s = [
...(e.dimensions || []).map((i) => ({
id: lt(),
field: i,
isTimeDimension: !1
})),
...n.map((i) => ({
id: lt(),
field: i.dimension,
granularity: i.granularity,
isTimeDimension: !0,
enableComparison: !!(i.compareDateRange && i.compareDateRange.length > 0)
}))
];
let a = t;
for (const i of n) {
if (!i.compareDateRange || i.compareDateRange.length === 0) continue;
const o = a.some(
(u) => "member" in u && u.member === i.dimension && u.operator === "inDateRange"
), c = i.compareDateRange[0], l = Array.isArray(c) || typeof c == "string" ? c : void 0;
if (l) {
if (!o) {
a = [
...a,
{
member: i.dimension,
operator: "inDateRange",
values: [],
dateRange: l
}
];
continue;
}
a = a.map((u) => "member" in u && u.member === i.dimension && u.operator === "inDateRange" && !u.dateRange ? { ...u, dateRange: l } : u);
}
}
return {
...Ve(),
metrics: (e.measures || []).map((i, o) => ({
id: lt(),
field: i,
label: rn(o)
})),
breakdowns: s,
filters: a,
order: e.order
};
}
function Nl(e) {
return "queries" in e && Array.isArray(e.queries);
}
function Cl(e) {
if (e.initialAnalysisType === "funnel" && e.initialFunnelState) {
const t = Qt.getDefaultChartConfig(), n = {
chartType: e.initialChartConfig?.chartType || t.chartType,
chartConfig: e.initialChartConfig?.chartConfig || t.chartConfig,
displayConfig: e.initialChartConfig?.displayConfig || t.displayConfig
}, s = {
funnelCube: e.initialFunnelState.funnelCube ?? null,
funnelSteps: e.initialFunnelState.funnelSteps || [],
activeFunnelStepIndex: 0,
funnelTimeDimension: e.initialFunnelState.funnelTimeDimension ?? null,
funnelBindingKey: e.initialFunnelState.funnelBindingKey ?? null
};
return Qt.save(
s,
{ funnel: n },
e.initialActiveView || "chart"
);
}
if (e.initialAnalysisType === "flow" && e.initialFlowState) {
const t = jt.getDefaultChartConfig(), n = {
chartType: e.initialChartConfig?.chartType || t.chartType,
chartConfig: e.initialChartConfig?.chartConfig || t.chartConfig,
displayConfig: e.initialChartConfig?.displayConfig || t.displayConfig
}, s = {
flowCube: e.initialFlowState.flowCube ?? null,
flowBindingKey: e.initialFlowState.flowBindingKey ?? null,
flowTimeDimension: e.initialFlowState.flowTimeDimension ?? null,
startingStep: e.initialFlowState.startingStep || { name: "", filters: [] },
stepsBefore: e.initialFlowState.stepsBefore ?? 3,
stepsAfter: e.initialFlowState.stepsAfter ?? 3,
eventDimension: e.initialFlowState.eventDimension ?? null,
joinStrategy: e.initialFlowState.joinStrategy ?? "auto"
};
return jt.save(
s,
{ flow: n },
e.initialActiveView || "chart"
);
}
if (e.initialQuery) {
const t = e.initialQuery;
let n, s = "concat";
Nl(t) ? (n = t.queries.map(os), t.mergeStrategy && (s = t.mergeStrategy)) : n = [os(t)];
const a = St.getDefaultChartConfig(), i = {
chartType: e.initialChartConfig?.chartType || a.chartType,
chartConfig: e.initialChartConfig?.chartConfig || a.chartConfig,
displayConfig: e.initialChartConfig?.displayConfig || a.displayConfig
};
return St.save(
{ queryStates: n, activeQueryIndex: 0, mergeStrategy: s },
{ query: i },
e.initialActiveView || "chart"
);
}
if (e.initialChartConfig) {
const t = St.getDefaultChartConfig(), n = {
chartType: e.initialChartConfig.chartType || t.chartType,
chartConfig: e.initialChartConfig.chartConfig || t.chartConfig,
displayConfig: e.initialChartConfig.displayConfig || t.displayConfig
};
return St.save(
{ queryStates: [Ve()], activeQueryIndex: 0, mergeStrategy: "concat" },
{ query: n },
e.initialActiveView || "chart"
);
}
return e.initialActiveView ? St.save(
{ queryStates: [Ve()], activeQueryIndex: 0, mergeStrategy: "concat" },
{ query: St.getDefaultChartConfig() },
e.initialActiveView
) : null;
}
function Sl(e, t) {
return {
reset: () => {
e({
...Aa(),
...vr(),
...wr(),
...Nr(),
// Apply adapter defaults for charts (may differ from slice defaults)
charts: {
query: St.getDefaultChartConfig(),
funnel: Qt.getDefaultChartConfig(),
flow: jt.getDefaultChartConfig()
},
activeViews: {
query: "chart",
funnel: "chart",
flow: "chart"
}
});
},
clearCurrentMode: () => e((n) => {
switch (n.analysisType) {
case "funnel":
return {
...wr(),
charts: {
...n.charts,
funnel: Qt.getDefaultChartConfig()
}
};
case "flow":
return {
...Nr(),
charts: {
...n.charts,
flow: jt.getDefaultChartConfig()
}
};
default:
return {
...vr(),
userManuallySelectedChart: !1,
charts: {
...n.charts,
query: St.getDefaultChartConfig()
}
};
}
}),
clearQuery: () => e((n) => {
const s = [...n.queryStates];
return s[n.activeQueryIndex] = Ve(), {
queryStates: s,
userManuallySelectedChart: !1,
charts: {
...n.charts,
query: St.getDefaultChartConfig()
}
};
}),
getValidation: () => {
const n = t(), s = Ft.get(n.analysisType), a = s.extractState(n);
return s.validate(a);
}
};
}
function Dl(e = {}) {
const t = Cl(e), n = (s, a, i) => ({
// Compose slices - they provide default state and actions
...gl(s, a),
...yl(s, a),
...bl(s, a),
...xl(s, a),
...wl(s),
// Cross-slice actions
...Sl(s, a)
});
if (e.disableLocalStorage) {
const s = pr()(
gr(yr(n), {
name: "AnalysisBuilderStore (no-persist)"
})
);
return t && s.getState().load(t), s;
}
return pr()(
gr(
yr(
Mo(n, {
name: Wo,
// Use workspace format to preserve ALL modes' state
partialize: (s) => s.saveWorkspace(),
merge: (s, a) => s && oo(s) ? {
...a,
_persistedWorkspace: s
} : s && Ir(s) ? {
...a,
_persistedConfig: s
} : t ? {
...a,
_initialConfig: t
} : a,
onRehydrateStorage: () => (s) => {
if (s) {
if (s._persistedWorkspace) {
const a = s._persistedWorkspace;
delete s._persistedWorkspace, delete s._persistedConfig, delete s._initialConfig, s.loadWorkspace(a);
} else if (s._persistedConfig) {
const a = s._persistedConfig;
delete s._persistedConfig, delete s._initialConfig, s.load(a);
} else if (s._initialConfig) {
const a = s._initialConfig;
delete s._initialConfig, s.load(a);
}
}
}
})
),
{ name: "AnalysisBuilderStore" }
)
);
}
const Or = ia(null);
function Tl({
children: e,
initialQuery: t,
initialChartConfig: n,
disableLocalStorage: s,
initialAnalysisType: a,
initialFunnelState: i,
initialFlowState: o,
initialActiveView: c
}) {
const l = ge(null);
return l.current || (l.current = Dl({
initialQuery: t,
initialChartConfig: n,
disableLocalStorage: s,
initialAnalysisType: a,
initialFunnelState: i,
initialFlowState: o,
initialActiveView: c
})), /* @__PURE__ */ r(Or.Provider, { value: l.current, children: e });
}
function W(e) {
const t = sn(Or);
if (!t)
throw new Error("useAnalysisBuilderStore must be used within AnalysisBuilderStoreProvider");
return Er(t, e);
}
function Ia() {
const e = sn(Or);
if (!e)
throw new Error("useAnalysisBuilderStoreApi must be used within AnalysisBuilderStoreProvider");
return e;
}
const $r = (e) => e.queryStates[e.activeQueryIndex] || Ve(), Ju = (e) => $r(e).metrics, Xu = (e) => $r(e).breakdowns, Zu = (e) => $r(e).filters, kl = (e) => {
const t = e.charts[e.analysisType];
return t ? {
chartType: t.chartType,
chartConfig: t.chartConfig,
displayConfig: t.displayConfig
} : {
chartType: "bar",
chartConfig: {},
displayConfig: { showLegend: !0, showGrid: !0, showTooltip: !0 }
};
}, ef = (e) => ({
activeTab: e.activeTab,
activeView: e.activeView,
displayLimit: e.displayLimit,
showFieldModal: e.showFieldModal,
fieldModalMode: e.fieldModalMode
}), tf = (e) => ({
queryStates: e.queryStates,
activeQueryIndex: e.activeQueryIndex,
mergeStrategy: e.mergeStrategy,
// Multi-query mode is when we have more than one query in 'query' analysis type
isMultiQueryMode: e.analysisType === "query" && e.queryStates.length > 1
}), nf = (e) => ({
funnelCube: e.funnelCube,
funnelSteps: e.funnelSteps,
activeFunnelStepIndex: e.activeFunnelStepIndex,
funnelTimeDimension: e.funnelTimeDimension,
funnelBindingKey: e.funnelBindingKey,
isFunnelMode: e.analysisType === "funnel",
// Deprecated field kept for backward compat
stepTimeToConvert: e.stepTimeToConvert
});
function ls(e) {
return e.timeDimensions || [];
}
function Al(e) {
const t = [];
if (e.length < 2) return t;
const n = ls(e[0]);
if (n.length === 0) return t;
for (let s = 1; s < e.length; s++) {
const a = ls(e[s]);
if (a.length === 0 && n.length > 0) {
t.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 i of n) {
const o = a.find((c) => c.dimension === i.dimension);
o && o.granularity !== i.granularity && t.push({
type: "granularity_mismatch",
queryIndex: s,
message: `Query ${s + 1} uses "${o.granularity}" granularity but Query 1 uses "${i.granularity}"`,
details: {
field: i.dimension,
expectedGranularity: i.granularity,
actualGranularity: o.granularity
}
});
}
}
return t;
}
function Ml(e, t) {
const n = [];
if (e.length < 2 || t.length === 0) return n;
for (let s = 0; s < e.length; s++) {
const a = e[s], i = /* @__PURE__ */ new Set([
...a.dimensions || [],
...a.timeDimensions?.map((o) => o.dimension) || []
]);
for (const o of t)
i.has(o) || n.push({
type: "missing_merge_key",
queryIndex: s,
message: `Query ${s + 1} is missing merge dimension "${o}"`,
details: { field: o }
});
}
return n;
}
function Il(e) {
const t = [];
if (e.length < 2) return t;
const n = /* @__PURE__ */ new Map();
e.forEach((i, o) => {
i.measures?.forEach((c) => {
n.has(c) || n.set(c, []), n.get(c).push(o);
});
});
const s = [], a = /* @__PURE__ */ new Set();
return n.forEach((i, o) => {
i.length > 1 && (s.push(o), i.forEach((c) => a.add(c)));
}), s.length > 0 && t.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
}), t;
}
function El(e) {
const t = [];
if (e.length < 2) return t;
const n = e.map((a) => a.timeDimensions?.[0]?.dateRange);
return new Set(n.map((a) => JSON.stringify(a))).size > 1 && t.push({
type: "asymmetric_date_range",
queryIndices: e.map((a, i) => i),
message: "Queries have different date ranges - some data points may be missing in merged results"
}), t;
}
function Fl(e, t, n = []) {
const s = [], a = [];
return e.length < 2 ? { isValid: !0, errors: s, warnings: a } : (a.push(...Il(e)), a.push(...El(e)), t === "merge" && (s.push(...Al(e)), n.length > 0 && s.push(...Ml(e, n))), {
isValid: s.length === 0,
errors: s,
warnings: a
});
}
function rf(e) {
return e.filter(
(t) => (t.measures?.length || 0) + (t.dimensions?.length || 0) + (t.timeDimensions?.length || 0) > 0
).length >= 2;
}
function sf(e) {
if (e.isValid && e.warnings.length === 0)
return "Configuration is valid";
const t = [];
return e.errors.length > 0 && t.push(`${e.errors.length} error${e.errors.length > 1 ? "s" : ""}`), e.warnings.length > 0 && t.push(`${e.warnings.length} warning${e.warnings.length > 1 ? "s" : ""}`), t.join(", ");
}
function Rl() {
const e = W((w) => w.queryStates), t = W((w) => w.activeQueryIndex), n = W((w) => w.mergeStrategy), s = W((w) => w.setActiveQueryIndex), a = W((w) => w.setMergeStrategy), i = W((w) => w.addQuery), o = W((w) => w.removeQuery), c = W((w) => w.getCurrentState), l = W((w) => w.getMergeKeys), u = W((w) => w.isMultiQueryMode), h = c(), f = u(), m = l(), g = V(() => {
const w = e[t] || h;
return In(w.metrics, w.breakdowns, w.filters, w.order);
}, [e, t, h]), b = V(() => {
const w = e[0]?.breakdowns || [];
return e.map((y, C) => {
const T = n === "merge" && C > 0 ? w : y.breakdowns;
return In(y.metrics, T, y.filters, y.order);
});
}, [e, n]), N = V(() => {
if (e.length <= 1) return null;
const w = b.filter((y) => y.measures && y.measures.length > 0 || y.dimensions && y.dimensions.length > 0 || y.timeDimensions && y.timeDimensions.length > 0);
return w.length < 2 ? null : {
queries: w,
mergeStrategy: n,
mergeKeys: m,
queryLabels: w.map((y, C) => `Q${C + 1}`)
};
}, [b, e.length, n, m]), x = V(() => f ? Fl(b, n, m || []) : null, [f, b, n, m]), A = V(() => g.measures && g.measures.length > 0 || g.dimensions && g.dimensions.length > 0 || g.timeDimensions && g.timeDimensions.length > 0, [g]);
return {
queryState: h,
queryStates: e,
activeQueryIndex: t,
mergeStrategy: n,
isMultiQueryMode: f,
mergeKeys: m,
currentQuery: g,
allQueries: b,
multiQueryConfig: N,
multiQueryValidation: x,
isValidQuery: A,
// Actions
setActiveQueryIndex: s,
setMergeStrategy: a,
addQuery: i,
removeQuery: o
};
}
function _l(e) {
const { queryState: t, queryStates: n, isMultiQueryMode: s, mergeStrategy: a, activeQueryIndex: i } = e, o = V(() => {
if (!s) return t.metrics;
const u = /* @__PURE__ */ new Set(), h = [];
for (let f = 0; f < n.length; f++) {
const m = n[f];
for (const g of m.metrics) {
const b = `Q${f + 1}:${g.field}`;
u.has(b) || (u.add(b), h.push({
...g,
label: `${g.label} (Q${f + 1})`
}));
}
}
return h;
}, [s, n, t.metrics]), c = V(() => {
if (!s) return t.breakdowns;
const u = /* @__PURE__ */ new Set(), h = [];
for (const f of n)
for (const m of f.breakdowns)
u.has(m.field) || (u.add(m.field), h.push(m));
return h;
}, [s, n, t.breakdowns]), l = V(() => a === "merge" && i > 0 ? n[0]?.breakdowns || [] : t.breakdowns, [a, i, n, t.breakdowns]);
return {
combinedMetrics: o,
combinedBreakdowns: c,
effectiveBreakdowns: l
};
}
function Ol(e) {
const {
currentQuery: t,
allQueries: n,
multiQueryConfig: s,
isMultiQueryMode: a,
isValidQuery: i,
initialData: o,
// Unused - legacy mergeStrategy === 'funnel' is no longer supported
funnelBindingKey: c,
isFunnelModeEnabled: l,
analysisType: u,
serverFunnelQuery: h,
serverFlowQuery: f
} = e, m = u === "funnel" || l, g = u === "flow", b = u === "query" && a, N = u === "query" && !a, x = u === "funnel" && !!h, A = V(() => x || !m || !c || n.length < 2 ? null : oi(n, c), [x, m, c, n]), w = ma(t, {
skip: !i || !N,
debounceMs: 300
}), y = ha(s, {
skip: !s || !b,
debounceMs: 300
}), C = pa(A, {
skip: !m || !A && !h,
debounceMs: 300,
prebuiltServerQuery: x ? h : void 0
}), T = ga(f ?? null, {
skip: !g || !f,
debounceMs: 300
}), p = Fi({
queries: a ? n : [t],
isMultiQueryMode: a,
skip: !i || m || g
}), v = Ri(
C.serverQuery,
{ skip: !m || !C.serverQuery }
), k = _i(
T.serverQuery,
{ skip: !g || !T.serverQuery }
), S = g ? T.isLoading || T.isDebouncing : m ? C.isExecuting || C.isDebouncing : b ? y.isLoading : w.isLoading, $ = g ? T.isFetching : m ? C.isExecuting : b ? y.isFetching : w.isFetching, D = g ? T.error : m ? C.error : b ? y.error : w.error, F = !!(w.debouncedQuery || y.debouncedConfig || !C.isDebouncing || // Funnel has debounced when not debouncing
!T.isDebouncing), K = E(() => {
g ? T.refetch() : m ? C.execute() : b ? y.refetch() : w.refetch();
}, [g, m, b, T, C, y, w]), P = V(() => {
const L = g ? T.data : m ? C.chartData : b ? y.data : w.rawData;
return o && o.length > 0 && !L ? "success" : i ? S && !L ? "loading" : $ && L ? "refreshing" : D ? "error" : L ? "success" : "idle" : "idle";
}, [i, S, $, D, w.rawData, y.data, C.chartData, T.data, o, b, m, g]), te = V(() => g && T.data ? [T.data] : m && C.chartData ? C.chartData : b && y.data ? y.data : w.rawData ? w.rawData : o && o.length > 0 ? o : null, [w.rawData, y.data, C.chartData, T.data, o, b, m, g]), _ = V(() => m && C.stepResults ? C.stepResults.map((L) => L.data) : !b || !y.perQueryData ? null : y.perQueryData, [b, m, y.perQueryData, C.stepResults]), O = m && C.executedQueries?.length > 0 ? C.executedQueries : null, ie = m ? C.serverQuery : null, X = m ? v.debugData : null, ce = g ? T.serverQuery : null, Q = g ? T.data : null, Se = g ? k.debugData : null;
return {
executionStatus: P,
executionResults: te,
perQueryResults: _,
isLoading: S,
isFetching: $,
error: D,
debugDataPerQuery: p.debugDataPerQuery,
hasDebounced: F,
refetch: K,
funnelExecutedQueries: O,
funnelServerQuery: ie,
funnelDebugData: X,
flowServerQuery: ce,
flowChartData: Q,
flowDebugData: Se
};
}
const cs = (e) => Symbol.iterator in e, ds = (e) => (
// HACK: avoid checking entries type
"entries" in e
), us = (e, t) => {
const n = e instanceof Map ? e : new Map(e.entries()), s = t instanceof Map ? t : new Map(t.entries());
if (n.size !== s.size)
return !1;
for (const [a, i] of n)
if (!s.has(a) || !Object.is(i, s.get(a)))
return !1;
return !0;
}, $l = (e, t) => {
const n = e[Symbol.iterator](), s = t[Symbol.iterator]();
let a = n.next(), i = s.next();
for (; !a.done && !i.done; ) {
if (!Object.is(a.value, i.value))
return !1;
a = n.next(), i = s.next();
}
return !!a.done && !!i.done;
};
function Ll(e, t) {
return Object.is(e, t) ? !0 : typeof e != "object" || e === null || typeof t != "object" || t === null || Object.getPrototypeOf(e) !== Object.getPrototypeOf(t) ? !1 : cs(e) && cs(t) ? ds(e) && ds(t) ? us(e, t) : $l(e, t) : us(
{ entries: () => Object.entries(e) },
{ entries: () => Object.entries(t) }
);
}
function Cr(e) {
const t = bt.useRef(void 0);
return (n) => {
const s = e(n);
return Ll(t.current, s) ? t.current : t.current = s;
};
}
function Ea(e) {
return e.isTimeDimension;
}
function Pl(e) {
return e.find(Ea);
}
function ql(e) {
return e.find((t) => !t.isTimeDimension);
}
function Lr(e) {
return e.filter((t) => !t.isTimeDimension);
}
function Fa(e) {
return e.filter(Ea);
}
function Pr(e, t, n) {
const s = t.length, a = Lr(n).length, i = Fa(n).length, o = n.length;
switch (e) {
// 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" } : o < 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" } : o < 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" } : o < 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 && o < 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" } : o < 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" } : i < 1 ? { available: !1, reason: "Requires a time dimension" } : { available: !0 };
default:
return { available: !0 };
}
}
function Bl(e, t) {
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] = Pr(a, e, t);
return s;
}
function Ra(e, t, n) {
if (Pr(n, e, t).available || e.length === 0 && t.length === 0)
return n;
const a = Fa(t).length > 0, i = Lr(t).length > 0, o = e.length > 0;
return a && o ? "line" : i && o ? "bar" : o && !i && !a ? "kpiNumber" : "table";
}
function Xn(e, t, n) {
const s = Ra(e, t, n), a = Ql(s, e, t);
return { chartType: s, chartConfig: a };
}
function Ql(e, t, n) {
const s = Pl(n), a = ql(n), i = Lr(n), o = n;
switch (e) {
case "line":
case "area":
return {
xAxis: s ? [s.field] : a ? [a.field] : [],
yAxis: t.map((c) => c.field),
series: i.length > 1 ? [i[1].field] : a && s ? [a.field] : []
};
case "bar":
return {
xAxis: a ? [a.field] : s ? [s.field] : [],
yAxis: t.map((c) => c.field),
series: i.length > 1 ? [i[1].field] : s && a ? [s.field] : []
};
case "pie":
return {
xAxis: a ? [a.field] : [],
yAxis: t.length > 0 ? [t[0].field] : []
};
case "scatter":
return t.length >= 2 ? {
xAxis: [t[0].field],
yAxis: [t[1].field],
series: a ? [a.field] : []
} : {
xAxis: o.length > 0 ? [o[0].field] : [],
yAxis: t.length > 0 ? [t[0].field] : [],
series: i.length > 1 ? [i[1].field] : []
};
case "bubble":
return {
xAxis: t.length > 0 ? [t[0].field] : [],
yAxis: t.length > 1 ? [t[1].field] : [],
sizeField: t.length > 2 ? t[2].field : t.length > 1 ? t[1].field : void 0,
series: a ? [a.field] : s ? [s.field] : []
};
case "radar":
case "radialBar":
case "treemap":
return {
xAxis: a ? [a.field] : [],
yAxis: t.length > 0 ? [t[0].field] : []
};
case "activityGrid":
return {
dateField: s ? [s.field] : [],
valueField: t.length > 0 ? [t[0].field] : []
};
case "kpiNumber":
case "kpiDelta":
case "kpiText":
return {
yAxis: t.length > 0 ? [t[0].field] : []
};
case "table":
return {
xAxis: [
...n.map((c) => c.field),
...t.map((c) => c.field)
]
};
case "markdown":
return {};
default:
return {
xAxis: o.length > 0 ? [o[0].field] : [],
yAxis: t.map((c) => c.field)
};
}
}
function jl(e, t, n, s) {
if (s && Pr(n, e, t).available)
return null;
const a = Ra(e, t, n);
return a !== n ? a : null;
}
function Kl(e) {
const { externalColorPalette: t, combinedMetrics: n, combinedBreakdowns: s, hasDebounced: a } = e, i = W((S) => S.analysisType), { chartType: o, chartConfig: c, displayConfig: l } = W(Cr(kl)), u = W((S) => S.userManuallySelectedChart), h = W((S) => S.localPaletteName), f = W((S) => S.setChartTypeManual), m = W((S) => S.setChartConfig), g = W((S) => S.setDisplayConfig), b = W((S) => S.setFunnelChartType), N = W((S) => S.setFunnelChartConfig), x = W((S) => S.setFunnelDisplayConfig), A = W((S) => S.setLocalPaletteName), w = W((S) => S.setUserManuallySelectedChart), y = E(
(S) => {
if (i === "funnel")
b(S);
else {
f(S);
const { chartConfig: $ } = Xn(
n,
s,
S
);
m($);
}
},
[
i,
n,
s,
b,
f,
m
]
), C = E(
(S) => {
i === "funnel" ? N(S) : m(S);
},
[i, N, m]
), T = E(
(S) => {
i === "funnel" ? x(S) : g(S);
},
[i, x, g]
), p = V(
() => Bl(n, s),
[n, s]
), v = V(() => t ? Array.isArray(t) && typeof t[0] == "string" ? {
name: "custom",
label: "Custom",
colors: t,
gradient: t
} : t : Fr(h), [t, h]), k = ge("");
return he(() => {
if (!a || n.length === 0 && s.length === 0) return;
const S = JSON.stringify({
metrics: n.map((D) => D.field),
breakdowns: s.map((D) => ({ field: D.field, isTime: D.isTimeDimension }))
});
if (S === k.current) return;
k.current = S;
const $ = jl(
n,
s,
o,
u
);
if ($) {
const { chartConfig: D } = Xn(
n,
s,
$
);
y($), C(D), w(!1);
} else if ((n.length > 0 || s.length > 0) && !c.xAxis?.length && !c.yAxis?.length && !c.series?.length) {
const { chartConfig: F } = Xn(
n,
s,
o
);
C(F);
}
}, [
a,
n,
s,
o,
u,
c,
y,
C,
w
]), {
chartType: o,
chartConfig: c,
displayConfig: l,
colorPalette: v,
localPaletteName: h,
chartAvailability: p,
userManuallySelectedChart: u,
// Actions - mode-aware setters route to appropriate store fields
setChartType: y,
setChartConfig: C,
setDisplayConfig: T,
setLocalPaletteName: A
};
}
function Vl() {
const e = W((m) => m.activeTab), t = W((m) => m.activeView), n = W((m) => m.displayLimit), s = W((m) => m.showFieldModal), a = W((m) => m.fieldModalMode), i = W((m) => m.userManuallySelectedChart), o = W((m) => m.setActiveTab), c = W((m) => m.setActiveView), l = W((m) => m.setDisplayLimit), u = W((m) => m.closeFieldModal), [h, f] = ee(0);
return {
// State
activeTab: e,
activeView: t,
displayLimit: n,
showFieldModal: s,
fieldModalMode: a,
activeTableIndex: h,
userManuallySelectedChart: i,
// Actions
setActiveTab: o,
setActiveView: c,
setDisplayLimit: l,
closeFieldModal: u,
setActiveTableIndex: f
};
}
function Ul(e) {
return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
}
var Zn = { exports: {} }, fs;
function Hl() {
return fs || (fs = 1, (function(e) {
var t = (function() {
var n = String.fromCharCode, s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$", i = {};
function o(l, u) {
if (!i[l]) {
i[l] = {};
for (var h = 0; h < l.length; h++)
i[l][l.charAt(h)] = h;
}
return i[l][u];
}
var c = {
compressToBase64: function(l) {
if (l == null) return "";
var u = c._compress(l, 6, function(h) {
return s.charAt(h);
});
switch (u.length % 4) {
// To produce valid Base64
default:
// When could this happen ?
case 0:
return u;
case 1:
return u + "===";
case 2:
return u + "==";
case 3:
return u + "=";
}
},
decompressFromBase64: function(l) {
return l == null ? "" : l == "" ? null : c._decompress(l.length, 32, function(u) {
return o(s, l.charAt(u));
});
},
compressToUTF16: function(l) {
return l == null ? "" : c._compress(l, 15, function(u) {
return n(u + 32);
}) + " ";
},
decompressFromUTF16: function(l) {
return l == null ? "" : l == "" ? null : c._decompress(l.length, 16384, function(u) {
return l.charCodeAt(u) - 32;
});
},
//compress into uint8array (UCS-2 big endian format)
compressToUint8Array: function(l) {
for (var u = c.compress(l), h = new Uint8Array(u.length * 2), f = 0, m = u.length; f < m; f++) {
var g = u.charCodeAt(f);
h[f * 2] = g >>> 8, h[f * 2 + 1] = g % 256;
}
return h;
},
//decompress from uint8array (UCS-2 big endian format)
decompressFromUint8Array: function(l) {
if (l == null)
return c.decompress(l);
for (var u = new Array(l.length / 2), h = 0, f = u.length; h < f; h++)
u[h] = l[h * 2] * 256 + l[h * 2 + 1];
var m = [];
return u.forEach(function(g) {
m.push(n(g));
}), c.decompress(m.join(""));
},
//compress into a string that is already URI encoded
compressToEncodedURIComponent: function(l) {
return l == null ? "" : c._compress(l, 6, function(u) {
return a.charAt(u);
});
},
//decompress from an output of compressToEncodedURIComponent
decompressFromEncodedURIComponent: function(l) {
return l == null ? "" : l == "" ? null : (l = l.replace(/ /g, "+"), c._decompress(l.length, 32, function(u) {
return o(a, l.charAt(u));
}));
},
compress: function(l) {
return c._compress(l, 16, function(u) {
return n(u);
});
},
_compress: function(l, u, h) {
if (l == null) return "";
var f, m, g = {}, b = {}, N = "", x = "", A = "", w = 2, y = 3, C = 2, T = [], p = 0, v = 0, k;
for (k = 0; k < l.length; k += 1)
if (N = l.charAt(k), Object.prototype.hasOwnProperty.call(g, N) || (g[N] = y++, b[N] = !0), x = A + N, Object.prototype.hasOwnProperty.call(g, x))
A = x;
else {
if (Object.prototype.hasOwnProperty.call(b, A)) {
if (A.charCodeAt(0) < 256) {
for (f = 0; f < C; f++)
p = p << 1, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++;
for (m = A.charCodeAt(0), f = 0; f < 8; f++)
p = p << 1 | m & 1, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++, m = m >> 1;
} else {
for (m = 1, f = 0; f < C; f++)
p = p << 1 | m, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++, m = 0;
for (m = A.charCodeAt(0), f = 0; f < 16; f++)
p = p << 1 | m & 1, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++, m = m >> 1;
}
w--, w == 0 && (w = Math.pow(2, C), C++), delete b[A];
} else
for (m = g[A], f = 0; f < C; f++)
p = p << 1 | m & 1, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++, m = m >> 1;
w--, w == 0 && (w = Math.pow(2, C), C++), g[x] = y++, A = String(N);
}
if (A !== "") {
if (Object.prototype.hasOwnProperty.call(b, A)) {
if (A.charCodeAt(0) < 256) {
for (f = 0; f < C; f++)
p = p << 1, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++;
for (m = A.charCodeAt(0), f = 0; f < 8; f++)
p = p << 1 | m & 1, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++, m = m >> 1;
} else {
for (m = 1, f = 0; f < C; f++)
p = p << 1 | m, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++, m = 0;
for (m = A.charCodeAt(0), f = 0; f < 16; f++)
p = p << 1 | m & 1, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++, m = m >> 1;
}
w--, w == 0 && (w = Math.pow(2, C), C++), delete b[A];
} else
for (m = g[A], f = 0; f < C; f++)
p = p << 1 | m & 1, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++, m = m >> 1;
w--, w == 0 && (w = Math.pow(2, C), C++);
}
for (m = 2, f = 0; f < C; f++)
p = p << 1 | m & 1, v == u - 1 ? (v = 0, T.push(h(p)), p = 0) : v++, m = m >> 1;
for (; ; )
if (p = p << 1, v == u - 1) {
T.push(h(p));
break;
} else v++;
return T.join("");
},
decompress: function(l) {
return l == null ? "" : l == "" ? null : c._decompress(l.length, 32768, function(u) {
return l.charCodeAt(u);
});
},
_decompress: function(l, u, h) {
var f = [], m = 4, g = 4, b = 3, N = "", x = [], A, w, y, C, T, p, v, k = { val: h(0), position: u, index: 1 };
for (A = 0; A < 3; A += 1)
f[A] = A;
for (y = 0, T = Math.pow(2, 2), p = 1; p != T; )
C = k.val & k.position, k.position >>= 1, k.position == 0 && (k.position = u, k.val = h(k.index++)), y |= (C > 0 ? 1 : 0) * p, p <<= 1;
switch (y) {
case 0:
for (y = 0, T = Math.pow(2, 8), p = 1; p != T; )
C = k.val & k.position, k.position >>= 1, k.position == 0 && (k.position = u, k.val = h(k.index++)), y |= (C > 0 ? 1 : 0) * p, p <<= 1;
v = n(y);
break;
case 1:
for (y = 0, T = Math.pow(2, 16), p = 1; p != T; )
C = k.val & k.position, k.position >>= 1, k.position == 0 && (k.position = u, k.val = h(k.index++)), y |= (C > 0 ? 1 : 0) * p, p <<= 1;
v = n(y);
break;
case 2:
return "";
}
for (f[3] = v, w = v, x.push(v); ; ) {
if (k.index > l)
return "";
for (y = 0, T = Math.pow(2, b), p = 1; p != T; )
C = k.val & k.position, k.position >>= 1, k.position == 0 && (k.position = u, k.val = h(k.index++)), y |= (C > 0 ? 1 : 0) * p, p <<= 1;
switch (v = y) {
case 0:
for (y = 0, T = Math.pow(2, 8), p = 1; p != T; )
C = k.val & k.position, k.position >>= 1, k.position == 0 && (k.position = u, k.val = h(k.index++)), y |= (C > 0 ? 1 : 0) * p, p <<= 1;
f[g++] = n(y), v = g - 1, m--;
break;
case 1:
for (y = 0, T = Math.pow(2, 16), p = 1; p != T; )
C = k.val & k.position, k.position >>= 1, k.position == 0 && (k.position = u, k.val = h(k.index++)), y |= (C > 0 ? 1 : 0) * p, p <<= 1;
f[g++] = n(y), v = g - 1, m--;
break;
case 2:
return x.join("");
}
if (m == 0 && (m = Math.pow(2, b), b++), f[v])
N = f[v];
else if (v === g)
N = w + w.charAt(0);
else
return null;
x.push(N), f[g++] = w + N.charAt(0), m--, w = N, m == 0 && (m = Math.pow(2, b), b++);
}
}
};
return c;
})();
e != null ? e.exports = t : typeof angular < "u" && angular != null && angular.module("LZString", []).factory("LZString", function() {
return t;
});
})(Zn)), Zn.exports;
}
var _a = /* @__PURE__ */ Hl();
const ms = 1800, hs = "share=";
function ps(e) {
const t = JSON.stringify(e);
return _a.compressToEncodedURIComponent(t);
}
function Oa(e) {
try {
const t = _a.decompressFromEncodedURIComponent(e);
if (!t) return null;
const n = JSON.parse(t);
return Ir(n) ? n : (console.warn("[shareUtils] Invalid AnalysisConfig in share URL"), null);
} catch {
return null;
}
}
function zl(e) {
const t = ps(e);
if (t.length <= ms)
return { encoded: t, queryOnly: !1 };
const n = {
version: e.version,
analysisType: e.analysisType,
activeView: e.activeView,
charts: {},
// Drop chart config to save space
query: e.query
}, s = ps(n);
return s.length <= ms ? { encoded: s, queryOnly: !0 } : { encoded: null, queryOnly: !0 };
}
function $a() {
if (typeof window > "u") return null;
const e = window.location.hash;
return !e || !e.startsWith(`#${hs}`) ? null : e.slice(hs.length + 1);
}
function Gl() {
if (typeof window > "u") return;
const e = new URL(window.location.href);
e.hash = "", window.history.replaceState(null, "", e.toString());
}
function Wl() {
const e = $a();
return e ? Oa(e) : null;
}
function Yl(e) {
const {
currentQuery: t,
isValidQuery: n,
chartType: s,
chartConfig: a,
displayConfig: i,
onQueryChange: o,
onChartConfigChange: c
} = e, l = W((h) => h.load), u = ge(!1);
he(() => {
if (u.current) return;
u.current = !0;
const h = Wl();
h && (l(h), Gl());
}, [l]), he(() => {
o && n && o(t);
}, [t, n, o]), he(() => {
c && c({
chartType: s,
chartConfig: a,
displayConfig: i
});
}, [s, a, i, c]);
}
function Jl(e = {}) {
const { initialData: t, externalColorPalette: n, onQueryChange: s, onChartConfigChange: a } = e, { features: i } = an(), o = Ia(), c = Rl(), l = _l({
queryState: c.queryState,
queryStates: c.queryStates,
isMultiQueryMode: c.isMultiQueryMode,
mergeStrategy: c.mergeStrategy,
activeQueryIndex: c.activeQueryIndex
}), u = W((R) => R.funnelBindingKey), h = W((R) => R.analysisType), f = W((R) => R.funnelCube), m = W((R) => R.funnelSteps), g = W((R) => R.activeFunnelStepIndex), b = W((R) => R.funnelTimeDimension), N = V(() => h !== "funnel" || !u?.dimension || !b || !m || m.length < 2 ? !1 : m.every((R) => R.filters.length > 0), [h, u, b, m]), x = W((R) => R.charts.funnel?.chartType) || "funnel", A = W((R) => R.charts.funnel?.chartConfig), w = V(() => A || {}, [A]), y = W((R) => R.flowCube), C = W((R) => R.flowBindingKey), T = W((R) => R.flowTimeDimension), p = W((R) => R.eventDimension), v = W((R) => R.startingStep), k = W((R) => R.stepsBefore), S = W((R) => R.stepsAfter), $ = W((R) => R.joinStrategy), D = W((R) => R.charts.flow?.displayConfig), F = V(
() => D || { showLegend: !0, showGrid: !0, showTooltip: !0 },
[D]
), K = W((R) => R.charts.flow?.chartType) || "sankey", P = W((R) => R.buildFunnelQueryFromSteps), te = V(() => h !== "funnel" ? null : P(), [h, P, m]), _ = W((R) => R.buildFlowQuery), O = V(() => h !== "flow" ? null : _(), [h, _, y, C, T, p, v, k, S, K, $]), ie = V(() => h === "flow" ? O !== null : h === "funnel" ? te !== null : c.isValidQuery ?? !1, [h, O, te, c.isValidQuery]), X = Ol({
currentQuery: c.currentQuery,
allQueries: c.allQueries,
multiQueryConfig: c.multiQueryConfig,
isMultiQueryMode: c.isMultiQueryMode,
isValidQuery: ie,
initialData: t,
funnelBindingKey: u,
isFunnelModeEnabled: N,
// New: pass analysisType and serverFunnelQuery for explicit mode routing
analysisType: h,
serverFunnelQuery: te,
// Flow mode: pass serverFlowQuery
serverFlowQuery: O
}), ce = Kl({
externalColorPalette: n,
combinedMetrics: l.combinedMetrics,
combinedBreakdowns: l.combinedBreakdowns,
hasDebounced: X.hasDebounced
}), Q = Vl();
Yl({
currentQuery: c.currentQuery,
isValidQuery: c.isValidQuery ?? !1,
chartType: ce.chartType,
chartConfig: ce.chartConfig,
displayConfig: ce.displayConfig,
onQueryChange: s,
onChartConfigChange: a
});
const Se = W((R) => R.openMetricsModal), L = W((R) => R.addMetric), pe = W((R) => R.removeMetric), z = W((R) => R.toggleMetric), H = W((R) => R.reorderMetrics), se = W((R) => R.openBreakdownsModal), me = W((R) => R.addBreakdown), le = W((R) => R.removeBreakdown), we = W((R) => R.toggleBreakdown), Y = W((R) => R.setBreakdownGranularity), Pe = W((R) => R.toggleBreakdownComparison), He = W((R) => R.reorderBreakdowns), Ne = W((R) => R.setFilters), _e = W((R) => R.dropFieldToFilter), We = W((R) => R.setOrder), Je = W((R) => R.clearQuery), Ke = W((R) => R.clearCurrentMode), Oe = W((R) => R.setFunnelBindingKey), Xe = W((R) => R.setAnalysisType), Qe = W((R) => R.setFunnelCube), J = W((R) => R.addFunnelStep), fe = W((R) => R.removeFunnelStep), ve = W((R) => R.updateFunnelStep), ke = W((R) => R.setActiveFunnelStepIndex), Fe = W((R) => R.reorderFunnelSteps), re = W((R) => R.setFunnelTimeDimension), be = W((R) => R.charts.funnel?.displayConfig), Ee = V(
() => be || { showLegend: !0, showGrid: !0, showTooltip: !0 },
[be]
), qe = W((R) => R.setFunnelDisplayConfig), Ze = W((R) => R.setFlowCube), xt = W((R) => R.setFlowBindingKey), vt = W((R) => R.setFlowTimeDimension), gt = W((R) => R.setEventDimension), wt = W((R) => R.setStartingStepName), Tt = W((R) => R.setStartingStepFilters), kt = W((R) => R.setStepsBefore), ct = W((R) => R.setStepsAfter), ut = W((R) => R.setJoinStrategy), Ye = E(
(R) => {
o.setState((Ue) => ({
charts: {
...Ue.charts,
flow: {
...Ue.charts.flow || { chartType: "sankey", chartConfig: {}, displayConfig: {} },
displayConfig: R
}
}
}));
},
[o]
), st = W((R) => R.aiState), Nt = W((R) => R.openAI), ze = W((R) => R.closeAI), M = W((R) => R.setAIPrompt), I = W((R) => R.setAIGenerating), B = W((R) => R.setAIError), Z = W((R) => R.setAIHasGeneratedQuery), ue = W((R) => R.saveAIPreviousState), ae = W((R) => R.restoreAIPreviousState), U = ge("idle"), G = ie, oe = W((R) => R.getValidation), Ae = V(
() => oe(),
// eslint-disable-next-line react-hooks/exhaustive-deps
[
oe,
c.queryStates,
h,
// Funnel deps
m,
u,
b,
// Flow deps
y,
C,
T,
p,
v,
k,
S,
$
]
), De = E(
(R, Ue, nt, $t) => {
Q.fieldModalMode === "metrics" && Ue === "measure" ? z(R.name) : Q.fieldModalMode === "breakdown" && we(R.name, Ue === "timeDimension"), $t || Q.closeFieldModal();
},
[Q, z, we]
), $e = E(async () => {
if (i?.aiEndpoint) {
ue(), I(!0), B(null);
try {
await new Promise((R) => setTimeout(R, 1e3)), Z(!0);
} catch (R) {
B(R instanceof Error ? R.message : "Failed to generate query");
} finally {
I(!1);
}
}
}, [i?.aiEndpoint, ue, I, B, Z]), et = E(() => {
ze(), Z(!1);
}, [ze, Z]), tt = E(() => {
ae(), ze();
}, [ae, ze]), at = E(async () => {
U.current = "copied", setTimeout(() => {
U.current = "idle";
}, 2e3);
}, []), Ct = E(() => {
const R = o.getState();
if (R.analysisType === "funnel") {
const Ue = R.buildFunnelQueryFromSteps();
return Ue || R.buildCurrentQuery();
}
return R.queryStates.length > 1 ? {
queries: R.buildAllQueries(),
mergeStrategy: R.mergeStrategy,
mergeKeys: R.getMergeKeys(),
queryLabels: R.queryStates.map((Ue, nt) => `Q${nt + 1}`),
// Include funnel-specific config when in funnel mode
funnelBindingKey: R.funnelBindingKey,
stepTimeToConvert: R.stepTimeToConvert
} : R.buildCurrentQuery();
}, [o]), Rt = E(() => {
const R = o.getState(), Ue = R.charts[R.analysisType];
return Ue ? {
chartType: Ue.chartType,
chartConfig: Ue.chartConfig,
displayConfig: Ue.displayConfig
} : {
chartType: ce.chartType,
chartConfig: ce.chartConfig,
displayConfig: ce.displayConfig
};
}, [o, ce.chartType, ce.chartConfig, ce.displayConfig]), yt = E(() => o.getState().analysisType, [o]);
return {
// Query state (from queryBuilder)
queryState: c.queryState,
queryStates: c.queryStates,
activeQueryIndex: c.activeQueryIndex,
mergeStrategy: c.mergeStrategy,
isMultiQueryMode: c.isMultiQueryMode,
mergeKeys: c.mergeKeys,
currentQuery: c.currentQuery,
allQueries: c.allQueries,
multiQueryConfig: c.multiQueryConfig,
multiQueryValidation: c.multiQueryValidation,
// Funnel state (legacy)
funnelBindingKey: u,
isFunnelModeEnabled: N,
// Analysis Type state (new)
analysisType: h,
funnelCube: f,
funnelSteps: m,
activeFunnelStepIndex: g,
funnelTimeDimension: b,
funnelChartType: x,
funnelChartConfig: w,
funnelDisplayConfig: Ee,
// Flow state (new)
flowCube: y,
flowBindingKey: C,
flowTimeDimension: T,
eventDimension: p,
startingStep: v,
stepsBefore: k,
stepsAfter: S,
joinStrategy: $,
flowDisplayConfig: F,
// Data fetching (from queryExecution)
executionStatus: X.executionStatus,
executionResults: X.executionResults,
perQueryResults: X.perQueryResults,
isLoading: X.isLoading,
isFetching: X.isFetching,
error: X.error,
isValidQuery: ie,
debugDataPerQuery: X.debugDataPerQuery,
funnelExecutedQueries: X.funnelExecutedQueries,
funnelServerQuery: X.funnelServerQuery,
funnelDebugData: X.funnelDebugData,
flowServerQuery: X.flowServerQuery,
flowDebugData: X.flowDebugData,
// Chart configuration (from chartDefaults)
// Note: Funnel chart type is determined by analysisType === 'funnel', not mergeStrategy
chartType: ce.chartType,
chartConfig: ce.chartConfig,
displayConfig: ce.displayConfig,
colorPalette: ce.colorPalette,
localPaletteName: ce.localPaletteName,
chartAvailability: ce.chartAvailability,
combinedMetrics: l.combinedMetrics,
combinedBreakdowns: l.combinedBreakdowns,
effectiveBreakdowns: l.effectiveBreakdowns,
// UI state (from uiState)
activeTab: Q.activeTab,
activeView: Q.activeView,
displayLimit: Q.displayLimit,
showFieldModal: Q.showFieldModal,
fieldModalMode: Q.fieldModalMode,
activeTableIndex: Q.activeTableIndex,
userManuallySelectedChart: Q.userManuallySelectedChart,
// AI state
aiState: {
isOpen: st.isOpen,
userPrompt: st.userPrompt,
isGenerating: st.isGenerating,
error: st.error,
hasGeneratedQuery: st.hasGeneratedQuery
},
// Share state
shareButtonState: U.current,
canShare: G,
// Adapter validation (NEW - Phase 5)
adapterValidation: Ae,
// Actions
actions: {
// Query state (from queryBuilder)
setActiveQueryIndex: c.setActiveQueryIndex,
setMergeStrategy: c.setMergeStrategy,
// Metrics
openMetricsModal: Se,
addMetric: L,
removeMetric: pe,
toggleMetric: z,
reorderMetrics: H,
// Breakdowns
openBreakdownsModal: se,
addBreakdown: me,
removeBreakdown: le,
toggleBreakdown: we,
setBreakdownGranularity: Y,
toggleBreakdownComparison: Pe,
reorderBreakdowns: He,
// Filters
setFilters: Ne,
dropFieldToFilter: _e,
setOrder: We,
// Multi-query (from queryBuilder)
addQuery: c.addQuery,
removeQuery: c.removeQuery,
// Funnel (legacy)
setFunnelBindingKey: Oe,
// Analysis Type (new)
setAnalysisType: Xe,
// Funnel Mode (new dedicated state)
setFunnelCube: Qe,
addFunnelStep: J,
removeFunnelStep: fe,
updateFunnelStep: ve,
setActiveFunnelStepIndex: ke,
reorderFunnelSteps: Fe,
setFunnelTimeDimension: re,
setFunnelDisplayConfig: qe,
// Flow Mode actions
setFlowCube: Ze,
setFlowBindingKey: xt,
setFlowTimeDimension: vt,
setEventDimension: gt,
setStartingStepName: wt,
setStartingStepFilters: Tt,
setStepsBefore: kt,
setStepsAfter: ct,
setJoinStrategy: ut,
setFlowDisplayConfig: Ye,
// Chart (from chartDefaults)
setChartType: ce.setChartType,
setChartConfig: ce.setChartConfig,
setDisplayConfig: ce.setDisplayConfig,
setLocalPaletteName: ce.setLocalPaletteName,
// UI (from uiState)
setActiveTab: Q.setActiveTab,
setActiveView: Q.setActiveView,
setDisplayLimit: Q.setDisplayLimit,
closeFieldModal: Q.closeFieldModal,
setActiveTableIndex: Q.setActiveTableIndex,
// AI
openAI: Nt,
closeAI: ze,
setAIPrompt: M,
generateAI: $e,
acceptAI: et,
cancelAI: tt,
// Share
share: at,
// Utility
clearQuery: Je,
clearCurrentMode: Ke,
refetch: X.refetch,
handleFieldSelected: De
},
// Refs
getQueryConfig: Ct,
getChartConfig: Rt,
getAnalysisType: yt
};
}
async function Xl(e, t, n = "/api/ai/generate") {
const s = {
text: t
// 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:", t.length);
const i = await fetch(n, {
method: "POST",
headers: a,
body: JSON.stringify(s)
});
if (console.log("📥 Client: Proxy response"), console.log(" Status:", i.status), console.log(" Status Text:", i.statusText), !i.ok) {
let c = `Failed to generate content: ${i.status} ${i.statusText}`;
try {
const l = await i.json();
if (console.error("❌ Client: Proxy error:", l), i.status === 429 && l.error === "Daily quota exceeded")
throw new Error(
`${l.message}
${l.suggestion || "Add your own Gemini API key for unlimited access."}`
);
l.error && (c = l.message || l.error, l.suggestion && (c += `
💡 ${l.suggestion}`));
} catch {
try {
const l = await i.text();
console.error("❌ Client: Proxy text error:", l), c = l || c;
} catch {
console.error("❌ Client: Could not parse error response");
}
}
throw new Error(c);
}
const o = await i.json();
return console.log("✅ Client: Successfully generated content"), o;
}
function Zl(e) {
return (e.query || "").replace(/```json\s*/g, "").replace(/```\s*/g, "").replace(/^\s*```.*\n/gm, "").trim();
}
function ec(e) {
return typeof e == "object" && e !== null && "funnel" in e && typeof e.funnel == "object";
}
function tc({
state: e,
setState: t,
chartType: n,
setChartType: s,
chartConfig: a,
setChartConfig: i,
displayConfig: o,
setDisplayConfig: c,
setUserManuallySelectedChart: l,
setActiveView: u,
aiEndpoint: h = "/api/ai",
analysisType: f,
setAnalysisType: m,
loadFunnelFromServerQuery: g,
getFullConfig: b,
loadFullConfig: N
}) {
const [x, A] = ee({
isOpen: !1,
userPrompt: "",
isGenerating: !1,
error: null,
hasGeneratedQuery: !1,
previousState: null,
previousConfig: null
}), w = E(() => {
const k = b?.() ?? null;
A({
isOpen: !0,
userPrompt: "",
isGenerating: !1,
error: null,
hasGeneratedQuery: !1,
previousState: {
metrics: [...e.metrics],
breakdowns: [...e.breakdowns],
filters: [...e.filters],
chartType: n,
chartConfig: { ...a },
displayConfig: { ...o },
analysisType: f || "query"
},
previousConfig: k
});
}, [e.metrics, e.breakdowns, e.filters, n, a, o, f, b]), y = E(() => {
A((k) => ({
...k,
isOpen: !1,
userPrompt: "",
error: null,
hasGeneratedQuery: !1
}));
}, []), C = E((k) => {
A((S) => ({ ...S, userPrompt: k }));
}, []), T = E(async () => {
if (x.userPrompt.trim()) {
A((k) => ({ ...k, isGenerating: !0, error: null }));
try {
const k = await Xl(
"",
// API key not needed for server-side AI
x.userPrompt,
h
), S = Zl(k), $ = JSON.parse(S), D = "query" in $ && $.query ? $.query : $, F = "chartType" in $ ? $.chartType : void 0, K = "chartConfig" in $ ? $.chartConfig : void 0;
if (ec(D))
if (m && g) {
m("funnel"), g(D), s("funnel"), l(!0), K && i(K), u("chart"), A((te) => ({
...te,
isGenerating: !1,
hasGeneratedQuery: !0
}));
return;
} else
throw new Error("Funnel queries require funnel mode support. Please switch to funnel mode manually.");
const P = D;
t((te) => ({
...te,
metrics: (P.measures || []).map((_, O) => ({
id: lt(),
field: _,
label: rn(O)
})),
breakdowns: [
...(P.dimensions || []).map((_) => ({
id: lt(),
field: _,
isTimeDimension: !1
})),
...(P.timeDimensions || []).map((_) => ({
id: lt(),
field: _.dimension,
granularity: _.granularity,
isTimeDimension: !0
}))
],
filters: P.filters || []
})), f === "funnel" && m && m("query"), F && (s(F), l(!0)), K && i(K), u("chart"), A((te) => ({
...te,
isGenerating: !1,
hasGeneratedQuery: !0
}));
} catch (k) {
A((S) => ({
...S,
isGenerating: !1,
error: k instanceof Error ? k.message : "Failed to generate query"
}));
}
}
}, [x.userPrompt, h, t, s, l, i, u, f, m, g]), p = E(() => {
A({
isOpen: !1,
userPrompt: "",
isGenerating: !1,
error: null,
hasGeneratedQuery: !1,
previousState: null,
previousConfig: null
});
}, []), v = E(() => {
x.previousConfig && N ? N(x.previousConfig) : x.previousState && (t((k) => ({
...k,
metrics: x.previousState.metrics,
breakdowns: x.previousState.breakdowns,
filters: x.previousState.filters
})), s(x.previousState.chartType), i(x.previousState.chartConfig), c(x.previousState.displayConfig), m && x.previousState.analysisType && m(x.previousState.analysisType)), A({
isOpen: !1,
userPrompt: "",
isGenerating: !1,
error: null,
hasGeneratedQuery: !1,
previousState: null,
previousConfig: null
});
}, [x.previousState, x.previousConfig, t, s, i, c, m, N]);
return {
aiState: x,
handleOpenAI: w,
handleCloseAI: y,
handleAIPromptChange: C,
handleGenerateAI: T,
handleAcceptAI: p,
handleCancelAI: v
};
}
function nc({
isValidQuery: e,
getAnalysisConfig: t
}) {
const [n, s] = ee("idle"), a = E(async () => {
if (!e) return;
const i = t(), { encoded: o, queryOnly: c } = zl(i);
if (!o)
return;
const l = `${window.location.origin}${window.location.pathname}#share=${o}`;
try {
await navigator.clipboard.writeText(l);
} catch {
const u = document.createElement("textarea");
u.value = l, document.body.appendChild(u), u.select(), document.execCommand("copy"), document.body.removeChild(u);
}
s(c ? "copied-no-chart" : "copied"), setTimeout(() => {
s("idle");
}, 2e3);
}, [e, t]);
return {
shareButtonState: n,
handleShare: a
};
}
const rc = q("check");
function sc({
field: e,
isSelected: t,
isFocused: n,
onClick: s,
onMouseEnter: a,
...i
}) {
const o = () => {
if (e.fieldType === "measure") {
const u = on(e.type);
return u ? /* @__PURE__ */ r(u, { className: "w-4 h-4" }) : null;
} else if (e.fieldType === "timeDimension") {
const u = kn("time");
return u ? /* @__PURE__ */ r(u, { className: "w-4 h-4" }) : null;
} else {
const u = kn("dimension");
return u ? /* @__PURE__ */ r(u, { className: "w-4 h-4" }) : null;
}
}, c = () => e.fieldType === "measure" ? "bg-dc-measure text-dc-measure-text" : e.fieldType === "timeDimension" ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text", l = () => e.fieldType === "measure" ? e.type.charAt(0).toUpperCase() + e.type.slice(1) : e.fieldType === "timeDimension" ? "Time" : "Dim";
return /* @__PURE__ */ d(
"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" : t ? "bg-dc-success/10" : "hover:bg-dc-surface-hover"}`,
...i,
children: [
/* @__PURE__ */ r(
"span",
{
className: `shrink-0 w-8 h-8 flex items-center justify-center rounded-md ${e.fieldType === "measure" ? "bg-dc-measure text-dc-measure-text" : e.fieldType === "timeDimension" ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text"}`,
children: o()
}
),
/* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ r("div", { className: "text-sm font-medium text-dc-text truncate", children: e.title }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted truncate", children: e.name })
] }),
/* @__PURE__ */ r(
"span",
{
className: `shrink-0 px-2 py-0.5 rounded text-xs font-medium ${c()}`,
children: l()
}
),
t && /* @__PURE__ */ r("span", { className: "shrink-0 w-5 h-5 flex items-center justify-center rounded-full bg-dc-success text-white", children: /* @__PURE__ */ r(rc, { className: "w-3 h-3" }) })
]
}
);
}
const gs = Ge(sc);
function ac({ field: e }) {
if (!e)
return /* @__PURE__ */ r("div", { className: "p-6 text-center text-dc-text-muted", children: /* @__PURE__ */ r("p", { className: "text-sm", children: "Hover over a field to see details" }) });
const t = () => {
if (e.fieldType === "measure") {
const a = on(e.type);
return a ? /* @__PURE__ */ r(a, { className: "w-6 h-6" }) : null;
} else if (e.fieldType === "timeDimension") {
const a = kn("time");
return a ? /* @__PURE__ */ r(a, { className: "w-6 h-6" }) : null;
} else {
const a = kn("dimension");
return a ? /* @__PURE__ */ r(a, { className: "w-6 h-6" }) : null;
}
}, n = () => e.fieldType === "measure" ? "bg-dc-measure text-dc-measure-text" : e.fieldType === "timeDimension" ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text", s = () => e.fieldType === "measure" ? {
count: "Count",
countDistinct: "Count Distinct",
countDistinctApprox: "Count Distinct (Approx)",
sum: "Sum",
avg: "Average",
min: "Minimum",
max: "Maximum",
runningTotal: "Running Total",
number: "Number"
}[e.type] || e.type : e.fieldType === "timeDimension" ? "Time Dimension" : {
string: "Text",
number: "Number",
boolean: "Boolean",
geo: "Geographic"
}[e.type] || "Dimension";
return /* @__PURE__ */ d("div", { className: "p-4", children: [
/* @__PURE__ */ d("div", { className: "flex items-start gap-3 mb-4", children: [
/* @__PURE__ */ r(
"span",
{
className: `shrink-0 w-12 h-12 flex items-center justify-center rounded-lg ${n()}`,
children: t()
}
),
/* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ r("h3", { className: "text-base font-semibold text-dc-text leading-tight", children: e.title }),
/* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted mt-0.5 truncate", children: e.name })
] })
] }),
e.description && /* @__PURE__ */ r("div", { className: "mb-4", children: /* @__PURE__ */ r("p", { className: "text-sm text-dc-text-secondary leading-relaxed", children: e.description }) }),
/* @__PURE__ */ d("div", { className: "space-y-3 pt-4 border-t border-dc-border", children: [
/* @__PURE__ */ d("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ r("span", { className: "text-xs text-dc-text-muted", children: "Type" }),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text font-medium", children: s() })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ r("span", { className: "text-xs text-dc-text-muted", children: "Cube" }),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text font-medium", children: e.cubeName })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ r("span", { className: "text-xs text-dc-text-muted", children: "Category" }),
/* @__PURE__ */ r(
"span",
{
className: `text-xs px-2 py-0.5 rounded font-medium ${e.fieldType === "measure" ? "bg-dc-measure text-dc-measure-text" : e.fieldType === "timeDimension" ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text"}`,
children: e.fieldType === "measure" ? "Measure" : e.fieldType === "timeDimension" ? "Time Dimension" : "Dimension"
}
)
] })
] }),
/* @__PURE__ */ r("div", { className: "mt-6 p-3 bg-dc-surface rounded-lg", children: /* @__PURE__ */ d("p", { className: "text-xs text-dc-text-muted", children: [
"Press ",
/* @__PURE__ */ r("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 ic = Ge(ac), oc = q("search"), lc = q("close");
function qr({
isOpen: e,
onClose: t,
onSelect: n,
mode: s,
schema: a,
selectedFields: i,
recentFields: o
}) {
const [c, l] = ee(""), [u, h] = ee(null), [f, m] = ee(null), [g, b] = ee(-1), [N, x] = ee(null), A = ge(null), w = ge(null), y = V(() => {
if (o) return o;
const O = ka();
return s === "metrics" ? O.metrics : O.breakdowns;
}, [o, s]), C = s, T = V(() => Da(a, C), [a, C]), p = V(() => Xo(a), [a]), v = V(() => Yo(T, c, u), [T, c, u]), k = V(() => Jo(v), [v]), S = V(() => c.trim() ? [] : rl(a, C, y).filter(
(O) => !u || O.cubeName === u
), [a, C, y, c, u]), $ = V(() => {
const O = [...S];
return k.forEach((ie) => {
O.push(...ie);
}), O;
}, [S, k]);
he(() => {
e && A.current && A.current.focus();
}, [e]), he(() => {
e || (l(""), h(null), m(null), b(-1), x(null));
}, [e]);
const D = E(
(O, ie = !1) => {
nl(O.name, s === "metrics" ? "metrics" : "breakdowns");
const X = {
name: O.name,
title: O.title,
shortTitle: O.shortTitle,
type: O.type,
description: O.description
};
n(X, O.fieldType, O.cubeName, ie);
},
[s, n]
), F = E(
(O, ie, X = !1) => {
if (X && N !== null && N !== ie) {
const ce = Math.min(N, ie), Q = Math.max(N, ie);
for (let Se = ce; Se <= Q; Se++) {
const L = $[Se];
L && !i.includes(L.name) && D(L, !0);
}
} else X ? D(O, !0) : D(O, !1);
x(ie);
},
[$, N, D, i]
), K = E(
(O) => {
if ($.length !== 0)
switch (O.key) {
case "ArrowDown":
O.preventDefault(), b((ie) => {
const X = Math.min(ie + 1, $.length - 1);
return m($[X]), X;
});
break;
case "ArrowUp":
O.preventDefault(), b((ie) => {
const X = Math.max(ie - 1, 0);
return m($[X]), X;
});
break;
case "Enter":
O.preventDefault(), g >= 0 && $[g] && F($[g], g, O.shiftKey);
break;
case "Escape":
O.preventDefault(), t();
break;
}
},
[$, g, F, t]
);
if (he(() => {
if (g >= 0 && w.current) {
const O = w.current.querySelector(
`[data-field-index="${g}"]`
);
O && O.scrollIntoView({ block: "nearest", behavior: "smooth" });
}
}, [g]), !e) return null;
const P = s === "metrics" ? "Search metrics..." : s === "filter" ? "Search fields to filter..." : "Search dimensions...", te = s === "metrics" ? "Select a Metric" : s === "filter" ? "Select a Field to Filter" : "Select a Dimension", _ = g >= 0 && $[g] ? `field-option-${$[g].name.replace(/\./g, "-")}` : void 0;
return /* @__PURE__ */ r(
"div",
{
className: "fixed inset-0 z-50 flex items-center justify-center",
style: { backgroundColor: "var(--dc-overlay)" },
onClick: t,
role: "presentation",
children: /* @__PURE__ */ d(
"div",
{
role: "dialog",
"aria-modal": "true",
"aria-label": te,
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: (O) => O.stopPropagation(),
onKeyDown: K,
children: [
/* @__PURE__ */ d("div", { className: "shrink-0 border-b border-dc-border", children: [
/* @__PURE__ */ d("div", { className: "flex items-center px-4 py-3 gap-3", children: [
/* @__PURE__ */ r(oc, { className: "w-5 h-5 text-dc-text-muted", "aria-hidden": !0 }),
/* @__PURE__ */ r(
"input",
{
ref: A,
type: "text",
value: c,
onChange: (O) => {
l(O.target.value), b(-1);
},
placeholder: P,
className: "flex-1 bg-transparent border-none outline-none text-dc-text placeholder-dc-text-muted text-lg",
"aria-label": P,
"aria-controls": "field-search-results",
"aria-activedescendant": _,
role: "combobox",
"aria-expanded": "true",
"aria-autocomplete": "list"
}
),
/* @__PURE__ */ r(
"button",
{
onClick: t,
className: "p-1 text-dc-text-secondary hover:text-dc-text rounded",
"aria-label": "Close dialog",
children: /* @__PURE__ */ r(lc, { className: "w-5 h-5", "aria-hidden": !0 })
}
)
] }),
p.length > 1 && /* @__PURE__ */ r("div", { className: "md:hidden px-4 pb-3", children: /* @__PURE__ */ d(
"select",
{
value: u || "",
onChange: (O) => h(O.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__ */ r("option", { value: "", children: "All Cubes" }),
p.map((O) => /* @__PURE__ */ r("option", { value: O, children: yn(O, a) }, O))
]
}
) })
] }),
/* @__PURE__ */ d("div", { className: "flex-1 flex overflow-hidden", children: [
/* @__PURE__ */ r(
"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__ */ d("div", { className: "p-2", role: "group", "aria-label": "Cube categories", children: [
/* @__PURE__ */ r(
"button",
{
onClick: () => h(null),
className: `w-full text-left px-3 py-2 rounded-md text-sm transition-colors ${u === null ? "bg-dc-primary/10 text-dc-primary font-medium" : "text-dc-text hover:bg-dc-surface-hover"}`,
"aria-pressed": u === null,
children: "All"
}
),
p.map((O) => /* @__PURE__ */ r(
"button",
{
onClick: () => h(O),
className: `w-full text-left px-3 py-2 rounded-md text-sm transition-colors truncate ${u === O ? "bg-dc-primary/10 text-dc-primary font-medium" : "text-dc-text hover:bg-dc-surface-hover"}`,
title: yn(O, a),
"aria-pressed": u === O,
children: yn(O, a)
},
O
))
] })
}
),
/* @__PURE__ */ r(
"div",
{
id: "field-search-results",
ref: w,
className: "flex-1 overflow-y-auto p-4",
role: "listbox",
"aria-label": "Available fields",
children: v.length === 0 && S.length === 0 ? /* @__PURE__ */ d("div", { className: "text-center py-12 text-dc-text-muted", children: [
/* @__PURE__ */ r("p", { className: "text-lg mb-2", children: "No fields found" }),
/* @__PURE__ */ r("p", { className: "text-sm", children: c ? `No ${s === "metrics" ? "metrics" : "dimensions"} match "${c}"` : `No ${s === "metrics" ? "metrics" : "dimensions"} available` })
] }) : /* @__PURE__ */ d("div", { className: "space-y-6", children: [
S.length > 0 && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("h3", { className: "text-xs font-semibold text-dc-text-muted uppercase tracking-wider mb-2", children: "Recents" }),
/* @__PURE__ */ r("div", { className: "space-y-1", children: S.map((O, ie) => /* @__PURE__ */ r(
gs,
{
field: O,
isSelected: i.includes(O.name),
isFocused: g === ie,
onClick: (X) => F(O, ie, X.shiftKey),
onMouseEnter: () => {
m(O), b(ie);
},
"data-field-index": ie
},
`recent-${O.name}`
)) })
] }),
Array.from(k.entries()).map(([O, ie]) => /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("h3", { className: "text-xs font-semibold text-dc-text-muted uppercase tracking-wider mb-2", children: yn(O, a) }),
/* @__PURE__ */ r("div", { className: "space-y-1", children: ie.map((X) => {
const ce = S.length + Array.from(k.entries()).slice(
0,
Array.from(k.keys()).indexOf(O)
).reduce((Q, [, Se]) => Q + Se.length, 0) + ie.indexOf(X);
return /* @__PURE__ */ r(
gs,
{
field: X,
isSelected: i.includes(X.name),
isFocused: g === ce,
onClick: (Q) => F(X, ce, Q.shiftKey),
onMouseEnter: () => {
m(X), b(ce);
},
"data-field-index": ce
},
X.name
);
}) })
] }, O))
] })
}
),
/* @__PURE__ */ r("div", { className: "hidden md:block w-72 shrink-0 border-l border-dc-border bg-dc-surface-secondary overflow-y-auto", children: /* @__PURE__ */ r(ic, { field: f }) })
] }),
/* @__PURE__ */ d("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__ */ d("div", { children: [
/* @__PURE__ */ r("span", { className: "text-dc-text-secondary", children: v.length }),
" ",
s === "metrics" ? "metrics" : s === "filter" ? "fields" : "dimensions",
" available"
] }),
/* @__PURE__ */ d("div", { className: "hidden md:flex items-center gap-4", children: [
/* @__PURE__ */ d("span", { children: [
/* @__PURE__ */ r("kbd", { className: "px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs", children: "↑↓" }),
" Navigate"
] }),
/* @__PURE__ */ d("span", { children: [
/* @__PURE__ */ r("kbd", { className: "px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs", children: "Enter" }),
" Select"
] }),
/* @__PURE__ */ d("span", { children: [
/* @__PURE__ */ r("kbd", { className: "px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs", children: "Shift" }),
"+Click Multi-select"
] }),
/* @__PURE__ */ d("span", { children: [
/* @__PURE__ */ r("kbd", { className: "px-1.5 py-0.5 bg-dc-surface-tertiary rounded text-xs", children: "Esc" }),
" Close"
] })
] })
] })
]
}
)
}
);
}
function ys(e) {
return e.replace(/_/g, " ");
}
function cc(e) {
switch (e) {
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 dc = ({ analysis: e }) => {
const t = q("info"), n = q("chevronRight"), s = q("warning"), a = q("table"), i = q("link"), o = q("success"), c = q("error");
return /* @__PURE__ */ d("div", { className: "bg-dc-surface-secondary border border-dc-border rounded-lg p-4 space-y-4", children: [
/* @__PURE__ */ d("div", { className: "border-b border-dc-border pb-3", children: [
/* @__PURE__ */ d("h4", { className: "text-sm font-semibold text-dc-text mb-2 flex items-center", children: [
/* @__PURE__ */ r(t, { className: "w-4 h-4 mr-2" }),
"Query Summary"
] }),
/* @__PURE__ */ d("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-2 text-xs", children: [
/* @__PURE__ */ d("div", { className: "bg-dc-surface p-2 rounded", children: [
/* @__PURE__ */ r("span", { className: "text-dc-text-muted", children: "Type:" }),
/* @__PURE__ */ r("span", { className: "ml-1 font-medium text-dc-text", children: ys(e.querySummary.queryType) })
] }),
/* @__PURE__ */ d("div", { className: "bg-dc-surface p-2 rounded", children: [
/* @__PURE__ */ r("span", { className: "text-dc-text-muted", children: "Cubes:" }),
/* @__PURE__ */ r("span", { className: "ml-1 font-medium text-dc-text", children: e.cubeCount })
] }),
/* @__PURE__ */ d("div", { className: "bg-dc-surface p-2 rounded", children: [
/* @__PURE__ */ r("span", { className: "text-dc-text-muted", children: "Joins:" }),
/* @__PURE__ */ r("span", { className: "ml-1 font-medium text-dc-text", children: e.querySummary.joinCount })
] }),
/* @__PURE__ */ d("div", { className: "bg-dc-surface p-2 rounded", children: [
/* @__PURE__ */ r("span", { className: "text-dc-text-muted", children: "CTEs:" }),
/* @__PURE__ */ r("span", { className: "ml-1 font-medium text-dc-text", children: e.querySummary.cteCount })
] })
] })
] }),
/* @__PURE__ */ d("div", { className: "border-b border-dc-border pb-3", children: [
/* @__PURE__ */ d("h4", { className: "text-sm font-semibold text-dc-text mb-2 flex items-center", children: [
/* @__PURE__ */ r(a, { className: "w-4 h-4 mr-2" }),
"Primary Cube (FROM table)"
] }),
/* @__PURE__ */ d("div", { className: "bg-dc-surface p-3 rounded text-sm", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 mb-2 flex-wrap", children: [
/* @__PURE__ */ r("span", { className: "font-mono font-medium text-dc-primary", children: e.primaryCube.selectedCube }),
/* @__PURE__ */ r("span", { className: `text-xs px-2 py-0.5 rounded ${cc(e.primaryCube.reason)}`, children: ys(e.primaryCube.reason) })
] }),
/* @__PURE__ */ r("p", { className: "text-dc-text-secondary text-xs", children: e.primaryCube.explanation }),
e.primaryCube.candidates && e.primaryCube.candidates.length > 1 && /* @__PURE__ */ d("details", { className: "mt-2", children: [
/* @__PURE__ */ d("summary", { className: "text-xs text-dc-text-muted cursor-pointer hover:text-dc-text", children: [
"Show candidates (",
e.primaryCube.candidates.length,
")"
] }),
/* @__PURE__ */ r("div", { className: "mt-2 space-y-1 ml-2", children: e.primaryCube.candidates.map((l, u) => /* @__PURE__ */ d("div", { className: "text-xs flex items-center gap-2 flex-wrap", children: [
/* @__PURE__ */ r("span", { className: `font-mono ${l.cubeName === e.primaryCube.selectedCube ? "font-bold text-dc-primary" : "text-dc-text-muted"}`, children: l.cubeName }),
/* @__PURE__ */ d("span", { className: "text-dc-text-muted", children: [
"dims: ",
l.dimensionCount,
", joins: ",
l.joinCount
] }),
l.canReachAll ? /* @__PURE__ */ d("span", { className: "text-dc-success flex items-center gap-0.5", children: [
/* @__PURE__ */ r(o, { className: "w-3 h-3" }),
"reachable"
] }) : /* @__PURE__ */ d("span", { className: "text-dc-error flex items-center gap-0.5", children: [
/* @__PURE__ */ r(c, { className: "w-3 h-3" }),
"cannot reach all"
] })
] }, u)) })
] })
] })
] }),
e.joinPaths.length > 0 && /* @__PURE__ */ d("div", { className: "border-b border-dc-border pb-3", children: [
/* @__PURE__ */ d("h4", { className: "text-sm font-semibold text-dc-text mb-2 flex items-center", children: [
/* @__PURE__ */ r(i, { className: "w-4 h-4 mr-2" }),
"Join Paths"
] }),
/* @__PURE__ */ r("div", { className: "space-y-2", children: e.joinPaths.map((l, u) => /* @__PURE__ */ d("div", { className: "bg-dc-surface p-3 rounded text-sm", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 mb-2 flex-wrap", children: [
/* @__PURE__ */ r("span", { className: "font-mono text-dc-text-secondary", children: e.primaryCube.selectedCube }),
/* @__PURE__ */ r(n, { className: "w-4 h-4 text-dc-text-muted" }),
/* @__PURE__ */ r("span", { className: "font-mono font-medium text-dc-text", children: l.targetCube }),
l.pathFound ? /* @__PURE__ */ d("span", { className: "text-xs px-2 py-0.5 bg-dc-success-bg text-dc-success rounded", children: [
l.pathLength,
" step",
l.pathLength !== 1 ? "s" : ""
] }) : /* @__PURE__ */ r("span", { className: "text-xs px-2 py-0.5 bg-dc-error-bg text-dc-error rounded", children: "No path" })
] }),
l.pathFound && l.path && l.path.length > 0 && /* @__PURE__ */ r("div", { className: "space-y-1 ml-2", children: l.path.map((h, f) => /* @__PURE__ */ d("div", { className: "flex items-center gap-1 text-xs flex-wrap", children: [
/* @__PURE__ */ r("span", { className: "font-mono text-dc-text-secondary", children: h.fromCube }),
/* @__PURE__ */ r(n, { className: "w-3 h-3 text-dc-text-muted" }),
/* @__PURE__ */ r("span", { className: "font-mono text-dc-text", children: h.toCube }),
/* @__PURE__ */ d("span", { className: "text-dc-text-muted", children: [
"(",
h.relationship,
", ",
h.joinType,
" join)"
] }),
h.joinColumns.length > 0 && /* @__PURE__ */ d("span", { className: "text-dc-text-muted", children: [
"on ",
h.joinColumns.map((m) => `${m.sourceColumn}=${m.targetColumn}`).join(", ")
] })
] }, f)) }),
!l.pathFound && l.error && /* @__PURE__ */ r("p", { className: "text-xs text-dc-error mt-1", children: l.error }),
l.visitedCubes && l.visitedCubes.length > 0 && !l.pathFound && /* @__PURE__ */ d("details", { className: "mt-1", children: [
/* @__PURE__ */ d("summary", { className: "text-xs text-dc-text-muted cursor-pointer hover:text-dc-text", children: [
"Cubes visited during search (",
l.visitedCubes.length,
")"
] }),
/* @__PURE__ */ r("div", { className: "mt-1 text-xs text-dc-text-muted ml-2", children: l.visitedCubes.join(" → ") })
] })
] }, u)) })
] }),
e.preAggregations.length > 0 && /* @__PURE__ */ d("div", { className: "border-b border-dc-border pb-3", children: [
/* @__PURE__ */ d("h4", { className: "text-sm font-semibold text-dc-text mb-2 flex items-center", children: [
/* @__PURE__ */ r(a, { className: "w-4 h-4 mr-2" }),
"Pre-Aggregation CTEs"
] }),
/* @__PURE__ */ r("div", { className: "space-y-2", children: e.preAggregations.map((l, u) => /* @__PURE__ */ d("div", { className: "bg-dc-surface p-3 rounded text-sm", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 mb-1 flex-wrap", children: [
/* @__PURE__ */ r("span", { className: "font-mono font-medium text-dc-text", children: l.cubeName }),
/* @__PURE__ */ r("span", { className: "text-xs text-dc-text-muted", children: "as" }),
/* @__PURE__ */ r("code", { className: "text-xs bg-dc-surface-secondary px-1 rounded font-mono", children: l.cteAlias })
] }),
/* @__PURE__ */ r("p", { className: "text-xs text-dc-text-secondary", children: l.reason }),
/* @__PURE__ */ d("div", { className: "mt-1 text-xs text-dc-text-muted", children: [
/* @__PURE__ */ r("span", { className: "font-medium", children: "Measures:" }),
" ",
l.measures.join(", ")
] }),
l.joinKeys.length > 0 && /* @__PURE__ */ d("div", { className: "mt-1 text-xs text-dc-text-muted", children: [
/* @__PURE__ */ r("span", { className: "font-medium", children: "Join keys:" }),
" ",
l.joinKeys.map((h) => `${h.sourceColumn}=${h.targetColumn}`).join(", ")
] })
] }, u)) })
] }),
e.warnings && e.warnings.length > 0 && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d("h4", { className: "text-sm font-semibold text-dc-warning mb-2 flex items-center", children: [
/* @__PURE__ */ r(s, { className: "w-4 h-4 mr-2" }),
"Warnings"
] }),
/* @__PURE__ */ r("ul", { className: "list-disc list-inside text-xs text-dc-warning space-y-1", children: e.warnings.map((l, u) => /* @__PURE__ */ r("li", { children: l }, u)) })
] }),
e.cubesInvolved.length > 0 && /* @__PURE__ */ d("div", { className: "text-xs text-dc-text-muted pt-2 border-t border-dc-border", children: [
/* @__PURE__ */ r("span", { className: "font-medium", children: "Cubes involved:" }),
" ",
e.cubesInvolved.join(", ")
] })
] });
};
var er, bs;
function uc() {
if (bs) return er;
bs = 1;
function e(M) {
return M instanceof Map ? M.clear = M.delete = M.set = function() {
throw new Error("map is read-only");
} : M instanceof Set && (M.add = M.clear = M.delete = function() {
throw new Error("set is read-only");
}), Object.freeze(M), Object.getOwnPropertyNames(M).forEach((I) => {
const B = M[I], Z = typeof B;
(Z === "object" || Z === "function") && !Object.isFrozen(B) && e(B);
}), M;
}
class t {
/**
* @param {CompiledMode} mode
*/
constructor(I) {
I.data === void 0 && (I.data = {}), this.data = I.data, this.isMatchIgnored = !1;
}
ignoreMatch() {
this.isMatchIgnored = !0;
}
}
function n(M) {
return M.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}
function s(M, ...I) {
const B = /* @__PURE__ */ Object.create(null);
for (const Z in M)
B[Z] = M[Z];
return I.forEach(function(Z) {
for (const ue in Z)
B[ue] = Z[ue];
}), /** @type {T} */
B;
}
const a = "</span>", i = (M) => !!M.scope, o = (M, { prefix: I }) => {
if (M.startsWith("language:"))
return M.replace("language:", "language-");
if (M.includes(".")) {
const B = M.split(".");
return [
`${I}${B.shift()}`,
...B.map((Z, ue) => `${Z}${"_".repeat(ue + 1)}`)
].join(" ");
}
return `${I}${M}`;
};
class c {
/**
* Creates a new HTMLRenderer
*
* @param {Tree} parseTree - the parse tree (must support `walk` API)
* @param {{classPrefix: string}} options
*/
constructor(I, B) {
this.buffer = "", this.classPrefix = B.classPrefix, I.walk(this);
}
/**
* Adds texts to the output stream
*
* @param {string} text */
addText(I) {
this.buffer += n(I);
}
/**
* Adds a node open to the output stream (if needed)
*
* @param {Node} node */
openNode(I) {
if (!i(I)) return;
const B = o(
I.scope,
{ prefix: this.classPrefix }
);
this.span(B);
}
/**
* Adds a node close to the output stream (if needed)
*
* @param {Node} node */
closeNode(I) {
i(I) && (this.buffer += a);
}
/**
* returns the accumulated buffer
*/
value() {
return this.buffer;
}
// helpers
/**
* Builds a span element
*
* @param {string} className */
span(I) {
this.buffer += `<span class="${I}">`;
}
}
const l = (M = {}) => {
const I = { children: [] };
return Object.assign(I, M), I;
};
class u {
constructor() {
this.rootNode = l(), this.stack = [this.rootNode];
}
get top() {
return this.stack[this.stack.length - 1];
}
get root() {
return this.rootNode;
}
/** @param {Node} node */
add(I) {
this.top.children.push(I);
}
/** @param {string} scope */
openNode(I) {
const B = l({ scope: I });
this.add(B), this.stack.push(B);
}
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(I) {
return this.constructor._walk(I, this.rootNode);
}
/**
* @param {Renderer} builder
* @param {Node} node
*/
static _walk(I, B) {
return typeof B == "string" ? I.addText(B) : B.children && (I.openNode(B), B.children.forEach((Z) => this._walk(I, Z)), I.closeNode(B)), I;
}
/**
* @param {Node} node
*/
static _collapse(I) {
typeof I != "string" && I.children && (I.children.every((B) => typeof B == "string") ? I.children = [I.children.join("")] : I.children.forEach((B) => {
u._collapse(B);
}));
}
}
class h extends u {
/**
* @param {*} options
*/
constructor(I) {
super(), this.options = I;
}
/**
* @param {string} text
*/
addText(I) {
I !== "" && this.add(I);
}
/** @param {string} scope */
startScope(I) {
this.openNode(I);
}
endScope() {
this.closeNode();
}
/**
* @param {Emitter & {root: DataNode}} emitter
* @param {string} name
*/
__addSublanguage(I, B) {
const Z = I.root;
B && (Z.scope = `language:${B}`), this.add(Z);
}
toHTML() {
return new c(this, this.options).value();
}
finalize() {
return this.closeAllNodes(), !0;
}
}
function f(M) {
return M ? typeof M == "string" ? M : M.source : null;
}
function m(M) {
return N("(?=", M, ")");
}
function g(M) {
return N("(?:", M, ")*");
}
function b(M) {
return N("(?:", M, ")?");
}
function N(...M) {
return M.map((B) => f(B)).join("");
}
function x(M) {
const I = M[M.length - 1];
return typeof I == "object" && I.constructor === Object ? (M.splice(M.length - 1, 1), I) : {};
}
function A(...M) {
return "(" + (x(M).capture ? "" : "?:") + M.map((Z) => f(Z)).join("|") + ")";
}
function w(M) {
return new RegExp(M.toString() + "|").exec("").length - 1;
}
function y(M, I) {
const B = M && M.exec(I);
return B && B.index === 0;
}
const C = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
function T(M, { joinWith: I }) {
let B = 0;
return M.map((Z) => {
B += 1;
const ue = B;
let ae = f(Z), U = "";
for (; ae.length > 0; ) {
const G = C.exec(ae);
if (!G) {
U += ae;
break;
}
U += ae.substring(0, G.index), ae = ae.substring(G.index + G[0].length), G[0][0] === "\\" && G[1] ? U += "\\" + String(Number(G[1]) + ue) : (U += G[0], G[0] === "(" && B++);
}
return U;
}).map((Z) => `(${Z})`).join(I);
}
const p = /\b\B/, v = "[a-zA-Z]\\w*", k = "[a-zA-Z_]\\w*", S = "\\b\\d+(\\.\\d+)?", $ = "(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)", D = "\\b(0b[01]+)", F = "!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", K = (M = {}) => {
const I = /^#![ ]*\//;
return M.binary && (M.begin = N(
I,
/.*\b/,
M.binary,
/\b.*/
)), s({
scope: "meta",
begin: I,
end: /$/,
relevance: 0,
/** @type {ModeCallback} */
"on:begin": (B, Z) => {
B.index !== 0 && Z.ignoreMatch();
}
}, M);
}, P = {
begin: "\\\\[\\s\\S]",
relevance: 0
}, te = {
scope: "string",
begin: "'",
end: "'",
illegal: "\\n",
contains: [P]
}, _ = {
scope: "string",
begin: '"',
end: '"',
illegal: "\\n",
contains: [P]
}, O = {
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/
}, ie = function(M, I, B = {}) {
const Z = s(
{
scope: "comment",
begin: M,
end: I,
contains: []
},
B
);
Z.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 ue = A(
// 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 Z.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: N(
/[ ]+/,
// necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */
"(",
ue,
/[.]?[:]?([.][ ]|[ ])/,
"){3}"
)
// look for 3 words in a row
}
), Z;
}, X = ie("//", "$"), ce = ie("/\\*", "\\*/"), Q = ie("#", "$"), Se = {
scope: "number",
begin: S,
relevance: 0
}, L = {
scope: "number",
begin: $,
relevance: 0
}, pe = {
scope: "number",
begin: D,
relevance: 0
}, z = {
scope: "regexp",
begin: /\/(?=[^/\n]*\/)/,
end: /\/[gimuy]*/,
contains: [
P,
{
begin: /\[/,
end: /\]/,
relevance: 0,
contains: [P]
}
]
}, H = {
scope: "title",
begin: v,
relevance: 0
}, se = {
scope: "title",
begin: k,
relevance: 0
}, me = {
// excludes method names from keyword processing
begin: "\\.\\s*" + k,
relevance: 0
};
var we = /* @__PURE__ */ Object.freeze({
__proto__: null,
APOS_STRING_MODE: te,
BACKSLASH_ESCAPE: P,
BINARY_NUMBER_MODE: pe,
BINARY_NUMBER_RE: D,
COMMENT: ie,
C_BLOCK_COMMENT_MODE: ce,
C_LINE_COMMENT_MODE: X,
C_NUMBER_MODE: L,
C_NUMBER_RE: $,
END_SAME_AS_BEGIN: function(M) {
return Object.assign(
M,
{
/** @type {ModeCallback} */
"on:begin": (I, B) => {
B.data._beginMatch = I[1];
},
/** @type {ModeCallback} */
"on:end": (I, B) => {
B.data._beginMatch !== I[1] && B.ignoreMatch();
}
}
);
},
HASH_COMMENT_MODE: Q,
IDENT_RE: v,
MATCH_NOTHING_RE: p,
METHOD_GUARD: me,
NUMBER_MODE: Se,
NUMBER_RE: S,
PHRASAL_WORDS_MODE: O,
QUOTE_STRING_MODE: _,
REGEXP_MODE: z,
RE_STARTERS_RE: F,
SHEBANG: K,
TITLE_MODE: H,
UNDERSCORE_IDENT_RE: k,
UNDERSCORE_TITLE_MODE: se
});
function Y(M, I) {
M.input[M.index - 1] === "." && I.ignoreMatch();
}
function Pe(M, I) {
M.className !== void 0 && (M.scope = M.className, delete M.className);
}
function He(M, I) {
I && M.beginKeywords && (M.begin = "\\b(" + M.beginKeywords.split(" ").join("|") + ")(?!\\.)(?=\\b|\\s)", M.__beforeBegin = Y, M.keywords = M.keywords || M.beginKeywords, delete M.beginKeywords, M.relevance === void 0 && (M.relevance = 0));
}
function Ne(M, I) {
Array.isArray(M.illegal) && (M.illegal = A(...M.illegal));
}
function _e(M, I) {
if (M.match) {
if (M.begin || M.end) throw new Error("begin & end are not supported with match");
M.begin = M.match, delete M.match;
}
}
function We(M, I) {
M.relevance === void 0 && (M.relevance = 1);
}
const Je = (M, I) => {
if (!M.beforeMatch) return;
if (M.starts) throw new Error("beforeMatch cannot be used with starts");
const B = Object.assign({}, M);
Object.keys(M).forEach((Z) => {
delete M[Z];
}), M.keywords = B.keywords, M.begin = N(B.beforeMatch, m(B.begin)), M.starts = {
relevance: 0,
contains: [
Object.assign(B, { endsParent: !0 })
]
}, M.relevance = 0, delete B.beforeMatch;
}, Ke = [
"of",
"and",
"for",
"in",
"not",
"or",
"if",
"then",
"parent",
// common variable name
"list",
// common variable name
"value"
// common variable name
], Oe = "keyword";
function Xe(M, I, B = Oe) {
const Z = /* @__PURE__ */ Object.create(null);
return typeof M == "string" ? ue(B, M.split(" ")) : Array.isArray(M) ? ue(B, M) : Object.keys(M).forEach(function(ae) {
Object.assign(
Z,
Xe(M[ae], I, ae)
);
}), Z;
function ue(ae, U) {
I && (U = U.map((G) => G.toLowerCase())), U.forEach(function(G) {
const oe = G.split("|");
Z[oe[0]] = [ae, Qe(oe[0], oe[1])];
});
}
}
function Qe(M, I) {
return I ? Number(I) : J(M) ? 0 : 1;
}
function J(M) {
return Ke.includes(M.toLowerCase());
}
const fe = {}, ve = (M) => {
console.error(M);
}, ke = (M, ...I) => {
console.log(`WARN: ${M}`, ...I);
}, Fe = (M, I) => {
fe[`${M}/${I}`] || (console.log(`Deprecated as of ${M}. ${I}`), fe[`${M}/${I}`] = !0);
}, re = new Error();
function be(M, I, { key: B }) {
let Z = 0;
const ue = M[B], ae = {}, U = {};
for (let G = 1; G <= I.length; G++)
U[G + Z] = ue[G], ae[G + Z] = !0, Z += w(I[G - 1]);
M[B] = U, M[B]._emit = ae, M[B]._multi = !0;
}
function Ee(M) {
if (Array.isArray(M.begin)) {
if (M.skip || M.excludeBegin || M.returnBegin)
throw ve("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), re;
if (typeof M.beginScope != "object" || M.beginScope === null)
throw ve("beginScope must be object"), re;
be(M, M.begin, { key: "beginScope" }), M.begin = T(M.begin, { joinWith: "" });
}
}
function qe(M) {
if (Array.isArray(M.end)) {
if (M.skip || M.excludeEnd || M.returnEnd)
throw ve("skip, excludeEnd, returnEnd not compatible with endScope: {}"), re;
if (typeof M.endScope != "object" || M.endScope === null)
throw ve("endScope must be object"), re;
be(M, M.end, { key: "endScope" }), M.end = T(M.end, { joinWith: "" });
}
}
function Ze(M) {
M.scope && typeof M.scope == "object" && M.scope !== null && (M.beginScope = M.scope, delete M.scope);
}
function xt(M) {
Ze(M), typeof M.beginScope == "string" && (M.beginScope = { _wrap: M.beginScope }), typeof M.endScope == "string" && (M.endScope = { _wrap: M.endScope }), Ee(M), qe(M);
}
function vt(M) {
function I(U, G) {
return new RegExp(
f(U),
"m" + (M.case_insensitive ? "i" : "") + (M.unicodeRegex ? "u" : "") + (G ? "g" : "")
);
}
class B {
constructor() {
this.matchIndexes = {}, this.regexes = [], this.matchAt = 1, this.position = 0;
}
// @ts-ignore
addRule(G, oe) {
oe.position = this.position++, this.matchIndexes[this.matchAt] = oe, this.regexes.push([oe, G]), this.matchAt += w(G) + 1;
}
compile() {
this.regexes.length === 0 && (this.exec = () => null);
const G = this.regexes.map((oe) => oe[1]);
this.matcherRe = I(T(G, { joinWith: "|" }), !0), this.lastIndex = 0;
}
/** @param {string} s */
exec(G) {
this.matcherRe.lastIndex = this.lastIndex;
const oe = this.matcherRe.exec(G);
if (!oe)
return null;
const Ae = oe.findIndex(($e, et) => et > 0 && $e !== void 0), De = this.matchIndexes[Ae];
return oe.splice(0, Ae), Object.assign(oe, De);
}
}
class Z {
constructor() {
this.rules = [], this.multiRegexes = [], this.count = 0, this.lastIndex = 0, this.regexIndex = 0;
}
// @ts-ignore
getMatcher(G) {
if (this.multiRegexes[G]) return this.multiRegexes[G];
const oe = new B();
return this.rules.slice(G).forEach(([Ae, De]) => oe.addRule(Ae, De)), oe.compile(), this.multiRegexes[G] = oe, oe;
}
resumingScanAtSamePosition() {
return this.regexIndex !== 0;
}
considerAll() {
this.regexIndex = 0;
}
// @ts-ignore
addRule(G, oe) {
this.rules.push([G, oe]), oe.type === "begin" && this.count++;
}
/** @param {string} s */
exec(G) {
const oe = this.getMatcher(this.regexIndex);
oe.lastIndex = this.lastIndex;
let Ae = oe.exec(G);
if (this.resumingScanAtSamePosition() && !(Ae && Ae.index === this.lastIndex)) {
const De = this.getMatcher(0);
De.lastIndex = this.lastIndex + 1, Ae = De.exec(G);
}
return Ae && (this.regexIndex += Ae.position + 1, this.regexIndex === this.count && this.considerAll()), Ae;
}
}
function ue(U) {
const G = new Z();
return U.contains.forEach((oe) => G.addRule(oe.begin, { rule: oe, type: "begin" })), U.terminatorEnd && G.addRule(U.terminatorEnd, { type: "end" }), U.illegal && G.addRule(U.illegal, { type: "illegal" }), G;
}
function ae(U, G) {
const oe = (
/** @type CompiledMode */
U
);
if (U.isCompiled) return oe;
[
Pe,
// do this early so compiler extensions generally don't have to worry about
// the distinction between match/begin
_e,
xt,
Je
].forEach((De) => De(U, G)), M.compilerExtensions.forEach((De) => De(U, G)), U.__beforeBegin = null, [
He,
// do this later so compiler extensions that come earlier have access to the
// raw array if they wanted to perhaps manipulate it, etc.
Ne,
// default to 1 relevance if not specified
We
].forEach((De) => De(U, G)), U.isCompiled = !0;
let Ae = null;
return typeof U.keywords == "object" && U.keywords.$pattern && (U.keywords = Object.assign({}, U.keywords), Ae = U.keywords.$pattern, delete U.keywords.$pattern), Ae = Ae || /\w+/, U.keywords && (U.keywords = Xe(U.keywords, M.case_insensitive)), oe.keywordPatternRe = I(Ae, !0), G && (U.begin || (U.begin = /\B|\b/), oe.beginRe = I(oe.begin), !U.end && !U.endsWithParent && (U.end = /\B|\b/), U.end && (oe.endRe = I(oe.end)), oe.terminatorEnd = f(oe.end) || "", U.endsWithParent && G.terminatorEnd && (oe.terminatorEnd += (U.end ? "|" : "") + G.terminatorEnd)), U.illegal && (oe.illegalRe = I(
/** @type {RegExp | string} */
U.illegal
)), U.contains || (U.contains = []), U.contains = [].concat(...U.contains.map(function(De) {
return wt(De === "self" ? U : De);
})), U.contains.forEach(function(De) {
ae(
/** @type Mode */
De,
oe
);
}), U.starts && ae(U.starts, G), oe.matcher = ue(oe), oe;
}
if (M.compilerExtensions || (M.compilerExtensions = []), M.contains && M.contains.includes("self"))
throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");
return M.classNameAliases = s(M.classNameAliases || {}), ae(
/** @type Mode */
M
);
}
function gt(M) {
return M ? M.endsWithParent || gt(M.starts) : !1;
}
function wt(M) {
return M.variants && !M.cachedVariants && (M.cachedVariants = M.variants.map(function(I) {
return s(M, { variants: null }, I);
})), M.cachedVariants ? M.cachedVariants : gt(M) ? s(M, { starts: M.starts ? s(M.starts) : null }) : Object.isFrozen(M) ? s(M) : M;
}
var Tt = "11.11.1";
class kt extends Error {
constructor(I, B) {
super(I), this.name = "HTMLInjectionError", this.html = B;
}
}
const ct = n, ut = s, Ye = /* @__PURE__ */ Symbol("nomatch"), st = 7, Nt = function(M) {
const I = /* @__PURE__ */ Object.create(null), B = /* @__PURE__ */ Object.create(null), Z = [];
let ue = !0;
const ae = "Could not find the language '{}', did you forget to load/include a language module?", U = { disableAutodetect: !0, name: "Plain text", contains: [] };
let G = {
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 oe(j) {
return G.noHighlightRe.test(j);
}
function Ae(j) {
let ne = j.className + " ";
ne += j.parentNode ? j.parentNode.className : "";
const ye = G.languageDetectRe.exec(ne);
if (ye) {
const Re = ft(ye[1]);
return Re || (ke(ae.replace("{}", ye[1])), ke("Falling back to no-highlight mode for this block.", j)), Re ? ye[1] : "no-highlight";
}
return ne.split(/\s+/).find((Re) => oe(Re) || ft(Re));
}
function De(j, ne, ye) {
let Re = "", je = "";
typeof ne == "object" ? (Re = j, ye = ne.ignoreIllegals, je = ne.language) : (Fe("10.7.0", "highlight(lang, code, ...args) has been deprecated."), Fe("10.7.0", `Please use highlight(code, options) instead.
https://github.com/highlightjs/highlight.js/issues/2277`), je = j, Re = ne), ye === void 0 && (ye = !0);
const mt = {
code: Re,
language: je
};
Kt("before:highlight", mt);
const Mt = mt.result ? mt.result : $e(mt.language, mt.code, ye);
return Mt.code = mt.code, Kt("after:highlight", Mt), Mt;
}
function $e(j, ne, ye, Re) {
const je = /* @__PURE__ */ Object.create(null);
function mt(de, xe) {
return de.keywords[xe];
}
function Mt() {
if (!Te.keywords) {
rt.addText(Be);
return;
}
let de = 0;
Te.keywordPatternRe.lastIndex = 0;
let xe = Te.keywordPatternRe.exec(Be), Ie = "";
for (; xe; ) {
Ie += Be.substring(de, xe.index);
const Le = Et.case_insensitive ? xe[0].toLowerCase() : xe[0], it = mt(Te, Le);
if (it) {
const [_t, Za] = it;
if (rt.addText(Ie), Ie = "", je[Le] = (je[Le] || 0) + 1, je[Le] <= st && (fn += Za), _t.startsWith("_"))
Ie += xe[0];
else {
const ei = Et.classNameAliases[_t] || _t;
It(xe[0], ei);
}
} else
Ie += xe[0];
de = Te.keywordPatternRe.lastIndex, xe = Te.keywordPatternRe.exec(Be);
}
Ie += Be.substring(de), rt.addText(Ie);
}
function dn() {
if (Be === "") return;
let de = null;
if (typeof Te.subLanguage == "string") {
if (!I[Te.subLanguage]) {
rt.addText(Be);
return;
}
de = $e(Te.subLanguage, Be, !0, Jr[Te.subLanguage]), Jr[Te.subLanguage] = /** @type {CompiledMode} */
de._top;
} else
de = tt(Be, Te.subLanguage.length ? Te.subLanguage : null);
Te.relevance > 0 && (fn += de.relevance), rt.__addSublanguage(de._emitter, de.language);
}
function ht() {
Te.subLanguage != null ? dn() : Mt(), Be = "";
}
function It(de, xe) {
de !== "" && (rt.startScope(xe), rt.addText(de), rt.endScope());
}
function zr(de, xe) {
let Ie = 1;
const Le = xe.length - 1;
for (; Ie <= Le; ) {
if (!de._emit[Ie]) {
Ie++;
continue;
}
const it = Et.classNameAliases[de[Ie]] || de[Ie], _t = xe[Ie];
it ? It(_t, it) : (Be = _t, Mt(), Be = ""), Ie++;
}
}
function Gr(de, xe) {
return de.scope && typeof de.scope == "string" && rt.openNode(Et.classNameAliases[de.scope] || de.scope), de.beginScope && (de.beginScope._wrap ? (It(Be, Et.classNameAliases[de.beginScope._wrap] || de.beginScope._wrap), Be = "") : de.beginScope._multi && (zr(de.beginScope, xe), Be = "")), Te = Object.create(de, { parent: { value: Te } }), Te;
}
function Wr(de, xe, Ie) {
let Le = y(de.endRe, Ie);
if (Le) {
if (de["on:end"]) {
const it = new t(de);
de["on:end"](xe, it), it.isMatchIgnored && (Le = !1);
}
if (Le) {
for (; de.endsParent && de.parent; )
de = de.parent;
return de;
}
}
if (de.endsWithParent)
return Wr(de.parent, xe, Ie);
}
function Ga(de) {
return Te.matcher.regexIndex === 0 ? (Be += de[0], 1) : (zn = !0, 0);
}
function Wa(de) {
const xe = de[0], Ie = de.rule, Le = new t(Ie), it = [Ie.__beforeBegin, Ie["on:begin"]];
for (const _t of it)
if (_t && (_t(de, Le), Le.isMatchIgnored))
return Ga(xe);
return Ie.skip ? Be += xe : (Ie.excludeBegin && (Be += xe), ht(), !Ie.returnBegin && !Ie.excludeBegin && (Be = xe)), Gr(Ie, de), Ie.returnBegin ? 0 : xe.length;
}
function Ya(de) {
const xe = de[0], Ie = ne.substring(de.index), Le = Wr(Te, de, Ie);
if (!Le)
return Ye;
const it = Te;
Te.endScope && Te.endScope._wrap ? (ht(), It(xe, Te.endScope._wrap)) : Te.endScope && Te.endScope._multi ? (ht(), zr(Te.endScope, de)) : it.skip ? Be += xe : (it.returnEnd || it.excludeEnd || (Be += xe), ht(), it.excludeEnd && (Be = xe));
do
Te.scope && rt.closeNode(), !Te.skip && !Te.subLanguage && (fn += Te.relevance), Te = Te.parent;
while (Te !== Le.parent);
return Le.starts && Gr(Le.starts, de), it.returnEnd ? 0 : xe.length;
}
function Ja() {
const de = [];
for (let xe = Te; xe !== Et; xe = xe.parent)
xe.scope && de.unshift(xe.scope);
de.forEach((xe) => rt.openNode(xe));
}
let un = {};
function Yr(de, xe) {
const Ie = xe && xe[0];
if (Be += de, Ie == null)
return ht(), 0;
if (un.type === "begin" && xe.type === "end" && un.index === xe.index && Ie === "") {
if (Be += ne.slice(xe.index, xe.index + 1), !ue) {
const Le = new Error(`0 width match regex (${j})`);
throw Le.languageName = j, Le.badRule = un.rule, Le;
}
return 1;
}
if (un = xe, xe.type === "begin")
return Wa(xe);
if (xe.type === "illegal" && !ye) {
const Le = new Error('Illegal lexeme "' + Ie + '" for mode "' + (Te.scope || "<unnamed>") + '"');
throw Le.mode = Te, Le;
} else if (xe.type === "end") {
const Le = Ya(xe);
if (Le !== Ye)
return Le;
}
if (xe.type === "illegal" && Ie === "")
return Be += `
`, 1;
if (Hn > 1e5 && Hn > xe.index * 3)
throw new Error("potential infinite loop, way more iterations than matches");
return Be += Ie, Ie.length;
}
const Et = ft(j);
if (!Et)
throw ve(ae.replace("{}", j)), new Error('Unknown language: "' + j + '"');
const Xa = vt(Et);
let Un = "", Te = Re || Xa;
const Jr = {}, rt = new G.__emitter(G);
Ja();
let Be = "", fn = 0, qt = 0, Hn = 0, zn = !1;
try {
if (Et.__emitTokens)
Et.__emitTokens(ne, rt);
else {
for (Te.matcher.considerAll(); ; ) {
Hn++, zn ? zn = !1 : Te.matcher.considerAll(), Te.matcher.lastIndex = qt;
const de = Te.matcher.exec(ne);
if (!de) break;
const xe = ne.substring(qt, de.index), Ie = Yr(xe, de);
qt = de.index + Ie;
}
Yr(ne.substring(qt));
}
return rt.finalize(), Un = rt.toHTML(), {
language: j,
value: Un,
relevance: fn,
illegal: !1,
_emitter: rt,
_top: Te
};
} catch (de) {
if (de.message && de.message.includes("Illegal"))
return {
language: j,
value: ct(ne),
illegal: !0,
relevance: 0,
_illegalBy: {
message: de.message,
index: qt,
context: ne.slice(qt - 100, qt + 100),
mode: de.mode,
resultSoFar: Un
},
_emitter: rt
};
if (ue)
return {
language: j,
value: ct(ne),
illegal: !1,
relevance: 0,
errorRaised: de,
_emitter: rt,
_top: Te
};
throw de;
}
}
function et(j) {
const ne = {
value: ct(j),
illegal: !1,
relevance: 0,
_top: U,
_emitter: new G.__emitter(G)
};
return ne._emitter.addText(j), ne;
}
function tt(j, ne) {
ne = ne || G.languages || Object.keys(I);
const ye = et(j), Re = ne.filter(ft).filter(cn).map(
(ht) => $e(ht, j, !1)
);
Re.unshift(ye);
const je = Re.sort((ht, It) => {
if (ht.relevance !== It.relevance) return It.relevance - ht.relevance;
if (ht.language && It.language) {
if (ft(ht.language).supersetOf === It.language)
return 1;
if (ft(It.language).supersetOf === ht.language)
return -1;
}
return 0;
}), [mt, Mt] = je, dn = mt;
return dn.secondBest = Mt, dn;
}
function at(j, ne, ye) {
const Re = ne && B[ne] || ye;
j.classList.add("hljs"), j.classList.add(`language-${Re}`);
}
function Ct(j) {
let ne = null;
const ye = Ae(j);
if (oe(ye)) return;
if (Kt(
"before:highlightElement",
{ el: j, language: ye }
), j.dataset.highlighted) {
console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.", j);
return;
}
if (j.children.length > 0 && (G.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)), G.throwUnescapedHTML))
throw new kt(
"One of your code blocks includes unescaped HTML.",
j.innerHTML
);
ne = j;
const Re = ne.textContent, je = ye ? De(Re, { language: ye, ignoreIllegals: !0 }) : tt(Re);
j.innerHTML = je.value, j.dataset.highlighted = "yes", at(j, ye, je.language), j.result = {
language: je.language,
// TODO: remove with version 11.0
re: je.relevance,
relevance: je.relevance
}, je.secondBest && (j.secondBest = {
language: je.secondBest.language,
relevance: je.secondBest.relevance
}), Kt("after:highlightElement", { el: j, result: je, text: Re });
}
function Rt(j) {
G = ut(G, j);
}
const yt = () => {
nt(), Fe("10.6.0", "initHighlighting() deprecated. Use highlightAll() now.");
};
function R() {
nt(), Fe("10.6.0", "initHighlightingOnLoad() deprecated. Use highlightAll() now.");
}
let Ue = !1;
function nt() {
function j() {
nt();
}
if (document.readyState === "loading") {
Ue || window.addEventListener("DOMContentLoaded", j, !1), Ue = !0;
return;
}
document.querySelectorAll(G.cssSelector).forEach(Ct);
}
function $t(j, ne) {
let ye = null;
try {
ye = ne(M);
} catch (Re) {
if (ve("Language definition for '{}' could not be registered.".replace("{}", j)), ue)
ve(Re);
else
throw Re;
ye = U;
}
ye.name || (ye.name = j), I[j] = ye, ye.rawDefinition = ne.bind(null, M), ye.aliases && Gt(ye.aliases, { languageName: j });
}
function Lt(j) {
delete I[j];
for (const ne of Object.keys(B))
B[ne] === j && delete B[ne];
}
function At() {
return Object.keys(I);
}
function ft(j) {
return j = (j || "").toLowerCase(), I[j] || I[B[j]];
}
function Gt(j, { languageName: ne }) {
typeof j == "string" && (j = [j]), j.forEach((ye) => {
B[ye.toLowerCase()] = ne;
});
}
function cn(j) {
const ne = ft(j);
return ne && !ne.disableAutodetect;
}
function Wt(j) {
j["before:highlightBlock"] && !j["before:highlightElement"] && (j["before:highlightElement"] = (ne) => {
j["before:highlightBlock"](
Object.assign({ block: ne.el }, ne)
);
}), j["after:highlightBlock"] && !j["after:highlightElement"] && (j["after:highlightElement"] = (ne) => {
j["after:highlightBlock"](
Object.assign({ block: ne.el }, ne)
);
});
}
function Vn(j) {
Wt(j), Z.push(j);
}
function Pt(j) {
const ne = Z.indexOf(j);
ne !== -1 && Z.splice(ne, 1);
}
function Kt(j, ne) {
const ye = j;
Z.forEach(function(Re) {
Re[ye] && Re[ye](ne);
});
}
function Me(j) {
return Fe("10.7.0", "highlightBlock will be removed entirely in v12.0"), Fe("10.7.0", "Please use highlightElement now."), Ct(j);
}
Object.assign(M, {
highlight: De,
highlightAuto: tt,
highlightAll: nt,
highlightElement: Ct,
// TODO: Remove with v12 API
highlightBlock: Me,
configure: Rt,
initHighlighting: yt,
initHighlightingOnLoad: R,
registerLanguage: $t,
unregisterLanguage: Lt,
listLanguages: At,
getLanguage: ft,
registerAliases: Gt,
autoDetection: cn,
inherit: ut,
addPlugin: Vn,
removePlugin: Pt
}), M.debugMode = function() {
ue = !1;
}, M.safeMode = function() {
ue = !0;
}, M.versionString = Tt, M.regex = {
concat: N,
lookahead: m,
either: A,
optional: b,
anyNumberOfTimes: g
};
for (const j in we)
typeof we[j] == "object" && e(we[j]);
return Object.assign(M, we), M;
}, ze = Nt({});
return ze.newInstance = () => Nt({}), er = ze, ze.HighlightJS = ze, ze.default = ze, er;
}
var fc = /* @__PURE__ */ uc();
const Br = /* @__PURE__ */ Ul(fc);
function La(e) {
const t = {
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: [
t,
n,
e.QUOTE_STRING_MODE,
a,
e.C_NUMBER_MODE,
e.C_LINE_COMMENT_MODE,
e.C_BLOCK_COMMENT_MODE
],
illegal: "\\S"
};
}
const mc = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
default: La
}, Symbol.toStringTag, { value: "Module" }));
function Pa(e) {
const t = e.regex, n = e.COMMENT("--", "$"), s = {
scope: "string",
variants: [
{
begin: /'/,
end: /'/,
contains: [{ match: /''/ }]
}
]
}, a = {
begin: /"/,
end: /"/,
contains: [{ match: /""/ }]
}, i = [
"true",
"false",
// Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way.
// "null",
"unknown"
], o = [
"double precision",
"large object",
"with timezone",
"without timezone"
], c = [
"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"
], l = [
"add",
"asc",
"collation",
"desc",
"final",
"first",
"last",
"view"
], u = [
"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"
], f = [
"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"
], g = h, b = [
...u,
...l
].filter((T) => !h.includes(T)), N = {
scope: "variable",
match: /@[a-z0-9][a-z0-9_]*/
}, x = {
scope: "operator",
match: /[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,
relevance: 0
}, A = {
match: t.concat(/\b/, t.either(...g), /\s*\(/),
relevance: 0,
keywords: { built_in: g }
};
function w(T) {
return t.concat(
/\b/,
t.either(...T.map((p) => p.replace(/\s+/, "\\s+"))),
/\b/
);
}
const y = {
scope: "keyword",
match: w(m),
relevance: 0
};
function C(T, {
exceptions: p,
when: v
} = {}) {
const k = v;
return p = p || [], T.map((S) => S.match(/\|\d+$/) || p.includes(S) ? S : k(S) ? `${S}|0` : S);
}
return {
name: "SQL",
case_insensitive: !0,
// does not include {} or HTML tags `</`
illegal: /[{}]|<\//,
keywords: {
$pattern: /\b[\w\.]+/,
keyword: C(b, { when: (T) => T.length < 3 }),
literal: i,
type: c,
built_in: f
},
contains: [
{
scope: "type",
match: w(o)
},
y,
A,
N,
s,
a,
e.C_NUMBER_MODE,
e.C_BLOCK_COMMENT_MODE,
n,
x
]
};
}
const hc = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
default: Pa
}, Symbol.toStringTag, { value: "Module" }));
Br.registerLanguage("json", La);
Br.registerLanguage("sql", Pa);
const ot = ({
code: e,
language: t,
title: n,
maxHeight: s = "16rem",
height: a,
className: i = "",
headerRight: o
}) => {
const [c, l] = ee(!1), u = ge(null), h = q("copy"), f = q("check");
he(() => {
u.current && e && (u.current.innerHTML = Br.highlight(e, { language: t }).value);
}, [e, t]);
const m = async () => {
try {
await navigator.clipboard.writeText(e), l(!0), setTimeout(() => l(!1), 2e3);
} catch {
const g = document.createElement("textarea");
g.value = e, g.style.position = "fixed", g.style.left = "-999999px", document.body.appendChild(g), g.select(), document.execCommand("copy"), document.body.removeChild(g), l(!0), setTimeout(() => l(!1), 2e3);
}
};
return /* @__PURE__ */ d("div", { className: `relative ${i}`, children: [
/* @__PURE__ */ d("div", { className: "flex items-center justify-between mb-2 gap-2", children: [
n && /* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text", children: n }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 ml-auto", children: [
o,
/* @__PURE__ */ r(
"button",
{
onClick: m,
className: "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: c ? "Copied!" : "Copy to clipboard",
children: c ? /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(f, { className: "w-3.5 h-3.5 text-dc-success" }),
/* @__PURE__ */ r("span", { className: "text-dc-success", children: "Copied" })
] }) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(h, { className: "w-3.5 h-3.5 text-dc-text-secondary" }),
/* @__PURE__ */ r("span", { className: "text-dc-text-secondary", children: "Copy" })
] })
}
)
] })
] }),
/* @__PURE__ */ r(
"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__ */ r("pre", { className: "p-3 text-xs m-0", children: /* @__PURE__ */ r(
"code",
{
ref: u,
className: `hljs language-${t}`,
children: e
}
) })
}
)
] });
}, qa = ({
isOpen: e,
onClose: t,
onConfirm: n,
title: s = "Confirm",
message: a,
confirmText: i = "Confirm",
cancelText: o = "Cancel",
confirmVariant: c = "primary",
isLoading: l = !1
}) => /* @__PURE__ */ r(
Rr,
{
isOpen: e,
onClose: t,
title: s,
size: "sm",
closeOnBackdropClick: !l,
closeOnEscape: !l,
footer: /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: t,
disabled: 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 transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-dc-primary disabled:opacity-50 disabled:cursor-not-allowed",
children: o
}
),
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: async () => {
await n(), t();
},
disabled: l,
className: (() => {
const f = "px-4 py-2 text-sm font-medium rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed";
switch (c) {
case "danger":
return `${f} bg-dc-danger text-white hover:bg-dc-danger/90 focus:ring-dc-danger`;
case "warning":
return `${f} bg-dc-warning text-white hover:bg-dc-warning/90 focus:ring-dc-warning`;
default:
return `${f} bg-dc-primary text-white hover:bg-dc-primary/90 focus:ring-dc-primary`;
}
})(),
children: l ? /* @__PURE__ */ d("span", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ d("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
/* @__PURE__ */ r("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
/* @__PURE__ */ r("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" })
] }),
"Processing..."
] }) : i
}
)
] }),
children: /* @__PURE__ */ r("div", { className: "text-dc-text-secondary", children: a })
}
), pc = q("chevronDown");
function Ba({
currentPalette: e = "default",
onPaletteChange: t,
className: n = ""
}) {
const [s, a] = ee(!1), i = ge(null), o = Fr(e);
he(() => {
function l(u) {
i.current && !i.current.contains(u.target) && a(!1);
}
if (s)
return document.addEventListener("mousedown", l), () => document.removeEventListener("mousedown", l);
}, [s]);
const c = (l) => {
t(l), a(!1);
};
return /* @__PURE__ */ d("div", { className: `relative ${n}`, ref: i, children: [
/* @__PURE__ */ d(
"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__ */ d("div", { className: "hidden md:flex items-center gap-1.5", children: [
/* @__PURE__ */ r("div", { className: "flex gap-0.5", children: o.colors.slice(0, 4).map((l, u) => /* @__PURE__ */ r(
"div",
{
className: "w-3 h-3 rounded-xs border border-dc-border",
style: { backgroundColor: l },
title: `Series Color ${u + 1}`
},
u
)) }),
/* @__PURE__ */ r("span", { className: "text-xs text-dc-text-secondary", children: "|" }),
/* @__PURE__ */ r("div", { className: "flex gap-0.5", children: o.gradient.slice(0, 3).map((l, u) => /* @__PURE__ */ r(
"div",
{
className: "w-2 h-3 border-r first:rounded-l-sm last:rounded-r-sm last:border-r-0",
style: {
backgroundColor: l,
borderColor: "var(--dc-border)"
},
title: `Gradient Color ${u + 1}`
},
u
)) })
] }),
/* @__PURE__ */ r("span", { children: o.label }),
/* @__PURE__ */ r(
pc,
{
className: `w-4 h-4 transition-transform ${s ? "rotate-180" : ""}`
}
)
]
}
),
s && /* @__PURE__ */ r("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__ */ r("div", { className: "py-1", children: tn.slice().sort((l, u) => l.label.localeCompare(u.label)).map((l) => /* @__PURE__ */ r(
"button",
{
type: "button",
onClick: () => c(l.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 ${l.name === e ? "bg-dc-surface-secondary" : "text-dc-text-secondary"}`,
style: l.name === e ? { color: "var(--dc-primary)" } : void 0,
children: /* @__PURE__ */ d("div", { className: "flex items-center gap-3", children: [
/* @__PURE__ */ d("div", { className: "hidden md:flex items-center gap-2", children: [
/* @__PURE__ */ r("div", { className: "flex gap-0.5", children: l.colors.slice(0, 6).map((u, h) => /* @__PURE__ */ r(
"div",
{
className: "w-3 h-3 rounded-xs border border-dc-border",
style: { backgroundColor: u }
},
`series-${h}`
)) }),
/* @__PURE__ */ r("div", { className: "w-px h-4 bg-dc-border" }),
/* @__PURE__ */ r("div", { className: "flex", children: l.gradient.map((u, h) => /* @__PURE__ */ r(
"div",
{
className: "w-2 h-4 first:rounded-l-sm last:rounded-r-sm",
style: { backgroundColor: u }
},
`gradient-${h}`
)) })
] }),
/* @__PURE__ */ r("span", { className: "font-medium", children: l.label }),
l.name === e && /* @__PURE__ */ r("div", { className: "ml-auto", children: /* @__PURE__ */ r("div", { className: "w-2 h-2 rounded-full", style: { backgroundColor: "var(--dc-primary)" } }) })
] })
},
l.name
)) }) })
] });
}
function Bt(e) {
return typeof e == "string" ? e : typeof e == "object" && e !== null ? JSON.stringify(e) : String(e ?? "");
}
const gc = {
good: "bg-dc-success-bg text-dc-success border-dc-success",
warning: "bg-dc-warning-bg text-dc-warning border-dc-warning",
critical: "bg-dc-danger-bg text-dc-error border-dc-error"
}, yc = {
critical: "bg-dc-danger-bg text-dc-error",
warning: "bg-dc-warning-bg text-dc-warning",
suggestion: "bg-dc-accent-bg text-dc-accent"
}, bc = {
high: "text-dc-error",
medium: "text-dc-warning",
low: "text-dc-text-muted"
};
function xc({ assessment: e, reason: t }) {
const n = {
good: "Good",
warning: "Warning",
critical: "Critical"
};
return /* @__PURE__ */ d("div", { className: `p-4 rounded-lg border ${gc[e]}`, children: [
/* @__PURE__ */ r("div", { className: "flex items-center gap-2 mb-1", children: /* @__PURE__ */ d("span", { className: "font-semibold uppercase text-base", children: [
e === "good" && "✓ ",
e === "warning" && "⚠ ",
e === "critical" && "✕ ",
n[e]
] }) }),
/* @__PURE__ */ r("p", { className: "text-sm", children: Bt(t) })
] });
}
function vc({ issue: e }) {
return /* @__PURE__ */ d("div", { className: "flex items-start gap-2 py-2", children: [
/* @__PURE__ */ d("span", { className: `text-sm ${bc[e.severity]}`, children: [
e.severity === "high" && "●",
e.severity === "medium" && "○",
e.severity === "low" && "○"
] }),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text-secondary", children: Bt(e.description) })
] });
}
function xs({ text: e }) {
const [t, n] = bt.useState(!1);
return /* @__PURE__ */ r(
"button",
{
onClick: async () => {
try {
await navigator.clipboard.writeText(e), n(!0), setTimeout(() => n(!1), 2e3);
} catch (a) {
console.error("Failed to copy:", a);
}
},
className: "px-2 py-1 text-xs rounded bg-dc-surface hover:bg-dc-surface-hover text-dc-text-muted",
title: "Copy to clipboard",
children: t ? "Copied!" : "Copy"
}
);
}
function wc({ rec: e }) {
const t = {
index: "INDEX",
table: "TABLE",
cube: "CUBE",
general: "TIP"
};
return /* @__PURE__ */ d("div", { className: "p-4 border border-dc-border rounded-lg bg-dc-surface", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 mb-2", children: [
/* @__PURE__ */ r(
"span",
{
className: `px-2 py-0.5 text-xs font-medium rounded ${yc[e.severity]}`,
children: t[e.type]
}
),
/* @__PURE__ */ r("h5", { className: "font-medium text-dc-text", children: Bt(e.title) })
] }),
/* @__PURE__ */ r("p", { className: "text-sm text-dc-text-secondary mb-3", children: Bt(e.description) }),
e.sql && /* @__PURE__ */ r("div", { className: "mt-2", children: /* @__PURE__ */ r(
ot,
{
code: e.sql,
language: "sql",
headerRight: /* @__PURE__ */ r(xs, { text: e.sql })
}
) }),
e.cubeCode && /* @__PURE__ */ d("div", { className: "mt-2", children: [
e.cubeName && /* @__PURE__ */ d("p", { className: "text-xs text-dc-text-muted mb-1", children: [
"Add to ",
/* @__PURE__ */ r("code", { className: "bg-dc-surface-secondary px-1 rounded", children: e.cubeName }),
" cube:"
] }),
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ r("pre", { className: "p-3 text-xs bg-dc-surface-secondary rounded overflow-x-auto font-mono text-dc-text", children: e.cubeCode }),
/* @__PURE__ */ r("div", { className: "absolute top-1 right-1", children: /* @__PURE__ */ r(xs, { text: e.cubeCode }) })
] })
] }),
e.estimatedImpact && /* @__PURE__ */ d("p", { className: "text-xs text-dc-text-muted mt-2", children: [
/* @__PURE__ */ r("strong", { children: "Expected impact:" }),
" ",
Bt(e.estimatedImpact)
] })
] });
}
function Nc({ analysis: e, onClose: t, onClear: n }) {
const s = t || n;
return bt.useEffect(() => {
const a = (i) => {
i.key === "Escape" && s && s();
};
return window.addEventListener("keydown", a), () => window.removeEventListener("keydown", a);
}, [s]), bt.useEffect(() => (document.body.style.overflow = "hidden", () => {
document.body.style.overflow = "";
}), []), /* @__PURE__ */ d("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50", children: [
/* @__PURE__ */ r(
"div",
{
className: "absolute inset-0",
onClick: s,
"aria-hidden": "true"
}
),
/* @__PURE__ */ d("div", { className: "relative w-full max-w-4xl max-h-[90vh] bg-dc-surface rounded-lg shadow-xl flex flex-col", children: [
/* @__PURE__ */ d("div", { className: "flex items-center justify-between px-6 py-4 border-b border-dc-border flex-shrink-0", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-3", children: [
/* @__PURE__ */ r("span", { className: "text-lg", children: "✨" }),
/* @__PURE__ */ r("h3", { className: "text-lg font-semibold text-dc-text", children: "AI Performance Analysis" })
] }),
/* @__PURE__ */ r(
"button",
{
onClick: s,
className: "p-2 rounded-lg hover:bg-dc-surface-hover text-dc-text-secondary hover:text-dc-text transition-colors",
"aria-label": "Close",
children: /* @__PURE__ */ r("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ r("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
}
)
] }),
/* @__PURE__ */ d("div", { className: "flex-1 overflow-y-auto px-6 py-4 space-y-6", children: [
/* @__PURE__ */ r(
xc,
{
assessment: e.assessment,
reason: e.assessmentReason
}
),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text-muted uppercase mb-2", children: "Summary" }),
/* @__PURE__ */ r("p", { className: "text-dc-text", children: Bt(e.summary) })
] }),
e.queryUnderstanding && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text-muted uppercase mb-2", children: "Query Analysis" }),
/* @__PURE__ */ r("p", { className: "text-dc-text-secondary", children: Bt(e.queryUnderstanding) })
] }),
e.issues && e.issues.length > 0 && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d("h4", { className: "text-sm font-semibold text-dc-text-muted uppercase mb-2", children: [
"Issues Found (",
e.issues.length,
")"
] }),
/* @__PURE__ */ r("div", { className: "space-y-1 bg-dc-surface-secondary rounded-lg p-3", children: e.issues.map((a, i) => /* @__PURE__ */ r(vc, { issue: a }, i)) })
] }),
e.recommendations && e.recommendations.length > 0 && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d("h4", { className: "text-sm font-semibold text-dc-text-muted uppercase mb-3", children: [
"Recommendations (",
e.recommendations.length,
")"
] }),
/* @__PURE__ */ r("div", { className: "space-y-4", children: e.recommendations.map((a, i) => /* @__PURE__ */ r(wc, { rec: a }, i)) })
] }),
(!e.recommendations || e.recommendations.length === 0) && /* @__PURE__ */ r("div", { className: "text-dc-text-muted italic p-4 bg-dc-surface-secondary rounded-lg", children: "No specific recommendations. The query appears to be well-optimized." })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center justify-between px-6 py-3 border-t border-dc-border flex-shrink-0 bg-dc-surface-secondary", children: [
e._meta && /* @__PURE__ */ d("div", { className: "text-xs text-dc-text-muted", children: [
"Model: ",
e._meta.model,
e._meta.usingUserKey && " (using your API key)"
] }),
/* @__PURE__ */ r(
"button",
{
onClick: s,
className: "px-4 py-2 text-sm font-medium rounded-lg bg-dc-primary text-white hover:bg-dc-primary-hover transition-colors",
children: "Close"
}
)
] })
] })
] });
}
const tr = Ge(function({
sql: t,
sqlLoading: n = !1,
sqlError: s,
sqlPlaceholder: a = "Add metrics to generate SQL",
explainResult: i,
explainLoading: o = !1,
explainHasRun: c = !1,
explainError: l,
runExplain: u,
aiAnalysis: h,
aiAnalysisLoading: f = !1,
aiAnalysisError: m,
runAIAnalysis: g,
clearAIAnalysis: b,
enableAI: N = !1,
query: x,
title: A = "Generated SQL",
height: w = "16rem"
}) {
const [y, C] = ee(!1), [T, p] = ee(!1), v = t ? t.sql + (t.params && t.params.length > 0 ? `
-- Parameters:
` + JSON.stringify(t.params, null, 2) : "") : "", k = () => {
g && i && x && (g(i, x), p(!0));
}, S = () => {
p(!1);
}, $ = N && i ? /* @__PURE__ */ r(
"button",
{
onClick: k,
disabled: f,
className: "px-2 py-1 text-xs font-medium rounded bg-dc-accent text-white hover:bg-dc-accent-hover disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1",
children: f ? /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("span", { className: "animate-spin", children: "⟳" }),
"Analyzing..."
] }) : /* @__PURE__ */ r(Ce, { children: "✨ AI Analysis" })
}
) : null;
return /* @__PURE__ */ d("div", { className: "space-y-3", children: [
n ? /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: A }),
/* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm animate-pulse", style: { height: w }, children: "Loading SQL..." })
] }) : s ? /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: A }),
/* @__PURE__ */ r("div", { className: "text-dc-error text-sm bg-dc-danger-bg p-3 rounded border border-dc-error", style: { height: w }, children: s.message })
] }) : t ? /* @__PURE__ */ r(
ot,
{
code: v,
language: "sql",
title: A,
height: w,
headerRight: /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ d("label", { className: "flex items-center gap-1 text-xs text-dc-text-secondary cursor-pointer", children: [
/* @__PURE__ */ r(
"input",
{
type: "checkbox",
checked: y,
onChange: (D) => C(D.target.checked),
className: "w-3 h-3 rounded border-dc-border text-dc-accent focus:ring-dc-accent"
}
),
"Include timing"
] }),
/* @__PURE__ */ r(
"button",
{
onClick: () => u({ analyze: y }),
disabled: o,
className: "px-2 py-1 text-xs font-medium rounded border border-dc-border bg-dc-surface hover:bg-dc-surface-hover text-dc-text-secondary hover:text-dc-text transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
children: o ? "Running..." : "Explain Plan"
}
)
] })
}
) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: A }),
/* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm", style: { height: w }, children: a })
] }),
c && /* @__PURE__ */ r("div", { children: o ? /* @__PURE__ */ d("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm animate-pulse", children: [
"Running EXPLAIN",
y ? " ANALYZE" : "",
"..."
] }) : l ? /* @__PURE__ */ d("div", { className: "text-dc-error text-sm bg-dc-danger-bg p-3 rounded border border-dc-error", children: [
/* @__PURE__ */ r("strong", { children: "Explain Error:" }),
" ",
l.message
] }) : i ? /* @__PURE__ */ d("div", { className: "space-y-3", children: [
/* @__PURE__ */ d("div", { className: "flex flex-wrap items-center gap-2", children: [
/* @__PURE__ */ r("span", { className: "px-2 py-1 text-xs font-medium bg-dc-accent text-white rounded", children: i.summary.database.toUpperCase() }),
i.summary.hasSequentialScans && /* @__PURE__ */ r("span", { className: "px-2 py-1 text-xs font-medium bg-dc-warning-bg text-dc-warning border border-dc-warning rounded", children: "Sequential Scans Detected" }),
i.summary.usedIndexes.length > 0 && /* @__PURE__ */ d("span", { className: "px-2 py-1 text-xs font-medium bg-dc-success-bg text-dc-success border border-dc-success rounded", children: [
i.summary.usedIndexes.length,
" Index",
i.summary.usedIndexes.length !== 1 ? "es" : "",
" Used"
] }),
i.summary.executionTime !== void 0 && /* @__PURE__ */ d("span", { className: "px-2 py-1 text-xs font-medium bg-dc-surface-secondary text-dc-text-secondary border border-dc-border rounded", children: [
"Execution: ",
i.summary.executionTime.toFixed(2),
"ms"
] }),
i.summary.planningTime !== void 0 && /* @__PURE__ */ d("span", { className: "px-2 py-1 text-xs font-medium bg-dc-surface-secondary text-dc-text-secondary border border-dc-border rounded", children: [
"Planning: ",
i.summary.planningTime.toFixed(2),
"ms"
] }),
i.summary.totalCost !== void 0 && /* @__PURE__ */ d("span", { className: "px-2 py-1 text-xs font-medium bg-dc-surface-secondary text-dc-text-secondary border border-dc-border rounded", children: [
"Cost: ",
i.summary.totalCost.toFixed(2)
] })
] }),
i.summary.usedIndexes.length > 0 && /* @__PURE__ */ d("div", { className: "text-xs text-dc-text-muted", children: [
/* @__PURE__ */ r("strong", { children: "Indexes:" }),
" ",
i.summary.usedIndexes.join(", ")
] }),
/* @__PURE__ */ r(
ot,
{
code: i.raw,
language: "sql",
title: `Execution Plan (${i.summary.database})`,
height: "16rem",
headerRight: $
}
)
] }) : null }),
m && /* @__PURE__ */ d("div", { className: "text-dc-error text-sm bg-dc-danger-bg p-3 rounded border border-dc-error", children: [
/* @__PURE__ */ r("strong", { children: "AI Analysis Error:" }),
" ",
m.message
] }),
T && h && /* @__PURE__ */ r(
Nc,
{
analysis: h,
onClose: S
}
)
] });
}), Cc = Ge(function({
executionStatus: t,
executionResults: n,
executionError: s,
totalRowCount: a,
resultsStale: i = !1,
chartType: o = "line",
chartConfig: c = {},
displayConfig: l = {},
colorPalette: u,
currentPaletteName: h,
onColorPaletteChange: f,
allQueries: m,
funnelExecutedQueries: g,
activeView: b = "chart",
onActiveViewChange: N,
displayLimit: x = 100,
onDisplayLimitChange: A,
hasMetrics: w = !1,
// Debug props - per-query for multi-query mode
debugDataPerQuery: y = [],
// Share props
onShareClick: C,
canShare: T = !1,
shareButtonState: p = "idle",
// Refresh functionality
onRefreshClick: v,
canRefresh: k = !1,
isRefreshing: S = !1,
// Clear functionality
onClearClick: $,
canClear: D = !1,
// AI functionality
enableAI: F = !1,
isAIOpen: K = !1,
onAIToggle: P,
// Multi-query props
queryCount: te = 1,
perQueryResults: _,
activeTableIndex: O = 0,
onActiveTableChange: ie,
// Analysis type (new) - primary way to detect funnel mode
analysisType: X,
// Legacy funnel mode prop (deprecated - use analysisType === 'funnel' instead)
isFunnelMode: ce = !1,
// Funnel-specific debug props
funnelServerQuery: Q,
funnelDebugData: Se,
// Flow-specific debug props
flowServerQuery: L,
flowDebugData: pe
}) {
const z = X === "funnel" || ce, H = X === "flow", [se, me] = ee(!1), [le, we] = ee(0), [Y, Pe] = ee(!1);
he(() => {
y.length > 0 && le >= y.length && we(y.length - 1);
}, [y.length, le]);
const He = y[le] || {
sql: null,
analysis: null,
loading: !1,
error: null
}, Ne = He.sql, _e = He.analysis, We = He.loading, Je = He.error, Ke = g?.[le] ?? m?.[le] ?? null, Oe = !!(g?.length && g[le]), {
explainResult: Xe,
isLoading: Qe,
hasRun: J,
error: fe,
runExplain: ve,
clearExplain: ke
} = Gn(Ke, {
skip: z || H || !Ke
}), {
explainResult: Fe,
isLoading: re,
hasRun: be,
error: Ee,
runExplain: qe,
clearExplain: Ze
} = Gn(Q, {
skip: !z || !Q
}), {
explainResult: xt,
isLoading: vt,
hasRun: gt,
error: wt,
runExplain: Tt,
clearExplain: kt
} = Gn(L, {
skip: !H || !L
}), {
analysis: ct,
isAnalyzing: ut,
error: Ye,
analyze: st,
clearAnalysis: Nt
} = to();
he(() => {
ke();
}, [le, ke]), he(() => {
Ze();
}, [Q, Ze]), he(() => {
kt();
}, [L, kt]);
const ze = ge(!0);
he(() => {
if (ze.current) {
ze.current = !1;
return;
}
X === "funnel" || X === "flow" || z || !w && b === "chart" && N("table");
}, [w, b, N, z, X]);
const M = V(() => {
if (!m || m.length === 0) return;
if (m.length === 1) return m[0];
const Me = m.flatMap((j) => j?.measures || []);
return {
...m[0],
measures: Me
};
}, [m]), I = q("success"), B = q("error"), Z = q("warning"), ue = q("table"), ae = q("measure"), U = q("codeBracket"), G = q("share"), oe = q("check"), Ae = q("delete"), De = q("sparkles"), $e = q("arrowPath"), et = () => /* @__PURE__ */ r("div", { className: "h-full flex items-center justify-center", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(
"div",
{
className: "animate-spin rounded-full h-12 w-12 border-b-2 mx-auto mb-4",
style: { borderBottomColor: "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold text-dc-text-secondary mb-1", children: "Executing Query..." }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted", children: "Running your query against the cube API" })
] }) }), tt = () => /* @__PURE__ */ d("div", { className: "h-full flex flex-col", children: [
Wt(),
/* @__PURE__ */ r("div", { className: "flex-1 flex items-center justify-center p-4", children: se ? /* @__PURE__ */ r("div", { className: "w-full h-full overflow-auto", children: Lt() }) : /* @__PURE__ */ d("div", { className: "text-center max-w-md", children: [
/* @__PURE__ */ r(B, { className: "w-12 h-12 mx-auto text-dc-error mb-4" }),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold text-dc-text mb-2", children: "Query Execution Failed" }),
/* @__PURE__ */ r("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__ */ r("div", { className: "bg-dc-danger-bg border border-dc-error rounded-lg p-3 text-left", children: /* @__PURE__ */ r("div", { className: "text-xs font-mono text-dc-error break-words", children: s }) })
] }) })
] }), at = !!m?.some(
(Me) => Me?.measures && Me.measures.length > 0 || Me?.dimensions && Me.dimensions.length > 0 || Me?.timeDimensions && Me.timeDimensions.length > 0
), Ct = () => /* @__PURE__ */ r("div", { className: "h-full flex items-center justify-center", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(
"div",
{
className: "animate-spin rounded-full h-12 w-12 border-b-2 mx-auto mb-4",
style: { borderBottomColor: "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold text-dc-text-secondary mb-1", children: "Preparing Query..." }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted", children: "Your query will execute shortly" })
] }) }), Rt = () => /* @__PURE__ */ r("div", { className: "h-full flex items-center justify-center pt-6", children: /* @__PURE__ */ d("div", { className: "text-center mb-16", children: [
/* @__PURE__ */ r(ae, { className: "w-12 h-12 mx-auto text-dc-text-muted mb-3" }),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold text-dc-text-secondary mb-1", children: "No Results Yet" }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted mb-4", children: "Add metrics or breakdowns from the panel on the right to see results" }),
F && P && /* @__PURE__ */ d(
"button",
{
onClick: P,
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__ */ r(De, { className: "w-4 h-4" }),
"Analyse with AI"
]
}
)
] }) }), yt = () => /* @__PURE__ */ r("div", { className: "h-full flex items-center justify-center", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(I, { className: "w-12 h-12 mx-auto text-dc-success mb-3" }),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold text-dc-text mb-1", children: "Query Successful" }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted", children: "No data returned from the query" })
] }) }), R = () => {
if (!n || n.length === 0)
return /* @__PURE__ */ r("div", { className: "flex items-center justify-center h-full text-dc-text-muted", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(ae, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold mb-1", children: "No data to display" }),
/* @__PURE__ */ r("div", { className: "text-xs", children: "Run a query to see chart visualization" })
] }) });
const Me = o === "sankey" && l?.flowVisualization === "sunburst" ? "sunburst" : o;
return da(Me) ? /* @__PURE__ */ r(
ur,
{
chartType: Me,
data: n,
chartConfig: c,
displayConfig: l,
colorPalette: u,
queryObject: M,
height: "100%",
fallback: /* @__PURE__ */ r("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ r("div", { className: "animate-pulse bg-dc-surface-secondary rounded w-full h-full" }) })
}
) : /* @__PURE__ */ r("div", { className: "flex items-center justify-center h-full text-dc-text-muted", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(Z, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold mb-1", children: "Unsupported chart type" }),
/* @__PURE__ */ r("div", { className: "text-xs", children: Me })
] }) });
}, Ue = () => {
const Me = Se?.sql, j = Se?.loading || !1, ne = Se?.error, ye = Se?.funnelMetadata;
return /* @__PURE__ */ d("div", { className: "p-4 space-y-4 overflow-auto h-full", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 mb-4", children: [
/* @__PURE__ */ r("span", { className: "px-2 py-1 text-xs font-medium bg-dc-accent text-white rounded", children: "Funnel Query" }),
ye?.stepCount && /* @__PURE__ */ d("span", { className: "text-xs text-dc-text-muted", children: [
ye.stepCount,
" steps"
] }),
j && /* @__PURE__ */ r("span", { className: "text-xs text-dc-text-muted animate-pulse", children: "Loading SQL..." })
] }),
s && /* @__PURE__ */ d("div", { className: "bg-dc-danger-bg dark:bg-dc-danger-bg border border-dc-error dark:border-dc-error rounded p-3", children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-error dark:text-dc-error mb-1", children: "Execution Error" }),
/* @__PURE__ */ r("p", { className: "text-sm text-dc-error dark:text-dc-error", children: s })
] }),
/* @__PURE__ */ r("div", { children: Q ? /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(Q, null, 2),
language: "json",
title: "Funnel Server Query",
height: "16rem"
}
) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Funnel Server Query" }),
/* @__PURE__ */ r("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 funnel query configured" })
] }) }),
/* @__PURE__ */ r(
tr,
{
sql: Me,
sqlLoading: j,
sqlError: ne,
sqlPlaceholder: "Configure funnel binding key to generate SQL",
explainResult: Fe,
explainLoading: re,
explainHasRun: be,
explainError: Ee,
runExplain: qe,
aiAnalysis: ct,
aiAnalysisLoading: ut,
aiAnalysisError: Ye,
runAIAnalysis: st,
clearAIAnalysis: Nt,
enableAI: F,
query: Q,
title: "Generated SQL",
height: "16rem"
}
),
ye && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Funnel Steps" }),
/* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3", children: /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-2", children: ye.steps.map((Re, je) => /* @__PURE__ */ d("div", { className: "flex items-center gap-2 px-3 py-1.5 bg-dc-bg border border-dc-border rounded text-sm", children: [
/* @__PURE__ */ r("span", { className: "w-5 h-5 flex items-center justify-center bg-dc-accent text-white text-xs rounded-full", children: je + 1 }),
/* @__PURE__ */ r("span", { className: "text-dc-text", children: Re.name }),
Re.timeToConvert && /* @__PURE__ */ d("span", { className: "text-xs text-dc-text-muted", children: [
"(",
Re.timeToConvert,
")"
] })
] }, je)) }) })
] }),
/* @__PURE__ */ d("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
/* @__PURE__ */ r("div", { children: /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(c, null, 2),
language: "json",
title: "Chart Config",
height: "16rem"
}
) }),
/* @__PURE__ */ r("div", { children: /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(l, null, 2),
language: "json",
title: "Display Config",
height: "16rem"
}
) })
] }),
/* @__PURE__ */ r("div", { children: n ? /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(n, null, 2),
language: "json",
title: `Server Response (${n.length} rows)`,
maxHeight: "24rem"
}
) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Server Response" }),
/* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm", children: "No results yet" })
] }) })
] });
}, nt = () => {
const Me = pe?.sql, j = pe?.loading || !1, ne = pe?.error, ye = pe?.flowMetadata;
return /* @__PURE__ */ d("div", { className: "p-4 space-y-4 overflow-auto h-full", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 mb-4", children: [
/* @__PURE__ */ r("span", { className: "px-2 py-1 text-xs font-medium bg-dc-accent text-white rounded", children: "Flow Query" }),
ye && /* @__PURE__ */ d("span", { className: "text-xs text-dc-text-muted", children: [
ye.stepsBefore,
" before, ",
ye.stepsAfter,
" after"
] }),
j && /* @__PURE__ */ r("span", { className: "text-xs text-dc-text-muted animate-pulse", children: "Loading SQL..." })
] }),
s && /* @__PURE__ */ d("div", { className: "bg-dc-danger-bg dark:bg-dc-danger-bg border border-dc-error dark:border-dc-error rounded p-3", children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-error dark:text-dc-error mb-1", children: "Execution Error" }),
/* @__PURE__ */ r("p", { className: "text-sm text-dc-error dark:text-dc-error", children: s })
] }),
/* @__PURE__ */ r("div", { children: L ? /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(L, null, 2),
language: "json",
title: "Flow Server Query",
height: "16rem"
}
) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Flow Server Query" }),
/* @__PURE__ */ r("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 flow query configured" })
] }) }),
/* @__PURE__ */ r(
tr,
{
sql: Me,
sqlLoading: j,
sqlError: ne,
sqlPlaceholder: "Configure flow to generate SQL",
explainResult: xt,
explainLoading: vt,
explainHasRun: gt,
explainError: wt,
runExplain: Tt,
aiAnalysis: ct,
aiAnalysisLoading: ut,
aiAnalysisError: Ye,
runAIAnalysis: st,
clearAIAnalysis: Nt,
enableAI: F,
query: L,
title: "Generated SQL",
height: "16rem"
}
),
ye && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Flow Configuration" }),
/* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3", children: /* @__PURE__ */ d("div", { className: "grid grid-cols-2 gap-4 text-sm", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("span", { className: "text-dc-text-muted", children: "Starting Step:" }),
" ",
/* @__PURE__ */ r("span", { className: "text-dc-text", children: ye.startingStep?.name || "Not set" })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("span", { className: "text-dc-text-muted", children: "Event Dimension:" }),
" ",
/* @__PURE__ */ r("span", { className: "text-dc-text", children: ye.eventDimension || "Not set" })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("span", { className: "text-dc-text-muted", children: "Steps Before:" }),
" ",
/* @__PURE__ */ r("span", { className: "text-dc-text", children: ye.stepsBefore ?? "Not set" })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("span", { className: "text-dc-text-muted", children: "Steps After:" }),
" ",
/* @__PURE__ */ r("span", { className: "text-dc-text", children: ye.stepsAfter ?? "Not set" })
] })
] }) })
] }),
/* @__PURE__ */ d("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
/* @__PURE__ */ r("div", { children: /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(c, null, 2),
language: "json",
title: "Chart Config",
height: "16rem"
}
) }),
/* @__PURE__ */ r("div", { children: /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(l, null, 2),
language: "json",
title: "Display Config",
height: "16rem"
}
) })
] }),
/* @__PURE__ */ r("div", { children: n ? /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(n, null, 2),
language: "json",
title: "Server Response (Sankey Data)",
maxHeight: "24rem"
}
) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Server Response" }),
/* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm", children: "No results yet" })
] }) })
] });
}, $t = () => /* @__PURE__ */ d("div", { className: "p-4 space-y-4 overflow-auto h-full", children: [
y.length > 1 && /* @__PURE__ */ d("div", { className: "flex items-center gap-1 mb-4", children: [
/* @__PURE__ */ r("span", { className: "text-xs font-medium text-dc-text-muted mr-2", children: "Query:" }),
/* @__PURE__ */ r("div", { className: "flex border border-dc-border rounded-md overflow-hidden", children: y.map((Me, j) => /* @__PURE__ */ d(
"button",
{
onClick: () => we(j),
className: `px-3 py-1 text-xs font-medium transition-colors border-r last:border-r-0 border-dc-border ${le === j ? "bg-dc-accent text-white" : "bg-dc-bg text-dc-text-secondary hover:bg-dc-bg-secondary"}`,
children: [
"Q",
j + 1,
Me.loading && /* @__PURE__ */ r("span", { className: "ml-1 opacity-70", children: "•" }),
Me.error && /* @__PURE__ */ r("span", { className: "ml-1 text-dc-error", children: "!" })
]
},
j
)) })
] }),
s && /* @__PURE__ */ d("div", { className: "bg-dc-danger-bg dark:bg-dc-danger-bg border border-dc-error dark:border-dc-error rounded p-3", children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-error dark:text-dc-error mb-1", children: "Execution Error" }),
/* @__PURE__ */ r("p", { className: "text-sm text-dc-error dark:text-dc-error", children: s })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Query Analysis" }),
We ? /* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm", children: "Loading..." }) : _e ? /* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3", children: /* @__PURE__ */ r(dc, { analysis: _e }) }) : /* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm", children: Je ? "Analysis unavailable due to error" : "Add metrics to see analysis" })
] }),
/* @__PURE__ */ r("div", { children: Ke ? /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(
ot,
{
code: JSON.stringify(Ke, null, 2),
language: "json",
title: Oe ? "Executed Query (with funnel filters)" : "Cube Query",
height: "16rem"
}
),
Oe && le > 0 && /* @__PURE__ */ d("div", { className: "mt-1 text-xs text-dc-text-muted", children: [
/* @__PURE__ */ r("span", { className: "text-dc-accent", children: "ℹ" }),
" This query includes an IN filter with binding key values from the previous step"
] })
] }) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Cube Query" }),
/* @__PURE__ */ r("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__ */ r(
tr,
{
sql: Ne,
sqlLoading: We,
sqlError: Je,
sqlPlaceholder: "Add metrics to generate SQL",
explainResult: Xe,
explainLoading: Qe,
explainHasRun: J,
explainError: fe,
runExplain: ve,
aiAnalysis: ct,
aiAnalysisLoading: ut,
aiAnalysisError: Ye,
runAIAnalysis: st,
clearAIAnalysis: Nt,
enableAI: F,
query: Ke,
title: "Generated SQL",
height: "16rem"
}
),
/* @__PURE__ */ d("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
/* @__PURE__ */ r("div", { children: /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(c, null, 2),
language: "json",
title: "Chart Config",
height: "16rem"
}
) }),
/* @__PURE__ */ r("div", { children: /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(l, null, 2),
language: "json",
title: "Display Config",
height: "16rem"
}
) })
] }),
/* @__PURE__ */ r("div", { children: n ? /* @__PURE__ */ r(
ot,
{
code: JSON.stringify(n, null, 2),
language: "json",
title: `Server Response (${n.length} rows)`,
maxHeight: "24rem"
}
) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("h4", { className: "text-sm font-semibold text-dc-text mb-2", children: "Server Response" }),
/* @__PURE__ */ r("div", { className: "bg-dc-surface-secondary border border-dc-border rounded p-3 text-dc-text-muted text-sm", children: "No results yet" })
] }) })
] }), Lt = () => H ? nt() : z ? Ue() : $t(), At = !z && te > 1 && _ && _.length > 1, ft = () => {
let Me = [], j = [];
if (!n || Array.isArray(n) && n.length === 0)
return /* @__PURE__ */ r("div", { className: "flex items-center justify-center h-full text-dc-text-muted", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(ue, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold mb-1", children: "No flow data to display" }),
/* @__PURE__ */ r("div", { className: "text-xs", children: "Configure flow analysis to see results" })
] }) });
if (Array.isArray(n) && n.length > 0) {
const ne = n[0];
ne && "nodes" in ne && "links" in ne ? (Me = ne.nodes || [], j = ne.links || []) : "record_type" in ne && (Me = n.filter((ye) => ye.record_type === "node"), j = n.filter((ye) => ye.record_type === "link"));
}
return Me.length === 0 && j.length === 0 ? /* @__PURE__ */ r("div", { className: "flex items-center justify-center h-full text-dc-text-muted", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(ue, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold mb-1", children: "No flow data to display" }),
/* @__PURE__ */ r("div", { className: "text-xs", children: "Configure flow analysis to see results" })
] }) }) : /* @__PURE__ */ d("div", { className: "h-full overflow-auto p-4 space-y-6", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d("h3", { className: "text-sm font-semibold text-dc-text mb-2", children: [
"Nodes (",
Me.length,
")"
] }),
/* @__PURE__ */ r("div", { className: "border border-dc-border rounded overflow-hidden", children: /* @__PURE__ */ d("table", { className: "w-full text-sm", children: [
/* @__PURE__ */ r("thead", { className: "bg-dc-surface-secondary", children: /* @__PURE__ */ d("tr", { children: [
/* @__PURE__ */ r("th", { className: "px-3 py-2 text-left text-xs font-medium text-dc-text-muted uppercase tracking-wider", children: "Layer" }),
/* @__PURE__ */ r("th", { className: "px-3 py-2 text-left text-xs font-medium text-dc-text-muted uppercase tracking-wider", children: "Name" }),
/* @__PURE__ */ r("th", { className: "px-3 py-2 text-right text-xs font-medium text-dc-text-muted uppercase tracking-wider", children: "Count" })
] }) }),
/* @__PURE__ */ r("tbody", { className: "divide-y divide-dc-border bg-dc-surface", children: Me.sort((ne, ye) => ne.layer - ye.layer).map((ne, ye) => /* @__PURE__ */ d("tr", { className: "hover:bg-dc-surface-hover", children: [
/* @__PURE__ */ r("td", { className: "px-3 py-2 whitespace-nowrap", children: /* @__PURE__ */ r("span", { className: `inline-flex items-center justify-center w-6 h-6 rounded text-xs font-medium ${ne.layer === 0 ? "bg-dc-primary text-white" : ne.layer < 0 ? "bg-dc-accent-bg text-dc-accent" : "bg-dc-success-bg text-dc-success"}`, children: ne.layer === 0 ? "★" : ne.layer }) }),
/* @__PURE__ */ r("td", { className: "px-3 py-2 text-dc-text", children: ne.name }),
/* @__PURE__ */ r("td", { className: "px-3 py-2 text-right text-dc-text font-mono", children: ne.value?.toLocaleString() })
] }, ye)) })
] }) })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d("h3", { className: "text-sm font-semibold text-dc-text mb-2", children: [
"Transitions (",
j.length,
")"
] }),
/* @__PURE__ */ r("div", { className: "border border-dc-border rounded overflow-hidden", children: /* @__PURE__ */ d("table", { className: "w-full text-sm", children: [
/* @__PURE__ */ r("thead", { className: "bg-dc-surface-secondary", children: /* @__PURE__ */ d("tr", { children: [
/* @__PURE__ */ r("th", { className: "px-3 py-2 text-left text-xs font-medium text-dc-text-muted uppercase tracking-wider", children: "From" }),
/* @__PURE__ */ r("th", { className: "px-3 py-2 text-center text-xs font-medium text-dc-text-muted uppercase tracking-wider", children: "→" }),
/* @__PURE__ */ r("th", { className: "px-3 py-2 text-left text-xs font-medium text-dc-text-muted uppercase tracking-wider", children: "To" }),
/* @__PURE__ */ r("th", { className: "px-3 py-2 text-right text-xs font-medium text-dc-text-muted uppercase tracking-wider", children: "Count" })
] }) }),
/* @__PURE__ */ r("tbody", { className: "divide-y divide-dc-border bg-dc-surface", children: j.map((ne, ye) => {
const Re = ne.source || ne.source_id || "", je = ne.target || ne.target_id || "", mt = Re.split("_").slice(-1)[0] || Re, Mt = je.split("_").slice(-1)[0] || je;
return /* @__PURE__ */ d("tr", { className: "hover:bg-dc-surface-hover", children: [
/* @__PURE__ */ r("td", { className: "px-3 py-2 text-dc-text", children: mt }),
/* @__PURE__ */ r("td", { className: "px-3 py-2 text-center text-dc-text-muted", children: "→" }),
/* @__PURE__ */ r("td", { className: "px-3 py-2 text-dc-text", children: Mt }),
/* @__PURE__ */ r("td", { className: "px-3 py-2 text-right text-dc-text font-mono", children: ne.value?.toLocaleString() })
] }, ye);
}) })
] }) })
] })
] });
}, Gt = (Me) => {
let j = null, ne = m?.[0];
if (At && Me !== void 0 && Me >= 0 && _ ? (j = _[Me] || null, ne = m?.[Me]) : (j = n, At && (ne = M)), !j || j.length === 0)
return /* @__PURE__ */ r("div", { className: "flex items-center justify-center h-full text-dc-text-muted", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(ue, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
/* @__PURE__ */ r("div", { className: "text-sm font-semibold mb-1", children: "No data to display" }),
/* @__PURE__ */ r("div", { className: "text-xs", children: "Run a query to see table data" })
] }) });
const ye = j.slice(0, x);
return /* @__PURE__ */ r(
ur,
{
chartType: "table",
data: ye,
colorPalette: u,
queryObject: ne,
height: "100%",
fallback: /* @__PURE__ */ r("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ r("div", { className: "animate-pulse bg-dc-surface-secondary rounded w-full h-full" }) })
}
);
}, cn = () => /* @__PURE__ */ r("div", { className: "absolute inset-0 flex items-center justify-center bg-dc-surface bg-opacity-75 z-10", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(
"div",
{
className: "animate-spin rounded-full h-10 w-10 border-b-2 mx-auto mb-2",
style: { borderBottomColor: "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-secondary", children: "Refreshing results..." })
] }) }), Wt = () => {
const Me = n && n.length > 0;
return /* @__PURE__ */ d("div", { className: "px-4 py-2 border-b border-dc-border bg-dc-surface-secondary flex-shrink-0", children: [
/* @__PURE__ */ d("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ d("div", { className: "flex items-center", children: [
t === "refreshing" ? /* @__PURE__ */ r(
"div",
{
className: "w-4 h-4 mr-2 rounded-full border-b-2 animate-spin",
style: { borderBottomColor: "var(--dc-primary)" }
}
) : Me ? /* @__PURE__ */ r(I, { className: "w-4 h-4 text-dc-success mr-2" }) : t === "error" ? /* @__PURE__ */ r(B, { className: "w-4 h-4 text-dc-error mr-2" }) : /* @__PURE__ */ r(Z, { className: "w-4 h-4 text-dc-text-muted mr-2" }),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text-secondary", children: Me ? /* @__PURE__ */ d(Ce, { children: [
n.length,
" row",
n.length !== 1 ? "s" : "",
a !== null && a > n.length && /* @__PURE__ */ d("span", { className: "text-dc-text-muted", children: [
" of ",
a.toLocaleString()
] }),
i && /* @__PURE__ */ r("span", { className: "text-dc-warning ml-2", children: "• Results may be outdated" })
] }) : t === "error" ? "Query failed" : t === "loading" ? "Executing..." : "No results" })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
Me && b === "table" && !se && A && /* @__PURE__ */ d(
"select",
{
value: x,
onChange: (j) => A(Number(j.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__ */ r("option", { value: 50, children: "50 rows" }),
/* @__PURE__ */ r("option", { value: 100, children: "100 rows" }),
/* @__PURE__ */ r("option", { value: 250, children: "250 rows" }),
/* @__PURE__ */ r("option", { value: 500, children: "500 rows" })
]
}
),
F && P && /* @__PURE__ */ d(
"button",
{
onClick: P,
className: `flex items-center gap-1 px-2 py-1.5 text-xs font-medium rounded transition-colors ${K ? "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: K ? "Close AI assistant" : "Analyse with AI",
children: [
/* @__PURE__ */ r(De, { className: "w-3 h-3" }),
/* @__PURE__ */ r("span", { className: "hidden sm:inline", children: "Analyse with AI" })
]
}
),
f && Me && /* @__PURE__ */ r(
Ba,
{
currentPalette: h || "default",
onPaletteChange: f
}
),
C && /* @__PURE__ */ r(
"button",
{
onClick: C,
className: `flex items-center gap-1 px-2 py-1.5 text-xs font-medium rounded transition-colors ${p === "idle" && T ? "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" : p !== "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: p === "idle" ? "Share this analysis" : "Link copied!",
disabled: !T || p !== "idle",
children: p === "idle" ? /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(G, { className: "w-3 h-3" }),
/* @__PURE__ */ r("span", { className: "hidden sm:inline", children: "Share" })
] }) : p === "copied" ? /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(oe, { className: "w-3 h-3" }),
/* @__PURE__ */ r("span", { className: "hidden sm:inline", children: "Copied!" })
] }) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(oe, { className: "w-3 h-3" }),
/* @__PURE__ */ r("span", { className: "hidden sm:inline", children: "Copied!" }),
/* @__PURE__ */ r("span", { className: "hidden lg:inline text-[10px] opacity-75", children: "(no chart)" })
] })
}
),
v && k && /* @__PURE__ */ d(
"button",
{
onClick: v,
disabled: S,
className: `flex items-center gap-1 px-2 py-1.5 text-xs font-medium rounded transition-colors ${S ? "text-dc-text-muted bg-dc-surface-secondary border border-dc-border cursor-wait" : "text-dc-accent bg-dc-accent-bg border border-dc-accent hover:bg-dc-accent-bg"}`,
title: S ? "Refreshing..." : "Refresh data",
children: [
/* @__PURE__ */ r($e, { className: `w-3 h-3 ${S ? "animate-spin" : ""}` }),
/* @__PURE__ */ r("span", { className: "hidden sm:inline", children: S ? "Refreshing" : "Refresh" })
]
}
),
$ && D && /* @__PURE__ */ d(
"button",
{
onClick: () => Pe(!0),
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: z ? "Clear funnel" : "Clear all query data",
children: [
/* @__PURE__ */ r(Ae, { className: "w-3 h-3" }),
/* @__PURE__ */ r("span", { className: "hidden sm:inline", children: "Clear" })
]
}
),
/* @__PURE__ */ d(
"button",
{
onClick: () => me(!se),
className: `p-1.5 rounded transition-colors relative ${se ? "bg-dc-primary text-white" : "text-dc-text-secondary hover:text-dc-text hover:bg-dc-surface-hover"}`,
title: se ? "Hide debug info" : "Show debug info",
children: [
/* @__PURE__ */ r(U, { className: "w-4 h-4" }),
(s || y.some((j) => j.error)) && !se && /* @__PURE__ */ r("span", { className: "absolute -top-0.5 -right-0.5 w-2 h-2 bg-dc-danger-bg0 rounded-full" })
]
}
)
] })
] }),
Me && a !== null && a > 1e3 && /* @__PURE__ */ d("div", { className: "mt-2 bg-dc-warning-bg border border-dc-warning rounded-lg p-2 flex items-start", children: [
/* @__PURE__ */ r(Z, { className: "w-4 h-4 text-dc-warning mr-2 shrink-0 mt-0.5" }),
/* @__PURE__ */ d("div", { className: "text-xs text-dc-warning", children: [
/* @__PURE__ */ r("span", { className: "font-semibold", children: "Large dataset:" }),
" ",
a.toLocaleString(),
" rows. Consider adding filters to improve performance."
] })
] })
] });
}, Vn = () => n && n.length > 0 ? /* @__PURE__ */ d("div", { className: "h-full flex flex-col", children: [
Wt(),
/* @__PURE__ */ r("div", { className: "flex-1 min-h-0 relative overflow-auto", children: se ? Lt() : b === "chart" ? /* @__PURE__ */ r("div", { className: "p-4 h-full", children: R() }) : H ? /* @__PURE__ */ r("div", { className: "h-full", children: ft() }, "table-flow") : At ? /* @__PURE__ */ r("div", { className: "h-full", children: Gt(O) }, `table-${O}`) : /* @__PURE__ */ r("div", { className: "h-full", children: Gt() }, "table-single") }),
!se && /* @__PURE__ */ r("div", { className: "px-4 py-3 border-t border-dc-border bg-dc-surface flex justify-center flex-shrink-0", children: /* @__PURE__ */ d("div", { className: "flex items-center bg-dc-surface-secondary border border-dc-border rounded-md overflow-hidden", children: [
/* @__PURE__ */ d(
"button",
{
onClick: () => (w || H || z) && N("chart"),
disabled: !w && !H && !z,
className: `flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium transition-colors ${b === "chart" ? "bg-dc-primary text-white" : !w && !H && !z ? "text-dc-text-disabled bg-dc-surface-tertiary cursor-not-allowed" : "text-dc-text-secondary hover:bg-dc-surface-hover"}`,
title: w || H || z ? "Chart view" : "Add metrics to enable chart view",
children: [
/* @__PURE__ */ r(ae, { className: "w-4 h-4" }),
"Chart"
]
}
),
At ? /* @__PURE__ */ d(Ce, { children: [
Array.from({ length: te }).map((j, ne) => /* @__PURE__ */ d(
"button",
{
onClick: () => {
N("table"), ie?.(ne);
},
className: `flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium transition-colors ${b === "table" && O === ne ? "bg-dc-primary text-white" : "text-dc-text-secondary hover:bg-dc-surface-hover"}`,
title: `Table Q${ne + 1}`,
children: [
/* @__PURE__ */ r(ue, { className: "w-4 h-4" }),
"Q",
ne + 1
]
},
`table-${ne}`
)),
/* @__PURE__ */ d(
"button",
{
onClick: () => {
N("table"), ie?.(-1);
},
className: `flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium transition-colors ${b === "table" && O === -1 ? "bg-dc-primary text-white" : "text-dc-text-secondary hover:bg-dc-surface-hover"}`,
title: "Merged table view",
children: [
/* @__PURE__ */ r(ue, { className: "w-4 h-4" }),
"Merged"
]
}
)
] }) : /* @__PURE__ */ d(
"button",
{
onClick: () => N("table"),
className: `flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium transition-colors ${b === "table" ? "bg-dc-primary text-white" : "text-dc-text-secondary hover:bg-dc-surface-hover"}`,
title: "Table view",
children: [
/* @__PURE__ */ r(ue, { className: "w-4 h-4" }),
"Table"
]
}
)
] }) })
] }) : /* @__PURE__ */ d("div", { className: "h-full flex flex-col", children: [
Wt(),
/* @__PURE__ */ r("div", { className: "flex-1 min-h-0 relative overflow-auto", children: se ? Lt() : yt() })
] }), Pt = n !== null, Kt = Pt && (t !== "idle" || at);
return /* @__PURE__ */ d("div", { className: "h-full min-h-[400px] flex flex-col bg-dc-surface relative", children: [
t === "idle" && !at && Rt(),
t === "idle" && at && !Pt && Ct(),
t === "loading" && !Pt && et(),
t === "error" && !Pt && tt(),
(t === "success" || Kt) && Vn(),
(t === "loading" || t === "refreshing") && Pt && cn(),
$ && /* @__PURE__ */ r(
qa,
{
isOpen: Y,
onClose: () => Pe(!1),
onConfirm: () => {
$(), Pe(!1);
},
title: z ? "Clear Funnel" : "Clear Query",
message: /* @__PURE__ */ r(Ce, { children: z ? "Are you sure you want to clear this funnel? This action cannot be undone." : "Are you sure you want to clear this query? This action cannot be undone." }),
confirmText: "Clear",
confirmVariant: "warning"
}
)
] });
}), Sc = Ge(function({
metric: t,
fieldMeta: n,
onRemove: s,
sortDirection: a,
sortPriority: i,
onToggleSort: o,
index: c,
isDragging: l,
onDragStart: u,
onDragEnd: h
}) {
const f = q("close"), m = q("chevronUp"), g = q("chevronDown"), b = q("chevronUpDown"), N = n?.type || "count", x = on(N) || q("measure"), A = n?.shortTitle || n?.title || t.field.split(".").pop() || t.field, w = t.field.split(".")[0], y = () => {
switch (a) {
case "asc":
return m ? /* @__PURE__ */ r(m, { className: "w-4 h-4" }) : "↑";
case "desc":
return g ? /* @__PURE__ */ r(g, { className: "w-4 h-4" }) : "↓";
default:
return b ? /* @__PURE__ */ r(b, { className: "w-4 h-4" }) : "⇅";
}
}, C = () => {
switch (a) {
case "asc":
return "Sorted ascending (click for descending)";
case "desc":
return "Sorted descending (click to remove)";
default:
return "Click to sort ascending";
}
}, T = typeof c == "number" && u && h;
return /* @__PURE__ */ d(
"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 ${T ? "cursor-grab active:cursor-grabbing" : ""} ${l ? "opacity-30" : ""}`,
draggable: T ? !0 : void 0,
onDragStart: T ? (p) => u(p, c) : void 0,
onDragEnd: T ? h : void 0,
children: [
/* @__PURE__ */ r("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-measure text-dc-measure-text flex-shrink-0", children: x && /* @__PURE__ */ r(x, { className: "w-4 h-4" }) }),
/* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ r("div", { className: "text-sm text-dc-text truncate", title: t.field, children: A }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted truncate", children: w })
] }),
o && /* @__PURE__ */ d(
"button",
{
onClick: o,
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: C(),
children: [
y(),
a && i && /* @__PURE__ */ d("span", { className: "text-xs font-medium", children: [
"(",
i,
")"
] })
]
}
),
/* @__PURE__ */ r(
"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__ */ r(f, { className: "w-4 h-4" })
}
)
]
}
);
}), Dc = q("add");
function Tc(e, t) {
if (!t?.cubes) return null;
const [n] = e.split("."), s = t.cubes.find((a) => a.name === n);
return s && s.measures?.find((a) => a.name === e) || null;
}
function kc(e) {
switch (e) {
case null:
return "asc";
case "asc":
return "desc";
case "desc":
return null;
default:
return "asc";
}
}
const Ac = Ge(function({
metrics: t,
schema: n,
onAdd: s,
onRemove: a,
order: i,
onOrderChange: o,
onReorder: c
}) {
const [l, u] = ee(null), [h, f] = ee(null), m = ge(null), g = ge(null), b = V(() => i ? Object.keys(i) : [], [i]), N = V(() => t.map((k, S) => {
const $ = i?.[k.field] || null, D = $ ? b.indexOf(k.field) + 1 : void 0;
return {
metric: k,
fieldMeta: Tc(k.field, n),
sortDirection: $,
sortPriority: D,
index: S
};
}), [t, n, i, b]), x = ge(null), A = E((k, S) => {
u(S), m.current = S, k.dataTransfer.effectAllowed = "move", k.dataTransfer.setData("text/plain", JSON.stringify({ type: "metric", index: S, field: t[S].field }));
const $ = k.currentTarget, D = $.cloneNode(!0);
D.style.cssText = `
position: absolute;
top: -9999px;
left: -9999px;
width: ${$.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(D), x.current = D;
const F = $.getBoundingClientRect(), K = k.clientX - F.left, P = k.clientY - F.top;
k.dataTransfer.setDragImage(D, K, P);
}, [t]), w = E(() => {
u(null), f(null), m.current = null, g.current = null, x.current && (document.body.removeChild(x.current), x.current = null);
}, []), y = E((k, S) => {
k.preventDefault(), k.stopPropagation();
const $ = m.current;
if ($ === null) return;
const D = k.currentTarget.getBoundingClientRect();
let P = k.clientY - D.top < D.height / 2 ? S : S + 1;
P === $ || P === $ + 1 ? (f(null), g.current = null) : (f(P), g.current = P);
}, []), C = E((k) => {
k.preventDefault(), k.stopPropagation();
const S = m.current, $ = g.current;
if (u(null), f(null), m.current = null, g.current = null, S === null || $ === null || !c)
return;
const D = $ > S ? $ - 1 : $;
D !== S && c(S, D);
}, [c]), T = E((k) => {
const S = k.relatedTarget;
(!S || !k.currentTarget.contains(S)) && f(null);
}, []), p = E((k) => {
if (l === null || h === null) return "";
const S = 40;
if (k === l) return "";
if (l < h) {
if (k > l && k < h)
return "";
if (k === h - 1)
return `translateY(-${S / 2}px)`;
if (k >= h)
return `translateY(${S / 2}px)`;
} else if (k >= h && k < l)
return `translateY(${S / 2}px)`;
return "";
}, [l, h]), v = E((k) => l === null || h === null ? !1 : k === h, [l, h]);
return /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d(
"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__ */ r(dt, { children: "Metrics" }),
/* @__PURE__ */ r(Dc, { className: "w-5 h-5 text-dc-text-secondary group-hover:text-dc-primary transition-colors" })
]
}
),
/* @__PURE__ */ d(
"div",
{
className: "space-y-2",
onDragLeave: c ? T : void 0,
onDragOver: c ? (k) => k.preventDefault() : void 0,
onDrop: c ? C : void 0,
children: [
N.map(({ metric: k, fieldMeta: S, sortDirection: $, sortPriority: D, index: F }) => {
const K = p(F), P = v(F);
return /* @__PURE__ */ d(
"div",
{
className: "relative",
style: {
transform: K,
transition: l !== null ? "transform 0.15s ease-out" : "none"
},
onDragOver: c ? (te) => y(te, F) : void 0,
onDrop: c ? C : void 0,
children: [
P && /* @__PURE__ */ r("div", { className: "absolute -top-5 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ r("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }),
/* @__PURE__ */ r(
Sc,
{
metric: k,
fieldMeta: S,
onRemove: () => a(k.id),
sortDirection: $,
sortPriority: D,
onToggleSort: o ? () => {
const te = kc($);
o(k.field, te);
} : void 0,
index: F,
isDragging: l === F,
onDragStart: c ? A : void 0,
onDragEnd: c ? w : void 0
}
)
]
},
k.id
);
}),
c && l !== null && h === t.length && /* @__PURE__ */ r("div", { className: "relative h-2", children: /* @__PURE__ */ r("div", { className: "absolute top-0 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ r("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }) }),
c && t.length > 0 && l !== null && /* @__PURE__ */ r(
"div",
{
className: "h-8",
onDragOver: (k) => {
k.preventDefault();
const S = t.length, $ = m.current;
g.current !== S && $ !== S - 1 && (f(S), g.current = S);
},
onDrop: C
}
)
]
}
)
] });
}), Mc = [
{ value: "hour", label: "Hour" },
{ value: "day", label: "Day" },
{ value: "week", label: "Week" },
{ value: "month", label: "Month" },
{ value: "quarter", label: "Quarter" },
{ value: "year", label: "Year" }
], Qa = Ge(function({
breakdown: t,
fieldMeta: n,
onRemove: s,
onGranularityChange: a,
onComparisonToggle: i,
comparisonDisabled: o,
sortDirection: c,
sortPriority: l,
onToggleSort: u,
index: h,
isDragging: f,
onDragStart: m,
onDragEnd: g
}) {
const b = q("dimension"), N = q("timeDimension"), x = q("close"), A = q("chevronUp"), w = q("chevronDown"), y = q("chevronUpDown"), C = n?.shortTitle || n?.title || t.field.split(".").pop() || t.field, T = t.field.split(".")[0], p = t.isTimeDimension ? N : b, v = () => {
switch (c) {
case "asc":
return A ? /* @__PURE__ */ r(A, { className: "w-4 h-4" }) : "↑";
case "desc":
return w ? /* @__PURE__ */ r(w, { className: "w-4 h-4" }) : "↓";
default:
return y ? /* @__PURE__ */ r(y, { className: "w-4 h-4" }) : "⇅";
}
}, k = () => {
switch (c) {
case "asc":
return "Sorted ascending (click for descending)";
case "desc":
return "Sorted descending (click to remove)";
default:
return "Click to sort ascending";
}
}, S = typeof h == "number" && m && g;
return /* @__PURE__ */ d(
"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 ${S ? "cursor-grab active:cursor-grabbing" : ""} ${f ? "opacity-30" : ""}`,
draggable: S ? !0 : void 0,
onDragStart: S ? ($) => m($, h) : void 0,
onDragEnd: S ? g : void 0,
children: [
/* @__PURE__ */ r("span", { className: `w-6 h-6 flex items-center justify-center rounded flex-shrink-0 ${t.isTimeDimension ? "bg-dc-time-dimension text-dc-time-dimension-text" : "bg-dc-dimension text-dc-dimension-text"}`, children: /* @__PURE__ */ r(p, { className: "w-4 h-4" }) }),
/* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ r("div", { className: "text-sm text-dc-text truncate", title: t.field, children: C }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted truncate", children: T })
] }),
t.isTimeDimension && a && /* @__PURE__ */ r(
"select",
{
value: t.granularity || "day",
onChange: ($) => a($.target.value),
onClick: ($) => $.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: Mc.map(($) => /* @__PURE__ */ r("option", { value: $.value, children: $.label }, $.value))
}
),
t.isTimeDimension && i && /* @__PURE__ */ r(
"button",
{
onClick: ($) => {
$.stopPropagation(), i();
},
disabled: o && !t.enableComparison,
className: `text-xs px-2 py-1 rounded flex-shrink-0 transition-colors ${t.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"} ${o && !t.enableComparison ? "opacity-50 cursor-not-allowed" : ""}`,
title: o && !t.enableComparison ? "Another time dimension already has comparison enabled" : t.enableComparison ? "Click to disable comparison" : "Compare with previous period",
children: "vs prior"
}
),
u && /* @__PURE__ */ d(
"button",
{
onClick: u,
className: `p-1 transition-opacity flex-shrink-0 flex items-center gap-0.5 ${c ? "opacity-100 text-dc-primary" : "opacity-100 sm:opacity-0 sm:group-hover:opacity-100 text-dc-text-muted hover:text-dc-primary"}`,
title: k(),
children: [
v(),
c && l && /* @__PURE__ */ d("span", { className: "text-xs font-medium", children: [
"(",
l,
")"
] })
]
}
),
/* @__PURE__ */ r(
"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__ */ r(x, { className: "w-4 h-4" })
}
)
]
}
);
}), Ic = q("add");
function Ec(e, t) {
if (!t?.cubes) return null;
const [n] = e.split("."), s = t.cubes.find((a) => a.name === n);
return s && s.dimensions?.find((a) => a.name === e) || null;
}
function Fc(e) {
switch (e) {
case null:
return "asc";
case "asc":
return "desc";
case "desc":
return null;
default:
return "asc";
}
}
const Rc = Ge(function({
breakdowns: t,
schema: n,
onAdd: s,
onRemove: a,
onGranularityChange: i,
onComparisonToggle: o,
order: c,
onOrderChange: l,
onReorder: u
}) {
const [h, f] = ee(null), [m, g] = ee(null), b = ge(null), N = ge(null), x = V(() => c ? Object.keys(c) : [], [c]), A = V(() => t.find((F) => F.isTimeDimension && F.enableComparison)?.id || null, [t]), w = V(() => t.map((D, F) => {
const K = c?.[D.field] || null, P = K ? x.indexOf(D.field) + 1 : void 0;
return {
breakdown: D,
fieldMeta: Ec(D.field, n),
sortDirection: K,
sortPriority: P,
index: F
};
}), [t, n, c, x]), y = ge(null), C = E((D, F) => {
f(F), b.current = F, D.dataTransfer.effectAllowed = "move", D.dataTransfer.setData("text/plain", JSON.stringify({ type: "breakdown", index: F, field: t[F].field }));
const K = D.currentTarget, P = K.cloneNode(!0);
P.style.cssText = `
position: absolute;
top: -9999px;
left: -9999px;
width: ${K.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(P), y.current = P;
const te = K.getBoundingClientRect(), _ = D.clientX - te.left, O = D.clientY - te.top;
D.dataTransfer.setDragImage(P, _, O);
}, [t]), T = E(() => {
f(null), g(null), b.current = null, N.current = null, y.current && (document.body.removeChild(y.current), y.current = null);
}, []), p = E((D, F) => {
D.preventDefault(), D.stopPropagation();
const K = b.current;
if (K === null) return;
const P = D.currentTarget.getBoundingClientRect();
let O = D.clientY - P.top < P.height / 2 ? F : F + 1;
O === K || O === K + 1 ? (g(null), N.current = null) : (g(O), N.current = O);
}, []), v = E((D) => {
D.preventDefault(), D.stopPropagation();
const F = b.current, K = N.current;
if (f(null), g(null), b.current = null, N.current = null, F === null || K === null || !u)
return;
const P = K > F ? K - 1 : K;
P !== F && u(F, P);
}, [u]), k = E((D) => {
const F = D.relatedTarget;
(!F || !D.currentTarget.contains(F)) && g(null);
}, []), S = E((D) => {
if (h === null || m === null) return "";
const F = 40;
if (D === h) return "";
if (h < m) {
if (D > h && D < m)
return "";
if (D === m - 1)
return `translateY(-${F / 2}px)`;
if (D >= m)
return `translateY(${F / 2}px)`;
} else if (D >= m && D < h)
return `translateY(${F / 2}px)`;
return "";
}, [h, m]), $ = E((D) => h === null || m === null ? !1 : D === m, [h, m]);
return /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d(
"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__ */ r(dt, { children: "Breakdown" }),
/* @__PURE__ */ r(Ic, { className: "w-5 h-5 text-dc-text-secondary group-hover:text-dc-primary transition-colors" })
]
}
),
/* @__PURE__ */ d(
"div",
{
className: "space-y-2",
onDragLeave: u ? k : void 0,
onDragOver: u ? (D) => D.preventDefault() : void 0,
onDrop: u ? v : void 0,
children: [
w.map(({ breakdown: D, fieldMeta: F, sortDirection: K, sortPriority: P, index: te }) => {
const _ = S(te), O = $(te);
return /* @__PURE__ */ d(
"div",
{
className: "relative",
style: {
transform: _,
transition: h !== null ? "transform 0.15s ease-out" : "none"
},
onDragOver: u ? (ie) => p(ie, te) : void 0,
onDrop: u ? v : void 0,
children: [
O && /* @__PURE__ */ r("div", { className: "absolute -top-5 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ r("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }),
/* @__PURE__ */ r(
Qa,
{
breakdown: D,
fieldMeta: F,
onRemove: () => a(D.id),
onGranularityChange: D.isTimeDimension ? (ie) => i(D.id, ie) : void 0,
onComparisonToggle: D.isTimeDimension && o ? () => o(D.id) : void 0,
comparisonDisabled: A !== null && A !== D.id,
sortDirection: K,
sortPriority: P,
onToggleSort: l ? () => {
const ie = Fc(K);
l(D.field, ie);
} : void 0,
index: te,
isDragging: h === te,
onDragStart: u ? C : void 0,
onDragEnd: u ? T : void 0
}
)
]
},
D.id
);
}),
u && h !== null && m === t.length && /* @__PURE__ */ r("div", { className: "relative h-2", children: /* @__PURE__ */ r("div", { className: "absolute top-0 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ r("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }) }),
u && t.length > 0 && h !== null && /* @__PURE__ */ r(
"div",
{
className: "h-8",
onDragOver: (D) => {
D.preventDefault();
const F = t.length, K = b.current;
N.current !== F && K !== F - 1 && (g(F), N.current = F);
},
onDrop: v
}
)
]
}
)
] });
}), vs = q("close"), nr = q("chevronDown"), _c = q("dimension"), Oc = q("timeDimension"), $c = q("measure");
function Lc({
filter: e,
schema: t,
onSave: n,
onCancel: s,
anchorElement: a
}) {
const [i, o] = ee(e), [c, l] = ee(!1), [u, h] = ee(!1), [f, m] = ee(!1), [g, b] = ee("this_month"), [N, x] = ee(1), [A, w] = ee(""), [y, C] = ee(null), [T, p] = ee(-1), v = ge(null), k = ge(null), S = Ar(A, 300), $ = jn(i.member, t), D = $?.field.type || "string", F = D === "time", K = $?.fieldType === "measure", P = $?.fieldType === "dimension", te = _r(i.member, t), _ = qn[i.operator], O = mr(D), ie = F && i.operator === "inDateRange", X = E(() => ["equals", "notEquals", "in", "notIn"].includes(i.operator) && P && !F, [i.operator, P, F])(), {
values: ce,
loading: Q,
error: Se,
searchValues: L
} = Mr(i.member, X);
he(() => {
if (!a) {
C(null);
return;
}
const J = a.getBoundingClientRect(), fe = 500, ve = J.top, ke = window.innerHeight - J.bottom, Fe = 400, re = ve > fe || ve > ke, be = Math.max(16, Math.min(J.left, window.innerWidth - Fe - 16));
C(re ? {
bottom: window.innerHeight - J.top + 8,
left: be
} : {
top: J.bottom + 8,
left: be
});
}, [a]), he(() => {
const J = (fe) => {
v.current && !v.current.contains(fe.target) && (l(!1), h(!1), m(!1));
};
return document.addEventListener("mousedown", J), () => document.removeEventListener("mousedown", J);
}, []), he(() => {
u && X && L && L("", !0), u || p(-1);
}, [u, X, L]), he(() => {
if (T >= 0 && k.current) {
const J = k.current.children[T];
J && J.scrollIntoView({ block: "nearest" });
}
}, [T]), he(() => {
u && X && L && S !== void 0 && L(S);
}, [S, u, X, L]), he(() => {
if (!(!ie || !i.dateRange))
if (Array.isArray(i.dateRange))
b("custom");
else {
const J = i.dateRange.match(/^last (\d+) (days|weeks|months|quarters|years)$/), fe = !J && i.dateRange.match(/^last (day|week|month|quarter|year)$/);
if (J) {
const [, ve, ke] = J;
b(`last_n_${ke}`), x(parseInt(ve) || 1);
} else if (fe) {
const [, ve] = fe;
b(`last_n_${ve === "day" ? "days" : ve === "week" ? "weeks" : ve === "month" ? "months" : ve === "quarter" ? "quarters" : "years"}`), x(1);
} else {
let ve = !1;
for (const ke of Ht)
if (ke.value !== "custom" && !Ot(ke.value) && Dt(ke.value) === i.dateRange) {
b(ke.value), ve = !0;
break;
}
ve || b("custom");
}
}
}, [i.dateRange, ie]);
const pe = E((J) => {
o({
member: i.member,
operator: J,
values: []
}), l(!1);
}, [i.member]), z = E((J, fe) => {
const ve = fe?.shiftKey ?? !1, ke = i.values || [];
_?.supportsMultipleValues ? (ke.includes(J) ? o({ ...i, values: ke.filter((Fe) => Fe !== J) }) : o({ ...i, values: [...ke, J] }), ve || h(!1)) : (o({ ...i, values: [J] }), h(!1)), w(""), p(-1);
}, [i, _?.supportsMultipleValues]), H = E((J) => {
const fe = (i.values || []).filter((ve) => ve !== J);
o({ ...i, values: fe });
}, [i]), se = E((J) => {
if (!(!u || ce.length === 0))
switch (J.key) {
case "ArrowDown":
J.preventDefault(), p(
(fe) => fe < ce.length - 1 ? fe + 1 : 0
);
break;
case "ArrowUp":
J.preventDefault(), p(
(fe) => fe > 0 ? fe - 1 : ce.length - 1
);
break;
case "Enter":
J.preventDefault(), T >= 0 && T < ce.length && z(ce[T], { shiftKey: J.shiftKey });
break;
case "Escape":
J.preventDefault(), h(!1), p(-1);
break;
}
}, [u, ce, T, z]), me = E((J) => {
const fe = J.target.value;
if (_?.valueType === "number") {
const ve = parseFloat(fe);
isNaN(ve) ? (fe === "" || fe === "-") && o({ ...i, values: [] }) : o({ ...i, values: [ve] });
} else
o({ ...i, values: fe ? [fe] : [] });
}, [i, _?.valueType]), le = E((J) => {
const fe = parseFloat(J.target.value), ve = i.values?.length >= 2 ? i.values : ["", ""], ke = [isNaN(fe) ? "" : fe, ve[1]].filter((Fe) => Fe !== "");
o({ ...i, values: ke });
}, [i]), we = E((J) => {
const fe = parseFloat(J.target.value), ke = [(i.values?.length >= 2 ? i.values : ["", ""])[0], isNaN(fe) ? "" : fe].filter((Fe) => Fe !== "");
o({ ...i, values: ke });
}, [i]), Y = E((J) => {
const fe = J.target.value;
o({ ...i, values: fe ? [fe] : [] });
}, [i]), Pe = E((J) => {
b(J), m(!1);
let fe;
if (J === "custom") {
const ve = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
fe = [ve, ve];
} else Ot(J) ? fe = Dt(J, N) : fe = Dt(J);
o({ ...i, dateRange: fe });
}, [i, N]), He = E((J) => {
if (x(J), Ot(g)) {
const fe = Dt(g, J);
o({ ...i, dateRange: fe });
}
}, [i, g]), Ne = E((J) => {
const fe = J.target.value, ke = (Array.isArray(i.dateRange) ? i.dateRange : [i.dateRange || "", ""])[1] || fe;
o({ ...i, dateRange: [fe, ke] });
}, [i]), _e = E((J) => {
const fe = J.target.value, ke = (Array.isArray(i.dateRange) ? i.dateRange : ["", i.dateRange || ""])[0] || fe;
o({ ...i, dateRange: [ke, fe] });
}, [i]), We = O.find((J) => J.operator === i.operator)?.label || i.operator, Je = Ht.find((J) => J.value === g)?.label || "Select range", Ke = F ? Oc : K ? $c : _c, Oe = () => _?.requiresValues ? ie ? /* @__PURE__ */ d("div", { className: "space-y-2", children: [
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
onClick: () => {
l(!1), h(!1), m(!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__ */ r("span", { className: "truncate", children: Je }),
/* @__PURE__ */ r(nr, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-2 transition-transform ${f ? "rotate-180" : ""}` })
]
}
),
f && /* @__PURE__ */ r("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: Ht.map((J) => /* @__PURE__ */ r(
"button",
{
onClick: () => Pe(J.value),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover ${J.value === g ? "bg-dc-primary/10 text-dc-primary" : "text-dc-text"}`,
children: J.label
},
J.value
)) })
] }),
Ot(g) && /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "number",
min: "1",
max: "1000",
value: N,
onChange: (J) => He(Math.max(1, parseInt(J.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__ */ r("span", { className: "text-sm text-dc-text-muted", children: g.replace("last_n_", "") })
] }),
g === "custom" && /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "date",
value: Array.isArray(i.dateRange) ? i.dateRange[0] : "",
onChange: Ne,
className: "flex-1 text-sm border border-dc-border rounded px-2 py-2 bg-dc-surface text-dc-text"
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ r(
"input",
{
type: "date",
value: Array.isArray(i.dateRange) ? i.dateRange[1] : "",
onChange: _e,
className: "flex-1 text-sm border border-dc-border rounded px-2 py-2 bg-dc-surface text-dc-text"
}
)
] })
] }) : i.operator === "between" || i.operator === "notBetween" ? /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "number",
value: i.values?.[0] ?? "",
onChange: le,
placeholder: "Min",
className: "flex-1 text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ r(
"input",
{
type: "number",
value: i.values?.[1] ?? "",
onChange: we,
placeholder: "Max",
className: "flex-1 text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
)
] }) : _?.valueType === "date" ? /* @__PURE__ */ r(
"input",
{
type: "date",
value: i.values?.[0] || "",
onChange: Y,
className: "w-full text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
) : _?.valueType === "number" ? /* @__PURE__ */ r(
"input",
{
type: "number",
value: i.values?.[0] ?? "",
onChange: me,
placeholder: "Enter number",
className: "w-full text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
) : X ? /* @__PURE__ */ d("div", { className: "space-y-2", children: [
i.values && i.values.length > 0 && /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-1.5", children: i.values.map((J, fe) => /* @__PURE__ */ d(
"span",
{
className: "inline-flex items-center gap-1 bg-dc-primary/10 text-dc-primary text-sm px-2 py-1 rounded",
children: [
/* @__PURE__ */ r("span", { className: "max-w-[150px] truncate", children: String(J) }),
/* @__PURE__ */ r(
"button",
{
onClick: () => H(J),
className: "hover:text-dc-danger",
children: /* @__PURE__ */ r(vs, { className: "w-3.5 h-3.5" })
}
)
]
},
fe
)) }),
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
onClick: () => {
l(!1), m(!1), h(!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__ */ r("span", { className: "text-dc-text-muted truncate", children: Q ? "Loading..." : "Select value..." }),
/* @__PURE__ */ r(nr, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-2 transition-transform ${u ? "rotate-180" : ""}` })
]
}
),
u && /* @__PURE__ */ d("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__ */ r("div", { className: "p-2 border-b border-dc-border", children: /* @__PURE__ */ r(
"input",
{
type: "text",
value: A,
onChange: (J) => {
w(J.target.value), p(-1);
},
onKeyDown: se,
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__ */ r("div", { ref: k, className: "max-h-40 overflow-y-auto", children: Q ? /* @__PURE__ */ r("div", { className: "px-3 py-2 text-sm text-dc-text-muted", children: "Loading..." }) : Se ? /* @__PURE__ */ d("div", { className: "px-3 py-2 text-sm text-dc-error", children: [
"Error: ",
Se
] }) : ce.length === 0 ? /* @__PURE__ */ r("div", { className: "px-3 py-2 text-sm text-dc-text-muted", children: "No values found" }) : ce.map((J, fe) => {
const ve = i.values?.includes(J);
return /* @__PURE__ */ d(
"button",
{
onClick: (Fe) => z(J, Fe),
className: `w-full text-left px-3 py-2 text-sm transition-colors ${fe === T ? "bg-dc-surface-hover" : ""} ${ve ? "bg-dc-primary/10 text-dc-primary" : "text-dc-text hover:bg-dc-surface-hover"}`,
children: [
String(J),
ve && /* @__PURE__ */ r("span", { className: "float-right", children: "✓" })
]
},
`${J}-${fe}`
);
}) })
] })
] }),
_?.supportsMultipleValues && /* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted", children: "Hold Shift to select multiple values" })
] }) : /* @__PURE__ */ r(
"input",
{
type: "text",
value: i.values?.[0] ?? "",
onChange: me,
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__ */ r("div", { className: "text-sm text-dc-text-muted italic py-2", children: "No value required" });
return /* @__PURE__ */ r(Ce, { children: /* @__PURE__ */ r(
"div",
{
className: `fixed inset-0 bg-dc-overlay z-50 ${y ? "" : "flex items-center justify-center p-4"}`,
onClick: s,
children: /* @__PURE__ */ d(
"div",
{
ref: v,
className: y ? "bg-dc-surface rounded-lg border border-dc-border" : "bg-dc-surface rounded-lg border border-dc-border max-w-md w-full",
style: { ...y ? {
position: "fixed",
...y,
maxWidth: "400px",
width: "100%"
} : {}, boxShadow: "var(--dc-shadow-xl)" },
onClick: (J) => J.stopPropagation(),
children: [
/* @__PURE__ */ d("div", { className: "flex items-center justify-between p-4 border-b border-dc-border", children: [
/* @__PURE__ */ r("h2", { className: "text-lg font-semibold text-dc-text", children: "Edit Filter" }),
/* @__PURE__ */ r(
"button",
{
onClick: s,
className: "p-1 text-dc-text-muted hover:text-dc-text transition-colors",
children: /* @__PURE__ */ r(vs, { className: "w-5 h-5" })
}
)
] }),
/* @__PURE__ */ d("div", { className: "p-4 space-y-4", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("label", { className: "block text-sm font-medium text-dc-text-secondary mb-2", children: "Field" }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 p-3 bg-dc-surface-secondary rounded", children: [
/* @__PURE__ */ r(Ke, { className: "w-5 h-5 text-dc-filter-text" }),
/* @__PURE__ */ r("span", { className: "text-sm font-medium text-dc-text", children: te })
] })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("label", { className: "block text-sm font-medium text-dc-text-secondary mb-2", children: "Operator" }),
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
onClick: () => {
h(!1), m(!1), l(!c);
},
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__ */ r("span", { className: "truncate", children: We }),
/* @__PURE__ */ r(nr, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-2 transition-transform ${c ? "rotate-180" : ""}` })
]
}
),
c && /* @__PURE__ */ r("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: O.map((J) => /* @__PURE__ */ r(
"button",
{
onClick: () => pe(J.operator),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover ${J.operator === i.operator ? "bg-dc-primary/10 text-dc-primary" : "text-dc-text"}`,
children: J.label
},
J.operator
)) })
] })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("label", { className: "block text-sm font-medium text-dc-text-secondary mb-2", children: "Value" }),
Oe()
] })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center justify-end gap-2 p-4 border-t border-dc-border", children: [
/* @__PURE__ */ r(
"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__ */ r(
"button",
{
onClick: () => n(i),
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 ws = q("close"), Pc = q("dimension"), qc = q("timeDimension"), Bc = q("measure");
function ja({
filter: e,
schema: t,
onRemove: n,
onUpdate: s
}) {
const [a, i] = ee(!1), o = ge(null), c = jn(e.member, t), u = (c?.field.type || "string") === "time", h = c?.fieldType === "measure", f = _r(e.member, t), m = qn[e.operator], g = m?.label || e.operator, b = Qc(e, m), N = u ? qc : h ? Bc : Pc;
return /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ d(
"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__ */ r("span", { className: `w-6 h-6 flex items-center justify-center rounded ${u ? "bg-dc-time-dimension" : h ? "bg-dc-measure" : "bg-dc-dimension"} ${u ? "text-dc-time-dimension-text" : h ? "text-dc-measure-text" : "text-dc-dimension-text"} flex-shrink-0 mt-0.5`, children: N && /* @__PURE__ */ r(N, { className: "w-4 h-4" }) }),
/* @__PURE__ */ r(
"button",
{
ref: o,
onClick: () => i(!0),
className: "flex-1 min-w-0 text-left",
title: `${f} ${g} ${b}`,
children: /* @__PURE__ */ d("div", { className: "text-sm text-dc-text break-words", children: [
/* @__PURE__ */ r("span", { className: "font-medium", children: f }),
/* @__PURE__ */ r("span", { className: "text-dc-text-muted mx-1", children: g }),
/* @__PURE__ */ r("span", { className: "text-dc-primary", children: b })
] })
}
),
/* @__PURE__ */ r(
"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: ws && /* @__PURE__ */ r(ws, { className: "w-4 h-4" })
}
)
]
}
),
a && /* @__PURE__ */ r(
Lc,
{
filter: e,
schema: t,
onSave: (w) => {
s(w), i(!1);
},
onCancel: () => i(!1),
anchorElement: o.current
}
)
] });
}
function Qc(e, t) {
if (!t?.requiresValues)
return "";
if (e.dateRange)
return Array.isArray(e.dateRange) ? `${e.dateRange[0]} to ${e.dateRange[1]}` : e.dateRange;
const n = e.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 jc = q("add"), Kc = q("close");
function Vc(e) {
return "member" in e && typeof e.member == "string";
}
function Uc(e) {
return "type" in e && (e.type === "and" || e.type === "or");
}
function Ka({
group: e,
schema: t,
onUpdate: n,
onRemove: s,
onAddFilter: a,
depth: i = 0,
hideRemoveButton: o = !1
}) {
const [c, l] = ee(!1), u = ge(null);
he(() => {
const C = (T) => {
u.current && !u.current.contains(T.target) && l(!1);
};
return document.addEventListener("mousedown", C), () => document.removeEventListener("mousedown", C);
}, []);
const h = E(() => {
const C = e.type === "and" ? "or" : "and";
n({ ...e, type: C });
}, [e, n]), f = E((C, T) => {
const p = [...e.filters];
p[C] = T, n({ ...e, filters: p });
}, [e, n]), m = E((C) => {
const T = e.filters.filter((p, v) => v !== C);
T.length === 0 ? s() : T.length === 1 && i > 0 ? n({ ...e, filters: T }) : n({ ...e, filters: T });
}, [e, n, s, i]), g = E((C) => {
const T = { type: C, filters: [] };
n({ ...e, filters: [...e.filters, T] }), l(!1);
}, [e, n]), b = E(() => {
a([]), l(!1);
}, [a]), N = E((C) => (T = []) => {
a([C, ...T]);
}, [a]), x = () => i % 2 === 0 ? "border-dc-border" : "border-dc-border dark:border-dc-border", A = () => e.type === "and" ? "bg-dc-info-bg/50" : "bg-dc-warning-bg/50", w = e.filters.length, y = w === 1 ? "condition" : "conditions";
return /* @__PURE__ */ d("div", { className: `border ${x()} rounded-lg bg-dc-surface w-full`, children: [
/* @__PURE__ */ d("div", { className: `flex items-center justify-between px-2 py-1.5 border-b border-dc-border/50 rounded-t-lg ${A()}`, children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"button",
{
onClick: h,
className: `px-2 py-0.5 text-xs font-semibold rounded transition-colors ${e.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 ${e.type === "and" ? "OR" : "AND"}`,
children: e.type.toUpperCase()
}
),
/* @__PURE__ */ d("span", { className: "text-xs text-dc-text-muted", children: [
w,
" ",
y
] })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-1", children: [
/* @__PURE__ */ d("div", { className: "relative", ref: u, children: [
/* @__PURE__ */ r(
"button",
{
onClick: () => l(!c),
className: "p-1 text-dc-text-secondary hover:text-dc-primary hover:bg-dc-surface-hover rounded transition-colors",
title: "Add condition",
children: /* @__PURE__ */ r(jc, { className: "w-4 h-4" })
}
),
c && /* @__PURE__ */ d("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__ */ r(
"button",
{
onClick: b,
className: "w-full text-left px-3 py-1.5 text-xs text-dc-text hover:bg-dc-surface-hover",
children: "Add Filter"
}
),
/* @__PURE__ */ r(
"button",
{
onClick: () => g("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__ */ r(
"button",
{
onClick: () => g("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"
}
)
] })
] }),
!o && /* @__PURE__ */ r(
"button",
{
onClick: s,
className: "p-1 text-dc-text-muted hover:text-dc-danger transition-colors",
title: "Remove group",
children: /* @__PURE__ */ r(Kc, { className: "w-4 h-4" })
}
)
] })
] }),
/* @__PURE__ */ r("div", { className: "p-1.5 flex flex-wrap gap-2", children: e.filters.length === 0 ? /* @__PURE__ */ d("div", { className: "text-center py-3", children: [
/* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted mb-1", children: "No conditions in this group" }),
/* @__PURE__ */ r(
"button",
{
onClick: () => a([]),
className: "text-xs text-dc-primary hover:underline",
children: "Add a filter"
}
)
] }) : e.filters.map((C, T) => Vc(C) ? /* @__PURE__ */ r(
ja,
{
filter: C,
schema: t,
onUpdate: (p) => f(T, p),
onRemove: () => m(T)
},
`filter-${T}`
) : Uc(C) ? /* @__PURE__ */ r(
Ka,
{
group: C,
schema: t,
onUpdate: (p) => f(T, p),
onRemove: () => m(T),
onAddFilter: N(T),
depth: i + 1
},
`group-${T}`
) : null) })
] });
}
const Hc = q("add");
function Kn(e) {
return "member" in e && typeof e.member == "string";
}
function zt(e) {
return "type" in e && (e.type === "and" || e.type === "or");
}
function Va(e) {
let t = 0;
for (const n of e)
Kn(n) ? t++ : zt(n) && (t += Va(n.filters));
return t;
}
function Ua(e) {
const t = [];
for (const n of e)
Kn(n) ? t.push(n.member) : zt(n) && t.push(...Ua(n.filters));
return t;
}
function Ha(e, t, n) {
if (t.length === 0)
return e.length === 0 ? [n] : e.length === 1 && Kn(e[0]) ? [{ type: "and", filters: [e[0], n] }] : e.length === 1 && zt(e[0]) ? [{
...e[0],
filters: [...e[0].filters, n]
}] : [{ type: "and", filters: [...e, n] }];
const [s, ...a] = t, i = [...e], o = i[s];
return zt(o) && (a.length === 0 ? i[s] = {
...o,
filters: [...o.filters, n]
} : i[s] = {
...o,
filters: Ha(o.filters, a, n)
}), i;
}
function Qr({
filters: e,
schema: t,
onFiltersChange: n,
onFieldDropped: s,
dimensionsOnly: a = !1
}) {
const [i, o] = ee(!1), [c, l] = ee(!1), u = ge([]), h = Va(e), f = E((p) => {
p.preventDefault(), p.stopPropagation(), l(!0);
}, []), m = E((p) => {
p.preventDefault(), p.stopPropagation(), l(!1);
}, []), g = E((p) => {
p.preventDefault(), p.stopPropagation(), l(!1);
try {
const v = JSON.parse(p.dataTransfer.getData("text/plain"));
v.field && s && s(v.field);
} catch {
}
}, [s]), b = Ua(e), N = E(
(p, v, k) => {
const S = p.type === "time", $ = S ? "inDateRange" : "equals", D = {
member: p.name,
operator: $,
values: []
};
S && $ === "inDateRange" && (D.dateRange = Dt("this_month"));
const F = Ha(e, u.current, D);
n(F), o(!1), u.current = [];
},
[e, n]
), x = E(
(p, v) => {
const k = [...e];
k[p] = v, n(k);
},
[e, n]
), A = E(
(p) => {
const v = e.filter((k, S) => S !== p);
if (v.length === 1 && zt(v[0])) {
const k = v[0];
if (k.filters.length === 1) {
n([k.filters[0]]);
return;
}
}
n(v);
},
[e, n]
), w = E(() => {
n([]);
}, [n]), y = E(() => {
u.current = [], o(!0);
}, []), C = E((p) => (v = []) => {
u.current = [...p, ...v], o(!0);
}, []), T = (p, v, k = []) => {
const S = [...k, v];
return Kn(p) ? /* @__PURE__ */ r(
ja,
{
filter: p,
schema: t,
onUpdate: ($) => x(v, $),
onRemove: () => A(v)
},
`filter-${S.join("-")}`
) : zt(p) ? /* @__PURE__ */ r(
Ka,
{
group: p,
schema: t,
onUpdate: ($) => x(v, $),
onRemove: () => A(v),
onAddFilter: C(S),
hideRemoveButton: e.length === 1
},
`group-${S.join("-")}`
) : null;
};
return /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d(
"button",
{
onClick: y,
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__ */ d(dt, { children: [
"Filter",
h > 0 && /* @__PURE__ */ d("span", { className: "ml-1.5 text-xs font-normal text-dc-text-muted normal-case tracking-normal", children: [
"(",
h,
")"
] })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
h > 0 && /* @__PURE__ */ r(
"span",
{
role: "button",
tabIndex: 0,
onClick: (p) => {
p.stopPropagation(), w();
},
onKeyDown: (p) => {
(p.key === "Enter" || p.key === " ") && (p.stopPropagation(), w());
},
className: "text-xs text-dc-text-muted hover:text-dc-error underline cursor-pointer",
children: "Clear all"
}
),
/* @__PURE__ */ r(Hc, { className: "w-5 h-5 text-dc-text-secondary group-hover:text-dc-primary transition-colors" })
] })
]
}
),
/* @__PURE__ */ r(
"div",
{
onDragOver: s ? f : void 0,
onDragLeave: s ? m : void 0,
onDrop: s ? g : void 0,
className: `p-2 -mx-2 rounded-lg border-2 border-dashed transition-all ${c ? "border-dc-primary bg-dc-primary/5" : "border-transparent"}`,
children: e.length === 0 ? /* @__PURE__ */ r("p", { className: `text-sm ${c ? "text-dc-primary font-medium" : "text-dc-text-muted"}`, children: c ? "Drop to add filter" : "No filters applied" }) : /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-2", children: e.map((p, v) => T(p, v)) })
}
),
/* @__PURE__ */ r(
qr,
{
isOpen: i,
onClose: () => {
o(!1), u.current = [];
},
onSelect: N,
mode: a ? "dimensionFilter" : "filter",
schema: t,
selectedFields: b
}
)
] });
}
const zc = q("close"), Gc = q("dimension"), Wc = q("timeDimension"), Yc = q("measure");
function Jc({
config: e,
fields: t,
onDrop: n,
onRemove: s,
onDragStart: a,
onDragEnd: i,
onDragOver: o,
onReorder: c,
draggedItem: l,
getFieldMeta: u,
yAxisAssignment: h,
onYAxisAssignmentChange: f
}) {
const { key: m, label: g, description: b, mandatory: N, maxItems: x, emptyText: A } = e, [w, y] = ee(null), [C, T] = ee(!1), [p, v] = ee(!1), k = ge(null), S = ge(null), $ = ge(t);
$.current = t;
const D = ge(null), F = () => {
let L = t.length;
return l && l.fromAxis === m && (L = Math.max(0, t.length - 1)), !x || L < x;
}, K = () => {
let L = t.length;
return l && l.fromAxis === m && (L = Math.max(0, t.length - 1)), x && L >= x;
}, P = F(), te = K();
he(() => {
const L = () => {
y(null), D.current = null, T(!1), v(!1), k.current = null;
};
return document.addEventListener("dragend", L), () => {
document.removeEventListener("dragend", L);
};
}, []), he(() => {
l ? l.fromAxis !== m ? (v(!1), y(null), D.current = null) : l.fromAxis === m && l.fromIndex !== void 0 && T(!1) : (y(null), D.current = null, T(!1), v(!1));
}, [l, m]);
const _ = E((L, pe) => {
if (!l || l.fromAxis !== m || l.fromIndex === void 0) return;
L.preventDefault(), L.stopPropagation();
const z = L.currentTarget.getBoundingClientRect(), se = L.clientY - z.top < z.height / 2, me = l.fromIndex;
let le = se ? pe : pe + 1;
le === me || le === me + 1 ? (y(null), D.current = null) : (y(le), D.current = le, v(!0));
}, [l, m]), O = E((L) => {
L.preventDefault();
const pe = D.current;
if (!(l && l.fromAxis === m && l.fromIndex !== void 0 && pe !== null)) {
y(null), D.current = null, v(!1);
return;
}
L.stopPropagation();
const H = l.fromIndex, se = pe > H ? pe - 1 : pe;
c && se !== H && c(H, se, m), y(null), D.current = null, v(!1);
}, [l, m, c]), ie = E((L, pe) => {
const z = S.current;
if (z && k.current === pe) {
const H = z.getBoundingClientRect();
L.clientX >= H.left && L.clientX <= H.right && L.clientY >= H.top && L.clientY <= H.bottom || setTimeout(() => {
$.current.includes(pe) && s(pe, m);
}, 0);
}
k.current = null, y(null), D.current = null, v(!1), i?.(L);
}, [m, s, i]), X = E((L) => {
if (!l || l.fromAxis !== m || l.fromIndex === void 0 || w === null)
return "";
const pe = l.fromIndex, z = 40;
if (L === pe) return "";
if (pe < w) {
if (L >= w)
return `translateY(${z / 2}px)`;
} else if (L >= w && L < pe)
return `translateY(${z / 2}px)`;
return "";
}, [l, m, w]), ce = E((L) => !l || l.fromAxis !== m || w === null ? !1 : L === w, [l, m, w]), Q = (L) => {
const pe = L.split("."), z = pe[0] || L, H = pe[1] || L;
return {
title: H,
shortTitle: H,
cubeName: z,
type: "dimension"
// Default assumption
};
}, Se = (L) => {
if (L.type === "measure") {
const pe = on(L.measureType || "count") || Yc;
return /* @__PURE__ */ r("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-measure text-dc-measure-text flex-shrink-0", children: /* @__PURE__ */ r(pe, { className: "w-4 h-4" }) });
} else return L.type === "timeDimension" ? /* @__PURE__ */ r("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__ */ r(Wc, { className: "w-4 h-4" }) }) : /* @__PURE__ */ r("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-dimension text-dc-dimension-text flex-shrink-0", children: /* @__PURE__ */ r(Gc, { className: "w-4 h-4" }) });
};
return /* @__PURE__ */ d("div", { className: "mb-3", children: [
/* @__PURE__ */ d("div", { className: "mb-2", children: [
/* @__PURE__ */ d("h4", { className: "text-sm font-medium text-dc-text flex items-center", children: [
g,
N && /* @__PURE__ */ r("span", { className: "text-dc-error ml-1", children: "*" })
] }),
b && /* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted mt-0.5", children: b })
] }),
/* @__PURE__ */ r(
"div",
{
ref: S,
"data-axis-container": m,
className: `min-h-[48px] border-2 border-dashed rounded-lg p-2 transition-all duration-200 ${C && (P || x === 1) || p ? "shadow-sm border-solid" : te ? "bg-dc-surface-secondary" : "bg-dc-surface-secondary hover:bg-dc-surface-hover"}`,
style: {
borderColor: C && (P || x === 1) || p ? "var(--dc-primary)" : "var(--dc-border)",
backgroundColor: C && (P || x === 1) || p ? "rgba(var(--dc-primary-rgb), 0.1)" : void 0
},
onDragOver: (L) => {
if (l && l.fromAxis === m && l.fromIndex !== void 0)
return;
P || x === 1 ? (T(!0), o(L)) : (L.preventDefault(), L.dataTransfer.dropEffect = "none");
},
onDragLeave: (L) => {
const pe = L.currentTarget.getBoundingClientRect(), z = L.clientX < pe.left || L.clientX > pe.right || L.clientY < pe.top || L.clientY > pe.bottom, H = L.relatedTarget, se = H && !L.currentTarget.contains(H);
(z || se || L.currentTarget === L.target) && (T(!1), v(!1));
},
onDrop: (L) => {
if (l && l.fromAxis === m && l.fromIndex !== void 0)
return;
P || x === 1 ? n(L, m) : L.preventDefault(), T(!1), v(!1);
},
children: t.length === 0 ? /* @__PURE__ */ r("div", { className: "text-sm text-dc-text-muted text-center py-2", children: te ? "Maximum items reached" : A || "Drop fields here" }) : /* @__PURE__ */ d(
"div",
{
className: "space-y-2",
onDragOver: (L) => {
l && l.fromAxis === m && L.preventDefault();
},
onDrop: (L) => {
l && l.fromAxis === m && l.fromIndex !== void 0 && O(L);
},
children: [
t.map((L, pe) => {
const z = u ? u(L) : Q(L), H = l && l.field === L && l.fromAxis === m, se = X(pe), me = ce(pe);
return /* @__PURE__ */ d(
"div",
{
className: "relative",
style: {
transform: se,
transition: l && l.fromAxis === m ? "transform 0.15s ease-out" : "none"
},
children: [
me && /* @__PURE__ */ r("div", { className: "absolute -top-5 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ r("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }),
/* @__PURE__ */ d(
"div",
{
draggable: !0,
onDragStart: (le) => {
k.current = L, a(le, L, m, pe);
},
onDragEnd: (le) => ie(le, L),
onDragOver: (le) => _(le, pe),
onDrop: O,
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: [
Se(z),
/* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ r("div", { className: "text-sm text-dc-text truncate", title: L, children: z.shortTitle || z.title || L.split(".").pop() }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted truncate", children: z.cubeName })
] }),
e.enableDualAxis && f && /* @__PURE__ */ r(
"button",
{
type: "button",
onClick: (le) => {
le.stopPropagation();
const we = h?.[L] || "left";
f(L, we === "left" ? "right" : "left");
},
className: `px-1.5 py-0.5 text-xs font-medium rounded transition-colors flex-shrink-0 ${(h?.[L] || "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?.[L] || "left") === "left" ? "Left" : "Right"} (click to toggle)`,
children: (h?.[L] || "left") === "left" ? "L" : "R"
}
),
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: () => s(L, 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 ${g}`,
children: /* @__PURE__ */ r(zc, { className: "w-4 h-4" })
}
)
]
}
)
]
},
`${L}-${pe}`
);
}),
l && l.fromAxis === m && w === t.length && /* @__PURE__ */ r("div", { className: "relative h-2", children: /* @__PURE__ */ r("div", { className: "absolute top-0 left-0 right-0 flex items-center justify-center pointer-events-none z-10", children: /* @__PURE__ */ r("div", { className: "h-0.5 w-full bg-dc-primary rounded-full" }) }) }),
l && l.fromAxis === m && t.length > 1 && /* @__PURE__ */ r(
"div",
{
className: "h-6",
onDragOver: (L) => {
if (l.fromIndex !== void 0) {
L.preventDefault();
const pe = t.length;
D.current !== pe && l.fromIndex !== pe - 1 && (y(pe), D.current = pe, v(!0));
}
},
onDrop: O
}
)
]
}
)
}
),
N && t.length === 0 && /* @__PURE__ */ r("div", { className: "text-xs text-dc-error mt-1", children: "This field is required" })
] });
}
const En = {
bar: Di,
line: Si,
area: Ci,
pie: Ni,
scatter: wi,
bubble: vi,
radar: xi,
radialBar: bi,
treemap: yi,
table: gi,
activityGrid: pi,
kpiNumber: hi,
kpiDelta: mi,
kpiText: fi,
markdown: ui,
funnel: di,
sankey: ci,
sunburst: li
}, bn = {
activityGrid: "Activity Grid",
area: "Area Chart",
bar: "Bar Chart",
bubble: "Bubble Chart",
funnel: "Funnel 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",
sankey: "Sankey Chart",
scatter: "Scatter Plot",
sunburst: "Sunburst Chart",
table: "Data Table",
treemap: "TreeMap"
};
function Xc({
selectedType: e,
onTypeChange: t,
className: n = "",
compact: s = !1,
availability: a,
excludeTypes: i = []
}) {
const [o, c] = ee(!1), l = Object.entries(En).filter(([m]) => !i.includes(m)).sort((m, g) => {
const b = bn[m[0]] || m[0], N = bn[g[0]] || g[0];
return b.localeCompare(N);
}), h = En[e]?.icon, f = bn[e];
return /* @__PURE__ */ d("div", { className: `${n} relative`, children: [
/* @__PURE__ */ d(
"button",
{
type: "button",
onClick: () => c(!o),
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__ */ d("div", { className: "flex items-center space-x-2", children: [
h && /* @__PURE__ */ r(h, { className: "h-5 w-5 text-dc-text-secondary" }),
/* @__PURE__ */ r("span", { className: "text-sm font-medium text-dc-text", children: f })
] }),
/* @__PURE__ */ r(
"svg",
{
className: `h-4 w-4 text-dc-text-muted transform transition-transform ${o ? "rotate-180" : ""}`,
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor",
children: /* @__PURE__ */ r("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
}
)
]
}
),
o && /* @__PURE__ */ r("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__ */ r("div", { className: "p-2", children: /* @__PURE__ */ r("div", { className: `grid gap-1.5 ${s ? "grid-cols-2" : "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4"}`, children: l.map(([m, g]) => {
const b = g.icon, N = bn[m], x = e === m, A = g.description, w = g.useCase, y = a?.[m], C = y?.available ?? !0, T = y?.reason, p = !C && T ? T : [A, w].filter(Boolean).join(". ");
return /* @__PURE__ */ d(
"button",
{
type: "button",
onClick: () => {
C && (t(m), c(!1));
},
disabled: !C,
className: `
relative p-1.5 rounded border transition-colors duration-150
text-left group min-h-[30px] flex items-center justify-start
${C ? x ? "bg-dc-surface-secondary" : "bg-dc-surface hover:bg-dc-surface-hover" : "opacity-50 cursor-not-allowed bg-dc-surface"}
`,
style: {
borderColor: x && C ? "var(--dc-primary)" : "var(--dc-border)"
},
title: p,
children: [
/* @__PURE__ */ d("div", { className: "flex items-center space-x-1.5", children: [
b && /* @__PURE__ */ r(
b,
{
className: `h-4 w-4 shrink-0 ${C ? x ? "text-dc-text" : "text-dc-text-secondary" : "text-dc-text-muted"}`
}
),
/* @__PURE__ */ r(
"span",
{
className: `text-xs font-medium leading-tight truncate ${C ? x ? "" : "text-dc-text" : "text-dc-text-muted"}`,
style: x && C ? { color: "var(--dc-primary)" } : void 0,
children: N
}
)
] }),
x && C && /* @__PURE__ */ r("div", { className: "absolute top-0.5 right-0.5", children: /* @__PURE__ */ r("div", { className: "w-1.5 h-1.5 rounded-full", style: { backgroundColor: "var(--dc-primary)" } }) })
]
},
m
);
}) }) }) })
] });
}
const Zc = q("measure"), ed = q("dimension"), td = q("timeDimension");
function nd({
chartType: e,
chartConfig: t,
metrics: n,
breakdowns: s,
schema: a,
chartAvailability: i,
onChartTypeChange: o,
onChartConfigChange: c
}) {
const [l, u] = ee(null), h = V(
() => ({
measures: n.map((D) => D.field),
dimensions: s.filter((D) => !D.isTimeDimension).map((D) => D.field),
timeDimensions: s.filter((D) => D.isTimeDimension).map((D) => D.field)
}),
[n, s]
), f = V(
() => ua(e, En),
[e]
), m = f.skipQuery === !0, g = E((D) => {
const F = t[D];
return Array.isArray(F) ? F : typeof F == "string" ? [F] : [];
}, [t]);
he(() => {
const D = [
...h.dimensions,
...h.timeDimensions,
...h.measures
];
let F = !1;
const K = { ...t };
f.dropZones.forEach((P) => {
const te = g(P.key), _ = te.filter((O) => D.includes(O));
_.length !== te.length && (F = !0, _.length === 0 ? delete K[P.key] : P.maxItems === 1 ? K[P.key] = _[0] : K[P.key] = _);
}), F && c(K);
}, [h, t, f.dropZones, c, g]);
const b = (D) => h.measures.includes(D) ? "measure" : h.timeDimensions.includes(D) ? "timeDimension" : "dimension", N = (D) => {
if (!a?.cubes) return null;
const [F] = D.split("."), K = a.cubes.find((_) => _.name === F);
if (!K) return null;
const P = K.measures?.find((_) => _.name === D);
if (P) return { ...P, fieldType: "measure" };
const te = K.dimensions?.find((_) => _.name === D);
return te ? { ...te, fieldType: te.type === "time" ? "timeDimension" : "dimension" } : null;
}, x = (D) => {
const F = b(D), K = D.split("."), P = K[0] || D, te = K[1] || D, _ = N(D), O = s.find((ie) => ie.field === D);
return _ ? {
title: _.title || te,
shortTitle: _.shortTitle || _.title || te,
cubeName: P,
type: _.fieldType,
measureType: _.fieldType === "measure" ? _.type : void 0
} : O ? {
title: te,
shortTitle: te,
cubeName: P,
type: O.isTimeDimension ? "timeDimension" : "dimension"
} : {
title: te,
shortTitle: te,
cubeName: P,
type: F
};
}, A = (D, F, K, P) => {
D.dataTransfer.setData("text/plain", JSON.stringify({ field: F, fromAxis: K, fromIndex: P })), u({ field: F, fromAxis: K, fromIndex: P });
}, w = (D) => {
D.preventDefault();
}, y = () => {
u(null);
}, C = (D, F) => {
D.preventDefault();
const K = JSON.parse(D.dataTransfer.getData("text/plain")), { field: P, fromAxis: te } = K, _ = { ...t };
if (te !== "available" && te !== F) {
const X = _[te];
if (Array.isArray(X)) {
const ce = X.filter((Q) => Q !== P);
ce.length === 0 ? delete _[te] : _[te] = ce;
} else X === P && delete _[te];
}
const O = _[F], ie = f.dropZones.find((X) => X.key === F);
if (ie?.maxItems === 1 ? _[F] = P : Array.isArray(O) ? O.includes(P) || (_[F] = [...O, P]) : _[F] = [P], F === "yAxis" && ie?.enableDualAxis) {
const ce = (Array.isArray(_.yAxis) ? _.yAxis : [P]).indexOf(P);
_.yAxisAssignment?.[P] || (_.yAxisAssignment = {
..._.yAxisAssignment,
[P]: ce === 1 ? "right" : "left"
});
}
u(null), c(_);
}, T = (D, F) => {
const K = { ...t }, P = K[F];
if (Array.isArray(P)) {
const te = P.filter((_) => _ !== D);
te.length === 0 ? delete K[F] : K[F] = te;
} else P === D && delete K[F];
if (F === "yAxis" && K.yAxisAssignment?.[D]) {
const { [D]: te, ..._ } = K.yAxisAssignment;
K.yAxisAssignment = Object.keys(_).length > 0 ? _ : void 0;
}
c(K);
}, p = (D, F, K) => {
const P = { ...t }, te = P[K];
if (Array.isArray(te) && te.length > 1 && D !== F) {
const _ = [...te], [O] = _.splice(D, 1);
_.splice(F, 0, O), P[K] = _, u(null), c(P);
}
}, v = E(
(D, F) => {
c({
...t,
yAxisAssignment: {
...t.yAxisAssignment,
[D]: F
}
});
},
[t, c]
), S = (() => {
const D = /* @__PURE__ */ new Set();
return f.dropZones.forEach((F) => {
g(F.key).forEach((K) => D.add(K));
}), l && l.fromAxis !== "available" && D.add(l.field), {
dimensions: h.dimensions.filter((F) => !D.has(F)),
timeDimensions: h.timeDimensions.filter((F) => !D.has(F)),
measures: h.measures.filter((F) => !D.has(F))
};
})(), $ = S.dimensions.length > 0 || S.timeDimensions.length > 0 || S.measures.length > 0;
return /* @__PURE__ */ d("div", { className: "space-y-6", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r(dt, { className: "mb-2", children: "Chart Type" }),
/* @__PURE__ */ r(
Xc,
{
selectedType: e,
onTypeChange: o,
availability: i,
excludeTypes: ["funnel"],
compact: !0
}
)
] }),
!m && f.dropZones.length > 0 && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r(dt, { className: "mb-2", children: "Chart Configuration" }),
/* @__PURE__ */ r("div", { className: "space-y-1", children: f.dropZones.map((D) => /* @__PURE__ */ r(
Jc,
{
config: D,
fields: g(D.key),
onDrop: C,
onRemove: T,
onDragStart: A,
onDragEnd: y,
onDragOver: w,
onReorder: p,
draggedItem: l,
getFieldMeta: x,
yAxisAssignment: t.yAxisAssignment,
onYAxisAssignmentChange: D.enableDualAxis ? v : void 0
},
D.key
)) })
] }),
!m && $ && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d("div", { className: "mb-2", children: [
/* @__PURE__ */ r(dt, { children: "Unassigned Fields" }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted mt-0.5", children: "Drag fields to chart axes above" })
] }),
/* @__PURE__ */ r("div", { className: "border-2 border-dashed border-dc-border rounded-lg p-2 bg-dc-surface-secondary", children: /* @__PURE__ */ d("div", { className: "space-y-2", children: [
S.measures.map((D) => {
const F = x(D), K = l && l.field === D && l.fromAxis === "available", P = on(F.measureType || "count") || Zc;
return /* @__PURE__ */ d(
"div",
{
draggable: !0,
onDragStart: (te) => A(te, D, "available"),
onDragEnd: y,
className: `flex items-center gap-2 p-2 bg-dc-surface rounded-lg hover:bg-dc-surface-tertiary transition-colors cursor-move ${K ? "opacity-50 cursor-grabbing" : ""}`,
title: D,
children: [
/* @__PURE__ */ r("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-measure text-dc-measure-text flex-shrink-0", children: /* @__PURE__ */ r(P, { className: "w-4 h-4" }) }),
/* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ r("div", { className: "text-sm text-dc-text truncate", children: F.shortTitle }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted truncate", children: F.cubeName })
] })
]
},
D
);
}),
S.dimensions.map((D) => {
const F = x(D), K = l && l.field === D && l.fromAxis === "available";
return /* @__PURE__ */ d(
"div",
{
draggable: !0,
onDragStart: (P) => A(P, D, "available"),
onDragEnd: y,
className: `flex items-center gap-2 p-2 bg-dc-surface rounded-lg hover:bg-dc-surface-tertiary transition-colors cursor-move ${K ? "opacity-50 cursor-grabbing" : ""}`,
title: D,
children: [
/* @__PURE__ */ r("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-dimension text-dc-dimension-text flex-shrink-0", children: /* @__PURE__ */ r(ed, { className: "w-4 h-4" }) }),
/* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ r("div", { className: "text-sm text-dc-text truncate", children: F.shortTitle }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted truncate", children: F.cubeName })
] })
]
},
D
);
}),
S.timeDimensions.map((D) => {
const F = x(D), K = l && l.field === D && l.fromAxis === "available";
return /* @__PURE__ */ d(
"div",
{
draggable: !0,
onDragStart: (P) => A(P, D, "available"),
onDragEnd: y,
className: `flex items-center gap-2 p-2 bg-dc-surface rounded-lg hover:bg-dc-surface-tertiary transition-colors cursor-move ${K ? "opacity-50 cursor-grabbing" : ""}`,
title: D,
children: [
/* @__PURE__ */ r("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__ */ r(td, { className: "w-4 h-4" }) }),
/* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ r("div", { className: "text-sm text-dc-text truncate", children: F.shortTitle }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-muted truncate", children: F.cubeName })
] })
]
},
D
);
})
] }) })
] }),
!m && h.measures.length === 0 && h.dimensions.length === 0 && h.timeDimensions.length === 0 && /* @__PURE__ */ r("div", { className: "text-center text-dc-text-muted text-sm py-4", children: /* @__PURE__ */ r("p", { children: "Add metrics and breakdowns in the Query tab to configure your chart." }) })
] });
}
function rd({
label: e,
value: t,
onChange: n,
placeholder: s,
description: a
}) {
const [i, o] = ee(() => t.join(`
`));
he(() => {
const l = t.join(`
`);
o(l);
}, [t]);
const c = E(() => {
const l = i.split(`
`).map((u) => u.trim()).filter((u) => u.length > 0);
n(l);
}, [i, n]);
return /* @__PURE__ */ d("div", { className: "space-y-1", children: [
/* @__PURE__ */ r("label", { className: "text-sm text-dc-text-secondary", children: e }),
/* @__PURE__ */ r(
"textarea",
{
value: i,
onChange: (l) => o(l.target.value),
onBlur: c,
placeholder: s,
rows: 4,
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 resize-y"
}
),
a && /* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted", children: a })
] });
}
function jr({
chartType: e,
displayConfig: t,
colorPalette: n,
onDisplayConfigChange: s
}) {
const a = V(
() => ua(e, En),
[e]
);
return a.displayOptions && a.displayOptions.length > 0 || a.displayOptionsConfig && a.displayOptionsConfig.length > 0 ? /* @__PURE__ */ r("div", { className: "space-y-6", children: /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r(dt, { className: "mb-2", children: "Display Options" }),
/* @__PURE__ */ d("div", { className: "space-y-2", children: [
a.displayOptions?.includes("showLegend") && /* @__PURE__ */ d("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "checkbox",
checked: t.showLegend ?? !0,
onChange: (o) => s({
...t,
showLegend: o.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text", children: "Show Legend" })
] }),
a.displayOptions?.includes("showGrid") && /* @__PURE__ */ d("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "checkbox",
checked: t.showGrid ?? !0,
onChange: (o) => s({
...t,
showGrid: o.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text", children: "Show Grid" })
] }),
a.displayOptions?.includes("showTooltip") && /* @__PURE__ */ d("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "checkbox",
checked: t.showTooltip ?? !0,
onChange: (o) => s({
...t,
showTooltip: o.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text", children: "Show Tooltip" })
] }),
a.displayOptions?.includes("stacked") && /* @__PURE__ */ d("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "checkbox",
checked: t.stacked ?? !1,
onChange: (o) => s({
...t,
stacked: o.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text", children: "Stacked" })
] }),
a.displayOptions?.includes("hideHeader") && /* @__PURE__ */ d("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "checkbox",
checked: t.hideHeader ?? !1,
onChange: (o) => s({
...t,
hideHeader: o.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text", children: "Hide Header" })
] }),
a.displayOptionsConfig?.map((o) => /* @__PURE__ */ d("div", { className: `space-y-1 ${o.type === "axisFormat" ? "mt-6 pt-2" : ""}`, children: [
o.type === "boolean" && /* @__PURE__ */ d("label", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "checkbox",
checked: t[o.key] ?? o.defaultValue ?? !1,
onChange: (c) => s({
...t,
[o.key]: c.target.checked
}),
className: "rounded border-dc-border focus:ring-dc-accent",
style: { color: "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text", children: o.label })
] }),
o.type === "string" && /* @__PURE__ */ d("div", { className: "space-y-1", children: [
/* @__PURE__ */ d("label", { className: "text-sm text-dc-text-secondary", children: [
o.label,
o.key === "content" && /* @__PURE__ */ r("span", { className: "text-xs text-dc-text-muted ml-1", children: "(only headers, lists and links)" })
] }),
o.key === "content" ? /* @__PURE__ */ r(
"textarea",
{
value: t[o.key] ?? o.defaultValue ?? "",
onChange: (c) => s({
...t,
[o.key]: c.target.value
}),
placeholder: o.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__ */ r(
"input",
{
type: "text",
value: t[o.key] ?? o.defaultValue ?? "",
onChange: (c) => s({
...t,
[o.key]: c.target.value
}),
placeholder: o.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"
}
),
o.description && /* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted", children: o.description })
] }),
o.type === "paletteColor" && /* @__PURE__ */ d("div", { className: "space-y-1", children: [
/* @__PURE__ */ r("label", { className: "text-sm text-dc-text-secondary", children: o.label }),
/* @__PURE__ */ r("div", { className: "flex flex-wrap gap-2", children: n?.colors.map((c, l) => {
const u = (t[o.key] ?? o.defaultValue ?? 0) === l;
return /* @__PURE__ */ r(
"button",
{
type: "button",
onClick: () => s({
...t,
[o.key]: l
}),
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 ${u ? "ring-2 ring-offset-1 scale-110" : "hover:border-dc-text-muted"}`,
style: {
backgroundColor: c,
borderColor: u ? "var(--dc-primary)" : "var(--dc-border)"
},
title: `Color ${l + 1}: ${c}`
},
l
);
}) || [
// Fallback if no palette available
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: () => s({
...t,
[o.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
)
] }),
o.description && /* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted", children: o.description })
] }),
o.type === "number" && /* @__PURE__ */ d("div", { className: "space-y-1", children: [
/* @__PURE__ */ r("label", { className: "text-sm text-dc-text-secondary", children: o.label }),
/* @__PURE__ */ r(
"input",
{
type: "number",
value: t[o.key] ?? o.defaultValue ?? 0,
onChange: (c) => s({
...t,
[o.key]: c.target.value === "" ? void 0 : Number(c.target.value)
}),
placeholder: o.placeholder,
min: o.min,
max: o.max,
step: o.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"
}
),
o.description && /* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted", children: o.description })
] }),
o.type === "select" && /* @__PURE__ */ d("div", { className: "space-y-1", children: [
/* @__PURE__ */ r("label", { className: "text-sm text-dc-text-secondary", children: o.label }),
/* @__PURE__ */ r(
"select",
{
value: t[o.key] ?? o.defaultValue ?? "",
onChange: (c) => s({
...t,
[o.key]: c.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: o.options?.map((c) => /* @__PURE__ */ r("option", { value: c.value, children: c.label }, c.value))
}
),
o.description && /* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted", children: o.description })
] }),
o.type === "color" && /* @__PURE__ */ d("div", { className: "space-y-1", children: [
/* @__PURE__ */ r("label", { className: "text-sm text-dc-text-secondary", children: o.label }),
/* @__PURE__ */ d("div", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "color",
value: t[o.key] ?? o.defaultValue ?? "#8884d8",
onChange: (c) => s({
...t,
[o.key]: c.target.value
}),
className: "w-12 h-8 border border-dc-border rounded-sm cursor-pointer"
}
),
/* @__PURE__ */ r(
"input",
{
type: "text",
value: t[o.key] ?? o.defaultValue ?? "#8884d8",
onChange: (c) => s({
...t,
[o.key]: c.target.value
}),
placeholder: o.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"
}
)
] }),
o.description && /* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted", children: o.description })
] }),
o.type === "axisFormat" && /* @__PURE__ */ r(
Ti,
{
axisLabel: o.label,
value: t[o.key] || {},
onChange: (c) => s({
...t,
[o.key]: Object.keys(c).length > 0 ? c : void 0
})
}
),
o.type === "stringArray" && /* @__PURE__ */ r(
rd,
{
label: o.label,
value: t[o.key] ?? [],
onChange: (c) => s({
...t,
[o.key]: c.length > 0 ? c : void 0
}),
placeholder: o.placeholder,
description: o.description
}
),
o.type === "buttonGroup" && /* @__PURE__ */ d("div", { className: "space-y-1", children: [
/* @__PURE__ */ r("label", { className: "text-sm text-dc-text-secondary", children: o.label }),
/* @__PURE__ */ r("div", { className: "flex border border-dc-border rounded-sm overflow-hidden", children: o.options?.map((c) => {
const l = (t[o.key] ?? o.defaultValue) === c.value;
return /* @__PURE__ */ r(
"button",
{
type: "button",
onClick: () => s({
...t,
[o.key]: c.value
}),
className: `flex-1 px-3 py-1.5 text-sm font-medium transition-colors ${l ? "bg-dc-primary text-white" : "bg-dc-surface text-dc-text hover:bg-dc-border"}`,
children: c.label
},
c.value
);
}) }),
o.description && /* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted", children: o.description })
] })
] }, o.key))
] })
] }) }) : /* @__PURE__ */ r("div", { className: "text-center text-dc-text-muted text-sm py-4", children: /* @__PURE__ */ r("p", { children: "No display options available for this chart type." }) });
}
function sd(e, t) {
const n = [];
if (!t?.cubes)
return n;
if (typeof e.dimension == "string") {
const [s, a] = e.dimension.split("."), i = t.cubes.find((o) => o.name === s);
i ? i.dimensions?.find((c) => c.name === e.dimension) || n.push({
type: "binding_key",
message: `Dimension "${a}" not found in cube "${s}"`
}) : n.push({
type: "binding_key",
message: `Cube "${s}" not found for binding key`
});
} else
for (const s of e.dimension) {
const a = t.cubes.find((i) => i.name === s.cube);
a ? a.dimensions?.find((o) => o.name === s.dimension) || n.push({
type: "cross_cube",
message: `Dimension "${s.dimension}" not found in cube "${s.cube}"`
}) : n.push({
type: "cross_cube",
message: `Cube "${s.cube}" not found for binding key mapping`
});
}
return n;
}
function ad(e) {
const t = [];
for (let n = 0; n < e.length; n++) {
const s = e[n], a = s.query;
a.measures && a.measures.length > 0 || a.dimensions && a.dimensions.length > 0 || a.timeDimensions && a.timeDimensions.length > 0 || t.push({
type: "step_query",
message: `Step ${n + 1} "${s.name}" has no measures, dimensions, or time dimensions`,
stepIndex: n
});
}
return t;
}
function id(e, t) {
if (typeof e.dimension == "string")
return !0;
const n = oa(t);
return n ? e.dimension.some((s) => s.cube === n) : !1;
}
function od(e, t) {
const n = [];
for (let s = 0; s < t.length; s++) {
const a = t[s];
if (!id(e, a.query)) {
const i = oa(a.query) || "unknown";
n.push({
type: "cross_cube",
message: `Step ${s + 1} uses cube "${i}" but no binding key mapping exists for it`,
stepIndex: s
});
}
}
return n;
}
function Ns(e) {
return e ? /^P(?:\d+Y)?(?:\d+M)?(?:\d+W)?(?:\d+D)?(?:T(?:\d+H)?(?:\d+M)?(?:\d+S)?)?$/.test(e) ? null : {
type: "time_window",
message: `Invalid time window format "${e}". Expected ISO 8601 duration (e.g., P7D, PT1H)`
} : null;
}
function af(e, t) {
const n = [], s = [];
e.steps.length < 2 && n.push({
type: "general",
message: "Funnel requires at least 2 steps"
}), e.bindingKey?.dimension ? (n.push(...sd(e.bindingKey, t)), n.push(...od(e.bindingKey, e.steps))) : n.push({
type: "binding_key",
message: "Binding key dimension is required"
}), n.push(...ad(e.steps));
for (let i = 0; i < e.steps.length; i++) {
const o = e.steps[i], c = Ns(o.timeToConvert);
c && (c.stepIndex = i, n.push(c));
}
const a = Ns(e.globalTimeWindow);
return a && n.push(a), e.steps.length > 5 && s.push({
type: "general",
message: "Funnels with more than 5 steps may have reduced performance"
}), {
isValid: n.length === 0,
errors: n,
warnings: s
};
}
function of(e, t) {
return t < 2 ? { isValid: !1, message: "Add at least 2 steps for funnel" } : e?.dimension ? typeof e.dimension == "string" && !e.dimension ? { isValid: !1, message: "Select a binding key dimension" } : Array.isArray(e.dimension) && e.dimension.length === 0 ? { isValid: !1, message: "Select a binding key dimension" } : { isValid: !0 } : { isValid: !1, message: "Select a binding key dimension" };
}
function Kr(e) {
if (!e?.cubes) return [];
const t = [];
for (const n of e.cubes)
if (n.dimensions)
for (const s of n.dimensions)
(s.type === "string" || s.type === "number") && t.push({
cube: n.name,
dimension: s.name,
label: s.title || s.shortTitle || s.name.split(".")[1] || s.name
});
return t;
}
function ld(e) {
if (!e?.dimension) return "Select binding key...";
if (typeof e.dimension == "string")
return e.dimension.split(".")[1] || e.dimension;
if (e.dimension.length > 0) {
const t = e.dimension[0];
return `${t.dimension.split(".")[1] || t.dimension} (${e.dimension.length} cubes)`;
}
return "Select binding key...";
}
const Cs = q("chevronDown"), Ss = q("check"), Ds = q("search"), cd = Ge(function({
bindingKey: t,
onChange: n,
schema: s,
disabled: a = !1,
className: i = ""
}) {
const [o, c] = ee(!1), [l, u] = ee(""), h = ge(null), f = ge(null), m = V(() => Kr(s), [s]), g = V(() => {
const C = {};
for (const T of m)
C[T.cube] || (C[T.cube] = []), C[T.cube].push(T);
return C;
}, [m]), b = V(() => {
if (!l.trim()) return g;
const C = l.toLowerCase(), T = {};
for (const [p, v] of Object.entries(g)) {
const k = v.filter(
(S) => S.label.toLowerCase().includes(C) || S.dimension.toLowerCase().includes(C) || p.toLowerCase().includes(C)
);
k.length > 0 && (T[p] = k);
}
return T;
}, [g, l]), N = E(
(C) => {
n({ dimension: C }), c(!1), u("");
},
[n]
), x = E(
(C) => {
C.stopPropagation(), n(null);
},
[n]
);
he(() => {
function C(T) {
h.current && !h.current.contains(T.target) && (c(!1), u(""));
}
if (o)
return document.addEventListener("mousedown", C), () => document.removeEventListener("mousedown", C);
}, [o]), he(() => {
o && f.current && f.current.focus();
}, [o]);
const A = E(
(C) => t ? typeof t.dimension == "string" ? t.dimension === C : t.dimension.some((T) => T.dimension === C) : !1,
[t]
), w = ld(t), y = t?.dimension !== null && t?.dimension !== void 0;
return /* @__PURE__ */ r("div", { className: i, children: /* @__PURE__ */ d("div", { ref: h, className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
type: "button",
onClick: () => !a && c(!o),
disabled: a,
className: `
flex items-center justify-between w-full px-2 py-1 text-xs
bg-dc-surface border border-dc-border rounded
transition-colors
${a ? "opacity-50 cursor-not-allowed" : "hover:border-dc-primary cursor-pointer"}
${o ? "border-dc-primary ring-1 ring-dc-primary" : ""}
`,
children: [
/* @__PURE__ */ r("span", { className: `truncate ${y ? "text-dc-text" : "text-dc-text-muted"}`, children: w }),
/* @__PURE__ */ d("span", { className: "flex items-center gap-1", children: [
y && /* @__PURE__ */ r(
"span",
{
role: "button",
tabIndex: 0,
onClick: x,
onKeyDown: (C) => C.key === "Enter" && x(C),
className: "p-0.5 rounded hover:bg-dc-surface-hover text-dc-text-muted hover:text-dc-text",
title: "Clear binding key",
children: "×"
}
),
Cs && /* @__PURE__ */ r(
Cs,
{
className: `w-4 h-4 text-dc-text-muted transition-transform ${o ? "rotate-180" : ""}`
}
)
] })
]
}
),
o && /* @__PURE__ */ d("div", { className: "absolute z-50 mt-1 right-0 w-[280px] bg-dc-surface border border-dc-border rounded-md shadow-lg", children: [
/* @__PURE__ */ r("div", { className: "p-2 border-b border-dc-border", children: /* @__PURE__ */ d("div", { className: "relative", children: [
Ds && /* @__PURE__ */ r(Ds, { className: "absolute left-2 top-1/2 -translate-y-1/2 w-4 h-4 text-dc-text-muted" }),
/* @__PURE__ */ r(
"input",
{
ref: f,
type: "text",
value: l,
onChange: (C) => u(C.target.value),
placeholder: "Search dimensions...",
className: "w-full pl-8 pr-3 py-1.5 text-sm bg-dc-surface-secondary border border-dc-border rounded text-dc-text placeholder:text-dc-text-muted focus:outline-none focus:ring-1 focus:ring-dc-primary"
}
)
] }) }),
/* @__PURE__ */ r("div", { className: "max-h-64 overflow-y-auto p-1", children: Object.entries(b).length === 0 ? /* @__PURE__ */ r("div", { className: "px-3 py-4 text-sm text-dc-text-muted text-center", children: "No matching dimensions found" }) : Object.entries(b).map(([C, T]) => /* @__PURE__ */ d("div", { className: "mb-2 last:mb-0", children: [
/* @__PURE__ */ r("div", { className: "px-2 py-1 text-xs font-medium text-dc-text-muted uppercase tracking-wide", children: C }),
T.map((p) => /* @__PURE__ */ d(
"button",
{
onClick: () => N(p.dimension),
className: `
flex items-center justify-between w-full px-3 py-1.5 text-sm
rounded transition-colors
${A(p.dimension) ? "bg-dc-primary-bg text-dc-primary" : "text-dc-text hover:bg-dc-surface-hover"}
`,
children: [
/* @__PURE__ */ r("span", { children: p.label }),
A(p.dimension) && Ss && /* @__PURE__ */ r(Ss, { className: "w-4 h-4" })
]
},
p.dimension
))
] }, C)) }),
/* @__PURE__ */ r("div", { className: "px-3 py-2 border-t border-dc-border text-xs text-dc-text-muted", children: "Select a dimension that identifies entities across funnel steps (e.g., user ID, order ID)" })
] })
] }) });
}), dd = q("chartBar"), ud = q("chartFunnel"), fd = q("chartSankey"), md = [
{
type: "query",
label: "Query",
description: "Standard analysis (single or multi-query)",
icon: dd
},
{
type: "funnel",
label: "Funnel",
description: "Sequential conversion analysis",
icon: ud
},
{
type: "flow",
label: "Flow",
description: "Bidirectional path analysis with Sankey visualization",
icon: fd
}
], hd = Ge(function({
value: t,
onChange: n,
disabled: s = !1
}) {
return /* @__PURE__ */ r("div", { className: "flex items-center gap-1 p-2 border-b border-dc-border bg-dc-surface", children: md.map((a) => {
const i = t === a.type, o = a.icon;
return /* @__PURE__ */ d(
"button",
{
onClick: () => !s && n(a.type),
disabled: s,
title: a.description,
className: `
flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium
transition-colors duration-150
${i ? "bg-dc-primary/10 text-dc-primary border border-dc-primary/30" : "text-dc-text-secondary hover:bg-dc-bg-secondary hover:text-dc-text border border-transparent"}
${s ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
`,
children: [
/* @__PURE__ */ r(o, { className: "h-4 w-4" }),
/* @__PURE__ */ r("span", { children: a.label })
]
},
a.type
);
}) });
}), Fn = q("chevronDown"), Ts = q("chevronRight"), Rn = q("check"), ks = q("search"), pd = q("dimension"), gd = q("link"), yd = q("timeDimension");
function bd(e) {
return e?.cubes ? e.cubes.filter((t) => t.meta?.eventStream).map((t) => ({
cube: t.name,
dimension: t.name,
// DropdownSelector uses dimension as value
label: t.title || t.name,
eventStream: t.meta?.eventStream
})) : [];
}
function xd(e) {
if (!e?.cubes) return [];
const t = [];
for (const n of e.cubes)
for (const s of n.dimensions || [])
s.type === "time" && t.push({
cube: n.name,
dimension: s.name,
label: s.shortTitle || s.title || s.name.split(".").pop() || s.name
});
return t;
}
const rr = Ge(function({
value: t,
label: n,
placeholder: s,
icon: a,
options: i,
onChange: o,
helpText: c
}) {
const [l, u] = ee(!1), [h, f] = ee(""), m = ge(null), g = ge(null), b = V(() => {
const y = {};
for (const C of i)
y[C.cube] || (y[C.cube] = []), y[C.cube].push(C);
return y;
}, [i]), N = V(() => {
if (!h.trim()) return b;
const y = h.toLowerCase(), C = {};
for (const [T, p] of Object.entries(b)) {
const v = p.filter(
(k) => k.label.toLowerCase().includes(y) || k.dimension.toLowerCase().includes(y) || T.toLowerCase().includes(y)
);
v.length > 0 && (C[T] = v);
}
return C;
}, [b, h]), x = E(
(y) => {
o(y), u(!1), f("");
},
[o]
), A = E(
(y) => {
y.stopPropagation(), o(null);
},
[o]
);
he(() => {
function y(C) {
m.current && !m.current.contains(C.target) && (u(!1), f(""));
}
if (l)
return document.addEventListener("mousedown", y), () => document.removeEventListener("mousedown", y);
}, [l]), he(() => {
l && g.current && g.current.focus();
}, [l]);
const w = t !== null;
return /* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ d("label", { className: "flex items-center gap-1.5 text-xs font-medium text-dc-text-muted mb-1", children: [
a && /* @__PURE__ */ r(a, { className: "w-3.5 h-3.5" }),
n
] }),
/* @__PURE__ */ d("div", { ref: m, className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
type: "button",
onClick: () => u(!l),
className: `
flex items-center justify-between w-full px-2.5 py-1.5 text-sm
bg-dc-surface border border-dc-border rounded
transition-colors hover:border-dc-primary cursor-pointer
${l ? "border-dc-primary ring-1 ring-dc-primary" : ""}
`,
children: [
/* @__PURE__ */ r("span", { className: `truncate ${w ? "text-dc-text" : "text-dc-text-muted"}`, children: w ? i.find((y) => y.dimension === t)?.label || t : s }),
/* @__PURE__ */ d("span", { className: "flex items-center gap-1 ml-2", children: [
w && /* @__PURE__ */ r(
"span",
{
role: "button",
tabIndex: 0,
onClick: A,
onKeyDown: (y) => y.key === "Enter" && A(y),
className: "p-0.5 rounded hover:bg-dc-surface-hover text-dc-text-muted hover:text-dc-text",
title: "Clear",
children: "×"
}
),
Fn && /* @__PURE__ */ r(
Fn,
{
className: `w-4 h-4 text-dc-text-muted transition-transform ${l ? "rotate-180" : ""}`
}
)
] })
]
}
),
l && /* @__PURE__ */ d("div", { className: "absolute z-50 mt-1 left-0 right-0 min-w-[200px] bg-dc-surface border border-dc-border rounded-md shadow-lg", children: [
/* @__PURE__ */ r("div", { className: "p-2 border-b border-dc-border", children: /* @__PURE__ */ d("div", { className: "relative", children: [
ks && /* @__PURE__ */ r(ks, { className: "absolute left-2 top-1/2 -translate-y-1/2 w-4 h-4 text-dc-text-muted" }),
/* @__PURE__ */ r(
"input",
{
ref: g,
type: "text",
value: h,
onChange: (y) => f(y.target.value),
placeholder: "Search...",
className: "w-full pl-8 pr-3 py-1.5 text-sm bg-dc-surface-secondary border border-dc-border rounded text-dc-text placeholder:text-dc-text-muted focus:outline-none focus:ring-1 focus:ring-dc-primary"
}
)
] }) }),
/* @__PURE__ */ r("div", { className: "max-h-48 overflow-y-auto p-1", children: Object.entries(N).length === 0 ? /* @__PURE__ */ r("div", { className: "px-3 py-4 text-sm text-dc-text-muted text-center", children: "No matching fields found" }) : Object.entries(N).map(([y, C]) => /* @__PURE__ */ d("div", { className: "mb-2 last:mb-0", children: [
/* @__PURE__ */ r("div", { className: "px-2 py-1 text-xs font-medium text-dc-text-muted uppercase tracking-wide", children: y }),
C.map((T) => /* @__PURE__ */ d(
"button",
{
onClick: () => x(T.dimension),
className: `
flex items-center justify-between w-full px-3 py-1.5 text-sm
rounded transition-colors
${t === T.dimension ? "bg-dc-primary-bg text-dc-primary" : "text-dc-text hover:bg-dc-surface-hover"}
`,
children: [
/* @__PURE__ */ r("span", { children: T.label }),
t === T.dimension && Rn && /* @__PURE__ */ r(Rn, { className: "w-4 h-4" })
]
},
T.dimension
))
] }, y)) }),
/* @__PURE__ */ r("div", { className: "px-3 py-2 border-t border-dc-border text-xs text-dc-text-muted", children: c })
] })
] })
] });
}), vd = Ge(function({
selectedCube: t,
bindingKey: n,
timeDimension: s,
schema: a,
onCubeChange: i,
onBindingKeyChange: o,
onTimeDimensionChange: c
}) {
const l = V(() => bd(a), [a]), u = V(() => {
const w = Kr(a);
return t ? w.filter((y) => y.cube === t) : [];
}, [a, t]), h = V(() => {
const w = xd(a);
return t ? w.filter((y) => y.cube === t) : [];
}, [a, t]), f = !!(t && n && s), [m, g] = ee(!1), b = ge(!1);
he(() => {
f && !b.current && (b.current = !0, g(!0));
}, [f]), he(() => {
if (!t || !a) return;
const w = a.cubes?.find((y) => y.name === t);
if (w?.meta?.eventStream) {
const y = w.meta.eventStream;
!n && y.bindingKey && o({ dimension: y.bindingKey }), !s && y.timeDimension && c(y.timeDimension);
}
}, [t, a, n, s, o, c]);
const N = n?.dimension ? typeof n.dimension == "string" ? n.dimension : n.dimension[0]?.dimension || null : null, x = E(
(w) => {
o(w ? { dimension: w } : null);
},
[o]
), A = l.find((w) => w.dimension === t)?.label || t;
return /* @__PURE__ */ d("div", { className: "bg-dc-surface-secondary border-b border-dc-border", children: [
/* @__PURE__ */ d(
"button",
{
type: "button",
onClick: () => g(!m),
className: "flex items-center justify-between w-full px-4 py-2.5 hover:bg-dc-surface-hover transition-colors",
children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
m ? Ts && /* @__PURE__ */ r(Ts, { className: "w-4 h-4 text-dc-text-muted" }) : Fn && /* @__PURE__ */ r(Fn, { className: "w-4 h-4 text-dc-text-muted" }),
/* @__PURE__ */ r(dt, { className: "mb-0", children: "Configuration" }),
f && /* @__PURE__ */ r("span", { className: "flex items-center gap-1 text-xs text-dc-success", children: Rn && /* @__PURE__ */ r(Rn, { className: "w-3.5 h-3.5" }) })
] }),
m && f && /* @__PURE__ */ r("span", { className: "text-xs text-dc-text-muted truncate max-w-[200px]", children: A })
]
}
),
!m && /* @__PURE__ */ d("div", { className: "flex flex-col gap-3 px-4 pb-3", children: [
/* @__PURE__ */ r(
rr,
{
value: t,
label: "Cube",
placeholder: "Select event stream cube",
icon: pd,
options: l,
onChange: i,
helpText: "Select a cube configured for funnel analysis"
}
),
/* @__PURE__ */ r(
rr,
{
value: N,
label: "Binding Key",
placeholder: t ? "Select binding key" : "Select cube first",
icon: gd,
options: u,
onChange: x,
helpText: "Entity that connects steps (e.g., user ID, order ID)"
}
),
/* @__PURE__ */ r(
rr,
{
value: s,
label: "Time Dimension",
placeholder: t ? "Select time dimension" : "Select cube first",
icon: yd,
options: h,
onChange: c,
helpText: "Timestamp field for step ordering"
}
)
] })
] });
}), As = q("menu"), Ms = q("close"), Is = q("chevronDown"), Es = q("check"), Fs = q("timeDimension"), Rs = [
{ value: null, label: "No limit" },
{ value: "PT1H", label: "1 hour" },
{ value: "PT6H", label: "6 hours" },
{ value: "PT12H", label: "12 hours" },
{ value: "P1D", label: "1 day" },
{ value: "P3D", label: "3 days" },
{ value: "P7D", label: "7 days" },
{ value: "P14D", label: "14 days" },
{ value: "P30D", label: "30 days" },
{ value: "P90D", label: "90 days" }
], wd = Ge(function({
step: t,
stepIndex: n,
isActive: s,
canRemove: a,
schema: i,
onSelect: o,
onRemove: c,
onUpdate: l
}) {
const [u, h] = ee(!1), [f, m] = ee(!1), g = ge(null), b = ge(null);
he(() => {
u && g.current && (g.current.focus(), g.current.select());
}, [u]), he(() => {
function p(v) {
b.current && !b.current.contains(v.target) && m(!1);
}
if (f)
return document.addEventListener("mousedown", p), () => document.removeEventListener("mousedown", p);
}, [f]);
const N = E(
(p) => {
l({ name: p.target.value });
},
[l]
), x = E(
(p) => {
(p.key === "Enter" || p.key === "Escape") && h(!1);
},
[]
), A = E(() => {
h(!1);
}, []), w = E(
(p) => {
l({ timeToConvert: p || void 0 }), m(!1);
},
[l]
), y = E(
(p) => {
l({ filters: p });
},
[l]
), C = t.timeToConvert ? Rs.find((p) => p.value === t.timeToConvert)?.label || t.timeToConvert : "No limit", T = V(() => {
if (!i) return null;
const p = {
cubes: i.cubes.map((v) => ({
...v,
description: v.description || ""
}))
};
return t.cube ? el(t.cube, p) : p;
}, [i, t.cube]);
return /* @__PURE__ */ d(
"div",
{
className: `
bg-dc-surface border rounded-lg transition-all cursor-pointer
${s ? "border-dc-primary ring-1 ring-dc-primary" : "border-dc-border hover:border-dc-text-muted"}
`,
onClick: o,
children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-dc-border", children: [
/* @__PURE__ */ r("div", { className: "cursor-grab active:cursor-grabbing text-dc-text-muted hover:text-dc-text", children: As && /* @__PURE__ */ r(As, { className: "w-4 h-4" }) }),
/* @__PURE__ */ r("span", { className: "flex-shrink-0 w-6 h-6 flex items-center justify-center rounded-full bg-dc-primary/10 text-dc-primary text-xs font-medium", children: n + 1 }),
u ? /* @__PURE__ */ r(
"input",
{
ref: g,
type: "text",
value: t.name,
onChange: N,
onKeyDown: x,
onBlur: A,
onClick: (p) => p.stopPropagation(),
className: "flex-1 px-1.5 py-0.5 text-sm font-medium bg-dc-surface border border-dc-primary rounded text-dc-text focus:outline-none",
placeholder: "Step name"
}
) : /* @__PURE__ */ r(
"button",
{
onClick: (p) => {
p.stopPropagation(), h(!0);
},
className: "flex-1 text-left text-sm font-medium text-dc-text hover:text-dc-primary truncate",
title: "Click to edit name",
children: t.name || `Step ${n + 1}`
}
),
a && /* @__PURE__ */ r(
"button",
{
onClick: (p) => {
p.stopPropagation(), c();
},
className: "p-1 rounded hover:bg-dc-danger-bg text-dc-text-muted hover:text-dc-error transition-colors",
title: "Remove step",
children: Ms && /* @__PURE__ */ r(Ms, { className: "w-4 h-4" })
}
)
] }),
s && /* @__PURE__ */ d("div", { className: "px-3 py-3 space-y-4", onClick: (p) => p.stopPropagation(), children: [
/* @__PURE__ */ r(
Qr,
{
filters: t.filters,
schema: T,
onFiltersChange: y,
dimensionsOnly: !0
}
),
n > 0 && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d("label", { className: "flex items-center gap-1.5 text-xs font-medium text-dc-text-muted mb-1", children: [
Fs && /* @__PURE__ */ r(Fs, { className: "w-3.5 h-3.5" }),
"Time Window"
] }),
/* @__PURE__ */ d("div", { ref: b, className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
type: "button",
onClick: () => m(!f),
className: `
flex items-center justify-between w-full px-2.5 py-1.5 text-sm
bg-dc-surface border border-dc-border rounded
transition-colors hover:border-dc-primary cursor-pointer
${f ? "border-dc-primary ring-1 ring-dc-primary" : ""}
`,
children: [
/* @__PURE__ */ r("span", { className: t.timeToConvert ? "text-dc-text" : "text-dc-text-muted", children: C }),
Is && /* @__PURE__ */ r(
Is,
{
className: `w-4 h-4 text-dc-text-muted transition-transform ${f ? "rotate-180" : ""}`
}
)
]
}
),
f && /* @__PURE__ */ d("div", { className: "absolute z-50 mt-1 left-0 right-0 bg-dc-surface border border-dc-border rounded-md shadow-lg max-h-48 overflow-y-auto", children: [
Rs.map((p) => /* @__PURE__ */ d(
"button",
{
onClick: () => w(p.value),
className: `
flex items-center justify-between w-full px-3 py-1.5 text-sm
transition-colors
${t.timeToConvert === p.value || !t.timeToConvert && p.value === null ? "bg-dc-primary-bg text-dc-primary" : "text-dc-text hover:bg-dc-surface-hover"}
`,
children: [
/* @__PURE__ */ r("span", { children: p.label }),
(t.timeToConvert === p.value || !t.timeToConvert && p.value === null) && Es && /* @__PURE__ */ r(Es, { className: "w-4 h-4" })
]
},
p.value || "none"
)),
/* @__PURE__ */ r("div", { className: "px-3 py-2 border-t border-dc-border text-xs text-dc-text-muted", children: "Max time from previous step to qualify" })
] })
] })
] })
] }),
!s && /* @__PURE__ */ d("div", { className: "px-3 py-2 text-xs text-dc-text-muted", children: [
t.filters.length > 0 && /* @__PURE__ */ d("span", { children: [
t.filters.length,
" filter",
t.filters.length !== 1 ? "s" : ""
] }),
t.timeToConvert && n > 0 && /* @__PURE__ */ d("span", { className: t.filters.length > 0 ? "ml-2" : "", children: [
t.filters.length > 0 ? "• " : "",
"within ",
C.toLowerCase()
] }),
t.filters.length === 0 && !t.timeToConvert && /* @__PURE__ */ r("span", { className: "italic", children: "No filters configured" })
] })
]
}
);
}), _s = q("add"), Nd = Ge(function({
steps: t,
activeStepIndex: n,
schema: s,
onAddStep: a,
onRemoveStep: i,
onUpdateStep: o,
onSelectStep: c,
onReorderSteps: l
}) {
const [u, h] = ee(null), [f, m] = ee(null), g = E((w) => {
h(w);
}, []), b = E((w, y) => {
w.preventDefault(), u !== null && u !== y && m(y);
}, [u]), N = E(() => {
m(null);
}, []), x = E((w, y) => {
w.preventDefault(), u !== null && u !== y && l(u, y), h(null), m(null);
}, [u, l]), A = E(() => {
h(null), m(null);
}, []);
return /* @__PURE__ */ d("div", { className: "space-y-4", children: [
/* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ d(dt, { children: [
"Funnel Steps",
t.length > 0 && /* @__PURE__ */ d("span", { className: "ml-1.5 text-xs font-normal text-dc-text-muted normal-case tracking-normal", children: [
"(",
t.length,
")"
] })
] }) }),
t.length === 0 ? /* @__PURE__ */ d("div", { className: "text-center py-8", children: [
/* @__PURE__ */ r("p", { className: "text-sm text-dc-text-muted mb-3", children: "No steps defined. Add at least 2 steps to create a funnel." }),
/* @__PURE__ */ d(
"button",
{
onClick: a,
className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-dc-primary bg-dc-primary/10 rounded-md hover:bg-dc-primary/20 transition-colors",
children: [
/* @__PURE__ */ r(_s, { className: "w-4 h-4" }),
"Add First Step"
]
}
)
] }) : /* @__PURE__ */ r("div", { className: "space-y-2", children: t.map((w, y) => /* @__PURE__ */ r(
"div",
{
draggable: !0,
onDragStart: () => g(y),
onDragOver: (C) => b(C, y),
onDragLeave: N,
onDrop: (C) => x(C, y),
onDragEnd: A,
className: `transition-all ${u === y ? "opacity-50" : ""} ${f === y ? "border-t-2 border-dc-primary pt-1" : ""}`,
children: /* @__PURE__ */ r(
wd,
{
step: w,
stepIndex: y,
isActive: y === n,
canRemove: t.length > 1,
schema: s,
onSelect: () => c(y),
onRemove: () => i(y),
onUpdate: (C) => o(y, C)
}
)
},
w.id
)) }),
t.length > 0 && /* @__PURE__ */ d(
"button",
{
onClick: a,
className: "flex items-center justify-center gap-1.5 w-full py-2 text-sm font-medium text-dc-text-secondary bg-dc-surface border-2 border-dashed border-dc-border rounded-lg hover:border-dc-primary hover:text-dc-primary hover:bg-dc-primary/5 transition-colors",
children: [
/* @__PURE__ */ r(_s, { className: "w-4 h-4" }),
"Add Step"
]
}
),
t.length === 1 && /* @__PURE__ */ r("p", { className: "text-xs text-dc-warning text-center", children: "Add at least one more step to create a valid funnel" })
] });
}), Cd = Ge(function({
funnelCube: t,
funnelSteps: n,
activeFunnelStepIndex: s,
funnelTimeDimension: a,
funnelBindingKey: i,
schema: o,
onCubeChange: c,
onAddStep: l,
onRemoveStep: u,
onUpdateStep: h,
onSelectStep: f,
onReorderSteps: m,
onTimeDimensionChange: g,
onBindingKeyChange: b,
// Display props
chartType: N = "funnel",
displayConfig: x,
colorPalette: A,
onDisplayConfigChange: w
}) {
const [y, C] = ee("steps"), T = x && w;
return /* @__PURE__ */ d("div", { className: "flex flex-col h-full", children: [
/* @__PURE__ */ d("div", { className: "flex border-b border-dc-border flex-shrink-0", children: [
/* @__PURE__ */ r(
"button",
{
onClick: () => C("steps"),
className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${y === "steps" ? "text-dc-primary border-b-2 border-dc-primary" : "text-dc-text-secondary hover:text-dc-text"}`,
children: "Steps"
}
),
/* @__PURE__ */ r(
"button",
{
onClick: () => T && C("display"),
disabled: !T,
className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${y === "display" ? "text-dc-primary border-b-2 border-dc-primary" : T ? "text-dc-text-secondary hover:text-dc-text" : "text-dc-text-muted cursor-not-allowed opacity-50"}`,
title: T ? "Display options" : "Display options not available",
children: "Display"
}
)
] }),
y === "steps" ? /* @__PURE__ */ d("div", { className: "flex flex-col flex-1 min-h-0", children: [
/* @__PURE__ */ r(
vd,
{
selectedCube: t,
bindingKey: i,
timeDimension: a,
schema: o,
onCubeChange: c,
onBindingKeyChange: b,
onTimeDimensionChange: g
}
),
/* @__PURE__ */ r("div", { className: "flex-1 min-h-0 overflow-auto p-4 pb-24", children: /* @__PURE__ */ r(
Nd,
{
steps: n,
activeStepIndex: s,
schema: o,
onAddStep: l,
onRemoveStep: u,
onUpdateStep: h,
onSelectStep: f,
onReorderSteps: m
}
) })
] }) : y === "display" && x && w ? /* @__PURE__ */ r("div", { className: "flex-1 min-h-0 overflow-auto p-4", children: /* @__PURE__ */ r(
jr,
{
chartType: N,
displayConfig: x,
colorPalette: A,
onDisplayConfigChange: w
}
) }) : null
] });
}), _n = q("chevronDown"), Os = q("chevronRight"), On = q("check"), $s = q("search"), Sd = q("dimension"), Dd = q("link"), Td = q("timeDimension"), kd = q("dimension");
function Ad(e) {
return e?.cubes ? e.cubes.filter((t) => t.meta?.eventStream).map((t) => ({
cube: t.name,
dimension: t.name,
label: t.title || t.name,
eventStream: t.meta?.eventStream
})) : [];
}
function Md(e) {
if (!e?.cubes) return [];
const t = [];
for (const n of e.cubes)
for (const s of n.dimensions || [])
s.type === "time" && t.push({
cube: n.name,
dimension: s.name,
label: s.shortTitle || s.title || s.name.split(".").pop() || s.name
});
return t;
}
function Id(e) {
if (!e?.cubes) return [];
const t = [];
for (const n of e.cubes)
for (const s of n.dimensions || [])
s.type === "string" && t.push({
cube: n.name,
dimension: s.name,
label: s.shortTitle || s.title || s.name.split(".").pop() || s.name
});
return t;
}
const xn = Ge(function({
value: t,
label: n,
placeholder: s,
icon: a,
options: i,
onChange: o,
helpText: c
}) {
const [l, u] = ee(!1), [h, f] = ee(""), m = ge(null), g = ge(null), b = V(() => {
const y = {};
for (const C of i)
y[C.cube] || (y[C.cube] = []), y[C.cube].push(C);
return y;
}, [i]), N = V(() => {
if (!h.trim()) return b;
const y = h.toLowerCase(), C = {};
for (const [T, p] of Object.entries(b)) {
const v = p.filter(
(k) => k.label.toLowerCase().includes(y) || k.dimension.toLowerCase().includes(y) || T.toLowerCase().includes(y)
);
v.length > 0 && (C[T] = v);
}
return C;
}, [b, h]), x = E(
(y) => {
o(y), u(!1), f("");
},
[o]
), A = E(
(y) => {
y.stopPropagation(), o(null);
},
[o]
);
he(() => {
function y(C) {
m.current && !m.current.contains(C.target) && (u(!1), f(""));
}
if (l)
return document.addEventListener("mousedown", y), () => document.removeEventListener("mousedown", y);
}, [l]), he(() => {
l && g.current && g.current.focus();
}, [l]);
const w = t !== null;
return /* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ d("label", { className: "flex items-center gap-1.5 text-xs font-medium text-dc-text-muted mb-1", children: [
a && /* @__PURE__ */ r(a, { className: "w-3.5 h-3.5" }),
n
] }),
/* @__PURE__ */ d("div", { ref: m, className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
type: "button",
onClick: () => u(!l),
className: `
flex items-center justify-between w-full px-2.5 py-1.5 text-sm
bg-dc-surface border border-dc-border rounded
transition-colors hover:border-dc-primary cursor-pointer
${l ? "border-dc-primary ring-1 ring-dc-primary" : ""}
`,
children: [
/* @__PURE__ */ r("span", { className: `truncate ${w ? "text-dc-text" : "text-dc-text-muted"}`, children: w ? i.find((y) => y.dimension === t)?.label || t : s }),
/* @__PURE__ */ d("span", { className: "flex items-center gap-1 ml-2", children: [
w && /* @__PURE__ */ r(
"span",
{
role: "button",
tabIndex: 0,
onClick: A,
onKeyDown: (y) => y.key === "Enter" && A(y),
className: "p-0.5 rounded hover:bg-dc-surface-hover text-dc-text-muted hover:text-dc-text",
title: "Clear",
children: "x"
}
),
_n && /* @__PURE__ */ r(
_n,
{
className: `w-4 h-4 text-dc-text-muted transition-transform ${l ? "rotate-180" : ""}`
}
)
] })
]
}
),
l && /* @__PURE__ */ d("div", { className: "absolute z-50 mt-1 left-0 right-0 min-w-[200px] bg-dc-surface border border-dc-border rounded-md shadow-lg", children: [
/* @__PURE__ */ r("div", { className: "p-2 border-b border-dc-border", children: /* @__PURE__ */ d("div", { className: "relative", children: [
$s && /* @__PURE__ */ r($s, { className: "absolute left-2 top-1/2 -translate-y-1/2 w-4 h-4 text-dc-text-muted" }),
/* @__PURE__ */ r(
"input",
{
ref: g,
type: "text",
value: h,
onChange: (y) => f(y.target.value),
placeholder: "Search...",
className: "w-full pl-8 pr-3 py-1.5 text-sm bg-dc-surface-secondary border border-dc-border rounded text-dc-text placeholder:text-dc-text-muted focus:outline-none focus:ring-1 focus:ring-dc-primary"
}
)
] }) }),
/* @__PURE__ */ r("div", { className: "max-h-48 overflow-y-auto p-1", children: Object.entries(N).length === 0 ? /* @__PURE__ */ r("div", { className: "px-3 py-4 text-sm text-dc-text-muted text-center", children: "No matching fields found" }) : Object.entries(N).map(([y, C]) => /* @__PURE__ */ d("div", { className: "mb-2 last:mb-0", children: [
/* @__PURE__ */ r("div", { className: "px-2 py-1 text-xs font-medium text-dc-text-muted uppercase tracking-wide", children: y }),
C.map((T) => /* @__PURE__ */ d(
"button",
{
onClick: () => x(T.dimension),
className: `
flex items-center justify-between w-full px-3 py-1.5 text-sm
rounded transition-colors
${t === T.dimension ? "bg-dc-primary-bg text-dc-primary" : "text-dc-text hover:bg-dc-surface-hover"}
`,
children: [
/* @__PURE__ */ r("span", { children: T.label }),
t === T.dimension && On && /* @__PURE__ */ r(On, { className: "w-4 h-4" })
]
},
T.dimension
))
] }, y)) }),
/* @__PURE__ */ r("div", { className: "px-3 py-2 border-t border-dc-border text-xs text-dc-text-muted", children: c })
] })
] })
] });
}), Ed = Ge(function({
selectedCube: t,
bindingKey: n,
timeDimension: s,
eventDimension: a,
schema: i,
onCubeChange: o,
onBindingKeyChange: c,
onTimeDimensionChange: l,
onEventDimensionChange: u
}) {
const h = V(() => Ad(i), [i]), f = V(() => {
const T = Kr(i);
return t ? T.filter((p) => p.cube === t) : [];
}, [i, t]), m = V(() => {
const T = Md(i);
return t ? T.filter((p) => p.cube === t) : [];
}, [i, t]), g = V(() => {
const T = Id(i);
return t ? T.filter((p) => p.cube === t) : [];
}, [i, t]), b = !!(t && n && s && a), [N, x] = ee(!1), A = ge(!1);
he(() => {
b && !A.current && (A.current = !0, x(!0));
}, [b]), he(() => {
if (!t || !i) return;
const T = i.cubes?.find((p) => p.name === t);
if (T?.meta?.eventStream) {
const p = T.meta.eventStream;
!n && p.bindingKey && c({ dimension: p.bindingKey }), !s && p.timeDimension && l(p.timeDimension);
}
}, [t, i, n, s, c, l]);
const w = n?.dimension ? typeof n.dimension == "string" ? n.dimension : n.dimension[0]?.dimension || null : null, y = E(
(T) => {
c(T ? { dimension: T } : null);
},
[c]
), C = h.find((T) => T.dimension === t)?.label || t;
return /* @__PURE__ */ d("div", { className: "bg-dc-surface-secondary border-b border-dc-border", children: [
/* @__PURE__ */ d(
"button",
{
type: "button",
onClick: () => x(!N),
className: "flex items-center justify-between w-full px-4 py-2.5 hover:bg-dc-surface-hover transition-colors",
children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
N ? Os && /* @__PURE__ */ r(Os, { className: "w-4 h-4 text-dc-text-muted" }) : _n && /* @__PURE__ */ r(_n, { className: "w-4 h-4 text-dc-text-muted" }),
/* @__PURE__ */ r(dt, { className: "mb-0", children: "Configuration" }),
b && /* @__PURE__ */ r("span", { className: "flex items-center gap-1 text-xs text-dc-success", children: On && /* @__PURE__ */ r(On, { className: "w-3.5 h-3.5" }) })
] }),
N && b && /* @__PURE__ */ r("span", { className: "text-xs text-dc-text-muted truncate max-w-[200px]", children: C })
]
}
),
!N && /* @__PURE__ */ d("div", { className: "flex flex-col gap-3 px-4 pb-3", children: [
/* @__PURE__ */ r(
xn,
{
value: t,
label: "Cube",
placeholder: "Select event stream cube",
icon: Sd,
options: h,
onChange: o,
helpText: "Select a cube configured for flow analysis"
}
),
/* @__PURE__ */ r(
xn,
{
value: w,
label: "Binding Key",
placeholder: t ? "Select binding key" : "Select cube first",
icon: Dd,
options: f,
onChange: y,
helpText: "Entity that links events together (e.g., user ID)"
}
),
/* @__PURE__ */ r(
xn,
{
value: s,
label: "Time Dimension",
placeholder: t ? "Select time dimension" : "Select cube first",
icon: Td,
options: m,
onChange: l,
helpText: "Timestamp field for event ordering"
}
),
/* @__PURE__ */ r(
xn,
{
value: a,
label: "Event Dimension",
placeholder: t ? "Select event dimension" : "Select cube first",
icon: kd,
options: g,
onChange: u,
helpText: "Dimension that categorizes events (node labels in Sankey)"
}
)
] })
] });
}), Fd = Ge(function({
flowCube: t,
flowBindingKey: n,
flowTimeDimension: s,
eventDimension: a,
startingStep: i,
stepsBefore: o,
stepsAfter: c,
joinStrategy: l = "auto",
schema: u,
onCubeChange: h,
onBindingKeyChange: f,
onTimeDimensionChange: m,
onEventDimensionChange: g,
onStartingStepFiltersChange: b,
onStepsBeforeChange: N,
onStepsAfterChange: x,
onJoinStrategyChange: A,
// Chart type (affects query!)
chartType: w = "sankey",
onChartTypeChange: y,
// Display props
displayConfig: C,
colorPalette: T,
onDisplayConfigChange: p
}) {
const [v, k] = ee("config"), S = C && p, $ = E(
(D) => {
b(D);
},
[b]
);
return /* @__PURE__ */ d("div", { className: "flex flex-col h-full min-h-0 overflow-hidden", children: [
/* @__PURE__ */ d("div", { className: "flex border-b border-dc-border flex-shrink-0", children: [
/* @__PURE__ */ r(
"button",
{
onClick: () => k("config"),
className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${v === "config" ? "text-dc-primary border-b-2 border-dc-primary" : "text-dc-text-secondary hover:text-dc-text"}`,
children: "Flow"
}
),
/* @__PURE__ */ r(
"button",
{
onClick: () => S && k("display"),
disabled: !S,
className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${v === "display" ? "text-dc-primary border-b-2 border-dc-primary" : S ? "text-dc-text-secondary hover:text-dc-text" : "text-dc-text-muted cursor-not-allowed opacity-50"}`,
title: S ? "Display options" : "Display options not available",
children: "Display"
}
)
] }),
v === "config" ? /* @__PURE__ */ d("div", { className: "flex flex-col flex-1 min-h-0", children: [
/* @__PURE__ */ r(
Ed,
{
selectedCube: t,
bindingKey: n,
timeDimension: s,
eventDimension: a,
schema: u,
onCubeChange: h,
onBindingKeyChange: f,
onTimeDimensionChange: m,
onEventDimensionChange: g
}
),
/* @__PURE__ */ d("div", { className: "flex-1 min-h-0 overflow-auto p-4 space-y-6", children: [
y && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r(dt, { children: "Visualization" }),
/* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted mb-3", children: "Choose how to visualize the flow data. This affects how data is aggregated." }),
/* @__PURE__ */ d("div", { className: "flex gap-2", children: [
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: () => y("sankey"),
className: `flex-1 px-3 py-2 rounded-md border text-sm font-medium transition-colors ${w === "sankey" ? "border-dc-primary bg-dc-primary/10 text-dc-primary" : "border-dc-border bg-dc-surface hover:bg-dc-surface-hover text-dc-text"}`,
children: /* @__PURE__ */ d("div", { className: "flex flex-col items-center gap-1", children: [
/* @__PURE__ */ r("span", { children: "Sankey" }),
/* @__PURE__ */ r("span", { className: "text-[10px] font-normal text-dc-text-muted", children: "Paths can converge" })
] })
}
),
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: () => y("sunburst"),
className: `flex-1 px-3 py-2 rounded-md border text-sm font-medium transition-colors ${w === "sunburst" ? "border-dc-primary bg-dc-primary/10 text-dc-primary" : "border-dc-border bg-dc-surface hover:bg-dc-surface-hover text-dc-text"}`,
children: /* @__PURE__ */ d("div", { className: "flex flex-col items-center gap-1", children: [
/* @__PURE__ */ r("span", { children: "Sunburst" }),
/* @__PURE__ */ r("span", { className: "text-[10px] font-normal text-dc-text-muted", children: "Unique paths only" })
] })
}
)
] })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r(dt, { children: "Starting Step" }),
/* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted mb-3", children: "Define the anchor event from which paths will be explored in both directions." }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("label", { className: "block text-xs font-medium text-dc-text-muted mb-2", children: "Filter Conditions" }),
/* @__PURE__ */ r(
Qr,
{
filters: i.filters,
schema: u,
onFiltersChange: $
}
)
] })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r(dt, { children: "Exploration Depth" }),
/* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted mb-3", children: w === "sunburst" ? "How many steps to explore after the starting step." : "How many steps to explore before and after the starting step." }),
/* @__PURE__ */ d("div", { className: "grid grid-cols-2 gap-4", children: [
/* @__PURE__ */ d("div", { className: w === "sunburst" ? "opacity-50" : "", children: [
/* @__PURE__ */ d("label", { className: "block text-xs font-medium text-dc-text-muted mb-1", children: [
"Steps Before",
w === "sunburst" && /* @__PURE__ */ r("span", { className: "ml-1 text-dc-text-muted", children: "(N/A)" })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "range",
min: Dn,
max: Tn,
value: o,
onChange: (D) => N(parseInt(D.target.value, 10)),
disabled: w === "sunburst",
className: "flex-1 disabled:cursor-not-allowed"
}
),
/* @__PURE__ */ r("span", { className: "w-6 text-sm font-medium text-dc-text text-center", children: w === "sunburst" ? "-" : o })
] })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("label", { className: "block text-xs font-medium text-dc-text-muted mb-1", children: "Steps After" }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "range",
min: Dn,
max: Tn,
value: c,
onChange: (D) => x(parseInt(D.target.value, 10)),
className: "flex-1"
}
),
/* @__PURE__ */ r("span", { className: "w-6 text-sm font-medium text-dc-text text-center", children: c })
] })
] })
] }),
(w !== "sunburst" && o >= 4 || c >= 4) && /* @__PURE__ */ r("div", { className: "mt-3 px-3 py-2 bg-dc-warning-bg rounded border border-dc-warning text-xs text-dc-warning", children: "High step depth (4-5) may impact query performance on large datasets." })
] }),
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r(dt, { children: "Join Strategy" }),
/* @__PURE__ */ r("p", { className: "text-xs text-dc-text-muted mb-3", children: "Control how before/after steps are fetched. Switch to window if lateral is slower on your DB." }),
/* @__PURE__ */ d(
"select",
{
className: "w-full border border-dc-border rounded px-2 py-2 text-sm bg-dc-surface text-dc-text",
value: l,
onChange: (D) => A?.(D.target.value),
children: [
/* @__PURE__ */ r("option", { value: "auto", children: "Auto (prefer lateral if available)" }),
/* @__PURE__ */ r("option", { value: "lateral", children: "Lateral (index seeks)" }),
/* @__PURE__ */ r("option", { value: "window", children: "Window (ROW_NUMBER)" })
]
}
)
] })
] })
] }) : v === "display" && C && p ? /* @__PURE__ */ r("div", { className: "flex-1 min-h-0 overflow-auto p-4", children: /* @__PURE__ */ r(
jr,
{
chartType: w,
displayConfig: C,
colorPalette: T,
onDisplayConfigChange: p
}
) }) : null
] });
}), Ls = q("add"), Rd = q("close"), sr = q("info"), ar = q("warning"), Ps = q("link"), _d = Ge(function({
metrics: t,
breakdowns: n,
filters: s,
schema: a,
activeTab: i,
onActiveTabChange: o,
onAddMetric: c,
onRemoveMetric: l,
onReorderMetrics: u,
onAddBreakdown: h,
onRemoveBreakdown: f,
onBreakdownGranularityChange: m,
onBreakdownComparisonToggle: g,
onReorderBreakdowns: b,
onFiltersChange: N,
onDropFieldToFilter: x,
// Sorting
order: A,
onOrderChange: w,
// Chart configuration
chartType: y,
chartConfig: C,
displayConfig: T,
colorPalette: p,
chartAvailability: v,
onChartTypeChange: k,
onChartConfigChange: S,
onDisplayConfigChange: $,
// Validation
validationStatus: D,
validationError: F,
// Multi-query props
queryCount: K = 1,
activeQueryIndex: P = 0,
mergeStrategy: te = "concat",
onActiveQueryChange: _,
onAddQuery: O,
onRemoveQuery: ie,
onMergeStrategyChange: X,
breakdownsLocked: ce = !1,
combinedMetrics: Q,
combinedBreakdowns: Se,
multiQueryValidation: L,
adapterValidation: pe,
// Funnel props (legacy - for merge strategy mode)
funnelBindingKey: z,
onFunnelBindingKeyChange: H,
// Analysis Type props
analysisType: se = "query",
onAnalysisTypeChange: me,
// Funnel Mode props (new dedicated state)
funnelCube: le = null,
funnelSteps: we = [],
activeFunnelStepIndex: Y = 0,
funnelTimeDimension: Pe,
onFunnelCubeChange: He,
onAddFunnelStep: Ne,
onRemoveFunnelStep: _e,
onUpdateFunnelStep: We,
onSelectFunnelStep: Je,
onReorderFunnelSteps: Ke,
onFunnelTimeDimensionChange: Oe,
// Funnel display config (for Display tab)
funnelDisplayConfig: Xe,
onFunnelDisplayConfigChange: Qe,
// Flow Mode props
flowCube: J,
flowBindingKey: fe,
flowTimeDimension: ve,
eventDimension: ke,
startingStep: Fe,
stepsBefore: re = 3,
stepsAfter: be = 3,
flowJoinStrategy: Ee = "auto",
onFlowCubeChange: qe,
onFlowBindingKeyChange: Ze,
onFlowTimeDimensionChange: xt,
onEventDimensionChange: vt,
onStartingStepFiltersChange: gt,
onStepsBeforeChange: wt,
onStepsAfterChange: Tt,
onFlowJoinStrategyChange: kt,
flowDisplayConfig: ct,
onFlowDisplayConfigChange: ut
}) {
const Ye = K > 1, st = se === "funnel", Nt = se === "flow", ze = se === "funnel", M = E((ae) => {
if (!a?.cubes) return null;
const [U] = ae.field.split("."), G = a.cubes.find((oe) => oe.name === U);
return G && G.dimensions?.find((oe) => oe.name === ae.field) || null;
}, [a]), I = V(() => n.find((ae) => ae.isTimeDimension && ae.enableComparison), [n]);
he(() => {
t.length === 0 && (i === "chart" || i === "display") && o("query");
}, [t.length, i, o]);
const B = E((ae) => {
_?.(ae), i !== "query" && o("query");
}, [_, i, o]), Z = E((ae, U) => {
ae.stopPropagation(), ie?.(U);
}, [ie]), ue = (ae) => Ye ? st ? `S${ae + 1}` : `Q${ae + 1}` : "Query";
return /* @__PURE__ */ d("div", { className: "h-full flex flex-col bg-dc-surface", children: [
me && /* @__PURE__ */ r(
hd,
{
value: se,
onChange: me
}
),
ze && He && Ne && _e && We && Je && Ke && Oe && H ? /* @__PURE__ */ r(
Cd,
{
funnelCube: le,
funnelSteps: we,
activeFunnelStepIndex: Y,
funnelTimeDimension: Pe ?? null,
funnelBindingKey: z ?? null,
schema: a,
onCubeChange: He,
onAddStep: Ne,
onRemoveStep: _e,
onUpdateStep: We,
onSelectStep: Je,
onReorderSteps: Ke,
onTimeDimensionChange: Oe,
onBindingKeyChange: H,
chartType: "funnel",
displayConfig: Xe,
colorPalette: p,
onDisplayConfigChange: Qe
}
) : Nt && qe && Ze && xt && vt && gt && wt && Tt && Fe ? (
/* Flow Mode - dedicated UI when analysisType === 'flow' */
/* @__PURE__ */ r(
Fd,
{
flowCube: J ?? null,
flowBindingKey: fe ?? null,
flowTimeDimension: ve ?? null,
eventDimension: ke ?? null,
startingStep: Fe,
stepsBefore: re,
stepsAfter: be,
joinStrategy: Ee,
schema: a,
onCubeChange: qe,
onBindingKeyChange: Ze,
onTimeDimensionChange: xt,
onEventDimensionChange: vt,
onStartingStepFiltersChange: gt,
onStepsBeforeChange: wt,
onStepsAfterChange: Tt,
onJoinStrategyChange: kt,
chartType: y,
onChartTypeChange: k,
displayConfig: ct,
colorPalette: p,
onDisplayConfigChange: ut
}
)
) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ d("div", { className: "flex border-b border-dc-border flex-shrink-0", children: [
Ye ? /* @__PURE__ */ d("div", { className: "flex min-w-0 overflow-x-auto scrollbar-thin", children: [
Array.from({ length: K }).map((ae, U) => /* @__PURE__ */ d(
"button",
{
onClick: () => B(U),
className: `flex items-center gap-1 px-3 py-3 text-sm font-medium transition-colors flex-shrink-0 ${U === P && i === "query" ? "text-dc-primary border-b-2 border-dc-primary" : "text-dc-text-secondary hover:text-dc-text"}`,
children: [
ue(U),
/* @__PURE__ */ r(
"span",
{
role: "button",
tabIndex: 0,
onClick: (oe) => Z(oe, U),
onKeyDown: (oe) => oe.key === "Enter" && Z(oe, U),
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 ${ue(U)}`,
children: /* @__PURE__ */ r(Rd, { className: "w-3 h-3" })
}
)
]
},
`q${U}`
)),
/* @__PURE__ */ r(
"button",
{
onClick: O,
className: "flex items-center justify-center px-2 py-3 text-dc-text-secondary hover:text-dc-text transition-colors flex-shrink-0",
title: "Add query",
"aria-label": "Add new query",
children: /* @__PURE__ */ r(Ls, { className: "w-4 h-4" })
}
)
] }) : /* @__PURE__ */ d(
"button",
{
onClick: () => o("query"),
className: `flex-1 px-4 py-3 text-sm font-medium transition-colors ${i === "query" ? "text-dc-primary border-b-2 border-dc-primary" : "text-dc-text-secondary hover:text-dc-text"}`,
children: [
"Query",
O && /* @__PURE__ */ r(
"span",
{
role: "button",
tabIndex: 0,
onClick: (ae) => {
ae.stopPropagation(), O();
},
onKeyDown: (ae) => {
ae.key === "Enter" && (ae.stopPropagation(), O());
},
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__ */ r(Ls, { className: "w-3 h-3" })
}
)
]
}
),
/* @__PURE__ */ r(
"button",
{
onClick: () => t.length > 0 && o("chart"),
disabled: t.length === 0,
className: `px-4 py-3 text-sm font-medium transition-colors flex-shrink-0 ${Ye ? "" : "flex-1"} ${i === "chart" ? "text-dc-primary border-b-2 border-dc-primary" : t.length === 0 ? "text-dc-text-muted cursor-not-allowed opacity-50" : "text-dc-text-secondary hover:text-dc-text"}`,
title: t.length === 0 ? "Add metrics to configure chart" : "Chart configuration",
children: "Chart"
}
),
/* @__PURE__ */ r(
"button",
{
onClick: () => t.length > 0 && o("display"),
disabled: t.length === 0,
className: `px-4 py-3 text-sm font-medium transition-colors flex-shrink-0 ${Ye ? "" : "flex-1"} ${i === "display" ? "text-dc-primary border-b-2 border-dc-primary" : t.length === 0 ? "text-dc-text-muted cursor-not-allowed opacity-50" : "text-dc-text-secondary hover:text-dc-text"}`,
title: t.length === 0 ? "Add metrics to configure display" : "Display options",
children: "Display"
}
)
] }),
Ye && i === "query" && /* @__PURE__ */ d("div", { className: "flex items-center gap-2 px-4 py-1.5 text-sm bg-dc-surface-secondary border-b border-dc-border", children: [
Ps && /* @__PURE__ */ r(Ps, { className: "w-3.5 h-3.5 text-dc-text-muted flex-shrink-0" }),
/* @__PURE__ */ d(
"select",
{
value: te,
onChange: (ae) => X?.(ae.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__ */ r("option", { value: "concat", children: "Separate series" }),
/* @__PURE__ */ r("option", { value: "merge", children: "Merge by dimension" }),
/* @__PURE__ */ r("option", { value: "funnel", children: "Funnel" })
]
}
),
st && H && /* @__PURE__ */ r(
cd,
{
bindingKey: z ?? null,
onChange: H,
schema: a,
className: "w-[180px] flex-shrink-0"
}
)
] }),
pe && (pe.errors.length > 0 || pe.warnings.length > 0) && i === "query" && /* @__PURE__ */ d("div", { className: "px-4 py-2 border-b border-dc-border bg-dc-warning-bg space-y-1", children: [
pe.errors.map((ae, U) => /* @__PURE__ */ d("div", { className: "flex items-start gap-2 text-xs text-dc-error", children: [
/* @__PURE__ */ r(ar, { className: "w-3.5 h-3.5 mt-0.5 flex-shrink-0" }),
/* @__PURE__ */ r("span", { children: ae })
] }, `adapter-error-${U}`)),
pe.warnings.map((ae, U) => /* @__PURE__ */ d("div", { className: "flex items-start gap-2 text-xs text-dc-warning", children: [
/* @__PURE__ */ r(sr, { className: "w-3.5 h-3.5 mt-0.5 flex-shrink-0" }),
/* @__PURE__ */ r("span", { children: ae })
] }, `adapter-warning-${U}`))
] }),
L && !st && (L.warnings.length > 0 || L.errors.length > 0) && i === "query" && /* @__PURE__ */ d("div", { className: "px-4 py-2 border-b border-dc-border bg-dc-warning-bg", children: [
L.errors.map((ae, U) => /* @__PURE__ */ d("div", { className: "flex items-start gap-2 text-xs text-dc-error", children: [
/* @__PURE__ */ r(ar, { className: "w-3.5 h-3.5 mt-0.5 flex-shrink-0" }),
/* @__PURE__ */ r("span", { children: ae.message })
] }, `error-${U}`)),
L.warnings.map((ae, U) => /* @__PURE__ */ d("div", { className: "flex items-start gap-2 text-xs text-dc-warning", children: [
/* @__PURE__ */ r(ar, { className: "w-3.5 h-3.5 mt-0.5 flex-shrink-0" }),
/* @__PURE__ */ r("span", { children: ae.message })
] }, `warning-${U}`))
] }),
/* @__PURE__ */ r("div", { className: "flex-1 overflow-auto p-4", children: i === "query" ? /* @__PURE__ */ d("div", { className: "space-y-6", children: [
/* @__PURE__ */ r(
Ac,
{
metrics: t,
schema: a,
onAdd: c,
onRemove: l,
order: A,
onOrderChange: w,
onReorder: u
}
),
ce ? /* @__PURE__ */ d("div", { className: "mb-4", children: [
/* @__PURE__ */ r("div", { className: "flex items-center justify-between mb-2", children: /* @__PURE__ */ r("h4", { className: "text-sm font-medium text-dc-text", children: "Dimensions" }) }),
/* @__PURE__ */ d("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: [
sr && /* @__PURE__ */ r(sr, { className: "w-4 h-4 text-dc-text-muted flex-shrink-0 mt-0.5" }),
/* @__PURE__ */ d("span", { className: "text-dc-text-muted", children: [
"In merge mode, dimensions are shared from Q1.",
X && /* @__PURE__ */ r(
"button",
{
onClick: () => X("concat"),
className: "text-dc-primary hover:underline ml-1",
children: "Switch to separate series"
}
)
] })
] }),
n.length > 0 && /* @__PURE__ */ r("div", { className: "space-y-1", children: n.map((ae) => /* @__PURE__ */ r(
Qa,
{
breakdown: ae,
fieldMeta: M(ae),
onRemove: () => {
},
onGranularityChange: ae.isTimeDimension ? (U) => m(ae.id, U) : void 0,
onComparisonToggle: ae.isTimeDimension && g ? () => g(ae.id) : void 0,
comparisonDisabled: !!I && I.id !== ae.id
},
ae.id
)) })
] }) : /* @__PURE__ */ r(
Rc,
{
breakdowns: n,
schema: a,
onAdd: h,
onRemove: f,
onGranularityChange: m,
onComparisonToggle: g,
order: A,
onOrderChange: w,
onReorder: b
}
),
/* @__PURE__ */ r(
Qr,
{
filters: s,
schema: a,
onFiltersChange: N,
onFieldDropped: x
}
)
] }) : i === "chart" ? (
/* Chart Tab Content - use combined metrics/breakdowns in multi-query mode */
/* @__PURE__ */ r(
nd,
{
chartType: y,
chartConfig: C,
metrics: Ye && Q ? Q : t,
breakdowns: Ye && Se ? Se : n,
schema: a,
chartAvailability: v,
onChartTypeChange: k,
onChartConfigChange: S
}
)
) : i === "display" ? (
/* Display Tab Content */
/* @__PURE__ */ r(
jr,
{
chartType: y,
displayConfig: T,
colorPalette: p,
onDisplayConfigChange: $
}
)
) : null })
] })
] });
}), qs = q("sparkles"), Od = q("error");
function $d({
userPrompt: e,
onPromptChange: t,
isGenerating: n,
error: s,
hasGeneratedQuery: a,
onGenerate: i,
onAccept: o,
onCancel: c
}) {
const l = E(
(u) => {
u.key === "Enter" && !u.shiftKey && (u.preventDefault(), i());
},
[i]
);
return /* @__PURE__ */ d(
"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__ */ d("div", { className: "px-4 py-2 flex items-center justify-between border-b border-dc-border bg-dc-surface-secondary", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(qs, { className: "w-4 h-4 text-dc-accent" }),
/* @__PURE__ */ r("span", { className: "text-sm font-medium text-dc-text", children: "AI Query Generator" }),
n && /* @__PURE__ */ r("span", { className: "text-xs text-dc-accent animate-pulse", children: "Generating..." })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
a && /* @__PURE__ */ r(
"button",
{
onClick: o,
className: "px-3 py-1 text-xs font-medium text-white bg-dc-success hover:opacity-80 rounded transition-colors",
children: "Accept"
}
),
/* @__PURE__ */ r(
"button",
{
onClick: c,
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__ */ d("div", { className: "p-4", children: [
/* @__PURE__ */ d("div", { className: "flex gap-3", children: [
/* @__PURE__ */ d("div", { className: "flex-1", children: [
/* @__PURE__ */ r(
"textarea",
{
value: e,
onChange: (u) => t(u.target.value),
onKeyDown: l,
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__ */ r("div", { className: "mt-1 text-xs text-dc-text-muted", children: "Press Enter to generate, Shift+Enter for new line" })
] }),
/* @__PURE__ */ r("div", { className: "flex-shrink-0", children: /* @__PURE__ */ r(
"button",
{
onClick: i,
disabled: n || !e.trim(),
className: `px-4 py-2 text-sm font-medium rounded-md transition-colors flex items-center gap-2 ${n || !e.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__ */ d(Ce, { children: [
/* @__PURE__ */ r("div", { className: "w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" }),
/* @__PURE__ */ r("span", { children: "Generating..." })
] }) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(qs, { className: "w-4 h-4" }),
/* @__PURE__ */ r("span", { children: "Generate" })
] })
}
) })
] }),
s && /* @__PURE__ */ d("div", { className: "mt-3 flex items-start gap-2 p-3 bg-dc-error-bg border border-dc-error-border rounded-md", children: [
/* @__PURE__ */ r(Od, { className: "w-4 h-4 text-dc-error mt-0.5 flex-shrink-0" }),
/* @__PURE__ */ r("div", { className: "text-sm text-dc-error", children: s })
] }),
a && !s && /* @__PURE__ */ r("div", { className: "mt-3 p-3 bg-dc-success-bg border border-dc-success-border rounded-md", children: /* @__PURE__ */ d("div", { className: "text-sm text-dc-success", children: [
"Query generated and loaded! Check the results below, then click",
" ",
/* @__PURE__ */ r("strong", { children: "Accept" }),
" to keep or ",
/* @__PURE__ */ r("strong", { children: "Cancel" }),
" to revert."
] }) })
] })
]
}
);
}
const Bs = q("warning"), Qs = q("refresh");
class Ld extends aa {
constructor(t) {
super(t), this.state = {
hasError: !1,
error: null,
errorInfo: null
};
}
static getDerivedStateFromError(t) {
return {
hasError: !0,
error: t,
errorInfo: null
};
}
componentDidCatch(t, n) {
this.setState({
error: t,
errorInfo: n.componentStack || null
}), console.error(
`[AnalysisModeErrorBoundary] Error in ${this.props.analysisType} mode:`,
t,
n
);
}
handleReset = () => {
this.setState({
hasError: !1,
error: null,
errorInfo: null
});
};
handleSwitchToSafeMode = () => {
this.handleReset(), this.props.onSwitchToSafeMode?.();
};
render() {
return this.state.hasError ? /* @__PURE__ */ d("div", { className: "flex flex-col items-center justify-center w-full h-full p-6 text-center bg-dc-surface", children: [
/* @__PURE__ */ r("div", { className: "h-10 w-10 mb-3 text-dc-warning", children: Bs && /* @__PURE__ */ r(Bs, { className: "w-10 h-10" }) }),
/* @__PURE__ */ r("h3", { className: "text-base font-semibold mb-2 text-dc-text", children: "Mode Error" }),
/* @__PURE__ */ d("p", { className: "text-sm text-dc-text-secondary mb-3 max-w-sm", children: [
"There was a problem with the ",
/* @__PURE__ */ r("strong", { children: this.props.analysisType }),
" mode. This might be due to invalid configuration data."
] }),
/* @__PURE__ */ d("details", { className: "w-full max-w-md mb-4 text-left", children: [
/* @__PURE__ */ r("summary", { className: "cursor-pointer text-xs text-dc-text-muted hover:text-dc-text", children: "Show error details" }),
/* @__PURE__ */ r("div", { className: "mt-2 p-2 bg-dc-surface-secondary rounded text-xs font-mono text-dc-text-secondary overflow-auto max-h-32", children: this.state.error?.message || "Unknown error" })
] }),
/* @__PURE__ */ d("div", { className: "flex gap-2", children: [
/* @__PURE__ */ d(
"button",
{
onClick: this.handleReset,
className: "px-3 py-1.5 border border-dc-border rounded text-sm text-dc-text hover:bg-dc-surface-hover transition-colors flex items-center gap-1",
children: [
Qs && /* @__PURE__ */ r(Qs, { className: "w-4 h-4" }),
"Try Again"
]
}
),
this.props.onSwitchToSafeMode && /* @__PURE__ */ r(
"button",
{
onClick: this.handleSwitchToSafeMode,
className: "px-3 py-1.5 bg-dc-primary text-white rounded text-sm hover:opacity-90 transition-opacity",
children: "Switch to Query Mode"
}
)
] })
] }) : this.props.children;
}
}
const za = Ln(
({
className: e = "",
maxHeight: t,
initialData: n,
colorPalette: s,
hideSettings: a = !1,
hideShare: i = !1,
onQueryChange: o,
onChartConfigChange: c
}, l) => {
const { meta: u } = la(), { features: h } = an(), f = Jl({
initialData: n,
externalColorPalette: s,
onQueryChange: o,
onChartConfigChange: c
}), m = Ia(), {
aiState: g,
handleOpenAI: b,
handleCloseAI: N,
handleAIPromptChange: x,
handleGenerateAI: A,
handleAcceptAI: w,
handleCancelAI: y
} = tc({
state: f.queryState,
setState: (v) => {
m.getState().updateQueryState(f.activeQueryIndex, (S) => {
const $ = typeof v == "function" ? v(S) : v;
return {
...S,
metrics: $.metrics,
breakdowns: $.breakdowns,
filters: $.filters
};
});
},
chartType: f.chartType,
setChartType: f.actions.setChartType,
chartConfig: f.chartConfig,
setChartConfig: f.actions.setChartConfig,
displayConfig: f.displayConfig,
setDisplayConfig: f.actions.setDisplayConfig,
setUserManuallySelectedChart: () => {
},
setActiveView: f.actions.setActiveView,
aiEndpoint: h?.aiEndpoint,
// Funnel mode support
analysisType: f.analysisType,
setAnalysisType: f.actions.setAnalysisType,
loadFunnelFromServerQuery: (v) => {
const k = {
version: 1,
analysisType: "funnel",
activeView: "chart",
charts: {
funnel: {
chartType: "funnel",
chartConfig: {},
displayConfig: {}
}
},
query: v
};
m.getState().load(k);
},
// Full config snapshot/restore for complete undo (handles funnel mode properly)
getFullConfig: () => m.getState().save(),
loadFullConfig: (v) => m.getState().load(v)
}), {
shareButtonState: C,
handleShare: T
} = nc({
isValidQuery: f.isValidQuery,
getAnalysisConfig: () => m.getState().save()
}), p = V(() => f.analysisType === "funnel" ? f.funnelSteps.length > 0 || f.funnelCube !== null || f.funnelBindingKey !== null || f.funnelTimeDimension !== null : f.queryState.metrics.length > 0 || f.queryState.breakdowns.length > 0 || f.queryState.filters.length > 0, [
f.analysisType,
f.funnelSteps.length,
f.funnelCube,
f.funnelBindingKey,
f.funnelTimeDimension,
f.queryState.metrics.length,
f.queryState.breakdowns.length,
f.queryState.filters.length
]);
return Dr(
l,
() => ({
getQueryConfig: f.getQueryConfig,
getChartConfig: f.getChartConfig,
getAnalysisType: f.getAnalysisType,
getFunnelState: () => {
const v = m.getState(), k = v.charts.funnel || {
chartType: "funnel",
chartConfig: {},
displayConfig: { showLegend: !0, showGrid: !0, showTooltip: !0 }
};
return {
funnelCube: v.funnelCube,
funnelSteps: v.funnelSteps,
funnelTimeDimension: v.funnelTimeDimension,
funnelBindingKey: v.funnelBindingKey,
funnelChartType: k.chartType,
funnelChartConfig: k.chartConfig,
funnelDisplayConfig: k.displayConfig,
activeFunnelStepIndex: v.activeFunnelStepIndex
};
},
// Phase 3: Complete AnalysisConfig from store.save()
getAnalysisConfig: () => m.getState().save(),
executeQuery: () => {
},
clearQuery: f.actions.clearQuery
}),
[
f.getQueryConfig,
f.getChartConfig,
f.getAnalysisType,
f.actions.clearQuery,
m
]
), /* @__PURE__ */ d(
"div",
{
className: `flex flex-col lg:flex-row bg-dc-surface border-x border-b border-dc-border ${t ? "lg:h-[var(--dc-max-h)] lg:max-h-[var(--dc-max-h)] lg:overflow-hidden" : "lg:h-full"} ${e}`,
style: t ? { "--dc-max-h": t } : void 0,
children: [
/* @__PURE__ */ d("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: [
g.isOpen && /* @__PURE__ */ r(
$d,
{
userPrompt: g.userPrompt,
onPromptChange: x,
isGenerating: g.isGenerating,
error: g.error,
hasGeneratedQuery: g.hasGeneratedQuery,
onGenerate: A,
onAccept: w,
onCancel: y
}
),
/* @__PURE__ */ r("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ r(
Cc,
{
executionStatus: f.executionStatus,
executionResults: f.executionResults,
executionError: f.error?.message || null,
totalRowCount: null,
resultsStale: f.isLoading && f.executionResults !== null,
chartType: f.chartType,
chartConfig: f.chartConfig,
displayConfig: f.analysisType === "flow" ? f.flowDisplayConfig : f.analysisType === "funnel" ? f.funnelDisplayConfig : f.displayConfig,
colorPalette: f.colorPalette,
currentPaletteName: s ? void 0 : f.localPaletteName,
onColorPaletteChange: s ? void 0 : f.actions.setLocalPaletteName,
allQueries: f.allQueries,
funnelExecutedQueries: f.funnelExecutedQueries ?? void 0,
schema: u,
activeView: f.activeView,
onActiveViewChange: f.actions.setActiveView,
displayLimit: f.displayLimit,
onDisplayLimitChange: f.actions.setDisplayLimit,
hasMetrics: f.analysisType === "funnel" ? f.funnelSteps.length >= 2 && !!f.funnelBindingKey && !!f.funnelTimeDimension : f.queryState.metrics.length > 0,
debugDataPerQuery: f.debugDataPerQuery,
onShareClick: i ? void 0 : T,
canShare: i ? !1 : f.isValidQuery,
shareButtonState: C,
onRefreshClick: f.actions.refetch,
canRefresh: f.isValidQuery,
isRefreshing: f.isFetching,
onClearClick: f.actions.clearCurrentMode,
canClear: p,
enableAI: h?.enableAI !== !1,
isAIOpen: g.isOpen,
onAIToggle: g.isOpen ? N : b,
queryCount: f.queryStates.length,
perQueryResults: f.perQueryResults ?? void 0,
activeTableIndex: f.activeTableIndex,
onActiveTableChange: f.actions.setActiveTableIndex,
analysisType: f.analysisType,
isFunnelMode: f.isFunnelModeEnabled,
funnelServerQuery: f.funnelServerQuery,
funnelDebugData: f.funnelDebugData,
flowServerQuery: f.flowServerQuery,
flowDebugData: f.flowDebugData
}
) })
] }),
/* @__PURE__ */ r("div", { className: "w-full lg:w-96 flex-shrink-0 lg:h-full overflow-auto lg:overflow-hidden", children: /* @__PURE__ */ r(
Ld,
{
analysisType: f.analysisType,
onSwitchToSafeMode: () => f.actions.setAnalysisType("query"),
children: /* @__PURE__ */ r(
_d,
{
metrics: f.queryState.metrics,
breakdowns: f.effectiveBreakdowns,
filters: f.queryState.filters,
schema: u,
activeTab: f.activeTab,
onActiveTabChange: f.actions.setActiveTab,
onAddMetric: f.actions.openMetricsModal,
onRemoveMetric: f.actions.removeMetric,
onReorderMetrics: f.actions.reorderMetrics,
onAddBreakdown: f.actions.openBreakdownsModal,
onRemoveBreakdown: f.actions.removeBreakdown,
onBreakdownGranularityChange: f.actions.setBreakdownGranularity,
onBreakdownComparisonToggle: f.actions.toggleBreakdownComparison,
onReorderBreakdowns: f.actions.reorderBreakdowns,
onFiltersChange: f.actions.setFilters,
onDropFieldToFilter: f.actions.dropFieldToFilter,
order: f.queryState.order,
onOrderChange: f.actions.setOrder,
chartType: f.chartType,
chartConfig: f.chartConfig,
displayConfig: f.displayConfig,
colorPalette: f.colorPalette,
chartAvailability: f.chartAvailability,
onChartTypeChange: f.actions.setChartType,
onChartConfigChange: f.actions.setChartConfig,
onDisplayConfigChange: f.actions.setDisplayConfig,
validationStatus: f.queryState.validationStatus,
validationError: f.queryState.validationError,
queryCount: f.queryStates.length,
activeQueryIndex: f.activeQueryIndex,
mergeStrategy: f.mergeStrategy,
onActiveQueryChange: f.actions.setActiveQueryIndex,
onAddQuery: f.actions.addQuery,
onRemoveQuery: f.actions.removeQuery,
onMergeStrategyChange: f.actions.setMergeStrategy,
breakdownsLocked: f.mergeStrategy === "merge" && f.activeQueryIndex > 0,
combinedMetrics: f.combinedMetrics,
combinedBreakdowns: f.combinedBreakdowns,
multiQueryValidation: f.multiQueryValidation,
adapterValidation: f.adapterValidation,
funnelBindingKey: f.funnelBindingKey,
onFunnelBindingKeyChange: f.actions.setFunnelBindingKey,
analysisType: f.analysisType,
onAnalysisTypeChange: f.actions.setAnalysisType,
funnelCube: f.funnelCube,
funnelSteps: f.funnelSteps,
activeFunnelStepIndex: f.activeFunnelStepIndex,
funnelTimeDimension: f.funnelTimeDimension,
onFunnelCubeChange: f.actions.setFunnelCube,
onAddFunnelStep: f.actions.addFunnelStep,
onRemoveFunnelStep: f.actions.removeFunnelStep,
onUpdateFunnelStep: f.actions.updateFunnelStep,
onSelectFunnelStep: f.actions.setActiveFunnelStepIndex,
onReorderFunnelSteps: f.actions.reorderFunnelSteps,
onFunnelTimeDimensionChange: f.actions.setFunnelTimeDimension,
funnelDisplayConfig: f.funnelDisplayConfig,
onFunnelDisplayConfigChange: f.actions.setFunnelDisplayConfig,
flowCube: f.flowCube,
flowBindingKey: f.flowBindingKey,
flowTimeDimension: f.flowTimeDimension,
eventDimension: f.eventDimension,
startingStep: f.startingStep,
stepsBefore: f.stepsBefore,
stepsAfter: f.stepsAfter,
flowJoinStrategy: f.joinStrategy,
onFlowCubeChange: f.actions.setFlowCube,
onFlowBindingKeyChange: f.actions.setFlowBindingKey,
onFlowTimeDimensionChange: f.actions.setFlowTimeDimension,
onEventDimensionChange: f.actions.setEventDimension,
onStartingStepFiltersChange: f.actions.setStartingStepFilters,
onStepsBeforeChange: f.actions.setStepsBefore,
onStepsAfterChange: f.actions.setStepsAfter,
onFlowJoinStrategyChange: f.actions.setJoinStrategy,
flowDisplayConfig: f.flowDisplayConfig,
onFlowDisplayConfigChange: f.actions.setFlowDisplayConfig
}
)
}
) }),
/* @__PURE__ */ r(
qr,
{
isOpen: f.showFieldModal,
onClose: f.actions.closeFieldModal,
onSelect: f.actions.handleFieldSelected,
mode: f.fieldModalMode,
schema: u,
selectedFields: [
...f.queryState.metrics.map((v) => v.field),
...f.effectiveBreakdowns.map((v) => v.field)
]
}
)
]
}
);
}
);
za.displayName = "AnalysisBuilderInner";
const Vr = Ln(
(e, t) => {
const {
initialQuery: n,
initialChartConfig: s,
initialAnalysisType: a,
initialFunnelState: i,
initialFlowState: o,
disableLocalStorage: c = !1,
...l
} = e, u = $a(), h = u ? Oa(u) : null, f = h?.activeView, m = h?.analysisType, g = (() => {
if (!h || h.analysisType !== "funnel") return;
const x = "funnel" in h.query ? h.query.funnel : null;
if (!x) return;
const A = h.charts?.funnel;
return {
funnelCube: null,
// Not stored in AnalysisConfig directly - will be derived from steps
funnelSteps: [],
// Steps need to be reconstructed from ServerFunnelQuery format
funnelTimeDimension: typeof x.timeDimension == "string" ? x.timeDimension : null,
funnelBindingKey: x.bindingKey ? { dimension: x.bindingKey } : null,
funnelChartType: A?.chartType || "funnel",
funnelChartConfig: A?.chartConfig || {},
funnelDisplayConfig: A?.displayConfig || {}
};
})(), b = (() => {
if (!h || h.analysisType !== "flow") return;
const x = "flow" in h.query ? h.query.flow : null;
if (!x) return;
const A = h.charts?.flow;
return {
flowCube: null,
// Not stored in AnalysisConfig directly
flowBindingKey: x.bindingKey ? typeof x.bindingKey == "string" ? { dimension: x.bindingKey } : { dimension: x.bindingKey[0]?.dimension || "" } : null,
flowTimeDimension: typeof x.timeDimension == "string" ? x.timeDimension : x.timeDimension?.[0]?.dimension || null,
startingStep: x.startingStep ? {
name: x.startingStep.name || "",
filters: Array.isArray(x.startingStep.filter) ? x.startingStep.filter : x.startingStep.filter ? [x.startingStep.filter] : []
} : { name: "", filters: [] },
stepsBefore: x.stepsBefore ?? 3,
stepsAfter: x.stepsAfter ?? 3,
eventDimension: x.eventDimension || null,
flowChartType: A?.chartType || "sankey",
flowChartConfig: A?.chartConfig || {},
flowDisplayConfig: A?.displayConfig || {}
};
})();
return /* @__PURE__ */ r(
Tl,
{
initialQuery: n,
initialChartConfig: s,
initialAnalysisType: a || m,
initialFunnelState: i || g,
initialFlowState: o || b,
initialActiveView: f,
disableLocalStorage: c || !!n || !!i || !!o || !!u,
children: /* @__PURE__ */ r(za, { ref: t, ...l, hideShare: !!n || !!i || !!o })
}
);
}
);
Vr.displayName = "AnalysisBuilder";
function js({
isOpen: e,
onClose: t,
onSave: n,
portlet: s,
initialData: a,
title: i,
submitText: o,
colorPalette: c,
dashboardFilters: l
}) {
const u = ge(null), [h, f] = ee(""), m = V(() => {
if (!l || !s?.dashboardFilterMapping)
return [];
const p = s.dashboardFilterMapping;
return l.filter((v) => !v.isUniversalTime && p.includes(v.id)).map((v) => v.filter);
}, [l, s?.dashboardFilterMapping]), g = V(() => s ? ln(s).analysisConfig : null, [s]), b = V(() => {
if (!g) return;
const p = g.query;
if (!p) return;
if (g.analysisType === "funnel")
return p;
if ("queries" in p && Array.isArray(p.queries))
return {
...p,
queries: p.queries.map((k) => ({
...k,
// Merge regular dashboard filters (not universal time)
filters: en(m, k.filters, "client"),
// Apply universal time filter dateRange to all time dimensions
timeDimensions: An(
l,
s?.dashboardFilterMapping,
k.timeDimensions
)
}))
};
const v = p;
return {
...v,
// Merge regular dashboard filters (not universal time)
filters: en(m, v.filters, "client"),
// Apply universal time filter dateRange to all time dimensions
timeDimensions: An(
l,
s?.dashboardFilterMapping,
v.timeDimensions
)
};
}, [g, m, l, s?.dashboardFilterMapping]), N = V(() => {
if (!g) return;
const p = g.charts[g.analysisType];
if (p)
return {
chartType: p.chartType,
chartConfig: p.chartConfig,
displayConfig: p.displayConfig
};
}, [g]), x = g?.analysisType, A = V(() => {
if (g?.analysisType === "funnel") {
if (s?.funnelSteps && s.funnelSteps.length > 0)
return {
funnelCube: s.funnelCube,
funnelSteps: s.funnelSteps,
funnelTimeDimension: s.funnelTimeDimension,
funnelBindingKey: s.funnelBindingKey,
funnelChartType: s.funnelChartType,
funnelChartConfig: s.funnelChartConfig,
funnelDisplayConfig: s.funnelDisplayConfig
};
if (g.query && "funnel" in g.query) {
const p = Qt.load(g), v = g.charts?.funnel;
return {
...p,
funnelChartType: v?.chartType,
funnelChartConfig: v?.chartConfig,
funnelDisplayConfig: v?.displayConfig
};
}
}
}, [g, s]), w = V(() => {
if (g?.analysisType === "flow" && g.query && "flow" in g.query) {
const p = jt.load(g), v = g.charts?.flow;
return {
...p,
flowChartType: v?.chartType,
flowChartConfig: v?.chartConfig,
flowDisplayConfig: v?.displayConfig
};
}
}, [g]);
he(() => {
e && f(s?.title || "");
}, [e, s]);
const y = E(() => {
if (!h.trim()) {
alert("Please enter a title for the portlet.");
return;
}
const p = u.current?.getAnalysisConfig();
if (!p) {
alert("Please configure a query before saving.");
return;
}
const { query: v, analysisType: k } = p;
let S = !1;
if ("flow" in v && v.flow)
S = !!(v.flow.bindingKey && v.flow.timeDimension && v.flow.eventDimension && v.flow.startingStep?.filter);
else if ("funnel" in v && v.funnel)
S = !!(v.funnel.steps && v.funnel.steps.length >= 2);
else if ("queries" in v) {
const D = v.queries[0];
S = !!(D?.measures && D.measures.length > 0 || D?.dimensions && D.dimensions.length > 0 || D?.timeDimensions && D.timeDimensions.length > 0);
} else {
const D = v;
S = !!(D.measures && D.measures.length > 0 || D.dimensions && D.dimensions.length > 0 || D.timeDimensions && D.timeDimensions.length > 0);
}
if (!S) {
let D;
k === "flow" ? D = "Please configure the flow analysis (binding key, time dimension, event dimension, and starting step filter)." : k === "funnel" ? D = "Please add at least two funnel steps." : D = "Please add at least one metric or breakdown to your query.", alert(D);
return;
}
const $ = {
...s || {},
title: h.trim(),
// === Canonical format - single source of truth ===
analysisConfig: p,
// Preserve dashboard filter mapping and eager load settings
dashboardFilterMapping: s?.dashboardFilterMapping,
eagerLoad: s?.eagerLoad,
// Preserve existing position or use defaults for new portlets
w: s?.w || 5,
h: s?.h || 4
};
n($), t();
}, [h, s, n, t]), C = E(() => {
t();
}, [t]);
return /* @__PURE__ */ r(
Rr,
{
isOpen: e,
onClose: t,
title: i,
size: "fullscreen-mobile",
showCloseButton: !0,
closeOnBackdropClick: !1,
closeOnEscape: !0,
noPadding: !0,
footer: /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(
"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__ */ r(
"button",
{
type: "button",
onClick: y,
className: "px-4 py-2 text-sm font-medium text-white bg-dc-accent hover:bg-dc-accent-hover rounded-md transition-colors",
children: o
}
)
] }),
children: /* @__PURE__ */ d("div", { className: "flex flex-col h-full", children: [
/* @__PURE__ */ r("div", { className: "shrink-0 px-4 py-3 border-b border-dc-border bg-dc-surface-secondary", children: /* @__PURE__ */ d("div", { className: "flex items-center gap-3", children: [
/* @__PURE__ */ r("label", { htmlFor: "portlet-title", className: "text-sm font-medium text-dc-text-secondary shrink-0", children: "Title" }),
/* @__PURE__ */ r(
"input",
{
id: "portlet-title",
type: "text",
value: h,
onChange: (p) => f(p.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__ */ r("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ r(
Vr,
{
ref: u,
maxHeight: "100%",
initialQuery: b,
initialChartConfig: N,
initialAnalysisType: x,
initialFunnelState: A,
initialFlowState: w,
initialData: a,
colorPalette: c,
disableLocalStorage: !0,
className: "h-full"
}
) })
] })
}
);
}
function Pd({
isOpen: e,
onClose: t,
dashboardFilters: n = [],
currentMapping: s = [],
onSave: a,
portletTitle: i
}) {
const [o, c] = ee(s);
he(() => {
c(s);
}, [s, e]);
const l = (m) => {
c((g) => g.includes(m) ? g.filter((b) => b !== m) : [...g, m]);
}, u = () => {
a(o), t();
}, h = () => {
c(s), t();
}, f = (m) => {
if (!m.filter) return "";
if ("member" in m.filter && m.filter.member) {
const g = m.filter.values || [], b = g.length > 0 ? g.join(", ") : "no value";
return `${m.filter.member} ${m.filter.operator} ${b}`;
}
if ("type" in m.filter && m.filter.type) {
const g = m.filter.filters?.length || 0;
return `${m.filter.type.toUpperCase()} group with ${g} filter${g !== 1 ? "s" : ""}`;
}
return "Complex filter";
};
return e ? /* @__PURE__ */ r("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50", onClick: h, children: /* @__PURE__ */ d(
"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__ */ d("div", { className: "px-6 py-4 border-b border-dc-border bg-dc-surface-secondary rounded-t-lg", children: [
/* @__PURE__ */ r("h2", { className: "text-lg font-semibold text-dc-text", children: "Configure Dashboard Filters" }),
/* @__PURE__ */ d("p", { className: "text-sm text-dc-text-secondary mt-1", children: [
'Choose which dashboard filters apply to "',
i,
'"'
] })
] }),
/* @__PURE__ */ r("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: n.length === 0 ? /* @__PURE__ */ d("div", { className: "text-center py-8 text-dc-text-muted", children: [
/* @__PURE__ */ r(
"svg",
{
className: "mx-auto h-12 w-12 mb-3",
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor",
children: /* @__PURE__ */ r(
"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__ */ r("p", { className: "text-sm font-medium", children: "No dashboard filters available" }),
/* @__PURE__ */ r("p", { className: "text-xs mt-1", children: "Add filters at the dashboard level first" })
] }) : /* @__PURE__ */ d("div", { className: "space-y-3", children: [
/* @__PURE__ */ d("div", { className: "flex items-center justify-between mb-4 pb-2 border-b border-dc-border", children: [
/* @__PURE__ */ r("span", { className: "text-sm font-medium text-dc-text", children: "Available Filters" }),
/* @__PURE__ */ d("span", { className: "text-xs text-dc-text-secondary", children: [
o.length,
" of ",
n.length,
" selected"
] })
] }),
n.map((m) => {
const g = o.includes(m.id);
return /* @__PURE__ */ d(
"label",
{
className: `flex items-start p-3 rounded-md border cursor-pointer transition-colors ${g ? "border-dc-primary bg-dc-surface-secondary" : "border-dc-border hover:bg-dc-surface-hover"}`,
children: [
/* @__PURE__ */ r(
"input",
{
type: "checkbox",
checked: g,
onChange: () => l(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__ */ d("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r("span", { className: "font-medium text-sm text-dc-text truncate", children: m.label }),
g && /* @__PURE__ */ r(
"span",
{
className: "px-2 py-0.5 text-xs rounded-full",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: "Applied"
}
)
] }),
/* @__PURE__ */ r("div", { className: "mt-1 text-xs text-dc-text-secondary break-words", children: f(m) })
] })
]
},
m.id
);
})
] }) }),
/* @__PURE__ */ d("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__ */ r(
"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__ */ r(
"button",
{
onClick: u,
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 Ks = q("close"), ir = q("chevronDown"), Vs = q("dimension"), qd = q("timeDimension"), Bd = q("measure"), Qd = q("edit"), jd = q("eye"), Kd = q("eyeOff");
function Vd({
filter: e,
fullSchema: t,
filteredSchema: n,
isOpen: s,
onSave: a,
onDelete: i,
onClose: o
}) {
const [c, l] = ee(e.label), [u, h] = ee(e.filter), [f, m] = ee(!1), [g, b] = ee(!1), [N, x] = ee(!1), [A, w] = ee(!1), [y, C] = ee(!1), [T, p] = ee("this_month"), [v, k] = ee(1), [S, $] = ee(""), D = ge(null), F = f ? t : n;
he(() => {
s && (l(e.label), h(e.filter));
}, [e, s]);
const K = Ar(S, 300), P = jn(u.member, F), te = P?.field.type || "string", _ = te === "time", O = P?.fieldType === "measure", ie = P?.fieldType === "dimension", X = _r(u.member, F), ce = qn[u.operator], Q = mr(te), Se = _ && u.operator === "inDateRange", L = ["equals", "notEquals", "in", "notIn"].includes(u.operator) && ie && !_, {
values: pe,
loading: z,
error: H,
searchValues: se
} = Mr(u.member, L);
he(() => {
const re = (be) => {
D.current && !D.current.contains(be.target) && (x(!1), w(!1), C(!1));
};
return document.addEventListener("mousedown", re), () => document.removeEventListener("mousedown", re);
}, []), he(() => {
A && L && se && se("", !0);
}, [A, L, se]), he(() => {
A && L && se && K !== void 0 && se(K);
}, [K, A, L, se]), he(() => {
if (!(!Se || !u.dateRange))
if (Array.isArray(u.dateRange))
p("custom");
else {
const re = u.dateRange.match(/^last (\d+) (days|weeks|months|quarters|years)$/), be = !re && u.dateRange.match(/^last (day|week|month|quarter|year)$/);
if (re) {
const [, Ee, qe] = re;
p(`last_n_${qe}`), k(parseInt(Ee) || 1);
} else if (be) {
const [, Ee] = be;
p(`last_n_${Ee === "day" ? "days" : Ee === "week" ? "weeks" : Ee === "month" ? "months" : Ee === "quarter" ? "quarters" : "years"}`), k(1);
} else {
let Ee = !1;
for (const qe of Ht)
if (qe.value !== "custom" && !Ot(qe.value) && Dt(qe.value) === u.dateRange) {
p(qe.value), Ee = !0;
break;
}
Ee || p("custom");
}
}
}, [u.dateRange, Se]);
const me = E((re, be) => {
const Ee = re.type, Ze = mr(Ee)[0]?.operator || "equals";
h({
member: re.name,
operator: Ze,
values: []
}), b(!1);
}, []), le = E((re) => {
h({
member: u.member,
operator: re,
values: []
}), x(!1);
}, [u.member]), we = E((re) => {
const be = u.values || [];
ce?.supportsMultipleValues ? be.includes(re) || h({ ...u, values: [...be, re] }) : (h({ ...u, values: [re] }), w(!1)), $("");
}, [u, ce?.supportsMultipleValues]), Y = E((re) => {
const be = (u.values || []).filter((Ee) => Ee !== re);
h({ ...u, values: be });
}, [u]), Pe = E((re) => {
const be = re.target.value;
if (ce?.valueType === "number") {
const Ee = parseFloat(be);
isNaN(Ee) ? (be === "" || be === "-") && h({ ...u, values: [] }) : h({ ...u, values: [Ee] });
} else
h({ ...u, values: be ? [be] : [] });
}, [u, ce?.valueType]), He = E((re) => {
const be = parseFloat(re.target.value), Ee = u.values?.length >= 2 ? u.values : ["", ""], qe = [isNaN(be) ? "" : be, Ee[1]].filter((Ze) => Ze !== "");
h({ ...u, values: qe });
}, [u]), Ne = E((re) => {
const be = parseFloat(re.target.value), qe = [(u.values?.length >= 2 ? u.values : ["", ""])[0], isNaN(be) ? "" : be].filter((Ze) => Ze !== "");
h({ ...u, values: qe });
}, [u]), _e = E((re) => {
const be = re.target.value;
h({ ...u, values: be ? [be] : [] });
}, [u]), We = E((re) => {
p(re), C(!1);
let be;
if (re === "custom") {
const Ee = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
be = [Ee, Ee];
} else Ot(re) ? be = Dt(re, v) : be = Dt(re);
h({ ...u, dateRange: be });
}, [u, v]), Je = E((re) => {
if (k(re), Ot(T)) {
const be = Dt(T, re);
h({ ...u, dateRange: be });
}
}, [u, T]), Ke = E((re) => {
const be = re.target.value, qe = (Array.isArray(u.dateRange) ? u.dateRange : [u.dateRange || "", ""])[1] || be;
h({ ...u, dateRange: [be, qe] });
}, [u]), Oe = E((re) => {
const be = re.target.value, qe = (Array.isArray(u.dateRange) ? u.dateRange : ["", u.dateRange || ""])[0] || be;
h({ ...u, dateRange: [qe, be] });
}, [u]), Xe = E(() => {
if (!c.trim()) {
alert("Filter label is required");
return;
}
if (!e.isUniversalTime && !u.member) {
alert("Please select a field for the filter");
return;
}
const re = {
id: e.id,
label: c,
filter: u,
...e.isUniversalTime && { isUniversalTime: !0 }
};
a(re);
}, [e.id, e.isUniversalTime, c, u, a]), Qe = Q.find((re) => re.operator === u.operator)?.label || u.operator, J = Ht.find((re) => re.value === T)?.label || "Select range", fe = _ ? qd : O ? Bd : Vs, ve = _ ? "bg-dc-time-dimension" : O ? "bg-dc-measure" : "bg-dc-dimension", ke = _ ? "text-dc-time-dimension-text" : O ? "text-dc-measure-text" : "text-dc-dimension-text";
if (!s) return null;
const Fe = () => ce?.requiresValues ? Se ? /* @__PURE__ */ d("div", { className: "space-y-2", children: [
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
onClick: () => {
x(!1), w(!1), C(!y);
},
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__ */ r("span", { className: "truncate", children: J }),
/* @__PURE__ */ r(ir, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-2 transition-transform ${y ? "rotate-180" : ""}` })
]
}
),
y && /* @__PURE__ */ r("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: Ht.map((re) => /* @__PURE__ */ r(
"button",
{
onClick: () => We(re.value),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover ${re.value === T ? "bg-dc-primary/10 text-dc-primary" : "text-dc-text"}`,
children: re.label
},
re.value
)) })
] }),
Ot(T) && /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "number",
min: "1",
max: "1000",
value: v,
onChange: (re) => Je(Math.max(1, parseInt(re.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__ */ r("span", { className: "text-sm text-dc-text-muted", children: T.replace("last_n_", "") })
] }),
T === "custom" && /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "date",
value: Array.isArray(u.dateRange) ? u.dateRange[0] : "",
onChange: Ke,
className: "flex-1 text-sm border border-dc-border rounded px-2 py-2 bg-dc-surface text-dc-text"
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ r(
"input",
{
type: "date",
value: Array.isArray(u.dateRange) ? u.dateRange[1] : "",
onChange: Oe,
className: "flex-1 text-sm border border-dc-border rounded px-2 py-2 bg-dc-surface text-dc-text"
}
)
] })
] }) : u.operator === "between" || u.operator === "notBetween" ? /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "number",
value: u.values?.[0] ?? "",
onChange: He,
placeholder: "Min",
className: "flex-1 text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
),
/* @__PURE__ */ r("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ r(
"input",
{
type: "number",
value: u.values?.[1] ?? "",
onChange: Ne,
placeholder: "Max",
className: "flex-1 text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
)
] }) : ce?.valueType === "date" ? /* @__PURE__ */ r(
"input",
{
type: "date",
value: u.values?.[0] || "",
onChange: _e,
className: "w-full text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
) : ce?.valueType === "number" ? /* @__PURE__ */ r(
"input",
{
type: "number",
value: u.values?.[0] ?? "",
onChange: Pe,
placeholder: "Enter number",
className: "w-full text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
) : L ? /* @__PURE__ */ d("div", { className: "space-y-2", children: [
u.values && u.values.length > 0 && /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-1.5", children: u.values.map((re, be) => /* @__PURE__ */ d(
"span",
{
className: "inline-flex items-center gap-1 bg-dc-primary/10 text-dc-primary text-sm px-2 py-1 rounded",
children: [
/* @__PURE__ */ r("span", { className: "max-w-[150px] truncate", children: String(re) }),
/* @__PURE__ */ r(
"button",
{
onClick: () => Y(re),
className: "hover:text-dc-danger",
children: /* @__PURE__ */ r(Ks, { className: "w-3.5 h-3.5" })
}
)
]
},
be
)) }),
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
onClick: () => {
x(!1), C(!1), w(!A);
},
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__ */ r("span", { className: "text-dc-text-muted truncate", children: z ? "Loading..." : "Select value..." }),
/* @__PURE__ */ r(ir, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-2 transition-transform ${A ? "rotate-180" : ""}` })
]
}
),
A && /* @__PURE__ */ d("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__ */ r("div", { className: "p-2 border-b border-dc-border", children: /* @__PURE__ */ r(
"input",
{
type: "text",
value: S,
onChange: (re) => $(re.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__ */ r("div", { className: "max-h-40 overflow-y-auto", children: z ? /* @__PURE__ */ r("div", { className: "px-3 py-2 text-sm text-dc-text-muted", children: "Loading..." }) : H ? /* @__PURE__ */ d("div", { className: "px-3 py-2 text-sm text-dc-error", children: [
"Error: ",
H
] }) : pe.length === 0 ? /* @__PURE__ */ r("div", { className: "px-3 py-2 text-sm text-dc-text-muted", children: "No values found" }) : pe.map((re, be) => {
const Ee = u.values?.includes(re);
return /* @__PURE__ */ d(
"button",
{
onClick: () => we(re),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover ${Ee ? "bg-dc-primary/10 text-dc-primary" : "text-dc-text"}`,
children: [
String(re),
Ee && /* @__PURE__ */ r("span", { className: "float-right", children: "✓" })
]
},
`${re}-${be}`
);
}) })
] })
] })
] }) : /* @__PURE__ */ r(
"input",
{
type: "text",
value: u.values?.[0] ?? "",
onChange: Pe,
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__ */ r("div", { className: "text-sm text-dc-text-muted italic py-2", children: "No value required" });
return /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(
"div",
{
className: "fixed inset-0 z-50 flex items-center justify-center p-4",
style: { backgroundColor: "var(--dc-overlay)" },
onClick: o,
children: /* @__PURE__ */ d(
"div",
{
ref: D,
className: "bg-dc-surface rounded-lg border border-dc-border max-w-md w-full max-h-[90vh] overflow-auto",
style: { boxShadow: "var(--dc-shadow-xl)" },
onClick: (re) => re.stopPropagation(),
children: [
/* @__PURE__ */ d("div", { className: "flex items-center justify-between p-4 border-b border-dc-border", children: [
/* @__PURE__ */ r("h2", { className: "text-lg font-semibold text-dc-text", children: "Edit Filter" }),
/* @__PURE__ */ r(
"button",
{
onClick: o,
className: "p-1 text-dc-text-muted hover:text-dc-text transition-colors",
children: /* @__PURE__ */ r(Ks, { className: "w-5 h-5" })
}
)
] }),
/* @__PURE__ */ d("div", { className: "p-4 space-y-4", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("label", { className: "block text-sm font-medium text-dc-text-secondary mb-2", children: "Filter Label" }),
/* @__PURE__ */ r(
"input",
{
type: "text",
value: c,
onChange: (re) => l(re.target.value),
placeholder: "Enter filter label",
className: "w-full text-sm border border-dc-border rounded px-3 py-2 bg-dc-surface text-dc-text"
}
)
] }),
e.isUniversalTime && /* @__PURE__ */ d("div", { className: "p-3 rounded-md bg-dc-info-bg border border-dc-info-border", children: [
/* @__PURE__ */ r("div", { className: "text-sm font-medium text-dc-info mb-1", children: "Universal Time Filter" }),
/* @__PURE__ */ r("div", { className: "text-xs text-dc-text-secondary", children: "This filter applies to all time dimensions in mapped portlets. Users can select the date range when viewing the dashboard." })
] }),
!e.isUniversalTime && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ d("div", { className: "flex items-center justify-between mb-2", children: [
/* @__PURE__ */ r("label", { className: "block text-sm font-medium text-dc-text-secondary", children: "Field" }),
/* @__PURE__ */ r(
"button",
{
onClick: () => m(!f),
className: "flex items-center gap-1 text-xs px-2 py-1 rounded hover:bg-dc-surface-hover text-dc-text-muted",
title: f ? "Show dashboard fields only" : "Show all fields",
children: f ? /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(Kd, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ r("span", { children: "Dashboard" })
] }) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(jd, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ r("span", { children: "All" })
] })
}
)
] }),
/* @__PURE__ */ d(
"button",
{
onClick: () => b(!0),
className: "w-full flex items-center gap-2 p-3 bg-dc-surface-secondary rounded hover:bg-dc-surface-tertiary transition-colors",
children: [
u.member ? /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("span", { className: `w-6 h-6 flex items-center justify-center rounded ${ve} ${ke}`, children: fe && /* @__PURE__ */ r(fe, { className: "w-4 h-4" }) }),
/* @__PURE__ */ r("span", { className: "flex-1 text-sm font-medium text-dc-text text-left", children: X })
] }) : /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("span", { className: "w-6 h-6 flex items-center justify-center rounded bg-dc-surface-tertiary text-dc-text-muted", children: /* @__PURE__ */ r(Vs, { className: "w-4 h-4" }) }),
/* @__PURE__ */ r("span", { className: "flex-1 text-sm text-dc-text-muted text-left", children: "Click to select a field" })
] }),
/* @__PURE__ */ r(Qd, { className: "w-4 h-4 text-dc-text-muted" })
]
}
)
] }),
(u.member || e.isUniversalTime) && !e.isUniversalTime && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("label", { className: "block text-sm font-medium text-dc-text-secondary mb-2", children: "Operator" }),
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
onClick: () => {
w(!1), C(!1), x(!N);
},
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__ */ r("span", { className: "truncate", children: Qe }),
/* @__PURE__ */ r(ir, { className: `w-4 h-4 text-dc-text-muted shrink-0 ml-2 transition-transform ${N ? "rotate-180" : ""}` })
]
}
),
N && /* @__PURE__ */ r("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: Q.map((re) => /* @__PURE__ */ r(
"button",
{
onClick: () => le(re.operator),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover ${re.operator === u.operator ? "bg-dc-primary/10 text-dc-primary" : "text-dc-text"}`,
children: re.label
},
re.operator
)) })
] })
] }),
u.member && !e.isUniversalTime && /* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("label", { className: "block text-sm font-medium text-dc-text-secondary mb-2", children: "Default Value" }),
Fe()
] })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center justify-between p-4 border-t border-dc-border", children: [
/* @__PURE__ */ r(
"button",
{
onClick: i,
className: "px-4 py-2 text-sm font-medium text-dc-danger hover:bg-dc-danger-bg rounded transition-colors",
children: "Delete Filter"
}
),
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"button",
{
onClick: o,
className: "px-4 py-2 text-sm font-medium text-dc-text-secondary hover:text-dc-text transition-colors",
children: "Cancel"
}
),
/* @__PURE__ */ r(
"button",
{
onClick: Xe,
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: "Done"
}
)
] })
] })
]
}
)
}
),
g && /* @__PURE__ */ r(
qr,
{
isOpen: g,
onClose: () => b(!1),
onSelect: me,
mode: "filter",
schema: F,
selectedFields: u.member ? [u.member] : []
}
)
] });
}
const Ud = ({
filter: e,
schema: t,
dashboardConfig: n,
isOpen: s,
onSave: a,
onClose: i,
onDelete: o,
convertToMetaResponse: c
}) => {
const l = V(() => c(t), [t, c]), u = V(() => go(n), [n]), h = V(() => {
if (!t) return null;
const m = t.cubes.map((b) => {
const N = b.name, x = b.measures.filter((w) => {
const y = w.name.includes(".") ? w.name : `${N}.${w.name}`;
return u.measures.has(y);
}), A = b.dimensions.filter((w) => {
const y = w.name.includes(".") ? w.name : `${N}.${w.name}`;
return u.dimensions.has(y) || u.timeDimensions.has(y);
});
return x.length > 0 || A.length > 0 ? {
...b,
measures: x,
dimensions: A
} : null;
}).filter((b) => b !== null), g = {
...t,
cubes: m
};
return c(g);
}, [t, u, c]), f = E(async (m) => {
try {
await a(m), i();
} catch (g) {
console.error("Failed to save filter:", g), alert("Failed to save filter. Please try again.");
}
}, [a, i]);
return s ? /* @__PURE__ */ r(
Vd,
{
filter: e,
fullSchema: l,
filteredSchema: h,
isOpen: s,
onSave: f,
onDelete: o,
onClose: i
}
) : null;
}, or = q("filter"), vn = q("add"), Hd = q("close"), zd = q("edit"), Gd = q("chevronDown"), Us = q("timeDimension"), Wd = ({
dashboardFilters: e,
onAddFilter: t,
onAddTimeFilter: n,
onEditFilter: s,
onRemoveFilter: a,
selectedFilterId: i,
onFilterSelect: o
}) => {
const [c, l] = bt.useState(!1), u = (h) => {
const { id: f, label: m, isUniversalTime: g } = h, b = i === f;
return /* @__PURE__ */ d(
"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: b ? "var(--dc-primary)" : "var(--dc-surface)",
borderColor: b ? "var(--dc-primary)" : "var(--dc-border)",
borderWidth: b ? "2px" : "1px",
color: b ? "white" : "var(--dc-text)",
boxShadow: b ? "0 0 0 3px rgba(var(--dc-primary-rgb), 0.1)" : "none"
},
onClick: () => {
o && o(f);
},
children: [
/* @__PURE__ */ r(
g ? Us : or,
{
className: "w-3.5 h-3.5 shrink-0",
style: { color: b ? "white" : "var(--dc-primary)" }
}
),
/* @__PURE__ */ r("span", { className: "font-medium truncate", children: m }),
!b && /* @__PURE__ */ d("div", { className: "flex items-center gap-0.5 ml-1", onClick: (x) => x.stopPropagation(), children: [
/* @__PURE__ */ r(
"button",
{
onClick: () => s(f),
className: "p-0.5 hover:bg-dc-hover rounded transition-colors",
title: "Edit filter",
children: /* @__PURE__ */ r(zd, { className: "w-3 h-3" })
}
),
/* @__PURE__ */ r(
"button",
{
onClick: () => a(f),
className: "p-0.5 hover:bg-dc-danger-bg hover:text-dc-danger rounded transition-colors",
title: "Remove filter",
children: /* @__PURE__ */ r(Hd, { className: "w-3 h-3" })
}
)
] })
]
},
f
);
};
return /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ d("div", { className: "md:hidden", children: [
/* @__PURE__ */ d(
"div",
{
className: "px-4 py-2 flex items-center justify-between cursor-pointer",
onClick: () => l(!c),
children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(or, { className: "w-4 h-4 shrink-0", style: { color: "var(--dc-primary)" } }),
/* @__PURE__ */ r("h3", { className: "text-sm font-semibold", style: { color: "var(--dc-text)" }, children: "Filters" }),
e.length > 0 && /* @__PURE__ */ r(
"span",
{
className: "px-1.5 py-0.5 rounded-full text-xs font-medium",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: e.length
}
),
/* @__PURE__ */ r(
Gd,
{
className: `w-4 h-4 transition-transform ${c ? "" : "rotate-180"}`,
style: { color: "var(--dc-text-secondary)" }
}
)
] }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-1", children: [
!e.some((h) => h.isUniversalTime) && /* @__PURE__ */ d(
"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__ */ r(vn, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ r(Us, { className: "w-3.5 h-3.5" })
]
}
),
/* @__PURE__ */ r(
"button",
{
onClick: (h) => {
h.stopPropagation(), t();
},
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__ */ r(vn, { className: "w-3.5 h-3.5" })
}
)
] })
]
}
),
e.length > 0 && !c && /* @__PURE__ */ r("div", { className: "px-4 pb-2 flex flex-col gap-2", children: e.map(u) }),
e.length === 0 && !c && /* @__PURE__ */ r("div", { className: "px-4 pb-2", children: /* @__PURE__ */ r(
"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__ */ d("div", { className: "hidden md:flex md:items-center md:gap-3 px-4 py-2", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 shrink-0", children: [
/* @__PURE__ */ r(or, { className: "w-4 h-4 shrink-0", style: { color: "var(--dc-primary)" } }),
/* @__PURE__ */ r("h3", { className: "text-sm font-semibold whitespace-nowrap", style: { color: "var(--dc-text)" }, children: "Filters" }),
e.length > 0 && /* @__PURE__ */ r(
"span",
{
className: "px-1.5 py-0.5 rounded-full text-xs font-medium",
style: {
backgroundColor: "var(--dc-primary)",
color: "white"
},
children: e.length
}
)
] }),
e.length > 0 ? /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-2 flex-1 min-w-0", children: e.map(u) }) : /* @__PURE__ */ r("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ r(
"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__ */ d("div", { className: "flex items-center gap-1 shrink-0", children: [
!e.some((h) => h.isUniversalTime) && /* @__PURE__ */ d(
"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__ */ r(vn, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ r("span", { children: "Date Range" })
]
}
),
/* @__PURE__ */ d(
"button",
{
onClick: t,
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__ */ r(vn, { className: "w-3.5 h-3.5" }),
/* @__PURE__ */ r("span", { children: "Filter" })
]
}
)
] })
] })
] });
}, Sr = [
{ 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" }
], Ur = [
{ 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 Hr(e) {
const t = /* @__PURE__ */ new Date();
t.setHours(0, 0, 0, 0);
const n = new Date(t);
switch (n.setHours(23, 59, 59, 999), e.toLowerCase()) {
case "today":
return { start: t, end: n };
case "yesterday": {
const s = new Date(t);
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(t), a = s.getDay(), i = a === 0 ? 6 : a - 1;
return s.setDate(s.getDate() - i), { start: s, end: n };
}
case "this month":
return { start: new Date(t.getFullYear(), t.getMonth(), 1), end: n };
case "this quarter": {
const s = Math.floor(t.getMonth() / 3);
return { start: new Date(t.getFullYear(), s * 3, 1), end: n };
}
case "this year":
return { start: new Date(t.getFullYear(), 0, 1), end: n };
default: {
const s = e.match(/^last\s+(\d+)\s+(day|days|week|weeks|month|months|quarter|quarters|year|years)$/i);
if (s) {
const i = parseInt(s[1], 10), o = s[2].toLowerCase(), c = new Date(t);
return o === "day" || o === "days" ? c.setDate(c.getDate() - i + 1) : o === "week" || o === "weeks" ? c.setDate(c.getDate() - i * 7 + 1) : o === "month" || o === "months" ? (c.setMonth(c.getMonth() - i), c.setDate(c.getDate() + 1)) : o === "quarter" || o === "quarters" ? (c.setMonth(c.getMonth() - i * 3), c.setDate(c.getDate() + 1)) : (o === "year" || o === "years") && (c.setFullYear(c.getFullYear() - i), c.setDate(c.getDate() + 1)), { start: c, end: n };
}
const a = e.match(/^last\s+(week|month|quarter|year)$/i);
if (a) {
const i = a[1].toLowerCase();
if (i === "week") {
const o = new Date(t), c = o.getDay(), l = c === 0 ? 6 : c - 1;
o.setDate(o.getDate() - l - 1), o.setHours(23, 59, 59, 999);
const u = new Date(o);
return u.setDate(u.getDate() - 6), u.setHours(0, 0, 0, 0), { start: u, end: o };
} else if (i === "month") {
const o = new Date(t.getFullYear(), t.getMonth() - 1, 1), c = new Date(t.getFullYear(), t.getMonth(), 0);
return c.setHours(23, 59, 59, 999), { start: o, end: c };
} else if (i === "quarter") {
const o = Math.floor(t.getMonth() / 3), c = o === 0 ? 3 : o - 1, l = o === 0 ? t.getFullYear() - 1 : t.getFullYear(), u = new Date(l, c * 3, 1), h = new Date(l, c * 3 + 3, 0);
return h.setHours(23, 59, 59, 999), { start: u, end: h };
} else if (i === "year") {
const o = new Date(t.getFullYear() - 1, 0, 1), c = new Date(t.getFullYear() - 1, 11, 31);
return c.setHours(23, 59, 59, 999), { start: o, end: c };
}
}
return null;
}
}
}
function $n(e, t) {
const n = {
month: "short",
day: "numeric",
year: "numeric"
}, s = e.toLocaleDateString("en-US", n), a = t.toLocaleDateString("en-US", n);
if (s === a)
return s;
if (e.getFullYear() === t.getFullYear()) {
const i = { month: "short", day: "numeric" };
return `${e.toLocaleDateString("en-US", i)} - ${a}`;
}
return `${s} - ${a}`;
}
function Hs(e) {
if (!e) return null;
if (Array.isArray(e))
return "custom";
const t = e.toLowerCase().trim();
for (const s of Sr)
if (s.value.toLowerCase() === t)
return s.id;
for (const s of Ur)
if (s.value.toLowerCase() === t)
return s.id;
return t.match(/^last\s+(\d+)\s+(day|days|week|weeks|month|months|quarter|quarters|year|years)$/i), "custom";
}
function Yd(e, t) {
if (!e || e.length === 0)
return t === "set" ? "is set" : t === "notSet" ? "is not set" : t === "isEmpty" ? "is empty" : t === "isNotEmpty" ? "is not empty" : "";
const n = e.map((s) => s === !0 ? "true" : s === !1 ? "false" : s == null ? "null" : String(s));
switch (t) {
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(", ");
}
}
const zs = ({
activePreset: e,
onPresetSelect: t,
disabled: n = !1
}) => {
const s = V(() => {
const a = {};
for (const i of Sr) {
const o = Hr(i.value);
o && (a[i.id] = $n(o.start, o.end));
}
return a;
}, []);
return /* @__PURE__ */ r("div", { className: "flex items-center gap-1", children: Sr.map((a) => {
const i = e === a.id, o = s[a.id];
return /* @__PURE__ */ r(
"button",
{
type: "button",
onClick: () => t(a.value),
disabled: n,
title: o,
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
${i ? "shadow-sm" : "border"}
`,
style: {
backgroundColor: i ? "var(--dc-primary)" : "var(--dc-surface)",
color: i ? "white" : "var(--dc-text)",
borderColor: i ? "transparent" : "var(--dc-border)",
...n ? {} : {
cursor: "pointer"
}
},
onMouseEnter: (c) => {
!i && !n && (c.currentTarget.style.backgroundColor = "var(--dc-surface-hover)");
},
onMouseLeave: (c) => {
!i && !n && (c.currentTarget.style.backgroundColor = "var(--dc-surface)");
},
children: a.label
},
a.id
);
}) });
}, Jd = [
{ value: "days", label: "Days" },
{ value: "weeks", label: "Weeks" },
{ value: "months", label: "Months" },
{ value: "quarters", label: "Quarters" },
{ value: "years", label: "Years" }
], Gs = ({
isOpen: e,
onClose: t,
onDateRangeChange: n,
currentDateRange: s
}) => {
const a = ge(null), [i, o] = ee("fixed"), [c, l] = ee(""), [u, h] = ee(""), [f, m] = ee(""), [g, b] = ee(7), [N, x] = ee("days");
he(() => {
if (s)
if (Array.isArray(s))
o("fixed"), l(s[0] || ""), h(s[1] || s[0] || "");
else {
const p = s.match(/^last\s+(\d+)\s+(day|days|week|weeks|month|months|quarter|quarters|year|years)$/i);
if (p) {
o("last"), b(parseInt(p[1], 10));
const v = p[2].toLowerCase();
x(v === "day" ? "days" : v === "week" ? "weeks" : v === "month" ? "months" : v === "quarter" ? "quarters" : v === "year" ? "years" : v.endsWith("s") ? v : `${v}s`);
}
}
}, [s]), he(() => {
if (!e) return;
const p = (S) => {
a.current && !a.current.contains(S.target) && t();
}, v = (S) => {
S.key === "Escape" && t();
}, k = setTimeout(() => {
document.addEventListener("mousedown", p), document.addEventListener("keydown", v);
}, 0);
return () => {
clearTimeout(k), document.removeEventListener("mousedown", p), document.removeEventListener("keydown", v);
};
}, [e, t]);
const A = E(() => {
c && u ? n([c, u]) : c && n([c, c]);
}, [c, u, n]), w = E(() => {
if (f) {
const p = Oi(/* @__PURE__ */ new Date());
n([f, p]);
}
}, [f, n]), y = E(() => {
if (g > 0) {
const p = `last_n_${N}`, v = Dt(p, g);
n(v);
}
}, [g, N, n]);
if (!e) return null;
const C = (p) => ({
backgroundColor: p ? "var(--dc-primary)" : "transparent",
color: p ? "white" : "var(--dc-text)",
borderBottom: p ? "none" : "2px solid var(--dc-border)"
}), T = (p) => {
p.stopPropagation();
};
return /* @__PURE__ */ d(
"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: T,
onMouseDown: T,
children: [
/* @__PURE__ */ r(
"div",
{
className: "flex border-b",
style: { borderColor: "var(--dc-border)" },
children: ["fixed", "since", "last"].map((p) => /* @__PURE__ */ r(
"button",
{
type: "button",
onClick: () => o(p),
className: "flex-1 px-4 py-2 text-sm font-medium capitalize transition-colors",
style: C(i === p),
children: p
},
p
))
}
),
/* @__PURE__ */ d("div", { className: "p-4", children: [
i === "fixed" && /* @__PURE__ */ d("div", { className: "space-y-3", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "Start Date"
}
),
/* @__PURE__ */ r(
"input",
{
type: "date",
value: c,
onChange: (p) => l(p.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__ */ d("div", { children: [
/* @__PURE__ */ r(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "End Date"
}
),
/* @__PURE__ */ r(
"input",
{
type: "date",
value: u,
onChange: (p) => h(p.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__ */ r(
"button",
{
type: "button",
onClick: A,
disabled: !c,
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"
}
)
] }),
i === "since" && /* @__PURE__ */ d("div", { className: "space-y-3", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "Since Date"
}
),
/* @__PURE__ */ r(
"input",
{
type: "date",
value: f,
onChange: (p) => m(p.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__ */ r(
"p",
{
className: "text-xs",
style: { color: "var(--dc-text-secondary)" },
children: "From selected date to today"
}
),
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: w,
disabled: !f,
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"
}
)
] }),
i === "last" && /* @__PURE__ */ d("div", { className: "space-y-3", children: [
/* @__PURE__ */ d("div", { className: "flex gap-2", children: [
/* @__PURE__ */ d("div", { className: "flex-1", children: [
/* @__PURE__ */ r(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "Number"
}
),
/* @__PURE__ */ r(
"input",
{
type: "number",
min: "1",
max: "999",
value: g,
onChange: (p) => b(Math.max(1, parseInt(p.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__ */ d("div", { className: "flex-1", children: [
/* @__PURE__ */ r(
"label",
{
className: "block text-xs font-medium mb-1",
style: { color: "var(--dc-text-secondary)" },
children: "Unit"
}
),
/* @__PURE__ */ r(
"select",
{
value: N,
onChange: (p) => x(p.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: Jd.map((p) => /* @__PURE__ */ r("option", { value: p.value, children: p.label }, p.value))
}
)
] })
] }),
/* @__PURE__ */ d(
"p",
{
className: "text-xs",
style: { color: "var(--dc-text-secondary)" },
children: [
"Last ",
g,
" ",
g === 1 ? N.slice(0, -1) : N
]
}
),
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: y,
disabled: g < 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__ */ r(
"div",
{
className: "px-4 pb-4",
children: /* @__PURE__ */ r(
"button",
{
type: "button",
onClick: t,
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"
}
)
}
)
]
}
);
}, Xd = q("check"), Ws = ({
isOpen: e,
onClose: t,
onSelect: n,
currentXTD: s
}) => {
const a = ge(null);
if (he(() => {
if (!e) return;
const o = (u) => {
a.current && !a.current.contains(u.target) && t();
}, c = (u) => {
u.key === "Escape" && t();
}, l = setTimeout(() => {
document.addEventListener("mousedown", o), document.addEventListener("keydown", c);
}, 0);
return () => {
clearTimeout(l), document.removeEventListener("mousedown", o), document.removeEventListener("keydown", c);
};
}, [e, t]), !e) return null;
const i = (o) => {
o.stopPropagation();
};
return /* @__PURE__ */ r(
"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: i,
onMouseDown: i,
children: Ur.map((o) => {
const c = s === o.id, l = Hr(o.value), u = l ? $n(l.start, l.end) : "";
return /* @__PURE__ */ d(
"button",
{
type: "button",
onClick: () => n(o.value),
className: "w-full px-3 py-2 text-left text-sm transition-colors flex items-center justify-between gap-2",
style: {
backgroundColor: c ? "var(--dc-primary-bg)" : "transparent",
color: "var(--dc-text)"
},
onMouseEnter: (h) => {
c || (h.currentTarget.style.backgroundColor = "var(--dc-surface-hover)");
},
onMouseLeave: (h) => {
c || (h.currentTarget.style.backgroundColor = "transparent");
},
children: [
/* @__PURE__ */ d("div", { className: "flex flex-col", children: [
/* @__PURE__ */ r("span", { className: "font-medium", children: o.label }),
u && /* @__PURE__ */ r(
"span",
{
className: "text-xs mt-0.5",
style: { color: "var(--dc-text-secondary)" },
children: u
}
)
] }),
c && /* @__PURE__ */ r(
Xd,
{
className: "w-4 h-4 shrink-0",
style: { color: "var(--dc-primary)" }
}
)
]
},
o.id
);
})
}
);
}, Zd = q("chevronDown"), lr = q("close"), eu = ({
fieldName: e,
operator: t,
values: n,
onValuesChange: s,
schema: a
}) => {
const i = qn[t], [o, c] = ee(!1), [l, u] = ee(""), [h, f] = ee(!1), m = ge(null), g = ge(""), b = Ar(l, 300), N = V(() => a ? a.cubes.some(
(_) => _.dimensions.some((O) => O.name === e)
) : !1, [a, e]), x = V(() => a ? a.cubes.some(
(_) => _.dimensions.some((O) => O.name === e && O.type === "time")
) : !1, [a, e]), A = V(
() => ["equals", "notEquals", "in", "notIn"].includes(t) && N && !x,
[t, N, x]
), w = A, {
values: y,
loading: C,
error: T,
searchValues: p
} = Mr(e, A);
he(() => {
const _ = (O) => {
m.current && !m.current.contains(O.target) && c(!1);
};
return document.addEventListener("mousedown", _), () => document.removeEventListener("mousedown", _);
}, []), he(() => {
o && A && p && (p("", !0), f(!0), g.current = "");
}, [o, A, p]), he(() => {
h && A && p && b !== g.current && (g.current = b, p(b));
}, [b, h, A, p]);
const v = E(() => {
const _ = !o;
c(_), _ || (u(""), g.current = "");
}, [o]), k = E((_) => {
const O = _.target.value;
u(O);
}, []), S = E((_) => {
i.supportsMultipleValues ? n.includes(_) || s([...n, _]) : (s([_]), c(!1)), u("");
}, [i.supportsMultipleValues, n, s]), $ = E((_) => {
s(n.filter((O) => O !== _));
}, [n, s]), D = E((_) => {
const O = _.target.value;
if (i.valueType === "number") {
const ie = parseFloat(O);
isNaN(ie) ? (O === "" || O === "-") && s([]) : s([ie]);
} else
s(O ? [O] : []);
}, [i.valueType, s]), F = E((_) => {
const O = _.target.value;
if (t === "inDateRange") {
const ie = n.length >= 2 ? n : ["", ""];
s([O, ie[1]]);
} else
s(O ? [O] : []);
}, [t, n, s]), K = E((_) => {
const O = _.target.value, ie = n.length >= 2 ? n : ["", ""];
s([ie[0], O]);
}, [n, s]), P = E((_) => {
const O = parseFloat(_.target.value), ie = n.length >= 2 ? n : ["", ""], X = [isNaN(O) ? _.target.value === "" ? "" : ie[0] : O, ie[1]];
s(X.filter((ce) => ce !== ""));
}, [n, s]), te = E((_) => {
const O = parseFloat(_.target.value), ie = n.length >= 2 ? n : ["", ""], X = [ie[0], isNaN(O) ? _.target.value === "" ? "" : ie[1] : O];
s(X.filter((ce) => ce !== ""));
}, [n, s]);
return i.requiresValues ? t === "inDateRange" ? /* @__PURE__ */ d("div", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "date",
value: n[0] || "",
onChange: F,
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__ */ r("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ r(
"input",
{
type: "date",
value: n[1] || "",
onChange: K,
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"
}
)
] }) : t === "between" || t === "notBetween" ? /* @__PURE__ */ d("div", { className: "flex items-center space-x-2", children: [
/* @__PURE__ */ r(
"input",
{
type: "number",
value: n[0] !== void 0 && n[0] !== null ? n[0] : "",
onChange: P,
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__ */ r("span", { className: "text-sm text-dc-text-muted", children: "to" }),
/* @__PURE__ */ r(
"input",
{
type: "number",
value: n[1] !== void 0 && n[1] !== null ? n[1] : "",
onChange: te,
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"
}
)
] }) : i.valueType === "date" ? /* @__PURE__ */ r(
"input",
{
type: "date",
value: n[0] || "",
onChange: F,
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"
}
) : i.valueType === "number" ? /* @__PURE__ */ r(
"input",
{
type: "number",
value: n[0] !== void 0 && n[0] !== null ? n[0] : "",
onChange: D,
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"
}
) : x && ["equals", "notEquals", "in", "notIn"].includes(t) ? i.supportsMultipleValues ? /* @__PURE__ */ d("div", { className: "space-y-2 min-w-0 max-w-full", children: [
n.length > 0 && /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-1 max-w-full", children: n.map((_, O) => /* @__PURE__ */ d(
"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__ */ r("span", { className: "mr-1", children: String(_) }),
/* @__PURE__ */ r(
"button",
{
onClick: () => $(_),
className: "text-dc-accent hover:text-dc-accent focus:outline-hidden",
children: /* @__PURE__ */ r(lr, { className: "w-3 h-3" })
}
)
]
},
O
)) }),
/* @__PURE__ */ r(
"input",
{
type: "date",
onChange: (_) => {
_.target.value && !n.includes(_.target.value) && (s([...n, _.target.value]), _.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__ */ r(
"input",
{
type: "date",
value: n[0] || "",
onChange: F,
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"
}
) : w ? /* @__PURE__ */ d("div", { className: "relative min-w-0 max-w-full", ref: m, children: [
i.supportsMultipleValues && n.length > 0 && /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-1 mb-2 max-w-full", children: n.map((_, O) => /* @__PURE__ */ d(
"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__ */ r("span", { className: "mr-1", children: String(_) }),
/* @__PURE__ */ r(
"button",
{
onClick: () => $(_),
className: "text-dc-accent hover:text-dc-accent focus:outline-hidden",
children: /* @__PURE__ */ r(lr, { className: "w-3 h-3" })
}
)
]
},
O
)) }),
!i.supportsMultipleValues && n.length > 0 && /* @__PURE__ */ r("div", { className: "mb-2", children: /* @__PURE__ */ d("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__ */ r("span", { className: "mr-1", children: String(n[0]) }),
/* @__PURE__ */ r(
"button",
{
onClick: () => s([]),
className: "text-dc-accent hover:text-dc-accent focus:outline-hidden",
children: /* @__PURE__ */ r(lr, { className: "w-3 h-3" })
}
)
] }) }),
/* @__PURE__ */ d(
"button",
{
onClick: v,
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__ */ r("span", { className: "text-dc-text-muted truncate", children: C && !h ? "Loading values..." : "Select value..." }),
/* @__PURE__ */ r(Zd, { className: "w-4 h-4 text-dc-text-muted" })
]
}
),
o && /* @__PURE__ */ d("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__ */ r("div", { className: "p-2 border-b border-dc-border", children: /* @__PURE__ */ r(
"input",
{
type: "text",
value: l,
onChange: k,
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__ */ r("div", { className: "max-h-48 overflow-y-auto", children: C ? /* @__PURE__ */ r("div", { className: "p-2 text-sm text-dc-text-muted", children: l ? "Searching..." : "Loading values..." }) : T ? /* @__PURE__ */ d("div", { className: "p-2 text-sm text-dc-error", children: [
"Error loading values: ",
T
] }) : y.length === 0 ? /* @__PURE__ */ r("div", { className: "p-2 text-sm text-dc-text-muted", children: l ? "No matching values" : "No values available" }) : y.map((_, O) => {
const ie = n.includes(_);
return /* @__PURE__ */ d(
"button",
{
onClick: () => S(_),
className: `w-full text-left px-3 py-2 text-sm hover:bg-dc-surface-hover focus:outline-hidden focus:bg-dc-surface-hover ${ie ? "bg-dc-accent-bg text-dc-accent" : "text-dc-text-secondary"}`,
children: [
String(_),
ie && /* @__PURE__ */ r("span", { className: "float-right text-dc-accent", children: "✓" })
]
},
`${_}-${O}`
);
}) })
] })
] }) : /* @__PURE__ */ r(
"input",
{
type: "text",
value: n[0] !== void 0 && n[0] !== null ? n[0] : "",
onChange: D,
placeholder: `Enter ${i.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__ */ r("div", { className: "text-sm text-dc-text-muted italic", children: "No value required" });
};
function tu(e) {
return e ? {
cubes: e.cubes.map((t) => ({
name: t.name,
title: t.title || t.name,
description: t.description || "",
measures: t.measures.map((n) => ({
name: n.name,
title: n.title || n.name,
type: n.type,
description: "",
shortTitle: n.shortTitle || n.title || n.name
})),
dimensions: t.dimensions.map((n) => ({
name: n.name,
title: n.title || n.name,
type: n.type,
description: "",
shortTitle: n.shortTitle || n.title || n.name
})),
segments: t.segments?.map((n) => ({
name: n.name,
title: n.title || n.name,
type: n.type,
description: "",
shortTitle: n.shortTitle || n.title || n.name
})) || []
}))
} : null;
}
const nu = ({
filter: e,
schema: t,
onValuesChange: n,
onClose: s,
anchorRef: a
}) => {
const i = ge(null);
he(() => {
const l = (f) => {
i.current && !i.current.contains(f.target) && a.current && !a.current.contains(f.target) && s();
}, u = (f) => {
f.key === "Escape" && s();
}, h = setTimeout(() => {
document.addEventListener("mousedown", l), document.addEventListener("keydown", u);
}, 0);
return () => {
clearTimeout(h), document.removeEventListener("mousedown", l), document.removeEventListener("keydown", u);
};
}, [s, a]);
const o = E((l) => {
n(l);
}, [n]), c = tu(t);
return /* @__PURE__ */ d(
"div",
{
ref: i,
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__ */ r(
"div",
{
className: "text-xs font-medium mb-2",
style: { color: "var(--dc-text-secondary)" },
children: "Edit value"
}
),
/* @__PURE__ */ r("div", { className: "min-w-[180px]", children: /* @__PURE__ */ r(
eu,
{
fieldName: e.member,
operator: e.operator,
values: e.values || [],
onValuesChange: o,
schema: c
}
) }),
/* @__PURE__ */ r("div", { className: "flex justify-end gap-2 mt-3 pt-2 border-t", style: { borderColor: "var(--dc-border)" }, children: /* @__PURE__ */ r(
"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"
}
) })
]
}
);
}, ru = q("close"), su = q("edit"), Ys = ({
filter: e,
schema: t,
isEditMode: n,
onChange: s,
onEdit: a,
onRemove: i
}) => {
const [o, c] = ee(!1), l = ge(null), u = e.filter, { label: h } = e, { operator: f, values: m } = u, g = Yd(m || [], f), b = E((x) => {
s({
...e,
filter: {
...u,
values: x
}
});
}, [e, u, s]), N = E(() => {
n ? a?.() : c(!0);
}, [n, a]);
return "member" in e.filter ? /* @__PURE__ */ d("div", { ref: l, className: "relative inline-flex", children: [
/* @__PURE__ */ d(
"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: N,
onMouseEnter: (x) => {
x.currentTarget.style.backgroundColor = "var(--dc-surface-hover)";
},
onMouseLeave: (x) => {
x.currentTarget.style.backgroundColor = "var(--dc-surface)";
},
title: `${h} ${g}`,
children: [
/* @__PURE__ */ r("span", { className: "font-medium truncate max-w-[100px]", children: h }),
g && /* @__PURE__ */ r(Ce, { children: /* @__PURE__ */ r("span", { style: { color: "var(--dc-text-secondary)" }, children: g }) }),
n && /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: (x) => {
x.stopPropagation(), a?.();
},
className: "p-0.5 rounded transition-colors",
style: { color: "var(--dc-text-secondary)" },
onMouseEnter: (x) => {
x.currentTarget.style.color = "var(--dc-text)";
},
onMouseLeave: (x) => {
x.currentTarget.style.color = "var(--dc-text-secondary)";
},
children: /* @__PURE__ */ r(su, { className: "w-3 h-3" })
}
),
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: (x) => {
x.stopPropagation(), i?.();
},
className: "p-0.5 rounded transition-colors",
style: { color: "var(--dc-text-secondary)" },
onMouseEnter: (x) => {
x.currentTarget.style.color = "var(--dc-error)";
},
onMouseLeave: (x) => {
x.currentTarget.style.color = "var(--dc-text-secondary)";
},
children: /* @__PURE__ */ r(ru, { className: "w-3 h-3" })
}
)
] })
]
}
),
o && !n && /* @__PURE__ */ r(
nu,
{
filter: u,
schema: t,
onValuesChange: b,
onClose: () => c(!1),
anchorRef: l
}
)
] }) : null;
}, Js = q("add"), Xs = q("timeDimension"), cr = q("chevronDown"), Zs = q("filter"), au = ({
dashboardFilters: e,
schema: t,
isEditMode: n,
onDashboardFiltersChange: s,
onAddFilter: a,
onEditFilter: i,
onRemoveFilter: o
}) => {
const [c, l] = ee(!1), [u, h] = ee(!1), f = ge(null), m = ge(null), g = V(() => e.find((S) => S.isUniversalTime), [e]), b = V(() => {
if (!g) return null;
const S = g.filter;
return S.dateRange ? S.dateRange : S.values && S.values.length > 0 ? S.values.length === 1 && typeof S.values[0] == "string" ? S.values[0] : S.values : null;
}, [g]), N = V(() => Hs(b), [b]), x = V(() => {
if (!b || Array.isArray(b)) return null;
const S = Hs(b);
return Ur.find(($) => $.id === S)?.id || null;
}, [b]), A = V(() => e.filter((S) => !S.isUniversalTime), [e]), w = E(() => `df_${Date.now()}_${Math.random().toString(36).substring(7)}`, []), y = E((S) => {
if (g) {
const $ = e.map((D) => D.id === g.id ? {
...D,
filter: {
...D.filter,
values: Array.isArray(S) ? S : [S],
dateRange: S
}
} : D);
s($);
} else {
const $ = {
id: w(),
label: "Date Range",
isUniversalTime: !0,
filter: {
member: "__universal_time__",
operator: "inDateRange",
values: Array.isArray(S) ? S : [S],
dateRange: S
}
};
s([...e, $]);
}
}, [e, g, s, w]), C = E((S) => {
y(S);
}, [y]), T = E((S) => {
y(S), h(!1);
}, [y]), p = E((S) => {
y(S), l(!1);
}, [y]), v = E((S, $) => {
const D = e.map(
(F) => F.id === S ? $ : F
);
s(D);
}, [e, s]), k = V(() => {
if (!b) return null;
if (Array.isArray(b)) {
const $ = new Date(b[0]), D = new Date(b[1] || b[0]);
return $n($, D);
}
const S = Hr(b);
return S ? $n(S.start, S.end) : b;
}, [b]);
return !n && e.length === 0 ? null : /* @__PURE__ */ d(
"div",
{
className: "border rounded-lg",
style: {
borderColor: "var(--dc-border)",
backgroundColor: "var(--dc-surface)"
},
children: [
/* @__PURE__ */ d("div", { className: "hidden md:flex items-center gap-2 px-3 py-2", children: [
/* @__PURE__ */ r(
Zs,
{
className: "w-4 h-4 shrink-0",
style: { color: "var(--dc-text-secondary)" }
}
),
/* @__PURE__ */ r(
zs,
{
activePreset: N !== "custom" && !x ? N : null,
onPresetSelect: C
}
),
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
ref: f,
type: "button",
onClick: () => {
l(!c), h(!1);
},
title: N === "custom" && k ? k : "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: N === "custom" ? "var(--dc-primary)" : "var(--dc-surface)",
color: N === "custom" ? "white" : "var(--dc-text)",
borderColor: N === "custom" ? "transparent" : "var(--dc-border)"
},
children: [
/* @__PURE__ */ r(Xs, { className: "w-3 h-3" }),
/* @__PURE__ */ r("span", { children: "Custom" }),
/* @__PURE__ */ r(cr, { className: "w-3 h-3" })
]
}
),
c && /* @__PURE__ */ r(
Gs,
{
isOpen: c,
onClose: () => l(!1),
onDateRangeChange: p,
currentDateRange: b,
anchorRef: f
}
)
] }),
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
ref: m,
type: "button",
onClick: () => {
h(!u), l(!1);
},
title: x && k ? k : "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: x ? "var(--dc-primary)" : "var(--dc-surface)",
color: x ? "white" : "var(--dc-text)",
borderColor: x ? "transparent" : "var(--dc-border)"
},
children: [
/* @__PURE__ */ r("span", { children: "XTD" }),
/* @__PURE__ */ r(cr, { className: "w-3 h-3" })
]
}
),
u && /* @__PURE__ */ r(
Ws,
{
isOpen: u,
onClose: () => h(!1),
onSelect: T,
currentXTD: x,
anchorRef: m
}
)
] }),
A.length > 0 && /* @__PURE__ */ r(
"div",
{
className: "h-5 w-px mx-1",
style: { backgroundColor: "var(--dc-border)" }
}
),
/* @__PURE__ */ r("div", { className: "flex items-center gap-1.5 flex-wrap", children: A.map((S) => /* @__PURE__ */ r(
Ys,
{
filter: S,
schema: t,
isEditMode: n,
onChange: ($) => v(S.id, $),
onEdit: () => i?.(S.id),
onRemove: () => o?.(S.id)
},
S.id
)) }),
n && a && /* @__PURE__ */ r(
"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: (S) => {
S.currentTarget.style.backgroundColor = "var(--dc-surface-hover)";
},
onMouseLeave: (S) => {
S.currentTarget.style.backgroundColor = "transparent";
},
children: /* @__PURE__ */ r(Js, { className: "w-3.5 h-3.5" })
}
)
] }),
/* @__PURE__ */ d("div", { className: "md:hidden", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 overflow-x-auto px-3 py-2 scrollbar-thin", children: [
/* @__PURE__ */ r(
Zs,
{
className: "w-4 h-4 shrink-0",
style: { color: "var(--dc-text-secondary)" }
}
),
/* @__PURE__ */ r(
zs,
{
activePreset: N !== "custom" && !x ? N : null,
onPresetSelect: C
}
)
] }),
/* @__PURE__ */ d(
"div",
{
className: "flex items-center justify-between px-3 py-2 border-t",
style: { borderColor: "var(--dc-border)" },
children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
ref: f,
type: "button",
onClick: () => {
l(!c), h(!1);
},
className: `
flex items-center gap-1 px-2.5 py-1 rounded text-xs font-medium border
transition-colors
`,
style: {
backgroundColor: N === "custom" ? "var(--dc-primary)" : "var(--dc-surface)",
color: N === "custom" ? "white" : "var(--dc-text)",
borderColor: N === "custom" ? "transparent" : "var(--dc-border)"
},
children: [
/* @__PURE__ */ r(Xs, { className: "w-3 h-3" }),
/* @__PURE__ */ r("span", { children: "Custom" })
]
}
),
c && /* @__PURE__ */ r(
Gs,
{
isOpen: c,
onClose: () => l(!1),
onDateRangeChange: p,
currentDateRange: b,
anchorRef: f
}
)
] }),
/* @__PURE__ */ d("div", { className: "relative", children: [
/* @__PURE__ */ d(
"button",
{
ref: m,
type: "button",
onClick: () => {
h(!u), l(!1);
},
className: `
flex items-center gap-1 px-2.5 py-1 rounded text-xs font-medium border
transition-colors
`,
style: {
backgroundColor: x ? "var(--dc-primary)" : "var(--dc-surface)",
color: x ? "white" : "var(--dc-text)",
borderColor: x ? "transparent" : "var(--dc-border)"
},
children: [
/* @__PURE__ */ r("span", { children: "XTD" }),
/* @__PURE__ */ r(cr, { className: "w-3 h-3" })
]
}
),
u && /* @__PURE__ */ r(
Ws,
{
isOpen: u,
onClose: () => h(!1),
onSelect: T,
currentXTD: x,
anchorRef: m
}
)
] })
] }),
n && a && /* @__PURE__ */ r(
"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__ */ r(Js, { className: "w-3.5 h-3.5" })
}
)
]
}
),
A.length > 0 && /* @__PURE__ */ r(
"div",
{
className: "px-3 py-2 border-t",
style: { borderColor: "var(--dc-border)" },
children: /* @__PURE__ */ r("div", { className: "flex items-center gap-1.5 flex-wrap", children: A.map((S) => /* @__PURE__ */ r(
Ys,
{
filter: S,
schema: t,
isEditMode: n,
onChange: ($) => v(S.id, $),
onEdit: () => i?.(S.id),
onRemove: () => o?.(S.id)
},
S.id
)) })
}
)
] })
]
}
);
}, iu = ({
dashboardFilters: e,
editable: t,
schema: n,
dashboardConfig: s,
onDashboardFiltersChange: a,
onSaveFilters: i,
selectedFilterId: o,
onFilterSelect: c,
isEditMode: l = !1
}) => {
const [u, h] = ee(null), [f, m] = ee(!1), g = E((T) => T ? {
cubes: T.cubes.map((p) => ({
name: p.name,
title: p.title || p.name,
description: p.description || "",
measures: p.measures.map((v) => ({
name: v.name,
title: v.title,
type: v.type,
description: "",
shortTitle: v.shortTitle
})),
dimensions: p.dimensions.map((v) => ({
name: v.name,
title: v.title,
type: v.type,
description: "",
shortTitle: v.shortTitle
})),
segments: p.segments?.map((v) => ({
name: v.name,
title: v.title,
type: v.type,
description: "",
shortTitle: v.shortTitle
})) || []
}))
} : null, []), b = E(() => `df_${Date.now()}_${Math.random().toString(36).substring(7)}`, []), N = E(() => {
const T = {
id: b(),
label: `Filter ${e.length + 1}`,
filter: {
member: "",
operator: "equals",
values: []
}
};
h(T), m(!0);
}, [e.length, b]), x = E(() => {
const T = {
id: b(),
label: "Date Range Filter",
isUniversalTime: !0,
filter: {
member: "__universal_time__",
// Placeholder, not used in merge logic
operator: "inDateRange",
values: ["last 30 days"]
}
}, p = [...e, T];
a(p);
}, [b, e, a]), A = E((T) => {
const p = e.find((v) => v.id === T);
p && (h(p), m(!0));
}, [e]), w = E((T) => {
const p = e.filter((v) => v.id !== T);
a(p), u?.id === T && (h(null), m(!1));
}, [e, u, a]), y = E(async (T) => {
const p = e.findIndex((k) => k.id === T.id);
let v;
if (p >= 0 ? v = e.map(
(k) => k.id === T.id ? T : k
) : v = [...e, T], a(v), i)
try {
await i(v);
} catch (k) {
throw console.error("Failed to save filters:", k), k;
}
}, [e, a, i]), C = E(() => {
h(null), m(!1);
}, []);
return !t || !l && e.length === 0 ? null : /* @__PURE__ */ d("div", { className: "mb-4", children: [
l ? /* @__PURE__ */ r(
"div",
{
className: "border rounded-lg",
style: {
borderColor: "var(--dc-border)",
backgroundColor: "var(--dc-surface)",
boxShadow: "var(--dc-shadow-sm)"
},
children: /* @__PURE__ */ r(
Wd,
{
dashboardFilters: e,
onAddFilter: N,
onAddTimeFilter: x,
onEditFilter: A,
onRemoveFilter: w,
selectedFilterId: o,
onFilterSelect: c
}
)
}
) : (
/* View Mode - Compact Mixpanel-style filter bar */
/* @__PURE__ */ r(
au,
{
dashboardFilters: e,
schema: n,
isEditMode: !1,
onDashboardFiltersChange: a,
onAddFilter: N,
onEditFilter: A,
onRemoveFilter: w
}
)
),
t && f && u && /* @__PURE__ */ r(
Ud,
{
filter: u,
schema: n,
dashboardConfig: s,
isOpen: f,
onSave: y,
onClose: C,
onDelete: () => w(u.id),
convertToMetaResponse: g
}
)
] });
};
function ou({
scaleFactor: e,
designWidth: t,
children: n
}) {
const [s, a] = ee(0), i = ge(null);
he(() => {
if (!i.current) return;
const c = new ResizeObserver((l) => {
a(l[0]?.contentRect.height ?? 0);
});
return c.observe(i.current), a(i.current.offsetHeight || 0), () => c.disconnect();
}, []);
const o = s * e;
return /* @__PURE__ */ r(
"div",
{
className: "scaled-grid-container",
style: {
height: o > 0 ? o : "auto",
overflow: "hidden",
width: "100%"
},
children: /* @__PURE__ */ r(
"div",
{
ref: i,
className: "scaled-grid-inner",
style: {
transform: `scale(${e})`,
transformOrigin: "top left",
width: t
},
children: n
}
)
}
);
}
const lu = q("refresh");
function cu(e) {
if (!e) return null;
let t = e.parentElement;
for (; t; ) {
const n = window.getComputedStyle(t), s = n.overflowY, a = n.overflowX, i = s === "auto" || s === "scroll" || a === "auto" || a === "scroll", o = t.scrollHeight > t.clientHeight || t.scrollWidth > t.clientWidth;
if (i && o)
return t;
if (t === document.body) break;
t = t.parentElement;
}
return null;
}
function du({
config: e,
colorPalette: t,
dashboardFilters: n,
onPortletRefresh: s
}) {
const a = ge({}), [i, o] = ee(null), c = ge(null), l = E((f) => {
c.current = f, f && o(cu(f));
}, []), u = V(() => [...e.portlets].sort((f, m) => f.y !== m.y ? f.y - m.y : f.x - m.x), [e.portlets]), h = (f) => {
a.current[f]?.refresh(), s?.(f);
};
return /* @__PURE__ */ r(ca, { value: i, children: /* @__PURE__ */ r("div", { ref: l, className: "mobile-stacked-layout space-y-4 px-2", children: u.map((f) => {
const m = ln(f), { analysisConfig: g } = m, b = g.charts[g.analysisType], N = JSON.stringify(g.query), x = b?.chartType || "line", A = b?.chartConfig, w = b?.displayConfig, y = Math.max(300, f.h * 80), C = w?.hideHeader ? 0 : 40, T = y - C - 24;
return /* @__PURE__ */ d(
"div",
{
"data-portlet-id": f.id,
className: "bg-dc-surface border border-dc-border rounded-lg flex flex-col",
style: {
height: y,
boxShadow: "var(--dc-shadow-sm)"
},
children: [
!w?.hideHeader && /* @__PURE__ */ d("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__ */ r("h3", { className: "font-semibold text-sm text-dc-text truncate flex-1", children: f.title }),
/* @__PURE__ */ r("div", { className: "flex items-center gap-1 shrink-0 ml-2", children: /* @__PURE__ */ r(
"button",
{
onClick: () => h(f.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__ */ r(lu, { style: { width: "16px", height: "16px", color: "currentColor" } })
}
) })
] }),
/* @__PURE__ */ r(
"div",
{
className: "px-2 py-3 overflow-visible flex flex-col",
style: { height: T },
children: /* @__PURE__ */ r(
Bn,
{
ref: (p) => {
a.current[f.id] = p;
},
query: N,
chartType: x,
chartConfig: A,
displayConfig: w,
dashboardFilters: n,
dashboardFilterMapping: f.dashboardFilterMapping,
eagerLoad: f.eagerLoad ?? e.eagerLoad ?? !1,
title: f.title,
height: T,
colorPalette: t
}
)
}
)
]
},
f.id
);
}) }) });
}
const ea = () => `row-${Date.now()}`, Sn = (e, t) => {
const n = e.length;
if (n === 0) return [];
const { cols: s, minW: a } = t, i = a * n;
if (i > s) {
const u = Math.floor(s / n), h = s % n;
return e.map((f, m) => ({
portletId: f,
w: u + (m < h ? 1 : 0)
}));
}
const o = s - i, c = Math.floor(o / n), l = o % n;
return e.map((u, h) => ({
portletId: u,
w: a + c + (h < l ? 1 : 0)
}));
}, uu = (e, t) => {
if (e.length === 0) return [];
const { cols: n, minW: s } = t, a = e.map((c) => ({
...c,
w: Math.max(s, c.w)
}));
let i = a.reduce((c, l) => c + l.w, 0);
if (i === n) return a;
if (i < n) {
let c = n - i, l = 0;
for (; c > 0; )
a[l % a.length].w += 1, c -= 1, l += 1;
return a;
}
let o = i - n;
for (let c = a.length - 1; c >= 0 && o > 0; c -= 1) {
const l = a[c], u = Math.max(0, l.w - s);
if (u === 0) continue;
const h = Math.min(u, o);
l.w -= h, o -= h;
}
return a;
}, dr = (e, t) => {
if (e.length === 0) return [];
const n = [...e].sort((a, i) => a.y !== i.y ? a.y - i.y : a.x - i.x), s = /* @__PURE__ */ new Map();
return n.forEach((a) => {
const i = s.get(a.y) ?? [];
i.push(a), s.set(a.y, i);
}), Array.from(s.entries()).sort(([a], [i]) => a - i).map(([a, i]) => {
const o = Math.max(t.minH, ...i.map((l) => l.h)), c = i.map((l) => l.id);
return {
id: `row-${a}`,
h: o,
columns: Sn(c, t)
};
});
}, wn = (e, t, n) => {
const s = new Set(t.map((a) => a.id));
return e.map((a) => ({
...a,
h: Math.max(n.minH, a.h),
columns: uu(
a.columns.filter((i) => s.has(i.portletId)),
n
)
})).filter((a) => a.columns.length > 0);
}, ta = (e, t) => {
const n = new Map(t.map((o) => [o.id, o]));
let s = 0;
const a = [];
e.forEach((o) => {
let c = 0;
o.columns.forEach((l) => {
const u = n.get(l.portletId);
u && (a.push({
...u,
x: c,
y: s,
w: l.w,
h: o.h
}), c += l.w);
}), s += o.h;
});
const i = new Set(a.map((o) => o.id));
return t.forEach((o) => {
i.has(o.id) || a.push(o);
}), a;
}, fu = (e) => ({
isEditMode: e.isEditMode,
selectedFilterId: e.selectedFilterId,
isPortletModalOpen: e.isPortletModalOpen,
editingPortlet: e.editingPortlet,
isFilterConfigModalOpen: e.isFilterConfigModalOpen,
filterConfigPortlet: e.filterConfigPortlet,
deleteConfirmPortletId: e.deleteConfirmPortletId,
draftRows: e.draftRows,
isDraggingPortlet: e.isDraggingPortlet,
lastKnownLayout: e.lastKnownLayout,
isInitialized: e.isInitialized,
debugData: e.debugData
}), mu = (e) => ({
setEditMode: e.setEditMode,
toggleEditMode: e.toggleEditMode,
setSelectedFilterId: e.setSelectedFilterId,
exitFilterSelectionMode: e.exitFilterSelectionMode,
openPortletModal: e.openPortletModal,
closePortletModal: e.closePortletModal,
openFilterConfigModal: e.openFilterConfigModal,
closeFilterConfigModal: e.closeFilterConfigModal,
openDeleteConfirm: e.openDeleteConfirm,
closeDeleteConfirm: e.closeDeleteConfirm,
setDraftRows: e.setDraftRows,
setIsDraggingPortlet: e.setIsDraggingPortlet,
setLastKnownLayout: e.setLastKnownLayout,
setIsInitialized: e.setIsInitialized,
setDragState: e.setDragState,
clearDragState: e.clearDragState,
setDebugData: e.setDebugData,
clearDebugData: e.clearDebugData
});
function hu(e) {
const {
config: t,
editable: n = !1,
dashboardFilters: s,
gridSettings: a,
allowedModes: i,
isResponsiveEditable: o = !0,
onConfigChange: c,
onSave: l,
portletComponentRefs: u,
onPortletRefresh: h
} = e, f = Ut(Cr(fu)), m = Ut(Cr(mu)), g = ge(null);
g.current = f.draftRows;
const b = V(() => i && i.length > 0 ? i : ["rows", "grid"], [i]), N = V(() => {
const z = b.includes("rows") ? "rows" : b[0] ?? "grid", H = t.layoutMode ?? "grid";
return b.includes(H) ? H : z;
}, [t.layoutMode, b]), x = V(() => n && f.isEditMode && o && !f.selectedFilterId, [n, f.isEditMode, o, f.selectedFilterId]), A = V(() => n && f.isEditMode && o && !f.selectedFilterId && b.length > 1, [
n,
f.isEditMode,
o,
f.selectedFilterId,
b.length
]), w = V(() => !f.selectedFilterId || !s ? null : s.find((z) => z.id === f.selectedFilterId) ?? null, [f.selectedFilterId, s]), y = V(() => {
if (N !== "rows") return [];
const z = f.draftRows ?? t.rows ?? dr(t.portlets, a);
return wn(z, t.portlets, a);
}, [N, f.draftRows, t.rows, t.portlets, a]), C = E(() => {
m.setEditMode(!0);
}, [m]), T = E(() => {
m.setEditMode(!1);
}, [m]), p = E(() => {
o && m.toggleEditMode();
}, [o, m]), v = E(
(z) => {
m.setSelectedFilterId(
z === f.selectedFilterId ? null : z
);
},
[m, f.selectedFilterId]
), k = E(() => {
m.openPortletModal(null);
}, [m]), S = E(
(z) => {
m.openPortletModal(z);
},
[m]
), $ = E(
(z) => {
m.openFilterConfigModal(z);
},
[m]
), D = E(
(z) => {
if (!f.isInitialized || f.lastKnownLayout.length === 0)
return !1;
for (const H of z) {
const se = f.lastKnownLayout.find((me) => me.i === H.i);
if (se && (se.x !== H.x || se.y !== H.y || se.w !== H.w || se.h !== H.h))
return !0;
}
return !1;
},
[f.isInitialized, f.lastKnownLayout]
), F = E(
async (z, H = !0, se) => {
if (!c) return;
const me = se ?? t.portlets, le = wn(z, me, a), we = ta(le, me), Y = {
...t,
layoutMode: "rows",
rows: le,
portlets: we
};
if (m.setDraftRows(null), c(Y), H && l)
try {
await l(Y);
} catch (Pe) {
console.error("Auto-save failed after row layout change:", Pe);
}
},
[t, a, c, l, m]
), K = E(
async (z) => {
if (!c || z === N || !A || !b.includes(z))
return;
const H = wn(
t.rows && t.rows.length > 0 ? t.rows : dr(t.portlets, a),
t.portlets,
a
), se = ta(H, t.portlets), me = {
...t,
layoutMode: z,
rows: H,
portlets: se
};
if (m.setDraftRows(null), c(me), l)
try {
await l(me);
} catch (le) {
console.error("Auto-save failed after layout mode switch:", le);
}
},
[
b,
A,
t,
a,
N,
c,
l,
m
]
), P = E(
async (z) => {
if (!c) return null;
let H = [...t.portlets], se = !1, me = null;
if (f.editingPortlet) {
const le = H.findIndex(
(we) => we.id === f.editingPortlet.id
);
le !== -1 && (H[le] = z);
} else {
se = !0;
const le = {
...z,
id: `portlet-${Date.now()}`,
x: 0,
y: 0
};
me = le.id;
let we = 0;
t.portlets.forEach((Y) => {
Y.y + Y.h > we && (we = Y.y + Y.h);
}), le.y = we, H.push(le);
}
if (N === "rows") {
const le = y.length > 0 ? y.map((Y) => ({
...Y,
columns: Y.columns.map((Pe) => ({ ...Pe }))
})) : wn(
t.rows ?? dr(t.portlets, a),
H,
a
), we = se && me ? [
...le,
{
id: ea(),
h: Math.max(a.minH, 5),
columns: Sn([me], a)
}
] : le;
await F(we, !0, H);
} else {
const le = {
...t,
portlets: H
};
if (c(le), l)
try {
await l(le);
} catch (we) {
console.error("Auto-save failed:", we);
}
}
return m.closePortletModal(), me;
},
[
t,
a,
N,
c,
l,
y,
m,
f.editingPortlet,
F
]
), te = E(
async (z) => {
if (!c) return;
const H = t.portlets.filter((se) => se.id !== z);
if (N === "rows") {
const se = y.map((me) => ({
...me,
columns: me.columns.filter((le) => le.portletId !== z)
})).filter((me) => me.columns.length > 0).map((me) => ({
...me,
columns: Sn(
me.columns.map((le) => le.portletId),
a
)
}));
await F(se, !0, H);
} else {
const se = {
...t,
portlets: H
};
if (c(se), l)
try {
await l(se);
} catch (me) {
console.error("Auto-save failed:", me);
}
}
},
[t, a, N, c, l, y, F]
), _ = E(
async (z) => {
m.openDeleteConfirm(z);
},
[m]
), O = E(async () => {
const z = f.deleteConfirmPortletId;
z && (await te(z), m.closeDeleteConfirm());
}, [te, f.deleteConfirmPortletId, m]), ie = E(
async (z) => {
if (!c) return;
const H = t.portlets.find((we) => we.id === z);
if (!H) return;
const se = {
...H,
id: `portlet-${Date.now()}`,
title: `${H.title} Duplicated`,
x: 0,
y: 0
};
let me = 0;
t.portlets.forEach((we) => {
we.y + we.h > me && (me = we.y + we.h);
}), se.y = me;
const le = [...t.portlets, se];
if (N === "rows") {
const Y = [
...y.map((Pe) => ({
...Pe,
columns: Pe.columns.map((He) => ({ ...He }))
})),
{
id: ea(),
h: Math.max(a.minH, 5),
columns: Sn([se.id], a)
}
];
await F(Y, !0, le);
} else {
const we = {
...t,
portlets: le
};
if (c(we), l)
try {
await l(we);
} catch (Y) {
console.error("Auto-save failed:", Y);
}
}
return se.id;
},
[t, a, N, c, l, y, F]
), X = E(
(z) => {
const H = u?.current?.[z];
H?.refresh && H.refresh(), h?.(z);
},
[u, h]
), ce = E(
async (z, H) => {
if (!c) return;
const se = t.portlets.map((le) => {
if (le.id === z) {
const we = le.dashboardFilterMapping || [], Y = we.includes(H);
return {
...le,
dashboardFilterMapping: Y ? we.filter((Pe) => Pe !== H) : [...we, H]
};
}
return le;
}), me = {
...t,
portlets: se
};
if (c(me), l)
try {
await l(me);
} catch (le) {
console.error("Auto-save failed:", le);
}
},
[t, c, l]
), Q = E(
async (z) => {
if (!c) return;
const H = t.portlets.map((me) => {
const le = me.dashboardFilterMapping || [];
return le.includes(z) ? me : {
...me,
dashboardFilterMapping: [...le, z]
};
}), se = {
...t,
portlets: H
};
if (c(se), l)
try {
await l(se);
} catch (me) {
console.error("Auto-save failed:", me);
}
},
[t, c, l]
), Se = E(
async (z) => {
if (!c || !f.filterConfigPortlet) return;
const H = t.portlets.map((me) => me.id === f.filterConfigPortlet.id ? {
...me,
dashboardFilterMapping: z
} : me), se = {
...t,
portlets: H
};
if (c(se), l)
try {
await l(se);
} catch (me) {
console.error("Auto-save failed:", me);
}
},
[t, c, l, f.filterConfigPortlet]
), L = E(
async (z) => {
if (!c) return;
const H = {
...t,
colorPalette: z
};
if (c(H), l)
try {
await l(H);
} catch (se) {
console.error("Auto-save failed:", se);
}
},
[t, c, l]
), pe = V(
() => ({
// Edit mode
enterEditMode: C,
exitEditMode: T,
toggleEditMode: p,
selectFilter: v,
exitFilterSelectionMode: m.exitFilterSelectionMode,
// Modals
openAddPortlet: k,
openEditPortlet: S,
closePortletModal: m.closePortletModal,
openFilterConfig: $,
closeFilterConfig: m.closeFilterConfigModal,
// Layout state
setDraftRows: m.setDraftRows,
setIsDraggingPortlet: m.setIsDraggingPortlet,
setLastKnownLayout: m.setLastKnownLayout,
setIsInitialized: m.setIsInitialized,
setDragState: m.setDragState,
clearDragState: m.clearDragState,
// Layout operations
hasLayoutActuallyChanged: D,
updateRowLayout: F,
handleLayoutModeChange: K,
// Portlet operations
savePortlet: P,
deletePortlet: _,
duplicatePortlet: ie,
refreshPortlet: X,
// Filter operations
toggleFilterForPortlet: ce,
selectAllForFilter: Q,
saveFilterConfig: Se,
// Config operations
handlePaletteChange: L,
// Delete confirmation
openDeleteConfirm: m.openDeleteConfirm,
closeDeleteConfirm: m.closeDeleteConfirm,
confirmDelete: O,
// Debug
setDebugData: m.setDebugData,
clearDebugData: m.clearDebugData
}),
[
C,
T,
p,
v,
m,
k,
S,
$,
D,
F,
K,
P,
_,
ie,
X,
ce,
Q,
Se,
L,
O
]
);
return {
// Store state
...f,
// Computed values
canEdit: x,
canChangeLayoutMode: A,
selectedFilter: w,
resolvedRows: y,
layoutMode: N,
allowedModes: b,
// Actions
actions: pe
};
}
const pu = q("measure"), gu = q("refresh"), na = q("edit"), yu = q("check"), bu = q("delete"), ra = q("add"), xu = q("copy"), sa = q("filter"), vu = q("desktop"), wu = q("segment"), Nu = q("table");
function Cu(e) {
if (!e) return null;
let t = e.parentElement;
for (; t; ) {
const n = window.getComputedStyle(t), s = n.overflowY, a = n.overflowX, i = s === "auto" || s === "scroll" || a === "auto" || a === "scroll", o = t.scrollHeight > t.clientHeight || t.scrollWidth > t.clientWidth;
if (i && o)
return t;
if (t === document.body) break;
t = t.parentElement;
}
return null;
}
const Nn = {
cols: 12,
rowHeight: 80,
minW: 2,
minH: 2
}, Su = () => `row-${Date.now()}`, Du = (e) => ({
cols: e.grid?.cols ?? Nn.cols,
rowHeight: e.grid?.rowHeight ?? Nn.rowHeight,
minW: e.grid?.minW ?? Nn.minW,
minH: e.grid?.minH ?? Nn.minH
}), Cn = (e, t) => {
const n = e.length;
if (n === 0) return [];
const { cols: s, minW: a } = t, i = a * n;
if (i > s) {
const u = Math.floor(s / n), h = s % n;
return e.map((f, m) => ({
portletId: f,
w: u + (m < h ? 1 : 0)
}));
}
const o = s - i, c = Math.floor(o / n), l = o % n;
return e.map((u, h) => ({
portletId: u,
w: a + c + (h < l ? 1 : 0)
}));
}, Tu = (e, t) => {
if (e.length === 0) return [];
const { cols: n, minW: s } = t, a = e.map((c) => ({
...c,
w: Math.max(s, c.w)
}));
let i = a.reduce((c, l) => c + l.w, 0);
if (i === n) return a;
if (i < n) {
let c = n - i, l = 0;
for (; c > 0; )
a[l % a.length].w += 1, c -= 1, l += 1;
return a;
}
let o = i - n;
for (let c = a.length - 1; c >= 0 && o > 0; c -= 1) {
const l = a[c], u = Math.max(0, l.w - s);
if (u === 0) continue;
const h = Math.min(u, o);
l.w -= h, o -= h;
}
return a;
};
function ku({
config: e,
editable: t = !1,
dashboardFilters: n,
loadingComponent: s,
onConfigChange: a,
onPortletRefresh: i,
onSave: o,
colorPalette: c,
schema: l,
onDashboardFiltersChange: u,
dashboardModes: h
}) {
const { features: f } = an(), {
containerRef: m,
containerWidth: g,
displayMode: b,
scaleFactor: N,
isEditable: x,
designWidth: A
} = $i(), w = h && h.length > 0 ? h : ["rows", "grid"], y = V(() => Du(e), [e]), [C, T] = ee(null), p = ge(null), v = ge(null), k = ge(null), S = E((I) => {
if (p.current = I, m(I), I) {
const B = Cu(I);
T(B), v.current = B;
}
}, [m]), $ = b === "desktop" ? g : A, D = ge({}), F = ge({}), K = ge(null), P = ge(null), te = hu({
config: e,
editable: t,
dashboardFilters: n,
gridSettings: y,
allowedModes: w,
isResponsiveEditable: x,
onConfigChange: a,
onSave: o,
portletComponentRefs: F,
onPortletRefresh: i
}), {
isEditMode: _,
selectedFilterId: O,
isPortletModalOpen: ie,
editingPortlet: X,
isFilterConfigModalOpen: ce,
filterConfigPortlet: Q,
deleteConfirmPortletId: Se,
draftRows: L,
isDraggingPortlet: pe,
isInitialized: z,
// debugData removed - now read from store directly in DashboardPortletCard
canEdit: H,
canChangeLayoutMode: se,
selectedFilter: me,
resolvedRows: le,
layoutMode: we,
actions: Y
} = te;
he(() => {
K.current = L;
}, [L]), he(() => {
(!_ || !x) && O && Y.exitFilterSelectionMode();
}, [_, x, O, Y]), he(() => {
!x && _ && Y.exitEditMode();
}, [x, _, Y]);
const Pe = yo(v, {
threshold: 20,
debounceMs: 150,
container: C
// State dependency to trigger re-init when container found
}), He = bo(k, {
threshold: 80,
debounceMs: 100,
containerRef: v,
container: C
// State dependency to trigger re-init when container found
});
he(() => {
const I = setTimeout(() => {
Y.setIsInitialized(!0);
const B = e.portlets.map((Z) => ({
i: Z.id,
x: Z.x,
y: Z.y,
w: Z.w,
h: Z.h
}));
Y.setLastKnownLayout(B);
}, 200);
return () => clearTimeout(I);
}, [e.portlets, Y]), he(() => {
const I = (B) => {
B.key === "Escape" && O && Y.exitFilterSelectionMode();
};
return window.addEventListener("keydown", I), () => {
window.removeEventListener("keydown", I);
};
}, [O, Y]);
const Ne = E((I) => {
}, []), _e = E(async (I, B, Z, ue, ae, U) => {
if (!t || !_ || !o || !z) return;
const G = [...I];
if (!Y.hasLayoutActuallyChanged(G))
return;
const oe = e.portlets.map((De) => {
const $e = G.find((et) => et.i === De.id);
return $e ? {
...De,
x: $e.x,
y: $e.y,
w: $e.w,
h: $e.h
} : De;
}), Ae = {
...e,
portlets: oe,
layouts: {
...e.layouts,
lg: G
// Only save the large layout, let RGL handle responsive adjustments
}
};
Y.setLastKnownLayout(G), a?.(Ae);
try {
await o(Ae);
} catch (De) {
console.error("Auto-save failed after drag:", De);
}
}, [e, t, _, a, o, z, Y]), We = E(async (I, B, Z, ue, ae, U) => {
if (!t || !_ || !a || !z) return;
const G = [...I];
if (!Y.hasLayoutActuallyChanged(G))
return;
const oe = e.portlets.map((De) => {
const $e = G.find((et) => et.i === De.id);
return $e ? {
...De,
x: $e.x,
y: $e.y,
w: $e.w,
h: $e.h
} : De;
}), Ae = {
...e,
portlets: oe,
layouts: {
...e.layouts,
lg: G
// Only save the large layout, let RGL handle responsive adjustments
}
};
if (Y.setLastKnownLayout(G), a(Ae), o)
try {
await o(Ae);
} catch (De) {
console.error("Auto-save failed after resize:", De);
}
}, [e, t, _, a, o, z, Y]), Je = E((I, B) => {
if (!H) return;
B.preventDefault();
const Z = B.clientY, ue = le.map((G) => ({
...G,
columns: G.columns.map((oe) => ({ ...oe }))
})), ae = (G) => {
const oe = G.clientY - Z, Ae = Math.round(oe / y.rowHeight), De = ue.map(($e, et) => et !== I ? $e : {
...$e,
h: Math.max(y.minH, $e.h + Ae)
});
Y.setDraftRows(De);
}, U = () => {
document.removeEventListener("mousemove", ae), document.removeEventListener("mouseup", U);
const G = K.current ?? ue;
Y.updateRowLayout(G);
};
document.addEventListener("mousemove", ae), document.addEventListener("mouseup", U);
}, [H, y, le, Y]), Ke = E((I, B, Z) => {
if (!H) return;
Z.preventDefault();
const ue = Z.clientX, ae = le.map((at) => ({
...at,
columns: at.columns.map((Ct) => ({ ...Ct }))
})), U = ae[I], G = U?.columns[B], oe = U?.columns[B + 1];
if (!U || !G || !oe) return;
const $e = ($ - (U.columns.length - 1) * 16) / y.cols, et = (at) => {
const Ct = at.clientX - ue, Rt = Math.round(Ct / $e);
if (Rt === 0) {
Y.setDraftRows(ae);
return;
}
let yt = G.w + Rt, R = oe.w - Rt;
if (yt < y.minW) {
const nt = y.minW - yt;
yt = y.minW, R -= nt;
}
if (R < y.minW) {
const nt = y.minW - R;
R = y.minW, yt -= nt;
}
if (yt < y.minW || R < y.minW) return;
const Ue = ae.map((nt, $t) => {
if ($t !== I) return nt;
const Lt = nt.columns.map((At, ft) => ft === B ? { ...At, w: yt } : ft === B + 1 ? { ...At, w: R } : At);
return {
...nt,
columns: Tu(Lt, y)
};
});
Y.setDraftRows(Ue);
}, tt = () => {
document.removeEventListener("mousemove", et), document.removeEventListener("mouseup", tt);
const at = K.current ?? ae;
Y.updateRowLayout(at);
};
document.addEventListener("mousemove", et), document.addEventListener("mouseup", tt);
}, [H, y, $, le, Y]), Oe = E((I, B, Z, ue) => {
H && (P.current = { rowIndex: I, colIndex: B, portletId: Z }, Y.setIsDraggingPortlet(!0), ue.dataTransfer.effectAllowed = "move", ue.dataTransfer.setData("text/plain", Z));
}, [H, Y]), Xe = E(() => {
P.current = null, Y.setIsDraggingPortlet(!1);
}, [Y]), Qe = E((I, B) => {
const Z = P.current;
if (!Z) return;
const ue = le.map((tt) => ({
...tt,
columns: tt.columns.map((at) => ({ ...at }))
})), ae = Z.rowIndex, U = ue[ae];
if (!U) return;
const [G] = U.columns.splice(Z.colIndex, 1);
let oe = !1;
U.columns.length === 0 && (ue.splice(ae, 1), oe = !0);
let Ae = I;
oe && ae < I && (Ae -= 1);
const De = ue[Ae];
if (!De) return;
let $e = B ?? De.columns.length;
!oe && ae === Ae && B !== null && B > Z.colIndex && ($e -= 1), De.columns.splice($e, 0, G), (ae !== Ae || oe) && (oe || (ue[ae] = {
...ue[ae],
columns: Cn(
ue[ae].columns.map((tt) => tt.portletId),
y
)
}), ue[Ae] = {
...ue[Ae],
columns: Cn(
ue[Ae].columns.map((tt) => tt.portletId),
y
)
}), Y.updateRowLayout(ue);
}, [y, le, Y]), J = E((I) => {
const B = P.current;
if (!B) return;
const Z = le.map((G) => ({
...G,
columns: G.columns.map((oe) => ({ ...oe }))
})), ue = Z[B.rowIndex];
if (!ue) return;
const [ae] = ue.columns.splice(B.colIndex, 1);
ue.columns.length === 0 ? Z.splice(B.rowIndex, 1) : ue.columns = Cn(
ue.columns.map((G) => G.portletId),
y
);
const U = {
id: Su(),
h: Math.max(y.minH, 5),
columns: Cn([ae.portletId], y)
};
Z.splice(I, 0, U), Y.updateRowLayout(Z);
}, [y, le, Y]), fe = E((I) => {
Y.refreshPortlet(I);
}, [Y]), ve = E(async (I) => {
const B = await Y.savePortlet(I);
Y.closePortletModal(), B && setTimeout(() => {
const Z = () => {
let ue = D.current[B];
return ue || (ue = document.querySelector(`[data-portlet-id="${B}"]`)), ue ? (ue.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "nearest"
}), !0) : !1;
};
Z() || setTimeout(() => {
Z() || setTimeout(() => {
Z();
}, 300);
}, 200);
}, 200);
}, [Y]), ke = E(async (I) => {
await Y.deletePortlet(I);
}, [Y]), Fe = E(async (I) => {
const B = await Y.duplicatePortlet(I);
B && setTimeout(() => {
const Z = () => {
let ue = D.current[B];
return ue || (ue = document.querySelector(`[data-portlet-id="${B}"]`)), ue ? (ue.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "nearest"
}), !0) : !1;
};
Z() || setTimeout(() => {
Z() || setTimeout(() => {
Z();
}, 300);
}, 200);
}, 200);
}, [Y]), re = E(() => {
Y.openAddPortlet();
}, [Y]), be = E((I) => {
Y.openEditPortlet(I);
}, [Y]), Ee = E(async (I) => {
await Y.handlePaletteChange(I);
}, [Y]), qe = E((I) => {
Y.openFilterConfig(I);
}, [Y]), Ze = E(async (I) => {
await Y.saveFilterConfig(I);
}, [Y]), xt = E((I, B) => {
D.current[I] = B;
}, []), vt = E((I, B) => {
F.current[I] = B;
}, []), gt = V(() => ({
RefreshIcon: gu,
EditIcon: na,
DeleteIcon: bu,
CopyIcon: xu,
FilterIcon: sa
}), []), wt = E(async (I, B) => {
await Y.toggleFilterForPortlet(I, B);
}, [Y]), Tt = E((I) => {
Y.selectFilter(I);
}, [Y]), kt = E(async (I) => {
await Y.selectAllForFilter(I);
}, [Y]), ct = V(() => ({
onToggleFilter: wt,
onRefresh: fe,
onDuplicate: Fe,
onEdit: be,
onDelete: ke,
onOpenFilterConfig: qe
}), [
wt,
fe,
Fe,
be,
ke,
qe
]), ut = E((I, B, Z) => /* @__PURE__ */ r(
$o,
{
portlet: I,
editable: t,
dashboardFilters: n,
configEagerLoad: e.eagerLoad,
loadingComponent: s,
colorPalette: c,
containerProps: B,
headerProps: Z,
callbacks: ct,
setPortletRef: xt,
setPortletComponentRef: vt,
icons: gt
}
), [
t,
n,
e.eagerLoad,
s,
c,
ct,
xt,
vt,
gt
]);
if (!e.portlets || e.portlets.length === 0)
return /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r("div", { className: "flex justify-center items-center min-h-[50vh]", children: /* @__PURE__ */ d("div", { className: "text-center", children: [
/* @__PURE__ */ r(pu, { style: { width: "64px", height: "64px", color: "var(--dc-text-muted)", margin: "0 auto 16px auto" } }),
/* @__PURE__ */ r("h3", { className: "text-lg font-semibold mb-2 text-dc-text", children: "No Portlets" }),
/* @__PURE__ */ r("p", { className: "text-sm text-dc-text-secondary mb-4", children: "Add your first portlet to start visualizing your data" }),
t && /* @__PURE__ */ d(
"button",
{
onClick: re,
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: (I) => I.currentTarget.style.backgroundColor = "var(--dc-surface-hover)",
onMouseLeave: (I) => I.currentTarget.style.backgroundColor = "var(--dc-surface)",
children: [
/* @__PURE__ */ r(ra, { className: "w-5 h-5 mr-2" }),
"Add Portlet"
]
}
)
] }) }),
/* @__PURE__ */ r(
js,
{
isOpen: ie,
onClose: Y.closePortletModal,
onSave: ve,
portlet: X,
title: X ? "Edit Portlet" : "Add New Portlet",
submitText: X ? "Update Portlet" : "Add Portlet",
colorPalette: c,
dashboardFilters: n
}
)
] });
const Ye = e.portlets.map((I) => ({
i: I.id,
x: I.x,
y: I.y,
w: I.w,
h: I.h,
minW: y.minW,
minH: y.minH,
// 2 rows at 80px = 160px minimum
// Only enable drag/resize in edit mode
isDraggable: H,
isResizable: H,
...H ? { resizeHandles: ["s", "w", "e", "n", "se", "sw", "ne", "nw"] } : {}
})), ze = we === "rows" ? /* @__PURE__ */ r(
Lo,
{
rows: le,
portlets: e.portlets,
gridSettings: y,
gridWidth: $,
canEdit: H,
isDragging: pe,
onRowResize: Je,
onColumnResize: Ke,
onPortletDragStart: Oe,
onPortletDragEnd: Xe,
onRowDrop: Qe,
onNewRowDrop: J,
renderPortlet: ut
}
) : /* @__PURE__ */ r(
Pi,
{
className: "layout",
layout: Ye,
onLayoutChange: Ne,
onDragStop: _e,
onResizeStop: We,
width: $,
gridConfig: {
cols: y.cols,
rowHeight: y.rowHeight,
margin: [16, 16],
containerPadding: [0, 0]
},
dragConfig: {
enabled: H,
handle: ".portlet-drag-handle"
},
resizeConfig: {
enabled: H,
handles: ["s", "w", "e", "n", "se", "sw", "ne", "nw"],
// Invisible but functional resize handles
handleComponent: (I, B) => /* @__PURE__ */ r(
"div",
{
ref: B,
className: `react-resizable-handle react-resizable-handle-${I}`,
style: { opacity: 0 }
}
)
},
compactor: qi,
children: e.portlets.filter((I) => I && I.id).map((I) => /* @__PURE__ */ r("div", { children: ut(I) }, I.id))
}
);
return /* @__PURE__ */ r(ca, { value: C, children: /* @__PURE__ */ d("div", { ref: S, className: "dashboard-grid-container w-full", style: { maxWidth: "100%", overflow: "hidden" }, children: [
t && f.editToolbar !== "floating" && /* @__PURE__ */ d(
"div",
{
ref: k,
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 ${Pe ? "border-b" : ""}`,
style: {
boxShadow: Pe ? "var(--dc-shadow-md)" : "var(--dc-shadow-sm)"
},
children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-4", children: [
/* @__PURE__ */ d(
"button",
{
onClick: () => x && Y.toggleEditMode(),
disabled: !x,
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 ${x ? _ ? "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: x ? "var(--dc-primary)" : "var(--dc-text-muted)",
borderColor: x ? _ ? "var(--dc-border)" : "var(--dc-primary)" : "var(--dc-border)"
},
children: [
_ ? /* @__PURE__ */ r(yu, { className: "w-4 h-4 mr-1.5" }) : /* @__PURE__ */ r(na, { className: "w-4 h-4 mr-1.5" }),
_ ? "Finish Editing" : "Edit"
]
}
),
_ && w.length > 1 && /* @__PURE__ */ d("div", { className: "inline-flex rounded-md border border-dc-border overflow-hidden whitespace-nowrap", children: [
/* @__PURE__ */ d(
"button",
{
onClick: () => Y.handleLayoutModeChange("grid"),
disabled: !se,
className: `inline-flex items-center gap-2 whitespace-nowrap px-3 py-1.5 text-sm font-medium transition-colors ${we === "grid" ? "bg-dc-surface-secondary text-dc-text shadow-inner" : "bg-dc-surface text-dc-text-secondary hover:bg-dc-surface-hover"} ${se ? "" : "cursor-not-allowed opacity-50"}`,
children: [
/* @__PURE__ */ r(wu, { className: "w-4 h-4 shrink-0" }),
"Grid"
]
}
),
/* @__PURE__ */ d(
"button",
{
onClick: () => Y.handleLayoutModeChange("rows"),
disabled: !se,
className: `inline-flex items-center gap-2 whitespace-nowrap px-3 py-1.5 text-sm font-medium transition-colors ${we === "rows" ? "bg-dc-surface-secondary text-dc-text shadow-inner" : "bg-dc-surface text-dc-text-secondary hover:bg-dc-surface-hover"} ${se ? "" : "cursor-not-allowed opacity-50"}`,
children: [
/* @__PURE__ */ r(Nu, { className: "w-4 h-4 shrink-0" }),
"Rows"
]
}
)
] }),
!x && /* @__PURE__ */ d("div", { className: "flex items-center gap-2 text-sm text-dc-text-secondary", children: [
/* @__PURE__ */ r(vu, { className: "w-4 h-4" }),
/* @__PURE__ */ r("span", { children: "Desktop view required for editing" })
] }),
_ && x && /* @__PURE__ */ r("p", { className: "hidden md:block text-sm text-dc-text-secondary", children: "Drag • Resize • Auto-save" })
] }),
_ && /* @__PURE__ */ d("div", { className: "flex items-center gap-3", children: [
/* @__PURE__ */ r(
Ba,
{
currentPalette: e.colorPalette,
onPaletteChange: Ee,
className: "shrink-0"
}
),
/* @__PURE__ */ d(
"button",
{
onClick: re,
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__ */ r(ra, { className: "w-5 h-5 mr-2" }),
"Add Portlet"
]
}
)
] })
]
}
),
t && f.editToolbar !== "top" && b === "desktop" && /* @__PURE__ */ r(
Vo,
{
isEditBarVisible: f.editToolbar === "floating" ? !1 : He,
position: f.floatingToolbarPosition || "right",
isEditMode: _,
onEditModeToggle: () => x && Y.toggleEditMode(),
layoutMode: we,
onLayoutModeChange: Y.handleLayoutModeChange,
allowedModes: w,
canChangeLayoutMode: se,
currentPalette: e.colorPalette || "default",
onPaletteChange: Y.handlePaletteChange,
onAddPortlet: Y.openAddPortlet
}
),
/* @__PURE__ */ r(
iu,
{
dashboardFilters: n || [],
editable: t,
schema: l || null,
dashboardConfig: e,
onDashboardFiltersChange: u || (() => {
}),
onSaveFilters: o ? async (I) => {
const B = {
...e,
filters: I
};
await o(B);
} : void 0,
selectedFilterId: O,
onFilterSelect: Tt,
isEditMode: _
}
),
O && me && /* @__PURE__ */ r(
"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__ */ d("div", { className: "flex items-center justify-between flex-wrap gap-2", children: [
/* @__PURE__ */ d("div", { className: "flex items-center gap-2 flex-wrap", children: [
/* @__PURE__ */ r(sa, { className: "w-5 h-5 shrink-0" }),
/* @__PURE__ */ d("span", { className: "font-medium", children: [
"Filter Selection Mode - Click portlets to toggle '",
me.label,
"'"
] }),
/* @__PURE__ */ r("span", { className: "text-sm opacity-90 hidden sm:inline", children: "• Press ESC to exit" })
] }),
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ r(
"button",
{
onClick: () => kt(O),
className: "px-3 py-1 rounded-md transition-colors text-sm font-medium",
style: {
backgroundColor: "rgba(255, 255, 255, 0.2)",
color: "white"
},
onMouseEnter: (I) => I.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.3)",
onMouseLeave: (I) => I.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)",
children: "Select All"
}
),
/* @__PURE__ */ r(
"button",
{
onClick: () => Y.exitFilterSelectionMode(),
className: "px-3 py-1 rounded-md transition-colors text-sm font-medium",
style: {
backgroundColor: "rgba(255, 255, 255, 0.2)",
color: "white"
},
onMouseEnter: (I) => I.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.3)",
onMouseLeave: (I) => I.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)",
children: "Exit"
}
)
] })
] })
}
),
b === "mobile" ? /* @__PURE__ */ r(
du,
{
config: e,
colorPalette: c,
dashboardFilters: n,
onPortletRefresh: fe
}
) : b === "scaled" ? /* @__PURE__ */ r(ou, { scaleFactor: N, designWidth: A, children: ze }) : ze,
/* @__PURE__ */ r(
js,
{
isOpen: ie,
onClose: Y.closePortletModal,
onSave: ve,
portlet: X,
title: X ? "Edit Portlet" : "Add New Portlet",
submitText: X ? "Update Portlet" : "Add Portlet",
colorPalette: c,
dashboardFilters: n
}
),
/* @__PURE__ */ r(
Pd,
{
isOpen: ce,
onClose: Y.closeFilterConfig,
dashboardFilters: n || [],
currentMapping: Q?.dashboardFilterMapping || [],
onSave: Ze,
portletTitle: Q?.title || ""
}
),
/* @__PURE__ */ r(
qa,
{
isOpen: !!Se,
onClose: Y.closeDeleteConfirm,
onConfirm: Y.confirmDelete,
title: "Delete Portlet",
message: /* @__PURE__ */ d(Ce, { children: [
"Are you sure you want to delete",
" ",
/* @__PURE__ */ r("strong", { children: e.portlets.find((I) => I.id === Se)?.title || "this portlet" }),
"? This action cannot be undone."
] }),
confirmText: "Delete",
confirmVariant: "danger"
}
)
] }) });
}
function lf({
config: e,
editable: t = !1,
dashboardFilters: n,
loadingComponent: s,
onConfigChange: a,
onSave: i,
onDirtyStateChange: o
}) {
const { meta: c } = la(), { dashboardModes: l } = an(), {
handleConfigChange: u,
handleSave: h
} = Li({
initialConfig: e,
onConfigChange: a,
onSave: i,
onDirtyStateChange: o
}), f = V(() => {
const b = e.filters || [], N = n || [];
if (N.length === 0)
return b;
if (b.length === 0)
return N;
const x = b.map((y) => {
const C = N.find((T) => T.id === y.id);
return C ? {
...y,
// Preserve id, label, isUniversalTime from config
filter: C.filter
// Use filter values from prop override
} : y;
}), A = new Set(b.map((y) => y.id)), w = N.filter((y) => !A.has(y.id));
return [...x, ...w];
}, [e.filters, n]), m = E((b) => {
if (!n || n.length === 0) {
const N = {
...e,
filters: b
};
u(N);
} else
console.warn("Dashboard filters are controlled via props - config changes ignored");
}, [e, n, u]), g = V(() => {
const b = e.colorPalette;
return Fr(b);
}, [e.colorPalette]);
return /* @__PURE__ */ r(_o, { children: /* @__PURE__ */ r("div", { className: "w-full", children: /* @__PURE__ */ r(
ku,
{
config: e,
editable: t,
dashboardFilters: f,
loadingComponent: s,
onConfigChange: u,
onSave: h,
colorPalette: g,
schema: c,
dashboardModes: l,
onDashboardFiltersChange: m
}
) }) });
}
function cf({
portlet: e,
editable: t = !1,
onEdit: n,
onDelete: s,
onRefresh: a
}) {
const i = V(() => ln(e), [e]), { analysisConfig: o } = i, c = o.charts[o.analysisType], l = V(() => JSON.stringify(o.query), [o.query]), u = c?.chartType || "line", h = c?.chartConfig, f = c?.displayConfig, [m, g] = ee(null), b = E((N) => {
g(N);
}, []);
return /* @__PURE__ */ d("div", { className: "bg-dc-surface border border-dc-border rounded-lg flex flex-col h-full", style: { boxShadow: "var(--dc-shadow-sm)" }, children: [
/* @__PURE__ */ d("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__ */ d("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
/* @__PURE__ */ r("h3", { className: "font-semibold text-sm truncate text-dc-text", children: e.title }),
m && /* @__PURE__ */ r(
va,
{
chartConfig: m.chartConfig,
displayConfig: m.displayConfig,
queryObject: m.queryObject,
data: m.data,
chartType: m.chartType,
cacheInfo: m.cacheInfo
}
)
] }),
/* @__PURE__ */ r("div", { className: "flex items-center gap-2 ml-4", children: t && /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(
"button",
{
onClick: () => a?.(e.id),
className: "p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary",
title: "Refresh",
children: /* @__PURE__ */ r("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ r("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__ */ r(
"button",
{
onClick: () => n?.(e),
className: "p-1.5 hover:bg-dc-surface-hover rounded-sm text-dc-text-secondary",
title: "Edit",
children: /* @__PURE__ */ r("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ r("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__ */ r(
"button",
{
onClick: () => s?.(e.id),
className: "p-1.5 rounded-sm text-dc-danger",
style: { backgroundColor: "transparent" },
onMouseEnter: (N) => N.currentTarget.style.backgroundColor = "var(--dc-danger-bg)",
onMouseLeave: (N) => N.currentTarget.style.backgroundColor = "transparent",
title: "Delete",
children: /* @__PURE__ */ r("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ r("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__ */ r("div", { className: "px-2 py-3 md:px-4 md:pt-6 md:pb-4 flex-1 min-h-0", children: /* @__PURE__ */ r(
Bn,
{
query: l,
chartType: u,
chartConfig: h,
displayConfig: f,
title: e.title,
height: "100%",
onDebugDataReady: b
}
) })
] });
}
function df({
isOpen: e,
onClose: t,
onSave: n,
title: s,
submitText: a,
initialName: i = "",
initialDescription: o = ""
}) {
const [c, l] = ee(""), [u, h] = ee(""), [f, m] = ee(!1);
he(() => {
e && (l(i), h(o));
}, [e, i, o]);
const g = async (x) => {
if (x.preventDefault(), !!c.trim()) {
m(!0);
try {
await n({
name: c.trim(),
description: u.trim() || void 0
}), b();
} catch {
} finally {
m(!1);
}
}
}, b = () => {
l(""), h(""), m(!1), t();
}, N = /* @__PURE__ */ d(Ce, { children: [
/* @__PURE__ */ r(
"button",
{
type: "button",
onClick: b,
disabled: f,
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__ */ r(
"button",
{
type: "submit",
form: "dashboard-form",
disabled: f || !c.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: f ? "Saving..." : a
}
)
] });
return /* @__PURE__ */ r(
Rr,
{
isOpen: e,
onClose: b,
title: s,
size: "fullscreen-mobile",
footer: N,
children: /* @__PURE__ */ d("form", { id: "dashboard-form", onSubmit: g, className: "space-y-4 w-full", children: [
/* @__PURE__ */ d("div", { children: [
/* @__PURE__ */ r("label", { htmlFor: "dashboard-name", className: "block text-sm font-medium text-dc-text-secondary mb-1", children: "Dashboard Name" }),
/* @__PURE__ */ r(
"input",
{
type: "text",
id: "dashboard-name",
value: c,
onChange: (x) => l(x.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__ */ d("div", { children: [
/* @__PURE__ */ r("label", { htmlFor: "dashboard-description", className: "block text-sm font-medium text-dc-text-secondary mb-1", children: "Description (optional)" }),
/* @__PURE__ */ r(
"textarea",
{
id: "dashboard-description",
rows: 3,
value: u,
onChange: (x) => h(x.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..."
}
)
] })
] })
}
);
}
const Au = Ln(
(e, t) => {
const n = ge(null);
return Dr(t, () => ({
getCurrentQuery: () => {
const s = n.current?.getQueryConfig();
return s ? "funnel" in s ? { measures: [], dimensions: [] } : "queries" in s ? s.queries[0] || { measures: [], dimensions: [] } : s : { measures: [], dimensions: [] };
},
getValidationState: () => ({
status: "valid"
}),
getValidationResult: () => null
}), []), /* @__PURE__ */ r(
Vr,
{
ref: n,
className: e.className,
initialQuery: e.initialQuery,
disableLocalStorage: e.disableLocalStorage,
hideSettings: e.hideSettings
}
);
}
);
Au.displayName = "QueryBuilder";
export {
sd as $,
Bn as A,
Ku as B,
qa as C,
ku as D,
Vu as E,
Uu as F,
Hu as G,
zu as H,
Gu as I,
Wu as J,
Yu as K,
Fl as L,
Rr as M,
Al as N,
Ml as O,
cf as P,
Au as Q,
Il as R,
El as S,
rf as T,
sf as U,
yo as V,
bo as W,
so as X,
ao as Y,
vo as Z,
af as _,
lf as a,
ad as a0,
od as a1,
of as a2,
Kr as a3,
ld as a4,
Br as a5,
js as b,
df as c,
Vr as d,
Lu as e,
ga as f,
Pu as g,
Jl as h,
hu as i,
W as j,
Ju as k,
Xu as l,
Zu as m,
kl as n,
ef as o,
tf as p,
nf as q,
_o as r,
$r as s,
Ut as t,
pa as u,
qu as v,
Bu as w,
wa as x,
Qu as y,
ju as z
};
//# sourceMappingURL=components-DIoQGahV.js.map