Redux Toolkit Redux Rewrite (#2003)

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2022-05-18 17:02:26 -05:00
committed by GitHub
parent f6cab5a65b
commit 6e31a42886
240 changed files with 6298 additions and 10745 deletions

View File

@@ -16,6 +16,7 @@
"@mui/material": "^5.4.0",
"@mui/styled-engine-sc": "^5.3.0",
"@mui/styles": "^5.3.0",
"@reduxjs/toolkit": "^1.8.1",
"@types/history": "^4.7.3",
"@types/jest": "27.4.0",
"@types/lodash": "^4.14.149",
@@ -25,7 +26,7 @@
"@types/react-copy-to-clipboard": "^5.0.2",
"@types/react-dom": "17.0.11",
"@types/react-grid-layout": "^1.1.1",
"@types/react-redux": "^7.1.5",
"@types/react-redux": "^7.1.24",
"@types/react-router": "^5.1.3",
"@types/react-router-dom": "^5.1.2",
"@types/react-virtualized": "^9.21.10",
@@ -92,8 +93,8 @@
"react-app-rewire-hot-loader": "^2.0.1",
"react-app-rewired": "^2.1.6",
"react-scripts": "5.0.1",
"typescript": "^4.4.3",
"testcafe": "^1.18.6"
"testcafe": "^1.18.6",
"typescript": "^4.4.3"
},
"resolutions": {
"nth-check": "^2.0.1",

View File

@@ -16,74 +16,63 @@
import React, { useEffect, useState } from "react";
import { Redirect } from "react-router-dom";
import { connect } from "react-redux";
import { AppState } from "./store";
import {
consoleOperatorMode,
setDistributedMode,
setErrorSnackMessage,
setSiteReplicationInfo,
userLoggedIn,
} from "./actions";
import api from "./common/api";
import { saveSessionResponse } from "./screens/Console/actions";
import { ISessionResponse } from "./screens/Console/types";
import useApi from "./screens/Console/Common/Hooks/useApi";
import { ErrorResponseHandler } from "./common/types";
import { ReplicationSite } from "./screens/Console/Configurations/SiteReplication/SiteReplication";
import { SRInfoStateType } from "./types";
import { baseUrl } from "./history";
import { useDispatch, useSelector } from "react-redux";
import {
globalSetDistributedSetup,
operatorMode,
setSiteReplicationInfo,
userLogged,
} from "./systemSlice";
import { SRInfoStateType } from "./types";
import { AppState } from "./store";
import { saveSessionResponse } from "./screens/Console/consoleSlice";
interface ProtectedRouteProps {
loggedIn: boolean;
Component: any;
userLoggedIn: typeof userLoggedIn;
consoleOperatorMode: typeof consoleOperatorMode;
saveSessionResponse: typeof saveSessionResponse;
setDistributedMode: typeof setDistributedMode;
setSiteReplicationInfo: typeof setSiteReplicationInfo;
}
const ProtectedRoute = ({
Component,
loggedIn,
userLoggedIn,
consoleOperatorMode,
saveSessionResponse,
setDistributedMode,
setSiteReplicationInfo,
}: ProtectedRouteProps) => {
const ProtectedRoute = ({ Component }: ProtectedRouteProps) => {
const dispatch = useDispatch();
const isOperatorMode = useSelector(
(state: AppState) => state.system.operatorMode
);
const [sessionLoading, setSessionLoading] = useState<boolean>(true);
const userLoggedIn = useSelector((state: AppState) => state.system.loggedIn);
useEffect(() => {
api
.invoke("GET", `/api/v1/session`)
.then((res: ISessionResponse) => {
saveSessionResponse(res);
userLoggedIn(true);
dispatch(saveSessionResponse(res));
dispatch(userLogged(true));
setSessionLoading(false);
setDistributedMode(res.distributedMode || false);
dispatch(globalSetDistributedSetup(res.distributedMode || false));
// check for tenants presence, that indicates we are in operator mode
if (res.operator) {
consoleOperatorMode(true);
dispatch(operatorMode(true));
document.title = "MinIO Operator";
}
})
.catch(() => setSessionLoading(false));
}, [
saveSessionResponse,
consoleOperatorMode,
userLoggedIn,
setDistributedMode,
]);
}, [dispatch]);
const [, invokeSRInfoApi] = useApi(
(res: any) => {
const {
sites: siteList = [],
name: curSiteName,
enabled = false,
} = res || {};
const { name: curSiteName, enabled = false } = res || {};
let siteList = res.site;
if (!siteList) {
siteList = [];
}
const isSiteNameInList = siteList.find((si: ReplicationSite) => {
return si.name === curSiteName;
});
@@ -95,42 +84,31 @@ const ProtectedRoute = ({
siteName: isCurSite ? curSiteName : "",
};
setSiteReplicationInfo(siteReplicationDetail);
dispatch(setSiteReplicationInfo(siteReplicationDetail));
},
(err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
// we will fail this call silently, but show it on the console
console.error(`Error loading site replication status`, err);
}
);
useEffect(() => {
if (loggedIn && !sessionLoading) {
if (userLoggedIn && !sessionLoading && !isOperatorMode) {
invokeSRInfoApi("GET", `api/v1/admin/site-replication`);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [loggedIn, sessionLoading]);
}, [userLoggedIn, sessionLoading]);
// if we still trying to retrieve user session render nothing
// if we're still trying to retrieve user session render nothing
if (sessionLoading) {
return null;
}
// redirect user to the right page based on session status
return loggedIn ? (
return userLoggedIn ? (
<Component />
) : (
<Redirect to={{ pathname: `${baseUrl}login` }} />
);
};
const mapState = (state: AppState) => ({
loggedIn: state.system.loggedIn,
});
const connector = connect(mapState, {
userLoggedIn,
consoleOperatorMode,
saveSessionResponse,
setDistributedMode,
setSiteReplicationInfo,
});
export default connector(ProtectedRoute);
export default ProtectedRoute;

View File

@@ -1,126 +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 { ErrorResponseHandler } from "./common/types";
import {
MENU_OPEN,
OPERATOR_MODE,
SERVER_IS_LOADING,
SERVER_NEEDS_RESTART,
USER_LOGGED,
SET_LOADING_PROGRESS,
SET_SNACK_BAR_MESSAGE,
SET_SERVER_DIAG_STAT,
SET_ERROR_SNACK_MESSAGE,
SET_SNACK_MODAL_MESSAGE,
SET_MODAL_ERROR_MESSAGE,
GLOBAL_SET_DISTRIBUTED_SETUP,
SET_SITE_REPLICATION_INFO,
SRInfoStateType,
} from "./types";
export function userLoggedIn(loggedIn: boolean) {
return {
type: USER_LOGGED,
logged: loggedIn,
};
}
export function consoleOperatorMode(operatorMode: boolean) {
return {
type: OPERATOR_MODE,
operatorMode: operatorMode,
};
}
export function setMenuOpen(open: boolean) {
return {
type: MENU_OPEN,
open: open,
};
}
export function serverNeedsRestart(needsRestart: boolean) {
return {
type: SERVER_NEEDS_RESTART,
needsRestart: needsRestart,
};
}
export function serverIsLoading(isLoading: boolean) {
return {
type: SERVER_IS_LOADING,
isLoading: isLoading,
};
}
export const setLoadingProgress = (progress: number) => {
return {
type: SET_LOADING_PROGRESS,
loadingProgress: progress,
};
};
export const setServerDiagStat = (status: string) => {
return {
type: SET_SERVER_DIAG_STAT,
serverDiagnosticStatus: status,
};
};
export const setSnackBarMessage = (message: string) => {
return {
type: SET_SNACK_BAR_MESSAGE,
message,
};
};
export const setErrorSnackMessage = (message: ErrorResponseHandler) => {
return {
type: SET_ERROR_SNACK_MESSAGE,
message,
};
};
export const setModalSnackMessage = (message: string) => {
return {
type: SET_SNACK_MODAL_MESSAGE,
message,
};
};
export const setModalErrorSnackMessage = (message: ErrorResponseHandler) => {
return {
type: SET_MODAL_ERROR_MESSAGE,
message,
};
};
export const setDistributedMode = (distributedSetup: boolean) => {
return {
type: GLOBAL_SET_DISTRIBUTED_SETUP,
distributedSetup,
};
};
export const setSiteReplicationInfo = (
siteReplicationInfo: SRInfoStateType
) => {
return {
type: SET_SITE_REPLICATION_INFO,
siteReplicationInfo,
};
};

View File

@@ -16,13 +16,12 @@
import hasPermission from "../accessControl";
import { store } from "../../../store";
import { SESSION_RESPONSE } from "../../../screens/Console/actions";
import { IAM_PAGES, IAM_PAGES_PERMISSIONS, IAM_SCOPES } from "../permissions";
import { saveSessionResponse } from "../../../screens/Console/consoleSlice";
const setPolicy1 = () => {
store.dispatch({
type: SESSION_RESPONSE,
message: {
store.dispatch(
saveSessionResponse({
distributedMode: true,
features: ["log-search"],
permissions: {
@@ -50,13 +49,12 @@ const setPolicy1 = () => {
},
operator: false,
status: "ok",
},
});
})
);
};
const setPolicy2 = () => {
store.dispatch({
type: SESSION_RESPONSE,
message: {
store.dispatch(
saveSessionResponse({
distributedMode: true,
operator: false,
features: [],
@@ -93,13 +91,12 @@ const setPolicy2 = () => {
"console-ui": ["admin:CreateServiceAccount", "admin:CreateUser"],
},
status: "ok",
},
});
})
);
};
const setPolicy3 = () => {
store.dispatch({
type: SESSION_RESPONSE,
message: {
store.dispatch(
saveSessionResponse({
distributedMode: true,
features: [],
permissions: {
@@ -112,14 +109,13 @@ const setPolicy3 = () => {
},
status: "ok",
operator: false,
},
});
})
);
};
const setPolicy4 = () => {
store.dispatch({
type: SESSION_RESPONSE,
message: {
store.dispatch(
saveSessionResponse({
distributedMode: true,
features: [],
permissions: {
@@ -129,8 +125,8 @@ const setPolicy4 = () => {
},
status: "ok",
operator: false,
},
});
})
);
};
test("Upload button disabled", () => {

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 82.816 18.487"><defs><style>.cls-1{fill:#1e1059;}</style></defs><title>mkube_logo_temp</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M19,18.127H16.152V3.612L11,16.4H8L2.848,3.751V18.127H0V.487H4.372L9.5,13.087,14.628.487H19Z"/><path class="cls-1" d="M28.556,10.623h-1.7v7.533H24V.489h2.852V7.922h1.741L35.231.489h3.685l-7.95,8.619,8.492,9.048H35.584Z"/><path class="cls-1" d="M51.962,13.049c0,3.848-2.775,5.438-5.6,5.438s-5.6-1.59-5.6-5.438V6.083h2.65v6.726c0,2.335,1.3,3.192,2.953,3.192s2.952-.857,2.952-3.192V6.083h2.65Z"/><path class="cls-1" d="M68.6,12.127a6.068,6.068,0,0,1-6.045,6.36,4.584,4.584,0,0,1-3.785-1.754v1.439H56.136V0h2.638V7.521a4.584,4.584,0,0,1,3.785-1.753A6.068,6.068,0,0,1,68.6,12.127Zm-10.007,0a3.654,3.654,0,1,0,7.294,0,3.654,3.654,0,1,0-7.294,0Z"/><path class="cls-1" d="M82.816,12.115c0,.34-.025.681-.051.984H73.831a3.415,3.415,0,0,0,3.6,3.079,5.778,5.778,0,0,0,3.5-1.275l1.312,1.881a7.279,7.279,0,0,1-4.971,1.7,5.963,5.963,0,0,1-6.184-6.36c0-3.785,2.461-6.359,6.02-6.359C80.481,5.768,82.8,8.342,82.816,12.115Zm-8.972-1.022h6.271c-.29-1.881-1.388-2.979-3.066-2.979A3.123,3.123,0,0,0,73.844,11.093Z"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -18,7 +18,7 @@ import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import Routes from "./Routes";
import configureStore from "./store";
import { store } from "./store";
import * as serviceWorker from "./serviceWorker";
import {
StyledEngineProvider,
@@ -127,7 +127,7 @@ const GlobalCss = withStyles({
})(() => null);
ReactDOM.render(
<Provider store={configureStore()}>
<Provider store={store}>
<GlobalCss />
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,159 +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 {
GLOBAL_SET_DISTRIBUTED_SETUP,
MENU_OPEN,
OPERATOR_MODE,
SERVER_IS_LOADING,
SERVER_NEEDS_RESTART,
SET_ERROR_SNACK_MESSAGE,
SET_LOADING_PROGRESS,
SET_MODAL_ERROR_MESSAGE,
SET_SERVER_DIAG_STAT,
SET_SITE_REPLICATION_INFO,
SET_SNACK_BAR_MESSAGE,
SET_SNACK_MODAL_MESSAGE,
SystemActionTypes,
SystemState,
USER_LOGGED,
} from "./types";
// determine whether we have the sidebar state stored on localstorage
const initSideBarOpen = localStorage.getItem("sidebarOpen")
? JSON.parse(localStorage.getItem("sidebarOpen")!)["open"]
: true;
const initialState: SystemState = {
loggedIn: false,
operatorMode: false,
session: "",
userName: "",
sidebarOpen: initSideBarOpen,
siteReplicationInfo: { siteName: "", curSite: false, enabled: false },
serverNeedsRestart: false,
serverIsLoading: false,
loadingProgress: 100,
snackBar: {
message: "",
detailedErrorMsg: "",
type: "message",
},
modalSnackBar: {
message: "",
detailedErrorMsg: "",
type: "message",
},
serverDiagnosticStatus: "",
distributedSetup: false,
};
export function systemReducer(
state = initialState,
action: SystemActionTypes
): SystemState {
switch (action.type) {
case USER_LOGGED:
return {
...state,
loggedIn: action.logged,
};
case OPERATOR_MODE:
return {
...state,
operatorMode: action.operatorMode,
};
case MENU_OPEN:
// persist preference to local storage
localStorage.setItem(
"sidebarOpen",
JSON.stringify({ open: action.open })
);
return {
...state,
sidebarOpen: action.open,
};
case SERVER_NEEDS_RESTART:
return {
...state,
serverNeedsRestart: action.needsRestart,
};
case SERVER_IS_LOADING:
return {
...state,
serverIsLoading: action.isLoading,
};
case SET_LOADING_PROGRESS:
return {
...state,
loadingProgress: action.loadingProgress,
};
case SET_SNACK_BAR_MESSAGE:
return {
...state,
snackBar: {
message: action.message,
detailedErrorMsg: "",
type: "message",
},
};
case SET_ERROR_SNACK_MESSAGE:
return {
...state,
snackBar: {
message: action.message.errorMessage,
detailedErrorMsg: action.message.detailedError,
type: "error",
},
};
case SET_SNACK_MODAL_MESSAGE:
return {
...state,
modalSnackBar: {
message: action.message,
detailedErrorMsg: "",
type: "message",
},
};
case SET_MODAL_ERROR_MESSAGE:
return {
...state,
modalSnackBar: {
message: action.message.errorMessage,
detailedErrorMsg: action.message.detailedError,
type: "error",
},
};
case SET_SERVER_DIAG_STAT:
return {
...state,
serverDiagnosticStatus: action.serverDiagnosticStatus,
};
case GLOBAL_SET_DISTRIBUTED_SETUP:
return {
...state,
distributedSetup: action.distributedSetup,
};
case SET_SITE_REPLICATION_INFO:
return {
...state,
siteReplicationInfo: action.siteReplicationInfo,
};
default:
return state;
}
}

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 { connect } from "react-redux";
import { connect, useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import Grid from "@mui/material/Grid";
import api from "../../../common/api";
import { Box } from "@mui/material";
import { setErrorSnackMessage, setSnackBarMessage } from "../../../actions";
import {
AccountIcon,
AddIcon,
PasswordKeyIcon,
DeleteIcon,
PasswordKeyIcon,
} from "../../../icons";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import { stringSort } from "../../../utils/sortFunctions";
@@ -47,8 +47,8 @@ import SearchBox from "../Common/SearchBox";
import withSuspense from "../Common/Components/withSuspense";
import {
CONSOLE_UI_RESOURCE,
IAM_SCOPES,
IAM_PAGES,
IAM_SCOPES,
} from "../../../common/SecureComponent/permissions";
import { SecureComponent } from "../../../common/SecureComponent";
import RBIconButton from "../Buckets/BucketDetails/SummaryItems/RBIconButton";
@@ -56,6 +56,7 @@ import { selectSAs } from "../Configurations/utils";
import DeleteMultipleServiceAccounts from "../Users/DeleteMultipleServiceAccounts";
import ServiceAccountPolicy from "./ServiceAccountPolicy";
import { AppState } from "../../../store";
import { setErrorSnackMessage, setSnackBarMessage } from "../../../systemSlice";
const DeleteServiceAccount = withSuspense(
React.lazy(() => import("./DeleteServiceAccount"))
@@ -77,16 +78,11 @@ const styles = (theme: Theme) =>
interface IServiceAccountsProps {
classes: any;
history: any;
displayErrorMessage: typeof setErrorSnackMessage;
features: any;
}
const Account = ({
classes,
displayErrorMessage,
history,
features,
}: IServiceAccountsProps) => {
const Account = ({ classes, history, features }: IServiceAccountsProps) => {
const dispatch = useDispatch();
const [records, setRecords] = useState<string[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const [filter, setFilter] = useState<string>("");
@@ -105,7 +101,7 @@ const Account = ({
useEffect(() => {
fetchRecords();
}, []);
useEffect(() => {
if (loading) {
api
@@ -117,11 +113,11 @@ const Account = ({
setRecords(serviceAccounts);
})
.catch((err: ErrorResponseHandler) => {
displayErrorMessage(err);
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}
}, [loading, setLoading, setRecords, displayErrorMessage]);
}, [loading, setLoading, setRecords, dispatch]);
const fetchRecords = () => {
setLoading(true);
@@ -138,7 +134,7 @@ const Account = ({
const closeDeleteMultipleModalAndRefresh = (refresh: boolean) => {
setDeleteMultipleOpen(false);
if (refresh) {
setSnackBarMessage(`Service accounts deleted successfully.`);
dispatch(setSnackBarMessage(`Service accounts deleted successfully.`));
setSelectedSAs([]);
setLoading(true);
}
@@ -310,8 +306,6 @@ const mapState = (state: AppState) => ({
features: state.console.session.features,
});
const connector = connect(mapState, {
displayErrorMessage: setErrorSnackMessage,
});
const connector = connect(mapState, null);
export default withStyles(styles)(connector(Account));

View File

@@ -17,9 +17,9 @@ import React from "react";
import { Box } from "@mui/material";
import {
HelpIconFilled,
ServiceAccountIcon,
PasswordKeyIcon,
IAMPoliciesIcon,
PasswordKeyIcon,
ServiceAccountIcon,
} from "../../../icons";
const FeatureItem = ({

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, useState, useEffect } from "react";
import React, { Fragment, useEffect, useState } from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -23,8 +23,12 @@ import {
modalStyleUtils,
} from "../Common/FormComponents/common/styleLibrary";
import Grid from "@mui/material/Grid";
import { Button, Box } from "@mui/material";
import { PasswordKeyIcon, ServiceAccountCredentialsIcon } from "../../../icons";
import { Box, Button } from "@mui/material";
import {
IAMPoliciesIcon,
PasswordKeyIcon,
ServiceAccountCredentialsIcon,
} from "../../../icons";
import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
import PageHeader from "../Common/PageHeader/PageHeader";
import PageLayout from "../Common/Layout/PageLayout";
@@ -34,22 +38,21 @@ import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSw
import AddServiceAccountHelpBox from "./AddServiceAccountHelpBox";
import BackLink from "../../../common/BackLink";
import { NewServiceAccount } from "../Common/CredentialsPrompt/types";
import { connect } from "react-redux";
import { IAMPoliciesIcon } from "../../../icons";
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import { ErrorResponseHandler } from "../../../../src/common/types";
import api from "../../../../src/common/api";
import CredentialsPrompt from "../Common/CredentialsPrompt/CredentialsPrompt";
import { setErrorSnackMessage } from "../../../../src/actions";
import SectionTitle from "../Common/SectionTitle";
import { getRandomString } from "../../../screens/Console/Tenants/utils";
import PanelTitle from "../Common/PanelTitle/PanelTitle";
import { useDispatch } from "react-redux";
import { setErrorSnackMessage } from "../../../systemSlice";
interface IAddServiceAccountProps {
classes: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
@@ -71,10 +74,8 @@ const styles = (theme: Theme) =>
...modalStyleUtils,
});
const AddServiceAccount = ({
classes,
setErrorSnackMessage,
}: IAddServiceAccountProps) => {
const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
const dispatch = useDispatch();
const [addSending, setAddSending] = useState<boolean>(false);
const [accessKey, setAccessKey] = useState<string>(getRandomString(16));
const [secretKey, setSecretKey] = useState<string>(getRandomString(32));
@@ -104,17 +105,10 @@ const AddServiceAccount = ({
.catch((err: ErrorResponseHandler) => {
setAddSending(false);
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
});
}
}, [
addSending,
setAddSending,
setErrorSnackMessage,
policyJSON,
accessKey,
secretKey,
]);
}, [addSending, setAddSending, dispatch, policyJSON, accessKey, secretKey]);
useEffect(() => {
if (isRestrictedByPolicy) {
@@ -313,10 +307,4 @@ const AddServiceAccount = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(AddServiceAccount));
export default withStyles(styles)(AddServiceAccount);

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -30,12 +30,12 @@ import {
spacingUtils,
} from "../Common/FormComponents/common/styleLibrary";
import { ChangePasswordRequest } from "../Buckets/types";
import { setModalErrorSnackMessage } from "../../../actions";
import { ErrorResponseHandler } from "../../../common/types";
import api from "../../../common/api";
import { ChangePasswordIcon } from "../../../icons";
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
import { setModalErrorSnackMessage } from "../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -49,15 +49,14 @@ interface IChangePasswordProps {
classes: any;
open: boolean;
closeModal: () => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const ChangePassword = ({
classes,
open,
closeModal,
setModalErrorSnackMessage,
}: IChangePasswordProps) => {
const dispatch = useDispatch();
const [currentPassword, setCurrentPassword] = useState<string>("");
const [newPassword, setNewPassword] = useState<string>("");
const [reNewPassword, setReNewPassword] = useState<string>("");
@@ -70,18 +69,22 @@ const ChangePassword = ({
event.preventDefault();
if (newPassword !== reNewPassword) {
setModalErrorSnackMessage({
errorMessage: "New passwords don't match",
detailedError: "",
});
dispatch(
setModalErrorSnackMessage({
errorMessage: "New passwords don't match",
detailedError: "",
})
);
return;
}
if (newPassword.length < 8) {
setModalErrorSnackMessage({
errorMessage: "Passwords must be at least 8 characters long",
detailedError: "",
});
dispatch(
setModalErrorSnackMessage({
errorMessage: "Passwords must be at least 8 characters long",
detailedError: "",
})
);
return;
}
@@ -109,7 +112,7 @@ const ChangePassword = ({
setNewPassword("");
setReNewPassword("");
setCurrentPassword("");
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -215,8 +218,4 @@ const ChangePassword = ({
) : null;
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(ChangePassword));
export default withStyles(styles)(ChangePassword);

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -30,10 +30,11 @@ import {
spacingUtils,
} from "../Common/FormComponents/common/styleLibrary";
import { ChangeUserPasswordRequest } from "../Buckets/types";
import { setModalErrorSnackMessage } from "../../../actions";
import { ErrorResponseHandler } from "../../../common/types";
import api from "../../../common/api";
import { ChangePasswordIcon } from "../../../icons";
import { setModalErrorSnackMessage } from "../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -51,7 +52,6 @@ interface IChangeUserPasswordProps {
open: boolean;
userName: string;
closeModal: () => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const ChangeUserPassword = ({
@@ -59,8 +59,8 @@ const ChangeUserPassword = ({
open,
userName,
closeModal,
setModalErrorSnackMessage,
}: IChangeUserPasswordProps) => {
const dispatch = useDispatch();
const [newPassword, setNewPassword] = useState<string>("");
const [reNewPassword, setReNewPassword] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false);
@@ -74,10 +74,12 @@ const ChangeUserPassword = ({
setLoading(true);
if (newPassword.length < 8) {
setModalErrorSnackMessage({
errorMessage: "Passwords must be at least 8 characters long",
detailedError: "",
});
dispatch(
setModalErrorSnackMessage({
errorMessage: "Passwords must be at least 8 characters long",
detailedError: "",
})
);
setLoading(false);
return;
}
@@ -99,7 +101,7 @@ const ChangeUserPassword = ({
setLoading(false);
setNewPassword("");
setReNewPassword("");
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -175,8 +177,4 @@ const ChangeUserPassword = ({
) : null;
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(ChangeUserPassword));
export default withStyles(styles)(ChangeUserPassword);

View File

@@ -15,17 +15,18 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { DialogContentText } from "@mui/material";
import { setErrorSnackMessage } from "../../../actions";
import { ErrorResponseHandler } from "../../../common/types";
import useApi from "../Common/Hooks/useApi";
import ConfirmDialog from "../Common/ModalWrapper/ConfirmDialog";
import { ConfirmDeleteIcon } from "../../../icons";
import { encodeURLString } from "../../../common/utils";
import { setErrorSnackMessage } from "../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -41,7 +42,6 @@ interface IDeleteServiceAccountProps {
closeDeleteModalAndRefresh: (refresh: boolean) => void;
deleteOpen: boolean;
selectedServiceAccount: string | null;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const DeleteServiceAccount = ({
@@ -49,10 +49,11 @@ const DeleteServiceAccount = ({
closeDeleteModalAndRefresh,
deleteOpen,
selectedServiceAccount,
setErrorSnackMessage,
}: IDeleteServiceAccountProps) => {
const dispatch = useDispatch();
const onDelSuccess = () => closeDeleteModalAndRefresh(true);
const onDelError = (err: ErrorResponseHandler) => setErrorSnackMessage(err);
const onDelError = (err: ErrorResponseHandler) =>
dispatch(setErrorSnackMessage(err));
const onClose = () => closeDeleteModalAndRefresh(false);
const [deleteLoading, invokeDeleteApi] = useApi(onDelSuccess, onDelError);
@@ -87,10 +88,4 @@ const DeleteServiceAccount = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(DeleteServiceAccount));
export default withStyles(styles)(DeleteServiceAccount);

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 { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { Button } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -26,13 +26,14 @@ import {
modalStyleUtils,
spacingUtils,
} from "../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../actions";
import { ErrorResponseHandler } from "../../../common/types";
import api from "../../../common/api";
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
import { ChangeAccessPolicyIcon } from "../../../icons";
import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
import { encodeURLString } from "../../../common/utils";
import { setModalErrorSnackMessage } from "../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -59,7 +60,6 @@ interface IServiceAccountPolicyProps {
open: boolean;
selectedAccessKey: string | null;
closeModalAndRefresh: () => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const ServiceAccountPolicy = ({
@@ -67,8 +67,8 @@ const ServiceAccountPolicy = ({
open,
selectedAccessKey,
closeModalAndRefresh,
setModalErrorSnackMessage,
}: IServiceAccountPolicyProps) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [policyDefinition, setPolicyDefinition] = useState<string>("");
useEffect(() => {
@@ -86,10 +86,10 @@ const ServiceAccountPolicy = ({
})
.catch((err: ErrorResponseHandler) => {
setLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
}
}, [loading, setLoading, setModalErrorSnackMessage, selectedAccessKey]);
}, [loading, setLoading, dispatch, selectedAccessKey]);
const setPolicy = (event: React.FormEvent, newPolicy: string) => {
event.preventDefault();
@@ -105,7 +105,7 @@ const ServiceAccountPolicy = ({
closeModalAndRefresh();
})
.catch((err: ErrorResponseHandler) => {
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -163,8 +163,4 @@ const ServiceAccountPolicy = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(ServiceAccountPolicy));
export default withStyles(styles)(ServiceAccountPolicy);

View File

@@ -15,12 +15,12 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { connect } from "react-redux";
import { connect, useDispatch } from "react-redux";
import { Paper } from "@mui/material";
import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../actions";
import { TabPanel } from "../../../shared/tabs";
import { Policy } from "../../Policies/types";
import { ISessionResponse } from "../../types";
@@ -37,14 +37,15 @@ import {
} from "../../../../common/SecureComponent/permissions";
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
import {
SecureComponent,
hasPermission,
SecureComponent,
} from "../../../../common/SecureComponent";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import { tableStyles } from "../../Common/FormComponents/common/styleLibrary";
import withStyles from "@mui/styles/withStyles";
import { encodeURLString } from "../../../../common/utils";
import { setErrorSnackMessage } from "../../../../systemSlice";
const mapState = (state: AppState) => ({
session: state.console.session,
@@ -52,7 +53,7 @@ const mapState = (state: AppState) => ({
bucketInfo: state.buckets.bucketDetails.bucketInfo,
});
const connector = connect(mapState, { setErrorSnackMessage });
const connector = connect(mapState, null);
function a11yProps(index: any) {
return {
@@ -63,7 +64,7 @@ function a11yProps(index: any) {
interface IAccessDetailsProps {
session: ISessionResponse;
setErrorSnackMessage: typeof setErrorSnackMessage;
classes: any;
match: any;
loadingBucket: boolean;
@@ -76,10 +77,11 @@ const styles = (theme: Theme) =>
});
const AccessDetails = ({
match,
setErrorSnackMessage,
loadingBucket,
classes,
}: IAccessDetailsProps) => {
const dispatch = useDispatch();
const [curTab, setCurTab] = useState<number>(0);
const [loadingPolicies, setLoadingPolicies] = useState<boolean>(true);
const [bucketPolicy, setBucketPolicy] = useState<Policy[]>([]);
@@ -148,14 +150,14 @@ const AccessDetails = ({
setLoadingUsers(false);
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
setLoadingUsers(false);
});
} else {
setLoadingUsers(false);
}
}
}, [loadingUsers, setErrorSnackMessage, bucketName, displayUsersList]);
}, [loadingUsers, dispatch, bucketName, displayUsersList]);
useEffect(() => {
if (loadingPolicies) {
@@ -167,14 +169,14 @@ const AccessDetails = ({
setLoadingPolicies(false);
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
setLoadingPolicies(false);
});
} else {
setLoadingPolicies(false);
}
}
}, [loadingPolicies, setErrorSnackMessage, bucketName, displayPoliciesList]);
}, [loadingPolicies, dispatch, bucketName, displayPoliciesList]);
return (
<Fragment>

View File

@@ -15,13 +15,12 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { connect } from "react-redux";
import { connect, useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Paper } from "@mui/material";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../actions";
import { ISessionResponse } from "../../types";
import { ErrorResponseHandler } from "../../../../common/types";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
@@ -40,12 +39,13 @@ import { BucketInfo } from "../types";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
import {
SecureComponent,
hasPermission,
SecureComponent,
} from "../../../../common/SecureComponent";
import withSuspense from "../../Common/Components/withSuspense";
import RBIconButton from "./SummaryItems/RBIconButton";
import { setErrorSnackMessage } from "../../../../systemSlice";
const AddAccessRuleModal = withSuspense(
React.lazy(() => import("./AddAccessRule"))
@@ -80,11 +80,10 @@ const mapState = (state: AppState) => ({
bucketInfo: state.buckets.bucketDetails.bucketInfo,
});
const connector = connect(mapState, { setErrorSnackMessage });
const connector = connect(mapState, null);
interface IAccessRuleProps {
session: ISessionResponse;
setErrorSnackMessage: typeof setErrorSnackMessage;
classes: any;
match: any;
loadingBucket: boolean;
@@ -94,10 +93,10 @@ interface IAccessRuleProps {
const AccessRule = ({
classes,
match,
setErrorSnackMessage,
loadingBucket,
bucketInfo,
}: IAccessRuleProps) => {
const dispatch = useDispatch();
const [loadingAccessRules, setLoadingAccessRules] = useState<boolean>(true);
const [accessRules, setAccessRules] = useState([]);
const [addAccessRuleOpen, setAddAccessRuleOpen] = useState<boolean>(false);
@@ -158,19 +157,14 @@ const AccessRule = ({
setLoadingAccessRules(false);
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
setLoadingAccessRules(false);
});
} else {
setLoadingAccessRules(false);
}
}
}, [
loadingAccessRules,
setErrorSnackMessage,
displayAccessRules,
bucketName,
]);
}, [loadingAccessRules, dispatch, displayAccessRules, bucketName]);
const closeAddAccessRuleModal = () => {
setAddAccessRuleOpen(false);

View File

@@ -25,19 +25,12 @@ import {
formFieldStyles,
modalStyleUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import api from "../../../../common/api";
import { ErrorResponseHandler } from "../../../../common/types";
import { setErrorSnackMessage } from "../../../../actions";
import { AppState } from "../../../../store";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { AddAccessRuleIcon } from "../../../../icons";
const mapState = (state: AppState) => ({
session: state.console.session,
});
const connector = connect(mapState, { setErrorSnackMessage });
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IAddAccessRule {
classes: any;
@@ -58,6 +51,8 @@ const AddAccessRule = ({
classes,
bucket,
}: IAddAccessRule) => {
const dispatch = useDispatch();
const [prefix, setPrefix] = useState("");
const [selectedAccess, setSelectedAccess] = useState<any>("readonly");
@@ -82,7 +77,7 @@ const AddAccessRule = ({
onClose();
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
onClose();
});
};
@@ -147,4 +142,4 @@ const AddAccessRule = ({
);
};
export default withStyles(styles)(connector(AddAccessRule));
export default withStyles(styles)(AddAccessRule);

View File

@@ -15,8 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import get from "lodash/get";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { Button, Grid } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -26,20 +25,19 @@ import {
modalStyleUtils,
spacingUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import { AppState } from "../../../../store";
import { ErrorResponseHandler } from "../../../../common/types";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import api from "../../../../common/api";
import { AddNewTagIcon } from "../../../../icons";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
interface IBucketTagModal {
modalOpen: boolean;
currentTags: any;
bucketName: string;
onCloseAndUpdate: (refresh: boolean) => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
classes: any;
}
@@ -55,9 +53,10 @@ const AddBucketTagModal = ({
currentTags,
onCloseAndUpdate,
bucketName,
setModalErrorSnackMessage,
classes,
}: IBucketTagModal) => {
const dispatch = useDispatch();
const [newKey, setNewKey] = useState<string>("");
const [newLabel, setNewLabel] = useState<string>("");
const [isSending, setIsSending] = useState<boolean>(false);
@@ -83,7 +82,7 @@ const AddBucketTagModal = ({
onCloseAndUpdate(true);
})
.catch((error: ErrorResponseHandler) => {
setModalErrorSnackMessage(error);
dispatch(setModalErrorSnackMessage(error));
setIsSending(false);
});
};
@@ -151,14 +150,4 @@ const AddBucketTagModal = ({
);
};
const mapStateToProps = ({ system }: AppState) => ({
distributedSetup: get(system, "distributedSetup", false),
});
const mapDispatchToProps = {
setModalErrorSnackMessage,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export default withStyles(styles)(connector(AddBucketTagModal));
export default withStyles(styles)(AddBucketTagModal);

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { ChangeEvent, useCallback, useEffect, useState } from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import Grid from "@mui/material/Grid";
import { Button } from "@mui/material";
import { Theme } from "@mui/material/styles";
@@ -33,12 +33,13 @@ import {
formFieldStyles,
modalStyleUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import AutocompleteWrapper from "../../Common/FormComponents/AutocompleteWrapper/AutocompleteWrapper";
import { EventSubscriptionIcon } from "../../../../icons";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -56,7 +57,6 @@ interface IAddEventProps {
open: boolean;
selectedBucket: string;
closeModalAndRefresh: () => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const AddEvent = ({
@@ -64,8 +64,8 @@ const AddEvent = ({
open,
selectedBucket,
closeModalAndRefresh,
setModalErrorSnackMessage,
}: IAddEventProps) => {
const dispatch = useDispatch();
const [addLoading, setAddLoading] = useState<boolean>(false);
const [prefix, setPrefix] = useState<string>("");
const [suffix, setSuffix] = useState<string>("");
@@ -95,7 +95,7 @@ const AddEvent = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -113,9 +113,9 @@ const AddEvent = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
}, [setModalErrorSnackMessage]);
}, [dispatch]);
useEffect(() => {
fetchArnList();
@@ -271,8 +271,4 @@ const AddEvent = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(AddEvent));
export default withStyles(styles)(AddEvent);

View File

@@ -16,7 +16,7 @@
import React, { Fragment, useEffect, useState } from "react";
import get from "lodash/get";
import { connect } 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";
@@ -30,7 +30,7 @@ import {
Typography,
} from "@mui/material";
import Grid from "@mui/material/Grid";
import { setModalErrorSnackMessage } from "../../../../actions";
import {
ITierElement,
ITierResponse,
@@ -53,14 +53,13 @@ import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMe
import { BucketVersioning } from "../types";
import { AppState } from "../../../../store";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
interface IReplicationModal {
open: boolean;
closeModalAndRefresh: (refresh: boolean) => any;
classes: any;
bucketName: string;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
distributedSetup: boolean;
}
export interface ITiersDropDown {
@@ -99,9 +98,11 @@ const AddLifecycleModal = ({
closeModalAndRefresh,
classes,
bucketName,
setModalErrorSnackMessage,
distributedSetup,
}: IReplicationModal) => {
const dispatch = useDispatch();
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const [loadingTiers, setLoadingTiers] = useState<boolean>(true);
const [tiersList, setTiersList] = useState<ITiersDropDown[]>([]);
const [addLoading, setAddLoading] = useState(false);
@@ -168,16 +169,11 @@ const AddLifecycleModal = ({
setLoadingVersioning(false);
})
.catch((err: ErrorResponseHandler) => {
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
setLoadingVersioning(false);
});
}
}, [
loadingVersioning,
setModalErrorSnackMessage,
bucketName,
distributedSetup,
]);
}, [loadingVersioning, dispatch, bucketName, distributedSetup]);
const addRecord = () => {
let rules = {};
@@ -230,7 +226,7 @@ const AddLifecycleModal = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -440,12 +436,4 @@ const AddLifecycleModal = ({
);
};
const mapState = (state: AppState) => ({
distributedSetup: state.system.distributedSetup,
});
const connector = connect(mapState, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(AddLifecycleModal));
export default withStyles(styles)(AddLifecycleModal);

View File

@@ -14,8 +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, { useState, useEffect } from "react";
import { connect } from "react-redux";
import React, { useEffect, useState } from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -29,7 +28,7 @@ import {
spacingUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { BucketReplicationRule, BulkReplicationResponse } from "../types";
import { setModalErrorSnackMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
@@ -40,13 +39,15 @@ import { getBytes, k8sScalarUnitsExcluding } from "../../../../common/utils";
import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
import { BucketReplicationIcon } from "../../../../icons";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import { useDispatch } from "react-redux";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
interface IReplicationModal {
open: boolean;
closeModalAndRefresh: () => any;
classes: any;
bucketName: string;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
setReplicationRules: BucketReplicationRule[];
}
@@ -82,9 +83,10 @@ const AddReplicationModal = ({
closeModalAndRefresh,
classes,
bucketName,
setModalErrorSnackMessage,
setReplicationRules,
}: IReplicationModal) => {
const dispatch = useDispatch();
const [addLoading, setAddLoading] = useState<boolean>(false);
const [priority, setPriority] = useState<string>("1");
const [accessKey, setAccessKey] = useState<string>("");
@@ -185,7 +187,7 @@ const AddReplicationModal = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -469,8 +471,4 @@ const AddReplicationModal = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(AddReplicationModal));
export default withStyles(styles)(AddReplicationModal);

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect } from "react";
import { connect } 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";
@@ -23,64 +23,58 @@ import { Grid, IconButton, Tooltip } from "@mui/material";
import get from "lodash/get";
import { AppState } from "../../../../store";
import { containerForHeader } from "../../Common/FormComponents/common/styleLibrary";
import {
setSearchObjects,
setVersionsModeEnabled,
setSearchVersions,
} from "../../ObjectBrowser/actions";
import ListObjects from "../ListBuckets/Objects/ListObjects/ListObjects";
import PageHeader from "../../Common/PageHeader/PageHeader";
import SettingsIcon from "../../../../icons/SettingsIcon";
import { BucketInfo } from "../types";
import { setErrorSnackMessage } from "../../../../actions";
import { SecureComponent } from "../../../../common/SecureComponent";
import {
IAM_PAGES,
IAM_PERMISSIONS,
IAM_ROLES,
IAM_SCOPES,
IAM_PAGES,
} from "../../../../common/SecureComponent/permissions";
import SearchBox from "../../Common/SearchBox";
import BackLink from "../../../../common/BackLink";
interface IBrowserHandlerProps {
versionsMode: boolean;
match: any;
history: any;
classes: any;
setVersionsModeEnabled: typeof setVersionsModeEnabled;
setErrorSnackMessage: typeof setErrorSnackMessage;
bucketInfo: BucketInfo | null;
searchObjects: string;
versionedFile: string;
searchVersions: string;
setSearchObjects: typeof setSearchObjects;
setSearchVersions: typeof setSearchVersions;
}
import {
setSearchObjects,
setSearchVersions,
setVersionsModeEnabled,
} from "../../ObjectBrowser/objectBrowserSlice";
const styles = (theme: Theme) =>
createStyles({
...containerForHeader(theme.spacing(4)),
});
const BrowserHandler = ({
versionsMode,
match,
history,
classes,
setVersionsModeEnabled,
searchObjects,
setSearchObjects,
setSearchVersions,
versionedFile,
searchVersions,
}: IBrowserHandlerProps) => {
interface IBrowserHandlerProps {
match: any;
history: any;
classes: any;
}
const BrowserHandler = ({ match, history, classes }: IBrowserHandlerProps) => {
const dispatch = useDispatch();
const versionsMode = useSelector(
(state: AppState) => state.objectBrowser.versionsMode
);
const searchObjects = useSelector(
(state: AppState) => state.objectBrowser.searchObjects
);
const versionedFile = useSelector(
(state: AppState) => state.objectBrowser.versionedFile
);
const searchVersions = useSelector(
(state: AppState) => state.objectBrowser.searchVersions
);
const bucketName = match.params["bucketName"];
const internalPaths = get(match.params, "subpaths", "");
useEffect(() => {
setVersionsModeEnabled(false);
}, [internalPaths, setVersionsModeEnabled]);
dispatch(setVersionsModeEnabled({ status: false }));
}, [internalPaths, dispatch]);
const openBucketConfiguration = () => {
history.push(`/buckets/${bucketName}/admin`);
@@ -120,7 +114,7 @@ const BrowserHandler = ({
<SearchBox
placeholder={"Start typing to filter objects in the bucket"}
onChange={(value) => {
setSearchObjects(value);
dispatch(setSearchObjects(value));
}}
value={searchObjects}
/>
@@ -130,7 +124,7 @@ const BrowserHandler = ({
<SearchBox
placeholder={`Start typing to filter versions of ${versionedFile}`}
onChange={(value) => {
setSearchVersions(value);
dispatch(setSearchVersions(value));
}}
value={searchVersions}
/>
@@ -146,22 +140,4 @@ const BrowserHandler = ({
);
};
const mapStateToProps = ({ objectBrowser, buckets }: AppState) => ({
versionsMode: get(objectBrowser, "versionsMode", false),
bucketToRewind: get(objectBrowser, "rewind.bucketToRewind", ""),
bucketInfo: buckets.bucketDetails.bucketInfo,
searchObjects: objectBrowser.searchObjects,
versionedFile: objectBrowser.versionedFile,
searchVersions: objectBrowser.searchVersions,
});
const mapDispatchToProps = {
setVersionsModeEnabled,
setErrorSnackMessage,
setSearchObjects,
setSearchVersions,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export default withStyles(styles)(connector(BrowserHandler));
export default withStyles(styles)(BrowserHandler);

View File

@@ -16,7 +16,7 @@
import React, { Fragment, useEffect, useState } from "react";
import { Link, Redirect, Route, Router, Switch } from "react-router-dom";
import { connect } 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";
@@ -30,8 +30,7 @@ import {
pageContentStyles,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import { setErrorSnackMessage } from "../../../../actions";
import { setBucketDetailsLoad, setBucketInfo } from "../actions";
import { AppState } from "../../../../store";
import { ErrorResponseHandler } from "../../../../common/types";
import PageHeader from "../../Common/PageHeader/PageHeader";
@@ -45,14 +44,15 @@ import PageLayout from "../../Common/Layout/PageLayout";
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
import BackLink from "../../../../common/BackLink";
import {
SecureComponent,
hasPermission,
SecureComponent,
} from "../../../../common/SecureComponent";
import withSuspense from "../../Common/Components/withSuspense";
import RBIconButton from "./SummaryItems/RBIconButton";
import { TrashIcon } from "../../../../icons";
import { SRInfoStateType } from "../../../../types";
import { setErrorSnackMessage } from "../../../../systemSlice";
import { setBucketDetailsLoad, setBucketInfo } from "../bucketsSlice";
const BucketsIcon = React.lazy(() => import("../../../../icons/BucketsIcon"));
const FolderIcon = React.lazy(() => import("../../../../icons/FolderIcon"));
@@ -102,27 +102,24 @@ interface IBucketDetailsProps {
classes: any;
match: any;
history: any;
distributedSetup: boolean;
setErrorSnackMessage: typeof setErrorSnackMessage;
setBucketDetailsLoad: typeof setBucketDetailsLoad;
loadingBucket: boolean;
setBucketInfo: typeof setBucketInfo;
bucketInfo: BucketInfo | null;
siteReplicationInfo: SRInfoStateType;
}
const BucketDetails = ({
classes,
match,
history,
setErrorSnackMessage,
distributedSetup,
setBucketDetailsLoad,
loadingBucket,
setBucketInfo,
bucketInfo,
siteReplicationInfo,
}: IBucketDetailsProps) => {
const BucketDetails = ({ classes, match, history }: IBucketDetailsProps) => {
const dispatch = useDispatch();
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const loadingBucket = useSelector(
(state: AppState) => state.buckets.bucketDetails.loadingBucket
);
const bucketInfo = useSelector(
(state: AppState) => state.buckets.bucketDetails.bucketInfo
);
const siteReplicationInfo = useSelector(
(state: AppState) => state.system.siteReplicationInfo
);
const [iniLoad, setIniLoad] = useState<boolean>(false);
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
const bucketName = match.params["bucketName"];
@@ -138,31 +135,25 @@ const BucketDetails = ({
useEffect(() => {
if (!iniLoad) {
setBucketDetailsLoad(true);
dispatch(setBucketDetailsLoad(true));
setIniLoad(true);
}
}, [iniLoad, setBucketDetailsLoad, setIniLoad]);
}, [iniLoad, dispatch, setIniLoad]);
useEffect(() => {
if (loadingBucket) {
api
.invoke("GET", `/api/v1/buckets/${bucketName}`)
.then((res: BucketInfo) => {
setBucketDetailsLoad(false);
setBucketInfo(res);
dispatch(setBucketDetailsLoad(false));
dispatch(setBucketInfo(res));
})
.catch((err: ErrorResponseHandler) => {
setBucketDetailsLoad(false);
setErrorSnackMessage(err);
dispatch(setBucketDetailsLoad(false));
dispatch(setErrorSnackMessage(err));
});
}
}, [
bucketName,
loadingBucket,
setBucketDetailsLoad,
setBucketInfo,
setErrorSnackMessage,
]);
}, [bucketName, loadingBucket, dispatch]);
let topLevelRoute = `/buckets/${bucketName}`;
const defaultRoute = "/admin/summary";
@@ -274,7 +265,7 @@ const BucketDetails = ({
</SecureComponent>
<RBIconButton
onClick={() => {
setBucketDetailsLoad(true);
dispatch(setBucketDetailsLoad(true));
}}
text={`Refresh`}
icon={<RefreshIcon />}
@@ -419,19 +410,4 @@ const BucketDetails = ({
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
selectedTab: state.buckets.bucketDetails.selectedTab,
distributedSetup: state.system.distributedSetup,
loadingBucket: state.buckets.bucketDetails.loadingBucket,
bucketInfo: state.buckets.bucketDetails.bucketInfo,
siteReplicationInfo: state.system.siteReplicationInfo,
});
const connector = connect(mapState, {
setErrorSnackMessage,
setBucketDetailsLoad,
setBucketInfo,
});
export default withStyles(styles)(connector(BucketDetails));
export default withStyles(styles)(BucketDetails);

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 } 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";
@@ -23,8 +23,8 @@ import get from "lodash/get";
import Grid from "@mui/material/Grid";
import AddIcon from "../../../../icons/AddIcon";
import LambdaIcon from "../../../../icons/LambdaIcon";
import { BucketEvent, BucketEventList, BucketInfo } from "../types";
import { setErrorSnackMessage } from "../../../../actions";
import { BucketEvent, BucketEventList } from "../types";
import { AppState } from "../../../../store";
import {
actionsTray,
@@ -37,13 +37,14 @@ import api from "../../../../common/api";
import HelpBox from "../../../../common/HelpBox";
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
import {
SecureComponent,
hasPermission,
SecureComponent,
} from "../../../../common/SecureComponent";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import withSuspense from "../../Common/Components/withSuspense";
import RBIconButton from "./SummaryItems/RBIconButton";
import { setErrorSnackMessage } from "../../../../systemSlice";
const DeleteEvent = withSuspense(React.lazy(() => import("./DeleteEvent")));
const AddEvent = withSuspense(React.lazy(() => import("./AddEvent")));
@@ -60,18 +61,15 @@ const styles = (theme: Theme) =>
interface IBucketEventsProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
loadingBucket: boolean;
bucketInfo: BucketInfo | null;
}
const BucketEventsPanel = ({
classes,
match,
setErrorSnackMessage,
loadingBucket,
bucketInfo,
}: IBucketEventsProps) => {
const BucketEventsPanel = ({ classes, match }: IBucketEventsProps) => {
const dispatch = useDispatch();
const loadingBucket = useSelector(
(state: AppState) => state.buckets.bucketDetails.loadingBucket
);
const [addEventScreenOpen, setAddEventScreenOpen] = useState<boolean>(false);
const [loadingEvents, setLoadingEvents] = useState<boolean>(true);
const [records, setRecords] = useState<BucketEvent[]>([]);
@@ -102,13 +100,13 @@ const BucketEventsPanel = ({
})
.catch((err: ErrorResponseHandler) => {
setLoadingEvents(false);
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
});
} else {
setLoadingEvents(false);
}
}
}, [loadingEvents, setErrorSnackMessage, bucketName, displayEvents]);
}, [loadingEvents, dispatch, bucketName, displayEvents]);
const eventsDisplay = (events: string[]) => {
return <Fragment>{events.join(", ")}</Fragment>;
@@ -203,7 +201,7 @@ const BucketEventsPanel = ({
</Grid>
{!loadingEvents && (
<Grid item xs={12}>
<br />
<br />
<HelpBox
title={"Lambda Notifications"}
iconComponent={<LambdaIcon />}
@@ -234,14 +232,4 @@ const BucketEventsPanel = ({
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
loadingBucket: state.buckets.bucketDetails.loadingBucket,
bucketInfo: state.buckets.bucketDetails.bucketInfo,
});
const connector = connect(mapState, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(BucketEventsPanel));
export default withStyles(styles)(BucketEventsPanel);

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 { connect } from "react-redux";
import { useSelector } from "react-redux";
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 { BucketInfo, LifeCycleItem } from "../types";
import { LifeCycleItem } from "../types";
import { AddIcon, TiersIcon } from "../../../../icons";
import {
actionsTray,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import { setErrorSnackMessage } from "../../../../actions";
import { AppState } from "../../../../store";
import { ErrorResponseHandler } from "../../../../common/types";
import api from "../../../../common/api";
@@ -56,18 +56,16 @@ const styles = (theme: Theme) =>
interface IBucketLifecyclePanelProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
loadingBucket: boolean;
bucketInfo: BucketInfo | null;
}
const BucketLifecyclePanel = ({
classes,
match,
setErrorSnackMessage,
loadingBucket,
bucketInfo,
}: IBucketLifecyclePanelProps) => {
const loadingBucket = useSelector(
(state: AppState) => state.buckets.bucketDetails.loadingBucket
);
const [loadingLifecycle, setLoadingLifecycle] = useState<boolean>(true);
const [lifecycleRecords, setLifecycleRecords] = useState<LifeCycleItem[]>([]);
const [addLifecycleOpen, setAddLifecycleOpen] = useState<boolean>(false);
@@ -352,14 +350,4 @@ const BucketLifecyclePanel = ({
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
loadingBucket: state.buckets.bucketDetails.loadingBucket,
bucketInfo: state.buckets.bucketDetails.bucketInfo,
});
const connector = connect(mapState, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(BucketLifecyclePanel));
export default withStyles(styles)(BucketLifecyclePanel);

View File

@@ -15,18 +15,17 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { connect } 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";
import Grid from "@mui/material/Grid";
import { setErrorSnackMessage } from "../../../../actions";
import {
actionsTray,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import {
BucketInfo,
BucketReplication,
BucketReplicationDestination,
BucketReplicationRule,
@@ -46,6 +45,7 @@ import PanelTitle from "../../Common/PanelTitle/PanelTitle";
import withSuspense from "../../Common/Components/withSuspense";
import RBIconButton from "./SummaryItems/RBIconButton";
import EditReplicationModal from "./EditReplicationModal";
import { setErrorSnackMessage } from "../../../../systemSlice";
const AddReplicationModal = withSuspense(
React.lazy(() => import("./AddReplicationModal"))
@@ -57,9 +57,6 @@ const DeleteReplicationRule = withSuspense(
interface IBucketReplicationProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
loadingBucket: boolean;
bucketInfo: BucketInfo | null;
}
const styles = (theme: Theme) =>
@@ -74,9 +71,13 @@ const styles = (theme: Theme) =>
const BucketReplicationPanel = ({
classes,
match,
setErrorSnackMessage,
loadingBucket,
}: IBucketReplicationProps) => {
const dispatch = useDispatch();
const loadingBucket = useSelector(
(state: AppState) => state.buckets.bucketDetails.loadingBucket
);
const [loadingReplication, setLoadingReplication] = useState<boolean>(true);
const [replicationRules, setReplicationRules] = useState<
BucketReplicationRule[]
@@ -117,19 +118,14 @@ const BucketReplicationPanel = ({
setLoadingReplication(false);
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
setLoadingReplication(false);
});
} else {
setLoadingReplication(false);
}
}
}, [
loadingReplication,
setErrorSnackMessage,
bucketName,
displayReplicationRules,
]);
}, [loadingReplication, dispatch, bucketName, displayReplicationRules]);
const closeAddReplication = () => {
setOpenReplicationOpen(false);
@@ -369,14 +365,4 @@ const BucketReplicationPanel = ({
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
loadingBucket: state.buckets.bucketDetails.loadingBucket,
bucketInfo: state.buckets.bucketDetails.bucketInfo,
});
const connector = connect(mapState, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(BucketReplicationPanel));
export default withStyles(styles)(BucketReplicationPanel);

View File

@@ -15,17 +15,15 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { connect } 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";
import { Box, Grid } from "@mui/material";
import get from "lodash/get";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../actions";
import {
BucketEncryptionInfo,
BucketInfo,
BucketObjectLocking,
BucketQuota,
BucketReplication,
@@ -41,7 +39,7 @@ import {
IRetentionConfig,
} from "../../../../common/types";
import api from "../../../../common/api";
import { setBucketDetailsLoad } from "../actions";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import {
hasPermission,
@@ -56,6 +54,8 @@ import EditablePropertyItem from "./SummaryItems/EditablePropertyItem";
import ReportedUsage from "./SummaryItems/ReportedUsage";
import BucketQuotaSize from "./SummaryItems/BucketQuotaSize";
import SectionTitle from "../../Common/SectionTitle";
import { setErrorSnackMessage } from "../../../../systemSlice";
import { setBucketDetailsLoad } from "../bucketsSlice";
const SetAccessPolicy = withSuspense(
React.lazy(() => import("./SetAccessPolicy"))
@@ -75,16 +75,6 @@ const BucketTags = withSuspense(
const EnableQuota = withSuspense(React.lazy(() => import("./EnableQuota")));
interface IBucketSummaryProps {
classes: any;
match: any;
distributedSetup: boolean;
setErrorSnackMessage: typeof setErrorSnackMessage;
loadingBucket: boolean;
bucketInfo: BucketInfo | null;
setBucketDetailsLoad: typeof setBucketDetailsLoad;
}
const styles = (theme: Theme) =>
createStyles({
...spacingUtils,
@@ -98,15 +88,25 @@ const twoColCssGridLayoutConfig = {
gap: 2,
};
const BucketSummary = ({
classes,
match,
distributedSetup,
setErrorSnackMessage,
loadingBucket,
bucketInfo,
setBucketDetailsLoad,
}: IBucketSummaryProps) => {
interface IBucketSummaryProps {
classes: any;
match: any;
}
const BucketSummary = ({ classes, match }: IBucketSummaryProps) => {
const dispatch = useDispatch();
const loadingBucket = useSelector(
(state: AppState) => state.buckets.bucketDetails.loadingBucket
);
const bucketInfo = useSelector(
(state: AppState) => state.buckets.bucketDetails.bucketInfo
);
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const [encryptionCfg, setEncryptionCfg] =
useState<BucketEncryptionInfo | null>(null);
const [bucketSize, setBucketSize] = useState<string>("0");
@@ -207,11 +207,11 @@ const BucketSummary = ({
setLoadingVersioning(false);
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
setLoadingVersioning(false);
});
}
}, [loadingVersioning, setErrorSnackMessage, bucketName, distributedSetup]);
}, [loadingVersioning, dispatch, bucketName, distributedSetup]);
useEffect(() => {
if (loadingQuota && distributedSetup) {
@@ -228,7 +228,7 @@ const BucketSummary = ({
setLoadingQuota(false);
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
setQuotaEnabled(false);
setLoadingQuota(false);
});
@@ -240,7 +240,7 @@ const BucketSummary = ({
}, [
loadingQuota,
setLoadingVersioning,
setErrorSnackMessage,
dispatch,
bucketName,
distributedSetup,
displayGetBucketQuota,
@@ -256,7 +256,7 @@ const BucketSummary = ({
setLoadingLocking(false);
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
setLoadingLocking(false);
});
} else {
@@ -265,7 +265,7 @@ const BucketSummary = ({
}
}, [
loadingObjectLocking,
setErrorSnackMessage,
dispatch,
bucketName,
loadingVersioning,
distributedSetup,
@@ -290,10 +290,10 @@ const BucketSummary = ({
})
.catch((err: ErrorResponseHandler) => {
setLoadingSize(false);
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
});
}
}, [loadingSize, setErrorSnackMessage, bucketName]);
}, [loadingSize, dispatch, bucketName]);
useEffect(() => {
if (loadingReplication && distributedSetup) {
@@ -305,11 +305,11 @@ const BucketSummary = ({
setLoadingReplication(false);
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
setLoadingReplication(false);
});
}
}, [loadingReplication, setErrorSnackMessage, bucketName, distributedSetup]);
}, [loadingReplication, dispatch, bucketName, distributedSetup]);
useEffect(() => {
if (loadingRetention && hasObjectLocking) {
@@ -329,7 +329,7 @@ const BucketSummary = ({
}, [loadingRetention, hasObjectLocking, bucketName]);
const loadAllBucketData = () => {
setBucketDetailsLoad(true);
dispatch(setBucketDetailsLoad(true));
setBucketLoading(true);
setLoadingSize(true);
setLoadingVersioning(true);
@@ -502,12 +502,7 @@ const BucketSummary = ({
<Box className={classes.spacerTop}>
<LabelValuePair
label={"Tags:"}
value={
<BucketTags
setErrorSnackMessage={setErrorSnackMessage}
bucketName={bucketName}
/>
}
value={<BucketTags bucketName={bucketName} />}
/>
</Box>
<EditablePropertyItem
@@ -651,16 +646,4 @@ const BucketSummary = ({
);
};
const mapState = (state: AppState) => ({
session: state.console.session,
distributedSetup: state.system.distributedSetup,
loadingBucket: state.buckets.bucketDetails.loadingBucket,
bucketInfo: state.buckets.bucketDetails.bucketInfo,
});
const connector = connect(mapState, {
setErrorSnackMessage,
setBucketDetailsLoad,
});
export default withStyles(styles)(connector(BucketSummary));
export default withStyles(styles)(BucketSummary);

View File

@@ -20,19 +20,12 @@ import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { ErrorResponseHandler } from "../../../../common/types";
import { setErrorSnackMessage } from "../../../../actions";
import { AppState } from "../../../../store";
import useApi from "../../Common/Hooks/useApi";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import { ConfirmDeleteIcon } from "../../../../icons";
const mapState = (state: AppState) => ({
session: state.console.session,
});
const connector = connect(mapState, { setErrorSnackMessage });
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IDeleteAccessRule {
modalOpen: boolean;
@@ -52,8 +45,10 @@ const DeleteAccessRule = ({
bucket,
toDelete,
}: IDeleteAccessRule) => {
const dispatch = useDispatch();
const onDelSuccess = () => onClose();
const onDelError = (err: ErrorResponseHandler) => setErrorSnackMessage(err);
const onDelError = (err: ErrorResponseHandler) =>
dispatch(setErrorSnackMessage(err));
const [deleteLoading, invokeDeleteApi] = useApi(onDelSuccess, onDelError);
@@ -81,4 +76,4 @@ const DeleteAccessRule = ({
);
};
export default withStyles(styles)(connector(DeleteAccessRule));
export default withStyles(styles)(DeleteAccessRule);

View File

@@ -14,25 +14,25 @@
// 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, { useState, useEffect } from "react";
import { connect } from "react-redux";
import React, { useEffect, useState } from "react";
import { DialogContentText } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
import { ErrorResponseHandler } from "../../../../common/types";
import { setErrorSnackMessage } from "../../../../actions";
import { ConfirmDeleteIcon } from "../../../../icons";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import api from "../../../../common/api";
import { useDispatch } from "react-redux";
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IDeleteLifecycleRule {
deleteOpen: boolean;
onCloseAndRefresh: (refresh: boolean) => any;
bucket: string;
id: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
@@ -45,8 +45,8 @@ const DeleteBucketLifecycleRule = ({
deleteOpen,
bucket,
id,
setErrorSnackMessage,
}: IDeleteLifecycleRule) => {
const dispatch = useDispatch();
const [deletingRule, setDeletingRule] = useState<boolean>(false);
useEffect(() => {
@@ -59,10 +59,10 @@ const DeleteBucketLifecycleRule = ({
})
.catch((err: ErrorResponseHandler) => {
setDeletingRule(false);
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
});
}
}, [deletingRule, bucket, id, onCloseAndRefresh, setErrorSnackMessage]);
}, [deletingRule, bucket, id, onCloseAndRefresh, dispatch]);
const onConfirmDelete = () => {
setDeletingRule(true);
@@ -86,8 +86,4 @@ const DeleteBucketLifecycleRule = ({
);
};
const connector = connect(null, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(DeleteBucketLifecycleRule));
export default withStyles(styles)(DeleteBucketLifecycleRule);

View File

@@ -15,19 +15,17 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import get from "lodash/get";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { DialogContentText } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
import { setErrorSnackMessage } from "../../../../actions";
import { AppState } from "../../../../store";
import { ErrorResponseHandler } from "../../../../common/types";
import useApi from "../../Common/Hooks/useApi";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import { ConfirmDeleteIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IDeleteBucketTagModal {
deleteOpen: boolean;
@@ -35,7 +33,6 @@ interface IDeleteBucketTagModal {
bucketName: string;
selectedTag: string[];
onCloseAndUpdate: (refresh: boolean) => void;
setErrorSnackMessage: typeof setErrorSnackMessage;
classes: any;
}
@@ -50,13 +47,14 @@ const DeleteBucketTagModal = ({
selectedTag,
onCloseAndUpdate,
bucketName,
setErrorSnackMessage,
classes,
}: IDeleteBucketTagModal) => {
const dispatch = useDispatch();
const [tagKey, tagLabel] = selectedTag;
const onDelSuccess = () => onCloseAndUpdate(true);
const onDelError = (err: ErrorResponseHandler) => setErrorSnackMessage(err);
const onDelError = (err: ErrorResponseHandler) =>
dispatch(setErrorSnackMessage(err));
const onClose = () => onCloseAndUpdate(false);
const [deleteLoading, invokeDeleteApi] = useApi(onDelSuccess, onDelError);
@@ -96,14 +94,4 @@ const DeleteBucketTagModal = ({
);
};
const mapStateToProps = ({ system }: AppState) => ({
distributedSetup: get(system, "distributedSetup", false),
});
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export default withStyles(styles)(connector(DeleteBucketTagModal));
export default withStyles(styles)(DeleteBucketTagModal);

View File

@@ -16,21 +16,21 @@
import React from "react";
import get from "lodash/get";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { DialogContentText } from "@mui/material";
import { BucketEvent } from "../types";
import { setErrorSnackMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import useApi from "../../Common/Hooks/useApi";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import { ConfirmDeleteIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IDeleteEventProps {
closeDeleteModalAndRefresh: (refresh: boolean) => void;
deleteOpen: boolean;
selectedBucket: string;
bucketEvent: BucketEvent | null;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const DeleteEvent = ({
@@ -38,10 +38,11 @@ const DeleteEvent = ({
deleteOpen,
selectedBucket,
bucketEvent,
setErrorSnackMessage,
}: IDeleteEventProps) => {
const dispatch = useDispatch();
const onDelSuccess = () => closeDeleteModalAndRefresh(true);
const onDelError = (err: ErrorResponseHandler) => setErrorSnackMessage(err);
const onDelError = (err: ErrorResponseHandler) =>
dispatch(setErrorSnackMessage(err));
const onClose = () => closeDeleteModalAndRefresh(false);
const [deleteLoading, invokeDeleteApi] = useApi(onDelSuccess, onDelError);
@@ -88,8 +89,4 @@ const DeleteEvent = ({
);
};
const connector = connect(null, {
setErrorSnackMessage,
});
export default connector(DeleteEvent);
export default DeleteEvent;

View File

@@ -15,9 +15,9 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useState } from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { DialogContentText } from "@mui/material";
import { setErrorSnackMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import useApi from "../../Common/Hooks/useApi";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
@@ -25,6 +25,7 @@ import { ConfirmDeleteIcon } from "../../../../icons";
import Grid from "@mui/material/Grid";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import WarningMessage from "../../Common/WarningMessage/WarningMessage";
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IDeleteReplicationProps {
closeDeleteModalAndRefresh: (refresh: boolean) => void;
@@ -35,7 +36,6 @@ interface IDeleteReplicationProps {
remainingRules: number;
allSelected: boolean;
deleteSelectedRules?: boolean;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const DeleteReplicationRule = ({
@@ -46,13 +46,14 @@ const DeleteReplicationRule = ({
rulesToDelete,
remainingRules,
allSelected,
setErrorSnackMessage,
deleteSelectedRules = false,
}: IDeleteReplicationProps) => {
const dispatch = useDispatch();
const [confirmationText, setConfirmationText] = useState<string>("");
const onDelSuccess = () => closeDeleteModalAndRefresh(true);
const onDelError = (err: ErrorResponseHandler) => setErrorSnackMessage(err);
const onDelError = (err: ErrorResponseHandler) =>
dispatch(setErrorSnackMessage(err));
const onClose = () => closeDeleteModalAndRefresh(false);
const [deleteLoading, invokeDeleteApi] = useApi(onDelSuccess, onDelError);
@@ -135,10 +136,4 @@ const DeleteReplicationRule = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default connector(DeleteReplicationRule);
export default DeleteReplicationRule;

View File

@@ -24,19 +24,20 @@ import {
modalStyleUtils,
spacingUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { connect } from "react-redux";
import { connect, useDispatch } from "react-redux";
import api from "../../../../common/api";
import { ErrorResponseHandler } from "../../../../common/types";
import { setErrorSnackMessage } from "../../../../actions";
import { AppState } from "../../../../store";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { AddAccessRuleIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../systemSlice";
const mapState = (state: AppState) => ({
session: state.console.session,
});
const connector = connect(mapState, { setErrorSnackMessage });
const connector = connect(mapState, null);
interface IEditAccessRule {
classes: any;
@@ -61,6 +62,7 @@ const EditAccessRule = ({
toEdit,
initial,
}: IEditAccessRule) => {
const dispatch = useDispatch();
const [selectedAccess, setSelectedAccess] = useState<any>(initial);
const accessOptions = [
@@ -83,7 +85,7 @@ const EditAccessRule = ({
onClose();
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
onClose();
});
};

View File

@@ -14,8 +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, { useEffect, useState, Fragment } from "react";
import { connect } from "react-redux";
import React, { Fragment, useEffect, useState } from "react";
import {
Accordion,
AccordionDetails,
@@ -36,7 +35,7 @@ import {
modalStyleUtils,
spacingUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import { LifeCycleItem } from "../types";
import { ErrorResponseHandler } from "../../../../common/types";
import { LifecycleConfigIcon } from "../../../../icons";
@@ -52,6 +51,8 @@ import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/For
import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
import { useDispatch } from "react-redux";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -85,7 +86,6 @@ interface IAddUserContentProps {
selectedBucket: string;
lifecycleRule: LifeCycleItem;
open: boolean;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const EditLifecycleConfiguration = ({
@@ -94,8 +94,8 @@ const EditLifecycleConfiguration = ({
selectedBucket,
lifecycleRule,
open,
setModalErrorSnackMessage,
}: IAddUserContentProps) => {
const dispatch = useDispatch();
const [loadingTiers, setLoadingTiers] = useState<boolean>(true);
const [addLoading, setAddLoading] = useState<boolean>(false);
const [tags, setTags] = useState<string>("");
@@ -321,7 +321,7 @@ const EditLifecycleConfiguration = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
}
};
@@ -571,10 +571,4 @@ const EditLifecycleConfiguration = ({
);
};
const mapDispatchToProps = {
setModalErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(EditLifecycleConfiguration));
export default withStyles(styles)(EditLifecycleConfiguration);

View File

@@ -31,12 +31,13 @@ import {
spacingUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { BucketReplicationRule } from "../types";
import { connect } from "react-redux";
import { setModalErrorSnackMessage } from "../../../../actions";
import { useDispatch } from "react-redux";
import api from "../../../../common/api";
import { ErrorResponseHandler } from "../../../../common/types";
import PredefinedList from "../../Common/FormComponents/PredefinedList/PredefinedList";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
interface IEditReplicationModal {
closeModalAndRefresh: (refresh: boolean) => void;
@@ -44,7 +45,6 @@ interface IEditReplicationModal {
classes: any;
bucketName: string;
ruleID: string;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const styles = (theme: Theme) =>
@@ -73,8 +73,8 @@ const EditReplicationModal = ({
classes,
bucketName,
ruleID,
setModalErrorSnackMessage,
}: IEditReplicationModal) => {
const dispatch = useDispatch();
const [editLoading, setEditLoading] = useState<boolean>(true);
const [saveEdit, setSaveEdit] = useState<boolean>(false);
const [priority, setPriority] = useState<string>("1");
@@ -111,11 +111,11 @@ const EditReplicationModal = ({
setEditLoading(false);
})
.catch((err: ErrorResponseHandler) => {
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
setEditLoading(false);
});
}
}, [editLoading, setModalErrorSnackMessage, bucketName, ruleID]);
}, [editLoading, dispatch, bucketName, ruleID]);
useEffect(() => {
if (saveEdit) {
@@ -143,7 +143,7 @@ const EditReplicationModal = ({
closeModalAndRefresh(true);
})
.catch((err: ErrorResponseHandler) => {
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
setSaveEdit(false);
});
}
@@ -162,7 +162,7 @@ const EditReplicationModal = ({
metadataSync,
targetStorageClass,
closeModalAndRefresh,
setModalErrorSnackMessage,
dispatch,
]);
return (
@@ -345,8 +345,5 @@ const EditReplicationModal = ({
</ModalWrapper>
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(EditReplicationModal));
export default withStyles(styles)(EditReplicationModal);

View File

@@ -15,13 +15,11 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import Grid from "@mui/material/Grid";
import { Button, LinearProgress, SelectChangeEvent } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { setModalErrorSnackMessage } from "../../../../actions";
import {
formFieldStyles,
modalStyleUtils,
@@ -33,6 +31,8 @@ import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { BucketEncryptionIcon } from "../../../../icons";
import { useDispatch } from "react-redux";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -47,7 +47,6 @@ interface IEnableBucketEncryptionProps {
encryptionCfg: BucketEncryptionInfo | null;
selectedBucket: string;
closeModalAndRefresh: () => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const EnableBucketEncryption = ({
@@ -56,8 +55,8 @@ const EnableBucketEncryption = ({
encryptionCfg,
selectedBucket,
closeModalAndRefresh,
setModalErrorSnackMessage,
}: IEnableBucketEncryptionProps) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(false);
const [kmsKeyID, setKmsKeyID] = useState<string>("");
const [encryptionType, setEncryptionType] = useState<string>("disabled");
@@ -87,7 +86,7 @@ const EnableBucketEncryption = ({
})
.catch((err: ErrorResponseHandler) => {
setLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
} else {
api
@@ -101,7 +100,7 @@ const EnableBucketEncryption = ({
})
.catch((err: ErrorResponseHandler) => {
setLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
}
};
@@ -196,8 +195,4 @@ const EnableBucketEncryption = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(EnableBucketEncryption));
export default withStyles(styles)(EnableBucketEncryption);

View File

@@ -15,7 +15,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { Button, LinearProgress } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -27,7 +26,7 @@ import {
k8sScalarUnitsExcluding,
} from "../../../../common/utils";
import { BucketQuota } from "../types";
import { setModalErrorSnackMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import {
formFieldStyles,
@@ -39,6 +38,8 @@ import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import api from "../../../../common/api";
import { BucketQuotaIcon } from "../../../../icons";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import { useDispatch } from "react-redux";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -53,7 +54,6 @@ interface IEnableQuotaProps {
cfg: BucketQuota | null;
selectedBucket: string;
closeModalAndRefresh: () => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const EnableQuota = ({
@@ -63,8 +63,8 @@ const EnableQuota = ({
cfg,
selectedBucket,
closeModalAndRefresh,
setModalErrorSnackMessage,
}: IEnableQuotaProps) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(false);
const [quotaEnabled, setQuotaEnabled] = useState<boolean>(false);
const [quotaSize, setQuotaSize] = useState<string>("1");
@@ -100,7 +100,7 @@ const EnableQuota = ({
})
.catch((err: ErrorResponseHandler) => {
setLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -204,8 +204,4 @@ const EnableQuota = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(EnableQuota));
export default withStyles(styles)(EnableQuota);

View File

@@ -14,21 +14,21 @@
// 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, { useState, Fragment } from "react";
import { connect } from "react-redux";
import React, { Fragment, useState } from "react";
import { DialogContentText } from "@mui/material";
import api from "../../../../common/api";
import { setErrorSnackMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import { ConfirmModalIcon } from "../../../../icons";
import { useDispatch } from "react-redux";
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IVersioningEventProps {
closeVersioningModalAndRefresh: (refresh: boolean) => void;
modalOpen: boolean;
selectedBucket: string;
versioningCurrentState: boolean;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const EnableVersioningModal = ({
@@ -36,8 +36,8 @@ const EnableVersioningModal = ({
modalOpen,
selectedBucket,
versioningCurrentState,
setErrorSnackMessage,
}: IVersioningEventProps) => {
const dispatch = useDispatch();
const [versioningLoading, setVersioningLoading] = useState<boolean>(false);
const enableVersioning = () => {
@@ -56,7 +56,7 @@ const EnableVersioningModal = ({
})
.catch((err: ErrorResponseHandler) => {
setVersioningLoading(false);
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
});
};
@@ -93,8 +93,4 @@ const EnableVersioningModal = ({
);
};
const connector = connect(null, {
setErrorSnackMessage,
});
export default connector(EnableVersioningModal);
export default EnableVersioningModal;

View File

@@ -15,7 +15,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { Button, SelectChangeEvent } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -26,13 +25,15 @@ import {
modalStyleUtils,
spacingUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import api from "../../../../common/api";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { ChangeAccessPolicyIcon } from "../../../../icons";
import CodeMirrorWrapper from "../../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
import { useDispatch } from "react-redux";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -61,7 +62,6 @@ interface ISetAccessPolicyProps {
actualPolicy: string;
actualDefinition: string;
closeModalAndRefresh: () => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const SetAccessPolicy = ({
@@ -71,8 +71,8 @@ const SetAccessPolicy = ({
actualPolicy,
actualDefinition,
closeModalAndRefresh,
setModalErrorSnackMessage,
}: ISetAccessPolicyProps) => {
const dispatch = useDispatch();
const [addLoading, setAddLoading] = useState<boolean>(false);
const [accessPolicy, setAccessPolicy] = useState<string>("");
const [policyDefinition, setPolicyDefinition] = useState<string>("");
@@ -93,7 +93,7 @@ const SetAccessPolicy = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -182,8 +182,4 @@ const SetAccessPolicy = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(SetAccessPolicy));
export default withStyles(styles)(SetAccessPolicy);

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 { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { Button, LinearProgress } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -27,7 +27,7 @@ import {
modalStyleUtils,
spacingUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import {
ErrorResponseHandler,
IRetentionConfig,
@@ -37,6 +37,7 @@ import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import Loader from "../../Common/Loader/Loader";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -51,7 +52,6 @@ interface ISetRetentionConfigProps {
open: boolean;
bucketName: string;
closeModalAndRefresh: () => void;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const SetRetentionConfig = ({
@@ -59,8 +59,8 @@ const SetRetentionConfig = ({
open,
bucketName,
closeModalAndRefresh,
setModalErrorSnackMessage,
}: ISetRetentionConfigProps) => {
const dispatch = useDispatch();
const [addLoading, setAddLoading] = useState<boolean>(false);
const [loadingForm, setLoadingForm] = useState<boolean>(true);
const [retentionMode, setRetentionMode] = useState<string>("compliance");
@@ -86,7 +86,7 @@ const SetRetentionConfig = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -214,8 +214,4 @@ const SetRetentionConfig = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(SetRetentionConfig));
export default withStyles(styles)(SetRetentionConfig);

View File

@@ -26,6 +26,8 @@ import CloseIcon from "@mui/icons-material/Close";
import AddIcon from "@mui/icons-material/Add";
import withSuspense from "../../../Common/Components/withSuspense";
import Loader from "../../../Common/Loader/Loader";
import { useDispatch } from "react-redux";
import { setErrorSnackMessage } from "../../../../../systemSlice";
const AddBucketTagModal = withSuspense(
React.lazy(() => import("../AddBucketTagModal"))
@@ -35,11 +37,12 @@ const DeleteBucketTagModal = withSuspense(
);
type BucketTagProps = {
setErrorSnackMessage: (err: ErrorResponseHandler) => void;
bucketName: string;
};
const BucketTags = ({ setErrorSnackMessage, bucketName }: BucketTagProps) => {
const BucketTags = ({ bucketName }: BucketTagProps) => {
const dispatch = useDispatch();
const [tags, setTags] = useState<any>(null);
const [tagModalOpen, setTagModalOpen] = useState<boolean>(false);
const [tagKeys, setTagKeys] = useState<string[]>([]);
@@ -67,14 +70,14 @@ const BucketTags = ({ setErrorSnackMessage, bucketName }: BucketTagProps) => {
};
const onTagLoaded = (res: Bucket) => {
if (res != null && res?.details != null) {
if (res != null && res?.details != null && "tags" in res?.details) {
setTags(res?.details?.tags);
setTagKeys(Object.keys(res?.details?.tags));
}
};
const onTagLoadFailed = (err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
};
const [isLoading, invokeTagsApi] = useApi(onTagLoaded, onTagLoadFailed);

View File

@@ -17,9 +17,7 @@
import React, { Suspense } from "react";
import history from "../../../history";
import { Redirect, Route, Router, Switch, withRouter } from "react-router-dom";
import { connect } from "react-redux";
import { AppState } from "../../../store";
import { setMenuOpen } from "../../../actions";
import NotFoundPage from "../../NotFoundPage";
import LoadingComponent from "../../../common/LoadingComponent";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
@@ -31,12 +29,6 @@ const BrowserHandler = React.lazy(
);
const AddBucket = React.lazy(() => import("./ListBuckets/AddBucket"));
const mapState = (state: AppState) => ({
open: state.system.sidebarOpen,
});
const connector = connect(mapState, { setMenuOpen });
const Buckets = () => {
return (
<Router history={history}>
@@ -105,4 +97,4 @@ const Buckets = () => {
);
};
export default withRouter(connector(Buckets));
export default withRouter(Buckets);

View File

@@ -27,7 +27,21 @@ import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/R
import { getBytes, k8sScalarUnitsExcluding } from "../../../../common/utils";
import { AppState } from "../../../../store";
import history from "../../../../history";
import { connect } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { useDebounce } from "use-debounce";
import { MakeBucketRequest } from "../types";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import { ErrorResponseHandler } from "../../../../common/types";
import PageHeader from "../../Common/PageHeader/PageHeader";
import BackLink from "../../../../common/BackLink";
import { BucketsIcon, InfoIcon } from "../../../../icons";
import PageLayout from "../../Common/Layout/PageLayout";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import FormLayout from "../../Common/FormLayout";
import HelpBox from "../../../../common/HelpBox";
import SectionTitle from "../../Common/SectionTitle";
import { setErrorSnackMessage } from "../../../../systemSlice";
import {
addBucketEnableObjectLocking,
addBucketName,
@@ -40,21 +54,7 @@ import {
addBucketRetentionUnit,
addBucketRetentionValidity,
addBucketVersioning,
} from "../actions";
import { useDebounce } from "use-debounce";
import { MakeBucketRequest } from "../types";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import { ErrorResponseHandler } from "../../../../common/types";
import PageHeader from "../../Common/PageHeader/PageHeader";
import BackLink from "../../../../common/BackLink";
import { BucketsIcon, InfoIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../actions";
import PageLayout from "../../Common/Layout/PageLayout";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import FormLayout from "../../Common/FormLayout";
import HelpBox from "../../../../common/HelpBox";
import SectionTitle from "../../Common/SectionTitle";
import { SRInfoStateType } from "../../../../types";
} from "../bucketsSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -103,61 +103,51 @@ const styles = (theme: Theme) =>
interface IAddBucketProps {
classes: any;
addBucketName: typeof addBucketName;
addBucketVersioned: typeof addBucketVersioning;
enableObjectLocking: typeof addBucketEnableObjectLocking;
addBucketQuota: typeof addBucketQuota;
addBucketQuotaType: typeof addBucketQuotaType;
addBucketQuotaSize: typeof addBucketQuotaSize;
addBucketQuotaUnit: typeof addBucketQuotaUnit;
addBucketRetention: typeof addBucketRetention;
addBucketRetentionMode: typeof addBucketRetentionMode;
addBucketRetentionUnit: typeof addBucketRetentionUnit;
addBucketRetentionValidity: typeof addBucketRetentionValidity;
setErrorSnackMessage: typeof setErrorSnackMessage;
bucketName: string;
versioningEnabled: boolean;
lockingEnabled: boolean;
quotaEnabled: boolean;
quotaType: string;
quotaSize: string;
quotaUnit: string;
retentionEnabled: boolean;
retentionMode: string;
retentionUnit: string;
retentionValidity: number;
distributedSetup: boolean;
siteReplicationInfo: SRInfoStateType;
}
const AddBucket = ({
classes,
addBucketName,
addBucketVersioned,
enableObjectLocking,
addBucketQuota,
addBucketQuotaType,
addBucketQuotaSize,
addBucketQuotaUnit,
addBucketRetention,
addBucketRetentionMode,
addBucketRetentionUnit,
addBucketRetentionValidity,
setErrorSnackMessage,
bucketName,
versioningEnabled,
lockingEnabled,
quotaEnabled,
quotaType,
quotaSize,
quotaUnit,
retentionEnabled,
retentionMode,
retentionUnit,
retentionValidity,
distributedSetup,
siteReplicationInfo,
}: IAddBucketProps) => {
const AddBucket = ({ classes }: IAddBucketProps) => {
const dispatch = useDispatch();
const bucketName = useSelector(
(state: AppState) => state.buckets.addBucketName
);
const versioningEnabled = useSelector(
(state: AppState) => state.buckets.addBucketVersioningEnabled
);
const lockingEnabled = useSelector(
(state: AppState) => state.buckets.addBucketLockingEnabled
);
const quotaEnabled = useSelector(
(state: AppState) => state.buckets.addBucketQuotaEnabled
);
const quotaType = useSelector(
(state: AppState) => state.buckets.addBucketQuotaType
);
const quotaSize = useSelector(
(state: AppState) => state.buckets.addBucketQuotaSize
);
const quotaUnit = useSelector(
(state: AppState) => state.buckets.addBucketQuotaUnit
);
const retentionEnabled = useSelector(
(state: AppState) => state.buckets.addBucketRetentionEnabled
);
const retentionMode = useSelector(
(state: AppState) => state.buckets.addBucketRetentionMode
);
const retentionUnit = useSelector(
(state: AppState) => state.buckets.addBucketRetentionUnit
);
const retentionValidity = useSelector(
(state: AppState) => state.buckets.addBucketRetentionValidity
);
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const siteReplicationInfo = useSelector(
(state: AppState) => state.system.siteReplicationInfo
);
const [addLoading, setAddLoading] = useState<boolean>(false);
const [sendEnabled, setSendEnabled] = useState<boolean>(false);
const [lockingFieldDisabled, setLockingFieldDisabled] =
@@ -208,28 +198,28 @@ const AddBucket = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
});
};
const [value] = useDebounce(bucketName, 1000);
useEffect(() => {
addBucketName(value);
}, [value, addBucketName]);
dispatch(addBucketName(value));
}, [value, dispatch]);
const resetForm = () => {
addBucketName("");
addBucketVersioned(false);
enableObjectLocking(false);
addBucketQuota(false);
addBucketQuotaType("hard");
addBucketQuotaSize("1");
addBucketQuotaUnit("Ti");
addBucketRetention(false);
addBucketRetentionMode("compliance");
addBucketRetentionUnit("days");
addBucketRetentionValidity(180);
dispatch(addBucketName(""));
dispatch(addBucketVersioning(false));
dispatch(addBucketEnableObjectLocking(false));
dispatch(addBucketQuota(false));
dispatch(addBucketQuotaType("hard"));
dispatch(addBucketQuotaSize("1"));
dispatch(addBucketQuotaUnit("Ti"));
dispatch(addBucketRetention(false));
dispatch(addBucketRetentionMode("compliance"));
dispatch(addBucketRetentionUnit("days"));
dispatch(addBucketRetentionValidity(180));
};
useEffect(() => {
@@ -246,15 +236,15 @@ const AddBucket = ({
}
if (!versioningEnabled || !retentionEnabled) {
addBucketRetention(false);
addBucketRetentionMode("compliance");
addBucketRetentionUnit("days");
addBucketRetentionValidity(180);
dispatch(addBucketRetention(false));
dispatch(addBucketRetentionMode("compliance"));
dispatch(addBucketRetentionUnit("days"));
dispatch(addBucketRetentionValidity(180));
}
if (retentionEnabled) {
// if retention is enabled, then objec locking should be enabled as well
enableObjectLocking(true);
dispatch(addBucketEnableObjectLocking(true));
setLockingFieldDisabled(true);
} else {
setLockingFieldDisabled(false);
@@ -276,13 +266,9 @@ const AddBucket = ({
quotaSize,
quotaUnit,
quotaEnabled,
addBucketRetention,
addBucketRetentionMode,
addBucketRetentionUnit,
addBucketRetentionValidity,
dispatch,
retentionValidity,
versioningEnabled,
enableObjectLocking,
]);
return (
@@ -336,7 +322,7 @@ const AddBucket = ({
name="bucket-name"
autoFocus={true}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
addBucketName(event.target.value);
dispatch(addBucketName(event.target.value));
}}
label="Bucket Name"
value={bucketName}
@@ -382,7 +368,7 @@ const AddBucket = ({
name="versioned"
checked={versioningEnabled}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
addBucketVersioned(event.target.checked);
dispatch(addBucketVersioning(event.target.checked));
}}
label={"Versioning"}
disabled={
@@ -400,9 +386,11 @@ const AddBucket = ({
disabled={lockingFieldDisabled || !distributedSetup}
checked={lockingEnabled}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
enableObjectLocking(event.target.checked);
dispatch(
addBucketEnableObjectLocking(event.target.checked)
);
if (event.target.checked && !siteReplicationInfo.enabled) {
addBucketVersioned(true);
dispatch(addBucketVersioning(true));
}
}}
label={"Object Locking"}
@@ -416,7 +404,7 @@ const AddBucket = ({
name="bucket_quota"
checked={quotaEnabled}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
addBucketQuota(event.target.checked);
dispatch(addBucketQuota(event.target.checked));
}}
label={"Quota"}
disabled={!distributedSetup}
@@ -431,7 +419,7 @@ const AddBucket = ({
name="quota_size"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.validity.valid) {
addBucketQuotaSize(e.target.value);
dispatch(addBucketQuotaSize(e.target.value));
}
}}
label="Capacity"
@@ -443,7 +431,7 @@ const AddBucket = ({
<InputUnitMenu
id={"quota_unit"}
onUnitChange={(newValue) => {
addBucketQuotaUnit(newValue);
dispatch(addBucketQuotaUnit(newValue));
}}
unitSelected={quotaUnit}
unitsList={k8sScalarUnitsExcluding(["Ki"])}
@@ -462,7 +450,7 @@ const AddBucket = ({
name="bucket_retention"
checked={retentionEnabled}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
addBucketRetention(event.target.checked);
dispatch(addBucketRetention(event.target.checked));
}}
label={"Retention"}
/>
@@ -477,7 +465,9 @@ const AddBucket = ({
name="retention_mode"
label="Mode"
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
addBucketRetentionMode(e.target.value as string);
dispatch(
addBucketRetentionMode(e.target.value as string)
);
}}
selectorOptions={[
{ value: "compliance", label: "Compliance" },
@@ -491,7 +481,9 @@ const AddBucket = ({
id="retention_validity"
name="retention_validity"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
addBucketRetentionValidity(e.target.valueAsNumber);
dispatch(
addBucketRetentionValidity(e.target.valueAsNumber)
);
}}
label="Validity"
value={String(retentionValidity)}
@@ -500,7 +492,7 @@ const AddBucket = ({
<InputUnitMenu
id={"retention_unit"}
onUnitChange={(newValue) => {
addBucketRetentionUnit(newValue);
dispatch(addBucketRetentionUnit(newValue));
}}
unitSelected={retentionUnit}
unitsList={[
@@ -545,36 +537,4 @@ const AddBucket = ({
);
};
const mapState = (state: AppState) => ({
addBucketModalOpen: state.buckets.open,
bucketName: state.buckets.addBucketName,
versioningEnabled: state.buckets.addBucketVersioningEnabled,
lockingEnabled: state.buckets.addBucketLockingEnabled,
quotaEnabled: state.buckets.addBucketQuotaEnabled,
quotaType: state.buckets.addBucketQuotaType,
quotaSize: state.buckets.addBucketQuotaSize,
quotaUnit: state.buckets.addBucketQuotaUnit,
retentionEnabled: state.buckets.addBucketRetentionEnabled,
retentionMode: state.buckets.addBucketRetentionMode,
retentionUnit: state.buckets.addBucketRetentionUnit,
retentionValidity: state.buckets.addBucketRetentionValidity,
distributedSetup: state.system.distributedSetup,
siteReplicationInfo: state.system.siteReplicationInfo,
});
const connector = connect(mapState, {
addBucketName: addBucketName,
addBucketVersioned: addBucketVersioning,
enableObjectLocking: addBucketEnableObjectLocking,
addBucketQuota: addBucketQuota,
addBucketQuotaType: addBucketQuotaType,
addBucketQuotaSize: addBucketQuotaSize,
addBucketQuotaUnit: addBucketQuotaUnit,
addBucketRetention: addBucketRetention,
addBucketRetentionMode: addBucketRetentionMode,
addBucketRetentionUnit: addBucketRetentionUnit,
addBucketRetentionValidity: addBucketRetentionValidity,
setErrorSnackMessage: setErrorSnackMessage,
});
export default connector(withStyles(styles)(AddBucket));
export default withStyles(styles)(AddBucket);

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 } from "react-redux";
import { useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -30,7 +30,6 @@ import {
modalStyleUtils,
spacingUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import PredefinedList from "../../Common/FormComponents/PredefinedList/PredefinedList";
@@ -47,13 +46,13 @@ import {
ITierResponse,
} from "../../Configurations/TiersConfiguration/types";
import { MultiBucketResult } from "../types";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
interface IBulkReplicationModal {
open: boolean;
closeModalAndRefresh: (clearSelection: boolean) => any;
classes: any;
buckets: string[];
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const styles = (theme: Theme) =>
@@ -83,8 +82,8 @@ const AddBulkReplicationModal = ({
closeModalAndRefresh,
classes,
buckets,
setModalErrorSnackMessage,
}: IBulkReplicationModal) => {
const dispatch = useDispatch();
const [addLoading, setAddLoading] = useState<boolean>(false);
const [loadingTiers, setLoadingTiers] = useState<boolean>(true);
const [tiersList, setTiersList] = useState<ITiersDropDown[]>([]);
@@ -125,10 +124,10 @@ const AddBulkReplicationModal = ({
})
.catch((err: ErrorResponseHandler) => {
setLoadingTiers(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
}
}, [loadingTiers, setModalErrorSnackMessage]);
}, [loadingTiers, dispatch]);
useEffect(() => {
let valid = true;
@@ -208,7 +207,7 @@ const AddBulkReplicationModal = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -451,8 +450,4 @@ const AddBulkReplicationModal = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(AddBulkReplicationModal));
export default withStyles(styles)(AddBulkReplicationModal);

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 } from "react-redux";
import { useDispatch } 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 {
modalBasic,
wizardCommon,
} from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import { BulkReplicationItem, BulkReplicationResponse } from "../types";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
@@ -41,13 +41,13 @@ import { SelectorTypes } from "../../Common/FormComponents/RadioGroupSelector/Ra
import { getBytes, k8sScalarUnitsExcluding } from "../../../../common/utils";
import { ErrorResponseHandler } from "../../../../common/types";
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
interface IBulkReplicationModal {
open: boolean;
closeModalAndRefresh: (clearSelection: boolean) => any;
classes: any;
buckets: string[];
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const styles = (theme: Theme) =>
@@ -77,8 +77,8 @@ const AddBulkReplicationModal = ({
closeModalAndRefresh,
classes,
buckets,
setModalErrorSnackMessage,
}: IBulkReplicationModal) => {
const dispatch = useDispatch();
const [bucketsToAlter, setBucketsToAlter] = useState<string[]>([]);
const [addLoading, setAddLoading] = useState<boolean>(false);
const [externalLoading, setExternalLoading] = useState<boolean>(false);
@@ -167,7 +167,7 @@ const AddBulkReplicationModal = ({
})
.catch((err: ErrorResponseHandler) => {
setAddLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -200,7 +200,7 @@ const AddBulkReplicationModal = ({
})
.catch((err: ErrorResponseHandler) => {
setExternalLoading(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
};
@@ -512,8 +512,4 @@ const AddBulkReplicationModal = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(AddBulkReplicationModal));
export default withStyles(styles)(AddBulkReplicationModal);

View File

@@ -15,29 +15,30 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { DialogContentText } from "@mui/material";
import { setErrorSnackMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import useApi from "../../Common/Hooks/useApi";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import { ConfirmDeleteIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IDeleteBucketProps {
closeDeleteModalAndRefresh: (refresh: boolean) => void;
deleteOpen: boolean;
selectedBucket: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const DeleteBucket = ({
closeDeleteModalAndRefresh,
deleteOpen,
selectedBucket,
setErrorSnackMessage,
}: IDeleteBucketProps) => {
const dispatch = useDispatch();
const onDelSuccess = () => closeDeleteModalAndRefresh(true);
const onDelError = (err: ErrorResponseHandler) => setErrorSnackMessage(err);
const onDelError = (err: ErrorResponseHandler) =>
dispatch(setErrorSnackMessage(err));
const onClose = () => closeDeleteModalAndRefresh(false);
const [deleteLoading, invokeDeleteApi] = useApi(onDelSuccess, onDelError);
@@ -71,10 +72,4 @@ const DeleteBucket = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default connector(DeleteBucket);
export default DeleteBucket;

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 } from "react-redux";
import { useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -28,7 +28,6 @@ import {
LifecycleConfigIcon,
SelectAllIcon,
} from "../../../../icons";
import { setErrorSnackMessage } from "../../../../actions";
import {
containerForHeader,
searchField,
@@ -55,6 +54,7 @@ import VirtualizedList from "../../Common/VirtualizedList/VirtualizedList";
import RBIconButton from "../BucketDetails/SummaryItems/RBIconButton";
import BulkLifecycleModal from "./BulkLifecycleModal";
import hasPermission from "../../../../common/SecureComponent/accessControl";
import { setErrorSnackMessage } from "../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -84,14 +84,11 @@ const styles = (theme: Theme) =>
interface IListBucketsProps {
classes: any;
history: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const ListBuckets = ({
classes,
history,
setErrorSnackMessage,
}: IListBucketsProps) => {
const ListBuckets = ({ classes, history }: IListBucketsProps) => {
const dispatch = useDispatch();
const [records, setRecords] = useState<Bucket[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [filterBuckets, setFilterBuckets] = useState<string>("");
@@ -114,12 +111,12 @@ const ListBuckets = ({
})
.catch((err: ErrorResponseHandler) => {
setLoading(false);
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
});
};
fetchRecords();
}
}, [loading, setErrorSnackMessage]);
}, [loading, dispatch]);
const filteredRecords = records.filter((b: Bucket) => {
if (filterBuckets === "") {
@@ -378,8 +375,4 @@ const ListBuckets = ({
);
};
const connector = connect(null, {
setErrorSnackMessage,
});
export default connector(withStyles(styles)(ListBuckets));
export default withStyles(styles)(ListBuckets);

View File

@@ -25,13 +25,14 @@ import {
formFieldStyles,
modalStyleUtils,
} from "../../../../Common/FormComponents/common/styleLibrary";
import { connect } from "react-redux";
import { connect, useDispatch } from "react-redux";
import history from "../../../../../../history";
import { encodeURLString } from "../../../../../../common/utils";
import { setModalErrorSnackMessage } from "../../../../../../actions";
import { BucketObjectItem } from "./types";
import { CreateNewPathIcon } from "../../../../../../icons";
import { AppState } from "../../../../../../store";
import { setModalErrorSnackMessage } from "../../../../../../systemSlice";
interface ICreatePath {
classes: any;
@@ -41,7 +42,6 @@ interface ICreatePath {
onClose: () => any;
existingFiles: BucketObjectItem[];
simplePath: string | null;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const styles = (theme: Theme) =>
@@ -55,11 +55,11 @@ const CreatePathModal = ({
folderName,
bucketName,
onClose,
setModalErrorSnackMessage,
classes,
existingFiles,
simplePath,
}: ICreatePath) => {
const dispatch = useDispatch();
const [pathUrl, setPathUrl] = useState("");
const [isFormValid, setIsFormValid] = useState<boolean>(false);
const [currentPath, setCurrentPath] = useState(bucketName);
@@ -89,10 +89,12 @@ const CreatePathModal = ({
record.name === folderPath + pathUrl;
if (existingFiles.findIndex(sharesName) !== -1) {
setModalErrorSnackMessage({
errorMessage: "Folder cannot have the same name as an existing file",
detailedError: "",
});
dispatch(
setModalErrorSnackMessage({
errorMessage: "Folder cannot have the same name as an existing file",
detailedError: "",
})
);
return;
}
@@ -191,10 +193,6 @@ const mapStateToProps = ({ objectBrowser }: AppState) => ({
simplePath: objectBrowser.simplePath,
});
const mapDispatchToProps = {
setModalErrorSnackMessage,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
const connector = connect(mapStateToProps);
export default connector(withStyles(styles)(CreatePathModal));

View File

@@ -15,21 +15,22 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import { connect } from "react-redux";
import { DialogContentText } from "@mui/material";
import { setErrorSnackMessage } from "../../../../../../actions";
import { ErrorResponseHandler } from "../../../../../../common/types";
import useApi from "../../../../Common/Hooks/useApi";
import ConfirmDialog from "../../../../Common/ModalWrapper/ConfirmDialog";
import { ConfirmDeleteIcon } from "../../../../../../icons";
import FormSwitchWrapper from "../../../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import { useDispatch } from "react-redux";
import { setErrorSnackMessage } from "../../../../../../systemSlice";
interface IDeleteObjectProps {
closeDeleteModalAndRefresh: (refresh: boolean) => void;
deleteOpen: boolean;
selectedObjects: string[];
selectedBucket: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
versioning: boolean;
}
@@ -38,11 +39,13 @@ const DeleteObject = ({
deleteOpen,
selectedBucket,
selectedObjects,
setErrorSnackMessage,
versioning,
}: IDeleteObjectProps) => {
const dispatch = useDispatch();
const onDelSuccess = () => closeDeleteModalAndRefresh(true);
const onDelError = (err: ErrorResponseHandler) => setErrorSnackMessage(err);
const onDelError = (err: ErrorResponseHandler) =>
dispatch(setErrorSnackMessage(err));
const onClose = () => closeDeleteModalAndRefresh(false);
const [deleteVersions, setDeleteVersions] = useState<boolean>(false);
@@ -111,10 +114,4 @@ const DeleteObject = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default connector(DeleteObject);
export default DeleteObject;

View File

@@ -14,24 +14,23 @@
// 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, { useState, useEffect } from "react";
import { connect } from "react-redux";
import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { DialogContentText } from "@mui/material";
import Grid from "@mui/material/Grid";
import { setErrorSnackMessage } from "../../../../../../actions";
import { ErrorResponseHandler } from "../../../../../../common/types";
import { decodeURLString } from "../../../../../../common/utils";
import { ConfirmDeleteIcon } from "../../../../../../icons";
import ConfirmDialog from "../../../../Common/ModalWrapper/ConfirmDialog";
import api from "../../../../../../common/api";
import InputBoxWrapper from "../../../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import { setErrorSnackMessage } from "../../../../../../systemSlice";
interface IDeleteNonCurrentProps {
closeDeleteModalAndRefresh: (refresh: boolean) => void;
deleteOpen: boolean;
selectedObject: string;
selectedBucket: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const DeleteNonCurrentVersions = ({
@@ -39,8 +38,8 @@ const DeleteNonCurrentVersions = ({
deleteOpen,
selectedBucket,
selectedObject,
setErrorSnackMessage,
}: IDeleteNonCurrentProps) => {
const dispatch = useDispatch();
const [deleteLoading, setDeleteLoading] = useState<boolean>(false);
const [typeConfirm, setTypeConfirm] = useState<string>("");
@@ -55,14 +54,14 @@ const DeleteNonCurrentVersions = ({
closeDeleteModalAndRefresh(true);
})
.catch((error: ErrorResponseHandler) => {
setErrorSnackMessage(error);
dispatch(setErrorSnackMessage(error));
setDeleteLoading(false);
});
}
}, [
deleteLoading,
closeDeleteModalAndRefresh,
setErrorSnackMessage,
dispatch,
selectedObject,
selectedBucket,
]);
@@ -109,10 +108,4 @@ const DeleteNonCurrentVersions = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default connector(DeleteNonCurrentVersions);
export default DeleteNonCurrentVersions;

View File

@@ -14,23 +14,24 @@
// 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, { useState, Fragment } from "react";
import { connect } from "react-redux";
import React, { Fragment, useState } from "react";
import { DialogContentText } from "@mui/material";
import { setErrorSnackMessage } from "../../../../../../actions";
import { ErrorResponseHandler } from "../../../../../../common/types";
import { decodeURLString } from "../../../../../../common/utils";
import ConfirmDialog from "../../../../Common/ModalWrapper/ConfirmDialog";
import useApi from "../../../../Common/Hooks/useApi";
import { ConfirmDeleteIcon } from "../../../../../../icons";
import FormSwitchWrapper from "../../../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import { useDispatch } from "react-redux";
import { setErrorSnackMessage } from "../../../../../../systemSlice";
interface IDeleteObjectProps {
closeDeleteModalAndRefresh: (refresh: boolean) => void;
deleteOpen: boolean;
selectedObject: string;
selectedBucket: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
versioning: boolean;
selectedVersion?: string;
}
@@ -40,12 +41,14 @@ const DeleteObject = ({
deleteOpen,
selectedBucket,
selectedObject,
setErrorSnackMessage,
versioning,
selectedVersion = "",
}: IDeleteObjectProps) => {
const dispatch = useDispatch();
const onDelSuccess = () => closeDeleteModalAndRefresh(true);
const onDelError = (err: ErrorResponseHandler) => setErrorSnackMessage(err);
const onDelError = (err: ErrorResponseHandler) =>
dispatch(setErrorSnackMessage(err));
const onClose = () => closeDeleteModalAndRefresh(false);
const [deleteLoading, invokeDeleteApi] = useApi(onDelSuccess, onDelError);
@@ -113,10 +116,4 @@ const DeleteObject = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default connector(DeleteObject);
export default DeleteObject;

View File

@@ -15,9 +15,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import withStyles from "@mui/styles/withStyles";
import { setErrorSnackMessage } from "../../../../../../actions";
import {
decodeURLString,
deleteCookie,
@@ -40,6 +39,7 @@ import {
import { PasswordKeyIcon } from "../../../../../../icons";
import { Box, DialogContentText } from "@mui/material";
import KeyRevealer from "../../../../Tools/KeyRevealer";
import { setErrorSnackMessage } from "../../../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -54,7 +54,6 @@ interface IInspectObjectProps {
inspectOpen: boolean;
inspectPath: string;
volumeName: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const InspectObject = ({
@@ -63,8 +62,8 @@ const InspectObject = ({
inspectOpen,
inspectPath,
volumeName,
setErrorSnackMessage,
}: IInspectObjectProps) => {
const dispatch = useDispatch();
const onClose = () => closeInspectModalAndRefresh(false);
const [isEncrypt, setIsEncrypt] = useState<boolean>(true);
const [decryptionKey, setDecryptionKey] = useState<string>("");
@@ -88,10 +87,12 @@ const InspectObject = ({
if (!res.ok) {
const resErr: any = await res.json();
setErrorSnackMessage({
errorMessage: resErr.message,
detailedError: resErr.code,
});
dispatch(
setErrorSnackMessage({
errorMessage: resErr.message,
detailedError: resErr.code,
})
);
}
const blob: Blob = await res.blob();
@@ -108,7 +109,7 @@ const InspectObject = ({
setDecryptionKey(decryptKey);
})
.catch((err) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
});
};
@@ -188,10 +189,4 @@ const InspectObject = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(InspectObject));
export default withStyles(styles)(InspectObject);

View File

@@ -22,11 +22,10 @@ import React, {
useRef,
useState,
} from "react";
import { connect } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { useDropzone } from "react-dropzone";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { withRouter } from "react-router-dom";
import Grid from "@mui/material/Grid";
import get from "lodash/get";
@@ -51,31 +50,9 @@ import {
} from "../../../../Common/FormComponents/common/styleLibrary";
import { Badge, Typography } from "@mui/material";
import BrowserBreadcrumbs from "../../../../ObjectBrowser/BrowserBreadcrumbs";
import {
cancelObjectInList,
completeObject,
failObject,
openList,
resetRewind,
setLoadingObjectInfo,
setLoadingObjectsList,
setLoadingVersions,
setNewObject,
setObjectDetailsView,
setSearchObjects,
setSelectedObjectView,
setShowDeletedObjects,
setSimplePathHandler,
setVersionsModeEnabled,
updateProgress,
} from "../../../../ObjectBrowser/actions";
import { Route } from "../../../../ObjectBrowser/types";
import { download, extensionPreview, sortListObjects } from "../utils";
import {
setErrorSnackMessage,
setSnackBarMessage,
} from "../../../../../../actions";
import {
BucketInfo,
BucketObjectLocking,
@@ -86,14 +63,13 @@ import { ErrorResponseHandler } from "../../../../../../common/types";
import ScreenTitle from "../../../../Common/ScreenTitle/ScreenTitle";
import { setBucketDetailsLoad, setBucketInfo } from "../../../actions";
import { AppState } from "../../../../../../store";
import PageLayout from "../../../../Common/Layout/PageLayout";
import { IAM_SCOPES } from "../../../../../../common/SecureComponent/permissions";
import {
SecureComponent,
hasPermission,
SecureComponent,
} from "../../../../../../common/SecureComponent";
import withSuspense from "../../../../Common/Components/withSuspense";
@@ -111,6 +87,34 @@ import ActionsListSection from "./ActionsListSection";
import { listModeColumns, rewindModeColumns } from "./ListObjectsHelpers";
import VersionsNavigator from "../ObjectDetails/VersionsNavigator";
import CheckboxWrapper from "../../../../Common/FormComponents/CheckboxWrapper/CheckboxWrapper";
import {
setErrorSnackMessage,
setSnackBarMessage,
} from "../../../../../../systemSlice";
import { setBucketDetailsLoad, setBucketInfo } from "../../../bucketsSlice";
import {
makeid,
storeCallForObjectWithID,
} from "../../../../ObjectBrowser/transferManager";
import {
cancelObjectInList,
completeObject,
failObject,
openList,
resetRewind,
setLoadingObjectInfo,
setLoadingObjectsList,
setLoadingVersions,
setNewObject,
setObjectDetailsView,
setSearchObjects,
setSelectedObjectView,
setShowDeletedObjects,
setSimplePathHandler,
setVersionsModeEnabled,
updateProgress,
} from "../../../../ObjectBrowser/objectBrowserSlice";
import makeStyles from "@mui/styles/makeStyles";
const HistoryIcon = React.lazy(
() => import("../../../../../../icons/HistoryIcon")
@@ -134,7 +138,7 @@ const PreviewFileModal = withSuspense(
React.lazy(() => import("../Preview/PreviewFileModal"))
);
const styles = (theme: Theme) =>
const useStyles = makeStyles((theme: Theme) =>
createStyles({
browsePaper: {
border: 0,
@@ -207,7 +211,8 @@ const styles = (theme: Theme) =>
...objectBrowserExtras,
...objectBrowserCommon,
...containerForHeader(theme.spacing(4)),
});
})
);
const baseDnDStyle = {
borderWidth: 2,
@@ -228,46 +233,6 @@ const acceptDnDStyle = {
borderColor: "#00e676",
};
interface IListObjectsProps {
classes: any;
match: any;
history: any;
routesList: Route[];
downloadingFiles: string[];
rewindEnabled: boolean;
rewindDate: any;
bucketToRewind: string;
searchObjects: string;
showDeleted: boolean;
loading: boolean;
loadingBucket: boolean;
bucketInfo: BucketInfo | null;
versionsMode: boolean;
detailsOpen: boolean;
simplePath: string | null;
setSnackBarMessage: typeof setSnackBarMessage;
setErrorSnackMessage: typeof setErrorSnackMessage;
resetRewind: typeof resetRewind;
setBucketInfo: typeof setBucketInfo;
setBucketDetailsLoad: typeof setBucketDetailsLoad;
setNewObject: typeof setNewObject;
updateProgress: typeof updateProgress;
completeObject: typeof completeObject;
openList: typeof openList;
setSearchObjects: typeof setSearchObjects;
selectedInternalPaths: string | null;
setVersionsModeEnabled: typeof setVersionsModeEnabled;
setShowDeletedObjects: typeof setShowDeletedObjects;
setLoadingVersions: typeof setLoadingVersions;
setObjectDetailsView: typeof setObjectDetailsView;
setSelectedObjectView: typeof setSelectedObjectView;
setLoadingObjectInfo: typeof setLoadingObjectInfo;
setLoadingObjectsList: typeof setLoadingObjectsList;
failObject: typeof failObject;
cancelObjectInList: typeof cancelObjectInList;
setSimplePathHandler: typeof setSimplePathHandler;
}
function useInterval(callback: any, delay: number) {
const savedCallback = useRef<Function | null>(null);
@@ -293,43 +258,54 @@ function useInterval(callback: any, delay: number) {
const defLoading = <Typography component="h3">Loading...</Typography>;
const ListObjects = ({
classes,
match,
history,
rewindEnabled,
rewindDate,
loading,
bucketToRewind,
setSnackBarMessage,
setErrorSnackMessage,
resetRewind,
setBucketDetailsLoad,
loadingBucket,
setBucketInfo,
bucketInfo,
setNewObject,
updateProgress,
completeObject,
setSearchObjects,
searchObjects,
versionsMode,
openList,
simplePath,
setVersionsModeEnabled,
showDeleted,
detailsOpen,
setShowDeletedObjects,
setLoadingVersions,
setObjectDetailsView,
selectedInternalPaths,
setSelectedObjectView,
setLoadingObjectInfo,
setLoadingObjectsList,
failObject,
cancelObjectInList,
setSimplePathHandler,
}: IListObjectsProps) => {
interface IListObjectsProps {
match: any;
history: any;
}
const ListObjects = ({ match, history }: IListObjectsProps) => {
const classes = useStyles();
const dispatch = useDispatch();
const rewindEnabled = useSelector(
(state: AppState) => state.objectBrowser.rewind.rewindEnabled
);
const rewindDate = useSelector(
(state: AppState) => state.objectBrowser.rewind.dateToRewind
);
const bucketToRewind = useSelector(
(state: AppState) => state.objectBrowser.rewind.bucketToRewind
);
const versionsMode = useSelector(
(state: AppState) => state.objectBrowser.versionsMode
);
const searchObjects = useSelector(
(state: AppState) => state.objectBrowser.searchObjects
);
const showDeleted = useSelector(
(state: AppState) => state.objectBrowser.showDeleted
);
const detailsOpen = useSelector(
(state: AppState) => state.objectBrowser.objectDetailsOpen
);
const selectedInternalPaths = useSelector(
(state: AppState) => state.objectBrowser.selectedInternalPaths
);
const loading = useSelector(
(state: AppState) => state.objectBrowser.loadingObjects
);
const simplePath = useSelector(
(state: AppState) => state.objectBrowser.simplePath
);
const loadingBucket = useSelector(
(state: AppState) => state.buckets.bucketDetails.loadingBucket
);
const bucketInfo = useSelector(
(state: AppState) => state.buckets.bucketDetails.bucketInfo
);
const [records, setRecords] = useState<BucketObjectItem[]>([]);
const [deleteMultipleOpen, setDeleteMultipleOpen] = useState<boolean>(false);
const [loadingStartTime, setLoadingStartTime] = useState<number>(0);
@@ -410,14 +386,14 @@ const ListObjects = ({
useEffect(() => {
if (selectedObjects.length > 0) {
setObjectDetailsView(true);
dispatch(setObjectDetailsView(true));
return;
}
if (selectedObjects.length === 0 && selectedInternalPaths === null) {
setObjectDetailsView(false);
dispatch(setObjectDetailsView(false));
}
}, [selectedObjects, selectedInternalPaths, setObjectDetailsView]);
}, [selectedObjects, selectedInternalPaths, dispatch]);
const displayDeleteObject = hasPermission(bucketName, [
IAM_SCOPES.S3_DELETE_OBJECT,
@@ -450,10 +426,10 @@ const ListObjects = ({
useEffect(() => {
if (!iniLoad) {
setBucketDetailsLoad(true);
dispatch(setBucketDetailsLoad(true));
setIniLoad(true);
}
}, [iniLoad, setBucketDetailsLoad, setIniLoad]);
}, [iniLoad, dispatch, setIniLoad]);
useInterval(() => {
// Your custom logic here
@@ -483,7 +459,7 @@ const ListObjects = ({
setRecords([]);
}
}
}, [bucketName, loadingVersioning, setErrorSnackMessage, displayListObjects]);
}, [bucketName, loadingVersioning, dispatch, displayListObjects]);
useEffect(() => {
if (loadingLocking) {
@@ -506,42 +482,39 @@ const ListObjects = ({
setLoadingLocking(false);
}
}
}, [bucketName, loadingLocking, setErrorSnackMessage, displayListObjects]);
}, [bucketName, loadingLocking, dispatch, displayListObjects]);
useEffect(() => {
const decodedIPaths = decodeURLString(internalPaths);
if (decodedIPaths.endsWith("/") || decodedIPaths === "") {
setObjectDetailsView(false);
setSelectedObjectView(null);
setSimplePathHandler(decodedIPaths === "" ? "/" : decodedIPaths);
} else {
setLoadingObjectInfo(true);
setObjectDetailsView(true);
setLoadingVersions(true);
setSelectedObjectView(
`${decodedIPaths ? `${encodeURLString(decodedIPaths)}` : ``}`
dispatch(setObjectDetailsView(false));
dispatch(setSelectedObjectView(""));
dispatch(
setSimplePathHandler(decodedIPaths === "" ? "/" : decodedIPaths)
);
setSimplePathHandler(
`${decodedIPaths.split("/").slice(0, -1).join("/")}/`
} else {
dispatch(setLoadingObjectInfo(true));
dispatch(setObjectDetailsView(true));
dispatch(setLoadingVersions(true));
dispatch(
setSelectedObjectView(
`${decodedIPaths ? `${encodeURLString(decodedIPaths)}` : ``}`
)
);
dispatch(
setSimplePathHandler(
`${decodedIPaths.split("/").slice(0, -1).join("/")}/`
)
);
}
}, [
internalPaths,
rewindDate,
rewindEnabled,
setLoadingObjectInfo,
setLoadingVersions,
setObjectDetailsView,
setSelectedObjectView,
setSimplePathHandler,
]);
}, [internalPaths, rewindDate, rewindEnabled, dispatch]);
useEffect(() => {
setSearchObjects("");
setLoadingObjectsList(true);
dispatch(setSearchObjects(""));
dispatch(setLoadingObjectsList(true));
setSelectedObjects([]);
}, [simplePath, setSearchObjects, setLoadingObjectsList, setSelectedObjects]);
}, [simplePath, dispatch, setSelectedObjects]);
useEffect(() => {
if (loading) {
@@ -564,7 +537,7 @@ const ListObjects = ({
// Is rewind enabled?, we use Rewind API
if (rewindEnabled) {
if (bucketToRewind !== bucketName) {
resetRewind();
dispatch(resetRewind());
return;
}
@@ -636,7 +609,7 @@ const ListObjects = ({
//It is a file since it has elements in the object, setting file flag and waiting for component mount
if (!res.objects) {
// It is a folder, we remove loader & set original results list
setLoadingObjectsList(false);
dispatch(setLoadingObjectsList(false));
setRecords(recordsInElement);
} else {
// This code prevents the program from opening a file when a substring of that file is entered as a new folder.
@@ -661,8 +634,8 @@ const ListObjects = ({
setRecords(recordsInElement);
} else {
// This is a file. We change URL & Open file details view.
setObjectDetailsView(true);
setSelectedObjectView(internalPaths);
dispatch(setObjectDetailsView(true));
dispatch(setSelectedObjectView(internalPaths));
// We split the selected object URL & remove the last item to fetch the files list for the parent folder
const parentPath = `${decodeURLString(internalPaths)
@@ -687,30 +660,30 @@ const ListObjects = ({
.catch(() => {});
}
setLoadingObjectsList(false);
dispatch(setLoadingObjectsList(false));
}
})
.catch((err: ErrorResponseHandler) => {
setLoadingObjectsList(false);
setErrorSnackMessage(err);
dispatch(setLoadingObjectsList(false));
dispatch(setErrorSnackMessage(err));
});
} else {
setRecords(recordsInElement);
setLoadingObjectsList(false);
dispatch(setLoadingObjectsList(false));
}
})
.catch((err: ErrorResponseHandler) => {
setLoadingObjectsList(false);
setErrorSnackMessage(err);
dispatch(setLoadingObjectsList(false));
dispatch(setErrorSnackMessage(err));
});
} else {
setLoadingObjectsList(false);
dispatch(setLoadingObjectsList(false));
}
}
}, [
loading,
match,
setErrorSnackMessage,
dispatch,
bucketName,
rewindEnabled,
rewindDate,
@@ -719,10 +692,6 @@ const ListObjects = ({
showDeleted,
displayListObjects,
bucketToRewind,
resetRewind,
setObjectDetailsView,
setSelectedObjectView,
setLoadingObjectsList,
]);
// bucket info
@@ -731,29 +700,23 @@ const ListObjects = ({
api
.invoke("GET", `/api/v1/buckets/${bucketName}`)
.then((res: BucketInfo) => {
setBucketDetailsLoad(false);
setBucketInfo(res);
dispatch(setBucketDetailsLoad(false));
dispatch(setBucketInfo(res));
})
.catch((err: ErrorResponseHandler) => {
setBucketDetailsLoad(false);
setErrorSnackMessage(err);
dispatch(setBucketDetailsLoad(false));
dispatch(setErrorSnackMessage(err));
});
}
}, [
bucketName,
loadingBucket,
setBucketDetailsLoad,
setBucketInfo,
setErrorSnackMessage,
]);
}, [bucketName, loadingBucket, dispatch]);
const closeDeleteMultipleModalAndRefresh = (refresh: boolean) => {
setDeleteMultipleOpen(false);
if (refresh) {
setSnackBarMessage(`Objects deleted successfully.`);
dispatch(setSnackBarMessage(`Objects deleted successfully.`));
setSelectedObjects([]);
setLoadingObjectsList(true);
dispatch(setLoadingObjectsList(true));
}
};
@@ -788,31 +751,39 @@ const ListObjects = ({
object.version_id,
object.size,
(progress) => {
updateProgress(identityDownload, progress);
dispatch(
updateProgress({
instanceID: identityDownload,
progress: progress,
})
);
},
() => {
completeObject(identityDownload);
dispatch(completeObject(identityDownload));
},
() => {
failObject(identityDownload);
dispatch(failObject(identityDownload));
},
() => {
cancelObjectInList(identityDownload);
dispatch(cancelObjectInList(identityDownload));
}
);
setNewObject({
bucketName,
done: false,
instanceID: identityDownload,
percentage: 0,
prefix: object.name,
type: "download",
waitingForFile: true,
failed: false,
cancelled: false,
call: downloadCall,
});
const ID = makeid(8);
storeCallForObjectWithID(ID, downloadCall);
dispatch(
setNewObject({
ID,
bucketName,
done: false,
instanceID: identityDownload,
percentage: 0,
prefix: object.name,
type: "download",
waitingForFile: true,
failed: false,
cancelled: false,
})
);
downloadCall.send();
};
@@ -825,10 +796,12 @@ const ListObjects = ({
}`;
history.push(newPath);
setObjectDetailsView(true);
setLoadingVersions(true);
setSelectedObjectView(
`${idElement ? `${encodeURLString(idElement)}` : ``}`
dispatch(setObjectDetailsView(true));
dispatch(setLoadingVersions(true));
dispatch(
setSelectedObjectView(
`${idElement ? `${encodeURLString(idElement)}` : ``}`
)
);
};
@@ -915,7 +888,7 @@ const ListObjects = ({
xhr.onload = function (event) {
// resolve promise only when HTTP code is ok
if (xhr.status >= 200 && xhr.status < 300) {
completeObject(identity);
dispatch(completeObject(identity));
resolve({ status: xhr.status });
} else {
// reject promise if there was a server error
@@ -929,53 +902,61 @@ const ListObjects = ({
errorMessage = "something went wrong";
}
}
failObject(identity);
dispatch(dispatch(failObject(identity)));
reject({ status: xhr.status, message: errorMessage });
}
};
xhr.upload.addEventListener("error", (event) => {
reject(errorMessage);
failObject(identity);
dispatch(dispatch(failObject(identity)));
return;
});
xhr.upload.addEventListener("progress", (event) => {
const progress = Math.floor((event.loaded * 100) / event.total);
updateProgress(identity, progress);
dispatch(
updateProgress({
instanceID: identity,
progress: progress,
})
);
});
xhr.onerror = () => {
reject(errorMessage);
failObject(identity);
dispatch(failObject(identity));
return;
};
xhr.onloadend = () => {
if (files.length === 0) {
setLoadingObjectsList(true);
dispatch(setLoadingObjectsList(true));
}
};
xhr.onabort = () => {
cancelObjectInList(identity);
dispatch(cancelObjectInList(identity));
};
const formData = new FormData();
if (file.size !== undefined) {
formData.append(file.size.toString(), blobFile, fileName);
setNewObject({
bucketName,
done: false,
instanceID: identity,
percentage: 0,
prefix: `${decodeURLString(encodedPath)}${fileName}`,
type: "upload",
waitingForFile: false,
failed: false,
cancelled: false,
call: xhr,
});
const ID = makeid(8);
storeCallForObjectWithID(ID, xhr);
dispatch(
setNewObject({
ID,
bucketName,
done: false,
instanceID: identity,
percentage: 0,
prefix: `${decodeURLString(encodedPath)}${fileName}`,
type: "upload",
waitingForFile: false,
failed: false,
cancelled: false,
})
);
xhr.send(formData);
}
@@ -984,7 +965,7 @@ const ListObjects = ({
const uploadFilePromises: any = [];
// open object manager
openList();
dispatch(openList());
for (let i = 0; i < files.length; i++) {
const file = files[i];
uploadFilePromises.push(uploadPromise(file));
@@ -1001,28 +982,17 @@ const ListObjects = ({
errorMessage: "There were some errors during file upload",
detailedError: `Uploaded files ${successUploadedFiles}/${totalFiles}`,
};
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
}
// We force objects list reload after all promises were handled
setLoadingObjectsList(true);
dispatch(setLoadingObjectsList(true));
setSelectedObjects([]);
});
};
upload(files, bucketName, pathPrefix, folderPath);
},
[
bucketName,
completeObject,
openList,
setNewObject,
setErrorSnackMessage,
updateProgress,
setLoadingObjectsList,
cancelObjectInList,
failObject,
simplePath,
]
[bucketName, dispatch, simplePath]
);
const onDrop = useCallback(
@@ -1124,7 +1094,7 @@ const ListObjects = ({
elements = elements.filter((element) => element !== value);
}
setSelectedObjects(elements);
setSelectedObjectView(null);
dispatch(setSelectedObjectView(""));
return elements;
};
@@ -1133,7 +1103,7 @@ const ListObjects = ({
const newSortDirection = get(sortData, "sortDirection", "DESC");
setCurrentSortField(sortData.sortBy);
setSortDirection(newSortDirection);
setLoadingObjectsList(true);
dispatch(setLoadingObjectsList(true));
};
const pageTitle = decodeURLString(internalPaths);
@@ -1151,7 +1121,7 @@ const ListObjects = ({
}
const selectAllItems = () => {
setSelectedObjectView(null);
dispatch(setSelectedObjectView(""));
if (selectedObjects.length === payload.length) {
setSelectedObjects([]);
@@ -1182,11 +1152,9 @@ const ListObjects = ({
}
const onClosePanel = (forceRefresh: boolean) => {
setSelectedObjectView(null);
setVersionsModeEnabled(false);
dispatch(setSelectedObjectView(""));
dispatch(setVersionsModeEnabled({ status: false }));
if (detailsOpen && selectedInternalPaths !== null) {
setSelectedObjectView(null);
setVersionsModeEnabled(false);
// We change URL to be the contained folder
const decodedPath = decodeURLString(internalPaths);
@@ -1204,16 +1172,16 @@ const ListObjects = ({
history.push(`/buckets/${bucketName}/browse/${encodeURLString(URLItem)}`);
}
setObjectDetailsView(false);
dispatch(setObjectDetailsView(false));
setSelectedObjects([]);
if (forceRefresh) {
setLoadingObjectsList(true);
dispatch(setLoadingObjectsList(true));
}
};
const setDeletedAction = () => {
setShowDeletedObjects(!showDeleted);
dispatch(setShowDeletedObjects(!showDeleted));
onClosePanel(true);
};
@@ -1390,9 +1358,9 @@ const ListObjects = ({
variant={"outlined"}
onClick={() => {
if (versionsMode) {
setLoadingVersions(true);
dispatch(setLoadingVersions(true));
} else {
setLoadingObjectsList(true);
dispatch(setLoadingObjectsList(true));
}
}}
disabled={
@@ -1559,46 +1527,4 @@ const ListObjects = ({
);
};
const mapStateToProps = ({ objectBrowser, buckets }: AppState) => ({
routesList: get(objectBrowser, "routesList", []),
downloadingFiles: get(objectBrowser, "downloadingFiles", []),
rewindEnabled: get(objectBrowser, "rewind.rewindEnabled", false),
rewindDate: get(objectBrowser, "rewind.dateToRewind", null),
bucketToRewind: get(objectBrowser, "rewind.bucketToRewind", ""),
versionsMode: get(objectBrowser, "versionsMode", false),
loadingBucket: buckets.bucketDetails.loadingBucket,
bucketInfo: buckets.bucketDetails.bucketInfo,
searchObjects: objectBrowser.searchObjects,
showDeleted: objectBrowser.showDeleted,
detailsOpen: objectBrowser.objectDetailsOpen,
selectedInternalPaths: objectBrowser.selectedInternalPaths,
loading: objectBrowser.loadingObjects,
simplePath: objectBrowser.simplePath,
});
const mapDispatchToProps = {
setSnackBarMessage,
setErrorSnackMessage,
resetRewind,
setBucketDetailsLoad,
setBucketInfo,
setNewObject,
updateProgress,
completeObject,
openList,
failObject,
setSearchObjects,
setVersionsModeEnabled,
setShowDeletedObjects,
setLoadingVersions,
setObjectDetailsView,
setSelectedObjectView,
setLoadingObjectInfo,
setLoadingObjectsList,
cancelObjectInList,
setSimplePathHandler,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export default withRouter(connector(withStyles(styles)(ListObjects)));
export default withRouter(ListObjects);

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 } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { Box, Button } from "@mui/material";
import { withStyles } from "@mui/styles";
import createStyles from "@mui/styles/createStyles";
@@ -24,17 +24,14 @@ import Grid from "@mui/material/Grid";
import {
actionsTray,
buttonsStyles,
detailsPanel,
spacingUtils,
textStyleUtils,
detailsPanel,
} from "../../../../Common/FormComponents/common/styleLibrary";
import { IFileInfo } from "../ObjectDetails/types";
import { download, extensionPreview } from "../utils";
import { ErrorResponseHandler } from "../../../../../../common/types";
import {
setErrorSnackMessage,
setSnackBarMessage,
} from "../../../../../../actions";
import {
decodeURLString,
encodeURLString,
@@ -43,29 +40,21 @@ import {
niceDaysInt,
} from "../../../../../../common/utils";
import { IAM_SCOPES } from "../../../../../../common/SecureComponent/permissions";
import {
cancelObjectInList,
completeObject,
failObject,
setLoadingObjectInfo,
setLoadingVersions,
setNewObject,
setSelectedVersion,
setVersionsModeEnabled,
updateProgress,
} from "../../../../ObjectBrowser/actions";
import { AppState } from "../../../../../../store";
import {
DeleteIcon,
DownloadIcon,
LegalHoldIcon,
MetadataIcon,
ObjectInfoIcon,
PreviewIcon,
RetentionIcon,
ShareIcon,
TagsIcon,
VersionsIcon,
} from "../../../../../../icons";
import { InspectMenuIcon } from "../../../../../../icons/SidebarMenus";
import { ShareIcon, DownloadIcon, DeleteIcon } from "../../../../../../icons";
import api from "../../../../../../common/api";
import ShareFile from "../ObjectDetails/ShareFile";
import SetRetention from "../ObjectDetails/SetRetention";
@@ -82,6 +71,22 @@ import { displayFileIconName } from "./utils";
import TagsModal from "../ObjectDetails/TagsModal";
import InspectObject from "./InspectObject";
import Loader from "../../../../Common/Loader/Loader";
import { setErrorSnackMessage } from "../../../../../../systemSlice";
import {
makeid,
storeCallForObjectWithID,
} from "../../../../ObjectBrowser/transferManager";
import {
cancelObjectInList,
completeObject,
failObject,
setLoadingObjectInfo,
setLoadingVersions,
setNewObject,
setSelectedVersion,
setVersionsModeEnabled,
updateProgress,
} from "../../../../ObjectBrowser/objectBrowserSlice";
const styles = () =>
createStyles({
@@ -117,33 +122,6 @@ const styles = () =>
...detailsPanel,
});
interface IObjectDetailPanelProps {
classes: any;
internalPaths: string;
bucketName: string;
rewindEnabled: boolean;
rewindDate: any;
bucketToRewind: string;
distributedSetup: boolean;
versioning: boolean;
locking: boolean;
versionsMode: boolean;
selectedVersion: string;
loadingObjectInfo: boolean;
onClosePanel: (hardRefresh: boolean) => void;
setErrorSnackMessage: typeof setErrorSnackMessage;
setSnackBarMessage: typeof setSnackBarMessage;
setNewObject: typeof setNewObject;
updateProgress: typeof updateProgress;
completeObject: typeof completeObject;
setVersionsModeEnabled: typeof setVersionsModeEnabled;
setLoadingObjectInfo: typeof setLoadingObjectInfo;
setLoadingVersions: typeof setLoadingVersions;
setSelectedVersion: typeof setSelectedVersion;
failObject: typeof failObject;
cancelObjectInList: typeof cancelObjectInList;
}
const emptyFile: IFileInfo = {
is_latest: true,
last_modified: "",
@@ -156,28 +134,39 @@ const emptyFile: IFileInfo = {
version_id: null,
};
interface IObjectDetailPanelProps {
classes: any;
internalPaths: string;
bucketName: string;
versioning: boolean;
locking: boolean;
onClosePanel: (hardRefresh: boolean) => void;
}
const ObjectDetailPanel = ({
classes,
internalPaths,
bucketName,
distributedSetup,
versioning,
locking,
setErrorSnackMessage,
setNewObject,
updateProgress,
completeObject,
versionsMode,
selectedVersion,
onClosePanel,
setVersionsModeEnabled,
loadingObjectInfo,
setLoadingObjectInfo,
setLoadingVersions,
setSelectedVersion,
failObject,
cancelObjectInList,
}: IObjectDetailPanelProps) => {
const dispatch = useDispatch();
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const versionsMode = useSelector(
(state: AppState) => state.objectBrowser.versionsMode
);
const selectedVersion = useSelector(
(state: AppState) => state.objectBrowser.selectedVersion
);
const loadingObjectInfo = useSelector(
(state: AppState) => state.objectBrowser.loadingObjectInfo
);
const [shareFileModalOpen, setShareFileModalOpen] = useState<boolean>(false);
const [retentionModalOpen, setRetentionModalOpen] = useState<boolean>(false);
const [tagModalOpen, setTagModalOpen] = useState<boolean>(false);
@@ -247,21 +236,20 @@ const ObjectDetailPanel = ({
setVersions([]);
}
setLoadingObjectInfo(false);
dispatch(setLoadingObjectInfo(false));
})
.catch((error: ErrorResponseHandler) => {
setErrorSnackMessage(error);
setLoadingObjectInfo(false);
dispatch(setErrorSnackMessage(error));
dispatch(setLoadingObjectInfo(false));
});
}
}, [
loadingObjectInfo,
bucketName,
internalPaths,
setErrorSnackMessage,
dispatch,
distributedSetup,
selectedVersion,
setLoadingObjectInfo,
]);
let tagKeys: string[] = [];
@@ -277,7 +265,7 @@ const ObjectDetailPanel = ({
const closeRetentionModal = (updateInfo: boolean) => {
setRetentionModalOpen(false);
if (updateInfo) {
setLoadingObjectInfo(true);
dispatch(setLoadingObjectInfo(true));
}
};
@@ -301,31 +289,39 @@ const ObjectDetailPanel = ({
object.version_id,
parseInt(object.size || "0"),
(progress) => {
updateProgress(identityDownload, progress);
dispatch(
updateProgress({
instanceID: identityDownload,
progress: progress,
})
);
},
() => {
completeObject(identityDownload);
dispatch(completeObject(identityDownload));
},
() => {
failObject(identityDownload);
dispatch(failObject(identityDownload));
},
() => {
cancelObjectInList(identityDownload);
dispatch(cancelObjectInList(identityDownload));
}
);
setNewObject({
bucketName,
done: false,
instanceID: identityDownload,
percentage: 0,
prefix: object.name,
type: "download",
waitingForFile: true,
failed: false,
cancelled: false,
call: downloadCall,
});
const ID = makeid(8);
storeCallForObjectWithID(ID, downloadCall);
dispatch(
setNewObject({
ID,
bucketName,
done: false,
instanceID: identityDownload,
percentage: 0,
prefix: object.name,
type: "download",
waitingForFile: true,
failed: false,
cancelled: false,
})
);
downloadCall.send();
};
@@ -336,30 +332,30 @@ const ObjectDetailPanel = ({
if (closeAndReload && selectedVersion === "") {
onClosePanel(true);
} else {
setLoadingVersions(true);
setSelectedVersion("");
setLoadingObjectInfo(true);
dispatch(setLoadingVersions(true));
dispatch(setSelectedVersion(""));
dispatch(setLoadingObjectInfo(true));
}
};
const closeAddTagModal = (reloadObjectData: boolean) => {
setTagModalOpen(false);
if (reloadObjectData) {
setLoadingObjectInfo(true);
dispatch(setLoadingObjectInfo(true));
}
};
const closeInspectModal = (reloadObjectData: boolean) => {
setInspectModalOpen(false);
if (reloadObjectData) {
setLoadingObjectInfo(true);
dispatch(setLoadingObjectInfo(true));
}
};
const closeLegalholdModal = (reload: boolean) => {
setLegalholdOpen(false);
if (reload) {
setLoadingObjectInfo(true);
dispatch(setLoadingObjectInfo(true));
}
};
@@ -475,7 +471,12 @@ const ObjectDetailPanel = ({
},
{
action: () => {
setVersionsModeEnabled(!versionsMode, objectName);
dispatch(
setVersionsModeEnabled({
status: !versionsMode,
objectName: objectName,
})
);
},
label: versionsMode ? "Hide Object Versions" : "Display Object Versions",
icon: <VersionsIcon />,
@@ -735,30 +736,4 @@ const ObjectDetailPanel = ({
);
};
const mapStateToProps = ({ objectBrowser, system }: AppState) => ({
rewindEnabled: get(objectBrowser, "rewind.rewindEnabled", false),
rewindDate: get(objectBrowser, "rewind.dateToRewind", null),
bucketToRewind: get(objectBrowser, "rewind.bucketToRewind", ""),
distributedSetup: get(system, "distributedSetup", false),
versionsMode: get(objectBrowser, "versionsMode", false),
selectedVersion: get(objectBrowser, "selectedVersion", ""),
loadingObjectInfo: get(objectBrowser, "loadingObjectInfo", false),
});
const mapDispatchToProps = {
setErrorSnackMessage,
setSnackBarMessage,
setNewObject,
updateProgress,
completeObject,
setVersionsModeEnabled,
setLoadingObjectInfo,
setLoadingVersions,
setSelectedVersion,
failObject,
cancelObjectInList,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export default connector(withStyles(styles)(ObjectDetailPanel));
export default withStyles(styles)(ObjectDetailPanel);

View File

@@ -15,53 +15,38 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { useDispatch, useSelector } from "react-redux";
import { Button, LinearProgress } from "@mui/material";
import Grid from "@mui/material/Grid";
import { ObjectBrowserReducer } from "../../../../ObjectBrowser/types";
import { modalBasic } from "../../../../Common/FormComponents/common/styleLibrary";
import {
resetRewind,
setRewindEnable,
} from "../../../../ObjectBrowser/actions";
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
import DateTimePickerWrapper from "../../../../Common/FormComponents/DateTimePickerWrapper/DateTimePickerWrapper";
import FormSwitchWrapper from "../../../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import { AppState } from "../../../../../../store";
import {
resetRewind,
setRewindEnable,
} from "../../../../ObjectBrowser/objectBrowserSlice";
interface IRewindEnable {
closeModalAndRefresh: () => void;
classes: any;
open: boolean;
bucketName: string;
bucketToRewind: string;
rewindEnabled: boolean;
dateRewind: any;
resetRewind: typeof resetRewind;
setRewindEnable: typeof setRewindEnable;
}
const styles = (theme: Theme) =>
createStyles({
buttonContainer: {
textAlign: "right",
},
...modalBasic,
});
const RewindEnable = ({
closeModalAndRefresh,
classes,
open,
bucketName,
bucketToRewind,
rewindEnabled,
dateRewind,
resetRewind,
setRewindEnable,
}: IRewindEnable) => {
const dispatch = useDispatch();
const rewindEnabled = useSelector(
(state: AppState) => state.objectBrowser.rewind.rewindEnabled
);
const dateRewind = useSelector(
(state: AppState) => state.objectBrowser.rewind.dateToRewind
);
const [rewindEnabling, setRewindEnabling] = useState<boolean>(false);
const [rewindEnableButton, setRewindEnableButton] = useState<boolean>(true);
const [dateSelected, setDateSelected] = useState<any>(null);
@@ -75,10 +60,16 @@ const RewindEnable = ({
const rewindApply = () => {
if (!rewindEnableButton && rewindEnabled) {
resetRewind();
dispatch(resetRewind());
} else {
setRewindEnabling(true);
setRewindEnable(true, bucketName, dateSelected);
dispatch(
setRewindEnable({
state: true,
bucket: bucketName,
dateRewind: dateSelected,
})
);
}
closeModalAndRefresh();
};
@@ -116,7 +107,7 @@ const RewindEnable = ({
/>
</Grid>
)}
<Grid item xs={12} className={classes.buttonContainer}>
<Grid item xs={12} style={{ textAlign: "right" }}>
<Button
type="button"
variant="contained"
@@ -139,17 +130,4 @@ const RewindEnable = ({
);
};
const mapStateToProps = ({ objectBrowser }: ObjectBrowserReducer) => ({
bucketToRewind: objectBrowser.rewind.bucketToRewind,
rewindEnabled: objectBrowser.rewind.rewindEnabled,
dateRewind: objectBrowser.rewind.dateToRewind,
});
const mapDispatchToProps = {
resetRewind,
setRewindEnable,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export default withStyles(styles)(connector(RewindEnable));
export default RewindEnable;

View File

@@ -14,14 +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 React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { DialogContentText } from "@mui/material";
import { setErrorSnackMessage } from "../../../../../../actions";
import { ErrorResponseHandler } from "../../../../../../common/types";
import ConfirmDialog from "../../../../Common/ModalWrapper/ConfirmDialog";
import { ConfirmDeleteIcon } from "../../../../../../icons";
import api from "../../../../../../common/api";
import { setErrorSnackMessage } from "../../../../../../systemSlice";
interface IDeleteSelectedVersionsProps {
closeDeleteModalAndRefresh: (refresh: boolean) => void;
@@ -29,7 +30,6 @@ interface IDeleteSelectedVersionsProps {
selectedVersions: string[];
selectedObject: string;
selectedBucket: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const DeleteObject = ({
@@ -38,8 +38,8 @@ const DeleteObject = ({
selectedBucket,
selectedVersions,
selectedObject,
setErrorSnackMessage,
}: IDeleteSelectedVersionsProps) => {
const dispatch = useDispatch();
const [deleteLoading, setDeleteLoading] = useState<boolean>(false);
const onClose = () => closeDeleteModalAndRefresh(false);
@@ -69,7 +69,7 @@ const DeleteObject = ({
closeDeleteModalAndRefresh(true);
})
.catch((error: ErrorResponseHandler) => {
setErrorSnackMessage(error);
dispatch(setErrorSnackMessage(error));
setDeleteLoading(false);
});
}
@@ -80,7 +80,7 @@ const DeleteObject = ({
selectedBucket,
selectedObject,
selectedVersions,
setErrorSnackMessage,
dispatch,
]);
if (!selectedVersions) {
@@ -106,10 +106,4 @@ const DeleteObject = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default connector(DeleteObject);
export default DeleteObject;

View File

@@ -79,7 +79,7 @@ const styles = (theme: Theme) =>
"& > div": {
borderBottomColor: "#E2E2E2",
},
}
},
},
},
versionContainer: {
@@ -98,7 +98,7 @@ const styles = (theme: Theme) =>
fontSize: 14,
"& svg.min-icon": {
display: "none",
}
},
},
},
buttonContainer: {
@@ -128,7 +128,7 @@ const styles = (theme: Theme) =>
textOverflow: "ellipsis",
maxWidth: "95%",
overflow: "hidden",
whiteSpace: "nowrap"
whiteSpace: "nowrap",
},
},
ctrItem: {
@@ -145,7 +145,7 @@ const styles = (theme: Theme) =>
"@media (max-width: 799px)": {
"&::before": {
display: "none",
}
},
},
},
collapsableInfo: {
@@ -156,9 +156,9 @@ const styles = (theme: Theme) =>
},
versionItem: {
"@media (max-width: 799px)": {
display: "none"
display: "none",
},
}
},
});
const FileVersionItem = ({
@@ -259,7 +259,9 @@ const FileVersionItem = ({
/>
)}
{displayFileIconName(fileName, true)} v{index.toString()}
<span className={classes.versionItem}>{pill && <SpecificVersionPill type={pill} />}</span>
<span className={classes.versionItem}>
{pill && <SpecificVersionPill type={pill} />}
</span>
</Grid>
<Grid item xs={10} md={8} className={classes.buttonContainer}>
{versionItemButtons.map((button, index) => {

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState, Fragment } from "react";
import React, { Fragment, useCallback, useEffect, useState } from "react";
import useApi from "../../../../Common/Hooks/useApi";
import { ErrorResponseHandler } from "../../../../../../common/types";
import { MetadataResponse } from "./types";

View File

@@ -17,16 +17,17 @@
import React, { useState } from "react";
import { DialogContentText } from "@mui/material";
import { Theme } from "@mui/material/styles";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { modalBasic } from "../../../../Common/FormComponents/common/styleLibrary";
import { setErrorSnackMessage } from "../../../../../../actions";
import { ErrorResponseHandler } from "../../../../../../common/types";
import { encodeURLString } from "../../../../../../common/utils";
import api from "../../../../../../common/api";
import ConfirmDialog from "../../../../Common/ModalWrapper/ConfirmDialog";
import RecoverIcon from "../../../../../../icons/RecoverIcon";
import { setErrorSnackMessage } from "../../../../../../systemSlice";
interface IRestoreFileVersion {
classes: any;
@@ -35,7 +36,6 @@ interface IRestoreFileVersion {
versionID: string;
objectPath: string;
onCloseAndUpdate: (refresh: boolean) => void;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
@@ -51,6 +51,7 @@ const RestoreFileVersion = ({
restoreOpen,
onCloseAndUpdate,
}: IRestoreFileVersion) => {
const dispatch = useDispatch();
const [restoreLoading, setRestoreLoading] = useState<boolean>(false);
const restoreVersion = () => {
@@ -68,7 +69,7 @@ const RestoreFileVersion = ({
onCloseAndUpdate(true);
})
.catch((error: ErrorResponseHandler) => {
setErrorSnackMessage(error);
dispatch(setErrorSnackMessage(error));
setRestoreLoading(false);
});
};
@@ -101,12 +102,4 @@ const RestoreFileVersion = ({
);
};
const mapStateToProps = null;
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export default withStyles(styles)(connector(RestoreFileVersion));
export default withStyles(styles)(RestoreFileVersion);

View File

@@ -14,8 +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, { useState, useEffect } from "react";
import { connect } from "react-redux";
import React, { useEffect, useState } from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -27,13 +26,15 @@ import {
modalStyleUtils,
spacingUtils,
} from "../../../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../../../actions";
import { IFileInfo } from "./types";
import { ErrorResponseHandler } from "../../../../../../common/types";
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
import FormSwitchWrapper from "../../../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import api from "../../../../../../common/api";
import { encodeURLString } from "../../../../../../common/utils";
import { useDispatch } from "react-redux";
import { setModalErrorSnackMessage } from "../../../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -49,7 +50,6 @@ interface ISetRetentionProps {
objectName: string;
bucketName: string;
actualInfo: IFileInfo;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const SetLegalHoldModal = ({
@@ -59,8 +59,8 @@ const SetLegalHoldModal = ({
objectName,
bucketName,
actualInfo,
setModalErrorSnackMessage,
}: ISetRetentionProps) => {
const dispatch = useDispatch();
const [legalHoldEnabled, setLegalHoldEnabled] = useState<boolean>(false);
const [isSaving, setIsSaving] = useState<boolean>(false);
const versionId = actualInfo.version_id;
@@ -87,7 +87,7 @@ const SetLegalHoldModal = ({
closeModalAndRefresh(true);
})
.catch((error: ErrorResponseHandler) => {
setModalErrorSnackMessage(error);
dispatch(setModalErrorSnackMessage(error));
setIsSaving(false);
});
};
@@ -155,10 +155,4 @@ const SetLegalHoldModal = ({
);
};
const mapDispatchToProps = {
setModalErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(SetLegalHoldModal));
export default withStyles(styles)(SetLegalHoldModal);

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useRef, useState } from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -27,7 +27,7 @@ import {
spacingUtils,
} from "../../../../Common/FormComponents/common/styleLibrary";
import { IFileInfo } from "./types";
import { setModalErrorSnackMessage } from "../../../../../../actions";
import { twoDigitDate } from "../../../../Common/FormComponents/DateSelector/utils";
import { ErrorResponseHandler } from "../../../../../../common/types";
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
@@ -36,6 +36,7 @@ import RadioGroupSelector from "../../../../Common/FormComponents/RadioGroupSele
import DateSelector from "../../../../Common/FormComponents/DateSelector/DateSelector";
import api from "../../../../../../common/api";
import { encodeURLString } from "../../../../../../common/utils";
import { setModalErrorSnackMessage } from "../../../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -66,7 +67,6 @@ interface ISetRetentionProps {
objectName: string;
bucketName: string;
objectInfo: IFileInfo;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
interface IRefObject {
@@ -80,8 +80,8 @@ const SetRetention = ({
objectName,
objectInfo,
bucketName,
setModalErrorSnackMessage,
}: ISetRetentionProps) => {
const dispatch = useDispatch();
const [statusEnabled, setStatusEnabled] = useState<boolean>(true);
const [type, setType] = useState<string>("");
const [date, setDate] = useState<string>("");
@@ -148,7 +148,7 @@ const SetRetention = ({
closeModalAndRefresh(true);
})
.catch((error: ErrorResponseHandler) => {
setModalErrorSnackMessage(error);
dispatch(setModalErrorSnackMessage(error));
setIsSaving(false);
});
};
@@ -169,7 +169,7 @@ const SetRetention = ({
closeModalAndRefresh(true);
})
.catch((error: ErrorResponseHandler) => {
setModalErrorSnackMessage(error);
dispatch(setModalErrorSnackMessage(error));
setIsSaving(false);
});
};
@@ -290,10 +290,4 @@ const SetRetention = ({
);
};
const mapDispatchToProps = {
setModalErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(SetRetention));
export default withStyles(styles)(SetRetention);

View File

@@ -16,7 +16,7 @@
import React, { Fragment, useEffect, useState } from "react";
import get from "lodash/get";
import { connect } 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";
@@ -29,10 +29,6 @@ import {
} from "../../../../Common/FormComponents/common/styleLibrary";
import { IFileInfo } from "./types";
import {
setModalErrorSnackMessage,
setModalSnackMessage,
} from "../../../../../../actions";
import { AppState } from "../../../../../../store";
import { ErrorResponseHandler } from "../../../../../../common/types";
import api from "../../../../../../common/api";
@@ -42,6 +38,10 @@ import DaysSelector from "../../../../Common/FormComponents/DaysSelector/DaysSel
import { encodeURLString } from "../../../../../../common/utils";
import { ShareIcon } from "../../../../../../icons";
import BoxIconButton from "../../../../Common/BoxIconButton/BoxIconButton";
import {
setModalErrorSnackMessage,
setModalSnackMessage,
} from "../../../../../../systemSlice";
const CopyIcon = React.lazy(() => import("../../../../../../icons/CopyIcon"));
@@ -84,10 +84,7 @@ interface IShareFileProps {
open: boolean;
bucketName: string;
dataObject: IFileInfo;
distributedSetup: boolean;
closeModalAndRefresh: () => void;
setModalSnackMessage: typeof setModalSnackMessage;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const ShareFile = ({
@@ -96,10 +93,11 @@ const ShareFile = ({
closeModalAndRefresh,
bucketName,
dataObject,
distributedSetup,
setModalSnackMessage,
setModalErrorSnackMessage,
}: IShareFileProps) => {
const dispatch = useDispatch();
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const [shareURL, setShareURL] = useState<string>("");
const [isLoadingVersion, setIsLoadingVersion] = useState<boolean>(true);
const [isLoadingFile, setIsLoadingFile] = useState<boolean>(false);
@@ -147,7 +145,7 @@ const ShareFile = ({
setVersionID("null");
})
.catch((error: ErrorResponseHandler) => {
setModalErrorSnackMessage(error);
dispatch(setModalErrorSnackMessage(error));
});
setIsLoadingVersion(false);
@@ -159,7 +157,7 @@ const ShareFile = ({
}
setVersionID(dataObject.version_id || "null");
setIsLoadingVersion(false);
}, [bucketName, dataObject, distributedSetup, setModalErrorSnackMessage]);
}, [bucketName, dataObject, distributedSetup, dispatch]);
useEffect(() => {
if (dateValid && !isLoadingVersion) {
@@ -188,7 +186,7 @@ const ShareFile = ({
setIsLoadingFile(false);
})
.catch((error: ErrorResponseHandler) => {
setModalErrorSnackMessage(error);
dispatch(setModalErrorSnackMessage(error));
setShareURL("");
setIsLoadingFile(false);
});
@@ -200,7 +198,7 @@ const ShareFile = ({
bucketName,
dateValid,
setShareURL,
setModalErrorSnackMessage,
dispatch,
distributedSetup,
isLoadingVersion,
versionID,
@@ -254,7 +252,11 @@ const ShareFile = ({
<BoxIconButton
variant="outlined"
onClick={() => {
setModalSnackMessage("Share URL Copied to clipboard");
dispatch(
setModalSnackMessage(
"Share URL Copied to clipboard"
)
);
}}
disabled={shareURL === "" || isLoadingFile}
sx={{
@@ -278,13 +280,4 @@ const ShareFile = ({
);
};
const mapStateToProps = ({ system }: AppState) => ({
distributedSetup: get(system, "distributedSetup", false),
});
const connector = connect(mapStateToProps, {
setModalSnackMessage,
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(ShareFile));
export default withStyles(styles)(ShareFile);

View File

@@ -14,14 +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 React, { useState, Fragment } from "react";
import React, { Fragment, useState } from "react";
import get from "lodash/get";
import { connect } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { Box, Button, Grid } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { setModalErrorSnackMessage } from "../../../../../../actions";
import { AppState } from "../../../../../../store";
import { ErrorResponseHandler } from "../../../../../../common/types";
import InputBoxWrapper from "../../../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
@@ -43,14 +43,13 @@ import { IAM_SCOPES } from "../../../../../../common/SecureComponent/permissions
import { SecureComponent } from "../../../../../../common/SecureComponent";
import Chip from "@mui/material/Chip";
import CloseIcon from "@mui/icons-material/Close";
import { setModalErrorSnackMessage } from "../../../../../../systemSlice";
interface ITagModal {
modalOpen: boolean;
bucketName: string;
actualInfo: IFileInfo;
onCloseAndUpdate: (refresh: boolean) => void;
distributedSetup: boolean;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
classes: any;
}
@@ -96,11 +95,13 @@ const AddTagModal = ({
modalOpen,
onCloseAndUpdate,
bucketName,
distributedSetup,
actualInfo,
setModalErrorSnackMessage,
classes,
}: ITagModal) => {
const dispatch = useDispatch();
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const [newKey, setNewKey] = useState<string>("");
const [newLabel, setNewLabel] = useState<string>("");
const [isSending, setIsSending] = useState<boolean>(false);
@@ -140,7 +141,7 @@ const AddTagModal = ({
setIsSending(false);
})
.catch((error: ErrorResponseHandler) => {
setModalErrorSnackMessage(error);
dispatch(setModalErrorSnackMessage(error));
setIsSending(false);
});
};
@@ -162,7 +163,7 @@ const AddTagModal = ({
setIsSending(false);
})
.catch((error: ErrorResponseHandler) => {
setModalErrorSnackMessage(error);
dispatch(setModalErrorSnackMessage(error));
setIsSending(false);
});
};
@@ -365,14 +366,4 @@ const AddTagModal = ({
);
};
const mapStateToProps = ({ system }: AppState) => ({
distributedSetup: get(system, "distributedSetup", false),
});
const mapDispatchToProps = {
setModalErrorSnackMessage,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export default withStyles(styles)(connector(AddTagModal));
export default withStyles(styles)(AddTagModal);

View File

@@ -16,7 +16,7 @@
import React, { Fragment, useEffect, useState } from "react";
import get from "lodash/get";
import { connect } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { withStyles } from "@mui/styles";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -28,20 +28,17 @@ import {
buttonsStyles,
containerForHeader,
hrClass,
tableStyles,
spacingUtils,
textStyleUtils,
objectBrowserExtras,
objectBrowserCommon,
objectBrowserExtras,
spacingUtils,
tableStyles,
textStyleUtils,
} from "../../../../Common/FormComponents/common/styleLibrary";
import { IFileInfo } from "./types";
import { download } from "../utils";
import api from "../../../../../../common/api";
import { ErrorResponseHandler } from "../../../../../../common/types";
import {
setErrorSnackMessage,
setSnackBarMessage,
} from "../../../../../../actions";
import {
decodeURLString,
encodeURLString,
@@ -49,16 +46,6 @@ import {
} from "../../../../../../common/utils";
import ScreenTitle from "../../../../Common/ScreenTitle/ScreenTitle";
import RestoreFileVersion from "./RestoreFileVersion";
import {
cancelObjectInList,
completeObject,
failObject,
setLoadingObjectInfo,
setLoadingVersions,
setNewObject,
setSelectedVersion,
updateProgress,
} from "../../../../ObjectBrowser/actions";
import { AppState } from "../../../../../../store";
import {
@@ -75,6 +62,21 @@ import RBIconButton from "../../../BucketDetails/SummaryItems/RBIconButton";
import DeleteNonCurrent from "../ListObjects/DeleteNonCurrent";
import BrowserBreadcrumbs from "../../../../ObjectBrowser/BrowserBreadcrumbs";
import DeleteSelectedVersions from "./DeleteSelectedVersions";
import { setErrorSnackMessage } from "../../../../../../systemSlice";
import {
makeid,
storeCallForObjectWithID,
} from "../../../../ObjectBrowser/transferManager";
import {
cancelObjectInList,
completeObject,
failObject,
setLoadingObjectInfo,
setLoadingVersions,
setNewObject,
setSelectedVersion,
updateProgress,
} from "../../../../ObjectBrowser/objectBrowserSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -136,22 +138,8 @@ const styles = (theme: Theme) =>
interface IVersionsNavigatorProps {
classes: any;
distributedSetup: boolean;
internalPaths: string;
bucketName: string;
searchVersions: string;
loadingVersions: boolean;
selectedVersion: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
setSnackBarMessage: typeof setSnackBarMessage;
setNewObject: typeof setNewObject;
updateProgress: typeof updateProgress;
completeObject: typeof completeObject;
setSelectedVersion: typeof setSelectedVersion;
setLoadingVersions: typeof setLoadingVersions;
setLoadingObjectInfo: typeof setLoadingObjectInfo;
failObject: typeof failObject;
cancelObjectInList: typeof cancelObjectInList;
}
const emptyFile: IFileInfo = {
@@ -168,22 +156,24 @@ const emptyFile: IFileInfo = {
const VersionsNavigator = ({
classes,
distributedSetup,
setErrorSnackMessage,
setNewObject,
updateProgress,
searchVersions,
loadingVersions,
selectedVersion,
completeObject,
internalPaths,
bucketName,
setSelectedVersion,
setLoadingVersions,
setLoadingObjectInfo,
failObject,
cancelObjectInList,
}: IVersionsNavigatorProps) => {
const dispatch = useDispatch();
const searchVersions = useSelector(
(state: AppState) => state.objectBrowser.searchVersions
);
const loadingVersions = useSelector(
(state: AppState) => state.objectBrowser.loadingVersions
);
const selectedVersion = useSelector(
(state: AppState) => state.objectBrowser.selectedVersion
);
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const [shareFileModalOpen, setShareFileModalOpen] = useState<boolean>(false);
const [actualInfo, setActualInfo] = useState<IFileInfo | null>(null);
const [objectToShare, setObjectToShare] = useState<IFileInfo | null>(null);
@@ -206,9 +196,9 @@ const VersionsNavigator = ({
useEffect(() => {
if (!loadingVersions && !actualInfo) {
setLoadingVersions(true);
dispatch(setLoadingVersions(true));
}
}, [loadingVersions, actualInfo, setLoadingVersions]);
}, [loadingVersions, actualInfo, dispatch]);
useEffect(() => {
if (loadingVersions && internalPaths !== "") {
@@ -231,21 +221,14 @@ const VersionsNavigator = ({
setVersions([]);
}
setLoadingVersions(false);
dispatch(setLoadingVersions(false));
})
.catch((error: ErrorResponseHandler) => {
setErrorSnackMessage(error);
setLoadingVersions(false);
.catch((err: ErrorResponseHandler) => {
dispatch(setErrorSnackMessage(err));
dispatch(setLoadingVersions(false));
});
}
}, [
setLoadingVersions,
loadingVersions,
bucketName,
internalPaths,
setErrorSnackMessage,
distributedSetup,
]);
}, [loadingVersions, bucketName, internalPaths, dispatch, distributedSetup]);
const shareObject = () => {
setShareFileModalOpen(true);
@@ -268,31 +251,39 @@ const VersionsNavigator = ({
object.version_id,
parseInt(object.size || "0"),
(progress) => {
updateProgress(identityDownload, progress);
dispatch(
updateProgress({
instanceID: identityDownload,
progress: progress,
})
);
},
() => {
completeObject(identityDownload);
dispatch(completeObject(identityDownload));
},
() => {
failObject(identityDownload);
dispatch(failObject(identityDownload));
},
() => {
cancelObjectInList(identityDownload);
dispatch(cancelObjectInList(identityDownload));
}
);
setNewObject({
bucketName,
done: false,
instanceID: identityDownload,
percentage: 0,
prefix: object.name,
type: "download",
waitingForFile: true,
failed: false,
cancelled: false,
call: downloadCall,
});
const ID = makeid(8);
storeCallForObjectWithID(ID, downloadCall);
dispatch(
setNewObject({
ID,
bucketName,
done: false,
instanceID: identityDownload,
percentage: 0,
prefix: object.name,
type: "download",
waitingForFile: true,
failed: false,
cancelled: false,
})
);
downloadCall.send();
};
@@ -317,7 +308,7 @@ const VersionsNavigator = ({
};
const onGlobalClick = (item: IFileInfo) => {
setSelectedVersion(item.version_id || "");
dispatch(setSelectedVersion(item.version_id || ""));
};
const filteredRecords = versions.filter((version) => {
@@ -332,8 +323,8 @@ const VersionsNavigator = ({
setRestoreVersion("");
if (reloadObjectData) {
setLoadingVersions(true);
setLoadingObjectInfo(true);
dispatch(setLoadingVersions(true));
dispatch(setLoadingObjectInfo(true));
}
};
@@ -341,9 +332,9 @@ const VersionsNavigator = ({
setDeleteNonCurrentOpen(false);
if (reloadAfterDelete) {
setLoadingVersions(true);
setSelectedVersion("");
setLoadingObjectInfo(true);
dispatch(setLoadingVersions(true));
dispatch(setSelectedVersion(""));
dispatch(setLoadingObjectInfo(true));
}
};
@@ -351,9 +342,9 @@ const VersionsNavigator = ({
setDelSelectedVOpen(false);
if (reloadOnComplete) {
setLoadingVersions(true);
setSelectedVersion("");
setLoadingObjectInfo(true);
dispatch(setLoadingVersions(true));
dispatch(setSelectedVersion(""));
dispatch(setLoadingObjectInfo(true));
setSelectedItems([]);
}
};
@@ -613,26 +604,4 @@ const VersionsNavigator = ({
);
};
const mapStateToProps = ({ system, objectBrowser }: AppState) => ({
distributedSetup: get(system, "distributedSetup", false),
searchVersions: objectBrowser.searchVersions,
loadingVersions: objectBrowser.loadingVersions,
selectedVersion: objectBrowser.selectedVersion,
});
const mapDispatchToProps = {
setErrorSnackMessage,
setSnackBarMessage,
setNewObject,
updateProgress,
completeObject,
setSelectedVersion,
setLoadingVersions,
setLoadingObjectInfo,
failObject,
cancelObjectInList,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
export default connector(withStyles(styles)(VersionsNavigator));
export default withStyles(styles)(VersionsNavigator);

View File

@@ -1,239 +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 { BucketInfo } from "./types";
export const ADD_BUCKET_OPEN = "ADD_BUCKET_OPEN";
export const ADD_BUCKET_NAME = "ADD_BUCKET_NAME";
export const ADD_BUCKET_VERSIONED = "ADD_BUCKET_VERSIONED";
export const ADD_BUCKET_LOCKING = "ADD_BUCKET_LOCKING";
export const ADD_BUCKET_QUOTA = "ADD_BUCKET_QUOTA";
export const ADD_BUCKET_QUOTA_TYPE = "ADD_BUCKET_QUOTA_TYPE";
export const ADD_BUCKET_QUOTA_SIZE = "ADD_BUCKET_QUOTA_SIZE";
export const ADD_BUCKET_QUOTA_UNIT = "ADD_BUCKET_QUOTA_UNIT";
export const ADD_BUCKET_RESET = "ADD_BUCKET_RESET";
export const ADD_BUCKET_RETENTION = "ADD_BUCKET_RETENTION";
export const ADD_BUCKET_RETENTION_MODE = "ADD_BUCKET_RETENTION_MODE";
export const ADD_BUCKET_RETENTION_UNIT = "ADD_BUCKET_RETENTION_UNIT";
export const ADD_BUCKET_RETENTION_VALIDITY = "ADD_BUCKET_RETENTION_VALIDITY";
export const BUCKET_DETAILS_SET_TAB = "BUCKET_DETAILS/SET_TAB";
export const BUCKET_DETAILS_LOADING = "BUCKET_DETAILS/LOADING";
export const BUCKET_DETAILS_SET_INFO = "BUCKET_DETAILS/SET_INFO";
interface AddBucketOpenAction {
type: typeof ADD_BUCKET_OPEN;
open: boolean;
}
interface AddBucketNameAction {
type: typeof ADD_BUCKET_NAME;
name: string;
}
interface AddBucketVersionedAction {
type: typeof ADD_BUCKET_VERSIONED;
versioned: boolean;
}
interface AddBucketLockingAction {
type: typeof ADD_BUCKET_LOCKING;
locking: boolean;
}
interface AddBucketQuotaAction {
type: typeof ADD_BUCKET_QUOTA;
quota: boolean;
}
interface AddBucketQuotaTypeAction {
type: typeof ADD_BUCKET_QUOTA_TYPE;
quotaType: string;
}
interface AddBucketQuotaSizeAction {
type: typeof ADD_BUCKET_QUOTA_SIZE;
quotaSize: string;
}
interface AddBucketQuotaUnitAction {
type: typeof ADD_BUCKET_QUOTA_UNIT;
quotaUnit: string;
}
interface AddBucketResetAction {
type: typeof ADD_BUCKET_RESET;
}
interface AddBucketRetentionAction {
type: typeof ADD_BUCKET_RETENTION;
retention: boolean;
}
interface AddBucketRetentionModeAction {
type: typeof ADD_BUCKET_RETENTION_MODE;
retentionMode: string;
}
interface AddBucketRetentionUnitAction {
type: typeof ADD_BUCKET_RETENTION_UNIT;
retentionUnit: string;
}
interface AddBucketRetentionValidityAction {
type: typeof ADD_BUCKET_RETENTION_VALIDITY;
retentionValidity: number;
}
interface SetBucketDetailsTab {
type: typeof BUCKET_DETAILS_SET_TAB;
tab: string;
}
interface SetLoadingBucket {
type: typeof BUCKET_DETAILS_LOADING;
state: boolean;
}
interface SetBucketInfo {
type: typeof BUCKET_DETAILS_SET_INFO;
info: BucketInfo | null;
}
export type BucketActionTypes =
| AddBucketOpenAction
| AddBucketNameAction
| AddBucketVersionedAction
| AddBucketLockingAction
| AddBucketQuotaAction
| AddBucketQuotaTypeAction
| AddBucketQuotaSizeAction
| AddBucketQuotaUnitAction
| AddBucketResetAction
| AddBucketRetentionAction
| AddBucketRetentionModeAction
| AddBucketRetentionUnitAction
| AddBucketRetentionValidityAction
| SetBucketDetailsTab
| SetLoadingBucket
| SetBucketInfo;
export function addBucketOpen(open: boolean) {
return {
type: ADD_BUCKET_OPEN,
open: open,
};
}
export function addBucketName(name: string) {
return {
type: ADD_BUCKET_NAME,
name: name,
};
}
export function addBucketVersioning(versioned: boolean) {
return {
type: ADD_BUCKET_VERSIONED,
versioned: versioned,
};
}
export function addBucketEnableObjectLocking(locking: boolean) {
return {
type: ADD_BUCKET_LOCKING,
locking: locking,
};
}
export function addBucketQuota(quota: boolean) {
return {
type: ADD_BUCKET_QUOTA,
quota: quota,
};
}
export function addBucketQuotaType(quotaType: string) {
return {
type: ADD_BUCKET_QUOTA_TYPE,
quotaType: quotaType,
};
}
export function addBucketQuotaSize(quotaSize: string) {
return {
type: ADD_BUCKET_QUOTA_SIZE,
quotaSize: quotaSize,
};
}
export function addBucketQuotaUnit(quotaUnit: string) {
return {
type: ADD_BUCKET_QUOTA_UNIT,
quotaUnit: quotaUnit,
};
}
export function addBucketReset() {
return {
type: ADD_BUCKET_RESET,
};
}
export function addBucketRetention(retention: boolean) {
return {
type: ADD_BUCKET_RETENTION,
retention: retention,
};
}
export function addBucketRetentionMode(mode: string) {
return {
type: ADD_BUCKET_RETENTION_MODE,
retentionMode: mode,
};
}
export function addBucketRetentionUnit(unit: string) {
return {
type: ADD_BUCKET_RETENTION_UNIT,
retentionUnit: unit,
};
}
export function addBucketRetentionValidity(validity: number) {
return {
type: ADD_BUCKET_RETENTION_VALIDITY,
retentionValidity: validity,
};
}
export function setBucketDetailsTab(tab: string) {
return {
type: BUCKET_DETAILS_SET_TAB,
tab,
};
}
export const setBucketDetailsLoad = (loading: boolean) => {
return {
type: BUCKET_DETAILS_LOADING,
state: loading,
};
};
export const setBucketInfo = (bucketInfo: BucketInfo | null) => {
return {
type: BUCKET_DETAILS_SET_INFO,
info: bucketInfo,
};
};

View File

@@ -0,0 +1,146 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { BucketInfo } from "./types";
export interface BucketsState {
open: boolean;
addBucketName: string;
addBucketVersioningEnabled: boolean;
addBucketLockingEnabled: boolean;
addBucketQuotaEnabled: boolean;
addBucketQuotaType: string;
addBucketQuotaSize: string;
addBucketQuotaUnit: string;
addBucketRetentionEnabled: boolean;
addBucketRetentionMode: string;
addBucketRetentionUnit: string;
addBucketRetentionValidity: number;
bucketDetails: BucketDetailsState;
}
export interface BucketDetailsState {
selectedTab: string;
loadingBucket: boolean;
bucketInfo: BucketInfo | null;
}
const initialState: BucketsState = {
open: false,
addBucketName: "",
addBucketVersioningEnabled: false,
addBucketLockingEnabled: false,
addBucketQuotaEnabled: false,
addBucketQuotaType: "hard",
addBucketQuotaSize: "1",
addBucketQuotaUnit: "Ti",
addBucketRetentionEnabled: false,
addBucketRetentionMode: "compliance",
addBucketRetentionUnit: "days",
addBucketRetentionValidity: 180,
bucketDetails: {
selectedTab: "summary",
loadingBucket: false,
bucketInfo: null,
},
};
export const bucketsSlice = createSlice({
name: "buckets",
initialState,
reducers: {
addBucketOpen: (state, action: PayloadAction<boolean>) => {
state.open = action.payload;
},
addBucketName: (state, action: PayloadAction<string>) => {
state.addBucketName = action.payload;
},
addBucketVersioning: (state, action: PayloadAction<boolean>) => {
state.addBucketVersioningEnabled = action.payload;
},
addBucketEnableObjectLocking: (state, action: PayloadAction<boolean>) => {
state.addBucketLockingEnabled = action.payload;
},
addBucketQuota: (state, action: PayloadAction<boolean>) => {
state.addBucketQuotaEnabled = action.payload;
},
addBucketQuotaType: (state, action: PayloadAction<string>) => {
state.addBucketQuotaType = action.payload;
},
addBucketQuotaSize: (state, action: PayloadAction<string>) => {
state.addBucketQuotaSize = action.payload;
},
addBucketQuotaUnit: (state, action: PayloadAction<string>) => {
state.addBucketQuotaUnit = action.payload;
},
addBucketRetention: (state, action: PayloadAction<boolean>) => {
state.addBucketRetentionEnabled = action.payload;
},
addBucketRetentionMode: (state, action: PayloadAction<string>) => {
state.addBucketRetentionMode = action.payload;
},
addBucketRetentionUnit: (state, action: PayloadAction<string>) => {
state.addBucketRetentionUnit = action.payload;
},
addBucketRetentionValidity: (state, action: PayloadAction<number>) => {
state.addBucketRetentionValidity = action.payload;
},
setBucketDetailsTab: (state, action: PayloadAction<string>) => {
state.bucketDetails.selectedTab = action.payload;
},
addBucketReset: (state) => {
state.addBucketName = "";
state.addBucketVersioningEnabled = false;
state.addBucketLockingEnabled = false;
state.addBucketQuotaEnabled = false;
state.addBucketQuotaType = "hard";
state.addBucketQuotaSize = "1";
state.addBucketQuotaUnit = "Ti";
state.addBucketRetentionEnabled = false;
state.addBucketRetentionMode = "compliance";
state.addBucketRetentionUnit = "days";
state.addBucketRetentionValidity = 180;
},
setBucketDetailsLoad: (state, action: PayloadAction<boolean>) => {
state.bucketDetails.loadingBucket = action.payload;
},
setBucketInfo: (state, action: PayloadAction<BucketInfo | null>) => {
state.bucketDetails.bucketInfo = action.payload;
},
},
});
export const {
addBucketOpen,
addBucketName,
addBucketVersioning,
addBucketEnableObjectLocking,
addBucketQuota,
addBucketQuotaType,
addBucketQuotaSize,
addBucketQuotaUnit,
addBucketReset,
addBucketRetention,
addBucketRetentionMode,
addBucketRetentionUnit,
addBucketRetentionValidity,
setBucketDetailsTab,
setBucketDetailsLoad,
setBucketInfo,
} = bucketsSlice.actions;
export default bucketsSlice.reducer;

View File

@@ -1,187 +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 {
ADD_BUCKET_LOCKING,
ADD_BUCKET_NAME,
ADD_BUCKET_OPEN,
ADD_BUCKET_QUOTA,
ADD_BUCKET_QUOTA_SIZE,
ADD_BUCKET_QUOTA_TYPE,
ADD_BUCKET_QUOTA_UNIT,
ADD_BUCKET_RESET,
ADD_BUCKET_RETENTION,
ADD_BUCKET_RETENTION_MODE,
ADD_BUCKET_RETENTION_UNIT,
ADD_BUCKET_RETENTION_VALIDITY,
ADD_BUCKET_VERSIONED,
BUCKET_DETAILS_LOADING,
BUCKET_DETAILS_SET_INFO,
BUCKET_DETAILS_SET_TAB,
BucketActionTypes,
} from "./actions";
import { BucketInfo } from "./types";
export interface BucketsState {
open: boolean;
addBucketName: string;
addBucketVersioningEnabled: boolean;
addBucketLockingEnabled: boolean;
addBucketQuotaEnabled: boolean;
addBucketQuotaType: string;
addBucketQuotaSize: string;
addBucketQuotaUnit: string;
addBucketRetentionEnabled: boolean;
addBucketRetentionMode: string;
addBucketRetentionUnit: string;
addBucketRetentionValidity: number;
bucketDetails: BucketDetailsState;
}
export interface BucketDetailsState {
selectedTab: string;
loadingBucket: boolean;
bucketInfo: BucketInfo | null;
}
const initialState: BucketsState = {
open: false,
addBucketName: "",
addBucketVersioningEnabled: false,
addBucketLockingEnabled: false,
addBucketQuotaEnabled: false,
addBucketQuotaType: "hard",
addBucketQuotaSize: "1",
addBucketQuotaUnit: "Ti",
addBucketRetentionEnabled: false,
addBucketRetentionMode: "compliance",
addBucketRetentionUnit: "days",
addBucketRetentionValidity: 180,
bucketDetails: {
selectedTab: "summary",
loadingBucket: false,
bucketInfo: null,
},
};
export function bucketsReducer(
state = initialState,
action: BucketActionTypes
): BucketsState {
switch (action.type) {
case ADD_BUCKET_OPEN:
return {
...state,
open: action.open,
};
case ADD_BUCKET_NAME:
return {
...state,
addBucketName: action.name,
};
case ADD_BUCKET_VERSIONED:
return {
...state,
addBucketVersioningEnabled: action.versioned,
};
case ADD_BUCKET_LOCKING:
return {
...state,
addBucketLockingEnabled: action.locking,
};
case ADD_BUCKET_QUOTA:
return {
...state,
addBucketQuotaEnabled: action.quota,
};
case ADD_BUCKET_QUOTA_TYPE:
return {
...state,
addBucketQuotaType: action.quotaType,
};
case ADD_BUCKET_QUOTA_SIZE:
return {
...state,
addBucketQuotaSize: action.quotaSize,
};
case ADD_BUCKET_QUOTA_UNIT:
return {
...state,
addBucketQuotaUnit: action.quotaUnit,
};
case ADD_BUCKET_RETENTION:
return {
...state,
addBucketRetentionEnabled: action.retention,
};
case ADD_BUCKET_RETENTION_MODE:
return {
...state,
addBucketRetentionMode: action.retentionMode,
};
case ADD_BUCKET_RETENTION_UNIT:
return {
...state,
addBucketRetentionUnit: action.retentionUnit,
};
case ADD_BUCKET_RETENTION_VALIDITY:
return {
...state,
addBucketRetentionValidity: action.retentionValidity,
};
case BUCKET_DETAILS_SET_TAB:
return {
...state,
bucketDetails: {
...state.bucketDetails,
selectedTab: action.tab,
},
};
case ADD_BUCKET_RESET:
return {
...state,
addBucketName: "",
addBucketVersioningEnabled: false,
addBucketLockingEnabled: false,
addBucketQuotaEnabled: false,
addBucketQuotaType: "hard",
addBucketQuotaSize: "1",
addBucketQuotaUnit: "Ti",
addBucketRetentionEnabled: false,
addBucketRetentionMode: "compliance",
addBucketRetentionUnit: "days",
addBucketRetentionValidity: 180,
};
case BUCKET_DETAILS_LOADING:
return {
...state,
bucketDetails: {
...state.bucketDetails,
loadingBucket: action.state,
},
};
case BUCKET_DETAILS_SET_INFO:
return {
...state,
bucketDetails: {
...state.bucketDetails,
bucketInfo: action.info,
},
};
default:
return state;
}
}

View File

@@ -14,6 +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 * as React from "react";
import { useCallback, useEffect, useState } from "react";
import {
ActionId,
ActionImpl,
@@ -22,10 +23,10 @@ import {
KBarPositioner,
KBarResults,
KBarSearch,
KBarState,
useKBar,
useMatches,
useRegisterActions,
useKBar,
KBarState,
} from "kbar";
import { Action } from "kbar/lib/types";
import { Theme } from "@mui/material/styles";
@@ -36,7 +37,6 @@ import { MenuExpandedIcon } from "../../icons/SidebarMenus";
import { AppState } from "../../store";
import { connect } from "react-redux";
import useApi from "./Common/Hooks/useApi";
import { useCallback, useEffect, useState } from "react";
import { Bucket, BucketList } from "./Buckets/types";
const useStyles = makeStyles((theme: Theme) => ({

View File

@@ -46,7 +46,7 @@ const DistributedOnly = ({ iconComponent, entity }: IDistributedOnly) => {
},
}}
>
<div>This feature is not available for a single-disk setup. </div>
<div>This feature is not available for a single-disk setup.</div>
<div>
Please deploy a server in{" "}

View File

@@ -18,7 +18,7 @@ import React from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Grid, Button, Box } from "@mui/material";
import { Box, Button, Grid } from "@mui/material";
import ScheduleIcon from "@mui/icons-material/Schedule";
import WatchLaterIcon from "@mui/icons-material/WatchLater";
import { actionsTray, widgetContainerCommon } from "../common/styleLibrary";

View File

@@ -15,10 +15,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, {
useState,
forwardRef,
useImperativeHandle,
useEffect,
useImperativeHandle,
useState,
} from "react";
import clsx from "clsx";
import Grid from "@mui/material/Grid";

View File

@@ -17,12 +17,12 @@ import React from "react";
import Grid from "@mui/material/Grid";
import {
FormControl,
InputBase,
InputLabel,
MenuItem,
Select,
InputBase,
Tooltip,
SelectChangeEvent,
Tooltip,
} from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";

View File

@@ -14,19 +14,16 @@
// 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, { useState, useEffect, useCallback } from "react";
import { connect } from "react-redux";
import React, { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import get from "lodash/get";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../actions";
import { snackBarMessage } from "../../../../types";
import { Box } from "@mui/material";
import { AlertCloseIcon } from "../../../../icons";
import { Portal } from "@mui/base";
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IMainErrorProps {
snackBar: snackBarMessage;
displayErrorMessage: typeof setErrorSnackMessage;
isModal?: boolean;
}
@@ -40,11 +37,11 @@ const stopHideTimer = () => {
clearInterval(timerI);
};
const MainError = ({
snackBar,
displayErrorMessage,
isModal = false,
}: IMainErrorProps) => {
const MainError = ({ isModal = false }: IMainErrorProps) => {
const dispatch = useDispatch();
const snackBar = useSelector((state: AppState) => {
return isModal ? state.system.modalSnackBar : state.system.snackBar;
});
const [displayErrorMsg, setDisplayErrorMsg] = useState<boolean>(false);
const closeErrorMessage = useCallback(() => {
@@ -53,10 +50,10 @@ const MainError = ({
useEffect(() => {
if (!displayErrorMsg) {
displayErrorMessage({ detailedError: "", errorMessage: "" });
dispatch(setErrorSnackMessage({ detailedError: "", errorMessage: "" }));
clearInterval(timerI);
}
}, [displayErrorMessage, displayErrorMsg]);
}, [dispatch, displayErrorMsg]);
useEffect(() => {
if (snackBar.message !== "" && snackBar.type === "error") {
@@ -162,16 +159,4 @@ const MainError = ({
);
};
const mapState = (state: AppState, ownProps: any) => ({
snackBar: ownProps.isModal
? state.system.modalSnackBar
: state.system.snackBar,
});
const mapDispatchToProps = {
displayErrorMessage: setErrorSnackMessage,
};
const connector = connect(mapState, mapDispatchToProps);
export default connector(MainError);
export default MainError;

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, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import IconButton from "@mui/material/IconButton";
import Snackbar from "@mui/material/Snackbar";
import { Dialog, DialogContent, DialogTitle } from "@mui/material";
@@ -26,10 +26,9 @@ import {
snackBarCommon,
} from "../FormComponents/common/styleLibrary";
import { AppState } from "../../../../store";
import { snackBarMessage } from "../../../../types";
import { setModalSnackMessage } from "../../../../actions";
import CloseIcon from "@mui/icons-material/Close";
import MainError from "../MainError/MainError";
import { setModalSnackMessage } from "../../../../systemSlice";
interface IModalProps {
classes: any;
@@ -38,9 +37,7 @@ interface IModalProps {
title: string | React.ReactNode;
children: any;
wideLimit?: boolean;
modalSnackMessage?: snackBarMessage;
noContentPadding?: boolean;
setModalSnackMessage: typeof setModalSnackMessage;
titleIcon?: React.ReactNode;
}
@@ -65,16 +62,19 @@ const ModalWrapper = ({
children,
classes,
wideLimit = true,
modalSnackMessage,
noContentPadding,
setModalSnackMessage,
titleIcon = null,
}: IModalProps) => {
const dispatch = useDispatch();
const [openSnackbar, setOpenSnackbar] = useState<boolean>(false);
const modalSnackMessage = useSelector(
(state: AppState) => state.system.modalSnackBar
);
useEffect(() => {
setModalSnackMessage("");
}, [setModalSnackMessage]);
dispatch(setModalSnackMessage(""));
}, [dispatch]);
useEffect(() => {
if (modalSnackMessage) {
@@ -91,7 +91,7 @@ const ModalWrapper = ({
const closeSnackBar = () => {
setOpenSnackbar(false);
setModalSnackMessage("");
dispatch(setModalSnackMessage(""));
};
const customSize = wideLimit
@@ -171,12 +171,4 @@ const ModalWrapper = ({
);
};
const mapState = (state: AppState) => ({
modalSnackMessage: state.system.modalSnackBar,
});
const connector = connect(mapState, {
setModalSnackMessage,
});
export default withStyles(styles)(connector(ModalWrapper));
export default withStyles(styles)(ModalWrapper);

View File

@@ -22,13 +22,14 @@ import withStyles from "@mui/styles/withStyles";
import { IFileItem } from "../../ObjectBrowser/types";
import ProgressBarWrapper from "../ProgressBarWrapper/ProgressBarWrapper";
import {
CancelledIcon,
DisabledIcon,
DownloadStatIcon,
EnabledIcon,
UploadStatIcon,
CancelledIcon,
} from "../../../../icons";
import clsx from "clsx";
import { callForObjectID } from "../../ObjectBrowser/transferManager";
interface IObjectHandled {
classes: any;
@@ -163,8 +164,10 @@ const ObjectHandled = ({
onClick={() => {
if (!objectToDisplay.done) {
console.log("//abort");
objectToDisplay.call?.abort();
const call = callForObjectID(objectToDisplay.ID);
if (call) {
call.abort();
}
} else {
deleteFromList(objectToDisplay.instanceID);
}

View File

@@ -16,23 +16,17 @@
import React, { Fragment } from "react";
import { Theme } from "@mui/material/styles";
import { connect } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Tooltip, IconButton } from "@mui/material";
import { IconButton, Tooltip } from "@mui/material";
import { AppState } from "../../../../store";
import { IFileItem } from "../../ObjectBrowser/types";
import { deleteFromList, cleanList } from "../../ObjectBrowser/actions";
import { RemoveAllIcon } from "../../../../icons";
import ObjectHandled from "./ObjectHandled";
interface IObjectManager {
objects: IFileItem[];
classes: any;
managerOpen: boolean;
deleteFromList: typeof deleteFromList;
cleanList: typeof cleanList;
}
import {
cleanList,
deleteFromList,
} from "../../ObjectBrowser/objectBrowserSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -87,13 +81,19 @@ const styles = (theme: Theme) =>
},
});
const ObjectManager = ({
objects,
classes,
managerOpen,
deleteFromList,
cleanList,
}: IObjectManager) => {
interface IObjectManager {
classes: any;
}
const ObjectManager = ({ classes }: IObjectManager) => {
const dispatch = useDispatch();
const objects = useSelector(
(state: AppState) => state.objectBrowser.objectManager.objectsToManage
);
const managerOpen = useSelector(
(state: AppState) => state.objectBrowser.objectManager.managerOpen
);
return (
<Fragment>
{managerOpen && (
@@ -107,7 +107,7 @@ const ObjectManager = ({
<IconButton
aria-label={"Clear Completed List"}
size={"small"}
onClick={cleanList}
onClick={() => dispatch(cleanList())}
className={classes.cleanButton}
>
<RemoveAllIcon />
@@ -120,7 +120,9 @@ const ObjectManager = ({
<ObjectHandled
objectToDisplay={object}
key={`object-handled-${object.instanceID}`}
deleteFromList={deleteFromList}
deleteFromList={(instanceID) =>
dispatch(deleteFromList(instanceID))
}
/>
))}
</div>
@@ -130,11 +132,4 @@ const ObjectManager = ({
);
};
const mapState = (state: AppState) => ({
objects: state.objectBrowser.objectManager.objectsToManage,
managerOpen: state.objectBrowser.objectManager.managerOpen,
});
const connector = connect(mapState, { deleteFromList, cleanList });
export default withStyles(styles)(connector(ObjectManager));
export default withStyles(styles)(ObjectManager);

View File

@@ -16,7 +16,7 @@
import React, { Fragment, useEffect, useState } from "react";
import { Theme } from "@mui/material/styles";
import { connect } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import Grid from "@mui/material/Grid";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -24,24 +24,10 @@ import IconButton from "@mui/material/IconButton";
import { AppState } from "../../../../store";
import OperatorLogo from "../../../../icons/OperatorLogo";
import ConsoleLogo from "../../../../icons/ConsoleLogo";
import { IFileItem } from "../../ObjectBrowser/types";
import { toggleList } from "../../ObjectBrowser/actions";
import { CircleIcon, ObjectManagerIcon } from "../../../../icons";
import { Box } from "@mui/material";
interface IPageHeader {
classes: any;
sidebarOpen?: boolean;
operatorMode?: boolean;
label: any;
actions?: any;
managerObjects: IFileItem[];
toggleList: typeof toggleList;
middleComponent?: React.ReactNode;
features: string[];
managerOpen: boolean;
newItems: boolean;
}
import { toggleList } from "../../ObjectBrowser/objectBrowserSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -100,19 +86,40 @@ const styles = (theme: Theme) =>
},
});
interface IPageHeader {
classes: any;
label: any;
actions?: any;
middleComponent?: React.ReactNode;
}
const PageHeader = ({
classes,
label,
actions,
sidebarOpen,
operatorMode,
managerObjects,
toggleList,
middleComponent,
features,
managerOpen,
newItems,
}: IPageHeader) => {
const dispatch = useDispatch();
const sidebarOpen = useSelector(
(state: AppState) => state.system.sidebarOpen
);
const operatorMode = useSelector(
(state: AppState) => state.system.operatorMode
);
const managerObjects = useSelector(
(state: AppState) => state.objectBrowser.objectManager.objectsToManage
);
const features = useSelector(
(state: AppState) => state.console.session.features
);
const managerOpen = useSelector(
(state: AppState) => state.objectBrowser.objectManager.managerOpen
);
const newItems = useSelector(
(state: AppState) => state.objectBrowser.objectManager.newItems
);
const [newObject, setNewObject] = useState<boolean>(false);
useEffect(() => {
@@ -187,7 +194,7 @@ const PageHeader = ({
aria-label="Refresh List"
component="span"
onClick={() => {
toggleList();
dispatch(toggleList());
}}
id="object-manager-toggle"
size="large"
@@ -222,19 +229,4 @@ const PageHeader = ({
);
};
const mapState = (state: AppState) => ({
sidebarOpen: state.system.sidebarOpen,
operatorMode: state.system.operatorMode,
managerObjects: state.objectBrowser.objectManager.objectsToManage,
features: state.console.session.features,
managerOpen: state.objectBrowser.objectManager.managerOpen,
newItems: state.objectBrowser.objectManager.newItems,
});
const mapDispatchToProps = {
toggleList,
};
const connector = connect(mapState, mapDispatchToProps);
export default connector(withStyles(styles)(PageHeader));
export default withStyles(styles)(PageHeader);

View File

@@ -22,15 +22,15 @@ import { ICertificateInfo } from "../../Tenants/types";
import LanguageIcon from "@mui/icons-material/Language";
import Chip from "@mui/material/Chip";
import {
Typography,
Divider,
Box,
Grid,
Container,
ListItemText,
Divider,
Grid,
List,
ListItem,
ListItemAvatar,
ListItemText,
Typography,
} from "@mui/material";
import EventBusyIcon from "@mui/icons-material/EventBusy";
import Moment from "react-moment";

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, useState, useEffect } from "react";
import React, { Fragment, useEffect, useState } from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";

View File

@@ -16,15 +16,12 @@
import React, { Fragment, useEffect, useState } from "react";
import { AddIcon, ClustersIcon, RemoveIcon } from "../../../../icons";
import { ReplicationSite } from "./SiteReplication";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import Grid from "@mui/material/Grid";
import { Box, Button, LinearProgress } from "@mui/material";
import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton";
import useApi from "../../Common/Hooks/useApi";
import { connect } from "react-redux";
import { setErrorSnackMessage, setSnackBarMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import { useDispatch } from "react-redux";
import PageHeader from "../../Common/PageHeader/PageHeader";
import BackLink from "../../../../common/BackLink";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
@@ -32,6 +29,10 @@ import PageLayout from "../../Common/Layout/PageLayout";
import HelpBox from "../../../../common/HelpBox";
import history from "../../../../history";
import SectionTitle from "../../Common/SectionTitle";
import {
setErrorSnackMessage,
setSnackBarMessage,
} from "../../../../systemSlice";
type SiteInputRow = {
name: string;
@@ -53,15 +54,8 @@ const isValidEndPoint = (ep: string) => {
return "Invalid Endpoint";
}
};
const AddReplicationSites = ({
setErrorSnackMessage,
setSnackBarMessage,
}: {
existingSites: ReplicationSite[];
onClose: () => void;
setErrorSnackMessage: (err: ErrorResponseHandler) => void;
setSnackBarMessage: (msg: string) => void;
}) => {
const AddReplicationSites = () => {
const dispatch = useDispatch();
const [existingSites, setExistingSites] = useState<SiteInputRow[]>([]);
const [accessKey, setAccessKey] = useState<string>("");
@@ -130,19 +124,21 @@ const AddReplicationSites = ({
const [isAdding, invokeSiteAddApi] = useApi(
(res: any) => {
if (res.success) {
setSnackBarMessage(res.status);
dispatch(setSnackBarMessage(res.status));
resetForm();
getSites();
history.push(IAM_PAGES.SITE_REPLICATION);
} else {
setErrorSnackMessage({
errorMessage: "Error",
detailedError: res.status,
});
dispatch(
setErrorSnackMessage({
errorMessage: "Error",
detailedError: res.status,
})
);
}
},
(err: any) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
}
);
@@ -612,8 +608,4 @@ const AddReplicationSites = ({
);
};
const connector = connect(null, {
setErrorSnackMessage,
setSnackBarMessage,
});
export default connector(AddReplicationSites);
export default AddReplicationSites;

View File

@@ -26,9 +26,7 @@ import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import Grid from "@mui/material/Grid";
import useApi from "../../Common/Hooks/useApi";
import { connect } from "react-redux";
import { setErrorSnackMessage, setSnackBarMessage } from "../../../../actions";
import { ErrorResponseHandler } from "../../../../common/types";
import { useDispatch } from "react-redux";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import withStyles from "@mui/styles/withStyles";
import { Theme } from "@mui/material/styles";
@@ -38,6 +36,10 @@ import {
modalStyleUtils,
spacingUtils,
} from "../../Common/FormComponents/common/styleLibrary";
import {
setErrorSnackMessage,
setSnackBarMessage,
} from "../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -49,18 +51,15 @@ const styles = (theme: Theme) =>
const ReplicationSites = ({
sites,
onDeleteSite,
setErrorSnackMessage,
setSnackBarMessage,
onRefresh,
classes,
}: {
sites: ReplicationSite[];
onDeleteSite: (isAll: boolean, sites: string[]) => void;
setErrorSnackMessage: (err: ErrorResponseHandler) => void;
setSnackBarMessage: (msg: string) => void;
onRefresh: () => void;
classes: any;
}) => {
const dispatch = useDispatch();
const [deleteSiteKey, setIsDeleteSiteKey] = useState<string>("");
const [editSite, setEditSite] = useState<any>(null);
const [editEndPointName, setEditEndPointName] = useState<string>("");
@@ -69,17 +68,19 @@ const ReplicationSites = ({
(res: any) => {
if (res.success) {
setEditSite(null);
setSnackBarMessage(res.status);
dispatch(setSnackBarMessage(res.status));
} else {
setErrorSnackMessage({
errorMessage: "Error",
detailedError: res.status,
});
dispatch(
setErrorSnackMessage({
errorMessage: "Error",
detailedError: res.status,
})
);
}
onRefresh();
},
(err: any) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
onRefresh();
}
);
@@ -353,8 +354,4 @@ const ReplicationSites = ({
);
};
const connector = connect(null, {
setErrorSnackMessage,
setSnackBarMessage,
});
export default connector(withStyles(styles)(ReplicationSites));
export default withStyles(styles)(ReplicationSites);

View File

@@ -29,13 +29,16 @@ import {
ConfirmDeleteIcon,
RecoverIcon,
} from "../../../../icons";
import { connect } from "react-redux";
import { setErrorSnackMessage, setSnackBarMessage } from "../../../../actions";
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,
setSnackBarMessage,
} from "../../../../systemSlice";
export type ReplicationSite = {
deploymentID: string;
@@ -44,11 +47,8 @@ export type ReplicationSite = {
isCurrent?: boolean;
};
const SiteReplication = ({
setSnackBarMessage,
}: {
setSnackBarMessage: (msg: string) => void;
}) => {
const SiteReplication = () => {
const dispatch = useDispatch();
const [sites, setSites] = useState([]);
const [deleteAll, setIsDeleteAll] = useState(false);
@@ -83,11 +83,11 @@ const SiteReplication = ({
const [isRemoving, invokeSiteRemoveApi] = useApi(
(res: any) => {
setIsDeleteAll(false);
setSnackBarMessage(`Successfully deleted.`);
dispatch(setSnackBarMessage(`Successfully deleted.`));
getSites();
},
(err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
}
);
@@ -259,9 +259,4 @@ const SiteReplication = ({
);
};
const connector = connect(null, {
setErrorSnackMessage,
setSnackBarMessage,
});
export default connector(SiteReplication);
export default SiteReplication;

View File

@@ -15,14 +15,13 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useCallback, useEffect, useState } from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import get from "lodash/get";
import Grid from "@mui/material/Grid";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Box, Button } from "@mui/material";
import { setErrorSnackMessage } from "../../../../actions";
import {
fileInputStyles,
formFieldStyles,
@@ -46,6 +45,7 @@ import PageLayout from "../../Common/Layout/PageLayout";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
import RegionSelectWrapper from "./RegionSelectWrapper";
import { setErrorSnackMessage } from "../../../../systemSlice";
const styles = (theme: Theme) =>
createStyles({
@@ -73,7 +73,6 @@ const styles = (theme: Theme) =>
});
interface IAddNotificationEndpointProps {
setErrorSnackMessage: typeof setErrorSnackMessage;
classes: any;
match: any;
history: any;
@@ -81,10 +80,10 @@ interface IAddNotificationEndpointProps {
const AddTierConfiguration = ({
classes,
setErrorSnackMessage,
match,
history,
}: IAddNotificationEndpointProps) => {
const dispatch = useDispatch();
//Local States
const [saving, setSaving] = useState<boolean>(false);
@@ -191,7 +190,7 @@ const AddTierConfiguration = ({
})
.catch((err: ErrorResponseHandler) => {
setSaving(false);
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
});
}
}, [
@@ -207,7 +206,7 @@ const AddTierConfiguration = ({
region,
saving,
secretKey,
setErrorSnackMessage,
dispatch,
storageClass,
type,
]);
@@ -533,10 +532,4 @@ const AddTierConfiguration = ({
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(AddTierConfiguration));
export default withStyles(styles)(AddTierConfiguration);

View File

@@ -16,7 +16,7 @@
import React, { Fragment, useEffect, useState } from "react";
import get from "lodash/get";
import { connect } 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";
@@ -31,7 +31,7 @@ import {
typesSelection,
} from "../../Common/FormComponents/common/styleLibrary";
import { AddIcon, TiersIcon, TiersNotAvailableIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../actions";
import { ITierElement, ITierResponse } from "./types";
import { ErrorResponseHandler } from "../../../../common/types";
import api from "../../../../common/api";
@@ -55,6 +55,7 @@ import {
import { SecureComponent } from "../../../../common/SecureComponent";
import { tierTypes } from "./utils";
import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton";
import { setErrorSnackMessage } from "../../../../systemSlice";
const UpdateTierCredentialsModal = withSuspense(
React.lazy(() => import("./UpdateTierCredentialsModal"))
@@ -63,8 +64,6 @@ const UpdateTierCredentialsModal = withSuspense(
interface IListTiersConfig {
classes: any;
history: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
distributedSetup: boolean;
}
const styles = (theme: Theme) =>
@@ -95,12 +94,11 @@ const styles = (theme: Theme) =>
...tableStyles,
});
const ListTiersConfiguration = ({
classes,
history,
setErrorSnackMessage,
distributedSetup,
}: IListTiersConfig) => {
const ListTiersConfiguration = ({ classes, history }: IListTiersConfig) => {
const dispatch = useDispatch();
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const [records, setRecords] = useState<ITierElement[]>([]);
const [filter, setFilter] = useState<string>("");
const [isLoading, setIsLoading] = useState<boolean>(true);
@@ -121,7 +119,7 @@ const ListTiersConfiguration = ({
setIsLoading(false);
})
.catch((err: ErrorResponseHandler) => {
setErrorSnackMessage(err);
dispatch(setErrorSnackMessage(err));
setIsLoading(false);
});
};
@@ -130,7 +128,7 @@ const ListTiersConfiguration = ({
setIsLoading(false);
}
}
}, [isLoading, setErrorSnackMessage, distributedSetup]);
}, [isLoading, dispatch, distributedSetup]);
const filteredRecords = records.filter((b: ITierElement) => {
if (filter === "") {
@@ -460,14 +458,4 @@ const ListTiersConfiguration = ({
);
};
const mapState = (state: AppState) => ({
distributedSetup: state.system.distributedSetup,
});
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(mapState, mapDispatchToProps);
export default withStyles(styles)(connector(ListTiersConfiguration));
export default withStyles(styles)(ListTiersConfiguration);

View File

@@ -16,7 +16,7 @@
import React, { Fragment, useEffect, useState } from "react";
import get from "lodash/get";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
@@ -26,7 +26,7 @@ import {
formFieldStyles,
modalBasic,
} from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector";
import api from "../../../../common/api";
@@ -34,13 +34,13 @@ import { ITierElement } from "./types";
import { ErrorResponseHandler } from "../../../../common/types";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import { LockIcon } from "../../../../icons";
import { setModalErrorSnackMessage } from "../../../../systemSlice";
interface ITierCredentialsModal {
open: boolean;
closeModalAndRefresh: (refresh: boolean) => any;
classes: any;
tierData: ITierElement;
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
}
const styles = (theme: Theme) =>
@@ -57,8 +57,8 @@ const UpdateTierCredentialsModal = ({
closeModalAndRefresh,
classes,
tierData,
setModalErrorSnackMessage,
}: ITierCredentialsModal) => {
const dispatch = useDispatch();
const [savingTiers, setSavingTiers] = useState<boolean>(false);
const [accessKey, setAccessKey] = useState<string>("");
const [secretKey, setSecretKey] = useState<string>("");
@@ -112,7 +112,7 @@ const UpdateTierCredentialsModal = ({
})
.catch((err: ErrorResponseHandler) => {
setSavingTiers(false);
setModalErrorSnackMessage(err);
dispatch(setModalErrorSnackMessage(err));
});
} else {
setModalErrorSnackMessage({
@@ -235,8 +235,4 @@ const UpdateTierCredentialsModal = ({
);
};
const connector = connect(null, {
setModalErrorSnackMessage,
});
export default withStyles(styles)(connector(UpdateTierCredentialsModal));
export default withStyles(styles)(UpdateTierCredentialsModal);

View File

@@ -16,13 +16,13 @@
import {
AzureTierIcon,
AzureTierIconXs,
GoogleTierIcon,
GoogleTierIconXs,
MinIOTierIcon,
MinIOTierIconXs,
S3TierIcon,
GoogleTierIconXs,
S3TierIconXs,
AzureTierIconXs,
} from "../../../../icons";
export const minioServiceName = "minio";

View File

@@ -18,8 +18,8 @@ import React, {
Fragment,
Suspense,
useEffect,
useState,
useLayoutEffect,
useState,
} from "react";
import { Theme } from "@mui/material/styles";
import debounce from "lodash/debounce";
@@ -30,16 +30,8 @@ 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 { connect } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { AppState } from "../../store";
import {
serverIsLoading,
serverNeedsRestart,
setMenuOpen,
setSnackBarMessage,
} from "../../actions";
import { ISessionResponse } from "./types";
import { snackBarMessage } from "../../types";
import { snackBarCommon } from "./Common/FormComponents/common/styleLibrary";
import { ErrorResponseHandler } from "../../common/types";
@@ -59,6 +51,12 @@ import { IRouteRule } from "./Menu/types";
import LoadingComponent from "../../common/LoadingComponent";
import EditPool from "./Tenants/TenantDetails/Pools/EditPool/EditPool";
import ComponentsScreen from "./Common/ComponentsScreen";
import {
menuOpen,
serverIsLoading,
setServerNeedsRestart,
setSnackBarMessage,
} from "../../systemSlice";
const Trace = React.lazy(() => import("./Trace/Trace"));
const Heal = React.lazy(() => import("./Heal/Heal"));
@@ -177,55 +175,52 @@ const styles = (theme: Theme) =>
});
interface IConsoleProps {
open: boolean;
needsRestart: boolean;
isServerLoading: boolean;
classes: any;
setMenuOpen: typeof setMenuOpen;
serverNeedsRestart: typeof serverNeedsRestart;
serverIsLoading: typeof serverIsLoading;
session: ISessionResponse;
loadingProgress: number;
snackBarMessage: snackBarMessage;
setSnackBarMessage: typeof setSnackBarMessage;
operatorMode: boolean;
distributedSetup: boolean;
features: string[] | null;
}
const Console = ({
classes,
open,
needsRestart,
isServerLoading,
serverNeedsRestart,
serverIsLoading,
session,
loadingProgress,
snackBarMessage,
setSnackBarMessage,
operatorMode,
distributedSetup,
features,
setMenuOpen,
}: IConsoleProps) => {
const Console = ({ classes }: IConsoleProps) => {
const dispatch = useDispatch();
const open = useSelector((state: AppState) => state.system.sidebarOpen);
const session = useSelector((state: AppState) => state.console.session);
const features = useSelector(
(state: AppState) => state.console.session.features
);
const distributedSetup = useSelector(
(state: AppState) => state.system.distributedSetup
);
const operatorMode = useSelector(
(state: AppState) => state.system.operatorMode
);
const snackBarMessage = useSelector(
(state: AppState) => state.system.snackBar
);
const needsRestart = useSelector(
(state: AppState) => state.system.serverNeedsRestart
);
const isServerLoading = useSelector(
(state: AppState) => state.system.serverIsLoading
);
const loadingProgress = useSelector(
(state: AppState) => state.system.loadingProgress
);
const [openSnackbar, setOpenSnackbar] = useState<boolean>(false);
const ldapIsEnabled = (features && features.includes("ldap-idp")) || false;
const restartServer = () => {
serverIsLoading(true);
dispatch(serverIsLoading(true));
api
.invoke("POST", "/api/v1/service/restart", {})
.then((res) => {
console.log("success restarting service");
serverIsLoading(false);
serverNeedsRestart(false);
dispatch(serverIsLoading(false));
dispatch(setServerNeedsRestart(false));
})
.catch((err: ErrorResponseHandler) => {
if (err.errorMessage === "Error 502") {
serverNeedsRestart(false);
dispatch(setServerNeedsRestart(false));
}
serverIsLoading(false);
dispatch(serverIsLoading(false));
console.log("failure restarting service");
console.error(err);
});
@@ -236,7 +231,7 @@ const Console = ({
// Debounce to not execute constantly
const debounceSize = debounce(() => {
if (open && window.innerWidth <= 800) {
setMenuOpen(false);
dispatch(menuOpen(false));
}
}, 300);
@@ -587,7 +582,7 @@ const Console = ({
const closeSnackBar = () => {
setOpenSnackbar(false);
setSnackBarMessage("");
dispatch(setSnackBarMessage(""));
};
useEffect(() => {
@@ -709,23 +704,4 @@ const Console = ({
);
};
const mapState = (state: AppState) => ({
open: state.system.sidebarOpen,
needsRestart: state.system.serverNeedsRestart,
isServerLoading: state.system.serverIsLoading,
session: state.console.session,
loadingProgress: state.system.loadingProgress,
snackBarMessage: state.system.snackBar,
operatorMode: state.system.operatorMode,
distributedSetup: state.system.distributedSetup,
features: state.console.session.features,
});
const connector = connect(mapState, {
setMenuOpen,
serverNeedsRestart,
serverIsLoading,
setSnackBarMessage,
});
export default withStyles(styles)(connector(Console));
export default withStyles(styles)(Console);

View File

@@ -17,10 +17,13 @@ import * as React from "react";
import { KBarProvider } from "kbar";
import Console from "./Console";
import { AppState } from "../../store";
import { connect } from "react-redux";
import { useSelector } from "react-redux";
import CommandBar from "./CommandBar";
const ConsoleKBar = ({ features }: { features: string[] | null }) => {
const ConsoleKBar = () => {
const features = useSelector(
(state: AppState) => state.console.session.features
);
// if we are hiding the menu also disable the k-bar so just return console
if (features?.includes("hide-menu")) {
return <Console />;
@@ -38,10 +41,4 @@ const ConsoleKBar = ({ features }: { features: string[] | null }) => {
);
};
const mapState = (state: AppState) => ({
features: state.console.session.features,
});
const connector = connect(mapState, null);
export default connector(ConsoleKBar);
export default ConsoleKBar;

View File

@@ -119,7 +119,8 @@ export const StatusCountCard = ({
},
}}
>
<CircleIcon /> <div className="stat-text">{okStatusText}</div>
<CircleIcon />
<div className="stat-text">{okStatusText}</div>
</Box>
</Box>

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useCallback, useEffect, useState } from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import get from "lodash/get";
import PrDashboard from "./Prometheus/PrDashboard";
import PageHeader from "../Common/PageHeader/PageHeader";
@@ -27,13 +27,13 @@ import withStyles from "@mui/styles/withStyles";
import { LinearProgress } from "@mui/material";
import api from "../../../common/api";
import { Usage } from "./types";
import { setErrorSnackMessage } from "../../../actions";
import { ErrorResponseHandler } from "../../../common/types";
import BasicDashboard from "./BasicDashboard/BasicDashboard";
import { setErrorSnackMessage } from "../../../systemSlice";
interface IDashboardSimple {
classes: any;
displayErrorMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
@@ -41,7 +41,8 @@ const styles = (theme: Theme) =>
...containerForHeader(theme.spacing(4)),
});
const Dashboard = ({ classes, displayErrorMessage }: IDashboardSimple) => {
const Dashboard = ({ classes }: IDashboardSimple) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [basicResult, setBasicResult] = useState<Usage | null>(null);
@@ -53,10 +54,10 @@ const Dashboard = ({ classes, displayErrorMessage }: IDashboardSimple) => {
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
displayErrorMessage(err);
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}, [setBasicResult, setLoading, displayErrorMessage]);
}, [setBasicResult, setLoading, dispatch]);
useEffect(() => {
if (loading) {
@@ -88,8 +89,4 @@ const Dashboard = ({ classes, displayErrorMessage }: IDashboardSimple) => {
);
};
const connector = connect(null, {
displayErrorMessage: setErrorSnackMessage,
});
export default withStyles(styles)(connector(Dashboard));
export default withStyles(styles)(Dashboard);

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useCallback, useEffect, useState } from "react";
import { connect } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import Grid from "@mui/material/Grid";
import { Theme } from "@mui/material/styles";
@@ -30,7 +30,6 @@ import { IDashboardPanel } from "./types";
import { getWidgetsWithValue, panelsConfiguration } from "./utils";
import { TabPanel } from "../../../shared/tabs";
import { ErrorResponseHandler } from "../../../../common/types";
import { setErrorSnackMessage } from "../../../../actions";
import api from "../../../../common/api";
import TabSelector from "../../Common/TabSelector/TabSelector";
@@ -48,13 +47,11 @@ import {
} from "./Widgets/LayoutUtil";
import MergedWidgetsRenderer from "./Widgets/MergedWidgetsRenderer";
import PageLayout from "../../Common/Layout/PageLayout";
import { setErrorSnackMessage } from "../../../../systemSlice";
interface IPrDashboard {
classes?: any;
displayErrorMessage: typeof setErrorSnackMessage;
apiPrefix?: string;
zoomOpen: boolean;
zoomWidget: null | IDashboardPanel;
}
const styles = (theme: Theme) =>
@@ -69,12 +66,15 @@ const styles = (theme: Theme) =>
},
});
const PrDashboard = ({
displayErrorMessage,
apiPrefix = "admin",
zoomOpen,
zoomWidget,
}: IPrDashboard) => {
const PrDashboard = ({ apiPrefix = "admin" }: IPrDashboard) => {
const dispatch = useDispatch();
const zoomOpen = useSelector(
(state: AppState) => state.dashboard.zoom.openZoom
);
const zoomWidget = useSelector(
(state: AppState) => state.dashboard.zoom.widgetRender
);
const [timeStart, setTimeStart] = useState<any>(null);
const [timeEnd, setTimeEnd] = useState<any>(null);
const [loading, setLoading] = useState<boolean>(true);
@@ -110,20 +110,22 @@ const PrDashboard = ({
const widgetsWithValue = getWidgetsWithValue(res.widgets);
setPanelInformation(widgetsWithValue);
} else {
displayErrorMessage({
errorMessage:
"Widget information could not be retrieved at this time. Please try again",
detailedError: "",
});
dispatch(
setErrorSnackMessage({
errorMessage:
"Widget information could not be retrieved at this time. Please try again",
detailedError: "",
})
);
}
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
displayErrorMessage(err);
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}, [timeStart, timeEnd, displayErrorMessage, apiPrefix]);
}, [timeStart, timeEnd, dispatch, apiPrefix]);
const triggerLoad = () => {
setLoading(true);
@@ -150,7 +152,6 @@ const PrDashboard = ({
timeEnd={timeEnd}
loading={loading}
apiPrefix={apiPrefix}
displayErrorMessage={displayErrorMessage}
/>
) : (
componentToUse(panelInfo, timeStart, timeEnd, loading, apiPrefix)
@@ -257,13 +258,4 @@ const PrDashboard = ({
);
};
const mapState = (state: AppState) => ({
zoomOpen: state.dashboard.zoom.openZoom,
zoomWidget: state.dashboard.zoom.widgetRender,
});
const connector = connect(mapState, {
displayErrorMessage: setErrorSnackMessage,
});
export default withStyles(styles)(connector(PrDashboard));
export default withStyles(styles)(PrDashboard);

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 } from "react-redux";
import { useDispatch } from "react-redux";
import {
Bar,
BarChart,
@@ -32,15 +32,15 @@ import withStyles from "@mui/styles/withStyles";
import { IBarChartConfiguration } from "./types";
import { widgetCommon } from "../../../Common/FormComponents/common/styleLibrary";
import BarChartTooltip from "./tooltips/BarChartTooltip";
import { setErrorSnackMessage } from "../../../../../actions";
import { IDashboardPanel } from "../types";
import { widgetDetailsToPanel } from "../utils";
import { ErrorResponseHandler } from "../../../../../common/types";
import api from "../../../../../common/api";
import { openZoomPage } from "../../actions";
import { useTheme } from "@mui/styles";
import Loader from "../../../Common/Loader/Loader";
import ExpandGraphLink from "./ExpandGraphLink";
import { setErrorSnackMessage } from "../../../../../systemSlice";
interface IBarChartWidget {
classes: any;
@@ -49,10 +49,8 @@ interface IBarChartWidget {
timeStart: any;
timeEnd: any;
propLoading: boolean;
displayErrorMessage: any;
apiPrefix: string;
zoomActivated?: boolean;
openZoomPage: typeof openZoomPage;
}
const styles = (theme: Theme) =>
@@ -89,10 +87,10 @@ const BarChartWidget = ({
timeStart,
timeEnd,
propLoading,
displayErrorMessage,
apiPrefix,
zoomActivated = false,
}: IBarChartWidget) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [data, setData] = useState<any>([]);
const [result, setResult] = useState<IDashboardPanel | null>(null);
@@ -131,11 +129,11 @@ const BarChartWidget = ({
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
displayErrorMessage(err);
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}
}, [loading, panelItem, timeEnd, timeStart, displayErrorMessage, apiPrefix]);
}, [loading, panelItem, timeEnd, timeStart, dispatch, apiPrefix]);
const barChartConfiguration = result
? (result.widgetConfiguration as IBarChartConfiguration[])
@@ -236,9 +234,4 @@ const BarChartWidget = ({
);
};
const connector = connect(null, {
displayErrorMessage: setErrorSnackMessage,
openZoomPage: openZoomPage,
});
export default withStyles(styles)(connector(BarChartWidget));
export default withStyles(styles)(BarChartWidget);

View File

@@ -20,12 +20,13 @@ import { Box } from "@mui/material";
import api from "../../../../../common/api";
import { widgetDetailsToPanel } from "../utils";
import { ErrorResponseHandler } from "../../../../../common/types";
import { connect } from "react-redux";
import { setErrorSnackMessage } from "../../../../../actions";
import { useDispatch } from "react-redux";
import { niceBytes } from "../../../../../common/utils";
import { Cell, Pie, PieChart } from "recharts";
import { ReportedUsageIcon } from "../../../../../icons";
import Loader from "../../../Common/Loader/Loader";
import { setErrorSnackMessage } from "../../../../../systemSlice";
const CapacityItem = ({
value,
@@ -33,15 +34,14 @@ const CapacityItem = ({
timeEnd,
propLoading,
apiPrefix,
displayErrorMessage,
}: {
value: IDashboardPanel;
timeStart: any;
timeEnd: any;
propLoading: boolean;
apiPrefix: string;
displayErrorMessage: any;
}) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [dataInner, setDataInner] = useState<Record<string, any>>([]);
const [result, setResult] = useState<IDashboardPanel | null>(null);
@@ -79,11 +79,11 @@ const CapacityItem = ({
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
displayErrorMessage(err);
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}
}, [loading, value, timeEnd, timeStart, displayErrorMessage, apiPrefix]);
}, [loading, value, timeEnd, timeStart, dispatch, apiPrefix]);
const [middleLabel, unitValue] = (result?.innerLabel || "").split(" ");
@@ -235,8 +235,4 @@ const CapacityItem = ({
);
};
const connector = connect(null, {
displayErrorMessage: setErrorSnackMessage,
});
export default connector(CapacityItem);
export default CapacityItem;

View File

@@ -20,7 +20,6 @@ import { Box } from "@mui/material";
import { CircleIcon, DrivesIcon, ServersIcon } from "../../../../../icons";
import DualStatCard from "./DualStatCard";
import { IDashboardPanel } from "../types";
import { setErrorSnackMessage } from "../../../../../actions";
const EntityStateItemRenderer = ({
info,
@@ -28,14 +27,12 @@ const EntityStateItemRenderer = ({
timeEnd,
loading,
apiPrefix,
displayErrorMessage,
}: {
info: IDashboardPanel;
timeStart: any;
timeEnd: any;
loading: boolean;
apiPrefix: string;
displayErrorMessage: typeof setErrorSnackMessage;
}) => {
const { mergedPanels = [], id } = info;
const [leftPanel, rightPanel] = mergedPanels;
@@ -46,7 +43,6 @@ const EntityStateItemRenderer = ({
timeStart={timeStart}
timeEnd={timeEnd}
propLoading={loading}
displayErrorMessage={displayErrorMessage}
apiPrefix={apiPrefix}
statLabel={
<Box
@@ -59,7 +55,8 @@ const EntityStateItemRenderer = ({
},
}}
>
<CircleIcon /> <div className="stat-text">Online</div>
<CircleIcon />
<div className="stat-text">Online</div>
</Box>
}
/>
@@ -70,7 +67,6 @@ const EntityStateItemRenderer = ({
timeStart={timeStart}
timeEnd={timeEnd}
propLoading={loading}
displayErrorMessage={displayErrorMessage}
apiPrefix={apiPrefix}
statLabel={
<Box
@@ -83,7 +79,8 @@ const EntityStateItemRenderer = ({
},
}}
>
<CircleIcon /> <div className="stat-text">Offline</div>
<CircleIcon />
<div className="stat-text">Offline</div>
</Box>
}
/>

View File

@@ -21,13 +21,14 @@ import { widgetDetailsToPanel } from "../utils";
import { ErrorResponseHandler } from "../../../../../common/types";
import { IDashboardPanel } from "../types";
import Loader from "../../../Common/Loader/Loader";
import { useDispatch } from "react-redux";
import { setErrorSnackMessage } from "../../../../../systemSlice";
const EntityStateStatItem = ({
panelItem,
timeStart,
timeEnd,
propLoading,
displayErrorMessage,
apiPrefix,
statLabel,
}: {
@@ -35,10 +36,10 @@ const EntityStateStatItem = ({
timeStart: any;
timeEnd: any;
propLoading: boolean;
displayErrorMessage: any;
apiPrefix: string;
statLabel: any;
}) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [data, setData] = useState<string>("");
@@ -75,11 +76,11 @@ const EntityStateStatItem = ({
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
displayErrorMessage(err);
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}
}, [loading, panelItem, timeEnd, timeStart, displayErrorMessage, apiPrefix]);
}, [loading, panelItem, timeEnd, timeStart, dispatch, apiPrefix]);
let toRender = loading ? (
<Box

View File

@@ -17,17 +17,12 @@
import React from "react";
import ZoomOutMapIcon from "@mui/icons-material/ZoomOutMap";
import { Box } from "@mui/material";
import { openZoomPage } from "../../actions";
import { IDashboardPanel } from "../types";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { openZoomPage } from "../../dashboardSlice";
const ExpandGraphLink = ({
panelItem,
openZoomPage,
}: {
panelItem: IDashboardPanel;
openZoomPage: (p: IDashboardPanel) => void;
}) => {
const ExpandGraphLink = ({ panelItem }: { panelItem: IDashboardPanel }) => {
const dispatch = useDispatch();
return (
<Box
sx={{
@@ -63,14 +58,14 @@ const ExpandGraphLink = ({
className={"link-text"}
onClick={(e) => {
e.preventDefault();
openZoomPage(panelItem);
dispatch(openZoomPage(panelItem));
}}
>
Expand Graph
</a>
<button
onClick={() => {
openZoomPage(panelItem);
dispatch(openZoomPage(panelItem));
}}
className={"zoom-graph-icon"}
>
@@ -80,8 +75,4 @@ const ExpandGraphLink = ({
);
};
const connector = connect(null, {
openZoomPage: openZoomPage,
});
export default connector(ExpandGraphLink);
export default ExpandGraphLink;

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 } from "react-redux";
import { useDispatch } from "react-redux";
import {
Area,
AreaChart,
@@ -32,7 +32,7 @@ import withStyles from "@mui/styles/withStyles";
import { ILinearGraphConfiguration } from "./types";
import { widgetCommon } from "../../../Common/FormComponents/common/styleLibrary";
import { IDashboardPanel } from "../types";
import { setErrorSnackMessage } from "../../../../../actions";
import { widgetDetailsToPanel } from "../utils";
import { ErrorResponseHandler } from "../../../../../common/types";
import api from "../../../../../common/api";
@@ -40,6 +40,7 @@ import LineChartTooltip from "./tooltips/LineChartTooltip";
import { useTheme } from "@mui/styles";
import Loader from "../../../Common/Loader/Loader";
import ExpandGraphLink from "./ExpandGraphLink";
import { setErrorSnackMessage } from "../../../../../systemSlice";
interface ILinearGraphWidget {
classes: any;
@@ -48,7 +49,7 @@ interface ILinearGraphWidget {
timeStart: any;
timeEnd: any;
propLoading: boolean;
displayErrorMessage: any;
apiPrefix: string;
hideYAxis?: boolean;
yAxisFormatter?: (item: string) => string;
@@ -94,7 +95,7 @@ const styles = (theme: Theme) =>
const LinearGraphWidget = ({
classes,
title,
displayErrorMessage,
timeStart,
timeEnd,
propLoading,
@@ -106,6 +107,7 @@ const LinearGraphWidget = ({
xAxisFormatter = (item: string) => item,
zoomActivated = false,
}: ILinearGraphWidget) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [data, setData] = useState<object[]>([]);
const [dataMax, setDataMax] = useState<number>(0);
@@ -163,11 +165,11 @@ const LinearGraphWidget = ({
setDataMax(maxVal);
})
.catch((err: ErrorResponseHandler) => {
displayErrorMessage(err);
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}
}, [loading, panelItem, timeEnd, timeStart, displayErrorMessage, apiPrefix]);
}, [loading, panelItem, timeEnd, timeStart, dispatch, apiPrefix]);
let intervalCount = Math.floor(data.length / 5);
@@ -344,8 +346,4 @@ const LinearGraphWidget = ({
);
};
const connector = connect(null, {
displayErrorMessage: setErrorSnackMessage,
});
export default withStyles(styles)(connector(LinearGraphWidget));
export default withStyles(styles)(LinearGraphWidget);

View File

@@ -18,7 +18,6 @@ import React from "react";
import { componentToUse } from "../widgetUtils";
import MergedWidgets from "../MergedWidgets";
import { IDashboardPanel } from "../types";
import { setErrorSnackMessage } from "../../../../../actions";
import EntityStateItemRenderer from "./EntityStateItemRenderer";
import NetworkItem from "./NetworkItem";
import DashboardItemBox from "../../DashboardItemBox";
@@ -29,14 +28,12 @@ const MergedWidgetsRenderer = ({
timeEnd,
loading,
apiPrefix,
displayErrorMessage,
}: {
info: IDashboardPanel;
timeStart: any;
timeEnd: any;
loading: boolean;
apiPrefix: string;
displayErrorMessage: typeof setErrorSnackMessage;
}) => {
const { mergedPanels = [], title = "", id } = info;
const [leftPanel, rightPanel] = mergedPanels;
@@ -50,7 +47,6 @@ const MergedWidgetsRenderer = ({
timeStart={timeStart}
timeEnd={timeEnd}
loading={loading}
displayErrorMessage={displayErrorMessage}
apiPrefix={apiPrefix}
/>
</DashboardItemBox>

View File

@@ -15,20 +15,21 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { useDispatch } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Cell, Pie, PieChart, ResponsiveContainer } from "recharts";
import { IPieChartConfiguration } from "./types";
import { widgetCommon } from "../../../Common/FormComponents/common/styleLibrary";
import { setErrorSnackMessage } from "../../../../../actions";
import { IDashboardPanel } from "../types";
import { splitSizeMetric, widgetDetailsToPanel } from "../utils";
import { ErrorResponseHandler } from "../../../../../common/types";
import get from "lodash/get";
import api from "../../../../../common/api";
import Loader from "../../../Common/Loader/Loader";
import { setErrorSnackMessage } from "../../../../../systemSlice";
interface IPieChartWidget {
classes: any;
@@ -37,7 +38,7 @@ interface IPieChartWidget {
timeStart: any;
timeEnd: any;
propLoading: boolean;
displayErrorMessage: any;
apiPrefix: string;
}
@@ -73,9 +74,10 @@ const PieChartWidget = ({
timeStart,
timeEnd,
propLoading,
displayErrorMessage,
apiPrefix,
}: IPieChartWidget) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [dataInner, setDataInner] = useState<object[]>([]);
const [dataOuter, setDataOuter] = useState<object[]>([]);
@@ -116,11 +118,11 @@ const PieChartWidget = ({
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
displayErrorMessage(err);
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}
}, [loading, panelItem, timeEnd, timeStart, displayErrorMessage, apiPrefix]);
}, [loading, panelItem, timeEnd, timeStart, dispatch, apiPrefix]);
const pieChartConfiguration = result
? (result.widgetConfiguration as IPieChartConfiguration)
@@ -237,8 +239,4 @@ const PieChartWidget = ({
);
};
const connector = connect(null, {
displayErrorMessage: setErrorSnackMessage,
});
export default withStyles(styles)(connector(PieChartWidget));
export default withStyles(styles)(PieChartWidget);

Some files were not shown because too many files have changed in this diff Show More