diff --git a/.betterer.results b/.betterer.results index e83b056e92c..38db6f6dd98 100644 --- a/.betterer.results +++ b/.betterer.results @@ -4085,6 +4085,9 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "11"], [0, 0, 0, "Do not use any type assertions.", "12"] ], + "public/app/features/trails/MetricScene.tsx:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/BasicMatcherEditor.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], diff --git a/public/app/features/trails/ActionTabs/BreakdownScene.tsx b/public/app/features/trails/ActionTabs/BreakdownScene.tsx index d76d7b1fe91..d4484bec19c 100644 --- a/public/app/features/trails/ActionTabs/BreakdownScene.tsx +++ b/public/app/features/trails/ActionTabs/BreakdownScene.tsx @@ -236,7 +236,6 @@ export function buildAllLayout(options: Array>, queryDef { value: 'grid', label: 'Grid' }, { value: 'rows', label: 'Rows' }, ], - active: 'grid', layouts: [ new SceneCSSGridLayout({ templateColumns: GRID_TEMPLATE_COLUMNS, @@ -269,7 +268,6 @@ function buildNormalLayout(queryDef: AutoQueryDef) { { value: 'grid', label: 'Grid' }, { value: 'rows', label: 'Rows' }, ], - active: 'grid', layouts: [ new SceneFlexLayout({ direction: 'column', diff --git a/public/app/features/trails/ActionTabs/LayoutSwitcher.tsx b/public/app/features/trails/ActionTabs/LayoutSwitcher.tsx index 92b3933728d..4e5a2e11a8e 100644 --- a/public/app/features/trails/ActionTabs/LayoutSwitcher.tsx +++ b/public/app/features/trails/ActionTabs/LayoutSwitcher.tsx @@ -1,11 +1,12 @@ import React from 'react'; import { SelectableValue } from '@grafana/data'; -import { SceneComponentProps, SceneObject, SceneObjectBase, SceneObjectState } from '@grafana/scenes'; +import { SceneComponentProps, sceneGraph, SceneObject, SceneObjectBase, SceneObjectState } from '@grafana/scenes'; import { Field, RadioButtonGroup } from '@grafana/ui'; +import { MetricScene } from '../MetricScene'; + export interface LayoutSwitcherState extends SceneObjectState { - active: LayoutType; layouts: SceneObject[]; options: Array>; } @@ -13,24 +14,30 @@ export interface LayoutSwitcherState extends SceneObjectState { export type LayoutType = 'single' | 'grid' | 'rows'; export class LayoutSwitcher extends SceneObjectBase { + private getMetricScene() { + return sceneGraph.getAncestor(this, MetricScene); + } + public Selector({ model }: { model: LayoutSwitcher }) { - const { active, options } = model.useState(); + const { options } = model.useState(); + const { layout } = model.getMetricScene().useState(); return ( - + ); } public onLayoutChange = (active: LayoutType) => { - this.setState({ active }); + this.getMetricScene().setState({ layout: active }); }; public static Component = ({ model }: SceneComponentProps) => { - const { layouts, options, active } = model.useState(); + const { layouts, options } = model.useState(); + const { layout: activeLayout } = model.getMetricScene().useState(); - const index = options.findIndex((o) => o.value === active); + const index = options.findIndex((o) => o.value === activeLayout); if (index === -1) { return null; } diff --git a/public/app/features/trails/MetricScene.tsx b/public/app/features/trails/MetricScene.tsx index 0ffd8f7ad63..b2df2863e86 100644 --- a/public/app/features/trails/MetricScene.tsx +++ b/public/app/features/trails/MetricScene.tsx @@ -17,6 +17,7 @@ import { ToolbarButton, Box, Stack, Icon, TabsBar, Tab, useStyles2, LinkButton, import { getExploreUrl } from '../../core/utils/explore'; import { buildBreakdownActionScene } from './ActionTabs/BreakdownScene'; +import { LayoutType } from './ActionTabs/LayoutSwitcher'; import { buildMetricOverviewScene } from './ActionTabs/MetricOverviewScene'; import { buildRelatedMetricsScene } from './ActionTabs/RelatedMetricsScene'; import { getAutoQueriesForMetric } from './AutomaticMetricQueries/AutoQueryEngine'; @@ -40,21 +41,23 @@ export interface MetricSceneState extends SceneObjectState { body: MetricGraphScene; metric: string; actionView?: string; + layout: LayoutType; autoQuery: AutoQueryInfo; queryDef?: AutoQueryDef; } export class MetricScene extends SceneObjectBase { - protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['actionView'] }); + protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['actionView', 'layout'] }); - public constructor(state: MakeOptional) { + public constructor(state: MakeOptional) { const autoQuery = state.autoQuery ?? getAutoQueriesForMetric(state.metric); super({ $variables: state.$variables ?? getVariableSet(state.metric), body: state.body ?? new MetricGraphScene({}), autoQuery, queryDef: state.queryDef ?? autoQuery.main, + layout: state.layout ?? 'grid', ...state, }); @@ -68,7 +71,7 @@ export class MetricScene extends SceneObjectBase { } getUrlState() { - return { actionView: this.state.actionView }; + return { actionView: this.state.actionView, layout: this.state.layout }; } updateFromUrl(values: SceneObjectUrlValues) { @@ -82,6 +85,13 @@ export class MetricScene extends SceneObjectBase { } else if (values.actionView === null) { this.setActionView(undefined); } + + if (typeof values.layout === 'string') { + const newLayout = values.layout as LayoutType; + if (this.state.layout !== newLayout) { + this.setState({ layout: newLayout }); + } + } } public setActionView(actionView?: ActionViewType) {