* fix(backups): prevent recursion in path that is backed up

* fix(share): show user currency instead of the default euro in the share page

* fix(files): show descriptive error for unsupported upload type

Unsupported file uploads showed a generic 'Upload failed' toast even
though the server already returns a descriptive 400. The client catch
blocks discarded the error and always showed t('files.uploadError').

The server now emits the i18n key 'files.uploadErrorType' as its error
message; a new translateApiError() helper resolves a server message that
is a known translation key via t() and falls back to the generic key
otherwise. Wired into the three trip-file upload catch sites.

Closes #1363
This commit is contained in:
jubnl
2026-07-01 18:57:16 +02:00
committed by GitHub
parent 0631e34a79
commit 819aa793ae
36 changed files with 275 additions and 18 deletions
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': 'ملف واحد',
'files.uploaded': 'تم رفع {count}',
'files.uploadError': 'فشل الرفع',
'files.uploadErrorType': 'نوع الملف هذا غير مدعوم',
'files.dropzone': 'أسقط الملفات هنا',
'files.dropzoneHint': 'أو انقر للتصفح',
'files.allowedTypes': 'صور، PDF، DOC، DOCX، XLS، XLSX، TXT، CSV · حد أقصى 50 ميغابايت',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 arquivo',
'files.uploaded': '{count} enviado(s)',
'files.uploadError': 'Falha no envio',
'files.uploadErrorType': 'Esse tipo de arquivo não é suportado',
'files.dropzone': 'Solte os arquivos aqui',
'files.dropzoneHint': 'ou clique para escolher',
'files.allowedTypes': 'Imagens, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Máx. 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 soubor',
'files.uploaded': '{count} nahráno',
'files.uploadError': 'Nahrávání se nezdařilo',
'files.uploadErrorType': 'Tento typ souboru není podporován',
'files.dropzone': 'Přetáhněte soubory sem',
'files.dropzoneHint': 'nebo klikněte pro výběr',
'files.allowedTypes': 'Obrázky, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Max 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 Datei',
'files.uploaded': '{count} hochgeladen',
'files.uploadError': 'Fehler beim Hochladen',
'files.uploadErrorType': 'Dieser Dateityp wird nicht unterstützt',
'files.dropzone': 'Dateien hier ablegen',
'files.dropzoneHint': 'oder klicken zum Auswählen',
'files.allowedTypes': 'Bilder, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Max 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 file',
'files.uploaded': '{count} uploaded',
'files.uploadError': 'Upload failed',
'files.uploadErrorType': "This file type isn't supported",
'files.dropzone': 'Drop files here',
'files.dropzoneHint': 'or click to browse',
'files.allowedTypes': 'Images, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Max 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 archivo',
'files.uploaded': '{count} archivos subidos',
'files.uploadError': 'La subida falló',
'files.uploadErrorType': 'Este tipo de archivo no es compatible',
'files.dropzone': 'Arrastra aquí los archivos',
'files.dropzoneHint': 'o haz clic para explorar',
'files.allowedTypes': 'Imágenes, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Máx. 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 fichier',
'files.uploaded': '{count} importés',
'files.uploadError': "Échec de l'import",
'files.uploadErrorType': "Ce type de fichier n'est pas pris en charge",
'files.dropzone': 'Déposez les fichiers ici',
'files.dropzoneHint': 'ou cliquez pour parcourir',
'files.allowedTypes': 'Images, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Max 50 Mo',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 αρχείο',
'files.uploaded': '{count} μεταφορτώθηκαν',
'files.uploadError': 'Η μεταφόρτωση απέτυχε',
'files.uploadErrorType': 'Αυτός ο τύπος αρχείου δεν υποστηρίζεται',
'files.dropzone': 'Αποθέστε αρχεία εδώ',
'files.dropzoneHint': 'ή κάντε κλικ για περιήγηση',
'files.allowedTypes': 'Εικόνες, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Μέγ. 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 fájl',
'files.uploaded': '{count} feltöltve',
'files.uploadError': 'Feltöltés sikertelen',
'files.uploadErrorType': 'Ez a fájltípus nem támogatott',
'files.dropzone': 'Húzd ide a fájlokat',
'files.dropzoneHint': 'vagy kattints a böngészéshez',
'files.allowedTypes': 'Képek, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Max 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 berkas',
'files.uploaded': '{count} diunggah',
'files.uploadError': 'Gagal mengunggah',
'files.uploadErrorType': 'Tipe file ini tidak didukung',
'files.dropzone': 'Jatuhkan file di sini',
'files.dropzoneHint': 'atau klik untuk memilih',
'files.allowedTypes': 'Gambar, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Maks 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 documento',
'files.uploaded': '{count} caricati',
'files.uploadError': 'Caricamento non riuscito',
'files.uploadErrorType': 'Questo tipo di file non è supportato',
'files.dropzone': 'Trascina qui i file',
'files.dropzoneHint': 'oppure clicca per sfogliare',
'files.allowedTypes': 'Immagini, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Max 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1件のファイル',
'files.uploaded': '{count}件アップロード',
'files.uploadError': 'アップロードに失敗しました',
'files.uploadErrorType': 'このファイル形式はサポートされていません',
'files.dropzone': 'ここにファイルをドロップ',
'files.dropzoneHint': 'またはクリックして参照',
'files.allowedTypes': '画像、PDF、DOC、DOCX、XLS、XLSX、TXT、CSV · 最大50MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '파일 1개',
'files.uploaded': '{count}개 업로드됨',
'files.uploadError': '업로드 실패',
'files.uploadErrorType': '지원되지 않는 파일 형식입니다',
'files.dropzone': '여기에 파일을 놓으세요',
'files.dropzoneHint': '또는 클릭하여 탐색',
'files.allowedTypes': '이미지, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · 최대 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 bestand',
'files.uploaded': '{count} geüpload',
'files.uploadError': 'Uploaden mislukt',
'files.uploadErrorType': 'Dit bestandstype wordt niet ondersteund',
'files.dropzone': 'Sleep bestanden hierheen',
'files.dropzoneHint': 'of klik om te bladeren',
'files.allowedTypes': 'Afbeeldingen, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Max 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 plik',
'files.uploaded': '{count} przesłanych',
'files.uploadError': 'Przesyłanie nie powiodło się',
'files.uploadErrorType': 'Ten typ pliku nie jest obsługiwany',
'files.dropzone': 'Przeciągnij pliki tutaj',
'files.dropzoneHint': 'lub kliknij, aby przeglądać',
'files.allowedTypes': 'Obrazki, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Maks 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 файл',
'files.uploaded': '{count} загружено',
'files.uploadError': 'Ошибка загрузки',
'files.uploadErrorType': 'Этот тип файла не поддерживается',
'files.dropzone': 'Перетащите файлы сюда',
'files.dropzoneHint': 'или нажмите для выбора',
'files.allowedTypes': 'Изображения, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Макс. 50 МБ',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 fil',
'files.uploaded': '{count} uppladdade',
'files.uploadError': 'Uppladdning misslyckades',
'files.uploadErrorType': 'Den här filtypen stöds inte',
'files.dropzone': 'Släpp filer här',
'files.dropzoneHint': 'eller klicka för att bläddra',
'files.allowedTypes': 'Foton, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Högst 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 dosya',
'files.uploaded': '{count} yüklendi',
'files.uploadError': 'Yükleme başarısız oldu',
'files.uploadErrorType': 'Bu dosya türü desteklenmiyor',
'files.dropzone': 'Dosyaları buraya bırakın',
'files.dropzoneHint': 'veya göz atmak için tıklayın',
'files.allowedTypes': 'Görsel, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Maks. 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 файл',
'files.uploaded': '{count} завантажено',
'files.uploadError': 'Помилка завантаження',
'files.uploadErrorType': 'Цей тип файлу не підтримується',
'files.dropzone': 'Перетягніть файли сюди',
'files.dropzoneHint': 'або натисніть для вибору',
'files.allowedTypes': 'Зображення, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Макс. 50 МБ',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 個檔案',
'files.uploaded': '已上傳 {count} 個',
'files.uploadError': '上傳失敗',
'files.uploadErrorType': '不支援此檔案類型',
'files.dropzone': '將檔案拖放到此處',
'files.dropzoneHint': '或點選瀏覽',
'files.allowedTypes': '圖片、PDF、DOC、DOCX、XLS、XLSX、TXT、CSV · 最大 50 MB',
+1
View File
@@ -11,6 +11,7 @@ const files: TranslationStrings = {
'files.countSingular': '1 个文件',
'files.uploaded': '已上传 {count} 个',
'files.uploadError': '上传失败',
'files.uploadErrorType': '不支持此文件类型',
'files.dropzone': '将文件拖放到此处',
'files.dropzoneHint': '或点击浏览',
'files.allowedTypes': '图片、PDF、DOC、DOCX、XLS、XLSX、TXT、CSV · 最大 50 MB',