From 580b4863072e70592f60a943fbf5b843cd566c89 Mon Sep 17 00:00:00 2001 From: Bogdan Kostov Date: Mon, 3 Jun 2024 14:13:01 +0200 Subject: [PATCH 1/2] [Fix #321] Add useSelectedSystemHook and add its SelectedSystemProvider in DashboardContentProvider --- src/hooks/DashboardContentProvider.tsx | 6 ++++- src/hooks/useSelectedSystem.tsx | 36 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/hooks/useSelectedSystem.tsx diff --git a/src/hooks/DashboardContentProvider.tsx b/src/hooks/DashboardContentProvider.tsx index c5558592..028a7a6d 100644 --- a/src/hooks/DashboardContentProvider.tsx +++ b/src/hooks/DashboardContentProvider.tsx @@ -3,12 +3,16 @@ import { ChildrenProps } from "../utils/hookUtils"; import { FaultTreesProvider } from "./useFaultTrees"; import { FailureModesTablesProvider } from "./useFailureModesTables"; import { SystemsProvider } from "@hooks/useSystems"; +import {SelectedSystemProvider} from "@hooks/useSelectedSystem"; const DashboardContentProvider = ({ children }: ChildrenProps) => { return ( + - {children} + + {children} + ); diff --git a/src/hooks/useSelectedSystem.tsx b/src/hooks/useSelectedSystem.tsx new file mode 100644 index 00000000..ac57b8cc --- /dev/null +++ b/src/hooks/useSelectedSystem.tsx @@ -0,0 +1,36 @@ +import * as React from "react"; +import { createContext, useContext, useState } from "react"; +import {SELECTED_SYSTEM} from "@utils/constants"; +import { ChildrenProps } from "@utils/hookUtils"; +import {System} from "../models/systemModel"; + +type systemContextType = [System, (system: System) => void]; + +export const selectedSystemContext = createContext(null!); + +export const useSelectedSystem = () => { + const [selectedSystem, setSelectedSystem] = useContext(selectedSystemContext); + return [selectedSystem, setSelectedSystem] as const; +}; + +export const getSelectedSystem = (): System => { + const item = sessionStorage.getItem(SELECTED_SYSTEM); + + if (!item) + return null; + + return JSON.parse(item); +}; + +export const SelectedSystemProvider = ({ children }: ChildrenProps) => { + const [_system, _setSelectedSystem] = useState(getSelectedSystem()); + + const setSelectedSystem = async (system: System) => { + sessionStorage.removeItem(SELECTED_SYSTEM); + if(system) + sessionStorage.setItem(SELECTED_SYSTEM, JSON.stringify(system)); + _setSelectedSystem(system); + }; + + return {children}; +}; From c834f2b01ab6d79d78029033bafd2da6bd972001 Mon Sep 17 00:00:00 2001 From: Bogdan Kostov Date: Tue, 4 Jun 2024 10:19:06 +0200 Subject: [PATCH 2/2] [Fix #321] Replace old global system selection with useSelectedSystem hook --- src/components/appBar/AppBar.tsx | 26 +++++++------------ .../list/FaultTreeAndSystemOverviewTable.tsx | 14 +++++----- .../content/list/FaultTreeOverview.tsx | 22 ++++------------ .../dashboard/content/list/SystemOverview.tsx | 20 +++----------- .../dialog/faultTree/FaultTreeDialog.tsx | 10 +++---- 5 files changed, 28 insertions(+), 64 deletions(-) diff --git a/src/components/appBar/AppBar.tsx b/src/components/appBar/AppBar.tsx index 11247a73..68a3512a 100644 --- a/src/components/appBar/AppBar.tsx +++ b/src/components/appBar/AppBar.tsx @@ -1,5 +1,4 @@ import * as React from "react"; -import { useEffect } from "react"; import useStyles from "@components/appBar/AppBar.styles"; import { AccountCircle } from "@mui/icons-material"; import { @@ -23,10 +22,11 @@ import { ROUTES } from "@utils/constants"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { useTranslation } from "react-i18next"; import LanguageIcon from "@mui/icons-material/Language"; -import { PRIMARY_LANGUAGE, SECONDARY_LANGUAGE, SELECTED_LANGUAGE_KEY, SELECTED_SYSTEM } from "@utils/constants"; +import { PRIMARY_LANGUAGE, SECONDARY_LANGUAGE, SELECTED_LANGUAGE_KEY } from "@utils/constants"; import { useAppBar } from "../../contexts/AppBarContext"; import { useLocation } from "react-router-dom"; import CancelIcon from "@mui/icons-material/Cancel"; +import {useSelectedSystem} from "@hooks/useSelectedSystem"; interface Props { title: string; @@ -43,16 +43,11 @@ const AppBar = ({ title, showBackButton = false, topPanelHeight }: Props) => { const { appBarTitle, systemsList } = useAppBar(); const [anchorEl, setAnchorEl] = React.useState(null); - const [selectedSystem, setSelectedSystem] = useState(() => sessionStorage.getItem(SELECTED_SYSTEM) || ""); + const [selectedSystem, setSelectedSystem] = useSelectedSystem(); const [changePasswordDialogOpen, setChangePasswordDialogOpen] = useState(false); const isMenuOpen = Boolean(anchorEl); - useEffect(() => { - const currentItem = sessionStorage.getItem(SELECTED_SYSTEM); - if (selectedSystem !== currentItem) setSelectedSystem(currentItem); - }, [location.pathname]); - const handleProfileMenuOpen = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; @@ -109,17 +104,14 @@ const AppBar = ({ title, showBackButton = false, topPanelHeight }: Props) => { } }; - const handleSystemChange = (event: React.ChangeEvent<{ value: unknown }>) => { + const handleSystemChange = (event : React.ChangeEvent<{ value: unknown }>) => { const value = event.target.value as string; - setSelectedSystem(value); - sessionStorage.setItem(SELECTED_SYSTEM, value); - window.dispatchEvent(new Event("storage")); + const selectedSystem = value ? systemsList.find((s) => s.iri == value) : null; + setSelectedSystem(selectedSystem); }; const handleSystemDelete = () => { - setSelectedSystem(""); - sessionStorage.setItem(SELECTED_SYSTEM, ""); - window.dispatchEvent(new Event("storage")); + setSelectedSystem(null); }; return ( @@ -147,12 +139,12 @@ const AppBar = ({ title, showBackButton = false, topPanelHeight }: Props) => { select InputLabelProps={{ shrink: false }} className={classes.textfieldSelect} - value={selectedSystem || ""} + value={selectedSystem ? selectedSystem.iri : ""} onChange={handleSystemChange} > {systemsList.map((s, i) => { return ( - + {s.name} ); diff --git a/src/components/dashboard/content/list/FaultTreeAndSystemOverviewTable.tsx b/src/components/dashboard/content/list/FaultTreeAndSystemOverviewTable.tsx index 0388bf7d..4cb40fb4 100644 --- a/src/components/dashboard/content/list/FaultTreeAndSystemOverviewTable.tsx +++ b/src/components/dashboard/content/list/FaultTreeAndSystemOverviewTable.tsx @@ -5,10 +5,11 @@ import { useTranslation } from "react-i18next"; import useStyles from "./FaultTreeOverviewTable.styles"; import { FaultTree } from "@models/faultTreeModel"; import { useNavigate } from "react-router-dom"; -import { ROUTES, SELECTED_SYSTEM } from "@utils/constants"; +import {ROUTES} from "@utils/constants"; import { extractFragment } from "@services/utils/uriIdentifierUtils"; import { System } from "@models/systemModel"; import { getModifiedSystemsList, getModifiedFaultTreesList, formatDate } from "@utils/utils"; +import {useSelectedSystem} from "@hooks/useSelectedSystem"; const faultTreeTableHeadCells = [ "faultTreeOverviewTable.name", @@ -45,13 +46,12 @@ const FaultTreeAndSystemOverviewTable: FC = ({ const { t } = useTranslation(); const theme = useTheme(); + const [, setSelectedSystem] = useSelectedSystem(); const modifiedSystemsList = getModifiedSystemsList(systems, selectedSystem); const modifiedFaultTreesList = getModifiedFaultTreesList(faultTrees, selectedSystem); - const redirectToPath = (routePath: string, systemName?: string) => { - if (systemName) { - sessionStorage.setItem(SELECTED_SYSTEM, systemName); - } + const redirectToPath = (routePath: string, system ) => { + setSelectedSystem(system); navigate(routePath); }; @@ -103,7 +103,7 @@ const FaultTreeAndSystemOverviewTable: FC = ({ @@ -128,7 +128,7 @@ const FaultTreeAndSystemOverviewTable: FC = ({ diff --git a/src/components/dashboard/content/list/FaultTreeOverview.tsx b/src/components/dashboard/content/list/FaultTreeOverview.tsx index 3543d27e..0d23b260 100644 --- a/src/components/dashboard/content/list/FaultTreeOverview.tsx +++ b/src/components/dashboard/content/list/FaultTreeOverview.tsx @@ -12,8 +12,8 @@ import FaultTreeEditDialog from "@components/dialog/faultTree/FaultTreeEditDialo import FaultTreeDialog from "@components/dialog/faultTree/FaultTreeDialog"; import { Box, Button } from "@mui/material"; import { useTranslation } from "react-i18next"; -import { SELECTED_SYSTEM, SELECTED_VIEW } from "@utils/constants"; -import { FaultEventsReuseProvider } from "@hooks/useReusableFaultEvents"; +import { SELECTED_VIEW } from "@utils/constants"; +import {useSelectedSystem} from "@hooks/useSelectedSystem"; const FaultTreeOverview = () => { const { t } = useTranslation(); @@ -25,25 +25,13 @@ const FaultTreeOverview = () => { const [contextMenuSelectedTree, setContextMenuSelectedTree] = useState(null); const [contextMenuAnchor, setContextMenuAnchor] = useState(contextMenuDefaultAnchor); const [createFaultTreeDialogOpen, setCreateFaultTreeDialogOpen] = useState(false); - const [selectedSystem, setSelectedSystem] = useState(sessionStorage.getItem(SELECTED_SYSTEM)); + const [selectedSystem] = useSelectedSystem(); useEffect(() => { const storedView = localStorage.getItem(SELECTED_VIEW) as ViewType; if (storedView) { setSelectedView(storedView); } - const handleStorageChange = () => { - const system = sessionStorage.getItem(SELECTED_SYSTEM); - if (system) { - setSelectedSystem(system); - } - }; - - window.addEventListener("storage", handleStorageChange); - - return () => { - window.removeEventListener("storage", handleStorageChange); - }; }, []); const toggleView = (viewType: ViewType) => { @@ -83,13 +71,13 @@ const FaultTreeOverview = () => { {selectedView === "table" ? ( ) : ( diff --git a/src/components/dashboard/content/list/SystemOverview.tsx b/src/components/dashboard/content/list/SystemOverview.tsx index af2dd76a..989d2d79 100644 --- a/src/components/dashboard/content/list/SystemOverview.tsx +++ b/src/components/dashboard/content/list/SystemOverview.tsx @@ -13,7 +13,7 @@ import FaultTreeAndSystemOverviewCardsList from "./FaultTreeAndSystemOverviewCar import { useTranslation } from "react-i18next"; import { Button, Box } from "@mui/material"; import SystemDialog from "@components/dialog/system/SystemDialog"; -import { SELECTED_SYSTEM } from "@utils/constants"; +import {useSelectedSystem} from "@hooks/useSelectedSystem"; const SystemOverview = () => { const { t } = useTranslation(); @@ -25,25 +25,13 @@ const SystemOverview = () => { const [contextMenuAnchor, setContextMenuAnchor] = useState(contextMenuDefaultAnchor); const [editDialogOpen, setEditDialogOpen] = useState(false); const [createSystemDialogOpen, setCreateSystemDialogOpen] = useState(false); - const [selectedSystem, setSelectedSystem] = useState(sessionStorage.getItem(SELECTED_SYSTEM)); + const [selectedSystem, setSelectedSystem] = useSelectedSystem(); useEffect(() => { const storedView = localStorage.getItem("selectedView") as ViewType; if (storedView) { setSelectedView(storedView); } - const handleStorageChange = () => { - const system = sessionStorage.getItem(SELECTED_SYSTEM); - if (system) { - setSelectedSystem(system); - } - }; - - window.addEventListener("storage", handleStorageChange); - - return () => { - window.removeEventListener("storage", handleStorageChange); - }; }, []); const toggleView = (viewType: ViewType) => { @@ -83,13 +71,13 @@ const SystemOverview = () => { {selectedView === "table" ? ( ) : ( diff --git a/src/components/dialog/faultTree/FaultTreeDialog.tsx b/src/components/dialog/faultTree/FaultTreeDialog.tsx index 68660c17..3dfc26b8 100644 --- a/src/components/dialog/faultTree/FaultTreeDialog.tsx +++ b/src/components/dialog/faultTree/FaultTreeDialog.tsx @@ -14,8 +14,8 @@ import { yupResolver } from "@hookform/resolvers/yup"; import { rootEventSchema } from "@components/dialog/faultEvent/FaultEventCreation.schema"; import { FaultEventsReuseProvider } from "@hooks/useReusableFaultEvents"; import { useTranslation } from "react-i18next"; -import { SELECTED_SYSTEM } from "@utils/constants"; import useStyles from "@components/dialog/faultTree/FaultTreeDialog.styles"; +import {useSelectedSystem} from "@hooks/useSelectedSystem"; const FaultTreeDialog = ({ open, handleCloseDialog }) => { const { t } = useTranslation(); @@ -23,15 +23,11 @@ const FaultTreeDialog = ({ open, handleCloseDialog }) => { const [, addFaultTree] = useFaultTrees(); const [processing, setIsProcessing] = useState(false); - const [systemName, setSystemName] = useState(sessionStorage.getItem(SELECTED_SYSTEM)); + const [selectedSystem] = useSelectedSystem(); const useFormMethods = useForm({ resolver: yupResolver(schema.concat(rootEventSchema)) }); const { handleSubmit, register } = useFormMethods; - useEffect(() => { - setSystemName(sessionStorage.getItem(SELECTED_SYSTEM)); - }, [sessionStorage.getItem(SELECTED_SYSTEM)]); - const handleCreateFaultTree = async (values: any) => { setIsProcessing(true); @@ -57,7 +53,7 @@ const FaultTreeDialog = ({ open, handleCloseDialog }) => {