@bitcobblers/wod-wiki-ui 0.48.2176 → 0.49.2177
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-6NFNCUZU.mjs → chunk-2XY6AZR6.mjs} +480 -162
- package/dist/chunk-2XY6AZR6.mjs.map +1 -0
- package/dist/extensions/index.cjs +477 -159
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.mjs +1 -1
- package/dist/index.cjs +483 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -8
- package/dist/index.d.ts +15 -8
- package/dist/index.mjs +8 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-6NFNCUZU.mjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -2555,7 +2555,7 @@ function InlineClauseEditor({
|
|
|
2555
2555
|
const meta = getClauseMeta(clause2.type);
|
|
2556
2556
|
const current = clause2.value.trim();
|
|
2557
2557
|
const typedIdx = filteredItems.length;
|
|
2558
|
-
const shownValues = selectedValues
|
|
2558
|
+
const shownValues = selectedValues;
|
|
2559
2559
|
const reorder = (i, dir) => {
|
|
2560
2560
|
if (!onReorder) return;
|
|
2561
2561
|
const to = i + dir;
|
|
@@ -2567,24 +2567,15 @@ function InlineClauseEditor({
|
|
|
2567
2567
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2568
2568
|
"div",
|
|
2569
2569
|
{
|
|
2570
|
-
className: "
|
|
2570
|
+
className: "min-w-0 pt-0.5",
|
|
2571
2571
|
"data-testid": "wql-clause-editor",
|
|
2572
2572
|
"data-clause-type": clause2.type,
|
|
2573
2573
|
children: [
|
|
2574
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
2575
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "text-[11px]", children: meta.icon }),
|
|
2576
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-[11px] font-semibold text-foreground font-mono", children: meta.label }),
|
|
2577
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "hidden sm:block ml-auto text-[10px] text-muted-foreground/70 font-mono truncate", children: [
|
|
2578
|
-
"\u2191\u2193 move \xB7 Enter ",
|
|
2579
|
-
isMulti ? "add/remove" : "set",
|
|
2580
|
-
" \xB7 Esc done \xB7 Tab exits"
|
|
2581
|
-
] })
|
|
2582
|
-
] }),
|
|
2583
|
-
shownValues.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("px-2 pb-1.5", isMulti && "border-b border-border/50"), children: [
|
|
2574
|
+
isMulti && shownValues.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border/50 px-2 pb-1.5", children: [
|
|
2584
2575
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1.5 sm:gap-1 max-h-24 overflow-y-auto overscroll-contain touch-pan-y sm:max-h-none sm:overflow-visible", children: shownValues.map((v, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2585
2576
|
"span",
|
|
2586
2577
|
{
|
|
2587
|
-
className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-primary/
|
|
2578
|
+
className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-primary/15 text-primary text-xs sm:text-[10px] font-mono min-h-8 sm:min-h-0",
|
|
2588
2579
|
children: [
|
|
2589
2580
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-40 truncate", children: v }),
|
|
2590
2581
|
onReorder && shownValues.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -2634,7 +2625,7 @@ function InlineClauseEditor({
|
|
|
2634
2625
|
role: "listbox",
|
|
2635
2626
|
"aria-label": `${meta.label} options`,
|
|
2636
2627
|
"aria-multiselectable": isMulti || void 0,
|
|
2637
|
-
className: "max-h-[min(
|
|
2628
|
+
className: "max-h-[min(38svh,16rem)] sm:max-h-36 overflow-y-auto overscroll-contain touch-pan-y flex flex-col gap-0.5 pt-1",
|
|
2638
2629
|
children: [
|
|
2639
2630
|
canCommitTyped && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2640
2631
|
"button",
|
|
@@ -2648,19 +2639,19 @@ function InlineClauseEditor({
|
|
|
2648
2639
|
onClick: () => onCommitTyped(typedValue),
|
|
2649
2640
|
"data-testid": `clause-commit-typed-${clause2.type}`,
|
|
2650
2641
|
className: cn(
|
|
2651
|
-
"flex items-center justify-between px-2 py-2 sm:py-1 text-sm sm:text-xs text-left rounded hover:bg-muted/60 transition-colors font-mono min-h-
|
|
2652
|
-
highlightIdx === typedIdx && "bg-muted/
|
|
2642
|
+
"flex items-center justify-between px-2.5 py-2 sm:py-1.5 text-sm sm:text-xs text-left rounded-md hover:bg-muted/60 transition-colors font-mono min-h-11 sm:min-h-0",
|
|
2643
|
+
highlightIdx === typedIdx && "bg-muted/70 ring-1 ring-border"
|
|
2653
2644
|
),
|
|
2654
2645
|
children: [
|
|
2655
2646
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "truncate", children: [
|
|
2656
2647
|
"Search for ",
|
|
2657
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold", children: [
|
|
2648
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-foreground", children: [
|
|
2658
2649
|
"\u201C",
|
|
2659
2650
|
typedValue,
|
|
2660
2651
|
"\u201D"
|
|
2661
2652
|
] })
|
|
2662
2653
|
] }),
|
|
2663
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/60 ml-1 shrink-0", children: "\u21B5" })
|
|
2654
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/60 ml-1 shrink-0 font-sans text-xs", children: "\u21B5" })
|
|
2664
2655
|
]
|
|
2665
2656
|
}
|
|
2666
2657
|
),
|
|
@@ -2679,29 +2670,39 @@ function InlineClauseEditor({
|
|
|
2679
2670
|
onMouseEnter: () => onHighlight(idx),
|
|
2680
2671
|
onClick: () => onCommitValue(item.value),
|
|
2681
2672
|
className: cn(
|
|
2682
|
-
"flex items-center justify-between px-2 py-2 sm:py-1 text-sm sm:text-xs text-left rounded transition-colors
|
|
2683
|
-
active ? "bg-primary/
|
|
2684
|
-
selected && "text-primary"
|
|
2673
|
+
"flex items-center justify-between px-2.5 py-2 sm:py-1.5 text-sm sm:text-xs text-left rounded-md transition-colors min-h-11 sm:min-h-0",
|
|
2674
|
+
active ? "bg-primary/10 text-foreground font-medium" : "hover:bg-muted/60 text-muted-foreground hover:text-foreground",
|
|
2675
|
+
selected && "text-primary font-medium"
|
|
2685
2676
|
),
|
|
2686
2677
|
children: [
|
|
2687
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2688
|
-
|
|
2678
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-2 min-w-0 flex-1", children: [
|
|
2679
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: item.label }),
|
|
2680
|
+
item.label !== item.value && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "font-mono text-[11px] text-muted-foreground/70 shrink-0", children: item.value })
|
|
2681
|
+
] }),
|
|
2682
|
+
selected && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-3.5 h-3.5 text-primary shrink-0 ml-1.5" })
|
|
2689
2683
|
]
|
|
2690
2684
|
},
|
|
2691
2685
|
item.value
|
|
2692
2686
|
);
|
|
2693
2687
|
}),
|
|
2694
|
-
emptyText && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-2
|
|
2688
|
+
emptyText && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2.5 py-2 text-sm sm:text-xs text-muted-foreground italic", children: emptyText })
|
|
2695
2689
|
]
|
|
2696
2690
|
}
|
|
2697
2691
|
),
|
|
2698
|
-
|
|
2692
|
+
(filteredItems.length > 0 || canCommitTyped) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden sm:flex items-center justify-between px-2 pt-2 text-[10px] text-muted-foreground/70 font-mono border-t border-border/40 mt-1", children: [
|
|
2693
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2694
|
+
"\u2191\u2193 choose \xB7 Enter ",
|
|
2695
|
+
isMulti ? "toggle" : "set"
|
|
2696
|
+
] }),
|
|
2697
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tab next segment \xB7 Esc close" })
|
|
2698
|
+
] }),
|
|
2699
|
+
isMulti && onDone && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2 flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2699
2700
|
"button",
|
|
2700
2701
|
{
|
|
2701
2702
|
type: "button",
|
|
2702
2703
|
onClick: onDone,
|
|
2703
2704
|
"data-testid": "wql-clause-editor-done",
|
|
2704
|
-
className: "inline-flex w-full sm:w-auto items-center justify-center min-h-
|
|
2705
|
+
className: "inline-flex w-full sm:w-auto items-center justify-center min-h-10 sm:min-h-7 px-3 rounded-md bg-primary text-primary-foreground text-xs font-semibold hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
2705
2706
|
children: [
|
|
2706
2707
|
"Done",
|
|
2707
2708
|
shownValues.length > 0 ? ` \xB7 ${shownValues.length} selected` : ""
|
|
@@ -2740,7 +2741,11 @@ var STATIC_OPTIONS = {
|
|
|
2740
2741
|
groupby: GROUPBY_OPTIONS,
|
|
2741
2742
|
metric: METRIC_OPTIONS,
|
|
2742
2743
|
unit: UNIT_OPTIONS,
|
|
2743
|
-
intensity: wodWikiWql.WQL_INTENSITY_TIERS.map((v) => ({ value: v, label: v }))
|
|
2744
|
+
intensity: wodWikiWql.WQL_INTENSITY_TIERS.map((v) => ({ value: v, label: v })),
|
|
2745
|
+
subscribed: [
|
|
2746
|
+
{ value: "true", label: "Subscribed" },
|
|
2747
|
+
{ value: "false", label: "All / unsubscribed" }
|
|
2748
|
+
]
|
|
2744
2749
|
};
|
|
2745
2750
|
function tagsFromStaticBlocks(blocks) {
|
|
2746
2751
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -3038,7 +3043,7 @@ function WqlDiagnosticsStrip({
|
|
|
3038
3043
|
"aria-live": "polite",
|
|
3039
3044
|
className: cn(
|
|
3040
3045
|
"flex flex-wrap items-center justify-between gap-x-4 gap-y-1.5 px-3 py-1.5 text-xs font-mono transition-colors",
|
|
3041
|
-
header ? valid ? "border-b border-
|
|
3046
|
+
header ? valid ? "border-b border-border/60 bg-muted/20 text-muted-foreground" : "border-b border-destructive/40 bg-destructive/5 text-destructive" : cn(
|
|
3042
3047
|
"rounded-lg border",
|
|
3043
3048
|
valid ? "bg-muted/30 border-border text-muted-foreground" : "bg-destructive/5 border-destructive/30 text-destructive"
|
|
3044
3049
|
),
|
|
@@ -3432,23 +3437,128 @@ var completionIcons = {
|
|
|
3432
3437
|
value: server.renderToStaticMarkup(React2.createElement(lucideReact.Tag, { size: 16 }))
|
|
3433
3438
|
};
|
|
3434
3439
|
var SLOT_NODES = { Head: true, Filter: true, TagValue: true, Rollup: true };
|
|
3440
|
+
var activeSegmentEffect = state.StateEffect.define();
|
|
3441
|
+
var activeSegmentField = state.StateField.define({
|
|
3442
|
+
create: () => view.Decoration.none,
|
|
3443
|
+
update(decorations, transaction) {
|
|
3444
|
+
const mapped = decorations.map(transaction.changes);
|
|
3445
|
+
for (const effect of transaction.effects) {
|
|
3446
|
+
if (!effect.is(activeSegmentEffect)) continue;
|
|
3447
|
+
const range = effect.value;
|
|
3448
|
+
if (!range || range.from >= range.to) return view.Decoration.none;
|
|
3449
|
+
return view.Decoration.set([view.Decoration.mark({ class: "wql-active-segment" }).range(range.from, range.to)]);
|
|
3450
|
+
}
|
|
3451
|
+
return mapped;
|
|
3452
|
+
},
|
|
3453
|
+
provide: (field) => view.EditorView.decorations.from(field)
|
|
3454
|
+
});
|
|
3455
|
+
function findClauseRange(state, clause2) {
|
|
3456
|
+
if (!clause2) return void 0;
|
|
3457
|
+
let range;
|
|
3458
|
+
const tree = language.syntaxTree(state);
|
|
3459
|
+
if (clause2.filterIndex !== void 0) {
|
|
3460
|
+
let index = 0;
|
|
3461
|
+
tree.iterate({
|
|
3462
|
+
enter: (node) => {
|
|
3463
|
+
if (node.name === "Filter") {
|
|
3464
|
+
if (index === clause2.filterIndex) {
|
|
3465
|
+
range = { from: node.from, to: node.to };
|
|
3466
|
+
return false;
|
|
3467
|
+
}
|
|
3468
|
+
index++;
|
|
3469
|
+
}
|
|
3470
|
+
return true;
|
|
3471
|
+
}
|
|
3472
|
+
});
|
|
3473
|
+
return range;
|
|
3474
|
+
}
|
|
3475
|
+
if (["kind", "target", "agg", "metric"].includes(clause2.type)) {
|
|
3476
|
+
tree.iterate({
|
|
3477
|
+
enter: (node) => {
|
|
3478
|
+
if (node.name === "Head") {
|
|
3479
|
+
range = { from: node.from, to: node.to };
|
|
3480
|
+
return false;
|
|
3481
|
+
}
|
|
3482
|
+
return true;
|
|
3483
|
+
}
|
|
3484
|
+
});
|
|
3485
|
+
return range;
|
|
3486
|
+
}
|
|
3487
|
+
if (clause2.type === "groupby") {
|
|
3488
|
+
tree.iterate({
|
|
3489
|
+
enter: (node) => {
|
|
3490
|
+
if (node.name === "GroupBy") {
|
|
3491
|
+
range = { from: node.from, to: node.to };
|
|
3492
|
+
return false;
|
|
3493
|
+
}
|
|
3494
|
+
return true;
|
|
3495
|
+
}
|
|
3496
|
+
});
|
|
3497
|
+
return range;
|
|
3498
|
+
}
|
|
3499
|
+
if (clause2.type === "rollup") {
|
|
3500
|
+
tree.iterate({
|
|
3501
|
+
enter: (node) => {
|
|
3502
|
+
if (node.name === "Rollup") {
|
|
3503
|
+
range = { from: node.from, to: node.to };
|
|
3504
|
+
return false;
|
|
3505
|
+
}
|
|
3506
|
+
return true;
|
|
3507
|
+
}
|
|
3508
|
+
});
|
|
3509
|
+
return range;
|
|
3510
|
+
}
|
|
3511
|
+
if (clause2.type === "time") {
|
|
3512
|
+
const doc = state.doc.toString();
|
|
3513
|
+
const match = /\b(last\s+\d+[dw]|from\s+\S+(?:\s+to\s+\S+)?)/i.exec(doc);
|
|
3514
|
+
if (match) return { from: match.index, to: match.index + match[0].length };
|
|
3515
|
+
}
|
|
3516
|
+
return void 0;
|
|
3517
|
+
}
|
|
3435
3518
|
function slotPositions(state) {
|
|
3436
3519
|
const slots = [];
|
|
3437
3520
|
language.syntaxTree(state).iterate({
|
|
3438
3521
|
enter: (node) => {
|
|
3439
3522
|
if (SLOT_NODES[node.name]) slots.push(node.from);
|
|
3440
|
-
else if (node.name === "Word" && node.node.parent?.name
|
|
3523
|
+
else if (node.name === "Word" && ["GroupBy", "Dimension"].includes(node.node.parent?.name ?? "")) slots.push(node.from);
|
|
3441
3524
|
return true;
|
|
3442
3525
|
}
|
|
3443
3526
|
});
|
|
3444
3527
|
return slots.sort((a, b) => a - b);
|
|
3445
3528
|
}
|
|
3446
|
-
function
|
|
3529
|
+
function activateSlot(view, position, onActivate) {
|
|
3530
|
+
if (!onActivate) return;
|
|
3531
|
+
let node = language.syntaxTree(view.state).resolveInner(position, 1);
|
|
3532
|
+
while (node.parent && !["Head", "Filter", "GroupBy", "Rollup"].includes(node.name)) node = node.parent;
|
|
3533
|
+
if (!["Head", "Filter", "GroupBy", "Rollup"].includes(node.name)) return;
|
|
3534
|
+
let filterIndex;
|
|
3535
|
+
if (node.name === "Filter") {
|
|
3536
|
+
filterIndex = 0;
|
|
3537
|
+
language.syntaxTree(view.state).iterate({
|
|
3538
|
+
enter: (candidate) => {
|
|
3539
|
+
if (candidate.name === "Filter") {
|
|
3540
|
+
if (candidate.from === node.from) return false;
|
|
3541
|
+
if (candidate.from < node.from) filterIndex += 1;
|
|
3542
|
+
}
|
|
3543
|
+
return true;
|
|
3544
|
+
}
|
|
3545
|
+
});
|
|
3546
|
+
}
|
|
3547
|
+
let text = view.state.sliceDoc(node.from, node.to);
|
|
3548
|
+
if (node.name === "Head") {
|
|
3549
|
+
const line = view.state.doc.lineAt(position);
|
|
3550
|
+
const word = Array.from(line.text.matchAll(/[\w.*-]+/g)).find((match) => line.from + match.index <= position && position <= line.from + match.index + match[0].length);
|
|
3551
|
+
if (word) text = word[0];
|
|
3552
|
+
}
|
|
3553
|
+
onActivate({ node: node.name, filterIndex, from: node.from, to: node.to, text });
|
|
3554
|
+
}
|
|
3555
|
+
function advanceSlot(view, dir, onActivate) {
|
|
3447
3556
|
const head = view.state.selection.main.head;
|
|
3448
3557
|
const slots = slotPositions(view.state);
|
|
3449
3558
|
const next = dir > 0 ? slots.find((slot) => slot > head) : [...slots].reverse().find((slot) => slot < head);
|
|
3450
3559
|
if (next === void 0) return false;
|
|
3451
3560
|
view.dispatch({ selection: { anchor: next }, scrollIntoView: true });
|
|
3561
|
+
activateSlot(view, next, onActivate);
|
|
3452
3562
|
return true;
|
|
3453
3563
|
}
|
|
3454
3564
|
function wqlLint(view) {
|
|
@@ -3491,7 +3601,7 @@ function wqlLint(view) {
|
|
|
3491
3601
|
});
|
|
3492
3602
|
return out;
|
|
3493
3603
|
}
|
|
3494
|
-
function wqlEditorKeymap(onSubmit, onEscape) {
|
|
3604
|
+
function wqlEditorKeymap(onSubmit, onEscape, onSlotActivate) {
|
|
3495
3605
|
return [
|
|
3496
3606
|
{ key: "Mod-Enter", run: () => {
|
|
3497
3607
|
onSubmit();
|
|
@@ -3515,7 +3625,7 @@ function wqlEditorKeymap(onSubmit, onEscape) {
|
|
|
3515
3625
|
run: (view) => {
|
|
3516
3626
|
if (view.compositionStarted) return false;
|
|
3517
3627
|
const accepted = autocomplete.acceptCompletion(view);
|
|
3518
|
-
return advanceSlot(view, 1) || accepted;
|
|
3628
|
+
return advanceSlot(view, 1, onSlotActivate) || accepted;
|
|
3519
3629
|
}
|
|
3520
3630
|
},
|
|
3521
3631
|
{
|
|
@@ -3523,7 +3633,7 @@ function wqlEditorKeymap(onSubmit, onEscape) {
|
|
|
3523
3633
|
run: (view) => {
|
|
3524
3634
|
if (view.compositionStarted) return false;
|
|
3525
3635
|
const accepted = autocomplete.acceptCompletion(view);
|
|
3526
|
-
return advanceSlot(view, -1) || accepted;
|
|
3636
|
+
return advanceSlot(view, -1, onSlotActivate) || accepted;
|
|
3527
3637
|
}
|
|
3528
3638
|
},
|
|
3529
3639
|
{
|
|
@@ -3542,11 +3652,11 @@ function wqlEditorKeymap(onSubmit, onEscape) {
|
|
|
3542
3652
|
...commands.historyKeymap
|
|
3543
3653
|
];
|
|
3544
3654
|
}
|
|
3545
|
-
function WqlTextEditor({ value, onChange, onSubmit, onEscape, placeholder, autoFocus = false, dense = false }) {
|
|
3655
|
+
function WqlTextEditor({ value, onChange, onSubmit, onEscape, placeholder, autoFocus = false, dense = false, onSlotActivate, activeRange, activeClause, className }) {
|
|
3546
3656
|
const host = React2.useRef(null);
|
|
3547
3657
|
const view$1 = React2.useRef(void 0);
|
|
3548
|
-
const callbacks = React2.useRef({ onChange, onSubmit, onEscape });
|
|
3549
|
-
callbacks.current = { onChange, onSubmit, onEscape };
|
|
3658
|
+
const callbacks = React2.useRef({ onChange, onSubmit, onEscape, onSlotActivate });
|
|
3659
|
+
callbacks.current = { onChange, onSubmit, onEscape, onSlotActivate };
|
|
3550
3660
|
const replacing = React2.useRef(false);
|
|
3551
3661
|
const initialValue = React2.useRef(value);
|
|
3552
3662
|
React2.useEffect(() => {
|
|
@@ -3563,6 +3673,7 @@ function WqlTextEditor({ value, onChange, onSubmit, onEscape, placeholder, autoF
|
|
|
3563
3673
|
language.syntaxHighlighting(wodWikiWql.wqlHighlightStyle),
|
|
3564
3674
|
commands.history(),
|
|
3565
3675
|
view.EditorView.lineWrapping,
|
|
3676
|
+
activeSegmentField,
|
|
3566
3677
|
...placeholder ? [view.placeholder(placeholder)] : [],
|
|
3567
3678
|
view.EditorView.contentAttributes.of({ "aria-label": "WQL", "data-testid": "wql-text-input" }),
|
|
3568
3679
|
autocomplete.autocompletion({
|
|
@@ -3583,11 +3694,12 @@ function WqlTextEditor({ value, onChange, onSubmit, onEscape, placeholder, autoF
|
|
|
3583
3694
|
lint.linter(wqlLint),
|
|
3584
3695
|
view.keymap.of(wqlEditorKeymap(
|
|
3585
3696
|
() => callbacks.current.onSubmit(),
|
|
3586
|
-
() => callbacks.current.onEscape()
|
|
3697
|
+
() => callbacks.current.onEscape(),
|
|
3698
|
+
(slot) => callbacks.current.onSlotActivate?.(slot)
|
|
3587
3699
|
)),
|
|
3588
3700
|
view.EditorView.domEventHandlers({
|
|
3589
|
-
//
|
|
3590
|
-
//
|
|
3701
|
+
// Host composers open the contextual writer; standalone editors
|
|
3702
|
+
// retain token selection and in-row completion.
|
|
3591
3703
|
mouseup: (event, editor2) => {
|
|
3592
3704
|
if (event.button !== 0) return false;
|
|
3593
3705
|
let { from, to } = editor2.state.selection.main;
|
|
@@ -3598,11 +3710,18 @@ function WqlTextEditor({ value, onChange, onSubmit, onEscape, placeholder, autoF
|
|
|
3598
3710
|
from = line.from + word.index;
|
|
3599
3711
|
to = from + word[0].length;
|
|
3600
3712
|
let node = language.syntaxTree(editor2.state).resolveInner(to, -1);
|
|
3601
|
-
while (node.parent && !["Head", "Filter"].includes(node.name)) node = node.parent;
|
|
3602
|
-
if (!["Head", "Filter"].includes(node.name)) return false;
|
|
3603
|
-
|
|
3713
|
+
while (node.parent && !["Head", "Filter", "GroupBy", "Rollup"].includes(node.name)) node = node.parent;
|
|
3714
|
+
if (!["Head", "Filter", "GroupBy", "Rollup"].includes(node.name)) return false;
|
|
3715
|
+
if (!callbacks.current.onSlotActivate) {
|
|
3716
|
+
editor2.dispatch({ selection: { anchor: from, head: to } });
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
if (callbacks.current.onSlotActivate) {
|
|
3720
|
+
autocomplete.closeCompletion(editor2);
|
|
3721
|
+
activateSlot(editor2, from, (slot) => callbacks.current.onSlotActivate?.(slot));
|
|
3722
|
+
} else {
|
|
3723
|
+
autocomplete.startCompletion(editor2);
|
|
3604
3724
|
}
|
|
3605
|
-
autocomplete.startCompletion(editor2);
|
|
3606
3725
|
return false;
|
|
3607
3726
|
},
|
|
3608
3727
|
keydown: (event, editor2) => {
|
|
@@ -3622,7 +3741,8 @@ function WqlTextEditor({ value, onChange, onSubmit, onEscape, placeholder, autoF
|
|
|
3622
3741
|
'.cm-line span[class*="tok-"]:hover, .cm-line span[class^="tok-"]:hover': { fontWeight: "700", textShadow: "0 0 0.5px currentColor", cursor: "pointer" },
|
|
3623
3742
|
".cm-scroller": { overflow: "auto" },
|
|
3624
3743
|
".cm-placeholder": { color: "hsl(var(--muted-foreground))" },
|
|
3625
|
-
".wql-completion-icon": { display: "inline-flex", flexShrink: "0", color: "hsl(var(--primary))" }
|
|
3744
|
+
".wql-completion-icon": { display: "inline-flex", flexShrink: "0", color: "hsl(var(--primary))" },
|
|
3745
|
+
".wql-active-segment": { backgroundColor: "hsl(var(--primary) / 0.16)", boxShadow: "inset 0 -2px hsl(var(--primary))", borderRadius: "4px", padding: "1px 2px", margin: "0 -2px", fontWeight: "600" }
|
|
3626
3746
|
}),
|
|
3627
3747
|
autocompleteTooltipTheme
|
|
3628
3748
|
]
|
|
@@ -3642,7 +3762,13 @@ function WqlTextEditor({ value, onChange, onSubmit, onEscape, placeholder, autoF
|
|
|
3642
3762
|
editor.dispatch({ changes: { from: 0, to: editor.state.doc.length, insert: value } });
|
|
3643
3763
|
replacing.current = false;
|
|
3644
3764
|
}, [value]);
|
|
3645
|
-
|
|
3765
|
+
React2.useEffect(() => {
|
|
3766
|
+
const editor = view$1.current;
|
|
3767
|
+
if (!editor) return;
|
|
3768
|
+
const resolvedRange = activeRange ?? findClauseRange(editor.state, activeClause);
|
|
3769
|
+
editor.dispatch({ effects: activeSegmentEffect.of(resolvedRange ?? null) });
|
|
3770
|
+
}, [activeRange, activeClause, value]);
|
|
3771
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: host, className: className ?? "min-w-0 w-full rounded-lg border border-border bg-background focus-within:ring-2 focus-within:ring-ring", "data-testid": "wql-text-editor" });
|
|
3646
3772
|
}
|
|
3647
3773
|
function WqlComposer({
|
|
3648
3774
|
initialQuery,
|
|
@@ -3664,7 +3790,8 @@ function WqlComposer({
|
|
|
3664
3790
|
preferredChoices,
|
|
3665
3791
|
autoFocus = false,
|
|
3666
3792
|
placeholder = "Search text or enter WQL",
|
|
3667
|
-
className
|
|
3793
|
+
className,
|
|
3794
|
+
segmentEditRequest
|
|
3668
3795
|
}) {
|
|
3669
3796
|
const [desktop, setDesktop] = React2.useState(false);
|
|
3670
3797
|
const [base, setBase] = React2.useState(query ?? initialQuery ?? ":note");
|
|
@@ -3746,7 +3873,7 @@ function WqlComposer({
|
|
|
3746
3873
|
}, [autoFocus]);
|
|
3747
3874
|
React2.useEffect(() => {
|
|
3748
3875
|
if (active.kind === "value") pickerRef.current?.focus();
|
|
3749
|
-
}, [active
|
|
3876
|
+
}, [active]);
|
|
3750
3877
|
React2.useEffect(() => {
|
|
3751
3878
|
if (highlight >= 0) document.getElementById(`${listId}-option-${highlight}`)?.scrollIntoView?.({ block: "nearest" });
|
|
3752
3879
|
}, [highlight, listId]);
|
|
@@ -3772,14 +3899,14 @@ function WqlComposer({
|
|
|
3772
3899
|
if (openerRef.current?.isConnected) openerRef.current.focus();
|
|
3773
3900
|
else inputRef.current?.focus();
|
|
3774
3901
|
};
|
|
3775
|
-
const openEditor = (clause2) => {
|
|
3902
|
+
const openEditor = (clause2, range) => {
|
|
3776
3903
|
if (pending && currentRef.current.valid) commit(currentRef.current);
|
|
3777
3904
|
openerRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
3778
3905
|
if (clause2.type === "where" || clause2.type === "pipes") {
|
|
3779
3906
|
setActive({ kind: "wql" });
|
|
3780
3907
|
commit(currentRef.current);
|
|
3781
3908
|
} else {
|
|
3782
|
-
setActive({ kind: "value", clause: clause2 });
|
|
3909
|
+
setActive({ kind: "value", clause: clause2, range });
|
|
3783
3910
|
setSearch("");
|
|
3784
3911
|
}
|
|
3785
3912
|
setHighlight(-1);
|
|
@@ -3790,6 +3917,24 @@ function WqlComposer({
|
|
|
3790
3917
|
if (pending) commit(resolveQueryDraft(base));
|
|
3791
3918
|
openEditor(existing ?? { id: `new-${type}`, type, ...getClauseMeta(type), value: "" });
|
|
3792
3919
|
};
|
|
3920
|
+
const openFieldRef = React2.useRef(openField);
|
|
3921
|
+
openFieldRef.current = openField;
|
|
3922
|
+
React2.useEffect(() => {
|
|
3923
|
+
if (segmentEditRequest) openFieldRef.current(segmentEditRequest.type);
|
|
3924
|
+
}, [segmentEditRequest]);
|
|
3925
|
+
const activateWqlSlot = (slot) => {
|
|
3926
|
+
const clause2 = slot.filterIndex !== void 0 ? pills.find((pill) => pill.filterIndex === slot.filterIndex) : slot.node === "GroupBy" ? pills.find((pill) => pill.type === "groupby") : slot.node === "Rollup" ? pills.find((pill) => pill.type === "rollup") : slot.node === "Head" ? pills.find((pill) => ["kind", "target", "agg", "metric"].includes(pill.type) && pill.value === slot.text) : void 0;
|
|
3927
|
+
if (clause2) openEditor(clause2, { from: slot.from, to: slot.to });
|
|
3928
|
+
};
|
|
3929
|
+
const moveEditor = (direction) => {
|
|
3930
|
+
if (active.kind !== "value") return false;
|
|
3931
|
+
const visible = pills.filter((pill) => !hidden.has(pill.type));
|
|
3932
|
+
const index = visible.findIndex((pill) => pill.id === active.clause.id);
|
|
3933
|
+
const next = visible[index + direction];
|
|
3934
|
+
if (!next) return false;
|
|
3935
|
+
openEditor(next);
|
|
3936
|
+
return true;
|
|
3937
|
+
};
|
|
3793
3938
|
const updateClause = (clause2, value) => {
|
|
3794
3939
|
if (clause2.type === "kind" || clause2.type === "target") {
|
|
3795
3940
|
const next2 = pivotQuery(currentRef.current.wql, clause2.type, value ?? "");
|
|
@@ -3841,6 +3986,13 @@ function WqlComposer({
|
|
|
3841
3986
|
onSubmit?.(draft.wql);
|
|
3842
3987
|
};
|
|
3843
3988
|
const handleKeys = (event) => {
|
|
3989
|
+
if (active.kind === "value" && event.key === "Tab" && !event.nativeEvent.isComposing) {
|
|
3990
|
+
if (moveEditor(event.shiftKey ? -1 : 1)) {
|
|
3991
|
+
event.preventDefault();
|
|
3992
|
+
event.stopPropagation();
|
|
3993
|
+
}
|
|
3994
|
+
return;
|
|
3995
|
+
}
|
|
3844
3996
|
if (event.nativeEvent.isComposing) return;
|
|
3845
3997
|
if (event.key === "Enter" && (event.ctrlKey || event.metaKey)) {
|
|
3846
3998
|
event.preventDefault();
|
|
@@ -3905,119 +4057,285 @@ function WqlComposer({
|
|
|
3905
4057
|
diagnosticsActions
|
|
3906
4058
|
] });
|
|
3907
4059
|
const diagnostics = { ...resolved, valid: resolved.valid && !error, error: error ?? resolved.error };
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
commit(resolveQueryDraft(undo));
|
|
3947
|
-
setUndo(void 0);
|
|
3948
|
-
}, className: cn("rounded-lg", desktop && compact ? "min-h-9 px-2.5 text-xs text-muted-foreground hover:text-foreground" : "min-h-12 px-3"), children: "Undo removal" })
|
|
3949
|
-
] }),
|
|
3950
|
-
active.kind === "value" && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": "wql-field-picker", className: "min-w-0 rounded-xl border border-border p-2 focus-within:ring-2 focus-within:ring-ring", onKeyDown: (event) => {
|
|
3951
|
-
if (event.key === "Escape" || event.key === "Enter" && (event.ctrlKey || event.metaKey)) handleKeys(event);
|
|
3952
|
-
}, children: [
|
|
3953
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: closeEditor, className: "min-h-12 px-3", children: "Back" }),
|
|
3954
|
-
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block text-sm", children: [
|
|
3955
|
-
"Search ",
|
|
3956
|
-
getClauseMeta(active.clause.type).label,
|
|
3957
|
-
/* @__PURE__ */ jsxRuntime.jsx("input", { ref: pickerRef, type: "search", role: "combobox", "aria-label": `Search ${getClauseMeta(active.clause.type).label}`, "aria-controls": listId, "aria-expanded": "true", "aria-activedescendant": highlight >= 0 ? `${listId}-option-${highlight}` : void 0, value: search, onChange: (event) => {
|
|
3958
|
-
setSearch(event.target.value);
|
|
3959
|
-
setHighlight(-1);
|
|
3960
|
-
setError(void 0);
|
|
3961
|
-
}, onKeyDown: handleKeys, className: "min-h-12 w-full rounded border border-border bg-background px-3 text-base", "data-testid": "wql-picker-search" })
|
|
3962
|
-
] }),
|
|
3963
|
-
active.kind === "value" && active.clause.filterIndex !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
3964
|
-
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-h-12 items-center gap-2", children: [
|
|
3965
|
-
/* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", checked: active.clause.negate ?? false, onChange: (event) => updateClause({ ...active.clause, negate: event.target.checked }, active.clause.value) }),
|
|
3966
|
-
"Exclude"
|
|
4060
|
+
const visiblePills = pills.filter((pill) => !hidden.has(pill.type));
|
|
4061
|
+
const activePillIndex = active.kind === "value" ? visiblePills.findIndex((pill) => pill.id === active.clause.id) : -1;
|
|
4062
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4063
|
+
"div",
|
|
4064
|
+
{
|
|
4065
|
+
className: cn(
|
|
4066
|
+
"min-w-0",
|
|
4067
|
+
compact ? "flex flex-col overflow-hidden rounded-xl border border-border bg-card shadow-xs transition-shadow focus-within:ring-2 focus-within:ring-ring" : "space-y-2",
|
|
4068
|
+
className
|
|
4069
|
+
),
|
|
4070
|
+
"data-testid": "wql-composer-root",
|
|
4071
|
+
children: [
|
|
4072
|
+
diagnosticsPosition === "top" && showDiagnostics && /* @__PURE__ */ jsxRuntime.jsx(WqlDiagnosticsStrip, { diagnostics, stages, actions: action, variant: "header" }),
|
|
4073
|
+
(desktop || compact || active.kind === "wql" || !guided) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 w-full items-center gap-2", children: [
|
|
4074
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4075
|
+
WqlTextEditor,
|
|
4076
|
+
{
|
|
4077
|
+
value: resolved.wql,
|
|
4078
|
+
placeholder,
|
|
4079
|
+
dense: compact,
|
|
4080
|
+
className: compact ? "min-w-0 w-full bg-transparent" : void 0,
|
|
4081
|
+
activeRange: active.kind === "value" ? active.range : void 0,
|
|
4082
|
+
activeClause: active.kind === "value" ? active.clause : void 0,
|
|
4083
|
+
onSlotActivate: activateWqlSlot,
|
|
4084
|
+
onChange: (text) => commit(resolveQueryDraft(text)),
|
|
4085
|
+
onSubmit: submit,
|
|
4086
|
+
onEscape: () => {
|
|
4087
|
+
if (active.kind === "closed") return false;
|
|
4088
|
+
closeEditor();
|
|
4089
|
+
return true;
|
|
4090
|
+
},
|
|
4091
|
+
autoFocus
|
|
4092
|
+
}
|
|
4093
|
+
) }),
|
|
4094
|
+
desktop && compact && undo && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => {
|
|
4095
|
+
commit(resolveQueryDraft(undo));
|
|
4096
|
+
setUndo(void 0);
|
|
4097
|
+
}, className: "min-h-9 shrink-0 rounded-lg px-2.5 text-xs text-muted-foreground hover:text-foreground", children: "Undo removal" })
|
|
3967
4098
|
] }),
|
|
3968
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
4099
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex min-w-0 flex-wrap items-center gap-1", !desktop && !compact && "rounded-xl border border-border p-2", compact && "hidden"), "data-testid": "wql-composer", onKeyDown: (event) => {
|
|
4100
|
+
if (!["Delete", "Backspace"].includes(event.key) || !(event.target instanceof HTMLButtonElement)) return;
|
|
4101
|
+
const buttons = Array.from(event.currentTarget.querySelectorAll('[data-testid^="token-slot-"]:not([data-testid^="token-slot-remove-"]):not([data-testid^="token-slot-value-"])'));
|
|
4102
|
+
const pill = visiblePills[buttons.indexOf(event.target)];
|
|
4103
|
+
if (!pill || ["kind", "target", "agg", "metric"].includes(pill.type)) return;
|
|
4104
|
+
event.preventDefault();
|
|
4105
|
+
event.stopPropagation();
|
|
4106
|
+
setUndo(currentRef.current.wql);
|
|
4107
|
+
updateClause(pill, null);
|
|
4108
|
+
inputRef.current?.focus();
|
|
4109
|
+
}, children: [
|
|
4110
|
+
guided && active.kind !== "wql" && visiblePills.map((pill) => /* @__PURE__ */ jsxRuntime.jsx(TokenSlotPill, { clause: pill, compact, isActive: active.kind === "value" && active.clause.id === pill.id, onClick: () => openEditor(pill), onRemove: ["kind", "target", "agg", "metric"].includes(pill.type) ? void 0 : () => {
|
|
4111
|
+
setUndo(currentRef.current.wql);
|
|
4112
|
+
updateClause(pill, null);
|
|
4113
|
+
} }, pill.id)),
|
|
4114
|
+
!desktop && !compact && active.kind !== "wql" && guided && /* @__PURE__ */ jsxRuntime.jsx("input", { ref: inputRef, type: "text", role: "combobox", "aria-label": "Search text or WQL", "aria-controls": suggesting ? listId : void 0, "aria-expanded": suggesting, "aria-activedescendant": suggesting && highlight >= 0 ? `${listId}-option-${highlight}` : void 0, value: pending, placeholder, onChange: (event) => {
|
|
4115
|
+
const text = event.target.value;
|
|
4116
|
+
setPending(text);
|
|
4117
|
+
setHighlight(-1);
|
|
4118
|
+
setError(void 0);
|
|
4119
|
+
notify(resolveQueryDraft(base, text));
|
|
4120
|
+
}, onKeyDown: handleKeys, className: "min-h-12 min-w-0 flex-[1_1_140px] bg-transparent font-mono text-base outline-none", "data-testid": "wql-composer-input" }),
|
|
4121
|
+
customSlots
|
|
3980
4122
|
] }),
|
|
3981
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
3982
|
-
"
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
] }),
|
|
3992
|
-
suggesting && /* @__PURE__ */ jsxRuntime.jsxs("div", { id: listId, role: "listbox", "aria-label": "Query conditions", className: "max-h-64 overflow-y-auto rounded-xl border border-border p-1", "data-testid": "wql-filter-typeahead", children: [
|
|
3993
|
-
catalog.map((type, index) => /* @__PURE__ */ jsxRuntime.jsxs("button", { id: `${listId}-option-${index}`, type: "button", role: "option", "aria-selected": false, onMouseEnter: () => setHighlight(index), onClick: () => openField(type), className: cn("flex min-h-12 w-full items-center gap-2 rounded px-3 text-left", index === highlight && "bg-muted"), "data-testid": `wql-filter-typeahead-${type}`, children: [
|
|
3994
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
3995
|
-
pills.some((pill) => pill.type === type) ? "Edit" : "Add",
|
|
3996
|
-
" ",
|
|
3997
|
-
getClauseMeta(type).label
|
|
4123
|
+
(!desktop && !compact || !compact && undo) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
4124
|
+
!desktop && !compact && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => {
|
|
4125
|
+
commit(currentRef.current);
|
|
4126
|
+
if (active.kind === "wql") closeEditor();
|
|
4127
|
+
else setActive({ kind: "wql" });
|
|
4128
|
+
}, disabled: active.kind === "wql" && !guided, className: "min-h-12 rounded-lg px-3", children: active.kind === "wql" ? "Guided controls" : "Edit WQL" }),
|
|
4129
|
+
undo && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => {
|
|
4130
|
+
commit(resolveQueryDraft(undo));
|
|
4131
|
+
setUndo(void 0);
|
|
4132
|
+
}, className: "min-h-12 rounded-lg px-3", children: "Undo removal" })
|
|
3998
4133
|
] }),
|
|
3999
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4134
|
+
active.kind === "value" && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4135
|
+
"div",
|
|
4136
|
+
{
|
|
4137
|
+
"data-testid": "wql-field-picker",
|
|
4138
|
+
className: cn(
|
|
4139
|
+
"min-w-0",
|
|
4140
|
+
compact ? "border-t border-border/70 bg-muted/20 px-2.5 py-2 space-y-1.5" : "space-y-2 rounded-xl border border-border/80 bg-muted/30 p-2 sm:p-2.5 shadow-xs backdrop-blur-sm"
|
|
4141
|
+
),
|
|
4142
|
+
onKeyDown: (event) => {
|
|
4143
|
+
if (event.key === "Escape" || event.key === "Enter" && (event.ctrlKey || event.metaKey)) handleKeys(event);
|
|
4144
|
+
},
|
|
4145
|
+
children: [
|
|
4146
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
4147
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex shrink-0 items-center gap-1.5 rounded-md border border-border/70 bg-background/80 px-2.5 py-1 text-xs font-semibold text-foreground font-mono", children: [
|
|
4148
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "text-xs", children: getClauseMeta(active.clause.type).icon }),
|
|
4149
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: getClauseMeta(active.clause.type).label })
|
|
4150
|
+
] }),
|
|
4151
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "sr-only", children: [
|
|
4152
|
+
"Search ",
|
|
4153
|
+
getClauseMeta(active.clause.type).label
|
|
4154
|
+
] }),
|
|
4155
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4156
|
+
"input",
|
|
4157
|
+
{
|
|
4158
|
+
ref: pickerRef,
|
|
4159
|
+
type: "search",
|
|
4160
|
+
role: "combobox",
|
|
4161
|
+
"aria-label": `Search ${getClauseMeta(active.clause.type).label}`,
|
|
4162
|
+
"aria-controls": listId,
|
|
4163
|
+
"aria-expanded": "true",
|
|
4164
|
+
"aria-activedescendant": highlight >= 0 ? `${listId}-option-${highlight}` : void 0,
|
|
4165
|
+
value: search,
|
|
4166
|
+
placeholder: active.clause.value ? `Current: ${active.clause.value}` : `Type value for ${getClauseMeta(active.clause.type).label}\u2026`,
|
|
4167
|
+
onChange: (event) => {
|
|
4168
|
+
setSearch(event.target.value);
|
|
4169
|
+
setHighlight(-1);
|
|
4170
|
+
setError(void 0);
|
|
4171
|
+
},
|
|
4172
|
+
onKeyDown: handleKeys,
|
|
4173
|
+
className: "min-h-10 sm:min-h-8 min-w-0 flex-1 rounded-lg border border-border/80 bg-background px-2.5 font-mono text-sm sm:text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-primary shadow-xs",
|
|
4174
|
+
"data-testid": "wql-picker-search"
|
|
4175
|
+
}
|
|
4176
|
+
),
|
|
4177
|
+
active.clause.filterIndex !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "order-last flex w-full items-center gap-1.5 sm:order-none sm:w-auto", children: [
|
|
4178
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex cursor-pointer select-none items-center gap-1.5 px-2 py-0.5 rounded-md border border-border/60 bg-background/70 text-[11px] text-muted-foreground hover:text-foreground transition-colors", children: [
|
|
4179
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4180
|
+
"input",
|
|
4181
|
+
{
|
|
4182
|
+
type: "checkbox",
|
|
4183
|
+
checked: active.clause.negate ?? false,
|
|
4184
|
+
onChange: (event) => updateClause({ ...active.clause, negate: event.target.checked }, active.clause.value),
|
|
4185
|
+
className: "size-3 rounded border-border text-primary focus:ring-primary"
|
|
4186
|
+
}
|
|
4187
|
+
),
|
|
4188
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Exclude" })
|
|
4189
|
+
] }),
|
|
4190
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex cursor-pointer select-none items-center gap-1.5 px-2 py-0.5 rounded-md border border-border/60 bg-background/70 text-[11px] text-muted-foreground hover:text-foreground transition-colors", children: [
|
|
4191
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4192
|
+
"input",
|
|
4193
|
+
{
|
|
4194
|
+
type: "checkbox",
|
|
4195
|
+
checked: active.clause.value.split("|").every((value) => value.endsWith("*")),
|
|
4196
|
+
onChange: (event) => updateClause(active.clause, active.clause.value.split("|").map((value) => `${value.replace(/\*$/, "")}${event.target.checked ? "*" : ""}`).join("|")),
|
|
4197
|
+
className: "size-3 rounded border-border text-primary focus:ring-primary"
|
|
4198
|
+
}
|
|
4199
|
+
),
|
|
4200
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Starts with" })
|
|
4201
|
+
] })
|
|
4202
|
+
] }),
|
|
4203
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
4204
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4205
|
+
"button",
|
|
4206
|
+
{
|
|
4207
|
+
type: "button",
|
|
4208
|
+
"aria-label": "Previous WQL segment",
|
|
4209
|
+
"data-testid": "wql-segment-previous",
|
|
4210
|
+
disabled: activePillIndex <= 0,
|
|
4211
|
+
onClick: () => {
|
|
4212
|
+
if (moveEditor(-1)) pickerRef.current?.focus();
|
|
4213
|
+
},
|
|
4214
|
+
className: "flex items-center justify-center min-h-9 min-w-9 sm:min-h-7 sm:min-w-7 rounded-md border border-border/70 bg-background/80 text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:pointer-events-none text-xs transition-colors",
|
|
4215
|
+
children: "\u2190"
|
|
4216
|
+
}
|
|
4217
|
+
),
|
|
4218
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4219
|
+
"button",
|
|
4220
|
+
{
|
|
4221
|
+
type: "button",
|
|
4222
|
+
"aria-label": "Next WQL segment",
|
|
4223
|
+
"data-testid": "wql-segment-next",
|
|
4224
|
+
disabled: activePillIndex < 0 || activePillIndex >= visiblePills.length - 1,
|
|
4225
|
+
onClick: () => {
|
|
4226
|
+
if (moveEditor(1)) pickerRef.current?.focus();
|
|
4227
|
+
},
|
|
4228
|
+
className: "flex items-center justify-center min-h-9 min-w-9 sm:min-h-7 sm:min-w-7 rounded-md border border-border/70 bg-background/80 text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:pointer-events-none text-xs transition-colors",
|
|
4229
|
+
children: "\u2192"
|
|
4230
|
+
}
|
|
4231
|
+
),
|
|
4232
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4233
|
+
"button",
|
|
4234
|
+
{
|
|
4235
|
+
type: "button",
|
|
4236
|
+
"aria-label": "Close segment editor",
|
|
4237
|
+
onClick: closeEditor,
|
|
4238
|
+
className: "flex items-center justify-center min-h-9 min-w-9 sm:min-h-7 sm:min-w-7 rounded-md text-muted-foreground hover:bg-muted hover:text-foreground text-xs transition-colors",
|
|
4239
|
+
children: "\u2715"
|
|
4240
|
+
}
|
|
4241
|
+
)
|
|
4242
|
+
] })
|
|
4243
|
+
] }),
|
|
4244
|
+
active.kind === "value" && active.clause.type === "time" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2 pt-0.5 text-xs", children: [
|
|
4245
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block text-muted-foreground", children: [
|
|
4246
|
+
"Start date",
|
|
4247
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4248
|
+
"input",
|
|
4249
|
+
{
|
|
4250
|
+
type: "date",
|
|
4251
|
+
"aria-label": "Start date",
|
|
4252
|
+
className: "mt-1 min-h-8 w-full rounded-md border border-border/80 bg-background px-2.5 text-xs text-foreground",
|
|
4253
|
+
onChange: (event) => {
|
|
4254
|
+
const end = draftWindow();
|
|
4255
|
+
updateClause(active.clause, `from ${event.target.value}${end?.kind === "range" && end.end ? ` to ${end.end}` : ""}`);
|
|
4256
|
+
},
|
|
4257
|
+
value: astWindow?.kind === "range" ? astWindow.start : ""
|
|
4258
|
+
}
|
|
4259
|
+
)
|
|
4260
|
+
] }),
|
|
4261
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block text-muted-foreground", children: [
|
|
4262
|
+
"End date",
|
|
4263
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4264
|
+
"input",
|
|
4265
|
+
{
|
|
4266
|
+
type: "date",
|
|
4267
|
+
"aria-label": "End date",
|
|
4268
|
+
className: "mt-1 min-h-8 w-full rounded-md border border-border/80 bg-background px-2.5 text-xs text-foreground",
|
|
4269
|
+
onChange: (event) => {
|
|
4270
|
+
const window2 = draftWindow();
|
|
4271
|
+
if (window2?.kind === "range") updateClause(active.clause, `from ${window2.start}${event.target.value ? ` to ${event.target.value}` : ""}`);
|
|
4272
|
+
else setError("Choose a start date first");
|
|
4273
|
+
},
|
|
4274
|
+
value: astWindow?.kind === "range" ? astWindow.end ?? "" : ""
|
|
4275
|
+
}
|
|
4276
|
+
)
|
|
4277
|
+
] })
|
|
4278
|
+
] }),
|
|
4279
|
+
active.kind === "value" && (customEditor ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4280
|
+
customEditor.Editor,
|
|
4281
|
+
{
|
|
4282
|
+
value: customEditor.parseValue ? customEditor.parseValue(active.clause.value) : active.clause.value,
|
|
4283
|
+
onChange: (value) => updateClause(active.clause, customEditor.formatValue ? customEditor.formatValue(value) : String(value)),
|
|
4284
|
+
onClose: closeEditor
|
|
4285
|
+
}
|
|
4286
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4287
|
+
InlineClauseEditor,
|
|
4288
|
+
{
|
|
4289
|
+
clause: active.clause,
|
|
4290
|
+
filteredItems: preferredItems,
|
|
4291
|
+
selectedValues: values2.selectedValues,
|
|
4292
|
+
isMulti: values2.isMulti,
|
|
4293
|
+
typedValue: values2.typedValue,
|
|
4294
|
+
canCommitTyped: values2.canCommitTyped,
|
|
4295
|
+
emptyText: values2.emptyText,
|
|
4296
|
+
highlightIdx: highlight,
|
|
4297
|
+
onHighlight: setHighlight,
|
|
4298
|
+
onCommitValue: chooseValue,
|
|
4299
|
+
onCommitTyped: chooseValue,
|
|
4300
|
+
listId,
|
|
4301
|
+
onDone: closeEditor,
|
|
4302
|
+
onReorder: (dimensions) => updateClause(active.clause, dimensions.join("|"))
|
|
4303
|
+
}
|
|
4304
|
+
))
|
|
4305
|
+
]
|
|
4306
|
+
}
|
|
4307
|
+
),
|
|
4308
|
+
suggesting && /* @__PURE__ */ jsxRuntime.jsxs("div", { id: listId, role: "listbox", "aria-label": "Query conditions", className: "max-h-64 overflow-y-auto rounded-xl border border-border p-1", "data-testid": "wql-filter-typeahead", children: [
|
|
4309
|
+
catalog.map((type, index) => /* @__PURE__ */ jsxRuntime.jsxs("button", { id: `${listId}-option-${index}`, type: "button", role: "option", "aria-selected": false, onMouseEnter: () => setHighlight(index), onClick: () => openField(type), className: cn("flex min-h-12 w-full items-center gap-2 rounded px-3 text-left", index === highlight && "bg-muted"), "data-testid": `wql-filter-typeahead-${type}`, children: [
|
|
4310
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4311
|
+
pills.some((pill) => pill.type === type) ? "Edit" : "Add",
|
|
4312
|
+
" ",
|
|
4313
|
+
getClauseMeta(type).label
|
|
4314
|
+
] }),
|
|
4315
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: type })
|
|
4316
|
+
] }, type)),
|
|
4317
|
+
textAction && /* @__PURE__ */ jsxRuntime.jsxs("button", { id: `${listId}-option-${catalog.length}`, type: "button", role: "option", "aria-selected": false, onMouseEnter: () => setHighlight(catalog.length), className: cn("min-h-12 w-full rounded px-3 text-left", highlight === catalog.length && "bg-muted"), onClick: submit, children: [
|
|
4318
|
+
"Search text ",
|
|
4319
|
+
pending
|
|
4320
|
+
] })
|
|
4321
|
+
] }),
|
|
4322
|
+
pivot && /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alertdialog", "aria-label": "Confirm query pivot", className: "rounded-xl border border-border p-3", children: [
|
|
4323
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "Changing the query removes incompatible clauses:" }),
|
|
4324
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { children: pivot.removed.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: item }, item)) }),
|
|
4325
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "min-h-12 px-3", onClick: () => setPivot(void 0), children: "Cancel" }),
|
|
4326
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "min-h-12 px-3", onClick: () => {
|
|
4327
|
+
commit(pivot.draft);
|
|
4328
|
+
setPivot(void 0);
|
|
4329
|
+
closeEditor();
|
|
4330
|
+
}, children: "Change query" })
|
|
4331
|
+
] }),
|
|
4332
|
+
!showDiagnostics && (error ?? resolved.error) && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive", children: error ?? resolved.error }),
|
|
4333
|
+
!guided && !resolved.error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "Use Edit WQL to preserve every clause." }),
|
|
4334
|
+
pending && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", "data-testid": "wql-composer-pending", children: resolved.valid ? "Current draft includes this text" : resolved.error }),
|
|
4335
|
+
showDiagnostics && diagnosticsPosition === "bottom" ? /* @__PURE__ */ jsxRuntime.jsx(WqlDiagnosticsStrip, { diagnostics, stages, actions: action }) : diagnosticsPosition !== "top" || !showDiagnostics ? Boolean(actionLabel || diagnosticsActions) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center justify-end gap-2", children: action }) : null
|
|
4336
|
+
]
|
|
4337
|
+
}
|
|
4338
|
+
);
|
|
4021
4339
|
}
|
|
4022
4340
|
|
|
4023
4341
|
// src/composer/filterTypeahead.ts
|
|
@@ -14041,13 +14359,13 @@ function editorPreset(optionsOrDialect = "markdown") {
|
|
|
14041
14359
|
}
|
|
14042
14360
|
|
|
14043
14361
|
// src/version.ts
|
|
14044
|
-
var VERSION = "0.
|
|
14045
|
-
var GIT_SHA = "
|
|
14046
|
-
var BUILD_TIME = "2026-10-
|
|
14362
|
+
var VERSION = "0.49.2177";
|
|
14363
|
+
var GIT_SHA = "2966790";
|
|
14364
|
+
var BUILD_TIME = "2026-10-29T03:03:43.665Z";
|
|
14047
14365
|
var SEMVER = {
|
|
14048
|
-
version: "0.
|
|
14049
|
-
gitSha: "
|
|
14050
|
-
buildTime: "2026-10-
|
|
14366
|
+
version: "0.49.2177",
|
|
14367
|
+
gitSha: "2966790",
|
|
14368
|
+
buildTime: "2026-10-29T03:03:43.665Z"
|
|
14051
14369
|
};
|
|
14052
14370
|
|
|
14053
14371
|
Object.defineProperty(exports, "CONTENT_GROUPING_DIMENSIONS", {
|