Added loading validation to avoid flashing empty components (#1177)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net> Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -168,31 +168,33 @@ const BucketEventsPanel = ({
|
|||||||
customPaperHeight={classes.twHeight}
|
customPaperHeight={classes.twHeight}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
{!loadingEvents && (
|
||||||
<HelpBox
|
<Grid item xs={12}>
|
||||||
title={"Lambda Notifications"}
|
<HelpBox
|
||||||
iconComponent={<LambdaIcon />}
|
title={"Lambda Notifications"}
|
||||||
help={
|
iconComponent={<LambdaIcon />}
|
||||||
<Fragment>
|
help={
|
||||||
MinIO bucket notifications allow administrators to send
|
<Fragment>
|
||||||
notifications to supported external services on certain object
|
MinIO bucket notifications allow administrators to send
|
||||||
or bucket events. MinIO supports bucket and object-level S3
|
notifications to supported external services on certain object
|
||||||
events similar to the Amazon S3 Event Notifications.
|
or bucket events. MinIO supports bucket and object-level S3
|
||||||
<br />
|
events similar to the Amazon S3 Event Notifications.
|
||||||
<br />
|
<br />
|
||||||
You can learn more at our{" "}
|
<br />
|
||||||
<a
|
You can learn more at our{" "}
|
||||||
href="https://docs.min.io/minio/baremetal/monitoring/bucket-notifications/bucket-notifications.html?ref=con"
|
<a
|
||||||
target="_blank"
|
href="https://docs.min.io/minio/baremetal/monitoring/bucket-notifications/bucket-notifications.html?ref=con"
|
||||||
rel="noreferrer"
|
target="_blank"
|
||||||
>
|
rel="noreferrer"
|
||||||
documentation
|
>
|
||||||
</a>
|
documentation
|
||||||
.
|
</a>
|
||||||
</Fragment>
|
.
|
||||||
}
|
</Fragment>
|
||||||
/>
|
}
|
||||||
</Grid>
|
/>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -208,31 +208,33 @@ const BucketLifecyclePanel = ({
|
|||||||
customPaperHeight={classes.twHeight}
|
customPaperHeight={classes.twHeight}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
{!loadingLifecycle && (
|
||||||
<HelpBox
|
<Grid item xs={12}>
|
||||||
title={"Lifecycle Rules"}
|
<HelpBox
|
||||||
iconComponent={<TiersIcon />}
|
title={"Lifecycle Rules"}
|
||||||
help={
|
iconComponent={<TiersIcon />}
|
||||||
<Fragment>
|
help={
|
||||||
MinIO Object Lifecycle Management allows creating rules for time
|
<Fragment>
|
||||||
or date based automatic transition or expiry of objects. For
|
MinIO Object Lifecycle Management allows creating rules for
|
||||||
object transition, MinIO automatically moves the object to a
|
time or date based automatic transition or expiry of objects.
|
||||||
configured remote storage tier.
|
For object transition, MinIO automatically moves the object to
|
||||||
<br />
|
a configured remote storage tier.
|
||||||
<br />
|
<br />
|
||||||
You can learn more at our{" "}
|
<br />
|
||||||
<a
|
You can learn more at our{" "}
|
||||||
href="https://docs.min.io/minio/baremetal/lifecycle-management/lifecycle-management-overview.html?ref=con"
|
<a
|
||||||
target="_blank"
|
href="https://docs.min.io/minio/baremetal/lifecycle-management/lifecycle-management-overview.html?ref=con"
|
||||||
rel="noreferrer"
|
target="_blank"
|
||||||
>
|
rel="noreferrer"
|
||||||
documentation
|
>
|
||||||
</a>
|
documentation
|
||||||
.
|
</a>
|
||||||
</Fragment>
|
.
|
||||||
}
|
</Fragment>
|
||||||
/>
|
}
|
||||||
</Grid>
|
/>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { connect } from "react-redux";
|
|||||||
import { Theme } from "@mui/material/styles";
|
import { Theme } from "@mui/material/styles";
|
||||||
import createStyles from "@mui/styles/createStyles";
|
import createStyles from "@mui/styles/createStyles";
|
||||||
import withStyles from "@mui/styles/withStyles";
|
import withStyles from "@mui/styles/withStyles";
|
||||||
import { Box, Button } from "@mui/material";
|
import { Box, Button, LinearProgress } from "@mui/material";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import InputAdornment from "@mui/material/InputAdornment";
|
import InputAdornment from "@mui/material/InputAdornment";
|
||||||
@@ -28,13 +28,12 @@ import { Bucket, BucketList, HasPermissionResponse } from "../types";
|
|||||||
import {
|
import {
|
||||||
AddIcon,
|
AddIcon,
|
||||||
BucketsIcon,
|
BucketsIcon,
|
||||||
TenantsIcon,
|
|
||||||
WatchIcon,
|
WatchIcon,
|
||||||
} from "../../../../icons";
|
} from "../../../../icons";
|
||||||
import { AppState } from "../../../../store";
|
import { AppState } from "../../../../store";
|
||||||
import { addBucketOpen, addBucketReset } from "../actions";
|
import { addBucketOpen, addBucketReset } from "../actions";
|
||||||
import { setErrorSnackMessage } from "../../../../actions";
|
import { setErrorSnackMessage } from "../../../../actions";
|
||||||
import { containerForHeader } from "../../Common/FormComponents/common/styleLibrary";
|
import { containerForHeader, linkStyles } from "../../Common/FormComponents/common/styleLibrary";
|
||||||
import { ErrorResponseHandler } from "../../../../common/types";
|
import { ErrorResponseHandler } from "../../../../common/types";
|
||||||
import api from "../../../../common/api";
|
import api from "../../../../common/api";
|
||||||
import AddBucket from "./AddBucket";
|
import AddBucket from "./AddBucket";
|
||||||
@@ -127,10 +126,7 @@ const styles = (theme: Theme) =>
|
|||||||
constrainedContainer: {
|
constrainedContainer: {
|
||||||
maxWidth: 1180,
|
maxWidth: 1180,
|
||||||
},
|
},
|
||||||
link: {
|
...linkStyles(theme.palette.info.main),
|
||||||
textDecoration: "underline",
|
|
||||||
color: theme.palette.info.main,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
interface IListBucketsProps {
|
interface IListBucketsProps {
|
||||||
@@ -408,53 +404,57 @@ const ListBuckets = ({
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<br />
|
<br />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
{loading && <LinearProgress />}
|
||||||
{filteredRecords.map((bucket, index) => {
|
{!loading && (
|
||||||
return (
|
<Grid item xs={12}>
|
||||||
<BucketListItem
|
{filteredRecords.map((bucket, index) => {
|
||||||
bucket={bucket}
|
return (
|
||||||
key={`bucketListItem-${index.toString()}`}
|
<BucketListItem
|
||||||
onDelete={confirmDeleteBucket}
|
bucket={bucket}
|
||||||
onSelect={selectListBuckets}
|
key={`bucketListItem-${index.toString()}`}
|
||||||
selected={selectedBuckets.includes(bucket.name)}
|
onDelete={confirmDeleteBucket}
|
||||||
bulkSelect={bulkSelect}
|
onSelect={selectListBuckets}
|
||||||
/>
|
selected={selectedBuckets.includes(bucket.name)}
|
||||||
);
|
bulkSelect={bulkSelect}
|
||||||
})}
|
|
||||||
{filteredRecords.length == 0 && (
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
justifyContent={"center"}
|
|
||||||
alignContent={"center"}
|
|
||||||
alignItems={"center"}
|
|
||||||
>
|
|
||||||
<Grid item xs={8}>
|
|
||||||
<HelpBox
|
|
||||||
iconComponent={<BucketsIcon />}
|
|
||||||
title={"Buckets"}
|
|
||||||
help={
|
|
||||||
<Fragment>
|
|
||||||
MinIO uses buckets to organize objects. A bucket is
|
|
||||||
similar to a folder or directory in a filesystem, where
|
|
||||||
each bucket can hold an arbitrary number of objects.
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
To get started,
|
|
||||||
<a
|
|
||||||
className={classes.link}
|
|
||||||
onClick={() => {
|
|
||||||
addBucketOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Create a Bucket.
|
|
||||||
</a>
|
|
||||||
</Fragment>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{filteredRecords.length === 0 && (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
justifyContent={"center"}
|
||||||
|
alignContent={"center"}
|
||||||
|
alignItems={"center"}
|
||||||
|
>
|
||||||
|
<Grid item xs={8}>
|
||||||
|
<HelpBox
|
||||||
|
iconComponent={<BucketsIcon />}
|
||||||
|
title={"Buckets"}
|
||||||
|
help={
|
||||||
|
<Fragment>
|
||||||
|
MinIO uses buckets to organize objects. A bucket is
|
||||||
|
similar to a folder or directory in a filesystem,
|
||||||
|
where each bucket can hold an arbitrary number of
|
||||||
|
objects.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
To get started,
|
||||||
|
<button
|
||||||
|
className={classes.link}
|
||||||
|
onClick={() => {
|
||||||
|
addBucketOpen(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Create a Bucket.
|
||||||
|
</button>
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
)}
|
||||||
)}
|
</Grid>
|
||||||
</Grid>
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|||||||
@@ -965,3 +965,13 @@ export const commonDashboardInfocard = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const linkStyles = (color: string) => ({
|
||||||
|
link: {
|
||||||
|
textDecoration: "underline",
|
||||||
|
color,
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
border: 0,
|
||||||
|
cursor: "pointer",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@@ -20,13 +20,14 @@ import { connect } from "react-redux";
|
|||||||
import { Theme } from "@mui/material/styles";
|
import { Theme } from "@mui/material/styles";
|
||||||
import createStyles from "@mui/styles/createStyles";
|
import createStyles from "@mui/styles/createStyles";
|
||||||
import withStyles from "@mui/styles/withStyles";
|
import withStyles from "@mui/styles/withStyles";
|
||||||
import { IconButton, TextField } from "@mui/material";
|
import { IconButton, LinearProgress, TextField } from "@mui/material";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import InputAdornment from "@mui/material/InputAdornment";
|
import InputAdornment from "@mui/material/InputAdornment";
|
||||||
import {
|
import {
|
||||||
actionsTray,
|
actionsTray,
|
||||||
containerForHeader,
|
containerForHeader,
|
||||||
|
linkStyles,
|
||||||
searchField,
|
searchField,
|
||||||
settingsCommon,
|
settingsCommon,
|
||||||
typesSelection,
|
typesSelection,
|
||||||
@@ -76,10 +77,7 @@ const styles = (theme: Theme) =>
|
|||||||
...settingsCommon.customTitle,
|
...settingsCommon.customTitle,
|
||||||
marginTop: 0,
|
marginTop: 0,
|
||||||
},
|
},
|
||||||
link: {
|
...linkStyles(theme.palette.info.main),
|
||||||
textDecoration: "underline",
|
|
||||||
color: theme.palette.info.main,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const ListTiersConfiguration = ({
|
const ListTiersConfiguration = ({
|
||||||
@@ -235,122 +233,127 @@ const ListTiersConfiguration = ({
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<br />
|
<br />
|
||||||
</Grid>
|
</Grid>
|
||||||
{records.length > 0 && (
|
{isLoading && <LinearProgress />}
|
||||||
|
{!isLoading && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Grid item xs={12}>
|
{records.length > 0 && (
|
||||||
<TableWrapper
|
<Fragment>
|
||||||
itemActions={[
|
<Grid item xs={12}>
|
||||||
{
|
<TableWrapper
|
||||||
type: "edit",
|
itemActions={[
|
||||||
onClick: (tierData: ITierElement) => {
|
{
|
||||||
setSelectedTier(tierData);
|
type: "edit",
|
||||||
setUpdateCredentialsOpen(true);
|
onClick: (tierData: ITierElement) => {
|
||||||
},
|
setSelectedTier(tierData);
|
||||||
},
|
setUpdateCredentialsOpen(true);
|
||||||
]}
|
},
|
||||||
columns={[
|
},
|
||||||
{
|
]}
|
||||||
label: "Tier Name",
|
columns={[
|
||||||
elementKey: "type",
|
{
|
||||||
renderFunction: renderTierName,
|
label: "Tier Name",
|
||||||
renderFullObject: true,
|
elementKey: "type",
|
||||||
},
|
renderFunction: renderTierName,
|
||||||
{
|
renderFullObject: true,
|
||||||
label: "Type",
|
},
|
||||||
elementKey: "type",
|
{
|
||||||
width: 150,
|
label: "Type",
|
||||||
},
|
elementKey: "type",
|
||||||
{
|
width: 150,
|
||||||
label: "Endpoint",
|
},
|
||||||
elementKey: "type",
|
{
|
||||||
renderFunction: renderTierEndpoint,
|
label: "Endpoint",
|
||||||
renderFullObject: true,
|
elementKey: "type",
|
||||||
},
|
renderFunction: renderTierEndpoint,
|
||||||
{
|
renderFullObject: true,
|
||||||
label: "Bucket",
|
},
|
||||||
elementKey: "type",
|
{
|
||||||
renderFunction: renderTierBucket,
|
label: "Bucket",
|
||||||
renderFullObject: true,
|
elementKey: "type",
|
||||||
},
|
renderFunction: renderTierBucket,
|
||||||
{
|
renderFullObject: true,
|
||||||
label: "Prefix",
|
},
|
||||||
elementKey: "type",
|
{
|
||||||
renderFunction: renderTierPrefix,
|
label: "Prefix",
|
||||||
renderFullObject: true,
|
elementKey: "type",
|
||||||
},
|
renderFunction: renderTierPrefix,
|
||||||
{
|
renderFullObject: true,
|
||||||
label: "Region",
|
},
|
||||||
elementKey: "type",
|
{
|
||||||
renderFunction: renderTierRegion,
|
label: "Region",
|
||||||
renderFullObject: true,
|
elementKey: "type",
|
||||||
},
|
renderFunction: renderTierRegion,
|
||||||
]}
|
renderFullObject: true,
|
||||||
isLoading={isLoading}
|
},
|
||||||
records={filteredRecords}
|
]}
|
||||||
entityName="Tiers"
|
isLoading={isLoading}
|
||||||
idField="service_name"
|
records={filteredRecords}
|
||||||
customPaperHeight={classes.customConfigurationPage}
|
entityName="Tiers"
|
||||||
/>
|
idField="service_name"
|
||||||
</Grid>
|
customPaperHeight={classes.customConfigurationPage}
|
||||||
<Grid item xs={12}>
|
/>
|
||||||
<HelpBox
|
</Grid>
|
||||||
title={"Learn more about TIERS"}
|
<Grid item xs={12}>
|
||||||
iconComponent={<TiersIcon />}
|
<HelpBox
|
||||||
help={
|
title={"Learn more about TIERS"}
|
||||||
<Fragment>
|
iconComponent={<TiersIcon />}
|
||||||
Tiers are used by the MinIO Object Lifecycle Management
|
help={
|
||||||
which allows creating rules for time or date based automatic
|
<Fragment>
|
||||||
transition or expiry of objects. For object transition,
|
Tiers are used by the MinIO Object Lifecycle Management
|
||||||
MinIO automatically moves the object to a configured remote
|
which allows creating rules for time or date based
|
||||||
storage tier.
|
automatic transition or expiry of objects. For object
|
||||||
<br />
|
transition, MinIO automatically moves the object to a
|
||||||
<br />
|
configured remote storage tier.
|
||||||
You can learn more at our{" "}
|
<br />
|
||||||
<a
|
<br />
|
||||||
href="https://docs.min.io/minio/baremetal/lifecycle-management/lifecycle-management-overview.html?ref=con"
|
You can learn more at our{" "}
|
||||||
target="_blank"
|
<a
|
||||||
rel="noreferrer"
|
href="https://docs.min.io/minio/baremetal/lifecycle-management/lifecycle-management-overview.html?ref=con"
|
||||||
>
|
target="_blank"
|
||||||
documentation
|
rel="noreferrer"
|
||||||
</a>
|
>
|
||||||
.
|
documentation
|
||||||
</Fragment>
|
</a>
|
||||||
}
|
.
|
||||||
/>
|
</Fragment>
|
||||||
</Grid>
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
{records.length === 0 && (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
justifyContent={"center"}
|
||||||
|
alignContent={"center"}
|
||||||
|
alignItems={"center"}
|
||||||
|
>
|
||||||
|
<Grid item xs={8}>
|
||||||
|
<HelpBox
|
||||||
|
title={"Tiers"}
|
||||||
|
iconComponent={<TiersIcon />}
|
||||||
|
help={
|
||||||
|
<Fragment>
|
||||||
|
Tiers are used by the MinIO Object Lifecycle Management
|
||||||
|
which allows creating rules for time or date based
|
||||||
|
automatic transition or expiry of objects. For object
|
||||||
|
transition, MinIO automatically moves the object to a
|
||||||
|
configured remote storage tier.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
To get started,{" "}
|
||||||
|
<button onClick={addTier} className={classes.link}>
|
||||||
|
Add Tier
|
||||||
|
</button>
|
||||||
|
.
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
{records.length == 0 && (
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
justifyContent={"center"}
|
|
||||||
alignContent={"center"}
|
|
||||||
alignItems={"center"}
|
|
||||||
>
|
|
||||||
<Grid item xs={8}>
|
|
||||||
<HelpBox
|
|
||||||
title={"Tiers"}
|
|
||||||
iconComponent={<TiersIcon />}
|
|
||||||
help={
|
|
||||||
<Fragment>
|
|
||||||
Tiers are used by the MinIO Object Lifecycle Management
|
|
||||||
which allows creating rules for time or date based automatic
|
|
||||||
transition or expiry of objects. For object transition,
|
|
||||||
MinIO automatically moves the object to a configured remote
|
|
||||||
storage tier.
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
To get started,{" "}
|
|
||||||
<a onClick={addTier} className={classes.link}>
|
|
||||||
Add Tier
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</Fragment>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
)}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import withStyles from "@mui/styles/withStyles";
|
|||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import InputAdornment from "@mui/material/InputAdornment";
|
import InputAdornment from "@mui/material/InputAdornment";
|
||||||
import { Button } from "@mui/material";
|
import { Button, LinearProgress } from "@mui/material";
|
||||||
import { AddIcon, GroupsIcon, UsersIcon } from "../../../icons";
|
import { AddIcon, GroupsIcon, UsersIcon } from "../../../icons";
|
||||||
import { setErrorSnackMessage } from "../../../actions";
|
import { setErrorSnackMessage } from "../../../actions";
|
||||||
import { GroupsList } from "./types";
|
import { GroupsList } from "./types";
|
||||||
@@ -30,6 +30,7 @@ import { stringSort } from "../../../utils/sortFunctions";
|
|||||||
import {
|
import {
|
||||||
actionsTray,
|
actionsTray,
|
||||||
containerForHeader,
|
containerForHeader,
|
||||||
|
linkStyles,
|
||||||
searchField,
|
searchField,
|
||||||
} from "../Common/FormComponents/common/styleLibrary";
|
} from "../Common/FormComponents/common/styleLibrary";
|
||||||
import { ErrorResponseHandler } from "../../../common/types";
|
import { ErrorResponseHandler } from "../../../common/types";
|
||||||
@@ -80,10 +81,7 @@ const styles = (theme: Theme) =>
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
link: {
|
...linkStyles(theme.palette.info.main),
|
||||||
textDecoration: "underline",
|
|
||||||
color: theme.palette.info.main,
|
|
||||||
},
|
|
||||||
...actionsTray,
|
...actionsTray,
|
||||||
...searchField,
|
...searchField,
|
||||||
...containerForHeader(theme.spacing(4)),
|
...containerForHeader(theme.spacing(4)),
|
||||||
@@ -230,81 +228,86 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<br />
|
<br />
|
||||||
</Grid>
|
</Grid>
|
||||||
{records.length > 0 && (
|
{loading && <LinearProgress />}
|
||||||
|
{!loading && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Grid item xs={12}>
|
{records.length > 0 && (
|
||||||
<TableWrapper
|
<Fragment>
|
||||||
itemActions={tableActions}
|
<Grid item xs={12}>
|
||||||
columns={[{ label: "Name", elementKey: "" }]}
|
<TableWrapper
|
||||||
isLoading={loading}
|
itemActions={tableActions}
|
||||||
records={filteredRecords}
|
columns={[{ label: "Name", elementKey: "" }]}
|
||||||
entityName="Groups"
|
isLoading={loading}
|
||||||
idField=""
|
records={filteredRecords}
|
||||||
/>
|
entityName="Groups"
|
||||||
</Grid>
|
idField=""
|
||||||
<Grid item xs={12}>
|
/>
|
||||||
<HelpBox
|
</Grid>
|
||||||
title={"Groups"}
|
<Grid item xs={12}>
|
||||||
iconComponent={<GroupsIcon />}
|
<HelpBox
|
||||||
help={
|
title={"Groups"}
|
||||||
<Fragment>
|
iconComponent={<GroupsIcon />}
|
||||||
A group can have one attached IAM policy, where all users
|
help={
|
||||||
with membership in that group inherit that policy. Groups
|
<Fragment>
|
||||||
support more simplified management of user permissions on
|
A group can have one attached IAM policy, where all
|
||||||
the MinIO Tenant.
|
users with membership in that group inherit that
|
||||||
<br />
|
policy. Groups support more simplified management of
|
||||||
<br />
|
user permissions on the MinIO Tenant.
|
||||||
You can learn more at our{" "}
|
<br />
|
||||||
<a
|
<br />
|
||||||
href="https://docs.min.io/minio/k8s/tutorials/group-management.html?ref=con"
|
You can learn more at our{" "}
|
||||||
target="_blank"
|
<a
|
||||||
rel="noreferrer"
|
href="https://docs.min.io/minio/k8s/tutorials/group-management.html?ref=con"
|
||||||
>
|
target="_blank"
|
||||||
documentation
|
rel="noreferrer"
|
||||||
</a>
|
>
|
||||||
.
|
documentation
|
||||||
</Fragment>
|
</a>
|
||||||
}
|
.
|
||||||
/>
|
</Fragment>
|
||||||
</Grid>
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
{records.length === 0 && (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
justifyContent={"center"}
|
||||||
|
alignContent={"center"}
|
||||||
|
alignItems={"center"}
|
||||||
|
>
|
||||||
|
<Grid item xs={8}>
|
||||||
|
<HelpBox
|
||||||
|
title={"Groups"}
|
||||||
|
iconComponent={<UsersIcon />}
|
||||||
|
help={
|
||||||
|
<Fragment>
|
||||||
|
A group can have one attached IAM policy, where all
|
||||||
|
users with membership in that group inherit that
|
||||||
|
policy. Groups support more simplified management of
|
||||||
|
user permissions on the MinIO Tenant.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
To get started,{" "}
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedGroup(null);
|
||||||
|
setGroupOpen(true);
|
||||||
|
}}
|
||||||
|
className={classes.link}
|
||||||
|
>
|
||||||
|
Create a Group
|
||||||
|
</button>
|
||||||
|
.
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
{records.length == 0 && (
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
justifyContent={"center"}
|
|
||||||
alignContent={"center"}
|
|
||||||
alignItems={"center"}
|
|
||||||
>
|
|
||||||
<Grid item xs={8}>
|
|
||||||
<HelpBox
|
|
||||||
title={"Groups"}
|
|
||||||
iconComponent={<UsersIcon />}
|
|
||||||
help={
|
|
||||||
<Fragment>
|
|
||||||
A group can have one attached IAM policy, where all users
|
|
||||||
with membership in that group inherit that policy. Groups
|
|
||||||
support more simplified management of user permissions on
|
|
||||||
the MinIO Tenant.
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
To get started,{" "}
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedGroup(null);
|
|
||||||
setGroupOpen(true);
|
|
||||||
}}
|
|
||||||
className={classes.link}
|
|
||||||
>
|
|
||||||
Create a Group
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</Fragment>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
)}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import { ErrorResponseHandler } from "../../../../common/types";
|
|||||||
import api from "../../../../common/api";
|
import api from "../../../../common/api";
|
||||||
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
|
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
|
||||||
import FilterInputWrapper from "../../Common/FormComponents/FilterInputWrapper/FilterInputWrapper";
|
import FilterInputWrapper from "../../Common/FormComponents/FilterInputWrapper/FilterInputWrapper";
|
||||||
import DateTimePickerWrapper from "../../Common/FormComponents/DateTimePickerWrapper/DateTimePickerWrapper";
|
|
||||||
import LogSearchFullModal from "./LogSearchFullModal";
|
import LogSearchFullModal from "./LogSearchFullModal";
|
||||||
import { LogSearchColumnLabels } from "./utils";
|
import { LogSearchColumnLabels } from "./utils";
|
||||||
import DateRangeSelector from "../../Common/FormComponents/DateRangeSelector/DateRangeSelector";
|
import DateRangeSelector from "../../Common/FormComponents/DateRangeSelector/DateRangeSelector";
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { connect } from "react-redux";
|
|||||||
import { Theme } from "@mui/material/styles";
|
import { Theme } from "@mui/material/styles";
|
||||||
import createStyles from "@mui/styles/createStyles";
|
import createStyles from "@mui/styles/createStyles";
|
||||||
import withStyles from "@mui/styles/withStyles";
|
import withStyles from "@mui/styles/withStyles";
|
||||||
import { IconButton, TextField } from "@mui/material";
|
import { IconButton, LinearProgress, TextField } from "@mui/material";
|
||||||
import { red } from "@mui/material/colors";
|
import { red } from "@mui/material/colors";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord";
|
import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord";
|
||||||
@@ -37,6 +37,7 @@ import { setErrorSnackMessage } from "../../../actions";
|
|||||||
import {
|
import {
|
||||||
actionsTray,
|
actionsTray,
|
||||||
containerForHeader,
|
containerForHeader,
|
||||||
|
linkStyles,
|
||||||
searchField,
|
searchField,
|
||||||
settingsCommon,
|
settingsCommon,
|
||||||
} from "../Common/FormComponents/common/styleLibrary";
|
} from "../Common/FormComponents/common/styleLibrary";
|
||||||
@@ -73,10 +74,7 @@ const styles = (theme: Theme) =>
|
|||||||
lambdaContainer: {
|
lambdaContainer: {
|
||||||
padding: "15px 0",
|
padding: "15px 0",
|
||||||
},
|
},
|
||||||
link: {
|
...linkStyles(theme.palette.info.main),
|
||||||
textDecoration: "underline",
|
|
||||||
color: theme.palette.info.main,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const ListNotificationEndpoints = ({
|
const ListNotificationEndpoints = ({
|
||||||
@@ -186,91 +184,96 @@ const ListNotificationEndpoints = ({
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<br />
|
<br />
|
||||||
</Grid>
|
</Grid>
|
||||||
{records.length > 0 && (
|
{isLoading && <LinearProgress />}
|
||||||
|
{!isLoading && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Grid item xs={12}>
|
{records.length > 0 && (
|
||||||
<TableWrapper
|
<Fragment>
|
||||||
itemActions={[]}
|
<Grid item xs={12}>
|
||||||
columns={[
|
<TableWrapper
|
||||||
{
|
itemActions={[]}
|
||||||
label: "Status",
|
columns={[
|
||||||
elementKey: "status",
|
{
|
||||||
renderFunction: statusDisplay,
|
label: "Status",
|
||||||
width: 150,
|
elementKey: "status",
|
||||||
},
|
renderFunction: statusDisplay,
|
||||||
{ label: "Service", elementKey: "service_name" },
|
width: 150,
|
||||||
]}
|
},
|
||||||
isLoading={isLoading}
|
{ label: "Service", elementKey: "service_name" },
|
||||||
records={filteredRecords}
|
]}
|
||||||
entityName="Notification Endpoints"
|
isLoading={isLoading}
|
||||||
idField="service_name"
|
records={filteredRecords}
|
||||||
customPaperHeight={classes.twHeight}
|
entityName="Notification Endpoints"
|
||||||
/>
|
idField="service_name"
|
||||||
</Grid>
|
customPaperHeight={classes.twHeight}
|
||||||
<Grid item xs={12}>
|
/>
|
||||||
<HelpBox
|
</Grid>
|
||||||
title={"Notification Endpoints"}
|
<Grid item xs={12}>
|
||||||
iconComponent={<LambdaIcon />}
|
<HelpBox
|
||||||
help={
|
title={"Notification Endpoints"}
|
||||||
<Fragment>
|
iconComponent={<LambdaIcon />}
|
||||||
MinIO bucket notifications allow administrators to send
|
help={
|
||||||
notifications to supported external services on certain
|
<Fragment>
|
||||||
object or bucket events. MinIO supports bucket and
|
MinIO bucket notifications allow administrators to send
|
||||||
object-level S3 events similar to the Amazon S3 Event
|
notifications to supported external services on certain
|
||||||
Notifications.
|
object or bucket events. MinIO supports bucket and
|
||||||
<br />
|
object-level S3 events similar to the Amazon S3 Event
|
||||||
<br />
|
Notifications.
|
||||||
You can learn more at our{" "}
|
<br />
|
||||||
<a
|
<br />
|
||||||
href="https://docs.min.io/minio/baremetal/monitoring/bucket-notifications/bucket-notifications.html?ref=con"
|
You can learn more at our{" "}
|
||||||
target="_blank"
|
<a
|
||||||
rel="noreferrer"
|
href="https://docs.min.io/minio/baremetal/monitoring/bucket-notifications/bucket-notifications.html?ref=con"
|
||||||
>
|
target="_blank"
|
||||||
documentation
|
rel="noreferrer"
|
||||||
</a>
|
>
|
||||||
.
|
documentation
|
||||||
</Fragment>
|
</a>
|
||||||
}
|
.
|
||||||
/>
|
</Fragment>
|
||||||
</Grid>
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
{records.length === 0 && (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
justifyContent={"center"}
|
||||||
|
alignContent={"center"}
|
||||||
|
alignItems={"center"}
|
||||||
|
>
|
||||||
|
<Grid item xs={8}>
|
||||||
|
<HelpBox
|
||||||
|
title={"Notification Targets"}
|
||||||
|
iconComponent={<LambdaIcon />}
|
||||||
|
help={
|
||||||
|
<Fragment>
|
||||||
|
MinIO bucket notifications allow administrators to send
|
||||||
|
notifications to supported external services on certain
|
||||||
|
object or bucket events. MinIO supports bucket and
|
||||||
|
object-level S3 events similar to the Amazon S3 Event
|
||||||
|
Notifications.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
To get started,{" "}
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
history.push("/notification-endpoints/add");
|
||||||
|
}}
|
||||||
|
className={classes.link}
|
||||||
|
>
|
||||||
|
Add a Notification Target
|
||||||
|
</button>
|
||||||
|
.
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
{records.length == 0 && (
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
justifyContent={"center"}
|
|
||||||
alignContent={"center"}
|
|
||||||
alignItems={"center"}
|
|
||||||
>
|
|
||||||
<Grid item xs={8}>
|
|
||||||
<HelpBox
|
|
||||||
title={"Notification Targets"}
|
|
||||||
iconComponent={<LambdaIcon />}
|
|
||||||
help={
|
|
||||||
<Fragment>
|
|
||||||
MinIO bucket notifications allow administrators to send
|
|
||||||
notifications to supported external services on certain
|
|
||||||
object or bucket events. MinIO supports bucket and
|
|
||||||
object-level S3 events similar to the Amazon S3 Event
|
|
||||||
Notifications.
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
To get started,{" "}
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
history.push("/notification-endpoints/add");
|
|
||||||
}}
|
|
||||||
className={classes.link}
|
|
||||||
>
|
|
||||||
Add a Notification Target
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</Fragment>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
)}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { connect } from "react-redux";
|
|||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import InputAdornment from "@mui/material/InputAdornment";
|
import InputAdornment from "@mui/material/InputAdornment";
|
||||||
import { Box, Button, IconButton } from "@mui/material";
|
import { Box, Button, IconButton, LinearProgress } from "@mui/material";
|
||||||
import { Theme } from "@mui/material/styles";
|
import { Theme } from "@mui/material/styles";
|
||||||
import createStyles from "@mui/styles/createStyles";
|
import createStyles from "@mui/styles/createStyles";
|
||||||
import withStyles from "@mui/styles/withStyles";
|
import withStyles from "@mui/styles/withStyles";
|
||||||
@@ -29,6 +29,7 @@ import { NewServiceAccount } from "../../Common/CredentialsPrompt/types";
|
|||||||
import {
|
import {
|
||||||
actionsTray,
|
actionsTray,
|
||||||
containerForHeader,
|
containerForHeader,
|
||||||
|
linkStyles,
|
||||||
searchField,
|
searchField,
|
||||||
} from "../../Common/FormComponents/common/styleLibrary";
|
} from "../../Common/FormComponents/common/styleLibrary";
|
||||||
import { setErrorSnackMessage } from "../../../../actions";
|
import { setErrorSnackMessage } from "../../../../actions";
|
||||||
@@ -104,10 +105,7 @@ const styles = (theme: Theme) =>
|
|||||||
paddingTop: 30,
|
paddingTop: 30,
|
||||||
paddingBottom: 30,
|
paddingBottom: 30,
|
||||||
},
|
},
|
||||||
link: {
|
...linkStyles(theme.palette.info.main),
|
||||||
textDecoration: "underline",
|
|
||||||
color: theme.palette.info.main,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const ListTenants = ({ classes, setErrorSnackMessage }: ITenantsList) => {
|
const ListTenants = ({ classes, setErrorSnackMessage }: ITenantsList) => {
|
||||||
@@ -273,43 +271,49 @@ const ListTenants = ({ classes, setErrorSnackMessage }: ITenantsList) => {
|
|||||||
<RefreshIcon />
|
<RefreshIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
{filteredRecords.map((t) => {
|
{isLoading && <LinearProgress />}
|
||||||
return <TenantListItem tenant={t} />;
|
{!isLoading && (
|
||||||
})}
|
<Fragment>
|
||||||
{filteredRecords.length == 0 && (
|
{filteredRecords.map((t) => {
|
||||||
<Grid
|
return <TenantListItem tenant={t} />;
|
||||||
container
|
})}
|
||||||
justifyContent={"center"}
|
{filteredRecords.length === 0 && (
|
||||||
alignContent={"center"}
|
<Grid
|
||||||
alignItems={"center"}
|
container
|
||||||
>
|
justifyContent={"center"}
|
||||||
<Grid item xs={8}>
|
alignContent={"center"}
|
||||||
<HelpBox
|
alignItems={"center"}
|
||||||
iconComponent={<TenantsIcon />}
|
>
|
||||||
title={"Tenants"}
|
<Grid item xs={8}>
|
||||||
help={
|
<HelpBox
|
||||||
<Fragment>
|
iconComponent={<TenantsIcon />}
|
||||||
Tenant is the logical structure to represent a MinIO
|
title={"Tenants"}
|
||||||
deployment. A tenant can have different size and
|
help={
|
||||||
configurations from other tenants, even a different
|
<Fragment>
|
||||||
storage class.
|
Tenant is the logical structure to represent a
|
||||||
<br />
|
MinIO deployment. A tenant can have different size
|
||||||
<br />
|
and configurations from other tenants, even a
|
||||||
To get started,
|
different storage class.
|
||||||
<a
|
<br />
|
||||||
className={classes.link}
|
<br />
|
||||||
onClick={() => {
|
To get started,
|
||||||
history.push("/tenants/add");
|
<button
|
||||||
}}
|
className={classes.link}
|
||||||
>
|
onClick={() => {
|
||||||
Create a Tenant.
|
history.push("/tenants/add");
|
||||||
</a>
|
}}
|
||||||
</Fragment>
|
>
|
||||||
}
|
Create a Tenant.
|
||||||
/>
|
</button>
|
||||||
</Grid>
|
</Fragment>
|
||||||
</Grid>
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -14,13 +14,19 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { Fragment, useCallback, useEffect, useState } from "react";
|
import React, { Fragment, useEffect, useState } from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { Theme } from "@mui/material/styles";
|
import { Theme } from "@mui/material/styles";
|
||||||
import createStyles from "@mui/styles/createStyles";
|
import createStyles from "@mui/styles/createStyles";
|
||||||
import withStyles from "@mui/styles/withStyles";
|
import withStyles from "@mui/styles/withStyles";
|
||||||
import api from "../../../common/api";
|
import api from "../../../common/api";
|
||||||
import { Button, Grid, InputAdornment, TextField } from "@mui/material";
|
import {
|
||||||
|
Button,
|
||||||
|
Grid,
|
||||||
|
InputAdornment,
|
||||||
|
LinearProgress,
|
||||||
|
TextField,
|
||||||
|
} from "@mui/material";
|
||||||
import GroupIcon from "@mui/icons-material/Group";
|
import GroupIcon from "@mui/icons-material/Group";
|
||||||
import { User, UsersList } from "./types";
|
import { User, UsersList } from "./types";
|
||||||
import { usersSort } from "../../../utils/sortFunctions";
|
import { usersSort } from "../../../utils/sortFunctions";
|
||||||
@@ -28,6 +34,7 @@ import { AddIcon, UsersIcon } from "../../../icons";
|
|||||||
import {
|
import {
|
||||||
actionsTray,
|
actionsTray,
|
||||||
containerForHeader,
|
containerForHeader,
|
||||||
|
linkStyles,
|
||||||
searchField,
|
searchField,
|
||||||
} from "../Common/FormComponents/common/styleLibrary";
|
} from "../Common/FormComponents/common/styleLibrary";
|
||||||
import { setErrorSnackMessage } from "../../../actions";
|
import { setErrorSnackMessage } from "../../../actions";
|
||||||
@@ -80,10 +87,7 @@ const styles = (theme: Theme) =>
|
|||||||
...actionsTray,
|
...actionsTray,
|
||||||
...searchField,
|
...searchField,
|
||||||
...containerForHeader(theme.spacing(4)),
|
...containerForHeader(theme.spacing(4)),
|
||||||
link: {
|
...linkStyles(theme.palette.info.main),
|
||||||
textDecoration: "underline",
|
|
||||||
color: theme.palette.info.main,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
interface IUsersProps {
|
interface IUsersProps {
|
||||||
@@ -94,7 +98,7 @@ interface IUsersProps {
|
|||||||
|
|
||||||
const ListUsers = ({ classes, setErrorSnackMessage, history }: IUsersProps) => {
|
const ListUsers = ({ classes, setErrorSnackMessage, history }: IUsersProps) => {
|
||||||
const [records, setRecords] = useState<User[]>([]);
|
const [records, setRecords] = useState<User[]>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
const [addScreenOpen, setAddScreenOpen] = useState<boolean>(false);
|
const [addScreenOpen, setAddScreenOpen] = useState<boolean>(false);
|
||||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||||
const [selectedUser, setSelectedUser] = useState<User | null>(null);
|
const [selectedUser, setSelectedUser] = useState<User | null>(null);
|
||||||
@@ -103,31 +107,15 @@ const ListUsers = ({ classes, setErrorSnackMessage, history }: IUsersProps) => {
|
|||||||
const [checkedUsers, setCheckedUsers] = useState<string[]>([]);
|
const [checkedUsers, setCheckedUsers] = useState<string[]>([]);
|
||||||
const [policyOpen, setPolicyOpen] = useState<boolean>(false);
|
const [policyOpen, setPolicyOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
const fetchRecords = useCallback(() => {
|
|
||||||
setLoading(true);
|
|
||||||
api
|
|
||||||
.invoke("GET", `/api/v1/users`)
|
|
||||||
.then((res: UsersList) => {
|
|
||||||
const users = res.users === null ? [] : res.users;
|
|
||||||
|
|
||||||
setLoading(false);
|
|
||||||
setRecords(users.sort(usersSort));
|
|
||||||
})
|
|
||||||
.catch((err: ErrorResponseHandler) => {
|
|
||||||
setLoading(false);
|
|
||||||
setErrorSnackMessage(err);
|
|
||||||
});
|
|
||||||
}, [setLoading, setRecords, setErrorSnackMessage]);
|
|
||||||
|
|
||||||
const closeAddModalAndRefresh = () => {
|
const closeAddModalAndRefresh = () => {
|
||||||
setAddScreenOpen(false);
|
setAddScreenOpen(false);
|
||||||
fetchRecords();
|
setLoading(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeDeleteModalAndRefresh = (refresh: boolean) => {
|
const closeDeleteModalAndRefresh = (refresh: boolean) => {
|
||||||
setDeleteOpen(false);
|
setDeleteOpen(false);
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
fetchRecords();
|
setLoading(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -139,8 +127,21 @@ const ListUsers = ({ classes, setErrorSnackMessage, history }: IUsersProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchRecords();
|
if (loading) {
|
||||||
}, [fetchRecords]);
|
api
|
||||||
|
.invoke("GET", `/api/v1/users`)
|
||||||
|
.then((res: UsersList) => {
|
||||||
|
const users = res.users === null ? [] : res.users;
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
setRecords(users.sort(usersSort));
|
||||||
|
})
|
||||||
|
.catch((err: ErrorResponseHandler) => {
|
||||||
|
setLoading(false);
|
||||||
|
setErrorSnackMessage(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [loading, setErrorSnackMessage]);
|
||||||
|
|
||||||
const filteredRecords = records.filter((elementItem) =>
|
const filteredRecords = records.filter((elementItem) =>
|
||||||
elementItem.accessKey.includes(filter)
|
elementItem.accessKey.includes(filter)
|
||||||
@@ -206,7 +207,7 @@ const ListUsers = ({ classes, setErrorSnackMessage, history }: IUsersProps) => {
|
|||||||
selectedGroup={null}
|
selectedGroup={null}
|
||||||
closeModalAndRefresh={() => {
|
closeModalAndRefresh={() => {
|
||||||
setPolicyOpen(false);
|
setPolicyOpen(false);
|
||||||
fetchRecords();
|
setLoading(true);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -278,98 +279,103 @@ const ListUsers = ({ classes, setErrorSnackMessage, history }: IUsersProps) => {
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<br />
|
<br />
|
||||||
</Grid>
|
</Grid>
|
||||||
{records.length > 0 && (
|
{loading && <LinearProgress />}
|
||||||
|
{!loading && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Grid item xs={12}>
|
{records.length > 0 && (
|
||||||
<TableWrapper
|
<Fragment>
|
||||||
itemActions={tableActions}
|
<Grid item xs={12}>
|
||||||
columns={[{ label: "Access Key", elementKey: "accessKey" }]}
|
<TableWrapper
|
||||||
onSelect={selectionChanged}
|
itemActions={tableActions}
|
||||||
selectedItems={checkedUsers}
|
columns={[{ label: "Access Key", elementKey: "accessKey" }]}
|
||||||
isLoading={loading}
|
onSelect={selectionChanged}
|
||||||
records={filteredRecords}
|
selectedItems={checkedUsers}
|
||||||
entityName="Users"
|
isLoading={loading}
|
||||||
idField="accessKey"
|
records={filteredRecords}
|
||||||
customPaperHeight={classes.twHeight}
|
entityName="Users"
|
||||||
/>
|
idField="accessKey"
|
||||||
</Grid>
|
customPaperHeight={classes.twHeight}
|
||||||
<Grid item xs={12}>
|
/>
|
||||||
<HelpBox
|
</Grid>
|
||||||
title={"Users"}
|
<Grid item xs={12}>
|
||||||
iconComponent={<UsersIcon />}
|
<HelpBox
|
||||||
help={
|
title={"Users"}
|
||||||
<Fragment>
|
iconComponent={<UsersIcon />}
|
||||||
A MinIO user consists of a unique access key (username) and
|
help={
|
||||||
corresponding secret key (password). Clients must
|
<Fragment>
|
||||||
authenticate their identity by specifying both a valid
|
A MinIO user consists of a unique access key (username)
|
||||||
access key (username) and the corresponding secret key
|
and corresponding secret key (password). Clients must
|
||||||
(password) of an existing MinIO user.
|
authenticate their identity by specifying both a valid
|
||||||
<br />
|
access key (username) and the corresponding secret key
|
||||||
<br />
|
(password) of an existing MinIO user.
|
||||||
Each user can have one or more assigned policies that
|
<br />
|
||||||
explicitly list the actions and resources to which that user
|
<br />
|
||||||
has access. Users can also inherit policies from the groups
|
Each user can have one or more assigned policies that
|
||||||
in which they have membership.
|
explicitly list the actions and resources to which that
|
||||||
<br />
|
user has access. Users can also inherit policies from
|
||||||
<br />
|
the groups in which they have membership.
|
||||||
You can learn more at our{" "}
|
<br />
|
||||||
<a
|
<br />
|
||||||
href="https://docs.min.io/minio/baremetal/monitoring/bucket-notifications/bucket-notifications.html?ref=con"
|
You can learn more at our{" "}
|
||||||
target="_blank"
|
<a
|
||||||
rel="noreferrer"
|
href="https://docs.min.io/minio/baremetal/monitoring/bucket-notifications/bucket-notifications.html?ref=con"
|
||||||
>
|
target="_blank"
|
||||||
documentation
|
rel="noreferrer"
|
||||||
</a>
|
>
|
||||||
.
|
documentation
|
||||||
</Fragment>
|
</a>
|
||||||
}
|
.
|
||||||
/>
|
</Fragment>
|
||||||
</Grid>
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
{records.length === 0 && (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
justifyContent={"center"}
|
||||||
|
alignContent={"center"}
|
||||||
|
alignItems={"center"}
|
||||||
|
>
|
||||||
|
<Grid item xs={8}>
|
||||||
|
<HelpBox
|
||||||
|
title={"Users"}
|
||||||
|
iconComponent={<UsersIcon />}
|
||||||
|
help={
|
||||||
|
<Fragment>
|
||||||
|
A MinIO user consists of a unique access key (username)
|
||||||
|
and corresponding secret key (password). Clients must
|
||||||
|
authenticate their identity by specifying both a valid
|
||||||
|
access key (username) and the corresponding secret key
|
||||||
|
(password) of an existing MinIO user.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Each user can have one or more assigned policies that
|
||||||
|
explicitly list the actions and resources to which that
|
||||||
|
user has access. Users can also inherit policies from
|
||||||
|
the groups in which they have membership.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
To get started,{" "}
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setAddScreenOpen(true);
|
||||||
|
setSelectedUser(null);
|
||||||
|
}}
|
||||||
|
className={classes.link}
|
||||||
|
>
|
||||||
|
Create a User
|
||||||
|
</button>
|
||||||
|
.
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
{records.length == 0 && (
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
justifyContent={"center"}
|
|
||||||
alignContent={"center"}
|
|
||||||
alignItems={"center"}
|
|
||||||
>
|
|
||||||
<Grid item xs={8}>
|
|
||||||
<HelpBox
|
|
||||||
title={"Users"}
|
|
||||||
iconComponent={<UsersIcon />}
|
|
||||||
help={
|
|
||||||
<Fragment>
|
|
||||||
A MinIO user consists of a unique access key (username) and
|
|
||||||
corresponding secret key (password). Clients must
|
|
||||||
authenticate their identity by specifying both a valid
|
|
||||||
access key (username) and the corresponding secret key
|
|
||||||
(password) of an existing MinIO user.
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
Each user can have one or more assigned policies that
|
|
||||||
explicitly list the actions and resources to which that user
|
|
||||||
has access. Users can also inherit policies from the groups
|
|
||||||
in which they have membership.
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
To get started,{" "}
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
setAddScreenOpen(true);
|
|
||||||
setSelectedUser(null);
|
|
||||||
}}
|
|
||||||
className={classes.link}
|
|
||||||
>
|
|
||||||
Create a User
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</Fragment>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
)}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user