mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Annotations: fire an event when changing annotations (#37175)
This commit is contained in:
@@ -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(),
|
||||
|
||||
@@ -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<Props, State> {
|
||||
style = getStyles(config.theme);
|
||||
subs = new Subscription();
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
@@ -40,6 +53,19 @@ export class AnnoListPanel extends PureComponent<Props, State> {
|
||||
|
||||
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<Props, State> {
|
||||
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<Props, State> {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{annotations.length < 1 && <div className="panel-alert-list__no-alerts">No Annotations Found</div>}
|
||||
{annotations.length < 1 && <div className={this.style.noneFound}>No Annotations Found</div>}
|
||||
|
||||
<AbstractList items={annotations} renderItem={this.renderItem} getItemKey={(item) => `${item.id}`} />
|
||||
</CustomScrollbar>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme) => ({
|
||||
noneFound: css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: calc(100% - 30px);
|
||||
`,
|
||||
}));
|
||||
|
||||
@@ -99,21 +99,17 @@ const TimeStamp: FC<TimeStampProps> = ({ 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%;
|
||||
|
||||
@@ -27,7 +27,7 @@ export const AnnotationListItemTags: FC<Props> = ({ tags, remove, onClick }) =>
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
{tags.map((tag) => {
|
||||
return (
|
||||
<span key={tag} onClick={(e) => onTagClicked(e, tag)} className={styles.pointer}>
|
||||
@@ -35,14 +35,13 @@ export const AnnotationListItemTags: FC<Props> = ({ tags, remove, onClick }) =>
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
function getStyles(theme: GrafanaTheme) {
|
||||
return {
|
||||
pointer: css`
|
||||
label: pointer;
|
||||
cursor: pointer;
|
||||
padding: ${theme.spacing.xxs};
|
||||
`,
|
||||
|
||||
Reference in New Issue
Block a user