Initial commit
Test / test (push) Successful in 7m5s
Release / gates (push) Successful in 7m28s
Release / build (amd64, freebsd) (push) Successful in 2m52s
Release / build (amd64, linux) (push) Successful in 2m46s
Release / build (arm64, freebsd) (push) Successful in 2m22s
Release / build (arm64, linux) (push) Successful in 2m38s
Release / build (loong64, linux) (push) Successful in 2m7s
Release / build (riscv64, linux) (push) Successful in 2m17s
Release / release (push) Successful in 1m0s
Test / test (push) Successful in 7m5s
Release / gates (push) Successful in 7m28s
Release / build (amd64, freebsd) (push) Successful in 2m52s
Release / build (amd64, linux) (push) Successful in 2m46s
Release / build (arm64, freebsd) (push) Successful in 2m22s
Release / build (arm64, linux) (push) Successful in 2m38s
Release / build (loong64, linux) (push) Successful in 2m7s
Release / build (riscv64, linux) (push) Successful in 2m17s
Release / release (push) Successful in 1m0s
Assisted-by: GLM 5.3
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
|
||||
package admin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"sourcedock.dev/petrbalvin/volumen/internal/store"
|
||||
"sourcedock.dev/petrbalvin/volumen/internal/tokens"
|
||||
"sourcedock.dev/petrbalvin/volumen/internal/users"
|
||||
"sourcedock.dev/petrbalvin/volumen/internal/webhooks"
|
||||
)
|
||||
|
||||
// roleOption is one <option> of a role select.
|
||||
type roleOption struct {
|
||||
Value string
|
||||
Selected bool
|
||||
}
|
||||
|
||||
// userRow is one entry of the users panel.
|
||||
type userRow struct {
|
||||
Username string
|
||||
Display string
|
||||
Initial string
|
||||
Role string
|
||||
Photo string
|
||||
IsSelf bool
|
||||
RoleOptions []roleOption
|
||||
}
|
||||
|
||||
// hookRow is one configured webhook endpoint.
|
||||
type hookRow struct {
|
||||
Index string
|
||||
URL string
|
||||
// Managed is false for a hook declared in config.toml, which the
|
||||
// settings forms may test but not change.
|
||||
Managed bool
|
||||
Enabled bool
|
||||
Signed bool
|
||||
EventsText string
|
||||
}
|
||||
|
||||
// deliveryRow is one webhook delivery log entry.
|
||||
type deliveryRow struct {
|
||||
Timestamp string
|
||||
Event string
|
||||
HookURL string
|
||||
OK bool
|
||||
StatusCode int
|
||||
Error string
|
||||
Attempts int
|
||||
|
||||
// Result is the pre-formatted failure text ("failed (N attempts)"),
|
||||
// translated by the caller that knows the request's language.
|
||||
Result string
|
||||
}
|
||||
|
||||
// tokenRow is one API token table row.
|
||||
type tokenRow struct {
|
||||
Name string
|
||||
CreatedDay string
|
||||
LastUsedDay string
|
||||
}
|
||||
|
||||
// mediaRow is one media library tile.
|
||||
type mediaRow struct {
|
||||
Name string
|
||||
URL string
|
||||
SizeKB string
|
||||
// Dimensions is the header-carried pixel size ("1920 × 1080"), or
|
||||
// "" when the container did not yield one.
|
||||
Dimensions string
|
||||
}
|
||||
|
||||
func roleOptions(current string) []roleOption {
|
||||
out := make([]roleOption, 0, len(users.Roles))
|
||||
for _, role := range users.Roles {
|
||||
out = append(out, roleOption{Value: role, Selected: role == current})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func userRows(current string, list []*users.User) []userRow {
|
||||
out := make([]userRow, 0, len(list))
|
||||
for _, user := range list {
|
||||
display := user.Name
|
||||
if display == "" {
|
||||
display = user.Username
|
||||
}
|
||||
out = append(out, userRow{
|
||||
Username: user.Username,
|
||||
Display: display,
|
||||
Initial: firstUpper(display, "?"),
|
||||
Role: user.Role,
|
||||
Photo: user.Photo,
|
||||
IsSelf: user.Username == current,
|
||||
RoleOptions: roleOptions(user.Role),
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// hookRows renders the manager's merged hook list; the first static
|
||||
// count came from config.toml and the rest are the admin's to manage.
|
||||
func hookRows(hooks []webhooks.Webhook, staticCount int) []hookRow {
|
||||
out := make([]hookRow, 0, len(hooks))
|
||||
for i, hook := range hooks {
|
||||
eventsText := "all"
|
||||
if len(hook.Events) > 0 {
|
||||
eventsText = strings.Join(hook.Events, ", ")
|
||||
}
|
||||
out = append(out, hookRow{
|
||||
Index: fmt.Sprintf("%d", i),
|
||||
URL: hook.URL,
|
||||
Managed: i >= staticCount,
|
||||
Enabled: hook.Enabled,
|
||||
Signed: hook.Secret != "",
|
||||
EventsText: eventsText,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func deliveryRows(list []webhooks.Delivery) []deliveryRow {
|
||||
out := make([]deliveryRow, 0, len(list))
|
||||
for _, d := range list {
|
||||
out = append(out, deliveryRow{
|
||||
Timestamp: d.Timestamp,
|
||||
Event: d.Event,
|
||||
HookURL: d.HookURL,
|
||||
OK: d.Status == "ok",
|
||||
StatusCode: d.StatusCode,
|
||||
Error: d.Error,
|
||||
Attempts: d.Attempts,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func tokenRows(list []tokens.Token) []tokenRow {
|
||||
out := make([]tokenRow, 0, len(list))
|
||||
for _, token := range list {
|
||||
lastUsed := "never"
|
||||
if len(token.LastUsed) >= 10 {
|
||||
lastUsed = token.LastUsed[:10]
|
||||
}
|
||||
created := token.Created
|
||||
if len(created) >= 10 {
|
||||
created = created[:10]
|
||||
}
|
||||
out = append(out, tokenRow{
|
||||
Name: token.Name,
|
||||
CreatedDay: created,
|
||||
LastUsedDay: lastUsed,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mediaRows(list []store.Media) []mediaRow {
|
||||
out := make([]mediaRow, 0, len(list))
|
||||
for _, item := range list {
|
||||
out = append(out, mediaRow{
|
||||
Name: item.Name,
|
||||
URL: item.URL,
|
||||
SizeKB: fmt.Sprintf("%.1f", float64(item.Size)/1024),
|
||||
Dimensions: pixelSize(item.Width, item.Height),
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// pixelSize renders the header-carried pixel size, empty when the
|
||||
// container did not yield one.
|
||||
func pixelSize(width, height int) string {
|
||||
if width <= 0 || height <= 0 {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%d × %d", width, height)
|
||||
}
|
||||
Reference in New Issue
Block a user