feat(windows): persistance et restauration des fenêtres au redémarrage (#40)

Persiste l'état des fenêtres (layout/position) et le restaure au
relancement de l'application. Découpage hexagonal :
- domaine : modèle et port d'état des fenêtres (layout, ports)
- application : use cases de persistance/restauration
- infrastructure : store window_state (adapter de persistance)
- présentation : câblage app-tauri (state, commands, lib)
Couvert par des tests ciblés domaine/application/infrastructure.

Depend de #39 (fermeture des fenêtres auxiliaires).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 08:00:20 +02:00
parent 55087b5d9b
commit 2eb51d3335
15 changed files with 887 additions and 40 deletions

View File

@ -2341,7 +2341,7 @@ pub struct ViewWindowLifecycleEventDto {
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ViewPanel {
pub(crate) enum ViewPanel {
Projects,
Context,
Work,
@ -2355,7 +2355,7 @@ enum ViewPanel {
}
impl ViewPanel {
fn parse(raw: &str) -> Result<Self, ErrorDto> {
pub(crate) fn parse(raw: &str) -> Result<Self, ErrorDto> {
match raw {
"projects" => Ok(Self::Projects),
"context" => Ok(Self::Context),
@ -2374,7 +2374,7 @@ impl ViewPanel {
}
}
const fn as_str(self) -> &'static str {
pub(crate) const fn as_str(self) -> &'static str {
match self {
Self::Projects => "projects",
Self::Context => "context",
@ -2389,7 +2389,7 @@ impl ViewPanel {
}
}
const fn title(self) -> &'static str {
pub(crate) const fn title(self) -> &'static str {
match self {
Self::Projects => "Projects",
Self::Context => "Project context",
@ -2405,15 +2405,15 @@ impl ViewPanel {
}
}
fn view_window_label(panel: ViewPanel, project_id: domain::ProjectId) -> String {
pub(crate) fn view_window_label(panel: ViewPanel, project_id: domain::ProjectId) -> String {
format!("view-{}-{}", panel.as_str(), project_id.as_uuid().simple())
}
fn view_window_url(panel: ViewPanel, project_id: domain::ProjectId) -> String {
pub(crate) fn view_window_url(panel: ViewPanel, project_id: domain::ProjectId) -> String {
format!("index.html?panel={}&project={}", panel.as_str(), project_id)
}
fn emit_view_window_lifecycle(
pub(crate) fn emit_view_window_lifecycle(
app: &AppHandle,
kind: &'static str,
panel: ViewPanel,