Dashboards: AdHoc and GroupBy wrapper (#115124)
Some checks are pending
Actionlint / Lint GitHub Actions files (push) Waiting to run
Backend Code Checks / Detect whether code changed (push) Waiting to run
Backend Code Checks / Validate Backend Configs (push) Blocked by required conditions
Backend Unit Tests / Detect whether code changed (push) Waiting to run
Backend Unit Tests / Grafana (1/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (2/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (3/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (4/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (5/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (6/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (7/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (8/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (1/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (2/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (3/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (4/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (5/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (6/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (7/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (8/8) (push) Blocked by required conditions
Backend Unit Tests / All backend unit tests complete (push) Blocked by required conditions
CodeQL checks / Detect whether code changed (push) Waiting to run
CodeQL checks / Analyze (push) Blocked by required conditions
Lint Frontend / Detect whether code changed (push) Waiting to run
Lint Frontend / Lint (push) Blocked by required conditions
Lint Frontend / Typecheck (push) Blocked by required conditions
Lint Frontend / Verify API clients (push) Waiting to run
Lint Frontend / Verify API clients (enterprise) (push) Waiting to run
golangci-lint / Detect whether code changed (push) Waiting to run
golangci-lint / go-fmt (push) Blocked by required conditions
golangci-lint / lint-go (push) Blocked by required conditions
Crowdin Upload Action / upload-sources-to-crowdin (push) Waiting to run
Verify i18n / verify-i18n (push) Waiting to run
Documentation / Build & Verify Docs (push) Waiting to run
End-to-end tests / Detect whether code changed (push) Waiting to run
End-to-end tests / Build & Package Grafana (push) Blocked by required conditions
End-to-end tests / Build E2E test runner (push) Blocked by required conditions
End-to-end tests / push-docker-image (push) Blocked by required conditions
End-to-end tests / dashboards-suite (old arch) (push) Blocked by required conditions
End-to-end tests / panels-suite (old arch) (push) Blocked by required conditions
End-to-end tests / smoke-tests-suite (old arch) (push) Blocked by required conditions
End-to-end tests / various-suite (old arch) (push) Blocked by required conditions
End-to-end tests / Verify Storybook (Playwright) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (1/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (2/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (3/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (4/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (5/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (6/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (7/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (8/8) (push) Blocked by required conditions
End-to-end tests / run-azure-monitor-e2e (push) Blocked by required conditions
End-to-end tests / All Playwright tests complete (push) Blocked by required conditions
End-to-end tests / A11y test (push) Blocked by required conditions
End-to-end tests / Publish metrics (push) Blocked by required conditions
End-to-end tests / All E2E tests complete (push) Blocked by required conditions
Frontend tests / Detect whether code changed (push) Waiting to run
Frontend tests / Unit tests (1 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (10 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (11 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (12 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (13 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (14 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (15 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (16 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (2 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (3 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (4 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (5 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (6 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (7 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (8 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (9 / 16) (push) Blocked by required conditions
Frontend tests / Decoupled plugin tests (push) Blocked by required conditions
Frontend tests / Packages unit tests (push) Blocked by required conditions
Frontend tests / All frontend unit tests complete (push) Blocked by required conditions
Frontend tests / Devenv frontend-service build (push) Blocked by required conditions
Integration Tests / Detect whether code changed (push) Waiting to run
Integration Tests / Sqlite (1/4) (push) Blocked by required conditions
Integration Tests / Sqlite (2/4) (push) Blocked by required conditions
Integration Tests / Sqlite (3/4) (push) Blocked by required conditions
Integration Tests / Sqlite (4/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (1/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (2/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (3/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (4/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (profiled) (push) Blocked by required conditions
Integration Tests / MySQL (1/16) (push) Blocked by required conditions
Integration Tests / MySQL (10/16) (push) Blocked by required conditions
Integration Tests / MySQL (11/16) (push) Blocked by required conditions
Integration Tests / MySQL (12/16) (push) Blocked by required conditions
Integration Tests / MySQL (13/16) (push) Blocked by required conditions
Integration Tests / MySQL (14/16) (push) Blocked by required conditions
Integration Tests / MySQL (15/16) (push) Blocked by required conditions
Integration Tests / MySQL (16/16) (push) Blocked by required conditions
Integration Tests / MySQL (2/16) (push) Blocked by required conditions
Integration Tests / MySQL (3/16) (push) Blocked by required conditions
Integration Tests / MySQL (4/16) (push) Blocked by required conditions
Integration Tests / MySQL (5/16) (push) Blocked by required conditions
Integration Tests / MySQL (6/16) (push) Blocked by required conditions
Integration Tests / MySQL (7/16) (push) Blocked by required conditions
Integration Tests / MySQL (8/16) (push) Blocked by required conditions
Integration Tests / MySQL (9/16) (push) Blocked by required conditions
Integration Tests / Postgres (1/16) (push) Blocked by required conditions
Integration Tests / Postgres (10/16) (push) Blocked by required conditions
Integration Tests / Postgres (11/16) (push) Blocked by required conditions
Integration Tests / Postgres (12/16) (push) Blocked by required conditions
Integration Tests / Postgres (13/16) (push) Blocked by required conditions
Integration Tests / Postgres (14/16) (push) Blocked by required conditions
Integration Tests / Postgres (15/16) (push) Blocked by required conditions
Integration Tests / Postgres (16/16) (push) Blocked by required conditions
Integration Tests / Postgres (2/16) (push) Blocked by required conditions
Integration Tests / Postgres (3/16) (push) Blocked by required conditions
Integration Tests / Postgres (4/16) (push) Blocked by required conditions
Integration Tests / Postgres (5/16) (push) Blocked by required conditions
Integration Tests / Postgres (6/16) (push) Blocked by required conditions
Integration Tests / Postgres (7/16) (push) Blocked by required conditions
Integration Tests / Postgres (8/16) (push) Blocked by required conditions
Integration Tests / Postgres (9/16) (push) Blocked by required conditions
Integration Tests / All backend integration tests complete (push) Blocked by required conditions
publish-technical-documentation-next / sync (push) Waiting to run
Reject GitHub secrets / reject-gh-secrets (push) Waiting to run
Build Release Packages / setup (push) Waiting to run
Build Release Packages / Dispatch grafana-enterprise build (push) Blocked by required conditions
Build Release Packages / / darwin-amd64 (push) Blocked by required conditions
Build Release Packages / / darwin-arm64 (push) Blocked by required conditions
Build Release Packages / / linux-amd64 (push) Blocked by required conditions
Build Release Packages / / linux-armv6 (push) Blocked by required conditions
Build Release Packages / / linux-armv7 (push) Blocked by required conditions
Build Release Packages / / linux-arm64 (push) Blocked by required conditions
Build Release Packages / / linux-s390x (push) Blocked by required conditions
Build Release Packages / / windows-amd64 (push) Blocked by required conditions
Build Release Packages / / windows-arm64 (push) Blocked by required conditions
Build Release Packages / Upload artifacts (push) Blocked by required conditions
Build Release Packages / publish-dockerhub (push) Blocked by required conditions
Build Release Packages / Dispatch publish NPM canaries (push) Blocked by required conditions
Build Release Packages / notify-pr (push) Blocked by required conditions
Run dashboard schema v2 e2e / dashboard-schema-v2-e2e (push) Waiting to run
Shellcheck / Shellcheck scripts (push) Waiting to run
Run Storybook a11y tests / Detect whether code changed (push) Waiting to run
Run Storybook a11y tests / Run Storybook a11y tests (light theme) (push) Blocked by required conditions
Run Storybook a11y tests / Run Storybook a11y tests (dark theme) (push) Blocked by required conditions
Swagger generated code / Detect whether code changed (push) Waiting to run
Swagger generated code / Verify committed API specs match (push) Blocked by required conditions
Dispatch sync to mirror / dispatch-job (push) Waiting to run
trigger-dashboard-search-e2e / trigger-search-e2e (push) Waiting to run

* wip; DrilldownControls

* use wrapper so that drilldown controls wrap inline

* keep labels on top when input expands vertically

* add clear all button

* add collapsible prop

* i18n

* Increase maxWidth for adhoc

* bump scenes for testing

* fix

* remove clear all button

* use new feature toggle; pass collapsible in v2

* update variable controls to use new feature flag

* cleanup

* wip (#115441)

* wip

* fix

* update wrapping on smaller screens

---------

Co-authored-by: Haris Rozajac <haris.rozajac12@gmail.com>

* Filter out variables that are not in inControlsMenu

* filter out inControlsMenu vars, not hidden ones

* canary scenes

* fix

* cleanup

* canary scenes

* pass wideInput to groupby based on ff

* update var name and bump scenes

* bump scenes

* yarn lock

---------

Co-authored-by: Victor Marin <victor.marin@grafana.com>
This commit is contained in:
Haris Rozajac 2025-12-18 11:58:21 -07:00 committed by GitHub
parent 1850163346
commit 05fd304dbd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 240 additions and 16 deletions

View file

@ -295,8 +295,8 @@
"@grafana/plugin-ui": "^0.11.1",
"@grafana/prometheus": "workspace:*",
"@grafana/runtime": "workspace:*",
"@grafana/scenes": "^6.51.0",
"@grafana/scenes-react": "^6.51.0",
"@grafana/scenes": "6.52.0",
"@grafana/scenes-react": "6.52.0",
"@grafana/schema": "workspace:*",
"@grafana/sql": "workspace:*",
"@grafana/ui": "workspace:*",

View file

@ -499,6 +499,10 @@ export interface FeatureToggles {
*/
newDashboardWithFiltersAndGroupBy?: boolean;
/**
* Wraps the ad hoc and group by variables in a single wrapper, with all other variables below it
*/
dashboardAdHocAndGroupByWrapper?: boolean;
/**
* Updates CloudWatch label parsing to be more accurate
* @default true
*/

View file

@ -820,6 +820,13 @@ var (
Owner: grafanaDashboardsSquad,
HideFromDocs: true,
},
{
Name: "dashboardAdHocAndGroupByWrapper",
Description: "Wraps the ad hoc and group by variables in a single wrapper, with all other variables below it",
Stage: FeatureStageExperimental,
Owner: grafanaDashboardsSquad,
HideFromDocs: true,
},
{
Name: "cloudWatchNewLabelParsing",
Description: "Updates CloudWatch label parsing to be more accurate",

View file

@ -113,6 +113,7 @@ scopeFilters,experimental,@grafana/dashboards-squad,false,false,false
oauthRequireSubClaim,experimental,@grafana/identity-access-team,false,false,false
refreshTokenRequired,experimental,@grafana/identity-access-team,false,false,false
newDashboardWithFiltersAndGroupBy,experimental,@grafana/dashboards-squad,false,false,false
dashboardAdHocAndGroupByWrapper,experimental,@grafana/dashboards-squad,false,false,false
cloudWatchNewLabelParsing,GA,@grafana/aws-datasources,false,false,false
disableNumericMetricsSortingInExpressions,experimental,@grafana/oss-big-tent,false,true,false
grafanaManagedRecordingRules,experimental,@grafana/alerting-squad,false,false,false

1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
113 oauthRequireSubClaim experimental @grafana/identity-access-team false false false
114 refreshTokenRequired experimental @grafana/identity-access-team false false false
115 newDashboardWithFiltersAndGroupBy experimental @grafana/dashboards-squad false false false
116 dashboardAdHocAndGroupByWrapper experimental @grafana/dashboards-squad false false false
117 cloudWatchNewLabelParsing GA @grafana/aws-datasources false false false
118 disableNumericMetricsSortingInExpressions experimental @grafana/oss-big-tent false true false
119 grafanaManagedRecordingRules experimental @grafana/alerting-squad false false false

View file

@ -339,6 +339,10 @@ const (
// Enables filters and group by variables on all new dashboards. Variables are added only if default data source supports filtering.
FlagNewDashboardWithFiltersAndGroupBy = "newDashboardWithFiltersAndGroupBy"
// FlagDashboardAdHocAndGroupByWrapper
// Wraps the ad hoc and group by variables in a single wrapper, with all other variables below it
FlagDashboardAdHocAndGroupByWrapper = "dashboardAdHocAndGroupByWrapper"
// FlagCloudWatchNewLabelParsing
// Updates CloudWatch label parsing to be more accurate
FlagCloudWatchNewLabelParsing = "cloudWatchNewLabelParsing"

View file

@ -922,6 +922,19 @@
"frontend": true
}
},
{
"metadata": {
"name": "dashboardAdHocAndGroupByWrapper",
"resourceVersion": "1765841806645",
"creationTimestamp": "2025-12-15T23:36:46Z"
},
"spec": {
"description": "Wraps the ad hoc and group by variables in a single wrapper, with all other variables below it",
"stage": "experimental",
"codeowner": "@grafana/dashboards-squad",
"hideFromDocs": true
}
},
{
"metadata": {
"name": "dashboardDisableSchemaValidationV1",

View file

@ -16,6 +16,7 @@ import {
SceneObjectUrlSyncConfig,
SceneObjectUrlValues,
CancelActivationHandler,
sceneUtils,
} from '@grafana/scenes';
import { Box, Button, useStyles2 } from '@grafana/ui';
import { playlistSrv } from 'app/features/playlist/PlaylistSrv';
@ -27,6 +28,7 @@ import { getDashboardSceneFor } from '../utils/utils';
import { DashboardDataLayerControls } from './DashboardDataLayerControls';
import { DashboardLinksControls } from './DashboardLinksControls';
import { DashboardScene } from './DashboardScene';
import { DrilldownControls } from './DrilldownControls';
import { VariableControls } from './VariableControls';
import { DashboardControlsButton } from './dashboard-controls-menu/DashboardControlsMenuButton';
import { hasDashboardControls, useHasDashboardControls } from './dashboard-controls-menu/utils';
@ -151,11 +153,63 @@ function DashboardControlsRenderer({ model }: SceneComponentProps<DashboardContr
const showDebugger = window.location.search.includes('scene-debugger');
const hasDashboardControls = useHasDashboardControls(dashboard);
// Get adhoc and groupby variables for drilldown controls
const { variables } = sceneGraph.getVariables(dashboard)?.useState() ?? { variables: [] };
const visibleVariables = variables.filter((v) => v.state.hide !== VariableHide.inControlsMenu);
const adHocVar = visibleVariables.find((v) => sceneUtils.isAdHocVariable(v));
const groupByVar = visibleVariables.find((v) => sceneUtils.isGroupByVariable(v));
const useUnifiedDrilldownUI = config.featureToggles.dashboardAdHocAndGroupByWrapper && adHocVar && groupByVar;
if (!model.hasControls()) {
// To still have spacing when no controls are rendered
return <Box padding={1}>{renderHiddenVariables(dashboard)}</Box>;
}
// When dashboardAdHocAndGroupByWrapper is enabled, use the new layout with topRow
if (useUnifiedDrilldownUI) {
return (
<div
data-testid={selectors.pages.Dashboard.Controls}
className={cx(styles.controls, editPanel && styles.controlsPanelEdit)}
>
<div className={styles.topRow}>
{config.featureToggles.scopeFilters && !editPanel && (
<ContextualNavigationPaneToggle className={styles.contextualNavToggleNewLayout} hideWhenOpen={true} />
)}
{!hideVariableControls && (
<div className={styles.drilldownControlsContainer}>
<DrilldownControls adHocVar={adHocVar} groupByVar={groupByVar} />
</div>
)}
<div className={cx(styles.rightControlsNewLayout, editPanel && styles.rightControlsWrap)}>
{!hideTimeControls && (
<div className={styles.fixedControlsNewLayout}>
<timePicker.Component model={timePicker} />
<refreshPicker.Component model={refreshPicker} />
</div>
)}
{config.featureToggles.dashboardNewLayouts && (
<div className={styles.fixedControlsNewLayout}>
<DashboardControlActions dashboard={dashboard} />
</div>
)}
</div>
</div>
{!hideVariableControls && (
<>
<VariableControls dashboard={dashboard} />
<DashboardDataLayerControls dashboard={dashboard} />
</>
)}
{!hideLinksControls && !editPanel && <DashboardLinksControls links={links} dashboard={dashboard} />}
{!hideDashboardControls && hasDashboardControls && <DashboardControlsButton dashboard={dashboard} />}
{editPanel && <PanelEditControls panelEditor={editPanel} />}
{showDebugger && <SceneDebugger scene={model} key={'scene-debugger'} />}
</div>
);
}
// Original layout when feature toggle is off
return (
<div
data-testid={selectors.pages.Dashboard.Controls}
@ -243,6 +297,7 @@ function renderHiddenVariables(dashboard: DashboardScene) {
function getStyles(theme: GrafanaTheme2) {
return {
// Original controls style
controls: css({
gap: theme.spacing(1),
padding: theme.spacing(2, 2, 1, 2),
@ -266,10 +321,31 @@ function getStyles(theme: GrafanaTheme2) {
// In panel edit we do not need any right padding as the splitter is providing it
paddingRight: 0,
}),
// New layout styles (used when feature toggle is on)
topRow: css({
display: 'flex',
alignItems: 'flex-start',
gap: theme.spacing(1),
width: '100%',
marginBottom: theme.spacing(1),
[theme.breakpoints.down('sm')]: {
flexWrap: 'wrap',
},
}),
drilldownControlsContainer: css({
flex: 1,
minWidth: 0,
display: 'flex',
[theme.breakpoints.down('sm')]: {
order: 1, // Move below the time controls
flex: '1 1 100%', // Take full width to force new line
},
}),
embedded: css({
background: 'unset',
position: 'unset',
}),
// Original rightControls style
rightControls: css({
display: 'flex',
gap: theme.spacing(1),
@ -279,6 +355,15 @@ function getStyles(theme: GrafanaTheme2) {
maxWidth: '100%',
minWidth: 0,
}),
// Modified rightControls for new layout
rightControlsNewLayout: css({
display: 'flex',
gap: theme.spacing(1),
alignItems: 'flex-start',
flexWrap: 'wrap',
flexShrink: 0,
}),
// Original fixedControls style
fixedControls: css({
display: 'flex',
justifyContent: 'flex-end',
@ -289,6 +374,14 @@ function getStyles(theme: GrafanaTheme2) {
flexShrink: 0,
alignSelf: 'flex-start',
}),
// Fixed controls for new layout (no margin/order)
fixedControlsNewLayout: css({
display: 'flex',
justifyContent: 'flex-end',
gap: theme.spacing(1),
flexShrink: 0,
alignSelf: 'flex-start',
}),
dashboardControlsButton: css({
order: 2,
marginLeft: 'auto',
@ -301,5 +394,9 @@ function getStyles(theme: GrafanaTheme2) {
display: 'inline-flex',
margin: theme.spacing(0, 1, 1, 0),
}),
contextualNavToggleNewLayout: css({
display: 'inline-flex',
flexShrink: 0,
}),
};
}

View file

@ -0,0 +1,77 @@
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { AdHocFiltersVariable, GroupByVariable } from '@grafana/scenes';
import { useStyles2 } from '@grafana/ui';
import { VariableValueSelectWrapper } from './VariableControls';
interface DrilldownControlsProps {
adHocVar: AdHocFiltersVariable;
groupByVar: GroupByVariable;
}
/**
* DrilldownControls renders the AdHoc and GroupBy variables in a single row above the other variables.
*/
export function DrilldownControls({ adHocVar, groupByVar }: DrilldownControlsProps) {
const styles = useStyles2(getStyles);
return (
<div className={styles.drilldownRow}>
<div className={styles.adHocContainer}>
<VariableValueSelectWrapper variable={adHocVar} />
</div>
<div className={styles.groupByContainer}>
<VariableValueSelectWrapper variable={groupByVar} />
</div>
</div>
);
}
const getStyles = (theme: GrafanaTheme2) => ({
drilldownRow: css({
display: 'flex',
flexWrap: 'nowrap',
[theme.breakpoints.down('xl')]: {
flexWrap: 'wrap',
},
gap: theme.spacing(1),
width: '100%',
}),
adHocContainer: css({
flex: '7 1 0%', // 70% of available space
minWidth: 0,
[theme.breakpoints.down('xl')]: {
// Force full width, causing groupBy to wrap
flex: '1 1 100%',
},
display: 'flex',
// Make the wrapper and its children take full width
'& > div': {
alignItems: 'flex-start',
width: '100%',
flex: 1,
},
}),
groupByContainer: css({
flex: '3 1 0%', // 30% of available space
minWidth: 0,
display: 'flex',
// Make the wrapper and its children take full width
'& > div': {
alignItems: 'flex-start',
width: '100%',
flex: 1,
},
[theme.breakpoints.down('sm')]: {
minWidth: '200px',
},
}),
clearAllButton: css({
alignSelf: 'flex-start',
fontSize: theme.typography.bodySmall.fontSize,
padding: theme.spacing(0.5, 0.5),
marginBottom: theme.spacing(1),
}),
});

View file

@ -20,13 +20,30 @@ import { AddVariableButton } from './VariableControlsAddButton';
export function VariableControls({ dashboard }: { dashboard: DashboardScene }) {
const { variables } = sceneGraph.getVariables(dashboard)!.useState();
// Get visible variables for drilldown layout
const visibleVariables = variables.filter((v) => v.state.hide !== VariableHide.inControlsMenu);
const adHocVar = visibleVariables.find((v) => sceneUtils.isAdHocVariable(v));
const groupByVar = visibleVariables.find((v) => sceneUtils.isGroupByVariable(v));
const hasDrilldownControls = config.featureToggles.dashboardAdHocAndGroupByWrapper && adHocVar && groupByVar;
const restVariables = visibleVariables.filter(
(v) => v.state.name !== adHocVar?.state.name && v.state.name !== groupByVar?.state.name
);
// Variables to render (exclude adhoc/groupby when drilldown controls are shown in top row)
const variablesToRender = hasDrilldownControls
? restVariables.filter((v) => v.state.hide !== VariableHide.inControlsMenu)
: variables.filter((v) => v.state.hide !== VariableHide.inControlsMenu);
return (
<>
{variables
.filter((v) => v.state.hide !== VariableHide.inControlsMenu)
.map((variable) => (
{variablesToRender.length > 0 &&
variablesToRender.map((variable) => (
<VariableValueSelectWrapper key={variable.state.key} variable={variable} />
))}
{config.featureToggles.dashboardNewLayouts ? <AddVariableButton dashboard={dashboard} /> : null}
</>
);

View file

@ -336,6 +336,7 @@ function createSceneVariableFromVariableModel(variable: TypedVariableModelV2): S
supportsMultiValueOperators: Boolean(
getDataSourceSrv().getInstanceSettings({ type: ds?.type })?.meta.multiValueFilterOperators
),
collapsible: config.featureToggles.dashboardAdHocAndGroupByWrapper,
};
if (variable.spec.allowCustomValue !== undefined) {
adhocVariableState.allowCustomValue = variable.spec.allowCustomValue;
@ -460,6 +461,7 @@ function createSceneVariableFromVariableModel(variable: TypedVariableModelV2): S
skipUrlSync: variable.spec.skipUrlSync,
isMulti: variable.spec.multi,
hide: transformVariableHideToEnumV1(variable.spec.hide),
wideInput: config.featureToggles.dashboardAdHocAndGroupByWrapper,
drilldownRecommendationsEnabled: config.featureToggles.drilldownRecommendations,
// @ts-expect-error
defaultOptions: variable.options,

View file

@ -164,6 +164,7 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode
useQueriesAsFilterForOptions: true,
drilldownRecommendationsEnabled: config.featureToggles.drilldownRecommendations,
layout: config.featureToggles.newFiltersUI ? 'combobox' : undefined,
collapsible: config.featureToggles.dashboardAdHocAndGroupByWrapper,
supportsMultiValueOperators: Boolean(
getDataSourceSrv().getInstanceSettings({ type: variable.datasource?.type })?.meta.multiValueFilterOperators
),
@ -288,6 +289,7 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode
text: variable.current?.text || [],
skipUrlSync: variable.skipUrlSync,
hide: variable.hide,
wideInput: config.featureToggles.dashboardAdHocAndGroupByWrapper,
// @ts-expect-error
defaultOptions: variable.options,
defaultValue: variable.defaultValue,

View file

@ -3604,11 +3604,11 @@ __metadata:
languageName: unknown
linkType: soft
"@grafana/scenes-react@npm:^6.51.0":
version: 6.51.0
resolution: "@grafana/scenes-react@npm:6.51.0"
"@grafana/scenes-react@npm:6.52.0":
version: 6.52.0
resolution: "@grafana/scenes-react@npm:6.52.0"
dependencies:
"@grafana/scenes": "npm:6.51.0"
"@grafana/scenes": "npm:6.52.0"
lru-cache: "npm:^10.2.2"
react-use: "npm:^17.4.0"
peerDependencies:
@ -3620,7 +3620,7 @@ __metadata:
react: ^18.0.0
react-dom: ^18.0.0
react-router-dom: ^6.28.0
checksum: 10/14acdfe5220e67e7450780320b779e2e4a255995d55f0c82eb0d25933e72598e54826df0a8beee05591efe01a91ddab840483fea3bb828bd5925c3f0b44b8d17
checksum: 10/7f121bcc4fd50f525c7c3457666ad3a32b04783d322d6715aedb6119538f911d0ec265c9c5b49a80478c1deb99286d36d003399a8831f76b6c483f4458b4ce8b
languageName: node
linkType: hard
@ -3650,9 +3650,9 @@ __metadata:
languageName: node
linkType: hard
"@grafana/scenes@npm:6.51.0, @grafana/scenes@npm:^6.51.0":
version: 6.51.0
resolution: "@grafana/scenes@npm:6.51.0"
"@grafana/scenes@npm:6.52.0":
version: 6.52.0
resolution: "@grafana/scenes@npm:6.52.0"
dependencies:
"@floating-ui/react": "npm:^0.26.16"
"@leeoniya/ufuzzy": "npm:^1.0.16"
@ -3672,7 +3672,7 @@ __metadata:
react: ^18.0.0
react-dom: ^18.0.0
react-router-dom: ^6.28.0
checksum: 10/4e4f43babe786ff729d58b7636182df57c58ce40c13b56036f725c070e0cf597cbe52aaa0f811184b8d42d8d1f9a32679695471d410f883051b09da44f8bf36a
checksum: 10/e52e0fb83396776c6cb79f8ac6a8aad0799eb2ccce9d0139f5734a49c3add7a1e3b97f14e0142c95b2bceee3ed8fa97b675b9b94c02382ecd683f470d06ef145
languageName: node
linkType: hard
@ -19508,8 +19508,8 @@ __metadata:
"@grafana/plugin-ui": "npm:^0.11.1"
"@grafana/prometheus": "workspace:*"
"@grafana/runtime": "workspace:*"
"@grafana/scenes": "npm:^6.51.0"
"@grafana/scenes-react": "npm:^6.51.0"
"@grafana/scenes": "npm:6.52.0"
"@grafana/scenes-react": "npm:6.52.0"
"@grafana/schema": "workspace:*"
"@grafana/sql": "workspace:*"
"@grafana/test-utils": "workspace:*"