// Akzeptanzkriterium 1: Ordnerbaum. Die Mail-API liefert Postfächer/Ordner // als flache Liste von Namen (mail/internal/search: mailbox-Facette, keine // Hierarchie im Datenmodell) — IMAP-Importe benennen verschachtelte Ordner // aber üblicherweise mit "/" als Trenner (z. B. "INBOX/Projekte"). Dieser // Baum wird daher rein clientseitig aus den flachen Namen aufgebaut, ohne // eine Backend-Hierarchie zu erfinden, die es nicht gibt. import type { MailboxDTO } from "./api"; export interface FolderNode { name: string; // voller Pfad, z.B. "INBOX/Projekte" — das ist der Wert für fetchMessages({ mailbox }) label: string; // letztes Pfadsegment, für die Anzeige depth: number; messageCount: number | null; // null = reine Gruppierungsebene, kein eigenes Postfach children: FolderNode[]; } export function buildFolderTree(mailboxes: MailboxDTO[]): FolderNode[] { const roots: FolderNode[] = []; const byPath = new Map(); function ensureNode(segments: string[]): FolderNode { const path = segments.join("/"); const existing = byPath.get(path); if (existing) return existing; const node: FolderNode = { name: path, label: segments[segments.length - 1], depth: segments.length - 1, messageCount: null, children: [], }; byPath.set(path, node); if (segments.length === 1) { roots.push(node); } else { const parent = ensureNode(segments.slice(0, -1)); parent.children.push(node); } return node; } for (const mailbox of mailboxes) { const node = ensureNode(mailbox.name.split("/")); node.messageCount = mailbox.messageCount; } return roots; } export function flattenVisible(nodes: FolderNode[], expanded: Set): FolderNode[] { const out: FolderNode[] = []; for (const node of nodes) { out.push(node); if (node.children.length > 0 && expanded.has(node.name)) { out.push(...flattenVisible(node.children, expanded)); } } return out; }