Merge branch 'master' of http://192.168.0.200/knowledge-base-bj/deerflow-server into gzy_iframedf
This commit is contained in:
commit
5f88efb2c9
76 files changed
+11989
-4307
No files matched your search
@@ -1,33 +1,44 @@
|
||||
"use client";
|
||||
'use client';
|
||||
|
||||
import { useParams, useRouter, useSearchParams } from "next/navigation";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useParams, useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { loginByUsername } from "@/core/auth/api";
|
||||
import { setStoredAuth } from "@/core/auth";
|
||||
import { useTheme } from '@/contexts/ThemeContext';
|
||||
import { loginByUsername } from '@/core/auth/api';
|
||||
import { setStoredAuth } from '@/core/auth';
|
||||
import {
|
||||
persistExternalLoginParams,
|
||||
resolveThemeFromQuery,
|
||||
} from '@/core/auth/external-login';
|
||||
import {
|
||||
GENERAL_QA_ROUTE,
|
||||
loginByYUserId,
|
||||
persistToolsToken,
|
||||
} from '@/core/auth/yuser-login';
|
||||
import {
|
||||
isSidebarEnabledFromSearch,
|
||||
persistSidebarEnabled,
|
||||
} from "@/core/page-layout/sidebar-enabled";
|
||||
} from '@/core/page-layout/sidebar-enabled';
|
||||
|
||||
const DEFAULT_USERNAME = "guest";
|
||||
const IFRAME_LOGIN_SOURCE = "iframe";
|
||||
const DEFAULT_REDIRECT_PATH = "/page/workspace/chats/new";
|
||||
const IFRAME_REDIRECT_PATH = "/page/workspace/chats_iframe/new";
|
||||
const DEFAULT_USERNAME = 'guest';
|
||||
const IFRAME_LOGIN_SOURCE = 'iframe';
|
||||
const DEFAULT_REDIRECT_PATH = '/page/workspace/chats/new';
|
||||
const IFRAME_REDIRECT_PATH = '/page/workspace/chats_iframe/new';
|
||||
|
||||
type LoginStatus = "loading" | "success" | "error";
|
||||
type LoginStatus = 'loading' | 'success' | 'error';
|
||||
|
||||
export default function LoginPage() {
|
||||
const { username } = useParams<{ username?: string }>();
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const { setTheme } = useTheme();
|
||||
const sidebarEnabled = useMemo(
|
||||
() => isSidebarEnabledFromSearch(searchParams.toString()),
|
||||
[searchParams],
|
||||
);
|
||||
const redirectPath = useMemo(
|
||||
() =>
|
||||
searchParams.get("from") === IFRAME_LOGIN_SOURCE
|
||||
searchParams.get('from') === IFRAME_LOGIN_SOURCE
|
||||
? IFRAME_REDIRECT_PATH
|
||||
: DEFAULT_REDIRECT_PATH,
|
||||
[searchParams],
|
||||
@@ -36,31 +47,64 @@ export default function LoginPage() {
|
||||
const raw = username?.trim();
|
||||
return raw && raw.length > 0 ? raw : DEFAULT_USERNAME;
|
||||
}, [username]);
|
||||
const [status, setStatus] = useState<LoginStatus>("loading");
|
||||
const [errorMessage, setErrorMessage] = useState<string>("");
|
||||
// 外部跳转参数:theme 直接调 setTheme;ticket/userId/env 持久化到 localStorage
|
||||
const yUserId = searchParams.get('yUserId')?.trim() ?? '';
|
||||
const toolToken = searchParams.get('token')?.trim() ?? '';
|
||||
const externalParams = useMemo(
|
||||
() => ({
|
||||
theme: searchParams.get('theme') ?? '',
|
||||
ticket: searchParams.get('ticket') ?? '',
|
||||
userId: searchParams.get('userId') ?? '',
|
||||
env: searchParams.get('env') ?? '',
|
||||
}),
|
||||
[searchParams],
|
||||
);
|
||||
const [status, setStatus] = useState<LoginStatus>('loading');
|
||||
const [errorMessage, setErrorMessage] = useState<string>('');
|
||||
|
||||
// 主题切换:theme=dark-blue → 深色,其他值或缺省 → 浅色
|
||||
useEffect(() => {
|
||||
if (!externalParams.theme) return;
|
||||
setTheme(resolveThemeFromQuery(externalParams.theme));
|
||||
}, [externalParams.theme, setTheme]);
|
||||
|
||||
// ticket / userId / env 持久化(与 login 请求并行做,互不阻塞)
|
||||
useEffect(() => {
|
||||
persistExternalLoginParams({
|
||||
ticket: externalParams.ticket,
|
||||
userId: externalParams.userId,
|
||||
env: externalParams.env,
|
||||
});
|
||||
}, [externalParams.ticket, externalParams.userId, externalParams.env]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
||||
async function runLogin() {
|
||||
setStatus("loading");
|
||||
setErrorMessage("");
|
||||
setStatus('loading');
|
||||
setErrorMessage('');
|
||||
try {
|
||||
if (yUserId) {
|
||||
await loginByYUserId(yUserId, toolToken || null);
|
||||
} else if (toolToken) {
|
||||
persistToolsToken(toolToken);
|
||||
}
|
||||
|
||||
const auth = await loginByUsername(resolvedUsername);
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
setStoredAuth(auth);
|
||||
persistSidebarEnabled(sidebarEnabled);
|
||||
setStatus("success");
|
||||
router.replace(redirectPath);
|
||||
setStatus('success');
|
||||
router.replace(yUserId ? GENERAL_QA_ROUTE : redirectPath);
|
||||
} catch (error) {
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
setStatus("error");
|
||||
setStatus('error');
|
||||
setErrorMessage(
|
||||
error instanceof Error ? error.message : "Login request failed.",
|
||||
error instanceof Error ? error.message : 'Login request failed.',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -69,19 +113,25 @@ export default function LoginPage() {
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [redirectPath, resolvedUsername, router, sidebarEnabled]);
|
||||
}, [
|
||||
redirectPath,
|
||||
resolvedUsername,
|
||||
router,
|
||||
sidebarEnabled,
|
||||
yUserId,
|
||||
toolToken,
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-background px-6">
|
||||
<div className="w-full max-w-lg rounded-xl border bg-card p-6 shadow-sm">
|
||||
<h1 className="text-xl font-semibold">正在进入智能体模式</h1>
|
||||
{status === "error" && (
|
||||
{status === 'error' && (
|
||||
<p className="mt-4 text-sm text-red-600">
|
||||
登录失败:{errorMessage || "未知错误"}
|
||||
登录失败:{errorMessage || '未知错误'}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,16 @@ function PageLayout() {
|
||||
)
|
||||
)}
|
||||
<main
|
||||
className={`flex-1 overflow-hidden transition-[padding] duration-300 ${
|
||||
!sidebarEnabled ? "" : collapsed ? "pl-16" : "pl-64"
|
||||
className={`flex-1 overflow-hidden ${
|
||||
!sidebarEnabled
|
||||
? ""
|
||||
: isDark
|
||||
// 深色 sidebar:展开 118px(10 + 98 + 10 gap),收起 = 0 sidebar 完全消失,
|
||||
// 只剩左下角浮动按钮(fixed,叠在 main 上不影响布局)。
|
||||
// 不加 transition:transition + sidebar 立刻 unmount 不同步会抽搐
|
||||
? (collapsed ? "pl-0" : "pl-[118px]")
|
||||
// 浅色仍保留过渡动画(pl-16 ↔ pl-64 平滑收展)
|
||||
: `transition-[padding] duration-300 ${collapsed ? "pl-16" : "pl-64"}`
|
||||
}`}
|
||||
>
|
||||
<Routes>
|
||||
@@ -50,6 +58,7 @@ function PageLayout() {
|
||||
pageSidebarHidden={!sidebarEnabled}
|
||||
headerHidden={!sidebarEnabled}
|
||||
compactWorkspaceSidebar={sidebarEnabled}
|
||||
pageSidebarDark={isDark}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
import type { CSSProperties, ReactNode } from "react";
|
||||
import { Navigate, Route, Routes } from "react-router-dom";
|
||||
import type { CSSProperties, ReactNode } from 'react';
|
||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||
|
||||
import { getStoredAuth } from "@/core/auth";
|
||||
import { getStoredAuth } from '@/core/auth';
|
||||
|
||||
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 { 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 { RouteBaseProvider } from "@/core/route-base";
|
||||
import { RouteBaseProvider } from '@/core/route-base';
|
||||
|
||||
import ChatsPage from "./ChatsPage";
|
||||
import ChatPage from "./ChatPage";
|
||||
import IframeChatPage from "./IframeChatPage";
|
||||
import AgentsPage from "./AgentsPage";
|
||||
import AgentChatPage from "./AgentChatPage";
|
||||
import NewAgentPage from "./NewAgentPage";
|
||||
import AdminAgentsPage from "./AdminAgentsPage";
|
||||
import AdminScheduledTasksPage from "./AdminScheduledTasksPage";
|
||||
import AdminSkillsPage from "./AdminSkillsPage";
|
||||
import ScheduledTaskRunDetailPage from "./ScheduledTaskRunDetailPage";
|
||||
import ScheduledTasksPage from "./ScheduledTasksPage";
|
||||
import LlmMetricsPage from "./LlmMetricsPage";
|
||||
import MemoryPage from "./MemoryPage";
|
||||
import PromptPrefixSettingsPage from "./PromptPrefixSettingsPage";
|
||||
import PrivateSquareSettingsPage from "./PrivateSquareSettingsPage";
|
||||
import SkillEvolutionPage from "./SkillEvolutionPage";
|
||||
import SkillsPage from "./SkillsPage";
|
||||
import UsersPage from "./UsersPage";
|
||||
import AdminUserActivityPage from "./AdminUserActivityPage";
|
||||
import AdminMemoryPage from "./AdminMemoryPage";
|
||||
import AdminUserHubPage from "./AdminUserHubPage";
|
||||
import TagsPage from "./TagsPage";
|
||||
import RecommendedQuestionsPage from "./RecommendedQuestionsPage";
|
||||
import AIWritingPage from "@/open-canvas/pages/AIWritingPage";
|
||||
import StudioNotebooksPage from "./StudioNotebooksPage";
|
||||
import StudioNotebookDetailPage from "./StudioNotebookDetailPage";
|
||||
import RoundtablePlanningPage from "@/roundtable-planning/pages/RoundtablePlanningPage";
|
||||
import "@/roundtable-planning/styles/roundtable-planning.css";
|
||||
import { cn } from "@/lib/utils";
|
||||
import ChatsPage from './ChatsPage';
|
||||
import ChatPage from './ChatPage';
|
||||
import IframeChatPage from './IframeChatPage';
|
||||
import AgentsPage from './AgentsPage';
|
||||
import AgentChatPage from './AgentChatPage';
|
||||
import NewAgentPage from './NewAgentPage';
|
||||
import AdminAgentsPage from './AdminAgentsPage';
|
||||
import AdminScheduledTasksPage from './AdminScheduledTasksPage';
|
||||
import AdminSkillsPage from './AdminSkillsPage';
|
||||
import ScheduledTaskRunDetailPage from './ScheduledTaskRunDetailPage';
|
||||
import ScheduledTasksPage from './ScheduledTasksPage';
|
||||
import LlmMetricsPage from './LlmMetricsPage';
|
||||
import MemoryPage from './MemoryPage';
|
||||
import PromptPrefixSettingsPage from './PromptPrefixSettingsPage';
|
||||
import PrivateSquareSettingsPage from './PrivateSquareSettingsPage';
|
||||
import SkillEvolutionPage from './SkillEvolutionPage';
|
||||
import SkillsPage from './SkillsPage';
|
||||
import UsersPage from './UsersPage';
|
||||
import AdminUserActivityPage from './AdminUserActivityPage';
|
||||
import AdminMemoryPage from './AdminMemoryPage';
|
||||
import AdminUserHubPage from './AdminUserHubPage';
|
||||
import TagsPage from './TagsPage';
|
||||
import RecommendedQuestionsPage from './RecommendedQuestionsPage';
|
||||
import AIWritingPage from '@/open-canvas/pages/AIWritingPage';
|
||||
import StudioNotebooksPage from './StudioNotebooksPage';
|
||||
import StudioNotebookDetailPage from './StudioNotebookDetailPage';
|
||||
import RoundtablePlanningPage from '@/roundtable-planning/pages/RoundtablePlanningPage';
|
||||
import '@/roundtable-planning/styles/roundtable-planning.css';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
export function WorkspaceLayout({
|
||||
children,
|
||||
@@ -51,6 +51,7 @@ export function WorkspaceLayout({
|
||||
compactWorkspaceSidebar = false,
|
||||
wrapperOverflowHidden = false,
|
||||
insetOverflowHidden = false,
|
||||
pageSidebarDark = false,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
pageSidebarCollapsed: boolean;
|
||||
@@ -59,23 +60,33 @@ export function WorkspaceLayout({
|
||||
compactWorkspaceSidebar?: boolean;
|
||||
wrapperOverflowHidden?: boolean;
|
||||
insetOverflowHidden?: boolean;
|
||||
pageSidebarDark?: boolean;
|
||||
}) {
|
||||
const pageSidebarWidth = pageSidebarHidden
|
||||
? "0rem"
|
||||
: pageSidebarCollapsed
|
||||
? "4rem"
|
||||
: "16rem";
|
||||
? '0rem'
|
||||
: pageSidebarDark
|
||||
? // dark page sidebar:
|
||||
// 展开: 视觉右边界 108px(外框 98 + 内层 translateX 10)+ 10px gap = 118px
|
||||
// 收起: sidebar 主体完全消失(连同其占据的宽度),workspace 内容铺到屏幕左边;
|
||||
// 左下角浮动按钮是 fixed,叠在主内容上不影响 layout
|
||||
// 与 PageRoutes.tsx 的 main pl-[118px] / pl-0 保持一致
|
||||
pageSidebarCollapsed
|
||||
? '0rem'
|
||||
: '118px'
|
||||
: pageSidebarCollapsed
|
||||
? '4rem'
|
||||
: '16rem';
|
||||
|
||||
return (
|
||||
<SidebarProvider
|
||||
className={[
|
||||
"h-full w-full [&_[data-slot=sidebar-container]]:left-[var(--page-sidebar-width)]",
|
||||
wrapperOverflowHidden ? "overflow-hidden" : "overflow-x-hidden",
|
||||
].join(" ")}
|
||||
'h-full w-full [&_[data-slot=sidebar-container]]:left-[var(--page-sidebar-width)]',
|
||||
wrapperOverflowHidden ? 'overflow-hidden' : 'overflow-x-hidden',
|
||||
].join(' ')}
|
||||
style={
|
||||
{
|
||||
"--page-sidebar-width": pageSidebarWidth,
|
||||
"--header-height": headerHidden ? "0rem" : "4rem",
|
||||
'--page-sidebar-width': pageSidebarWidth,
|
||||
'--header-height': headerHidden ? '0rem' : '4rem',
|
||||
} as CSSProperties
|
||||
}
|
||||
// Keep the fixed workspace sidebar aligned to the outer page sidebar width.
|
||||
@@ -85,7 +96,7 @@ export function WorkspaceLayout({
|
||||
>
|
||||
<WorkspaceSidebar compactChrome={compactWorkspaceSidebar} />
|
||||
<SidebarInset
|
||||
className={cn("min-w-0", insetOverflowHidden && "overflow-hidden")}
|
||||
className={cn('min-w-0', insetOverflowHidden && 'overflow-hidden')}
|
||||
>
|
||||
{children}
|
||||
</SidebarInset>
|
||||
@@ -110,302 +121,307 @@ export default function WorkspaceRoutes({
|
||||
pageSidebarHidden = false,
|
||||
headerHidden = false,
|
||||
compactWorkspaceSidebar = false,
|
||||
pageSidebarDark = false,
|
||||
}: {
|
||||
pageSidebarCollapsed?: boolean;
|
||||
pageSidebarHidden?: boolean;
|
||||
headerHidden?: boolean;
|
||||
compactWorkspaceSidebar?: boolean;
|
||||
pageSidebarDark?: boolean;
|
||||
}) {
|
||||
const layoutProps = {
|
||||
pageSidebarCollapsed,
|
||||
pageSidebarHidden,
|
||||
headerHidden,
|
||||
compactWorkspaceSidebar,
|
||||
pageSidebarDark,
|
||||
};
|
||||
|
||||
return (
|
||||
<RouteBaseProvider value="/page/workspace">
|
||||
<Routes>
|
||||
<Route index element={<Navigate to="chats/new" replace />} />
|
||||
<Route
|
||||
path="chats"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ChatsPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="chats/:thread_id"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ChatRuntime>
|
||||
<ChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="chats_iframe/new"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ChatRuntime>
|
||||
<IframeChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="chats_iframe/:thread_id"
|
||||
element={
|
||||
<WorkspaceLayout
|
||||
{...layoutProps}
|
||||
wrapperOverflowHidden
|
||||
insetOverflowHidden
|
||||
>
|
||||
<ChatRuntime>
|
||||
<IframeChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="agents"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AgentsPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="agents/new"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<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 {...layoutProps}>
|
||||
<ChatRuntime>
|
||||
<AgentChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="skills"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<SkillsPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="skills/evolution"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<SkillEvolutionPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="memory"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<MemoryPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="ai-writing"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AIWritingPage hideAdvancedFields />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="studio/notebooks"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<StudioNotebooksPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="studio/notebooks/:notebookId"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ChatRuntime>
|
||||
<StudioNotebookDetailPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="roundtable"
|
||||
element={<Navigate to="/page/workspace/roundtable/planning" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="roundtable/planning"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ChatRuntime>
|
||||
<RoundtablePlanningPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="scheduled"
|
||||
element={<Navigate to="/page/workspace/scheduled/tasks" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="scheduled/tasks"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ScheduledTasksPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="scheduled/runs/:run_id"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ScheduledTaskRunDetailPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
{/* Unified admin user hub */}
|
||||
<Route
|
||||
path="admin"
|
||||
element={
|
||||
getStoredAuth()?.system_role === "admin" ? (
|
||||
<WorkspaceLayout {...layoutProps} pageSidebarHidden>
|
||||
<AdminUserHubPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
{/* Legacy redirects */}
|
||||
<Route
|
||||
path="admin/users"
|
||||
element={<Navigate to="/page/workspace/admin" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="admin/user-activity"
|
||||
element={<Navigate to="/page/workspace/admin" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="admin/memory"
|
||||
element={<Navigate to="/page/workspace/admin" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="admin/scheduled-tasks"
|
||||
element={
|
||||
getStoredAuth()?.system_role === "admin" ? (
|
||||
<Routes>
|
||||
<Route index element={<Navigate to="chats/new" replace />} />
|
||||
<Route
|
||||
path="chats"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AdminScheduledTasksPage />
|
||||
<ChatsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="admin/agents"
|
||||
element={
|
||||
getStoredAuth()?.system_role === "admin" ? (
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="chats/:thread_id"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AdminAgentsPage />
|
||||
<ChatRuntime>
|
||||
<ChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="admin/skills"
|
||||
element={
|
||||
getStoredAuth()?.system_role === "admin" ? (
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="chats_iframe/new"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AdminSkillsPage />
|
||||
<ChatRuntime>
|
||||
<IframeChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="admin/tags"
|
||||
element={
|
||||
getStoredAuth()?.system_role === "admin" ? (
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="chats_iframe/:thread_id"
|
||||
element={
|
||||
<WorkspaceLayout
|
||||
{...layoutProps}
|
||||
wrapperOverflowHidden
|
||||
insetOverflowHidden
|
||||
>
|
||||
<ChatRuntime>
|
||||
<IframeChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="agents"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<TagsPage />
|
||||
<AgentsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="settings/recommended-questions"
|
||||
element={
|
||||
getStoredAuth()?.system_role === "admin" ? (
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="agents/new"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<RecommendedQuestionsPage />
|
||||
<NewAgentPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="settings/prompt-prefix"
|
||||
element={
|
||||
getStoredAuth()?.system_role === "admin" ? (
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="agents/:agent_id/chats"
|
||||
element={<Navigate to="/page/workspace/agents" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="agents/:agent_id/chats/:thread_id"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<PromptPrefixSettingsPage />
|
||||
<ChatRuntime>
|
||||
<AgentChatPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="settings/private-square"
|
||||
element={
|
||||
getStoredAuth()?.system_role === "admin" ? (
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="skills"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<PrivateSquareSettingsPage />
|
||||
<SkillsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="settings/llm-metrics"
|
||||
element={
|
||||
getStoredAuth()?.system_role === "admin" ? (
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="skills/evolution"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<LlmMetricsPage />
|
||||
<SkillEvolutionPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="memory"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<MemoryPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="ai-writing"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AIWritingPage hideAdvancedFields />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="studio/notebooks"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<StudioNotebooksPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="studio/notebooks/:notebookId"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ChatRuntime>
|
||||
<StudioNotebookDetailPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="roundtable"
|
||||
element={
|
||||
<Navigate to="/page/workspace/roundtable/planning" replace />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="roundtable/planning"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ChatRuntime>
|
||||
<RoundtablePlanningPage />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="scheduled"
|
||||
element={<Navigate to="/page/workspace/scheduled/tasks" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="scheduled/tasks"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ScheduledTasksPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="scheduled/runs/:run_id"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ScheduledTaskRunDetailPage />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
{/* Unified admin user hub */}
|
||||
<Route
|
||||
path="admin"
|
||||
element={
|
||||
getStoredAuth()?.system_role === 'admin' ? (
|
||||
<WorkspaceLayout {...layoutProps} pageSidebarHidden>
|
||||
<AdminUserHubPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
{/* Legacy redirects */}
|
||||
<Route
|
||||
path="admin/users"
|
||||
element={<Navigate to="/page/workspace/admin" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="admin/user-activity"
|
||||
element={<Navigate to="/page/workspace/admin" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="admin/memory"
|
||||
element={<Navigate to="/page/workspace/admin" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="admin/scheduled-tasks"
|
||||
element={
|
||||
getStoredAuth()?.system_role === 'admin' ? (
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AdminScheduledTasksPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="admin/agents"
|
||||
element={
|
||||
getStoredAuth()?.system_role === 'admin' ? (
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AdminAgentsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="admin/skills"
|
||||
element={
|
||||
getStoredAuth()?.system_role === 'admin' ? (
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AdminSkillsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="admin/tags"
|
||||
element={
|
||||
getStoredAuth()?.system_role === 'admin' ? (
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<TagsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="settings/recommended-questions"
|
||||
element={
|
||||
getStoredAuth()?.system_role === 'admin' ? (
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<RecommendedQuestionsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="settings/prompt-prefix"
|
||||
element={
|
||||
getStoredAuth()?.system_role === 'admin' ? (
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<PromptPrefixSettingsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="settings/private-square"
|
||||
element={
|
||||
getStoredAuth()?.system_role === 'admin' ? (
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<PrivateSquareSettingsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="settings/llm-metrics"
|
||||
element={
|
||||
getStoredAuth()?.system_role === 'admin' ? (
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<LlmMetricsPage />
|
||||
</WorkspaceLayout>
|
||||
) : (
|
||||
<Navigate to="/page/workspace/chats/new" replace />
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</RouteBaseProvider>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user