From 98a229af5cad67734cd2c84279bdd1741790ced1 Mon Sep 17 00:00:00 2001 From: HouYunFei <1844025705@qq.com> Date: Tue, 2 Jun 2026 16:22:40 +0800 Subject: [PATCH] feat(docs): add documentation link in top menu and user status actions --- docs/content/docs/progress/pending-test.mdx | 1 + .../(user)/canvas/[id]/canvas-client-page.tsx | 4 +- web/src/components/layout/app-top-nav.tsx | 41 +------------------ .../components/layout/user-status-actions.tsx | 18 ++++---- web/src/constant/env.ts | 2 + 5 files changed, 19 insertions(+), 47 deletions(-) diff --git a/docs/content/docs/progress/pending-test.mdx b/docs/content/docs/progress/pending-test.mdx index c8613e2..ac212c3 100644 --- a/docs/content/docs/progress/pending-test.mdx +++ b/docs/content/docs/progress/pending-test.mdx @@ -5,6 +5,7 @@ description: 当前版本已实现但仍需人工验证的变更项 # 待测试 +- 画布左上角菜单和右上角状态栏新增“文档”入口,会使用 `NEXT_PUBLIC_DOC_URL` 配置的地址并在新标签打开文档站;需要验证登录和未登录状态下顶部入口都可见。 - 文档站搜索改为中英文混合 tokenizer,中文正文、标题和短语会按中文词、单字、二元和三元片段建立索引;需要验证 `/api/search` 和搜索弹窗能命中文档中的中文关键词。 - 文档站改为 Next.js standalone server 输出,新增 `docs/Dockerfile`、`docs/docker-compose.yml` 和 `docs/docker-compose.local.yml` 独立运行入口;需要验证文档页、搜索接口和 LLM 文本接口在文档站容器中可访问。 - 画布连线支持右键打开删除菜单;拖拽连线到目标卡片内部、连接点附近或卡片边缘外扩范围内会自动吸附并连接,拖到已有但不可连接的节点附近不会再误弹创建节点菜单。 diff --git a/web/src/app/(user)/canvas/[id]/canvas-client-page.tsx b/web/src/app/(user)/canvas/[id]/canvas-client-page.tsx index 1721a4e..776de60 100644 --- a/web/src/app/(user)/canvas/[id]/canvas-client-page.tsx +++ b/web/src/app/(user)/canvas/[id]/canvas-client-page.tsx @@ -3,11 +3,12 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; import type { ChangeEvent as ReactChangeEvent, DragEvent as ReactDragEvent, MouseEvent as ReactMouseEvent, PointerEvent as ReactPointerEvent } from "react"; import { useParams, useRouter } from "next/navigation"; -import { Home, ImageIcon, Images, List, Menu, MessageSquare, Music2, Plus, Redo2, Settings2, Trash2, Undo2, Upload, Video } from "lucide-react"; +import { BookOpen, Home, ImageIcon, Images, List, Menu, MessageSquare, Music2, Plus, Redo2, Settings2, Trash2, Undo2, Upload, Video } from "lucide-react"; import { saveAs } from "file-saver"; import { requestEdit, requestGeneration, requestImageQuestion } from "@/services/api/image"; import { requestVideoGeneration, storeGeneratedVideo } from "@/services/api/video"; +import { DOCS_URL } from "@/constant/env"; import { defaultConfig, type AiConfig, useConfigStore, useEffectiveConfig } from "@/stores/use-config-store"; import { resolveImageUrl, uploadImage, type UploadedImage } from "@/services/image-storage"; import { resolveMediaUrl, uploadMediaFile, type UploadedFile } from "@/services/file-storage"; @@ -2441,6 +2442,7 @@ function CanvasTopBar({ menu={{ items: [ { key: "home", icon: , label: "主页", onClick: onHome }, + { key: "docs", icon: , label: "文档", onClick: () => window.open(DOCS_URL, "_blank", "noopener,noreferrer") }, { key: "projects", icon: , label: "我的画布", onClick: onProjects }, { type: "divider" }, { key: "new", icon: , label: "新建画布", onClick: onCreateProject }, diff --git a/web/src/components/layout/app-top-nav.tsx b/web/src/components/layout/app-top-nav.tsx index 0a368fc..0940afa 100644 --- a/web/src/components/layout/app-top-nav.tsx +++ b/web/src/components/layout/app-top-nav.tsx @@ -1,30 +1,19 @@ "use client"; -import { Menu, Settings2 } from "lucide-react"; +import { Menu } from "lucide-react"; import Link from "next/link"; import { usePathname } from "next/navigation"; -import { AnimatedThemeToggler } from "@/components/ui/animated-theme-toggler"; import { navigationTools, type NavigationToolSlug } from "@/constant/navigation-tools"; import { AppConfigModal } from "@/components/layout/app-config-modal"; -import { GitHubLink } from "@/components/layout/github-link"; import { MobileNavDrawer } from "@/components/layout/mobile-nav-drawer"; import { UserStatusActions } from "@/components/layout/user-status-actions"; -import { VersionReleaseModal } from "@/components/layout/version-release-modal"; -import { useConfigStore } from "@/stores/use-config-store"; -import { useThemeStore } from "@/stores/use-theme-store"; -import { useUserStore } from "@/stores/use-user-store"; import { cn } from "@/lib/utils"; import { useState } from "react"; export function AppTopNav() { const pathname = usePathname(); const [mobileNavOpen, setMobileNavOpen] = useState(false); - const openConfigDialog = useConfigStore((state) => state.openConfigDialog); - const theme = useThemeStore((state) => state.theme); - const setTheme = useThemeStore((state) => state.setTheme); - const user = useUserStore((state) => state.user); - const isReady = useUserStore((state) => state.isReady); const hideHeader = /^\/canvas\/[^/]+/.test(pathname); const slug = pathname.split("/").filter(Boolean)[0]; const activeToolSlug = navigationTools.some((tool) => tool.slug === slug) ? (slug as NavigationToolSlug) : undefined; @@ -80,33 +69,7 @@ export function AppTopNav() {
- {isReady && user ? ( - - ) : ( - <> - - - - - - 登录 - - - )} +
diff --git a/web/src/components/layout/user-status-actions.tsx b/web/src/components/layout/user-status-actions.tsx index 9793bab..a035278 100644 --- a/web/src/components/layout/user-status-actions.tsx +++ b/web/src/components/layout/user-status-actions.tsx @@ -2,7 +2,7 @@ import type { CSSProperties, RefObject } from "react"; import { Avatar, Dropdown, Tooltip } from "antd"; -import { Keyboard, LogOut, Settings2, Shield } from "lucide-react"; +import { BookOpen, Keyboard, LogOut, Settings2, Shield } from "lucide-react"; import type { ItemType } from "antd/es/menu/interface"; import Link from "next/link"; @@ -10,6 +10,7 @@ import { AnimatedThemeToggler } from "@/components/ui/animated-theme-toggler"; import { GitHubLink } from "@/components/layout/github-link"; import { VersionReleaseModal } from "@/components/layout/version-release-modal"; import { CreditSymbol } from "@/constant/credits"; +import { DOCS_URL } from "@/constant/env"; import { cn } from "@/lib/utils"; import { canvasThemes } from "@/lib/canvas-theme"; import { useConfigStore } from "@/stores/use-config-store"; @@ -37,10 +38,10 @@ export function UserStatusActions({ showConfig = true, variant = "default", onOp const credits = user?.credits ?? 0; const avatarUrl = user?.avatarUrl?.trim(); const avatarText = (userName.trim()[0] || "U").toUpperCase(); - const naturalIconClass = "inline-flex size-8 shrink-0 items-center justify-center text-stone-600 transition hover:text-stone-950 dark:text-stone-300 dark:hover:text-white [&_svg]:size-4"; + const naturalIconClass = "inline-flex size-7 shrink-0 items-center justify-center text-stone-600 transition hover:text-stone-950 dark:text-stone-300 dark:hover:text-white [&_svg]:size-4"; const iconStyle: CSSProperties | undefined = variant === "canvas" ? { color: canvasTheme.node.text } : undefined; const versionStyle = iconStyle; - const gitHubClassName = variant === "canvas" ? "size-11 text-base" : undefined; + const gitHubClassName = "size-7 text-base"; const gitHubStyle = iconStyle; const avatarStyle: CSSProperties | undefined = variant === "canvas" ? { borderColor: canvasTheme.toolbar.border, color: canvasTheme.node.text, background: "transparent" } : undefined; const menuItems: ItemType[] = [ @@ -52,7 +53,10 @@ export function UserStatusActions({ showConfig = true, variant = "default", onOp ]; return ( -
+
+ + + {showConfig ? (