fixed when client select is a id instead of an clientId (#38974)

fixes: #38929

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
Erik Jan de Wit 2025-04-16 18:18:21 +02:00 committed by GitHub
parent 1197885164
commit 025ee4ee6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 57 additions and 2 deletions

View File

@ -2,6 +2,7 @@ import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/
import type { ClientQuery } from "@keycloak/keycloak-admin-client/lib/resources/clients";
import {
SelectControl,
SelectControlOption,
SelectVariant,
useFetch,
} from "@keycloak/keycloak-ui-shared";
@ -11,6 +12,7 @@ import { useAdminClient } from "../../admin-client";
import type { ComponentProps } from "../dynamic/components";
import { PermissionsConfigurationTabsParams } from "../../permissions-configuration/routes/PermissionsConfigurationTabs";
import { useParams } from "react-router-dom";
import { useFormContext, useWatch } from "react-hook-form";
type ClientSelectProps = Omit<ComponentProps, "convertToName"> & {
variant?: `${SelectVariant}`;
@ -35,9 +37,18 @@ export const ClientSelect = ({
const { t } = useTranslation();
const [clients, setClients] = useState<ClientRepresentation[]>([]);
const [selectedClients, setSelectedClients] =
useState<SelectControlOption[]>();
const [search, setSearch] = useState("");
const { tab } = useParams<PermissionsConfigurationTabsParams>();
const { control } = useFormContext();
const value = useWatch({
control,
name: name!,
defaultValue: defaultValue || "",
});
useFetch(
() => {
const params: ClientQuery = {
@ -53,6 +64,30 @@ export const ClientSelect = ({
[search],
);
useFetch(
() => {
const values = ((value as string[]) || []).map(async (clientId) => {
if (clientKey === "clientId") {
return (await adminClient.clients.find({ clientId }))[0];
} else {
return adminClient.clients.findOne({ id: clientId });
}
});
return Promise.all(values);
},
(clients) => {
setSelectedClients(
clients
.filter((client) => !!client)
.map((client) => ({
key: client[clientKey] as string,
value: client.clientId!,
})),
);
},
[],
);
return (
<SelectControl
name={name!}
@ -70,6 +105,7 @@ export const ClientSelect = ({
onFilter={(value) => setSearch(value)}
variant={variant}
isDisabled={isDisabled}
selectedOptions={selectedClients}
options={clients.map((client) => ({
key: client[clientKey] as string,
value: client.clientId!,

View File

@ -41,6 +41,7 @@ export type SelectControlProps<
name: string;
label?: string;
options: OptionType;
selectedOptions?: SelectControlOption[];
labelIcon?: string;
controller: Omit<ControllerProps, "name" | "render">;
onFilter?: (value: string) => void;

View File

@ -43,6 +43,7 @@ export const TypeaheadSelectControl = <
name,
label,
options,
selectedOptions = [],
controller,
labelIcon,
placeholderText,
@ -57,6 +58,9 @@ export const TypeaheadSelectControl = <
const [open, setOpen] = useState(false);
const [filterValue, setFilterValue] = useState("");
const [focusedItemIndex, setFocusedItemIndex] = useState<number>(0);
const [selectedOptionsState, setSelectedOptions] = useState<
SelectControlOption[]
>([]);
const textInputRef = useRef<HTMLInputElement>();
const required = getRuleValue(controller.rules?.required) === true;
const isTypeaheadMulti = variant === SelectVariant.typeaheadMulti;
@ -85,8 +89,19 @@ export const TypeaheadSelectControl = <
) => {
if (field.value.includes(option)) {
field.onChange(field.value.filter((item: string) => item !== option));
if (isSelectBasedOptions(options)) {
setSelectedOptions(
selectedOptionsState.filter((item) => item.key !== option),
);
}
} else {
field.onChange([...field.value, option]);
if (isSelectBasedOptions(options)) {
setSelectedOptions([
...selectedOptionsState,
options.find((o) => o.key === option)!,
]);
}
}
};
@ -240,8 +255,11 @@ export const TypeaheadSelectControl = <
}}
>
{isSelectBasedOptions(options)
? options.find((o) => selection === o.key)
?.value
? [
...options,
...selectedOptionsState,
...selectedOptions,
].find((o) => selection === o.key)?.value
: getValue(selection)}
</Chip>
),