frontend: FE-029 工作台外壳改版,顶栏徽片化+动作图标化+三栏折叠过渡动画
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { PanelBottom, PanelLeft, PanelRight } from "lucide-react"
|
||||
import { FolderCog, PanelBottom, PanelLeft, PanelRight, Unplug } from "lucide-react"
|
||||
|
||||
import { Button } from "~/components/ui/button"
|
||||
import { Separator } from "~/components/ui/separator"
|
||||
@@ -41,20 +41,19 @@ export function TopBar({
|
||||
)}
|
||||
>
|
||||
<div className="flex min-w-0 items-center gap-2 text-sm">
|
||||
<span className="shrink-0 font-semibold">MacTFS</span>
|
||||
<span className="shrink-0 font-semibold tracking-tight">MacTFS</span>
|
||||
<Separator orientation="vertical" className="h-4!" />
|
||||
<span className="hidden shrink-0 text-xs text-muted-foreground lg:inline">
|
||||
服务器
|
||||
</span>
|
||||
<span className="hidden max-w-56 truncate font-mono text-xs lg:inline">
|
||||
<span className="hidden max-w-56 truncate font-mono text-xs text-muted-foreground lg:inline">
|
||||
{session.serverUri}
|
||||
</span>
|
||||
<Separator orientation="vertical" className="hidden h-4! lg:block" />
|
||||
<span className="shrink-0 text-xs text-muted-foreground">Collection</span>
|
||||
<span className="max-w-40 truncate text-xs font-medium">{session.collection}</span>
|
||||
<Separator orientation="vertical" className="h-4!" />
|
||||
<span className="shrink-0 text-xs text-muted-foreground">Workspace</span>
|
||||
<span className="max-w-44 truncate font-mono text-xs">{session.workspace}</span>
|
||||
<span className="hidden max-w-44 shrink-0 items-center gap-1 truncate rounded-md bg-muted px-2 py-0.5 text-xs font-medium sm:inline-flex">
|
||||
<span className="text-muted-foreground">Collection</span>
|
||||
<span className="truncate">{session.collection}</span>
|
||||
</span>
|
||||
<span className="inline-flex max-w-52 shrink-0 items-center gap-1 truncate rounded-md bg-muted px-2 py-0.5 text-xs">
|
||||
<span className="text-muted-foreground">Workspace</span>
|
||||
<span className="truncate font-mono">{session.workspace}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="app-no-drag flex shrink-0 items-center gap-1">
|
||||
@@ -80,12 +79,22 @@ export function TopBar({
|
||||
<PanelBottom />
|
||||
</PanelToggle>
|
||||
<Separator orientation="vertical" className="mx-1 h-4!" />
|
||||
<Button size="sm" variant="outline" onClick={onManageWorkspace}>
|
||||
工作区
|
||||
</Button>
|
||||
<Button size="sm" variant="outline" onClick={onReconnect}>
|
||||
重新连接
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button size="icon-sm" variant="ghost" onClick={onManageWorkspace} aria-label="工作区与映射管理">
|
||||
<FolderCog />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom">工作区与映射管理</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button size="icon-sm" variant="ghost" onClick={onReconnect} aria-label="重新连接">
|
||||
<Unplug />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom">重新连接</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
|
||||
@@ -99,7 +99,13 @@ export function WorkspaceShell({
|
||||
)}
|
||||
|
||||
<div className="flex min-h-0 flex-1">
|
||||
{panels.tree && (
|
||||
{/* 左右面板保持挂载,通过宽度过渡实现折叠 / 展开动画 */}
|
||||
<div
|
||||
className={cn(
|
||||
"flex min-h-0 shrink-0 overflow-hidden transition-[width] duration-250 ease-out-quart",
|
||||
panels.tree ? "w-[280px]" : "w-0",
|
||||
)}
|
||||
>
|
||||
<SourceTreePanel
|
||||
collection={session.collection}
|
||||
mappings={session.mappings}
|
||||
@@ -107,7 +113,7 @@ export function WorkspaceShell({
|
||||
onNavigate={onNavigate}
|
||||
onFileAction={actions.handleFileAction}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<FolderItemsPanel
|
||||
session={session}
|
||||
selectedServerPath={selectedServerPath}
|
||||
@@ -117,7 +123,12 @@ export function WorkspaceShell({
|
||||
onFileAction={actions.handleFileAction}
|
||||
onRefresh={refreshItems}
|
||||
/>
|
||||
{panels.changes && (
|
||||
<div
|
||||
className={cn(
|
||||
"flex min-h-0 shrink-0 justify-end overflow-hidden transition-[width] duration-250 ease-out-quart",
|
||||
panels.changes ? "w-[340px]" : "w-0",
|
||||
)}
|
||||
>
|
||||
<ChangesPanel
|
||||
mappings={session.mappings}
|
||||
pendingChanges={pending.pendingChanges}
|
||||
@@ -130,16 +141,22 @@ export function WorkspaceShell({
|
||||
onFileAction={actions.handleFileAction}
|
||||
onRefresh={() => void pending.refresh()}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{panels.console && (
|
||||
{/* 底部操作台通过高度过渡实现滑入滑出 */}
|
||||
<div
|
||||
className={cn(
|
||||
"shrink-0 overflow-hidden transition-[height] duration-250 ease-out-quart",
|
||||
panels.console ? "h-[180px]" : "h-0",
|
||||
)}
|
||||
>
|
||||
<ConsolePanel
|
||||
refreshToken={logsRefreshToken}
|
||||
busy={actions.actionBusy || actions.checkinBusy}
|
||||
busyText={actions.notice?.kind === "info" ? actions.notice.text : null}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<WorkspaceDialogs
|
||||
dialog={actions.dialog}
|
||||
|
||||
@@ -129,7 +129,9 @@ export function SourceTreePanel({
|
||||
return (
|
||||
<aside className="flex h-full w-[280px] shrink-0 flex-col border-r bg-sidebar">
|
||||
<div className="flex h-9 shrink-0 items-center gap-2 border-b px-3">
|
||||
<span className="text-xs font-medium text-muted-foreground">源码目录</span>
|
||||
<span className="text-[11px] font-medium tracking-wider text-muted-foreground uppercase">
|
||||
源码目录
|
||||
</span>
|
||||
<span className="ml-auto max-w-28 truncate text-xs text-muted-foreground">{collection}</span>
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
||||
@@ -68,7 +68,9 @@ export function ChangesPanel({
|
||||
return (
|
||||
<aside className="flex h-full w-[340px] shrink-0 flex-col border-l bg-sidebar">
|
||||
<div className="flex h-9 shrink-0 items-center gap-2 border-b px-3">
|
||||
<span className="text-xs font-medium text-muted-foreground">挂起更改</span>
|
||||
<span className="text-[11px] font-medium tracking-wider text-muted-foreground uppercase">
|
||||
挂起更改
|
||||
</span>
|
||||
{pendingChanges.length > 0 && (
|
||||
<span className="ml-auto text-xs text-muted-foreground">{pendingChanges.length} 项</span>
|
||||
)}
|
||||
|
||||
@@ -62,7 +62,9 @@ export function ConsolePanel({
|
||||
return (
|
||||
<footer className="flex h-[180px] shrink-0 flex-col border-t bg-background">
|
||||
<div className="flex h-8 shrink-0 items-center gap-2 border-b px-3">
|
||||
<span className="text-xs font-medium text-muted-foreground">操作日志</span>
|
||||
<span className="text-[11px] font-medium tracking-wider text-muted-foreground uppercase">
|
||||
操作日志
|
||||
</span>
|
||||
{busy && (
|
||||
<span className="flex items-center gap-1.5 text-xs text-primary">
|
||||
<Loader2 className="size-3 animate-spin" />
|
||||
|
||||
Reference in New Issue
Block a user