diff --git a/frontend/src/components/ResultGrid.tsx b/frontend/src/components/ResultGrid.tsx index a3aa790ae7d4a9ffc3dd72133955750b52bb15d4..09ad8da29906227181c000561883fdd470b3aff9 100644 --- a/frontend/src/components/ResultGrid.tsx +++ b/frontend/src/components/ResultGrid.tsx @@ -299,6 +299,7 @@ const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => { return ( <RunDetails run={params.row} + basePath={basePath} onHeightChange={(height: number) => handleDetailPanelHeightChange(params.row.id, height)} // Pass callback for dynamic height /> ); diff --git a/frontend/src/components/RunDetails.tsx b/frontend/src/components/RunDetails.tsx index 02cbf63aacf43777d7cc80b269bcc5fe302f1371..b0914a3a6e1ab2421da1168beb1319fa8fbc9371 100644 --- a/frontend/src/components/RunDetails.tsx +++ b/frontend/src/components/RunDetails.tsx @@ -5,18 +5,23 @@ import { AccordionDetails, Typography, Grid, + Modal, + Box } from '@mui/material'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import './SampleImage.css'; interface RunDetailsProps { run: ExperimentParameters; + basePath: string; onHeightChange?: (height: number) => void; // Callback to notify the parent about height changes } -const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange }) => { +const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange, basePath }) => { const containerRef = useRef<HTMLDivElement | null>(null); // Ref to track component height const [currentHeight, setCurrentHeight] = useState<number>(0); + const [modalOpen, setModalOpen] = useState<boolean>(false); // For modal state + const [selectedImage, setSelectedImage] = useState<string | null>(null); // Tracks the selected image for the modal const { beamline_parameters, images } = run; const { synchrotron, beamline, detector } = beamline_parameters; @@ -49,8 +54,20 @@ const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange }) => { }; }, [containerRef]); + const handleImageClick = (imagePath: string) => { + setSelectedImage(imagePath); + setModalOpen(true); // Open the modal when the image is clicked + }; + + const closeModal = () => { + setSelectedImage(null); // Clear the current image + setModalOpen(false); + }; + + return ( <div + className="details-panel" // Add the class here ref={containerRef} // Attach the ref to the main container style={{ display: 'flex', @@ -61,7 +78,8 @@ const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange }) => { alignItems: 'flex-start', }} > - {/* Main Details Section */} + + {/* Main Details Section */} <div style={{ flexGrow: 1 }}> <Typography variant="h6" gutterBottom> Run {run.run_number} Details @@ -144,17 +162,23 @@ const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange }) => { Associated Images </Typography> {images && images.length > 0 ? ( - <Grid container spacing={2}> + <Grid container spacing={1}> {images.map((img) => ( - <Grid item xs={6} key={img.id}> - <div className="image-container"> + <Grid item xs={4} key={img.id}> + <div + className="image-container" + onClick={() => handleImageClick(`${basePath || ''}${img.filepath}`)} // Open modal with image + style={{ + cursor: 'pointer', + }} + > <img - src={img.filepath} + src={`${basePath || ''}${img.filepath}`} // Ensure basePath alt={img.comment || 'Image'} className="zoom-image" style={{ - width: '100%', - maxWidth: '100%', + width: '100%', // Ensure the image takes the full width of its container + maxWidth: '100%', // Prevent any overflow borderRadius: '4px', }} /> @@ -168,6 +192,35 @@ const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange }) => { </Typography> )} </div> + + {/* Modal for Zoomed Image */} + <Modal open={modalOpen} onClose={closeModal}> + <Box + style={{ + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + backgroundColor: '#fff', + boxShadow: 24, + padding: 16, + maxHeight: '90%', + overflow: 'auto', + }} + > + {selectedImage && ( + <img + src={selectedImage} + alt="Zoomed" + style={{ + maxWidth: '100%', + height: 'auto', + borderRadius: '4px', + }} + /> + )} + </Box> + </Modal> </div> ); }; diff --git a/frontend/src/components/SampleImage.css b/frontend/src/components/SampleImage.css index ba545b9ed486b07b8e42b1db995317f73904667f..e42d575b0f523b8f85aefa2a8cb90822c26c0611 100644 --- a/frontend/src/components/SampleImage.css +++ b/frontend/src/components/SampleImage.css @@ -13,4 +13,11 @@ .image-container { overflow: visible; /* Ensures zoomed images are not cropped by the parent */ -} \ No newline at end of file +} + +/* Disable zoom effect specifically in the details panel */ +.details-panel .zoom-image:hover { + transform: none; /* Disable scaling */ + z-index: 1; /* Reset any z-index adjustment */ + border: none; /* Reset border effect */ +}