feat: preview components
This commit is contained in:
@@ -7,7 +7,10 @@ import type {
|
||||
} from "../../services/api";
|
||||
import { scriptIcon } from "./WorkspaceTree";
|
||||
import type { MouseEvent as ReactMouseEvent, RefObject } from "react";
|
||||
import { useRef, useEffect } from "react";
|
||||
import Editor from "@monaco-editor/react";
|
||||
import { useRef, useLayoutEffect } from "react";
|
||||
|
||||
import { useScriptWorkspaceStore } from "./state/scriptWorkspaceStore";
|
||||
|
||||
type ToastState = {
|
||||
tone: "success" | "error" | "info";
|
||||
@@ -129,9 +132,9 @@ export function ScriptWorkspace({
|
||||
left: direction === "left" ? -scrollAmount : scrollAmount,
|
||||
behavior: "smooth",
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
const tabbar = tabbarRef.current;
|
||||
if (!tabbar) return;
|
||||
const activeTab = tabbar.querySelector(".editor-tab--active") as HTMLElement | null;
|
||||
@@ -232,13 +235,11 @@ export function ScriptWorkspace({
|
||||
</button>
|
||||
<span className={`stage-badge${isEditing ? " is-editing" : ""}`}>
|
||||
<span />
|
||||
{isEditing
|
||||
? isNotebook
|
||||
? "Demo 无锁模式 · Kernel 已连接"
|
||||
: "Demo 无锁模式 · 编辑中"
|
||||
: latestVersion
|
||||
{
|
||||
latestVersion
|
||||
? `最新 ${latestVersion.version_label}`
|
||||
: "工作副本已就绪"}
|
||||
: "工作副本已就绪"
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -378,13 +379,13 @@ export function ScriptWorkspace({
|
||||
<span>Python 预览</span>
|
||||
<em>{isEditing ? "Jupyter 中可编辑" : "平台只读预览"}</em>
|
||||
</div>
|
||||
<PythonPreview />
|
||||
<PythonPreview workspaceId={script.workspace_id} filePath={`${script.script_id}.py`}/>
|
||||
</div>
|
||||
|
||||
<div className="integrity-row">
|
||||
<span>
|
||||
<Icon name="check" size={15} />
|
||||
{isEditing ? "Demo 无锁编辑会话已连接" : "工作副本已同步"}
|
||||
{/*{isEditing ? "Demo 无锁编辑会话已连接" : "工作副本已同步"}*/}
|
||||
</span>
|
||||
<span>SHA-256 {shortHash(script.content_hash)}</span>
|
||||
<span>
|
||||
@@ -403,19 +404,59 @@ export function ScriptWorkspace({
|
||||
);
|
||||
}
|
||||
|
||||
function PythonPreview() {
|
||||
|
||||
interface PythonPreviewProps {
|
||||
workspaceId: string;
|
||||
filePath: string;
|
||||
}
|
||||
export function PythonPreview({
|
||||
workspaceId,
|
||||
filePath,
|
||||
}: PythonPreviewProps) {
|
||||
const previewKey = `${workspaceId}::${filePath}`;
|
||||
const storeKey = useScriptWorkspaceStore((s) => s.previewKey);
|
||||
const previewCode = useScriptWorkspaceStore((s) => s.previewCode);
|
||||
const previewCodeSize = useScriptWorkspaceStore((s) => s.previewCodeSize);
|
||||
const previewLoading = useScriptWorkspaceStore((s) => s.previewLoading);
|
||||
const previewError = useScriptWorkspaceStore((s) => s.previewError);
|
||||
const loadPreview = useScriptWorkspaceStore((s) => s.loadPreview);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
void loadPreview(workspaceId, filePath);
|
||||
}, [previewKey]);
|
||||
|
||||
if (storeKey !== previewKey) {
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
|
||||
if (previewLoading) {
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
|
||||
if (previewError) {
|
||||
return <div>Failed to load: {previewError}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="python-preview">
|
||||
<div className="line-numbers">
|
||||
1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9
|
||||
</div>
|
||||
<pre>
|
||||
<span className="code-comment">"""模型实验开发平台构建脚本。"""</span>
|
||||
{"\n\n"}<b>def</b> <span className="code-function">main</span>() -> <b>None</b>:
|
||||
{"\n"} print(<i>"Hello, Model Platform!"</i>)
|
||||
{"\n\n\n"}<b>if</b> __name__ == <i>"__main__"</i>:
|
||||
{"\n"} main()
|
||||
</pre>
|
||||
</div>
|
||||
<Editor
|
||||
height="550px"
|
||||
language="python"
|
||||
value={previewCode ?? ""}
|
||||
theme="vs"
|
||||
options={{
|
||||
readOnly: true,
|
||||
domReadOnly: true,
|
||||
minimap: {
|
||||
enabled: previewCodeSize !== null && previewCodeSize > 1000,
|
||||
},
|
||||
lineNumbers: "off",
|
||||
folding: true,
|
||||
wordWrap: "on",
|
||||
contextmenu: false,
|
||||
dragAndDrop: false,
|
||||
automaticLayout: true,
|
||||
renderLineHighlight: "none",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user