|
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 '../ChatComponents/Sources'; |
|
import Evaluate from '../ChatComponents/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); |
|
|
|
|
|
const startResize = (e) => { |
|
e.preventDefault(); |
|
sidebarRef.current.classList.add("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"); |
|
document.removeEventListener("mousemove", resizeSidebar); |
|
document.removeEventListener("mouseup", stopResize); |
|
}; |
|
|
|
|
|
const handleSourceClick = (source) => { |
|
if (source && source.link) { |
|
window.open(source.link, '_blank'); |
|
} |
|
}; |
|
|
|
|
|
const getTaskIcon = (task) => { |
|
|
|
if (typeof task === 'string') { |
|
return <FaCheck />; |
|
} |
|
|
|
switch (task.status) { |
|
case 'RUNNING': |
|
|
|
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; |