From 9ec87fda9baeafd1a43850395aca8b66ea80afd9 Mon Sep 17 00:00:00 2001 From: Levente Balogh Date: Wed, 3 Dec 2025 12:02:19 +0100 Subject: [PATCH] fix: layout issues --- .../scene/DashboardControls.tsx | 44 ++++++++++++++----- .../scene/DashboardDataLayerControls.tsx | 24 ++-------- .../scene/DashboardLinkRenderer.tsx | 1 - .../scene/DashboardLinksControls.tsx | 24 ++-------- .../scene/VariableControls.tsx | 21 ++------- .../SubMenu/DashboardLinksDashboard.tsx | 1 - 6 files changed, 44 insertions(+), 71 deletions(-) diff --git a/public/app/features/dashboard-scene/scene/DashboardControls.tsx b/public/app/features/dashboard-scene/scene/DashboardControls.tsx index f21a9ea01aa..0c8b3b51e6b 100644 --- a/public/app/features/dashboard-scene/scene/DashboardControls.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardControls.tsx @@ -38,6 +38,7 @@ export interface DashboardControlsState extends SceneObjectState { refreshPicker: SceneRefreshPicker; hideTimeControls?: boolean; hideVariableControls?: boolean; + hideAnnotationControls?: boolean; hideLinksControls?: boolean; // Hides the dashboard-controls dropdown menu hideDashboardControls?: boolean; @@ -63,7 +64,8 @@ export class DashboardControls extends SceneObjectBase { } updateFromUrl(values: SceneObjectUrlValues) { - const { hideTimeControls, hideVariableControls, hideLinksControls, hideDashboardControls } = this.state; + const { hideTimeControls, hideVariableControls, hideLinksControls, hideDashboardControls, hideAnnotationControls } = + this.state; const isEnabledViaUrl = (key: string) => values[key] === 'true' || values[key] === ''; // Only allow hiding, never "unhiding" from url @@ -77,6 +79,10 @@ export class DashboardControls extends SceneObjectBase { this.setState({ hideVariableControls: true }); } + if (!hideAnnotationControls && isEnabledViaUrl('_dash.hideAnnotations')) { + this.setState({ hideAnnotationControls: true }); + } + if (!hideLinksControls && isEnabledViaUrl('_dash.hideLinks')) { this.setState({ hideLinksControls: true }); } @@ -126,11 +132,12 @@ export class DashboardControls extends SceneObjectBase { const hasAnnotations = sceneGraph.getDataLayers(this).some((d) => d.state.isEnabled && !d.state.isHidden); const hasLinks = getDashboardSceneFor(this).state.links?.length > 0; const hideLinks = this.state.hideLinksControls || !hasLinks; - const hideVariables = this.state.hideVariableControls || (!hasAnnotations && !hasVariables); + const hideVariables = this.state.hideVariableControls || !hasVariables; + const hideAnnotationControls = this.state.hideAnnotationControls || !hasAnnotations; const hideTimePicker = this.state.hideTimeControls; const hideDashboardControls = this.state.hideDashboardControls || !hasDashboardControls(dashboard); - return !(hideVariables && hideLinks && hideTimePicker && hideDashboardControls); + return !(hideVariables && hideLinks && hideTimePicker && hideDashboardControls && hideAnnotationControls); } } @@ -140,6 +147,7 @@ function DashboardControlsRenderer({ model }: SceneComponentProps + {/* Right controls */}
+ {/* Time controls */} {!hideTimeControls && (
)} + + {/* Actions (edit, play, share, etc.) */} {config.featureToggles.dashboardNewLayouts && (
)} - {!hideLinksControls && !editPanel && }
- {!hideVariableControls && ( - <> - - - - )} - {!hideDashboardControls && hasDashboardControls && } + + {/* Left controls */} +
+ {/* Variables */} + {!hideVariableControls && } + {!hideAnnotationControls && } + {!hideLinksControls && !editPanel && } + {!hideDashboardControls && hasDashboardControls(dashboard) && } +
{editPanel && } {showDebugger && } @@ -260,6 +273,15 @@ function getStyles(theme: GrafanaTheme2) { background: 'unset', position: 'unset', }), + leftControls: css({ + display: 'flex', + gap: theme.spacing(1), + float: 'left', + alignItems: 'flex-start', + flexWrap: 'wrap', + maxWidth: '100%', + minWidth: 0, + }), rightControls: css({ display: 'flex', gap: theme.spacing(1), diff --git a/public/app/features/dashboard-scene/scene/DashboardDataLayerControls.tsx b/public/app/features/dashboard-scene/scene/DashboardDataLayerControls.tsx index 24f7e2dbd79..94929687be2 100644 --- a/public/app/features/dashboard-scene/scene/DashboardDataLayerControls.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardDataLayerControls.tsx @@ -1,8 +1,5 @@ -import { css } from '@emotion/css'; - -import { GrafanaTheme2 } from '@grafana/data'; import { SceneDataLayerProvider, sceneGraph } from '@grafana/scenes'; -import { useStyles2 } from '@grafana/ui'; +import { Stack } from '@grafana/ui'; import { isDashboardDataLayerSetState } from './DashboardDataLayerSet'; import { DashboardScene } from './DashboardScene'; @@ -16,29 +13,16 @@ export function DashboardDataLayerControls({ dashboard }: { dashboard: Dashboard // It is possible to render the controls for the annotation data layers in separate places using the `placement` property. // In case it's not specified, we are rendering the controls here (default). const isDefaultPlacement = (layer: SceneDataLayerProvider) => layer.state.placement === undefined; - const styles = useStyles2(getStyles); if (isDashboardDataLayerSetState(state)) { return ( - <> + {state.annotationLayers.filter(isDefaultPlacement).map((layer) => ( -
- -
+ ))} - +
); } return null; } - -const getStyles = (theme: GrafanaTheme2) => ({ - container: css({ - display: 'inline-flex', - alignItems: 'center', - verticalAlign: 'middle', - marginBottom: theme.spacing(1), - marginRight: theme.spacing(1), - }), -}); diff --git a/public/app/features/dashboard-scene/scene/DashboardLinkRenderer.tsx b/public/app/features/dashboard-scene/scene/DashboardLinkRenderer.tsx index e7bc346642b..d2571314782 100644 --- a/public/app/features/dashboard-scene/scene/DashboardLinkRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardLinkRenderer.tsx @@ -64,7 +64,6 @@ function getStyles(theme: GrafanaTheme2) { alignItems: 'center', verticalAlign: 'middle', marginBottom: theme.spacing(1), - marginRight: theme.spacing(1), }), }; } diff --git a/public/app/features/dashboard-scene/scene/DashboardLinksControls.tsx b/public/app/features/dashboard-scene/scene/DashboardLinksControls.tsx index 11639554e5d..5a9569dd298 100644 --- a/public/app/features/dashboard-scene/scene/DashboardLinksControls.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardLinksControls.tsx @@ -1,9 +1,6 @@ -import { css } from '@emotion/css'; - -import { GrafanaTheme2 } from '@grafana/data'; import { sceneGraph } from '@grafana/scenes'; import { DashboardLink } from '@grafana/schema'; -import { useStyles2 } from '@grafana/ui'; +import { Stack } from '@grafana/ui'; import { DashboardLinkRenderer } from './DashboardLinkRenderer'; import { DashboardScene } from './DashboardScene'; @@ -16,33 +13,18 @@ export interface Props { export function DashboardLinksControls({ links, dashboard }: Props) { sceneGraph.getTimeRange(dashboard).useState(); const uid = dashboard.state.uid; - const styles = useStyles2(getStyles); if (!links || !uid) { return null; } return ( -
+ {links .filter((link) => link.placement === undefined) .map((link: DashboardLink, index: number) => ( ))} -
+ ); } - -function getStyles(theme: GrafanaTheme2) { - return { - linksContainer: css({ - display: 'flex', - flexWrap: 'wrap', - gap: theme.spacing(1), - maxWidth: '100%', - minWidth: 0, - order: 1, - flex: '1 1 0%', - }), - }; -} diff --git a/public/app/features/dashboard-scene/scene/VariableControls.tsx b/public/app/features/dashboard-scene/scene/VariableControls.tsx index 1061938e5e6..457a6a06fad 100644 --- a/public/app/features/dashboard-scene/scene/VariableControls.tsx +++ b/public/app/features/dashboard-scene/scene/VariableControls.tsx @@ -12,28 +12,23 @@ import { ControlsLayout, sceneUtils, } from '@grafana/scenes'; -import { useElementSelection, useStyles2 } from '@grafana/ui'; +import { Stack, useElementSelection, useStyles2 } from '@grafana/ui'; import { DashboardScene } from './DashboardScene'; import { AddVariableButton } from './VariableControlsAddButton'; export function VariableControls({ dashboard }: { dashboard: DashboardScene }) { const { variables } = sceneGraph.getVariables(dashboard)!.useState(); - const styles = useStyles2(getStyles); return ( - <> + {variables .filter((v) => v.state.hide !== VariableHide.inControlsMenu) .map((variable) => ( ))} - {config.featureToggles.dashboardNewLayouts ? ( -
- -
- ) : null} - + {config.featureToggles.dashboardNewLayouts ? : null} +
); } @@ -179,7 +174,6 @@ const getStyles = (theme: GrafanaTheme2) => ({ borderBottomLeftRadius: 'unset', }), marginBottom: theme.spacing(1), - marginRight: theme.spacing(1), }), verticalContainer: css({ display: 'flex', @@ -211,11 +205,4 @@ const getStyles = (theme: GrafanaTheme2) => ({ display: 'flex', alignItems: 'center', }), - addButton: css({ - display: 'inline-flex', - alignItems: 'center', - verticalAlign: 'middle', - marginBottom: theme.spacing(1), - marginRight: theme.spacing(1), - }), }); diff --git a/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.tsx b/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.tsx index 43d1dda185f..ae5cffb9b31 100644 --- a/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.tsx +++ b/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.tsx @@ -182,7 +182,6 @@ function getStyles(theme: GrafanaTheme2) { alignItems: 'center', verticalAlign: 'middle', marginBottom: theme.spacing(1), - marginRight: theme.spacing(1), }), }; }