file-input.tsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import { useFile } from './hooks'
  2. import { useStore } from './store'
  3. import type { FileUpload } from '@/app/components/base/features/types'
  4. import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants'
  5. import { SupportUploadFileTypes } from '@/app/components/workflow/types'
  6. type FileInputProps = {
  7. fileConfig: FileUpload
  8. }
  9. const FileInput = ({
  10. fileConfig,
  11. }: FileInputProps) => {
  12. const files = useStore(s => s.files)
  13. const { handleLocalFileUpload } = useFile(fileConfig)
  14. const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  15. const targetFiles = e.target.files
  16. if (targetFiles) {
  17. if (fileConfig.number_limits) {
  18. for (let i = 0; i < targetFiles.length; i++) {
  19. if (i + 1 + files.length <= fileConfig.number_limits)
  20. handleLocalFileUpload(targetFiles[i])
  21. }
  22. }
  23. else {
  24. handleLocalFileUpload(targetFiles[0])
  25. }
  26. }
  27. }
  28. const allowedFileTypes = fileConfig.allowed_file_types
  29. const isCustom = allowedFileTypes?.includes(SupportUploadFileTypes.custom)
  30. const exts = isCustom ? (fileConfig.allowed_file_extensions || []) : (allowedFileTypes?.map(type => FILE_EXTS[type]) || []).flat().map(item => `.${item}`)
  31. const accept = exts.join(',')
  32. return (
  33. <input
  34. className='absolute block inset-0 opacity-0 text-[0] w-full disabled:cursor-not-allowed cursor-pointer'
  35. onClick={e => ((e.target as HTMLInputElement).value = '')}
  36. type='file'
  37. onChange={handleChange}
  38. accept={accept}
  39. disabled={!!(fileConfig.number_limits && files.length >= fileConfig?.number_limits)}
  40. multiple={!!fileConfig.number_limits && fileConfig.number_limits > 1}
  41. />
  42. )
  43. }
  44. export default FileInput