Tooltips for Bucket Lifecycle, Delete bucket, Manage bucket (#2334)
This commit is contained in:
@@ -18,6 +18,7 @@ export const IAM_ROLES = {
|
||||
BUCKET_OWNER: "BUCKET_OWNER", // upload/delete objects from the bucket
|
||||
BUCKET_VIEWER: "BUCKET_VIEWER", // only view objects on the bucket
|
||||
BUCKET_ADMIN: "BUCKET_ADMIN", // administrate the bucket
|
||||
BUCKET_LIFECYCLE: "BUCKET_LIFECYCLE", // can manage bucket lifecycle
|
||||
};
|
||||
|
||||
export const IAM_SCOPES = {
|
||||
@@ -281,6 +282,12 @@ export const IAM_PERMISSIONS = {
|
||||
IAM_SCOPES.ADMIN_LIST_USERS,
|
||||
IAM_SCOPES.ADMIN_HEAL,
|
||||
],
|
||||
[IAM_ROLES.BUCKET_LIFECYCLE]: [
|
||||
IAM_SCOPES.S3_GET_LIFECYCLE_CONFIGURATION,
|
||||
IAM_SCOPES.S3_PUT_LIFECYCLE_CONFIGURATION,
|
||||
IAM_SCOPES.ADMIN_LIST_TIERS,
|
||||
IAM_SCOPES.ADMIN_SET_TIER,
|
||||
],
|
||||
};
|
||||
|
||||
// application pages/routes and required scopes/roles
|
||||
@@ -434,6 +441,10 @@ export const permissionTooltipHelper = (scopes: string[], name: string) => {
|
||||
name +
|
||||
". Please ask your MinIO administrator to grant you " +
|
||||
scopes +
|
||||
" permission in order to enable Versioning."
|
||||
" permission" +
|
||||
(scopes.length > 1 ? "s" : "") +
|
||||
" in order to enable " +
|
||||
name +
|
||||
"."
|
||||
);
|
||||
};
|
||||
|
||||
@@ -45,7 +45,12 @@ import ScreenTitle from "../../Common/ScreenTitle/ScreenTitle";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
import RefreshIcon from "../../../../icons/RefreshIcon";
|
||||
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
|
||||
import {
|
||||
IAM_SCOPES,
|
||||
IAM_PERMISSIONS,
|
||||
IAM_ROLES,
|
||||
permissionTooltipHelper,
|
||||
} from "../../../../common/SecureComponent/permissions";
|
||||
import PageLayout from "../../Common/Layout/PageLayout";
|
||||
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
|
||||
import BackLink from "../../../../common/BackLink";
|
||||
@@ -136,6 +141,14 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
|
||||
selTab = selTab ? selTab : "summary";
|
||||
|
||||
const [activeTab, setActiveTab] = useState(selTab);
|
||||
const canDelete = hasPermission(bucketName, [
|
||||
IAM_SCOPES.S3_DELETE_BUCKET,
|
||||
IAM_SCOPES.S3_FORCE_DELETE_BUCKET,
|
||||
]);
|
||||
const canBrowse = hasPermission(
|
||||
bucketName,
|
||||
IAM_PERMISSIONS[IAM_ROLES.BUCKET_VIEWER]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setActiveTab(selTab);
|
||||
@@ -209,7 +222,16 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
|
||||
<PageHeader
|
||||
label={<BackLink to={"/buckets"} label={"Buckets"} />}
|
||||
actions={
|
||||
<TooltipWrapper tooltip={"Browse Bucket"}>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canBrowse
|
||||
? "Browse Bucket"
|
||||
: permissionTooltipHelper(
|
||||
IAM_PERMISSIONS[IAM_ROLES.BUCKET_VIEWER],
|
||||
"browsing this bucket"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id={"switch-browse-view"}
|
||||
aria-label="Browse Bucket"
|
||||
@@ -220,6 +242,7 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
|
||||
style={{
|
||||
padding: "0 10px",
|
||||
}}
|
||||
disabled={!canBrowse}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
}
|
||||
@@ -260,7 +283,19 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
|
||||
resource={bucketName}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<TooltipWrapper tooltip={"Delete Bucket"}>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canDelete
|
||||
? ""
|
||||
: permissionTooltipHelper(
|
||||
[
|
||||
IAM_SCOPES.S3_DELETE_BUCKET,
|
||||
IAM_SCOPES.S3_FORCE_DELETE_BUCKET,
|
||||
],
|
||||
"deleting this bucket"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id={"delete-bucket-button"}
|
||||
onClick={() => {
|
||||
@@ -269,6 +304,7 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
|
||||
label={"Delete Bucket"}
|
||||
icon={<TrashIcon />}
|
||||
variant={"secondary"}
|
||||
disabled={!canDelete}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</SecureComponent>
|
||||
|
||||
@@ -38,10 +38,12 @@ import { Link, useNavigate } from "react-router-dom";
|
||||
import {
|
||||
IAM_PERMISSIONS,
|
||||
IAM_ROLES,
|
||||
permissionTooltipHelper,
|
||||
} from "../../../../common/SecureComponent/permissions";
|
||||
import { SecureComponent } from "../../../../common/SecureComponent";
|
||||
import clsx from "clsx";
|
||||
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
|
||||
import { hasPermission } from "../../../../common/SecureComponent";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -187,6 +189,11 @@ const BucketListItem = ({
|
||||
const quota = get(bucket, "details.quota.quota", "0");
|
||||
const quotaForString = calculateBytes(quota, true, false);
|
||||
|
||||
const manageAllowed = hasPermission(
|
||||
bucket.name,
|
||||
IAM_PERMISSIONS[IAM_ROLES.BUCKET_ADMIN]
|
||||
);
|
||||
|
||||
const accessToStr = (bucket: Bucket): string => {
|
||||
if (bucket.rw_access?.read && !bucket.rw_access?.write) {
|
||||
return "R";
|
||||
@@ -249,7 +256,16 @@ const BucketListItem = ({
|
||||
scopes={IAM_PERMISSIONS[IAM_ROLES.BUCKET_ADMIN]}
|
||||
resource={bucket.name}
|
||||
>
|
||||
<TooltipWrapper tooltip={"Manage"}>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
manageAllowed
|
||||
? "Manage Bucket"
|
||||
: permissionTooltipHelper(
|
||||
IAM_PERMISSIONS[IAM_ROLES.BUCKET_ADMIN],
|
||||
"managing this bucket"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
onClick={() => navigate(`/buckets/${bucket.name}/admin`)}
|
||||
label={"Manage"}
|
||||
@@ -257,6 +273,7 @@ const BucketListItem = ({
|
||||
color={"primary"}
|
||||
variant={"regular"}
|
||||
id={`manage-${bucket.name}`}
|
||||
disabled={!manageAllowed}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</SecureComponent>
|
||||
|
||||
@@ -47,7 +47,10 @@ import { SecureComponent } from "../../../../common/SecureComponent";
|
||||
import {
|
||||
CONSOLE_UI_RESOURCE,
|
||||
IAM_PAGES,
|
||||
IAM_PERMISSIONS,
|
||||
IAM_ROLES,
|
||||
IAM_SCOPES,
|
||||
permissionTooltipHelper,
|
||||
} from "../../../../common/SecureComponent/permissions";
|
||||
import PageLayout from "../../Common/Layout/PageLayout";
|
||||
import SearchBox from "../../Common/SearchBox";
|
||||
@@ -105,6 +108,7 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
|
||||
const [replicationModalOpen, setReplicationModalOpen] =
|
||||
useState<boolean>(false);
|
||||
const [lifecycleModalOpen, setLifecycleModalOpen] = useState<boolean>(false);
|
||||
const [canPutLifecycle, setCanPutLifecycle] = useState<boolean>(false);
|
||||
const [bulkSelect, setBulkSelect] = useState<boolean>(false);
|
||||
|
||||
const features = useSelector(selFeatures);
|
||||
@@ -172,6 +176,16 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
var failLifecycle = false;
|
||||
selectedBuckets.forEach((bucket: string) => {
|
||||
hasPermission(bucket, IAM_PERMISSIONS[IAM_ROLES.BUCKET_LIFECYCLE], true)
|
||||
? setCanPutLifecycle(true)
|
||||
: (failLifecycle = true);
|
||||
});
|
||||
failLifecycle ? setCanPutLifecycle(false) : setCanPutLifecycle(true);
|
||||
}, [selectedBuckets]);
|
||||
|
||||
const renderItemLine = (index: number) => {
|
||||
const bucket = filteredRecords[index] || null;
|
||||
if (bucket) {
|
||||
@@ -282,7 +296,20 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
|
||||
</TooltipWrapper>
|
||||
)}
|
||||
|
||||
<TooltipWrapper tooltip={"Set Lifecycle"}>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
selectedBuckets.length === 0
|
||||
? bulkSelect
|
||||
? "Please select at least one bucket on which to configure Lifecycle"
|
||||
: "Use the Select Multiple Buckets button to choose buckets on which to configure Lifecycle"
|
||||
: canPutLifecycle
|
||||
? "Set Lifecycle"
|
||||
: permissionTooltipHelper(
|
||||
IAM_PERMISSIONS[IAM_ROLES.BUCKET_LIFECYCLE],
|
||||
"configuring lifecycle for the selected buckets"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id={"set-lifecycle"}
|
||||
onClick={() => {
|
||||
@@ -290,7 +317,7 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
|
||||
}}
|
||||
icon={<LifecycleConfigIcon />}
|
||||
variant={"regular"}
|
||||
disabled={selectedBuckets.length === 0}
|
||||
disabled={selectedBuckets.length === 0 || !canPutLifecycle}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
|
||||
@@ -323,10 +350,11 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canCreateBucket
|
||||
? "Create Bucket"
|
||||
: "You require additional permissions in order to create a new Bucket. Please ask your MinIO administrator to grant you " +
|
||||
IAM_SCOPES.S3_CREATE_BUCKET +
|
||||
" permission in order to create a Bucket."
|
||||
? ""
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_CREATE_BUCKET],
|
||||
"creating a bucket"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user