mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AppEvents: export appEvents in @grafana/runtime and support copy panel (#40715)
This commit is contained in:
parent
b60ae7ebed
commit
ad69de4a10
59
packages/grafana-runtime/src/services/appEvents.ts
Normal file
59
packages/grafana-runtime/src/services/appEvents.ts
Normal 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;
|
||||||
|
}
|
@ -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';
|
||||||
|
@ -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>
|
||||||
|
@ -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';
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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';
|
||||||
|
@ -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;
|
||||||
|
@ -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';
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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';
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user