diff --git a/pkg/api/api.go b/pkg/api/api.go
index 28e2ea8ab3d..f79c0661d55 100644
--- a/pkg/api/api.go
+++ b/pkg/api/api.go
@@ -75,6 +75,7 @@ func Register(r *macaron.Macaron) {
r.Group("/datasources", func() {
r.Combo("/").Get(GetDataSources).Put(AddDataSource).Post(UpdateDataSource)
r.Delete("/:id", DeleteDataSource)
+ r.Get("/:id", GetDataSourceById)
}, reqAccountAdmin)
r.Any("/datasources/proxy/:id/*", reqSignedIn, ProxyDataSourceRequest)
diff --git a/pkg/api/datasources.go b/pkg/api/datasources.go
index c4a7ae4d657..33a7bac2667 100644
--- a/pkg/api/datasources.go
+++ b/pkg/api/datasources.go
@@ -9,9 +9,8 @@ import (
func GetDataSources(c *middleware.Context) {
query := m.GetDataSourcesQuery{AccountId: c.AccountId}
- err := bus.Dispatch(&query)
- if err != nil {
+ if err := bus.Dispatch(&query); err != nil {
c.JsonApiErr(500, "Failed to query datasources", err)
return
}
@@ -36,6 +35,34 @@ func GetDataSources(c *middleware.Context) {
c.JSON(200, result)
}
+func GetDataSourceById(c *middleware.Context) {
+ query := m.GetDataSourceByIdQuery{
+ Id: c.ParamsInt64(":id"),
+ AccountId: c.AccountId,
+ }
+
+ if err := bus.Dispatch(&query); err != nil {
+ c.JsonApiErr(500, "Failed to query datasources", err)
+ return
+ }
+
+ ds := query.Result
+
+ c.JSON(200, &dtos.DataSource{
+ Id: ds.Id,
+ AccountId: ds.AccountId,
+ Name: ds.Name,
+ Url: ds.Url,
+ Type: ds.Type,
+ Access: ds.Access,
+ Password: ds.Password,
+ Database: ds.Database,
+ User: ds.User,
+ BasicAuth: ds.BasicAuth,
+ IsDefault: ds.IsDefault,
+ })
+}
+
func DeleteDataSource(c *middleware.Context) {
id := c.ParamsInt64(":id")
diff --git a/src/app/controllers/sidemenuCtrl.js b/src/app/controllers/sidemenuCtrl.js
index 211ca4451c0..184e2cab2fb 100644
--- a/src/app/controllers/sidemenuCtrl.js
+++ b/src/app/controllers/sidemenuCtrl.js
@@ -37,7 +37,7 @@ function (angular, _, $, config) {
if (contextSrv.user.isGrafanaAdmin) {
$scope.menu.push({
- text: "Admin", href: $scope.getUrl("/admin/users"),
+ text: "Admin", href: $scope.getUrl("/admin/settings"),
icon: "fa fa-cube",
requireSignedIn: true,
});
diff --git a/src/app/features/account/all.js b/src/app/features/account/all.js
index 7c01d7b8c1c..277ae1a75f1 100644
--- a/src/app/features/account/all.js
+++ b/src/app/features/account/all.js
@@ -1,6 +1,7 @@
define([
'./accountUsersCtrl',
'./datasourcesCtrl',
+ './datasourceEditCtrl',
'./apiKeysCtrl',
'./importCtrl',
'./accountCtrl',
diff --git a/src/app/features/account/datasourceEditCtrl.js b/src/app/features/account/datasourceEditCtrl.js
new file mode 100644
index 00000000000..bf1912f2677
--- /dev/null
+++ b/src/app/features/account/datasourceEditCtrl.js
@@ -0,0 +1,69 @@
+define([
+ 'angular',
+ 'lodash',
+],
+function (angular) {
+ 'use strict';
+
+ var module = angular.module('grafana.controllers');
+
+ module.controller('DataSourceEditCtrl', function($scope, $http, backendSrv, $routeParams, $location) {
+
+ var defaults = {
+ name: '',
+ type: 'graphite',
+ url: '',
+ access: 'proxy'
+ };
+
+ $scope.types = [
+ { name: 'Graphite', type: 'graphite' },
+ { name: 'InfluxDB', type: 'influxdb' },
+ { name: 'Elasticsearch', type: 'elasticsearch' },
+ { name: 'OpenTSDB', type: 'opentsdb' },
+ ];
+
+ $scope.init = function() {
+ $scope.isNew = true;
+ $scope.datasources = [];
+
+ if ($routeParams.id) {
+ $scope.isNew = false;
+ $scope.getDatasourceById($routeParams.id);
+ } else {
+ $scope.current = angular.copy(defaults);
+ }
+ };
+
+ $scope.getDatasourceById = function(id) {
+ backendSrv.get('/api/datasources/' + id).then(function(ds) {
+ $scope.current = ds;
+ });
+ };
+
+ $scope.update = function() {
+ if (!$scope.editForm.$valid) {
+ return;
+ }
+
+ backendSrv.post('/api/datasources', $scope.current).then(function() {
+ $location.path("account/datasources");
+ });
+ };
+
+ $scope.add = function() {
+ if (!$scope.editForm.$valid) {
+ return;
+ }
+
+ backendSrv.put('/api/datasources', $scope.current)
+ .then(function() {
+ $scope.editor.index = 0;
+ $scope.getDatasources();
+ });
+ };
+
+ $scope.init();
+
+ });
+});
diff --git a/src/app/features/account/datasourcesCtrl.js b/src/app/features/account/datasourcesCtrl.js
index b8f9f9fda7a..00a906ba64e 100644
--- a/src/app/features/account/datasourcesCtrl.js
+++ b/src/app/features/account/datasourcesCtrl.js
@@ -1,5 +1,6 @@
define([
'angular',
+ 'lodash',
],
function (angular) {
'use strict';
@@ -8,47 +9,9 @@ function (angular) {
module.controller('DataSourcesCtrl', function($scope, $http, backendSrv) {
- var defaults = {
- name: '',
- type: 'graphite',
- url: '',
- 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};
$scope.datasources = [];
$scope.getDatasources();
-
- $scope.$watch('editor.index', function(newVal) {
- if (newVal !== 2) {
- $scope.reset();
- }
- });
- };
-
- $scope.reset = function() {
- $scope.current = angular.copy(defaults);
- $scope.currentIsNew = true;
- };
-
- $scope.edit = function(ds) {
- $scope.current = ds;
- $scope.currentIsNew = false;
- $scope.editor.index = 2;
- };
-
- $scope.cancel = function() {
- $scope.reset();
- $scope.editor.index = 0;
};
$scope.getDatasources = function() {
@@ -63,25 +26,6 @@ function (angular) {
});
};
- $scope.update = function() {
- backendSrv.post('/api/datasources', $scope.current).then(function() {
- $scope.editor.index = 0;
- $scope.getDatasources();
- });
- };
-
- $scope.add = function() {
- if (!$scope.editForm.$valid) {
- return;
- }
-
- backendSrv.put('/api/datasources', $scope.current)
- .then(function() {
- $scope.editor.index = 0;
- $scope.getDatasources();
- });
- };
-
$scope.init();
});
diff --git a/src/app/features/account/partials/datasourceEdit.html b/src/app/features/account/partials/datasourceEdit.html
new file mode 100644
index 00000000000..fc8b865974f
--- /dev/null
+++ b/src/app/features/account/partials/datasourceEdit.html
@@ -0,0 +1,74 @@
+