@grafana/scenes 6.37.0--canary.1240.17829532252.0 → 6.37.0--canary.1250.17837997062.0
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/esm/behaviors/SceneRenderProfiler.js +2 -65
- package/dist/esm/behaviors/SceneRenderProfiler.js.map +1 -1
- package/dist/esm/behaviors/index.js +0 -1
- package/dist/esm/behaviors/index.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js +4 -1
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js +16 -15
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js.map +1 -1
- package/dist/esm/variables/groupby/GroupByVariable.js +0 -8
- package/dist/esm/variables/groupby/GroupByVariable.js.map +1 -1
- package/dist/index.d.ts +0 -26
- package/dist/index.js +18 -124
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/esm/behaviors/SceneInteractionTracker.js +0 -30
- package/dist/esm/behaviors/SceneInteractionTracker.js.map +0 -1
- package/dist/esm/core/sceneGraph/getInteractionTracker.js +0 -19
- package/dist/esm/core/sceneGraph/getInteractionTracker.js.map +0 -1
|
@@ -16,7 +16,7 @@ var __privateWrapper = (obj, member, setter, getter) => ({
|
|
|
16
16
|
return __privateGet(obj, member, getter);
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
|
-
var _profileInProgress,
|
|
19
|
+
var _profileInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans, _longFrameDetector, _longFramesCount, _longFramesTotalTime, _visibilityChangeHandler;
|
|
20
20
|
const POST_STORM_WINDOW = 2e3;
|
|
21
21
|
const DEFAULT_LONG_FRAME_THRESHOLD = 30;
|
|
22
22
|
const TAB_INACTIVE_THRESHOLD = 1e3;
|
|
@@ -24,7 +24,6 @@ class SceneRenderProfiler {
|
|
|
24
24
|
constructor(queryController) {
|
|
25
25
|
this.queryController = queryController;
|
|
26
26
|
__privateAdd(this, _profileInProgress, null);
|
|
27
|
-
__privateAdd(this, _interactionInProgress, null);
|
|
28
27
|
__privateAdd(this, _profileStartTs, null);
|
|
29
28
|
__privateAdd(this, _trailAnimationFrameId, null);
|
|
30
29
|
// Will keep measured lengths trailing frames
|
|
@@ -34,7 +33,6 @@ class SceneRenderProfiler {
|
|
|
34
33
|
__privateAdd(this, _longFramesCount, 0);
|
|
35
34
|
__privateAdd(this, _longFramesTotalTime, 0);
|
|
36
35
|
__privateAdd(this, _visibilityChangeHandler, null);
|
|
37
|
-
__privateAdd(this, _onInteractionComplete, null);
|
|
38
36
|
this.measureTrailingFrames = (measurementStartTs, lastFrameTime, profileStartTs) => {
|
|
39
37
|
var _a, _b, _c, _d;
|
|
40
38
|
const currentFrameTime = performance.now();
|
|
@@ -151,14 +149,10 @@ class SceneRenderProfiler {
|
|
|
151
149
|
};
|
|
152
150
|
__privateSet(this, _longFrameDetector, new LongFrameDetector());
|
|
153
151
|
this.setupVisibilityChangeHandler();
|
|
154
|
-
__privateSet(this, _interactionInProgress, null);
|
|
155
152
|
}
|
|
156
153
|
setQueryController(queryController) {
|
|
157
154
|
this.queryController = queryController;
|
|
158
155
|
}
|
|
159
|
-
setInteractionCompleteHandler(handler) {
|
|
160
|
-
__privateSet(this, _onInteractionComplete, handler != null ? handler : null);
|
|
161
|
-
}
|
|
162
156
|
setupVisibilityChangeHandler() {
|
|
163
157
|
if (__privateGet(this, _visibilityChangeHandler)) {
|
|
164
158
|
return;
|
|
@@ -197,55 +191,6 @@ class SceneRenderProfiler {
|
|
|
197
191
|
this._startNewProfile(name);
|
|
198
192
|
}
|
|
199
193
|
}
|
|
200
|
-
startInteraction(interaction) {
|
|
201
|
-
if (__privateGet(this, _interactionInProgress)) {
|
|
202
|
-
writeSceneLog("profile", "Cancelled interaction:", __privateGet(this, _interactionInProgress));
|
|
203
|
-
__privateSet(this, _interactionInProgress, null);
|
|
204
|
-
}
|
|
205
|
-
__privateSet(this, _interactionInProgress, {
|
|
206
|
-
interaction,
|
|
207
|
-
startTs: performance.now()
|
|
208
|
-
});
|
|
209
|
-
writeSceneLog("SceneRenderProfiler", "Started interaction:", interaction);
|
|
210
|
-
}
|
|
211
|
-
stopInteraction() {
|
|
212
|
-
if (!__privateGet(this, _interactionInProgress)) {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
const endTs = performance.now();
|
|
216
|
-
const interactionDuration = endTs - __privateGet(this, _interactionInProgress).startTs;
|
|
217
|
-
const networkDuration = captureNetwork(__privateGet(this, _interactionInProgress).startTs, endTs);
|
|
218
|
-
writeSceneLog("SceneRenderProfiler", "Completed interaction:");
|
|
219
|
-
writeSceneLog("", ` \u251C\u2500 Total time: ${interactionDuration.toFixed(1)}ms`);
|
|
220
|
-
writeSceneLog("", ` \u251C\u2500 Network duration: ${networkDuration.toFixed(1)}ms`);
|
|
221
|
-
writeSceneLog("", ` \u251C\u2500 StartTs: ${__privateGet(this, _interactionInProgress).startTs.toFixed(1)}ms`);
|
|
222
|
-
writeSceneLog("", ` \u2514\u2500 EndTs: ${endTs.toFixed(1)}ms`);
|
|
223
|
-
if (__privateGet(this, _onInteractionComplete) && __privateGet(this, _profileInProgress)) {
|
|
224
|
-
__privateGet(this, _onInteractionComplete).call(this, {
|
|
225
|
-
origin: __privateGet(this, _interactionInProgress).interaction,
|
|
226
|
-
duration: interactionDuration,
|
|
227
|
-
networkDuration,
|
|
228
|
-
startTs: __privateGet(this, _interactionInProgress).startTs,
|
|
229
|
-
endTs
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
performance.mark(`${__privateGet(this, _interactionInProgress).interaction}_start`, {
|
|
233
|
-
startTime: __privateGet(this, _interactionInProgress).startTs
|
|
234
|
-
});
|
|
235
|
-
performance.mark(`${__privateGet(this, _interactionInProgress).interaction}_end`, {
|
|
236
|
-
startTime: endTs
|
|
237
|
-
});
|
|
238
|
-
performance.measure(
|
|
239
|
-
`Interaction_${__privateGet(this, _interactionInProgress).interaction}`,
|
|
240
|
-
`${__privateGet(this, _interactionInProgress).interaction}_start`,
|
|
241
|
-
`${__privateGet(this, _interactionInProgress).interaction}_end`
|
|
242
|
-
);
|
|
243
|
-
__privateSet(this, _interactionInProgress, null);
|
|
244
|
-
}
|
|
245
|
-
getCurrentInteraction() {
|
|
246
|
-
var _a, _b;
|
|
247
|
-
return (_b = (_a = __privateGet(this, _interactionInProgress)) == null ? void 0 : _a.interaction) != null ? _b : null;
|
|
248
|
-
}
|
|
249
194
|
/**
|
|
250
195
|
* Starts a new profile for performance measurement.
|
|
251
196
|
*
|
|
@@ -291,9 +236,6 @@ class SceneRenderProfiler {
|
|
|
291
236
|
}
|
|
292
237
|
tryCompletingProfile() {
|
|
293
238
|
var _a;
|
|
294
|
-
if (!__privateGet(this, _profileInProgress)) {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
239
|
writeSceneLog("SceneRenderProfiler", "Trying to complete profile", __privateGet(this, _profileInProgress));
|
|
298
240
|
if (((_a = this.queryController) == null ? void 0 : _a.runningQueriesCount()) === 0 && __privateGet(this, _profileInProgress)) {
|
|
299
241
|
writeSceneLog("SceneRenderProfiler", "All queries completed, starting tail measurement");
|
|
@@ -334,7 +276,6 @@ class SceneRenderProfiler {
|
|
|
334
276
|
}
|
|
335
277
|
}
|
|
336
278
|
_profileInProgress = new WeakMap();
|
|
337
|
-
_interactionInProgress = new WeakMap();
|
|
338
279
|
_profileStartTs = new WeakMap();
|
|
339
280
|
_trailAnimationFrameId = new WeakMap();
|
|
340
281
|
_recordedTrailingSpans = new WeakMap();
|
|
@@ -342,7 +283,6 @@ _longFrameDetector = new WeakMap();
|
|
|
342
283
|
_longFramesCount = new WeakMap();
|
|
343
284
|
_longFramesTotalTime = new WeakMap();
|
|
344
285
|
_visibilityChangeHandler = new WeakMap();
|
|
345
|
-
_onInteractionComplete = new WeakMap();
|
|
346
286
|
function processRecordedSpans(spans) {
|
|
347
287
|
for (let i = spans.length - 1; i >= 0; i--) {
|
|
348
288
|
if (spans[i] > DEFAULT_LONG_FRAME_THRESHOLD) {
|
|
@@ -392,9 +332,6 @@ const FILTER_CHANGED_INTERACTION = "filter_changed";
|
|
|
392
332
|
const FILTER_RESTORED_INTERACTION = "filter_restored";
|
|
393
333
|
const VARIABLE_VALUE_CHANGED_INTERACTION = "variable_value_changed";
|
|
394
334
|
const SCOPES_CHANGED_INTERACTION = "scopes_changed";
|
|
395
|
-
const ADHOC_KEYS_DROPDOWN_INTERACTION = "adhoc_keys_dropdown";
|
|
396
|
-
const ADHOC_VALUES_DROPDOWN_INTERACTION = "adhoc_values_dropdown";
|
|
397
|
-
const GROUPBY_DIMENSIONS_INTERACTION = "groupby_dimensions";
|
|
398
335
|
|
|
399
|
-
export {
|
|
336
|
+
export { FILTER_CHANGED_INTERACTION, FILTER_REMOVED_INTERACTION, FILTER_RESTORED_INTERACTION, REFRESH_INTERACTION, SCOPES_CHANGED_INTERACTION, SceneRenderProfiler, TIME_RANGE_CHANGE_INTERACTION, VARIABLE_VALUE_CHANGED_INTERACTION, calculateNetworkTime, captureNetwork, processRecordedSpans };
|
|
400
337
|
//# sourceMappingURL=SceneRenderProfiler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writeSceneLog, writeSceneLogStyled } from '../utils/writeSceneLog';\nimport { SceneQueryControllerLike, LongFrameEvent, SceneComponentInteractionEvent } from './types';\nimport { LongFrameDetector } from './LongFrameDetector';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst DEFAULT_LONG_FRAME_THRESHOLD = 30; // Threshold for tail recording slow frames\nconst TAB_INACTIVE_THRESHOLD = 1000; // Tab inactive threshold in ms\n\n/**\n * SceneRenderProfiler tracks dashboard interaction performance including:\n * - Total interaction duration\n * - Network time\n * - Long frame detection (50ms threshold) during interaction using LoAF API (default) or manual tracking (fallback)\n * - Slow frame detection (30ms threshold) for tail recording after interaction\n *\n * Long frame detection during interaction:\n * - 50ms threshold aligned with LoAF API default\n * - LoAF API preferred (Chrome 123+) with manual fallback\n * - Provides script attribution when using LoAF API\n *\n * Slow frame detection for tail recording:\n * - 30ms threshold for post-interaction monitoring\n * - Manual frame timing measurement\n * - Captures rendering delays after user interaction completes\n */\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n // Profile origin, i.e. scene refresh picker\n origin: string;\n crumbs: string[];\n } | null = null;\n\n #interactionInProgress: {\n interaction: string;\n startTs: number;\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Will keep measured lengths trailing frames\n #recordedTrailingSpans: number[] = [];\n\n // Long frame tracking\n #longFrameDetector: LongFrameDetector;\n #longFramesCount = 0;\n #longFramesTotalTime = 0;\n\n #visibilityChangeHandler: (() => void) | null = null;\n #onInteractionComplete: ((event: SceneComponentInteractionEvent) => void) | null = null;\n\n public constructor(private queryController?: SceneQueryControllerLike) {\n this.#longFrameDetector = new LongFrameDetector();\n this.setupVisibilityChangeHandler();\n this.#interactionInProgress = null;\n }\n\n public setQueryController(queryController: SceneQueryControllerLike) {\n this.queryController = queryController;\n }\n\n public setInteractionCompleteHandler(handler?: (event: SceneComponentInteractionEvent) => void) {\n this.#onInteractionComplete = handler ?? null;\n }\n\n private setupVisibilityChangeHandler() {\n // Ensure event listener is only added once\n if (this.#visibilityChangeHandler) {\n return;\n }\n\n // Handle tab switching with Page Visibility API\n this.#visibilityChangeHandler = () => {\n if (document.hidden && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Tab became inactive, cancelling profile');\n this.cancelProfile();\n }\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', this.#visibilityChangeHandler);\n }\n }\n\n public cleanup() {\n // Remove event listener to prevent memory leaks\n if (this.#visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.#visibilityChangeHandler);\n this.#visibilityChangeHandler = null;\n }\n\n // Cleanup long frame tracking\n this.#longFrameDetector.stop();\n\n // Cancel any ongoing profiling\n this.cancelProfile();\n }\n\n public startProfile(name: string) {\n // Only start profile if tab is active. This makes sure we don't start a profile when i.e. someone opens a dashboard in a new tab\n // and doesn't interact with it.\n if (document.hidden) {\n writeSceneLog('SceneRenderProfiler', 'Tab is inactive, skipping profile', name);\n return;\n }\n\n if (this.#profileInProgress) {\n if (this.#trailAnimationFrameId) {\n this.cancelProfile();\n this._startNewProfile(name, true);\n } else {\n this.addCrumb(name);\n }\n } else {\n this._startNewProfile(name);\n }\n }\n\n public startInteraction(interaction: string) {\n // Cancel any existing interaction recording\n if (this.#interactionInProgress) {\n writeSceneLog('profile', 'Cancelled interaction:', this.#interactionInProgress);\n this.#interactionInProgress = null;\n }\n\n this.#interactionInProgress = {\n interaction,\n startTs: performance.now(),\n };\n\n writeSceneLog('SceneRenderProfiler', 'Started interaction:', interaction);\n }\n\n public stopInteraction() {\n if (!this.#interactionInProgress) {\n return;\n }\n\n const endTs = performance.now();\n const interactionDuration = endTs - this.#interactionInProgress.startTs;\n\n // Capture network requests that occurred during the interaction\n const networkDuration = captureNetwork(this.#interactionInProgress.startTs, endTs);\n\n writeSceneLog('SceneRenderProfiler', 'Completed interaction:');\n writeSceneLog('', ` ├─ Total time: ${interactionDuration.toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Network duration: ${networkDuration.toFixed(1)}ms`);\n writeSceneLog('', ` ├─ StartTs: ${this.#interactionInProgress.startTs.toFixed(1)}ms`);\n writeSceneLog('', ` └─ EndTs: ${endTs.toFixed(1)}ms`);\n\n if (this.#onInteractionComplete && this.#profileInProgress) {\n this.#onInteractionComplete({\n origin: this.#interactionInProgress.interaction,\n duration: interactionDuration,\n networkDuration,\n startTs: this.#interactionInProgress.startTs,\n endTs,\n });\n }\n\n // Create performance marks for browser dev tools\n performance.mark(`${this.#interactionInProgress.interaction}_start`, {\n startTime: this.#interactionInProgress.startTs,\n });\n performance.mark(`${this.#interactionInProgress.interaction}_end`, {\n startTime: endTs,\n });\n performance.measure(\n `Interaction_${this.#interactionInProgress.interaction}`,\n `${this.#interactionInProgress.interaction}_start`,\n `${this.#interactionInProgress.interaction}_end`\n );\n\n this.#interactionInProgress = null;\n }\n\n public getCurrentInteraction(): string | null {\n return this.#interactionInProgress?.interaction ?? null;\n }\n\n /**\n * Starts a new profile for performance measurement.\n *\n * @param name - The origin/trigger of the profile (e.g., 'time_range_change', 'variable_value_changed')\n * @param force - Whether this is a \"forced\" profile (true) or \"clean\" profile (false)\n * - \"forced\": Started by canceling an existing profile that was recording trailing frames\n * This happens when a new user interaction occurs before the previous one\n * finished measuring its performance impact\n * - \"clean\": Started when no profile is currently active\n */\n private _startNewProfile(name: string, force = false) {\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n\n // Add performance mark for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark) {\n const markName = `Dashboard Profile Start: ${name}`;\n performance.mark(markName);\n }\n\n // Log profile start in structured format\n writeSceneLogStyled(\n 'SceneRenderProfiler',\n `Profile started[${force ? 'forced' : 'clean'}]`,\n 'color: #FFCC00; font-weight: bold;'\n );\n writeSceneLog('', ` ├─ Origin: ${this.#profileInProgress?.origin || 'unknown'}`);\n writeSceneLog('', ` └─ Timestamp: ${this.#profileStartTs.toFixed(1)}ms`);\n\n // Start long frame detection with callback\n this.#longFrameDetector.start((event: LongFrameEvent) => {\n // Only record long frames during active profiling\n if (!this.#profileInProgress || !this.#profileStartTs) {\n return;\n }\n\n // Only record frames that occur after profile started\n if (event.timestamp < this.#profileStartTs) {\n return;\n }\n\n this.#longFramesCount++;\n this.#longFramesTotalTime += event.duration;\n });\n }\n\n private recordProfileTail(measurementStartTime: number, profileStartTs: number) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTime, measurementStartTime, profileStartTs)\n );\n }\n\n private measureTrailingFrames = (measurementStartTs: number, lastFrameTime: number, profileStartTs: number) => {\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - lastFrameTime;\n\n // Fallback: Detect if tab was inactive (frame longer than reasonable threshold)\n // This serves as backup to Page Visibility API in case the event wasn't triggered\n if (frameLength > TAB_INACTIVE_THRESHOLD) {\n writeSceneLog('SceneRenderProfiler', 'Tab was inactive, cancelling profile measurement');\n this.cancelProfile();\n return;\n }\n\n this.#recordedTrailingSpans.push(frameLength);\n\n if (currentFrameTime - measurementStartTs! < POST_STORM_WINDOW) {\n if (this.#profileInProgress) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTs, currentFrameTime, profileStartTs)\n );\n }\n } else {\n const slowFrames = processRecordedSpans(this.#recordedTrailingSpans);\n const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);\n\n // Log tail recording in structured format\n writeSceneLog(\n 'SceneRenderProfiler',\n `Profile tail recorded - Slow frames: ${slowFramesTime.toFixed(1)}ms (${slowFrames.length} frames)`\n );\n writeSceneLog('', ` ├─ Origin: ${this.#profileInProgress?.origin || 'unknown'}`);\n writeSceneLog('', ` └─ Crumbs:`, this.#profileInProgress?.crumbs || []);\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n // Add performance marks for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark) {\n const profileName = this.#profileInProgress?.origin || 'unknown';\n const totalTime = profileDuration + slowFramesTime;\n\n // Mark profile completion\n performance.mark(`Dashboard Profile End: ${profileName}`);\n\n // Add measure from start to end if possible\n const startMarkName = `Dashboard Profile Start: ${profileName}`;\n try {\n performance.measure(\n `Dashboard Profile: ${profileName} (${totalTime.toFixed(1)}ms)`,\n startMarkName,\n `Dashboard Profile End: ${profileName}`\n );\n } catch {\n // Start mark might not exist, create a simple end mark\n performance.mark(`Dashboard Profile Complete: ${profileName} (${totalTime.toFixed(1)}ms)`);\n }\n\n // Add measurements for slow frame details if significant\n if (slowFrames.length > 0) {\n const slowFramesMarkName = `Slow Frames Summary: ${slowFrames.length} frames (${slowFramesTime.toFixed(\n 1\n )}ms)`;\n performance.mark(slowFramesMarkName);\n\n // Create individual measurements for each slow frame during tail\n slowFrames.forEach((frameTime, index) => {\n if (frameTime > 16) {\n // Only measure frames slower than 16ms (60fps)\n try {\n const frameStartTime =\n this.#profileStartTs! +\n profileDuration +\n (index > 0 ? slowFrames.slice(0, index).reduce((sum, t) => sum + t, 0) : 0);\n const frameId = `slow-frame-${index}`;\n const frameStartMark = `${frameId}-start`;\n const frameEndMark = `${frameId}-end`;\n\n performance.mark(frameStartMark, { startTime: frameStartTime });\n performance.mark(frameEndMark, { startTime: frameStartTime + frameTime });\n performance.measure(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`, frameStartMark, frameEndMark);\n } catch {\n // Fallback if startTime not supported\n performance.mark(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`);\n }\n }\n });\n }\n }\n\n // Log performance summary in a structured format\n const completionTimestamp = performance.now();\n writeSceneLog('SceneRenderProfiler', 'Profile completed');\n writeSceneLog('', ` ├─ Timestamp: ${completionTimestamp.toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Total time: ${(profileDuration + slowFramesTime).toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Slow frames: ${slowFramesTime}ms (${slowFrames.length} frames)`);\n writeSceneLog('', ` └─ Long frames: ${this.#longFramesTotalTime}ms (${this.#longFramesCount} frames)`);\n\n // Stop long frame detection now that the profile is complete\n this.#longFrameDetector.stop();\n writeSceneLogStyled(\n 'SceneRenderProfiler',\n `Stopped long frame detection - profile complete at ${completionTimestamp.toFixed(1)}ms`,\n 'color: #00CC00; font-weight: bold;'\n );\n\n this.#trailAnimationFrameId = null;\n\n const profileEndTs = profileStartTs + profileDuration + slowFramesTime;\n\n // Guard against race condition where profile might be cancelled during execution\n if (!this.#profileInProgress) {\n return;\n }\n\n performance.measure(`DashboardInteraction ${this.#profileInProgress.origin}`, {\n start: profileStartTs,\n end: profileEndTs,\n });\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.queryController?.state.onProfileComplete && this.#profileInProgress) {\n this.queryController.state.onProfileComplete({\n origin: this.#profileInProgress.origin,\n crumbs: this.#profileInProgress.crumbs,\n duration: profileDuration + slowFramesTime,\n networkDuration,\n startTs: profileStartTs,\n endTs: profileEndTs,\n longFramesCount: this.#longFramesCount,\n longFramesTotalTime: this.#longFramesTotalTime,\n // @ts-ignore\n jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,\n // @ts-ignore\n usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,\n // @ts-ignore\n totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0,\n });\n\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n }\n // @ts-ignore\n if (window.__runs) {\n // @ts-ignore\n window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n } else {\n // @ts-ignore\n window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n }\n }\n };\n\n public tryCompletingProfile() {\n if (!this.#profileInProgress) {\n return;\n }\n\n writeSceneLog('SceneRenderProfiler', 'Trying to complete profile', this.#profileInProgress);\n if (this.queryController?.runningQueriesCount() === 0 && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'All queries completed, starting tail measurement');\n // Note: Long frame detector continues running during tail measurement\n // It will be stopped when the profile completely finishes\n this.recordProfileTail(performance.now(), this.#profileStartTs!);\n }\n }\n\n public isTailRecording() {\n return Boolean(this.#trailAnimationFrameId);\n }\n\n public cancelTailRecording() {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n writeSceneLog('SceneRenderProfiler', 'Cancelled recording frames, new profile started');\n }\n }\n\n // cancel profile\n public cancelProfile() {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Cancelling profile', this.#profileInProgress);\n this.#profileInProgress = null;\n // Cancel any pending animation frame to prevent accessing null profileInProgress\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n }\n // Stop long frame tracking\n this.#longFrameDetector.stop();\n writeSceneLog('SceneRenderProfiler', 'Stopped long frame detection - profile cancelled');\n // Reset recorded spans to ensure complete cleanup\n this.#recordedTrailingSpans = [];\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Adding crumb:', crumb);\n this.#profileInProgress.crumbs.push(crumb);\n }\n }\n}\n\nexport function processRecordedSpans(spans: number[]) {\n // identify last span in spans that's bigger than default threshold\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > DEFAULT_LONG_FRAME_THRESHOLD) {\n return spans.slice(0, i + 1);\n }\n }\n return [spans[0]];\n}\n\nexport function captureNetwork(startTs: number, endTs: number) {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n performance.clearResourceTimings();\n // Only include network entries that both started AND ended within the time window\n const networkEntries = entries.filter(\n (entry) =>\n entry.startTime >= startTs &&\n entry.startTime <= endTs &&\n entry.responseEnd >= startTs &&\n entry.responseEnd <= endTs\n );\n for (const entry of networkEntries) {\n performance.measure('Network entry ' + entry.name, {\n start: entry.startTime,\n end: entry.responseEnd,\n });\n }\n\n return calculateNetworkTime(networkEntries);\n}\n\n// Will calculate total time spent on Network\nexport function calculateNetworkTime(requests: PerformanceResourceTiming[]): number {\n if (requests.length === 0) {\n return 0;\n }\n\n // Step 1: Sort the requests by startTs\n requests.sort((a, b) => a.startTime - b.startTime);\n\n // Step 2: Initialize variables\n let totalNetworkTime = 0;\n let currentStart = requests[0].startTime;\n let currentEnd = requests[0].responseEnd;\n\n // Step 3: Iterate through the sorted list and merge overlapping intervals\n for (let i = 1; i < requests.length; i++) {\n if (requests[i].startTime <= currentEnd) {\n // Overlapping intervals, merge them\n currentEnd = Math.max(currentEnd, requests[i].responseEnd);\n } else {\n // Non-overlapping interval, add the duration to total time\n totalNetworkTime += currentEnd - currentStart;\n\n // Update current interval\n currentStart = requests[i].startTime;\n currentEnd = requests[i].responseEnd;\n }\n }\n\n // Step 4: Add the last interval\n totalNetworkTime += currentEnd - currentStart;\n\n return totalNetworkTime;\n}\n\nexport const REFRESH_INTERACTION = 'refresh';\nexport const TIME_RANGE_CHANGE_INTERACTION = 'time_range_change';\nexport const FILTER_ADDED_INTERACTION = 'filter_added';\nexport const FILTER_REMOVED_INTERACTION = 'filter_removed';\nexport const FILTER_CHANGED_INTERACTION = 'filter_changed';\nexport const FILTER_RESTORED_INTERACTION = 'filter_restored';\nexport const VARIABLE_VALUE_CHANGED_INTERACTION = 'variable_value_changed';\nexport const SCOPES_CHANGED_INTERACTION = 'scopes_changed';\nexport const ADHOC_KEYS_DROPDOWN_INTERACTION = 'adhoc_keys_dropdown';\nexport const ADHOC_VALUES_DROPDOWN_INTERACTION = 'adhoc_values_dropdown';\nexport const GROUPBY_DIMENSIONS_INTERACTION = 'groupby_dimensions';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writeSceneLog, writeSceneLogStyled } from '../utils/writeSceneLog';\nimport { SceneQueryControllerLike, LongFrameEvent } from './types';\nimport { LongFrameDetector } from './LongFrameDetector';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst DEFAULT_LONG_FRAME_THRESHOLD = 30; // Threshold for tail recording slow frames\nconst TAB_INACTIVE_THRESHOLD = 1000; // Tab inactive threshold in ms\n\n/**\n * SceneRenderProfiler tracks dashboard interaction performance including:\n * - Total interaction duration\n * - Network time\n * - Long frame detection (50ms threshold) during interaction using LoAF API (default) or manual tracking (fallback)\n * - Slow frame detection (30ms threshold) for tail recording after interaction\n *\n * Long frame detection during interaction:\n * - 50ms threshold aligned with LoAF API default\n * - LoAF API preferred (Chrome 123+) with manual fallback\n * - Provides script attribution when using LoAF API\n *\n * Slow frame detection for tail recording:\n * - 30ms threshold for post-interaction monitoring\n * - Manual frame timing measurement\n * - Captures rendering delays after user interaction completes\n */\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n // Profile origin, i.e. scene refresh picker\n origin: string;\n crumbs: string[];\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Will keep measured lengths trailing frames\n #recordedTrailingSpans: number[] = [];\n\n // Long frame tracking\n #longFrameDetector: LongFrameDetector;\n #longFramesCount = 0;\n #longFramesTotalTime = 0;\n\n #visibilityChangeHandler: (() => void) | null = null;\n\n public constructor(private queryController?: SceneQueryControllerLike) {\n this.#longFrameDetector = new LongFrameDetector();\n this.setupVisibilityChangeHandler();\n }\n\n public setQueryController(queryController: SceneQueryControllerLike) {\n this.queryController = queryController;\n }\n\n private setupVisibilityChangeHandler() {\n // Ensure event listener is only added once\n if (this.#visibilityChangeHandler) {\n return;\n }\n\n // Handle tab switching with Page Visibility API\n this.#visibilityChangeHandler = () => {\n if (document.hidden && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Tab became inactive, cancelling profile');\n this.cancelProfile();\n }\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', this.#visibilityChangeHandler);\n }\n }\n\n public cleanup() {\n // Remove event listener to prevent memory leaks\n if (this.#visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.#visibilityChangeHandler);\n this.#visibilityChangeHandler = null;\n }\n\n // Cleanup long frame tracking\n this.#longFrameDetector.stop();\n\n // Cancel any ongoing profiling\n this.cancelProfile();\n }\n\n public startProfile(name: string) {\n // Only start profile if tab is active. This makes sure we don't start a profile when i.e. someone opens a dashboard in a new tab\n // and doesn't interact with it.\n if (document.hidden) {\n writeSceneLog('SceneRenderProfiler', 'Tab is inactive, skipping profile', name);\n return;\n }\n\n if (this.#profileInProgress) {\n if (this.#trailAnimationFrameId) {\n this.cancelProfile();\n this._startNewProfile(name, true);\n } else {\n this.addCrumb(name);\n }\n } else {\n this._startNewProfile(name);\n }\n }\n\n /**\n * Starts a new profile for performance measurement.\n *\n * @param name - The origin/trigger of the profile (e.g., 'time_range_change', 'variable_value_changed')\n * @param force - Whether this is a \"forced\" profile (true) or \"clean\" profile (false)\n * - \"forced\": Started by canceling an existing profile that was recording trailing frames\n * This happens when a new user interaction occurs before the previous one\n * finished measuring its performance impact\n * - \"clean\": Started when no profile is currently active\n */\n private _startNewProfile(name: string, force = false) {\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n\n // Add performance mark for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark) {\n const markName = `Dashboard Profile Start: ${name}`;\n performance.mark(markName);\n }\n\n // Log profile start in structured format\n writeSceneLogStyled(\n 'SceneRenderProfiler',\n `Profile started[${force ? 'forced' : 'clean'}]`,\n 'color: #FFCC00; font-weight: bold;'\n );\n writeSceneLog('', ` ├─ Origin: ${this.#profileInProgress?.origin || 'unknown'}`);\n writeSceneLog('', ` └─ Timestamp: ${this.#profileStartTs.toFixed(1)}ms`);\n\n // Start long frame detection with callback\n this.#longFrameDetector.start((event: LongFrameEvent) => {\n // Only record long frames during active profiling\n if (!this.#profileInProgress || !this.#profileStartTs) {\n return;\n }\n\n // Only record frames that occur after profile started\n if (event.timestamp < this.#profileStartTs) {\n return;\n }\n\n this.#longFramesCount++;\n this.#longFramesTotalTime += event.duration;\n });\n }\n\n private recordProfileTail(measurementStartTime: number, profileStartTs: number) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTime, measurementStartTime, profileStartTs)\n );\n }\n\n private measureTrailingFrames = (measurementStartTs: number, lastFrameTime: number, profileStartTs: number) => {\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - lastFrameTime;\n\n // Fallback: Detect if tab was inactive (frame longer than reasonable threshold)\n // This serves as backup to Page Visibility API in case the event wasn't triggered\n if (frameLength > TAB_INACTIVE_THRESHOLD) {\n writeSceneLog('SceneRenderProfiler', 'Tab was inactive, cancelling profile measurement');\n this.cancelProfile();\n return;\n }\n\n this.#recordedTrailingSpans.push(frameLength);\n\n if (currentFrameTime - measurementStartTs! < POST_STORM_WINDOW) {\n if (this.#profileInProgress) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTs, currentFrameTime, profileStartTs)\n );\n }\n } else {\n const slowFrames = processRecordedSpans(this.#recordedTrailingSpans);\n const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);\n\n // Log tail recording in structured format\n writeSceneLog(\n 'SceneRenderProfiler',\n `Profile tail recorded - Slow frames: ${slowFramesTime.toFixed(1)}ms (${slowFrames.length} frames)`\n );\n writeSceneLog('', ` ├─ Origin: ${this.#profileInProgress?.origin || 'unknown'}`);\n writeSceneLog('', ` └─ Crumbs:`, this.#profileInProgress?.crumbs || []);\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n // Add performance marks for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark) {\n const profileName = this.#profileInProgress?.origin || 'unknown';\n const totalTime = profileDuration + slowFramesTime;\n\n // Mark profile completion\n performance.mark(`Dashboard Profile End: ${profileName}`);\n\n // Add measure from start to end if possible\n const startMarkName = `Dashboard Profile Start: ${profileName}`;\n try {\n performance.measure(\n `Dashboard Profile: ${profileName} (${totalTime.toFixed(1)}ms)`,\n startMarkName,\n `Dashboard Profile End: ${profileName}`\n );\n } catch {\n // Start mark might not exist, create a simple end mark\n performance.mark(`Dashboard Profile Complete: ${profileName} (${totalTime.toFixed(1)}ms)`);\n }\n\n // Add measurements for slow frame details if significant\n if (slowFrames.length > 0) {\n const slowFramesMarkName = `Slow Frames Summary: ${slowFrames.length} frames (${slowFramesTime.toFixed(\n 1\n )}ms)`;\n performance.mark(slowFramesMarkName);\n\n // Create individual measurements for each slow frame during tail\n slowFrames.forEach((frameTime, index) => {\n if (frameTime > 16) {\n // Only measure frames slower than 16ms (60fps)\n try {\n const frameStartTime =\n this.#profileStartTs! +\n profileDuration +\n (index > 0 ? slowFrames.slice(0, index).reduce((sum, t) => sum + t, 0) : 0);\n const frameId = `slow-frame-${index}`;\n const frameStartMark = `${frameId}-start`;\n const frameEndMark = `${frameId}-end`;\n\n performance.mark(frameStartMark, { startTime: frameStartTime });\n performance.mark(frameEndMark, { startTime: frameStartTime + frameTime });\n performance.measure(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`, frameStartMark, frameEndMark);\n } catch {\n // Fallback if startTime not supported\n performance.mark(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`);\n }\n }\n });\n }\n }\n\n // Log performance summary in a structured format\n const completionTimestamp = performance.now();\n writeSceneLog('SceneRenderProfiler', 'Profile completed');\n writeSceneLog('', ` ├─ Timestamp: ${completionTimestamp.toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Total time: ${(profileDuration + slowFramesTime).toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Slow frames: ${slowFramesTime}ms (${slowFrames.length} frames)`);\n writeSceneLog('', ` └─ Long frames: ${this.#longFramesTotalTime}ms (${this.#longFramesCount} frames)`);\n\n // Stop long frame detection now that the profile is complete\n this.#longFrameDetector.stop();\n writeSceneLogStyled(\n 'SceneRenderProfiler',\n `Stopped long frame detection - profile complete at ${completionTimestamp.toFixed(1)}ms`,\n 'color: #00CC00; font-weight: bold;'\n );\n\n this.#trailAnimationFrameId = null;\n\n const profileEndTs = profileStartTs + profileDuration + slowFramesTime;\n\n // Guard against race condition where profile might be cancelled during execution\n if (!this.#profileInProgress) {\n return;\n }\n\n performance.measure(`DashboardInteraction ${this.#profileInProgress.origin}`, {\n start: profileStartTs,\n end: profileEndTs,\n });\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.queryController?.state.onProfileComplete && this.#profileInProgress) {\n this.queryController.state.onProfileComplete({\n origin: this.#profileInProgress.origin,\n crumbs: this.#profileInProgress.crumbs,\n duration: profileDuration + slowFramesTime,\n networkDuration,\n startTs: profileStartTs,\n endTs: profileEndTs,\n longFramesCount: this.#longFramesCount,\n longFramesTotalTime: this.#longFramesTotalTime,\n // @ts-ignore\n jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,\n // @ts-ignore\n usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,\n // @ts-ignore\n totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0,\n });\n\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n }\n // @ts-ignore\n if (window.__runs) {\n // @ts-ignore\n window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n } else {\n // @ts-ignore\n window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n }\n }\n };\n\n public tryCompletingProfile() {\n writeSceneLog('SceneRenderProfiler', 'Trying to complete profile', this.#profileInProgress);\n if (this.queryController?.runningQueriesCount() === 0 && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'All queries completed, starting tail measurement');\n // Note: Long frame detector continues running during tail measurement\n // It will be stopped when the profile completely finishes\n this.recordProfileTail(performance.now(), this.#profileStartTs!);\n }\n }\n\n public isTailRecording() {\n return Boolean(this.#trailAnimationFrameId);\n }\n\n public cancelTailRecording() {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n writeSceneLog('SceneRenderProfiler', 'Cancelled recording frames, new profile started');\n }\n }\n\n // cancel profile\n public cancelProfile() {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Cancelling profile', this.#profileInProgress);\n this.#profileInProgress = null;\n // Cancel any pending animation frame to prevent accessing null profileInProgress\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n }\n // Stop long frame tracking\n this.#longFrameDetector.stop();\n writeSceneLog('SceneRenderProfiler', 'Stopped long frame detection - profile cancelled');\n // Reset recorded spans to ensure complete cleanup\n this.#recordedTrailingSpans = [];\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Adding crumb:', crumb);\n this.#profileInProgress.crumbs.push(crumb);\n }\n }\n}\n\nexport function processRecordedSpans(spans: number[]) {\n // identify last span in spans that's bigger than default threshold\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > DEFAULT_LONG_FRAME_THRESHOLD) {\n return spans.slice(0, i + 1);\n }\n }\n return [spans[0]];\n}\n\nexport function captureNetwork(startTs: number, endTs: number) {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n performance.clearResourceTimings();\n // Only include network entries that both started AND ended within the time window\n const networkEntries = entries.filter(\n (entry) =>\n entry.startTime >= startTs &&\n entry.startTime <= endTs &&\n entry.responseEnd >= startTs &&\n entry.responseEnd <= endTs\n );\n for (const entry of networkEntries) {\n performance.measure('Network entry ' + entry.name, {\n start: entry.startTime,\n end: entry.responseEnd,\n });\n }\n\n return calculateNetworkTime(networkEntries);\n}\n\n// Will calculate total time spent on Network\nexport function calculateNetworkTime(requests: PerformanceResourceTiming[]): number {\n if (requests.length === 0) {\n return 0;\n }\n\n // Step 1: Sort the requests by startTs\n requests.sort((a, b) => a.startTime - b.startTime);\n\n // Step 2: Initialize variables\n let totalNetworkTime = 0;\n let currentStart = requests[0].startTime;\n let currentEnd = requests[0].responseEnd;\n\n // Step 3: Iterate through the sorted list and merge overlapping intervals\n for (let i = 1; i < requests.length; i++) {\n if (requests[i].startTime <= currentEnd) {\n // Overlapping intervals, merge them\n currentEnd = Math.max(currentEnd, requests[i].responseEnd);\n } else {\n // Non-overlapping interval, add the duration to total time\n totalNetworkTime += currentEnd - currentStart;\n\n // Update current interval\n currentStart = requests[i].startTime;\n currentEnd = requests[i].responseEnd;\n }\n }\n\n // Step 4: Add the last interval\n totalNetworkTime += currentEnd - currentStart;\n\n return totalNetworkTime;\n}\n\nexport const REFRESH_INTERACTION = 'refresh';\nexport const TIME_RANGE_CHANGE_INTERACTION = 'time_range_change';\nexport const FILTER_ADDED_INTERACTION = 'filter_added';\nexport const FILTER_REMOVED_INTERACTION = 'filter_removed';\nexport const FILTER_CHANGED_INTERACTION = 'filter_changed';\nexport const FILTER_RESTORED_INTERACTION = 'filter_restored';\nexport const VARIABLE_VALUE_CHANGED_INTERACTION = 'variable_value_changed';\nexport const SCOPES_CHANGED_INTERACTION = 'scopes_changed';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,IAAA,kBAAA,EAAA,eAAA,EAAA,sBAAA,EAAA,sBAAA,EAAA,kBAAA,EAAA,gBAAA,EAAA,oBAAA,EAAA,wBAAA;AAIA,MAAM,iBAAoB,GAAA,GAAA;AAC1B,MAAM,4BAA+B,GAAA,EAAA;AACrC,MAAM,sBAAyB,GAAA,GAAA;AAoBxB,MAAM,mBAAoB,CAAA;AAAA,EAoBxB,YAAoB,eAA4C,EAAA;AAA5C,IAAA,IAAA,CAAA,eAAA,GAAA,eAAA;AAnB3B,IAIW,YAAA,CAAA,IAAA,EAAA,kBAAA,EAAA,IAAA,CAAA;AAEX,IAAiC,YAAA,CAAA,IAAA,EAAA,eAAA,EAAA,IAAA,CAAA;AACjC,IAAwC,YAAA,CAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,CAAA;AAGxC;AAAA,IAAA,YAAA,CAAA,IAAA,EAAA,sBAAA,EAAmC,EAAC,CAAA;AAGpC;AAAA,IAAA,YAAA,CAAA,IAAA,EAAA,kBAAA,CAAA;AACA,IAAmB,YAAA,CAAA,IAAA,EAAA,gBAAA,EAAA,CAAA,CAAA;AACnB,IAAuB,YAAA,CAAA,IAAA,EAAA,oBAAA,EAAA,CAAA,CAAA;AAEvB,IAAgD,YAAA,CAAA,IAAA,EAAA,wBAAA,EAAA,IAAA,CAAA;AAsHhD,IAAA,IAAA,CAAQ,qBAAwB,GAAA,CAAC,kBAA4B,EAAA,aAAA,EAAuB,cAA2B,KAAA;AAlKjH,MAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAmKI,MAAM,MAAA,gBAAA,GAAmB,YAAY,GAAI,EAAA;AACzC,MAAA,MAAM,cAAc,gBAAmB,GAAA,aAAA;AAIvC,MAAA,IAAI,cAAc,sBAAwB,EAAA;AACxC,QAAA,aAAA,CAAc,uBAAuB,kDAAkD,CAAA;AACvF,QAAA,IAAA,CAAK,aAAc,EAAA;AACnB,QAAA;AAAA;AAGF,MAAK,YAAA,CAAA,IAAA,EAAA,sBAAA,CAAA,CAAuB,KAAK,WAAW,CAAA;AAE5C,MAAI,IAAA,gBAAA,GAAmB,qBAAsB,iBAAmB,EAAA;AAC9D,QAAA,IAAI,mBAAK,kBAAoB,CAAA,EAAA;AAC3B,UAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,qBAAA;AAAA,YAAsB,MAClD,IAAA,CAAK,qBAAsB,CAAA,kBAAA,EAAoB,kBAAkB,cAAc;AAAA,WACjF,CAAA;AAAA;AACF,OACK,MAAA;AACL,QAAM,MAAA,UAAA,GAAa,oBAAqB,CAAA,YAAA,CAAA,IAAA,EAAK,sBAAsB,CAAA,CAAA;AACnE,QAAM,MAAA,cAAA,GAAiB,WAAW,MAAO,CAAA,CAAC,KAAK,GAAQ,KAAA,GAAA,GAAM,KAAK,CAAC,CAAA;AAGnE,QAAA,aAAA;AAAA,UACE,qBAAA;AAAA,UACA,wCAAwC,cAAe,CAAA,OAAA,CAAQ,CAAC,CAAC,CAAA,IAAA,EAAO,WAAW,MAAM,CAAA,QAAA;AAAA,SAC3F;AACA,QAAA,aAAA,CAAc,IAAI,CAAgB,uBAAA,EAAA,CAAA,CAAA,EAAA,GAAA,YAAA,CAAA,IAAA,EAAK,wBAAL,IAAyB,GAAA,MAAA,GAAA,EAAA,CAAA,MAAA,KAAU,SAAS,CAAE,CAAA,CAAA;AAChF,QAAA,aAAA,CAAc,IAAI,CAAgB,sBAAA,CAAA,EAAA,CAAA,CAAA,EAAA,GAAA,YAAA,CAAA,IAAA,EAAK,wBAAL,IAAyB,GAAA,MAAA,GAAA,EAAA,CAAA,MAAA,KAAU,EAAE,CAAA;AAEvE,QAAA,YAAA,CAAA,IAAA,EAAK,wBAAyB,EAAC,CAAA;AAE/B,QAAA,MAAM,kBAAkB,kBAAqB,GAAA,cAAA;AAG7C,QAAA,IAAI,OAAO,WAAA,KAAgB,WAAe,IAAA,WAAA,CAAY,IAAM,EAAA;AAC1D,UAAA,MAAM,WAAc,GAAA,CAAA,CAAA,EAAA,GAAA,YAAA,CAAA,IAAA,EAAK,kBAAL,CAAA,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAyB,MAAU,KAAA,SAAA;AACvD,UAAA,MAAM,YAAY,eAAkB,GAAA,cAAA;AAGpC,UAAY,WAAA,CAAA,IAAA,CAAK,CAA0B,uBAAA,EAAA,WAAW,CAAE,CAAA,CAAA;AAGxD,UAAM,MAAA,aAAA,GAAgB,4BAA4B,WAAW,CAAA,CAAA;AAC7D,UAAI,IAAA;AACF,YAAY,WAAA,CAAA,OAAA;AAAA,cACV,sBAAsB,WAAW,CAAA,EAAA,EAAK,SAAU,CAAA,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,CAAA;AAAA,cAC1D,aAAA;AAAA,cACA,0BAA0B,WAAW,CAAA;AAAA,aACvC;AAAA,WACM,CAAA,OAAA,CAAA,EAAA;AAEN,YAAY,WAAA,CAAA,IAAA,CAAK,+BAA+B,WAAW,CAAA,EAAA,EAAK,UAAU,OAAQ,CAAA,CAAC,CAAC,CAAK,GAAA,CAAA,CAAA;AAAA;AAI3F,UAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,YAAA,MAAM,kBAAqB,GAAA,CAAA,qBAAA,EAAwB,UAAW,CAAA,MAAM,YAAY,cAAe,CAAA,OAAA;AAAA,cAC7F;AAAA,aACD,CAAA,GAAA,CAAA;AACD,YAAA,WAAA,CAAY,KAAK,kBAAkB,CAAA;AAGnC,YAAW,UAAA,CAAA,OAAA,CAAQ,CAAC,SAAA,EAAW,KAAU,KAAA;AACvC,cAAA,IAAI,YAAY,EAAI,EAAA;AAElB,gBAAI,IAAA;AACF,kBAAA,MAAM,iBACJ,YAAK,CAAA,IAAA,EAAA,eAAA,CAAA,GACL,mBACC,KAAQ,GAAA,CAAA,GAAI,WAAW,KAAM,CAAA,CAAA,EAAG,KAAK,CAAA,CAAE,OAAO,CAAC,GAAA,EAAK,MAAM,GAAM,GAAA,CAAA,EAAG,CAAC,CAAI,GAAA,CAAA,CAAA;AAC3E,kBAAM,MAAA,OAAA,GAAU,cAAc,KAAK,CAAA,CAAA;AACnC,kBAAM,MAAA,cAAA,GAAiB,GAAG,OAAO,CAAA,MAAA,CAAA;AACjC,kBAAM,MAAA,YAAA,GAAe,GAAG,OAAO,CAAA,IAAA,CAAA;AAE/B,kBAAA,WAAA,CAAY,IAAK,CAAA,cAAA,EAAgB,EAAE,SAAA,EAAW,gBAAgB,CAAA;AAC9D,kBAAA,WAAA,CAAY,KAAK,YAAc,EAAA,EAAE,SAAW,EAAA,cAAA,GAAiB,WAAW,CAAA;AACxE,kBAAY,WAAA,CAAA,OAAA,CAAQ,CAAc,WAAA,EAAA,KAAA,GAAQ,CAAC,CAAA,EAAA,EAAK,SAAU,CAAA,OAAA,CAAQ,CAAC,CAAC,CAAM,EAAA,CAAA,EAAA,cAAA,EAAgB,YAAY,CAAA;AAAA,iBAChG,CAAA,OAAA,CAAA,EAAA;AAEN,kBAAY,WAAA,CAAA,IAAA,CAAK,cAAc,KAAQ,GAAA,CAAC,KAAK,SAAU,CAAA,OAAA,CAAQ,CAAC,CAAC,CAAI,EAAA,CAAA,CAAA;AAAA;AACvE;AACF,aACD,CAAA;AAAA;AACH;AAIF,QAAM,MAAA,mBAAA,GAAsB,YAAY,GAAI,EAAA;AAC5C,QAAA,aAAA,CAAc,uBAAuB,mBAAmB,CAAA;AACxD,QAAA,aAAA,CAAc,IAAI,CAAmB,0BAAA,EAAA,mBAAA,CAAoB,OAAQ,CAAA,CAAC,CAAC,CAAI,EAAA,CAAA,CAAA;AACvE,QAAA,aAAA,CAAc,IAAI,CAAqB,2BAAA,EAAA,CAAA,eAAA,GAAkB,gBAAgB,OAAQ,CAAA,CAAC,CAAC,CAAI,EAAA,CAAA,CAAA;AACvF,QAAA,aAAA,CAAc,IAAI,CAAqB,4BAAA,EAAA,cAAc,CAAO,IAAA,EAAA,UAAA,CAAW,MAAM,CAAU,QAAA,CAAA,CAAA;AACvF,QAAA,aAAA,CAAc,IAAI,CAAqB,4BAAA,EAAA,YAAA,CAAA,IAAA,EAAK,qBAAoB,CAAO,IAAA,EAAA,YAAA,CAAA,IAAA,EAAK,iBAAgB,CAAU,QAAA,CAAA,CAAA;AAGtG,QAAA,YAAA,CAAA,IAAA,EAAK,oBAAmB,IAAK,EAAA;AAC7B,QAAA,mBAAA;AAAA,UACE,qBAAA;AAAA,UACA,CAAsD,mDAAA,EAAA,mBAAA,CAAoB,OAAQ,CAAA,CAAC,CAAC,CAAA,EAAA,CAAA;AAAA,UACpF;AAAA,SACF;AAEA,QAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,IAAA,CAAA;AAE9B,QAAM,MAAA,YAAA,GAAe,iBAAiB,eAAkB,GAAA,cAAA;AAGxD,QAAI,IAAA,CAAC,mBAAK,kBAAoB,CAAA,EAAA;AAC5B,UAAA;AAAA;AAGF,QAAA,WAAA,CAAY,OAAQ,CAAA,CAAA,qBAAA,EAAwB,YAAK,CAAA,IAAA,EAAA,kBAAA,CAAA,CAAmB,MAAM,CAAI,CAAA,EAAA;AAAA,UAC5E,KAAO,EAAA,cAAA;AAAA,UACP,GAAK,EAAA;AAAA,SACN,CAAA;AAED,QAAM,MAAA,eAAA,GAAkB,cAAe,CAAA,cAAA,EAAgB,YAAY,CAAA;AAEnE,QAAA,IAAA,CAAA,CAAI,UAAK,eAAL,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAsB,KAAM,CAAA,iBAAA,KAAqB,mBAAK,kBAAoB,CAAA,EAAA;AAC5E,UAAK,IAAA,CAAA,eAAA,CAAgB,MAAM,iBAAkB,CAAA;AAAA,YAC3C,MAAA,EAAQ,mBAAK,kBAAmB,CAAA,CAAA,MAAA;AAAA,YAChC,MAAA,EAAQ,mBAAK,kBAAmB,CAAA,CAAA,MAAA;AAAA,YAChC,UAAU,eAAkB,GAAA,cAAA;AAAA,YAC5B,eAAA;AAAA,YACA,OAAS,EAAA,cAAA;AAAA,YACT,KAAO,EAAA,YAAA;AAAA,YACP,iBAAiB,YAAK,CAAA,IAAA,EAAA,gBAAA,CAAA;AAAA,YACtB,qBAAqB,YAAK,CAAA,IAAA,EAAA,oBAAA,CAAA;AAAA;AAAA,YAE1B,eAAiB,EAAA,WAAA,CAAY,MAAS,GAAA,WAAA,CAAY,OAAO,eAAkB,GAAA,CAAA;AAAA;AAAA,YAE3E,cAAgB,EAAA,WAAA,CAAY,MAAS,GAAA,WAAA,CAAY,OAAO,cAAiB,GAAA,CAAA;AAAA;AAAA,YAEzE,eAAiB,EAAA,WAAA,CAAY,MAAS,GAAA,WAAA,CAAY,OAAO,eAAkB,GAAA;AAAA,WAC5E,CAAA;AAED,UAAA,YAAA,CAAA,IAAA,EAAK,kBAAqB,EAAA,IAAA,CAAA;AAC1B,UAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,IAAA,CAAA;AAAA;AAGhC,QAAA,IAAI,OAAO,MAAQ,EAAA;AAEjB,UAAA,MAAA,CAAO,UAAU,CAAG,EAAA,IAAA,CAAK,KAAK,CAAA,EAAA,EAAK,kBAAkB,cAAc;AAAA,CAAA;AAAA,SAC9D,MAAA;AAEL,UAAA,MAAA,CAAO,SAAS,CAAG,EAAA,IAAA,CAAK,KAAK,CAAA,EAAA,EAAK,kBAAkB,cAAc;AAAA,CAAA;AAAA;AACpE;AACF,KACF;AA1QE,IAAK,YAAA,CAAA,IAAA,EAAA,kBAAA,EAAqB,IAAI,iBAAkB,EAAA,CAAA;AAChD,IAAA,IAAA,CAAK,4BAA6B,EAAA;AAAA;AACpC,EAEO,mBAAmB,eAA2C,EAAA;AACnE,IAAA,IAAA,CAAK,eAAkB,GAAA,eAAA;AAAA;AACzB,EAEQ,4BAA+B,GAAA;AAErC,IAAA,IAAI,mBAAK,wBAA0B,CAAA,EAAA;AACjC,MAAA;AAAA;AAIF,IAAA,YAAA,CAAA,IAAA,EAAK,0BAA2B,MAAM;AACpC,MAAI,IAAA,QAAA,CAAS,MAAU,IAAA,YAAA,CAAA,IAAA,EAAK,kBAAoB,CAAA,EAAA;AAC9C,QAAA,aAAA,CAAc,uBAAuB,yCAAyC,CAAA;AAC9E,QAAA,IAAA,CAAK,aAAc,EAAA;AAAA;AACrB,KACF,CAAA;AAEA,IAAI,IAAA,OAAO,aAAa,WAAa,EAAA;AACnC,MAAS,QAAA,CAAA,gBAAA,CAAiB,kBAAoB,EAAA,YAAA,CAAA,IAAA,EAAK,wBAAwB,CAAA,CAAA;AAAA;AAC7E;AACF,EAEO,OAAU,GAAA;AAEf,IAAA,IAAI,YAAK,CAAA,IAAA,EAAA,wBAAA,CAAA,IAA4B,OAAO,QAAA,KAAa,WAAa,EAAA;AACpE,MAAS,QAAA,CAAA,mBAAA,CAAoB,kBAAoB,EAAA,YAAA,CAAA,IAAA,EAAK,wBAAwB,CAAA,CAAA;AAC9E,MAAA,YAAA,CAAA,IAAA,EAAK,wBAA2B,EAAA,IAAA,CAAA;AAAA;AAIlC,IAAA,YAAA,CAAA,IAAA,EAAK,oBAAmB,IAAK,EAAA;AAG7B,IAAA,IAAA,CAAK,aAAc,EAAA;AAAA;AACrB,EAEO,aAAa,IAAc,EAAA;AAGhC,IAAA,IAAI,SAAS,MAAQ,EAAA;AACnB,MAAc,aAAA,CAAA,qBAAA,EAAuB,qCAAqC,IAAI,CAAA;AAC9E,MAAA;AAAA;AAGF,IAAA,IAAI,mBAAK,kBAAoB,CAAA,EAAA;AAC3B,MAAA,IAAI,mBAAK,sBAAwB,CAAA,EAAA;AAC/B,QAAA,IAAA,CAAK,aAAc,EAAA;AACnB,QAAK,IAAA,CAAA,gBAAA,CAAiB,MAAM,IAAI,CAAA;AAAA,OAC3B,MAAA;AACL,QAAA,IAAA,CAAK,SAAS,IAAI,CAAA;AAAA;AACpB,KACK,MAAA;AACL,MAAA,IAAA,CAAK,iBAAiB,IAAI,CAAA;AAAA;AAC5B;AACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,gBAAA,CAAiB,IAAc,EAAA,KAAA,GAAQ,KAAO,EAAA;AAtHxD,IAAA,IAAA,EAAA;AAuHI,IAAA,YAAA,CAAA,IAAA,EAAK,oBAAqB,EAAE,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,EAAG,EAAA,CAAA;AACrD,IAAK,YAAA,CAAA,IAAA,EAAA,eAAA,EAAkB,YAAY,GAAI,EAAA,CAAA;AACvC,IAAA,YAAA,CAAA,IAAA,EAAK,gBAAmB,EAAA,CAAA,CAAA;AACxB,IAAA,YAAA,CAAA,IAAA,EAAK,oBAAuB,EAAA,CAAA,CAAA;AAG5B,IAAA,IAAI,OAAO,WAAA,KAAgB,WAAe,IAAA,WAAA,CAAY,IAAM,EAAA;AAC1D,MAAM,MAAA,QAAA,GAAW,4BAA4B,IAAI,CAAA,CAAA;AACjD,MAAA,WAAA,CAAY,KAAK,QAAQ,CAAA;AAAA;AAI3B,IAAA,mBAAA;AAAA,MACE,qBAAA;AAAA,MACA,CAAA,gBAAA,EAAmB,KAAQ,GAAA,QAAA,GAAW,OAAO,CAAA,CAAA,CAAA;AAAA,MAC7C;AAAA,KACF;AACA,IAAA,aAAA,CAAc,IAAI,CAAgB,uBAAA,EAAA,CAAA,CAAA,EAAA,GAAA,YAAA,CAAA,IAAA,EAAK,wBAAL,IAAyB,GAAA,MAAA,GAAA,EAAA,CAAA,MAAA,KAAU,SAAS,CAAE,CAAA,CAAA;AAChF,IAAA,aAAA,CAAc,IAAI,CAAmB,0BAAA,EAAA,YAAA,CAAA,IAAA,EAAK,iBAAgB,OAAQ,CAAA,CAAC,CAAC,CAAI,EAAA,CAAA,CAAA;AAGxE,IAAK,YAAA,CAAA,IAAA,EAAA,kBAAA,CAAA,CAAmB,KAAM,CAAA,CAAC,KAA0B,KAAA;AAEvD,MAAA,IAAI,CAAC,YAAA,CAAA,IAAA,EAAK,kBAAsB,CAAA,IAAA,CAAC,mBAAK,eAAiB,CAAA,EAAA;AACrD,QAAA;AAAA;AAIF,MAAI,IAAA,KAAA,CAAM,SAAY,GAAA,YAAA,CAAA,IAAA,EAAK,eAAiB,CAAA,EAAA;AAC1C,QAAA;AAAA;AAGF,MAAA,gBAAA,CAAA,IAAA,EAAK,gBAAL,CAAA,CAAA,CAAA,EAAA;AACA,MAAK,YAAA,CAAA,IAAA,EAAA,oBAAA,EAAL,YAAK,CAAA,IAAA,EAAA,oBAAA,CAAA,GAAwB,KAAM,CAAA,QAAA,CAAA;AAAA,KACpC,CAAA;AAAA;AACH,EAEQ,iBAAA,CAAkB,sBAA8B,cAAwB,EAAA;AAC9E,IAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,qBAAA;AAAA,MAAsB,MAClD,IAAA,CAAK,qBAAsB,CAAA,oBAAA,EAAsB,sBAAsB,cAAc;AAAA,KACvF,CAAA;AAAA;AACF,EA2JO,oBAAuB,GAAA;AA3ThC,IAAA,IAAA,EAAA;AA4TI,IAAc,aAAA,CAAA,qBAAA,EAAuB,4BAA8B,EAAA,YAAA,CAAA,IAAA,EAAK,kBAAkB,CAAA,CAAA;AAC1F,IAAA,IAAA,CAAA,CAAI,UAAK,eAAL,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAsB,mBAA0B,EAAA,MAAA,CAAA,IAAK,mBAAK,kBAAoB,CAAA,EAAA;AAChF,MAAA,aAAA,CAAc,uBAAuB,kDAAkD,CAAA;AAGvF,MAAA,IAAA,CAAK,iBAAkB,CAAA,WAAA,CAAY,GAAI,EAAA,EAAG,mBAAK,eAAgB,CAAA,CAAA;AAAA;AACjE;AACF,EAEO,eAAkB,GAAA;AACvB,IAAO,OAAA,OAAA,CAAQ,mBAAK,sBAAsB,CAAA,CAAA;AAAA;AAC5C,EAEO,mBAAsB,GAAA;AAC3B,IAAA,IAAI,mBAAK,sBAAwB,CAAA,EAAA;AAC/B,MAAA,oBAAA,CAAqB,mBAAK,sBAAsB,CAAA,CAAA;AAChD,MAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,IAAA,CAAA;AAC9B,MAAA,aAAA,CAAc,uBAAuB,iDAAiD,CAAA;AAAA;AACxF;AACF;AAAA,EAGO,aAAgB,GAAA;AACrB,IAAA,IAAI,mBAAK,kBAAoB,CAAA,EAAA;AAC3B,MAAc,aAAA,CAAA,qBAAA,EAAuB,oBAAsB,EAAA,YAAA,CAAA,IAAA,EAAK,kBAAkB,CAAA,CAAA;AAClF,MAAA,YAAA,CAAA,IAAA,EAAK,kBAAqB,EAAA,IAAA,CAAA;AAE1B,MAAA,IAAI,mBAAK,sBAAwB,CAAA,EAAA;AAC/B,QAAA,oBAAA,CAAqB,mBAAK,sBAAsB,CAAA,CAAA;AAChD,QAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,IAAA,CAAA;AAAA;AAGhC,MAAA,YAAA,CAAA,IAAA,EAAK,oBAAmB,IAAK,EAAA;AAC7B,MAAA,aAAA,CAAc,uBAAuB,kDAAkD,CAAA;AAEvF,MAAA,YAAA,CAAA,IAAA,EAAK,wBAAyB,EAAC,CAAA;AAC/B,MAAA,YAAA,CAAA,IAAA,EAAK,gBAAmB,EAAA,CAAA,CAAA;AACxB,MAAA,YAAA,CAAA,IAAA,EAAK,oBAAuB,EAAA,CAAA,CAAA;AAAA;AAC9B;AACF,EAEO,SAAS,KAAe,EAAA;AAC7B,IAAA,IAAI,mBAAK,kBAAoB,CAAA,EAAA;AAC3B,MAAc,aAAA,CAAA,qBAAA,EAAuB,iBAAiB,KAAK,CAAA;AAC3D,MAAK,YAAA,CAAA,IAAA,EAAA,kBAAA,CAAA,CAAmB,MAAO,CAAA,IAAA,CAAK,KAAK,CAAA;AAAA;AAC3C;AAEJ;AAhVE,kBAAA,GAAA,IAAA,OAAA,EAAA;AAMA,eAAA,GAAA,IAAA,OAAA,EAAA;AACA,sBAAA,GAAA,IAAA,OAAA,EAAA;AAGA,sBAAA,GAAA,IAAA,OAAA,EAAA;AAGA,kBAAA,GAAA,IAAA,OAAA,EAAA;AACA,gBAAA,GAAA,IAAA,OAAA,EAAA;AACA,oBAAA,GAAA,IAAA,OAAA,EAAA;AAEA,wBAAA,GAAA,IAAA,OAAA,EAAA;AAiUK,SAAS,qBAAqB,KAAiB,EAAA;AAEpD,EAAA,KAAA,IAAS,IAAI,KAAM,CAAA,MAAA,GAAS,CAAG,EAAA,CAAA,IAAK,GAAG,CAAK,EAAA,EAAA;AAC1C,IAAI,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,4BAA8B,EAAA;AAC3C,MAAA,OAAO,KAAM,CAAA,KAAA,CAAM,CAAG,EAAA,CAAA,GAAI,CAAC,CAAA;AAAA;AAC7B;AAEF,EAAO,OAAA,CAAC,KAAM,CAAA,CAAC,CAAC,CAAA;AAClB;AAEgB,SAAA,cAAA,CAAe,SAAiB,KAAe,EAAA;AAC7D,EAAM,MAAA,OAAA,GAAU,WAAY,CAAA,gBAAA,CAAiB,UAAU,CAAA;AACvD,EAAA,WAAA,CAAY,oBAAqB,EAAA;AAEjC,EAAA,MAAM,iBAAiB,OAAQ,CAAA,MAAA;AAAA,IAC7B,CAAC,KAAA,KACC,KAAM,CAAA,SAAA,IAAa,OACnB,IAAA,KAAA,CAAM,SAAa,IAAA,KAAA,IACnB,KAAM,CAAA,WAAA,IAAe,OACrB,IAAA,KAAA,CAAM,WAAe,IAAA;AAAA,GACzB;AACA,EAAA,KAAA,MAAW,SAAS,cAAgB,EAAA;AAClC,IAAY,WAAA,CAAA,OAAA,CAAQ,gBAAmB,GAAA,KAAA,CAAM,IAAM,EAAA;AAAA,MACjD,OAAO,KAAM,CAAA,SAAA;AAAA,MACb,KAAK,KAAM,CAAA;AAAA,KACZ,CAAA;AAAA;AAGH,EAAA,OAAO,qBAAqB,cAAc,CAAA;AAC5C;AAGO,SAAS,qBAAqB,QAA+C,EAAA;AAClF,EAAI,IAAA,QAAA,CAAS,WAAW,CAAG,EAAA;AACzB,IAAO,OAAA,CAAA;AAAA;AAIT,EAAA,QAAA,CAAS,KAAK,CAAC,CAAA,EAAG,MAAM,CAAE,CAAA,SAAA,GAAY,EAAE,SAAS,CAAA;AAGjD,EAAA,IAAI,gBAAmB,GAAA,CAAA;AACvB,EAAI,IAAA,YAAA,GAAe,QAAS,CAAA,CAAC,CAAE,CAAA,SAAA;AAC/B,EAAI,IAAA,UAAA,GAAa,QAAS,CAAA,CAAC,CAAE,CAAA,WAAA;AAG7B,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,QAAA,CAAS,QAAQ,CAAK,EAAA,EAAA;AACxC,IAAA,IAAI,QAAS,CAAA,CAAC,CAAE,CAAA,SAAA,IAAa,UAAY,EAAA;AAEvC,MAAA,UAAA,GAAa,KAAK,GAAI,CAAA,UAAA,EAAY,QAAS,CAAA,CAAC,EAAE,WAAW,CAAA;AAAA,KACpD,MAAA;AAEL,MAAA,gBAAA,IAAoB,UAAa,GAAA,YAAA;AAGjC,MAAe,YAAA,GAAA,QAAA,CAAS,CAAC,CAAE,CAAA,SAAA;AAC3B,MAAa,UAAA,GAAA,QAAA,CAAS,CAAC,CAAE,CAAA,WAAA;AAAA;AAC3B;AAIF,EAAA,gBAAA,IAAoB,UAAa,GAAA,YAAA;AAEjC,EAAO,OAAA,gBAAA;AACT;AAEO,MAAM,mBAAsB,GAAA;AAC5B,MAAM,6BAAgC,GAAA;AAEtC,MAAM,0BAA6B,GAAA;AACnC,MAAM,0BAA6B,GAAA;AACnC,MAAM,2BAA8B,GAAA;AACpC,MAAM,kCAAqC,GAAA;AAC3C,MAAM,0BAA6B,GAAA;;;;"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { ActWhenVariableChanged } from './ActWhenVariableChanged.js';
|
|
2
2
|
export { CursorSync } from './CursorSync.js';
|
|
3
3
|
export { SceneQueryController } from './SceneQueryController.js';
|
|
4
|
-
export { SceneInteractionTracker } from './SceneInteractionTracker.js';
|
|
5
4
|
export { LiveNowTimer } from './LiveNowTimer.js';
|
|
6
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t } from '@grafana/i18n';
|
|
2
2
|
import React, { useState, useMemo } from 'react';
|
|
3
|
-
import { isMultiValueOperator } from './AdHocFiltersVariable.js';
|
|
3
|
+
import { isMultiValueOperator, OPERATORS } from './AdHocFiltersVariable.js';
|
|
4
4
|
import { useStyles2, Select, Field, Button } from '@grafana/ui';
|
|
5
5
|
import { css, cx } from '@emotion/css';
|
|
6
6
|
import { ControlsLabel } from '../../utils/ControlsLabel.js';
|
|
@@ -94,11 +94,13 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
};
|
|
97
|
+
const operatorDefinition = OPERATORS.find((op) => filter.operator === op.value);
|
|
97
98
|
const valueSelect = /* @__PURE__ */ React.createElement(
|
|
98
99
|
Select,
|
|
99
100
|
{
|
|
100
101
|
virtualized: true,
|
|
101
102
|
allowCustomValue: (_b = model.state.allowCustomValue) != null ? _b : true,
|
|
103
|
+
createOptionPosition: (operatorDefinition == null ? void 0 : operatorDefinition.isRegex) ? "first" : "last",
|
|
102
104
|
isValidNewOption: (inputValue) => inputValue.trim().length > 0,
|
|
103
105
|
allowCreateWhileLoading: true,
|
|
104
106
|
formatCreateLabel: (inputValue) => `Use custom value: ${inputValue}`,
|
|
@@ -156,6 +158,7 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
|
156
158
|
className: cx(styles.key, isKeysOpen ? styles.widthWhenOpen : void 0),
|
|
157
159
|
width: "auto",
|
|
158
160
|
allowCustomValue: (_c = model.state.allowCustomValue) != null ? _c : true,
|
|
161
|
+
createOptionPosition: (operatorDefinition == null ? void 0 : operatorDefinition.isRegex) ? "first" : "last",
|
|
159
162
|
value: keyValue,
|
|
160
163
|
placeholder: t(
|
|
161
164
|
"grafana-scenes.variables.ad-hoc-filter-renderer.key-select.placeholder-select-label",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdHocFilterRenderer.js","sources":["../../../../src/variables/adhoc/AdHocFilterRenderer.tsx"],"sourcesContent":["import { t } from '@grafana/i18n';\nimport React, { useMemo, useState } from 'react';\n\nimport { AdHocFiltersVariable, AdHocFilterWithLabels, isMultiValueOperator } from './AdHocFiltersVariable';\nimport { GrafanaTheme2, SelectableValue } from '@grafana/data';\nimport { Button, Field, InputActionMeta, Select, useStyles2 } from '@grafana/ui';\nimport { css, cx } from '@emotion/css';\nimport { ControlsLabel } from '../../utils/ControlsLabel';\nimport { getAdhocOptionSearcher } from './getAdhocOptionSearcher';\nimport { handleOptionGroups } from '../utils';\nimport { OptionWithCheckbox } from '../components/VariableValueSelect';\n\ninterface Props {\n filter: AdHocFilterWithLabels;\n model: AdHocFiltersVariable;\n}\n\nfunction keyLabelToOption(key: string, label?: string): SelectableValue | null {\n return key !== ''\n ? {\n value: key,\n label: label || key,\n }\n : null;\n}\n\nconst filterNoOp = () => true;\n\nexport function AdHocFilterRenderer({ filter, model }: Props) {\n const styles = useStyles2(getStyles);\n\n const [keys, setKeys] = useState<SelectableValue[]>([]);\n const [values, setValues] = useState<SelectableValue[]>([]);\n const [isKeysLoading, setIsKeysLoading] = useState(false);\n const [isValuesLoading, setIsValuesLoading] = useState(false);\n const [isKeysOpen, setIsKeysOpen] = useState(false);\n const [isValuesOpen, setIsValuesOpen] = useState(false);\n const [isOperatorOpen, setIsOperatorOpen] = useState(false);\n const [valueInputValue, setValueInputValue] = useState('');\n const [valueHasCustomValue, setValueHasCustomValue] = useState(false);\n // To not trigger queries on every selection we store this state locally here and only update the variable onBlur\n const [uncommittedValue, setUncommittedValue] = useState<SelectableValue>(\n filter.values ? filter.values.map((value, index) => keyLabelToOption(value, filter.valueLabels?.[index])) : []\n );\n const isMultiValue = isMultiValueOperator(filter.operator);\n\n const keyValue = keyLabelToOption(filter.key, filter.keyLabel);\n const valueValue = keyLabelToOption(filter.value, filter.valueLabels?.[0]);\n\n const optionSearcher = useMemo(() => getAdhocOptionSearcher(values), [values]);\n const onAddCustomValue = model.state.onAddCustomValue;\n\n const onValueInputChange = (value: string, { action }: InputActionMeta) => {\n if (action === 'input-change') {\n setValueInputValue(value);\n }\n return value;\n };\n\n const onOperatorChange = (v: SelectableValue) => {\n const existingOperator = filter.operator;\n const newOperator = v.value;\n\n const update: Partial<AdHocFilterWithLabels> = { operator: newOperator };\n // clear value if operator has changed from multi to single\n if (isMultiValueOperator(existingOperator) && !isMultiValueOperator(newOperator)) {\n update.value = '';\n update.valueLabels = [''];\n update.values = undefined;\n setUncommittedValue([]);\n // set values if operator has changed from single to multi\n } else if (!isMultiValueOperator(existingOperator) && isMultiValueOperator(newOperator) && filter.value) {\n update.values = [filter.value];\n setUncommittedValue([\n {\n value: filter.value,\n label: filter.valueLabels?.[0] ?? filter.value,\n },\n ]);\n }\n model._updateFilter(filter, update);\n };\n\n const filteredValueOptions = useMemo(\n () => handleOptionGroups(optionSearcher(valueInputValue)),\n [optionSearcher, valueInputValue]\n );\n\n const multiValueProps = {\n isMulti: true,\n value: uncommittedValue,\n components: {\n Option: OptionWithCheckbox,\n },\n hideSelectedOptions: false,\n closeMenuOnSelect: false,\n openMenuOnFocus: false,\n onChange: (v: SelectableValue) => {\n setUncommittedValue(v);\n // clear input value when creating a new custom multi value\n if (v.some((value: SelectableValue) => value.__isNew__)) {\n setValueInputValue('');\n }\n },\n onBlur: () => {\n model._updateFilter(filter, {\n value: uncommittedValue[0]?.value ?? '',\n // TODO remove expect-error when we're on the latest version of @grafana/data\n values: uncommittedValue.map((option: SelectableValue<string>) => option.value),\n valueLabels: uncommittedValue.map((option: SelectableValue<string>) => option.label),\n });\n },\n };\n\n const valueSelect = (\n <Select\n virtualized\n allowCustomValue={model.state.allowCustomValue ?? true}\n isValidNewOption={(inputValue) => inputValue.trim().length > 0}\n allowCreateWhileLoading\n formatCreateLabel={(inputValue) => `Use custom value: ${inputValue}`}\n disabled={model.state.readOnly}\n className={cx(styles.value, isValuesOpen ? styles.widthWhenOpen : undefined)}\n width=\"auto\"\n value={valueValue}\n filterOption={filterNoOp}\n placeholder={t(\n 'grafana-scenes.variables.ad-hoc-filter-renderer.value-select.placeholder-select-value',\n 'Select value'\n )}\n options={filteredValueOptions}\n inputValue={valueInputValue}\n onInputChange={onValueInputChange}\n onChange={(v) => {\n if (onAddCustomValue && v.__isNew__) {\n model._updateFilter(filter, onAddCustomValue(v, filter));\n } else {\n model._updateFilter(filter, {\n value: v.value,\n valueLabels: v.label ? [v.label] : [v.value],\n });\n }\n\n if (valueHasCustomValue !== v.__isNew__) {\n setValueHasCustomValue(v.__isNew__);\n }\n }}\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n isOpen={isValuesOpen && !isValuesLoading}\n isLoading={isValuesLoading}\n openMenuOnFocus={true}\n onOpenMenu={async () => {\n setIsValuesLoading(true);\n setIsValuesOpen(true);\n const values = await model._getValuesFor(filter);\n setIsValuesLoading(false);\n setValues(values);\n if (valueHasCustomValue) {\n setValueInputValue(valueValue?.label ?? '');\n }\n }}\n onCloseMenu={() => {\n setIsValuesOpen(false);\n setValueInputValue('');\n }}\n {...(isMultiValue && multiValueProps)}\n />\n );\n\n const keySelect = (\n <Select\n // By changing the key, we reset the Select component,\n // to ensure that the loaded values are shown after they are loaded\n key={`${isValuesLoading ? 'loading' : 'loaded'}`}\n disabled={model.state.readOnly}\n className={cx(styles.key, isKeysOpen ? styles.widthWhenOpen : undefined)}\n width=\"auto\"\n allowCustomValue={model.state.allowCustomValue ?? true}\n value={keyValue}\n placeholder={t(\n 'grafana-scenes.variables.ad-hoc-filter-renderer.key-select.placeholder-select-label',\n 'Select label'\n )}\n options={handleOptionGroups(keys)}\n onChange={(v) => {\n model._updateFilter(filter, {\n key: v.value,\n keyLabel: v.label,\n // clear value if key has changed\n value: '',\n valueLabels: [''],\n values: undefined,\n });\n setUncommittedValue([]);\n }}\n autoFocus={filter.key === ''}\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n isOpen={isKeysOpen && !isKeysLoading}\n isLoading={isKeysLoading}\n onOpenMenu={async () => {\n setIsKeysOpen(true);\n setIsKeysLoading(true);\n const keys = await model._getKeys(filter.key);\n setIsKeysLoading(false);\n setKeys(keys);\n }}\n onCloseMenu={() => {\n setIsKeysOpen(false);\n }}\n onBlur={() => {\n if (filter.key === '') {\n model._removeFilter(filter);\n }\n }}\n openMenuOnFocus={true}\n />\n );\n\n const operatorSelect = (\n <Select\n className={cx(styles.operator, {\n [styles.widthWhenOpen]: isOperatorOpen,\n })}\n value={filter.operator}\n disabled={model.state.readOnly}\n options={model._getOperators()}\n onChange={onOperatorChange}\n onOpenMenu={() => {\n setIsOperatorOpen(true);\n }}\n onCloseMenu={() => {\n setIsOperatorOpen(false);\n }}\n />\n );\n\n if (model.state.layout === 'vertical') {\n if (filter.key) {\n const label = (\n <ControlsLabel layout=\"vertical\" label={filter.key ?? ''} onRemove={() => model._removeFilter(filter)} />\n );\n\n return (\n <Field label={label} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n <div className={styles.wrapper}>\n {operatorSelect}\n {valueSelect}\n </div>\n </Field>\n );\n } else {\n return (\n <Field\n label={t('grafana-scenes.variables.ad-hoc-filter-renderer.label-select-label', 'Select label')}\n data-testid={`AdHocFilter-${filter.key}`}\n className={styles.field}\n >\n {keySelect}\n </Field>\n );\n }\n }\n\n return (\n <div className={styles.wrapper} data-testid={`AdHocFilter-${filter.key}`}>\n {keySelect}\n {operatorSelect}\n {valueSelect}\n <Button\n variant=\"secondary\"\n aria-label={t('grafana-scenes.variables.ad-hoc-filter-renderer.aria-label-remove-filter', 'Remove filter')}\n title={t('grafana-scenes.variables.ad-hoc-filter-renderer.title-remove-filter', 'Remove filter')}\n className={styles.removeButton}\n icon=\"times\"\n data-testid={`AdHocFilter-remove-${filter.key ?? ''}`}\n onClick={() => model._removeFilter(filter)}\n />\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n field: css({\n marginBottom: 0,\n }),\n wrapper: css({\n display: 'flex',\n '> *': {\n '&:not(:first-child)': {\n // Negative margin hides the double-border on adjacent selects\n marginLeft: -1,\n },\n\n '&:first-child': {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n },\n\n '&:last-child': {\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n },\n\n '&:not(:first-child):not(:last-child)': {\n borderRadius: 0,\n },\n\n // Fix focus state zIndex issues\n position: 'relative',\n zIndex: 0,\n\n // Adjacent borders are overlapping, so raise children up when hovering etc\n // so all that child's borders are visible.\n '&:hover': {\n zIndex: 1,\n },\n\n '&:focus-within': {\n zIndex: 2,\n },\n },\n }),\n widthWhenOpen: css({\n minWidth: theme.spacing(16),\n }),\n value: css({\n flexBasis: 'content',\n flexShrink: 1,\n minWidth: '90px',\n }),\n key: css({\n flexBasis: 'content',\n minWidth: '90px',\n flexShrink: 1,\n }),\n operator: css({\n flexShrink: 0,\n flexBasis: 'content',\n }),\n removeButton: css({\n paddingLeft: theme.spacing(3 / 2),\n paddingRight: theme.spacing(3 / 2),\n borderLeft: 'none',\n width: theme.spacing(3),\n marginRight: theme.spacing(1),\n boxSizing: 'border-box',\n // To not have button background and last select border intersect\n position: 'relative',\n left: '1px',\n }),\n});\n"],"names":["_a","_b","values","keys"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AdHocFilterRenderer.js","sources":["../../../../src/variables/adhoc/AdHocFilterRenderer.tsx"],"sourcesContent":["import { t } from '@grafana/i18n';\nimport React, { useMemo, useState } from 'react';\n\nimport { AdHocFiltersVariable, AdHocFilterWithLabels, isMultiValueOperator, OPERATORS } from './AdHocFiltersVariable';\nimport { GrafanaTheme2, SelectableValue } from '@grafana/data';\nimport { Button, Field, InputActionMeta, Select, useStyles2 } from '@grafana/ui';\nimport { css, cx } from '@emotion/css';\nimport { ControlsLabel } from '../../utils/ControlsLabel';\nimport { getAdhocOptionSearcher } from './getAdhocOptionSearcher';\nimport { handleOptionGroups } from '../utils';\nimport { OptionWithCheckbox } from '../components/VariableValueSelect';\n\ninterface Props {\n filter: AdHocFilterWithLabels;\n model: AdHocFiltersVariable;\n}\n\nfunction keyLabelToOption(key: string, label?: string): SelectableValue | null {\n return key !== ''\n ? {\n value: key,\n label: label || key,\n }\n : null;\n}\n\nconst filterNoOp = () => true;\n\nexport function AdHocFilterRenderer({ filter, model }: Props) {\n const styles = useStyles2(getStyles);\n\n const [keys, setKeys] = useState<SelectableValue[]>([]);\n const [values, setValues] = useState<SelectableValue[]>([]);\n const [isKeysLoading, setIsKeysLoading] = useState(false);\n const [isValuesLoading, setIsValuesLoading] = useState(false);\n const [isKeysOpen, setIsKeysOpen] = useState(false);\n const [isValuesOpen, setIsValuesOpen] = useState(false);\n const [isOperatorOpen, setIsOperatorOpen] = useState(false);\n const [valueInputValue, setValueInputValue] = useState('');\n const [valueHasCustomValue, setValueHasCustomValue] = useState(false);\n // To not trigger queries on every selection we store this state locally here and only update the variable onBlur\n const [uncommittedValue, setUncommittedValue] = useState<SelectableValue>(\n filter.values ? filter.values.map((value, index) => keyLabelToOption(value, filter.valueLabels?.[index])) : []\n );\n const isMultiValue = isMultiValueOperator(filter.operator);\n\n const keyValue = keyLabelToOption(filter.key, filter.keyLabel);\n const valueValue = keyLabelToOption(filter.value, filter.valueLabels?.[0]);\n\n const optionSearcher = useMemo(() => getAdhocOptionSearcher(values), [values]);\n const onAddCustomValue = model.state.onAddCustomValue;\n\n const onValueInputChange = (value: string, { action }: InputActionMeta) => {\n if (action === 'input-change') {\n setValueInputValue(value);\n }\n return value;\n };\n\n const onOperatorChange = (v: SelectableValue) => {\n const existingOperator = filter.operator;\n const newOperator = v.value;\n\n const update: Partial<AdHocFilterWithLabels> = { operator: newOperator };\n // clear value if operator has changed from multi to single\n if (isMultiValueOperator(existingOperator) && !isMultiValueOperator(newOperator)) {\n update.value = '';\n update.valueLabels = [''];\n update.values = undefined;\n setUncommittedValue([]);\n // set values if operator has changed from single to multi\n } else if (!isMultiValueOperator(existingOperator) && isMultiValueOperator(newOperator) && filter.value) {\n update.values = [filter.value];\n setUncommittedValue([\n {\n value: filter.value,\n label: filter.valueLabels?.[0] ?? filter.value,\n },\n ]);\n }\n model._updateFilter(filter, update);\n };\n\n const filteredValueOptions = useMemo(\n () => handleOptionGroups(optionSearcher(valueInputValue)),\n [optionSearcher, valueInputValue]\n );\n\n const multiValueProps = {\n isMulti: true,\n value: uncommittedValue,\n components: {\n Option: OptionWithCheckbox,\n },\n hideSelectedOptions: false,\n closeMenuOnSelect: false,\n openMenuOnFocus: false,\n onChange: (v: SelectableValue) => {\n setUncommittedValue(v);\n // clear input value when creating a new custom multi value\n if (v.some((value: SelectableValue) => value.__isNew__)) {\n setValueInputValue('');\n }\n },\n onBlur: () => {\n model._updateFilter(filter, {\n value: uncommittedValue[0]?.value ?? '',\n // TODO remove expect-error when we're on the latest version of @grafana/data\n values: uncommittedValue.map((option: SelectableValue<string>) => option.value),\n valueLabels: uncommittedValue.map((option: SelectableValue<string>) => option.label),\n });\n },\n };\n\n const operatorDefinition = OPERATORS.find((op) => filter.operator === op.value);\n\n const valueSelect = (\n <Select\n virtualized\n allowCustomValue={model.state.allowCustomValue ?? true}\n createOptionPosition={operatorDefinition?.isRegex ? 'first' : 'last'}\n isValidNewOption={(inputValue) => inputValue.trim().length > 0}\n allowCreateWhileLoading\n formatCreateLabel={(inputValue) => `Use custom value: ${inputValue}`}\n disabled={model.state.readOnly}\n className={cx(styles.value, isValuesOpen ? styles.widthWhenOpen : undefined)}\n width=\"auto\"\n value={valueValue}\n filterOption={filterNoOp}\n placeholder={t(\n 'grafana-scenes.variables.ad-hoc-filter-renderer.value-select.placeholder-select-value',\n 'Select value'\n )}\n options={filteredValueOptions}\n inputValue={valueInputValue}\n onInputChange={onValueInputChange}\n onChange={(v) => {\n if (onAddCustomValue && v.__isNew__) {\n model._updateFilter(filter, onAddCustomValue(v, filter));\n } else {\n model._updateFilter(filter, {\n value: v.value,\n valueLabels: v.label ? [v.label] : [v.value],\n });\n }\n\n if (valueHasCustomValue !== v.__isNew__) {\n setValueHasCustomValue(v.__isNew__);\n }\n }}\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n isOpen={isValuesOpen && !isValuesLoading}\n isLoading={isValuesLoading}\n openMenuOnFocus={true}\n onOpenMenu={async () => {\n setIsValuesLoading(true);\n setIsValuesOpen(true);\n const values = await model._getValuesFor(filter);\n setIsValuesLoading(false);\n setValues(values);\n if (valueHasCustomValue) {\n setValueInputValue(valueValue?.label ?? '');\n }\n }}\n onCloseMenu={() => {\n setIsValuesOpen(false);\n setValueInputValue('');\n }}\n {...(isMultiValue && multiValueProps)}\n />\n );\n\n const keySelect = (\n <Select\n // By changing the key, we reset the Select component,\n // to ensure that the loaded values are shown after they are loaded\n key={`${isValuesLoading ? 'loading' : 'loaded'}`}\n disabled={model.state.readOnly}\n className={cx(styles.key, isKeysOpen ? styles.widthWhenOpen : undefined)}\n width=\"auto\"\n allowCustomValue={model.state.allowCustomValue ?? true}\n createOptionPosition={operatorDefinition?.isRegex ? 'first' : 'last'}\n value={keyValue}\n placeholder={t(\n 'grafana-scenes.variables.ad-hoc-filter-renderer.key-select.placeholder-select-label',\n 'Select label'\n )}\n options={handleOptionGroups(keys)}\n onChange={(v) => {\n model._updateFilter(filter, {\n key: v.value,\n keyLabel: v.label,\n // clear value if key has changed\n value: '',\n valueLabels: [''],\n values: undefined,\n });\n setUncommittedValue([]);\n }}\n autoFocus={filter.key === ''}\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n isOpen={isKeysOpen && !isKeysLoading}\n isLoading={isKeysLoading}\n onOpenMenu={async () => {\n setIsKeysOpen(true);\n setIsKeysLoading(true);\n const keys = await model._getKeys(filter.key);\n setIsKeysLoading(false);\n setKeys(keys);\n }}\n onCloseMenu={() => {\n setIsKeysOpen(false);\n }}\n onBlur={() => {\n if (filter.key === '') {\n model._removeFilter(filter);\n }\n }}\n openMenuOnFocus={true}\n />\n );\n\n const operatorSelect = (\n <Select\n className={cx(styles.operator, {\n [styles.widthWhenOpen]: isOperatorOpen,\n })}\n value={filter.operator}\n disabled={model.state.readOnly}\n options={model._getOperators()}\n onChange={onOperatorChange}\n onOpenMenu={() => {\n setIsOperatorOpen(true);\n }}\n onCloseMenu={() => {\n setIsOperatorOpen(false);\n }}\n />\n );\n\n if (model.state.layout === 'vertical') {\n if (filter.key) {\n const label = (\n <ControlsLabel layout=\"vertical\" label={filter.key ?? ''} onRemove={() => model._removeFilter(filter)} />\n );\n\n return (\n <Field label={label} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n <div className={styles.wrapper}>\n {operatorSelect}\n {valueSelect}\n </div>\n </Field>\n );\n } else {\n return (\n <Field\n label={t('grafana-scenes.variables.ad-hoc-filter-renderer.label-select-label', 'Select label')}\n data-testid={`AdHocFilter-${filter.key}`}\n className={styles.field}\n >\n {keySelect}\n </Field>\n );\n }\n }\n\n return (\n <div className={styles.wrapper} data-testid={`AdHocFilter-${filter.key}`}>\n {keySelect}\n {operatorSelect}\n {valueSelect}\n <Button\n variant=\"secondary\"\n aria-label={t('grafana-scenes.variables.ad-hoc-filter-renderer.aria-label-remove-filter', 'Remove filter')}\n title={t('grafana-scenes.variables.ad-hoc-filter-renderer.title-remove-filter', 'Remove filter')}\n className={styles.removeButton}\n icon=\"times\"\n data-testid={`AdHocFilter-remove-${filter.key ?? ''}`}\n onClick={() => model._removeFilter(filter)}\n />\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n field: css({\n marginBottom: 0,\n }),\n wrapper: css({\n display: 'flex',\n '> *': {\n '&:not(:first-child)': {\n // Negative margin hides the double-border on adjacent selects\n marginLeft: -1,\n },\n\n '&:first-child': {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n },\n\n '&:last-child': {\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n },\n\n '&:not(:first-child):not(:last-child)': {\n borderRadius: 0,\n },\n\n // Fix focus state zIndex issues\n position: 'relative',\n zIndex: 0,\n\n // Adjacent borders are overlapping, so raise children up when hovering etc\n // so all that child's borders are visible.\n '&:hover': {\n zIndex: 1,\n },\n\n '&:focus-within': {\n zIndex: 2,\n },\n },\n }),\n widthWhenOpen: css({\n minWidth: theme.spacing(16),\n }),\n value: css({\n flexBasis: 'content',\n flexShrink: 1,\n minWidth: '90px',\n }),\n key: css({\n flexBasis: 'content',\n minWidth: '90px',\n flexShrink: 1,\n }),\n operator: css({\n flexShrink: 0,\n flexBasis: 'content',\n }),\n removeButton: css({\n paddingLeft: theme.spacing(3 / 2),\n paddingRight: theme.spacing(3 / 2),\n borderLeft: 'none',\n width: theme.spacing(3),\n marginRight: theme.spacing(1),\n boxSizing: 'border-box',\n // To not have button background and last select border intersect\n position: 'relative',\n left: '1px',\n }),\n});\n"],"names":["_a","_b","values","keys"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import React, { forwardRef, useState, useRef, useId, useMemo, useCallback, useIm
|
|
|
3
3
|
import { FloatingPortal, FloatingFocusManager } from '@floating-ui/react';
|
|
4
4
|
import { useStyles2, Spinner, Text } from '@grafana/ui';
|
|
5
5
|
import { css, cx } from '@emotion/css';
|
|
6
|
-
import { isMultiValueOperator, isFilterComplete } from '../AdHocFiltersVariable.js';
|
|
6
|
+
import { isMultiValueOperator, OPERATORS, isFilterComplete } from '../AdHocFiltersVariable.js';
|
|
7
7
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
8
8
|
import { LoadingOptionsPlaceholder, OptionsErrorPlaceholder, NoOptionsPlaceholder, DropdownItem, MultiValueApplyButton } from './DropdownItem.js';
|
|
9
9
|
import { flattenOptionGroups, setupDropdownAccessibility, VIRTUAL_LIST_OVERSCAN, VIRTUAL_LIST_ITEM_HEIGHT_WITH_DESCRIPTION, VIRTUAL_LIST_ITEM_HEIGHT, generateFilterUpdatePayload, populateInputValueOnInputTypeSwitch, switchToNextInputType, switchInputType, generatePlaceholder, ERROR_STATE_DROPDOWN_WIDTH } from './utils.js';
|
|
@@ -12,8 +12,7 @@ import { useFloatingInteractions, MAX_MENU_HEIGHT } from './useFloatingInteracti
|
|
|
12
12
|
import { MultiValuePill } from './MultiValuePill.js';
|
|
13
13
|
import { getAdhocOptionSearcher } from '../getAdhocOptionSearcher.js';
|
|
14
14
|
import { getQueryController } from '../../../core/sceneGraph/getQueryController.js';
|
|
15
|
-
import { FILTER_CHANGED_INTERACTION,
|
|
16
|
-
import { getInteractionTracker } from '../../../core/sceneGraph/getInteractionTracker.js';
|
|
15
|
+
import { FILTER_CHANGED_INTERACTION, FILTER_REMOVED_INTERACTION } from '../../../behaviors/SceneRenderProfiler.js';
|
|
17
16
|
|
|
18
17
|
const AdHocCombobox = forwardRef(function AdHocCombobox2({ filter, model, isAlwaysWip, handleChangeViewMode, focusOnWipInputRef, populateInputOnEdit }, parentRef) {
|
|
19
18
|
var _a, _b, _c, _d;
|
|
@@ -165,22 +164,26 @@ const AdHocCombobox = forwardRef(function AdHocCombobox2({ filter, model, isAlwa
|
|
|
165
164
|
handleOptionGroups(optionsSearcher(preventFiltering ? "" : inputValue))
|
|
166
165
|
);
|
|
167
166
|
if (allowCustomValue && filterInputType !== "operator" && inputValue) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
167
|
+
const operatorDefinition = OPERATORS.find((op) => (filter == null ? void 0 : filter.operator) === op.value);
|
|
168
|
+
if (operatorDefinition == null ? void 0 : operatorDefinition.isRegex) {
|
|
169
|
+
filteredDropDownItems.unshift({
|
|
170
|
+
value: inputValue.trim(),
|
|
171
|
+
label: inputValue.trim(),
|
|
172
|
+
isCustom: true
|
|
173
|
+
});
|
|
174
|
+
} else {
|
|
175
|
+
filteredDropDownItems.push({
|
|
176
|
+
value: inputValue.trim(),
|
|
177
|
+
label: inputValue.trim(),
|
|
178
|
+
isCustom: true
|
|
179
|
+
});
|
|
180
|
+
}
|
|
173
181
|
}
|
|
174
182
|
const onAddCustomValue = model.state.onAddCustomValue;
|
|
175
183
|
const maxOptionWidth = setupDropdownAccessibility(filteredDropDownItems, listRef, disabledIndicesRef);
|
|
176
184
|
const handleFetchOptions = useCallback(
|
|
177
185
|
async (inputType) => {
|
|
178
186
|
var _a2;
|
|
179
|
-
const profiler = getInteractionTracker(model);
|
|
180
|
-
const interactionName = inputType === "key" ? ADHOC_KEYS_DROPDOWN_INTERACTION : ADHOC_VALUES_DROPDOWN_INTERACTION;
|
|
181
|
-
if (inputType !== "operator") {
|
|
182
|
-
profiler == null ? void 0 : profiler.startInteraction(interactionName);
|
|
183
|
-
}
|
|
184
187
|
setOptionsError(false);
|
|
185
188
|
setOptionsLoading(true);
|
|
186
189
|
setOptions([]);
|
|
@@ -194,7 +197,6 @@ const AdHocCombobox = forwardRef(function AdHocCombobox2({ filter, model, isAlwa
|
|
|
194
197
|
options2 = await model._getValuesFor(filter);
|
|
195
198
|
}
|
|
196
199
|
if (filterInputTypeRef.current !== inputType) {
|
|
197
|
-
profiler == null ? void 0 : profiler.stopInteraction();
|
|
198
200
|
return;
|
|
199
201
|
}
|
|
200
202
|
setOptions(options2);
|
|
@@ -207,7 +209,6 @@ const AdHocCombobox = forwardRef(function AdHocCombobox2({ filter, model, isAlwa
|
|
|
207
209
|
setOptionsError(true);
|
|
208
210
|
}
|
|
209
211
|
setOptionsLoading(false);
|
|
210
|
-
profiler == null ? void 0 : profiler.stopInteraction();
|
|
211
212
|
},
|
|
212
213
|
[filter, model]
|
|
213
214
|
);
|