fix(windows): fenêtres de panneau détachées suivent le projet en focus côté UI (#47)
Partie frontend. Ajoute un adaptateur focusedProject et un port dédié : la ViewWindow détachée n'est plus liée à un project_id figé, elle s'abonne à l'event focused-project émis par la fenêtre principale et affiche le panneau du projet courant. ProjectsView propage le focus ; le détachement crée une fenêtre panel-only. Couvert par les tests window/ViewWindow/focusedProject/ ProjectsView.focus. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
48
frontend/src/adapters/focusedProject.ts
Normal file
48
frontend/src/adapters/focusedProject.ts
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Tauri adapter for {@link FocusedProjectGateway} (ticket #47). Bridges the
|
||||
* main-window ⇄ detached-panel focused-project channel to the backend commands
|
||||
* and event. Like the sibling adapters, this is the only layer allowed to touch
|
||||
* `@tauri-apps/api`; components reach it exclusively through the port.
|
||||
*
|
||||
* Command/event names and payloads mirror the backend contract owned by
|
||||
* DevBackend: `set_focused_project` / `get_focused_project` and the
|
||||
* `focused-project://changed` event whose payload is `{ project: FocusedProject
|
||||
* | null }`.
|
||||
*/
|
||||
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
|
||||
import type { Unsubscribe } from "@/domain";
|
||||
import type { FocusedProject, FocusedProjectGateway } from "@/ports";
|
||||
|
||||
/** The Tauri event carrying focused-project transitions. */
|
||||
const FOCUSED_PROJECT_CHANGED = "focused-project://changed";
|
||||
|
||||
/** Backend payload for `focused-project://changed`. */
|
||||
interface FocusedProjectChanged {
|
||||
project: FocusedProject | null;
|
||||
}
|
||||
|
||||
export class TauriFocusedProjectGateway implements FocusedProjectGateway {
|
||||
async setFocusedProject(project: FocusedProject | null): Promise<void> {
|
||||
// The backend command takes `project: Option<FocusedProjectDto>`; `null`
|
||||
// clears the focus (no project open).
|
||||
await invoke("set_focused_project", { project });
|
||||
}
|
||||
|
||||
async getFocusedProject(): Promise<FocusedProject | null> {
|
||||
const project = await invoke<FocusedProject | null>("get_focused_project");
|
||||
return project ?? null;
|
||||
}
|
||||
|
||||
async onFocusedProjectChanged(
|
||||
handler: (project: FocusedProject | null) => void,
|
||||
): Promise<Unsubscribe> {
|
||||
const unlisten = await listen<FocusedProjectChanged>(
|
||||
FOCUSED_PROJECT_CHANGED,
|
||||
(e) => handler(e.payload.project ?? null),
|
||||
);
|
||||
return unlisten;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user