From 29cf962f193b0d8721c8ad48a8f1d54b5cdd4e95 Mon Sep 17 00:00:00 2001 From: Erik Jan de Wit Date: Tue, 6 Sep 2022 15:34:11 +0200 Subject: [PATCH] The role picker no longer queries all clients (#3197) --- .../identity_providers/AddMapperPage.ts | 14 +- .../manage/providers/ProviderPage.ts | 13 +- .../src/components/dynamic/RoleComponent.tsx | 229 ++++-------------- .../components/role-mapping/RoleMapping.tsx | 2 +- 4 files changed, 56 insertions(+), 202 deletions(-) diff --git a/apps/admin-ui/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts b/apps/admin-ui/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts index 30c0e20fb6..520f9020d1 100644 --- a/apps/admin-ui/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts +++ b/apps/admin-ui/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts @@ -87,17 +87,9 @@ export default class AddMapperPage { } addRoleToMapperForm() { - cy.get("#group-role-select-typeahead") - .click() - .get(".pf-c-select__menu-item") - .first() - .click(); - cy.get("#role-role-select-typeahead") - .click() - .get(".pf-c-select__menu-item") - .first() - .click(); - + cy.findByTestId("add-roles").click(); + cy.get("[aria-label='Select row 1']").click(); + cy.findByTestId("assign").click(); return this; } diff --git a/apps/admin-ui/cypress/support/pages/admin_console/manage/providers/ProviderPage.ts b/apps/admin-ui/cypress/support/pages/admin_console/manage/providers/ProviderPage.ts index 9fb378e429..15df264329 100644 --- a/apps/admin-ui/cypress/support/pages/admin_console/manage/providers/ProviderPage.ts +++ b/apps/admin-ui/cypress/support/pages/admin_console/manage/providers/ProviderPage.ts @@ -371,16 +371,9 @@ export default class ProviderPage { break; case this.hcLdapRoleMapper: - cy.get("#group-role-select-typeahead") - .click() - .get(".pf-c-select__menu-item") - .first() - .click(); - cy.get("#role-role-select-typeahead") - .click() - .get(".pf-c-select__menu-item") - .first() - .click(); + cy.findByTestId("add-roles").click(); + cy.get("[aria-label='Select row 1']").click(); + cy.findByTestId("assign").click(); break; default: console.log("Invalid mapper type."); diff --git a/apps/admin-ui/src/components/dynamic/RoleComponent.tsx b/apps/admin-ui/src/components/dynamic/RoleComponent.tsx index 208bd663b2..efdf353f0a 100644 --- a/apps/admin-ui/src/components/dynamic/RoleComponent.tsx +++ b/apps/admin-ui/src/components/dynamic/RoleComponent.tsx @@ -1,138 +1,42 @@ -import { useEffect, useState } from "react"; -import { Controller, useFormContext } from "react-hook-form"; import { useTranslation } from "react-i18next"; +import { Controller, useFormContext } from "react-hook-form"; import { - Divider, + Button, + Chip, FormGroup, - Select, - SelectGroup, - SelectOption, - SelectVariant, Split, SplitItem, } from "@patternfly/react-core"; -import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation"; -import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation"; -import { useAdminClient, useFetch } from "../../context/auth/AdminClient"; -import { useRealm } from "../../context/realm-context/RealmContext"; -import { HelpItem } from "../help-enabler/HelpItem"; import type { ComponentProps } from "./components"; +import { HelpItem } from "../help-enabler/HelpItem"; +import useToggle from "../../utils/useToggle"; +import { AddRoleMappingModal } from "../role-mapping/AddRoleMappingModal"; +import { ServiceRole, Row } from "../role-mapping/RoleMapping"; import { convertToName } from "./DynamicComponents"; -const RealmClient = (realm: string): ClientRepresentation => ({ - name: "realmRoles", - clientId: realm, -}); +const parseValue = (value: any) => + value?.includes(".") ? value.split(".") : ["", value || ""]; + +const parseRow = (value: Row) => + value.client?.clientId + ? `${value.client.clientId}.${value.role.name}` + : value.role.name; export const RoleComponent = ({ name, label, helpText, + defaultValue, isDisabled = false, }: ComponentProps) => { const { t } = useTranslation("dynamic"); - const { adminClient } = useAdminClient(); - const { realm } = useRealm(); - const { - control, - getValues, - formState: { errors }, - } = useFormContext(); - - const [roleOpen, setRoleOpen] = useState(false); - const [clientsOpen, setClientsOpen] = useState(false); - const [clients, setClients] = useState(); - const [selectedClient, setSelectedClient] = useState(); - const [clientRoles, setClientRoles] = useState([]); - const [selectedRole, setSelectedRole] = useState(); + const [openModal, toggleModal] = useToggle(); + const { control, errors } = useFormContext(); const fieldName = convertToName(name!); - useFetch( - async () => { - const clients = await adminClient.clients.find(); - - const asyncFilter = async ( - predicate: (client: ClientRepresentation) => Promise - ) => { - const results = await Promise.all(clients.map(predicate)); - return clients.filter((_, index) => results[index]); - }; - - const filteredClients = await asyncFilter( - async (client) => - (await adminClient.clients.listRoles({ id: client.id! })).length > 0 - ); - - return filteredClients; - }, - (filteredClients) => setClients(filteredClients), - [] - ); - - useEffect(() => { - const value = getValues(fieldName); - const [client, role] = value?.includes(".") - ? value.split(".") - : ["", value || ""]; - if (client) { - setSelectedClient(clients?.find((c) => c.clientId === client)); - } else { - setSelectedClient(RealmClient(realm)); - } - setSelectedRole({ name: role }); - }, [clients, getValues]); - - const createSelectGroup = (clients: ClientRepresentation[]) => { - return [ - - - {realm} - - , - , - - {clients.map((client) => ( - - {client.clientId} - - ))} - , - ]; - }; - - const roleSelectOptions = () => { - const createItem = (role: RoleRepresentation) => ( - - {role.name} - - ); - return clientRoles.map((role) => createItem(role)); - }; - - useFetch( - async () => { - if (selectedClient && selectedClient.name !== "realmRoles") { - const clientRoles = await adminClient.clients.listRoles({ - id: selectedClient.id!, - }); - return clientRoles; - } else { - return await adminClient.roles.find(); - } - }, - (clientRoles) => setClientRoles(clientRoles), - [selectedClient] - ); - - const onClear = (onChange: (value: string) => void) => { - setSelectedClient(undefined); - setSelectedRole(undefined); - onChange(""); - }; - return ( ( - + render={({ onChange, value }) => ( + + {openModal && ( + onChange(parseRow(rows[0]))} + onClose={toggleModal} + isRadio + /> + )} + + {value !== "" && ( + + onChange("")}> + + + + )} - {clients && ( - - )} - - - + {t("selectRole.label")} + )} diff --git a/apps/admin-ui/src/components/role-mapping/RoleMapping.tsx b/apps/admin-ui/src/components/role-mapping/RoleMapping.tsx index 83b0ebb3b1..378ed6dcf1 100644 --- a/apps/admin-ui/src/components/role-mapping/RoleMapping.tsx +++ b/apps/admin-ui/src/components/role-mapping/RoleMapping.tsx @@ -60,7 +60,7 @@ export const mapRoles = ( export const ServiceRole = ({ role, client }: Row) => ( <> - {client && ( + {client?.clientId && ( {client.clientId}