mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Graphite: Rollup Indicator (#22738)
* WIP: Rollup indiator progress * Progress * Progress, can now open inspector with right tab * changed type and made inspect * Showing stats * Progress * Progress * Getting ready for v1 * Added option and fixed some strict nulls * Updated * Fixed test
This commit is contained in:
@@ -12,6 +12,7 @@ import { PanelChromeAngular } from './PanelChromeAngular';
|
||||
|
||||
// Actions
|
||||
import { initDashboardPanel } from '../state/actions';
|
||||
import { updateLocation } from 'app/core/reducers/location';
|
||||
|
||||
// Types
|
||||
import { PanelModel, DashboardModel } from '../state';
|
||||
@@ -33,6 +34,7 @@ export interface ConnectedProps {
|
||||
|
||||
export interface DispatchProps {
|
||||
initDashboardPanel: typeof initDashboardPanel;
|
||||
updateLocation: typeof updateLocation;
|
||||
}
|
||||
|
||||
export type Props = OwnProps & ConnectedProps & DispatchProps;
|
||||
@@ -72,7 +74,7 @@ export class DashboardPanelUnconnected extends PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
renderPanel(plugin: PanelPlugin) {
|
||||
const { dashboard, panel, isFullscreen, isInView, isInEditMode } = this.props;
|
||||
const { dashboard, panel, isFullscreen, isInView, isInEditMode, updateLocation } = this.props;
|
||||
|
||||
return (
|
||||
<AutoSizer>
|
||||
@@ -105,6 +107,7 @@ export class DashboardPanelUnconnected extends PureComponent<Props, State> {
|
||||
isInEditMode={isInEditMode}
|
||||
width={width}
|
||||
height={height}
|
||||
updateLocation={updateLocation}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
@@ -170,6 +173,6 @@ const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = (
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = { initDashboardPanel };
|
||||
const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = { initDashboardPanel, updateLocation };
|
||||
|
||||
export const DashboardPanel = connect(mapStateToProps, mapDispatchToProps)(DashboardPanelUnconnected);
|
||||
|
||||
@@ -11,6 +11,7 @@ import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel';
|
||||
import { profiler } from 'app/core/profiler';
|
||||
import { getProcessedDataFrames } from '../state/runRequest';
|
||||
import config from 'app/core/config';
|
||||
import { updateLocation } from 'app/core/actions';
|
||||
// Types
|
||||
import { DashboardModel, PanelModel } from '../state';
|
||||
import { PANEL_BORDER } from 'app/core/constants';
|
||||
@@ -36,6 +37,7 @@ export interface Props {
|
||||
isInEditMode?: boolean;
|
||||
width: number;
|
||||
height: number;
|
||||
updateLocation: typeof updateLocation;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
@@ -43,8 +45,6 @@ export interface State {
|
||||
renderCounter: number;
|
||||
errorMessage?: string;
|
||||
refreshWhenInView: boolean;
|
||||
|
||||
// Current state of all events
|
||||
data: PanelData;
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ export class PanelChrome extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { dashboard, panel, isFullscreen, width, height } = this.props;
|
||||
const { dashboard, panel, isFullscreen, width, height, updateLocation } = this.props;
|
||||
const { errorMessage, data } = this.state;
|
||||
const { transparent } = panel;
|
||||
|
||||
@@ -328,14 +328,14 @@ export class PanelChrome extends PureComponent<Props, State> {
|
||||
<PanelHeader
|
||||
panel={panel}
|
||||
dashboard={dashboard}
|
||||
timeInfo={data.request ? data.request.timeInfo : undefined}
|
||||
title={panel.title}
|
||||
description={panel.description}
|
||||
scopedVars={panel.scopedVars}
|
||||
links={panel.links}
|
||||
error={errorMessage}
|
||||
isFullscreen={isFullscreen}
|
||||
isLoading={data.state === LoadingState.Loading}
|
||||
data={data}
|
||||
updateLocation={updateLocation}
|
||||
/>
|
||||
<ErrorBoundary>
|
||||
{({ error }) => {
|
||||
|
||||
@@ -17,6 +17,7 @@ import config from 'app/core/config';
|
||||
import { DashboardModel, PanelModel } from '../state';
|
||||
import { StoreState } from 'app/types';
|
||||
import { LoadingState, DefaultTimeRange, PanelData, PanelPlugin, PanelEvents } from '@grafana/data';
|
||||
import { updateLocation } from 'app/core/actions';
|
||||
import { PANEL_BORDER } from 'app/core/constants';
|
||||
|
||||
interface OwnProps {
|
||||
@@ -35,6 +36,7 @@ interface ConnectedProps {
|
||||
|
||||
interface DispatchProps {
|
||||
setPanelAngularComponent: typeof setPanelAngularComponent;
|
||||
updateLocation: typeof updateLocation;
|
||||
}
|
||||
|
||||
export type Props = OwnProps & ConnectedProps & DispatchProps;
|
||||
@@ -215,7 +217,7 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { dashboard, panel, isFullscreen, plugin, angularComponent } = this.props;
|
||||
const { dashboard, panel, isFullscreen, plugin, angularComponent, updateLocation } = this.props;
|
||||
const { errorMessage, data, alertState } = this.state;
|
||||
const { transparent } = panel;
|
||||
|
||||
@@ -238,7 +240,6 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
|
||||
<PanelHeader
|
||||
panel={panel}
|
||||
dashboard={dashboard}
|
||||
timeInfo={data.request ? data.request.timeInfo : undefined}
|
||||
title={panel.title}
|
||||
description={panel.description}
|
||||
scopedVars={panel.scopedVars}
|
||||
@@ -246,7 +247,8 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
|
||||
links={panel.links}
|
||||
error={errorMessage}
|
||||
isFullscreen={isFullscreen}
|
||||
isLoading={data.state === LoadingState.Loading}
|
||||
data={data}
|
||||
updateLocation={updateLocation}
|
||||
/>
|
||||
<div className={panelContentClassNames}>
|
||||
<div ref={element => (this.element = element)} className="panel-height-helper" />
|
||||
@@ -262,6 +264,6 @@ const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = (
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = { setPanelAngularComponent };
|
||||
const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = { setPanelAngularComponent, updateLocation };
|
||||
|
||||
export const PanelChromeAngular = connect(mapStateToProps, mapDispatchToProps)(PanelChromeAngularUnconnected);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { Component } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { isEqual } from 'lodash';
|
||||
import { DataLink, ScopedVars, PanelMenuItem } from '@grafana/data';
|
||||
import { DataLink, ScopedVars, PanelMenuItem, PanelData, LoadingState, QueryResultMetaNotice } from '@grafana/data';
|
||||
import { AngularComponent } from '@grafana/runtime';
|
||||
import { ClickOutsideWrapper } from '@grafana/ui';
|
||||
import { ClickOutsideWrapper, Tooltip } from '@grafana/ui';
|
||||
import { e2e } from '@grafana/e2e';
|
||||
|
||||
import PanelHeaderCorner from './PanelHeaderCorner';
|
||||
@@ -14,11 +14,11 @@ import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
|
||||
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
|
||||
import { getPanelLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers';
|
||||
import { getPanelMenu } from 'app/features/dashboard/utils/getPanelMenu';
|
||||
import { updateLocation } from 'app/core/actions';
|
||||
|
||||
export interface Props {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
timeInfo?: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
scopedVars?: ScopedVars;
|
||||
@@ -26,7 +26,8 @@ export interface Props {
|
||||
links?: DataLink[];
|
||||
error?: string;
|
||||
isFullscreen: boolean;
|
||||
isLoading: boolean;
|
||||
data: PanelData;
|
||||
updateLocation: typeof updateLocation;
|
||||
}
|
||||
|
||||
interface ClickCoordinates {
|
||||
@@ -92,8 +93,35 @@ export class PanelHeader extends Component<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
openInspect = (e: React.SyntheticEvent, tab: string) => {
|
||||
const { updateLocation, panel } = this.props;
|
||||
|
||||
e.stopPropagation();
|
||||
|
||||
updateLocation({
|
||||
query: { inspect: panel.id, tab },
|
||||
partial: true,
|
||||
});
|
||||
};
|
||||
|
||||
renderNotice = (notice: QueryResultMetaNotice) => {
|
||||
return (
|
||||
<Tooltip content={notice.text} key={notice.severity}>
|
||||
{notice.inspect ? (
|
||||
<div className="panel-info-notice" onClick={e => this.openInspect(e, notice.inspect)}>
|
||||
<span className="fa fa-info-circle" style={{ marginRight: '8px', cursor: 'pointer' }} />
|
||||
</div>
|
||||
) : (
|
||||
<a className="panel-info-notice" href={notice.url} target="_blank">
|
||||
<span className="fa fa-info-circle" style={{ marginRight: '8px', cursor: 'pointer' }} />
|
||||
</a>
|
||||
)}
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { panel, timeInfo, scopedVars, error, isFullscreen, isLoading } = this.props;
|
||||
const { panel, scopedVars, error, isFullscreen, data } = this.props;
|
||||
const { menuItems } = this.state;
|
||||
const title = templateSrv.replaceWithText(panel.title, scopedVars);
|
||||
|
||||
@@ -102,9 +130,20 @@ export class PanelHeader extends Component<Props, State> {
|
||||
'grid-drag-handle': !isFullscreen,
|
||||
});
|
||||
|
||||
// dedupe on severity
|
||||
const notices: Record<string, QueryResultMetaNotice> = {};
|
||||
|
||||
for (const series of data.series) {
|
||||
if (series.meta && series.meta.notices) {
|
||||
for (const notice of series.meta.notices) {
|
||||
notices[notice.severity] = notice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading && this.renderLoadingState()}
|
||||
{data.state === LoadingState.Loading && this.renderLoadingState()}
|
||||
<div className={panelHeaderClass}>
|
||||
<PanelHeaderCorner
|
||||
panel={panel}
|
||||
@@ -121,6 +160,7 @@ export class PanelHeader extends Component<Props, State> {
|
||||
aria-label={e2e.pages.Dashboard.Panels.Panel.selectors.title(title)}
|
||||
>
|
||||
<div className="panel-title">
|
||||
{Object.values(notices).map(this.renderNotice)}
|
||||
<span className="icon-gf panel-alert-icon" />
|
||||
<span className="panel-title-text">
|
||||
{title} <span className="fa fa-caret-down panel-menu-toggle" />
|
||||
@@ -130,9 +170,9 @@ export class PanelHeader extends Component<Props, State> {
|
||||
<PanelHeaderMenu items={menuItems} />
|
||||
</ClickOutsideWrapper>
|
||||
)}
|
||||
{timeInfo && (
|
||||
{data.request && data.request.timeInfo && (
|
||||
<span className="panel-time-info">
|
||||
<i className="fa fa-clock-o" /> {timeInfo}
|
||||
<i className="fa fa-clock-o" /> {data.request.timeInfo}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user