import { useEffect, useMemo, useRef, useState } from 'react' import type { FC } from 'react' import { useTranslation } from 'react-i18next' import { RiArrowDownSLine } from '@remixicon/react' import type { CitationItem } from '../type' import Popup from './popup' export type Resources = { documentId: string documentName: string dataSourceType: string sources: CitationItem[] } type CitationProps = { data: CitationItem[] showHitInfo?: boolean containerClassName?: string } const Citation: FC = ({ data, showHitInfo, containerClassName = 'chat-answer-container', }) => { const { t } = useTranslation() const elesRef = useRef([]) const [limitNumberInOneLine, setLimitNumberInOneLine] = useState(0) const [showMore, setShowMore] = useState(false) const resources = useMemo(() => data.reduce((prev: Resources[], next) => { const documentId = next.document_id const documentName = next.document_name const dataSourceType = next.data_source_type const documentIndex = prev.findIndex(i => i.documentId === documentId) if (documentIndex > -1) { prev[documentIndex].sources.push(next) } else { prev.push({ documentId, documentName, dataSourceType, sources: [next], }) } return prev }, []), [data]) const handleAdjustResourcesLayout = () => { const containerWidth = document.querySelector(`.${containerClassName}`)!.clientWidth - 40 let totalWidth = 0 for (let i = 0; i < resources.length; i++) { totalWidth += elesRef.current[i].clientWidth if (totalWidth + i * 4 > containerWidth!) { totalWidth -= elesRef.current[i].clientWidth if (totalWidth + 34 > containerWidth!) setLimitNumberInOneLine(i - 1) else setLimitNumberInOneLine(i) break } else { setLimitNumberInOneLine(i + 1) } } } useEffect(() => { handleAdjustResourcesLayout() }, []) const resourcesLength = resources.length return (
{t('common.chat.citation.title')}
{ resources.map((res, index) => (
(elesRef.current[index] = ele!)} > {res.documentName}
)) } { resources.slice(0, showMore ? resourcesLength : limitNumberInOneLine).map((res, index) => (
)) } { limitNumberInOneLine < resourcesLength && (
setShowMore(v => !v)} > { !showMore ? `+ ${resourcesLength - limitNumberInOneLine}` : }
) }
) } export default Citation