瀏覽代碼

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.
Daniel Lee 8 年之前
父節點
當前提交
9efb6e76e9

+ 3 - 1
pkg/api/user.go

@@ -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
 	}

+ 11 - 2
pkg/services/sqlstore/user.go

@@ -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
 }

+ 49 - 1
pkg/services/sqlstore/user_test.go

@@ -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)
+		})
 	})
 }

+ 4 - 2
public/app/features/admin/admin_list_users_ctrl.ts

@@ -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;

+ 6 - 0
public/app/features/admin/partials/users.html

@@ -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>