import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation"; import { Button, Drawer, DrawerContent, DrawerContentBody, DrawerHead, DrawerPanelContent, DropdownItem, PageSection, PageSectionVariants, Tab, TabTitleText, Tabs, Tooltip, } from "@patternfly/react-core"; import { AngleLeftIcon, TreeIcon } from "@patternfly/react-icons"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; import { GroupBreadCrumbs } from "../components/bread-crumb/GroupBreadCrumbs"; import { PermissionsTab } from "../components/permission-tab/PermissionTab"; import { ViewHeader } from "../components/view-header/ViewHeader"; import { useAccess } from "../context/access/Access"; import { fetchAdminUI } from "../context/auth/admin-ui-endpoint"; import { useRealm } from "../context/realm-context/RealmContext"; import helpUrls from "../help-urls"; import { useFetch } from "../utils/useFetch"; import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled"; import useToggle from "../utils/useToggle"; import { GroupAttributes } from "./GroupAttributes"; import { GroupRoleMapping } from "./GroupRoleMapping"; import { GroupTable } from "./GroupTable"; import { GroupsModal } from "./GroupsModal"; import { Members } from "./Members"; import { useSubGroups } from "./SubGroupsContext"; import { DeleteGroup } from "./components/DeleteGroup"; import { GroupTree } from "./components/GroupTree"; import { getId, getLastId } from "./groupIdUtils"; import { toGroups } from "./routes/Groups"; import "./GroupsSection.css"; export default function GroupsSection() { const { t } = useTranslation("groups"); const [activeTab, setActiveTab] = useState(0); const { subGroups, setSubGroups, currentGroup } = useSubGroups(); const { realm } = useRealm(); const [rename, setRename] = useState(); const [deleteOpen, toggleDeleteOpen] = useToggle(); const navigate = useNavigate(); const location = useLocation(); const id = getLastId(location.pathname); const [open, toggle] = useToggle(true); const [key, setKey] = useState(0); const refresh = () => setKey(key + 1); const { hasAccess } = useAccess(); const isFeatureEnabled = useIsFeatureEnabled(); const canViewPermissions = isFeatureEnabled(Feature.AdminFineGrainedAuthz) && hasAccess("manage-authorization", "manage-users", "manage-clients"); const canManageGroup = hasAccess("manage-users") || currentGroup()?.access?.manage; const canManageRoles = hasAccess("manage-users"); const canViewDetails = hasAccess("query-groups", "view-users") || hasAccess("manage-users", "query-groups"); const canViewMembers = hasAccess("view-users") || currentGroup()?.access?.viewMembers || currentGroup()?.access?.manageMembers; useFetch( async () => { const ids = getId(location.pathname); const isNavigationStateInValid = ids && ids.length > subGroups.length; if (isNavigationStateInValid) { const groups: GroupRepresentation[] = []; for (const i of ids!) { const group = i !== "search" ? await fetchAdminUI( "ui-ext/groups/" + i, ) : { name: t("searchGroups"), id: "search" }; if (group) { groups.push(group); } else { throw new Error(t("common:notFound")); } } return groups; } return []; }, (groups: GroupRepresentation[]) => { if (groups.length) setSubGroups(groups); }, [id], ); return ( <> { navigate(toGroups({ realm })); refresh(); }} /> {rename && ( { refresh(); setSubGroups([...subGroups.slice(0, subGroups.length - 1), group!]); }} handleModalToggle={() => setRename(undefined)} /> )} } >