From d9d46096dd5c41600f96f9f32e29e53b47083f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 13 May 2016 17:39:22 +0200 Subject: [PATCH] feat(import): lots of work on dashboard import --- .../dash_importer/dash_importer.html | 76 ----------- .../components/dash_importer/dash_importer.ts | 77 ------------ public/app/core/components/search/search.html | 8 +- public/app/core/components/search/search.ts | 10 +- public/app/core/directives/dash_edit_link.js | 29 ++--- public/app/core/services/util_srv.ts | 2 +- public/app/features/dashboard/all.js | 1 + public/app/features/dashboard/exporter.ts | 1 + .../app/features/dashboard/import/import.html | 96 ++++++++++++++ .../app/features/dashboard/import/import.ts | 119 ++++++++++++++++++ public/app/features/dashboard/upload.ts | 4 +- public/sass/_variables.dark.scss | 4 +- public/vendor/angular-other/angular-strap.js | 11 +- 13 files changed, 247 insertions(+), 191 deletions(-) delete mode 100644 public/app/core/components/dash_importer/dash_importer.html delete mode 100644 public/app/core/components/dash_importer/dash_importer.ts create mode 100644 public/app/features/dashboard/import/import.html create mode 100644 public/app/features/dashboard/import/import.ts diff --git a/public/app/core/components/dash_importer/dash_importer.html b/public/app/core/components/dash_importer/dash_importer.html deleted file mode 100644 index 8b4e649dd50..00000000000 --- a/public/app/core/components/dash_importer/dash_importer.html +++ /dev/null @@ -1,76 +0,0 @@ - - diff --git a/public/app/core/components/dash_importer/dash_importer.ts b/public/app/core/components/dash_importer/dash_importer.ts deleted file mode 100644 index 2f04640ffc2..00000000000 --- a/public/app/core/components/dash_importer/dash_importer.ts +++ /dev/null @@ -1,77 +0,0 @@ -/// - -import kbn from 'app/core/utils/kbn'; -import coreModule from 'app/core/core_module'; - -import appEvents from 'app/core/app_events'; -import {WizardFlow} from 'app/core/core'; - -var wnd: any = window; - -export class DashImporter { - step: number; - jsonText: string; - parseError: string; - nameExists: boolean; - dash: any; - dismiss: any; - - constructor(private backendSrv, private $location) { - } - - onUpload(dash) { - this.dash = dash; - this.dash.id = null; - - this.backendSrv.saveDashboard(this.dash, {overwrite: false}).then(res => { - - }).catch(err => { - if (err.data.status === 'name-exists') { - err.isHandled = true; - this.step = 2; - this.nameExists = true; - } - console.log(err); - }); - } - - titleChanged() { - this.backendSrv.search({query: this.dash.title}).then(res => { - this.nameExists = false; - for (let hit of res) { - if (this.dash.title === hit.title) { - this.nameExists = true; - break; - } - } - }); - } - - saveDashboard() { - return this.backendSrv.saveDashboard(this.dash, {overwrite: true}).then(res => { - this.$location.url('dashboard/db/' + res.slug); - this.dismiss(); - }); - } - - loadJsonText() { - try { - this.parseError = ''; - var dash = JSON.parse(this.jsonText); - this.onUpload(dash); - } catch (err) { - console.log(err); - this.parseError = err.message; - return; - } - } - - run() { - this.step = 0; - - appEvents.emit('show-modal', { - src: 'public/app/core/components/dash_importer/dash_importer.html', - model: this - }); - } -} diff --git a/public/app/core/components/search/search.html b/public/app/core/components/search/search.html index ddfe22215a9..72ff0d15f83 100644 --- a/public/app/core/components/search/search.html +++ b/public/app/core/components/search/search.html @@ -62,15 +62,15 @@ diff --git a/public/app/core/components/search/search.ts b/public/app/core/components/search/search.ts index 30ad9792c31..9da95278c57 100644 --- a/public/app/core/components/search/search.ts +++ b/public/app/core/components/search/search.ts @@ -5,7 +5,7 @@ import config from 'app/core/config'; import _ from 'lodash'; import $ from 'jquery'; import coreModule from '../../core_module'; -import {DashImporter} from '../dash_importer/dash_importer'; +import appEvents from 'app/core/app_events'; export class SearchCtrl { isOpen: boolean; @@ -149,12 +149,10 @@ export class SearchCtrl { this.searchDashboards(); }; - newDashboard() { - this.$location.url('dashboard/new'); - }; - import() { - new DashImporter(this.backendSrv, this.$location).run(); + appEvents.emit('show-modal', { + templateHtml: '', + }); } } diff --git a/public/app/core/directives/dash_edit_link.js b/public/app/core/directives/dash_edit_link.js index 23855925541..eb0fe453741 100644 --- a/public/app/core/directives/dash_edit_link.js +++ b/public/app/core/directives/dash_edit_link.js @@ -6,27 +6,12 @@ function ($, coreModule) { 'use strict'; var editViewMap = { - 'settings': { src: 'public/app/features/dashboard/partials/settings.html', title: "Settings" }, - 'annotations': { src: 'public/app/features/annotations/partials/editor.html', title: "Annotations" }, - 'templating': { src: 'public/app/features/templating/partials/editor.html', title: "Templating" } + 'settings': { src: 'public/app/features/dashboard/partials/settings.html'}, + 'annotations': { src: 'public/app/features/annotations/partials/editor.html'}, + 'templating': { src: 'public/app/features/templating/partials/editor.html'}, + 'import': { src: '' } }; - coreModule.default.directive('dashEditorLink', function($timeout) { - return { - restrict: 'A', - link: function(scope, elem, attrs) { - var partial = attrs.dashEditorLink; - - elem.bind('click',function() { - $timeout(function() { - var editorScope = attrs.editorScope === 'isolated' ? null : scope; - scope.appEvent('show-dash-editor', { src: partial, scope: editorScope }); - }); - }); - } - }; - }); - coreModule.default.directive('dashEditorView', function($compile, $location) { return { restrict: 'A', @@ -72,8 +57,10 @@ function ($, coreModule) { } }; - var src = "'" + payload.src + "'"; - var view = $('
'); + var view = payload.src; + if (view.indexOf('.html') > 0) { + view = $('
'); + } elem.append(view); $compile(elem.contents())(editorScope); diff --git a/public/app/core/services/util_srv.ts b/public/app/core/services/util_srv.ts index 595962cd3c6..538527b5fda 100644 --- a/public/app/core/services/util_srv.ts +++ b/public/app/core/services/util_srv.ts @@ -26,6 +26,7 @@ export class UtilSrv { var modal = this.$modal({ modalClass: options.modalClass, template: options.src, + templateHtml: options.templateHtml, persist: false, show: false, scope: options.scope, @@ -34,7 +35,6 @@ export class UtilSrv { Promise.resolve(modal).then(function(modalEl) { modalEl.modal('show'); - options.scope.model.dismiss = options.scope.dismiss; }); } } diff --git a/public/app/features/dashboard/all.js b/public/app/features/dashboard/all.js index 926288a6e71..51a2b806e19 100644 --- a/public/app/features/dashboard/all.js +++ b/public/app/features/dashboard/all.js @@ -17,4 +17,5 @@ define([ './importCtrl', './impression_store', './upload', + './import/import', ], function () {}); diff --git a/public/app/features/dashboard/exporter.ts b/public/app/features/dashboard/exporter.ts index 9a8d5bae5b1..63067502605 100644 --- a/public/app/features/dashboard/exporter.ts +++ b/public/app/features/dashboard/exporter.ts @@ -29,6 +29,7 @@ export class DashboardExporter { name: refName, type: 'datasource', pluginId: ds.meta.id, + pluginName: ds.meta.name, }; panel.datasource = '${' + refName +'}'; diff --git a/public/app/features/dashboard/import/import.html b/public/app/features/dashboard/import/import.html new file mode 100644 index 00000000000..8a3a276ce53 --- /dev/null +++ b/public/app/features/dashboard/import/import.html @@ -0,0 +1,96 @@ + + diff --git a/public/app/features/dashboard/import/import.ts b/public/app/features/dashboard/import/import.ts new file mode 100644 index 00000000000..852a927ded8 --- /dev/null +++ b/public/app/features/dashboard/import/import.ts @@ -0,0 +1,119 @@ +/// + +import kbn from 'app/core/utils/kbn'; +import coreModule from 'app/core/core_module'; +import appEvents from 'app/core/app_events'; +import config from 'app/core/config'; +import _ from 'lodash'; + +export class DashImportCtrl { + step: number; + jsonText: string; + parseError: string; + nameExists: boolean; + dash: any; + dismiss: any; + inputs: any[]; + inputsValid: boolean; + + /** @ngInject */ + constructor(private backendSrv, private $location, private $scope) { + this.step = 1; + this.nameExists = false; + } + + onUpload(dash) { + this.dash = dash; + this.dash.id = null; + this.step = 2; + this.inputs = []; + + if (this.dash.__inputs) { + for (let input of this.dash.__inputs) { + var inputModel = { + name: input.name, + type: input.type, + options: [] + }; + + if (input.type === 'datasource') { + this.setDatasourceOptions(input, inputModel); + } + + this.inputs.push(inputModel); + } + } + + this.inputsValid = this.inputs.length === 0; + this.titleChanged(); + } + + setDatasourceOptions(input, inputModel) { + var sources = _.filter(config.datasources, val => { + return val.type === input.pluginId; + }); + + if (sources.length === 0) { + inputModel.error = "No data sources of type " + input.pluginName + " found"; + } else { + inputModel.info = "Select a " + input.pluginName + " data source"; + } + + inputModel.options = sources.map(val => { + return {text: val.name, value: val.name}; + }); + } + + inputOptionChanged() { + this.inputsValid = true; + for (let input of this.inputs) { + if (!input.value) { + this.inputsValid = false; + } + } + } + + titleChanged() { + this.backendSrv.search({query: this.dash.title}).then(res => { + this.nameExists = false; + for (let hit of res) { + if (this.dash.title === hit.title) { + this.nameExists = true; + break; + } + } + }); + } + + saveDashboard() { + return this.backendSrv.saveDashboard(this.dash, {overwrite: true}).then(res => { + this.$location.url('dashboard/db/' + res.slug); + this.dismiss(); + }); + } + + loadJsonText() { + try { + this.parseError = ''; + var dash = JSON.parse(this.jsonText); + this.onUpload(dash); + } catch (err) { + console.log(err); + this.parseError = err.message; + return; + } + } + +} + +export function dashImportDirective() { + return { + restrict: 'E', + templateUrl: 'public/app/features/dashboard/import/import.html', + controller: DashImportCtrl, + bindToController: true, + controllerAs: 'ctrl', + }; +} + +coreModule.directive('dashImport', dashImportDirective); diff --git a/public/app/features/dashboard/upload.ts b/public/app/features/dashboard/upload.ts index ddc4005546c..57be7b8fd11 100644 --- a/public/app/features/dashboard/upload.ts +++ b/public/app/features/dashboard/upload.ts @@ -33,7 +33,9 @@ function uploadDashboardDirective(timer, alertSrv, $location) { return; } - scope.onUpload({dash: dash}); + scope.$apply(function() { + scope.onUpload({dash: dash}); + }); }; }; diff --git a/public/sass/_variables.dark.scss b/public/sass/_variables.dark.scss index 29e3cce1ee5..d977689f553 100644 --- a/public/sass/_variables.dark.scss +++ b/public/sass/_variables.dark.scss @@ -232,13 +232,13 @@ $paginationActiveBackground: $blue; // Form states and alerts // ------------------------- -$state-warning-text: darken(#c09853, 10%); +$state-warning-text: $warn; $state-warning-bg: $brand-warning; $errorText: #E84D4D; $errorBackground: $btn-danger-bg; -$successText: #468847; +$successText: #12D95A; $successBackground: $btn-success-bg; $infoText: $blue-dark; diff --git a/public/vendor/angular-other/angular-strap.js b/public/vendor/angular-other/angular-strap.js index d9721bda038..3670f3f8ac4 100644 --- a/public/vendor/angular-other/angular-strap.js +++ b/public/vendor/angular-other/angular-strap.js @@ -25,11 +25,16 @@ angular.module('$strap.directives').factory('$modal', [ function ($rootScope, $compile, $http, $timeout, $q, $templateCache, $strapConfig) { var ModalFactory = function ModalFactory(config) { function Modal(config) { - var options = angular.extend({ show: true }, $strapConfig.modal, config), scope = options.scope ? options.scope : $rootScope.$new(), templateUrl = options.template; - return $q.when($templateCache.get(templateUrl) || $http.get(templateUrl, { cache: true }).then(function (res) { + var options = angular.extend({ show: true }, $strapConfig.modal, config); + var scope = options.scope ? options.scope : $rootScope.$new() + var templateUrl = options.template; + return $q.when(options.templateHtml || $templateCache.get(templateUrl) || $http.get(templateUrl, { cache: true }).then(function (res) { return res.data; })).then(function onSuccess(template) { - var id = templateUrl.replace('.html', '').replace(/[\/|\.|:]/g, '-') + '-' + scope.$id; + var id = scope.$id; + if (templateUrl) { + id += templateUrl.replace('.html', '').replace(/[\/|\.|:]/g, '-'); + } // grafana change, removed fade var $modal = $('').attr('id', id).html(template); if (options.modalClass)