Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9ac010a
Add the starting bare bones of a package to upda pvws
noemifrisina Mar 23, 2026
fd86bc2
At least add loadConfiguration for a start
noemifrisina Mar 26, 2026
4b97826
Start adding config to i15-1
noemifrisina Mar 27, 2026
2d8d5c6
For now use known-to-work version of cs-web-lib
noemifrisina Mar 27, 2026
a38ba6c
Just a comment
noemifrisina Mar 27, 2026
7bd972c
Start adding utility functions and a hook
noemifrisina Mar 27, 2026
e4bf173
Add exports
noemifrisina Mar 27, 2026
ab94608
Add a dependency
noemifrisina Mar 27, 2026
f657ccb
Add a dependency - again
noemifrisina Mar 27, 2026
fe1a82f
Add some basic components to display PV with a fallback if connection…
noemifrisina Mar 27, 2026
a6becd0
Fix some bit and actually save changes
noemifrisina Mar 27, 2026
03ac75c
Merge branch 'main' into 30-31_pvws-and-component
noemifrisina Apr 9, 2026
d7508a3
Add dependency to i15-1 and remove property from config as stuck a fe…
noemifrisina Apr 9, 2026
7fb5624
A first attempt - not working, dependency issues to be worked out
noemifrisina Apr 9, 2026
a9181ca
Fix text filed
noemifrisina Apr 10, 2026
bde657b
Update fallback
noemifrisina Apr 10, 2026
0f6d0a3
Tidy up some bits
noemifrisina Apr 10, 2026
a37e361
First version of a card with PV info
noemifrisina Apr 10, 2026
3e49791
... and save it
noemifrisina Apr 10, 2026
f6b1aec
Put state card in a sort-of-sidebar
noemifrisina Apr 10, 2026
40d3834
Merge branch 'main' into 30-31_pvws-and-component
noemifrisina Apr 10, 2026
de43dd2
Add dependencies to i15-1 app
noemifrisina Apr 13, 2026
3c80ed2
Refactor the layout
noemifrisina Apr 13, 2026
e83bd35
Try to make it look slightly more aligned
noemifrisina Apr 14, 2026
d81d0a6
Make the default PV a box
noemifrisina Apr 14, 2026
894b156
Add another example
noemifrisina Apr 14, 2026
8f1cbc2
Tidy up robot page
noemifrisina Apr 17, 2026
f0b8843
Tidy up the Pv box
noemifrisina Apr 17, 2026
4aca3da
Merge branch 'main' into 30-31_pvws-and-component
noemifrisina Apr 17, 2026
2594000
Try adding one test
noemifrisina Apr 17, 2026
6fa9f4d
Tidy up parseNumeric function and add a first test
noemifrisina Apr 22, 2026
faf44c8
Add test using dtype
noemifrisina Apr 22, 2026
d633be8
Test parseString too
noemifrisina Apr 22, 2026
6eb1a9b
A small test of the default box rendering
noemifrisina Apr 22, 2026
9a9550e
Add hook and tidy up main
noemifrisina Apr 24, 2026
5e29b0f
Fill in readme
noemifrisina Apr 24, 2026
29707fd
Add forgotten test file
noemifrisina Apr 24, 2026
3413e60
Merge branch 'main' into 30-31_pvws-and-component
noemifrisina May 8, 2026
06f4e12
Run pnpm i on changes
noemifrisina May 8, 2026
2944fa2
Merge branch 'main' into 30-31_pvws-and-component
noemifrisina May 8, 2026
65a79dc
Add handler for websocket
noemifrisina May 8, 2026
36b1800
Fix the logo
noemifrisina May 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/i15-1/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"dependencies": {
"@atlas/blueapi": "workspace:*",
"@atlas/blueapi-query": "workspace:*",
"@atlas/pvws-config": "workspace:*",
"@diamondlightsource/sci-react-ui": "^0.4.0",
"@diamondlightsource/cs-web-lib": "0.9.5",
"@mui/icons-material": "^6.5.0",
"@mui/material": "<7.0.0",
"@tanstack/react-query": "^5.90.21",
Expand All @@ -23,7 +25,9 @@
"@vitejs/plugin-react-swc": "^3.11.0",
"msw": "^2.10.4",
"react-router-dom": "^7.7.1",
"react-redux": "^7.2.9",
"typescript": "~5.9.3",
"@types/react-redux": "7.1.34",
"vite": "^7.3.1",
"vite-plugin-relay": "^2.1.0",
"vitest": "*"
Expand Down
5 changes: 5 additions & 0 deletions apps/i15-1/public/pvwsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"PVWS_SOCKET": "pvws.diamond.ac.uk",
"PVWS_SSL": true,
"THROTTLE_PERIOD": 100
}
55 changes: 55 additions & 0 deletions apps/i15-1/src/components/StatusCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Card, CardContent, Stack, Typography, useTheme } from "@mui/material";
import type { ReactNode } from "react";

type StatusCardProps = {
children: ReactNode;
title?: string;
bgColor?: string;
cardColor?: string;
};

export function StatusCard(props: StatusCardProps) {
const theme = useTheme();
const bgColor = props.bgColor
? props.bgColor
: theme.palette.background.paper;
const cardColor = props.cardColor
? props.cardColor
: theme.palette.text.primary;
if (props.title) {
return (
<Card
variant="outlined"
sx={{
minWidth: 250,
maxHeight: 200,
bgcolor: bgColor,
borderColor: cardColor,
}}
>
<CardContent>
<Stack spacing={1}>
<Typography
variant="body1"
sx={{
fontSize: 16,
fontStyle: "italic",
fontWeight: "bold",
color: cardColor,
}}
>
{props.title}
</Typography>
{props.children}
</Stack>
</CardContent>
</Card>
);
} else {
return (
<Card variant="outlined" sx={{ minWidth: 250, bgColor: bgColor }}>
<CardContent>{props.children}</CardContent>
</Card>
);
}
}
29 changes: 10 additions & 19 deletions apps/i15-1/src/components/WaffleNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
User,
} from "@diamondlightsource/sci-react-ui";
import { useUserAuth } from "../context/userAuth/useUserAuth";
import React from "react";

function WaffleNavbar() {
const user = useUserAuth();
Expand All @@ -19,24 +20,6 @@ function WaffleNavbar() {
<Navbar
logo="theme"
containerWidth={false}
leftSlot={
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
flexWrap: "nowrap",
overflow: "hidden",
}}
>
<NavLinks>
<NavLink to="/robot" linkComponent={Link}>
Robot
</NavLink>
</NavLinks>
</Box>
}
rightSlot={
<Box sx={{ marginLeft: 4 }}>
<User
Expand All @@ -52,7 +35,15 @@ function WaffleNavbar() {
<ColourSchemeButton />
</Box>
}
/>
>
<React.Fragment>
<NavLinks>
<NavLink to="/robot" linkComponent={Link}>
Robot
</NavLink>
</NavLinks>
</React.Fragment>
</Navbar>
);
}

Expand Down
29 changes: 21 additions & 8 deletions apps/i15-1/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { DiamondTheme, ThemeProvider } from "@diamondlightsource/sci-react-ui";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import { createRoot } from "react-dom/client";
import { StrictMode } from "react";
import { StrictMode, useEffect, useState } from "react";

import { Layout } from "./routes/Layout.tsx";
import Dashboard from "./routes/Dashboard.tsx";
import Robot from "./routes/Robot.tsx";
import { InstrumentSessionProvider } from "./context/instrumentSession/InstrumentSessionProvider.tsx";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { store } from "@diamondlightsource/cs-web-lib";
import { Provider } from "react-redux";

declare global {
interface Window {
Expand All @@ -17,6 +19,7 @@ declare global {

import { createApi } from "@atlas/blueapi";
import { BlueapiProvider } from "@atlas/blueapi-query";
import { useLoadPvwsConfig } from "@atlas/pvws-config";
import { UserAuthProvider } from "./context/userAuth/UserAuthProvider.tsx";

async function enableMocking() {
Expand Down Expand Up @@ -46,18 +49,28 @@ const router = createBrowserRouter([
const api = createApi("/api");
const queryClient = new QueryClient();

function App() {
const config = useLoadPvwsConfig();

return (
<Provider store={store(config)}>
<QueryClientProvider client={queryClient}>
<UserAuthProvider>
<BlueapiProvider api={api}>
<RouterProvider router={router} />
</BlueapiProvider>
</UserAuthProvider>
</QueryClientProvider>
</Provider>
);
}

enableMocking().then(() => {
createRoot(document.getElementById("root")!).render(
<InstrumentSessionProvider>
<StrictMode>
<ThemeProvider theme={DiamondTheme} defaultMode="light">
<QueryClientProvider client={queryClient}>
<UserAuthProvider>
<BlueapiProvider api={api}>
<RouterProvider router={router} />
</BlueapiProvider>
</UserAuthProvider>
</QueryClientProvider>
<App />
</ThemeProvider>
</StrictMode>
</InstrumentSessionProvider>,
Expand Down
8 changes: 7 additions & 1 deletion apps/i15-1/src/mocks/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { http, HttpResponse } from "msw";
import { http, HttpResponse, ws } from "msw";

const fakeTaskId = "7304e8e0-81c6-4978-9a9d-9046ab79ce3c";
let workerStatus = { status: "IDLE", duration: 0 };

const fakePvws = ws.link("wss://pvws.diamond.ac.uk/pvws/pv");

export const handlers = [
http.put("/api/worker/task", () => {
workerStatus.status = "RUNNING";
Expand Down Expand Up @@ -32,4 +34,8 @@ export const handlers = [
} else workerStatus.duration++;
return HttpResponse.json(workerStatus.status);
}),

fakePvws.addEventListener("connection", () => {
console.log("WebSocket client connecting...");
}),
];
85 changes: 66 additions & 19 deletions apps/i15-1/src/routes/Robot.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,86 @@
import { useInstrumentSession } from "../context/instrumentSession/useInstrumentSession";
import { Box, Typography, Stack } from "@mui/material";
import { Box, Typography, Stack, useTheme, TextField } from "@mui/material";
import { useState } from "react";
import { NumberInput } from "../components/NumberInput";
import RunPlanButton from "../components/RunPlanButton";
import { ReadOnlyPv } from "@atlas/pvws-config";
import { StatusCard } from "../components/StatusCard";

type RobotSampleFormData = {
puck: number;
position: number;
};

function StatusSidebar() {
const theme = useTheme();
return (
<Box sx={{ ml: 5 }}>
<Stack direction={"column"} spacing={2}>
<StatusCard
title="Currently loaded"
bgColor={theme.palette.info.light}
cardColor={theme.palette.primary.main}
>
<ReadOnlyPv label="Puck" pv="ca://BL15J-EA-LOC-01:PUCK:INDEX" />
<ReadOnlyPv
label="Sample Pin"
pv="ca://BL15J-EA-LOC-01:SAMPLE:INDEX"
/>
</StatusCard>
<StatusCard
title="Ring status"
bgColor={theme.palette.success.light}
cardColor={theme.palette.primary.main}
>
<ReadOnlyPv
label="Ring Current"
pv="ca://SR-DI-DCCT-01:SIGNAL"
parseNumeric
units="mA"
/>
<ReadOnlyPv
label="Ring Energy"
pv="ca://CS-CS-MSTAT-01:BEAMENERGY"
parseNumeric
units="GeV"
/>
</StatusCard>
</Stack>
</Box>
);
}

function Robot() {
const { instrumentSession, setInstrumentSession } = useInstrumentSession();
const { instrumentSession } = useInstrumentSession();
const [formData, setFormData] = useState<RobotSampleFormData>({
puck: 1,
position: 1,
});
const theme = useTheme();
return (
<>
<Box display={"flex"} justifyContent={"center"} sx={{ mt: 3 }}>
<Box
// component={"section"}
sx={{
display: "flex",
justifyContent: "center",
mt: 3,
mr: 5,
ml: 5,
}}
>
<Box
sx={{
padding: 5,
borderRadius: 1,
border: "1px solid",
borderColor: theme.palette.primary.main,
}}
>
<Stack direction={"column"} spacing={3} alignItems={"center"}>
<Typography component="h1" variant="h5">
Sample Position
</Typography>
<Box
sx={{
display: "flex",
justifyContent: "center",
gridTemplateColumns: {
xs: "1fr",
sm: "1fr 1fr",
md: "1fr 1fr 1fr",
},
gap: 3,
flexGrow: 1,
}}
>
<Stack direction={"row"} spacing={3} alignItems={"center"}>
<NumberInput
label="Puck"
numberMode="natural"
Expand All @@ -51,7 +97,7 @@ function Robot() {
setFormData({ ...formData, ["position"]: parsedValue });
}}
/>
</Box>
</Stack>
<RunPlanButton
name="robot_load"
params={formData}
Expand All @@ -65,7 +111,8 @@ function Robot() {
/>
</Stack>
</Box>
</>
<StatusSidebar />
</Box>
);
}

Expand Down
4 changes: 4 additions & 0 deletions apps/i15-1/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import relay from "vite-plugin-relay";
export default defineConfig({
plugins: [react(), relay],
define: {
"process.env": {
VITE_PVWS_SOCKET: "pvws.diamond.ac.uk",
VITE_PVWS_SSL: "true",
},
global: {},
},
});
Loading
Loading