feat: add Back to app button to redirect to last non-settings page (#821)

* add 'back to app' button to redirect to last non-settings page

Users struggle to navigate back from the Settings page. I'd like to add a backwards arrow icon in the top left of the Settings page that navigates the user back to where they were before (perhaps like a browser back). What's the best way to go about this?

* i18n

* remove session storage use global state
This commit is contained in:
Gabriel Gordon-Hall
2025-09-24 11:29:43 +01:00
committed by GitHub
parent b797a9549c
commit 3aafd5d96b
6 changed files with 50 additions and 9 deletions

View File

@@ -6,6 +6,7 @@ import { Navbar } from '@/components/layout/navbar';
import { Projects } from '@/pages/projects';
import { ProjectTasks } from '@/pages/project-tasks';
import { useTaskViewManager } from '@/hooks/useTaskViewManager';
import { usePreviousPath } from '@/hooks/usePreviousPath';
import {
AgentSettings,
@@ -37,6 +38,9 @@ function AppContent() {
const { config, updateAndSaveConfig, loading } = useUserSystem();
const { isFullscreen } = useTaskViewManager();
// Track previous path for back navigation
usePreviousPath();
const showNavbar = !isFullscreen;
useEffect(() => {

View File

@@ -0,0 +1,28 @@
import { useCallback, useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
const globalVisited: string[] = [];
export function usePreviousPath() {
const navigate = useNavigate();
const location = useLocation();
// Track pathnames as user navigates
useEffect(() => {
if (globalVisited[globalVisited.length - 1] !== location.pathname) {
globalVisited.push(location.pathname);
// Keep only last 50 entries to prevent memory bloat
if (globalVisited.length > 50) {
globalVisited.splice(0, globalVisited.length - 50);
}
}
}, [location]);
return useCallback(() => {
// Find last non-settings route in history
const lastNonSettingsPath = [...globalVisited]
.reverse()
.find((p) => !p.startsWith('/settings'));
navigate(lastNonSettingsPath || '/');
}, [navigate]);
}

View File

@@ -8,7 +8,8 @@
"agents": "Agents",
"agentsDesc": "Coding agent configurations",
"mcp": "MCP Servers",
"mcpDesc": "Model Context Protocol servers"
"mcpDesc": "Model Context Protocol servers",
"backToApp": "Back to app"
}
},
"general": {

View File

@@ -8,7 +8,8 @@
"agents": "Agentes",
"agentsDesc": "Configuraciones de agentes",
"mcp": "Servidores MCP",
"mcpDesc": "Servidores de Protocolo de Contexto de Modelo (MCP)"
"mcpDesc": "Servidores de Protocolo de Contexto de Modelo (MCP)",
"backToApp": "Volver a la app"
}
},
"general": {
@@ -134,7 +135,10 @@
"mcp": {
"title": "Configuración de Servidor MCP",
"description": "Configura los servidores del Protocolo de Contexto de Modelos (MCP) para ampliar las capacidades del agente de codificación con herramientas y recursos personalizados.",
"loading": "Cargando configuración MCP...",
"loading": {
"jsonEditor": "Cargando...",
"configuration": "Cargando configuración actual del servidor MCP..."
},
"applying": "Aplicando configuración...",
"labels": {
"agent": "Agente",
@@ -145,10 +149,6 @@
"serverHelper": "Haz clic en una tarjeta para insertar ese Servidor MCP en el JSON de arriba.",
"saveLocation": "Los cambios se guardarán en:"
},
"loading": {
"jsonEditor": "Cargando...",
"configuration": "Cargando configuración actual del servidor MCP..."
},
"errors": {
"loadFailed": "Error al cargar la configuración.",
"invalidJson": "Formato JSON inválido",

View File

@@ -8,7 +8,8 @@
"agents": "エージェント",
"agentsDesc": "コーディングエージェントの設定",
"mcp": "MCPサーバー",
"mcpDesc": "モデルコンテキストプロトコルサーバー"
"mcpDesc": "モデルコンテキストプロトコルサーバー",
"backToApp": "アプリに戻る"
}
},
"general": {

View File

@@ -1,7 +1,9 @@
import { NavLink, Outlet } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Settings, Cpu, Server } from 'lucide-react';
import { Settings, Cpu, Server, ArrowLeft } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { usePreviousPath } from '@/hooks/usePreviousPath';
const settingsNavigation = [
{
@@ -20,6 +22,7 @@ const settingsNavigation = [
export function SettingsLayout() {
const { t } = useTranslation('settings');
const goToPreviousPath = usePreviousPath();
return (
<div className="container mx-auto px-4 py-8">
@@ -27,6 +30,10 @@ export function SettingsLayout() {
{/* Sidebar Navigation */}
<aside className="w-full lg:w-64 lg:shrink-0 lg:sticky lg:top-8 lg:h-fit lg:max-h-[calc(100vh-4rem)] lg:overflow-y-auto">
<div className="space-y-1">
<Button variant="ghost" onClick={goToPreviousPath} className="mb-4">
<ArrowLeft className="mr-2 h-4 w-4" />
{t('settings.layout.nav.backToApp')}
</Button>
<h2 className="px-3 py-2 text-lg font-semibold">
{t('settings.layout.nav.title')}
</h2>