UNPKG

@keycloakify/keycloak-admin-ui

Version:
153 lines 11.7 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { ListEmptyState, PaginatingTableToolbar, useAlerts, useFetch, } from "../../ui-shared"; import { Alert, AlertVariant, ButtonVariant, DescriptionList, Divider, Dropdown, DropdownItem, DropdownList, MenuToggle, PageSection, ToolbarItem, } from "@patternfly/react-core"; import { ExpandableRowContent, Table, Tbody, Td, Th, Thead, Tr, } from "@patternfly/react-table"; import { useState } from "react"; 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 { useRealm } from "../../context/realm-context/RealmContext"; import useToggle from "../../utils/useToggle"; import { toNewPermission } from "../../clients/routes/NewPermission"; import { toPermissionDetails } from "../../clients/routes/PermissionDetails"; import { toPolicyDetails } from "../../clients/routes/PolicyDetails"; import { DetailDescriptionLink } from "../../clients/authorization/DetailDescription"; import { EmptyPermissionsState } from "../../clients/authorization/EmptyPermissionsState"; import { MoreLabel } from "../../clients/authorization/MoreLabel"; import { SearchDropdown } from "../../clients/authorization/SearchDropdown"; import "./permissions.css"; const AssociatedPoliciesRenderer = ({ row, }) => { var _a, _b; return (_jsxs(_Fragment, { children: [((_b = (_a = row.associatedPolicies) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.name) || "—", " ", _jsx(MoreLabel, { array: row.associatedPolicies })] })); }; export const AuthorizationPermissions = ({ clientId, isDisabled = false, }) => { const { adminClient } = useAdminClient(); const { t } = useTranslation(); const navigate = useNavigate(); const { addAlert, addError } = useAlerts(); const { realm } = useRealm(); const [permissions, setPermissions] = useState(); const [selectedPermission, setSelectedPermission] = useState(); const [policyProviders, setPolicyProviders] = useState(); const [disabledCreate, setDisabledCreate] = useState(); const [createOpen, toggleCreate] = useToggle(); const [search, setSearch] = useState({}); const [key, setKey] = useState(0); const refresh = () => setKey(key + 1); const [max, setMax] = useState(10); const [first, setFirst] = useState(0); useFetch(async () => { const permissions = await adminClient.clients.findPermissions({ first, max: max + 1, id: clientId, ...search, }); return await Promise.all(permissions.map(async (permission) => { const associatedPolicies = await adminClient.clients.getAssociatedPolicies({ id: clientId, permissionId: permission.id, }); return { ...permission, associatedPolicies, isExpanded: false, }; })); }, setPermissions, [key, search, first, max]); useFetch(async () => { const params = { first: 0, max: 1, }; const [policies, resources, scopes] = await Promise.all([ adminClient.clients.listPolicyProviders({ id: clientId, }), adminClient.clients.listResources({ ...params, id: clientId }), adminClient.clients.listAllScopes({ ...params, id: clientId }), ]); return { policies: policies.filter((p) => p.type === "resource" || p.type === "scope"), resources: resources.length !== 1, scopes: scopes.length !== 1, }; }, ({ policies, resources, scopes }) => { setPolicyProviders(policies); setDisabledCreate({ resources, scopes }); }, []); const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ titleKey: "deletePermission", messageKey: t("deletePermissionConfirm", { permission: selectedPermission === null || selectedPermission === void 0 ? void 0 : selectedPermission.name, }), continueButtonVariant: ButtonVariant.danger, continueButtonLabel: "confirm", onConfirm: async () => { try { await adminClient.clients.delPermission({ id: clientId, type: selectedPermission === null || selectedPermission === void 0 ? void 0 : selectedPermission.type, permissionId: selectedPermission === null || selectedPermission === void 0 ? void 0 : selectedPermission.id, }); addAlert(t("permissionDeletedSuccess"), AlertVariant.success); refresh(); } catch (error) { addError("permissionDeletedError", error); } }, }); if (!permissions) { return _jsx(KeycloakSpinner, {}); } const noData = permissions.length === 0; const searching = Object.keys(search).length !== 0; return (_jsxs(PageSection, { variant: "light", className: "pf-v5-u-p-0", children: [_jsx(DeleteConfirm, {}), (!noData || searching) && (_jsx(PaginatingTableToolbar, { count: permissions.length, first: first, max: max, onNextClick: setFirst, onPreviousClick: setFirst, onPerPageSelect: (first, max) => { setFirst(first); setMax(max); }, toolbarItem: _jsxs(_Fragment, { children: [_jsx(ToolbarItem, { children: _jsx(SearchDropdown, { types: policyProviders, search: search, onSearch: setSearch, type: "permission" }) }), _jsx(ToolbarItem, { children: _jsx(Dropdown, { onOpenChange: toggleCreate, toggle: (ref) => (_jsx(MenuToggle, { ref: ref, onClick: toggleCreate, isDisabled: isDisabled, variant: "primary", "data-testid": "permissionCreateDropdown", children: t("createPermission") })), isOpen: createOpen, children: _jsxs(DropdownList, { children: [_jsx(DropdownItem, { "data-testid": "create-resource", isDisabled: isDisabled || (disabledCreate === null || disabledCreate === void 0 ? void 0 : disabledCreate.resources), component: "button", onClick: () => navigate(toNewPermission({ realm, id: clientId, permissionType: "resource", })), children: t("createResourceBasedPermission") }), _jsx(Divider, {}), _jsxs(DropdownItem, { "data-testid": "create-scope", isDisabled: isDisabled || (disabledCreate === null || disabledCreate === void 0 ? void 0 : disabledCreate.scopes), component: "button", onClick: () => navigate(toNewPermission({ realm, id: clientId, permissionType: "scope", })), children: [t("createScopeBasedPermission"), (disabledCreate === null || disabledCreate === void 0 ? void 0 : disabledCreate.scopes) && (_jsx(Alert, { className: "pf-v5-u-mt-sm", variant: "warning", isInline: true, isPlain: true, title: t("noScopeCreateHint") }))] })] }) }) })] }), children: !noData && (_jsxs(Table, { "aria-label": t("resources"), variant: "compact", children: [_jsx(Thead, { children: _jsxs(Tr, { children: [_jsx(Th, { "aria-hidden": "true" }), _jsx(Th, { children: t("name") }), _jsx(Th, { children: t("type") }), _jsx(Th, { children: t("associatedPolicy") }), _jsx(Th, { children: t("description") }), _jsx(Th, { "aria-hidden": "true" })] }) }), permissions.map((permission, rowIndex) => { var _a; return (_jsxs(Tbody, { isExpanded: permission.isExpanded, children: [_jsxs(Tr, { children: [_jsx(Td, { expand: { rowIndex, isExpanded: permission.isExpanded, onToggle: (_, rowIndex) => { const rows = permissions.map((p, index) => index === rowIndex ? { ...p, isExpanded: !p.isExpanded } : p); setPermissions(rows); }, } }), _jsx(Td, { "data-testid": `name-column-${permission.name}`, children: _jsx(Link, { to: toPermissionDetails({ realm, id: clientId, permissionType: permission.type, permissionId: permission.id, }), children: permission.name }) }), _jsx(Td, { children: (_a = policyProviders === null || policyProviders === void 0 ? void 0 : policyProviders.find((p) => p.type === permission.type)) === null || _a === void 0 ? void 0 : _a.name }), _jsx(Td, { children: _jsx(AssociatedPoliciesRenderer, { row: permission }) }), _jsx(Td, { children: permission.description || "—" }), _jsx(Td, { actions: { items: [ { title: t("delete"), onClick: async () => { setSelectedPermission(permission); toggleDeleteDialog(); }, }, ], } })] }), _jsxs(Tr, { isExpanded: permission.isExpanded, children: [_jsx(Td, {}), _jsx(Td, { colSpan: 5, children: _jsx(ExpandableRowContent, { children: permission.isExpanded && (_jsx(DescriptionList, { isHorizontal: true, className: "keycloak_resource_details", children: _jsx(DetailDescriptionLink, { name: "associatedPolicy", array: permission.associatedPolicies, convert: (p) => p.name, link: (p) => toPolicyDetails({ id: clientId, realm, policyId: p.id, policyType: p.type, }) }) })) }) })] }, `child-${permission.id}`)] }, permission.id)); })] })) })), noData && !searching && (_jsx(EmptyPermissionsState, { clientId: clientId, isResourceEnabled: !isDisabled && (disabledCreate === null || disabledCreate === void 0 ? void 0 : disabledCreate.resources), isScopeEnabled: !isDisabled && (disabledCreate === null || disabledCreate === void 0 ? void 0 : disabledCreate.scopes) })), noData && searching && (_jsx(ListEmptyState, { isSearchVariant: true, message: t("noSearchResults"), instructions: t("noSearchResultsInstructions") }))] })); }; //# sourceMappingURL=Permissions.js.map