Merge pull request #401 from jenny-s51/usersInRole
Realm roles: add "users in role" tab
This commit is contained in:
commit
9c1efdcc3b
11 changed files with 273 additions and 44 deletions
|
@ -4,6 +4,7 @@ import ModalUtils from "../support/util/ModalUtils";
|
||||||
import ListingPage from "../support/pages/admin_console/ListingPage";
|
import ListingPage from "../support/pages/admin_console/ListingPage";
|
||||||
import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
||||||
import CreateRealmRolePage from "../support/pages/admin_console/manage/realm_roles/CreateRealmRolePage";
|
import CreateRealmRolePage from "../support/pages/admin_console/manage/realm_roles/CreateRealmRolePage";
|
||||||
|
import AssociatedRolesPage from "../support/pages/admin_console/manage/realm_roles/AssociatedRolesPage";
|
||||||
|
|
||||||
let itemId = "realm_role_crud";
|
let itemId = "realm_role_crud";
|
||||||
const loginPage = new LoginPage();
|
const loginPage = new LoginPage();
|
||||||
|
@ -12,6 +13,7 @@ const modalUtils = new ModalUtils();
|
||||||
const sidebarPage = new SidebarPage();
|
const sidebarPage = new SidebarPage();
|
||||||
const listingPage = new ListingPage();
|
const listingPage = new ListingPage();
|
||||||
const createRealmRolePage = new CreateRealmRolePage();
|
const createRealmRolePage = new CreateRealmRolePage();
|
||||||
|
const associatedRolesPage = new AssociatedRolesPage();
|
||||||
|
|
||||||
describe("Realm roles test", function () {
|
describe("Realm roles test", function () {
|
||||||
describe("Realm roles creation", function () {
|
describe("Realm roles creation", function () {
|
||||||
|
@ -48,7 +50,7 @@ describe("Realm roles test", function () {
|
||||||
|
|
||||||
listingPage.searchItem(itemId).itemExist(itemId);
|
listingPage.searchItem(itemId).itemExist(itemId);
|
||||||
|
|
||||||
// Update
|
cy.wait(100);
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
listingPage.deleteItem(itemId);
|
listingPage.deleteItem(itemId);
|
||||||
|
@ -70,40 +72,15 @@ describe("Realm roles test", function () {
|
||||||
|
|
||||||
masthead.checkNotificationMessage("Role created");
|
masthead.checkNotificationMessage("Role created");
|
||||||
|
|
||||||
|
cy.wait(100);
|
||||||
|
|
||||||
// Add associated realm role
|
// Add associated realm role
|
||||||
cy.get("#roles-actions-dropdown").last().click();
|
|
||||||
|
|
||||||
cy.get("#add-roles").click();
|
associatedRolesPage.addAssociatedRealmRole();
|
||||||
|
|
||||||
cy.wait(100);
|
|
||||||
|
|
||||||
cy.get('[type="checkbox"]').eq(1).check();
|
|
||||||
|
|
||||||
cy.get("#add-associated-roles-button").contains("Add").click();
|
|
||||||
|
|
||||||
cy.url().should("include", "/AssociatedRoles");
|
|
||||||
|
|
||||||
cy.get("#composite-role-badge").should("contain.text", "Composite");
|
|
||||||
|
|
||||||
cy.wait(100);
|
|
||||||
|
|
||||||
// Add associated client role
|
// Add associated client role
|
||||||
|
|
||||||
cy.get('[data-cy=add-role-button]').click();
|
associatedRolesPage.addAssociatedClientRole();
|
||||||
|
|
||||||
cy.wait(100);
|
|
||||||
|
|
||||||
cy.get('[data-cy=filter-type-dropdown]').click()
|
|
||||||
|
|
||||||
cy.get('[data-cy=filter-type-dropdown-item]').click()
|
|
||||||
|
|
||||||
cy.wait(2500);
|
|
||||||
|
|
||||||
cy.get('[type="checkbox"]').eq(40).check({force: true});
|
|
||||||
|
|
||||||
cy.get("#add-associated-roles-button").contains("Add").click();
|
|
||||||
|
|
||||||
cy.wait(2500);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
export default class AssociatedRolesPage {
|
||||||
|
actionDropdown: string;
|
||||||
|
addRolesDropdownItem: string;
|
||||||
|
addRoleToolbarButton: string;
|
||||||
|
checkbox: string;
|
||||||
|
addAssociatedRolesModalButton: string;
|
||||||
|
compositeRoleBadge: string;
|
||||||
|
filterTypeDropdown: string;
|
||||||
|
filterTypeDropdownItem: string;
|
||||||
|
usersPage: string;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.actionDropdown = "[data-testid=action-dropdown]";
|
||||||
|
this.addRolesDropdownItem = "[data-testid=add-roles]";
|
||||||
|
this.addRoleToolbarButton = "[data-testid=add-role-button]";
|
||||||
|
this.checkbox = "[type=checkbox]";
|
||||||
|
this.addAssociatedRolesModalButton =
|
||||||
|
"[data-testid=add-associated-roles-button]";
|
||||||
|
this.compositeRoleBadge = "[data-testid=composite-role-badge]";
|
||||||
|
this.filterTypeDropdown = "[data-testid=filter-type-dropdown]";
|
||||||
|
this.filterTypeDropdownItem = "[data-testid=filter-type-dropdown-item]";
|
||||||
|
this.usersPage = "[data-testid=users-page]";
|
||||||
|
}
|
||||||
|
|
||||||
|
addAssociatedRealmRole() {
|
||||||
|
cy.get(this.actionDropdown).last().click();
|
||||||
|
|
||||||
|
cy.get(this.addRolesDropdownItem).click();
|
||||||
|
|
||||||
|
cy.wait(100);
|
||||||
|
|
||||||
|
cy.get(this.checkbox).eq(1).check();
|
||||||
|
|
||||||
|
cy.get(this.addAssociatedRolesModalButton).contains("Add").click();
|
||||||
|
|
||||||
|
cy.url().should("include", "/AssociatedRoles");
|
||||||
|
|
||||||
|
cy.get(this.compositeRoleBadge).should("contain.text", "Composite");
|
||||||
|
|
||||||
|
cy.wait(2500);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
addAssociatedClientRole() {
|
||||||
|
cy.get(this.addRoleToolbarButton).click();
|
||||||
|
|
||||||
|
cy.wait(100);
|
||||||
|
|
||||||
|
cy.get(this.filterTypeDropdown).click();
|
||||||
|
|
||||||
|
cy.get(this.filterTypeDropdownItem).click();
|
||||||
|
|
||||||
|
cy.wait(2500);
|
||||||
|
|
||||||
|
cy.get(this.checkbox).eq(40).check({ force: true });
|
||||||
|
|
||||||
|
cy.get(this.addAssociatedRolesModalButton).contains("Add").click();
|
||||||
|
|
||||||
|
cy.wait(2500);
|
||||||
|
|
||||||
|
cy.contains("Users in role").click().get(this.usersPage).should("exist");
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ import {
|
||||||
Switch,
|
Switch,
|
||||||
TextContent,
|
TextContent,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { HelpIcon, ExternalLinkAltIcon } from "@patternfly/react-icons";
|
import { HelpIcon, ExternalLinkAltIcon } from "@patternfly/react-icons";
|
||||||
|
|
||||||
import "./help-header.css";
|
import "./help-header.css";
|
||||||
|
|
|
@ -19,7 +19,7 @@ export type Action = {
|
||||||
|
|
||||||
export type ListEmptyStateProps = {
|
export type ListEmptyStateProps = {
|
||||||
message: string;
|
message: string;
|
||||||
instructions: string;
|
instructions: React.ReactNode;
|
||||||
primaryActionText?: string;
|
primaryActionText?: string;
|
||||||
onPrimaryAction?: MouseEventHandler<HTMLButtonElement>;
|
onPrimaryAction?: MouseEventHandler<HTMLButtonElement>;
|
||||||
hasIcon?: boolean;
|
hasIcon?: boolean;
|
||||||
|
|
|
@ -41,7 +41,6 @@ export const ViewHeader = ({
|
||||||
actionsDropdownId,
|
actionsDropdownId,
|
||||||
titleKey,
|
titleKey,
|
||||||
badge,
|
badge,
|
||||||
badgeId,
|
|
||||||
badgeIsRead,
|
badgeIsRead,
|
||||||
subKey,
|
subKey,
|
||||||
subKeyLinkProps,
|
subKeyLinkProps,
|
||||||
|
@ -77,7 +76,10 @@ export const ViewHeader = ({
|
||||||
</LevelItem>
|
</LevelItem>
|
||||||
{badge && (
|
{badge && (
|
||||||
<LevelItem>
|
<LevelItem>
|
||||||
<Badge id={badgeId} isRead={badgeIsRead}>
|
<Badge
|
||||||
|
data-testid="composite-role-badge"
|
||||||
|
isRead={badgeIsRead}
|
||||||
|
>
|
||||||
{badge}
|
{badge}
|
||||||
</Badge>
|
</Badge>
|
||||||
</LevelItem>
|
</LevelItem>
|
||||||
|
|
|
@ -177,7 +177,7 @@ export const AssociatedRolesModal = (props: AssociatedRolesModalProps) => {
|
||||||
actions={[
|
actions={[
|
||||||
<Button
|
<Button
|
||||||
key="add"
|
key="add"
|
||||||
id="add-associated-roles-button"
|
data-testid="add-associated-roles-button"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
isDisabled={!selectedRows?.length}
|
isDisabled={!selectedRows?.length}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -206,7 +206,7 @@ export const AssociatedRolesModal = (props: AssociatedRolesModalProps) => {
|
||||||
searchTypeComponent={
|
searchTypeComponent={
|
||||||
<Dropdown
|
<Dropdown
|
||||||
onSelect={() => onFilterDropdownSelect(filterType)}
|
onSelect={() => onFilterDropdownSelect(filterType)}
|
||||||
data-cy="filter-type-dropdown"
|
data-testid="filter-type-dropdown"
|
||||||
toggle={
|
toggle={
|
||||||
<DropdownToggle
|
<DropdownToggle
|
||||||
id="toggle-id-9"
|
id="toggle-id-9"
|
||||||
|
@ -220,7 +220,7 @@ export const AssociatedRolesModal = (props: AssociatedRolesModalProps) => {
|
||||||
isOpen={isFilterDropdownOpen}
|
isOpen={isFilterDropdownOpen}
|
||||||
dropdownItems={[
|
dropdownItems={[
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
data-cy="filter-type-dropdown-item"
|
data-testid="filter-type-dropdown-item"
|
||||||
key="filter-type"
|
key="filter-type"
|
||||||
>
|
>
|
||||||
{filterType == "roles"
|
{filterType == "roles"
|
||||||
|
@ -231,7 +231,7 @@ export const AssociatedRolesModal = (props: AssociatedRolesModalProps) => {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
canSelectAll
|
canSelectAll
|
||||||
// isPaginated
|
isPaginated
|
||||||
onSelect={(rows) => {
|
onSelect={(rows) => {
|
||||||
setSelectedRows([...rows]);
|
setSelectedRows([...rows]);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -184,13 +184,13 @@ export const AssociatedRolesTab = ({
|
||||||
<KeycloakDataTable
|
<KeycloakDataTable
|
||||||
key={key}
|
key={key}
|
||||||
loader={loader}
|
loader={loader}
|
||||||
|
isPaginated
|
||||||
ariaLabelKey="roles:roleList"
|
ariaLabelKey="roles:roleList"
|
||||||
searchPlaceholderKey="roles:searchFor"
|
searchPlaceholderKey="roles:searchFor"
|
||||||
canSelectAll
|
canSelectAll
|
||||||
onSelect={(rows) => {
|
onSelect={(rows) => {
|
||||||
setSelectedRows([...rows]);
|
setSelectedRows([...rows]);
|
||||||
}}
|
}}
|
||||||
isPaginated
|
|
||||||
toolbarItem={
|
toolbarItem={
|
||||||
<>
|
<>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
@ -204,7 +204,7 @@ export const AssociatedRolesTab = ({
|
||||||
className="kc-add-role-button"
|
className="kc-add-role-button"
|
||||||
key="add-role-button"
|
key="add-role-button"
|
||||||
onClick={() => toggleModal()}
|
onClick={() => toggleModal()}
|
||||||
data-cy="add-role-button"
|
data-testid="add-role-button"
|
||||||
>
|
>
|
||||||
{t("addRole")}
|
{t("addRole")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -23,6 +23,7 @@ import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { AssociatedRolesModal } from "./AssociatedRolesModal";
|
import { AssociatedRolesModal } from "./AssociatedRolesModal";
|
||||||
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
|
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
|
||||||
import { AssociatedRolesTab } from "./AssociatedRolesTab";
|
import { AssociatedRolesTab } from "./AssociatedRolesTab";
|
||||||
|
import { UsersInRoleTab } from "./UsersInRoleTab";
|
||||||
|
|
||||||
const arrayToAttributes = (attributeArray: KeyValueType[]) => {
|
const arrayToAttributes = (attributeArray: KeyValueType[]) => {
|
||||||
const initValue: { [index: string]: string[] } = {};
|
const initValue: { [index: string]: string[] } = {};
|
||||||
|
@ -254,7 +255,6 @@ export const RealmRoleTabs = () => {
|
||||||
<ViewHeader
|
<ViewHeader
|
||||||
titleKey={role?.name || t("createRole")}
|
titleKey={role?.name || t("createRole")}
|
||||||
badge={additionalRoles.length > 0 ? t("composite") : ""}
|
badge={additionalRoles.length > 0 ? t("composite") : ""}
|
||||||
badgeId="composite-role-badge"
|
|
||||||
badgeIsRead={true}
|
badgeIsRead={true}
|
||||||
subKey={id ? "" : "roles:roleCreateExplain"}
|
subKey={id ? "" : "roles:roleCreateExplain"}
|
||||||
actionsDropdownId="roles-actions-dropdown"
|
actionsDropdownId="roles-actions-dropdown"
|
||||||
|
@ -287,7 +287,7 @@ export const RealmRoleTabs = () => {
|
||||||
</DropdownItem>,
|
</DropdownItem>,
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
key="toggle-modal"
|
key="toggle-modal"
|
||||||
id="add-roles"
|
data-testid="add-roles"
|
||||||
component="button"
|
component="button"
|
||||||
onClick={() => toggleModal()}
|
onClick={() => toggleModal()}
|
||||||
>
|
>
|
||||||
|
@ -336,6 +336,12 @@ export const RealmRoleTabs = () => {
|
||||||
reset={() => form.reset(role)}
|
reset={() => form.reset(role)}
|
||||||
/>
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab
|
||||||
|
eventKey="users-in-role"
|
||||||
|
title={<TabTitleText>{t("usersInRole")}</TabTitleText>}
|
||||||
|
>
|
||||||
|
<UsersInRoleTab data-cy="users-in-role-tab" />
|
||||||
|
</Tab>
|
||||||
</KeycloakTabs>
|
</KeycloakTabs>
|
||||||
)}
|
)}
|
||||||
{!id && (
|
{!id && (
|
||||||
|
|
|
@ -24,5 +24,33 @@
|
||||||
--pf-c-form__group--m-action--MarginTop: calc(
|
--pf-c-form__group--m-action--MarginTop: calc(
|
||||||
var(--pf-global--spacer--2xl) - var(--pf-global--spacer--sm)
|
var(--pf-global--spacer--2xl) - var(--pf-global--spacer--sm)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.kc-who-will-appear-button {
|
||||||
|
padding-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-c-button.pf-m-link.kc-groups-link {
|
||||||
|
font-size: var(--pf-global--FontSize--sm);
|
||||||
|
padding-left: 0px;
|
||||||
|
padding-right: var(--pf-global--spacer--xs);
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-c-button.pf-m-link.kc-users-link {
|
||||||
|
font-size: var(--pf-global--FontSize--sm);
|
||||||
|
padding-left: var(--pf-global--spacer--xs);
|
||||||
|
padding-right: var(--pf-global--spacer--xs);
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-c-button.pf-m-link.kc-groups-link-empty-state {
|
||||||
|
padding-left: var(--pf-global--spacer--xs);
|
||||||
|
padding-right: var(--pf-global--spacer--xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-c-button.pf-m-link.kc-users-link-empty-state {
|
||||||
|
padding-left: var(--pf-global--spacer--xs);
|
||||||
|
padding-right: var(--pf-global--spacer--xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
134
src/realm-roles/UsersInRoleTab.tsx
Normal file
134
src/realm-roles/UsersInRoleTab.tsx
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
import React, { useContext } from "react";
|
||||||
|
import { useHistory, useParams } from "react-router-dom";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Button, PageSection, Popover } from "@patternfly/react-core";
|
||||||
|
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||||
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||||
|
import { boolFormatter, emptyFormatter } from "../util";
|
||||||
|
import { useAdminClient } from "../context/auth/AdminClient";
|
||||||
|
import { QuestionCircleIcon } from "@patternfly/react-icons";
|
||||||
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
|
import { HelpContext } from "../components/help-enabler/HelpHeader";
|
||||||
|
|
||||||
|
export const UsersInRoleTab = () => {
|
||||||
|
const history = useHistory();
|
||||||
|
const { realm } = useRealm();
|
||||||
|
|
||||||
|
const { t } = useTranslation("roles");
|
||||||
|
|
||||||
|
const { id } = useParams<{ id: string }>();
|
||||||
|
|
||||||
|
const adminClient = useAdminClient();
|
||||||
|
|
||||||
|
const loader = async (first?: number, max?: number) => {
|
||||||
|
const role = await adminClient.roles.findOneById({ id: id });
|
||||||
|
const usersWithRole = await adminClient.roles.findUsersWithRole({
|
||||||
|
name: role.name!,
|
||||||
|
first: first!,
|
||||||
|
max: max!,
|
||||||
|
} as any);
|
||||||
|
return usersWithRole;
|
||||||
|
};
|
||||||
|
|
||||||
|
const { enabled } = useContext(HelpContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageSection data-testid="users-page" variant="light">
|
||||||
|
<KeycloakDataTable
|
||||||
|
isPaginated
|
||||||
|
loader={loader}
|
||||||
|
ariaLabelKey="roles:roleList"
|
||||||
|
searchPlaceholderKey=""
|
||||||
|
toolbarItem={
|
||||||
|
enabled && (
|
||||||
|
<Popover
|
||||||
|
aria-label="Basic popover"
|
||||||
|
position="bottom"
|
||||||
|
bodyContent={
|
||||||
|
<div>
|
||||||
|
{t("roles:whoWillAppearPopoverText")}
|
||||||
|
<Button
|
||||||
|
className="kc-groups-link"
|
||||||
|
variant="link"
|
||||||
|
onClick={() => history.push(`/${realm}/groups`)}
|
||||||
|
>
|
||||||
|
{t("groups")}
|
||||||
|
</Button>
|
||||||
|
{t("or")}
|
||||||
|
<Button
|
||||||
|
className="kc-users-link"
|
||||||
|
variant="link"
|
||||||
|
onClick={() => history.push(`/${realm}/users`)}
|
||||||
|
>
|
||||||
|
{t("users")}.
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
footerContent={t("roles:whoWillAppearPopoverFooterText")}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
className="kc-who-will-appear-button"
|
||||||
|
key="who-will-appear-button"
|
||||||
|
icon={<QuestionCircleIcon />}
|
||||||
|
>
|
||||||
|
{t("roles:whoWillAppearLinkText")}
|
||||||
|
</Button>
|
||||||
|
</Popover>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
emptyState={
|
||||||
|
<ListEmptyState
|
||||||
|
hasIcon={true}
|
||||||
|
message={t("noDirectUsers")}
|
||||||
|
instructions={
|
||||||
|
<div>
|
||||||
|
{t("noUsersEmptyStateDescription")}
|
||||||
|
<Button
|
||||||
|
className="kc-groups-link-empty-state"
|
||||||
|
variant="link"
|
||||||
|
onClick={() => history.push(`/${realm}/groups`)}
|
||||||
|
>
|
||||||
|
{t("groups")}
|
||||||
|
</Button>
|
||||||
|
{t("or")}
|
||||||
|
<Button
|
||||||
|
className="kc-users-link-empty-state"
|
||||||
|
variant="link"
|
||||||
|
onClick={() => history.push(`/${realm}/users`)}
|
||||||
|
>
|
||||||
|
{t("users")}
|
||||||
|
</Button>
|
||||||
|
{t("noUsersEmptyStateDescriptionContinued")}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
name: "username",
|
||||||
|
displayKey: "roles:userName",
|
||||||
|
cellFormatters: [emptyFormatter()],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "email",
|
||||||
|
displayKey: "roles:email",
|
||||||
|
cellFormatters: [emptyFormatter()],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastName",
|
||||||
|
displayKey: "roles:lastName",
|
||||||
|
cellFormatters: [emptyFormatter()],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "firstName",
|
||||||
|
displayKey: "roles:firstName",
|
||||||
|
cellFormatters: [boolFormatter(), emptyFormatter()],
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</PageSection>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -48,6 +48,24 @@
|
||||||
"roleRemoveAssociatedText": "This action will remove {{role}} from {{roleName}. All the associated roles of {{role}} will also be removed.",
|
"roleRemoveAssociatedText": "This action will remove {{role}} from {{roleName}. All the associated roles of {{role}} will also be removed.",
|
||||||
"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",
|
||||||
|
"whoWillAppearLinkText": "Who will appear in this user list?",
|
||||||
|
"whoWillAppearPopoverText": "This tab shows only the users who are assigned directly to this role. To see users who are assigned this role as an associated role or through a group, go to",
|
||||||
|
"whoWillAppearPopoverFooterText": "Users who have this role as an effective role cannot be added on this tab.",
|
||||||
|
"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, go to",
|
||||||
|
"noUsersEmptyStateDescriptionContinued": "to find them. Users that already have this role as an effective role cannot be added here.",
|
||||||
|
"id": "ID",
|
||||||
|
"groups": "Groups",
|
||||||
|
"or": "or",
|
||||||
|
"users": "Users",
|
||||||
|
"userName": "Username",
|
||||||
|
"email": "Email",
|
||||||
|
"lastName": "Last name",
|
||||||
|
"firstName": "First name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue