Convert string value to number (#3925)

This commit is contained in:
Erik Jan de Wit 2022-12-07 04:06:01 -05:00 committed by GitHub
parent d9e44202d4
commit 998b111d6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 24 deletions

View file

@ -1,6 +1,3 @@
import { useEffect, useMemo, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { import {
ActionGroup, ActionGroup,
AlertVariant, AlertVariant,
@ -20,16 +17,19 @@ import {
ToolbarItem, ToolbarItem,
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import { PlusCircleIcon } from "@patternfly/react-icons"; import { PlusCircleIcon } from "@patternfly/react-icons";
import { useEffect, useMemo, useState } from "react";
import { FormProvider, useForm } from "react-hook-form-v7";
import { useTranslation } from "react-i18next";
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
import type PasswordPolicyTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/passwordPolicyTypeRepresentation"; import type PasswordPolicyTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/passwordPolicyTypeRepresentation";
import { useServerInfo } from "../../context/server-info/ServerInfoProvider"; import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form-access/FormAccess"; import { FormAccess } from "../../components/form-access/FormAccess";
import { useAdminClient } from "../../context/auth/AdminClient"; import { useAdminClient } from "../../context/auth/AdminClient";
import { useRealm } from "../../context/realm-context/RealmContext"; import { useRealm } from "../../context/realm-context/RealmContext";
import { useAlerts } from "../../components/alert/Alerts"; import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
import { parsePolicy, SubmittedValues, serializePolicy } from "./util";
import { PolicyRow } from "./PolicyRow"; import { PolicyRow } from "./PolicyRow";
import { parsePolicy, serializePolicy, SubmittedValues } from "./util";
type PolicySelectProps = { type PolicySelectProps = {
onSelect: (row: PasswordPolicyTypeRepresentation) => void; onSelect: (row: PasswordPolicyTypeRepresentation) => void;
@ -87,16 +87,27 @@ export const PasswordPolicy = ({
const { realm: realmName } = useRealm(); const { realm: realmName } = useRealm();
const [rows, setRows] = useState<PasswordPolicyTypeRepresentation[]>([]); const [rows, setRows] = useState<PasswordPolicyTypeRepresentation[]>([]);
const onSelect = (row: PasswordPolicyTypeRepresentation) => const onSelect = (row: PasswordPolicyTypeRepresentation) => {
setRows([...rows, row]); setRows([...rows, row]);
setValue(row.id!, row.defaultValue!, { shouldDirty: true });
};
const form = useForm<SubmittedValues>({ shouldUnregister: false }); const form = useForm<SubmittedValues>({
const { handleSubmit, setValue, getValues } = form; defaultValues: {},
shouldUnregister: false,
});
const {
handleSubmit,
setValue,
reset,
formState: { isDirty },
} = form;
const setupForm = (realm: RealmRepresentation) => { const setupForm = (realm: RealmRepresentation) => {
reset();
const values = parsePolicy(realm.passwordPolicy || "", passwordPolicies!); const values = parsePolicy(realm.passwordPolicy || "", passwordPolicies!);
values.forEach((v) => { values.forEach((v) => {
setValue(v.id!, v.value); setValue(v.id!, v.value!);
}); });
setRows(values); setRows(values);
}; };
@ -142,7 +153,10 @@ export const PasswordPolicy = ({
<PolicyRow <PolicyRow
key={`${r.id}-${index}`} key={`${r.id}-${index}`}
policy={r} policy={r}
onRemove={(id) => setRows(rows.filter((r) => r.id !== id))} onRemove={(id) => {
setRows(rows.filter((r) => r.id !== id));
setValue(r.id!, "", { shouldDirty: true });
}}
/> />
))} ))}
<ActionGroup> <ActionGroup>
@ -150,10 +164,7 @@ export const PasswordPolicy = ({
data-testid="save" data-testid="save"
variant="primary" variant="primary"
type="submit" type="submit"
isDisabled={ isDisabled={!isDirty}
serializePolicy(rows, getValues()) ===
realm.passwordPolicy
}
> >
{t("common:save")} {t("common:save")}
</Button> </Button>

View file

@ -1,5 +1,4 @@
import { useTranslation } from "react-i18next"; import type PasswordPolicyTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/passwordPolicyTypeRepresentation";
import { Controller, useFormContext } from "react-hook-form";
import { import {
Button, Button,
FormGroup, FormGroup,
@ -10,10 +9,11 @@ import {
ValidatedOptions, ValidatedOptions,
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import { MinusCircleIcon } from "@patternfly/react-icons"; import { MinusCircleIcon } from "@patternfly/react-icons";
import type PasswordPolicyTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/passwordPolicyTypeRepresentation"; import { Controller, useFormContext } from "react-hook-form-v7";
import { useTranslation } from "react-i18next";
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
import { HelpItem } from "../../components/help-enabler/HelpItem"; import { HelpItem } from "../../components/help-enabler/HelpItem";
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
import "./policy-row.css"; import "./policy-row.css";
@ -32,6 +32,7 @@ export const PolicyRow = ({
register, register,
formState: { errors }, formState: { errors },
} = useFormContext(); } = useFormContext();
return ( return (
<FormGroup <FormGroup
label={displayName} label={displayName}
@ -54,8 +55,7 @@ export const PolicyRow = ({
<KeycloakTextInput <KeycloakTextInput
id={id} id={id}
data-testid={id} data-testid={id}
ref={register({ required: true })} {...register(id!, { required: true })}
name={id}
defaultValue={defaultValue} defaultValue={defaultValue}
validated={ validated={
errors[id!] ? ValidatedOptions.error : ValidatedOptions.default errors[id!] ? ValidatedOptions.error : ValidatedOptions.default
@ -67,10 +67,11 @@ export const PolicyRow = ({
name={id!} name={id!}
defaultValue={Number.parseInt(defaultValue || "0")} defaultValue={Number.parseInt(defaultValue || "0")}
control={control} control={control}
render={({ onChange, value }) => { render={({ field }) => {
const MIN_VALUE = 0; const MIN_VALUE = 0;
const setValue = (newValue: number) => const setValue = (newValue: number) =>
onChange(Math.max(newValue, MIN_VALUE)); field.onChange(Math.max(newValue, MIN_VALUE));
const value = Number(field.value);
return ( return (
<NumberInput <NumberInput