Promote archive mailbox menu

This commit is contained in:
DonVoo 2026-07-12 22:54:47 +02:00
parent fe3ece17ba
commit 84bc0de876
2 changed files with 61 additions and 34 deletions

View file

@ -55,9 +55,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-8">
<link rel="stylesheet" href="/static/style.css?v=20260712-9">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-8" defer></script></head>
<script src="/static/app.js?v=20260712-9" 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>
@ -74,7 +74,7 @@ func renderShell(w http.ResponseWriter, active, readingPane string) {
<a class="backstage-item active" href="/view">Archiv-Boxen</a>
<a class="backstage-item" href="/view">Import/Export</a>
<a class="backstage-item" href="/accounts">Konten-Verwaltung</a>
<a class="backstage-item sub" href="/archives">Archiv-mbox Verwaltung</a>
<a class="backstage-item" href="/archives">Archiv-mbox Verwaltung</a>
<a class="backstage-item" href="/view">Mail-Transfer</a>
<a class="backstage-item" href="/accounts">Einstellungen</a>
</aside>
@ -295,9 +295,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-8">
<link rel="stylesheet" href="/static/style.css?v=20260712-9">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-8" defer></script></head>
<script src="/static/app.js?v=20260712-9" 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>
@ -314,7 +314,7 @@ func renderAccountsPage(w http.ResponseWriter, accounts []Account, edit Account,
<a class="backstage-item" href="/view">Archiv-Boxen</a>
<a class="backstage-item" href="/view">Import/Export</a>
<a class="backstage-item active" href="/accounts">Konten-Verwaltung</a>
<a class="backstage-item sub" href="/archives">Archiv-mbox Verwaltung</a>
<a class="backstage-item" href="/archives">Archiv-mbox Verwaltung</a>
<a class="backstage-item" href="/view">Mail-Transfer</a>
<a class="backstage-item" href="/accounts">Einstellungen</a>
</aside>
@ -338,9 +338,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-8">
<link rel="stylesheet" href="/static/style.css?v=20260712-9">
<script src="/static/htmx.min.js"></script>
<script src="/static/app.js?v=20260712-8" defer></script></head>
<script src="/static/app.js?v=20260712-9" 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>
@ -357,7 +357,7 @@ func renderArchivesPage(w http.ResponseWriter, archives []string, accounts []Acc
<a class="backstage-item" href="/view">Archiv-Boxen</a>
<a class="backstage-item" href="/view">Import/Export</a>
<a class="backstage-item" href="/accounts">Konten-Verwaltung</a>
<a class="backstage-item sub active" href="/archives">Archiv-mbox Verwaltung</a>
<a class="backstage-item active" href="/archives">Archiv-mbox Verwaltung</a>
<a class="backstage-item" href="/view">Mail-Transfer</a>
<a class="backstage-item" href="/accounts">Einstellungen</a>
</aside>
@ -369,9 +369,11 @@ func renderArchivesPage(w http.ResponseWriter, archives []string, accounts []Acc
if errMsg != "" {
fmt.Fprintf(w, `<div class="notice bad">%s</div>`, html.EscapeString(errMsg))
}
fmt.Fprint(w, `<section class="archive-page-layout"><div class="pane-head">Archiv-mbox Verwaltung</div>`)
renderArchiveManager(w, archives, accounts)
fmt.Fprint(w, `</section></main><footer class="statusbar"><span id="mig-status" hx-get="/migrate/status" hx-trigger="load,every 3s" hx-swap="innerHTML">bereit</span></footer></body></html>`)
fmt.Fprint(w, `<section class="archive-page-layout"><div class="archive-list-panel"><div class="pane-head">Archiv-mboxen</div>`)
renderArchiveList(w, archives, accounts)
fmt.Fprint(w, `</div><div class="archive-form-panel"><div class="pane-head">Archiv-mbox anlegen</div>`)
renderArchiveForm(w)
fmt.Fprint(w, `</div></section></main><footer class="statusbar"><span id="mig-status" hx-get="/migrate/status" hx-trigger="load,every 3s" hx-swap="innerHTML">bereit</span></footer></body></html>`)
}
func renderAccountsTable(w http.ResponseWriter, accounts []Account, editName string) {
@ -401,13 +403,9 @@ func renderAccountsTable(w http.ResponseWriter, accounts []Account, editName str
fmt.Fprint(w, `</tbody></table>`)
}
func renderArchiveManager(w http.ResponseWriter, archives []string, accounts []Account) {
fmt.Fprint(w, `<div class="archive-manager"><form class="archive-create" method="post" action="/archives/create">
<input class="input" name="archive_name" placeholder="neue Archiv-Mailbox">
<button class="btn compact" type="submit">Erstellen</button>
</form>`)
func renderArchiveList(w http.ResponseWriter, archives []string, accounts []Account) {
if len(archives) == 0 {
fmt.Fprint(w, `<div class="ef-empty">Noch keine Archiv-Mailbox angelegt.</div></div>`)
fmt.Fprint(w, `<div class="ef-empty">Noch keine Archiv-Mailbox angelegt.</div>`)
return
}
fmt.Fprint(w, `<table class="archive-table"><thead><tr><th>Archiv-Mailbox</th><th>Zuordnung</th><th></th></tr></thead><tbody>`)
@ -420,7 +418,19 @@ func renderArchiveManager(w http.ResponseWriter, archives []string, accounts []A
}
fmt.Fprintf(w, `<tr><td>%s</td><td>%s</td><td class="archive-action">%s</td></tr>`, html.EscapeString(archive), html.EscapeString(uses), action)
}
fmt.Fprint(w, `</tbody></table></div>`)
fmt.Fprint(w, `</tbody></table>`)
}
func renderArchiveForm(w http.ResponseWriter) {
fmt.Fprint(w, `<form class="archive-create-panel" method="post" action="/archives/create">
<label class="label">Neue Archiv-Mailbox<input class="input" name="archive_name" placeholder="z.B. kunde-altarchiv"></label>
<button class="btn" type="submit">Erstellen</button>
</form>
<div class="archive-help">
<div class="archive-help-title">Schutzlogik</div>
<p>Archiv-mboxen werden als lokale Ordner unter dem Backup-Root angelegt.</p>
<p>Entfernen ist nur moeglich, wenn die Mailbox keinem Konto zugeordnet und leer ist.</p>
</div>`)
}
func renderAccountForm(w http.ResponseWriter, a Account, archives []string) {

View file

@ -120,10 +120,6 @@ body.ol2013 {
color: var(--ol-blue);
border-left-color: #fff;
}
.backstage-item.sub {
padding-left: 38px;
font-size: 12px;
}
.backstage-shade {
position: fixed;
inset: 44px 0 22px 0;
@ -356,9 +352,18 @@ a.tree-node { display: block; color: inherit; text-decoration: none; }
background: #fff;
}
.archive-page-layout {
max-width: 900px;
display: grid;
grid-template-columns: minmax(520px, 1fr) minmax(360px, 460px);
min-height: 100%;
}
.archive-list-panel,
.archive-form-panel {
min-width: 0;
border-right: 1px solid var(--ol-border);
background: #fff;
}
.archive-form-panel {
border-right: 0;
}
.account-table {
width: 100%;
@ -441,16 +446,6 @@ a.tree-node { display: block; color: inherit; text-decoration: none; }
}
.form-actions a { text-decoration: none; }
.btn.danger { color: #8a1f11; }
.archive-manager {
padding: 12px;
border-bottom: 1px solid var(--ol-border);
}
.archive-create {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 8px;
margin: 0 0 10px;
}
.archive-table {
width: 100%;
border-collapse: collapse;
@ -475,6 +470,27 @@ a.tree-node { display: block; color: inherit; text-decoration: none; }
text-align: right;
}
.archive-action form { margin: 0; }
.archive-create-panel {
display: grid;
gap: 12px;
padding: 14px;
border-bottom: 1px solid var(--ol-border);
}
.archive-create-panel .btn {
justify-self: start;
}
.archive-help {
padding: 14px;
color: var(--ol-muted);
line-height: 1.45;
}
.archive-help p {
margin: 8px 0 0;
}
.archive-help-title {
color: var(--ol-blue-dark);
font-weight: 700;
}
.muted { color: var(--ol-muted); }
/* Statusleiste */
@ -510,6 +526,7 @@ a.tree-node { display: block; color: inherit; text-decoration: none; }
.pane-target { grid-column: auto; }
.searchbar { top: 30px; }
.account-layout,
.archive-page-layout,
.form-columns,
.form-section {
grid-template-columns: 1fr;