fix: polish compact workspace controls
This commit is contained in:
1 parent
eb61b332a2
commit
210cb5117f
13 files changed
+516
-274
No files matched your search
@@ -4,7 +4,7 @@ import { BotIcon, PlusSquare } from "lucide-react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useRouteBase } from "@/core/route-base";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
|
||||
|
||||
import type { PromptInputMessage } from "@/components/ai-elements/prompt-input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -65,6 +65,7 @@ export default function AgentChatPage({
|
||||
taskBind,
|
||||
autoStartWhenPurposeEmpty,
|
||||
showAgentList,
|
||||
compactAppearanceActions,
|
||||
}: {
|
||||
/** 当作为「通用问答右侧嵌入」渲染时由父组件传入的 agent id(替代路由参数)。
|
||||
* 传入即视为嵌入态:路由仍停留在 /chats/new,仅右侧问答区换成该智能体的对话。 */
|
||||
@@ -85,6 +86,8 @@ export default function AgentChatPage({
|
||||
/** 是否在最左侧展示「智能体列表」栏(顶部下拉切换 我的/广场,点击进入该智能体对话)。
|
||||
* 仅独立的智能体问答整页开启;任务工作区 / 模块页 / 嵌入态不传(各有自己的左栏)。 */
|
||||
showAgentList?: boolean;
|
||||
/** 简洁模式下,挂到右侧智能体信息面板收起按钮左侧的外观控件。 */
|
||||
compactAppearanceActions?: ReactNode;
|
||||
} = {}) {
|
||||
const routeBase = useRouteBase();
|
||||
const { t } = useI18n();
|
||||
@@ -589,6 +592,7 @@ export default function AgentChatPage({
|
||||
onAskQuestion={(text) => handleSubmit({ text, files: [] })}
|
||||
defaultCollapsed={taskCtxOn}
|
||||
showRecentChats={!taskCtxOn}
|
||||
compactAppearanceActions={compactAppearanceActions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -15,6 +15,10 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { ImportConversationsDialog } from "@/components/workspace/thread-share-dialogs";
|
||||
import {
|
||||
LayoutModeSwitcher,
|
||||
ThemeSwitcher,
|
||||
} from "@/components/workspace/appearance-controls";
|
||||
import {
|
||||
WorkspaceBody,
|
||||
WorkspaceContainer,
|
||||
@@ -40,7 +44,11 @@ import { cn } from "@/lib/utils";
|
||||
|
||||
const PAGE_SIZE = 20;
|
||||
|
||||
export default function ChatsPage() {
|
||||
export default function ChatsPage({
|
||||
compactChrome = false,
|
||||
}: {
|
||||
compactChrome?: boolean;
|
||||
}) {
|
||||
const pathOfThread = usePathOfThread();
|
||||
const { t } = useI18n();
|
||||
const { toggle: togglePin } = useToggleThreadPin();
|
||||
@@ -171,7 +179,16 @@ export default function ChatsPage() {
|
||||
|
||||
return (
|
||||
<WorkspaceContainer>
|
||||
<WorkspaceHeader></WorkspaceHeader>
|
||||
<WorkspaceHeader
|
||||
rightActions={
|
||||
compactChrome ? (
|
||||
<div className="flex items-center gap-1">
|
||||
<ThemeSwitcher tone="content" />
|
||||
<LayoutModeSwitcher tone="content" />
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
<WorkspaceBody>
|
||||
<div className="flex size-full flex-col">
|
||||
<header className="flex shrink-0 flex-col items-center gap-3 pt-8">
|
||||
|
||||
@@ -43,6 +43,10 @@ import {
|
||||
WorkspaceContainer,
|
||||
WorkspaceHeader,
|
||||
} from "@/components/workspace/workspace-container";
|
||||
import {
|
||||
LayoutModeSwitcher,
|
||||
ThemeSwitcher,
|
||||
} from "@/components/workspace/appearance-controls";
|
||||
import { TagChipList } from "@/components/workspace/tags/tag-chip";
|
||||
import { TagPickerDialog } from "@/components/workspace/tags/tag-picker-dialog";
|
||||
import { TagSearchBar } from "@/components/workspace/tags/tag-search-bar";
|
||||
@@ -144,7 +148,11 @@ const SCHEDULED_TASK_TEXTAREA_CLASS =
|
||||
const DESCRIPTION_TEXTAREA_ROWS = 4;
|
||||
const PROMPT_TEXTAREA_ROWS = 10;
|
||||
|
||||
export default function ScheduledTasksPage() {
|
||||
export default function ScheduledTasksPage({
|
||||
compactChrome = false,
|
||||
}: {
|
||||
compactChrome?: boolean;
|
||||
}) {
|
||||
const queryClient = useQueryClient();
|
||||
const { theme } = useTheme();
|
||||
const darkToastOpts =
|
||||
@@ -490,7 +498,16 @@ export default function ScheduledTasksPage() {
|
||||
|
||||
return (
|
||||
<WorkspaceContainer>
|
||||
<WorkspaceHeader />
|
||||
<WorkspaceHeader
|
||||
rightActions={
|
||||
compactChrome ? (
|
||||
<div className="flex items-center gap-1">
|
||||
<ThemeSwitcher tone="content" />
|
||||
<LayoutModeSwitcher tone="content" />
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
<WorkspaceBody>
|
||||
<div className="grid size-full min-h-0 grid-cols-1 grid-rows-[minmax(0,1fr)_minmax(0,1fr)] gap-4 p-4 xl:grid-cols-[420px_minmax(0,1fr)] xl:grid-rows-1">
|
||||
<Card className="flex min-h-0 min-w-0 flex-col">
|
||||
|
||||
@@ -5,7 +5,12 @@ import { getStoredAuth } from '@/core/auth';
|
||||
|
||||
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar';
|
||||
import { PromptInputProvider } from '@/components/ai-elements/prompt-input';
|
||||
import {
|
||||
LayoutModeSwitcher,
|
||||
ThemeSwitcher,
|
||||
} from '@/components/workspace/appearance-controls';
|
||||
import { WorkspaceSidebar } from '@/components/workspace/workspace-sidebar';
|
||||
import { UserIdentityBadge } from '@/components/workspace/user-identity-badge';
|
||||
import { CommandPalette } from '@/components/workspace/command-palette';
|
||||
import { Toaster } from 'sonner';
|
||||
import { SubtasksProvider } from '@/core/tasks/context';
|
||||
@@ -72,6 +77,27 @@ function isInIframe(): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
function shouldShowCompactTopActions(pathname: string): boolean {
|
||||
return (
|
||||
pathname === '/page/workspace/agents' ||
|
||||
pathname === '/page/workspace/skills' ||
|
||||
pathname === '/page/workspace/memory' ||
|
||||
pathname === '/page/workspace/knowledge' ||
|
||||
pathname.startsWith('/page/workspace/knowledge/')
|
||||
);
|
||||
}
|
||||
|
||||
function CompactWorkspaceTopActions() {
|
||||
return (
|
||||
<div className="z-[60] flex h-12 shrink-0 items-center justify-end gap-2 border-b border-border/70 bg-card/90 px-4 shadow-sm backdrop-blur-md">
|
||||
<ThemeSwitcher tone="content" />
|
||||
<LayoutModeSwitcher tone="content" />
|
||||
<div className="bg-border/70 mx-1 h-6 w-px shrink-0" aria-hidden />
|
||||
<UserIdentityBadge />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function WorkspaceLayout({
|
||||
children,
|
||||
pageSidebarCollapsed,
|
||||
@@ -98,7 +124,10 @@ export function WorkspaceLayout({
|
||||
}) {
|
||||
// 全量模式下通用问答(/page/workspace/chats*)的历史侧栏默认展开;其余紧凑页
|
||||
// (如智能体对话,为聊天区更宽而默认收起)维持原默认。
|
||||
const isGeneralQa = useLocation().pathname.startsWith("/page/workspace/chats");
|
||||
const pathname = useLocation().pathname;
|
||||
const isGeneralQa = pathname.startsWith('/page/workspace/chats');
|
||||
const showCompactTopActions =
|
||||
headerHidden && shouldShowCompactTopActions(pathname);
|
||||
|
||||
const pageSidebarWidth = pageSidebarHidden
|
||||
? '0rem'
|
||||
@@ -136,7 +165,14 @@ export function WorkspaceLayout({
|
||||
<SidebarInset
|
||||
className={cn('min-w-0', insetOverflowHidden && 'overflow-hidden')}
|
||||
>
|
||||
{children}
|
||||
{showCompactTopActions ? (
|
||||
<>
|
||||
<CompactWorkspaceTopActions />
|
||||
<div className="min-h-0 flex-1">{children}</div>
|
||||
</>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</SidebarInset>
|
||||
<CommandPalette />
|
||||
<Toaster position="top-center" />
|
||||
@@ -222,7 +258,7 @@ export default function WorkspaceRoutes({
|
||||
path="chats"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ChatsPage />
|
||||
<ChatsPage compactChrome={headerHidden} />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
@@ -338,7 +374,10 @@ export default function WorkspaceRoutes({
|
||||
path="ai-writing/*"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<AIWritingPage hideAdvancedFields />
|
||||
<AIWritingPage
|
||||
hideAdvancedFields
|
||||
compactChrome={headerHidden}
|
||||
/>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
@@ -371,7 +410,7 @@ export default function WorkspaceRoutes({
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ChatRuntime>
|
||||
<RoundtablePlanningPage />
|
||||
<RoundtablePlanningPage compactChrome={headerHidden} />
|
||||
</ChatRuntime>
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
@@ -433,7 +472,7 @@ export default function WorkspaceRoutes({
|
||||
path="scheduled/tasks"
|
||||
element={
|
||||
<WorkspaceLayout {...layoutProps}>
|
||||
<ScheduledTasksPage />
|
||||
<ScheduledTasksPage compactChrome={headerHidden} />
|
||||
</WorkspaceLayout>
|
||||
}
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user