123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- 'use client'
- import type { FC } from 'react'
- import React, { useEffect, useState } from 'react'
- import { useTranslation } from 'react-i18next'
- import EditItem, { EditItemType } from '../edit-annotation-modal/edit-item'
- import type { AnnotationItem, HitHistoryItem } from '../type'
- import s from './style.module.css'
- import HitHistoryNoData from './hit-history-no-data'
- import cn from '@/utils/classnames'
- import Pagination from '@/app/components/base/pagination'
- import Drawer from '@/app/components/base/drawer-plus'
- import { MessageCheckRemove } from '@/app/components/base/icons/src/vender/line/communication'
- import Confirm from '@/app/components/base/confirm'
- import TabSlider from '@/app/components/base/tab-slider-plain'
- import { fetchHitHistoryList } from '@/service/annotation'
- import { APP_PAGE_LIMIT } from '@/config'
- import useTimestamp from '@/hooks/use-timestamp'
- type Props = {
- appId: string
- isShow: boolean
- onHide: () => void
- item: AnnotationItem
- onSave: (editedQuery: string, editedAnswer: string) => void
- onRemove: () => void
- }
- enum TabType {
- annotation = 'annotation',
- hitHistory = 'hitHistory',
- }
- const ViewAnnotationModal: FC<Props> = ({
- appId,
- isShow,
- onHide,
- item,
- onSave,
- onRemove,
- }) => {
- const { id, question, answer, created_at: createdAt } = item
- const [newQuestion, setNewQuery] = useState(question)
- const [newAnswer, setNewAnswer] = useState(answer)
- const { t } = useTranslation()
- const { formatTime } = useTimestamp()
- const [currPage, setCurrPage] = React.useState<number>(0)
- const [total, setTotal] = useState(0)
- const [hitHistoryList, setHitHistoryList] = useState<HitHistoryItem[]>([])
- const fetchHitHistory = async (page = 1) => {
- try {
- const { data, total }: any = await fetchHitHistoryList(appId, id, {
- page,
- limit: 10,
- })
- setHitHistoryList(data as HitHistoryItem[])
- setTotal(total)
- }
- catch (e) {
- }
- }
- useEffect(() => {
- fetchHitHistory(currPage + 1)
- }, [currPage])
- const tabs = [
- { value: TabType.annotation, text: t('appAnnotation.viewModal.annotatedResponse') },
- {
- value: TabType.hitHistory,
- text: (
- hitHistoryList.length > 0
- ? (
- <div className='flex items-center space-x-1'>
- <div>{t('appAnnotation.viewModal.hitHistory')}</div>
- <div className='flex px-1.5 item-center rounded-md border border-black/[8%] h-5 text-xs font-medium text-gray-500'>{total} {t(`appAnnotation.viewModal.hit${hitHistoryList.length > 1 ? 's' : ''}`)}</div>
- </div>
- )
- : t('appAnnotation.viewModal.hitHistory')
- ),
- },
- ]
- const [activeTab, setActiveTab] = useState(TabType.annotation)
- const handleSave = (type: EditItemType, editedContent: string) => {
- if (type === EditItemType.Query) {
- setNewQuery(editedContent)
- onSave(editedContent, newAnswer)
- }
- else {
- setNewAnswer(editedContent)
- onSave(newQuestion, editedContent)
- }
- }
- const [showModal, setShowModal] = useState(false)
- const annotationTab = (
- <>
- <EditItem
- type={EditItemType.Query}
- content={question}
- onSave={editedContent => handleSave(EditItemType.Query, editedContent)}
- />
- <EditItem
- type={EditItemType.Answer}
- content={answer}
- onSave={editedContent => handleSave(EditItemType.Answer, editedContent)}
- />
- </>
- )
- const hitHistoryTab = total === 0
- ? (<HitHistoryNoData />)
- : (
- <div>
- <table className={cn(s.table, 'w-full min-w-[440px] border-collapse border-0 text-sm')} >
- <thead className="h-8 leading-8 border-b border-gray-200 text-gray-500 font-bold">
- <tr className='uppercase'>
- <td className='whitespace-nowrap'>{t('appAnnotation.hitHistoryTable.query')}</td>
- <td className='whitespace-nowrap'>{t('appAnnotation.hitHistoryTable.match')}</td>
- <td className='whitespace-nowrap'>{t('appAnnotation.hitHistoryTable.response')}</td>
- <td className='whitespace-nowrap'>{t('appAnnotation.hitHistoryTable.source')}</td>
- <td className='whitespace-nowrap'>{t('appAnnotation.hitHistoryTable.score')}</td>
- <td className='whitespace-nowrap w-[160px]'>{t('appAnnotation.hitHistoryTable.time')}</td>
- </tr>
- </thead>
- <tbody className="text-gray-500">
- {hitHistoryList.map(item => (
- <tr
- key={item.id}
- className={'border-b border-gray-200 h-8 hover:bg-gray-50 cursor-pointer'}
- >
- <td
- className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[250px]'
- title={item.question}
- >{item.question}</td>
- <td
- className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[250px]'
- title={item.match}
- >{item.match}</td>
- <td
- className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[250px]'
- title={item.response}
- >{item.response}</td>
- <td>{item.source}</td>
- <td>{item.score ? item.score.toFixed(2) : '-'}</td>
- <td>{formatTime(item.created_at, t('appLog.dateTimeFormat') as string)}</td>
- </tr>
- ))}
- </tbody>
- </table>
- {(total && total > APP_PAGE_LIMIT)
- ? <Pagination
- current={currPage}
- onChange={setCurrPage}
- total={total}
- />
- : null}
- </div>
- )
- return (
- <div>
- <Drawer
- isShow={isShow}
- onHide={onHide}
- maxWidthClassName='!max-w-[800px]'
- // t('appAnnotation.editModal.title') as string
- title={
- <TabSlider
- className='shrink-0 relative top-[9px]'
- value={activeTab}
- onChange={v => setActiveTab(v as TabType)}
- options={tabs}
- noBorderBottom
- itemClassName='!pb-3.5'
- />
- }
- body={(
- <div>
- <div className='p-6 pb-4 space-y-6'>
- {activeTab === TabType.annotation ? annotationTab : hitHistoryTab}
- </div>
- <Confirm
- isShow={showModal}
- onCancel={() => setShowModal(false)}
- onConfirm={async () => {
- await onRemove()
- setShowModal(false)
- onHide()
- }}
- title={t('appDebug.feature.annotation.removeConfirm')}
- />
- </div>
- )}
- foot={id
- ? (
- <div className='px-4 flex h-16 items-center justify-between border-t border-black/5 bg-gray-50 rounded-bl-xl rounded-br-xl leading-[18px] text-[13px] font-medium text-gray-500'>
- <div
- className='flex items-center pl-3 space-x-2 cursor-pointer'
- onClick={() => setShowModal(true)}
- >
- <MessageCheckRemove />
- <div>{t('appAnnotation.editModal.removeThisCache')}</div>
- </div>
- <div>{t('appAnnotation.editModal.createdAt')} {formatTime(createdAt, t('appLog.dateTimeFormat') as string)}</div>
- </div>
- )
- : undefined}
- />
- </div>
- )
- }
- export default React.memo(ViewAnnotationModal)
|