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": "Contatos",
"calendar": "Calendário",
"settings": "Configurações",
"files": "Ficheiros",
"loading_mailboxes": "Carregando caixas de entrada...",
"push_connected": "Atualizações em tempo real ativas",
"push_disconnected": "Atualizações em tempo real inativas",
@@ -1692,5 +1693,83 @@
"got_it": "Entendi",
"settings": "Configurações",
"dismiss": "Fechar"
},
"files": {
"title": "Ficheiros",
"search_placeholder": "Pesquisar ficheiros...",
"empty_state_title": "Ainda não há ficheiros",
"empty_state_description": "Carregue ficheiros ou crie pastas para começar",
"upload": "Carregar",
"upload_files": "Carregar ficheiros",
"new_folder": "Nova pasta",
"new_folder_name": "Nome da pasta",
"rename": "Renomear",
"rename_title": "Renomear",
"new_name": "Novo nome",
"delete": "Eliminar",
"delete_confirm_title": "Eliminar recurso",
"delete_confirm_message": "Tem a certeza de que deseja eliminar \"{name}\"? Esta ação não pode ser desfeita.",
"download": "Transferir",
"name": "Nome",
"size": "Tamanho",
"modified": "Modificado",
"type": "Tipo",
"folder": "Pasta",
"file": "Ficheiro",
"parent_directory": "Diretório superior",
"breadcrumb_root": "Início",
"drop_files_here": "Largue os ficheiros aqui para carregar",
"uploading": "A carregar...",
"upload_success": "{count, plural, one {1 ficheiro carregado} other {# ficheiros carregados}}",
"upload_error": "Falha ao carregar o ficheiro",
"create_folder_success": "Pasta criada",
"create_folder_error": "Falha ao criar a pasta",
"delete_success": "Eliminado com sucesso",
"delete_error": "Falha ao eliminar",
"rename_success": "Renomeado com sucesso",
"rename_error": "Falha ao renomear",
"download_error": "Falha ao transferir",
"not_available": "O armazenamento de ficheiros WebDAV não está disponível neste servidor",
"cancel": "Cancelar",
"create": "Criar",
"save": "Guardar",
"no_results": "Nenhum ficheiro corresponde à sua pesquisa",
"batch_delete_confirm_message": "Tem a certeza de que deseja eliminar {count, plural, one {1 item} other {# itens}}? Esta ação não pode ser desfeita.",
"batch_delete_success": "{count, plural, one {1 item eliminado} other {# itens eliminados}}",
"grid_view": "Vista em grelha",
"list_view": "Vista em lista",
"details": "Detalhes",
"path": "Caminho",
"preview": "Pré-visualização",
"preview_error": "Falha ao carregar a pré-visualização",
"cut": "Cortar",
"copy": "Copiar",
"paste": "Colar",
"move_success": "{count, plural, one {1 item movido} other {# itens movidos}}",
"move_error": "Falha ao mover",
"paste_success": "Colado com sucesso",
"paste_error": "Falha ao colar",
"new_text_file": "Novo ficheiro de texto",
"file_name": "Nome do ficheiro",
"retry": "Tentar novamente",
"refresh": "Atualizar",
"toggle_favorite": "Alternar favorito",
"duplicate": "Duplicar",
"duplicate_success": "Duplicado com sucesso",
"duplicate_error": "Falha ao duplicar",
"create_file_success": "Ficheiro criado",
"create_file_error": "Falha ao criar ficheiro",
"favorites": "Favoritos",
"recent": "Recentes",
"properties": "Propriedades",
"open_folder": "Abrir pasta",
"upload_folder": "Carregar pasta",
"file_too_large": "\"{name}\" excede o tamanho máximo do ficheiro ({max})",
"undo": "Desfazer",
"undo_success": "Ação desfeita",
"undo_error": "Falha ao desfazer",
"toolbar": "Ações de arquivo",
"file_list": "Ficheiros e pastas",
"context_menu": "Ações"
}
}