UNPKG

@keycloakify/keycloak-admin-ui

Version:
148 lines 8.26 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { useHelp } from "../ui-shared"; import { AlertVariant, Button, ButtonVariant, Checkbox, Popover, } from "@patternfly/react-core"; import { QuestionCircleIcon } from "@patternfly/react-icons"; import { cellWidth } from "@patternfly/react-table"; import { intersectionBy, sortBy, uniqBy } from "lodash-es"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useAdminClient } from "../admin-client"; import { useAlerts } from "../ui-shared"; import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog"; import { GroupPath } from "../components/group/GroupPath"; import { GroupPickerDialog } from "../components/group/GroupPickerDialog"; import { ListEmptyState } from "../ui-shared"; import { KeycloakDataTable } from "../ui-shared"; import { useAccess } from "../context/access/Access"; export const UserGroups = ({ user }) => { var _a, _b, _c; const { adminClient } = useAdminClient(); const { t } = useTranslation(); const { addAlert, addError } = useAlerts(); const [key, setKey] = useState(0); const refresh = () => setKey(key + 1); const [selectedGroups, setSelectedGroups] = useState([]); const [isDirectMembership, setDirectMembership] = useState(true); const [directMembershipList, setDirectMembershipList] = useState([]); const [open, setOpen] = useState(false); const { enabled } = useHelp(); const { hasAccess } = useAccess(); const isManager = hasAccess("manage-users"); const alphabetize = (groupsList) => { return sortBy(groupsList, (group) => { var _a; return (_a = group.path) === null || _a === void 0 ? void 0 : _a.toUpperCase(); }); }; const loader = async (first, max, search) => { const params = { first: first, max: max, }; const searchParam = search || ""; if (searchParam) { params.search = searchParam; } const joinedUserGroups = await adminClient.users.listGroups({ ...params, id: user.id, }); setDirectMembershipList([...joinedUserGroups]); const indirect = []; if (!isDirectMembership) joinedUserGroups.forEach((g) => { var _a; const paths = (((_a = g.path) === null || _a === void 0 ? void 0 : _a.substring(1).match(/((~\/)|[^/])+/g)) || []).slice(0, -1); indirect.push(...paths.map((p) => { var _a; return ({ name: p, path: (_a = g.path) === null || _a === void 0 ? void 0 : _a.substring(0, g.path.indexOf(p) + p.length), }); })); }); return alphabetize(uniqBy([...joinedUserGroups, ...indirect], "path")); }; const toggleModal = () => { setOpen(!open); }; const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ titleKey: t("leaveGroup", { count: selectedGroups.length, name: (_a = selectedGroups[0]) === null || _a === void 0 ? void 0 : _a.name, }), messageKey: t("leaveGroupConfirmDialog", { count: selectedGroups.length, groupname: (_b = selectedGroups[0]) === null || _b === void 0 ? void 0 : _b.name, username: user.username, }), continueButtonLabel: "leave", continueButtonVariant: ButtonVariant.danger, onConfirm: async () => { try { await Promise.all(selectedGroups.map((group) => adminClient.users.delFromGroup({ id: user.id, groupId: group.id, }))); setSelectedGroups([]); addAlert(t("removedGroupMembership"), AlertVariant.success); } catch (error) { addError("removedGroupMembershipError", error); } refresh(); }, }); const leave = (group) => { setSelectedGroups(group); toggleDeleteDialog(); }; const addGroups = async (groups) => { try { await Promise.all(groups.map((group) => adminClient.users.addToGroup({ id: user.id, groupId: group.id, }))); addAlert(t("addedGroupMembership"), AlertVariant.success); } catch (error) { addError("addedGroupMembershipError", error); } refresh(); }; return (_jsxs(_Fragment, { children: [_jsx(DeleteConfirm, {}), open && (_jsx(GroupPickerDialog, { id: user.id, type: "selectMany", text: { title: t("joinGroupsFor", { username: user.username }), ok: "join", }, canBrowse: isManager, onClose: () => setOpen(false), onConfirm: async (groups = []) => { await addGroups(groups); setOpen(false); } })), _jsx(KeycloakDataTable, { loader: loader, className: "keycloak_user-section_groups-table", isPaginated: true, ariaLabelKey: "roleList", searchPlaceholderKey: "searchGroup", canSelectAll: true, onSelect: (groups) => isDirectMembership ? setSelectedGroups(groups) : setSelectedGroups(intersectionBy(groups, directMembershipList, "id")), isRowDisabled: (group) => !isDirectMembership && directMembershipList.every((item) => item.id !== group.id), toolbarItem: _jsxs(_Fragment, { children: [_jsx(Button, { className: "kc-join-group-button", onClick: toggleModal, "data-testid": "add-group-button", isDisabled: !((_c = user.access) === null || _c === void 0 ? void 0 : _c.manageGroupMembership), children: t("joinGroup") }), _jsx(Checkbox, { label: t("directMembership"), id: "kc-direct-membership-checkbox", onChange: () => { setDirectMembership(!isDirectMembership); refresh(); }, isChecked: isDirectMembership, className: "direct-membership-check" }, "direct-membership-check"), _jsx(Button, { onClick: () => leave(selectedGroups), "data-testid": "leave-group-button", variant: "link", isDisabled: selectedGroups.length === 0, children: t("leave") }), enabled && (_jsx(Popover, { "aria-label": "Basic popover", position: "bottom", bodyContent: _jsx("div", { children: t("whoWillAppearPopoverTextUsers") }), children: _jsx(Button, { variant: "link", className: "kc-who-will-appear-button", icon: _jsx(QuestionCircleIcon, {}), children: t("whoWillAppearLinkTextUsers") }, "who-will-appear-button") }))] }), columns: [ { name: "groupMembership", displayKey: "groupMembership", cellRenderer: (group) => group.name || "-", transforms: [cellWidth(40)], }, { name: "path", displayKey: "path", cellRenderer: (group) => (_jsx(GroupPath, { group: group })), transforms: [cellWidth(45)], }, { name: "", cellRenderer: (group) => { var _a; const canLeaveGroup = directMembershipList.some((item) => item.id === group.id) || directMembershipList.length === 0 || isDirectMembership; return canLeaveGroup ? (_jsx(Button, { "data-testid": `leave-${group.name}`, onClick: () => leave([group]), variant: "link", isDisabled: !((_a = user.access) === null || _a === void 0 ? void 0 : _a.manageGroupMembership), children: t("leave") })) : ("-"); }, transforms: [cellWidth(20)], }, ], emptyState: _jsx(ListEmptyState, { hasIcon: true, message: t("noGroups"), instructions: t("noGroupsText"), primaryActionText: t("joinGroup"), onPrimaryAction: toggleModal }) }, key)] })); }; //# sourceMappingURL=UserGroups.js.map