UNPKG

@keycloakify/keycloak-admin-ui

Version:
152 lines 12.5 kB
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