grafana/public/app/features/trails/MetricGraphScene.tsx
Andre Pereira 6241386a96
Data Trails: Sticky main metric graph (#84389)
* WIP

* Refactor code a bit so we can sticky the main graph and tabs

* Make sure it works in Firefox. Avoid annoying warnings in breakdown tab. Update pin metrics graph label

* Small copy change

Co-authored-by: Darren Janeczek <38694490+darrenjaneczek@users.noreply.github.com>

---------

Co-authored-by: Darren Janeczek <38694490+darrenjaneczek@users.noreply.github.com>
2024-03-18 13:38:17 +02:00

93 lines
2.5 KiB
TypeScript

import { css } from '@emotion/css';
import React from 'react';
import { DashboardCursorSync, GrafanaTheme2 } from '@grafana/data';
import {
behaviors,
SceneComponentProps,
SceneFlexItem,
SceneFlexLayout,
SceneObject,
SceneObjectBase,
SceneObjectState,
} from '@grafana/scenes';
import { useStyles2 } from '@grafana/ui';
import { AutoVizPanel } from './AutomaticMetricQueries/AutoVizPanel';
import { MetricActionBar } from './MetricScene';
import { getTrailSettings } from './utils';
export const MAIN_PANEL_MIN_HEIGHT = 280;
export const MAIN_PANEL_MAX_HEIGHT = '40%';
export interface MetricGraphSceneState extends SceneObjectState {
topView: SceneFlexLayout;
selectedTab?: SceneObject;
}
export class MetricGraphScene extends SceneObjectBase<MetricGraphSceneState> {
public constructor(state: Partial<MetricGraphSceneState>) {
super({
topView: state.topView ?? buildGraphTopView(),
...state,
});
}
public static Component = ({ model }: SceneComponentProps<MetricGraphScene>) => {
const { topView, selectedTab } = model.useState();
const { stickyMainGraph } = getTrailSettings(model).useState();
const styles = useStyles2(getStyles);
return (
<div className={styles.container}>
<div className={stickyMainGraph ? styles.sticky : styles.nonSticky}>
<topView.Component model={topView} />
</div>
{selectedTab && <selectedTab.Component model={selectedTab} />}
</div>
);
};
}
function getStyles(theme: GrafanaTheme2) {
return {
container: css({
display: 'flex',
flexDirection: 'column',
position: 'relative',
}),
sticky: css({
display: 'flex',
flexDirection: 'row',
background: theme.isLight ? theme.colors.background.primary : theme.colors.background.canvas,
position: 'sticky',
top: '70px',
zIndex: 10,
}),
nonSticky: css({
display: 'flex',
flexDirection: 'row',
}),
};
}
function buildGraphTopView() {
const bodyAutoVizPanel = new AutoVizPanel({});
return new SceneFlexLayout({
direction: 'column',
$behaviors: [new behaviors.CursorSync({ key: 'metricCrosshairSync', sync: DashboardCursorSync.Crosshair })],
children: [
new SceneFlexItem({
minHeight: MAIN_PANEL_MIN_HEIGHT,
maxHeight: MAIN_PANEL_MAX_HEIGHT,
body: bodyAutoVizPanel,
}),
new SceneFlexItem({
ySizing: 'content',
body: new MetricActionBar({}),
}),
],
});
}