/* eslint-disable */ // @ts-nocheck import type { UserProfileAttribute } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata"; import { KeycloakSelect, SelectVariant } from "../../../shared/keycloak-ui-shared"; import { Button, ButtonVariant, Divider, SelectOption, Toolbar, ToolbarContent, ToolbarItem, } from "../../../shared/@patternfly/react-core"; import { FilterIcon } from "../../../shared/@patternfly/react-icons"; import { uniqBy } from "lodash-es"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { Link, useNavigate } from "react-router-dom"; import { useAdminClient } from "../../admin-client"; import { DraggableTable } from "../../authentication/components/DraggableTable"; import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog"; import { KeycloakSpinner } from "../../../shared/keycloak-ui-shared"; import { useRealm } from "../../context/realm-context/RealmContext"; import useLocale from "../../utils/useLocale"; import useToggle from "../../utils/useToggle"; import { toAddAttribute } from "../routes/AddAttribute"; import { toAttribute } from "../routes/Attribute"; import { useUserProfile } from "./UserProfileContext"; const RESTRICTED_ATTRIBUTES = ["username", "email"]; type movedAttributeType = UserProfileAttribute; type AttributesTabProps = { setTableData: React.Dispatch< React.SetStateAction[] | undefined> >; }; export const AttributesTab = ({ setTableData }: AttributesTabProps) => { const { adminClient } = useAdminClient(); const { config, save } = useUserProfile(); const { realm } = useRealm(); const { t } = useTranslation(); const combinedLocales = useLocale(); const navigate = useNavigate(); const [filter, setFilter] = useState("allGroups"); const [isFilterTypeDropdownOpen, toggleIsFilterTypeDropdownOpen] = useToggle(); const [data, setData] = useState(config?.attributes); const [attributeToDelete, setAttributeToDelete] = useState(""); const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ titleKey: t("deleteAttributeConfirmTitle"), messageKey: t("deleteAttributeConfirm", { attributeName: attributeToDelete, }), continueButtonLabel: t("delete"), continueButtonVariant: ButtonVariant.danger, onConfirm: async () => { if (!config?.attributes) return; const translationsToDelete = config.attributes.find( (attribute) => attribute.name === attributeToDelete, )?.displayName; // Remove the the `${}` from translationsToDelete string const formattedTranslationsToDelete = translationsToDelete?.substring( 2, translationsToDelete.length - 1, ); try { await Promise.all( combinedLocales.map(async (locale) => { try { const response = (await adminClient.realms.getRealmLocalizationTexts({ realm, selectedLocale: locale, })) as Record | undefined; if (response) { await adminClient.realms.deleteRealmLocalizationTexts({ realm, selectedLocale: locale, key: formattedTranslationsToDelete, }); const updatedData = await adminClient.realms.getRealmLocalizationTexts({ realm, selectedLocale: locale, }); setTableData([updatedData]); } } catch { console.error(`Error removing translations for ${locale}`); } }), ); const updatedAttributes = config.attributes.filter( (attribute) => attribute.name !== attributeToDelete, ); await save( { ...config, attributes: updatedAttributes, groups: config.groups }, { successMessageKey: "deleteAttributeSuccess", errorMessageKey: "deleteAttributeError", }, ); setAttributeToDelete(""); } catch (error) { console.error( `Error removing translations or updating attributes: ${error}`, ); } }, }); if (!config) { return ; } const attributes = config.attributes ?? []; const groups = config.groups ?? []; const executeMove = async ( attribute: UserProfileAttribute, newIndex: number, ) => { const fromIndex = attributes.findIndex((attr) => { return attr.name === attribute.name; }); let movedAttribute: movedAttributeType = {}; movedAttribute = attributes[fromIndex]; attributes.splice(fromIndex, 1); attributes.splice(newIndex, 0, movedAttribute); await save( { ...config, attributes, groups }, { successMessageKey: "updatedUserProfileSuccess", errorMessageKey: "updatedUserProfileError", }, ); }; const cellFormatter = (row: UserProfileAttribute) => ( {row.name} ); return ( <> } onSelect={(value) => { const filter = value.toString(); setFilter(filter); setData( filter === "allGroups" ? attributes : attributes.filter((attr) => attr.group === filter), ); toggleIsFilterTypeDropdownOpen(); }} selections={filter === "allGroups" ? t(filter) : filter} > {[ {t("allGroups")} , ...uniqBy( attributes.filter((attr) => !!attr.group), "group", ).map((attr) => ( {attr.group} )), ]} { const keys = attributes.map((e) => e.name); const newIndex = items.indexOf(nameDragged); const oldIndex = keys.indexOf(nameDragged); const dragged = attributes[oldIndex]; if (!dragged.name) return; await executeMove(dragged, newIndex); }} actions={[ { title: t("edit"), onClick: (_key, _idx, component) => { navigate( toAttribute({ realm, attributeName: component.name, }), ); }, }, { title: t("delete"), isActionable: ({ name }) => !RESTRICTED_ATTRIBUTES.includes(name!), onClick: (_key, _idx, component) => { setAttributeToDelete(component.name); toggleDeleteDialog(); }, }, ]} columns={[ { name: "name", displayKey: t("attributeName"), cellRenderer: cellFormatter, }, { name: "displayName", displayKey: t("attributeDisplayName"), }, { name: "group", displayKey: t("attributeGroup"), }, ]} data={data ?? attributes} /> ); };