From 2027db74114ed67e912da28f7661350c17c7fcd4 Mon Sep 17 00:00:00 2001 From: Will Miao <13051207myq@gmail.com> Date: Sat, 3 May 2025 16:31:17 +0800 Subject: [PATCH] feat: refactor model deletion functionality with confirmation modal --- static/js/api/baseModelApi.js | 41 ++++++++++++++++++++++++-- static/js/components/CheckpointCard.js | 5 ++-- static/js/components/LoraCard.js | 5 ++-- static/js/utils/modalUtils.js | 36 ++++++++-------------- 4 files changed, 57 insertions(+), 30 deletions(-) diff --git a/static/js/api/baseModelApi.js b/static/js/api/baseModelApi.js index 7991b52e..46c13a42 100644 --- a/static/js/api/baseModelApi.js +++ b/static/js/api/baseModelApi.js @@ -208,8 +208,45 @@ export function replaceModelPreview(filePath, modelType = 'lora') { } // Delete a model (generic) -export function deleteModel(filePath, modelType = 'lora') { - showDeleteModal(filePath); +export async function deleteModel(filePath, modelType = 'lora') { + try { + const endpoint = modelType === 'checkpoint' + ? '/api/checkpoints/delete' + : '/api/delete_model'; + + const response = await fetch(endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + file_path: filePath + }) + }); + + if (!response.ok) { + throw new Error(`Failed to delete ${modelType}: ${response.statusText}`); + } + + const data = await response.json(); + + if (data.success) { + // Remove the card from UI + const card = document.querySelector(`.lora-card[data-filepath="${filePath}"]`); + if (card) { + card.remove(); + } + + showToast(`${modelType} deleted successfully`, 'success'); + return true; + } else { + throw new Error(data.error || `Failed to delete ${modelType}`); + } + } catch (error) { + console.error(`Error deleting ${modelType}:`, error); + showToast(`Failed to delete ${modelType}: ${error.message}`, 'error'); + return false; + } } // Reset and reload models diff --git a/static/js/components/CheckpointCard.js b/static/js/components/CheckpointCard.js index 0e753fea..4b9b7d20 100644 --- a/static/js/components/CheckpointCard.js +++ b/static/js/components/CheckpointCard.js @@ -2,7 +2,8 @@ import { showToast, copyToClipboard } from '../utils/uiHelpers.js'; import { state } from '../state/index.js'; import { showCheckpointModal } from './checkpointModal/index.js'; import { NSFW_LEVELS } from '../utils/constants.js'; -import { replaceCheckpointPreview as apiReplaceCheckpointPreview, saveModelMetadata, deleteCheckpoint } from '../api/checkpointApi.js'; +import { replaceCheckpointPreview as apiReplaceCheckpointPreview, saveModelMetadata } from '../api/checkpointApi.js'; +import { showDeleteModal } from '../utils/modalUtils.js'; export function createCheckpointCard(checkpoint) { const card = document.createElement('div'); @@ -262,7 +263,7 @@ export function createCheckpointCard(checkpoint) { // Delete button click event card.querySelector('.fa-trash')?.addEventListener('click', e => { e.stopPropagation(); - deleteCheckpoint(checkpoint.file_path); + showDeleteModal(checkpoint.file_path); }); // Replace preview button click event diff --git a/static/js/components/LoraCard.js b/static/js/components/LoraCard.js index b5add51d..26c54458 100644 --- a/static/js/components/LoraCard.js +++ b/static/js/components/LoraCard.js @@ -3,7 +3,8 @@ import { state } from '../state/index.js'; import { showLoraModal } from './loraModal/index.js'; import { bulkManager } from '../managers/BulkManager.js'; import { NSFW_LEVELS } from '../utils/constants.js'; -import { replacePreview, deleteModel, saveModelMetadata } from '../api/loraApi.js' +import { replacePreview, saveModelMetadata } from '../api/loraApi.js' +import { showDeleteModal } from '../utils/modalUtils.js'; export function createLoraCard(lora) { const card = document.createElement('div'); @@ -260,7 +261,7 @@ export function createLoraCard(lora) { // Delete button click event card.querySelector('.fa-trash')?.addEventListener('click', e => { e.stopPropagation(); - deleteModel(lora.file_path); + showDeleteModal(lora.file_path); }); // Replace preview button click event diff --git a/static/js/utils/modalUtils.js b/static/js/utils/modalUtils.js index 414eceb0..0bb098f6 100644 --- a/static/js/utils/modalUtils.js +++ b/static/js/utils/modalUtils.js @@ -1,6 +1,6 @@ import { modalManager } from '../managers/ModalManager.js'; -import { excludeLora } from '../api/loraApi.js'; -import { excludeCheckpoint } from '../api/checkpointApi.js'; +import { excludeLora, deleteModel as deleteLora } from '../api/loraApi.js'; +import { excludeCheckpoint, deleteCheckpoint } from '../api/checkpointApi.js'; let pendingDeletePath = null; let pendingModelType = null; @@ -31,31 +31,19 @@ export async function confirmDelete() { const card = document.querySelector(`.lora-card[data-filepath="${pendingDeletePath}"]`); try { - // Use the appropriate endpoint based on model type - const endpoint = pendingModelType === 'checkpoint' ? - '/api/checkpoints/delete' : - '/api/delete_model'; - - const response = await fetch(endpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - file_path: pendingDeletePath - }) - }); - - if (response.ok) { - if (card) { - card.remove(); - } - closeDeleteModal(); + // Use appropriate delete function based on model type + if (pendingModelType === 'checkpoint') { + await deleteCheckpoint(pendingDeletePath); } else { - const error = await response.text(); - alert(`Failed to delete model: ${error}`); + await deleteLora(pendingDeletePath); } + + if (card) { + card.remove(); + } + closeDeleteModal(); } catch (error) { + console.error('Error deleting model:', error); alert(`Error deleting model: ${error}`); } }