user manager: search by group
UserStore: modify SearchOffset method signature modify CountSearch method signature phrases: add panel_users_search_group add panel_users_search_group_none add panel_users_search_title add missing paginator_mod template x.x eliminate bytes here and there
This commit is contained in:
parent
0bf1b6dbd3
commit
f69e077347
|
@ -614,10 +614,14 @@ type PanelMenuItemPage struct {
|
||||||
type PanelUserPageSearch struct {
|
type PanelUserPageSearch struct {
|
||||||
Name string
|
Name string
|
||||||
Email string
|
Email string
|
||||||
|
Group int
|
||||||
|
|
||||||
|
Any bool
|
||||||
}
|
}
|
||||||
type PanelUserPage struct {
|
type PanelUserPage struct {
|
||||||
*BasePanelPage
|
*BasePanelPage
|
||||||
ItemList []*User
|
ItemList []*User
|
||||||
|
Groups []*Group
|
||||||
Search PanelUserPageSearch
|
Search PanelUserPageSearch
|
||||||
PaginatorMod
|
PaginatorMod
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ type UserStore interface {
|
||||||
Getn(id int) *User
|
Getn(id int) *User
|
||||||
GetByName(name string) (*User, error)
|
GetByName(name string) (*User, error)
|
||||||
Exists(id int) bool
|
Exists(id int) bool
|
||||||
SearchOffset(name, email string, offset, perPage int) (users []*User, err error)
|
SearchOffset(name, email string, gid, offset, perPage int) (users []*User, err error)
|
||||||
GetOffset(offset, perPage int) ([]*User, error)
|
GetOffset(offset, perPage int) ([]*User, error)
|
||||||
Each(f func(*User) error) error
|
Each(f func(*User) error) error
|
||||||
//BulkGet(ids []int) ([]*User, error)
|
//BulkGet(ids []int) ([]*User, error)
|
||||||
|
@ -30,7 +30,7 @@ type UserStore interface {
|
||||||
Create(name, password, email string, group int, active bool) (int, error)
|
Create(name, password, email string, group int, active bool) (int, error)
|
||||||
Reload(id int) error
|
Reload(id int) error
|
||||||
Count() int
|
Count() int
|
||||||
CountSearch(name, email string) int
|
CountSearch(name, email string, gid int) int
|
||||||
|
|
||||||
SetCache(cache UserCache)
|
SetCache(cache UserCache)
|
||||||
GetCache() UserCache
|
GetCache() UserCache
|
||||||
|
@ -66,7 +66,7 @@ func NewDefaultUserStore(cache UserCache) (*DefaultUserStore, error) {
|
||||||
|
|
||||||
get: acc.Select(u).Columns("name,group,active,is_super_admin,session,email,avatar,message,level,score,posts,liked,last_ip,temp_group,createdAt,enable_embeds,profile_comments,who_can_convo").Where("uid=?").Prepare(),
|
get: acc.Select(u).Columns("name,group,active,is_super_admin,session,email,avatar,message,level,score,posts,liked,last_ip,temp_group,createdAt,enable_embeds,profile_comments,who_can_convo").Where("uid=?").Prepare(),
|
||||||
getByName: acc.Select(u).Columns(allCols).Where("name=?").Prepare(),
|
getByName: acc.Select(u).Columns(allCols).Where("name=?").Prepare(),
|
||||||
searchOffset: acc.Select(u).Columns(allCols).Where("(name=? OR ?='') AND (email=? OR ?='')").Orderby("uid ASC").Limit("?,?").Prepare(),
|
searchOffset: acc.Select(u).Columns(allCols).Where("(name=? OR ?='') AND (email=? OR ?='') AND (group=? OR ?='')").Orderby("uid ASC").Limit("?,?").Prepare(),
|
||||||
getOffset: acc.Select(u).Columns(allCols).Orderby("uid ASC").Limit("?,?").Prepare(),
|
getOffset: acc.Select(u).Columns(allCols).Orderby("uid ASC").Limit("?,?").Prepare(),
|
||||||
getAll: acc.Select(u).Columns(allCols).Prepare(),
|
getAll: acc.Select(u).Columns(allCols).Prepare(),
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ func NewDefaultUserStore(cache UserCache) (*DefaultUserStore, error) {
|
||||||
nameExists: acc.Exists(u, "name").Prepare(),
|
nameExists: acc.Exists(u, "name").Prepare(),
|
||||||
|
|
||||||
count: acc.Count(u).Prepare(),
|
count: acc.Count(u).Prepare(),
|
||||||
countSearch: acc.Count(u).Where("(name=? OR ?='') AND (email=? OR ?='')").Prepare(),
|
countSearch: acc.Count(u).Where("(name=? OR ?='') AND (email=? OR ?='') AND (group=? OR ?='')").Prepare(),
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,8 +180,8 @@ func (s *DefaultUserStore) GetOffset(offset, perPage int) (users []*User, err er
|
||||||
}
|
}
|
||||||
return users, rows.Err()
|
return users, rows.Err()
|
||||||
}
|
}
|
||||||
func (s *DefaultUserStore) SearchOffset(name, email string, offset, perPage int) (users []*User, err error) {
|
func (s *DefaultUserStore) SearchOffset(name, email string, gid, offset, perPage int) (users []*User, err error) {
|
||||||
rows, err := s.searchOffset.Query(name, name, email, email, offset, perPage)
|
rows, err := s.searchOffset.Query(name, name, email, email, gid, gid, offset, perPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return users, err
|
return users, err
|
||||||
}
|
}
|
||||||
|
@ -384,8 +384,8 @@ func (s *DefaultUserStore) Count() (count int) {
|
||||||
return Countf(s.count)
|
return Countf(s.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultUserStore) CountSearch(name, email string) (count int) {
|
func (s *DefaultUserStore) CountSearch(name, email string, gid int) (count int) {
|
||||||
return Countf(s.countSearch, name, name, email, email)
|
return Countf(s.countSearch, name, name, email, email, gid, gid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultUserStore) SetCache(cache UserCache) {
|
func (s *DefaultUserStore) SetCache(cache UserCache) {
|
||||||
|
|
|
@ -900,7 +900,10 @@
|
||||||
"panel_users_search_name_placeholder":"John Doe",
|
"panel_users_search_name_placeholder":"John Doe",
|
||||||
"panel_users_search_email":"Email",
|
"panel_users_search_email":"Email",
|
||||||
"panel_users_search_email_placeholder":"john.doe@example.com",
|
"panel_users_search_email_placeholder":"john.doe@example.com",
|
||||||
|
"panel_users_search_group":"Group",
|
||||||
|
"panel_users_search_group_none":"None",
|
||||||
"panel_users_search_button":"Search",
|
"panel_users_search_button":"Search",
|
||||||
|
"panel_users_search_title":"Search Users",
|
||||||
|
|
||||||
"panel_user_head":"User Editor",
|
"panel_user_head":"User Editor",
|
||||||
"panel_user_avatar":"Avatar",
|
"panel_user_avatar":"Avatar",
|
||||||
|
|
|
@ -21,20 +21,38 @@ func Users(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
if !u.Perms.EditUserEmail && email != "" {
|
if !u.Perms.EditUserEmail && email != "" {
|
||||||
return c.LocalError("Only users with the EditUserEmail permission can search by email.", w, r, u)
|
return c.LocalError("Only users with the EditUserEmail permission can search by email.", w, r, u)
|
||||||
}
|
}
|
||||||
hasParam := name != "" || email != ""
|
group := r.FormValue("s-group")
|
||||||
|
f := func(l ...string) bool {
|
||||||
|
for _, ll := range l {
|
||||||
|
if ll != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
hasParam := f(name, email, group)
|
||||||
|
gid, _ := strconv.Atoi(group)
|
||||||
|
/*if group == "" {
|
||||||
|
gid = -1
|
||||||
|
}*/
|
||||||
|
hasParam = hasParam && gid > 0
|
||||||
|
|
||||||
page, _ := strconv.Atoi(r.FormValue("page"))
|
page, _ := strconv.Atoi(r.FormValue("page"))
|
||||||
perPage := 15
|
perPage := 15
|
||||||
userCount := basePage.Stats.Users
|
userCount := basePage.Stats.Users
|
||||||
if hasParam {
|
if hasParam {
|
||||||
userCount = c.Users.CountSearch(name, email)
|
userCount = c.Users.CountSearch(name, email, gid)
|
||||||
}
|
}
|
||||||
offset, page, lastPage := c.PageOffset(userCount, page, perPage)
|
offset, page, lastPage := c.PageOffset(userCount, page, perPage)
|
||||||
|
|
||||||
|
allGroups, e := c.Groups.GetAll()
|
||||||
|
if e != nil {
|
||||||
|
return c.InternalError(e, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
var users []*c.User
|
var users []*c.User
|
||||||
var e error
|
|
||||||
if hasParam {
|
if hasParam {
|
||||||
users, e = c.Users.SearchOffset(name, email, offset, perPage)
|
users, e = c.Users.SearchOffset(name, email, gid, offset, perPage)
|
||||||
} else {
|
} else {
|
||||||
users, e = c.Users.GetOffset(offset, perPage)
|
users, e = c.Users.GetOffset(offset, perPage)
|
||||||
}
|
}
|
||||||
|
@ -44,7 +62,7 @@ func Users(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
|
|
||||||
name = url.QueryEscape(name)
|
name = url.QueryEscape(name)
|
||||||
email = url.QueryEscape(email)
|
email = url.QueryEscape(email)
|
||||||
search := c.PanelUserPageSearch{name, email}
|
search := c.PanelUserPageSearch{name, email, gid, hasParam}
|
||||||
|
|
||||||
var params string
|
var params string
|
||||||
if hasParam {
|
if hasParam {
|
||||||
|
@ -56,7 +74,7 @@ func Users(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pageList := c.Paginate(page, lastPage, 5)
|
pageList := c.Paginate(page, lastPage, 5)
|
||||||
pi := c.PanelUserPage{basePage, users, search, c.PaginatorMod{template.URL(params), pageList, page, lastPage}}
|
pi := c.PanelUserPage{basePage, users, allGroups, search, c.PaginatorMod{template.URL(params), pageList, page, lastPage}}
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_users", &pi})
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_users", &pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="rowblock">
|
<div class="rowblock">
|
||||||
{{range .GuildList}}<div class="rowitem datarow">
|
{{range .GuildList}}<div class="rowitem datarow">
|
||||||
<span style="float:left;">
|
<span style="float:left;">
|
||||||
<a href="{{.Link}}" style="">{{.Name}}</a>
|
<a href="{{.Link}}"style="">{{.Name}}</a>
|
||||||
<br><span class="rowsmall">{{.Desc}}</span>
|
<br><span class="rowsmall">{{.Desc}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span style="float:right;">
|
<span style="float:right;">
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
{{if gt .LastPage 1}}
|
||||||
|
<div class="pageset">
|
||||||
|
{{if gt .Page 1}}<div class="pageitem pagefirst"><a href="?{{.Params}}page=1"aria-label="{{lang "paginator.first_page_aria"}}">{{lang "paginator.first_page"}}</a></div>
|
||||||
|
<div class="pageitem pageprev"><a href="?{{.Params}}page={{subtract .Page 1}}"rel="prev"aria-label="{{lang "paginator.prev_page_aria"}}">{{lang "paginator.prev_page"}}</a></div>
|
||||||
|
<link rel="prev"href="?{{.Params}}page={{subtract .Page 1}}">{{end}}
|
||||||
|
{{range .PageList}}
|
||||||
|
<div class="pageitem{{if eq . $.Page}} pagecurrent{{end}}"><a href="?{{$.Params}}page={{.}}">{{.}}</a></div>
|
||||||
|
{{end}}
|
||||||
|
{{if ne .LastPage .Page}}
|
||||||
|
<link rel="next"href="?{{.Params}}page={{add .Page 1}}">
|
||||||
|
<div class="pageitem pagenext"><a href="?{{.Params}}page={{add .Page 1}}"rel="next"aria-label="{{lang "paginator.next_page_aria"}}">{{lang "paginator.next_page"}}</a></div>
|
||||||
|
<div class="pageitem pagelast"><a href="?{{.Params}}page={{.LastPage}}"aria-label="{{lang "paginator.last_page_aria"}}">{{lang "paginator.last_page"}}</a></div>{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
|
@ -10,7 +10,7 @@
|
||||||
<div class="formitem avataritem">
|
<div class="formitem avataritem">
|
||||||
{{if .User.RawAvatar}}<img src="{{.User.Avatar}}"height=56 width=56>{{end}}
|
{{if .User.RawAvatar}}<img src="{{.User.Avatar}}"height=56 width=56>{{end}}
|
||||||
<div class="avatarbuttons">
|
<div class="avatarbuttons">
|
||||||
<input form="avatar_form"id="select_avatar"name="avatar_file"type="file" required class="auto_hide">
|
<input form="avatar_form"id="select_avatar"name="avatar_file"type="file"required class="auto_hide">
|
||||||
<label for="select_avatar"class="formbutton">{{lang "panel_user_avatar_select"}}</label>
|
<label for="select_avatar"class="formbutton">{{lang "panel_user_avatar_select"}}</label>
|
||||||
<button form="avatar_form"name="avatar_action"value=0>{{lang "panel_user_avatar_upload"}}</button>
|
<button form="avatar_form"name="avatar_action"value=0>{{lang "panel_user_avatar_upload"}}</button>
|
||||||
{{if .User.RawAvatar}}<button form="remove_avatar_form"name="avatar_action"value=1>{{lang "panel_user_avatar_remove"}}</button>{{end}}
|
{{if .User.RawAvatar}}<button form="remove_avatar_form"name="avatar_action"value=1>{{lang "panel_user_avatar_remove"}}</button>{{end}}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_users_head"}}</h1></div>
|
<div class="rowitem"><h1>{{if .Search.Any}}{{lang "panel_users_search_title"}}{{else}}{{lang "panel_users_head"}}{{end}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_users"class="colstack_item rowlist bgavatars">
|
<div id="panel_users"class="colstack_item rowlist bgavatars">
|
||||||
{{range .ItemList}}
|
{{range .ItemList}}
|
||||||
|
@ -32,6 +32,14 @@
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_users_search_email"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_users_search_email"}}</a></div>
|
||||||
<div class="formitem"><input name="s-email"type="email"{{if .Search.Email}}value="{{.Search.Email}}"{{end}}placeholder="{{lang "panel_users_search_email_placeholder"}}"></div>
|
<div class="formitem"><input name="s-email"type="email"{{if .Search.Email}}value="{{.Search.Email}}"{{end}}placeholder="{{lang "panel_users_search_email_placeholder"}}"></div>
|
||||||
</div>{{end}}
|
</div>{{end}}
|
||||||
|
{{if .CurrentUser.Perms.EditUserGroup}}<div class="formrow">
|
||||||
|
<div class="formitem formlabel"><a>{{lang "panel_users_search_group"}}</a></div>
|
||||||
|
<div class="formitem"><select name="s-group">
|
||||||
|
<option value="0"{{if eq $.Search.Group 0}}selected{{end}}>{{lang "panel_users_search_group_none"}}</option>
|
||||||
|
{{range .Groups}}{{if ne .ID 0}}
|
||||||
|
<option value="{{.ID}}"{{if eq $.Search.Group .ID}}selected{{end}}>{{.Name}}</option>
|
||||||
|
{{end}}{{end}}</select></div>
|
||||||
|
</div>{{end}}
|
||||||
<div class="formrow form_button_row">
|
<div class="formrow form_button_row">
|
||||||
<div class="formitem"><button class="formbutton">{{lang "panel_users_search_button"}}</button></div>
|
<div class="formitem"><button class="formbutton">{{lang "panel_users_search_button"}}</button></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue