update: data source
This commit is contained in:
@@ -3,6 +3,7 @@ import { type FormEvent, useEffect, useMemo, useRef } from "react";
|
||||
import { useAuth } from "../../context/AuthContext";
|
||||
import { CreateFolderModal } from "../../components/platform/CreateFolderModal";
|
||||
import { CreateScriptModal } from "../../components/platform/CreateScriptModal";
|
||||
import { DataResourceUploadModal } from "../../components/platform/DataResourceUploadModal";
|
||||
import Icon from "../../components/common/Icon";
|
||||
import { PublishModal } from "../../components/platform/PublishModal";
|
||||
import { ScriptExplorer } from "../../components/platform/ScriptExplorer";
|
||||
@@ -32,6 +33,9 @@ export default function ScriptsPage() {
|
||||
const latestVersion = useScriptWorkspaceStore((s) => s.latestVersion);
|
||||
const latestVersionLoading = useScriptWorkspaceStore((s) => s.latestVersionLoading);
|
||||
|
||||
const dataResources = useScriptWorkspaceStore((s) => s.dataResources);
|
||||
const loadDataResources = useScriptWorkspaceStore((s) => s.loadDataResources);
|
||||
|
||||
const pythonEditorBuffers = useScriptWorkspaceStore((s) => s.pythonEditorBuffers);
|
||||
|
||||
// store actions
|
||||
@@ -51,6 +55,7 @@ export default function ScriptsPage() {
|
||||
const loadLatestVersion = useScriptWorkspaceStore((s) => s.loadLatestVersion);
|
||||
const createScript = useScriptWorkspaceStore((s) => s.createScript);
|
||||
const uploadScripts = useScriptWorkspaceStore((s) => s.uploadScripts);
|
||||
const uploadDataResource = useScriptWorkspaceStore((s) => s.uploadDataResource);
|
||||
const createFolder = useScriptWorkspaceStore((s) => s.createFolder);
|
||||
const deleteScript = useScriptWorkspaceStore((s) => s.deleteScript);
|
||||
const deleteDirectory = useScriptWorkspaceStore((s) => s.deleteDirectory);
|
||||
@@ -74,6 +79,13 @@ export default function ScriptsPage() {
|
||||
const openCreateDialog = useUiStore((s) => s.openCreateDialog);
|
||||
const openFolderDialog = useUiStore((s) => s.openFolderDialog);
|
||||
const chooseUpload = useUiStore((s) => s.chooseUpload);
|
||||
const dataResourceDialog = useUiStore((s) => s.dataResourceDialog);
|
||||
const openDataResourceDialog = useUiStore((s) => s.openDataResourceDialog);
|
||||
const closeDataResourceDialog = useUiStore((s) => s.closeDataResourceDialog);
|
||||
const setDataResourceName = useUiStore((s) => s.setDataResourceName);
|
||||
const setDataResourceVisibility = useUiStore((s) => s.setDataResourceVisibility);
|
||||
const setDataResourceDescription = useUiStore((s) => s.setDataResourceDescription);
|
||||
const setDataResourceTargetPath = useUiStore((s) => s.setDataResourceTargetPath);
|
||||
const publish = useUiStore((s) => s.publish);
|
||||
const setReleaseNote = useUiStore((s) => s.setReleaseNote);
|
||||
const setPublishVisibility = useUiStore((s) => s.setPublishVisibility);
|
||||
@@ -87,6 +99,10 @@ export default function ScriptsPage() {
|
||||
void load();
|
||||
}, [load]);
|
||||
|
||||
useEffect(() => {
|
||||
void loadDataResources();
|
||||
}, [loadDataResources, workspaceId]);
|
||||
|
||||
useEffect(() => {
|
||||
reset();
|
||||
// 刷新前递增版本号,触发已打开标签页的只读内容刷新
|
||||
@@ -189,12 +205,68 @@ export default function ScriptsPage() {
|
||||
void closeTab(scriptId);
|
||||
};
|
||||
|
||||
// 5) handlers
|
||||
// 5) handlers
|
||||
const SCRIPT_EXTS = [".py", ".ipynb"];
|
||||
const DATA_EXTS = [".csv", ".xlsx", ".xls", ".tsv", ".json", ".parquet", ".txt"];
|
||||
|
||||
const matchesExt = (name: string, exts: string[]) =>
|
||||
exts.some((ext) => name.toLowerCase().endsWith(ext));
|
||||
|
||||
const handleUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const files = Array.from(event.target.files ?? []);
|
||||
event.target.value = "";
|
||||
if (files.length === 0) return;
|
||||
void uploadScripts(files, upload.parentPath);
|
||||
const scriptFiles = files.filter((f) => matchesExt(f.name, SCRIPT_EXTS));
|
||||
const dataFiles = files.filter((f) => matchesExt(f.name, DATA_EXTS));
|
||||
const rejected = files.filter(
|
||||
(f) => !matchesExt(f.name, SCRIPT_EXTS) && !matchesExt(f.name, DATA_EXTS),
|
||||
);
|
||||
if (rejected.length) {
|
||||
pushToast({
|
||||
tone: "error",
|
||||
message: `不支持的文件类型: ${rejected.map((f) => f.name).join(", ")}`,
|
||||
});
|
||||
}
|
||||
if (scriptFiles.length) {
|
||||
void uploadScripts(scriptFiles, upload.parentPath);
|
||||
}
|
||||
if (dataFiles.length === 1) {
|
||||
openDataResourceDialog(dataFiles[0], upload.parentPath);
|
||||
} else if (dataFiles.length > 1) {
|
||||
pushToast({
|
||||
tone: "info",
|
||||
message: "数据资源一次只支持上传一个文件,请分别上传",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDataResourceSubmit = (event: FormEvent) => {
|
||||
event.preventDefault();
|
||||
const { file, resourceName, visibility, description, targetPath } = dataResourceDialog;
|
||||
if (!file || !resourceName.trim()) return;
|
||||
void uploadDataResource(file, {
|
||||
resourceName: resourceName.trim(),
|
||||
visibility,
|
||||
description: description.trim(),
|
||||
targetPath: targetPath.trim(),
|
||||
}).then((resource) => {
|
||||
if (resource) void loadDataResources();
|
||||
});
|
||||
};
|
||||
|
||||
const handleCopyResourcePath = async (jupyterPath: string) => {
|
||||
if (!jupyterPath) return;
|
||||
const fullPrefix = `${workspaceId ?? ""}/${user?.user_id ?? ""}/`;
|
||||
let stripped = jupyterPath;
|
||||
if (fullPrefix !== "/" && stripped.startsWith(fullPrefix)) {
|
||||
stripped = stripped.slice(fullPrefix.length);
|
||||
}
|
||||
try {
|
||||
await navigator.clipboard.writeText(stripped);
|
||||
pushToast({ tone: "success", message: `已复制:${stripped}` });
|
||||
} catch {
|
||||
pushToast({ tone: "error", message: "复制失败" });
|
||||
}
|
||||
};
|
||||
|
||||
const handleCreateSubmit = (event: FormEvent) => {
|
||||
@@ -223,6 +295,7 @@ export default function ScriptsPage() {
|
||||
scripts={scripts}
|
||||
filteredScripts={filteredScripts}
|
||||
directories={directories}
|
||||
dataResources={dataResources}
|
||||
user={user}
|
||||
selectedId={selectedId}
|
||||
loading={loading}
|
||||
@@ -238,6 +311,7 @@ export default function ScriptsPage() {
|
||||
onChooseUpload={(parentPath) => triggerUpload(parentPath)}
|
||||
onContextMenu={showContextMenu}
|
||||
onSelect={openTab}
|
||||
onCopyResourcePath={(p) => void handleCopyResourcePath(p)}
|
||||
uploadInputRef={uploadInputRef}
|
||||
onHandleUpload={handleUpload}
|
||||
/>
|
||||
@@ -344,8 +418,9 @@ export default function ScriptsPage() {
|
||||
onOpenCreateDialog={(parentPath, scriptType) =>
|
||||
openCreateDialog(parentPath, scriptType)}
|
||||
onOpenFolderDialog={(parentPath) => openFolderDialog(parentPath)}
|
||||
onChooseUpload={(parentPath) => chooseUpload(parentPath)}
|
||||
onChooseUpload={(parentPath) => triggerUpload(parentPath ?? "")}
|
||||
onRemoveDirectory={(p) => void deleteDirectory(p)}
|
||||
onCopyResourcePath={(p) => void handleCopyResourcePath(p)}
|
||||
onClose={closeContextMenu}
|
||||
/>
|
||||
|
||||
@@ -360,10 +435,26 @@ export default function ScriptsPage() {
|
||||
onClose={closePublishDialog}
|
||||
/>
|
||||
|
||||
<VersionReceiptModal
|
||||
publishedVersion={publish.publishedVersion}
|
||||
onClose={clearPublishedVersion}
|
||||
onCopy={(message) => pushToast({ tone: "success", message })}
|
||||
<VersionReceiptModal
|
||||
publishedVersion={publish.publishedVersion}
|
||||
onClose={clearPublishedVersion}
|
||||
onCopy={(message) => pushToast({ tone: "success", message })}
|
||||
/>
|
||||
<DataResourceUploadModal
|
||||
open={dataResourceDialog.open}
|
||||
file={dataResourceDialog.file}
|
||||
resourceName={dataResourceDialog.resourceName}
|
||||
visibility={dataResourceDialog.visibility}
|
||||
description={dataResourceDialog.description}
|
||||
uploading={dataResourceDialog.uploading}
|
||||
parentPath={dataResourceDialog.parentPath}
|
||||
targetPath={dataResourceDialog.targetPath}
|
||||
onNameChange={setDataResourceName}
|
||||
onVisibilityChange={setDataResourceVisibility}
|
||||
onDescriptionChange={setDataResourceDescription}
|
||||
onTargetPathChange={setDataResourceTargetPath}
|
||||
onSubmit={handleDataResourceSubmit}
|
||||
onClose={closeDataResourceDialog}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user