mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
users: adds search and pagination (#7753)
ref #7469. Follow up change that adds proper paging with 50 results per page as well as a search box to search by name, login or email.
This commit is contained in:
parent
8e3f22d307
commit
9efb6e76e9
@ -239,7 +239,9 @@ func searchUser(c *middleware.Context) (*m.SearchUsersQuery, error) {
|
||||
page = 1
|
||||
}
|
||||
|
||||
query := &m.SearchUsersQuery{Query: "", Page: page, Limit: perPage}
|
||||
searchQuery := c.Query("query")
|
||||
|
||||
query := &m.SearchUsersQuery{Query: searchQuery, Page: page, Limit: perPage}
|
||||
if err := bus.Dispatch(query); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -363,8 +363,12 @@ func SearchUsers(query *m.SearchUsersQuery) error {
|
||||
query.Result = m.SearchUserQueryResult{
|
||||
Users: make([]*m.UserSearchHitDTO, 0),
|
||||
}
|
||||
queryWithWildcards := "%" + query.Query + "%"
|
||||
|
||||
sess := x.Table("user")
|
||||
sess.Where("email LIKE ?", query.Query+"%")
|
||||
if query.Query != "" {
|
||||
sess.Where("email LIKE ? OR name LIKE ? OR login like ?", queryWithWildcards, queryWithWildcards, queryWithWildcards)
|
||||
}
|
||||
offset := query.Limit * (query.Page - 1)
|
||||
sess.Limit(query.Limit, offset)
|
||||
sess.Cols("id", "email", "name", "login", "is_admin")
|
||||
@ -373,7 +377,12 @@ func SearchUsers(query *m.SearchUsersQuery) error {
|
||||
}
|
||||
|
||||
user := m.User{}
|
||||
count, err := x.Count(&user)
|
||||
|
||||
countSess := x.Table("user")
|
||||
if query.Query != "" {
|
||||
countSess.Where("email LIKE ? OR name LIKE ? OR login like ?", queryWithWildcards, queryWithWildcards, queryWithWildcards)
|
||||
}
|
||||
count, err := countSess.Count(&user)
|
||||
query.Result.TotalCount = count
|
||||
return err
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
err = CreateUser(&models.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
Name: fmt.Sprint("user", i),
|
||||
Login: fmt.Sprint("user", i),
|
||||
Login: fmt.Sprint("loginuser", i),
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
}
|
||||
@ -41,5 +41,53 @@ func TestUserDataAccess(t *testing.T) {
|
||||
So(len(query.Result.Users), ShouldEqual, 2)
|
||||
So(query.Result.TotalCount, ShouldEqual, 5)
|
||||
})
|
||||
|
||||
Convey("Can return list of users matching query on user name", func() {
|
||||
query := models.SearchUsersQuery{Query: "use", Page: 1, Limit: 3}
|
||||
err = SearchUsers(&query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result.Users), ShouldEqual, 3)
|
||||
So(query.Result.TotalCount, ShouldEqual, 5)
|
||||
|
||||
query = models.SearchUsersQuery{Query: "ser1", Page: 1, Limit: 3}
|
||||
err = SearchUsers(&query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result.Users), ShouldEqual, 1)
|
||||
So(query.Result.TotalCount, ShouldEqual, 1)
|
||||
|
||||
query = models.SearchUsersQuery{Query: "USER1", Page: 1, Limit: 3}
|
||||
err = SearchUsers(&query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result.Users), ShouldEqual, 1)
|
||||
So(query.Result.TotalCount, ShouldEqual, 1)
|
||||
|
||||
query = models.SearchUsersQuery{Query: "idontexist", Page: 1, Limit: 3}
|
||||
err = SearchUsers(&query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result.Users), ShouldEqual, 0)
|
||||
So(query.Result.TotalCount, ShouldEqual, 0)
|
||||
})
|
||||
|
||||
Convey("Can return list of users matching query on email", func() {
|
||||
query := models.SearchUsersQuery{Query: "ser1@test.com", Page: 1, Limit: 3}
|
||||
err = SearchUsers(&query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result.Users), ShouldEqual, 1)
|
||||
So(query.Result.TotalCount, ShouldEqual, 1)
|
||||
})
|
||||
|
||||
Convey("Can return list of users matching query on login name", func() {
|
||||
query := models.SearchUsersQuery{Query: "loginuser1", Page: 1, Limit: 3}
|
||||
err = SearchUsers(&query)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result.Users), ShouldEqual, 1)
|
||||
So(query.Result.TotalCount, ShouldEqual, 1)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -3,18 +3,20 @@
|
||||
export default class AdminListUsersCtrl {
|
||||
users: any;
|
||||
pages = [];
|
||||
perPage = 1000;
|
||||
perPage = 50;
|
||||
page = 1;
|
||||
totalPages: number;
|
||||
showPaging = false;
|
||||
query: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private backendSrv) {
|
||||
this.query = '';
|
||||
this.getUsers();
|
||||
}
|
||||
|
||||
getUsers() {
|
||||
this.backendSrv.get(`/api/users/search?perpage=${this.perPage}&page=${this.page}`).then((result) => {
|
||||
this.backendSrv.get(`/api/users/search?perpage=${this.perPage}&page=${this.page}&query=${this.query}`).then((result) => {
|
||||
this.users = result.users;
|
||||
this.page = result.page;
|
||||
this.perPage = result.perPage;
|
||||
|
@ -14,6 +14,12 @@
|
||||
Add new user
|
||||
</a>
|
||||
</div>
|
||||
<div class="search-field-wrapper pull-right width-18">
|
||||
<span style="position: relative;">
|
||||
<input type="text" placeholder="Find user by name/login/email" tabindex="1" give-focus="true"
|
||||
ng-model="ctrl.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.getUsers()" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="admin-list-table">
|
||||
<table class="filter-table form-inline">
|
||||
<thead>
|
||||
|
Loading…
Reference in New Issue
Block a user