Updated React router to V6 (#2107)

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
Alex
2022-06-09 17:37:21 -05:00
committed by GitHub
parent 51afc337ff
commit e3d96b5bb3
94 changed files with 1288 additions and 1551 deletions

View File

@@ -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",

View File

@@ -15,8 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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 (
<Router history={history}>
<Switch>
<BrowserRouter>
<Routes>
<Route
exact
path="/oauth_callback"
children={(routerProps) => (
element={
<Suspense fallback={<LoadingComponent />}>
<LoginCallback />
</Suspense>
)}
}
/>
<Route
exact
path="/login"
children={(routerProps) => (
element={
<div
style={{
backgroundImage: `url('images/background-wave-orig2.svg'), url('images/background.svg')`,
@@ -61,12 +58,15 @@ const Routes = () => {
<Login />
</Suspense>
</div>
)}
}
/>
<ProtectedRoute Component={AppConsole} />
</Switch>
</Router>
<Route
path={"/*"}
element={<ProtectedRoute Component={AppConsole} />}
/>
</Routes>
</BrowserRouter>
);
};
export default Routes;
export default MainRouter;

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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 <Redirect to={{ pathname: `${baseUrl}login` }} />;
return <Navigate to={{ pathname: `${baseUrl}login` }} />;
};
useEffect(() => {

View File

@@ -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",

View File

@@ -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(
<GlobalCss />
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<Routes />
<MainRouter />
</ThemeProvider>
</StyledEngineProvider>
</Provider>

View File

@@ -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) => {
</SecureComponent>
<RBIconButton
onClick={(e) => {
history.push(`${IAM_PAGES.ACCOUNT_ADD}`);
navigate(`${IAM_PAGES.ACCOUNT_ADD}`);
}}
text={`Create service account`}
icon={<AddIcon />}

View File

@@ -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<boolean>(false);
const [accessKey, setAccessKey] = useState<string>(getRandomString(16));
const [secretKey, setSecretKey] = useState<string>(getRandomString(32));
@@ -133,7 +135,7 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
const closeCredentialsModal = () => {
setNewServiceAccount(null);
history.push(`${IAM_PAGES.ACCOUNT}`);
navigate(`${IAM_PAGES.ACCOUNT}`);
};
return (

View File

@@ -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<boolean>(true);
const [bucketUsers, setBucketUsers] = useState<User[]>([]);
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)}`);
},
},
];

View File

@@ -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<string>("");
const [initialAccess, setInitialAccess] = useState<string>("");
const bucketName = match.params["bucketName"];
const bucketName = params.bucketName || "";
const displayAccessRules = hasPermission(bucketName, [
IAM_SCOPES.S3_GET_BUCKET_POLICY,

View File

@@ -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 (

View File

@@ -15,7 +15,14 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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<boolean>(false);
const [deleteOpen, setDeleteOpen] = useState<boolean>(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={
<div className={classes.contentSpacer}>
<Router history={history}>
<Switch>
<Routes>
<Route path="summary" element={<BucketSummaryPanel />} />
<Route path="events" element={<BucketEventsPanel />} />
{distributedSetup && (
<Route
exact
path="/buckets/:bucketName/admin/summary"
component={BucketSummaryPanel}
path="replication"
element={<BucketReplicationPanel />}
/>
)}
{distributedSetup && (
<Route
exact
path="/buckets/:bucketName/admin/events"
component={BucketEventsPanel}
path="lifecycle"
element={<BucketLifecyclePanel />}
/>
{distributedSetup && (
<Route
exact
path="/buckets/:bucketName/admin/replication"
component={BucketReplicationPanel}
/>
)}
{distributedSetup && (
<Route
exact
path="/buckets/:bucketName/admin/lifecycle"
component={BucketLifecyclePanel}
/>
)}
)}
<Route
exact
path="/buckets/:bucketName/admin/access"
component={AccessDetailsPanel}
/>
<Route
exact
path="/buckets/:bucketName/admin/prefix"
component={AccessRulePanel}
/>
<Route
path="/buckets/:bucketName"
component={() => (
<Redirect to={`/buckets/${bucketName}/admin/summary`} />
)}
/>
</Switch>
</Router>
<Route path="access" element={<AccessDetailsPanel />} />
<Route path="prefix" element={<AccessRulePanel />} />
<Route
path="*"
element={
<Navigate to={`/buckets/${bucketName}/admin/summary`} />
}
/>
</Routes>
</div>
}
>

View File

@@ -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<boolean>(false);
const [selectedEvent, setSelectedEvent] = useState<BucketEvent | null>(null);
const bucketName = match.params["bucketName"];
const bucketName = params.bucketName || "";
const displayEvents = hasPermission(bucketName, [
IAM_SCOPES.S3_GET_BUCKET_NOTIFICATIONS,

View File

@@ -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<boolean>(true);
const [lifecycleRecords, setLifecycleRecords] = useState<LifeCycleItem[]>([]);
@@ -73,7 +71,7 @@ const BucketLifecyclePanel = ({
useState<boolean>(false);
const [selectedID, setSelectedID] = useState<string | null>(null);
const bucketName = match.params["bucketName"];
const bucketName = params.bucketName || "";
const displayLifeCycleRules = hasPermission(bucketName, [
IAM_SCOPES.S3_GET_LIFECYCLE_CONFIGURATION,

View File

@@ -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<boolean>(false);
const bucketName = match.params["bucketName"];
const bucketName = params.bucketName || "";
const displayReplicationRules = hasPermission(bucketName, [
IAM_SCOPES.S3_GET_REPLICATION_CONFIGURATION,

View File

@@ -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<boolean>(false);
const bucketName = match.params["bucketName"];
const bucketName = params.bucketName || "";
let accessPolicy = "n/a";
let policyDefinition = "";

View File

@@ -15,8 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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 (
<Router history={history}>
<Switch>
<Route
path={IAM_PAGES.ADD_BUCKETS}
children={(routerProps) => (
<Suspense fallback={<LoadingComponent />}>
<AddBucket />
</Suspense>
)}
/>
<Route
path="/buckets/:bucketName/admin/*"
children={(routerProps) => (
<Suspense fallback={<LoadingComponent />}>
<BucketDetails {...routerProps} />
</Suspense>
)}
/>
<Route
path="/buckets/:bucketName/admin"
children={(routerProps) => (
<Suspense fallback={<LoadingComponent />}>
<BucketDetails {...routerProps} />
</Suspense>
)}
/>
<Route
path="/buckets/:bucketName/browse/:subpaths+"
children={(routerProps) => (
<Suspense fallback={<LoadingComponent />}>
<BrowserHandler {...routerProps} />
</Suspense>
)}
/>
<Route
path="/buckets/:bucketName/browse"
children={(routerProps) => (
<Suspense fallback={<LoadingComponent />}>
<BrowserHandler {...routerProps} />
</Suspense>
)}
/>
<Route
path="/buckets/:bucketName"
component={() => <Redirect to={`/buckets`} />}
/>
<Route
path="/"
children={(routerProps) => (
<Suspense fallback={<LoadingComponent />}>
<ListBuckets {...routerProps} />
</Suspense>
)}
/>
<Route
children={(routerProps) => (
<Suspense fallback={<LoadingComponent />}>
<NotFoundPage />
</Suspense>
)}
/>
</Switch>
</Router>
<Routes>
<Route
path={IAM_PAGES.ADD_BUCKETS}
element={
<Suspense fallback={<LoadingComponent />}>
<AddBucket />
</Suspense>
}
/>
<Route
path="/"
element={
<Suspense fallback={<LoadingComponent />}>
<ListBuckets />
</Suspense>
}
/>
<Route
path=":bucketName/admin/*"
element={
<Suspense fallback={<LoadingComponent />}>
<BucketDetails />
</Suspense>
}
/>
<Route
path=":bucketName/browse/:subpaths"
element={
<Suspense fallback={<LoadingComponent />}>
<BrowserHandler />
</Suspense>
}
/>
<Route
path=":bucketName/browse"
element={
<Suspense fallback={<LoadingComponent />}>
<BrowserHandler />
</Suspense>
}
/>
<Route element={<Navigate to={`/buckets`} />} path="*" />
<Route
element={
<Suspense fallback={<LoadingComponent />}>
<NotFoundPage />
</Suspense>
}
/>
</Routes>
);
};
export default withRouter(Buckets);
export default Buckets;

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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 (
<Fragment>
<PageHeader label={<BackLink to={"/buckets"} label={"Buckets"} />} />

View File

@@ -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));

View File

@@ -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`;
});
},
});

View File

@@ -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<Bucket[]>([]);
const [loading, setLoading] = useState<boolean>(true);
@@ -291,7 +292,7 @@ const ListBuckets = ({ classes, history }: IListBucketsProps) => {
<RBIconButton
tooltip={"Create Bucket"}
onClick={() => {
history.push(IAM_PAGES.ADD_BUCKETS);
navigate(IAM_PAGES.ADD_BUCKETS);
}}
text={"Create Bucket"}
icon={<AddIcon />}
@@ -356,7 +357,7 @@ const ListBuckets = ({ classes, history }: IListBucketsProps) => {
To get started,&nbsp;
<AButton
onClick={() => {
history.push(IAM_PAGES.ADD_BUCKETS);
navigate(IAM_PAGES.ADD_BUCKETS);
}}
>
Create a Bucket.

View File

@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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<boolean>(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();
};

View File

@@ -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 = <Typography component="h3">Loading...</Typography>;
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<boolean>(false);
const [quota, setQuota] = useState<BucketQuota | null>(null);
const internalPaths = get(match.params, "subpaths", "");
const bucketName = match.params["bucketName"];
const internalPaths = get(params, "subpaths", "");
const bucketName = params.bucketName || "";
const fileUpload = useRef<HTMLInputElement>(null);
const folderUpload = useRef<HTMLInputElement>(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;

View File

@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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<Bucket[]>([]);
@@ -146,7 +148,8 @@ const CommandBar = () => {
const initialActions: Action[] = routesAsKbarActions(
features,
operatorMode,
buckets
buckets,
navigate
);
useRegisterActions(initialActions, [operatorMode, buckets, features]);

View File

@@ -14,8 +14,6 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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<boolean>(false);
const [anchorEl, setAnchorEl] = React.useState<any>(null);
@@ -487,7 +489,7 @@ const TableWrapper = ({
}
if (findView.to && !disabled) {
history.push(`${findView.to}/${valueClick}`);
navigate(`${findView.to}/${valueClick}`);
return;
}

View File

@@ -15,19 +15,16 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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 (
<Router history={history}>
<Switch>
<Route path="/settings" component={ConfigurationOptions} />
<Route component={NotFoundPage} />
</Switch>
</Router>
<Routes>
<Route path="/settings" element={<ConfigurationOptions />} />
<Route element={<NotFoundPage />} />
</Routes>
);
};

View File

@@ -15,22 +15,15 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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) => {
<EditConfiguration
className={`${containerClassName}`}
selectedConfiguration={validActiveConfig}
history={history}
/>
)}
</Grid>

View File

@@ -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={
<Router history={history}>
<Switch>
{configurationElements.map((element) => (
<Route
exact
key={`configItem-${element.configuration_label}`}
path={`${IAM_PAGES.SETTINGS}/${element.configuration_id}`}
component={ConfigurationForm}
/>
))}
<Route exact path={IAM_PAGES.SETTINGS}>
<Redirect to={`${IAM_PAGES.SETTINGS}/region`} />
</Route>
</Switch>
</Router>
<Routes>
{configurationElements.map((element) => (
<Route
key={`configItem-${element.configuration_label}`}
path={`${element.configuration_id}`}
element={<ConfigurationForm />}
/>
))}
<Route
path={"/"}
element={<Navigate to={`${IAM_PAGES.SETTINGS}/region`} />}
/>
</Routes>
}
>
{configurationElements.map((element) => {

View File

@@ -15,19 +15,19 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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<SiteInputRow[]>([]);
const [accessKey, setAccessKey] = useState<string>("");
@@ -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({

View File

@@ -15,9 +15,11 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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={<RecoverIcon />}
onClick={(e) => {
e.preventDefault();
history.push(IAM_PAGES.SITE_REPLICATION_STATUS);
navigate(IAM_PAGES.SITE_REPLICATION_STATUS);
}}
/>
</Box>
@@ -151,7 +153,7 @@ const SiteReplication = () => {
disabled={isRemoving}
icon={<AddIcon />}
onClick={() => {
history.push(IAM_PAGES.SITE_REPLICATION_ADD);
navigate(IAM_PAGES.SITE_REPLICATION_ADD);
}}
/>
</Box>
@@ -195,7 +197,7 @@ const SiteReplication = () => {
To get started,{" "}
<AButton
onClick={() => {
history.push(IAM_PAGES.SITE_REPLICATION_ADD);
navigate(IAM_PAGES.SITE_REPLICATION_ADD);
}}
>
Add a Replication Site

View File

@@ -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<boolean>(false);
@@ -106,7 +108,7 @@ const AddTierConfiguration = ({
const [titleSelection, setTitleSelection] = useState<string>("");
const type = get(match, "params.service", "s3");
const type = get(params, "service", "s3");
// Validations
const [isFormValid, setIsFormValid] = useState<boolean>(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 && (

View File

@@ -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<ITierElement[]>([]);
const [filter, setFilter] = useState<string>("");
@@ -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) => {

View File

@@ -15,23 +15,21 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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 (

View File

@@ -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) => {
<Suspense fallback={<LoadingComponent />}>
<ObjectManager />
</Suspense>
<Router history={history}>
<Switch>
{allowedRoutes.map((route: any) => (
<Route
key={route.path}
exact
path={route.path}
children={(routerProps) => (
<Suspense fallback={<LoadingComponent />}>
<route.component {...routerProps} {...route.props} />
</Suspense>
)}
/>
))}
<Route key={"/icons"} exact path={"/icons"}>
<Routes>
{allowedRoutes.map((route: any) => (
<Route
key={route.path}
path={`${route.path}/*`}
element={
<Suspense fallback={<LoadingComponent />}>
<route.component {...route.props} />
</Suspense>
}
/>
))}
<Route
key={"icons"}
path={"icons"}
element={
<Suspense fallback={<LoadingComponent />}>
<IconsScreen />
</Suspense>
</Route>
<Route key={"/components"} exact path={"/components"}>
}
/>
<Route
key={"components"}
path={"components"}
element={
<Suspense fallback={<LoadingComponent />}>
<ComponentsScreen />
</Suspense>
</Route>
{allowedRoutes.length > 0 ? (
<Redirect to={allowedRoutes[0].path} />
) : null}
</Switch>
</Router>
}
/>
<Route
path={"*"}
element={
<Fragment>
{allowedRoutes.length > 0 ? (
<Navigate to={allowedRoutes[0].path} />
) : (
<Fragment />
)}
</Fragment>
}
/>
</Routes>
</main>
</div>
) : null}

View File

@@ -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<string>("");
const [saving, isSaving] = useState<boolean>(false);
const [selectedUsers, setSelectedUsers] = useState<string[]>([]);
@@ -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) => {

View File

@@ -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<boolean>(false);
const [loading, isLoading] = useState<boolean>(false);
const [records, setRecords] = useState<any[]>([]);
@@ -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 (
<React.Fragment>
<Fragment>
{deleteOpen && (
<DeleteGroup
deleteOpen={deleteOpen}
@@ -279,7 +282,7 @@ const Groups = ({ classes, history }: IGroupsProps) => {
color="primary"
icon={<AddIcon />}
onClick={() => {
history.push(`${IAM_PAGES.GROUPS_ADD}`);
navigate(`${IAM_PAGES.GROUPS_ADD}`);
}}
/>
</SecureComponent>
@@ -365,7 +368,7 @@ const Groups = ({ classes, history }: IGroupsProps) => {
To get started,{" "}
<AButton
onClick={() => {
history.push(`${IAM_PAGES.GROUPS_ADD}`);
navigate(`${IAM_PAGES.GROUPS_ADD}`);
}}
>
Create a Group
@@ -381,7 +384,7 @@ const Groups = ({ classes, history }: IGroupsProps) => {
</Fragment>
)}
</PageLayout>
</React.Fragment>
</Fragment>
);
};

View File

@@ -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<GroupInfo>({});
/*Modals*/
@@ -117,7 +119,7 @@ const GroupsDetails = ({ classes, match }: IGroupDetailsProps) => {
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
const [memberFilter, setMemberFilter] = useState<string>("");
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);
}
}}
/>

View File

@@ -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";

View File

@@ -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`)

View File

@@ -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<IElementValue[]>([]);
const [saving, setSaving] = useState<boolean>(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) => {

View File

@@ -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<IElementValue[]>([]);
const [saving, setSaving] = useState<boolean>(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) => {

View File

@@ -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<TransformedEndpointItem[]>([]);
const [filter, setFilter] = useState<string>("");
@@ -166,7 +167,7 @@ const ListNotificationEndpoints = ({ classes }: IListNotificationEndpoints) => {
color="primary"
icon={<AddIcon />}
onClick={() => {
history.push(IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD);
navigate(IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD);
}}
/>
</div>
@@ -246,7 +247,7 @@ const ListNotificationEndpoints = ({ classes }: IListNotificationEndpoints) => {
To get started,{" "}
<AButton
onClick={() => {
history.push(IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD);
navigate(IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD);
}}
>
Add a Notification Target

View File

@@ -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 (
<Fragment>
<PageHeader
@@ -68,7 +69,7 @@ const NotificationTypeSelector = ({ classes }: INotificationTypeSelector) => {
key={`icon-${item.targetTitle}`}
className={classes.lambdaNotif}
onClick={() => {
history.push(
navigate(
`${IAM_PAGES.NOTIFICATIONS_ENDPOINTS_ADD}/${item.actionTrigger}`
);
}}

View File

@@ -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);
}
};

View File

@@ -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<boolean>(false);
const [policyName, setPolicyName] = useState<string>("");
@@ -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);

View File

@@ -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<Policy[]>([]);
const [loading, setLoading] = useState<boolean>(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={<AddIcon />}
onClick={() => {
history.push(`${IAM_PAGES.POLICY_ADD}`);
navigate(`${IAM_PAGES.POLICY_ADD}`);
}}
/>
</SecureComponent>

View File

@@ -2,34 +2,22 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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 (
<Router history={history}>
<Switch>
<Route
path={IAM_PAGES.POLICIES}
exact={true}
component={ListPolicies}
/>
<Route
path={`${IAM_PAGES.POLICIES}/:policyName+`}
component={PolicyDetails}
/>
<Route path="/" component={ListPolicies} />
<Route component={NotFoundPage} />
</Switch>
</Router>
<Routes>
<Route path={"/"} element={<ListPolicies />} />
<Route path={`:policyName`} element={<PolicyDetails />} />
<Route element={<NotFoundPage />} />
</Routes>
);
};
export default withRouter(Policies);
export default Policies;

View File

@@ -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<string[]>([]);
const [addLoading, setAddLoading] = useState<boolean>(false);
const policyName = decodeURLString(match.params["policyName"]);
const policyName = decodeURLString(params.policyName || "");
const [policyDefinition, setPolicyDefinition] = useState<string>("");
const [loadingPolicy, setLoadingPolicy] = useState<boolean>(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 = [

View File

@@ -66,7 +66,6 @@ import { selOpMode, setErrorSnackMessage } from "../../../systemSlice";
interface IRegister {
classes: any;
operatorMode: boolean;
}
const styles = (theme: Theme) =>

View File

@@ -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");
},
};

View File

@@ -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"
/>

View File

@@ -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<boolean>(false);
const [filterTenants, setFilterTenants] = useState<string>("");
const [records, setRecords] = useState<ITenant[]>([]);
@@ -283,7 +285,7 @@ const ListTenants = ({ classes }: ITenantsList) => {
tooltip={"Create Tenant"}
text={"Create Tenant"}
onClick={() => {
history.push("/tenants/add");
navigate("/tenants/add");
}}
icon={<AddIcon />}
color="primary"
@@ -360,7 +362,7 @@ const ListTenants = ({ classes }: ITenantsList) => {
To get started,&nbsp;
<AButton
onClick={() => {
history.push("/tenants/add");
navigate("/tenants/add");
}}
>
Create a Tenant.

View File

@@ -15,20 +15,19 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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 (

View File

@@ -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<boolean>(false);
const [selectedPod, setSelectedPod] = useState<any>(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++) {

View File

@@ -14,8 +14,9 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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);
},
};

View File

@@ -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;
}
});
},
});

View File

@@ -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));

View File

@@ -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) => {
<RBIconButton
icon={<EditTenantIcon />}
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;

View File

@@ -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`

View File

@@ -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);
},
};

View File

@@ -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;
}
});
},
});

View File

@@ -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));

View File

@@ -44,6 +44,7 @@ export interface IEditPool {
limitSize: any;
fields: IEditPoolFields;
editSending: boolean;
navigateTo: string;
}
export interface PageFieldValue {

View File

@@ -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}
/>
</Grid>
)}
@@ -76,13 +76,12 @@ const PoolsSummary = ({ classes, history, match }: IPoolsSummary) => {
</h1>
<Grid container>
{poolDetailsOpen ? (
<PoolDetails history={history} />
<PoolDetails />
) : (
<PoolsListing
setPoolDetailsView={() => {
dispatch(setOpenPoolDetails(true));
}}
history={history}
/>
)}
</Grid>

View File

@@ -14,8 +14,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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<boolean>(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,

View File

@@ -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<boolean>(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) => {
<TenantsIcon />
</Fragment>
}
title={match.params["tenantName"]}
title={tenantName}
subTitle={
<Fragment>
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={
<div className={classes.contentSpacer}>
<Router history={history}>
<Switch>
<Route
path={`${IAM_PAGES.NAMESPACE_TENANT_SUMMARY}/yaml`}
component={TenantYAML}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_SUMMARY}
component={TenantSummary}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_METRICS}
component={TenantMetrics}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_TRACE}
component={TenantTrace}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_IDENTITY_PROVIDER}
component={TenantIdentityProvider}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_SECURITY}
component={TenantSecurity}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_ENCRYPTION}
component={TenantEncryption}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_POOLS}
component={PoolsSummary}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_PODS}
component={PodDetails}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_PODS_LIST}
component={PodsSummary}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_PVCS}
component={TenantVolumes}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_VOLUMES}
component={VolumesSummary}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_LICENSE}
component={TenantLicense}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_MONITORING}
component={TenantMonitoring}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_LOGGING}
component={TenantLogging}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_EVENTS}
component={TenantEvents}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT_CSR}
component={TenantCSR}
/>
<Route
path={IAM_PAGES.NAMESPACE_TENANT}
component={() => (
<Redirect
to={`/namespaces/${tenantNamespace}/tenants/${tenantName}/summary`}
/>
)}
/>
</Switch>
</Router>
<Routes>
<Route path={"summary"} element={<TenantSummary />} />
<Route path={`summary/yaml`} element={<TenantYAML />} />
<Route path={"metrics"} element={<TenantMetrics />} />
<Route path={"trace"} element={<TenantTrace />} />
<Route
path={"identity-provider"}
element={<TenantIdentityProvider />}
/>
<Route path={"security"} element={<TenantSecurity />} />
<Route path={"encryption"} element={<TenantEncryption />} />
<Route path={"pools"} element={<PoolsSummary />} />
<Route path={"pods/:podName"} element={<PodDetails />} />
<Route path={"pods"} element={<PodsSummary />} />
<Route path={"pvcs/:PVCName"} element={<TenantVolumes />} />
<Route path={"volumes"} element={<VolumesSummary />} />
<Route path={"license"} element={<TenantLicense />} />
<Route path={"monitoring"} element={<TenantMonitoring />} />
<Route path={"logging"} element={<TenantLogging />} />
<Route path={"events"} element={<TenantEvents />} />
<Route path={"csr"} element={<TenantCSR />} />
<Route
path={"/"}
element={
<Navigate
to={`/namespaces/${tenantNamespace}/tenants/${tenantName}/summary`}
/>
}
/>
</Routes>
</div>
}
>

View File

@@ -15,8 +15,9 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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<IEvent[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const tenantName = match.params["tenantName"];
const tenantNamespace = match.params["tenantNamespace"];
const tenantName = params.tenantName || "";
const tenantNamespace = params.tenantNamespace || "";
useEffect(() => {
if (loadingTenant) {

View File

@@ -14,11 +14,15 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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<boolean>(false);
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
const [idpSelection, setIdpSelection] = useState<string>("Built-in");

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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<boolean>(true);
const [logInfo, setLogInfo] = useState<ITenantLogsStruct>();
const [edit, setEdit] = useState<boolean>(false);
@@ -75,8 +75,8 @@ const TenantLogging = ({
const [disableDialogOpen, setDisableDialogOpen] = useState<boolean>(false);
const [enableDialogOpen, setEnableDialogOpen] = useState<boolean>(false);
const tenantName = match.params["tenantName"];
const tenantNamespace = match.params["tenantNamespace"];
const tenantName = params.tenantName;
const tenantNamespace = params.tenantNamespace;
useEffect(() => {
if (loadingTenantLogs) {

View File

@@ -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<boolean>(true);
@@ -59,7 +58,9 @@ const TenantMetrics = ({ classes, match }: ITenantMetrics) => {
<iframe
className={classes.iframeStyle}
title={"metrics"}
src={`/api/proxy/${tenantNamespace}/${tenantName}${IAM_PAGES.DASHBOARD}?cp=y`}
src={`/api/proxy/${tenantNamespace || ""}/${tenantName || ""}${
IAM_PAGES.DASHBOARD
}?cp=y`}
onLoad={() => {
setLoading(false);
}}

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -28,7 +28,7 @@ import {
} from "../../Common/FormComponents/common/styleLibrary";
import { DialogContentText } from "@mui/material";
import Paper from "@mui/material/Paper";
import { ITenant, ITenantMonitoringStruct } from "../ListTenants/types";
import { ITenantMonitoringStruct } from "../ListTenants/types";
import { ErrorResponseHandler } from "../../../../common/types";
import EditTenantMonitoringModal from "./EditTenantMonitoringModal";
@@ -41,12 +41,11 @@ import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton";
import Loader from "../../Common/Loader/Loader";
import { setErrorSnackMessage } from "../../../../systemSlice";
import { useParams } from "react-router-dom";
import { AppState } from "../../../../store";
interface ITenantMonitoring {
classes: any;
match: any;
tenant: ITenant | null;
loadingTenant: boolean;
}
const styles = (theme: Theme) =>
@@ -60,13 +59,15 @@ const styles = (theme: Theme) =>
...containerForHeader(theme.spacing(4)),
});
const TenantMonitoring = ({
classes,
match,
tenant,
loadingTenant,
}: ITenantMonitoring) => {
const TenantMonitoring = ({ classes }: ITenantMonitoring) => {
const dispatch = useDispatch();
const { tenantName, tenantNamespace } = useParams();
const loadingTenant = useSelector(
(state: AppState) => state.tenants.loadingTenant
);
const tenant = useSelector((state: AppState) => state.tenants.tenantInfo);
const [prometheusMonitoringEnabled, setPrometheusMonitoringEnabled] =
useState<boolean>(false);
const [edit, setEdit] = useState<boolean>(false);
@@ -76,9 +77,6 @@ const TenantMonitoring = ({
const [refreshMonitoringInfo, setRefreshMonitoringInfo] =
useState<boolean>(true);
const tenantName = match.params["tenantName"];
const tenantNamespace = match.params["tenantNamespace"];
const onCloseEditAndRefresh = () => {
setEdit(false);
setRefreshMonitoringInfo(true);
@@ -89,7 +87,9 @@ const TenantMonitoring = ({
api
.invoke(
"GET",
`/api/v1/namespaces/${tenantNamespace}/tenants/${tenantName}/monitoring`
`/api/v1/namespaces/${tenantNamespace || ""}/tenants/${
tenantName || ""
}/monitoring`
)
.then((res: ITenantMonitoringStruct) => {
setPrometheusMonitoringEnabled(res.prometheusEnabled);
@@ -146,8 +146,8 @@ const TenantMonitoring = ({
annotations={monitoringInfo?.annotations || []}
nodeSelector={monitoringInfo?.nodeSelector || []}
serviceAccountName={monitoringInfo?.serviceAccountName || ""}
tenantName={tenantName}
tenantNamespace={tenantNamespace}
tenantName={tenantName || ""}
tenantNamespace={tenantNamespace || ""}
storageClassName={monitoringInfo?.storageClassName || ""}
cpuRequest={monitoringInfo?.monitoringCPURequest || ""}
memRequest={monitoringInfo?.monitoringMemRequest || ""}

View File

@@ -14,11 +14,14 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import { ITenant } from "../ListTenants/types";
import { ICertificateInfo, ITenantSecurityResponse } from "../types";
import React, { Fragment, useCallback, useEffect, useState } from "react";
import { connect, useDispatch, useSelector } from "react-redux";
import { Theme } from "@mui/material/styles";
import { Button, DialogContentText } from "@mui/material";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import Grid from "@mui/material/Grid";
import { ICertificateInfo, ITenantSecurityResponse } from "../types";
import {
containerForHeader,
createTenantCommon,
@@ -28,27 +31,22 @@ import {
tenantDetailsStyles,
wizardCommon,
} from "../../Common/FormComponents/common/styleLibrary";
import Grid from "@mui/material/Grid";
import React, { Fragment, useCallback, useEffect, useState } from "react";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import { Button, DialogContentText } from "@mui/material";
import { KeyPair } from "../ListTenants/utils";
import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector";
import api from "../../../../common/api";
import { connect, useDispatch } from "react-redux";
import { AppState } from "../../../../store";
import { ErrorResponseHandler } from "../../../../common/types";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import { AddIcon, ConfirmModalIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../systemSlice";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector";
import api from "../../../../common/api";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import Loader from "../../Common/Loader/Loader";
import TLSCertificate from "../../Common/TLSCertificate/TLSCertificate";
import SectionTitle from "../../Common/SectionTitle";
import { setErrorSnackMessage } from "../../../../systemSlice";
interface ITenantSecurity {
classes: any;
loadingTenant: boolean;
tenant: ITenant | null;
}
const styles = (theme: Theme) =>
@@ -78,12 +76,14 @@ const styles = (theme: Theme) =>
...wizardCommon,
});
const TenantSecurity = ({
classes,
tenant,
loadingTenant,
}: ITenantSecurity) => {
const TenantSecurity = ({ classes }: ITenantSecurity) => {
const dispatch = useDispatch();
const tenant = useSelector((state: AppState) => state.tenants.tenantInfo);
const loadingTenant = useSelector(
(state: AppState) => state.tenants.loadingTenant
);
const [isSending, setIsSending] = useState<boolean>(false);
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
const [enableAutoCert, setEnableAutoCert] = useState<boolean>(false);

View File

@@ -37,10 +37,10 @@ import { EditIcon } from "../../../../icons";
import EditDomains from "./EditDomains";
import { setTenantDetailsLoad } from "../tenantsSlice";
import { ITenant } from "../ListTenants/types";
import { useParams } from "react-router-dom";
interface ITenantsSummary {
classes: any;
match: any;
}
const styles = (theme: Theme) =>
@@ -181,8 +181,9 @@ const featureItemStyleProps = {
},
},
};
const TenantSummary = ({ classes, match }: ITenantsSummary) => {
const TenantSummary = ({ classes }: ITenantsSummary) => {
const dispatch = useDispatch();
const { tenantName, tenantNamespace } = useParams();
const tenant = useSelector((state: AppState) => state.tenants.tenantInfo);
const logEnabled = useSelector((state: AppState) =>
@@ -210,9 +211,6 @@ const TenantSummary = ({ classes, match }: ITenantsSummary) => {
const [updateMinioVersion, setUpdateMinioVersion] = useState<boolean>(false);
const [editDomainsOpen, setEditDomainsOpen] = useState<boolean>(false);
const tenantName = match.params["tenantName"];
const tenantNamespace = match.params["tenantNamespace"];
useEffect(() => {
if (tenant) {
setPoolCount(tenant.pools.length);
@@ -237,16 +235,16 @@ const TenantSummary = ({ classes, match }: ITenantsSummary) => {
closeModalAndRefresh={() => {
setUpdateMinioVersion(false);
}}
idTenant={tenantName}
namespace={tenantNamespace}
idTenant={tenantName || ""}
namespace={tenantNamespace || ""}
/>
)}
{editDomainsOpen && (
<EditDomains
open={editDomainsOpen}
idTenant={tenantName}
namespace={tenantNamespace}
idTenant={tenantName || ""}
namespace={tenantNamespace || ""}
domains={tenant?.domains || null}
closeModalAndRefresh={closeEditDomainsModal}
/>

View File

@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import { useParams } from "react-router-dom";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -22,14 +23,11 @@ import {
containerForHeader,
tenantDetailsStyles,
} from "../../Common/FormComponents/common/styleLibrary";
import { ITenant } from "../ListTenants/types";
import { LinearProgress } from "@mui/material";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
interface ITenantTrace {
classes: any;
match: any;
tenant: ITenant | null;
}
const styles = (theme: Theme) =>
@@ -44,9 +42,8 @@ const styles = (theme: Theme) =>
...containerForHeader(theme.spacing(4)),
});
const TenantTrace = ({ classes, match }: ITenantTrace) => {
const tenantName = match.params["tenantName"];
const tenantNamespace = match.params["tenantNamespace"];
const TenantTrace = ({ classes }: ITenantTrace) => {
const { tenantName, tenantNamespace } = useParams();
const [loading, setLoading] = useState<boolean>(true);
@@ -61,7 +58,9 @@ const TenantTrace = ({ classes, match }: ITenantTrace) => {
<iframe
className={classes.iframeStyle}
title={"metrics"}
src={`/api/proxy/${tenantNamespace}/${tenantName}${IAM_PAGES.TOOLS_TRACE}?cp=y`}
src={`/api/proxy/${tenantNamespace || ""}/${tenantName || ""}${
IAM_PAGES.TOOLS_TRACE
}?cp=y`}
onLoad={() => {
setLoading(false);
}}

View File

@@ -16,6 +16,7 @@
import React, { Fragment, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import Grid from "@mui/material/Grid";
import { Button, LinearProgress } from "@mui/material";
import { Theme } from "@mui/material/styles";
@@ -60,11 +61,11 @@ interface ITenantYAML {
interface ITenantYAMLProps {
classes: any;
history: any;
}
const TenantYAML = ({ classes, history }: ITenantYAMLProps) => {
const TenantYAML = ({ classes }: ITenantYAMLProps) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const tenant = useSelector((state: AppState) => state.tenants.currentTenant);
const namespace = useSelector(
@@ -91,7 +92,7 @@ const TenantYAML = ({ classes, history }: ITenantYAMLProps) => {
setAddLoading(false);
dispatch(getTenantAsync());
setErrorMessage("");
history.push(`/namespaces/${namespace}/tenants/${tenant}/summary`);
navigate(`/namespaces/${namespace}/tenants/${tenant}/summary`);
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
@@ -157,7 +158,7 @@ const TenantYAML = ({ classes, history }: ITenantYAMLProps) => {
color="primary"
disabled={addLoading}
onClick={() => {
history.push(
navigate(
`/namespaces/${namespace}/tenants/${tenant}/summary`
);
}}

View File

@@ -35,13 +35,12 @@ import { IPodListElement } from "../ListTenants/types";
import withSuspense from "../../Common/Components/withSuspense";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../systemSlice";
import { useNavigate, useParams } from "react-router-dom";
const DeletePVC = withSuspense(React.lazy(() => import("./DeletePVC")));
interface ITenantVolumesProps {
classes: any;
history: any;
match: any;
}
const styles = (theme: Theme) =>
@@ -51,8 +50,10 @@ const styles = (theme: Theme) =>
...containerForHeader(theme.spacing(4)),
});
const TenantVolumes = ({ classes, history, match }: ITenantVolumesProps) => {
const TenantVolumes = ({ classes }: ITenantVolumesProps) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const { tenantName, tenantNamespace } = useParams();
const loadingTenant = useSelector(
(state: AppState) => state.tenants.loadingTenant
@@ -64,9 +65,6 @@ const TenantVolumes = ({ classes, history, match }: ITenantVolumesProps) => {
const [selectedPVC, setSelectedPVC] = useState<any>(null);
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
const tenantName = match.params["tenantName"];
const tenantNamespace = match.params["tenantNamespace"];
useEffect(() => {
if (loading) {
api
@@ -101,8 +99,10 @@ const TenantVolumes = ({ classes, history, match }: ITenantVolumesProps) => {
);
const PVCViewAction = (PVC: IPodListElement) => {
history.push(
`/namespaces/${tenantNamespace}/tenants/${tenantName}/pvcs/${PVC.name}`
navigate(
`/namespaces/${tenantNamespace || ""}/tenants/${tenantName || ""}/pvcs/${
PVC.name
}`
);
return;
};

View File

@@ -16,20 +16,18 @@
import React, { Fragment, useState } from "react";
import { Theme } from "@mui/material/styles";
import { Link, useNavigate, useParams } from "react-router-dom";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Link } from "react-router-dom";
import { Box, IconButton } from "@mui/material";
import PageHeader from "../../../Common/PageHeader/PageHeader";
import { containerForHeader } from "../../../Common/FormComponents/common/styleLibrary";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import history from "./../../../../../history";
import RefreshIcon from "../../../../../icons/RefreshIcon";
import Loader from "../../../Common/Loader/Loader";
interface IHopSimple {
classes: any;
match: any;
}
const styles = (theme: Theme) =>
@@ -64,11 +62,14 @@ const styles = (theme: Theme) =>
...containerForHeader(theme.spacing(4)),
});
const Hop = ({ classes, match }: IHopSimple) => {
const Hop = ({ classes }: IHopSimple) => {
const navigate = useNavigate();
const params = useParams();
const [loading, setLoading] = useState<boolean>(true);
const tenantName = match.params["tenantName"];
const tenantNamespace = match.params["tenantNamespace"];
const tenantName = params.tenantName || "";
const tenantNamespace = params.tenantNamespace || "";
const consoleFrame = React.useRef<HTMLIFrameElement>(null);
return (
@@ -85,7 +86,7 @@ const Hop = ({ classes, match }: IHopSimple) => {
to={`/namespaces/${tenantNamespace}/tenants/${tenantName}`}
className={classes.breadcrumLink}
>
{match.params["tenantName"]}
{tenantName}
</Link>
{` > Management`}
</Fragment>
@@ -130,7 +131,7 @@ const Hop = ({ classes, match }: IHopSimple) => {
aria-label="Refresh List"
component="span"
onClick={() => {
history.push(
navigate(
`/namespaces/${tenantNamespace}/tenants/${tenantName}`
);
}}

View File

@@ -16,13 +16,13 @@
import React, { Fragment, useEffect, useState } from "react";
import { Theme } from "@mui/material/styles";
import { Link, useParams } from "react-router-dom";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { containerForHeader } from "../../../Common/FormComponents/common/styleLibrary";
import Grid from "@mui/material/Grid";
import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
import { Link } from "react-router-dom";
import PodLogs from "./PodLogs";
import PodEvents from "./PodEvents";
@@ -30,7 +30,6 @@ import PodDescribe from "./PodDescribe";
interface IPodDetailsProps {
classes: any;
match: any;
}
const styles = (theme: Theme) =>
@@ -42,12 +41,11 @@ const styles = (theme: Theme) =>
...containerForHeader(theme.spacing(4)),
});
const PodDetails = ({ classes, match }: IPodDetailsProps) => {
const PodDetails = ({ classes }: IPodDetailsProps) => {
const { tenantNamespace, tenantName, podName } = useParams();
const [curTab, setCurTab] = useState<number>(0);
const [loading, setLoading] = useState<boolean>(true);
const tenantNamespace = match.params["tenantNamespace"];
const tenantName = match.params["tenantName"];
const podName = match.params["podName"];
function a11yProps(index: any) {
return {
@@ -67,7 +65,9 @@ const PodDetails = ({ classes, match }: IPodDetailsProps) => {
<Grid item xs={12}>
<h1 className={classes.sectionTitle}>
<Link
to={`/namespaces/${tenantNamespace}/tenants/${tenantName}/pods`}
to={`/namespaces/${tenantNamespace || ""}/tenants/${
tenantName || ""
}/pods`}
className={classes.breadcrumLink}
>
Pods
@@ -95,25 +95,25 @@ const PodDetails = ({ classes, match }: IPodDetailsProps) => {
</Grid>
{curTab === 0 && (
<PodEvents
tenant={tenantName}
namespace={tenantNamespace}
podName={podName}
tenant={tenantName || ""}
namespace={tenantNamespace || ""}
podName={podName || ""}
propLoading={loading}
/>
)}
{curTab === 1 && (
<PodDescribe
tenant={tenantName}
namespace={tenantNamespace}
podName={podName}
tenant={tenantName || ""}
namespace={tenantNamespace || ""}
podName={podName || ""}
propLoading={loading}
/>
)}
{curTab === 2 && (
<PodLogs
tenant={tenantName}
namespace={tenantNamespace}
podName={podName}
tenant={tenantName || ""}
namespace={tenantNamespace || ""}
podName={podName || ""}
propLoading={loading}
/>
)}

View File

@@ -22,7 +22,7 @@ import { containerForHeader } from "../../../Common/FormComponents/common/styleL
import Grid from "@mui/material/Grid";
import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
import { Link } from "react-router-dom";
import { Link, useParams } from "react-router-dom";
import api from "../../../../../common/api";
import { IEvent } from "../../ListTenants/types";
@@ -35,7 +35,6 @@ import { setErrorSnackMessage } from "../../../../../systemSlice";
interface IPVCDetailsProps {
classes: any;
match: any;
}
const styles = (theme: Theme) =>
@@ -47,13 +46,12 @@ const styles = (theme: Theme) =>
...containerForHeader(theme.spacing(4)),
});
const TenantVolumes = ({ classes, match }: IPVCDetailsProps) => {
const [curTab, setCurTab] = useState<number>(0);
const TenantVolumes = ({ classes }: IPVCDetailsProps) => {
const dispatch = useDispatch();
const { tenantName, PVCName, tenantNamespace } = useParams();
const [curTab, setCurTab] = useState<number>(0);
const [loading, setLoading] = useState<boolean>(true);
const tenantNamespace = match.params["tenantNamespace"];
const tenantName = match.params["tenantName"];
const PVCName = match.params["PVCName"];
const [events, setEvents] = useState<IEvent[]>([]);
useEffect(() => {
@@ -117,9 +115,9 @@ const TenantVolumes = ({ classes, match }: IPVCDetailsProps) => {
)}
{curTab === 1 && (
<PVCDescribe
tenant={tenantName}
namespace={tenantNamespace}
pvcName={PVCName}
tenant={tenantName || ""}
namespace={tenantNamespace || ""}
pvcName={PVCName || ""}
propLoading={loading}
/>
)}

View File

@@ -15,15 +15,12 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { Route, Router, Switch } from "react-router-dom";
import history from "../../../history";
import NotFoundPage from "../../NotFoundPage";
import ToolsList from "./ToolsPanel/ToolsList";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import { Route, Routes } from "react-router-dom";
import FeatureNotAvailablePage from "../Common/Components/FeatureNotAvailablePage";
import { SupportMenuIcon } from "../../../icons/SidebarMenus";
import withSuspense from "../Common/Components/withSuspense";
import NotFoundPage from "../../NotFoundPage";
const Inspect = withSuspense(React.lazy(() => import("./Inspect")));
const Register = withSuspense(React.lazy(() => import("../Support/Register")));
@@ -31,29 +28,23 @@ const Profile = withSuspense(React.lazy(() => import("../Support/Profile")));
const Tools = () => {
return (
<Router history={history}>
<Switch>
<Route path={IAM_PAGES.TOOLS} exact component={ToolsList} />
<Route path={IAM_PAGES.REGISTER_SUPPORT} exact component={Register} />
<Route path={IAM_PAGES.PROFILE} exact component={Profile} />
<Route
path={IAM_PAGES.CALL_HOME}
exact
render={() => {
return (
<FeatureNotAvailablePage
icon={<SupportMenuIcon />}
pageHeaderText={"Support"}
title={"Call Home"}
message={<div>This feature is currently not available.</div>}
/>
);
}}
/>
<Route path={IAM_PAGES.SUPPORT_INSPECT} exact component={Inspect} />
<Route component={NotFoundPage} />
</Switch>
</Router>
<Routes>
<Route path={"register"} element={<Register />} />
<Route path={"profile"} element={<Profile />} />
<Route
path={"call-home"}
element={
<FeatureNotAvailablePage
icon={<SupportMenuIcon />}
pageHeaderText={"Support"}
title={"Call Home"}
message={<div>This feature is currently not available.</div>}
/>
}
/>
<Route path={"inspect"} element={<Inspect />} />
<Route path={"*"} element={<NotFoundPage />} />
</Routes>
);
};

View File

@@ -1,157 +0,0 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment } from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import Grid from "@mui/material/Grid";
import {
actionsTray,
containerForHeader,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import PageHeader from "../../Common/PageHeader/PageHeader";
import SettingsCard from "../../Common/SettingsCard/SettingsCard";
import PageLayout from "../../Common/Layout/PageLayout";
import { IElement } from "../types";
import {
DiagnosticsIcon,
HealIcon,
LogsIcon,
SearchIcon,
SpeedtestIcon,
TraceIcon,
WatchIcon,
} from "../../../../icons";
import {
CONSOLE_UI_RESOURCE,
IAM_PAGES,
IAM_PAGES_PERMISSIONS,
} from "../../../../common/SecureComponent/permissions";
import { hasPermission } from "../../../../common/SecureComponent";
import makeStyles from "@mui/styles/makeStyles";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
settingsOptionsContainer: {
display: "flex" as const,
flexDirection: "row" as const,
justifyContent: "flex-start" as const,
flexWrap: "wrap" as const,
border: "#E5E5E5 1px solid",
borderRadius: 2,
padding: 5,
backgroundColor: "#fff",
},
...searchField,
...actionsTray,
...containerForHeader(theme.spacing(4)),
})
);
const ToolsList = () => {
const classes = useStyles();
const configurationElements: IElement[] = [
{
icon: <LogsIcon />,
configuration_id: "logs",
configuration_label: "Logs",
disabled: !hasPermission(
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS[IAM_PAGES.TOOLS_LOGS]
),
},
{
icon: <SearchIcon />,
configuration_id: "audit-logs",
configuration_label: "Audit Logs",
disabled: !hasPermission(
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS[IAM_PAGES.TOOLS_AUDITLOGS]
),
},
{
icon: <WatchIcon />,
configuration_id: "watch",
configuration_label: "Watch",
disabled: !hasPermission(
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS[IAM_PAGES.TOOLS_WATCH]
),
},
{
icon: <TraceIcon />,
configuration_id: "trace",
configuration_label: "Trace",
disabled: !hasPermission(
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS[IAM_PAGES.TOOLS_TRACE]
),
},
{
icon: <HealIcon />,
configuration_id: "heal",
configuration_label: "Heal",
disabled: !hasPermission(
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS[IAM_PAGES.TOOLS_HEAL]
),
},
{
icon: <DiagnosticsIcon />,
configuration_id: "diagnostics",
configuration_label: "Diagnostics",
disabled: !hasPermission(
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS[IAM_PAGES.TOOLS_DIAGNOSTICS]
),
},
{
icon: <SpeedtestIcon />,
configuration_id: "speedtest",
configuration_label: "Speedtest",
disabled: !hasPermission(
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS[IAM_PAGES.TOOLS_SPEEDTEST]
),
},
];
return (
<Fragment>
<PageHeader label={"Tools"} />
<PageLayout>
<Grid item xs={12}>
<Grid item xs={12}>
<div className={classes.settingsOptionsContainer}>
{configurationElements.map((element) => (
<SettingsCard
prefix={"tools"}
configuration={element}
key={`configItem-${element.configuration_label}`}
disabled={element.disabled || false}
/>
))}
</div>
</Grid>
</Grid>
</PageLayout>
</Fragment>
);
};
export default ToolsList;

View File

@@ -28,14 +28,12 @@ import { CreateUserIcon } from "../../../icons";
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 PolicySelectors from "../Policies/PolicySelectors";
import BackLink from "../../../common/BackLink";
import GroupsSelectors from "./GroupsSelectors";
import { useDispatch } from "react-redux";
import { User } from "./types";
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
@@ -46,10 +44,10 @@ import api from "../../../../src/common/api";
import FormLayout from "../Common/FormLayout";
import AddUserHelpBox from "./AddUserHelpBox";
import { setErrorSnackMessage } from "../../../systemSlice";
import { useNavigate } from "react-router-dom";
interface IAddUserProps {
classes: any;
selectedUser: User | null;
}
const styles = (theme: Theme) =>
@@ -73,6 +71,8 @@ const styles = (theme: Theme) =>
const AddUser = ({ classes }: IAddUserProps) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const [addLoading, setAddLoading] = useState<boolean>(false);
const [accessKey, setAccessKey] = useState<string>("");
const [secretKey, setSecretKey] = useState<string>("");
@@ -109,7 +109,7 @@ const AddUser = ({ classes }: IAddUserProps) => {
})
.then((res) => {
setAddLoading(false);
history.push(`${IAM_PAGES.USERS}`);
navigate(`${IAM_PAGES.USERS}`);
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);

View File

@@ -16,6 +16,7 @@
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 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 BackLink from "../../../common/BackLink";
@@ -52,7 +52,6 @@ import { setErrorSnackMessage } from "../../../systemSlice";
interface IAddServiceAccountProps {
classes: any;
match: any;
}
const styles = (theme: Theme) =>
@@ -74,8 +73,11 @@ const styles = (theme: Theme) =>
...modalStyleUtils,
});
const AddServiceAccount = ({ classes, match }: IAddServiceAccountProps) => {
const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
const dispatch = useDispatch();
const params = useParams();
const navigate = useNavigate();
const [addSending, setAddSending] = useState<boolean>(false);
const [accessKey, setAccessKey] = useState<string>(getRandomString(16));
const [secretKey, setSecretKey] = useState<string>(getRandomString(32));
@@ -86,7 +88,7 @@ const AddServiceAccount = ({ classes, match }: IAddServiceAccountProps) => {
const [showPassword, setShowPassword] = useState<boolean>(false);
const [policyJSON, setPolicyJSON] = useState<string>("");
const userName = decodeURLString(match.params["userName"]);
const userName = decodeURLString(params.userName || "");
useEffect(() => {
if (addSending) {
@@ -153,7 +155,7 @@ const AddServiceAccount = ({ classes, match }: IAddServiceAccountProps) => {
const closeCredentialsModal = () => {
setNewServiceAccount(null);
history.push(`${IAM_PAGES.USERS}/${encodeURLString(userName)}`);
navigate(`${IAM_PAGES.USERS}/${encodeURLString(userName)}`);
};
return (

View File

@@ -17,23 +17,24 @@
import React, { useEffect, useState, Fragment } from "react";
import { connect } from "react-redux";
import { DialogContentText } from "@mui/material";
import { useNavigate } from "react-router-dom";
import { setErrorSnackMessage } from "../../../systemSlice";
import useApi from "../Common/Hooks/useApi";
import ConfirmDialog from "../Common/ModalWrapper/ConfirmDialog";
import { ErrorResponseHandler } from "../../../common/types";
import { ConfirmDeleteIcon } from "../../../icons";
import { encodeURLString } from "../../../common/utils";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import useApi from "../Common/Hooks/useApi";
import ConfirmDialog from "../Common/ModalWrapper/ConfirmDialog";
import WarningMessage from "../Common/WarningMessage/WarningMessage";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import api from "../../../common/api";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import Loader from "../Common/Loader/Loader";
interface IDeleteUserProps {
closeDeleteModalAndRefresh: (refresh: boolean) => void;
deleteOpen: boolean;
selectedUsers: string[] | null;
setErrorSnackMessage: typeof setErrorSnackMessage;
history: any;
}
const DeleteUser = ({
@@ -41,8 +42,9 @@ const DeleteUser = ({
deleteOpen,
selectedUsers,
setErrorSnackMessage,
history,
}: IDeleteUserProps) => {
const navigate = useNavigate();
const onDelSuccess = () => closeDeleteModalAndRefresh(true);
const onDelError = (err: ErrorResponseHandler) => setErrorSnackMessage(err);
const onClose = () => closeDeleteModalAndRefresh(false);
@@ -81,7 +83,7 @@ const DeleteUser = ({
</div>
));
const viewAction = (selectionElement: any): void => {
history.push(
navigate(
`${IAM_PAGES.USERS}/${encodeURLString(selectionElement.userName)}`
);
onClose();
@@ -104,7 +106,7 @@ const DeleteUser = ({
} else {
invokeDeleteApi("DELETE", `/api/v1/user/${encodeURLString(user)}`);
closeDeleteModalAndRefresh(true);
history.push(`${IAM_PAGES.USERS}`);
navigate(`${IAM_PAGES.USERS}`);
}
}
};

View File

@@ -16,10 +16,9 @@
import React from "react";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import { DialogContentText } from "@mui/material";
import { ErrorResponseHandler } from "../../../common/types";
import history from "../../../history";
import useApi from "../Common/Hooks/useApi";
import ConfirmDialog from "../Common/ModalWrapper/ConfirmDialog";
import { ConfirmDeleteIcon } from "../../../icons";
@@ -39,8 +38,10 @@ const DeleteUserModal = ({
userName,
}: IDeleteUserStringProps) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const onDelSuccess = () => {
history.push(IAM_PAGES.USERS);
navigate(IAM_PAGES.USERS);
};
const onDelError = (err: ErrorResponseHandler) =>
dispatch(setErrorSnackMessage(err));

View File

@@ -17,6 +17,7 @@
import React, { Fragment, useEffect, useState } from "react";
import { useDispatch } from "react-redux";
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 api from "../../../common/api";
@@ -72,11 +73,12 @@ const styles = (theme: Theme) =>
interface IUsersProps {
classes: any;
history: any;
}
const ListUsers = ({ classes, history }: IUsersProps) => {
const ListUsers = ({ classes }: IUsersProps) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const [records, setRecords] = useState<User[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
@@ -159,7 +161,7 @@ const ListUsers = ({ classes, history }: IUsersProps) => {
};
const viewAction = (selectionElement: any): void => {
history.push(
navigate(
`${IAM_PAGES.USERS}/${encodeURLString(selectionElement.accessKey)}`
);
};
@@ -186,7 +188,6 @@ const ListUsers = ({ classes, history }: IUsersProps) => {
closeDeleteModalAndRefresh={(refresh: boolean) => {
closeDeleteModalAndRefresh(refresh);
}}
history={history}
/>
)}
{addGroupOpen && (
@@ -261,7 +262,7 @@ const ListUsers = ({ classes, history }: IUsersProps) => {
icon={<AddIcon />}
color="primary"
onClick={() => {
history.push(`${IAM_PAGES.USER_ADD}`);
navigate(`${IAM_PAGES.USER_ADD}`);
}}
variant={"contained"}
/>
@@ -399,7 +400,7 @@ const ListUsers = ({ classes, history }: IUsersProps) => {
To get started,{" "}
<AButton
onClick={() => {
history.push(`${IAM_PAGES.USER_ADD}`);
navigate(`${IAM_PAGES.USER_ADD}`);
}}
>
Create a User

View File

@@ -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 { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -41,7 +42,6 @@ import api from "../../../common/api";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import ChangeUserGroups from "./ChangeUserGroups";
import SetUserPolicies from "./SetUserPolicies";
import history from "../../../history";
import UserServiceAccountsPanel from "./UserServiceAccountsPanel";
import ChangeUserPasswordModal from "../Account/ChangeUserPasswordModal";
import DeleteUser from "./DeleteUser";
@@ -83,15 +83,16 @@ const styles = (theme: Theme) =>
interface IUserDetailsProps {
classes: any;
match: any;
}
interface IGroupItem {
group: string;
}
const UserDetails = ({ classes, match }: IUserDetailsProps) => {
const UserDetails = ({ classes }: IUserDetailsProps) => {
const dispatch = useDispatch();
const params = useParams();
const navigate = useNavigate();
const [loading, setLoading] = useState<boolean>(false);
const [addGroupOpen, setAddGroupOpen] = useState<boolean>(false);
@@ -106,7 +107,8 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
useState<boolean>(false);
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
const [hasPolicy, setHasPolicy] = useState<boolean>(false);
const userName = decodeURLString(match.params["userName"]);
const userName = decodeURLString(params.userName || "");
const changeUserPassword = () => {
setChangeUserPasswordModalOpen(true);
@@ -187,7 +189,7 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
};
const groupViewAction = (group: any) => {
history.push(`${IAM_PAGES.GROUPS}/${encodeURLString(group.group)}`);
navigate(`${IAM_PAGES.GROUPS}/${encodeURLString(group.group)}`);
};
const groupTableActions = [
@@ -199,7 +201,7 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
];
return (
<React.Fragment>
<Fragment>
<PageHeader
label={
<Fragment>
@@ -236,7 +238,6 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
closeDeleteModalAndRefresh={(refresh: boolean) => {
closeDeleteModalAndRefresh(refresh);
}}
history={history}
/>
)}
{changeUserPasswordModalOpen && (
@@ -338,7 +339,6 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
<UserServiceAccountsPanel
user={userName}
hasPolicy={hasPolicy}
history={history}
/>
),
}}
@@ -347,7 +347,7 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
label: "Policies",
},
content: (
<React.Fragment>
<Fragment>
<div className={classes.actionsTray}>
<PanelTitle>Policies</PanelTitle>
@@ -368,7 +368,7 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
{
type: "view",
onClick: (policy: IPolicyItem) => {
history.push(
navigate(
`${IAM_PAGES.POLICIES}/${encodeURLString(
policy.policy
)}`
@@ -383,13 +383,13 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
idField="policy"
/>
</div>
</React.Fragment>
</Fragment>
),
}}
</VerticalTabs>
</Grid>
</PageLayout>
</React.Fragment>
</Fragment>
);
};

View File

@@ -18,6 +18,7 @@ import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import { Box } from "@mui/material";
import { useNavigate } from "react-router-dom";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import {
@@ -51,7 +52,6 @@ interface IUserServiceAccountsProps {
classes: any;
user: string;
hasPolicy: boolean;
history: any;
}
const styles = (theme: Theme) =>
@@ -68,9 +68,9 @@ const UserServiceAccountsPanel = ({
classes,
user,
hasPolicy,
history,
}: IUserServiceAccountsProps) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const [records, setRecords] = useState<string[]>([]);
const [loading, setLoading] = useState<boolean>(false);
@@ -253,7 +253,7 @@ const UserServiceAccountsPanel = ({
color="primary"
icon={<AddIcon />}
onClick={() => {
history.push(
navigate(
`/identity/users/new-user-sa/${encodeURLString(user)}`
);
}}

View File

@@ -15,26 +15,26 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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 ListUsers from "./ListUsers";
import UserDetails from "./UserDetails";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import AddUserScreen from "./AddUserScreen";
import AddUserServiceAccountScreen from "./AddUserServiceAccountScreen";
const Users = () => {
return (
<Router history={history}>
<Switch>
<Route path={IAM_PAGES.USER_ADD} exact component={AddUserScreen} />
<Route path={IAM_PAGES.USERS_VIEW} exact component={UserDetails} />
<Route path={IAM_PAGES.USERS} exact component={ListUsers} />
<Route component={NotFoundPage} />
</Switch>
</Router>
<Routes>
<Route path={"add-user"} element={<AddUserScreen />} />
<Route path={":userName"} element={<UserDetails />} />
<Route
path={"new-user-sa/:userName"}
element={<AddUserServiceAccountScreen />}
/>
<Route path={"/"} element={<ListUsers />} />
<Route element={<NotFoundPage />} />
</Routes>
);
};
export default withRouter(Users);
export default Users;

View File

@@ -15,7 +15,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import { Action } from "kbar/lib/types";
import history from "../../history";
import { BucketsIcon } from "../../icons";
import { validRoutes } from "./valid-routes";
import { IAM_PAGES } from "../../common/SecureComponent/permissions";
@@ -24,7 +23,8 @@ import { Bucket } from "./Buckets/types";
export const routesAsKbarActions = (
features: string[] | null,
operatorMode: boolean,
buckets: Bucket[]
buckets: Bucket[],
navigate: (url: string) => void
) => {
const initialActions: Action[] = [];
const allowedMenuItems = validRoutes(features, operatorMode);
@@ -35,7 +35,7 @@ export const routesAsKbarActions = (
id: `${childI.id}`,
name: childI.name,
section: i.name,
perform: () => history.push(`${childI.to}`),
perform: () => navigate(`${childI.to}`),
icon: <childI.icon />,
};
initialActions.push(a);
@@ -45,7 +45,7 @@ export const routesAsKbarActions = (
id: `${i.id}`,
name: i.name,
section: "Navigation",
perform: () => history.push(`${i.to}`),
perform: () => navigate(`${i.to}`),
icon: <i.icon />,
};
initialActions.push(a);
@@ -57,7 +57,7 @@ export const routesAsKbarActions = (
id: `create-bucket`,
name: "Create Bucket",
section: "Buckets",
perform: () => history.push(IAM_PAGES.ADD_BUCKETS),
perform: () => navigate(IAM_PAGES.ADD_BUCKETS),
icon: <BucketsIcon />,
};
initialActions.push(a);
@@ -69,7 +69,7 @@ export const routesAsKbarActions = (
name: buck.name,
section: "List of Buckets",
perform: () => {
history.push(`/buckets/${buck.name}/browse`);
navigate(`/buckets/${buck.name}/browse`);
},
icon: <BucketsIcon />,
}),

View File

@@ -15,11 +15,12 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState } from "react"; // eslint-disable-line @typescript-eslint/no-unused-vars
import { useNavigate } from "react-router-dom";
import api from "../../common/api";
import withStyles from "@mui/styles/withStyles";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import history, { baseUrl } from "../../history";
import { baseUrl } from "../../history";
import { Paper } from "@mui/material";
import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";
@@ -110,6 +111,8 @@ interface ILoginCallBackProps {
}
const LoginCallback = ({ classes }: ILoginCallBackProps) => {
const navigate = useNavigate();
const [error, setError] = useState<string>("");
const [errorDescription, setErrorDescription] = useState<string>("");
const [loading, setLoading] = useState<boolean>(true);
@@ -140,7 +143,7 @@ const LoginCallback = ({ classes }: ILoginCallBackProps) => {
localStorage.setItem("redirect-path", "");
}
setLoading(false);
history.push(targetPath);
navigate(targetPath);
})
.catch((error) => {
setError(error.errorMessage);
@@ -149,7 +152,7 @@ const LoginCallback = ({ classes }: ILoginCallBackProps) => {
});
}
}
}, [loading]);
}, [loading, navigate]);
return error !== "" || errorDescription !== "" ? (
<React.Fragment>
<Paper className={classes.paper}>

View File

@@ -16,6 +16,7 @@
import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import {
Box,
InputAdornment,
@@ -32,7 +33,6 @@ import Grid from "@mui/material/Grid";
import { ILoginDetails, loginStrategyType } from "./types";
import { ErrorResponseHandler } from "../../common/types";
import api from "../../common/api";
import history from "../../history";
import RefreshIcon from "../../icons/RefreshIcon";
import MainError from "../Console/Common/MainError/MainError";
import {
@@ -287,6 +287,7 @@ interface LoginStrategyPayload {
const Login = ({ classes }: ILoginProps) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const [accessKey, setAccessKey] = useState<string>("");
const [jwt, setJwt] = useState<string>("");
@@ -338,7 +339,7 @@ const Login = ({ classes }: ILoginProps) => {
targetPath = `${localStorage.getItem("redirect-path")}`;
localStorage.setItem("redirect-path", "");
}
history.push(targetPath);
navigate(targetPath);
})
.catch((err) => {
setLoginSending(false);

File diff suppressed because it is too large Load Diff

View File

@@ -6976,6 +6976,20 @@ func init() {
}
}
},
"userSAs": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"recursive": {
"type": "boolean"
},
"versionID": {
"type": "string"
}
}
},
"userServiceAccountItem": {
"type": "object",
"properties": {
@@ -14175,6 +14189,20 @@ func init() {
}
}
},
"userSAs": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"recursive": {
"type": "boolean"
},
"versionID": {
"type": "string"
}
}
},
"userServiceAccountItem": {
"type": "object",
"properties": {

View File

@@ -19,7 +19,7 @@ securityDefinitions:
tokenUrl: http://min.io
# Apply the key security definition to all APIs
security:
- key: []
- key: [ ]
paths:
/login:
get:
@@ -35,7 +35,7 @@ paths:
schema:
$ref: "#/definitions/error"
# Exclude this API from the authentication requirement
security: []
security: [ ]
tags:
- Auth
post:
@@ -55,7 +55,7 @@ paths:
schema:
$ref: "#/definitions/error"
# Exclude this API from the authentication requirement
security: []
security: [ ]
tags:
- Auth
/login/oauth2/auth:
@@ -75,7 +75,7 @@ paths:
description: Generic error response.
schema:
$ref: "#/definitions/error"
security: []
security: [ ]
tags:
- Auth
@@ -122,7 +122,7 @@ paths:
description: Generic error response.
schema:
$ref: "#/definitions/error"
security: []
security: [ ]
tags:
- System
@@ -2823,7 +2823,7 @@ paths:
- name: order
in: query
type: string
enum: [timeDesc, timeAsc]
enum: [ timeDesc, timeAsc ]
default: timeDesc
- name: timeStart
in: query
@@ -2917,7 +2917,7 @@ definitions:
type: string
numSAs:
type: integer
format: int64
format: int64
bucket:
type: object
@@ -3656,7 +3656,7 @@ definitions:
properties:
loginStrategy:
type: string
enum: [form, redirect, service-account, redirect-service-account]
enum: [ form, redirect, service-account, redirect-service-account ]
redirect:
type: string
loginOauth2AuthRequest:
@@ -3739,7 +3739,7 @@ definitions:
type: string
status:
type: string
enum: [ok]
enum: [ ok ]
operator:
type: boolean
distributedMode:
@@ -3764,7 +3764,7 @@ definitions:
type: string
values:
type: array
items: {}
items: { }
resultTarget:
type: object
properties:
@@ -4156,7 +4156,7 @@ definitions:
type: string
service:
type: string
enum: [replication]
enum: [ replication ]
syncMode:
type: string
bandwidth:
@@ -4670,7 +4670,7 @@ definitions:
recursive:
type: boolean
userSAs:
userSAs:
type: object
properties:
path: