Use internal compose modal for mail actions

This commit is contained in:
DonVoo 2026-07-13 12:16:21 +02:00
parent e8029a177c
commit 29fd3f5cae
3 changed files with 229 additions and 24 deletions

View file

@ -61,6 +61,51 @@ func RegisterRoutes(mux *http.ServeMux) {
mux.HandleFunc("/view/target/select", targetSelectHandler)
mux.HandleFunc("/view/manual-copy", manualCopyHandler)
mux.HandleFunc("/view/forward", forwardHandler)
mux.HandleFunc("/mail/send", mailSendHandler)
}
func mailSendHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
to := splitRecipients(r.FormValue("to"))
subject := strings.TrimSpace(r.FormValue("subject"))
body := r.FormValue("body")
if len(to) == 0 {
http.Error(w, "Bitte mindestens einen Empfaenger eintragen.", http.StatusBadRequest)
return
}
if subject == "" {
subject = "(ohne Betreff)"
}
if err := SendPlainMail(to, subject, body); err != nil {
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
fmt.Fprint(w, "gesendet")
}
func splitRecipients(value string) []string {
fields := strings.FieldsFunc(value, func(r rune) bool {
return r == ',' || r == ';' || r == '\n' || r == '\r' || r == '\t' || r == ' '
})
recipients := make([]string, 0, len(fields))
seen := make(map[string]bool, len(fields))
for _, field := range fields {
addr := strings.TrimSpace(field)
if addr == "" || seen[strings.ToLower(addr)] {
continue
}
recipients = append(recipients, addr)
seen[strings.ToLower(addr)] = true
}
return recipients
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
@ -73,8 +118,8 @@ func renderStartPage(w http.ResponseWriter, r *http.Request) {
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=20260713-10">
<script src="/static/app.js?v=20260713-10" defer></script></head>
<link rel="stylesheet" href="/static/style.css?v=20260713-11">
<script src="/static/app.js?v=20260713-11" 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>
@ -121,9 +166,9 @@ func renderShell(w http.ResponseWriter, r *http.Request, active, readingPane str
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=20260713-10">
<link rel="stylesheet" href="/static/style.css?v=20260713-11">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260713-10" defer></script></head>
<script src="/static/app.js?v=20260713-11" 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>
@ -697,9 +742,9 @@ func renderAccountsPage(w http.ResponseWriter, r *http.Request, accounts []Accou
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=20260713-10">
<link rel="stylesheet" href="/static/style.css?v=20260713-11">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260713-10" defer></script></head>
<script src="/static/app.js?v=20260713-11" 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>
@ -743,9 +788,9 @@ func renderArchivesPage(w http.ResponseWriter, r *http.Request, archives []strin
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=20260713-10">
<link rel="stylesheet" href="/static/style.css?v=20260713-11">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260713-10" defer></script></head>
<script src="/static/app.js?v=20260713-11" 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>
@ -791,9 +836,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=20260713-10">
<link rel="stylesheet" href="/static/style.css?v=20260713-11">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260713-10" defer></script></head>
<script src="/static/app.js?v=20260713-11" 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>
@ -865,9 +910,9 @@ func renderTransferPage(w http.ResponseWriter, r *http.Request, mode transferMod
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=20260713-10">
<link rel="stylesheet" href="/static/style.css?v=20260713-11">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260713-10" defer></script></head>
<script src="/static/app.js?v=20260713-11" 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>
@ -1317,9 +1362,9 @@ func renderSourceEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts [
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=20260713-10">
<link rel="stylesheet" href="/static/style.css?v=20260713-11">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260713-10" defer></script></head>
<script src="/static/app.js?v=20260713-11" 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>
@ -1361,9 +1406,9 @@ func renderTargetEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts [
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=20260713-10">
<link rel="stylesheet" href="/static/style.css?v=20260713-11">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260713-10" defer></script></head>
<script src="/static/app.js?v=20260713-11" 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>