Commit de314851 by Torkel Ödegaard Committed by GitHub

NewPanelEditor: Fixes alert state & annotations, alert history (#23124)

* Updated title to show dashboard title

* Sort of fixed annotations and alerting state
parent 4eae1b54
...@@ -104,13 +104,15 @@ class UnConnectedAlertTab extends PureComponent<Props, State> { ...@@ -104,13 +104,15 @@ class UnConnectedAlertTab extends PureComponent<Props, State> {
} }
stateHistory = (): EditorToolbarView => { stateHistory = (): EditorToolbarView => {
const { panel, dashboard } = this.props;
return { return {
title: 'State history', title: 'State history',
render: () => { render: () => {
return ( return (
<StateHistory <StateHistory
dashboard={this.props.dashboard} dashboard={dashboard}
panelId={this.props.panel.id} panelId={panel.editSourceId ?? panel.id}
onRefresh={this.panelCtrl.refresh} onRefresh={this.panelCtrl.refresh}
/> />
); );
......
...@@ -7,8 +7,8 @@ import coreModule from 'app/core/core_module'; ...@@ -7,8 +7,8 @@ import coreModule from 'app/core/core_module';
// Utils & Services // Utils & Services
import { dedupAnnotations } from './events_processing'; import { dedupAnnotations } from './events_processing';
// Types // Types
import { DashboardModel } from '../dashboard/state/DashboardModel'; import { DashboardModel, PanelModel } from '../dashboard/state';
import { AnnotationEvent, AppEvents, DataSourceApi, PanelEvents, PanelModel, TimeRange } from '@grafana/data'; import { AnnotationEvent, AppEvents, DataSourceApi, PanelEvents, TimeRange } from '@grafana/data';
import { getBackendSrv, getDataSourceSrv } from '@grafana/runtime'; import { getBackendSrv, getDataSourceSrv } from '@grafana/runtime';
import { appEvents } from 'app/core/core'; import { appEvents } from 'app/core/core';
import { getTimeSrv } from '../dashboard/services/TimeSrv'; import { getTimeSrv } from '../dashboard/services/TimeSrv';
...@@ -36,12 +36,14 @@ export class AnnotationsSrv { ...@@ -36,12 +36,14 @@ export class AnnotationsSrv {
.then(results => { .then(results => {
// combine the annotations and flatten results // combine the annotations and flatten results
let annotations: AnnotationEvent[] = flattenDeep(results[0]); let annotations: AnnotationEvent[] = flattenDeep(results[0]);
// when in edit mode we need to use editSourceId
let panelFilterId = options.panel.editSourceId ?? options.panel.id;
// filter out annotations that do not belong to requesting panel // filter out annotations that do not belong to requesting panel
annotations = annotations.filter(item => { annotations = annotations.filter(item => {
// if event has panel id and query is of type dashboard then panel and requesting panel id must match // if event has panel id and query is of type dashboard then panel and requesting panel id must match
if (item.panelId && item.source.type === 'dashboard') { if (item.panelId && item.source.type === 'dashboard') {
return item.panelId === options.panel.id; return item.panelId === panelFilterId;
} }
return true; return true;
}); });
...@@ -49,7 +51,7 @@ export class AnnotationsSrv { ...@@ -49,7 +51,7 @@ export class AnnotationsSrv {
annotations = dedupAnnotations(annotations); annotations = dedupAnnotations(annotations);
// look for alert state for this panel // look for alert state for this panel
const alertState: any = results[1].find((res: any) => res.panelId === options.panel.id); const alertState: any = results[1].find((res: any) => res.panelId === panelFilterId);
return { return {
annotations: annotations, annotations: annotations,
......
...@@ -14,7 +14,6 @@ import { StoreState } from '../../../../types/store'; ...@@ -14,7 +14,6 @@ import { StoreState } from '../../../../types/store';
import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux'; import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux';
import { updateLocation } from '../../../../core/reducers/location'; import { updateLocation } from '../../../../core/reducers/location';
import { Unsubscribable } from 'rxjs'; import { Unsubscribable } from 'rxjs';
import { PanelTitle } from './PanelTitle';
import { DisplayMode, displayModes, PanelEditorTab } from './types'; import { DisplayMode, displayModes, PanelEditorTab } from './types';
import { PanelEditorTabs } from './PanelEditorTabs'; import { PanelEditorTabs } from './PanelEditorTabs';
import { DashNavTimeControls } from '../DashNav/DashNavTimeControls'; import { DashNavTimeControls } from '../DashNav/DashNavTimeControls';
...@@ -187,14 +186,14 @@ export class PanelEditorUnconnected extends PureComponent<Props> { ...@@ -187,14 +186,14 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
} }
renderToolbar() { renderToolbar() {
const { dashboard, location, uiState, panel } = this.props; const { dashboard, location, uiState } = this.props;
const styles = getStyles(config.theme); const styles = getStyles(config.theme);
return ( return (
<div className={styles.toolbar}> <div className={styles.toolbar}>
<div className={styles.toolbarLeft}> <div className={styles.toolbarLeft}>
<BackButton onClick={this.onPanelExit} /> <BackButton onClick={this.onPanelExit} />
<PanelTitle value={panel.title} onChange={this.onPanelTitleChange} /> <span className={styles.editorTitle}>{dashboard.title} / Edit Panel</span>
</div> </div>
<div className={styles.toolbarLeft}> <div className={styles.toolbarLeft}>
<div className={styles.toolbarItem}> <div className={styles.toolbarItem}>
...@@ -403,5 +402,9 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => { ...@@ -403,5 +402,9 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
`, `,
editorTitle: css`
font-size: ${theme.typography.size.lg};
padding-left: ${theme.spacing.md};
`,
}; };
}); });
import React, { useState } from 'react';
import { css } from 'emotion';
import { Forms, useTheme, stylesFactory } from '@grafana/ui';
import { GrafanaTheme } from '@grafana/data';
interface PanelTitleProps {
value: string;
onChange: (value: string) => void;
}
export const PanelTitle: React.FC<PanelTitleProps> = ({ value, onChange }) => {
const [isEditing, setIsEditing] = useState(false);
const theme = useTheme();
const styles = getStyles(theme);
return (
<div className={styles.wrapper}>
{isEditing ? (
<Forms.Input
value={value || ''}
ref={elem => elem && elem.focus()}
onChange={e => onChange(e.currentTarget.value)}
onBlur={() => setIsEditing(false)}
placeholder="Panel Title"
/>
) : (
<span onClick={() => setIsEditing(true)}>{value}</span>
)}
</div>
);
};
const getStyles = stylesFactory((theme: GrafanaTheme) => {
return {
wrapper: css`
font-size: ${theme.typography.size.lg};
padding-left: ${theme.spacing.md};
`,
};
});
...@@ -45,6 +45,7 @@ const notPersistedProperties: { [str: string]: boolean } = { ...@@ -45,6 +45,7 @@ const notPersistedProperties: { [str: string]: boolean } = {
plugin: true, plugin: true,
queryRunner: true, queryRunner: true,
replaceVariables: true, replaceVariables: true,
editSourceId: true,
}; };
// For angular panels we need to clean up properties when changing type // For angular panels we need to clean up properties when changing type
...@@ -96,6 +97,7 @@ const defaults: any = { ...@@ -96,6 +97,7 @@ const defaults: any = {
export class PanelModel implements DataConfigSource { export class PanelModel implements DataConfigSource {
/* persisted id, used in URL to identify a panel */ /* persisted id, used in URL to identify a panel */
id: number; id: number;
editSourceId: number;
gridPos: GridPos; gridPos: GridPos;
type: string; type: string;
title: string; title: string;
...@@ -389,6 +391,7 @@ export class PanelModel implements DataConfigSource { ...@@ -389,6 +391,7 @@ export class PanelModel implements DataConfigSource {
// Temporary id for the clone, restored later in redux action when changes are saved // Temporary id for the clone, restored later in redux action when changes are saved
sourceModel.id = EDIT_PANEL_ID; sourceModel.id = EDIT_PANEL_ID;
sourceModel.editSourceId = this.id;
const clone = new PanelModel(sourceModel); const clone = new PanelModel(sourceModel);
const sourceQueryRunner = this.getQueryRunner(); const sourceQueryRunner = this.getQueryRunner();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment