mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PanelEvents: Refactors and removes unnecessary events, fixes panel editor update issue when panel options change (#29414)
* Refactoring some events to new events * More refactoring * Make panel editor subscribe to new event * Minor change and comment added * Updated snapshot
This commit is contained in:
parent
26e3b61f92
commit
bba1208c3d
@ -22,7 +22,6 @@ export const PanelEvents = {
|
||||
dataSnapshotLoad: eventFactory<DataQueryResponseData[]>('data-snapshot-load'),
|
||||
editModeInitialized: eventFactory('init-edit-mode'),
|
||||
initPanelActions: eventFactory<AngularPanelMenuItem[]>('init-panel-actions'),
|
||||
panelInitialized: eventFactory('panel-initialized'),
|
||||
panelSizeChanged: eventFactory('panel-size-changed'),
|
||||
panelTeardown: eventFactory('panel-teardown'),
|
||||
render: eventFactory<any>('render'),
|
||||
|
@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
|
||||
import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import { css, cx } from 'emotion';
|
||||
import { Unsubscribable } from 'rxjs';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { FieldConfigSource, GrafanaTheme, PanelPlugin } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
@ -36,6 +36,7 @@ import { CoreEvents, LocationState, StoreState } from 'app/types';
|
||||
import { DisplayMode, displayModes, PanelEditorTab } from './types';
|
||||
import { VariableModel } from 'app/features/variables/types';
|
||||
import { DashboardModel, PanelModel } from '../../state';
|
||||
import { PanelOptionsChangedEvent } from 'app/types/events';
|
||||
|
||||
interface OwnProps {
|
||||
dashboard: DashboardModel;
|
||||
@ -64,15 +65,30 @@ interface DispatchProps {
|
||||
type Props = OwnProps & ConnectedProps & DispatchProps;
|
||||
|
||||
export class PanelEditorUnconnected extends PureComponent<Props> {
|
||||
querySubscription: Unsubscribable;
|
||||
private eventSubs?: Subscription;
|
||||
|
||||
componentDidMount() {
|
||||
this.props.initPanelEditor(this.props.sourcePanel, this.props.dashboard);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { panel, initDone } = this.props;
|
||||
|
||||
if (initDone && !this.eventSubs) {
|
||||
this.eventSubs = new Subscription();
|
||||
this.eventSubs.add(panel.events.subscribe(PanelOptionsChangedEvent, this.triggerForceUpdate));
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.panelEditorCleanUp();
|
||||
this.eventSubs?.unsubscribe();
|
||||
}
|
||||
|
||||
triggerForceUpdate = () => {
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
onPanelExit = () => {
|
||||
this.props.updateLocation({
|
||||
query: { editPanel: null, tab: null },
|
||||
@ -113,8 +129,9 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
||||
};
|
||||
|
||||
onPanelOptionsChanged = (options: any) => {
|
||||
// we do not need to trigger force update here as the function call below
|
||||
// fires PanelOptionsChangedEvent which we subscribe to above
|
||||
this.props.panel.updateOptions(options);
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
onPanelConfigChanged = (configKey: string, value: any) => {
|
||||
|
@ -6,8 +6,9 @@ import { QueriesTab } from '../../panel_editor/QueriesTab';
|
||||
import { AlertTab } from 'app/features/alerting/AlertTab';
|
||||
import { TransformationsEditor } from '../TransformationsEditor/TransformationsEditor';
|
||||
import { DashboardModel, PanelModel } from '../../state';
|
||||
import { CoreEvents } from 'app/types';
|
||||
import { PanelEditorTab, PanelEditorTabId } from './types';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { PanelQueriesChangedEvent, PanelTransformationsChangedEvent } from 'app/types/events';
|
||||
|
||||
interface PanelEditorTabsProps {
|
||||
panel: PanelModel;
|
||||
@ -17,16 +18,16 @@ interface PanelEditorTabsProps {
|
||||
}
|
||||
|
||||
export class PanelEditorTabs extends PureComponent<PanelEditorTabsProps> {
|
||||
private eventSubs = new Subscription();
|
||||
|
||||
componentDidMount() {
|
||||
const { panel } = this.props;
|
||||
panel.on(CoreEvents.queryChanged, this.triggerForceUpdate);
|
||||
panel.on(CoreEvents.transformationChanged, this.triggerForceUpdate);
|
||||
const { events } = this.props.panel;
|
||||
this.eventSubs.add(events.subscribe(PanelQueriesChangedEvent, this.triggerForceUpdate));
|
||||
this.eventSubs.add(events.subscribe(PanelTransformationsChangedEvent, this.triggerForceUpdate));
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { panel } = this.props;
|
||||
panel.off(CoreEvents.queryChanged, this.triggerForceUpdate);
|
||||
panel.off(CoreEvents.transformationChanged, this.triggerForceUpdate);
|
||||
this.eventSubs.unsubscribe();
|
||||
}
|
||||
|
||||
triggerForceUpdate = () => {
|
||||
|
@ -14,8 +14,8 @@ import { DashboardRow } from '../components/DashboardRow';
|
||||
import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT } from 'app/core/constants';
|
||||
import { DashboardPanel } from './DashboardPanel';
|
||||
import { DashboardModel, PanelModel } from '../state';
|
||||
import { CoreEvents } from 'app/types';
|
||||
import { panelAdded, panelRemoved } from '../state/PanelModel';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { DashboardPanelsChangedEvent } from 'app/types/events';
|
||||
|
||||
let lastGridWidth = 1200;
|
||||
let ignoreNextWidthChange = false;
|
||||
@ -102,26 +102,17 @@ export interface Props {
|
||||
}
|
||||
|
||||
export class DashboardGrid extends PureComponent<Props> {
|
||||
panelMap: { [id: string]: PanelModel };
|
||||
panelRef: { [id: string]: HTMLElement } = {};
|
||||
private panelMap: { [id: string]: PanelModel };
|
||||
private panelRef: { [id: string]: HTMLElement } = {};
|
||||
private eventSubs = new Subscription();
|
||||
|
||||
componentDidMount() {
|
||||
const { dashboard } = this.props;
|
||||
|
||||
dashboard.on(panelAdded, this.triggerForceUpdate);
|
||||
dashboard.on(panelRemoved, this.triggerForceUpdate);
|
||||
dashboard.on(CoreEvents.repeatsProcessed, this.triggerForceUpdate);
|
||||
dashboard.on(CoreEvents.rowCollapsed, this.triggerForceUpdate);
|
||||
dashboard.on(CoreEvents.rowExpanded, this.triggerForceUpdate);
|
||||
this.eventSubs.add(dashboard.events.subscribe(DashboardPanelsChangedEvent, this.triggerForceUpdate));
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { dashboard } = this.props;
|
||||
dashboard.off(panelAdded, this.triggerForceUpdate);
|
||||
dashboard.off(panelRemoved, this.triggerForceUpdate);
|
||||
dashboard.off(CoreEvents.repeatsProcessed, this.triggerForceUpdate);
|
||||
dashboard.off(CoreEvents.rowCollapsed, this.triggerForceUpdate);
|
||||
dashboard.off(CoreEvents.rowExpanded, this.triggerForceUpdate);
|
||||
this.eventSubs.unsubscribe();
|
||||
}
|
||||
|
||||
buildLayout() {
|
||||
|
@ -71,33 +71,13 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
"events": EventBusSrv {
|
||||
"emitter": EventEmitter {
|
||||
"_events": Object {
|
||||
"panel-added": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"panel-removed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"repeats-processed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"row-collapsed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"row-expanded": EE {
|
||||
"dashboard-panels-changed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
},
|
||||
"_eventsCount": 5,
|
||||
"_eventsCount": 1,
|
||||
},
|
||||
},
|
||||
"getVariables": [Function],
|
||||
@ -313,33 +293,13 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
"events": EventBusSrv {
|
||||
"emitter": EventEmitter {
|
||||
"_events": Object {
|
||||
"panel-added": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"panel-removed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"repeats-processed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"row-collapsed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"row-expanded": EE {
|
||||
"dashboard-panels-changed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
},
|
||||
"_eventsCount": 5,
|
||||
"_eventsCount": 1,
|
||||
},
|
||||
},
|
||||
"getVariables": [Function],
|
||||
@ -555,33 +515,13 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
"events": EventBusSrv {
|
||||
"emitter": EventEmitter {
|
||||
"_events": Object {
|
||||
"panel-added": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"panel-removed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"repeats-processed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"row-collapsed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"row-expanded": EE {
|
||||
"dashboard-panels-changed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
},
|
||||
"_eventsCount": 5,
|
||||
"_eventsCount": 1,
|
||||
},
|
||||
},
|
||||
"getVariables": [Function],
|
||||
@ -797,33 +737,13 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
"events": EventBusSrv {
|
||||
"emitter": EventEmitter {
|
||||
"_events": Object {
|
||||
"panel-added": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"panel-removed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"repeats-processed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"row-collapsed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
"row-expanded": EE {
|
||||
"dashboard-panels-changed": EE {
|
||||
"context": [Circular],
|
||||
"fn": [Function],
|
||||
"once": false,
|
||||
},
|
||||
},
|
||||
"_eventsCount": 5,
|
||||
"_eventsCount": 1,
|
||||
},
|
||||
},
|
||||
"getVariables": [Function],
|
||||
|
@ -7,7 +7,7 @@ import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT, REPEAT_DIR_VERT
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import sortByKeys from 'app/core/utils/sort_by_keys';
|
||||
// Types
|
||||
import { GridPos, panelAdded, PanelModel, panelRemoved } from './PanelModel';
|
||||
import { GridPos, PanelModel } from './PanelModel';
|
||||
import { DashboardMigrator } from './DashboardMigrator';
|
||||
import {
|
||||
AppEvent,
|
||||
@ -27,6 +27,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';
|
||||
|
||||
export interface CloneOptions {
|
||||
saveVariables?: boolean;
|
||||
@ -285,8 +286,6 @@ export class DashboardModel {
|
||||
}
|
||||
|
||||
panelInitialized(panel: PanelModel) {
|
||||
panel.initialized();
|
||||
|
||||
const lastResult = panel.getQueryRunner().getLastResult();
|
||||
|
||||
if (!this.otherPanelInFullscreen(panel) && !lastResult) {
|
||||
@ -379,13 +378,11 @@ export class DashboardModel {
|
||||
addPanel(panelData: any) {
|
||||
panelData.id = this.getNextPanelId();
|
||||
|
||||
const panel = new PanelModel(panelData);
|
||||
|
||||
this.panels.unshift(panel);
|
||||
this.panels.unshift(new PanelModel(panelData));
|
||||
|
||||
this.sortPanelsByGridPos();
|
||||
|
||||
this.events.emit(panelAdded, panel);
|
||||
this.events.publish(new DashboardPanelsChangedEvent());
|
||||
}
|
||||
|
||||
sortPanelsByGridPos() {
|
||||
@ -422,7 +419,7 @@ export class DashboardModel {
|
||||
_.pull(this.panels, ...panelsToRemove);
|
||||
panelsToRemove.map(p => p.destroy());
|
||||
this.sortPanelsByGridPos();
|
||||
this.events.emit(CoreEvents.repeatsProcessed);
|
||||
this.events.publish(new DashboardPanelsChangedEvent());
|
||||
}
|
||||
|
||||
processRepeats() {
|
||||
@ -442,7 +439,7 @@ export class DashboardModel {
|
||||
}
|
||||
|
||||
this.sortPanelsByGridPos();
|
||||
this.events.emit(CoreEvents.repeatsProcessed);
|
||||
this.events.publish(new DashboardPanelsChangedEvent());
|
||||
}
|
||||
|
||||
cleanUpRowRepeats(rowPanels: PanelModel[]) {
|
||||
@ -681,9 +678,8 @@ export class DashboardModel {
|
||||
}
|
||||
|
||||
removePanel(panel: PanelModel) {
|
||||
const index = _.indexOf(this.panels, panel);
|
||||
this.panels.splice(index, 1);
|
||||
this.events.emit(panelRemoved, panel);
|
||||
this.panels = this.panels.filter(item => item !== panel);
|
||||
this.events.publish(new DashboardPanelsChangedEvent());
|
||||
}
|
||||
|
||||
removeRow(row: PanelModel, removePanels: boolean) {
|
||||
@ -848,7 +844,7 @@ export class DashboardModel {
|
||||
this.sortPanelsByGridPos();
|
||||
|
||||
// emit change event
|
||||
this.events.emit(CoreEvents.rowExpanded);
|
||||
this.events.publish(new DashboardPanelsChangedEvent());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -861,7 +857,7 @@ export class DashboardModel {
|
||||
row.collapsed = true;
|
||||
|
||||
// emit change event
|
||||
this.events.emit(CoreEvents.rowCollapsed);
|
||||
this.events.publish(new DashboardPanelsChangedEvent());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,12 +5,10 @@ import { getTemplateSrv } from '@grafana/runtime';
|
||||
import { getNextRefIdChar } from 'app/core/utils/query';
|
||||
// Types
|
||||
import {
|
||||
AppEvent,
|
||||
DataConfigSource,
|
||||
DataLink,
|
||||
DataQuery,
|
||||
DataTransformerConfig,
|
||||
eventFactory,
|
||||
FieldColorConfigSettings,
|
||||
FieldColorModeId,
|
||||
fieldColorModeRegistry,
|
||||
@ -29,10 +27,7 @@ import { EDIT_PANEL_ID } from 'app/core/constants';
|
||||
import config from 'app/core/config';
|
||||
import { PanelQueryRunner } from './PanelQueryRunner';
|
||||
import { getDatasourceSrv } from '../../plugins/datasource_srv';
|
||||
import { CoreEvents } from '../../../types';
|
||||
|
||||
export const panelAdded = eventFactory<PanelModel | undefined>('panel-added');
|
||||
export const panelRemoved = eventFactory<PanelModel | undefined>('panel-removed');
|
||||
import { PanelOptionsChangedEvent, PanelQueriesChangedEvent, PanelTransformationsChangedEvent } from 'app/types/events';
|
||||
|
||||
export interface GridPos {
|
||||
x: number;
|
||||
@ -219,6 +214,7 @@ export class PanelModel implements DataConfigSource {
|
||||
|
||||
updateOptions(options: object) {
|
||||
this.options = options;
|
||||
this.events.publish(new PanelOptionsChangedEvent());
|
||||
this.render();
|
||||
}
|
||||
|
||||
@ -291,10 +287,6 @@ export class PanelModel implements DataConfigSource {
|
||||
}
|
||||
}
|
||||
|
||||
initialized() {
|
||||
this.events.emit(PanelEvents.panelInitialized);
|
||||
}
|
||||
|
||||
private getOptionsToRemember() {
|
||||
return Object.keys(this).reduce((acc, property) => {
|
||||
if (notPersistedProperties[property] || mustKeepProps[property]) {
|
||||
@ -418,7 +410,7 @@ export class PanelModel implements DataConfigSource {
|
||||
}
|
||||
|
||||
updateQueries(queries: DataQuery[]) {
|
||||
this.events.emit(CoreEvents.queryChanged);
|
||||
this.events.publish(new PanelQueriesChangedEvent());
|
||||
this.targets = queries;
|
||||
}
|
||||
|
||||
@ -501,9 +493,9 @@ export class PanelModel implements DataConfigSource {
|
||||
}
|
||||
|
||||
setTransformations(transformations: DataTransformerConfig[]) {
|
||||
this.events.emit(CoreEvents.transformationChanged);
|
||||
this.transformations = transformations;
|
||||
this.resendLastResult();
|
||||
this.events.publish(new PanelTransformationsChangedEvent());
|
||||
}
|
||||
|
||||
replaceVariables(value: string, extraVars?: ScopedVars, format?: string) {
|
||||
@ -529,14 +521,6 @@ export class PanelModel implements DataConfigSource {
|
||||
getSavedId(): number {
|
||||
return this.editSourceId ?? this.id;
|
||||
}
|
||||
|
||||
on<T>(event: AppEvent<T>, callback: (payload?: T) => void) {
|
||||
this.events.on(event, callback);
|
||||
}
|
||||
|
||||
off<T>(event: AppEvent<T>, callback: (payload?: T) => void) {
|
||||
this.events.off(event, callback);
|
||||
}
|
||||
}
|
||||
|
||||
function applyFieldConfigDefaults(fieldConfig: FieldConfigSource, defaults: FieldConfigSource): FieldConfigSource {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { eventFactory, TimeRange } from '@grafana/data';
|
||||
import { BusEventBase, eventFactory, TimeRange } from '@grafana/data';
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
|
||||
/**
|
||||
@ -106,10 +106,6 @@ export const toggleKioskMode = eventFactory<ToggleKioskModePayload>('toggle-kios
|
||||
export const toggleViewMode = eventFactory('toggle-view-mode');
|
||||
|
||||
export const timeRangeUpdated = eventFactory<TimeRange>('time-range-updated');
|
||||
|
||||
export const repeatsProcessed = eventFactory('repeats-processed');
|
||||
export const rowExpanded = eventFactory('row-expanded');
|
||||
export const rowCollapsed = eventFactory('row-collapsed');
|
||||
export const templateVariableValueUpdated = eventFactory('template-variable-value-updated');
|
||||
export const submenuVisibilityChanged = eventFactory<boolean>('submenu-visibility-changed');
|
||||
|
||||
@ -125,5 +121,32 @@ export const elasticQueryUpdated = eventFactory('elastic-query-updated');
|
||||
|
||||
export const routeUpdated = eventFactory('$routeUpdate');
|
||||
|
||||
export const queryChanged = eventFactory('queryChanged');
|
||||
export const transformationChanged = eventFactory('transformationChanged');
|
||||
/**
|
||||
* Used for syncing queries badge count in panel edit queries tab
|
||||
* Think we can get rid of this soon
|
||||
*/
|
||||
export class PanelQueriesChangedEvent extends BusEventBase {
|
||||
static type = 'panel-queries-changed';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for syncing transformations badge count in panel edit transform tab
|
||||
* Think we can get rid of this soon
|
||||
*/
|
||||
export class PanelTransformationsChangedEvent extends BusEventBase {
|
||||
static type = 'panel-transformations-changed';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by panel editor to know when panel plugin it'self trigger option updates
|
||||
*/
|
||||
export class PanelOptionsChangedEvent extends BusEventBase {
|
||||
static type = 'panels-options-changed';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally by DashboardModel to commmunicate with DashboardGrid that it needs to re-render
|
||||
*/
|
||||
export class DashboardPanelsChangedEvent extends BusEventBase {
|
||||
static type = 'dashboard-panels-changed';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user