feat: Enhance model moving functionality with improved error handling and unique filename generation

This commit is contained in:
Will Miao
2025-08-25 13:08:35 +08:00
parent 1814f83bee
commit 919fed05c5
6 changed files with 159 additions and 60 deletions

View File

@@ -419,6 +419,7 @@ export class BaseModelApiClient {
};
});
// Wait for WebSocket connection to establish
await new Promise((resolve, reject) => {
ws.onopen = resolve;
ws.onerror = reject;
@@ -434,6 +435,7 @@ export class BaseModelApiClient {
throw new Error('Failed to fetch metadata');
}
// Wait for the operation to complete via WebSocket
await operationComplete;
resetAndReload(false);
@@ -749,7 +751,10 @@ export class BaseModelApiClient {
}
if (result.success) {
return result.new_file_path;
return {
original_file_path: result.original_file_path || filePath,
new_file_path: result.new_file_path
};
}
return null;
}
@@ -785,7 +790,6 @@ export class BaseModelApiClient {
throw new Error(`Failed to move ${this.apiConfig.config.displayName}s`);
}
let successFilePaths = [];
if (result.success) {
if (result.failure_count > 0) {
showToast(`Moved ${result.success_count} ${this.apiConfig.config.displayName}s, ${result.failure_count} failed`, 'warning');
@@ -793,7 +797,7 @@ export class BaseModelApiClient {
const failedFiles = result.results
.filter(r => !r.success)
.map(r => {
const fileName = r.path.substring(r.path.lastIndexOf('/') + 1);
const fileName = r.original_file_path.substring(r.original_file_path.lastIndexOf('/') + 1);
return `${fileName}: ${r.message}`;
});
if (failedFiles.length > 0) {
@@ -805,13 +809,12 @@ export class BaseModelApiClient {
} else {
showToast(`Successfully moved ${result.success_count} ${this.apiConfig.config.displayName}s`, 'success');
}
successFilePaths = result.results
.filter(r => r.success)
.map(r => r.path);
// Return the results array with original_file_path and new_file_path
return result.results || [];
} else {
throw new Error(result.message || `Failed to move ${this.apiConfig.config.displayName}s`);
}
return successFilePaths;
}
async bulkDeleteModels(filePaths) {

View File

@@ -177,40 +177,48 @@ class MoveManager {
try {
if (this.bulkFilePaths) {
// Bulk move mode
const movedFilePaths = await apiClient.moveBulkModels(this.bulkFilePaths, targetPath);
const results = await apiClient.moveBulkModels(this.bulkFilePaths, targetPath);
// Update virtual scroller if in active folder view
const pageState = getCurrentPageState();
if (pageState.activeFolder !== null && state.virtualScroller) {
// Remove only successfully moved items
movedFilePaths.forEach(newFilePath => {
// Find original filePath by matching filename
const filename = newFilePath.substring(newFilePath.lastIndexOf('/') + 1);
const originalFilePath = this.bulkFilePaths.find(fp => fp.endsWith('/' + filename));
if (originalFilePath) {
state.virtualScroller.removeItemByFilePath(originalFilePath);
// Remove items that were successfully moved
results.forEach(result => {
if (result.success) {
state.virtualScroller.removeItemByFilePath(result.original_file_path);
}
});
} else {
// Update the model cards' filepath in the DOM
movedFilePaths.forEach(newFilePath => {
const filename = newFilePath.substring(newFilePath.lastIndexOf('/') + 1);
const originalFilePath = this.bulkFilePaths.find(fp => fp.endsWith('/' + filename));
if (originalFilePath) {
state.virtualScroller.updateSingleItem(originalFilePath, {file_path: newFilePath});
// Update the model cards' filepath and filename in the DOM
results.forEach(result => {
if (result.success && result.new_file_path !== result.original_file_path) {
const newFileName = result.new_file_path.substring(result.new_file_path.lastIndexOf('/') + 1);
const baseFileName = newFileName.substring(0, newFileName.lastIndexOf('.'));
state.virtualScroller.updateSingleItem(result.original_file_path, {
file_path: result.new_file_path,
file_name: baseFileName
});
}
});
}
} else {
// Single move mode
const newFilePath = await apiClient.moveSingleModel(this.currentFilePath, targetPath);
const result = await apiClient.moveSingleModel(this.currentFilePath, targetPath);
const pageState = getCurrentPageState();
if (newFilePath) {
if (result && result.new_file_path) {
if (pageState.activeFolder !== null && state.virtualScroller) {
state.virtualScroller.removeItemByFilePath(this.currentFilePath);
} else {
state.virtualScroller.updateSingleItem(this.currentFilePath, {file_path: newFilePath});
} else if (result.new_file_path !== this.currentFilePath) {
// Update both file_path and file_name if they changed
const newFileName = result.new_file_path.substring(result.new_file_path.lastIndexOf('/') + 1);
const baseFileName = newFileName.substring(0, newFileName.lastIndexOf('.'));
state.virtualScroller.updateSingleItem(this.currentFilePath, {
file_path: result.new_file_path,
file_name: baseFileName
});
}
}
}