mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-16 01:12:46 +00:00
refactor: go to /sessions/<sessionId> route on session click
This commit is contained in:
25
src/App.tsx
25
src/App.tsx
@@ -66,7 +66,7 @@ function WorkspaceTabRoute() {
|
|||||||
tab: string;
|
tab: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
if (!workspaceId) {
|
if (!workspaceId && !sessionId) {
|
||||||
return <Navigate to="/" replace />;
|
return <Navigate to="/" replace />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ function WorkspaceTabRoute() {
|
|||||||
return <Navigate to="../chat" replace />;
|
return <Navigate to="../chat" replace />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const decodedWorkspaceId = decodeURIComponent(workspaceId);
|
const decodedWorkspaceId = workspaceId ? decodeURIComponent(workspaceId) : null;
|
||||||
const decodedSessionId = sessionId ? decodeURIComponent(sessionId) : null;
|
const decodedSessionId = sessionId ? decodeURIComponent(sessionId) : null;
|
||||||
const decodedTab = tab ? decodeURIComponent(tab) : 'chat';
|
const decodedTab = tab ? decodeURIComponent(tab) : 'chat';
|
||||||
|
|
||||||
@@ -83,7 +83,10 @@ function WorkspaceTabRoute() {
|
|||||||
<div className="rounded-xl border border-border/70 bg-card/30 p-5">
|
<div className="rounded-xl border border-border/70 bg-card/30 p-5">
|
||||||
<h2 className="text-lg font-semibold">{decodedTab} view</h2>
|
<h2 className="text-lg font-semibold">{decodedTab} view</h2>
|
||||||
<p className="mt-2 text-sm text-muted-foreground">
|
<p className="mt-2 text-sm text-muted-foreground">
|
||||||
Workspace: <span className="font-medium text-foreground">{decodedWorkspaceId}</span>
|
Workspace:{' '}
|
||||||
|
<span className="font-medium text-foreground">
|
||||||
|
{decodedWorkspaceId || 'none (session-level route)'}
|
||||||
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1 text-sm text-muted-foreground">
|
<p className="mt-1 text-sm text-muted-foreground">
|
||||||
Session:{' '}
|
Session:{' '}
|
||||||
@@ -102,20 +105,20 @@ const router = createBrowserRouter(
|
|||||||
path: '/',
|
path: '/',
|
||||||
element: <RootLayout />,
|
element: <RootLayout />,
|
||||||
children: [
|
children: [
|
||||||
{ index: true, element: <NoWorkspaceRoute /> },
|
{ index: true, element: <NoWorkspaceRoute /> }, // TODO: Show empty state component loader here.
|
||||||
{
|
{
|
||||||
path: 'workspaces/:workspaceId',
|
path: 'workspaces/:workspaceId',
|
||||||
element: <WorkspaceLayout />,
|
element: <WorkspaceLayout />,
|
||||||
children: [
|
children: [
|
||||||
{ index: true, element: <Navigate to="chat" replace /> },
|
{ index: true, element: <Navigate to="chat" replace /> },
|
||||||
{ path: ':tab', element: <WorkspaceTabRoute /> },
|
{ path: ':tab', element: <WorkspaceTabRoute /> },
|
||||||
{
|
],
|
||||||
path: 'sessions/:sessionId',
|
},
|
||||||
children: [
|
{
|
||||||
{ index: true, element: <Navigate to="chat" replace /> },
|
path: 'sessions/:sessionId',
|
||||||
{ path: ':tab', element: <WorkspaceTabRoute /> },
|
children: [
|
||||||
],
|
{ index: true, element: <Navigate to="chat" replace /> },
|
||||||
},
|
{ path: ':tab', element: <WorkspaceTabRoute /> },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -111,22 +111,20 @@ export function MainHeading() {
|
|||||||
return () => observer.disconnect();
|
return () => observer.disconnect();
|
||||||
}, [isMobile, updateScrollState]);
|
}, [isMobile, updateScrollState]);
|
||||||
|
|
||||||
if (!workspaceId) {
|
if (!workspaceId && !sessionId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleTabSelect = (nextTab: AppTab) => {
|
const handleTabSelect = (nextTab: AppTab) => {
|
||||||
// Preserve workspace/session context while switching only the active tab path segment.
|
// Preserve route context while switching only the active tab path segment.
|
||||||
const encodedWorkspaceId = encodeURIComponent(decodedWorkspaceId);
|
|
||||||
const encodedTab = encodeURIComponent(nextTab);
|
const encodedTab = encodeURIComponent(nextTab);
|
||||||
|
|
||||||
if (decodedSessionId) {
|
if (decodedSessionId) {
|
||||||
navigate(
|
navigate(`/sessions/${encodeURIComponent(decodedSessionId)}/${encodedTab}`);
|
||||||
`/workspaces/${encodedWorkspaceId}/sessions/${encodeURIComponent(decodedSessionId)}/${encodedTab}`,
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const encodedWorkspaceId = encodeURIComponent(decodedWorkspaceId);
|
||||||
navigate(`/workspaces/${encodedWorkspaceId}/${encodedTab}`);
|
navigate(`/workspaces/${encodedWorkspaceId}/${encodedTab}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -158,7 +156,7 @@ export function MainHeading() {
|
|||||||
{title}
|
{title}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="truncate text-[11px] leading-tight text-muted-foreground">
|
<div className="truncate text-[11px] leading-tight text-muted-foreground">
|
||||||
{decodedWorkspaceId}
|
{decodedWorkspaceId || t('mainContent.newSession')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -89,21 +89,19 @@ export function MobileNav() {
|
|||||||
}, [moreOpen]);
|
}, [moreOpen]);
|
||||||
|
|
||||||
const navigateToTab = (nextTab: AppTab) => {
|
const navigateToTab = (nextTab: AppTab) => {
|
||||||
if (!workspaceId) {
|
if (!workspaceId && !sessionId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const encodedWorkspaceId = encodeURIComponent(decodeValue(workspaceId));
|
|
||||||
const encodedTab = encodeURIComponent(nextTab);
|
const encodedTab = encodeURIComponent(nextTab);
|
||||||
const decodedSessionId = decodeValue(sessionId);
|
const decodedSessionId = decodeValue(sessionId);
|
||||||
|
|
||||||
if (decodedSessionId) {
|
if (decodedSessionId) {
|
||||||
navigate(
|
navigate(`/sessions/${encodeURIComponent(decodedSessionId)}/${encodedTab}`);
|
||||||
`/workspaces/${encodedWorkspaceId}/sessions/${encodeURIComponent(decodedSessionId)}/${encodedTab}`,
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const encodedWorkspaceId = encodeURIComponent(decodeValue(workspaceId));
|
||||||
navigate(`/workspaces/${encodedWorkspaceId}/${encodedTab}`);
|
navigate(`/workspaces/${encodedWorkspaceId}/${encodedTab}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
splitWorkspacesByStarred,
|
splitWorkspacesByStarred,
|
||||||
} from '@/components/refactored/sidebar/utils/workspaceTransforms';
|
} from '@/components/refactored/sidebar/utils/workspaceTransforms';
|
||||||
|
|
||||||
const SESSION_ROUTE_PATTERN = /^\/workspaces\/[^/]+\/sessions\/([^/]+)(?:\/[^/]+)?$/;
|
const SESSION_ROUTE_PATTERN = /^\/sessions\/([^/]+)(?:\/[^/]+)?$/;
|
||||||
|
|
||||||
const extractSessionIdFromPathname = (pathname: string): string | null => {
|
const extractSessionIdFromPathname = (pathname: string): string | null => {
|
||||||
const sessionMatch = pathname.match(SESSION_ROUTE_PATTERN);
|
const sessionMatch = pathname.match(SESSION_ROUTE_PATTERN);
|
||||||
@@ -120,7 +120,7 @@ export const useWorkspaces = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigate(
|
navigate(
|
||||||
`/workspaces/${encodeURIComponent(matchedWorkspace.workspaceId)}/sessions/${encodeURIComponent(sessionId)}`,
|
`/sessions/${encodeURIComponent(sessionId)}`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[navigate, workspaces],
|
[navigate, workspaces],
|
||||||
|
|||||||
Reference in New Issue
Block a user