# L10 — Fenêtres & multi-window **Binôme :** `dev-windows` / `test-windows` **Zones :** `application`, `app-tauri`, `frontend/app` **Dépendances amont :** L0, L1, L2, L4. ## Objectif Gestion des fenêtres et onglets : un onglet par projet ; **drag d'un onglet hors de la fenêtre → nouvelle fenêtre OS** portant ce projet. ## Périmètre (DEV) - Entités `Workspace`/`Window`/`Tab` + persistance (`workspace.json`, machine-local). - Use case `MoveTabToNewWindow` (réaffectation `WindowId`, l'onglet est déplacé, pas dupliqué). - `app-tauri` : création de `WebviewWindow`, transfert d'état, fermeture de l'onglet source. - Front : barre d'onglets, drag & drop, restauration de session. ## Périmètre (TEST) - `MoveTabToNewWindow` : invariants (un projet dans un seul onglet à la fois ; fenêtre ≥ 1 onglet ou fermée). - Persistance workspace round-trip. - Front : interactions onglets (mock). ## Definition of Done - `cargo test` + `vitest` verts ; détacher un onglet en nouvelle fenêtre fonctionne (dev manuel). ## Avancement ### ✅ Backend (vert) - **Domaine** : opération **pure** `Workspace::move_tab_to_new_window(tab, new_window)` (`layout.rs`) — l'onglet est *déplacé* (jamais dupliqué) ; fenêtre source vidée → supprimée ; onglet actif déplacé → repli sur un onglet restant. Variante d'erreur `LayoutError::TabNotFound`. 4 tests domaine. - **Application** (`application/window/`) : `MoveTabToNewWindow` (charge le workspace, mint `WindowId`, applique l'op pure, persiste via `ProjectStore`). 2 tests (store mock). La persistance round-trip du workspace est déjà couverte par `FsProjectStore` (L2). - `cargo test --workspace` : **323 verts, 0 régression** ; clippy clean. ### ✅ IPC `app-tauri` (vert) - Composition root : use case `MoveTabToNewWindow` injecté. Commande `move_tab_to_new_window(tabId)` : applique la topologie (persistée) **et ouvre une vraie `WebviewWindow`** (primitive de détach résolue). DTO `MoveTabResultDto` + `parse_tab_id`. Test `tests/dto_window.rs` (2). Workspace **325 verts, 0 régression**, clippy clean. ### ⏳ Reste (fait pendant la refonte disposition L11) - **Front multi-fenêtres** : adopter le modèle `Workspace`/`Window`/`Tab` persistant (aujourd'hui les onglets vivent en state React transitoire), barre d'onglets, **DnD detach** + handoff d'état vers la nouvelle fenêtre. Couplé à la refonte de disposition IDE (L11), donc traité là-bas pour éviter de construire une barre d'onglets jetable. ## Spike (cf. ARCHITECTURE §13) - DnD inter-fenêtres Tauri (le DnD HTML ne traverse pas les fenêtres OS) → protocole « detach » via store + event.