2023-03-02 12:54:34 +00:00
|
|
|
import { ActionGroup, Button, Form } from "@patternfly/react-core";
|
|
|
|
import { useState } from "react";
|
|
|
|
import { FormProvider, useForm } from "react-hook-form";
|
2022-11-03 14:06:26 +00:00
|
|
|
import { useTranslation } from "react-i18next";
|
2023-03-02 12:54:34 +00:00
|
|
|
import { useAlerts } from "ui-shared";
|
2022-10-10 10:14:19 +00:00
|
|
|
|
2023-03-02 12:54:34 +00:00
|
|
|
import { getPersonalInfo, savePersonalInfo } from "../api/methods";
|
|
|
|
import {
|
|
|
|
UserProfileMetadata,
|
|
|
|
UserRepresentation,
|
|
|
|
} from "../api/representations";
|
2022-11-03 14:06:26 +00:00
|
|
|
import { Page } from "../components/page/Page";
|
|
|
|
import { usePromise } from "../utils/usePromise";
|
2023-03-02 12:54:34 +00:00
|
|
|
import { FormField } from "./FormField";
|
|
|
|
|
|
|
|
type FieldError = {
|
|
|
|
field: string;
|
|
|
|
errorMessage: string;
|
|
|
|
params: string[];
|
|
|
|
};
|
|
|
|
|
|
|
|
const ROOT_ATTRIBUTES = ["username", "firstName", "lastName", "email"];
|
|
|
|
export const isBundleKey = (key?: string) => key?.includes("${");
|
|
|
|
export const unWrap = (key: string) => key.substring(2, key.length - 1);
|
|
|
|
export const isRootAttribute = (attr?: string) =>
|
|
|
|
attr && ROOT_ATTRIBUTES.includes(attr);
|
|
|
|
export const fieldName = (name: string) =>
|
|
|
|
`${isRootAttribute(name) ? "" : "attributes."}${name}`;
|
2022-11-03 14:06:26 +00:00
|
|
|
|
|
|
|
const PersonalInfo = () => {
|
|
|
|
const { t } = useTranslation();
|
2023-03-02 12:54:34 +00:00
|
|
|
const [userProfileMetadata, setUserProfileMetadata] =
|
|
|
|
useState<UserProfileMetadata>();
|
|
|
|
const form = useForm<UserRepresentation>({ mode: "onChange" });
|
|
|
|
const { handleSubmit, reset, setError } = form;
|
|
|
|
const { addAlert, addError } = useAlerts();
|
|
|
|
|
|
|
|
usePromise(
|
|
|
|
(signal) => getPersonalInfo({ signal }),
|
|
|
|
(personalInfo) => {
|
|
|
|
setUserProfileMetadata(personalInfo.userProfileMetadata);
|
|
|
|
reset(personalInfo);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
const onSubmit = async (user: UserRepresentation) => {
|
|
|
|
try {
|
|
|
|
await savePersonalInfo(user);
|
|
|
|
addAlert(t("accountUpdatedMessage"));
|
|
|
|
} catch (error) {
|
|
|
|
addError(t("accountUpdatedError").toString());
|
2022-11-03 14:06:26 +00:00
|
|
|
|
2023-03-02 12:54:34 +00:00
|
|
|
(error as FieldError[]).forEach((e) => {
|
|
|
|
const params = Object.assign(
|
|
|
|
{},
|
|
|
|
e.params.map((p) => (isBundleKey(p) ? unWrap(p) : p))
|
|
|
|
);
|
|
|
|
setError(fieldName(e.field) as keyof UserRepresentation, {
|
|
|
|
message: t(e.errorMessage, { ...params, defaultValue: e.field }),
|
|
|
|
type: "server",
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
2022-11-03 14:06:26 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<Page title={t("personalInfo")} description={t("personalInfoDescription")}>
|
2023-03-02 12:54:34 +00:00
|
|
|
<Form isHorizontal onSubmit={handleSubmit(onSubmit)}>
|
|
|
|
<FormProvider {...form}>
|
|
|
|
{(userProfileMetadata?.attributes || []).map((attribute) => (
|
|
|
|
<FormField key={attribute.name} attribute={attribute} />
|
|
|
|
))}
|
|
|
|
</FormProvider>
|
|
|
|
<ActionGroup>
|
|
|
|
<Button type="submit" id="save-btn" variant="primary">
|
|
|
|
{t("doSave")}
|
|
|
|
</Button>
|
|
|
|
<Button id="cancel-btn" variant="link" onClick={() => reset()}>
|
|
|
|
{t("doCancel")}
|
|
|
|
</Button>
|
|
|
|
</ActionGroup>
|
2022-11-03 14:06:26 +00:00
|
|
|
</Form>
|
|
|
|
</Page>
|
|
|
|
);
|
|
|
|
};
|
2022-10-10 10:14:19 +00:00
|
|
|
|
|
|
|
export default PersonalInfo;
|