Spaces:
Sleeping
Sleeping
import "./SearchResultsItem.scss"; | |
import { forwardRef, useEffect, useRef, useState } from "react"; | |
import Button from "@/components/generics/button/Button"; | |
import { SearchResultsItemProps } from "./SearchResultsItemProps"; | |
import { downloadDocument } from "@/api/documents/documentsApi"; | |
const SearchResultsItem = forwardRef<HTMLDivElement, SearchResultsItemProps>(({ document, index, handleRead }, ref) => { | |
const [opened, setOpened] = useState<boolean>(false); | |
const [isNarrow, setIsNarrow] = useState(false); | |
const [isOverflowing, setIsOverflowing] = useState<boolean>(false); | |
const [isLoadingDownload, setIsLoadingDownload] = useState<boolean>(false); | |
const previewRef = useRef<HTMLDivElement>(null); | |
const actionsRef = useRef(null); | |
const docName = | |
document.title && document.title !== "unknown" | |
? document.title.toUpperCase() | |
: document.filename.replace(".json", "").toUpperCase(); | |
const handleDocumentDownload = () => { | |
setIsLoadingDownload(true); | |
if (document.id) | |
downloadDocument(null, document.id, document.filename).finally(() => setIsLoadingDownload(false)); | |
}; | |
useEffect(() => { | |
if (previewRef.current) { | |
const previewElement = previewRef.current; | |
setIsOverflowing(previewElement.scrollHeight > previewElement.clientHeight); | |
} | |
}, [document]); | |
useEffect(() => { | |
const observer = new ResizeObserver((entries) => { | |
for (const entry of entries) { | |
if (entry.contentRect.width <= 525) { | |
// Ширина в 525px | |
setIsNarrow(true); | |
} else { | |
setIsNarrow(false); | |
} | |
} | |
}); | |
if (actionsRef.current) { | |
observer.observe(actionsRef.current); | |
} | |
return () => observer.disconnect(); | |
}, []); | |
return ( | |
<div key={document.filename + index} className="search_result_item" ref={ref}> | |
<div className="document"> | |
<p className="link_button"> | |
<span>{index + 1}. </span> | |
<span className="title">{docName}</span> | |
</p> | |
</div> | |
{/* Превью текста */} | |
{!opened && ( | |
<div ref={previewRef} className="chunk chunk_preview"> | |
{document.chunks.map((chunk) => chunk.other_info.join("\n")).join("\n")} | |
</div> | |
)} | |
{/* Текст чанков */} | |
{opened && <div className="chunk">{document.chunks.map((chunk) => chunk.other_info.join("\n")).join("\n")}</div>} | |
<div className="actions" ref={actionsRef}> | |
<div className={`doc_actions ${isNarrow ? "narrow" : ""}`}> | |
<Button | |
buttonType="link" | |
className="open_button" | |
onClick={() => handleRead(document)} | |
name="Открыть документ" | |
/> | |
<Button | |
buttonType="link" | |
className="download_button" | |
onClick={handleDocumentDownload} | |
name="Скачать документ" | |
loading={isLoadingDownload} | |
/> | |
</div> | |
{isOverflowing && ( | |
<Button | |
buttonType="link" | |
onClick={() => setOpened(!opened)} | |
name={opened ? "Свернуть ответ" : "Развернуть ответ"} | |
/> | |
)} | |
</div> | |
</div> | |
); | |
}); | |
export default SearchResultsItem; | |