fix:脚本文件标签栏

This commit is contained in:
xiaozhu
2026-08-04 15:53:17 +08:00
parent eace1109ac
commit a4019b1a74
3 changed files with 199 additions and 28 deletions
@@ -3,8 +3,11 @@ import type {
ActiveEditSession,
LatestVersion,
ScriptItem,
ScriptType,
} from "../../services/api";
import { scriptIcon } from "./WorkspaceTree";
import type { MouseEvent as ReactMouseEvent } from "react";
import { useRef, useEffect } from "react";
type ToastState = {
tone: "success" | "error" | "info";
@@ -19,9 +22,12 @@ type ScriptWorkspaceProps = {
openError: string | null;
latestVersion: LatestVersion | null;
versionsLoading: boolean;
openTabs: Array<{ scriptId: string; scriptName: string; scriptType: ScriptType }>;
onOpenEditor: () => void;
onEndEditing: () => void;
onClose: () => void;
onClose: (scriptId: string, event?: ReactMouseEvent) => void;
onSwitchTab: (scriptId: string) => void;
onNewTab: () => void;
onPublish: () => void;
onInfo: (toast: ToastState) => void;
};
@@ -91,32 +97,88 @@ export function ScriptWorkspace({
openError,
latestVersion,
versionsLoading,
openTabs,
onOpenEditor,
onEndEditing,
onClose,
onSwitchTab,
onNewTab,
onPublish,
onInfo,
}: ScriptWorkspaceProps) {
const tabbarRef = useRef<HTMLDivElement | null>(null);
const isNotebook = script.script_type === "notebook";
const isEditing = editSession?.session_status === "active";
const scroll = (direction: "left" | "right") => {
const tabbar = tabbarRef.current;
if (!tabbar) return;
const scrollAmount = 200;
tabbar.scrollBy({
left: direction === "left" ? -scrollAmount : scrollAmount,
behavior: "smooth",
});
};
useEffect(() => {
const tabbar = tabbarRef.current;
if (!tabbar) return;
const activeTab = tabbar.querySelector(".editor-tab--active") as HTMLElement | null;
if (activeTab) {
const tabbarRect = tabbar.getBoundingClientRect();
const tabRect = activeTab.getBoundingClientRect();
if (tabRect.right > tabbarRect.right || tabRect.left < tabbarRect.left) {
activeTab.scrollIntoView({ behavior: "smooth", inline: "center" });
}
}
}, [script.script_id]);
return (
<>
<div className="tabbar">
<div className="editor-tab editor-tab--active">
<span className={`file-icon file-icon--${script.script_type}`}>
<Icon name={scriptIcon(script)} size={16} />
</span>
<span>{script.script_name}</span>
<button type="button" aria-label="关闭标签" onClick={onClose}>
<Icon name="close" size={14} />
<button
className="tabbar-scroll-btn tabbar-scroll-btn--left"
type="button"
aria-label="向左滚动"
onClick={() => scroll("left")}
>
<Icon name="chevron" size={16} />
</button>
<div className="tabbar-scroll-content" ref={tabbarRef}>
{openTabs.map((tab) => (
<div
key={tab.scriptId}
className={`editor-tab${tab.scriptId === script.script_id ? " editor-tab--active" : ""}`}
onClick={() => onSwitchTab(tab.scriptId)}
>
<span className={`file-icon file-icon--${tab.scriptType}`}>
<Icon name={tab.scriptType === "notebook" ? "notebook" : "python"} size={16} />
</span>
<span>{tab.scriptName}</span>
<button
type="button"
aria-label="关闭标签"
onClick={(event) => onClose(tab.scriptId, event)}
>
<Icon name="close" size={14} />
</button>
</div>
))}
<button
className="new-tab"
type="button"
onClick={onNewTab}
>
<Icon name="plus" size={17} />
</button>
</div>
<button
className="new-tab"
className="tabbar-scroll-btn tabbar-scroll-btn--right"
type="button"
onClick={() => onInfo({ tone: "info", message: "请从左侧选择或新建脚本" })}
aria-label="向右滚动"
onClick={() => scroll("right")}
>
<Icon name="plus" size={17} />
<Icon name="chevron" size={16} />
</button>
</div>