fix: enhance file uploader with billing support and update translations (#35583)

Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
This commit is contained in:
Wu Tianwei
2026-04-27 14:33:34 +08:00
committed by GitHub
parent 3a28868a6c
commit 89bf75eba9
27 changed files with 190 additions and 43 deletions

View File

@@ -1,9 +1,17 @@
import type { RefObject } from 'react'
import type { UploadDropzoneProps } from '../upload-dropzone'
import type { ProviderContextState } from '@/context/provider-context'
import { fireEvent, render, screen } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import UploadDropzone from '../upload-dropzone'
let mockEnableBilling = false
vi.mock('@/context/provider-context', () => ({
useProviderContextSelector: <T,>(selector: (state: Pick<ProviderContextState, 'enableBilling'>) => T): T =>
selector({ enableBilling: mockEnableBilling }),
}))
// Helper to create mock ref objects for testing
const createMockRef = <T,>(value: T | null = null): RefObject<T | null> => ({ current: value })
@@ -27,6 +35,7 @@ describe('UploadDropzone', () => {
beforeEach(() => {
vi.clearAllMocks()
mockEnableBilling = false
})
describe('rendering', () => {
@@ -46,7 +55,7 @@ describe('UploadDropzone', () => {
it('should render upload icon', () => {
render(<UploadDropzone {...defaultProps} />)
const icon = document.querySelector('svg')
const icon = document.querySelector('.i-ri-upload-cloud-2-line')
expect(icon).toBeInTheDocument()
})
@@ -67,6 +76,51 @@ describe('UploadDropzone', () => {
})
})
describe('tip rendering by billing state', () => {
it('should render tip without total count limit when billing is disabled', () => {
mockEnableBilling = false
render(<UploadDropzone {...defaultProps} />)
const tipWithoutTotal = screen.getByText(/datasetCreation\.stepOne\.uploader\.tip(?!WithTotalLimit)/)
expect(tipWithoutTotal).toBeInTheDocument()
expect(screen.queryByText(/datasetCreation\.stepOne\.uploader\.tipWithTotalLimit/)).not.toBeInTheDocument()
})
it('should render tip with total count limit when billing is enabled', () => {
mockEnableBilling = true
render(<UploadDropzone {...defaultProps} />)
expect(screen.getByText(/datasetCreation\.stepOne\.uploader\.tipWithTotalLimit/)).toBeInTheDocument()
expect(screen.queryByText(/datasetCreation\.stepOne\.uploader\.tip(?!WithTotalLimit)/)).not.toBeInTheDocument()
})
it('should pass file size, batch count and supported types to tip when billing is disabled', () => {
mockEnableBilling = false
render(<UploadDropzone {...defaultProps} />)
const tipText = screen.getByText(/datasetCreation\.stepOne\.uploader\.tip/).textContent ?? ''
expect(tipText).toContain('"size":15')
expect(tipText).toContain('"batchCount":5')
expect(tipText).toContain('"supportTypes":"PDF, DOCX, TXT"')
expect(tipText).not.toContain('"totalCount"')
})
it('should additionally pass total count to tip when billing is enabled', () => {
mockEnableBilling = true
render(<UploadDropzone {...defaultProps} />)
const tipText = screen.getByText(/datasetCreation\.stepOne\.uploader\.tipWithTotalLimit/).textContent ?? ''
expect(tipText).toContain('"size":15')
expect(tipText).toContain('"batchCount":5')
expect(tipText).toContain('"supportTypes":"PDF, DOCX, TXT"')
expect(tipText).toContain('"totalCount":10')
})
})
describe('file input configuration', () => {
it('should allow multiple files when supportBatchUpload is true', () => {
render(<UploadDropzone {...defaultProps} supportBatchUpload={true} />)

View File

@@ -2,8 +2,8 @@
import type { RefObject } from 'react'
import type { FileUploadConfig } from '../hooks/use-file-upload'
import { cn } from '@langgenius/dify-ui/cn'
import { RiUploadCloud2Line } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { useProviderContextSelector } from '@/context/provider-context'
export type UploadDropzoneProps = {
dropRef: RefObject<HTMLDivElement | null>
@@ -31,6 +31,7 @@ const UploadDropzone = ({
onFileChange,
}: UploadDropzoneProps) => {
const { t } = useTranslation()
const enableBilling = useProviderContextSelector(state => state.enableBilling)
return (
<>
@@ -51,7 +52,7 @@ const UploadDropzone = ({
)}
>
<div className="flex min-h-5 items-center justify-center text-sm leading-4 text-text-secondary">
<RiUploadCloud2Line className="mr-2 size-5" />
<span className="mr-2 i-ri-upload-cloud-2-line size-5" />
<span>
{supportBatchUpload
? t('stepOne.uploader.button', { ns: 'datasetCreation' })
@@ -67,13 +68,20 @@ const UploadDropzone = ({
</span>
</div>
<div>
{t('stepOne.uploader.tip', {
ns: 'datasetCreation',
size: fileUploadConfig.file_size_limit,
supportTypes: supportTypesShowNames,
batchCount: fileUploadConfig.batch_count_limit,
totalCount: fileUploadConfig.file_upload_limit,
})}
{enableBilling
? t('stepOne.uploader.tipWithTotalLimit', {
ns: 'datasetCreation',
size: fileUploadConfig.file_size_limit,
supportTypes: supportTypesShowNames,
batchCount: fileUploadConfig.batch_count_limit,
totalCount: fileUploadConfig.file_upload_limit,
})
: t('stepOne.uploader.tip', {
ns: 'datasetCreation',
size: fileUploadConfig.file_size_limit,
supportTypes: supportTypesShowNames,
batchCount: fileUploadConfig.batch_count_limit,
})}
</div>
{dragging && <div ref={dragRef} className="absolute top-0 left-0 h-full w-full" />}
</div>

View File

@@ -1,9 +1,17 @@
import type { RefObject } from 'react'
import type { UploadDropzoneProps } from '../upload-dropzone'
import type { ProviderContextState } from '@/context/provider-context'
import { fireEvent, render, screen } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import UploadDropzone from '../upload-dropzone'
let mockEnableBilling = false
vi.mock('@/context/provider-context', () => ({
useProviderContextSelector: <T,>(selector: (state: Pick<ProviderContextState, 'enableBilling'>) => T): T =>
selector({ enableBilling: mockEnableBilling }),
}))
// Helper to create mock ref objects for testing
const createMockRef = <T,>(value: T | null = null): RefObject<T | null> => ({ current: value })
@@ -28,6 +36,7 @@ describe('UploadDropzone', () => {
beforeEach(() => {
vi.clearAllMocks()
mockEnableBilling = false
})
describe('rendering', () => {
@@ -50,7 +59,7 @@ describe('UploadDropzone', () => {
it('should render upload icon', () => {
render(<UploadDropzone {...defaultProps} />)
const icon = document.querySelector('svg')
const icon = document.querySelector('.i-ri-upload-cloud-2-line')
expect(icon).toBeInTheDocument()
})
@@ -73,6 +82,51 @@ describe('UploadDropzone', () => {
})
})
describe('tip rendering by billing state', () => {
it('should render tip without total count limit when billing is disabled', () => {
mockEnableBilling = false
render(<UploadDropzone {...defaultProps} />)
const tipWithoutTotal = screen.getByText(/datasetCreation\.stepOne\.uploader\.tip(?!WithTotalLimit)/)
expect(tipWithoutTotal).toBeInTheDocument()
expect(screen.queryByText(/datasetCreation\.stepOne\.uploader\.tipWithTotalLimit/)).not.toBeInTheDocument()
})
it('should render tip with total count limit when billing is enabled', () => {
mockEnableBilling = true
render(<UploadDropzone {...defaultProps} />)
expect(screen.getByText(/datasetCreation\.stepOne\.uploader\.tipWithTotalLimit/)).toBeInTheDocument()
expect(screen.queryByText(/datasetCreation\.stepOne\.uploader\.tip(?!WithTotalLimit)/)).not.toBeInTheDocument()
})
it('should pass file size, batch count and supported types to tip when billing is disabled', () => {
mockEnableBilling = false
render(<UploadDropzone {...defaultProps} />)
const tipText = screen.getByText(/datasetCreation\.stepOne\.uploader\.tip/).textContent ?? ''
expect(tipText).toContain('"size":15')
expect(tipText).toContain('"batchCount":5')
expect(tipText).toContain('"supportTypes":"PDF, DOCX, TXT"')
expect(tipText).not.toContain('"totalCount"')
})
it('should additionally pass total count to tip when billing is enabled', () => {
mockEnableBilling = true
render(<UploadDropzone {...defaultProps} />)
const tipText = screen.getByText(/datasetCreation\.stepOne\.uploader\.tipWithTotalLimit/).textContent ?? ''
expect(tipText).toContain('"size":15')
expect(tipText).toContain('"batchCount":5')
expect(tipText).toContain('"supportTypes":"PDF, DOCX, TXT"')
expect(tipText).toContain('"totalCount":10')
})
})
describe('file input configuration', () => {
it('should allow multiple files when supportBatchUpload is true', () => {
render(<UploadDropzone {...defaultProps} supportBatchUpload={true} />)

View File

@@ -1,7 +1,7 @@
import type { ChangeEvent, RefObject } from 'react'
import { cn } from '@langgenius/dify-ui/cn'
import { RiUploadCloud2Line } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { useProviderContextSelector } from '@/context/provider-context'
type FileUploadConfig = {
file_size_limit: number
@@ -37,6 +37,7 @@ const UploadDropzone = ({
allowedExtensions,
}: UploadDropzoneProps) => {
const { t } = useTranslation()
const enableBilling = useProviderContextSelector(state => state.enableBilling)
return (
<>
@@ -57,7 +58,7 @@ const UploadDropzone = ({
)}
>
<div className="flex min-h-5 items-center justify-center text-sm leading-4 text-text-secondary">
<RiUploadCloud2Line className="mr-2 size-5" />
<span className="mr-2 i-ri-upload-cloud-2-line size-5" />
<span>
{supportBatchUpload ? t('stepOne.uploader.button', { ns: 'datasetCreation' }) : t('stepOne.uploader.buttonSingleFile', { ns: 'datasetCreation' })}
{allowedExtensions.length > 0 && (
@@ -66,13 +67,20 @@ const UploadDropzone = ({
</span>
</div>
<div>
{t('stepOne.uploader.tip', {
ns: 'datasetCreation',
size: fileUploadConfig.file_size_limit,
supportTypes: supportTypesShowNames,
batchCount: fileUploadConfig.batch_count_limit,
totalCount: fileUploadConfig.file_upload_limit,
})}
{enableBilling
? t('stepOne.uploader.tipWithTotalLimit', {
ns: 'datasetCreation',
size: fileUploadConfig.file_size_limit,
supportTypes: supportTypesShowNames,
batchCount: fileUploadConfig.batch_count_limit,
totalCount: fileUploadConfig.file_upload_limit,
})
: t('stepOne.uploader.tip', {
ns: 'datasetCreation',
size: fileUploadConfig.file_size_limit,
supportTypes: supportTypesShowNames,
batchCount: fileUploadConfig.batch_count_limit,
})}
</div>
{dragging && <div ref={dragRef} className="absolute top-0 left-0 h-full w-full" />}
</div>

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "إلغاء",
"stepOne.uploader.change": "تغيير",
"stepOne.uploader.failed": "فشل التحميل",
"stepOne.uploader.tip": "يدعم {{supportTypes}}. بحد أقصى {{batchCount}} في الدفعة الواحدة و {{size}} ميجابايت لكل منها. الحد الأقصى الإجمالي {{totalCount}} ملفات.",
"stepOne.uploader.tip": "يدعم {{supportTypes}}. بحد أقصى {{batchCount}} في الدفعة الواحدة و {{size}} ميجابايت لكل منها.",
"stepOne.uploader.tipWithTotalLimit": "يدعم {{supportTypes}}. بحد أقصى {{batchCount}} في الدفعة الواحدة و {{size}} ميجابايت لكل منها. الحد الأقصى الإجمالي {{totalCount}} ملفات.",
"stepOne.uploader.title": "تحميل ملف",
"stepOne.uploader.validation.count": "ملفات متعددة غير مدعومة",
"stepOne.uploader.validation.filesNumber": "لقد وصلت إلى حد تحميل الدفعة البالغ {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Abbrechen",
"stepOne.uploader.change": "Ändern",
"stepOne.uploader.failed": "Hochladen fehlgeschlagen",
"stepOne.uploader.tip": "Unterstützt {{supportTypes}}. Maximal {{batchCount}} Dateien pro Batch und {{size}} MB pro Datei. Insgesamt maximal {{totalCount}} Dateien.",
"stepOne.uploader.tip": "Unterstützt {{supportTypes}}. Maximal {{batchCount}} Dateien pro Batch und {{size}} MB pro Datei.",
"stepOne.uploader.tipWithTotalLimit": "Unterstützt {{supportTypes}}. Maximal {{batchCount}} Dateien pro Batch und {{size}} MB pro Datei. Insgesamt maximal {{totalCount}} Dateien.",
"stepOne.uploader.title": "Textdatei hochladen",
"stepOne.uploader.validation.count": "Mehrere Dateien nicht unterstützt",
"stepOne.uploader.validation.filesNumber": "Sie haben das Limit für die Stapelverarbeitung von {{filesNumber}} erreicht.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Cancel",
"stepOne.uploader.change": "Change",
"stepOne.uploader.failed": "Upload failed",
"stepOne.uploader.tip": "Supports {{supportTypes}}. Max {{batchCount}} in a batch and {{size}} MB each. Max total {{totalCount}} files.",
"stepOne.uploader.tip": "Supports {{supportTypes}}. Max {{batchCount}} in a batch and {{size}} MB each.",
"stepOne.uploader.tipWithTotalLimit": "Supports {{supportTypes}}. Max {{batchCount}} in a batch and {{size}} MB each. Max total {{totalCount}} files.",
"stepOne.uploader.title": "Upload file",
"stepOne.uploader.validation.count": "Multiple files not supported",
"stepOne.uploader.validation.filesNumber": "You have reached the batch upload limit of {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Cancelar",
"stepOne.uploader.change": "Cambiar",
"stepOne.uploader.failed": "Error al cargar",
"stepOne.uploader.tip": "Soporta {{supportTypes}}. Máximo {{batchCount}} archivos por lote y {{size}} MB cada uno. Total máximo de {{totalCount}} archivos.",
"stepOne.uploader.tip": "Soporta {{supportTypes}}. Máximo {{batchCount}} archivos por lote y {{size}} MB cada uno.",
"stepOne.uploader.tipWithTotalLimit": "Soporta {{supportTypes}}. Máximo {{batchCount}} archivos por lote y {{size}} MB cada uno. Total máximo de {{totalCount}} archivos.",
"stepOne.uploader.title": "Cargar archivo",
"stepOne.uploader.validation.count": "No se admiten varios archivos",
"stepOne.uploader.validation.filesNumber": "Has alcanzado el límite de carga por lotes de {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "لغو",
"stepOne.uploader.change": "تغییر",
"stepOne.uploader.failed": "بارگذاری ناموفق بود",
"stepOne.uploader.tip": "پشتیبانی از {{supportTypes}}. حداکثر {{batchCount}} فایل در هر دسته و {{size}} مگابایت برای هر فایل. حداکثر کل {{totalCount}} فایل.",
"stepOne.uploader.tip": "پشتیبانی از {{supportTypes}}. حداکثر {{batchCount}} فایل در هر دسته و {{size}} مگابایت برای هر فایل.",
"stepOne.uploader.tipWithTotalLimit": "پشتیبانی از {{supportTypes}}. حداکثر {{batchCount}} فایل در هر دسته و {{size}} مگابایت برای هر فایل. حداکثر کل {{totalCount}} فایل.",
"stepOne.uploader.title": "بارگذاری فایل",
"stepOne.uploader.validation.count": "چندین فایل پشتیبانی نمیشود",
"stepOne.uploader.validation.filesNumber": "شما به حد مجاز بارگذاری دستهای {{filesNumber}} رسیدهاید.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Annuler",
"stepOne.uploader.change": "Changer",
"stepOne.uploader.failed": "Le téléchargement a échoué",
"stepOne.uploader.tip": "Prend en charge {{supportTypes}}. Maximum {{batchCount}} fichiers par lot et {{size}} MB chacun. Maximum total de {{totalCount}} fichiers.",
"stepOne.uploader.tip": "Prend en charge {{supportTypes}}. Maximum {{batchCount}} fichiers par lot et {{size}} MB chacun.",
"stepOne.uploader.tipWithTotalLimit": "Prend en charge {{supportTypes}}. Maximum {{batchCount}} fichiers par lot et {{size}} MB chacun. Maximum total de {{totalCount}} fichiers.",
"stepOne.uploader.title": "Télécharger le fichier texte",
"stepOne.uploader.validation.count": "Plusieurs fichiers non pris en charge",
"stepOne.uploader.validation.filesNumber": "Vous avez atteint la limite de téléchargement par lot de {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "रद्द करें",
"stepOne.uploader.change": "बदलें",
"stepOne.uploader.failed": "अपलोड विफल रहा",
"stepOne.uploader.tip": "{{supportTypes}} समर्थित है। एक बैच में अधिकतम {{batchCount}} फ़ाइलें और प्रत्येक {{size}} MB। कुल अधिकतम {{totalCount}} फ़ाइलें।",
"stepOne.uploader.tip": "{{supportTypes}} समर्थित है। एक बैच में अधिकतम {{batchCount}} फ़ाइलें और प्रत्येक {{size}} MB।",
"stepOne.uploader.tipWithTotalLimit": "{{supportTypes}} समर्थित है। एक बैच में अधिकतम {{batchCount}} फ़ाइलें और प्रत्येक {{size}} MB। कुल अधिकतम {{totalCount}} फ़ाइलें।",
"stepOne.uploader.title": "फ़ाइल अपलोड करें",
"stepOne.uploader.validation.count": "एकाधिक फ़ाइलें समर्थित नहीं हैं",
"stepOne.uploader.validation.filesNumber": "आपने {{filesNumber}} की बैच अपलोड सीमा तक पहुँच गए हैं।",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Membatalkan",
"stepOne.uploader.change": "Ubah",
"stepOne.uploader.failed": "Upload gagal",
"stepOne.uploader.tip": "Mendukung {{supportTypes}}. Maksimal {{batchCount}} dalam satu batch dan {{size}} MB masing-masing. Total maksimal {{totalCount}} file.",
"stepOne.uploader.tip": "Mendukung {{supportTypes}}. Maksimal {{batchCount}} dalam satu batch dan {{size}} MB masing-masing.",
"stepOne.uploader.tipWithTotalLimit": "Mendukung {{supportTypes}}. Maksimal {{batchCount}} dalam satu batch dan {{size}} MB masing-masing. Total maksimal {{totalCount}} file.",
"stepOne.uploader.title": "Unggah file",
"stepOne.uploader.validation.count": "Beberapa file tidak didukung",
"stepOne.uploader.validation.filesNumber": "Anda telah mencapai batas unggah batch sebanyak {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Annulla",
"stepOne.uploader.change": "Cambia",
"stepOne.uploader.failed": "Caricamento fallito",
"stepOne.uploader.tip": "Supporta {{supportTypes}}. Massimo {{batchCount}} file per batch e {{size}} MB ciascuno. Totale massimo {{totalCount}} file.",
"stepOne.uploader.tip": "Supporta {{supportTypes}}. Massimo {{batchCount}} file per batch e {{size}} MB ciascuno.",
"stepOne.uploader.tipWithTotalLimit": "Supporta {{supportTypes}}. Massimo {{batchCount}} file per batch e {{size}} MB ciascuno. Totale massimo {{totalCount}} file.",
"stepOne.uploader.title": "Carica file",
"stepOne.uploader.validation.count": "Più file non supportati",
"stepOne.uploader.validation.filesNumber": "Hai raggiunto il limite di caricamento batch di {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "キャンセル",
"stepOne.uploader.change": "変更",
"stepOne.uploader.failed": "アップロードに失敗しました",
"stepOne.uploader.tip": "{{supportTypes}}をサポートしています。1バッチあたり最大{{batchCount}}ファイル、各ファイル{{size}}MB まで。合計最大{{totalCount}}ファイル。",
"stepOne.uploader.tip": "{{supportTypes}}をサポートしています。1バッチあたり最大{{batchCount}}ファイル、各ファイル{{size}}MB まで。",
"stepOne.uploader.tipWithTotalLimit": "{{supportTypes}}をサポートしています。1バッチあたり最大{{batchCount}}ファイル、各ファイル{{size}}MB まで。合計最大{{totalCount}}ファイル。",
"stepOne.uploader.title": "テキストファイルをアップロード",
"stepOne.uploader.validation.count": "複数のファイルはサポートされていません",
"stepOne.uploader.validation.filesNumber": "バッチアップロードの制限({{filesNumber}}個)に達しました。",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "취소",
"stepOne.uploader.change": "변경",
"stepOne.uploader.failed": "업로드에 실패했습니다",
"stepOne.uploader.tip": "{{supportTypes}}을(를) 지원합니다. 배치당 최대 {{batchCount}}개 파일, 각 파일당 {{size}}MB까지. 총 최대 {{totalCount}}개 파일.",
"stepOne.uploader.tip": "{{supportTypes}}을(를) 지원합니다. 배치당 최대 {{batchCount}}개 파일, 각 파일당 {{size}}MB까지.",
"stepOne.uploader.tipWithTotalLimit": "{{supportTypes}}을(를) 지원합니다. 배치당 최대 {{batchCount}}개 파일, 각 파일당 {{size}}MB까지. 총 최대 {{totalCount}}개 파일.",
"stepOne.uploader.title": "텍스트 파일 업로드",
"stepOne.uploader.validation.count": "여러 파일은 지원되지 않습니다",
"stepOne.uploader.validation.filesNumber": "일괄 업로드 제한 ({{filesNumber}}개) 에 도달했습니다.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Cancel",
"stepOne.uploader.change": "Change",
"stepOne.uploader.failed": "Upload failed",
"stepOne.uploader.tip": "Supports {{supportTypes}}. Max {{batchCount}} in a batch and {{size}} MB each. Max total {{totalCount}} files.",
"stepOne.uploader.tip": "Supports {{supportTypes}}. Max {{batchCount}} in a batch and {{size}} MB each.",
"stepOne.uploader.tipWithTotalLimit": "Supports {{supportTypes}}. Max {{batchCount}} in a batch and {{size}} MB each. Max total {{totalCount}} files.",
"stepOne.uploader.title": "Upload file",
"stepOne.uploader.validation.count": "Multiple files not supported",
"stepOne.uploader.validation.filesNumber": "You have reached the batch upload limit of {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Anuluj",
"stepOne.uploader.change": "Zmień",
"stepOne.uploader.failed": "Przesyłanie nie powiodło się",
"stepOne.uploader.tip": "Obsługuje {{supportTypes}}. Maksymalnie {{batchCount}} plików w partii, każdy do {{size}} MB. Łącznie maksymalnie {{totalCount}} plików.",
"stepOne.uploader.tip": "Obsługuje {{supportTypes}}. Maksymalnie {{batchCount}} plików w partii, każdy do {{size}} MB.",
"stepOne.uploader.tipWithTotalLimit": "Obsługuje {{supportTypes}}. Maksymalnie {{batchCount}} plików w partii, każdy do {{size}} MB. Łącznie maksymalnie {{totalCount}} plików.",
"stepOne.uploader.title": "Prześlij plik tekstowy",
"stepOne.uploader.validation.count": "Nieobsługiwane przesyłanie wielu plików",
"stepOne.uploader.validation.filesNumber": "Osiągnąłeś limit przesłania partii {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Cancelar",
"stepOne.uploader.change": "Alterar",
"stepOne.uploader.failed": "Falha no envio",
"stepOne.uploader.tip": "Suporta {{supportTypes}}. Máximo de {{batchCount}} arquivos por lote e {{size}} MB cada. Total máximo de {{totalCount}} arquivos.",
"stepOne.uploader.tip": "Suporta {{supportTypes}}. Máximo de {{batchCount}} arquivos por lote e {{size}} MB cada.",
"stepOne.uploader.tipWithTotalLimit": "Suporta {{supportTypes}}. Máximo de {{batchCount}} arquivos por lote e {{size}} MB cada. Total máximo de {{totalCount}} arquivos.",
"stepOne.uploader.title": "Enviar arquivo de texto",
"stepOne.uploader.validation.count": "Vários arquivos não suportados",
"stepOne.uploader.validation.filesNumber": "Limite de upload em massa {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Anulează",
"stepOne.uploader.change": "Schimbă",
"stepOne.uploader.failed": "Încărcarea a eșuat",
"stepOne.uploader.tip": "Acceptă {{supportTypes}}. Maxim {{batchCount}} fișiere pe lot și {{size}} MB fiecare. Total maxim {{totalCount}} fișiere.",
"stepOne.uploader.tip": "Acceptă {{supportTypes}}. Maxim {{batchCount}} fișiere pe lot și {{size}} MB fiecare.",
"stepOne.uploader.tipWithTotalLimit": "Acceptă {{supportTypes}}. Maxim {{batchCount}} fișiere pe lot și {{size}} MB fiecare. Total maxim {{totalCount}} fișiere.",
"stepOne.uploader.title": "Încărcați fișier text",
"stepOne.uploader.validation.count": "Nu se acceptă mai multe fișiere",
"stepOne.uploader.validation.filesNumber": "Ați atins limita de încărcare în lot de {{filesNumber}} fișiere.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Отмена",
"stepOne.uploader.change": "Изменить",
"stepOne.uploader.failed": "Ошибка загрузки",
"stepOne.uploader.tip": "Поддерживаются {{supportTypes}}. Максимум {{batchCount}} файлов за раз, каждый до {{size}} МБ. Всего максимум {{totalCount}} файлов.",
"stepOne.uploader.tip": "Поддерживаются {{supportTypes}}. Максимум {{batchCount}} файлов за раз, каждый до {{size}} МБ.",
"stepOne.uploader.tipWithTotalLimit": "Поддерживаются {{supportTypes}}. Максимум {{batchCount}} файлов за раз, каждый до {{size}} МБ. Всего максимум {{totalCount}} файлов.",
"stepOne.uploader.title": "Загрузить файл",
"stepOne.uploader.validation.count": "Несколько файлов не поддерживаются",
"stepOne.uploader.validation.filesNumber": "Вы достигли лимита пакетной загрузки {{filesNumber}} файлов.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Prekliči",
"stepOne.uploader.change": "Zamenjaj",
"stepOne.uploader.failed": "Nalaganje ni uspelo",
"stepOne.uploader.tip": "Podpira {{supportTypes}}. Največje število datotek v seriji: {{batchCount}}, vsaka do {{size}} MB. Skupaj največ {{totalCount}} datotek.",
"stepOne.uploader.tip": "Podpira {{supportTypes}}. Največje število datotek v seriji: {{batchCount}}, vsaka do {{size}} MB.",
"stepOne.uploader.tipWithTotalLimit": "Podpira {{supportTypes}}. Največje število datotek v seriji: {{batchCount}}, vsaka do {{size}} MB. Skupaj največ {{totalCount}} datotek.",
"stepOne.uploader.title": "Naloži datoteko",
"stepOne.uploader.validation.count": "Podprta je le ena datoteka",
"stepOne.uploader.validation.filesNumber": "Dosegli ste omejitev za pošiljanje {{filesNumber}} datotek.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "ยกเลิก",
"stepOne.uploader.change": "เปลี่ยน",
"stepOne.uploader.failed": "อัปโหลดล้มเหลว",
"stepOne.uploader.tip": "รองรับ {{supportTypes}} สูงสุด {{batchCount}} ไฟล์ต่อชุดและ {{size}} MB แต่ละไฟล์ รวมสูงสุด {{totalCount}} ไฟล์",
"stepOne.uploader.tip": "รองรับ {{supportTypes}} สูงสุด {{batchCount}} ไฟล์ต่อชุดและ {{size}} MB แต่ละไฟล์",
"stepOne.uploader.tipWithTotalLimit": "รองรับ {{supportTypes}} สูงสุด {{batchCount}} ไฟล์ต่อชุดและ {{size}} MB แต่ละไฟล์ รวมสูงสุด {{totalCount}} ไฟล์",
"stepOne.uploader.title": "อัปโหลดไฟล์",
"stepOne.uploader.validation.count": "ไม่รองรับหลายไฟล์",
"stepOne.uploader.validation.filesNumber": "คุณถึงขีดจํากัดการอัปโหลดเป็นชุดของ {{filesNumber}} แล้ว",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "İptal",
"stepOne.uploader.change": "Değiştir",
"stepOne.uploader.failed": "Yükleme başarısız",
"stepOne.uploader.tip": "{{supportTypes}} destekler. Parti başına en fazla {{batchCount}} dosya ve her biri {{size}} MB. Toplam en fazla {{totalCount}} dosya.",
"stepOne.uploader.tip": "{{supportTypes}} destekler. Parti başına en fazla {{batchCount}} dosya ve her biri {{size}} MB.",
"stepOne.uploader.tipWithTotalLimit": "{{supportTypes}} destekler. Parti başına en fazla {{batchCount}} dosya ve her biri {{size}} MB. Toplam en fazla {{totalCount}} dosya.",
"stepOne.uploader.title": "Dosya yükle",
"stepOne.uploader.validation.count": "Birden fazla dosya desteklenmiyor",
"stepOne.uploader.validation.filesNumber": "Toplu yükleme sınırına ulaştınız, {{filesNumber}} dosya.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Скасувати",
"stepOne.uploader.change": "Змінити",
"stepOne.uploader.failed": "Завантаження не вдалося",
"stepOne.uploader.tip": "Підтримуються {{supportTypes}}. Максимум {{batchCount}} файлів за раз, кожен до {{size}} МБ. Загалом максимум {{totalCount}} файлів.",
"stepOne.uploader.tip": "Підтримуються {{supportTypes}}. Максимум {{batchCount}} файлів за раз, кожен до {{size}} МБ.",
"stepOne.uploader.tipWithTotalLimit": "Підтримуються {{supportTypes}}. Максимум {{batchCount}} файлів за раз, кожен до {{size}} МБ. Загалом максимум {{totalCount}} файлів.",
"stepOne.uploader.title": "Завантажити текстовий файл",
"stepOne.uploader.validation.count": "Не підтримується завантаження кількох файлів",
"stepOne.uploader.validation.filesNumber": "Ліміт масового завантаження {{filesNumber}}.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "Hủy",
"stepOne.uploader.change": "Thay đổi",
"stepOne.uploader.failed": "Tải lên thất bại",
"stepOne.uploader.tip": "Hỗ trợ {{supportTypes}}. Tối đa {{batchCount}} tệp trong một lô và {{size}} MB mỗi tệp. Tổng tối đa {{totalCount}} tệp.",
"stepOne.uploader.tip": "Hỗ trợ {{supportTypes}}. Tối đa {{batchCount}} tệp trong một lô và {{size}} MB mỗi tệp.",
"stepOne.uploader.tipWithTotalLimit": "Hỗ trợ {{supportTypes}}. Tối đa {{batchCount}} tệp trong một lô và {{size}} MB mỗi tệp. Tổng tối đa {{totalCount}} tệp.",
"stepOne.uploader.title": "Tải lên tệp văn bản",
"stepOne.uploader.validation.count": "Không hỗ trợ tải lên nhiều tệp",
"stepOne.uploader.validation.filesNumber": "Bạn đã đạt đến giới hạn tải lên lô của {{filesNumber}} tệp.",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "取消",
"stepOne.uploader.change": "更改文件",
"stepOne.uploader.failed": "上传失败",
"stepOne.uploader.tip": "已支持 {{supportTypes}},每批最多 {{batchCount}} 个文件,每个文件不超过 {{size}} MB ,总数不超过 {{totalCount}} 个文件。",
"stepOne.uploader.tip": "已支持 {{supportTypes}},每批最多 {{batchCount}} 个文件,每个文件不超过 {{size}} MB。",
"stepOne.uploader.tipWithTotalLimit": "已支持 {{supportTypes}},每批最多 {{batchCount}} 个文件,每个文件不超过 {{size}} MB总数不超过 {{totalCount}} 个文件。",
"stepOne.uploader.title": "上传文本文件",
"stepOne.uploader.validation.count": "暂不支持多个文件",
"stepOne.uploader.validation.filesNumber": "批量上传限制 {{filesNumber}}。",

View File

@@ -35,7 +35,8 @@
"stepOne.uploader.cancel": "取消",
"stepOne.uploader.change": "更改檔案",
"stepOne.uploader.failed": "上傳失敗",
"stepOne.uploader.tip": "支援 {{supportTypes}}。每批最多 {{batchCount}} 個檔案,每個檔案不超過 {{size}} MB,總數不超過 {{totalCount}} 個檔案。",
"stepOne.uploader.tip": "支援 {{supportTypes}}。每批最多 {{batchCount}} 個檔案,每個檔案不超過 {{size}} MB。",
"stepOne.uploader.tipWithTotalLimit": "支援 {{supportTypes}}。每批最多 {{batchCount}} 個檔案,每個檔案不超過 {{size}} MB總數不超過 {{totalCount}} 個檔案。",
"stepOne.uploader.title": "上傳文字檔案",
"stepOne.uploader.validation.count": "暫不支援多個檔案",
"stepOne.uploader.validation.filesNumber": "批次上傳限制 {{filesNumber}}。",