Skip to content

Commit

Permalink
Fix #2874Support ability to select a role as default from the UI (#3145)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sachin-chaurasiya committed Mar 4, 2022
1 parent bd7b91b commit 13e24c5
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,9 @@ export const updateUser = (
): Promise<AxiosResponse> => {
return APIClient.put('/users', data);
};

export const getUserCounts = () => {
return APIClient.get(
'/search/query?q=*&from=0&size=0&index=user_search_index'
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { Button } from '../../buttons/Button/Button';
type Props = {
cancelText: string | ReactNode;
confirmText: string | ReactNode;
bodyText: string;
bodyText: string | ReactNode;
header: string;
headerClassName?: string;
bodyClassName?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
updatePolicy,
updateRole,
} from '../../axiosAPIs/rolesAPI';
import { getUserCounts } from '../../axiosAPIs/userAPI';
import { Button } from '../../components/buttons/Button/Button';
import Description from '../../components/common/description/Description';
import ErrorPlaceHolder from '../../components/common/error-with-placeholder/ErrorPlaceHolder';
Expand Down Expand Up @@ -83,6 +84,12 @@ const RolesPage = () => {
state: boolean;
}>({ rule: undefined, state: false });

const [isSettingDefaultRole, setIsSettingDefaultRole] =
useState<boolean>(false);
const [userCounts, setUserCounts] = useState<number>(0);

const [defaultRole, setDefaultRole] = useState<Role>();

const onNewDataChange = (data: Role, forceSet = false) => {
if (errorData || forceSet) {
const errData: { [key: string]: string } = {};
Expand Down Expand Up @@ -156,6 +163,7 @@ const RolesPage = () => {
.then((res: AxiosResponse) => {
const { data } = res.data;
setRoles(data);
setDefaultRole(data.find((role: Role) => role.default));
setCurrentRole(data[0]);
AppState.updateUserRole(data);
})
Expand Down Expand Up @@ -201,6 +209,15 @@ const RolesPage = () => {
getRoleByName(name, ['users', 'policy'])
.then((res: AxiosResponse) => {
setCurrentRole(res.data);
setRoles((pre) => {
return pre.map((role) => {
if (role.id === res.data.id) {
return { ...res.data };
} else {
return role;
}
});
});
if (roles.length <= 0) {
fetchRoles();
}
Expand Down Expand Up @@ -234,6 +251,42 @@ const RolesPage = () => {
}
};

const startSetDefaultRole = () => {
setIsSettingDefaultRole(true);
};

const cancelSetDefaultRole = () => {
setIsSettingDefaultRole(false);
};

const onSetDefaultRole = () => {
if (isSettingDefaultRole) {
const updatedRole = { ...currentRole, default: true };
const jsonPatch = compare(currentRole as Role, updatedRole);
updateRole(currentRole?.id as string, jsonPatch)
.then((res: AxiosResponse) => {
if (res.data) {
fetchCurrentRole(res.data.name, true);
setRoles((pre) => {
return pre.map((role) => ({
...role,
default: false,
}));
});
}
})
.catch(() => {
showToast({
variant: 'error',
body: 'Error while setting role as default.',
});
})
.finally(() => {
cancelSetDefaultRole();
});
}
};

const createRule = (data: Rule) => {
const errData = validateRuleData(data, true);
if (!Object.values(errData).length) {
Expand Down Expand Up @@ -314,6 +367,18 @@ const RolesPage = () => {
});
};

const getDefaultBadge = (className?: string) => {
return (
<span
className={classNames(
'tw-border tw-border-grey-muted tw-rounded tw-px-1 tw-font-normal',
className
)}>
Default
</span>
);
};

const getTabs = () => {
return (
<div className="tw-mb-3 ">
Expand Down Expand Up @@ -347,7 +412,7 @@ const RolesPage = () => {
);
};

const fetchLeftPanel = () => {
const fetchLeftPanel = (roles: Array<Role>) => {
return (
<>
<div className="tw-flex tw-justify-between tw-items-center tw-mb-3 tw-border-b">
Expand Down Expand Up @@ -386,8 +451,9 @@ const RolesPage = () => {
<p
className="tag-category label-category tw-self-center tw-truncate tw-w-52"
title={role.displayName}>
{role.displayName}
<span>{role.displayName}</span>{' '}
</p>
{role.default ? getDefaultBadge() : null}
</div>
))}
</>
Expand Down Expand Up @@ -510,8 +576,22 @@ const RolesPage = () => {
);
};

const fetchUserCounts = () => {
getUserCounts()
.then((res: AxiosResponse) => {
setUserCounts(res.data.hits.total.value);
})
.catch(() => {
showToast({
variant: 'error',
body: 'Error while getting users count.',
});
});
};

useEffect(() => {
fetchRoles();
fetchUserCounts();
}, []);

useEffect(() => {
Expand All @@ -526,7 +606,7 @@ const RolesPage = () => {
<ErrorPlaceHolder />
) : (
<PageContainerV1 className="tw-py-4">
<PageLayout leftPanel={fetchLeftPanel()}>
<PageLayout leftPanel={fetchLeftPanel(roles)}>
{isLoading ? (
<Loader />
) : (
Expand All @@ -540,25 +620,51 @@ const RolesPage = () => {
className="tw-heading tw-text-link tw-text-base"
data-testid="header-title">
{currentRole?.displayName}
{currentRole?.default
? getDefaultBadge('tw-ml-2')
: null}
</div>
<div className="tw-flex">
{!currentRole?.default ? (
<NonAdminAction
position="bottom"
title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button
className={classNames(
'tw-h-8 tw-rounded tw-mb-3 tw-mr-2',
{
'tw-opacity-40':
!isAdminUser && !isAuthDisabled,
}
)}
data-testid="set-as-default-button"
size="small"
theme="primary"
variant="contained"
onClick={startSetDefaultRole}>
Set as default
</Button>
</NonAdminAction>
) : null}
<NonAdminAction
position="bottom"
title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button
className={classNames('tw-h-8 tw-rounded tw-mb-3', {
'tw-opacity-40': !isAdminUser && !isAuthDisabled,
})}
data-testid="add-new-rule-button"
size="small"
theme="primary"
variant="contained"
onClick={() => {
setErrorData(undefined);
setIsAddingRule(true);
}}>
Add new rule
</Button>
</NonAdminAction>
</div>
<NonAdminAction
position="bottom"
title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button
className={classNames('tw-h-8 tw-rounded tw-mb-3', {
'tw-opacity-40': !isAdminUser && !isAuthDisabled,
})}
data-testid="add-new-rule-button"
size="small"
theme="primary"
variant="contained"
onClick={() => {
setErrorData(undefined);
setIsAddingRule(true);
}}>
Add new rule
</Button>
</NonAdminAction>
</div>
<div
className="tw-mb-3 tw--ml-5"
Expand Down Expand Up @@ -663,6 +769,29 @@ const RolesPage = () => {
}}
/>
)}

{isSettingDefaultRole && (
<ConfirmationModal
bodyText={
<Fragment>
{userCounts} users will be assigned{' '}
<span className="tw-font-medium">
{currentRole?.displayName ?? currentRole?.name}
</span>{' '}
role and unassigned{' '}
<span className="tw-font-medium">
{defaultRole?.displayName ?? defaultRole?.name}
</span>{' '}
role.`
</Fragment>
}
cancelText="Cancel"
confirmText="Confirm"
header={`Set ${currentRole?.name} as default role`}
onCancel={cancelSetDefaultRole}
onConfirm={onSetDefaultRole}
/>
)}
</div>
)}
</PageLayout>
Expand Down

0 comments on commit 13e24c5

Please sign in to comment.