Spaces:
Paused
Paused
import React, { useRef } from 'react'; | |
import { FaTimes, FaCheck, FaSpinner } from 'react-icons/fa'; | |
import { BsChevronLeft } from 'react-icons/bs'; | |
import CircularProgress from '@mui/material/CircularProgress'; | |
import Sources from './Sources'; | |
import Evaluate from './Evaluate' | |
import './RightSidebar.css'; | |
function RightSidebar({ | |
isOpen, | |
rightSidebarWidth, | |
setRightSidebarWidth, | |
toggleRightSidebar, | |
sidebarContent, | |
tasks = [], | |
tasksLoading, | |
sources = [], | |
sourcesLoading, | |
onTaskClick, | |
onSourceClick, | |
evaluation | |
}) { | |
const minWidth = 200; | |
const maxWidth = 450; | |
const sidebarRef = useRef(null); | |
// Called when the user starts resizing the sidebar. | |
const startResize = (e) => { | |
e.preventDefault(); | |
sidebarRef.current.classList.add("resizing"); // Add the "resizing" class to the sidebar when resizing | |
document.addEventListener("mousemove", resizeSidebar); | |
document.addEventListener("mouseup", stopResize); | |
}; | |
const resizeSidebar = (e) => { | |
let newWidth = window.innerWidth - e.clientX; | |
if (newWidth < minWidth) newWidth = minWidth; | |
if (newWidth > maxWidth) newWidth = maxWidth; | |
setRightSidebarWidth(newWidth); | |
}; | |
const stopResize = () => { | |
sidebarRef.current.classList.remove("resizing"); // Remove the "resizing" class from the sidebar when resizing stops | |
document.removeEventListener("mousemove", resizeSidebar); | |
document.removeEventListener("mouseup", stopResize); | |
}; | |
// Default handler for source clicks: open the link in a new tab. | |
const handleSourceClick = (source) => { | |
if (source && source.link) { | |
window.open(source.link, '_blank'); | |
} | |
}; | |
// Helper function to return the proper icon based on task status. | |
const getTaskIcon = (task) => { | |
// If the task is a simple string, default to the completed icon. | |
if (typeof task === 'string') { | |
return <FaCheck />; | |
} | |
// Use the status field to determine which icon to render. | |
switch (task.status) { | |
case 'RUNNING': | |
// FaSpinner is used for running tasks. The CSS class "spin" can be defined to add animation. | |
return <FaSpinner className="spin"/>; | |
case 'DONE': | |
return <FaCheck className="checkmark" />; | |
case 'FAILED': | |
return <FaTimes className="x" />; | |
default: | |
return <FaCheck />; | |
} | |
}; | |
return ( | |
<> | |
<nav | |
ref={sidebarRef} | |
className={`right-side-bar ${isOpen ? "open" : "closed"}`} | |
style={{ width: isOpen ? rightSidebarWidth : 0 }} | |
> | |
<div className="sidebar-header"> | |
<h3> | |
{sidebarContent === "sources" | |
? "Sources" | |
: sidebarContent === "evaluate" | |
? "Evaluation" | |
: "Tasks"} | |
</h3> | |
<button className="close-btn" onClick={toggleRightSidebar}> | |
<FaTimes /> | |
</button> | |
</div> | |
<div className="sidebar-content"> | |
{sidebarContent === "sources" ? ( // If the sidebar content is "sources", show the sources component | |
sourcesLoading ? ( | |
<div className="tasks-loading"> | |
<CircularProgress size={20} sx={{ color: '#ccc' }} /> | |
<span className="loading-tasks-text">Generating sources...</span> | |
</div> | |
) : ( | |
<Sources sources={sources} handleSourceClick={onSourceClick || handleSourceClick} /> | |
) | |
) | |
// If the sidebar content is "evaluate", show the evaluation component | |
: sidebarContent === "evaluate" ? ( | |
<Evaluate evaluation={evaluation} /> | |
) : ( | |
// Otherwise, show tasks | |
tasksLoading ? ( | |
<div className="tasks-loading"> | |
<CircularProgress size={20} sx={{ color: '#ccc' }} /> | |
<span className="loading-tasks-text">Generating tasks...</span> | |
</div> | |
) : ( | |
<ul className="nav-links" style={{ listStyle: 'none', padding: 0 }}> | |
{tasks.map((task, index) => ( | |
<li key={index} className="task-item"> | |
<span className="task-icon"> | |
{getTaskIcon(task)} | |
</span> | |
<span className="task-text"> | |
{typeof task === 'string' ? task : task.task} | |
</span> | |
</li> | |
))} | |
</ul> | |
) | |
)} | |
</div> | |
<div className="resizer" onMouseDown={startResize}></div> | |
</nav> | |
{!isOpen && ( | |
<button className="toggle-btn right-toggle" onClick={toggleRightSidebar}> | |
<BsChevronLeft /> | |
</button> | |
)} | |
</> | |
); | |
} | |
export default RightSidebar; |