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