keycloak-scim/src/realm-settings/RealmSettingsSection.tsx
jenny-s51 fd1466c0d6 test email working, modal wip
email connection done

remove comment

fix cypress test

revert test file

fdisable email prompting when user email entered

prettier

update cypress tests

fix lint

try fix cypress test

try longer wait
2021-06-21 14:47:34 -04:00

336 lines
10 KiB
TypeScript

import React, { useEffect, useState, useContext } from "react";
import { useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { Controller, FormProvider, useForm } from "react-hook-form";
import {
AlertVariant,
ButtonVariant,
DropdownItem,
DropdownSeparator,
PageSection,
Tab,
Tabs,
TabTitleText,
} from "@patternfly/react-core";
import type RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation";
import { toUpperCase } from "../util";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
import { useRealm } from "../context/realm-context/RealmContext";
import { ViewHeader } from "../components/view-header/ViewHeader";
import { useAlerts } from "../components/alert/Alerts";
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
import { RealmSettingsLoginTab } from "./LoginTab";
import { RealmSettingsGeneralTab } from "./GeneralTab";
import { PartialImportDialog } from "./PartialImport";
import { RealmSettingsThemesTab } from "./ThemesTab";
import { RealmSettingsEmailTab } from "./EmailTab";
import { KeysListTab } from "./KeysListTab";
import { EventsTab } from "./event-config/EventsTab";
import type ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
import { KeysProviderTab } from "./KeysProvidersTab";
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
import { LocalizationTab } from "./LocalizationTab";
import { WhoAmIContext } from "../context/whoami/WhoAmI";
import type UserRepresentation from "keycloak-admin/lib/defs/userRepresentation";
type RealmSettingsHeaderProps = {
onChange: (value: boolean) => void;
value: boolean;
save: () => void;
realmName: string;
};
const RealmSettingsHeader = ({
save,
onChange,
value,
realmName,
}: RealmSettingsHeaderProps) => {
const { t } = useTranslation("realm-settings");
const adminClient = useAdminClient();
const { addAlert } = useAlerts();
const history = useHistory();
const { refresh } = useRealm();
const [partialImportOpen, setPartialImportOpen] = useState(false);
const [toggleDisableDialog, DisableConfirm] = useConfirmDialog({
titleKey: "realm-settings:disableConfirmTitle",
messageKey: "realm-settings:disableConfirm",
continueButtonLabel: "common:disable",
onConfirm: () => {
onChange(!value);
save();
},
});
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
titleKey: "realm-settings:deleteConfirmTitle",
messageKey: "realm-settings:deleteConfirm",
continueButtonLabel: "common:delete",
continueButtonVariant: ButtonVariant.danger,
onConfirm: async () => {
try {
await adminClient.realms.del({ realm: realmName });
addAlert(t("deletedSuccess"), AlertVariant.success);
history.push("/master/");
refresh();
} catch (error) {
addAlert(t("deleteError", { error }), AlertVariant.danger);
}
},
});
return (
<>
<DisableConfirm />
<DeleteConfirm />
<PartialImportDialog
open={partialImportOpen}
toggleDialog={() => setPartialImportOpen(!partialImportOpen)}
/>
<ViewHeader
titleKey={toUpperCase(realmName)}
divider={false}
dropdownItems={[
<DropdownItem
key="import"
data-testid="openPartialImportModal"
onClick={() => {
setPartialImportOpen(true);
}}
>
{t("partialImport")}
</DropdownItem>,
<DropdownItem key="export" onClick={() => {}}>
{t("partialExport")}
</DropdownItem>,
<DropdownSeparator key="separator" />,
<DropdownItem key="delete" onClick={toggleDeleteDialog}>
{t("common:delete")}
</DropdownItem>,
]}
isEnabled={value}
onToggle={(value) => {
if (!value) {
toggleDisableDialog();
} else {
onChange(value);
save();
}
}}
/>
</>
);
};
export const RealmSettingsSection = () => {
const { t } = useTranslation("realm-settings");
const adminClient = useAdminClient();
const { realm: realmName } = useRealm();
const { addAlert } = useAlerts();
const form = useForm();
const { control, getValues, setValue, reset: resetForm } = form;
const [key, setKey] = useState(0);
const [realm, setRealm] = useState<RealmRepresentation>();
const [activeTab, setActiveTab] = useState(0);
const [realmComponents, setRealmComponents] = useState<
ComponentRepresentation[]
>();
const [currentUser, setCurrentUser] = useState<UserRepresentation>();
const { whoAmI } = useContext(WhoAmIContext);
const kpComponentTypes = useServerInfo().componentTypes![
"org.keycloak.keys.KeyProvider"
];
useFetch(
() => adminClient.realms.findOne({ realm: realmName }),
(realm) => {
setupForm(realm);
setRealm(realm);
},
[]
);
useFetch(
() => adminClient.users.findOne({ id: whoAmI.getUserId()! }),
(user) => {
setCurrentUser(user);
},
[]
);
useEffect(() => {
const update = async () => {
const realmComponents = await adminClient.components.find({
type: "org.keycloak.keys.KeyProvider",
realm: realmName,
});
setRealmComponents(realmComponents);
};
setTimeout(update, 100);
}, [key]);
useFetch(
async () => {
const realm = await adminClient.realms.findOne({ realm: realmName });
const realmComponents = await adminClient.components.find({
type: "org.keycloak.keys.KeyProvider",
realm: realmName,
});
return { realm, realmComponents };
},
(result) => {
setRealm(result.realm);
setRealmComponents(result.realmComponents);
},
[key]
);
const refresh = () => {
setKey(new Date().getTime());
};
useEffect(() => {
if (realm) setupForm(realm);
}, [realm]);
const setupForm = (realm: RealmRepresentation) => {
resetForm(realm);
Object.entries(realm).map((entry) => setValue(entry[0], entry[1]));
};
const save = async (realm: RealmRepresentation) => {
try {
await adminClient.realms.update({ realm: realmName }, realm);
setRealm(realm);
addAlert(t("saveSuccess"), AlertVariant.success);
} catch (error) {
addAlert(
t("saveError", { error: error.response?.data?.errorMessage || error }),
AlertVariant.danger
);
}
};
return (
<>
<Controller
name="enabled"
control={control}
defaultValue={true}
render={({ onChange, value }) => (
<RealmSettingsHeader
value={value}
onChange={onChange}
realmName={realmName}
save={() => save(getValues())}
/>
)}
/>
<PageSection variant="light" className="pf-u-p-0">
<FormProvider {...form}>
<KeycloakTabs isBox>
<Tab
eventKey="general"
title={<TabTitleText>{t("general")}</TabTitleText>}
data-testid="rs-general-tab"
>
<RealmSettingsGeneralTab
save={save}
reset={() => setupForm(realm!)}
/>
</Tab>
<Tab
eventKey="login"
title={<TabTitleText>{t("login")}</TabTitleText>}
data-testid="rs-login-tab"
>
<RealmSettingsLoginTab save={save} realm={realm!} />
</Tab>
<Tab
eventKey="email"
title={<TabTitleText>{t("email")}</TabTitleText>}
data-testid="rs-email-tab"
>
{realm && (
<RealmSettingsEmailTab user={currentUser!} realm={realm} />
)}
</Tab>
<Tab
eventKey="themes"
title={<TabTitleText>{t("themes")}</TabTitleText>}
data-testid="rs-themes-tab"
>
<RealmSettingsThemesTab
save={save}
reset={() => setupForm(realm!)}
realm={realm!}
/>
</Tab>
<Tab
eventKey="keys"
title={<TabTitleText>{t("realm-settings:keys")}</TabTitleText>}
data-testid="rs-keys-tab"
>
{realmComponents && (
<Tabs
activeKey={activeTab}
onSelect={(_, key) => setActiveTab(key as number)}
>
<Tab
id="keysList"
eventKey={0}
data-testid="rs-keys-list-tab"
title={<TabTitleText>{t("keysList")}</TabTitleText>}
>
<KeysListTab realmComponents={realmComponents} />
</Tab>
<Tab
id="providers"
data-testid="rs-providers-tab"
eventKey={1}
title={<TabTitleText>{t("providers")}</TabTitleText>}
>
<KeysProviderTab
realmComponents={realmComponents}
keyProviderComponentTypes={kpComponentTypes}
refresh={refresh}
/>
</Tab>
</Tabs>
)}
</Tab>
<Tab
eventKey="events"
title={<TabTitleText>{t("events")}</TabTitleText>}
data-testid="rs-realm-events-tab"
>
<EventsTab />
</Tab>
{realm && (
<Tab
id="localization"
eventKey="localization"
title={<TabTitleText>{t("localization")}</TabTitleText>}
>
<LocalizationTab
key={key}
refresh={refresh}
save={save}
reset={() => setupForm(realm)}
realm={realm}
/>
</Tab>
)}
</KeycloakTabs>
</FormProvider>
</PageSection>
</>
);
};