@bitcobblers/wod-wiki-ui 0.10.42 → 0.35.2115
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-S77JRUQM.mjs → chunk-GUN6PZNI.mjs} +3593 -1589
- package/dist/chunk-GUN6PZNI.mjs.map +1 -0
- package/dist/extensions/index.cjs +3498 -1511
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +2 -2
- package/dist/extensions/index.d.ts +2 -2
- package/dist/extensions/index.mjs +1 -1
- package/dist/{index-CTQ7Hrsa.d.cts → index-DMTXLSJ0.d.cts} +61 -7
- package/dist/{index-CTQ7Hrsa.d.ts → index-DMTXLSJ0.d.ts} +61 -7
- package/dist/index.cjs +3948 -1645
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +425 -189
- package/dist/index.d.ts +425 -189
- package/dist/index.mjs +353 -78
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +46 -1
- package/package.json +4 -4
- package/dist/chunk-S77JRUQM.mjs.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { Q as QueryExecutor } from './index-
|
|
2
|
-
export { B as ButtonAction, C as CursorFocusState, D as DefaultFrontmatterWidget, E as EditorDialect,
|
|
1
|
+
import { Q as QueryExecutor } from './index-DMTXLSJ0.cjs';
|
|
2
|
+
export { B as ButtonAction, C as CursorFocusState, a as CustomCompletionSource, D as DefaultFrontmatterWidget, E as EditorDialect, b as EditorPresetOptions, c as EditorSection, d as EditorSectionSubtype, e as EditorSectionType, f as EmbedType, F as FrontmatterSuggestionCatalog, G as GeometryListener, N as NavigationHook, O as OverlayAction, g as QueryBlockPreviewOptions, R as RuntimePanelEntry, S as SectionRect, h as SectionState, W as WidgetConfig, i as WidgetProps, j as WidgetRegistry, k as activeCursorSection, l as addRuntimePanel, m as configureOverlayActions, n as cursorFocusExtension, o as dispatchAddRuntimePanel, p as dispatchExpandRuntimePanel, q as dispatchGutterHighlights, r as dispatchRemoveRuntimePanel, s as editingWidgetsField, t as editorPreset, u as editorTheme, v as embedPreviewDecorations, w as expandRuntimePanel, x as fenceCompletion, y as findQueryBlockSection, z as findWorkoutErrors, A as forceSectionParse, H as frontmatterPreview, I as frontmatterPreviewField, J as frontmatterSuggestions, K as frontmatterVisibility, L as getCursorFocusState, M as getOverlayActions, P as gutterHighlightsField, T as gutterUnified, U as handleFenceAutoWrap, V as inlineButtonDecoration, X as lineIdsExtension, Y as linkOpen, Z as linkPreview, _ as markdownSyntaxHiding, $ as markdownTablePreview, a0 as navigationFacet, a1 as previewDecorations, a2 as queryBlockPreview, a3 as registerCustomCompletionSource, a4 as removeRuntimePanel, a5 as runtimePanelField, a6 as saveBlockQuerySource, a7 as sectionAtPos, a8 as sectionField, a9 as sectionGeometry, aa as sessionQueryInsert, ab as sessionQueryWql, ac as setGutterHighlights, ad as smartIncrement, ae as toggleWidgetEdit, af as unregisterCustomCompletionSource, ag as urlAtPos, ah as widgetBlockPreview, ai as wodAutoWrap, aj as wodAutocompletion, ak as wodEditorKeymap, al as wodLinter, am as wodOverlayPanel, an as workoutLintSource, ao as wrapInTimeFence } from './index-DMTXLSJ0.cjs';
|
|
3
3
|
import * as react from 'react';
|
|
4
|
-
import { ReactNode, ComponentType } from 'react';
|
|
5
|
-
import { QueryResult, DashboardToken, DashboardDocument, DashboardWidget, Series, RowsQueryResult, RowsRun, AnyParsedQuery, FindQueryResult, ParsedAggregateQuery, ParsedFindQuery } from '@bitcobblers/wod-wiki-wql';
|
|
6
|
-
export { FindOptions, FindQueryResult, ParsedAggregateQuery, ParsedFindQuery, ParsedRowsQuery, QueryOptions, QueryResult, RowsQueryResult, RowsRun } from '@bitcobblers/wod-wiki-wql';
|
|
7
|
-
import {
|
|
4
|
+
import react__default, { ReactNode, ComponentType } from 'react';
|
|
5
|
+
import { QueryResult, DashboardToken, DashboardDocument, DashboardWidget, Series, RowsQueryResult, RowsRun, AnyParsedQuery, FindQueryResult, ParsedAggregateQuery, ParsedFindQuery, ParsedPipelineQuery } from '@bitcobblers/wod-wiki-wql';
|
|
6
|
+
export { CONTENT_GROUPING_DIMENSIONS, FindOptions, FindQueryResult, ParsedAggregateQuery, ParsedFindQuery, ParsedPipelineQuery, ParsedRowsQuery, PipelineResult, QueryOptions, QueryResult, RowsQueryResult, RowsRun } from '@bitcobblers/wod-wiki-wql';
|
|
7
|
+
import { IMetric, EventRecord, BlockIndexRow } from '@bitcobblers/wod-wiki-core';
|
|
8
|
+
export { blockContentId } from '@bitcobblers/wod-wiki-core';
|
|
9
|
+
import { MetricPresentationToken } from '@bitcobblers/wod-wiki-lang';
|
|
8
10
|
import { ClassValue } from 'clsx';
|
|
9
11
|
import '@codemirror/state';
|
|
10
12
|
import '@codemirror/view';
|
|
@@ -20,13 +22,46 @@ interface StorageLike {
|
|
|
20
22
|
declare const CODEMIRROR_SINGLETON_DEPS: readonly ["@codemirror/autocomplete", "@codemirror/commands", "@codemirror/lang-markdown", "@codemirror/language", "@codemirror/lint", "@codemirror/search", "@codemirror/state", "@codemirror/theme-one-dark", "@codemirror/view", "@lezer/common", "@lezer/highlight", "@lezer/lr", "@lezer/markdown"];
|
|
21
23
|
|
|
22
24
|
interface WidgetFrameProps {
|
|
25
|
+
/** DOM anchor for the frame (e.g. `widget-<key>`) — L3 indexes scroll here. */
|
|
26
|
+
id?: string;
|
|
23
27
|
title: string;
|
|
24
28
|
question: string;
|
|
25
|
-
|
|
29
|
+
/** Raw WQL for the widget. Hidden by default — only rendered with showQuery. */
|
|
30
|
+
query?: string;
|
|
26
31
|
span?: string;
|
|
32
|
+
/** Show the raw WQL query box (teaching/authoring surfaces). View-first default hides it. */
|
|
33
|
+
showQuery?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Read-only inspection affordance — an always-visible button (prebuilt
|
|
36
|
+
* seeds, teaching surfaces) opening the host's query inspector. Distinct
|
|
37
|
+
* from editing: present without a toolbar.
|
|
38
|
+
*/
|
|
39
|
+
onInspect?: () => void;
|
|
40
|
+
/** Always-visible affordance: open this widget's resolved query in the
|
|
41
|
+
* WQL explorer (host navigates). */
|
|
42
|
+
onOpenInExplorer?: () => void;
|
|
43
|
+
/**
|
|
44
|
+
* Edit-mode action cluster (edit / duplicate / remove / reorder / size),
|
|
45
|
+
* rendered top-right and always visible while present. The host builds it;
|
|
46
|
+
* the frame only positions it.
|
|
47
|
+
*/
|
|
48
|
+
toolbar?: ReactNode;
|
|
27
49
|
children: ReactNode;
|
|
28
50
|
}
|
|
29
|
-
declare function WidgetFrame({ title, question, query, span, children }: WidgetFrameProps): react.JSX.Element;
|
|
51
|
+
declare function WidgetFrame({ id, title, question, query, span, showQuery, onInspect, onOpenInExplorer, toolbar, children }: WidgetFrameProps): react.JSX.Element;
|
|
52
|
+
/** Standard edit-mode tool-button chrome for the widget toolbar. */
|
|
53
|
+
declare function WidgetToolButton({ label, onClick, disabled, active, children, }: {
|
|
54
|
+
label: string;
|
|
55
|
+
onClick: () => void;
|
|
56
|
+
disabled?: boolean;
|
|
57
|
+
active?: boolean;
|
|
58
|
+
children: ReactNode;
|
|
59
|
+
}): react.JSX.Element;
|
|
60
|
+
/** The primary "open the full editor" affordance inside the toolbar. */
|
|
61
|
+
declare function WidgetEditButton({ title, onClick }: {
|
|
62
|
+
title: string;
|
|
63
|
+
onClick: () => void;
|
|
64
|
+
}): react.JSX.Element;
|
|
30
65
|
|
|
31
66
|
interface QueryValueProps {
|
|
32
67
|
result: QueryResult;
|
|
@@ -66,20 +101,27 @@ interface WidgetChartProps {
|
|
|
66
101
|
unit?: string;
|
|
67
102
|
/** Positional widget parameters from the block body (e.g. goal target or zone targets). */
|
|
68
103
|
params?: string[];
|
|
104
|
+
/** Fence-tag presentation attributes (decision 22) — preferred over legacy positional params. */
|
|
105
|
+
attributes?: Record<string, string>;
|
|
69
106
|
}
|
|
70
|
-
declare function WidgetChart({ type, result, label, unit, params }: WidgetChartProps):
|
|
107
|
+
declare function WidgetChart({ type, result, label, unit, params, attributes }: WidgetChartProps): react__default.JSX.Element;
|
|
71
108
|
declare function WidgetProblemBadge({ message }: {
|
|
72
109
|
message: string;
|
|
73
|
-
}):
|
|
110
|
+
}): react__default.JSX.Element;
|
|
74
111
|
declare function ProposedMetricBadge({ metric }: {
|
|
75
112
|
metric: string;
|
|
76
|
-
}):
|
|
113
|
+
}): react__default.JSX.Element;
|
|
77
114
|
|
|
78
115
|
interface DashboardTokenControlsProps {
|
|
79
116
|
tokens: DashboardToken[];
|
|
80
117
|
/** Current value per token name (defaults applied by the caller). */
|
|
81
118
|
values: Record<string, string>;
|
|
82
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* Present when the note is editable — a change commits exactly once, on an
|
|
121
|
+
* explicit action: a list-token segment click, or a scalar-token blur /
|
|
122
|
+
* Enter. Keystrokes only edit the local draft — they never rewrite the
|
|
123
|
+
* note or re-run widgets mid-edit.
|
|
124
|
+
*/
|
|
83
125
|
onChange?: (name: string, value: string) => void;
|
|
84
126
|
}
|
|
85
127
|
/**
|
|
@@ -90,19 +132,50 @@ interface DashboardTokenControlsProps {
|
|
|
90
132
|
*/
|
|
91
133
|
declare function DashboardTokenControls({ tokens, values, onChange }: DashboardTokenControlsProps): react.JSX.Element | null;
|
|
92
134
|
|
|
135
|
+
/** A widget's grid placement — column span 1..4, or a forced full row. */
|
|
136
|
+
interface WidgetSpanOption {
|
|
137
|
+
spanCols?: number;
|
|
138
|
+
spanFull?: boolean;
|
|
139
|
+
}
|
|
140
|
+
/** A note heading rendered as a full-width grid row between widgets, with its
|
|
141
|
+
* own DOM anchor (L3 scroll target). Order within `headings` is preserved. */
|
|
142
|
+
interface DashboardHeadingAnchor {
|
|
143
|
+
id: string;
|
|
144
|
+
/** Markdown heading level (2+; level 1 renders as the page title surface). */
|
|
145
|
+
level: number;
|
|
146
|
+
text: string;
|
|
147
|
+
/** Insert before this widget index; `widgets.length` = after the last. */
|
|
148
|
+
beforeWidget: number;
|
|
149
|
+
}
|
|
93
150
|
interface DashboardViewProps {
|
|
94
151
|
/** Parsed dashboard note (buildDashboardDocument). */
|
|
95
152
|
document: DashboardDocument;
|
|
153
|
+
/** Note headings to render between the widgets (document order). */
|
|
154
|
+
headings?: DashboardHeadingAnchor[];
|
|
96
155
|
/** Injected QueryExecutor for executing WQL queries. Zero singleton coupling. */
|
|
97
156
|
executor?: QueryExecutor;
|
|
98
157
|
/** Optional rollup fact warmer callback. */
|
|
99
158
|
onEnsureRollupFacts?: () => Promise<void>;
|
|
100
159
|
/** Current token values; defaults to each token's declared default. */
|
|
101
160
|
tokenValues?: Record<string, string>;
|
|
102
|
-
/** Present when the note is editable — control changes write back to frontmatter. */
|
|
161
|
+
/** Present when the note is editable — committed control changes write back to frontmatter. */
|
|
103
162
|
onTokenChange?: (name: string, value: string) => void;
|
|
104
|
-
/**
|
|
105
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Edit mode: per-widget arrangement chrome (edit / duplicate / remove /
|
|
165
|
+
* reorder / size) renders on every card. View mode stays chrome-free —
|
|
166
|
+
* the host gates editing on this flag plus the handler set below.
|
|
167
|
+
*/
|
|
168
|
+
editMode?: boolean;
|
|
169
|
+
/** Open the shared authoring composer for this widget (edit flow). */
|
|
170
|
+
onEditWidget?: (widget: DashboardWidget) => void;
|
|
171
|
+
/** Read-only query inspection (prebuilt seeds, teaching surfaces). */
|
|
172
|
+
onInspectWidget?: (widget: DashboardWidget) => void;
|
|
173
|
+
/** Open the widget's token-resolved query in the WQL explorer (host navigates). */
|
|
174
|
+
onOpenInExplorer?: (widget: DashboardWidget, query: string) => void;
|
|
175
|
+
onDuplicateWidget?: (widget: DashboardWidget) => void;
|
|
176
|
+
onRemoveWidget?: (widget: DashboardWidget) => void;
|
|
177
|
+
onMoveWidget?: (widget: DashboardWidget, delta: -1 | 1) => void;
|
|
178
|
+
onResizeWidget?: (widget: DashboardWidget, span: WidgetSpanOption) => void;
|
|
106
179
|
/** Optional execution range (ms epoch). Omit to use each query's own window. */
|
|
107
180
|
rangeStart?: number;
|
|
108
181
|
rangeEnd?: number;
|
|
@@ -112,15 +185,19 @@ interface DashboardViewProps {
|
|
|
112
185
|
* DashboardView — the state-free dashboard renderer (#900, format locked in #899).
|
|
113
186
|
*
|
|
114
187
|
* Takes a parsed DashboardDocument + current token values, runs all widget
|
|
115
|
-
* queries concurrently via the injected QueryExecutor, and renders the
|
|
188
|
+
* queries concurrently via the injected QueryExecutor, and renders the
|
|
189
|
+
* responsive CSS grid. All authoring interactions are host-owned: the view
|
|
190
|
+
* surfaces the affordances (edit-mode toolbar, inspect button) and reports
|
|
191
|
+
* through the injected callbacks — it never owns dialog or write state.
|
|
116
192
|
*/
|
|
117
|
-
declare function DashboardView({ document, executor, onEnsureRollupFacts, tokenValues, onTokenChange,
|
|
193
|
+
declare function DashboardView({ document, headings, executor, onEnsureRollupFacts, tokenValues, onTokenChange, editMode, onEditWidget, onInspectWidget, onOpenInExplorer, onDuplicateWidget, onRemoveWidget, onMoveWidget, onResizeWidget, rangeStart, rangeEnd, preferredUnit, }: DashboardViewProps): react.JSX.Element;
|
|
118
194
|
|
|
119
195
|
interface WqlEmptyStateProps {
|
|
120
|
-
result
|
|
196
|
+
result?: QueryResult | undefined;
|
|
121
197
|
className?: string;
|
|
198
|
+
actions?: ReactNode;
|
|
122
199
|
}
|
|
123
|
-
declare function WqlEmptyState({ result, className }: WqlEmptyStateProps): react.JSX.Element | null;
|
|
200
|
+
declare function WqlEmptyState({ result, className, actions }: WqlEmptyStateProps): react.JSX.Element | null;
|
|
124
201
|
|
|
125
202
|
interface TopListProps {
|
|
126
203
|
result: QueryResult;
|
|
@@ -141,14 +218,18 @@ interface GoalRingsProps {
|
|
|
141
218
|
label?: string;
|
|
142
219
|
unit?: string;
|
|
143
220
|
}
|
|
144
|
-
declare function GoalRings({ result, params, label, unit }: GoalRingsProps
|
|
221
|
+
declare function GoalRings({ result, attributes, params, label, unit }: GoalRingsProps & {
|
|
222
|
+
attributes?: Record<string, string>;
|
|
223
|
+
}): react.JSX.Element;
|
|
145
224
|
|
|
146
225
|
interface ZoneDistributionProps {
|
|
147
226
|
result: QueryResult | undefined;
|
|
148
227
|
params?: string[];
|
|
149
228
|
unit?: string;
|
|
150
229
|
}
|
|
151
|
-
declare function ZoneDistribution({ result, params }: ZoneDistributionProps
|
|
230
|
+
declare function ZoneDistribution({ result, params, attributes }: ZoneDistributionProps & {
|
|
231
|
+
attributes?: Record<string, string>;
|
|
232
|
+
}): react.JSX.Element;
|
|
152
233
|
|
|
153
234
|
type AnalyticsRangeWeeks = 4 | 8 | 16;
|
|
154
235
|
interface RangeSelectorProps {
|
|
@@ -220,14 +301,82 @@ interface AnalyticsUnitPreferenceProps {
|
|
|
220
301
|
}
|
|
221
302
|
declare function AnalyticsUnitPreference({ className, unit: unitProp, forced, storage }: AnalyticsUnitPreferenceProps): react.JSX.Element;
|
|
222
303
|
|
|
304
|
+
declare function formatMMSS(ms: number): string;
|
|
305
|
+
declare function formatClockTime(d: Date): string;
|
|
306
|
+
declare const TONE_CLASS: Record<string, string>;
|
|
307
|
+
declare function MetricBadge({ token }: {
|
|
308
|
+
token: MetricPresentationToken;
|
|
309
|
+
}): react.JSX.Element | null;
|
|
310
|
+
/** Metric badges for a statement/output metric group. */
|
|
311
|
+
declare function presentBadges(metrics: Iterable<IMetric>): ReactNode;
|
|
312
|
+
declare const OUTPUT_TYPE_CLASS: Record<string, string>;
|
|
313
|
+
declare const OUTPUT_TYPE_DOT: Record<string, string>;
|
|
314
|
+
interface CategorizedMetrics {
|
|
315
|
+
efforts: IMetric[];
|
|
316
|
+
reps: IMetric[];
|
|
317
|
+
loads: IMetric[];
|
|
318
|
+
rounds: IMetric[];
|
|
319
|
+
durations: IMetric[];
|
|
320
|
+
distances: IMetric[];
|
|
321
|
+
hints: IMetric[];
|
|
322
|
+
}
|
|
323
|
+
declare function extractMetricsByCategory(metrics?: Iterable<IMetric>): CategorizedMetrics;
|
|
324
|
+
interface OutputFilterPreset {
|
|
325
|
+
label: string;
|
|
326
|
+
query: string;
|
|
327
|
+
}
|
|
328
|
+
type OutputFilterInput = string | OutputFilterPreset;
|
|
329
|
+
/** Default row filter — segment statements only (the Workbench default). */
|
|
330
|
+
declare const DEFAULT_PRIMARY_FILTER = "type:segment";
|
|
331
|
+
declare const DEFAULT_OUTPUT_FILTERS: OutputFilterPreset[];
|
|
332
|
+
declare function normalizeOutputFilter(filter: OutputFilterInput): OutputFilterPreset;
|
|
333
|
+
/** Structural subset satisfied by live `IOutputStatement`s, stored statements,
|
|
334
|
+
* and `EventRecord` event rows alike. */
|
|
335
|
+
interface OutputStatementRow {
|
|
336
|
+
readonly id?: number | string;
|
|
337
|
+
readonly outputType?: string;
|
|
338
|
+
readonly timeSpan?: {
|
|
339
|
+
started: number;
|
|
340
|
+
ended?: number;
|
|
341
|
+
};
|
|
342
|
+
readonly metrics?: Iterable<IMetric>;
|
|
343
|
+
readonly sourceBlockKey?: string;
|
|
344
|
+
readonly completionReason?: string;
|
|
345
|
+
}
|
|
346
|
+
declare function OutputFilterPills({ presets, filter, onChange, }: {
|
|
347
|
+
presets: OutputFilterPreset[];
|
|
348
|
+
filter: string;
|
|
349
|
+
onChange: (next: string) => void;
|
|
350
|
+
}): react.JSX.Element;
|
|
351
|
+
interface OutputStatementsTableProps {
|
|
352
|
+
outputs: readonly OutputStatementRow[];
|
|
353
|
+
/** Filter expression (`type:segment`, free text). Empty shows all. */
|
|
354
|
+
filter?: string;
|
|
355
|
+
/** Epoch ms the +offset column is relative to. Defaults to first statement start. */
|
|
356
|
+
timeOrigin?: number;
|
|
357
|
+
/** Clears the active filter — enables the Card List's Clear-filter
|
|
358
|
+
* affordance on the filtered-empty state. Optional; hosts without a
|
|
359
|
+
* clearable filter omit it. */
|
|
360
|
+
onClearFilter?: () => void;
|
|
361
|
+
}
|
|
362
|
+
/** The Session Results surface — Card List below `sm`, the 9-column table at
|
|
363
|
+
* `sm` and above. One component: same props, same filtering; hosts (analytics
|
|
364
|
+
* explorer, editor query blocks, workbench) inherit the phone path. */
|
|
365
|
+
declare function OutputStatementsTable({ outputs, filter, timeOrigin, onClearFilter, }: OutputStatementsTableProps): react.JSX.Element;
|
|
366
|
+
|
|
223
367
|
interface RowsTableProps {
|
|
224
368
|
result: RowsQueryResult;
|
|
225
369
|
/** Optional per-run chrome rendered inside the section header (#948 RPE). */
|
|
226
370
|
renderRunHeaderExtra?: (run: RowsRun) => ReactNode;
|
|
227
|
-
/**
|
|
228
|
-
|
|
371
|
+
/** Filter presets for the pills row (defaults to All/Segments/Events). */
|
|
372
|
+
presets?: OutputFilterInput[];
|
|
373
|
+
/** Controlled filter expression — omit to let the table own its filter state. */
|
|
374
|
+
filter?: string;
|
|
375
|
+
onFilterChange?: (filter: string) => void;
|
|
229
376
|
}
|
|
230
|
-
|
|
377
|
+
/** The Session Results Table — renders a Rows Query result: one section per
|
|
378
|
+
* run, filter pills on top, and the shared statement table as the body. */
|
|
379
|
+
declare function RowsTable({ result, renderRunHeaderExtra, presets, filter, onFilterChange, }: RowsTableProps): react.JSX.Element;
|
|
231
380
|
|
|
232
381
|
interface QueryBlockViewProps {
|
|
233
382
|
/** Raw text between the ```query fences — the WQL query string or block source. */
|
|
@@ -236,8 +385,10 @@ interface QueryBlockViewProps {
|
|
|
236
385
|
executor?: QueryExecutor;
|
|
237
386
|
/** Optional callback or subscription hook for when a result is saved, replacing hardcoded resultRecorder coupling. */
|
|
238
387
|
onResultSaved?: (callback: () => void) => (() => void) | void;
|
|
239
|
-
/** Present when the query block is editable — opens the WQL composer.
|
|
240
|
-
|
|
388
|
+
/** Present when the query block is editable — opens the WQL composer.
|
|
389
|
+
* May return the write's Promise so a rejected save keeps the editor
|
|
390
|
+
* open; a plain void write is fire-and-forget. */
|
|
391
|
+
onSaveQuery?: (nextQuery: string) => void | Promise<void>;
|
|
241
392
|
/** When multiple queries appear in one block, the index of this query. */
|
|
242
393
|
queryIndex?: number;
|
|
243
394
|
/** When true, editing the query is disallowed. */
|
|
@@ -248,14 +399,26 @@ interface QueryBlockViewProps {
|
|
|
248
399
|
widgetError?: string;
|
|
249
400
|
/** Token values from the note's frontmatter, for `$token` substitution. */
|
|
250
401
|
tokenValues?: Record<string, string>;
|
|
402
|
+
/** Fence-tag presentation attributes (decision 22). */
|
|
403
|
+
attributes?: Record<string, string>;
|
|
251
404
|
/** Optional RPE capture handler. */
|
|
252
405
|
onCaptureRpe?: (resultId: string, rpe: number) => Promise<void>;
|
|
253
|
-
/** Optional
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
406
|
+
/** Optional click handler for opening a note from :note results. */
|
|
407
|
+
onOpenNote?: (item: {
|
|
408
|
+
id: string;
|
|
409
|
+
title?: string;
|
|
410
|
+
blockContentId?: string;
|
|
411
|
+
}) => void;
|
|
412
|
+
/** Optional resolver returning the destination href for an item in :note results. */
|
|
413
|
+
noteHref?: (item: {
|
|
414
|
+
id: string;
|
|
415
|
+
title?: string;
|
|
416
|
+
blockContentId?: string;
|
|
417
|
+
}) => string;
|
|
418
|
+
}
|
|
419
|
+
declare function QueryBlockView({ query, executor, onResultSaved, onSaveQuery, queryIndex: _queryIndex, readOnly, widgetType, widgetError, tokenValues, attributes, onCaptureRpe, onOpenNote, noteHref, }: QueryBlockViewProps): react.JSX.Element;
|
|
420
|
+
|
|
421
|
+
declare function readSessionRpe(events: EventRecord[] | undefined): number | undefined;
|
|
259
422
|
interface RowsResultsChromeProps {
|
|
260
423
|
/** The session result id from the written `rows:{result:…}` query. */
|
|
261
424
|
resultId: string;
|
|
@@ -267,21 +430,23 @@ interface RowsResultsChromeProps {
|
|
|
267
430
|
onCaptureRpe?: (resultId: string, rpe: number) => Promise<void>;
|
|
268
431
|
/** Re-run the parent query after a capture so the grid reflects the RPE. */
|
|
269
432
|
onCaptured?: () => void;
|
|
270
|
-
/** Optional segment grid renderer. */
|
|
271
|
-
renderSegments?: (segments: Segment[], run: RowsRun) => React.ReactNode;
|
|
272
433
|
}
|
|
273
|
-
declare function RowsResultsChrome({ resultId, sessionResult, executor, onCaptureRpe, onCaptured,
|
|
434
|
+
declare function RowsResultsChrome({ resultId, sessionResult, executor, onCaptureRpe, onCaptured, }: RowsResultsChromeProps): react.JSX.Element;
|
|
274
435
|
|
|
275
436
|
interface WqlQueryInspectorModalProps {
|
|
276
437
|
isOpen: boolean;
|
|
277
438
|
onClose: () => void;
|
|
278
439
|
initialQuery: string;
|
|
279
|
-
|
|
440
|
+
/** Persist the applied query. A returned Promise gates the button until
|
|
441
|
+
* it settles; a rejection keeps the dialog open with the error visible. */
|
|
442
|
+
onApply: (newQuery: string) => void | Promise<void>;
|
|
280
443
|
title?: string;
|
|
281
444
|
subtitle?: string;
|
|
445
|
+
/** Label for the confirm button (defaults to "Apply to Block"). */
|
|
446
|
+
applyLabel?: string;
|
|
282
447
|
executor?: QueryExecutor;
|
|
283
448
|
}
|
|
284
|
-
declare function WqlQueryInspectorModal({ isOpen, onClose, initialQuery, onApply, title, subtitle, executor, }: WqlQueryInspectorModalProps): react.JSX.Element
|
|
449
|
+
declare function WqlQueryInspectorModal({ isOpen, onClose, initialQuery, onApply, title, subtitle, applyLabel, executor, }: WqlQueryInspectorModalProps): react.JSX.Element;
|
|
285
450
|
|
|
286
451
|
type WqlExecutor = (ast: AnyParsedQuery) => Promise<FindQueryResult | QueryResult>;
|
|
287
452
|
type WqlStageCounts = {
|
|
@@ -299,22 +464,25 @@ declare const DEFAULT_DIAGNOSTICS_DEBOUNCE_MS = 150;
|
|
|
299
464
|
declare function useWqlStageCounts(ast: AnyParsedQuery, valid: boolean, execute: WqlExecutor | undefined, debounceMs?: number): WqlStageCounts | undefined;
|
|
300
465
|
|
|
301
466
|
/**
|
|
302
|
-
*
|
|
467
|
+
* The WqlComposer pill vocabulary — types, metadata, and option lists.
|
|
468
|
+
* Compilation and restore live in `./queryAst` (ticket 013): composer state
|
|
469
|
+
* is the C6 AST; strings are produced only through the engine serializer.
|
|
303
470
|
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
*
|
|
471
|
+
* Canonical structure (work item 3): a query has a `kind` (find documents vs
|
|
472
|
+
* measure numbers), a singular `target` (colon `<target>` head), and an optional
|
|
473
|
+
* `source` storage scope (`Where stored` — WQL_SOURCE_VALUES; all sources =
|
|
474
|
+
* no source filter). Filter capability sets mirror what the QueryService
|
|
475
|
+
* executors actually apply — parser acceptance alone never advertises a
|
|
476
|
+
* clause (`has:` parses but no executor applies it, so it is not offered).
|
|
310
477
|
*
|
|
311
478
|
* Static option lists live here; dynamic typeahead data sources live in
|
|
312
479
|
* ./suggestionSources (issue #831). All vocab is sourced from the canonical
|
|
313
|
-
* modules (@bitcobblers/wod-wiki-
|
|
480
|
+
* modules (@bitcobblers/wod-wiki-wql) — never hardcoded in the composer (decision #824).
|
|
314
481
|
*
|
|
315
482
|
* Supports freeform token slots, placeholder guidance, and keyboard navigation.
|
|
316
483
|
*/
|
|
317
|
-
|
|
484
|
+
|
|
485
|
+
type ClauseType = 'kind' | 'target' | 'source' | 'text' | 'catalog' | 'tag' | 'effort' | 'domain' | 'format' | 'equipment' | 'quality' | 'intent' | 'discipline' | 'intensity' | 'origin' | 'type' | 'time' | 'where' | 'agg' | 'metric' | 'groupby' | 'rollup' | 'unit' | 'result' | 'block' | 'note' | 'page' | 'plane' | 'pipes';
|
|
318
486
|
interface QueryClause {
|
|
319
487
|
id: string;
|
|
320
488
|
/** Built-in ClauseType or a custom slot type id from the ComposerRegistry. */
|
|
@@ -325,16 +493,39 @@ interface QueryClause {
|
|
|
325
493
|
placeholder?: string;
|
|
326
494
|
icon?: string;
|
|
327
495
|
prefix?: string;
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
496
|
+
/** Index into the parsed AST's global filters array (ast.filters[filterIndex])
|
|
497
|
+
* — identifies one specific filter occurrence; editing one occurrence must
|
|
498
|
+
* never merge or rewrite another. */
|
|
499
|
+
filterIndex?: number;
|
|
500
|
+
/** True when this filter occurrence is negated (`!key:value`). */
|
|
501
|
+
negate?: boolean;
|
|
502
|
+
}
|
|
503
|
+
/** Query shape: `find` compiles the colon `<target>` skeleton (`:note{…}`),
|
|
504
|
+
* `aggregate` compiles `agg:metric{filters} by {dims}` and exposes agg/metric. */
|
|
505
|
+
declare const KIND_OPTIONS: {
|
|
334
506
|
value: string;
|
|
335
507
|
label: string;
|
|
336
508
|
description: string;
|
|
337
509
|
}[];
|
|
510
|
+
/** Singular find targets — the colon `<target>` head (C7 closed enum). */
|
|
511
|
+
declare const TARGET_OPTIONS: {
|
|
512
|
+
value: "note" | "effort" | "segment" | "event" | "session" | "block";
|
|
513
|
+
label: string;
|
|
514
|
+
description: string;
|
|
515
|
+
}[];
|
|
516
|
+
/** Storage scopes — the `source:` filter values (`Where stored`). All
|
|
517
|
+
* sources means no source filter at all. */
|
|
518
|
+
declare const SOURCE_OPTIONS: {
|
|
519
|
+
value: "efforts" | "journal" | "feeds" | "guides" | "playground" | "dashboards";
|
|
520
|
+
label: string;
|
|
521
|
+
description: string;
|
|
522
|
+
}[];
|
|
523
|
+
/** Output-statement planes for `plane:` on `:session` (executor narrows
|
|
524
|
+
* events by the promoted `outputType` column). */
|
|
525
|
+
declare const PLANE_OPTIONS: {
|
|
526
|
+
value: "system" | "segment" | "completion" | "event" | "load" | "compiler" | "analytics" | "wellness";
|
|
527
|
+
label: "system" | "segment" | "completion" | "event" | "load" | "compiler" | "analytics" | "wellness";
|
|
528
|
+
}[];
|
|
338
529
|
declare const TIME_OPTIONS: {
|
|
339
530
|
value: string;
|
|
340
531
|
label: string;
|
|
@@ -344,17 +535,20 @@ declare const AGG_OPTIONS: {
|
|
|
344
535
|
value: "max" | "min" | "sum" | "avg" | "count" | "last" | "delta";
|
|
345
536
|
label: "max" | "min" | "sum" | "avg" | "count" | "last" | "delta";
|
|
346
537
|
}[];
|
|
538
|
+
/** Multi-unit bucket widths — parse accepts any `N>1` + d|w (single-unit
|
|
539
|
+
* day/week grouping is `by {day}`/`by {week}`, never `.rollup(1w)`); the
|
|
540
|
+
* list is common suggestions, typed widths are parser-validated. */
|
|
347
541
|
declare const ROLLUP_OPTIONS: {
|
|
348
|
-
value:
|
|
542
|
+
value: string;
|
|
349
543
|
label: string;
|
|
350
544
|
}[];
|
|
351
545
|
declare const GROUPBY_OPTIONS: {
|
|
352
|
-
value: "result" | "day" | "
|
|
353
|
-
label: "result" | "day" | "
|
|
546
|
+
value: "format" | "origin" | "result" | "day" | "page" | "domain" | "round" | "metric" | "note" | "week" | "effort" | "intensity" | "session" | "equipment" | "quality" | "intent" | "discipline" | "block" | "grade" | "grain" | "tags";
|
|
547
|
+
label: "format" | "origin" | "result" | "day" | "page" | "domain" | "round" | "metric" | "note" | "week" | "effort" | "intensity" | "session" | "equipment" | "quality" | "intent" | "discipline" | "block" | "grade" | "grain" | "tags";
|
|
354
548
|
}[];
|
|
355
549
|
declare const METRIC_OPTIONS: {
|
|
356
|
-
value: "
|
|
357
|
-
label: "
|
|
550
|
+
value: "distance" | "resistance" | "elapsed" | "totalVolume" | "totalDistance" | "tis" | "sessionLoad" | "reps" | "power" | "pace" | "calc.metMinutes" | "calc.acwr" | "calc.monotony" | "calc.strain" | "calc.e1rm" | "calc.ctl" | "calc.atl" | "calc.tsb" | "calc.soreness" | "calc.sleep" | "calc.hrv" | "calc.readiness" | "calc.mvcBw" | "calc.ef" | "calc.adherence" | "calc.pct1rm" | "calc.sends";
|
|
551
|
+
label: "distance" | "resistance" | "elapsed" | "totalVolume" | "totalDistance" | "tis" | "sessionLoad" | "reps" | "power" | "pace" | "calc.metMinutes" | "calc.acwr" | "calc.monotony" | "calc.strain" | "calc.e1rm" | "calc.ctl" | "calc.atl" | "calc.tsb" | "calc.soreness" | "calc.sleep" | "calc.hrv" | "calc.readiness" | "calc.mvcBw" | "calc.ef" | "calc.adherence" | "calc.pct1rm" | "calc.sends";
|
|
358
552
|
}[];
|
|
359
553
|
declare const UNIT_OPTIONS: {
|
|
360
554
|
value: "kg" | "lb";
|
|
@@ -367,7 +561,6 @@ declare const UNIT_OPTIONS: {
|
|
|
367
561
|
*/
|
|
368
562
|
declare const WHERE_AGGREGATORS: readonly string[];
|
|
369
563
|
declare const WHERE_METRICS: readonly string[];
|
|
370
|
-
declare const WHERE_OPERATORS: readonly string[];
|
|
371
564
|
interface ClauseMeta {
|
|
372
565
|
label: string;
|
|
373
566
|
inputType: 'radio' | 'freetext' | 'select';
|
|
@@ -385,109 +578,88 @@ declare const CLAUSE_META: Record<ClauseType, ClauseMeta>;
|
|
|
385
578
|
* anything else gets a generic fallback so a stale clause still renders.
|
|
386
579
|
*/
|
|
387
580
|
declare function getClauseMeta(type: string): ClauseMeta;
|
|
388
|
-
/**
|
|
389
|
-
* Maps a single clause to its WQL fragment syntax.
|
|
390
|
-
*/
|
|
391
|
-
declare function clauseToWql(clause: QueryClause): {
|
|
392
|
-
key?: string;
|
|
393
|
-
filterStr?: string;
|
|
394
|
-
};
|
|
395
|
-
/**
|
|
396
|
-
* Composes a full WQL string from an array of QueryClauses.
|
|
397
|
-
*
|
|
398
|
-
* Content planes: find:<target>{<filters>} in <scope> [last <n><unit>] [where <join>]
|
|
399
|
-
* — target/scope derived from `source` (journal|collections|feeds → note in
|
|
400
|
-
* <source>; notes → note in all; blocks → block in all; anything else →
|
|
401
|
-
* note in <verbatim value>, the salvage path for exotic scopes).
|
|
402
|
-
* Metrics plane: <agg>:<metric>{<filters>} [by {<dims>}] [.rollup(<p>)] [in <unit>] [where <find join>]
|
|
403
|
-
*/
|
|
404
|
-
declare function clausesToWql(clauses: QueryClause[]): string;
|
|
405
|
-
/**
|
|
406
|
-
* Restore composer clauses from a WQL string — the inverse of
|
|
407
|
-
* `clausesToWql`, used to hydrate composer state from the URL.
|
|
408
|
-
*
|
|
409
|
-
* Unlike `parseQuery`, this is a *salvage* parser: it mirrors the compiler's
|
|
410
|
-
* structure on both planes without validating the fragments, so composer-
|
|
411
|
-
* reachable states that are WQL-invalid (e.g. `text:hello world`, a `1m`
|
|
412
|
-
* rollup period, an empty metric) still restore exactly — the diagnostics
|
|
413
|
-
* strip then attributes the parse error to the offending slot.
|
|
414
|
-
*
|
|
415
|
-
* Returns null when the string cannot be a composer product: a negated
|
|
416
|
-
* filter, or an unknown/custom-less filter key.
|
|
417
|
-
*/
|
|
418
|
-
declare function wqlToClauses(wql: string): QueryClause[] | null;
|
|
419
|
-
/**
|
|
420
|
-
* Set the aggregate metric, re-basing the clause list on the metrics plane
|
|
421
|
-
* when needed (sidebar / launcher flows, issue #839): content planes pivot
|
|
422
|
-
* via `pivotClauses` (shared filters survive), a missing source or metric
|
|
423
|
-
* clause is seeded, and the metric value lands on the first metric clause.
|
|
424
|
-
*/
|
|
425
|
-
declare function setMetricClause(clauses: QueryClause[], metric: string): QueryClause[];
|
|
426
|
-
/**
|
|
427
|
-
* Re-base the clause list on a new source value (decision #836): shared
|
|
428
|
-
* filter clauses survive the pivot; kind-specific clauses are dropped
|
|
429
|
-
* (content plane: time/where and any metrics head; metrics plane: time/
|
|
430
|
-
* where). Pivoting to metrics seeds the head slots (agg=sum, metric empty
|
|
431
|
-
* for placeholder guidance).
|
|
432
|
-
*/
|
|
433
|
-
declare function pivotClauses(clauses: QueryClause[], source: string): QueryClause[];
|
|
434
|
-
declare function defaultClauses(): QueryClause[];
|
|
435
|
-
/** Default clauses for aggregate/metrics queries (source=metrics, agg=sum, empty metric). */
|
|
436
|
-
declare function defaultMetricsClauses(): QueryClause[];
|
|
437
|
-
/**
|
|
438
|
-
* Value of the first clause of `type`, trimmed, or `fallback` when absent or
|
|
439
|
-
* empty. Mirrors the lookup/defaulting `clausesToWql` performs, so consumers
|
|
440
|
-
* (e.g. the Library shelf) share one defaulting rule with the compiler.
|
|
441
|
-
*/
|
|
442
|
-
declare function clauseValue(clauses: QueryClause[], type: string, fallback?: string): string;
|
|
443
581
|
|
|
444
582
|
interface WqlValidationState {
|
|
445
|
-
/** True when the composed WQL parses without error. */
|
|
446
583
|
valid: boolean;
|
|
447
|
-
/** Parser error message when invalid. */
|
|
448
584
|
error?: string;
|
|
449
585
|
}
|
|
450
586
|
interface WqlComposerProps {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
/**
|
|
454
|
-
|
|
455
|
-
/** Fired whenever the clause list changes (add / edit / remove). */
|
|
456
|
-
onClausesChange?: (clauses: QueryClause[]) => void;
|
|
457
|
-
/** Fired (including on mount) with the composed WQL string. */
|
|
458
|
-
onWqlChange?: (wql: string) => void;
|
|
459
|
-
/** Fired (including on mount) with parse validation state. */
|
|
587
|
+
initialQuery?: string;
|
|
588
|
+
query?: string;
|
|
589
|
+
/** Synchronous resolved draft, including invalid exact text. Execution debounce belongs to the host. */
|
|
590
|
+
onQueryChange?: (wql: string) => void;
|
|
460
591
|
onValidationChange?: (state: WqlValidationState) => void;
|
|
461
|
-
/** Fired (including on mount) with the parsed AST. */
|
|
462
592
|
onAstChange?: (ast: AnyParsedQuery) => void;
|
|
463
|
-
/**
|
|
464
|
-
* Fired on Enter when no free text is pending — the run-on-submit signal
|
|
465
|
-
* for hosts like the analytics explorer. Receives the composed WQL.
|
|
466
|
-
*/
|
|
593
|
+
/** Explicit actions receive the current valid draft on the first activation. */
|
|
467
594
|
onSubmit?: (wql: string) => void;
|
|
468
|
-
|
|
595
|
+
actionLabel?: string;
|
|
596
|
+
compact?: boolean;
|
|
469
597
|
showDiagnostics?: boolean;
|
|
470
|
-
|
|
471
|
-
* Executor for live stage counts in the diagnostics strip.
|
|
472
|
-
*/
|
|
598
|
+
diagnosticsPosition?: 'top' | 'bottom';
|
|
473
599
|
execute?: WqlExecutor;
|
|
474
|
-
/**
|
|
600
|
+
/** Reuse host execution counts instead of running another query. */
|
|
601
|
+
stages?: WqlStageCounts;
|
|
475
602
|
debounceMs?: number;
|
|
476
|
-
/** Extension point: extra content rendered inside the bar, after the free-text input. */
|
|
477
603
|
customSlots?: ReactNode;
|
|
478
|
-
/** Host actions appended on the diagnostics line. */
|
|
479
604
|
diagnosticsActions?: ReactNode;
|
|
480
|
-
/**
|
|
481
|
-
* Clause types kept in the model but NOT rendered as pills.
|
|
482
|
-
*/
|
|
483
605
|
hiddenClauseTypes?: ClauseType[];
|
|
484
|
-
/**
|
|
606
|
+
/** Priority only; valid choices are never excluded by favorites. */
|
|
607
|
+
preferredChoices?: readonly string[];
|
|
485
608
|
autoFocus?: boolean;
|
|
486
|
-
/** Free-text input placeholder. */
|
|
487
609
|
placeholder?: string;
|
|
488
610
|
className?: string;
|
|
489
611
|
}
|
|
490
|
-
declare function WqlComposer({
|
|
612
|
+
declare function WqlComposer({ initialQuery, query, onQueryChange, onValidationChange, onAstChange, onSubmit, actionLabel, compact, showDiagnostics, diagnosticsPosition, execute, stages: suppliedStages, debounceMs, customSlots, diagnosticsActions, hiddenClauseTypes, preferredChoices, autoFocus, placeholder, className, }: WqlComposerProps): react.JSX.Element;
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* filterTypeahead — matches free text typed into the WqlComposer's input
|
|
616
|
+
* against the filter-clause vocabulary (queryClauses). While the user types
|
|
617
|
+
* a filter key ('so', 'inten', 'eff'…) the composer proposes adding that
|
|
618
|
+
* filter — or, when a pill of that type is already on the query, editing it.
|
|
619
|
+
* Accept (Tab or tap) adds/activates the pill and opens its condition
|
|
620
|
+
* editor; the composer owns candidates (source-plane allowlist, existing
|
|
621
|
+
* pills, hidden types) and the accept behavior.
|
|
622
|
+
*
|
|
623
|
+
* Pure module: no React.
|
|
624
|
+
*/
|
|
625
|
+
interface FilterTypeaheadCandidate {
|
|
626
|
+
/** Clause type key, e.g. 'source' | 'effort' | 'catalog'. */
|
|
627
|
+
type: string;
|
|
628
|
+
label: string;
|
|
629
|
+
/** Placeholder describing the condition, e.g. 'journal, notes, metrics…'. */
|
|
630
|
+
hint: string;
|
|
631
|
+
icon: string;
|
|
632
|
+
/** True when a pill of this type is already on the query — accept edits it. */
|
|
633
|
+
present: boolean;
|
|
634
|
+
/** Index of the existing pill when `present`. */
|
|
635
|
+
pillIdx?: number;
|
|
636
|
+
}
|
|
637
|
+
interface FilterTypeaheadMatch extends FilterTypeaheadCandidate {
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Match the typed text against candidate filter keys/labels: prefix match on
|
|
641
|
+
* the type key first, then the display label; shorter keys rank first within
|
|
642
|
+
* the same class. Mid-WQL text (whitespace, braces, or a `:` — the
|
|
643
|
+
* composer's query/raw/invalid pending paths own that) proposes nothing.
|
|
644
|
+
*/
|
|
645
|
+
declare function matchFilterTypeahead(freeText: string, candidates: FilterTypeaheadCandidate[]): FilterTypeaheadMatch[];
|
|
646
|
+
|
|
647
|
+
interface TokenSlotPillProps {
|
|
648
|
+
clause: QueryClause;
|
|
649
|
+
isActive?: boolean;
|
|
650
|
+
invalid?: boolean;
|
|
651
|
+
invalidReason?: string;
|
|
652
|
+
onClick?: () => void;
|
|
653
|
+
onRemove?: () => void;
|
|
654
|
+
compact?: boolean;
|
|
655
|
+
placeholderOverride?: string;
|
|
656
|
+
}
|
|
657
|
+
declare function TokenSlotPill({ clause, isActive, invalid, invalidReason, onClick, onRemove, compact, placeholderOverride, }: TokenSlotPillProps): react.JSX.Element;
|
|
658
|
+
|
|
659
|
+
/** Multi-select (toggle-in-place) clause types. `source` is independently
|
|
660
|
+
* multi-select — applySourceFilter ORs the scope values. Typed tag keys and
|
|
661
|
+
* `groupby` OR their values in the engine (value lists join with `|`). */
|
|
662
|
+
declare const MULTI_VALUE_TYPES: Record<string, true>;
|
|
491
663
|
|
|
492
664
|
interface CustomSlotEditorProps<TValue> {
|
|
493
665
|
value: TValue | undefined;
|
|
@@ -515,47 +687,14 @@ declare class ComposerRegistry {
|
|
|
515
687
|
private cachedList;
|
|
516
688
|
registerSlot<TValue>(def: CustomSlotDefinition<TValue>): () => void;
|
|
517
689
|
unregisterSlot(type: string): void;
|
|
518
|
-
getSlot(type: string): CustomSlotDefinition
|
|
519
|
-
listSlots(): CustomSlotDefinition
|
|
520
|
-
getAllSlots(): CustomSlotDefinition
|
|
690
|
+
getSlot(type: string): CustomSlotDefinition | undefined;
|
|
691
|
+
listSlots(): CustomSlotDefinition[];
|
|
692
|
+
getAllSlots(): CustomSlotDefinition[];
|
|
521
693
|
subscribe(listener: () => void): () => void;
|
|
522
694
|
private notify;
|
|
523
695
|
}
|
|
524
696
|
declare const composerRegistry: ComposerRegistry;
|
|
525
|
-
declare function useComposerSlots(registry?: ComposerRegistry): CustomSlotDefinition
|
|
526
|
-
|
|
527
|
-
interface TokenSlotPillProps {
|
|
528
|
-
clause: QueryClause;
|
|
529
|
-
isActive?: boolean;
|
|
530
|
-
invalid?: boolean;
|
|
531
|
-
invalidReason?: string;
|
|
532
|
-
onClick?: () => void;
|
|
533
|
-
onRemove?: () => void;
|
|
534
|
-
onChange?: (patch: Partial<QueryClause>) => void;
|
|
535
|
-
compact?: boolean;
|
|
536
|
-
placeholderOverride?: string;
|
|
537
|
-
}
|
|
538
|
-
declare function TokenSlotPill({ clause, isActive, invalid, invalidReason, onClick, onRemove, onChange, compact, placeholderOverride, }: TokenSlotPillProps): react.JSX.Element;
|
|
539
|
-
declare const MULTI_VALUE_TYPES: Record<string, true>;
|
|
540
|
-
declare function ClausePopover({ clause, onClose, onChange, }: {
|
|
541
|
-
clause: QueryClause;
|
|
542
|
-
onClose: () => void;
|
|
543
|
-
onChange: (patch: Partial<QueryClause>) => void;
|
|
544
|
-
}): react.JSX.Element;
|
|
545
|
-
declare function CustomSlotPopover<TValue>({ clause, definition, onClose, onChange, }: {
|
|
546
|
-
clause: QueryClause;
|
|
547
|
-
definition: CustomSlotDefinition<TValue>;
|
|
548
|
-
onClose: () => void;
|
|
549
|
-
onChange: (value: TValue) => void;
|
|
550
|
-
}): react.JSX.Element;
|
|
551
|
-
declare function AddFilterDropdown({ clauses, onAdd, }: {
|
|
552
|
-
clauses: QueryClause[];
|
|
553
|
-
onAdd: (clause: QueryClause) => void;
|
|
554
|
-
}): react.JSX.Element;
|
|
555
|
-
declare function AddCalcDropdown({ clauses, onAdd, }: {
|
|
556
|
-
clauses: QueryClause[];
|
|
557
|
-
onAdd: (clause: QueryClause) => void;
|
|
558
|
-
}): react.JSX.Element | null;
|
|
697
|
+
declare function useComposerSlots(registry?: ComposerRegistry): CustomSlotDefinition[];
|
|
559
698
|
|
|
560
699
|
interface DateRange {
|
|
561
700
|
start: string;
|
|
@@ -581,7 +720,17 @@ interface SuggestionBinding {
|
|
|
581
720
|
declare function tagsFromStaticBlocks(blocks: BlockIndexRow[]): string[];
|
|
582
721
|
declare function catalogIdsFromBlocks(blocks: BlockIndexRow[]): string[];
|
|
583
722
|
declare function blockTypesFromBlocks(blocks: BlockIndexRow[]): string[];
|
|
723
|
+
/** Tags: user labels rank first with their spelling, corpus fills the rest —
|
|
724
|
+
* one case-insensitive dedup path, insertion order kept (no global sort). */
|
|
584
725
|
declare function mergeTagSuggestions(userLabels: string[], corpusLabels: string[]): string[];
|
|
726
|
+
/** Canonical static block types — actual indexed corpus types rank ahead at runtime. */
|
|
727
|
+
declare const CANONICAL_BLOCK_TYPES: readonly ["wod", "movement", "workout"];
|
|
728
|
+
/** Suggestion items for a canonical readonly vocabulary; labels are display-only. */
|
|
729
|
+
declare function canonicalSuggestionItems(values: readonly string[]): SuggestionItem[];
|
|
730
|
+
/** Case-insensitive dedup by value key: vault entries keep their position,
|
|
731
|
+
* enum keys take the canonical spelling, then remaining canonical values
|
|
732
|
+
* append. First label wins — it is display-only. */
|
|
733
|
+
declare function mergeSuggestionItems(vault: SuggestionItem[], canonical: SuggestionItem[]): SuggestionItem[];
|
|
585
734
|
declare const SUGGESTION_BINDINGS: Record<string, SuggestionBinding>;
|
|
586
735
|
declare function setSuggestionBinding(type: string, binding: SuggestionBinding | undefined): void;
|
|
587
736
|
declare function getSuggestionBinding(type: string): SuggestionBinding | undefined;
|
|
@@ -599,7 +748,7 @@ declare function useSuggestions(type: string): ClauseSuggestions;
|
|
|
599
748
|
|
|
600
749
|
interface WqlDiagnostics {
|
|
601
750
|
valid: boolean;
|
|
602
|
-
/**
|
|
751
|
+
/** Exact resolved draft text, including invalid input. */
|
|
603
752
|
wql: string;
|
|
604
753
|
ast: AnyParsedQuery;
|
|
605
754
|
error?: string;
|
|
@@ -609,6 +758,7 @@ interface WqlFindSummary {
|
|
|
609
758
|
target: string;
|
|
610
759
|
scope: string;
|
|
611
760
|
timeWindow?: string;
|
|
761
|
+
groupBy?: string;
|
|
612
762
|
hasJoin: boolean;
|
|
613
763
|
filterCount: number;
|
|
614
764
|
}
|
|
@@ -624,16 +774,102 @@ interface WqlAggregateSummary {
|
|
|
624
774
|
filterCount: number;
|
|
625
775
|
}
|
|
626
776
|
declare function summarizeAggregate(ast: ParsedAggregateQuery): WqlAggregateSummary;
|
|
627
|
-
|
|
777
|
+
interface WqlPipelineSummary {
|
|
778
|
+
source: string;
|
|
779
|
+
/** One entry per transform stage, in order — `sum:tis`, `avg:load`, … */
|
|
780
|
+
functions: string[];
|
|
781
|
+
sink?: string;
|
|
782
|
+
timeWindow?: string;
|
|
783
|
+
filterCount: number;
|
|
784
|
+
}
|
|
785
|
+
declare function summarizePipeline(ast: ParsedPipelineQuery): WqlPipelineSummary;
|
|
628
786
|
|
|
629
787
|
interface WqlDiagnosticsStripProps {
|
|
630
788
|
diagnostics: WqlDiagnostics;
|
|
631
789
|
offendingLabel?: string;
|
|
632
790
|
stages?: WqlStageCounts;
|
|
791
|
+
/** Hide the AST summary chips (target/scope/time or agg/metric/by…) —
|
|
792
|
+
* header contexts where the pills right below already show that state. */
|
|
793
|
+
hideSummary?: boolean;
|
|
794
|
+
/** 'card' (default) renders the rounded, bordered bubble. 'header' renders
|
|
795
|
+
* a flat header section separated from the composer by an accent line. */
|
|
796
|
+
variant?: 'card' | 'header';
|
|
633
797
|
actions?: ReactNode;
|
|
634
798
|
className?: string;
|
|
635
799
|
}
|
|
636
|
-
declare function WqlDiagnosticsStrip({ diagnostics, offendingLabel, stages, actions, className, }: WqlDiagnosticsStripProps): react.JSX.Element;
|
|
800
|
+
declare function WqlDiagnosticsStrip({ diagnostics, offendingLabel, stages, hideSummary, variant, actions, className, }: WqlDiagnosticsStripProps): react.JSX.Element;
|
|
801
|
+
|
|
802
|
+
interface QueryDraft {
|
|
803
|
+
wql: string;
|
|
804
|
+
ast: AnyParsedQuery;
|
|
805
|
+
valid: boolean;
|
|
806
|
+
error?: string;
|
|
807
|
+
}
|
|
808
|
+
declare function wqlToPills(wql: string): QueryClause[] | null;
|
|
809
|
+
declare function editQueryClause(query: string, edited: QueryClause, value: string | null): QueryDraft;
|
|
810
|
+
declare function resolveQueryDraft(query: string, pendingText?: string): QueryDraft;
|
|
811
|
+
|
|
812
|
+
interface EditorDialogProps {
|
|
813
|
+
/** Controls visibility; the dialog unmounts its portal when closed. */
|
|
814
|
+
open: boolean;
|
|
815
|
+
onClose: () => void;
|
|
816
|
+
/** Dialog heading (aria-labelledby target). */
|
|
817
|
+
title: string;
|
|
818
|
+
/** Optional secondary line under the title (aria-describedby target). */
|
|
819
|
+
description?: string;
|
|
820
|
+
/** Body content — scrolls independently of the header/footer. */
|
|
821
|
+
children: ReactNode;
|
|
822
|
+
/** Sticky footer (e.g. Cancel/Save) — pinned above the keyboard on mobile. */
|
|
823
|
+
footer?: ReactNode;
|
|
824
|
+
/** 'default' (centered/full-screen, unchanged) or 'sheet' (mobile bottom
|
|
825
|
+
* sheet over the lower visible viewport, non-input initial focus,
|
|
826
|
+
* safe-area footer; desktop keeps the centered panel). */
|
|
827
|
+
presentation?: 'default' | 'sheet';
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* EditorDialog — accessible editor surface shared by dashboard/effort/note
|
|
831
|
+
* editing flows.
|
|
832
|
+
*
|
|
833
|
+
* Deliberately NOT a native `<dialog>`: the top layer would obscure any
|
|
834
|
+
* body-portaled surfaces a host renders above it (the WQL composer's
|
|
835
|
+
* hover/touch affordances, palette results). This renders a plain fixed
|
|
836
|
+
* overlay via portal, so portaled content keeps painting and receiving
|
|
837
|
+
* clicks/focus above it.
|
|
838
|
+
*
|
|
839
|
+
* Focus containment is lenient by the same constraint: Tab cycles within the
|
|
840
|
+
* dialog only while focus is inside it — focus that moves into a body-portaled
|
|
841
|
+
* popover is never yanked back, and the popover keeps its own keyboard
|
|
842
|
+
* handling. Escape is handled at the dialog container, so Escape consumed by
|
|
843
|
+
* a popover (e.g. to dismiss it) does not also close the dialog.
|
|
844
|
+
*
|
|
845
|
+
* Mobile (< sm): full visual-viewport screen driven by `window.visualViewport`
|
|
846
|
+
* (falls back to `100dvh`) — the keyboard shrinking the viewport lifts the
|
|
847
|
+
* footer, never the focused field. Desktop (sm+): contained centered panel.
|
|
848
|
+
*/
|
|
849
|
+
declare function EditorDialog({ open, onClose, title, description, children, footer, presentation, }: EditorDialogProps): react.ReactPortal | null;
|
|
850
|
+
|
|
851
|
+
interface VisualViewportRect {
|
|
852
|
+
/**
|
|
853
|
+
* Visible viewport height in px, or null when the VisualViewport API is
|
|
854
|
+
* unavailable (SSR, older engines). Consumers should fall back to a
|
|
855
|
+
* dynamic-viewport unit (e.g. `100dvh`) in that case.
|
|
856
|
+
*/
|
|
857
|
+
height: number | null;
|
|
858
|
+
/** Distance from the layout viewport top to the visual viewport top (pinch-zoom). */
|
|
859
|
+
offsetTop: number;
|
|
860
|
+
/**
|
|
861
|
+
* Distance the visual viewport's bottom edge sits above the layout
|
|
862
|
+
* viewport's bottom edge — i.e. the on-screen keyboard's height (0 when
|
|
863
|
+
* the keyboard is closed).
|
|
864
|
+
*/
|
|
865
|
+
offsetBottom: number;
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Tracks `window.visualViewport` (resize + scroll). Drives keyboard-aware
|
|
869
|
+
* bottom-anchored UI (dialogs, thumb docks) without keyboard-size guessing
|
|
870
|
+
* or browser sniffing: the platform reports the visible rectangle.
|
|
871
|
+
*/
|
|
872
|
+
declare function useVisualViewportRect(): VisualViewportRect;
|
|
637
873
|
|
|
638
874
|
declare function cn(...inputs: ClassValue[]): string;
|
|
639
875
|
declare function hashCode(str: string): number;
|
|
@@ -658,13 +894,13 @@ declare function patchBlockQuery(blockContent: string, newQuery: string, queryIn
|
|
|
658
894
|
* Auto-generated build version metadata.
|
|
659
895
|
* Do not edit directly; updated by scripts/stamp-version.ts
|
|
660
896
|
*/
|
|
661
|
-
declare const VERSION = "0.
|
|
662
|
-
declare const GIT_SHA = "
|
|
663
|
-
declare const BUILD_TIME = "2026-
|
|
897
|
+
declare const VERSION = "0.35.2115";
|
|
898
|
+
declare const GIT_SHA = "37944a8";
|
|
899
|
+
declare const BUILD_TIME = "2026-10-11T23:54:36.367Z";
|
|
664
900
|
declare const SEMVER: {
|
|
665
|
-
readonly version: "0.
|
|
666
|
-
readonly gitSha: "
|
|
667
|
-
readonly buildTime: "2026-
|
|
901
|
+
readonly version: "0.35.2115";
|
|
902
|
+
readonly gitSha: "37944a8";
|
|
903
|
+
readonly buildTime: "2026-10-11T23:54:36.367Z";
|
|
668
904
|
};
|
|
669
905
|
|
|
670
|
-
export { AGG_OPTIONS, ANALYTICS_UNIT_STORAGE_KEY,
|
|
906
|
+
export { AGG_OPTIONS, ANALYTICS_UNIT_STORAGE_KEY, type AnalyticsQueriesState, type AnalyticsQueryDef, type AnalyticsRangeWeeks, type AnalyticsUnit, AnalyticsUnitPreference, type AnalyticsUnitPreferenceProps, BUILD_TIME, CANONICAL_BLOCK_TYPES, CLAUSE_META, CODEMIRROR_SINGLETON_DEPS, type CategorizedMetrics, type ChartShape, type ClauseMeta, type ClauseSuggestions, type ClauseType, ComposerRegistry, type CustomSlotDefinition, type CustomSlotEditorProps, DEFAULT_ANALYTICS_UNIT, DEFAULT_DIAGNOSTICS_DEBOUNCE_MS, DEFAULT_OUTPUT_FILTERS, DEFAULT_PRIMARY_FILTER, type DashboardHeadingAnchor, DashboardTokenControls, type DashboardTokenControlsProps, DashboardView, type DashboardViewProps, type DateRange, EditorDialog, type EditorDialogProps, type ExtractedQuery, type FilterTypeaheadCandidate, type FilterTypeaheadMatch, GIT_SHA, GROUPBY_OPTIONS, GoalRings, type GoalRingsProps, KIND_OPTIONS, METRIC_OPTIONS, MULTI_VALUE_TYPES, type MergedPoint, MetricBadge, OUTPUT_TYPE_CLASS, OUTPUT_TYPE_DOT, type OutputFilterInput, OutputFilterPills, type OutputFilterPreset, type OutputStatementRow, OutputStatementsTable, type OutputStatementsTableProps, PLANE_OPTIONS, ProposedMetricBadge, QueryBlockView, type QueryBlockViewProps, type QueryClause, type QueryDraft, QueryExecutor, QueryValue, type QueryValueProps, ROLLUP_OPTIONS, RangeSelector, type RangeSelectorProps, RowsResultsChrome, type RowsResultsChromeProps, RowsTable, type RowsTableProps, SEMVER, SERIES_COLORS, SOURCE_OPTIONS, SUGGESTION_BINDINGS, StackedBar, type StackedBarProps, type StorageLike, type SuggestionBinding, type SuggestionCachePolicy, type SuggestionItem, TARGET_OPTIONS, TIME_OPTIONS, TONE_CLASS, TokenSlotPill, type TokenSlotPillProps, TopList, type TopListProps, UNIT_OPTIONS, VERSION, type VisualViewportRect, WHERE_AGGREGATORS, WHERE_METRICS, WidgetChart, type WidgetChartProps, WidgetEditButton, WidgetFrame, type WidgetFrameProps, WidgetProblemBadge, type WidgetSpanOption, WidgetToolButton, type WqlAggregateSummary, WqlBars, type WqlBarsProps, WqlComposer, type WqlComposerProps, type WqlDiagnostics, WqlDiagnosticsStrip, type WqlDiagnosticsStripProps, WqlEmptyState, type WqlEmptyStateProps, type WqlExecutor, type WqlFindSummary, type WqlPipelineSummary, WqlQueryInspectorModal, type WqlQueryInspectorModalProps, type WqlStageCounts, WqlTable, type WqlTableProps, WqlTimeseries, type WqlTimeseriesProps, type WqlValidationState, ZoneDistribution, type ZoneDistributionProps, blockTypesFromBlocks, canonicalSuggestionItems, catalogIdsFromBlocks, cn, compactNumber, composerRegistry, dateRangeSlot, editQueryClause, extractBlockQueries, extractMetricsByCategory, formatClockTime, formatMMSS, formatTimestamp, getClauseMeta, getDashboardEffectiveUnit, getEffectiveAnalyticsUnit, getSuggestionBinding, hashCode, invalidateSuggestions, loadSuggestions, matchFilterTypeahead, mergeSeries, mergeSuggestionItems, mergeTagSuggestions, normalizeOutputFilter, patchBlockQuery, presentBadges, readSessionRpe, readStoredUnit, resolveQueryDraft, setSuggestionBinding, summarizeAggregate, summarizeFind, summarizePipeline, tagsFromStaticBlocks, tooltipTimestamp, useAnalyticsQueries, useAnalyticsUnitPreference, useChartShape, useComposerSlots, useSuggestions, useVisualViewportRect, useWqlStageCounts, wqlToPills };
|