Repository: provectus/kafka-ui
Issue: Entering the same parameter multiple times during Topic's creation
Labels: type/bug
good first issue
scope/frontend
status/accepted
status/confirmed

**Describe the bug**
<!--(A clear and concise description of what the bug is.)-->
You can enter different value for the same parameter of a topic. 

**Set up**
<!--
(How do you run the app? 
Which version of the app are you running? Provide either docker image version or check commit hash at the top left corner. We won't be able to help you without this information.)
-->
https://www.kafka-ui.provectus.io/

**Steps to Reproduce**
Steps to reproduce the behavior:

1. Navigate to local->Topics
2. Push the button Create Topic
3. Push the button Add custom parameter
4. Choose 1 of parameters, input it`s value
5. Choose the same parameter again, enter another value
6. Input the Topic name 
7. Push the button Submit
8. Navigate to the created topic-> Settings
9. Observe: the last value of parameter has saved

**Expected behavior**
<!--
(A clear and concise description of what you expected to happen)
-->
Warning message that this parameter exists for the topic or unavailable parameter in the dropdown selector
**Screenshots**
<!--
(If applicable, add screenshots to help explain your problem)
-->


**Additional context**
<!--
(Add any other context about the problem here)
-->


Issue comments:

Pull request review comments:
Can we move this condition inside updateSelectedOption method?
Oops, I missed it. Definitely. Fixed it 👍.

Patch that resolved the issue:
diff --git a/kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx b/kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx
index 5984247a753..d56bd50d54e 100644
--- a/kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx
+++ b/kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx
@@ -39,6 +39,14 @@ const CustomParamField: React.FC<Props> = ({
   const nameValue = watch(`customParams.${index}.name`);
   const prevName = useRef(nameValue);
 
+  const options = Object.keys(TOPIC_CUSTOM_PARAMS)
+    .sort()
+    .map((option) => ({
+      value: option,
+      label: option,
+      disabled: existingFields.includes(option),
+    }));
+
   React.useEffect(() => {
     if (nameValue !== prevName.current) {
       let newExistingFields = [...existingFields];
@@ -72,13 +80,7 @@ const CustomParamField: React.FC<Props> = ({
               minWidth="270px"
               onChange={onChange}
               value={value}
-              options={Object.keys(TOPIC_CUSTOM_PARAMS)
-                .sort()
-                .map((opt) => ({
-                  value: opt,
-                  label: opt,
-                  disabled: existingFields.includes(opt),
-                }))}
+              options={options}
             />
           )}
         />
diff --git a/kafka-ui-react-app/src/components/common/Select/Select.styled.ts b/kafka-ui-react-app/src/components/common/Select/Select.styled.ts
index 936a4786e38..cf70423295c 100644
--- a/kafka-ui-react-app/src/components/common/Select/Select.styled.ts
+++ b/kafka-ui-react-app/src/components/common/Select/Select.styled.ts
@@ -94,9 +94,12 @@ export const Option = styled.li<OptionProps>`
   transition: all 0.2s ease-in-out;
   cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')};
   gap: 5px;
+  color: ${(props) =>
+    props.theme.select.color[props.disabled ? 'disabled' : 'normal']};
 
   &:hover {
-    background-color: ${(props) => props.theme.select.backgroundColor.hover};
+    background-color: ${(props) =>
+      props.theme.select.backgroundColor[props.disabled ? 'normal' : 'hover']};
   }
 
   &:active {
diff --git a/kafka-ui-react-app/src/components/common/Select/Select.tsx b/kafka-ui-react-app/src/components/common/Select/Select.tsx
index ae9824e2914..d9c56ebdab2 100644
--- a/kafka-ui-react-app/src/components/common/Select/Select.tsx
+++ b/kafka-ui-react-app/src/components/common/Select/Select.tsx
@@ -48,12 +48,17 @@ const Select: React.FC<SelectProps> = ({
   useClickOutside(selectContainerRef, clickOutsideHandler);
 
   const updateSelectedOption = (option: SelectOption) => {
-    if (disabled) return;
+    if (!option.disabled) {
+      setSelectedOption(option.value);
 
-    setSelectedOption(option.value);
-    if (onChange) onChange(option.value);
-    setShowOptions(false);
+      if (onChange) {
+        onChange(option.value);
+      }
+
+      setShowOptions(false);
+    }
   };
+
   React.useEffect(() => {
     setSelectedOption(value);
   }, [isLive, value]);
diff --git a/kafka-ui-react-app/src/components/common/Select/__tests__/Select.spec.tsx b/kafka-ui-react-app/src/components/common/Select/__tests__/Select.spec.tsx
index 5ace7a28460..dd433b991c8 100644
--- a/kafka-ui-react-app/src/components/common/Select/__tests__/Select.spec.tsx
+++ b/kafka-ui-react-app/src/components/common/Select/__tests__/Select.spec.tsx
@@ -1,4 +1,7 @@
-import Select, { SelectProps } from 'components/common/Select/Select';
+import Select, {
+  SelectOption,
+  SelectProps,
+} from 'components/common/Select/Select';
 import React from 'react';
 import { render } from 'lib/testHelpers';
 import { screen } from '@testing-library/react';
@@ -10,34 +13,54 @@ jest.mock('react-hook-form', () => ({
   }),
 }));
 
-const options = [
-  { label: 'test-label1', value: 'test-value1' },
-  { label: 'test-label2', value: 'test-value2' },
+const options: Array<SelectOption> = [
+  { label: 'test-label1', value: 'test-value1', disabled: false },
+  { label: 'test-label2', value: 'test-value2', disabled: true },
 ];
 
 const renderComponent = (props?: Partial<SelectProps>) =>
   render(<Select name="test" {...props} />);
 
 describe('Custom Select', () => {
-  it('renders component', () => {
-    renderComponent();
-    expect(screen.getByRole('listbox')).toBeInTheDocument();
-  });
-  it('show select options when select is being clicked', () => {
-    renderComponent({
-      options,
+  describe('when isLive is not specified', () => {
+    beforeEach(() => {
+      renderComponent({
+        options,
+      });
     });
-    expect(screen.getByRole('option')).toBeInTheDocument();
-    userEvent.click(screen.getByRole('listbox'));
-    expect(screen.getAllByRole('option')).toHaveLength(3);
-  });
-  it('checking select option change', () => {
-    renderComponent({
-      options,
+
+    it('renders component', () => {
+      expect(screen.getByRole('listbox')).toBeInTheDocument();
+    });
+
+    it('show select options when select is being clicked', () => {
+      expect(screen.getByRole('option')).toBeInTheDocument();
+      userEvent.click(screen.getByRole('listbox'));
+      expect(screen.getAllByRole('option')).toHaveLength(3);
+    });
+
+    it('checking select option change', () => {
+      const listbox = screen.getByRole('listbox');
+      const optionLabel = 'test-label1';
+
+      userEvent.click(listbox);
+      userEvent.selectOptions(listbox, [optionLabel]);
+
+      expect(screen.getByRole('option')).toHaveTextContent(optionLabel);
+    });
+
+    it('trying to select disabled option does not trigger change', () => {
+      const listbox = screen.getByRole('listbox');
+      const normalOptionLabel = 'test-label1';
+      const disabledOptionLabel = 'test-label2';
+
+      userEvent.click(listbox);
+      userEvent.selectOptions(listbox, [normalOptionLabel]);
+      userEvent.click(listbox);
+      userEvent.selectOptions(listbox, [disabledOptionLabel]);
+
+      expect(screen.getByRole('option')).toHaveTextContent(normalOptionLabel);
     });
-    userEvent.click(screen.getByRole('listbox'));
-    userEvent.selectOptions(screen.getByRole('listbox'), ['test-label1']);
-    expect(screen.getByRole('option')).toHaveTextContent('test-label1');
   });
 
   describe('when non-live', () => {


Test patch: