Refactor RunDetails and integrate with ResultGrid
Reworked `RunDetails` to enhance details presentation and added new UI components like images and processing results. Incorporated the `RunDetails` expansion panel into `ResultGrid` for better user interaction and streamlined grid functionalities.
This commit is contained in:
@ -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;
|
||||
export default RunDetails;
|
Reference in New Issue
Block a user