Admin view for User Notes page

face-detect
Noah Petherbridge 2023-12-21 14:59:41 -08:00
parent 483e5a2db3
commit 13775b9722
5 changed files with 122 additions and 10 deletions

View File

@ -177,9 +177,10 @@ func MyNotes() http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Filter parameters.
var (
search = r.FormValue("search")
sort = r.FormValue("sort")
sortOK bool
search = r.FormValue("search")
sort = r.FormValue("sort")
adminNotes = r.FormValue("admin_notes") == "true"
sortOK bool
)
// Sort options.
@ -206,6 +207,11 @@ func MyNotes() http.HandlerFunc {
return
}
// Admin notes?
if adminNotes && !currentUser.IsAdmin {
adminNotes = false
}
// Are we deleting a note?
if r.Method == http.MethodPost {
var (
@ -253,11 +259,21 @@ func MyNotes() http.HandlerFunc {
PerPage: config.PageSizeAdminUserNotes,
Sort: sort,
}
userIDs = []uint64{}
userIDs = []uint64{}
notes []*models.UserNote
adminUserMap models.UserMap
)
pager.ParsePage(r)
notes, err := models.PaginateMyUserNotes(currentUser, search, pager)
if adminNotes {
notes, err = models.PaginateAdminUserNotes(search, pager)
if userMap, err := models.MapAdminUsers(currentUser); err == nil {
adminUserMap = userMap
}
} else {
notes, err = models.PaginateMyUserNotes(currentUser, search, pager)
}
if err != nil {
session.FlashError(w, r, "Error getting your user notes: %s", err)
templates.Redirect(w, "/")
@ -274,13 +290,15 @@ func MyNotes() http.HandlerFunc {
}
vars := map[string]interface{}{
"Notes": notes,
"Pager": pager,
"UserMap": userMap,
"Notes": notes,
"Pager": pager,
"UserMap": userMap, // users talked about on this page
"AdminUserMap": adminUserMap, // other admin note authors for AdminNotes view
// Search filters
"Search": search,
"Sort": sort,
"Search": search,
"Sort": sort,
"AdminNotes": adminNotes,
}
if err := tmpl.Execute(w, r, vars); err != nil {

View File

@ -451,6 +451,20 @@ func MapUsers(user *User, userIDs []uint64) (UserMap, error) {
return usermap, result.Error
}
// MapAdminUsers returns a MapUsers result for all admin user accounts on the site.
func MapAdminUsers(user *User) (UserMap, error) {
adminUsers, err := ListAdminUsers()
if err != nil {
return nil, err
}
var userIDs = []uint64{}
for _, user := range adminUsers {
userIDs = append(userIDs, user.ID)
}
return MapUsers(user, userIDs)
}
// Has a user ID in the map?
func (um UserMap) Has(id uint64) bool {
_, ok := um[id]

View File

@ -2,6 +2,7 @@ package models
import (
"errors"
"fmt"
"strings"
"time"
@ -134,6 +135,52 @@ func PaginateMyUserNotes(currentUser *User, search string, pager *Pagination) ([
return notes, result.Error
}
// PaginateAdminUserNotes shows all notes written by any admin user account on nonshy.
func PaginateAdminUserNotes(search string, pager *Pagination) ([]*UserNote, error) {
var (
adminUserIDs = []uint64{}
notes = []*UserNote{}
wheres = []string{}
placeholders = []interface{}{}
ilike = "%" + search + "%"
)
// Get all the admin users.
adminUsers, err := ListAdminUsers()
if err != nil {
return nil, fmt.Errorf("couldn't get admin users: %s", err)
}
for _, user := range adminUsers {
adminUserIDs = append(adminUserIDs, user.ID)
}
// Filter to notes written by admin users.
wheres = append(wheres, "user_notes.user_id IN ?")
placeholders = append(placeholders, adminUserIDs)
// Searching?
if search != "" {
wheres = append(wheres, "(users.username ILIKE ? OR user_notes.message ILIKE ?)")
placeholders = append(placeholders, ilike, ilike)
}
query := DB.Joins("JOIN users ON users.id = user_notes.about_user_id").Where(
strings.Join(wheres, " AND "),
placeholders...,
).Order(
pager.Sort,
)
query.Model(&UserNote{}).Count(&pager.Total)
result := query.Offset(
pager.GetOffset(),
).Limit(pager.PerPage).Find(&notes)
return notes, result.Error
}
// Save the note.
func (p *UserNote) Save() error {
if p.ID == 0 {

View File

@ -51,6 +51,22 @@
</div>
</div>
<!-- Admin Notes filter -->
{{if .CurrentUser.IsAdmin}}
<div class="column">
<div class="field">
<label class="label has-text-danger" for="admin_notes"><i class="fa fa-peace mr-1"></i> Admin Notes:</label>
<label class="checkbox">
<input type="checkbox" id="admin_notes"
name="admin_notes"
value="true"
{{if .AdminNotes}}checked{{end}}>
Show all notes by admin users
</label>
</div>
</div>
{{end}}
<div class="column">
<div class="field">
<label class="label" for="sort">Sort by:</label>
@ -113,6 +129,15 @@
</span>
{{end}}
<!-- Admin Notes view? Say which admin wrote this note. -->
{{if $Root.AdminNotes}}
<span class="ml-4">
<strong>Written by:</strong>
{{$AdminUser := $Root.AdminUserMap.Get .UserID}}
<a href="/u/{{$AdminUser.Username}}">{{$AdminUser.Username}}</a>
</span>
{{end}}
<div class="my-2" style="white-space: pre-wrap; word-break: break-word; overflow: auto">{{.Message}}</div>
<div class="mt-3">
@ -126,11 +151,13 @@
</em>
<!-- Delete button -->
{{if eq $Root.CurrentUser.ID .UserID}}
<button type="submit" class="button is-small is-outlined is-danger"
onclick="return confirm('Do you want to delete this note?')">
<i class="fa fa-trash mr-1"></i>
Delete
</button>
{{end}}
</form>
</div>
</div>
@ -138,6 +165,8 @@
</div>
</div>
{{end}}
{{SimplePager .Pager}}
</div>
</div>

View File

@ -181,6 +181,10 @@
<span class="icon"><i class="fa fa-eye"></i></span>
<span>Private Photos</span>
</a>
<a class="navbar-item" href="/notes/me">
<span class="icon"><i class="fa fa-pen-to-square"></i></span>
<span>My User Notes</span>
</a>
{{if .CurrentUser.IsInnerCircle}}
<a class="navbar-item" href="/inner-circle">
<span class="icon"><img src="/static/img/circle-16.png"></span>