@bitcobblers/wod-wiki-ui 0.50.2189 → 0.50.2190
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-UAIJTD74.mjs → chunk-GM2PO7LK.mjs} +436 -279
- package/dist/chunk-GM2PO7LK.mjs.map +1 -0
- package/dist/extensions/index.cjs +430 -273
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +1 -1
- package/dist/extensions/index.d.ts +1 -1
- package/dist/extensions/index.mjs +1 -1
- package/dist/{index--_wwHFvD.d.cts → index-CoaeAnTJ.d.cts} +2 -0
- package/dist/{index--_wwHFvD.d.ts → index-CoaeAnTJ.d.ts} +2 -0
- package/dist/index.cjs +410 -299
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -33
- package/dist/index.d.ts +99 -33
- package/dist/index.mjs +24 -73
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-UAIJTD74.mjs.map +0 -1
|
@@ -452,6 +452,7 @@ function deriveState(state, rawContent, sourceRevision, lineage, savedVersions,
|
|
|
452
452
|
contentId: section.contentId,
|
|
453
453
|
queryType: query?.type,
|
|
454
454
|
queryError: query?.error,
|
|
455
|
+
queryAttributes: query?.attributes,
|
|
455
456
|
embed: section.embed
|
|
456
457
|
};
|
|
457
458
|
});
|
|
@@ -4136,6 +4137,108 @@ function RowsResultsChrome({
|
|
|
4136
4137
|
)
|
|
4137
4138
|
] });
|
|
4138
4139
|
}
|
|
4140
|
+
|
|
4141
|
+
// src/widgets/chartPalette.ts
|
|
4142
|
+
var SERIES_COLORS = [
|
|
4143
|
+
"hsl(var(--metric-time))",
|
|
4144
|
+
"hsl(var(--metric-effort))",
|
|
4145
|
+
"hsl(var(--metric-rep))",
|
|
4146
|
+
"hsl(var(--metric-rounds))",
|
|
4147
|
+
"hsl(var(--metric-distance))",
|
|
4148
|
+
"hsl(var(--metric-resistance))",
|
|
4149
|
+
"hsl(var(--metric-action))",
|
|
4150
|
+
"hsl(var(--primary))"
|
|
4151
|
+
];
|
|
4152
|
+
function createExecutorDocumentHost(executor, range = {}) {
|
|
4153
|
+
return {
|
|
4154
|
+
runAggregate: (queryText, overrides) => executor.runQuery(queryText, {
|
|
4155
|
+
context: overrides.context,
|
|
4156
|
+
rangeStart: range.rangeStart,
|
|
4157
|
+
rangeEnd: range.rangeEnd,
|
|
4158
|
+
preferredUnit: range.preferredUnit
|
|
4159
|
+
}),
|
|
4160
|
+
runFind: async (queryText, context) => {
|
|
4161
|
+
const parsed = wodWikiWql.parseQuery(queryText);
|
|
4162
|
+
if (!wodWikiWql.isFindQuery(parsed)) return { kind: "find", error: `not a content query: ${queryText}` };
|
|
4163
|
+
const res = await executor.runFind(parsed, {
|
|
4164
|
+
context,
|
|
4165
|
+
range: range.rangeStart !== void 0 ? { start: range.rangeStart, end: range.rangeEnd ?? Number.MAX_SAFE_INTEGER, endExclusive: false } : void 0
|
|
4166
|
+
});
|
|
4167
|
+
return {
|
|
4168
|
+
kind: "find",
|
|
4169
|
+
notes: res.notes,
|
|
4170
|
+
blocks: res.blocks,
|
|
4171
|
+
efforts: res.efforts,
|
|
4172
|
+
containers: res.containers,
|
|
4173
|
+
runs: res.runs,
|
|
4174
|
+
table: res.table
|
|
4175
|
+
};
|
|
4176
|
+
},
|
|
4177
|
+
runPipeline: async (queryText, context) => {
|
|
4178
|
+
const res = await executor.runPipeline?.(queryText, {
|
|
4179
|
+
context,
|
|
4180
|
+
rangeStart: range.rangeStart,
|
|
4181
|
+
rangeEnd: range.rangeEnd,
|
|
4182
|
+
preferredUnit: range.preferredUnit
|
|
4183
|
+
});
|
|
4184
|
+
return res ?? { error: "pipeline queries are not supported by this executor" };
|
|
4185
|
+
},
|
|
4186
|
+
rollupEnsure: range.rollupEnsure
|
|
4187
|
+
};
|
|
4188
|
+
}
|
|
4189
|
+
function toChartResult(input) {
|
|
4190
|
+
const parsed = input.parsed;
|
|
4191
|
+
const series = input.series ?? [];
|
|
4192
|
+
const scalar = series.length === 1 && series[0].points.length === 1 ? series[0].points[0].value : void 0;
|
|
4193
|
+
return {
|
|
4194
|
+
parsed,
|
|
4195
|
+
series,
|
|
4196
|
+
stages: { selected: 0, buckets: 0, aggregated: 0, groups: 0 },
|
|
4197
|
+
matched: [],
|
|
4198
|
+
...scalar !== void 0 ? { scalar } : {},
|
|
4199
|
+
...input.unit !== void 0 ? { unit: input.unit } : {},
|
|
4200
|
+
...input.error ? { error: input.error } : {},
|
|
4201
|
+
...input.table ? { table: input.table } : {}
|
|
4202
|
+
};
|
|
4203
|
+
}
|
|
4204
|
+
function outputToRunResult(parsed, out) {
|
|
4205
|
+
const base = toChartResult({
|
|
4206
|
+
parsed,
|
|
4207
|
+
series: out.series,
|
|
4208
|
+
unit: out.unit,
|
|
4209
|
+
error: out.error,
|
|
4210
|
+
table: out.table
|
|
4211
|
+
});
|
|
4212
|
+
return Object.assign(base, {
|
|
4213
|
+
...out.notes ? { notes: out.notes } : {},
|
|
4214
|
+
...out.blocks ? { blocks: out.blocks } : {},
|
|
4215
|
+
...out.efforts ? { efforts: out.efforts } : {},
|
|
4216
|
+
...out.containers ? { containers: out.containers } : {},
|
|
4217
|
+
...out.runs ? { runs: out.runs } : {},
|
|
4218
|
+
...out.chart ? { chart: out.chart } : {}
|
|
4219
|
+
});
|
|
4220
|
+
}
|
|
4221
|
+
function mergeSeries(series) {
|
|
4222
|
+
const map = /* @__PURE__ */ new Map();
|
|
4223
|
+
for (const s of series) {
|
|
4224
|
+
for (const p of s.points) {
|
|
4225
|
+
if (!map.has(p.ts)) map.set(p.ts, { ts: p.ts });
|
|
4226
|
+
map.get(p.ts)[s.label] = p.value;
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
return Array.from(map.values()).sort((a, b) => a.ts - b.ts);
|
|
4230
|
+
}
|
|
4231
|
+
function compactNumber(value) {
|
|
4232
|
+
const n = typeof value === "number" ? value : Number(value);
|
|
4233
|
+
if (Math.abs(n) >= 1e3) return `${(n / 1e3).toFixed(1)}k`;
|
|
4234
|
+
return String(n);
|
|
4235
|
+
}
|
|
4236
|
+
function formatTimestamp(ts) {
|
|
4237
|
+
return new Date(ts).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
4238
|
+
}
|
|
4239
|
+
function tooltipTimestamp(ts) {
|
|
4240
|
+
return new Date(ts).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
4241
|
+
}
|
|
4139
4242
|
function useChartShape(result) {
|
|
4140
4243
|
return React2.useMemo(() => {
|
|
4141
4244
|
if (!result) return { kind: "empty" };
|
|
@@ -4186,53 +4289,6 @@ function QueryValue({ result, unit: unitProp, label, thresholds }) {
|
|
|
4186
4289
|
] })
|
|
4187
4290
|
] });
|
|
4188
4291
|
}
|
|
4189
|
-
|
|
4190
|
-
// src/widgets/chartData.ts
|
|
4191
|
-
function toChartResult(input) {
|
|
4192
|
-
const parsed = input.parsed;
|
|
4193
|
-
return {
|
|
4194
|
-
parsed,
|
|
4195
|
-
series: input.series ?? [],
|
|
4196
|
-
stages: { selected: 0, buckets: 0, aggregated: 0, groups: 0 },
|
|
4197
|
-
matched: [],
|
|
4198
|
-
...input.unit !== void 0 ? { unit: input.unit } : {},
|
|
4199
|
-
...input.error ? { error: input.error } : {},
|
|
4200
|
-
...input.table ? { table: input.table } : {}
|
|
4201
|
-
};
|
|
4202
|
-
}
|
|
4203
|
-
function mergeSeries(series) {
|
|
4204
|
-
const map = /* @__PURE__ */ new Map();
|
|
4205
|
-
for (const s of series) {
|
|
4206
|
-
for (const p of s.points) {
|
|
4207
|
-
if (!map.has(p.ts)) map.set(p.ts, { ts: p.ts });
|
|
4208
|
-
map.get(p.ts)[s.label] = p.value;
|
|
4209
|
-
}
|
|
4210
|
-
}
|
|
4211
|
-
return Array.from(map.values()).sort((a, b) => a.ts - b.ts);
|
|
4212
|
-
}
|
|
4213
|
-
function compactNumber(value) {
|
|
4214
|
-
const n = typeof value === "number" ? value : Number(value);
|
|
4215
|
-
if (Math.abs(n) >= 1e3) return `${(n / 1e3).toFixed(1)}k`;
|
|
4216
|
-
return String(n);
|
|
4217
|
-
}
|
|
4218
|
-
function formatTimestamp(ts) {
|
|
4219
|
-
return new Date(ts).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
4220
|
-
}
|
|
4221
|
-
function tooltipTimestamp(ts) {
|
|
4222
|
-
return new Date(ts).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
4223
|
-
}
|
|
4224
|
-
|
|
4225
|
-
// src/widgets/chartPalette.ts
|
|
4226
|
-
var SERIES_COLORS = [
|
|
4227
|
-
"hsl(var(--metric-time))",
|
|
4228
|
-
"hsl(var(--metric-effort))",
|
|
4229
|
-
"hsl(var(--metric-rep))",
|
|
4230
|
-
"hsl(var(--metric-rounds))",
|
|
4231
|
-
"hsl(var(--metric-distance))",
|
|
4232
|
-
"hsl(var(--metric-resistance))",
|
|
4233
|
-
"hsl(var(--metric-action))",
|
|
4234
|
-
"hsl(var(--primary))"
|
|
4235
|
-
];
|
|
4236
4292
|
function WqlTimeseries({ result, unit: unitProp }) {
|
|
4237
4293
|
const shape = useChartShape(result);
|
|
4238
4294
|
const data2 = React2.useMemo(() => mergeSeries(result.series), [result]);
|
|
@@ -4812,16 +4868,52 @@ function ZoneDistribution({ result, params, attributes }) {
|
|
|
4812
4868
|
}
|
|
4813
4869
|
);
|
|
4814
4870
|
}
|
|
4815
|
-
function
|
|
4871
|
+
function inferChartTypeFromResult(result) {
|
|
4872
|
+
if (!result || result.series.length === 0) return "table";
|
|
4873
|
+
if (result.series.length === 1 && result.series[0].points.length === 1) return "value";
|
|
4874
|
+
const hasTimeAxis = result.series.some((s) => s.points.length > 1);
|
|
4875
|
+
return hasTimeAxis ? "timeseries" : "bar";
|
|
4876
|
+
}
|
|
4877
|
+
function WidgetChart({
|
|
4878
|
+
type,
|
|
4879
|
+
result,
|
|
4880
|
+
label,
|
|
4881
|
+
unit,
|
|
4882
|
+
params,
|
|
4883
|
+
attributes,
|
|
4884
|
+
inferDefaultShape = false,
|
|
4885
|
+
onOpenNote,
|
|
4886
|
+
noteHref
|
|
4887
|
+
}) {
|
|
4816
4888
|
if (type !== "" && !wodWikiWql.isDashboardWidgetType(type)) {
|
|
4817
4889
|
return /* @__PURE__ */ jsxRuntime.jsx(WidgetProblemBadge, { message: wodWikiWql.unknownWidgetTypeMessage(type) });
|
|
4818
4890
|
}
|
|
4819
|
-
const resolved = wodWikiWql.resolveWidgetType(type);
|
|
4820
|
-
|
|
4821
|
-
|
|
4891
|
+
const resolved = type === "" && inferDefaultShape ? inferChartTypeFromResult(result) : wodWikiWql.resolveWidgetType(type);
|
|
4892
|
+
const runResult = result;
|
|
4893
|
+
const parsedFamily = runResult?.parsed?.family;
|
|
4894
|
+
const hasContentItems = parsedFamily === "find" || Boolean(runResult?.notes?.length || runResult?.blocks?.length || runResult?.efforts?.length || runResult?.runs?.length);
|
|
4895
|
+
if (resolved === "table" && runResult?.table) {
|
|
4896
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(TabularTable, { table: runResult.table }) });
|
|
4897
|
+
}
|
|
4898
|
+
if (resolved === "table" && hasContentItems && (!result || !("series" in result) || result.series.length === 0)) {
|
|
4899
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4900
|
+
ContentRecordsTable,
|
|
4901
|
+
{
|
|
4902
|
+
result: runResult,
|
|
4903
|
+
onOpenNote,
|
|
4904
|
+
noteHref
|
|
4905
|
+
}
|
|
4906
|
+
) });
|
|
4822
4907
|
}
|
|
4823
|
-
if (resolved === "list" &&
|
|
4824
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4908
|
+
if (resolved === "list" && hasContentItems) {
|
|
4909
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4910
|
+
ThingList,
|
|
4911
|
+
{
|
|
4912
|
+
result: runResult,
|
|
4913
|
+
onOpenNote,
|
|
4914
|
+
noteHref
|
|
4915
|
+
}
|
|
4916
|
+
) });
|
|
4825
4917
|
}
|
|
4826
4918
|
if (!result || result.parsed.error || "series" in result && result.series.length === 0) {
|
|
4827
4919
|
return /* @__PURE__ */ jsxRuntime.jsx(WqlEmptyState, { result });
|
|
@@ -4935,9 +5027,138 @@ function TabularTable({ table }) {
|
|
|
4935
5027
|
] }, group.key)) : table.rows.map((row, i) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "border-b border-border/40 hover:bg-muted/20", children: table.columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 px-2 whitespace-nowrap", children: String(row[c.name] ?? "") }, c.name)) }, i)) })
|
|
4936
5028
|
] }) });
|
|
4937
5029
|
}
|
|
4938
|
-
function
|
|
4939
|
-
|
|
4940
|
-
|
|
5030
|
+
function containerPageHref(container) {
|
|
5031
|
+
if (!container || container.kind !== "page") return void 0;
|
|
5032
|
+
const { slug, date } = container;
|
|
5033
|
+
if (slug) return `/page/${encodeURIComponent(slug)}`;
|
|
5034
|
+
if (date) return `/day/${encodeURIComponent(date)}`;
|
|
5035
|
+
return void 0;
|
|
5036
|
+
}
|
|
5037
|
+
function formatItemDate(item) {
|
|
5038
|
+
const raw = item.date ?? item.timestamp ?? item.createdAt;
|
|
5039
|
+
if (raw === void 0 || raw === null || raw === "") return "\u2014";
|
|
5040
|
+
if (typeof raw === "string" && /^\d{4}-\d{2}-\d{2}/.test(raw)) return raw.slice(0, 10);
|
|
5041
|
+
const ms = typeof raw === "number" ? raw : Date.parse(String(raw));
|
|
5042
|
+
if (!Number.isFinite(ms) || ms <= 0) return "\u2014";
|
|
5043
|
+
return new Date(ms).toISOString().slice(0, 10);
|
|
5044
|
+
}
|
|
5045
|
+
function ContentRecordsTable({
|
|
5046
|
+
result,
|
|
5047
|
+
onOpenNote,
|
|
5048
|
+
noteHref
|
|
5049
|
+
}) {
|
|
5050
|
+
const parsed = result?.parsed;
|
|
5051
|
+
const target = parsed?.target ?? (parsed?.source?.kind === "query" && parsed?.source?.query?.family === "find" ? parsed.source.query.target ?? "note" : result?.blocks?.length ? "block" : "note");
|
|
5052
|
+
const isBlock = target === "block" || Boolean(result?.blocks?.length && !result?.notes?.length);
|
|
5053
|
+
const rawItems = result?.notes?.length ? result.notes : result?.blocks?.length ? result.blocks : result?.efforts?.length ? result.efforts : result?.runs ?? [];
|
|
5054
|
+
const items = rawItems;
|
|
5055
|
+
if (items.length === 0) {
|
|
5056
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground py-4 text-center", "data-testid": "content-records-table-empty", children: [
|
|
5057
|
+
"No ",
|
|
5058
|
+
target,
|
|
5059
|
+
"s matched this query."
|
|
5060
|
+
] });
|
|
5061
|
+
}
|
|
5062
|
+
const containers = result?.containers;
|
|
5063
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-auto border-y border-border/60 bg-card/40", "data-testid": "content-records-table", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left border-collapse text-xs", children: [
|
|
5064
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b border-border bg-muted/30 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground", children: [
|
|
5065
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "py-2 px-3", children: "Title" }),
|
|
5066
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "py-2 px-3", children: "Kind" }),
|
|
5067
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "py-2 px-3", children: "Tags / Details" }),
|
|
5068
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "py-2 px-3 text-right", children: "Date" })
|
|
5069
|
+
] }) }),
|
|
5070
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-border/40", children: items.map((item, i) => {
|
|
5071
|
+
const id = item.id ?? item.resultId ?? String(i);
|
|
5072
|
+
const typedItem = { ...item, id, title: item.title ?? item.label ?? item.noteTitle };
|
|
5073
|
+
const title = isBlock ? typedItem.title || typedItem.blockContentId || id : typedItem.title || id;
|
|
5074
|
+
const href = containers ? containerPageHref(containers[id]) ?? (noteHref ? noteHref(typedItem) : void 0) : noteHref ? noteHref(typedItem) : void 0;
|
|
5075
|
+
const kindLabel = item.type ?? item.dataType ?? item.baseAttributes?.discipline ?? target;
|
|
5076
|
+
const detail = Array.isArray(item.tags) && item.tags.length > 0 ? item.tags.map((t) => `#${t}`).join(" ") : item.baseAttributes?.met ? `MET ${item.baseAttributes.met}` : item.sourceId ?? "\u2014";
|
|
5077
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "hover:bg-muted/30 transition-colors", children: [
|
|
5078
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-2 px-3 font-medium truncate max-w-[260px]", children: href ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5079
|
+
"a",
|
|
5080
|
+
{
|
|
5081
|
+
href,
|
|
5082
|
+
onClick: (e) => {
|
|
5083
|
+
if (onOpenNote) {
|
|
5084
|
+
e.preventDefault();
|
|
5085
|
+
onOpenNote(typedItem);
|
|
5086
|
+
}
|
|
5087
|
+
},
|
|
5088
|
+
className: "text-primary hover:underline",
|
|
5089
|
+
children: title
|
|
5090
|
+
}
|
|
5091
|
+
) : onOpenNote ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5092
|
+
"button",
|
|
5093
|
+
{
|
|
5094
|
+
type: "button",
|
|
5095
|
+
onClick: () => onOpenNote(typedItem),
|
|
5096
|
+
className: "text-left text-primary hover:underline",
|
|
5097
|
+
children: title
|
|
5098
|
+
}
|
|
5099
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground", children: title }) }),
|
|
5100
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-2 px-3 font-mono text-[11px] text-muted-foreground", children: kindLabel }),
|
|
5101
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-2 px-3 font-mono text-[11px] text-muted-foreground truncate max-w-[200px]", children: detail }),
|
|
5102
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-2 px-3 font-mono text-[11px] text-muted-foreground text-right tabular-nums", children: formatItemDate(item) })
|
|
5103
|
+
] }, id);
|
|
5104
|
+
}) })
|
|
5105
|
+
] }) });
|
|
5106
|
+
}
|
|
5107
|
+
function ThingList({
|
|
5108
|
+
result,
|
|
5109
|
+
onOpenNote,
|
|
5110
|
+
noteHref
|
|
5111
|
+
}) {
|
|
5112
|
+
const parsed = result?.parsed;
|
|
5113
|
+
const target = parsed?.target ?? (parsed?.source?.kind === "query" && parsed?.source?.query?.family === "find" ? parsed.source.query.target ?? "note" : result?.blocks?.length ? "block" : "note");
|
|
5114
|
+
const isBlock = target === "block" || Boolean(result?.blocks?.length && !result?.notes?.length);
|
|
5115
|
+
const rawItems = result?.notes?.length ? result.notes : result?.blocks?.length ? result.blocks : result?.efforts?.length ? result.efforts : result?.runs ?? [];
|
|
5116
|
+
const items = rawItems;
|
|
5117
|
+
if (items.length === 0) {
|
|
5118
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground py-2", "data-testid": "thing-list", children: [
|
|
5119
|
+
"No ",
|
|
5120
|
+
target,
|
|
5121
|
+
"s matched this query."
|
|
5122
|
+
] });
|
|
5123
|
+
}
|
|
5124
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full overflow-auto space-y-1", "data-testid": "thing-list", children: [
|
|
5125
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[11px] font-medium text-muted-foreground mb-1", children: [
|
|
5126
|
+
items.length,
|
|
5127
|
+
" ",
|
|
5128
|
+
target,
|
|
5129
|
+
items.length === 1 ? "" : "s",
|
|
5130
|
+
" matched"
|
|
5131
|
+
] }),
|
|
5132
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-0.5 max-h-48 overflow-y-auto font-mono text-xs", children: items.map((item, i) => {
|
|
5133
|
+
const id = item.id ?? item.resultId ?? String(i);
|
|
5134
|
+
const typedItem = { ...item, id, title: item.title ?? item.label ?? item.noteTitle };
|
|
5135
|
+
const title = isBlock ? typedItem.title || typedItem.blockContentId || id : typedItem.title || id;
|
|
5136
|
+
const containers = result?.containers;
|
|
5137
|
+
const href = containers ? containerPageHref(containers[id]) ?? (noteHref ? noteHref(typedItem) : void 0) : noteHref ? noteHref(typedItem) : void 0;
|
|
5138
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { className: "rounded hover:bg-muted/50 truncate", children: href ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5139
|
+
"a",
|
|
5140
|
+
{
|
|
5141
|
+
href,
|
|
5142
|
+
onClick: (e) => {
|
|
5143
|
+
if (onOpenNote) {
|
|
5144
|
+
e.preventDefault();
|
|
5145
|
+
onOpenNote(typedItem);
|
|
5146
|
+
}
|
|
5147
|
+
},
|
|
5148
|
+
className: "block py-0.5 px-1.5 text-primary hover:underline truncate",
|
|
5149
|
+
children: title
|
|
5150
|
+
}
|
|
5151
|
+
) : onOpenNote ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5152
|
+
"button",
|
|
5153
|
+
{
|
|
5154
|
+
type: "button",
|
|
5155
|
+
onClick: () => onOpenNote(typedItem),
|
|
5156
|
+
className: "w-full text-left py-0.5 px-1.5 text-primary hover:underline truncate",
|
|
5157
|
+
children: title
|
|
5158
|
+
}
|
|
5159
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block py-0.5 px-1.5 text-foreground truncate", children: title }) }, id);
|
|
5160
|
+
}) })
|
|
5161
|
+
] });
|
|
4941
5162
|
}
|
|
4942
5163
|
|
|
4943
5164
|
// src/utils/blockQueryPatcher.ts
|
|
@@ -7186,21 +7407,31 @@ function QueryBlockView({
|
|
|
7186
7407
|
widgetError,
|
|
7187
7408
|
tokenValues,
|
|
7188
7409
|
attributes,
|
|
7410
|
+
onAddToDashboard,
|
|
7189
7411
|
onCaptureRpe,
|
|
7190
7412
|
onOpenNote,
|
|
7191
7413
|
noteHref
|
|
7192
7414
|
}) {
|
|
7193
7415
|
const [isModalOpen, setIsModalOpen] = React2.useState(false);
|
|
7194
7416
|
const extracted = React2.useMemo(() => extractBlockQueries(query), [query]);
|
|
7417
|
+
const rawBody = React2.useMemo(() => {
|
|
7418
|
+
const trimmed = query.trim();
|
|
7419
|
+
if (trimmed.includes("\n")) {
|
|
7420
|
+
const docParsed = wodWikiWql.parseDocument(trimmed);
|
|
7421
|
+
if (!docParsed.doc.degenerate && docParsed.diagnostics.length === 0 && docParsed.doc.assignments.length > 0) {
|
|
7422
|
+
return trimmed;
|
|
7423
|
+
}
|
|
7424
|
+
}
|
|
7425
|
+
return extracted.length > 0 ? extracted[0].query : query;
|
|
7426
|
+
}, [extracted, query]);
|
|
7195
7427
|
const { query: effectiveQuery, missing } = React2.useMemo(() => {
|
|
7196
|
-
const
|
|
7197
|
-
const subQuery = wodWikiWql.substituteTokens(raw, tokenValues ?? {});
|
|
7428
|
+
const subQuery = wodWikiWql.substituteTokens(rawBody, tokenValues ?? {});
|
|
7198
7429
|
const missingSet = new Set(subQuery.missing);
|
|
7199
7430
|
for (const value of Object.values(attributes ?? {})) {
|
|
7200
7431
|
for (const m of wodWikiWql.substituteTokens(value, tokenValues ?? {}).missing) missingSet.add(m);
|
|
7201
7432
|
}
|
|
7202
7433
|
return { query: subQuery.query, missing: [...missingSet] };
|
|
7203
|
-
}, [
|
|
7434
|
+
}, [rawBody, tokenValues, attributes]);
|
|
7204
7435
|
const resolvedAttributes = React2.useMemo(() => {
|
|
7205
7436
|
const out = {};
|
|
7206
7437
|
for (const [key, value] of Object.entries(attributes ?? {})) {
|
|
@@ -7208,11 +7439,12 @@ function QueryBlockView({
|
|
|
7208
7439
|
}
|
|
7209
7440
|
return out;
|
|
7210
7441
|
}, [attributes, tokenValues]);
|
|
7442
|
+
const docParse = React2.useMemo(() => wodWikiWql.parseDocument(effectiveQuery), [effectiveQuery]);
|
|
7443
|
+
const isMultiLineDoc = !docParse.doc.degenerate && docParse.doc.assignments.length > 0;
|
|
7211
7444
|
const parsed = React2.useMemo(() => wodWikiWql.parseQuery(effectiveQuery), [effectiveQuery]);
|
|
7445
|
+
const syntaxError = isMultiLineDoc ? docParse.diagnostics[0] : parsed.error;
|
|
7212
7446
|
const unknownType = widgetType != null && widgetType !== "" && !wodWikiWql.isDashboardWidgetType(widgetType);
|
|
7213
|
-
const [
|
|
7214
|
-
const [findResult, setFindResult] = React2.useState(void 0);
|
|
7215
|
-
const [pipelineResult, setPipelineResult] = React2.useState(void 0);
|
|
7447
|
+
const [runResult, setRunResult] = React2.useState(void 0);
|
|
7216
7448
|
const [runError, setRunError] = React2.useState(void 0);
|
|
7217
7449
|
const [rowsRefreshKey, setRowsRefreshKey] = React2.useState(0);
|
|
7218
7450
|
React2.useEffect(() => {
|
|
@@ -7227,59 +7459,45 @@ function QueryBlockView({
|
|
|
7227
7459
|
}, [onResultSaved]);
|
|
7228
7460
|
React2.useEffect(() => {
|
|
7229
7461
|
let cancelled = false;
|
|
7462
|
+
let retryTimer;
|
|
7230
7463
|
setRunError(void 0);
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
};
|
|
7259
|
-
}
|
|
7260
|
-
if (wodWikiWql.isPipelineQuery(parsed)) {
|
|
7261
|
-
if (!executor.runPipeline) {
|
|
7262
|
-
setRunError("pipeline queries are not supported by this executor");
|
|
7263
|
-
return;
|
|
7264
|
-
}
|
|
7265
|
-
void executor.runPipeline(effectiveQuery).then((res) => {
|
|
7266
|
-
if (!cancelled) setPipelineResult(res);
|
|
7464
|
+
setRunResult(void 0);
|
|
7465
|
+
if (syntaxError || widgetError || unknownType || missing.length > 0 || !executor) return;
|
|
7466
|
+
const isSessionFind = !isMultiLineDoc && wodWikiWql.isFindQuery(parsed) && parsed.target === "session";
|
|
7467
|
+
const host = createExecutorDocumentHost(executor);
|
|
7468
|
+
const executeRun = (attemptCount) => {
|
|
7469
|
+
const runner = new wodWikiWql.SharedQueryDocumentRunner(host);
|
|
7470
|
+
void runner.run(effectiveQuery).then((res) => {
|
|
7471
|
+
if (cancelled) return;
|
|
7472
|
+
const out = res.outputs[0];
|
|
7473
|
+
if (!out) {
|
|
7474
|
+
setRunError(res.diagnostics[0] ?? "widget produced no output");
|
|
7475
|
+
return;
|
|
7476
|
+
}
|
|
7477
|
+
const err = out.error ?? res.diagnostics[0];
|
|
7478
|
+
if (err) {
|
|
7479
|
+
setRunError(err);
|
|
7480
|
+
return;
|
|
7481
|
+
}
|
|
7482
|
+
const effectiveParsed = isMultiLineDoc ? out.kind === "find" ? { family: "find", raw: effectiveQuery, target: "note", filters: [] } : { family: "aggregate", raw: effectiveQuery, agg: "sum", metric: out.name, filters: [], groupBy: out.groupBy ?? [] } : parsed;
|
|
7483
|
+
const shaped = outputToRunResult(effectiveParsed, out);
|
|
7484
|
+
setRunResult(shaped);
|
|
7485
|
+
if (isSessionFind && (shaped.runs ?? []).length === 0 && attemptCount < 4) {
|
|
7486
|
+
const delays = [50, 150, 350, 750];
|
|
7487
|
+
retryTimer = setTimeout(() => {
|
|
7488
|
+
if (!cancelled) executeRun(attemptCount + 1);
|
|
7489
|
+
}, delays[attemptCount] ?? 500);
|
|
7490
|
+
}
|
|
7267
7491
|
}).catch((err) => {
|
|
7268
7492
|
if (!cancelled) setRunError(err instanceof Error ? err.message : String(err));
|
|
7269
7493
|
});
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
};
|
|
7273
|
-
}
|
|
7274
|
-
void executor.runQuery(effectiveQuery).then((res) => {
|
|
7275
|
-
if (!cancelled) setResult(res);
|
|
7276
|
-
}).catch((err) => {
|
|
7277
|
-
if (!cancelled) setRunError(err instanceof Error ? err.message : String(err));
|
|
7278
|
-
});
|
|
7494
|
+
};
|
|
7495
|
+
executeRun(0);
|
|
7279
7496
|
return () => {
|
|
7280
7497
|
cancelled = true;
|
|
7498
|
+
clearTimeout(retryTimer);
|
|
7281
7499
|
};
|
|
7282
|
-
}, [effectiveQuery, parsed, widgetError, unknownType, missing, executor, rowsRefreshKey]);
|
|
7500
|
+
}, [effectiveQuery, parsed, isMultiLineDoc, syntaxError, widgetError, unknownType, missing, executor, rowsRefreshKey]);
|
|
7283
7501
|
const canEdit = onSaveQuery !== void 0 && !readOnly;
|
|
7284
7502
|
const onEdit = canEdit ? () => setIsModalOpen(true) : void 0;
|
|
7285
7503
|
const resultId = React2.useMemo(() => {
|
|
@@ -7287,50 +7505,32 @@ function QueryBlockView({
|
|
|
7287
7505
|
const resultFilter = parsed.filters.find((f) => f.key === "result");
|
|
7288
7506
|
return resultFilter?.values[0]?.value;
|
|
7289
7507
|
}, [parsed]);
|
|
7508
|
+
const fallbackLabel = React2.useMemo(() => {
|
|
7509
|
+
if (!wodWikiWql.isFindQuery(parsed) && !wodWikiWql.isPipelineQuery(parsed)) return parsed.metric;
|
|
7510
|
+
return parsed.raw;
|
|
7511
|
+
}, [parsed]);
|
|
7290
7512
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": "query-block-view", children: [
|
|
7291
|
-
widgetError ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-destructive bg-destructive/10 border border-destructive/20 rounded p-2", children: widgetError }) }) : unknownType ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, children: /* @__PURE__ */ jsxRuntime.jsx(WidgetProblemBadge, { message: wodWikiWql.unknownWidgetTypeMessage(widgetType) }) }) : missing.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, children: /* @__PURE__ */ jsxRuntime.jsx(WidgetProblemBadge, { message: wodWikiWql.unknownTokensMessage(missing) }) }) :
|
|
7513
|
+
widgetError ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, onAddToDashboard, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-destructive bg-destructive/10 border border-destructive/20 rounded p-2", children: widgetError }) }) : unknownType ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, onAddToDashboard, children: /* @__PURE__ */ jsxRuntime.jsx(WidgetProblemBadge, { message: wodWikiWql.unknownWidgetTypeMessage(widgetType) }) }) : missing.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, onAddToDashboard, children: /* @__PURE__ */ jsxRuntime.jsx(WidgetProblemBadge, { message: wodWikiWql.unknownTokensMessage(missing) }) }) : syntaxError ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, onAddToDashboard, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-destructive bg-destructive/10 border border-destructive/20 rounded p-2", children: [
|
|
7292
7514
|
"Query syntax error: ",
|
|
7293
|
-
|
|
7294
|
-
] }) }) : runError ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-destructive bg-destructive/10 border border-destructive/20 rounded p-2", children: [
|
|
7515
|
+
syntaxError
|
|
7516
|
+
] }) }) : runError ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, onAddToDashboard, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-destructive bg-destructive/10 border border-destructive/20 rounded p-2", children: [
|
|
7295
7517
|
"Query execution error: ",
|
|
7296
7518
|
runError
|
|
7297
|
-
] }) }) :
|
|
7298
|
-
|
|
7519
|
+
] }) }) : /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, onAddToDashboard, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7520
|
+
QueryBlockBody,
|
|
7299
7521
|
{
|
|
7522
|
+
parsed,
|
|
7523
|
+
result: runResult,
|
|
7300
7524
|
resultId,
|
|
7301
|
-
|
|
7525
|
+
widgetType,
|
|
7526
|
+
attributes: resolvedAttributes,
|
|
7527
|
+
fallbackLabel,
|
|
7302
7528
|
executor,
|
|
7303
7529
|
onCaptureRpe,
|
|
7304
|
-
onCaptured: () => setRowsRefreshKey((k) => k + 1)
|
|
7305
|
-
}
|
|
7306
|
-
) : findResult?.runs ? /* @__PURE__ */ jsxRuntime.jsx(RowsTable, { result: findResult }) : findResult ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
7307
|
-
FindResultList,
|
|
7308
|
-
{
|
|
7309
|
-
target: parsed.target,
|
|
7310
|
-
notes: findResult.notes,
|
|
7311
|
-
blocks: findResult.blocks,
|
|
7312
|
-
containers: findResult.containers,
|
|
7530
|
+
onCaptured: () => setRowsRefreshKey((k) => k + 1),
|
|
7313
7531
|
onOpenNote,
|
|
7314
7532
|
noteHref
|
|
7315
7533
|
}
|
|
7316
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground py-2", children: "Loading rows\u2026" }) }) : wodWikiWql.isPipelineQuery(parsed) ? /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7317
|
-
PipelineResultView,
|
|
7318
|
-
{
|
|
7319
|
-
result: pipelineResult,
|
|
7320
|
-
onOpenNote,
|
|
7321
|
-
noteHref,
|
|
7322
|
-
widgetType,
|
|
7323
|
-
attributes: resolvedAttributes,
|
|
7324
|
-
fallbackLabel: parsed.raw
|
|
7325
|
-
}
|
|
7326
|
-
) }) : /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7327
|
-
AnalyticsChart,
|
|
7328
|
-
{
|
|
7329
|
-
result,
|
|
7330
|
-
metric: parsed.metric,
|
|
7331
|
-
widgetType,
|
|
7332
|
-
attributes: resolvedAttributes
|
|
7333
|
-
}
|
|
7334
7534
|
) }),
|
|
7335
7535
|
canEdit && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7336
7536
|
WqlQueryInspectorModal,
|
|
@@ -7344,179 +7544,127 @@ function QueryBlockView({
|
|
|
7344
7544
|
)
|
|
7345
7545
|
] });
|
|
7346
7546
|
}
|
|
7347
|
-
function
|
|
7547
|
+
function QueryBlockBody({
|
|
7548
|
+
parsed,
|
|
7348
7549
|
result,
|
|
7349
|
-
|
|
7550
|
+
resultId,
|
|
7350
7551
|
widgetType,
|
|
7351
|
-
attributes
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
}
|
|
7357
|
-
if (shape.kind === "scalar") {
|
|
7358
|
-
return /* @__PURE__ */ jsxRuntime.jsx(QueryValue, { result, label: metric });
|
|
7359
|
-
}
|
|
7360
|
-
if (shape.kind === "timeseries") {
|
|
7361
|
-
return /* @__PURE__ */ jsxRuntime.jsx(WqlTimeseries, { result });
|
|
7362
|
-
}
|
|
7363
|
-
if (shape.kind === "bars") {
|
|
7364
|
-
return /* @__PURE__ */ jsxRuntime.jsx(WqlBars, { result });
|
|
7365
|
-
}
|
|
7366
|
-
return /* @__PURE__ */ jsxRuntime.jsx(WqlEmptyState, { result });
|
|
7367
|
-
}
|
|
7368
|
-
function containerPageHref(container) {
|
|
7369
|
-
if (!container || container.kind !== "page") return void 0;
|
|
7370
|
-
const { slug, date } = container;
|
|
7371
|
-
if (slug) return `/page/${encodeURIComponent(slug)}`;
|
|
7372
|
-
if (date) return `/day/${encodeURIComponent(date)}`;
|
|
7373
|
-
return void 0;
|
|
7374
|
-
}
|
|
7375
|
-
function FindResultList({
|
|
7376
|
-
target,
|
|
7377
|
-
notes,
|
|
7378
|
-
blocks,
|
|
7379
|
-
containers,
|
|
7552
|
+
attributes,
|
|
7553
|
+
fallbackLabel,
|
|
7554
|
+
executor,
|
|
7555
|
+
onCaptureRpe,
|
|
7556
|
+
onCaptured,
|
|
7380
7557
|
onOpenNote,
|
|
7381
7558
|
noteHref
|
|
7382
|
-
}) {
|
|
7383
|
-
const isBlock = target === "block";
|
|
7384
|
-
const items = isBlock ? blocks : notes;
|
|
7385
|
-
if (items.length === 0) {
|
|
7386
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground py-2", children: [
|
|
7387
|
-
"No ",
|
|
7388
|
-
target,
|
|
7389
|
-
"s matched this query."
|
|
7390
|
-
] });
|
|
7391
|
-
}
|
|
7392
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
7393
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[11px] font-medium text-muted-foreground mb-1", children: [
|
|
7394
|
-
items.length,
|
|
7395
|
-
" ",
|
|
7396
|
-
target,
|
|
7397
|
-
items.length === 1 ? "" : "s",
|
|
7398
|
-
" matched"
|
|
7399
|
-
] }),
|
|
7400
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-0.5 max-h-48 overflow-y-auto font-mono text-xs", children: items.map((item) => {
|
|
7401
|
-
const typedItem = item;
|
|
7402
|
-
const title = isBlock ? typedItem.title || typedItem.blockContentId || item.id : typedItem.title || item.id;
|
|
7403
|
-
const href = containers ? containerPageHref(containers[item.id]) ?? (noteHref ? noteHref(typedItem) : void 0) : noteHref ? noteHref(typedItem) : void 0;
|
|
7404
|
-
return /* @__PURE__ */ jsxRuntime.jsx("li", { className: "rounded hover:bg-muted/50 truncate", children: href ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
7405
|
-
"a",
|
|
7406
|
-
{
|
|
7407
|
-
href,
|
|
7408
|
-
onClick: (e) => {
|
|
7409
|
-
if (onOpenNote) {
|
|
7410
|
-
e.preventDefault();
|
|
7411
|
-
onOpenNote(typedItem);
|
|
7412
|
-
}
|
|
7413
|
-
},
|
|
7414
|
-
className: "block py-0.5 px-1.5 text-primary hover:underline truncate",
|
|
7415
|
-
children: title
|
|
7416
|
-
}
|
|
7417
|
-
) : onOpenNote ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
7418
|
-
"button",
|
|
7419
|
-
{
|
|
7420
|
-
type: "button",
|
|
7421
|
-
onClick: () => onOpenNote(typedItem),
|
|
7422
|
-
className: "w-full text-left py-0.5 px-1.5 text-primary hover:underline truncate",
|
|
7423
|
-
children: title
|
|
7424
|
-
}
|
|
7425
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block py-0.5 px-1.5 text-foreground truncate", children: title }) }, item.id);
|
|
7426
|
-
}) })
|
|
7427
|
-
] });
|
|
7428
|
-
}
|
|
7429
|
-
function PipelineResultView({
|
|
7430
|
-
result,
|
|
7431
|
-
onOpenNote,
|
|
7432
|
-
noteHref,
|
|
7433
|
-
widgetType,
|
|
7434
|
-
attributes,
|
|
7435
|
-
fallbackLabel
|
|
7436
7559
|
}) {
|
|
7437
7560
|
if (!result) {
|
|
7438
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground py-2", children: "Loading\u2026" });
|
|
7561
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground py-2", children: wodWikiWql.isFindQuery(parsed) ? "Loading rows\u2026" : "Loading\u2026" });
|
|
7439
7562
|
}
|
|
7440
|
-
if (result.
|
|
7441
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
7442
|
-
"Query execution error: ",
|
|
7443
|
-
result.error
|
|
7444
|
-
] });
|
|
7563
|
+
if (result.table && (widgetType == null || widgetType === "" || widgetType === "table")) {
|
|
7564
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WidgetChart, { type: "table", result });
|
|
7445
7565
|
}
|
|
7446
|
-
|
|
7447
|
-
if ((result.notes?.length ?? 0) + (result.blocks?.length ?? 0) > 0) {
|
|
7566
|
+
if (resultId && result.runs && result.runs.length > 0) {
|
|
7448
7567
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7449
|
-
|
|
7568
|
+
RowsResultsChrome,
|
|
7450
7569
|
{
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
noteHref
|
|
7570
|
+
resultId,
|
|
7571
|
+
sessionResult: result,
|
|
7572
|
+
executor,
|
|
7573
|
+
onCaptureRpe,
|
|
7574
|
+
onCaptured
|
|
7457
7575
|
}
|
|
7458
7576
|
);
|
|
7459
7577
|
}
|
|
7460
|
-
if (result.runs && result.runs.length > 0) {
|
|
7461
|
-
|
|
7462
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RowsTable, { result: rowsResult });
|
|
7578
|
+
if (result.runs && (wodWikiWql.isFindQuery(parsed) || result.runs.length > 0)) {
|
|
7579
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RowsTable, { result });
|
|
7463
7580
|
}
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
const sinkAttributes = Object.fromEntries(
|
|
7467
|
-
(result.chart?.filters ?? []).map((f) => [f.key, f.values.map((v) => v.value).join(",")])
|
|
7468
|
-
);
|
|
7469
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-[220px] min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7581
|
+
if (wodWikiWql.isFindQuery(parsed) || (result.notes?.length ?? 0) + (result.blocks?.length ?? 0) + (result.efforts?.length ?? 0) > 0 && (!result.series || result.series.length === 0)) {
|
|
7582
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7470
7583
|
WidgetChart,
|
|
7471
7584
|
{
|
|
7472
|
-
type:
|
|
7473
|
-
result
|
|
7474
|
-
|
|
7475
|
-
|
|
7585
|
+
type: "list",
|
|
7586
|
+
result,
|
|
7587
|
+
onOpenNote,
|
|
7588
|
+
noteHref
|
|
7476
7589
|
}
|
|
7477
|
-
)
|
|
7478
|
-
}
|
|
7479
|
-
if (result.series && result.series.length > 0) {
|
|
7480
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-[220px] min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(AnalyticsChart, { result: toChartResult(result), metric: fallbackLabel }) });
|
|
7590
|
+
);
|
|
7481
7591
|
}
|
|
7482
|
-
|
|
7592
|
+
const sinkHead = result.chart?.head;
|
|
7593
|
+
const effectiveType = widgetType != null && widgetType !== "" ? widgetType : sinkHead ?? "";
|
|
7594
|
+
const sinkAttributes = Object.fromEntries(
|
|
7595
|
+
(result.chart?.filters ?? []).map((f) => [f.key, f.values.map((v) => v.value).join(",")])
|
|
7596
|
+
);
|
|
7597
|
+
const mergedAttributes = { ...sinkAttributes, ...attributes };
|
|
7598
|
+
const needsChartHeight = wodWikiWql.isPipelineQuery(parsed) && (Boolean(effectiveType) || (result.series?.length ?? 0) > 0);
|
|
7599
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: needsChartHeight ? "w-full h-[220px] min-h-[160px]" : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7600
|
+
WidgetChart,
|
|
7601
|
+
{
|
|
7602
|
+
type: effectiveType,
|
|
7603
|
+
result,
|
|
7604
|
+
label: fallbackLabel,
|
|
7605
|
+
attributes: mergedAttributes,
|
|
7606
|
+
inferDefaultShape: effectiveType === "",
|
|
7607
|
+
onOpenNote,
|
|
7608
|
+
noteHref
|
|
7609
|
+
}
|
|
7610
|
+
) });
|
|
7483
7611
|
}
|
|
7484
7612
|
function QueryBlockShell({
|
|
7485
7613
|
children,
|
|
7486
7614
|
onEdit,
|
|
7487
|
-
readOnly
|
|
7615
|
+
readOnly,
|
|
7616
|
+
onAddToDashboard
|
|
7488
7617
|
}) {
|
|
7489
7618
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group/block my-2 p-3 rounded-lg border border-border/80 bg-card/60 shadow-sm", children: [
|
|
7490
|
-
onEdit && !readOnly && /* @__PURE__ */ jsxRuntime.
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7619
|
+
(onAddToDashboard || onEdit && !readOnly) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-2 right-2 z-10 flex items-center gap-1", children: [
|
|
7620
|
+
onAddToDashboard && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7621
|
+
"button",
|
|
7622
|
+
{
|
|
7623
|
+
type: "button",
|
|
7624
|
+
onClick: onAddToDashboard,
|
|
7625
|
+
"aria-label": "Add to dashboard",
|
|
7626
|
+
title: "Add to dashboard",
|
|
7627
|
+
"data-testid": "query-add-dashboard",
|
|
7628
|
+
className: "p-1 rounded bg-muted/80 text-muted-foreground hover:text-foreground",
|
|
7629
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChartBar, { className: "w-3.5 h-3.5" })
|
|
7630
|
+
}
|
|
7631
|
+
),
|
|
7632
|
+
onEdit && !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7633
|
+
"button",
|
|
7634
|
+
{
|
|
7635
|
+
type: "button",
|
|
7636
|
+
onClick: onEdit,
|
|
7637
|
+
"aria-label": "Edit query in Omni-Composer",
|
|
7638
|
+
title: "Edit query in Omni-Composer",
|
|
7639
|
+
className: "p-1 rounded bg-muted/80 text-muted-foreground hover:text-foreground opacity-0 group-hover/block:opacity-100 focus-visible:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity",
|
|
7640
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Edit3, { className: "w-3.5 h-3.5" })
|
|
7641
|
+
}
|
|
7642
|
+
)
|
|
7643
|
+
] }),
|
|
7500
7644
|
children
|
|
7501
7645
|
] });
|
|
7502
7646
|
}
|
|
7503
7647
|
var ReactQueryBlock = class extends view.WidgetType {
|
|
7504
|
-
constructor(queryText, sectionId, widgetType, widgetError, options) {
|
|
7648
|
+
constructor(queryText, sectionId, widgetType, widgetError, attributes, tokenValues, options) {
|
|
7505
7649
|
super();
|
|
7506
7650
|
this.queryText = queryText;
|
|
7507
7651
|
this.sectionId = sectionId;
|
|
7508
7652
|
this.widgetType = widgetType;
|
|
7509
7653
|
this.widgetError = widgetError;
|
|
7654
|
+
this.attributes = attributes;
|
|
7655
|
+
this.tokenValues = tokenValues;
|
|
7510
7656
|
this.options = options;
|
|
7511
7657
|
}
|
|
7512
7658
|
queryText;
|
|
7513
7659
|
sectionId;
|
|
7514
7660
|
widgetType;
|
|
7515
7661
|
widgetError;
|
|
7662
|
+
attributes;
|
|
7663
|
+
tokenValues;
|
|
7516
7664
|
options;
|
|
7517
7665
|
root = null;
|
|
7518
7666
|
eq(other) {
|
|
7519
|
-
return this.queryText === other.queryText && this.sectionId === other.sectionId && this.widgetType === other.widgetType && this.widgetError === other.widgetError && this.options?.readOnly === other.options?.readOnly && this.options?.executor === other.options?.executor && this.options?.onOpenNote === other.options?.onOpenNote && this.options?.noteHref === other.options?.noteHref;
|
|
7667
|
+
return this.queryText === other.queryText && this.sectionId === other.sectionId && this.widgetType === other.widgetType && this.widgetError === other.widgetError && JSON.stringify(this.attributes ?? {}) === JSON.stringify(other.attributes ?? {}) && JSON.stringify(this.tokenValues ?? {}) === JSON.stringify(other.tokenValues ?? {}) && this.options?.readOnly === other.options?.readOnly && this.options?.executor === other.options?.executor && this.options?.onOpenNote === other.options?.onOpenNote && this.options?.noteHref === other.options?.noteHref;
|
|
7520
7668
|
}
|
|
7521
7669
|
toDOM(view) {
|
|
7522
7670
|
const container = document.createElement("div");
|
|
@@ -7537,6 +7685,8 @@ var ReactQueryBlock = class extends view.WidgetType {
|
|
|
7537
7685
|
query: this.queryText,
|
|
7538
7686
|
widgetType: this.widgetType,
|
|
7539
7687
|
widgetError: this.widgetError,
|
|
7688
|
+
attributes: this.attributes,
|
|
7689
|
+
tokenValues: this.tokenValues,
|
|
7540
7690
|
readOnly: this.options?.readOnly,
|
|
7541
7691
|
executor: this.options?.executor,
|
|
7542
7692
|
onResultSaved: this.options?.onResultSaved,
|
|
@@ -7564,6 +7714,8 @@ var ReactQueryBlock = class extends view.WidgetType {
|
|
|
7564
7714
|
query: this.queryText,
|
|
7565
7715
|
widgetType: this.widgetType,
|
|
7566
7716
|
widgetError: this.widgetError,
|
|
7717
|
+
attributes: this.attributes,
|
|
7718
|
+
tokenValues: this.tokenValues,
|
|
7567
7719
|
readOnly: this.options?.readOnly,
|
|
7568
7720
|
executor: this.options?.executor,
|
|
7569
7721
|
onResultSaved: this.options?.onResultSaved,
|
|
@@ -7591,8 +7743,11 @@ var ReactQueryBlock = class extends view.WidgetType {
|
|
|
7591
7743
|
};
|
|
7592
7744
|
function buildQueryBlockDecos(state$1, options) {
|
|
7593
7745
|
const builder = new state.RangeSetBuilder();
|
|
7594
|
-
const { sections } = state$1.field(sectionField);
|
|
7746
|
+
const { sections, rawContent: fullRawContent } = state$1.field(sectionField);
|
|
7595
7747
|
const cursor2 = state$1.selection.main.head;
|
|
7748
|
+
const fmMeta = wodWikiCore.parseFrontmatter(fullRawContent).meta;
|
|
7749
|
+
const fmTokens = wodWikiWql.defaultTokenValues(wodWikiWql.extractDashboardTokens(fmMeta));
|
|
7750
|
+
const mergedTokens = { ...fmTokens, ...options?.tokenValues };
|
|
7596
7751
|
for (const section of sections) {
|
|
7597
7752
|
if (section.type !== "query") continue;
|
|
7598
7753
|
if (cursor2 >= section.from && cursor2 <= section.to) continue;
|
|
@@ -7607,6 +7762,8 @@ function buildQueryBlockDecos(state$1, options) {
|
|
|
7607
7762
|
section.id,
|
|
7608
7763
|
section.queryType,
|
|
7609
7764
|
section.queryError,
|
|
7765
|
+
section.queryAttributes,
|
|
7766
|
+
mergedTokens,
|
|
7610
7767
|
options
|
|
7611
7768
|
),
|
|
7612
7769
|
block: true
|