Unify utils for interpolated labels under ui-shared
(#25203)
Signed-off-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
parent
3b26e5d489
commit
dc0455b73c
14 changed files with 61 additions and 98 deletions
|
@ -7,6 +7,7 @@ import {
|
||||||
Spinner,
|
Spinner,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { ExternalLinkSquareAltIcon } from "@patternfly/react-icons";
|
import { ExternalLinkSquareAltIcon } from "@patternfly/react-icons";
|
||||||
|
import { TFunction } from "i18next";
|
||||||
import { useKeycloak } from "keycloak-masthead";
|
import { useKeycloak } from "keycloak-masthead";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { ErrorOption, useForm } from "react-hook-form";
|
import { ErrorOption, useForm } from "react-hook-form";
|
||||||
|
@ -16,6 +17,7 @@ import {
|
||||||
setUserProfileServerError,
|
setUserProfileServerError,
|
||||||
useAlerts,
|
useAlerts,
|
||||||
} from "ui-shared";
|
} from "ui-shared";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getPersonalInfo,
|
getPersonalInfo,
|
||||||
getSupportedLocales,
|
getSupportedLocales,
|
||||||
|
@ -65,7 +67,7 @@ const PersonalInfo = () => {
|
||||||
{ responseData: { errors: error as any } },
|
{ responseData: { errors: error as any } },
|
||||||
(name: string | number, error: unknown) =>
|
(name: string | number, error: unknown) =>
|
||||||
setError(name as string, error as ErrorOption),
|
setError(name as string, error as ErrorOption),
|
||||||
(key: TFuncKey, param?: object) => t(key, { ...param }),
|
((key: TFuncKey, param?: object) => t(key, param as any)) as TFunction,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -87,7 +89,10 @@ const PersonalInfo = () => {
|
||||||
form={form}
|
form={form}
|
||||||
userProfileMetadata={userProfileMetadata}
|
userProfileMetadata={userProfileMetadata}
|
||||||
supportedLocales={supportedLocales}
|
supportedLocales={supportedLocales}
|
||||||
t={(key: unknown, params) => t(key as TFuncKey, { ...params })}
|
t={
|
||||||
|
((key: unknown, params) =>
|
||||||
|
t(key as TFuncKey, params as any)) as TFunction
|
||||||
|
}
|
||||||
renderer={(attribute) =>
|
renderer={(attribute) =>
|
||||||
attribute.name === "email" &&
|
attribute.name === "email" &&
|
||||||
updateEmailFeatureEnabled &&
|
updateEmailFeatureEnabled &&
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
import { TFunction } from "i18next";
|
|
||||||
import { TFuncKey } from "../i18n";
|
|
||||||
import { UserProfileAttributeMetadata } from "../api/representations";
|
|
||||||
|
|
||||||
export const isBundleKey = (displayName?: string) =>
|
|
||||||
displayName?.includes("${");
|
|
||||||
export const unWrap = (key: string) => key.substring(2, key.length - 1);
|
|
||||||
|
|
||||||
export const label = (attribute: UserProfileAttributeMetadata, t: TFunction) =>
|
|
||||||
(isBundleKey(attribute.displayName)
|
|
||||||
? t(unWrap(attribute.displayName!) as TFuncKey)
|
|
||||||
: attribute.displayName) || attribute.name;
|
|
||||||
|
|
||||||
const ROOT_ATTRIBUTES = ["username", "firstName", "lastName", "email"];
|
|
||||||
|
|
||||||
const isRootAttribute = (attr?: string) =>
|
|
||||||
attr && ROOT_ATTRIBUTES.includes(attr);
|
|
||||||
|
|
||||||
export const fieldName = (attribute: UserProfileAttributeMetadata) =>
|
|
||||||
`${isRootAttribute(attribute.name) ? "" : "attributes."}${attribute.name}`;
|
|
|
@ -13,14 +13,15 @@ import {
|
||||||
TextContent,
|
TextContent,
|
||||||
TextVariants,
|
TextVariants,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { Form } from "react-router-dom";
|
|
||||||
import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { isBundleKey, unWrap } from "../../user/utils";
|
|
||||||
import { CheckIcon } from "@patternfly/react-icons";
|
import { CheckIcon } from "@patternfly/react-icons";
|
||||||
import { useAlerts } from "../alert/Alerts";
|
|
||||||
import { ReactNode, useState } from "react";
|
import { ReactNode, useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Form } from "react-router-dom";
|
||||||
|
import { label } from "ui-shared";
|
||||||
|
|
||||||
|
import { useAlerts } from "../alert/Alerts";
|
||||||
|
import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
|
||||||
import { UserAttribute } from "./UserDataTable";
|
import { UserAttribute } from "./UserDataTable";
|
||||||
|
|
||||||
type UserDataTableAttributeSearchFormProps = {
|
type UserDataTableAttributeSearchFormProps = {
|
||||||
|
@ -153,11 +154,7 @@ export function UserDataTableAttributeSearchForm({
|
||||||
{profile.attributes?.map((option) => (
|
{profile.attributes?.map((option) => (
|
||||||
<SelectOption
|
<SelectOption
|
||||||
key={option.name}
|
key={option.name}
|
||||||
value={
|
value={label(t, option.displayName!, option.name)}
|
||||||
(isBundleKey(option.displayName)
|
|
||||||
? t(unWrap(option.displayName!))
|
|
||||||
: option.displayName) || option.name
|
|
||||||
}
|
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setSelectAttributeKeyOpen(false);
|
setSelectAttributeKeyOpen(false);
|
||||||
|
|
|
@ -2,10 +2,12 @@ import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/g
|
||||||
import RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
import RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
||||||
import type { UserProfileMetadata } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
import type { UserProfileMetadata } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
||||||
import { AlertVariant, PageSection } from "@patternfly/react-core";
|
import { AlertVariant, PageSection } from "@patternfly/react-core";
|
||||||
|
import { TFunction } from "i18next";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { isUserProfileError, setUserProfileServerError } from "ui-shared";
|
||||||
|
|
||||||
import { adminClient } from "../admin-client";
|
import { adminClient } from "../admin-client";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
|
@ -15,7 +17,6 @@ import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { useFetch } from "../utils/useFetch";
|
import { useFetch } from "../utils/useFetch";
|
||||||
import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled";
|
import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled";
|
||||||
import { UserForm } from "./UserForm";
|
import { UserForm } from "./UserForm";
|
||||||
import { isUserProfileError, setUserProfileServerError } from "ui-shared";
|
|
||||||
import { UserFormFields, toUserRepresentation } from "./form-state";
|
import { UserFormFields, toUserRepresentation } from "./form-state";
|
||||||
import { toUser } from "./routes/User";
|
import { toUser } from "./routes/User";
|
||||||
|
|
||||||
|
@ -71,9 +72,8 @@ export default function CreateUser() {
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (isUserProfileError(error)) {
|
if (isUserProfileError(error)) {
|
||||||
setUserProfileServerError(error, form.setError, (key, param) =>
|
setUserProfileServerError(error, form.setError, ((key, param) =>
|
||||||
t(key as string, { ...param }),
|
t(key as string, param as any)) as TFunction);
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
addError("userCreateError", error);
|
addError("userCreateError", error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,13 @@ import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { InfoCircleIcon } from "@patternfly/react-icons";
|
import { InfoCircleIcon } from "@patternfly/react-icons";
|
||||||
|
import { TFunction } from "i18next";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { FormProvider, useForm } from "react-hook-form";
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { isUserProfileError, setUserProfileServerError } from "ui-shared";
|
import { isUserProfileError, setUserProfileServerError } from "ui-shared";
|
||||||
|
|
||||||
import { adminClient } from "../admin-client";
|
import { adminClient } from "../admin-client";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
|
@ -158,9 +160,8 @@ export default function EditUser() {
|
||||||
refresh();
|
refresh();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (isUserProfileError(error)) {
|
if (isUserProfileError(error)) {
|
||||||
setUserProfileServerError(error, form.setError, (key, param) =>
|
setUserProfileServerError(error, form.setError, ((key, param) =>
|
||||||
t(key as string, { ...param }),
|
t(key as string, param as any)) as TFunction);
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
addError("userCreateError", error);
|
addError("userCreateError", error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,13 @@ import {
|
||||||
InputGroup,
|
InputGroup,
|
||||||
Switch,
|
Switch,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
|
import { TFunction } from "i18next";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, UseFormReturn } from "react-hook-form";
|
import { Controller, UseFormReturn } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { HelpItem, UserProfileFields } from "ui-shared";
|
import { HelpItem, UserProfileFields } from "ui-shared";
|
||||||
|
|
||||||
import { adminClient } from "../admin-client";
|
import { adminClient } from "../admin-client";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { FormAccess } from "../components/form/FormAccess";
|
import { FormAccess } from "../components/form/FormAccess";
|
||||||
|
@ -218,7 +220,10 @@ export const UserForm = ({
|
||||||
userProfileMetadata={userProfileMetadata}
|
userProfileMetadata={userProfileMetadata}
|
||||||
hideReadOnly={!user}
|
hideReadOnly={!user}
|
||||||
supportedLocales={realm.supportedLocales || []}
|
supportedLocales={realm.supportedLocales || []}
|
||||||
t={(key: unknown, params) => t(key as string, { ...params })}
|
t={
|
||||||
|
((key: unknown, params) =>
|
||||||
|
t(key as string, params as any)) as TFunction
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
@ -1,30 +1,2 @@
|
||||||
import { UserProfileAttributeMetadata } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
|
||||||
import { TFunction } from "i18next";
|
|
||||||
|
|
||||||
export const isBundleKey = (displayName?: string) =>
|
|
||||||
displayName?.includes("${");
|
|
||||||
export const unWrap = (key: string) => key.substring(2, key.length - 1);
|
|
||||||
|
|
||||||
export const label = (
|
|
||||||
text: string | undefined,
|
|
||||||
fallback: string | undefined,
|
|
||||||
t: TFunction,
|
|
||||||
) => (isBundleKey(text) ? t(unWrap(text!)) : text) || fallback;
|
|
||||||
|
|
||||||
export const labelAttribute = (
|
|
||||||
attribute: UserProfileAttributeMetadata,
|
|
||||||
t: TFunction,
|
|
||||||
) => label(attribute.displayName, attribute.name, t);
|
|
||||||
|
|
||||||
const ROOT_ATTRIBUTES = ["username", "firstName", "lastName", "email"];
|
|
||||||
|
|
||||||
export const isRootAttribute = (attr?: string) =>
|
|
||||||
attr && ROOT_ATTRIBUTES.includes(attr);
|
|
||||||
|
|
||||||
export const fieldName = (attribute: UserProfileAttributeMetadata) =>
|
|
||||||
isRootAttribute(attribute.name)
|
|
||||||
? attribute.name
|
|
||||||
: `attributes.${attribute.name}`;
|
|
||||||
|
|
||||||
export const isLightweightUser = (userId?: string) =>
|
export const isLightweightUser = (userId?: string) =>
|
||||||
userId?.startsWith("lightweight-");
|
userId?.startsWith("lightweight-");
|
||||||
|
|
|
@ -40,13 +40,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@keycloak/keycloak-admin-client": "workspace:*",
|
||||||
"@patternfly/react-core": "^4.278.0",
|
"@patternfly/react-core": "^4.278.0",
|
||||||
"@patternfly/react-icons": "^4.93.7",
|
"@patternfly/react-icons": "^4.93.7",
|
||||||
"@keycloak/keycloak-admin-client": "workspace:*",
|
"i18next": "^23.7.6",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "7.48.2"
|
"react-hook-form": "7.48.2",
|
||||||
|
"react-i18next": "^13.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
|
|
|
@ -18,6 +18,7 @@ export { UserProfileFields } from "./user-profile/UserProfileFields";
|
||||||
export {
|
export {
|
||||||
setUserProfileServerError,
|
setUserProfileServerError,
|
||||||
isUserProfileError,
|
isUserProfileError,
|
||||||
|
label,
|
||||||
} from "./user-profile/utils";
|
} from "./user-profile/utils";
|
||||||
export type { UserFormFields } from "./user-profile/utils";
|
export type { UserFormFields } from "./user-profile/utils";
|
||||||
export { ScrollForm, mainPageContentId } from "./scroll-form/ScrollForm";
|
export { ScrollForm, mainPageContentId } from "./scroll-form/ScrollForm";
|
||||||
|
|
|
@ -6,16 +6,13 @@ import {
|
||||||
TextInputProps,
|
TextInputProps,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
||||||
|
import { type TFunction } from "i18next";
|
||||||
import { Fragment, useEffect, useMemo } from "react";
|
import { Fragment, useEffect, useMemo } from "react";
|
||||||
import { FieldPath, UseFormReturn, useWatch } from "react-hook-form";
|
import { FieldPath, UseFormReturn, useWatch } from "react-hook-form";
|
||||||
|
|
||||||
import { UserProfileFieldProps } from "./UserProfileFields";
|
import { UserProfileFieldProps } from "./UserProfileFields";
|
||||||
import { UserProfileGroup } from "./UserProfileGroup";
|
import { UserProfileGroup } from "./UserProfileGroup";
|
||||||
import {
|
import { UserFormFields, fieldName, labelAttribute } from "./utils";
|
||||||
TranslationFunction,
|
|
||||||
UserFormFields,
|
|
||||||
fieldName,
|
|
||||||
labelAttribute,
|
|
||||||
} from "./utils";
|
|
||||||
|
|
||||||
export const MultiInputComponent = ({
|
export const MultiInputComponent = ({
|
||||||
t,
|
t,
|
||||||
|
@ -37,7 +34,7 @@ export const MultiInputComponent = ({
|
||||||
);
|
);
|
||||||
|
|
||||||
export type MultiLineInputProps = Omit<TextInputProps, "form"> & {
|
export type MultiLineInputProps = Omit<TextInputProps, "form"> & {
|
||||||
t: TranslationFunction;
|
t: TFunction;
|
||||||
name: FieldPath<UserFormFields>;
|
name: FieldPath<UserFormFields>;
|
||||||
form: UseFormReturn<UserFormFields>;
|
form: UseFormReturn<UserFormFields>;
|
||||||
addButtonLabel?: string;
|
addButtonLabel?: string;
|
||||||
|
|
|
@ -4,8 +4,10 @@ import {
|
||||||
UserProfileMetadata,
|
UserProfileMetadata,
|
||||||
} from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
} from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
||||||
import { Text } from "@patternfly/react-core";
|
import { Text } from "@patternfly/react-core";
|
||||||
|
import { TFunction } from "i18next";
|
||||||
import { ReactNode, useMemo } from "react";
|
import { ReactNode, useMemo } from "react";
|
||||||
import { FieldPath, UseFormReturn } from "react-hook-form";
|
import { FieldPath, UseFormReturn } from "react-hook-form";
|
||||||
|
|
||||||
import { ScrollForm } from "../main";
|
import { ScrollForm } from "../main";
|
||||||
import { LocaleSelector } from "./LocaleSelector";
|
import { LocaleSelector } from "./LocaleSelector";
|
||||||
import { MultiInputComponent } from "./MultiInputComponent";
|
import { MultiInputComponent } from "./MultiInputComponent";
|
||||||
|
@ -13,13 +15,7 @@ import { OptionComponent } from "./OptionsComponent";
|
||||||
import { SelectComponent } from "./SelectComponent";
|
import { SelectComponent } from "./SelectComponent";
|
||||||
import { TextAreaComponent } from "./TextAreaComponent";
|
import { TextAreaComponent } from "./TextAreaComponent";
|
||||||
import { TextComponent } from "./TextComponent";
|
import { TextComponent } from "./TextComponent";
|
||||||
import {
|
import { UserFormFields, fieldName, isRootAttribute, label } from "./utils";
|
||||||
TranslationFunction,
|
|
||||||
UserFormFields,
|
|
||||||
fieldName,
|
|
||||||
isRootAttribute,
|
|
||||||
label,
|
|
||||||
} from "./utils";
|
|
||||||
|
|
||||||
export type UserProfileError = {
|
export type UserProfileError = {
|
||||||
responseData: { errors?: { errorMessage: string }[] };
|
responseData: { errors?: { errorMessage: string }[] };
|
||||||
|
@ -51,7 +47,7 @@ const INPUT_TYPES = [
|
||||||
export type InputType = (typeof INPUT_TYPES)[number];
|
export type InputType = (typeof INPUT_TYPES)[number];
|
||||||
|
|
||||||
export type UserProfileFieldProps = {
|
export type UserProfileFieldProps = {
|
||||||
t: TranslationFunction;
|
t: TFunction;
|
||||||
form: UseFormReturn<UserFormFields>;
|
form: UseFormReturn<UserFormFields>;
|
||||||
inputType: InputType;
|
inputType: InputType;
|
||||||
attribute: UserProfileAttributeMetadata;
|
attribute: UserProfileAttributeMetadata;
|
||||||
|
@ -80,7 +76,7 @@ export const FIELDS: {
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type UserProfileFieldsProps = {
|
export type UserProfileFieldsProps = {
|
||||||
t: TranslationFunction;
|
t: TFunction;
|
||||||
form: UseFormReturn<UserFormFields>;
|
form: UseFormReturn<UserFormFields>;
|
||||||
userProfileMetadata: UserProfileMetadata;
|
userProfileMetadata: UserProfileMetadata;
|
||||||
supportedLocales: string[];
|
supportedLocales: string[];
|
||||||
|
@ -167,7 +163,7 @@ export const UserProfileFields = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
type FormFieldProps = {
|
type FormFieldProps = {
|
||||||
t: TranslationFunction;
|
t: TFunction;
|
||||||
form: UseFormReturn<UserFormFields>;
|
form: UseFormReturn<UserFormFields>;
|
||||||
supportedLocales: string[];
|
supportedLocales: string[];
|
||||||
attribute: UserProfileAttributeMetadata;
|
attribute: UserProfileAttributeMetadata;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { UserProfileAttributeMetadata } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
import { UserProfileAttributeMetadata } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
||||||
import { FormGroup, InputGroup } from "@patternfly/react-core";
|
import { FormGroup, InputGroup } from "@patternfly/react-core";
|
||||||
|
import { TFunction } from "i18next";
|
||||||
import { get } from "lodash-es";
|
import { get } from "lodash-es";
|
||||||
import { PropsWithChildren, ReactNode } from "react";
|
import { PropsWithChildren, ReactNode } from "react";
|
||||||
import { UseFormReturn } from "react-hook-form";
|
import { UseFormReturn } from "react-hook-form";
|
||||||
|
|
||||||
import { HelpItem } from "../controls/HelpItem";
|
import { HelpItem } from "../controls/HelpItem";
|
||||||
import {
|
import {
|
||||||
TranslationFunction,
|
|
||||||
UserFormFields,
|
UserFormFields,
|
||||||
fieldName,
|
fieldName,
|
||||||
isRequiredAttribute,
|
isRequiredAttribute,
|
||||||
|
@ -13,7 +14,7 @@ import {
|
||||||
} from "./utils";
|
} from "./utils";
|
||||||
|
|
||||||
export type UserProfileGroupProps = {
|
export type UserProfileGroupProps = {
|
||||||
t: TranslationFunction;
|
t: TFunction;
|
||||||
form: UseFormReturn<UserFormFields>;
|
form: UseFormReturn<UserFormFields>;
|
||||||
attribute: UserProfileAttributeMetadata;
|
attribute: UserProfileAttributeMetadata;
|
||||||
renderer?: (attribute: UserProfileAttributeMetadata) => ReactNode;
|
renderer?: (attribute: UserProfileAttributeMetadata) => ReactNode;
|
||||||
|
@ -39,7 +40,9 @@ export const UserProfileGroup = ({
|
||||||
fieldId={attribute.name}
|
fieldId={attribute.name}
|
||||||
isRequired={isRequiredAttribute(attribute)}
|
isRequired={isRequiredAttribute(attribute)}
|
||||||
validated={get(errors, fieldName(attribute.name)) ? "error" : "default"}
|
validated={get(errors, fieldName(attribute.name)) ? "error" : "default"}
|
||||||
helperTextInvalid={t(get(errors, fieldName(attribute.name))?.message)}
|
helperTextInvalid={t(
|
||||||
|
get(errors, fieldName(attribute.name))?.message as string,
|
||||||
|
)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
helpText ? (
|
helpText ? (
|
||||||
<HelpItem helpText={helpText} fieldLabelId={attribute.name!} />
|
<HelpItem helpText={helpText} fieldLabelId={attribute.name!} />
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { UserProfileAttributeMetadata } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
import { UserProfileAttributeMetadata } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
||||||
import UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
|
import UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
|
||||||
|
import { TFunction } from "i18next";
|
||||||
import { FieldPath } from "react-hook-form";
|
import { FieldPath } from "react-hook-form";
|
||||||
|
|
||||||
export type KeyValueType = { key: string; value: string };
|
export type KeyValueType = { key: string; value: string };
|
||||||
|
@ -23,18 +24,17 @@ export type UserProfileError = {
|
||||||
responseData: ErrorArray | FieldError;
|
responseData: ErrorArray | FieldError;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isBundleKey = (displayName?: string) =>
|
const isBundleKey = (displayName?: string) => displayName?.includes("${");
|
||||||
displayName?.includes("${");
|
|
||||||
export const unWrap = (key: string) => key.substring(2, key.length - 1);
|
export const unWrap = (key: string) => key.substring(2, key.length - 1);
|
||||||
|
|
||||||
export const label = (
|
export const label = (
|
||||||
t: TranslationFunction,
|
t: TFunction,
|
||||||
text: string | undefined,
|
text: string | undefined,
|
||||||
fallback: string | undefined,
|
fallback: string | undefined,
|
||||||
) => (isBundleKey(text) ? t(unWrap(text!)) : text) || fallback;
|
) => (isBundleKey(text) ? t(unWrap(text!)) : text) || fallback;
|
||||||
|
|
||||||
export const labelAttribute = (
|
export const labelAttribute = (
|
||||||
t: TranslationFunction,
|
t: TFunction,
|
||||||
attribute: UserProfileAttributeMetadata,
|
attribute: UserProfileAttributeMetadata,
|
||||||
) => label(t, attribute.displayName, attribute.name);
|
) => label(t, attribute.displayName, attribute.name);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ export const fieldName = (name?: string) =>
|
||||||
export function setUserProfileServerError<T>(
|
export function setUserProfileServerError<T>(
|
||||||
error: UserProfileError,
|
error: UserProfileError,
|
||||||
setError: (field: keyof T, params: object) => void,
|
setError: (field: keyof T, params: object) => void,
|
||||||
t: TranslationFunction,
|
t: TFunction,
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
((error.responseData as ErrorArray).errors !== undefined
|
((error.responseData as ErrorArray).errors !== undefined
|
||||||
|
@ -152,5 +152,3 @@ function isFieldError(error: unknown): error is FieldError {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TranslationFunction = (key: unknown, params?: object) => string;
|
|
||||||
|
|
|
@ -439,6 +439,9 @@ importers:
|
||||||
'@patternfly/react-icons':
|
'@patternfly/react-icons':
|
||||||
specifier: ^4.93.7
|
specifier: ^4.93.7
|
||||||
version: 4.93.7(react-dom@18.2.0)(react@18.2.0)
|
version: 4.93.7(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
i18next:
|
||||||
|
specifier: ^23.7.6
|
||||||
|
version: 23.7.7
|
||||||
lodash-es:
|
lodash-es:
|
||||||
specifier: ^4.17.21
|
specifier: ^4.17.21
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
|
@ -451,6 +454,9 @@ importers:
|
||||||
react-hook-form:
|
react-hook-form:
|
||||||
specifier: 7.48.2
|
specifier: 7.48.2
|
||||||
version: 7.48.2(react@18.2.0)
|
version: 7.48.2(react@18.2.0)
|
||||||
|
react-i18next:
|
||||||
|
specifier: ^13.5.0
|
||||||
|
version: 13.5.0(i18next@23.7.7)(react-dom@18.2.0)(react@18.2.0)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/lodash-es':
|
'@types/lodash-es':
|
||||||
specifier: ^4.17.12
|
specifier: ^4.17.12
|
||||||
|
|
Loading…
Reference in a new issue