Files
object-browser/portal-ui/src/screens/Console/Configurations/TiersConfiguration/AddTierConfiguration.tsx

432 lines
12 KiB
TypeScript

// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { connect } from "react-redux";
import Grid from "@material-ui/core/Grid";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button } from "@material-ui/core";
import api from "../../../../common/api";
import { setErrorSnackMessage } from "../../../../actions";
import {
modalBasic,
settingsCommon,
} from "../../Common/FormComponents/common/styleLibrary";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector";
const styles = (theme: Theme) =>
createStyles({
...modalBasic,
...settingsCommon,
strongText: {
fontWeight: 700,
},
keyName: {
marginLeft: 5,
},
buttonContainer: {
textAlign: "right",
},
customTitle: {
...settingsCommon.customTitle,
marginTop: 0,
},
settingsFormContainer: {
...settingsCommon.settingsFormContainer,
height: "calc(100vh - 422px)",
},
});
interface IAddNotificationEndpointProps {
saveAndRefresh: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
classes: any;
type: string;
}
const AddTierConfiguration = ({
saveAndRefresh,
classes,
setErrorSnackMessage,
type,
}: IAddNotificationEndpointProps) => {
//Local States
const [saving, setSaving] = useState<boolean>(false);
// Form Items
const [name, setName] = useState<string>("");
const [endpoint, setEndpoint] = useState<string>("");
const [bucket, setBucket] = useState<string>("");
const [prefix, setPrefix] = useState<string>("");
const [region, setRegion] = useState<string>("");
const [storageClass, setStorageClass] = useState<string>("");
const [accessKey, setAccessKey] = useState<string>("");
const [secretKey, setSecretKey] = useState<string>("");
const [creds, setCreds] = useState<string>("");
const [encodedCreds, setEncodedCreds] = useState<string>("");
const [accountName, setAccountName] = useState<string>("");
const [accountKey, setAccountKey] = useState<string>("");
const [titleSelection, setTitleSelection] = useState<string>("");
// Validations
const [isFormValid, setIsFormValid] = useState<boolean>(true);
//Effects
useEffect(() => {
if (saving) {
let request = {};
let fields = {
name,
endpoint,
bucket,
prefix,
region,
};
let tierType = type;
if (type === "minio") {
tierType = "s3";
}
switch (type) {
case "minio":
case "s3":
request = {
s3: {
...fields,
accesskey: accessKey,
secretkey: secretKey,
storageclass: storageClass,
},
};
break;
case "gcs":
request = {
gcs: {
...fields,
creds: encodedCreds,
},
};
break;
case "azure":
request = {
azure: {
...fields,
accountname: accountName,
accountkey: accountKey,
},
};
}
let payload = {
type: tierType,
...request,
};
api
.invoke("POST", `/api/v1/admin/tiers`, payload)
.then(() => {
setSaving(false);
saveAndRefresh();
})
.catch((err) => {
setSaving(false);
setErrorSnackMessage(err);
});
}
}, [
accessKey,
accountKey,
accountName,
bucket,
encodedCreds,
endpoint,
name,
prefix,
region,
saveAndRefresh,
saving,
secretKey,
setErrorSnackMessage,
storageClass,
type,
]);
useEffect(() => {
let valid = true;
if (type === "") {
valid = false;
}
if (type === "") {
valid = false;
}
if (name === "") {
valid = false;
}
if (endpoint === "") {
valid = false;
}
if (bucket === "") {
valid = false;
}
if (prefix === "") {
valid = false;
}
if (region === "") {
valid = false;
}
if (type === "s3" || type === "minio") {
if (accessKey === "") {
valid = false;
}
if (secretKey === "") {
valid = false;
}
}
if (type === "gcs") {
if (encodedCreds === "") {
valid = false;
}
}
if (type === "azure") {
if (accountName === "") {
valid = false;
}
if (accountKey === "") {
valid = false;
}
}
setIsFormValid(valid);
}, [
accessKey,
accountKey,
accountName,
bucket,
encodedCreds,
endpoint,
isFormValid,
name,
prefix,
region,
secretKey,
storageClass,
type,
]);
useEffect(() => {
switch (type) {
case "gcs":
setEndpoint("https://storage.googleapis.com/");
setTitleSelection("Google Cloud");
break;
case "s3":
setEndpoint("https://s3.amazonaws.com");
setTitleSelection("Amazon S3");
break;
case "azure":
setEndpoint("http://blob.core.windows.net");
setTitleSelection("Azure");
break;
case "minio":
setEndpoint("");
setTitleSelection("MinIO");
}
}, [type]);
//Fetch Actions
const submitForm = (event: React.FormEvent) => {
event.preventDefault();
setSaving(true);
};
return (
<Fragment>
<form noValidate onSubmit={submitForm}>
<Grid item xs={12} className={classes.customTitle}>
{titleSelection} - Add Tier Configuration
</Grid>
<Grid item xs={12} className={classes.settingsFormContainer}>
<Grid container>
{type !== "" && (
<Fragment>
<InputBoxWrapper
id="name"
name="name"
label="Name"
placeholder="Enter Name"
value={name}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setName(e.target.value);
}}
/>
<InputBoxWrapper
id="endpoint"
name="endpoint"
label="Endpoint"
placeholder="Enter Endpoint"
value={endpoint}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setEndpoint(e.target.value);
}}
/>
{type === "s3" ||
(type === "minio" && (
<Fragment>
<InputBoxWrapper
id="accessKey"
name="accessKey"
label="Access Key"
placeholder="Enter Access Key"
value={accessKey}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setAccessKey(e.target.value);
}}
/>
<InputBoxWrapper
id="secretKey"
name="secretKey"
label="Secret Key"
placeholder="Enter Secret Key"
value={secretKey}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setSecretKey(e.target.value);
}}
/>
</Fragment>
))}
{type === "gcs" && (
<Fragment>
<FileSelector
accept=".json"
id="creds"
label="Credentials"
name="creds"
onChange={(encodedValue, fileName) => {
setEncodedCreds(encodedValue);
setCreds(fileName);
}}
value={creds}
/>
</Fragment>
)}
{type === "azure" && (
<Fragment>
<InputBoxWrapper
id="accountName"
name="accountName"
label="Account Name"
placeholder="Enter Account Name"
value={accountName}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setAccountName(e.target.value);
}}
/>
<InputBoxWrapper
id="accountKey"
name="accountKey"
label="Account Key"
placeholder="Enter Account Key"
value={accountKey}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setAccountKey(e.target.value);
}}
/>
</Fragment>
)}
<InputBoxWrapper
id="bucket"
name="bucket"
label="Bucket"
placeholder="Enter Bucket"
value={bucket}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setBucket(e.target.value);
}}
/>
<InputBoxWrapper
id="prefix"
name="prefix"
label="Prefix"
placeholder="Enter Prefix"
value={prefix}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setPrefix(e.target.value);
}}
/>
<InputBoxWrapper
id="region"
name="region"
label="Region"
placeholder="Enter Region"
value={region}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setRegion(e.target.value);
}}
/>
{type === "s3" ||
(type === "minio" && (
<InputBoxWrapper
id="storageClass"
name="storageClass"
label="Storage Class"
placeholder="Enter Storage Class"
value={storageClass}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setStorageClass(e.target.value);
}}
/>
))}
</Fragment>
)}
</Grid>
</Grid>
<Grid item xs={12} className={classes.settingsButtonContainer}>
<Grid item xs={12} className={classes.innerSettingsButtonContainer}>
<Button
type="submit"
variant="contained"
color="primary"
disabled={saving || !isFormValid}
>
Save
</Button>
</Grid>
</Grid>
</form>
</Fragment>
);
};
const mapDispatchToProps = {
setErrorSnackMessage,
};
const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(AddTierConfiguration));