AppEvents: export appEvents in @grafana/runtime and support copy panel (#40715)

This commit is contained in:
Ryan McKinley 2021-10-20 13:01:21 -07:00 committed by GitHub
parent b60ae7ebed
commit ad69de4a10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 85 additions and 39 deletions

View File

@ -0,0 +1,59 @@
import { BusEventBase, BusEventWithPayload, EventBus, GrafanaTheme2, PanelModel, TimeRange } from '@grafana/data';
/**
* Called when a dashboard is refreshed
*
* @public
*/
export class RefreshEvent extends BusEventBase {
static type = 'refresh';
}
/**
* Called when the theme settings change
*
* @public
*/
export class ThemeChangedEvent extends BusEventWithPayload<GrafanaTheme2> {
static type = 'theme-changed';
}
/**
* Called when time range is updated
*
* @public
*/
export class TimeRangeUpdatedEvent extends BusEventWithPayload<TimeRange> {
static type = 'time-range-updated';
}
/**
* Called to copy a panel JSON into local storage
*
* @public
*/
export class CopyPanelEvent extends BusEventWithPayload<PanelModel> {
static type = 'copy-panel';
}
// Internal singleton instance
let singletonInstance: EventBus;
/**
* Used during startup by Grafana to set the LocationSrv so it is available
* via the {@link getLocationSrv} to the rest of the application.
*
* @internal
*/
export function setAppEvents(instance: EventBus) {
singletonInstance = instance;
}
/**
* Used to retrieve an event bus that manages application level events
*
* @public
*/
export function getAppEvents(): EventBus {
return singletonInstance;
}

View File

@ -7,3 +7,4 @@ export * from './templateSrv';
export * from './legacyAngularInjector'; export * from './legacyAngularInjector';
export * from './live'; export * from './live';
export * from './LocationService'; export * from './LocationService';
export * from './appEvents';

View File

@ -4,8 +4,9 @@ import { PanelEvents } from '@grafana/data';
import { PanelModel } from '../../features/dashboard/state'; import { PanelModel } from '../../features/dashboard/state';
import { PanelCtrl } from './panel_ctrl'; import { PanelCtrl } from './panel_ctrl';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { PanelDirectiveReadyEvent, RefreshEvent, RenderEvent } from 'app/types/events'; import { PanelDirectiveReadyEvent, RenderEvent } from 'app/types/events';
import { coreModule } from 'app/core/core_module'; import { coreModule } from 'app/core/core_module';
import { RefreshEvent } from '@grafana/runtime';
const panelTemplate = ` const panelTemplate = `
<ng-transclude class="panel-height-helper"></ng-transclude> <ng-transclude class="panel-height-helper"></ng-transclude>

View File

@ -1,4 +1,4 @@
import { ThemeChangedEvent } from 'app/types/events'; import { ThemeChangedEvent } from '@grafana/runtime';
import appEvents from '../app_events'; import appEvents from '../app_events';
import { config } from '../config'; import { config } from '../config';
import { PreferencesService } from './PreferencesService'; import { PreferencesService } from './PreferencesService';

View File

@ -16,6 +16,8 @@ import {
} from '../../types/events'; } from '../../types/events';
import { ConfirmModal, ConfirmModalProps } from '@grafana/ui'; import { ConfirmModal, ConfirmModalProps } from '@grafana/ui';
import { deprecationWarning, textUtil } from '@grafana/data'; import { deprecationWarning, textUtil } from '@grafana/data';
import { CopyPanelEvent } from '@grafana/runtime';
import { copyPanel } from 'app/features/dashboard/utils/panel';
export class UtilSrv { export class UtilSrv {
modalScope: any; modalScope: any;
@ -32,6 +34,7 @@ export class UtilSrv {
appEvents.subscribe(HideModalEvent, this.hideModal.bind(this)); appEvents.subscribe(HideModalEvent, this.hideModal.bind(this));
appEvents.subscribe(ShowConfirmModalEvent, (e) => this.showConfirmModal(e.payload)); appEvents.subscribe(ShowConfirmModalEvent, (e) => this.showConfirmModal(e.payload));
appEvents.subscribe(ShowModalReactEvent, (e) => this.showModalReact(e.payload)); appEvents.subscribe(ShowModalReactEvent, (e) => this.showModalReact(e.payload));
appEvents.subscribe(CopyPanelEvent, (e) => copyPanel(e.payload));
} }
showModalReact(options: any) { showModalReact(options: any) {

View File

@ -1,8 +1,7 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { config, GrafanaBootConfig } from '@grafana/runtime'; import { config, GrafanaBootConfig, ThemeChangedEvent } from '@grafana/runtime';
import { ThemeContext } from '@grafana/ui'; import { ThemeContext } from '@grafana/ui';
import { appEvents } from '../core'; import { appEvents } from '../core';
import { ThemeChangedEvent } from 'app/types/events';
import { createTheme } from '@grafana/data'; import { createTheme } from '@grafana/data';
export const ConfigContext = React.createContext<GrafanaBootConfig>(config); export const ConfigContext = React.createContext<GrafanaBootConfig>(config);

View File

@ -1,6 +1,7 @@
// Libraries // Libraries
import React, { Component } from 'react'; import React, { Component } from 'react';
import { dateMath, TimeRange, TimeZone } from '@grafana/data'; import { dateMath, TimeRange, TimeZone } from '@grafana/data';
import { TimeRangeUpdatedEvent } from '@grafana/runtime';
// Types // Types
import { DashboardModel } from '../../state'; import { DashboardModel } from '../../state';
@ -12,7 +13,7 @@ import { TimePickerWithHistory } from 'app/core/components/TimePicker/TimePicker
// Utils & Services // Utils & Services
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { appEvents } from 'app/core/core'; import { appEvents } from 'app/core/core';
import { ShiftTimeEvent, ShiftTimeEventPayload, TimeRangeUpdatedEvent, ZoomOutEvent } from '../../../../types/events'; import { ShiftTimeEvent, ShiftTimeEventPayload, ZoomOutEvent } from '../../../../types/events';
import { Unsubscribable } from 'rxjs'; import { Unsubscribable } from 'rxjs';
export interface Props { export interface Props {

View File

@ -5,8 +5,8 @@ import { PanelModel } from '../../state/PanelModel';
import { DashboardModel } from '../../state/DashboardModel'; import { DashboardModel } from '../../state/DashboardModel';
import appEvents from 'app/core/app_events'; import appEvents from 'app/core/app_events';
import { RowOptionsButton } from '../RowOptions/RowOptionsButton'; import { RowOptionsButton } from '../RowOptions/RowOptionsButton';
import { getTemplateSrv } from '@grafana/runtime'; import { getTemplateSrv, RefreshEvent } from '@grafana/runtime';
import { RefreshEvent, ShowConfirmModalEvent } from '../../../../types/events'; import { ShowConfirmModalEvent } from '../../../../types/events';
import { Unsubscribable } from 'rxjs'; import { Unsubscribable } from 'rxjs';
export interface DashboardRowProps { export interface DashboardRowProps {

View File

@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react';
import { PanelModel, DashboardModel } from '../../state'; import { PanelModel, DashboardModel } from '../../state';
import { usePanelLatestData } from './usePanelLatestData'; import { usePanelLatestData } from './usePanelLatestData';
import { PanelOptions } from 'app/plugins/panel/table/models.gen'; import { PanelOptions } from 'app/plugins/panel/table/models.gen';
import { RefreshEvent } from 'app/types/events'; import { RefreshEvent } from '@grafana/runtime';
import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel'; import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel';
import { getTimeSrv, TimeSrv } from '../../services/TimeSrv'; import { getTimeSrv, TimeSrv } from '../../services/TimeSrv';
interface Props { interface Props {

View File

@ -9,7 +9,7 @@ import { DashboardLink } from '../../state/DashboardModel';
import { linkIconMap } from '../LinksSettings/LinkSettingsEdit'; import { linkIconMap } from '../LinksSettings/LinkSettingsEdit';
import { useEffectOnce } from 'react-use'; import { useEffectOnce } from 'react-use';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import { TimeRangeUpdatedEvent } from 'app/types/events'; import { TimeRangeUpdatedEvent } from '@grafana/runtime';
export interface Props { export interface Props {
dashboard: DashboardModel; dashboard: DashboardModel;

View File

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { locationService } from '@grafana/runtime'; import { locationService, RefreshEvent } from '@grafana/runtime';
import { import {
AbsoluteTimeRange, AbsoluteTimeRange,
AnnotationChangeEvent, AnnotationChangeEvent,
@ -30,7 +30,7 @@ import config from 'app/core/config';
import { DashboardModel, PanelModel } from '../state'; import { DashboardModel, PanelModel } from '../state';
import { PANEL_BORDER } from 'app/core/constants'; import { PANEL_BORDER } from 'app/core/constants';
import { loadSnapshotData } from '../utils/loadSnapshotData'; import { loadSnapshotData } from '../utils/loadSnapshotData';
import { RefreshEvent, RenderEvent } from 'app/types/events'; import { RenderEvent } from 'app/types/events';
import { changeSeriesColorConfigFactory } from 'app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory'; import { changeSeriesColorConfigFactory } from 'app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory';
import { seriesVisibilityConfigFactory } from './SeriesVisibilityConfigFactory'; import { seriesVisibilityConfigFactory } from './SeriesVisibilityConfigFactory';
import { deleteAnnotation, saveAnnotation, updateAnnotation } from '../../annotations/api'; import { deleteAnnotation, saveAnnotation, updateAnnotation } from '../../annotations/api';

View File

@ -42,10 +42,11 @@ import { variableAdapters } from 'app/features/variables/adapters';
import { onTimeRangeUpdated } from 'app/features/variables/state/actions'; import { onTimeRangeUpdated } from 'app/features/variables/state/actions';
import { dispatch } from '../../../store/store'; import { dispatch } from '../../../store/store';
import { isAllVariable } from '../../variables/utils'; import { isAllVariable } from '../../variables/utils';
import { DashboardPanelsChangedEvent, RefreshEvent, RenderEvent, TimeRangeUpdatedEvent } from 'app/types/events'; import { DashboardPanelsChangedEvent, RenderEvent } from 'app/types/events';
import { getTimeSrv } from '../services/TimeSrv'; import { getTimeSrv } from '../services/TimeSrv';
import { mergePanels, PanelMergeInfo } from '../utils/panelMerge'; import { mergePanels, PanelMergeInfo } from '../utils/panelMerge';
import { isOnTheSameGridRow } from './utils'; import { isOnTheSameGridRow } from './utils';
import { RefreshEvent, TimeRangeUpdatedEvent } from '@grafana/runtime';
export interface CloneOptions { export interface CloneOptions {
saveVariables?: boolean; saveVariables?: boolean;

View File

@ -2,7 +2,7 @@
import { cloneDeep, defaultsDeep, isArray, isEqual, keys } from 'lodash'; import { cloneDeep, defaultsDeep, isArray, isEqual, keys } from 'lodash';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
// Utils // Utils
import { getTemplateSrv } from '@grafana/runtime'; import { getTemplateSrv, RefreshEvent } from '@grafana/runtime';
import { getNextRefIdChar } from 'app/core/utils/query'; import { getNextRefIdChar } from 'app/core/utils/query';
// Types // Types
import { import {
@ -27,7 +27,6 @@ import {
PanelOptionsChangedEvent, PanelOptionsChangedEvent,
PanelQueriesChangedEvent, PanelQueriesChangedEvent,
PanelTransformationsChangedEvent, PanelTransformationsChangedEvent,
RefreshEvent,
RenderEvent, RenderEvent,
} from 'app/types/events'; } from 'app/types/events';
import { getTimeSrv } from '../services/TimeSrv'; import { getTimeSrv } from '../services/TimeSrv';

View File

@ -4,7 +4,7 @@ import store from 'app/core/store';
// Models // Models
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
import { PanelModel } from 'app/features/dashboard/state/PanelModel'; import { PanelModel } from 'app/features/dashboard/state/PanelModel';
import { TimeRange, AppEvents, rangeUtil, dateMath } from '@grafana/data'; import { TimeRange, AppEvents, rangeUtil, dateMath, PanelModel as IPanelModel } from '@grafana/data';
// Utils // Utils
import { isString as _isString } from 'lodash'; import { isString as _isString } from 'lodash';
@ -52,7 +52,7 @@ export const duplicatePanel = (dashboard: DashboardModel, panel: PanelModel) =>
dashboard.duplicatePanel(panel); dashboard.duplicatePanel(panel);
}; };
export const copyPanel = (panel: PanelModel) => { export const copyPanel = (panel: IPanelModel) => {
let saveModel = panel; let saveModel = panel;
if (panel instanceof PanelModel) { if (panel instanceof PanelModel) {
saveModel = panel.getSaveModel(); saveModel = panel.getSaveModel();

View File

@ -8,11 +8,10 @@ import { CopyToClipboard } from 'app/core/components/CopyToClipboard/CopyToClipb
import { PanelModel } from 'app/features/dashboard/state'; import { PanelModel } from 'app/features/dashboard/state';
import { getPanelInspectorStyles } from './styles'; import { getPanelInspectorStyles } from './styles';
import { supportsDataQuery } from 'app/features/dashboard/components/PanelEditor/utils'; import { supportsDataQuery } from 'app/features/dashboard/components/PanelEditor/utils';
import { config } from '@grafana/runtime'; import { config, RefreshEvent } from '@grafana/runtime';
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { backendSrv } from 'app/core/services/backend_srv'; import { backendSrv } from 'app/core/services/backend_srv';
import { RefreshEvent } from 'app/types/events';
interface DsQuery { interface DsQuery {
isLoading: boolean; isLoading: boolean;

View File

@ -16,7 +16,7 @@ import { AnnotationsWorker } from './AnnotationsWorker';
import { getAnnotationsByPanelId } from './utils'; import { getAnnotationsByPanelId } from './utils';
import { DashboardModel } from '../../../dashboard/state'; import { DashboardModel } from '../../../dashboard/state';
import { getTimeSrv, TimeSrv } from '../../../dashboard/services/TimeSrv'; import { getTimeSrv, TimeSrv } from '../../../dashboard/services/TimeSrv';
import { RefreshEvent } from '../../../../types/events'; import { RefreshEvent } from '@grafana/runtime';
import { config } from 'app/core/config'; import { config } from 'app/core/config';
import { UnifiedAlertStatesWorker } from './UnifiedAlertStatesWorker'; import { UnifiedAlertStatesWorker } from './UnifiedAlertStatesWorker';

View File

@ -11,6 +11,7 @@ import {
setLegacyAngularInjector, setLegacyAngularInjector,
setLocationSrv, setLocationSrv,
locationService, locationService,
setAppEvents,
} from '@grafana/runtime'; } from '@grafana/runtime';
import config from 'app/core/config'; import config from 'app/core/config';
import coreModule from 'app/core/core_module'; import coreModule from 'app/core/core_module';
@ -56,6 +57,7 @@ export class GrafanaCtrl {
datasourceSrv.init(config.datasources, config.defaultDatasource); datasourceSrv.init(config.datasources, config.defaultDatasource);
setLocationSrv(locationService); setLocationSrv(locationService);
setAppEvents(appEvents);
initGrafanaLive(); initGrafanaLive();

View File

@ -1,11 +1,4 @@
import { import { AnnotationQuery, BusEventBase, BusEventWithPayload, eventFactory } from '@grafana/data';
AnnotationQuery,
BusEventBase,
BusEventWithPayload,
eventFactory,
GrafanaTheme2,
TimeRange,
} from '@grafana/data';
import { IconName } from '@grafana/ui'; import { IconName } from '@grafana/ui';
/** /**
@ -132,10 +125,6 @@ export class DashboardPanelsChangedEvent extends BusEventBase {
static type = 'dashboard-panels-changed'; static type = 'dashboard-panels-changed';
} }
export class RefreshEvent extends BusEventBase {
static type = 'refresh';
}
export class PanelDirectiveReadyEvent extends BusEventBase { export class PanelDirectiveReadyEvent extends BusEventBase {
static type = 'panel-directive-ready'; static type = 'panel-directive-ready';
} }
@ -144,10 +133,6 @@ export class RenderEvent extends BusEventBase {
static type = 'render'; static type = 'render';
} }
export class ThemeChangedEvent extends BusEventWithPayload<GrafanaTheme2> {
static type = 'theme-changed';
}
export class ZoomOutEvent extends BusEventWithPayload<number> { export class ZoomOutEvent extends BusEventWithPayload<number> {
static type = 'zoom-out'; static type = 'zoom-out';
} }
@ -198,10 +183,6 @@ export class AnnotationQueryFinished extends BusEventWithPayload<AnnotationQuery
static type = 'annotation-query-finished'; static type = 'annotation-query-finished';
} }
export class TimeRangeUpdatedEvent extends BusEventWithPayload<TimeRange> {
static type = 'time-range-updated';
}
export class PanelEditEnteredEvent extends BusEventWithPayload<number> { export class PanelEditEnteredEvent extends BusEventWithPayload<number> {
static type = 'panel-edit-started'; static type = 'panel-edit-started';
} }