Skip to content
Closed
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
35 changes: 35 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
FileProvider,
FileContext,
NotificationContainer,
store
} from "@diamondlightsource/cs-web-lib";
Expand All @@ -12,6 +13,7 @@ import { SynopticPage } from "./routes/SynopticPage";
import { EditorPage } from "./routes/EditorPage";
import { LandingPage } from "./routes/LandingPage";
import { DataBrowserPage } from "./routes/DataBrowserPage";
import { ResumeLastSession } from "./components/ResumeLastSession";
import { createContext, useEffect, useReducer, useState } from "react";
import {
APPEND_BEAMLINES,
Expand All @@ -23,6 +25,15 @@ import { DaedalusConfig, loadConfig } from "./config";
import { Box, CircularProgress, Typography } from "@mui/material";
import { diamondTheme } from "./theme";
import { QuickScreensPage } from "./routes/QuickScreensPage";
import { useLocation } from "react-router";
import { useContext } from "react";

type SavedSession = {
version: 1;
pathname: string;
pageState: any;
tabState: any;
};

const INITIAL_SCREEN_STATE = {
main: {
Expand All @@ -32,6 +43,28 @@ const INITIAL_SCREEN_STATE = {
}
};

function SessionPersistence() {
const fileContext = useContext(FileContext);
const location = useLocation();

useEffect(() => {
if (location.pathname === "/resume-last-session") return;

const session: SavedSession = {
version: 1,
pathname: location.pathname,
pageState: fileContext.pageState,
tabState: fileContext.tabState
};

if (session.pathname !== "/") {
localStorage.setItem("lastSession", JSON.stringify(session));
}
}, [location.pathname, fileContext.pageState, fileContext.tabState]);

return null;
}

export const BeamlineTreeStateContext = createContext<{
state: BeamlineTreeState;
dispatch: React.Dispatch<any>;
Expand Down Expand Up @@ -74,6 +107,7 @@ const App = ({}) => {
<BeamlineTreeStateContext.Provider value={{ state, dispatch }}>
<FileProvider initialPageState={INITIAL_SCREEN_STATE}>
<>
<SessionPersistence />
<NotificationContainer />
<Outlet />
</>
Expand Down Expand Up @@ -101,6 +135,7 @@ export const appRouter = createBrowserRouter([
]
},
{ path: "/quick-screens", element: <QuickScreensPage /> },
{ path: "/resume-last-session", element: <ResumeLastSession /> },
{ index: true, element: <LandingPage /> }
]
}
Expand Down
4 changes: 3 additions & 1 deletion src/components/AppBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ const DLSAppBar = (props: {
flexGrow: 1
}}
>
{PageRouteInfo.map(page => {
{PageRouteInfo.filter(
page => page.route !== "/resume-last-session"
).map(page => {
return (
<Tooltip key={`PageNavButton_${page.name}`} title={page.name}>
<IconButton
Expand Down
36 changes: 36 additions & 0 deletions src/components/ResumeLastSession.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useEffect } from "react";
import { useNavigate } from "react-router";

export function ResumeLastSession() {
const navigate = useNavigate();

useEffect(() => {
const lastSession = localStorage.getItem("lastSession");

if (!lastSession) {
navigate("/", { replace: true });
return;
}

try {
const session = JSON.parse(lastSession);

if (session.version !== 1 || !session.pathname) {
navigate("/", { replace: true });
return;
}

navigate(session.pathname, {
replace: true,
state: {
pageState: session.pageState,
tabState: session.tabState
}
});
} catch {
navigate("/", { replace: true });
}
}, [navigate]);

return null;
}
9 changes: 9 additions & 0 deletions src/routes/PageRouteInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import MonitorIcon from "@mui/icons-material/Monitor";
import EditIcon from "@mui/icons-material/Edit";
import ShowChartIcon from "@mui/icons-material/ShowChart";
import RateReviewIcon from "@mui/icons-material/RateReview";
import KeyboardReturn from "@mui/icons-material/KeyboardReturn";

export const PageRouteInfo = [
{
Expand Down Expand Up @@ -53,5 +54,13 @@ export const PageRouteInfo = [
text: "A demonstration of the Daedalus Editor functionality. This will eventually allow editing of .bob files inside the web.\n\nOpen files, view widget properties and drag-and-drop new widgets from the palette.",
icon: <EditIcon />,
showCard: true
},
{
name: "Resume Last Session",
ariaLabel: "open last session",
route: "/resume-last-session",
text: "Continue from where you left off in your last session. This will restore the last open screens and their state. \n\n\n\n\n\n",
icon: <KeyboardReturn />,
showCard: true
}
];
8 changes: 5 additions & 3 deletions src/tests/components/AppBar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,11 @@ describe("DLSAppBar Component", () => {
it("renders all page navigation buttons from PageRouteInfo", () => {
renderComponent();

PageRouteInfo.forEach(page => {
expect(screen.getByLabelText(page.ariaLabel)).toBeInTheDocument();
});
PageRouteInfo.filter(page => page.route !== "/resume-last-session").forEach(
page => {
expect(screen.getByLabelText(page.ariaLabel)).toBeInTheDocument();
}
);
});

it("navigates to the correct route when page button is clicked", () => {
Expand Down
Loading