UNPKG

@keycloakify/keycloak-admin-ui

Version:
151 lines 10.3 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { DecisionStrategy } from "@keycloak/keycloak-admin-client/lib/defs/policyRepresentation"; import { FormErrorText, HelpItem, SelectVariant, TextAreaControl, TextControl, useAlerts, useFetch, } from "../../ui-shared"; import { ActionGroup, AlertVariant, Button, ButtonVariant, DropdownItem, FormGroup, PageSection, Radio, Switch, } from "@patternfly/react-core"; import { useState } from "react"; import { Controller, FormProvider, useForm, useWatch } 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 { useAccess } from "../../context/access/Access"; import { toUpperCase } from "../../util"; import { useParams } from "../../utils/useParams"; import { toAuthorizationTab } from "../../clients/routes/AuthenticationTab"; import { toPermissionDetails, } from "../../clients/routes/PermissionDetails"; import { ResourcesPolicySelect } from "../../clients/authorization/ResourcesPolicySelect"; import { ScopeSelect } from "../../clients/authorization/ScopeSelect"; export default function PermissionDetails() { const { adminClient } = useAdminClient(); const { t } = useTranslation(); const form = useForm({ mode: "onChange", }); const { control, reset, formState: { errors }, handleSubmit, } = form; const navigate = useNavigate(); const { id, realm, permissionType, permissionId, selectedId } = useParams(); const { addAlert, addError } = useAlerts(); const [permission, setPermission] = useState(); const [applyToResourceTypeFlag, setApplyToResourceTypeFlag] = useState(false); const { hasAccess } = useAccess(); const isDisabled = !hasAccess("manage-authorization"); useFetch(async () => { if (!permissionId) { return {}; } const [permission, resources, policies, scopes] = await Promise.all([ adminClient.clients.findOnePermission({ id, type: permissionType, permissionId, }), adminClient.clients.getAssociatedResources({ id, permissionId, }), adminClient.clients.getAssociatedPolicies({ id, permissionId, }), adminClient.clients.getAssociatedScopes({ id, permissionId, }), ]); if (!permission) { throw new Error(t("notFound")); } return { permission, resources: resources.map((r) => r._id), policies: policies.map((p) => p.id), scopes: scopes.map((s) => s.id), }; }, ({ permission, resources, policies, scopes }) => { reset({ ...permission, resources, policies, scopes }); if (permission && "resourceType" in permission) { setApplyToResourceTypeFlag(!!permission.resourceType); } setPermission({ ...permission, resources, policies }); }, []); const save = async (permission) => { try { if (permissionId) { await adminClient.clients.updatePermission({ id, type: permissionType, permissionId }, permission); } else { const result = await adminClient.clients.createPermission({ id, type: permissionType }, permission); setPermission(result); navigate(toPermissionDetails({ realm, id, permissionType, permissionId: result.id, })); } addAlert(t((permissionId ? "update" : "create") + "PermissionSuccess"), AlertVariant.success); } catch (error) { addError("permissionSaveError", error); } }; const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ titleKey: "deletePermission", messageKey: t("deletePermissionConfirm", { permission: permission === null || permission === void 0 ? void 0 : permission.name, }), continueButtonVariant: ButtonVariant.danger, continueButtonLabel: "confirm", onConfirm: async () => { try { await adminClient.clients.delPermission({ id, type: permissionType, permissionId: permissionId, }); addAlert(t("permissionDeletedSuccess"), AlertVariant.success); navigate(toAuthorizationTab({ realm, clientId: id, tab: "permissions" })); } catch (error) { addError("permissionDeletedError", error); } }, }); const resourcesIds = useWatch({ control, name: "resources", defaultValue: [], }); if (!permission) { return _jsx(KeycloakSpinner, {}); } return (_jsxs(_Fragment, { children: [_jsx(DeleteConfirm, {}), _jsx(ViewHeader, { titleKey: permissionId ? permission.name : `create${toUpperCase(permissionType)}BasedPermission`, dropdownItems: permissionId ? [ _jsx(DropdownItem, { "data-testid": "delete-resource", isDisabled: isDisabled, onClick: () => toggleDeleteDialog(), children: t("delete") }, "delete"), ] : undefined }), _jsx(PageSection, { variant: "light", children: _jsx(FormAccess, { isHorizontal: true, role: "manage-authorization", onSubmit: handleSubmit(save), children: _jsxs(FormProvider, { ...form, children: [_jsx(TextControl, { name: "name", label: t("name"), labelIcon: t("permissionName"), rules: { required: t("required"), } }), _jsx(TextAreaControl, { name: "description", label: t("description"), labelIcon: t("permissionDescription"), rules: { maxLength: { value: 255, message: t("maxLength", { length: 255 }), }, } }), _jsx(FormGroup, { label: t("applyToResourceTypeFlag"), fieldId: "applyToResourceTypeFlag", labelIcon: _jsx(HelpItem, { helpText: t("applyToResourceTypeFlagHelp"), fieldLabelId: "applyToResourceTypeFlag" }), children: _jsx(Switch, { id: "applyToResourceTypeFlag", name: "applyToResourceTypeFlag", label: t("on"), labelOff: t("off"), isChecked: applyToResourceTypeFlag, onChange: (_event, val) => setApplyToResourceTypeFlag(val), "aria-label": t("applyToResourceTypeFlag") }) }), applyToResourceTypeFlag ? (_jsx(TextControl, { name: "resourceType", label: t("resourceType"), labelIcon: t("resourceTypeHelp"), rules: { required: { value: permissionType === "scope" ? true : false, message: t("required"), }, } })) : (_jsxs(FormGroup, { label: t("resource"), fieldId: "resources", labelIcon: _jsx(HelpItem, { helpText: t("permissionResources"), fieldLabelId: "resources" }), isRequired: permissionType !== "scope", children: [_jsx(ResourcesPolicySelect, { name: "resources", clientId: id, permissionId: permissionId, preSelected: permissionType === "scope" ? undefined : selectedId, variant: permissionType === "scope" ? SelectVariant.typeahead : SelectVariant.typeaheadMulti, isRequired: permissionType !== "scope" }), errors.resources && _jsx(FormErrorText, { message: t("required") })] })), permissionType === "scope" && (_jsxs(FormGroup, { label: t("authorizationScopes"), fieldId: "scopes", labelIcon: _jsx(HelpItem, { helpText: t("permissionScopesHelp"), fieldLabelId: "scopesSelect" }), isRequired: true, children: [_jsx(ScopeSelect, { clientId: id, resourceId: resourcesIds === null || resourcesIds === void 0 ? void 0 : resourcesIds[0], preSelected: selectedId }), errors.scopes && _jsx(FormErrorText, { message: t("required") })] })), _jsx(FormGroup, { label: t("policies"), fieldId: "policies", labelIcon: _jsx(HelpItem, { helpText: t("permissionPoliciesHelp"), fieldLabelId: "policies" }), children: _jsx(ResourcesPolicySelect, { name: "policies", clientId: id, permissionId: permissionId }) }), _jsx(FormGroup, { label: t("decisionStrategy"), labelIcon: _jsx(HelpItem, { helpText: t("permissionDecisionStrategyHelp"), fieldLabelId: "decisionStrategy" }), fieldId: "policyEnforcementMode", hasNoPaddingTop: true, children: _jsx(Controller, { name: "decisionStrategy", "data-testid": "decisionStrategy", defaultValue: DecisionStrategy.UNANIMOUS, control: control, render: ({ field }) => (_jsx(_Fragment, { children: Object.values(DecisionStrategy).map((strategy) => (_jsx(Radio, { id: strategy, "data-testid": strategy, isChecked: field.value === strategy, isDisabled: isDisabled, name: "decisionStrategies", onChange: () => field.onChange(strategy), label: t(`decisionStrategies.${strategy}`), className: "pf-v5-u-mb-md" }, strategy))) })) }) }), _jsx(ActionGroup, { children: _jsxs("div", { className: "pf-v5-u-mt-md", children: [_jsx(Button, { variant: ButtonVariant.primary, type: "submit", "data-testid": "save", children: t("save") }), _jsx(Button, { variant: "link", "data-testid": "cancel", component: (props) => (_jsx(Link, { ...props, to: toAuthorizationTab({ realm, clientId: id, tab: "permissions", }) })), children: t("cancel") })] }) })] }) }) })] })); } //# sourceMappingURL=PermissionDetails.js.map