Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Filter by Role to user search #1278

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from
18 changes: 15 additions & 3 deletions api/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"net/http"
"regexp"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -125,16 +126,27 @@ func (r usersRoutes) updateUser(c *gin.Context) {

func (r usersRoutes) prepareUserSearch(c *gin.Context) (users []model.User, err error) {
q := c.Query("q")
reg, _ := regexp.Compile("[^a-zA-Z0-9 ]+")
rQ := c.Query("r")
reg := regexp.MustCompile("[^a-zA-Z0-9 ]+")
q = reg.ReplaceAllString(q, "")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all of these variable names are hard to understand without context. Also why are we only enforcing the regex on one of the two paramters? Does rQ not need to be checked for validity?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edited the PR, PTAL if you think thats better (otherwise revert my commit please).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also why are we only enforcing the regex on one of the two paramters? Does rQ not need to be checked for validity?

Probably hard to immediately understand and therefore bad code, but it's checked before it's used:

gocast/api/users.go

Lines 143 to 144 in 6d0c3cc

role, err := strconv.ParseUint(roleQuery, 10, 64)
if err != nil {

if len(q) < 3 {
// make the search work with empty query but selected role
if len(q) < 3 && (rQ == "-1" || rQ == "") {
_ = c.Error(tools.RequestError{
Status: http.StatusBadRequest,
CustomMessage: "query too short (minimum length is 3)",
})
return nil, errors.New("query too short (minimum length is 3)")
}
users, err = r.UsersDao.SearchUser(q)
role, err := strconv.ParseUint(rQ, 10, 64)
karjo24 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil && rQ != "" && rQ != "-1" {
tools.RenderErrorPage(c, http.StatusBadRequest, "invalid role")
karjo24 marked this conversation as resolved.
Show resolved Hide resolved
return nil, err
}
if rQ == "" || rQ == "-1" {
users, err = r.UsersDao.SearchUser(q)
} else {
users, err = r.UsersDao.SearchUserWithRole(q, role)
}
if err != nil && err != gorm.ErrRecordNotFound {
_ = c.Error(tools.RequestError{
Status: http.StatusInternalServerError,
Expand Down
7 changes: 7 additions & 0 deletions dao/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type UsersDao interface {
CreateUser(ctx context.Context, user *model.User) (err error)
DeleteUser(ctx context.Context, uid uint) (err error)
SearchUser(query string) (users []model.User, err error)
SearchUserWithRole(query string, role uint64) (users []model.User, err error)
IsUserAdmin(ctx context.Context, uid uint) (res bool, err error)
GetUserByEmail(ctx context.Context, email string) (user model.User, err error)
GetAllAdminsAndLecturers(users *[]model.User) (err error)
Expand Down Expand Up @@ -69,6 +70,12 @@ func (d usersDao) SearchUser(query string) (users []model.User, err error) {
return users, res.Error
}

func (d usersDao) SearchUserWithRole(query string, role uint64) (users []model.User, err error) {
q := "%" + query + "%"
res := DB.Where("role = ? AND (UPPER(lrz_id) LIKE UPPER(?) OR UPPER(email) LIKE UPPER(?) OR UPPER(name) LIKE UPPER(?))", role, q, q, q).Limit(10).Preload("Settings").Find(&users)
return users, res.Error
}

func (d usersDao) IsUserAdmin(ctx context.Context, uid uint) (res bool, err error) {
var user model.User
err = DB.Find(&user, "id = ?", uid).Error
Expand Down
17 changes: 16 additions & 1 deletion mock_dao/users.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions web/template/admin/admin_tabs/users.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
<h2>Search</h2>
<input class="tl-input" placeholder="Search for users" type="text" x-model="userlist.searchInput"
@keyup="userlist.search()">
<div class="bg-transparent text-gray-800 dark:text-gray-200">
<label for="role">Role:</label>
<select id="role" class="bg-transparent dark:text-gray-300 text-gray-800" x-model="userlist.roles" @change="userlist.search()">
<option value="-1">All</option>
<option value="1">Admin</option>
<option value="2">Lecturer</option>
<option value="4">Student</option>
</select>
</div>
<div class="w-4 m-auto">
<i class="fas fa-circle-notch text-4 m-auto animate-spin" x-show="userlist.searchLoading"></i>
</div>
Expand Down
10 changes: 6 additions & 4 deletions web/ts/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,27 @@ export class AdminUserList {
showSearchResults: boolean;
searchLoading: boolean;
searchInput: string;
roles: number;

constructor(usersAsJson: object[]) {
this.list = usersAsJson;
this.rowsPerPage = 10;
this.showSearchResults = false;
this.currentIndex = 0;
this.searchInput = "";
this.roles = -1;
this.numberOfPages = Math.ceil(this.list.length / this.rowsPerPage);
this.updateVisibleRows();
}

async search() {
if (this.searchInput.length < 3) {
if (this.searchInput.length < 3 && this.roles == -1) {
this.showSearchResults = false;
this.updateVisibleRows();
return;
}
if (this.searchInput.length > 2) {
} else {
this.searchLoading = true;
fetch("/api/searchUser?q=" + this.searchInput)
fetch("/api/searchUser?q=" + this.searchInput + "&r=" + this.roles)
.then((response) => {
this.searchLoading = false;
if (!response.ok) {
Expand Down
Loading