migrated some of the controls to ui-shared (#27424)

* migrated some of the controls to ui-shared

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Update js/apps/admin-ui/src/user-federation/ldap/LdapSettingsGeneral.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Update js/apps/admin-ui/src/user-federation/ldap/LdapSettingsGeneral.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Update js/apps/admin-ui/src/user-federation/ldap/LdapSettingsKerberosIntegration.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Update js/apps/admin-ui/src/user-federation/ldap/LdapSettingsSearching.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Update js/apps/admin-ui/src/user-federation/ldap/mappers/LdapMapperDetails.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Update js/apps/admin-ui/src/user-federation/ldap/mappers/LdapMapperDetails.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Update js/apps/admin-ui/src/user-federation/ldap/mappers/LdapMapperDetails.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Update js/apps/admin-ui/src/user-federation/ldap/mappers/LdapMapperDetails.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Update js/apps/admin-ui/src/user-federation/ldap/LdapSettingsGeneral.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* Apply suggestions from code review

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* review fixes

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* fixed test

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* tests

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

---------

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
Co-authored-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
Erik Jan de Wit 2024-03-06 09:40:54 +01:00 committed by GitHub
parent 61c3edcab8
commit b486972485
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 382 additions and 953 deletions

View file

@ -1,23 +1,23 @@
export default class ProviderPage {
// KerberosSettingsRequired input values
#kerberosNameInput = "kerberos-name";
#kerberosRealmInput = "kerberos-realm";
#kerberosPrincipalInput = "kerberos-principal";
#kerberosKeytabInput = "kerberos-keytab";
#kerberosNameInput = "name";
#kerberosRealmInput = "config.kerberosRealm.0";
#kerberosPrincipalInput = "config.serverPrincipal.0";
#kerberosKeytabInput = "config.keyTab.0";
// LdapSettingsGeneral input values
#ldapNameInput = "ldap-name";
#ldapNameInput = "name";
#ldapVendorInput = "#kc-vendor";
#ldapVendorList = "#kc-vendor + ul";
// LdapSettingsConnection input values
connectionUrlInput = "ldap-connection-url";
connectionUrlInput = "config.connectionUrl.0";
truststoreSpiInput = "#kc-use-truststore-spi";
truststoreSpiList = "#kc-use-truststore-spi + ul";
connectionTimeoutInput = "connection-timeout";
connectionTimeoutInput = "config.connectionTimeout.0";
bindTypeInput = "#kc-bind-type";
#bindTypeList = "#kc-bind-type + ul";
bindDnInput = "ldap-bind-dn";
bindDnInput = "config.bindDn.0";
bindCredsInput = "ldap-bind-credentials";
#testConnectionBtn = "test-connection-button";
#testAuthBtn = "test-auth-button";
@ -28,26 +28,26 @@ export default class ProviderPage {
ldapSearchScopeInput = "#kc-search-scope";
#ldapSearchScopeInputList = "#kc-search-scope + ul";
ldapPagination = "ui-pagination";
ldapUsersDnInput = "ldap-users-dn";
ldapUserLdapAttInput = "ldap-username-attribute";
ldapRdnLdapAttInput = "ldap-rdn-attribute";
ldapUuidLdapAttInput = "ldap-uuid-attribute";
ldapUserObjClassesInput = "ldap-user-object-classes";
ldapUserLdapFilter = "user-ldap-filter";
ldapReadTimeout = "ldap-read-timeout";
ldapUsersDnInput = "config.usersDn.0";
ldapUserLdapAttInput = "config.usernameLDAPAttribute.0";
ldapRdnLdapAttInput = "config.rdnLDAPAttribute.0";
ldapUuidLdapAttInput = "config.uuidLDAPAttribute.0";
ldapUserObjClassesInput = "config.userObjectClasses.0";
ldapUserLdapFilter = "config.customUserSearchFilter.0";
ldapReadTimeout = "config.readTimeout.0";
// LdapSettingsKerberosIntegration input values
ldapKerberosRealmInput = "kerberos-realm";
ldapServerPrincipalInput = "kerberos-principal";
ldapKeyTabInput = "kerberos-keytab";
ldapKerberosRealmInput = "config.kerberosRealm.0";
ldapServerPrincipalInput = "config.serverPrincipal.0";
ldapKeyTabInput = "config.keyTab.0";
allowKerberosAuth = "allow-kerberos-auth";
debug = "debug";
useKerberosForPwAuth = "use-kerberos-pw-auth";
// LdapSettingsSynchronization input values
ldapBatchSizeInput = "batch-size";
ldapFullSyncPeriodInput = "full-sync-period";
ldapUsersSyncPeriodInput = "changed-users-sync-period";
ldapBatchSizeInput = "config.batchSizeForSync.0";
ldapFullSyncPeriodInput = "config.fullSyncPeriod.0";
ldapUsersSyncPeriodInput = "config.changedSyncPeriod.0";
importUsers = "import-users";
periodicFullSync = "periodic-full-sync";
periodicUsersSync = "periodic-changed-users-sync";
@ -327,7 +327,7 @@ export default class ProviderPage {
cy.get("#kc-providerId").click();
cy.get("button").contains(mapperType).click();
cy.findByTestId("ldap-mapper-name").clear().type(`${mapperType}-test`);
cy.findByTestId("name").clear().type(`${mapperType}-test`);
switch (mapperType) {
case this.#msadUserAcctMapper:

View file

@ -1,18 +1,17 @@
import { FormGroup, Switch } from "@patternfly/react-core";
import { Controller, useFormContext } from "react-hook-form";
import { Controller, FormProvider, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem } from "ui-shared";
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
import { HelpItem, TextControl } from "ui-shared";
export const SyncSettings = () => {
const { t } = useTranslation();
const { control, register, watch } = useFormContext();
const form = useFormContext();
const { control, watch } = form;
const watchPeriodicSync = watch("config.fullSyncPeriod", "-1");
const watchChangedSync = watch("config.changedSyncPeriod", "-1");
return (
<>
<FormProvider {...form}>
<FormGroup
label={t("periodicFullSync")}
labelIcon={
@ -44,26 +43,14 @@ export const SyncSettings = () => {
/>
</FormGroup>
{watchPeriodicSync !== "-1" && (
<FormGroup
hasNoPaddingTop
<TextControl
name="config.fullSyncPeriod"
label={t("fullSyncPeriod")}
labelIcon={
<HelpItem
helpText={t("fullSyncPeriodHelp")}
fieldLabelId="fullSyncPeriod"
/>
}
fieldId="kc-full-sync-period"
>
<KeycloakTextInput
labelIcon={t("fullSyncPeriodHelp")}
type="number"
min={-1}
defaultValue="604800"
id="kc-full-sync-period"
data-testid="full-sync-period"
{...register("config.fullSyncPeriod")}
/>
</FormGroup>
)}
<FormGroup
label={t("periodicChangedUsersSync")}
@ -96,27 +83,15 @@ export const SyncSettings = () => {
/>
</FormGroup>
{watchChangedSync !== "-1" && (
<FormGroup
<TextControl
name="config.changedSyncPeriod"
label={t("changedUsersSyncPeriod")}
labelIcon={
<HelpItem
helpText={t("changedUsersSyncHelp")}
fieldLabelId="changedUsersSyncPeriod"
/>
}
fieldId="kc-changed-users-sync-period"
hasNoPaddingTop
>
<KeycloakTextInput
labelIcon={t("changedUsersSyncHelp")}
type="number"
min={-1}
defaultValue="86400"
id="kc-changed-users-sync-period"
data-testid="changed-users-sync-period"
{...register("config.changedSyncPeriod")}
/>
</FormGroup>
)}
</>
</FormProvider>
);
};

View file

@ -7,10 +7,14 @@ import {
} from "@patternfly/react-core";
import { isEqual } from "lodash-es";
import { useState } from "react";
import { Controller, UseFormReturn, useWatch } from "react-hook-form";
import {
Controller,
FormProvider,
UseFormReturn,
useWatch,
} from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem } from "ui-shared";
import { HelpItem, TextControl } from "ui-shared";
import { adminClient } from "../../admin-client";
import { FormAccess } from "../../components/form/FormAccess";
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
@ -47,7 +51,7 @@ export const KerberosSettingsRequired = ({
);
return (
<>
<FormProvider {...form}>
{showSectionHeading && (
<WizardSectionHeader
title={t("requiredSettings")}
@ -58,162 +62,54 @@ export const KerberosSettingsRequired = ({
{/* Required settings */}
<FormAccess role="manage-realm" isHorizontal>
<FormGroup
label={t("uiDisplayName")}
labelIcon={
<HelpItem
helpText={t("uiDisplayNameHelp")}
fieldLabelId="uiDisplayName"
/>
}
fieldId="kc-ui-display-name"
isRequired
validated={form.formState.errors.name ? "error" : "default"}
helperTextInvalid={(form.formState.errors.name as any)?.message}
>
{/* These hidden fields are required so data object written back matches data retrieved */}
<KeycloakTextInput
hidden
id="kc-ui-providerId"
defaultValue="kerberos"
{...form.register("providerId")}
/>
<KeycloakTextInput
hidden
id="kc-ui-providerType"
defaultValue="org.keycloak.storage.UserStorageProvider"
{...form.register("providerType")}
/>
<KeycloakTextInput
hidden
id="kc-ui-parentId"
defaultValue={realm}
{...form.register("parentId")}
/>
<KeycloakTextInput
isRequired
id="kc-ui-name"
data-testid="kerberos-name"
validated={form.formState.errors.name ? "error" : "default"}
aria-label={t("uiDisplayName")}
{...form.register("name", {
required: {
value: true,
message: t("validateName"),
},
})}
<TextControl
name="name"
label={t("uiDisplayName")}
labelIcon={t("uiDisplayNameHelp")}
rules={{
required: t("validateName"),
}}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.kerberosRealm.0"
label={t("kerberosRealm")}
labelIcon={
<HelpItem
helpText={t("kerberosRealmHelp")}
fieldLabelId="kc-kerberos-realm"
labelIcon={t("kerberosRealmHelp")}
rules={{
required: t("validateRealm"),
}}
/>
}
fieldId="kc-kerberos-realm"
isRequired
validated={
(form.formState.errors.config as any)?.kerberosRealm?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.kerberosRealm?.[0].message
}
>
<KeycloakTextInput
isRequired
id="kc-kerberos-realm"
data-testid="kerberos-realm"
validated={
(form.formState.errors.config as any)?.kerberosRealm?.[0]
? "error"
: "default"
}
{...form.register("config.kerberosRealm.0", {
required: {
value: true,
message: t("validateRealm"),
},
})}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.serverPrincipal.0"
label={t("serverPrincipal")}
labelIcon={
<HelpItem
helpText={t("serverPrincipalHelp")}
fieldLabelId="serverPrincipal"
labelIcon={t("serverPrincipalHelp")}
rules={{
required: t("validateServerPrincipal"),
}}
/>
}
fieldId="kc-server-principal"
isRequired
validated={
(form.formState.errors.config as any)?.serverPrincipal?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.serverPrincipal?.[0].message
}
>
<KeycloakTextInput
isRequired
id="kc-server-principal"
data-testid="kerberos-principal"
validated={
(form.formState.errors.config as any)?.serverPrincipal?.[0]
? "error"
: "default"
}
{...form.register("config.serverPrincipal.0", {
required: {
value: true,
message: t("validateServerPrincipal"),
},
})}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.keyTab.0"
label={t("keyTab")}
labelIcon={
<HelpItem helpText={t("keyTabHelp")} fieldLabelId="keyTab" />
}
fieldId="kc-key-tab"
isRequired
validated={
(form.formState.errors.config as any)?.keyTab?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.keyTab?.[0].message
}
>
<KeycloakTextInput
isRequired
id="kc-key-tab"
data-testid="kerberos-keytab"
validated={
(form.formState.errors.config as any)?.keyTab?.[0]
? "error"
: "default"
}
{...form.register("config.keyTab.0", {
required: {
value: true,
message: t("validateKeyTab"),
},
})}
labelIcon={t("keyTabHelp")}
rules={{
required: t("validateKeyTab"),
}}
/>
</FormGroup>
<FormGroup
label={t("debug")}
labelIcon={
@ -222,7 +118,6 @@ export const KerberosSettingsRequired = ({
fieldId="kc-debug"
hasNoPaddingTop
>
{" "}
<Controller
name="config.debug"
defaultValue={["false"]}
@ -240,7 +135,6 @@ export const KerberosSettingsRequired = ({
)}
/>
</FormGroup>
<FormGroup
label={t("allowPasswordAuthentication")}
labelIcon={
@ -269,7 +163,6 @@ export const KerberosSettingsRequired = ({
)}
/>
</FormGroup>
{isEqual(allowPassAuth, ["true"]) ? (
<FormGroup
label={t("editMode")}
@ -282,7 +175,6 @@ export const KerberosSettingsRequired = ({
isRequired
fieldId="kc-edit-mode"
>
{" "}
<Controller
name="config.editMode[0]"
defaultValue="READ_ONLY"
@ -310,7 +202,6 @@ export const KerberosSettingsRequired = ({
></Controller>
</FormGroup>
) : null}
<FormGroup
label={t("updateFirstLogin")}
labelIcon={
@ -340,6 +231,6 @@ export const KerberosSettingsRequired = ({
/>
</FormGroup>
</FormAccess>
</>
</FormProvider>
);
};

View file

@ -11,14 +11,17 @@ import {
} from "@patternfly/react-core";
import { get, isEqual } from "lodash-es";
import { useState } from "react";
import { Controller, UseFormReturn, useWatch } from "react-hook-form";
import {
Controller,
FormProvider,
UseFormReturn,
useWatch,
} from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem } from "ui-shared";
import { HelpItem, TextControl } from "ui-shared";
import { adminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
import { PasswordInput } from "../../components/password-input/PasswordInput";
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
import { useRealm } from "../../context/realm-context/RealmContext";
@ -89,7 +92,7 @@ export const LdapSettingsConnection = ({
});
return (
<>
<FormProvider {...form}>
{showSectionHeading && (
<WizardSectionHeader
title={t("connectionAndAuthenticationSettings")}
@ -98,43 +101,15 @@ export const LdapSettingsConnection = ({
/>
)}
<FormAccess role="manage-realm" isHorizontal>
<FormGroup
<TextControl
name="config.connectionUrl.0"
label={t("connectionURL")}
labelIcon={
<HelpItem
helpText={t("consoleDisplayConnectionUrlHelp")}
fieldLabelId="connectionURL"
/>
}
fieldId="kc-ui-connection-url"
isRequired
validated={
(form.formState.errors.config as any)?.connectionUrl?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.connectionUrl?.[0].message
}
>
<KeycloakTextInput
isRequired
labelIcon={t("consoleDisplayConnectionUrlHelp")}
type="url"
id="kc-ui-connection-url"
data-testid="ldap-connection-url"
validated={
(form.formState.errors.config as any)?.connectionUrl?.[0]
? "error"
: "default"
}
{...form.register("config.connectionUrl.0", {
required: {
value: true,
message: t("validateConnectionUrl").toString(),
},
})}
rules={{
required: t("validateConnectionUrl"),
}}
/>
</FormGroup>
<FormGroup
label={t("enableStartTls")}
labelIcon={
@ -162,9 +137,8 @@ export const LdapSettingsConnection = ({
aria-label={t("enableStartTls")}
/>
)}
></Controller>
/>
</FormGroup>
<FormGroup
label={t("useTruststoreSpi")}
labelIcon={
@ -196,7 +170,7 @@ export const LdapSettingsConnection = ({
<SelectOption value="never">{t("never")}</SelectOption>
</Select>
)}
></Controller>
/>
</FormGroup>
<FormGroup
label={t("connectionPooling")}
@ -225,26 +199,15 @@ export const LdapSettingsConnection = ({
aria-label={t("connectionPooling")}
/>
)}
></Controller>
</FormGroup>
<FormGroup
label={t("connectionTimeout")}
labelIcon={
<HelpItem
helpText={t("connectionTimeoutHelp")}
fieldLabelId="consoleTimeout"
/>
}
fieldId="kc-ui-connection-timeout"
>
<KeycloakTextInput
</FormGroup>
<TextControl
name="config.connectionTimeout.0"
label={t("connectionTimeout")}
labelIcon={t("connectionTimeoutHelp")}
type="number"
min={0}
id="kc-ui-connection-timeout"
data-testid="connection-timeout"
{...form.register("config.connectionTimeout.0")}
/>
</FormGroup>
<FormGroup fieldId="kc-test-connection-button">
<Button
variant="secondary"
@ -288,37 +251,19 @@ export const LdapSettingsConnection = ({
<SelectOption value="none" />
</Select>
)}
></Controller>
/>
</FormGroup>
{isEqual(ldapBindType, ["simple"]) && (
<>
<FormGroup
<TextControl
name="config.bindDn.0"
label={t("bindDn")}
labelIcon={
<HelpItem helpText={t("bindDnHelp")} fieldLabelId="bindDn" />
}
fieldId="kc-ui-bind-dn"
helperTextInvalid={t("validateBindDn")}
validated={
(form.formState.errors.config as any)?.bindDn
? ValidatedOptions.error
: ValidatedOptions.default
}
isRequired
>
<KeycloakTextInput
type="text"
id="kc-ui-bind-dn"
data-testid="ldap-bind-dn"
validated={
(form.formState.errors.config as any)?.bindDn
? ValidatedOptions.error
: ValidatedOptions.default
}
{...form.register("config.bindDn.0", { required: true })}
labelIcon={t("bindDnHelp")}
rules={{
required: t("validateBindDn"),
}}
/>
</FormGroup>
<FormGroup
label={t("bindCredentials")}
labelIcon={
@ -364,6 +309,6 @@ export const LdapSettingsConnection = ({
</Button>
</FormGroup>
</FormAccess>
</>
</FormProvider>
);
};

View file

@ -6,9 +6,9 @@ import {
SelectVariant,
} from "@patternfly/react-core";
import { useState } from "react";
import { Controller, UseFormReturn } from "react-hook-form";
import { Controller, FormProvider, UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem } from "ui-shared";
import { HelpItem, TextControl } from "ui-shared";
import { adminClient } from "../../admin-client";
import { FormAccess } from "../../components/form/FormAccess";
@ -98,7 +98,7 @@ export const LdapSettingsGeneral = ({
};
return (
<>
<FormProvider {...form}>
{showSectionHeading && (
<WizardSectionHeader
title={t("generalOptions")}
@ -107,52 +107,31 @@ export const LdapSettingsGeneral = ({
/>
)}
<FormAccess role="manage-realm" isHorizontal>
<FormGroup
label={t("uiDisplayName")}
labelIcon={
<HelpItem
helpText={t("uiDisplayNameHelp")}
fieldLabelId="uiDisplayName"
/>
}
fieldId="kc-ui-display-name"
isRequired
validated={form.formState.errors.name ? "error" : "default"}
helperTextInvalid={form.formState.errors.name?.message}
>
{/* These hidden fields are required so data object written back matches data retrieved */}
<KeycloakTextInput
hidden
id="kc-ui-provider-id"
defaultValue="ldap"
{...form.register("providerId")}
/>
<KeycloakTextInput
hidden
id="kc-ui-provider-type"
defaultValue="org.keycloak.storage.UserStorageProvider"
{...form.register("providerType")}
/>
<KeycloakTextInput
hidden
id="kc-ui-parentId"
defaultValue={realm}
{...form.register("parentId")}
/>
<KeycloakTextInput
isRequired
id="kc-ui-display-name"
<TextControl
name="name"
label={t("uiDisplayName")}
labelIcon={t("uiDisplayNameHelp")}
defaultValue="ldap"
data-testid="ldap-name"
validated={form.formState.errors.name ? "error" : "default"}
{...form.register("name", {
required: {
value: true,
message: `${t("validateName")}`,
},
})}
rules={{
required: t("validateName"),
}}
/>
</FormGroup>
<FormGroup
label={t("vendor")}
labelIcon={
@ -201,6 +180,6 @@ export const LdapSettingsGeneral = ({
></Controller>
</FormGroup>
</FormAccess>
</>
</FormProvider>
);
};

View file

@ -1,10 +1,13 @@
import { FormGroup, Switch } from "@patternfly/react-core";
import { Controller, UseFormReturn, useWatch } from "react-hook-form";
import {
Controller,
FormProvider,
UseFormReturn,
useWatch,
} from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem, TextControl } from "ui-shared";
import { FormAccess } from "../../components/form/FormAccess";
import { HelpItem } from "ui-shared";
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
export type LdapSettingsKerberosIntegrationProps = {
@ -27,7 +30,7 @@ export const LdapSettingsKerberosIntegration = ({
});
return (
<>
<FormProvider {...form}>
{showSectionHeading && (
<WizardSectionHeader
title={t("kerberosIntegration")}
@ -69,148 +72,35 @@ export const LdapSettingsKerberosIntegration = ({
{allowKerberosAuth[0] === "true" && (
<>
<FormGroup
<TextControl
name="config.kerberosRealm.0"
label={t("kerberosRealm")}
labelIcon={
<HelpItem
helpText={t("kerberosRealmHelp")}
fieldLabelId="kerberosRealm"
labelIcon={t("kerberosRealmHelp")}
rules={{
required: t("validateRealm"),
}}
/>
}
fieldId="kc-kerberos-realm"
isRequired
validated={
(form.formState.errors.config as any)?.kerberosRealm?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.kerberosRealm?.[0]
.message
}
>
<KeycloakTextInput
isRequired
id="kc-kerberos-realm"
data-testid="kerberos-realm"
validated={
(form.formState.errors.config as any)?.kerberosRealm?.[0]
? "error"
: "default"
}
{...form.register("config.kerberosRealm.0", {
required: {
value: true,
message: t("validateRealm").toString(),
},
})}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.serverPrincipal.0"
label={t("serverPrincipal")}
labelIcon={
<HelpItem
helpText={t("serverPrincipalHelp")}
fieldLabelId="serverPrincipal"
labelIcon={t("serverPrincipalHelp")}
rules={{
required: t("validateServerPrincipal"),
}}
/>
}
fieldId="kc-server-principal"
isRequired
validated={
(form.formState.errors.config as any)?.serverPrincipal?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.serverPrincipal?.[0]
.message
}
>
<KeycloakTextInput
isRequired
id="kc-server-principal"
data-testid="kerberos-principal"
validated={
(form.formState.errors.config as any)?.serverPrincipal?.[0]
? "error"
: "default"
}
{...form.register("config.serverPrincipal.0", {
required: {
value: true,
message: `${t("validateServerPrincipal")}`,
},
})}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.keyTab.0"
label={t("keyTab")}
labelIcon={
<HelpItem helpText={t("keyTabHelp")} fieldLabelId="keyTab" />
}
fieldId="kc-key-tab"
isRequired
validated={
(form.formState.errors.config as any)?.keyTab?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.keyTab?.[0].message
}
>
<KeycloakTextInput
isRequired
id="kc-key-tab"
data-testid="kerberos-keytab"
validated={
(form.formState.errors.config as any)?.keyTab?.[0]
? "error"
: "default"
}
{...form.register("config.keyTab.0", {
required: {
value: true,
message: `${t("validateKeyTab")}`,
},
})}
labelIcon={t("keyTabHelp")}
rules={{
required: t("validateKeyTab"),
}}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.krbPrincipalAttribute.0"
label={t("krbPrincipalAttribute")}
labelIcon={
<HelpItem
helpText={t("krbPrincipalAttributeHelp")}
fieldLabelId="krbPrincipalAttribute"
labelIcon={t("krbPrincipalAttributeHelp")}
/>
}
fieldId="kc-krb-principal-attribute"
validated={
(form.formState.errors.config as any)
?.krbPrincipalAttribute?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)
?.krbPrincipalAttribute?.[0].message
}
>
<KeycloakTextInput
id="kc-krb-principal-attribute"
data-testid="krb-principal-attribute"
validated={
(form.formState.errors.config as any)
?.krbPrincipalAttribute?.[0]
? "error"
: "default"
}
{...form.register("config.krbPrincipalAttribute.0")}
/>
</FormGroup>
<FormGroup
label={t("debug")}
@ -220,7 +110,6 @@ export const LdapSettingsKerberosIntegration = ({
fieldId="kc-debug"
hasNoPaddingTop
>
{" "}
<Controller
name="config.debug"
defaultValue={["false"]}
@ -237,7 +126,7 @@ export const LdapSettingsKerberosIntegration = ({
aria-label={t("debug")}
/>
)}
></Controller>
/>
</FormGroup>
</>
)}
@ -271,6 +160,6 @@ export const LdapSettingsKerberosIntegration = ({
></Controller>
</FormGroup>
</FormAccess>
</>
</FormProvider>
);
};

View file

@ -6,12 +6,10 @@ import {
Switch,
} from "@patternfly/react-core";
import { useState } from "react";
import { Controller, UseFormReturn } from "react-hook-form";
import { Controller, FormProvider, UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem, TextControl } from "ui-shared";
import { FormAccess } from "../../components/form/FormAccess";
import { HelpItem } from "ui-shared";
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
export type LdapSettingsSearchingProps = {
@ -33,7 +31,7 @@ export const LdapSettingsSearching = ({
const [isReferralDropdownOpen, setIsReferralDropdownOpen] = useState(false);
return (
<>
<FormProvider {...form}>
{showSectionHeading && (
<WizardSectionHeader
title={t("ldapSearchingAndUpdatingSettings")}
@ -111,227 +109,61 @@ export const LdapSettingsSearching = ({
)}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.usersDn.0"
label={t("usersDN")}
labelIcon={
<HelpItem helpText={t("usersDNHelp")} fieldLabelId="usersDn" />
}
fieldId="kc-ui-users-dn"
isRequired
validated={
(form.formState.errors.config as any)?.usersDn?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.usersDn?.[0].message
}
>
<KeycloakTextInput
isRequired
defaultValue=""
id="kc-ui-users-dn"
data-testid="ldap-users-dn"
validated={
(form.formState.errors.config as any)?.usersDn?.[0]
? "error"
: "default"
}
{...form.register("config.usersDn.0", {
required: {
value: true,
message: t("validateUsersDn").toString(),
},
})}
labelIcon={t("usersDNHelp")}
rules={{
required: t("validateUsersDn"),
}}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.usernameLDAPAttribute.0"
label={t("usernameLdapAttribute")}
labelIcon={
<HelpItem
helpText={t("usernameLdapAttributeHelp")}
fieldLabelId="usernameLdapAttribute"
/>
}
fieldId="kc-username-ldap-attribute"
isRequired
validated={
(form.formState.errors.config as any)?.usernameLDAPAttribute?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.usernameLDAPAttribute?.[0]
.message
}
>
<KeycloakTextInput
isRequired
labelIcon={t("usernameLdapAttributeHelp")}
defaultValue="cn"
id="kc-username-ldap-attribute"
data-testid="ldap-username-attribute"
validated={
(form.formState.errors.config as any)?.usernameLDAPAttribute?.[0]
? "error"
: "default"
}
{...form.register("config.usernameLDAPAttribute.0", {
required: {
value: true,
message: `${t("validateUsernameLDAPAttribute")}`,
},
})}
rules={{
required: t("validateUsernameLDAPAttribute"),
}}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.rdnLDAPAttribute.0"
label={t("rdnLdapAttribute")}
labelIcon={
<HelpItem
helpText={t("rdnLdapAttributeHelp")}
fieldLabelId="rdnLdapAttribute"
/>
}
fieldId="kc-rdn-ldap-attribute"
isRequired
validated={
(form.formState.errors.config as any)?.rdnLDAPAttribute?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.rdnLDAPAttribute?.[0].message
}
>
<KeycloakTextInput
isRequired
labelIcon={t("rdnLdapAttributeHelp")}
defaultValue="cn"
id="kc-rdn-ldap-attribute"
data-testid="ldap-rdn-attribute"
validated={
(form.formState.errors.config as any)?.rdnLDAPAttribute?.[0]
? "error"
: "default"
}
{...form.register("config.rdnLDAPAttribute.0", {
required: {
value: true,
message: `${t("validateRdnLdapAttribute")}`,
},
})}
rules={{
required: t("validateRdnLdapAttribute"),
}}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.uuidLDAPAttribute.0"
label={t("uuidLdapAttribute")}
labelIcon={
<HelpItem
helpText={t("uuidLdapAttributeHelp")}
fieldLabelId="uuidLdapAttribute"
/>
}
fieldId="kc-uuid-ldap-attribute"
isRequired
validated={
(form.formState.errors.config as any)?.uuidLDAPAttribute?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.uuidLDAPAttribute?.[0]
.message
}
>
<KeycloakTextInput
isRequired
labelIcon={t("uuidLdapAttributeHelp")}
defaultValue="objectGUID"
id="kc-uuid-ldap-attribute"
data-testid="ldap-uuid-attribute"
validated={
(form.formState.errors.config as any)?.uuidLDAPAttribute?.[0]
? "error"
: "default"
}
{...form.register("config.uuidLDAPAttribute.0", {
required: {
value: true,
message: `${t("validateUuidLDAPAttribute")}`,
},
})}
rules={{
required: t("validateUuidLDAPAttribute"),
}}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.userObjectClasses.0"
label={t("userObjectClasses")}
labelIcon={
<HelpItem
helpText={t("userObjectClassesHelp")}
fieldLabelId="userObjectClasses"
/>
}
fieldId="kc-user-object-classes"
isRequired
validated={
(form.formState.errors.config as any)?.userObjectClasses?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.userObjectClasses?.[0]
.message
}
>
<KeycloakTextInput
isRequired
labelIcon={t("userObjectClassesHelp")}
defaultValue="person, organizationalPerson, user"
id="kc-user-object-classes"
data-testid="ldap-user-object-classes"
validated={
(form.formState.errors.config as any)?.userObjectClasses?.[0]
? "error"
: "default"
}
{...form.register("config.userObjectClasses.0", {
required: {
value: true,
message: t("validateUserObjectClasses").toString(),
},
})}
rules={{
required: t("validateUserObjectClasses"),
}}
/>
</FormGroup>
<FormGroup
<TextControl
name="config.customUserSearchFilter.0"
label={t("userLdapFilter")}
labelIcon={
<HelpItem
helpText={t("userLdapFilterHelp")}
fieldLabelId="userLdapFilter"
/>
}
fieldId="kc-user-ldap-filter"
validated={
(form.formState.errors.config as any)?.customUserSearchFilter?.[0]
? "error"
: "default"
}
helperTextInvalid={
(form.formState.errors.config as any)?.customUserSearchFilter?.[0]
.message
}
>
<KeycloakTextInput
id="kc-user-ldap-filter"
data-testid="user-ldap-filter"
validated={
(form.formState.errors.config as any)?.customUserSearchFilter?.[0]
? "error"
: "default"
}
{...form.register("config.customUserSearchFilter.0", {
labelIcon={t("userLdapFilterHelp")}
rules={{
pattern: {
value: /(\(.*\))$/,
message: t("validateCustomUserSearchFilter").toString(),
message: t("validateCustomUserSearchFilter"),
},
})}
}}
/>
</FormGroup>
<FormGroup
label={t("searchScope")}
labelIcon={
@ -369,26 +201,15 @@ export const LdapSettingsSearching = ({
</SelectOption>
</Select>
)}
></Controller>
</FormGroup>
<FormGroup
label={t("readTimeout")}
labelIcon={
<HelpItem
helpText={t("readTimeoutHelp")}
fieldLabelId="readTimeout"
/>
}
fieldId="kc-read-timeout"
>
<KeycloakTextInput
</FormGroup>
<TextControl
name="config.readTimeout.0"
label={t("readTimeout")}
labelIcon={t("readTimeoutHelp")}
type="number"
min={0}
id="kc-read-timeout"
data-testid="ldap-read-timeout"
{...form.register("config.readTimeout.0")}
/>
</FormGroup>
<FormGroup
label={t("pagination")}
labelIcon={
@ -450,6 +271,6 @@ export const LdapSettingsSearching = ({
></Controller>
</FormGroup>
</FormAccess>
</>
</FormProvider>
);
};

View file

@ -1,10 +1,8 @@
import { FormGroup, Switch } from "@patternfly/react-core";
import { Controller, UseFormReturn } from "react-hook-form";
import { Controller, FormProvider, UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem, TextControl } from "ui-shared";
import { FormAccess } from "../../components/form/FormAccess";
import { HelpItem } from "ui-shared";
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
export type LdapSettingsSynchronizationProps = {
@ -24,7 +22,7 @@ export const LdapSettingsSynchronization = ({
const watchChangedSync = form.watch("config.periodicChangedUsersSync", false);
return (
<>
<FormProvider {...form}>
{showSectionHeading && (
<WizardSectionHeader
title={t("synchronizationSettings")}
@ -32,6 +30,7 @@ export const LdapSettingsSynchronization = ({
showDescription={showSectionDescription}
/>
)}
<FormAccess role="manage-realm" isHorizontal>
<FormGroup
hasNoPaddingTop
@ -91,21 +90,13 @@ export const LdapSettingsSynchronization = ({
)}
/>
</FormGroup>
<FormGroup
label={t("batchSize")}
labelIcon={
<HelpItem helpText={t("batchSizeHelp")} fieldLabelId="batchSize" />
}
fieldId="kc-batch-size"
>
<KeycloakTextInput
<TextControl
name="config.batchSizeForSync.0"
type="number"
min={0}
id="kc-batch-size"
data-testid="batch-size"
{...form.register("config.batchSizeForSync.0")}
label={t("batchSize")}
labelIcon={t("batchSizeHelp")}
/>
</FormGroup>
<FormGroup
label={t("periodicFullSync")}
labelIcon={
@ -133,29 +124,17 @@ export const LdapSettingsSynchronization = ({
aria-label={t("periodicFullSync")}
/>
)}
></Controller>
/>
</FormGroup>
{watchPeriodicSync && (
<FormGroup
hasNoPaddingTop
<TextControl
name="config.fullSyncPeriod.0"
label={t("fullSyncPeriod")}
labelIcon={
<HelpItem
helpText={t("fullSyncPeriodHelp")}
fieldLabelId="fullSyncPeriod"
/>
}
fieldId="kc-full-sync-period"
>
<KeycloakTextInput
labelIcon={t("fullSyncPeriodHelp")}
type="number"
min={-1}
defaultValue={604800}
id="kc-full-sync-period"
data-testid="full-sync-period"
{...form.register("config.fullSyncPeriod.0")}
/>
</FormGroup>
)}
<FormGroup
label={t("periodicChangedUsersSync")}
@ -184,31 +163,19 @@ export const LdapSettingsSynchronization = ({
aria-label={t("periodicChangedUsersSync")}
/>
)}
></Controller>
/>
</FormGroup>
{watchChangedSync && (
<FormGroup
<TextControl
name="config.changedSyncPeriod.0"
label={t("changedUsersSyncPeriod")}
labelIcon={
<HelpItem
helpText={t("changedUsersSyncHelp")}
fieldLabelId="changedUsersSyncPeriod"
/>
}
fieldId="kc-changed-users-sync-period"
hasNoPaddingTop
>
<KeycloakTextInput
labelIcon={t("changedUsersSyncHelp")}
type="number"
min={-1}
defaultValue={86400}
id="kc-changed-users-sync-period"
data-testid="changed-users-sync-period"
{...form.register("config.changedSyncPeriod.0")}
/>
</FormGroup>
)}
</FormAccess>
</>
</FormProvider>
);
};

View file

@ -7,20 +7,17 @@ import {
Button,
ButtonVariant,
DropdownItem,
Form,
FormGroup,
PageSection,
Select,
SelectOption,
SelectVariant,
ValidatedOptions,
} from "@patternfly/react-core";
import { useState } from "react";
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { HelpItem } from "ui-shared";
import { HelpItem, TextControl } from "ui-shared";
import { adminClient } from "../../../admin-client";
import { useAlerts } from "../../../components/alert/Alerts";
import { useConfirmDialog } from "../../../components/confirm-dialog/ConfirmDialog";
@ -208,74 +205,42 @@ export default function LdapMapperDetails() {
}
/>
<PageSection variant="light" isFilled>
<FormAccess role="manage-realm" isHorizontal>
{!isNew && (
<FormGroup label={t("id")} fieldId="kc-ldap-mapper-id">
<KeycloakTextInput
isDisabled
id="kc-ldap-mapper-id"
data-testid="ldap-mapper-id"
{...form.register("id")}
/>
</FormGroup>
)}
<FormGroup
label={t("name")}
labelIcon={
<HelpItem helpText={t("nameHelp")} fieldLabelId="name" />
}
fieldId="kc-ldap-mapper-name"
isRequired
<FormProvider {...form}>
<FormAccess
role="manage-realm"
isHorizontal
onSubmit={form.handleSubmit(() => save(form.getValues()))}
>
<KeycloakTextInput
{!isNew && <TextControl name="id" label={t("id")} isDisabled />}
<TextControl
name="name"
label={t("name")}
labelIcon={t("nameHelp")}
isDisabled={!isNew}
isRequired
id="kc-ldap-mapper-name"
data-testid="ldap-mapper-name"
validated={
form.formState.errors.name
? ValidatedOptions.error
: ValidatedOptions.default
}
{...form.register("name", { required: true })}
rules={{ required: t("required") }}
/>
<KeycloakTextInput
hidden
defaultValue={isNew ? id : mapping ? mapping.parentId : ""}
id="kc-ldap-parentId"
data-testid="ldap-mapper-parentId"
{...form.register("parentId")}
/>
<KeycloakTextInput
hidden
defaultValue="org.keycloak.storage.ldap.mappers.LDAPStorageMapper"
id="kc-ldap-provider-type"
data-testid="ldap-mapper-provider-type"
{...form.register("providerType")}
/>
</FormGroup>
{!isNew ? (
<FormGroup
<TextControl
name="providerId"
label={t("mapperType")}
labelIcon={
<HelpItem
helpText={
mapper?.helpText ? mapper.helpText : t("mapperTypeHelp")
}
fieldLabelId="mapperType"
/>
}
fieldId="kc-ldap-mapper-type"
isRequired
>
<KeycloakTextInput
rules={{ required: t("required") }}
isDisabled={!isNew}
isRequired
id="kc-ldap-mapper-type"
data-testid="ldap-mapper-type-fld"
{...form.register("providerId")}
/>
</FormGroup>
) : (
<FormGroup
label={t("mapperType")}
@ -331,14 +296,10 @@ export default function LdapMapperDetails() {
></Controller>
</FormGroup>
)}
<FormProvider {...form}>
{!!mapperType && (
<DynamicComponents properties={mapper?.properties!} />
)}
</FormProvider>
</FormAccess>
<Form onSubmit={form.handleSubmit(() => save(form.getValues()))}>
<ActionGroup>
<Button
isDisabled={!form.formState.isDirty}
@ -364,7 +325,8 @@ export default function LdapMapperDetails() {
{t("cancel")}
</Button>
</ActionGroup>
</Form>
</FormAccess>
</FormProvider>
</PageSection>
</>
);