@grafana/scenes 4.26.3--canary.765.9399849393.0 → 4.27.0--canary.766.9367073867.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +0 -29
- package/README.md +0 -2
- package/dist/esm/components/EmbeddedScene.js +5 -0
- package/dist/esm/components/EmbeddedScene.js.map +1 -1
- package/dist/esm/components/SceneApp/SceneAppPage.js +5 -0
- package/dist/esm/components/SceneApp/SceneAppPage.js.map +1 -1
- package/dist/esm/components/SceneApp/SceneAppPageView.js +1 -3
- package/dist/esm/components/SceneApp/SceneAppPageView.js.map +1 -1
- package/dist/esm/components/SceneTimeRangeCompare.js +1 -55
- package/dist/esm/components/SceneTimeRangeCompare.js.map +1 -1
- package/dist/esm/components/VizPanel/VizPanel.js +0 -3
- package/dist/esm/components/VizPanel/VizPanel.js.map +1 -1
- package/dist/esm/core/sceneGraph/sceneGraph.js +1 -1
- package/dist/esm/core/types.js.map +1 -1
- package/dist/esm/index.js +1 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/querying/SceneQueryRunner.js +88 -85
- package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
- package/dist/esm/querying/timeShiftQueryResponseOperator.js +60 -0
- package/dist/esm/querying/timeShiftQueryResponseOperator.js.map +1 -0
- package/dist/esm/services/UniqueUrlKeyMapper.js +16 -24
- package/dist/esm/services/UniqueUrlKeyMapper.js.map +1 -1
- package/dist/esm/services/UrlSyncManager.js +34 -27
- package/dist/esm/services/UrlSyncManager.js.map +1 -1
- package/dist/esm/services/utils.js +4 -10
- package/dist/esm/services/utils.js.map +1 -1
- package/dist/esm/utils/writeSceneLog.js +1 -5
- package/dist/esm/utils/writeSceneLog.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js +40 -3
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js.map +1 -1
- package/dist/esm/variables/interpolation/sceneInterpolator.js +3 -3
- package/dist/esm/variables/interpolation/sceneInterpolator.js.map +1 -1
- package/dist/esm/variables/utils.js.map +1 -1
- package/dist/esm/variables/variants/query/QueryVariable.js.map +1 -1
- package/dist/index.d.ts +159 -275
- package/dist/index.js +1672 -1884
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
- package/dist/esm/core/PanelBuilders/VizConfigBuilder.js +0 -78
- package/dist/esm/core/PanelBuilders/VizConfigBuilder.js.map +0 -1
- package/dist/esm/core/PanelBuilders/VizConfigBuilders.js +0 -114
- package/dist/esm/core/PanelBuilders/VizConfigBuilders.js.map +0 -1
- package/dist/esm/querying/ExtraQueryProvider.js +0 -6
- package/dist/esm/querying/ExtraQueryProvider.js.map +0 -1
- package/dist/esm/querying/extraQueryProcessingOperator.js +0 -46
- package/dist/esm/querying/extraQueryProcessingOperator.js.map +0 -1
- package/dist/esm/services/UrlSyncContextProvider.js +0 -12
- package/dist/esm/services/UrlSyncContextProvider.js.map +0 -1
- package/dist/esm/services/useUrlSync.js +0 -27
- package/dist/esm/services/useUrlSync.js.map +0 -1
@@ -1,5 +1,3 @@
|
|
1
|
-
import { sceneGraph } from '../core/sceneGraph/index.js';
|
2
|
-
|
3
1
|
class UniqueUrlKeyMapper {
|
4
2
|
constructor() {
|
5
3
|
this.index = /* @__PURE__ */ new Map();
|
@@ -7,39 +5,33 @@ class UniqueUrlKeyMapper {
|
|
7
5
|
getUniqueKey(key, obj) {
|
8
6
|
const objectsWithKey = this.index.get(key);
|
9
7
|
if (!objectsWithKey) {
|
10
|
-
|
11
|
-
return key;
|
12
|
-
}
|
13
|
-
let address = objectsWithKey.findIndex((o) => o === obj);
|
14
|
-
if (address === -1) {
|
15
|
-
filterOutOrphanedObjects(objectsWithKey);
|
16
|
-
objectsWithKey.push(obj);
|
17
|
-
address = objectsWithKey.length - 1;
|
8
|
+
throw new Error("Cannot find any scene object that uses the key '" + key + "'");
|
18
9
|
}
|
10
|
+
const address = objectsWithKey.findIndex((o) => o.sceneObject === obj);
|
19
11
|
if (address > 0) {
|
20
12
|
return `${key}-${address + 1}`;
|
21
13
|
}
|
22
14
|
return key;
|
23
15
|
}
|
24
|
-
|
16
|
+
rebuildIndex(root) {
|
25
17
|
this.index.clear();
|
18
|
+
this.buildIndex(root, 0);
|
26
19
|
}
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
20
|
+
buildIndex(sceneObject, depth) {
|
21
|
+
if (sceneObject.urlSync) {
|
22
|
+
for (const key of sceneObject.urlSync.getKeys()) {
|
23
|
+
const hit = this.index.get(key);
|
24
|
+
if (hit) {
|
25
|
+
hit.push({ sceneObject, depth });
|
26
|
+
hit.sort((a, b) => a.depth - b.depth);
|
27
|
+
} else {
|
28
|
+
this.index.set(key, [{ sceneObject, depth }]);
|
29
|
+
}
|
30
|
+
}
|
33
31
|
}
|
32
|
+
sceneObject.forEachChild((child) => this.buildIndex(child, depth + 1));
|
34
33
|
}
|
35
34
|
}
|
36
|
-
function isOrphanOrInActive(obj) {
|
37
|
-
const root = obj.getRoot();
|
38
|
-
if (!sceneGraph.findObject(root, (child) => child === obj)) {
|
39
|
-
return true;
|
40
|
-
}
|
41
|
-
return false;
|
42
|
-
}
|
43
35
|
|
44
36
|
export { UniqueUrlKeyMapper };
|
45
37
|
//# sourceMappingURL=UniqueUrlKeyMapper.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"UniqueUrlKeyMapper.js","sources":["../../../src/services/UniqueUrlKeyMapper.ts"],"sourcesContent":["import {
|
1
|
+
{"version":3,"file":"UniqueUrlKeyMapper.js","sources":["../../../src/services/UniqueUrlKeyMapper.ts"],"sourcesContent":["import { SceneObject } from '../core/types';\n\nexport interface SceneObjectWithDepth {\n sceneObject: SceneObject;\n depth: number;\n}\n\nexport class UniqueUrlKeyMapper {\n private index = new Map<string, SceneObjectWithDepth[]>();\n\n public getUniqueKey(key: string, obj: SceneObject) {\n const objectsWithKey = this.index.get(key);\n if (!objectsWithKey) {\n throw new Error(\"Cannot find any scene object that uses the key '\" + key + \"'\");\n }\n\n const address = objectsWithKey.findIndex((o) => o.sceneObject === obj);\n if (address > 0) {\n return `${key}-${address + 1}`;\n }\n\n return key;\n }\n\n public rebuildIndex(root: SceneObject) {\n this.index.clear();\n this.buildIndex(root, 0);\n }\n\n private buildIndex(sceneObject: SceneObject, depth: number) {\n if (sceneObject.urlSync) {\n for (const key of sceneObject.urlSync.getKeys()) {\n const hit = this.index.get(key);\n if (hit) {\n hit.push({ sceneObject, depth });\n hit.sort((a, b) => a.depth - b.depth);\n } else {\n this.index.set(key, [{ sceneObject, depth }]);\n }\n }\n }\n\n sceneObject.forEachChild((child) => this.buildIndex(child, depth + 1));\n }\n}\n"],"names":[],"mappings":"AAOO,MAAM,kBAAmB,CAAA;AAAA,EAAzB,WAAA,GAAA;AACL,IAAQ,IAAA,CAAA,KAAA,uBAAY,GAAoC,EAAA,CAAA;AAAA,GAAA;AAAA,EAEjD,YAAA,CAAa,KAAa,GAAkB,EAAA;AACjD,IAAA,MAAM,cAAiB,GAAA,IAAA,CAAK,KAAM,CAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AACzC,IAAA,IAAI,CAAC,cAAgB,EAAA;AACnB,MAAA,MAAM,IAAI,KAAA,CAAM,kDAAqD,GAAA,GAAA,GAAM,GAAG,CAAA,CAAA;AAAA,KAChF;AAEA,IAAA,MAAM,UAAU,cAAe,CAAA,SAAA,CAAU,CAAC,CAAM,KAAA,CAAA,CAAE,gBAAgB,GAAG,CAAA,CAAA;AACrE,IAAA,IAAI,UAAU,CAAG,EAAA;AACf,MAAO,OAAA,CAAA,EAAG,OAAO,OAAU,GAAA,CAAA,CAAA,CAAA,CAAA;AAAA,KAC7B;AAEA,IAAO,OAAA,GAAA,CAAA;AAAA,GACT;AAAA,EAEO,aAAa,IAAmB,EAAA;AACrC,IAAA,IAAA,CAAK,MAAM,KAAM,EAAA,CAAA;AACjB,IAAK,IAAA,CAAA,UAAA,CAAW,MAAM,CAAC,CAAA,CAAA;AAAA,GACzB;AAAA,EAEQ,UAAA,CAAW,aAA0B,KAAe,EAAA;AAC1D,IAAA,IAAI,YAAY,OAAS,EAAA;AACvB,MAAA,KAAA,MAAW,GAAO,IAAA,WAAA,CAAY,OAAQ,CAAA,OAAA,EAAW,EAAA;AAC/C,QAAA,MAAM,GAAM,GAAA,IAAA,CAAK,KAAM,CAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAC9B,QAAA,IAAI,GAAK,EAAA;AACP,UAAA,GAAA,CAAI,IAAK,CAAA,EAAE,WAAa,EAAA,KAAA,EAAO,CAAA,CAAA;AAC/B,UAAA,GAAA,CAAI,KAAK,CAAC,CAAA,EAAG,MAAM,CAAE,CAAA,KAAA,GAAQ,EAAE,KAAK,CAAA,CAAA;AAAA,SAC/B,MAAA;AACL,UAAK,IAAA,CAAA,KAAA,CAAM,IAAI,GAAK,EAAA,CAAC,EAAE,WAAa,EAAA,KAAA,EAAO,CAAC,CAAA,CAAA;AAAA,SAC9C;AAAA,OACF;AAAA,KACF;AAEA,IAAY,WAAA,CAAA,YAAA,CAAa,CAAC,KAAU,KAAA,IAAA,CAAK,WAAW,KAAO,EAAA,KAAA,GAAQ,CAAC,CAAC,CAAA,CAAA;AAAA,GACvE;AACF;;;;"}
|
@@ -2,18 +2,34 @@ import { locationService } from '@grafana/runtime';
|
|
2
2
|
import { SceneObjectStateChangedEvent } from '../core/events.js';
|
3
3
|
import { writeSceneLog } from '../utils/writeSceneLog.js';
|
4
4
|
import { UniqueUrlKeyMapper } from './UniqueUrlKeyMapper.js';
|
5
|
-
import {
|
5
|
+
import { syncStateFromUrl, isUrlValueEqual, getUrlState } from './utils.js';
|
6
6
|
|
7
7
|
class UrlSyncManager {
|
8
8
|
constructor() {
|
9
9
|
this._urlKeyMapper = new UniqueUrlKeyMapper();
|
10
10
|
this._stateSub = null;
|
11
|
+
this._locationSub = null;
|
12
|
+
this._ignoreNextLocationUpdate = false;
|
13
|
+
this._onLocationUpdate = (location) => {
|
14
|
+
if (this._ignoreNextLocationUpdate) {
|
15
|
+
this._ignoreNextLocationUpdate = false;
|
16
|
+
return;
|
17
|
+
}
|
18
|
+
if (this._lastPath !== location.pathname) {
|
19
|
+
return;
|
20
|
+
}
|
21
|
+
const urlParams = new URLSearchParams(location.search);
|
22
|
+
this._urlKeyMapper.rebuildIndex(this._sceneRoot);
|
23
|
+
syncStateFromUrl(this._sceneRoot, urlParams, this._urlKeyMapper);
|
24
|
+
this._lastPath = location.pathname;
|
25
|
+
};
|
11
26
|
this._onStateChanged = ({ payload }) => {
|
12
27
|
const changedObject = payload.changedObject;
|
13
28
|
if (changedObject.urlSync) {
|
14
29
|
const newUrlState = changedObject.urlSync.getUrlState();
|
15
30
|
const searchParams = locationService.getSearch();
|
16
31
|
const mappedUpdated = {};
|
32
|
+
this._urlKeyMapper.rebuildIndex(this._sceneRoot);
|
17
33
|
for (const [key, newUrlValue] of Object.entries(newUrlState)) {
|
18
34
|
const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);
|
19
35
|
const currentUrlValue = searchParams.getAll(uniqueKey);
|
@@ -22,33 +38,36 @@ class UrlSyncManager {
|
|
22
38
|
}
|
23
39
|
}
|
24
40
|
if (Object.keys(mappedUpdated).length > 0) {
|
25
|
-
|
41
|
+
this._ignoreNextLocationUpdate = true;
|
26
42
|
locationService.partial(mappedUpdated, true);
|
27
|
-
this._lastLocation = locationService.getLocation();
|
28
|
-
this._urlParams = new URLSearchParams(this._lastLocation.search);
|
29
43
|
}
|
30
44
|
}
|
31
45
|
};
|
32
46
|
}
|
33
47
|
initSync(root) {
|
34
|
-
|
48
|
+
if (!this._locationSub) {
|
49
|
+
writeSceneLog("UrlSyncManager", "New location listen");
|
50
|
+
this._locationSub = locationService.getHistory().listen(this._onLocationUpdate);
|
51
|
+
}
|
35
52
|
if (this._stateSub) {
|
36
|
-
writeSceneLog("UrlSyncManager", "Unregister previous scene state subscription",
|
53
|
+
writeSceneLog("UrlSyncManager", "Unregister previous scene state subscription", this._sceneRoot.state.key);
|
37
54
|
this._stateSub.unsubscribe();
|
38
55
|
}
|
39
|
-
writeSceneLog("UrlSyncManager", "init", root.state.key);
|
40
56
|
this._sceneRoot = root;
|
57
|
+
this._lastPath = locationService.getLocation().pathname;
|
41
58
|
this._stateSub = root.subscribeToEvent(SceneObjectStateChangedEvent, this._onStateChanged);
|
42
|
-
this.
|
43
|
-
this._lastLocation = locationService.getLocation();
|
44
|
-
this._urlParams = new URLSearchParams(this._lastLocation.search);
|
45
|
-
this.handleNewObject(this._sceneRoot);
|
59
|
+
this.syncFrom(this._sceneRoot);
|
46
60
|
}
|
47
61
|
cleanUp(root) {
|
48
62
|
if (this._sceneRoot !== root) {
|
49
63
|
return;
|
50
64
|
}
|
51
65
|
writeSceneLog("UrlSyncManager", "Clean up");
|
66
|
+
if (this._locationSub) {
|
67
|
+
this._locationSub();
|
68
|
+
writeSceneLog("UrlSyncManager", "Unregister history listen");
|
69
|
+
this._locationSub = null;
|
70
|
+
}
|
52
71
|
if (this._stateSub) {
|
53
72
|
this._stateSub.unsubscribe();
|
54
73
|
this._stateSub = null;
|
@@ -59,23 +78,11 @@ class UrlSyncManager {
|
|
59
78
|
this._sceneRoot.state.key === root.state.key
|
60
79
|
);
|
61
80
|
}
|
62
|
-
this._sceneRoot = void 0;
|
63
|
-
this._urlParams = void 0;
|
64
81
|
}
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
writeSceneLog("UrlSyncManager", "handleNewLocation");
|
70
|
-
this._urlParams = new URLSearchParams(location.search);
|
71
|
-
this._lastLocation = location;
|
72
|
-
syncStateFromUrl(this._sceneRoot, this._urlParams, this._urlKeyMapper);
|
73
|
-
}
|
74
|
-
handleNewObject(sceneObj) {
|
75
|
-
if (!this._sceneRoot || !this._urlParams) {
|
76
|
-
return;
|
77
|
-
}
|
78
|
-
syncStateFromUrl(sceneObj, this._urlParams, this._urlKeyMapper);
|
82
|
+
syncFrom(sceneObj) {
|
83
|
+
const urlParams = locationService.getSearch();
|
84
|
+
this._urlKeyMapper.rebuildIndex(this._sceneRoot);
|
85
|
+
syncStateFromUrl(sceneObj, urlParams, this._urlKeyMapper);
|
79
86
|
}
|
80
87
|
getUrlState(root) {
|
81
88
|
return getUrlState(root);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"UrlSyncManager.js","sources":["../../../src/services/UrlSyncManager.ts"],"sourcesContent":["import { Location } from 'history';\n\nimport { locationService } from '@grafana/runtime';\n\nimport { SceneObjectStateChangedEvent } from '../core/events';\nimport { SceneObject, SceneObjectUrlValues } from '../core/types';\nimport { writeSceneLog } from '../utils/writeSceneLog';\nimport { Unsubscribable } from 'rxjs';\nimport { UniqueUrlKeyMapper } from './UniqueUrlKeyMapper';\nimport { getUrlState, isUrlValueEqual, syncStateFromUrl } from './utils';\n\nexport interface UrlSyncManagerLike {\n initSync(root: SceneObject): void;\n cleanUp(root: SceneObject): void;\n getUrlState(root: SceneObject): SceneObjectUrlValues;\n
|
1
|
+
{"version":3,"file":"UrlSyncManager.js","sources":["../../../src/services/UrlSyncManager.ts"],"sourcesContent":["import { Location, UnregisterCallback } from 'history';\n\nimport { locationService } from '@grafana/runtime';\n\nimport { SceneObjectStateChangedEvent } from '../core/events';\nimport { SceneObject, SceneObjectUrlValues } from '../core/types';\nimport { writeSceneLog } from '../utils/writeSceneLog';\nimport { Unsubscribable } from 'rxjs';\nimport { UniqueUrlKeyMapper } from './UniqueUrlKeyMapper';\nimport { getUrlState, isUrlValueEqual, syncStateFromUrl } from './utils';\n\nexport interface UrlSyncManagerLike {\n initSync(root: SceneObject): void;\n cleanUp(root: SceneObject): void;\n getUrlState(root: SceneObject): SceneObjectUrlValues;\n}\n\nexport class UrlSyncManager implements UrlSyncManagerLike {\n private _urlKeyMapper = new UniqueUrlKeyMapper();\n private _sceneRoot!: SceneObject;\n private _stateSub: Unsubscribable | null = null;\n private _locationSub?: UnregisterCallback | null = null;\n private _lastPath?: string;\n private _ignoreNextLocationUpdate = false;\n\n /**\n * Updates the current scene state to match URL state.\n */\n public initSync(root: SceneObject) {\n if (!this._locationSub) {\n writeSceneLog('UrlSyncManager', 'New location listen');\n this._locationSub = locationService.getHistory().listen(this._onLocationUpdate);\n }\n\n if (this._stateSub) {\n writeSceneLog('UrlSyncManager', 'Unregister previous scene state subscription', this._sceneRoot.state.key);\n this._stateSub.unsubscribe();\n }\n\n this._sceneRoot = root;\n this._lastPath = locationService.getLocation().pathname;\n this._stateSub = root.subscribeToEvent(SceneObjectStateChangedEvent, this._onStateChanged);\n\n this.syncFrom(this._sceneRoot);\n }\n\n public cleanUp(root: SceneObject) {\n // Ignore this if we have a new or different root\n if (this._sceneRoot !== root) {\n return;\n }\n\n writeSceneLog('UrlSyncManager', 'Clean up');\n\n if (this._locationSub) {\n this._locationSub();\n writeSceneLog('UrlSyncManager', 'Unregister history listen');\n this._locationSub = null;\n }\n\n if (this._stateSub) {\n this._stateSub.unsubscribe();\n this._stateSub = null;\n writeSceneLog(\n 'UrlSyncManager',\n 'Root deactived, unsub to state',\n 'same key',\n this._sceneRoot.state.key === root.state.key\n );\n }\n }\n\n public syncFrom(sceneObj: SceneObject) {\n const urlParams = locationService.getSearch();\n // The index is always from the root\n this._urlKeyMapper.rebuildIndex(this._sceneRoot);\n syncStateFromUrl(sceneObj, urlParams, this._urlKeyMapper);\n }\n\n private _onLocationUpdate = (location: Location) => {\n if (this._ignoreNextLocationUpdate) {\n this._ignoreNextLocationUpdate = false;\n return;\n }\n\n if (this._lastPath !== location.pathname) {\n return;\n }\n\n const urlParams = new URLSearchParams(location.search);\n // Rebuild key mapper index before starting sync\n this._urlKeyMapper.rebuildIndex(this._sceneRoot);\n // Sync scene state tree from url\n syncStateFromUrl(this._sceneRoot, urlParams, this._urlKeyMapper);\n this._lastPath = location.pathname;\n };\n\n private _onStateChanged = ({ payload }: SceneObjectStateChangedEvent) => {\n const changedObject = payload.changedObject;\n\n if (changedObject.urlSync) {\n const newUrlState = changedObject.urlSync.getUrlState();\n\n const searchParams = locationService.getSearch();\n const mappedUpdated: SceneObjectUrlValues = {};\n\n this._urlKeyMapper.rebuildIndex(this._sceneRoot);\n\n for (const [key, newUrlValue] of Object.entries(newUrlState)) {\n const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);\n const currentUrlValue = searchParams.getAll(uniqueKey);\n\n if (!isUrlValueEqual(currentUrlValue, newUrlValue)) {\n mappedUpdated[uniqueKey] = newUrlValue;\n }\n }\n\n if (Object.keys(mappedUpdated).length > 0) {\n this._ignoreNextLocationUpdate = true;\n locationService.partial(mappedUpdated, true);\n }\n }\n };\n\n public getUrlState(root: SceneObject): SceneObjectUrlValues {\n return getUrlState(root);\n }\n}\n\nlet urlSyncManager: UrlSyncManagerLike | undefined;\n\nexport function getUrlSyncManager(): UrlSyncManagerLike {\n if (!urlSyncManager) {\n urlSyncManager = new UrlSyncManager();\n }\n\n return urlSyncManager;\n}\n"],"names":[],"mappings":"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"}
|
@@ -3,6 +3,7 @@ import { UniqueUrlKeyMapper } from './UniqueUrlKeyMapper.js';
|
|
3
3
|
|
4
4
|
function getUrlState(root) {
|
5
5
|
const urlKeyMapper = new UniqueUrlKeyMapper();
|
6
|
+
urlKeyMapper.rebuildIndex(root);
|
6
7
|
const result = {};
|
7
8
|
const visitNode = (obj) => {
|
8
9
|
if (obj.urlSync) {
|
@@ -21,18 +22,10 @@ function getUrlState(root) {
|
|
21
22
|
}
|
22
23
|
function syncStateFromSearchParams(root, urlParams) {
|
23
24
|
const urlKeyMapper = new UniqueUrlKeyMapper();
|
25
|
+
urlKeyMapper.rebuildIndex(root);
|
24
26
|
syncStateFromUrl(root, urlParams, urlKeyMapper);
|
25
27
|
}
|
26
|
-
function syncStateFromUrl(
|
27
|
-
if (!root.parent) {
|
28
|
-
syncUrlStateToObject(root, urlParams, urlKeyMapper);
|
29
|
-
}
|
30
|
-
root.forEachChild((child) => {
|
31
|
-
syncUrlStateToObject(child, urlParams, urlKeyMapper);
|
32
|
-
});
|
33
|
-
root.forEachChild((child) => syncStateFromUrl(child, urlParams, urlKeyMapper));
|
34
|
-
}
|
35
|
-
function syncUrlStateToObject(sceneObject, urlParams, urlKeyMapper) {
|
28
|
+
function syncStateFromUrl(sceneObject, urlParams, urlKeyMapper) {
|
36
29
|
if (sceneObject.urlSync) {
|
37
30
|
const urlState = {};
|
38
31
|
const currentState = sceneObject.urlSync.getUrlState();
|
@@ -57,6 +50,7 @@ function syncUrlStateToObject(sceneObject, urlParams, urlKeyMapper) {
|
|
57
50
|
sceneObject.urlSync.updateFromUrl(urlState);
|
58
51
|
}
|
59
52
|
}
|
53
|
+
sceneObject.forEachChild((child) => syncStateFromUrl(child, urlParams, urlKeyMapper));
|
60
54
|
}
|
61
55
|
function isUrlValueEqual(currentUrlValue, newUrlValue) {
|
62
56
|
if (currentUrlValue.length === 0 && newUrlValue == null) {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../src/services/utils.ts"],"sourcesContent":["import { isEqual } from 'lodash';\n\nimport { SceneObject, SceneObjectUrlValue, SceneObjectUrlValues } from '../core/types';\nimport { UniqueUrlKeyMapper } from './UniqueUrlKeyMapper';\n\n/**\n * @param root\n * @returns the full scene url state as a object with keys and values\n */\nexport function getUrlState(root: SceneObject): SceneObjectUrlValues {\n const urlKeyMapper = new UniqueUrlKeyMapper();\n const result: SceneObjectUrlValues = {};\n\n const visitNode = (obj: SceneObject) => {\n if (obj.urlSync) {\n const newUrlState = obj.urlSync.getUrlState();\n\n for (const [key, value] of Object.entries(newUrlState)) {\n if (value != null) {\n const uniqueKey = urlKeyMapper.getUniqueKey(key, obj);\n result[uniqueKey] = value;\n }\n }\n }\n\n obj.forEachChild(visitNode);\n };\n\n visitNode(root);\n return result;\n}\n\n/**\n * Exported util function to sync state from an initial url state.\n * Useful for initializing an embedded scenes with a url state string.\n */\nexport function syncStateFromSearchParams(root: SceneObject, urlParams: URLSearchParams) {\n const urlKeyMapper = new UniqueUrlKeyMapper();\n
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../src/services/utils.ts"],"sourcesContent":["import { isEqual } from 'lodash';\n\nimport { SceneObject, SceneObjectUrlValue, SceneObjectUrlValues } from '../core/types';\nimport { UniqueUrlKeyMapper } from './UniqueUrlKeyMapper';\n\n/**\n * @param root\n * @returns the full scene url state as a object with keys and values\n */\nexport function getUrlState(root: SceneObject): SceneObjectUrlValues {\n const urlKeyMapper = new UniqueUrlKeyMapper();\n urlKeyMapper.rebuildIndex(root);\n\n const result: SceneObjectUrlValues = {};\n\n const visitNode = (obj: SceneObject) => {\n if (obj.urlSync) {\n const newUrlState = obj.urlSync.getUrlState();\n\n for (const [key, value] of Object.entries(newUrlState)) {\n if (value != null) {\n const uniqueKey = urlKeyMapper.getUniqueKey(key, obj);\n result[uniqueKey] = value;\n }\n }\n }\n\n obj.forEachChild(visitNode);\n };\n\n visitNode(root);\n return result;\n}\n\n/**\n * Exported util function to sync state from an initial url state.\n * Useful for initializing an embedded scenes with a url state string.\n */\nexport function syncStateFromSearchParams(root: SceneObject, urlParams: URLSearchParams) {\n const urlKeyMapper = new UniqueUrlKeyMapper();\n urlKeyMapper.rebuildIndex(root);\n syncStateFromUrl(root, urlParams, urlKeyMapper);\n}\n\nexport function syncStateFromUrl(\n sceneObject: SceneObject,\n urlParams: URLSearchParams,\n urlKeyMapper: UniqueUrlKeyMapper\n) {\n if (sceneObject.urlSync) {\n const urlState: SceneObjectUrlValues = {};\n const currentState = sceneObject.urlSync.getUrlState();\n\n for (const key of sceneObject.urlSync.getKeys()) {\n const uniqueKey = urlKeyMapper.getUniqueKey(key, sceneObject);\n const newValue = urlParams.getAll(uniqueKey);\n const currentValue = currentState[key];\n\n if (isUrlValueEqual(newValue, currentValue)) {\n continue;\n }\n\n if (newValue.length > 0) {\n if (Array.isArray(currentValue)) {\n urlState[key] = newValue;\n } else {\n urlState[key] = newValue[0];\n }\n } else {\n // mark this key as having no url state\n urlState[key] = null;\n }\n }\n\n if (Object.keys(urlState).length > 0) {\n sceneObject.urlSync.updateFromUrl(urlState);\n }\n }\n\n sceneObject.forEachChild((child) => syncStateFromUrl(child, urlParams, urlKeyMapper));\n}\n\nexport function isUrlValueEqual(currentUrlValue: string[], newUrlValue: SceneObjectUrlValue): boolean {\n if (currentUrlValue.length === 0 && newUrlValue == null) {\n return true;\n }\n\n if (!Array.isArray(newUrlValue) && currentUrlValue?.length === 1) {\n return newUrlValue === currentUrlValue[0];\n }\n\n if (newUrlValue?.length === 0 && currentUrlValue === null) {\n return true;\n }\n\n // We have two arrays, lets compare them\n return isEqual(currentUrlValue, newUrlValue);\n}\n"],"names":[],"mappings":"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"}
|
@@ -1,9 +1,5 @@
|
|
1
1
|
function writeSceneLog(logger, message, ...rest) {
|
2
|
-
|
3
|
-
if (typeof window !== "undefined") {
|
4
|
-
loggingEnabled = localStorage.getItem("grafana.debug.scenes") === "true";
|
5
|
-
}
|
6
|
-
if (loggingEnabled) {
|
2
|
+
if (window.grafanaSceneLogging) {
|
7
3
|
console.log(`${logger}: `, message, ...rest);
|
8
4
|
}
|
9
5
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"writeSceneLog.js","sources":["../../../src/utils/writeSceneLog.ts"],"sourcesContent":["export function writeSceneLog(logger: string, message: string, ...rest: unknown[]) {\n
|
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,8 +1,16 @@
|
|
1
|
-
import React, { useState } from 'react';
|
1
|
+
import React, { useState, useMemo } from 'react';
|
2
2
|
import { useStyles2, Select, Field, Button } from '@grafana/ui';
|
3
3
|
import { cx, css } from '@emotion/css';
|
4
4
|
import { ControlsLabel } from '../../utils/ControlsLabel.js';
|
5
|
+
import { getOptionSearcher } from '../components/getOptionSearcher.js';
|
5
6
|
|
7
|
+
function selectableValueToVariableValueOption(value) {
|
8
|
+
var _a;
|
9
|
+
return {
|
10
|
+
label: (_a = value.label) != null ? _a : String(value.value),
|
11
|
+
value: value.value
|
12
|
+
};
|
13
|
+
}
|
6
14
|
function keyLabelToOption(key, label) {
|
7
15
|
return key !== "" ? {
|
8
16
|
value: key,
|
@@ -18,9 +26,26 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
18
26
|
const [isValuesLoading, setIsValuesLoading] = useState(false);
|
19
27
|
const [isKeysOpen, setIsKeysOpen] = useState(false);
|
20
28
|
const [isValuesOpen, setIsValuesOpen] = useState(false);
|
29
|
+
const [valueInputValue, setValueInputValue] = useState("");
|
30
|
+
const [valueHasCustomValue, setValueHasCustomValue] = useState(false);
|
21
31
|
const keyValue = keyLabelToOption(filter.key, filter.keyLabel);
|
22
32
|
const valueValue = keyLabelToOption(filter.value, filter.valueLabel);
|
33
|
+
const optionSearcher = useMemo(
|
34
|
+
() => {
|
35
|
+
var _a2, _b2;
|
36
|
+
return getOptionSearcher(values.map(selectableValueToVariableValueOption), void 0, (_a2 = valueValue == null ? void 0 : valueValue.value) != null ? _a2 : "", (_b2 = valueValue == null ? void 0 : valueValue.label) != null ? _b2 : "");
|
37
|
+
},
|
38
|
+
[values, valueValue == null ? void 0 : valueValue.value, valueValue == null ? void 0 : valueValue.label]
|
39
|
+
);
|
40
|
+
const onValueInputChange = (value, { action }) => {
|
41
|
+
if (action === "input-change") {
|
42
|
+
setValueInputValue(value);
|
43
|
+
}
|
44
|
+
return value;
|
45
|
+
};
|
46
|
+
const filteredValueOptions = optionSearcher(valueInputValue);
|
23
47
|
const valueSelect = /* @__PURE__ */ React.createElement(Select, {
|
48
|
+
virtualized: true,
|
24
49
|
allowCustomValue: true,
|
25
50
|
isValidNewOption: (inputValue) => inputValue.trim().length > 0,
|
26
51
|
allowCreateWhileLoading: true,
|
@@ -30,21 +55,33 @@ function AdHocFilterRenderer({ filter, model }) {
|
|
30
55
|
width: "auto",
|
31
56
|
value: valueValue,
|
32
57
|
placeholder: "Select value",
|
33
|
-
options:
|
34
|
-
|
58
|
+
options: filteredValueOptions,
|
59
|
+
inputValue: valueInputValue,
|
60
|
+
onInputChange: onValueInputChange,
|
61
|
+
onChange: (v) => {
|
62
|
+
model._updateFilter(filter, "value", v);
|
63
|
+
if (valueHasCustomValue !== v.__isNew__) {
|
64
|
+
setValueHasCustomValue(v.__isNew__);
|
65
|
+
}
|
66
|
+
},
|
35
67
|
isOpen: isValuesOpen && !isValuesLoading,
|
36
68
|
isLoading: isValuesLoading,
|
37
69
|
autoFocus: filter.key !== "" && filter.value === "",
|
38
70
|
openMenuOnFocus: true,
|
39
71
|
onOpenMenu: async () => {
|
72
|
+
var _a2;
|
40
73
|
setIsValuesLoading(true);
|
41
74
|
setIsValuesOpen(true);
|
42
75
|
const values2 = await model._getValuesFor(filter);
|
43
76
|
setIsValuesLoading(false);
|
44
77
|
setValues(values2);
|
78
|
+
if (valueHasCustomValue) {
|
79
|
+
setValueInputValue((_a2 = valueValue == null ? void 0 : valueValue.label) != null ? _a2 : "");
|
80
|
+
}
|
45
81
|
},
|
46
82
|
onCloseMenu: () => {
|
47
83
|
setIsValuesOpen(false);
|
84
|
+
setValueInputValue("");
|
48
85
|
}
|
49
86
|
});
|
50
87
|
const keySelect = /* @__PURE__ */ React.createElement(Select, {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"AdHocFilterRenderer.js","sources":["../../../../src/variables/adhoc/AdHocFilterRenderer.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport { AdHocFiltersVariable, AdHocFilterWithLabels } from './AdHocFiltersVariable';\nimport { GrafanaTheme2, SelectableValue } from '@grafana/data';\nimport { Button, Field, Select, useStyles2 } from '@grafana/ui';\nimport { css, cx } from '@emotion/css';\nimport { ControlsLabel } from '../../utils/ControlsLabel';\n\ninterface Props {\n filter: AdHocFilterWithLabels;\n model: AdHocFiltersVariable;\n}\n\nfunction keyLabelToOption(key: string, label?: string): SelectableValue | null {\n return key !== ''\n ? {\n value: key,\n label: label || key,\n }\n : null;\n}\n\nexport function AdHocFilterRenderer({ filter, model }: Props) {\n const styles = useStyles2(getStyles);\n\n const [keys, setKeys] = useState<SelectableValue[]>([]);\n const [values, setValues] = useState<SelectableValue[]>([]);\n const [isKeysLoading, setIsKeysLoading] = useState(false);\n const [isValuesLoading, setIsValuesLoading] = useState(false);\n const [isKeysOpen, setIsKeysOpen] = useState(false);\n const [isValuesOpen, setIsValuesOpen] = useState(false);\n\n const keyValue = keyLabelToOption(filter.key, filter.keyLabel);\n const valueValue = keyLabelToOption(filter.value, filter.valueLabel);\n\n const valueSelect = (\n <Select\n allowCustomValue\n isValidNewOption={(inputValue) => inputValue.trim().length > 0}\n allowCreateWhileLoading\n formatCreateLabel={(inputValue) => `Use custom value: ${inputValue}`}\n disabled={model.state.readOnly}\n className={cx(styles.value, isKeysOpen ? styles.widthWhenOpen : undefined)}\n width=\"auto\"\n value={valueValue}\n placeholder={'Select value'}\n options={values}\n onChange={(v) => model._updateFilter(filter, 'value', v)}\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n isOpen={isValuesOpen && !isValuesLoading}\n isLoading={isValuesLoading}\n autoFocus={filter.key !== '' && filter.value === ''}\n openMenuOnFocus={true}\n onOpenMenu={async () => {\n setIsValuesLoading(true);\n setIsValuesOpen(true);\n const values = await model._getValuesFor(filter);\n setIsValuesLoading(false);\n setValues(values);\n }}\n onCloseMenu={() => {\n setIsValuesOpen(false);\n }}\n />\n );\n\n const keySelect = (\n <Select\n // By changing the key, we reset the Select component,\n // to ensure that the loaded values are shown after they are loaded\n key={`${isValuesLoading ? 'loading' : 'loaded'}`}\n disabled={model.state.readOnly}\n className={cx(styles.key, isKeysOpen ? styles.widthWhenOpen : undefined)}\n width=\"auto\"\n value={keyValue}\n placeholder={'Select label'}\n options={keys}\n onChange={(v) => model._updateFilter(filter, 'key', v)}\n autoFocus={filter.key === ''}\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n isOpen={isKeysOpen && !isKeysLoading}\n isLoading={isKeysLoading}\n onOpenMenu={async () => {\n setIsKeysOpen(true);\n setIsKeysLoading(true);\n const keys = await model._getKeys(filter.key);\n setIsKeysLoading(false);\n setKeys(keys);\n }}\n onCloseMenu={() => {\n setIsKeysOpen(false);\n }}\n onBlur={() => {\n if (filter.key === '') {\n model._removeFilter(filter);\n }\n }}\n openMenuOnFocus={true}\n />\n );\n\n if (model.state.layout === 'vertical') {\n if (filter.key) {\n const label = (\n <ControlsLabel layout=\"vertical\" label={filter.key ?? ''} onRemove={() => model._removeFilter(filter)} />\n );\n\n return (\n <Field label={label} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n {valueSelect}\n </Field>\n );\n } else {\n return (\n <Field label={'Select label'} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n {keySelect}\n </Field>\n );\n }\n }\n\n return (\n <div className={styles.wrapper} data-testid={`AdHocFilter-${filter.key}`}>\n {keySelect}\n <Select\n className={styles.operator}\n value={filter.operator}\n disabled={model.state.readOnly}\n options={model._getOperators()}\n width=\"auto\"\n onChange={(v) => model._updateFilter(filter, 'operator', v)}\n />\n {valueSelect}\n <Button\n variant=\"secondary\"\n aria-label=\"Remove filter\"\n title=\"Remove filter\"\n className={styles.removeButton}\n icon=\"times\"\n data-testid={`AdHocFilter-remove-${filter.key ?? ''}`}\n onClick={() => model._removeFilter(filter)}\n />\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n field: css({\n marginBottom: 0,\n }),\n wrapper: css({\n display: 'flex',\n '> *': {\n '&:not(:first-child)': {\n // Negative margin hides the double-border on adjacent selects\n marginLeft: -1,\n },\n\n '&:first-child': {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n },\n\n '&:last-child': {\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n },\n\n '&:not(:first-child):not(:last-child)': {\n borderRadius: 0,\n },\n\n // Fix focus state zIndex issues\n position: 'relative',\n zIndex: 0,\n\n // Adjacent borders are overlapping, so raise children up when hovering etc\n // so all that child's borders are visible.\n '&:hover': {\n zIndex: 1,\n },\n\n '&:focus-within': {\n zIndex: 2,\n },\n },\n }),\n widthWhenOpen: css({\n minWidth: theme.spacing(16),\n }),\n value: css({\n flexShrink: 1,\n }),\n key: css({\n minWidth: '90px',\n flexShrink: 1,\n }),\n operator: css({\n flexShrink: 0,\n }),\n removeButton: css({\n paddingLeft: theme.spacing(3 / 2),\n paddingRight: theme.spacing(3 / 2),\n borderLeft: 'none',\n width: theme.spacing(3),\n marginRight: theme.spacing(1),\n boxSizing: 'border-box',\n // To not have button background and last select border intersect\n position: 'relative',\n left: '1px',\n }),\n});\n"],"names":["values","keys"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"AdHocFilterRenderer.js","sources":["../../../../src/variables/adhoc/AdHocFilterRenderer.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\n\nimport { AdHocFiltersVariable, AdHocFilterWithLabels } from './AdHocFiltersVariable';\nimport { GrafanaTheme2, SelectableValue } from '@grafana/data';\nimport { Button, Field, InputActionMeta, Select, useStyles2 } from '@grafana/ui';\nimport { css, cx } from '@emotion/css';\nimport { ControlsLabel } from '../../utils/ControlsLabel';\nimport { getOptionSearcher } from '../components/getOptionSearcher';\nimport { VariableValueOption } from '../types';\n\ninterface Props {\n filter: AdHocFilterWithLabels;\n model: AdHocFiltersVariable;\n}\n\nfunction selectableValueToVariableValueOption(value: SelectableValue): VariableValueOption {\n return {\n label: value.label ?? String(value.value),\n value: value.value,\n }\n}\n\nfunction keyLabelToOption(key: string, label?: string): SelectableValue | null {\n return key !== ''\n ? {\n value: key,\n label: label || key,\n }\n : null;\n}\n\nexport function AdHocFilterRenderer({ filter, model }: Props) {\n const styles = useStyles2(getStyles);\n\n const [keys, setKeys] = useState<SelectableValue[]>([]);\n const [values, setValues] = useState<SelectableValue[]>([]);\n const [isKeysLoading, setIsKeysLoading] = useState(false);\n const [isValuesLoading, setIsValuesLoading] = useState(false);\n const [isKeysOpen, setIsKeysOpen] = useState(false);\n const [isValuesOpen, setIsValuesOpen] = useState(false);\n const [valueInputValue, setValueInputValue] = useState('');\n const [valueHasCustomValue, setValueHasCustomValue] = useState(false);\n\n const keyValue = keyLabelToOption(filter.key, filter.keyLabel);\n const valueValue = keyLabelToOption(filter.value, filter.valueLabel);\n\n const optionSearcher = useMemo(\n () => getOptionSearcher(values.map(selectableValueToVariableValueOption), undefined, valueValue?.value ?? '', valueValue?.label ?? ''),\n [values, valueValue?.value, valueValue?.label]\n );\n\n const onValueInputChange = (value: string, { action }: InputActionMeta) => {\n if (action === 'input-change') {\n setValueInputValue(value);\n }\n return value;\n };\n\n const filteredValueOptions: SelectableValue[] = optionSearcher(valueInputValue);\n\n const valueSelect = (\n <Select\n virtualized\n allowCustomValue\n isValidNewOption={(inputValue) => inputValue.trim().length > 0}\n allowCreateWhileLoading\n formatCreateLabel={(inputValue) => `Use custom value: ${inputValue}`}\n disabled={model.state.readOnly}\n className={cx(styles.value, isKeysOpen ? styles.widthWhenOpen : undefined)}\n width=\"auto\"\n value={valueValue}\n placeholder={'Select value'}\n options={filteredValueOptions}\n inputValue={valueInputValue}\n onInputChange={onValueInputChange}\n onChange={(v) => {\n model._updateFilter(filter, 'value', v)\n\n if (valueHasCustomValue !== v.__isNew__) {\n setValueHasCustomValue(v.__isNew__);\n }\n }}\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n isOpen={isValuesOpen && !isValuesLoading}\n isLoading={isValuesLoading}\n autoFocus={filter.key !== '' && filter.value === ''}\n openMenuOnFocus={true}\n onOpenMenu={async () => {\n setIsValuesLoading(true);\n setIsValuesOpen(true);\n const values = await model._getValuesFor(filter);\n setIsValuesLoading(false);\n setValues(values);\n if (valueHasCustomValue) {\n setValueInputValue(valueValue?.label ?? '');\n }\n }}\n onCloseMenu={() => {\n setIsValuesOpen(false);\n setValueInputValue('');\n }}\n />\n );\n\n const keySelect = (\n <Select\n // By changing the key, we reset the Select component,\n // to ensure that the loaded values are shown after they are loaded\n key={`${isValuesLoading ? 'loading' : 'loaded'}`}\n disabled={model.state.readOnly}\n className={cx(styles.key, isKeysOpen ? styles.widthWhenOpen : undefined)}\n width=\"auto\"\n value={keyValue}\n placeholder={'Select label'}\n options={keys}\n onChange={(v) => model._updateFilter(filter, 'key', v)}\n autoFocus={filter.key === ''}\n // there's a bug in react-select where the menu doesn't recalculate its position when the options are loaded asynchronously\n // see https://github.com/grafana/grafana/issues/63558\n // instead, we explicitly control the menu visibility and prevent showing it until the options have fully loaded\n isOpen={isKeysOpen && !isKeysLoading}\n isLoading={isKeysLoading}\n onOpenMenu={async () => {\n setIsKeysOpen(true);\n setIsKeysLoading(true);\n const keys = await model._getKeys(filter.key);\n setIsKeysLoading(false);\n setKeys(keys);\n }}\n onCloseMenu={() => {\n setIsKeysOpen(false);\n }}\n onBlur={() => {\n if (filter.key === '') {\n model._removeFilter(filter);\n }\n }}\n openMenuOnFocus={true}\n />\n );\n\n if (model.state.layout === 'vertical') {\n if (filter.key) {\n const label = (\n <ControlsLabel layout=\"vertical\" label={filter.key ?? ''} onRemove={() => model._removeFilter(filter)} />\n );\n\n return (\n <Field label={label} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n {valueSelect}\n </Field>\n );\n } else {\n return (\n <Field label={'Select label'} data-testid={`AdHocFilter-${filter.key}`} className={styles.field}>\n {keySelect}\n </Field>\n );\n }\n }\n\n return (\n <div className={styles.wrapper} data-testid={`AdHocFilter-${filter.key}`}>\n {keySelect}\n <Select\n className={styles.operator}\n value={filter.operator}\n disabled={model.state.readOnly}\n options={model._getOperators()}\n width=\"auto\"\n onChange={(v) => model._updateFilter(filter, 'operator', v)}\n />\n {valueSelect}\n <Button\n variant=\"secondary\"\n aria-label=\"Remove filter\"\n title=\"Remove filter\"\n className={styles.removeButton}\n icon=\"times\"\n data-testid={`AdHocFilter-remove-${filter.key ?? ''}`}\n onClick={() => model._removeFilter(filter)}\n />\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n field: css({\n marginBottom: 0,\n }),\n wrapper: css({\n display: 'flex',\n '> *': {\n '&:not(:first-child)': {\n // Negative margin hides the double-border on adjacent selects\n marginLeft: -1,\n },\n\n '&:first-child': {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n },\n\n '&:last-child': {\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n },\n\n '&:not(:first-child):not(:last-child)': {\n borderRadius: 0,\n },\n\n // Fix focus state zIndex issues\n position: 'relative',\n zIndex: 0,\n\n // Adjacent borders are overlapping, so raise children up when hovering etc\n // so all that child's borders are visible.\n '&:hover': {\n zIndex: 1,\n },\n\n '&:focus-within': {\n zIndex: 2,\n },\n },\n }),\n widthWhenOpen: css({\n minWidth: theme.spacing(16),\n }),\n value: css({\n flexShrink: 1,\n }),\n key: css({\n minWidth: '90px',\n flexShrink: 1,\n }),\n operator: css({\n flexShrink: 0,\n }),\n removeButton: css({\n paddingLeft: theme.spacing(3 / 2),\n paddingRight: theme.spacing(3 / 2),\n borderLeft: 'none',\n width: theme.spacing(3),\n marginRight: theme.spacing(1),\n boxSizing: 'border-box',\n // To not have button background and last select border intersect\n position: 'relative',\n left: '1px',\n }),\n});\n"],"names":["_a","_b","values","keys"],"mappings":"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"}
|
@@ -21,7 +21,7 @@ function sceneInterpolator(sceneObject, target, scopedVars, format, interpolatio
|
|
21
21
|
}
|
22
22
|
return match;
|
23
23
|
}
|
24
|
-
const value = formatValue(
|
24
|
+
const value = formatValue(variable, variable.getValue(fieldPath), fmt);
|
25
25
|
if (interpolations) {
|
26
26
|
interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match });
|
27
27
|
}
|
@@ -42,12 +42,12 @@ function lookupFormatVariable(name, match, scopedVars, sceneObject) {
|
|
42
42
|
}
|
43
43
|
return null;
|
44
44
|
}
|
45
|
-
function formatValue(
|
45
|
+
function formatValue(variable, value, formatNameOrFn) {
|
46
46
|
if (value === null || value === void 0) {
|
47
47
|
return "";
|
48
48
|
}
|
49
49
|
if (isCustomVariableValue(value)) {
|
50
|
-
return
|
50
|
+
return value.formatter(formatNameOrFn);
|
51
51
|
}
|
52
52
|
if (!Array.isArray(value) && typeof value === "object") {
|
53
53
|
value = `${value}`;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"sceneInterpolator.js","sources":["../../../../src/variables/interpolation/sceneInterpolator.ts"],"sourcesContent":["import { ScopedVars } from '@grafana/data';\nimport { VariableInterpolation } from '@grafana/runtime';\nimport { VariableType, VariableFormatID } from '@grafana/schema';\n\nimport { SceneObject } from '../../core/types';\nimport { InterpolationFormatParameter, isCustomVariableValue, VariableValue } from '../types';\n\nimport { getSceneVariableForScopedVar } from './ScopedVarsVariable';\nimport { formatRegistry, FormatVariable } from './formatRegistry';\nimport { VARIABLE_REGEX } from '../constants';\nimport { lookupVariable } from '../lookupVariable';\nimport { macrosIndex } from '../macros';\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?: InterpolationFormatParameter,\n interpolations?: VariableInterpolation[]
|
1
|
+
{"version":3,"file":"sceneInterpolator.js","sources":["../../../../src/variables/interpolation/sceneInterpolator.ts"],"sourcesContent":["import { ScopedVars } from '@grafana/data';\nimport { VariableInterpolation } from '@grafana/runtime';\nimport { VariableType, VariableFormatID } from '@grafana/schema';\n\nimport { SceneObject } from '../../core/types';\nimport { InterpolationFormatParameter, isCustomVariableValue, VariableValue } from '../types';\n\nimport { getSceneVariableForScopedVar } from './ScopedVarsVariable';\nimport { formatRegistry, FormatVariable } from './formatRegistry';\nimport { VARIABLE_REGEX } from '../constants';\nimport { lookupVariable } from '../lookupVariable';\nimport { macrosIndex } from '../macros';\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?: InterpolationFormatParameter,\n interpolations?: VariableInterpolation[],\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 const variable = lookupFormatVariable(variableName, match, scopedVars, sceneObject);\n\n if (!variable) {\n if (interpolations) {\n // Set `value` equal to `match` as documented in the `VariableInterpolation` interface.\n interpolations.push({ match, variableName, fieldPath, format: fmt, value: match, found: false });\n }\n return match;\n }\n const value = formatValue(variable, variable.getValue(fieldPath), fmt);\n if (interpolations) {\n interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match });\n }\n return value;\n });\n}\n\nfunction lookupFormatVariable(\n name: string,\n match: string,\n scopedVars: ScopedVars | undefined,\n sceneObject: SceneObject\n): FormatVariable | null {\n const scopedVar = scopedVars?.[name];\n\n if (scopedVar) {\n return getSceneVariableForScopedVar(name, scopedVar);\n }\n\n const variable = lookupVariable(name, sceneObject);\n if (variable) {\n return variable;\n }\n\n if (macrosIndex[name]) {\n return new macrosIndex[name](name, sceneObject, match, scopedVars);\n }\n\n return null;\n}\n\nfunction formatValue(\n variable: FormatVariable,\n value: VariableValue | undefined | null,\n formatNameOrFn?: InterpolationFormatParameter\n): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Variable can return a custom value that handles formatting\n // This is useful for customAllValue and macros that return values that are already formatted or need special formatting\n if (isCustomVariableValue(value)) {\n return value.formatter(formatNameOrFn);\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 multi: variable.state.isMulti,\n includeAll: variable.state.includeAll,\n });\n }\n\n let args: string[] = [];\n\n if (!formatNameOrFn) {\n formatNameOrFn = VariableFormatID.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(VariableFormatID.Glob);\n }\n\n return formatter.formatter(value, args, variable);\n}\n"],"names":[],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../src/variables/utils.ts"],"sourcesContent":["import { isEqual } from 'lodash';\nimport { VariableValue } from './types';\nimport { AdHocVariableFilter } from '@grafana/data';\nimport { sceneGraph } from '../core/sceneGraph';\nimport {
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../src/variables/utils.ts"],"sourcesContent":["import { isEqual } from 'lodash';\nimport { VariableValue } from './types';\nimport { AdHocVariableFilter } from '@grafana/data';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObject, SceneObjectState } from '../core/types';\nimport { DataQueryExtended, SceneQueryRunner } from '../querying/SceneQueryRunner';\nimport { DataSourceRef } from '@grafana/schema';\n\nexport function isVariableValueEqual(a: VariableValue | null | undefined, b: VariableValue | null | undefined) {\n if (a === b) {\n return true;\n }\n\n return isEqual(a, b);\n}\n\nexport function safeStringifyValue(value: unknown) {\n // Avoid circular references ignoring those references\n const getCircularReplacer = () => {\n const seen = new WeakSet();\n return (_: string, value: object | null) => {\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) {\n return;\n }\n seen.add(value);\n }\n return value;\n };\n };\n\n try {\n return JSON.stringify(value, getCircularReplacer());\n } catch (error) {\n console.error(error);\n }\n\n return '';\n}\n\nexport function renderPrometheusLabelFilters(filters: AdHocVariableFilter[]) {\n return filters.map((filter) => renderFilter(filter)).join(',');\n}\n\nfunction renderFilter(filter: AdHocVariableFilter) {\n let value = '';\n\n if (filter.operator === '=~' || filter.operator === '!~¨') {\n value = escapeLabelValueInRegexSelector(filter.value);\n } else {\n value = escapeLabelValueInExactSelector(filter.value);\n }\n\n return `${filter.key}${filter.operator}\"${value}\"`;\n}\n\n// based on the openmetrics-documentation, the 3 symbols we have to handle are:\n// - \\n ... the newline character\n// - \\ ... the backslash character\n// - \" ... the double-quote character\nexport function escapeLabelValueInExactSelector(labelValue: string): string {\n return labelValue.replace(/\\\\/g, '\\\\\\\\').replace(/\\n/g, '\\\\n').replace(/\"/g, '\\\\\"');\n}\n\nexport function escapeLabelValueInRegexSelector(labelValue: string): string {\n return escapeLabelValueInExactSelector(escapeLokiRegexp(labelValue));\n}\n\nexport function isRegexSelector(selector?: string) {\n if (selector && (selector.includes('=~') || selector.includes('!~'))) {\n return true;\n }\n return false;\n}\n\n// Loki regular-expressions use the RE2 syntax (https://github.com/google/re2/wiki/Syntax),\n// so every character that matches something in that list has to be escaped.\n// the list of meta characters is: *+?()|\\.[]{}^$\n// we make a javascript regular expression that matches those characters:\nconst RE2_METACHARACTERS = /[*+?()|\\\\.\\[\\]{}^$]/g;\nfunction escapeLokiRegexp(value: string): string {\n return value.replace(RE2_METACHARACTERS, '\\\\$&');\n}\n\n/**\n * Get all queries in the scene that have the same datasource as provided source object\n */\nexport function getQueriesForVariables(\n sourceObject: SceneObject<SceneObjectState & { datasource: DataSourceRef | null }>\n) {\n const runners = sceneGraph.findAllObjects(\n sourceObject.getRoot(),\n (o) => o instanceof SceneQueryRunner\n ) as SceneQueryRunner[];\n\n const applicableRunners = filterOutInactiveRunnerDuplicates(runners).filter((r) => {\n return r.state.datasource?.uid === sourceObject.state.datasource?.uid;\n });\n\n if (applicableRunners.length === 0) {\n return [];\n }\n\n const result: DataQueryExtended[] = [];\n applicableRunners.forEach((r) => {\n result.push(...r.state.queries);\n });\n\n return result;\n}\n\n// Filters out inactive runner duplicates, keeping only the ones that are currently active.\n// This is needed for scnearios whan a query runner is cloned and the original is not removed but de-activated.\n// Can happen i.e. when editing a panel in Grafana Core dashboards.\nfunction filterOutInactiveRunnerDuplicates(runners: SceneQueryRunner[]) {\n // Group items by key\n const groupedItems: { [key: string]: SceneQueryRunner[] } = {};\n\n for (const item of runners) {\n if (item.state.key) {\n if (!(item.state.key in groupedItems)) {\n groupedItems[item.state.key] = [];\n }\n groupedItems[item.state.key].push(item);\n }\n }\n\n // Filter out inactive items and concatenate active items\n return Object.values(groupedItems).flatMap((group) => {\n const activeItems = group.filter((item) => item.isActive);\n // Keep inactive items if there's only one item with the key\n if (activeItems.length === 0 && group.length === 1) {\n return group;\n }\n return activeItems;\n });\n}\n\nexport function escapeUrlPipeDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Replace the pipe due to using it as a filter separator\n return (value = /\\|/g[Symbol.replace](value, '__gfp__'));\n}\n\nexport function escapeUrlCommaDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Replace the comma due to using it as a value/label separator\n return /,/g[Symbol.replace](value, '__gfc__');\n}\n\nexport function unescapeUrlDelimiters(value: string | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n value = /__gfp__/g[Symbol.replace](value, '|');\n value = /__gfc__/g[Symbol.replace](value, ',');\n\n return value;\n}\n\nexport function toUrlCommaDelimitedString(key: string, label?: string): string {\n // Omit for identical key/label or when label is not set at all\n if (!label || key === label) {\n return escapeUrlCommaDelimiters(key);\n }\n\n return [key, label].map(escapeUrlCommaDelimiters).join(',');\n}\n"],"names":["value"],"mappings":"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"}
|