Display Retention Policy details inside bucket details (#905)
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.8cfac526.chunk.css",
|
||||
"main.js": "/static/js/main.dd8abda8.chunk.js",
|
||||
"main.js.map": "/static/js/main.dd8abda8.chunk.js.map",
|
||||
"main.js": "/static/js/main.d02553d5.chunk.js",
|
||||
"main.js.map": "/static/js/main.d02553d5.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.43a31377.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.43a31377.js.map",
|
||||
"static/css/2.60e04a19.chunk.css": "/static/css/2.60e04a19.chunk.css",
|
||||
"static/js/2.fdaf1119.chunk.js": "/static/js/2.fdaf1119.chunk.js",
|
||||
"static/js/2.fdaf1119.chunk.js.map": "/static/js/2.fdaf1119.chunk.js.map",
|
||||
"static/js/2.a3d22cff.chunk.js": "/static/js/2.a3d22cff.chunk.js",
|
||||
"static/js/2.a3d22cff.chunk.js.map": "/static/js/2.a3d22cff.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/css/2.60e04a19.chunk.css.map": "/static/css/2.60e04a19.chunk.css.map",
|
||||
"static/css/main.8cfac526.chunk.css.map": "/static/css/main.8cfac526.chunk.css.map",
|
||||
"static/js/2.fdaf1119.chunk.js.LICENSE.txt": "/static/js/2.fdaf1119.chunk.js.LICENSE.txt",
|
||||
"static/js/2.a3d22cff.chunk.js.LICENSE.txt": "/static/js/2.a3d22cff.chunk.js.LICENSE.txt",
|
||||
"static/media/minio_console_logo.0837460e.svg": "/static/media/minio_console_logo.0837460e.svg",
|
||||
"static/media/minio_operator_logo.1312b7c9.svg": "/static/media/minio_operator_logo.1312b7c9.svg"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.43a31377.js",
|
||||
"static/css/2.60e04a19.chunk.css",
|
||||
"static/js/2.fdaf1119.chunk.js",
|
||||
"static/js/2.a3d22cff.chunk.js",
|
||||
"static/css/main.8cfac526.chunk.css",
|
||||
"static/js/main.dd8abda8.chunk.js"
|
||||
"static/js/main.d02553d5.chunk.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link href="/styles/root-styles.css" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.60e04a19.chunk.css" rel="stylesheet"><link href="/static/css/main.8cfac526.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></div></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.fdaf1119.chunk.js"></script><script src="/static/js/main.dd8abda8.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link href="/styles/root-styles.css" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.60e04a19.chunk.css" rel="stylesheet"><link href="/static/css/main.8cfac526.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></div></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.a3d22cff.chunk.js"></script><script src="/static/js/main.d02553d5.chunk.js"></script></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
portal-ui/build/static/js/main.d02553d5.chunk.js
Normal file
2
portal-ui/build/static/js/main.d02553d5.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
portal-ui/build/static/js/main.d02553d5.chunk.js.map
Normal file
1
portal-ui/build/static/js/main.d02553d5.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -383,3 +383,9 @@ export interface ErrorResponseHandler {
|
||||
errorMessage: string;
|
||||
detailedError: string;
|
||||
}
|
||||
|
||||
export interface IRetentionConfig {
|
||||
mode: string;
|
||||
unit: string;
|
||||
validity: number;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,10 @@ import {
|
||||
buttonsStyles,
|
||||
hrClass,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import {
|
||||
ErrorResponseHandler,
|
||||
IRetentionConfig,
|
||||
} from "../../../../common/types";
|
||||
import api from "../../../../common/api";
|
||||
import SetAccessPolicy from "./SetAccessPolicy";
|
||||
import SetRetentionConfig from "./SetRetentionConfig";
|
||||
@@ -82,6 +85,12 @@ const styles = (theme: Theme) =>
|
||||
dualCardRight: {
|
||||
paddingLeft: "5px",
|
||||
},
|
||||
capitalizeFirst: {
|
||||
textTransform: "capitalize",
|
||||
},
|
||||
titleCol: {
|
||||
width: "25%",
|
||||
},
|
||||
...hrClass,
|
||||
...buttonsStyles,
|
||||
});
|
||||
@@ -107,10 +116,14 @@ const BucketSummary = ({
|
||||
const [loadingVersioning, setLoadingVersioning] = useState<boolean>(true);
|
||||
const [loadingQuota, setLoadingQuota] = useState<boolean>(true);
|
||||
const [loadingReplication, setLoadingReplication] = useState<boolean>(true);
|
||||
const [loadingRetention, setLoadingRetention] = useState<boolean>(true);
|
||||
const [isVersioned, setIsVersioned] = useState<boolean>(false);
|
||||
const [quotaEnabled, setQuotaEnabled] = useState<boolean>(false);
|
||||
const [quota, setQuota] = useState<BucketQuota | null>(null);
|
||||
const [encryptionEnabled, setEncryptionEnabled] = useState<boolean>(false);
|
||||
const [retentionEnabled, setRetentionEnabled] = useState<boolean>(false);
|
||||
const [retentionConfig, setRetentionConfig] =
|
||||
useState<IRetentionConfig | null>(null);
|
||||
const [retentionConfigOpen, setRetentionConfigOpen] =
|
||||
useState<boolean>(false);
|
||||
const [enableEncryptionScreenOpen, setEnableEncryptionScreenOpen] =
|
||||
@@ -270,11 +283,29 @@ const BucketSummary = ({
|
||||
}
|
||||
}, [loadingReplication, setErrorSnackMessage, bucketName, distributedSetup]);
|
||||
|
||||
useEffect(() => {
|
||||
if (loadingRetention && hasObjectLocking) {
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets/${bucketName}/retention`)
|
||||
.then((res: IRetentionConfig) => {
|
||||
setLoadingRetention(false);
|
||||
setRetentionEnabled(true);
|
||||
setRetentionConfig(res);
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
setRetentionEnabled(false);
|
||||
setLoadingRetention(false);
|
||||
setRetentionConfig(null);
|
||||
});
|
||||
}
|
||||
}, [loadingRetention, hasObjectLocking, bucketName]);
|
||||
|
||||
const loadAllBucketData = () => {
|
||||
setLoadingBucket(true);
|
||||
setLoadingSize(true);
|
||||
setLoadingVersioning(true);
|
||||
setLoadingEncryption(true);
|
||||
setLoadingRetention(true);
|
||||
};
|
||||
|
||||
const setBucketVersioning = () => {
|
||||
@@ -396,7 +427,7 @@ const BucketSummary = ({
|
||||
</td>
|
||||
</tr>
|
||||
{distributedSetup && (
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<tr>
|
||||
<td className={classes.titleCol}>Replication:</td>
|
||||
<td className={classes.doubleElement}>
|
||||
@@ -404,14 +435,10 @@ const BucketSummary = ({
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
{!hasObjectLocking && (
|
||||
<React.Fragment>
|
||||
<td className={classes.titleCol}>Object Locking:</td>
|
||||
<td>Disabled</td>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<td className={classes.titleCol}>Object Locking:</td>
|
||||
<td>{!hasObjectLocking ? "Disabled" : "Enabled"}</td>
|
||||
</tr>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
)}
|
||||
<tr>
|
||||
<td className={classes.titleCol}>Encryption:</td>
|
||||
@@ -539,14 +566,14 @@ const BucketSummary = ({
|
||||
<Paper className={classes.paperContainer}>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<h2>Object Locking</h2>
|
||||
<h2>Retention</h2>
|
||||
<hr className={classes.hrClass} />
|
||||
<table>
|
||||
<table width={"100%"}>
|
||||
<tbody>
|
||||
<tr className={classes.gridContainer}>
|
||||
<td className={classes.titleCol}>Retention:</td>
|
||||
<td className={classes.titleCol}>Status:</td>
|
||||
<td>
|
||||
{loadingVersioning ? (
|
||||
{loadingRetention ? (
|
||||
<CircularProgress
|
||||
color="primary"
|
||||
size={16}
|
||||
@@ -561,11 +588,37 @@ const BucketSummary = ({
|
||||
setRetentionConfigOpen(true);
|
||||
}}
|
||||
>
|
||||
Configure
|
||||
{!retentionEnabled ? "Disabled" : "Enabled"}
|
||||
</Button>
|
||||
</Fragment>
|
||||
)}
|
||||
</td>
|
||||
{retentionConfig === null ? (
|
||||
<td colSpan={2}> </td>
|
||||
) : (
|
||||
<Fragment>
|
||||
<td className={classes.titleCol}>Mode:</td>
|
||||
<td className={classes.capitalizeFirst}>
|
||||
{retentionConfig && retentionConfig.mode}
|
||||
</td>
|
||||
</Fragment>
|
||||
)}
|
||||
</tr>
|
||||
<tr className={classes.gridContainer}>
|
||||
{retentionConfig === null ? (
|
||||
<td colSpan={2}></td>
|
||||
) : (
|
||||
<Fragment>
|
||||
<td className={classes.titleCol}>Valitidy:</td>
|
||||
<td className={classes.capitalizeFirst}>
|
||||
{retentionConfig && retentionConfig.validity}{" "}
|
||||
{retentionConfig &&
|
||||
(retentionConfig.validity === 1
|
||||
? retentionConfig.unit.slice(0, -1)
|
||||
: retentionConfig.unit)}
|
||||
</td>
|
||||
</Fragment>
|
||||
)}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
import { Button, LinearProgress, CircularProgress } from "@material-ui/core";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import { setModalErrorSnackMessage } from "../../../../actions";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import {
|
||||
ErrorResponseHandler,
|
||||
IRetentionConfig,
|
||||
} from "../../../../common/types";
|
||||
import api from "../../../../common/api";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
@@ -48,6 +51,7 @@ const SetRetentionConfig = ({
|
||||
setModalErrorSnackMessage,
|
||||
}: ISetRetentionConfigProps) => {
|
||||
const [addLoading, setAddLoading] = useState<boolean>(false);
|
||||
const [loadingForm, setLoadingForm] = useState<boolean>(true);
|
||||
const [retentionMode, setRetentionMode] = useState<string>("compliance");
|
||||
const [retentionUnit, setRetentionUnit] = useState<string>("days");
|
||||
const [retentionValidity, setRetentionValidity] = useState<number>(1);
|
||||
@@ -83,6 +87,24 @@ const SetRetentionConfig = ({
|
||||
setValid(true);
|
||||
}, [retentionValidity]);
|
||||
|
||||
useEffect(() => {
|
||||
if (loadingForm) {
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets/${bucketName}/retention`)
|
||||
.then((res: IRetentionConfig) => {
|
||||
setLoadingForm(false);
|
||||
|
||||
// We set default values
|
||||
setRetentionMode(res.mode);
|
||||
setRetentionValidity(res.validity);
|
||||
setRetentionUnit(res.unit);
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
setLoadingForm(false);
|
||||
});
|
||||
}
|
||||
}, [loadingForm, bucketName]);
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
title="Set Retention Configuration"
|
||||
@@ -91,78 +113,82 @@ const SetRetentionConfig = ({
|
||||
closeModalAndRefresh();
|
||||
}}
|
||||
>
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
setRetention(e);
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
<Grid item xs={12}>
|
||||
<RadioGroupSelector
|
||||
currentSelection={retentionMode}
|
||||
id="retention_mode"
|
||||
name="retention_mode"
|
||||
label="Retention Mode"
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
setRetentionMode(e.target.value as string);
|
||||
}}
|
||||
selectorOptions={[
|
||||
{ value: "compliance", label: "Compliance" },
|
||||
{ value: "governance", label: "Governance" },
|
||||
]}
|
||||
/>
|
||||
{loadingForm ? (
|
||||
<CircularProgress color="primary" size={16} variant="indeterminate" />
|
||||
) : (
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
setRetention(e);
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
<Grid item xs={12}>
|
||||
<RadioGroupSelector
|
||||
currentSelection={retentionMode}
|
||||
id="retention_mode"
|
||||
name="retention_mode"
|
||||
label="Retention Mode"
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
setRetentionMode(e.target.value as string);
|
||||
}}
|
||||
selectorOptions={[
|
||||
{ value: "compliance", label: "Compliance" },
|
||||
{ value: "governance", label: "Governance" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<RadioGroupSelector
|
||||
currentSelection={retentionUnit}
|
||||
id="retention_unit"
|
||||
name="retention_unit"
|
||||
label="Retention Unit"
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
setRetentionUnit(e.target.value as string);
|
||||
}}
|
||||
selectorOptions={[
|
||||
{ value: "days", label: "Days" },
|
||||
{ value: "years", label: "Years" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="retention_validity"
|
||||
name="retention_validity"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setRetentionValidity(e.target.valueAsNumber);
|
||||
}}
|
||||
label="Retention Validity"
|
||||
value={String(retentionValidity)}
|
||||
required
|
||||
min="1"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<RadioGroupSelector
|
||||
currentSelection={retentionUnit}
|
||||
id="retention_unit"
|
||||
name="retention_unit"
|
||||
label="Retention Unit"
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
setRetentionUnit(e.target.value as string);
|
||||
}}
|
||||
selectorOptions={[
|
||||
{ value: "days", label: "Days" },
|
||||
{ value: "years", label: "Years" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="retention_validity"
|
||||
name="retention_validity"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setRetentionValidity(e.target.valueAsNumber);
|
||||
}}
|
||||
label="Retention Validity"
|
||||
value={String(retentionValidity)}
|
||||
required
|
||||
min="1"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
fullWidth
|
||||
disabled={addLoading || !valid}
|
||||
>
|
||||
Set
|
||||
</Button>
|
||||
</Grid>
|
||||
{addLoading && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
fullWidth
|
||||
disabled={addLoading || !valid}
|
||||
>
|
||||
Set
|
||||
</Button>
|
||||
</Grid>
|
||||
{addLoading && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</form>
|
||||
</form>
|
||||
)}
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user