From e1d53c640eac9cc9e071bb03f2af014700c7c700 Mon Sep 17 00:00:00 2001 From: Erik Jan de Wit Date: Fri, 30 Apr 2021 21:08:12 +0200 Subject: [PATCH] only query realm once (#563) fixing: #548 --- src/realm-settings/GeneralTab.tsx | 51 ++------ src/realm-settings/LoginTab.tsx | 48 ++----- src/realm-settings/RealmSettingsSection.tsx | 62 +++++---- src/realm-settings/RealmSettingsTabs.tsx | 31 ----- src/realm-settings/ThemesTab.tsx | 135 ++++++-------------- src/route-config.ts | 7 - 6 files changed, 104 insertions(+), 230 deletions(-) delete mode 100644 src/realm-settings/RealmSettingsTabs.tsx diff --git a/src/realm-settings/GeneralTab.tsx b/src/realm-settings/GeneralTab.tsx index 1897aaa275..e0af4d1a9a 100644 --- a/src/realm-settings/GeneralTab.tsx +++ b/src/realm-settings/GeneralTab.tsx @@ -1,10 +1,8 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import { useTranslation } from "react-i18next"; -import { Controller, useForm } from "react-hook-form"; -import { useErrorHandler } from "react-error-boundary"; +import { Controller, useFormContext } from "react-hook-form"; import { ActionGroup, - AlertVariant, Button, ClipboardCopy, FormGroup, @@ -20,52 +18,31 @@ import { import RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation"; import { getBaseUrl } from "../util"; -import { useAdminClient, asyncStateFetch } from "../context/auth/AdminClient"; +import { useAdminClient } from "../context/auth/AdminClient"; import { useRealm } from "../context/realm-context/RealmContext"; -import { useAlerts } from "../components/alert/Alerts"; import { FormAccess } from "../components/form-access/FormAccess"; import { HelpItem } from "../components/help-enabler/HelpItem"; import { FormattedLink } from "../components/external-link/FormattedLink"; -export const RealmSettingsGeneralTab = () => { +type RealmSettingsGeneralTabProps = { + save: (realm: RealmRepresentation) => void; + reset: () => void; +}; + +export const RealmSettingsGeneralTab = ({ + save, + reset, +}: RealmSettingsGeneralTabProps) => { const { t } = useTranslation("realm-settings"); const adminClient = useAdminClient(); - const handleError = useErrorHandler(); const { realm: realmName } = useRealm(); - const { addAlert } = useAlerts(); - const { register, control, setValue, handleSubmit } = useForm(); - const [realm, setRealm] = useState(); + const { register, control, handleSubmit } = useFormContext(); const [open, setOpen] = useState(false); const baseUrl = getBaseUrl(adminClient); const requireSslTypes = ["all", "external", "none"]; - useEffect(() => { - return asyncStateFetch( - () => adminClient.realms.findOne({ realm: realmName }), - (realm) => { - setRealm(realm); - setupForm(realm); - }, - handleError - ); - }, []); - - const setupForm = (realm: RealmRepresentation) => { - 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 }), AlertVariant.danger); - } - }; - return ( <> @@ -219,7 +196,7 @@ export const RealmSettingsGeneralTab = () => { > {t("common:save")} - diff --git a/src/realm-settings/LoginTab.tsx b/src/realm-settings/LoginTab.tsx index c59bc1372e..a40ba619be 100644 --- a/src/realm-settings/LoginTab.tsx +++ b/src/realm-settings/LoginTab.tsx @@ -1,47 +1,21 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import { useTranslation } from "react-i18next"; -import { - AlertVariant, - FormGroup, - PageSection, - Switch, -} from "@patternfly/react-core"; +import { FormGroup, PageSection, Switch } from "@patternfly/react-core"; import { FormAccess } from "../components/form-access/FormAccess"; import { HelpItem } from "../components/help-enabler/HelpItem"; import { FormPanel } from "../components/scroll-form/FormPanel"; -import { asyncStateFetch, useAdminClient } from "../context/auth/AdminClient"; import RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation"; -import { useErrorHandler } from "react-error-boundary"; -import { useRealm } from "../context/realm-context/RealmContext"; -import { useAlerts } from "../components/alert/Alerts"; -export const RealmSettingsLoginTab = () => { +type RealmSettingsLoginTabProps = { + save: (realm: RealmRepresentation) => void; + realm: RealmRepresentation; +}; + +export const RealmSettingsLoginTab = ({ + save, + realm, +}: RealmSettingsLoginTabProps) => { const { t } = useTranslation("realm-settings"); - const [realm, setRealm] = useState(); - const handleError = useErrorHandler(); - const adminClient = useAdminClient(); - const { realm: realmName } = useRealm(); - const { addAlert } = useAlerts(); - - useEffect(() => { - return asyncStateFetch( - () => adminClient.realms.findOne({ realm: realmName }), - (realm) => { - setRealm(realm); - }, - handleError - ); - }, []); - - 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 }), AlertVariant.danger); - } - }; return ( <> diff --git a/src/realm-settings/RealmSettingsSection.tsx b/src/realm-settings/RealmSettingsSection.tsx index e45d4115c0..65110dc524 100644 --- a/src/realm-settings/RealmSettingsSection.tsx +++ b/src/realm-settings/RealmSettingsSection.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from "react"; import { useHistory } from "react-router-dom"; import { useTranslation } from "react-i18next"; -import { Controller, useForm } from "react-hook-form"; +import { Controller, FormProvider, useForm } from "react-hook-form"; import { useErrorHandler } from "react-error-boundary"; import { AlertVariant, @@ -122,13 +122,16 @@ export const RealmSettingsSection = () => { const handleError = useErrorHandler(); const { realm: realmName } = useRealm(); const { addAlert } = useAlerts(); - const { control, getValues, setValue } = useForm(); + const form = useForm(); + const { control, getValues, setValue } = form; + const [realm, setRealm] = useState(); useEffect(() => { return asyncStateFetch( () => adminClient.realms.findOne({ realm: realmName }), (realm) => { setupForm(realm); + setRealm(realm); }, handleError ); @@ -141,6 +144,7 @@ export const RealmSettingsSection = () => { 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 }), AlertVariant.danger); @@ -163,29 +167,37 @@ export const RealmSettingsSection = () => { )} /> - - {t("realm-settings:general")}} - data-testid="rs-general-tab" - > - - - {t("realm-settings:login")}} - data-testid="rs-login-tab" - > - - - {t("realm-settings:themes")}} - data-testid="rs-themes-tab" - > - - - + + + {t("realm-settings:general")}} + data-testid="rs-general-tab" + > + setupForm(realm!)} + /> + + {t("realm-settings:login")}} + data-testid="rs-login-tab" + > + + + {t("realm-settings:themes")}} + data-testid="rs-themes-tab" + > + setupForm(realm!)} + /> + + + ); diff --git a/src/realm-settings/RealmSettingsTabs.tsx b/src/realm-settings/RealmSettingsTabs.tsx deleted file mode 100644 index fb80ad4dad..0000000000 --- a/src/realm-settings/RealmSettingsTabs.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react"; -import { PageSection, Tab, TabTitleText } from "@patternfly/react-core"; -import { useTranslation } from "react-i18next"; -import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs"; -import { RealmSettingsLoginTab } from "./LoginTab"; -import { RealmSettingsGeneralTab } from "./GeneralTab"; - -export const RealmSettingsTabs = () => { - const { t } = useTranslation("roles"); - - return ( - <> - - - {t("realm-settings:general")}} - > - - - {t("realm-settings:login")}} - > - - - - - - ); -}; diff --git a/src/realm-settings/ThemesTab.tsx b/src/realm-settings/ThemesTab.tsx index d2ad16def0..8dcf74c6d2 100644 --- a/src/realm-settings/ThemesTab.tsx +++ b/src/realm-settings/ThemesTab.tsx @@ -1,10 +1,8 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import { useTranslation } from "react-i18next"; -import { Controller, useForm } from "react-hook-form"; -import { useErrorHandler } from "react-error-boundary"; +import { Controller, useFormContext, useWatch } from "react-hook-form"; import { ActionGroup, - AlertVariant, Button, FormGroup, PageSection, @@ -15,21 +13,20 @@ import { } from "@patternfly/react-core"; import RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation"; -import { useAdminClient, asyncStateFetch } from "../context/auth/AdminClient"; -import { useRealm } from "../context/realm-context/RealmContext"; -import { useAlerts } from "../components/alert/Alerts"; import { FormAccess } from "../components/form-access/FormAccess"; import { HelpItem } from "../components/help-enabler/HelpItem"; import { useServerInfo } from "../context/server-info/ServerInfoProvider"; -export const RealmSettingsThemesTab = () => { +type RealmSettingsThemesTabProps = { + save: (realm: RealmRepresentation) => void; + reset: () => void; +}; + +export const RealmSettingsThemesTab = ({ + save, + reset, +}: RealmSettingsThemesTabProps) => { const { t } = useTranslation("realm-settings"); - const adminClient = useAdminClient(); - const handleError = useErrorHandler(); - const { realm: realmName } = useRealm(); - const { addAlert } = useAlerts(); - const { control, setValue, handleSubmit } = useForm(); - const [realm, setRealm] = useState(); const [loginThemeOpen, setLoginThemeOpen] = useState(false); const [accountThemeOpen, setAccountThemeOpen] = useState(false); @@ -38,60 +35,22 @@ export const RealmSettingsThemesTab = () => { const [supportedLocalesOpen, setSupportedLocalesOpen] = useState(false); const [defaultLocaleOpen, setDefaultLocaleOpen] = useState(false); - const [selections, setSelections] = useState([]); - const [ - internationalizationEnabled, - setInternationalizationEnabled, - ] = useState(false); - - const form = useForm(); + const { control, handleSubmit } = useFormContext(); const themeTypes = useServerInfo().themes!; - const watchSupportedLocales = form.watch( - "supportedLocales", - themeTypes?.account![0].locales - ); + const watchSupportedLocales = useWatch({ + control, + name: "supportedLocales", + defaultValue: themeTypes?.account![0].locales, + }); - useEffect(() => { - return asyncStateFetch( - () => adminClient.realms.findOne({ realm: realmName }), - (realm) => { - setRealm(realm); - setupForm(realm); - setInternationalizationEnabled(realm.internationalizationEnabled!); - }, - handleError - ); - }, []); - - useEffect(() => { - setValue("supportedLocales", realm?.supportedLocales); - setValue("defaultLocale", realm?.defaultLocale); - }, [internationalizationEnabled]); - - const setupForm = (realm: RealmRepresentation) => { - const { ...formValues } = realm; - - form.reset(formValues); - Object.entries(realm).map((entry) => { - if (entry[0] === "internationalizationEnabled") { - setInternationalizationEnabled(realm!.internationalizationEnabled!); - } - setValue(entry[0], entry[1]); - }); - }; - - const save = async (realm: RealmRepresentation) => { - try { - await adminClient.realms.update({ realm: realmName }, realm); - setRealm({ supportedLocales: selections, ...realm }); - addAlert(t("saveSuccess"), AlertVariant.success); - } catch (error) { - addAlert(t("saveError", { error }), AlertVariant.danger); - } - }; + const internationalizationEnabled = useWatch({ + control, + name: "internationalizationEnabled", + defaultValue: false, + }); return ( <> @@ -116,6 +75,7 @@ export const RealmSettingsThemesTab = () => { ( { ( { ( { ? "internationalization-enabled" : "internationalization-disabled" } - onChange={(value) => { - onChange(value); - if (value) { - setValue("internationalizationEnabled", true); - setInternationalizationEnabled(value); - } - setInternationalizationEnabled(value); - }} + onChange={onChange} /> )} /> @@ -311,6 +268,7 @@ export const RealmSettingsThemesTab = () => { ( { placeholderText="Select one" data-testid="select-default-locale" > - {selections.length !== 0 - ? selections.map((locale: string, idx: number) => ( - - {t(`allSupportedLocales.${locale}`)} - - )) - : watchSupportedLocales.map( - (locale: string, idx: number) => ( - - {t(`allSupportedLocales.${locale}`)} - - ) - )} + {watchSupportedLocales.map( + (locale: string, idx: number) => ( + + {t(`allSupportedLocales.${locale}`)} + + ) + )} )} /> @@ -408,7 +357,7 @@ export const RealmSettingsThemesTab = () => { > {t("common:save")} - diff --git a/src/route-config.ts b/src/route-config.ts index 096f8dbfa3..04f5bfe1dc 100644 --- a/src/route-config.ts +++ b/src/route-config.ts @@ -29,7 +29,6 @@ import { RoleMappingForm } from "./client-scopes/add/RoleMappingForm"; import { RealmRoleTabs } from "./realm-roles/RealmRoleTabs"; import { SearchGroups } from "./groups/SearchGroups"; import { CreateInitialAccessToken } from "./clients/initial-access/CreateInitialAccessToken"; -import { RealmSettingsTabs } from "./realm-settings/RealmSettingsTabs"; import { LdapMapperDetails } from "./user-federation/ldap/mappers/LdapMapperDetails"; import { AddIdentityProvider } from "./identity-providers/add/AddIdentityProvider"; @@ -179,12 +178,6 @@ export const routes: RoutesFn = (t: TFunction) => [ breadcrumb: t("realmSettings"), access: "view-realm", }, - { - path: "/:realm/realm-settings/general", - component: RealmSettingsTabs, - breadcrumb: t("realmSettings"), - access: "view-realm", - }, { path: "/:realm/authentication", component: AuthenticationSection,