E-Mail Ordner einklappbar machen
KI-AGENT: Ergänzt auf- und zuklappbare IMAP-Ordner in der E-Mail Übersicht. Elternordner bleiben initial sichtbar, ausgewählte Unterordner öffnen automatisch ihre übergeordneten Ordner.
This commit is contained in:
@@ -69,6 +69,7 @@ const loadingMailboxes = ref(false)
|
||||
const loadingMessages = ref(false)
|
||||
const loadingMessage = ref(false)
|
||||
const syncing = ref(false)
|
||||
const expandedMailboxPaths = ref<string[]>([])
|
||||
|
||||
const selectedAccount = computed(() =>
|
||||
accounts.value.find((account) => account.id === selectedAccountId.value) || null
|
||||
@@ -144,11 +145,14 @@ const mailboxTree = computed(() => {
|
||||
})
|
||||
|
||||
const mailboxRows = computed(() => {
|
||||
const rows: Array<{ mailbox: EmailMailbox; depth: number }> = []
|
||||
const rows: Array<{ mailbox: EmailMailbox; depth: number; hasChildren: boolean }> = []
|
||||
const append = (node: EmailMailboxNode, depth: number) => {
|
||||
rows.push({ mailbox: node.mailbox, depth })
|
||||
const expanded = expandedMailboxPaths.value.includes(node.mailbox.path)
|
||||
rows.push({ mailbox: node.mailbox, depth, hasChildren: node.children.length > 0 })
|
||||
if (expanded) {
|
||||
node.children.forEach((child) => append(child, depth + 1))
|
||||
}
|
||||
}
|
||||
|
||||
mailboxTree.value.forEach((node) => append(node, 0))
|
||||
return rows
|
||||
@@ -186,6 +190,47 @@ const mailboxLabel = (mailbox: EmailMailbox) => {
|
||||
return mailbox.name || mailbox.path
|
||||
}
|
||||
|
||||
const isMailboxExpanded = (mailbox: EmailMailbox) => expandedMailboxPaths.value.includes(mailbox.path)
|
||||
|
||||
const expandMailboxPath = (path: string) => {
|
||||
if (!expandedMailboxPaths.value.includes(path)) {
|
||||
expandedMailboxPaths.value = [...expandedMailboxPaths.value, path]
|
||||
}
|
||||
}
|
||||
|
||||
const collapseMailboxPath = (path: string) => {
|
||||
expandedMailboxPaths.value = expandedMailboxPaths.value.filter((item) => item !== path)
|
||||
}
|
||||
|
||||
const toggleMailboxExpanded = (mailbox: EmailMailbox) => {
|
||||
if (isMailboxExpanded(mailbox)) {
|
||||
collapseMailboxPath(mailbox.path)
|
||||
} else {
|
||||
expandMailboxPath(mailbox.path)
|
||||
}
|
||||
}
|
||||
|
||||
const expandMailboxAncestors = (path: string) => {
|
||||
const mailbox = mailboxes.value.find((item) => item.path === path)
|
||||
if (!mailbox) return
|
||||
|
||||
const delimiter = mailboxDelimiter(mailbox)
|
||||
const parts = path.split(delimiter)
|
||||
|
||||
while (parts.length > 1) {
|
||||
parts.pop()
|
||||
expandMailboxPath(parts.join(delimiter))
|
||||
}
|
||||
}
|
||||
|
||||
const resetExpandedMailboxes = () => {
|
||||
const roots = mailboxTree.value.map((node) => node.mailbox.path)
|
||||
expandedMailboxPaths.value = Array.from(new Set([
|
||||
...roots,
|
||||
...expandedMailboxPaths.value.filter((path) => mailboxes.value.some((mailbox) => mailbox.path === path)),
|
||||
]))
|
||||
}
|
||||
|
||||
const formatAddress = (address?: EmailAddress | null) => {
|
||||
if (!address) return "Unbekannt"
|
||||
return address.name || address.address || "Unbekannt"
|
||||
@@ -254,8 +299,10 @@ async function loadMailboxes() {
|
||||
|
||||
try {
|
||||
mailboxes.value = await $api(`/api/email/accounts/${selectedAccountId.value}/mailboxes`)
|
||||
resetExpandedMailboxes()
|
||||
const inbox = mailboxes.value.find((mailbox) => mailbox.specialUse === "\\Inbox" || mailbox.path.toUpperCase() === "INBOX")
|
||||
selectedMailboxPath.value = inbox?.path || mailboxes.value[0]?.path || "INBOX"
|
||||
expandMailboxAncestors(selectedMailboxPath.value)
|
||||
await loadMessages()
|
||||
} finally {
|
||||
loadingMailboxes.value = false
|
||||
@@ -286,6 +333,7 @@ async function loadMessages() {
|
||||
|
||||
async function selectMailbox(mailbox: EmailMailbox) {
|
||||
selectedMailboxPath.value = mailbox.path
|
||||
expandMailboxAncestors(mailbox.path)
|
||||
await loadMessages()
|
||||
}
|
||||
|
||||
@@ -467,9 +515,14 @@ onMounted(loadAccounts)
|
||||
@click="selectMailbox(row.mailbox)"
|
||||
>
|
||||
<UIcon
|
||||
v-if="row.depth > 0"
|
||||
name="i-heroicons-chevron-right"
|
||||
v-if="row.hasChildren"
|
||||
:name="isMailboxExpanded(row.mailbox) ? 'i-heroicons-chevron-down' : 'i-heroicons-chevron-right'"
|
||||
class="size-3 shrink-0 text-dimmed"
|
||||
@click.stop="toggleMailboxExpanded(row.mailbox)"
|
||||
/>
|
||||
<span
|
||||
v-else
|
||||
class="size-3 shrink-0"
|
||||
/>
|
||||
<UIcon :name="mailboxIcon(row.mailbox)" class="size-4 shrink-0" />
|
||||
<span class="min-w-0 flex-1 truncate">{{ mailboxLabel(row.mailbox) }}</span>
|
||||
|
||||
Reference in New Issue
Block a user