2019-01-18 00:59:47 +08:00
|
|
|
// Libraries
|
2017-12-20 19:33:33 +08:00
|
|
|
import _ from 'lodash';
|
2019-03-18 17:44:00 +08:00
|
|
|
// Utils
|
2019-01-18 00:59:47 +08:00
|
|
|
import { Emitter } from 'app/core/utils/emitter';
|
2019-03-18 18:17:58 +08:00
|
|
|
import { getNextRefIdChar } from 'app/core/utils/query';
|
2020-03-16 21:26:03 +08:00
|
|
|
import templateSrv from 'app/features/templating/template_srv';
|
2019-03-18 17:44:00 +08:00
|
|
|
// Types
|
2019-10-31 17:48:05 +08:00
|
|
|
import {
|
2020-03-16 21:26:03 +08:00
|
|
|
DataConfigSource,
|
2020-03-10 15:53:41 +08:00
|
|
|
DataLink,
|
2019-10-31 17:48:05 +08:00
|
|
|
DataQuery,
|
|
|
|
|
DataQueryResponseData,
|
|
|
|
|
DataTransformerConfig,
|
2020-03-10 15:53:41 +08:00
|
|
|
eventFactory,
|
|
|
|
|
PanelEvents,
|
|
|
|
|
PanelPlugin,
|
2019-10-31 17:48:05 +08:00
|
|
|
ScopedVars,
|
2020-03-19 18:50:31 +08:00
|
|
|
FieldConfigSource,
|
2019-10-31 17:48:05 +08:00
|
|
|
} from '@grafana/data';
|
2020-02-23 04:08:42 +08:00
|
|
|
import { EDIT_PANEL_ID } from 'app/core/constants';
|
2019-07-07 00:18:23 +08:00
|
|
|
|
2019-03-25 21:10:23 +08:00
|
|
|
import config from 'app/core/config';
|
2017-10-10 15:34:14 +08:00
|
|
|
|
2019-04-18 14:22:14 +08:00
|
|
|
import { PanelQueryRunner } from './PanelQueryRunner';
|
2020-02-08 20:23:16 +08:00
|
|
|
import { take } from 'rxjs/operators';
|
2019-10-14 16:27:47 +08:00
|
|
|
|
|
|
|
|
export const panelAdded = eventFactory<PanelModel | undefined>('panel-added');
|
|
|
|
|
export const panelRemoved = eventFactory<PanelModel | undefined>('panel-removed');
|
2019-04-18 14:22:14 +08:00
|
|
|
|
2017-10-10 20:20:53 +08:00
|
|
|
export interface GridPos {
|
2017-10-10 15:34:14 +08:00
|
|
|
x: number;
|
|
|
|
|
y: number;
|
2017-10-10 20:20:53 +08:00
|
|
|
w: number;
|
|
|
|
|
h: number;
|
2017-10-16 15:55:55 +08:00
|
|
|
static?: boolean;
|
2017-10-10 20:20:53 +08:00
|
|
|
}
|
|
|
|
|
|
2017-12-19 23:06:54 +08:00
|
|
|
const notPersistedProperties: { [str: string]: boolean } = {
|
|
|
|
|
events: true,
|
|
|
|
|
fullscreen: true,
|
2017-12-20 19:33:33 +08:00
|
|
|
isEditing: true,
|
2019-05-04 03:55:22 +08:00
|
|
|
isInView: true,
|
2018-08-25 23:49:39 +08:00
|
|
|
hasRefreshed: true,
|
2018-12-04 21:19:55 +08:00
|
|
|
cachedPluginOptions: true,
|
2019-03-24 22:56:32 +08:00
|
|
|
plugin: true,
|
2019-04-18 14:22:14 +08:00
|
|
|
queryRunner: true,
|
2020-03-16 21:26:03 +08:00
|
|
|
replaceVariables: true,
|
2017-10-10 20:20:53 +08:00
|
|
|
};
|
|
|
|
|
|
2018-11-16 17:00:13 +08:00
|
|
|
// For angular panels we need to clean up properties when changing type
|
|
|
|
|
// To make sure the change happens without strange bugs happening when panels use same
|
|
|
|
|
// named property with different type / value expectations
|
|
|
|
|
// This is not required for react panels
|
|
|
|
|
const mustKeepProps: { [str: string]: boolean } = {
|
|
|
|
|
id: true,
|
|
|
|
|
gridPos: true,
|
|
|
|
|
type: true,
|
|
|
|
|
title: true,
|
|
|
|
|
scopedVars: true,
|
|
|
|
|
repeat: true,
|
|
|
|
|
repeatIteration: true,
|
|
|
|
|
repeatPanelId: true,
|
|
|
|
|
repeatDirection: true,
|
|
|
|
|
repeatedByRow: true,
|
|
|
|
|
minSpan: true,
|
|
|
|
|
collapsed: true,
|
|
|
|
|
panels: true,
|
|
|
|
|
targets: true,
|
|
|
|
|
datasource: true,
|
|
|
|
|
timeFrom: true,
|
|
|
|
|
timeShift: true,
|
|
|
|
|
hideTimeOverride: true,
|
|
|
|
|
description: true,
|
|
|
|
|
links: true,
|
|
|
|
|
fullscreen: true,
|
|
|
|
|
isEditing: true,
|
|
|
|
|
hasRefreshed: true,
|
|
|
|
|
events: true,
|
|
|
|
|
cacheTimeout: true,
|
2018-12-04 21:19:55 +08:00
|
|
|
cachedPluginOptions: true,
|
2018-12-06 17:34:27 +08:00
|
|
|
transparent: true,
|
2019-03-23 04:45:09 +08:00
|
|
|
pluginVersion: true,
|
2019-05-03 16:29:22 +08:00
|
|
|
queryRunner: true,
|
2019-09-09 14:58:57 +08:00
|
|
|
transformations: true,
|
2020-03-19 18:50:31 +08:00
|
|
|
fieldConfig: true,
|
2018-11-16 17:00:13 +08:00
|
|
|
};
|
|
|
|
|
|
2018-10-15 03:14:11 +08:00
|
|
|
const defaults: any = {
|
|
|
|
|
gridPos: { x: 0, y: 0, h: 3, w: 6 },
|
2019-01-22 03:35:24 +08:00
|
|
|
targets: [{ refId: 'A' }],
|
2018-12-04 21:19:55 +08:00
|
|
|
cachedPluginOptions: {},
|
2018-12-06 17:34:27 +08:00
|
|
|
transparent: false,
|
2020-02-13 23:06:45 +08:00
|
|
|
options: {},
|
2018-10-15 03:14:11 +08:00
|
|
|
};
|
|
|
|
|
|
2020-03-16 21:26:03 +08:00
|
|
|
export class PanelModel implements DataConfigSource {
|
2020-02-10 21:23:54 +08:00
|
|
|
/* persisted id, used in URL to identify a panel */
|
2017-10-10 20:20:53 +08:00
|
|
|
id: number;
|
2017-12-19 23:06:54 +08:00
|
|
|
gridPos: GridPos;
|
2017-10-10 15:34:14 +08:00
|
|
|
type: string;
|
|
|
|
|
title: string;
|
2017-10-11 22:08:56 +08:00
|
|
|
alert?: any;
|
2019-03-04 17:42:59 +08:00
|
|
|
scopedVars?: ScopedVars;
|
2017-10-13 20:50:16 +08:00
|
|
|
repeat?: string;
|
|
|
|
|
repeatIteration?: number;
|
|
|
|
|
repeatPanelId?: number;
|
|
|
|
|
repeatDirection?: string;
|
2018-01-10 21:30:43 +08:00
|
|
|
repeatedByRow?: boolean;
|
2018-08-20 21:33:49 +08:00
|
|
|
maxPerRow?: number;
|
2017-10-17 20:53:52 +08:00
|
|
|
collapsed?: boolean;
|
2017-10-17 18:04:18 +08:00
|
|
|
panels?: any;
|
2017-11-28 16:38:28 +08:00
|
|
|
soloMode?: boolean;
|
2019-01-22 03:35:24 +08:00
|
|
|
targets: DataQuery[];
|
2019-09-09 14:58:57 +08:00
|
|
|
transformations?: DataTransformerConfig[];
|
2018-06-26 22:32:01 +08:00
|
|
|
datasource: string;
|
2018-08-26 03:22:50 +08:00
|
|
|
thresholds?: any;
|
2019-03-23 04:45:09 +08:00
|
|
|
pluginVersion?: string;
|
2017-10-11 17:42:49 +08:00
|
|
|
|
2019-03-29 03:59:59 +08:00
|
|
|
snapshotData?: DataQueryResponseData[];
|
2018-11-08 21:44:12 +08:00
|
|
|
timeFrom?: any;
|
|
|
|
|
timeShift?: any;
|
|
|
|
|
hideTimeOverride?: any;
|
2019-02-18 18:40:25 +08:00
|
|
|
options: {
|
|
|
|
|
[key: string]: any;
|
|
|
|
|
};
|
2020-03-19 18:50:31 +08:00
|
|
|
fieldConfig: FieldConfigSource;
|
2018-11-08 21:44:12 +08:00
|
|
|
|
2018-11-12 17:35:46 +08:00
|
|
|
maxDataPoints?: number;
|
|
|
|
|
interval?: string;
|
2018-11-14 15:07:16 +08:00
|
|
|
description?: string;
|
2019-06-25 17:38:51 +08:00
|
|
|
links?: DataLink[];
|
2018-12-06 17:34:27 +08:00
|
|
|
transparent: boolean;
|
2018-11-12 16:32:55 +08:00
|
|
|
|
2017-10-11 17:42:49 +08:00
|
|
|
// non persisted
|
|
|
|
|
fullscreen: boolean;
|
|
|
|
|
isEditing: boolean;
|
2019-05-04 03:55:22 +08:00
|
|
|
isInView: boolean;
|
2018-08-25 23:49:39 +08:00
|
|
|
hasRefreshed: boolean;
|
2017-10-10 20:20:53 +08:00
|
|
|
events: Emitter;
|
2018-11-20 23:33:26 +08:00
|
|
|
cacheTimeout?: any;
|
2018-12-04 21:19:55 +08:00
|
|
|
cachedPluginOptions?: any;
|
2020-03-10 15:53:41 +08:00
|
|
|
legend?: { show: boolean; sort?: string; sortDesc?: boolean };
|
2019-05-01 13:36:46 +08:00
|
|
|
plugin?: PanelPlugin;
|
2020-02-09 17:53:34 +08:00
|
|
|
|
2019-04-19 05:10:18 +08:00
|
|
|
private queryRunner?: PanelQueryRunner;
|
2018-12-04 21:19:55 +08:00
|
|
|
|
2019-03-20 01:24:09 +08:00
|
|
|
constructor(model: any) {
|
2017-10-10 23:57:53 +08:00
|
|
|
this.events = new Emitter();
|
2019-09-24 18:15:35 +08:00
|
|
|
// should not be part of defaults as defaults are removed in save model and
|
|
|
|
|
// this should not be removed in save model as exporter needs to templatize it
|
|
|
|
|
this.datasource = null;
|
2020-02-07 21:59:04 +08:00
|
|
|
this.restoreModel(model);
|
2020-03-16 21:26:03 +08:00
|
|
|
this.replaceVariables = this.replaceVariables.bind(this);
|
2020-02-07 21:59:04 +08:00
|
|
|
}
|
2019-09-24 18:15:35 +08:00
|
|
|
|
2020-02-07 21:59:04 +08:00
|
|
|
/** Given a persistened PanelModel restores property values */
|
2020-02-28 18:04:40 +08:00
|
|
|
restoreModel(model: any) {
|
2017-10-10 20:20:53 +08:00
|
|
|
// copy properties from persisted model
|
2018-08-29 20:26:50 +08:00
|
|
|
for (const property in model) {
|
2019-03-20 01:24:09 +08:00
|
|
|
(this as any)[property] = model[property];
|
2017-10-10 20:20:53 +08:00
|
|
|
}
|
2017-10-13 03:37:27 +08:00
|
|
|
|
2018-06-26 22:32:01 +08:00
|
|
|
// defaults
|
2018-10-15 03:14:11 +08:00
|
|
|
_.defaultsDeep(this, _.cloneDeep(defaults));
|
2019-05-07 12:07:33 +08:00
|
|
|
|
2019-01-22 03:35:24 +08:00
|
|
|
// queries must have refId
|
|
|
|
|
this.ensureQueryIds();
|
2020-02-28 18:04:40 +08:00
|
|
|
}
|
2019-01-22 03:35:24 +08:00
|
|
|
|
|
|
|
|
ensureQueryIds() {
|
2019-03-15 15:26:56 +08:00
|
|
|
if (this.targets && _.isArray(this.targets)) {
|
2019-01-22 03:35:24 +08:00
|
|
|
for (const query of this.targets) {
|
|
|
|
|
if (!query.refId) {
|
2019-03-18 18:17:58 +08:00
|
|
|
query.refId = getNextRefIdChar(this.targets);
|
2019-01-22 03:35:24 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-10 20:20:53 +08:00
|
|
|
}
|
|
|
|
|
|
2019-05-21 19:19:19 +08:00
|
|
|
getOptions() {
|
|
|
|
|
return this.options;
|
2018-11-06 00:46:09 +08:00
|
|
|
}
|
2020-03-19 18:50:31 +08:00
|
|
|
getFieldConfig() {
|
|
|
|
|
return this.fieldConfig;
|
|
|
|
|
}
|
2018-11-06 00:46:09 +08:00
|
|
|
|
|
|
|
|
updateOptions(options: object) {
|
2019-02-18 18:41:14 +08:00
|
|
|
this.options = options;
|
2020-03-19 18:50:31 +08:00
|
|
|
|
|
|
|
|
this.render();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateFieldConfig(config: FieldConfigSource) {
|
|
|
|
|
this.fieldConfig = config;
|
|
|
|
|
|
2020-03-16 21:26:03 +08:00
|
|
|
this.resendLastResult();
|
2018-11-06 00:46:09 +08:00
|
|
|
this.render();
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-10 20:20:53 +08:00
|
|
|
getSaveModel() {
|
2017-10-10 23:57:53 +08:00
|
|
|
const model: any = {};
|
2018-08-29 20:26:50 +08:00
|
|
|
for (const property in this) {
|
2017-10-10 20:20:53 +08:00
|
|
|
if (notPersistedProperties[property] || !this.hasOwnProperty(property)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-15 03:14:11 +08:00
|
|
|
if (_.isEqual(this[property], defaults[property])) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-13 03:37:27 +08:00
|
|
|
model[property] = _.cloneDeep(this[property]);
|
2017-10-10 20:20:53 +08:00
|
|
|
}
|
2017-10-10 23:57:53 +08:00
|
|
|
return model;
|
2017-10-10 20:20:53 +08:00
|
|
|
}
|
|
|
|
|
|
2017-10-11 17:42:49 +08:00
|
|
|
setViewMode(fullscreen: boolean, isEditing: boolean) {
|
|
|
|
|
this.fullscreen = fullscreen;
|
|
|
|
|
this.isEditing = isEditing;
|
2019-10-14 16:27:47 +08:00
|
|
|
this.events.emit(PanelEvents.viewModeChanged);
|
2017-10-11 17:42:49 +08:00
|
|
|
}
|
|
|
|
|
|
2017-10-10 20:20:53 +08:00
|
|
|
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) {
|
2019-10-14 16:27:47 +08:00
|
|
|
this.events.emit(PanelEvents.panelSizeChanged);
|
2017-10-10 20:20:53 +08:00
|
|
|
}
|
|
|
|
|
}
|
2017-10-12 03:36:03 +08:00
|
|
|
|
|
|
|
|
resizeDone() {
|
2019-10-14 16:27:47 +08:00
|
|
|
this.events.emit(PanelEvents.panelSizeChanged);
|
2017-10-12 03:36:03 +08:00
|
|
|
}
|
2017-10-16 22:09:23 +08:00
|
|
|
|
2018-08-25 23:49:39 +08:00
|
|
|
refresh() {
|
|
|
|
|
this.hasRefreshed = true;
|
2019-10-14 16:27:47 +08:00
|
|
|
this.events.emit(PanelEvents.refresh);
|
2018-08-25 23:49:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render() {
|
|
|
|
|
if (!this.hasRefreshed) {
|
|
|
|
|
this.refresh();
|
|
|
|
|
} else {
|
2019-10-14 16:27:47 +08:00
|
|
|
this.events.emit(PanelEvents.render);
|
2018-08-25 23:49:39 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-05 16:23:47 +08:00
|
|
|
initialized() {
|
2019-10-14 16:27:47 +08:00
|
|
|
this.events.emit(PanelEvents.panelInitialized);
|
2018-08-25 23:49:39 +08:00
|
|
|
}
|
|
|
|
|
|
2018-12-05 14:33:21 +08:00
|
|
|
private getOptionsToRemember() {
|
2018-12-04 21:19:55 +08:00
|
|
|
return Object.keys(this).reduce((acc, property) => {
|
2018-12-05 14:33:21 +08:00
|
|
|
if (notPersistedProperties[property] || mustKeepProps[property]) {
|
2018-12-04 21:19:55 +08:00
|
|
|
return acc;
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
...acc,
|
2019-03-20 01:24:09 +08:00
|
|
|
[property]: (this as any)[property],
|
2018-12-04 21:19:55 +08:00
|
|
|
};
|
|
|
|
|
}, {});
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-05 14:33:21 +08:00
|
|
|
private restorePanelOptions(pluginId: string) {
|
2018-12-04 21:39:56 +08:00
|
|
|
const prevOptions = this.cachedPluginOptions[pluginId] || {};
|
2018-12-04 21:19:55 +08:00
|
|
|
|
2018-12-05 14:33:21 +08:00
|
|
|
Object.keys(prevOptions).map(property => {
|
2019-03-20 01:24:09 +08:00
|
|
|
(this as any)[property] = prevOptions[property];
|
2018-12-04 21:19:55 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-21 19:19:19 +08:00
|
|
|
private applyPluginOptionDefaults(plugin: PanelPlugin) {
|
|
|
|
|
if (plugin.angularConfigCtrl) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-11-19 21:59:39 +08:00
|
|
|
this.options = _.mergeWith({}, plugin.defaults, this.options || {}, (objValue: any, srcValue: any): any => {
|
|
|
|
|
if (_.isArray(srcValue)) {
|
|
|
|
|
return srcValue;
|
2019-11-08 16:46:53 +08:00
|
|
|
}
|
2019-11-19 21:59:39 +08:00
|
|
|
});
|
2020-03-19 18:50:31 +08:00
|
|
|
|
|
|
|
|
this.fieldConfig = {
|
|
|
|
|
defaults: _.mergeWith(
|
|
|
|
|
{},
|
|
|
|
|
plugin.fieldConfigDefaults.defaults,
|
|
|
|
|
this.fieldConfig ? this.fieldConfig.defaults : {},
|
|
|
|
|
(objValue: any, srcValue: any): any => {
|
|
|
|
|
if (_.isArray(srcValue)) {
|
|
|
|
|
return srcValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
overrides: [
|
|
|
|
|
...plugin.fieldConfigDefaults.overrides,
|
|
|
|
|
...(this.fieldConfig && this.fieldConfig.overrides ? this.fieldConfig.overrides : []),
|
|
|
|
|
],
|
|
|
|
|
};
|
2019-05-21 19:19:19 +08:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 13:36:46 +08:00
|
|
|
pluginLoaded(plugin: PanelPlugin) {
|
2019-03-24 22:56:32 +08:00
|
|
|
this.plugin = plugin;
|
|
|
|
|
|
2019-05-01 13:36:46 +08:00
|
|
|
if (plugin.panel && plugin.onPanelMigration) {
|
|
|
|
|
const version = getPluginVersion(plugin);
|
2020-02-10 21:23:54 +08:00
|
|
|
|
2019-03-25 21:10:23 +08:00
|
|
|
if (version !== this.pluginVersion) {
|
2019-05-01 13:36:46 +08:00
|
|
|
this.options = plugin.onPanelMigration(this);
|
2019-03-25 21:10:23 +08:00
|
|
|
this.pluginVersion = version;
|
|
|
|
|
}
|
2019-03-24 22:56:32 +08:00
|
|
|
}
|
2019-08-06 14:26:11 +08:00
|
|
|
|
|
|
|
|
this.applyPluginOptionDefaults(plugin);
|
2020-03-16 21:26:03 +08:00
|
|
|
this.resendLastResult();
|
2019-03-24 22:56:32 +08:00
|
|
|
}
|
|
|
|
|
|
2019-05-01 13:36:46 +08:00
|
|
|
changePlugin(newPlugin: PanelPlugin) {
|
|
|
|
|
const pluginId = newPlugin.meta.id;
|
2019-02-21 20:43:36 +08:00
|
|
|
const oldOptions: any = this.getOptionsToRemember();
|
|
|
|
|
const oldPluginId = this.type;
|
2019-08-19 06:01:07 +08:00
|
|
|
const wasAngular = !!this.plugin.angularPanelCtrl;
|
2018-08-26 03:22:50 +08:00
|
|
|
|
2019-02-18 18:41:14 +08:00
|
|
|
// remove panel type specific options
|
|
|
|
|
for (const key of _.keys(this)) {
|
|
|
|
|
if (mustKeepProps[key]) {
|
|
|
|
|
continue;
|
2018-11-16 17:00:13 +08:00
|
|
|
}
|
2019-02-18 18:41:14 +08:00
|
|
|
|
2019-03-20 01:24:09 +08:00
|
|
|
delete (this as any)[key];
|
2018-11-16 17:00:13 +08:00
|
|
|
}
|
2018-12-04 21:19:55 +08:00
|
|
|
|
2019-02-21 20:43:36 +08:00
|
|
|
this.cachedPluginOptions[oldPluginId] = oldOptions;
|
2018-12-04 21:19:55 +08:00
|
|
|
this.restorePanelOptions(pluginId);
|
2019-02-21 20:43:36 +08:00
|
|
|
|
2019-03-24 23:39:55 +08:00
|
|
|
// Let panel plugins inspect options from previous panel and keep any that it can use
|
2019-05-01 13:36:46 +08:00
|
|
|
if (newPlugin.onPanelTypeChanged) {
|
2019-08-19 06:01:07 +08:00
|
|
|
let old: any = {};
|
|
|
|
|
|
|
|
|
|
if (wasAngular) {
|
|
|
|
|
old = { angular: oldOptions };
|
|
|
|
|
} else if (oldOptions && oldOptions.options) {
|
|
|
|
|
old = oldOptions.options;
|
|
|
|
|
}
|
2019-05-01 13:36:46 +08:00
|
|
|
this.options = this.options || {};
|
2020-03-13 15:27:16 +08:00
|
|
|
Object.assign(this.options, newPlugin.onPanelTypeChanged(this, oldPluginId, old));
|
2019-05-01 13:36:46 +08:00
|
|
|
}
|
2019-04-05 00:30:15 +08:00
|
|
|
|
2019-08-19 06:01:07 +08:00
|
|
|
// switch
|
|
|
|
|
this.type = pluginId;
|
|
|
|
|
this.plugin = newPlugin;
|
2020-03-16 21:26:03 +08:00
|
|
|
|
|
|
|
|
// For some reason I need to rebind replace variables here, otherwise the viz repeater does not work
|
|
|
|
|
this.replaceVariables = this.replaceVariables.bind(this);
|
2019-08-19 06:01:07 +08:00
|
|
|
this.applyPluginOptionDefaults(newPlugin);
|
|
|
|
|
|
2019-05-01 13:36:46 +08:00
|
|
|
if (newPlugin.onPanelMigration) {
|
|
|
|
|
this.pluginVersion = getPluginVersion(newPlugin);
|
2019-02-21 20:43:36 +08:00
|
|
|
}
|
2018-07-10 00:17:51 +08:00
|
|
|
}
|
|
|
|
|
|
2018-12-12 15:54:12 +08:00
|
|
|
addQuery(query?: Partial<DataQuery>) {
|
2018-12-11 20:36:44 +08:00
|
|
|
query = query || { refId: 'A' };
|
2019-03-18 18:17:58 +08:00
|
|
|
query.refId = getNextRefIdChar(this.targets);
|
2019-01-22 03:35:24 +08:00
|
|
|
this.targets.push(query as DataQuery);
|
2018-12-11 20:36:44 +08:00
|
|
|
}
|
|
|
|
|
|
2019-01-29 16:39:23 +08:00
|
|
|
changeQuery(query: DataQuery, index: number) {
|
|
|
|
|
// ensure refId is maintained
|
|
|
|
|
query.refId = this.targets[index].refId;
|
|
|
|
|
|
|
|
|
|
// update query in array
|
|
|
|
|
this.targets = this.targets.map((item, itemIndex) => {
|
|
|
|
|
if (itemIndex === index) {
|
|
|
|
|
return query;
|
|
|
|
|
}
|
|
|
|
|
return item;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-07 21:59:04 +08:00
|
|
|
getEditClone() {
|
2020-02-13 23:06:45 +08:00
|
|
|
const sourceModel = this.getSaveModel();
|
|
|
|
|
|
|
|
|
|
// Temporary id for the clone, restored later in redux action when changes are saved
|
2020-02-23 04:08:42 +08:00
|
|
|
sourceModel.id = EDIT_PANEL_ID;
|
2020-02-13 23:06:45 +08:00
|
|
|
|
|
|
|
|
const clone = new PanelModel(sourceModel);
|
2020-02-11 21:57:16 +08:00
|
|
|
const sourceQueryRunner = this.getQueryRunner();
|
2020-02-08 20:23:16 +08:00
|
|
|
|
2020-02-11 21:57:16 +08:00
|
|
|
// pipe last result to new clone query runner
|
|
|
|
|
sourceQueryRunner
|
2020-02-08 20:23:16 +08:00
|
|
|
.getData()
|
|
|
|
|
.pipe(take(1))
|
2020-02-11 21:57:16 +08:00
|
|
|
.subscribe(val => clone.getQueryRunner().pipeDataToSubject(val));
|
2020-02-08 20:23:16 +08:00
|
|
|
|
2020-02-07 21:59:04 +08:00
|
|
|
return clone;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-16 21:26:03 +08:00
|
|
|
getTransformations() {
|
|
|
|
|
return this.transformations;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getFieldOverrideOptions() {
|
|
|
|
|
if (!this.plugin) {
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
2020-03-19 18:50:31 +08:00
|
|
|
fieldOptions: this.fieldConfig,
|
2020-03-16 21:26:03 +08:00
|
|
|
replaceVariables: this.replaceVariables,
|
|
|
|
|
custom: this.plugin.customFieldConfigs,
|
|
|
|
|
theme: config.theme,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-19 05:10:18 +08:00
|
|
|
getQueryRunner(): PanelQueryRunner {
|
|
|
|
|
if (!this.queryRunner) {
|
2020-03-16 21:26:03 +08:00
|
|
|
this.queryRunner = new PanelQueryRunner(this);
|
2019-04-19 05:10:18 +08:00
|
|
|
}
|
|
|
|
|
return this.queryRunner;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-06 21:26:09 +08:00
|
|
|
hasTitle() {
|
2019-05-08 23:21:46 +08:00
|
|
|
return this.title && this.title.length > 0;
|
2019-05-06 21:26:09 +08:00
|
|
|
}
|
|
|
|
|
|
2019-09-12 23:28:46 +08:00
|
|
|
isAngularPlugin(): boolean {
|
|
|
|
|
return this.plugin && !!this.plugin.angularPanelCtrl;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-16 22:09:23 +08:00
|
|
|
destroy() {
|
|
|
|
|
this.events.removeAllListeners();
|
2019-04-19 12:56:27 +08:00
|
|
|
|
|
|
|
|
if (this.queryRunner) {
|
|
|
|
|
this.queryRunner.destroy();
|
2019-05-07 01:35:10 +08:00
|
|
|
this.queryRunner = null;
|
2019-04-19 12:56:27 +08:00
|
|
|
}
|
2017-10-16 22:09:23 +08:00
|
|
|
}
|
2019-09-09 14:58:57 +08:00
|
|
|
|
|
|
|
|
setTransformations(transformations: DataTransformerConfig[]) {
|
|
|
|
|
this.transformations = transformations;
|
2020-03-16 21:26:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
replaceVariables(value: string, extraVars?: ScopedVars, format?: string) {
|
|
|
|
|
let vars = this.scopedVars;
|
|
|
|
|
if (extraVars) {
|
|
|
|
|
vars = vars ? { ...vars, ...extraVars } : extraVars;
|
|
|
|
|
}
|
|
|
|
|
return templateSrv.replace(value, vars, format);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resendLastResult() {
|
|
|
|
|
if (!this.plugin) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.getQueryRunner().resendLastResult();
|
2019-09-09 14:58:57 +08:00
|
|
|
}
|
2017-10-10 15:34:14 +08:00
|
|
|
}
|
2019-05-01 13:36:46 +08:00
|
|
|
|
|
|
|
|
function getPluginVersion(plugin: PanelPlugin): string {
|
|
|
|
|
return plugin && plugin.meta.info.version ? plugin.meta.info.version : config.buildInfo.version;
|
|
|
|
|
}
|