keycloak-scim/js/apps/admin-ui/src/user/components/SelectComponent.tsx
Erik Jan de Wit 564441899b
merge all namespaces into one (#22949)
* merge all namespaces into one

added fallback namespace to the configuration to minimize
changes to the keys

* small fix

* Fix the broken `OverridesBackend`

* remove stray console log

* restore ns argument

* PR review

* merge main

---------

Co-authored-by: Jon Koops <jonkoops@gmail.com>
2023-09-08 15:17:17 +02:00

97 lines
2.8 KiB
TypeScript

import { Select, SelectOption } from "@patternfly/react-core";
import { useState } from "react";
import {
Controller,
useFormContext,
ControllerRenderProps,
FieldValues,
} from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Options } from "../UserProfileFields";
import { fieldName, unWrap } from "../utils";
import { UserProfileFieldsProps, UserProfileGroup } from "./UserProfileGroup";
type OptionLabel = Record<string, string> | undefined;
export const SelectComponent = (attribute: UserProfileFieldsProps) => {
const { t } = useTranslation();
const { control } = useFormContext();
const [open, setOpen] = useState(false);
const isMultiValue = (field: ControllerRenderProps<FieldValues, string>) => {
return (
attribute.annotations?.["inputType"] === "multiselect" ||
Array.isArray(field.value)
);
};
const setValue = (
value: string,
field: ControllerRenderProps<FieldValues, string>,
) => {
if (isMultiValue(field)) {
if (field.value.includes(value)) {
field.onChange(field.value.filter((item: string) => item !== value));
} else {
field.onChange([...field.value, value]);
}
} else {
field.onChange(value);
}
};
const options =
(attribute.validations?.options as Options | undefined)?.options || [];
const optionLabel = attribute.annotations?.[
"inputOptionLabels"
] as OptionLabel;
const label = (label: string) =>
optionLabel ? t(unWrap(optionLabel[label])) : label;
return (
<UserProfileGroup {...attribute}>
<Controller
name={fieldName(attribute)}
defaultValue=""
control={control}
render={({ field }) => (
<Select
toggleId={attribute.name}
onToggle={(b) => setOpen(b)}
isCreatable
onCreateOption={(value) => setValue(value, field)}
onSelect={(_, value) => {
const option = value.toString();
setValue(option, field);
if (!Array.isArray(field.value)) {
setOpen(false);
}
}}
selections={
field.value
? field.value
: isMultiValue(field)
? []
: t("common:choose")
}
variant={isMultiValue(field) ? "typeaheadmulti" : "single"}
aria-label={t("common:selectOne")}
isOpen={open}
readOnly={attribute.readOnly}
>
{options.map((option) => (
<SelectOption
selected={field.value === option}
key={option}
value={option}
>
{label(option)}
</SelectOption>
))}
</Select>
)}
/>
</UserProfileGroup>
);
};