2023-11-14 11:04:55 +00:00
|
|
|
import type { UserProfileGroup } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
2022-03-01 05:44:42 +00:00
|
|
|
import {
|
|
|
|
ActionGroup,
|
|
|
|
Button,
|
|
|
|
FormGroup,
|
|
|
|
PageSection,
|
|
|
|
Text,
|
|
|
|
TextContent,
|
|
|
|
} from "@patternfly/react-core";
|
2022-08-03 12:12:07 +00:00
|
|
|
import { useEffect, useMemo } from "react";
|
2022-04-20 17:11:46 +00:00
|
|
|
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
|
2022-03-01 05:44:42 +00:00
|
|
|
import { useTranslation } from "react-i18next";
|
2023-01-18 12:09:49 +00:00
|
|
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
2022-12-07 14:23:12 +00:00
|
|
|
|
2023-05-24 12:11:06 +00:00
|
|
|
import { FormAccess } from "../../components/form/FormAccess";
|
2023-03-07 09:29:40 +00:00
|
|
|
import { HelpItem } from "ui-shared";
|
2022-12-07 14:23:12 +00:00
|
|
|
import type { KeyValueType } from "../../components/key-value-form/key-value-convert";
|
|
|
|
import { KeyValueInput } from "../../components/key-value-form/KeyValueInput";
|
2022-04-21 15:03:26 +00:00
|
|
|
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
2022-03-01 05:44:42 +00:00
|
|
|
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
|
|
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
|
|
|
import type { EditAttributesGroupParams } from "../routes/EditAttributesGroup";
|
|
|
|
import { toUserProfile } from "../routes/UserProfile";
|
|
|
|
import { useUserProfile } from "./UserProfileContext";
|
|
|
|
|
2022-04-20 17:11:46 +00:00
|
|
|
import "../realm-settings-section.css";
|
2022-03-01 05:44:42 +00:00
|
|
|
|
2022-04-20 17:11:46 +00:00
|
|
|
function parseAnnotations(input: Record<string, unknown>): KeyValueType[] {
|
|
|
|
return Object.entries(input).reduce((p, [key, value]) => {
|
2022-03-01 05:44:42 +00:00
|
|
|
if (typeof value === "string") {
|
2022-04-20 17:11:46 +00:00
|
|
|
return [...p, { key, value }];
|
|
|
|
} else {
|
|
|
|
return [...p];
|
2022-03-01 05:44:42 +00:00
|
|
|
}
|
2022-04-20 17:11:46 +00:00
|
|
|
}, [] as KeyValueType[]);
|
2022-03-01 05:44:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-20 17:11:46 +00:00
|
|
|
function transformAnnotations(input: KeyValueType[]): Record<string, unknown> {
|
2022-03-01 05:44:42 +00:00
|
|
|
return Object.fromEntries(
|
|
|
|
input
|
|
|
|
.filter((annotation) => annotation.key.length > 0)
|
2023-07-11 14:03:21 +00:00
|
|
|
.map((annotation) => [annotation.key, annotation.value] as const),
|
2022-03-01 05:44:42 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
type FormFields = Required<Omit<UserProfileGroup, "annotations">> & {
|
2022-04-20 17:11:46 +00:00
|
|
|
annotations: KeyValueType[];
|
2022-03-01 05:44:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const defaultValues: FormFields = {
|
2023-10-18 10:33:52 +00:00
|
|
|
annotations: [],
|
2022-03-01 05:44:42 +00:00
|
|
|
displayDescription: "",
|
|
|
|
displayHeader: "",
|
|
|
|
name: "",
|
|
|
|
};
|
|
|
|
|
|
|
|
export default function AttributesGroupForm() {
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const { realm } = useRealm();
|
|
|
|
const { config, save } = useUserProfile();
|
2022-08-16 13:09:14 +00:00
|
|
|
const navigate = useNavigate();
|
2022-12-07 14:23:12 +00:00
|
|
|
const params = useParams<EditAttributesGroupParams>();
|
2023-01-26 09:31:07 +00:00
|
|
|
const form = useForm<FormFields>({ defaultValues });
|
2022-03-01 05:44:42 +00:00
|
|
|
|
|
|
|
const matchingGroup = useMemo(
|
|
|
|
() => config?.groups?.find(({ name }) => name === params.name),
|
2023-07-11 14:03:21 +00:00
|
|
|
[config?.groups],
|
2022-03-01 05:44:42 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (!matchingGroup) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const annotations = matchingGroup.annotations
|
|
|
|
? parseAnnotations(matchingGroup.annotations)
|
|
|
|
: [];
|
|
|
|
|
|
|
|
form.reset({ ...defaultValues, ...matchingGroup, annotations });
|
|
|
|
}, [matchingGroup]);
|
|
|
|
|
|
|
|
const onSubmit: SubmitHandler<FormFields> = async (values) => {
|
|
|
|
if (!config) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const groups = [...(config.groups ?? [])];
|
|
|
|
const updateAt = matchingGroup ? groups.indexOf(matchingGroup) : -1;
|
|
|
|
const updatedGroup: UserProfileGroup = {
|
|
|
|
...values,
|
|
|
|
annotations: transformAnnotations(values.annotations),
|
|
|
|
};
|
|
|
|
|
|
|
|
if (updateAt === -1) {
|
|
|
|
groups.push(updatedGroup);
|
|
|
|
} else {
|
|
|
|
groups[updateAt] = updatedGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
const success = await save({ ...config, groups });
|
|
|
|
|
|
|
|
if (success) {
|
2022-08-16 13:09:14 +00:00
|
|
|
navigate(toUserProfile({ realm, tab: "attributes-group" }));
|
2022-03-01 05:44:42 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<ViewHeader
|
2023-09-25 07:06:56 +00:00
|
|
|
titleKey={matchingGroup ? "editGroupText" : "createGroupText"}
|
2022-03-01 05:44:42 +00:00
|
|
|
divider
|
|
|
|
/>
|
|
|
|
<PageSection variant="light" onSubmit={form.handleSubmit(onSubmit)}>
|
|
|
|
<FormAccess isHorizontal role="manage-realm">
|
|
|
|
<FormGroup
|
2023-09-25 07:06:56 +00:00
|
|
|
label={t("nameField")}
|
2022-03-01 05:44:42 +00:00
|
|
|
fieldId="kc-name"
|
|
|
|
isRequired
|
2023-09-14 09:01:15 +00:00
|
|
|
helperTextInvalid={t("required")}
|
2023-01-26 09:31:07 +00:00
|
|
|
validated={form.formState.errors.name ? "error" : "default"}
|
2022-03-01 05:44:42 +00:00
|
|
|
labelIcon={
|
2023-09-25 07:06:56 +00:00
|
|
|
<HelpItem helpText={t("nameHintHelp")} fieldLabelId="nameField" />
|
2022-03-01 05:44:42 +00:00
|
|
|
}
|
|
|
|
>
|
2022-04-21 15:03:26 +00:00
|
|
|
<KeycloakTextInput
|
2022-03-01 05:44:42 +00:00
|
|
|
id="kc-name"
|
2022-03-10 21:05:15 +00:00
|
|
|
isReadOnly={!!matchingGroup}
|
2023-01-26 09:31:07 +00:00
|
|
|
{...form.register("name", { required: true })}
|
2022-03-01 05:44:42 +00:00
|
|
|
/>
|
2022-03-11 10:19:43 +00:00
|
|
|
{!!matchingGroup && (
|
2023-01-26 09:31:07 +00:00
|
|
|
<input type="hidden" {...form.register("name")} />
|
2022-03-11 10:19:43 +00:00
|
|
|
)}
|
2022-03-01 05:44:42 +00:00
|
|
|
</FormGroup>
|
|
|
|
<FormGroup
|
2023-09-25 07:06:56 +00:00
|
|
|
label={t("displayHeaderField")}
|
2022-03-01 05:44:42 +00:00
|
|
|
fieldId="kc-display-header"
|
|
|
|
labelIcon={
|
|
|
|
<HelpItem
|
2023-09-20 08:52:43 +00:00
|
|
|
helpText={t("displayHeaderHintHelp")}
|
2023-09-25 07:06:56 +00:00
|
|
|
fieldLabelId="displayHeaderField"
|
2022-03-01 05:44:42 +00:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
>
|
2022-04-21 15:03:26 +00:00
|
|
|
<KeycloakTextInput
|
2022-03-01 05:44:42 +00:00
|
|
|
id="kc-display-header"
|
2023-01-26 09:31:07 +00:00
|
|
|
{...form.register("displayHeader")}
|
2022-03-01 05:44:42 +00:00
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
<FormGroup
|
2023-09-25 07:06:56 +00:00
|
|
|
label={t("displayDescriptionField")}
|
2022-03-01 05:44:42 +00:00
|
|
|
fieldId="kc-display-description"
|
|
|
|
labelIcon={
|
|
|
|
<HelpItem
|
2023-09-20 08:52:43 +00:00
|
|
|
helpText={t("displayDescriptionHintHelp")}
|
2023-09-25 07:06:56 +00:00
|
|
|
fieldLabelId="displayDescriptionField"
|
2022-03-01 05:44:42 +00:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
>
|
2022-04-21 15:03:26 +00:00
|
|
|
<KeycloakTextInput
|
2022-03-01 05:44:42 +00:00
|
|
|
id="kc-display-description"
|
2023-01-26 09:31:07 +00:00
|
|
|
{...form.register("displayDescription")}
|
2022-03-01 05:44:42 +00:00
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
<TextContent>
|
2023-09-25 07:06:56 +00:00
|
|
|
<Text component="h2">{t("annotationsText")}</Text>
|
2022-03-01 05:44:42 +00:00
|
|
|
</TextContent>
|
2023-09-25 07:06:56 +00:00
|
|
|
<FormGroup label={t("annotationsText")} fieldId="kc-annotations">
|
2022-04-20 17:11:46 +00:00
|
|
|
<FormProvider {...form}>
|
2024-01-09 13:39:53 +00:00
|
|
|
<KeyValueInput label={t("annotationsText")} name="annotations" />
|
2022-04-20 17:11:46 +00:00
|
|
|
</FormProvider>
|
2022-03-01 05:44:42 +00:00
|
|
|
</FormGroup>
|
|
|
|
<ActionGroup>
|
2023-10-26 13:22:43 +00:00
|
|
|
<Button variant="primary" type="submit" data-testid="saveGroupBtn">
|
2023-09-14 09:01:15 +00:00
|
|
|
{t("save")}
|
2022-03-01 05:44:42 +00:00
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
variant="link"
|
|
|
|
component={(props) => (
|
|
|
|
<Link
|
|
|
|
{...props}
|
2022-06-22 11:35:10 +00:00
|
|
|
to={toUserProfile({ realm, tab: "attributes-group" })}
|
2022-03-01 05:44:42 +00:00
|
|
|
/>
|
|
|
|
)}
|
|
|
|
>
|
2023-09-14 09:01:15 +00:00
|
|
|
{t("cancel")}
|
2022-03-01 05:44:42 +00:00
|
|
|
</Button>
|
|
|
|
</ActionGroup>
|
|
|
|
</FormAccess>
|
|
|
|
</PageSection>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|