File size: 3,307 Bytes
79278ec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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;