@grafana/scenes 6.52.5 → 6.52.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # v6.52.6 (Mon Jan 19 2026)
2
+
3
+ #### 🐛 Bug Fix
4
+
5
+ - Filtering recommendations: Add subs to filters and grouping changes [#1334](https://github.com/grafana/scenes/pull/1334) ([@mdvictor](https://github.com/mdvictor))
6
+
7
+ #### Authors: 1
8
+
9
+ - Victor Marin ([@mdvictor](https://github.com/mdvictor))
10
+
11
+ ---
12
+
1
13
  # v6.52.5 (Mon Jan 19 2026)
2
14
 
3
15
  #### 🐛 Bug Fix
@@ -26,6 +26,7 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
26
26
  this._fetchRecommendedDrilldowns();
27
27
  const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._adHocFilter);
28
28
  let scopesSubscription;
29
+ let adHocSubscription;
29
30
  if (scopesVariable instanceof ScopesVariable) {
30
31
  this._subs.add(
31
32
  scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {
@@ -40,8 +41,21 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
40
41
  })
41
42
  );
42
43
  }
44
+ this._subs.add(
45
+ adHocSubscription = this._adHocFilter.subscribeToState((newState, prevState) => {
46
+ if (newState.filters !== prevState.filters) {
47
+ const json2 = store.get(this._getStorageKey());
48
+ const storedFilters2 = json2 ? JSON.parse(json2) : [];
49
+ if (storedFilters2.length > 0) {
50
+ this._verifyRecentFiltersApplicability(storedFilters2);
51
+ }
52
+ this._fetchRecommendedDrilldowns();
53
+ }
54
+ })
55
+ );
43
56
  return () => {
44
57
  scopesSubscription == null ? void 0 : scopesSubscription.unsubscribe();
58
+ adHocSubscription == null ? void 0 : adHocSubscription.unsubscribe();
45
59
  };
46
60
  };
47
61
  this.addActivationHandler(this._activationHandler);
@@ -1 +1 @@
1
- {"version":3,"file":"AdHocFiltersRecommendations.js","sources":["../../../../../../../src/variables/adhoc/AdHocFiltersRecommendations.tsx"],"sourcesContent":["import React from 'react';\nimport {\n // @ts-expect-error (temporary till we update grafana/data)\n DrilldownsApplicability,\n store,\n} from '@grafana/data';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { getEnrichedDataRequest } from '../../querying/getEnrichedDataRequest';\nimport { getQueriesForVariables } from '../utils';\nimport { getDataSource } from '../../utils/getDataSource';\nimport { DrilldownRecommendations, DrilldownPill } from '../components/DrilldownRecommendations';\nimport { ScopesVariable } from '../variants/ScopesVariable';\nimport { SCOPES_VARIABLE_NAME } from '../constants';\nimport { AdHocFilterWithLabels, AdHocFiltersVariable } from './AdHocFiltersVariable';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObjectState } from '../../core/types';\nimport { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject';\nimport { Unsubscribable } from 'rxjs';\n\nexport const MAX_RECENT_DRILLDOWNS = 3;\nexport const MAX_STORED_RECENT_DRILLDOWNS = 10;\n\nexport const getRecentFiltersKey = (datasourceUid: string | undefined) =>\n `grafana.filters.recent.${datasourceUid ?? 'default'}`;\n\nexport interface AdHocFiltersRecommendationsState extends SceneObjectState {\n recentFilters?: AdHocFilterWithLabels[];\n recommendedFilters?: AdHocFilterWithLabels[];\n}\n\nexport class AdHocFiltersRecommendations extends SceneObjectBase<AdHocFiltersRecommendationsState> {\n static Component = AdHocFiltersRecommendationsRenderer;\n\n public constructor(state: Partial<AdHocFiltersRecommendationsState> = {}) {\n super(state);\n\n this.addActivationHandler(this._activationHandler);\n }\n\n public get _adHocFilter(): AdHocFiltersVariable {\n if (!(this.parent instanceof AdHocFiltersVariable)) {\n throw new Error('AdHocFiltersRecommendations must be a child of AdHocFiltersVariable');\n }\n\n return this.parent;\n }\n\n private get _scopedVars() {\n return { __sceneObject: wrapInSafeSerializableSceneObject(this._adHocFilter) };\n }\n\n private _activationHandler = () => {\n const json = store.get(this._getStorageKey());\n const storedFilters = json ? JSON.parse(json) : [];\n\n if (storedFilters.length > 0) {\n this._verifyRecentFiltersApplicability(storedFilters);\n } else {\n this.setState({ recentFilters: [] });\n }\n\n this._fetchRecommendedDrilldowns();\n\n // Set up subscription to scopes variable\n const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._adHocFilter);\n let scopesSubscription: Unsubscribable | undefined;\n\n if (scopesVariable instanceof ScopesVariable) {\n this._subs.add(\n (scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {\n if (newState.scopes !== prevState.scopes) {\n const json = store.get(this._getStorageKey());\n const storedFilters = json ? JSON.parse(json) : [];\n\n if (storedFilters.length > 0) {\n this._verifyRecentFiltersApplicability(storedFilters);\n }\n\n this._fetchRecommendedDrilldowns();\n }\n }))\n );\n }\n\n return () => {\n scopesSubscription?.unsubscribe();\n };\n };\n\n private _getStorageKey(): string {\n return getRecentFiltersKey(this._adHocFilter.state.datasource?.uid);\n }\n\n private async _fetchRecommendedDrilldowns() {\n const adhoc = this._adHocFilter;\n const ds = await getDataSource(adhoc.state.datasource, this._scopedVars);\n\n // @ts-expect-error (temporary till we update grafana/data)\n if (!ds || !ds.getRecommendedDrilldowns) {\n return;\n }\n\n const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : undefined;\n const timeRange = sceneGraph.getTimeRange(adhoc).state.value;\n const scopes = sceneGraph.getScopes(adhoc);\n const filters = [...(adhoc.state.originFilters ?? []), ...adhoc.state.filters];\n\n const enrichedRequest = getEnrichedDataRequest(adhoc);\n const dashboardUid = enrichedRequest?.dashboardUID;\n\n try {\n // @ts-expect-error (temporary till we update grafana/data)\n const recommendedDrilldowns = await ds.getRecommendedDrilldowns({\n timeRange,\n dashboardUid,\n queries: queries ?? [],\n filters,\n scopes,\n });\n\n if (recommendedDrilldowns?.filters) {\n this.setState({ recommendedFilters: recommendedDrilldowns.filters });\n }\n } catch (error) {\n console.error('Failed to fetch recommended drilldowns:', error);\n }\n }\n\n private async _verifyRecentFiltersApplicability(storedFilters: AdHocFilterWithLabels[]) {\n const adhoc = this._adHocFilter;\n const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : undefined;\n const response = await adhoc.getFiltersApplicabilityForQueries(storedFilters, queries ?? []);\n\n if (!response) {\n this.setState({ recentFilters: storedFilters.slice(-MAX_RECENT_DRILLDOWNS) });\n return;\n }\n\n const applicabilityMap = new Map<string, boolean>();\n response.forEach((item: DrilldownsApplicability) => {\n applicabilityMap.set(item.key, item.applicable !== false);\n });\n\n const applicableFilters = storedFilters\n .filter((f) => {\n const isApplicable = applicabilityMap.get(f.key);\n return isApplicable === undefined || isApplicable === true;\n })\n .slice(-MAX_RECENT_DRILLDOWNS);\n\n this.setState({ recentFilters: applicableFilters });\n }\n\n /**\n * Stores a recent filter in localStorage and updates state.\n * Should be called by the parent variable when a filter is added/updated.\n */\n public storeRecentFilter(filter: AdHocFilterWithLabels) {\n const key = this._getStorageKey();\n const storedFilters = store.get(key);\n const allRecentFilters = storedFilters ? JSON.parse(storedFilters) : [];\n\n const updatedStoredFilters = [...allRecentFilters, filter].slice(-MAX_STORED_RECENT_DRILLDOWNS);\n store.set(key, JSON.stringify(updatedStoredFilters));\n\n const adhoc = this._adHocFilter;\n const existingFilter = adhoc.state.filters.find((f) => f.key === filter.key && !Boolean(f.nonApplicable));\n if (existingFilter && !Boolean(existingFilter.nonApplicable)) {\n this.setState({ recentFilters: updatedStoredFilters.slice(-MAX_RECENT_DRILLDOWNS) });\n }\n }\n\n public addFilterToParent(filter: AdHocFilterWithLabels) {\n this._adHocFilter.updateFilters([...this._adHocFilter.state.filters, filter]);\n }\n}\n\nfunction AdHocFiltersRecommendationsRenderer({ model }: SceneComponentProps<AdHocFiltersRecommendations>) {\n const { recentFilters, recommendedFilters } = model.useState();\n const { filters } = model._adHocFilter.useState();\n\n const recentDrilldowns: DrilldownPill[] | undefined = recentFilters?.map((filter) => ({\n label: `${filter.key} ${filter.operator} ${filter.value}`,\n onClick: () => {\n const exists = filters.some((f) => f.key === filter.key && f.value === filter.value);\n if (!exists) {\n model.addFilterToParent(filter);\n }\n },\n }));\n\n const recommendedDrilldowns: DrilldownPill[] | undefined = recommendedFilters?.map((filter) => ({\n label: `${filter.key} ${filter.operator} ${filter.value}`,\n onClick: () => {\n const exists = filters.some((f) => f.key === filter.key && f.value === filter.value);\n if (!exists) {\n model.addFilterToParent(filter);\n }\n },\n }));\n\n return <DrilldownRecommendations recentDrilldowns={recentDrilldowns} recommendedDrilldowns={recommendedDrilldowns} />;\n}\n"],"names":["json","storedFilters"],"mappings":"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"}
1
+ {"version":3,"file":"AdHocFiltersRecommendations.js","sources":["../../../../../../../src/variables/adhoc/AdHocFiltersRecommendations.tsx"],"sourcesContent":["import React from 'react';\nimport {\n // @ts-expect-error (temporary till we update grafana/data)\n DrilldownsApplicability,\n store,\n} from '@grafana/data';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { getEnrichedDataRequest } from '../../querying/getEnrichedDataRequest';\nimport { getQueriesForVariables } from '../utils';\nimport { getDataSource } from '../../utils/getDataSource';\nimport { DrilldownRecommendations, DrilldownPill } from '../components/DrilldownRecommendations';\nimport { ScopesVariable } from '../variants/ScopesVariable';\nimport { SCOPES_VARIABLE_NAME } from '../constants';\nimport { AdHocFilterWithLabels, AdHocFiltersVariable } from './AdHocFiltersVariable';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObjectState } from '../../core/types';\nimport { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject';\nimport { Unsubscribable } from 'rxjs';\n\nexport const MAX_RECENT_DRILLDOWNS = 3;\nexport const MAX_STORED_RECENT_DRILLDOWNS = 10;\n\nexport const getRecentFiltersKey = (datasourceUid: string | undefined) =>\n `grafana.filters.recent.${datasourceUid ?? 'default'}`;\n\nexport interface AdHocFiltersRecommendationsState extends SceneObjectState {\n recentFilters?: AdHocFilterWithLabels[];\n recommendedFilters?: AdHocFilterWithLabels[];\n}\n\nexport class AdHocFiltersRecommendations extends SceneObjectBase<AdHocFiltersRecommendationsState> {\n static Component = AdHocFiltersRecommendationsRenderer;\n\n public constructor(state: Partial<AdHocFiltersRecommendationsState> = {}) {\n super(state);\n\n this.addActivationHandler(this._activationHandler);\n }\n\n public get _adHocFilter(): AdHocFiltersVariable {\n if (!(this.parent instanceof AdHocFiltersVariable)) {\n throw new Error('AdHocFiltersRecommendations must be a child of AdHocFiltersVariable');\n }\n\n return this.parent;\n }\n\n private get _scopedVars() {\n return { __sceneObject: wrapInSafeSerializableSceneObject(this._adHocFilter) };\n }\n\n private _activationHandler = () => {\n const json = store.get(this._getStorageKey());\n const storedFilters = json ? JSON.parse(json) : [];\n\n if (storedFilters.length > 0) {\n this._verifyRecentFiltersApplicability(storedFilters);\n } else {\n this.setState({ recentFilters: [] });\n }\n\n this._fetchRecommendedDrilldowns();\n\n // Set up subscription to scopes variable\n const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._adHocFilter);\n let scopesSubscription: Unsubscribable | undefined;\n let adHocSubscription: Unsubscribable | undefined;\n\n if (scopesVariable instanceof ScopesVariable) {\n this._subs.add(\n (scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {\n if (newState.scopes !== prevState.scopes) {\n const json = store.get(this._getStorageKey());\n const storedFilters = json ? JSON.parse(json) : [];\n\n if (storedFilters.length > 0) {\n this._verifyRecentFiltersApplicability(storedFilters);\n }\n\n this._fetchRecommendedDrilldowns();\n }\n }))\n );\n }\n\n this._subs.add(\n (adHocSubscription = this._adHocFilter.subscribeToState((newState, prevState) => {\n if (newState.filters !== prevState.filters) {\n const json = store.get(this._getStorageKey());\n const storedFilters = json ? JSON.parse(json) : [];\n\n if (storedFilters.length > 0) {\n this._verifyRecentFiltersApplicability(storedFilters);\n }\n\n this._fetchRecommendedDrilldowns();\n }\n }))\n );\n\n return () => {\n scopesSubscription?.unsubscribe();\n adHocSubscription?.unsubscribe();\n };\n };\n\n private _getStorageKey(): string {\n return getRecentFiltersKey(this._adHocFilter.state.datasource?.uid);\n }\n\n private async _fetchRecommendedDrilldowns() {\n const adhoc = this._adHocFilter;\n const ds = await getDataSource(adhoc.state.datasource, this._scopedVars);\n\n // @ts-expect-error (temporary till we update grafana/data)\n if (!ds || !ds.getRecommendedDrilldowns) {\n return;\n }\n\n const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : undefined;\n const timeRange = sceneGraph.getTimeRange(adhoc).state.value;\n const scopes = sceneGraph.getScopes(adhoc);\n const filters = [...(adhoc.state.originFilters ?? []), ...adhoc.state.filters];\n\n const enrichedRequest = getEnrichedDataRequest(adhoc);\n const dashboardUid = enrichedRequest?.dashboardUID;\n\n try {\n // @ts-expect-error (temporary till we update grafana/data)\n const recommendedDrilldowns = await ds.getRecommendedDrilldowns({\n timeRange,\n dashboardUid,\n queries: queries ?? [],\n filters,\n scopes,\n });\n\n if (recommendedDrilldowns?.filters) {\n this.setState({ recommendedFilters: recommendedDrilldowns.filters });\n }\n } catch (error) {\n console.error('Failed to fetch recommended drilldowns:', error);\n }\n }\n\n private async _verifyRecentFiltersApplicability(storedFilters: AdHocFilterWithLabels[]) {\n const adhoc = this._adHocFilter;\n const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : undefined;\n const response = await adhoc.getFiltersApplicabilityForQueries(storedFilters, queries ?? []);\n\n if (!response) {\n this.setState({ recentFilters: storedFilters.slice(-MAX_RECENT_DRILLDOWNS) });\n return;\n }\n\n const applicabilityMap = new Map<string, boolean>();\n response.forEach((item: DrilldownsApplicability) => {\n applicabilityMap.set(item.key, item.applicable !== false);\n });\n\n const applicableFilters = storedFilters\n .filter((f) => {\n const isApplicable = applicabilityMap.get(f.key);\n return isApplicable === undefined || isApplicable === true;\n })\n .slice(-MAX_RECENT_DRILLDOWNS);\n\n this.setState({ recentFilters: applicableFilters });\n }\n\n /**\n * Stores a recent filter in localStorage and updates state.\n * Should be called by the parent variable when a filter is added/updated.\n */\n public storeRecentFilter(filter: AdHocFilterWithLabels) {\n const key = this._getStorageKey();\n const storedFilters = store.get(key);\n const allRecentFilters = storedFilters ? JSON.parse(storedFilters) : [];\n\n const updatedStoredFilters = [...allRecentFilters, filter].slice(-MAX_STORED_RECENT_DRILLDOWNS);\n store.set(key, JSON.stringify(updatedStoredFilters));\n\n const adhoc = this._adHocFilter;\n const existingFilter = adhoc.state.filters.find((f) => f.key === filter.key && !Boolean(f.nonApplicable));\n if (existingFilter && !Boolean(existingFilter.nonApplicable)) {\n this.setState({ recentFilters: updatedStoredFilters.slice(-MAX_RECENT_DRILLDOWNS) });\n }\n }\n\n public addFilterToParent(filter: AdHocFilterWithLabels) {\n this._adHocFilter.updateFilters([...this._adHocFilter.state.filters, filter]);\n }\n}\n\nfunction AdHocFiltersRecommendationsRenderer({ model }: SceneComponentProps<AdHocFiltersRecommendations>) {\n const { recentFilters, recommendedFilters } = model.useState();\n const { filters } = model._adHocFilter.useState();\n\n const recentDrilldowns: DrilldownPill[] | undefined = recentFilters?.map((filter) => ({\n label: `${filter.key} ${filter.operator} ${filter.value}`,\n onClick: () => {\n const exists = filters.some((f) => f.key === filter.key && f.value === filter.value);\n if (!exists) {\n model.addFilterToParent(filter);\n }\n },\n }));\n\n const recommendedDrilldowns: DrilldownPill[] | undefined = recommendedFilters?.map((filter) => ({\n label: `${filter.key} ${filter.operator} ${filter.value}`,\n onClick: () => {\n const exists = filters.some((f) => f.key === filter.key && f.value === filter.value);\n if (!exists) {\n model.addFilterToParent(filter);\n }\n },\n }));\n\n return <DrilldownRecommendations recentDrilldowns={recentDrilldowns} recommendedDrilldowns={recommendedDrilldowns} />;\n}\n"],"names":["json","storedFilters"],"mappings":"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"}
@@ -28,6 +28,7 @@ class GroupByRecommendations extends SceneObjectBase {
28
28
  this._fetchRecommendedDrilldowns();
29
29
  const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._groupBy);
30
30
  let scopesSubscription;
31
+ let groupBySubscription;
31
32
  if (scopesVariable instanceof ScopesVariable) {
32
33
  this._subs.add(
33
34
  scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {
@@ -42,8 +43,21 @@ class GroupByRecommendations extends SceneObjectBase {
42
43
  })
43
44
  );
44
45
  }
46
+ this._subs.add(
47
+ groupBySubscription = this._groupBy.subscribeToState((newState, prevState) => {
48
+ if (newState.value !== prevState.value) {
49
+ const json2 = store.get(this._getStorageKey());
50
+ const storedGroupings2 = json2 ? JSON.parse(json2) : [];
51
+ if (storedGroupings2.length > 0) {
52
+ this._verifyRecentGroupingsApplicability(storedGroupings2);
53
+ }
54
+ this._fetchRecommendedDrilldowns();
55
+ }
56
+ })
57
+ );
45
58
  return () => {
46
59
  scopesSubscription == null ? void 0 : scopesSubscription.unsubscribe();
60
+ groupBySubscription == null ? void 0 : groupBySubscription.unsubscribe();
47
61
  };
48
62
  };
49
63
  this.addActivationHandler(this._activationHandler);
@@ -1 +1 @@
1
- {"version":3,"file":"GroupByRecommendations.js","sources":["../../../../../../../src/variables/groupby/GroupByRecommendations.tsx"],"sourcesContent":["import React from 'react';\nimport {\n // @ts-expect-error (temporary till we update grafana/data)\n DrilldownsApplicability,\n SelectableValue,\n store,\n} from '@grafana/data';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { getEnrichedDataRequest } from '../../querying/getEnrichedDataRequest';\nimport { getQueriesForVariables } from '../utils';\nimport { getDataSource } from '../../utils/getDataSource';\nimport { DrilldownRecommendations, DrilldownPill } from '../components/DrilldownRecommendations';\nimport { ScopesVariable } from '../variants/ScopesVariable';\nimport { SCOPES_VARIABLE_NAME } from '../constants';\nimport { GroupByVariable } from './GroupByVariable';\nimport { MAX_RECENT_DRILLDOWNS, MAX_STORED_RECENT_DRILLDOWNS } from '../adhoc/AdHocFiltersRecommendations';\nimport { VariableValueSingle } from '../types';\nimport { isArray } from 'lodash';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObjectState } from '../../core/types';\nimport { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject';\nimport { Unsubscribable } from 'rxjs';\n\nexport const getRecentGroupingKey = (datasourceUid: string | undefined) =>\n `grafana.grouping.recent.${datasourceUid ?? 'default'}`;\n\nexport interface GroupByRecommendationsState extends SceneObjectState {\n recentGrouping?: Array<SelectableValue<VariableValueSingle>>;\n recommendedGrouping?: Array<SelectableValue<VariableValueSingle>>;\n}\n\nexport class GroupByRecommendations extends SceneObjectBase<GroupByRecommendationsState> {\n static Component = GroupByRecommendationsRenderer;\n\n public constructor(state: Partial<GroupByRecommendationsState> = {}) {\n super(state);\n\n this.addActivationHandler(this._activationHandler);\n }\n\n private get _groupBy(): GroupByVariable {\n if (!(this.parent instanceof GroupByVariable)) {\n throw new Error('GroupByRecommendations must be a child of GroupByVariable');\n }\n\n return this.parent;\n }\n\n private get _scopedVars() {\n return { __sceneObject: wrapInSafeSerializableSceneObject(this._groupBy) };\n }\n\n private _activationHandler = () => {\n const json = store.get(this._getStorageKey());\n const storedGroupings = json ? JSON.parse(json) : [];\n\n if (storedGroupings.length > 0) {\n this._verifyRecentGroupingsApplicability(storedGroupings);\n } else {\n this.setState({ recentGrouping: [] });\n }\n\n this._fetchRecommendedDrilldowns();\n\n // Subscribe to scopes variable changes\n const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._groupBy);\n let scopesSubscription: Unsubscribable | undefined;\n\n if (scopesVariable instanceof ScopesVariable) {\n this._subs.add(\n (scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {\n if (newState.scopes !== prevState.scopes) {\n const json = store.get(this._getStorageKey());\n const storedGroupings = json ? JSON.parse(json) : [];\n\n if (storedGroupings.length > 0) {\n this._verifyRecentGroupingsApplicability(storedGroupings);\n }\n\n this._fetchRecommendedDrilldowns();\n }\n }))\n );\n }\n\n return () => {\n scopesSubscription?.unsubscribe();\n };\n };\n\n private _getStorageKey(): string {\n return getRecentGroupingKey(this._groupBy.state.datasource?.uid);\n }\n\n private async _fetchRecommendedDrilldowns() {\n const ds = await getDataSource(this._groupBy.state.datasource, this._scopedVars);\n\n // @ts-expect-error (temporary till we update grafana/data)\n if (!ds || !ds.getRecommendedDrilldowns) {\n return;\n }\n\n const queries = getQueriesForVariables(this._groupBy);\n const timeRange = sceneGraph.getTimeRange(this._groupBy).state.value;\n const scopes = sceneGraph.getScopes(this._groupBy);\n const groupByKeys = Array.isArray(this._groupBy.state.value)\n ? this._groupBy.state.value.map((v) => String(v))\n : this._groupBy.state.value\n ? [String(this._groupBy.state.value)]\n : [];\n\n const enrichedRequest = getEnrichedDataRequest(this._groupBy);\n const dashboardUid = enrichedRequest?.dashboardUID;\n\n try {\n // @ts-expect-error (temporary till we update grafana/data)\n const recommendedDrilldowns = await ds.getRecommendedDrilldowns({\n timeRange,\n dashboardUid,\n queries,\n groupByKeys,\n scopes,\n });\n\n if (recommendedDrilldowns?.groupByKeys) {\n this.setState({\n recommendedGrouping: recommendedDrilldowns.groupByKeys.map((key: string) => ({ value: key, text: key })),\n });\n }\n } catch (error) {\n console.error('Failed to fetch recommended drilldowns:', error);\n }\n }\n\n private async _verifyRecentGroupingsApplicability(storedGroupings: Array<SelectableValue<VariableValueSingle>>) {\n const queries = getQueriesForVariables(this._groupBy);\n const keys = storedGroupings.map((g) => String(g.value));\n const response = await this._groupBy.getGroupByApplicabilityForQueries(keys, queries);\n\n if (!response) {\n this.setState({ recentGrouping: storedGroupings.slice(-MAX_RECENT_DRILLDOWNS) });\n return;\n }\n\n const applicabilityMap = new Map<string, boolean>();\n response.forEach((item: DrilldownsApplicability) => {\n applicabilityMap.set(item.key, item.applicable !== false);\n });\n\n const applicableGroupings = storedGroupings\n .filter((g) => {\n const isApplicable = applicabilityMap.get(String(g.value));\n return isApplicable === undefined || isApplicable === true;\n })\n .slice(-MAX_RECENT_DRILLDOWNS);\n\n this.setState({ recentGrouping: applicableGroupings });\n }\n\n /**\n * Stores recent groupings in localStorage and updates state.\n * Should be called by the parent variable when a grouping is added/updated.\n */\n public storeRecentGrouping(applicableValues: string[]) {\n if (applicableValues.length === 0) {\n return;\n }\n\n const key = this._getStorageKey();\n const storedGroupings = store.get(key);\n const allRecentGroupings: Array<SelectableValue<VariableValueSingle>> = storedGroupings\n ? JSON.parse(storedGroupings)\n : [];\n\n const existingWithoutApplicableValues = allRecentGroupings.filter(\n (grouping) => !applicableValues.includes(String(grouping.value))\n );\n const updatedStoredGroupings = [\n ...existingWithoutApplicableValues,\n ...applicableValues.map((value) => ({ value, text: value })),\n ];\n\n const limitedStoredGroupings = updatedStoredGroupings.slice(-MAX_STORED_RECENT_DRILLDOWNS);\n\n store.set(key, JSON.stringify(limitedStoredGroupings));\n\n this.setState({ recentGrouping: limitedStoredGroupings.slice(-MAX_RECENT_DRILLDOWNS) });\n }\n\n /**\n * Add a grouping value to the parent variable\n */\n public addValueToParent(newValue: VariableValueSingle, newText?: string) {\n const value = isArray(this._groupBy.state.value) ? this._groupBy.state.value : [this._groupBy.state.value];\n const text = isArray(this._groupBy.state.text)\n ? this._groupBy.state.text.map(String)\n : [String(this._groupBy.state.text)];\n\n // Check if value already exists\n if (value.includes(newValue)) {\n return;\n }\n\n this._groupBy.changeValueTo(\n [...value.filter((v) => v !== ''), newValue],\n [...text.filter((t) => t !== ''), newText ?? String(newValue)],\n true\n );\n }\n}\n\nfunction GroupByRecommendationsRenderer({ model }: SceneComponentProps<GroupByRecommendations>) {\n const { recentGrouping, recommendedGrouping } = model.useState();\n\n const recentDrilldowns: DrilldownPill[] | undefined = recentGrouping?.map((groupBy) => ({\n label: `${groupBy.value}`,\n onClick: () => {\n model.addValueToParent(groupBy.value!, groupBy.text ?? String(groupBy.value));\n },\n }));\n\n const recommendedDrilldowns: DrilldownPill[] | undefined = recommendedGrouping?.map((groupBy) => ({\n label: `${groupBy.value}`,\n onClick: () => {\n model.addValueToParent(groupBy.value!, groupBy.text ?? String(groupBy.value));\n },\n }));\n\n return <DrilldownRecommendations recentDrilldowns={recentDrilldowns} recommendedDrilldowns={recommendedDrilldowns} />;\n}\n"],"names":["json","storedGroupings"],"mappings":"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"}
1
+ {"version":3,"file":"GroupByRecommendations.js","sources":["../../../../../../../src/variables/groupby/GroupByRecommendations.tsx"],"sourcesContent":["import React from 'react';\nimport {\n // @ts-expect-error (temporary till we update grafana/data)\n DrilldownsApplicability,\n SelectableValue,\n store,\n} from '@grafana/data';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { getEnrichedDataRequest } from '../../querying/getEnrichedDataRequest';\nimport { getQueriesForVariables } from '../utils';\nimport { getDataSource } from '../../utils/getDataSource';\nimport { DrilldownRecommendations, DrilldownPill } from '../components/DrilldownRecommendations';\nimport { ScopesVariable } from '../variants/ScopesVariable';\nimport { SCOPES_VARIABLE_NAME } from '../constants';\nimport { GroupByVariable } from './GroupByVariable';\nimport { MAX_RECENT_DRILLDOWNS, MAX_STORED_RECENT_DRILLDOWNS } from '../adhoc/AdHocFiltersRecommendations';\nimport { VariableValueSingle } from '../types';\nimport { isArray } from 'lodash';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObjectState } from '../../core/types';\nimport { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject';\nimport { Unsubscribable } from 'rxjs';\n\nexport const getRecentGroupingKey = (datasourceUid: string | undefined) =>\n `grafana.grouping.recent.${datasourceUid ?? 'default'}`;\n\nexport interface GroupByRecommendationsState extends SceneObjectState {\n recentGrouping?: Array<SelectableValue<VariableValueSingle>>;\n recommendedGrouping?: Array<SelectableValue<VariableValueSingle>>;\n}\n\nexport class GroupByRecommendations extends SceneObjectBase<GroupByRecommendationsState> {\n static Component = GroupByRecommendationsRenderer;\n\n public constructor(state: Partial<GroupByRecommendationsState> = {}) {\n super(state);\n\n this.addActivationHandler(this._activationHandler);\n }\n\n private get _groupBy(): GroupByVariable {\n if (!(this.parent instanceof GroupByVariable)) {\n throw new Error('GroupByRecommendations must be a child of GroupByVariable');\n }\n\n return this.parent;\n }\n\n private get _scopedVars() {\n return { __sceneObject: wrapInSafeSerializableSceneObject(this._groupBy) };\n }\n\n private _activationHandler = () => {\n const json = store.get(this._getStorageKey());\n const storedGroupings = json ? JSON.parse(json) : [];\n\n if (storedGroupings.length > 0) {\n this._verifyRecentGroupingsApplicability(storedGroupings);\n } else {\n this.setState({ recentGrouping: [] });\n }\n\n this._fetchRecommendedDrilldowns();\n\n // Subscribe to scopes variable changes\n const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._groupBy);\n let scopesSubscription: Unsubscribable | undefined;\n let groupBySubscription: Unsubscribable | undefined;\n\n if (scopesVariable instanceof ScopesVariable) {\n this._subs.add(\n (scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {\n if (newState.scopes !== prevState.scopes) {\n const json = store.get(this._getStorageKey());\n const storedGroupings = json ? JSON.parse(json) : [];\n\n if (storedGroupings.length > 0) {\n this._verifyRecentGroupingsApplicability(storedGroupings);\n }\n\n this._fetchRecommendedDrilldowns();\n }\n }))\n );\n }\n\n this._subs.add(\n (groupBySubscription = this._groupBy.subscribeToState((newState, prevState) => {\n if (newState.value !== prevState.value) {\n const json = store.get(this._getStorageKey());\n const storedGroupings = json ? JSON.parse(json) : [];\n\n if (storedGroupings.length > 0) {\n this._verifyRecentGroupingsApplicability(storedGroupings);\n }\n\n this._fetchRecommendedDrilldowns();\n }\n }))\n );\n\n return () => {\n scopesSubscription?.unsubscribe();\n groupBySubscription?.unsubscribe();\n };\n };\n\n private _getStorageKey(): string {\n return getRecentGroupingKey(this._groupBy.state.datasource?.uid);\n }\n\n private async _fetchRecommendedDrilldowns() {\n const ds = await getDataSource(this._groupBy.state.datasource, this._scopedVars);\n\n // @ts-expect-error (temporary till we update grafana/data)\n if (!ds || !ds.getRecommendedDrilldowns) {\n return;\n }\n\n const queries = getQueriesForVariables(this._groupBy);\n const timeRange = sceneGraph.getTimeRange(this._groupBy).state.value;\n const scopes = sceneGraph.getScopes(this._groupBy);\n const groupByKeys = Array.isArray(this._groupBy.state.value)\n ? this._groupBy.state.value.map((v) => String(v))\n : this._groupBy.state.value\n ? [String(this._groupBy.state.value)]\n : [];\n\n const enrichedRequest = getEnrichedDataRequest(this._groupBy);\n const dashboardUid = enrichedRequest?.dashboardUID;\n\n try {\n // @ts-expect-error (temporary till we update grafana/data)\n const recommendedDrilldowns = await ds.getRecommendedDrilldowns({\n timeRange,\n dashboardUid,\n queries,\n groupByKeys,\n scopes,\n });\n\n if (recommendedDrilldowns?.groupByKeys) {\n this.setState({\n recommendedGrouping: recommendedDrilldowns.groupByKeys.map((key: string) => ({ value: key, text: key })),\n });\n }\n } catch (error) {\n console.error('Failed to fetch recommended drilldowns:', error);\n }\n }\n\n private async _verifyRecentGroupingsApplicability(storedGroupings: Array<SelectableValue<VariableValueSingle>>) {\n const queries = getQueriesForVariables(this._groupBy);\n const keys = storedGroupings.map((g) => String(g.value));\n const response = await this._groupBy.getGroupByApplicabilityForQueries(keys, queries);\n\n if (!response) {\n this.setState({ recentGrouping: storedGroupings.slice(-MAX_RECENT_DRILLDOWNS) });\n return;\n }\n\n const applicabilityMap = new Map<string, boolean>();\n response.forEach((item: DrilldownsApplicability) => {\n applicabilityMap.set(item.key, item.applicable !== false);\n });\n\n const applicableGroupings = storedGroupings\n .filter((g) => {\n const isApplicable = applicabilityMap.get(String(g.value));\n return isApplicable === undefined || isApplicable === true;\n })\n .slice(-MAX_RECENT_DRILLDOWNS);\n\n this.setState({ recentGrouping: applicableGroupings });\n }\n\n /**\n * Stores recent groupings in localStorage and updates state.\n * Should be called by the parent variable when a grouping is added/updated.\n */\n public storeRecentGrouping(applicableValues: string[]) {\n if (applicableValues.length === 0) {\n return;\n }\n\n const key = this._getStorageKey();\n const storedGroupings = store.get(key);\n const allRecentGroupings: Array<SelectableValue<VariableValueSingle>> = storedGroupings\n ? JSON.parse(storedGroupings)\n : [];\n\n const existingWithoutApplicableValues = allRecentGroupings.filter(\n (grouping) => !applicableValues.includes(String(grouping.value))\n );\n const updatedStoredGroupings = [\n ...existingWithoutApplicableValues,\n ...applicableValues.map((value) => ({ value, text: value })),\n ];\n\n const limitedStoredGroupings = updatedStoredGroupings.slice(-MAX_STORED_RECENT_DRILLDOWNS);\n\n store.set(key, JSON.stringify(limitedStoredGroupings));\n\n this.setState({ recentGrouping: limitedStoredGroupings.slice(-MAX_RECENT_DRILLDOWNS) });\n }\n\n /**\n * Add a grouping value to the parent variable\n */\n public addValueToParent(newValue: VariableValueSingle, newText?: string) {\n const value = isArray(this._groupBy.state.value) ? this._groupBy.state.value : [this._groupBy.state.value];\n const text = isArray(this._groupBy.state.text)\n ? this._groupBy.state.text.map(String)\n : [String(this._groupBy.state.text)];\n\n // Check if value already exists\n if (value.includes(newValue)) {\n return;\n }\n\n this._groupBy.changeValueTo(\n [...value.filter((v) => v !== ''), newValue],\n [...text.filter((t) => t !== ''), newText ?? String(newValue)],\n true\n );\n }\n}\n\nfunction GroupByRecommendationsRenderer({ model }: SceneComponentProps<GroupByRecommendations>) {\n const { recentGrouping, recommendedGrouping } = model.useState();\n\n const recentDrilldowns: DrilldownPill[] | undefined = recentGrouping?.map((groupBy) => ({\n label: `${groupBy.value}`,\n onClick: () => {\n model.addValueToParent(groupBy.value!, groupBy.text ?? String(groupBy.value));\n },\n }));\n\n const recommendedDrilldowns: DrilldownPill[] | undefined = recommendedGrouping?.map((groupBy) => ({\n label: `${groupBy.value}`,\n onClick: () => {\n model.addValueToParent(groupBy.value!, groupBy.text ?? String(groupBy.value));\n },\n }));\n\n return <DrilldownRecommendations recentDrilldowns={recentDrilldowns} recommendedDrilldowns={recommendedDrilldowns} />;\n}\n"],"names":["json","storedGroupings"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -6677,6 +6677,7 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
6677
6677
  this._fetchRecommendedDrilldowns();
6678
6678
  const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._adHocFilter);
6679
6679
  let scopesSubscription;
6680
+ let adHocSubscription;
6680
6681
  if (scopesVariable instanceof ScopesVariable) {
6681
6682
  this._subs.add(
6682
6683
  scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {
@@ -6691,8 +6692,21 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
6691
6692
  })
6692
6693
  );
6693
6694
  }
6695
+ this._subs.add(
6696
+ adHocSubscription = this._adHocFilter.subscribeToState((newState, prevState) => {
6697
+ if (newState.filters !== prevState.filters) {
6698
+ const json2 = data.store.get(this._getStorageKey());
6699
+ const storedFilters2 = json2 ? JSON.parse(json2) : [];
6700
+ if (storedFilters2.length > 0) {
6701
+ this._verifyRecentFiltersApplicability(storedFilters2);
6702
+ }
6703
+ this._fetchRecommendedDrilldowns();
6704
+ }
6705
+ })
6706
+ );
6694
6707
  return () => {
6695
6708
  scopesSubscription == null ? void 0 : scopesSubscription.unsubscribe();
6709
+ adHocSubscription == null ? void 0 : adHocSubscription.unsubscribe();
6696
6710
  };
6697
6711
  };
6698
6712
  this.addActivationHandler(this._activationHandler);
@@ -6816,6 +6830,7 @@ class GroupByRecommendations extends SceneObjectBase {
6816
6830
  this._fetchRecommendedDrilldowns();
6817
6831
  const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._groupBy);
6818
6832
  let scopesSubscription;
6833
+ let groupBySubscription;
6819
6834
  if (scopesVariable instanceof ScopesVariable) {
6820
6835
  this._subs.add(
6821
6836
  scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {
@@ -6830,8 +6845,21 @@ class GroupByRecommendations extends SceneObjectBase {
6830
6845
  })
6831
6846
  );
6832
6847
  }
6848
+ this._subs.add(
6849
+ groupBySubscription = this._groupBy.subscribeToState((newState, prevState) => {
6850
+ if (newState.value !== prevState.value) {
6851
+ const json2 = data.store.get(this._getStorageKey());
6852
+ const storedGroupings2 = json2 ? JSON.parse(json2) : [];
6853
+ if (storedGroupings2.length > 0) {
6854
+ this._verifyRecentGroupingsApplicability(storedGroupings2);
6855
+ }
6856
+ this._fetchRecommendedDrilldowns();
6857
+ }
6858
+ })
6859
+ );
6833
6860
  return () => {
6834
6861
  scopesSubscription == null ? void 0 : scopesSubscription.unsubscribe();
6862
+ groupBySubscription == null ? void 0 : groupBySubscription.unsubscribe();
6835
6863
  };
6836
6864
  };
6837
6865
  this.addActivationHandler(this._activationHandler);