Show folders for selected source mailbox

This commit is contained in:
DonVoo 2026-07-13 02:53:09 +02:00
parent d5576ddbde
commit b1f3deca1d

View file

@ -301,7 +301,7 @@ func emailBoxHandler(w http.ResponseWriter, r *http.Request) {
kind := strings.TrimPrefix(r.URL.Path, "/boxes/")
switch kind {
case "source":
renderSourceEmailBoxPage(w, r, accounts)
renderSourceEmailBoxPage(w, r, accounts, r.URL.Query().Get("source"))
case "target":
renderTargetEmailBoxPage(w, r, accounts)
default:
@ -779,7 +779,7 @@ func renderTransferPage(w http.ResponseWriter, r *http.Request, mode transferMod
html.EscapeString(mode.RightTitle), renderTransferPicker(mode.RightKind, accounts, archives))
}
func renderSourceEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts []Account) {
func renderSourceEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts []Account, selected string) {
user := CurrentUser(r)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
@ -811,14 +811,14 @@ func renderSourceEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts [
</aside>
<button class="backstage-shade" type="button" aria-label="Menue schliessen" data-backstage-close></button>
<div class="three-pane email-box-view">
<aside class="pane pane-tree">%s</aside>
<aside class="pane pane-tree" id="source-tree">%s</aside>
<div class="pane-resizer" data-resize-index="0"></div>
<section class="pane pane-list"><div class="pane-head">Nachrichten</div><div class="ef-empty">Quell-Postfach waehlen.</div></section>
<div class="pane-resizer" data-resize-index="1"></div>
<section class="pane pane-read"><div class="ef-empty">Nachricht waehlen.</div></section>
</div>
<footer class="statusbar"><span id="mig-status" hx-get="/migrate/status" hx-trigger="load,every 3s" hx-swap="innerHTML">bereit</span></footer></body></html>`,
renderRibbonEmailBoxMenu("source"), renderRibbonTransferMenu(""), renderRibbonActions(false, user), renderEmailBoxSourcePane(accounts))
renderRibbonEmailBoxMenu("source"), renderRibbonTransferMenu(""), renderRibbonActions(false, user), renderEmailBoxSourcePane(accounts, selected))
}
func renderTargetEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts []Account) {
@ -863,28 +863,61 @@ func renderTargetEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts [
renderRibbonEmailBoxMenu("target"), renderRibbonTransferMenu(""), renderRibbonActions(false, user), renderEmailBoxTargetPane(accounts))
}
func renderEmailBoxSourcePane(accounts []Account) string {
func renderEmailBoxSourcePane(accounts []Account, selected string) string {
var b strings.Builder
b.WriteString(`<div class="pane-head archive-head"><span>Quell-Postfach</span><form class="archive-select-form"><select class="archive-select" name="source">`)
sourceAccounts := accountsBySource(accounts)
if len(sourceAccounts) == 0 {
b.WriteString(`<option>Keine Quellen</option>`)
b.WriteString(`<div class="pane-head archive-head"><span>Quell-Postfach</span></div><div class="ef-empty">Keine Quell-Postfaecher eingetragen.</div>`)
return b.String()
}
selectedAccount := sourceAccounts[0]
if selected != "" {
for _, a := range sourceAccounts {
if a.Name == selected {
selectedAccount = a
break
}
}
}
b.WriteString(`<div class="pane-head archive-head"><span>Quell-Postfach</span><form class="archive-select-form" hx-get="/boxes/source" hx-target="#source-tree" hx-swap="innerHTML" hx-trigger="change from:#source-mailbox-select"><select id="source-mailbox-select" class="archive-select" name="source">`)
for _, a := range sourceAccounts {
label := fmt.Sprintf("%s (%s)", a.SrcUser, strings.ToUpper(accountProto(a)))
fmt.Fprintf(&b, `<option value="%s">%s</option>`, html.EscapeString(a.Name), html.EscapeString(label))
sel := ""
if a.Name == selectedAccount.Name {
sel = ` selected`
}
fmt.Fprintf(&b, `<option value="%s"%s>%s</option>`, html.EscapeString(a.Name), sel, html.EscapeString(label))
}
b.WriteString(`</select></form></div>`)
if len(sourceAccounts) == 0 {
b.WriteString(`<div class="ef-empty">Keine Quell-Postfaecher eingetragen.</div>`)
renderSourceFolders(&b, selectedAccount)
return b.String()
}
func renderSourceFolders(b *strings.Builder, account Account) {
fmt.Fprintf(b, `<div class="tree-node account">%s</div>`, html.EscapeString(account.SrcUser))
if accountProto(account) == "pop3" {
b.WriteString(`<div class="tree-node folder"><span class="tree-label">INBOX</span><span class="tree-count">POP3</span></div>`)
return
}
for _, a := range sourceAccounts {
fmt.Fprintf(&b, `<div class="tree-node account">%s</div>`, html.EscapeString(a.SrcUser))
fmt.Fprintf(&b, `<div class="tree-node folder"><span class="tree-label">%s</span><span class="tree-count">%s</span></div>`,
html.EscapeString(strings.ToUpper(accountProto(a))), html.EscapeString(a.SrcHost))
src, err := OpenIMAPSource(account)
if err != nil {
fmt.Fprintf(b, `<div class="ef-empty">Ordner konnten nicht geladen werden: %s</div>`, html.EscapeString(err.Error()))
return
}
defer src.Close()
folders, err := src.Folders()
if err != nil {
fmt.Fprintf(b, `<div class="ef-empty">Ordner konnten nicht geladen werden: %s</div>`, html.EscapeString(err.Error()))
return
}
if len(folders) == 0 {
b.WriteString(`<div class="ef-empty">Keine Ordner in diesem Quell-Postfach.</div>`)
return
}
for _, folder := range folders {
fmt.Fprintf(b, `<div class="tree-node folder"><span class="tree-label">%s</span><span class="tree-count">%s</span></div>`,
html.EscapeString(folder.Name), html.EscapeString(strings.Join(folder.Attrs, " ")))
}
return b.String()
}
func renderEmailBoxTargetPane(accounts []Account) string {