UNPKG

@keycloakify/keycloak-admin-ui

Version:
184 lines 10.7 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { KeycloakDataTable, useAlerts, useFetch, } from "../ui-shared"; import { CodeEditor, Language } from "@patternfly/react-code-editor"; import { AlertVariant, Button, ButtonVariant, Divider, Flex, FlexItem, PageSection, Radio, Switch, Title, ToolbarItem, } from "@patternfly/react-core"; import { omit } from "lodash-es"; import { useState } from "react"; import { Controller, 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 { KeycloakSpinner } from "../ui-shared"; import { ListEmptyState } from "../ui-shared"; import { useRealm } from "../context/realm-context/RealmContext"; import { prettyPrintJSON } from "../util"; import { translationFormatter } from "../utils/translationFormatter"; import { toAddClientPolicy } from "../realm-settings/routes/AddClientPolicy"; import { toClientPolicies } from "../realm-settings/routes/ClientPolicies"; import { toEditClientPolicy } from "../realm-settings/routes/EditClientPolicy"; import "./realm-settings-section.css"; export const PoliciesTab = () => { const { adminClient } = useAdminClient(); const { t } = useTranslation(); const { addAlert, addError } = useAlerts(); const { realm } = useRealm(); const navigate = useNavigate(); const [show, setShow] = useState(false); const [policies, setPolicies] = useState(); const [selectedPolicy, setSelectedPolicy] = useState(); const [key, setKey] = useState(0); const [code, setCode] = useState(); const [tablePolicies, setTablePolicies] = useState(); const refresh = () => setKey(key + 1); const form = useForm({ mode: "onChange" }); useFetch(() => adminClient.clientPolicies.listPolicies({ includeGlobalPolicies: true, }), (allPolicies) => { var _a, _b; const globalPolicies = (_a = allPolicies.globalPolicies) === null || _a === void 0 ? void 0 : _a.map((globalPolicies) => ({ ...globalPolicies, global: true, })); const policies = (_b = allPolicies.policies) === null || _b === void 0 ? void 0 : _b.map((policies) => ({ ...policies, global: false, })); const allClientPolicies = globalPolicies === null || globalPolicies === void 0 ? void 0 : globalPolicies.concat(policies !== null && policies !== void 0 ? policies : []); setPolicies(allClientPolicies); setTablePolicies(allClientPolicies || []); setCode(prettyPrintJSON(allClientPolicies)); }, [key]); const loader = async () => policies !== null && policies !== void 0 ? policies : []; const saveStatus = async () => { const switchValues = form.getValues(); const updatedPolicies = policies === null || policies === void 0 ? void 0 : policies.filter((policy) => { return !policy.global; }).map((policy) => { const enabled = switchValues[policy.name]; const enabledPolicy = { ...policy, enabled, }; delete enabledPolicy.global; return enabledPolicy; }); try { await adminClient.clientPolicies.updatePolicy({ policies: updatedPolicies, }); navigate(toClientPolicies({ realm, tab: "policies" })); addAlert(t("updateClientPolicySuccess"), AlertVariant.success); } catch (error) { addError("updateClientPolicyError", error); } }; const normalizePolicy = (policy) => omit(policy, "global"); const save = async () => { if (!code) { return; } try { const obj = JSON.parse(code); const changedPolicies = obj .filter((policy) => !policy.global) .map((policy) => normalizePolicy(policy)); const changedGlobalPolicies = obj .filter((policy) => policy.global) .map((policy) => normalizePolicy(policy)); try { await adminClient.clientPolicies.updatePolicy({ policies: changedPolicies, globalPolicies: changedGlobalPolicies, }); addAlert(t("updateClientPoliciesSuccess"), AlertVariant.success); refresh(); } catch (error) { addError("updateClientPoliciesError", error); } } catch (error) { console.warn("Invalid json, ignoring value using {}"); addError("invalidJsonClientPoliciesError", error); } }; const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ titleKey: t("deleteClientPolicyConfirmTitle"), messageKey: t("deleteClientPolicyConfirm", { policyName: selectedPolicy === null || selectedPolicy === void 0 ? void 0 : selectedPolicy.name, }), continueButtonLabel: t("delete"), continueButtonVariant: ButtonVariant.danger, onConfirm: async () => { const updatedPolicies = policies === null || policies === void 0 ? void 0 : policies.filter((policy) => { return !policy.global && policy.name !== (selectedPolicy === null || selectedPolicy === void 0 ? void 0 : selectedPolicy.name); }).map((policy) => { const newPolicy = { ...policy }; delete newPolicy.global; return newPolicy; }); try { await adminClient.clientPolicies.updatePolicy({ policies: updatedPolicies, }); addAlert(t("deleteClientPolicySuccess"), AlertVariant.success); refresh(); } catch (error) { addError("deleteClientPolicyError", error); } }, }); if (!policies) { return _jsx(KeycloakSpinner, {}); } return (_jsxs(_Fragment, { children: [_jsx(DeleteConfirm, {}), _jsx(PageSection, { children: _jsxs(Flex, { className: "kc-policies-config-section", children: [_jsx(FlexItem, { children: _jsx(Title, { headingLevel: "h1", size: "md", children: t("policiesConfigType") }) }), _jsx(FlexItem, { children: _jsx(Radio, { isChecked: !show, name: "policiesView", onChange: () => setShow(false), label: t("policiesConfigTypes.formView"), id: "formView-policiesView", "data-testid": "formView-policiesView", className: "kc-form-radio-btn pf-v5-u-mr-sm pf-v5-u-ml-sm" }) }), _jsx(FlexItem, { children: _jsx(Radio, { isChecked: show, name: "policiesView", onChange: () => setShow(true), label: t("policiesConfigTypes.jsonEditor"), id: "jsonEditor-policiesView", "data-testid": "jsonEditor-policiesView", className: "kc-editor-radio-btn" }) })] }) }), _jsx(Divider, {}), !show ? (_jsx(KeycloakDataTable, { emptyState: _jsx(ListEmptyState, { message: t("noClientPolicies"), instructions: t("noClientPoliciesInstructions"), primaryActionText: t("createClientPolicy"), onPrimaryAction: () => navigate(toAddClientPolicy({ realm })) }), ariaLabelKey: "clientPolicies", searchPlaceholderKey: "clientPolicySearch", loader: loader, toolbarItem: _jsx(ToolbarItem, { children: _jsx(Button, { id: "createPolicy", component: (props) => (_jsx(Link, { ...props, to: toAddClientPolicy({ realm }) })), "data-testid": "createPolicy", children: t("createClientPolicy") }) }), isRowDisabled: (value) => !!value.global, actions: [ { title: t("delete"), onRowClick: (item) => { toggleDeleteDialog(); setSelectedPolicy(item); }, }, ], columns: [ { name: "name", cellRenderer: ({ name }) => (_jsx(Link, { to: toEditClientPolicy({ realm, policyName: name }), children: name })), }, { name: "enabled", displayKey: "status", cellRenderer: (clientPolicy) => (_jsx(SwitchRenderer, { clientPolicy: clientPolicy, form: form, saveStatus: saveStatus, onConfirm: () => { form.setValue(clientPolicy.name, false); saveStatus(); } })), }, { name: "description", cellFormatters: [translationFormatter(t)], }, ] }, policies.length)) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "pf-v5-u-mt-md pf-v5-u-ml-lg", children: _jsx(CodeEditor, { isLineNumbersVisible: true, isLanguageLabelVisible: true, isReadOnly: false, code: code, language: Language.json, height: "30rem", onChange: setCode }) }), _jsxs("div", { className: "pf-v5-u-mt-md", children: [_jsx(Button, { variant: ButtonVariant.primary, className: "pf-v5-u-mr-md pf-v5-u-ml-lg", "data-testid": "jsonEditor-policies-saveBtn", onClick: save, children: t("save") }), _jsx(Button, { variant: ButtonVariant.link, "data-testid": "jsonEditor-reloadBtn", onClick: () => { setCode(prettyPrintJSON(tablePolicies)); }, children: t("reload") })] })] }))] })); }; const SwitchRenderer = ({ clientPolicy, form, saveStatus, onConfirm, }) => { const { t } = useTranslation(); const [toggleDisableDialog, DisableConfirm] = useConfirmDialog({ titleKey: "disablePolicyConfirmTitle", messageKey: "disablePolicyConfirm", continueButtonLabel: "disable", onConfirm, }); return (_jsxs(_Fragment, { children: [_jsx(DisableConfirm, {}), _jsx(Controller, { name: clientPolicy.name, "data-testid": `${clientPolicy.name}-switch`, defaultValue: clientPolicy.enabled, control: form.control, render: ({ field }) => (_jsx(Switch, { label: t("enabled"), labelOff: t("disabled"), isChecked: field.value, isDisabled: clientPolicy.global, onChange: (_event, value) => { if (!value) { toggleDisableDialog(); } else { field.onChange(value); saveStatus(); } }, "aria-label": clientPolicy.name })) })] })); }; //# sourceMappingURL=PoliciesTab.js.map