Commit a0bb5886 by Torkel Ödegaard

Merge branch 'develop' into develop-newgrid-row-panels

parents 55c6b4b9 dc249cf9
...@@ -235,13 +235,20 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { ...@@ -235,13 +235,20 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
}, },
}, },
{ {
Text: "Users", Text: "Members",
Id: "users", Id: "users",
Description: "Manage users & user groups", Description: "Manage org members",
Icon: "fa fa-fw fa-users", Icon: "icon-gf icon-gf-users",
Url: setting.AppSubUrl + "/org/users", Url: setting.AppSubUrl + "/org/users",
}, },
{ {
Text: "Groups",
Id: "users",
Description: "Manage org groups",
Icon: "fa fa-fw fa-users",
Url: setting.AppSubUrl + "/org/user-groups",
},
{
Text: "API Keys", Text: "API Keys",
Id: "apikeys", Id: "apikeys",
Description: "Create & manage API keys", Description: "Create & manage API keys",
......
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"
...@@ -247,6 +248,10 @@ func searchUser(c *middleware.Context) (*m.SearchUsersQuery, error) { ...@@ -247,6 +248,10 @@ func searchUser(c *middleware.Context) (*m.SearchUsersQuery, error) {
return nil, err return nil, err
} }
for _, user := range query.Result.Users {
user.AvatarUrl = dtos.GetGravatarUrl(user.Email)
}
query.Result.Page = page query.Result.Page = page
query.Result.PerPage = perPage query.Result.PerPage = perPage
......
...@@ -197,6 +197,7 @@ type UserSearchHitDTO struct { ...@@ -197,6 +197,7 @@ type UserSearchHitDTO struct {
Name string `json:"name"` Name string `json:"name"`
Login string `json:"login"` Login string `json:"login"`
Email string `json:"email"` Email string `json:"email"`
AvatarUrl string `json:"avatarUrl"`
IsAdmin bool `json:"isAdmin"` IsAdmin bool `json:"isAdmin"`
LastSeenAt time.Time `json:"lastSeenAt"` LastSeenAt time.Time `json:"lastSeenAt"`
LastSeenAtAge string `json:"lastSeenAtAge"` LastSeenAtAge string `json:"lastSeenAtAge"`
......
...@@ -21,8 +21,7 @@ ...@@ -21,8 +21,7 @@
<table class="filter-table form-inline"> <table class="filter-table form-inline">
<thead> <thead>
<tr> <tr>
<th>Id</th> <th></th>
<th>Name</th>
<th>Login</th> <th>Login</th>
<th>Email</th> <th>Email</th>
<th> <th>
...@@ -35,8 +34,9 @@ ...@@ -35,8 +34,9 @@
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="user in ctrl.users"> <tr ng-repeat="user in ctrl.users">
<td>{{user.id}}</td> <td class="width-4 text-center">
<td>{{user.name}}</td> <img class="filter-table__avatar" ng-src="{{user.avatarUrl}}"></img>
</td>
<td>{{user.login}}</td> <td>{{user.login}}</td>
<td>{{user.email}}</td> <td>{{user.email}}</td>
<td> <td>
......
...@@ -2,20 +2,18 @@ ...@@ -2,20 +2,18 @@
<div class="page-container"> <div class="page-container">
<div class="page-header"> <div class="page-header">
<h1> <page-h1 model="ctrl.navModel"></page-h1>
<i class="{{ctrl.navModel.node.icon}}"></i>
{{ctrl.navModel.node.text}} <button class="btn btn-success" ng-click="ctrl.openAddUsersView()" ng-hide="ctrl.externalUserMngLinkUrl">
</h1> <i class="fa fa-plus"></i>
<span>{{ctrl.addUsersBtnName}}</span>
</button>
<div class="page-header-tabs"> <div class="page-header-tabs">
<button class="btn btn-success" ng-click="ctrl.openAddUsersView()" ng-hide="ctrl.externalUserMngLinkUrl">
<i class="fa fa-plus"></i>
<span>{{ctrl.addUsersBtnName}}</span>
</button>
<a class="btn btn-inverse" ng-href="{{ctrl.externalUserMngLinkUrl}}" target="_blank" ng-if="ctrl.externalUserMngLinkUrl"> <a class="btn btn-inverse" ng-href="{{ctrl.externalUserMngLinkUrl}}" target="_blank" ng-if="ctrl.externalUserMngLinkUrl">
<i class="fa fa-external-link-square"></i> <i class="fa fa-external-link-square"></i>
{{ctrl.addUsersBtnName}} {{ctrl.addUsersBtnName}}
</a> </a>
<ul class="gf-tabs"> <ul class="gf-tabs">
...@@ -24,13 +22,8 @@ ...@@ -24,13 +22,8 @@
Users ({{ctrl.users.length}}) Users ({{ctrl.users.length}})
</a> </a>
</li> </li>
<li class="gf-tabs-item">
<a class="gf-tabs-link" ng-click="ctrl.editor.index = 1" ng-class="{active: ctrl.editor.index === 1}">
Groups (0)
</a>
</li>
<li class="gf-tabs-item" ng-show="ctrl.pendingInvites.length"> <li class="gf-tabs-item" ng-show="ctrl.pendingInvites.length">
<a class="gf-tabs-link" ng-click="ctrl.editor.index = 2" ng-class="{active: ctrl.editor.index === 2}"> <a class="gf-tabs-link" ng-click="ctrl.editor.index = 1" ng-class="{active: ctrl.editor.index === 1}">
Pending Invitations ({{ctrl.pendingInvites.length}}) Pending Invitations ({{ctrl.pendingInvites.length}})
</a> </a>
</li> </li>
...@@ -79,7 +72,7 @@ ...@@ -79,7 +72,7 @@
</table> </table>
</div> </div>
<div ng-if="ctrl.editor.index === 2"> <div ng-if="ctrl.editor.index === 1">
<table class="filter-table form-inline"> <table class="filter-table form-inline">
<thead> <thead>
<tr> <tr>
......
...@@ -19,7 +19,8 @@ var backendSrv = { ...@@ -19,7 +19,8 @@ var backendSrv = {
ctx.ctrl = $controller(UserGroupDetailsCtrl, { ctx.ctrl = $controller(UserGroupDetailsCtrl, {
$scope: ctx.scope, $scope: ctx.scope,
backendSrv: backendSrv, backendSrv: backendSrv,
$routeParams: {id: 1} $routeParams: {id: 1},
navModelSrv: {getNav: sinon.stub()}
}); });
})); }));
......
...@@ -6,7 +6,9 @@ describe('PlaylistEditCtrl', () => { ...@@ -6,7 +6,9 @@ describe('PlaylistEditCtrl', () => {
var ctx: any; var ctx: any;
beforeEach(() => { beforeEach(() => {
let navModelSrv = { let navModelSrv = {
getPlaylistsNav: page => {}, getNav: () => {
return { breadcrumbs: [], node: {}};
},
}; };
ctx = new PlaylistEditCtrl(null, null, null, null, { current: { params: {} } }, navModelSrv); ctx = new PlaylistEditCtrl(null, null, null, null, { current: { params: {} } }, navModelSrv);
......
$gf-form-margin: 0.1rem; $gf-form-margin: 1px;
.gf-form { .gf-form {
margin-bottom: $gf-form-margin; margin-bottom: $gf-form-margin;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
baseURL: '/base/', baseURL: '/base/',
defaultJSExtensions: true, defaultJSExtensions: true,
paths: { paths: {
'gemini-scrollbar': 'vendor/npm/gemini-scrollbar/index.js',
'mousetrap': 'vendor/npm/mousetrap/mousetrap.js', 'mousetrap': 'vendor/npm/mousetrap/mousetrap.js',
'eventemitter3': 'vendor/npm/eventemitter3/index.js', 'eventemitter3': 'vendor/npm/eventemitter3/index.js',
'remarkable': 'vendor/npm/remarkable/dist/remarkable.js', 'remarkable': 'vendor/npm/remarkable/dist/remarkable.js',
......
...@@ -24,6 +24,7 @@ module.exports = function(config, grunt) { ...@@ -24,6 +24,7 @@ module.exports = function(config, grunt) {
gaze([ gaze([
config.srcDir + '/sass/**/*', config.srcDir + '/sass/**/*',
config.srcDir + '/app/**/*', config.srcDir + '/app/**/*',
config.srcDir + '/test/**/*',
config.srcDir + '/vendor/npm/gemini-scrollbar/*.js', config.srcDir + '/vendor/npm/gemini-scrollbar/*.js',
], function(err, watcher) { ], function(err, watcher) {
......
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