basic user manager search
reduce template sizes add PaginatorMod struct UserStore: add SearchOffset method add CountSearch method phrases: add panel_users_search_head add panel_users_search_name add panel_users_search_name_placeholder add panel_users_search_email add panel_users_search_email_placeholder add panel_users_search_button
This commit is contained in:
parent
e792dbc2c7
commit
c9e99c075d
|
@ -154,6 +154,13 @@ type Paginator struct {
|
||||||
LastPage int
|
LastPage int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PaginatorMod struct {
|
||||||
|
Params template.URL
|
||||||
|
PageList []int
|
||||||
|
Page int
|
||||||
|
LastPage int
|
||||||
|
}
|
||||||
|
|
||||||
type CustomPagePage struct {
|
type CustomPagePage struct {
|
||||||
*Header
|
*Header
|
||||||
Page *CustomPage
|
Page *CustomPage
|
||||||
|
@ -604,10 +611,15 @@ type PanelMenuItemPage struct {
|
||||||
Item MenuItem
|
Item MenuItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PanelUserPageSearch struct {
|
||||||
|
Name string
|
||||||
|
Email string
|
||||||
|
}
|
||||||
type PanelUserPage struct {
|
type PanelUserPage struct {
|
||||||
*BasePanelPage
|
*BasePanelPage
|
||||||
ItemList []*User
|
ItemList []*User
|
||||||
Paginator
|
Search PanelUserPageSearch
|
||||||
|
PaginatorMod
|
||||||
}
|
}
|
||||||
|
|
||||||
type PanelGroupPage struct {
|
type PanelGroupPage struct {
|
||||||
|
|
|
@ -21,6 +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)
|
||||||
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)
|
||||||
|
@ -29,6 +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
|
||||||
|
|
||||||
SetCache(cache UserCache)
|
SetCache(cache UserCache)
|
||||||
GetCache() UserCache
|
GetCache() UserCache
|
||||||
|
@ -39,12 +41,15 @@ type DefaultUserStore struct {
|
||||||
|
|
||||||
get *sql.Stmt
|
get *sql.Stmt
|
||||||
getByName *sql.Stmt
|
getByName *sql.Stmt
|
||||||
|
searchOffset *sql.Stmt
|
||||||
getOffset *sql.Stmt
|
getOffset *sql.Stmt
|
||||||
getAll *sql.Stmt
|
getAll *sql.Stmt
|
||||||
exists *sql.Stmt
|
exists *sql.Stmt
|
||||||
register *sql.Stmt
|
register *sql.Stmt
|
||||||
nameExists *sql.Stmt
|
nameExists *sql.Stmt
|
||||||
|
|
||||||
count *sql.Stmt
|
count *sql.Stmt
|
||||||
|
countSearch *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDefaultUserStore gives you a new instance of DefaultUserStore
|
// NewDefaultUserStore gives you a new instance of DefaultUserStore
|
||||||
|
@ -58,14 +63,19 @@ func NewDefaultUserStore(cache UserCache) (*DefaultUserStore, error) {
|
||||||
// TODO: Add an admin version of registerStmt with more flexibility?
|
// TODO: Add an admin version of registerStmt with more flexibility?
|
||||||
return &DefaultUserStore{
|
return &DefaultUserStore{
|
||||||
cache: cache,
|
cache: cache,
|
||||||
|
|
||||||
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(),
|
||||||
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(),
|
||||||
|
|
||||||
exists: acc.Exists(u, "uid").Prepare(),
|
exists: acc.Exists(u, "uid").Prepare(),
|
||||||
register: acc.Insert(u).Columns("name,email,password,salt,group,is_super_admin,session,active,message,createdAt,lastActiveAt,lastLiked,oldestItemLikedCreatedAt").Fields("?,?,?,?,?,0,'',?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP()").Prepare(), // TODO: Implement user_count on users_groups here
|
register: acc.Insert(u).Columns("name,email,password,salt,group,is_super_admin,session,active,message,createdAt,lastActiveAt,lastLiked,oldestItemLikedCreatedAt").Fields("?,?,?,?,?,0,'',?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP()").Prepare(), // TODO: Implement user_count on users_groups here
|
||||||
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(),
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +180,30 @@ 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) {
|
||||||
|
rows, err := s.searchOffset.Query(name, name, email, email, offset, perPage)
|
||||||
|
if err != nil {
|
||||||
|
return users, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var embeds int
|
||||||
|
for rows.Next() {
|
||||||
|
u := &User{Loggedin: true}
|
||||||
|
err := rows.Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds, &u.Privacy.ShowComments, &u.Privacy.AllowMessage)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if embeds != -1 {
|
||||||
|
u.ParseSettings = DefaultParseSettings.CopyPtr()
|
||||||
|
u.ParseSettings.NoEmbed = embeds == 0
|
||||||
|
}
|
||||||
|
u.Init()
|
||||||
|
s.cache.Set(u)
|
||||||
|
users = append(users, u)
|
||||||
|
}
|
||||||
|
return users, rows.Err()
|
||||||
|
}
|
||||||
func (s *DefaultUserStore) Each(f func(*User) error) error {
|
func (s *DefaultUserStore) Each(f func(*User) error) error {
|
||||||
rows, e := s.getAll.Query()
|
rows, e := s.getAll.Query()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
|
@ -350,6 +384,10 @@ func (s *DefaultUserStore) Count() (count int) {
|
||||||
return Countf(s.count)
|
return Countf(s.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DefaultUserStore) CountSearch(name, email string) (count int) {
|
||||||
|
return Countf(s.countSearch, name, name, email, email)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *DefaultUserStore) SetCache(cache UserCache) {
|
func (s *DefaultUserStore) SetCache(cache UserCache) {
|
||||||
s.cache = cache
|
s.cache = cache
|
||||||
}
|
}
|
||||||
|
|
|
@ -895,6 +895,13 @@
|
||||||
"panel_users_ban":"Ban",
|
"panel_users_ban":"Ban",
|
||||||
"panel_users_activate":"Activate",
|
"panel_users_activate":"Activate",
|
||||||
|
|
||||||
|
"panel_users_search_head":"Search",
|
||||||
|
"panel_users_search_name":"Name",
|
||||||
|
"panel_users_search_name_placeholder":"John Doe",
|
||||||
|
"panel_users_search_email":"Email",
|
||||||
|
"panel_users_search_email_placeholder":"john.doe@example.com",
|
||||||
|
"panel_users_search_button":"Search",
|
||||||
|
|
||||||
"panel_user_head":"User Editor",
|
"panel_user_head":"User Editor",
|
||||||
"panel_user_avatar":"Avatar",
|
"panel_user_avatar":"Avatar",
|
||||||
"panel_user_avatar_select":"Select",
|
"panel_user_avatar_select":"Select",
|
||||||
|
|
|
@ -2,7 +2,9 @@ package panel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
|
@ -13,17 +15,45 @@ func Users(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name := r.FormValue("s-name")
|
||||||
|
email := r.FormValue("s-email")
|
||||||
|
hasParam := name != "" || email != ""
|
||||||
|
|
||||||
page, _ := strconv.Atoi(r.FormValue("page"))
|
page, _ := strconv.Atoi(r.FormValue("page"))
|
||||||
perPage := 15
|
perPage := 15
|
||||||
offset, page, lastPage := c.PageOffset(basePage.Stats.Users, page, perPage)
|
userCount := basePage.Stats.Users
|
||||||
|
if hasParam {
|
||||||
|
userCount = c.Users.CountSearch(name, email)
|
||||||
|
}
|
||||||
|
offset, page, lastPage := c.PageOffset(userCount, page, perPage)
|
||||||
|
|
||||||
users, err := c.Users.GetOffset(offset, perPage)
|
var users []*c.User
|
||||||
if err != nil {
|
var e error
|
||||||
return c.InternalError(err, w, r)
|
if hasParam {
|
||||||
|
users, e = c.Users.SearchOffset(name, email, offset, perPage)
|
||||||
|
} else {
|
||||||
|
users, e = c.Users.GetOffset(offset, perPage)
|
||||||
|
}
|
||||||
|
if e != nil {
|
||||||
|
return c.InternalError(e, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = url.QueryEscape(name)
|
||||||
|
email = url.QueryEscape(email)
|
||||||
|
search := c.PanelUserPageSearch{name, email}
|
||||||
|
|
||||||
|
var params string
|
||||||
|
if hasParam {
|
||||||
|
if name != "" {
|
||||||
|
params += "s-name=" + name + "&"
|
||||||
|
}
|
||||||
|
if email != "" {
|
||||||
|
params += "s-email=" + email + "&"
|
||||||
|
}
|
||||||
|
}
|
||||||
pageList := c.Paginate(page, lastPage, 5)
|
pageList := c.Paginate(page, lastPage, 5)
|
||||||
pi := c.PanelUserPage{basePage, users, c.Paginator{pageList, page, lastPage}}
|
pi := c.PanelUserPage{basePage, users, 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})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,4 +17,23 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{template "paginator.html" . }}
|
{{template "paginator_mod.html" . }}
|
||||||
|
|
||||||
|
<div class="colstack_item colstack_head">
|
||||||
|
<div class="rowitem"><h1>{{lang "panel_users_search_head"}}</h1></div>
|
||||||
|
</div>
|
||||||
|
<div class="colstack_item the_form">
|
||||||
|
<form action="/panel/users/"method="get">
|
||||||
|
<div class="formrow">
|
||||||
|
<div class="formitem formlabel"><a>{{lang "panel_users_search_name"}}</a></div>
|
||||||
|
<div class="formitem"><input name="s-name"type="text"{{if .Search.Name}}value="{{.Search.Name}}"{{end}}placeholder="{{lang "panel_users_search_name_placeholder"}}"></div>
|
||||||
|
</div>
|
||||||
|
{{if .CurrentUser.Perms.EditUserEmail}}<div class="formrow">
|
||||||
|
<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>{{end}}
|
||||||
|
<div class="formrow form_button_row">
|
||||||
|
<div class="formitem"><button class="formbutton">{{lang "panel_users_search_button"}}</button></div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
Loading…
Reference in New Issue