diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 0c9eb10312bd7d6fab039aef67040769ca40b7e8..c897724197062bb83f79a2362908c7ebe0d54fea 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -19,6 +19,7 @@ "@fullcalendar/react": "^6.1.15", "@fullcalendar/timegrid": "^6.1.15", "@mui/icons-material": "^6.1.5", + "@mui/lab": "^6.0.0-beta.29", "@mui/material": "^6.1.6", "@mui/system": "^6.1.6", "@mui/x-data-grid-premium": "^7.27.2", @@ -1255,6 +1256,44 @@ "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", "license": "MIT" }, + "node_modules/@floating-ui/core": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", + "license": "MIT" + }, "node_modules/@fullcalendar/core": { "version": "6.1.15", "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.15.tgz", @@ -1443,6 +1482,39 @@ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", "license": "MIT" }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.69", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.69.tgz", + "integrity": "sha512-r2YyGUXpZxj8rLAlbjp1x2BnMERTZ/dMqd9cClKj2OJ7ALAuiv/9X5E9eHfRc9o/dGRuLSMq/WTjREktJVjxVA==", + "deprecated": "This package has been replaced by @base-ui-components/react", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@floating-ui/react-dom": "^2.1.1", + "@mui/types": "^7.2.21", + "@mui/utils": "^6.4.1", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/core-downloads-tracker": { "version": "6.4.6", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.6.tgz", @@ -1479,6 +1551,51 @@ } } }, + "node_modules/@mui/lab": { + "version": "6.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.0-beta.29.tgz", + "integrity": "sha512-C5nTm9xfzVi4Zz4DLrZq1Kn+cQ2fGZmSJxyoUbOu+jDPlLZrUpSsgxEkkbjJB5dasiv6fgGKhO3EaKKyfobLAQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/base": "5.0.0-beta.69", + "@mui/system": "^6.4.6", + "@mui/types": "^7.2.21", + "@mui/utils": "^6.4.6", + "clsx": "^2.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": "^6.4.6", + "@mui/material-pigment-css": "^6.4.6", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material": { "version": "6.4.6", "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.6.tgz", diff --git a/frontend/package.json b/frontend/package.json index ac47655471d4027d17e515d6a48b708824082d4a..7a3cf6611bcfcdef16993b894e820c6339f0611e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -25,6 +25,7 @@ "@fullcalendar/react": "^6.1.15", "@fullcalendar/timegrid": "^6.1.15", "@mui/icons-material": "^6.1.5", + "@mui/lab": "^6.0.0-beta.29", "@mui/material": "^6.1.6", "@mui/system": "^6.1.6", "@mui/x-data-grid-premium": "^7.27.2", diff --git a/frontend/src/components/RunDetails.tsx b/frontend/src/components/RunDetails.tsx index 9f4215e46e42841940a4fa4348d72b0b5996f7a0..d20380a385f4592db55282a94eb9045b51c24ae3 100644 --- a/frontend/src/components/RunDetails.tsx +++ b/frontend/src/components/RunDetails.tsx @@ -1,139 +1,120 @@ -import React from 'react'; -import { - Dialog, - DialogTitle, - DialogContent, - IconButton, - Typography, - Grid, -} from '@mui/material'; -import CloseIcon from '@mui/icons-material/Close'; -import { SimpleTreeView, TreeItem } from '@mui/x-tree-view'; + import React from 'react'; + import { + Accordion, + AccordionSummary, + AccordionDetails, + Typography, + } from '@mui/material'; + import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -interface ExperimentParameters { - id: number; - run_number: number; - beamline_parameters: { - synchrotron: string; - beamline: string; - detector: { - manufacturer: string; - model: string; - type: string; - serialNumber: string; - detectorDistance_mm: number; - beamCenterX_px: number; - beamCenterY_px: number; - pixelSizeX_um: number; - pixelSizeY_um: number; - }; - // Include additional parameters as needed. - }; - // Optionally, add fields for images and processing results. - images?: Array<{ - id: number; - filepath: string; - comment?: string; - }>; - processingResults?: any; -} + const RunDetails: React.FC<RunDetailsProps> = ({ run }) => { + const { beamline_parameters } = run; + const { synchrotron, beamline, detector } = beamline_parameters; -interface RunDetailsProps { - run: ExperimentParameters; - onClose: () => void; -} + return ( + <div style={{ padding: '16px', border: '1px solid #ccc', borderRadius: '4px' }}> + <Typography variant="h6" gutterBottom> + Run {run.run_number} Details + </Typography> + <Typography variant="subtitle1" gutterBottom> + Beamline: {beamline} | Synchrotron: {synchrotron} + </Typography> -const RunDetails: React.FC<RunDetailsProps> = ({ run }) => { - const { beamline_parameters } = run; - const { synchrotron, beamline, detector } = beamline_parameters; + <Accordion> + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="detector-content" + id="detector-header" + > + <Typography><strong>Detector Details</strong></Typography> + </AccordionSummary> + <AccordionDetails> + <Typography>Manufacturer: {detector?.manufacturer || 'N/A'}</Typography> + <Typography>Model: {detector?.model || 'N/A'}</Typography> + <Typography>Type: {detector?.type || 'N/A'}</Typography> + <Typography> + Beam Center (px): x: {detector?.beamCenterX_px || 'N/A'}, y: {detector?.beamCenterY_px || 'N/A'} + </Typography> + </AccordionDetails> + </Accordion> - return ( - <div style={{ padding: '16px', border: '1px solid #ccc', borderRadius: '4px' }}> - <Typography variant="h6" gutterBottom> - Run {run.run_number} Details - </Typography> - <Typography variant="subtitle1" gutterBottom> - Beamline: {beamline} | Synchrotron: {synchrotron} - </Typography> + <Accordion> + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="beamline-content" + id="beamline-header" + > + <Typography><strong>Beamline Details</strong></Typography> + </AccordionSummary> + <AccordionDetails> + <Typography>Synchrotron: {beamline_parameters?.synchrotron || 'N/A'}</Typography> + <Typography>Ring mode: {beamline_parameters?.ringMode || 'N/A'}</Typography> + <Typography>Ring current: {beamline_parameters?.ringCurrent_A || 'N/A'}</Typography> + <Typography>Beamline: {beamline_parameters?.beamline || 'N/A'}</Typography> + <Typography>Undulator: {beamline_parameters?.undulator || 'N/A'}</Typography> + <Typography>Undulator gap: {beamline_parameters?.undulatorgap_mm || 'N/A'}</Typography> + <Typography>Focusing optic: {beamline_parameters?.focusingOptic || 'N/A'}</Typography> + <Typography>Monochromator: {beamline_parameters?.monochromator || 'N/A'}</Typography> + </AccordionDetails> + </Accordion> - <SimpleTreeView - defaultCollapseIcon="▾" - defaultExpandIcon="▸" - sx={{ fontSize: '0.875rem' }} - > - <TreeItem nodeId="detector-group" label={<strong>Detector Details</strong>}> - <TreeItem - nodeId="detector-manufacturer" - label={`Manufacturer: ${detector?.manufacturer || 'N/A'}`} - /> - <TreeItem - nodeId="detector-model" - label={`Model: ${detector?.model || 'N/A'}`} - /> - <TreeItem - nodeId="detector-type" - label={`Type: ${detector?.type || 'N/A'}`} - /> - <TreeItem - nodeId="detector-serial" - label={`Serial Number: ${detector?.serialNumber || 'N/A'}`} - /> - <TreeItem - nodeId="detector-distance" - label={`Distance (mm): ${detector?.detectorDistance_mm ?? 'N/A'}`} - /> - <TreeItem - nodeId="beam-center" - label={ - detector - ? `Beam Center: x: ${detector.beamCenterX_px}, y: ${detector.beamCenterY_px}` - : 'Beam Center: N/A' - } - /> - <TreeItem - nodeId="pixel-size" - label={ - detector - ? `Pixel Size (µm): x: ${detector.pixelSizeX_um}, y: ${detector.pixelSizeY_um}` - : 'Pixel Size: N/A' - } - /> - </TreeItem> - </SimpleTreeView> + <Accordion> + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="beam-content" + id="beam-header" + > + <Typography><strong>Beam characteristics</strong></Typography> + </AccordionSummary> + <AccordionDetails> + <Typography>Wavelength: {beamline_parameters?.wavelength || 'N/A'}</Typography> + <Typography>Energy: {beamline_parameters?.energy || 'N/A'}</Typography> + <Typography>Transmission: {beamline_parameters?.transmission || 'N/A'}</Typography> + <Typography>Beam focus (µm): vertical: {beamline_parameters?.beamSizeHeight || 'N/A'} , horizontal: {beamline_parameters?.beamSizeWidth || 'N/A'}</Typography> + <Typography>Flux at sample (ph/s): {beamline_parameters?.beamlineFluxAtSample_ph_s || 'N/A'}</Typography> + </AccordionDetails> + </Accordion> - <Typography variant="h6" sx={{ mt: 2 }}> - Associated Images - </Typography> - {run.images && run.images.length > 0 ? ( - <Grid container spacing={2} sx={{ mt: 1 }}> - {run.images.map((img) => ( - <Grid item xs={4} key={img.id}> - <img - src={img.filepath} - alt={img.comment || 'Sample Image'} - style={{ width: '100%', border: '1px solid #ccc' }} - /> - </Grid> - ))} - </Grid> - ) : ( - <Typography>No images available.</Typography> - )} + <Accordion> + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="sample-content" + id="sample-header" + > + <Typography><strong>Sample environment</strong></Typography> + </AccordionSummary> + <AccordionDetails> + <Typography>Cryojet temperature (K): {beamline_parameters?.cryojetTemperature_K || 'N/A'}</Typography> + <Typography>Humidifier temperature (K): {beamline_parameters?.humidifierTemperature_K || 'N/A'}</Typography> + <Typography>Humidifier humidity (%): {beamline_parameters?.humidifierHumidity || 'N/A'}</Typography> + </AccordionDetails> + </Accordion> - <Typography variant="h6" sx={{ mt: 2 }}> - Processing Results - </Typography> - {run.processingResults ? ( - <Typography variant="body2" sx={{ mt: 1 }}> - {JSON.stringify(run.processingResults, null, 2)} - </Typography> - ) : ( - <Typography variant="body2" sx={{ mt: 1 }}> - Processing details and results go here. - </Typography> - )} - </div> - ); -}; + <Accordion> + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="images-content" + id="images-header" + > + <Typography><strong>Associated Images</strong></Typography> + </AccordionSummary> + <AccordionDetails> + {run.images?.map((img) => ( + <img + key={img.id} + src={img.filepath} + alt={img.comment || 'Sample Image'} + style={{ + width: '100%', + border: '1px solid #ccc', + marginTop: 8, + }} + /> + )) || 'No Images Available'} + </AccordionDetails> + </Accordion> + </div> + ); + }; -export default RunDetails; \ No newline at end of file + export default RunDetails; \ No newline at end of file