import React, { useMemo, useState } from "react"; import { omit } from "lodash"; import { AlertVariant, Button, ButtonVariant, Label, PageSection, Spinner, ToolbarItem, } from "@patternfly/react-core"; import { Divider, Flex, FlexItem, Radio, Title } from "@patternfly/react-core"; import { CodeEditor, Language } from "@patternfly/react-code-editor"; import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable"; import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; import { useTranslation } from "react-i18next"; import { useAdminClient, useFetch } from "../context/auth/AdminClient"; import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog"; import { useRealm } from "../context/realm-context/RealmContext"; import { useAlerts } from "../components/alert/Alerts"; import { Link } from "react-router-dom"; import { toNewClientProfile } from "./routes/NewClientProfile"; import type ClientProfileRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientProfileRepresentation"; import "./RealmSettingsSection.css"; type ClientProfile = ClientProfileRepresentation & { global: boolean; }; export const ProfilesTab = () => { const { t } = useTranslation("realm-settings"); const adminClient = useAdminClient(); const { realm } = useRealm(); const { addAlert, addError } = useAlerts(); const [tableProfiles, setTableProfiles] = useState(); const [globalProfiles, setGlobalProfiles] = useState(); const [selectedProfile, setSelectedProfile] = useState(); const [show, setShow] = useState(false); const [key, setKey] = useState(0); useFetch( () => adminClient.clientPolicies.listProfiles({ includeGlobalProfiles: true, }), (allProfiles) => { setGlobalProfiles(allProfiles.globalProfiles); const globalProfiles = allProfiles.globalProfiles?.map( (globalProfiles) => ({ ...globalProfiles, global: true, }) ); const profiles = allProfiles.profiles?.map((profiles) => ({ ...profiles, global: false, })); const allClientProfiles = globalProfiles?.concat(profiles ?? []); setTableProfiles(allClientProfiles || []); }, [key] ); const loader = async () => tableProfiles ?? []; const code = useMemo( () => JSON.stringify(tableProfiles, null, 2), [tableProfiles] ); const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ titleKey: t("deleteClientProfileConfirmTitle"), messageKey: t("deleteClientProfileConfirm"), continueButtonLabel: t("delete"), continueButtonVariant: ButtonVariant.danger, onConfirm: async () => { const updatedProfiles = tableProfiles ?.filter( (profile) => profile.name !== selectedProfile?.name && !profile.global ) .map((profile) => omit(profile, "global")); try { await adminClient.clientPolicies.createProfiles({ profiles: updatedProfiles, globalProfiles, }); addAlert(t("deleteClientSuccess"), AlertVariant.success); setKey(key + 1); } catch (error) { addError(t("deleteClientError"), error); } }, }); const cellFormatter = (row: ClientProfile) => ( {row.name} {row.global && } ); if (!tableProfiles) { return (
); } return ( <> {t("profilesConfigType")} setShow(false)} label={t("profilesConfigTypes.formView")} id="formView-profilesView" className="kc-form-radio-btn pf-u-mr-sm pf-u-ml-sm" data-testid="formView-profilesView" /> setShow(true)} label={t("profilesConfigTypes.jsonEditor")} id="jsonEditor-profilesView" className="kc-editor-radio-btn" data-testid="jsonEditor-profilesView" /> {!show ? ( } isRowDisabled={(value) => value.global} actions={[ { title: t("common:delete"), onRowClick: (profile) => { setSelectedProfile(profile); toggleDeleteDialog(); }, }, ]} columns={[ { name: "name", displayKey: t("clientProfileName"), cellRenderer: cellFormatter, }, { name: "description", displayKey: t("clientProfileDescription"), }, ]} emptyState={ } /> ) : ( <>
)} ); };