UNPKG

@keycloakify/keycloak-admin-ui

Version:
133 lines 9.53 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { ListEmptyState, PaginatingTableToolbar, useFetch, } from "../../ui-shared"; import { Button, DescriptionList, 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 { KeycloakSpinner } from "../../ui-shared"; import { useRealm } from "../../context/realm-context/RealmContext"; import useToggle from "../../utils/useToggle"; import { toNewPermission } from "../../clients/routes/NewPermission"; import { toNewScope } from "../../clients/routes/NewScope"; import { toPermissionDetails } from "../../clients/routes/PermissionDetails"; import { toResourceDetails } from "../../clients/routes/Resource"; import { toScopeDetails } from "../../clients/routes/Scope"; import { DeleteScopeDialog } from "../../clients/authorization/DeleteScopeDialog"; import { DetailDescriptionLink } from "../../clients/authorization/DetailDescription"; export const AuthorizationScopes = ({ clientId, isDisabled = false, }) => { const { adminClient } = useAdminClient(); const { t } = useTranslation(); const navigate = useNavigate(); const { realm } = useRealm(); const [deleteDialog, toggleDeleteDialog] = useToggle(); const [scopes, setScopes] = useState(); const [selectedScope, setSelectedScope] = useState(); const [collapsed, setCollapsed] = useState([]); const [key, setKey] = useState(0); const refresh = () => setKey(key + 1); const [max, setMax] = useState(10); const [first, setFirst] = useState(0); const [search, setSearch] = useState(""); useFetch(() => { const params = { first, max: max + 1, deep: false, name: search, }; return adminClient.clients.listAllScopes({ ...params, id: clientId, }); }, (scopes) => { setScopes(scopes.map((s) => ({ ...s, isLoaded: false }))); setCollapsed(scopes.map((s) => ({ id: s.id, isExpanded: false }))); }, [key, search, first, max]); const getScope = (id) => scopes === null || scopes === void 0 ? void 0 : scopes.find((scope) => scope.id === id); const isExpanded = (id) => { var _a; return ((_a = collapsed.find((c) => c.id === id)) === null || _a === void 0 ? void 0 : _a.isExpanded) || false; }; useFetch(() => { const newlyOpened = collapsed .filter((row) => row.isExpanded) .map(({ id }) => getScope(id)) .filter((s) => !s.isLoaded); return Promise.all(newlyOpened.map(async (scope) => { const [resources, permissions] = await Promise.all([ adminClient.clients.listAllResourcesByScope({ id: clientId, scopeId: scope.id, }), adminClient.clients.listAllPermissionsByScope({ id: clientId, scopeId: scope.id, }), ]); return { ...scope, resources, permissions, isLoaded: true, }; })); }, (resourcesScopes) => { let result = [...(scopes || [])]; resourcesScopes.forEach((resourceScope) => { const index = scopes === null || scopes === void 0 ? void 0 : scopes.findIndex((scope) => resourceScope.id === scope.id); result = [ ...result.slice(0, index), resourceScope, ...result.slice(index + 1), ]; }); setScopes(result); }, [collapsed]); if (!scopes) { return _jsx(KeycloakSpinner, {}); } const noData = scopes.length === 0; const searching = search !== ""; return (_jsxs(PageSection, { variant: "light", className: "pf-v5-u-p-0", children: [_jsx(DeleteScopeDialog, { clientId: clientId, open: deleteDialog, toggleDialog: toggleDeleteDialog, selectedScope: selectedScope, refresh: refresh }), (!noData || searching) && (_jsx(PaginatingTableToolbar, { count: scopes.length, first: first, max: max, onNextClick: setFirst, onPreviousClick: setFirst, onPerPageSelect: (first, max) => { setFirst(first); setMax(max); }, inputGroupName: "search", inputGroupPlaceholder: t("searchByName"), inputGroupOnEnter: setSearch, toolbarItem: _jsx(ToolbarItem, { children: _jsx(Button, { "data-testid": "createAuthorizationScope", component: (props) => (_jsx(Link, { ...props, to: toNewScope({ realm, id: clientId }) })), children: t("createAuthorizationScope") }) }), children: !noData && (_jsxs(Table, { "aria-label": t("scopes"), variant: "compact", children: [_jsx(Thead, { children: _jsxs(Tr, { children: [_jsx(Th, { "aria-hidden": "true" }), _jsx(Th, { children: t("name") }), _jsx(Th, { children: t("displayName") }), _jsx(Th, { "aria-hidden": "true" }), _jsx(Th, { "aria-hidden": "true" })] }) }), scopes.map((scope, rowIndex) => (_jsxs(Tbody, { isExpanded: isExpanded(scope.id), children: [_jsxs(Tr, { children: [_jsx(Td, { expand: { rowIndex, isExpanded: isExpanded(scope.id), onToggle: (_event, index, isExpanded) => { setCollapsed([ ...collapsed.slice(0, index), { id: scope.id, isExpanded }, ...collapsed.slice(index + 1), ]); }, } }), _jsx(Td, { "data-testid": `name-column-${scope.name}`, children: _jsx(Link, { to: toScopeDetails({ realm, id: clientId, scopeId: scope.id, }), children: scope.name }) }), _jsx(Td, { children: scope.displayName }), _jsx(Td, { width: 10, children: _jsx(Button, { variant: "link", component: (props) => (_jsx(Link, { ...props, to: toNewPermission({ realm, id: clientId, permissionType: "scope", selectedId: scope.id, }) })), children: t("createPermission") }) }), _jsx(Td, { isActionCell: true, actions: { items: [ { title: t("delete"), onClick: () => { setSelectedScope(scope); toggleDeleteDialog(); }, }, ], } })] }), _jsxs(Tr, { isExpanded: isExpanded(scope.id), children: [_jsx(Td, {}), _jsx(Td, { colSpan: 4, children: _jsx(ExpandableRowContent, { children: isExpanded(scope.id) && scope.isLoaded ? (_jsxs(DescriptionList, { isHorizontal: true, className: "keycloak_resource_details", children: [_jsx(DetailDescriptionLink, { name: "resources", array: scope.resources, convert: (r) => r.name, link: (r) => toResourceDetails({ id: clientId, realm, resourceId: r._id, }) }), _jsx(DetailDescriptionLink, { name: "associatedPermissions", array: scope.permissions, convert: (p) => p.name, link: (p) => toPermissionDetails({ id: clientId, realm, permissionId: p.id, permissionType: p.type, }) })] })) : (_jsx(KeycloakSpinner, {})) }) })] }, `child-${scope.id}`)] }, scope.id)))] })) })), noData && !searching && (_jsx(ListEmptyState, { message: t("emptyAuthorizationScopes"), instructions: t("emptyAuthorizationInstructions"), isDisabled: isDisabled, onPrimaryAction: () => navigate(toNewScope({ id: clientId, realm })), primaryActionText: t("createAuthorizationScope") })), noData && searching && (_jsx(ListEmptyState, { isSearchVariant: true, isDisabled: isDisabled, message: t("noSearchResults"), instructions: t("noSearchResultsInstructions") }))] })); }; //# sourceMappingURL=Scopes.js.map