@grafana/scenes 0.0.12 → 0.0.14

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.
Files changed (46) hide show
  1. package/dist/esm/components/EmbeddedScene.js +3 -2
  2. package/dist/esm/components/EmbeddedScene.js.map +1 -1
  3. package/dist/esm/components/SceneApp/SceneApp.js +164 -0
  4. package/dist/esm/components/SceneApp/SceneApp.js.map +1 -0
  5. package/dist/esm/components/SceneApp/utils.js +38 -0
  6. package/dist/esm/components/SceneApp/utils.js.map +1 -0
  7. package/dist/esm/components/SceneTimePicker.js +2 -1
  8. package/dist/esm/components/SceneTimePicker.js.map +1 -1
  9. package/dist/esm/components/VizPanel/VizPanelRenderer.js +6 -0
  10. package/dist/esm/components/VizPanel/VizPanelRenderer.js.map +1 -1
  11. package/dist/esm/core/SceneObjectBase.js +10 -4
  12. package/dist/esm/core/SceneObjectBase.js.map +1 -1
  13. package/dist/esm/core/SceneTimeRange.js +0 -2
  14. package/dist/esm/core/SceneTimeRange.js.map +1 -1
  15. package/dist/esm/core/sceneGraph.js +19 -2
  16. package/dist/esm/core/sceneGraph.js.map +1 -1
  17. package/dist/esm/core/types.js.map +1 -1
  18. package/dist/esm/index.js +1 -0
  19. package/dist/esm/index.js.map +1 -1
  20. package/dist/esm/querying/SceneQueryRunner.js +32 -3
  21. package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
  22. package/dist/esm/utils/writeSceneLog.js +8 -0
  23. package/dist/esm/utils/writeSceneLog.js.map +1 -0
  24. package/dist/esm/variables/VariableDependencyConfig.js +19 -8
  25. package/dist/esm/variables/VariableDependencyConfig.js.map +1 -1
  26. package/dist/esm/variables/VariableValueRecorder.js +56 -0
  27. package/dist/esm/variables/VariableValueRecorder.js.map +1 -0
  28. package/dist/esm/variables/components/VariableValueSelectors.js +34 -8
  29. package/dist/esm/variables/components/VariableValueSelectors.js.map +1 -1
  30. package/dist/esm/variables/interpolation/defaults.js +14 -3
  31. package/dist/esm/variables/interpolation/defaults.js.map +1 -1
  32. package/dist/esm/variables/interpolation/sceneInterpolator.js +2 -18
  33. package/dist/esm/variables/interpolation/sceneInterpolator.js.map +1 -1
  34. package/dist/esm/variables/lookupVariable.js +20 -0
  35. package/dist/esm/variables/lookupVariable.js.map +1 -0
  36. package/dist/esm/variables/sets/SceneVariableSet.js +28 -29
  37. package/dist/esm/variables/sets/SceneVariableSet.js.map +1 -1
  38. package/dist/esm/variables/types.js.map +1 -1
  39. package/dist/esm/variables/utils.js +11 -0
  40. package/dist/esm/variables/utils.js.map +1 -0
  41. package/dist/esm/variables/variants/query/QueryVariable.js +1 -3
  42. package/dist/esm/variables/variants/query/QueryVariable.js.map +1 -1
  43. package/dist/index.d.ts +82 -11
  44. package/dist/index.js +785 -431
  45. package/dist/index.js.map +1 -1
  46. package/package.json +6 -3
@@ -6,6 +6,8 @@ import { SceneObjectBase } from '../core/SceneObjectBase.js';
6
6
  import { sceneGraph } from '../core/sceneGraph.js';
7
7
  import { getDataSource } from '../utils/getDataSource.js';
8
8
  import { VariableDependencyConfig } from '../variables/VariableDependencyConfig.js';
9
+ import { writeSceneLog } from '../utils/writeSceneLog.js';
10
+ import { VariableValueRecorder } from '../variables/VariableValueRecorder.js';
9
11
 
10
12
  var __defProp = Object.defineProperty;
11
13
  var __defProps = Object.defineProperties;
@@ -33,9 +35,10 @@ function getNextRequestId() {
33
35
  class SceneQueryRunner extends SceneObjectBase {
34
36
  constructor() {
35
37
  super(...arguments);
38
+ this._variableValueRecorder = new VariableValueRecorder();
36
39
  this._variableDependency = new VariableDependencyConfig(this, {
37
40
  statePaths: ["queries", "datasource"],
38
- onReferencedVariableValueChanged: () => this.runQueries()
41
+ onVariableUpdatesCompleted: (variables, dependencyChanged) => this.onVariableUpdatesCompleted(variables, dependencyChanged)
39
42
  });
40
43
  this.onDataReceived = (data) => {
41
44
  this.setState({ data });
@@ -55,11 +58,27 @@ class SceneQueryRunner extends SceneObjectBase {
55
58
  this.runQueries();
56
59
  }
57
60
  }
61
+ onVariableUpdatesCompleted(_variablesThatHaveChanged, dependencyChanged) {
62
+ if (this.state.isWaitingForVariables && this.shouldRunQueriesOnActivate()) {
63
+ this.runQueries();
64
+ return;
65
+ }
66
+ if (dependencyChanged) {
67
+ this.runQueries();
68
+ }
69
+ }
58
70
  shouldRunQueriesOnActivate() {
59
- if (this.state.data) {
71
+ if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {
60
72
  return false;
61
73
  }
62
- if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {
74
+ if (this._variableValueRecorder.hasDependenciesChanged(this)) {
75
+ writeSceneLog(
76
+ "SceneQueryRunner",
77
+ "Variable dependency changed while inactive, shouldRunQueriesOnActivate returns true"
78
+ );
79
+ return true;
80
+ }
81
+ if (this.state.data) {
63
82
  return false;
64
83
  }
65
84
  return true;
@@ -70,6 +89,7 @@ class SceneQueryRunner extends SceneObjectBase {
70
89
  this._querySub.unsubscribe();
71
90
  this._querySub = void 0;
72
91
  }
92
+ this._variableValueRecorder.recordCurrentDependencyValuesForSceneObject(this);
73
93
  }
74
94
  setContainerWidth(width) {
75
95
  if (!this._containerWidth && width > 0) {
@@ -96,6 +116,14 @@ class SceneQueryRunner extends SceneObjectBase {
96
116
  return (_b = (_a = this.state.maxDataPoints) != null ? _a : this._containerWidth) != null ? _b : 500;
97
117
  }
98
118
  async runWithTimeRange(timeRange) {
119
+ if (sceneGraph.hasVariableDependencyInLoadingState(this)) {
120
+ writeSceneLog("SceneQueryRunner", "Variable dependency is in loading state, skipping query execution");
121
+ this.setState({ isWaitingForVariables: true });
122
+ return;
123
+ }
124
+ if (this.state.isWaitingForVariables) {
125
+ this.setState({ isWaitingForVariables: false });
126
+ }
99
127
  const { datasource, minInterval, queries } = this.state;
100
128
  const sceneObjectScopedVar = {
101
129
  __sceneObject: { text: "__sceneObject", value: this }
@@ -131,6 +159,7 @@ class SceneQueryRunner extends SceneObjectBase {
131
159
  request.interval = norm.interval;
132
160
  request.intervalMs = norm.intervalMs;
133
161
  const runRequest = getRunRequest();
162
+ writeSceneLog("SceneQueryRunner", "Starting runRequest", this.state.key);
134
163
  this._querySub = runRequest(ds, request).pipe(getTransformationsStream(this, this.state.transformations)).subscribe({
135
164
  next: this.onDataReceived
136
165
  });
@@ -1 +1 @@
1
- {"version":3,"file":"SceneQueryRunner.js","sources":["../../../src/querying/SceneQueryRunner.ts"],"sourcesContent":["import { cloneDeep } from 'lodash';\nimport { mergeMap, MonoTypeOperatorFunction, Unsubscribable, map, of } from 'rxjs';\n\nimport {\n CoreApp,\n DataQuery,\n DataQueryRequest,\n DataSourceRef,\n DataTransformerConfig,\n PanelData,\n rangeUtil,\n ScopedVar,\n TimeRange,\n transformDataFrame,\n} from '@grafana/data';\nimport { getRunRequest } from '@grafana/runtime';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObject, SceneObjectStatePlain } from '../core/types';\nimport { getDataSource } from '../utils/getDataSource';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\n\nlet counter = 100;\n\nexport function getNextRequestId() {\n return 'QS' + counter++;\n}\n\nexport interface QueryRunnerState extends SceneObjectStatePlain {\n data?: PanelData;\n queries: DataQueryExtended[];\n transformations?: DataTransformerConfig[];\n datasource?: DataSourceRef;\n minInterval?: string;\n maxDataPoints?: number;\n // Non persisted state\n maxDataPointsFromWidth?: boolean;\n}\n\nexport interface DataQueryExtended extends DataQuery {\n [key: string]: any;\n}\n\nexport class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> {\n private _querySub?: Unsubscribable;\n private _containerWidth?: number;\n\n protected _variableDependency = new VariableDependencyConfig(this, {\n statePaths: ['queries', 'datasource'],\n onReferencedVariableValueChanged: () => this.runQueries(),\n });\n\n public activate() {\n super.activate();\n const timeRange = sceneGraph.getTimeRange(this);\n\n this._subs.add(\n timeRange.subscribeToState({\n next: (timeRange) => {\n this.runWithTimeRange(timeRange.value);\n },\n })\n );\n\n if (this.shouldRunQueriesOnActivate()) {\n this.runQueries();\n }\n }\n\n private shouldRunQueriesOnActivate() {\n // If we already have data, no need\n // TODO validate that time range is similar and if not we should run queries again\n if (this.state.data) {\n return false;\n }\n\n // If no maxDataPoints specified we need might to wait for container width to be set from the outside\n if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {\n return false;\n }\n\n return true;\n }\n\n public deactivate(): void {\n super.deactivate();\n\n if (this._querySub) {\n this._querySub.unsubscribe();\n this._querySub = undefined;\n }\n }\n\n public setContainerWidth(width: number) {\n // If we don't have a width we should run queries\n if (!this._containerWidth && width > 0) {\n this._containerWidth = width;\n\n // If we don't have maxDataPoints specifically set and maxDataPointsFromWidth is true\n if (this.state.maxDataPointsFromWidth && !this.state.maxDataPoints) {\n // As this is called from render path we need to wait for next tick before running queries\n setTimeout(() => {\n if (this.isActive && !this._querySub) {\n this.runQueries();\n }\n }, 0);\n }\n } else {\n // if the updated container width is bigger than 0 let's remember the width until next query issue\n if (width > 0) {\n this._containerWidth = width;\n }\n }\n }\n\n public runQueries() {\n const timeRange = sceneGraph.getTimeRange(this);\n this.runWithTimeRange(timeRange.state.value);\n }\n\n private getMaxDataPoints() {\n return this.state.maxDataPoints ?? this._containerWidth ?? 500;\n }\n\n private async runWithTimeRange(timeRange: TimeRange) {\n const { datasource, minInterval, queries } = this.state;\n const sceneObjectScopedVar: Record<string, ScopedVar<SceneQueryRunner>> = {\n __sceneObject: { text: '__sceneObject', value: this },\n };\n const request: DataQueryRequest = {\n app: CoreApp.Dashboard,\n requestId: getNextRequestId(),\n timezone: 'browser',\n panelId: 1,\n dashboardId: 1,\n range: timeRange,\n interval: '1s',\n intervalMs: 1000,\n targets: cloneDeep(queries),\n maxDataPoints: this.getMaxDataPoints(),\n scopedVars: sceneObjectScopedVar,\n startTime: Date.now(),\n };\n\n try {\n const ds = await getDataSource(datasource, request.scopedVars);\n\n // Attach the data source name to each query\n request.targets = request.targets.map((query) => {\n if (!query.datasource) {\n query.datasource = ds.getRef();\n }\n return query;\n });\n\n // TODO interpolate minInterval\n const lowerIntervalLimit = minInterval ? minInterval : ds.interval;\n const norm = rangeUtil.calculateInterval(timeRange, request.maxDataPoints!, lowerIntervalLimit);\n\n // make shallow copy of scoped vars,\n // and add built in variables interval and interval_ms\n request.scopedVars = Object.assign({}, request.scopedVars, {\n __interval: { text: norm.interval, value: norm.interval },\n __interval_ms: { text: norm.intervalMs.toString(), value: norm.intervalMs },\n });\n\n request.interval = norm.interval;\n request.intervalMs = norm.intervalMs;\n\n const runRequest = getRunRequest();\n this._querySub = runRequest(ds, request)\n .pipe(getTransformationsStream(this, this.state.transformations))\n .subscribe({\n next: this.onDataReceived,\n });\n } catch (err) {\n console.error('PanelQueryRunner Error', err);\n }\n }\n\n private onDataReceived = (data: PanelData) => {\n this.setState({ data });\n };\n}\n\nexport const getTransformationsStream: (\n sceneObject: SceneObject,\n transformations?: DataTransformerConfig[]\n) => MonoTypeOperatorFunction<PanelData> = (sceneObject, transformations) => (inputStream) => {\n return inputStream.pipe(\n mergeMap((data) => {\n if (!transformations || transformations.length === 0) {\n return of(data);\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(sceneObject, value, data?.request?.scopedVars);\n },\n };\n\n return transformDataFrame(transformations, data.series, ctx).pipe(map((series) => ({ ...data, series })));\n })\n );\n};\n"],"names":["timeRange"],"mappings":"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"}
1
+ {"version":3,"file":"SceneQueryRunner.js","sources":["../../../src/querying/SceneQueryRunner.ts"],"sourcesContent":["import { cloneDeep } from 'lodash';\nimport { mergeMap, MonoTypeOperatorFunction, Unsubscribable, map, of } from 'rxjs';\n\nimport {\n CoreApp,\n DataQuery,\n DataQueryRequest,\n DataSourceRef,\n DataTransformerConfig,\n PanelData,\n rangeUtil,\n ScopedVar,\n TimeRange,\n transformDataFrame,\n} from '@grafana/data';\nimport { getRunRequest } from '@grafana/runtime';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObject, SceneObjectStatePlain } from '../core/types';\nimport { getDataSource } from '../utils/getDataSource';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\nimport { SceneVariable } from '../variables/types';\nimport { writeSceneLog } from '../utils/writeSceneLog';\nimport { VariableValueRecorder } from '../variables/VariableValueRecorder';\n\nlet counter = 100;\n\nexport function getNextRequestId() {\n return 'QS' + counter++;\n}\n\nexport interface QueryRunnerState extends SceneObjectStatePlain {\n data?: PanelData;\n queries: DataQueryExtended[];\n transformations?: DataTransformerConfig[];\n datasource?: DataSourceRef;\n minInterval?: string;\n maxDataPoints?: number;\n // Non persisted state\n maxDataPointsFromWidth?: boolean;\n isWaitingForVariables?: boolean;\n}\n\nexport interface DataQueryExtended extends DataQuery {\n [key: string]: any;\n}\n\nexport class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> {\n private _querySub?: Unsubscribable;\n private _containerWidth?: number;\n private _variableValueRecorder = new VariableValueRecorder();\n\n protected _variableDependency: VariableDependencyConfig<QueryRunnerState> = new VariableDependencyConfig(this, {\n statePaths: ['queries', 'datasource'],\n onVariableUpdatesCompleted: (variables, dependencyChanged) =>\n this.onVariableUpdatesCompleted(variables, dependencyChanged),\n });\n\n public activate() {\n super.activate();\n const timeRange = sceneGraph.getTimeRange(this);\n\n this._subs.add(\n timeRange.subscribeToState({\n next: (timeRange) => {\n this.runWithTimeRange(timeRange.value);\n },\n })\n );\n\n if (this.shouldRunQueriesOnActivate()) {\n this.runQueries();\n }\n }\n\n /**\n * Handles some tricky cases where we need to run queries even when they have not changed in case\n * the query execution on activate was stopped due to VariableSet still not having processed all variables.\n */\n private onVariableUpdatesCompleted(_variablesThatHaveChanged: Set<SceneVariable>, dependencyChanged: boolean) {\n if (this.state.isWaitingForVariables && this.shouldRunQueriesOnActivate()) {\n this.runQueries();\n return;\n }\n\n if (dependencyChanged) {\n this.runQueries();\n }\n }\n\n private shouldRunQueriesOnActivate() {\n // If no maxDataPoints specified we might need to wait for container width to be set from the outside\n if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {\n return false;\n }\n\n if (this._variableValueRecorder.hasDependenciesChanged(this)) {\n writeSceneLog(\n 'SceneQueryRunner',\n 'Variable dependency changed while inactive, shouldRunQueriesOnActivate returns true'\n );\n return true;\n }\n\n // If we already have data, no need\n // TODO validate that time range is similar and if not we should run queries again\n if (this.state.data) {\n return false;\n }\n\n return true;\n }\n\n public deactivate(): void {\n super.deactivate();\n\n if (this._querySub) {\n this._querySub.unsubscribe();\n this._querySub = undefined;\n }\n\n this._variableValueRecorder.recordCurrentDependencyValuesForSceneObject(this);\n }\n\n public setContainerWidth(width: number) {\n // If we don't have a width we should run queries\n if (!this._containerWidth && width > 0) {\n this._containerWidth = width;\n\n // If we don't have maxDataPoints specifically set and maxDataPointsFromWidth is true\n if (this.state.maxDataPointsFromWidth && !this.state.maxDataPoints) {\n // As this is called from render path we need to wait for next tick before running queries\n setTimeout(() => {\n if (this.isActive && !this._querySub) {\n this.runQueries();\n }\n }, 0);\n }\n } else {\n // if the updated container width is bigger than 0 let's remember the width until next query issue\n if (width > 0) {\n this._containerWidth = width;\n }\n }\n }\n\n public runQueries() {\n const timeRange = sceneGraph.getTimeRange(this);\n this.runWithTimeRange(timeRange.state.value);\n }\n\n private getMaxDataPoints() {\n return this.state.maxDataPoints ?? this._containerWidth ?? 500;\n }\n\n private async runWithTimeRange(timeRange: TimeRange) {\n // Skip executing queries if variable dependency is in loading state\n if (sceneGraph.hasVariableDependencyInLoadingState(this)) {\n writeSceneLog('SceneQueryRunner', 'Variable dependency is in loading state, skipping query execution');\n this.setState({ isWaitingForVariables: true });\n return;\n }\n\n // If we where waiting for variables clear that flag\n if (this.state.isWaitingForVariables) {\n this.setState({ isWaitingForVariables: false });\n }\n\n const { datasource, minInterval, queries } = this.state;\n const sceneObjectScopedVar: Record<string, ScopedVar<SceneQueryRunner>> = {\n __sceneObject: { text: '__sceneObject', value: this },\n };\n\n const request: DataQueryRequest = {\n app: CoreApp.Dashboard,\n requestId: getNextRequestId(),\n timezone: 'browser',\n panelId: 1,\n dashboardId: 1,\n range: timeRange,\n interval: '1s',\n intervalMs: 1000,\n targets: cloneDeep(queries),\n maxDataPoints: this.getMaxDataPoints(),\n scopedVars: sceneObjectScopedVar,\n startTime: Date.now(),\n };\n\n try {\n const ds = await getDataSource(datasource, request.scopedVars);\n\n // Attach the data source name to each query\n request.targets = request.targets.map((query) => {\n if (!query.datasource) {\n query.datasource = ds.getRef();\n }\n return query;\n });\n\n // TODO interpolate minInterval\n const lowerIntervalLimit = minInterval ? minInterval : ds.interval;\n const norm = rangeUtil.calculateInterval(timeRange, request.maxDataPoints!, lowerIntervalLimit);\n\n // make shallow copy of scoped vars,\n // and add built in variables interval and interval_ms\n request.scopedVars = Object.assign({}, request.scopedVars, {\n __interval: { text: norm.interval, value: norm.interval },\n __interval_ms: { text: norm.intervalMs.toString(), value: norm.intervalMs },\n });\n\n request.interval = norm.interval;\n request.intervalMs = norm.intervalMs;\n\n const runRequest = getRunRequest();\n\n writeSceneLog('SceneQueryRunner', 'Starting runRequest', this.state.key);\n\n this._querySub = runRequest(ds, request)\n .pipe(getTransformationsStream(this, this.state.transformations))\n .subscribe({\n next: this.onDataReceived,\n });\n } catch (err) {\n console.error('PanelQueryRunner Error', err);\n }\n }\n\n private onDataReceived = (data: PanelData) => {\n this.setState({ data });\n };\n}\n\nexport const getTransformationsStream: (\n sceneObject: SceneObject,\n transformations?: DataTransformerConfig[]\n) => MonoTypeOperatorFunction<PanelData> = (sceneObject, transformations) => (inputStream) => {\n return inputStream.pipe(\n mergeMap((data) => {\n if (!transformations || transformations.length === 0) {\n return of(data);\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(sceneObject, value, data?.request?.scopedVars);\n },\n };\n\n return transformDataFrame(transformations, data.series, ctx).pipe(map((series) => ({ ...data, series })));\n })\n );\n};\n"],"names":["timeRange"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ function writeSceneLog(logger, message, ...rest) {
2
+ if (window.grafanaSceneLogging) {
3
+ console.log(`${logger}: `, message, ...rest);
4
+ }
5
+ }
6
+
7
+ export { writeSceneLog };
8
+ //# sourceMappingURL=writeSceneLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeSceneLog.js","sources":["../../../src/utils/writeSceneLog.ts"],"sourcesContent":["export function writeSceneLog(logger: string, message: string, ...rest: unknown[]) {\n if ((window as any).grafanaSceneLogging) {\n console.log(`${logger}: `, message, ...rest);\n }\n}\n"],"names":[],"mappings":"AAAgB,SAAA,aAAA,CAAc,MAAgB,EAAA,OAAA,EAAA,GAAoB,IAAiB,EAAA;AACjF,EAAA,IAAK,OAAe,mBAAqB,EAAA;AACvC,IAAA,OAAA,CAAQ,GAAI,CAAA,CAAA,EAAG,MAAY,CAAA,EAAA,CAAA,EAAA,OAAA,EAAS,GAAG,IAAI,CAAA,CAAA;AAAA,GAC7C;AACF;;;;"}
@@ -1,26 +1,37 @@
1
1
  import { VARIABLE_REGEX } from './constants.js';
2
2
 
3
3
  class VariableDependencyConfig {
4
- constructor(_sceneObject, options) {
4
+ constructor(_sceneObject, _options) {
5
5
  this._sceneObject = _sceneObject;
6
+ this._options = _options;
6
7
  this._dependencies = /* @__PURE__ */ new Set();
7
8
  this.scanCount = 0;
8
9
  this.defaultHandlerReferencedVariableValueChanged = () => {
9
10
  this._sceneObject.forceRender();
10
11
  };
11
- var _a;
12
- this._statePaths = options.statePaths;
13
- this._onReferencedVariableValueChanged = (_a = options.onReferencedVariableValueChanged) != null ? _a : this.defaultHandlerReferencedVariableValueChanged;
12
+ this._statePaths = _options.statePaths;
14
13
  }
15
14
  hasDependencyOn(name) {
16
15
  return this.getNames().has(name);
17
16
  }
18
- variableValuesChanged(variables) {
17
+ variableUpdatesCompleted(changedVariables) {
19
18
  const deps = this.getNames();
20
- for (const variable of variables) {
19
+ let dependencyChanged = false;
20
+ for (const variable of changedVariables) {
21
21
  if (deps.has(variable.state.name)) {
22
- this._onReferencedVariableValueChanged();
23
- return;
22
+ dependencyChanged = true;
23
+ break;
24
+ }
25
+ }
26
+ if (this._options.onVariableUpdatesCompleted) {
27
+ this._options.onVariableUpdatesCompleted(changedVariables, dependencyChanged);
28
+ return;
29
+ }
30
+ if (dependencyChanged) {
31
+ if (this._options.onReferencedVariableValueChanged) {
32
+ this._options.onReferencedVariableValueChanged();
33
+ } else {
34
+ this.defaultHandlerReferencedVariableValueChanged();
24
35
  }
25
36
  }
26
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"VariableDependencyConfig.js","sources":["../../../src/variables/VariableDependencyConfig.ts"],"sourcesContent":["import { SceneObject, SceneObjectState } from '../core/types';\nimport { VARIABLE_REGEX } from './constants';\n\nimport { SceneVariable, SceneVariableDependencyConfigLike } from './types';\n\ninterface VariableDependencyConfigOptions<TState extends SceneObjectState> {\n /**\n * State paths to scan / extract variable dependencies from. Leave empty to scan all paths.\n */\n statePaths?: Array<keyof TState>;\n /**\n * Optional way to customize how to handle when a dependent variable changes\n * If not specified the default behavior is to trigger a re-render\n */\n onReferencedVariableValueChanged?: () => void;\n}\n\nexport class VariableDependencyConfig<TState extends SceneObjectState> implements SceneVariableDependencyConfigLike {\n private _state: TState | undefined;\n private _dependencies = new Set<string>();\n private _statePaths?: Array<keyof TState>;\n private _onReferencedVariableValueChanged: () => void;\n\n public scanCount = 0;\n\n public constructor(private _sceneObject: SceneObject<TState>, options: VariableDependencyConfigOptions<TState>) {\n this._statePaths = options.statePaths;\n this._onReferencedVariableValueChanged =\n options.onReferencedVariableValueChanged ?? this.defaultHandlerReferencedVariableValueChanged;\n }\n\n /**\n * Used to check for dependency on a specific variable\n */\n public hasDependencyOn(name: string): boolean {\n return this.getNames().has(name);\n }\n\n /**\n * This is called whenever any set of variables have new values. It up to this implementation to check if it's relevant given the current dependencies.\n */\n public variableValuesChanged(variables: Set<SceneVariable>) {\n const deps = this.getNames();\n\n for (const variable of variables) {\n if (deps.has(variable.state.name)) {\n this._onReferencedVariableValueChanged();\n return;\n }\n }\n }\n\n /**\n * Only way to force a re-render is to update state right now\n */\n private defaultHandlerReferencedVariableValueChanged = () => {\n this._sceneObject.forceRender();\n };\n\n public getNames(): Set<string> {\n const prevState = this._state;\n const newState = (this._state = this._sceneObject.state);\n\n if (!prevState) {\n // First time we always scan for dependencies\n this.scanStateForDependencies(this._state);\n return this._dependencies;\n }\n\n // Second time we only scan if state is a different and if any specific state path has changed\n if (newState !== prevState) {\n if (this._statePaths) {\n for (const path of this._statePaths) {\n if (newState[path] !== prevState[path]) {\n this.scanStateForDependencies(newState);\n break;\n }\n }\n } else {\n this.scanStateForDependencies(newState);\n }\n }\n\n return this._dependencies;\n }\n\n private scanStateForDependencies(state: TState) {\n this._dependencies.clear();\n this.scanCount += 1;\n\n if (this._statePaths) {\n for (const path of this._statePaths) {\n const value = state[path];\n if (value) {\n this.extractVariablesFrom(value);\n }\n }\n } else {\n this.extractVariablesFrom(state);\n }\n }\n\n private extractVariablesFrom(value: unknown) {\n VARIABLE_REGEX.lastIndex = 0;\n\n const stringToCheck = typeof value !== 'string' ? safeStringifyValue(value) : value;\n\n const matches = stringToCheck.matchAll(VARIABLE_REGEX);\n if (!matches) {\n return;\n }\n\n for (const match of matches) {\n const [, var1, var2, , var3] = match;\n const variableName = var1 || var2 || var3;\n this._dependencies.add(variableName);\n }\n }\n}\n\nconst safeStringifyValue = (value: unknown) => {\n try {\n return JSON.stringify(value, null);\n } catch (error) {\n console.error(error);\n }\n\n return '';\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VariableDependencyConfig.js","sources":["../../../src/variables/VariableDependencyConfig.ts"],"sourcesContent":["import { SceneObject, SceneObjectState } from '../core/types';\nimport { VARIABLE_REGEX } from './constants';\n\nimport { SceneVariable, SceneVariableDependencyConfigLike } from './types';\n\ninterface VariableDependencyConfigOptions<TState extends SceneObjectState> {\n /**\n * State paths to scan / extract variable dependencies from. Leave empty to scan all paths.\n */\n statePaths?: Array<keyof TState>;\n /**\n * Optional way to customize how to handle when a dependent variable changes\n * If not specified the default behavior is to trigger a re-render\n */\n onReferencedVariableValueChanged?: () => void;\n\n /**\n * Optional way to customize how to handle when the variable system has completed an update\n */\n onVariableUpdatesCompleted?: (changedVariables: Set<SceneVariable>, dependencyChanged: boolean) => void;\n}\n\nexport class VariableDependencyConfig<TState extends SceneObjectState> implements SceneVariableDependencyConfigLike {\n private _state: TState | undefined;\n private _dependencies = new Set<string>();\n private _statePaths?: Array<keyof TState>;\n\n public scanCount = 0;\n\n public constructor(\n private _sceneObject: SceneObject<TState>,\n private _options: VariableDependencyConfigOptions<TState>\n ) {\n this._statePaths = _options.statePaths;\n }\n\n /**\n * Used to check for dependency on a specific variable\n */\n public hasDependencyOn(name: string): boolean {\n return this.getNames().has(name);\n }\n\n /**\n * This is called whenever any set of variables have new values. It up to this implementation to check if it's relevant given the current dependencies.\n */\n public variableUpdatesCompleted(changedVariables: Set<SceneVariable>) {\n const deps = this.getNames();\n let dependencyChanged = false;\n\n for (const variable of changedVariables) {\n if (deps.has(variable.state.name)) {\n dependencyChanged = true;\n break;\n }\n }\n\n // If custom handler is always called to let the scene object know that SceneVariableSet has completed processing variables\n if (this._options.onVariableUpdatesCompleted) {\n this._options.onVariableUpdatesCompleted(changedVariables, dependencyChanged);\n return;\n }\n\n if (dependencyChanged) {\n if (this._options.onReferencedVariableValueChanged) {\n this._options.onReferencedVariableValueChanged();\n } else {\n this.defaultHandlerReferencedVariableValueChanged();\n }\n }\n }\n\n /**\n * Only way to force a re-render is to update state right now\n */\n private defaultHandlerReferencedVariableValueChanged = () => {\n this._sceneObject.forceRender();\n };\n\n public getNames(): Set<string> {\n const prevState = this._state;\n const newState = (this._state = this._sceneObject.state);\n\n if (!prevState) {\n // First time we always scan for dependencies\n this.scanStateForDependencies(this._state);\n return this._dependencies;\n }\n\n // Second time we only scan if state is a different and if any specific state path has changed\n if (newState !== prevState) {\n if (this._statePaths) {\n for (const path of this._statePaths) {\n if (newState[path] !== prevState[path]) {\n this.scanStateForDependencies(newState);\n break;\n }\n }\n } else {\n this.scanStateForDependencies(newState);\n }\n }\n\n return this._dependencies;\n }\n\n private scanStateForDependencies(state: TState) {\n this._dependencies.clear();\n this.scanCount += 1;\n\n if (this._statePaths) {\n for (const path of this._statePaths) {\n const value = state[path];\n if (value) {\n this.extractVariablesFrom(value);\n }\n }\n } else {\n this.extractVariablesFrom(state);\n }\n }\n\n private extractVariablesFrom(value: unknown) {\n VARIABLE_REGEX.lastIndex = 0;\n\n const stringToCheck = typeof value !== 'string' ? safeStringifyValue(value) : value;\n\n const matches = stringToCheck.matchAll(VARIABLE_REGEX);\n if (!matches) {\n return;\n }\n\n for (const match of matches) {\n const [, var1, var2, , var3] = match;\n const variableName = var1 || var2 || var3;\n this._dependencies.add(variableName);\n }\n }\n}\n\nconst safeStringifyValue = (value: unknown) => {\n try {\n return JSON.stringify(value, null);\n } catch (error) {\n console.error(error);\n }\n\n return '';\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { sceneGraph } from '../core/sceneGraph.js';
2
+ import { isVariableValueEqual } from './utils.js';
3
+
4
+ class VariableValueRecorder {
5
+ constructor() {
6
+ this._values = /* @__PURE__ */ new Map();
7
+ }
8
+ recordCurrentDependencyValuesForSceneObject(sceneObject) {
9
+ this.clearValues();
10
+ for (const variableName of sceneObject.variableDependency.getNames()) {
11
+ const variable = sceneGraph.lookupVariable(variableName, sceneObject);
12
+ if (variable) {
13
+ this._values.set(variable, variable.getValue());
14
+ }
15
+ }
16
+ }
17
+ clearValues() {
18
+ this._values.clear();
19
+ }
20
+ hasValues() {
21
+ return !!this._values;
22
+ }
23
+ recordCurrentValue(variable) {
24
+ this._values.set(variable, variable.getValue());
25
+ }
26
+ hasRecordedValue(variable) {
27
+ return this._values.has(variable);
28
+ }
29
+ hasValueChanged(variable) {
30
+ if (this._values.has(variable)) {
31
+ const value = this._values.get(variable);
32
+ if (!isVariableValueEqual(value, variable.getValue())) {
33
+ return true;
34
+ }
35
+ }
36
+ return false;
37
+ }
38
+ hasDependenciesChanged(sceneObject) {
39
+ if (!this._values) {
40
+ return false;
41
+ }
42
+ for (const variableName of sceneObject.variableDependency.getNames()) {
43
+ const variable = sceneGraph.lookupVariable(variableName, sceneObject);
44
+ if (variable && this._values.has(variable)) {
45
+ const value = this._values.get(variable);
46
+ if (!isVariableValueEqual(value, variable.getValue())) {
47
+ return true;
48
+ }
49
+ }
50
+ }
51
+ return false;
52
+ }
53
+ }
54
+
55
+ export { VariableValueRecorder };
56
+ //# sourceMappingURL=VariableValueRecorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariableValueRecorder.js","sources":["../../../src/variables/VariableValueRecorder.ts"],"sourcesContent":["import { sceneGraph } from '../core/sceneGraph';\nimport { SceneObject } from '../core/types';\nimport { SceneVariable, VariableValue } from './types';\nimport { isVariableValueEqual } from './utils';\n\n/**\n * Useful for remembering variable values to know if they have changed\n **/\nexport class VariableValueRecorder {\n private _values = new Map<SceneVariable, VariableValue | undefined | null>();\n\n public recordCurrentDependencyValuesForSceneObject(sceneObject: SceneObject) {\n this.clearValues();\n\n for (const variableName of sceneObject.variableDependency!.getNames()) {\n const variable = sceneGraph.lookupVariable(variableName, sceneObject);\n if (variable) {\n this._values.set(variable, variable.getValue());\n }\n }\n }\n\n public clearValues() {\n this._values.clear();\n }\n\n public hasValues(): boolean {\n return !!this._values;\n }\n\n public recordCurrentValue(variable: SceneVariable) {\n this._values.set(variable, variable.getValue());\n }\n\n public hasRecordedValue(variable: SceneVariable): boolean {\n return this._values.has(variable);\n }\n\n public hasValueChanged(variable: SceneVariable): boolean {\n if (this._values.has(variable)) {\n const value = this._values.get(variable);\n if (!isVariableValueEqual(value, variable.getValue())) {\n return true;\n }\n }\n\n return false;\n }\n\n public hasDependenciesChanged(sceneObject: SceneObject): boolean {\n if (!this._values) {\n return false;\n }\n\n for (const variableName of sceneObject.variableDependency!.getNames()) {\n const variable = sceneGraph.lookupVariable(variableName, sceneObject);\n if (variable && this._values.has(variable)) {\n const value = this._values.get(variable);\n if (!isVariableValueEqual(value, variable.getValue())) {\n return true;\n }\n }\n }\n\n return false;\n }\n}\n"],"names":[],"mappings":";;;AAQO,MAAM,qBAAsB,CAAA;AAAA,EAA5B,WAAA,GAAA;AACL,IAAQ,IAAA,CAAA,OAAA,uBAAc,GAAqD,EAAA,CAAA;AAAA,GAAA;AAAA,EAEpE,4CAA4C,WAA0B,EAAA;AAC3E,IAAA,IAAA,CAAK,WAAY,EAAA,CAAA;AAEjB,IAAA,KAAA,MAAW,YAAgB,IAAA,WAAA,CAAY,kBAAoB,CAAA,QAAA,EAAY,EAAA;AACrE,MAAA,MAAM,QAAW,GAAA,UAAA,CAAW,cAAe,CAAA,YAAA,EAAc,WAAW,CAAA,CAAA;AACpE,MAAA,IAAI,QAAU,EAAA;AACZ,QAAA,IAAA,CAAK,OAAQ,CAAA,GAAA,CAAI,QAAU,EAAA,QAAA,CAAS,UAAU,CAAA,CAAA;AAAA,OAChD;AAAA,KACF;AAAA,GACF;AAAA,EAEO,WAAc,GAAA;AACnB,IAAA,IAAA,CAAK,QAAQ,KAAM,EAAA,CAAA;AAAA,GACrB;AAAA,EAEO,SAAqB,GAAA;AAC1B,IAAO,OAAA,CAAC,CAAC,IAAK,CAAA,OAAA,CAAA;AAAA,GAChB;AAAA,EAEO,mBAAmB,QAAyB,EAAA;AACjD,IAAA,IAAA,CAAK,OAAQ,CAAA,GAAA,CAAI,QAAU,EAAA,QAAA,CAAS,UAAU,CAAA,CAAA;AAAA,GAChD;AAAA,EAEO,iBAAiB,QAAkC,EAAA;AACxD,IAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,GAAA,CAAI,QAAQ,CAAA,CAAA;AAAA,GAClC;AAAA,EAEO,gBAAgB,QAAkC,EAAA;AACvD,IAAA,IAAI,IAAK,CAAA,OAAA,CAAQ,GAAI,CAAA,QAAQ,CAAG,EAAA;AAC9B,MAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,OAAQ,CAAA,GAAA,CAAI,QAAQ,CAAA,CAAA;AACvC,MAAA,IAAI,CAAC,oBAAqB,CAAA,KAAA,EAAO,QAAS,CAAA,QAAA,EAAU,CAAG,EAAA;AACrD,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,KACF;AAEA,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAAA,EAEO,uBAAuB,WAAmC,EAAA;AAC/D,IAAI,IAAA,CAAC,KAAK,OAAS,EAAA;AACjB,MAAO,OAAA,KAAA,CAAA;AAAA,KACT;AAEA,IAAA,KAAA,MAAW,YAAgB,IAAA,WAAA,CAAY,kBAAoB,CAAA,QAAA,EAAY,EAAA;AACrE,MAAA,MAAM,QAAW,GAAA,UAAA,CAAW,cAAe,CAAA,YAAA,EAAc,WAAW,CAAA,CAAA;AACpE,MAAA,IAAI,QAAY,IAAA,IAAA,CAAK,OAAQ,CAAA,GAAA,CAAI,QAAQ,CAAG,EAAA;AAC1C,QAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,OAAQ,CAAA,GAAA,CAAI,QAAQ,CAAA,CAAA;AACvC,QAAA,IAAI,CAAC,oBAAqB,CAAA,KAAA,EAAO,QAAS,CAAA,QAAA,EAAU,CAAG,EAAA;AACrD,UAAO,OAAA,IAAA,CAAA;AAAA,SACT;AAAA,OACF;AAAA,KACF;AAEA,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF;;;;"}
@@ -1,34 +1,41 @@
1
1
  import React from 'react';
2
2
  import { VariableHide } from '@grafana/data';
3
3
  import { selectors } from '@grafana/e2e-selectors';
4
- import { Tooltip } from '@grafana/ui';
4
+ import { useStyles2, Tooltip } from '@grafana/ui';
5
5
  import { SceneObjectBase } from '../../core/SceneObjectBase.js';
6
6
  import { sceneGraph } from '../../core/sceneGraph.js';
7
+ import { css } from '@emotion/css';
7
8
 
8
9
  class VariableValueSelectors extends SceneObjectBase {
9
10
  }
10
11
  VariableValueSelectors.Component = VariableValueSelectorsRenderer;
11
12
  function VariableValueSelectorsRenderer({ model }) {
12
13
  const variables = sceneGraph.getVariables(model).useState();
14
+ const styles = useStyles2(getStyles);
13
15
  return /* @__PURE__ */ React.createElement(React.Fragment, null, variables.variables.map((variable) => /* @__PURE__ */ React.createElement(VariableValueSelectWrapper, {
14
16
  key: variable.state.key,
15
- variable
17
+ variable,
18
+ styles
16
19
  })));
17
20
  }
18
- function VariableValueSelectWrapper({ variable }) {
21
+ function VariableValueSelectWrapper({
22
+ variable,
23
+ styles
24
+ }) {
19
25
  const state = variable.useState();
20
26
  if (state.hide === VariableHide.hideVariable) {
21
27
  return null;
22
28
  }
23
29
  return /* @__PURE__ */ React.createElement("div", {
24
- className: "gf-form"
30
+ className: styles.container
25
31
  }, /* @__PURE__ */ React.createElement(VariableLabel, {
26
- state
32
+ state,
33
+ styles
27
34
  }), /* @__PURE__ */ React.createElement(variable.Component, {
28
35
  model: variable
29
36
  }));
30
37
  }
31
- function VariableLabel({ state }) {
38
+ function VariableLabel({ state, styles }) {
32
39
  var _a;
33
40
  if (state.hide === VariableHide.hideLabel) {
34
41
  return null;
@@ -40,17 +47,36 @@ function VariableLabel({ state }) {
40
47
  content: state.description,
41
48
  placement: "bottom"
42
49
  }, /* @__PURE__ */ React.createElement("label", {
43
- className: "gf-form-label gf-form-label--variable",
50
+ className: styles.variableLabel,
44
51
  "data-testid": selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName),
45
52
  htmlFor: elementId
46
53
  }, labelOrName));
47
54
  }
48
55
  return /* @__PURE__ */ React.createElement("label", {
49
- className: "gf-form-label gf-form-label--variable",
56
+ className: styles.variableLabel,
50
57
  "data-testid": selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName),
51
58
  htmlFor: elementId
52
59
  }, labelOrName);
53
60
  }
61
+ const getStyles = (theme) => ({
62
+ container: css({
63
+ display: "flex"
64
+ }),
65
+ variableLabel: css({
66
+ background: theme.isDark ? theme.colors.background.primary : theme.colors.background.secondary,
67
+ display: `flex`,
68
+ alignItems: "center",
69
+ padding: theme.spacing(0, 1),
70
+ fontWeight: theme.typography.fontWeightMedium,
71
+ fontSize: theme.typography.bodySmall.fontSize,
72
+ height: theme.spacing(theme.components.height.md),
73
+ lineHeight: theme.spacing(theme.components.height.md),
74
+ borderRadius: theme.shape.borderRadius(1),
75
+ border: `1px solid ${theme.components.input.borderColor}`,
76
+ position: "relative",
77
+ right: -1
78
+ })
79
+ });
54
80
 
55
81
  export { VariableValueSelectors };
56
82
  //# sourceMappingURL=VariableValueSelectors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VariableValueSelectors.js","sources":["../../../../src/variables/components/VariableValueSelectors.tsx"],"sourcesContent":["import React from 'react';\n\nimport { VariableHide } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { Tooltip } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { SceneComponentProps, SceneObject, SceneObjectStatePlain } from '../../core/types';\nimport { SceneVariableState } from '../types';\n\nexport class VariableValueSelectors extends SceneObjectBase<SceneObjectStatePlain> {\n public static Component = VariableValueSelectorsRenderer;\n}\n\nfunction VariableValueSelectorsRenderer({ model }: SceneComponentProps<VariableValueSelectors>) {\n const variables = sceneGraph.getVariables(model)!.useState();\n\n return (\n <>\n {variables.variables.map((variable) => (\n <VariableValueSelectWrapper key={variable.state.key} variable={variable} />\n ))}\n </>\n );\n}\n\nfunction VariableValueSelectWrapper({ variable }: { variable: SceneObject<SceneVariableState> }) {\n const state = variable.useState();\n\n if (state.hide === VariableHide.hideVariable) {\n return null;\n }\n\n return (\n <div className=\"gf-form\">\n <VariableLabel state={state} />\n <variable.Component model={variable} />\n </div>\n );\n}\n\nfunction VariableLabel({ state }: { state: SceneVariableState }) {\n if (state.hide === VariableHide.hideLabel) {\n return null;\n }\n\n const elementId = `var-${state.key}`;\n const labelOrName = state.label ?? state.name;\n\n if (state.description) {\n return (\n <Tooltip content={state.description} placement={'bottom'}>\n <label\n className=\"gf-form-label gf-form-label--variable\"\n data-testid={selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName)}\n htmlFor={elementId}\n >\n {labelOrName}\n </label>\n </Tooltip>\n );\n }\n\n return (\n <label\n className=\"gf-form-label gf-form-label--variable\"\n data-testid={selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName)}\n htmlFor={elementId}\n >\n {labelOrName}\n </label>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAWO,MAAM,+BAA+B,eAAuC,CAAA;AAEnF,CAAA;AAFa,sBAAA,CACG,SAAY,GAAA,8BAAA,CAAA;AAG5B,SAAS,8BAAA,CAA+B,EAAE,KAAA,EAAsD,EAAA;AAC9F,EAAA,MAAM,SAAY,GAAA,UAAA,CAAW,YAAa,CAAA,KAAK,EAAG,QAAS,EAAA,CAAA;AAE3D,EAAA,iEAEK,SAAU,CAAA,SAAA,CAAU,GAAI,CAAA,CAAC,6BACvB,KAAA,CAAA,aAAA,CAAA,0BAAA,EAAA;AAAA,IAA2B,GAAA,EAAK,SAAS,KAAM,CAAA,GAAA;AAAA,IAAK,QAAA;AAAA,GAAoB,CAC1E,CACH,CAAA,CAAA;AAEJ,CAAA;AAEA,SAAS,0BAAA,CAA2B,EAAE,QAAA,EAA2D,EAAA;AAC/F,EAAM,MAAA,KAAA,GAAQ,SAAS,QAAS,EAAA,CAAA;AAEhC,EAAI,IAAA,KAAA,CAAM,IAAS,KAAA,YAAA,CAAa,YAAc,EAAA;AAC5C,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,SAAU,EAAA,SAAA;AAAA,GAAA,kBACZ,KAAA,CAAA,aAAA,CAAA,aAAA,EAAA;AAAA,IAAc,KAAA;AAAA,GAAc,CAAA,kBAC5B,KAAA,CAAA,aAAA,CAAA,QAAA,CAAS,SAAT,EAAA;AAAA,IAAmB,KAAO,EAAA,QAAA;AAAA,GAAU,CACvC,CAAA,CAAA;AAEJ,CAAA;AAEA,SAAS,aAAA,CAAc,EAAE,KAAA,EAAwC,EAAA;AA1CjE,EAAA,IAAA,EAAA,CAAA;AA2CE,EAAI,IAAA,KAAA,CAAM,IAAS,KAAA,YAAA,CAAa,SAAW,EAAA;AACzC,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAM,MAAA,SAAA,GAAY,OAAO,KAAM,CAAA,GAAA,CAAA,CAAA,CAAA;AAC/B,EAAA,MAAM,WAAc,GAAA,CAAA,EAAA,GAAA,KAAA,CAAM,KAAN,KAAA,IAAA,GAAA,EAAA,GAAe,KAAM,CAAA,IAAA,CAAA;AAEzC,EAAA,IAAI,MAAM,WAAa,EAAA;AACrB,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA;AAAA,MAAQ,SAAS,KAAM,CAAA,WAAA;AAAA,MAAa,SAAW,EAAA,QAAA;AAAA,KAAA,kBAC7C,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA;AAAA,MACC,SAAU,EAAA,uCAAA;AAAA,MACV,eAAa,SAAU,CAAA,KAAA,CAAM,SAAU,CAAA,OAAA,CAAQ,kBAAkB,WAAW,CAAA;AAAA,MAC5E,OAAS,EAAA,SAAA;AAAA,KAAA,EAER,WACH,CACF,CAAA,CAAA;AAAA,GAEJ;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA;AAAA,IACC,SAAU,EAAA,uCAAA;AAAA,IACV,eAAa,SAAU,CAAA,KAAA,CAAM,SAAU,CAAA,OAAA,CAAQ,kBAAkB,WAAW,CAAA;AAAA,IAC5E,OAAS,EAAA,SAAA;AAAA,GAAA,EAER,WACH,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"VariableValueSelectors.js","sources":["../../../../src/variables/components/VariableValueSelectors.tsx"],"sourcesContent":["import React from 'react';\n\nimport { GrafanaTheme2, VariableHide } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { Tooltip, useStyles2 } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { SceneComponentProps, SceneObject, SceneObjectStatePlain } from '../../core/types';\nimport { SceneVariableState } from '../types';\nimport { css } from '@emotion/css';\n\nexport class VariableValueSelectors extends SceneObjectBase<SceneObjectStatePlain> {\n public static Component = VariableValueSelectorsRenderer;\n}\n\nfunction VariableValueSelectorsRenderer({ model }: SceneComponentProps<VariableValueSelectors>) {\n const variables = sceneGraph.getVariables(model)!.useState();\n const styles = useStyles2(getStyles);\n\n return (\n <>\n {variables.variables.map((variable) => (\n <VariableValueSelectWrapper key={variable.state.key} variable={variable} styles={styles} />\n ))}\n </>\n );\n}\n\nfunction VariableValueSelectWrapper({\n variable,\n styles,\n}: {\n variable: SceneObject<SceneVariableState>;\n styles: VariableLabelStyles;\n}) {\n const state = variable.useState();\n\n if (state.hide === VariableHide.hideVariable) {\n return null;\n }\n\n return (\n <div className={styles.container}>\n <VariableLabel state={state} styles={styles} />\n <variable.Component model={variable} />\n </div>\n );\n}\n\nfunction VariableLabel({ state, styles }: { state: SceneVariableState; styles: VariableLabelStyles }) {\n if (state.hide === VariableHide.hideLabel) {\n return null;\n }\n\n const elementId = `var-${state.key}`;\n const labelOrName = state.label ?? state.name;\n\n if (state.description) {\n return (\n <Tooltip content={state.description} placement={'bottom'}>\n <label\n className={styles.variableLabel}\n data-testid={selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName)}\n htmlFor={elementId}\n >\n {labelOrName}\n </label>\n </Tooltip>\n );\n }\n\n return (\n <label\n className={styles.variableLabel}\n data-testid={selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName)}\n htmlFor={elementId}\n >\n {labelOrName}\n </label>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n container: css({\n display: 'flex',\n }),\n variableLabel: css({\n background: theme.isDark ? theme.colors.background.primary : theme.colors.background.secondary,\n display: `flex`,\n alignItems: 'center',\n padding: theme.spacing(0, 1),\n fontWeight: theme.typography.fontWeightMedium,\n fontSize: theme.typography.bodySmall.fontSize,\n height: theme.spacing(theme.components.height.md),\n lineHeight: theme.spacing(theme.components.height.md),\n borderRadius: theme.shape.borderRadius(1),\n border: `1px solid ${theme.components.input.borderColor}`,\n position: 'relative',\n // To make the border line up with the input border\n right: -1,\n }),\n});\n\ntype VariableLabelStyles = ReturnType<typeof getStyles>;\n"],"names":[],"mappings":"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"}
@@ -1,9 +1,8 @@
1
1
  import { LoadingState, getDefaultTimeRange } from '@grafana/data';
2
2
  import { SceneDataNode } from '../../core/SceneDataNode.js';
3
+ import { SceneObjectBase } from '../../core/SceneObjectBase.js';
3
4
  import { SceneTimeRange } from '../../core/SceneTimeRange.js';
4
- import { SceneVariableSet } from '../sets/SceneVariableSet.js';
5
5
 
6
- const EmptyVariableSet = new SceneVariableSet({ variables: [] });
7
6
  const EmptyDataNode = new SceneDataNode({
8
7
  data: {
9
8
  state: LoadingState.Done,
@@ -12,6 +11,18 @@ const EmptyDataNode = new SceneDataNode({
12
11
  }
13
12
  });
14
13
  const DefaultTimeRange = new SceneTimeRange();
14
+ class EmptyVariableSetImpl extends SceneObjectBase {
15
+ constructor() {
16
+ super({ variables: [] });
17
+ }
18
+ getByName(name) {
19
+ return void 0;
20
+ }
21
+ isVariableLoadingOrWaitingToUpdate(variable) {
22
+ return false;
23
+ }
24
+ }
25
+ const EmptyVariableSet = new EmptyVariableSetImpl();
15
26
 
16
- export { DefaultTimeRange, EmptyDataNode, EmptyVariableSet };
27
+ export { DefaultTimeRange, EmptyDataNode, EmptyVariableSet, EmptyVariableSetImpl };
17
28
  //# sourceMappingURL=defaults.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","sources":["../../../../src/variables/interpolation/defaults.ts"],"sourcesContent":["import { getDefaultTimeRange, LoadingState } from '@grafana/data';\nimport { SceneDataNode } from '../../core/SceneDataNode';\nimport { SceneTimeRange } from '../../core/SceneTimeRange';\nimport { SceneVariableSet } from '../sets/SceneVariableSet';\n\nexport const EmptyVariableSet = new SceneVariableSet({ variables: [] });\n\nexport const EmptyDataNode = new SceneDataNode({\n data: {\n state: LoadingState.Done,\n series: [],\n timeRange: getDefaultTimeRange(),\n },\n});\n\nexport const DefaultTimeRange = new SceneTimeRange();\n"],"names":[],"mappings":";;;;;AAKO,MAAM,mBAAmB,IAAI,gBAAA,CAAiB,EAAE,SAAW,EAAA,IAAI,EAAA;AAEzD,MAAA,aAAA,GAAgB,IAAI,aAAc,CAAA;AAAA,EAC7C,IAAM,EAAA;AAAA,IACJ,OAAO,YAAa,CAAA,IAAA;AAAA,IACpB,QAAQ,EAAC;AAAA,IACT,WAAW,mBAAoB,EAAA;AAAA,GACjC;AACF,CAAC,EAAA;AAEY,MAAA,gBAAA,GAAmB,IAAI,cAAe;;;;"}
1
+ {"version":3,"file":"defaults.js","sources":["../../../../src/variables/interpolation/defaults.ts"],"sourcesContent":["import { getDefaultTimeRange, LoadingState } from '@grafana/data';\nimport { SceneDataNode } from '../../core/SceneDataNode';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneTimeRange } from '../../core/SceneTimeRange';\nimport { SceneVariable, SceneVariables, SceneVariableSetState, SceneVariableState } from '../types';\n\nexport const EmptyDataNode = new SceneDataNode({\n data: {\n state: LoadingState.Done,\n series: [],\n timeRange: getDefaultTimeRange(),\n },\n});\n\nexport const DefaultTimeRange = new SceneTimeRange();\n\n/**\n * Since this is used from sceneGraph.getVariables we cannot reference SceneVariableSet here as it would create a circular reference\n */\nexport class EmptyVariableSetImpl extends SceneObjectBase<SceneVariableSetState> implements SceneVariables {\n public constructor() {\n super({ variables: [] });\n }\n\n public getByName(name: string): SceneVariable<SceneVariableState> | undefined {\n return undefined;\n }\n\n public isVariableLoadingOrWaitingToUpdate(variable: SceneVariable<SceneVariableState>): boolean {\n return false;\n }\n}\n\nexport const EmptyVariableSet = new EmptyVariableSetImpl();\n"],"names":[],"mappings":";;;;;AAMa,MAAA,aAAA,GAAgB,IAAI,aAAc,CAAA;AAAA,EAC7C,IAAM,EAAA;AAAA,IACJ,OAAO,YAAa,CAAA,IAAA;AAAA,IACpB,QAAQ,EAAC;AAAA,IACT,WAAW,mBAAoB,EAAA;AAAA,GACjC;AACF,CAAC,EAAA;AAEY,MAAA,gBAAA,GAAmB,IAAI,cAAe,GAAA;AAK5C,MAAM,6BAA6B,eAAiE,CAAA;AAAA,EAClG,WAAc,GAAA;AACnB,IAAA,KAAA,CAAM,EAAE,SAAA,EAAW,EAAC,EAAG,CAAA,CAAA;AAAA,GACzB;AAAA,EAEO,UAAU,IAA6D,EAAA;AAC5E,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AAAA,EAEO,mCAAmC,QAAsD,EAAA;AAC9F,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA;AAEa,MAAA,gBAAA,GAAmB,IAAI,oBAAqB;;;;"}
@@ -1,6 +1,7 @@
1
1
  import { getSceneVariableForScopedVar } from './ScopedVarsVariable.js';
2
2
  import { FormatRegistryID, formatRegistry } from './formatRegistry.js';
3
3
  import { VARIABLE_REGEX } from '../constants.js';
4
+ import { lookupVariable } from '../lookupVariable.js';
4
5
 
5
6
  function sceneInterpolator(sceneObject, target, scopedVars, format) {
6
7
  if (!target) {
@@ -14,7 +15,7 @@ function sceneInterpolator(sceneObject, target, scopedVars, format) {
14
15
  if (scopedVars && scopedVars[variableName]) {
15
16
  variable = getSceneVariableForScopedVar(variableName, scopedVars[variableName]);
16
17
  } else {
17
- variable = lookupSceneVariable(variableName, sceneObject);
18
+ variable = lookupVariable(variableName, sceneObject);
18
19
  }
19
20
  if (!variable) {
20
21
  return match;
@@ -22,23 +23,6 @@ function sceneInterpolator(sceneObject, target, scopedVars, format) {
22
23
  return formatValue(variable, variable.getValue(fieldPath), fmt);
23
24
  });
24
25
  }
25
- function lookupSceneVariable(name, sceneObject) {
26
- const variables = sceneObject.state.$variables;
27
- if (!variables) {
28
- if (sceneObject.parent) {
29
- return lookupSceneVariable(name, sceneObject.parent);
30
- } else {
31
- return null;
32
- }
33
- }
34
- const found = variables.getByName(name);
35
- if (found) {
36
- return found;
37
- } else if (sceneObject.parent) {
38
- return lookupSceneVariable(name, sceneObject.parent);
39
- }
40
- return null;
41
- }
42
26
  function formatValue(variable, value, formatNameOrFn) {
43
27
  if (value === null || value === void 0) {
44
28
  return "";
@@ -1 +1 @@
1
- {"version":3,"file":"sceneInterpolator.js","sources":["../../../../src/variables/interpolation/sceneInterpolator.ts"],"sourcesContent":["import { ScopedVars } from '@grafana/data';\nimport { VariableModel, VariableType } from '@grafana/schema';\n\nimport { SceneObject } from '../../core/types';\nimport { VariableValue } from '../types';\n\nimport { getSceneVariableForScopedVar } from './ScopedVarsVariable';\nimport { formatRegistry, FormatRegistryID, FormatVariable } from './formatRegistry';\nimport { VARIABLE_REGEX } from '../constants';\n\nexport type CustomFormatterFn = (\n value: unknown,\n legacyVariableModel: Partial<VariableModel>,\n legacyDefaultFormatter?: CustomFormatterFn\n) => string;\n\n/**\n * This function will try to parse and replace any variable expression found in the target string. The sceneObject will be used as the source of variables. It will\n * use the scene graph and walk up the parent tree until it finds the closest variable.\n *\n * ScopedVars should not really be needed much in the new scene architecture as they can be added to the local scene node instead of passed in interpolate function.\n * It is supported here for backward compatibility and some edge cases where adding scoped vars to local scene node is not practical.\n */\nexport function sceneInterpolator(\n sceneObject: SceneObject,\n target: string | undefined | null,\n scopedVars?: ScopedVars,\n format?: string | CustomFormatterFn\n): string {\n if (!target) {\n return target ?? '';\n }\n\n VARIABLE_REGEX.lastIndex = 0;\n\n return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {\n const variableName = var1 || var2 || var3;\n const fmt = fmt2 || fmt3 || format;\n let variable: FormatVariable | undefined | null;\n\n if (scopedVars && scopedVars[variableName]) {\n variable = getSceneVariableForScopedVar(variableName, scopedVars[variableName]);\n } else {\n variable = lookupSceneVariable(variableName, sceneObject);\n }\n\n if (!variable) {\n return match;\n }\n\n return formatValue(variable, variable.getValue(fieldPath), fmt);\n });\n}\n\nfunction lookupSceneVariable(name: string, sceneObject: SceneObject): FormatVariable | null | undefined {\n const variables = sceneObject.state.$variables;\n if (!variables) {\n if (sceneObject.parent) {\n return lookupSceneVariable(name, sceneObject.parent);\n } else {\n return null;\n }\n }\n\n const found = variables.getByName(name);\n if (found) {\n return found;\n } else if (sceneObject.parent) {\n return lookupSceneVariable(name, sceneObject.parent);\n }\n\n return null;\n}\n\nfunction formatValue(\n variable: FormatVariable,\n value: VariableValue | undefined | null,\n formatNameOrFn?: string | CustomFormatterFn\n): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Special handling for custom values that should not be formatted / escaped\n // This is used by the custom allValue that usually contain wildcards and therefore should not be escaped\n if (typeof value === 'object' && 'isCustomValue' in value && formatNameOrFn !== FormatRegistryID.text) {\n return value.toString();\n }\n\n // if (isAdHoc(variable) && format !== FormatRegistryID.queryParam) {\n // return '';\n // }\n\n // if it's an object transform value to string\n if (!Array.isArray(value) && typeof value === 'object') {\n value = `${value}`;\n }\n\n if (typeof formatNameOrFn === 'function') {\n return formatNameOrFn(value, {\n name: variable.state.name,\n type: variable.state.type as VariableType,\n });\n }\n\n let args: string[] = [];\n\n if (!formatNameOrFn) {\n formatNameOrFn = FormatRegistryID.glob;\n } else {\n // some formats have arguments that come after ':' character\n args = formatNameOrFn.split(':');\n if (args.length > 1) {\n formatNameOrFn = args[0];\n args = args.slice(1);\n } else {\n args = [];\n }\n }\n\n let formatter = formatRegistry.getIfExists(formatNameOrFn);\n\n if (!formatter) {\n console.error(`Variable format ${formatNameOrFn} not found. Using glob format as fallback.`);\n formatter = formatRegistry.get(FormatRegistryID.glob);\n }\n\n return formatter.formatter(value, args, variable);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sceneInterpolator.js","sources":["../../../../src/variables/interpolation/sceneInterpolator.ts"],"sourcesContent":["import { ScopedVars } from '@grafana/data';\nimport { VariableModel, VariableType } from '@grafana/schema';\n\nimport { SceneObject } from '../../core/types';\nimport { VariableValue } from '../types';\n\nimport { getSceneVariableForScopedVar } from './ScopedVarsVariable';\nimport { formatRegistry, FormatRegistryID, FormatVariable } from './formatRegistry';\nimport { VARIABLE_REGEX } from '../constants';\nimport { lookupVariable } from '../lookupVariable';\n\nexport type CustomFormatterFn = (\n value: unknown,\n legacyVariableModel: Partial<VariableModel>,\n legacyDefaultFormatter?: CustomFormatterFn\n) => string;\n\n/**\n * This function will try to parse and replace any variable expression found in the target string. The sceneObject will be used as the source of variables. It will\n * use the scene graph and walk up the parent tree until it finds the closest variable.\n *\n * ScopedVars should not really be needed much in the new scene architecture as they can be added to the local scene node instead of passed in interpolate function.\n * It is supported here for backward compatibility and some edge cases where adding scoped vars to local scene node is not practical.\n */\nexport function sceneInterpolator(\n sceneObject: SceneObject,\n target: string | undefined | null,\n scopedVars?: ScopedVars,\n format?: string | CustomFormatterFn\n): string {\n if (!target) {\n return target ?? '';\n }\n\n VARIABLE_REGEX.lastIndex = 0;\n\n return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {\n const variableName = var1 || var2 || var3;\n const fmt = fmt2 || fmt3 || format;\n let variable: FormatVariable | undefined | null;\n\n if (scopedVars && scopedVars[variableName]) {\n variable = getSceneVariableForScopedVar(variableName, scopedVars[variableName]);\n } else {\n variable = lookupVariable(variableName, sceneObject);\n }\n\n if (!variable) {\n return match;\n }\n\n return formatValue(variable, variable.getValue(fieldPath), fmt);\n });\n}\n\nfunction formatValue(\n variable: FormatVariable,\n value: VariableValue | undefined | null,\n formatNameOrFn?: string | CustomFormatterFn\n): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Special handling for custom values that should not be formatted / escaped\n // This is used by the custom allValue that usually contain wildcards and therefore should not be escaped\n if (typeof value === 'object' && 'isCustomValue' in value && formatNameOrFn !== FormatRegistryID.text) {\n return value.toString();\n }\n\n // if (isAdHoc(variable) && format !== FormatRegistryID.queryParam) {\n // return '';\n // }\n\n // if it's an object transform value to string\n if (!Array.isArray(value) && typeof value === 'object') {\n value = `${value}`;\n }\n\n if (typeof formatNameOrFn === 'function') {\n return formatNameOrFn(value, {\n name: variable.state.name,\n type: variable.state.type as VariableType,\n });\n }\n\n let args: string[] = [];\n\n if (!formatNameOrFn) {\n formatNameOrFn = FormatRegistryID.glob;\n } else {\n // some formats have arguments that come after ':' character\n args = formatNameOrFn.split(':');\n if (args.length > 1) {\n formatNameOrFn = args[0];\n args = args.slice(1);\n } else {\n args = [];\n }\n }\n\n let formatter = formatRegistry.getIfExists(formatNameOrFn);\n\n if (!formatter) {\n console.error(`Variable format ${formatNameOrFn} not found. Using glob format as fallback.`);\n formatter = formatRegistry.get(FormatRegistryID.glob);\n }\n\n return formatter.formatter(value, args, variable);\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ function lookupVariable(name, sceneObject) {
2
+ const variables = sceneObject.state.$variables;
3
+ if (!variables) {
4
+ if (sceneObject.parent) {
5
+ return lookupVariable(name, sceneObject.parent);
6
+ } else {
7
+ return null;
8
+ }
9
+ }
10
+ const found = variables.getByName(name);
11
+ if (found) {
12
+ return found;
13
+ } else if (sceneObject.parent) {
14
+ return lookupVariable(name, sceneObject.parent);
15
+ }
16
+ return null;
17
+ }
18
+
19
+ export { lookupVariable };
20
+ //# sourceMappingURL=lookupVariable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookupVariable.js","sources":["../../../src/variables/lookupVariable.ts"],"sourcesContent":["import { SceneObject } from '../core/types';\nimport { SceneVariable } from './types';\n\n/**\n * Will walk the scene object graph up to the root looking for the first variable with the specified name\n */\nexport function lookupVariable(name: string, sceneObject: SceneObject): SceneVariable | null | undefined {\n const variables = sceneObject.state.$variables;\n if (!variables) {\n if (sceneObject.parent) {\n return lookupVariable(name, sceneObject.parent);\n } else {\n return null;\n }\n }\n\n const found = variables.getByName(name);\n if (found) {\n return found;\n } else if (sceneObject.parent) {\n return lookupVariable(name, sceneObject.parent);\n }\n\n return null;\n}\n"],"names":[],"mappings":"AAMgB,SAAA,cAAA,CAAe,MAAc,WAA4D,EAAA;AACvG,EAAM,MAAA,SAAA,GAAY,YAAY,KAAM,CAAA,UAAA,CAAA;AACpC,EAAA,IAAI,CAAC,SAAW,EAAA;AACd,IAAA,IAAI,YAAY,MAAQ,EAAA;AACtB,MAAO,OAAA,cAAA,CAAe,IAAM,EAAA,WAAA,CAAY,MAAM,CAAA,CAAA;AAAA,KACzC,MAAA;AACL,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAAA,GACF;AAEA,EAAM,MAAA,KAAA,GAAQ,SAAU,CAAA,SAAA,CAAU,IAAI,CAAA,CAAA;AACtC,EAAA,IAAI,KAAO,EAAA;AACT,IAAO,OAAA,KAAA,CAAA;AAAA,GACT,MAAA,IAAW,YAAY,MAAQ,EAAA;AAC7B,IAAO,OAAA,cAAA,CAAe,IAAM,EAAA,WAAA,CAAY,MAAM,CAAA,CAAA;AAAA,GAChD;AAEA,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}