new-segment-modal.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { memo, useState } from 'react'
  2. import type { FC } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import { useContext } from 'use-context-selector'
  5. import { useParams } from 'next/navigation'
  6. import Modal from '@/app/components/base/modal'
  7. import Button from '@/app/components/base/button'
  8. import AutoHeightTextarea from '@/app/components/base/auto-height-textarea/common'
  9. import { Hash02, XClose } from '@/app/components/base/icons/src/vender/line/general'
  10. import { ToastContext } from '@/app/components/base/toast'
  11. import type { SegmentUpdator } from '@/models/datasets'
  12. import { addSegment } from '@/service/datasets'
  13. type NewSegmentModalProps = {
  14. isShow: boolean
  15. onCancel: () => void
  16. docForm: string
  17. onSave: () => void
  18. }
  19. const NewSegmentModal: FC<NewSegmentModalProps> = memo(({
  20. isShow,
  21. onCancel,
  22. docForm,
  23. onSave,
  24. }) => {
  25. const { t } = useTranslation()
  26. const { notify } = useContext(ToastContext)
  27. const [question, setQuestion] = useState('')
  28. const [answer, setAnswer] = useState('')
  29. const { datasetId, documentId } = useParams()
  30. const handleCancel = () => {
  31. setQuestion('')
  32. setAnswer('')
  33. onCancel()
  34. }
  35. const handleSave = async () => {
  36. const params: SegmentUpdator = { content: '' }
  37. if (docForm === 'qa_model') {
  38. if (!question.trim())
  39. return notify({ type: 'error', message: t('datasetDocuments.segment.questionEmpty') })
  40. if (!answer.trim())
  41. return notify({ type: 'error', message: t('datasetDocuments.segment.answerEmpty') })
  42. params.content = question
  43. params.answer = answer
  44. }
  45. else {
  46. if (!question.trim())
  47. return notify({ type: 'error', message: t('datasetDocuments.segment.contentEmpty') })
  48. params.content = question
  49. }
  50. await addSegment({ datasetId, documentId, body: params })
  51. notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
  52. handleCancel()
  53. onSave()
  54. }
  55. const renderContent = () => {
  56. if (docForm === 'qa_model') {
  57. return (
  58. <>
  59. <div className='mb-1 text-xs font-medium text-gray-500'>QUESTION</div>
  60. <AutoHeightTextarea
  61. outerClassName='mb-4'
  62. className='leading-6 text-md text-gray-800'
  63. value={question}
  64. placeholder={t('datasetDocuments.segment.questionPlaceholder') || ''}
  65. onChange={e => setQuestion(e.target.value)}
  66. autoFocus
  67. />
  68. <div className='mb-1 text-xs font-medium text-gray-500'>ANSWER</div>
  69. <AutoHeightTextarea
  70. outerClassName='mb-4'
  71. className='leading-6 text-md text-gray-800'
  72. value={answer}
  73. placeholder={t('datasetDocuments.segment.answerPlaceholder') || ''}
  74. onChange={e => setAnswer(e.target.value)}
  75. />
  76. </>
  77. )
  78. }
  79. return (
  80. <AutoHeightTextarea
  81. className='leading-6 text-md text-gray-800'
  82. value={question}
  83. placeholder={t('datasetDocuments.segment.contentPlaceholder') || ''}
  84. onChange={e => setQuestion(e.target.value)}
  85. autoFocus
  86. />
  87. )
  88. }
  89. return (
  90. <Modal isShow={isShow} onClose={() => {}} className='pt-8 px-8 pb-6 !max-w-[640px] !rounded-xl'>
  91. <div className={'flex flex-col relative'}>
  92. <div className='absolute right-0 -top-0.5 flex items-center h-6'>
  93. <div className='flex justify-center items-center w-6 h-6 cursor-pointer' onClick={handleCancel}>
  94. <XClose className='w-4 h-4 text-gray-500' />
  95. </div>
  96. </div>
  97. <div className='mb-[14px]'>
  98. <span className='inline-flex items-center px-1.5 h-5 border border-gray-200 rounded-md'>
  99. <Hash02 className='mr-0.5 w-3 h-3 text-gray-400' />
  100. <span className='text-[11px] font-medium text-gray-500 italic'>
  101. {
  102. docForm === 'qa_model'
  103. ? t('datasetDocuments.segment.newQaSegment')
  104. : t('datasetDocuments.segment.newTextSegment')
  105. }
  106. </span>
  107. </span>
  108. </div>
  109. <div className='mb-4 py-1.5 h-[420px] overflow-auto'>{renderContent()}</div>
  110. <div className='mb-2 text-xs font-medium text-gray-500'>{t('datasetDocuments.segment.keywords')}</div>
  111. <div className='mb-8'></div>
  112. <div className='flex justify-end'>
  113. <Button
  114. className='mr-2 !h-9 !px-4 !py-2 text-sm font-medium text-gray-700 !rounded-lg'
  115. onClick={handleCancel}>
  116. {t('common.operation.cancel')}
  117. </Button>
  118. <Button
  119. type='primary'
  120. className='!h-9 !px-4 !py-2 text-sm font-medium !rounded-lg'
  121. onClick={handleSave}>
  122. {t('common.operation.save')}
  123. </Button>
  124. </div>
  125. </div>
  126. </Modal>
  127. )
  128. })
  129. export default NewSegmentModal