converted client select to ui-shared (#27799)

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
Erik Jan de Wit 2024-03-14 13:41:36 +01:00 committed by GitHub
parent 42244d2a67
commit 63bd46b8cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 66 deletions

View file

@ -1,15 +1,9 @@
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
import type { ClientQuery } from "@keycloak/keycloak-admin-client/lib/resources/clients";
import {
FormGroup,
Select,
SelectOption,
SelectVariant,
} from "@patternfly/react-core";
import { SelectVariant } from "@patternfly/react-core";
import { useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem } from "ui-shared";
import { SelectControl } from "ui-shared";
import { adminClient } from "../../admin-client";
import { useFetch } from "../../utils/useFetch";
@ -26,12 +20,7 @@ export const ClientSelect = ({
required = false,
}: ClientSelectProps) => {
const { t } = useTranslation();
const {
control,
formState: { errors },
} = useFormContext();
const [open, setOpen] = useState(false);
const [clients, setClients] = useState<ClientRepresentation[]>([]);
const [search, setSearch] = useState("");
@ -50,51 +39,27 @@ export const ClientSelect = ({
[search],
);
const convert = (clients: ClientRepresentation[]) => [
<SelectOption key="empty" value="">
{t("none")}
</SelectOption>,
...clients.map((option) => (
<SelectOption key={option.id} value={option.clientId} />
)),
];
return (
<FormGroup
label={t(label!)}
isRequired={required}
labelIcon={<HelpItem helpText={t(helpText!)} fieldLabelId={label!} />}
fieldId={name!}
validated={errors[name!] ? "error" : "default"}
helperTextInvalid={t("required")}
>
<Controller
<SelectControl
name={name!}
defaultValue={defaultValue || ""}
control={control}
rules={required ? { required: true } : {}}
render={({ field }) => (
<Select
toggleId={name}
label={t(label!)}
labelIcon={t(helpText!)}
controller={{
defaultValue: defaultValue || "",
rules: {
required: {
value: required,
message: t("required"),
},
},
}}
onFilter={(value) => setSearch(value)}
variant={SelectVariant.typeahead}
onToggle={(open) => setOpen(open)}
isOpen={open}
isDisabled={isDisabled}
selections={field.value}
onFilter={(_, value) => {
setSearch(value);
return convert(clients);
}}
onSelect={(_, value) => {
field.onChange(value.toString());
setOpen(false);
}}
typeAheadAriaLabel={t(label!)}
>
{convert(clients)}
</Select>
)}
options={[
{ key: "", value: t("none") },
...clients.map(({ id, clientId }) => ({ key: id!, value: clientId! })),
]}
/>
</FormGroup>
);
};

View file

@ -26,7 +26,13 @@ export type SelectControlProps<
P extends FieldPath<T> = FieldPath<T>,
> = Omit<
SelectProps,
"name" | "onToggle" | "selections" | "onSelect" | "onClear" | "isOpen"
| "name"
| "onToggle"
| "selections"
| "onSelect"
| "onClear"
| "isOpen"
| "onFilter"
> &
UseControllerProps<T, P> & {
name: string;
@ -34,6 +40,7 @@ export type SelectControlProps<
options: string[] | SelectControlOption[];
labelIcon?: string;
controller: Omit<ControllerProps, "name" | "render">;
onFilter?: (value: string) => void;
};
export const SelectControl = <
@ -46,6 +53,7 @@ export const SelectControl = <
controller,
variant = SelectVariant.single,
labelIcon,
onFilter,
...rest
}: SelectControlProps<T, P>) => {
const {
@ -53,6 +61,15 @@ export const SelectControl = <
formState: { errors },
} = useFormContext();
const [open, setOpen] = useState(false);
const convert = () =>
options.map((option) => (
<SelectOption
key={typeof option === "string" ? option : option.key}
value={typeof option === "string" ? option : option.key}
>
{typeof option === "string" ? option : option.value}
</SelectOption>
));
return (
<FormLabel
name={name}
@ -98,20 +115,17 @@ export const SelectControl = <
}
: undefined
}
onFilter={(_, value) => {
onFilter?.(value);
return convert();
}}
isOpen={open}
variant={variant}
validated={
errors[name] ? ValidatedOptions.error : ValidatedOptions.default
}
>
{options.map((option) => (
<SelectOption
key={typeof option === "string" ? option : option.key}
value={typeof option === "string" ? option : option.key}
>
{typeof option === "string" ? option : option.value}
</SelectOption>
))}
{convert()}
</Select>
)}
/>