form.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import { useTranslation } from 'react-i18next'
  2. import { useEmbeddedChatbotContext } from '../context'
  3. import Input from './form-input'
  4. import { PortalSelect } from '@/app/components/base/select'
  5. import { InputVarType } from '@/app/components/workflow/types'
  6. import { FileUploaderInAttachmentWrapper } from '@/app/components/base/file-uploader'
  7. const Form = () => {
  8. const { t } = useTranslation()
  9. const {
  10. inputsForms,
  11. newConversationInputs,
  12. newConversationInputsRef,
  13. handleNewConversationInputsChange,
  14. isMobile,
  15. } = useEmbeddedChatbotContext()
  16. const handleFormChange = (variable: string, value: any) => {
  17. handleNewConversationInputsChange({
  18. ...newConversationInputsRef.current,
  19. [variable]: value,
  20. })
  21. }
  22. const renderField = (form: any) => {
  23. const {
  24. label,
  25. required,
  26. variable,
  27. options,
  28. } = form
  29. if (form.type === 'text-input' || form.type === 'paragraph') {
  30. return (
  31. <Input
  32. form={form}
  33. value={newConversationInputs[variable]}
  34. onChange={handleFormChange}
  35. />
  36. )
  37. }
  38. if (form.type === 'number') {
  39. return (
  40. <input
  41. className="grow h-9 rounded-lg bg-gray-100 px-2.5 outline-none appearance-none"
  42. type="number"
  43. value={newConversationInputs[variable] || ''}
  44. onChange={e => handleFormChange(variable, e.target.value)}
  45. placeholder={`${label}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
  46. />
  47. )
  48. }
  49. if (form.type === 'number') {
  50. return (
  51. <input
  52. className="grow h-9 rounded-lg bg-gray-100 px-2.5 outline-none appearance-none"
  53. type="number"
  54. value={newConversationInputs[variable] || ''}
  55. onChange={e => handleFormChange(variable, e.target.value)}
  56. placeholder={`${label}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
  57. />
  58. )
  59. }
  60. if (form.type === InputVarType.singleFile) {
  61. return (
  62. <FileUploaderInAttachmentWrapper
  63. value={newConversationInputs[variable] ? [newConversationInputs[variable]] : []}
  64. onChange={files => handleFormChange(variable, files[0])}
  65. fileConfig={{
  66. allowed_file_types: form.allowed_file_types,
  67. allowed_file_extensions: form.allowed_file_extensions,
  68. allowed_file_upload_methods: form.allowed_file_upload_methods,
  69. number_limits: 1,
  70. }}
  71. />
  72. )
  73. }
  74. if (form.type === InputVarType.multiFiles) {
  75. return (
  76. <FileUploaderInAttachmentWrapper
  77. value={newConversationInputs[variable]}
  78. onChange={files => handleFormChange(variable, files)}
  79. fileConfig={{
  80. allowed_file_types: form.allowed_file_types,
  81. allowed_file_extensions: form.allowed_file_extensions,
  82. allowed_file_upload_methods: form.allowed_file_upload_methods,
  83. number_limits: form.max_length,
  84. }}
  85. />
  86. )
  87. }
  88. return (
  89. <PortalSelect
  90. popupClassName='w-[200px]'
  91. value={newConversationInputs[variable]}
  92. items={options.map((option: string) => ({ value: option, name: option }))}
  93. onSelect={item => handleFormChange(variable, item.value as string)}
  94. placeholder={`${label}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
  95. />
  96. )
  97. }
  98. if (!inputsForms.length)
  99. return null
  100. return (
  101. <div className='mb-4 py-2'>
  102. {
  103. inputsForms.map(form => (
  104. <div
  105. key={form.variable}
  106. className={`flex mb-3 last-of-type:mb-0 text-sm text-gray-900 ${isMobile && '!flex-wrap'}`}
  107. >
  108. <div className={`shrink-0 mr-2 py-2 w-[128px] ${isMobile && '!w-full'}`}>{form.label}</div>
  109. {renderField(form)}
  110. </div>
  111. ))
  112. }
  113. </div>
  114. )
  115. }
  116. export default Form