From 511e5cffef366e2cf8d23a9269bc60a486332e78 Mon Sep 17 00:00:00 2001 From: Tom Kane Date: Fri, 14 Aug 2026 15:07:32 +0000 Subject: [PATCH 1/8] Update controls drawer to take a list, displays items side by side with vertical seperators --- apps/visr/src/components/ControlsDrawer.tsx | 40 ++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/apps/visr/src/components/ControlsDrawer.tsx b/apps/visr/src/components/ControlsDrawer.tsx index da552d9e..3fafeb36 100644 --- a/apps/visr/src/components/ControlsDrawer.tsx +++ b/apps/visr/src/components/ControlsDrawer.tsx @@ -1,12 +1,13 @@ import { Drawer, Box, IconButton, Typography } from "@mui/material"; import UnfoldLessIcon from "@mui/icons-material/UnfoldLess"; import UnfoldMoreIcon from "@mui/icons-material/UnfoldMore"; +import { Children, Fragment, type ReactNode } from "react"; interface ControlsDrawerProps { open: boolean; collapsedHeight: number; onToggle: () => void; - controls: JSX.Element; + controls: ReactNode | ReactNode[]; } function ControlsDrawer({ @@ -15,6 +16,8 @@ function ControlsDrawer({ onToggle, controls, }: ControlsDrawerProps) { + const items = Children.toArray(controls); + return ( Controls - + {open ? : } + - {open ? controls : } + {items.map((control, index) => ( + + {index > 0 && ( + + )} + {control} + + ))} ); From dbeb4ad0fcfd873aa9603600545abdd24f358bf0 Mon Sep 17 00:00:00 2001 From: Tom Kane Date: Fri, 14 Aug 2026 15:09:14 +0000 Subject: [PATCH 2/8] new tomography form for submitting bluesky plans --- .../components/tomography/TomographyForm.tsx | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 apps/visr/src/components/tomography/TomographyForm.tsx diff --git a/apps/visr/src/components/tomography/TomographyForm.tsx b/apps/visr/src/components/tomography/TomographyForm.tsx new file mode 100644 index 00000000..866985b1 --- /dev/null +++ b/apps/visr/src/components/tomography/TomographyForm.tsx @@ -0,0 +1,111 @@ +import { useInstrumentSession } from "../../context/instrumentSession/useInstrumentSession"; +import { RunPlanButton } from "@atlas/blueapi-ui"; +import AbortButton from "../AbortButton"; +import { useState } from "react"; +import { NumberInput } from "@diamondlightsource/sci-react-ui"; +import { Box } from "@mui/material"; +import { visitToText, VisitInput } from "@diamondlightsource/sci-react-ui"; +import { visitTextToVisit } from "../../utils/common"; + +enum LightSource { + LED = "led", + SR = "sr", + DARK = "dark", +} + +export type TomographyFormData = { + number_of_projections: number; + light_source: LightSource; +}; + +export function TomographyForm() { + const { instrumentSession, setInstrumentSession } = useInstrumentSession(); + const [formData, setFormData] = useState({ + number_of_projections: 360, + light_source: LightSource.LED, + }); + const minProjections = 30; + const maxProjections = 1440; + + return ( + + + { + setFormData({ + ...formData, + ["number_of_projections"]: parsedValue, + }); + }} + minValue={minProjections} + maxValue={maxProjections} + /> + setInstrumentSession(visitToText(visit))} + submitButton={false} + /> + + + + + + + + + + + + + ); +} From 1951f6474008adae089de3679a171c4c830a0784 Mon Sep 17 00:00:00 2001 From: Tom Kane Date: Fri, 14 Aug 2026 15:10:07 +0000 Subject: [PATCH 3/8] add new tomography form to controls drawer, and remove redundant controls and handles --- .../tomography/TomographyControls.tsx | 132 +++++++----------- .../components/tomography/TomographyView.tsx | 53 ++----- 2 files changed, 64 insertions(+), 121 deletions(-) diff --git a/apps/visr/src/components/tomography/TomographyControls.tsx b/apps/visr/src/components/tomography/TomographyControls.tsx index 69a08e2c..e4bb73dc 100644 --- a/apps/visr/src/components/tomography/TomographyControls.tsx +++ b/apps/visr/src/components/tomography/TomographyControls.tsx @@ -1,118 +1,86 @@ import { Box, - Button, FormControlLabel, - LinearProgress, Radio, RadioGroup, Slider, - Stack, - TextField, Typography, } from "@mui/material"; import { Plane } from "./PlaneEnum"; interface Props { - onRun: () => void; - onReset: () => void; onSlide: (event: Event, newValue: number | number[]) => void; onSetDirection: (event: React.ChangeEvent) => void; plane: Plane; - progress: number; slice: number; volumeShape: [number, number, number]; } export default function Controls({ - onRun, - onReset, onSlide, onSetDirection, plane, - progress, slice, volumeShape, }: Props) { + const maxSlice: Record = { + [Plane.Z]: volumeShape[0] - 1, + [Plane.Y]: volumeShape[1] - 1, + [Plane.X]: volumeShape[2] - 1, + }; + return ( - - - - - Reconstruction - - - - - - - - - - - - Slice View - - - Slice - - - - Axis - - - } label="X" /> - } label="Y" /> - } label="Z" /> - - - - {/* */} + + Slice View + + + + + Slice + + + - {/* onRevolveChange(!revolve)} - color="secondary" - sx={{ textTransform: "none" }} - > - Revolve - */} + + + Axis + + + } label="X" /> + } label="Y" /> + } label="Z" /> + + ); } + +{ + /* onRevolveChange(!revolve)} + color="secondary" + sx={{ textTransform: "none" }} + > + Revolve + */ +} diff --git a/apps/visr/src/components/tomography/TomographyView.tsx b/apps/visr/src/components/tomography/TomographyView.tsx index 8ecf05dd..feb20010 100644 --- a/apps/visr/src/components/tomography/TomographyView.tsx +++ b/apps/visr/src/components/tomography/TomographyView.tsx @@ -1,6 +1,7 @@ import { Box } from "@mui/material"; import { useEffect, useRef, useState } from "react"; -import Controls from "./TomographyControls"; +import TomographyControls from "./TomographyControls"; +import { TomographyForm } from "./TomographyForm"; import { Plane } from "./PlaneEnum"; import ControlsDrawer from "../ControlsDrawer"; import TomographyPlots from "./TomographyPlots"; @@ -14,8 +15,7 @@ const SCAN_DURATION_MS = 3000; function TomographyView() { const [volume, setVolume] = useState(null); - const [volumeVisible, setVolumeVisible] = useState(false); - const [progress, setProgress] = useState(0); + const [volumeVisible, setVolumeVisible] = useState(true); const intervalRef = useRef | null>(null); // const [revolve, setRevolve] = useState(false); const [slice, setSlice] = useState(0); @@ -48,8 +48,7 @@ function TomographyView() { localStorage.setItem("plane", plane.toString()); localStorage.setItem("volumeVisible", volumeVisible.toString()); localStorage.setItem("slice", slice.toString()); - localStorage.setItem("progress", progress.toString()); - }, [plane, volumeVisible, slice, progress]); + }, [plane, volumeVisible, slice]); useEffect(() => { const onReceiveMessage = (e: StorageEvent) => { @@ -67,10 +66,6 @@ function TomographyView() { setSlice(Number(newValue)); break; } - case "progress": { - setProgress(Number(newValue)); - break; - } } }; window.addEventListener("storage", onReceiveMessage); @@ -79,30 +74,12 @@ function TomographyView() { }; }, []); - // run waits 3 seconds, updating progress bar then allows mock volume to be seen - const handleRun = () => { - if (intervalRef.current) clearInterval(intervalRef.current); - setVolumeVisible(false); - setProgress(0); - - const startTime = Date.now(); - intervalRef.current = setInterval(() => { - const elapsed = Date.now() - startTime; - const next = Math.min((elapsed / SCAN_DURATION_MS) * 100, 100); - setProgress(next); - if (next >= 100) { - clearInterval(intervalRef.current!); - setVolumeVisible(true); - } - }, 50); - }; - // reset reverts progress bar and volume viewing - const handleReset = () => { - if (intervalRef.current) clearInterval(intervalRef.current); - setVolumeVisible(false); - setProgress(0); - }; + // const handleReset = () => { + // if (intervalRef.current) clearInterval(intervalRef.current); + // setVolumeVisible(false); + // setProgress(0); + // }; const handleSlider = (event: Event, newValue: number | number[]) => { const slice = typeof newValue == "number" ? newValue : newValue[0]; @@ -140,18 +117,16 @@ function TomographyView() { open={drawerOpen} collapsedHeight={DRAWER_COLLAPSED_HEIGHT} onToggle={() => setDrawerOpen(prev => !prev)} - controls={ - , + - } + />, + ]} /> ); From 0c9c2092cad0a6b55f2532a2b2e36e01f269b6e1 Mon Sep 17 00:00:00 2001 From: Tom Kane Date: Fri, 14 Aug 2026 15:42:38 +0000 Subject: [PATCH 4/8] simplify action labels --- apps/visr/src/components/ControlsDrawer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/visr/src/components/ControlsDrawer.tsx b/apps/visr/src/components/ControlsDrawer.tsx index 3fafeb36..40ff29c1 100644 --- a/apps/visr/src/components/ControlsDrawer.tsx +++ b/apps/visr/src/components/ControlsDrawer.tsx @@ -47,7 +47,7 @@ function ControlsDrawer({ Controls {open ? : } From cbdd0a50d3d4c016c0424722d092735d40eab518 Mon Sep 17 00:00:00 2001 From: Tom Kane Date: Fri, 14 Aug 2026 15:43:27 +0000 Subject: [PATCH 5/8] add light source switch, and rearrange plan buttons --- .../components/tomography/TomographyForm.tsx | 56 ++++++++++++++----- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/apps/visr/src/components/tomography/TomographyForm.tsx b/apps/visr/src/components/tomography/TomographyForm.tsx index 866985b1..eeacb849 100644 --- a/apps/visr/src/components/tomography/TomographyForm.tsx +++ b/apps/visr/src/components/tomography/TomographyForm.tsx @@ -3,7 +3,13 @@ import { RunPlanButton } from "@atlas/blueapi-ui"; import AbortButton from "../AbortButton"; import { useState } from "react"; import { NumberInput } from "@diamondlightsource/sci-react-ui"; -import { Box } from "@mui/material"; +import { + Box, + FormControl, + FormLabel, + ToggleButton, + ToggleButtonGroup, +} from "@mui/material"; import { visitToText, VisitInput } from "@diamondlightsource/sci-react-ui"; import { visitTextToVisit } from "../../utils/common"; @@ -34,7 +40,6 @@ export function TomographyForm() { flexDirection: "column", gap: 3, p: 3, - maxWidth: 600, }} > setInstrumentSession(visitToText(visit))} submitButton={false} /> + + + Light Source + + + value && setFormData({ ...formData, light_source: value }) + } + > + LED + Synchrotron + Off + + - - + + + From 7c29ea90fcf72524d5e341293ea912196c958ad8 Mon Sep 17 00:00:00 2001 From: Tom Kane Date: Fri, 14 Aug 2026 16:26:58 +0000 Subject: [PATCH 6/8] fix ci; remove unused variables --- apps/visr/src/components/tomography/TomographyView.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/visr/src/components/tomography/TomographyView.tsx b/apps/visr/src/components/tomography/TomographyView.tsx index feb20010..a41f5471 100644 --- a/apps/visr/src/components/tomography/TomographyView.tsx +++ b/apps/visr/src/components/tomography/TomographyView.tsx @@ -11,12 +11,9 @@ interface Volume { volumeShape: [number, number, number]; } -const SCAN_DURATION_MS = 3000; - function TomographyView() { const [volume, setVolume] = useState(null); const [volumeVisible, setVolumeVisible] = useState(true); - const intervalRef = useRef | null>(null); // const [revolve, setRevolve] = useState(false); const [slice, setSlice] = useState(0); const [plane, setPlane] = useState(Plane.Z); From b8544fe790fee855d480fe19d2f33e416ccba743 Mon Sep 17 00:00:00 2001 From: Tom Kane Date: Fri, 14 Aug 2026 16:31:05 +0000 Subject: [PATCH 7/8] remove useref --- apps/visr/src/components/tomography/TomographyView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/visr/src/components/tomography/TomographyView.tsx b/apps/visr/src/components/tomography/TomographyView.tsx index a41f5471..fa584796 100644 --- a/apps/visr/src/components/tomography/TomographyView.tsx +++ b/apps/visr/src/components/tomography/TomographyView.tsx @@ -1,5 +1,5 @@ import { Box } from "@mui/material"; -import { useEffect, useRef, useState } from "react"; +import { useEffect, useState } from "react"; import TomographyControls from "./TomographyControls"; import { TomographyForm } from "./TomographyForm"; import { Plane } from "./PlaneEnum"; From 747225ab8ebeb6eea75a6b80ae9d749599470432 Mon Sep 17 00:00:00 2001 From: Tom Kane Date: Wed, 19 Aug 2026 16:32:49 +0100 Subject: [PATCH 8/8] update correction plan in form, and delete commented out handle --- apps/visr/src/components/tomography/TomographyForm.tsx | 6 +++--- apps/visr/src/components/tomography/TomographyView.tsx | 7 ------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/apps/visr/src/components/tomography/TomographyForm.tsx b/apps/visr/src/components/tomography/TomographyForm.tsx index eeacb849..1f2528b5 100644 --- a/apps/visr/src/components/tomography/TomographyForm.tsx +++ b/apps/visr/src/components/tomography/TomographyForm.tsx @@ -121,10 +121,10 @@ export function TomographyForm() { }} > diff --git a/apps/visr/src/components/tomography/TomographyView.tsx b/apps/visr/src/components/tomography/TomographyView.tsx index fa584796..ea6b1a99 100644 --- a/apps/visr/src/components/tomography/TomographyView.tsx +++ b/apps/visr/src/components/tomography/TomographyView.tsx @@ -71,13 +71,6 @@ function TomographyView() { }; }, []); - // reset reverts progress bar and volume viewing - // const handleReset = () => { - // if (intervalRef.current) clearInterval(intervalRef.current); - // setVolumeVisible(false); - // setProgress(0); - // }; - const handleSlider = (event: Event, newValue: number | number[]) => { const slice = typeof newValue == "number" ? newValue : newValue[0]; setSlice(slice);