diff --git a/src/App.tsx b/src/App.tsx index eca00b1654c76ba941f7fdc8d98b3b0775752a0d..b6c7db91d2f4a0e63419f0668c51d10ed8d99dc0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,12 +20,13 @@ import { JobLogAccessControl } from "./views/jobs/JobLogAccessControl"; import { RecordListView } from "./views/records/RecordListView"; import { RecordDetailsView } from "./views/records/RecordDetailsView"; import { TestErrorView } from "./views/TestErrorView"; -import { applicationTitle } from "./components/common/Helper"; +import { applicationTitle } from "./components/common/applicationTitle"; import { CreateIOCAccessControl } from "./views/IOC/CreateIOCAccessControl"; import { UserDetailsAccessControl } from "./views/UserPage/UserDetailsAccessControl"; import { ReduxProvider } from "./store/ReduxProvider"; -import env from "./config/env"; +import { env } from "./config/env"; import { GlobalAppBarContext as GlobalAppBarContextType } from "./types/common"; +import { MAX_SNACK } from "./constants"; // setting up the application (TAB)title function App() { @@ -38,7 +39,7 @@ function App() { <BrowserRouter> <SnackbarProvider preventDuplicate - maxSnack={5} + maxSnack={MAX_SNACK} > <StyledEngineProvider injectFirst> <ThemeProvider theme={theme}> diff --git a/src/api/UserProvider.spec.tsx b/src/api/UserProvider.spec.tsx index ec8cd1fe5a8bf41beacbbca2f6c4ce28d0bda044..b52cf8982a833ab91e5a3b82582a8e3bf2fabd5b 100644 --- a/src/api/UserProvider.spec.tsx +++ b/src/api/UserProvider.spec.tsx @@ -4,6 +4,7 @@ import { SnackbarProvider } from "notistack"; import { UserProvider } from "./UserProvider"; import { ReduxProvider } from "../store/ReduxProvider"; import { UserContext } from "../types/common"; +import { MAX_SNACK } from "../constants"; function DisplayUserContextValue() { const contextValue = useContext(userContext); @@ -30,7 +31,7 @@ describe("UserProvider", () => { <ReduxProvider> <SnackbarProvider preventDuplicate - maxSnack={5} + maxSnack={MAX_SNACK} > <UserProvider> <LoginTrigger /> diff --git a/src/api/UserProvider.tsx b/src/api/UserProvider.tsx index a2aeb551c20d80c9c3c0185bedb2c0ff03b98527..3d39cf191e82b0189f6c21a72d550f9f4af80be6 100644 --- a/src/api/UserProvider.tsx +++ b/src/api/UserProvider.tsx @@ -1,47 +1,48 @@ -import { useCallback, useEffect, useState, type ReactNode } from "react"; +import { useCallback, useEffect, useState, ReactNode } from "react"; import { userContext } from "@ess-ics/ce-ui-common"; import { useLoginMutation, useLogoutMutation, useInfoFromUserNameQuery, useGetUserRolesQuery, - InfoFromUserNameApiResponse, + UserInfoResponse, GetUserRolesApiResponse } from "../store/deployApi"; import { getErrorState } from "../components/common/Alerts/AlertsData"; export function UserProvider({ children }: { children: ReactNode }) { - const [user, setUser] = useState<InfoFromUserNameApiResponse | undefined>( - undefined - ); + const [user, setUser] = useState<UserInfoResponse | undefined>(undefined); const [userRoles, setUserRoles] = useState< GetUserRolesApiResponse | undefined >(undefined); const [ callLogin, - { - data: loginResponse, - error: loginError, - isLoading: loginLoading, - reset: resetLogin - } + { error: loginError, isLoading: loginLoading, reset: resetLogin } ] = useLoginMutation(); const [callLogout, { isLoading: logoutLoading }] = useLogoutMutation(); - const { data: userResponse, isLoading: userLoading } = - useInfoFromUserNameQuery({}, { skip: !loginResponse }); - const { data: userRolesResponse, isLoading: userRolesLoading } = - useGetUserRolesQuery(undefined, { skip: !loginResponse }); + const { + data: userResponse, + isLoading: userLoading, + refetch: refetchUserInfo + } = useInfoFromUserNameQuery({}); + const { + data: userRolesResponse, + isLoading: userRolesLoading, + refetch: refetchUserRoles + } = useGetUserRolesQuery(undefined); const initialized = Boolean( !loginLoading || !logoutLoading || !userLoading || !userRolesLoading ); const login = useCallback( - (username: string, password: string) => { - callLogin({ login: { userName: username, password } }); + async (username: string, password: string) => { + await callLogin({ login: { userName: username, password } }); + refetchUserInfo(); + refetchUserRoles(); }, - [callLogin] + [callLogin, refetchUserInfo, refetchUserRoles] ); useEffect(() => { diff --git a/src/api/initRequestParams.ts b/src/api/initRequestParams.ts new file mode 100644 index 0000000000000000000000000000000000000000..a08a5364506238e5baba4deb1194ca0b13861ead --- /dev/null +++ b/src/api/initRequestParams.ts @@ -0,0 +1,22 @@ +import { Pagination } from "../types/common"; + +interface initRequestParamsProps { + pagination: Pagination; + filter?: string; +} + +export function initRequestParams({ + pagination, + filter +}: initRequestParamsProps) { + const requestParams = { + page: pagination.page, + limit: pagination.rows, + query: "" + }; + if (filter != null && filter) { + requestParams.query = filter; + } + + return requestParams; +} diff --git a/src/components/IOC/ChangeHostAdmin/ChangeHostAdmin.tsx b/src/components/IOC/ChangeHostAdmin/ChangeHostAdmin.tsx index b95635715baa8bb2a509412243f4464582d5f61c..d1bd7c2f4d5ae10a8e9b483051eea800e3c71c8b 100644 --- a/src/components/IOC/ChangeHostAdmin/ChangeHostAdmin.tsx +++ b/src/components/IOC/ChangeHostAdmin/ChangeHostAdmin.tsx @@ -3,8 +3,8 @@ import { useEffect, useCallback, useMemo, - type SetStateAction, - type Dispatch + SetStateAction, + Dispatch } from "react"; import { ConfirmationDialog } from "@ess-ics/ce-ui-common"; import { diff --git a/src/components/IOC/CreateIOC/CreateIOC.tsx b/src/components/IOC/CreateIOC/CreateIOC.tsx index 5a96e6fc94d3b4d0f9d1759a0eeaa5665a204a57..515d92cdffae2d5ec217a81e25f8446973237206 100644 --- a/src/components/IOC/CreateIOC/CreateIOC.tsx +++ b/src/components/IOC/CreateIOC/CreateIOC.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState, type KeyboardEvent } from "react"; +import { useEffect, useState, KeyboardEvent } from "react"; import { useNavigate } from "react-router-dom"; import { RootPaper } from "@ess-ics/ce-ui-common"; import { @@ -16,8 +16,8 @@ import { RepositoryName } from "./RepositoryName"; import { useTypingTimer } from "../../../hooks/useTypingTimer"; import { useCustomSnackbar } from "../../common/snackbar"; import { - type GitProject, - type NameResponse, + GitProject, + NameResponse, useCreateIocMutation, useLazyFetchIocByNameQuery, useLazyListProjectsQuery diff --git a/src/components/IOC/CreateIOC/RepositoryName.tsx b/src/components/IOC/CreateIOC/RepositoryName.tsx index 9e66d142218f702b8301b2b5ea941f738c78936c..e4d015a05175faa8e6f2dcf2a8d13b63fb6ef714 100644 --- a/src/components/IOC/CreateIOC/RepositoryName.tsx +++ b/src/components/IOC/CreateIOC/RepositoryName.tsx @@ -1,4 +1,4 @@ -import { useState, useCallback, type ChangeEvent } from "react"; +import { useState, useCallback, ChangeEvent } from "react"; import { Box, Stack, TextField, Typography } from "@mui/material"; import { string, func } from "prop-types"; diff --git a/src/components/IOC/IOCDeployDialog/IOCDeployDialog.tsx b/src/components/IOC/IOCDeployDialog/IOCDeployDialog.tsx index 456c653d30955adc0ae9dc69a93088a5671abe26..886a6d6b8669edf3afdf0244c3e19cfcbbd9e7da 100644 --- a/src/components/IOC/IOCDeployDialog/IOCDeployDialog.tsx +++ b/src/components/IOC/IOCDeployDialog/IOCDeployDialog.tsx @@ -24,7 +24,7 @@ import { import { getErrorState } from "../../common/Alerts/AlertsData"; import { ApiAlertError } from "../../common/Alerts/ApiAlertError"; import { useStartJobMutation } from "../../../store/enhancedApi"; -import type { ApiError, DeployIocFormDefaults } from "../../../types/common"; +import { ApiError, DeployIocFormDefaults } from "../../../types/common"; export type StartJobMutationTrigger = ReturnType<typeof useStartJobMutation>[0]; interface IOCDeployDialogProps { diff --git a/src/components/IOC/IOCDetailAdmin/IOCDetailAdmin.tsx b/src/components/IOC/IOCDetailAdmin/IOCDetailAdmin.tsx index 83f86029e360ad2d0dff9ffa4ff180915b9b5cba..3e26ded6a042513f93c3a9e0c551fced3719aee5 100644 --- a/src/components/IOC/IOCDetailAdmin/IOCDetailAdmin.tsx +++ b/src/components/IOC/IOCDetailAdmin/IOCDetailAdmin.tsx @@ -14,7 +14,7 @@ import { AccessControl } from "../../auth/AccessControl"; import { useLazyListProjectsQuery, useLazyFetchIocByNameQuery, - type IocDetails, + IocDetails, NameResponse } from "../../../store/deployApi"; import { useUpdateIocMutation } from "../../../store/enhancedApi"; diff --git a/src/components/IOC/IOCDetails/IOCDetails.tsx b/src/components/IOC/IOCDetails/IOCDetails.tsx index 9edf79c0108e8296c6b02168682f83ca8512bd89..6ae05e9220668a04e895bac7f70c813f9a67e2fc 100644 --- a/src/components/IOC/IOCDetails/IOCDetails.tsx +++ b/src/components/IOC/IOCDetails/IOCDetails.tsx @@ -9,20 +9,6 @@ interface IOCDetailsProps { getSubset: ( ioc: IocDetails ) => Record<string, string | JSX.Element | undefined> | undefined; - // getSubset: (ioc: IocDetails) => { - // Description: string | undefined; - // Revision: JSX.Element; - // "Deployed on": JSX.Element; - // }; - - // getSubset: (ioc: IocDetails) => - // | { - // "Naming service record": JSX.Element; - // Repository: JSX.Element; - // "Created by": JSX.Element; - // "IOC Service Controls": JSX.Element; - // } - // | undefined; buttons?: JSX.Element; } diff --git a/src/components/IOC/IOCLiveStatus/IOCLiveStatus.tsx b/src/components/IOC/IOCLiveStatus/IOCLiveStatus.tsx index ceae8e058232a6320fb4d8bdf916b3bce4bea178..3ca87ebface15265dace0cfdd8d9a40a7b716ab3 100644 --- a/src/components/IOC/IOCLiveStatus/IOCLiveStatus.tsx +++ b/src/components/IOC/IOCLiveStatus/IOCLiveStatus.tsx @@ -1,4 +1,4 @@ -import { useCallback, useState, type ChangeEvent } from "react"; +import { useCallback, useState, ChangeEvent } from "react"; import { Typography } from "@mui/material"; import { SimpleAccordion, diff --git a/src/components/IOC/IOCManage/IOCManage.tsx b/src/components/IOC/IOCManage/IOCManage.tsx index 715c293fdacecd4ca2913bcc26a8efca638475de..a4f8e25a5516af1a92414395efde8473fc2a74a5 100644 --- a/src/components/IOC/IOCManage/IOCManage.tsx +++ b/src/components/IOC/IOCManage/IOCManage.tsx @@ -12,7 +12,7 @@ import { IocDetails, useLazyFetchJobStatusQuery } from "../../../store/deployApi"; -import env from "../../../config/env"; +import { env } from "../../../config/env"; import { UserContext } from "../../../types/common"; export const IOCManage = ({ ioc }: { ioc: IocDetails }) => { diff --git a/src/components/IOC/IOCManage/IOCService.tsx b/src/components/IOC/IOCManage/IOCService.tsx index 5a1ac6af4cdd97365063d44a7d4d1a499cd1280a..8072be142f971c5bf726e0333fc29bf9320e76a2 100644 --- a/src/components/IOC/IOCManage/IOCService.tsx +++ b/src/components/IOC/IOCManage/IOCService.tsx @@ -11,7 +11,7 @@ import { ConfirmationDialog } from "@ess-ics/ce-ui-common"; import { AccessControl } from "../../auth/AccessControl"; import { useStartJobMutation } from "../../../store/enhancedApi"; import { ApiAlertError } from "../../common/Alerts/ApiAlertError"; -import type { IocDetails, Job } from "../../../store/deployApi"; +import { IocDetails, Job } from "../../../store/deployApi"; export function IOCService({ ioc }: { ioc: IocDetails }) { const navigate = useNavigate(); diff --git a/src/components/IOC/IOCManage/JobSection.tsx b/src/components/IOC/IOCManage/JobSection.tsx index 583b1a5588c46deecf80a777c600d4f4752c08c4..84b7e95506712301ebf7a218cc00fb2ee6986b5b 100644 --- a/src/components/IOC/IOCManage/JobSection.tsx +++ b/src/components/IOC/IOCManage/JobSection.tsx @@ -2,7 +2,7 @@ import { useEffect } from "react"; import { Stack, Typography } from "@mui/material"; import { usePagination } from "@ess-ics/ce-ui-common"; import { useListJobsQuery, IocDetails } from "../../../store/deployApi"; -import { initRequestParams } from "../../common/Helper"; +import { initRequestParams } from "../../../api/initRequestParams"; import { ROWS_PER_PAGE } from "../../../constants"; import { JobTable } from "../../Job"; diff --git a/src/components/IOC/IOCUndeployDialog/IOCUndeployDialog.tsx b/src/components/IOC/IOCUndeployDialog/IOCUndeployDialog.tsx index 327ea1baabf58d9159dcfe35450bf338e8e1a64c..2ac5215057a969fdfa624bc7ef0a0f902168033a 100644 --- a/src/components/IOC/IOCUndeployDialog/IOCUndeployDialog.tsx +++ b/src/components/IOC/IOCUndeployDialog/IOCUndeployDialog.tsx @@ -1,4 +1,4 @@ -import { type SyntheticEvent } from "react"; +import { SyntheticEvent } from "react"; import { Stack, Typography, Button } from "@mui/material"; import { Dialog } from "@ess-ics/ce-ui-common"; import { ApiAlertError } from "../../common/Alerts/ApiAlertError"; diff --git a/src/components/Job/JobTable/JobDetailsColumn.tsx b/src/components/Job/JobTable/JobDetailsColumn.tsx index 11aa15ea3c160f90f5d7a879be89afa8172fd9fd..309166581d17a1cdc0fb901f979c17589689f6cb 100644 --- a/src/components/Job/JobTable/JobDetailsColumn.tsx +++ b/src/components/Job/JobTable/JobDetailsColumn.tsx @@ -7,7 +7,6 @@ import { ACTION_TYPES } from "../JobData"; import { JobRevisionChip } from "../JobRevisionChip"; import { Job } from "../../../store/deployApi"; -// Ask johanna regarding batch jobs export const JobDetailsColumn = ({ job }: { job: Job }) => { const isBatchOperation = isBatchJob(job.action); diff --git a/src/components/Job/JobTable/JobTable.tsx b/src/components/Job/JobTable/JobTable.tsx index bc7d261c717603fa9fe2ca17add177ea3110955c..9c7f3845528e2042b81da1448ae2c2a17ff3ecfe 100644 --- a/src/components/Job/JobTable/JobTable.tsx +++ b/src/components/Job/JobTable/JobTable.tsx @@ -1,6 +1,6 @@ import { useState, useEffect } from "react"; import { Table, InternalLink } from "@ess-ics/ce-ui-common"; -import { type GridColDef } from "@mui/x-data-grid"; +import { GridColDef } from "@mui/x-data-grid"; import { JobStatusColumn } from "./JobStatusColumn"; import { JobDetailsColumn } from "./JobDetailsColumn"; import { UserAvatar } from "../../common/User/UserAvatar"; diff --git a/src/components/auth/AccessDenied/AccessDenied.tsx b/src/components/auth/AccessDenied/AccessDenied.tsx index 22f41e48a1aa12f440c8afab6f09f3d0216c62bc..7817f8ea749819cd74b3fc30daac166a42e2c5cb 100644 --- a/src/components/auth/AccessDenied/AccessDenied.tsx +++ b/src/components/auth/AccessDenied/AccessDenied.tsx @@ -1,5 +1,5 @@ import { ServerErrorPage } from "@ess-ics/ce-ui-common"; -import env from "../../../config/env"; +import { env } from "../../../config/env"; export const AccessDenied = () => { return ( diff --git a/src/components/auth/TokenRenew/TokenRenew.tsx b/src/components/auth/TokenRenew/TokenRenew.tsx index 0353c6c6e34338b95661ae025b129124ba36447a..f40eab66a4c460dfb15fb882d93623fe0b16519a 100644 --- a/src/components/auth/TokenRenew/TokenRenew.tsx +++ b/src/components/auth/TokenRenew/TokenRenew.tsx @@ -1,6 +1,6 @@ import { useContext, useEffect } from "react"; import { userContext } from "@ess-ics/ce-ui-common"; -import env from "../../../config/env"; +import { env } from "../../../config/env"; import { useTokenRenewMutation } from "../../../store/deployApi"; import { UserContext } from "../../../types/common"; diff --git a/src/components/common/Alerts/AlertsData.ts b/src/components/common/Alerts/AlertsData.ts index b792fbebd5c9fcb473bd2e49874ddf883fd6c4be..1179fb87a8746e2f98180462a6a1573e9ba52b03 100644 --- a/src/components/common/Alerts/AlertsData.ts +++ b/src/components/common/Alerts/AlertsData.ts @@ -8,12 +8,7 @@ interface BrowserError { } const isBrowserError = ( - error: - | BrowserError - | FetchBaseQueryError - | SerializedError - | BrowserError - | unknown + error: BrowserError | FetchBaseQueryError | SerializedError | unknown ) => { return ( error != null && @@ -69,6 +64,10 @@ export const getErrorState = ( status: browserError.status }; } + return { + message: "Unknown Error", + status: 0 + }; } return { message: "", diff --git a/src/components/common/Helper.tsx b/src/components/common/Helper.tsx deleted file mode 100644 index 2b640b7ef407690088427c57afe467745afb31e3..0000000000000000000000000000000000000000 --- a/src/components/common/Helper.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import env from "../../config/env"; -import { Pagination } from "../../types/common"; - -function applicationSubTitle() { - const title = `${env.ENVIRONMENT_TITLE}`; - - if (title && title !== "undefined") { - return " - " + title; - } - - return ""; -} - -export function applicationTitle(title: string = "") { - return [`CE deploy & monitor ${applicationSubTitle()}`, title].join(" / "); -} -interface initRequestParamsProps { - pagination: Pagination; - filter?: string; -} - -export function initRequestParams({ - pagination, - filter -}: initRequestParamsProps) { - const requestParams = { - page: pagination.page, - limit: pagination.rows, - query: "" - }; - if (filter != null && filter) { - requestParams.query = filter; - } - - return requestParams; -} diff --git a/src/components/common/Loki/LokiPanel.tsx b/src/components/common/Loki/LokiPanel.tsx index 2718bb19b7ca2662dbd439525a0137e574181e13..4404827bd399b55655451484897b29da5240a363 100644 --- a/src/components/common/Loki/LokiPanel.tsx +++ b/src/components/common/Loki/LokiPanel.tsx @@ -3,16 +3,11 @@ import { useEffect, useCallback, useMemo, - type Dispatch, - type SetStateAction + Dispatch, + SetStateAction } from "react"; -import { - Stack, - LinearProgress, - Box, - type SelectChangeEvent -} from "@mui/material"; -import { closeSnackbar } from "notistack"; +import { Stack, LinearProgress, Box, SelectChangeEvent } from "@mui/material"; +import { SnackbarKey, closeSnackbar } from "notistack"; import { formatDateAndTime } from "@ess-ics/ce-ui-common"; import Convert from "ansi-to-html"; import { @@ -27,7 +22,6 @@ import { LogStreamConsoleDialog } from "../LogStream/LogStreamConsoleDialog"; import { TimeRange } from "../Inputs/TimeRange"; import { PopoutButton } from "../Buttons/PopoutButton"; import { useCustomSnackbar } from "../snackbar/Snackbar"; -import type { SnackbarKey } from "notistack"; const TIME_RANGE_VALUES = [ { diff --git a/src/components/common/Status/StatusBadge.tsx b/src/components/common/Status/StatusBadge.tsx index 3cedb480361a4cae56d7b85a2db5431757ec689e..34394e5e6e6a6e92494ac389b5b23902fbf6227d 100644 --- a/src/components/common/Status/StatusBadge.tsx +++ b/src/components/common/Status/StatusBadge.tsx @@ -1,6 +1,6 @@ -import { type ReactNode } from "react"; +import { ReactNode } from "react"; import { string, object, arrayOf, oneOfType, node } from "prop-types"; -import { Stack, useTheme } from "@mui/material"; +import { Stack } from "@mui/material"; import WarningAmberIcon from "@mui/icons-material/WarningAmber"; import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline"; import { STATUS } from "./StatusData"; @@ -24,7 +24,6 @@ interface StatusBadgeProps { } export const StatusBadge = ({ status, children }: StatusBadgeProps) => { - const theme = useTheme(); const showWarning = status === STATUS.warning || status === STATUS.inactiveWarning || @@ -40,12 +39,12 @@ export const StatusBadge = ({ status, children }: StatusBadgeProps) => { {children} {showWarning && ( <WarningAmberIcon - sx={{ fill: theme.palette.warning.main, ...commonStyles }} + sx={{ fill: (theme) => theme.palette.warning.main, ...commonStyles }} /> )} {showError && ( <ErrorOutlineIcon - sx={{ fill: theme.palette.error.main, ...commonStyles }} + sx={{ fill: (theme) => theme.palette.error.main, ...commonStyles }} /> )} </Stack> diff --git a/src/components/common/User/UserOperationList.tsx b/src/components/common/User/UserOperationList.tsx index 51c868fdf39dce3772295383ea5f9bc0e28d4bd4..7b8e252af851da8ad3e9beb13a53a84e5e2b8484 100644 --- a/src/components/common/User/UserOperationList.tsx +++ b/src/components/common/User/UserOperationList.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect } from "react"; import { Typography } from "@mui/material"; import { usePagination } from "@ess-ics/ce-ui-common"; -import { initRequestParams } from "../Helper"; +import { initRequestParams } from "../../../api/initRequestParams"; import { JobTable } from "../../Job"; import { DEFAULT_POLLING_INTERVAL_MILLIS, @@ -10,7 +10,11 @@ import { import { useLazyListJobsQuery } from "../../../store/deployApi"; import { OnPageParams } from "../../../types/common"; -export function UserOperationList({ userName }: { userName?: string }) { +interface UserOperationListProps { + userName?: string; +} + +export function UserOperationList({ userName }: UserOperationListProps) { const [getJobs, { data: jobs, isLoading }] = useLazyListJobsQuery({ pollingInterval: DEFAULT_POLLING_INTERVAL_MILLIS }); diff --git a/src/components/common/applicationTitle.ts b/src/components/common/applicationTitle.ts new file mode 100644 index 0000000000000000000000000000000000000000..b2861ff4f5b1bdab799fbecf7113c077b856385f --- /dev/null +++ b/src/components/common/applicationTitle.ts @@ -0,0 +1,15 @@ +import { env } from "../../config/env"; + +function applicationSubTitle() { + const title = `${env.ENVIRONMENT_TITLE}`; + + if (title && title !== "undefined") { + return " - " + title; + } + + return ""; +} + +export function applicationTitle(title: string = "") { + return [`CE deploy & monitor ${applicationSubTitle()}`, title].join(" / "); +} diff --git a/src/components/common/snackbar/Snackbar.tsx b/src/components/common/snackbar/Snackbar.tsx index 3c33e5713520f27fef80d3346874f38700740b1b..2709355fbffdb6ba81fc1ba309145498ad75a6e0 100644 --- a/src/components/common/snackbar/Snackbar.tsx +++ b/src/components/common/snackbar/Snackbar.tsx @@ -1,17 +1,8 @@ import { useCallback } from "react"; import { useSnackbar, SnackbarKey } from "notistack"; -import { Button, styled } from "@mui/material"; +import { SnackbarButton } from "./SnackbarButton"; -// eslint-disable-next-line react-refresh/only-export-components -const SnackbarButton = styled(Button)(() => ({ - color: "#f0f0f0", - borderColor: "#f0f0f0", - "&:hover": { - backgroundColor: "#8d8d8d", - borderColor: "#8d8d8d", - boxShadow: "none" - } -})); +const AUTO_HIDE_DURATION = 3000; export function useCustomSnackbar() { const { enqueueSnackbar, closeSnackbar } = useSnackbar(); @@ -42,7 +33,7 @@ export function useCustomSnackbar() { (message: string) => { return enqueueSnackbar(message, { variant: "success", - autoHideDuration: 3000 + autoHideDuration: AUTO_HIDE_DURATION }); }, [enqueueSnackbar] @@ -52,7 +43,7 @@ export function useCustomSnackbar() { (message: string) => { return enqueueSnackbar(message, { variant: "warning", - autoHideDuration: 3000 + autoHideDuration: AUTO_HIDE_DURATION }); }, [enqueueSnackbar] diff --git a/src/components/common/snackbar/SnackbarButton.tsx b/src/components/common/snackbar/SnackbarButton.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ed36006feb9439b1a4d6364e89044250cb078a54 --- /dev/null +++ b/src/components/common/snackbar/SnackbarButton.tsx @@ -0,0 +1,11 @@ +import { Button, styled } from "@mui/material"; + +export const SnackbarButton = styled(Button)(() => ({ + color: "#f0f0f0", + borderColor: "#f0f0f0", + "&:hover": { + backgroundColor: "#8d8d8d", + borderColor: "#8d8d8d", + boxShadow: "none" + } +})); diff --git a/src/components/navigation/NavigationMenu/LoginControls.tsx b/src/components/navigation/NavigationMenu/LoginControls.tsx index ac096a18cdf663dd8de4192af8ec1a62067aa1ee..d8997881f4fa5aafc744b36a6aaee4db2f583141 100644 --- a/src/components/navigation/NavigationMenu/LoginControls.tsx +++ b/src/components/navigation/NavigationMenu/LoginControls.tsx @@ -11,7 +11,11 @@ import { import { useNavigate } from "react-router-dom"; import { User, UserContext } from "../../../types/common"; -export const ProfileMenu = ({ user }: { user: User }) => { +interface ProfileMenuProps { + user: User; +} + +export const ProfileMenu = ({ user }: ProfileMenuProps) => { const { userRoles, logout } = useContext<UserContext>(userContext); const navigate = useNavigate(); diff --git a/src/components/navigation/NavigationMenu/NavigationMenu.tsx b/src/components/navigation/NavigationMenu/NavigationMenu.tsx index 3194e11745f7c5a7152c9d06050a1bca819bc4d8..2cb093bc4b69c45c7f1aaa44b2512b11cec5fcf5 100644 --- a/src/components/navigation/NavigationMenu/NavigationMenu.tsx +++ b/src/components/navigation/NavigationMenu/NavigationMenu.tsx @@ -26,7 +26,7 @@ import { useNavigate } from "react-router"; import { Link } from "react-router-dom"; import { LoginControls } from "./LoginControls"; import { CreateIOCButton } from "./CreateIOCButton"; -import { applicationTitle } from "../../common/Helper"; +import { applicationTitle } from "../../common/applicationTitle"; import { CCCEControlSymbol } from "../../../icons/CCCEControlSymbol"; import { theme } from "../../../style/Theme"; import { useGetCurrentModeQuery } from "../../../store/deployApi"; @@ -62,13 +62,12 @@ function MenuListItem({ url, icon, text, tooltip }: MenuListItemProps) { ); } -function MenuListItems({ - drawerOpen, - menuItems -}: { +interface MenuListItemsProps { drawerOpen: boolean; menuItems: typeof menuItemsAll; -}) { +} + +function MenuListItems({ drawerOpen, menuItems }: MenuListItemsProps) { const menuItemsKeys = useUniqueKeys(menuItems); return ( <Box sx={{ paddingTop: 3 }}> @@ -89,11 +88,13 @@ function MenuListItems({ </Box> ); } + const makeLink = (text: string, url: string, icon: ReactElement) => ({ text, url, icon }); + const menuItemsAll = [ makeLink("Records", "/records", <SettingsInputComponent />), makeLink( @@ -108,7 +109,11 @@ const menuItemsAll = [ makeLink("Log", "/jobs", <Assignment />) ]; -export const NavigationMenu = ({ children }: { children: ReactNode }) => { +interface NavigationMenuProps { + children: ReactNode; +} + +export const NavigationMenu = ({ children }: NavigationMenuProps) => { const [drawerOpen, setDrawerOpen] = useState(false); const navigate = useNavigate(); const goHome = () => { diff --git a/src/components/navigation/NotFoundView/NotFoundView.tsx b/src/components/navigation/NotFoundView/NotFoundView.tsx index 9c35d3435b1b4b6104e36aba0d79ffc22fbb809f..6343f19e1bc59d146e5cc7c00b9cc716d125b8fb 100644 --- a/src/components/navigation/NotFoundView/NotFoundView.tsx +++ b/src/components/navigation/NotFoundView/NotFoundView.tsx @@ -8,7 +8,7 @@ import { SidewaysMascot, VerticalMascot } from "@ess-ics/ce-ui-common"; -import env from "../../../config/env"; +import { env } from "../../../config/env"; interface NotFoundProps { /** String containing message of page not found. Otherwise defaults to a generic "Page Not Found" message */ diff --git a/src/components/records/RecordBadge.tsx b/src/components/records/RecordBadge.tsx index b515584407db8c17639f0e891dba1d1aa5485312..2fb9a109c34bc47d007af2ecf60043f5cdc5db18 100644 --- a/src/components/records/RecordBadge.tsx +++ b/src/components/records/RecordBadge.tsx @@ -1,14 +1,12 @@ import { IconBadge, InternalLink } from "@ess-ics/ce-ui-common"; -import { type SxProps } from "@mui/material"; import { RecordStatusIcon } from "./RecordIcons"; import { Record } from "../../store/deployApi"; interface RecordBadgeProps { record: Record; - sx?: SxProps; } -export function RecordBadge({ record, sx }: RecordBadgeProps) { +export function RecordBadge({ record }: RecordBadgeProps) { return ( <IconBadge icon={<RecordStatusIcon record={record} />} @@ -21,7 +19,6 @@ export function RecordBadge({ record, sx }: RecordBadgeProps) { {record?.iocName} </InternalLink> } - sx={sx} /> ); } diff --git a/src/components/records/RecordHostLink.tsx b/src/components/records/RecordHostLink.tsx index 7d004aac6bc5a5e6980df0b1ae19aa996f95e5a1..898cc090ef97556e74850ff10dfc35f7cdd980b6 100644 --- a/src/components/records/RecordHostLink.tsx +++ b/src/components/records/RecordHostLink.tsx @@ -5,7 +5,7 @@ import { useFindNetBoxHostByFqdnQuery } from "../../store/deployApi"; -function createHostLink(hostInfo: HostInfoWithId, fqdn?: string) { +function createHostLink(hostInfo?: HostInfoWithId, fqdn?: string) { // if the fqdn field is empty for some reason if (fqdn === null || fqdn?.trim() === "") { return <EmptyValue />; @@ -27,7 +27,11 @@ function createHostLink(hostInfo: HostInfoWithId, fqdn?: string) { return <Typography>{fqdn}</Typography>; } -export const RecordHostLink = ({ fqdn }: { fqdn?: string }) => { +interface RecordHostLinkProps { + fqdn?: string; +} + +export const RecordHostLink = ({ fqdn }: RecordHostLinkProps) => { const { data: hostInfo, isLoading } = useFindNetBoxHostByFqdnQuery( { fqdn: fqdn ?? "" }, { skip: !fqdn } @@ -40,11 +44,7 @@ export const RecordHostLink = ({ fqdn }: { fqdn?: string }) => { justifyContent="center" alignItems="center" > - {isLoading || !hostInfo ? ( - <Skeleton width="100%" /> - ) : ( - createHostLink(hostInfo, fqdn) - )} + {isLoading ? <Skeleton width="100%" /> : createHostLink(hostInfo, fqdn)} </Grid> ); }; diff --git a/src/components/records/RecordIcons.tsx b/src/components/records/RecordIcons.tsx index 6ea8cf4e973fb17fd9e28381fe5ebc598f8ffd8f..c99bad2e284da7e030360b971ef9941a03f3d131 100644 --- a/src/components/records/RecordIcons.tsx +++ b/src/components/records/RecordIcons.tsx @@ -1,6 +1,6 @@ -import { type SvgIconTypeMap, useTheme } from "@mui/material"; +import { SvgIconTypeMap, useTheme } from "@mui/material"; import { LabeledIcon } from "@ess-ics/ce-ui-common"; -import { type OverridableComponent } from "@mui/material/OverridableComponent"; +import { OverridableComponent } from "@mui/material/OverridableComponent"; import { Brightness1, RadioButtonUnchecked, @@ -8,7 +8,11 @@ import { } from "@mui/icons-material"; import { Record as ApiRecord } from "../../store/deployApi"; -export function RecordStatusIcon({ record }: { record: ApiRecord }) { +interface RecordStatusIconProps { + record: ApiRecord; +} + +export function RecordStatusIcon({ record }: RecordStatusIconProps) { const theme = useTheme(); const { pvStatus } = record; @@ -30,13 +34,13 @@ export function RecordStatusIcon({ record }: { record: ApiRecord }) { title: "Inactive", icon: RadioButtonUnchecked }, - null: { + unknown: { title: "Unknown", icon: HelpOutline } }; - const state = pvStatus ? pvStatus.toLowerCase() : "null"; + const state = pvStatus ? pvStatus.toLowerCase() : "unknown"; const iconStyle = { fill: theme.palette.status.icons }; const iconTitle = iconConfig[state].title; const statusIcon = iconConfig[state].icon; diff --git a/src/components/records/RecordSearch.tsx b/src/components/records/RecordSearch.tsx index 446afd0622a87b5058ce339400cdd9f1b71144ee..fc302db8f726401acff911f08ff179158649d449 100644 --- a/src/components/records/RecordSearch.tsx +++ b/src/components/records/RecordSearch.tsx @@ -3,7 +3,7 @@ import { useSearchParams } from "react-router-dom"; import { Grid, Tabs, Tab } from "@mui/material"; import { usePagination, SearchBar } from "@ess-ics/ce-ui-common"; import { RecordTable } from "./RecordTable"; -import { initRequestParams } from "../common/Helper"; +import { initRequestParams } from "../../api/initRequestParams"; import { ROWS_PER_PAGE } from "../../constants"; import { useLazyFindAllRecordsQuery } from "../../store/deployApi"; import { Pagination } from "../../types/common"; @@ -19,7 +19,7 @@ export function RecordSearch({ rowType, isExpanded }: RecordSearchProps) { - const [getRecords, { data: records, isFetching, isSuccess: dataReady }] = + const [getRecords, { data: records, isFetching }] = useLazyFindAllRecordsQuery(); const [searchParams, setSearchParams] = useSearchParams({ query: "" }); @@ -101,11 +101,11 @@ export function RecordSearch({ <SearchBar search={setSearch} query={searchParams.get("query")} - loading={isFetching || !dataReady} + loading={isFetching} > <RecordTable records={records} - loading={isFetching || !dataReady} + loading={isFetching} rowType={rowType} pagination={pagination} onPage={onPage} diff --git a/src/components/records/RecordTable.tsx b/src/components/records/RecordTable.tsx index 2f0d3709845d2b98e9dfd1b09e76b81f90498394..960a74da0df243909ec71841d0b96de99bc3e8cf 100644 --- a/src/components/records/RecordTable.tsx +++ b/src/components/records/RecordTable.tsx @@ -8,7 +8,7 @@ import { Grid } from "@mui/material"; import { RecordStatusIcon } from "./RecordIcons"; import { RecordHostLink } from "./RecordHostLink"; import { Pagination } from "../../types/common"; -import type { +import { PagedRecordResponse, Record as ApiRecord } from "../../store/deployApi"; diff --git a/src/config/env.ts b/src/config/env.ts index c21e0d7911a853e374810e25b44fb8a2e5ace903..32ace0b46b26e48f6825a692bc24ce9594ce2ffb 100644 --- a/src/config/env.ts +++ b/src/config/env.ts @@ -1,12 +1,11 @@ -const env = { +export const env = { SERVER_ADDRESS: window.SERVER_ADDRESS, ENVIRONMENT_TITLE: window.ENVIRONMENT_TITLE, API_BASE_ENDPOINT: window.API_BASE_ENDPOINT, TOKEN_RENEW_INTERVAL: window.TOKEN_RENEW_INTERVAL, FRONTEND_VERSION: window.FRONTEND_VERSION, + VITE_APP_MUI_PRO_LICENSE_KEY: import.meta.env.VITE_APP_MUI_PRO_LICENSE_KEY, SUPPORT_URL: window.SUPPORT_URL, NETBOX_ADDRESS: window.NETBOX_ADDRESS, NAMING_ADDRESS: window.NAMING_ADDRESS }; - -export default env; diff --git a/src/constants/index.ts b/src/constants/index.ts index 26ae5f5ab0a6e590edc6a267fa03172e6b2e80a6..ea136b2d19694af213815341ee8171e65264ead9 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,2 +1,3 @@ export const ROWS_PER_PAGE = [20, 50]; export const DEFAULT_POLLING_INTERVAL_MILLIS = 3000; +export const MAX_SNACK = 5; diff --git a/src/hooks/useTypingTimer.tsx b/src/hooks/useTypingTimer.tsx index eb680237f4889efd5a53329369fff2f26a1a73bc..0c78ce16e21fe04d93b4eb085fac958b0e988718 100644 --- a/src/hooks/useTypingTimer.tsx +++ b/src/hooks/useTypingTimer.tsx @@ -1,4 +1,4 @@ -import { useState, type KeyboardEvent } from "react"; +import { useState, KeyboardEvent } from "react"; interface UseTypingTimerReturn { value: string; diff --git a/src/icons/BatchUndeploySymbol.tsx b/src/icons/BatchUndeploySymbol.tsx index 3ad1d693442b12dbd151bc4221fe145175b5a85f..caa278e2fd16a5aac86344d7c4cf80caed960187 100644 --- a/src/icons/BatchUndeploySymbol.tsx +++ b/src/icons/BatchUndeploySymbol.tsx @@ -1,4 +1,4 @@ -import { type ComponentProps } from "react"; +import { ComponentProps } from "react"; import BatchUndeployIconSvg from "./resources/batch/batch_undeploy_icon.svg?react"; import { BatchUndeployIcon } from "../components/Job/JobIcons"; diff --git a/src/index.tsx b/src/index.tsx index b9170974d28b5828c70b1060d2019e9786ee2584..9c102b448fb5a46dbb3c83d862c3264680861d83 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,20 +1,20 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import { LicenseInfo } from "@mui/x-license-pro"; +import { AppErrorBoundary } from "@ess-ics/ce-ui-common"; +import { env } from "./config/env"; import App from "./App"; // Set license key -LicenseInfo.setLicenseKey(import.meta.env.VITE_APP_MUI_PRO_LICENSE_KEY); +LicenseInfo.setLicenseKey(env.VITE_APP_MUI_PRO_LICENSE_KEY ?? ""); -const container = document.getElementById("root"); -if (container) { - const root = createRoot(container); +// Render app +const root = createRoot(document.getElementById("root") as HTMLElement); - root.render( - <StrictMode> +root.render( + <StrictMode> + <AppErrorBoundary supportHref={window.SUPPORT_URL}> <App /> - </StrictMode> - ); -} else { - throw new Error("No root element found"); -} + </AppErrorBoundary> + </StrictMode> +); diff --git a/src/mocks/AppHarness.tsx b/src/mocks/AppHarness.tsx index e44806ec46ff7568ccb6c14414c72e45a8442543..88d0beebbfdd717ed267f13eafde1b37796f1dd9 100644 --- a/src/mocks/AppHarness.tsx +++ b/src/mocks/AppHarness.tsx @@ -1,4 +1,4 @@ -import { type ReactNode } from "react"; +import { ReactNode } from "react"; import { SnackbarProvider } from "notistack"; import { Container, CssBaseline, StyledEngineProvider } from "@mui/material"; import { ThemeProvider } from "@mui/material/styles"; @@ -9,6 +9,7 @@ import { UserProvider } from "../api/UserProvider"; import { NavigationMenu } from "../components/navigation/NavigationMenu"; import { ReduxProvider } from "../store/ReduxProvider"; import { User } from "../types/common"; +import { MAX_SNACK } from "../constants"; interface RouterHarnessProps { children: ReactNode; @@ -61,7 +62,7 @@ export function AppHarness({ <ReduxProvider> <SnackbarProvider preventDuplicate - maxSnack={5} + maxSnack={MAX_SNACK} > <RouterHarness initialHistory={initialHistory}> <SelectedUserProvider> diff --git a/src/mocks/mockAPI.ts b/src/mocks/mockAPI.ts index 9a003197a802a610a52245af90cfdc543b5b1448..61425f71ee29a0e5c8aa005b95a99c9ca2eb6953 100644 --- a/src/mocks/mockAPI.ts +++ b/src/mocks/mockAPI.ts @@ -93,6 +93,7 @@ function logout() { function isLoggedIn(req: any) { const { cookies } = req; + console.log({ cookies }); if (cookies) { return Boolean(cookies["ce-deploy-auth"]); } else { diff --git a/src/stories/components/common/job/JobTable.stories.tsx b/src/stories/components/common/job/JobTable.stories.tsx index 98f2a2e1957f94fbd7f92ff6169490762dbfffb5..9a2d5c53979a9151688029816f9b4ad19f99cd73 100644 --- a/src/stories/components/common/job/JobTable.stories.tsx +++ b/src/stories/components/common/job/JobTable.stories.tsx @@ -1,4 +1,5 @@ import { Box } from "@mui/material"; +import { Meta, StoryFn } from "@storybook/react"; import { RouterHarness } from "../../../../mocks/AppHarness"; import { JobTable } from "../../../../components/Job/JobTable"; import operationList from "../../../../mocks/fixtures/Jobs.json"; @@ -7,7 +8,6 @@ import { paginationNoResults } from "../../../utils/common-args"; import { Job } from "../../../../store/deployApi"; -import type { Meta, StoryFn } from "@storybook/react"; export default { title: "Jobs/JobTable", diff --git a/global.d.ts b/src/types/index.d.ts similarity index 100% rename from global.d.ts rename to src/types/index.d.ts diff --git a/declaration.d.ts b/src/types/typings.d.ts similarity index 77% rename from declaration.d.ts rename to src/types/typings.d.ts index ff05c729be798297ab4b2e8883ab756ba71d6fee..1e5e549bfc947a84c1b658ec42b98992cb04e9a5 100644 --- a/declaration.d.ts +++ b/src/types/typings.d.ts @@ -1,3 +1,4 @@ +declare module "@ess-ics/ce-ui-common"; declare module "*.svg?react" { const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>; diff --git a/src/typings.d.ts b/src/typings.d.ts deleted file mode 100644 index 0a50ac473539e7bfca7958e622f2a7355ccbe3ce..0000000000000000000000000000000000000000 --- a/src/typings.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -declare module "@ess-ics/ce-ui-common"; -declare module "*.svg" { - import { FunctionComponent, SVGAttributes } from "react"; - - export const ReactComponent: FunctionComponent< - Element<SVGAttributes> & { title?: string } - >; - const content: string; - export default content; -} diff --git a/src/views/IOC/CreateIOCView.tsx b/src/views/IOC/CreateIOCView.tsx index 37d4d4918b8a3de0a6540506a1946bfa6d099f2d..b895b6e1c21e59719d2bcbcc9b6bcb97046bdcd7 100644 --- a/src/views/IOC/CreateIOCView.tsx +++ b/src/views/IOC/CreateIOCView.tsx @@ -1,6 +1,6 @@ import { GlobalAppBarContext } from "@ess-ics/ce-ui-common"; import { useContext, useEffect } from "react"; -import { applicationTitle } from "../../components/common/Helper"; +import { applicationTitle } from "../../components/common/applicationTitle"; import { CreateIOC } from "../../components/IOC/CreateIOC"; import { GlobalAppBarContext as GlobalAppBarContextType } from "../../types/common"; diff --git a/src/views/IOC/IOCDetailsContainer.tsx b/src/views/IOC/IOCDetailsContainer.tsx index 38bfccdfe8131d6d427d3e5a5010b56ca62c64e0..057e7e09606efc456f17c249d31944656a987c0e 100644 --- a/src/views/IOC/IOCDetailsContainer.tsx +++ b/src/views/IOC/IOCDetailsContainer.tsx @@ -8,13 +8,17 @@ import { ApiAlertError } from "../../components/common/Alerts/ApiAlertError"; const IOC_POLL_INTERVAL = 5000; -export function IOCDetailsContainer({ id }: { id?: string }) { +interface IOCDetailsContainerProps { + id?: string; +} + +export function IOCDetailsContainer({ id }: IOCDetailsContainerProps) { const { data: ioc, isLoading, error } = useGetIocQuery( - { iocId: Number(id) || 0 }, + { iocId: Number(id) }, { skip: !id, pollingInterval: IOC_POLL_INTERVAL } ); diff --git a/src/views/IOC/IOCDetailsView.tsx b/src/views/IOC/IOCDetailsView.tsx index 80df78afea8f89afd7b79c3f9da2a0a473e71c6f..79916a6da6931899732508f7d8edbf19e751e361 100644 --- a/src/views/IOC/IOCDetailsView.tsx +++ b/src/views/IOC/IOCDetailsView.tsx @@ -10,7 +10,7 @@ import { import { IOCLiveStatus } from "../../components/IOC/IOCLiveStatus"; import { IOCManage } from "../../components/IOC/IOCManage"; import { IOCAdmin } from "../../components/IOC/IOCAdmin"; -import { applicationTitle } from "../../components/common/Helper"; +import { applicationTitle } from "../../components/common/applicationTitle"; import { GlobalAppBarContext } from "../../types/common"; import { IocDetails } from "../../store/deployApi"; diff --git a/src/views/IOC/IOCListView.tsx b/src/views/IOC/IOCListView.tsx index b439afcd21a2d46a4dc7d1ac35392d670a4dc4dc..9ba72287eb36ab1aac08dcc3dbbe792f8bc06c2a 100644 --- a/src/views/IOC/IOCListView.tsx +++ b/src/views/IOC/IOCListView.tsx @@ -8,10 +8,8 @@ import { import { useSearchParams } from "react-router-dom"; import { Container, Grid, Tabs, Tab } from "@mui/material"; import { useLazyListIocsQuery, ListIocsApiArg } from "../../store/deployApi"; -import { - applicationTitle, - initRequestParams -} from "../../components/common/Helper"; +import { applicationTitle } from "../../components/common/applicationTitle"; +import { initRequestParams } from "../../api/initRequestParams"; import { GlobalAppBarContext, OnPageParams } from "../../types/common"; import { ApiAlertError } from "../../components/common/Alerts/ApiAlertError"; import { IOCTable } from "../../components/IOC/IOCTable"; diff --git a/src/views/UserPage/UserPageView.tsx b/src/views/UserPage/UserPageView.tsx index 566425d97b56999d2bfef579f2e150e8262a72bb..bd1a6eca2380456a78504194925224f593c10161 100644 --- a/src/views/UserPage/UserPageView.tsx +++ b/src/views/UserPage/UserPageView.tsx @@ -1,7 +1,7 @@ import { useContext, useEffect } from "react"; import { Grid } from "@mui/material"; import { GlobalAppBarContext } from "@ess-ics/ce-ui-common"; -import { applicationTitle } from "../../components/common/Helper"; +import { applicationTitle } from "../../components/common/applicationTitle"; import { UserProfile } from "../../components/common/User/UserProfile"; import { UserOperationList } from "../../components/common/User/UserOperationList"; import { UserInfoResponse } from "../../store/deployApi"; diff --git a/src/views/help/HelpView.tsx b/src/views/help/HelpView.tsx index dab63530710fe2de76b61d666612a2e59eb8dea2..5327ec5117b7d78e446b1447e7ad72a45bf39d57 100644 --- a/src/views/help/HelpView.tsx +++ b/src/views/help/HelpView.tsx @@ -1,8 +1,8 @@ import { useContext, useEffect } from "react"; import { RootPaper, Help, GlobalAppBarContext } from "@ess-ics/ce-ui-common"; import { Stack, Typography } from "@mui/material"; -import { applicationTitle } from "../../components/common/Helper"; -import env from "../../config/env"; +import { applicationTitle } from "../../components/common/applicationTitle"; +import { env } from "../../config/env"; import { GlobalAppBarContext as GlobalAppBarContextType } from "../../types/common"; export function HelpView() { diff --git a/src/views/host/HostListView.tsx b/src/views/host/HostListView.tsx index 50a416b0d16c9355c2613ac251038bc0cc119e3a..67bf367e44d632c3a145d127552411f39b23e137 100644 --- a/src/views/host/HostListView.tsx +++ b/src/views/host/HostListView.tsx @@ -8,12 +8,10 @@ import { } from "@ess-ics/ce-ui-common"; import { useSearchParams } from "react-router-dom"; import { HostTable } from "../../components/host/HostTable"; -import { - applicationTitle, - initRequestParams -} from "../../components/common/Helper"; +import { applicationTitle } from "../../components/common/applicationTitle"; +import { initRequestParams } from "../../api/initRequestParams"; import { ROWS_PER_PAGE } from "../../constants"; -import { useLazyListHostsQuery } from "../../store/deployApi"; +import { ListHostsApiArg, useLazyListHostsQuery } from "../../store/deployApi"; import { GlobalAppBarContext as GlobalAppBarContextType, OnPageParams @@ -28,9 +26,8 @@ export function HostListView() { const [searchParams, setSearchParams] = useSearchParams({ query: "" }); const [tabIndex, setTabIndex] = useState(0); - const [hostFilter, setHostFilter] = useState< - "ALL" | "IOCS_DEPLOYED" | "NO_IOCS" | "OWN" - >("ALL"); + const [hostFilter, setHostFilter] = + useState<ListHostsApiArg["filter"]>("ALL"); const handleTabChange = (tab: number) => { if (tab === 0) { diff --git a/src/views/host/details/HostDetailsContainer.tsx b/src/views/host/details/HostDetailsContainer.tsx index be22b0604b8da2304f6be4004b80d3a4738c58c7..ed65825268694ce950cf955a1320fd0fe8abc800 100644 --- a/src/views/host/details/HostDetailsContainer.tsx +++ b/src/views/host/details/HostDetailsContainer.tsx @@ -8,7 +8,11 @@ import { } from "../../../store/deployApi"; import { getErrorState } from "../../../components/common/Alerts/AlertsData"; -export function HostDetailsContainer({ hostId }: { hostId?: string }) { +interface HostDetailsContainerProps { + hostId?: string; +} + +export function HostDetailsContainer({ hostId }: HostDetailsContainerProps) { const { data: host, error: fetchError } = useFindNetBoxHostByHostIdQuery( { hostId: hostId ?? "" @@ -21,6 +25,7 @@ export function HostDetailsContainer({ hostId }: { hostId?: string }) { }, { skip: !hostId } ); + const { status, message } = getErrorState(fetchError || alertError); if (status === "404" || status === 404) { diff --git a/src/views/host/details/HostDetailsView.tsx b/src/views/host/details/HostDetailsView.tsx index d01286c1a2410c212d06057e5bd49e74052a7c68..1db71268fdf0d3a451136852e9340d1e131fe221 100644 --- a/src/views/host/details/HostDetailsView.tsx +++ b/src/views/host/details/HostDetailsView.tsx @@ -13,10 +13,10 @@ import { HostDetailsTable } from "./HostDetailsTable"; import { HostJobsSection } from "./HostJobsSection"; import { HostIocSection } from "./HostIocSection"; import { LokiPanel } from "../../../components/common/Loki/LokiPanel"; -import { applicationTitle } from "../../../components/common/Helper"; +import { applicationTitle } from "../../../components/common/applicationTitle"; import { AccessControl } from "../../../components/auth/AccessControl"; import { HostStatus } from "../../../components/host/HostStatus"; -import env from "../../../config/env"; +import { env } from "../../../config/env"; import { HostAlertResponse, HostInfoWithId } from "../../../store/deployApi"; import { GlobalAppBarContext as GlobalAppBarContextType } from "../../../types/common"; diff --git a/src/views/host/details/HostIocSection.tsx b/src/views/host/details/HostIocSection.tsx index 9e0547b0a0167b50b91bd04df89719647ee5d9d1..d70ef5a088ac4d9576a4fc42b8c1b8eb2e67a3c2 100644 --- a/src/views/host/details/HostIocSection.tsx +++ b/src/views/host/details/HostIocSection.tsx @@ -3,7 +3,7 @@ import { string } from "prop-types"; import { Typography } from "@mui/material"; import { usePagination } from "@ess-ics/ce-ui-common"; import { IOCTable } from "../../../components/IOC/IOCTable"; -import { initRequestParams } from "../../../components/common/Helper"; +import { initRequestParams } from "../../../api/initRequestParams"; import { ROWS_PER_PAGE } from "../../../constants"; import { useLazyFindAssociatedIocsByHostIdQuery } from "../../../store/deployApi"; import { OnPageParams } from "../../../types/common"; diff --git a/src/views/jobs/JobDetailsContainer.tsx b/src/views/jobs/JobDetailsContainer.tsx index c4cee54c8670feb53792c33ef53bf9b501bdb890..981d45c457a240fcf7c6a62d9415aecdf2cbc7a6 100644 --- a/src/views/jobs/JobDetailsContainer.tsx +++ b/src/views/jobs/JobDetailsContainer.tsx @@ -15,7 +15,7 @@ export function JobDetailsContainer({ id }: { id?: string }) { isLoading, error: jobError } = useFetchJobQuery( - { jobId: Number(id) ?? 0 }, + { jobId: Number(id) }, { skip: !id, pollingInterval: !jobFinished ? POLL_DEPLOYMENT_INTERVAL : undefined diff --git a/src/views/jobs/JobDetailsView.tsx b/src/views/jobs/JobDetailsView.tsx index bc23194b5b2679b91e40977641f224c92508c6d1..0e581ef3374550574e79f275ae4977a6fb5ecd0b 100644 --- a/src/views/jobs/JobDetailsView.tsx +++ b/src/views/jobs/JobDetailsView.tsx @@ -4,7 +4,7 @@ import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { useNavigate } from "react-router-dom"; import { GlobalAppBarContext } from "@ess-ics/ce-ui-common"; import { JobsDetails } from "../../components/Job/JobDetails"; -import { applicationTitle } from "../../components/common/Helper"; +import { applicationTitle } from "../../components/common/applicationTitle"; import { GlobalAppBarContext as GlobalAppBarContextType } from "../../types/common"; import { JobDetails } from "../../store/deployApi"; diff --git a/src/views/jobs/JobListView.tsx b/src/views/jobs/JobListView.tsx index f7d9c3968d11b4504c653cf97d9490503a2e379f..53e5006329e0750695c01ab270a1de2aa7dbc572 100644 --- a/src/views/jobs/JobListView.tsx +++ b/src/views/jobs/JobListView.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect } from "react"; import { Box } from "@mui/material"; import { RootPaper, usePagination } from "@ess-ics/ce-ui-common"; -import { initRequestParams } from "../../components/common/Helper"; +import { initRequestParams } from "../../api/initRequestParams"; import { JobTable } from "../../components/Job/JobTable"; import { ROWS_PER_PAGE } from "../../constants"; import { useLazyListJobsQuery } from "../../store/deployApi"; diff --git a/src/views/jobs/JobLogAccessControl.tsx b/src/views/jobs/JobLogAccessControl.tsx index 14cc01eab8486d20f978d1016fb98ac7b0843938..5c98f2d5555b892ab38bd9577d5e1474ffb966d3 100644 --- a/src/views/jobs/JobLogAccessControl.tsx +++ b/src/views/jobs/JobLogAccessControl.tsx @@ -2,8 +2,8 @@ import { useContext, useEffect } from "react"; import { GlobalAppBarContext } from "@ess-ics/ce-ui-common"; import { JobListView } from "./JobListView"; import { AccessControl } from "../../components/auth/AccessControl"; -import { applicationTitle } from "../../components/common/Helper"; -import { type GlobalAppBarContext as GlobalAppBarContextType } from "../../types/common"; +import { applicationTitle } from "../../components/common/applicationTitle"; +import { GlobalAppBarContext as GlobalAppBarContextType } from "../../types/common"; export function JobLogAccessControl() { const { setTitle } = useContext<GlobalAppBarContextType>(GlobalAppBarContext); diff --git a/src/views/login/LoginView.tsx b/src/views/login/LoginView.tsx index 4a2a8fa5027d22d624c03cecf430c0342bcee380..8d23a30d8f3c81a06a7bf8ac71b346f315ea0abe 100644 --- a/src/views/login/LoginView.tsx +++ b/src/views/login/LoginView.tsx @@ -7,7 +7,7 @@ import { LoginForm } from "@ess-ics/ce-ui-common"; import { useRedirect } from "../../hooks/Redirect"; -import { applicationTitle } from "../../components/common/Helper"; +import { applicationTitle } from "../../components/common/applicationTitle"; import { GlobalAppBarContext as GlobalAppBarContextType, UserContext diff --git a/src/views/records/RecordDetailsView.tsx b/src/views/records/RecordDetailsView.tsx index 49f1663b8a6f0ea8a0f4b212b13f7c5cb3896beb..2763ae1ed1fe81db88ee5b5a06653c60a2bc157c 100644 --- a/src/views/records/RecordDetailsView.tsx +++ b/src/views/records/RecordDetailsView.tsx @@ -12,13 +12,18 @@ import { import { useParams, useNavigate } from "react-router-dom"; import { Alias } from "./Alias"; import { RecordBadge } from "../../components/records/RecordBadge"; -import { applicationTitle } from "../../components/common/Helper"; +import { applicationTitle } from "../../components/common/applicationTitle"; import { NotFoundView } from "../../components/navigation/NotFoundView/NotFoundView"; import { RecordDetails, useGetRecordQuery } from "../../store/deployApi"; -import { type GlobalAppBarContext as GlobalAppBarContextType } from "../../types/common"; +import { GlobalAppBarContext as GlobalAppBarContextType } from "../../types/common"; import { getErrorState } from "../../components/common/Alerts/AlertsData"; +const LAST_UPDATED = "Last updated"; +const RECORD_TYPE = "Record type"; +const DESCRIPTION = "Description"; +const IOC_REVISION = "IOC Revision"; + export function RecordDetailsView() { const { name } = useParams(); const decodedName = decodeURIComponent(name ?? ""); @@ -50,9 +55,9 @@ export function RecordDetailsView() { "Alias for": ( <Alias aliases={record?.aliasFor ? [record?.aliasFor] : []} /> ), - Description: record?.description || <EmptyValue />, + [DESCRIPTION]: record?.description || <EmptyValue />, Version: record?.iocVersion || <EmptyValue />, - "Record type": record.recordType || <EmptyValue />, + [RECORD_TYPE]: record.recordType || <EmptyValue />, Host: record.hostId ? ( <Typography> <InternalLink @@ -66,20 +71,20 @@ export function RecordDetailsView() { record?.hostName ), "Alias to": <Alias aliases={record?.aliasTo} />, - "Last updated": "", - "IOC Revision": "" + [LAST_UPDATED]: "", + [IOC_REVISION]: "" }; if (record?.properties) { for (const [key, value] of Object.entries(record.properties)) { if (key.toLowerCase().includes("time")) { - subset["Last updated"] = formatDateAndTime(value); + subset[LAST_UPDATED] = formatDateAndTime(value); } else if (key.toLowerCase().includes("recordtype")) { - subset["Record type"] = value; + subset[RECORD_TYPE] = value; } else if (key.toLowerCase().includes("recorddesc")) { - subset.Description = value; + subset[DESCRIPTION] = value; } else if (key.toLowerCase() === "iocversion") { - subset["IOC Revision"] = value; + subset[IOC_REVISION] = value; } } return subset; @@ -112,10 +117,7 @@ export function RecordDetailsView() { </IconButton> {record && ( <> - <RecordBadge - record={record} - sx={{ mt: 2.5 }} - /> + <RecordBadge record={record} /> <KeyValueTable obj={getSubset(record)} variant="overline" diff --git a/src/views/records/RecordListView.tsx b/src/views/records/RecordListView.tsx index 43c37b05f4b2e3a65c337d05ecbfb96e263e93d5..26f62f02e8b19039379d14d7ea4881b433644b31 100644 --- a/src/views/records/RecordListView.tsx +++ b/src/views/records/RecordListView.tsx @@ -7,13 +7,11 @@ import { usePagination, SearchBar } from "@ess-ics/ce-ui-common"; -import { - applicationTitle, - initRequestParams -} from "../../components/common/Helper"; +import { applicationTitle } from "../../components/common/applicationTitle"; +import { initRequestParams } from "../../api/initRequestParams"; import { RecordTable } from "../../components/records/RecordTable"; import { ROWS_PER_PAGE } from "../../constants"; -import { useLazyFindAllRecordsQuery } from "../../store/deployApi"; +import { Record, useLazyFindAllRecordsQuery } from "../../store/deployApi"; import { GlobalAppBarContext as GlobalAppBarContextType, OnPageParams @@ -29,7 +27,7 @@ export function RecordListView() { const [searchParams, setSearchParams] = useSearchParams({ query: "" }); const [tabIndex, setTabIndex] = useState(0); const [recordFilter, setRecordFilter] = useState< - "ACTIVE" | "INACTIVE" | undefined + Record["pvStatus"] | undefined >(undefined); // used to request record list again when tab is switched, but request it only once! (totalRecord is a random number that is generated by ChannelFinder) diff --git a/tsconfig.json b/tsconfig.json index 9744dfaa006d249516276f90b4649fd5cdfd8847..696440257f9d5be9f9935d3118a0ef2974ca6f62 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "target": "ESNext", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, + "checkJs": true, "module": "ESNext", "skipLibCheck": true, "esModuleInterop": true, @@ -29,7 +30,12 @@ "msw" ] }, - "include": ["src", "cypress.d.ts", "./global.d.ts", "declaration.d.ts"], + "include": [ + "src", + "cypress.d.ts", + "src/types/index.d.ts", + "src/types/typings.d.ts" + ], "exclude": [ "node_modules", "build",