页面结构修改
This commit is contained in:
1 parent
efc4d89fdf
commit
2e4bdf122e
21 files changed
+1266
-133
No files matched your search
+2
-107
@@ -3,27 +3,14 @@ import { Navigate, Route, Routes } from "react-router-dom";
|
||||
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
||||
|
||||
import { QueryClientProvider } from "@/components/query-client-provider";
|
||||
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
|
||||
import { PromptInputProvider } from "@/components/ai-elements/prompt-input";
|
||||
import { WorkspaceSidebar } from "@/components/workspace/workspace-sidebar";
|
||||
import { CommandPalette } from "@/components/workspace/command-palette";
|
||||
import { Toaster } from "sonner";
|
||||
import { I18nProvider } from "@/core/i18n/context";
|
||||
import { detectLocale } from "@/core/i18n/locale";
|
||||
import { SubtasksProvider } from "@/core/tasks/context";
|
||||
import { ArtifactsProvider } from "@/components/workspace/artifacts";
|
||||
|
||||
import { HashRouter, useLocation } from "react-router-dom";
|
||||
|
||||
import LandingPage from "./pages/LandingPage";
|
||||
import ChatsPage from "./pages/ChatsPage";
|
||||
import ChatPage from "./pages/ChatPage";
|
||||
import AgentsPage from "./pages/AgentsPage";
|
||||
import AgentChatPage from "./pages/AgentChatPage";
|
||||
import NewAgentPage from "./pages/NewAgentPage";
|
||||
import LoginPage from "./pages/LoginPage";
|
||||
import ScheduledTaskRunDetailPage from "./pages/ScheduledTaskRunDetailPage";
|
||||
import ScheduledTasksPage from "./pages/ScheduledTasksPage";
|
||||
import PageRoutes from "./pages/PageRoutes";
|
||||
import { NotFoundPage } from "./pages/NotFoundPage";
|
||||
|
||||
function AppProviders({ children }: { children: React.ReactNode }) {
|
||||
@@ -45,27 +32,6 @@ function AppProviders({ children }: { children: React.ReactNode }) {
|
||||
);
|
||||
}
|
||||
|
||||
function WorkspaceLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<SidebarProvider className="h-screen" defaultOpen>
|
||||
<WorkspaceSidebar />
|
||||
<SidebarInset className="min-w-0">{children}</SidebarInset>
|
||||
<CommandPalette />
|
||||
<Toaster position="top-center" />
|
||||
</SidebarProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function ChatRuntime({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<SubtasksProvider>
|
||||
<ArtifactsProvider>
|
||||
<PromptInputProvider>{children}</PromptInputProvider>
|
||||
</ArtifactsProvider>
|
||||
</SubtasksProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<HashRouter>
|
||||
@@ -75,78 +41,7 @@ export function App() {
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/login/:username" element={<LoginPage />} />
|
||||
<Route path="/landing" element={<LandingPage />} />
|
||||
<Route
|
||||
path="/workspace"
|
||||
element={<Navigate to="/workspace/chats/new" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/chats"
|
||||
element={
|
||||
<WorkspaceLayout>
|
||||
<ChatsPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/chats/:thread_id"
|
||||
element={
|
||||
<WorkspaceLayout>
|
||||
<ChatRuntime>
|
||||
<ChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/agents"
|
||||
element={
|
||||
<WorkspaceLayout>
|
||||
<AgentsPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/scheduled"
|
||||
element={<Navigate to="/workspace/scheduled/tasks" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/scheduled/tasks"
|
||||
element={
|
||||
<WorkspaceLayout>
|
||||
<ScheduledTasksPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/scheduled/runs/:run_id"
|
||||
element={
|
||||
<WorkspaceLayout>
|
||||
<ScheduledTaskRunDetailPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/agents/new"
|
||||
element={
|
||||
<WorkspaceLayout>
|
||||
<NewAgentPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/agents/:agent_id/chats"
|
||||
element={<Navigate to="/workspace/agents" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/agents/:agent_id/chats/:thread_id"
|
||||
element={
|
||||
<WorkspaceLayout>
|
||||
<ChatRuntime>
|
||||
<AgentChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route path="/page/*" element={<PageRoutes />} />
|
||||
<Route path="*" element={<NotFoundPage />} />
|
||||
</Routes>
|
||||
</AppProviders>
|
||||
|
||||
@@ -84,7 +84,7 @@ export function AgentCard({ agent }: AgentCardProps) {
|
||||
]);
|
||||
|
||||
function handleChat() {
|
||||
router.push(`/workspace/agents/${agent.id}/chats/new`);
|
||||
router.push(`/page/workspace/agents/${agent.id}/chats/new`);
|
||||
}
|
||||
|
||||
async function handleDelete() {
|
||||
|
||||
@@ -15,7 +15,7 @@ export function AgentGallery() {
|
||||
const router = useRouter();
|
||||
|
||||
const handleNewAgent = () => {
|
||||
router.push("/workspace/agents/new");
|
||||
router.push("/page/workspace/agents/new");
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -38,7 +38,7 @@ export function CommandPalette() {
|
||||
const [isMac, setIsMac] = useState(false);
|
||||
|
||||
const handleNewChat = useCallback(() => {
|
||||
router.push("/workspace/chats/new");
|
||||
router.push("/page/workspace/chats/new");
|
||||
setOpen(false);
|
||||
}, [router]);
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ export function WorkspaceHeader({ className }: { className?: string }) {
|
||||
<div className="flex items-center gap-2.5 px-2.5 py-3">
|
||||
<BrandMark />
|
||||
{env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true" ? (
|
||||
<Link href="/workspace/chats/new" className="min-w-0 flex-1 outline-none">
|
||||
<Link href="/page/workspace/chats/new" className="min-w-0 flex-1 outline-none">
|
||||
{titleBlock}
|
||||
</Link>
|
||||
) : (
|
||||
|
||||
@@ -20,18 +20,18 @@ export function WorkspaceNavChatList() {
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton
|
||||
isActive={pathname === "/workspace/chats/new"}
|
||||
isActive={pathname === "/page/workspace/chats/new"}
|
||||
asChild
|
||||
>
|
||||
<Link className="text-sidebar-foreground" href="/workspace/chats/new">
|
||||
<Link className="text-sidebar-foreground" href="/page/workspace/chats/new">
|
||||
<MessageSquarePlus />
|
||||
<span>{t.sidebar.newChat}</span>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton isActive={pathname === "/workspace/chats"} asChild>
|
||||
<Link className="text-sidebar-foreground" href="/workspace/chats">
|
||||
<SidebarMenuButton isActive={pathname === "/page/workspace/chats"} asChild>
|
||||
<Link className="text-sidebar-foreground" href="/page/workspace/chats">
|
||||
<MessagesSquare />
|
||||
<span>{t.sidebar.chats}</span>
|
||||
</Link>
|
||||
@@ -39,10 +39,10 @@ export function WorkspaceNavChatList() {
|
||||
</SidebarMenuItem>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton
|
||||
isActive={pathname.startsWith("/workspace/agents")}
|
||||
isActive={pathname.startsWith("/page/workspace/agents")}
|
||||
asChild
|
||||
>
|
||||
<Link className="text-sidebar-foreground" href="/workspace/agents">
|
||||
<Link className="text-sidebar-foreground" href="/page/workspace/agents">
|
||||
<BotIcon />
|
||||
<span>{t.sidebar.agents}</span>
|
||||
</Link>
|
||||
@@ -50,10 +50,10 @@ export function WorkspaceNavChatList() {
|
||||
</SidebarMenuItem>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton
|
||||
isActive={pathname === "/workspace/scheduled/tasks"}
|
||||
isActive={pathname === "/page/workspace/scheduled/tasks"}
|
||||
asChild
|
||||
>
|
||||
<Link className="text-sidebar-foreground" href="/workspace/scheduled/tasks">
|
||||
<Link className="text-sidebar-foreground" href="/page/workspace/scheduled/tasks">
|
||||
<ListChecks />
|
||||
<span>任务管理</span>
|
||||
</Link>
|
||||
|
||||
@@ -36,8 +36,8 @@ export function pathOfThread(
|
||||
: pickAgentRef(thread.context, thread.metadata);
|
||||
|
||||
return agentRef
|
||||
? `/workspace/agents/${encodeURIComponent(agentRef)}/chats/${threadId}`
|
||||
: `/workspace/chats/${threadId}`;
|
||||
? `/page/workspace/agents/${encodeURIComponent(agentRef)}/chats/${threadId}`
|
||||
: `/page/workspace/chats/${threadId}`;
|
||||
}
|
||||
|
||||
export function textOfMessage(message: Message) {
|
||||
|
||||
@@ -66,7 +66,7 @@ export default function AgentChatPage() {
|
||||
history.replaceState(
|
||||
null,
|
||||
"",
|
||||
`${window.location.pathname}${window.location.search}#/workspace/agents/${agent_id}/chats/${createdThreadId}`,
|
||||
`${window.location.pathname}${window.location.search}#/page/workspace/agents/${agent_id}/chats/${createdThreadId}`,
|
||||
);
|
||||
},
|
||||
onFinish: (state) => {
|
||||
@@ -137,7 +137,7 @@ export default function AgentChatPage() {
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
router.push(`/workspace/agents/${agent_id}/chats/new`);
|
||||
router.push(`/page/workspace/agents/${agent_id}/chats/new`);
|
||||
}}
|
||||
>
|
||||
<PlusSquare /> {t.agents.newChat}
|
||||
|
||||
@@ -64,7 +64,7 @@ export default function ChatPage() {
|
||||
history.replaceState(
|
||||
null,
|
||||
"",
|
||||
`${window.location.pathname}${window.location.search}#/workspace/chats/${createdThreadId}`,
|
||||
`${window.location.pathname}${window.location.search}#/page/workspace/chats/${createdThreadId}`,
|
||||
);
|
||||
},
|
||||
onFinish: (state) => {
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function LoginPage() {
|
||||
}
|
||||
setStoredAuth(auth);
|
||||
setStatus("success");
|
||||
router.replace("/workspace/chats/new");
|
||||
router.replace("/page/workspace/chats/new");
|
||||
} catch (error) {
|
||||
if (cancelled) {
|
||||
return;
|
||||
|
||||
@@ -317,7 +317,7 @@ export default function NewAgentPage() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
onClick={() => router.push("/workspace/agents")}
|
||||
onClick={() => router.push("/page/workspace/agents")}
|
||||
>
|
||||
<ArrowLeftIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
@@ -478,7 +478,7 @@ export default function NewAgentPage() {
|
||||
<Button
|
||||
onClick={() =>
|
||||
router.push(
|
||||
`/workspace/agents/${agentId}/chats/new`,
|
||||
`/page/workspace/agents/${agentId}/chats/new`,
|
||||
)
|
||||
}
|
||||
>
|
||||
@@ -486,7 +486,7 @@ export default function NewAgentPage() {
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => router.push("/workspace/agents")}
|
||||
onClick={() => router.push("/page/workspace/agents")}
|
||||
>
|
||||
{t.agents.backToGallery}
|
||||
</Button>
|
||||
|
||||
@@ -10,7 +10,7 @@ export function NotFoundPage() {
|
||||
dedicated migration pass.
|
||||
</p>
|
||||
<Link
|
||||
to="/workspace/chats/new"
|
||||
to="/page/workspace/chats/new"
|
||||
className="bg-primary text-primary-foreground rounded-md px-4 py-2 text-sm font-medium"
|
||||
>
|
||||
Open workspace
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Navigate, Route, Routes } from "react-router-dom";
|
||||
|
||||
import WorkspaceRoutes from "./WorkspaceRoutes";
|
||||
|
||||
// 根路由容器,统一承接 /page/* 下的所有子系统路由
|
||||
export default function PageRoutes() {
|
||||
return (
|
||||
<Routes>
|
||||
<Route index element={<Navigate to="workspace" replace />} />
|
||||
|
||||
{/* 现有系统:DeerFlow Workspace */}
|
||||
<Route path="workspace/*" element={<WorkspaceRoutes />} />
|
||||
|
||||
{/* TODO: 引入外部系统路由
|
||||
import AnotherSystemRoutes from "外部系统路径";
|
||||
<Route path="other/*" element={<AnotherSystemRoutes />} />
|
||||
*/}
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export default function ScheduledChatPage() {
|
||||
const { data, isLoading, error } = useSchedulerThread();
|
||||
|
||||
if (data?.thread_id) {
|
||||
return <Navigate to={`/workspace/chats/${data.thread_id}`} replace />;
|
||||
return <Navigate to={`/page/workspace/chats/${data.thread_id}`} replace />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -174,7 +174,7 @@ export default function ScheduledTaskRunDetailPage() {
|
||||
try {
|
||||
await actions.removeRun.mutateAsync(run.id);
|
||||
toast.success("执行记录已删除");
|
||||
navigate("/workspace/scheduled/tasks");
|
||||
navigate("/page/workspace/scheduled/tasks");
|
||||
} catch (error) {
|
||||
toast.error(error instanceof Error ? error.message : "删除失败");
|
||||
}
|
||||
@@ -198,7 +198,7 @@ export default function ScheduledTaskRunDetailPage() {
|
||||
<ChevronDown className={cn("size-3 transition-transform", showMeta && "rotate-180")} />
|
||||
执行信息
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="h-7 px-2 text-xs" onClick={() => navigate("/workspace/scheduled/tasks")}>
|
||||
<Button variant="ghost" size="sm" className="h-7 px-2 text-xs" onClick={() => navigate("/page/workspace/scheduled/tasks")}>
|
||||
<ListChecks className="size-3" />
|
||||
返回记录
|
||||
</Button>
|
||||
|
||||
@@ -686,7 +686,7 @@ export default function ScheduledTasksPage() {
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => navigate(`/workspace/scheduled/runs/${run.id}`)}
|
||||
onClick={() => navigate(`/page/workspace/scheduled/runs/${run.id}`)}
|
||||
>
|
||||
<Eye className="size-4" />
|
||||
查看结果
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { Navigate, Route, Routes } from "react-router-dom";
|
||||
|
||||
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
|
||||
import { PromptInputProvider } from "@/components/ai-elements/prompt-input";
|
||||
import { WorkspaceSidebar } from "@/components/workspace/workspace-sidebar";
|
||||
import { CommandPalette } from "@/components/workspace/command-palette";
|
||||
import { Toaster } from "sonner";
|
||||
import { SubtasksProvider } from "@/core/tasks/context";
|
||||
import { ArtifactsProvider } from "@/components/workspace/artifacts";
|
||||
|
||||
import ChatsPage from "./ChatsPage";
|
||||
import ChatPage from "./ChatPage";
|
||||
import AgentsPage from "./AgentsPage";
|
||||
import AgentChatPage from "./AgentChatPage";
|
||||
import NewAgentPage from "./NewAgentPage";
|
||||
import ScheduledTaskRunDetailPage from "./ScheduledTaskRunDetailPage";
|
||||
import ScheduledTasksPage from "./ScheduledTasksPage";
|
||||
|
||||
function WorkspaceLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<SidebarProvider className="h-screen" defaultOpen>
|
||||
<WorkspaceSidebar />
|
||||
<SidebarInset className="min-w-0">{children}</SidebarInset>
|
||||
<CommandPalette />
|
||||
<Toaster position="top-center" />
|
||||
</SidebarProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function ChatRuntime({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<SubtasksProvider>
|
||||
<ArtifactsProvider>
|
||||
<PromptInputProvider>{children}</PromptInputProvider>
|
||||
</ArtifactsProvider>
|
||||
</SubtasksProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default function WorkspaceRoutes() {
|
||||
return (
|
||||
<Routes>
|
||||
<Route index element={<Navigate to="chats/new" replace />} />
|
||||
<Route
|
||||
path="chats"
|
||||
element={<WorkspaceLayout><ChatsPage /></WorkspaceLayout>}
|
||||
/>
|
||||
<Route
|
||||
path="chats/:thread_id"
|
||||
element={
|
||||
<WorkspaceLayout>
|
||||
<ChatRuntime>
|
||||
<ChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="agents"
|
||||
element={<WorkspaceLayout><AgentsPage /></WorkspaceLayout>}
|
||||
/>
|
||||
<Route
|
||||
path="agents/new"
|
||||
element={<WorkspaceLayout><NewAgentPage /></WorkspaceLayout>}
|
||||
/>
|
||||
<Route
|
||||
path="agents/:agent_id/chats"
|
||||
element={<Navigate to="/page/workspace/agents" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="agents/:agent_id/chats/:thread_id"
|
||||
element={
|
||||
<WorkspaceLayout>
|
||||
<ChatRuntime>
|
||||
<AgentChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="scheduled"
|
||||
element={<Navigate to="/page/workspace/scheduled/tasks" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="scheduled/tasks"
|
||||
element={<WorkspaceLayout><ScheduledTasksPage /></WorkspaceLayout>}
|
||||
/>
|
||||
<Route
|
||||
path="scheduled/runs/:run_id"
|
||||
element={<WorkspaceLayout><ScheduledTaskRunDetailPage /></WorkspaceLayout>}
|
||||
/>
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user