Browse Source

Merge branch 'master' into rbac_classes_refactoring

Ilya Kuramshin 1 năm trước cách đây
mục cha
commit
bec96674e2

+ 2 - 2
.github/workflows/frontend.yaml

@@ -25,11 +25,11 @@ jobs:
           ref: ${{ github.event.pull_request.head.sha }}
       - uses: pnpm/action-setup@v2.4.0
         with:
-          version: 7.4.0
+          version: 8.6.12
       - name: Install node
         uses: actions/setup-node@v3.8.1
         with:
-          node-version: "16.15.0"
+          node-version: "18.17.1"
           cache: "pnpm"
           cache-dependency-path: "./kafka-ui-react-app/pnpm-lock.yaml"
       - name: Install Node dependencies

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

@@ -16,6 +16,8 @@ import java.util.stream.Stream;
 
 public class BrokersConfigTab extends BasePage {
 
+  protected List<SelenideElement> editBtn = $$x("//button[@aria-label='editAction']");
+  protected SelenideElement searchByKeyField = $x("//input[@placeholder='Search by Key or Value']");
   protected SelenideElement sourceInfoIcon = $x("//div[text()='Source']/..//div/div[@class]");
   protected SelenideElement sourceInfoTooltip = $x("//div[text()='Source']/..//div/div[@style]");
   protected ElementsCollection editBtns = $$x("//button[@aria-label='editAction']");

+ 1 - 1
kafka-ui-react-app/.nvmrc

@@ -1 +1 @@
-v16.15.0
+v18.17.1

+ 2 - 2
kafka-ui-react-app/package.json

@@ -106,7 +106,7 @@
     "vite-plugin-ejs": "^1.6.4"
   },
   "engines": {
-    "node": "v16.15.0",
-    "pnpm": "^7.4.0"
+    "node": "v18.17.1",
+    "pnpm": "^8.6.12"
   }
 }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 331 - 264
kafka-ui-react-app/pnpm-lock.yaml


+ 12 - 7
kafka-ui-react-app/src/components/Brokers/Broker/Configs/Configs.tsx

@@ -34,14 +34,19 @@ const Configs: React.FC = () => {
 
   const getData = () => {
     return data
-      .filter(
-        (item) =>
-          item.name.toLocaleLowerCase().indexOf(keyword.toLocaleLowerCase()) >
-          -1
-      )
+      .filter((item) => {
+        const nameMatch = item.name
+          .toLocaleLowerCase()
+          .includes(keyword.toLocaleLowerCase());
+        return nameMatch
+          ? true
+          : item.value &&
+              item.value
+                .toLocaleLowerCase()
+                .includes(keyword.toLocaleLowerCase()); // try to match the keyword on any of the item.value elements when nameMatch fails but item.value exists
+      })
       .sort((a, b) => {
         if (a.source === b.source) return 0;
-
         return a.source === ConfigSource.DYNAMIC_BROKER_CONFIG ? -1 : 1;
       });
   };
@@ -95,7 +100,7 @@ const Configs: React.FC = () => {
       <S.SearchWrapper>
         <Search
           onChange={setKeyword}
-          placeholder="Search by Key"
+          placeholder="Search by Key or Value"
           value={keyword}
         />
       </S.SearchWrapper>

+ 1 - 1
kafka-ui-react-app/src/components/Brokers/Broker/__test__/Broker.spec.tsx

@@ -13,7 +13,7 @@ import { brokersPayload } from 'lib/fixtures/brokers';
 import { clusterStatsPayload } from 'lib/fixtures/clusters';
 
 const clusterName = 'local';
-const brokerId = 1;
+const brokerId = 200;
 const activeClassName = 'is-active';
 const brokerLogdir = {
   pageText: 'brokerLogdir',

+ 2 - 2
kafka-ui-react-app/src/components/Brokers/BrokersList/BrokersList.tsx

@@ -73,13 +73,13 @@ const BrokersList: React.FC = () => {
         header: 'Broker ID',
         accessorKey: 'brokerId',
         // eslint-disable-next-line react/no-unstable-nested-components
-        cell: ({ row: { id }, getValue }) => (
+        cell: ({ getValue }) => (
           <S.RowCell>
             <LinkCell
               value={`${getValue<string | number>()}`}
               to={encodeURIComponent(`${getValue<string | number>()}`)}
             />
-            {id === String(activeControllers) && (
+            {getValue<string | number>() === activeControllers && (
               <Tooltip
                 value={<CheckMarkRoundIcon />}
                 content="Active Controller"

+ 37 - 4
kafka-ui-react-app/src/components/Brokers/BrokersList/__test__/BrokersList.spec.tsx

@@ -56,11 +56,11 @@ describe('BrokersList Component', () => {
       });
       it('opens broker when row clicked', async () => {
         renderComponent();
-        await userEvent.click(screen.getByRole('cell', { name: '0' }));
+        await userEvent.click(screen.getByRole('cell', { name: '100' }));
 
         await waitFor(() =>
           expect(mockedUsedNavigate).toBeCalledWith(
-            clusterBrokerPath(clusterName, '0')
+            clusterBrokerPath(clusterName, '100')
           )
         );
       });
@@ -124,6 +124,39 @@ describe('BrokersList Component', () => {
       });
     });
 
+    describe('BrokersList', () => {
+      describe('when the brokers are loaded', () => {
+        const testActiveControllers = 0;
+        beforeEach(() => {
+          (useBrokers as jest.Mock).mockImplementation(() => ({
+            data: brokersPayload,
+          }));
+          (useClusterStats as jest.Mock).mockImplementation(() => ({
+            data: clusterStatsPayload,
+          }));
+        });
+
+        it(`Indicates correct active cluster`, async () => {
+          renderComponent();
+          await waitFor(() =>
+            expect(screen.getByRole('tooltip')).toBeInTheDocument()
+          );
+        });
+        it(`Correct display even if there is no active cluster: ${testActiveControllers} `, async () => {
+          (useClusterStats as jest.Mock).mockImplementation(() => ({
+            data: {
+              ...clusterStatsPayload,
+              activeControllers: testActiveControllers,
+            },
+          }));
+          renderComponent();
+          await waitFor(() =>
+            expect(screen.queryByRole('tooltip')).not.toBeInTheDocument()
+          );
+        });
+      });
+    });
+
     describe('when diskUsage is empty', () => {
       beforeEach(() => {
         (useBrokers as jest.Mock).mockImplementation(() => ({
@@ -157,11 +190,11 @@ describe('BrokersList Component', () => {
       });
       it('opens broker when row clicked', async () => {
         renderComponent();
-        await userEvent.click(screen.getByRole('cell', { name: '1' }));
+        await userEvent.click(screen.getByRole('cell', { name: '100' }));
 
         await waitFor(() =>
           expect(mockedUsedNavigate).toBeCalledWith(
-            clusterBrokerPath(clusterName, '1')
+            clusterBrokerPath(clusterName, '100')
           )
         );
       });

+ 1 - 1
kafka-ui-react-app/src/components/Topics/New/New.tsx

@@ -15,7 +15,7 @@ enum Filters {
   PARTITION_COUNT = 'partitionCount',
   REPLICATION_FACTOR = 'replicationFactor',
   INSYNC_REPLICAS = 'inSyncReplicas',
-  CLEANUP_POLICY = 'Delete',
+  CLEANUP_POLICY = 'cleanUpPolicy',
 }
 
 const New: React.FC = () => {

+ 5 - 5
kafka-ui-react-app/src/components/Topics/New/__test__/New.spec.tsx

@@ -60,16 +60,16 @@ describe('New', () => {
     await userEvent.clear(screen.getByPlaceholderText('Topic Name'));
     await userEvent.tab();
     await expect(
-      screen.getByText('name is a required field')
+      screen.getByText('Topic Name is required')
     ).toBeInTheDocument();
     await userEvent.type(
-      screen.getByLabelText('Number of partitions *'),
+      screen.getByLabelText('Number of Partitions *'),
       minValue
     );
-    await userEvent.clear(screen.getByLabelText('Number of partitions *'));
+    await userEvent.clear(screen.getByLabelText('Number of Partitions *'));
     await userEvent.tab();
     await expect(
-      screen.getByText('Number of partitions is required and must be a number')
+      screen.getByText('Number of Partitions is required and must be a number')
     ).toBeInTheDocument();
 
     expect(createTopicMock).not.toHaveBeenCalled();
@@ -89,7 +89,7 @@ describe('New', () => {
     renderComponent(clusterTopicNewPath(clusterName));
     await userEvent.type(screen.getByPlaceholderText('Topic Name'), topicName);
     await userEvent.type(
-      screen.getByLabelText('Number of partitions *'),
+      screen.getByLabelText('Number of Partitions *'),
       minValue
     );
     await userEvent.click(screen.getByText('Create topic'));

+ 5 - 0
kafka-ui-react-app/src/components/Topics/shared/Form/TopicForm.styled.ts

@@ -1,4 +1,5 @@
 import styled from 'styled-components';
+import Input from 'components/common/Input/Input';
 
 export const Column = styled.div`
   display: flex;
@@ -16,6 +17,10 @@ export const CustomParamsHeading = styled.h4`
   color: ${({ theme }) => theme.heading.h4};
 `;
 
+export const MessageSizeInput = styled(Input)`
+  min-width: 195px;
+`;
+
 export const Label = styled.div`
   display: flex;
   gap: 16px;

+ 3 - 3
kafka-ui-react-app/src/components/Topics/shared/Form/TopicForm.tsx

@@ -109,12 +109,12 @@ const TopicForm: React.FC<Props> = ({
             {!isEditing && (
               <div>
                 <InputLabel htmlFor="topicFormNumberOfPartitions">
-                  Number of partitions *
+                  Number of Partitions *
                 </InputLabel>
                 <Input
                   id="topicFormNumberOfPartitions"
                   type="number"
-                  placeholder="Number of partitions"
+                  placeholder="Number of Partitions"
                   min="1"
                   name="partitions"
                   positiveOnly
@@ -228,7 +228,7 @@ const TopicForm: React.FC<Props> = ({
             <InputLabel htmlFor="topicFormMaxMessageBytes">
               Maximum message size in bytes
             </InputLabel>
-            <Input
+            <S.MessageSizeInput
               id="topicFormMaxMessageBytes"
               type="number"
               placeholder="Maximum message size"

+ 1 - 1
kafka-ui-react-app/src/components/Topics/shared/Form/__tests__/TopicForm.spec.tsx

@@ -37,7 +37,7 @@ describe('TopicForm', () => {
 
     expectByRoleAndNameToBeInDocument('textbox', 'Topic Name *');
 
-    expectByRoleAndNameToBeInDocument('spinbutton', 'Number of partitions *');
+    expectByRoleAndNameToBeInDocument('spinbutton', 'Number of Partitions *');
     expectByRoleAndNameToBeInDocument('spinbutton', 'Replication Factor');
 
     expectByRoleAndNameToBeInDocument('spinbutton', 'Min In Sync Replicas');

+ 1 - 0
kafka-ui-react-app/src/components/common/Icons/CheckMarkRoundIcon.tsx

@@ -7,6 +7,7 @@ const CheckMarkRoundIcon: React.FC = () => {
       height="14"
       viewBox="0 0 14 14"
       fill="none"
+      role="tooltip"
       xmlns="http://www.w3.org/2000/svg"
     >
       <path

+ 2 - 2
kafka-ui-react-app/src/lib/fixtures/brokers.ts

@@ -1,8 +1,8 @@
 import { BrokerConfig, BrokersLogdirs, ConfigSource } from 'generated-sources';
 
 export const brokersPayload = [
-  { id: 1, host: 'b-1.test.kafka.amazonaws.com', port: 9092 },
-  { id: 2, host: 'b-2.test.kafka.amazonaws.com', port: 9092 },
+  { id: 100, host: 'b-1.test.kafka.amazonaws.com', port: 9092 },
+  { id: 200, host: 'b-2.test.kafka.amazonaws.com', port: 9092 },
 ];
 
 const partition = {

+ 3 - 3
kafka-ui-react-app/src/lib/fixtures/clusters.ts

@@ -32,15 +32,15 @@ export const clustersPayload: Cluster[] = [
 
 export const clusterStatsPayload = {
   brokerCount: 2,
-  activeControllers: 1,
+  activeControllers: 100,
   onlinePartitionCount: 138,
   offlinePartitionCount: 0,
   inSyncReplicasCount: 239,
   outOfSyncReplicasCount: 0,
   underReplicatedPartitionCount: 0,
   diskUsage: [
-    { brokerId: 0, segmentSize: 334567, segmentCount: 245 },
-    { brokerId: 1, segmentSize: 12345678, segmentCount: 121 },
+    { brokerId: 100, segmentSize: 334567, segmentCount: 245 },
+    { brokerId: 200, segmentSize: 12345678, segmentCount: 121 },
   ],
   version: '2.2.1',
 };

+ 0 - 2
kafka-ui-react-app/src/lib/hooks/api/topics.ts

@@ -76,7 +76,6 @@ const formatTopicCreation = (form: TopicFormData): TopicCreation => {
     partitions,
     replicationFactor,
     cleanupPolicy,
-    retentionBytes,
     retentionMs,
     maxMessageBytes,
     minInSyncReplicas,
@@ -86,7 +85,6 @@ const formatTopicCreation = (form: TopicFormData): TopicCreation => {
   const configs = {
     'cleanup.policy': cleanupPolicy,
     'retention.ms': retentionMs.toString(),
-    'retention.bytes': retentionBytes.toString(),
     'max.message.bytes': maxMessageBytes.toString(),
     'min.insync.replicas': minInSyncReplicas.toString(),
     ...Object.values(customParams || {}).reduce(topicReducer, {}),

+ 3 - 3
kafka-ui-react-app/src/lib/yupExtended.ts

@@ -66,17 +66,17 @@ export const topicFormValidationSchema = yup.object().shape({
   name: yup
     .string()
     .max(249)
-    .required()
+    .required('Topic Name is required')
     .matches(
       TOPIC_NAME_VALIDATION_PATTERN,
       'Only alphanumeric, _, -, and . allowed'
     ),
   partitions: yup
     .number()
-    .min(1)
+    .min(1, 'Number of Partitions must be greater than or equal to 1')
     .max(2147483647)
     .required()
-    .typeError('Number of partitions is required and must be a number'),
+    .typeError('Number of Partitions is required and must be a number'),
   replicationFactor: yup.string(),
   minInSyncReplicas: yup.string(),
   cleanupPolicy: yup.string().required(),

+ 0 - 1
kafka-ui-react-app/src/redux/interfaces/topic.ts

@@ -44,7 +44,6 @@ export interface TopicFormData {
   minInSyncReplicas: number;
   cleanupPolicy: string;
   retentionMs: number;
-  retentionBytes: number;
   maxMessageBytes: number;
   customParams: {
     name: string;

+ 2 - 2
pom.xml

@@ -49,8 +49,8 @@
         <testcontainers.version>1.17.5</testcontainers.version>
 
         <!-- Frontend dependency versions -->
-        <node.version>v16.15.0</node.version>
-        <pnpm.version>v7.4.0</pnpm.version>
+        <node.version>v18.17.1</node.version>
+        <pnpm.version>v8.6.12</pnpm.version>
 
         <!-- Plugin versions -->
         <fabric8-maven-plugin.version>0.42.1</fabric8-maven-plugin.version>

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác