@grafana/scenes 6.2.1--canary.990.13570008543.0 → 6.3.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/esm/components/SceneApp/SceneApp.js +3 -9
  3. package/dist/esm/components/SceneApp/SceneApp.js.map +1 -1
  4. package/dist/esm/components/SceneApp/SceneAppPage.js +0 -16
  5. package/dist/esm/components/SceneApp/SceneAppPage.js.map +1 -1
  6. package/dist/esm/core/SceneObjectBase.js +7 -0
  7. package/dist/esm/core/SceneObjectBase.js.map +1 -1
  8. package/dist/esm/core/sceneGraph/index.js +2 -3
  9. package/dist/esm/core/sceneGraph/index.js.map +1 -1
  10. package/dist/esm/core/sceneGraph/sceneGraph.js +1 -6
  11. package/dist/esm/core/sceneGraph/sceneGraph.js.map +1 -1
  12. package/dist/esm/index.js +0 -1
  13. package/dist/esm/index.js.map +1 -1
  14. package/dist/esm/querying/SceneQueryRunner.js +8 -33
  15. package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
  16. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js +4 -3
  17. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js.map +1 -1
  18. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/utils.js +1 -22
  19. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/utils.js.map +1 -1
  20. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +4 -10
  21. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
  22. package/dist/esm/variables/adhoc/getAdhocOptionSearcher.js +2 -3
  23. package/dist/esm/variables/adhoc/getAdhocOptionSearcher.js.map +1 -1
  24. package/dist/esm/variables/components/getOptionSearcher.js +2 -3
  25. package/dist/esm/variables/components/getOptionSearcher.js.map +1 -1
  26. package/dist/esm/variables/filter.js +35 -0
  27. package/dist/esm/variables/filter.js.map +1 -0
  28. package/dist/esm/variables/groupby/GroupByVariable.js +2 -3
  29. package/dist/esm/variables/groupby/GroupByVariable.js.map +1 -1
  30. package/dist/esm/variables/utils.js +1 -23
  31. package/dist/esm/variables/utils.js.map +1 -1
  32. package/dist/esm/variables/variants/query/createQueryVariableRunner.js +1 -1
  33. package/dist/esm/variables/variants/query/createQueryVariableRunner.js.map +1 -1
  34. package/dist/index.d.ts +25 -66
  35. package/dist/index.js +62 -228
  36. package/dist/index.js.map +1 -1
  37. package/package.json +2 -2
  38. package/dist/esm/core/SceneScopesBridge.js +0 -111
  39. package/dist/esm/core/SceneScopesBridge.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafana/scenes",
3
- "version": "6.2.1--canary.990.13570008543.0",
3
+ "version": "6.3.0",
4
4
  "description": "Grafana framework for building dynamic dashboards",
5
5
  "author": "Grafana Labs",
6
6
  "license": "AGPL-3.0-only",
@@ -116,5 +116,5 @@
116
116
  "prettier --write"
117
117
  ]
118
118
  },
119
- "gitHead": "6c7836911e351362419905e85e83ddedc4873918"
119
+ "gitHead": "ad5de5b8d8d435d6e4786135371f25e7ade47c96"
120
120
  }
@@ -1,111 +0,0 @@
1
- import { isEqual } from 'lodash';
2
- import { useEffect } from 'react';
3
- import { BehaviorSubject, filter, pairwise, map } from 'rxjs';
4
- import { useScopes } from '@grafana/runtime';
5
- import { SceneObjectBase } from './SceneObjectBase.js';
6
- import { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig.js';
7
-
8
- class SceneScopesBridge extends SceneObjectBase {
9
- constructor() {
10
- super(...arguments);
11
- this._urlSync = new SceneObjectUrlSyncConfig(this, { keys: ["scopes"] });
12
- this._renderBeforeActivation = true;
13
- this._contextSubject = new BehaviorSubject(void 0);
14
- this._pendingScopes = null;
15
- }
16
- getUrlState() {
17
- var _a, _b, _c;
18
- return {
19
- scopes: (_c = this._pendingScopes) != null ? _c : ((_b = (_a = this.context) == null ? void 0 : _a.state.value) != null ? _b : []).map((scope) => scope.metadata.name)
20
- };
21
- }
22
- updateFromUrl(values) {
23
- var _a, _b;
24
- let scopes = (_a = values["scopes"]) != null ? _a : [];
25
- scopes = (Array.isArray(scopes) ? scopes : [scopes]).map(String);
26
- if (!this.context) {
27
- this._pendingScopes = scopes;
28
- return;
29
- }
30
- (_b = this.context) == null ? void 0 : _b.changeScopes(scopes);
31
- }
32
- getValue() {
33
- var _a, _b;
34
- return (_b = (_a = this.context) == null ? void 0 : _a.state.value) != null ? _b : [];
35
- }
36
- subscribeToValue(cb) {
37
- return this.contextObservable.pipe(
38
- filter((context) => !!context && !context.state.loading),
39
- pairwise(),
40
- map(
41
- ([prevContext, newContext]) => {
42
- var _a, _b;
43
- return [(_a = prevContext == null ? void 0 : prevContext.state.value) != null ? _a : [], (_b = newContext == null ? void 0 : newContext.state.value) != null ? _b : []];
44
- }
45
- ),
46
- filter(([prevScopes, newScopes]) => !isEqual(prevScopes, newScopes))
47
- ).subscribe(([prevScopes, newScopes]) => {
48
- cb(newScopes, prevScopes);
49
- });
50
- }
51
- isLoading() {
52
- var _a, _b;
53
- return (_b = (_a = this.context) == null ? void 0 : _a.state.loading) != null ? _b : false;
54
- }
55
- subscribeToLoading(cb) {
56
- return this.contextObservable.pipe(
57
- filter((context) => !!context),
58
- pairwise(),
59
- map(
60
- ([prevContext, newContext]) => {
61
- var _a, _b;
62
- return [(_a = prevContext == null ? void 0 : prevContext.state.loading) != null ? _a : false, (_b = newContext == null ? void 0 : newContext.state.loading) != null ? _b : false];
63
- }
64
- ),
65
- filter(([prevLoading, newLoading]) => prevLoading !== newLoading)
66
- ).subscribe(([_prevLoading, newLoading]) => {
67
- cb(newLoading);
68
- });
69
- }
70
- setEnabled(enabled) {
71
- var _a;
72
- (_a = this.context) == null ? void 0 : _a.setEnabled(enabled);
73
- }
74
- setReadOnly(readOnly) {
75
- var _a;
76
- (_a = this.context) == null ? void 0 : _a.setReadOnly(readOnly);
77
- }
78
- updateContext(newContext) {
79
- var _a, _b;
80
- if (this._pendingScopes && newContext) {
81
- setTimeout(() => {
82
- newContext == null ? void 0 : newContext.changeScopes(this._pendingScopes);
83
- this._pendingScopes = null;
84
- });
85
- }
86
- if (this.context !== newContext || ((_a = this.context) == null ? void 0 : _a.state) !== (newContext == null ? void 0 : newContext.state)) {
87
- const shouldUpdate = ((_b = this.context) == null ? void 0 : _b.state.value) !== (newContext == null ? void 0 : newContext.state.value);
88
- this._contextSubject.next(newContext);
89
- if (shouldUpdate) {
90
- this.forceRender();
91
- }
92
- }
93
- }
94
- get context() {
95
- return this._contextSubject.getValue();
96
- }
97
- get contextObservable() {
98
- return this._contextSubject.asObservable();
99
- }
100
- }
101
- SceneScopesBridge.Component = SceneScopesBridgeRenderer;
102
- function SceneScopesBridgeRenderer({ model }) {
103
- const context = useScopes();
104
- useEffect(() => {
105
- model.updateContext(context);
106
- }, [context, model]);
107
- return null;
108
- }
109
-
110
- export { SceneScopesBridge };
111
- //# sourceMappingURL=SceneScopesBridge.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SceneScopesBridge.js","sources":["../../../src/core/SceneScopesBridge.ts"],"sourcesContent":["import { isEqual } from 'lodash';\nimport { useEffect } from 'react';\nimport { BehaviorSubject, filter, map, Observable, pairwise, Unsubscribable } from 'rxjs';\n\nimport { Scope } from '@grafana/data';\nimport { ScopesContextValue, useScopes } from '@grafana/runtime';\n\nimport { SceneObjectBase } from './SceneObjectBase';\nimport { SceneComponentProps, SceneObjectUrlValues, SceneObjectWithUrlSync } from './types';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\n\nexport class SceneScopesBridge extends SceneObjectBase implements SceneObjectWithUrlSync {\n static Component = SceneScopesBridgeRenderer;\n\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['scopes'] });\n\n protected _renderBeforeActivation = true;\n\n private _contextSubject = new BehaviorSubject<ScopesContextValue | undefined>(undefined);\n\n // Needed to maintain scopes values received from URL until the context is available\n private _pendingScopes: string[] | null = null;\n\n public getUrlState(): SceneObjectUrlValues {\n return {\n scopes: this._pendingScopes ?? (this.context?.state.value ?? []).map((scope: Scope) => scope.metadata.name),\n };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n let scopes = values['scopes'] ?? [];\n scopes = (Array.isArray(scopes) ? scopes : [scopes]).map(String);\n\n if (!this.context) {\n this._pendingScopes = scopes;\n return;\n }\n\n this.context?.changeScopes(scopes);\n }\n\n public getValue(): Scope[] {\n return this.context?.state.value ?? [];\n }\n\n public subscribeToValue(cb: (newScopes: Scope[], prevScopes: Scope[]) => void): Unsubscribable {\n return this.contextObservable\n .pipe(\n filter((context) => !!context && !context.state.loading),\n pairwise(),\n map(\n ([prevContext, newContext]) =>\n [prevContext?.state.value ?? [], newContext?.state.value ?? []] as [Scope[], Scope[]]\n ),\n filter(([prevScopes, newScopes]) => !isEqual(prevScopes, newScopes))\n )\n .subscribe(([prevScopes, newScopes]) => {\n cb(newScopes, prevScopes);\n });\n }\n\n public isLoading(): boolean {\n return this.context?.state.loading ?? false;\n }\n\n public subscribeToLoading(cb: (loading: boolean) => void): Unsubscribable {\n return this.contextObservable\n .pipe(\n filter((context) => !!context),\n pairwise(),\n map(\n ([prevContext, newContext]) =>\n [prevContext?.state.loading ?? false, newContext?.state.loading ?? false] as [boolean, boolean]\n ),\n filter(([prevLoading, newLoading]) => prevLoading !== newLoading)\n )\n .subscribe(([_prevLoading, newLoading]) => {\n cb(newLoading);\n });\n }\n\n public setEnabled(enabled: boolean) {\n this.context?.setEnabled(enabled);\n }\n\n public setReadOnly(readOnly: boolean) {\n this.context?.setReadOnly(readOnly);\n }\n\n /**\n * This method is used to keep the context up to date with the scopes context received from React\n *\n * Its rationale is:\n * - When a new context is available, check if we have pending scopes passed from the URL\n * - If we have pending scopes, ask the new context to load them\n * - The loading should happen in a setTimeout to allow the existing context to pass its values to the URL sync handler\n * - If a new context is received, propagate it as a new value in the behavior subject\n * - If a new value is received, force a re-render to trigger the URL sync handler\n */\n public updateContext(newContext: ScopesContextValue | undefined) {\n if (this._pendingScopes && newContext) {\n /**\n * The setTimeout here is needed to avoid a potential race condition in the URL sync handler\n * One way to test this is:\n * - navigate to a dashboard and select some scopes\n * - navigate to a suggested dashboard and change the selected scopes\n * - observe the URL not containing any scopes\n */\n setTimeout(() => {\n newContext?.changeScopes(this._pendingScopes!);\n this._pendingScopes = null;\n });\n\n /**\n * If we return here and don't allow the context to be propagated, scopes will never get activated when\n * navigating from a page without scopes to a page that has scopes.\n *\n * This is happening because the app will try to call `enable` on the context, but the context would not be available yet\n */\n }\n\n if (this.context !== newContext || this.context?.state !== newContext?.state) {\n // Checking if we should trigger a re-render before pushing new value for the context\n // Doing it here because otherwise the check would not be valid (this.context would be newContext due to the value push)\n const shouldUpdate = this.context?.state.value !== newContext?.state.value;\n\n this._contextSubject.next(newContext);\n\n /**\n * Whenever we got a new set of scopes, we force a re-render in order to trigger the URL sync handler\n * Without this, the URL would never be updated when the scopes change\n * TODO: This is a workaround and should be removed once we have a better way to handle this (aka trigger URL sync handler on demand)\n */\n if (shouldUpdate) {\n this.forceRender();\n }\n }\n }\n\n private get context(): ScopesContextValue | undefined {\n return this._contextSubject.getValue();\n }\n\n private get contextObservable(): Observable<ScopesContextValue | undefined> {\n return this._contextSubject.asObservable();\n }\n}\n\nfunction SceneScopesBridgeRenderer({ model }: SceneComponentProps<SceneScopesBridge>) {\n const context = useScopes();\n\n useEffect(() => {\n model.updateContext(context);\n }, [context, model]);\n\n return null;\n}\n"],"names":[],"mappings":"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"}