From ffa0ef9b3d813bb8a9d60339cf3c61c02b9a9ad9 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Mon, 26 Jul 2021 11:57:52 -0700 Subject: [PATCH] Annotations: fire an event when changing annotations (#37175) --- packages/grafana-data/src/events/common.ts | 7 ++- .../dashboard/dashgrid/PanelChrome.tsx | 14 ++++-- .../panel/annolist/AnnoListPanel.test.tsx | 5 +- .../plugins/panel/annolist/AnnoListPanel.tsx | 48 ++++++++++++++++--- .../panel/annolist/AnnotationListItem.tsx | 7 --- .../panel/annolist/AnnotationListItemTags.tsx | 5 +- public/sass/_grafana.scss | 1 - public/sass/components/_panel_alertlist.scss | 11 ----- 8 files changed, 64 insertions(+), 34 deletions(-) delete mode 100644 public/sass/components/_panel_alertlist.scss diff --git a/packages/grafana-data/src/events/common.ts b/packages/grafana-data/src/events/common.ts index 1dc5ba66993..9021ddb7ccb 100644 --- a/packages/grafana-data/src/events/common.ts +++ b/packages/grafana-data/src/events/common.ts @@ -1,4 +1,4 @@ -import { DataFrame } from '../types'; +import { AnnotationEvent, DataFrame } from '../types'; import { BusEventWithPayload } from './types'; /** @@ -34,3 +34,8 @@ export class DataHoverClearEvent extends BusEventWithPayload { export class DataSelectEvent extends BusEventWithPayload { static type = 'data-select'; } + +/** @alpha */ +export class AnnotationChangeEvent extends BusEventWithPayload> { + static type = 'annotation-event'; +} diff --git a/public/app/features/dashboard/dashgrid/PanelChrome.tsx b/public/app/features/dashboard/dashgrid/PanelChrome.tsx index 43366f540b6..4ec676ec0bd 100644 --- a/public/app/features/dashboard/dashgrid/PanelChrome.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChrome.tsx @@ -15,6 +15,7 @@ import { DashboardModel, PanelModel } from '../state'; import { PANEL_BORDER } from 'app/core/constants'; import { AbsoluteTimeRange, + AnnotationChangeEvent, AnnotationEventUIModel, DashboardCursorSync, EventFilterOptions, @@ -278,7 +279,7 @@ export class PanelChrome extends Component { onAnnotationCreate = async (event: AnnotationEventUIModel) => { const isRegion = event.from !== event.to; - await saveAnnotation({ + const anno = { dashboardId: this.props.dashboard.id, panelId: this.props.panel.id, isRegion, @@ -286,18 +287,21 @@ export class PanelChrome extends Component { timeEnd: isRegion ? event.to : 0, tags: event.tags, text: event.description, - }); + }; + await saveAnnotation(anno); getDashboardQueryRunner().run({ dashboard: this.props.dashboard, range: this.timeSrv.timeRange() }); + this.state.context.eventBus.publish(new AnnotationChangeEvent(anno)); }; onAnnotationDelete = async (id: string) => { await deleteAnnotation({ id }); getDashboardQueryRunner().run({ dashboard: this.props.dashboard, range: this.timeSrv.timeRange() }); + this.state.context.eventBus.publish(new AnnotationChangeEvent({ id })); }; onAnnotationUpdate = async (event: AnnotationEventUIModel) => { const isRegion = event.from !== event.to; - await updateAnnotation({ + const anno = { id: event.id, dashboardId: this.props.dashboard.id, panelId: this.props.panel.id, @@ -306,9 +310,11 @@ export class PanelChrome extends Component { timeEnd: isRegion ? event.to : 0, tags: event.tags, text: event.description, - }); + }; + await updateAnnotation(anno); getDashboardQueryRunner().run({ dashboard: this.props.dashboard, range: this.timeSrv.timeRange() }); + this.state.context.eventBus.publish(new AnnotationChangeEvent(anno)); }; get hasPanelSnapshot() { diff --git a/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx b/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx index 576e6f834de..97e931d7819 100644 --- a/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx +++ b/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx @@ -56,7 +56,10 @@ async function setupTestContext({ data: { state: LoadingState.Done, timeRange: getDefaultTimeRange(), series: [] }, eventBus: { subscribe: jest.fn(), - getStream: jest.fn(), + getStream: () => + ({ + subscribe: jest.fn(), + } as any), publish: jest.fn(), removeAllListeners: jest.fn(), newScopedBus: jest.fn(), diff --git a/public/app/plugins/panel/annolist/AnnoListPanel.tsx b/public/app/plugins/panel/annolist/AnnoListPanel.tsx index fe2ec6ec1a9..aec121dfcd5 100644 --- a/public/app/plugins/panel/annolist/AnnoListPanel.tsx +++ b/public/app/plugins/panel/annolist/AnnoListPanel.tsx @@ -2,14 +2,25 @@ import React, { PureComponent } from 'react'; // Types import { AnnoOptions } from './types'; -import { AnnotationEvent, AppEvents, dateTime, DurationUnit, locationUtil, PanelProps } from '@grafana/data'; -import { getBackendSrv, locationService } from '@grafana/runtime'; +import { + AnnotationChangeEvent, + AnnotationEvent, + AppEvents, + dateTime, + DurationUnit, + GrafanaTheme, + locationUtil, + PanelProps, +} from '@grafana/data'; +import { config, getBackendSrv, locationService } from '@grafana/runtime'; import { AbstractList } from '@grafana/ui/src/components/List/AbstractList'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; import appEvents from 'app/core/app_events'; import { AnnotationListItem } from './AnnotationListItem'; import { AnnotationListItemTags } from './AnnotationListItemTags'; -import { CustomScrollbar } from '@grafana/ui'; +import { CustomScrollbar, stylesFactory } from '@grafana/ui'; +import { css } from '@emotion/css'; +import { Subscription } from 'rxjs'; interface UserInfo { id?: number; @@ -25,8 +36,10 @@ interface State { queryUser?: UserInfo; queryTags: string[]; } - export class AnnoListPanel extends PureComponent { + style = getStyles(config.theme); + subs = new Subscription(); + constructor(props: Props) { super(props); @@ -40,6 +53,19 @@ export class AnnoListPanel extends PureComponent { componentDidMount() { this.doSearch(); + + // When an annotation on this dashboard changes, re-run the query + this.subs.add( + this.props.eventBus.getStream(AnnotationChangeEvent).subscribe({ + next: () => { + this.doSearch(); + }, + }) + ); + } + + componentWillUnmount() { + this.subs.unsubscribe(); } componentDidUpdate(prevProps: Props, prevState: State) { @@ -48,7 +74,7 @@ export class AnnoListPanel extends PureComponent { options !== prevProps.options || this.state.queryTags !== prevState.queryTags || this.state.queryUser !== prevState.queryUser || - timeRange !== prevProps.timeRange; + (options.onlyInTimeRange && timeRange !== prevProps.timeRange); if (needsQuery) { this.doSearch(); @@ -228,10 +254,20 @@ export class AnnoListPanel extends PureComponent { )} - {annotations.length < 1 &&
No Annotations Found
} + {annotations.length < 1 &&
No Annotations Found
} `${item.id}`} /> ); } } + +const getStyles = stylesFactory((theme: GrafanaTheme) => ({ + noneFound: css` + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: calc(100% - 30px); + `, +})); diff --git a/public/app/plugins/panel/annolist/AnnotationListItem.tsx b/public/app/plugins/panel/annolist/AnnotationListItem.tsx index 1155df4ea8a..6c9e6a516c8 100644 --- a/public/app/plugins/panel/annolist/AnnotationListItem.tsx +++ b/public/app/plugins/panel/annolist/AnnotationListItem.tsx @@ -99,21 +99,17 @@ const TimeStamp: FC = ({ time, formatDate }) => { function getStyles(theme: GrafanaTheme) { return { pointer: css` - label: pointer; cursor: pointer; `, item: css` - label: labelItem; margin: ${theme.spacing.xs}; padding: ${theme.spacing.sm}; ${styleMixins.listItem(theme)}// display: flex; `, title: css` - label: title; flex-basis: 80%; `, link: css` - label: link; display: flex; .fa { @@ -125,7 +121,6 @@ function getStyles(theme: GrafanaTheme) { } `, login: css` - label: login; align-self: center; flex: auto; display: flex; @@ -133,13 +128,11 @@ function getStyles(theme: GrafanaTheme) { font-size: ${theme.typography.size.sm}; `, time: css` - label: time; margin-left: ${theme.spacing.sm}; font-size: ${theme.typography.size.sm}; color: ${theme.colors.textWeak}; `, avatar: css` - label: avatar; padding: ${theme.spacing.xs}; img { border-radius: 50%; diff --git a/public/app/plugins/panel/annolist/AnnotationListItemTags.tsx b/public/app/plugins/panel/annolist/AnnotationListItemTags.tsx index 80cc589bf01..d8469a06102 100644 --- a/public/app/plugins/panel/annolist/AnnotationListItemTags.tsx +++ b/public/app/plugins/panel/annolist/AnnotationListItemTags.tsx @@ -27,7 +27,7 @@ export const AnnotationListItemTags: FC = ({ tags, remove, onClick }) => } return ( -
+ <> {tags.map((tag) => { return ( onTagClicked(e, tag)} className={styles.pointer}> @@ -35,14 +35,13 @@ export const AnnotationListItemTags: FC = ({ tags, remove, onClick }) => ); })} -
+ ); }; function getStyles(theme: GrafanaTheme) { return { pointer: css` - label: pointer; cursor: pointer; padding: ${theme.spacing.xxs}; `, diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index 9a228e6874f..ef28cd03f5c 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -42,7 +42,6 @@ @import 'components/tags'; @import 'components/panel_graph'; @import 'components/submenu'; -@import 'components/panel_alertlist'; @import 'components/panel_dashlist'; @import 'components/panel_gettingstarted'; @import 'components/panel_piechart'; diff --git a/public/sass/components/_panel_alertlist.scss b/public/sass/components/_panel_alertlist.scss deleted file mode 100644 index c5d76c2f3b1..00000000000 --- a/public/sass/components/_panel_alertlist.scss +++ /dev/null @@ -1,11 +0,0 @@ -.panel-alert-list { - overflow-y: auto; -} - -.panel-alert-list__no-alerts { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: calc(100% - 30px); -}