Procházet zdrojové kódy

issue2724 add Controller wrapper for Input & Checkbox components

Nail Badiullin před 2 roky
rodič
revize
064ac3c691
20 změnil soubory, kde provedl 199 přidání a 153 odebrání
  1. 2 2
      kafka-ui-react-app/src/components/Connect/New/New.tsx
  2. 2 2
      kafka-ui-react-app/src/components/ConsumerGroups/Details/ResetOffsets/Form.tsx
  3. 5 3
      kafka-ui-react-app/src/components/KsqlDb/Query/QueryForm/QueryForm.tsx
  4. 3 3
      kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.tsx
  5. 2 2
      kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/AddEditFilterContainer.tsx
  6. 2 2
      kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx
  7. 18 18
      kafka-ui-react-app/src/components/common/Checkbox/Checkbox.tsx
  8. 15 0
      kafka-ui-react-app/src/components/common/Checkbox/ControlledCheckbox.tsx
  9. 21 0
      kafka-ui-react-app/src/components/common/Input/ControlledInput.tsx
  10. 92 84
      kafka-ui-react-app/src/components/common/Input/Input.tsx
  11. 11 11
      kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/Authentication/AuthenticationMethods.tsx
  12. 2 2
      kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/CustomAuthentication.tsx
  13. 2 2
      kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/KSQL.tsx
  14. 6 6
      kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/KafkaCluster.tsx
  15. 3 3
      kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/KafkaConnect.tsx
  16. 2 2
      kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/Metrics.tsx
  17. 2 2
      kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/SchemaRegistry.tsx
  18. 5 5
      kafka-ui-react-app/src/widgets/ClusterConfigForm/common/Credentials.tsx
  19. 2 2
      kafka-ui-react-app/src/widgets/ClusterConfigForm/common/Fileupload.tsx
  20. 2 2
      kafka-ui-react-app/src/widgets/ClusterConfigForm/common/SSLForm.tsx

+ 2 - 2
kafka-ui-react-app/src/components/Connect/New/New.tsx

@@ -13,7 +13,7 @@ import yup from 'lib/yupExtended';
 import Editor from 'components/common/Editor/Editor';
 import Select from 'components/common/Select/Select';
 import { FormError } from 'components/common/Input/Input.styled';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { Button } from 'components/common/Button/Button';
 import PageHeading from 'components/common/PageHeading/PageHeading';
 import Heading from 'components/common/heading/Heading.styled';
@@ -133,7 +133,7 @@ const New: React.FC = () => {
 
         <div>
           <Heading level={3}>Name</Heading>
-          <Input
+          <ControlledInput
             inputSize="M"
             placeholder="Connector Name"
             name="name"

+ 2 - 2
kafka-ui-react-app/src/components/ConsumerGroups/Details/ResetOffsets/Form.tsx

@@ -17,7 +17,7 @@ import 'react-datepicker/dist/react-datepicker.css';
 import { ErrorMessage } from '@hookform/error-message';
 import { InputLabel } from 'components/common/Input/InputLabel.styled';
 import { Button } from 'components/common/Button/Button';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { FormError } from 'components/common/Input/Input.styled';
 import useAppParams from 'lib/hooks/useAppParams';
 import { useResetConsumerGroupOffsetsMutation } from 'lib/hooks/api/consumers';
@@ -160,7 +160,7 @@ const Form: React.FC<FormProps> = ({ defaultValues, partitions, topics }) => {
             partitionsValue.length > 0 && (
               <S.OffsetsWrapper>
                 {fields.map((field, index) => (
-                  <Input
+                  <ControlledInput
                     key={field.id}
                     label={`Partition #${field.partition} Offset`}
                     type="number"

+ 5 - 3
kafka-ui-react-app/src/components/KsqlDb/Query/QueryForm/QueryForm.tsx

@@ -14,7 +14,7 @@ import { yupResolver } from '@hookform/resolvers/yup';
 import yup from 'lib/yupExtended';
 import PlusIcon from 'components/common/Icons/PlusIcon';
 import ReactAce from 'react-ace';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 
 import * as S from './QueryForm.styled';
 
@@ -156,14 +156,16 @@ const QueryForm: React.FC<QueryFormProps> = ({
               Stream properties:
               {fields.map((field, index) => (
                 <S.InputsContainer key={field.id}>
-                  <Input
+                  <ControlledInput
+                    control={control}
                     name={`streamsProperties.${index}.key`}
                     placeholder="Key"
                     type="text"
                     autoComplete="off"
                     withError
                   />
-                  <Input
+                  <ControlledInput
+                    control={control}
                     name={`streamsProperties.${index}.value`}
                     placeholder="Value"
                     type="text"

+ 3 - 3
kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.tsx

@@ -1,6 +1,6 @@
 import { ErrorMessage } from '@hookform/error-message';
 import { Button } from 'components/common/Button/Button';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { FormError } from 'components/common/Input/Input.styled';
 import { InputLabel } from 'components/common/Input/InputLabel.styled';
 import React from 'react';
@@ -99,7 +99,7 @@ const DangerZone: React.FC<DangerZoneProps> = ({
               <InputLabel htmlFor="partitions">
                 Number of partitions *
               </InputLabel>
-              <Input
+              <ControlledInput
                 inputSize="M"
                 type="number"
                 id="partitions"
@@ -139,7 +139,7 @@ const DangerZone: React.FC<DangerZoneProps> = ({
               <InputLabel htmlFor="replicationFactor">
                 Replication Factor *
               </InputLabel>
-              <Input
+              <ControlledInput
                 id="replicationFactor"
                 inputSize="M"
                 type="number"

+ 2 - 2
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/AddEditFilterContainer.tsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import * as S from 'components/Topics/Topic/Messages/Filters/Filters.styled';
 import { InputLabel } from 'components/common/Input/InputLabel.styled';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { FormProvider, Controller, useForm } from 'react-hook-form';
 import { ErrorMessage } from '@hookform/error-message';
 import { Button } from 'components/common/Button/Button';
@@ -96,7 +96,7 @@ const AddEditFilterContainer: React.FC<AddEditFilterContainerProps> = ({
         )}
         <div>
           <InputLabel>Display name</InputLabel>
-          <Input
+          <ControlledInput
             inputSize="M"
             placeholder="Enter Name"
             autoComplete="off"

+ 2 - 2
kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx

@@ -6,7 +6,7 @@ import { TopicConfigParams, TopicFormData } from 'redux/interfaces';
 import { InputLabel } from 'components/common/Input/InputLabel.styled';
 import { FormError } from 'components/common/Input/Input.styled';
 import Select from 'components/common/Select/Select';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
 import CloseIcon from 'components/common/Icons/CloseIcon';
 import * as C from 'components/Topics/shared/Form/TopicForm.styled';
@@ -99,7 +99,7 @@ const CustomParamField: React.FC<Props> = ({
       </div>
       <div>
         <InputLabel>Value *</InputLabel>
-        <Input
+        <ControlledInput
           name={`customParams.${index}.value` as const}
           hookFormOptions={{
             required: 'Value is required.',

+ 18 - 18
kafka-ui-react-app/src/components/common/Checkbox/Checkbox.tsx

@@ -1,30 +1,30 @@
 import * as React from 'react';
-import { useFormContext } from 'react-hook-form';
 import { InputLabel } from 'components/common/Input/InputLabel.styled';
 import { FormError, InputHint } from 'components/common/Input/Input.styled';
 import { ErrorMessage } from '@hookform/error-message';
 
-interface CheckboxProps {
+export interface CheckboxProps {
   name: string;
   label: React.ReactNode;
   hint?: string;
+  onChange?: (event: React.SyntheticEvent<HTMLInputElement>) => void;
 }
 
-const Checkbox: React.FC<CheckboxProps> = ({ name, label, hint }) => {
-  const { register } = useFormContext();
-
-  return (
-    <div>
-      <InputLabel>
-        <input {...register(name)} type="checkbox" />
-        {label}
-      </InputLabel>
-      <InputHint>{hint}</InputHint>
-      <FormError>
-        <ErrorMessage name={name} />
-      </FormError>
-    </div>
-  );
-};
+const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
+  ({ name, label, hint, onChange }, ref) => {
+    return (
+      <div>
+        <InputLabel>
+          <input type="checkbox" ref={ref} onChange={onChange} />
+          {label}
+        </InputLabel>
+        <InputHint>{hint}</InputHint>
+        <FormError>
+          <ErrorMessage name={name} />
+        </FormError>
+      </div>
+    );
+  }
+);
 
 export default Checkbox;

+ 15 - 0
kafka-ui-react-app/src/components/common/Checkbox/ControlledCheckbox.tsx

@@ -0,0 +1,15 @@
+import React from 'react';
+import { Controller } from 'react-hook-form';
+
+import Checkbox, { CheckboxProps } from './Checkbox';
+
+const ControlledCheckbox = ({ name, label, hint }: CheckboxProps) => {
+  return (
+    <Controller
+      name={name}
+      render={({ field }) => <Checkbox label={label} hint={hint} {...field} />}
+    />
+  );
+};
+
+export default ControlledCheckbox;

+ 21 - 0
kafka-ui-react-app/src/components/common/Input/ControlledInput.tsx

@@ -0,0 +1,21 @@
+import React from 'react';
+import { Controller } from 'react-hook-form';
+
+import Input, { InputProps } from './Input';
+
+const ControlledInput = ({
+  name,
+  control,
+  ...restProps
+}: // eslint-disable-next-line @typescript-eslint/no-explicit-any
+InputProps & { control: any }) => {
+  return (
+    <Controller
+      control={control}
+      name={name ?? ''}
+      render={({ field }) => <Input {...restProps} {...field} />}
+    />
+  );
+};
+
+export default ControlledInput;

+ 92 - 84
kafka-ui-react-app/src/components/common/Input/Input.tsx

@@ -99,99 +99,107 @@ function pasteNumberCheck(
   return value;
 }
 
-const Input: React.FC<InputProps> = ({
-  name,
-  hookFormOptions,
-  search,
-  inputSize = 'L',
-  type,
-  positiveOnly,
-  integerOnly,
-  withError = false,
-  label,
-  hint,
-  ...rest
-}) => {
-  const methods = useFormContext();
+const Input = React.forwardRef<HTMLInputElement, InputProps>(
+  (
+    {
+      name,
+      hookFormOptions,
+      search,
+      inputSize = 'L',
+      type,
+      positiveOnly,
+      integerOnly,
+      withError = false,
+      label,
+      hint,
+      ...rest
+    },
+    ref
+  ) => {
+    const methods = useFormContext();
 
-  const fieldId = React.useId();
+    const fieldId = React.useId();
 
-  const isHookFormField = !!name && !!methods.register;
+    const isHookFormField = !!name && !!methods.register;
 
-  const keyPressEventHandler = (
-    event: React.KeyboardEvent<HTMLInputElement>
-  ) => {
-    const { key } = event;
-    if (type === 'number') {
-      // Manually prevent input of non-digit and non-minus for all number inputs
-      // and prevent input of negative numbers for positiveOnly inputs
-      if (
-        !inputNumberCheck(
-          key,
-          typeof positiveOnly === 'boolean' ? positiveOnly : false,
-          typeof integerOnly === 'boolean' ? integerOnly : false,
-          methods.getValues,
-          typeof name === 'string' ? name : ''
-        )
-      ) {
-        event.preventDefault();
+    const keyPressEventHandler = (
+      event: React.KeyboardEvent<HTMLInputElement>
+    ) => {
+      const { key } = event;
+      if (type === 'number') {
+        // Manually prevent input of non-digit and non-minus for all number inputs
+        // and prevent input of negative numbers for positiveOnly inputs
+        if (
+          !inputNumberCheck(
+            key,
+            typeof positiveOnly === 'boolean' ? positiveOnly : false,
+            typeof integerOnly === 'boolean' ? integerOnly : false,
+            methods.getValues,
+            typeof name === 'string' ? name : ''
+          )
+        ) {
+          event.preventDefault();
+        }
       }
-    }
-  };
-  const pasteEventHandler = (event: React.ClipboardEvent<HTMLInputElement>) => {
-    if (type === 'number') {
-      const { clipboardData } = event;
-      // The 'clipboardData' does not have key 'Text', but has key 'text' instead.
-      const text = clipboardData.getData('text');
-      // Check the format of pasted text.
-      const value = pasteNumberCheck(
-        text,
-        typeof positiveOnly === 'boolean' ? positiveOnly : false,
-        typeof integerOnly === 'boolean' ? integerOnly : false
-      );
-      // if paste value contains non-numeric characters or
-      // negative for positiveOnly fields then prevent paste
-      if (value !== text) {
-        event.preventDefault();
+    };
+    const pasteEventHandler = (
+      event: React.ClipboardEvent<HTMLInputElement>
+    ) => {
+      if (type === 'number') {
+        const { clipboardData } = event;
+        // The 'clipboardData' does not have key 'Text', but has key 'text' instead.
+        const text = clipboardData.getData('text');
+        // Check the format of pasted text.
+        const value = pasteNumberCheck(
+          text,
+          typeof positiveOnly === 'boolean' ? positiveOnly : false,
+          typeof integerOnly === 'boolean' ? integerOnly : false
+        );
+        // if paste value contains non-numeric characters or
+        // negative for positiveOnly fields then prevent paste
+        if (value !== text) {
+          event.preventDefault();
 
-        // for react-hook-form fields only set transformed value
-        if (isHookFormField) {
-          methods.setValue(name, value);
+          // for react-hook-form fields only set transformed value
+          if (isHookFormField) {
+            methods.setValue(name, value);
+          }
         }
       }
+    };
+
+    let inputOptions = { ...rest };
+    if (isHookFormField) {
+      // extend input options with react-hook-form options
+      // if the field is a part of react-hook-form form
+      inputOptions = { ...rest, ...methods.register(name, hookFormOptions) };
     }
-  };
 
-  let inputOptions = { ...rest };
-  if (isHookFormField) {
-    // extend input options with react-hook-form options
-    // if the field is a part of react-hook-form form
-    inputOptions = { ...rest, ...methods.register(name, hookFormOptions) };
+    return (
+      <div>
+        {label && <InputLabel htmlFor={rest.id || fieldId}>{label}</InputLabel>}
+        <S.Wrapper>
+          {search && <SearchIcon />}
+          <S.Input
+            id={fieldId}
+            inputSize={inputSize}
+            search={!!search}
+            type={type}
+            onKeyPress={keyPressEventHandler}
+            onPaste={pasteEventHandler}
+            ref={ref}
+            {...inputOptions}
+          />
+          {withError && isHookFormField && (
+            <S.FormError>
+              <ErrorMessage name={name} />
+            </S.FormError>
+          )}
+          {hint && <S.InputHint>{hint}</S.InputHint>}
+        </S.Wrapper>
+      </div>
+    );
   }
-
-  return (
-    <div>
-      {label && <InputLabel htmlFor={rest.id || fieldId}>{label}</InputLabel>}
-      <S.Wrapper>
-        {search && <SearchIcon />}
-        <S.Input
-          id={fieldId}
-          inputSize={inputSize}
-          search={!!search}
-          type={type}
-          onKeyPress={keyPressEventHandler}
-          onPaste={pasteEventHandler}
-          {...inputOptions}
-        />
-        {withError && isHookFormField && (
-          <S.FormError>
-            <ErrorMessage name={name} />
-          </S.FormError>
-        )}
-        {hint && <S.InputHint>{hint}</S.InputHint>}
-      </S.Wrapper>
-    </div>
-  );
-};
+);
 
 export default Input;

+ 11 - 11
kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/Authentication/AuthenticationMethods.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
-import Input from 'components/common/Input/Input';
-import Checkbox from 'components/common/Checkbox/Checkbox';
+import ControlledInput from 'components/common/Input/ControlledInput';
+import ControlledCheckbox from 'components/common/Checkbox/ControlledCheckbox';
 import Fileupload from 'widgets/ClusterConfigForm/common/Fileupload';
 import SSLForm from 'widgets/ClusterConfigForm/common/SSLForm';
 import Credentials from 'widgets/ClusterConfigForm/common/Credentials';
@@ -10,13 +10,13 @@ const AuthenticationMethods: React.FC<{ method: string }> = ({ method }) => {
     case 'SASL/JAAS':
       return (
         <>
-          <Input
+          <ControlledInput
             type="text"
             name="auth.props.saslJaasConfig"
             label="sasl.jaas.config"
             withError
           />
-          <Input
+          <ControlledInput
             type="text"
             name="auth.props.saslMechanism"
             label="sasl.mechanism"
@@ -27,15 +27,15 @@ const AuthenticationMethods: React.FC<{ method: string }> = ({ method }) => {
     case 'SASL/GSSAPI':
       return (
         <>
-          <Input
+          <ControlledInput
             label="Kerberos service name"
             type="text"
             name="auth.props.saslKerberosServiceName"
             withError
           />
-          <Checkbox name="auth.props.storeKey" label="Store Key" />
+          <ControlledCheckbox name="auth.props.storeKey" label="Store Key" />
           <Fileupload name="auth.props.keyTabFile" label="Key Tab (optional)" />
-          <Input
+          <ControlledInput
             type="text"
             name="auth.props.principal"
             label="Principal *"
@@ -45,7 +45,7 @@ const AuthenticationMethods: React.FC<{ method: string }> = ({ method }) => {
       );
     case 'SASL/OAUTHBEARER':
       return (
-        <Input
+        <ControlledInput
           label="Unsecured Login String Claim_sub *"
           type="text"
           name="auth.props.unsecuredLoginStringClaim_sub"
@@ -60,13 +60,13 @@ const AuthenticationMethods: React.FC<{ method: string }> = ({ method }) => {
     case 'Delegation tokens':
       return (
         <>
-          <Input
+          <ControlledInput
             label="Token Id"
             type="text"
             name="auth.props.tokenId"
             withError
           />
-          <Input
+          <ControlledInput
             label="Token Value *"
             type="text"
             name="auth.props.tokenValue"
@@ -76,7 +76,7 @@ const AuthenticationMethods: React.FC<{ method: string }> = ({ method }) => {
       );
     case 'SASL/AWS IAM':
       return (
-        <Input
+        <ControlledInput
           label="AWS Profile Name"
           type="text"
           name="auth.props.awsProfileName"

+ 2 - 2
kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/CustomAuthentication.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import { useFormContext } from 'react-hook-form';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { convertFormKeyToPropsKey } from 'widgets/ClusterConfigForm/utils/convertFormKeyToPropsKey';
 import SectionHeader from 'widgets/ClusterConfigForm/common/SectionHeader';
 
@@ -26,7 +26,7 @@ const CustomAuthentication: React.FC = () => {
       {hasCustomConfig && (
         <>
           {Object.keys(customConf).map((key) => (
-            <Input
+            <ControlledInput
               key={key}
               type="text"
               name={`customAuth.${key}`}

+ 2 - 2
kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/KSQL.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
-import Input from 'components/common/Input/Input';
+import ControlledInput from "../../../components/common/Input/ControlledInput";
 import { useFormContext } from 'react-hook-form';
 import SectionHeader from 'widgets/ClusterConfigForm/common/SectionHeader';
 import SSLForm from 'widgets/ClusterConfigForm/common/SSLForm';
@@ -25,7 +25,7 @@ const KSQL = () => {
       />
       {ksql && (
         <>
-          <Input
+          <ControlledInput
             label="URL *"
             name="ksql.url"
             type="text"

+ 6 - 6
kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/KafkaCluster.tsx

@@ -1,5 +1,4 @@
 import React from 'react';
-import Input from 'components/common/Input/Input';
 import { useFieldArray, useFormContext } from 'react-hook-form';
 import { FormError, InputHint } from 'components/common/Input/Input.styled';
 import { ErrorMessage } from '@hookform/error-message';
@@ -9,9 +8,10 @@ import PlusIcon from 'components/common/Icons/PlusIcon';
 import * as S from 'widgets/ClusterConfigForm/ClusterConfigForm.styled';
 import Heading from 'components/common/heading/Heading.styled';
 import { InputLabel } from 'components/common/Input/InputLabel.styled';
-import Checkbox from 'components/common/Checkbox/Checkbox';
+import ControlledCheckbox from 'components/common/Checkbox/ControlledCheckbox';
 import SectionHeader from 'widgets/ClusterConfigForm/common/SectionHeader';
 import SSLForm from 'widgets/ClusterConfigForm/common/SSLForm';
+import ControlledInput from 'components/common/Input/ControlledInput';
 
 const KafkaCluster: React.FC = () => {
   const { control, watch, setValue } = useFormContext();
@@ -38,14 +38,14 @@ const KafkaCluster: React.FC = () => {
   return (
     <>
       <Heading level={3}>Kafka Cluster</Heading>
-      <Input
+      <ControlledInput
         label="Cluster name *"
         type="text"
         name="name"
         withError
         hint="this name will help you recognize the cluster in the application interface"
       />
-      <Checkbox
+      <ControlledCheckbox
         name="readOnly"
         label="Read-only mode"
         hint="allows you to run an application in read-only mode for a specific cluster"
@@ -59,7 +59,7 @@ const KafkaCluster: React.FC = () => {
           {fields.map((field, index) => (
             <S.BootstrapServer key={field.id}>
               <div>
-                <Input
+                <ControlledInput
                   name={`bootstrapServers.${index}.host`}
                   placeholder="Host"
                   type="text"
@@ -68,7 +68,7 @@ const KafkaCluster: React.FC = () => {
                 />
               </div>
               <div>
-                <Input
+                <ControlledInput
                   name={`bootstrapServers.${index}.port`}
                   placeholder="Port"
                   type="number"

+ 3 - 3
kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/KafkaConnect.tsx

@@ -1,7 +1,7 @@
 import * as React from 'react';
 import * as S from 'widgets/ClusterConfigForm/ClusterConfigForm.styled';
 import { Button } from 'components/common/Button/Button';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { useFieldArray, useFormContext } from 'react-hook-form';
 import PlusIcon from 'components/common/Icons/PlusIcon';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
@@ -39,7 +39,7 @@ const KafkaConnect = () => {
             <div key={item.id}>
               <FlexRow>
                 <FlexGrow1>
-                  <Input
+                  <ControlledInput
                     label="Kafka Connect name *"
                     name={`kafkaConnect.${index}.name`}
                     placeholder="Name"
@@ -47,7 +47,7 @@ const KafkaConnect = () => {
                     hint="Given name for the Kafka Connect cluster"
                     withError
                   />
-                  <Input
+                  <ControlledInput
                     label="Kafka Connect URL *"
                     name={`kafkaConnect.${index}.address`}
                     placeholder="URl"

+ 2 - 2
kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/Metrics.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { useFormContext } from 'react-hook-form';
 import ControlledSelect from 'components/common/Select/ControlledSelect';
 import { METRICS_OPTIONS } from 'lib/constants';
@@ -41,7 +41,7 @@ const Metrics = () => {
             options={METRICS_OPTIONS}
           />
           <S.Port>
-            <Input
+            <ControlledInput
               label="Port *"
               name="metrics.port"
               type="number"

+ 2 - 2
kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/SchemaRegistry.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { useFormContext } from 'react-hook-form';
 import SectionHeader from 'widgets/ClusterConfigForm/common/SectionHeader';
 import SSLForm from 'widgets/ClusterConfigForm/common/SSLForm';
@@ -25,7 +25,7 @@ const SchemaRegistry = () => {
       />
       {schemaRegistry && (
         <>
-          <Input
+          <ControlledInput
             label="URL *"
             name="schemaRegistry.url"
             type="text"

+ 5 - 5
kafka-ui-react-app/src/widgets/ClusterConfigForm/common/Credentials.tsx

@@ -1,7 +1,7 @@
 import * as React from 'react';
-import Input from 'components/common/Input/Input';
 import * as S from 'widgets/ClusterConfigForm/ClusterConfigForm.styled';
-import Checkbox from 'components/common/Checkbox/Checkbox';
+import ControlledCheckbox from 'components/common/Checkbox/ControlledCheckbox';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { useFormContext } from 'react-hook-form';
 
 type CredentialsProps = {
@@ -17,11 +17,11 @@ const Credentials: React.FC<CredentialsProps> = ({
 
   return (
     <S.GroupFieldWrapper>
-      <Checkbox name={`${prefix}.isAuth`} label={title} />
+      <ControlledCheckbox name={`${prefix}.isAuth`} label={title} />
       {watch(`${prefix}.isAuth`) && (
         <S.FlexRow>
           <S.FlexGrow1>
-            <Input
+            <ControlledInput
               label="Username *"
               type="text"
               name={`${prefix}.username`}
@@ -29,7 +29,7 @@ const Credentials: React.FC<CredentialsProps> = ({
             />
           </S.FlexGrow1>
           <S.FlexGrow1>
-            <Input
+            <ControlledInput
               label="Password *"
               type="password"
               name={`${prefix}.password`}

+ 2 - 2
kafka-ui-react-app/src/widgets/ClusterConfigForm/common/Fileupload.tsx

@@ -3,7 +3,7 @@ import { FormError } from 'components/common/Input/Input.styled';
 import { InputLabel } from 'components/common/Input/InputLabel.styled';
 import { ErrorMessage } from '@hookform/error-message';
 import { useFormContext } from 'react-hook-form';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import { Button } from 'components/common/Button/Button';
 import * as S from 'widgets/ClusterConfigForm/ClusterConfigForm.styled';
 import { useAppConfigFilesUpload } from 'lib/hooks/api/appConfig';
@@ -42,7 +42,7 @@ const Fileupload: React.FC<{ name: string; label: string }> = ({
       {loc ? (
         <S.FlexRow>
           <S.FlexGrow1>
-            <Input name={name} disabled />
+            <ControlledInput name={name} disabled />
           </S.FlexGrow1>
           <Button buttonType="secondary" buttonSize="L" onClick={onReset}>
             Reset

+ 2 - 2
kafka-ui-react-app/src/widgets/ClusterConfigForm/common/SSLForm.tsx

@@ -1,5 +1,5 @@
 import * as React from 'react';
-import Input from 'components/common/Input/Input';
+import ControlledInput from 'components/common/Input/ControlledInput';
 import Fileupload from 'widgets/ClusterConfigForm/common/Fileupload';
 import * as S from 'widgets/ClusterConfigForm/ClusterConfigForm.styled';
 
@@ -12,7 +12,7 @@ const SSLForm: React.FC<SSLFormProps> = ({ prefix, title }) => {
   return (
     <S.GroupFieldWrapper>
       <Fileupload name={`${prefix}.location`} label={`${title} Location`} />
-      <Input
+      <ControlledInput
         label={`${title} Password`}
         name={`${prefix}.password`}
         type="password"