| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- commit 1c5f902770c260f9bc63a0f07f1e9d22f60ce796
- Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
- Date: Sat Jan 17 10:39:01 2015 +0100
- Added dashboard import feature
- diff --git a/src/app/features/account/datasourcesCtrl.js b/src/app/features/account/datasourcesCtrl.js
- index 983c74b4b..b8f9f9fda 100644
- --- a/src/app/features/account/datasourcesCtrl.js
- +++ b/src/app/features/account/datasourcesCtrl.js
- @@ -15,6 +15,13 @@ function (angular) {
- access: 'proxy'
- };
-
- + $scope.types = [
- + { name: 'Graphite', type: 'graphite' },
- + { name: 'InfluxDB', type: 'influxdb' },
- + { name: 'Elasticsearch', type: 'elasticsearch' },
- + { name: 'OpenTSDB', type: 'opentsdb' },
- + ];
- +
- $scope.init = function() {
- $scope.reset();
- $scope.editor = {index: 0};
- diff --git a/src/app/features/account/importCtrl.js b/src/app/features/account/importCtrl.js
- new file mode 100644
- index 000000000..a8548491c
- --- /dev/null
- +++ b/src/app/features/account/importCtrl.js
- @@ -0,0 +1,78 @@
- +define([
- + 'angular',
- + 'lodash',
- +],
- +function (angular, _) {
- + 'use strict';
- +
- + var module = angular.module('grafana.controllers');
- +
- + module.controller('ImportCtrl', function($scope, $http, backendSrv, datasourceSrv) {
- +
- + $scope.init = function() {
- + $scope.datasources = [];
- + $scope.sourceName = 'grafana';
- + $scope.destName = 'grafana';
- + $scope.imported = [];
- + $scope.dashboards = [];
- + $scope.infoText = '';
- + $scope.importing = false;
- +
- + _.each(datasourceSrv.getAll(), function(ds) {
- + if (ds.type === 'influxdb' || ds.type === 'elasticsearch') {
- + $scope.sourceName = ds.name;
- + $scope.datasources.push(ds.name);
- + } else if (ds.type === 'grafana') {
- + $scope.datasources.push(ds.name);
- + }
- + });
- + };
- +
- + $scope.startImport = function() {
- + $scope.sourceDs = datasourceSrv.get($scope.sourceName);
- + $scope.destDs = datasourceSrv.get($scope.destName);
- +
- + $scope.sourceDs.searchDashboards('title:').then(function(results) {
- + $scope.dashboards = results.dashboards;
- +
- + if ($scope.dashboards.length === 0) {
- + $scope.infoText = 'No dashboards found';
- + return;
- + }
- +
- + $scope.importing = true;
- + $scope.imported = [];
- + $scope.next();
- + });
- + };
- +
- + $scope.next = function() {
- + if ($scope.dashboards.length === 0) {
- + $scope.infoText = "Done! Imported " + $scope.imported.length + " dashboards";
- + }
- +
- + var dash = $scope.dashboards.shift();
- + if (!dash.title) {
- + console.log(dash);
- + return;
- + }
- +
- + var infoObj = {name: dash.title, info: 'Importing...'};
- + $scope.imported.push(infoObj);
- + $scope.infoText = "Importing " + $scope.imported.length + '/' + ($scope.imported.length + $scope.dashboards.length);
- +
- + $scope.sourceDs.getDashboard(dash.id).then(function(loadedDash) {
- + $scope.destDs.saveDashboard(loadedDash).then(function() {
- + infoObj.info = "Done!";
- + $scope.next();
- + }, function(err) {
- + infoObj.info = "Error: " + err;
- + $scope.next();
- + });
- + });
- + };
- +
- + $scope.init();
- +
- + });
- +});
- diff --git a/src/app/features/account/partials/collaborators.html b/src/app/features/account/partials/collaborators.html
- index e66a55d07..4d3f581c0 100644
- --- a/src/app/features/account/partials/collaborators.html
- +++ b/src/app/features/account/partials/collaborators.html
- @@ -17,20 +17,20 @@
- <div class="tight-form">
- <ul class="tight-form-list">
- <li class="tight-form-item" style="width: 160px">
- - <strong>Username or Email</strong>
- + <strong>username or email</strong>
- </li>
- <li>
- - <input type="text" ng-model="collaborator.loginOrEmail" required class="input-xlarge tight-form-input" placeholder="collaborator@email.com">
- + <input type="text" ng-model="collaborator.loginoremail" required class="input-xlarge tight-form-input" placeholder="collaborator@email.com">
- </li>
- <li class="tight-form-item">
- - Role
- + role
- </li>
- <li>
- - <select type="text" ng-model="collaborator.role" class="input-small tight-form-input" ng-options="f for f in ['Viewer', 'Editor', 'Admin']">
- + <select type="text" ng-model="collaborator.role" class="input-small tight-form-input" ng-options="f for f in ['viewer', 'editor', 'admin']">
- </select>
- </li>
- <li>
- - <button class="btn btn-success tight-form-btn" ng-click="addCollaborator()">Add</button>
- + <button class="btn btn-success tight-form-btn" ng-click="addcollaborator()">add</button>
- </li>
- </ul>
- <div class="clearfix"></div>
- diff --git a/src/app/features/account/partials/datasources.html b/src/app/features/account/partials/datasources.html
- index 86264721c..4f5f2399d 100644
- --- a/src/app/features/account/partials/datasources.html
- +++ b/src/app/features/account/partials/datasources.html
- @@ -70,7 +70,7 @@
- </div>
- <div class="editor-option">
- <label class="small">Type</label>
- - <select class="input-medium" ng-model="current.type" ng-options="f for f in ['graphite', 'influxdb', 'opentsdb']" ng-change="typeChanged()"></select>
- + <select class="input-medium" ng-model="current.type" ng-options="f.type as f.name for f in types" ng-change="typeChanged()"></select>
- </div>
- <editor-opt-bool text="Mark as default" model="current.isDefault" change="render()"></editor-opt-bool>
- </div>
- @@ -103,6 +103,15 @@
- </div>
- </div>
- </div>
- + <div class="editor-row" ng-if="current.type === 'elasticsearch'">
- + <div class="section">
- + <h5>Elastic search details</h5>
- + <div class="editor-option">
- + <label class="small">Index name</label>
- + <input type="text" class="input-large" required ng-model='current.database' placeholder=""></input>
- + </div>
- + </div>
- + </div>
- </div>
-
- <div class="dashboard-editor-footer" style="margin-top: 20px">
- diff --git a/src/app/features/account/partials/import.html b/src/app/features/account/partials/import.html
- new file mode 100644
- index 000000000..3ce6e101b
- --- /dev/null
- +++ b/src/app/features/account/partials/import.html
- @@ -0,0 +1,59 @@
- +<div ng-include="'app/partials/navbar.html'" ng-init="pageTitle='Import'"></div>
- +
- +<div class="dashboard-edit-view" style="min-height: 500px">
- +
- + <div class="dashboard-editor-header">
- + <div class="dashboard-editor-title">
- + <i class="fa fa-th-large"></i>
- + Import Dashboards
- + </div>
- + </div>
- +
- + <div class="dashboard-editor-body">
- +
- + <div class="editor-row">
- + <div class="section">
- + <div class="tight-form">
- + <ul class="tight-form-list">
- + <li class="tight-form-item" style="width: 160px">
- + <strong>Dashboard source</strong>
- + </li>
- + <li>
- + <select type="text" ng-model="sourceName" class="input-small tight-form-input" ng-options="f for f in datasources">
- + </select>
- + </li>
- + <li class="tight-form-item" style="width: 160px">
- + <strong>Destination</strong>
- + </li>
- + <li>
- + <select type="text" ng-model="destName" class="input-small tight-form-input" ng-options="f for f in datasources">
- + </select>
- + </li>
- + <li>
- + <button class="btn btn-success tight-form-btn" ng-click="startImport()">Import</button>
- + </li>
- + </ul>
- + <div class="clearfix"></div>
- + </div>
- + </div>
- + </div>
- +
- + <div class="editor-row" ng-if="importing">
- + <section class="section">
- + <h5>{{infoText}}</h5>
- +
- + <div class="editor-row row">
- + <table class="grafana-options-table span5">
- + <tr ng-repeat="dash in imported">
- + <td>{{dash.name}}</td>
- + <td>
- + {{dash.info}}
- + </td>
- + </tr>
- + </table>
- + </div>
- + </section>
- + </div>
- + </div>
- +</div>
- +
- diff --git a/src/app/features/admin/partials/accounts.html b/src/app/features/admin/partials/accounts.html
- index ffd6c7015..d8dffe750 100644
- --- a/src/app/features/admin/partials/accounts.html
- +++ b/src/app/features/admin/partials/accounts.html
- @@ -1,37 +1,39 @@
- -<div ng-include="'app/partials/navbar.html'" ng-init="pageTitle='Accounts'"></div>
- +<div ng-include="'app/partials/navbar.html'" ng-init="pageTitle='Admin > Accounts'"></div>
-
- <div class="dashboard-edit-view" style="min-height: 500px">
-
- - <div class="row-fluid">
- - <div class="span8">
- + <div class="dashboard-editor-body">
-
- - <table class="grafana-options-table">
- - <tr>
- - <th style="text-align:left">Id</th>
- - <th>Login</th>
- - <th>Email</th>
- - <th>Name</th>
- - <th>Admin</th>
- - <th></th>
- - </tr>
- - <tr ng-repeat="account in accounts">
- - <td>{{account.id}}</td>
- - <td>{{account.login}}</td>
- - <td>{{account.email}}</td>
- - <td>{{account.name}}</td>
- - <td>{{account.isAdmin}}</td>
- - <td style="width: 1%">
- - <a ng-click="edit(variable)" class="btn btn-success">
- - <i class="fa fa-edit"></i>
- - Edit
- - </a>
- -
- - <a ng-click="edit(variable)" class="btn btn-danger">
- - <i class="fa fa-remove"></i>
- - </a>
- - </td>
- - </tr>
- - </table>
- + <div class="editor-row row">
- + <div class="section span6">
- + <table class="grafana-options-table">
- + <tr>
- + <th style="text-align:left">Id</th>
- + <th>Login</th>
- + <th>Email</th>
- + <th>Name</th>
- + <th>Admin</th>
- + <th></th>
- + </tr>
- + <tr ng-repeat="account in accounts">
- + <td>{{account.id}}</td>
- + <td>{{account.login}}</td>
- + <td>{{account.email}}</td>
- + <td>{{account.name}}</td>
- + <td>{{account.isAdmin}}</td>
- + <td style="width: 1%">
- + <a ng-click="edit(variable)" class="btn btn-success btn-small">
- + <i class="fa fa-edit"></i>
- + Edit
- + </a>
- +
- + <a ng-click="edit(variable)" class="btn btn-danger btn-small">
- + <i class="fa fa-remove"></i>
- + </a>
- + </td>
- + </tr>
- + </table>
- + </div>
- </div>
- </div>
- </div>
- diff --git a/src/app/features/all.js b/src/app/features/all.js
- index 6b22c50e9..f3833c659 100644
- --- a/src/app/features/all.js
- +++ b/src/app/features/all.js
- @@ -11,6 +11,7 @@ define([
- './account/collaboratorsCtrl',
- './account/datasourcesCtrl',
- './account/apiKeysCtrl',
- + './account/importCtrl',
- './admin/accountsCtrl',
- './grafanaDatasource/datasource',
- ], function () {});
- diff --git a/src/app/features/annotations/partials/editor.html b/src/app/features/annotations/partials/editor.html
- index 14208dc2a..ae2d624ed 100644
- --- a/src/app/features/annotations/partials/editor.html
- +++ b/src/app/features/annotations/partials/editor.html
- @@ -26,7 +26,7 @@
- {{annotation.name}}
- </td>
- <td style="width: 1%">
- - <a ng-click="edit(annotation)" class="btn btn-success btn-mini">
- + <a ng-click="edit(annotation)" class="btn btn-success btn-small">
- <i class="fa fa-edit"></i>
- Edit
- </a>
- @@ -34,7 +34,7 @@
- <td style="width: 1%"><i ng-click="_.move(annotations,$index,$index-1)" ng-hide="$first" class="pointer fa fa-arrow-up"></i></td>
- <td style="width: 1%"><i ng-click="_.move(annotations,$index,$index+1)" ng-hide="$last" class="pointer fa fa-arrow-down"></i></td>
- <td style="width: 1%">
- - <a ng-click="removeAnnotation(annotation)" class="btn btn-danger btn-mini">
- + <a ng-click="removeAnnotation(annotation)" class="btn btn-danger btn-small">
- <i class="fa fa-remove"></i>
- </a>
- </td>
- diff --git a/src/app/features/elasticsearch/datasource.js b/src/app/features/elasticsearch/datasource.js
- index 3c82d98f8..0ca8ec853 100644
- --- a/src/app/features/elasticsearch/datasource.js
- +++ b/src/app/features/elasticsearch/datasource.js
- @@ -13,7 +13,7 @@ function (angular, _, config, kbn, moment) {
- module.factory('ElasticDatasource', function($q, $http, templateSrv) {
-
- function ElasticDatasource(datasource) {
- - this.type = 'elastic';
- + this.type = 'elasticsearch';
- this.basicAuth = datasource.basicAuth;
- this.url = datasource.url;
- this.name = datasource.name;
- diff --git a/src/app/features/influxdb/datasource.js b/src/app/features/influxdb/datasource.js
- index cef933d8d..692fdbdbb 100644
- --- a/src/app/features/influxdb/datasource.js
- +++ b/src/app/features/influxdb/datasource.js
- @@ -15,7 +15,7 @@ function (angular, _, kbn, InfluxSeries, InfluxQueryBuilder) {
- module.factory('InfluxDatasource', function($q, $http, templateSrv) {
-
- function InfluxDatasource(datasource) {
- - this.type = 'influxDB';
- + this.type = 'influxdb';
- this.urls = datasource.urls;
- this.username = datasource.username;
- this.password = datasource.password;
- diff --git a/src/app/partials/sidemenu.html b/src/app/partials/sidemenu.html
- index 25aeca4c9..207688965 100644
- --- a/src/app/partials/sidemenu.html
- +++ b/src/app/partials/sidemenu.html
- @@ -26,6 +26,10 @@
- <a class="pro-sidemenu-link" href="account/apikeys">
- <i class="fa fa-key"></i>API Keys
- </a>
- + <a class="pro-sidemenu-link" href="account/import">
- + <i class="fa fa-download"></i>
- + Import
- + </a>
- <a class="pro-sidemenu-link" href="admin/accounts" ng-if="grafana.user.isGrafanaAdmin">
- <i class="fa fa-institution"></i>Admin
- </a>
- diff --git a/src/app/routes/backend/all.js b/src/app/routes/backend/all.js
- index ec2635603..740baf48c 100644
- --- a/src/app/routes/backend/all.js
- +++ b/src/app/routes/backend/all.js
- @@ -42,6 +42,10 @@ define([
- templateUrl: 'app/features/account/partials/apikeys.html',
- controller : 'ApiKeysCtrl',
- })
- + .when('/account/import', {
- + templateUrl: 'app/features/account/partials/import.html',
- + controller : 'ImportCtrl',
- + })
- .when('/account', {
- templateUrl: 'app/features/account/partials/account.html',
- controller : 'AccountCtrl',
- diff --git a/src/app/services/datasourceSrv.js b/src/app/services/datasourceSrv.js
- index e77ca7077..1a2c4db5f 100644
- --- a/src/app/services/datasourceSrv.js
- +++ b/src/app/services/datasourceSrv.js
- @@ -82,6 +82,10 @@ function (angular, _, config) {
- return this.default;
- };
-
- + this.getAll = function() {
- + return datasources;
- + };
- +
- this.getAnnotationSources = function() {
- return annotationSources;
- };
|