fix(app): make settings navigation deterministic

Settings detail screens must return to their logical parent regardless of the route used to enter them. Keep compact navigation in the header while preserving the desktop project-list affordance.
This commit is contained in:
Mohamed Boudra
2026-08-16 19:14:05 +02:00
parent 97ac967495
commit ac7796035d
8 changed files with 173 additions and 68 deletions
+14 -32
View File
@@ -121,27 +121,18 @@ import {
useEnableBuiltInDaemonOption,
} from "@/desktop/hooks/use-enable-built-in-daemon-option";
import {
buildOpenProjectRoute,
buildSettingsHostSectionRoute,
buildSettingsSectionRoute,
type HostSectionSlug,
type SettingsSectionSlug,
} from "@/utils/host-routes";
import {
navigateToLastWorkspace,
useLastWorkspaceSelection,
} from "@/stores/navigation-active-workspace-store";
import { useLastWorkspaceSelection } from "@/stores/navigation-active-workspace-store";
import { returnFromSettings, type SettingsView } from "@/navigation/settings-navigation";
// ---------------------------------------------------------------------------
// View model
// ---------------------------------------------------------------------------
export type SettingsView =
| { kind: "root" }
| { kind: "section"; section: SettingsSectionSlug }
| { kind: "host"; serverId: string; section: HostSectionSlug }
| { kind: "project"; serverId: string; projectId: string };
interface SidebarSectionItem {
id: SettingsSectionSlug;
labelKey: string;
@@ -1367,29 +1358,13 @@ export default function SettingsScreen({ view, openAddHostIntent = null }: Setti
}
}, [isCompactLayout, router]);
const handleBackToRoot = useCallback(() => {
if (router.canGoBack()) {
router.back();
} else {
router.replace("/settings");
}
}, [router]);
const detailProjectServerId = view.kind === "project" ? view.serverId : null;
const handleBackFromDetail = useCallback(() => {
if (detailProjectServerId) {
router.navigate(buildSettingsHostSectionRoute(detailProjectServerId, "projects"));
return;
}
handleBackToRoot();
}, [detailProjectServerId, handleBackToRoot, router]);
returnFromSettings(view);
}, [view]);
const handleBackToWorkspace = useCallback(() => {
if (navigateToLastWorkspace()) {
return;
}
router.replace(buildOpenProjectRoute());
}, [router]);
returnFromSettings({ kind: "root" });
}, []);
const detailHeader = ((): {
title: string;
@@ -1417,7 +1392,14 @@ export default function SettingsScreen({ view, openAddHostIntent = null }: Setti
return renderHostSettingsContent(view, handleHostRemoved);
}
if (view.kind === "project") {
return <ProjectSettingsScreen serverId={view.serverId} projectId={view.projectId} />;
return (
<ProjectSettingsScreen
serverId={view.serverId}
projectId={view.projectId}
onBackToProjects={handleBackFromDetail}
showBackToProjects={!isCompactLayout}
/>
);
}
if (view.kind === "section") {
switch (view.section) {