import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation"; import { AlertVariant, Button, ButtonVariant, Dropdown, DropdownItem, KebabToggle, Popover, Text, TextContent, ToolbarItem, } from "@patternfly/react-core"; import { QuestionCircleIcon } from "@patternfly/react-icons"; import { useState } from "react"; import { Trans, useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import { useHelp } from "ui-shared"; import { adminClient } from "../admin-client"; import { useAlerts } from "../components/alert/Alerts"; import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog"; import { GroupPickerDialog } from "../components/group/GroupPickerDialog"; import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner"; import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; import { Action, KeycloakDataTable, } from "../components/table-toolbar/KeycloakDataTable"; import { useRealm } from "../context/realm-context/RealmContext"; import { toUserFederation } from "../user-federation/routes/UserFederation"; import { useFetch } from "../utils/useFetch"; import useToggle from "../utils/useToggle"; export const DefaultsGroupsTab = () => { const { t } = useTranslation("realm-settings"); const [isKebabOpen, toggleKebab] = useToggle(); const [isGroupPickerOpen, toggleGroupPicker] = useToggle(); const [defaultGroups, setDefaultGroups] = useState(); const [selectedRows, setSelectedRows] = useState([]); const [key, setKey] = useState(0); const [load, setLoad] = useState(0); const reload = () => setLoad(load + 1); const { realm } = useRealm(); const { addAlert, addError } = useAlerts(); const { enabled } = useHelp(); useFetch( () => adminClient.realms.getDefaultGroups({ realm }), (groups) => { setDefaultGroups(groups); setKey(key + 1); }, [load] ); const loader = () => Promise.resolve(defaultGroups!); const removeGroup = async () => { try { await Promise.all( selectedRows.map((group) => adminClient.realms.removeDefaultGroup({ realm, id: group.id!, }) ) ); addAlert( t("groupRemove", { count: selectedRows.length }), AlertVariant.success ); setSelectedRows([]); } catch (error) { addError("realm-settings:groupRemoveError", error); } reload(); }; const addGroups = async (groups: GroupRepresentation[]) => { try { await Promise.all( groups.map((group) => adminClient.realms.addDefaultGroup({ realm, id: group.id!, }) ) ); addAlert( t("defaultGroupAdded", { count: groups.length }), AlertVariant.success ); } catch (error) { addError("realm-settings:defaultGroupAddedError", error); } reload(); }; const [toggleRemoveDialog, RemoveDialog] = useConfirmDialog({ titleKey: t("removeConfirmTitle", { count: selectedRows.length }), messageKey: t("removeConfirm", { count: selectedRows.length }), continueButtonLabel: "common:delete", continueButtonVariant: ButtonVariant.danger, onConfirm: removeGroup, }); if (!defaultGroups) { return ; } return ( <> {isGroupPickerOpen && ( { addGroups(groups || []); toggleGroupPicker(); }} onClose={toggleGroupPicker} /> )} {enabled && ( {" "} . } > {t("whatIsDefaultGroups")} )} setSelectedRows([...rows])} loader={loader} ariaLabelKey="realm-settings:defaultGroups" searchPlaceholderKey="realm-settings:searchForGroups" toolbarItem={ <> } isOpen={isKebabOpen} isPlain dropdownItems={[ { toggleRemoveDialog(); toggleKebab(); }} > {t("common:remove")} , ]} /> } actions={[ { title: t("common:remove"), onRowClick: (group) => { setSelectedRows([group]); toggleRemoveDialog(); return Promise.resolve(false); }, } as Action, ]} columns={[ { name: "name", displayKey: "groups:groupName", }, { name: "path", displayKey: "groups:path", }, ]} emptyState={ {" "} Add groups... } primaryActionText={t("addGroups")} onPrimaryAction={toggleGroupPicker} /> } /> ); };