Commit 4cf703e3 authored by StyleZhang's avatar StyleZhang

feat: segment detail support edit

parent 90f718c7
import { forwardRef, useEffect, useRef } from 'react'
import cn from 'classnames'
type AutoHeightTextareaProps =
& React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>
& { outerClassName?: string }
const AutoHeightTextarea = forwardRef<HTMLTextAreaElement, AutoHeightTextareaProps>(
(
{
outerClassName,
value,
className,
placeholder,
autoFocus,
disabled,
...rest
},
outRef,
) => {
const innerRef = useRef<HTMLTextAreaElement>(null)
const ref = outRef || innerRef
useEffect(() => {
if (autoFocus && !disabled && value) {
if (typeof ref !== 'function') {
ref.current?.setSelectionRange(`${value}`.length, `${value}`.length)
ref.current?.focus()
}
}
}, [autoFocus, disabled, ref, value])
return (
<div className={outerClassName}>
<div className='relative'>
<div className={cn(className, 'invisible whitespace-pre-wrap break-all')}>
{!value ? placeholder : `${value}`.replace(/\n$/, '\n ')}
</div>
<textarea
ref={ref}
placeholder={placeholder}
className={cn(className, 'disabled:bg-transparent absolute inset-0 outline-none border-none appearance-none resize-none')}
value={value}
disabled={disabled}
{...rest}
/>
</div>
</div>
)
},
)
export default AutoHeightTextarea
...@@ -67,11 +67,11 @@ const SegmentCard: FC<ISegmentCardProps> = ({ ...@@ -67,11 +67,11 @@ const SegmentCard: FC<ISegmentCardProps> = ({
<> <>
<div className='flex mb-2'> <div className='flex mb-2'>
<div className='mr-2 text-[13px] font-semibold text-gray-400'>Q</div> <div className='mr-2 text-[13px] font-semibold text-gray-400'>Q</div>
<div className='text-[13px]'>{answer}</div> <div className='text-[13px]'>{content}</div>
</div> </div>
<div className='flex'> <div className='flex'>
<div className='mr-2 text-[13px] font-semibold text-gray-400'>A</div> <div className='mr-2 text-[13px] font-semibold text-gray-400'>A</div>
<div className='text-[13px]'>{content}</div> <div className='text-[13px]'>{answer}</div>
</div> </div>
</> </>
) )
......
...@@ -23,6 +23,8 @@ import type { SegmentDetailModel, SegmentsQuery, SegmentsResponse } from '@/mode ...@@ -23,6 +23,8 @@ import type { SegmentDetailModel, SegmentsQuery, SegmentsResponse } from '@/mode
import { asyncRunSafe } from '@/utils' import { asyncRunSafe } from '@/utils'
import type { CommonResponse } from '@/models/common' import type { CommonResponse } from '@/models/common'
import { Edit03, XClose } from '@/app/components/base/icons/src/vender/line/general' import { Edit03, XClose } from '@/app/components/base/icons/src/vender/line/general'
import AutoHeightTextarea from '@/app/components/base/auto-height-textarea/common'
import Button from '@/app/components/base/button'
export const SegmentIndexTag: FC<{ positionId: string | number; className?: string }> = ({ positionId, className }) => { export const SegmentIndexTag: FC<{ positionId: string | number; className?: string }> = ({ positionId, className }) => {
const localPositionId = useMemo(() => { const localPositionId = useMemo(() => {
...@@ -53,28 +55,82 @@ export const SegmentDetail: FC<ISegmentDetailProps> = memo(({ ...@@ -53,28 +55,82 @@ export const SegmentDetail: FC<ISegmentDetailProps> = memo(({
onCancel, onCancel,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const [isEditing, setIsEditing] = useState(false)
const [question, setQuestion] = useState(segInfo?.content || '')
const [answer, setAnswer] = useState(segInfo?.answer || '')
const handleCancel = () => {
setIsEditing(false)
setQuestion(segInfo?.content || '')
setAnswer(segInfo?.answer || '')
}
const handleSave = () => {}
const renderContent = () => { const renderContent = () => {
if (segInfo?.answer) { if (segInfo?.answer) {
return ( return (
<> <>
<div className='mb-1 text-xs font-medium text-gray-500'>QUESTION</div> <div className='mb-1 text-xs font-medium text-gray-500'>QUESTION</div>
<div className='mb-4 text-md text-gray-800'>{segInfo.answer}</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)}
disabled={!isEditing}
/>
<div className='mb-1 text-xs font-medium text-gray-500'>ANSWER</div> <div className='mb-1 text-xs font-medium text-gray-500'>ANSWER</div>
<div className='text-md text-gray-800'>{segInfo.content}</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)}
disabled={!isEditing}
autoFocus
/>
</> </>
) )
} }
return segInfo?.content return (
<AutoHeightTextarea
className='leading-6 text-md text-gray-800'
value={question}
placeholder={t('datasetDocuments.segment.questionPlaceholder') || ''}
onChange={e => setQuestion(e.target.value)}
disabled={!isEditing}
autoFocus
/>
)
} }
return ( return (
<div className={'flex flex-col relative'}> <div className={'flex flex-col relative'}>
<div className='absolute right-0 top-0 flex items-center'> <div className='absolute right-0 top-0 flex items-center h-7'>
<div className='flex justify-center items-center w-6 h-6 hover:bg-gray-100 rounded-md cursor-pointer'> {
<Edit03 className='w-4 h-4 text-gray-500' /> isEditing
</div> ? (
<>
<Button
className='mr-2 !h-7 !px-3 !py-[5px] text-xs font-medium text-gray-700 !rounded-md'
onClick={handleCancel}>
{t('common.operation.cancel')}
</Button>
<Button
type='primary'
className='!h-7 !px-3 !py-[5px] text-xs font-medium !rounded-md'
onClick={handleSave}>
{t('common.operation.save')}
</Button>
</>
)
: (
<div className='flex justify-center items-center w-6 h-6 hover:bg-gray-100 rounded-md cursor-pointer'>
<Edit03 className='w-4 h-4 text-gray-500' onClick={() => setIsEditing(true)} />
</div>
)
}
<div className='mx-3 w-[1px] h-3 bg-gray-200' /> <div className='mx-3 w-[1px] h-3 bg-gray-200' />
<div className='flex justify-center items-center w-6 h-6 cursor-pointer' onClick={onCancel}> <div className='flex justify-center items-center w-6 h-6 cursor-pointer' onClick={onCancel}>
<XClose className='w-4 h-4 text-gray-500' /> <XClose className='w-4 h-4 text-gray-500' />
......
...@@ -54,9 +54,9 @@ const HitDetail: FC<IHitDetailProps> = ({ segInfo, vectorInfo }) => { ...@@ -54,9 +54,9 @@ const HitDetail: FC<IHitDetailProps> = ({ segInfo, vectorInfo }) => {
return ( return (
<> <>
<div className='mt-2 mb-1 text-xs font-medium text-gray-500'>QUESTION</div> <div className='mt-2 mb-1 text-xs font-medium text-gray-500'>QUESTION</div>
<div className='mb-4 text-md text-gray-800'>{segInfo.answer}</div> <div className='mb-4 text-md text-gray-800'>{segInfo.content}</div>
<div className='mb-1 text-xs font-medium text-gray-500'>ANSWER</div> <div className='mb-1 text-xs font-medium text-gray-500'>ANSWER</div>
<div className='text-md text-gray-800'>{segInfo.content}</div> <div className='text-md text-gray-800'>{segInfo.answer}</div>
</> </>
) )
} }
......
...@@ -310,6 +310,8 @@ const translation = { ...@@ -310,6 +310,8 @@ const translation = {
characters: 'characters', characters: 'characters',
hitCount: 'hit count', hitCount: 'hit count',
vectorHash: 'Vector hash: ', vectorHash: 'Vector hash: ',
questionPlaceholder: 'add question here',
answerPlaceholder: 'add answer here',
}, },
} }
......
...@@ -309,6 +309,8 @@ const translation = { ...@@ -309,6 +309,8 @@ const translation = {
characters: '字符', characters: '字符',
hitCount: '命中次数', hitCount: '命中次数',
vectorHash: '向量哈希:', vectorHash: '向量哈希:',
questionPlaceholder: '在这里添加问题',
answerPlaceholder: '在这里添加答案',
}, },
} }
......
...@@ -295,6 +295,7 @@ export type SegmentDetailModel = { ...@@ -295,6 +295,7 @@ export type SegmentDetailModel = {
completed_at: number completed_at: number
error: string | null error: string | null
stopped_at: number stopped_at: number
answer?: string
} }
export type SegmentsResponse = { export type SegmentsResponse = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment