diff --git a/src/panel/graph_panel/controllers/analytic_controller.ts b/src/panel/graph_panel/controllers/analytic_controller.ts index e4cc505..55be332 100644 --- a/src/panel/graph_panel/controllers/analytic_controller.ts +++ b/src/panel/graph_panel/controllers/analytic_controller.ts @@ -17,6 +17,7 @@ import { SegmentArray } from '../models/segment_array'; import { HasticServerInfo, HasticServerInfoUnknown } from '../models/hastic_server_info'; import { Condition } from '../models/analytic_units/threshold_analytic_unit'; import { DetectionStatus, DETECTION_STATUS_TEXT, DetectionSpan } from '../models/detection'; +import { PanelTemplate, TemplateVariables } from '../models/panel'; import { createAnalyticUnit } from '../models/analytic_units/utils'; import helpSectionText from '../partials/help_section.html'; @@ -115,8 +116,15 @@ export class AnalyticController { this._creatingNewAnalyticUnit = false; } - async exportAnalyticUnits(): Promise { - return this._analyticService.exportAnalyticUnits(this._panelId); + async exportPanel(): Promise { + return this._analyticService.exportPanel(this._panelId); + } + + async importPanel( + panelTemplate: PanelTemplate, + templateVariables: TemplateVariables + ): Promise { + return this._analyticService.importPanel(panelTemplate, templateVariables); } async saveNew(metric: MetricExpanded, datasource: DatasourceRequest) { diff --git a/src/panel/graph_panel/graph_ctrl.ts b/src/panel/graph_panel/graph_ctrl.ts index 84680fb..2dc4d49 100644 --- a/src/panel/graph_panel/graph_ctrl.ts +++ b/src/panel/graph_panel/graph_ctrl.ts @@ -12,12 +12,15 @@ import { BOUND_TYPES } from './models/analytic_units/anomaly_analytic_unit'; import { AnalyticService } from './services/analytic_service'; import { AnalyticController } from './controllers/analytic_controller'; import { HasticPanelInfo } from './models/hastic_panel_info'; +import { PanelTemplate, TemplateVariables } from './models/panel'; import { axesEditorComponent } from './axes_editor'; import { MetricsPanelCtrl } from 'grafana/app/plugins/sdk'; import { appEvents } from 'grafana/app/core/core' import { BackendSrv } from 'grafana/app/core/services/backend_srv'; +import angular from 'angular'; + import _ from 'lodash'; @@ -65,6 +68,8 @@ class GraphCtrl extends MetricsPanelCtrl { to?: number }; + public panelTemplate: PanelTemplate = {}; + panelDefaults = { // datasource name, null = default datasource datasource: null, @@ -305,7 +310,8 @@ class GraphCtrl extends MetricsPanelCtrl { onInitPanelActions(actions: { text: string, click: string }[]): void { actions.push({ text: 'Export CSV', click: 'ctrl.exportCsv()' }); actions.push({ text: 'Toggle legend', click: 'ctrl.toggleLegend()' }); - actions.push({ text: 'Export analytic units', click: 'ctrl.exportAnalyticUnits()' }); + actions.push({ text: 'Export analytic units', click: 'ctrl.exportPanel()' }); + actions.push({ text: 'Import analytic units', click: 'ctrl.displayImportPanelModal()' }); } async onHasticDatasourceChange() { @@ -553,14 +559,44 @@ class GraphCtrl extends MetricsPanelCtrl { }); } - async exportAnalyticUnits(): Promise { - const json = await this.analyticsController.exportAnalyticUnits(); + async exportPanel(): Promise { + const panelTemplate = await this.analyticsController.exportPanel(); this.publishAppEvent('show-modal', { src: 'public/app/partials/edit_json.html', - model: { object: json, enableCopy: true } + model: { object: panelTemplate, enableCopy: true } }); } + async displayImportPanelModal(): Promise { + const modalScope = this.$scope.$new(true); + + const prettify = true; + modalScope.panelTemplate = angular.toJson({}, prettify); + modalScope.import = async ( + panelTemplate: string, + grafanaUrl: string, + panelId: string, + datasourceUrl: string + ) => { + // TODO: use template variables from form + await this.importPanel(JSON.parse(panelTemplate), { + grafanaUrl: this._grafanaUrl, + panelId: this._panelId, + datasourceUrl: this._datasourceRequest.url + }); + }; + + this.publishAppEvent('show-modal', { + src: `${this.partialsPath}/import_panel.html`, + scope: modalScope + }); + } + + async importPanel(panelTemplate: PanelTemplate, templateVariables: TemplateVariables): Promise { + // TODO: show import errors properly + await this.analyticsController.importPanel(panelTemplate, templateVariables); + } + // getAnnotationsByTag(tag) { // var res = []; // for (var annotation of this.annotations) { diff --git a/src/panel/graph_panel/models/panel.ts b/src/panel/graph_panel/models/panel.ts new file mode 100644 index 0000000..56bd480 --- /dev/null +++ b/src/panel/graph_panel/models/panel.ts @@ -0,0 +1,12 @@ +export type PanelTemplate = { + analyticUnits?: any[], + caches?: any[], + detectionSpans?: any[], + segments?: any[] +} + +export type TemplateVariables = { + grafanaUrl: string, + panelId: string, + datasourceUrl: string +}; diff --git a/src/panel/graph_panel/partials/import_panel.html b/src/panel/graph_panel/partials/import_panel.html new file mode 100644 index 0000000..3425bc8 --- /dev/null +++ b/src/panel/graph_panel/partials/import_panel.html @@ -0,0 +1,21 @@ +
+
+

+ JSON +

+ + +
+ +
+
+ +
+ +
+ +
+
+
diff --git a/src/panel/graph_panel/services/analytic_service.ts b/src/panel/graph_panel/services/analytic_service.ts index e23568f..f228e4e 100644 --- a/src/panel/graph_panel/services/analytic_service.ts +++ b/src/panel/graph_panel/services/analytic_service.ts @@ -5,6 +5,7 @@ import { SegmentsSet } from '../models/segment_set'; import { AnalyticUnitId, AnalyticUnit, AnalyticSegment } from '../models/analytic_units/analytic_unit'; import { HasticServerInfo, HasticServerInfoUnknown } from '../models/hastic_server_info'; import { DetectionSpan } from '../models/detection'; +import { PanelTemplate, TemplateVariables } from '../models/panel'; import { isHasticServerResponse, isSupportedServerVersion, SUPPORTED_SERVER_VERSION } from '../../../utils'; @@ -61,7 +62,7 @@ export class AnalyticService { return resp.analyticUnits; } - async exportAnalyticUnits(panelId: string): Promise { + async exportPanel(panelId: string): Promise { const resp = await this.get('/panels/template', { panelId }); if(resp === undefined) { return {}; @@ -69,6 +70,13 @@ export class AnalyticService { return resp; } + async importPanel( + panelTemplate: PanelTemplate, + templateVariables: TemplateVariables + ): Promise { + await this.post('/panels/template', { panelTemplate, templateVariables }); + } + async postNewAnalyticUnit( analyticUnit: AnalyticUnit, metric: MetricExpanded,