diff --git a/portal-ui/package.json b/portal-ui/package.json index 0bd97ccc6..aaf3fd058 100644 --- a/portal-ui/package.json +++ b/portal-ui/package.json @@ -24,8 +24,8 @@ "@types/react-dom": "18.0.5", "@types/react-grid-layout": "^1.1.1", "@types/react-redux": "^7.1.24", - "@types/react-router": "^5.1.3", - "@types/react-router-dom": "^5.1.2", + "@types/react-router": "^5.1.18", + "@types/react-router-dom": "^5.3.3", "@types/react-virtualized": "^9.21.21", "@types/superagent": "^4.1.12", "@types/webpack-env": "^1.14.1", @@ -46,7 +46,7 @@ "react-grid-layout": "^1.2.0", "react-moment": "^1.1.1", "react-redux": "^7.1.3", - "react-router-dom": "^5.1.2", + "react-router-dom": "6", "react-virtualized": "^9.22.3", "react-window": "^1.8.7", "react-window-infinite-loader": "^1.0.7", diff --git a/portal-ui/src/Routes.tsx b/portal-ui/src/MainRouter.tsx similarity index 83% rename from portal-ui/src/Routes.tsx rename to portal-ui/src/MainRouter.tsx index 8a6dde1ef..b55e22e9e 100644 --- a/portal-ui/src/Routes.tsx +++ b/portal-ui/src/MainRouter.tsx @@ -15,8 +15,7 @@ // along with this program. If not, see . import React, { Suspense } from "react"; -import { Route, Router, Switch } from "react-router-dom"; -import history from "./history"; +import { BrowserRouter, Route, Routes } from "react-router-dom"; import ProtectedRoute from "./ProtectedRoutes"; import LoadingComponent from "./common/LoadingComponent"; import AppConsole from "./screens/Console/ConsoleKBar"; @@ -26,23 +25,21 @@ const LoginCallback = React.lazy( () => import("./screens/LoginPage/LoginCallback") ); -const Routes = () => { +const MainRouter = () => { return ( - - + + ( + element={ }> - )} + } /> ( + element={
{
- )} + } /> - -
-
+ } + /> + + ); }; -export default Routes; +export default MainRouter; diff --git a/portal-ui/src/ProtectedRoutes.tsx b/portal-ui/src/ProtectedRoutes.tsx index 3270ac5dc..240c781fb 100644 --- a/portal-ui/src/ProtectedRoutes.tsx +++ b/portal-ui/src/ProtectedRoutes.tsx @@ -15,7 +15,7 @@ // along with this program. If not, see . import React, { useEffect, useState } from "react"; -import { Redirect, useLocation } from "react-router-dom"; +import { Navigate, useLocation } from "react-router-dom"; import api from "./common/api"; import { ISessionResponse } from "./screens/Console/types"; import useApi from "./screens/Console/Common/Hooks/useApi"; @@ -50,7 +50,7 @@ const ProtectedRoute = ({ Component }: ProtectedRouteProps) => { const StorePathAndRedirect = () => { localStorage.setItem("redirect-path", pathname); - return ; + return ; }; useEffect(() => { diff --git a/portal-ui/src/common/SecureComponent/permissions.ts b/portal-ui/src/common/SecureComponent/permissions.ts index df4c54d5a..57dff1334 100644 --- a/portal-ui/src/common/SecureComponent/permissions.ts +++ b/portal-ui/src/common/SecureComponent/permissions.ts @@ -113,9 +113,9 @@ export const IAM_SCOPES = { export const IAM_PAGES = { /* Buckets */ BUCKETS: "/buckets", - ADD_BUCKETS: "/buckets/add-bucket", - BUCKETS_ADMIN_VIEW: "/buckets/:bucketName/admin*", - BUCKETS_BROWSE_VIEW: "/buckets/:bucketName/browse*", + ADD_BUCKETS: "add-bucket", + BUCKETS_ADMIN_VIEW: ":bucketName/admin/*", + BUCKETS_BROWSE_VIEW: ":bucketName/browse/*", /* Identity */ IDENTITY: "/identity", USERS: "/identity/users", @@ -123,10 +123,10 @@ export const IAM_PAGES = { USER_ADD: "/identity/users/add-user", GROUPS: "/identity/groups", GROUPS_ADD: "/identity/groups/create-group", - GROUPS_VIEW: "/identity/groups/:groupName+", + GROUPS_VIEW: "/identity/groups/:groupName", ACCOUNT: "/identity/account", ACCOUNT_ADD: "/identity/account/new-account", - USER_SA_ACCOUNT_ADD: "/identity/users/new-user-sa/:userName+", + USER_SA_ACCOUNT_ADD: "/identity/users/new-user-sa/:userName", /* Access */ POLICIES: "/access/policies", diff --git a/portal-ui/src/index.tsx b/portal-ui/src/index.tsx index f204c8f0e..496a72e39 100644 --- a/portal-ui/src/index.tsx +++ b/portal-ui/src/index.tsx @@ -17,7 +17,6 @@ import React from "react"; import ReactDOM from "react-dom/client"; import { Provider } from "react-redux"; -import Routes from "./Routes"; import { store } from "./store"; import * as serviceWorker from "./serviceWorker"; import { @@ -32,6 +31,7 @@ import "react-resizable/css/styles.css"; import "./index.css"; import theme from "./theme/main"; +import MainRouter from "./MainRouter"; declare module "@mui/styles/defaultTheme" { // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -137,7 +137,7 @@ root.render( - + diff --git a/portal-ui/src/screens/Console/Account/Account.tsx b/portal-ui/src/screens/Console/Account/Account.tsx index 2511839f0..6da2f3b75 100644 --- a/portal-ui/src/screens/Console/Account/Account.tsx +++ b/portal-ui/src/screens/Console/Account/Account.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import Grid from "@mui/material/Grid"; @@ -76,12 +77,10 @@ const useStyles = makeStyles((theme: Theme) => }) ); -interface IServiceAccountsProps { - history: any; -} - -const Account = ({ history }: IServiceAccountsProps) => { +const Account = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const classes = useStyles(); const features = useSelector(selFeatures); @@ -248,7 +247,7 @@ const Account = ({ history }: IServiceAccountsProps) => { { - history.push(`${IAM_PAGES.ACCOUNT_ADD}`); + navigate(`${IAM_PAGES.ACCOUNT_ADD}`); }} text={`Create service account`} icon={} diff --git a/portal-ui/src/screens/Console/Account/AddServiceAccountScreen.tsx b/portal-ui/src/screens/Console/Account/AddServiceAccountScreen.tsx index 2f4f60c91..49a8f12af 100644 --- a/portal-ui/src/screens/Console/Account/AddServiceAccountScreen.tsx +++ b/portal-ui/src/screens/Console/Account/AddServiceAccountScreen.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { Theme } from "@mui/material/styles"; +import { useNavigate } from "react-router-dom"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import { @@ -32,7 +33,6 @@ import { import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper"; import PageHeader from "../Common/PageHeader/PageHeader"; import PageLayout from "../Common/Layout/PageLayout"; -import history from "../../../../src/history"; import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; import AddServiceAccountHelpBox from "./AddServiceAccountHelpBox"; @@ -76,6 +76,8 @@ const styles = (theme: Theme) => const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const [addSending, setAddSending] = useState(false); const [accessKey, setAccessKey] = useState(getRandomString(16)); const [secretKey, setSecretKey] = useState(getRandomString(32)); @@ -133,7 +135,7 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => { const closeCredentialsModal = () => { setNewServiceAccount(null); - history.push(`${IAM_PAGES.ACCOUNT}`); + navigate(`${IAM_PAGES.ACCOUNT}`); }; return ( diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessDetailsPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessDetailsPanel.tsx index 022e3a20a..d4d456f8c 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessDetailsPanel.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessDetailsPanel.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate, useParams } from "react-router-dom"; import { Paper } from "@mui/material"; import Tabs from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; @@ -26,7 +27,6 @@ import { User } from "../../Users/types"; import { ErrorResponseHandler } from "../../../../common/types"; import TableWrapper from "../../Common/TableWrapper/TableWrapper"; import api from "../../../../common/api"; -import history from "../../../../history"; import { CONSOLE_UI_RESOURCE, IAM_PAGES, @@ -48,12 +48,10 @@ function a11yProps(index: any) { }; } -interface IAccessDetailsProps { - match: any; -} - -const AccessDetails = ({ match }: IAccessDetailsProps) => { +const AccessDetails = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const params = useParams(); const loadingBucket = useSelector(selBucketDetailsLoading); @@ -63,7 +61,7 @@ const AccessDetails = ({ match }: IAccessDetailsProps) => { const [loadingUsers, setLoadingUsers] = useState(true); const [bucketUsers, setBucketUsers] = useState([]); - const bucketName = match.params["bucketName"]; + const bucketName = params.bucketName || ""; const displayPoliciesList = hasPermission(bucketName, [ IAM_SCOPES.ADMIN_LIST_USER_POLICIES, @@ -100,7 +98,7 @@ const AccessDetails = ({ match }: IAccessDetailsProps) => { type: "view", disableButtonFunction: () => !viewPolicy, onClick: (policy: any) => { - history.push(`${IAM_PAGES.POLICIES}/${encodeURLString(policy.name)}`); + navigate(`${IAM_PAGES.POLICIES}/${encodeURLString(policy.name)}`); }, }, ]; @@ -110,7 +108,7 @@ const AccessDetails = ({ match }: IAccessDetailsProps) => { type: "view", disableButtonFunction: () => !viewUser, onClick: (user: any) => { - history.push(`${IAM_PAGES.USERS}/${encodeURLString(user)}`); + navigate(`${IAM_PAGES.USERS}/${encodeURLString(user)}`); }, }, ]; diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessRulePanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessRulePanel.tsx index 2ea178a16..e8a052221 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessRulePanel.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessRulePanel.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useParams } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import { Paper } from "@mui/material"; @@ -73,13 +74,10 @@ const useStyles = makeStyles((theme: Theme) => }) ); -interface IAccessRuleProps { - match: any; -} - -const AccessRule = ({ match }: IAccessRuleProps) => { +const AccessRule = () => { const dispatch = useDispatch(); const classes = useStyles(); + const params = useParams(); const loadingBucket = useSelector(selBucketDetailsLoading); @@ -93,7 +91,7 @@ const AccessRule = ({ match }: IAccessRuleProps) => { const [accessRuleToEdit, setAccessRuleToEdit] = useState(""); const [initialAccess, setInitialAccess] = useState(""); - const bucketName = match.params["bucketName"]; + const bucketName = params.bucketName || ""; const displayAccessRules = hasPermission(bucketName, [ IAM_SCOPES.S3_GET_BUCKET_POLICY, diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BrowserHandler.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BrowserHandler.tsx index c9676778c..d03819e07 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BrowserHandler.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BrowserHandler.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate, useParams } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; @@ -48,14 +49,11 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -interface IBrowserHandlerProps { - match: any; - history: any; - classes: any; -} - -const BrowserHandler = ({ match, history, classes }: IBrowserHandlerProps) => { +const BrowserHandler = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const params = useParams(); + const versionsMode = useSelector( (state: AppState) => state.objectBrowser.versionsMode ); @@ -69,15 +67,15 @@ const BrowserHandler = ({ match, history, classes }: IBrowserHandlerProps) => { (state: AppState) => state.objectBrowser.searchVersions ); - const bucketName = match.params["bucketName"]; - const internalPaths = get(match.params, "subpaths", ""); + const bucketName = params.bucketName || ""; + const internalPaths = get(params, "subpaths", ""); useEffect(() => { dispatch(setVersionsModeEnabled({ status: false })); }, [internalPaths, dispatch]); const openBucketConfiguration = () => { - history.push(`/buckets/${bucketName}/admin`); + navigate(`/buckets/${bucketName}/admin`); }; return ( diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketDetails.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketDetails.tsx index 579ee472f..c1e8a7598 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketDetails.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketDetails.tsx @@ -15,7 +15,14 @@ // along with this program. If not, see . import React, { Fragment, useEffect, useState } from "react"; -import { Link, Redirect, Route, Router, Switch } from "react-router-dom"; +import { + Link, + Navigate, + Route, + Routes, + useNavigate, + useParams, +} from "react-router-dom"; import { useDispatch, useSelector } from "react-redux"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; @@ -107,12 +114,12 @@ const styles = (theme: Theme) => interface IBucketDetailsProps { classes: any; - match: any; - history: any; } -const BucketDetails = ({ classes, match, history }: IBucketDetailsProps) => { +const BucketDetails = ({ classes }: IBucketDetailsProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const params = useParams(); const distributedSetup = useSelector(selDistSet); const loadingBucket = useSelector(selBucketDetailsLoading); @@ -121,9 +128,9 @@ const BucketDetails = ({ classes, match, history }: IBucketDetailsProps) => { const [iniLoad, setIniLoad] = useState(false); const [deleteOpen, setDeleteOpen] = useState(false); - const bucketName = match.params["bucketName"]; + const bucketName = params.bucketName || ""; - let selTab = match?.params["0"]; + let selTab = params["0"] || ""; selTab = selTab ? selTab : "summary"; const [activeTab, setActiveTab] = useState(selTab); @@ -178,12 +185,12 @@ const BucketDetails = ({ classes, match, history }: IBucketDetailsProps) => { const closeDeleteModalAndRefresh = (refresh: boolean) => { setDeleteOpen(false); if (refresh) { - history.push("/buckets"); + navigate("/buckets"); } }; const openBucketBrowser = () => { - history.push(`/buckets/${bucketName}/browse`); + navigate(`/buckets/${bucketName}/browse`); }; return ( @@ -280,51 +287,31 @@ const BucketDetails = ({ classes, match, history }: IBucketDetailsProps) => { isRouteTabs routes={
- - + + } /> + } /> + {distributedSetup && ( } /> + )} + {distributedSetup && ( } /> - {distributedSetup && ( - - )} - {distributedSetup && ( - - )} + )} - - - ( - - )} - /> - - + } /> + } /> + + } + /> +
} > diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx index 72a5ffa74..6c8acc746 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useParams } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; @@ -59,11 +60,11 @@ const styles = (theme: Theme) => interface IBucketEventsProps { classes: any; - match: any; } -const BucketEventsPanel = ({ classes, match }: IBucketEventsProps) => { +const BucketEventsPanel = ({ classes }: IBucketEventsProps) => { const dispatch = useDispatch(); + const params = useParams(); const loadingBucket = useSelector(selBucketDetailsLoading); @@ -73,7 +74,7 @@ const BucketEventsPanel = ({ classes, match }: IBucketEventsProps) => { const [deleteOpen, setDeleteOpen] = useState(false); const [selectedEvent, setSelectedEvent] = useState(null); - const bucketName = match.params["bucketName"]; + const bucketName = params.bucketName || ""; const displayEvents = hasPermission(bucketName, [ IAM_SCOPES.S3_GET_BUCKET_NOTIFICATIONS, diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx index 896cdeeb4..5a7ecdf90 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx @@ -42,6 +42,7 @@ import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions"; import RBIconButton from "./SummaryItems/RBIconButton"; import DeleteBucketLifecycleRule from "./DeleteBucketLifecycleRule"; import { selBucketDetailsLoading } from "./bucketDetailsSlice"; +import { useParams } from "react-router-dom"; const styles = (theme: Theme) => createStyles({ @@ -54,14 +55,11 @@ const styles = (theme: Theme) => interface IBucketLifecyclePanelProps { classes: any; - match: any; } -const BucketLifecyclePanel = ({ - classes, - match, -}: IBucketLifecyclePanelProps) => { +const BucketLifecyclePanel = ({ classes }: IBucketLifecyclePanelProps) => { const loadingBucket = useSelector(selBucketDetailsLoading); + const params = useParams(); const [loadingLifecycle, setLoadingLifecycle] = useState(true); const [lifecycleRecords, setLifecycleRecords] = useState([]); @@ -73,7 +71,7 @@ const BucketLifecyclePanel = ({ useState(false); const [selectedID, setSelectedID] = useState(null); - const bucketName = match.params["bucketName"]; + const bucketName = params.bucketName || ""; const displayLifeCycleRules = hasPermission(bucketName, [ IAM_SCOPES.S3_GET_LIFECYCLE_CONFIGURATION, diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx index 6c32dbd7e..7f4f82b4e 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx @@ -46,6 +46,7 @@ import RBIconButton from "./SummaryItems/RBIconButton"; import EditReplicationModal from "./EditReplicationModal"; import { setErrorSnackMessage } from "../../../../systemSlice"; import { selBucketDetailsLoading } from "./bucketDetailsSlice"; +import { useParams } from "react-router-dom"; const AddReplicationModal = withSuspense( React.lazy(() => import("./AddReplicationModal")) @@ -56,7 +57,6 @@ const DeleteReplicationRule = withSuspense( interface IBucketReplicationProps { classes: any; - match: any; } const styles = (theme: Theme) => @@ -68,11 +68,9 @@ const styles = (theme: Theme) => }, }); -const BucketReplicationPanel = ({ - classes, - match, -}: IBucketReplicationProps) => { +const BucketReplicationPanel = ({ classes }: IBucketReplicationProps) => { const dispatch = useDispatch(); + const params = useParams(); const loadingBucket = useSelector(selBucketDetailsLoading); @@ -90,7 +88,7 @@ const BucketReplicationPanel = ({ const [deleteSelectedRules, setDeleteSelectedRules] = useState(false); - const bucketName = match.params["bucketName"]; + const bucketName = params.bucketName || ""; const displayReplicationRules = hasPermission(bucketName, [ IAM_SCOPES.S3_GET_REPLICATION_CONFIGURATION, diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketSummaryPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketSummaryPanel.tsx index 6bf3d85c1..dbbe7234b 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketSummaryPanel.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketSummaryPanel.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useParams } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; @@ -93,11 +94,11 @@ const twoColCssGridLayoutConfig = { interface IBucketSummaryProps { classes: any; - match: any; } -const BucketSummary = ({ classes, match }: IBucketSummaryProps) => { +const BucketSummary = ({ classes }: IBucketSummaryProps) => { const dispatch = useDispatch(); + const params = useParams(); const loadingBucket = useSelector(selBucketDetailsLoading); const bucketInfo = useSelector(selBucketDetailsInfo); @@ -135,7 +136,7 @@ const BucketSummary = ({ classes, match }: IBucketSummaryProps) => { const [enableVersioningOpen, setEnableVersioningOpen] = useState(false); - const bucketName = match.params["bucketName"]; + const bucketName = params.bucketName || ""; let accessPolicy = "n/a"; let policyDefinition = ""; diff --git a/portal-ui/src/screens/Console/Buckets/Buckets.tsx b/portal-ui/src/screens/Console/Buckets/Buckets.tsx index c5259a1eb..c7026f217 100644 --- a/portal-ui/src/screens/Console/Buckets/Buckets.tsx +++ b/portal-ui/src/screens/Console/Buckets/Buckets.tsx @@ -15,8 +15,7 @@ // along with this program. If not, see . import React, { Suspense } from "react"; -import history from "../../../history"; -import { Redirect, Route, Router, Switch, withRouter } from "react-router-dom"; +import { Navigate, Route, Routes } from "react-router-dom"; import NotFoundPage from "../../NotFoundPage"; import LoadingComponent from "../../../common/LoadingComponent"; @@ -31,70 +30,59 @@ const AddBucket = React.lazy(() => import("./ListBuckets/AddBucket/AddBucket")); const Buckets = () => { return ( - - - ( - }> - - - )} - /> - ( - }> - - - )} - /> - ( - }> - - - )} - /> - ( - }> - - - )} - /> - ( - }> - - - )} - /> - } - /> - ( - }> - - - )} - /> - ( - }> - - - )} - /> - - + + }> + + + } + /> + }> + + + } + /> + + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + } path="*" /> + + }> + + + } + /> + ); }; -export default withRouter(Buckets); +export default Buckets; diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/AddBucket.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/AddBucket.tsx index 98cc096f6..5e50ddd6f 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/AddBucket.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/AddBucket.tsx @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import React, { Fragment } from "react"; +import React, { Fragment, useEffect } from "react"; import Grid from "@mui/material/Grid"; import { Button, LinearProgress } from "@mui/material"; import { Theme } from "@mui/material/styles"; @@ -51,6 +51,7 @@ import { } from "./addBucketsSlice"; import { addBucketAsync } from "./addBucketThunks"; import AddBucketName from "./AddBucketName"; +import { useNavigate } from "react-router-dom"; const styles = (theme: Theme) => createStyles({ @@ -103,6 +104,7 @@ interface IsetProps { const AddBucket = ({ classes }: IsetProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); const versioningEnabled = useSelector( (state: AppState) => state.addBucket.versioningEnabled @@ -134,11 +136,22 @@ const AddBucket = ({ classes }: IsetProps) => { ); const distributedSetup = useSelector(selDistSet); const siteReplicationInfo = useSelector(selSiteRep); + const navigateTo = useSelector( + (state: AppState) => state.addBucket.navigateTo + ); const resForm = () => { dispatch(resetForm()); }; + useEffect(() => { + if (navigateTo !== "") { + const goTo = `${navigateTo}`; + dispatch(resetForm()); + navigate(goTo); + } + }, [navigateTo, navigate, dispatch]); + return ( } /> diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/addBucketThunks.ts b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/addBucketThunks.ts index 0ee746b6e..29e74c47b 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/addBucketThunks.ts +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/addBucketThunks.ts @@ -17,7 +17,6 @@ import { MakeBucketRequest } from "../../types"; import { getBytes } from "../../../../../common/utils"; import api from "../../../../../common/api"; -import history from "../../../../../history"; import { ErrorResponseHandler } from "../../../../../common/types"; import { setErrorSnackMessage } from "../../../../../systemSlice"; import { createAsyncThunk } from "@reduxjs/toolkit"; @@ -75,7 +74,7 @@ export const addBucketAsync = createAsyncThunk( .then((res) => { const newBucketName = `${bucketName}`; dispatch(resetForm()); - history.push(`/buckets/${newBucketName}/browse`); + return newBucketName; }) .catch((err: ErrorResponseHandler) => { dispatch(setErrorSnackMessage(err)); diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/addBucketsSlice.ts b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/addBucketsSlice.ts index 68f1b38f8..598531af1 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/addBucketsSlice.ts +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/AddBucket/addBucketsSlice.ts @@ -31,6 +31,7 @@ export interface AddBucketState { retentionMode: string; retentionUnit: string; retentionValidity: number; + navigateTo: string; } const initialState: AddBucketState = { @@ -47,6 +48,7 @@ const initialState: AddBucketState = { retentionMode: "compliance", retentionUnit: "days", retentionValidity: 180, + navigateTo: "", }; export const addBucketsSlice = createSlice({ @@ -138,6 +140,7 @@ export const addBucketsSlice = createSlice({ }) .addCase(addBucketAsync.fulfilled, (state, action) => { state.loading = false; + state.navigateTo = `/buckets/${action.payload}/browse`; }); }, }); diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx index 29d17b537..4c9026ea5 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch } from "react-redux"; +import { useNavigate } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; @@ -83,11 +84,11 @@ const styles = (theme: Theme) => interface IListBucketsProps { classes: any; - history: any; } -const ListBuckets = ({ classes, history }: IListBucketsProps) => { +const ListBuckets = ({ classes }: IListBucketsProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); const [records, setRecords] = useState([]); const [loading, setLoading] = useState(true); @@ -291,7 +292,7 @@ const ListBuckets = ({ classes, history }: IListBucketsProps) => { { - history.push(IAM_PAGES.ADD_BUCKETS); + navigate(IAM_PAGES.ADD_BUCKETS); }} text={"Create Bucket"} icon={} @@ -356,7 +357,7 @@ const ListBuckets = ({ classes, history }: IListBucketsProps) => { To get started,  { - history.push(IAM_PAGES.ADD_BUCKETS); + navigate(IAM_PAGES.ADD_BUCKETS); }} > Create a Bucket. diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/CreatePathModal.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/CreatePathModal.tsx index bb8aeba68..3165678a6 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/CreatePathModal.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/CreatePathModal.tsx @@ -15,6 +15,7 @@ // along with this program. If not, see . import React, { useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper"; import { Button, Grid } from "@mui/material"; import InputBoxWrapper from "../../../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; @@ -26,7 +27,6 @@ import { modalStyleUtils, } from "../../../../Common/FormComponents/common/styleLibrary"; import { connect, useDispatch } from "react-redux"; -import history from "../../../../../../history"; import { encodeURLString } from "../../../../../../common/utils"; import { BucketObjectItem } from "./types"; @@ -60,6 +60,8 @@ const CreatePathModal = ({ simplePath, }: ICreatePath) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const [pathUrl, setPathUrl] = useState(""); const [isFormValid, setIsFormValid] = useState(false); const [currentPath, setCurrentPath] = useState(bucketName); @@ -106,7 +108,7 @@ const CreatePathModal = ({ const newPath = `/buckets/${bucketName}/browse/${encodeURLString( `${folderPath}${cleanPathURL}/` )}`; - history.push(newPath); + navigate(newPath); onClose(); }; diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx index f9e2b6a65..3f3515143 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx @@ -23,10 +23,10 @@ import React, { useState, } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate, useParams } from "react-router-dom"; import { useDropzone } from "react-dropzone"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; -import { withRouter } from "react-router-dom"; import Grid from "@mui/material/Grid"; import get from "lodash/get"; import { BucketObjectItem, BucketObjectItemsList } from "./types"; @@ -268,14 +268,11 @@ function useInterval(callback: any, delay: number) { const defLoading = Loading...; -interface IListObjectsProps { - match: any; - history: any; -} - -const ListObjects = ({ match, history }: IListObjectsProps) => { +const ListObjects = () => { const classes = useStyles(); const dispatch = useDispatch(); + const params = useParams(); + const navigate = useNavigate(); const rewindEnabled = useSelector( (state: AppState) => state.objectBrowser.rewind.rewindEnabled @@ -339,8 +336,8 @@ const ListObjects = ({ match, history }: IListObjectsProps) => { const [canPreviewFile, setCanPreviewFile] = useState(false); const [quota, setQuota] = useState(null); - const internalPaths = get(match.params, "subpaths", ""); - const bucketName = match.params["bucketName"]; + const internalPaths = get(params, "subpaths", ""); + const bucketName = params.bucketName || ""; const fileUpload = useRef(null); const folderUpload = useRef(null); @@ -702,7 +699,6 @@ const ListObjects = ({ match, history }: IListObjectsProps) => { } }, [ loading, - match, dispatch, bucketName, rewindEnabled, @@ -815,7 +811,7 @@ const ListObjects = ({ match, history }: IListObjectsProps) => { const newPath = `/buckets/${bucketName}/browse${ idElement ? `/${encodeURLString(idElement)}` : `` }`; - history.push(newPath); + navigate(newPath); dispatch(setObjectDetailsView(true)); dispatch(setLoadingVersions(true)); @@ -1190,7 +1186,7 @@ const ListObjects = ({ match, history }: IListObjectsProps) => { URLItem = `${splitURLS.join("/")}/`; } - history.push(`/buckets/${bucketName}/browse/${encodeURLString(URLItem)}`); + navigate(`/buckets/${bucketName}/browse/${encodeURLString(URLItem)}`); } dispatch(setObjectDetailsView(false)); @@ -1548,4 +1544,4 @@ const ListObjects = ({ match, history }: IListObjectsProps) => { ); }; -export default withRouter(ListObjects); +export default ListObjects; diff --git a/portal-ui/src/screens/Console/CommandBar.tsx b/portal-ui/src/screens/Console/CommandBar.tsx index 74d09425b..82bf73d36 100644 --- a/portal-ui/src/screens/Console/CommandBar.tsx +++ b/portal-ui/src/screens/Console/CommandBar.tsx @@ -15,6 +15,7 @@ // along with this program. If not, see . import * as React from "react"; import { useCallback, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; import { ActionId, ActionImpl, @@ -128,6 +129,7 @@ const KBarStateChangeMonitor = ({ const CommandBar = () => { const operatorMode = useSelector(selOpMode); const features = useSelector(selFeatures); + const navigate = useNavigate(); const [buckets, setBuckets] = useState([]); @@ -146,7 +148,8 @@ const CommandBar = () => { const initialActions: Action[] = routesAsKbarActions( features, operatorMode, - buckets + buckets, + navigate ); useRegisterActions(initialActions, [operatorMode, buckets, features]); diff --git a/portal-ui/src/screens/Console/Common/TableWrapper/TableWrapper.tsx b/portal-ui/src/screens/Console/Common/TableWrapper/TableWrapper.tsx index 53dd4dd8b..d2a36a9dd 100644 --- a/portal-ui/src/screens/Console/Common/TableWrapper/TableWrapper.tsx +++ b/portal-ui/src/screens/Console/Common/TableWrapper/TableWrapper.tsx @@ -14,8 +14,6 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import React, { Fragment, useState } from "react"; -import get from "lodash/get"; -import isString from "lodash/isString"; import { Checkbox, Grid, @@ -25,7 +23,10 @@ import { Popover, Typography, } from "@mui/material"; +import { useNavigate } from "react-router-dom"; import { AutoSizer, Column, InfiniteLoader, Table } from "react-virtualized"; +import get from "lodash/get"; +import isString from "lodash/isString"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import ViewColumnIcon from "@mui/icons-material/ViewColumn"; @@ -33,7 +34,6 @@ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp"; import TableActionButton from "./TableActionButton"; import CheckboxWrapper from "../FormComponents/CheckboxWrapper/CheckboxWrapper"; -import history from "../../../../history"; import { checkboxIcons, radioIcons, @@ -467,6 +467,8 @@ const TableWrapper = ({ rowStyle, parentClassName = "", }: TableWrapperProps) => { + const navigate = useNavigate(); + const [columnSelectorOpen, setColumnSelectorOpen] = useState(false); const [anchorEl, setAnchorEl] = React.useState(null); @@ -487,7 +489,7 @@ const TableWrapper = ({ } if (findView.to && !disabled) { - history.push(`${findView.to}/${valueClick}`); + navigate(`${findView.to}/${valueClick}`); return; } diff --git a/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx b/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx index e2775abce..defa9c2da 100644 --- a/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx +++ b/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx @@ -15,19 +15,16 @@ // along with this program. If not, see . import React from "react"; -import { Route, Router, Switch } from "react-router-dom"; -import history from "../../../history"; +import { Route, Routes } from "react-router-dom"; import ConfigurationOptions from "./ConfigurationPanels/ConfigurationOptions"; import NotFoundPage from "../../NotFoundPage"; const ConfigurationMain = () => { return ( - - - - - - + + } /> + } /> + ); }; diff --git a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationForm.tsx b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationForm.tsx index 13e872f2e..6683a5a39 100644 --- a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationForm.tsx +++ b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationForm.tsx @@ -15,22 +15,15 @@ // along with this program. If not, see . import React from "react"; -import get from "lodash/get"; +import { useLocation } from "react-router-dom"; import Grid from "@mui/material/Grid"; import { configurationElements } from "../utils"; import EditConfiguration from "../../NotificationEndpoints/CustomForms/EditConfiguration"; -interface IConfigurationForm { - match: any; - history: any; -} +const ConfigurationsList = () => { + const { pathname = "" } = useLocation(); -const ConfigurationsList = ({ match, history }: IConfigurationForm) => { - const activeConfRoute = get(match, "url", ""); - - const configName = activeConfRoute.substring( - activeConfRoute.lastIndexOf("/") + 1 - ); + const configName = pathname.substring(pathname.lastIndexOf("/") + 1); const validActiveConfig = configurationElements.find( (element) => element.configuration_id === configName @@ -55,7 +48,6 @@ const ConfigurationsList = ({ match, history }: IConfigurationForm) => { )} diff --git a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationOptions.tsx b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationOptions.tsx index 97a240fce..563ab5cfb 100644 --- a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationOptions.tsx +++ b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationOptions.tsx @@ -29,11 +29,9 @@ import { import PageHeader from "../../Common/PageHeader/PageHeader"; import HelpBox from "../../../../common/HelpBox"; import { SettingsIcon } from "../../../../icons"; -import { Link, Redirect, Route, Router, Switch } from "react-router-dom"; -import history from "../../../../history"; +import { Link, Navigate, Route, Routes, useLocation } from "react-router-dom"; import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs"; import PageLayout from "../../Common/Layout/PageLayout"; -import get from "lodash/get"; import ScreenTitle from "../../Common/ScreenTitle/ScreenTitle"; import withSuspense from "../../Common/Components/withSuspense"; @@ -45,7 +43,6 @@ const ConfigurationForm = withSuspense( interface IConfigurationOptions { classes: any; - match: any; } const styles = (theme: Theme) => @@ -68,11 +65,10 @@ const getRoutePath = (path: string) => { return `${IAM_PAGES.SETTINGS}/${path}`; }; -const ConfigurationOptions = ({ classes, match }: IConfigurationOptions) => { - const configurationName = get(match, "url", ""); - let selConfigTab = configurationName.substring( - configurationName.lastIndexOf("/") + 1 - ); +const ConfigurationOptions = ({ classes }: IConfigurationOptions) => { + const { pathname = "" } = useLocation(); + + let selConfigTab = pathname.substring(pathname.lastIndexOf("/") + 1); selConfigTab = selConfigTab === "settings" ? "region" : selConfigTab; return ( @@ -90,21 +86,19 @@ const ConfigurationOptions = ({ classes, match }: IConfigurationOptions) => { selectedTab={selConfigTab} isRouteTabs routes={ - - - {configurationElements.map((element) => ( - - ))} - - - - - + + {configurationElements.map((element) => ( + } + /> + ))} + } + /> + } > {configurationElements.map((element) => { diff --git a/portal-ui/src/screens/Console/Configurations/SiteReplication/AddReplicationSites.tsx b/portal-ui/src/screens/Console/Configurations/SiteReplication/AddReplicationSites.tsx index 2aadc0e3a..9de303f82 100644 --- a/portal-ui/src/screens/Console/Configurations/SiteReplication/AddReplicationSites.tsx +++ b/portal-ui/src/screens/Console/Configurations/SiteReplication/AddReplicationSites.tsx @@ -15,19 +15,19 @@ // along with this program. If not, see . import React, { Fragment, useEffect, useState } from "react"; -import { AddIcon, ClustersIcon, RemoveIcon } from "../../../../icons"; -import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import Grid from "@mui/material/Grid"; import { Box, Button, LinearProgress } from "@mui/material"; +import { useNavigate } from "react-router-dom"; +import { useDispatch } from "react-redux"; import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton"; import useApi from "../../Common/Hooks/useApi"; -import { useDispatch } from "react-redux"; +import { AddIcon, ClustersIcon, RemoveIcon } from "../../../../icons"; +import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import PageHeader from "../../Common/PageHeader/PageHeader"; import BackLink from "../../../../common/BackLink"; import { IAM_PAGES } from "../../../../common/SecureComponent/permissions"; import PageLayout from "../../Common/Layout/PageLayout"; import HelpBox from "../../../../common/HelpBox"; -import history from "../../../../history"; import SectionTitle from "../../Common/SectionTitle"; import { setErrorSnackMessage, @@ -56,6 +56,8 @@ const isValidEndPoint = (ep: string) => { }; const AddReplicationSites = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const [existingSites, setExistingSites] = useState([]); const [accessKey, setAccessKey] = useState(""); @@ -127,7 +129,7 @@ const AddReplicationSites = () => { dispatch(setSnackBarMessage(res.status)); resetForm(); getSites(); - history.push(IAM_PAGES.SITE_REPLICATION); + navigate(IAM_PAGES.SITE_REPLICATION); } else { dispatch( setErrorSnackMessage({ diff --git a/portal-ui/src/screens/Console/Configurations/SiteReplication/SiteReplication.tsx b/portal-ui/src/screens/Console/Configurations/SiteReplication/SiteReplication.tsx index 3d5e7233d..ea29bd3e4 100644 --- a/portal-ui/src/screens/Console/Configurations/SiteReplication/SiteReplication.tsx +++ b/portal-ui/src/screens/Console/Configurations/SiteReplication/SiteReplication.tsx @@ -15,9 +15,11 @@ // along with this program. If not, see . import React, { Fragment, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { useDispatch } from "react-redux"; +import { Box, DialogContentText, Grid } from "@mui/material"; import PageHeader from "../../Common/PageHeader/PageHeader"; import PageLayout from "../../Common/Layout/PageLayout"; -import { Box, DialogContentText, Grid } from "@mui/material"; import useApi from "../../Common/Hooks/useApi"; import ReplicationSites from "./ReplicationSites"; import TrashIcon from "../../../../icons/TrashIcon"; @@ -29,11 +31,9 @@ import { ConfirmDeleteIcon, RecoverIcon, } from "../../../../icons"; -import { useDispatch } from "react-redux"; import { ErrorResponseHandler } from "../../../../common/types"; import HelpBox from "../../../../common/HelpBox"; import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog"; -import history from "../../../../history"; import { IAM_PAGES } from "../../../../common/SecureComponent/permissions"; import { setErrorSnackMessage, @@ -50,6 +50,8 @@ export type ReplicationSite = { const SiteReplication = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const [sites, setSites] = useState([]); const [deleteAll, setIsDeleteAll] = useState(false); @@ -138,7 +140,7 @@ const SiteReplication = () => { icon={} onClick={(e) => { e.preventDefault(); - history.push(IAM_PAGES.SITE_REPLICATION_STATUS); + navigate(IAM_PAGES.SITE_REPLICATION_STATUS); }} /> @@ -151,7 +153,7 @@ const SiteReplication = () => { disabled={isRemoving} icon={} onClick={() => { - history.push(IAM_PAGES.SITE_REPLICATION_ADD); + navigate(IAM_PAGES.SITE_REPLICATION_ADD); }} /> @@ -195,7 +197,7 @@ const SiteReplication = () => { To get started,{" "} { - history.push(IAM_PAGES.SITE_REPLICATION_ADD); + navigate(IAM_PAGES.SITE_REPLICATION_ADD); }} > Add a Replication Site diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/AddTierConfiguration.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/AddTierConfiguration.tsx index d06c77cb9..61fc35b11 100644 --- a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/AddTierConfiguration.tsx +++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/AddTierConfiguration.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useCallback, useEffect, useState } from "react"; import { useDispatch } from "react-redux"; +import { useNavigate, useParams } from "react-router-dom"; import get from "lodash/get"; import Grid from "@mui/material/Grid"; import { Theme } from "@mui/material/styles"; @@ -74,16 +75,17 @@ const styles = (theme: Theme) => interface IAddNotificationEndpointProps { classes: any; - match: any; history: any; } const AddTierConfiguration = ({ classes, - match, history, }: IAddNotificationEndpointProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const params = useParams(); + //Local States const [saving, setSaving] = useState(false); @@ -106,7 +108,7 @@ const AddTierConfiguration = ({ const [titleSelection, setTitleSelection] = useState(""); - const type = get(match, "params.service", "s3"); + const type = get(params, "service", "s3"); // Validations const [isFormValid, setIsFormValid] = useState(true); @@ -186,7 +188,7 @@ const AddTierConfiguration = ({ .then(() => { setSaving(false); - history.push(IAM_PAGES.TIERS); + navigate(IAM_PAGES.TIERS); }) .catch((err: ErrorResponseHandler) => { setSaving(false); @@ -209,6 +211,7 @@ const AddTierConfiguration = ({ dispatch, storageClass, type, + navigate, ]); useEffect(() => { @@ -497,7 +500,7 @@ const AddTierConfiguration = ({ label={"Region"} id="region" name="region" - type={type} + type={type as "azure" | "s3" | "minio" | "gcs"} /> {type === s3ServiceName || (type === minioServiceName && ( diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx index c0373eb6f..e69ff3976 100644 --- a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx +++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx @@ -55,6 +55,7 @@ import { SecureComponent } from "../../../../common/SecureComponent"; import { tierTypes } from "./utils"; import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton"; import { selDistSet, setErrorSnackMessage } from "../../../../systemSlice"; +import { useNavigate } from "react-router-dom"; const UpdateTierCredentialsModal = withSuspense( React.lazy(() => import("./UpdateTierCredentialsModal")) @@ -62,7 +63,6 @@ const UpdateTierCredentialsModal = withSuspense( interface IListTiersConfig { classes: any; - history: any; } const styles = (theme: Theme) => @@ -93,8 +93,10 @@ const styles = (theme: Theme) => ...tableStyles, }); -const ListTiersConfiguration = ({ classes, history }: IListTiersConfig) => { +const ListTiersConfiguration = ({ classes }: IListTiersConfig) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const distributedSetup = useSelector(selDistSet); const [records, setRecords] = useState([]); const [filter, setFilter] = useState(""); @@ -138,7 +140,7 @@ const ListTiersConfiguration = ({ classes, history }: IListTiersConfig) => { }); const addTier = () => { - history.push(IAM_PAGES.TIERS_ADD); + navigate(IAM_PAGES.TIERS_ADD); }; const renderTierName = (item: ITierElement) => { diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/TierTypeSelector.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/TierTypeSelector.tsx index 5d472c1c7..bc295919d 100644 --- a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/TierTypeSelector.tsx +++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/TierTypeSelector.tsx @@ -15,23 +15,21 @@ // along with this program. If not, see . import React, { Fragment } from "react"; - -import PageHeader from "../../Common/PageHeader/PageHeader"; +import { useNavigate } from "react-router-dom"; +import { Box } from "@mui/material"; import { tierTypes } from "./utils"; +import { IAM_PAGES } from "../../../../common/SecureComponent/permissions"; +import PageHeader from "../../Common/PageHeader/PageHeader"; import BackLink from "../../../../common/BackLink"; import PageLayout from "../../Common/Layout/PageLayout"; -import { Box } from "@mui/material"; import TierTypeCard from "./TierTypeCard"; -import { IAM_PAGES } from "../../../../common/SecureComponent/permissions"; import ContentBox from "../../Common/ContentBox"; -interface ITypeTiersConfig { - history: any; -} +const TierTypeSelector = () => { + const navigate = useNavigate(); -const TierTypeSelector = ({ history }: ITypeTiersConfig) => { const typeSelect = (selectName: string) => { - history.push(`${IAM_PAGES.TIERS_ADD}/${selectName}`); + navigate(`${IAM_PAGES.TIERS_ADD}/${selectName}`); }; return ( diff --git a/portal-ui/src/screens/Console/Console.tsx b/portal-ui/src/screens/Console/Console.tsx index c84fadc75..92ec1a00b 100644 --- a/portal-ui/src/screens/Console/Console.tsx +++ b/portal-ui/src/screens/Console/Console.tsx @@ -28,8 +28,7 @@ import withStyles from "@mui/styles/withStyles"; import { Button, LinearProgress } from "@mui/material"; import CssBaseline from "@mui/material/CssBaseline"; import Snackbar from "@mui/material/Snackbar"; -import history from "../../history"; -import { Redirect, Route, Router, Switch, useLocation } from "react-router-dom"; +import { Navigate, Route, Routes, useLocation } from "react-router-dom"; import { useDispatch, useSelector } from "react-redux"; import { AppState } from "../../store"; import { snackBarCommon } from "./Common/FormComponents/common/styleLibrary"; @@ -119,9 +118,7 @@ const Account = React.lazy(() => import("./Account/Account")); const AccountCreate = React.lazy( () => import("./Account/AddServiceAccountScreen") ); -const UserSACreate = React.lazy( - () => import("./Users/AddUserServiceAccountScreen") -); + const Users = React.lazy(() => import("./Users/Users")); const Groups = React.lazy(() => import("./Groups/Groups")); @@ -183,6 +180,7 @@ interface IConsoleProps { const Console = ({ classes }: IConsoleProps) => { const dispatch = useDispatch(); + const { pathname = "" } = useLocation(); const open = useSelector((state: AppState) => state.system.sidebarOpen); const session = useSelector(selSession); const features = useSelector(selFeatures); @@ -296,14 +294,6 @@ const Console = ({ classes }: IConsoleProps) => { component: Speedtest, path: IAM_PAGES.TOOLS_SPEEDTEST, }, - { - component: Users, - path: IAM_PAGES.USERS_VIEW, - }, - { - component: Users, - path: IAM_PAGES.USER_ADD, - }, { component: Users, path: IAM_PAGES.USERS, @@ -363,32 +353,12 @@ const Console = ({ classes }: IConsoleProps) => { }, { component: Tools, - path: IAM_PAGES.REGISTER_SUPPORT, - }, - { - component: Tools, - path: IAM_PAGES.CALL_HOME, - }, - { - component: Tools, - path: IAM_PAGES.TOOLS_WATCH, - }, - { - component: Tools, - path: IAM_PAGES.PROFILE, - }, - { - component: Tools, - path: IAM_PAGES.SUPPORT_INSPECT, + path: IAM_PAGES.TOOLS, }, { component: ConfigurationOptions, path: IAM_PAGES.SETTINGS, }, - { - component: ConfigurationOptions, - path: IAM_PAGES.SETTINGS_VIEW, - }, { component: AddNotificationEndpoint, path: IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD_SERVICE, @@ -438,11 +408,6 @@ const Console = ({ classes }: IConsoleProps) => { path: IAM_PAGES.ACCOUNT_ADD, forceDisplay: true, // user has implicit access to service-accounts }, - { - component: UserSACreate, - path: IAM_PAGES.USER_SA_ACCOUNT_ADD, - forceDisplay: true, // user has implicit access to service-accounts - }, { component: License, path: IAM_PAGES.LICENSE, @@ -471,46 +436,6 @@ const Console = ({ classes }: IConsoleProps) => { path: IAM_PAGES.NAMESPACE_TENANT_HOP, forceDisplay: true, }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_PODS, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_PVCS, - forceDisplay: true, - }, - { - component: TenantDetails, - path: `${IAM_PAGES.NAMESPACE_TENANT_SUMMARY}/yaml`, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_SUMMARY, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_METRICS, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_TRACE, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_PODS_LIST, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_POOLS, - forceDisplay: true, - }, { component: AddPool, path: IAM_PAGES.NAMESPACE_TENANT_POOLS_ADD, @@ -521,51 +446,6 @@ const Console = ({ classes }: IConsoleProps) => { path: IAM_PAGES.NAMESPACE_TENANT_POOLS_EDIT, forceDisplay: true, }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_VOLUMES, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_LICENSE, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_IDENTITY_PROVIDER, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_SECURITY, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_ENCRYPTION, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_MONITORING, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_LOGGING, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_EVENTS, - forceDisplay: true, - }, - { - component: TenantDetails, - path: IAM_PAGES.NAMESPACE_TENANT_CSR, - forceDisplay: true, - }, { component: License, path: IAM_PAGES.LICENSE, @@ -603,12 +483,10 @@ const Console = ({ classes }: IConsoleProps) => { } }, [snackBarMessage]); - const location = useLocation(); - let hideMenu = false; if (features?.includes("hide-menu")) { hideMenu = true; - } else if (location.pathname.endsWith("/hop")) { + } else if (pathname.endsWith("/hop")) { hideMenu = true; } @@ -675,35 +553,49 @@ const Console = ({ classes }: IConsoleProps) => { }> - - - {allowedRoutes.map((route: any) => ( - ( - }> - - - )} - /> - ))} - + + {allowedRoutes.map((route: any) => ( + }> + + + } + /> + ))} + }> - - + } + /> + }> - - {allowedRoutes.length > 0 ? ( - - ) : null} - - + } + /> + + {allowedRoutes.length > 0 ? ( + + ) : ( + + )} + + } + /> + ) : null} diff --git a/portal-ui/src/screens/Console/Groups/AddGroupScreen.tsx b/portal-ui/src/screens/Console/Groups/AddGroupScreen.tsx index b8c8efc93..091c56102 100644 --- a/portal-ui/src/screens/Console/Groups/AddGroupScreen.tsx +++ b/portal-ui/src/screens/Console/Groups/AddGroupScreen.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { Theme } from "@mui/material/styles"; +import { useNavigate } from "react-router-dom"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import { @@ -26,7 +27,6 @@ import Grid from "@mui/material/Grid"; import { Button, LinearProgress } from "@mui/material"; import PageHeader from "../Common/PageHeader/PageHeader"; import PageLayout from "../Common/Layout/PageLayout"; -import history from "../../../../src/history"; import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import AddGroupHelpBox from "./AddGroupHelpBox"; import UsersSelectors from "./UsersSelectors"; @@ -65,6 +65,7 @@ const styles = (theme: Theme) => const AddGroupScreen = ({ classes }: IAddGroupProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); const [groupName, setGroupName] = useState(""); const [saving, isSaving] = useState(false); const [selectedUsers, setSelectedUsers] = useState([]); @@ -84,7 +85,7 @@ const AddGroupScreen = ({ classes }: IAddGroupProps) => { }) .then((res) => { isSaving(false); - history.push(`${IAM_PAGES.GROUPS}`); + navigate(`${IAM_PAGES.GROUPS}`); }) .catch((err: ErrorResponseHandler) => { isSaving(false); @@ -94,7 +95,7 @@ const AddGroupScreen = ({ classes }: IAddGroupProps) => { saveRecord(); } - }, [saving, groupName, selectedUsers, dispatch]); + }, [saving, groupName, selectedUsers, dispatch, navigate]); //Fetch Actions const setSaving = (event: React.FormEvent) => { diff --git a/portal-ui/src/screens/Console/Groups/Groups.tsx b/portal-ui/src/screens/Console/Groups/Groups.tsx index a3655d573..18d560611 100644 --- a/portal-ui/src/screens/Console/Groups/Groups.tsx +++ b/portal-ui/src/screens/Console/Groups/Groups.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { Theme } from "@mui/material/styles"; +import { useNavigate } from "react-router-dom"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import Grid from "@mui/material/Grid"; @@ -85,8 +86,10 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -const Groups = ({ classes, history }: IGroupsProps) => { +const Groups = ({ classes }: IGroupsProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const [deleteOpen, setDeleteOpen] = useState(false); const [loading, isLoading] = useState(false); const [records, setRecords] = useState([]); @@ -171,7 +174,7 @@ const Groups = ({ classes, history }: IGroupsProps) => { ); const viewAction = (group: any) => { - history.push(`${IAM_PAGES.GROUPS}/${encodeURLString(group)}`); + navigate(`${IAM_PAGES.GROUPS}/${encodeURLString(group)}`); }; const tableActions = [ @@ -188,7 +191,7 @@ const Groups = ({ classes, history }: IGroupsProps) => { ]; return ( - + {deleteOpen && ( { color="primary" icon={} onClick={() => { - history.push(`${IAM_PAGES.GROUPS_ADD}`); + navigate(`${IAM_PAGES.GROUPS_ADD}`); }} /> @@ -365,7 +368,7 @@ const Groups = ({ classes, history }: IGroupsProps) => { To get started,{" "} { - history.push(`${IAM_PAGES.GROUPS_ADD}`); + navigate(`${IAM_PAGES.GROUPS_ADD}`); }} > Create a Group @@ -381,7 +384,7 @@ const Groups = ({ classes, history }: IGroupsProps) => { )} - + ); }; diff --git a/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx b/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx index 254947c39..261a60c20 100644 --- a/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx +++ b/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx @@ -1,5 +1,6 @@ import React, { Fragment, useEffect, useState } from "react"; import { Theme } from "@mui/material/styles"; +import { useNavigate, useParams } from "react-router-dom"; import createStyles from "@mui/styles/createStyles"; import { actionsTray, @@ -20,7 +21,6 @@ import { TrashIcon, } from "../../../icons"; import TableWrapper from "../Common/TableWrapper/TableWrapper"; -import history from "../../../history"; import api from "../../../common/api"; import SetPolicy from "../Policies/SetPolicy"; import AddGroupMember from "./AddGroupMember"; @@ -92,7 +92,6 @@ const styles = (theme: Theme) => interface IGroupDetailsProps { classes: any; - match: any; } type GroupInfo = { @@ -107,8 +106,11 @@ export const formatPolicy = (policy: string = ""): string[] => { return policy.split(","); }; -const GroupsDetails = ({ classes, match }: IGroupDetailsProps) => { +const GroupsDetails = ({ classes }: IGroupDetailsProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const params = useParams(); + const [groupDetails, setGroupDetails] = useState({}); /*Modals*/ @@ -117,7 +119,7 @@ const GroupsDetails = ({ classes, match }: IGroupDetailsProps) => { const [deleteOpen, setDeleteOpen] = useState(false); const [memberFilter, setMemberFilter] = useState(""); - const groupName = decodeURLString(match.params["groupName"]); + const groupName = decodeURLString(params.groupName || ""); const { members = [], policy = "", status: groupEnabled } = groupDetails; @@ -210,9 +212,7 @@ const GroupsDetails = ({ classes, match }: IGroupDetailsProps) => { { type: "view", onClick: (userName) => { - history.push( - `${IAM_PAGES.USERS}/${encodeURLString(userName)}` - ); + navigate(`${IAM_PAGES.USERS}/${encodeURLString(userName)}`); }, }, ]} @@ -250,9 +250,7 @@ const GroupsDetails = ({ classes, match }: IGroupDetailsProps) => { { type: "view", onClick: (policy) => { - history.push( - `${IAM_PAGES.POLICIES}/${encodeURLString(policy)}` - ); + navigate(`${IAM_PAGES.POLICIES}/${encodeURLString(policy)}`); }, }, ]} @@ -378,7 +376,7 @@ const GroupsDetails = ({ classes, match }: IGroupDetailsProps) => { closeDeleteModalAndRefresh={(isDelSuccess: boolean) => { setDeleteOpen(false); if (isDelSuccess) { - history.push(IAM_PAGES.GROUPS); + navigate(IAM_PAGES.GROUPS); } }} /> diff --git a/portal-ui/src/screens/Console/Menu/ConsoleMenuList.tsx b/portal-ui/src/screens/Console/Menu/ConsoleMenuList.tsx index 7d7527ca5..3f5ffdf7e 100644 --- a/portal-ui/src/screens/Console/Menu/ConsoleMenuList.tsx +++ b/portal-ui/src/screens/Console/Menu/ConsoleMenuList.tsx @@ -16,6 +16,7 @@ import React, { useEffect, useState } from "react"; import { Box } from "@mui/material"; +import { useLocation } from "react-router-dom"; import ListItem from "@mui/material/ListItem"; import ListItemIcon from "@mui/material/ListItemIcon"; import LogoutIcon from "../../../icons/LogoutIcon"; @@ -28,7 +29,6 @@ import { menuItemTextStyles, } from "./MenuStyleUtils"; import MenuItem from "./MenuItem"; -import { useLocation } from "react-router-dom"; import { IAM_PAGES } from "../../../common/SecureComponent/permissions"; diff --git a/portal-ui/src/screens/Console/Menu/Menu.tsx b/portal-ui/src/screens/Console/Menu/Menu.tsx index 01b07f141..7c069bb9a 100644 --- a/portal-ui/src/screens/Console/Menu/Menu.tsx +++ b/portal-ui/src/screens/Console/Menu/Menu.tsx @@ -16,6 +16,7 @@ import React from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; import { Drawer } from "@mui/material"; import withStyles from "@mui/styles/withStyles"; import { Theme } from "@mui/material/styles"; @@ -26,7 +27,7 @@ import { AppState } from "../../../store"; import { ErrorResponseHandler } from "../../../common/types"; import { clearSession } from "../../../common/utils"; -import history, { baseUrl } from "../../../history"; +import { baseUrl } from "../../../history"; import api from "../../../common/api"; import MenuToggle from "./MenuToggle"; @@ -90,6 +91,7 @@ interface IMenuProps { const Menu = ({ classes }: IMenuProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); const features = useSelector(selFeatures); @@ -105,7 +107,7 @@ const Menu = ({ classes }: IMenuProps) => { localStorage.setItem("userLoggedIn", ""); localStorage.setItem("redirect-path", ""); dispatch(resetSession()); - history.push(`${baseUrl}login`); + navigate(`${baseUrl}login`); }; api .invoke("POST", `/api/v1/logout`) diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/AddNotificationEndpoint.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/AddNotificationEndpoint.tsx index 65dbb75b9..32e6fae67 100644 --- a/portal-ui/src/screens/Console/NotificationEndpoints/AddNotificationEndpoint.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/AddNotificationEndpoint.tsx @@ -39,7 +39,6 @@ import { ErrorResponseHandler } from "../../../common/types"; import { IElementValue } from "../Configurations/types"; import PageHeader from "../Common/PageHeader/PageHeader"; -import history from "../../../history"; import withSuspense from "../Common/Components/withSuspense"; import BackLink from "../../../common/BackLink"; @@ -49,6 +48,7 @@ import { setErrorSnackMessage, setServerNeedsRestart, } from "../../../systemSlice"; +import { useNavigate, useParams } from "react-router-dom"; const ConfMySql = withSuspense( React.lazy(() => import("./CustomForms/ConfMySql")) @@ -106,21 +106,22 @@ const styles = (theme: Theme) => }); interface IAddNotificationEndpointProps { - match: any; saveAndRefresh: any; classes: any; } const AddNotificationEndpoint = ({ - match, saveAndRefresh, classes, }: IAddNotificationEndpointProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const params = useParams(); + //Local States const [valuesArr, setValueArr] = useState([]); const [saving, setSaving] = useState(false); - const service = match.params["service"]; + const service = params.service || ""; //Effects useEffect(() => { @@ -133,14 +134,14 @@ const AddNotificationEndpoint = ({ .then(() => { setSaving(false); dispatch(setServerNeedsRestart(true)); - history.push(IAM_PAGES.NOTIFICATIONS_ENDPOINTS); + navigate(IAM_PAGES.NOTIFICATIONS_ENDPOINTS); }) .catch((err: ErrorResponseHandler) => { setSaving(false); dispatch(setErrorSnackMessage(err)); }); } - }, [saving, service, valuesArr, saveAndRefresh, dispatch]); + }, [saving, service, valuesArr, saveAndRefresh, dispatch, navigate]); //Fetch Actions const submitForm = (event: React.FormEvent) => { diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx index 5b417fc1e..e749666f8 100644 --- a/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useCallback, useEffect, useState } from "react"; import { useDispatch } from "react-redux"; +import { useNavigate } from "react-router-dom"; import get from "lodash/get"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; @@ -58,17 +59,17 @@ const styles = (theme: Theme) => interface IAddNotificationEndpointProps { selectedConfiguration: IConfigurationElement; classes: any; - history: any; className?: string; } const EditConfiguration = ({ selectedConfiguration, classes, - history, className = "", }: IAddNotificationEndpointProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + //Local States const [valuesObj, setValueObj] = useState([]); const [saving, setSaving] = useState(false); @@ -115,14 +116,14 @@ const EditConfiguration = ({ setSaving(false); dispatch(setServerNeedsRestart(res.restart)); - history.push("/settings"); + navigate("/settings"); }) .catch((err: ErrorResponseHandler) => { setSaving(false); dispatch(setErrorSnackMessage(err)); }); } - }, [saving, history, dispatch, selectedConfiguration, valuesObj]); + }, [saving, dispatch, selectedConfiguration, valuesObj, navigate]); //Fetch Actions const submitForm = (event: React.FormEvent) => { diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx index 7753e6c8c..a2070e4b8 100644 --- a/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch } from "react-redux"; +import { useNavigate } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; @@ -42,7 +43,6 @@ import { import { ErrorResponseHandler } from "../../../common/types"; import api from "../../../common/api"; import RefreshIcon from "../../../icons/RefreshIcon"; -import history from "../../../history"; import HelpBox from "../../../common/HelpBox"; import AButton from "../Common/AButton/AButton"; import PageLayout from "../Common/Layout/PageLayout"; @@ -81,6 +81,7 @@ const styles = (theme: Theme) => const ListNotificationEndpoints = ({ classes }: IListNotificationEndpoints) => { const dispatch = useDispatch(); + const navigate = useNavigate(); //Local States const [records, setRecords] = useState([]); const [filter, setFilter] = useState(""); @@ -166,7 +167,7 @@ const ListNotificationEndpoints = ({ classes }: IListNotificationEndpoints) => { color="primary" icon={} onClick={() => { - history.push(IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD); + navigate(IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD); }} /> @@ -246,7 +247,7 @@ const ListNotificationEndpoints = ({ classes }: IListNotificationEndpoints) => { To get started,{" "} { - history.push(IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD); + navigate(IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD); }} > Add a Notification Target diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/NotificationTypeSelector.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/NotificationTypeSelector.tsx index a0453be43..943b3a2ef 100644 --- a/portal-ui/src/screens/Console/NotificationEndpoints/NotificationTypeSelector.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/NotificationTypeSelector.tsx @@ -16,6 +16,7 @@ import React, { Fragment } from "react"; import { Theme } from "@mui/material/styles"; +import { useNavigate } from "react-router-dom"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import { servicesList } from "./utils"; @@ -24,7 +25,6 @@ import { typesSelection, } from "../Common/FormComponents/common/styleLibrary"; import PageHeader from "../Common/PageHeader/PageHeader"; -import history from "../../../history"; import BackLink from "../../../common/BackLink"; import PageLayout from "../Common/Layout/PageLayout"; import { IAM_PAGES } from "../../../common/SecureComponent/permissions"; @@ -43,6 +43,7 @@ const styles = (theme: Theme) => }); const NotificationTypeSelector = ({ classes }: INotificationTypeSelector) => { + const navigate = useNavigate(); return ( { key={`icon-${item.targetTitle}`} className={classes.lambdaNotif} onClick={() => { - history.push( + navigate( `${IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD}/${item.actionTrigger}` ); }} diff --git a/portal-ui/src/screens/Console/ObjectBrowser/BrowserBreadcrumbs.tsx b/portal-ui/src/screens/Console/ObjectBrowser/BrowserBreadcrumbs.tsx index 3242b513c..c07820f73 100644 --- a/portal-ui/src/screens/Console/ObjectBrowser/BrowserBreadcrumbs.tsx +++ b/portal-ui/src/screens/Console/ObjectBrowser/BrowserBreadcrumbs.tsx @@ -21,7 +21,7 @@ import Grid from "@mui/material/Grid"; import withStyles from "@mui/styles/withStyles"; import createStyles from "@mui/styles/createStyles"; import { Theme } from "@mui/material/styles"; -import { Link } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import { Button, IconButton, Tooltip } from "@mui/material"; import { objectBrowserCommon } from "../Common/FormComponents/common/styleLibrary"; import { encodeURLString } from "../../../common/utils"; @@ -29,7 +29,6 @@ import { BackCaretIcon, CopyIcon, NewPathIcon } from "../../../icons"; import { hasPermission } from "../../../common/SecureComponent"; import { IAM_SCOPES } from "../../../common/SecureComponent/permissions"; import { BucketObjectItem } from "../Buckets/ListBuckets/Objects/ListObjects/types"; -import history from "../../../history"; import withSuspense from "../Common/Components/withSuspense"; import { setSnackBarMessage } from "../../../systemSlice"; import { AppState } from "../../../store"; @@ -68,6 +67,7 @@ const BrowserBreadcrumbs = ({ additionalOptions, }: IObjectBrowser) => { const dispatch = useDispatch(); + const navigate = useNavigate(); const rewindEnabled = useSelector( (state: AppState) => state.objectBrowser.rewind.rewindEnabled @@ -157,7 +157,7 @@ const BrowserBreadcrumbs = ({ if (versionsMode) { dispatch(setVersionsModeEnabled({ status: false, objectName: "" })); } else { - history.goBack(); + navigate(-1); } }; diff --git a/portal-ui/src/screens/Console/Policies/AddPolicyScreen.tsx b/portal-ui/src/screens/Console/Policies/AddPolicyScreen.tsx index a9a6e8ce6..174865a64 100644 --- a/portal-ui/src/screens/Console/Policies/AddPolicyScreen.tsx +++ b/portal-ui/src/screens/Console/Policies/AddPolicyScreen.tsx @@ -25,7 +25,6 @@ import { import Grid from "@mui/material/Grid"; import { Box, Button } from "@mui/material"; import PageHeader from "../Common/PageHeader/PageHeader"; -import history from "../../../../src/history"; import PageLayout from "../Common/Layout/PageLayout"; import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import AddPolicyHelpBox from "./AddPolicyHelpBox"; @@ -38,6 +37,7 @@ import { ErrorResponseHandler } from "../../../../src/common/types"; import api from "../../../../src/common/api"; import FormLayout from "../Common/FormLayout"; import { setErrorSnackMessage } from "../../../systemSlice"; +import { useNavigate } from "react-router-dom"; interface IAddPolicyProps { classes: any; @@ -64,6 +64,7 @@ const styles = (theme: Theme) => const AddPolicyScreen = ({ classes }: IAddPolicyProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); const [addLoading, setAddLoading] = useState(false); const [policyName, setPolicyName] = useState(""); @@ -82,7 +83,7 @@ const AddPolicyScreen = ({ classes }: IAddPolicyProps) => { }) .then((res) => { setAddLoading(false); - history.push(`${IAM_PAGES.POLICIES}`); + navigate(`${IAM_PAGES.POLICIES}`); }) .catch((err: ErrorResponseHandler) => { setAddLoading(false); diff --git a/portal-ui/src/screens/Console/Policies/ListPolicies.tsx b/portal-ui/src/screens/Console/Policies/ListPolicies.tsx index 378b9b1e3..1df5092f5 100644 --- a/portal-ui/src/screens/Console/Policies/ListPolicies.tsx +++ b/portal-ui/src/screens/Console/Policies/ListPolicies.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch } from "react-redux"; +import { useNavigate } from "react-router-dom"; import get from "lodash/get"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; @@ -34,7 +35,6 @@ import { ErrorResponseHandler } from "../../../common/types"; import TableWrapper from "../Common/TableWrapper/TableWrapper"; import PageHeader from "../Common/PageHeader/PageHeader"; import api from "../../../common/api"; -import history from "../../../history"; import HelpBox from "../../../common/HelpBox"; import PageLayout from "../Common/Layout/PageLayout"; import { @@ -72,6 +72,7 @@ interface IPoliciesProps { const ListPolicies = ({ classes }: IPoliciesProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); const [records, setRecords] = useState([]); const [loading, setLoading] = useState(false); @@ -145,7 +146,7 @@ const ListPolicies = ({ classes }: IPoliciesProps) => { }; const viewAction = (policy: any) => { - history.push(`${IAM_PAGES.POLICIES}/${encodeURLString(policy.name)}`); + navigate(`${IAM_PAGES.POLICIES}/${encodeURLString(policy.name)}`); }; const tableActions = [ @@ -198,7 +199,7 @@ const ListPolicies = ({ classes }: IPoliciesProps) => { color="primary" icon={} onClick={() => { - history.push(`${IAM_PAGES.POLICY_ADD}`); + navigate(`${IAM_PAGES.POLICY_ADD}`); }} /> diff --git a/portal-ui/src/screens/Console/Policies/Policies.tsx b/portal-ui/src/screens/Console/Policies/Policies.tsx index b7ac9daaf..5dc043b93 100644 --- a/portal-ui/src/screens/Console/Policies/Policies.tsx +++ b/portal-ui/src/screens/Console/Policies/Policies.tsx @@ -2,34 +2,22 @@ // along with this program. If not, see . import React from "react"; -import history from "../../../history"; -import { Route, Router, Switch, withRouter } from "react-router-dom"; +import { Route, Routes } from "react-router-dom"; import NotFoundPage from "../../NotFoundPage"; import withSuspense from "../Common/Components/withSuspense"; -import { IAM_PAGES } from "../../../common/SecureComponent/permissions"; const ListPolicies = withSuspense(React.lazy(() => import("./ListPolicies"))); const PolicyDetails = withSuspense(React.lazy(() => import("./PolicyDetails"))); const Policies = () => { return ( - - - - - - - - + + } /> + } /> + } /> + ); }; -export default withRouter(Policies); +export default Policies; diff --git a/portal-ui/src/screens/Console/Policies/PolicyDetails.tsx b/portal-ui/src/screens/Console/Policies/PolicyDetails.tsx index 1f74fd22e..1e51192ec 100644 --- a/portal-ui/src/screens/Console/Policies/PolicyDetails.tsx +++ b/portal-ui/src/screens/Console/Policies/PolicyDetails.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { IAMPolicy, IAMStatement, Policy } from "./types"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate, useParams } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; @@ -34,7 +35,6 @@ import PageHeader from "../Common/PageHeader/PageHeader"; import { ErrorResponseHandler } from "../../../common/types"; import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper"; -import history from "../../../history"; import InputAdornment from "@mui/material/InputAdornment"; import TextField from "@mui/material/TextField"; import ScreenTitle from "../Common/ScreenTitle/ScreenTitle"; @@ -95,11 +95,12 @@ const styles = (theme: Theme) => interface IPolicyDetailsProps { classes: any; - match: any; } -const PolicyDetails = ({ classes, match }: IPolicyDetailsProps) => { +const PolicyDetails = ({ classes }: IPolicyDetailsProps) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const params = useParams(); const features = useSelector(selFeatures); @@ -109,7 +110,7 @@ const PolicyDetails = ({ classes, match }: IPolicyDetailsProps) => { const [groupList, setGroupList] = useState([]); const [addLoading, setAddLoading] = useState(false); - const policyName = decodeURLString(match.params["policyName"]); + const policyName = decodeURLString(params.policyName || ""); const [policyDefinition, setPolicyDefinition] = useState(""); const [loadingPolicy, setLoadingPolicy] = useState(true); @@ -279,11 +280,11 @@ const PolicyDetails = ({ classes, match }: IPolicyDetailsProps) => { const closeDeleteModalAndRefresh = (refresh: boolean) => { setDeleteOpen(false); - history.push(IAM_PAGES.POLICIES); + navigate(IAM_PAGES.POLICIES); }; const userViewAction = (user: any) => { - history.push(`${IAM_PAGES.USERS}/${encodeURLString(user)}`); + navigate(`${IAM_PAGES.USERS}/${encodeURLString(user)}`); }; const userTableActions = [ { @@ -298,7 +299,7 @@ const PolicyDetails = ({ classes, match }: IPolicyDetailsProps) => { ); const groupViewAction = (group: any) => { - history.push(`${IAM_PAGES.GROUPS}/${encodeURLString(group)}`); + navigate(`${IAM_PAGES.GROUPS}/${encodeURLString(group)}`); }; const groupTableActions = [ diff --git a/portal-ui/src/screens/Console/Support/Register.tsx b/portal-ui/src/screens/Console/Support/Register.tsx index 76229439f..7a54ffe1c 100644 --- a/portal-ui/src/screens/Console/Support/Register.tsx +++ b/portal-ui/src/screens/Console/Support/Register.tsx @@ -66,7 +66,6 @@ import { selOpMode, setErrorSnackMessage } from "../../../systemSlice"; interface IRegister { classes: any; - operatorMode: boolean; } const styles = (theme: Theme) => diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx b/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx index 08a0dbcea..a2dc29dab 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx @@ -39,7 +39,6 @@ import Security from "./Steps/Security"; import Encryption from "./Steps/Encryption"; import Affinity from "./Steps/Affinity"; import PageHeader from "../../Common/PageHeader/PageHeader"; -import history from "../../../../history"; import Images from "./Steps/Images"; import PageLayout from "../../Common/Layout/PageLayout"; import BackLink from "../../../../common/BackLink"; @@ -57,6 +56,7 @@ import makeStyles from "@mui/styles/makeStyles"; import { resetAddTenantForm } from "./createTenantSlice"; import CreateTenantButton from "./CreateTenantButton"; import NewTenantCredentials from "./NewTenantCredentials"; +import { useNavigate } from "react-router-dom"; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -71,6 +71,7 @@ const useStyles = makeStyles((theme: Theme) => const AddTenant = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); const classes = useStyles(); const features = useSelector(selFeatures); @@ -107,7 +108,7 @@ const AddTenant = () => { enabled: true, action: () => { dispatch(resetAddTenantForm()); - history.push("/tenants"); + navigate("/tenants"); }, }; diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/NewTenantCredentials.tsx b/portal-ui/src/screens/Console/Tenants/AddTenant/NewTenantCredentials.tsx index c22c448ce..53184bc70 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/NewTenantCredentials.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/NewTenantCredentials.tsx @@ -17,12 +17,13 @@ import React, { Fragment } from "react"; import CredentialsPrompt from "../../Common/CredentialsPrompt/CredentialsPrompt"; import { resetAddTenantForm } from "./createTenantSlice"; -import history from "../../../../history"; import { useDispatch, useSelector } from "react-redux"; import { AppState } from "../../../../store"; +import { useNavigate } from "react-router-dom"; const NewTenantCredentials = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); const showNewCredentials = useSelector( (state: AppState) => state.createTenant.showNewCredentials @@ -39,7 +40,7 @@ const NewTenantCredentials = () => { open={showNewCredentials} closeModal={() => { dispatch(resetAddTenantForm()); - history.push("/tenants"); + navigate("/tenants"); }} entity="Tenant" /> diff --git a/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx b/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx index 87b17d316..a56e637e3 100644 --- a/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx +++ b/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx @@ -33,7 +33,6 @@ import { import { AddIcon, TenantsIcon } from "../../../../icons"; import { ErrorResponseHandler } from "../../../../common/types"; import api from "../../../../common/api"; -import history from "../../../../history"; import RefreshIcon from "../../../../icons/RefreshIcon"; import PageHeader from "../../Common/PageHeader/PageHeader"; import TenantListItem from "./TenantListItem"; @@ -47,6 +46,7 @@ import SearchBox from "../../Common/SearchBox"; import PageLayout from "../../Common/Layout/PageLayout"; import { setErrorSnackMessage } from "../../../../systemSlice"; import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; +import { useNavigate } from "react-router-dom"; const CredentialsPrompt = withSuspense( React.lazy(() => import("../../Common/CredentialsPrompt/CredentialsPrompt")) @@ -109,6 +109,8 @@ const styles = (theme: Theme) => const ListTenants = ({ classes }: ITenantsList) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const [isLoading, setIsLoading] = useState(false); const [filterTenants, setFilterTenants] = useState(""); const [records, setRecords] = useState([]); @@ -283,7 +285,7 @@ const ListTenants = ({ classes }: ITenantsList) => { tooltip={"Create Tenant"} text={"Create Tenant"} onClick={() => { - history.push("/tenants/add"); + navigate("/tenants/add"); }} icon={} color="primary" @@ -360,7 +362,7 @@ const ListTenants = ({ classes }: ITenantsList) => { To get started,  { - history.push("/tenants/add"); + navigate("/tenants/add"); }} > Create a Tenant. diff --git a/portal-ui/src/screens/Console/Tenants/ListTenants/TenantListItem.tsx b/portal-ui/src/screens/Console/Tenants/ListTenants/TenantListItem.tsx index 974ec8277..5423cc9e5 100644 --- a/portal-ui/src/screens/Console/Tenants/ListTenants/TenantListItem.tsx +++ b/portal-ui/src/screens/Console/Tenants/ListTenants/TenantListItem.tsx @@ -15,20 +15,19 @@ // along with this program. If not, see . import React, { Fragment } from "react"; -import { CapacityValues, ITenant, ValueUnit } from "./types"; - -import Grid from "@mui/material/Grid"; -import history from "../../../../history"; +import { useDispatch } from "react-redux"; +import { useNavigate } from "react-router-dom"; import { Theme } from "@mui/material/styles"; -import createStyles from "@mui/styles/createStyles"; -import withStyles from "@mui/styles/withStyles"; -import { niceBytes, niceBytesInt } from "../../../../common/utils"; -import InformationItem from "./InformationItem"; -import TenantCapacity from "./TenantCapacity"; -import { DrivesIcon } from "../../../../icons"; +import { CapacityValues, ITenant, ValueUnit } from "./types"; import { setTenantName } from "../tenantsSlice"; import { getTenantAsync } from "../thunks/tenantDetailsAsync"; -import { useDispatch } from "react-redux"; +import { DrivesIcon } from "../../../../icons"; +import { niceBytes, niceBytesInt } from "../../../../common/utils"; +import Grid from "@mui/material/Grid"; +import createStyles from "@mui/styles/createStyles"; +import withStyles from "@mui/styles/withStyles"; +import InformationItem from "./InformationItem"; +import TenantCapacity from "./TenantCapacity"; const styles = (theme: Theme) => createStyles({ @@ -108,6 +107,8 @@ interface ITenantListItem { const TenantListItem = ({ tenant, classes }: ITenantListItem) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const healthStatusToClass = (health_status: string) => { switch (health_status) { case "red": @@ -185,7 +186,7 @@ const TenantListItem = ({ tenant, classes }: ITenantListItem) => { }) ); dispatch(getTenantAsync()); - history.push(`/namespaces/${tenant.namespace}/tenants/${tenant.name}`); + navigate(`/namespaces/${tenant.namespace}/tenants/${tenant.name}`); }; return ( diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/PodsSummary.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/PodsSummary.tsx index f34bc06ff..f44881132 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/PodsSummary.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/PodsSummary.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate, useParams } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; @@ -38,8 +39,6 @@ import { setErrorSnackMessage } from "../../../../systemSlice"; interface IPodsSummary { classes: any; - match: any; - history: any; } const styles = (theme: Theme) => @@ -49,8 +48,10 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -const PodsSummary = ({ classes, match, history }: IPodsSummary) => { +const PodsSummary = ({ classes }: IPodsSummary) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const { tenantName, tenantNamespace } = useParams(); const loadingTenant = useSelector( (state: AppState) => state.tenants.loadingTenant @@ -61,12 +62,12 @@ const PodsSummary = ({ classes, match, history }: IPodsSummary) => { const [deleteOpen, setDeleteOpen] = useState(false); const [selectedPod, setSelectedPod] = useState(null); const [filter, setFilter] = useState(""); - const tenantName = match.params["tenantName"]; - const tenantNamespace = match.params["tenantNamespace"]; const podViewAction = (pod: IPodListElement) => { - history.push( - `/namespaces/${tenantNamespace}/tenants/${tenantName}/pods/${pod.name}` + navigate( + `/namespaces/${tenantNamespace || ""}/tenants/${tenantName || ""}/pods/${ + pod.name + }` ); return; }; @@ -103,7 +104,9 @@ const PodsSummary = ({ classes, match, history }: IPodsSummary) => { api .invoke( "GET", - `/api/v1/namespaces/${tenantNamespace}/tenants/${tenantName}/pods` + `/api/v1/namespaces/${tenantNamespace || ""}/tenants/${ + tenantName || "" + }/pods` ) .then((result: IPodListElement[]) => { for (let i = 0; i < result.length; i++) { diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/AddPool.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/AddPool.tsx index 30051426f..76ca5af30 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/AddPool.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/AddPool.tsx @@ -14,8 +14,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import React, { Fragment } from "react"; +import React, { Fragment, useEffect } from "react"; import { Theme } from "@mui/material/styles"; +import { useNavigate } from "react-router-dom"; import createStyles from "@mui/styles/createStyles"; import { formFieldStyles, @@ -28,7 +29,6 @@ import PageHeader from "../../../../Common/PageHeader/PageHeader"; import PageLayout from "../../../../Common/Layout/PageLayout"; import GenericWizard from "../../../../Common/GenericWizard/GenericWizard"; import { IWizardElement } from "../../../../Common/GenericWizard/types"; -import history from "../../../../../../history"; import PoolResources from "./PoolResources"; import ScreenTitle from "../../../../Common/ScreenTitle/ScreenTitle"; import TenantsIcon from "../../../../../../icons/TenantsIcon"; @@ -72,22 +72,32 @@ const useStyles = makeStyles((theme: Theme) => const AddPool = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); const classes = useStyles(); const tenant = useSelector((state: AppState) => state.tenants.tenantInfo); const sending = useSelector((state: AppState) => state.addPool.sending); + const navigateTo = useSelector((state: AppState) => state.addPool.navigateTo); const poolsURL = `/namespaces/${tenant?.namespace || ""}/tenants/${ tenant?.name || "" }/pools`; + useEffect(() => { + if (navigateTo !== "") { + const goTo = `${navigateTo}`; + dispatch(resetPoolForm()); + navigate(goTo); + } + }, [navigateTo, navigate, dispatch]); + const cancelButton = { label: "Cancel", type: "other", enabled: true, action: () => { dispatch(resetPoolForm()); - history.push(poolsURL); + navigate(poolsURL); }, }; diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/addPoolSlice.ts b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/addPoolSlice.ts index 253c5b0de..b5b4fd47f 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/addPoolSlice.ts +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/addPoolSlice.ts @@ -41,6 +41,7 @@ export interface IAddPool { configuration: IPoolConfiguration; tolerations: ITolerationModel[]; nodeSelectorPairs: LabelKeyPair[]; + navigateTo: string; } const initialState: IAddPool = { @@ -49,6 +50,7 @@ const initialState: IAddPool = { validPages: ["affinity", "configure"], storageClasses: [], limitSize: {}, + navigateTo: "", setup: { numberOfNodes: 0, storageClass: "", @@ -171,6 +173,9 @@ export const addPoolSlice = createSlice({ }) .addCase(addPoolAsync.fulfilled, (state, action) => { state.sending = false; + if (action.payload) { + state.navigateTo = action.payload; + } }); }, }); diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/addPoolThunks.ts b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/addPoolThunks.ts index 54f91a9d3..e17ff090b 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/addPoolThunks.ts +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/AddPool/addPoolThunks.ts @@ -16,7 +16,6 @@ import { createAsyncThunk } from "@reduxjs/toolkit"; import { AppState } from "../../../../../../store"; -import api from "../../../../../../common/api"; import { IAddPoolRequest } from "../../../ListTenants/types"; import { generatePoolName } from "../../../../../../common/utils"; import { ErrorResponseHandler } from "../../../../../../common/types"; @@ -24,7 +23,7 @@ import { setErrorSnackMessage } from "../../../../../../systemSlice"; import { getDefaultAffinity, getNodeSelector } from "../../utils"; import { resetPoolForm } from "./addPoolSlice"; import { getTenantAsync } from "../../../thunks/tenantDetailsAsync"; -import history from "../../../../../../history"; +import api from "../../../../../../common/api"; export const addPoolAsync = createAsyncThunk( "addPool/addPoolAsync", @@ -98,7 +97,7 @@ export const addPoolAsync = createAsyncThunk( .then(() => { dispatch(resetPoolForm()); dispatch(getTenantAsync()); - history.push(poolsURL); + return poolsURL; }) .catch((err: ErrorResponseHandler) => { dispatch(setErrorSnackMessage(err)); diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/Details/PoolDetails.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/Details/PoolDetails.tsx index 149054931..d4e6eb5ef 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/Details/PoolDetails.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/Details/PoolDetails.tsx @@ -16,17 +16,7 @@ import React, { Fragment } from "react"; import { useSelector } from "react-redux"; -import { Theme } from "@mui/material/styles"; -import createStyles from "@mui/styles/createStyles"; -import withStyles from "@mui/styles/withStyles"; -import { - containerForHeader, - spacingUtils, - tableStyles, - tenantDetailsStyles, - textStyleUtils, -} from "../../../../Common/FormComponents/common/styleLibrary"; - +import { useNavigate } from "react-router-dom"; import { AppState } from "../../../../../../store"; import { Box } from "@mui/material"; import Grid from "@mui/material/Grid"; @@ -36,20 +26,6 @@ import StackRow from "../../../../Common/UsageBarWrapper/StackRow"; import RBIconButton from "../../../../Buckets/BucketDetails/SummaryItems/RBIconButton"; import { EditTenantIcon } from "../../../../../../icons"; -interface IPoolDetails { - classes: any; - history: any; -} - -const styles = (theme: Theme) => - createStyles({ - ...spacingUtils, - ...textStyleUtils, - ...tenantDetailsStyles, - ...tableStyles, - ...containerForHeader(theme.spacing(4)), - }); - const stylingLayout = { border: "#EAEAEA 1px solid", borderRadius: "3px", @@ -65,7 +41,9 @@ const twoColCssGridLayoutConfig = { padding: "15px", }; -const PoolDetails = ({ history }: IPoolDetails) => { +const PoolDetails = () => { + const navigate = useNavigate(); + const tenant = useSelector((state: AppState) => state.tenants.tenantInfo); const selectedPool = useSelector( (state: AppState) => state.tenants.selectedPool @@ -109,7 +87,7 @@ const PoolDetails = ({ history }: IPoolDetails) => { } onClick={() => { - history.push( + navigate( `/namespaces/${tenant?.namespace || ""}/tenants/${ tenant?.name || "" }/edit-pool` @@ -277,4 +255,4 @@ const PoolDetails = ({ history }: IPoolDetails) => { ); }; -export default withStyles(styles)(PoolDetails); +export default PoolDetails; diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/Details/PoolsListing.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/Details/PoolsListing.tsx index ec767afb8..c92864586 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/Details/PoolsListing.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/Details/PoolsListing.tsx @@ -18,7 +18,7 @@ import React, { Fragment, useEffect, useState } from "react"; import withStyles from "@mui/styles/withStyles"; import { AppState } from "../../../../../../store"; import { useDispatch, useSelector } from "react-redux"; - +import { useNavigate } from "react-router-dom"; import { IPool } from "../../../ListTenants/types"; import Grid from "@mui/material/Grid"; import { TextField } from "@mui/material"; @@ -39,7 +39,6 @@ import { setSelectedPool } from "../../../tenantsSlice"; interface IPoolsSummary { classes: any; - history: any; setPoolDetailsView: () => void; } @@ -51,12 +50,9 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -const PoolsListing = ({ - classes, - history, - setPoolDetailsView, -}: IPoolsSummary) => { +const PoolsListing = ({ classes, setPoolDetailsView }: IPoolsSummary) => { const dispatch = useDispatch(); + const navigate = useNavigate(); const loadingTenant = useSelector( (state: AppState) => state.tenants.loadingTenant @@ -117,7 +113,7 @@ const PoolsListing = ({ tooltip={"Expand Tenant"} text={"Expand Tenant"} onClick={() => { - history.push( + navigate( `/namespaces/${tenant?.namespace || ""}/tenants/${ tenant?.name || "" }/add-pool` diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/EditPool.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/EditPool.tsx index e35d3a908..824264d5a 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/EditPool.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/EditPool.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import Grid from "@mui/material/Grid"; @@ -28,7 +29,6 @@ import BackLink from "../../../../../../common/BackLink"; import EditPoolResources from "./EditPoolResources"; import EditPoolConfiguration from "./EditPoolConfiguration"; import EditPoolPlacement from "./EditPoolPlacement"; -import history from "../../../../../../history"; import { IWizardElement } from "../../../../Common/GenericWizard/types"; import { LinearProgress } from "@mui/material"; import { niceBytes } from "../../../../../../common/utils"; @@ -72,6 +72,8 @@ const useStyles = makeStyles((theme: Theme) => const EditPool = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const classes = useStyles(); const tenant = useSelector((state: AppState) => state.tenants.tenantInfo); @@ -82,6 +84,9 @@ const EditPool = () => { const editSending = useSelector( (state: AppState) => state.editPool.editSending ); + const navigateTo = useSelector( + (state: AppState) => state.editPool.navigateTo + ); const poolsURL = `/namespaces/${tenant?.namespace || ""}/tenants/${ tenant?.name || "" @@ -96,10 +101,18 @@ const EditPool = () => { if (poolDetails) { dispatch(setInitialPoolDetails(poolDetails)); } else { - history.push("/tenants"); + navigate("/tenants"); } } - }, [selectedPool, dispatch, tenant]); + }, [selectedPool, dispatch, tenant, navigate]); + + useEffect(() => { + if (navigateTo !== "") { + const goTo = `${navigateTo}`; + dispatch(resetEditPoolForm()); + navigate(goTo); + } + }, [navigateTo, navigate, dispatch]); const cancelButton = { label: "Cancel", @@ -107,7 +120,7 @@ const EditPool = () => { enabled: true, action: () => { dispatch(resetEditPoolForm()); - history.push(poolsURL); + navigate(poolsURL); }, }; diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/editPoolSlice.ts b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/editPoolSlice.ts index fd59f5967..03f90276e 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/editPoolSlice.ts +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/editPoolSlice.ts @@ -65,6 +65,7 @@ const initialState: IEditPool = { ], }, editSending: false, + navigateTo: "", }; export const editPoolSlice = createSlice({ @@ -257,6 +258,9 @@ export const editPoolSlice = createSlice({ }) .addCase(editPoolAsync.fulfilled, (state, action) => { state.editSending = false; + if (action.payload) { + state.navigateTo = action.payload; + } }); }, }); diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/thunks/editPoolAsync.ts b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/thunks/editPoolAsync.ts index 11476aa3a..1ac593c64 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/thunks/editPoolAsync.ts +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/thunks/editPoolAsync.ts @@ -22,7 +22,6 @@ import { setErrorSnackMessage } from "../../../../../../../systemSlice"; import { generatePoolName } from "../../../../../../../common/utils"; import { getDefaultAffinity, getNodeSelector } from "../../../utils"; import { IEditPoolItem, IEditPoolRequest } from "../../../../ListTenants/types"; -import history from "../../../../../../../history"; import { resetEditPoolForm } from "../editPoolSlice"; import { setTenantDetailsLoad } from "../../../../tenantsSlice"; @@ -117,7 +116,7 @@ export const editPoolAsync = createAsyncThunk( }, ], }; - const poolsURL = `/namespaces/${tenant?.namespace || ""}/tenants/${ + const poolsURL: string = `/namespaces/${tenant?.namespace || ""}/tenants/${ tenant?.name || "" }/pools`; @@ -130,7 +129,7 @@ export const editPoolAsync = createAsyncThunk( .then(() => { dispatch(resetEditPoolForm()); dispatch(setTenantDetailsLoad(true)); - history.push(poolsURL); + return poolsURL; }) .catch((err: ErrorResponseHandler) => { dispatch(setErrorSnackMessage(err)); diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/types.ts b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/types.ts index 5730d63c4..f2e6b3c04 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/types.ts +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/Pools/EditPool/types.ts @@ -44,6 +44,7 @@ export interface IEditPool { limitSize: any; fields: IEditPoolFields; editSending: boolean; + navigateTo: string; } export interface PageFieldValue { diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/PoolsSummary.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/PoolsSummary.tsx index 97b5028bf..5155792fc 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/PoolsSummary.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/PoolsSummary.tsx @@ -17,6 +17,7 @@ import React, { Fragment } from "react"; import { useDispatch, useSelector } from "react-redux"; import { Theme } from "@mui/material/styles"; +import { useLocation } from "react-router-dom"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import { @@ -36,8 +37,6 @@ import { setOpenPoolDetails } from "../tenantsSlice"; interface IPoolsSummary { classes: any; - history: any; - match: any; } const styles = (theme: Theme) => @@ -48,8 +47,9 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -const PoolsSummary = ({ classes, history, match }: IPoolsSummary) => { +const PoolsSummary = ({ classes }: IPoolsSummary) => { const dispatch = useDispatch(); + const { pathname = "" } = useLocation(); const selectedPool = useSelector( (state: AppState) => state.tenants.selectedPool @@ -67,7 +67,7 @@ const PoolsSummary = ({ classes, history, match }: IPoolsSummary) => { dispatch(setOpenPoolDetails(false)); }} label={"Pools list"} - to={match.url} + to={pathname} /> )} @@ -76,13 +76,12 @@ const PoolsSummary = ({ classes, history, match }: IPoolsSummary) => { {poolDetailsOpen ? ( - + ) : ( { dispatch(setOpenPoolDetails(true)); }} - history={history} /> )} diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantCSR.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantCSR.tsx index e70407e3c..4c64f4a57 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantCSR.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantCSR.tsx @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import React, { useEffect, useState, Fragment } from "react"; -import { useDispatch } from "react-redux"; +import React, { Fragment, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; @@ -35,12 +35,11 @@ import TableHead from "@mui/material/TableHead"; import TableRow from "@mui/material/TableRow"; import TableCell from "@mui/material/TableCell"; import TableBody from "@mui/material/TableBody"; +import { useParams } from "react-router-dom"; +import { AppState } from "../../../../store"; interface ITenantCSRProps { classes: any; - match: any; - loadingTenant: boolean; - setErrorSnackMessage: typeof setErrorSnackMessage; } const styles = (theme: Theme) => @@ -54,19 +53,19 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -const TenantCSR = ({ - classes, - match, - loadingTenant, - setErrorSnackMessage, -}: ITenantCSRProps) => { +const TenantCSR = ({ classes }: ITenantCSRProps) => { + const dispatch = useDispatch(); + const { tenantName, tenantNamespace } = useParams(); + + const loadingTenant = useSelector( + (state: AppState) => state.tenants.loadingTenant + ); + const [loading, setLoading] = useState(true); - const tenantName = match.params["tenantName"]; - const tenantNamespace = match.params["tenantNamespace"]; const [csrStatus] = useState([""]); const [csrName] = useState([""]); const [csrAnnotations] = useState([""]); - const dispatch = useDispatch(); + useEffect(() => { if (loadingTenant) { setLoading(true); @@ -78,7 +77,9 @@ const TenantCSR = ({ api .invoke( "GET", - `/api/v1/namespaces/${tenantNamespace}/tenants/${tenantName}/csr` + `/api/v1/namespaces/${tenantNamespace || ""}/tenants/${ + tenantName || "" + }/csr` ) .then((res) => { for (var _i = 0; _i < res.csrElement.length; _i++) { @@ -97,7 +98,6 @@ const TenantCSR = ({ loading, tenantNamespace, tenantName, - setErrorSnackMessage, csrAnnotations, csrName, csrStatus, diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantDetails.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantDetails.tsx index d015bac53..5f209b4f3 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantDetails.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantDetails.tsx @@ -16,11 +16,18 @@ import React, { Fragment, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; -import { Link, Redirect, Route, Router, Switch } from "react-router-dom"; +import { + Link, + Navigate, + Route, + Routes, + useLocation, + useNavigate, + useParams, +} from "react-router-dom"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; -import get from "lodash/get"; import Grid from "@mui/material/Grid"; import { containerForHeader, @@ -82,8 +89,6 @@ const TenantMonitoring = withSuspense( interface ITenantDetailsProps { classes: any; - match: any; - history: any; } const styles = (theme: Theme) => @@ -157,8 +162,11 @@ const styles = (theme: Theme) => }, }); -const TenantDetails = ({ classes, match, history }: ITenantDetailsProps) => { +const TenantDetails = ({ classes }: ITenantDetailsProps) => { const dispatch = useDispatch(); + const params = useParams(); + const navigate = useNavigate(); + const { pathname = "" } = useLocation(); const loadingTenant = useSelector( (state: AppState) => state.tenants.loadingTenant @@ -171,8 +179,8 @@ const TenantDetails = ({ classes, match, history }: ITenantDetailsProps) => { ); const tenantInfo = useSelector((state: AppState) => state.tenants.tenantInfo); - const tenantName = match.params["tenantName"]; - const tenantNamespace = match.params["tenantNamespace"]; + const tenantName = params.tenantName || ""; + const tenantNamespace = params.tenantNamespace || ""; const [deleteOpen, setDeleteOpen] = useState(false); // if the current tenant selected is not the one in the redux, reload it @@ -197,8 +205,7 @@ const TenantDetails = ({ classes, match, history }: ITenantDetailsProps) => { tenantNamespace, ]); - const path = get(match, "path", "/"); - const splitSections = path.split("/"); + const splitSections = pathname.split("/"); let highlightedTab = splitSections[splitSections.length - 1] || "summary"; if (highlightedTab === ":podName" || highlightedTab === "pods") { @@ -212,7 +219,7 @@ const TenantDetails = ({ classes, match, history }: ITenantDetailsProps) => { }, [highlightedTab]); const editYaml = () => { - history.push(`${getRoutePath("summary")}/yaml`); + navigate(getRoutePath("summary/yaml")); }; const getRoutePath = (newValue: string) => { @@ -228,7 +235,7 @@ const TenantDetails = ({ classes, match, history }: ITenantDetailsProps) => { if (reloadData) { dispatch(setSnackBarMessage("Tenant Deleted")); - history.push(`/tenants`); + navigate(`/tenants`); } }; @@ -285,7 +292,7 @@ const TenantDetails = ({ classes, match, history }: ITenantDetailsProps) => { } - title={match.params["tenantName"]} + title={tenantName} subTitle={ Namespace: {tenantNamespace} / Capacity:{" "} @@ -332,7 +339,7 @@ const TenantDetails = ({ classes, match, history }: ITenantDetailsProps) => { }} tooltip={"Management Console"} onClick={() => { - history.push( + navigate( `/namespaces/${tenantNamespace}/tenants/${tenantName}/hop` ); }} @@ -367,86 +374,36 @@ const TenantDetails = ({ classes, match, history }: ITenantDetailsProps) => { isRouteTabs routes={
- - - - - - - - - - - - - - - - - - - - ( - - )} - /> - - + + } /> + } /> + } /> + } /> + } + /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + } + /> +
} > diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantEvents.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantEvents.tsx index ff525b15f..1ac749abf 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantEvents.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantEvents.tsx @@ -15,8 +15,9 @@ // along with this program. If not, see . import React, { useEffect, useState } from "react"; -import { connect, useDispatch } from "react-redux"; +import { connect, useDispatch, useSelector } from "react-redux"; import { Theme } from "@mui/material/styles"; +import { useParams } from "react-router-dom"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import { @@ -36,8 +37,6 @@ import { setErrorSnackMessage } from "../../../../systemSlice"; interface ITenantEventsProps { classes: any; - match: any; - loadingTenant: boolean; } const styles = (theme: Theme) => @@ -48,16 +47,18 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -const TenantEvents = ({ - classes, - match, - loadingTenant, -}: ITenantEventsProps) => { +const TenantEvents = ({ classes }: ITenantEventsProps) => { const dispatch = useDispatch(); + const params = useParams(); + + const loadingTenant = useSelector( + (state: AppState) => state.tenants.loadingTenant + ); + const [events, setEvents] = useState([]); const [loading, setLoading] = useState(true); - const tenantName = match.params["tenantName"]; - const tenantNamespace = match.params["tenantNamespace"]; + const tenantName = params.tenantName || ""; + const tenantNamespace = params.tenantNamespace || ""; useEffect(() => { if (loadingTenant) { diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantIdentityProvider.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantIdentityProvider.tsx index 2dd067771..1c8386eeb 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantIdentityProvider.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantIdentityProvider.tsx @@ -14,11 +14,15 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import { ITenant } from "../ListTenants/types"; -import { ITenantIdentityProviderResponse } from "../types"; +import React, { Fragment, useCallback, useEffect, useState } from "react"; +import { connect, useDispatch, useSelector } from "react-redux"; +import { Button, DialogContentText, Typography } from "@mui/material"; import { Theme } from "@mui/material/styles"; +import Grid from "@mui/material/Grid"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; +import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; import { containerForHeader, createTenantCommon, @@ -28,32 +32,25 @@ import { tenantDetailsStyles, wizardCommon, } from "../../Common/FormComponents/common/styleLibrary"; -import Grid from "@mui/material/Grid"; -import React, { Fragment, useCallback, useEffect, useState } from "react"; -import { Button, DialogContentText, Typography } from "@mui/material"; -import api from "../../../../common/api"; -import { connect, useDispatch } from "react-redux"; -import { AppState } from "../../../../store"; -import { ErrorResponseHandler } from "../../../../common/types"; -import Loader from "../../Common/Loader/Loader"; -import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; -import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; +import { ITenantIdentityProviderResponse } from "../types"; import { clearValidationError } from "../utils"; import { commonFormValidation, IValidation, } from "../../../../utils/validationFunctions"; -import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; -import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; -import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; -import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog"; import { ConfirmModalIcon } from "../../../../icons"; import { setErrorSnackMessage } from "../../../../systemSlice"; +import { AppState } from "../../../../store"; +import { ErrorResponseHandler } from "../../../../common/types"; +import Loader from "../../Common/Loader/Loader"; +import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; +import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; +import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; +import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog"; +import api from "../../../../common/api"; interface ITenantIdentityProvider { classes: any; - loadingTenant: boolean; - tenant: ITenant | null; } const styles = (theme: Theme) => @@ -83,12 +80,14 @@ const styles = (theme: Theme) => ...wizardCommon, }); -const TenantIdentityProvider = ({ - classes, - tenant, - loadingTenant, -}: ITenantIdentityProvider) => { +const TenantIdentityProvider = ({ classes }: ITenantIdentityProvider) => { const dispatch = useDispatch(); + + const tenant = useSelector((state: AppState) => state.tenants.tenantInfo); + const loadingTenant = useSelector( + (state: AppState) => state.tenants.loadingTenant + ); + const [isSending, setIsSending] = useState(false); const [dialogOpen, setDialogOpen] = useState(false); const [idpSelection, setIdpSelection] = useState("Built-in"); diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantLogging.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantLogging.tsx index 5207e363f..04e613517 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantLogging.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantLogging.tsx @@ -15,7 +15,7 @@ // along with this program. If not, see . import React, { Fragment, useEffect, useState } from "react"; -import { connect, useDispatch } from "react-redux"; +import { connect, useDispatch, useSelector } from "react-redux"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import { Theme } from "@mui/material/styles"; @@ -29,7 +29,7 @@ import Grid from "@mui/material/Grid"; import { DialogContentText } from "@mui/material"; import Paper from "@mui/material/Paper"; import api from "../../../../common/api"; -import { ITenant, ITenantLogsStruct } from "../ListTenants/types"; +import { ITenantLogsStruct } from "../ListTenants/types"; import { AppState } from "../../../../store"; import { ErrorResponseHandler } from "../../../../common/types"; import { EditIcon } from "../../../../icons"; @@ -41,12 +41,10 @@ import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton" import { niceBytes } from "../../../../common/utils"; import Loader from "../../Common/Loader/Loader"; import { setErrorSnackMessage } from "../../../../systemSlice"; +import { useParams } from "react-router-dom"; interface ITenantLogs { classes: any; - match: any; - tenant: ITenant | null; - loadingTenant: boolean; } const styles = (theme: Theme) => @@ -60,13 +58,15 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -const TenantLogging = ({ - classes, - match, - tenant, - loadingTenant, -}: ITenantLogs) => { +const TenantLogging = ({ classes }: ITenantLogs) => { const dispatch = useDispatch(); + const params = useParams(); + + const loadingTenant = useSelector( + (state: AppState) => state.tenants.loadingTenant + ); + const tenant = useSelector((state: AppState) => state.tenants.tenantInfo); + const [loadingTenantLogs, setLoadingTenantLogs] = useState(true); const [logInfo, setLogInfo] = useState(); const [edit, setEdit] = useState(false); @@ -75,8 +75,8 @@ const TenantLogging = ({ const [disableDialogOpen, setDisableDialogOpen] = useState(false); const [enableDialogOpen, setEnableDialogOpen] = useState(false); - const tenantName = match.params["tenantName"]; - const tenantNamespace = match.params["tenantNamespace"]; + const tenantName = params.tenantName; + const tenantNamespace = params.tenantNamespace; useEffect(() => { if (loadingTenantLogs) { diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantMetrics.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantMetrics.tsx index f853a4533..1c6212dff 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantMetrics.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantMetrics.tsx @@ -16,18 +16,18 @@ import React, { useState } from "react"; import { Theme } from "@mui/material/styles"; +import { useParams } from "react-router-dom"; +import { LinearProgress } from "@mui/material"; import createStyles from "@mui/styles/createStyles"; import withStyles from "@mui/styles/withStyles"; import { containerForHeader, tenantDetailsStyles, } from "../../Common/FormComponents/common/styleLibrary"; -import { LinearProgress } from "@mui/material"; import { IAM_PAGES } from "../../../../common/SecureComponent/permissions"; interface ITenantMetrics { classes: any; - match: any; } const styles = (theme: Theme) => @@ -42,9 +42,8 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -const TenantMetrics = ({ classes, match }: ITenantMetrics) => { - const tenantName = match.params["tenantName"]; - const tenantNamespace = match.params["tenantNamespace"]; +const TenantMetrics = ({ classes }: ITenantMetrics) => { + const { tenantName, tenantNamespace } = useParams(); const [loading, setLoading] = useState(true); @@ -59,7 +58,9 @@ const TenantMetrics = ({ classes, match }: ITenantMetrics) => {