Add pager to admin user list

This enables paging through the entire list of users.

Ref T553
This commit is contained in:
Matt Baer 2019-01-05 09:37:53 -05:00
parent 3d301c97e9
commit bf7d422039
4 changed files with 64 additions and 7 deletions

View file

@ -29,6 +29,8 @@ var (
sysStatus systemStatus
)
const adminUsersPerPage = 30
type systemStatus struct {
Uptime string
NumGoroutine int
@ -116,15 +118,32 @@ func handleViewAdminUsers(app *app, u *User, w http.ResponseWriter, r *http.Requ
Config config.AppCfg
Message string
Users *[]User
Users *[]User
CurPage int
TotalUsers int64
TotalPages []int
}{
UserPage: NewUserPage(app, r, u, "Users", nil),
Config: app.cfg.App,
Message: r.FormValue("m"),
}
p.TotalUsers = app.db.GetAllUsersCount()
ttlPages := p.TotalUsers / adminUsersPerPage
p.TotalPages = []int{}
for i := 1; i <= int(ttlPages); i++ {
p.TotalPages = append(p.TotalPages, i)
}
var err error
p.Users, err = app.db.GetAllUsers(1)
p.CurPage, err = strconv.Atoi(r.FormValue("p"))
if err != nil || p.CurPage < 1 {
p.CurPage = 1
} else if p.CurPage > int(ttlPages) {
p.CurPage = int(ttlPages)
}
p.Users, err = app.db.GetAllUsers(uint(p.CurPage))
if err != nil {
return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get users: %v", err)}
}

View file

@ -113,6 +113,7 @@ type writestore interface {
GetDynamicContent(id string) (string, *time.Time, error)
UpdateDynamicContent(id, content string) error
GetAllUsers(page uint) (*[]User, error)
GetAllUsersCount() int64
GetUserLastPostTime(id int64) (*time.Time, error)
GetCollectionLastPostTime(id int64) (*time.Time, error)
}
@ -2220,10 +2221,9 @@ func (db *datastore) UpdateDynamicContent(id, content string) error {
}
func (db *datastore) GetAllUsers(page uint) (*[]User, error) {
const usersPerPage = 30
limitStr := fmt.Sprintf("0, %d", usersPerPage)
limitStr := fmt.Sprintf("0, %d", adminUsersPerPage)
if page > 1 {
limitStr = fmt.Sprintf("%d, %d", (page-1)*usersPerPage, usersPerPage)
limitStr = fmt.Sprintf("%d, %d", (page-1)*adminUsersPerPage, adminUsersPerPage)
}
rows, err := db.Query("SELECT id, username, created FROM users ORDER BY created DESC LIMIT " + limitStr)
@ -2246,6 +2246,20 @@ func (db *datastore) GetAllUsers(page uint) (*[]User, error) {
return &users, nil
}
func (db *datastore) GetAllUsersCount() int64 {
var count int64
err := db.QueryRow("SELECT COUNT(*) FROM users").Scan(&count)
switch {
case err == sql.ErrNoRows:
return 0
case err != nil:
log.Error("Failed selecting all users count: %v", err)
return 0
}
return count
}
func (db *datastore) GetUserLastPostTime(id int64) (*time.Time, error) {
var t time.Time
err := db.QueryRow("SELECT created FROM posts WHERE owner_id = ? ORDER BY created DESC LIMIT 1", id).Scan(&t)

View file

@ -9,3 +9,23 @@ header.admin {
margin-left: 1em;
}
}
.pager {
display: flex;
justify-content: center;
a {
color: #333;
font-family: @sansFont;
font-size: 0.86em;
padding: 0.5em 1em;
border: 1px solid #ccc;
&:hover {
text-decoration: none;
background: #efefef;
}
&.selected {
cursor: default;
background: #ccc;
}
}
}

View file

@ -4,9 +4,9 @@
<div class="snug content-container">
{{template "admin-header" .}}
<h2 id="posts-header">Users</h2>
<h2 id="posts-header" style="display: flex; justify-content: space-between;">Users <span style="font-style: italic; font-size: 0.75em;">{{.TotalUsers}} total</strong></h2>
<table class="classy export">
<table class="classy export" style="width:100%">
<tr>
<th>User</th>
<th>Joined</th>
@ -21,6 +21,10 @@
{{end}}
</table>
<nav class="pager">
{{range $n := .TotalPages}}<a href="/admin/users{{if ne $n 1}}?p={{$n}}{{end}}" {{if eq $.CurPage $n}}class="selected"{{end}}>{{$n}}</a>{{end}}
</nav>
</div>
{{template "footer" .}}