From 88711202efd5505127c924b106b68cbd52d3c628 Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Wed, 24 Feb 2021 08:47:27 -0500 Subject: [PATCH 01/19] users tab WIP --- src/realm-roles/RealmRoleTabs.tsx | 16 ++- src/realm-roles/UsersInRoleTab.tsx | 193 +++++++++++++++++++++++++++++ src/realm-roles/messages.json | 4 +- 3 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 src/realm-roles/UsersInRoleTab.tsx diff --git a/src/realm-roles/RealmRoleTabs.tsx b/src/realm-roles/RealmRoleTabs.tsx index 68d1e1df54..5e916c635f 100644 --- a/src/realm-roles/RealmRoleTabs.tsx +++ b/src/realm-roles/RealmRoleTabs.tsx @@ -23,6 +23,7 @@ import { useRealm } from "../context/realm-context/RealmContext"; import { AssociatedRolesModal } from "./AssociatedRolesModal"; import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs"; import { AssociatedRolesTab } from "./AssociatedRolesTab"; +import { UsersInRoleTab } from "./UsersInRoleTab"; const arrayToAttributes = (attributeArray: KeyValueType[]) => { const initValue: { [index: string]: string[] } = {}; @@ -168,7 +169,8 @@ export const RealmRoleTabs = () => { ); } }; - + + console.log(role) const addComposites = async (composites: Composites[]): Promise => { const compositeArray = composites; setAdditionalRoles([...additionalRoles, ...compositeArray]); @@ -336,6 +338,18 @@ export const RealmRoleTabs = () => { reset={() => form.reset(role)} /> + {t("usersInRole")}} + > + form.reset(role)} + /> + )} {!id && ( diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx new file mode 100644 index 0000000000..2154aca6f5 --- /dev/null +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -0,0 +1,193 @@ +import React, { useState } from "react"; +import { useHistory, useParams, useRouteMatch } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import { + 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 { 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 { AssociatedRolesModal } from "./AssociatedRolesModal"; +import { useAdminClient } from "../context/auth/AdminClient"; + +type UsersInRoleTabProps = { + roleName: string; + }; + + +export const UsersInRoleTab = ({roleName}: UsersInRoleTabProps) => { + const { t } = useTranslation("roles"); + const history = useHistory(); + const { addAlert } = useAlerts(); + const { url } = useRouteMatch(); + const tableRefresher = React.useRef<() => void>(); + + const [selectedRows, setSelectedRows] = useState([]); + const [open, setOpen] = useState(false); + +// console.log(role); + + const adminClient = useAdminClient(); + const { id } = useParams<{ id: string; clientId: string }>(); + + const loader = async () => { + const beep = await adminClient.roles.findUsersWithRole({name: "admin"}) + console.log(beep); + if (!beep) { + console.log("lalala"); + } + else return beep; + }; + + + 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 ( + <> + + + {/* + setOpen(!open)} + /> */} + { + // setSelectedRows([...rows]); + // }} + isPaginated + setRefresher={setRefresher} + toolbarItem={ + <> + + + + + } + actions={[ + { + title: t("common:remove"), + onRowClick: (role) => { + // setSelectedRows([role]); + toggleDeleteDialog(); + }, + }, + ]} + columns={[ + { + name: "name", + displayKey: "roles:roleName", + // cellRenderer: RoleName, + cellFormatters: [formattedLinkTableCell(), emptyFormatter()], + }, + { + name: "inherited from", + displayKey: "roles:inheritedFrom", + cellFormatters: [boolFormatter(), emptyFormatter()], + }, + { + name: "description", + displayKey: "common:description", + cellFormatters: [emptyFormatter()], + }, + ]} + emptyState={ + + } + /> + + + ); +}; diff --git a/src/realm-roles/messages.json b/src/realm-roles/messages.json index 623dca94ea..ca60a75165 100644 --- a/src/realm-roles/messages.json +++ b/src/realm-roles/messages.json @@ -48,6 +48,8 @@ "roleRemoveAssociatedText": "This action will remove {{role}} from {{roleName}. All the associated roles of {{role}} will also be removed.", "compositeRoleOff": "Composite role turned off", "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" + } } From 8ead0d0fff4d9ef2dacaab5f65bdc16c34a39f17 Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Wed, 24 Feb 2021 15:05:19 -0500 Subject: [PATCH 02/19] read-only users in role tab --- src/realm-roles/AssociatedRolesTab.tsx | 1 - src/realm-roles/RealmRoleTabs.tsx | 11 +- src/realm-roles/UsersInRoleTab.tsx | 225 ++++++------------------- src/realm-roles/messages.json | 13 +- 4 files changed, 70 insertions(+), 180 deletions(-) diff --git a/src/realm-roles/AssociatedRolesTab.tsx b/src/realm-roles/AssociatedRolesTab.tsx index 07e073ef08..d28fc3d963 100644 --- a/src/realm-roles/AssociatedRolesTab.tsx +++ b/src/realm-roles/AssociatedRolesTab.tsx @@ -190,7 +190,6 @@ export const AssociatedRolesTab = ({ onSelect={(rows) => { setSelectedRows([...rows]); }} - isPaginated toolbarItem={ <> { } }; - console.log(role) + + const addComposites = async (composites: Composites[]): Promise => { const compositeArray = composites; setAdditionalRoles([...additionalRoles, ...compositeArray]); @@ -342,13 +343,7 @@ export const RealmRoleTabs = () => { eventKey="users-in-role" title={{t("usersInRole")}} > - form.reset(role)} - /> + )} diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 2154aca6f5..343c3bfc2a 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -1,192 +1,79 @@ -import React, { useState } from "react"; -import { useHistory, useParams, useRouteMatch } from "react-router-dom"; +import React, { useState, useEffect } from "react"; +import { useParams } from "react-router-dom"; import { useTranslation } from "react-i18next"; -import { - AlertVariant, - Button, - ButtonVariant, - Checkbox, - PageSection, -} from "@patternfly/react-core"; -import RoleRepresentation from "keycloak-admin/lib/defs/roleRepresentation"; +import { PageSection } from "@patternfly/react-core"; import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; 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 { AssociatedRolesModal } from "./AssociatedRolesModal"; import { useAdminClient } from "../context/auth/AdminClient"; +import UserRepresentation from "keycloak-admin/lib/defs/userRepresentation"; -type UsersInRoleTabProps = { - roleName: string; - }; - - -export const UsersInRoleTab = ({roleName}: UsersInRoleTabProps) => { +export const UsersInRoleTab = () => { const { t } = useTranslation("roles"); - const history = useHistory(); - const { addAlert } = useAlerts(); - const { url } = useRouteMatch(); - const tableRefresher = React.useRef<() => void>(); - const [selectedRows, setSelectedRows] = useState([]); - const [open, setOpen] = useState(false); + const [users, setUsers] = useState([]); -// console.log(role); + const { id } = useParams<{ id: string }>(); const adminClient = useAdminClient(); - const { id } = useParams<{ id: string; clientId: string }>(); const loader = async () => { - const beep = await adminClient.roles.findUsersWithRole({name: "admin"}) - console.log(beep); - if (!beep) { - console.log("lalala"); - } - else return beep; + const role = await adminClient.roles.findOneById({ id: id }); + const usersWithRole = await adminClient.roles.findUsersWithRole({ + name: role.name!, + }); + setUsers(usersWithRole); + 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 ( <> - - {/* - setOpen(!open)} - /> */} - { - // setSelectedRows([...rows]); - // }} - isPaginated - setRefresher={setRefresher} - toolbarItem={ - <> - - - - - } - actions={[ - { - title: t("common:remove"), - onRowClick: (role) => { - // setSelectedRows([role]); - toggleDeleteDialog(); + {users.length == 0 ? ( + + ) : ( + - } - /> + { + 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()], + }, + ]} + /> + )} ); diff --git a/src/realm-roles/messages.json b/src/realm-roles/messages.json index ca60a75165..b714d71447 100644 --- a/src/realm-roles/messages.json +++ b/src/realm-roles/messages.json @@ -49,7 +49,16 @@ "compositeRoleOff": "Composite role turned off", "associatedRolesRemoved": "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" } } From 7657c4df734274f3f2b8be420b1bd843db5c7d13 Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Wed, 24 Feb 2021 15:51:34 -0500 Subject: [PATCH 03/19] cypress test --- cypress/integration/realm_roles_test.spec.ts | 11 ++++++++--- src/components/list-empty-state/ListEmptyState.tsx | 4 +++- src/realm-roles/RealmRoleTabs.tsx | 2 +- src/realm-roles/UsersInRoleTab.tsx | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/cypress/integration/realm_roles_test.spec.ts b/cypress/integration/realm_roles_test.spec.ts index a13294ea89..a0ef18c064 100644 --- a/cypress/integration/realm_roles_test.spec.ts +++ b/cypress/integration/realm_roles_test.spec.ts @@ -89,13 +89,13 @@ describe("Realm roles test", function () { // Add associated client role - cy.get('[data-cy=add-role-button]').click(); + cy.get("[data-cy=add-role-button]").click(); cy.wait(100); - cy.get('[data-cy=filter-type-dropdown]').click() + cy.get("[data-cy=filter-type-dropdown]").click(); - cy.get('[data-cy=filter-type-dropdown-item]').click() + cy.get("[data-cy=filter-type-dropdown-item]").click(); cy.wait(2500); @@ -104,6 +104,11 @@ describe("Realm roles test", function () { cy.get("#add-associated-roles-button").contains("Add").click(); cy.wait(2500); + + cy.contains("Users in role") + .click() + .get("#users-empty-state > div > h4") + .contains("No direct users"); }); }); }); diff --git a/src/components/list-empty-state/ListEmptyState.tsx b/src/components/list-empty-state/ListEmptyState.tsx index 3a805477d6..68ff13df0b 100644 --- a/src/components/list-empty-state/ListEmptyState.tsx +++ b/src/components/list-empty-state/ListEmptyState.tsx @@ -18,6 +18,7 @@ export type Action = { }; export type ListEmptyStateProps = { + id?: string, message: string; instructions: string; primaryActionText?: string; @@ -28,6 +29,7 @@ export type ListEmptyStateProps = { }; export const ListEmptyState = ({ + id, message, instructions, onPrimaryAction, @@ -38,7 +40,7 @@ export const ListEmptyState = ({ }: ListEmptyStateProps) => { return ( <> - + {hasIcon && isSearchVariant ? ( ) : ( diff --git a/src/realm-roles/RealmRoleTabs.tsx b/src/realm-roles/RealmRoleTabs.tsx index c0d9a68f90..7fb746d589 100644 --- a/src/realm-roles/RealmRoleTabs.tsx +++ b/src/realm-roles/RealmRoleTabs.tsx @@ -343,7 +343,7 @@ export const RealmRoleTabs = () => { eventKey="users-in-role" title={{t("usersInRole")}} > - + )} diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 343c3bfc2a..6b1112aaa1 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -38,7 +38,7 @@ export const UsersInRoleTab = () => { hasIcon={true} message={t("noDirectUsers")} instructions={t("noUsersEmptyStateDescription")} - primaryActionText={t("addUser")} + id="users-empty-state" /> ) : ( Date: Wed, 24 Feb 2021 16:05:56 -0500 Subject: [PATCH 04/19] format --- src/components/list-empty-state/ListEmptyState.tsx | 2 +- src/realm-roles/RealmRoleTabs.tsx | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/list-empty-state/ListEmptyState.tsx b/src/components/list-empty-state/ListEmptyState.tsx index 68ff13df0b..ee1fdde383 100644 --- a/src/components/list-empty-state/ListEmptyState.tsx +++ b/src/components/list-empty-state/ListEmptyState.tsx @@ -18,7 +18,7 @@ export type Action = { }; export type ListEmptyStateProps = { - id?: string, + id?: string; message: string; instructions: string; primaryActionText?: string; diff --git a/src/realm-roles/RealmRoleTabs.tsx b/src/realm-roles/RealmRoleTabs.tsx index 7fb746d589..6ba9b55afd 100644 --- a/src/realm-roles/RealmRoleTabs.tsx +++ b/src/realm-roles/RealmRoleTabs.tsx @@ -169,8 +169,6 @@ export const RealmRoleTabs = () => { ); } }; - - const addComposites = async (composites: Composites[]): Promise => { const compositeArray = composites; From eca3bb8e71819b1daa5206174b6638ea576877be Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Thu, 25 Feb 2021 10:17:42 -0500 Subject: [PATCH 05/19] address PR feedback from Erik, remove user ID per Haley feedback --- cypress/integration/realm_roles_test.spec.ts | 4 ++-- src/components/list-empty-state/ListEmptyState.tsx | 4 +--- src/realm-roles/UsersInRoleTab.tsx | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/cypress/integration/realm_roles_test.spec.ts b/cypress/integration/realm_roles_test.spec.ts index a0ef18c064..62e7654c42 100644 --- a/cypress/integration/realm_roles_test.spec.ts +++ b/cypress/integration/realm_roles_test.spec.ts @@ -107,8 +107,8 @@ describe("Realm roles test", function () { cy.contains("Users in role") .click() - .get("#users-empty-state > div > h4") - .contains("No direct users"); + .get('[data-test-id="users-page"]') + .should('exist') }); }); }); diff --git a/src/components/list-empty-state/ListEmptyState.tsx b/src/components/list-empty-state/ListEmptyState.tsx index ee1fdde383..3a805477d6 100644 --- a/src/components/list-empty-state/ListEmptyState.tsx +++ b/src/components/list-empty-state/ListEmptyState.tsx @@ -18,7 +18,6 @@ export type Action = { }; export type ListEmptyStateProps = { - id?: string; message: string; instructions: string; primaryActionText?: string; @@ -29,7 +28,6 @@ export type ListEmptyStateProps = { }; export const ListEmptyState = ({ - id, message, instructions, onPrimaryAction, @@ -40,7 +38,7 @@ export const ListEmptyState = ({ }: ListEmptyStateProps) => { return ( <> - + {hasIcon && isSearchVariant ? ( ) : ( diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 6b1112aaa1..e593636ee5 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -32,13 +32,12 @@ export const UsersInRoleTab = () => { return ( <> - + {users.length == 0 ? ( ) : ( Date: Thu, 25 Feb 2021 10:18:12 -0500 Subject: [PATCH 06/19] remove ID col --- src/realm-roles/UsersInRoleTab.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index e593636ee5..448fc95375 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -45,11 +45,6 @@ export const UsersInRoleTab = () => { ariaLabelKey="roles:roleList" searchPlaceholderKey="" columns={[ - { - name: "id", - displayKey: "roles:id", - cellFormatters: [emptyFormatter()], - }, { name: "username", displayKey: "roles:userName", From 993e75b14fd6b74fd6b855c5eff45cb86cb53d77 Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Mon, 1 Mar 2021 10:22:25 -0500 Subject: [PATCH 07/19] refactor tests to use data-testid --- cypress/integration/realm_roles_test.spec.ts | 20 ++++++++++---------- src/components/view-header/ViewHeader.tsx | 6 ++++-- src/realm-roles/AssociatedRolesModal.tsx | 6 +++--- src/realm-roles/AssociatedRolesTab.tsx | 2 +- src/realm-roles/RealmRoleTabs.tsx | 3 +-- src/realm-roles/UsersInRoleTab.tsx | 2 +- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/cypress/integration/realm_roles_test.spec.ts b/cypress/integration/realm_roles_test.spec.ts index 62e7654c42..92512e2bdb 100644 --- a/cypress/integration/realm_roles_test.spec.ts +++ b/cypress/integration/realm_roles_test.spec.ts @@ -71,43 +71,43 @@ describe("Realm roles test", function () { masthead.checkNotificationMessage("Role created"); // Add associated realm role - cy.get("#roles-actions-dropdown").last().click(); + cy.get("[data-testid=action-dropdown]").last().click(); - cy.get("#add-roles").click(); + cy.get("[data-testid=add-roles]").click(); cy.wait(100); cy.get('[type="checkbox"]').eq(1).check(); - cy.get("#add-associated-roles-button").contains("Add").click(); + cy.get("[data-testid=add-associated-roles-button]").contains("Add").click(); cy.url().should("include", "/AssociatedRoles"); - cy.get("#composite-role-badge").should("contain.text", "Composite"); + cy.get("[data-testid=composite-role-badge]").should("contain.text", "Composite"); - cy.wait(100); + cy.wait(2500); // Add associated client role - cy.get("[data-cy=add-role-button]").click(); + cy.get("[data-testid=add-role-button]").click(); cy.wait(100); - cy.get("[data-cy=filter-type-dropdown]").click(); + cy.get("[data-testid=filter-type-dropdown]").click(); - cy.get("[data-cy=filter-type-dropdown-item]").click(); + cy.get("[data-testid=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.get("[data-testid=add-associated-roles-button]").contains("Add").click(); cy.wait(2500); cy.contains("Users in role") .click() - .get('[data-test-id="users-page"]') + .get('[data-testid="users-page"]') .should('exist') }); }); diff --git a/src/components/view-header/ViewHeader.tsx b/src/components/view-header/ViewHeader.tsx index 4f25de5a8c..2cc6b281a6 100644 --- a/src/components/view-header/ViewHeader.tsx +++ b/src/components/view-header/ViewHeader.tsx @@ -41,7 +41,6 @@ export const ViewHeader = ({ actionsDropdownId, titleKey, badge, - badgeId, badgeIsRead, subKey, subKeyLinkProps, @@ -77,7 +76,10 @@ export const ViewHeader = ({ {badge && ( - + {badge} diff --git a/src/realm-roles/AssociatedRolesModal.tsx b/src/realm-roles/AssociatedRolesModal.tsx index e72a8adec8..8d2cbaed1d 100644 --- a/src/realm-roles/AssociatedRolesModal.tsx +++ b/src/realm-roles/AssociatedRolesModal.tsx @@ -177,7 +177,7 @@ export const AssociatedRolesModal = (props: AssociatedRolesModalProps) => { actions={[ diff --git a/src/realm-roles/RealmRoleTabs.tsx b/src/realm-roles/RealmRoleTabs.tsx index 6ba9b55afd..7bd9dca9b2 100644 --- a/src/realm-roles/RealmRoleTabs.tsx +++ b/src/realm-roles/RealmRoleTabs.tsx @@ -255,7 +255,6 @@ export const RealmRoleTabs = () => { 0 ? t("composite") : ""} - badgeId="composite-role-badge" badgeIsRead={true} subKey={id ? "" : "roles:roleCreateExplain"} actionsDropdownId="roles-actions-dropdown" @@ -288,7 +287,7 @@ export const RealmRoleTabs = () => { , toggleModal()} > diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 448fc95375..56ce1e265b 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -32,7 +32,7 @@ export const UsersInRoleTab = () => { return ( <> - + {users.length == 0 ? ( Date: Mon, 1 Mar 2021 10:30:16 -0500 Subject: [PATCH 08/19] rebase and use new empty state logic --- src/realm-roles/UsersInRoleTab.tsx | 73 ++++++++++++++---------------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 56ce1e265b..427105792f 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -6,13 +6,10 @@ 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 UserRepresentation from "keycloak-admin/lib/defs/userRepresentation"; export const UsersInRoleTab = () => { const { t } = useTranslation("roles"); - const [users, setUsers] = useState([]); - const { id } = useParams<{ id: string }>(); const adminClient = useAdminClient(); @@ -22,7 +19,6 @@ export const UsersInRoleTab = () => { const usersWithRole = await adminClient.roles.findUsersWithRole({ name: role.name!, }); - setUsers(usersWithRole); return usersWithRole; }; @@ -33,41 +29,40 @@ export const UsersInRoleTab = () => { return ( <> - {users.length == 0 ? ( - - ) : ( - - )} + + } + 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()], + }, + ]} + /> ); From fdf3e7e78af911c832eefbaaa8697e9f5ff88924 Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Mon, 1 Mar 2021 10:55:54 -0500 Subject: [PATCH 09/19] fix lint --- src/realm-roles/AssociatedRolesModal.tsx | 2 +- src/realm-roles/UsersInRoleTab.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/realm-roles/AssociatedRolesModal.tsx b/src/realm-roles/AssociatedRolesModal.tsx index 8d2cbaed1d..45a0121109 100644 --- a/src/realm-roles/AssociatedRolesModal.tsx +++ b/src/realm-roles/AssociatedRolesModal.tsx @@ -231,7 +231,7 @@ export const AssociatedRolesModal = (props: AssociatedRolesModalProps) => { /> } canSelectAll - // isPaginated + isPaginated onSelect={(rows) => { setSelectedRows([...rows]); }} diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 427105792f..47611c626e 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useEffect } from "react"; import { useParams } from "react-router-dom"; import { useTranslation } from "react-i18next"; import { PageSection } from "@patternfly/react-core"; From 65348bd125174579cd17b906284e0942e12cad3c Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Mon, 1 Mar 2021 12:20:58 -0500 Subject: [PATCH 10/19] add popover --- src/realm-roles/RealmRolesSection.css | 20 ++++++++++++ src/realm-roles/UsersInRoleTab.tsx | 45 +++++++++++++++++++++++++-- src/realm-roles/messages.json | 6 ++++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/realm-roles/RealmRolesSection.css b/src/realm-roles/RealmRolesSection.css index a45446edc6..296b16b67d 100644 --- a/src/realm-roles/RealmRolesSection.css +++ b/src/realm-roles/RealmRolesSection.css @@ -26,3 +26,23 @@ ); } + +.kc-who-will-appear-button { + /* padding-left: 0px; */ + /* padding-top: 0px; */ + margin-bottom: var(--pf-global--spacer--lg);; +} + +.kc-groups-link { + font-size: var(--pf-global--FontSize--sm); + padding-left: 0px; + padding-right: var(--pf-global--spacer--xs); +} + +.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 + +} diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 47611c626e..300105a177 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -1,13 +1,18 @@ import React, { useEffect } from "react"; -import { useParams } from "react-router-dom"; +import { useHistory, useParams } from "react-router-dom"; import { useTranslation } from "react-i18next"; -import { PageSection } from "@patternfly/react-core"; +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"; export const UsersInRoleTab = () => { + const history = useHistory(); + const { realm } = useRealm(); + const { t } = useTranslation("roles"); const { id } = useParams<{ id: string }>(); @@ -33,6 +38,42 @@ export const UsersInRoleTab = () => { loader={loader} ariaLabelKey="roles:roleList" searchPlaceholderKey="" + toolbarItem={ + + {t("roles:whoWillAppearPopoverText")} + + {t("or")} + + + } + footerContent={t("roles:whoWillAppearPopoverFooterText")} + > + + + } emptyState={ Date: Mon, 1 Mar 2021 12:22:01 -0500 Subject: [PATCH 11/19] clean css --- src/realm-roles/RealmRolesSection.css | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/realm-roles/RealmRolesSection.css b/src/realm-roles/RealmRolesSection.css index 296b16b67d..bf8ecdedba 100644 --- a/src/realm-roles/RealmRolesSection.css +++ b/src/realm-roles/RealmRolesSection.css @@ -28,9 +28,7 @@ } .kc-who-will-appear-button { - /* padding-left: 0px; */ - /* padding-top: 0px; */ - margin-bottom: var(--pf-global--spacer--lg);; + padding-left: 0px; } .kc-groups-link { From 5c78afef506a352b6d1f6a762e36b1ba66e2a0d5 Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Mon, 1 Mar 2021 14:09:55 -0500 Subject: [PATCH 12/19] remove useEffect --- src/realm-roles/RealmRolesSection.css | 7 +++---- src/realm-roles/UsersInRoleTab.tsx | 4 ---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/realm-roles/RealmRolesSection.css b/src/realm-roles/RealmRolesSection.css index bf8ecdedba..7e0f4a159d 100644 --- a/src/realm-roles/RealmRolesSection.css +++ b/src/realm-roles/RealmRolesSection.css @@ -24,23 +24,22 @@ --pf-c-form__group--m-action--MarginTop: calc( var(--pf-global--spacer--2xl) - var(--pf-global--spacer--sm) ); - } .kc-who-will-appear-button { padding-left: 0px; } -.kc-groups-link { +.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 - + padding-top: 0px; } diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 300105a177..30eae56cc0 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -27,10 +27,6 @@ export const UsersInRoleTab = () => { return usersWithRole; }; - useEffect(() => { - loader(); - }, []); - return ( <> From 24d136eeed87bbed3d107902e34550a5eabf1af7 Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Mon, 1 Mar 2021 14:20:26 -0500 Subject: [PATCH 13/19] add links to empty state --- .../list-empty-state/ListEmptyState.tsx | 2 +- src/realm-roles/RealmRolesSection.css | 11 ++++++++++ src/realm-roles/UsersInRoleTab.tsx | 22 ++++++++++++++++++- src/realm-roles/messages.json | 5 +++-- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/components/list-empty-state/ListEmptyState.tsx b/src/components/list-empty-state/ListEmptyState.tsx index 3a805477d6..cc095f1c05 100644 --- a/src/components/list-empty-state/ListEmptyState.tsx +++ b/src/components/list-empty-state/ListEmptyState.tsx @@ -19,7 +19,7 @@ export type Action = { export type ListEmptyStateProps = { message: string; - instructions: string; + instructions: React.ReactNode; primaryActionText?: string; onPrimaryAction?: MouseEventHandler; hasIcon?: boolean; diff --git a/src/realm-roles/RealmRolesSection.css b/src/realm-roles/RealmRolesSection.css index 7e0f4a159d..b45ea91f84 100644 --- a/src/realm-roles/RealmRolesSection.css +++ b/src/realm-roles/RealmRolesSection.css @@ -43,3 +43,14 @@ 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); +} + diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 30eae56cc0..979a851057 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -74,7 +74,27 @@ export const UsersInRoleTab = () => { + {t("noUsersEmptyStateDescription")} + + {t("or")} + + {t("noUsersEmptyStateDescriptionContinued")} + + } /> } columns={[ diff --git a/src/realm-roles/messages.json b/src/realm-roles/messages.json index 7adde7343a..02af1031e6 100644 --- a/src/realm-roles/messages.json +++ b/src/realm-roles/messages.json @@ -57,11 +57,12 @@ "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.", + "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", - "users": "Users", "or": "or", + "users": "Users", "userName": "Username", "email": "Email", "lastName": "Last name", From e672ed42ee6e6c8627db9c1b9c097951ca010b03 Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Mon, 1 Mar 2021 14:20:45 -0500 Subject: [PATCH 14/19] fix lint --- src/realm-roles/UsersInRoleTab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 979a851057..ec722d45d4 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React from "react"; import { useHistory, useParams } from "react-router-dom"; import { useTranslation } from "react-i18next"; import { Button, PageSection, Popover } from "@patternfly/react-core"; From f763fa85fbc210dde8fa2ff02c0d44044f478c7e Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Tue, 2 Mar 2021 10:27:33 -0500 Subject: [PATCH 15/19] paginate users table --- src/realm-roles/AssociatedRolesTab.tsx | 26 ++++++++++++++++++++++---- src/realm-roles/RealmRolesSection.tsx | 3 ++- src/realm-roles/UsersInRoleTab.tsx | 7 +++++-- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/realm-roles/AssociatedRolesTab.tsx b/src/realm-roles/AssociatedRolesTab.tsx index 427fe0f716..af4aff606a 100644 --- a/src/realm-roles/AssociatedRolesTab.tsx +++ b/src/realm-roles/AssociatedRolesTab.tsx @@ -51,14 +51,18 @@ export const AssociatedRolesTab = ({ const { id } = useParams<{ id: string }>(); const inheritanceMap = React.useRef<{ [key: string]: string }>({}); + console.log(id) + const getSubRoles = async ( role: RoleRepresentation, - allRoles: RoleRepresentation[] + allRoles: RoleRepresentation[], + first?: number, + max?: number, + search?: string, ): Promise => { + // Fetch all composite roles - const allCompositeRoles = await adminClient.roles.getCompositeRoles({ - id: role.id!, - }); + const allCompositeRoles = await adminClient.roles.getCompositeRoles({id: role.id!}); // Need to ensure we don't get into an infinite loop, do not add any role that is already there or the starting role const newRoles: Promise = allCompositeRoles.reduce( @@ -87,6 +91,8 @@ export const AssociatedRolesTab = ({ return additionalRoles; } + + const allRoles: Promise = additionalRoles.reduce( async (acc: Promise, role) => { const resolvedRoles = await acc; @@ -101,6 +107,17 @@ export const AssociatedRolesTab = ({ return allRoles; }; + + // const loader = async (first?: number, max?: number, search?: string, id?: string) => { + // const params = { + // first: first!, + // max: max!, + // search: search!, + // id: id! + // }; + // return await adminClient.roles.getCompositeRoles({...params}); + // }; + useEffect(() => { refresh(); }, [additionalRoles, isInheritedHidden]); @@ -184,6 +201,7 @@ export const AssociatedRolesTab = ({ { max: max!, search: search!, }; - return await adminClient.roles.find(params); + const x = await adminClient.roles.find(params); + return x; }; return ( <> diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index ec722d45d4..43b2a82b28 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -19,11 +19,13 @@ export const UsersInRoleTab = () => { const adminClient = useAdminClient(); - const loader = async () => { + 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; }; @@ -31,6 +33,7 @@ export const UsersInRoleTab = () => { <> Date: Tue, 2 Mar 2021 10:28:03 -0500 Subject: [PATCH 16/19] cleaning up --- src/realm-roles/AssociatedRolesTab.tsx | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/realm-roles/AssociatedRolesTab.tsx b/src/realm-roles/AssociatedRolesTab.tsx index af4aff606a..f78432a929 100644 --- a/src/realm-roles/AssociatedRolesTab.tsx +++ b/src/realm-roles/AssociatedRolesTab.tsx @@ -56,9 +56,6 @@ export const AssociatedRolesTab = ({ const getSubRoles = async ( role: RoleRepresentation, allRoles: RoleRepresentation[], - first?: number, - max?: number, - search?: string, ): Promise => { // Fetch all composite roles @@ -107,17 +104,6 @@ export const AssociatedRolesTab = ({ return allRoles; }; - - // const loader = async (first?: number, max?: number, search?: string, id?: string) => { - // const params = { - // first: first!, - // max: max!, - // search: search!, - // id: id! - // }; - // return await adminClient.roles.getCompositeRoles({...params}); - // }; - useEffect(() => { refresh(); }, [additionalRoles, isInheritedHidden]); From 74638f9eb33fc406d6e6caf1b798115734e1c4b1 Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Tue, 2 Mar 2021 10:29:04 -0500 Subject: [PATCH 17/19] revert changes to RealmRolesSection --- src/realm-roles/AssociatedRolesTab.tsx | 2 -- src/realm-roles/RealmRolesSection.tsx | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/realm-roles/AssociatedRolesTab.tsx b/src/realm-roles/AssociatedRolesTab.tsx index f78432a929..87fda3162d 100644 --- a/src/realm-roles/AssociatedRolesTab.tsx +++ b/src/realm-roles/AssociatedRolesTab.tsx @@ -51,8 +51,6 @@ export const AssociatedRolesTab = ({ const { id } = useParams<{ id: string }>(); const inheritanceMap = React.useRef<{ [key: string]: string }>({}); - console.log(id) - const getSubRoles = async ( role: RoleRepresentation, allRoles: RoleRepresentation[], diff --git a/src/realm-roles/RealmRolesSection.tsx b/src/realm-roles/RealmRolesSection.tsx index ddf7655d69..0878b3fcca 100644 --- a/src/realm-roles/RealmRolesSection.tsx +++ b/src/realm-roles/RealmRolesSection.tsx @@ -13,8 +13,7 @@ export const RealmRolesSection = () => { max: max!, search: search!, }; - const x = await adminClient.roles.find(params); - return x; + return await adminClient.roles.find(params); }; return ( <> From 78a2c76c79078d3cb4d82ce28c6a3ad552f98dca Mon Sep 17 00:00:00 2001 From: jenny-s51 Date: Tue, 2 Mar 2021 11:11:08 -0500 Subject: [PATCH 18/19] hide popover link when help enabled --- src/components/help-enabler/HelpHeader.tsx | 2 +- src/realm-roles/AssociatedRolesTab.tsx | 9 ++- src/realm-roles/UsersInRoleTab.tsx | 73 ++++++++++++---------- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/components/help-enabler/HelpHeader.tsx b/src/components/help-enabler/HelpHeader.tsx index 9848a12db8..d42cda08a9 100644 --- a/src/components/help-enabler/HelpHeader.tsx +++ b/src/components/help-enabler/HelpHeader.tsx @@ -9,7 +9,7 @@ import { Switch, TextContent, } from "@patternfly/react-core"; -import { Trans, useTranslation } from "react-i18next"; +import { useTranslation } from "react-i18next"; import { HelpIcon, ExternalLinkAltIcon } from "@patternfly/react-icons"; import "./help-header.css"; diff --git a/src/realm-roles/AssociatedRolesTab.tsx b/src/realm-roles/AssociatedRolesTab.tsx index 87fda3162d..39b62ee67f 100644 --- a/src/realm-roles/AssociatedRolesTab.tsx +++ b/src/realm-roles/AssociatedRolesTab.tsx @@ -53,11 +53,12 @@ export const AssociatedRolesTab = ({ const getSubRoles = async ( role: RoleRepresentation, - allRoles: RoleRepresentation[], + allRoles: RoleRepresentation[] ): Promise => { - // Fetch all composite roles - const allCompositeRoles = await adminClient.roles.getCompositeRoles({id: role.id!}); + const allCompositeRoles = await adminClient.roles.getCompositeRoles({ + id: role.id!, + }); // Need to ensure we don't get into an infinite loop, do not add any role that is already there or the starting role const newRoles: Promise = allCompositeRoles.reduce( @@ -86,8 +87,6 @@ export const AssociatedRolesTab = ({ return additionalRoles; } - - const allRoles: Promise = additionalRoles.reduce( async (acc: Promise, role) => { const resolvedRoles = await acc; diff --git a/src/realm-roles/UsersInRoleTab.tsx b/src/realm-roles/UsersInRoleTab.tsx index 43b2a82b28..4a88611b33 100644 --- a/src/realm-roles/UsersInRoleTab.tsx +++ b/src/realm-roles/UsersInRoleTab.tsx @@ -1,4 +1,4 @@ -import React from "react"; +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"; @@ -8,6 +8,7 @@ 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(); @@ -29,6 +30,8 @@ export const UsersInRoleTab = () => { return usersWithRole; }; + const { enabled } = useContext(HelpContext); + return ( <> @@ -38,40 +41,42 @@ export const UsersInRoleTab = () => { ariaLabelKey="roles:roleList" searchPlaceholderKey="" toolbarItem={ - - {t("roles:whoWillAppearPopoverText")} - - {t("or")} - - - } - footerContent={t("roles:whoWillAppearPopoverFooterText")} - > - + {t("or")} + + + } + footerContent={t("roles:whoWillAppearPopoverFooterText")} > - {t("roles:whoWillAppearLinkText")} - - + + + ) } emptyState={ Date: Wed, 3 Mar 2021 09:55:19 -0500 Subject: [PATCH 19/19] cypress tests passing, standardize to match --- cypress/integration/realm_roles_test.spec.ts | 40 ++---------- .../manage/realm_roles/AssociatedRolesPage.ts | 64 +++++++++++++++++++ 2 files changed, 70 insertions(+), 34 deletions(-) create mode 100644 cypress/support/pages/admin_console/manage/realm_roles/AssociatedRolesPage.ts diff --git a/cypress/integration/realm_roles_test.spec.ts b/cypress/integration/realm_roles_test.spec.ts index 92512e2bdb..60da90447e 100644 --- a/cypress/integration/realm_roles_test.spec.ts +++ b/cypress/integration/realm_roles_test.spec.ts @@ -4,6 +4,7 @@ import ModalUtils from "../support/util/ModalUtils"; import ListingPage from "../support/pages/admin_console/ListingPage"; import SidebarPage from "../support/pages/admin_console/SidebarPage"; 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"; const loginPage = new LoginPage(); @@ -12,6 +13,7 @@ const modalUtils = new ModalUtils(); const sidebarPage = new SidebarPage(); const listingPage = new ListingPage(); const createRealmRolePage = new CreateRealmRolePage(); +const associatedRolesPage = new AssociatedRolesPage(); describe("Realm roles test", function () { describe("Realm roles creation", function () { @@ -48,7 +50,7 @@ describe("Realm roles test", function () { listingPage.searchItem(itemId).itemExist(itemId); - // Update + cy.wait(100); // Delete listingPage.deleteItem(itemId); @@ -70,45 +72,15 @@ describe("Realm roles test", function () { masthead.checkNotificationMessage("Role created"); - // Add associated realm role - cy.get("[data-testid=action-dropdown]").last().click(); - - cy.get("[data-testid=add-roles]").click(); - cy.wait(100); - cy.get('[type="checkbox"]').eq(1).check(); + // Add associated realm role - cy.get("[data-testid=add-associated-roles-button]").contains("Add").click(); - - cy.url().should("include", "/AssociatedRoles"); - - cy.get("[data-testid=composite-role-badge]").should("contain.text", "Composite"); - - cy.wait(2500); + associatedRolesPage.addAssociatedRealmRole(); // Add associated client role - cy.get("[data-testid=add-role-button]").click(); - - cy.wait(100); - - cy.get("[data-testid=filter-type-dropdown]").click(); - - cy.get("[data-testid=filter-type-dropdown-item]").click(); - - cy.wait(2500); - - cy.get('[type="checkbox"]').eq(40).check({force: true}); - - cy.get("[data-testid=add-associated-roles-button]").contains("Add").click(); - - cy.wait(2500); - - cy.contains("Users in role") - .click() - .get('[data-testid="users-page"]') - .should('exist') + associatedRolesPage.addAssociatedClientRole(); }); }); }); diff --git a/cypress/support/pages/admin_console/manage/realm_roles/AssociatedRolesPage.ts b/cypress/support/pages/admin_console/manage/realm_roles/AssociatedRolesPage.ts new file mode 100644 index 0000000000..1d8fe1dbd2 --- /dev/null +++ b/cypress/support/pages/admin_console/manage/realm_roles/AssociatedRolesPage.ts @@ -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"); + } +}