Commit c12eb8d6 authored by StyleZhang's avatar StyleZhang

feat: update segment

parent 4cf703e3
...@@ -18,8 +18,8 @@ import Input from '@/app/components/base/input' ...@@ -18,8 +18,8 @@ import Input from '@/app/components/base/input'
import { ToastContext } from '@/app/components/base/toast' import { ToastContext } from '@/app/components/base/toast'
import type { Item } from '@/app/components/base/select' import type { Item } from '@/app/components/base/select'
import { SimpleSelect } from '@/app/components/base/select' import { SimpleSelect } from '@/app/components/base/select'
import { disableSegment, enableSegment, fetchSegments } from '@/service/datasets' import { disableSegment, enableSegment, fetchSegments, updateSegment } from '@/service/datasets'
import type { SegmentDetailModel, SegmentsQuery, SegmentsResponse } from '@/models/datasets' import type { SegmentDetailModel, SegmentUpdator, SegmentsQuery, SegmentsResponse } from '@/models/datasets'
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'
...@@ -44,6 +44,7 @@ export const SegmentIndexTag: FC<{ positionId: string | number; className?: stri ...@@ -44,6 +44,7 @@ export const SegmentIndexTag: FC<{ positionId: string | number; className?: stri
type ISegmentDetailProps = { type ISegmentDetailProps = {
segInfo?: Partial<SegmentDetailModel> & { id: string } segInfo?: Partial<SegmentDetailModel> & { id: string }
onChangeSwitch?: (segId: string, enabled: boolean) => Promise<void> onChangeSwitch?: (segId: string, enabled: boolean) => Promise<void>
onUpdate: (segmentId: string, q: string, a: string) => void
onCancel: () => void onCancel: () => void
} }
/** /**
...@@ -52,6 +53,7 @@ type ISegmentDetailProps = { ...@@ -52,6 +53,7 @@ type ISegmentDetailProps = {
export const SegmentDetail: FC<ISegmentDetailProps> = memo(({ export const SegmentDetail: FC<ISegmentDetailProps> = memo(({
segInfo, segInfo,
onChangeSwitch, onChangeSwitch,
onUpdate,
onCancel, onCancel,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
...@@ -64,7 +66,9 @@ export const SegmentDetail: FC<ISegmentDetailProps> = memo(({ ...@@ -64,7 +66,9 @@ export const SegmentDetail: FC<ISegmentDetailProps> = memo(({
setQuestion(segInfo?.content || '') setQuestion(segInfo?.content || '')
setAnswer(segInfo?.answer || '') setAnswer(segInfo?.answer || '')
} }
const handleSave = () => {} const handleSave = () => {
onUpdate(segInfo?.id || '', question, answer)
}
const renderContent = () => { const renderContent = () => {
if (segInfo?.answer) { if (segInfo?.answer) {
...@@ -126,7 +130,8 @@ export const SegmentDetail: FC<ISegmentDetailProps> = memo(({ ...@@ -126,7 +130,8 @@ export const SegmentDetail: FC<ISegmentDetailProps> = memo(({
</> </>
) )
: ( : (
<div className='flex justify-center items-center w-6 h-6 hover:bg-gray-100 rounded-md cursor-pointer'> <div className='group relative flex justify-center items-center w-6 h-6 hover:bg-gray-100 rounded-md cursor-pointer'>
<div className={cn(s.editTip, 'hidden items-center absolute -top-10 px-3 h-[34px] bg-white rounded-lg whitespace-nowrap text-xs font-semibold text-gray-700 group-hover:flex')}>{t('common.operation.edit')}</div>
<Edit03 className='w-4 h-4 text-gray-500' onClick={() => setIsEditing(true)} /> <Edit03 className='w-4 h-4 text-gray-500' onClick={() => setIsEditing(true)} />
</div> </div>
) )
...@@ -187,7 +192,7 @@ type ICompletedProps = { ...@@ -187,7 +192,7 @@ type ICompletedProps = {
const Completed: FC<ICompletedProps> = () => { const Completed: FC<ICompletedProps> = () => {
const { t } = useTranslation() const { t } = useTranslation()
const { notify } = useContext(ToastContext) const { notify } = useContext(ToastContext)
const { datasetId = '', documentId = '' } = useContext(DocumentContext) const { datasetId = '', documentId = '', docForm } = useContext(DocumentContext)
// the current segment id and whether to show the modal // the current segment id and whether to show the modal
const [currSegment, setCurrSegment] = useState<{ segInfo?: SegmentDetailModel; showModal: boolean }>({ showModal: false }) const [currSegment, setCurrSegment] = useState<{ segInfo?: SegmentDetailModel; showModal: boolean }>({ showModal: false })
...@@ -256,6 +261,29 @@ const Completed: FC<ICompletedProps> = () => { ...@@ -256,6 +261,29 @@ const Completed: FC<ICompletedProps> = () => {
} }
} }
const handleUpdateSegment = async (segmentId: string, question: string, answer: string) => {
const params: SegmentUpdator = { content: question }
if (docForm === 'qa_model')
params.answer = answer
const res = await updateSegment({ datasetId, documentId, segmentId, body: params })
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
onCloseModal()
for (const item of allSegments) {
for (const seg of item) {
if (seg.id === segmentId) {
seg.answer = res.data.answer
seg.content = res.data.content
seg.word_count = res.data.word_count
seg.hit_count = res.data.hit_count
seg.index_node_hash = res.data.index_node_hash
seg.enabled = res.data.enabled
}
}
}
setAllSegments([...allSegments])
}
return ( return (
<> <>
<div className={s.docSearchWrapper}> <div className={s.docSearchWrapper}>
...@@ -280,8 +308,13 @@ const Completed: FC<ICompletedProps> = () => { ...@@ -280,8 +308,13 @@ const Completed: FC<ICompletedProps> = () => {
onChangeSwitch={onChangeSwitch} onChangeSwitch={onChangeSwitch}
onClick={onClickCard} onClick={onClickCard}
/> />
<Modal isShow={currSegment.showModal} onClose={() => {}} className='!max-w-[640px]'> <Modal isShow={currSegment.showModal} onClose={() => {}} className='!max-w-[640px] !overflow-visible'>
<SegmentDetail segInfo={currSegment.segInfo ?? { id: '' }} onChangeSwitch={onChangeSwitch} onCancel={onCloseModal} /> <SegmentDetail
segInfo={currSegment.segInfo ?? { id: '' }}
onChangeSwitch={onChangeSwitch}
onUpdate={handleUpdateSegment}
onCancel={onCloseModal}
/>
</Modal> </Modal>
</> </>
) )
......
...@@ -129,3 +129,6 @@ ...@@ -129,3 +129,6 @@
border-radius: 5px; border-radius: 5px;
@apply h-3.5 w-3.5 bg-[#EAECF0]; @apply h-3.5 w-3.5 bg-[#EAECF0];
} }
.editTip {
box-shadow: 0px 4px 6px -2px rgba(16, 24, 40, 0.03), 0px 12px 16px -4px rgba(16, 24, 40, 0.08);
}
...@@ -27,7 +27,7 @@ export const BackCircleBtn: FC<{ onClick: () => void }> = ({ onClick }) => { ...@@ -27,7 +27,7 @@ export const BackCircleBtn: FC<{ onClick: () => void }> = ({ onClick }) => {
) )
} }
export const DocumentContext = createContext<{ datasetId?: string; documentId?: string }>({}) export const DocumentContext = createContext<{ datasetId?: string; documentId?: string; docForm: string }>({ docForm: '' })
type DocumentTitleProps = { type DocumentTitleProps = {
extension?: string extension?: string
...@@ -87,7 +87,7 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => { ...@@ -87,7 +87,7 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
} }
return ( return (
<DocumentContext.Provider value={{ datasetId, documentId }}> <DocumentContext.Provider value={{ datasetId, documentId, docForm: documentDetail?.doc_form || '' }}>
<div className='flex flex-col h-full'> <div className='flex flex-col h-full'>
<div className='flex h-16 border-b-gray-100 border-b items-center p-4'> <div className='flex h-16 border-b-gray-100 border-b items-center p-4'>
<BackCircleBtn onClick={backToPrev} /> <BackCircleBtn onClick={backToPrev} />
......
...@@ -373,3 +373,8 @@ export type RelatedAppResponse = { ...@@ -373,3 +373,8 @@ export type RelatedAppResponse = {
data: Array<RelatedApp> data: Array<RelatedApp>
total: number total: number
} }
export type SegmentUpdator = {
content: string
answer?: string
}
import type { Fetcher } from 'swr' import type { Fetcher } from 'swr'
import qs from 'qs' import qs from 'qs'
import { del, get, patch, post, put } from './base' import { del, get, patch, post, put } from './base'
import type { CreateDocumentReq, DataSet, DataSetListResponse, DocumentDetailResponse, DocumentListResponse, FileIndexingEstimateResponse, HitTestingRecordsResponse, HitTestingResponse, IndexingEstimateResponse, IndexingStatusBatchResponse, IndexingStatusResponse, ProcessRuleResponse, RelatedAppResponse, SegmentsQuery, SegmentsResponse, createDocumentResponse } from '@/models/datasets' import type {
CreateDocumentReq,
DataSet,
DataSetListResponse,
DocumentDetailResponse,
DocumentListResponse,
FileIndexingEstimateResponse,
HitTestingRecordsResponse,
HitTestingResponse,
IndexingEstimateResponse,
IndexingStatusBatchResponse,
IndexingStatusResponse,
ProcessRuleResponse,
RelatedAppResponse,
SegmentDetailModel,
SegmentUpdator,
SegmentsQuery,
SegmentsResponse,
createDocumentResponse,
} from '@/models/datasets'
import type { CommonResponse, DataSourceNotionWorkspace } from '@/models/common' import type { CommonResponse, DataSourceNotionWorkspace } from '@/models/common'
// apis for documents in a dataset // apis for documents in a dataset
...@@ -137,6 +156,10 @@ export const disableSegment: Fetcher<CommonResponse, { datasetId: string; segmen ...@@ -137,6 +156,10 @@ export const disableSegment: Fetcher<CommonResponse, { datasetId: string; segmen
return patch(`/datasets/${datasetId}/segments/${segmentId}/disable`) as Promise<CommonResponse> return patch(`/datasets/${datasetId}/segments/${segmentId}/disable`) as Promise<CommonResponse>
} }
export const updateSegment: Fetcher<{ data: SegmentDetailModel; doc_form: string }, { datasetId: string; documentId: string; segmentId: string; body: SegmentUpdator }> = ({ datasetId, documentId, segmentId, body }) => {
return patch(`/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}`, { body }) as Promise<{ data: SegmentDetailModel; doc_form: string }>
}
// hit testing // hit testing
export const hitTesting: Fetcher<HitTestingResponse, { datasetId: string; queryText: string }> = ({ datasetId, queryText }) => { export const hitTesting: Fetcher<HitTestingResponse, { datasetId: string; queryText: string }> = ({ datasetId, queryText }) => {
return post(`/datasets/${datasetId}/hit-testing`, { body: { query: queryText } }) as Promise<HitTestingResponse> return post(`/datasets/${datasetId}/hit-testing`, { body: { query: queryText } }) as Promise<HitTestingResponse>
......
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