Skip to content

Commit

Permalink
migrated to use ui-shared
Browse files Browse the repository at this point in the history
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
  • Loading branch information
edewit committed Mar 13, 2024
1 parent 343479d commit 189e2cd
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@ import {
ActionGroup,
Button,
FormGroup,
NumberInput,
Select,
SelectOption,
SelectVariant,
} from "@patternfly/react-core";
import { useEffect, useState } from "react";
import { Controller, FormProvider, useForm } from "react-hook-form";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";

import { HelpItem, NumberControl } from "ui-shared";
import { FormAccess } from "../../components/form/FormAccess";
import { HelpItem } from "ui-shared";
import { convertToFormValues } from "../../util";
import { Time } from "./Time";

Expand All @@ -31,7 +29,6 @@ export const BruteForceDetection = ({
const {
setValue,
handleSubmit,
control,
formState: { isDirty },
} = form;

Expand Down Expand Up @@ -131,74 +128,26 @@ export const BruteForceDetection = ({
</FormGroup>
{bruteForceMode !== BruteForceMode.Disabled && (
<>
<FormGroup
<NumberControl
name="failureFactor"
label={t("failureFactor")}
labelIcon={
<HelpItem
helpText={t("failureFactorHelp")}
fieldLabelId="failureFactor"
/>
}
fieldId="failureFactor"
>
<Controller
name="failureFactor"
defaultValue={0}
control={control}
rules={{ required: true }}
render={({ field }) => (
<NumberInput
type="text"
id="failureFactor"
value={field.value}
onPlus={() => field.onChange(field.value + 1)}
onMinus={() => field.onChange(field.value - 1)}
onChange={(event) =>
field.onChange(
Number((event.target as HTMLInputElement).value),
)
}
/>
)}
/>
</FormGroup>

labelIcon={t("failureFactorHelp")}
controller={{
defaultValue: 0,
rules: { required: t("required") },
}}
/>
{bruteForceMode ===
BruteForceMode.PermanentAfterTemporaryLockout && (
<FormGroup
<NumberControl
name="maxTemporaryLockouts"
label={t("maxTemporaryLockouts")}
labelIcon={
<HelpItem
helpText={t("maxTemporaryLockoutsHelp")}
fieldLabelId="maxTemporaryLockouts"
/>
}
fieldId="maxTemporaryLockouts"
hasNoPaddingTop
>
<Controller
name="maxTemporaryLockouts"
defaultValue={0}
control={control}
render={({ field }) => (
<NumberInput
type="text"
id="maxTemporaryLockouts"
value={field.value}
onPlus={() => field.onChange(field.value + 1)}
onMinus={() => field.onChange(field.value - 1)}
onChange={(event) =>
field.onChange(
Number((event.target as HTMLInputElement).value),
)
}
aria-label={t("maxTemporaryLockouts")}
/>
)}
/>
</FormGroup>
labelIcon={t("maxTemporaryLockoutsHelp")}
controller={{
defaultValue: 0,
}}
/>
)}

{(bruteForceMode === BruteForceMode.TemporaryLockout ||
bruteForceMode ===
BruteForceMode.PermanentAfterTemporaryLockout) && (
Expand All @@ -208,38 +157,14 @@ export const BruteForceDetection = ({
<Time name="maxDeltaTimeSeconds" />
</>
)}

<FormGroup
<NumberControl
name="quickLoginCheckMilliSeconds"
label={t("quickLoginCheckMilliSeconds")}
labelIcon={
<HelpItem
helpText={t("quickLoginCheckMilliSecondsHelp")}
fieldLabelId="quickLoginCheckMilliSeconds"
/>
}
fieldId="quickLoginCheckMilliSeconds"
>
<Controller
name="quickLoginCheckMilliSeconds"
defaultValue={0}
control={control}
render={({ field }) => (
<NumberInput
type="text"
id="quickLoginCheckMilliSeconds"
value={field.value}
onPlus={() => field.onChange(field.value + 1)}
onMinus={() => field.onChange(field.value - 1)}
onChange={(event) =>
field.onChange(
Number((event.target as HTMLInputElement).value),
)
}
/>
)}
/>
</FormGroup>

labelIcon={t("quickLoginCheckMilliSecondsHelp")}
controller={{
defaultValue: 0,
}}
/>
<Time name="minimumQuickLoginWaitSeconds" />
</>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { FormGroup } from "@patternfly/react-core";
import { useFormContext } from "react-hook-form";
import { Trans, useTranslation } from "react-i18next";

import { TextControl } from "ui-shared";
import { FormattedLink } from "../../components/external-link/FormattedLink";
import { HelpItem } from "ui-shared";
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";

type HelpLinkTextInputProps = {
fieldName: string;
Expand All @@ -16,25 +12,17 @@ export const HelpLinkTextInput = ({
url,
}: HelpLinkTextInputProps) => {
const { t } = useTranslation();
const { register } = useFormContext();
const name = fieldName.substr(fieldName.indexOf(".") + 1);
return (
<FormGroup
<TextControl
name={fieldName}
label={t(name)}
fieldId={name}
labelIcon={
<HelpItem
helpText={
<Trans i18nKey={`${name}Help`}>
Default value prevents pages from being included
<FormattedLink href={url} title={t("learnMore")} />
</Trans>
}
fieldLabelId={name}
/>
<Trans i18nKey={`${name}Help`}>
Default value prevents pages from being included
<FormattedLink href={url} title={t("learnMore")} />
</Trans>
}
>
<KeycloakTextInput id={name} {...register(fieldName)} />
</FormGroup>
/>
);
};
42 changes: 9 additions & 33 deletions js/apps/admin-ui/src/realm-settings/security-defences/Time.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { FormGroup, ValidatedOptions } from "@patternfly/react-core";
import { CSSProperties } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";

import { HelpItem } from "ui-shared";
import { TimeSelector } from "../../components/time-selector/TimeSelector";
import { TimeSelectorControl } from "../../components/time-selector/TimeSelectorControl";

export const Time = ({
name,
Expand All @@ -14,37 +11,16 @@ export const Time = ({
style?: CSSProperties;
}) => {
const { t } = useTranslation();
const {
control,
formState: { errors },
} = useFormContext();
return (
<FormGroup
<TimeSelectorControl
name={name}
style={style}
label={t(name)}
fieldId={name}
labelIcon={<HelpItem helpText={t(`${name}Help`)} fieldLabelId={name} />}
validated={
errors[name] ? ValidatedOptions.error : ValidatedOptions.default
}
helperTextInvalid={t("required")}
>
<Controller
name={name}
defaultValue=""
control={control}
rules={{ required: true }}
render={({ field }) => (
<TimeSelector
data-testid={name}
value={field.value}
onChange={field.onChange}
validated={
errors[name] ? ValidatedOptions.error : ValidatedOptions.default
}
/>
)}
/>
</FormGroup>
labelIcon={t(`${name}Help`)}
controller={{
defaultValue: "",
rules: { required: t("required") },
}}
/>
);
};
4 changes: 2 additions & 2 deletions js/libs/ui-shared/src/controls/FormLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import {
FormGroupProps,
ValidatedOptions,
} from "@patternfly/react-core";
import { PropsWithChildren } from "react";
import { PropsWithChildren, ReactNode } from "react";
import { FieldError, FieldValues, Merge } from "react-hook-form";
import { HelpItem } from "./HelpItem";

export type FieldProps<T extends FieldValues = FieldValues> = {
label?: string;
name: string;
labelIcon?: string;
labelIcon?: string | ReactNode;
error?: FieldError | Merge<FieldError, T>;
isRequired: boolean;
};
Expand Down
3 changes: 2 additions & 1 deletion js/libs/ui-shared/src/controls/TextControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import {

import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
import { FormLabel } from "./FormLabel";
import { ReactNode } from "react";

export type TextControlProps<
T extends FieldValues,
P extends FieldPath<T> = FieldPath<T>,
> = UseControllerProps<T, P> &
Omit<TextInputProps, "name" | "isRequired" | "required"> & {
label: string;
labelIcon?: string;
labelIcon?: string | ReactNode;
isDisabled?: boolean;
helperText?: string;
};
Expand Down

0 comments on commit 189e2cd

Please sign in to comment.