From 7697f3d35b5e3f82afdd80b4d2d8d7a9d9c7ffcb Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Sat, 9 May 2026 00:06:30 +0200 Subject: [PATCH] feat(ui): handle errors on folder creation or folder/file renaming - protect file_management_service::rename_file with validate_storage_name - remove specific rename modal and use the generic modal class (less duplicate) - handle errors on modal action: do not close the modal on error and display this error - hide "Go to parent folder" contextMenu if section is files and folder is the same as current one --- .../services/file_management_service.rs | 7 + static/css/components/dialogs.css | 4 + static/css/components/modals.css | 10 ++ static/index.html | 1 + static/js/app/main.js | 7 +- static/js/app/ui.js | 23 ---- static/js/core/modal.js | 87 ++++++++++-- static/js/features/files/contextMenus.js | 129 +++--------------- static/js/features/files/fileOperations.js | 66 +++++---- 9 files changed, 160 insertions(+), 174 deletions(-) diff --git a/src/application/services/file_management_service.rs b/src/application/services/file_management_service.rs index 0d959eac..1c4bf638 100644 --- a/src/application/services/file_management_service.rs +++ b/src/application/services/file_management_service.rs @@ -6,6 +6,7 @@ use crate::application::ports::storage_ports::{CopyFolderTreeResult, FileReadPor use crate::application::ports::trash_ports::TrashUseCase; use crate::application::services::trash_service::TrashService; use crate::common::errors::DomainError; +use crate::domain::services::path_service::validate_storage_name; use crate::infrastructure::repositories::pg::file_blob_read_repository::FileBlobReadRepository; use crate::infrastructure::repositories::pg::file_blob_write_repository::FileBlobWriteRepository; use crate::infrastructure::repositories::pg::folder_db_repository::FolderDbRepository; @@ -189,6 +190,12 @@ impl FileManagementUseCase for FileManagementService { } async fn rename_file(&self, file_id: &str, new_name: &str) -> Result { + if let Err(reason) = validate_storage_name(new_name) { + return Err(DomainError::validation_error(format!( + "Invalid file name '{new_name}': {reason}" + ))); + } + info!("Renaming file with ID: {} to \"{}\"", file_id, new_name); let renamed_file = self diff --git a/static/css/components/dialogs.css b/static/css/components/dialogs.css index 284b2724..4aec2cfb 100644 --- a/static/css/components/dialogs.css +++ b/static/css/components/dialogs.css @@ -78,6 +78,10 @@ box-shadow: 0 0 0 3px var(--color-accent-ring); } +.rename-dialog input--error { + border-color: var(--color-error-text); +} + .rename-dialog-buttons { display: flex; justify-content: flex-end; diff --git a/static/css/components/modals.css b/static/css/components/modals.css index 570fad38..a69fdd58 100644 --- a/static/css/components/modals.css +++ b/static/css/components/modals.css @@ -253,6 +253,16 @@ color: var(--color-text-placeholder); } +.modal-input--error { + border-color: var(--color-error-text); +} + +.modal-error { + margin-top: 8px; + font-size: 13px; + color: var(--color-error-text); +} + .modal-footer { display: flex; justify-content: flex-end; diff --git a/static/index.html b/static/index.html index 3d5037de..fdfea9b0 100644 --- a/static/index.html +++ b/static/index.html @@ -258,6 +258,7 @@