@keycloakify/keycloak-admin-ui
Version:
Repackaged Keycloak Admin UI
151 lines • 10.3 kB
JavaScript
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