add props for annontations and viewerstate

This commit is contained in:
Ross
2025-06-09 14:02:27 +01:00
parent 28569a1c94
commit a9e3c215ed
3 changed files with 79 additions and 1 deletions
+70 -1
View File
@@ -139,11 +139,13 @@ type AppProps = {
container_id?: string;
imageStacks: () => Promise<string[][]>;
autoCacheStack?: boolean; // <-- new prop
annotationJson?: string;
viewerState?: string;
// ...other props if needed
};
// App definintion
function App({ container_id, imageStacks, autoCacheStack, ...props }: AppProps) {
function App({ container_id, imageStacks, autoCacheStack, annotationJson, viewerState, ...props }: AppProps) {
const elementRef = useRef<HTMLDivElement>(null)
const running = useRef(false)
@@ -172,6 +174,47 @@ function App({ container_id, imageStacks, autoCacheStack, ...props }: AppProps)
() => Array(MAX_VIEWPORTS).fill(0)
);
const [loadingState, setLoadingState] = useState<null | "annotations" | "viewerState">(null);
// Load annotations and viewer state from props if provided
useEffect(() => {
let didCancel = false;
// Wait until availableStacks and viewportImageIds are loaded (i.e., app is ready)
if (annotationJson || viewerState) {
setLoadingState(annotationJson ? "annotations" : "viewerState");
// Use a short delay to ensure Cornerstone is initialized and viewports are ready
const timeout = setTimeout(() => {
if (didCancel) return;
const apiKey = container_id || "default";
if (annotationJson) {
try {
const fn = window[`importAnnotations_${apiKey}`] || window.importAnnotations;
if (typeof fn === "function") {
fn(annotationJson);
}
} catch (e) {
console.error("Failed to import annotations from prop:", e);
}
}
if (viewerState) {
try {
const fn = window[`importViewerState_${apiKey}`] || window.importViewerState;
if (typeof fn === "function") {
fn(viewerState);
}
} catch (e) {
console.error("Failed to import viewer state from prop:", e);
}
}
setLoadingState(null);
}, 800); // 500ms delay, adjust as needed
return () => {
didCancel = true;
clearTimeout(timeout);
setLoadingState(null);
};
}
}, [annotationJson, viewerState, container_id]);
// Load available stacks on mount
useEffect(() => {
@@ -2311,6 +2354,32 @@ function App({ container_id, imageStacks, autoCacheStack, ...props }: AppProps)
padding: "12px",
overflow: "hidden",
}}>
{/* Loading overlay */}
{loadingState && (
<div
style={{
position: "absolute",
zIndex: 3000,
top: 0,
left: 0,
width: "100%",
height: "100%",
background: "rgba(0,0,0,0.7)",
color: "#fff",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: 28,
fontWeight: "bold",
letterSpacing: 1,
}}
>
{loadingState === "annotations"
? "Loading Annotations..."
: "Loading Viewer State..."}
</div>
)}
<div>
{/* Side menu toggle button */}
<button
+7
View File
@@ -55,11 +55,18 @@ export function mountDicomViewers() {
const autoCacheStackAttr = container.getAttribute('data-auto-cache-stack');
const autoCacheStack = autoCacheStackAttr === "true" || autoCacheStackAttr === "1";
const annotationJson = container.getAttribute('data-annotationjson');
const viewerState = container.getAttribute('data-viewerstate');
console.log("Mounting DICOM viewer:")
console.log(viewerState, annotationJson, autoCacheStack);
createRoot(container).render(
<App
container_id={id}
imageStacks={imageStacks}
autoCacheStack={autoCacheStack}
annotationJson={annotationJson ? annotationJson : undefined}
viewerState={viewerState ? viewerState : undefined}
/>
);
});