Commit e06756bc by Torkel Ödegaard

Merge branch 'preferences' of github.com:grafana/grafana into preferences

parents 9c222a44 51bde36d
...@@ -96,7 +96,6 @@ func Register(r *macaron.Macaron) { ...@@ -96,7 +96,6 @@ func Register(r *macaron.Macaron) {
r.Delete("/stars/dashboard/:id", wrap(UnstarDashboard)) r.Delete("/stars/dashboard/:id", wrap(UnstarDashboard))
r.Put("/password", bind(m.ChangeUserPasswordCommand{}), wrap(ChangeUserPassword)) r.Put("/password", bind(m.ChangeUserPasswordCommand{}), wrap(ChangeUserPassword))
r.Get("/quotas", wrap(GetUserQuotas)) r.Get("/quotas", wrap(GetUserQuotas))
r.Combo("/prefs").Get(GetUserPreferences).Put(bind(m.SavePreferencesCommand{}), wrap(SaveUserPreferences))
}) })
// users (admin permission required) // users (admin permission required)
...@@ -161,6 +160,8 @@ func Register(r *macaron.Macaron) { ...@@ -161,6 +160,8 @@ func Register(r *macaron.Macaron) {
r.Delete("/:id", wrap(DeleteApiKey)) r.Delete("/:id", wrap(DeleteApiKey))
}, reqOrgAdmin) }, reqOrgAdmin)
r.Combo("/preferences").Get(GetPreferences).Put(bind(m.SavePreferencesCommand{}), wrap(SavePreferences))
// Data sources // Data sources
r.Group("/datasources", func() { r.Group("/datasources", func() {
r.Get("/", GetDataSources) r.Get("/", GetDataSources)
......
...@@ -7,32 +7,33 @@ import ( ...@@ -7,32 +7,33 @@ import (
) )
// PUT /api/user/prefs // PUT /api/user/prefs
func SaveUserPreferences(c *middleware.Context, cmd m.SavePreferencesCommand) Response { func SavePreferences(c *middleware.Context, cmd m.SavePreferencesCommand) Response {
cmd.PrefId = c.UserId cmd.UserId = c.UserId
cmd.PrefType = `user` cmd.OrgId = c.OrgId
if err := bus.Dispatch(&cmd); err != nil { if err := bus.Dispatch(&cmd); err != nil {
return ApiError(500, "Failed to saved user preferences", err) return ApiError(500, "Failed to save preferences", err)
} }
return ApiSuccess("User preferences saved") return ApiSuccess("Preferences saved")
} }
// GET /api/user/prefs // GET /api/user/prefs
func GetUserPreferences(c *middleware.Context) { func GetPreferences(c *middleware.Context) {
query := m.GetPreferencesQuery{PrefId: c.UserId, PrefType: `user`} query := m.GetPreferencesQuery{UserId: c.UserId, OrgId: c.OrgId}
if err := bus.Dispatch(&query); err != nil { if err := bus.Dispatch(&query); err != nil {
c.JsonApiErr(500, "Failed to get preferences for user", err) c.JsonApiErr(500, "Failed to get preferences", err)
} }
dto := m.PreferencesDTO{ dto := m.PreferencesDTO{
PrefId: query.Result.PrefId, Id: query.Result.Id,
PrefType: query.Result.PrefType, UserId: query.Result.UserId,
PrefData: query.Result.PrefData, OrgId: query.Result.OrgId,
Preference: query.Result.Preference,
} }
c.JSON(200, dto) c.JSON(200, dto)
......
...@@ -2,6 +2,7 @@ package models ...@@ -2,6 +2,7 @@ package models
import ( import (
"errors" "errors"
"time"
) )
// Typed errors // Typed errors
...@@ -10,18 +11,22 @@ var ( ...@@ -10,18 +11,22 @@ var (
) )
type Preferences struct { type Preferences struct {
Id int64 Id int64
PrefId int64 OrgId int64
PrefType string UserId int64
PrefData map[string]interface{} Version int
Preference map[string]interface{}
Created time.Time
Updated time.Time
} }
// --------------------- // ---------------------
// QUERIES // QUERIES
type GetPreferencesQuery struct { type GetPreferencesQuery struct {
PrefId int64 Id int64
PrefType string OrgId int64
UserId int64
Result *Preferences Result *Preferences
} }
...@@ -30,16 +35,17 @@ type GetPreferencesQuery struct { ...@@ -30,16 +35,17 @@ type GetPreferencesQuery struct {
// COMMANDS // COMMANDS
type SavePreferencesCommand struct { type SavePreferencesCommand struct {
PrefData map[string]interface{} `json:"prefData" binding:"Required"` Preference map[string]interface{} `json:"Preference" binding:"Required"`
PrefId int64 `json:"-"` UserId int64 `json:"-"`
PrefType string `json:"-"` OrgId int64 `json:"-"`
} }
// ---------------------- // ----------------------
// DTO & Projections // DTO & Projections
type PreferencesDTO struct { type PreferencesDTO struct {
PrefId int64 `json:"prefId"` Id int64 `json:"Id"`
PrefType string `json:"prefType"` UserId int64 `json:"UserId"`
PrefData map[string]interface{} `json:"prefData"` OrgId int64 `json:"OrgId"`
Preference map[string]interface{} `json:"Preference"`
} }
...@@ -8,9 +8,12 @@ func addPreferencesMigrations(mg *Migrator) { ...@@ -8,9 +8,12 @@ func addPreferencesMigrations(mg *Migrator) {
Name: "preferences", Name: "preferences",
Columns: []*Column{ Columns: []*Column{
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true}, {Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
{Name: "pref_id", Type: DB_Int, Nullable: false}, {Name: "org_id", Type: DB_Int, Nullable: false},
{Name: "pref_type", Type: DB_NVarchar, Length: 255, Nullable: false}, {Name: "user_id", Type: DB_NVarchar, Length: 255, Nullable: false},
{Name: "pref_data", Type: DB_Text, Nullable: false}, {Name: "version", Type: DB_Int, Nullable: false},
{Name: "preference", Type: DB_Text, Nullable: false},
{Name: "created", Type: DB_DateTime, Nullable: false},
{Name: "updated", Type: DB_DateTime, Nullable: false},
}, },
} }
......
...@@ -3,6 +3,7 @@ package sqlstore ...@@ -3,6 +3,7 @@ package sqlstore
import ( import (
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
m "github.com/grafana/grafana/pkg/models" m "github.com/grafana/grafana/pkg/models"
"time"
) )
func init() { func init() {
...@@ -12,12 +13,12 @@ func init() { ...@@ -12,12 +13,12 @@ func init() {
func GetPreferences(query *m.GetPreferencesQuery) error { func GetPreferences(query *m.GetPreferencesQuery) error {
sql := `SELECT * FROM preferences WHERE pref_id = ? ` + sql := `SELECT * FROM preferences WHERE user_id = ? ` +
`AND pref_type = ?` `AND org_id = ?`
var prefResults = make([]m.Preferences, 0) var prefResults = make([]m.Preferences, 0)
resultsErr := x.Sql(sql, query.PrefId, query.PrefType).Find(&prefResults) resultsErr := x.Sql(sql, query.UserId, query.OrgId).Find(&prefResults)
if resultsErr != nil { if resultsErr != nil {
return resultsErr return resultsErr
...@@ -35,12 +36,12 @@ func GetPreferences(query *m.GetPreferencesQuery) error { ...@@ -35,12 +36,12 @@ func GetPreferences(query *m.GetPreferencesQuery) error {
func SavePreferences(cmd *m.SavePreferencesCommand) error { func SavePreferences(cmd *m.SavePreferencesCommand) error {
return inTransaction2(func(sess *session) error { return inTransaction2(func(sess *session) error {
sql := `SELECT * FROM preferences WHERE pref_id = ? ` + sql := `SELECT * FROM preferences WHERE user_id = ? ` +
`AND pref_type = ?` `AND org_id = ?`
var prefResults = make([]m.Preferences, 0) var prefResults = make([]m.Preferences, 0)
resultsErr := sess.Sql(sql, cmd.PrefId, cmd.PrefType).Find(&prefResults) resultsErr := sess.Sql(sql, cmd.UserId, cmd.OrgId).Find(&prefResults)
if resultsErr != nil { if resultsErr != nil {
return resultsErr return resultsErr
...@@ -51,13 +52,15 @@ func SavePreferences(cmd *m.SavePreferencesCommand) error { ...@@ -51,13 +52,15 @@ func SavePreferences(cmd *m.SavePreferencesCommand) error {
var saveErr error var saveErr error
if len(prefResults) == 0 { if len(prefResults) == 0 {
savePref.PrefId = cmd.PrefId savePref.UserId = cmd.UserId
savePref.PrefType = cmd.PrefType savePref.OrgId = cmd.OrgId
savePref.PrefData = cmd.PrefData savePref.Preference = cmd.Preference
savePref = SetPreferencesModel(savePref, false)
affectedRows, saveErr = sess.Insert(&savePref) affectedRows, saveErr = sess.Insert(&savePref)
} else { } else {
savePref = prefResults[0] savePref = prefResults[0]
savePref.PrefData = cmd.PrefData savePref.Preference = cmd.Preference
savePref = SetPreferencesModel(savePref, true)
affectedRows, saveErr = sess.Id(savePref.Id).Update(&savePref) affectedRows, saveErr = sess.Id(savePref.Id).Update(&savePref)
} }
...@@ -68,3 +71,16 @@ func SavePreferences(cmd *m.SavePreferencesCommand) error { ...@@ -68,3 +71,16 @@ func SavePreferences(cmd *m.SavePreferencesCommand) error {
return saveErr return saveErr
}) })
} }
func SetPreferencesModel(pref m.Preferences, updating bool) m.Preferences {
if updating {
pref.Version = pref.Version + 1
} else {
pref.Version = 0
pref.Created = time.Now()
}
pref.Updated = time.Now()
return pref
}
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="editJson();">View JSON</a></li> <li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="editJson();">View JSON</a></li>
<li ng-if="contextSrv.isEditor && !dashboard.editable"><a class="pointer" ng-click="makeEditable();">Make Editable</a></li> <li ng-if="contextSrv.isEditor && !dashboard.editable"><a class="pointer" ng-click="makeEditable();">Make Editable</a></li>
<li ng-if="contextSrv.isEditor"><a class="pointer" ng-click="saveDashboardAs();">Save As...</a></li> <li ng-if="contextSrv.isEditor"><a class="pointer" ng-click="saveDashboardAs();">Save As...</a></li>
<li ng-if="contextSrv.isEditor"><a class="pointer" ng-click="saveDashboardAsHome();">Save As Home</a></li>
<li ng-if="dashboardMeta.canSave"><a class="pointer" ng-click="deleteDashboard();">Delete dashboard</a></li> <li ng-if="dashboardMeta.canSave"><a class="pointer" ng-click="deleteDashboard();">Delete dashboard</a></li>
</ul> </ul>
</li> </li>
......
...@@ -7,7 +7,7 @@ import angular from 'angular'; ...@@ -7,7 +7,7 @@ import angular from 'angular';
export class DashNavCtrl { export class DashNavCtrl {
/** @ngInject */ /** @ngInject */
constructor($scope, $rootScope, alertSrv, $location, playlistSrv, backendSrv, $timeout) { constructor($scope, $rootScope, alertSrv, $location, playlistSrv, backendSrv, contextSrv, $timeout) {
$scope.init = function() { $scope.init = function() {
$scope.onAppEvent('save-dashboard', $scope.saveDashboard); $scope.onAppEvent('save-dashboard', $scope.saveDashboard);
...@@ -103,6 +103,26 @@ export class DashNavCtrl { ...@@ -103,6 +103,26 @@ export class DashNavCtrl {
}, $scope.handleSaveDashError); }, $scope.handleSaveDashError);
}; };
$scope.saveDashboardAsHome = function() {
var orgId = 'org-' + contextSrv.user.orgId;
backendSrv.get('/api/preferences').then(function(prefs) {
// Checking if the preferences already exists or not
if (prefs.userId === 0 && prefs.orgId === 0 && prefs.preference === null) {
prefs.preference = {};
}
if (prefs.preference == null) {
prefs.preference = {
home_dashboard_id: $scope.dashboard.id
};
} else {
var orgPrefs = prefs.preference;
orgPrefs.home_dashboard = $scope.dashboard.id;
}
backendSrv.put('api/preferences', prefs);
});
};
$scope.handleSaveDashError = function(err) { $scope.handleSaveDashError = function(err) {
if (err.data && err.data.status === "version-mismatch") { if (err.data && err.data.status === "version-mismatch") {
err.isHandled = true; err.isHandled = true;
......
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