read-only users in role tab
This commit is contained in:
parent
88711202ef
commit
8ead0d0fff
4 changed files with 70 additions and 180 deletions
|
@ -190,7 +190,6 @@ export const AssociatedRolesTab = ({
|
||||||
onSelect={(rows) => {
|
onSelect={(rows) => {
|
||||||
setSelectedRows([...rows]);
|
setSelectedRows([...rows]);
|
||||||
}}
|
}}
|
||||||
isPaginated
|
|
||||||
toolbarItem={
|
toolbarItem={
|
||||||
<>
|
<>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|
|
@ -170,7 +170,8 @@ export const RealmRoleTabs = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(role)
|
|
||||||
|
|
||||||
const addComposites = async (composites: Composites[]): Promise<void> => {
|
const addComposites = async (composites: Composites[]): Promise<void> => {
|
||||||
const compositeArray = composites;
|
const compositeArray = composites;
|
||||||
setAdditionalRoles([...additionalRoles, ...compositeArray]);
|
setAdditionalRoles([...additionalRoles, ...compositeArray]);
|
||||||
|
@ -342,13 +343,7 @@ export const RealmRoleTabs = () => {
|
||||||
eventKey="users-in-role"
|
eventKey="users-in-role"
|
||||||
title={<TabTitleText>{t("usersInRole")}</TabTitleText>}
|
title={<TabTitleText>{t("usersInRole")}</TabTitleText>}
|
||||||
>
|
>
|
||||||
<UsersInRoleTab
|
<UsersInRoleTab />
|
||||||
roleName={role}
|
|
||||||
// form={form}
|
|
||||||
// save={save}
|
|
||||||
// array={{ fields, append, remove }}
|
|
||||||
// reset={() => form.reset(role)}
|
|
||||||
/>
|
|
||||||
</Tab>
|
</Tab>
|
||||||
</KeycloakTabs>
|
</KeycloakTabs>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,192 +1,79 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { useHistory, useParams, useRouteMatch } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import { PageSection } from "@patternfly/react-core";
|
||||||
AlertVariant,
|
|
||||||
Button,
|
|
||||||
ButtonVariant,
|
|
||||||
Checkbox,
|
|
||||||
PageSection,
|
|
||||||
} from "@patternfly/react-core";
|
|
||||||
import RoleRepresentation from "keycloak-admin/lib/defs/roleRepresentation";
|
|
||||||
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||||
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||||
import { formattedLinkTableCell } from "../components/external-link/FormattedLink";
|
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
|
||||||
import { boolFormatter, emptyFormatter } from "../util";
|
import { boolFormatter, emptyFormatter } from "../util";
|
||||||
import { AssociatedRolesModal } from "./AssociatedRolesModal";
|
|
||||||
import { useAdminClient } from "../context/auth/AdminClient";
|
import { useAdminClient } from "../context/auth/AdminClient";
|
||||||
|
import UserRepresentation from "keycloak-admin/lib/defs/userRepresentation";
|
||||||
|
|
||||||
type UsersInRoleTabProps = {
|
export const UsersInRoleTab = () => {
|
||||||
roleName: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export const UsersInRoleTab = ({roleName}: UsersInRoleTabProps) => {
|
|
||||||
const { t } = useTranslation("roles");
|
const { t } = useTranslation("roles");
|
||||||
const history = useHistory();
|
|
||||||
const { addAlert } = useAlerts();
|
|
||||||
const { url } = useRouteMatch();
|
|
||||||
const tableRefresher = React.useRef<() => void>();
|
|
||||||
|
|
||||||
const [selectedRows, setSelectedRows] = useState<RoleRepresentation[]>([]);
|
const [users, setUsers] = useState<UserRepresentation[]>([]);
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
|
|
||||||
// console.log(role);
|
const { id } = useParams<{ id: string }>();
|
||||||
|
|
||||||
const adminClient = useAdminClient();
|
const adminClient = useAdminClient();
|
||||||
const { id } = useParams<{ id: string; clientId: string }>();
|
|
||||||
|
|
||||||
const loader = async () => {
|
const loader = async () => {
|
||||||
const beep = await adminClient.roles.findUsersWithRole({name: "admin"})
|
const role = await adminClient.roles.findOneById({ id: id });
|
||||||
console.log(beep);
|
const usersWithRole = await adminClient.roles.findUsersWithRole({
|
||||||
if (!beep) {
|
name: role.name!,
|
||||||
console.log("lalala");
|
});
|
||||||
}
|
setUsers(usersWithRole);
|
||||||
else return beep;
|
return usersWithRole;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loader();
|
||||||
|
}, []);
|
||||||
|
|
||||||
loader();
|
|
||||||
|
|
||||||
// const RoleName = (role: RoleRepresentation) => <>{role.name}</>;
|
|
||||||
|
|
||||||
const toggleModal = () => setOpen(!open);
|
|
||||||
|
|
||||||
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
|
|
||||||
titleKey: "roles:roleRemoveAssociatedRoleConfirm",
|
|
||||||
messageKey: t("roles:roleRemoveAssociatedText"),
|
|
||||||
continueButtonLabel: "common:delete",
|
|
||||||
continueButtonVariant: ButtonVariant.danger,
|
|
||||||
onConfirm: async () => {
|
|
||||||
try {
|
|
||||||
await adminClient.roles.delCompositeRoles({ id }, selectedRows);
|
|
||||||
setSelectedRows([]);
|
|
||||||
|
|
||||||
addAlert(t("associatedRolesRemoved"), AlertVariant.success);
|
|
||||||
} catch (error) {
|
|
||||||
addAlert(t("roleDeleteError", { error }), AlertVariant.danger);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// const [
|
|
||||||
// toggleDeleteAssociatedRolesDialog,
|
|
||||||
// DeleteAssociatedRolesConfirm,
|
|
||||||
// ] = useConfirmDialog({
|
|
||||||
// titleKey: t("roles:removeAssociatedRoles") + "?",
|
|
||||||
// messageKey: t("roles:removeAllAssociatedRolesConfirmDialog", {
|
|
||||||
// name: parentRole?.name || t("createRole"),
|
|
||||||
// }),
|
|
||||||
// continueButtonLabel: "common:delete",
|
|
||||||
// continueButtonVariant: ButtonVariant.danger,
|
|
||||||
// onConfirm: async () => {
|
|
||||||
// try {
|
|
||||||
// if (selectedRows.length === additionalRoles.length) {
|
|
||||||
// onRemove(selectedRows);
|
|
||||||
// const loc = url.replace(/\/AssociatedRoles/g, "/details");
|
|
||||||
// history.push(loc);
|
|
||||||
// }
|
|
||||||
// onRemove(selectedRows);
|
|
||||||
// await adminClient.roles.delCompositeRoles({ id }, selectedRows);
|
|
||||||
// addAlert(t("associatedRolesRemoved"), AlertVariant.success);
|
|
||||||
// } catch (error) {
|
|
||||||
// addAlert(`${t("roleDeleteError")} ${error}`, AlertVariant.danger);
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
|
|
||||||
const setRefresher = (refresher: () => void) => {
|
|
||||||
tableRefresher.current = refresher;
|
|
||||||
};
|
|
||||||
|
|
||||||
const goToCreate = () => history.push(`${url}/add-role`);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
<DeleteConfirm />
|
{users.length == 0 ? (
|
||||||
{/* <DeleteAssociatedRolesConfirm />
|
<ListEmptyState
|
||||||
<AssociatedRolesModal
|
hasIcon={true}
|
||||||
// onConfirm={addComposites}
|
message={t("noDirectUsers")}
|
||||||
existingCompositeRoles={additionalRoles}
|
instructions={t("noUsersEmptyStateDescription")}
|
||||||
open={open}
|
primaryActionText={t("addUser")}
|
||||||
toggleDialog={() => setOpen(!open)}
|
/>
|
||||||
/> */}
|
) : (
|
||||||
<KeycloakDataTable
|
<KeycloakDataTable
|
||||||
loader={loader}
|
loader={loader}
|
||||||
ariaLabelKey="roles:roleList"
|
ariaLabelKey="roles:roleList"
|
||||||
searchPlaceholderKey="roles:searchFor"
|
searchPlaceholderKey=""
|
||||||
canSelectAll
|
columns={[
|
||||||
// onSelect={(rows) => {
|
{
|
||||||
// setSelectedRows([...rows]);
|
name: "id",
|
||||||
// }}
|
displayKey: "roles:id",
|
||||||
isPaginated
|
cellFormatters: [emptyFormatter()],
|
||||||
setRefresher={setRefresher}
|
|
||||||
toolbarItem={
|
|
||||||
<>
|
|
||||||
<Checkbox
|
|
||||||
label="Hide inherited roles"
|
|
||||||
key="associated-roles-check"
|
|
||||||
id="kc-hide-inherited-roles-checkbox"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
className="kc-add-role-button"
|
|
||||||
key="add-role-button"
|
|
||||||
onClick={() => toggleModal()}
|
|
||||||
data-cy="add-role-button"
|
|
||||||
>
|
|
||||||
{t("addRole")}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="link"
|
|
||||||
isDisabled={selectedRows.length == 0}
|
|
||||||
key="remove-role-button"
|
|
||||||
onClick={() => {
|
|
||||||
// toggleDeleteAssociatedRolesDialog();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t("removeRoles")}
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
actions={[
|
|
||||||
{
|
|
||||||
title: t("common:remove"),
|
|
||||||
onRowClick: (role) => {
|
|
||||||
// setSelectedRows([role]);
|
|
||||||
toggleDeleteDialog();
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
]}
|
name: "username",
|
||||||
columns={[
|
displayKey: "roles:userName",
|
||||||
{
|
cellFormatters: [emptyFormatter()],
|
||||||
name: "name",
|
},
|
||||||
displayKey: "roles:roleName",
|
{
|
||||||
// cellRenderer: RoleName,
|
name: "email",
|
||||||
cellFormatters: [formattedLinkTableCell(), emptyFormatter()],
|
displayKey: "roles:email",
|
||||||
},
|
cellFormatters: [emptyFormatter()],
|
||||||
{
|
},
|
||||||
name: "inherited from",
|
{
|
||||||
displayKey: "roles:inheritedFrom",
|
name: "lastName",
|
||||||
cellFormatters: [boolFormatter(), emptyFormatter()],
|
displayKey: "roles:lastName",
|
||||||
},
|
cellFormatters: [emptyFormatter()],
|
||||||
{
|
},
|
||||||
name: "description",
|
{
|
||||||
displayKey: "common:description",
|
name: "firstName",
|
||||||
cellFormatters: [emptyFormatter()],
|
displayKey: "roles:firstName",
|
||||||
},
|
cellFormatters: [boolFormatter(), emptyFormatter()],
|
||||||
]}
|
},
|
||||||
emptyState={
|
]}
|
||||||
<ListEmptyState
|
/>
|
||||||
hasIcon={true}
|
)}
|
||||||
message={t("noRolesInThisRealm")}
|
|
||||||
instructions={t("noRolesInThisRealmInstructions")}
|
|
||||||
primaryActionText={t("createRole")}
|
|
||||||
onPrimaryAction={goToCreate}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</PageSection>
|
</PageSection>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -49,7 +49,16 @@
|
||||||
"compositeRoleOff": "Composite role turned off",
|
"compositeRoleOff": "Composite role turned off",
|
||||||
"associatedRolesRemoved": "Associated roles have been removed",
|
"associatedRolesRemoved": "Associated roles have been removed",
|
||||||
"compositesRemovedAlertDescription": "All the associated roles have been removed",
|
"compositesRemovedAlertDescription": "All the associated roles have been removed",
|
||||||
"usersInRole": "Users in role"
|
"usersInRole": "Users in role",
|
||||||
|
"addUser": "Add user",
|
||||||
|
"removeUser": "Remove users",
|
||||||
|
"removeUserText": "Do you want to remove {{numSelected}} users?. These users will no longer have permissions of the role {{role}} and the associated roles of it.",
|
||||||
|
"noDirectUsers": "No direct users",
|
||||||
|
"noUsersEmptyStateDescription": "Only the users with this role directly assigned will appear under this tab. If you need to find users assigned to this role, you can go to Groups or Users to find them. Users that already have this role as an effective role cannot be added here.",
|
||||||
|
"id": "ID",
|
||||||
|
"userName": "Username",
|
||||||
|
"email": "Email",
|
||||||
|
"lastName": "Last name",
|
||||||
|
"firstName": "First name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue