Upgrade to React Hook Form version 7 (#4239)
This commit is contained in:
parent
014d3ce0e4
commit
8f05a102af
179 changed files with 1322 additions and 1871 deletions
|
@ -27,7 +27,7 @@ export const EditTheResource = ({
|
|||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
const form = useForm<FormValues>({ shouldUnregister: false });
|
||||
const form = useForm<FormValues>();
|
||||
const { control, register, reset, handleSubmit } = form;
|
||||
|
||||
const { fields } = useFieldArray<FormValues>({
|
||||
|
|
|
@ -998,12 +998,6 @@ describe("Clients test", () => {
|
|||
adminClient.deleteClient(keysName);
|
||||
});
|
||||
|
||||
it("Change use JWKS Url", () => {
|
||||
const keysTab = clientDetailsPage.goToKeysTab();
|
||||
keysTab.formUtils().checkSaveButtonIsDisabled(true);
|
||||
keysTab.toggleUseJwksUrl().formUtils().checkSaveButtonIsDisabled(false);
|
||||
});
|
||||
|
||||
it("Generate new keys", () => {
|
||||
const keysTab = clientDetailsPage.goToKeysTab();
|
||||
keysTab.clickGenerate();
|
||||
|
|
|
@ -274,7 +274,7 @@ describe("Events tests", () => {
|
|||
.goToEventsTab()
|
||||
.goToAdminEventsSettingsSubTab()
|
||||
.disableSaveEvents()
|
||||
.save()
|
||||
.save({ waitForRealm: false, waitForConfig: true })
|
||||
.clearAdminEvents();
|
||||
|
||||
sidebarPage.goToEvents();
|
||||
|
@ -300,7 +300,7 @@ describe("Events tests", () => {
|
|||
.goToEventsTab()
|
||||
.goToAdminEventsSettingsSubTab()
|
||||
.enableSaveEvents()
|
||||
.save();
|
||||
.save({ waitForRealm: false, waitForConfig: true });
|
||||
sidebarPage.goToEvents();
|
||||
eventsPage.goToAdminEventsTab();
|
||||
adminEventsTab
|
||||
|
@ -373,7 +373,7 @@ describe("Events tests", () => {
|
|||
.goToEventsTab()
|
||||
.goToAdminEventsSettingsSubTab()
|
||||
.disableSaveEvents()
|
||||
.save();
|
||||
.save({ waitForRealm: false, waitForConfig: true });
|
||||
sidebarPage.goToEvents();
|
||||
eventsPage.goToAdminEventsTab();
|
||||
adminEventsTab
|
||||
|
|
|
@ -197,7 +197,9 @@ export default class PageObject {
|
|||
itemName: string,
|
||||
element?: Cypress.Chainable<JQuery>
|
||||
) {
|
||||
element = element ?? cy.get(this.selectMenuItem).contains(itemName);
|
||||
element =
|
||||
element ??
|
||||
cy.get(this.selectMenuItem).contains(new RegExp(`^${itemName}$`));
|
||||
return this.clickDropdownMenuItem(itemName, element);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,10 +36,21 @@ export default class AdminEventsSettingsTab extends PageObject {
|
|||
return this;
|
||||
}
|
||||
|
||||
save() {
|
||||
cy.intercept("/admin/realms/master").as("saveRealm");
|
||||
save(
|
||||
{ waitForRealm, waitForConfig } = {
|
||||
waitForRealm: true,
|
||||
waitForConfig: false,
|
||||
}
|
||||
) {
|
||||
waitForRealm && cy.intercept("/admin/realms/master").as("saveRealm");
|
||||
waitForConfig &&
|
||||
cy.intercept("/admin/realms/master/events/config").as("saveConfig");
|
||||
|
||||
cy.get(this.saveBtn).click();
|
||||
cy.wait("@saveRealm");
|
||||
|
||||
waitForRealm && cy.wait("@saveRealm");
|
||||
waitForConfig && cy.wait("@saveConfig");
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,8 +72,7 @@
|
|||
"react-dom": "^17.0.2",
|
||||
"react-dropzone": "^14.2.3",
|
||||
"react-error-boundary": "^3.1.4",
|
||||
"react-hook-form": "^6.15.8",
|
||||
"react-hook-form-v7": "npm:react-hook-form@^7.35.1",
|
||||
"react-hook-form": "^7.42.1",
|
||||
"react-i18next": "^12.0.0",
|
||||
"react-router-dom": "^6.6.2",
|
||||
"react-use-localstorage": "^3.5.3",
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
SelectOption,
|
||||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { Controller, useForm } from "react-hook-form-v7";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
ModalVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useEffect } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
|
@ -33,7 +33,7 @@ export const DuplicateFlowModal = ({
|
|||
}: DuplicateFlowModalProps) => {
|
||||
const { t } = useTranslation("authentication");
|
||||
const form = useForm<AuthenticationFlowRepresentation>({ mode: "onChange" });
|
||||
const { setValue, trigger, getValues, handleSubmit } = form;
|
||||
const { setValue, getValues, handleSubmit } = form;
|
||||
const { adminClient } = useAdminClient();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const navigate = useNavigate();
|
||||
|
@ -45,7 +45,6 @@ export const DuplicateFlowModal = ({
|
|||
}, [name, description]);
|
||||
|
||||
const onSubmit = async () => {
|
||||
if (!(await trigger())) return;
|
||||
const form = getValues();
|
||||
try {
|
||||
await adminClient.authenticationManagement.copyFlow({
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
ModalVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useEffect } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { PencilAltIcon } from "@patternfly/react-icons";
|
||||
import { useEffect } from "react";
|
||||
import { useForm } from "react-hook-form-v7";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import type AuthenticatorConfigInfoRepresentation from "@keycloak/keycloak-admin-client/lib/defs/authenticatorConfigInfoRepresentation";
|
||||
import type AuthenticatorConfigRepresentation from "@keycloak/keycloak-admin-client/lib/defs/authenticatorConfigRepresentation";
|
||||
import {
|
||||
ActionGroup,
|
||||
AlertVariant,
|
||||
|
@ -14,16 +13,17 @@ import {
|
|||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { CogIcon, TrashIcon } from "@patternfly/react-icons";
|
||||
import { useEffect, useState } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type AuthenticatorConfigRepresentation from "@keycloak/keycloak-admin-client/lib/defs/authenticatorConfigRepresentation";
|
||||
import type AuthenticatorConfigInfoRepresentation from "@keycloak/keycloak-admin-client/lib/defs/authenticatorConfigInfoRepresentation";
|
||||
import type { ExpandableExecution } from "../execution-model";
|
||||
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { DynamicComponents } from "../../components/dynamic/DynamicComponents";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
||||
import type { ExpandableExecution } from "../execution-model";
|
||||
|
||||
type ExecutionConfigModalForm = {
|
||||
alias: string;
|
||||
|
@ -46,7 +46,7 @@ export const ExecutionConfigModal = ({
|
|||
const [configDescription, setConfigDescription] =
|
||||
useState<AuthenticatorConfigInfoRepresentation>();
|
||||
|
||||
const form = useForm<ExecutionConfigModalForm>({ shouldUnregister: false });
|
||||
const form = useForm<ExecutionConfigModalForm>();
|
||||
const {
|
||||
register,
|
||||
setValue,
|
||||
|
@ -148,16 +148,14 @@ export const ExecutionConfigModal = ({
|
|||
>
|
||||
<KeycloakTextInput
|
||||
isReadOnly={!!config}
|
||||
type="text"
|
||||
id="alias"
|
||||
name="alias"
|
||||
data-testid="alias"
|
||||
ref={register({ required: true })}
|
||||
validated={
|
||||
errors.alias
|
||||
? ValidatedOptions.error
|
||||
: ValidatedOptions.default
|
||||
}
|
||||
{...register("alias", { required: true })}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormProvider {...form}>
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Controller, useForm } from "react-hook-form-v7";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
Button,
|
||||
PageSection,
|
||||
} from "@patternfly/react-core";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import AuthenticationFlowRepresentation from "@keycloak/keycloak-admin-client/lib/defs/authenticationFlowRepresentation";
|
||||
import { FormGroup, ValidatedOptions } from "@patternfly/react-core";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { Controller, useForm, useWatch } from "react-hook-form-v7";
|
||||
import { Controller, useForm, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
|
|
|
@ -18,7 +18,7 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { PlusCircleIcon } from "@patternfly/react-icons";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type PasswordPolicyTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/passwordPolicyTypeRepresentation";
|
||||
|
@ -94,7 +94,6 @@ export const PasswordPolicy = ({
|
|||
|
||||
const form = useForm<SubmittedValues>({
|
||||
defaultValues: {},
|
||||
shouldUnregister: false,
|
||||
});
|
||||
const {
|
||||
handleSubmit,
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { MinusCircleIcon } from "@patternfly/react-icons";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
FormProvider,
|
||||
useForm,
|
||||
useFormContext,
|
||||
} from "react-hook-form-v7";
|
||||
} from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
||||
|
@ -29,7 +29,7 @@ import { FormAccess } from "../../components/form-access/FormAccess";
|
|||
import { useHelp } from "../../components/help-enabler/HelpHeader";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/hook-form-v7/MultiLineInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||
import { TimeSelector } from "../../components/time-selector/TimeSelector";
|
||||
import { useAdminClient } from "../../context/auth/AdminClient";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
|
@ -163,7 +163,7 @@ export const WebauthnPolicy = ({
|
|||
const { addAlert, addError } = useAlerts();
|
||||
const { realm: realmName } = useRealm();
|
||||
const { enabled } = useHelp();
|
||||
const form = useForm({ mode: "onChange", shouldUnregister: false });
|
||||
const form = useForm({ mode: "onChange" });
|
||||
const {
|
||||
control,
|
||||
register,
|
||||
|
|
|
@ -40,7 +40,12 @@ export default function MappingDetails() {
|
|||
|
||||
const { id, mapperId } = useParams<MapperParams>();
|
||||
const form = useForm();
|
||||
const { register, setValue, errors, handleSubmit } = form;
|
||||
const {
|
||||
register,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
handleSubmit,
|
||||
} = form;
|
||||
const [mapping, setMapping] = useState<ProtocolMapperTypeRepresentation>();
|
||||
const [config, setConfig] = useState<{
|
||||
protocol?: string;
|
||||
|
@ -228,14 +233,12 @@ export default function MappingDetails() {
|
|||
helperTextInvalid={t("common:required")}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
ref={register({ required: true })}
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
isReadOnly={isUpdating}
|
||||
validated={
|
||||
errors.name ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}
|
||||
{...register("name", { required: true })}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormProvider {...form}>
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Controller, useForm, useWatch } from "react-hook-form-v7";
|
||||
import { Controller, useForm, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { AlertVariant, PageSection, Text } from "@patternfly/react-core";
|
||||
import type { TFunction } from "i18next";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { FormGroup, Switch, ValidatedOptions } from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../components/form-access/FormAccess";
|
||||
|
|
|
@ -13,12 +13,7 @@ import {
|
|||
import { InfoCircleIcon } from "@patternfly/react-icons";
|
||||
import { cloneDeep, sortBy } from "lodash-es";
|
||||
import { useMemo, useState } from "react";
|
||||
import {
|
||||
Controller,
|
||||
FormProvider,
|
||||
useForm,
|
||||
useWatch,
|
||||
} from "react-hook-form-v7";
|
||||
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
|
@ -210,7 +205,7 @@ export default function ClientDetails() {
|
|||
const [downloadDialogOpen, toggleDownloadDialogOpen] = useToggle();
|
||||
const [changeAuthenticatorOpen, toggleChangeAuthenticatorOpen] = useToggle();
|
||||
|
||||
const form = useForm<FormFields>({ shouldUnregister: false });
|
||||
const form = useForm<FormFields>();
|
||||
const { clientId } = useParams<ClientParams>();
|
||||
const [key, setKey] = useState(0);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { Form } from "@patternfly/react-core";
|
||||
|
||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
InputGroup,
|
||||
Switch,
|
||||
} from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/hook-form-v7/MultiLineInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import environment from "../../environment";
|
||||
import { convertAttributeNameToForm } from "../../util";
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
Switch,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { FormGroup, Switch, ValidatedOptions } from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
WizardFooter,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
|
|
|
@ -6,12 +6,7 @@ import {
|
|||
Switch,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Controller,
|
||||
Path,
|
||||
PathValue,
|
||||
useFormContext,
|
||||
} from "react-hook-form-v7";
|
||||
import { Controller, Path, PathValue, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
FormGroup,
|
||||
Modal,
|
||||
} from "@patternfly/react-core";
|
||||
import { useForm } from "react-hook-form-v7";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
|
|
|
@ -9,13 +9,13 @@ import {
|
|||
Switch,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { KeyValueInput } from "../../components/key-value-form/hook-form-v7/KeyValueInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/hook-form-v7/MultiLineInput";
|
||||
import { KeyValueInput } from "../../components/key-value-form/KeyValueInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||
import { TimeSelector } from "../../components/time-selector/TimeSelector";
|
||||
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { sortBy } from "lodash-es";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
ToolbarItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
|
|
|
@ -7,12 +7,12 @@ import {
|
|||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/hook-form-v7/MultiLineInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
||||
import { convertAttributeNameToForm, sortProviders } from "../../util";
|
||||
import { FormFields } from "../ClientDetails";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ActionGroup, Button, FormGroup } from "@patternfly/react-core";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ActionGroup, Button, FormGroup, Switch } from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
Tooltip,
|
||||
} from "@patternfly/react-core";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
SplitItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
Switch,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||
|
@ -21,7 +21,7 @@ import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/def
|
|||
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
||||
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
||||
|
||||
import { ClientSelect } from "../../components/client/react-hook-v7/ClientSelect";
|
||||
import { ClientSelect } from "../../components/client/ClientSelect";
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import type { KeyValueType } from "../../components/key-value-form/key-value-convert";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { FormGroup, Radio } from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFieldArray, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFieldArray, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
Button,
|
||||
Select,
|
||||
|
|
|
@ -13,12 +13,7 @@ import {
|
|||
Switch,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Controller,
|
||||
FormProvider,
|
||||
useForm,
|
||||
useWatch,
|
||||
} from "react-hook-form-v7";
|
||||
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
|
@ -50,7 +45,6 @@ export default function PermissionDetails() {
|
|||
const { t } = useTranslation("clients");
|
||||
|
||||
const form = useForm<FormFields>({
|
||||
shouldUnregister: false,
|
||||
mode: "onChange",
|
||||
});
|
||||
const {
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
|
@ -23,10 +23,10 @@ import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog"
|
|||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import type { KeyValueType } from "../../components/key-value-form/key-value-convert";
|
||||
import { KeyValueInput } from "../../components/key-value-form/hook-form-v7/KeyValueInput";
|
||||
import { KeyValueInput } from "../../components/key-value-form/KeyValueInput";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/hook-form-v7/MultiLineInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
||||
|
@ -55,7 +55,6 @@ export default function ResourceDetails() {
|
|||
const { adminClient } = useAdminClient();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const form = useForm<SubmittedResource>({
|
||||
shouldUnregister: false,
|
||||
mode: "onChange",
|
||||
});
|
||||
const {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { Select, SelectOption, SelectVariant } from "@patternfly/react-core";
|
||||
|
||||
import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceRepresentation";
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form-v7";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
FormGroup,
|
||||
Select,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { Select, SelectOption, SelectVariant } from "@patternfly/react-core";
|
||||
|
||||
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form-v7";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form";
|
||||
import {
|
||||
AlertVariant,
|
||||
Button,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
SelectOption,
|
||||
FormGroup,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext, Controller } from "react-hook-form-v7";
|
||||
import { useFormContext, Controller } from "react-hook-form";
|
||||
import { FormGroup, Button, Checkbox } from "@patternfly/react-core";
|
||||
import { MinusCircleIcon } from "@patternfly/react-icons";
|
||||
import {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext, Controller } from "react-hook-form-v7";
|
||||
import { useFormContext, Controller } from "react-hook-form";
|
||||
import { MinusCircleIcon } from "@patternfly/react-icons";
|
||||
import { FormGroup, Button, Checkbox } from "@patternfly/react-core";
|
||||
import {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { FormGroup, Radio } from "@patternfly/react-core";
|
||||
|
||||
import { HelpItem } from "../../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { FormGroup, ValidatedOptions } from "@patternfly/react-core";
|
||||
|
||||
import { HelpItem } from "../../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
PageSection,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
|
@ -64,7 +64,7 @@ export default function PolicyDetails() {
|
|||
const { t } = useTranslation("clients");
|
||||
const { id, realm, policyId, policyType } = useParams<PolicyDetailsParams>();
|
||||
const navigate = useNavigate();
|
||||
const form = useForm({ shouldUnregister: false });
|
||||
const form = useForm();
|
||||
const { reset, handleSubmit } = form;
|
||||
|
||||
const { adminClient } = useAdminClient();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
|
||||
import { HelpItem } from "../../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext, Controller } from "react-hook-form-v7";
|
||||
import { useFormContext, Controller } from "react-hook-form";
|
||||
import { FormGroup, Button, Checkbox } from "@patternfly/react-core";
|
||||
import { MinusCircleIcon } from "@patternfly/react-icons";
|
||||
import {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
DatePicker,
|
||||
Flex,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
SplitItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext, useWatch } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
FormGroup,
|
||||
Select,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { FormGroup, Switch, ValidatedOptions } from "@patternfly/react-core";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
PageSection,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
|
@ -39,7 +39,7 @@ export default function ImportForm() {
|
|||
const navigate = useNavigate();
|
||||
const { adminClient } = useAdminClient();
|
||||
const { realm } = useRealm();
|
||||
const form = useForm<FormFields>({ shouldUnregister: false });
|
||||
const form = useForm<FormFields>();
|
||||
const { register, handleSubmit, setValue } = form;
|
||||
const [imported, setImported] = useState<ClientRepresentation>({});
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useForm } from "react-hook-form-v7";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import {
|
||||
ActionGroup,
|
||||
AlertVariant,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { Button, Modal, Form } from "@patternfly/react-core";
|
||||
import { saveAs } from "file-saver";
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
FormProvider,
|
||||
useForm,
|
||||
useFormContext,
|
||||
} from "react-hook-form-v7";
|
||||
} from "react-hook-form";
|
||||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Controller,
|
||||
FormProvider,
|
||||
useForm,
|
||||
useWatch,
|
||||
} from "react-hook-form-v7";
|
||||
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
||||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
|
|
|
@ -18,7 +18,7 @@ import { useTranslation } from "react-i18next";
|
|||
|
||||
import type CertificateRepresentation from "@keycloak/keycloak-admin-client/lib/defs/certificateRepresentation";
|
||||
import type KeyStoreConfig from "@keycloak/keycloak-admin-client/lib/defs/keystoreConfig";
|
||||
import { Controller, useFormContext, useWatch } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { FormProvider, useFormContext } from "react-hook-form-v7";
|
||||
import { FormProvider, useFormContext } from "react-hook-form";
|
||||
import { AlertVariant } from "@patternfly/react-core";
|
||||
|
||||
import type { KeyTypes } from "./SamlKeys";
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { saveAs } from "file-saver";
|
||||
import { Fragment, useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type CertificateRepresentation from "@keycloak/keycloak-admin-client/lib/defs/certificateRepresentation";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useState } from "react";
|
||||
import { saveAs } from "file-saver";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import {
|
||||
AlertVariant,
|
||||
Button,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext } from "react-hook-form-v7";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
|
||||
import type KeyStoreConfig from "@keycloak/keycloak-admin-client/lib/defs/keystoreConfig";
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { QuestionCircleIcon } from "@patternfly/react-icons";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form-v7";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useHelp } from "../../components/help-enabler/HelpHeader";
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
FormGroup,
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||
import type { ClientQuery } from "@keycloak/keycloak-admin-client/lib/resources/clients";
|
||||
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import type { ComponentProps } from "../dynamic/components";
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
|
||||
type ClientSelectProps = ComponentProps & {
|
||||
namespace: string;
|
||||
|
@ -29,7 +29,10 @@ export const ClientSelect = ({
|
|||
required = false,
|
||||
}: ClientSelectProps) => {
|
||||
const { t } = useTranslation(namespace);
|
||||
const { control, errors } = useFormContext();
|
||||
const {
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useFormContext();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [clients, setClients] = useState<ClientRepresentation[]>([]);
|
||||
|
@ -80,20 +83,20 @@ export const ClientSelect = ({
|
|||
defaultValue={defaultValue || ""}
|
||||
control={control}
|
||||
rules={required ? { required: true } : {}}
|
||||
render={({ onChange, value }) => (
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId={name}
|
||||
variant={SelectVariant.typeahead}
|
||||
onToggle={(open) => setOpen(open)}
|
||||
isOpen={open}
|
||||
isDisabled={isDisabled}
|
||||
selections={value}
|
||||
selections={field.value}
|
||||
onFilter={(_, value) => {
|
||||
setSearch(value);
|
||||
return convert(clients);
|
||||
}}
|
||||
onSelect={(_, value) => {
|
||||
onChange(value.toString());
|
||||
field.onChange(value.toString());
|
||||
setOpen(false);
|
||||
}}
|
||||
aria-label={t(label!)}
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form-v7";
|
||||
import {
|
||||
FormGroup,
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
|
||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||
import type { ClientQuery } from "@keycloak/keycloak-admin-client/lib/resources/clients";
|
||||
import { useAdminClient, useFetch } from "../../../context/auth/AdminClient";
|
||||
import { HelpItem } from "../../help-enabler/HelpItem";
|
||||
import type { ComponentProps } from "../../dynamic/components";
|
||||
|
||||
type ClientSelectProps = ComponentProps & {
|
||||
namespace: string;
|
||||
required?: boolean;
|
||||
};
|
||||
|
||||
export const ClientSelect = ({
|
||||
name,
|
||||
label,
|
||||
helpText,
|
||||
defaultValue,
|
||||
namespace,
|
||||
isDisabled = false,
|
||||
required = false,
|
||||
}: ClientSelectProps) => {
|
||||
const { t } = useTranslation(namespace);
|
||||
const {
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useFormContext();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [clients, setClients] = useState<ClientRepresentation[]>([]);
|
||||
const [search, setSearch] = useState("");
|
||||
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
useFetch(
|
||||
() => {
|
||||
const params: ClientQuery = {
|
||||
max: 20,
|
||||
};
|
||||
if (search) {
|
||||
params.clientId = search;
|
||||
params.search = true;
|
||||
}
|
||||
return adminClient.clients.find(params);
|
||||
},
|
||||
(clients) => setClients(clients),
|
||||
[search]
|
||||
);
|
||||
|
||||
const convert = (clients: ClientRepresentation[]) => [
|
||||
<SelectOption key="empty" value="">
|
||||
{t("common:none")}
|
||||
</SelectOption>,
|
||||
...clients.map((option) => (
|
||||
<SelectOption key={option.id} value={option.clientId} />
|
||||
)),
|
||||
];
|
||||
|
||||
return (
|
||||
<FormGroup
|
||||
label={t(label!)}
|
||||
isRequired={required}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t(helpText!)}
|
||||
fieldLabelId={`${namespace}:${label}`}
|
||||
/>
|
||||
}
|
||||
fieldId={name!}
|
||||
validated={errors[name!] ? "error" : "default"}
|
||||
helperTextInvalid={t("common:required")}
|
||||
>
|
||||
<Controller
|
||||
name={name!}
|
||||
defaultValue={defaultValue || ""}
|
||||
control={control}
|
||||
rules={required ? { required: true } : {}}
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId={name}
|
||||
variant={SelectVariant.typeahead}
|
||||
onToggle={(open) => setOpen(open)}
|
||||
isOpen={open}
|
||||
isDisabled={isDisabled}
|
||||
selections={field.value}
|
||||
onFilter={(_, value) => {
|
||||
setSearch(value);
|
||||
return convert(clients);
|
||||
}}
|
||||
onSelect={(_, value) => {
|
||||
field.onChange(value.toString());
|
||||
setOpen(false);
|
||||
}}
|
||||
aria-label={t(label!)}
|
||||
>
|
||||
{convert(clients)}
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
|
@ -1,9 +1,9 @@
|
|||
import { FormGroup, Switch } from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormGroup, Switch } from "@patternfly/react-core";
|
||||
|
||||
import type { ComponentProps } from "./components";
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import type { ComponentProps } from "./components";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
|
||||
export const BooleanComponent = ({
|
||||
|
@ -29,16 +29,18 @@ export const BooleanComponent = ({
|
|||
data-testid={name}
|
||||
defaultValue={false}
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
render={({ field }) => (
|
||||
<Switch
|
||||
id={name!}
|
||||
isDisabled={isDisabled}
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
isChecked={
|
||||
value === "true" || value === true || value[0] === "true"
|
||||
field.value === "true" ||
|
||||
field.value === true ||
|
||||
field.value[0] === "true"
|
||||
}
|
||||
onChange={(value) => onChange("" + value)}
|
||||
onChange={(value) => field.onChange("" + value)}
|
||||
data-testid={name}
|
||||
aria-label={t(label!)}
|
||||
/>
|
||||
|
|
|
@ -26,5 +26,5 @@ export const DynamicComponents = ({
|
|||
</>
|
||||
);
|
||||
|
||||
export const convertToName = (name: string) =>
|
||||
export const convertToName = (name: string): string =>
|
||||
convertAttributeNameToForm(`config.${name}`);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import { FileUpload } from "../json-file-upload/patternfly/FileUpload";
|
||||
import type { ComponentProps } from "./components";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
import { FileUpload } from "../json-file-upload/patternfly/FileUpload";
|
||||
|
||||
export const FileComponent = ({
|
||||
name,
|
||||
|
@ -32,10 +32,10 @@ export const FileComponent = ({
|
|||
name={convertToName(name!)}
|
||||
control={control}
|
||||
defaultValue={defaultValue || ""}
|
||||
render={({ onChange, value }) => (
|
||||
render={({ field }) => (
|
||||
<FileUpload
|
||||
id={name!}
|
||||
value={value}
|
||||
value={field.value}
|
||||
type="text"
|
||||
filename={filename}
|
||||
isDisabled={isDisabled}
|
||||
|
@ -43,13 +43,13 @@ export const FileComponent = ({
|
|||
onReadStarted={() => setIsLoading(true)}
|
||||
onReadFinished={() => setIsLoading(false)}
|
||||
onClearClick={() => {
|
||||
onChange("");
|
||||
field.onChange("");
|
||||
setFilename("");
|
||||
}}
|
||||
isLoading={isLoading}
|
||||
allowEditingUploadedText={false}
|
||||
onChange={(value, filename) => {
|
||||
onChange(value);
|
||||
field.onChange(value);
|
||||
setFilename(filename);
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -25,9 +25,8 @@ export const GroupComponent = ({ name, label, helpText }: ComponentProps) => {
|
|||
<Controller
|
||||
name={convertToName(name!)}
|
||||
defaultValue=""
|
||||
typeAheadAriaLabel={t("selectGroup")}
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
render={({ field }) => (
|
||||
<>
|
||||
{open && (
|
||||
<GroupPickerDialog
|
||||
|
@ -37,7 +36,7 @@ export const GroupComponent = ({ name, label, helpText }: ComponentProps) => {
|
|||
ok: "common:select",
|
||||
}}
|
||||
onConfirm={(groups) => {
|
||||
onChange(groups?.[0].path);
|
||||
field.onChange(groups?.[0].path);
|
||||
setGroups(groups);
|
||||
setOpen(false);
|
||||
}}
|
||||
|
@ -58,8 +57,10 @@ export const GroupComponent = ({ name, label, helpText }: ComponentProps) => {
|
|||
>
|
||||
<InputGroup>
|
||||
<ChipGroup>
|
||||
{value && (
|
||||
<Chip onClick={() => onChange(undefined)}>{value}</Chip>
|
||||
{field.value && (
|
||||
<Chip onClick={() => field.onChange(undefined)}>
|
||||
{field.value}
|
||||
</Chip>
|
||||
)}
|
||||
</ChipGroup>
|
||||
<Button
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
FormGroup,
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type { ComponentProps } from "./components";
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import type { ComponentProps } from "./components";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
|
||||
export const ListComponent = ({
|
||||
|
@ -37,23 +37,23 @@ export const ListComponent = ({
|
|||
data-testid={name}
|
||||
defaultValue={defaultValue || ""}
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId={name}
|
||||
isDisabled={isDisabled}
|
||||
onToggle={(toggle) => setOpen(toggle)}
|
||||
onSelect={(_, value) => {
|
||||
onChange(value as string);
|
||||
field.onChange(value as string);
|
||||
setOpen(false);
|
||||
}}
|
||||
selections={value}
|
||||
selections={field.value}
|
||||
variant={SelectVariant.single}
|
||||
aria-label={t(label!)}
|
||||
isOpen={open}
|
||||
>
|
||||
{options?.map((option) => (
|
||||
<SelectOption
|
||||
selected={option === value}
|
||||
selected={option === field.value}
|
||||
key={option}
|
||||
value={option}
|
||||
/>
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import {
|
||||
ActionList,
|
||||
ActionListItem,
|
||||
|
@ -11,11 +8,14 @@ import {
|
|||
TextInput,
|
||||
} from "@patternfly/react-core";
|
||||
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type { ComponentProps } from "./components";
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
import { KeyValueType } from "../key-value-form/key-value-convert";
|
||||
import type { ComponentProps } from "./components";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
|
||||
type IdKeyValueType = KeyValueType & {
|
||||
id: number;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
FormGroup,
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import type { ComponentProps } from "./components";
|
||||
|
@ -36,7 +36,7 @@ export const MultiValuedListComponent = ({
|
|||
name={convertToName(name!)}
|
||||
control={control}
|
||||
defaultValue={defaultValue ? [defaultValue] : []}
|
||||
render={({ onChange, value }) => (
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId={name}
|
||||
data-testid={name}
|
||||
|
@ -49,18 +49,20 @@ export const MultiValuedListComponent = ({
|
|||
variant={SelectVariant.typeaheadMulti}
|
||||
typeAheadAriaLabel="Select"
|
||||
onToggle={(isOpen) => setOpen(isOpen)}
|
||||
selections={value}
|
||||
selections={field.value}
|
||||
onSelect={(_, v) => {
|
||||
const option = v.toString();
|
||||
if (value.includes(option)) {
|
||||
onChange(value.filter((item: string) => item !== option));
|
||||
if (field.value.includes(option)) {
|
||||
field.onChange(
|
||||
field.value.filter((item: string) => item !== option)
|
||||
);
|
||||
} else {
|
||||
onChange([...value, option]);
|
||||
field.onChange([...field.value, option]);
|
||||
}
|
||||
}}
|
||||
onClear={(event) => {
|
||||
event.stopPropagation();
|
||||
onChange([]);
|
||||
field.onChange([]);
|
||||
}}
|
||||
isOpen={open}
|
||||
aria-label={t(label!)}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type { ComponentProps } from "./components";
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import { PasswordInput } from "../password-input/PasswordInput";
|
||||
import type { ComponentProps } from "./components";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
|
||||
export const PasswordComponent = ({
|
||||
|
@ -29,9 +29,8 @@ export const PasswordComponent = ({
|
|||
id={name!}
|
||||
data-testid={name}
|
||||
isDisabled={isDisabled}
|
||||
ref={register()}
|
||||
name={convertToName(name!)}
|
||||
defaultValue={defaultValue?.toString()}
|
||||
{...register(convertToName(name!))}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
Button,
|
||||
Chip,
|
||||
|
@ -7,12 +5,14 @@ import {
|
|||
Split,
|
||||
SplitItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type { ComponentProps } from "./components";
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import useToggle from "../../utils/useToggle";
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import { AddRoleMappingModal } from "../role-mapping/AddRoleMappingModal";
|
||||
import { ServiceRole, Row } from "../role-mapping/RoleMapping";
|
||||
import { Row, ServiceRole } from "../role-mapping/RoleMapping";
|
||||
import type { ComponentProps } from "./components";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
|
||||
const parseValue = (value: any) =>
|
||||
|
@ -33,7 +33,10 @@ export const RoleComponent = ({
|
|||
const { t } = useTranslation("dynamic");
|
||||
|
||||
const [openModal, toggleModal] = useToggle();
|
||||
const { control, errors } = useFormContext();
|
||||
const {
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useFormContext();
|
||||
|
||||
const fieldName = convertToName(name!);
|
||||
|
||||
|
@ -50,27 +53,26 @@ export const RoleComponent = ({
|
|||
<Controller
|
||||
name={fieldName}
|
||||
defaultValue={defaultValue || ""}
|
||||
typeAheadAriaLabel="Select an action"
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
render={({ field }) => (
|
||||
<Split>
|
||||
{openModal && (
|
||||
<AddRoleMappingModal
|
||||
id="id"
|
||||
type="roles"
|
||||
name={name}
|
||||
onAssign={(rows) => onChange(parseRow(rows[0]))}
|
||||
onAssign={(rows) => field.onChange(parseRow(rows[0]))}
|
||||
onClose={toggleModal}
|
||||
isRadio
|
||||
/>
|
||||
)}
|
||||
|
||||
{value !== "" && (
|
||||
{field.value !== "" && (
|
||||
<SplitItem>
|
||||
<Chip textMaxWidth="500px" onClick={() => onChange("")}>
|
||||
<Chip textMaxWidth="500px" onClick={() => field.onChange("")}>
|
||||
<ServiceRole
|
||||
role={{ name: parseValue(value)[1] }}
|
||||
client={{ clientId: parseValue(value)[0] }}
|
||||
role={{ name: parseValue(field.value)[1] }}
|
||||
client={{ clientId: parseValue(field.value)[0] }}
|
||||
/>
|
||||
</Chip>
|
||||
</SplitItem>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import type { ComponentProps } from "./components";
|
||||
|
@ -32,14 +32,14 @@ export const ScriptComponent = ({
|
|||
name={convertToName(name!)}
|
||||
defaultValue={defaultValue}
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
render={({ field }) => (
|
||||
<CodeEditor
|
||||
id={name!}
|
||||
data-testid={name}
|
||||
isReadOnly={isDisabled}
|
||||
type="text"
|
||||
onChange={onChange}
|
||||
code={value}
|
||||
onChange={field.onChange}
|
||||
code={field.value}
|
||||
height="600px"
|
||||
language={Language.javascript}
|
||||
/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
|
||||
|
@ -29,10 +29,8 @@ export const StringComponent = ({
|
|||
id={name!}
|
||||
data-testid={name}
|
||||
isDisabled={isDisabled}
|
||||
ref={register()}
|
||||
type="text"
|
||||
name={convertToName(name!)}
|
||||
defaultValue={defaultValue?.toString()}
|
||||
{...register(convertToName(name!))}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "../help-enabler/HelpItem";
|
||||
import { KeycloakTextArea } from "../keycloak-text-area/KeycloakTextArea";
|
||||
|
@ -29,9 +29,8 @@ export const TextComponent = ({
|
|||
id={name!}
|
||||
data-testid={name}
|
||||
isDisabled={isDisabled}
|
||||
ref={register()}
|
||||
name={convertToName(name!)}
|
||||
defaultValue={defaultValue?.toString()}
|
||||
{...register(convertToName(name!))}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
/**
|
||||
* @vitest-environment jsdom
|
||||
*/
|
||||
import type WhoAmIRepresentation from "@keycloak/keycloak-admin-client/lib/defs/whoAmIRepresentation";
|
||||
import { FormGroup, Switch } from "@patternfly/react-core";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { AccessContextProvider } from "../../context/access/Access";
|
||||
import { RealmContext } from "../../context/realm-context/RealmContext";
|
||||
import { WhoAmI, WhoAmIContext } from "../../context/whoami/WhoAmI";
|
||||
import whoami from "../../context/whoami/__tests__/mock-whoami.json";
|
||||
import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
|
||||
import { FormAccess } from "./FormAccess";
|
||||
|
||||
describe("FormAccess", () => {
|
||||
const Form = ({ realm }: { realm: string }) => {
|
||||
const { register, control } = useForm();
|
||||
return (
|
||||
<WhoAmIContext.Provider
|
||||
value={{
|
||||
refresh: () => {},
|
||||
whoAmI: new WhoAmI(whoami as WhoAmIRepresentation),
|
||||
}}
|
||||
>
|
||||
<RealmContext.Provider value={{ realm }}>
|
||||
<AccessContextProvider>
|
||||
<FormAccess role="manage-clients">
|
||||
<FormGroup label="test" fieldId="field">
|
||||
<KeycloakTextInput
|
||||
type="text"
|
||||
id="field"
|
||||
data-testid="field"
|
||||
name="fieldName"
|
||||
ref={register()}
|
||||
/>
|
||||
</FormGroup>
|
||||
<Controller
|
||||
name="consentRequired"
|
||||
defaultValue={false}
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
data-testid="kc-consent"
|
||||
label={"on"}
|
||||
labelOff="off"
|
||||
isChecked={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormAccess>
|
||||
</AccessContextProvider>
|
||||
</RealmContext.Provider>
|
||||
</WhoAmIContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
it("renders disabled form for test realm", () => {
|
||||
render(<Form realm="test" />);
|
||||
expect(screen.getByTestId("field")).toBeDisabled();
|
||||
expect(screen.getByTestId("kc-consent")).toBeDisabled();
|
||||
});
|
||||
});
|
|
@ -1,18 +1,18 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { FormProvider, UseFormMethods } from "react-hook-form";
|
||||
import { ActionGroup, Button } from "@patternfly/react-core";
|
||||
|
||||
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
||||
import { ActionGroup, Button } from "@patternfly/react-core";
|
||||
import { FormProvider, UseFormReturn } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../form-access/FormAccess";
|
||||
import type { KeyValueType } from "./key-value-convert";
|
||||
import { KeyValueInput } from "./KeyValueInput";
|
||||
import { FormAccess } from "../form-access/FormAccess";
|
||||
|
||||
export type AttributeForm = Omit<RoleRepresentation, "attributes"> & {
|
||||
attributes?: KeyValueType[];
|
||||
};
|
||||
|
||||
export type AttributesFormProps = {
|
||||
form: UseFormMethods<AttributeForm>;
|
||||
form: UseFormReturn<AttributeForm>;
|
||||
save?: (model: AttributeForm) => void;
|
||||
reset?: () => void;
|
||||
fineGrainedAccess?: boolean;
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useFieldArray, useFormContext, useWatch } from "react-hook-form";
|
||||
import {
|
||||
ActionList,
|
||||
ActionListItem,
|
||||
|
@ -9,9 +6,12 @@ import {
|
|||
FlexItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
||||
import { useEffect } from "react";
|
||||
import { useFieldArray, useFormContext, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type { KeyValueType } from "./key-value-convert";
|
||||
import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
|
||||
import { KeyValueType } from "./key-value-convert";
|
||||
|
||||
type KeyValueInputProps = {
|
||||
name: string;
|
||||
|
@ -20,25 +20,28 @@ type KeyValueInputProps = {
|
|||
export const KeyValueInput = ({ name }: KeyValueInputProps) => {
|
||||
const { t } = useTranslation("common");
|
||||
const { control, register } = useFormContext();
|
||||
const { fields, append, remove } = useFieldArray<KeyValueType>({
|
||||
control: control,
|
||||
name,
|
||||
});
|
||||
|
||||
const watchFields = useWatch<KeyValueType[]>({
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name,
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
const isValid = watchFields.every(
|
||||
({ key, value }) =>
|
||||
key && key.trim().length !== 0 && value && value.trim().length !== 0
|
||||
const watchFields = useWatch({
|
||||
control,
|
||||
name,
|
||||
defaultValue: [{ key: "", value: "" }],
|
||||
});
|
||||
|
||||
const isValid =
|
||||
Array.isArray(watchFields) &&
|
||||
watchFields.every(
|
||||
({ key, value }: KeyValueType) =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
key?.trim().length !== 0 && value?.trim().length !== 0
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!fields.length) {
|
||||
append({ key: "", value: "" }, false);
|
||||
append({ key: "", value: "" }, { shouldFocus: false });
|
||||
}
|
||||
}, [fields]);
|
||||
|
||||
|
@ -60,12 +63,11 @@ export const KeyValueInput = ({ name }: KeyValueInputProps) => {
|
|||
<Flex key={attribute.id} data-testid="row">
|
||||
<FlexItem grow={{ default: "grow" }}>
|
||||
<KeycloakTextInput
|
||||
name={`${name}[${index}].key`}
|
||||
ref={register()}
|
||||
placeholder={t("keyPlaceholder")}
|
||||
aria-label={t("key")}
|
||||
defaultValue={attribute.key}
|
||||
defaultValue=""
|
||||
data-testid={`${name}[${index}].key`}
|
||||
{...register(`${name}[${index}].key`)}
|
||||
/>
|
||||
</FlexItem>
|
||||
<FlexItem
|
||||
|
@ -73,12 +75,11 @@ export const KeyValueInput = ({ name }: KeyValueInputProps) => {
|
|||
spacer={{ default: "spacerNone" }}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
name={`${name}[${index}].value`}
|
||||
ref={register()}
|
||||
placeholder={t("valuePlaceholder")}
|
||||
aria-label={t("value")}
|
||||
defaultValue={attribute.value}
|
||||
defaultValue=""
|
||||
data-testid={`${name}[${index}].value`}
|
||||
{...register(`${name}[${index}].value`)}
|
||||
/>
|
||||
</FlexItem>
|
||||
<FlexItem>
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
import {
|
||||
ActionList,
|
||||
ActionListItem,
|
||||
Button,
|
||||
Flex,
|
||||
FlexItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
||||
import { useEffect } from "react";
|
||||
import { useFieldArray, useFormContext, useWatch } from "react-hook-form-v7";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { KeycloakTextInput } from "../../keycloak-text-input/KeycloakTextInput";
|
||||
import { KeyValueType } from "../key-value-convert";
|
||||
|
||||
type KeyValueInputProps = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export const KeyValueInput = ({ name }: KeyValueInputProps) => {
|
||||
const { t } = useTranslation("common");
|
||||
const { control, register } = useFormContext();
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
control,
|
||||
name,
|
||||
});
|
||||
|
||||
const watchFields = useWatch({
|
||||
control,
|
||||
name,
|
||||
defaultValue: [{ key: "", value: "" }],
|
||||
});
|
||||
|
||||
const isValid =
|
||||
Array.isArray(watchFields) &&
|
||||
watchFields.every(
|
||||
({ key, value }: KeyValueType) =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
key?.trim().length !== 0 && value?.trim().length !== 0
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!fields.length) {
|
||||
append({ key: "", value: "" }, { shouldFocus: false });
|
||||
}
|
||||
}, [fields]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex direction={{ default: "column" }}>
|
||||
<Flex>
|
||||
<FlexItem
|
||||
grow={{ default: "grow" }}
|
||||
spacer={{ default: "spacerNone" }}
|
||||
>
|
||||
<strong>{t("key")}</strong>
|
||||
</FlexItem>
|
||||
<FlexItem grow={{ default: "grow" }}>
|
||||
<strong>{t("value")}</strong>
|
||||
</FlexItem>
|
||||
</Flex>
|
||||
{fields.map((attribute, index) => (
|
||||
<Flex key={attribute.id} data-testid="row">
|
||||
<FlexItem grow={{ default: "grow" }}>
|
||||
<KeycloakTextInput
|
||||
placeholder={t("keyPlaceholder")}
|
||||
aria-label={t("key")}
|
||||
defaultValue=""
|
||||
data-testid={`${name}[${index}].key`}
|
||||
{...register(`${name}[${index}].key`)}
|
||||
/>
|
||||
</FlexItem>
|
||||
<FlexItem
|
||||
grow={{ default: "grow" }}
|
||||
spacer={{ default: "spacerNone" }}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
placeholder={t("valuePlaceholder")}
|
||||
aria-label={t("value")}
|
||||
defaultValue=""
|
||||
data-testid={`${name}[${index}].value`}
|
||||
{...register(`${name}[${index}].value`)}
|
||||
/>
|
||||
</FlexItem>
|
||||
<FlexItem>
|
||||
<Button
|
||||
variant="link"
|
||||
title={t("removeAttribute")}
|
||||
isDisabled={watchFields.length === 1}
|
||||
onClick={() => remove(index)}
|
||||
data-testid={`${name}[${index}].remove`}
|
||||
>
|
||||
<MinusCircleIcon />
|
||||
</Button>
|
||||
</FlexItem>
|
||||
</Flex>
|
||||
))}
|
||||
</Flex>
|
||||
<ActionList>
|
||||
<ActionListItem>
|
||||
<Button
|
||||
data-testid={`${name}-add-row`}
|
||||
className="pf-u-px-0 pf-u-mt-sm"
|
||||
variant="link"
|
||||
icon={<PlusCircleIcon />}
|
||||
isDisabled={!isValid}
|
||||
onClick={() => append({ key: "", value: "" })}
|
||||
>
|
||||
{t("addAttribute")}
|
||||
</Button>
|
||||
</ActionListItem>
|
||||
</ActionList>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
import { Path, PathValue } from "react-hook-form-v7";
|
||||
import { Path, PathValue } from "react-hook-form";
|
||||
|
||||
export type KeyValueType = { key: string; value: string };
|
||||
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
InputGroup,
|
||||
TextInput,
|
||||
TextInputProps,
|
||||
} from "@patternfly/react-core";
|
||||
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
||||
import { Fragment, useEffect, useMemo } from "react";
|
||||
import { useFormContext, useWatch } from "react-hook-form-v7";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
function stringToMultiline(value?: string): string[] {
|
||||
return typeof value === "string" ? value.split("##") : [];
|
||||
}
|
||||
|
||||
function toStringValue(formValue: string[]): string {
|
||||
return formValue.join("##");
|
||||
}
|
||||
|
||||
export type MultiLineInputProps = Omit<TextInputProps, "form"> & {
|
||||
name: string;
|
||||
addButtonLabel?: string;
|
||||
isDisabled?: boolean;
|
||||
defaultValue?: string[];
|
||||
stringify?: boolean;
|
||||
};
|
||||
|
||||
export const MultiLineInput = ({
|
||||
name,
|
||||
addButtonLabel,
|
||||
isDisabled = false,
|
||||
defaultValue,
|
||||
stringify = false,
|
||||
...rest
|
||||
}: MultiLineInputProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { register, setValue, control } = useFormContext();
|
||||
const value = useWatch({
|
||||
name,
|
||||
control,
|
||||
defaultValue: defaultValue || "",
|
||||
});
|
||||
|
||||
const fields = useMemo<string[]>(() => {
|
||||
let values = stringify ? stringToMultiline(value as string) : value;
|
||||
|
||||
values =
|
||||
Array.isArray(values) && values.length !== 0
|
||||
? values
|
||||
: defaultValue || [""];
|
||||
|
||||
return values;
|
||||
}, [value]);
|
||||
|
||||
const remove = (index: number) => {
|
||||
update([...fields.slice(0, index), ...fields.slice(index + 1)]);
|
||||
};
|
||||
|
||||
const append = () => {
|
||||
update([...fields, ""]);
|
||||
};
|
||||
|
||||
const updateValue = (index: number, value: string) => {
|
||||
update([...fields.slice(0, index), value, ...fields.slice(index + 1)]);
|
||||
};
|
||||
|
||||
const update = (values: string[]) => {
|
||||
const fieldValue = values.flatMap((field) => field);
|
||||
setValue(name, stringify ? toStringValue(fieldValue) : fieldValue, {
|
||||
shouldDirty: true,
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
register(name);
|
||||
}, [register]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{fields.map((value, index) => (
|
||||
<Fragment key={index}>
|
||||
<InputGroup>
|
||||
<TextInput
|
||||
data-testid={name + index}
|
||||
onChange={(value) => updateValue(index, value)}
|
||||
name={`${name}[${index}].value`}
|
||||
value={value}
|
||||
isDisabled={isDisabled}
|
||||
{...rest}
|
||||
/>
|
||||
<Button
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => remove(index)}
|
||||
tabIndex={-1}
|
||||
aria-label={t("common:remove")}
|
||||
isDisabled={fields.length === 1}
|
||||
>
|
||||
<MinusCircleIcon />
|
||||
</Button>
|
||||
</InputGroup>
|
||||
{index === fields.length - 1 && (
|
||||
<Button
|
||||
variant={ButtonVariant.link}
|
||||
onClick={append}
|
||||
tabIndex={-1}
|
||||
aria-label={t("common:add")}
|
||||
data-testid="addValue"
|
||||
isDisabled={!value}
|
||||
>
|
||||
<PlusCircleIcon /> {t(addButtonLabel || "common:add")}
|
||||
</Button>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue