/ concept-collection / benchcompress
Sign in
concept-collection / benchcompress
benchcompress / web-ui / src / pages / BenchmarkView.tsx
251 lines · 8.1 KBBlameHistoryRaw
1import { useLocation, useNavigate, useParams } from "react-router-dom";
2import { useReducer, useEffect } from "react";
3import { tabsReducer } from "../reducers/tabsReducer";
4import { AlgorithmContent } from "../components/algorithm/AlgorithmContent";
5import { DatasetContent } from "../components/dataset/DatasetContent";
6import {
7 AlgorithmTable,
8 DatasetTable,
9} from "../components/tables/DatasetAlgorithmTables";
10import { useBenchmarkChartData } from "../hooks/useBenchmarkChartData";
11import { useTagFilter } from "../hooks/useTagFilter";
12import { BenchmarkData } from "../types";
14interface BenchmarkViewProps {
15 benchmarkData: BenchmarkData | null;
18export default function BenchmarkView({ benchmarkData }: BenchmarkViewProps) {
19 const location = useLocation();
20 const navigate = useNavigate();
21 const { datasetName, algorithmName } = useParams<{
22 datasetName?: string;
23 algorithmName?: string;
24 }>();
26 const [tabsState, dispatch] = useReducer(tabsReducer, {
27 tabs: [
28 { id: "datasets", label: "Datasets", route: "/datasets" },
29 { id: "algorithms", label: "Algorithms", route: "/algorithms" },
30 ],
31 activeTabId: "datasets",
32 });
34 // Effect to handle URL changes and update tabs
35 useEffect(() => {
36 if (datasetName) {
37 dispatch({
38 type: "ADD_TAB",
39 payload: {
40 id: `dataset-${datasetName}`,
41 label: datasetName,
42 route: `/dataset/${datasetName}`,
43 },
44 });
45 } else if (algorithmName) {
46 dispatch({
47 type: "ADD_TAB",
48 payload: {
49 id: `algorithm-${algorithmName}`,
50 label: algorithmName,
51 route: `/algorithm/${algorithmName}`,
52 },
53 });
54 } else if (location.pathname.includes("/algorithms")) {
55 dispatch({ type: "SET_ACTIVE_TAB", payload: "algorithms" });
56 } else if (location.pathname.includes("/datasets")) {
57 dispatch({ type: "SET_ACTIVE_TAB", payload: "datasets" });
58 }
59 }, [datasetName, algorithmName, location.pathname]);
61 // Handle tab click
62 const handleTabClick = (tabId: string, route: string) => {
63 dispatch({ type: "SET_ACTIVE_TAB", payload: tabId });
64 navigate(route);
65 };
67 // Get specific dataset or algorithm if viewing one
68 const dataset = datasetName
69 ? benchmarkData?.datasets.find((d) => d.name === datasetName)
70 : undefined;
71 const algorithm = algorithmName
72 ? benchmarkData?.algorithms.find((a) => a.name === algorithmName)
73 : undefined;
75 // Get chart data for specific dataset or algorithm view
76 const chartData = useBenchmarkChartData(
77 benchmarkData?.results || [],
78 dataset?.name || null,
79 algorithm?.name || null,
80 );
82 // Get selected tags from URL
83 const searchParams = new URLSearchParams(location.search);
84 const selectedTags = searchParams.get("tag")?.split(",") || [];
86 // Set up tag filtering for datasets and algorithms
87 const {
88 availableTags: availableDatasetTags,
89 filteredItems: filteredDatasets,
90 } = useTagFilter(
91 benchmarkData?.datasets || [],
92 location.pathname.includes("/datasets") ? selectedTags : [],
93 );
95 const {
96 availableTags: availableAlgorithmTags,
97 filteredItems: filteredAlgorithms,
98 } = useTagFilter(
99 benchmarkData?.algorithms || [],
100 location.pathname.includes("/algorithms") ? selectedTags : [],
101 );
103 // Handle tag toggling by updating URL
104 const handleTagToggle = (tag: string) => {
105 const newTags = selectedTags.includes(tag)
106 ? selectedTags.filter((t) => t !== tag)
107 : [...selectedTags, tag];
109 const params = new URLSearchParams();
110 if (newTags.length > 0) {
111 params.set("tag", newTags.join(","));
112 }
113 navigate({ search: params.toString() });
114 };
116 return (
117 <div>
118 <main>
119 <div
120 style={{
121 position: "fixed",
122 top: "3rem",
123 left: 0,
124 right: 0,
125 backgroundColor: "white",
126 zIndex: 999,
127 padding: "0 2rem 0 2rem",
128 marginTop: "-4px",
129 boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
130 borderBottom: "1px solid #eaeaea",
131 }}
132 >
133 <div
134 style={{
135 paddingBottom: "2px",
136 display: "flex",
137 gap: "4px",
138 overflowX: "auto",
139 width: "100%",
140 backgroundColor: "white",
141 }}
142 >
143 {tabsState.tabs.map((tab) => (
144 <div
145 key={tab.id}
146 style={{
147 display: "flex",
148 alignItems: "center",
149 gap: "4px",
150 }}
151 >
152 <button
153 onClick={() => handleTabClick(tab.id, tab.route)}
154 style={{
155 padding: "8px 16px",
156 border: "none",
157 background: "none",
158 borderBottom:
159 tabsState.activeTabId === tab.id
160 ? "2px solid #0066cc"
161 : "none",
162 color:
163 tabsState.activeTabId === tab.id ? "#0066cc" : "#666",
164 fontWeight:
165 tabsState.activeTabId === tab.id ? "600" : "normal",
166 cursor: "pointer",
167 textDecoration: "none",
168 whiteSpace: "nowrap",
169 }}
170 >
171 {tab.label}
172 </button>
173 {tab.id !== "datasets" && tab.id !== "algorithms" && (
174 <button
175 onClick={(e) => {
176 e.stopPropagation();
177 const newActiveTab =
178 tab.id === tabsState.activeTabId
179 ? tabsState.tabs[0].id // Default to first tab if closing active
180 : tabsState.activeTabId;
181 dispatch({ type: "CLOSE_TAB", payload: tab.id });
182 // Navigate if closing active tab
183 if (tab.id === tabsState.activeTabId) {
184 const defaultTab = tabsState.tabs.find(
185 (t) => t.id === newActiveTab,
186 );
187 if (defaultTab) {
188 navigate(defaultTab.route);
189 }
190 }
191 }}
192 style={{
193 padding: "4px",
194 border: "none",
195 background: "none",
196 color: "#666",
197 cursor: "pointer",
198 fontSize: "12px",
199 display: "flex",
200 alignItems: "center",
201 justifyContent: "center",
202 width: "20px",
203 height: "20px",
204 borderRadius: "50%",
205 marginRight: "4px",
206 marginLeft: "-4px",
207 }}
208 aria-label="Close tab"
209 >
210 ×
211 </button>
212 )}
213 </div>
214 ))}
215 </div>
216 </div>
218 <div style={{ padding: "3rem 0 1rem 0" }}>
219 {dataset ? (
220 <DatasetContent
221 dataset={dataset}
222 benchmarkData={benchmarkData}
223 chartData={chartData}
224 />
225 ) : algorithm ? (
226 <AlgorithmContent
227 algorithm={algorithm}
228 benchmarkData={benchmarkData}
229 chartData={chartData}
230 />
231 ) : tabsState.activeTabId === "datasets" ? (
232 <DatasetTable
233 filteredDatasets={filteredDatasets}
234 availableDatasetTags={availableDatasetTags}
235 selectedTags={selectedTags}
236 toggleTag={handleTagToggle}
237 benchmarkResults={benchmarkData?.results || []}
238 />
239 ) : (
240 <AlgorithmTable
241 filteredAlgorithms={filteredAlgorithms}
242 availableAlgorithmTags={availableAlgorithmTags}
243 selectedTags={selectedTags}
244 toggleTag={handleTagToggle}
245 />
246 )}
247 </div>
248 </main>
249 </div>
250 );
moveopenescclose