import React, { useState } from "react";
import {
Grid,
Card,
CardContent,
Typography,
Box,
Divider,
IconButton,
Link,
CircularProgress,
} from "@mui/material";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import HelpOutlineIcon from "@mui/icons-material/HelpOutline"; // Icon for explanations
import CloseIcon from "@mui/icons-material/Close"; // Icon to close explanation
import axios from "axios";
function ResultsGrid({ results, threadId }) {
const [expandedDocs, setExpandedDocs] = useState({});
const [pageIndices, setPageIndices] = useState({});
const [explanations, setExplanations] = useState({});
const [loadingExplanation, setLoadingExplanation] = useState({});
const [explanationVisible, setExplanationVisible] = useState({}); // Track visibility of explanations
const handleToggleExpand = (source, index) => {
setExpandedDocs((prev) => ({
...prev,
[`${source}-${index}`]: !prev[`${source}-${index}`],
}));
};
const handlePageChange = (source, direction) => {
setPageIndices((prev) => ({
...prev,
[source]: Math.max(
0,
Math.min(
results[source].length - 4,
(prev[source] || 0) + direction * 4,
),
),
}));
};
const handleFetchExplanation = async (originalIndex) => {
if (explanationVisible[originalIndex]) {
setExplanationVisible((prev) => ({
...prev,
[originalIndex]: false,
}));
return;
}
setExplanationVisible((prev) => ({
...prev,
[originalIndex]: true,
}));
if (explanations[`${threadId}-${originalIndex}`]) return;
setLoadingExplanation((prev) => ({
...prev,
[originalIndex]: true,
}));
try {
const response = await axios.get(
`http://localhost:8000/explain/${threadId}?docid=${originalIndex}`,
);
setExplanations((prev) => ({
...prev,
[`${threadId}-${originalIndex}`]: response.data,
}));
} catch (error) {
console.error("Error fetching explanation:", error);
} finally {
setLoadingExplanation((prev) => ({
...prev,
[originalIndex]: false,
}));
}
};
if (!results || Object.keys(results).length === 0) {
return (
No results found.
);
}
return (
{Object.keys(results).map((source, idx) => (
handlePageChange(source, -1)}
disabled={(pageIndices[source] || 0) === 0}
sx={{
color: "text.secondary",
"&:hover": {
color: "text.primary",
},
}}
>
{source}
handlePageChange(source, 1)}
disabled={
(pageIndices[source] || 0) + 4 >= results[source].length
}
sx={{
color: "text.secondary",
"&:hover": {
color: "text.primary",
},
}}
>
{results[source]
.slice(
pageIndices[source] || 0,
(pageIndices[source] || 0) + 4,
)
.map((document, index) => (
{document.metadata.title || "Untitled"}
handleToggleExpand(source, index)}
sx={{
ml: 1,
color: expandedDocs[`${source}-${index}`]
? "primary.main"
: "text.primary",
fontSize: "1rem",
transition: "color 0.3s",
"&:hover": {
color: "primary.dark",
},
}}
>
handleFetchExplanation(document.originalIndex)
}
sx={{
ml: 1,
color: explanationVisible[document.originalIndex]
? "error.main"
: "info.main",
fontSize: "1.2rem",
transition: "color 0.3s",
"&:hover": {
color: explanationVisible[document.originalIndex]
? "error.dark"
: "info.dark",
},
}}
>
{explanationVisible[document.originalIndex] ? (
) : (
)}
{/* Conditionally render page_content based on its starting text */}
{document.page_content?.startsWith("Dataset Title:")
? document.page_content.slice(
document.metadata.title.length + 15,
50000,
)
: document.page_content || "No preview available."}
{/* Explanation Box */}
{explanationVisible[document.originalIndex] && (
Explanation
{loadingExplanation[document.originalIndex] ? (
) : (
{explanations[
`${threadId}-${document.originalIndex}`
]?.generation || "No explanation available."}
)}
)}
))}
))}
);
}
export default ResultsGrid;