feat(frontend): écran Appareils et parcours d'appairage nommé (#77 F1/F2)
Expose la gestion des appareils appairés introduite en B1-B4, sur une surface unique partagée par le web et le desktop. - Écran Appareils : liste, renommage, révocation unitaire ou globale, activité formatée, panneau de code éphémère. - Le parcours d'appairage demande un nom d'appareil, pour qu'une révocation porte sur quelque chose d'identifiable par l'utilisateur. - Gateways DeviceGateway en trois adapters (Tauri, HTTP, Mock), le port restant le seul contrat connu de la feature. Les erreurs sont mappées localement et le message du serveur n'est jamais affiché tel quel : un échec d'appairage ne doit pas devenir un oracle pour qui teste des codes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -17,19 +17,32 @@
|
||||
|
||||
import { Button, cn } from "@/shared";
|
||||
import { ProfilesSettings } from "@/features/first-run";
|
||||
import { DevicesScreen } from "@/features/devices";
|
||||
import { DeploymentSettings } from "./DeploymentSettings";
|
||||
|
||||
/** The Settings sections, in menu/nav order. */
|
||||
export type SettingsSection = "aiProfiles" | "deployment";
|
||||
export type SettingsSection = "aiProfiles" | "deployment" | "devices";
|
||||
|
||||
/** Human labels, shared by the nav column and the `Settings` menu. */
|
||||
/**
|
||||
* Human labels, shared by the nav column and the `Settings` menu.
|
||||
*
|
||||
* `Appareils` is French where its neighbours are English: the device vocabulary
|
||||
* is frozen by UX across web and desktop (carnet #77), and the web surface it
|
||||
* mirrors is French throughout. Aligning the whole Settings surface on one
|
||||
* language is a UX call beyond this ticket.
|
||||
*/
|
||||
export const SETTINGS_SECTION_LABEL: Record<SettingsSection, string> = {
|
||||
aiProfiles: "AI Profiles",
|
||||
deployment: "Deployment",
|
||||
devices: "Appareils",
|
||||
};
|
||||
|
||||
/** Section order — the single source of truth for both nav and menu. */
|
||||
export const SETTINGS_SECTIONS: SettingsSection[] = ["aiProfiles", "deployment"];
|
||||
export const SETTINGS_SECTIONS: SettingsSection[] = [
|
||||
"aiProfiles",
|
||||
"deployment",
|
||||
"devices",
|
||||
];
|
||||
|
||||
interface SettingsViewProps {
|
||||
section: SettingsSection;
|
||||
@ -77,7 +90,15 @@ export function SettingsView({
|
||||
|
||||
<div className="flex flex-1 justify-center overflow-y-auto p-6">
|
||||
<div className="w-full max-w-2xl">
|
||||
{section === "aiProfiles" ? <ProfilesSettings /> : <DeploymentSettings />}
|
||||
{section === "aiProfiles" ? (
|
||||
<ProfilesSettings />
|
||||
) : section === "deployment" ? (
|
||||
<DeploymentSettings />
|
||||
) : (
|
||||
// No `onSessionEnded`: the desktop app hosts the server and is never
|
||||
// itself a paired device, so it cannot revoke its own session.
|
||||
<DevicesScreen />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user