@grafana/scenes 6.50.0--canary.1312.20235582466.0 → 6.50.0--canary.1312.20242044820.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,29 +3,10 @@ import { useStyles2, Icon } from '@grafana/ui';
3
3
  import React, { memo, useRef } from 'react';
4
4
  import { AdHocFilterPill } from './AdHocFilterPill.js';
5
5
  import { AdHocFiltersAlwaysWipCombobox } from './AdHocFiltersAlwaysWipCombobox.js';
6
- import { DrilldownRecommendations } from '../../components/DrilldownRecommendations.js';
7
6
 
8
7
  const AdHocFiltersComboboxRenderer = memo(function AdHocFiltersComboboxRenderer2({ controller }) {
9
- const { originFilters, filters, readOnly, recentFilters, recommendedFilters, drilldownRecommendationsEnabled } = controller.useState();
8
+ const { originFilters, filters, readOnly, valueRecommendations, drilldownRecommendationsEnabled } = controller.useState();
10
9
  const styles = useStyles2(getStyles);
11
- let drilldownRecommendationComponent = null;
12
- if (drilldownRecommendationsEnabled) {
13
- const recentDrilldowns = recentFilters == null ? void 0 : recentFilters.map((filter) => ({
14
- label: `${filter.key} ${filter.operator} ${filter.value}`,
15
- onClick: () => {
16
- var _a;
17
- (_a = controller.updateFilters) == null ? void 0 : _a.call(controller, [...filters, filter]);
18
- }
19
- }));
20
- const recommendedDrilldowns = recommendedFilters == null ? void 0 : recommendedFilters.map((filter) => ({
21
- label: `${filter.key} ${filter.operator} ${filter.value}`,
22
- onClick: () => {
23
- var _a;
24
- (_a = controller.updateFilters) == null ? void 0 : _a.call(controller, [...filters, filter]);
25
- }
26
- }));
27
- drilldownRecommendationComponent = /* @__PURE__ */ React.createElement(DrilldownRecommendations, { recentDrilldowns, recommendedDrilldowns });
28
- }
29
10
  const focusOnWipInputRef = useRef();
30
11
  return /* @__PURE__ */ React.createElement(
31
12
  "div",
@@ -37,7 +18,7 @@ const AdHocFiltersComboboxRenderer = memo(function AdHocFiltersComboboxRenderer2
37
18
  }
38
19
  },
39
20
  /* @__PURE__ */ React.createElement(Icon, { name: "filter", className: styles.filterIcon, size: "lg" }),
40
- drilldownRecommendationComponent,
21
+ drilldownRecommendationsEnabled && valueRecommendations && /* @__PURE__ */ React.createElement(valueRecommendations.Component, { model: valueRecommendations }),
41
22
  originFilters == null ? void 0 : originFilters.map(
42
23
  (filter, index) => filter.origin ? /* @__PURE__ */ React.createElement(
43
24
  AdHocFilterPill,
@@ -1 +1 @@
1
- {"version":3,"file":"AdHocFiltersComboboxRenderer.js","sources":["../../../../../../../../src/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Icon, useStyles2 } from '@grafana/ui';\nimport React, { memo, useRef } from 'react';\nimport { AdHocFiltersController } from '../controller/AdHocFiltersController';\nimport { AdHocFilterPill } from './AdHocFilterPill';\nimport { AdHocFiltersAlwaysWipCombobox } from './AdHocFiltersAlwaysWipCombobox';\nimport { DrilldownRecommendations } from '../../components/DrilldownRecommendations';\n\ninterface Props {\n controller: AdHocFiltersController;\n}\n\nexport const AdHocFiltersComboboxRenderer = memo(function AdHocFiltersComboboxRenderer({ controller }: Props) {\n const { originFilters, filters, readOnly, recentFilters, recommendedFilters, drilldownRecommendationsEnabled } =\n controller.useState();\n const styles = useStyles2(getStyles);\n\n let drilldownRecommendationComponent = null;\n\n if (drilldownRecommendationsEnabled) {\n const recentDrilldowns = recentFilters?.map((filter) => ({\n label: `${filter.key} ${filter.operator} ${filter.value}`,\n onClick: () => {\n controller.updateFilters?.([...filters, filter]);\n },\n }));\n\n const recommendedDrilldowns = recommendedFilters?.map((filter) => ({\n label: `${filter.key} ${filter.operator} ${filter.value}`,\n onClick: () => {\n controller.updateFilters?.([...filters, filter]);\n },\n }));\n\n drilldownRecommendationComponent = (\n <DrilldownRecommendations recentDrilldowns={recentDrilldowns} recommendedDrilldowns={recommendedDrilldowns} />\n );\n }\n\n // ref that focuses on the always wip filter input\n // defined in the combobox component via useImperativeHandle\n const focusOnWipInputRef = useRef<() => void>();\n\n return (\n <div\n className={cx(styles.comboboxWrapper, { [styles.comboboxFocusOutline]: !readOnly })}\n onClick={() => {\n focusOnWipInputRef.current?.();\n }}\n >\n <Icon name=\"filter\" className={styles.filterIcon} size=\"lg\" />\n\n {drilldownRecommendationComponent}\n\n {originFilters?.map((filter, index) =>\n filter.origin ? (\n <AdHocFilterPill\n key={`${index}-${filter.key}`}\n filter={filter}\n controller={controller}\n focusOnWipInputRef={focusOnWipInputRef.current}\n />\n ) : null\n )}\n\n {filters\n .filter((filter) => !filter.hidden)\n .map((filter, index) => (\n <AdHocFilterPill\n key={`${index}-${filter.key}`}\n filter={filter}\n controller={controller}\n readOnly={readOnly || filter.readOnly}\n focusOnWipInputRef={focusOnWipInputRef.current}\n />\n ))}\n\n {!readOnly ? <AdHocFiltersAlwaysWipCombobox controller={controller} ref={focusOnWipInputRef} /> : null}\n </div>\n );\n});\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n comboboxWrapper: css({\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: theme.spacing(1),\n rowGap: theme.spacing(0.5),\n minHeight: theme.spacing(4),\n backgroundColor: theme.components.input.background,\n border: `1px solid ${theme.colors.border.strong}`,\n borderRadius: theme.shape.radius.default,\n paddingInline: theme.spacing(1),\n paddingBlock: theme.spacing(0.5),\n flexGrow: 1,\n }),\n comboboxFocusOutline: css({\n '&:focus-within': {\n outline: '2px dotted transparent',\n outlineOffset: '2px',\n boxShadow: `0 0 0 2px ${theme.colors.background.canvas}, 0 0 0px 4px ${theme.colors.primary.main}`,\n transitionTimingFunction: `cubic-bezier(0.19, 1, 0.22, 1)`,\n transitionDuration: '0.2s',\n transitionProperty: 'outline, outline-offset, box-shadow',\n zIndex: 2,\n },\n }),\n filterIcon: css({\n color: theme.colors.text.secondary,\n alignSelf: 'center',\n }),\n});\n"],"names":["AdHocFiltersComboboxRenderer"],"mappings":"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"}
1
+ {"version":3,"file":"AdHocFiltersComboboxRenderer.js","sources":["../../../../../../../../src/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Icon, useStyles2 } from '@grafana/ui';\nimport React, { memo, useRef } from 'react';\nimport { AdHocFiltersController } from '../controller/AdHocFiltersController';\nimport { AdHocFilterPill } from './AdHocFilterPill';\nimport { AdHocFiltersAlwaysWipCombobox } from './AdHocFiltersAlwaysWipCombobox';\n\ninterface Props {\n controller: AdHocFiltersController;\n}\n\nexport const AdHocFiltersComboboxRenderer = memo(function AdHocFiltersComboboxRenderer({ controller }: Props) {\n const { originFilters, filters, readOnly, valueRecommendations, drilldownRecommendationsEnabled } =\n controller.useState();\n const styles = useStyles2(getStyles);\n\n // ref that focuses on the always wip filter input\n // defined in the combobox component via useImperativeHandle\n const focusOnWipInputRef = useRef<() => void>();\n\n return (\n <div\n className={cx(styles.comboboxWrapper, { [styles.comboboxFocusOutline]: !readOnly })}\n onClick={() => {\n focusOnWipInputRef.current?.();\n }}\n >\n <Icon name=\"filter\" className={styles.filterIcon} size=\"lg\" />\n\n {drilldownRecommendationsEnabled && valueRecommendations && (\n <valueRecommendations.Component model={valueRecommendations} />\n )}\n\n {originFilters?.map((filter, index) =>\n filter.origin ? (\n <AdHocFilterPill\n key={`${index}-${filter.key}`}\n filter={filter}\n controller={controller}\n focusOnWipInputRef={focusOnWipInputRef.current}\n />\n ) : null\n )}\n\n {filters\n .filter((filter) => !filter.hidden)\n .map((filter, index) => (\n <AdHocFilterPill\n key={`${index}-${filter.key}`}\n filter={filter}\n controller={controller}\n readOnly={readOnly || filter.readOnly}\n focusOnWipInputRef={focusOnWipInputRef.current}\n />\n ))}\n\n {!readOnly ? <AdHocFiltersAlwaysWipCombobox controller={controller} ref={focusOnWipInputRef} /> : null}\n </div>\n );\n});\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n comboboxWrapper: css({\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: theme.spacing(1),\n rowGap: theme.spacing(0.5),\n minHeight: theme.spacing(4),\n backgroundColor: theme.components.input.background,\n border: `1px solid ${theme.colors.border.strong}`,\n borderRadius: theme.shape.radius.default,\n paddingInline: theme.spacing(1),\n paddingBlock: theme.spacing(0.5),\n flexGrow: 1,\n }),\n comboboxFocusOutline: css({\n '&:focus-within': {\n outline: '2px dotted transparent',\n outlineOffset: '2px',\n boxShadow: `0 0 0 2px ${theme.colors.background.canvas}, 0 0 0px 4px ${theme.colors.primary.main}`,\n transitionTimingFunction: `cubic-bezier(0.19, 1, 0.22, 1)`,\n transitionDuration: '0.2s',\n transitionProperty: 'outline, outline-offset, box-shadow',\n zIndex: 2,\n },\n }),\n filterIcon: css({\n color: theme.colors.text.secondary,\n alignSelf: 'center',\n }),\n});\n"],"names":["AdHocFiltersComboboxRenderer"],"mappings":"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"}
@@ -0,0 +1,174 @@
1
+ import React from 'react';
2
+ import { config } from '@grafana/runtime';
3
+ import { store } from '@grafana/data';
4
+ import { SceneObjectBase } from '../../core/SceneObjectBase.js';
5
+ import { sceneGraph } from '../../core/sceneGraph/index.js';
6
+ import { getEnrichedDataRequest } from '../../querying/getEnrichedDataRequest.js';
7
+ import { getQueriesForVariables } from '../utils.js';
8
+ import { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject.js';
9
+ import { getDataSource } from '../../utils/getDataSource.js';
10
+ import { getEnrichedFiltersRequest } from '../getEnrichedFiltersRequest.js';
11
+ import { DrilldownRecommendations } from '../components/DrilldownRecommendations.js';
12
+ import { ScopesVariable } from '../variants/ScopesVariable.js';
13
+ import { SCOPES_VARIABLE_NAME } from '../constants.js';
14
+ import { getRecentFiltersKey } from './AdHocFiltersVariable.js';
15
+
16
+ class AdHocFiltersRecommendations extends SceneObjectBase {
17
+ constructor(parent) {
18
+ super({});
19
+ this._scopedVars = { __sceneObject: wrapInSafeSerializableSceneObject(this) };
20
+ this._activationHandler = () => {
21
+ const json = store.get(this._getStorageKey());
22
+ const storedFilters = json ? JSON.parse(json) : [];
23
+ if (storedFilters.length > 0) {
24
+ this._verifyRecentFiltersApplicability(storedFilters);
25
+ } else {
26
+ this.setState({ recentFilters: [] });
27
+ }
28
+ this._fetchRecommendedDrilldowns();
29
+ const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this);
30
+ let scopesSubscription;
31
+ if (scopesVariable instanceof ScopesVariable) {
32
+ scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {
33
+ if (newState.scopes !== prevState.scopes) {
34
+ const json2 = store.get(this._getStorageKey());
35
+ const storedFilters2 = json2 ? JSON.parse(json2) : [];
36
+ if (storedFilters2.length > 0) {
37
+ this._verifyRecentFiltersApplicability(storedFilters2);
38
+ }
39
+ }
40
+ });
41
+ }
42
+ return () => {
43
+ scopesSubscription == null ? void 0 : scopesSubscription.unsubscribe();
44
+ };
45
+ };
46
+ this._parentVariable = parent;
47
+ this.addActivationHandler(this._activationHandler);
48
+ }
49
+ /**
50
+ * Get the parent variable
51
+ */
52
+ get parent() {
53
+ return this._parentVariable;
54
+ }
55
+ _getStorageKey() {
56
+ var _a;
57
+ return getRecentFiltersKey((_a = this._parentVariable.state.datasource) == null ? void 0 : _a.uid);
58
+ }
59
+ async _fetchRecommendedDrilldowns() {
60
+ var _a;
61
+ const parent = this._parentVariable;
62
+ const ds = await getDataSource(parent.state.datasource, this._scopedVars);
63
+ if (!ds || !ds.getRecommendedDrilldowns) {
64
+ return;
65
+ }
66
+ const queries = parent.state.useQueriesAsFilterForOptions ? getQueriesForVariables(parent) : void 0;
67
+ const timeRange = sceneGraph.getTimeRange(this).state.value;
68
+ const scopes = sceneGraph.getScopes(this);
69
+ const filters = [...(_a = parent.state.originFilters) != null ? _a : [], ...parent.state.filters];
70
+ const enrichedRequest = getEnrichedDataRequest(this);
71
+ const dashboardUid = enrichedRequest == null ? void 0 : enrichedRequest.dashboardUID;
72
+ try {
73
+ const recommendedDrilldowns = await ds.getRecommendedDrilldowns({
74
+ timeRange,
75
+ dashboardUid,
76
+ queries: queries != null ? queries : [],
77
+ filters,
78
+ scopes,
79
+ userId: config.bootData.user.id
80
+ });
81
+ if (recommendedDrilldowns == null ? void 0 : recommendedDrilldowns.filters) {
82
+ this.setState({ recommendedFilters: recommendedDrilldowns.filters });
83
+ }
84
+ } catch (error) {
85
+ console.error("Failed to fetch recommended drilldowns:", error);
86
+ }
87
+ }
88
+ async _verifyRecentFiltersApplicability(storedFilters) {
89
+ const parent = this._parentVariable;
90
+ const queries = parent.state.useQueriesAsFilterForOptions ? getQueriesForVariables(parent) : void 0;
91
+ const response = await this._getFiltersApplicabilityForQueries(storedFilters, queries != null ? queries : []);
92
+ if (!response) {
93
+ this.setState({ recentFilters: storedFilters.slice(-3) });
94
+ return;
95
+ }
96
+ const applicabilityMap = /* @__PURE__ */ new Map();
97
+ response.forEach((item) => {
98
+ applicabilityMap.set(item.key, item.applicable !== false);
99
+ });
100
+ const applicableFilters = storedFilters.filter((f) => {
101
+ const isApplicable = applicabilityMap.get(f.key);
102
+ return isApplicable === void 0 || isApplicable === true;
103
+ }).slice(-3);
104
+ this.setState({ recentFilters: applicableFilters });
105
+ }
106
+ async _getFiltersApplicabilityForQueries(filters, queries) {
107
+ const parent = this._parentVariable;
108
+ const ds = await getDataSource(parent.state.datasource, this._scopedVars);
109
+ if (!ds || !ds.getDrilldownsApplicability) {
110
+ return;
111
+ }
112
+ const timeRange = sceneGraph.getTimeRange(this).state.value;
113
+ return await ds.getDrilldownsApplicability({
114
+ filters,
115
+ queries,
116
+ timeRange,
117
+ scopes: sceneGraph.getScopes(this),
118
+ ...getEnrichedFiltersRequest(this)
119
+ });
120
+ }
121
+ /**
122
+ * Stores a recent filter in localStorage and updates state.
123
+ * Should be called by the parent variable when a filter is added/updated.
124
+ */
125
+ storeRecentFilter(filter) {
126
+ const key = this._getStorageKey();
127
+ const storedFilters = store.get(key);
128
+ const allRecentFilters = storedFilters ? JSON.parse(storedFilters) : [];
129
+ const updatedStoredFilters = [...allRecentFilters, filter].slice(-10);
130
+ store.set(key, JSON.stringify(updatedStoredFilters));
131
+ const parent = this._parentVariable;
132
+ const existingFilter = parent.state.filters.find((f) => f.key === filter.key && !Boolean(f.nonApplicable));
133
+ if (existingFilter && !Boolean(existingFilter.nonApplicable)) {
134
+ this.setState({ recentFilters: updatedStoredFilters.slice(-3) });
135
+ }
136
+ }
137
+ /**
138
+ * Get the current filters from the parent variable
139
+ */
140
+ getParentFilters() {
141
+ return this._parentVariable.state.filters;
142
+ }
143
+ /**
144
+ * Add a filter to the parent variable
145
+ */
146
+ addFilterToParent(filter) {
147
+ const parent = this._parentVariable;
148
+ parent.updateFilters([...parent.state.filters, filter]);
149
+ }
150
+ }
151
+ AdHocFiltersRecommendations.Component = AdHocFiltersRecommendationsRenderer;
152
+ function AdHocFiltersRecommendationsRenderer({ model }) {
153
+ const { recentFilters, recommendedFilters } = model.useState();
154
+ const { filters } = model.parent.useState();
155
+ const recentDrilldowns = recentFilters == null ? void 0 : recentFilters.map((filter) => ({
156
+ label: `${filter.key} ${filter.operator} ${filter.value}`,
157
+ onClick: () => {
158
+ model.addFilterToParent(filter);
159
+ }
160
+ }));
161
+ const recommendedDrilldowns = recommendedFilters == null ? void 0 : recommendedFilters.map((filter) => ({
162
+ label: `${filter.key} ${filter.operator} ${filter.value}`,
163
+ onClick: () => {
164
+ const exists = filters.some((f) => f.key === filter.key && f.value === filter.value);
165
+ if (!exists) {
166
+ model.addFilterToParent(filter);
167
+ }
168
+ }
169
+ }));
170
+ return /* @__PURE__ */ React.createElement(DrilldownRecommendations, { recentDrilldowns, recommendedDrilldowns });
171
+ }
172
+
173
+ export { AdHocFiltersRecommendations };
174
+ //# sourceMappingURL=AdHocFiltersRecommendations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdHocFiltersRecommendations.js","sources":["../../../../../../../src/variables/adhoc/AdHocFiltersRecommendations.tsx"],"sourcesContent":["import React from 'react';\nimport { config } from '@grafana/runtime';\nimport {\n // @ts-expect-error (temporary till we update grafana/data)\n DrilldownsApplicability,\n store,\n} from '@grafana/data';\nimport { Unsubscribable } from 'rxjs';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneDataQuery, SceneObjectState } from '../../core/types';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { getEnrichedDataRequest } from '../../querying/getEnrichedDataRequest';\nimport { getQueriesForVariables } from '../utils';\nimport { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject';\nimport { getDataSource } from '../../utils/getDataSource';\nimport { getEnrichedFiltersRequest } from '../getEnrichedFiltersRequest';\nimport { DrilldownRecommendations, DrilldownPill } from '../components/DrilldownRecommendations';\nimport { ScopesVariable } from '../variants/ScopesVariable';\nimport { SCOPES_VARIABLE_NAME } from '../constants';\nimport {\n AdHocFilterWithLabels,\n AdHocFiltersVariable,\n getRecentFiltersKey,\n MAX_RECENT_DRILLDOWNS,\n MAX_STORED_RECENT_DRILLDOWNS,\n} from './AdHocFiltersVariable';\n\nexport interface AdHocFiltersRecommendationsState extends SceneObjectState {\n /** Recent filters */\n recentFilters?: AdHocFilterWithLabels[];\n /** Recommended filters */\n recommendedFilters?: AdHocFilterWithLabels[];\n}\n\n/**\n * Scene object component that manages recommendations for AdHocFiltersVariable.\n * It handles fetching recommended drilldowns, verifying applicability of recent filters,\n * and storing/displaying recent filters.\n */\nexport class AdHocFiltersRecommendations extends SceneObjectBase<AdHocFiltersRecommendationsState> {\n static Component = AdHocFiltersRecommendationsRenderer;\n\n private _scopedVars = { __sceneObject: wrapInSafeSerializableSceneObject(this) };\n\n // Store parent as a class property, not in state, to avoid circular parent references\n private _parentVariable: AdHocFiltersVariable;\n\n public constructor(parent: AdHocFiltersVariable) {\n super({});\n this._parentVariable = parent;\n this.addActivationHandler(this._activationHandler);\n }\n\n /**\n * Get the parent variable\n */\n public get parent(): AdHocFiltersVariable {\n return this._parentVariable;\n }\n\n private _activationHandler = () => {\n const json = store.get(this._getStorageKey());\n const storedFilters = json ? JSON.parse(json) : [];\n\n // Verify applicability of stored recent filters\n if (storedFilters.length > 0) {\n this._verifyRecentFiltersApplicability(storedFilters);\n } else {\n this.setState({ recentFilters: [] });\n }\n\n this._fetchRecommendedDrilldowns();\n\n // Subscribe to scopes variable changes\n const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this);\n let scopesSubscription: Unsubscribable | undefined;\n\n if (scopesVariable instanceof ScopesVariable) {\n scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {\n // Check if scopes have changed\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 });\n }\n\n return () => {\n scopesSubscription?.unsubscribe();\n };\n };\n\n private _getStorageKey(): string {\n return getRecentFiltersKey(this._parentVariable.state.datasource?.uid);\n }\n\n private async _fetchRecommendedDrilldowns() {\n const parent = this._parentVariable;\n const ds = await getDataSource(parent.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 = parent.state.useQueriesAsFilterForOptions ? getQueriesForVariables(parent) : undefined;\n const timeRange = sceneGraph.getTimeRange(this).state.value;\n const scopes = sceneGraph.getScopes(this);\n const filters = [...(parent.state.originFilters ?? []), ...parent.state.filters];\n\n const enrichedRequest = getEnrichedDataRequest(this);\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 userId: config.bootData.user.id,\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 parent = this._parentVariable;\n const queries = parent.state.useQueriesAsFilterForOptions ? getQueriesForVariables(parent) : undefined;\n const response = await this._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 private async _getFiltersApplicabilityForQueries(\n filters: AdHocFilterWithLabels[],\n queries: SceneDataQuery[]\n ): Promise<DrilldownsApplicability[] | undefined> {\n const parent = this._parentVariable;\n const ds = await getDataSource(parent.state.datasource, this._scopedVars);\n // @ts-expect-error (temporary till we update grafana/data)\n if (!ds || !ds.getDrilldownsApplicability) {\n return;\n }\n\n const timeRange = sceneGraph.getTimeRange(this).state.value;\n\n // @ts-expect-error (temporary till we update grafana/data)\n return await ds.getDrilldownsApplicability({\n filters,\n queries,\n timeRange,\n scopes: sceneGraph.getScopes(this),\n ...getEnrichedFiltersRequest(this),\n });\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 parent = this._parentVariable;\n const existingFilter = parent.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 /**\n * Get the current filters from the parent variable\n */\n public getParentFilters(): AdHocFilterWithLabels[] {\n return this._parentVariable.state.filters;\n }\n\n /**\n * Add a filter to the parent variable\n */\n public addFilterToParent(filter: AdHocFilterWithLabels) {\n const parent = this._parentVariable;\n parent.updateFilters([...parent.state.filters, filter]);\n }\n}\n\nfunction AdHocFiltersRecommendationsRenderer({ model }: SceneComponentProps<AdHocFiltersRecommendations>) {\n const { recentFilters, recommendedFilters } = model.useState();\n const { filters } = model.parent.useState();\n\n const recentDrilldowns: DrilldownPill[] | undefined = recentFilters?.map((filter) => ({\n label: `${filter.key} ${filter.operator} ${filter.value}`,\n onClick: () => {\n model.addFilterToParent(filter);\n },\n }));\n\n const recommendedDrilldowns: DrilldownPill[] | undefined = recommendedFilters?.map((filter) => ({\n label: `${filter.key} ${filter.operator} ${filter.value}`,\n onClick: () => {\n // Check if filter already exists\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,18 +1,16 @@
1
1
  import React, { useMemo } from 'react';
2
- import { store } from '@grafana/data';
3
2
  import { SceneObjectBase } from '../../core/SceneObjectBase.js';
4
3
  import { SceneVariableValueChangedEvent } from '../types.js';
5
- import { getQueriesForVariables, escapeOriginFilterUrlDelimiters, dataFromResponse, responseHasError, renderPrometheusLabelFilters } from '../utils.js';
4
+ import { escapeOriginFilterUrlDelimiters, getQueriesForVariables, dataFromResponse, responseHasError, renderPrometheusLabelFilters } from '../utils.js';
6
5
  import { patchGetAdhocFilters } from './patchGetAdhocFilters.js';
7
6
  import { useStyles2 } from '@grafana/ui';
8
7
  import { sceneGraph } from '../../core/sceneGraph/index.js';
9
8
  import { AdHocFilterBuilder } from './AdHocFilterBuilder.js';
10
9
  import { AdHocFilterRenderer } from './AdHocFilterRenderer.js';
11
- import { getDataSourceSrv, config } from '@grafana/runtime';
10
+ import { getDataSourceSrv } from '@grafana/runtime';
12
11
  import { AdHocFiltersVariableUrlSyncHandler, toArray } from './AdHocFiltersVariableUrlSyncHandler.js';
13
12
  import { css } from '@emotion/css';
14
13
  import { getEnrichedFiltersRequest } from '../getEnrichedFiltersRequest.js';
15
- import { getEnrichedDataRequest } from '../../querying/getEnrichedDataRequest.js';
16
14
  import { AdHocFiltersComboboxRenderer } from './AdHocFiltersCombobox/AdHocFiltersComboboxRenderer.js';
17
15
  import { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject.js';
18
16
  import { debounce, isEqual } from 'lodash';
@@ -21,6 +19,7 @@ import { VariableDependencyConfig } from '../VariableDependencyConfig.js';
21
19
  import { getQueryController } from '../../core/sceneGraph/getQueryController.js';
22
20
  import { FILTER_RESTORED_INTERACTION, FILTER_REMOVED_INTERACTION } from '../../performance/interactionConstants.js';
23
21
  import { AdHocFiltersVariableController } from './controller/AdHocFiltersVariableController.js';
22
+ import { AdHocFiltersRecommendations } from './AdHocFiltersRecommendations.js';
24
23
 
25
24
  const ORIGIN_FILTERS_KEY = "originFilters";
26
25
  const getRecentFiltersKey = (datasourceUid) => `grafana.filters.recent.${datasourceUid != null ? datasourceUid : "default"}`;
@@ -97,21 +96,15 @@ class AdHocFiltersVariable extends SceneObjectBase {
97
96
  this._urlSync = new AdHocFiltersVariableUrlSyncHandler(this);
98
97
  this._debouncedVerifyApplicability = debounce(this._verifyApplicability, 100);
99
98
  this._activationHandler = () => {
100
- var _a;
101
99
  this._debouncedVerifyApplicability();
102
- if (this.state.drilldownRecommendationsEnabled) {
103
- const json = store.get(getRecentFiltersKey((_a = this.state.datasource) == null ? void 0 : _a.uid));
104
- const storedFilters = json ? JSON.parse(json) : [];
105
- if (storedFilters.length > 0) {
106
- this._verifyRecentFiltersApplicability(storedFilters);
107
- } else {
108
- this.setState({ _recentFilters: [] });
109
- }
110
- this._fetchRecommendedDrilldowns();
100
+ if (this.state.drilldownRecommendationsEnabled && !this.state._valueRecommendations) {
101
+ const valueRecommendations = new AdHocFiltersRecommendations(this);
102
+ this.setState({ _valueRecommendations: valueRecommendations });
103
+ valueRecommendations.activate();
111
104
  }
112
105
  return () => {
113
- var _a2;
114
- (_a2 = this.state.originFilters) == null ? void 0 : _a2.forEach((filter) => {
106
+ var _a;
107
+ (_a = this.state.originFilters) == null ? void 0 : _a.forEach((filter) => {
115
108
  if (filter.restorable) {
116
109
  this.restoreOriginalFilter(filter);
117
110
  }
@@ -131,34 +124,6 @@ class AdHocFiltersVariable extends SceneObjectBase {
131
124
  });
132
125
  this.addActivationHandler(this._activationHandler);
133
126
  }
134
- async _fetchRecommendedDrilldowns() {
135
- var _a;
136
- const ds = await this._dataSourceSrv.get(this.state.datasource, this._scopedVars);
137
- if (!ds || !ds.getRecommendedDrilldowns) {
138
- return;
139
- }
140
- const queries = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : void 0;
141
- const timeRange = sceneGraph.getTimeRange(this).state.value;
142
- const scopes = sceneGraph.getScopes(this);
143
- const filters = [...(_a = this.state.originFilters) != null ? _a : [], ...this.state.filters];
144
- const enrichedRequest = getEnrichedDataRequest(this);
145
- const dashboardUid = enrichedRequest == null ? void 0 : enrichedRequest.dashboardUID;
146
- try {
147
- const recommendedDrilldowns = await ds.getRecommendedDrilldowns({
148
- timeRange,
149
- dashboardUid,
150
- queries: queries != null ? queries : [],
151
- filters,
152
- scopes,
153
- userId: config.bootData.user.id
154
- });
155
- if (recommendedDrilldowns == null ? void 0 : recommendedDrilldowns.filters) {
156
- this.setRecommendedFilters(recommendedDrilldowns.filters);
157
- }
158
- } catch (error) {
159
- console.error("Failed to fetch recommended drilldowns:", error);
160
- }
161
- }
162
127
  _updateScopesFilters() {
163
128
  var _a, _b;
164
129
  const scopes = sceneGraph.getScopes(this);
@@ -208,10 +173,10 @@ class AdHocFiltersVariable extends SceneObjectBase {
208
173
  }
209
174
  async verifyApplicabilityAndStoreRecentFilter(update) {
210
175
  await this._verifyApplicability();
211
- if (!this.state.drilldownRecommendationsEnabled) {
176
+ if (!this.state.drilldownRecommendationsEnabled || !this.state._valueRecommendations) {
212
177
  return;
213
178
  }
214
- this.storeRecentFilter(update);
179
+ this.state._valueRecommendations.storeRecentFilter(update);
215
180
  }
216
181
  setState(update) {
217
182
  var _a, _b;
@@ -318,39 +283,12 @@ class AdHocFiltersVariable extends SceneObjectBase {
318
283
  return f === filter ? { ...f, ...update } : f;
319
284
  });
320
285
  this.setState({ filters: updatedFilters });
321
- this.storeRecentFilter({ ...filter, ...update });
322
- }
323
- storeRecentFilter(update) {
324
- var _a;
325
- if (!this.state.drilldownRecommendationsEnabled) {
326
- return;
327
- }
328
- const key = getRecentFiltersKey((_a = this.state.datasource) == null ? void 0 : _a.uid);
329
- const storedFilters = store.get(key);
330
- const allRecentFilters = storedFilters ? JSON.parse(storedFilters) : [];
331
- const updatedStoredFilters = [...allRecentFilters, update].slice(-10);
332
- store.set(key, JSON.stringify(updatedStoredFilters));
333
- const filter = this.state.filters.find((f) => f.key === update.key && !Boolean(f.nonApplicable));
334
- if (filter && !Boolean(filter.nonApplicable)) {
335
- this.setState({ _recentFilters: updatedStoredFilters.slice(-3) });
336
- }
337
- }
338
- async _verifyRecentFiltersApplicability(storedFilters) {
339
- const queries = this.state.useQueriesAsFilterForOptions ? getQueriesForVariables(this) : void 0;
340
- const response = await this.getFiltersApplicabilityForQueries(storedFilters, queries != null ? queries : []);
341
- if (!response) {
342
- this.setState({ _recentFilters: storedFilters.slice(-3) });
343
- return;
286
+ if (this.state.drilldownRecommendationsEnabled && this.state._valueRecommendations) {
287
+ this.state._valueRecommendations.storeRecentFilter({
288
+ ...filter,
289
+ ...update
290
+ });
344
291
  }
345
- const applicabilityMap = /* @__PURE__ */ new Map();
346
- response.forEach((item) => {
347
- applicabilityMap.set(item.key, item.applicable !== false);
348
- });
349
- const applicableFilters = storedFilters.filter((f) => {
350
- const isApplicable = applicabilityMap.get(f.key);
351
- return isApplicable === void 0 || isApplicable === true;
352
- }).slice(-3);
353
- this.setState({ _recentFilters: applicableFilters });
354
292
  }
355
293
  updateToMatchAll(filter) {
356
294
  this._updateFilter(filter, {
@@ -427,11 +365,6 @@ class AdHocFiltersVariable extends SceneObjectBase {
427
365
  });
428
366
  }
429
367
  }
430
- setRecommendedFilters(recommendedFilters) {
431
- this.setState({
432
- _recommendedFilters: recommendedFilters
433
- });
434
- }
435
368
  async getFiltersApplicabilityForQueries(filters, queries) {
436
369
  const ds = await this._dataSourceSrv.get(this.state.datasource, this._scopedVars);
437
370
  if (!ds || !ds.getDrilldownsApplicability) {