diff --git a/web/components/workspace-switcher.tsx b/web/components/workspace-switcher.tsx index 6dbe2f4..ff97c0a 100644 --- a/web/components/workspace-switcher.tsx +++ b/web/components/workspace-switcher.tsx @@ -2,6 +2,7 @@ import { CheckIcon, ChevronsUpDownIcon } from "lucide-react" import Link from "next/link" +import { useRef, useState } from "react" import type { ReactElement } from "react" import { useI18n } from "@/i18n/provider" @@ -51,8 +52,36 @@ export function WorkspaceSwitcher({ trigger, }: WorkspaceSwitcherProps) { const t = useI18n() + const [hoverOpen, setHoverOpen] = useState(false) + const closeTimerRef = useRef | null>(null) + const isRail = variant === "rail" const currentOption = workspaceOptions.find((item) => item.key === currentWorkspace) ?? workspaceOptions[0] + + const clearCloseTimer = () => { + if (closeTimerRef.current) { + clearTimeout(closeTimerRef.current) + closeTimerRef.current = null + } + } + const openHoverMenu = () => { + if (!isRail) { + return + } + clearCloseTimer() + setHoverOpen(true) + } + const closeHoverMenu = () => { + if (!isRail) { + return + } + clearCloseTimer() + closeTimerRef.current = setTimeout(() => { + setHoverOpen(false) + closeTimerRef.current = null + }, 120) + } + const triggerClassName = cn( "gap-2 text-left", variant === "header" && @@ -97,8 +126,15 @@ export function WorkspaceSwitcher({ ) return ( - + } @@ -109,6 +145,8 @@ export function WorkspaceSwitcher({ align="start" side={variant === "sidebar" || variant === "rail" ? "right" : "bottom"} sideOffset={8} + onPointerEnter={openHoverMenu} + onPointerLeave={closeHoverMenu} className="w-60 min-w-60" > diff --git a/web/e2e/workbench-function.spec.ts b/web/e2e/workbench-function.spec.ts index d2f80dc..1bc15a2 100644 --- a/web/e2e/workbench-function.spec.ts +++ b/web/e2e/workbench-function.spec.ts @@ -82,8 +82,7 @@ test.describe("support workbench", () => { await conversationsEntry.hover(); await expect(page.getByText(/会话|Conversations/).last()).toBeVisible(); await screenshot(page, "04-workbench-rail-tooltip"); - await page.getByRole("button", { name: /贝壳AGENT|Agent Desk/i }).first().click(); - await expect(page.getByText(/切换工作区|Switch workspace/)).toBeVisible(); + await page.getByRole("button", { name: /贝壳AGENT|Agent Desk/i }).first().hover(); await expect(page.getByRole("menuitem", { name: /管理后台|Admin Dashboard/ })).toBeVisible(); await page.waitForTimeout(300); await screenshot(page, "05-workbench-switcher-open");