@keycloakify/keycloak-admin-ui
Version:
Repackaged Keycloak Admin UI
152 lines • 12.5 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { HelpItem, TextAreaControl, TextControl, useAlerts, useFetch, } from "../ui-shared";
import { ActionGroup, AlertVariant, Button, ButtonVariant, DataList, DataListCell, DataListItem, DataListItemCells, DataListItemRow, Divider, DropdownItem, Flex, FlexItem, Label, PageSection, Text, TextVariants, } from "@patternfly/react-core";
import { PlusCircleIcon, TrashIcon } from "@patternfly/react-icons";
import { Fragment, useMemo, useState } from "react";
import { FormProvider, useFieldArray, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { useAdminClient } from "../admin-client";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { FormAccess } from "../components/form/FormAccess";
import { KeycloakSpinner } from "../ui-shared";
import { ViewHeader } from "../components/view-header/ViewHeader";
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
import { useParams } from "../utils/useParams";
import { toAddExecutor } from "../realm-settings/routes/AddExecutor";
import { toClientPolicies } from "../realm-settings/routes/ClientPolicies";
import { toClientProfile } from "../realm-settings/routes/ClientProfile";
import { toExecutor } from "../realm-settings/routes/Executor";
import "./realm-settings-section.css";
const defaultValues = {
name: "",
description: "",
executors: [],
};
export default function ClientProfileForm() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const form = useForm({
defaultValues,
mode: "onChange",
});
const { handleSubmit, setValue, getValues, formState: { isDirty }, control, } = form;
const { fields: profileExecutors, remove } = useFieldArray({
name: "executors",
control,
});
const { addAlert, addError } = useAlerts();
const [profiles, setProfiles] = useState();
const [isGlobalProfile, setIsGlobalProfile] = useState(false);
const { realm, profileName } = useParams();
const serverInfo = useServerInfo();
const executorTypes = useMemo(() => {
var _a;
return (_a = serverInfo.componentTypes) === null || _a === void 0 ? void 0 : _a["org.keycloak.services.clientpolicy.executor.ClientPolicyExecutorProvider"];
}, []);
const [executorToDelete, setExecutorToDelete] = useState();
const editMode = profileName ? true : false;
const [key, setKey] = useState(0);
const reload = () => setKey(key + 1);
useFetch(() => adminClient.clientPolicies.listProfiles({ includeGlobalProfiles: true }), (profiles) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
setProfiles({
globalProfiles: profiles.globalProfiles,
profiles: (_a = profiles.profiles) === null || _a === void 0 ? void 0 : _a.filter((p) => p.name !== profileName),
});
const globalProfile = (_b = profiles.globalProfiles) === null || _b === void 0 ? void 0 : _b.find((p) => p.name === profileName);
const profile = (_c = profiles.profiles) === null || _c === void 0 ? void 0 : _c.find((p) => p.name === profileName);
setIsGlobalProfile(globalProfile !== undefined);
setValue("name", (_e = (_d = globalProfile === null || globalProfile === void 0 ? void 0 : globalProfile.name) !== null && _d !== void 0 ? _d : profile === null || profile === void 0 ? void 0 : profile.name) !== null && _e !== void 0 ? _e : "");
setValue("description", (_g = (_f = globalProfile === null || globalProfile === void 0 ? void 0 : globalProfile.description) !== null && _f !== void 0 ? _f : profile === null || profile === void 0 ? void 0 : profile.description) !== null && _g !== void 0 ? _g : "");
setValue("executors", (_j = (_h = globalProfile === null || globalProfile === void 0 ? void 0 : globalProfile.executors) !== null && _h !== void 0 ? _h : profile === null || profile === void 0 ? void 0 : profile.executors) !== null && _j !== void 0 ? _j : []);
}, [key]);
const save = async (form) => {
const updatedProfiles = form;
try {
await adminClient.clientPolicies.createProfiles({
...profiles,
profiles: [...((profiles === null || profiles === void 0 ? void 0 : profiles.profiles) || []), updatedProfiles],
});
addAlert(editMode
? t("updateClientProfileSuccess")
: t("createClientProfileSuccess"), AlertVariant.success);
navigate(toClientProfile({ realm, profileName: form.name }));
}
catch (error) {
addError(editMode ? "updateClientProfileError" : "createClientProfileError", error);
}
};
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
titleKey: (executorToDelete === null || executorToDelete === void 0 ? void 0 : executorToDelete.name)
? t("deleteExecutorProfileConfirmTitle")
: t("deleteClientProfileConfirmTitle"),
messageKey: (executorToDelete === null || executorToDelete === void 0 ? void 0 : executorToDelete.name)
? t("deleteExecutorProfileConfirm", {
executorName: executorToDelete.name,
})
: t("deleteClientProfileConfirm", {
profileName,
}),
continueButtonLabel: t("delete"),
continueButtonVariant: ButtonVariant.danger,
onConfirm: async () => {
if (executorToDelete === null || executorToDelete === void 0 ? void 0 : executorToDelete.name) {
remove(executorToDelete.idx);
try {
await adminClient.clientPolicies.createProfiles({
...profiles,
profiles: [...(profiles.profiles || []), getValues()],
});
addAlert(t("deleteExecutorSuccess"), AlertVariant.success);
navigate(toClientProfile({ realm, profileName }));
}
catch (error) {
addError("deleteExecutorError", error);
}
}
else {
try {
await adminClient.clientPolicies.createProfiles(profiles);
addAlert(t("deleteClientSuccess"), AlertVariant.success);
navigate(toClientPolicies({ realm, tab: "profiles" }));
}
catch (error) {
addError("deleteClientError", error);
}
}
},
});
if (!profiles) {
return _jsx(KeycloakSpinner, {});
}
return (_jsxs(_Fragment, { children: [_jsx(DeleteConfirm, {}), _jsx(ViewHeader, { titleKey: editMode ? profileName : t("newClientProfile"), badges: [
{
id: "global-client-profile-badge",
text: isGlobalProfile ? (_jsx(Label, { color: "blue", children: t("global") })) : (""),
},
], divider: true, dropdownItems: editMode && !isGlobalProfile
? [
_jsx(DropdownItem, { value: "delete", onClick: toggleDeleteDialog, "data-testid": "deleteClientProfileDropdown", children: t("deleteClientProfile") }, "delete"),
]
: undefined }), _jsx(PageSection, { variant: "light", children: _jsx(FormProvider, { ...form, children: _jsxs(FormAccess, { isHorizontal: true, role: "view-realm", className: "pf-v5-u-mt-lg", children: [_jsx(TextControl, { name: "name", label: t("newClientProfileName"), helperText: t("createClientProfileNameHelperText"), readOnly: isGlobalProfile, rules: {
required: t("required"),
} }), _jsx(TextAreaControl, { name: "description", label: t("description"), readOnly: isGlobalProfile }), _jsxs(ActionGroup, { children: [!isGlobalProfile && (_jsx(Button, { variant: "primary", onClick: () => handleSubmit(save)(), "data-testid": "saveCreateProfile", isDisabled: !isDirty, children: t("save") })), editMode && !isGlobalProfile && (_jsx(Button, { id: "reloadProfile", variant: "link", "data-testid": "reloadProfile", isDisabled: !isDirty, onClick: reload, children: t("reload") })), !editMode && !isGlobalProfile && (_jsx(Button, { id: "cancelCreateProfile", variant: "link", component: (props) => (_jsx(Link, { ...props, to: toClientPolicies({ realm, tab: "profiles" }) })), "data-testid": "cancelCreateProfile", children: t("cancel") }))] }), editMode && (_jsxs(_Fragment, { children: [_jsxs(Flex, { children: [_jsx(FlexItem, { children: _jsxs(Text, { className: "kc-executors", component: TextVariants.h1, children: [t("executors"), _jsx(HelpItem, { helpText: t("executorsHelpText"), fieldLabelId: "executors" })] }) }), !isGlobalProfile && (_jsx(FlexItem, { align: { default: "alignRight" }, children: _jsx(Button, { id: "addExecutor", component: (props) => (_jsx(Link, { ...props, to: toAddExecutor({
realm,
profileName,
}) })), variant: "link", className: "kc-addExecutor", "data-testid": "addExecutor", icon: _jsx(PlusCircleIcon, {}), children: t("addExecutor") }) }))] }), profileExecutors.length > 0 && (_jsxs(_Fragment, { children: [_jsx(DataList, { "aria-label": t("executors"), isCompact: true, children: profileExecutors.map((executor, idx) => (_jsx(DataListItem, { "aria-labelledby": "executors-list-item", id: executor.executor, children: _jsx(DataListItemRow, { "data-testid": "executors-list-row", children: _jsx(DataListItemCells, { dataListCells: [
_jsxs(DataListCell, { "data-testid": "executor-type", children: [executor.configuration ? (_jsx(Button, { component: (props) => (_jsx(Link, { ...props, to: toExecutor({
realm,
profileName,
executorName: executor.executor,
}) })), variant: "link", "data-testid": "editExecutor", children: executor.executor })) : (_jsx("span", { className: "kc-unclickable-executor", children: executor.executor })), executorTypes === null || executorTypes === void 0 ? void 0 : executorTypes.filter((type) => type.id === executor.executor).map((type) => (_jsxs(Fragment, { children: [_jsx(HelpItem, { helpText: type.helpText, fieldLabelId: "executorTypeTextHelpText" }, type.id), !isGlobalProfile && (_jsx(Button, { variant: "link", isInline: true, icon: _jsx(TrashIcon, { className: "kc-executor-trash-icon", "data-testid": "deleteExecutor" }, `executorType-trash-icon-${type.id}`), onClick: () => {
toggleDeleteDialog();
setExecutorToDelete({
idx: idx,
name: type.id,
});
}, "aria-label": t("remove") }))] }, type.id)))] }, "executor"),
] }) }) }, executor.executor))) }), isGlobalProfile && (_jsx(Button, { id: "backToClientPolicies", component: (props) => (_jsx(Link, { ...props, to: toClientPolicies({ realm, tab: "profiles" }) })), variant: "primary", className: "kc-backToPolicies", "data-testid": "backToClientPolicies", children: t("back") }))] })), profileExecutors.length === 0 && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(Text, { className: "kc-emptyExecutors", component: TextVariants.h2, children: t("emptyExecutors") })] }))] }))] }) }) })] }));
}
//# sourceMappingURL=ClientProfileForm.js.map