+
+
+
+
+ setTemplateSearch(event.target.value)}
+ onKeyDown={(event) => {
+ if (event.key === "Enter") event.preventDefault();
+ }}
+ placeholder="搜索写作模板..."
+ className="h-8 w-full rounded-lg border border-slate-200 bg-slate-50/80 pl-8 pr-3 text-[12px] text-slate-600 outline-none transition focus:border-blue-200 focus:bg-white focus:ring-2 focus:ring-blue-100 dark:border-[#1B477E] dark:bg-[#022248] dark:text-[#AACEFF]"
+ />
+
+
+
+ {templates.length === 0 ? (
+
+ 暂无研究模板,点击标题配置
+
+ ) : filteredTemplates.length === 0 ? (
+
+ 暂无匹配模板
+
+ ) : (
+
+ {filteredTemplates.map((tpl, index) => {
+ const visual = getTemplateVisual(tpl, index);
+ const Icon = visual.Icon;
+ return (
+
+ );
+ })}
+
+ )}
+
+ );
+}
diff --git a/frontend-web/src/open-canvas/pages/AIWritingPage.tsx b/frontend-web/src/open-canvas/pages/AIWritingPage.tsx
index afc3fceb..4c56e940 100644
--- a/frontend-web/src/open-canvas/pages/AIWritingPage.tsx
+++ b/frontend-web/src/open-canvas/pages/AIWritingPage.tsx
@@ -81,7 +81,7 @@
* -d '{"retention_days": 0}'
* ──────────────────────────────────────────────────────────────────────────
*/
-import { useEffect, useMemo, useRef, useState } from 'react';
+import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';
import {
ArrowLeft,
History,
@@ -113,6 +113,10 @@ import StudioNotebookDetailPage from '@/pages/StudioNotebookDetailPage';
import StudioNotebooksPage from '@/pages/StudioNotebooksPage';
import AgentChatPage from '@/pages/AgentChatPage';
import { ChatRuntime } from '@/pages/WorkspaceRoutes';
+import {
+ LayoutModeSwitcher,
+ ThemeSwitcher,
+} from '@/components/workspace/appearance-controls';
import {
AgentModuleSidebar,
useAgentModuleSidebarData,
@@ -137,10 +141,20 @@ const WRITING_ID = 'aw-writing';
const DRAFT_ID = 'aw-draft';
const AI_WRITING_AGENT_MODULE_KEY = 'ai-writing';
const AI_WRITING_AGENT_MODULE_TITLE = 'AI 写作智能体';
+const AI_WRITING_LAST_AGENT_KEY = `agent-module:${AI_WRITING_AGENT_MODULE_KEY}:last-agent`;
// Match the original canvas page proportions (chat=35, artifact=65)
const DEFAULT_LAYOUT = { [WRITING_ID]: 35, [DRAFT_ID]: 65 };
+function AIWritingCompactAppearanceActions() {
+ return (
+
暂无可用智能体,请先在模块设置中配置或创建智能体。
@@ -188,24 +210,44 @@ function AIWritingAgentDefaultRedirect() {
);
}
- return
;
+ return
;
}
-function AIWritingAgentChatRoute() {
+function AIWritingAgentChatRoute({
+ compactAppearanceActions,
+}: {
+ compactAppearanceActions?: ReactNode;
+}) {
const { agent_id } = useParams<{ agent_id: string }>();
return (
-
+
);
}
-function AIWritingAgentRoutes({ base }: { base: string }) {
+function AIWritingAgentRoutes({
+ base,
+ compactAppearanceActions,
+}: {
+ base: string;
+ compactAppearanceActions?: ReactNode;
+}) {
return (
} />
- } />
+
+ }
+ />
);
@@ -220,11 +262,26 @@ interface NotebookProps {
studioToken?: string;
}
-function WritingFormPanel({ hideAdvancedFields, initialNotebookId, initialDocumentIds, studioToken }: { hideAdvancedFields: boolean } & NotebookProps) {
+function WritingFormPanel({
+ hideAdvancedFields,
+ initialNotebookId,
+ initialDocumentIds,
+ studioToken,
+ headerActionsBeforeCollapse,
+}: {
+ hideAdvancedFields: boolean;
+ headerActionsBeforeCollapse?: ReactNode;
+} & NotebookProps) {
return (
// 与原布局保持相同的 flex-1 min-h-0 包裹,确保内部 h-full 正确解析
);
}
@@ -234,7 +291,16 @@ function WritingFormPanel({ hideAdvancedFields, initialNotebookId, initialDocume
* - idle(初始问答阶段):左=「写作助手 Q&A」,右=「写作配置选项」表单;
* - 开始写作后:回到原布局——左=写作配置/时间线面板,右=草稿预览。
*/
-function AIWritingLayout({ hideAdvancedFields, initialNotebookId, initialDocumentIds, studioToken }: { hideAdvancedFields: boolean } & NotebookProps) {
+function AIWritingLayout({
+ hideAdvancedFields,
+ initialNotebookId,
+ initialDocumentIds,
+ studioToken,
+ compactAppearanceActions,
+}: {
+ hideAdvancedFields: boolean;
+ compactAppearanceActions?: ReactNode;
+} & NotebookProps) {
const layoutRef = useRef
(null);
const { state } = useAIWriting();
const { isHistoryMode } = useAIWritingHistory();
@@ -262,19 +328,28 @@ function AIWritingLayout({ hideAdvancedFields, initialNotebookId, initialDocumen
formExpanded ? 'w-[36%] min-w-[340px] max-w-[600px] border-l' : 'w-0 min-w-0',
)}
>
-
+
{/* 收起态:右上角浮动展开图标按钮(与展开态头部的收起按钮位置呼应) */}
{!formExpanded && (
-