added locale selector for account console

fixes: #20941
This commit is contained in:
Erik Jan de Wit 2023-07-03 12:06:56 +02:00 committed by Pedro Igor
parent c3c544b907
commit 2f5040f565
7 changed files with 78 additions and 6 deletions

View file

@ -115,6 +115,7 @@
"resourceSharedWith_one": "Resource is shared with <0>{{username}}</0>",
"resourceSharedWith_other": "Resource is shared with <0>{{username}}</0> and <1>{{other}}</1> other users",
"resourceSharedWith_zero": "This resource is not shared.",
"selectALocale": "Select a locale",
"selectOne": "Select an option",
"setUpNew": "Set up {{0}}",
"share": "Share",

View file

@ -29,6 +29,13 @@ export async function getPersonalInfo({
return parseResponse<UserRepresentation>(response);
}
export async function supportedLocales({ signal }: CallOptions = {}): Promise<
string[]
> {
const response = await request("/supportedLocales", { signal });
return parseResponse<string[]>(response);
}
export async function savePersonalInfo(
info: UserRepresentation
): Promise<void> {

View file

@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next";
import { KeycloakTextInput } from "ui-shared";
import { UserProfileAttributeMetadata } from "../api/representations";
import { TFuncKey } from "../i18n";
import { LocaleSelector } from "./LocaleSelector";
import { fieldName, isBundleKey, unWrap } from "./PersonalInfo";
type FormFieldProps = {
@ -25,6 +26,7 @@ export const FormField = ({ attribute }: FormFieldProps) => {
const isSelect = (attribute: UserProfileAttributeMetadata) =>
Object.hasOwn(attribute.validators, "options");
if (attribute.name === "locale") return <LocaleSelector />;
return (
<FormGroup
key={attribute.name}

View file

@ -0,0 +1,43 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import type { Option } from "ui-shared";
import { SelectControl } from "ui-shared";
import { supportedLocales } from "../api/methods";
import { usePromise } from "../utils/usePromise";
const localeToDisplayName = (locale: string) => {
try {
return new Intl.DisplayNames([locale], { type: "language" }).of(locale);
} catch (error) {
return locale;
}
};
export const LocaleSelector = () => {
const { t } = useTranslation();
const [locales, setLocales] = useState<Option[]>([]);
usePromise(
(signal) => supportedLocales({ signal }),
(locales) =>
setLocales(
locales.map(
(l) =>
({
key: l,
value: localeToDisplayName(l),
} as Option)
)
)
);
return (
<SelectControl
id="locale-select"
name="attributes.locale"
label={t("selectALocale")}
controller={{ defaultValue: "" }}
options={locales}
/>
);
};

View file

@ -15,7 +15,7 @@ import {
} from "@patternfly/react-core";
import { FormLabel } from "./FormLabel";
type Option = {
export type Option = {
key: string;
value: string;
};
@ -42,6 +42,7 @@ export const SelectControl = <
label,
options,
controller,
variant,
...rest
}: SelectControlProps<T, P>) => {
const {
@ -65,20 +66,31 @@ export const SelectControl = <
{...rest}
toggleId={name}
onToggle={(isOpen) => setOpen(isOpen)}
selections={value}
selections={
typeof options[0] !== "string"
? (options as Option[]).find((o) => o.key === value[0])
?.value || value
: value
}
onSelect={(_, v) => {
if (variant === "typeaheadmulti") {
const option = v.toString();
if (value.includes(option)) {
onChange(value.filter((item: string) => item !== option));
} else {
onChange([...value, option]);
}
} else {
onChange([v]);
setOpen(false);
}
}}
onClear={(event) => {
event.stopPropagation();
onChange([]);
}}
isOpen={open}
variant={variant}
validated={
errors[name] ? ValidatedOptions.error : ValidatedOptions.default
}

View file

@ -1,5 +1,6 @@
export { ContinueCancelModal } from "./continue-cancel/ContinueCancelModal";
export { SelectControl } from "./controls/SelectControl";
export type { Option } from "./controls/SelectControl";
export { SwitchControl } from "./controls/SwitchControl";
export { TextControl } from "./controls/TextControl";
export { TextAreaControl } from "./controls/TextAreaControl";

View file

@ -284,6 +284,12 @@ public class AccountRestService {
return new ResourcesService(session, user, auth, request);
}
@Path("supportedLocales")
@GET
public List<String> supportedLocales() {
return auth.getRealm().getSupportedLocalesStream().collect(Collectors.toList());
}
private ClientRepresentation modelToRepresentation(ClientModel model, List<String> inUseClients, List<String> offlineClients, Map<String, UserConsentModel> consents) {
ClientRepresentation representation = new ClientRepresentation();
representation.setClientId(model.getClientId());