@grafana/scenes 7.3.0 → 7.3.1

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
+ # v7.3.1 (Wed Apr 01 2026)
2
+
3
+ #### 🐛 Bug Fix
4
+
5
+ - Filters: Move recommendations to unified adhoc [#1406](https://github.com/grafana/scenes/pull/1406) ([@mdvictor](https://github.com/mdvictor))
6
+
7
+ #### Authors: 1
8
+
9
+ - Victor Marin ([@mdvictor](https://github.com/mdvictor))
10
+
11
+ ---
12
+
1
13
  # v7.3.0 (Tue Mar 31 2026)
2
14
 
3
15
  #### 🚀 Enhancement
@@ -7,6 +7,7 @@ import { AdHocFilterPill } from './AdHocFilterPill.js';
7
7
  import { AdHocFiltersAlwaysWipCombobox } from './AdHocFiltersAlwaysWipCombobox.js';
8
8
  import { GroupByPill } from './GroupByPill.js';
9
9
  import { isGroupByFilter } from '../AdHocFiltersVariable.js';
10
+ import { AdHocGroupByRecommendationsRenderer } from '../AdHocFiltersRecommendations.js';
10
11
 
11
12
  const MAX_VISIBLE_FILTERS_DEFAULT = 4;
12
13
  const MAX_VISIBLE_FILTERS_WITH_GROUP_BY = 2;
@@ -100,7 +101,7 @@ const AdHocFiltersComboboxRenderer = memo(function AdHocFiltersComboboxRenderer2
100
101
  adhocHiddenCount
101
102
  ),
102
103
  !readOnly && /* @__PURE__ */ React.createElement(AdHocFiltersAlwaysWipCombobox, { ref: focusOnWipInputRef, controller, onInputClick: handleExpand }),
103
- enableGroupBy && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: styles.sectionDivider }), /* @__PURE__ */ React.createElement("span", { className: styles.groupByLabel }, t("grafana-scenes.variables.adhoc-filters-combobox-renderer.group-by-label", "Group by:")), groupByFiltersToRender.map((filter, index) => /* @__PURE__ */ React.createElement(
104
+ enableGroupBy && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: styles.sectionDivider }), /* @__PURE__ */ React.createElement("span", { className: styles.groupByLabel }, t("grafana-scenes.variables.adhoc-filters-combobox-renderer.group-by-label", "Group by:")), !readOnly && valueRecommendations && /* @__PURE__ */ React.createElement(AdHocGroupByRecommendationsRenderer, { model: valueRecommendations }), groupByFiltersToRender.map((filter, index) => /* @__PURE__ */ React.createElement(
104
105
  GroupByPill,
105
106
  {
106
107
  key: `groupby-${index}-${filter.key}`,
@@ -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 { Button, IconButton, Icon, useStyles2, useTheme2 } from '@grafana/ui';\nimport { t } from '@grafana/i18n';\nimport React, { memo, useRef, useState, useEffect } from 'react';\nimport { useMeasure } from 'react-use';\nimport { AdHocFiltersController } from '../controller/AdHocFiltersController';\nimport { AdHocFilterPill } from './AdHocFilterPill';\nimport { AdHocFiltersAlwaysWipCombobox } from './AdHocFiltersAlwaysWipCombobox';\nimport { GroupByPill } from './GroupByPill';\nimport { isGroupByFilter } from '../AdHocFiltersVariable';\n\nconst MAX_VISIBLE_FILTERS_DEFAULT = 4;\nconst MAX_VISIBLE_FILTERS_WITH_GROUP_BY = 2;\nconst MAX_VISIBLE_GROUP_BY = 2;\n\ninterface Props {\n controller: AdHocFiltersController;\n}\n\nexport const AdHocFiltersComboboxRenderer = memo(function AdHocFiltersComboboxRenderer({ controller }: Props) {\n const { originFilters, filters, readOnly, collapsible, valueRecommendations, enableGroupBy, groupByRestorable } =\n controller.useState();\n const styles = useStyles2(getStyles);\n const theme = useTheme2();\n const [collapsed, setCollapsed] = useState(true);\n const [wrapperRef, { height: wrapperHeight }] = useMeasure<HTMLDivElement>();\n\n const clearAll = () => {\n controller.clearAll?.();\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 const focusOnGroupByWipInputRef = useRef<() => void>();\n\n // Single line height is approximately minHeight (4 spacing units) + small buffer\n const singleLineThreshold = theme.spacing.gridSize * 5;\n const isMultiLine = collapsible && wrapperHeight > singleLineThreshold;\n\n const handleCollapseToggle = (event: React.MouseEvent) => {\n event.stopPropagation();\n if (collapsible) {\n setCollapsed(true);\n }\n };\n\n const handleExpand = () => {\n if (collapsible && collapsed) {\n setCollapsed(false);\n }\n };\n\n // Combine all visible filters into one array\n const visibleOriginFilters = originFilters?.filter((f) => f.origin && !f.hidden && !f.dismissedGroupBy) ?? [];\n const visibleFilters = filters.filter((f) => !f.hidden);\n const allFilters = [...visibleOriginFilters, ...visibleFilters];\n const totalFiltersCount = allFilters.length;\n\n const adhocFilters = allFilters.filter((f) => !isGroupByFilter(f));\n const groupByFilters = allFilters.filter(isGroupByFilter);\n\n const shouldCollapse = collapsible && collapsed && totalFiltersCount > 0;\n\n const maxVisibleAdhocFilters = enableGroupBy ? MAX_VISIBLE_FILTERS_WITH_GROUP_BY : MAX_VISIBLE_FILTERS_DEFAULT;\n const adhocFiltersToRender = shouldCollapse ? adhocFilters.slice(0, maxVisibleAdhocFilters) : adhocFilters;\n const adhocHiddenCount = shouldCollapse ? Math.max(0, adhocFilters.length - maxVisibleAdhocFilters) : 0;\n\n const groupByFiltersToRender = shouldCollapse ? groupByFilters.slice(0, MAX_VISIBLE_GROUP_BY) : groupByFilters;\n const groupByHiddenCount = shouldCollapse ? Math.max(0, groupByFilters.length - MAX_VISIBLE_GROUP_BY) : 0;\n\n // Reset collapsed state when there are no filters (only when collapsible)\n useEffect(() => {\n if (collapsible && totalFiltersCount === 0 && collapsed) {\n setCollapsed(false);\n }\n }, [collapsible, totalFiltersCount, collapsed]);\n\n // Only show collapse button when expanded and content wraps to multiple lines\n const showCollapseButton = collapsible && isMultiLine && !collapsed;\n const showExpandButton = shouldCollapse && (adhocHiddenCount > 0 || groupByHiddenCount > 0);\n\n return (\n <div\n ref={wrapperRef}\n className={cx(styles.comboboxWrapper, {\n [styles.comboboxFocusOutline]: !readOnly,\n [styles.collapsed]: shouldCollapse,\n })}\n >\n {!readOnly && valueRecommendations && <valueRecommendations.Component model={valueRecommendations} />}\n\n {adhocFiltersToRender.map((filter, index) => (\n <AdHocFilterPill\n key={`${filter.origin ? 'origin-' : ''}${index}-${filter.key}`}\n filter={filter}\n controller={controller}\n readOnly={readOnly || filter.readOnly}\n focusOnWipInputRef={focusOnWipInputRef.current}\n />\n ))}\n\n {shouldCollapse && adhocHiddenCount > 0 && (\n <Button\n className={styles.moreIndicator}\n fill=\"text\"\n size=\"sm\"\n aria-label={t(\n 'grafana-scenes.variables.adhoc-filters-combobox-renderer.show-more-filters',\n 'Show {{count}} more filters',\n { count: adhocHiddenCount }\n )}\n onClick={(e) => {\n e.stopPropagation();\n handleExpand();\n setTimeout(() => focusOnWipInputRef.current?.());\n }}\n >\n +{adhocHiddenCount}\n </Button>\n )}\n\n {!readOnly && (\n <AdHocFiltersAlwaysWipCombobox ref={focusOnWipInputRef} controller={controller} onInputClick={handleExpand} />\n )}\n\n {enableGroupBy && (\n <>\n <div className={styles.sectionDivider} />\n <span className={styles.groupByLabel}>\n {t('grafana-scenes.variables.adhoc-filters-combobox-renderer.group-by-label', 'Group by:')}\n </span>\n\n {groupByFiltersToRender.map((filter, index) => (\n <GroupByPill\n key={`groupby-${index}-${filter.key}`}\n filter={filter}\n controller={controller}\n readOnly={readOnly || filter.readOnly}\n focusOnWipInputRef={focusOnGroupByWipInputRef.current}\n />\n ))}\n\n {shouldCollapse && groupByHiddenCount > 0 && (\n <Button\n className={styles.moreIndicator}\n fill=\"text\"\n size=\"sm\"\n aria-label={t(\n 'grafana-scenes.variables.adhoc-filters-combobox-renderer.show-more-group-by',\n 'Show {{count}} more group by',\n { count: groupByHiddenCount }\n )}\n onClick={(e) => {\n e.stopPropagation();\n handleExpand();\n setTimeout(() => focusOnGroupByWipInputRef.current?.());\n }}\n >\n +{groupByHiddenCount}\n </Button>\n )}\n\n {!readOnly && (\n <AdHocFiltersAlwaysWipCombobox\n ref={focusOnGroupByWipInputRef}\n controller={controller}\n onInputClick={handleExpand}\n isGroupBy\n />\n )}\n\n {groupByRestorable && (\n <IconButton\n name=\"history\"\n size=\"md\"\n className={styles.controlButton}\n tooltip={t(\n 'grafana-scenes.variables.adhoc-filters-combobox-renderer.restore-default-group-by',\n 'Restore groupby set by this dashboard.'\n )}\n onClick={() => controller.restoreOriginalGroupBy?.()}\n />\n )}\n </>\n )}\n\n {/* Right-side controls: collapse button and clear all */}\n {(showCollapseButton || showExpandButton || !readOnly) && (\n <div className={styles.rightControls}>\n <div className={styles.sectionDivider} />\n\n {showCollapseButton && (\n <Button\n className={styles.collapseButton}\n fill=\"text\"\n size=\"sm\"\n onClick={handleCollapseToggle}\n aria-label={t(\n 'grafana-scenes.variables.adhoc-filters-combobox-renderer.collapse-filters',\n 'Collapse filters'\n )}\n aria-expanded={!collapsed}\n >\n {t('grafana-scenes.variables.adhoc-filters-combobox-renderer.collapse', 'Collapse')}\n <Icon name=\"angle-up\" size=\"md\" />\n </Button>\n )}\n\n {showExpandButton && (\n <IconButton\n name=\"angle-down\"\n size=\"md\"\n className={styles.dropdownIndicator}\n tooltip={t('grafana-scenes.variables.adhoc-filters-combobox-renderer.expand-filters', 'Expand filters')}\n onClick={(e) => {\n e.stopPropagation();\n handleExpand();\n }}\n />\n )}\n\n {!readOnly && (\n <IconButton\n name=\"times\"\n size=\"md\"\n className={styles.controlButton}\n tooltip={t('grafana-scenes.variables.adhoc-filters-combobox-renderer.clear-all', 'Clear all')}\n onClick={clearAll}\n />\n )}\n </div>\n )}\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 width: '100%',\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 collapsed: css({\n flexWrap: 'nowrap',\n overflow: 'hidden',\n }),\n rightControls: css({\n display: 'flex',\n alignItems: 'center',\n marginLeft: 'auto',\n flexShrink: 0,\n gap: theme.spacing(1.5),\n }),\n moreIndicator: css({\n color: theme.colors.text.primary,\n background: theme.colors.action.selected,\n height: 'auto',\n lineHeight: 'normal',\n alignSelf: 'stretch',\n '&:hover': {\n background: theme.colors.action.hover,\n },\n }),\n dropdownIndicator: css({\n color: theme.colors.text.secondary,\n flexShrink: 0,\n }),\n collapseButton: css({\n color: theme.colors.text.secondary,\n padding: 0,\n height: 'auto',\n lineHeight: 'normal',\n '&:hover': {\n background: 'transparent',\n color: theme.colors.text.primary,\n },\n }),\n sectionDivider: css({\n width: '1px',\n alignSelf: 'stretch',\n backgroundColor: theme.colors.border.weak,\n flexShrink: 0,\n }),\n groupByLabel: css({\n ...theme.typography.bodySmall,\n fontWeight: theme.typography.fontWeightBold,\n color: theme.colors.text.primary,\n whiteSpace: 'nowrap',\n }),\n controlButton: css({\n color: theme.colors.text.secondary,\n '&:hover': {\n color: theme.colors.text.primary,\n },\n }),\n});\n"],"names":["AdHocFiltersComboboxRenderer","_a"],"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 { Button, IconButton, Icon, useStyles2, useTheme2 } from '@grafana/ui';\nimport { t } from '@grafana/i18n';\nimport React, { memo, useRef, useState, useEffect } from 'react';\nimport { useMeasure } from 'react-use';\nimport { AdHocFiltersController } from '../controller/AdHocFiltersController';\nimport { AdHocFilterPill } from './AdHocFilterPill';\nimport { AdHocFiltersAlwaysWipCombobox } from './AdHocFiltersAlwaysWipCombobox';\nimport { GroupByPill } from './GroupByPill';\nimport { isGroupByFilter } from '../AdHocFiltersVariable';\nimport { AdHocGroupByRecommendationsRenderer } from '../AdHocFiltersRecommendations';\n\nconst MAX_VISIBLE_FILTERS_DEFAULT = 4;\nconst MAX_VISIBLE_FILTERS_WITH_GROUP_BY = 2;\nconst MAX_VISIBLE_GROUP_BY = 2;\n\ninterface Props {\n controller: AdHocFiltersController;\n}\n\nexport const AdHocFiltersComboboxRenderer = memo(function AdHocFiltersComboboxRenderer({ controller }: Props) {\n const { originFilters, filters, readOnly, collapsible, valueRecommendations, enableGroupBy, groupByRestorable } =\n controller.useState();\n const styles = useStyles2(getStyles);\n const theme = useTheme2();\n const [collapsed, setCollapsed] = useState(true);\n const [wrapperRef, { height: wrapperHeight }] = useMeasure<HTMLDivElement>();\n\n const clearAll = () => {\n controller.clearAll?.();\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 const focusOnGroupByWipInputRef = useRef<() => void>();\n\n // Single line height is approximately minHeight (4 spacing units) + small buffer\n const singleLineThreshold = theme.spacing.gridSize * 5;\n const isMultiLine = collapsible && wrapperHeight > singleLineThreshold;\n\n const handleCollapseToggle = (event: React.MouseEvent) => {\n event.stopPropagation();\n if (collapsible) {\n setCollapsed(true);\n }\n };\n\n const handleExpand = () => {\n if (collapsible && collapsed) {\n setCollapsed(false);\n }\n };\n\n // Combine all visible filters into one array\n const visibleOriginFilters = originFilters?.filter((f) => f.origin && !f.hidden && !f.dismissedGroupBy) ?? [];\n const visibleFilters = filters.filter((f) => !f.hidden);\n const allFilters = [...visibleOriginFilters, ...visibleFilters];\n const totalFiltersCount = allFilters.length;\n\n const adhocFilters = allFilters.filter((f) => !isGroupByFilter(f));\n const groupByFilters = allFilters.filter(isGroupByFilter);\n\n const shouldCollapse = collapsible && collapsed && totalFiltersCount > 0;\n\n const maxVisibleAdhocFilters = enableGroupBy ? MAX_VISIBLE_FILTERS_WITH_GROUP_BY : MAX_VISIBLE_FILTERS_DEFAULT;\n const adhocFiltersToRender = shouldCollapse ? adhocFilters.slice(0, maxVisibleAdhocFilters) : adhocFilters;\n const adhocHiddenCount = shouldCollapse ? Math.max(0, adhocFilters.length - maxVisibleAdhocFilters) : 0;\n\n const groupByFiltersToRender = shouldCollapse ? groupByFilters.slice(0, MAX_VISIBLE_GROUP_BY) : groupByFilters;\n const groupByHiddenCount = shouldCollapse ? Math.max(0, groupByFilters.length - MAX_VISIBLE_GROUP_BY) : 0;\n\n // Reset collapsed state when there are no filters (only when collapsible)\n useEffect(() => {\n if (collapsible && totalFiltersCount === 0 && collapsed) {\n setCollapsed(false);\n }\n }, [collapsible, totalFiltersCount, collapsed]);\n\n // Only show collapse button when expanded and content wraps to multiple lines\n const showCollapseButton = collapsible && isMultiLine && !collapsed;\n const showExpandButton = shouldCollapse && (adhocHiddenCount > 0 || groupByHiddenCount > 0);\n\n return (\n <div\n ref={wrapperRef}\n className={cx(styles.comboboxWrapper, {\n [styles.comboboxFocusOutline]: !readOnly,\n [styles.collapsed]: shouldCollapse,\n })}\n >\n {!readOnly && valueRecommendations && <valueRecommendations.Component model={valueRecommendations} />}\n\n {adhocFiltersToRender.map((filter, index) => (\n <AdHocFilterPill\n key={`${filter.origin ? 'origin-' : ''}${index}-${filter.key}`}\n filter={filter}\n controller={controller}\n readOnly={readOnly || filter.readOnly}\n focusOnWipInputRef={focusOnWipInputRef.current}\n />\n ))}\n\n {shouldCollapse && adhocHiddenCount > 0 && (\n <Button\n className={styles.moreIndicator}\n fill=\"text\"\n size=\"sm\"\n aria-label={t(\n 'grafana-scenes.variables.adhoc-filters-combobox-renderer.show-more-filters',\n 'Show {{count}} more filters',\n { count: adhocHiddenCount }\n )}\n onClick={(e) => {\n e.stopPropagation();\n handleExpand();\n setTimeout(() => focusOnWipInputRef.current?.());\n }}\n >\n +{adhocHiddenCount}\n </Button>\n )}\n\n {!readOnly && (\n <AdHocFiltersAlwaysWipCombobox ref={focusOnWipInputRef} controller={controller} onInputClick={handleExpand} />\n )}\n\n {enableGroupBy && (\n <>\n <div className={styles.sectionDivider} />\n <span className={styles.groupByLabel}>\n {t('grafana-scenes.variables.adhoc-filters-combobox-renderer.group-by-label', 'Group by:')}\n </span>\n {!readOnly && valueRecommendations && <AdHocGroupByRecommendationsRenderer model={valueRecommendations} />}\n\n {groupByFiltersToRender.map((filter, index) => (\n <GroupByPill\n key={`groupby-${index}-${filter.key}`}\n filter={filter}\n controller={controller}\n readOnly={readOnly || filter.readOnly}\n focusOnWipInputRef={focusOnGroupByWipInputRef.current}\n />\n ))}\n\n {shouldCollapse && groupByHiddenCount > 0 && (\n <Button\n className={styles.moreIndicator}\n fill=\"text\"\n size=\"sm\"\n aria-label={t(\n 'grafana-scenes.variables.adhoc-filters-combobox-renderer.show-more-group-by',\n 'Show {{count}} more group by',\n { count: groupByHiddenCount }\n )}\n onClick={(e) => {\n e.stopPropagation();\n handleExpand();\n setTimeout(() => focusOnGroupByWipInputRef.current?.());\n }}\n >\n +{groupByHiddenCount}\n </Button>\n )}\n\n {!readOnly && (\n <AdHocFiltersAlwaysWipCombobox\n ref={focusOnGroupByWipInputRef}\n controller={controller}\n onInputClick={handleExpand}\n isGroupBy\n />\n )}\n\n {groupByRestorable && (\n <IconButton\n name=\"history\"\n size=\"md\"\n className={styles.controlButton}\n tooltip={t(\n 'grafana-scenes.variables.adhoc-filters-combobox-renderer.restore-default-group-by',\n 'Restore groupby set by this dashboard.'\n )}\n onClick={() => controller.restoreOriginalGroupBy?.()}\n />\n )}\n </>\n )}\n\n {/* Right-side controls: collapse button and clear all */}\n {(showCollapseButton || showExpandButton || !readOnly) && (\n <div className={styles.rightControls}>\n <div className={styles.sectionDivider} />\n\n {showCollapseButton && (\n <Button\n className={styles.collapseButton}\n fill=\"text\"\n size=\"sm\"\n onClick={handleCollapseToggle}\n aria-label={t(\n 'grafana-scenes.variables.adhoc-filters-combobox-renderer.collapse-filters',\n 'Collapse filters'\n )}\n aria-expanded={!collapsed}\n >\n {t('grafana-scenes.variables.adhoc-filters-combobox-renderer.collapse', 'Collapse')}\n <Icon name=\"angle-up\" size=\"md\" />\n </Button>\n )}\n\n {showExpandButton && (\n <IconButton\n name=\"angle-down\"\n size=\"md\"\n className={styles.dropdownIndicator}\n tooltip={t('grafana-scenes.variables.adhoc-filters-combobox-renderer.expand-filters', 'Expand filters')}\n onClick={(e) => {\n e.stopPropagation();\n handleExpand();\n }}\n />\n )}\n\n {!readOnly && (\n <IconButton\n name=\"times\"\n size=\"md\"\n className={styles.controlButton}\n tooltip={t('grafana-scenes.variables.adhoc-filters-combobox-renderer.clear-all', 'Clear all')}\n onClick={clearAll}\n />\n )}\n </div>\n )}\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 width: '100%',\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 collapsed: css({\n flexWrap: 'nowrap',\n overflow: 'hidden',\n }),\n rightControls: css({\n display: 'flex',\n alignItems: 'center',\n marginLeft: 'auto',\n flexShrink: 0,\n gap: theme.spacing(1.5),\n }),\n moreIndicator: css({\n color: theme.colors.text.primary,\n background: theme.colors.action.selected,\n height: 'auto',\n lineHeight: 'normal',\n alignSelf: 'stretch',\n '&:hover': {\n background: theme.colors.action.hover,\n },\n }),\n dropdownIndicator: css({\n color: theme.colors.text.secondary,\n flexShrink: 0,\n }),\n collapseButton: css({\n color: theme.colors.text.secondary,\n padding: 0,\n height: 'auto',\n lineHeight: 'normal',\n '&:hover': {\n background: 'transparent',\n color: theme.colors.text.primary,\n },\n }),\n sectionDivider: css({\n width: '1px',\n alignSelf: 'stretch',\n backgroundColor: theme.colors.border.weak,\n flexShrink: 0,\n }),\n groupByLabel: css({\n ...theme.typography.bodySmall,\n fontWeight: theme.typography.fontWeightBold,\n color: theme.colors.text.primary,\n whiteSpace: 'nowrap',\n }),\n controlButton: css({\n color: theme.colors.text.secondary,\n '&:hover': {\n color: theme.colors.text.primary,\n },\n }),\n});\n"],"names":["AdHocFiltersComboboxRenderer","_a"],"mappings":"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"}
@@ -7,11 +7,12 @@ import { getDataSource } from '../../utils/getDataSource.js';
7
7
  import { DrilldownRecommendations } from '../components/DrilldownRecommendations.js';
8
8
  import { ScopesVariable } from '../variants/ScopesVariable.js';
9
9
  import { SCOPES_VARIABLE_NAME } from '../constants.js';
10
- import { AdHocFiltersVariable, isGroupByFilter } from './AdHocFiltersVariable.js';
10
+ import { AdHocFiltersVariable, isGroupByFilter, GROUP_BY_OPERATOR } from './AdHocFiltersVariable.js';
11
11
  import { SceneObjectBase } from '../../core/SceneObjectBase.js';
12
12
  import { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject.js';
13
13
 
14
14
  const getRecentFiltersKey = (datasourceUid) => `grafana.filters.recent.${datasourceUid != null ? datasourceUid : "default"}`;
15
+ const getRecentGroupingKey = (datasourceUid) => `grafana.grouping.recent.${datasourceUid != null ? datasourceUid : "default"}`;
15
16
  function getFilterIdentity(filter) {
16
17
  return `${filter.key}|${filter.operator}|${filter.value}`;
17
18
  }
@@ -26,17 +27,37 @@ function deduplicateFilters(filters) {
26
27
  }
27
28
  return Array.from(filterMap.values());
28
29
  }
30
+ function deduplicateGroupings(groupings) {
31
+ const seen = /* @__PURE__ */ new Map();
32
+ for (const g of groupings) {
33
+ const key = String(g.value);
34
+ if (seen.has(key)) {
35
+ seen.delete(key);
36
+ }
37
+ seen.set(key, g);
38
+ }
39
+ return Array.from(seen.values());
40
+ }
29
41
  class AdHocFiltersRecommendations extends SceneObjectBase {
30
42
  constructor(state = {}) {
31
43
  super(state);
32
44
  this._activationHandler = () => {
33
- const json = store.get(this._getStorageKey());
34
- const storedFilters = json ? JSON.parse(json) : [];
45
+ const filterJson = store.get(this._getFiltersStorageKey());
46
+ const storedFilters = filterJson ? JSON.parse(filterJson) : [];
35
47
  if (storedFilters.length > 0) {
36
48
  this._verifyRecentFiltersApplicability(storedFilters);
37
49
  } else {
38
50
  this.setState({ recentFilters: [] });
39
51
  }
52
+ if (this._isGroupByEnabled) {
53
+ const groupingJson = store.get(this._getGroupingStorageKey());
54
+ const storedGroupings = groupingJson ? JSON.parse(groupingJson) : [];
55
+ if (storedGroupings.length > 0) {
56
+ this._verifyRecentGroupingsApplicability(storedGroupings);
57
+ } else {
58
+ this.setState({ recentGrouping: [] });
59
+ }
60
+ }
40
61
  this._fetchRecommendedDrilldowns();
41
62
  const scopesVariable = sceneGraph.lookupVariable(SCOPES_VARIABLE_NAME, this._adHocFilter);
42
63
  let scopesSubscription;
@@ -45,10 +66,9 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
45
66
  this._subs.add(
46
67
  scopesSubscription = scopesVariable.subscribeToState((newState, prevState) => {
47
68
  if (newState.scopes !== prevState.scopes) {
48
- const json2 = store.get(this._getStorageKey());
49
- const storedFilters2 = json2 ? JSON.parse(json2) : [];
50
- if (storedFilters2.length > 0) {
51
- this._verifyRecentFiltersApplicability(storedFilters2);
69
+ this._reloadStoredFilters();
70
+ if (this._isGroupByEnabled) {
71
+ this._reloadStoredGroupings();
52
72
  }
53
73
  this._fetchRecommendedDrilldowns();
54
74
  }
@@ -58,10 +78,9 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
58
78
  this._subs.add(
59
79
  adHocSubscription = this._adHocFilter.subscribeToState((newState, prevState) => {
60
80
  if (newState.filters !== prevState.filters) {
61
- const json2 = store.get(this._getStorageKey());
62
- const storedFilters2 = json2 ? JSON.parse(json2) : [];
63
- if (storedFilters2.length > 0) {
64
- this._verifyRecentFiltersApplicability(storedFilters2);
81
+ this._reloadStoredFilters();
82
+ if (this._isGroupByEnabled) {
83
+ this._reloadStoredGroupings();
65
84
  }
66
85
  this._fetchRecommendedDrilldowns();
67
86
  }
@@ -83,10 +102,31 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
83
102
  get _scopedVars() {
84
103
  return { __sceneObject: wrapInSafeSerializableSceneObject(this._adHocFilter) };
85
104
  }
86
- _getStorageKey() {
105
+ get _isGroupByEnabled() {
106
+ return this._adHocFilter.state.enableGroupBy === true;
107
+ }
108
+ _reloadStoredFilters() {
109
+ const json = store.get(this._getFiltersStorageKey());
110
+ const storedFilters = json ? JSON.parse(json) : [];
111
+ if (storedFilters.length > 0) {
112
+ this._verifyRecentFiltersApplicability(storedFilters);
113
+ }
114
+ }
115
+ _reloadStoredGroupings() {
116
+ const json = store.get(this._getGroupingStorageKey());
117
+ const storedGroupings = json ? JSON.parse(json) : [];
118
+ if (storedGroupings.length > 0) {
119
+ this._verifyRecentGroupingsApplicability(storedGroupings);
120
+ }
121
+ }
122
+ _getFiltersStorageKey() {
87
123
  var _a;
88
124
  return getRecentFiltersKey((_a = this._adHocFilter.state.datasource) == null ? void 0 : _a.uid);
89
125
  }
126
+ _getGroupingStorageKey() {
127
+ var _a;
128
+ return getRecentGroupingKey((_a = this._adHocFilter.state.datasource) == null ? void 0 : _a.uid);
129
+ }
90
130
  async _fetchRecommendedDrilldowns() {
91
131
  var _a;
92
132
  const adhoc = this._adHocFilter;
@@ -99,7 +139,9 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
99
139
  const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : void 0;
100
140
  const timeRange = sceneGraph.getTimeRange(adhoc).state.value;
101
141
  const scopes = sceneGraph.getScopes(adhoc);
102
- const filters = [...(_a = adhoc.state.originFilters) != null ? _a : [], ...adhoc.state.filters].filter((f) => !isGroupByFilter(f));
142
+ const allFilters = [...(_a = adhoc.state.originFilters) != null ? _a : [], ...adhoc.state.filters];
143
+ const filters = allFilters.filter((f) => !isGroupByFilter(f));
144
+ const groupByKeys = this._isGroupByEnabled ? allFilters.filter((f) => isGroupByFilter(f)).map((f) => f.key) : void 0;
103
145
  const enrichedRequest = getEnrichedDataRequest(adhoc);
104
146
  const dashboardUid = enrichedRequest == null ? void 0 : enrichedRequest.dashboardUID;
105
147
  try {
@@ -108,11 +150,20 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
108
150
  dashboardUid,
109
151
  queries: queries != null ? queries : [],
110
152
  filters,
153
+ ...groupByKeys ? { groupByKeys } : {},
111
154
  scopes
112
155
  });
156
+ const stateUpdate = {};
113
157
  if (recommendedDrilldowns == null ? void 0 : recommendedDrilldowns.filters) {
114
- this.setState({ recommendedFilters: recommendedDrilldowns.filters });
158
+ stateUpdate.recommendedFilters = recommendedDrilldowns.filters;
159
+ }
160
+ if (this._isGroupByEnabled && (recommendedDrilldowns == null ? void 0 : recommendedDrilldowns.groupByKeys)) {
161
+ stateUpdate.recommendedGrouping = recommendedDrilldowns.groupByKeys.map((key) => ({
162
+ value: key,
163
+ text: key
164
+ }));
115
165
  }
166
+ this.setState(stateUpdate);
116
167
  } catch (error) {
117
168
  console.error("Failed to fetch recommended drilldowns:", error);
118
169
  }
@@ -137,12 +188,35 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
137
188
  const recentFilters = deduplicateFilters(applicableFilters).slice(-3);
138
189
  this.setState({ recentFilters });
139
190
  }
191
+ async _verifyRecentGroupingsApplicability(storedGroupings) {
192
+ const adhoc = this._adHocFilter;
193
+ const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : void 0;
194
+ const groupByFilters = storedGroupings.map((g) => ({
195
+ key: String(g.value),
196
+ operator: GROUP_BY_OPERATOR,
197
+ value: "",
198
+ condition: ""
199
+ }));
200
+ const response = await adhoc.getFiltersApplicabilityForQueries(groupByFilters, queries != null ? queries : []);
201
+ if (!response) {
202
+ this.setState({ recentGrouping: deduplicateGroupings(storedGroupings).slice(-3) });
203
+ return;
204
+ }
205
+ const applicabilityMap = /* @__PURE__ */ new Map();
206
+ response.forEach((item) => {
207
+ applicabilityMap.set(item.key, item.applicable !== false);
208
+ });
209
+ const applicableGroupings = deduplicateGroupings(storedGroupings).filter((g) => {
210
+ const isApplicable = applicabilityMap.get(String(g.value));
211
+ return isApplicable === void 0 || isApplicable === true;
212
+ }).slice(-3);
213
+ this.setState({ recentGrouping: applicableGroupings });
214
+ }
140
215
  /**
141
216
  * Stores a recent filter in localStorage and updates state.
142
- * Should be called by the parent variable when a filter is added/updated.
143
217
  */
144
218
  storeRecentFilter(filter) {
145
- const key = this._getStorageKey();
219
+ const key = this._getFiltersStorageKey();
146
220
  const storedFilters = store.get(key);
147
221
  const allRecentFilters = storedFilters ? JSON.parse(storedFilters) : [];
148
222
  const updatedStoredFilters = deduplicateFilters([...allRecentFilters, filter]).slice(-10);
@@ -153,9 +227,37 @@ class AdHocFiltersRecommendations extends SceneObjectBase {
153
227
  this.setState({ recentFilters: updatedStoredFilters.slice(-3) });
154
228
  }
155
229
  }
230
+ /**
231
+ * Stores a recent grouping key in localStorage and updates state.
232
+ * No-op when enableGroupBy is false.
233
+ */
234
+ storeRecentGrouping(groupByKey) {
235
+ if (!this._isGroupByEnabled) {
236
+ return;
237
+ }
238
+ const storageKey = this._getGroupingStorageKey();
239
+ const storedGroupings = store.get(storageKey);
240
+ const allRecentGroupings = storedGroupings ? JSON.parse(storedGroupings) : [];
241
+ const withoutDuplicate = allRecentGroupings.filter((g) => String(g.value) !== groupByKey);
242
+ const updated = [...withoutDuplicate, { value: groupByKey, text: groupByKey }];
243
+ const limited = updated.slice(-10);
244
+ store.set(storageKey, JSON.stringify(limited));
245
+ this.setState({ recentGrouping: limited.slice(-3) });
246
+ }
156
247
  addFilterToParent(filter) {
157
248
  this._adHocFilter.updateFilters([...this._adHocFilter.state.filters, filter]);
158
249
  }
250
+ addGroupByToParent(key) {
251
+ if (!this._isGroupByEnabled) {
252
+ return;
253
+ }
254
+ const adhoc = this._adHocFilter;
255
+ const exists = adhoc.state.filters.some((f) => isGroupByFilter(f) && f.key === key);
256
+ if (exists) {
257
+ return;
258
+ }
259
+ adhoc._addGroupByFilter({ value: key, label: key });
260
+ }
159
261
  }
160
262
  AdHocFiltersRecommendations.Component = AdHocFiltersRecommendationsRenderer;
161
263
  function AdHocFiltersRecommendationsRenderer({ model }) {
@@ -188,6 +290,29 @@ function AdHocFiltersRecommendationsRenderer({ model }) {
188
290
  }
189
291
  );
190
292
  }
293
+ function AdHocGroupByRecommendationsRenderer({ model }) {
294
+ const { recentGrouping, recommendedGrouping, datasourceSupportsRecommendations } = model.useState();
295
+ const recentDrilldowns = recentGrouping == null ? void 0 : recentGrouping.map((groupBy) => ({
296
+ label: `${groupBy.value}`,
297
+ onClick: () => {
298
+ model.addGroupByToParent(String(groupBy.value));
299
+ }
300
+ }));
301
+ const recommendedDrilldowns = recommendedGrouping == null ? void 0 : recommendedGrouping.map((groupBy) => ({
302
+ label: `${groupBy.value}`,
303
+ onClick: () => {
304
+ model.addGroupByToParent(String(groupBy.value));
305
+ }
306
+ }));
307
+ return /* @__PURE__ */ React.createElement(
308
+ DrilldownRecommendations,
309
+ {
310
+ recentDrilldowns,
311
+ recommendedDrilldowns,
312
+ showRecommended: datasourceSupportsRecommendations
313
+ }
314
+ );
315
+ }
191
316
 
192
- export { AdHocFiltersRecommendations, getRecentFiltersKey };
317
+ export { AdHocFiltersRecommendations, AdHocGroupByRecommendationsRenderer, getRecentFiltersKey, getRecentGroupingKey };
193
318
  //# sourceMappingURL=AdHocFiltersRecommendations.js.map
@@ -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, isGroupByFilter } 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 datasourceSupportsRecommendations?: boolean;\n}\n\n/**\n * Keeps only the last occurrence of each unique (key, operator, value) triple,\n * preserving the most-recent-wins ordering.\n */\nfunction getFilterIdentity(filter: AdHocFilterWithLabels): string {\n return `${filter.key}|${filter.operator}|${filter.value}`;\n}\n\nfunction deduplicateFilters(filters: AdHocFilterWithLabels[]): AdHocFilterWithLabels[] {\n const filterMap = new Map<string, AdHocFilterWithLabels>();\n\n for (const filter of filters) {\n const identity = getFilterIdentity(filter);\n // Re-insert duplicates so the last occurrence is kept at the latest position.\n if (filterMap.has(identity)) {\n filterMap.delete(identity);\n }\n filterMap.set(identity, filter);\n }\n\n return Array.from(filterMap.values());\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 this.setState({ datasourceSupportsRecommendations: false });\n return;\n }\n\n this.setState({ datasourceSupportsRecommendations: true });\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].filter((f) => !isGroupByFilter(f));\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 const deduped = deduplicateFilters(storedFilters);\n this.setState({ recentFilters: deduped.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.filter((f) => {\n const isApplicable = applicabilityMap.get(f.key);\n return isApplicable === undefined || isApplicable === true;\n });\n\n const recentFilters = deduplicateFilters(applicableFilters).slice(-MAX_RECENT_DRILLDOWNS);\n\n this.setState({ recentFilters });\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 = deduplicateFilters([...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, datasourceSupportsRecommendations } = 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 (\n <DrilldownRecommendations\n recentDrilldowns={recentDrilldowns}\n recommendedDrilldowns={recommendedDrilldowns}\n showRecommended={datasourceSupportsRecommendations}\n />\n );\n}\n"],"names":["json","storedFilters"],"mappings":";;;;;;;;;;;;;AAsBO,MAAM,mBAAsB,GAAA,CAAC,aAClC,KAAA,CAAA,uBAAA,EAA0B,wCAAiB,SAAS,CAAA;AAYtD,SAAS,kBAAkB,MAAuC,EAAA;AAChE,EAAO,OAAA,CAAA,EAAG,OAAO,GAAG,CAAA,CAAA,EAAI,OAAO,QAAQ,CAAA,CAAA,EAAI,OAAO,KAAK,CAAA,CAAA;AACzD;AAEA,SAAS,mBAAmB,OAA2D,EAAA;AACrF,EAAM,MAAA,SAAA,uBAAgB,GAAmC,EAAA;AAEzD,EAAA,KAAA,MAAW,UAAU,OAAS,EAAA;AAC5B,IAAM,MAAA,QAAA,GAAW,kBAAkB,MAAM,CAAA;AAEzC,IAAI,IAAA,SAAA,CAAU,GAAI,CAAA,QAAQ,CAAG,EAAA;AAC3B,MAAA,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA;AAE3B,IAAU,SAAA,CAAA,GAAA,CAAI,UAAU,MAAM,CAAA;AAAA;AAGhC,EAAA,OAAO,KAAM,CAAA,IAAA,CAAK,SAAU,CAAA,MAAA,EAAQ,CAAA;AACtC;AAEO,MAAM,oCAAoC,eAAkD,CAAA;AAAA,EAG1F,WAAA,CAAY,KAAmD,GAAA,EAAI,EAAA;AACxE,IAAA,KAAA,CAAM,KAAK,CAAA;AAiBb,IAAA,IAAA,CAAQ,qBAAqB,MAAM;AACjC,MAAA,MAAM,IAAO,GAAA,KAAA,CAAM,GAAI,CAAA,IAAA,CAAK,gBAAgB,CAAA;AAC5C,MAAA,MAAM,gBAAgB,IAAO,GAAA,IAAA,CAAK,KAAM,CAAA,IAAI,IAAI,EAAC;AAEjD,MAAI,IAAA,aAAA,CAAc,SAAS,CAAG,EAAA;AAC5B,QAAA,IAAA,CAAK,kCAAkC,aAAa,CAAA;AAAA,OAC/C,MAAA;AACL,QAAA,IAAA,CAAK,QAAS,CAAA,EAAE,aAAe,EAAA,IAAI,CAAA;AAAA;AAGrC,MAAA,IAAA,CAAK,2BAA4B,EAAA;AAGjC,MAAA,MAAM,cAAiB,GAAA,UAAA,CAAW,cAAe,CAAA,oBAAA,EAAsB,KAAK,YAAY,CAAA;AACxF,MAAI,IAAA,kBAAA;AACJ,MAAI,IAAA,iBAAA;AAEJ,MAAA,IAAI,0BAA0B,cAAgB,EAAA;AAC5C,QAAA,IAAA,CAAK,KAAM,CAAA,GAAA;AAAA,UACR,kBAAqB,GAAA,cAAA,CAAe,gBAAiB,CAAA,CAAC,UAAU,SAAc,KAAA;AAC7E,YAAI,IAAA,QAAA,CAAS,MAAW,KAAA,SAAA,CAAU,MAAQ,EAAA;AACxC,cAAA,MAAMA,KAAO,GAAA,KAAA,CAAM,GAAI,CAAA,IAAA,CAAK,gBAAgB,CAAA;AAC5C,cAAA,MAAMC,iBAAgBD,KAAO,GAAA,IAAA,CAAK,KAAMA,CAAAA,KAAI,IAAI,EAAC;AAEjD,cAAIC,IAAAA,cAAAA,CAAc,SAAS,CAAG,EAAA;AAC5B,gBAAA,IAAA,CAAK,kCAAkCA,cAAa,CAAA;AAAA;AAGtD,cAAA,IAAA,CAAK,2BAA4B,EAAA;AAAA;AACnC,WACD;AAAA,SACH;AAAA;AAGF,MAAA,IAAA,CAAK,KAAM,CAAA,GAAA;AAAA,QACR,oBAAoB,IAAK,CAAA,YAAA,CAAa,gBAAiB,CAAA,CAAC,UAAU,SAAc,KAAA;AAC/E,UAAI,IAAA,QAAA,CAAS,OAAY,KAAA,SAAA,CAAU,OAAS,EAAA;AAC1C,YAAA,MAAMD,KAAO,GAAA,KAAA,CAAM,GAAI,CAAA,IAAA,CAAK,gBAAgB,CAAA;AAC5C,YAAA,MAAMC,iBAAgBD,KAAO,GAAA,IAAA,CAAK,KAAMA,CAAAA,KAAI,IAAI,EAAC;AAEjD,YAAIC,IAAAA,cAAAA,CAAc,SAAS,CAAG,EAAA;AAC5B,cAAA,IAAA,CAAK,kCAAkCA,cAAa,CAAA;AAAA;AAGtD,YAAA,IAAA,CAAK,2BAA4B,EAAA;AAAA;AACnC,SACD;AAAA,OACH;AAEA,MAAA,OAAO,MAAM;AACX,QAAoB,kBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,kBAAA,CAAA,WAAA,EAAA;AACpB,QAAmB,iBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,iBAAA,CAAA,WAAA,EAAA;AAAA,OACrB;AAAA,KACF;AApEE,IAAK,IAAA,CAAA,oBAAA,CAAqB,KAAK,kBAAkB,CAAA;AAAA;AACnD,EAEA,IAAW,YAAqC,GAAA;AAC9C,IAAI,IAAA,EAAE,IAAK,CAAA,MAAA,YAAkB,oBAAuB,CAAA,EAAA;AAClD,MAAM,MAAA,IAAI,MAAM,qEAAqE,CAAA;AAAA;AAGvF,IAAA,OAAO,IAAK,CAAA,MAAA;AAAA;AACd,EAEA,IAAY,WAAc,GAAA;AACxB,IAAA,OAAO,EAAE,aAAA,EAAe,iCAAkC,CAAA,IAAA,CAAK,YAAY,CAAE,EAAA;AAAA;AAC/E,EAyDQ,cAAyB,GAAA;AAlInC,IAAA,IAAA,EAAA;AAmII,IAAA,OAAO,qBAAoB,EAAK,GAAA,IAAA,CAAA,YAAA,CAAa,KAAM,CAAA,UAAA,KAAxB,mBAAoC,GAAG,CAAA;AAAA;AACpE,EAEA,MAAc,2BAA8B,GAAA;AAtI9C,IAAA,IAAA,EAAA;AAuII,IAAA,MAAM,QAAQ,IAAK,CAAA,YAAA;AACnB,IAAA,MAAM,KAAK,MAAM,aAAA,CAAc,MAAM,KAAM,CAAA,UAAA,EAAY,KAAK,WAAW,CAAA;AAGvE,IAAA,IAAI,CAAC,EAAA,IAAM,CAAC,EAAA,CAAG,wBAA0B,EAAA;AACvC,MAAA,IAAA,CAAK,QAAS,CAAA,EAAE,iCAAmC,EAAA,KAAA,EAAO,CAAA;AAC1D,MAAA;AAAA;AAGF,IAAA,IAAA,CAAK,QAAS,CAAA,EAAE,iCAAmC,EAAA,IAAA,EAAM,CAAA;AAEzD,IAAA,MAAM,UAAU,KAAM,CAAA,KAAA,CAAM,4BAA+B,GAAA,sBAAA,CAAuB,KAAK,CAAI,GAAA,MAAA;AAC3F,IAAA,MAAM,SAAY,GAAA,UAAA,CAAW,YAAa,CAAA,KAAK,EAAE,KAAM,CAAA,KAAA;AACvD,IAAM,MAAA,MAAA,GAAS,UAAW,CAAA,SAAA,CAAU,KAAK,CAAA;AACzC,IAAM,MAAA,OAAA,GAAU,CAAC,GAAI,CAAA,EAAA,GAAA,KAAA,CAAM,MAAM,aAAZ,KAAA,IAAA,GAAA,EAAA,GAA6B,EAAK,EAAA,GAAG,MAAM,KAAM,CAAA,OAAO,EAAE,MAAO,CAAA,CAAC,MAAM,CAAC,eAAA,CAAgB,CAAC,CAAC,CAAA;AAEhH,IAAM,MAAA,eAAA,GAAkB,uBAAuB,KAAK,CAAA;AACpD,IAAA,MAAM,eAAe,eAAiB,IAAA,IAAA,GAAA,MAAA,GAAA,eAAA,CAAA,YAAA;AAEtC,IAAI,IAAA;AAEF,MAAM,MAAA,qBAAA,GAAwB,MAAM,EAAA,CAAG,wBAAyB,CAAA;AAAA,QAC9D,SAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAA,EAAS,4BAAW,EAAC;AAAA,QACrB,OAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,IAAI,+DAAuB,OAAS,EAAA;AAClC,QAAA,IAAA,CAAK,QAAS,CAAA,EAAE,kBAAoB,EAAA,qBAAA,CAAsB,SAAS,CAAA;AAAA;AACrE,aACO,KAAO,EAAA;AACd,MAAQ,OAAA,CAAA,KAAA,CAAM,2CAA2C,KAAK,CAAA;AAAA;AAChE;AACF,EAEA,MAAc,kCAAkC,aAAwC,EAAA;AACtF,IAAA,MAAM,QAAQ,IAAK,CAAA,YAAA;AACnB,IAAA,MAAM,UAAU,KAAM,CAAA,KAAA,CAAM,4BAA+B,GAAA,sBAAA,CAAuB,KAAK,CAAI,GAAA,MAAA;AAC3F,IAAA,MAAM,WAAW,MAAM,KAAA,CAAM,kCAAkC,aAAe,EAAA,OAAA,IAAA,IAAA,GAAA,OAAA,GAAW,EAAE,CAAA;AAE3F,IAAA,IAAI,CAAC,QAAU,EAAA;AACb,MAAM,MAAA,OAAA,GAAU,mBAAmB,aAAa,CAAA;AAChD,MAAK,IAAA,CAAA,QAAA,CAAS,EAAE,aAAe,EAAA,OAAA,CAAQ,MAAM,EAAsB,GAAG,CAAA;AACtE,MAAA;AAAA;AAGF,IAAM,MAAA,gBAAA,uBAAuB,GAAqB,EAAA;AAClD,IAAS,QAAA,CAAA,OAAA,CAAQ,CAAC,IAAkC,KAAA;AAClD,MAAA,gBAAA,CAAiB,GAAI,CAAA,IAAA,CAAK,GAAK,EAAA,IAAA,CAAK,eAAe,KAAK,CAAA;AAAA,KACzD,CAAA;AAED,IAAA,MAAM,iBAAoB,GAAA,aAAA,CAAc,MAAO,CAAA,CAAC,CAAM,KAAA;AACpD,MAAA,MAAM,YAAe,GAAA,gBAAA,CAAiB,GAAI,CAAA,CAAA,CAAE,GAAG,CAAA;AAC/C,MAAO,OAAA,YAAA,KAAiB,UAAa,YAAiB,KAAA,IAAA;AAAA,KACvD,CAAA;AAED,IAAA,MAAM,gBAAgB,kBAAmB,CAAA,iBAAiB,CAAE,CAAA,KAAA,CAAM,EAAsB,CAAA;AAExF,IAAK,IAAA,CAAA,QAAA,CAAS,EAAE,aAAA,EAAe,CAAA;AAAA;AACjC;AAAA;AAAA;AAAA;AAAA,EAMO,kBAAkB,MAA+B,EAAA;AACtD,IAAM,MAAA,GAAA,GAAM,KAAK,cAAe,EAAA;AAChC,IAAM,MAAA,aAAA,GAAgB,KAAM,CAAA,GAAA,CAAI,GAAG,CAAA;AACnC,IAAA,MAAM,mBAAmB,aAAgB,GAAA,IAAA,CAAK,KAAM,CAAA,aAAa,IAAI,EAAC;AAEtE,IAAM,MAAA,oBAAA,GAAuB,kBAAmB,CAAA,CAAC,GAAG,gBAAA,EAAkB,MAAM,CAAC,CAAA,CAAE,KAAM,CAAA,GAA6B,CAAA;AAClH,IAAA,KAAA,CAAM,GAAI,CAAA,GAAA,EAAK,IAAK,CAAA,SAAA,CAAU,oBAAoB,CAAC,CAAA;AAEnD,IAAA,MAAM,QAAQ,IAAK,CAAA,YAAA;AACnB,IAAA,MAAM,cAAiB,GAAA,KAAA,CAAM,KAAM,CAAA,OAAA,CAAQ,KAAK,CAAC,CAAA,KAAM,CAAE,CAAA,GAAA,KAAQ,OAAO,GAAO,IAAA,CAAC,OAAQ,CAAA,CAAA,CAAE,aAAa,CAAC,CAAA;AACxG,IAAA,IAAI,cAAkB,IAAA,CAAC,OAAQ,CAAA,cAAA,CAAe,aAAa,CAAG,EAAA;AAC5D,MAAK,IAAA,CAAA,QAAA,CAAS,EAAE,aAAe,EAAA,oBAAA,CAAqB,MAAM,EAAsB,GAAG,CAAA;AAAA;AACrF;AACF,EAEO,kBAAkB,MAA+B,EAAA;AACtD,IAAK,IAAA,CAAA,YAAA,CAAa,cAAc,CAAC,GAAG,KAAK,YAAa,CAAA,KAAA,CAAM,OAAS,EAAA,MAAM,CAAC,CAAA;AAAA;AAEhF;AAtKa,2BAAA,CACJ,SAAY,GAAA,mCAAA;AAuKrB,SAAS,mCAAA,CAAoC,EAAE,KAAA,EAA2D,EAAA;AACxG,EAAA,MAAM,EAAE,aAAe,EAAA,kBAAA,EAAoB,iCAAkC,EAAA,GAAI,MAAM,QAAS,EAAA;AAChG,EAAA,MAAM,EAAE,OAAA,EAAY,GAAA,KAAA,CAAM,aAAa,QAAS,EAAA;AAEhD,EAAA,MAAM,gBAAgD,GAAA,aAAA,IAAA,IAAA,GAAA,MAAA,GAAA,aAAA,CAAe,GAAI,CAAA,CAAC,MAAY,MAAA;AAAA,IACpF,KAAA,EAAO,GAAG,MAAO,CAAA,GAAG,IAAI,MAAO,CAAA,QAAQ,CAAI,CAAA,EAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAAA,IACvD,SAAS,MAAM;AACb,MAAA,MAAM,MAAS,GAAA,OAAA,CAAQ,IAAK,CAAA,CAAC,CAAM,KAAA,CAAA,CAAE,GAAQ,KAAA,MAAA,CAAO,GAAO,IAAA,CAAA,CAAE,KAAU,KAAA,MAAA,CAAO,KAAK,CAAA;AACnF,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAA,KAAA,CAAM,kBAAkB,MAAM,CAAA;AAAA;AAChC;AACF,GACF,CAAA,CAAA;AAEA,EAAA,MAAM,qBAAqD,GAAA,kBAAA,IAAA,IAAA,GAAA,MAAA,GAAA,kBAAA,CAAoB,GAAI,CAAA,CAAC,MAAY,MAAA;AAAA,IAC9F,KAAA,EAAO,GAAG,MAAO,CAAA,GAAG,IAAI,MAAO,CAAA,QAAQ,CAAI,CAAA,EAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAAA,IACvD,SAAS,MAAM;AACb,MAAA,MAAM,MAAS,GAAA,OAAA,CAAQ,IAAK,CAAA,CAAC,CAAM,KAAA,CAAA,CAAE,GAAQ,KAAA,MAAA,CAAO,GAAO,IAAA,CAAA,CAAE,KAAU,KAAA,MAAA,CAAO,KAAK,CAAA;AACnF,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAA,KAAA,CAAM,kBAAkB,MAAM,CAAA;AAAA;AAChC;AACF,GACF,CAAA,CAAA;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,wBAAA;AAAA,IAAA;AAAA,MACC,gBAAA;AAAA,MACA,qBAAA;AAAA,MACA,eAAiB,EAAA;AAAA;AAAA,GACnB;AAEJ;;;;"}
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 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 {\n AdHocFilterWithLabels,\n AdHocFiltersVariable,\n GROUP_BY_OPERATOR,\n isGroupByFilter,\n} from './AdHocFiltersVariable';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObjectState } from '../../core/types';\nimport { wrapInSafeSerializableSceneObject } from '../../utils/wrapInSafeSerializableSceneObject';\nimport { VariableValueSingle } from '../types';\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 const getRecentGroupingKey = (datasourceUid: string | undefined) =>\n `grafana.grouping.recent.${datasourceUid ?? 'default'}`;\n\nexport interface AdHocFiltersRecommendationsState extends SceneObjectState {\n recentFilters?: AdHocFilterWithLabels[];\n recommendedFilters?: AdHocFilterWithLabels[];\n recentGrouping?: Array<SelectableValue<VariableValueSingle>>;\n recommendedGrouping?: Array<SelectableValue<VariableValueSingle>>;\n datasourceSupportsRecommendations?: boolean;\n}\n\n/**\n * Keeps only the last occurrence of each unique (key, operator, value) triple,\n * preserving the most-recent-wins ordering.\n */\nfunction getFilterIdentity(filter: AdHocFilterWithLabels): string {\n return `${filter.key}|${filter.operator}|${filter.value}`;\n}\n\nfunction deduplicateFilters(filters: AdHocFilterWithLabels[]): AdHocFilterWithLabels[] {\n const filterMap = new Map<string, AdHocFilterWithLabels>();\n\n for (const filter of filters) {\n const identity = getFilterIdentity(filter);\n if (filterMap.has(identity)) {\n filterMap.delete(identity);\n }\n filterMap.set(identity, filter);\n }\n\n return Array.from(filterMap.values());\n}\n\nfunction deduplicateGroupings(\n groupings: Array<SelectableValue<VariableValueSingle>>\n): Array<SelectableValue<VariableValueSingle>> {\n const seen = new Map<string, SelectableValue<VariableValueSingle>>();\n\n for (const g of groupings) {\n const key = String(g.value);\n if (seen.has(key)) {\n seen.delete(key);\n }\n seen.set(key, g);\n }\n\n return Array.from(seen.values());\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 get _isGroupByEnabled(): boolean {\n return this._adHocFilter.state.enableGroupBy === true;\n }\n\n private _activationHandler = () => {\n const filterJson = store.get(this._getFiltersStorageKey());\n const storedFilters = filterJson ? JSON.parse(filterJson) : [];\n\n if (storedFilters.length > 0) {\n this._verifyRecentFiltersApplicability(storedFilters);\n } else {\n this.setState({ recentFilters: [] });\n }\n\n if (this._isGroupByEnabled) {\n const groupingJson = store.get(this._getGroupingStorageKey());\n const storedGroupings = groupingJson ? JSON.parse(groupingJson) : [];\n\n if (storedGroupings.length > 0) {\n this._verifyRecentGroupingsApplicability(storedGroupings);\n } else {\n this.setState({ recentGrouping: [] });\n }\n }\n\n this._fetchRecommendedDrilldowns();\n\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 this._reloadStoredFilters();\n if (this._isGroupByEnabled) {\n this._reloadStoredGroupings();\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 this._reloadStoredFilters();\n if (this._isGroupByEnabled) {\n this._reloadStoredGroupings();\n }\n this._fetchRecommendedDrilldowns();\n }\n }))\n );\n\n return () => {\n scopesSubscription?.unsubscribe();\n adHocSubscription?.unsubscribe();\n };\n };\n\n private _reloadStoredFilters() {\n const json = store.get(this._getFiltersStorageKey());\n const storedFilters = json ? JSON.parse(json) : [];\n if (storedFilters.length > 0) {\n this._verifyRecentFiltersApplicability(storedFilters);\n }\n }\n\n private _reloadStoredGroupings() {\n const json = store.get(this._getGroupingStorageKey());\n const storedGroupings = json ? JSON.parse(json) : [];\n if (storedGroupings.length > 0) {\n this._verifyRecentGroupingsApplicability(storedGroupings);\n }\n }\n\n private _getFiltersStorageKey(): string {\n return getRecentFiltersKey(this._adHocFilter.state.datasource?.uid);\n }\n\n private _getGroupingStorageKey(): string {\n return getRecentGroupingKey(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 this.setState({ datasourceSupportsRecommendations: false });\n return;\n }\n\n this.setState({ datasourceSupportsRecommendations: true });\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\n const allFilters = [...(adhoc.state.originFilters ?? []), ...adhoc.state.filters];\n const filters = allFilters.filter((f) => !isGroupByFilter(f));\n const groupByKeys = this._isGroupByEnabled\n ? allFilters.filter((f) => isGroupByFilter(f)).map((f) => f.key)\n : undefined;\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 ...(groupByKeys ? { groupByKeys } : {}),\n scopes,\n });\n\n const stateUpdate: Partial<AdHocFiltersRecommendationsState> = {};\n\n if (recommendedDrilldowns?.filters) {\n stateUpdate.recommendedFilters = recommendedDrilldowns.filters;\n }\n\n if (this._isGroupByEnabled && recommendedDrilldowns?.groupByKeys) {\n stateUpdate.recommendedGrouping = recommendedDrilldowns.groupByKeys.map((key: string) => ({\n value: key,\n text: key,\n }));\n }\n\n this.setState(stateUpdate);\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 const deduped = deduplicateFilters(storedFilters);\n this.setState({ recentFilters: deduped.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.filter((f) => {\n const isApplicable = applicabilityMap.get(f.key);\n return isApplicable === undefined || isApplicable === true;\n });\n\n const recentFilters = deduplicateFilters(applicableFilters).slice(-MAX_RECENT_DRILLDOWNS);\n\n this.setState({ recentFilters });\n }\n\n private async _verifyRecentGroupingsApplicability(storedGroupings: Array<SelectableValue<VariableValueSingle>>) {\n const adhoc = this._adHocFilter;\n const queries = adhoc.state.useQueriesAsFilterForOptions ? getQueriesForVariables(adhoc) : undefined;\n\n const groupByFilters: AdHocFilterWithLabels[] = storedGroupings.map((g) => ({\n key: String(g.value),\n operator: GROUP_BY_OPERATOR,\n value: '',\n condition: '',\n }));\n\n const response = await adhoc.getFiltersApplicabilityForQueries(groupByFilters, queries ?? []);\n\n if (!response) {\n this.setState({ recentGrouping: deduplicateGroupings(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 = deduplicateGroupings(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 a recent filter in localStorage and updates state.\n */\n public storeRecentFilter(filter: AdHocFilterWithLabels) {\n const key = this._getFiltersStorageKey();\n const storedFilters = store.get(key);\n const allRecentFilters = storedFilters ? JSON.parse(storedFilters) : [];\n\n const updatedStoredFilters = deduplicateFilters([...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 /**\n * Stores a recent grouping key in localStorage and updates state.\n * No-op when enableGroupBy is false.\n */\n public storeRecentGrouping(groupByKey: string) {\n if (!this._isGroupByEnabled) {\n return;\n }\n\n const storageKey = this._getGroupingStorageKey();\n const storedGroupings = store.get(storageKey);\n const allRecentGroupings: Array<SelectableValue<VariableValueSingle>> = storedGroupings\n ? JSON.parse(storedGroupings)\n : [];\n\n const withoutDuplicate = allRecentGroupings.filter((g) => String(g.value) !== groupByKey);\n const updated = [...withoutDuplicate, { value: groupByKey, text: groupByKey }];\n const limited = updated.slice(-MAX_STORED_RECENT_DRILLDOWNS);\n\n store.set(storageKey, JSON.stringify(limited));\n\n this.setState({ recentGrouping: limited.slice(-MAX_RECENT_DRILLDOWNS) });\n }\n\n public addFilterToParent(filter: AdHocFilterWithLabels) {\n this._adHocFilter.updateFilters([...this._adHocFilter.state.filters, filter]);\n }\n\n public addGroupByToParent(key: string) {\n if (!this._isGroupByEnabled) {\n return;\n }\n\n const adhoc = this._adHocFilter;\n const exists = adhoc.state.filters.some((f) => isGroupByFilter(f) && f.key === key);\n if (exists) {\n return;\n }\n\n adhoc._addGroupByFilter({ value: key, label: key });\n }\n}\n\nfunction AdHocFiltersRecommendationsRenderer({ model }: SceneComponentProps<AdHocFiltersRecommendations>) {\n const { recentFilters, recommendedFilters, datasourceSupportsRecommendations } = 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 (\n <DrilldownRecommendations\n recentDrilldowns={recentDrilldowns}\n recommendedDrilldowns={recommendedDrilldowns}\n showRecommended={datasourceSupportsRecommendations}\n />\n );\n}\n\nexport function AdHocGroupByRecommendationsRenderer({ model }: SceneComponentProps<AdHocFiltersRecommendations>) {\n const { recentGrouping, recommendedGrouping, datasourceSupportsRecommendations } = model.useState();\n\n const recentDrilldowns: DrilldownPill[] | undefined = recentGrouping?.map((groupBy) => ({\n label: `${groupBy.value}`,\n onClick: () => {\n model.addGroupByToParent(String(groupBy.value));\n },\n }));\n\n const recommendedDrilldowns: DrilldownPill[] | undefined = recommendedGrouping?.map((groupBy) => ({\n label: `${groupBy.value}`,\n onClick: () => {\n model.addGroupByToParent(String(groupBy.value));\n },\n }));\n\n return (\n <DrilldownRecommendations\n recentDrilldowns={recentDrilldowns}\n recommendedDrilldowns={recommendedDrilldowns}\n showRecommended={datasourceSupportsRecommendations}\n />\n );\n}\n"],"names":[],"mappings":"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"}
@@ -257,7 +257,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
257
257
  * No-op when enableGroupBy is false.
258
258
  */
259
259
  _addGroupByFilter(item) {
260
- var _a, _b;
260
+ var _a, _b, _c;
261
261
  if (!this.state.enableGroupBy) {
262
262
  return;
263
263
  }
@@ -270,6 +270,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
270
270
  value: "",
271
271
  condition: ""
272
272
  };
273
+ (_c = this._recommendations) == null ? void 0 : _c.storeRecentGrouping(key);
273
274
  this.updateFilters([...this.state.filters, newFilter]);
274
275
  }
275
276
  restoreOriginalFilter(filter) {
@@ -403,7 +404,7 @@ class AdHocFiltersVariable extends SceneObjectBase {
403
404
  return this.state.filterExpression;
404
405
  }
405
406
  _updateFilter(filter, update) {
406
- var _a, _b, _c, _d, _e;
407
+ var _a, _b, _c, _d, _e, _f;
407
408
  const { originFilters, filters, _wip } = this.state;
408
409
  if ("value" in update && !("values" in update)) {
409
410
  update = { ...update, values: void 0 };
@@ -473,10 +474,12 @@ class AdHocFiltersVariable extends SceneObjectBase {
473
474
  return f === filter ? { ...f, ...update } : f;
474
475
  });
475
476
  this.setState({ filters: updatedFilters });
476
- (_e = this._recommendations) == null ? void 0 : _e.storeRecentFilter({
477
- ...filter,
478
- ...update
479
- });
477
+ const merged = { ...filter, ...update };
478
+ if (isGroupByFilter(merged)) {
479
+ (_e = this._recommendations) == null ? void 0 : _e.storeRecentGrouping(merged.key);
480
+ } else {
481
+ (_f = this._recommendations) == null ? void 0 : _f.storeRecentFilter(merged);
482
+ }
480
483
  }
481
484
  updateToMatchAll(filter) {
482
485
  var _a;