@grafana/scenes 6.37.0 → 6.39.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/index.js CHANGED
@@ -1058,7 +1058,7 @@ var __privateWrapper = (obj, member, setter, getter) => ({
1058
1058
  return __privateGet$2(obj, member, getter);
1059
1059
  }
1060
1060
  });
1061
- var _profileInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans, _longFrameDetector, _longFramesCount, _longFramesTotalTime, _visibilityChangeHandler;
1061
+ var _profileInProgress, _interactionInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans, _longFrameDetector, _longFramesCount, _longFramesTotalTime, _visibilityChangeHandler, _onInteractionComplete;
1062
1062
  const POST_STORM_WINDOW = 2e3;
1063
1063
  const DEFAULT_LONG_FRAME_THRESHOLD = 30;
1064
1064
  const TAB_INACTIVE_THRESHOLD = 1e3;
@@ -1066,6 +1066,7 @@ class SceneRenderProfiler {
1066
1066
  constructor(queryController) {
1067
1067
  this.queryController = queryController;
1068
1068
  __privateAdd$2(this, _profileInProgress, null);
1069
+ __privateAdd$2(this, _interactionInProgress, null);
1069
1070
  __privateAdd$2(this, _profileStartTs, null);
1070
1071
  __privateAdd$2(this, _trailAnimationFrameId, null);
1071
1072
  // Will keep measured lengths trailing frames
@@ -1075,6 +1076,7 @@ class SceneRenderProfiler {
1075
1076
  __privateAdd$2(this, _longFramesCount, 0);
1076
1077
  __privateAdd$2(this, _longFramesTotalTime, 0);
1077
1078
  __privateAdd$2(this, _visibilityChangeHandler, null);
1079
+ __privateAdd$2(this, _onInteractionComplete, null);
1078
1080
  this.measureTrailingFrames = (measurementStartTs, lastFrameTime, profileStartTs) => {
1079
1081
  var _a, _b, _c, _d;
1080
1082
  const currentFrameTime = performance.now();
@@ -1191,10 +1193,14 @@ class SceneRenderProfiler {
1191
1193
  };
1192
1194
  __privateSet$2(this, _longFrameDetector, new LongFrameDetector());
1193
1195
  this.setupVisibilityChangeHandler();
1196
+ __privateSet$2(this, _interactionInProgress, null);
1194
1197
  }
1195
1198
  setQueryController(queryController) {
1196
1199
  this.queryController = queryController;
1197
1200
  }
1201
+ setInteractionCompleteHandler(handler) {
1202
+ __privateSet$2(this, _onInteractionComplete, handler != null ? handler : null);
1203
+ }
1198
1204
  setupVisibilityChangeHandler() {
1199
1205
  if (__privateGet$2(this, _visibilityChangeHandler)) {
1200
1206
  return;
@@ -1233,6 +1239,55 @@ class SceneRenderProfiler {
1233
1239
  this._startNewProfile(name);
1234
1240
  }
1235
1241
  }
1242
+ startInteraction(interaction) {
1243
+ if (__privateGet$2(this, _interactionInProgress)) {
1244
+ writeSceneLog("profile", "Cancelled interaction:", __privateGet$2(this, _interactionInProgress));
1245
+ __privateSet$2(this, _interactionInProgress, null);
1246
+ }
1247
+ __privateSet$2(this, _interactionInProgress, {
1248
+ interaction,
1249
+ startTs: performance.now()
1250
+ });
1251
+ writeSceneLog("SceneRenderProfiler", "Started interaction:", interaction);
1252
+ }
1253
+ stopInteraction() {
1254
+ if (!__privateGet$2(this, _interactionInProgress)) {
1255
+ return;
1256
+ }
1257
+ const endTs = performance.now();
1258
+ const interactionDuration = endTs - __privateGet$2(this, _interactionInProgress).startTs;
1259
+ const networkDuration = captureNetwork(__privateGet$2(this, _interactionInProgress).startTs, endTs);
1260
+ writeSceneLog("SceneRenderProfiler", "Completed interaction:");
1261
+ writeSceneLog("", ` \u251C\u2500 Total time: ${interactionDuration.toFixed(1)}ms`);
1262
+ writeSceneLog("", ` \u251C\u2500 Network duration: ${networkDuration.toFixed(1)}ms`);
1263
+ writeSceneLog("", ` \u251C\u2500 StartTs: ${__privateGet$2(this, _interactionInProgress).startTs.toFixed(1)}ms`);
1264
+ writeSceneLog("", ` \u2514\u2500 EndTs: ${endTs.toFixed(1)}ms`);
1265
+ if (__privateGet$2(this, _onInteractionComplete) && __privateGet$2(this, _profileInProgress)) {
1266
+ __privateGet$2(this, _onInteractionComplete).call(this, {
1267
+ origin: __privateGet$2(this, _interactionInProgress).interaction,
1268
+ duration: interactionDuration,
1269
+ networkDuration,
1270
+ startTs: __privateGet$2(this, _interactionInProgress).startTs,
1271
+ endTs
1272
+ });
1273
+ }
1274
+ performance.mark(`${__privateGet$2(this, _interactionInProgress).interaction}_start`, {
1275
+ startTime: __privateGet$2(this, _interactionInProgress).startTs
1276
+ });
1277
+ performance.mark(`${__privateGet$2(this, _interactionInProgress).interaction}_end`, {
1278
+ startTime: endTs
1279
+ });
1280
+ performance.measure(
1281
+ `Interaction_${__privateGet$2(this, _interactionInProgress).interaction}`,
1282
+ `${__privateGet$2(this, _interactionInProgress).interaction}_start`,
1283
+ `${__privateGet$2(this, _interactionInProgress).interaction}_end`
1284
+ );
1285
+ __privateSet$2(this, _interactionInProgress, null);
1286
+ }
1287
+ getCurrentInteraction() {
1288
+ var _a, _b;
1289
+ return (_b = (_a = __privateGet$2(this, _interactionInProgress)) == null ? void 0 : _a.interaction) != null ? _b : null;
1290
+ }
1236
1291
  /**
1237
1292
  * Starts a new profile for performance measurement.
1238
1293
  *
@@ -1278,6 +1333,9 @@ class SceneRenderProfiler {
1278
1333
  }
1279
1334
  tryCompletingProfile() {
1280
1335
  var _a;
1336
+ if (!__privateGet$2(this, _profileInProgress)) {
1337
+ return;
1338
+ }
1281
1339
  writeSceneLog("SceneRenderProfiler", "Trying to complete profile", __privateGet$2(this, _profileInProgress));
1282
1340
  if (((_a = this.queryController) == null ? void 0 : _a.runningQueriesCount()) === 0 && __privateGet$2(this, _profileInProgress)) {
1283
1341
  writeSceneLog("SceneRenderProfiler", "All queries completed, starting tail measurement");
@@ -1318,6 +1376,7 @@ class SceneRenderProfiler {
1318
1376
  }
1319
1377
  }
1320
1378
  _profileInProgress = new WeakMap();
1379
+ _interactionInProgress = new WeakMap();
1321
1380
  _profileStartTs = new WeakMap();
1322
1381
  _trailAnimationFrameId = new WeakMap();
1323
1382
  _recordedTrailingSpans = new WeakMap();
@@ -1325,6 +1384,7 @@ _longFrameDetector = new WeakMap();
1325
1384
  _longFramesCount = new WeakMap();
1326
1385
  _longFramesTotalTime = new WeakMap();
1327
1386
  _visibilityChangeHandler = new WeakMap();
1387
+ _onInteractionComplete = new WeakMap();
1328
1388
  function processRecordedSpans(spans) {
1329
1389
  for (let i = spans.length - 1; i >= 0; i--) {
1330
1390
  if (spans[i] > DEFAULT_LONG_FRAME_THRESHOLD) {
@@ -1374,6 +1434,9 @@ const FILTER_CHANGED_INTERACTION = "filter_changed";
1374
1434
  const FILTER_RESTORED_INTERACTION = "filter_restored";
1375
1435
  const VARIABLE_VALUE_CHANGED_INTERACTION = "variable_value_changed";
1376
1436
  const SCOPES_CHANGED_INTERACTION = "scopes_changed";
1437
+ const ADHOC_KEYS_DROPDOWN_INTERACTION = "adhoc_keys_dropdown";
1438
+ const ADHOC_VALUES_DROPDOWN_INTERACTION = "adhoc_values_dropdown";
1439
+ const GROUPBY_DIMENSIONS_INTERACTION = "groupby_dimensions";
1377
1440
 
1378
1441
  class SceneTimeRange extends SceneObjectBase {
1379
1442
  constructor(state = {}) {
@@ -3655,6 +3718,47 @@ const GroupByValueContainer = ({
3655
3718
  return /* @__PURE__ */ React__default.default.createElement("div", { className: css.cx(styles.multiValueContainer, !isApplicable && css.cx(disabledPill, strikethrough)) }, children);
3656
3719
  };
3657
3720
 
3721
+ function isInteractionTracker(s) {
3722
+ return "isInteractionTracker" in s;
3723
+ }
3724
+ class SceneInteractionTracker extends SceneObjectBase {
3725
+ constructor(state = {}, renderProfiler) {
3726
+ super(state);
3727
+ this.renderProfiler = renderProfiler;
3728
+ this.isInteractionTracker = true;
3729
+ if (renderProfiler) {
3730
+ this.renderProfiler = renderProfiler;
3731
+ this.renderProfiler.setInteractionCompleteHandler(state.onInteractionComplete);
3732
+ }
3733
+ }
3734
+ startInteraction(name) {
3735
+ var _a;
3736
+ if (!this.state.enableInteractionTracking) {
3737
+ return;
3738
+ }
3739
+ (_a = this.renderProfiler) == null ? void 0 : _a.startInteraction(name);
3740
+ }
3741
+ stopInteraction() {
3742
+ var _a;
3743
+ (_a = this.renderProfiler) == null ? void 0 : _a.stopInteraction();
3744
+ }
3745
+ }
3746
+
3747
+ function getInteractionTracker(sceneObject) {
3748
+ let parent = sceneObject;
3749
+ while (parent) {
3750
+ if (parent.state.$behaviors) {
3751
+ for (const behavior of parent.state.$behaviors) {
3752
+ if (isInteractionTracker(behavior)) {
3753
+ return behavior;
3754
+ }
3755
+ }
3756
+ }
3757
+ parent = parent.parent;
3758
+ }
3759
+ return void 0;
3760
+ }
3761
+
3658
3762
  class GroupByVariable extends MultiValueVariable {
3659
3763
  constructor(initialState) {
3660
3764
  super({
@@ -3960,10 +4064,13 @@ function GroupByVariableRenderer({ model }) {
3960
4064
  setUncommittedValue(newValue);
3961
4065
  },
3962
4066
  onOpenMenu: async () => {
4067
+ const profiler = getInteractionTracker(model);
4068
+ profiler == null ? void 0 : profiler.startInteraction(GROUPBY_DIMENSIONS_INTERACTION);
3963
4069
  setIsFetchingOptions(true);
3964
4070
  await rxjs.lastValueFrom(model.validateAndUpdate());
3965
4071
  setIsFetchingOptions(false);
3966
4072
  setIsOptionsOpen(true);
4073
+ profiler == null ? void 0 : profiler.stopInteraction();
3967
4074
  },
3968
4075
  onCloseMenu: () => {
3969
4076
  setIsOptionsOpen(false);
@@ -4013,10 +4120,13 @@ function GroupByVariableRenderer({ model }) {
4013
4120
  }
4014
4121
  },
4015
4122
  onOpenMenu: async () => {
4123
+ const profiler = getInteractionTracker(model);
4124
+ profiler == null ? void 0 : profiler.startInteraction(GROUPBY_DIMENSIONS_INTERACTION);
4016
4125
  setIsFetchingOptions(true);
4017
4126
  await rxjs.lastValueFrom(model.validateAndUpdate());
4018
4127
  setIsFetchingOptions(false);
4019
4128
  setIsOptionsOpen(true);
4129
+ profiler == null ? void 0 : profiler.stopInteraction();
4020
4130
  },
4021
4131
  onCloseMenu: () => {
4022
4132
  setIsOptionsOpen(false);
@@ -4273,11 +4383,13 @@ function AdHocFilterRenderer({ filter, model }) {
4273
4383
  });
4274
4384
  }
4275
4385
  };
4386
+ const operatorDefinition = OPERATORS.find((op) => filter.operator === op.value);
4276
4387
  const valueSelect = /* @__PURE__ */ React__default.default.createElement(
4277
4388
  ui.Select,
4278
4389
  {
4279
4390
  virtualized: true,
4280
4391
  allowCustomValue: (_b = model.state.allowCustomValue) != null ? _b : true,
4392
+ createOptionPosition: (operatorDefinition == null ? void 0 : operatorDefinition.isRegex) ? "first" : "last",
4281
4393
  isValidNewOption: (inputValue) => inputValue.trim().length > 0,
4282
4394
  allowCreateWhileLoading: true,
4283
4395
  formatCreateLabel: (inputValue) => `Use custom value: ${inputValue}`,
@@ -4335,6 +4447,7 @@ function AdHocFilterRenderer({ filter, model }) {
4335
4447
  className: css.cx(styles.key, isKeysOpen ? styles.widthWhenOpen : void 0),
4336
4448
  width: "auto",
4337
4449
  allowCustomValue: (_c = model.state.allowCustomValue) != null ? _c : true,
4450
+ createOptionPosition: (operatorDefinition == null ? void 0 : operatorDefinition.isRegex) ? "first" : "last",
4338
4451
  value: keyValue,
4339
4452
  placeholder: i18n.t(
4340
4453
  "grafana-scenes.variables.ad-hoc-filter-renderer.key-select.placeholder-select-label",
@@ -5170,17 +5283,28 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5170
5283
  handleOptionGroups(optionsSearcher(preventFiltering ? "" : inputValue))
5171
5284
  );
5172
5285
  if (allowCustomValue && filterInputType !== "operator" && inputValue) {
5173
- filteredDropDownItems.push({
5286
+ const operatorDefinition = OPERATORS.find((op) => (filter == null ? void 0 : filter.operator) === op.value);
5287
+ const customOptionValue = {
5174
5288
  value: inputValue.trim(),
5175
5289
  label: inputValue.trim(),
5176
5290
  isCustom: true
5177
- });
5291
+ };
5292
+ if (operatorDefinition == null ? void 0 : operatorDefinition.isRegex) {
5293
+ filteredDropDownItems.unshift(customOptionValue);
5294
+ } else {
5295
+ filteredDropDownItems.push(customOptionValue);
5296
+ }
5178
5297
  }
5179
5298
  const onAddCustomValue = model.state.onAddCustomValue;
5180
5299
  const maxOptionWidth = setupDropdownAccessibility(filteredDropDownItems, listRef, disabledIndicesRef);
5181
5300
  const handleFetchOptions = React.useCallback(
5182
5301
  async (inputType) => {
5183
5302
  var _a2;
5303
+ const profiler = getInteractionTracker(model);
5304
+ const interactionName = inputType === "key" ? ADHOC_KEYS_DROPDOWN_INTERACTION : ADHOC_VALUES_DROPDOWN_INTERACTION;
5305
+ if (inputType !== "operator") {
5306
+ profiler == null ? void 0 : profiler.startInteraction(interactionName);
5307
+ }
5184
5308
  setOptionsError(false);
5185
5309
  setOptionsLoading(true);
5186
5310
  setOptions([]);
@@ -5194,6 +5318,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5194
5318
  options2 = await model._getValuesFor(filter);
5195
5319
  }
5196
5320
  if (filterInputTypeRef.current !== inputType) {
5321
+ profiler == null ? void 0 : profiler.stopInteraction();
5197
5322
  return;
5198
5323
  }
5199
5324
  setOptions(options2);
@@ -5206,6 +5331,7 @@ const AdHocCombobox = React.forwardRef(function AdHocCombobox2({ filter, model,
5206
5331
  setOptionsError(true);
5207
5332
  }
5208
5333
  setOptionsLoading(false);
5334
+ profiler == null ? void 0 : profiler.stopInteraction();
5209
5335
  },
5210
5336
  [filter, model]
5211
5337
  );
@@ -9859,6 +9985,7 @@ var index$1 = /*#__PURE__*/Object.freeze({
9859
9985
  ActWhenVariableChanged: ActWhenVariableChanged,
9860
9986
  CursorSync: CursorSync,
9861
9987
  LiveNowTimer: LiveNowTimer,
9988
+ SceneInteractionTracker: SceneInteractionTracker,
9862
9989
  SceneQueryController: SceneQueryController
9863
9990
  });
9864
9991