Commit 52cf3c98 authored by StyleZhang's avatar StyleZhang

feat: segment detail style

parent f53d3343
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon">
<path id="Icon_2" d="M7.99998 13.3332H14M2 13.3332H3.11636C3.44248 13.3332 3.60554 13.3332 3.75899 13.2963C3.89504 13.2637 4.0251 13.2098 4.1444 13.1367C4.27895 13.0542 4.39425 12.9389 4.62486 12.7083L13 4.33316C13.5523 3.78087 13.5523 2.88544 13 2.33316C12.4477 1.78087 11.5523 1.78087 11 2.33316L2.62484 10.7083C2.39424 10.9389 2.27894 11.0542 2.19648 11.1888C2.12338 11.3081 2.0695 11.4381 2.03684 11.5742C2 11.7276 2 11.8907 2 12.2168V13.3332Z" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "16",
"height": "16",
"viewBox": "0 0 16 16",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "Icon"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Icon_2",
"d": "M7.99998 13.3332H14M2 13.3332H3.11636C3.44248 13.3332 3.60554 13.3332 3.75899 13.2963C3.89504 13.2637 4.0251 13.2098 4.1444 13.1367C4.27895 13.0542 4.39425 12.9389 4.62486 12.7083L13 4.33316C13.5523 3.78087 13.5523 2.88544 13 2.33316C12.4477 1.78087 11.5523 1.78087 11 2.33316L2.62484 10.7083C2.39424 10.9389 2.27894 11.0542 2.19648 11.1888C2.12338 11.3081 2.0695 11.4381 2.03684 11.5742C2 11.7276 2 11.8907 2 12.2168V13.3332Z",
"stroke": "currentColor",
"stroke-width": "1.5",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
}
]
},
"name": "Edit03"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Edit03.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
export { default as Edit03 } from './Edit03'
export { default as Loading02 } from './Loading02'
export { default as Trash03 } from './Trash03'
export { default as XClose } from './XClose'
......
'use client'
import type { FC } from 'react'
import React, { memo, useState, useEffect, useMemo } from 'react'
import React, { memo, useEffect, useMemo, useState } from 'react'
import { HashtagIcon } from '@heroicons/react/24/solid'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { omitBy, isNil, debounce } from 'lodash-es'
import { formatNumber } from '@/utils/format'
import { debounce, isNil, omitBy } from 'lodash-es'
import cn from 'classnames'
import { StatusItem } from '../../list'
import { DocumentContext } from '../index'
import s from './style.module.css'
import InfiniteVirtualList from './InfiniteVirtualList'
import { formatNumber } from '@/utils/format'
import Modal from '@/app/components/base/modal'
import Switch from '@/app/components/base/switch'
import Divider from '@/app/components/base/divider'
import Input from '@/app/components/base/input'
import Loading from '@/app/components/base/loading'
import { ToastContext } from '@/app/components/base/toast'
import { SimpleSelect, Item } from '@/app/components/base/select'
import type { Item } from '@/app/components/base/select'
import { SimpleSelect } from '@/app/components/base/select'
import { disableSegment, enableSegment, fetchSegments } from '@/service/datasets'
import type { SegmentDetailModel, SegmentsResponse, SegmentsQuery } from '@/models/datasets'
import type { SegmentDetailModel, SegmentsQuery, SegmentsResponse } from '@/models/datasets'
import { asyncRunSafe } from '@/utils'
import type { CommonResponse } from '@/models/common'
import InfiniteVirtualList from "./InfiniteVirtualList";
import cn from 'classnames'
import { Edit03, XClose } from '@/app/components/base/icons/src/vender/line/general'
export const SegmentIndexTag: FC<{ positionId: string | number; className?: string }> = ({ positionId, className }) => {
const localPositionId = useMemo(() => {
......@@ -41,19 +42,46 @@ export const SegmentIndexTag: FC<{ positionId: string | number; className?: stri
type ISegmentDetailProps = {
segInfo?: Partial<SegmentDetailModel> & { id: string }
onChangeSwitch?: (segId: string, enabled: boolean) => Promise<void>
onCancel: () => void
}
/**
* Show all the contents of the segment
*/
export const SegmentDetail: FC<ISegmentDetailProps> = memo(({
segInfo,
onChangeSwitch }) => {
onChangeSwitch,
onCancel,
}) => {
const { t } = useTranslation()
const renderContent = () => {
if (segInfo?.answer) {
return (
<>
<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>
<div className='mb-1 text-xs font-medium text-gray-500'>ANSWER</div>
<div className='text-md text-gray-800'>{segInfo.content}</div>
</>
)
}
return segInfo?.content
}
return (
<div className={'flex flex-col'}>
<SegmentIndexTag positionId={segInfo?.position || ''} className='w-fit mb-6' />
<div className={s.segModalContent}>{segInfo?.content}</div>
<div className={'flex flex-col relative'}>
<div className='absolute right-0 top-0 flex items-center'>
<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' />
</div>
<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}>
<XClose className='w-4 h-4 text-gray-500' />
</div>
</div>
<SegmentIndexTag positionId={segInfo?.position || ''} className='w-fit mt-[2px] mb-6' />
<div className={s.segModalContent}>{renderContent()}</div>
<div className={s.keywordTitle}>{t('datasetDocuments.segment.keywords')}</div>
<div className={s.keywordWrapper}>
{!segInfo?.keywords?.length
......@@ -74,7 +102,7 @@ export const SegmentDetail: FC<ISegmentDetailProps> = memo(({
<Switch
size='md'
defaultValue={segInfo?.enabled}
onChange={async val => {
onChange={async (val) => {
await onChangeSwitch?.(segInfo?.id || '', val)
}}
/>
......@@ -115,18 +143,12 @@ const Completed: FC<ICompletedProps> = () => {
const [loading, setLoading] = useState(false)
const [total, setTotal] = useState<number | undefined>()
useEffect(() => {
if (lastSegmentsRes !== undefined) {
getSegments(false)
}
}, [selectedStatus, searchValue])
const onChangeStatus = ({ value }: Item) => {
setSelectedStatus(value === 'all' ? 'all' : !!value)
}
const getSegments = async (needLastId?: boolean) => {
const finalLastId = lastSegmentsRes?.data?.[lastSegmentsRes.data.length - 1]?.id || '';
const finalLastId = lastSegmentsRes?.data?.[lastSegmentsRes.data.length - 1]?.id || ''
setLoading(true)
const [e, res] = await asyncRunSafe<SegmentsResponse>(fetchSegments({
datasetId,
......@@ -136,16 +158,22 @@ const Completed: FC<ICompletedProps> = () => {
limit: 9,
keyword: searchValue,
enabled: selectedStatus === 'all' ? 'all' : !!selectedStatus,
}, isNil) as SegmentsQuery
}, isNil) as SegmentsQuery,
}) as Promise<SegmentsResponse>)
if (!e) {
setAllSegments([...(!needLastId ? [] : allSegments), ...splitArray(res.data || [])])
setLastSegmentsRes(res)
if (!lastSegmentsRes) { setTotal(res?.total || 0) }
if (!lastSegmentsRes)
setTotal(res?.total || 0)
}
setLoading(false)
}
useEffect(() => {
if (lastSegmentsRes !== undefined)
getSegments(false)
}, [selectedStatus, searchValue])
const onClickCard = (detail: SegmentDetailModel) => {
setCurrSegment({ segInfo: detail, showModal: true })
}
......@@ -161,13 +189,13 @@ const Completed: FC<ICompletedProps> = () => {
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
for (const item of allSegments) {
for (const seg of item) {
if (seg.id === segId) {
if (seg.id === segId)
seg.enabled = enabled
}
}
}
setAllSegments([...allSegments])
} else {
}
else {
notify({ type: 'error', message: t('common.actionMsg.modificationFailed') })
}
}
......@@ -196,8 +224,8 @@ const Completed: FC<ICompletedProps> = () => {
onChangeSwitch={onChangeSwitch}
onClick={onClickCard}
/>
<Modal isShow={currSegment.showModal} onClose={onCloseModal} className='!max-w-[640px]' closable>
<SegmentDetail segInfo={currSegment.segInfo ?? { id: '' }} onChangeSwitch={onChangeSwitch} />
<Modal isShow={currSegment.showModal} onClose={() => {}} className='!max-w-[640px]'>
<SegmentDetail segInfo={currSegment.segInfo ?? { id: '' }} onChangeSwitch={onChangeSwitch} onCancel={onCloseModal} />
</Modal>
</>
)
......
import React, { FC } from "react";
import cn from "classnames";
import { SegmentDetailModel } from "@/models/datasets";
import { useTranslation } from "react-i18next";
import Divider from "@/app/components/base/divider";
import { SegmentIndexTag } from "../documents/detail/completed";
import s from "../documents/detail/completed/style.module.css";
import ReactECharts from "echarts-for-react";
import type { FC } from 'react'
import React from 'react'
import cn from 'classnames'
import { useTranslation } from 'react-i18next'
import ReactECharts from 'echarts-for-react'
import { SegmentIndexTag } from '../documents/detail/completed'
import s from '../documents/detail/completed/style.module.css'
import type { SegmentDetailModel } from '@/models/datasets'
import Divider from '@/app/components/base/divider'
type IScatterChartProps = {
data: Array<number[]>
......@@ -19,8 +20,8 @@ const ScatterChart: FC<IScatterChartProps> = ({ data, curr }) => {
tooltip: {
trigger: 'item',
axisPointer: {
type: 'cross'
}
type: 'cross',
},
},
series: [
{
......@@ -32,49 +33,64 @@ const ScatterChart: FC<IScatterChartProps> = ({ data, curr }) => {
type: 'scatter',
symbolSize: 5,
data,
}
]
};
},
],
}
return (
<ReactECharts option={option} style={{ height: 380, width: 430 }} />
)
}
type IHitDetailProps = {
segInfo?: Partial<SegmentDetailModel> & { id: string };
vectorInfo?: { curr: Array<number[]>; points: Array<number[]> };
};
segInfo?: Partial<SegmentDetailModel> & { id: string }
vectorInfo?: { curr: Array<number[]>; points: Array<number[]> }
}
const HitDetail: FC<IHitDetailProps> = ({ segInfo, vectorInfo }) => {
const { t } = useTranslation();
const { t } = useTranslation()
const renderContent = () => {
if (segInfo?.answer) {
return (
<>
<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-1 text-xs font-medium text-gray-500'>ANSWER</div>
<div className='text-md text-gray-800'>{segInfo.content}</div>
</>
)
}
return segInfo?.content
}
return (
<div className={"flex flex-row"}>
<div className={'flex flex-row'}>
<div className="flex-1 bg-gray-25 p-6">
<div className="flex items-center">
<SegmentIndexTag
positionId={segInfo?.position || ""}
positionId={segInfo?.position || ''}
className="w-fit mr-6"
/>
<div className={cn(s.commonIcon, s.typeSquareIcon)} />
<span className={cn("mr-6", s.numberInfo)}>
{segInfo?.word_count} {t("datasetDocuments.segment.characters")}
<span className={cn('mr-6', s.numberInfo)}>
{segInfo?.word_count} {t('datasetDocuments.segment.characters')}
</span>
<div className={cn(s.commonIcon, s.targetIcon)} />
<span className={s.numberInfo}>
{segInfo?.hit_count} {t("datasetDocuments.segment.hitCount")}
{segInfo?.hit_count} {t('datasetDocuments.segment.hitCount')}
</span>
</div>
<Divider />
<div className={s.segModalContent}>{segInfo?.content}</div>
<div className={s.segModalContent}>{renderContent()}</div>
<div className={s.keywordTitle}>
{t("datasetDocuments.segment.keywords")}
{t('datasetDocuments.segment.keywords')}
</div>
<div className={s.keywordWrapper}>
{!segInfo?.keywords?.length
? "-"
? '-'
: segInfo?.keywords?.map((word: any) => {
return <div className={s.keyword}>{word}</div>;
return <div className={s.keyword}>{word}</div>
})}
</div>
</div>
......@@ -82,18 +98,18 @@ const HitDetail: FC<IHitDetailProps> = ({ segInfo, vectorInfo }) => {
<div className="flex items-center">
<div className={cn(s.commonIcon, s.bezierCurveIcon)} />
<span className={s.numberInfo}>
{t("datasetDocuments.segment.vectorHash")}
{t('datasetDocuments.segment.vectorHash')}
</span>
</div>
<div
className={cn(s.numberInfo, "w-[400px] truncate text-gray-700 mt-1")}
className={cn(s.numberInfo, 'w-[400px] truncate text-gray-700 mt-1')}
>
{segInfo?.index_node_hash}
</div>
<ScatterChart data={vectorInfo?.points || []} curr={vectorInfo?.curr || []} />
</div>
</div>
);
};
)
}
export default HitDetail;
export default HitDetail
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