Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
38a10f8b
Commit
38a10f8b
authored
Apr 01, 2016
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
progress
parent
f165ba64
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
189 additions
and
68 deletions
+189
-68
pkg/api/api.go
+2
-0
pkg/api/dashboard.go
+0
-1
pkg/api/dtos/prefs.go
+10
-1
pkg/api/preferences.go
+35
-0
pkg/services/sqlstore/preferences.go
+2
-1
public/app/core/components/dashboard_selector.ts
+17
-1
public/app/core/core.ts
+2
-0
public/app/core/routes/routes.ts
+1
-0
public/app/features/all.js
+1
-1
public/app/features/org/partials/orgDetails.html
+0
-1
public/app/features/profile/partials/profile.html
+31
-9
public/app/features/profile/profileCtrl.js
+0
-51
public/app/features/profile/profile_ctrl.ts
+87
-0
public/vendor/angular/angular.js
+1
-2
No files found.
pkg/api/api.go
View file @
38a10f8b
...
...
@@ -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)
...
...
pkg/api/dashboard.go
View file @
38a10f8b
...
...
@@ -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
}
...
...
pkg/api/dtos/prefs.go
View file @
38a10f8b
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"`
...
...
pkg/api/preferences.go
View file @
38a10f8b
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"
)
}
pkg/services/sqlstore/preferences.go
View file @
38a10f8b
package
sqlstore
import
(
"time"
"github.com/grafana/grafana/pkg/bus"
m
"github.com/grafana/grafana/pkg/models"
"time"
)
func
init
()
{
...
...
public/app/core/components/dashboard_selector.ts
View file @
38a10f8b
...
...
@@ -6,12 +6,25 @@ import $ from 'jquery';
import
coreModule
from
'app/core/core_module'
;
var
template
=
`
<select class="gf-form-input" ng-model="ctrl.model" ng-options="f.value as f.text for f in ctrl.options"></select>
`
;
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
:
'='
}
};
}
...
...
public/app/core/core.ts
View file @
38a10f8b
...
...
@@ -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
,
};
public/app/core/routes/routes.ts
View file @
38a10f8b
...
...
@@ -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'
,
...
...
public/app/features/all.js
View file @
38a10f8b
...
...
@@ -7,7 +7,7 @@ define([
'./playlist/all'
,
'./snapshot/all'
,
'./panel/all'
,
'./profile/profile
C
trl'
,
'./profile/profile
_c
trl'
,
'./profile/changePasswordCtrl'
,
'./profile/selectOrgCtrl'
,
'./styleguide/styleguide'
,
...
...
public/app/features/org/partials/orgDetails.html
View file @
38a10f8b
...
...
@@ -19,7 +19,6 @@
</div>
</form>
<h3
class=
"page-heading"
>
Address
</h3>
<form
name=
"addressForm"
class=
"gf-form-group"
>
...
...
public/app/features/profile/partials/profile.html
View file @
38a10f8b
...
...
@@ -6,35 +6,57 @@
<h1>
Profile
</h1>
</div>
<form
name=
"userForm"
class=
"gf-form-group"
>
<h3
class=
"page-heading"
>
Preferences
</h3>
<form
name=
"
ctrl.
userForm"
class=
"gf-form-group"
>
<h3
class=
"page-heading"
>
Information
</h3>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label width-9"
>
Name
</span>
<input
class=
"gf-form-input max-width-21"
type=
"text"
required
ng-model=
"user.name"
>
<input
class=
"gf-form-input max-width-21"
type=
"text"
required
ng-model=
"
ctrl.
user.name"
>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label width-9"
>
Email
</span>
<input
class=
"gf-form-input max-width-21"
type=
"email"
required
ng-model=
"user.email"
>
<input
class=
"gf-form-input max-width-21"
type=
"email"
required
ng-model=
"
ctrl.
user.email"
>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label width-9"
>
Username
</span>
<input
class=
"gf-form-input max-width-21"
type=
"text"
required
ng-model=
"user.login"
>
<input
class=
"gf-form-input max-width-21"
type=
"text"
required
ng-model=
"ctrl.user.login"
>
</div>
<div
class=
"gf-form-button-row"
>
<button
type=
"submit"
class=
"btn btn-success"
ng-click=
"ctrl.update()"
>
Update
</button>
</div>
</form>
<form
name=
"ctrl.prefsForm"
class=
"gf-form-group"
>
<h3
class=
"page-heading"
>
Preferences
</h3>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label width-9"
>
UI Theme
</span>
<select
class=
"gf-form-input gf-size-auto"
ng-model=
"user.theme"
ng-options=
"f for f in ['dark', 'light']"
></select>
<div
class=
"gf-form-select-wrapper max-width-20"
>
<select
class=
"gf-form-input"
ng-model=
"ctrl.prefs.theme"
ng-options=
"f.value as f.text for f in ctrl.themes"
></select>
</div>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label width-9"
>
Home Dashboard
</span>
<dashboard-selector
model=
"user.homeDashboardId"
></dashboard-selector>
<dashboard-selector
class=
"gf-form-select-wrapper max-width-20"
model=
"ctrl.prefs.homeDashboardId"
>
</dashboard-selector>
</div>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-9"
>
Timezone
</label>
<div
class=
"gf-form-select-wrapper max-width-20"
>
<select
class=
"gf-form-input"
ng-model=
"ctrl.prefs.timezone"
ng-options=
"f.value as f.text for f in ctrl.timezones"
></select>
</div>
</div>
<div
class=
"gf-form-button-row"
>
<button
type=
"submit"
class=
"btn btn-success"
ng-click=
"
update
()"
>
Update
</button>
<button
type=
"submit"
class=
"btn btn-success"
ng-click=
"
ctrl.updatePrefs
()"
>
Update
</button>
</div>
</form>
<h3
class=
"page-heading"
>
Password
</h3>
<div
class=
"gf-form-group"
>
<a
href=
"profile/password"
class=
"btn btn-inverse"
>
Change Password
</a>
...
...
@@ -51,7 +73,7 @@
</tr>
</thead>
<tbody>
<tr
ng-repeat=
"org in orgs"
>
<tr
ng-repeat=
"org in
ctrl.
orgs"
>
<td>
{{org.name}}
</td>
<td>
{{org.role}}
</td>
<td
class=
"text-right"
>
...
...
public/app/features/profile/profileCtrl.js
deleted
100644 → 0
View file @
f165ba64
define
([
'angular'
,
'app/core/config'
,
],
function
(
angular
,
config
)
{
'use strict'
;
var
module
=
angular
.
module
(
'grafana.controllers'
);
module
.
controller
(
'ProfileCtrl'
,
function
(
$scope
,
backendSrv
,
contextSrv
,
$location
)
{
$scope
.
init
=
function
()
{
$scope
.
getUser
();
$scope
.
getUserOrgs
();
};
$scope
.
getUser
=
function
()
{
backendSrv
.
get
(
'/api/user'
).
then
(
function
(
user
)
{
$scope
.
user
=
user
;
$scope
.
user
.
theme
=
user
.
theme
||
'dark'
;
$scope
.
old_theme
=
$scope
.
user
.
theme
;
});
};
$scope
.
getUserOrgs
=
function
()
{
backendSrv
.
get
(
'/api/user/orgs'
).
then
(
function
(
orgs
)
{
$scope
.
orgs
=
orgs
;
});
};
$scope
.
setUsingOrg
=
function
(
org
)
{
backendSrv
.
post
(
'/api/user/using/'
+
org
.
orgId
).
then
(
function
()
{
window
.
location
.
href
=
config
.
appSubUrl
+
'/profile'
;
});
};
$scope
.
update
=
function
()
{
if
(
!
$scope
.
userForm
.
$valid
)
{
return
;
}
backendSrv
.
put
(
'/api/user/'
,
$scope
.
user
).
then
(
function
()
{
contextSrv
.
user
.
name
=
$scope
.
user
.
name
||
$scope
.
user
.
login
;
if
(
$scope
.
old_theme
!==
$scope
.
user
.
theme
)
{
window
.
location
.
href
=
config
.
appSubUrl
+
$location
.
path
();
}
});
};
$scope
.
init
();
});
});
public/app/features/profile/profile_ctrl.ts
0 → 100644
View file @
38a10f8b
///<reference path="../../headers/common.d.ts" />
import
config
from
'app/core/config'
;
import
{
coreModule
}
from
'app/core/core'
;
import
_
from
'lodash'
;
export
class
ProfileCtrl
{
user
:
any
;
old_theme
:
any
;
orgs
:
any
;
prefs
:
any
;
userForm
:
any
;
prefsForm
:
any
;
timezones
:
any
=
[
{
value
:
''
,
text
:
'Default'
},
{
value
:
'browser'
,
text
:
'Local browser time'
},
{
value
:
'utc'
,
text
:
'UTC'
},
];
themes
:
any
=
[
{
value
:
''
,
text
:
'Default'
},
{
value
:
'dark'
,
text
:
'Dark'
},
{
value
:
'light'
,
text
:
'Light'
},
];
/** @ngInject **/
constructor
(
private
$scope
,
private
backendSrv
,
private
contextSrv
,
private
$location
)
{
this
.
getUser
();
this
.
getUserOrgs
();
this
.
getUserPrefs
();
}
getUser
()
{
this
.
backendSrv
.
get
(
'/api/user'
).
then
(
user
=>
{
this
.
user
=
user
;
this
.
user
.
theme
=
user
.
theme
||
'dark'
;
});
}
getUserPrefs
()
{
this
.
backendSrv
.
get
(
'/api/user/preferences'
).
then
(
prefs
=>
{
this
.
prefs
=
prefs
;
this
.
old_theme
=
prefs
.
theme
;
});
}
getUserOrgs
()
{
this
.
backendSrv
.
get
(
'/api/user/orgs'
).
then
(
orgs
=>
{
this
.
orgs
=
orgs
;
});
}
setUsingOrg
(
org
)
{
this
.
backendSrv
.
post
(
'/api/user/using/'
+
org
.
orgId
).
then
(()
=>
{
window
.
location
.
href
=
config
.
appSubUrl
+
'/profile'
;
});
}
update
()
{
if
(
!
this
.
userForm
.
$valid
)
{
return
;
}
this
.
backendSrv
.
put
(
'/api/user/'
,
this
.
user
).
then
(()
=>
{
this
.
contextSrv
.
user
.
name
=
this
.
user
.
name
||
this
.
user
.
login
;
if
(
this
.
old_theme
!==
this
.
user
.
theme
)
{
window
.
location
.
href
=
config
.
appSubUrl
+
this
.
$location
.
path
();
}
});
}
updatePrefs
()
{
if
(
!
this
.
prefsForm
.
$valid
)
{
return
;
}
var
cmd
=
{
theme
:
this
.
prefs
.
theme
,
timezone
:
this
.
prefs
.
timezone
,
homeDashboardId
:
this
.
prefs
.
homeDashboardId
};
this
.
backendSrv
.
put
(
'/api/user/preferences'
,
cmd
).
then
(()
=>
{
if
(
this
.
old_theme
!==
cmd
.
theme
)
{
window
.
location
.
href
=
config
.
appSubUrl
+
this
.
$location
.
path
();
}
});
}
}
coreModule
.
controller
(
'ProfileCtrl'
,
ProfileCtrl
);
public/vendor/angular/angular.js
View file @
38a10f8b
...
...
@@ -30711,4 +30711,4 @@ $provide.value("$locale", {
})(
window
,
document
);
!
window
.
angular
.
$$csp
().
noInlineStyle
&&
window
.
angular
.
element
(
document
.
head
).
prepend
(
'<style type="text/css">@charset "UTF-8";[ng
\\
:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng
\\
:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>'
);
\ No newline at end of file
!
window
.
angular
.
$$csp
().
noInlineStyle
&&
window
.
angular
.
element
(
document
.
head
).
prepend
(
'<style type="text/css">@charset "UTF-8";[ng
\\
:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng
\\
:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>'
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment