Added tooltips, button permission UI, for Groups, GroupDetails screens (#2353)

This commit is contained in:
jinapurapu
2022-10-06 20:53:31 -07:00
committed by GitHub
parent 2b17aa598f
commit e6a2364209
4 changed files with 479 additions and 308 deletions

View File

@@ -449,11 +449,15 @@ export const permissionTooltipHelper = (scopes: string[], name: string) => {
}; };
export const listUsersPermissions = [IAM_SCOPES.ADMIN_LIST_USERS]; export const listUsersPermissions = [IAM_SCOPES.ADMIN_LIST_USERS];
export const viewUserPermissions = [IAM_SCOPES.ADMIN_GET_USER];
export const addUserToGroupPermissions = [IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP]; export const addUserToGroupPermissions = [IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP];
export const deleteUserPermissions = [IAM_SCOPES.ADMIN_DELETE_USER]; export const deleteUserPermissions = [IAM_SCOPES.ADMIN_DELETE_USER];
export const enableUserPermissions = [IAM_SCOPES.ADMIN_ENABLE_USER]; export const enableUserPermissions = [IAM_SCOPES.ADMIN_ENABLE_USER];
export const disableUserPermissions = [IAM_SCOPES.ADMIN_DISABLE_USER]; export const disableUserPermissions = [IAM_SCOPES.ADMIN_DISABLE_USER];
export const assignIAMPolicyPermissions = [ export const assignIAMPolicyPermissions = [
IAM_SCOPES.ADMIN_ATTACH_USER_OR_GROUP_POLICY, IAM_SCOPES.ADMIN_ATTACH_USER_OR_GROUP_POLICY,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES, IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
@@ -479,3 +483,35 @@ export const editServiceAccountPermissions = [
IAM_SCOPES.ADMIN_UPDATE_SERVICEACCOUNT, IAM_SCOPES.ADMIN_UPDATE_SERVICEACCOUNT,
IAM_SCOPES.ADMIN_REMOVE_SERVICEACCOUNT, IAM_SCOPES.ADMIN_REMOVE_SERVICEACCOUNT,
]; ];
export const applyPolicyPermissions = [
IAM_SCOPES.ADMIN_ATTACH_USER_OR_GROUP_POLICY,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
];
export const deleteGroupPermissions = [IAM_SCOPES.ADMIN_REMOVE_USER_FROM_GROUP];
export const displayGroupsPermissions = [IAM_SCOPES.ADMIN_LIST_GROUPS];
export const createGroupPermissions = [
IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP,
IAM_SCOPES.ADMIN_LIST_USERS,
];
export const viewUserPermissions = [
IAM_SCOPES.ADMIN_GET_USER,
IAM_SCOPES.ADMIN_LIST_USERS,
];
export const editGroupMembersPermissions = [
IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP,
IAM_SCOPES.ADMIN_LIST_USERS,
];
export const setGroupPoliciesPermissions = [
IAM_SCOPES.ADMIN_ATTACH_USER_OR_GROUP_POLICY,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
];
export const viewPolicyPermissions = [IAM_SCOPES.ADMIN_GET_POLICY];
export const enableDisableGroupPermissions = [
IAM_SCOPES.ADMIN_ENABLE_GROUP,
IAM_SCOPES.ADMIN_DISABLE_GROUP,
];

View File

@@ -40,6 +40,7 @@ import {
TableRowPredefStyles, TableRowPredefStyles,
} from "../FormComponents/common/styleLibrary"; } from "../FormComponents/common/styleLibrary";
import Loader from "../Loader/Loader"; import Loader from "../Loader/Loader";
import TooltipWrapper from "../TooltipWrapper/TooltipWrapper";
//Interfaces for table Items //Interfaces for table Items
@@ -111,6 +112,7 @@ interface TableWrapperProps {
index: number; index: number;
}) => "deleted" | "" | React.CSSProperties; }) => "deleted" | "" | React.CSSProperties;
parentClassName?: string; parentClassName?: string;
tooltip?: any;
} }
const borderColor = "#9c9c9c80"; const borderColor = "#9c9c9c80";
@@ -465,6 +467,7 @@ const TableWrapper = ({
onSelectAll, onSelectAll,
rowStyle, rowStyle,
parentClassName = "", parentClassName = "",
tooltip,
}: TableWrapperProps) => { }: TableWrapperProps) => {
const navigate = useNavigate(); const navigate = useNavigate();
@@ -558,235 +561,249 @@ const TableWrapper = ({
return ( return (
<Grid item xs={12} className={parentClassName}> <Grid item xs={12} className={parentClassName}>
<Paper <TooltipWrapper tooltip={tooltip ? tooltip : ""}>
className={`${classes.paper} ${noBackground ? classes.noBackground : ""} <Paper
className={`${classes.paper} ${
noBackground ? classes.noBackground : ""
}
${disabled ? classes.disabled : ""} ${disabled ? classes.disabled : ""}
${ ${
customPaperHeight !== "" customPaperHeight !== ""
? customPaperHeight ? customPaperHeight
: classes.defaultPaperHeight : classes.defaultPaperHeight
}`} }`}
> >
{isLoading && ( {isLoading && (
<Grid container className={classes.loadingBox}> <Grid container className={classes.loadingBox}>
<Grid item xs={12} style={{ textAlign: "center" }}> <Grid item xs={12} style={{ textAlign: "center" }}>
{loadingMessage} {loadingMessage}
</Grid>
<Grid item xs={12}>
<LinearProgress />
</Grid>
</Grid> </Grid>
<Grid item xs={12}> )}
<LinearProgress /> {columnsSelector && !isLoading && records.length > 0 && (
</Grid> <div className={classes.overlayColumnSelection}>
</Grid> {columnsSelection(columns)}
)} </div>
{columnsSelector && !isLoading && records.length > 0 && ( )}
<div className={classes.overlayColumnSelection}> {records && !isLoading && records.length > 0 ? (
{columnsSelection(columns)} // @ts-ignore
</div> <InfiniteLoader
)} isRowLoaded={({ index }) => !!records[index]}
{records && !isLoading && records.length > 0 ? ( loadMoreRows={
// @ts-ignore infiniteScrollConfig
<InfiniteLoader ? infiniteScrollConfig.loadMoreRecords
isRowLoaded={({ index }) => !!records[index]} : () => new Promise(() => true)
loadMoreRows={ }
infiniteScrollConfig rowCount={
? infiniteScrollConfig.loadMoreRecords infiniteScrollConfig
: () => new Promise(() => true) ? infiniteScrollConfig.recordsCount
} : records.length
rowCount={ }
infiniteScrollConfig >
? infiniteScrollConfig.recordsCount {({ onRowsRendered, registerChild }) => (
: records.length // @ts-ignore
} <AutoSizer>
> {({ width, height }: any) => {
{({ onRowsRendered, registerChild }) => ( const optionsWidth = calculateOptionsSize(
// @ts-ignore width,
<AutoSizer> itemActions
{({ width, height }: any) => { ? itemActions.filter((el) => el.type !== "view").length
const optionsWidth = calculateOptionsSize( : 0
width, );
itemActions const hasSelect: boolean = !!(onSelect && selectedItems);
? itemActions.filter((el) => el.type !== "view").length const hasOptions: boolean = !!(
: 0 (itemActions && itemActions.length > 1) ||
); (itemActions &&
const hasSelect: boolean = !!(onSelect && selectedItems); itemActions.length === 1 &&
const hasOptions: boolean = !!( itemActions[0].type !== "view")
(itemActions && itemActions.length > 1) || );
(itemActions && return (
itemActions.length === 1 && // @ts-ignore
itemActions[0].type !== "view") <Table
); ref={registerChild}
return ( disableHeader={false}
// @ts-ignore headerClassName={"headerItem"}
<Table headerHeight={40}
ref={registerChild} height={height}
disableHeader={false} noRowsRenderer={() => (
headerClassName={"headerItem"} <Fragment>
headerHeight={40} {customEmptyMessage !== ""
height={height} ? customEmptyMessage
noRowsRenderer={() => ( : `There are no ${entityName} yet.`}
<Fragment> </Fragment>
{customEmptyMessage !== "" )}
? customEmptyMessage overscanRowCount={10}
: `There are no ${entityName} yet.`} rowHeight={40}
</Fragment> width={width}
)} rowCount={records.length}
overscanRowCount={10} rowGetter={({ index }) => records[index]}
rowHeight={40} onRowClick={({ rowData }) => {
width={width} clickAction(rowData);
rowCount={records.length} }}
rowGetter={({ index }) => records[index]} rowClassName={`rowLine ${findView ? "canClick" : ""} ${
onRowClick={({ rowData }) => { !findView && textSelectable ? "canSelectText" : ""
clickAction(rowData); }`}
}} onRowsRendered={onRowsRendered}
rowClassName={`rowLine ${findView ? "canClick" : ""} ${ sort={sortConfig ? sortConfig.triggerSort : undefined}
!findView && textSelectable ? "canSelectText" : "" sortBy={sortConfig ? sortConfig.currentSort : undefined}
}`} sortDirection={
onRowsRendered={onRowsRendered} sortConfig ? sortConfig.currentDirection : undefined
sort={sortConfig ? sortConfig.triggerSort : undefined} }
sortBy={sortConfig ? sortConfig.currentSort : undefined} scrollToIndex={
sortDirection={ autoScrollToBottom ? records.length - 1 : -1
sortConfig ? sortConfig.currentDirection : undefined }
} rowStyle={(r) => {
scrollToIndex={ if (rowStyle) {
autoScrollToBottom ? records.length - 1 : -1 const returnElement = rowStyle(r);
}
rowStyle={(r) => {
if (rowStyle) {
const returnElement = rowStyle(r);
if (typeof returnElement === "string") { if (typeof returnElement === "string") {
return get(TableRowPredefStyles, returnElement, {}); return get(
TableRowPredefStyles,
returnElement,
{}
);
}
return returnElement;
} }
return returnElement; return {};
} }}
>
{hasSelect && (
// @ts-ignore
<Column
headerRenderer={() => (
<Fragment>
{onSelectAll ? (
<div className={classes.checkAllWrapper}>
<CheckboxWrapper
label={""}
onChange={onSelectAll}
value="all"
id={"selectAll"}
name={"selectAll"}
checked={
selectedItems?.length === records.length
}
/>
</div>
) : (
<Fragment>Select</Fragment>
)}
</Fragment>
)}
dataKey={`select-${idField}`}
width={selectWidth}
disableSort
cellRenderer={({ rowData }) => {
const isSelected = selectedItems
? selectedItems.includes(
isString(rowData)
? rowData
: rowData[idField]
)
: false;
return {}; return (
}} <Checkbox
> value={
{hasSelect && ( isString(rowData)
// @ts-ignore ? rowData
<Column : rowData[idField]
headerRenderer={() => ( }
<Fragment> color="primary"
{onSelectAll ? ( inputProps={{
<div className={classes.checkAllWrapper}> "aria-label": "secondary checkbox",
<CheckboxWrapper }}
label={""} className="TableCheckbox"
onChange={onSelectAll} checked={isSelected}
value="all" onChange={onSelect}
id={"selectAll"} onClick={(e) => {
name={"selectAll"} e.stopPropagation();
checked={ }}
selectedItems?.length === records.length checkedIcon={
} <span
/> className={
</div> radioSelection
) : ( ? classes.radioSelectedIcon
<Fragment>Select</Fragment> : classes.checkedIcon
)} }
</Fragment> />
)} }
dataKey={`select-${idField}`} icon={
width={selectWidth} <span
disableSort className={
cellRenderer={({ rowData }) => { radioSelection
const isSelected = selectedItems ? classes.radioUnselectedIcon
? selectedItems.includes( : classes.unCheckedIcon
isString(rowData) ? rowData : rowData[idField] }
) />
: false; }
/>
return ( );
<Checkbox }}
value={ />
isString(rowData) ? rowData : rowData[idField] )}
} {generateColumnsMap(
color="primary" columns,
inputProps={{ width,
"aria-label": "secondary checkbox", optionsWidth,
}} hasSelect,
className="TableCheckbox" hasOptions,
checked={isSelected} selectedItems || [],
onChange={onSelect} idField,
onClick={(e) => { columnsSelector,
e.stopPropagation(); columnsShown,
}} sortConfig ? sortConfig.currentSort : "",
checkedIcon={ sortConfig ? sortConfig.currentDirection : undefined
<span )}
className={ {hasOptions && (
radioSelection // @ts-ignore
? classes.radioSelectedIcon <Column
: classes.checkedIcon dataKey={idField}
} width={optionsWidth}
/> headerClassName="optionsAlignment"
} className="optionsAlignment"
icon={ cellRenderer={({ rowData }) => {
<span const isSelected = selectedItems
className={ ? selectedItems.includes(
radioSelection isString(rowData)
? classes.radioUnselectedIcon ? rowData
: classes.unCheckedIcon : rowData[idField]
} )
/> : false;
} return elementActions(
/> itemActions || [],
); rowData,
}} isSelected,
/> idField
)} );
{generateColumnsMap( }}
columns, />
width, )}
optionsWidth, </Table>
hasSelect, );
hasOptions, }}
selectedItems || [], </AutoSizer>
idField, )}
columnsSelector, </InfiniteLoader>
columnsShown, ) : (
sortConfig ? sortConfig.currentSort : "", <Fragment>
sortConfig ? sortConfig.currentDirection : undefined {!isLoading && (
)} <div id={"empty-results"}>
{hasOptions && ( {customEmptyMessage !== ""
// @ts-ignore ? customEmptyMessage
<Column : `There are no ${entityName} yet.`}
dataKey={idField} </div>
width={optionsWidth} )}
headerClassName="optionsAlignment" </Fragment>
className="optionsAlignment" )}
cellRenderer={({ rowData }) => { </Paper>
const isSelected = selectedItems </TooltipWrapper>
? selectedItems.includes(
isString(rowData) ? rowData : rowData[idField]
)
: false;
return elementActions(
itemActions || [],
rowData,
isSelected,
idField
);
}}
/>
)}
</Table>
);
}}
</AutoSizer>
)}
</InfiniteLoader>
) : (
<Fragment>
{!isLoading && (
<div id={"empty-results"}>
{customEmptyMessage !== ""
? customEmptyMessage
: `There are no ${entityName} yet.`}
</div>
)}
</Fragment>
)}
</Paper>
</Grid> </Grid>
); );
}; };

View File

@@ -49,7 +49,12 @@ import SearchBox from "../Common/SearchBox";
import { import {
CONSOLE_UI_RESOURCE, CONSOLE_UI_RESOURCE,
IAM_PAGES, IAM_PAGES,
IAM_SCOPES, permissionTooltipHelper,
applyPolicyPermissions,
displayGroupsPermissions,
deleteGroupPermissions,
getGroupPermissions,
createGroupPermissions,
} from "../../../common/SecureComponent/permissions"; } from "../../../common/SecureComponent/permissions";
import { import {
hasPermission, hasPermission,
@@ -107,17 +112,23 @@ const Groups = ({ classes }: IGroupsProps) => {
isLoading(true); isLoading(true);
}, []); }, []);
const displayGroups = hasPermission(CONSOLE_UI_RESOURCE, [ const displayGroups = hasPermission(
IAM_SCOPES.ADMIN_LIST_GROUPS, CONSOLE_UI_RESOURCE,
]); displayGroupsPermissions
);
const deleteGroup = hasPermission(CONSOLE_UI_RESOURCE, [ const deleteGroup = hasPermission(
IAM_SCOPES.ADMIN_REMOVE_USER_FROM_GROUP, CONSOLE_UI_RESOURCE,
]); deleteGroupPermissions
);
const getGroup = hasPermission(CONSOLE_UI_RESOURCE, [ const getGroup = hasPermission(CONSOLE_UI_RESOURCE, getGroupPermissions);
IAM_SCOPES.ADMIN_GET_GROUP,
]); const applyPolicy = hasPermission(
CONSOLE_UI_RESOURCE,
applyPolicyPermissions,
true
);
const selectionChanged = (e: React.ChangeEvent<HTMLInputElement>) => { const selectionChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
const { target: { value = "", checked = false } = {} } = e; const { target: { value = "", checked = false } = {} } = e;
@@ -217,7 +228,7 @@ const Groups = ({ classes }: IGroupsProps) => {
<Grid item xs={12} className={classes.actionsTray}> <Grid item xs={12} className={classes.actionsTray}>
<SecureComponent <SecureComponent
resource={CONSOLE_UI_RESOURCE} resource={CONSOLE_UI_RESOURCE}
scopes={[IAM_SCOPES.ADMIN_LIST_GROUPS]} scopes={displayGroupsPermissions}
errorProps={{ disabled: true }} errorProps={{ disabled: true }}
> >
<SearchBox <SearchBox
@@ -234,11 +245,22 @@ const Groups = ({ classes }: IGroupsProps) => {
> >
<SecureComponent <SecureComponent
resource={CONSOLE_UI_RESOURCE} resource={CONSOLE_UI_RESOURCE}
scopes={[IAM_SCOPES.ADMIN_ATTACH_USER_OR_GROUP_POLICY]} scopes={applyPolicyPermissions}
matchAll matchAll
errorProps={{ disabled: true }} errorProps={{ disabled: true }}
> >
<TooltipWrapper tooltip={"Select Policy"}> <TooltipWrapper
tooltip={
checkedGroups.length < 1
? "Please select Groups on which you want to apply Policies"
: applyPolicy
? "Select Policy"
: permissionTooltipHelper(
applyPolicyPermissions,
"apply policies to Groups"
)
}
>
<Button <Button
id={"assign-policy"} id={"assign-policy"}
onClick={() => { onClick={() => {
@@ -246,18 +268,29 @@ const Groups = ({ classes }: IGroupsProps) => {
}} }}
label={"Assign Policy"} label={"Assign Policy"}
icon={<IAMPoliciesIcon />} icon={<IAMPoliciesIcon />}
disabled={checkedGroups.length < 1} disabled={checkedGroups.length < 1 || !applyPolicy}
variant={"regular"} variant={"regular"}
/> />
</TooltipWrapper> </TooltipWrapper>
</SecureComponent> </SecureComponent>
<SecureComponent <SecureComponent
resource={CONSOLE_UI_RESOURCE} resource={CONSOLE_UI_RESOURCE}
scopes={[IAM_SCOPES.ADMIN_REMOVE_USER_FROM_GROUP]} scopes={deleteGroupPermissions}
matchAll matchAll
errorProps={{ disabled: true }} errorProps={{ disabled: true }}
> >
<TooltipWrapper tooltip={"Delete Selected"}> <TooltipWrapper
tooltip={
checkedGroups.length === 0
? "Select Groups to delete"
: getGroup
? "Delete Selected"
: permissionTooltipHelper(
getGroupPermissions,
"delete Groups"
)
}
>
<Button <Button
id="delete-selected-groups" id="delete-selected-groups"
onClick={() => { onClick={() => {
@@ -266,16 +299,13 @@ const Groups = ({ classes }: IGroupsProps) => {
label={"Delete Selected"} label={"Delete Selected"}
icon={<DeleteIcon />} icon={<DeleteIcon />}
variant="secondary" variant="secondary"
disabled={checkedGroups.length === 0} disabled={checkedGroups.length === 0 || !getGroup}
/> />
</TooltipWrapper> </TooltipWrapper>
</SecureComponent> </SecureComponent>
<SecureComponent <SecureComponent
resource={CONSOLE_UI_RESOURCE} resource={CONSOLE_UI_RESOURCE}
scopes={[ scopes={createGroupPermissions}
IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP,
IAM_SCOPES.ADMIN_LIST_USERS,
]}
matchAll matchAll
errorProps={{ disabled: true }} errorProps={{ disabled: true }}
> >
@@ -298,24 +328,37 @@ const Groups = ({ classes }: IGroupsProps) => {
<Fragment> <Fragment>
{records.length > 0 && ( {records.length > 0 && (
<Fragment> <Fragment>
<Grid item xs={12} className={classes.tableBlock}> <TooltipWrapper
<SecureComponent tooltip={
resource={CONSOLE_UI_RESOURCE} getGroup
scopes={[IAM_SCOPES.ADMIN_LIST_GROUPS]} ? ""
errorProps={{ disabled: true }} : permissionTooltipHelper(
> getGroupPermissions,
<TableWrapper "view Group details"
itemActions={tableActions} )
columns={[{ label: "Name", elementKey: "" }]} }
isLoading={loading} >
selectedItems={checkedGroups} <Grid item xs={12} className={classes.tableBlock}>
onSelect={deleteGroup ? selectionChanged : undefined} <SecureComponent
records={filteredRecords} resource={CONSOLE_UI_RESOURCE}
entityName="Groups" scopes={displayGroupsPermissions}
idField="" errorProps={{ disabled: true }}
/> >
</SecureComponent> <TableWrapper
</Grid> itemActions={tableActions}
columns={[{ label: "Name", elementKey: "" }]}
isLoading={loading}
selectedItems={checkedGroups}
onSelect={
deleteGroup || getGroup ? selectionChanged : undefined
}
records={filteredRecords}
entityName="Groups"
idField=""
/>
</SecureComponent>
</Grid>
</TooltipWrapper>
<Grid item xs={12} marginTop={"25px"}> <Grid item xs={12} marginTop={"25px"}>
<HelpBox <HelpBox
title={"Groups"} title={"Groups"}
@@ -362,10 +405,7 @@ const Groups = ({ classes }: IGroupsProps) => {
permissions on the MinIO Tenant. permissions on the MinIO Tenant.
<SecureComponent <SecureComponent
resource={CONSOLE_UI_RESOURCE} resource={CONSOLE_UI_RESOURCE}
scopes={[ scopes={createGroupPermissions}
IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP,
IAM_SCOPES.ADMIN_LIST_USERS,
]}
matchAll matchAll
> >
<br /> <br />

View File

@@ -32,9 +32,18 @@ import PageLayout from "../Common/Layout/PageLayout";
import PanelTitle from "../Common/PanelTitle/PanelTitle"; import PanelTitle from "../Common/PanelTitle/PanelTitle";
import SearchBox from "../Common/SearchBox"; import SearchBox from "../Common/SearchBox";
import { import {
addUserToGroupPermissions,
CONSOLE_UI_RESOURCE, CONSOLE_UI_RESOURCE,
createGroupPermissions,
editGroupMembersPermissions,
enableDisableGroupPermissions,
getGroupPermissions,
IAM_PAGES, IAM_PAGES,
IAM_SCOPES, listUsersPermissions,
permissionTooltipHelper,
setGroupPoliciesPermissions,
viewPolicyPermissions,
viewUserPermissions,
} from "../../../common/SecureComponent/permissions"; } from "../../../common/SecureComponent/permissions";
import { import {
hasPermission, hasPermission,
@@ -130,6 +139,12 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
elementItem.includes(memberFilter) elementItem.includes(memberFilter)
); );
const viewUser = hasPermission(
CONSOLE_UI_RESOURCE,
viewUserPermissions,
true
);
useEffect(() => { useEffect(() => {
if (groupName) { if (groupName) {
fetchGroupInfo(); fetchGroupInfo();
@@ -141,9 +156,28 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
const isGroupEnabled = groupEnabled === "enabled"; const isGroupEnabled = groupEnabled === "enabled";
const memberActionText = members.length > 0 ? "Edit Members" : "Add Members"; const memberActionText = members.length > 0 ? "Edit Members" : "Add Members";
const getGroupDetails = hasPermission(CONSOLE_UI_RESOURCE, [ const getGroupDetails = hasPermission(
IAM_SCOPES.ADMIN_GET_GROUP, CONSOLE_UI_RESOURCE,
]); getGroupPermissions
);
const canEditGroupMembers = hasPermission(
CONSOLE_UI_RESOURCE,
editGroupMembersPermissions,
true
);
const canSetPolicies = hasPermission(
CONSOLE_UI_RESOURCE,
setGroupPoliciesPermissions,
true
);
const canViewPolicy = hasPermission(
CONSOLE_UI_RESOURCE,
viewPolicyPermissions,
true
);
function fetchGroupInfo() { function fetchGroupInfo() {
if (getGroupDetails) { if (getGroupDetails) {
@@ -188,10 +222,19 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
/> />
<SecureComponent <SecureComponent
resource={CONSOLE_UI_RESOURCE} resource={CONSOLE_UI_RESOURCE}
scopes={[IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP]} scopes={addUserToGroupPermissions}
errorProps={{ disabled: true }} errorProps={{ disabled: true }}
> >
<TooltipWrapper tooltip={memberActionText}> <TooltipWrapper
tooltip={
canEditGroupMembers
? memberActionText
: permissionTooltipHelper(
createGroupPermissions,
"edit Group membership"
)
}
>
<Button <Button
id={"add-user-group"} id={"add-user-group"}
label={memberActionText} label={memberActionText}
@@ -200,6 +243,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
onClick={() => { onClick={() => {
setUsersOpen(true); setUsersOpen(true);
}} }}
disabled={!canEditGroupMembers}
/> />
</TooltipWrapper> </TooltipWrapper>
</SecureComponent> </SecureComponent>
@@ -208,7 +252,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
<div className={classes.tableBlock}> <div className={classes.tableBlock}>
<SecureComponent <SecureComponent
resource={CONSOLE_UI_RESOURCE} resource={CONSOLE_UI_RESOURCE}
scopes={[IAM_SCOPES.ADMIN_LIST_USERS]} scopes={listUsersPermissions}
errorProps={{ disabled: true }} errorProps={{ disabled: true }}
> >
<TableWrapper <TableWrapper
@@ -218,6 +262,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
onClick: (userName) => { onClick: (userName) => {
navigate(`${IAM_PAGES.USERS}/${encodeURLString(userName)}`); navigate(`${IAM_PAGES.USERS}/${encodeURLString(userName)}`);
}, },
disableButtonFunction: () => !viewUser,
}, },
]} ]}
columns={[{ label: "Access Key", elementKey: "" }]} columns={[{ label: "Access Key", elementKey: "" }]}
@@ -226,6 +271,14 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
records={filteredMembers} records={filteredMembers}
entityName="Users" entityName="Users"
idField="" idField=""
tooltip={
viewUser
? ""
: permissionTooltipHelper(
viewUserPermissions,
"view User details"
)
}
/> />
</SecureComponent> </SecureComponent>
</div> </div>
@@ -236,7 +289,16 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
<React.Fragment> <React.Fragment>
<div className={classes.actionsTray}> <div className={classes.actionsTray}>
<PanelTitle>Policies</PanelTitle> <PanelTitle>Policies</PanelTitle>
<TooltipWrapper tooltip={"Set Policies"}> <TooltipWrapper
tooltip={
canSetPolicies
? "Set Policies"
: permissionTooltipHelper(
setGroupPoliciesPermissions,
"assign Policies"
)
}
>
<Button <Button
id={"set-policies"} id={"set-policies"}
label={`Set Policies`} label={`Set Policies`}
@@ -245,6 +307,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
onClick={() => { onClick={() => {
setPolicyOpen(true); setPolicyOpen(true);
}} }}
disabled={!canSetPolicies}
/> />
</TooltipWrapper> </TooltipWrapper>
</div> </div>
@@ -256,6 +319,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
onClick: (policy) => { onClick: (policy) => {
navigate(`${IAM_PAGES.POLICIES}/${encodeURLString(policy)}`); navigate(`${IAM_PAGES.POLICIES}/${encodeURLString(policy)}`);
}, },
disableButtonFunction: () => !canViewPolicy,
}, },
]} ]}
columns={[{ label: "Policy", elementKey: "" }]} columns={[{ label: "Policy", elementKey: "" }]}
@@ -263,6 +327,14 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
records={groupPolicies} records={groupPolicies}
entityName="Policies" entityName="Policies"
idField="" idField=""
tooltip={
canViewPolicy
? ""
: permissionTooltipHelper(
viewPolicyPermissions,
"view Policy details"
)
}
/> />
</div> </div>
</React.Fragment> </React.Fragment>
@@ -287,46 +359,52 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
<span id="group-status" className={classes.statusValue}> <span id="group-status" className={classes.statusValue}>
{isGroupEnabled ? "Enabled" : "Disabled"} {isGroupEnabled ? "Enabled" : "Disabled"}
</span> </span>
<SecureComponent <TooltipWrapper
resource={CONSOLE_UI_RESOURCE} tooltip={
scopes={[ hasPermission(
IAM_SCOPES.ADMIN_ENABLE_GROUP, CONSOLE_UI_RESOURCE,
IAM_SCOPES.ADMIN_DISABLE_GROUP, enableDisableGroupPermissions,
]} true
errorProps={{ disabled: true }} )
matchAll ? ""
: permissionTooltipHelper(
enableDisableGroupPermissions,
"enable or disable Groups"
)
}
> >
<FormSwitchWrapper <SecureComponent
indicatorLabels={["Enabled", "Disabled"]} resource={CONSOLE_UI_RESOURCE}
checked={isGroupEnabled} scopes={enableDisableGroupPermissions}
value={"group_enabled"} errorProps={{ disabled: true }}
id="group-status" matchAll
name="group-status" >
onChange={() => { <FormSwitchWrapper
toggleGroupStatus(!isGroupEnabled); indicatorLabels={["Enabled", "Disabled"]}
}} checked={isGroupEnabled}
switchOnly value={"group_enabled"}
/> id="group-status"
</SecureComponent> name="group-status"
onChange={() => {
toggleGroupStatus(!isGroupEnabled);
}}
switchOnly
/>
</SecureComponent>
</TooltipWrapper>
<SecureComponent <div className={classes.spacerLeft}>
resource={CONSOLE_UI_RESOURCE} <TooltipWrapper tooltip={"Delete Group"}>
scopes={[IAM_SCOPES.ADMIN_REMOVE_USER_FROM_GROUP]} <Button
errorProps={{ disabled: true }} id={"delete-user-group"}
> variant="secondary"
<div className={classes.spacerLeft}> icon={<TrashIcon />}
<TooltipWrapper tooltip={"Delete Group"}> onClick={() => {
<Button setDeleteOpen(true);
id={"delete-user-group"} }}
variant="secondary" />
icon={<TrashIcon />} </TooltipWrapper>
onClick={() => { </div>
setDeleteOpen(true);
}}
/>
</TooltipWrapper>
</div>
</SecureComponent>
</Fragment> </Fragment>
} }
/> />