Commit f48f5428 by Torkel Ödegaard

Adding snapshot storage and route, #1623

parent 964f0861
package api package api
import ( import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models" m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
) )
func CreateDashboardSnapshotCommand(c *middleware.Context, cmd m.CreateDashboardSnapshotCommand) { func CreateDashboardSnapshot(c *middleware.Context, cmd m.CreateDashboardSnapshotCommand) {
cmd.Key = util.GetRandomString(20) cmd.Key = util.GetRandomString(20)
if err := bus.Dispatch(&cmd); err != nil { if err := bus.Dispatch(&cmd); err != nil {
...@@ -29,5 +30,10 @@ func GetDashboardSnapshot(c *middleware.Context) { ...@@ -29,5 +30,10 @@ func GetDashboardSnapshot(c *middleware.Context) {
return return
} }
c.JSON(200, query.Result) dto := dtos.Dashboard{
Model: query.Result.Dashboard,
Meta: dtos.DashboardMeta{IsSnapshot: true},
}
c.JSON(200, dto)
} }
...@@ -27,9 +27,10 @@ type CurrentUser struct { ...@@ -27,9 +27,10 @@ type CurrentUser struct {
} }
type DashboardMeta struct { type DashboardMeta struct {
IsStarred bool `json:"isStarred"` IsStarred bool `json:"isStarred"`
IsHome bool `json:"isHome"` IsHome bool `json:"isHome"`
Slug string `json:"slug"` IsSnapshot bool `json:"isSnapshot"`
Slug string `json:"slug"`
} }
type Dashboard struct { type Dashboard struct {
......
...@@ -3,7 +3,7 @@ package migrations ...@@ -3,7 +3,7 @@ package migrations
import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator" import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
func addDashboardSnapshotMigrations(mg *Migrator) { func addDashboardSnapshotMigrations(mg *Migrator) {
snapshotV3 := Table{ snapshotV4 := Table{
Name: "dashboard_snapshot", Name: "dashboard_snapshot",
Columns: []*Column{ Columns: []*Column{
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true}, {Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
...@@ -19,6 +19,6 @@ func addDashboardSnapshotMigrations(mg *Migrator) { ...@@ -19,6 +19,6 @@ func addDashboardSnapshotMigrations(mg *Migrator) {
}, },
} }
mg.AddMigration("create dashboard_snapshot table v3", NewAddTableMigration(snapshotV3)) mg.AddMigration("create dashboard_snapshot table v4", NewAddTableMigration(snapshotV4))
addTableIndicesMigrations(mg, "v3", snapshotV3) addTableIndicesMigrations(mg, "v4", snapshotV4)
} }
...@@ -54,7 +54,33 @@ ...@@ -54,7 +54,33 @@
</em> </em>
</p> </p>
<button class="btn btn-success btn" ng-click="snapshot()">Create snapshot</button> <div ng-if="!snapshotUrl" style="margin-bottom: 20px;">
<div class="tight-form last">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px">
Snapshot name
</li>
<li>
<input type="text" ng-model="snapshot.name" class="input-xxlarge tight-form-input last" >
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
<div class="gf-form" ng-if="snapshotUrl">
<div class="gf-form-row">
<button class="btn btn-inverse pull-right" data-clipboard-text="{{snapshotUrl}}" clipboard-button><i class="fa fa-clipboard"></i> Copy</button>
<span class="gf-fluid-input">
<input type="text" data-share-panel-url class="input" ng-model='snapshotUrl'></input>
</span>
</div>
</div>
<button class="btn btn-success btn" ng-click="createSnapshot()" ng-if="!snapshotUrl" ng-disabled="loading">
Create snapshot
<i ng-if="loading" class="fa fa-spinner fa-spin"></i>
</button>
</div> </div>
......
...@@ -6,18 +6,27 @@ function (angular) { ...@@ -6,18 +6,27 @@ function (angular) {
var module = angular.module('grafana.controllers'); var module = angular.module('grafana.controllers');
module.controller('ShareSnapshotCtrl', function($scope, $rootScope, backendSrv, $timeout) { module.controller('ShareSnapshotCtrl', function($scope, $rootScope, $location, backendSrv, $timeout) {
$scope.snapshot = function() { $scope.snapshot = {
name: $scope.dashboard.title
};
$scope.createSnapshot = function() {
$scope.dashboard.snapshot = true; $scope.dashboard.snapshot = true;
$scope.loading = true;
$rootScope.$broadcast('refresh'); $rootScope.$broadcast('refresh');
$timeout(function() { $timeout(function() {
var dash = angular.copy($scope.dashboard); var dash = angular.copy($scope.dashboard);
backendSrv.post('/api/snapshots/', { backendSrv.post('/api/snapshots/', {dashboard: dash}).then(function(results) {
dashboard: dash $scope.loading = false;
}).then(function(results) {
console.log(results); var baseUrl = $location.absUrl().replace($location.url(), "");
$scope.snapshotUrl = baseUrl + '/dashboard/snapshots/' + results.key;
}, function() {
$scope.loading = false;
}); });
$scope.dashboard.snapshot = false; $scope.dashboard.snapshot = false;
......
...@@ -35,6 +35,10 @@ define([ ...@@ -35,6 +35,10 @@ define([
controller : 'DashFromImportCtrl', controller : 'DashFromImportCtrl',
reloadOnSearch: false, reloadOnSearch: false,
}) })
.when('/dashboard/snapshots/:key', {
templateUrl: 'app/partials/dashboard.html',
controller : 'DashFromSnapshotCtrl',
})
.when('/dashboard/new', { .when('/dashboard/new', {
templateUrl: 'app/partials/dashboard.html', templateUrl: 'app/partials/dashboard.html',
controller : 'NewDashboardCtrl', controller : 'NewDashboardCtrl',
......
...@@ -33,6 +33,15 @@ function (angular, _, kbn, moment, $) { ...@@ -33,6 +33,15 @@ function (angular, _, kbn, moment, $) {
}); });
}); });
module.controller('DashFromSnapshotCtrl', function($scope, $routeParams, backendSrv) {
backendSrv.get('/api/snapshots/' + $routeParams.key).then(function(result) {
$scope.initDashboard(result, $scope);
},function() {
$scope.initDashboard({}, $scope);
$scope.appEvent('alert-error', ['Dashboard Snapshot', '']);
});
});
module.controller('DashFromImportCtrl', function($scope, $location, alertSrv) { module.controller('DashFromImportCtrl', function($scope, $location, alertSrv) {
if (!window.grafanaImportDashboard) { if (!window.grafanaImportDashboard) {
alertSrv.set('Not found', 'Cannot reload page with unsaved imported dashboard', 'warning', 7000); alertSrv.set('Not found', 'Cannot reload page with unsaved imported dashboard', 'warning', 7000);
...@@ -47,7 +56,7 @@ function (angular, _, kbn, moment, $) { ...@@ -47,7 +56,7 @@ function (angular, _, kbn, moment, $) {
meta: {}, meta: {},
model: { model: {
title: "New dashboard", title: "New dashboard",
rows: [{ height: '250px', panels:[] }] rows: [{ height: '250px', panels:[] }]
}, },
}, $scope); }, $scope);
}); });
...@@ -57,10 +66,10 @@ function (angular, _, kbn, moment, $) { ...@@ -57,10 +66,10 @@ function (angular, _, kbn, moment, $) {
var file_load = function(file) { var file_load = function(file) {
return $http({ return $http({
url: "public/dashboards/"+file.replace(/\.(?!json)/,"/")+'?' + new Date().getTime(), url: "public/dashboards/"+file.replace(/\.(?!json)/,"/")+'?' + new Date().getTime(),
method: "GET", method: "GET",
transformResponse: function(response) { transformResponse: function(response) {
return angular.fromJson(response); return angular.fromJson(response);
} }
}).then(function(result) { }).then(function(result) {
if(!result) { if(!result) {
return false; return false;
...@@ -83,8 +92,8 @@ function (angular, _, kbn, moment, $) { ...@@ -83,8 +92,8 @@ function (angular, _, kbn, moment, $) {
var execute_script = function(result) { var execute_script = function(result) {
var services = { var services = {
dashboardSrv: dashboardSrv, dashboardSrv: dashboardSrv,
datasourceSrv: datasourceSrv, datasourceSrv: datasourceSrv,
$q: $q, $q: $q,
}; };
/*jshint -W054 */ /*jshint -W054 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment