Mappers are now sorted (#2700)
This commit is contained in:
parent
8828b20a57
commit
be000ff08c
3 changed files with 43 additions and 42 deletions
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"addMultivaluedLabel": "Add {{fieldLabel}}",
|
"addMultivaluedLabel": "Add {{fieldLabel}}",
|
||||||
"selectARole": "Select a role",
|
"selectARole": "Select a role",
|
||||||
|
"selectGroup": "Select group",
|
||||||
"usermodel": {
|
"usermodel": {
|
||||||
"prop": {
|
"prop": {
|
||||||
"label": "Property",
|
"label": "Property",
|
||||||
|
|
|
@ -35,6 +35,7 @@ import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinn
|
||||||
import type { AttributeForm } from "../../components/key-value-form/AttributeForm";
|
import type { AttributeForm } from "../../components/key-value-form/AttributeForm";
|
||||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||||
|
import useLocaleSort, { mapByKey } from "../../utils/useLocaleSort";
|
||||||
|
|
||||||
export type IdPMapperRepresentationWithAttributes =
|
export type IdPMapperRepresentationWithAttributes =
|
||||||
IdentityProviderMapperRepresentation & AttributeForm;
|
IdentityProviderMapperRepresentation & AttributeForm;
|
||||||
|
@ -52,6 +53,7 @@ export default function AddMapper() {
|
||||||
const { handleSubmit, register, errors } = form;
|
const { handleSubmit, register, errors } = form;
|
||||||
const { addAlert, addError } = useAlerts();
|
const { addAlert, addError } = useAlerts();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const localeSort = useLocaleSort();
|
||||||
|
|
||||||
const { realm } = useRealm();
|
const { realm } = useRealm();
|
||||||
const adminClient = useAdminClient();
|
const adminClient = useAdminClient();
|
||||||
|
@ -60,11 +62,10 @@ export default function AddMapper() {
|
||||||
const { id } = useParams<IdentityProviderEditMapperParams>();
|
const { id } = useParams<IdentityProviderEditMapperParams>();
|
||||||
|
|
||||||
const [mapperTypes, setMapperTypes] =
|
const [mapperTypes, setMapperTypes] =
|
||||||
useState<Record<string, IdentityProviderMapperTypeRepresentation>>();
|
useState<IdentityProviderMapperTypeRepresentation[]>();
|
||||||
const [mapperType, setMapperType] = useState<string>();
|
|
||||||
|
|
||||||
const [currentMapper, setCurrentMapper] =
|
const [currentMapper, setCurrentMapper] =
|
||||||
useState<IdentityProviderMapperRepresentation>();
|
useState<IdentityProviderMapperTypeRepresentation>();
|
||||||
|
|
||||||
const save = async (idpMapper: IdentityProviderMapperRepresentation) => {
|
const save = async (idpMapper: IdentityProviderMapperRepresentation) => {
|
||||||
const mapper = convertFormValuesToObject(
|
const mapper = convertFormValuesToObject(
|
||||||
|
@ -148,15 +149,17 @@ export default function AddMapper() {
|
||||||
adminClient.identityProviders.findMapperTypes({ alias }),
|
adminClient.identityProviders.findMapperTypes({ alias }),
|
||||||
]),
|
]),
|
||||||
([mapper, mapperTypes]) => {
|
([mapper, mapperTypes]) => {
|
||||||
|
const mappers = localeSort(Object.values(mapperTypes), mapByKey("name"));
|
||||||
if (mapper) {
|
if (mapper) {
|
||||||
setCurrentMapper(mapper);
|
setCurrentMapper(
|
||||||
|
mappers.find(({ id }) => id === mapper.identityProviderMapper)
|
||||||
|
);
|
||||||
setupForm(mapper);
|
setupForm(mapper);
|
||||||
setMapperType(mapper.identityProviderMapper!);
|
|
||||||
} else {
|
} else {
|
||||||
setMapperType(Object.keys(mapperTypes)[0]);
|
setCurrentMapper(mappers[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setMapperTypes(mapperTypes);
|
setMapperTypes(mappers);
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
@ -167,7 +170,7 @@ export default function AddMapper() {
|
||||||
form.setValue("config.claims", JSON.parse(mapper.config.claims));
|
form.setValue("config.claims", JSON.parse(mapper.config.claims));
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!mapperTypes) {
|
if (!mapperTypes || !currentMapper) {
|
||||||
return <KeycloakSpinner />;
|
return <KeycloakSpinner />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +219,7 @@ export default function AddMapper() {
|
||||||
<KeycloakTextInput
|
<KeycloakTextInput
|
||||||
ref={register()}
|
ref={register()}
|
||||||
type="text"
|
type="text"
|
||||||
value={currentMapper?.id}
|
value={currentMapper.id}
|
||||||
datatest-id="name-input"
|
datatest-id="name-input"
|
||||||
id="kc-name"
|
id="kc-name"
|
||||||
name="name"
|
name="name"
|
||||||
|
@ -227,20 +230,21 @@ export default function AddMapper() {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
<AddMapperForm
|
{currentMapper.properties && (
|
||||||
form={form}
|
<>
|
||||||
id={id}
|
<AddMapperForm
|
||||||
mapperTypes={mapperTypes}
|
form={form}
|
||||||
updateMapperType={setMapperType}
|
id={id}
|
||||||
mapperType={mapperType!}
|
mapperTypes={mapperTypes}
|
||||||
/>
|
updateMapperType={setCurrentMapper}
|
||||||
<FormProvider {...form}>
|
mapperType={currentMapper}
|
||||||
{mapperType && mapperTypes[mapperType].properties && (
|
|
||||||
<DynamicComponents
|
|
||||||
properties={mapperTypes[mapperType].properties!}
|
|
||||||
/>
|
/>
|
||||||
)}
|
<FormProvider {...form}>
|
||||||
</FormProvider>
|
<DynamicComponents properties={currentMapper.properties!} />
|
||||||
|
</FormProvider>{" "}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<ActionGroup>
|
<ActionGroup>
|
||||||
<Button
|
<Button
|
||||||
data-testid="new-mapper-save-button"
|
data-testid="new-mapper-save-button"
|
||||||
|
|
|
@ -9,17 +9,19 @@ import {
|
||||||
ValidatedOptions,
|
ValidatedOptions,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
|
|
||||||
|
import type { IdentityProviderMapperTypeRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/identityProviderMapperTypeRepresentation";
|
||||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||||
import type IdentityProviderMapperRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderMapperRepresentation";
|
import type IdentityProviderMapperRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderMapperRepresentation";
|
||||||
import type { IdPMapperRepresentationWithAttributes } from "./AddMapper";
|
import type { IdPMapperRepresentationWithAttributes } from "./AddMapper";
|
||||||
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
|
||||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||||
|
|
||||||
type AddMapperFormProps = {
|
type AddMapperFormProps = {
|
||||||
mapperTypes: Record<string, IdentityProviderMapperRepresentation>;
|
mapperTypes: IdentityProviderMapperRepresentation[];
|
||||||
mapperType: string;
|
mapperType: IdentityProviderMapperTypeRepresentation;
|
||||||
id: string;
|
id: string;
|
||||||
updateMapperType: (mapperType: string) => void;
|
updateMapperType: (
|
||||||
|
mapperType: IdentityProviderMapperTypeRepresentation
|
||||||
|
) => void;
|
||||||
form: UseFormMethods<IdPMapperRepresentationWithAttributes>;
|
form: UseFormMethods<IdPMapperRepresentationWithAttributes>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,10 +40,6 @@ export const AddMapperForm = ({
|
||||||
|
|
||||||
const syncModes = ["inherit", "import", "legacy", "force"];
|
const syncModes = ["inherit", "import", "legacy", "force"];
|
||||||
const [syncModeOpen, setSyncModeOpen] = useState(false);
|
const [syncModeOpen, setSyncModeOpen] = useState(false);
|
||||||
const serverInfo = useServerInfo();
|
|
||||||
const mapper = serverInfo.componentTypes?.[
|
|
||||||
"org.keycloak.broker.provider.IdentityProviderMapper"
|
|
||||||
].find((p) => p.id === mapperType);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -121,7 +119,7 @@ export const AddMapperForm = ({
|
||||||
label={t("mapperType")}
|
label={t("mapperType")}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<HelpItem
|
<HelpItem
|
||||||
helpText={mapper?.helpText}
|
helpText={mapperType.helpText}
|
||||||
fieldLabelId="identity-providers:mapperType"
|
fieldLabelId="identity-providers:mapperType"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
@ -129,7 +127,7 @@ export const AddMapperForm = ({
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="identityProviderMapper"
|
name="identityProviderMapper"
|
||||||
defaultValue={Object.keys(mapperTypes)[0]}
|
defaultValue={mapperTypes[0].id}
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
|
@ -139,25 +137,23 @@ export const AddMapperForm = ({
|
||||||
required
|
required
|
||||||
onToggle={() => setMapperTypeOpen(!mapperTypeOpen)}
|
onToggle={() => setMapperTypeOpen(!mapperTypeOpen)}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
updateMapperType(value.toString());
|
const mapperType =
|
||||||
onChange(value.toString());
|
value as IdentityProviderMapperTypeRepresentation;
|
||||||
|
updateMapperType(mapperType);
|
||||||
|
onChange(mapperType.id);
|
||||||
setMapperTypeOpen(false);
|
setMapperTypeOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={
|
selections={mapperType.name}
|
||||||
Object.values(mapperTypes).find(
|
|
||||||
(item) => item.id?.toLowerCase() === value
|
|
||||||
)?.name
|
|
||||||
}
|
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
aria-label={t("syncMode")}
|
aria-label={t("mapperType")}
|
||||||
isOpen={mapperTypeOpen}
|
isOpen={mapperTypeOpen}
|
||||||
>
|
>
|
||||||
{Object.values(mapperTypes).map((option) => (
|
{mapperTypes.map((option) => (
|
||||||
<SelectOption
|
<SelectOption
|
||||||
selected={option === value}
|
selected={option === value}
|
||||||
datatest-id={option.id}
|
datatest-id={option.id}
|
||||||
key={option.name}
|
key={option.name}
|
||||||
value={option.id}
|
value={option}
|
||||||
>
|
>
|
||||||
{option.name}
|
{option.name}
|
||||||
</SelectOption>
|
</SelectOption>
|
||||||
|
|
Loading…
Reference in a new issue