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; |