mirror of https://github.com/grafana/grafana
parent
a76758255f
commit
964f0861d6
@ -0,0 +1,33 @@ |
||||
package api |
||||
|
||||
import ( |
||||
"github.com/grafana/grafana/pkg/bus" |
||||
"github.com/grafana/grafana/pkg/middleware" |
||||
m "github.com/grafana/grafana/pkg/models" |
||||
"github.com/grafana/grafana/pkg/util" |
||||
) |
||||
|
||||
func CreateDashboardSnapshotCommand(c *middleware.Context, cmd m.CreateDashboardSnapshotCommand) { |
||||
cmd.Key = util.GetRandomString(20) |
||||
|
||||
if err := bus.Dispatch(&cmd); err != nil { |
||||
c.JsonApiErr(500, "Failed to create snaphost", err) |
||||
return |
||||
} |
||||
|
||||
c.JSON(200, util.DynMap{"key": cmd.Key}) |
||||
} |
||||
|
||||
func GetDashboardSnapshot(c *middleware.Context) { |
||||
key := c.Params(":key") |
||||
|
||||
query := &m.GetDashboardSnapshotQuery{Key: key} |
||||
|
||||
err := bus.Dispatch(query) |
||||
if err != nil { |
||||
c.JsonApiErr(500, "Failed to get dashboard snapshot", err) |
||||
return |
||||
} |
||||
|
||||
c.JSON(200, query.Result) |
||||
} |
@ -0,0 +1,33 @@ |
||||
package models |
||||
|
||||
import "time" |
||||
|
||||
// DashboardSnapshot model
|
||||
type DashboardSnapshot struct { |
||||
Id int64 |
||||
Name string |
||||
Key string |
||||
|
||||
Expires time.Time |
||||
Created time.Time |
||||
Updated time.Time |
||||
|
||||
Dashboard map[string]interface{} |
||||
} |
||||
|
||||
// -----------------
|
||||
// COMMANDS
|
||||
|
||||
type CreateDashboardSnapshotCommand struct { |
||||
Dashboard map[string]interface{} `json:"dashboard" binding:"Required"` |
||||
|
||||
Key string `json:"-"` |
||||
|
||||
Result *DashboardSnapshot |
||||
} |
||||
|
||||
type GetDashboardSnapshotQuery struct { |
||||
Key string |
||||
|
||||
Result *DashboardSnapshot |
||||
} |
@ -0,0 +1,46 @@ |
||||
package sqlstore |
||||
|
||||
import ( |
||||
"time" |
||||
|
||||
"github.com/go-xorm/xorm" |
||||
"github.com/grafana/grafana/pkg/bus" |
||||
m "github.com/grafana/grafana/pkg/models" |
||||
) |
||||
|
||||
func init() { |
||||
bus.AddHandler("sql", CreateDashboardSnapshot) |
||||
bus.AddHandler("sql", GetDashboardSnapshot) |
||||
} |
||||
|
||||
func CreateDashboardSnapshot(cmd *m.CreateDashboardSnapshotCommand) error { |
||||
return inTransaction(func(sess *xorm.Session) error { |
||||
|
||||
snapshot := &m.DashboardSnapshot{ |
||||
Key: cmd.Key, |
||||
Dashboard: cmd.Dashboard, |
||||
Expires: time.Unix(0, 0), |
||||
Created: time.Now(), |
||||
Updated: time.Now(), |
||||
} |
||||
|
||||
_, err := sess.Insert(snapshot) |
||||
cmd.Result = snapshot |
||||
|
||||
return err |
||||
}) |
||||
} |
||||
|
||||
func GetDashboardSnapshot(query *m.GetDashboardSnapshotQuery) error { |
||||
var snapshot m.DashboardSnapshot |
||||
has, err := x.Where("key=?", query.Key).Get(&snapshot) |
||||
|
||||
if err != nil { |
||||
return err |
||||
} else if has == false { |
||||
return m.ErrNotFound |
||||
} |
||||
|
||||
query.Result = &snapshot |
||||
return nil |
||||
} |
@ -0,0 +1,37 @@ |
||||
package sqlstore |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
. "github.com/smartystreets/goconvey/convey" |
||||
|
||||
m "github.com/grafana/grafana/pkg/models" |
||||
) |
||||
|
||||
func TestDashboardSnapshotDBAccess(t *testing.T) { |
||||
|
||||
Convey("Testing DashboardSnapshot data access", t, func() { |
||||
InitTestDB(t) |
||||
|
||||
Convey("Given saved snaphot", func() { |
||||
cmd := m.CreateDashboardSnapshotCommand{ |
||||
Key: "hej", |
||||
Dashboard: map[string]interface{}{ |
||||
"hello": "mupp", |
||||
}, |
||||
} |
||||
err := CreateDashboardSnapshot(&cmd) |
||||
So(err, ShouldBeNil) |
||||
|
||||
Convey("Should be able to get snaphot by key", func() { |
||||
query := m.GetDashboardSnapshotQuery{Key: "hej"} |
||||
err = GetDashboardSnapshot(&query) |
||||
So(err, ShouldBeNil) |
||||
|
||||
So(query.Result, ShouldNotBeNil) |
||||
So(query.Result.Dashboard["hello"], ShouldEqual, "mupp") |
||||
}) |
||||
|
||||
}) |
||||
}) |
||||
} |
@ -0,0 +1,24 @@ |
||||
package migrations |
||||
|
||||
import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator" |
||||
|
||||
func addDashboardSnapshotMigrations(mg *Migrator) { |
||||
snapshotV3 := Table{ |
||||
Name: "dashboard_snapshot", |
||||
Columns: []*Column{ |
||||
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true}, |
||||
{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false}, |
||||
{Name: "key", Type: DB_NVarchar, Length: 255, Nullable: false}, |
||||
{Name: "dashboard", Type: DB_Text, Nullable: false}, |
||||
{Name: "expires", Type: DB_DateTime, Nullable: false}, |
||||
{Name: "created", Type: DB_DateTime, Nullable: false}, |
||||
{Name: "updated", Type: DB_DateTime, Nullable: false}, |
||||
}, |
||||
Indices: []*Index{ |
||||
{Cols: []string{"key"}, Type: UniqueIndex}, |
||||
}, |
||||
} |
||||
|
||||
mg.AddMigration("create dashboard_snapshot table v3", NewAddTableMigration(snapshotV3)) |
||||
addTableIndicesMigrations(mg, "v3", snapshotV3) |
||||
} |
@ -0,0 +1,30 @@ |
||||
define([ |
||||
'angular', |
||||
], |
||||
function (angular) { |
||||
'use strict'; |
||||
|
||||
var module = angular.module('grafana.controllers'); |
||||
|
||||
module.controller('ShareSnapshotCtrl', function($scope, $rootScope, backendSrv, $timeout) { |
||||
|
||||
$scope.snapshot = function() { |
||||
$scope.dashboard.snapshot = true; |
||||
$rootScope.$broadcast('refresh'); |
||||
|
||||
$timeout(function() { |
||||
var dash = angular.copy($scope.dashboard); |
||||
backendSrv.post('/api/snapshots/', { |
||||
dashboard: dash |
||||
}).then(function(results) { |
||||
console.log(results); |
||||
}); |
||||
|
||||
$scope.dashboard.snapshot = false; |
||||
$scope.appEvent('dashboard-snapshot-cleanup'); |
||||
}, 2000); |
||||
}; |
||||
|
||||
}); |
||||
|
||||
}); |
@ -1,18 +0,0 @@ |
||||
<div class="modal-body gf-box gf-box-no-margin"> |
||||
<div class="gf-box-header"> |
||||
<div class="gf-box-title"> |
||||
<i class="fa fa-share-alt"></i> |
||||
Share dashboard |
||||
</div> |
||||
|
||||
<button class="gf-box-header-close-btn" ng-click="dismiss();"> |
||||
<i class="fa fa-remove"></i> |
||||
</button> |
||||
</div> |
||||
|
||||
<div class="gf-box-body"> |
||||
<label>Share this dashboard with this URL</label> |
||||
<input ng-model='share.url' type="text" style="width:90%" onclick="this.select()" onfocus="this.select()"> |
||||
</div> |
||||
|
||||
</div> |
Loading…
Reference in new issue