@grafana/scenes 4.18.0 → 4.19.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/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # v4.19.0 (Fri May 10 2024)
2
+
3
+ #### 🚀 Enhancement
4
+
5
+ - SceneDataTransformer: Performance optimizations [#725](https://github.com/grafana/scenes/pull/725) ([@torkelo](https://github.com/torkelo))
6
+ - Variables: Do not update value when value and text are the same [#726](https://github.com/grafana/scenes/pull/726) ([@torkelo](https://github.com/torkelo))
7
+
8
+ #### Authors: 1
9
+
10
+ - Torkel Ödegaard ([@torkelo](https://github.com/torkelo))
11
+
12
+ ---
13
+
1
14
  # v4.18.0 (Fri May 10 2024)
2
15
 
3
16
  #### 🚀 Enhancement
@@ -75,7 +75,7 @@ class SceneDataTransformer extends SceneObjectBase {
75
75
  return true;
76
76
  }
77
77
  reprocessTransformations() {
78
- this.transform(this.getSourceData().state.data);
78
+ this.transform(this.getSourceData().state.data, true);
79
79
  }
80
80
  cancelQuery() {
81
81
  var _a, _b;
@@ -84,8 +84,42 @@ class SceneDataTransformer extends SceneObjectBase {
84
84
  getResultsStream() {
85
85
  return this._results;
86
86
  }
87
- transform(data) {
87
+ clone(withState) {
88
+ const clone = super.clone(withState);
89
+ if (this._prevDataFromSource) {
90
+ clone["_prevDataFromSource"] = this._prevDataFromSource;
91
+ }
92
+ return clone;
93
+ }
94
+ haveAlreadyTransformedData(data) {
95
+ if (!this._prevDataFromSource) {
96
+ return false;
97
+ }
98
+ if (data === this._prevDataFromSource) {
99
+ return true;
100
+ }
101
+ const { series, annotations } = this._prevDataFromSource;
102
+ if (data.series === series && data.annotations === annotations) {
103
+ if (this.state.data && data.state !== this.state.data.state) {
104
+ this.setState({ data: __spreadProps(__spreadValues({}, this.state.data), { state: data.state }) });
105
+ }
106
+ return true;
107
+ }
108
+ return false;
109
+ }
110
+ transform(data, force = false) {
88
111
  var _a;
112
+ if (this.state.transformations.length === 0 || !data) {
113
+ this._prevDataFromSource = data;
114
+ this.setState({ data });
115
+ if (data) {
116
+ this._results.next({ origin: this, data });
117
+ }
118
+ return;
119
+ }
120
+ if (!force && this.haveAlreadyTransformedData(data)) {
121
+ return;
122
+ }
89
123
  const seriesTransformations = this.state.transformations.filter((transformation) => {
90
124
  if ("options" in transformation || "topic" in transformation) {
91
125
  return transformation.topic == null || transformation.topic === DataTopic.Series;
@@ -98,13 +132,6 @@ class SceneDataTransformer extends SceneObjectBase {
98
132
  }
99
133
  return false;
100
134
  }).map((transformation) => "operator" in transformation ? transformation.operator : transformation);
101
- if (this.state.transformations.length === 0 || !data) {
102
- this.setState({ data });
103
- if (data) {
104
- this._results.next({ origin: this, data });
105
- }
106
- return;
107
- }
108
135
  if (this._transformSub) {
109
136
  this._transformSub.unsubscribe();
110
137
  }
@@ -139,9 +166,10 @@ class SceneDataTransformer extends SceneObjectBase {
139
166
  });
140
167
  return of(result);
141
168
  })
142
- ).subscribe((data2) => {
143
- this.setState({ data: data2 });
144
- this._results.next({ origin: this, data: data2 });
169
+ ).subscribe((transformedData) => {
170
+ this.setState({ data: transformedData });
171
+ this._results.next({ origin: this, data: transformedData });
172
+ this._prevDataFromSource = data;
145
173
  });
146
174
  }
147
175
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SceneDataTransformer.js","sources":["../../../src/querying/SceneDataTransformer.ts"],"sourcesContent":["import { DataTopic, DataTransformerConfig, LoadingState, PanelData, transformDataFrame } from '@grafana/data';\nimport { toDataQueryError } from '@grafana/runtime';\nimport { catchError, forkJoin, map, of, ReplaySubject, Unsubscribable } from 'rxjs';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { CustomTransformerDefinition, SceneDataProvider, SceneDataProviderResult, SceneDataState } from '../core/types';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\nimport { SceneDataLayerSet } from './SceneDataLayerSet';\n\nexport interface SceneDataTransformerState extends SceneDataState {\n /**\n * Array of standard transformation configs and custom transform operators\n */\n transformations: Array<DataTransformerConfig | CustomTransformerDefinition>;\n}\n\n/**\n * You can use this as a $data object. It can either transform an inner $data DataProvider or if that is not set it will\n * subscribe to a DataProvider higher up in the scene graph and transform its data.\n *\n * The transformations array supports custom (runtime defined) transformation as well as declarative core transformations.\n * You can manually re-process the transformations by calling reprocessTransformations(). This is useful if you have\n * transformations that depend on other scene object states.\n */\nexport class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerState> implements SceneDataProvider {\n private _transformSub?: Unsubscribable;\n private _results = new ReplaySubject<SceneDataProviderResult>(1);\n\n /**\n * Scan transformations for variable usage and re-process transforms when a variable values change\n */\n protected _variableDependency: VariableDependencyConfig<SceneDataTransformerState> = new VariableDependencyConfig(\n this,\n {\n statePaths: ['transformations'],\n onReferencedVariableValueChanged: () => this.reprocessTransformations(),\n }\n );\n\n public constructor(state: SceneDataTransformerState) {\n super(state);\n\n this.addActivationHandler(() => this.activationHandler());\n }\n\n private activationHandler() {\n const sourceData = this.getSourceData();\n\n this._subs.add(sourceData.subscribeToState((state) => this.transform(state.data)));\n\n if (sourceData.state.data) {\n this.transform(sourceData.state.data);\n }\n\n return () => {\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n };\n }\n\n private getSourceData(): SceneDataProvider {\n if (this.state.$data) {\n if (this.state.$data instanceof SceneDataLayerSet) {\n throw new Error('SceneDataLayerSet can not be used as data provider for SceneDataTransformer.');\n }\n return this.state.$data;\n }\n\n if (!this.parent || !this.parent.parent) {\n throw new Error('SceneDataTransformer must either have $data set on it or have a parent.parent with $data');\n }\n\n return sceneGraph.getData(this.parent.parent);\n }\n\n public setContainerWidth(width: number) {\n if (this.state.$data && this.state.$data.setContainerWidth) {\n this.state.$data.setContainerWidth(width);\n }\n }\n\n public isDataReadyToDisplay() {\n const dataObject = this.getSourceData();\n if (dataObject.isDataReadyToDisplay) {\n return dataObject.isDataReadyToDisplay();\n }\n\n return true;\n }\n\n public reprocessTransformations() {\n this.transform(this.getSourceData().state.data);\n }\n\n public cancelQuery() {\n this.getSourceData().cancelQuery?.();\n }\n\n public getResultsStream() {\n return this._results;\n }\n\n private transform(data: PanelData | undefined) {\n const seriesTransformations = this.state.transformations\n .filter((transformation) => {\n if ('options' in transformation || 'topic' in transformation) {\n return transformation.topic == null || transformation.topic === DataTopic.Series;\n }\n\n return true;\n })\n .map((transformation) => ('operator' in transformation ? transformation.operator : transformation));\n\n const annotationsTransformations = this.state.transformations\n .filter((transformation) => {\n if ('options' in transformation || 'topic' in transformation) {\n return transformation.topic === DataTopic.Annotations;\n }\n\n return false;\n })\n .map((transformation) => ('operator' in transformation ? transformation.operator : transformation));\n\n if (this.state.transformations.length === 0 || !data) {\n this.setState({ data });\n\n if (data) {\n this._results.next({ origin: this, data });\n }\n return;\n }\n\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(this, value, data.request?.scopedVars);\n },\n };\n\n let streams = [transformDataFrame(seriesTransformations, data.series, ctx)];\n\n if (data.annotations && data.annotations.length > 0 && annotationsTransformations.length > 0) {\n streams.push(transformDataFrame(annotationsTransformations, data.annotations ?? []));\n }\n\n this._transformSub = forkJoin(streams)\n .pipe(\n map((values) => {\n const transformedSeries = values[0];\n const transformedAnnotations = values[1];\n\n return {\n ...data,\n series: transformedSeries,\n annotations: transformedAnnotations ?? data.annotations,\n };\n }),\n catchError((err) => {\n console.error('Error transforming data: ', err);\n const sourceErr = this.getSourceData().state.data?.errors || [];\n\n const transformationError = toDataQueryError(err);\n transformationError.message = `Error transforming data: ${transformationError.message}`;\n\n const result: PanelData = {\n ...data,\n state: LoadingState.Error,\n // Combine transformation error with upstream errors\n errors: [...sourceErr, transformationError],\n };\n\n return of(result);\n })\n )\n .subscribe((data) => {\n this.setState({ data });\n this._results.next({ origin: this, data });\n });\n }\n}\n"],"names":["_a","data"],"mappings":"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"}
1
+ {"version":3,"file":"SceneDataTransformer.js","sources":["../../../src/querying/SceneDataTransformer.ts"],"sourcesContent":["import { DataTopic, DataTransformerConfig, LoadingState, PanelData, transformDataFrame } from '@grafana/data';\nimport { toDataQueryError } from '@grafana/runtime';\nimport { catchError, forkJoin, map, of, ReplaySubject, Unsubscribable } from 'rxjs';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { CustomTransformerDefinition, SceneDataProvider, SceneDataProviderResult, SceneDataState } from '../core/types';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\nimport { SceneDataLayerSet } from './SceneDataLayerSet';\n\nexport interface SceneDataTransformerState extends SceneDataState {\n /**\n * Array of standard transformation configs and custom transform operators\n */\n transformations: Array<DataTransformerConfig | CustomTransformerDefinition>;\n}\n\n/**\n * You can use this as a $data object. It can either transform an inner $data DataProvider or if that is not set it will\n * subscribe to a DataProvider higher up in the scene graph and transform its data.\n *\n * The transformations array supports custom (runtime defined) transformation as well as declarative core transformations.\n * You can manually re-process the transformations by calling reprocessTransformations(). This is useful if you have\n * transformations that depend on other scene object states.\n */\nexport class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerState> implements SceneDataProvider {\n private _transformSub?: Unsubscribable;\n private _results = new ReplaySubject<SceneDataProviderResult>(1);\n private _prevDataFromSource?: PanelData;\n\n /**\n * Scan transformations for variable usage and re-process transforms when a variable values change\n */\n protected _variableDependency: VariableDependencyConfig<SceneDataTransformerState> = new VariableDependencyConfig(\n this,\n {\n statePaths: ['transformations'],\n onReferencedVariableValueChanged: () => this.reprocessTransformations(),\n }\n );\n\n public constructor(state: SceneDataTransformerState) {\n super(state);\n\n this.addActivationHandler(() => this.activationHandler());\n }\n\n private activationHandler() {\n const sourceData = this.getSourceData();\n\n this._subs.add(sourceData.subscribeToState((state) => this.transform(state.data)));\n\n if (sourceData.state.data) {\n this.transform(sourceData.state.data);\n }\n\n return () => {\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n };\n }\n\n private getSourceData(): SceneDataProvider {\n if (this.state.$data) {\n if (this.state.$data instanceof SceneDataLayerSet) {\n throw new Error('SceneDataLayerSet can not be used as data provider for SceneDataTransformer.');\n }\n return this.state.$data;\n }\n\n if (!this.parent || !this.parent.parent) {\n throw new Error('SceneDataTransformer must either have $data set on it or have a parent.parent with $data');\n }\n\n return sceneGraph.getData(this.parent.parent);\n }\n\n public setContainerWidth(width: number) {\n if (this.state.$data && this.state.$data.setContainerWidth) {\n this.state.$data.setContainerWidth(width);\n }\n }\n\n public isDataReadyToDisplay() {\n const dataObject = this.getSourceData();\n if (dataObject.isDataReadyToDisplay) {\n return dataObject.isDataReadyToDisplay();\n }\n\n return true;\n }\n\n public reprocessTransformations() {\n this.transform(this.getSourceData().state.data, true);\n }\n\n public cancelQuery() {\n this.getSourceData().cancelQuery?.();\n }\n\n public getResultsStream() {\n return this._results;\n }\n\n public clone(withState?: Partial<SceneDataTransformerState>) {\n const clone = super.clone(withState);\n\n if (this._prevDataFromSource) {\n clone['_prevDataFromSource'] = this._prevDataFromSource;\n }\n\n return clone;\n }\n\n private haveAlreadyTransformedData(data: PanelData) {\n if (!this._prevDataFromSource) {\n return false;\n }\n\n if (data === this._prevDataFromSource) {\n return true;\n }\n\n const { series, annotations } = this._prevDataFromSource;\n\n if (data.series === series && data.annotations === annotations) {\n if (this.state.data && data.state !== this.state.data.state) {\n this.setState({ data: { ...this.state.data, state: data.state } });\n }\n return true;\n }\n\n return false;\n }\n\n private transform(data: PanelData | undefined, force = false) {\n if (this.state.transformations.length === 0 || !data) {\n this._prevDataFromSource = data;\n this.setState({ data });\n\n if (data) {\n this._results.next({ origin: this, data });\n }\n return;\n }\n\n // Skip transform step if we have already transformed this data\n if (!force && this.haveAlreadyTransformedData(data)) {\n return;\n }\n\n const seriesTransformations = this.state.transformations\n .filter((transformation) => {\n if ('options' in transformation || 'topic' in transformation) {\n return transformation.topic == null || transformation.topic === DataTopic.Series;\n }\n\n return true;\n })\n .map((transformation) => ('operator' in transformation ? transformation.operator : transformation));\n\n const annotationsTransformations = this.state.transformations\n .filter((transformation) => {\n if ('options' in transformation || 'topic' in transformation) {\n return transformation.topic === DataTopic.Annotations;\n }\n\n return false;\n })\n .map((transformation) => ('operator' in transformation ? transformation.operator : transformation));\n\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(this, value, data.request?.scopedVars);\n },\n };\n\n let streams = [transformDataFrame(seriesTransformations, data.series, ctx)];\n\n if (data.annotations && data.annotations.length > 0 && annotationsTransformations.length > 0) {\n streams.push(transformDataFrame(annotationsTransformations, data.annotations ?? []));\n }\n\n this._transformSub = forkJoin(streams)\n .pipe(\n map((values) => {\n const transformedSeries = values[0];\n const transformedAnnotations = values[1];\n\n return {\n ...data,\n series: transformedSeries,\n annotations: transformedAnnotations ?? data.annotations,\n };\n }),\n catchError((err) => {\n console.error('Error transforming data: ', err);\n const sourceErr = this.getSourceData().state.data?.errors || [];\n\n const transformationError = toDataQueryError(err);\n transformationError.message = `Error transforming data: ${transformationError.message}`;\n\n const result: PanelData = {\n ...data,\n state: LoadingState.Error,\n // Combine transformation error with upstream errors\n errors: [...sourceErr, transformationError],\n };\n\n return of(result);\n })\n )\n .subscribe((transformedData) => {\n this.setState({ data: transformedData });\n this._results.next({ origin: this, data: transformedData });\n this._prevDataFromSource = data;\n });\n }\n}\n"],"names":["_a"],"mappings":"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"}
@@ -147,6 +147,9 @@ class MultiValueVariable extends SceneObjectBase {
147
147
  }
148
148
  }
149
149
  }
150
+ if (isEqual(value, this.state.value) && isEqual(text, this.state.text)) {
151
+ return;
152
+ }
150
153
  this.setStateHelper({ value, text, loading: false });
151
154
  this.publishEvent(new SceneVariableValueChangedEvent(this), true);
152
155
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MultiValueVariable.js","sources":["../../../../src/variables/variants/MultiValueVariable.ts"],"sourcesContent":["import { isArray, isEqual } from 'lodash';\nimport { map, Observable } from 'rxjs';\n\nimport { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneObjectUrlSyncHandler, SceneObjectUrlValues } from '../../core/types';\nimport {\n SceneVariable,\n SceneVariableValueChangedEvent,\n SceneVariableState,\n ValidateAndUpdateResult,\n VariableValue,\n VariableValueOption,\n VariableValueSingle,\n CustomVariableValue,\n VariableCustomFormatterFn,\n} from '../types';\nimport { formatRegistry } from '../interpolation/formatRegistry';\nimport { VariableFormatID } from '@grafana/schema';\nimport { SceneVariableSet } from '../sets/SceneVariableSet';\nimport { setBaseClassState } from '../../utils/utils';\n\nexport interface MultiValueVariableState extends SceneVariableState {\n value: VariableValue; // old current.text\n text: VariableValue; // old current.value\n options: VariableValueOption[];\n isMulti?: boolean;\n includeAll?: boolean;\n defaultToAll?: boolean;\n allValue?: string;\n placeholder?: string;\n /**\n * For multi value variables, this option controls how many values to show before they are collapsed into +N.\n * Defaults to 5\n */\n maxVisibleValues?: number;\n noValueOnClear?: boolean;\n}\n\nexport interface VariableGetOptionsArgs {\n searchFilter?: string;\n}\n\nexport abstract class MultiValueVariable<TState extends MultiValueVariableState = MultiValueVariableState>\n extends SceneObjectBase<TState>\n implements SceneVariable<TState>\n{\n protected _urlSync: SceneObjectUrlSyncHandler = new MultiValueUrlSyncHandler(this);\n\n /**\n * Set to true to skip next value validation to maintain the current value even it it's not among the options (ie valid values)\n */\n public skipNextValidation?: boolean;\n\n /**\n * The source of value options.\n */\n public abstract getValueOptions(args: VariableGetOptionsArgs): Observable<VariableValueOption[]>;\n\n /**\n * This function is called on when SceneVariableSet is activated or when a dependency changes.\n */\n public validateAndUpdate(): Observable<ValidateAndUpdateResult> {\n return this.getValueOptions({}).pipe(\n map((options) => {\n this.updateValueGivenNewOptions(options);\n return {};\n })\n );\n }\n\n public onCancel(): void {\n this.setStateHelper({ loading: false });\n const sceneVarSet = this.parent as SceneVariableSet;\n sceneVarSet?.cancel(this);\n }\n\n /**\n * Check if current value is valid given new options. If not update the value.\n */\n private updateValueGivenNewOptions(options: VariableValueOption[]) {\n // Remember current value and text\n const { value: currentValue, text: currentText } = this.state;\n\n const stateUpdate: Partial<MultiValueVariableState> = {\n options,\n loading: false,\n value: currentValue,\n text: currentText,\n };\n\n if (options.length === 0) {\n if (this.state.defaultToAll || this.state.includeAll) {\n stateUpdate.value = ALL_VARIABLE_VALUE;\n stateUpdate.text = ALL_VARIABLE_TEXT;\n } else if (this.state.isMulti) {\n stateUpdate.value = [];\n stateUpdate.text = [];\n } else {\n stateUpdate.value = '';\n stateUpdate.text = '';\n }\n } else if (this.hasAllValue()) {\n // If value is set to All then we keep it set to All but just store the options\n } else if (this.state.isMulti) {\n // If we are a multi valued variable validate the current values are among the options\n const currentValues = Array.isArray(currentValue) ? currentValue : [currentValue];\n const validValues = currentValues.filter((v) => options.find((o) => o.value === v));\n const validTexts = validValues.map((v) => options.find((o) => o.value === v)!.label);\n\n // If no valid values pick the first option\n if (validValues.length === 0) {\n const defaultState = this.getDefaultMultiState(options);\n stateUpdate.value = defaultState.value;\n stateUpdate.text = defaultState.text;\n }\n // We have valid values, if it's different from current valid values update current values\n else {\n if (!isEqual(validValues, currentValue)) {\n stateUpdate.value = validValues;\n }\n if (!isEqual(validTexts, currentText)) {\n stateUpdate.text = validTexts;\n }\n }\n } else {\n // Try find by value then text\n let matchingOption = findOptionMatchingCurrent(currentValue, currentText, options);\n if (matchingOption) {\n // When updating the initial state from URL the text property is set the same as value\n // Here we can correct the text value state\n stateUpdate.text = matchingOption.label;\n stateUpdate.value = matchingOption.value;\n } else {\n // Current value is found in options\n if (this.state.defaultToAll) {\n stateUpdate.value = ALL_VARIABLE_VALUE;\n stateUpdate.text = ALL_VARIABLE_TEXT;\n } else {\n // Current value is not valid. Set to first of the available options\n stateUpdate.value = options[0].value;\n stateUpdate.text = options[0].label;\n }\n }\n }\n\n this.interceptStateUpdateAfterValidation(stateUpdate);\n\n // Perform state change\n this.setStateHelper(stateUpdate);\n\n // Publish value changed event only if value changed\n if (stateUpdate.value !== currentValue || stateUpdate.text !== currentText || this.hasAllValue()) {\n this.publishEvent(new SceneVariableValueChangedEvent(this), true);\n }\n }\n\n /**\n * Values set by initial URL sync needs to survive the next validation and update.\n * This function can intercept and make sure those values are preserved.\n */\n protected interceptStateUpdateAfterValidation(stateUpdate: Partial<MultiValueVariableState>): void {\n // If the validation wants to fix the all value (All ==> $__all) then we should let that pass\n const isAllValueFix = stateUpdate.value === ALL_VARIABLE_VALUE && this.state.text === ALL_VARIABLE_TEXT;\n\n if (this.skipNextValidation && stateUpdate.value !== this.state.value && !isAllValueFix) {\n stateUpdate.value = this.state.value;\n stateUpdate.text = this.state.text;\n }\n\n this.skipNextValidation = false;\n }\n\n public getValue(): VariableValue {\n if (this.hasAllValue()) {\n if (this.state.allValue) {\n return new CustomAllValue(this.state.allValue, this);\n }\n\n return this.state.options.map((x) => x.value);\n }\n\n return this.state.value;\n }\n\n public getValueText(): string {\n if (this.hasAllValue()) {\n return ALL_VARIABLE_TEXT;\n }\n\n if (Array.isArray(this.state.text)) {\n return this.state.text.join(' + ');\n }\n\n return String(this.state.text);\n }\n\n public hasAllValue() {\n const value = this.state.value;\n return value === ALL_VARIABLE_VALUE || (Array.isArray(value) && value[0] === ALL_VARIABLE_VALUE);\n }\n\n public getDefaultMultiState(options: VariableValueOption[]) {\n if (this.state.defaultToAll) {\n return { value: [ALL_VARIABLE_VALUE], text: [ALL_VARIABLE_TEXT] };\n } else if (options.length > 0) {\n return { value: [options[0].value], text: [options[0].label] };\n } else {\n return { value: [], text: [] };\n }\n }\n\n /**\n * Change the value and publish SceneVariableValueChangedEvent event.\n */\n public changeValueTo(value: VariableValue, text?: VariableValue) {\n // Ignore if there is no change\n if (value === this.state.value && text === this.state.text) {\n return;\n }\n\n if (!text) {\n if (Array.isArray(value)) {\n text = value.map((v) => this.findLabelTextForValue(v));\n } else {\n text = this.findLabelTextForValue(value);\n }\n }\n\n if (Array.isArray(value)) {\n // If we are a multi valued variable is cleared (empty array) we need to set the default empty state\n if (value.length === 0) {\n const state = this.getDefaultMultiState(this.state.options);\n value = state.value;\n text = state.text;\n }\n\n // If last value is the All value then replace all with it\n if (value[value.length - 1] === ALL_VARIABLE_VALUE) {\n value = [ALL_VARIABLE_VALUE];\n text = [ALL_VARIABLE_TEXT];\n }\n // If the first value is the ALL value and we have other values, then remove the All value\n else if (value[0] === ALL_VARIABLE_VALUE && value.length > 1) {\n value.shift();\n if (Array.isArray(text)) {\n text.shift();\n }\n }\n }\n\n this.setStateHelper({ value, text, loading: false });\n this.publishEvent(new SceneVariableValueChangedEvent(this), true);\n }\n\n private findLabelTextForValue(value: VariableValueSingle): VariableValueSingle {\n const option = this.state.options.find((x) => x.value === value);\n if (option) {\n return option.label;\n }\n\n const optionByLabel = this.state.options.find((x) => x.label === value);\n if (optionByLabel) {\n return optionByLabel.label;\n }\n\n return value;\n }\n\n /**\n * This helper function is to counter the contravariance of setState\n */\n private setStateHelper(state: Partial<MultiValueVariableState>) {\n setBaseClassState<MultiValueVariableState>(this, state);\n }\n\n public getOptionsForSelect(): VariableValueOption[] {\n let options = this.state.options;\n\n if (this.state.includeAll) {\n options = [{ value: ALL_VARIABLE_VALUE, label: ALL_VARIABLE_TEXT }, ...options];\n }\n\n if (!Array.isArray(this.state.value)) {\n const current = options.find((x) => x.value === this.state.value);\n if (!current) {\n options = [{ value: this.state.value, label: String(this.state.text) }, ...options];\n }\n }\n\n return options;\n }\n\n /**\n * Can be used by subclasses to do custom handling of option search based on search input\n */\n public onSearchChange?(searchFilter: string): void;\n}\n\n/**\n * Looks for matching option, first by value but as a fallback by text (label).\n */\nfunction findOptionMatchingCurrent(\n currentValue: VariableValue,\n currentText: VariableValue,\n options: VariableValueOption[]\n) {\n let textMatch: VariableValueOption | undefined;\n\n for (const item of options) {\n if (item.value === currentValue) {\n return item;\n }\n\n // No early return here as want to continue to look a value match\n if (item.label === currentText) {\n textMatch = item;\n }\n }\n\n return textMatch;\n}\n\nexport class MultiValueUrlSyncHandler<TState extends MultiValueVariableState = MultiValueVariableState>\n implements SceneObjectUrlSyncHandler\n{\n public constructor(private _sceneObject: MultiValueVariable<TState>) {}\n\n private getKey(): string {\n return `var-${this._sceneObject.state.name}`;\n }\n\n public getKeys(): string[] {\n if (this._sceneObject.state.skipUrlSync) {\n return [];\n }\n\n return [this.getKey()];\n }\n\n public getUrlState(): SceneObjectUrlValues {\n if (this._sceneObject.state.skipUrlSync) {\n return {};\n }\n\n let urlValue: string | string[] | null = null;\n let value = this._sceneObject.state.value;\n\n if (Array.isArray(value)) {\n urlValue = value.map(String);\n } else if ((this, this._sceneObject.state.isMulti)) {\n // If we are inMulti mode we must return an array here as otherwise UrlSyncManager will not pass all values (in an array) in updateFromUrl\n urlValue = [String(value)];\n } else {\n urlValue = String(value);\n }\n\n return { [this.getKey()]: urlValue };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues): void {\n let urlValue = values[this.getKey()];\n\n if (urlValue != null) {\n // This is to be backwards compatible with old url all value\n if (this._sceneObject.state.includeAll) {\n urlValue = handleLegacyUrlAllValue(urlValue);\n }\n\n /**\n * Initial URL Sync happens before scene objects are activated.\n * We need to skip validation in this case to make sure values set via URL are maintained.\n */\n if (!this._sceneObject.isActive) {\n this._sceneObject.skipNextValidation = true;\n }\n\n this._sceneObject.changeValueTo(urlValue);\n }\n }\n}\n\nfunction handleLegacyUrlAllValue(value: string | string[]) {\n if (isArray(value) && value[0] === ALL_VARIABLE_TEXT) {\n return [ALL_VARIABLE_VALUE];\n } else if (value === ALL_VARIABLE_TEXT) {\n return ALL_VARIABLE_VALUE;\n }\n\n return value;\n}\n\n/**\n * Variable getValue can return this to skip any subsequent formatting.\n * This is useful for custom all values that should not be escaped/formatted.\n */\nexport class CustomAllValue implements CustomVariableValue {\n public constructor(private _value: string, private _variable: SceneVariable) {}\n\n public formatter(formatNameOrFn?: string | VariableCustomFormatterFn): string {\n if (formatNameOrFn === VariableFormatID.Text) {\n return ALL_VARIABLE_TEXT;\n }\n\n if (formatNameOrFn === VariableFormatID.PercentEncode) {\n return formatRegistry.get(VariableFormatID.PercentEncode).formatter(this._value, [], this._variable);\n }\n\n if (formatNameOrFn === VariableFormatID.QueryParam) {\n return formatRegistry.get(VariableFormatID.QueryParam).formatter(ALL_VARIABLE_TEXT, [], this._variable);\n }\n\n return this._value;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MultiValueVariable.js","sources":["../../../../src/variables/variants/MultiValueVariable.ts"],"sourcesContent":["import { isArray, isEqual } from 'lodash';\nimport { map, Observable } from 'rxjs';\n\nimport { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneObjectUrlSyncHandler, SceneObjectUrlValues } from '../../core/types';\nimport {\n SceneVariable,\n SceneVariableValueChangedEvent,\n SceneVariableState,\n ValidateAndUpdateResult,\n VariableValue,\n VariableValueOption,\n VariableValueSingle,\n CustomVariableValue,\n VariableCustomFormatterFn,\n} from '../types';\nimport { formatRegistry } from '../interpolation/formatRegistry';\nimport { VariableFormatID } from '@grafana/schema';\nimport { SceneVariableSet } from '../sets/SceneVariableSet';\nimport { setBaseClassState } from '../../utils/utils';\n\nexport interface MultiValueVariableState extends SceneVariableState {\n value: VariableValue; // old current.text\n text: VariableValue; // old current.value\n options: VariableValueOption[];\n isMulti?: boolean;\n includeAll?: boolean;\n defaultToAll?: boolean;\n allValue?: string;\n placeholder?: string;\n /**\n * For multi value variables, this option controls how many values to show before they are collapsed into +N.\n * Defaults to 5\n */\n maxVisibleValues?: number;\n noValueOnClear?: boolean;\n}\n\nexport interface VariableGetOptionsArgs {\n searchFilter?: string;\n}\n\nexport abstract class MultiValueVariable<TState extends MultiValueVariableState = MultiValueVariableState>\n extends SceneObjectBase<TState>\n implements SceneVariable<TState>\n{\n protected _urlSync: SceneObjectUrlSyncHandler = new MultiValueUrlSyncHandler(this);\n\n /**\n * Set to true to skip next value validation to maintain the current value even it it's not among the options (ie valid values)\n */\n public skipNextValidation?: boolean;\n\n /**\n * The source of value options.\n */\n public abstract getValueOptions(args: VariableGetOptionsArgs): Observable<VariableValueOption[]>;\n\n /**\n * This function is called on when SceneVariableSet is activated or when a dependency changes.\n */\n public validateAndUpdate(): Observable<ValidateAndUpdateResult> {\n return this.getValueOptions({}).pipe(\n map((options) => {\n this.updateValueGivenNewOptions(options);\n return {};\n })\n );\n }\n\n public onCancel(): void {\n this.setStateHelper({ loading: false });\n const sceneVarSet = this.parent as SceneVariableSet;\n sceneVarSet?.cancel(this);\n }\n\n /**\n * Check if current value is valid given new options. If not update the value.\n */\n private updateValueGivenNewOptions(options: VariableValueOption[]) {\n // Remember current value and text\n const { value: currentValue, text: currentText } = this.state;\n\n const stateUpdate: Partial<MultiValueVariableState> = {\n options,\n loading: false,\n value: currentValue,\n text: currentText,\n };\n\n if (options.length === 0) {\n if (this.state.defaultToAll || this.state.includeAll) {\n stateUpdate.value = ALL_VARIABLE_VALUE;\n stateUpdate.text = ALL_VARIABLE_TEXT;\n } else if (this.state.isMulti) {\n stateUpdate.value = [];\n stateUpdate.text = [];\n } else {\n stateUpdate.value = '';\n stateUpdate.text = '';\n }\n } else if (this.hasAllValue()) {\n // If value is set to All then we keep it set to All but just store the options\n } else if (this.state.isMulti) {\n // If we are a multi valued variable validate the current values are among the options\n const currentValues = Array.isArray(currentValue) ? currentValue : [currentValue];\n const validValues = currentValues.filter((v) => options.find((o) => o.value === v));\n const validTexts = validValues.map((v) => options.find((o) => o.value === v)!.label);\n\n // If no valid values pick the first option\n if (validValues.length === 0) {\n const defaultState = this.getDefaultMultiState(options);\n stateUpdate.value = defaultState.value;\n stateUpdate.text = defaultState.text;\n }\n // We have valid values, if it's different from current valid values update current values\n else {\n if (!isEqual(validValues, currentValue)) {\n stateUpdate.value = validValues;\n }\n if (!isEqual(validTexts, currentText)) {\n stateUpdate.text = validTexts;\n }\n }\n } else {\n // Try find by value then text\n let matchingOption = findOptionMatchingCurrent(currentValue, currentText, options);\n if (matchingOption) {\n // When updating the initial state from URL the text property is set the same as value\n // Here we can correct the text value state\n stateUpdate.text = matchingOption.label;\n stateUpdate.value = matchingOption.value;\n } else {\n // Current value is found in options\n if (this.state.defaultToAll) {\n stateUpdate.value = ALL_VARIABLE_VALUE;\n stateUpdate.text = ALL_VARIABLE_TEXT;\n } else {\n // Current value is not valid. Set to first of the available options\n stateUpdate.value = options[0].value;\n stateUpdate.text = options[0].label;\n }\n }\n }\n\n this.interceptStateUpdateAfterValidation(stateUpdate);\n\n // Perform state change\n this.setStateHelper(stateUpdate);\n\n // Publish value changed event only if value changed\n if (stateUpdate.value !== currentValue || stateUpdate.text !== currentText || this.hasAllValue()) {\n this.publishEvent(new SceneVariableValueChangedEvent(this), true);\n }\n }\n\n /**\n * Values set by initial URL sync needs to survive the next validation and update.\n * This function can intercept and make sure those values are preserved.\n */\n protected interceptStateUpdateAfterValidation(stateUpdate: Partial<MultiValueVariableState>): void {\n // If the validation wants to fix the all value (All ==> $__all) then we should let that pass\n const isAllValueFix = stateUpdate.value === ALL_VARIABLE_VALUE && this.state.text === ALL_VARIABLE_TEXT;\n\n if (this.skipNextValidation && stateUpdate.value !== this.state.value && !isAllValueFix) {\n stateUpdate.value = this.state.value;\n stateUpdate.text = this.state.text;\n }\n\n this.skipNextValidation = false;\n }\n\n public getValue(): VariableValue {\n if (this.hasAllValue()) {\n if (this.state.allValue) {\n return new CustomAllValue(this.state.allValue, this);\n }\n\n return this.state.options.map((x) => x.value);\n }\n\n return this.state.value;\n }\n\n public getValueText(): string {\n if (this.hasAllValue()) {\n return ALL_VARIABLE_TEXT;\n }\n\n if (Array.isArray(this.state.text)) {\n return this.state.text.join(' + ');\n }\n\n return String(this.state.text);\n }\n\n public hasAllValue() {\n const value = this.state.value;\n return value === ALL_VARIABLE_VALUE || (Array.isArray(value) && value[0] === ALL_VARIABLE_VALUE);\n }\n\n public getDefaultMultiState(options: VariableValueOption[]) {\n if (this.state.defaultToAll) {\n return { value: [ALL_VARIABLE_VALUE], text: [ALL_VARIABLE_TEXT] };\n } else if (options.length > 0) {\n return { value: [options[0].value], text: [options[0].label] };\n } else {\n return { value: [], text: [] };\n }\n }\n\n /**\n * Change the value and publish SceneVariableValueChangedEvent event.\n */\n public changeValueTo(value: VariableValue, text?: VariableValue) {\n // Ignore if there is no change\n if (value === this.state.value && text === this.state.text) {\n return;\n }\n\n if (!text) {\n if (Array.isArray(value)) {\n text = value.map((v) => this.findLabelTextForValue(v));\n } else {\n text = this.findLabelTextForValue(value);\n }\n }\n\n if (Array.isArray(value)) {\n // If we are a multi valued variable is cleared (empty array) we need to set the default empty state\n if (value.length === 0) {\n const state = this.getDefaultMultiState(this.state.options);\n value = state.value;\n text = state.text;\n }\n\n // If last value is the All value then replace all with it\n if (value[value.length - 1] === ALL_VARIABLE_VALUE) {\n value = [ALL_VARIABLE_VALUE];\n text = [ALL_VARIABLE_TEXT];\n }\n // If the first value is the ALL value and we have other values, then remove the All value\n else if (value[0] === ALL_VARIABLE_VALUE && value.length > 1) {\n value.shift();\n if (Array.isArray(text)) {\n text.shift();\n }\n }\n }\n\n // Do nothing if value and text are the same\n if (isEqual(value, this.state.value) && isEqual(text, this.state.text)) {\n return;\n }\n\n this.setStateHelper({ value, text, loading: false });\n this.publishEvent(new SceneVariableValueChangedEvent(this), true);\n }\n\n private findLabelTextForValue(value: VariableValueSingle): VariableValueSingle {\n const option = this.state.options.find((x) => x.value === value);\n if (option) {\n return option.label;\n }\n\n const optionByLabel = this.state.options.find((x) => x.label === value);\n if (optionByLabel) {\n return optionByLabel.label;\n }\n\n return value;\n }\n\n /**\n * This helper function is to counter the contravariance of setState\n */\n private setStateHelper(state: Partial<MultiValueVariableState>) {\n setBaseClassState<MultiValueVariableState>(this, state);\n }\n\n public getOptionsForSelect(): VariableValueOption[] {\n let options = this.state.options;\n\n if (this.state.includeAll) {\n options = [{ value: ALL_VARIABLE_VALUE, label: ALL_VARIABLE_TEXT }, ...options];\n }\n\n if (!Array.isArray(this.state.value)) {\n const current = options.find((x) => x.value === this.state.value);\n if (!current) {\n options = [{ value: this.state.value, label: String(this.state.text) }, ...options];\n }\n }\n\n return options;\n }\n\n /**\n * Can be used by subclasses to do custom handling of option search based on search input\n */\n public onSearchChange?(searchFilter: string): void;\n}\n\n/**\n * Looks for matching option, first by value but as a fallback by text (label).\n */\nfunction findOptionMatchingCurrent(\n currentValue: VariableValue,\n currentText: VariableValue,\n options: VariableValueOption[]\n) {\n let textMatch: VariableValueOption | undefined;\n\n for (const item of options) {\n if (item.value === currentValue) {\n return item;\n }\n\n // No early return here as want to continue to look a value match\n if (item.label === currentText) {\n textMatch = item;\n }\n }\n\n return textMatch;\n}\n\nexport class MultiValueUrlSyncHandler<TState extends MultiValueVariableState = MultiValueVariableState>\n implements SceneObjectUrlSyncHandler\n{\n public constructor(private _sceneObject: MultiValueVariable<TState>) {}\n\n private getKey(): string {\n return `var-${this._sceneObject.state.name}`;\n }\n\n public getKeys(): string[] {\n if (this._sceneObject.state.skipUrlSync) {\n return [];\n }\n\n return [this.getKey()];\n }\n\n public getUrlState(): SceneObjectUrlValues {\n if (this._sceneObject.state.skipUrlSync) {\n return {};\n }\n\n let urlValue: string | string[] | null = null;\n let value = this._sceneObject.state.value;\n\n if (Array.isArray(value)) {\n urlValue = value.map(String);\n } else if ((this, this._sceneObject.state.isMulti)) {\n // If we are inMulti mode we must return an array here as otherwise UrlSyncManager will not pass all values (in an array) in updateFromUrl\n urlValue = [String(value)];\n } else {\n urlValue = String(value);\n }\n\n return { [this.getKey()]: urlValue };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues): void {\n let urlValue = values[this.getKey()];\n\n if (urlValue != null) {\n // This is to be backwards compatible with old url all value\n if (this._sceneObject.state.includeAll) {\n urlValue = handleLegacyUrlAllValue(urlValue);\n }\n\n /**\n * Initial URL Sync happens before scene objects are activated.\n * We need to skip validation in this case to make sure values set via URL are maintained.\n */\n if (!this._sceneObject.isActive) {\n this._sceneObject.skipNextValidation = true;\n }\n\n this._sceneObject.changeValueTo(urlValue);\n }\n }\n}\n\nfunction handleLegacyUrlAllValue(value: string | string[]) {\n if (isArray(value) && value[0] === ALL_VARIABLE_TEXT) {\n return [ALL_VARIABLE_VALUE];\n } else if (value === ALL_VARIABLE_TEXT) {\n return ALL_VARIABLE_VALUE;\n }\n\n return value;\n}\n\n/**\n * Variable getValue can return this to skip any subsequent formatting.\n * This is useful for custom all values that should not be escaped/formatted.\n */\nexport class CustomAllValue implements CustomVariableValue {\n public constructor(private _value: string, private _variable: SceneVariable) {}\n\n public formatter(formatNameOrFn?: string | VariableCustomFormatterFn): string {\n if (formatNameOrFn === VariableFormatID.Text) {\n return ALL_VARIABLE_TEXT;\n }\n\n if (formatNameOrFn === VariableFormatID.PercentEncode) {\n return formatRegistry.get(VariableFormatID.PercentEncode).formatter(this._value, [], this._variable);\n }\n\n if (formatNameOrFn === VariableFormatID.QueryParam) {\n return formatRegistry.get(VariableFormatID.QueryParam).formatter(ALL_VARIABLE_TEXT, [], this._variable);\n }\n\n return this._value;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;AA4CO,MAAe,2BACZ,eAEV,CAAA;AAAA,EAHO,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA,CAAA;AAIL,IAAU,IAAA,CAAA,QAAA,GAAsC,IAAI,wBAAA,CAAyB,IAAI,CAAA,CAAA;AAAA,GAAA;AAAA,EAe1E,iBAAyD,GAAA;AAC9D,IAAA,OAAO,IAAK,CAAA,eAAA,CAAgB,EAAE,CAAE,CAAA,IAAA;AAAA,MAC9B,GAAA,CAAI,CAAC,OAAY,KAAA;AACf,QAAA,IAAA,CAAK,2BAA2B,OAAO,CAAA,CAAA;AACvC,QAAA,OAAO,EAAC,CAAA;AAAA,OACT,CAAA;AAAA,KACH,CAAA;AAAA,GACF;AAAA,EAEO,QAAiB,GAAA;AACtB,IAAA,IAAA,CAAK,cAAe,CAAA,EAAE,OAAS,EAAA,KAAA,EAAO,CAAA,CAAA;AACtC,IAAA,MAAM,cAAc,IAAK,CAAA,MAAA,CAAA;AACzB,IAAA,WAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,WAAA,CAAa,MAAO,CAAA,IAAA,CAAA,CAAA;AAAA,GACtB;AAAA,EAKQ,2BAA2B,OAAgC,EAAA;AAEjE,IAAA,MAAM,EAAE,KAAO,EAAA,YAAA,EAAc,IAAM,EAAA,WAAA,KAAgB,IAAK,CAAA,KAAA,CAAA;AAExD,IAAA,MAAM,WAAgD,GAAA;AAAA,MACpD,OAAA;AAAA,MACA,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA,YAAA;AAAA,MACP,IAAM,EAAA,WAAA;AAAA,KACR,CAAA;AAEA,IAAI,IAAA,OAAA,CAAQ,WAAW,CAAG,EAAA;AACxB,MAAA,IAAI,IAAK,CAAA,KAAA,CAAM,YAAgB,IAAA,IAAA,CAAK,MAAM,UAAY,EAAA;AACpD,QAAA,WAAA,CAAY,KAAQ,GAAA,kBAAA,CAAA;AACpB,QAAA,WAAA,CAAY,IAAO,GAAA,iBAAA,CAAA;AAAA,OACrB,MAAA,IAAW,IAAK,CAAA,KAAA,CAAM,OAAS,EAAA;AAC7B,QAAA,WAAA,CAAY,QAAQ,EAAC,CAAA;AACrB,QAAA,WAAA,CAAY,OAAO,EAAC,CAAA;AAAA,OACf,MAAA;AACL,QAAA,WAAA,CAAY,KAAQ,GAAA,EAAA,CAAA;AACpB,QAAA,WAAA,CAAY,IAAO,GAAA,EAAA,CAAA;AAAA,OACrB;AAAA,KACF,MAAA,IAAW,IAAK,CAAA,WAAA,EAAe,EAAA,CAE/B,MAAA,IAAW,IAAK,CAAA,KAAA,CAAM,OAAS,EAAA;AAE7B,MAAA,MAAM,gBAAgB,KAAM,CAAA,OAAA,CAAQ,YAAY,CAAI,GAAA,YAAA,GAAe,CAAC,YAAY,CAAA,CAAA;AAChF,MAAA,MAAM,WAAc,GAAA,aAAA,CAAc,MAAO,CAAA,CAAC,CAAM,KAAA,OAAA,CAAQ,IAAK,CAAA,CAAC,CAAM,KAAA,CAAA,CAAE,KAAU,KAAA,CAAC,CAAC,CAAA,CAAA;AAClF,MAAA,MAAM,UAAa,GAAA,WAAA,CAAY,GAAI,CAAA,CAAC,CAAM,KAAA,OAAA,CAAQ,IAAK,CAAA,CAAC,CAAM,KAAA,CAAA,CAAE,KAAU,KAAA,CAAC,EAAG,KAAK,CAAA,CAAA;AAGnF,MAAI,IAAA,WAAA,CAAY,WAAW,CAAG,EAAA;AAC5B,QAAM,MAAA,YAAA,GAAe,IAAK,CAAA,oBAAA,CAAqB,OAAO,CAAA,CAAA;AACtD,QAAA,WAAA,CAAY,QAAQ,YAAa,CAAA,KAAA,CAAA;AACjC,QAAA,WAAA,CAAY,OAAO,YAAa,CAAA,IAAA,CAAA;AAAA,OAG7B,MAAA;AACH,QAAA,IAAI,CAAC,OAAA,CAAQ,WAAa,EAAA,YAAY,CAAG,EAAA;AACvC,UAAA,WAAA,CAAY,KAAQ,GAAA,WAAA,CAAA;AAAA,SACtB;AACA,QAAA,IAAI,CAAC,OAAA,CAAQ,UAAY,EAAA,WAAW,CAAG,EAAA;AACrC,UAAA,WAAA,CAAY,IAAO,GAAA,UAAA,CAAA;AAAA,SACrB;AAAA,OACF;AAAA,KACK,MAAA;AAEL,MAAA,IAAI,cAAiB,GAAA,yBAAA,CAA0B,YAAc,EAAA,WAAA,EAAa,OAAO,CAAA,CAAA;AACjF,MAAA,IAAI,cAAgB,EAAA;AAGlB,QAAA,WAAA,CAAY,OAAO,cAAe,CAAA,KAAA,CAAA;AAClC,QAAA,WAAA,CAAY,QAAQ,cAAe,CAAA,KAAA,CAAA;AAAA,OAC9B,MAAA;AAEL,QAAI,IAAA,IAAA,CAAK,MAAM,YAAc,EAAA;AAC3B,UAAA,WAAA,CAAY,KAAQ,GAAA,kBAAA,CAAA;AACpB,UAAA,WAAA,CAAY,IAAO,GAAA,iBAAA,CAAA;AAAA,SACd,MAAA;AAEL,UAAY,WAAA,CAAA,KAAA,GAAQ,QAAQ,CAAG,CAAA,CAAA,KAAA,CAAA;AAC/B,UAAY,WAAA,CAAA,IAAA,GAAO,QAAQ,CAAG,CAAA,CAAA,KAAA,CAAA;AAAA,SAChC;AAAA,OACF;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,oCAAoC,WAAW,CAAA,CAAA;AAGpD,IAAA,IAAA,CAAK,eAAe,WAAW,CAAA,CAAA;AAG/B,IAAI,IAAA,WAAA,CAAY,UAAU,YAAgB,IAAA,WAAA,CAAY,SAAS,WAAe,IAAA,IAAA,CAAK,aAAe,EAAA;AAChG,MAAA,IAAA,CAAK,YAAa,CAAA,IAAI,8BAA+B,CAAA,IAAI,GAAG,IAAI,CAAA,CAAA;AAAA,KAClE;AAAA,GACF;AAAA,EAMU,oCAAoC,WAAqD,EAAA;AAEjG,IAAA,MAAM,gBAAgB,WAAY,CAAA,KAAA,KAAU,kBAAsB,IAAA,IAAA,CAAK,MAAM,IAAS,KAAA,iBAAA,CAAA;AAEtF,IAAI,IAAA,IAAA,CAAK,sBAAsB,WAAY,CAAA,KAAA,KAAU,KAAK,KAAM,CAAA,KAAA,IAAS,CAAC,aAAe,EAAA;AACvF,MAAY,WAAA,CAAA,KAAA,GAAQ,KAAK,KAAM,CAAA,KAAA,CAAA;AAC/B,MAAY,WAAA,CAAA,IAAA,GAAO,KAAK,KAAM,CAAA,IAAA,CAAA;AAAA,KAChC;AAEA,IAAA,IAAA,CAAK,kBAAqB,GAAA,KAAA,CAAA;AAAA,GAC5B;AAAA,EAEO,QAA0B,GAAA;AAC/B,IAAI,IAAA,IAAA,CAAK,aAAe,EAAA;AACtB,MAAI,IAAA,IAAA,CAAK,MAAM,QAAU,EAAA;AACvB,QAAA,OAAO,IAAI,cAAA,CAAe,IAAK,CAAA,KAAA,CAAM,UAAU,IAAI,CAAA,CAAA;AAAA,OACrD;AAEA,MAAA,OAAO,KAAK,KAAM,CAAA,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,EAAE,KAAK,CAAA,CAAA;AAAA,KAC9C;AAEA,IAAA,OAAO,KAAK,KAAM,CAAA,KAAA,CAAA;AAAA,GACpB;AAAA,EAEO,YAAuB,GAAA;AAC5B,IAAI,IAAA,IAAA,CAAK,aAAe,EAAA;AACtB,MAAO,OAAA,iBAAA,CAAA;AAAA,KACT;AAEA,IAAA,IAAI,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,KAAA,CAAM,IAAI,CAAG,EAAA;AAClC,MAAA,OAAO,IAAK,CAAA,KAAA,CAAM,IAAK,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,KACnC;AAEA,IAAO,OAAA,MAAA,CAAO,IAAK,CAAA,KAAA,CAAM,IAAI,CAAA,CAAA;AAAA,GAC/B;AAAA,EAEO,WAAc,GAAA;AACnB,IAAM,MAAA,KAAA,GAAQ,KAAK,KAAM,CAAA,KAAA,CAAA;AACzB,IAAA,OAAO,UAAU,kBAAuB,IAAA,KAAA,CAAM,QAAQ,KAAK,CAAA,IAAK,MAAM,CAAO,CAAA,KAAA,kBAAA,CAAA;AAAA,GAC/E;AAAA,EAEO,qBAAqB,OAAgC,EAAA;AAC1D,IAAI,IAAA,IAAA,CAAK,MAAM,YAAc,EAAA;AAC3B,MAAO,OAAA,EAAE,OAAO,CAAC,kBAAkB,GAAG,IAAM,EAAA,CAAC,iBAAiB,CAAE,EAAA,CAAA;AAAA,KAClE,MAAA,IAAW,OAAQ,CAAA,MAAA,GAAS,CAAG,EAAA;AAC7B,MAAA,OAAO,EAAE,KAAA,EAAO,CAAC,OAAA,CAAQ,CAAG,CAAA,CAAA,KAAK,CAAG,EAAA,IAAA,EAAM,CAAC,OAAA,CAAQ,CAAG,CAAA,CAAA,KAAK,CAAE,EAAA,CAAA;AAAA,KACxD,MAAA;AACL,MAAA,OAAO,EAAE,KAAO,EAAA,EAAI,EAAA,IAAA,EAAM,EAAG,EAAA,CAAA;AAAA,KAC/B;AAAA,GACF;AAAA,EAKO,aAAA,CAAc,OAAsB,IAAsB,EAAA;AAE/D,IAAA,IAAI,UAAU,IAAK,CAAA,KAAA,CAAM,SAAS,IAAS,KAAA,IAAA,CAAK,MAAM,IAAM,EAAA;AAC1D,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AACxB,QAAA,IAAA,GAAO,MAAM,GAAI,CAAA,CAAC,MAAM,IAAK,CAAA,qBAAA,CAAsB,CAAC,CAAC,CAAA,CAAA;AAAA,OAChD,MAAA;AACL,QAAO,IAAA,GAAA,IAAA,CAAK,sBAAsB,KAAK,CAAA,CAAA;AAAA,OACzC;AAAA,KACF;AAEA,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AAExB,MAAI,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AACtB,QAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,oBAAqB,CAAA,IAAA,CAAK,MAAM,OAAO,CAAA,CAAA;AAC1D,QAAA,KAAA,GAAQ,KAAM,CAAA,KAAA,CAAA;AACd,QAAA,IAAA,GAAO,KAAM,CAAA,IAAA,CAAA;AAAA,OACf;AAGA,MAAA,IAAI,KAAM,CAAA,KAAA,CAAM,MAAS,GAAA,CAAA,CAAA,KAAO,kBAAoB,EAAA;AAClD,QAAA,KAAA,GAAQ,CAAC,kBAAkB,CAAA,CAAA;AAC3B,QAAA,IAAA,GAAO,CAAC,iBAAiB,CAAA,CAAA;AAAA,iBAGlB,KAAM,CAAA,CAAA,CAAA,KAAO,kBAAsB,IAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AAC5D,QAAA,KAAA,CAAM,KAAM,EAAA,CAAA;AACZ,QAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,IAAI,CAAG,EAAA;AACvB,UAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,SACb;AAAA,OACF;AAAA,KACF;AAGA,IAAI,IAAA,OAAA,CAAQ,KAAO,EAAA,IAAA,CAAK,KAAM,CAAA,KAAK,CAAK,IAAA,OAAA,CAAQ,IAAM,EAAA,IAAA,CAAK,KAAM,CAAA,IAAI,CAAG,EAAA;AACtE,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,eAAe,EAAE,KAAA,EAAO,IAAM,EAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AACnD,IAAA,IAAA,CAAK,YAAa,CAAA,IAAI,8BAA+B,CAAA,IAAI,GAAG,IAAI,CAAA,CAAA;AAAA,GAClE;AAAA,EAEQ,sBAAsB,KAAiD,EAAA;AAC7E,IAAM,MAAA,MAAA,GAAS,KAAK,KAAM,CAAA,OAAA,CAAQ,KAAK,CAAC,CAAA,KAAM,CAAE,CAAA,KAAA,KAAU,KAAK,CAAA,CAAA;AAC/D,IAAA,IAAI,MAAQ,EAAA;AACV,MAAA,OAAO,MAAO,CAAA,KAAA,CAAA;AAAA,KAChB;AAEA,IAAM,MAAA,aAAA,GAAgB,KAAK,KAAM,CAAA,OAAA,CAAQ,KAAK,CAAC,CAAA,KAAM,CAAE,CAAA,KAAA,KAAU,KAAK,CAAA,CAAA;AACtE,IAAA,IAAI,aAAe,EAAA;AACjB,MAAA,OAAO,aAAc,CAAA,KAAA,CAAA;AAAA,KACvB;AAEA,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAAA,EAKQ,eAAe,KAAyC,EAAA;AAC9D,IAAA,iBAAA,CAA2C,MAAM,KAAK,CAAA,CAAA;AAAA,GACxD;AAAA,EAEO,mBAA6C,GAAA;AAClD,IAAI,IAAA,OAAA,GAAU,KAAK,KAAM,CAAA,OAAA,CAAA;AAEzB,IAAI,IAAA,IAAA,CAAK,MAAM,UAAY,EAAA;AACzB,MAAU,OAAA,GAAA,CAAC,EAAE,KAAO,EAAA,kBAAA,EAAoB,OAAO,iBAAkB,EAAA,EAAG,GAAG,OAAO,CAAA,CAAA;AAAA,KAChF;AAEA,IAAA,IAAI,CAAC,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,KAAA,CAAM,KAAK,CAAG,EAAA;AACpC,MAAM,MAAA,OAAA,GAAU,QAAQ,IAAK,CAAA,CAAC,MAAM,CAAE,CAAA,KAAA,KAAU,IAAK,CAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AAChE,MAAA,IAAI,CAAC,OAAS,EAAA;AACZ,QAAA,OAAA,GAAU,CAAC,EAAE,KAAO,EAAA,IAAA,CAAK,MAAM,KAAO,EAAA,KAAA,EAAO,MAAO,CAAA,IAAA,CAAK,KAAM,CAAA,IAAI,CAAE,EAAA,EAAG,GAAG,OAAO,CAAA,CAAA;AAAA,OACpF;AAAA,KACF;AAEA,IAAO,OAAA,OAAA,CAAA;AAAA,GACT;AAMF,CAAA;AAKA,SAAS,yBAAA,CACP,YACA,EAAA,WAAA,EACA,OACA,EAAA;AACA,EAAI,IAAA,SAAA,CAAA;AAEJ,EAAA,KAAA,MAAW,QAAQ,OAAS,EAAA;AAC1B,IAAI,IAAA,IAAA,CAAK,UAAU,YAAc,EAAA;AAC/B,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAGA,IAAI,IAAA,IAAA,CAAK,UAAU,WAAa,EAAA;AAC9B,MAAY,SAAA,GAAA,IAAA,CAAA;AAAA,KACd;AAAA,GACF;AAEA,EAAO,OAAA,SAAA,CAAA;AACT,CAAA;AAEO,MAAM,wBAEb,CAAA;AAAA,EACS,YAAoB,YAA0C,EAAA;AAA1C,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA,CAAA;AAAA,GAA2C;AAAA,EAE9D,MAAiB,GAAA;AACvB,IAAO,OAAA,CAAA,IAAA,EAAO,IAAK,CAAA,YAAA,CAAa,KAAM,CAAA,IAAA,CAAA,CAAA,CAAA;AAAA,GACxC;AAAA,EAEO,OAAoB,GAAA;AACzB,IAAI,IAAA,IAAA,CAAK,YAAa,CAAA,KAAA,CAAM,WAAa,EAAA;AACvC,MAAA,OAAO,EAAC,CAAA;AAAA,KACV;AAEA,IAAO,OAAA,CAAC,IAAK,CAAA,MAAA,EAAQ,CAAA,CAAA;AAAA,GACvB;AAAA,EAEO,WAAoC,GAAA;AACzC,IAAI,IAAA,IAAA,CAAK,YAAa,CAAA,KAAA,CAAM,WAAa,EAAA;AACvC,MAAA,OAAO,EAAC,CAAA;AAAA,KACV;AAEA,IAAA,IAAI,QAAqC,GAAA,IAAA,CAAA;AACzC,IAAI,IAAA,KAAA,GAAQ,IAAK,CAAA,YAAA,CAAa,KAAM,CAAA,KAAA,CAAA;AAEpC,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AACxB,MAAW,QAAA,GAAA,KAAA,CAAM,IAAI,MAAM,CAAA,CAAA;AAAA,KACjB,MAAA,IAAM,IAAK,CAAA,YAAA,CAAa,MAAM,OAAU,EAAA;AAElD,MAAW,QAAA,GAAA,CAAC,MAAO,CAAA,KAAK,CAAC,CAAA,CAAA;AAAA,KACpB,MAAA;AACL,MAAA,QAAA,GAAW,OAAO,KAAK,CAAA,CAAA;AAAA,KACzB;AAEA,IAAA,OAAO,EAAE,CAAC,IAAK,CAAA,MAAA,KAAW,QAAS,EAAA,CAAA;AAAA,GACrC;AAAA,EAEO,cAAc,MAAoC,EAAA;AACvD,IAAI,IAAA,QAAA,GAAW,MAAO,CAAA,IAAA,CAAK,MAAO,EAAA,CAAA,CAAA;AAElC,IAAA,IAAI,YAAY,IAAM,EAAA;AAEpB,MAAI,IAAA,IAAA,CAAK,YAAa,CAAA,KAAA,CAAM,UAAY,EAAA;AACtC,QAAA,QAAA,GAAW,wBAAwB,QAAQ,CAAA,CAAA;AAAA,OAC7C;AAMA,MAAI,IAAA,CAAC,IAAK,CAAA,YAAA,CAAa,QAAU,EAAA;AAC/B,QAAA,IAAA,CAAK,aAAa,kBAAqB,GAAA,IAAA,CAAA;AAAA,OACzC;AAEA,MAAK,IAAA,CAAA,YAAA,CAAa,cAAc,QAAQ,CAAA,CAAA;AAAA,KAC1C;AAAA,GACF;AACF,CAAA;AAEA,SAAS,wBAAwB,KAA0B,EAAA;AACzD,EAAA,IAAI,OAAQ,CAAA,KAAK,CAAK,IAAA,KAAA,CAAM,OAAO,iBAAmB,EAAA;AACpD,IAAA,OAAO,CAAC,kBAAkB,CAAA,CAAA;AAAA,GAC5B,MAAA,IAAW,UAAU,iBAAmB,EAAA;AACtC,IAAO,OAAA,kBAAA,CAAA;AAAA,GACT;AAEA,EAAO,OAAA,KAAA,CAAA;AACT,CAAA;AAMO,MAAM,cAA8C,CAAA;AAAA,EAClD,WAAA,CAAoB,QAAwB,SAA0B,EAAA;AAAlD,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA,CAAA;AAAwB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA,CAAA;AAAA,GAA2B;AAAA,EAEvE,UAAU,cAA6D,EAAA;AAC5E,IAAI,IAAA,cAAA,KAAmB,iBAAiB,IAAM,EAAA;AAC5C,MAAO,OAAA,iBAAA,CAAA;AAAA,KACT;AAEA,IAAI,IAAA,cAAA,KAAmB,iBAAiB,aAAe,EAAA;AACrD,MAAO,OAAA,cAAA,CAAe,GAAI,CAAA,gBAAA,CAAiB,aAAa,CAAA,CAAE,SAAU,CAAA,IAAA,CAAK,MAAQ,EAAA,EAAI,EAAA,IAAA,CAAK,SAAS,CAAA,CAAA;AAAA,KACrG;AAEA,IAAI,IAAA,cAAA,KAAmB,iBAAiB,UAAY,EAAA;AAClD,MAAO,OAAA,cAAA,CAAe,GAAI,CAAA,gBAAA,CAAiB,UAAU,CAAA,CAAE,UAAU,iBAAmB,EAAA,EAAI,EAAA,IAAA,CAAK,SAAS,CAAA,CAAA;AAAA,KACxG;AAEA,IAAA,OAAO,IAAK,CAAA,MAAA,CAAA;AAAA,GACd;AACF;;;;"}
package/dist/index.d.ts CHANGED
@@ -1362,6 +1362,7 @@ interface SceneDataTransformerState extends SceneDataState {
1362
1362
  declare class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerState> implements SceneDataProvider {
1363
1363
  private _transformSub?;
1364
1364
  private _results;
1365
+ private _prevDataFromSource?;
1365
1366
  /**
1366
1367
  * Scan transformations for variable usage and re-process transforms when a variable values change
1367
1368
  */
@@ -1374,6 +1375,8 @@ declare class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerS
1374
1375
  reprocessTransformations(): void;
1375
1376
  cancelQuery(): void;
1376
1377
  getResultsStream(): ReplaySubject<SceneDataProviderResult>;
1378
+ clone(withState?: Partial<SceneDataTransformerState>): this;
1379
+ private haveAlreadyTransformedData;
1377
1380
  private transform;
1378
1381
  }
1379
1382
 
package/dist/index.js CHANGED
@@ -2779,6 +2779,9 @@ class MultiValueVariable extends SceneObjectBase {
2779
2779
  }
2780
2780
  }
2781
2781
  }
2782
+ if (lodash.isEqual(value, this.state.value) && lodash.isEqual(text, this.state.text)) {
2783
+ return;
2784
+ }
2782
2785
  this.setStateHelper({ value, text, loading: false });
2783
2786
  this.publishEvent(new SceneVariableValueChangedEvent(this), true);
2784
2787
  }
@@ -6154,7 +6157,7 @@ class SceneDataTransformer extends SceneObjectBase {
6154
6157
  return true;
6155
6158
  }
6156
6159
  reprocessTransformations() {
6157
- this.transform(this.getSourceData().state.data);
6160
+ this.transform(this.getSourceData().state.data, true);
6158
6161
  }
6159
6162
  cancelQuery() {
6160
6163
  var _a, _b;
@@ -6163,8 +6166,42 @@ class SceneDataTransformer extends SceneObjectBase {
6163
6166
  getResultsStream() {
6164
6167
  return this._results;
6165
6168
  }
6166
- transform(data$1) {
6169
+ clone(withState) {
6170
+ const clone = super.clone(withState);
6171
+ if (this._prevDataFromSource) {
6172
+ clone["_prevDataFromSource"] = this._prevDataFromSource;
6173
+ }
6174
+ return clone;
6175
+ }
6176
+ haveAlreadyTransformedData(data) {
6177
+ if (!this._prevDataFromSource) {
6178
+ return false;
6179
+ }
6180
+ if (data === this._prevDataFromSource) {
6181
+ return true;
6182
+ }
6183
+ const { series, annotations } = this._prevDataFromSource;
6184
+ if (data.series === series && data.annotations === annotations) {
6185
+ if (this.state.data && data.state !== this.state.data.state) {
6186
+ this.setState({ data: __spreadProps$a(__spreadValues$k({}, this.state.data), { state: data.state }) });
6187
+ }
6188
+ return true;
6189
+ }
6190
+ return false;
6191
+ }
6192
+ transform(data$1, force = false) {
6167
6193
  var _a;
6194
+ if (this.state.transformations.length === 0 || !data$1) {
6195
+ this._prevDataFromSource = data$1;
6196
+ this.setState({ data: data$1 });
6197
+ if (data$1) {
6198
+ this._results.next({ origin: this, data: data$1 });
6199
+ }
6200
+ return;
6201
+ }
6202
+ if (!force && this.haveAlreadyTransformedData(data$1)) {
6203
+ return;
6204
+ }
6168
6205
  const seriesTransformations = this.state.transformations.filter((transformation) => {
6169
6206
  if ("options" in transformation || "topic" in transformation) {
6170
6207
  return transformation.topic == null || transformation.topic === data.DataTopic.Series;
@@ -6177,13 +6214,6 @@ class SceneDataTransformer extends SceneObjectBase {
6177
6214
  }
6178
6215
  return false;
6179
6216
  }).map((transformation) => "operator" in transformation ? transformation.operator : transformation);
6180
- if (this.state.transformations.length === 0 || !data$1) {
6181
- this.setState({ data: data$1 });
6182
- if (data$1) {
6183
- this._results.next({ origin: this, data: data$1 });
6184
- }
6185
- return;
6186
- }
6187
6217
  if (this._transformSub) {
6188
6218
  this._transformSub.unsubscribe();
6189
6219
  }
@@ -6218,9 +6248,10 @@ class SceneDataTransformer extends SceneObjectBase {
6218
6248
  });
6219
6249
  return rxjs.of(result);
6220
6250
  })
6221
- ).subscribe((data2) => {
6222
- this.setState({ data: data2 });
6223
- this._results.next({ origin: this, data: data2 });
6251
+ ).subscribe((transformedData) => {
6252
+ this.setState({ data: transformedData });
6253
+ this._results.next({ origin: this, data: transformedData });
6254
+ this._prevDataFromSource = data$1;
6224
6255
  });
6225
6256
  }
6226
6257
  }