PanelChrome: Implement Panel header with error, loading, and streaming data status (#60147)

* dashboards squad mob! 🔱

lastFile:packages/grafana-ui/src/components/LoadingBar/LoadingBar.tsx

* dashboards squad mob! 🔱

* dashboards squad mob! 🔱

lastFile:packages/grafana-ui/src/components/LoadingBar/LoadingBar.tsx

* user essentials mob! 🔱

* create grafana/ui LoadingBar and set it up in Storybook

* Remove test changes on PanelChrome

* Fix mdx page reference

* dashboards squad mob! 🔱

lastFile:public/api-merged.json

* dashboards squad mob! 🔱

* dashboards squad mob! 🔱

* dashboards squad mob! 🔱

* dashboards squad mob! 🔱

lastFile:public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderState.tsx

* Implemented basic draft of panel header states. Using ToolbarButton instead of IconButton.

* use 'warning' styled Button in ToolbarButton

* make LoadingBar a simple JSX Element; do not use containerWidth; have a wrapper around the loading bar itself;

* fix wrapper around LoadingBar: willChange css prop makes performance of rerendering better

* States: Render general panel query error states and render notices next
to the title

* add streaming to PanelChrome if data is streaming instead of loading

* PanelHeaderState with its own state 'mode'

* clean up useEffect

* notices have their own square space in the size of the panel header

* clean up

* minor fixes

* moving the LoadingBar to core

* LoadingBar is not in grafana/ui

* always have a place for the loading bar in the PanelChrome, otherwise it moves everything when appearing;

remove titleItemsNodes for now - in later development

make no changes to Notice component, not part of this PR

* Revert "moving the LoadingBar to core"

This reverts commit 11f0f4ff2f.

* do not use internal comment as it doesn't do anything

* integrate LoadingBar in PanelChrome from grafana/ui directly

* fix deprecated leftItems comment

* Modify annimation to 1 second

* remove comments

* remove streaming stopped UI because we cannot know when the streaming has stopped

* skip unnecessary test for now

* no point in removing hoverHeader now, even though it's not yet implemented

* small fixes

* error state of the data in a panel is positioned in PanelChrome itself, not in PanelHeaderState

* Fixed loading state jitter

* remove warning state as we have none of it

* streaming cannot be stopped from the icon

* explicit content container width and height

* explicit content container width and height

* edit deprecated comment

* fix LoadingBar to be relative to width of panel; remove explicit width and height on content strict

* no warning state of the data

* status of the panel data given directly to PanelChrome, not a node

* clean up

* clean up console log

Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com>

* panel title design fits typography h6 styles; render error status only if error or error message are passed to PanelChrome

* add storybook examples; prepare PanelChrome for hoverHeader because this will be a breaking change and it will affect how the storybook example shows up

* show storybook example for streaming panel with title because that's the condition for having a header

* override margin-bottom: 0.45em of h6

Co-authored-by: Alexandra Vargas <alexa1866@gmail.com>
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com>
This commit is contained in:
Polina Boneva
2023-01-05 11:48:11 +02:00
committed by GitHub
parent 88a8cba6b0
commit 3f1908464d
9 changed files with 1715 additions and 6333 deletions

View File

@@ -34,6 +34,7 @@ import {
import { PANEL_BORDER } from 'app/core/constants';
import { profiler } from 'app/core/profiler';
import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel';
import { InspectTab } from 'app/features/inspector/types';
import { changeSeriesColorConfigFactory } from 'app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory';
import { RenderEvent } from 'app/types/events';
@@ -45,7 +46,6 @@ import { DashboardModel, PanelModel } from '../state';
import { loadSnapshotData } from '../utils/loadSnapshotData';
import { PanelHeader } from './PanelHeader/PanelHeader';
import { PanelHeaderLoadingIndicator } from './PanelHeader/PanelHeaderLoadingIndicator';
import { seriesVisibilityConfigFactory } from './SeriesVisibilityConfigFactory';
import { liveTimer } from './liveTimer';
@@ -566,6 +566,11 @@ export class PanelStateWrapper extends PureComponent<Props, State> {
return !panel.hasTitle();
}
onOpenErrorInspect(e: React.SyntheticEvent, tab: string) {
e.stopPropagation();
locationService.partial({ inspect: this.props.panel.id, inspectTab: tab });
}
render() {
const { dashboard, panel, isViewing, isEditing, width, height, plugin } = this.props;
const { errorMessage, data } = this.state;
@@ -581,17 +586,22 @@ export class PanelStateWrapper extends PureComponent<Props, State> {
[`panel-alert-state--${alertState}`]: alertState !== undefined,
});
// for new panel header design
const onCancelQuery = () => panel.getQueryRunner().cancelQuery();
const title = panel.getDisplayTitle();
const noPadding: PanelPadding = plugin.noPadding ? 'none' : 'md';
const leftItems = [
<PanelHeaderLoadingIndicator state={data.state} onClick={onCancelQuery} key="loading-indicator" />,
];
const padding: PanelPadding = plugin.noPadding ? 'none' : 'md';
if (config.featureToggles.newPanelChromeUI) {
return (
<PanelChrome width={width} height={height} title={title} leftItems={leftItems} padding={noPadding}>
<PanelChrome
width={width}
height={height}
padding={padding}
title={title}
loadingState={data.state}
status={{
message: errorMessage,
onClick: (e: React.SyntheticEvent) => this.onOpenErrorInspect(e, InspectTab.Error),
}}
>
{(innerWidth, innerHeight) => (
<>
<ErrorBoundary