@bitcobblers/wod-wiki-ui 0.50.2188 → 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
package/dist/index.cjs
CHANGED
|
@@ -204,20 +204,75 @@ function QueryValue({ result, unit: unitProp, label, thresholds }) {
|
|
|
204
204
|
] })
|
|
205
205
|
] });
|
|
206
206
|
}
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
function createExecutorDocumentHost(executor, range = {}) {
|
|
208
|
+
return {
|
|
209
|
+
runAggregate: (queryText, overrides) => executor.runQuery(queryText, {
|
|
210
|
+
context: overrides.context,
|
|
211
|
+
rangeStart: range.rangeStart,
|
|
212
|
+
rangeEnd: range.rangeEnd,
|
|
213
|
+
preferredUnit: range.preferredUnit
|
|
214
|
+
}),
|
|
215
|
+
runFind: async (queryText, context) => {
|
|
216
|
+
const parsed = wodWikiWql.parseQuery(queryText);
|
|
217
|
+
if (!wodWikiWql.isFindQuery(parsed)) return { kind: "find", error: `not a content query: ${queryText}` };
|
|
218
|
+
const res = await executor.runFind(parsed, {
|
|
219
|
+
context,
|
|
220
|
+
range: range.rangeStart !== void 0 ? { start: range.rangeStart, end: range.rangeEnd ?? Number.MAX_SAFE_INTEGER, endExclusive: false } : void 0
|
|
221
|
+
});
|
|
222
|
+
return {
|
|
223
|
+
kind: "find",
|
|
224
|
+
notes: res.notes,
|
|
225
|
+
blocks: res.blocks,
|
|
226
|
+
efforts: res.efforts,
|
|
227
|
+
containers: res.containers,
|
|
228
|
+
runs: res.runs,
|
|
229
|
+
table: res.table
|
|
230
|
+
};
|
|
231
|
+
},
|
|
232
|
+
runPipeline: async (queryText, context) => {
|
|
233
|
+
const res = await executor.runPipeline?.(queryText, {
|
|
234
|
+
context,
|
|
235
|
+
rangeStart: range.rangeStart,
|
|
236
|
+
rangeEnd: range.rangeEnd,
|
|
237
|
+
preferredUnit: range.preferredUnit
|
|
238
|
+
});
|
|
239
|
+
return res ?? { error: "pipeline queries are not supported by this executor" };
|
|
240
|
+
},
|
|
241
|
+
rollupEnsure: range.rollupEnsure
|
|
242
|
+
};
|
|
243
|
+
}
|
|
209
244
|
function toChartResult(input) {
|
|
210
245
|
const parsed = input.parsed;
|
|
246
|
+
const series = input.series ?? [];
|
|
247
|
+
const scalar = series.length === 1 && series[0].points.length === 1 ? series[0].points[0].value : void 0;
|
|
211
248
|
return {
|
|
212
249
|
parsed,
|
|
213
|
-
series
|
|
250
|
+
series,
|
|
214
251
|
stages: { selected: 0, buckets: 0, aggregated: 0, groups: 0 },
|
|
215
252
|
matched: [],
|
|
253
|
+
...scalar !== void 0 ? { scalar } : {},
|
|
216
254
|
...input.unit !== void 0 ? { unit: input.unit } : {},
|
|
217
255
|
...input.error ? { error: input.error } : {},
|
|
218
256
|
...input.table ? { table: input.table } : {}
|
|
219
257
|
};
|
|
220
258
|
}
|
|
259
|
+
function outputToRunResult(parsed, out) {
|
|
260
|
+
const base = toChartResult({
|
|
261
|
+
parsed,
|
|
262
|
+
series: out.series,
|
|
263
|
+
unit: out.unit,
|
|
264
|
+
error: out.error,
|
|
265
|
+
table: out.table
|
|
266
|
+
});
|
|
267
|
+
return Object.assign(base, {
|
|
268
|
+
...out.notes ? { notes: out.notes } : {},
|
|
269
|
+
...out.blocks ? { blocks: out.blocks } : {},
|
|
270
|
+
...out.efforts ? { efforts: out.efforts } : {},
|
|
271
|
+
...out.containers ? { containers: out.containers } : {},
|
|
272
|
+
...out.runs ? { runs: out.runs } : {},
|
|
273
|
+
...out.chart ? { chart: out.chart } : {}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
221
276
|
function mergeSeries(series) {
|
|
222
277
|
const map = /* @__PURE__ */ new Map();
|
|
223
278
|
for (const s of series) {
|
|
@@ -830,16 +885,52 @@ function ZoneDistribution({ result, params, attributes }) {
|
|
|
830
885
|
}
|
|
831
886
|
);
|
|
832
887
|
}
|
|
833
|
-
function
|
|
888
|
+
function inferChartTypeFromResult(result) {
|
|
889
|
+
if (!result || result.series.length === 0) return "table";
|
|
890
|
+
if (result.series.length === 1 && result.series[0].points.length === 1) return "value";
|
|
891
|
+
const hasTimeAxis = result.series.some((s) => s.points.length > 1);
|
|
892
|
+
return hasTimeAxis ? "timeseries" : "bar";
|
|
893
|
+
}
|
|
894
|
+
function WidgetChart({
|
|
895
|
+
type,
|
|
896
|
+
result,
|
|
897
|
+
label,
|
|
898
|
+
unit,
|
|
899
|
+
params,
|
|
900
|
+
attributes,
|
|
901
|
+
inferDefaultShape = false,
|
|
902
|
+
onOpenNote,
|
|
903
|
+
noteHref
|
|
904
|
+
}) {
|
|
834
905
|
if (type !== "" && !wodWikiWql.isDashboardWidgetType(type)) {
|
|
835
906
|
return /* @__PURE__ */ jsxRuntime.jsx(WidgetProblemBadge, { message: wodWikiWql.unknownWidgetTypeMessage(type) });
|
|
836
907
|
}
|
|
837
|
-
const resolved = wodWikiWql.resolveWidgetType(type);
|
|
838
|
-
|
|
839
|
-
|
|
908
|
+
const resolved = type === "" && inferDefaultShape ? inferChartTypeFromResult(result) : wodWikiWql.resolveWidgetType(type);
|
|
909
|
+
const runResult = result;
|
|
910
|
+
const parsedFamily = runResult?.parsed?.family;
|
|
911
|
+
const hasContentItems = parsedFamily === "find" || Boolean(runResult?.notes?.length || runResult?.blocks?.length || runResult?.efforts?.length || runResult?.runs?.length);
|
|
912
|
+
if (resolved === "table" && runResult?.table) {
|
|
913
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(TabularTable, { table: runResult.table }) });
|
|
914
|
+
}
|
|
915
|
+
if (resolved === "table" && hasContentItems && (!result || !("series" in result) || result.series.length === 0)) {
|
|
916
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
917
|
+
ContentRecordsTable,
|
|
918
|
+
{
|
|
919
|
+
result: runResult,
|
|
920
|
+
onOpenNote,
|
|
921
|
+
noteHref
|
|
922
|
+
}
|
|
923
|
+
) });
|
|
840
924
|
}
|
|
841
|
-
if (resolved === "list" &&
|
|
842
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
925
|
+
if (resolved === "list" && hasContentItems) {
|
|
926
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
927
|
+
ThingList,
|
|
928
|
+
{
|
|
929
|
+
result: runResult,
|
|
930
|
+
onOpenNote,
|
|
931
|
+
noteHref
|
|
932
|
+
}
|
|
933
|
+
) });
|
|
843
934
|
}
|
|
844
935
|
if (!result || result.parsed.error || "series" in result && result.series.length === 0) {
|
|
845
936
|
return /* @__PURE__ */ jsxRuntime.jsx(WqlEmptyState, { result });
|
|
@@ -966,9 +1057,138 @@ function TabularTable({ table }) {
|
|
|
966
1057
|
] }, 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)) })
|
|
967
1058
|
] }) });
|
|
968
1059
|
}
|
|
969
|
-
function
|
|
970
|
-
|
|
971
|
-
|
|
1060
|
+
function containerPageHref(container) {
|
|
1061
|
+
if (!container || container.kind !== "page") return void 0;
|
|
1062
|
+
const { slug, date } = container;
|
|
1063
|
+
if (slug) return `/page/${encodeURIComponent(slug)}`;
|
|
1064
|
+
if (date) return `/day/${encodeURIComponent(date)}`;
|
|
1065
|
+
return void 0;
|
|
1066
|
+
}
|
|
1067
|
+
function formatItemDate(item) {
|
|
1068
|
+
const raw = item.date ?? item.timestamp ?? item.createdAt;
|
|
1069
|
+
if (raw === void 0 || raw === null || raw === "") return "\u2014";
|
|
1070
|
+
if (typeof raw === "string" && /^\d{4}-\d{2}-\d{2}/.test(raw)) return raw.slice(0, 10);
|
|
1071
|
+
const ms = typeof raw === "number" ? raw : Date.parse(String(raw));
|
|
1072
|
+
if (!Number.isFinite(ms) || ms <= 0) return "\u2014";
|
|
1073
|
+
return new Date(ms).toISOString().slice(0, 10);
|
|
1074
|
+
}
|
|
1075
|
+
function ContentRecordsTable({
|
|
1076
|
+
result,
|
|
1077
|
+
onOpenNote,
|
|
1078
|
+
noteHref
|
|
1079
|
+
}) {
|
|
1080
|
+
const parsed = result?.parsed;
|
|
1081
|
+
const target = parsed?.target ?? (parsed?.source?.kind === "query" && parsed?.source?.query?.family === "find" ? parsed.source.query.target ?? "note" : result?.blocks?.length ? "block" : "note");
|
|
1082
|
+
const isBlock = target === "block" || Boolean(result?.blocks?.length && !result?.notes?.length);
|
|
1083
|
+
const rawItems = result?.notes?.length ? result.notes : result?.blocks?.length ? result.blocks : result?.efforts?.length ? result.efforts : result?.runs ?? [];
|
|
1084
|
+
const items = rawItems;
|
|
1085
|
+
if (items.length === 0) {
|
|
1086
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground py-4 text-center", "data-testid": "content-records-table-empty", children: [
|
|
1087
|
+
"No ",
|
|
1088
|
+
target,
|
|
1089
|
+
"s matched this query."
|
|
1090
|
+
] });
|
|
1091
|
+
}
|
|
1092
|
+
const containers = result?.containers;
|
|
1093
|
+
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: [
|
|
1094
|
+
/* @__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: [
|
|
1095
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "py-2 px-3", children: "Title" }),
|
|
1096
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "py-2 px-3", children: "Kind" }),
|
|
1097
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "py-2 px-3", children: "Tags / Details" }),
|
|
1098
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "py-2 px-3 text-right", children: "Date" })
|
|
1099
|
+
] }) }),
|
|
1100
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-border/40", children: items.map((item, i) => {
|
|
1101
|
+
const id = item.id ?? item.resultId ?? String(i);
|
|
1102
|
+
const typedItem = { ...item, id, title: item.title ?? item.label ?? item.noteTitle };
|
|
1103
|
+
const title = isBlock ? typedItem.title || typedItem.blockContentId || id : typedItem.title || id;
|
|
1104
|
+
const href = containers ? containerPageHref(containers[id]) ?? (noteHref ? noteHref(typedItem) : void 0) : noteHref ? noteHref(typedItem) : void 0;
|
|
1105
|
+
const kindLabel = item.type ?? item.dataType ?? item.baseAttributes?.discipline ?? target;
|
|
1106
|
+
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";
|
|
1107
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "hover:bg-muted/30 transition-colors", children: [
|
|
1108
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-2 px-3 font-medium truncate max-w-[260px]", children: href ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1109
|
+
"a",
|
|
1110
|
+
{
|
|
1111
|
+
href,
|
|
1112
|
+
onClick: (e) => {
|
|
1113
|
+
if (onOpenNote) {
|
|
1114
|
+
e.preventDefault();
|
|
1115
|
+
onOpenNote(typedItem);
|
|
1116
|
+
}
|
|
1117
|
+
},
|
|
1118
|
+
className: "text-primary hover:underline",
|
|
1119
|
+
children: title
|
|
1120
|
+
}
|
|
1121
|
+
) : onOpenNote ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1122
|
+
"button",
|
|
1123
|
+
{
|
|
1124
|
+
type: "button",
|
|
1125
|
+
onClick: () => onOpenNote(typedItem),
|
|
1126
|
+
className: "text-left text-primary hover:underline",
|
|
1127
|
+
children: title
|
|
1128
|
+
}
|
|
1129
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground", children: title }) }),
|
|
1130
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-2 px-3 font-mono text-[11px] text-muted-foreground", children: kindLabel }),
|
|
1131
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-2 px-3 font-mono text-[11px] text-muted-foreground truncate max-w-[200px]", children: detail }),
|
|
1132
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-2 px-3 font-mono text-[11px] text-muted-foreground text-right tabular-nums", children: formatItemDate(item) })
|
|
1133
|
+
] }, id);
|
|
1134
|
+
}) })
|
|
1135
|
+
] }) });
|
|
1136
|
+
}
|
|
1137
|
+
function ThingList({
|
|
1138
|
+
result,
|
|
1139
|
+
onOpenNote,
|
|
1140
|
+
noteHref
|
|
1141
|
+
}) {
|
|
1142
|
+
const parsed = result?.parsed;
|
|
1143
|
+
const target = parsed?.target ?? (parsed?.source?.kind === "query" && parsed?.source?.query?.family === "find" ? parsed.source.query.target ?? "note" : result?.blocks?.length ? "block" : "note");
|
|
1144
|
+
const isBlock = target === "block" || Boolean(result?.blocks?.length && !result?.notes?.length);
|
|
1145
|
+
const rawItems = result?.notes?.length ? result.notes : result?.blocks?.length ? result.blocks : result?.efforts?.length ? result.efforts : result?.runs ?? [];
|
|
1146
|
+
const items = rawItems;
|
|
1147
|
+
if (items.length === 0) {
|
|
1148
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground py-2", "data-testid": "thing-list", children: [
|
|
1149
|
+
"No ",
|
|
1150
|
+
target,
|
|
1151
|
+
"s matched this query."
|
|
1152
|
+
] });
|
|
1153
|
+
}
|
|
1154
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full overflow-auto space-y-1", "data-testid": "thing-list", children: [
|
|
1155
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[11px] font-medium text-muted-foreground mb-1", children: [
|
|
1156
|
+
items.length,
|
|
1157
|
+
" ",
|
|
1158
|
+
target,
|
|
1159
|
+
items.length === 1 ? "" : "s",
|
|
1160
|
+
" matched"
|
|
1161
|
+
] }),
|
|
1162
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-0.5 max-h-48 overflow-y-auto font-mono text-xs", children: items.map((item, i) => {
|
|
1163
|
+
const id = item.id ?? item.resultId ?? String(i);
|
|
1164
|
+
const typedItem = { ...item, id, title: item.title ?? item.label ?? item.noteTitle };
|
|
1165
|
+
const title = isBlock ? typedItem.title || typedItem.blockContentId || id : typedItem.title || id;
|
|
1166
|
+
const containers = result?.containers;
|
|
1167
|
+
const href = containers ? containerPageHref(containers[id]) ?? (noteHref ? noteHref(typedItem) : void 0) : noteHref ? noteHref(typedItem) : void 0;
|
|
1168
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { className: "rounded hover:bg-muted/50 truncate", children: href ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1169
|
+
"a",
|
|
1170
|
+
{
|
|
1171
|
+
href,
|
|
1172
|
+
onClick: (e) => {
|
|
1173
|
+
if (onOpenNote) {
|
|
1174
|
+
e.preventDefault();
|
|
1175
|
+
onOpenNote(typedItem);
|
|
1176
|
+
}
|
|
1177
|
+
},
|
|
1178
|
+
className: "block py-0.5 px-1.5 text-primary hover:underline truncate",
|
|
1179
|
+
children: title
|
|
1180
|
+
}
|
|
1181
|
+
) : onOpenNote ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1182
|
+
"button",
|
|
1183
|
+
{
|
|
1184
|
+
type: "button",
|
|
1185
|
+
onClick: () => onOpenNote(typedItem),
|
|
1186
|
+
className: "w-full text-left py-0.5 px-1.5 text-primary hover:underline truncate",
|
|
1187
|
+
children: title
|
|
1188
|
+
}
|
|
1189
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block py-0.5 px-1.5 text-foreground truncate", children: title }) }, id);
|
|
1190
|
+
}) })
|
|
1191
|
+
] });
|
|
972
1192
|
}
|
|
973
1193
|
function ScalarTokenInput({
|
|
974
1194
|
name,
|
|
@@ -1044,53 +1264,6 @@ function DashboardTokenControls({ tokens, values: values2, onChange }) {
|
|
|
1044
1264
|
}
|
|
1045
1265
|
);
|
|
1046
1266
|
}
|
|
1047
|
-
function createExecutorDocumentHost(executor, range = {}) {
|
|
1048
|
-
return {
|
|
1049
|
-
runAggregate: (queryText, overrides) => executor.runQuery(queryText, {
|
|
1050
|
-
context: overrides.context,
|
|
1051
|
-
rangeStart: range.rangeStart,
|
|
1052
|
-
rangeEnd: range.rangeEnd,
|
|
1053
|
-
preferredUnit: range.preferredUnit
|
|
1054
|
-
}),
|
|
1055
|
-
runFind: async (queryText, context) => {
|
|
1056
|
-
const parsed = wodWikiWql.parseQuery(queryText);
|
|
1057
|
-
if (!wodWikiWql.isFindQuery(parsed)) return { kind: "find", error: `not a content query: ${queryText}` };
|
|
1058
|
-
const res = await executor.runFind(parsed, {
|
|
1059
|
-
context,
|
|
1060
|
-
range: range.rangeStart !== void 0 ? { start: range.rangeStart, end: range.rangeEnd ?? Number.MAX_SAFE_INTEGER, endExclusive: false } : void 0
|
|
1061
|
-
});
|
|
1062
|
-
return {
|
|
1063
|
-
kind: "find",
|
|
1064
|
-
notes: res.notes,
|
|
1065
|
-
blocks: res.blocks,
|
|
1066
|
-
efforts: res.efforts,
|
|
1067
|
-
containers: res.containers,
|
|
1068
|
-
runs: res.runs,
|
|
1069
|
-
table: res.table
|
|
1070
|
-
};
|
|
1071
|
-
},
|
|
1072
|
-
runPipeline: async (queryText, context) => {
|
|
1073
|
-
const res = await executor.runPipeline?.(queryText, {
|
|
1074
|
-
context,
|
|
1075
|
-
rangeStart: range.rangeStart,
|
|
1076
|
-
rangeEnd: range.rangeEnd,
|
|
1077
|
-
preferredUnit: range.preferredUnit
|
|
1078
|
-
});
|
|
1079
|
-
return res ?? { error: "pipeline queries are not supported by this executor" };
|
|
1080
|
-
},
|
|
1081
|
-
rollupEnsure: range.rollupEnsure
|
|
1082
|
-
};
|
|
1083
|
-
}
|
|
1084
|
-
function outputToRunResult(parsed, out) {
|
|
1085
|
-
const base = toChartResult({ parsed, series: out.series, unit: out.unit, error: out.error, table: out.table });
|
|
1086
|
-
return Object.assign(base, {
|
|
1087
|
-
...out.notes ? { notes: out.notes } : {},
|
|
1088
|
-
...out.blocks ? { blocks: out.blocks } : {},
|
|
1089
|
-
...out.efforts ? { efforts: out.efforts } : {},
|
|
1090
|
-
...out.containers ? { containers: out.containers } : {},
|
|
1091
|
-
...out.runs ? { runs: out.runs } : {}
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
1267
|
function spanClass(widget) {
|
|
1095
1268
|
if (widget.spanFull) return "col-span-1 md:col-span-2 lg:col-span-4";
|
|
1096
1269
|
if (widget.spanCols != null) {
|
|
@@ -1131,7 +1304,9 @@ function DashboardView({
|
|
|
1131
1304
|
onResizeWidget,
|
|
1132
1305
|
rangeStart,
|
|
1133
1306
|
rangeEnd,
|
|
1134
|
-
preferredUnit
|
|
1307
|
+
preferredUnit,
|
|
1308
|
+
onOpenNote,
|
|
1309
|
+
noteHref
|
|
1135
1310
|
}) {
|
|
1136
1311
|
const values2 = React2.useMemo(
|
|
1137
1312
|
() => ({ ...wodWikiWql.defaultTokenValues(document2.tokens), ...tokenValues }),
|
|
@@ -1172,9 +1347,12 @@ function DashboardView({
|
|
|
1172
1347
|
next[widget.key] = { error: wodWikiWql.unknownTokensMessage(missing) };
|
|
1173
1348
|
continue;
|
|
1174
1349
|
}
|
|
1175
|
-
const
|
|
1176
|
-
|
|
1177
|
-
|
|
1350
|
+
const docParse = wodWikiWql.parseDocument(query);
|
|
1351
|
+
const isMultiLineDoc = !docParse.doc.degenerate && docParse.doc.assignments.length > 0;
|
|
1352
|
+
const parsed = isMultiLineDoc ? { family: "aggregate", raw: query, agg: "sum", metric: docParse.doc.show[0] ?? "value", filters: [], groupBy: [] } : wodWikiWql.parseQuery(query);
|
|
1353
|
+
const syntaxErr = isMultiLineDoc ? docParse.diagnostics[0] : parsed.error;
|
|
1354
|
+
if (syntaxErr) {
|
|
1355
|
+
next[widget.key] = { error: syntaxErr };
|
|
1178
1356
|
continue;
|
|
1179
1357
|
}
|
|
1180
1358
|
const resolvedType = wodWikiWql.resolveWidgetType(widget.type);
|
|
@@ -1183,7 +1361,7 @@ function DashboardView({
|
|
|
1183
1361
|
next[widget.key] = { error: "content queries return things \u2014 use a table or list widget instead" };
|
|
1184
1362
|
continue;
|
|
1185
1363
|
}
|
|
1186
|
-
} else if (!wodWikiWql.isPipelineQuery(parsed) && resolvedType === "list") {
|
|
1364
|
+
} else if (!wodWikiWql.isPipelineQuery(parsed) && !isMultiLineDoc && resolvedType === "list") {
|
|
1187
1365
|
next[widget.key] = { error: "aggregate queries return numbers \u2014 use a chart or value widget instead" };
|
|
1188
1366
|
continue;
|
|
1189
1367
|
}
|
|
@@ -1321,7 +1499,9 @@ function DashboardView({
|
|
|
1321
1499
|
result: run?.result,
|
|
1322
1500
|
label: widget.title,
|
|
1323
1501
|
unit: preferredUnit,
|
|
1324
|
-
attributes
|
|
1502
|
+
attributes,
|
|
1503
|
+
onOpenNote,
|
|
1504
|
+
noteHref
|
|
1325
1505
|
}
|
|
1326
1506
|
)
|
|
1327
1507
|
},
|
|
@@ -1395,17 +1575,8 @@ function useAnalyticsQueries(queries, weeks, executor, refreshKey = 0, preferred
|
|
|
1395
1575
|
const res = await runner.run(q.query);
|
|
1396
1576
|
const out = res.outputs[0];
|
|
1397
1577
|
const error = out?.error ?? res.diagnostics[0];
|
|
1398
|
-
const
|
|
1399
|
-
|
|
1400
|
-
series: out?.series,
|
|
1401
|
-
unit: out?.unit,
|
|
1402
|
-
error,
|
|
1403
|
-
table: out?.table
|
|
1404
|
-
});
|
|
1405
|
-
if (out?.notes) result.notes = out.notes;
|
|
1406
|
-
if (out?.blocks) result.blocks = out.blocks;
|
|
1407
|
-
if (out?.efforts) result.efforts = out.efforts;
|
|
1408
|
-
if (out?.runs) result.runs = out.runs;
|
|
1578
|
+
const parsed = wodWikiWql.parseQuery(q.query);
|
|
1579
|
+
const result = out ? outputToRunResult(parsed, { ...out, ...error ? { error } : {} }) : outputToRunResult(parsed, { name: q.key, kind: "aggregate", error });
|
|
1409
1580
|
return [q.key, result];
|
|
1410
1581
|
})
|
|
1411
1582
|
);
|
|
@@ -4551,21 +4722,31 @@ function QueryBlockView({
|
|
|
4551
4722
|
widgetError,
|
|
4552
4723
|
tokenValues,
|
|
4553
4724
|
attributes,
|
|
4725
|
+
onAddToDashboard,
|
|
4554
4726
|
onCaptureRpe,
|
|
4555
4727
|
onOpenNote,
|
|
4556
4728
|
noteHref
|
|
4557
4729
|
}) {
|
|
4558
4730
|
const [isModalOpen, setIsModalOpen] = React2.useState(false);
|
|
4559
4731
|
const extracted = React2.useMemo(() => extractBlockQueries(query), [query]);
|
|
4732
|
+
const rawBody = React2.useMemo(() => {
|
|
4733
|
+
const trimmed = query.trim();
|
|
4734
|
+
if (trimmed.includes("\n")) {
|
|
4735
|
+
const docParsed = wodWikiWql.parseDocument(trimmed);
|
|
4736
|
+
if (!docParsed.doc.degenerate && docParsed.diagnostics.length === 0 && docParsed.doc.assignments.length > 0) {
|
|
4737
|
+
return trimmed;
|
|
4738
|
+
}
|
|
4739
|
+
}
|
|
4740
|
+
return extracted.length > 0 ? extracted[0].query : query;
|
|
4741
|
+
}, [extracted, query]);
|
|
4560
4742
|
const { query: effectiveQuery, missing } = React2.useMemo(() => {
|
|
4561
|
-
const
|
|
4562
|
-
const subQuery = wodWikiWql.substituteTokens(raw, tokenValues ?? {});
|
|
4743
|
+
const subQuery = wodWikiWql.substituteTokens(rawBody, tokenValues ?? {});
|
|
4563
4744
|
const missingSet = new Set(subQuery.missing);
|
|
4564
4745
|
for (const value of Object.values(attributes ?? {})) {
|
|
4565
4746
|
for (const m of wodWikiWql.substituteTokens(value, tokenValues ?? {}).missing) missingSet.add(m);
|
|
4566
4747
|
}
|
|
4567
4748
|
return { query: subQuery.query, missing: [...missingSet] };
|
|
4568
|
-
}, [
|
|
4749
|
+
}, [rawBody, tokenValues, attributes]);
|
|
4569
4750
|
const resolvedAttributes = React2.useMemo(() => {
|
|
4570
4751
|
const out = {};
|
|
4571
4752
|
for (const [key, value] of Object.entries(attributes ?? {})) {
|
|
@@ -4573,11 +4754,12 @@ function QueryBlockView({
|
|
|
4573
4754
|
}
|
|
4574
4755
|
return out;
|
|
4575
4756
|
}, [attributes, tokenValues]);
|
|
4757
|
+
const docParse = React2.useMemo(() => wodWikiWql.parseDocument(effectiveQuery), [effectiveQuery]);
|
|
4758
|
+
const isMultiLineDoc = !docParse.doc.degenerate && docParse.doc.assignments.length > 0;
|
|
4576
4759
|
const parsed = React2.useMemo(() => wodWikiWql.parseQuery(effectiveQuery), [effectiveQuery]);
|
|
4760
|
+
const syntaxError = isMultiLineDoc ? docParse.diagnostics[0] : parsed.error;
|
|
4577
4761
|
const unknownType = widgetType != null && widgetType !== "" && !wodWikiWql.isDashboardWidgetType(widgetType);
|
|
4578
|
-
const [
|
|
4579
|
-
const [findResult, setFindResult] = React2.useState(void 0);
|
|
4580
|
-
const [pipelineResult, setPipelineResult] = React2.useState(void 0);
|
|
4762
|
+
const [runResult, setRunResult] = React2.useState(void 0);
|
|
4581
4763
|
const [runError, setRunError] = React2.useState(void 0);
|
|
4582
4764
|
const [rowsRefreshKey, setRowsRefreshKey] = React2.useState(0);
|
|
4583
4765
|
React2.useEffect(() => {
|
|
@@ -4592,59 +4774,45 @@ function QueryBlockView({
|
|
|
4592
4774
|
}, [onResultSaved]);
|
|
4593
4775
|
React2.useEffect(() => {
|
|
4594
4776
|
let cancelled = false;
|
|
4777
|
+
let retryTimer;
|
|
4595
4778
|
setRunError(void 0);
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
};
|
|
4624
|
-
}
|
|
4625
|
-
if (wodWikiWql.isPipelineQuery(parsed)) {
|
|
4626
|
-
if (!executor.runPipeline) {
|
|
4627
|
-
setRunError("pipeline queries are not supported by this executor");
|
|
4628
|
-
return;
|
|
4629
|
-
}
|
|
4630
|
-
void executor.runPipeline(effectiveQuery).then((res) => {
|
|
4631
|
-
if (!cancelled) setPipelineResult(res);
|
|
4779
|
+
setRunResult(void 0);
|
|
4780
|
+
if (syntaxError || widgetError || unknownType || missing.length > 0 || !executor) return;
|
|
4781
|
+
const isSessionFind = !isMultiLineDoc && wodWikiWql.isFindQuery(parsed) && parsed.target === "session";
|
|
4782
|
+
const host = createExecutorDocumentHost(executor);
|
|
4783
|
+
const executeRun = (attemptCount) => {
|
|
4784
|
+
const runner = new wodWikiWql.SharedQueryDocumentRunner(host);
|
|
4785
|
+
void runner.run(effectiveQuery).then((res) => {
|
|
4786
|
+
if (cancelled) return;
|
|
4787
|
+
const out = res.outputs[0];
|
|
4788
|
+
if (!out) {
|
|
4789
|
+
setRunError(res.diagnostics[0] ?? "widget produced no output");
|
|
4790
|
+
return;
|
|
4791
|
+
}
|
|
4792
|
+
const err = out.error ?? res.diagnostics[0];
|
|
4793
|
+
if (err) {
|
|
4794
|
+
setRunError(err);
|
|
4795
|
+
return;
|
|
4796
|
+
}
|
|
4797
|
+
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;
|
|
4798
|
+
const shaped = outputToRunResult(effectiveParsed, out);
|
|
4799
|
+
setRunResult(shaped);
|
|
4800
|
+
if (isSessionFind && (shaped.runs ?? []).length === 0 && attemptCount < 4) {
|
|
4801
|
+
const delays = [50, 150, 350, 750];
|
|
4802
|
+
retryTimer = setTimeout(() => {
|
|
4803
|
+
if (!cancelled) executeRun(attemptCount + 1);
|
|
4804
|
+
}, delays[attemptCount] ?? 500);
|
|
4805
|
+
}
|
|
4632
4806
|
}).catch((err) => {
|
|
4633
4807
|
if (!cancelled) setRunError(err instanceof Error ? err.message : String(err));
|
|
4634
4808
|
});
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
};
|
|
4638
|
-
}
|
|
4639
|
-
void executor.runQuery(effectiveQuery).then((res) => {
|
|
4640
|
-
if (!cancelled) setResult(res);
|
|
4641
|
-
}).catch((err) => {
|
|
4642
|
-
if (!cancelled) setRunError(err instanceof Error ? err.message : String(err));
|
|
4643
|
-
});
|
|
4809
|
+
};
|
|
4810
|
+
executeRun(0);
|
|
4644
4811
|
return () => {
|
|
4645
4812
|
cancelled = true;
|
|
4813
|
+
clearTimeout(retryTimer);
|
|
4646
4814
|
};
|
|
4647
|
-
}, [effectiveQuery, parsed, widgetError, unknownType, missing, executor, rowsRefreshKey]);
|
|
4815
|
+
}, [effectiveQuery, parsed, isMultiLineDoc, syntaxError, widgetError, unknownType, missing, executor, rowsRefreshKey]);
|
|
4648
4816
|
const canEdit = onSaveQuery !== void 0 && !readOnly;
|
|
4649
4817
|
const onEdit = canEdit ? () => setIsModalOpen(true) : void 0;
|
|
4650
4818
|
const resultId = React2.useMemo(() => {
|
|
@@ -4652,50 +4820,32 @@ function QueryBlockView({
|
|
|
4652
4820
|
const resultFilter = parsed.filters.find((f) => f.key === "result");
|
|
4653
4821
|
return resultFilter?.values[0]?.value;
|
|
4654
4822
|
}, [parsed]);
|
|
4823
|
+
const fallbackLabel = React2.useMemo(() => {
|
|
4824
|
+
if (!wodWikiWql.isFindQuery(parsed) && !wodWikiWql.isPipelineQuery(parsed)) return parsed.metric;
|
|
4825
|
+
return parsed.raw;
|
|
4826
|
+
}, [parsed]);
|
|
4655
4827
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": "query-block-view", children: [
|
|
4656
|
-
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) }) }) :
|
|
4828
|
+
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: [
|
|
4657
4829
|
"Query syntax error: ",
|
|
4658
|
-
|
|
4659
|
-
] }) }) : 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: [
|
|
4830
|
+
syntaxError
|
|
4831
|
+
] }) }) : 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: [
|
|
4660
4832
|
"Query execution error: ",
|
|
4661
4833
|
runError
|
|
4662
|
-
] }) }) :
|
|
4663
|
-
|
|
4834
|
+
] }) }) : /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, onAddToDashboard, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4835
|
+
QueryBlockBody,
|
|
4664
4836
|
{
|
|
4837
|
+
parsed,
|
|
4838
|
+
result: runResult,
|
|
4665
4839
|
resultId,
|
|
4666
|
-
|
|
4840
|
+
widgetType,
|
|
4841
|
+
attributes: resolvedAttributes,
|
|
4842
|
+
fallbackLabel,
|
|
4667
4843
|
executor,
|
|
4668
4844
|
onCaptureRpe,
|
|
4669
|
-
onCaptured: () => setRowsRefreshKey((k) => k + 1)
|
|
4670
|
-
}
|
|
4671
|
-
) : findResult?.runs ? /* @__PURE__ */ jsxRuntime.jsx(RowsTable, { result: findResult }) : findResult ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4672
|
-
FindResultList,
|
|
4673
|
-
{
|
|
4674
|
-
target: parsed.target,
|
|
4675
|
-
notes: findResult.notes,
|
|
4676
|
-
blocks: findResult.blocks,
|
|
4677
|
-
containers: findResult.containers,
|
|
4845
|
+
onCaptured: () => setRowsRefreshKey((k) => k + 1),
|
|
4678
4846
|
onOpenNote,
|
|
4679
4847
|
noteHref
|
|
4680
4848
|
}
|
|
4681
|
-
) : /* @__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(
|
|
4682
|
-
PipelineResultView,
|
|
4683
|
-
{
|
|
4684
|
-
result: pipelineResult,
|
|
4685
|
-
onOpenNote,
|
|
4686
|
-
noteHref,
|
|
4687
|
-
widgetType,
|
|
4688
|
-
attributes: resolvedAttributes,
|
|
4689
|
-
fallbackLabel: parsed.raw
|
|
4690
|
-
}
|
|
4691
|
-
) }) : /* @__PURE__ */ jsxRuntime.jsx(QueryBlockShell, { onEdit, readOnly, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4692
|
-
AnalyticsChart,
|
|
4693
|
-
{
|
|
4694
|
-
result,
|
|
4695
|
-
metric: parsed.metric,
|
|
4696
|
-
widgetType,
|
|
4697
|
-
attributes: resolvedAttributes
|
|
4698
|
-
}
|
|
4699
4849
|
) }),
|
|
4700
4850
|
canEdit && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4701
4851
|
WqlQueryInspectorModal,
|
|
@@ -4709,159 +4859,103 @@ function QueryBlockView({
|
|
|
4709
4859
|
)
|
|
4710
4860
|
] });
|
|
4711
4861
|
}
|
|
4712
|
-
function
|
|
4862
|
+
function QueryBlockBody({
|
|
4863
|
+
parsed,
|
|
4713
4864
|
result,
|
|
4714
|
-
|
|
4865
|
+
resultId,
|
|
4715
4866
|
widgetType,
|
|
4716
|
-
attributes
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
}
|
|
4722
|
-
if (shape.kind === "scalar") {
|
|
4723
|
-
return /* @__PURE__ */ jsxRuntime.jsx(QueryValue, { result, label: metric });
|
|
4724
|
-
}
|
|
4725
|
-
if (shape.kind === "timeseries") {
|
|
4726
|
-
return /* @__PURE__ */ jsxRuntime.jsx(WqlTimeseries, { result });
|
|
4727
|
-
}
|
|
4728
|
-
if (shape.kind === "bars") {
|
|
4729
|
-
return /* @__PURE__ */ jsxRuntime.jsx(WqlBars, { result });
|
|
4730
|
-
}
|
|
4731
|
-
return /* @__PURE__ */ jsxRuntime.jsx(WqlEmptyState, { result });
|
|
4732
|
-
}
|
|
4733
|
-
function containerPageHref(container) {
|
|
4734
|
-
if (!container || container.kind !== "page") return void 0;
|
|
4735
|
-
const { slug, date } = container;
|
|
4736
|
-
if (slug) return `/page/${encodeURIComponent(slug)}`;
|
|
4737
|
-
if (date) return `/day/${encodeURIComponent(date)}`;
|
|
4738
|
-
return void 0;
|
|
4739
|
-
}
|
|
4740
|
-
function FindResultList({
|
|
4741
|
-
target,
|
|
4742
|
-
notes,
|
|
4743
|
-
blocks,
|
|
4744
|
-
containers,
|
|
4867
|
+
attributes,
|
|
4868
|
+
fallbackLabel,
|
|
4869
|
+
executor,
|
|
4870
|
+
onCaptureRpe,
|
|
4871
|
+
onCaptured,
|
|
4745
4872
|
onOpenNote,
|
|
4746
4873
|
noteHref
|
|
4747
|
-
}) {
|
|
4748
|
-
const isBlock = target === "block";
|
|
4749
|
-
const items = isBlock ? blocks : notes;
|
|
4750
|
-
if (items.length === 0) {
|
|
4751
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground py-2", children: [
|
|
4752
|
-
"No ",
|
|
4753
|
-
target,
|
|
4754
|
-
"s matched this query."
|
|
4755
|
-
] });
|
|
4756
|
-
}
|
|
4757
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
4758
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[11px] font-medium text-muted-foreground mb-1", children: [
|
|
4759
|
-
items.length,
|
|
4760
|
-
" ",
|
|
4761
|
-
target,
|
|
4762
|
-
items.length === 1 ? "" : "s",
|
|
4763
|
-
" matched"
|
|
4764
|
-
] }),
|
|
4765
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-0.5 max-h-48 overflow-y-auto font-mono text-xs", children: items.map((item) => {
|
|
4766
|
-
const typedItem = item;
|
|
4767
|
-
const title = isBlock ? typedItem.title || typedItem.blockContentId || item.id : typedItem.title || item.id;
|
|
4768
|
-
const href = containers ? containerPageHref(containers[item.id]) ?? (noteHref ? noteHref(typedItem) : void 0) : noteHref ? noteHref(typedItem) : void 0;
|
|
4769
|
-
return /* @__PURE__ */ jsxRuntime.jsx("li", { className: "rounded hover:bg-muted/50 truncate", children: href ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4770
|
-
"a",
|
|
4771
|
-
{
|
|
4772
|
-
href,
|
|
4773
|
-
onClick: (e) => {
|
|
4774
|
-
if (onOpenNote) {
|
|
4775
|
-
e.preventDefault();
|
|
4776
|
-
onOpenNote(typedItem);
|
|
4777
|
-
}
|
|
4778
|
-
},
|
|
4779
|
-
className: "block py-0.5 px-1.5 text-primary hover:underline truncate",
|
|
4780
|
-
children: title
|
|
4781
|
-
}
|
|
4782
|
-
) : onOpenNote ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4783
|
-
"button",
|
|
4784
|
-
{
|
|
4785
|
-
type: "button",
|
|
4786
|
-
onClick: () => onOpenNote(typedItem),
|
|
4787
|
-
className: "w-full text-left py-0.5 px-1.5 text-primary hover:underline truncate",
|
|
4788
|
-
children: title
|
|
4789
|
-
}
|
|
4790
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block py-0.5 px-1.5 text-foreground truncate", children: title }) }, item.id);
|
|
4791
|
-
}) })
|
|
4792
|
-
] });
|
|
4793
|
-
}
|
|
4794
|
-
function PipelineResultView({
|
|
4795
|
-
result,
|
|
4796
|
-
onOpenNote,
|
|
4797
|
-
noteHref,
|
|
4798
|
-
widgetType,
|
|
4799
|
-
attributes,
|
|
4800
|
-
fallbackLabel
|
|
4801
4874
|
}) {
|
|
4802
4875
|
if (!result) {
|
|
4803
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground py-2", children: "Loading\u2026" });
|
|
4876
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground py-2", children: wodWikiWql.isFindQuery(parsed) ? "Loading rows\u2026" : "Loading\u2026" });
|
|
4804
4877
|
}
|
|
4805
|
-
if (result.
|
|
4806
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
4807
|
-
"Query execution error: ",
|
|
4808
|
-
result.error
|
|
4809
|
-
] });
|
|
4878
|
+
if (result.table && (widgetType == null || widgetType === "" || widgetType === "table")) {
|
|
4879
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WidgetChart, { type: "table", result });
|
|
4810
4880
|
}
|
|
4811
|
-
|
|
4812
|
-
if ((result.notes?.length ?? 0) + (result.blocks?.length ?? 0) > 0) {
|
|
4881
|
+
if (resultId && result.runs && result.runs.length > 0) {
|
|
4813
4882
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4814
|
-
|
|
4883
|
+
RowsResultsChrome,
|
|
4815
4884
|
{
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
noteHref
|
|
4885
|
+
resultId,
|
|
4886
|
+
sessionResult: result,
|
|
4887
|
+
executor,
|
|
4888
|
+
onCaptureRpe,
|
|
4889
|
+
onCaptured
|
|
4822
4890
|
}
|
|
4823
4891
|
);
|
|
4824
4892
|
}
|
|
4825
|
-
if (result.runs && result.runs.length > 0) {
|
|
4826
|
-
|
|
4827
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RowsTable, { result: rowsResult });
|
|
4893
|
+
if (result.runs && (wodWikiWql.isFindQuery(parsed) || result.runs.length > 0)) {
|
|
4894
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RowsTable, { result });
|
|
4828
4895
|
}
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
const sinkAttributes = Object.fromEntries(
|
|
4832
|
-
(result.chart?.filters ?? []).map((f) => [f.key, f.values.map((v) => v.value).join(",")])
|
|
4833
|
-
);
|
|
4834
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-[220px] min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4896
|
+
if (wodWikiWql.isFindQuery(parsed) || (result.notes?.length ?? 0) + (result.blocks?.length ?? 0) + (result.efforts?.length ?? 0) > 0 && (!result.series || result.series.length === 0)) {
|
|
4897
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4835
4898
|
WidgetChart,
|
|
4836
4899
|
{
|
|
4837
|
-
type:
|
|
4838
|
-
result
|
|
4839
|
-
|
|
4840
|
-
|
|
4900
|
+
type: "list",
|
|
4901
|
+
result,
|
|
4902
|
+
onOpenNote,
|
|
4903
|
+
noteHref
|
|
4841
4904
|
}
|
|
4842
|
-
)
|
|
4843
|
-
}
|
|
4844
|
-
if (result.series && result.series.length > 0) {
|
|
4845
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-[220px] min-h-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(AnalyticsChart, { result: toChartResult(result), metric: fallbackLabel }) });
|
|
4905
|
+
);
|
|
4846
4906
|
}
|
|
4847
|
-
|
|
4907
|
+
const sinkHead = result.chart?.head;
|
|
4908
|
+
const effectiveType = widgetType != null && widgetType !== "" ? widgetType : sinkHead ?? "";
|
|
4909
|
+
const sinkAttributes = Object.fromEntries(
|
|
4910
|
+
(result.chart?.filters ?? []).map((f) => [f.key, f.values.map((v) => v.value).join(",")])
|
|
4911
|
+
);
|
|
4912
|
+
const mergedAttributes = { ...sinkAttributes, ...attributes };
|
|
4913
|
+
const needsChartHeight = wodWikiWql.isPipelineQuery(parsed) && (Boolean(effectiveType) || (result.series?.length ?? 0) > 0);
|
|
4914
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: needsChartHeight ? "w-full h-[220px] min-h-[160px]" : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4915
|
+
WidgetChart,
|
|
4916
|
+
{
|
|
4917
|
+
type: effectiveType,
|
|
4918
|
+
result,
|
|
4919
|
+
label: fallbackLabel,
|
|
4920
|
+
attributes: mergedAttributes,
|
|
4921
|
+
inferDefaultShape: effectiveType === "",
|
|
4922
|
+
onOpenNote,
|
|
4923
|
+
noteHref
|
|
4924
|
+
}
|
|
4925
|
+
) });
|
|
4848
4926
|
}
|
|
4849
4927
|
function QueryBlockShell({
|
|
4850
4928
|
children,
|
|
4851
4929
|
onEdit,
|
|
4852
|
-
readOnly
|
|
4930
|
+
readOnly,
|
|
4931
|
+
onAddToDashboard
|
|
4853
4932
|
}) {
|
|
4854
4933
|
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: [
|
|
4855
|
-
onEdit && !readOnly && /* @__PURE__ */ jsxRuntime.
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4934
|
+
(onAddToDashboard || onEdit && !readOnly) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-2 right-2 z-10 flex items-center gap-1", children: [
|
|
4935
|
+
onAddToDashboard && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4936
|
+
"button",
|
|
4937
|
+
{
|
|
4938
|
+
type: "button",
|
|
4939
|
+
onClick: onAddToDashboard,
|
|
4940
|
+
"aria-label": "Add to dashboard",
|
|
4941
|
+
title: "Add to dashboard",
|
|
4942
|
+
"data-testid": "query-add-dashboard",
|
|
4943
|
+
className: "p-1 rounded bg-muted/80 text-muted-foreground hover:text-foreground",
|
|
4944
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChartBar, { className: "w-3.5 h-3.5" })
|
|
4945
|
+
}
|
|
4946
|
+
),
|
|
4947
|
+
onEdit && !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4948
|
+
"button",
|
|
4949
|
+
{
|
|
4950
|
+
type: "button",
|
|
4951
|
+
onClick: onEdit,
|
|
4952
|
+
"aria-label": "Edit query in Omni-Composer",
|
|
4953
|
+
title: "Edit query in Omni-Composer",
|
|
4954
|
+
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",
|
|
4955
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Edit3, { className: "w-3.5 h-3.5" })
|
|
4956
|
+
}
|
|
4957
|
+
)
|
|
4958
|
+
] }),
|
|
4865
4959
|
children
|
|
4866
4960
|
] });
|
|
4867
4961
|
}
|
|
@@ -5273,6 +5367,7 @@ function deriveState(state, rawContent, sourceRevision, lineage, savedVersions,
|
|
|
5273
5367
|
contentId: section.contentId,
|
|
5274
5368
|
queryType: query?.type,
|
|
5275
5369
|
queryError: query?.error,
|
|
5370
|
+
queryAttributes: query?.attributes,
|
|
5276
5371
|
embed: section.embed
|
|
5277
5372
|
};
|
|
5278
5373
|
});
|
|
@@ -8351,22 +8446,26 @@ var cursorFocusExtension = [
|
|
|
8351
8446
|
cursorFocusInternal
|
|
8352
8447
|
];
|
|
8353
8448
|
var ReactQueryBlock = class extends view.WidgetType {
|
|
8354
|
-
constructor(queryText, sectionId, widgetType, widgetError, options) {
|
|
8449
|
+
constructor(queryText, sectionId, widgetType, widgetError, attributes, tokenValues, options) {
|
|
8355
8450
|
super();
|
|
8356
8451
|
this.queryText = queryText;
|
|
8357
8452
|
this.sectionId = sectionId;
|
|
8358
8453
|
this.widgetType = widgetType;
|
|
8359
8454
|
this.widgetError = widgetError;
|
|
8455
|
+
this.attributes = attributes;
|
|
8456
|
+
this.tokenValues = tokenValues;
|
|
8360
8457
|
this.options = options;
|
|
8361
8458
|
}
|
|
8362
8459
|
queryText;
|
|
8363
8460
|
sectionId;
|
|
8364
8461
|
widgetType;
|
|
8365
8462
|
widgetError;
|
|
8463
|
+
attributes;
|
|
8464
|
+
tokenValues;
|
|
8366
8465
|
options;
|
|
8367
8466
|
root = null;
|
|
8368
8467
|
eq(other) {
|
|
8369
|
-
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;
|
|
8468
|
+
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;
|
|
8370
8469
|
}
|
|
8371
8470
|
toDOM(view) {
|
|
8372
8471
|
const container = document.createElement("div");
|
|
@@ -8387,6 +8486,8 @@ var ReactQueryBlock = class extends view.WidgetType {
|
|
|
8387
8486
|
query: this.queryText,
|
|
8388
8487
|
widgetType: this.widgetType,
|
|
8389
8488
|
widgetError: this.widgetError,
|
|
8489
|
+
attributes: this.attributes,
|
|
8490
|
+
tokenValues: this.tokenValues,
|
|
8390
8491
|
readOnly: this.options?.readOnly,
|
|
8391
8492
|
executor: this.options?.executor,
|
|
8392
8493
|
onResultSaved: this.options?.onResultSaved,
|
|
@@ -8414,6 +8515,8 @@ var ReactQueryBlock = class extends view.WidgetType {
|
|
|
8414
8515
|
query: this.queryText,
|
|
8415
8516
|
widgetType: this.widgetType,
|
|
8416
8517
|
widgetError: this.widgetError,
|
|
8518
|
+
attributes: this.attributes,
|
|
8519
|
+
tokenValues: this.tokenValues,
|
|
8417
8520
|
readOnly: this.options?.readOnly,
|
|
8418
8521
|
executor: this.options?.executor,
|
|
8419
8522
|
onResultSaved: this.options?.onResultSaved,
|
|
@@ -8441,8 +8544,11 @@ var ReactQueryBlock = class extends view.WidgetType {
|
|
|
8441
8544
|
};
|
|
8442
8545
|
function buildQueryBlockDecos(state$1, options) {
|
|
8443
8546
|
const builder = new state.RangeSetBuilder();
|
|
8444
|
-
const { sections } = state$1.field(sectionField);
|
|
8547
|
+
const { sections, rawContent: fullRawContent } = state$1.field(sectionField);
|
|
8445
8548
|
const cursor2 = state$1.selection.main.head;
|
|
8549
|
+
const fmMeta = wodWikiCore.parseFrontmatter(fullRawContent).meta;
|
|
8550
|
+
const fmTokens = wodWikiWql.defaultTokenValues(wodWikiWql.extractDashboardTokens(fmMeta));
|
|
8551
|
+
const mergedTokens = { ...fmTokens, ...options?.tokenValues };
|
|
8446
8552
|
for (const section of sections) {
|
|
8447
8553
|
if (section.type !== "query") continue;
|
|
8448
8554
|
if (cursor2 >= section.from && cursor2 <= section.to) continue;
|
|
@@ -8457,6 +8563,8 @@ function buildQueryBlockDecos(state$1, options) {
|
|
|
8457
8563
|
section.id,
|
|
8458
8564
|
section.queryType,
|
|
8459
8565
|
section.queryError,
|
|
8566
|
+
section.queryAttributes,
|
|
8567
|
+
mergedTokens,
|
|
8460
8568
|
options
|
|
8461
8569
|
),
|
|
8462
8570
|
block: true
|
|
@@ -14303,13 +14411,13 @@ function editorPreset(optionsOrDialect = "markdown") {
|
|
|
14303
14411
|
}
|
|
14304
14412
|
|
|
14305
14413
|
// src/version.ts
|
|
14306
|
-
var VERSION = "0.50.
|
|
14307
|
-
var GIT_SHA = "
|
|
14308
|
-
var BUILD_TIME = "2026-11-
|
|
14414
|
+
var VERSION = "0.50.2190";
|
|
14415
|
+
var GIT_SHA = "9ee7872";
|
|
14416
|
+
var BUILD_TIME = "2026-11-01T23:32:46.829Z";
|
|
14309
14417
|
var SEMVER = {
|
|
14310
|
-
version: "0.50.
|
|
14311
|
-
gitSha: "
|
|
14312
|
-
buildTime: "2026-11-
|
|
14418
|
+
version: "0.50.2190",
|
|
14419
|
+
gitSha: "9ee7872",
|
|
14420
|
+
buildTime: "2026-11-01T23:32:46.829Z"
|
|
14313
14421
|
};
|
|
14314
14422
|
|
|
14315
14423
|
Object.defineProperty(exports, "CONTENT_GROUPING_DIMENSIONS", {
|
|
@@ -14391,6 +14499,7 @@ exports.cn = cn;
|
|
|
14391
14499
|
exports.compactNumber = compactNumber;
|
|
14392
14500
|
exports.composerRegistry = composerRegistry;
|
|
14393
14501
|
exports.configureOverlayActions = configureOverlayActions;
|
|
14502
|
+
exports.createExecutorDocumentHost = createExecutorDocumentHost;
|
|
14394
14503
|
exports.cursorFocusExtension = cursorFocusExtension;
|
|
14395
14504
|
exports.customCompletionSources = customCompletionSources;
|
|
14396
14505
|
exports.dateRangeSlot = dateRangeSlot;
|
|
@@ -14447,6 +14556,7 @@ exports.nestedCompletion = nestedCompletion;
|
|
|
14447
14556
|
exports.nestedCompletionOptions = nestedCompletionOptions;
|
|
14448
14557
|
exports.normalizeOutputFilter = normalizeOutputFilter;
|
|
14449
14558
|
exports.notebookSlugsFromBlocks = notebookSlugsFromBlocks;
|
|
14559
|
+
exports.outputToRunResult = outputToRunResult;
|
|
14450
14560
|
exports.patchBlockQuery = patchBlockQuery;
|
|
14451
14561
|
exports.presentBadges = presentBadges;
|
|
14452
14562
|
exports.previewDecorations = previewDecorations;
|
|
@@ -14479,6 +14589,7 @@ exports.summarizeAggregate = summarizeAggregate;
|
|
|
14479
14589
|
exports.summarizeFind = summarizeFind;
|
|
14480
14590
|
exports.summarizePipeline = summarizePipeline;
|
|
14481
14591
|
exports.tagsFromStaticBlocks = tagsFromStaticBlocks;
|
|
14592
|
+
exports.toChartResult = toChartResult;
|
|
14482
14593
|
exports.toggleWidgetEdit = toggleWidgetEdit;
|
|
14483
14594
|
exports.tooltipTimestamp = tooltipTimestamp;
|
|
14484
14595
|
exports.urlAtPos = urlAtPos;
|