Default value and required field for generate keys (#2195)

This commit is contained in:
Erik Jan de Wit 2022-03-16 11:37:45 +01:00 committed by GitHub
parent 8d5b2f903a
commit 0a33d5f0dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 27 deletions

View file

@ -1,6 +1,11 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Control, Controller, useForm } from "react-hook-form"; import {
Controller,
FormProvider,
useForm,
useFormContext,
} from "react-hook-form";
import { import {
Button, Button,
ButtonVariant, ButtonVariant,
@ -21,26 +26,23 @@ import { HelpItem } from "../../components/help-enabler/HelpItem";
import { StoreSettings } from "./StoreSettings"; import { StoreSettings } from "./StoreSettings";
type GenerateKeyDialogProps = { type GenerateKeyDialogProps = {
clientId: string;
toggleDialog: () => void; toggleDialog: () => void;
save: (keyStoreConfig: KeyStoreConfig) => void; save: (keyStoreConfig: KeyStoreConfig) => void;
}; };
type KeyFormProps = { type KeyFormProps = {
register: () => void;
control: Control<KeyStoreConfig>;
useFile?: boolean; useFile?: boolean;
}; };
export const KeyForm = ({ export const KeyForm = ({ useFile = false }: KeyFormProps) => {
register,
control,
useFile = false,
}: KeyFormProps) => {
const { t } = useTranslation("clients"); const { t } = useTranslation("clients");
const [filename, setFilename] = useState<string>(); const [filename, setFilename] = useState<string>();
const [openArchiveFormat, setOpenArchiveFormat] = useState(false); const [openArchiveFormat, setOpenArchiveFormat] = useState(false);
const { control } = useFormContext<KeyStoreConfig>();
return ( return (
<Form className="pf-u-pt-lg"> <Form className="pf-u-pt-lg">
<FormGroup <FormGroup
@ -111,17 +113,26 @@ export const KeyForm = ({
/> />
</FormGroup> </FormGroup>
)} )}
<StoreSettings register={register} hidePassword={useFile} /> <StoreSettings hidePassword={useFile} />
</Form> </Form>
); );
}; };
export const GenerateKeyDialog = ({ export const GenerateKeyDialog = ({
clientId,
save, save,
toggleDialog, toggleDialog,
}: GenerateKeyDialogProps) => { }: GenerateKeyDialogProps) => {
const { t } = useTranslation("clients"); const { t } = useTranslation("clients");
const { register, control, handleSubmit } = useForm<KeyStoreConfig>(); const form = useForm<KeyStoreConfig>({
defaultValues: { keyAlias: clientId },
mode: "onChange",
});
const {
handleSubmit,
formState: { isValid },
} = form;
return ( return (
<Modal <Modal
@ -134,6 +145,7 @@ export const GenerateKeyDialog = ({
id="modal-confirm" id="modal-confirm"
key="confirm" key="confirm"
data-testid="confirm" data-testid="confirm"
isDisabled={!isValid}
onClick={() => { onClick={() => {
handleSubmit((config) => { handleSubmit((config) => {
save(config); save(config);
@ -159,7 +171,9 @@ export const GenerateKeyDialog = ({
<TextContent> <TextContent>
<Text>{t("clients-help:generateKeysDescription")}</Text> <Text>{t("clients-help:generateKeysDescription")}</Text>
</TextContent> </TextContent>
<KeyForm register={register} control={control} /> <FormProvider {...form}>
<KeyForm />
</FormProvider>
</Modal> </Modal>
); );
}; };

View file

@ -1,6 +1,6 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Controller, useForm, useWatch } from "react-hook-form"; import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
import { import {
Button, Button,
ButtonVariant, ButtonVariant,
@ -43,7 +43,8 @@ export const ImportKeyDialog = ({
toggleDialog, toggleDialog,
}: ImportKeyDialogProps) => { }: ImportKeyDialogProps) => {
const { t } = useTranslation("clients"); const { t } = useTranslation("clients");
const { register, control, handleSubmit } = useForm<ImportFile>(); const form = useForm<ImportFile>();
const { control, handleSubmit } = form;
const [openArchiveFormat, setOpenArchiveFormat] = useState(false); const [openArchiveFormat, setOpenArchiveFormat] = useState(false);
@ -128,7 +129,9 @@ export const ImportKeyDialog = ({
/> />
</FormGroup> </FormGroup>
{baseFormats.includes(format) && ( {baseFormats.includes(format) && (
<StoreSettings register={register} hidePassword /> <FormProvider {...form}>
<StoreSettings hidePassword />
</FormProvider>
)} )}
<FormGroup label={t("importFile")} fieldId="importFile"> <FormGroup label={t("importFile")} fieldId="importFile">
<Controller <Controller

View file

@ -42,6 +42,7 @@ export const Keys = ({ clientId, save }: KeysProps) => {
const { const {
control, control,
register, register,
getValues,
formState: { isDirty }, formState: { isDirty },
} = useFormContext<ClientRepresentation>(); } = useFormContext<ClientRepresentation>();
const adminClient = useAdminClient(); const adminClient = useAdminClient();
@ -106,6 +107,7 @@ export const Keys = ({ clientId, save }: KeysProps) => {
<PageSection variant="light" className="keycloak__form"> <PageSection variant="light" className="keycloak__form">
{openGenerateKeys && ( {openGenerateKeys && (
<GenerateKeyDialog <GenerateKeyDialog
clientId={getValues("clientId")!}
toggleDialog={toggleOpenGenerateKeys} toggleDialog={toggleOpenGenerateKeys}
save={generate} save={generate}
/> />

View file

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useFormContext } from "react-hook-form"; import { FormProvider, useFormContext } from "react-hook-form";
import { AlertVariant } from "@patternfly/react-core"; import { AlertVariant } from "@patternfly/react-core";
import type { KeyTypes } from "./SamlKeys"; import type { KeyTypes } from "./SamlKeys";
@ -22,7 +22,8 @@ export const SamlImportKeyDialog = ({
onClose, onClose,
}: SamlImportKeyDialogProps) => { }: SamlImportKeyDialogProps) => {
const { t } = useTranslation("clients"); const { t } = useTranslation("clients");
const { register, control, handleSubmit } = useFormContext(); const form = useFormContext();
const { handleSubmit } = form;
const adminClient = useAdminClient(); const adminClient = useAdminClient();
const { addAlert, addError } = useAlerts(); const { addAlert, addError } = useAlerts();
@ -48,7 +49,9 @@ export const SamlImportKeyDialog = ({
onClose(); onClose();
}} }}
> >
<KeyForm register={register} control={control} useFile /> <FormProvider {...form}>
<KeyForm useFile />
</FormProvider>
</ConfirmDialogModal> </ConfirmDialogModal>
); );
}; };

View file

@ -1,7 +1,7 @@
import React, { useState } from "react"; import React, { useState } from "react";
import FileSaver from "file-saver"; import FileSaver from "file-saver";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useForm } from "react-hook-form"; import { FormProvider, useForm } from "react-hook-form";
import { import {
AlertVariant, AlertVariant,
Button, Button,
@ -75,12 +75,11 @@ export const SamlKeysDialog = ({
const { t } = useTranslation("clients"); const { t } = useTranslation("clients");
const [type, setType] = useState(false); const [type, setType] = useState(false);
const [keys, setKeys] = useState<CertificateRepresentation>(); const [keys, setKeys] = useState<CertificateRepresentation>();
const form = useForm<SamlKeysDialogForm>();
const { const {
register,
control,
handleSubmit, handleSubmit,
formState: { isDirty }, formState: { isDirty },
} = useForm<SamlKeysDialogForm>(); } = form;
const adminClient = useAdminClient(); const adminClient = useAdminClient();
const { addAlert, addError } = useAlerts(); const { addAlert, addError } = useAlerts();
@ -211,7 +210,11 @@ export const SamlKeysDialog = ({
</FormGroup> </FormGroup>
</Form> </Form>
)} )}
{type && <KeyForm register={register} control={control} useFile />} {type && (
<FormProvider {...form}>
<KeyForm useFile />
</FormProvider>
)}
</Modal> </Modal>
); );
}; };

View file

@ -1,24 +1,26 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useFormContext } from "react-hook-form";
import { FormGroup, TextInput } from "@patternfly/react-core"; import { FormGroup, TextInput } from "@patternfly/react-core";
import type KeyStoreConfig from "@keycloak/keycloak-admin-client/lib/defs/keystoreConfig";
import { HelpItem } from "../../components/help-enabler/HelpItem"; import { HelpItem } from "../../components/help-enabler/HelpItem";
import { PasswordInput } from "../../components/password-input/PasswordInput"; import { PasswordInput } from "../../components/password-input/PasswordInput";
export const StoreSettings = ({ export const StoreSettings = ({
register,
hidePassword = false, hidePassword = false,
}: { }: {
register: () => void;
hidePassword?: boolean; hidePassword?: boolean;
}) => { }) => {
const { t } = useTranslation("clients"); const { t } = useTranslation("clients");
const { register } = useFormContext<KeyStoreConfig>();
return ( return (
<> <>
<FormGroup <FormGroup
label={t("keyAlias")} label={t("keyAlias")}
fieldId="keyAlias" fieldId="keyAlias"
isRequired
labelIcon={ labelIcon={
<HelpItem <HelpItem
helpText="clients-help:keyAlias" helpText="clients-help:keyAlias"
@ -31,13 +33,14 @@ export const StoreSettings = ({
type="text" type="text"
id="keyAlias" id="keyAlias"
name="keyAlias" name="keyAlias"
ref={register} ref={register({ required: true })}
/> />
</FormGroup> </FormGroup>
{!hidePassword && ( {!hidePassword && (
<FormGroup <FormGroup
label={t("keyPassword")} label={t("keyPassword")}
fieldId="keyPassword" fieldId="keyPassword"
isRequired
labelIcon={ labelIcon={
<HelpItem <HelpItem
helpText="clients-help:keyPassword" helpText="clients-help:keyPassword"
@ -49,13 +52,14 @@ export const StoreSettings = ({
data-testid="keyPassword" data-testid="keyPassword"
id="keyPassword" id="keyPassword"
name="keyPassword" name="keyPassword"
ref={register} ref={register({ required: true })}
/> />
</FormGroup> </FormGroup>
)} )}
<FormGroup <FormGroup
label={t("storePassword")} label={t("storePassword")}
fieldId="storePassword" fieldId="storePassword"
isRequired
labelIcon={ labelIcon={
<HelpItem <HelpItem
helpText="clients-help:storePassword" helpText="clients-help:storePassword"
@ -67,7 +71,7 @@ export const StoreSettings = ({
data-testid="storePassword" data-testid="storePassword"
id="storePassword" id="storePassword"
name="storePassword" name="storePassword"
ref={register} ref={register({ required: true })}
/> />
</FormGroup> </FormGroup>
</> </>