Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 12 additions & 7 deletions src/blueapi/BlueapiComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type RunPlanButtonProps = {
sx?: object;
tooltipSx?: object;
typographySx?: object;
onSuccess?: () => void | Promise<void>; // Optional callback after plan succeeds
};

export function RunPlanButton(props: RunPlanButtonProps) {
Expand Down Expand Up @@ -63,13 +64,17 @@ export function RunPlanButton(props: RunPlanButtonProps) {
planName: props.planName,
planParams: params,
instrumentSession: instrumentSession,
}).catch((error) => {
setSeverity("error");
setMsg(
`Failed to run plan ${props.planName}, see console and logs for full error`,
);
console.log(`${msg}. Reason: ${error}`);
});
})
.then(() => {
props.onSuccess?.();
})
.catch((error) => {
setSeverity("error");
setMsg(
`Failed to run plan ${props.planName}, see console and logs for full error`,
);
console.log(`${msg}. Reason: ${error}`);
});
} catch (error) {
setSeverity("error");
setMsg(
Expand Down
2 changes: 0 additions & 2 deletions src/components/OavVideoStream.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ function VideoBoxWithOverlay(props: {
drawCanvas(canvasRef, props.crosshairX, props.crosshairY);
}, [props.crosshairX, props.crosshairY, width, height]);

console.info();

return (
<Box position={"relative"} padding={0} ref={videoBoxRef}>
<img
Expand Down
2 changes: 1 addition & 1 deletion src/config_server/configServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ export function useConfigCall(
return await response.text();
};
return useQuery(queryKey ?? "ConfigCall", fetchCall, {
refetchInterval: pollRateMillis ?? 500,
refetchInterval: pollRateMillis ?? false,
});
}
11 changes: 11 additions & 0 deletions src/context/beamcenter/BeamCenterContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createContext } from "react";

type BeamCenterQueryResult = {
data: string | null | undefined;
refetch: () => void;
};

export const BeamCenterContext = createContext<BeamCenterQueryResult>({
data: null,
refetch: () => {},
});
80 changes: 80 additions & 0 deletions src/context/beamcenter/BeamCenterProvider.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { describe, it, expect, vi, afterEach, beforeEach } from "vitest";
import { useContext } from "react";
import "@testing-library/jest-dom/vitest";
import { BeamCenterProvider } from "./BeamCenterProvider";
import { BeamCenterContext } from "./BeamCenterContext";
import { useConfigCall } from "#/config_server/configServer.ts";
import type { UseQueryResult } from "react-query";

vi.mock("#/config_server/configServer.ts", () => ({
useConfigCall: vi.fn(),
}));

const TestConsumer = () => {
const value = useContext(BeamCenterContext);
return (
<>
<div data-testid="context-value">{value.data}</div>
<button data-testid="refetch-button" onClick={() => value.refetch()}>
Refetch
</button>
</>
);
};

describe("BeamCenterProvider", () => {
afterEach(() => {
cleanup();
vi.clearAllMocks();
});

const mockRefetch = vi.fn();
const mockQueryResult = {
data: "mock config text",
refetch: mockRefetch,
};

beforeEach(() =>
vi
.mocked(useConfigCall)
.mockReturnValue(
mockQueryResult as unknown as UseQueryResult<string, unknown>,
),
);

it("calls useConfigCall with the correct endpoint", () => {
render(
<BeamCenterProvider>
<TestConsumer />
</BeamCenterProvider>,
);

expect(useConfigCall).toHaveBeenCalledWith(
"/dls_sw/i24/software/daq_configuration/domain/display.configuration",
);
});

it("provides the data to consumers via context", () => {
render(
<BeamCenterProvider>
<TestConsumer />
</BeamCenterProvider>,
);

expect(screen.getByTestId("context-value")).toHaveTextContent(
"mock config text",
);
});

it("passes refetch function through context and it can be called", () => {
render(
<BeamCenterProvider>
<TestConsumer />
</BeamCenterProvider>,
);

fireEvent.click(screen.getByTestId("refetch-button"));
expect(mockRefetch).toHaveBeenCalled();
});
});
16 changes: 16 additions & 0 deletions src/context/beamcenter/BeamCenterProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ReactNode } from "react";
import { useConfigCall } from "#/config_server/configServer.ts";
import { BeamCenterContext } from "./BeamCenterContext";

const DISPLAY_CONFIG_ENDPOINT =
"/dls_sw/i24/software/daq_configuration/domain/display.configuration";

export const BeamCenterProvider = ({ children }: { children: ReactNode }) => {
const beamCenterQuery = useConfigCall(DISPLAY_CONFIG_ENDPOINT);

return (
<BeamCenterContext.Provider value={beamCenterQuery}>
{children}
</BeamCenterContext.Provider>
);
};
9 changes: 6 additions & 3 deletions src/routes/BeamlineI24.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { BeamlineStatsTabPanel } from "#/screens/BeamlineStats.tsx";
import { DetectorMotionTabPanel } from "#/screens/DetectorMotion.tsx";
import { FallbackScreen } from "#/screens/FallbackScreen.tsx";
import { OavMover } from "#/screens/OavMover/OAVStageController.tsx";
import { BeamCenterProvider } from "#/context/beamcenter/BeamCenterProvider.tsx";
import { Box, Tab, Tabs, useTheme } from "@mui/material";
import React from "react";
import { ErrorBoundary } from "react-error-boundary";
import { useState } from "react";

interface TabPanelProps {
children?: React.ReactNode;
Expand Down Expand Up @@ -37,7 +38,7 @@ function CustomTabPanel(props: TabPanelProps) {

export function BeamlineI24() {
const theme = useTheme();
const [tab, setTab] = React.useState(0);
const [tab, setTab] = useState(0);

const handleChange = (_event: React.SyntheticEvent, newTab: number) => {
setTab(newTab);
Expand Down Expand Up @@ -73,7 +74,9 @@ export function BeamlineI24() {
<DetectorMotionTabPanel />
</CustomTabPanel>
<CustomTabPanel value={tab} index={2}>
<OavMover />
<BeamCenterProvider>
<OavMover />
</BeamCenterProvider>
</CustomTabPanel>
</Box>
</ErrorBoundary>
Expand Down
Loading
Loading