mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
refactor(console): guard file types in the file input dialog box (#3673)
This commit is contained in:
parent
4220f554db
commit
0edb2de4e8
16 changed files with 42 additions and 12 deletions
|
@ -2,7 +2,7 @@ import type { AllowedUploadMimeType, UserAssets } from '@logto/schemas';
|
|||
import { maxUploadFileSize } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
import { type FileRejection, useDropzone } from 'react-dropzone';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import UploaderIcon from '@/assets/images/upload.svg';
|
||||
|
@ -43,35 +43,49 @@ function FileUploader({
|
|||
const api = useApi();
|
||||
|
||||
const onDrop = useCallback(
|
||||
async (acceptedFiles: File[]) => {
|
||||
async (acceptedFiles: File[] = [], fileRejection: FileRejection[] = []) => {
|
||||
setUploadError(undefined);
|
||||
|
||||
const selectedFile = acceptedFiles[0];
|
||||
if (fileRejection.length > 1) {
|
||||
setUploadError(t('components.uploader.error_file_count'));
|
||||
|
||||
if (!selectedFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!allowedMimeTypes.map(String).includes(selectedFile.type)) {
|
||||
setUploadError(
|
||||
t('components.uploader.error_file_type', {
|
||||
extensions: convertToFileExtensionArray(allowedMimeTypes),
|
||||
})
|
||||
);
|
||||
const rejectedFile = fileRejection[0]?.file;
|
||||
|
||||
if (rejectedFile) {
|
||||
/**
|
||||
* Note:
|
||||
* We need to display this invalid file type error, since the user can select an invalid file type by modifying the file input dialog settings.
|
||||
*/
|
||||
if (!allowedMimeTypes.map(String).includes(rejectedFile.type)) {
|
||||
setUploadError(
|
||||
t('components.uploader.error_file_type', {
|
||||
extensions: convertToFileExtensionArray(allowedMimeTypes),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const acceptedFile = acceptedFiles[0];
|
||||
|
||||
if (!acceptedFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fileSizeLimit = Math.min(maxSize, maxUploadFileSize);
|
||||
|
||||
if (selectedFile.size > fileSizeLimit) {
|
||||
if (acceptedFile.size > fileSizeLimit) {
|
||||
setUploadError(t('components.uploader.error_file_size', { size: fileSizeLimit / 1024 }));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', selectedFile);
|
||||
formData.append('file', acceptedFile);
|
||||
|
||||
try {
|
||||
setIsUploading(true);
|
||||
|
@ -91,6 +105,7 @@ function FileUploader({
|
|||
onDrop,
|
||||
disabled: isUploading,
|
||||
multiple: false,
|
||||
accept: Object.fromEntries(allowedMimeTypes.map((mimeType) => [mimeType, []])),
|
||||
});
|
||||
|
||||
return (
|
||||
|
|
|
@ -8,6 +8,7 @@ const components = {
|
|||
error_file_size: 'Dateigröße ist zu groß. Bitte lade eine Datei unter {{size, number}}KB hoch.',
|
||||
error_file_type:
|
||||
'Dateityp wird nicht unterstützt. Nur {{extensions, list(style: narrow; type: conjunction;)}}.',
|
||||
error_file_count: 'Sie können nur 1 Datei hochladen.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const components = {
|
|||
error_file_size: 'File size is too large. Please upload a file under {{size, number}}KB.',
|
||||
error_file_type:
|
||||
'File type is not supported. {{extensions, list(style: narrow; type: conjunction;)}} only.',
|
||||
error_file_count: 'You can only upload 1 file.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ const components = {
|
|||
'El archivo es demasiado grande. Por favor, sube un archivo de menos de {{size, number}}KB.',
|
||||
error_file_type:
|
||||
'El tipo de archivo no es compatible. Solo {{extensions, list(style: narrow; type: conjunction;)}}.',
|
||||
error_file_count: 'Solo puedes subir 1 archivo.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ const components = {
|
|||
'La taille du fichier est trop grande. Veuillez télécharger un fichier de moins de {{size, number}}Ko.',
|
||||
error_file_type:
|
||||
"Le type de fichier n'est pas pris en charge. Uniquement {{extensions, list(style: narrow; type: conjunction;)}}.",
|
||||
error_file_count: 'You can only upload 1 file.', // UNTRANSLATED
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const components = {
|
|||
error_file_size: 'Il file è troppo grande. Carica un file sotto i {{size, number}}KB.',
|
||||
error_file_type:
|
||||
'Formato file non supportato. Sono accettati solo formati {{extensions, list(style: narrow; type: conjunction;)}}.',
|
||||
error_file_count: 'Puoi caricare solo 1 file.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const components = {
|
|||
error_file_size: '{{size, number}}KB以下のファイルをアップロードしてください。',
|
||||
error_file_type:
|
||||
'{{extensions, list(style: narrow; type: conjunction;)}}のみサポートされます。',
|
||||
error_file_count: 'You can only upload 1 file.', // UNTRANSLATED
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const components = {
|
|||
error_file_size: '파일 크기가 너무 커요. {{size, number}}KB 미만의 파일을 업로드해 주세요.',
|
||||
error_file_type:
|
||||
'지원되지 않는 파일 유형이에요. {{extensions, list(style: narrow; type: conjunction;)}} 파일만 사용 가능해요.',
|
||||
error_file_count: 'You can only upload 1 file.', // UNTRANSLATED
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ const components = {
|
|||
'Plik jest zbyt duży. Wyślij plik o rozmiarze mniejszym niż {{size, number}}KB.',
|
||||
error_file_type:
|
||||
'Ten typ pliku nie jest obsługiwany. Obsługiwane formaty to {{extensions, list(style: narrow; type: conjunction;)}}.',
|
||||
error_file_count: 'Możesz przesłać tylko 1 plik.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ const components = {
|
|||
'Tamanho do arquivo é muito grande. Por favor, envie um arquivo abaixo de {{size, number}}KB.',
|
||||
error_file_type:
|
||||
'Tipo de arquivo não é suportado. Apenas {{extensions, list(style: narrow; type: conjunction;)}}.',
|
||||
error_file_count: 'Você só pode enviar 1 arquivo.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ const components = {
|
|||
'O ficheiro é demasiado grande. Por favor carregue um ficheiro com menos de {{size, number}}KB.',
|
||||
error_file_type:
|
||||
'O tipo de ficheiro não é suportado. Apenas {{extensions, list(style: narrow; type: conjunction;)}}.',
|
||||
error_file_count: 'Só é possível carregar 1 ficheiro.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ const components = {
|
|||
'Размер файла слишком большой. Пожалуйста, загрузите файл размером менее {{size, number}} КБ.',
|
||||
error_file_type:
|
||||
'Тип файла не поддерживается. Допустимы только файлы типа {{extensions, list(style: narrow; type: conjunction;)}}.',
|
||||
error_file_count: 'You can only upload 1 file.', // UNTRANSLATED
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ const components = {
|
|||
'Dosya boyutu çok büyük. Lütfen {{size, number}}KB altında bir dosya yükleyin.',
|
||||
error_file_type:
|
||||
'Dosya türü desteklenmiyor. Yalnızca {{extensions, list(style: narrow; type: conjunction;)}} dosyaları kabul edilir.',
|
||||
error_file_count: 'Sadece 1 dosya yükleyebilirsiniz.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const components = {
|
|||
error_file_size: '文件太大了,请上传小于 {{size, number}}KB 的文件。',
|
||||
error_file_type:
|
||||
'不支持该文件类型。只支持 {{extensions, list(style: narrow; type: conjunction;)}} 格式的文件。',
|
||||
error_file_count: '只能上传一个文件。',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const components = {
|
|||
error_file_size: '檔案太大了,請上傳小於 {{size, number}}KB 的檔案。',
|
||||
error_file_type:
|
||||
'不支援該檔案格式,只支援 {{extensions, list(style: narrow; type: conjunction;)}} 格式的檔案。',
|
||||
error_file_count: '你只能上載一個檔案。',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const components = {
|
|||
error_file_size: '文件太大了,請上傳小於 {{size, number}}KB 的文件。',
|
||||
error_file_type:
|
||||
'不支持該文件類型。只支持 {{extensions, list(style: narrow; type: conjunction;)}} 格式的文件。',
|
||||
error_file_count: '您只能上傳一個檔案。',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue