@grafana/scenes 4.25.0 → 4.26.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
@@ -13,6 +13,7 @@ var schema = require('@grafana/schema');
13
13
  var ui = require('@grafana/ui');
14
14
  var css = require('@emotion/css');
15
15
  var e2eSelectors = require('@grafana/e2e-selectors');
16
+ var uFuzzy = require('@leeoniya/ufuzzy');
16
17
  var reactUse = require('react-use');
17
18
  var operators = require('rxjs/operators');
18
19
  var ReactGridLayout = require('react-grid-layout');
@@ -36,6 +37,7 @@ var XYChartPanelCfg_types_gen = require('@grafana/schema/dist/esm/raw/composable
36
37
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
37
38
 
38
39
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
40
+ var uFuzzy__default = /*#__PURE__*/_interopDefaultLegacy(uFuzzy);
39
41
  var ReactGridLayout__default = /*#__PURE__*/_interopDefaultLegacy(ReactGridLayout);
40
42
  var AutoSizer__default = /*#__PURE__*/_interopDefaultLegacy(AutoSizer);
41
43
 
@@ -1532,6 +1534,27 @@ function findObjectInternal(scene, check, alreadySearchedChild, shouldSearchUp)
1532
1534
  }
1533
1535
  return null;
1534
1536
  }
1537
+ function findByKey(sceneObject, key) {
1538
+ const found = findObject(sceneObject, (sceneToCheck) => {
1539
+ return sceneToCheck.state.key === key;
1540
+ });
1541
+ if (!found) {
1542
+ throw new Error("Unable to find scene with key " + key);
1543
+ }
1544
+ return found;
1545
+ }
1546
+ function findByKeyAndType(sceneObject, key, targetType) {
1547
+ const found = findObject(sceneObject, (sceneToCheck) => {
1548
+ return sceneToCheck.state.key === key;
1549
+ });
1550
+ if (!found) {
1551
+ throw new Error("Unable to find scene with key " + key);
1552
+ }
1553
+ if (!(found instanceof targetType)) {
1554
+ throw new Error(`Found scene object with key ${key} does not match type ${targetType.name}`);
1555
+ }
1556
+ return found;
1557
+ }
1535
1558
  function findObject(scene, check) {
1536
1559
  return findObjectInternal(scene, check, void 0, true);
1537
1560
  }
@@ -2026,6 +2049,8 @@ const sceneGraph = {
2026
2049
  interpolate,
2027
2050
  lookupVariable,
2028
2051
  hasVariableDependencyInLoadingState,
2052
+ findByKey,
2053
+ findByKeyAndType,
2029
2054
  findObject,
2030
2055
  findAllObjects,
2031
2056
  getAncestor,
@@ -2920,6 +2945,51 @@ class CustomAllValue {
2920
2945
  }
2921
2946
  }
2922
2947
 
2948
+ function getOptionSearcher(options, includeAll, value, text) {
2949
+ const ufuzzy = new uFuzzy__default["default"]();
2950
+ let allOptions = options;
2951
+ const haystack = [];
2952
+ const limit = 1e4;
2953
+ if (includeAll) {
2954
+ allOptions = [{ value: ALL_VARIABLE_VALUE, label: ALL_VARIABLE_TEXT }, ...allOptions];
2955
+ }
2956
+ if (!Array.isArray(value)) {
2957
+ const current = options.find((x) => x.value === value);
2958
+ if (!current) {
2959
+ allOptions = [{ value, label: String(text) }, ...allOptions];
2960
+ }
2961
+ }
2962
+ return (search) => {
2963
+ if (search === "") {
2964
+ if (allOptions.length > limit) {
2965
+ return allOptions.slice(0, limit);
2966
+ } else {
2967
+ return allOptions;
2968
+ }
2969
+ }
2970
+ if (haystack.length === 0) {
2971
+ for (let i = 0; i < allOptions.length; i++) {
2972
+ haystack.push(allOptions[i].label);
2973
+ }
2974
+ }
2975
+ const idxs = ufuzzy.filter(haystack, search);
2976
+ const filteredOptions = [];
2977
+ if (idxs) {
2978
+ for (let i = 0; i < idxs.length; i++) {
2979
+ filteredOptions.push(allOptions[idxs[i]]);
2980
+ if (filteredOptions.length > limit) {
2981
+ return filteredOptions;
2982
+ }
2983
+ }
2984
+ return filteredOptions;
2985
+ }
2986
+ if (allOptions.length > limit) {
2987
+ return allOptions.slice(0, limit);
2988
+ }
2989
+ return allOptions;
2990
+ };
2991
+ }
2992
+
2923
2993
  var __defProp$z = Object.defineProperty;
2924
2994
  var __defProps$n = Object.defineProperties;
2925
2995
  var __getOwnPropDescs$n = Object.getOwnPropertyDescriptors;
@@ -2951,35 +3021,66 @@ var __objRest$3 = (source, exclude) => {
2951
3021
  }
2952
3022
  return target;
2953
3023
  };
3024
+ const filterNoOp$1 = () => true;
2954
3025
  function VariableValueSelect({ model }) {
2955
- const { value, key } = model.useState();
2956
- const onInputChange = model.onSearchChange ? (value2, meta) => {
2957
- if (meta.action === "input-change") {
2958
- model.onSearchChange(value2);
3026
+ const { value, text, key, options, includeAll } = model.useState();
3027
+ const [inputValue, setInputValue] = React.useState("");
3028
+ const [hasCustomValue, setHasCustomValue] = React.useState(false);
3029
+ const optionSearcher = React.useMemo(
3030
+ () => getOptionSearcher(options, includeAll, value, text),
3031
+ [options, includeAll, value, text]
3032
+ );
3033
+ const onInputChange = (value2, { action }) => {
3034
+ if (action === "input-change") {
3035
+ setInputValue(value2);
3036
+ if (model.onSearchChange) {
3037
+ model.onSearchChange(value2);
3038
+ }
3039
+ return value2;
3040
+ }
3041
+ return value2;
3042
+ };
3043
+ const filteredOptions = optionSearcher(inputValue);
3044
+ const onOpenMenu = () => {
3045
+ if (hasCustomValue) {
3046
+ setInputValue(String(text));
2959
3047
  }
2960
- } : void 0;
3048
+ };
3049
+ const onCloseMenu = () => {
3050
+ setInputValue("");
3051
+ };
2961
3052
  return /* @__PURE__ */ React__default["default"].createElement(ui.Select, {
2962
3053
  id: key,
2963
3054
  placeholder: "Select value",
2964
3055
  width: "auto",
2965
3056
  value,
3057
+ inputValue,
2966
3058
  allowCustomValue: true,
2967
3059
  virtualized: true,
3060
+ filterOption: filterNoOp$1,
2968
3061
  tabSelectsValue: false,
2969
3062
  onInputChange,
2970
- options: model.getOptionsForSelect(),
3063
+ onOpenMenu,
3064
+ onCloseMenu,
3065
+ options: filteredOptions,
2971
3066
  "data-testid": e2eSelectors.selectors.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts(`${value}`),
2972
3067
  onChange: (newValue) => {
2973
3068
  model.changeValueTo(newValue.value, newValue.label);
3069
+ if (hasCustomValue !== newValue.__isNew__) {
3070
+ setHasCustomValue(newValue.__isNew__);
3071
+ }
2974
3072
  }
2975
3073
  });
2976
3074
  }
2977
3075
  function VariableValueSelectMulti({ model }) {
2978
- const { value, key, maxVisibleValues, noValueOnClear } = model.useState();
3076
+ const { value, text, options, key, maxVisibleValues, noValueOnClear, includeAll } = model.useState();
2979
3077
  const arrayValue = React.useMemo(() => lodash.isArray(value) ? value : [value], [value]);
2980
- const options = model.getOptionsForSelect();
2981
3078
  const [uncommittedValue, setUncommittedValue] = React.useState(arrayValue);
2982
3079
  const [inputValue, setInputValue] = React.useState("");
3080
+ const optionSearcher = React.useMemo(
3081
+ () => getOptionSearcher(options, includeAll, value, text),
3082
+ [options, includeAll, value, text]
3083
+ );
2983
3084
  React.useEffect(() => {
2984
3085
  setUncommittedValue(arrayValue);
2985
3086
  }, [arrayValue]);
@@ -2998,6 +3099,7 @@ function VariableValueSelectMulti({ model }) {
2998
3099
  return inputValue;
2999
3100
  };
3000
3101
  const placeholder = options.length > 0 ? "Select value" : "";
3102
+ const filteredOptions = optionSearcher(inputValue);
3001
3103
  return /* @__PURE__ */ React__default["default"].createElement(ui.MultiSelect, {
3002
3104
  id: key,
3003
3105
  placeholder,
@@ -3009,7 +3111,7 @@ function VariableValueSelectMulti({ model }) {
3009
3111
  tabSelectsValue: false,
3010
3112
  virtualized: true,
3011
3113
  allowCustomValue: true,
3012
- options: model.getOptionsForSelect(),
3114
+ options: filteredOptions,
3013
3115
  closeMenuOnSelect: false,
3014
3116
  components: { Option: OptionWithCheckbox },
3015
3117
  isClearable: true,
@@ -3018,6 +3120,7 @@ function VariableValueSelectMulti({ model }) {
3018
3120
  onBlur: () => {
3019
3121
  model.changeValueTo(uncommittedValue);
3020
3122
  },
3123
+ filterOption: filterNoOp$1,
3021
3124
  "data-testid": e2eSelectors.selectors.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts(`${uncommittedValue}`),
3022
3125
  onChange: (newValue, action) => {
3023
3126
  if (action.action === "clear" && noValueOnClear) {
@@ -3256,7 +3359,7 @@ class GroupByVariable extends MultiValueVariable {
3256
3359
  }
3257
3360
  GroupByVariable.Component = GroupByVariableRenderer;
3258
3361
  function GroupByVariableRenderer({ model }) {
3259
- const { value, text, key, maxVisibleValues, noValueOnClear } = model.useState();
3362
+ const { value, text, key, maxVisibleValues, noValueOnClear, options, includeAll } = model.useState();
3260
3363
  const values = React.useMemo(() => {
3261
3364
  const arrayValue = lodash.isArray(value) ? value : [value];
3262
3365
  const arrayText = lodash.isArray(text) ? text : [text];
@@ -3272,6 +3375,10 @@ function GroupByVariableRenderer({ model }) {
3272
3375
  const [isOptionsOpen, setIsOptionsOpen] = React.useState(false);
3273
3376
  const [inputValue, setInputValue] = React.useState("");
3274
3377
  const [uncommittedValue, setUncommittedValue] = React.useState(values);
3378
+ const optionSearcher = React.useMemo(
3379
+ () => getOptionSearcher(options, includeAll, value, text),
3380
+ [options, includeAll, value, text]
3381
+ );
3275
3382
  React.useEffect(() => {
3276
3383
  setUncommittedValue(values);
3277
3384
  }, [values]);
@@ -3289,11 +3396,11 @@ function GroupByVariableRenderer({ model }) {
3289
3396
  }
3290
3397
  return inputValue;
3291
3398
  };
3292
- const placeholder = "Select value";
3399
+ const filteredOptions = optionSearcher(inputValue);
3293
3400
  return /* @__PURE__ */ React__default["default"].createElement(ui.MultiSelect, {
3294
3401
  "data-testid": `GroupBySelect-${key}`,
3295
3402
  id: key,
3296
- placeholder,
3403
+ placeholder: "Select value",
3297
3404
  width: "auto",
3298
3405
  inputValue,
3299
3406
  value: uncommittedValue,
@@ -3301,7 +3408,8 @@ function GroupByVariableRenderer({ model }) {
3301
3408
  maxVisibleValues: maxVisibleValues != null ? maxVisibleValues : 5,
3302
3409
  tabSelectsValue: false,
3303
3410
  virtualized: true,
3304
- options: model.getOptionsForSelect(),
3411
+ options: filteredOptions,
3412
+ filterOption: filterNoOp,
3305
3413
  closeMenuOnSelect: false,
3306
3414
  isOpen: isOptionsOpen,
3307
3415
  isClearable: true,
@@ -3332,6 +3440,7 @@ function GroupByVariableRenderer({ model }) {
3332
3440
  }
3333
3441
  });
3334
3442
  }
3443
+ const filterNoOp = () => true;
3335
3444
 
3336
3445
  function LoadingIndicator(props) {
3337
3446
  return /* @__PURE__ */ React__default["default"].createElement(ui.Tooltip, {