@keycloakify/keycloak-admin-ui
Version:
Repackaged Keycloak Admin UI
210 lines • 11.3 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { getI18n } from "react-i18next";
import { ScrollForm, useAlerts, useFetch } from "../ui-shared";
import { AlertVariant, Button, Form, PageSection, } from "@patternfly/react-core";
import { flatten } from "flat";
import { useState } from "react";
import { FormProvider, useForm, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { useAdminClient } from "../admin-client";
import { FixedButtonsGroup } from "../components/form/FixedButtonGroup";
import { ViewHeader } from "../components/view-header/ViewHeader";
import { useRealm } from "../context/realm-context/RealmContext";
import { convertToFormValues } from "../util";
import useLocale from "../utils/useLocale";
import { useParams } from "../utils/useParams";
import "./realm-settings-section.css";
import { toUserProfile } from "../realm-settings/routes/UserProfile";
import { UserProfileProvider } from "../realm-settings/user-profile/UserProfileContext";
import { AttributeAnnotations } from "../realm-settings/user-profile/attribute/AttributeAnnotations";
import { AttributeGeneralSettings } from "../realm-settings/user-profile/attribute/AttributeGeneralSettings";
import { AttributePermission } from "../realm-settings/user-profile/attribute/AttributePermission";
import { AttributeValidations } from "../realm-settings/user-profile/attribute/AttributeValidations";
export const USERNAME_EMAIL = ["username", "email"];
const CreateAttributeFormContent = ({ onHandlingTranslationsData, onHandlingGeneratedDisplayName, save, }) => {
const { t } = useTranslation();
const form = useFormContext();
const { realm, attributeName } = useParams();
const editMode = attributeName ? true : false;
const handleTranslationsData = (translationsData) => {
onHandlingTranslationsData(translationsData);
};
const handleGeneratedDisplayName = (generatedDisplayName) => {
onHandlingGeneratedDisplayName(generatedDisplayName);
};
return (_jsxs(UserProfileProvider, { children: [_jsx(ScrollForm, { label: t("jumpToSection"), sections: [
{
title: t("generalSettings"),
panel: (_jsx(AttributeGeneralSettings, { onHandlingTranslationData: handleTranslationsData, onHandlingGeneratedDisplayName: handleGeneratedDisplayName })),
},
{ title: t("permission"), panel: _jsx(AttributePermission, {}) },
{ title: t("validations"), panel: _jsx(AttributeValidations, {}) },
{ title: t("annotations"), panel: _jsx(AttributeAnnotations, {}) },
] }), _jsx(Form, { onSubmit: form.handleSubmit(save), children: _jsxs(FixedButtonsGroup, { name: "attribute-settings", children: [_jsx(Button, { variant: "primary", type: "submit", "data-testid": "attribute-create", children: editMode ? t("save") : t("create") }), _jsx(Link, { to: toUserProfile({ realm, tab: "attributes" }), "data-testid": "attribute-cancel", className: "kc-attributeCancel", children: t("cancel") })] }) })] }));
};
export default function NewAttributeSettings() {
const { adminClient } = useAdminClient();
const { realm: realmName, attributeName } = useParams();
const { realmRepresentation: realm } = useRealm();
const form = useForm();
const { t } = useTranslation();
const combinedLocales = useLocale();
const navigate = useNavigate();
const { addAlert, addError } = useAlerts();
const [config, setConfig] = useState(null);
const editMode = attributeName ? true : false;
const [translationsData, setTranslationsData] = useState({
key: "",
translations: [],
});
const [generatedDisplayName, setGeneratedDisplayName] = useState("");
useFetch(async () => {
const translationsToSave = [];
await Promise.all(combinedLocales.map(async (selectedLocale) => {
var _a;
try {
const translations = await adminClient.realms.getRealmLocalizationTexts({
realm: realmName,
selectedLocale,
});
const formData = form.getValues();
const formattedKey = (_a = formData.displayName) === null || _a === void 0 ? void 0 : _a.substring(2, formData.displayName.length - 1);
const filteredTranslations = [];
const allTranslations = Object.entries(translations).map(([key, value]) => ({
key,
value,
}));
allTranslations.forEach((translation) => {
if (translation.key === formattedKey) {
filteredTranslations.push({
locale: selectedLocale,
value: translation.value,
});
}
});
const translationToSave = {
key: formattedKey,
translations: filteredTranslations,
};
translationsToSave.push(translationToSave);
}
catch (error) {
console.error(`Error fetching translations for ${selectedLocale}:`, error);
}
}));
return translationsToSave;
}, (translationsToSaveData) => {
setTranslationsData(() => ({
key: translationsToSaveData[0].key,
translations: translationsToSaveData.flatMap((translationData) => translationData.translations),
}));
}, [combinedLocales]);
useFetch(() => adminClient.users.getProfile(), (config) => {
setConfig(config);
const { annotations, validations, permissions, selector, required, multivalued, ...values } = config.attributes.find((attribute) => attribute.name === attributeName) || { permissions: { edit: ["admin"] } };
convertToFormValues({
...values,
hasSelector: typeof selector !== "undefined",
hasRequiredScopes: typeof (required === null || required === void 0 ? void 0 : required.scopes) !== "undefined",
}, form.setValue);
Object.entries(flatten({ permissions, selector, required }, { safe: true })).map(([key, value]) => form.setValue(key, value));
form.setValue("annotations", Object.entries(annotations || {}).map(([key, value]) => ({
key,
value: value,
})));
form.setValue("validations", Object.entries(validations || {}).map(([key, value]) => ({
key,
value: value,
})));
form.setValue("isRequired", required !== undefined);
form.setValue("multivalued", multivalued === true);
}, []);
const saveTranslations = async () => {
try {
const nonEmptyTranslations = translationsData.translations.map(async (translation) => {
try {
await adminClient.realms.addLocalization({
realm: realmName,
selectedLocale: translation.locale,
key: translationsData.key,
}, translation.value);
}
catch (_a) {
console.error(`Error saving translation for ${translation.locale}`);
}
});
await Promise.all(nonEmptyTranslations);
}
catch (error) {
console.error(`Error saving translations: ${error}`);
}
};
const save = async ({ hasSelector, hasRequiredScopes, ...formFields }) => {
var _a;
if (!hasSelector) {
delete formFields.selector;
}
if (!hasRequiredScopes) {
(_a = formFields.required) === null || _a === void 0 ? true : delete _a.scopes;
}
const validations = formFields.validations.reduce((prevValidations, currentValidations) => {
prevValidations[currentValidations.key] =
currentValidations.value || {};
return prevValidations;
}, {});
const annotations = formFields.annotations.reduce((obj, item) => Object.assign(obj, { [item.key]: item.value }), {});
const patchAttributes = () => ((config === null || config === void 0 ? void 0 : config.attributes) || []).map((attribute) => {
if (attribute.name !== attributeName) {
return attribute;
}
delete attribute.required;
return Object.assign({
...attribute,
name: attributeName,
displayName: formFields.displayName,
selector: formFields.selector,
permissions: formFields.permissions,
multivalued: formFields.multivalued,
annotations,
validations,
}, formFields.isRequired ? { required: formFields.required } : undefined, formFields.group ? { group: formFields.group } : { group: null });
});
const addAttribute = () => ((config === null || config === void 0 ? void 0 : config.attributes) || []).concat([
Object.assign({
name: formFields.name,
displayName: formFields.displayName || generatedDisplayName,
required: formFields.isRequired ? formFields.required : undefined,
selector: formFields.selector,
permissions: formFields.permissions,
multivalued: formFields.multivalued,
annotations,
validations,
}, formFields.isRequired ? { required: formFields.required } : undefined, formFields.group ? { group: formFields.group } : undefined),
]);
if (realm === null || realm === void 0 ? void 0 : realm.internationalizationEnabled) {
const hasNonEmptyTranslations = translationsData.translations.some((translation) => translation.value.trim() !== "");
if (!hasNonEmptyTranslations && !formFields.displayName) {
addError("createAttributeError", t("translationError"));
return;
}
}
try {
const updatedAttributes = editMode ? patchAttributes() : addAttribute();
await adminClient.users.updateProfile({
...config,
attributes: updatedAttributes,
realm: realmName,
});
await saveTranslations();
getI18n().reloadResources();
navigate(toUserProfile({ realm: realmName, tab: "attributes" }));
addAlert(t("createAttributeSuccess"), AlertVariant.success);
}
catch (error) {
addError("createAttributeError", error);
}
};
return (_jsxs(FormProvider, { ...form, children: [_jsx(ViewHeader, { titleKey: editMode ? attributeName : t("createAttribute"), subKey: editMode ? "" : t("createAttributeSubTitle") }), _jsx(PageSection, { variant: "light", children: _jsx(CreateAttributeFormContent, { save: () => form.handleSubmit(save)(), onHandlingTranslationsData: setTranslationsData, onHandlingGeneratedDisplayName: setGeneratedDisplayName }) })] }));
}
//# sourceMappingURL=NewAttributeSettings.js.map