Inline component

This commit is contained in:
Fang-Pen Lin
2026-01-05 18:28:43 -08:00
parent 4a851b148a
commit c330ae450d
2 changed files with 61 additions and 72 deletions

View File

@@ -1,12 +1,12 @@
import { FormProvider, useForm } from "react-hook-form";
import { useEffect, useState } from "react";
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Button, ModalClose } from "@app/components/v2";
import { Button, FormControl, Input, ModalClose } from "@app/components/v2";
import { PamResourceType, TRedisAccount } from "@app/hooks/api/pam";
import { UNCHANGED_PASSWORD_SENTINEL } from "@app/hooks/api/pam/constants";
import { UsernamePasswordFields } from "./shared/UsernamePasswordFields";
import { GenericAccountFields, genericAccountFieldsSchema } from "./GenericAccountFields";
type Props = {
@@ -55,9 +55,19 @@ export const RedisAccountForm = ({ account, onSubmit }: Props) => {
const {
handleSubmit,
control,
formState: { isSubmitting, isDirty }
} = form;
const [showPassword, setShowPassword] = useState(false);
const password = useWatch({ control, name: "credentials.password" });
useEffect(() => {
if (password === UNCHANGED_PASSWORD_SENTINEL) {
setShowPassword(false);
}
}, [password]);
return (
<FormProvider {...form}>
<form
@@ -66,7 +76,54 @@ export const RedisAccountForm = ({ account, onSubmit }: Props) => {
}}
>
<GenericAccountFields />
<UsernamePasswordFields isUpdate={isUpdate} />
<div className="flex gap-2">
<Controller
name="credentials.username"
control={control}
render={({ field, fieldState: { error } }) => (
<FormControl
className="flex-1"
errorText={error?.message}
isError={Boolean(error?.message)}
label="Username"
isOptional
>
<Input {...field} autoComplete="off" />
</FormControl>
)}
/>
<Controller
name="credentials.password"
control={control}
render={({ field, fieldState: { error } }) => (
<FormControl
className="flex-1"
errorText={error?.message}
isError={Boolean(error?.message)}
label="Password"
isOptional
>
<Input
{...field}
type={showPassword ? "text" : "password"}
autoComplete="new-password"
onFocus={() => {
if (isUpdate && field.value === UNCHANGED_PASSWORD_SENTINEL) {
field.onChange("");
}
setShowPassword(true);
}}
onBlur={() => {
if (isUpdate && field.value === "") {
field.onChange(UNCHANGED_PASSWORD_SENTINEL);
}
setShowPassword(false);
}}
/>
</FormControl>
)}
/>
</div>
<div className="mt-6 flex items-center">
<Button
className="mr-4"

View File

@@ -1,68 +0,0 @@
import { useEffect, useState } from "react";
import { Controller, useFormContext, useWatch } from "react-hook-form";
import { FormControl, Input } from "@app/components/v2";
import { UNCHANGED_PASSWORD_SENTINEL } from "@app/hooks/api/pam/constants";
export const UsernamePasswordFields = ({ isUpdate }: { isUpdate: boolean }) => {
const { control } = useFormContext();
const [showPassword, setShowPassword] = useState(false);
const password = useWatch({ control, name: "credentials.password" });
useEffect(() => {
if (password === UNCHANGED_PASSWORD_SENTINEL) {
setShowPassword(false);
}
}, [password]);
return (
<div className="flex gap-2">
<Controller
name="credentials.username"
control={control}
render={({ field, fieldState: { error } }) => (
<FormControl
className="flex-1"
errorText={error?.message}
isError={Boolean(error?.message)}
label="Username"
isOptional
>
<Input {...field} autoComplete="off" />
</FormControl>
)}
/>
<Controller
name="credentials.password"
control={control}
render={({ field, fieldState: { error } }) => (
<FormControl
className="flex-1"
errorText={error?.message}
isError={Boolean(error?.message)}
label="Password"
isOptional
>
<Input
{...field}
type={showPassword ? "text" : "password"}
autoComplete="new-password"
onFocus={() => {
if (isUpdate && field.value === UNCHANGED_PASSWORD_SENTINEL) {
field.onChange("");
}
setShowPassword(true);
}}
onBlur={() => {
if (isUpdate && field.value === "") {
field.onChange(UNCHANGED_PASSWORD_SENTINEL);
}
setShowPassword(false);
}}
/>
</FormControl>
)}
/>
</div>
);
};