优化模型删除后的列表刷新
This commit is contained in:
@@ -63,7 +63,8 @@ async function runFolderAction(action: () => Promise<void>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadFolders() {
|
export async function loadFolders(options: { reloadModels?: boolean } = {}) {
|
||||||
|
const reloadModels = options.reloadModels ?? true;
|
||||||
const result = await api<FolderTreeResponse>("/api/folders");
|
const result = await api<FolderTreeResponse>("/api/folders");
|
||||||
appState.folders = result.folders;
|
appState.folders = result.folders;
|
||||||
const root = appState.folders.find((folder) => folder.parent_id === null);
|
const root = appState.folders.find((folder) => folder.parent_id === null);
|
||||||
@@ -125,8 +126,10 @@ export async function loadFolders() {
|
|||||||
|
|
||||||
if (appState.selectedFolderId) {
|
if (appState.selectedFolderId) {
|
||||||
$("#folderTree").on("ready.jstree", () => {
|
$("#folderTree").on("ready.jstree", () => {
|
||||||
$("#folderTree").jstree(true).select_node(String(appState.selectedFolderId));
|
$("#folderTree").jstree(true).select_node(String(appState.selectedFolderId), true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
await loadModels();
|
if (reloadModels) {
|
||||||
|
await loadModels();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ let dictionariesLoading: Promise<void> | null = null;
|
|||||||
let sceneModelBridgeBound = false;
|
let sceneModelBridgeBound = false;
|
||||||
let pendingSceneModelRequestId = "";
|
let pendingSceneModelRequestId = "";
|
||||||
let pendingSceneModelRequestTimer: number | null = null;
|
let pendingSceneModelRequestTimer: number | null = null;
|
||||||
|
let visibleModels = new Map<number, ModelItem>();
|
||||||
|
|
||||||
export function bindModelActions() {
|
export function bindModelActions() {
|
||||||
const isAdmin = getCurrentUser()?.role === "admin";
|
const isAdmin = getCurrentUser()?.role === "admin";
|
||||||
@@ -123,7 +124,7 @@ export function bindModelActions() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadModels() {
|
export async function loadModels(options: { preserveCards?: boolean } = {}) {
|
||||||
const grid = document.querySelector<HTMLDivElement>("#modelGrid");
|
const grid = document.querySelector<HTMLDivElement>("#modelGrid");
|
||||||
if (!grid || !appState.selectedFolderId) return;
|
if (!grid || !appState.selectedFolderId) return;
|
||||||
await loadDictionaries();
|
await loadDictionaries();
|
||||||
@@ -153,42 +154,85 @@ export async function loadModels() {
|
|||||||
await loadModels();
|
await loadModels();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
grid.innerHTML = result.items.map(renderModelCard).join("") || `<div class="empty-state">当前目录暂无模型</div>`;
|
visibleModels = new Map(result.items.map((item) => [item.id, item]));
|
||||||
grid.querySelectorAll<HTMLButtonElement>("[data-action='preview']").forEach((button) => {
|
renderModelGrid(grid, result.items, options.preserveCards);
|
||||||
const model = result.items.find((item) => item.id === Number(button.dataset.id));
|
bindModelGridActions(grid);
|
||||||
if (model) {
|
}
|
||||||
button.addEventListener("click", async () => {
|
|
||||||
|
function bindModelGridActions(grid: HTMLDivElement) {
|
||||||
|
if (grid.dataset.actionsBound === "true") return;
|
||||||
|
grid.dataset.actionsBound = "true";
|
||||||
|
grid.addEventListener("click", async (event) => {
|
||||||
|
const target = event.target instanceof Element ? event.target : null;
|
||||||
|
const button = target?.closest<HTMLButtonElement>("button[data-action][data-id]");
|
||||||
|
if (!button || !grid.contains(button)) return;
|
||||||
|
const id = Number(button.dataset.id);
|
||||||
|
const model = visibleModels.get(id);
|
||||||
|
try {
|
||||||
|
switch (button.dataset.action) {
|
||||||
|
case "preview": {
|
||||||
|
if (!model) return;
|
||||||
const { openModelPreview } = await import("./preview");
|
const { openModelPreview } = await import("./preview");
|
||||||
openModelPreview(model, loadModels);
|
openModelPreview(model, loadModels);
|
||||||
});
|
break;
|
||||||
|
}
|
||||||
|
case "edit":
|
||||||
|
await editModel(id);
|
||||||
|
break;
|
||||||
|
case "import": {
|
||||||
|
if (!model) return;
|
||||||
|
const { createImportScenePayload, emitImportScenePayload } = await import("./preview");
|
||||||
|
const payload = createImportScenePayload({
|
||||||
|
model,
|
||||||
|
basePointEnabled: false,
|
||||||
|
basePoint: { x: 0, y: 0, z: 0, rx: 0, ry: 0, rz: 0 },
|
||||||
|
selectedOperationIndex: null
|
||||||
|
});
|
||||||
|
emitImportScenePayload(payload);
|
||||||
|
notify("导入场景数据已输出");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "delete":
|
||||||
|
await deleteModel(id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
notifyError(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
grid.querySelectorAll<HTMLButtonElement>("[data-action='edit']").forEach((button) => {
|
|
||||||
button.addEventListener("click", () => editModel(Number(button.dataset.id)));
|
|
||||||
});
|
|
||||||
grid.querySelectorAll<HTMLButtonElement>("[data-action='import']").forEach((button) => {
|
|
||||||
const model = result.items.find((item) => item.id === Number(button.dataset.id));
|
|
||||||
if (!model) return;
|
|
||||||
button.addEventListener("click", async () => {
|
|
||||||
const { createImportScenePayload, emitImportScenePayload } = await import("./preview");
|
|
||||||
const payload = createImportScenePayload({
|
|
||||||
model,
|
|
||||||
basePointEnabled: false,
|
|
||||||
basePoint: { x: 0, y: 0, z: 0, rx: 0, ry: 0, rz: 0 },
|
|
||||||
selectedOperationIndex: null
|
|
||||||
});
|
|
||||||
emitImportScenePayload(payload);
|
|
||||||
notify("导入场景数据已输出");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
grid.querySelectorAll<HTMLButtonElement>("[data-action='delete']").forEach((button) => {
|
|
||||||
button.addEventListener("click", () => deleteModel(Number(button.dataset.id)));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function reloadFoldersAndModels() {
|
function renderModelGrid(grid: HTMLDivElement, items: ModelItem[], preserveCards = false) {
|
||||||
|
if (!preserveCards) {
|
||||||
|
grid.innerHTML = items.map(renderModelCard).join("") || `<div class="empty-state">当前目录暂无模型</div>`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (items.length === 0) {
|
||||||
|
grid.innerHTML = `<div class="empty-state">当前目录暂无模型</div>`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const existingCards = new Map(
|
||||||
|
Array.from(grid.querySelectorAll<HTMLElement>(".model-card[data-model-id]"))
|
||||||
|
.map((card) => [Number(card.dataset.modelId), card])
|
||||||
|
);
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
for (const item of items) {
|
||||||
|
const existingCard = existingCards.get(item.id);
|
||||||
|
if (existingCard) {
|
||||||
|
fragment.append(existingCard);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const template = document.createElement("template");
|
||||||
|
template.innerHTML = renderModelCard(item).trim();
|
||||||
|
fragment.append(template.content);
|
||||||
|
}
|
||||||
|
grid.replaceChildren(fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function reloadFoldersAndModels(preserveModelCards = false) {
|
||||||
const { loadFolders } = await import("./folders");
|
const { loadFolders } = await import("./folders");
|
||||||
await loadFolders();
|
await loadFolders({ reloadModels: false });
|
||||||
|
await loadModels({ preserveCards: preserveModelCards });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadDictionaries(force = false) {
|
async function loadDictionaries(force = false) {
|
||||||
@@ -786,5 +830,5 @@ async function deleteModel(id: number) {
|
|||||||
const confirmed = await confirmDialog("确认删除该模型?");
|
const confirmed = await confirmDialog("确认删除该模型?");
|
||||||
if (!confirmed) return;
|
if (!confirmed) return;
|
||||||
await api(`/api/models/${id}`, { method: "DELETE" });
|
await api(`/api/models/${id}`, { method: "DELETE" });
|
||||||
await reloadFoldersAndModels();
|
await reloadFoldersAndModels(true);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user