Add display names for app users

This commit is contained in:
DonVoo 2026-07-13 00:56:38 +02:00
parent 6e7aa87de6
commit b625c95c29
3 changed files with 92 additions and 35 deletions

View file

@ -64,9 +64,9 @@ func renderShell(w http.ResponseWriter, active, readingPane string) {
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-16">
<link rel="stylesheet" href="/static/style.css?v=20260712-17">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-16" defer></script></head>
<script src="/static/app.js?v=20260712-17" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -385,6 +385,7 @@ func userSaveHandler(w http.ResponseWriter, r *http.Request) {
return
}
username := strings.TrimSpace(r.FormValue("username"))
displayName := strings.TrimSpace(r.FormValue("display_name"))
password := r.FormValue("password")
role := strings.TrimSpace(r.FormValue("role"))
active := r.FormValue("active") == "1"
@ -413,7 +414,7 @@ func userSaveHandler(w http.ResponseWriter, r *http.Request) {
return
}
}
if err := SaveAppUser(username, hash, role, active); err != nil {
if err := SaveAppUser(username, displayName, hash, role, active); err != nil {
redirectUsers(w, r, username, err.Error())
return
}
@ -482,7 +483,7 @@ func userToggleActiveHandler(w http.ResponseWriter, r *http.Request) {
redirectUsers(w, r, username, "Nur Admins duerfen Verwalter oder Admins sperren.")
return
}
if err := SaveAppUser(username, "", target.Role, active); err != nil {
if err := SaveAppUser(username, target.DisplayName, "", target.Role, active); err != nil {
redirectUsers(w, r, username, err.Error())
return
}
@ -503,9 +504,9 @@ func renderAccountsPage(w http.ResponseWriter, accounts []Account, edit Account,
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Konten-Verwaltung - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-16">
<link rel="stylesheet" href="/static/style.css?v=20260712-17">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-16" defer></script></head>
<script src="/static/app.js?v=20260712-17" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -548,9 +549,9 @@ func renderArchivesPage(w http.ResponseWriter, archives []string, accounts []Acc
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Archiv-mbox Verwaltung - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-16">
<link rel="stylesheet" href="/static/style.css?v=20260712-17">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-16" defer></script></head>
<script src="/static/app.js?v=20260712-17" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -596,9 +597,9 @@ func renderUsersPage(w http.ResponseWriter, r *http.Request, users []AppUser, ed
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Benutzerverwaltung - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-16">
<link rel="stylesheet" href="/static/style.css?v=20260712-17">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-16" defer></script></head>
<script src="/static/app.js?v=20260712-17" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -634,7 +635,7 @@ func renderUsersPage(w http.ResponseWriter, r *http.Request, users []AppUser, ed
fmt.Fprint(w, `</div><div class="account-form-panel"><div class="pane-head">Benutzer eintragen</div>`)
renderUserForm(w, r, edit)
fmt.Fprint(w, `</div></section></main><footer class="statusbar"><span>angemeldet als `)
fmt.Fprint(w, html.EscapeString(CurrentUser(r).Username+" / "+CurrentUser(r).Role))
fmt.Fprint(w, html.EscapeString(userDisplayLabel(CurrentUser(r))+" / "+CurrentUser(r).Role))
fmt.Fprint(w, `</span></footer></body></html>`)
}
@ -666,9 +667,9 @@ func renderTransferPage(w http.ResponseWriter, mode transferMode, accounts []Acc
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>%s - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-16">
<link rel="stylesheet" href="/static/style.css?v=20260712-17">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-16" defer></script></head>
<script src="/static/app.js?v=20260712-17" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -707,9 +708,9 @@ func renderSourceEmailBoxPage(w http.ResponseWriter, accounts []Account) {
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Quell-Postfach - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-16">
<link rel="stylesheet" href="/static/style.css?v=20260712-17">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-16" defer></script></head>
<script src="/static/app.js?v=20260712-17" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -749,9 +750,9 @@ func renderTargetEmailBoxPage(w http.ResponseWriter, accounts []Account) {
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Ziel-Postfach - Mail-Graveyard</title>
<link rel="stylesheet" href="/static/style.css?v=20260712-16">
<link rel="stylesheet" href="/static/style.css?v=20260712-17">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-16" defer></script></head>
<script src="/static/app.js?v=20260712-17" defer></script></head>
<body class="ol2013">
<header class="ribbon">
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
@ -999,7 +1000,7 @@ func renderUsersTable(w http.ResponseWriter, users []AppUser, editName string) {
fmt.Fprint(w, `<div class="ef-empty">Noch keine Benutzer eingetragen.</div>`)
return
}
fmt.Fprint(w, `<table class="account-table user-table"><thead><tr><th>Benutzer</th><th>Rolle</th><th>Status</th><th class="actions-col"></th></tr></thead><tbody>`)
fmt.Fprint(w, `<table class="account-table user-table"><thead><tr><th>Name</th><th>Login/E-Mail</th><th>Rolle</th><th>Status</th><th class="actions-col"></th></tr></thead><tbody>`)
for _, u := range users {
activeClass := ""
if u.Username == editName {
@ -1020,8 +1021,8 @@ func renderUsersTable(w http.ResponseWriter, users []AppUser, editName string) {
toggleButton := fmt.Sprintf(`<form method="post" action="/users/toggle-active"><input type="hidden" name="username" value="%s"><input type="hidden" name="active" value="%s"><button class="%s" type="submit">%s</button></form>`,
html.EscapeString(u.Username), nextActive, toggleClass, toggleLabel)
deleteButton := fmt.Sprintf(`<form method="post" action="/users/delete"><input type="hidden" name="username" value="%s"><button class="btn compact secondary danger" type="submit">Loeschen</button></form>`, html.EscapeString(u.Username))
fmt.Fprintf(w, `<tr%s><td>%s</td><td>%s</td><td>%s</td><td class="row-actions">%s%s%s</td></tr>`,
activeClass, html.EscapeString(u.Username), html.EscapeString(u.Role), status, editButton, toggleButton, deleteButton)
fmt.Fprintf(w, `<tr%s><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td class="row-actions">%s%s%s</td></tr>`,
activeClass, html.EscapeString(userDisplayName(u)), html.EscapeString(u.Username), html.EscapeString(u.Role), status, editButton, toggleButton, deleteButton)
}
fmt.Fprint(w, `</tbody></table>`)
}
@ -1033,11 +1034,12 @@ func renderUserForm(w http.ResponseWriter, r *http.Request, u AppUser) {
}
fmt.Fprintf(w, `<form class="account-form user-form" method="post" action="/users/save">
<div class="form-section">
<label class="label">Benutzername<input class="input" name="username" value="%s" required></label>
<label class="label">Login/E-Mail<input class="input" name="username" value="%s" required></label>
<label class="check-row"><input type="checkbox" name="active" value="1" %s> Aktiv</label>
</div>
<div class="form-columns">
<fieldset><legend>Zugang</legend>
<label class="label">Anzeigename<input class="input" name="display_name" value="%s" placeholder="z.B. Max Mustermann"></label>
<div class="form-hint">%s</div>
<label class="label">Passwort<input class="input" name="password" type="password" autocomplete="new-password" placeholder="%s"></label>
<label class="label">Rolle%s</label>
@ -1048,7 +1050,23 @@ func renderUserForm(w http.ResponseWriter, r *http.Request, u AppUser) {
<a class="btn secondary" href="/users">Neu</a>
</div>
</form>`,
html.EscapeString(u.Username), checked(u.Active), passwordHint(u.Username), passwordPlaceholder(u.Username), roleField)
html.EscapeString(u.Username), checked(u.Active), html.EscapeString(u.DisplayName), passwordHint(u.Username), passwordPlaceholder(u.Username), roleField)
}
func userDisplayName(u AppUser) string {
name := strings.TrimSpace(u.DisplayName)
if name != "" {
return name
}
return u.Username
}
func userDisplayLabel(u AppUser) string {
name := strings.TrimSpace(u.DisplayName)
if name != "" {
return name + " <" + u.Username + ">"
}
return u.Username
}
func roleSelect(current string, admin bool) string {