diff --git a/pkg/api/api.go b/pkg/api/api.go index 277e5f4373a..b47c632a918 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -100,6 +100,8 @@ func Register(r *macaron.Macaron) { r.Delete("/stars/dashboard/:id", wrap(UnstarDashboard)) r.Put("/password", bind(m.ChangeUserPasswordCommand{}), wrap(ChangeUserPassword)) r.Get("/quotas", wrap(GetUserQuotas)) + r.Get("/preferences", wrap(GetUserPreferences)) + r.Put("/preferences", bind(dtos.UpdateUserPrefsCmd{}), wrap(UpdateUserPreferences)) }) // users (admin permission required) diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 1a45ffcd020..fc4aa59fbb0 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -159,7 +159,6 @@ func canEditDashboard(role m.RoleType) bool { } func GetHomeDashboard(c *middleware.Context) { - // Checking if there is any preference set for home dashboard query := m.GetPreferencesQuery{UserId: c.UserId, OrgId: c.OrgId} diff --git a/pkg/api/dtos/prefs.go b/pkg/api/dtos/prefs.go index f66068edccb..77ef0a1da14 100644 --- a/pkg/api/dtos/prefs.go +++ b/pkg/api/dtos/prefs.go @@ -1,6 +1,15 @@ package dtos -type Preferences struct { +type UserPrefs struct { + Theme string `json:"theme"` + ThemeDefault string `json:"themeDefault"` + HomeDashboardId int64 `json:"homeDashboardId"` + HomeDashboardIdDefault int64 `json:"homeDashboardIdDefault"` + Timezone string `json:"timezone"` + TimezoneDefault string `json:"timezoneDefault"` +} + +type UpdateUserPrefsCmd struct { Theme string `json:"theme"` HomeDashboardId int64 `json:"homeDashboardId"` Timezone string `json:"timezone"` diff --git a/pkg/api/preferences.go b/pkg/api/preferences.go index 490da451afc..ed51ddaa9ae 100644 --- a/pkg/api/preferences.go +++ b/pkg/api/preferences.go @@ -1,6 +1,7 @@ package api import ( + "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/middleware" m "github.com/grafana/grafana/pkg/models" @@ -18,3 +19,37 @@ func SetHomeDashboard(c *middleware.Context, cmd m.SavePreferencesCommand) Respo return ApiSuccess("Home dashboard set") } + +// GET /api/user/preferences +func GetUserPreferences(c *middleware.Context) Response { + userPrefs := m.GetPreferencesQuery{UserId: c.UserId, OrgId: c.OrgId} + + if err := bus.Dispatch(&userPrefs); err != nil { + c.JsonApiErr(500, "Failed to get preferences", err) + } + + dto := dtos.UserPrefs{ + Theme: userPrefs.Result.Theme, + HomeDashboardId: userPrefs.Result.HomeDashboardId, + Timezone: userPrefs.Result.Timezone, + } + + return Json(200, &dto) +} + +// PUT /api/user/preferences +func UpdateUserPreferences(c *middleware.Context, dtoCmd dtos.UpdateUserPrefsCmd) Response { + saveCmd := m.SavePreferencesCommand{ + UserId: c.UserId, + OrgId: c.OrgId, + Theme: dtoCmd.Theme, + Timezone: dtoCmd.Timezone, + HomeDashboardId: dtoCmd.HomeDashboardId, + } + + if err := bus.Dispatch(&saveCmd); err != nil { + c.JsonApiErr(500, "Failed to save preferences", err) + } + + return ApiSuccess("User preferences updated") +} diff --git a/pkg/services/sqlstore/preferences.go b/pkg/services/sqlstore/preferences.go index 8882495329f..1b5fa79d879 100644 --- a/pkg/services/sqlstore/preferences.go +++ b/pkg/services/sqlstore/preferences.go @@ -1,9 +1,10 @@ package sqlstore import ( + "time" + "github.com/grafana/grafana/pkg/bus" m "github.com/grafana/grafana/pkg/models" - "time" ) func init() { diff --git a/public/app/core/components/dashboard_selector.ts b/public/app/core/components/dashboard_selector.ts index ada4866f98e..913a43911fa 100644 --- a/public/app/core/components/dashboard_selector.ts +++ b/public/app/core/components/dashboard_selector.ts @@ -6,12 +6,25 @@ import $ from 'jquery'; import coreModule from 'app/core/core_module'; var template = ` + `; export class DashboardSelectorCtrl { + model: any; + options: any; /** @ngInject */ - constructor(private $scope, private $rootScope) { + constructor(private backendSrv) { + } + + $onInit() { + this.options = [{value: 0, text: 'Default'}]; + + return this.backendSrv.search({starred: true}).then(res => { + res.forEach(dash => { + this.options.push({value: dash.id, text: dash.title}); + }); + }); } } @@ -22,6 +35,9 @@ export function dashboardSelector() { bindToController: true, controllerAs: 'ctrl', template: template, + scope: { + model: '=' + } }; } diff --git a/public/app/core/core.ts b/public/app/core/core.ts index 279f54d4e45..abebb5ce560 100644 --- a/public/app/core/core.ts +++ b/public/app/core/core.ts @@ -32,6 +32,7 @@ import {liveSrv} from './live/live_srv'; import {Emitter} from './utils/emitter'; import {layoutSelector} from './components/layout_selector/layout_selector'; import {switchDirective} from './components/switch'; +import {dashboardSelector} from './components/dashboard_selector'; import 'app/core/controllers/all'; import 'app/core/services/all'; import 'app/core/routes/routes'; @@ -54,4 +55,5 @@ export { infoPopover, Emitter, appEvents, + dashboardSelector, }; diff --git a/public/app/core/routes/routes.ts b/public/app/core/routes/routes.ts index 92cf32448a1..ddc0ac06250 100644 --- a/public/app/core/routes/routes.ts +++ b/public/app/core/routes/routes.ts @@ -90,6 +90,7 @@ function setupAngularRoutes($routeProvider, $locationProvider) { .when('/profile', { templateUrl: 'public/app/features/profile/partials/profile.html', controller : 'ProfileCtrl', + controllerAs: 'ctrl', }) .when('/profile/password', { templateUrl: 'public/app/features/profile/partials/password.html', diff --git a/public/app/features/all.js b/public/app/features/all.js index c110bcff7cd..19ca8d7e2c9 100644 --- a/public/app/features/all.js +++ b/public/app/features/all.js @@ -7,7 +7,7 @@ define([ './playlist/all', './snapshot/all', './panel/all', - './profile/profileCtrl', + './profile/profile_ctrl', './profile/changePasswordCtrl', './profile/selectOrgCtrl', './styleguide/styleguide', diff --git a/public/app/features/org/partials/orgDetails.html b/public/app/features/org/partials/orgDetails.html index fe988570e50..b3ba0f73d83 100644 --- a/public/app/features/org/partials/orgDetails.html +++ b/public/app/features/org/partials/orgDetails.html @@ -19,7 +19,6 @@ -