Refactor image rendering in ResultGrid with CSS enhancements

Simplified image rendering logic in `ResultGrid` by removing hover state management within JavaScript. Added `SampleImage.css` to handle hover effects for images and tooltips with scalable zoom. Cleaned up unnecessary comments and improved code readability.
This commit is contained in:
GotthardG 2025-02-27 11:40:40 +01:00
parent 548a86678b
commit de4a6d2db8
2 changed files with 88 additions and 105 deletions

View File

@ -1,6 +1,9 @@
// TypeScript (ResultGrid.tsx snippet)
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { DataGrid, GridColDef } from '@mui/x-data-grid'; import { DataGrid, GridColDef } from '@mui/x-data-grid';
import { OpenAPI, SamplesService } from '../../openapi'; import { OpenAPI, SamplesService } from '../../openapi';
import './Sampleimage.css';
interface ImageInfo { interface ImageInfo {
id: number; id: number;
@ -22,14 +25,10 @@ interface ResultGridProps {
const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => { const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => {
const [rows, setRows] = useState<SampleResult[]>([]); const [rows, setRows] = useState<SampleResult[]>([]);
const [basePath, setBasePath] = React.useState(""); const [basePath, setBasePath] = useState('');
const [hoveredImageUrl, setHoveredImageUrl] = useState<string | null>(null);
useEffect(() => { useEffect(() => {
// Detect the current environment
const mode = import.meta.env.MODE; const mode = import.meta.env.MODE;
// Dynamic resolution for OpenAPI.BASE
OpenAPI.BASE = OpenAPI.BASE =
mode === 'test' mode === 'test'
? import.meta.env.VITE_OPENAPI_BASE_TEST ? import.meta.env.VITE_OPENAPI_BASE_TEST
@ -45,7 +44,7 @@ const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => {
console.log('Environment Mode:', mode); console.log('Environment Mode:', mode);
console.log('Resolved OpenAPI.BASE:', OpenAPI.BASE); console.log('Resolved OpenAPI.BASE:', OpenAPI.BASE);
// Set the base path for images dynamically // Update the base path for images
setBasePath(`${OpenAPI.BASE}/`); setBasePath(`${OpenAPI.BASE}/`);
}, []); }, []);
@ -74,30 +73,16 @@ const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => {
const imageList: ImageInfo[] = params.value; const imageList: ImageInfo[] = params.value;
if (imageList && imageList.length) { if (imageList && imageList.length) {
const primaryImage = imageList[0]; const primaryImage = imageList[0];
// Define the base path to your backend images directory
const imageUrl = basePath + primaryImage.filepath; const imageUrl = basePath + primaryImage.filepath;
console.log("Local relative path:", imageUrl);
console.log("Updated image URL:", imageUrl);
return ( return (
<div style={{ display: 'flex', alignItems: 'center', position: 'relative' }}> <div style={{ display: 'flex', alignItems: 'center', position: 'relative' }}>
<img <img
src={imageUrl} src={imageUrl}
alt="sample" alt="sample"
style={{ width: 50, height: 50, marginRight: 5, borderRadius: 4, cursor: 'pointer' }} className="zoom-image"
onMouseEnter={() => { style={{ width: 40, height: 40, marginRight: 5, borderRadius: 4 }}
console.log("Mouse entered image");
setHoveredImageUrl(imageUrl);
}}
onMouseLeave={() => {
console.log("Mouse left image");
setHoveredImageUrl(null);
}}
/> />
{imageList.length > 1 && ( {imageList.length > 1 && (
<div className="tooltip" style={{ position: 'relative', cursor: 'pointer' }}> <div className="tooltip" style={{ position: 'relative', cursor: 'pointer' }}>
<span>+{imageList.length - 1}</span> <span>+{imageList.length - 1}</span>
@ -115,16 +100,18 @@ const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => {
}} }}
> >
{imageList.slice(1).map((img) => { {imageList.slice(1).map((img) => {
const tooltipImageUrl = basePath + img.filepath; const url = basePath + img.filepath;
return ( return (
<img <img
key={img.id} key={img.id}
src={tooltipImageUrl} src={url}
alt="sample" alt={img.comment || 'additional sample'}
style={{width: 50, height: 50, margin: 2, borderRadius: 4}} className="zoom-image"
style={{ width: 40, height: 40, marginRight: 5, borderRadius: 4 }}
/> />
); );
})} })}
</div> </div>
</div> </div>
)} )}
@ -136,37 +123,20 @@ const ResultGrid: React.FC<ResultGridProps> = ({ activePgroup }) => {
}, },
]; ];
// Map each row so that DataGrid can use a unique "id" prop; here we use sample_id.
const gridRows = rows.map((row) => ({ ...row, id: row.sample_id }));
return ( return (
<div style={{ position: 'relative' }}> <DataGrid
<div style={{ height: 600, width: '100%' }}> rows={rows}
<DataGrid rows={gridRows} columns={columns} pageSize={10} /> columns={columns}
</div> pageSize={10}
{hoveredImageUrl && ( getRowId={(row) => row.sample_id}
<div sx={{
style={{ '& .MuiDataGrid-cell': {
position: 'fixed', overflow: 'visible',
top: '20%', },
left: '50%',
transform: 'translate(-50%, -50%)',
zIndex: 2000,
border: '2px solid #ccc',
background: '#fff',
padding: '10px',
borderRadius: '4px',
pointerEvents: 'none', // Ensures hover stays on the image
}} }}
> />
<img src={hoveredImageUrl} alt="large preview" style={{ maxWidth: '400px', maxHeight: '400px' }} />
</div>
)}
</div>
); );
}; };
export default ResultGrid; export default ResultGrid;

View File

@ -0,0 +1,13 @@
.zoom-image {
transition: transform 0.3s ease;
cursor: pointer;
}
.zoom-image:hover {
transform: scale(10); /* Adjust the scale value as needed */
z-index: 10; /* Bring it to front if overlapping */
}
.tooltip:hover .tooltip-content {
display: block !important;
}