File size: 4,791 Bytes
85a4a41
4279593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85a4a41
4279593
 
 
 
85a4a41
4279593
 
 
 
 
 
 
 
 
 
 
 
85a4a41
4279593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85a4a41
4279593
85a4a41
4279593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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;