mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PanelEvents: Isolating angular panel events into it's own event bus + more event refactoring (#29904)
* PanelEvents: Isolate angular events from panel model events, use new Event patterns * Removing some events that are not longer needed * Updated DashboardModel * Update * Review fixes
This commit is contained in:
parent
334dfa7e3f
commit
e375fb0f2b
@ -22,7 +22,6 @@ export const PanelEvents = {
|
||||
dataSnapshotLoad: eventFactory<DataQueryResponseData[]>('data-snapshot-load'),
|
||||
editModeInitialized: eventFactory('init-edit-mode'),
|
||||
initPanelActions: eventFactory<AngularPanelMenuItem[]>('init-panel-actions'),
|
||||
panelSizeChanged: eventFactory('panel-size-changed'),
|
||||
panelTeardown: eventFactory('panel-teardown'),
|
||||
render: eventFactory<any>('render'),
|
||||
};
|
||||
|
@ -14,7 +14,6 @@ import {
|
||||
CoreApp,
|
||||
DataQueryRequest,
|
||||
DataSourceApi,
|
||||
PanelEvents,
|
||||
rangeUtil,
|
||||
ScopedVars,
|
||||
} from '@grafana/data';
|
||||
@ -26,6 +25,7 @@ import { map, mergeMap } from 'rxjs/operators';
|
||||
import { AnnotationQueryOptions, AnnotationQueryResponse } from './types';
|
||||
import { standardAnnotationSupport } from './standardAnnotationSupport';
|
||||
import { runRequest } from '../query/state/runRequest';
|
||||
import { RefreshEvent } from 'app/types/events';
|
||||
|
||||
let counter = 100;
|
||||
function getNextRequestId() {
|
||||
@ -41,7 +41,7 @@ export class AnnotationsSrv {
|
||||
// always clearPromiseCaches when loading new dashboard
|
||||
this.clearPromiseCaches();
|
||||
// clear promises on refresh events
|
||||
dashboard.on(PanelEvents.refresh, this.clearPromiseCaches.bind(this));
|
||||
dashboard.events.subscribe(RefreshEvent, this.clearPromiseCaches.bind(this));
|
||||
}
|
||||
|
||||
clearPromiseCaches() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Button, JSONFormatter, LoadingPlaceholder } from '@grafana/ui';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { AppEvents, PanelEvents, DataFrame } from '@grafana/data';
|
||||
import { AppEvents, DataFrame } from '@grafana/data';
|
||||
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { CopyToClipboard } from 'app/core/components/CopyToClipboard/CopyToClipboard';
|
||||
@ -10,8 +10,9 @@ import { getPanelInspectorStyles } from './styles';
|
||||
import { supportsDataQuery } from '../PanelEditor/utils';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { css } from 'emotion';
|
||||
import { Unsubscribable } from 'rxjs';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { backendSrv } from 'app/core/services/backend_srv';
|
||||
import { RefreshEvent } from 'app/types/events';
|
||||
|
||||
interface DsQuery {
|
||||
isLoading: boolean;
|
||||
@ -39,9 +40,8 @@ interface State {
|
||||
}
|
||||
|
||||
export class QueryInspector extends PureComponent<Props, State> {
|
||||
formattedJson: any;
|
||||
clipboard: any;
|
||||
subscription?: Unsubscribable;
|
||||
private formattedJson: any;
|
||||
private subs = new Subscription();
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
@ -58,11 +58,15 @@ export class QueryInspector extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.subscription = backendSrv.getInspectorStream().subscribe({
|
||||
next: response => this.onDataSourceResponse(response),
|
||||
});
|
||||
const { panel } = this.props;
|
||||
|
||||
this.props.panel.events.on(PanelEvents.refresh, this.onPanelRefresh);
|
||||
this.subs.add(
|
||||
backendSrv.getInspectorStream().subscribe({
|
||||
next: response => this.onDataSourceResponse(response),
|
||||
})
|
||||
);
|
||||
|
||||
this.subs.add(panel.events.subscribe(RefreshEvent, this.onPanelRefresh));
|
||||
this.updateQueryList();
|
||||
}
|
||||
|
||||
@ -112,13 +116,7 @@ export class QueryInspector extends PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
const { panel } = this.props;
|
||||
|
||||
if (this.subscription) {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
panel.events.off(PanelEvents.refresh, this.onPanelRefresh);
|
||||
this.subs.unsubscribe();
|
||||
}
|
||||
|
||||
onPanelRefresh = () => {
|
||||
|
@ -28,7 +28,6 @@ interface GridWrapperProps {
|
||||
onDragStop: ItemCallback;
|
||||
onResize: ItemCallback;
|
||||
onResizeStop: ItemCallback;
|
||||
onWidthChange: () => void;
|
||||
className: string;
|
||||
isResizable?: boolean;
|
||||
isDraggable?: boolean;
|
||||
@ -43,7 +42,6 @@ function GridWrapper({
|
||||
onDragStop,
|
||||
onResize,
|
||||
onResizeStop,
|
||||
onWidthChange,
|
||||
className,
|
||||
isResizable,
|
||||
isDraggable,
|
||||
@ -56,7 +54,6 @@ function GridWrapper({
|
||||
if (ignoreNextWidthChange) {
|
||||
ignoreNextWidthChange = false;
|
||||
} else if (!viewPanel && Math.abs(width - lastGridWidth) > 8) {
|
||||
onWidthChange();
|
||||
lastGridWidth = width;
|
||||
}
|
||||
}
|
||||
@ -164,12 +161,6 @@ export class DashboardGrid extends PureComponent<Props> {
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
onWidthChange = () => {
|
||||
for (const panel of this.props.dashboard.panels) {
|
||||
panel.resizeDone();
|
||||
}
|
||||
};
|
||||
|
||||
updateGridPos = (item: ReactGridLayout.Layout, layout: ReactGridLayout.Layout[]) => {
|
||||
this.panelMap[item.i!].updateGridPos(item);
|
||||
|
||||
@ -184,7 +175,6 @@ export class DashboardGrid extends PureComponent<Props> {
|
||||
|
||||
onResizeStop: ItemCallback = (layout, oldItem, newItem) => {
|
||||
this.updateGridPos(newItem, layout);
|
||||
this.panelMap[newItem.i!].resizeDone();
|
||||
};
|
||||
|
||||
onDragStop: ItemCallback = (layout, oldItem, newItem) => {
|
||||
@ -277,7 +267,6 @@ export class DashboardGrid extends PureComponent<Props> {
|
||||
isResizable={dashboard.meta.canEdit}
|
||||
isDraggable={dashboard.meta.canEdit}
|
||||
onLayoutChange={this.onLayoutChange}
|
||||
onWidthChange={this.onWidthChange}
|
||||
onDragStop={this.onDragStop}
|
||||
onResize={this.onResize}
|
||||
onResizeStop={this.onResizeStop}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Libraries
|
||||
import React, { Component } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Unsubscribable } from 'rxjs';
|
||||
import { Subscription } from 'rxjs';
|
||||
// Components
|
||||
import { PanelHeader } from './PanelHeader/PanelHeader';
|
||||
import { ErrorBoundary } from '@grafana/ui';
|
||||
@ -20,7 +20,6 @@ import {
|
||||
DefaultTimeRange,
|
||||
toUtc,
|
||||
toDataFrameDTO,
|
||||
PanelEvents,
|
||||
PanelData,
|
||||
PanelPlugin,
|
||||
FieldConfigSource,
|
||||
@ -28,6 +27,7 @@ import {
|
||||
} from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { loadSnapshotData } from '../utils/loadSnapshotData';
|
||||
import { RefreshEvent, RenderEvent } from 'app/types/events';
|
||||
|
||||
const DEFAULT_PLUGIN_ERROR = 'Error in plugin';
|
||||
|
||||
@ -52,9 +52,8 @@ export interface State {
|
||||
}
|
||||
|
||||
export class PanelChrome extends Component<Props, State> {
|
||||
readonly timeSrv: TimeSrv = getTimeSrv();
|
||||
|
||||
querySubscription?: Unsubscribable;
|
||||
private readonly timeSrv: TimeSrv = getTimeSrv();
|
||||
private subs = new Subscription();
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
@ -75,8 +74,8 @@ export class PanelChrome extends Component<Props, State> {
|
||||
const { panel, dashboard } = this.props;
|
||||
|
||||
// Subscribe to panel events
|
||||
panel.events.on(PanelEvents.refresh, this.onRefresh);
|
||||
panel.events.on(PanelEvents.render, this.onRender);
|
||||
this.subs.add(panel.events.subscribe(RefreshEvent, this.onRefresh));
|
||||
this.subs.add(panel.events.subscribe(RenderEvent, this.onRender));
|
||||
|
||||
dashboard.panelInitialized(this.props.panel);
|
||||
|
||||
@ -93,21 +92,18 @@ export class PanelChrome extends Component<Props, State> {
|
||||
this.setState({ isFirstLoad: false });
|
||||
}
|
||||
|
||||
this.querySubscription = panel
|
||||
.getQueryRunner()
|
||||
.getData({ withTransforms: true, withFieldConfig: true })
|
||||
.subscribe({
|
||||
next: data => this.onDataUpdate(data),
|
||||
});
|
||||
this.subs.add(
|
||||
panel
|
||||
.getQueryRunner()
|
||||
.getData({ withTransforms: true, withFieldConfig: true })
|
||||
.subscribe({
|
||||
next: data => this.onDataUpdate(data),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.panel.events.off(PanelEvents.refresh, this.onRefresh);
|
||||
this.props.panel.events.off(PanelEvents.render, this.onRender);
|
||||
|
||||
if (this.querySubscription) {
|
||||
this.querySubscription.unsubscribe();
|
||||
}
|
||||
this.subs.unsubscribe();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Libraries
|
||||
import React, { PureComponent } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Unsubscribable } from 'rxjs';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux';
|
||||
// Components
|
||||
import { PanelHeader } from './PanelHeader/PanelHeader';
|
||||
@ -13,10 +13,11 @@ import config from 'app/core/config';
|
||||
// Types
|
||||
import { DashboardModel, PanelModel } from '../state';
|
||||
import { StoreState } from 'app/types';
|
||||
import { DefaultTimeRange, LoadingState, PanelData, PanelEvents, PanelPlugin } from '@grafana/data';
|
||||
import { DefaultTimeRange, LoadingState, PanelData, PanelPlugin } from '@grafana/data';
|
||||
import { updateLocation } from 'app/core/actions';
|
||||
import { PANEL_BORDER } from 'app/core/constants';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { RenderEvent } from 'app/types/events';
|
||||
|
||||
interface OwnProps {
|
||||
panel: PanelModel;
|
||||
@ -59,7 +60,7 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
|
||||
element: HTMLElement | null = null;
|
||||
timeSrv: TimeSrv = getTimeSrv();
|
||||
scopeProps?: AngularScopeProps;
|
||||
querySubscription: Unsubscribable;
|
||||
subs = new Subscription();
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
@ -80,16 +81,13 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
|
||||
const queryRunner = panel.getQueryRunner();
|
||||
|
||||
// we are not displaying any of this data so no need for transforms or field config
|
||||
this.querySubscription = queryRunner.getData({ withTransforms: false, withFieldConfig: false }).subscribe({
|
||||
next: (data: PanelData) => this.onPanelDataUpdate(data),
|
||||
});
|
||||
}
|
||||
this.subs.add(
|
||||
queryRunner.getData({ withTransforms: false, withFieldConfig: false }).subscribe({
|
||||
next: (data: PanelData) => this.onPanelDataUpdate(data),
|
||||
})
|
||||
);
|
||||
|
||||
subscribeToRenderEvent() {
|
||||
// Subscribe to render event, this is as far as I know only needed for changes to title & transparent
|
||||
// These changes are modified in the model and only way to communicate that change is via this event
|
||||
// Need to find another solution for this in tthe future (panel title in redux?)
|
||||
this.props.panel.events.on(PanelEvents.render, this.onPanelRenderEvent);
|
||||
this.subs.add(panel.events.subscribe(RenderEvent, this.onPanelRenderEvent));
|
||||
}
|
||||
|
||||
onPanelRenderEvent = (payload?: any) => {
|
||||
@ -126,12 +124,7 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
|
||||
|
||||
componentWillUnmount() {
|
||||
this.cleanUpAngularPanel();
|
||||
|
||||
if (this.querySubscription) {
|
||||
this.querySubscription.unsubscribe();
|
||||
}
|
||||
|
||||
this.props.panel.events.off(PanelEvents.render, this.onPanelRenderEvent);
|
||||
this.subs.unsubscribe();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Props, prevState: State) {
|
||||
@ -146,7 +139,7 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
|
||||
if (this.scopeProps) {
|
||||
this.scopeProps.size.height = this.getInnerPanelHeight();
|
||||
this.scopeProps.size.width = this.getInnerPanelWidth();
|
||||
panel.events.emit(PanelEvents.panelSizeChanged);
|
||||
panel.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -189,9 +182,6 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
|
||||
panelId: panel.id,
|
||||
angularComponent: loader.load(this.element, this.scopeProps, template),
|
||||
});
|
||||
|
||||
// need to to this every time we load an angular as all events are unsubscribed when panel is destroyed
|
||||
this.subscribeToRenderEvent();
|
||||
}
|
||||
|
||||
cleanUpAngularPanel() {
|
||||
|
@ -41,7 +41,6 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
onLayoutChange={[Function]}
|
||||
onResize={[Function]}
|
||||
onResizeStop={[Function]}
|
||||
onWidthChange={[Function]}
|
||||
viewPanel={null}
|
||||
>
|
||||
<div
|
||||
|
@ -16,7 +16,6 @@ import {
|
||||
DateTimeInput,
|
||||
EventBusExtended,
|
||||
EventBusSrv,
|
||||
PanelEvents,
|
||||
TimeRange,
|
||||
TimeZone,
|
||||
UrlQueryValue,
|
||||
@ -27,7 +26,7 @@ import { variableAdapters } from 'app/features/variables/adapters';
|
||||
import { onTimeRangeUpdated } from 'app/features/variables/state/actions';
|
||||
import { dispatch } from '../../../store/store';
|
||||
import { isAllVariable } from '../../variables/utils';
|
||||
import { DashboardPanelsChangedEvent } from 'app/types/events';
|
||||
import { DashboardPanelsChangedEvent, RefreshEvent, RenderEvent } from 'app/types/events';
|
||||
|
||||
export interface CloneOptions {
|
||||
saveVariables?: boolean;
|
||||
@ -266,7 +265,7 @@ export class DashboardModel {
|
||||
}
|
||||
|
||||
startRefresh() {
|
||||
this.events.emit(PanelEvents.refresh);
|
||||
this.events.publish(new RefreshEvent());
|
||||
|
||||
if (this.panelInEdit) {
|
||||
this.panelInEdit.refresh();
|
||||
@ -281,8 +280,7 @@ export class DashboardModel {
|
||||
}
|
||||
|
||||
render() {
|
||||
this.events.emit(PanelEvents.render);
|
||||
|
||||
this.events.publish(new RenderEvent());
|
||||
for (const panel of this.panels) {
|
||||
panel.render();
|
||||
}
|
||||
@ -884,11 +882,15 @@ export class DashboardModel {
|
||||
return rowPanels;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
on<T>(event: AppEvent<T>, callback: (payload?: T) => void) {
|
||||
console.log('DashboardModel.on is deprecated use events.subscribe');
|
||||
this.events.on(event, callback);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
off<T>(event: AppEvent<T>, callback: (payload?: T) => void) {
|
||||
console.log('DashboardModel.off is deprecated');
|
||||
this.events.off(event, callback);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,13 @@ import {
|
||||
import { EDIT_PANEL_ID } from 'app/core/constants';
|
||||
import config from 'app/core/config';
|
||||
import { PanelQueryRunner } from '../../query/state/PanelQueryRunner';
|
||||
import { PanelOptionsChangedEvent, PanelQueriesChangedEvent, PanelTransformationsChangedEvent } from 'app/types/events';
|
||||
import {
|
||||
PanelOptionsChangedEvent,
|
||||
PanelQueriesChangedEvent,
|
||||
PanelTransformationsChangedEvent,
|
||||
RefreshEvent,
|
||||
RenderEvent,
|
||||
} from 'app/types/events';
|
||||
import { getTimeSrv } from '../services/TimeSrv';
|
||||
import { getAllVariableValuesForUrl } from '../../variables/getAllVariableValuesForUrl';
|
||||
|
||||
@ -258,36 +264,22 @@ export class PanelModel implements DataConfigSource {
|
||||
}
|
||||
|
||||
updateGridPos(newPos: GridPos) {
|
||||
let sizeChanged = false;
|
||||
|
||||
if (this.gridPos.w !== newPos.w || this.gridPos.h !== newPos.h) {
|
||||
sizeChanged = true;
|
||||
}
|
||||
|
||||
this.gridPos.x = newPos.x;
|
||||
this.gridPos.y = newPos.y;
|
||||
this.gridPos.w = newPos.w;
|
||||
this.gridPos.h = newPos.h;
|
||||
|
||||
if (sizeChanged) {
|
||||
this.events.emit(PanelEvents.panelSizeChanged);
|
||||
}
|
||||
}
|
||||
|
||||
resizeDone() {
|
||||
this.events.emit(PanelEvents.panelSizeChanged);
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.hasRefreshed = true;
|
||||
this.events.emit(PanelEvents.refresh);
|
||||
this.events.publish(new RefreshEvent());
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.hasRefreshed) {
|
||||
this.refresh();
|
||||
} else {
|
||||
this.events.emit(PanelEvents.render);
|
||||
this.events.publish(new RenderEvent());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,14 @@ import _ from 'lodash';
|
||||
import config from 'app/core/config';
|
||||
import { profiler } from 'app/core/core';
|
||||
import { auto } from 'angular';
|
||||
import { AppEvent, PanelEvents, PanelPluginMeta, AngularPanelMenuItem, EventBusExtended } from '@grafana/data';
|
||||
import {
|
||||
AppEvent,
|
||||
PanelEvents,
|
||||
PanelPluginMeta,
|
||||
AngularPanelMenuItem,
|
||||
EventBusExtended,
|
||||
EventBusSrv,
|
||||
} from '@grafana/data';
|
||||
import { DashboardModel } from '../dashboard/state';
|
||||
|
||||
export class PanelCtrl {
|
||||
@ -30,7 +37,7 @@ export class PanelCtrl {
|
||||
this.$scope = $scope;
|
||||
this.$timeout = $injector.get('$timeout');
|
||||
this.editorTabs = [];
|
||||
this.events = this.panel.events;
|
||||
this.events = new EventBusSrv();
|
||||
this.timing = {}; // not used but here to not break plugins
|
||||
|
||||
const plugin = config.panels[this.panel.type];
|
||||
|
@ -4,6 +4,8 @@ import baron from 'baron';
|
||||
import { PanelEvents } from '@grafana/data';
|
||||
import { PanelModel } from '../dashboard/state';
|
||||
import { PanelCtrl } from './panel_ctrl';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { RefreshEvent, RenderEvent } from 'app/types/events';
|
||||
|
||||
const module = angular.module('grafana.directives');
|
||||
|
||||
@ -20,6 +22,7 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
|
||||
link: (scope: any, elem) => {
|
||||
const ctrl: PanelCtrl = scope.ctrl;
|
||||
const panel: PanelModel = scope.ctrl.panel;
|
||||
const subs = new Subscription();
|
||||
|
||||
let panelScrollbar: any;
|
||||
|
||||
@ -58,32 +61,38 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
|
||||
}
|
||||
});
|
||||
|
||||
function onPanelSizeChanged() {
|
||||
$timeout(() => {
|
||||
resizeScrollableContent();
|
||||
ctrl.render();
|
||||
});
|
||||
}
|
||||
|
||||
function onPanelModelRender(payload?: any) {
|
||||
function updateDimensionsFromParentScope() {
|
||||
ctrl.height = scope.$parent.$parent.size.height;
|
||||
ctrl.width = scope.$parent.$parent.size.width;
|
||||
}
|
||||
|
||||
function onPanelModelRefresh() {
|
||||
ctrl.height = scope.$parent.$parent.size.height;
|
||||
ctrl.width = scope.$parent.$parent.size.width;
|
||||
}
|
||||
// Pass PanelModel events down to angular controller event emitter
|
||||
subs.add(
|
||||
panel.events.subscribe(RefreshEvent, () => {
|
||||
updateDimensionsFromParentScope();
|
||||
ctrl.events.emit('refresh');
|
||||
})
|
||||
);
|
||||
|
||||
panel.events.on(PanelEvents.refresh, onPanelModelRefresh);
|
||||
panel.events.on(PanelEvents.render, onPanelModelRender);
|
||||
panel.events.on(PanelEvents.panelSizeChanged, onPanelSizeChanged);
|
||||
subs.add(
|
||||
panel.events.subscribe(RenderEvent, () => {
|
||||
updateDimensionsFromParentScope();
|
||||
|
||||
$timeout(() => {
|
||||
resizeScrollableContent();
|
||||
ctrl.events.emit('render');
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
scope.$on('$destroy', () => {
|
||||
elem.off();
|
||||
|
||||
panel.events.emit(PanelEvents.panelTeardown);
|
||||
panel.events.removeAllListeners();
|
||||
// Remove PanelModel.event subs
|
||||
subs.unsubscribe();
|
||||
// Remove Angular controller event subs
|
||||
ctrl.events.emit(PanelEvents.panelTeardown);
|
||||
ctrl.events.removeAllListeners();
|
||||
|
||||
if (panelScrollbar) {
|
||||
panelScrollbar.dispose();
|
||||
|
@ -4,7 +4,7 @@ import _ from 'lodash';
|
||||
import config from 'app/core/config';
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
import { DataSourceApi } from '@grafana/data';
|
||||
import { DataSourceApi, PanelEvents } from '@grafana/data';
|
||||
import { importPanelPlugin, importDataSourcePlugin, importAppPlugin } from './plugin_loader';
|
||||
import DatasourceSrv from './datasource_srv';
|
||||
import { GrafanaRootScope } from 'app/routes/GrafanaCtrl';
|
||||
@ -229,7 +229,7 @@ function pluginDirectiveLoader(
|
||||
elem.append(child);
|
||||
setTimeout(() => {
|
||||
scope.$applyAsync(() => {
|
||||
scope.$broadcast('component-did-mount');
|
||||
scope.$broadcast(PanelEvents.componentDidMount.name);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -148,3 +148,11 @@ export class PanelOptionsChangedEvent extends BusEventBase {
|
||||
export class DashboardPanelsChangedEvent extends BusEventBase {
|
||||
static type = 'dashboard-panels-changed';
|
||||
}
|
||||
|
||||
export class RefreshEvent extends BusEventBase {
|
||||
static type = 'refresh';
|
||||
}
|
||||
|
||||
export class RenderEvent extends BusEventBase {
|
||||
static type = 'render';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user