|
| 1 | +import ExpandLess from "@mui/icons-material/ExpandLess"; |
| 2 | +import ExpandMore from "@mui/icons-material/ExpandMore"; |
1 | 3 | import { |
2 | 4 | Box, |
3 | 5 | Typography, |
|
6 | 8 | Button, |
7 | 9 | Card, |
8 | 10 | CardContent, |
| 11 | + Collapse, |
9 | 12 | } from "@mui/material"; |
10 | 13 | import theme, { Colors } from "design/theme"; |
11 | 14 | import { useAppDispatch } from "hooks/useAppDispatch"; |
@@ -33,6 +36,7 @@ const DatasetDetailPage: React.FC = () => { |
33 | 36 | error, |
34 | 37 | } = useAppSelector(NeurojsonSelector); |
35 | 38 | const [externalLinks, setExternalLinks] = useState<ExternalDataLink[]>([]); |
| 39 | + const [isExpanded, setIsExpanded] = useState(false); |
36 | 40 |
|
37 | 41 | // Recursive function to find `_DataLink_` |
38 | 42 | const extractDataLinks = (obj: any, path: string): ExternalDataLink[] => { |
@@ -150,145 +154,170 @@ const DatasetDetailPage: React.FC = () => { |
150 | 154 | </Typography> |
151 | 155 | )} |
152 | 156 | </Box> |
153 | | - |
154 | 157 | {externalLinks.length > 0 && ( |
155 | 158 | <Box sx={{ marginTop: 4 }}> |
156 | | - <Typography variant="h5" gutterBottom color={Colors.primary.dark}> |
157 | | - External Data ({externalLinks.length} links) |
158 | | - </Typography> |
159 | 159 | <Box |
| 160 | + onClick={() => setIsExpanded(!isExpanded)} |
160 | 161 | sx={{ |
161 | | - backgroundColor: Colors.white, |
162 | | - border: `1px solid ${Colors.lightGray}`, |
163 | | - borderRadius: "8px", |
164 | | - padding: 2, |
165 | | - boxShadow: "0px 2px 4px rgba(0,0,0,0.05)", |
| 162 | + display: "flex", |
| 163 | + alignItems: "center", |
| 164 | + cursor: "pointer", |
| 165 | + marginBottom: 2, |
166 | 166 | }} |
167 | 167 | > |
| 168 | + <Typography |
| 169 | + variant="h5" |
| 170 | + color={Colors.primary.dark} |
| 171 | + sx={{ marginRight: 1 }} |
| 172 | + > |
| 173 | + External Data ({externalLinks.length} links) |
| 174 | + </Typography> |
| 175 | + {isExpanded ? <ExpandLess /> : <ExpandMore />} |
| 176 | + </Box> |
| 177 | + |
| 178 | + <Collapse in={isExpanded}> |
168 | 179 | <Box |
169 | 180 | sx={{ |
170 | | - display: "flex", |
171 | | - justifyContent: "space-between", |
172 | | - alignItems: "center", |
173 | | - marginBottom: 2, |
174 | | - padding: "0 1rem", |
| 181 | + backgroundColor: Colors.white, |
| 182 | + border: `1px solid ${Colors.lightGray}`, |
| 183 | + borderRadius: "8px", |
| 184 | + padding: 2, |
| 185 | + boxShadow: "0px 2px 4px rgba(0,0,0,0.05)", |
175 | 186 | }} |
176 | 187 | > |
177 | | - <Button |
178 | | - variant="contained" |
| 188 | + <Box |
179 | 189 | sx={{ |
180 | | - backgroundColor: Colors.primary.main, |
181 | | - "&:hover": { |
182 | | - backgroundColor: Colors.primary.dark, |
183 | | - }, |
| 190 | + display: "flex", |
| 191 | + justifyContent: "space-between", |
| 192 | + alignItems: "center", |
| 193 | + marginBottom: 2, |
| 194 | + padding: "0 1rem", |
184 | 195 | }} |
185 | | - onClick={() => |
186 | | - externalLinks.forEach((link) => |
187 | | - window.open(link.url, "_blank") |
188 | | - ) |
189 | | - } |
190 | 196 | > |
191 | | - Download All Files |
192 | | - </Button> |
193 | | - <Typography variant="body2" color={Colors.textSecondary}> |
194 | | - Total Size:{" "} |
195 | | - {externalLinks |
196 | | - .reduce((acc, link) => { |
197 | | - const sizeMatch = link.size.match(/(\d+(\.\d+)?)/); |
198 | | - const sizeInMB = sizeMatch ? parseFloat(sizeMatch[1]) : 0; |
199 | | - return acc + sizeInMB; |
200 | | - }, 0) |
201 | | - .toFixed(2)}{" "} |
202 | | - MB |
203 | | - </Typography> |
204 | | - </Box> |
205 | | - |
206 | | - <Box |
207 | | - sx={{ |
208 | | - maxHeight: "400px", |
209 | | - overflowY: "auto", |
210 | | - "&::-webkit-scrollbar": { |
211 | | - width: "8px", |
212 | | - }, |
213 | | - "&::-webkit-scrollbar-track": { |
214 | | - background: Colors.lightGray, |
215 | | - borderRadius: "4px", |
216 | | - }, |
217 | | - "&::-webkit-scrollbar-thumb": { |
218 | | - background: Colors.primary.light, |
219 | | - borderRadius: "4px", |
220 | | - }, |
221 | | - }} |
222 | | - > |
223 | | - {externalLinks.map((link, index) => ( |
224 | | - <Box |
225 | | - key={index} |
| 197 | + <Button |
| 198 | + variant="contained" |
226 | 199 | sx={{ |
227 | | - padding: 2, |
228 | | - borderBottom: |
229 | | - index < externalLinks.length - 1 |
230 | | - ? `1px solid ${Colors.lightGray}` |
231 | | - : "none", |
232 | | - display: "flex", |
233 | | - justifyContent: "space-between", |
234 | | - alignItems: "center", |
| 200 | + backgroundColor: Colors.primary.main, |
235 | 201 | "&:hover": { |
236 | | - backgroundColor: Colors.lightGray, |
| 202 | + backgroundColor: Colors.primary.dark, |
237 | 203 | }, |
238 | 204 | }} |
| 205 | + onClick={() => |
| 206 | + externalLinks.forEach((link) => |
| 207 | + window.open(link.url, "_blank") |
| 208 | + ) |
| 209 | + } |
239 | 210 | > |
240 | | - <Box> |
241 | | - <Typography |
242 | | - color={Colors.textPrimary} |
243 | | - sx={{ |
244 | | - fontWeight: 500, |
245 | | - fontFamily: theme.typography.fontFamily, |
246 | | - }} |
247 | | - > |
248 | | - {link.name} |
249 | | - </Typography> |
250 | | - <Typography |
251 | | - variant="body2" |
252 | | - color={Colors.textSecondary} |
253 | | - sx={{ fontFamily: theme.typography.fontFamily }} |
254 | | - > |
255 | | - Size: {link.size} |
256 | | - </Typography> |
257 | | - </Box> |
258 | | - <Box sx={{ display: "flex", gap: 1 }}> |
259 | | - <Button |
260 | | - variant="contained" |
261 | | - size="small" |
262 | | - sx={{ |
263 | | - backgroundColor: Colors.primary.main, |
264 | | - "&:hover": { |
265 | | - backgroundColor: Colors.primary.dark, |
266 | | - }, |
267 | | - }} |
268 | | - onClick={() => window.open(link.url, "_blank")} |
269 | | - > |
270 | | - Download |
271 | | - </Button> |
272 | | - <Button |
273 | | - variant="outlined" |
274 | | - size="small" |
| 211 | + Download All Files |
| 212 | + </Button> |
| 213 | + <Typography variant="body2" color={Colors.textSecondary}> |
| 214 | + Total Size:{" "} |
| 215 | + {externalLinks |
| 216 | + .reduce((acc, link) => { |
| 217 | + const sizeMatch = link.size.match(/(\d+(\.\d+)?)/); |
| 218 | + const sizeInMB = sizeMatch ? parseFloat(sizeMatch[1]) : 0; |
| 219 | + return acc + sizeInMB; |
| 220 | + }, 0) |
| 221 | + .toFixed(2)}{" "} |
| 222 | + MB |
| 223 | + </Typography> |
| 224 | + </Box> |
| 225 | + |
| 226 | + <Box |
| 227 | + sx={{ |
| 228 | + maxHeight: "400px", |
| 229 | + overflowY: "auto", |
| 230 | + "&::-webkit-scrollbar": { |
| 231 | + width: "8px", |
| 232 | + }, |
| 233 | + "&::-webkit-scrollbar-track": { |
| 234 | + background: Colors.lightGray, |
| 235 | + borderRadius: "4px", |
| 236 | + }, |
| 237 | + "&::-webkit-scrollbar-thumb": { |
| 238 | + background: Colors.primary.light, |
| 239 | + borderRadius: "4px", |
| 240 | + }, |
| 241 | + }} |
| 242 | + > |
| 243 | + <Box |
| 244 | + sx={{ |
| 245 | + display: "grid", |
| 246 | + gridTemplateColumns: "repeat(3, 1fr)", |
| 247 | + gap: 2, |
| 248 | + padding: 1, |
| 249 | + }} |
| 250 | + > |
| 251 | + {externalLinks.map((link, index) => ( |
| 252 | + <Box |
| 253 | + key={index} |
275 | 254 | sx={{ |
276 | | - color: Colors.secondary.main, |
277 | | - borderColor: Colors.secondary.main, |
| 255 | + padding: 2, |
| 256 | + border: `1px solid ${Colors.lightGray}`, |
| 257 | + borderRadius: "8px", |
| 258 | + display: "flex", |
| 259 | + flexDirection: "column", |
| 260 | + justifyContent: "space-between", |
| 261 | + backgroundColor: Colors.white, |
278 | 262 | "&:hover": { |
279 | | - borderColor: Colors.secondary.dark, |
280 | | - color: Colors.secondary.dark, |
| 263 | + backgroundColor: Colors.lightGray, |
281 | 264 | }, |
282 | 265 | }} |
283 | | - onClick={() => window.open(link.url)} |
284 | 266 | > |
285 | | - View |
286 | | - </Button> |
287 | | - </Box> |
| 267 | + <Box> |
| 268 | + <Typography |
| 269 | + color={Colors.textPrimary} |
| 270 | + sx={{ |
| 271 | + fontWeight: 500, |
| 272 | + fontFamily: theme.typography.fontFamily, |
| 273 | + }} |
| 274 | + > |
| 275 | + {link.name} |
| 276 | + </Typography> |
| 277 | + <Typography |
| 278 | + variant="body2" |
| 279 | + color={Colors.textSecondary} |
| 280 | + sx={{ fontFamily: theme.typography.fontFamily }} |
| 281 | + > |
| 282 | + Size: {link.size} |
| 283 | + </Typography> |
| 284 | + </Box> |
| 285 | + <Box sx={{ display: "flex", gap: 1, marginTop: 2 }}> |
| 286 | + <Button |
| 287 | + variant="contained" |
| 288 | + size="small" |
| 289 | + sx={{ |
| 290 | + backgroundColor: Colors.primary.main, |
| 291 | + "&:hover": { |
| 292 | + backgroundColor: Colors.primary.dark, |
| 293 | + }, |
| 294 | + }} |
| 295 | + onClick={() => window.open(link.url, "_blank")} |
| 296 | + > |
| 297 | + Download |
| 298 | + </Button> |
| 299 | + <Button |
| 300 | + variant="outlined" |
| 301 | + size="small" |
| 302 | + sx={{ |
| 303 | + color: Colors.secondary.main, |
| 304 | + borderColor: Colors.secondary.main, |
| 305 | + "&:hover": { |
| 306 | + borderColor: Colors.secondary.dark, |
| 307 | + color: Colors.secondary.dark, |
| 308 | + }, |
| 309 | + }} |
| 310 | + onClick={() => console.log("preview")} |
| 311 | + > |
| 312 | + Preview |
| 313 | + </Button> |
| 314 | + </Box> |
| 315 | + </Box> |
| 316 | + ))} |
288 | 317 | </Box> |
289 | | - ))} |
| 318 | + </Box> |
290 | 319 | </Box> |
291 | | - </Box> |
| 320 | + </Collapse> |
292 | 321 | </Box> |
293 | 322 | )} |
294 | 323 | </Box> |
|
0 commit comments