|
import { memo, useState } from 'react' |
|
import type { FC } from 'react' |
|
import { useTranslation } from 'react-i18next' |
|
import { useContext } from 'use-context-selector' |
|
import { useParams } from 'next/navigation' |
|
import { RiCloseLine } from '@remixicon/react' |
|
import Modal from '@/app/components/base/modal' |
|
import Button from '@/app/components/base/button' |
|
import AutoHeightTextarea from '@/app/components/base/auto-height-textarea/common' |
|
import { Hash02 } from '@/app/components/base/icons/src/vender/line/general' |
|
import { ToastContext } from '@/app/components/base/toast' |
|
import type { SegmentUpdater } from '@/models/datasets' |
|
import { addSegment } from '@/service/datasets' |
|
import TagInput from '@/app/components/base/tag-input' |
|
|
|
type NewSegmentModalProps = { |
|
isShow: boolean |
|
onCancel: () => void |
|
docForm: string |
|
onSave: () => void |
|
} |
|
|
|
const NewSegmentModal: FC<NewSegmentModalProps> = ({ |
|
isShow, |
|
onCancel, |
|
docForm, |
|
onSave, |
|
}) => { |
|
const { t } = useTranslation() |
|
const { notify } = useContext(ToastContext) |
|
const [question, setQuestion] = useState('') |
|
const [answer, setAnswer] = useState('') |
|
const { datasetId, documentId } = useParams() |
|
const [keywords, setKeywords] = useState<string[]>([]) |
|
const [loading, setLoading] = useState(false) |
|
|
|
const handleCancel = () => { |
|
setQuestion('') |
|
setAnswer('') |
|
onCancel() |
|
setKeywords([]) |
|
} |
|
|
|
const handleSave = async () => { |
|
const params: SegmentUpdater = { content: '' } |
|
if (docForm === 'qa_model') { |
|
if (!question.trim()) |
|
return notify({ type: 'error', message: t('datasetDocuments.segment.questionEmpty') }) |
|
if (!answer.trim()) |
|
return notify({ type: 'error', message: t('datasetDocuments.segment.answerEmpty') }) |
|
|
|
params.content = question |
|
params.answer = answer |
|
} |
|
else { |
|
if (!question.trim()) |
|
return notify({ type: 'error', message: t('datasetDocuments.segment.contentEmpty') }) |
|
|
|
params.content = question |
|
} |
|
|
|
if (keywords?.length) |
|
params.keywords = keywords |
|
|
|
setLoading(true) |
|
try { |
|
await addSegment({ datasetId, documentId, body: params }) |
|
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) |
|
handleCancel() |
|
onSave() |
|
} |
|
finally { |
|
setLoading(false) |
|
} |
|
} |
|
|
|
const renderContent = () => { |
|
if (docForm === 'qa_model') { |
|
return ( |
|
<> |
|
<div className='mb-1 text-xs font-medium text-gray-500'>QUESTION</div> |
|
<AutoHeightTextarea |
|
outerClassName='mb-4' |
|
className='leading-6 text-md text-gray-800' |
|
value={question} |
|
placeholder={t('datasetDocuments.segment.questionPlaceholder') || ''} |
|
onChange={e => setQuestion(e.target.value)} |
|
autoFocus |
|
/> |
|
<div className='mb-1 text-xs font-medium text-gray-500'>ANSWER</div> |
|
<AutoHeightTextarea |
|
outerClassName='mb-4' |
|
className='leading-6 text-md text-gray-800' |
|
value={answer} |
|
placeholder={t('datasetDocuments.segment.answerPlaceholder') || ''} |
|
onChange={e => setAnswer(e.target.value)} |
|
/> |
|
</> |
|
) |
|
} |
|
|
|
return ( |
|
<AutoHeightTextarea |
|
className='leading-6 text-md text-gray-800' |
|
value={question} |
|
placeholder={t('datasetDocuments.segment.contentPlaceholder') || ''} |
|
onChange={e => setQuestion(e.target.value)} |
|
autoFocus |
|
/> |
|
) |
|
} |
|
|
|
return ( |
|
<Modal isShow={isShow} onClose={() => { }} className='pt-8 px-8 pb-6 !max-w-[640px] !rounded-xl'> |
|
<div className={'flex flex-col relative'}> |
|
<div className='absolute right-0 -top-0.5 flex items-center h-6'> |
|
<div className='flex justify-center items-center w-6 h-6 cursor-pointer' onClick={handleCancel}> |
|
<RiCloseLine className='w-4 h-4 text-gray-500' /> |
|
</div> |
|
</div> |
|
<div className='mb-[14px]'> |
|
<span className='inline-flex items-center px-1.5 h-5 border border-gray-200 rounded-md'> |
|
<Hash02 className='mr-0.5 w-3 h-3 text-gray-400' /> |
|
<span className='text-[11px] font-medium text-gray-500 italic'> |
|
{ |
|
docForm === 'qa_model' |
|
? t('datasetDocuments.segment.newQaSegment') |
|
: t('datasetDocuments.segment.newTextSegment') |
|
} |
|
</span> |
|
</span> |
|
</div> |
|
<div className='mb-4 py-1.5 h-[420px] overflow-auto'>{renderContent()}</div> |
|
<div className='text-xs font-medium text-gray-500'>{t('datasetDocuments.segment.keywords')}</div> |
|
<div className='mb-8'> |
|
<TagInput items={keywords} onChange={newKeywords => setKeywords(newKeywords)} /> |
|
</div> |
|
<div className='flex justify-end'> |
|
<Button |
|
onClick={handleCancel}> |
|
{t('common.operation.cancel')} |
|
</Button> |
|
<Button |
|
variant='primary' |
|
onClick={handleSave} |
|
disabled={loading} |
|
> |
|
{t('common.operation.save')} |
|
</Button> |
|
</div> |
|
</div> |
|
</Modal> |
|
) |
|
} |
|
|
|
export default memo(NewSegmentModal) |
|
|