Browse Source

Merge branch 'master' into feat/kafka-ui-svc-lbip

Nicolas BOURON 2 years ago
parent
commit
6d5d736a9b
35 changed files with 511 additions and 196 deletions
  1. 1 1
      .github/workflows/aws_publisher.yaml
  2. 3 3
      .github/workflows/branch-deploy.yml
  3. 3 3
      .github/workflows/branch-remove.yml
  4. 3 3
      .github/workflows/master.yaml
  5. 3 3
      .github/workflows/separate_env_public_create.yml
  6. 3 3
      .github/workflows/separate_env_public_remove.yml
  7. 8 0
      kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/BasePage.java
  8. 68 5
      kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersConfigTab.java
  9. 2 7
      kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersDetails.java
  10. 8 8
      kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersList.java
  11. 50 8
      kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topics/TopicDetails.java
  12. 11 0
      kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topics/TopicsList.java
  13. 12 19
      kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/manualsuite/backlog/SmokeBacklog.java
  14. 32 1
      kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/smokesuite/brokers/BrokersTest.java
  15. 45 14
      kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/smokesuite/topics/TopicsTest.java
  16. 3 2
      kafka-ui-react-app/src/components/Dashboard/ClusterTableActionsCell.tsx
  17. 3 2
      kafka-ui-react-app/src/components/Dashboard/Dashboard.tsx
  18. 2 2
      kafka-ui-react-app/src/components/KsqlDb/Query/QueryForm/QueryForm.tsx
  19. 1 1
      kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/EditFilter.tsx
  20. 25 15
      kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/FilterModal.tsx
  21. 66 16
      kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/Filters.styled.ts
  22. 49 17
      kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/Filters.tsx
  23. 1 1
      kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/__tests__/EditFilter.spec.tsx
  24. 9 3
      kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/__tests__/FilterModal.spec.tsx
  25. 2 2
      kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx
  26. 11 3
      kafka-ui-react-app/src/components/Version/Version.tsx
  27. 2 2
      kafka-ui-react-app/src/components/common/Alert/Alert.tsx
  28. 24 0
      kafka-ui-react-app/src/components/common/Icons/CloseCircleIcon.tsx
  29. 9 9
      kafka-ui-react-app/src/components/common/Icons/CloseIcon.tsx
  30. 11 30
      kafka-ui-react-app/src/components/common/Icons/EditIcon.tsx
  31. 2 2
      kafka-ui-react-app/src/components/common/Search/Search.tsx
  32. 33 5
      kafka-ui-react-app/src/theme/theme.ts
  33. 2 2
      kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/KafkaCluster.tsx
  34. 2 2
      kafka-ui-react-app/src/widgets/ClusterConfigForm/Sections/KafkaConnect.tsx
  35. 2 2
      pom.xml

+ 1 - 1
.github/workflows/aws_publisher.yaml

@@ -24,7 +24,7 @@ jobs:
       - name: Clone infra repo
       - name: Clone infra repo
         run: |
         run: |
           echo "Cloning repo..."
           echo "Cloning repo..."
-          git clone https://kafka-ui-infra:${{ secrets.KAFKA_UI_INFRA_TOKEN }}@gitlab.provectus.com/provectus-internals/kafka-ui-infra.git --branch ${{ github.event.inputs.KafkaUIInfraBranch }}
+          git clone https://infra-tech:${{ secrets.INFRA_USER_ACCESS_TOKEN }}@github.com/provectus/kafka-ui-infra.git --branch ${{ github.event.inputs.KafkaUIInfraBranch }}
           echo "Cd to packer DIR..."
           echo "Cd to packer DIR..."
           cd kafka-ui-infra/ami
           cd kafka-ui-infra/ami
           echo "WORK_DIR=$(pwd)" >> $GITHUB_ENV
           echo "WORK_DIR=$(pwd)" >> $GITHUB_ENV

+ 3 - 3
.github/workflows/branch-deploy.yml

@@ -73,14 +73,14 @@ jobs:
     steps:
     steps:
       - name: clone
       - name: clone
         run: |
         run: |
-          git clone https://kafka-ui-infra:${{ secrets.KAFKA_UI_INFRA_TOKEN }}@gitlab.provectus.com/provectus-internals/kafka-ui-infra.git
+          git clone https://infra-tech:${{ secrets.INFRA_USER_ACCESS_TOKEN }}@github.com/provectus/kafka-ui-infra.git --branch envs
       - name: create deployment
       - name: create deployment
         run: |
         run: |
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           echo "Branch:${{ needs.build.outputs.tag }}"
           echo "Branch:${{ needs.build.outputs.tag }}"
           ./kafka-ui-deployment-from-branch.sh ${{ needs.build.outputs.tag }} ${{ github.event.label.name }} ${{ secrets.FEATURE_TESTING_UI_PASSWORD }}
           ./kafka-ui-deployment-from-branch.sh ${{ needs.build.outputs.tag }} ${{ github.event.label.name }} ${{ secrets.FEATURE_TESTING_UI_PASSWORD }}
-          git config --global user.email "kafka-ui-infra@provectus.com"
-          git config --global user.name "kafka-ui-infra"
+          git config --global user.email "infra-tech@provectus.com"
+          git config --global user.name "infra-tech"
           git add ../kafka-ui-from-branch/
           git add ../kafka-ui-from-branch/
           git commit -m "added env:${{ needs.build.outputs.deploy }}" && git push || true
           git commit -m "added env:${{ needs.build.outputs.deploy }}" && git push || true
 
 

+ 3 - 3
.github/workflows/branch-remove.yml

@@ -11,13 +11,13 @@ jobs:
       - uses: actions/checkout@v3
       - uses: actions/checkout@v3
       - name: clone
       - name: clone
         run: |
         run: |
-          git clone https://kafka-ui-infra:${{ secrets.KAFKA_UI_INFRA_TOKEN }}@gitlab.provectus.com/provectus-internals/kafka-ui-infra.git
+          git clone https://infra-tech:${{ secrets.INFRA_USER_ACCESS_TOKEN }}@github.com/provectus/kafka-ui-infra.git --branch envs
       - name: remove env
       - name: remove env
         run: |
         run: |
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           ./delete-env.sh pr${{ github.event.pull_request.number }} || true
           ./delete-env.sh pr${{ github.event.pull_request.number }} || true
-          git config --global user.email "kafka-ui-infra@provectus.com"
-          git config --global user.name "kafka-ui-infra"
+          git config --global user.email "infra-tech@provectus.com"
+          git config --global user.name "infra-tech"
           git add ../kafka-ui-from-branch/
           git add ../kafka-ui-from-branch/
           git commit -m "removed env:${{ needs.build.outputs.deploy }}" && git push || true
           git commit -m "removed env:${{ needs.build.outputs.deploy }}" && git push || true
       - name: make comment with deployment link
       - name: make comment with deployment link

+ 3 - 3
.github/workflows/master.yaml

@@ -73,11 +73,11 @@ jobs:
 #################################
 #################################
       - name: update-master-deployment
       - name: update-master-deployment
         run: |
         run: |
-          git clone https://kafka-ui-infra:${{ secrets.KAFKA_UI_INFRA_TOKEN }}@gitlab.provectus.com/provectus-internals/kafka-ui-infra.git --branch master
+          git clone https://infra-tech:${{ secrets.INFRA_USER_ACCESS_TOKEN }}@github.com/provectus/kafka-ui-infra.git --branch master
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           echo "Image digest is:${{ steps.docker_build_and_push.outputs.digest }}"
           echo "Image digest is:${{ steps.docker_build_and_push.outputs.digest }}"
           ./kafka-ui-update-master-digest.sh ${{ steps.docker_build_and_push.outputs.digest }}
           ./kafka-ui-update-master-digest.sh ${{ steps.docker_build_and_push.outputs.digest }}
-          git config --global user.email "kafka-ui-infra@provectus.com"
-          git config --global user.name "kafka-ui-infra"
+          git config --global user.email "infra-tech@provectus.com"
+          git config --global user.name "infra-tech"
           git add ../kafka-ui/*
           git add ../kafka-ui/*
           git commit -m "updated master image digest: ${{ steps.docker_build_and_push.outputs.digest }}" && git push
           git commit -m "updated master image digest: ${{ steps.docker_build_and_push.outputs.digest }}" && git push

+ 3 - 3
.github/workflows/separate_env_public_create.yml

@@ -76,14 +76,14 @@ jobs:
     steps:
     steps:
       - name: clone
       - name: clone
         run: |
         run: |
-          git clone https://kafka-ui-infra:${{ secrets.KAFKA_UI_INFRA_TOKEN }}@gitlab.provectus.com/provectus-internals/kafka-ui-infra.git
+          git clone https://infra-tech:${{ secrets.INFRA_USER_ACCESS_TOKEN }}@github.com/provectus/kafka-ui-infra.git --branch envs
 
 
       - name: separate env create
       - name: separate env create
         run: |
         run: |
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           bash separate_env_create.sh ${{ github.event.inputs.ENV_NAME }} ${{ secrets.FEATURE_TESTING_UI_PASSWORD }} ${{ needs.build.outputs.tag }}
           bash separate_env_create.sh ${{ github.event.inputs.ENV_NAME }} ${{ secrets.FEATURE_TESTING_UI_PASSWORD }} ${{ needs.build.outputs.tag }}
-          git config --global user.email "kafka-ui-infra@provectus.com"
-          git config --global user.name "kafka-ui-infra"
+          git config --global user.email "infra-tech@provectus.com"
+          git config --global user.name "infra-tech"
           git add -A
           git add -A
           git commit -m "separate env added: ${{ github.event.inputs.ENV_NAME }}" && git push || true
           git commit -m "separate env added: ${{ github.event.inputs.ENV_NAME }}" && git push || true
 
 

+ 3 - 3
.github/workflows/separate_env_public_remove.yml

@@ -13,12 +13,12 @@ jobs:
     steps:
     steps:
       - name: clone
       - name: clone
         run: |
         run: |
-          git clone https://kafka-ui-infra:${{ secrets.KAFKA_UI_INFRA_TOKEN }}@gitlab.provectus.com/provectus-internals/kafka-ui-infra.git
+          git clone https://infra-tech:${{ secrets.INFRA_USER_ACCESS_TOKEN }}@github.com/provectus/kafka-ui-infra.git --branch envs
       - name: separate environment remove
       - name: separate environment remove
         run: |
         run: |
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           cd kafka-ui-infra/aws-infrastructure4eks/argocd/scripts
           bash separate_env_remove.sh ${{ github.event.inputs.ENV_NAME }}
           bash separate_env_remove.sh ${{ github.event.inputs.ENV_NAME }}
-          git config --global user.email "kafka-ui-infra@provectus.com"
-          git config --global user.name "kafka-ui-infra"
+          git config --global user.email "infra-tech@provectus.com"
+          git config --global user.name "infra-tech"
           git add -A
           git add -A
           git commit -m "separate env removed: ${{ github.event.inputs.ENV_NAME }}" && git push || true
           git commit -m "separate env removed: ${{ github.event.inputs.ENV_NAME }}" && git push || true

+ 8 - 0
kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/BasePage.java

@@ -67,6 +67,14 @@ public abstract class BasePage extends WebUtils {
     clickByJavaScript(submitBtn);
     clickByJavaScript(submitBtn);
   }
   }
 
 
+  protected void clickNextBtn() {
+    clickByJavaScript(nextBtn);
+  }
+
+  protected void clickBackBtn() {
+    clickByJavaScript(backBtn);
+  }
+
   protected void setJsonInputValue(SelenideElement jsonInput, String jsonConfig) {
   protected void setJsonInputValue(SelenideElement jsonInput, String jsonConfig) {
     sendKeysByActions(jsonInput, jsonConfig.replace("  ", ""));
     sendKeysByActions(jsonInput, jsonConfig.replace("  ", ""));
     new Actions(WebDriverRunner.getWebDriver())
     new Actions(WebDriverRunner.getWebDriver())

+ 68 - 5
kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersConfigTab.java

@@ -3,29 +3,37 @@ package com.provectus.kafka.ui.pages.brokers;
 import static com.codeborne.selenide.Selenide.$$x;
 import static com.codeborne.selenide.Selenide.$$x;
 import static com.codeborne.selenide.Selenide.$x;
 import static com.codeborne.selenide.Selenide.$x;
 
 
+import com.codeborne.selenide.CollectionCondition;
 import com.codeborne.selenide.Condition;
 import com.codeborne.selenide.Condition;
+import com.codeborne.selenide.ElementsCollection;
 import com.codeborne.selenide.SelenideElement;
 import com.codeborne.selenide.SelenideElement;
 import com.provectus.kafka.ui.pages.BasePage;
 import com.provectus.kafka.ui.pages.BasePage;
 import io.qameta.allure.Step;
 import io.qameta.allure.Step;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.Stream;
 
 
 public class BrokersConfigTab extends BasePage {
 public class BrokersConfigTab extends BasePage {
 
 
-  protected List<SelenideElement> editBtn = $$x("//button[@aria-label='editAction']");
-  protected SelenideElement searchByKeyField = $x("//input[@placeholder='Search by Key']");
+  protected ElementsCollection editBtns = $$x("//button[@aria-label='editAction']");
 
 
   @Step
   @Step
   public BrokersConfigTab waitUntilScreenReady() {
   public BrokersConfigTab waitUntilScreenReady() {
     waitUntilSpinnerDisappear();
     waitUntilSpinnerDisappear();
-    searchByKeyField.shouldBe(Condition.visible);
+    searchFld.shouldBe(Condition.visible);
     return this;
     return this;
   }
   }
 
 
   @Step
   @Step
   public boolean isSearchByKeyVisible() {
   public boolean isSearchByKeyVisible() {
-    return isVisible(searchByKeyField);
+    return isVisible(searchFld);
+  }
+
+  @Step
+  public BrokersConfigTab searchConfig(String key) {
+    searchItem(key);
+    return this;
   }
   }
 
 
   public List<SelenideElement> getColumnHeaders() {
   public List<SelenideElement> getColumnHeaders() {
@@ -35,6 +43,61 @@ public class BrokersConfigTab extends BasePage {
   }
   }
 
 
   public List<SelenideElement> getEditButtons() {
   public List<SelenideElement> getEditButtons() {
-    return editBtn;
+    return editBtns;
+  }
+
+  @Step
+  public BrokersConfigTab clickNextButton() {
+    clickNextBtn();
+    waitUntilSpinnerDisappear(1);
+    return this;
+  }
+
+  private List<BrokersConfigTab.BrokersConfigItem> initGridItems() {
+    List<BrokersConfigTab.BrokersConfigItem> gridItemList = new ArrayList<>();
+    gridItems.shouldHave(CollectionCondition.sizeGreaterThan(0))
+        .forEach(item -> gridItemList.add(new BrokersConfigTab.BrokersConfigItem(item)));
+    return gridItemList;
+  }
+
+  @Step
+  public BrokersConfigTab.BrokersConfigItem getConfig(String key) {
+    return initGridItems().stream()
+        .filter(e -> e.getKey().equals(key))
+        .findFirst().orElseThrow();
+  }
+
+  @Step
+  public List<BrokersConfigTab.BrokersConfigItem> getAllConfigs() {
+    return initGridItems();
+  }
+
+  public static class BrokersConfigItem extends BasePage {
+
+    private final SelenideElement element;
+
+    public BrokersConfigItem(SelenideElement element) {
+      this.element = element;
+    }
+
+    @Step
+    public String getKey() {
+      return element.$x("./td[1]").getText().trim();
+    }
+
+    @Step
+    public String getValue() {
+      return element.$x("./td[2]//span").getText().trim();
+    }
+
+    @Step
+    public void edit() {
+      element.$x("./td[2]//button").shouldBe(Condition.enabled).click();
+    }
+
+    @Step
+    public String getSource() {
+      return element.$x("./td[3]").getText().trim();
+    }
   }
   }
 }
 }

+ 2 - 7
kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersDetails.java

@@ -1,6 +1,5 @@
 package com.provectus.kafka.ui.pages.brokers;
 package com.provectus.kafka.ui.pages.brokers;
 
 
-import static com.codeborne.selenide.Selenide.$;
 import static com.codeborne.selenide.Selenide.$x;
 import static com.codeborne.selenide.Selenide.$x;
 
 
 import com.codeborne.selenide.Condition;
 import com.codeborne.selenide.Condition;
@@ -8,28 +7,24 @@ import com.codeborne.selenide.SelenideElement;
 import com.provectus.kafka.ui.pages.BasePage;
 import com.provectus.kafka.ui.pages.BasePage;
 import io.qameta.allure.Step;
 import io.qameta.allure.Step;
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.Stream;
-import org.openqa.selenium.By;
 
 
 public class BrokersDetails extends BasePage {
 public class BrokersDetails extends BasePage {
 
 
-  protected SelenideElement logDirectoriesTab = $x("//a[text()='Log directories']");
-  protected SelenideElement metricsTab = $x("//a[text()='Metrics']");
   protected String brokersTabLocator = "//a[text()='%s']";
   protected String brokersTabLocator = "//a[text()='%s']";
 
 
   @Step
   @Step
   public BrokersDetails waitUntilScreenReady() {
   public BrokersDetails waitUntilScreenReady() {
     waitUntilSpinnerDisappear();
     waitUntilSpinnerDisappear();
-    Arrays.asList(logDirectoriesTab, metricsTab).forEach(element -> element.shouldBe(Condition.visible));
+    $x(String.format(brokersTabLocator, DetailsTab.LOG_DIRECTORIES)).shouldBe(Condition.visible);
     return this;
     return this;
   }
   }
 
 
   @Step
   @Step
   public BrokersDetails openDetailsTab(DetailsTab menu) {
   public BrokersDetails openDetailsTab(DetailsTab menu) {
-    $(By.linkText(menu.toString())).shouldBe(Condition.enabled).click();
+    $x(String.format(brokersTabLocator, menu.toString())).shouldBe(Condition.enabled).click();
     waitUntilSpinnerDisappear();
     waitUntilSpinnerDisappear();
     return this;
     return this;
   }
   }

+ 8 - 8
kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/brokers/BrokersList.java

@@ -24,7 +24,7 @@ public class BrokersList extends BasePage {
 
 
   @Step
   @Step
   public BrokersList openBroker(int brokerId) {
   public BrokersList openBroker(int brokerId) {
-    getBrokerItem(brokerId).openItem();
+    getBroker(brokerId).openItem();
     return this;
     return this;
   }
   }
 
 
@@ -59,30 +59,30 @@ public class BrokersList extends BasePage {
     return getEnabledColumnHeaders();
     return getEnabledColumnHeaders();
   }
   }
 
 
-  private List<BrokersList.BrokerGridItem> initGridItems() {
-    List<BrokersList.BrokerGridItem> gridItemList = new ArrayList<>();
+  private List<BrokersGridItem> initGridItems() {
+    List<BrokersGridItem> gridItemList = new ArrayList<>();
     gridItems.shouldHave(CollectionCondition.sizeGreaterThan(0))
     gridItems.shouldHave(CollectionCondition.sizeGreaterThan(0))
-        .forEach(item -> gridItemList.add(new BrokersList.BrokerGridItem(item)));
+        .forEach(item -> gridItemList.add(new BrokersGridItem(item)));
     return gridItemList;
     return gridItemList;
   }
   }
 
 
   @Step
   @Step
-  public BrokerGridItem getBrokerItem(int id) {
+  public BrokersGridItem getBroker(int id) {
     return initGridItems().stream()
     return initGridItems().stream()
         .filter(e -> e.getId() == id)
         .filter(e -> e.getId() == id)
         .findFirst().orElseThrow();
         .findFirst().orElseThrow();
   }
   }
 
 
   @Step
   @Step
-  public List<BrokerGridItem> getAllBrokers() {
+  public List<BrokersGridItem> getAllBrokers() {
     return initGridItems();
     return initGridItems();
   }
   }
 
 
-  public static class BrokerGridItem extends BasePage {
+  public static class BrokersGridItem extends BasePage {
 
 
     private final SelenideElement element;
     private final SelenideElement element;
 
 
-    public BrokerGridItem(SelenideElement element) {
+    public BrokersGridItem(SelenideElement element) {
       this.element = element;
       this.element = element;
     }
     }
 
 

+ 50 - 8
kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topics/TopicDetails.java

@@ -37,11 +37,13 @@ public class TopicDetails extends BasePage {
   protected SelenideElement addFiltersBtn = $x("//button[text()='Add Filters']");
   protected SelenideElement addFiltersBtn = $x("//button[text()='Add Filters']");
   protected SelenideElement savedFiltersLink = $x("//div[text()='Saved Filters']");
   protected SelenideElement savedFiltersLink = $x("//div[text()='Saved Filters']");
   protected SelenideElement addFilterCodeModalTitle = $x("//label[text()='Filter code']");
   protected SelenideElement addFilterCodeModalTitle = $x("//label[text()='Filter code']");
-  protected SelenideElement addFilterCodeInput = $x("//div[@id='ace-editor']//textarea");
+  protected SelenideElement addFilterCodeEditor = $x("//div[@id='ace-editor']");
+  protected SelenideElement addFilterCodeTextarea = $x("//div[@id='ace-editor']//textarea");
   protected SelenideElement saveThisFilterCheckBoxAddFilterMdl = $x("//input[@name='saveFilter']");
   protected SelenideElement saveThisFilterCheckBoxAddFilterMdl = $x("//input[@name='saveFilter']");
   protected SelenideElement displayNameInputAddFilterMdl = $x("//input[@placeholder='Enter Name']");
   protected SelenideElement displayNameInputAddFilterMdl = $x("//input[@placeholder='Enter Name']");
   protected SelenideElement cancelBtnAddFilterMdl = $x("//button[text()='Cancel']");
   protected SelenideElement cancelBtnAddFilterMdl = $x("//button[text()='Cancel']");
   protected SelenideElement addFilterBtnAddFilterMdl = $x("//button[text()='Add filter']");
   protected SelenideElement addFilterBtnAddFilterMdl = $x("//button[text()='Add filter']");
+  protected SelenideElement saveFilterBtnEditFilterMdl = $x("//button[text()='Save']");
   protected SelenideElement addFiltersBtnMessages = $x("//button[text()='Add Filters']");
   protected SelenideElement addFiltersBtnMessages = $x("//button[text()='Add Filters']");
   protected SelenideElement selectFilterBtnAddFilterMdl = $x("//button[text()='Select filter']");
   protected SelenideElement selectFilterBtnAddFilterMdl = $x("//button[text()='Select filter']");
   protected SelenideElement editSettingsMenu = $x("//li[@role][contains(text(),'Edit settings')]");
   protected SelenideElement editSettingsMenu = $x("//li[@role][contains(text(),'Edit settings')]");
@@ -62,7 +64,8 @@ public class TopicDetails extends BasePage {
   protected String savedFilterNameLocator = "//div[@role='savedFilter']/div[contains(text(),'%s')]";
   protected String savedFilterNameLocator = "//div[@role='savedFilter']/div[contains(text(),'%s')]";
   protected String consumerIdLocator = "//a[@title='%s']";
   protected String consumerIdLocator = "//a[@title='%s']";
   protected String topicHeaderLocator = "//h1[contains(text(),'%s')]";
   protected String topicHeaderLocator = "//h1[contains(text(),'%s')]";
-  protected String activeFilterNameLocator = "//div[@data-testid='activeSmartFilter'][contains(text(),'%s')]";
+  protected String activeFilterNameLocator = "//div[@data-testid='activeSmartFilter']/div[1][contains(text(),'%s')]";
+  protected String editActiveFilterBtnLocator = "//div[text()='%s']/../div[@data-testid='editActiveSmartFilterBtn']";
   protected String settingsGridValueLocator = "//tbody/tr/td/span[text()='%s']//ancestor::tr/td[2]/span";
   protected String settingsGridValueLocator = "//tbody/tr/td/span[text()='%s']//ancestor::tr/td[2]/span";
 
 
   @Step
   @Step
@@ -184,9 +187,16 @@ public class TopicDetails extends BasePage {
     return this;
     return this;
   }
   }
 
 
+  @Step
+  public TopicDetails clickEditActiveFilterBtn(String filterName) {
+    $x(String.format(editActiveFilterBtnLocator, filterName))
+        .shouldBe(Condition.enabled).click();
+    return this;
+  }
+
   @Step
   @Step
   public TopicDetails clickNextButton() {
   public TopicDetails clickNextButton() {
-    nextBtn.shouldBe(Condition.enabled).click();
+    clickNextBtn();
     waitUntilSpinnerDisappear();
     waitUntilSpinnerDisappear();
     return this;
     return this;
   }
   }
@@ -223,11 +233,27 @@ public class TopicDetails extends BasePage {
   }
   }
 
 
   @Step
   @Step
-  public TopicDetails setFilterCodeFieldAddFilterMdl(String filterCode) {
-    addFilterCodeInput.shouldBe(Condition.enabled).sendKeys(filterCode);
+  public TopicDetails setFilterCodeFldAddFilterMdl(String filterCode) {
+    addFilterCodeTextarea.shouldBe(Condition.enabled).setValue(filterCode);
     return this;
     return this;
   }
   }
 
 
+  @Step
+  public String getFilterCodeValue() {
+    addFilterCodeEditor.shouldBe(Condition.enabled).click();
+    String value = addFilterCodeTextarea.getValue();
+    if (value == null) {
+      return null;
+    } else {
+      return value.substring(0, value.length() - 2);
+    }
+  }
+
+  @Step
+  public String getFilterNameValue() {
+    return displayNameInputAddFilterMdl.shouldBe(Condition.enabled).getValue();
+  }
+
   @Step
   @Step
   public TopicDetails selectSaveThisFilterCheckboxMdl(boolean select) {
   public TopicDetails selectSaveThisFilterCheckboxMdl(boolean select) {
     selectElement(saveThisFilterCheckBoxAddFilterMdl, select);
     selectElement(saveThisFilterCheckBoxAddFilterMdl, select);
@@ -241,7 +267,7 @@ public class TopicDetails extends BasePage {
 
 
   @Step
   @Step
   public TopicDetails setDisplayNameFldAddFilterMdl(String displayName) {
   public TopicDetails setDisplayNameFldAddFilterMdl(String displayName) {
-    displayNameInputAddFilterMdl.shouldBe(Condition.enabled).sendKeys(displayName);
+    displayNameInputAddFilterMdl.shouldBe(Condition.enabled).setValue(displayName);
     return this;
     return this;
   }
   }
 
 
@@ -256,6 +282,17 @@ public class TopicDetails extends BasePage {
     return this;
     return this;
   }
   }
 
 
+  @Step
+  public TopicDetails clickSaveFilterBtnAndCloseMdl(boolean closeModal) {
+    saveFilterBtnEditFilterMdl.shouldBe(Condition.enabled).click();
+    if (closeModal) {
+      addFilterCodeModalTitle.shouldBe(Condition.hidden);
+    } else {
+      addFilterCodeModalTitle.shouldBe(Condition.visible);
+    }
+    return this;
+  }
+
   @Step
   @Step
   public boolean isAddFilterBtnAddFilterMdlEnabled() {
   public boolean isAddFilterBtnAddFilterMdlEnabled() {
     return isEnabled(addFilterBtnAddFilterMdl);
     return isEnabled(addFilterBtnAddFilterMdl);
@@ -272,8 +309,13 @@ public class TopicDetails extends BasePage {
   }
   }
 
 
   @Step
   @Step
-  public boolean isActiveFilterVisible(String activeFilterName) {
-    return isVisible($x(String.format(activeFilterNameLocator, activeFilterName)));
+  public boolean isActiveFilterVisible(String filterName) {
+    return isVisible($x(String.format(activeFilterNameLocator, filterName)));
+  }
+
+  @Step
+  public String getSearchFieldValue() {
+    return searchFld.shouldBe(Condition.visible).getValue();
   }
   }
 
 
   public List<SelenideElement> getAllAddFilterModalVisibleElements() {
   public List<SelenideElement> getAllAddFilterModalVisibleElements() {

+ 11 - 0
kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/topics/TopicsList.java

@@ -68,6 +68,17 @@ public class TopicsList extends BasePage {
     return this;
     return this;
   }
   }
 
 
+  @Step
+  public TopicsList goToLastPage() {
+    if (nextBtn.exists()) {
+      while (nextBtn.isEnabled()) {
+        clickNextBtn();
+        waitUntilSpinnerDisappear(1);
+      }
+    }
+    return this;
+  }
+
   @Step
   @Step
   public TopicsList openTopic(String topicName) {
   public TopicsList openTopic(String topicName) {
     getTopicItem(topicName).openItem();
     getTopicItem(topicName).openItem();

+ 12 - 19
kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/manualsuite/backlog/SmokeBacklog.java

@@ -15,94 +15,87 @@ import org.testng.annotations.Test;
 
 
 public class SmokeBacklog extends BaseManualTest {
 public class SmokeBacklog extends BaseManualTest {
 
 
-  @Automation(state = TO_BE_AUTOMATED)
-  @Suite(id = BROKERS_SUITE_ID)
-  @QaseId(330)
-  @Test
-  public void testCaseA() {
-  }
-
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = BROKERS_SUITE_ID)
   @Suite(id = BROKERS_SUITE_ID)
   @QaseId(331)
   @QaseId(331)
   @Test
   @Test
-  public void testCaseB() {
+  public void testCaseA() {
   }
   }
 
 
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = BROKERS_SUITE_ID)
   @Suite(id = BROKERS_SUITE_ID)
   @QaseId(332)
   @QaseId(332)
   @Test
   @Test
-  public void testCaseC() {
+  public void testCaseB() {
   }
   }
 
 
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = TOPICS_PROFILE_SUITE_ID)
   @Suite(id = TOPICS_PROFILE_SUITE_ID)
   @QaseId(335)
   @QaseId(335)
   @Test
   @Test
-  public void testCaseD() {
+  public void testCaseC() {
   }
   }
 
 
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = TOPICS_PROFILE_SUITE_ID)
   @Suite(id = TOPICS_PROFILE_SUITE_ID)
   @QaseId(336)
   @QaseId(336)
   @Test
   @Test
-  public void testCaseE() {
+  public void testCaseD() {
   }
   }
 
 
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = TOPICS_PROFILE_SUITE_ID)
   @Suite(id = TOPICS_PROFILE_SUITE_ID)
   @QaseId(343)
   @QaseId(343)
   @Test
   @Test
-  public void testCaseF() {
+  public void testCaseE() {
   }
   }
 
 
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = SCHEMAS_SUITE_ID)
   @Suite(id = SCHEMAS_SUITE_ID)
   @QaseId(345)
   @QaseId(345)
   @Test
   @Test
-  public void testCaseG() {
+  public void testCaseF() {
   }
   }
 
 
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = SCHEMAS_SUITE_ID)
   @Suite(id = SCHEMAS_SUITE_ID)
   @QaseId(346)
   @QaseId(346)
   @Test
   @Test
-  public void testCaseH() {
+  public void testCaseG() {
   }
   }
 
 
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = TOPICS_PROFILE_SUITE_ID)
   @Suite(id = TOPICS_PROFILE_SUITE_ID)
   @QaseId(347)
   @QaseId(347)
   @Test
   @Test
-  public void testCaseI() {
+  public void testCaseH() {
   }
   }
 
 
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = BROKERS_SUITE_ID)
   @Suite(id = BROKERS_SUITE_ID)
   @QaseId(348)
   @QaseId(348)
   @Test
   @Test
-  public void testCaseJ() {
+  public void testCaseI() {
   }
   }
 
 
   @Automation(state = TO_BE_AUTOMATED)
   @Automation(state = TO_BE_AUTOMATED)
   @Suite(id = BROKERS_SUITE_ID)
   @Suite(id = BROKERS_SUITE_ID)
   @QaseId(350)
   @QaseId(350)
   @Test
   @Test
-  public void testCaseK() {
+  public void testCaseJ() {
   }
   }
 
 
   @Automation(state = NOT_AUTOMATED)
   @Automation(state = NOT_AUTOMATED)
   @Suite(id = TOPICS_SUITE_ID)
   @Suite(id = TOPICS_SUITE_ID)
   @QaseId(50)
   @QaseId(50)
   @Test
   @Test
-  public void testCaseL() {
+  public void testCaseK() {
   }
   }
 
 
   @Automation(state = NOT_AUTOMATED)
   @Automation(state = NOT_AUTOMATED)
   @Suite(id = SCHEMAS_SUITE_ID)
   @Suite(id = SCHEMAS_SUITE_ID)
   @QaseId(351)
   @QaseId(351)
   @Test
   @Test
-  public void testCaseM() {
+  public void testCaseL() {
   }
   }
 }
 }

+ 32 - 1
kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/smokesuite/brokers/BrokersTest.java

@@ -4,12 +4,17 @@ import static com.provectus.kafka.ui.pages.brokers.BrokersDetails.DetailsTab.CON
 
 
 import com.codeborne.selenide.Condition;
 import com.codeborne.selenide.Condition;
 import com.provectus.kafka.ui.BaseTest;
 import com.provectus.kafka.ui.BaseTest;
+import com.provectus.kafka.ui.pages.brokers.BrokersConfigTab;
+import io.qameta.allure.Issue;
 import io.qase.api.annotation.QaseId;
 import io.qase.api.annotation.QaseId;
 import org.testng.Assert;
 import org.testng.Assert;
+import org.testng.annotations.Ignore;
 import org.testng.annotations.Test;
 import org.testng.annotations.Test;
 
 
 public class BrokersTest extends BaseTest {
 public class BrokersTest extends BaseTest {
 
 
+  public static final int DEFAULT_BROKER_ID = 1;
+
   @QaseId(1)
   @QaseId(1)
   @Test
   @Test
   public void checkBrokersOverview() {
   public void checkBrokersOverview() {
@@ -25,7 +30,7 @@ public class BrokersTest extends BaseTest {
     navigateToBrokers();
     navigateToBrokers();
     Assert.assertTrue(brokersList.getAllBrokers().size() > 0, "getAllBrokers()");
     Assert.assertTrue(brokersList.getAllBrokers().size() > 0, "getAllBrokers()");
     brokersList
     brokersList
-        .openBroker(1);
+        .openBroker(DEFAULT_BROKER_ID);
     brokersDetails
     brokersDetails
         .waitUntilScreenReady();
         .waitUntilScreenReady();
     verifyElementsCondition(brokersDetails.getAllVisibleElements(), Condition.visible);
     verifyElementsCondition(brokersDetails.getAllVisibleElements(), Condition.visible);
@@ -38,4 +43,30 @@ public class BrokersTest extends BaseTest {
     verifyElementsCondition(brokersConfigTab.getEditButtons(), Condition.enabled);
     verifyElementsCondition(brokersConfigTab.getEditButtons(), Condition.enabled);
     Assert.assertTrue(brokersConfigTab.isSearchByKeyVisible(), "isSearchByKeyVisible()");
     Assert.assertTrue(brokersConfigTab.isSearchByKeyVisible(), "isSearchByKeyVisible()");
   }
   }
+
+  @Ignore
+  @Issue("https://github.com/provectus/kafka-ui/issues/3347")
+  @QaseId(330)
+  @Test
+  public void brokersConfigSearchCheck() {
+    navigateToBrokersAndOpenDetails(DEFAULT_BROKER_ID);
+    brokersDetails
+        .openDetailsTab(CONFIGS);
+    String anyConfigKey = brokersConfigTab
+        .getAllConfigs().stream()
+        .findAny().orElseThrow()
+        .getKey();
+    brokersConfigTab
+        .clickNextButton();
+    Assert.assertFalse(brokersConfigTab.getAllConfigs().stream()
+            .map(BrokersConfigTab.BrokersConfigItem::getKey)
+            .toList().contains(anyConfigKey),
+        String.format("getAllConfigs().contains(%s)", anyConfigKey));
+    brokersConfigTab
+        .searchConfig(anyConfigKey);
+    Assert.assertTrue(brokersConfigTab.getAllConfigs().stream()
+            .map(BrokersConfigTab.BrokersConfigItem::getKey)
+            .toList().contains(anyConfigKey),
+        String.format("getAllConfigs().contains(%s)", anyConfigKey));
+  }
 }
 }

+ 45 - 14
kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/smokesuite/topics/TopicsTest.java

@@ -313,14 +313,44 @@ public class TopicsTest extends BaseTest {
     verifyElementsCondition(topicDetails.getAllAddFilterModalDisabledElements(), Condition.disabled);
     verifyElementsCondition(topicDetails.getAllAddFilterModalDisabledElements(), Condition.disabled);
     Assert.assertFalse(topicDetails.isSaveThisFilterCheckBoxSelected(), "isSaveThisFilterCheckBoxSelected()");
     Assert.assertFalse(topicDetails.isSaveThisFilterCheckBoxSelected(), "isSaveThisFilterCheckBoxSelected()");
     topicDetails
     topicDetails
-        .setFilterCodeFieldAddFilterMdl(filterName);
+        .setFilterCodeFldAddFilterMdl(filterName);
     Assert.assertTrue(topicDetails.isAddFilterBtnAddFilterMdlEnabled(), "isAddFilterBtnAddFilterMdlEnabled()");
     Assert.assertTrue(topicDetails.isAddFilterBtnAddFilterMdlEnabled(), "isAddFilterBtnAddFilterMdlEnabled()");
     topicDetails.clickAddFilterBtnAndCloseMdl(true);
     topicDetails.clickAddFilterBtnAndCloseMdl(true);
     Assert.assertTrue(topicDetails.isActiveFilterVisible(filterName), "isActiveFilterVisible()");
     Assert.assertTrue(topicDetails.isActiveFilterVisible(filterName), "isActiveFilterVisible()");
   }
   }
 
 
-  @QaseId(13)
+  @QaseId(352)
   @Test(priority = 13)
   @Test(priority = 13)
+  public void editActiveSmartFilterCheck() {
+    String filterName = randomAlphabetic(5);
+    String filterCode = randomAlphabetic(5);
+    navigateToTopicsAndOpenDetails(TOPIC_FOR_CHECK_FILTERS.getName());
+    topicDetails
+        .openDetailsTab(MESSAGES)
+        .clickMessagesAddFiltersBtn()
+        .waitUntilAddFiltersMdlVisible()
+        .setFilterCodeFldAddFilterMdl(filterCode)
+        .setDisplayNameFldAddFilterMdl(filterName)
+        .clickAddFilterBtnAndCloseMdl(true)
+        .clickEditActiveFilterBtn(filterName)
+        .waitUntilAddFiltersMdlVisible();
+    SoftAssert softly = new SoftAssert();
+    softly.assertEquals(topicDetails.getFilterCodeValue(), filterCode, "getFilterCodeValue()");
+    softly.assertEquals(topicDetails.getFilterNameValue(), filterName, "getFilterNameValue()");
+    softly.assertAll();
+    String newFilterName = randomAlphabetic(5);
+    String newFilterCode = randomAlphabetic(5);
+    topicDetails
+        .setFilterCodeFldAddFilterMdl(newFilterCode)
+        .setDisplayNameFldAddFilterMdl(newFilterName)
+        .clickSaveFilterBtnAndCloseMdl(true);
+    softly.assertTrue(topicDetails.isActiveFilterVisible(newFilterName), "isActiveFilterVisible()");
+    softly.assertEquals(topicDetails.getSearchFieldValue(), newFilterCode, "getSearchFieldValue()");
+    softly.assertAll();
+  }
+
+  @QaseId(13)
+  @Test(priority = 14)
   public void checkFilterSavingWithinSavedFilters() {
   public void checkFilterSavingWithinSavedFilters() {
     String displayName = randomAlphabetic(5);
     String displayName = randomAlphabetic(5);
     navigateToTopicsAndOpenDetails(TOPIC_FOR_CHECK_FILTERS.getName());
     navigateToTopicsAndOpenDetails(TOPIC_FOR_CHECK_FILTERS.getName());
@@ -328,7 +358,7 @@ public class TopicsTest extends BaseTest {
         .openDetailsTab(MESSAGES)
         .openDetailsTab(MESSAGES)
         .clickMessagesAddFiltersBtn()
         .clickMessagesAddFiltersBtn()
         .waitUntilAddFiltersMdlVisible()
         .waitUntilAddFiltersMdlVisible()
-        .setFilterCodeFieldAddFilterMdl(randomAlphabetic(4))
+        .setFilterCodeFldAddFilterMdl(randomAlphabetic(4))
         .selectSaveThisFilterCheckboxMdl(true)
         .selectSaveThisFilterCheckboxMdl(true)
         .setDisplayNameFldAddFilterMdl(displayName);
         .setDisplayNameFldAddFilterMdl(displayName);
     Assert.assertTrue(topicDetails.isAddFilterBtnAddFilterMdlEnabled(),
     Assert.assertTrue(topicDetails.isAddFilterBtnAddFilterMdlEnabled(),
@@ -341,7 +371,7 @@ public class TopicsTest extends BaseTest {
   }
   }
 
 
   @QaseId(14)
   @QaseId(14)
-  @Test(priority = 14)
+  @Test(priority = 15)
   public void checkApplyingSavedFilterWithinTopicMessages() {
   public void checkApplyingSavedFilterWithinTopicMessages() {
     String displayName = randomAlphabetic(5);
     String displayName = randomAlphabetic(5);
     navigateToTopicsAndOpenDetails(TOPIC_FOR_CHECK_FILTERS.getName());
     navigateToTopicsAndOpenDetails(TOPIC_FOR_CHECK_FILTERS.getName());
@@ -349,7 +379,7 @@ public class TopicsTest extends BaseTest {
         .openDetailsTab(MESSAGES)
         .openDetailsTab(MESSAGES)
         .clickMessagesAddFiltersBtn()
         .clickMessagesAddFiltersBtn()
         .waitUntilAddFiltersMdlVisible()
         .waitUntilAddFiltersMdlVisible()
-        .setFilterCodeFieldAddFilterMdl(randomAlphabetic(4))
+        .setFilterCodeFldAddFilterMdl(randomAlphabetic(4))
         .selectSaveThisFilterCheckboxMdl(true)
         .selectSaveThisFilterCheckboxMdl(true)
         .setDisplayNameFldAddFilterMdl(displayName)
         .setDisplayNameFldAddFilterMdl(displayName)
         .clickAddFilterBtnAndCloseMdl(false)
         .clickAddFilterBtnAndCloseMdl(false)
@@ -360,24 +390,25 @@ public class TopicsTest extends BaseTest {
   }
   }
 
 
   @QaseId(11)
   @QaseId(11)
-  @Test(priority = 15)
+  @Test(priority = 16)
   public void checkShowInternalTopicsButton() {
   public void checkShowInternalTopicsButton() {
     navigateToTopics();
     navigateToTopics();
     topicsList
     topicsList
         .setShowInternalRadioButton(true);
         .setShowInternalRadioButton(true);
-    SoftAssert softly = new SoftAssert();
-    softly.assertTrue(topicsList.getInternalTopics().size() > 0, "getInternalTopics()");
-    softly.assertTrue(topicsList.getNonInternalTopics().size() > 0, "getNonInternalTopics()");
-    softly.assertAll();
+    Assert.assertTrue(topicsList.getInternalTopics().size() > 0, "getInternalTopics()");
+    topicsList
+        .goToLastPage();
+    Assert.assertTrue(topicsList.getNonInternalTopics().size() > 0, "getNonInternalTopics()");
     topicsList
     topicsList
         .setShowInternalRadioButton(false);
         .setShowInternalRadioButton(false);
+    SoftAssert softly = new SoftAssert();
     softly.assertEquals(topicsList.getInternalTopics().size(), 0, "getInternalTopics()");
     softly.assertEquals(topicsList.getInternalTopics().size(), 0, "getInternalTopics()");
     softly.assertTrue(topicsList.getNonInternalTopics().size() > 0, "getNonInternalTopics()");
     softly.assertTrue(topicsList.getNonInternalTopics().size() > 0, "getNonInternalTopics()");
     softly.assertAll();
     softly.assertAll();
   }
   }
 
 
   @QaseId(334)
   @QaseId(334)
-  @Test(priority = 16)
+  @Test(priority = 17)
   public void checkInternalTopicsNaming() {
   public void checkInternalTopicsNaming() {
     navigateToTopics();
     navigateToTopics();
     SoftAssert softly = new SoftAssert();
     SoftAssert softly = new SoftAssert();
@@ -390,7 +421,7 @@ public class TopicsTest extends BaseTest {
   }
   }
 
 
   @QaseId(56)
   @QaseId(56)
-  @Test(priority = 17)
+  @Test(priority = 18)
   public void checkRetentionBytesAccordingToMaxSizeOnDisk() {
   public void checkRetentionBytesAccordingToMaxSizeOnDisk() {
     navigateToTopics();
     navigateToTopics();
     topicsList
     topicsList
@@ -438,7 +469,7 @@ public class TopicsTest extends BaseTest {
   }
   }
 
 
   @QaseId(247)
   @QaseId(247)
-  @Test(priority = 18)
+  @Test(priority = 19)
   public void recreateTopicFromTopicProfile() {
   public void recreateTopicFromTopicProfile() {
     Topic topicToRecreate = new Topic()
     Topic topicToRecreate = new Topic()
         .setName("topic-to-recreate-" + randomAlphabetic(5))
         .setName("topic-to-recreate-" + randomAlphabetic(5))
@@ -466,7 +497,7 @@ public class TopicsTest extends BaseTest {
   }
   }
 
 
   @QaseId(8)
   @QaseId(8)
-  @Test(priority = 19)
+  @Test(priority = 20)
   public void checkCopyTopicPossibility() {
   public void checkCopyTopicPossibility() {
     Topic topicToCopy = new Topic()
     Topic topicToCopy = new Topic()
         .setName("topic-to-copy-" + randomAlphabetic(5))
         .setName("topic-to-copy-" + randomAlphabetic(5))

+ 3 - 2
kafka-ui-react-app/src/components/Dashboard/ClusterTableActionsCell.tsx

@@ -11,7 +11,8 @@ const ClusterTableActionsCell: React.FC<Props> = ({ row }) => {
   const { name } = row.original;
   const { name } = row.original;
   const { data } = useGetUserInfo();
   const { data } = useGetUserInfo();
 
 
-  const isApplicationConfig = useMemo(() => {
+  const hasPermissions = useMemo(() => {
+    if (!data?.rbacEnabled) return true;
     return !!data?.userInfo?.permissions.some(
     return !!data?.userInfo?.permissions.some(
       (permission) => permission.resource === ResourceType.APPLICATIONCONFIG
       (permission) => permission.resource === ResourceType.APPLICATIONCONFIG
     );
     );
@@ -22,7 +23,7 @@ const ClusterTableActionsCell: React.FC<Props> = ({ row }) => {
       buttonType="secondary"
       buttonType="secondary"
       buttonSize="S"
       buttonSize="S"
       to={clusterConfigPath(name)}
       to={clusterConfigPath(name)}
-      canDoAction={isApplicationConfig}
+      canDoAction={hasPermissions}
     >
     >
       Configure
       Configure
     </ActionCanButton>
     </ActionCanButton>

+ 3 - 2
kafka-ui-react-app/src/components/Dashboard/Dashboard.tsx

@@ -57,7 +57,8 @@ const Dashboard: React.FC = () => {
     return initialColumns;
     return initialColumns;
   }, []);
   }, []);
 
 
-  const isApplicationConfig = useMemo(() => {
+  const hasPermissions = useMemo(() => {
+    if (!data?.rbacEnabled) return true;
     return !!data?.userInfo?.permissions.some(
     return !!data?.userInfo?.permissions.some(
       (permission) => permission.resource === ResourceType.APPLICATIONCONFIG
       (permission) => permission.resource === ResourceType.APPLICATIONCONFIG
     );
     );
@@ -91,7 +92,7 @@ const Dashboard: React.FC = () => {
             buttonType="primary"
             buttonType="primary"
             buttonSize="M"
             buttonSize="M"
             to={clusterNewConfigPath}
             to={clusterNewConfigPath}
-            canDoAction={isApplicationConfig}
+            canDoAction={hasPermissions}
           >
           >
             Configure new cluster
             Configure new cluster
           </ActionCanButton>
           </ActionCanButton>

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

@@ -9,7 +9,7 @@ import {
 } from 'react-hook-form';
 } from 'react-hook-form';
 import { Button } from 'components/common/Button/Button';
 import { Button } from 'components/common/Button/Button';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
-import CloseIcon from 'components/common/Icons/CloseIcon';
+import CloseCircleIcon from 'components/common/Icons/CloseCircleIcon';
 import { yupResolver } from '@hookform/resolvers/yup';
 import { yupResolver } from '@hookform/resolvers/yup';
 import yup from 'lib/yupExtended';
 import yup from 'lib/yupExtended';
 import PlusIcon from 'components/common/Icons/PlusIcon';
 import PlusIcon from 'components/common/Icons/PlusIcon';
@@ -174,7 +174,7 @@ const QueryForm: React.FC<QueryFormProps> = ({
                     aria-label="deleteProperty"
                     aria-label="deleteProperty"
                     onClick={removeProperty(index)}
                     onClick={removeProperty(index)}
                   >
                   >
-                    <CloseIcon aria-hidden />
+                    <CloseCircleIcon aria-hidden />
                   </IconButtonWrapper>
                   </IconButtonWrapper>
                 </S.InputsContainer>
                 </S.InputsContainer>
               ))}
               ))}

+ 1 - 1
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/EditFilter.tsx

@@ -22,7 +22,7 @@ const EditFilter: React.FC<EditFilterProps> = ({
   };
   };
   return (
   return (
     <>
     <>
-      <S.FilterTitle>Edit saved filter</S.FilterTitle>
+      <S.FilterTitle>Edit filter</S.FilterTitle>
       <AddEditFilterContainer
       <AddEditFilterContainer
         cancelBtnHandler={() => toggleEditModal()}
         cancelBtnHandler={() => toggleEditModal()}
         submitBtnText="Save"
         submitBtnText="Save"

+ 25 - 15
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/FilterModal.tsx

@@ -1,6 +1,9 @@
 import React from 'react';
 import React from 'react';
 import * as S from 'components/Topics/Topic/Messages/Filters/Filters.styled';
 import * as S from 'components/Topics/Topic/Messages/Filters/Filters.styled';
-import { MessageFilters } from 'components/Topics/Topic/Messages/Filters/Filters';
+import {
+  ActiveMessageFilter,
+  MessageFilters,
+} from 'components/Topics/Topic/Messages/Filters/Filters';
 import AddFilter from 'components/Topics/Topic/Messages/Filters/AddFilter';
 import AddFilter from 'components/Topics/Topic/Messages/Filters/AddFilter';
 import EditFilter from 'components/Topics/Topic/Messages/Filters/EditFilter';
 import EditFilter from 'components/Topics/Topic/Messages/Filters/EditFilter';
 
 
@@ -11,7 +14,8 @@ export interface FilterModalProps {
   deleteFilter(index: number): void;
   deleteFilter(index: number): void;
   activeFilterHandler(activeFilter: MessageFilters, index: number): void;
   activeFilterHandler(activeFilter: MessageFilters, index: number): void;
   editSavedFilter(filter: FilterEdit): void;
   editSavedFilter(filter: FilterEdit): void;
-  activeFilter?: MessageFilters;
+  activeFilter: ActiveMessageFilter;
+  quickEditMode?: boolean;
 }
 }
 
 
 export interface FilterEdit {
 export interface FilterEdit {
@@ -27,27 +31,39 @@ const FilterModal: React.FC<FilterModalProps> = ({
   activeFilterHandler,
   activeFilterHandler,
   editSavedFilter,
   editSavedFilter,
   activeFilter,
   activeFilter,
+  quickEditMode = false,
 }) => {
 }) => {
-  const [addFilterModal, setAddFilterModal] = React.useState<boolean>(true);
+  const [isInEditMode, setIsInEditMode] =
+    React.useState<boolean>(quickEditMode);
   const [isSavedFiltersOpen, setIsSavedFiltersOpen] =
   const [isSavedFiltersOpen, setIsSavedFiltersOpen] =
     React.useState<boolean>(false);
     React.useState<boolean>(false);
 
 
   const toggleEditModal = () => {
   const toggleEditModal = () => {
-    setAddFilterModal(!addFilterModal);
+    setIsInEditMode(!isInEditMode);
   };
   };
 
 
-  const [editFilter, setEditFilter] = React.useState<FilterEdit>({
-    index: -1,
-    filter: { name: '', code: '' },
+  const [editFilter, setEditFilter] = React.useState<FilterEdit>(() => {
+    const { index, name, code } = activeFilter;
+    return quickEditMode
+      ? { index, filter: { name, code } }
+      : { index: -1, filter: { name: '', code: '' } };
   });
   });
   const editFilterHandler = (value: FilterEdit) => {
   const editFilterHandler = (value: FilterEdit) => {
     setEditFilter(value);
     setEditFilter(value);
-    setAddFilterModal(!addFilterModal);
+    setIsInEditMode(!isInEditMode);
   };
   };
 
 
+  const toggleEditModalHandler = quickEditMode ? toggleIsOpen : toggleEditModal;
+
   return (
   return (
     <S.MessageFilterModal data-testid="messageFilterModal">
     <S.MessageFilterModal data-testid="messageFilterModal">
-      {addFilterModal ? (
+      {isInEditMode ? (
+        <EditFilter
+          editFilter={editFilter}
+          toggleEditModal={toggleEditModalHandler}
+          editSavedFilter={editSavedFilter}
+        />
+      ) : (
         <AddFilter
         <AddFilter
           toggleIsOpen={toggleIsOpen}
           toggleIsOpen={toggleIsOpen}
           filters={filters}
           filters={filters}
@@ -60,12 +76,6 @@ const FilterModal: React.FC<FilterModalProps> = ({
           onClickSavedFilters={() => setIsSavedFiltersOpen(!isSavedFiltersOpen)}
           onClickSavedFilters={() => setIsSavedFiltersOpen(!isSavedFiltersOpen)}
           activeFilter={activeFilter}
           activeFilter={activeFilter}
         />
         />
-      ) : (
-        <EditFilter
-          editFilter={editFilter}
-          toggleEditModal={toggleEditModal}
-          editSavedFilter={editSavedFilter}
-        />
       )}
       )}
     </S.MessageFilterModal>
     </S.MessageFilterModal>
   );
   );

+ 66 - 16
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/Filters.styled.ts

@@ -2,6 +2,8 @@ import Input from 'components/common/Input/Input';
 import Select from 'components/common/Select/Select';
 import Select from 'components/common/Select/Select';
 import styled, { css } from 'styled-components';
 import styled, { css } from 'styled-components';
 import DatePicker from 'react-datepicker';
 import DatePicker from 'react-datepicker';
+import EditIcon from 'components/common/Icons/EditIcon';
+import closeIcon from 'components/common/Icons/CloseIcon';
 
 
 interface SavedFilterProps {
 interface SavedFilterProps {
   selected: boolean;
   selected: boolean;
@@ -280,29 +282,77 @@ export const SavedFilter = styled.div.attrs({
 `;
 `;
 
 
 export const ActiveSmartFilter = styled.div`
 export const ActiveSmartFilter = styled.div`
-  border-radius: 4px;
-  min-width: 115px;
-  height: 24px;
-  background: ${({ theme }) => theme.savedFilter.backgroundColor};
-  font-size: 14px;
-  line-height: 20px;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   justify-content: space-between;
   justify-content: space-between;
-  color: ${({ theme }) => theme.savedFilter.color};
-  padding: 16px 8px;
+  height: 32px;
+  color: ${({ theme }) => theme.activeFilter.color};
+  background: ${({ theme }) => theme.activeFilter.backgroundColor};
+  border-radius: 4px;
+  font-size: 14px;
+  line-height: 20px;
 `;
 `;
 
 
-export const DeleteSavedFilterIcon = styled.div`
-  color: ${({ theme }) => theme.icons.closeIcon};
-  display: flex;
-  align-items: center;
-  padding-left: 6px;
-  height: 24px;
-  cursor: pointer;
-  margin-left: 4px;
+export const EditSmartFilterIcon = styled.div(
+  ({ theme: { icons } }) => css`
+    color: ${icons.editIcon.normal};
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 32px;
+    width: 32px;
+    cursor: pointer;
+    border-left: 1px solid ${icons.editIcon.border};
+
+    &:hover {
+      ${EditIcon} {
+        fill: ${icons.editIcon.hover};
+      }
+    }
+
+    &:active {
+      ${EditIcon} {
+        fill: ${icons.editIcon.active};
+      }
+    }
+  `
+);
+
+export const SmartFilterName = styled.div`
+  padding: 0 8px;
+  min-width: 32px;
 `;
 `;
 
 
+export const DeleteSmartFilterIcon = styled.div(
+  ({ theme: { icons } }) => css`
+    color: ${icons.closeIcon.normal};
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 32px;
+    width: 32px;
+    cursor: pointer;
+    border-left: 1px solid ${icons.closeIcon.border};
+
+    svg {
+      height: 14px;
+      width: 14px;
+    }
+
+    &:hover {
+      ${closeIcon} {
+        fill: ${icons.closeIcon.hover};
+      }
+    }
+
+    &:active {
+      ${closeIcon} {
+        fill: ${icons.closeIcon.active};
+      }
+    }
+  `
+);
+
 export const MessageLoading = styled.div.attrs({
 export const MessageLoading = styled.div.attrs({
   role: 'contentLoader',
   role: 'contentLoader',
 })<MessageLoadingProps>`
 })<MessageLoadingProps>`

+ 49 - 17
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/Filters.tsx

@@ -30,6 +30,7 @@ import useBoolean from 'lib/hooks/useBoolean';
 import { RouteParamsClusterTopic } from 'lib/paths';
 import { RouteParamsClusterTopic } from 'lib/paths';
 import useAppParams from 'lib/hooks/useAppParams';
 import useAppParams from 'lib/hooks/useAppParams';
 import PlusIcon from 'components/common/Icons/PlusIcon';
 import PlusIcon from 'components/common/Icons/PlusIcon';
+import EditIcon from 'components/common/Icons/EditIcon';
 import CloseIcon from 'components/common/Icons/CloseIcon';
 import CloseIcon from 'components/common/Icons/CloseIcon';
 import ClockIcon from 'components/common/Icons/ClockIcon';
 import ClockIcon from 'components/common/Icons/ClockIcon';
 import ArrowDownIcon from 'components/common/Icons/ArrowDownIcon';
 import ArrowDownIcon from 'components/common/Icons/ArrowDownIcon';
@@ -67,7 +68,7 @@ export interface MessageFilters {
   code: string;
   code: string;
 }
 }
 
 
-interface ActiveMessageFilter {
+export interface ActiveMessageFilter {
   index: number;
   index: number;
   name: string;
   name: string;
   code: string;
   code: string;
@@ -108,6 +109,8 @@ const Filters: React.FC<FiltersProps> = ({
 
 
   const { value: isOpen, toggle } = useBoolean();
   const { value: isOpen, toggle } = useBoolean();
 
 
+  const { value: isQuickEditOpen, toggle: toggleQuickEdit } = useBoolean();
+
   const source = React.useRef<EventSource | null>(null);
   const source = React.useRef<EventSource | null>(null);
 
 
   const [selectedPartitions, setSelectedPartitions] = React.useState<Option[]>(
   const [selectedPartitions, setSelectedPartitions] = React.useState<Option[]>(
@@ -307,27 +310,37 @@ const Filters: React.FC<FiltersProps> = ({
     setActiveFilter({ index, ...newActiveFilter });
     setActiveFilter({ index, ...newActiveFilter });
     setQueryType(MessageFilterType.GROOVY_SCRIPT);
     setQueryType(MessageFilterType.GROOVY_SCRIPT);
   };
   };
+
+  const composeMessageFilter = (filter: FilterEdit): ActiveMessageFilter => ({
+    index: filter.index,
+    name: filter.filter.name,
+    code: filter.filter.code,
+  });
+
+  const storeAsActiveFilter = (filter: FilterEdit) => {
+    const messageFilter = JSON.stringify(composeMessageFilter(filter));
+    localStorage.setItem('activeFilter', messageFilter);
+  };
+
   const editSavedFilter = (filter: FilterEdit) => {
   const editSavedFilter = (filter: FilterEdit) => {
     const filters = [...savedFilters];
     const filters = [...savedFilters];
     filters[filter.index] = filter.filter;
     filters[filter.index] = filter.filter;
     if (activeFilter.name && activeFilter.index === filter.index) {
     if (activeFilter.name && activeFilter.index === filter.index) {
-      setActiveFilter({
-        index: filter.index,
-        name: filter.filter.name,
-        code: filter.filter.code,
-      });
-      localStorage.setItem(
-        'activeFilter',
-        JSON.stringify({
-          index: filter.index,
-          name: filter.filter.name,
-          code: filter.filter.code,
-        })
-      );
+      setActiveFilter(composeMessageFilter(filter));
+      storeAsActiveFilter(filter);
     }
     }
     localStorage.setItem('savedFilters', JSON.stringify(filters));
     localStorage.setItem('savedFilters', JSON.stringify(filters));
     setSavedFilters(filters);
     setSavedFilters(filters);
   };
   };
+
+  const editCurrentFilter = (filter: FilterEdit) => {
+    if (filter.index < 0) {
+      setActiveFilter(composeMessageFilter(filter));
+      storeAsActiveFilter(filter);
+    } else {
+      editSavedFilter(filter);
+    }
+  };
   // eslint-disable-next-line consistent-return
   // eslint-disable-next-line consistent-return
   React.useEffect(() => {
   React.useEffect(() => {
     if (location.search?.length !== 0) {
     if (location.search?.length !== 0) {
@@ -542,13 +555,32 @@ const Filters: React.FC<FiltersProps> = ({
         </Button>
         </Button>
         {activeFilter.name && (
         {activeFilter.name && (
           <S.ActiveSmartFilter data-testid="activeSmartFilter">
           <S.ActiveSmartFilter data-testid="activeSmartFilter">
-            {activeFilter.name}
-            <S.DeleteSavedFilterIcon onClick={deleteActiveFilter}>
+            <S.SmartFilterName>{activeFilter.name}</S.SmartFilterName>
+            <S.EditSmartFilterIcon
+              data-testid="editActiveSmartFilterBtn"
+              onClick={toggleQuickEdit}
+            >
+              <EditIcon />
+            </S.EditSmartFilterIcon>
+            <S.DeleteSmartFilterIcon onClick={deleteActiveFilter}>
               <CloseIcon />
               <CloseIcon />
-            </S.DeleteSavedFilterIcon>
+            </S.DeleteSmartFilterIcon>
           </S.ActiveSmartFilter>
           </S.ActiveSmartFilter>
         )}
         )}
       </S.ActiveSmartFilterWrapper>
       </S.ActiveSmartFilterWrapper>
+      {isQuickEditOpen && (
+        <FilterModal
+          quickEditMode
+          activeFilter={activeFilter}
+          toggleIsOpen={toggleQuickEdit}
+          editSavedFilter={editCurrentFilter}
+          filters={[]}
+          addFilter={() => null}
+          deleteFilter={() => null}
+          activeFilterHandler={() => null}
+        />
+      )}
+
       {isOpen && (
       {isOpen && (
         <FilterModal
         <FilterModal
           toggleIsOpen={toggle}
           toggleIsOpen={toggle}

+ 1 - 1
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/__tests__/EditFilter.spec.tsx

@@ -27,7 +27,7 @@ describe('EditFilter component', () => {
     await act(() => {
     await act(() => {
       renderComponent();
       renderComponent();
     });
     });
-    expect(screen.getByText(/edit saved filter/i)).toBeInTheDocument();
+    expect(screen.getByText(/edit filter/i)).toBeInTheDocument();
   });
   });
 
 
   it('closes editFilter modal', async () => {
   it('closes editFilter modal', async () => {

+ 9 - 3
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/__tests__/FilterModal.spec.tsx

@@ -3,11 +3,16 @@ import FilterModal, {
   FilterModalProps,
   FilterModalProps,
 } from 'components/Topics/Topic/Messages/Filters/FilterModal';
 } from 'components/Topics/Topic/Messages/Filters/FilterModal';
 import { render } from 'lib/testHelpers';
 import { render } from 'lib/testHelpers';
-import { MessageFilters } from 'components/Topics/Topic/Messages/Filters/Filters';
+import {
+  ActiveMessageFilter,
+  MessageFilters,
+} from 'components/Topics/Topic/Messages/Filters/Filters';
 import { screen, act } from '@testing-library/react';
 import { screen, act } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 import userEvent from '@testing-library/user-event';
 
 
-const filters: MessageFilters[] = [{ name: 'name', code: 'code' }];
+const filter = { name: 'name', code: 'code' };
+const filters: MessageFilters[] = [filter];
+const activeFilter: ActiveMessageFilter = { index: -1, ...filter };
 
 
 const renderComponent = (props?: Partial<FilterModalProps>) =>
 const renderComponent = (props?: Partial<FilterModalProps>) =>
   render(
   render(
@@ -18,6 +23,7 @@ const renderComponent = (props?: Partial<FilterModalProps>) =>
       deleteFilter={jest.fn()}
       deleteFilter={jest.fn()}
       activeFilterHandler={jest.fn()}
       activeFilterHandler={jest.fn()}
       editSavedFilter={jest.fn()}
       editSavedFilter={jest.fn()}
+      activeFilter={activeFilter}
       {...props}
       {...props}
     />
     />
   );
   );
@@ -36,7 +42,7 @@ describe('FilterModal component', () => {
     await userEvent.click(screen.getByRole('savedFilterText'));
     await userEvent.click(screen.getByRole('savedFilterText'));
     await userEvent.click(screen.getByText('Edit'));
     await userEvent.click(screen.getByText('Edit'));
     expect(
     expect(
-      screen.getByRole('heading', { name: /edit saved filter/i, level: 3 })
+      screen.getByRole('heading', { name: /edit filter/i, level: 3 })
     ).toBeInTheDocument();
     ).toBeInTheDocument();
   });
   });
 });
 });

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

@@ -8,7 +8,7 @@ import { FormError } from 'components/common/Input/Input.styled';
 import Select from 'components/common/Select/Select';
 import Select from 'components/common/Select/Select';
 import Input from 'components/common/Input/Input';
 import Input from 'components/common/Input/Input';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
-import CloseIcon from 'components/common/Icons/CloseIcon';
+import CloseCircleIcon from 'components/common/Icons/CloseCircleIcon';
 import * as C from 'components/Topics/shared/Form/TopicForm.styled';
 import * as C from 'components/Topics/shared/Form/TopicForm.styled';
 import { ConfigSource } from 'generated-sources';
 import { ConfigSource } from 'generated-sources';
 
 
@@ -125,7 +125,7 @@ const CustomParamField: React.FC<Props> = ({
           }
           }
           title={`Delete customParam field ${index}`}
           title={`Delete customParam field ${index}`}
         >
         >
-          <CloseIcon aria-hidden />
+          <CloseCircleIcon aria-hidden />
         </IconButtonWrapper>
         </IconButtonWrapper>
       </S.DeleteButtonWrapper>
       </S.DeleteButtonWrapper>
     </C.Column>
     </C.Column>

+ 11 - 3
kafka-ui-react-app/src/components/Version/Version.tsx

@@ -8,14 +8,22 @@ import * as S from './Version.styled';
 
 
 const Version: React.FC = () => {
 const Version: React.FC = () => {
   const { data: latestVersionInfo = {} } = useLatestVersion();
   const { data: latestVersionInfo = {} } = useLatestVersion();
-  const { buildTime, commitId, isLatestRelease } = latestVersionInfo.build;
+  const { buildTime, commitId, isLatestRelease, version } =
+    latestVersionInfo.build;
   const { versionTag } = latestVersionInfo?.latestRelease || '';
   const { versionTag } = latestVersionInfo?.latestRelease || '';
 
 
+  const currentVersion =
+    isLatestRelease && version?.match(versionTag)
+      ? versionTag
+      : formatTimestamp(buildTime);
+
   return (
   return (
     <S.Wrapper>
     <S.Wrapper>
       {!isLatestRelease && (
       {!isLatestRelease && (
         <S.OutdatedWarning
         <S.OutdatedWarning
-          title={`Your app version is outdated. Current latest version is ${versionTag}`}
+          title={`Your app version is outdated. Latest version is ${
+            versionTag || 'UNKNOWN'
+          }`}
         >
         >
           <WarningIcon />
           <WarningIcon />
         </S.OutdatedWarning>
         </S.OutdatedWarning>
@@ -32,7 +40,7 @@ const Version: React.FC = () => {
           </S.CurrentCommitLink>
           </S.CurrentCommitLink>
         </div>
         </div>
       )}
       )}
-      <S.CurrentVersion>{formatTimestamp(buildTime)}</S.CurrentVersion>
+      <S.CurrentVersion>{currentVersion}</S.CurrentVersion>
     </S.Wrapper>
     </S.Wrapper>
   );
   );
 };
 };

+ 2 - 2
kafka-ui-react-app/src/components/common/Alert/Alert.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
 import React from 'react';
-import CloseIcon from 'components/common/Icons/CloseIcon';
+import CloseCircleIcon from 'components/common/Icons/CloseCircleIcon';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
 import { ToastTypes } from 'lib/errorHandling';
 import { ToastTypes } from 'lib/errorHandling';
 
 
@@ -19,7 +19,7 @@ const Alert: React.FC<AlertProps> = ({ title, type, message, onDissmiss }) => (
       <S.Message role="contentinfo">{message}</S.Message>
       <S.Message role="contentinfo">{message}</S.Message>
     </div>
     </div>
     <IconButtonWrapper role="button" onClick={onDissmiss}>
     <IconButtonWrapper role="button" onClick={onDissmiss}>
-      <CloseIcon />
+      <CloseCircleIcon />
     </IconButtonWrapper>
     </IconButtonWrapper>
   </S.Alert>
   </S.Alert>
 );
 );

+ 24 - 0
kafka-ui-react-app/src/components/common/Icons/CloseCircleIcon.tsx

@@ -0,0 +1,24 @@
+import React from 'react';
+import { useTheme } from 'styled-components';
+
+const CloseCircleIcon: React.FC = () => {
+  const theme = useTheme();
+  return (
+    <svg
+      width="16"
+      height="16"
+      viewBox="0 0 16 16"
+      fill="none"
+      xmlns="http://www.w3.org/2000/svg"
+    >
+      <path
+        fillRule="evenodd"
+        clipRule="evenodd"
+        d="M8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16ZM11.707 4.29289C12.0976 4.68342 12.0976 5.31658 11.707 5.70711L9.41415 8L11.707 10.2929C12.0976 10.6834 12.0976 11.3166 11.707 11.7071C11.3165 12.0976 10.6834 12.0976 10.2928 11.7071L7.99994 9.41421L5.70711 11.707C5.31658 12.0976 4.68342 12.0976 4.29289 11.707C3.90237 11.3165 3.90237 10.6834 4.29289 10.2928L6.58573 8L4.29289 5.70717C3.90237 5.31664 3.90237 4.68348 4.29289 4.29295C4.68342 3.90243 5.31658 3.90243 5.70711 4.29295L7.99994 6.58579L10.2928 4.29289C10.6834 3.90237 11.3165 3.90237 11.707 4.29289Z"
+        fill={theme.icons.closeCircleIcon}
+      />
+    </svg>
+  );
+};
+
+export default CloseCircleIcon;

+ 9 - 9
kafka-ui-react-app/src/components/common/Icons/CloseIcon.tsx

@@ -1,24 +1,24 @@
 import React from 'react';
 import React from 'react';
-import { useTheme } from 'styled-components';
+import styled, { useTheme } from 'styled-components';
 
 
-const CloseIcon: React.FC = () => {
+const CloseIcon: React.FC<{ className?: string }> = ({ className }) => {
   const theme = useTheme();
   const theme = useTheme();
   return (
   return (
     <svg
     <svg
-      width="16"
-      height="16"
-      viewBox="0 0 16 16"
-      fill="none"
+      width="10"
+      height="10"
+      viewBox="0 0 10 10"
+      className={className}
+      fill={theme.icons.closeIcon.normal}
       xmlns="http://www.w3.org/2000/svg"
       xmlns="http://www.w3.org/2000/svg"
     >
     >
       <path
       <path
         fillRule="evenodd"
         fillRule="evenodd"
         clipRule="evenodd"
         clipRule="evenodd"
-        d="M8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16ZM11.707 4.29289C12.0976 4.68342 12.0976 5.31658 11.707 5.70711L9.41415 8L11.707 10.2929C12.0976 10.6834 12.0976 11.3166 11.707 11.7071C11.3165 12.0976 10.6834 12.0976 10.2928 11.7071L7.99994 9.41421L5.70711 11.707C5.31658 12.0976 4.68342 12.0976 4.29289 11.707C3.90237 11.3165 3.90237 10.6834 4.29289 10.2928L6.58573 8L4.29289 5.70717C3.90237 5.31664 3.90237 4.68348 4.29289 4.29295C4.68342 3.90243 5.31658 3.90243 5.70711 4.29295L7.99994 6.58579L10.2928 4.29289C10.6834 3.90237 11.3165 3.90237 11.707 4.29289Z"
-        fill={theme.icons.closeIcon}
+        d="M0.646447 0.646447C0.841709 0.451184 1.15829 0.451184 1.35355 0.646447L5 4.29289L8.64645 0.646447C8.84171 0.451184 9.15829 0.451184 9.35355 0.646447C9.54882 0.841709 9.54882 1.15829 9.35355 1.35355L5.70711 5L9.35355 8.64645C9.54882 8.84171 9.54882 9.15829 9.35355 9.35355C9.15829 9.54882 8.84171 9.54882 8.64645 9.35355L5 5.70711L1.35355 9.35355C1.15829 9.54881 0.841709 9.54881 0.646447 9.35355C0.451185 9.15829 0.451185 8.84171 0.646447 8.64645L4.29289 5L0.646447 1.35355C0.451184 1.15829 0.451184 0.841709 0.646447 0.646447Z"
       />
       />
     </svg>
     </svg>
   );
   );
 };
 };
 
 
-export default CloseIcon;
+export default styled(CloseIcon)``;

+ 11 - 30
kafka-ui-react-app/src/components/common/Icons/EditIcon.tsx

@@ -1,42 +1,23 @@
-import React, { FC } from 'react';
-import { useTheme } from 'styled-components';
+import React from 'react';
+import styled, { useTheme } from 'styled-components';
 
 
-const EditIcon: FC = () => {
+const EditIcon: React.FC<{ className?: string }> = ({ className }) => {
   const theme = useTheme();
   const theme = useTheme();
   return (
   return (
     <svg
     <svg
-      viewBox="0 0 64 64"
-      width="12"
-      height="12"
+      width="13"
+      height="14"
+      viewBox="0 0 13 14"
+      className={className}
+      fill={theme.icons.editIcon.normal}
       xmlns="http://www.w3.org/2000/svg"
       xmlns="http://www.w3.org/2000/svg"
       aria-labelledby="title"
       aria-labelledby="title"
-      aria-describedby="desc"
-      role="img"
     >
     >
       <title>Edit</title>
       <title>Edit</title>
-      <desc>A line styled icon from Orion Icon Library.</desc>
-      <path
-        d="M54.368 17.674l6.275-6.267-8.026-8.025-6.274 6.267"
-        strokeWidth="2"
-        strokeMiterlimit="10"
-        stroke={theme.icons.editIcon}
-        fill="none"
-        data-name="layer2"
-        strokeLinejoin="round"
-        strokeLinecap="round"
-      />
-      <path
-        d="M17.766 54.236l36.602-36.562-8.025-8.025L9.74 46.211 3.357 60.618l14.409-6.382zM9.74 46.211l8.026 8.025"
-        strokeWidth="2"
-        strokeMiterlimit="10"
-        stroke={theme.icons.editIcon}
-        fill="none"
-        data-name="layer1"
-        strokeLinejoin="round"
-        strokeLinecap="round"
-      />
+      <path d="M9.53697 1.15916C10.0914 0.60473 10.9886 0.602975 11.5408 1.15524L12.5408 2.15518C13.093 2.70745 13.0913 3.60461 12.5368 4.15904L10.3564 6.33944L7.35657 3.33956L9.53697 1.15916Z" />
+      <path d="M6.64946 4.04667L9.53674e-07 10.6961L0 13.696L2.99988 13.696L9.64934 7.04655L6.64946 4.04667Z" />
     </svg>
     </svg>
   );
   );
 };
 };
 
 
-export default EditIcon;
+export default styled(EditIcon)``;

+ 2 - 2
kafka-ui-react-app/src/components/common/Search/Search.tsx

@@ -2,7 +2,7 @@ import React, { useRef } from 'react';
 import { useDebouncedCallback } from 'use-debounce';
 import { useDebouncedCallback } from 'use-debounce';
 import Input from 'components/common/Input/Input';
 import Input from 'components/common/Input/Input';
 import { useSearchParams } from 'react-router-dom';
 import { useSearchParams } from 'react-router-dom';
-import CloseIcon from 'components/common/Icons/CloseIcon';
+import CloseCircleIcon from 'components/common/Icons/CloseCircleIcon';
 import styled from 'styled-components';
 import styled from 'styled-components';
 
 
 interface SearchProps {
 interface SearchProps {
@@ -66,7 +66,7 @@ const Search: React.FC<SearchProps> = ({
       search
       search
       clearIcon={
       clearIcon={
         <IconButtonWrapper onClick={clearSearchValue}>
         <IconButtonWrapper onClick={clearSearchValue}>
-          <CloseIcon />
+          <CloseCircleIcon />
         </IconButtonWrapper>
         </IconButtonWrapper>
       }
       }
     />
     />

+ 33 - 5
kafka-ui-react-app/src/theme/theme.ts

@@ -162,7 +162,18 @@ const baseTheme = {
   },
   },
   icons: {
   icons: {
     chevronDownIcon: Colors.neutral[0],
     chevronDownIcon: Colors.neutral[0],
-    editIcon: Colors.neutral[30],
+    editIcon: {
+      normal: Colors.neutral[30],
+      hover: Colors.neutral[90],
+      active: Colors.neutral[100],
+      border: Colors.neutral[10],
+    },
+    closeIcon: {
+      normal: Colors.neutral[30],
+      hover: Colors.neutral[90],
+      active: Colors.neutral[100],
+      border: Colors.neutral[10],
+    },
     cancelIcon: Colors.neutral[30],
     cancelIcon: Colors.neutral[30],
     autoIcon: Colors.neutral[95],
     autoIcon: Colors.neutral[95],
     fileIcon: Colors.neutral[90],
     fileIcon: Colors.neutral[90],
@@ -171,7 +182,7 @@ const baseTheme = {
     moonIcon: Colors.neutral[95],
     moonIcon: Colors.neutral[95],
     sunIcon: Colors.neutral[95],
     sunIcon: Colors.neutral[95],
     infoIcon: Colors.neutral[30],
     infoIcon: Colors.neutral[30],
-    closeIcon: Colors.neutral[30],
+    closeCircleIcon: Colors.neutral[30],
     deleteIcon: Colors.red[20],
     deleteIcon: Colors.red[20],
     warningIcon: Colors.yellow[20],
     warningIcon: Colors.yellow[20],
     warningRedIcon: {
     warningRedIcon: {
@@ -688,10 +699,13 @@ export const theme = {
       color: Colors.neutral[80],
       color: Colors.neutral[80],
     },
     },
   },
   },
+  activeFilter: {
+    color: Colors.neutral[70],
+    backgroundColor: Colors.neutral[5],
+  },
   savedFilter: {
   savedFilter: {
     filterName: Colors.neutral[90],
     filterName: Colors.neutral[90],
     color: Colors.neutral[30],
     color: Colors.neutral[30],
-    backgroundColor: Colors.neutral[5],
   },
   },
   editFilter: {
   editFilter: {
     textColor: Colors.brand[50],
     textColor: Colors.brand[50],
@@ -1128,10 +1142,13 @@ export const darkTheme: ThemeType = {
       color: Colors.neutral[0],
       color: Colors.neutral[0],
     },
     },
   },
   },
+  activeFilter: {
+    color: Colors.neutral[0],
+    backgroundColor: Colors.neutral[80],
+  },
   savedFilter: {
   savedFilter: {
     filterName: Colors.neutral[0],
     filterName: Colors.neutral[0],
     color: Colors.neutral[70],
     color: Colors.neutral[70],
-    backgroundColor: Colors.neutral[80],
   },
   },
   editFilter: {
   editFilter: {
     textColor: Colors.brand[30],
     textColor: Colors.brand[30],
@@ -1157,7 +1174,18 @@ export const darkTheme: ThemeType = {
   },
   },
   icons: {
   icons: {
     ...baseTheme.icons,
     ...baseTheme.icons,
-    editIcon: Colors.neutral[0],
+    editIcon: {
+      normal: Colors.neutral[50],
+      hover: Colors.neutral[30],
+      active: Colors.neutral[40],
+      border: Colors.neutral[70],
+    },
+    closeIcon: {
+      normal: Colors.neutral[50],
+      hover: Colors.neutral[30],
+      active: Colors.neutral[40],
+      border: Colors.neutral[70],
+    },
     cancelIcon: Colors.neutral[0],
     cancelIcon: Colors.neutral[0],
     autoIcon: Colors.neutral[0],
     autoIcon: Colors.neutral[0],
     fileIcon: Colors.neutral[0],
     fileIcon: Colors.neutral[0],

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

@@ -3,7 +3,7 @@ import Input from 'components/common/Input/Input';
 import { useFieldArray, useFormContext } from 'react-hook-form';
 import { useFieldArray, useFormContext } from 'react-hook-form';
 import { FormError, InputHint } from 'components/common/Input/Input.styled';
 import { FormError, InputHint } from 'components/common/Input/Input.styled';
 import { ErrorMessage } from '@hookform/error-message';
 import { ErrorMessage } from '@hookform/error-message';
-import CloseIcon from 'components/common/Icons/CloseIcon';
+import CloseCircleIcon from 'components/common/Icons/CloseCircleIcon';
 import { Button } from 'components/common/Button/Button';
 import { Button } from 'components/common/Button/Button';
 import PlusIcon from 'components/common/Icons/PlusIcon';
 import PlusIcon from 'components/common/Icons/PlusIcon';
 import * as S from 'widgets/ClusterConfigForm/ClusterConfigForm.styled';
 import * as S from 'widgets/ClusterConfigForm/ClusterConfigForm.styled';
@@ -80,7 +80,7 @@ const KafkaCluster: React.FC = () => {
                 aria-label="deleteProperty"
                 aria-label="deleteProperty"
                 onClick={() => remove(index)}
                 onClick={() => remove(index)}
               >
               >
-                <CloseIcon aria-hidden />
+                <CloseCircleIcon aria-hidden />
               </S.BootstrapServerActions>
               </S.BootstrapServerActions>
             </S.BootstrapServer>
             </S.BootstrapServer>
           ))}
           ))}

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

@@ -5,7 +5,7 @@ import Input from 'components/common/Input/Input';
 import { useFieldArray, useFormContext } from 'react-hook-form';
 import { useFieldArray, useFormContext } from 'react-hook-form';
 import PlusIcon from 'components/common/Icons/PlusIcon';
 import PlusIcon from 'components/common/Icons/PlusIcon';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
 import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper';
-import CloseIcon from 'components/common/Icons/CloseIcon';
+import CloseCircleIcon from 'components/common/Icons/CloseCircleIcon';
 import {
 import {
   FlexGrow1,
   FlexGrow1,
   FlexRow,
   FlexRow,
@@ -66,7 +66,7 @@ const KafkaConnect = () => {
                 </FlexGrow1>
                 </FlexGrow1>
                 <S.RemoveButton onClick={() => remove(index)}>
                 <S.RemoveButton onClick={() => remove(index)}>
                   <IconButtonWrapper aria-label="deleteProperty">
                   <IconButtonWrapper aria-label="deleteProperty">
-                    <CloseIcon aria-hidden />
+                    <CloseCircleIcon aria-hidden />
                   </IconButtonWrapper>
                   </IconButtonWrapper>
                 </S.RemoveButton>
                 </S.RemoveButton>
               </FlexRow>
               </FlexRow>

+ 2 - 2
pom.xml

@@ -38,13 +38,13 @@
         <snakeyaml.version>2.0</snakeyaml.version>
         <snakeyaml.version>2.0</snakeyaml.version>
         <spring-boot.version>3.0.6</spring-boot.version>
         <spring-boot.version>3.0.6</spring-boot.version>
         <kafka-ui-serde-api.version>1.0.0</kafka-ui-serde-api.version>
         <kafka-ui-serde-api.version>1.0.0</kafka-ui-serde-api.version>
-        <odd-oddrn-generator.version>0.1.15</odd-oddrn-generator.version>
+        <odd-oddrn-generator.version>0.1.17</odd-oddrn-generator.version>
         <odd-oddrn-client.version>0.1.23</odd-oddrn-client.version>
         <odd-oddrn-client.version>0.1.23</odd-oddrn-client.version>
         <org.json.version>20230227</org.json.version>
         <org.json.version>20230227</org.json.version>
 
 
         <!-- Test dependency versions -->
         <!-- Test dependency versions -->
         <junit.version>5.9.1</junit.version>
         <junit.version>5.9.1</junit.version>
-        <mockito.version>5.3.0</mockito.version>
+        <mockito.version>5.3.1</mockito.version>
         <okhttp3.mockwebserver.version>4.10.0</okhttp3.mockwebserver.version>
         <okhttp3.mockwebserver.version>4.10.0</okhttp3.mockwebserver.version>
         <testcontainers.version>1.17.5</testcontainers.version>
         <testcontainers.version>1.17.5</testcontainers.version>