feat(frontend): add delete confirmation modal for library management
-- Add dedicated delete confirmation modal to admin/library page -- Refactor deleteLibrary() to use modal instead of inline confirm() -- Add showDeleteModal(), hideDeleteModal(), confirmDeleteLibrary() functions -- Modal displays clear warning about what gets deleted -- Improves UX by making the confirmation dialog more prominent and informative
This commit is contained in:
+66
-33
@@ -195,33 +195,7 @@ async function deleteLibrary(libraryId: string): Promise<void> {
|
||||
const library = libraries.find(l => l.id === libraryId);
|
||||
if (!library) return;
|
||||
|
||||
const message = `Are you sure you want to delete "${library.name}"?
|
||||
|
||||
This will remove:
|
||||
• Library metadata from the database
|
||||
• All folder references
|
||||
• All book records from the database
|
||||
|
||||
⚠️ Book files on disk will NOT be deleted.
|
||||
|
||||
This action cannot be undone.`;
|
||||
|
||||
if (!confirm(message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await (window as any).api.delete(`/libraries/${libraryId}`);
|
||||
await (window as any).api.handleVoidResponse(response);
|
||||
|
||||
if ((window as any).showToast?.success) {
|
||||
(window as any).showToast.success('Library deleted successfully');
|
||||
}
|
||||
|
||||
await reloadLibraries();
|
||||
} catch (error) {
|
||||
(window as any).api.handleError(error, 'Failed to delete library');
|
||||
}
|
||||
showDeleteModal(library);
|
||||
}
|
||||
|
||||
// Show library folders
|
||||
@@ -361,6 +335,60 @@ function hideCreateLibraryModal(): void {
|
||||
}
|
||||
}
|
||||
|
||||
// Delete modal state
|
||||
let libraryToDelete: Library | null = null;
|
||||
|
||||
function showDeleteModal(library: Library): void {
|
||||
libraryToDelete = library;
|
||||
|
||||
const modal = document.getElementById('delete-library-modal') as HTMLElement;
|
||||
const content = document.getElementById('delete-modal-content') as HTMLElement;
|
||||
|
||||
if (modal && content) {
|
||||
const message = `Are you sure you want to delete "<strong>${escapeHtmlLocal(library.name)}</strong>"?
|
||||
|
||||
This will remove:
|
||||
• Library metadata from the database
|
||||
• All folder references
|
||||
• All book records from the database
|
||||
|
||||
⚠️ Book files on disk will NOT be deleted.
|
||||
|
||||
This action cannot be undone.`;
|
||||
|
||||
content.innerHTML = message.replace(/\n/g, '<br>');
|
||||
modal.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
function hideDeleteModal(): void {
|
||||
const modal = document.getElementById('delete-library-modal') as HTMLElement;
|
||||
if (modal) {
|
||||
modal.classList.add('hidden');
|
||||
}
|
||||
libraryToDelete = null;
|
||||
}
|
||||
|
||||
async function confirmDeleteLibrary(): Promise<void> {
|
||||
if (!libraryToDelete) return;
|
||||
|
||||
const libraryId = libraryToDelete.id;
|
||||
hideDeleteModal();
|
||||
|
||||
try {
|
||||
const response = await (window as any).api.delete(`/libraries/${libraryId}`);
|
||||
await (window as any).api.handleVoidResponse(response);
|
||||
|
||||
if ((window as any).showToast?.success) {
|
||||
(window as any).showToast.success('Library deleted successfully');
|
||||
}
|
||||
|
||||
await reloadLibraries();
|
||||
} catch (error) {
|
||||
(window as any).api.handleError(error, 'Failed to delete library');
|
||||
}
|
||||
}
|
||||
|
||||
// Local escape HTML helper
|
||||
function escapeHtmlLocal(text: string): string {
|
||||
const div = document.createElement('div');
|
||||
@@ -443,6 +471,12 @@ function handleGlobalClick(event: Event): void {
|
||||
case 'hide-create-modal':
|
||||
hideCreateLibraryModal();
|
||||
break;
|
||||
case 'hide-delete-modal':
|
||||
hideDeleteModal();
|
||||
break;
|
||||
case 'confirm-delete':
|
||||
void confirmDeleteLibrary();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,12 +598,8 @@ function initializeLibraryAdmin(): void {
|
||||
createLibraryForm.addEventListener('submit', handleCreateLibrarySubmit);
|
||||
}
|
||||
|
||||
// Initial data is already SSR'd, no need to fetch
|
||||
// Just store it for updates
|
||||
const ssrLibraries = document.querySelectorAll('#libraries-list [data-library-id]');
|
||||
if (ssrLibraries.length === 0) {
|
||||
// No libraries SSR'd, which is fine
|
||||
}
|
||||
// Load libraries from API on page load
|
||||
void reloadLibraries();
|
||||
}
|
||||
|
||||
// Export functions for global access
|
||||
@@ -585,6 +615,9 @@ function initializeLibraryAdmin(): void {
|
||||
(window as any).navigateFolderBrowser = navigateFolderBrowser;
|
||||
(window as any).selectBrowseFolder = selectBrowseFolder;
|
||||
(window as any).hideFolderBrowser = hideFolderBrowser;
|
||||
(window as any).showDeleteModal = showDeleteModal;
|
||||
(window as any).hideDeleteModal = hideDeleteModal;
|
||||
(window as any).confirmDeleteLibrary = confirmDeleteLibrary;
|
||||
|
||||
// Initialize on DOM ready
|
||||
if (document.readyState === 'loading') {
|
||||
|
||||
Reference in New Issue
Block a user