From 67329d0468c7ca1ab68351141689978996eb3249 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 22 Sep 2025 10:26:49 +0100 Subject: [PATCH] Refactor layout to integrate right-side stack panel with improved hover and pinning functionality --- dicom-viewer/src/App.tsx | 123 +++++++++++++++++++++++++++++++++------ 1 file changed, 106 insertions(+), 17 deletions(-) diff --git a/dicom-viewer/src/App.tsx b/dicom-viewer/src/App.tsx index 4458625..4711987 100644 --- a/dicom-viewer/src/App.tsx +++ b/dicom-viewer/src/App.tsx @@ -3582,25 +3582,114 @@ function App({ container_id, imageStacks, autoCacheStack, annotationJson, viewer - {/* Viewport grid (inside main div) */} -
- {viewports} + {/* Main content area: viewports and right-side panel in a row so panel pushes content */} +
+ {/* Viewport grid container — flex:1 so it shrinks when panel takes space */} +
+ {viewports} +
+ {/* Right-side panel occupies layout space when visible or pinned */} +
+ {/* Reuse the existing right-side panel markup but ensure pointerEvents are enabled inside */} +
+ {/* Panel (same content as before) */} +
setStackPanelHover(true)} + onMouseLeave={() => setStackPanelHover(false)} + style={{ + height: '100%', + width: '100%', + background: '#1f2428', + color: '#fff', + boxShadow: '0 2px 14px rgba(0,0,0,0.45)', + borderLeft: '1px solid #2f3336', + transform: 'translateX(0)', + transition: 'transform 220ms ease', + display: 'flex', + flexDirection: 'column', + overflow: 'hidden', + }} + > +
+
Stacks
+
+ + +
+
+
+ {availableStacks.length === 0 ? ( +
No stacks available
+ ) : ( +
+ {availableStacks.map((stack, idx) => { + const imageIds = Array.isArray(stack.imageIds) ? stack.imageIds : []; + const label = stack.name || (stack.caseId ? `Case: ${stack.caseId}` : `Stack ${idx + 1}`); + const count = imageIds.length; + const invalid = !Array.isArray(imageIds) || count === 0; + const isSelected = selectedStackIdx.includes(idx); + return ( +
{ + if (invalid) return; + e.dataTransfer.setData('text/stack-idx', String(idx)); + e.dataTransfer.effectAllowed = 'copy'; + }} + onClick={() => { if (!invalid) handleLoadStack(0, idx); }} + style={{ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + padding: '8px 10px', + background: isSelected ? '#1976d2' : 'transparent', + color: isSelected ? '#fff' : '#ddd', + borderRadius: 6, + cursor: invalid ? 'not-allowed' : 'pointer', + }} + > +
+
{label}
+
{count} img{count === 1 ? '' : 's'}
+
+
{stack.studyId || ''}
+
+ ); + })} +
+ )} +
+
+
+