133 lines
4.5 KiB
TypeScript
133 lines
4.5 KiB
TypeScript
import $ from "jquery";
|
|
import "jstree";
|
|
import { api } from "../../../services/api";
|
|
import { getCurrentUser } from "../../../services/authState";
|
|
import type { FolderTreeResponse } from "../../../types";
|
|
import { confirmDialog, notify, notifyError, promptDialog } from "../../../ui/dialogs";
|
|
import { appState } from "../appState";
|
|
import { loadModels } from "./models";
|
|
|
|
type JsTreeNode = {
|
|
id: string;
|
|
text: string;
|
|
};
|
|
|
|
function isRealFolderId(id: string) {
|
|
return /^\d+$/.test(id);
|
|
}
|
|
|
|
function selectFolder(node: JsTreeNode) {
|
|
appState.selectedFolderId = Number(node.id);
|
|
appState.selectedFolderName = appState.folders.find((folder) => folder.id === Number(node.id))?.name ?? node.text;
|
|
}
|
|
|
|
async function createFolder(parentId: number | null) {
|
|
const name = await promptDialog({ title: "新建目录", label: "目录名称" });
|
|
if (!name) return;
|
|
await api("/api/folders", {
|
|
method: "POST",
|
|
body: JSON.stringify({ parentId, name })
|
|
});
|
|
await loadFolders();
|
|
}
|
|
|
|
async function renameFolder(folderId: number | null) {
|
|
if (!folderId) return notify("请先选择目录");
|
|
const current = appState.folders.find((folder) => folder.id === folderId);
|
|
if (!current?.parent_id) return notify("根目录不能重命名");
|
|
const name = await promptDialog({ title: "重命名目录", label: "目录名称", value: current.name });
|
|
if (!name) return;
|
|
await api(`/api/folders/${folderId}`, {
|
|
method: "PUT",
|
|
body: JSON.stringify({ name })
|
|
});
|
|
await loadFolders();
|
|
}
|
|
|
|
async function deleteFolder(folderId: number | null) {
|
|
if (!folderId) return notify("请先选择目录");
|
|
const current = appState.folders.find((folder) => folder.id === folderId);
|
|
if (!current?.parent_id) return notify("根目录不能删除");
|
|
const confirmed = await confirmDialog("删除目录会删除目录下所有模型和子目录,是否继续?");
|
|
if (!confirmed) return;
|
|
await api(`/api/folders/${folderId}`, { method: "DELETE" });
|
|
appState.selectedFolderId = null;
|
|
await loadFolders();
|
|
}
|
|
|
|
async function runFolderAction(action: () => Promise<void>) {
|
|
try {
|
|
await action();
|
|
} catch (error) {
|
|
notifyError(error);
|
|
}
|
|
}
|
|
|
|
export async function loadFolders() {
|
|
const result = await api<FolderTreeResponse>("/api/folders");
|
|
appState.folders = result.folders;
|
|
const root = appState.folders.find((folder) => folder.parent_id === null);
|
|
appState.selectedFolderId ??= root?.id ?? null;
|
|
appState.selectedFolderName = appState.folders.find((folder) => folder.id === appState.selectedFolderId)?.name ?? "";
|
|
|
|
$("#folderTree").jstree("destroy");
|
|
$("#folderTree").jstree({
|
|
core: {
|
|
data: result.tree,
|
|
multiple: false
|
|
},
|
|
plugins: ["contextmenu"],
|
|
contextmenu: {
|
|
items(node: JsTreeNode) {
|
|
if (!isRealFolderId(node.id)) return {};
|
|
const folderId = Number(node.id);
|
|
const folder = appState.folders.find((item) => item.id === folderId);
|
|
const canWrite = Boolean(folder?.permissions.write);
|
|
const isSystem = Boolean(folder?.is_system);
|
|
return {
|
|
create: {
|
|
label: "新建目录",
|
|
icon: "tree-menu-icon tree-menu-icon-add",
|
|
_disabled: !canWrite,
|
|
action: () => runFolderAction(async () => {
|
|
selectFolder(node);
|
|
await createFolder(folderId);
|
|
})
|
|
},
|
|
rename: {
|
|
label: "重命名",
|
|
icon: "tree-menu-icon tree-menu-icon-edit",
|
|
_disabled: !canWrite || isSystem,
|
|
action: () => runFolderAction(async () => {
|
|
selectFolder(node);
|
|
await renameFolder(folderId);
|
|
})
|
|
},
|
|
remove: {
|
|
label: "删除",
|
|
icon: "tree-menu-icon tree-menu-icon-delete",
|
|
_disabled: !canWrite || isSystem,
|
|
action: () => runFolderAction(async () => {
|
|
selectFolder(node);
|
|
await deleteFolder(folderId);
|
|
})
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}).on("select_node.jstree", async (_event: JQuery.Event, data: { node: { id: string; text: string } }) => {
|
|
if (!isRealFolderId(data.node.id)) return;
|
|
appState.selectedFolderId = Number(data.node.id);
|
|
appState.selectedFolderName = appState.folders.find((folder) => folder.id === appState.selectedFolderId)?.name ?? data.node.text;
|
|
appState.page = 1;
|
|
await loadModels();
|
|
});
|
|
|
|
if (appState.selectedFolderId) {
|
|
$("#folderTree").on("ready.jstree", () => {
|
|
$("#folderTree").jstree(true).select_node(String(appState.selectedFolderId));
|
|
});
|
|
}
|
|
await loadModels();
|
|
}
|