initial commit
This commit is contained in:
125
web/src/pages/app/modules/folders.ts
Normal file
125
web/src/pages/app/modules/folders.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
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 selectFolder(node: JsTreeNode) {
|
||||
appState.selectedFolderId = Number(node.id);
|
||||
appState.selectedFolderName = 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 isAdmin = getCurrentUser()?.role === "admin";
|
||||
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: isAdmin ? ["contextmenu"] : [],
|
||||
contextmenu: {
|
||||
items(node: JsTreeNode) {
|
||||
const folderId = Number(node.id);
|
||||
const folder = appState.folders.find((item) => item.id === folderId);
|
||||
const isRoot = folder?.parent_id === null;
|
||||
return {
|
||||
create: {
|
||||
label: "新建目录",
|
||||
icon: "tree-menu-icon tree-menu-icon-add",
|
||||
action: () => runFolderAction(async () => {
|
||||
selectFolder(node);
|
||||
await createFolder(folderId);
|
||||
})
|
||||
},
|
||||
rename: {
|
||||
label: "重命名",
|
||||
icon: "tree-menu-icon tree-menu-icon-edit",
|
||||
_disabled: isRoot,
|
||||
action: () => runFolderAction(async () => {
|
||||
selectFolder(node);
|
||||
await renameFolder(folderId);
|
||||
})
|
||||
},
|
||||
remove: {
|
||||
label: "删除",
|
||||
icon: "tree-menu-icon tree-menu-icon-delete",
|
||||
_disabled: isRoot,
|
||||
action: () => runFolderAction(async () => {
|
||||
selectFolder(node);
|
||||
await deleteFolder(folderId);
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}).on("select_node.jstree", async (_event: JQuery.Event, data: { node: { id: string; text: string } }) => {
|
||||
appState.selectedFolderId = Number(data.node.id);
|
||||
appState.selectedFolderName = 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();
|
||||
}
|
||||
Reference in New Issue
Block a user