diff --git a/src/client-scopes/add/MapperDialog.test.tsx b/src/client-scopes/add/MapperDialog.test.tsx index f725d4cce9..a1cf6b3aab 100644 --- a/src/client-scopes/add/MapperDialog.test.tsx +++ b/src/client-scopes/add/MapperDialog.test.tsx @@ -1,13 +1,18 @@ /** * @jest-environment jsdom */ -import { Button } from "@patternfly/react-core"; -import { fireEvent, render, screen } from "@testing-library/react"; -import type { ServerInfoRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation"; import React, { useState } from "react"; +import { fireEvent, render, screen } from "@testing-library/react"; +import { Button } from "@patternfly/react-core"; + +import type { ServerInfoRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation"; +import type WhoAmIRepresentation from "@keycloak/keycloak-admin-client/lib/defs/whoAmIRepresentation"; import { ServerInfoContext } from "../../context/server-info/ServerInfoProvider"; import serverInfo from "../../context/server-info/__tests__/mock.json"; import { AddMapperDialog, AddMapperDialogModalProps } from "./MapperDialog"; +import { WhoAmI, WhoAmIContext } from "../../context/whoami/WhoAmI"; + +import whoami from "../../context/whoami/__tests__/mock-whoami.json"; describe("MapperDialog", () => { const Test = (args: AddMapperDialogModalProps) => { @@ -17,12 +22,21 @@ describe("MapperDialog", () => { - setOpen(!open)} - /> - + {}, + whoAmI: new WhoAmI(whoami as WhoAmIRepresentation), + }} + > + setOpen(!open)} + /> + + ); }; @@ -59,7 +73,7 @@ describe("MapperDialog", () => { render(); fireEvent.click(screen.getByText("Show")); - fireEvent.click(screen.getByLabelText("User Realm Role")); + fireEvent.click(screen.getByLabelText("Allowed Web Origins")); expect(onConfirm).toBeCalledWith( serverInfo.protocolMapperTypes[protocol][0] diff --git a/src/client-scopes/add/MapperDialog.tsx b/src/client-scopes/add/MapperDialog.tsx index d27d10f97e..0bb16671db 100644 --- a/src/client-scopes/add/MapperDialog.tsx +++ b/src/client-scopes/add/MapperDialog.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useMemo, useState } from "react"; import { Button, ButtonVariant, @@ -11,6 +11,7 @@ import { ModalVariant, Text, TextContent, + TextVariants, } from "@patternfly/react-core"; import { Table, @@ -23,6 +24,7 @@ import type ProtocolMapperRepresentation from "@keycloak/keycloak-admin-client/l import type { ProtocolMapperTypeRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation"; import { useServerInfo } from "../../context/server-info/ServerInfoProvider"; +import { useWhoAmI } from "../../context/whoami/WhoAmI"; import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState"; export type AddMapperDialogModalProps = { @@ -42,21 +44,28 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => { const { t } = useTranslation("client-scopes"); const serverInfo = useServerInfo(); + const { whoAmI } = useWhoAmI(); const protocol = props.protocol; const protocolMappers = serverInfo.protocolMapperTypes![protocol]; const builtInMappers = serverInfo.builtinProtocolMappers![protocol]; const [filter, setFilter] = useState([]); - const allRows = builtInMappers.map((mapper) => { - const mapperType = protocolMappers.filter( - (type) => type.id === mapper.protocolMapper - )[0]; - return { - item: mapper, - selected: false, - cells: [mapper.name, mapperType.helpText], - }; - }); + const allRows = useMemo( + () => + builtInMappers + .sort((a, b) => a.name!.localeCompare(b.name!, whoAmI.getLocale())) + .map((mapper) => { + const mapperType = protocolMappers.filter( + (type) => type.id === mapper.protocolMapper + )[0]; + return { + item: mapper, + selected: false, + cells: [mapper.name, mapperType.helpText], + }; + }), + [] + ); const [rows, setRows] = useState(allRows); if (props.filter && props.filter.length !== filter.length) { @@ -68,12 +77,29 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => { const selectedRows = rows .filter((row) => row.selected) .map((row) => row.item); + + const sortedProtocolMappers = useMemo( + () => + protocolMappers.sort((a, b) => + a.name!.localeCompare(b.name!, whoAmI.getLocale()) + ), + [protocolMappers] + ); + const isBuiltIn = !!props.filter; + const header = [t("common:name"), t("common:description")]; + return ( + {t("chooseAMapperType")} + {t("predefinedMappingDescription")} + + } isOpen={props.open} onClose={props.toggleDialog} actions={ @@ -105,9 +131,6 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => { : [] } > - - {t("predefinedMappingDescription")} - {!isBuiltIn && ( { @@ -118,7 +141,18 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => { aria-label={t("chooseAMapperType")} isCompact > - {protocolMappers.map((mapper) => ( + + + ( + + {name} + + ))} + /> + + + {sortedProtocolMappers.map((mapper) => ( { {isBuiltIn && rows.length > 0 && ( { rows[rowIndex].selected = isSelected; setRows([...rows]); diff --git a/src/common-messages.ts b/src/common-messages.ts index 7cd00b7f0d..87affd67bf 100644 --- a/src/common-messages.ts +++ b/src/common-messages.ts @@ -49,6 +49,7 @@ export default { enableHelpMode: "Enable help mode", learnMore: "Learn more", test: "Test", + testConnection: "Test connection", name: "Name", role: "Role", description: "Description", diff --git a/src/realm-settings/AddUserEmailModal.tsx b/src/realm-settings/AddUserEmailModal.tsx index 9ddcb814a5..c10530e811 100644 --- a/src/realm-settings/AddUserEmailModal.tsx +++ b/src/realm-settings/AddUserEmailModal.tsx @@ -50,7 +50,7 @@ export const AddUserEmailModal = ({ form="email-form" isDisabled={!watchEmailInput} > - {t("realm-settings:testConnection")} + {t("common:testConnection")} , + testLdap()} + onClick={() => testLdap("testAuthentication")} > - {t("common:test")} + {t("testAuthentication")} diff --git a/src/user-federation/messages.ts b/src/user-federation/messages.ts index 96b2049fed..dfb20456d4 100644 --- a/src/user-federation/messages.ts +++ b/src/user-federation/messages.ts @@ -90,6 +90,7 @@ export default { saveError: "User federation provider could not be saved: {{error}}", createSuccess: "User federation provider successfully created", createError: "User federation provider could not be created: {{error}}", + testAuthentication: "Test authentication", testSuccess: "Successfully connected to LDAP", testError: "Error when trying to connect to LDAP. See server.log for details. {{error}}",