feat: add WebDAV file browser with auth improvements

Add a new Files section powered by WebDAV for browsing, uploading,
downloading, renaming, and deleting files and folders.

New features:
- WebDAV file browser with grid/list views and breadcrumb navigation
- File upload (drag-and-drop and button), folder creation, rename, delete
- File preview modals for images and other file types
- WebDAV proxy API route to handle authentication
- Navigation rail entry for Files (auto-hidden when WebDAV is unsupported)

Auth improvements:
- Fix premature redirects on calendar, contacts, and settings pages by
  adding explicit auth check on mount before redirecting to login
- Persist active settings tab in localStorage

Other:
- Expose getAuthHeader() and getServerUrl() on JMAPClient
- Add WebDAV store with connection testing and capability detection
- Add i18n translations for file browser in all 8 locales (de, en, es,
  fr, it, ja, nl, pt)
This commit is contained in:
Linus Rath
2026-03-15 05:24:27 +01:00
parent cb74e3bf73
commit 1f1db8fac8
23 changed files with 4179 additions and 12 deletions
+79
View File
@@ -61,6 +61,7 @@
"contacts": "Contactos",
"calendar": "Calendario",
"settings": "Configuración",
"files": "Archivos",
"loading_mailboxes": "Cargando buzones...",
"push_connected": "Actualizaciones en tiempo real activas",
"push_disconnected": "Actualizaciones en tiempo real inactivas",
@@ -1692,5 +1693,83 @@
"got_it": "Entendido",
"settings": "Ajustes",
"dismiss": "Cerrar"
},
"files": {
"title": "Archivos",
"search_placeholder": "Buscar archivos...",
"empty_state_title": "Aún no hay archivos",
"empty_state_description": "Suba archivos o cree carpetas para comenzar",
"upload": "Subir",
"upload_files": "Subir archivos",
"new_folder": "Nueva carpeta",
"new_folder_name": "Nombre de la carpeta",
"rename": "Renombrar",
"rename_title": "Renombrar",
"new_name": "Nuevo nombre",
"delete": "Eliminar",
"delete_confirm_title": "Eliminar recurso",
"delete_confirm_message": "¿Está seguro de que desea eliminar \"{name}\"? Esta acción no se puede deshacer.",
"download": "Descargar",
"name": "Nombre",
"size": "Tamaño",
"modified": "Modificado",
"type": "Tipo",
"folder": "Carpeta",
"file": "Archivo",
"parent_directory": "Directorio superior",
"breadcrumb_root": "Inicio",
"drop_files_here": "Suelte los archivos aquí para subirlos",
"uploading": "Subiendo...",
"upload_success": "{count, plural, one {1 archivo subido} other {# archivos subidos}}",
"upload_error": "Error al subir el archivo",
"create_folder_success": "Carpeta creada",
"create_folder_error": "Error al crear la carpeta",
"delete_success": "Eliminado correctamente",
"delete_error": "Error al eliminar",
"rename_success": "Renombrado correctamente",
"rename_error": "Error al renombrar",
"download_error": "Error al descargar",
"not_available": "El almacenamiento de archivos WebDAV no está disponible en este servidor",
"cancel": "Cancelar",
"create": "Crear",
"save": "Guardar",
"no_results": "Ningún archivo coincide con su búsqueda",
"batch_delete_confirm_message": "¿Está seguro de que desea eliminar {count, plural, one {1 elemento} other {# elementos}}? Esta acción no se puede deshacer.",
"batch_delete_success": "{count, plural, one {1 elemento eliminado} other {# elementos eliminados}}",
"grid_view": "Vista de cuadrícula",
"list_view": "Vista de lista",
"details": "Detalles",
"path": "Ruta",
"preview": "Vista previa",
"preview_error": "Error al cargar la vista previa",
"cut": "Cortar",
"copy": "Copiar",
"paste": "Pegar",
"move_success": "{count, plural, one {1 elemento movido} other {# elementos movidos}}",
"move_error": "Error al mover",
"paste_success": "Pegado correctamente",
"paste_error": "Error al pegar",
"new_text_file": "Nuevo archivo de texto",
"file_name": "Nombre del archivo",
"retry": "Reintentar",
"refresh": "Actualizar",
"toggle_favorite": "Alternar favorito",
"duplicate": "Duplicar",
"duplicate_success": "Duplicado correctamente",
"duplicate_error": "Error al duplicar",
"create_file_success": "Archivo creado",
"create_file_error": "Error al crear el archivo",
"favorites": "Favoritos",
"recent": "Recientes",
"properties": "Propiedades",
"open_folder": "Abrir carpeta",
"upload_folder": "Subir carpeta",
"file_too_large": "\"{name}\" excede el tamaño máximo de archivo ({max})",
"undo": "Deshacer",
"undo_success": "Acción deshecha",
"undo_error": "Error al deshacer",
"toolbar": "Acciones de archivo",
"file_list": "Archivos y carpetas",
"context_menu": "Acciones"
}
}