feat(ui): auto-exit bulk mode after all bulk operations complete

This commit is contained in:
Will Miao
2026-07-06 18:51:33 +08:00
parent 54b44131b6
commit b019326747
2 changed files with 20 additions and 4 deletions

View File

@@ -633,7 +633,7 @@ export class BulkManager {
filePaths.forEach(path => { filePaths.forEach(path => {
state.virtualScroller.removeItemByFilePath(path); state.virtualScroller.removeItemByFilePath(path);
}); });
this.clearSelection(); if (state.bulkMode) this.toggleBulkMode();
if (window.modelDuplicatesManager) { if (window.modelDuplicatesManager) {
window.modelDuplicatesManager.updateDuplicatesBadgeAfterRefresh(); window.modelDuplicatesManager.updateDuplicatesBadgeAfterRefresh();
@@ -763,8 +763,9 @@ export class BulkManager {
`Re-import complete: ${completed} re-imported, ${failed} failed` `Re-import complete: ${completed} re-imported, ${failed} failed`
); );
const { resetAndReload: recipeResetAndReload } = await import('../api/recipeApi.js'); const { resetAndReload: recipeResetAndReload } = await import('../api/recipeApi.js');
recipeResetAndReload(false, { preserveScroll: false });
this.clearSelection(); this.clearSelection();
if (state.bulkMode) this.toggleBulkMode();
recipeResetAndReload(false, { preserveScroll: false });
} else { } else {
state.loadingManager.hide(); state.loadingManager.hide();
showToast('toast.recipes.reimportBulkFailed', {}, 'error'); showToast('toast.recipes.reimportBulkFailed', {}, 'error');
@@ -829,7 +830,7 @@ export class BulkManager {
); );
} }
this.clearSelection(); if (state.bulkMode) this.toggleBulkMode();
} else { } else {
throw new Error(result.error || 'Bulk repair failed'); throw new Error(result.error || 'Bulk repair failed');
} }
@@ -874,6 +875,8 @@ export class BulkManager {
if (this.isStripVisible) { if (this.isStripVisible) {
this.updateThumbnailStrip(); this.updateThumbnailStrip();
} }
if (state.bulkMode) this.toggleBulkMode();
} }
} catch (error) { } catch (error) {
@@ -927,6 +930,7 @@ export class BulkManager {
showToast('toast.models.bulkUpdatesNone', { type: typeLabel }, 'info'); showToast('toast.models.bulkUpdatesNone', { type: typeLabel }, 'info');
} }
if (state.bulkMode) this.toggleBulkMode();
await resetAndReload(false); await resetAndReload(false);
} catch (error) { } catch (error) {
console.error('Error checking updates for selected models:', error); console.error('Error checking updates for selected models:', error);
@@ -1273,6 +1277,8 @@ export class BulkManager {
showToast(toastKey, { count: failCount }, 'warning'); showToast(toastKey, { count: failCount }, 'warning');
} }
if (state.bulkMode) this.toggleBulkMode();
} catch (error) { } catch (error) {
console.error('Error during bulk tag operation:', error); console.error('Error during bulk tag operation:', error);
const toastKey = mode === 'replace' ? 'toast.models.bulkTagsReplaceFailed' : 'toast.models.bulkTagsAddFailed'; const toastKey = mode === 'replace' ? 'toast.models.bulkTagsReplaceFailed' : 'toast.models.bulkTagsAddFailed';
@@ -1398,6 +1404,8 @@ export class BulkManager {
} else { } else {
showToast('toast.models.bulkFavoriteFailed', {}, 'error'); showToast('toast.models.bulkFavoriteFailed', {}, 'error');
} }
if (state.bulkMode) this.toggleBulkMode();
} }
/** /**
@@ -1526,6 +1534,8 @@ export class BulkManager {
showToast('toast.models.bulkContentRatingFailed', {}, 'error'); showToast('toast.models.bulkContentRatingFailed', {}, 'error');
} }
if (state.bulkMode) this.toggleBulkMode();
return successCount > 0; return successCount > 0;
} }
@@ -1580,6 +1590,8 @@ export class BulkManager {
} else { } else {
showToast('toast.models.skipMetadataRefreshFailed', {}, 'error'); showToast('toast.models.skipMetadataRefreshFailed', {}, 'error');
} }
if (state.bulkMode) this.toggleBulkMode();
} }
/** /**
@@ -1674,6 +1686,8 @@ export class BulkManager {
showToast('toast.models.bulkBaseModelUpdateFailed', {}, 'error'); showToast('toast.models.bulkBaseModelUpdateFailed', {}, 'error');
} }
if (state.bulkMode) this.toggleBulkMode();
} catch (error) { } catch (error) {
console.error('Error during bulk base model operation:', error); console.error('Error during bulk base model operation:', error);
showToast('toast.models.bulkBaseModelUpdateFailed', {}, 'error'); showToast('toast.models.bulkBaseModelUpdateFailed', {}, 'error');
@@ -1711,6 +1725,7 @@ export class BulkManager {
// Call the auto-organize method with selected file paths // Call the auto-organize method with selected file paths
await apiClient.autoOrganizeModels(filePaths); await apiClient.autoOrganizeModels(filePaths);
if (state.bulkMode) this.toggleBulkMode();
resetAndReload(true); resetAndReload(true);
} catch (error) { } catch (error) {
console.error('Error during bulk auto-organize:', error); console.error('Error during bulk auto-organize:', error);

View File

@@ -330,8 +330,9 @@ class MoveManager {
.filter(r => r.success) .filter(r => r.success)
.map(r => ({ original_file_path: r.original_file_path, new_file_path: r.new_file_path })); .map(r => ({ original_file_path: r.original_file_path, new_file_path: r.new_file_path }));
// Deselect moving items // Deselect moving items and exit bulk mode
this.bulkFilePaths.forEach(path => bulkManager.deselectItem(path)); this.bulkFilePaths.forEach(path => bulkManager.deselectItem(path));
if (state.bulkMode) bulkManager.toggleBulkMode();
} else { } else {
// Single move mode // Single move mode
const result = await apiClient.moveSingleModel(this.currentFilePath, targetPath, this.useDefaultPath); const result = await apiClient.moveSingleModel(this.currentFilePath, targetPath, this.useDefaultPath);