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