Prechádzať zdrojové kódy

Review all tables and unify the way of data displaying. #602 (#687)

MBovtriukProvectus 4 rokov pred
rodič
commit
c035f58f5a
16 zmenil súbory, kde vykonal 322 pridanie a 127 odobranie
  1. 5 0
      kafka-ui-react-app/src/components/ConsumerGroups/Details/Details.tsx
  2. 8 0
      kafka-ui-react-app/src/components/ConsumerGroups/Details/__tests__/DetailsContainer.spec.tsx
  3. 43 42
      kafka-ui-react-app/src/components/ConsumerGroups/List/List.tsx
  4. 46 0
      kafka-ui-react-app/src/components/ConsumerGroups/List/__test__/List.spec.tsx
  5. 8 0
      kafka-ui-react-app/src/components/ConsumerGroups/List/__test__/ListContainer.spec.tsx
  6. 33 0
      kafka-ui-react-app/src/components/ConsumerGroups/List/__test__/ListItem.spec.tsx
  7. 5 0
      kafka-ui-react-app/src/components/Schemas/Details/Details.tsx
  8. 7 0
      kafka-ui-react-app/src/components/Schemas/Details/__test__/Details.spec.tsx
  9. 18 2
      kafka-ui-react-app/src/components/Schemas/Details/__test__/__snapshots__/Details.spec.tsx.snap
  10. 31 30
      kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/TopicConsumerGroups.tsx
  11. 2 4
      kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/__test__/TopicConsumerGroups.spec.tsx
  12. 42 43
      kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessagesTable.tsx
  13. 3 3
      kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/__test__/MessagesTable.spec.tsx
  14. 51 3
      kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/__test__/__snapshots__/MessagesTable.spec.tsx.snap
  15. 5 0
      kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/Overview.tsx
  16. 15 0
      kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx

+ 5 - 0
kafka-ui-react-app/src/components/ConsumerGroups/Details/Details.tsx

@@ -96,6 +96,11 @@ const Details: React.FC<Props> = ({
               </tr>
             </thead>
             <tbody>
+              {items.length === 0 && (
+                <tr>
+                  <td colSpan={10}>No active consumer groups</td>
+                </tr>
+              )}
               {items.map((consumer) => (
                 <ListItem
                   key={consumer.consumerId}

+ 8 - 0
kafka-ui-react-app/src/components/ConsumerGroups/Details/__tests__/DetailsContainer.spec.tsx

@@ -0,0 +1,8 @@
+import React from 'react';
+import { containerRendersView } from 'lib/testHelpers';
+import Details from 'components/ConsumerGroups/Details/Details';
+import DetailsContainer from 'components/ConsumerGroups/Details/DetailsContainer';
+
+describe('DetailsContainer', () => {
+  containerRendersView(<DetailsContainer />, Details);
+});

+ 43 - 42
kafka-ui-react-app/src/components/ConsumerGroups/List/List.tsx

@@ -22,51 +22,52 @@ const List: React.FC<Props> = ({ consumerGroups }) => {
       <Breadcrumb>All Consumer Groups</Breadcrumb>
 
       <div className="box">
-        {consumerGroups.length > 0 ? (
-          <div>
-            <div className="columns">
-              <div className="column is-half is-offset-half">
-                <input
-                  id="searchText"
-                  type="text"
-                  name="searchText"
-                  className="input"
-                  placeholder="Search"
-                  value={searchText}
-                  onChange={handleInputChange}
-                />
-              </div>
+        <div>
+          <div className="columns">
+            <div className="column is-half is-offset-half">
+              <input
+                id="searchText"
+                type="text"
+                name="searchText"
+                className="input"
+                placeholder="Search"
+                value={searchText}
+                onChange={handleInputChange}
+              />
             </div>
-            <table className="table is-striped is-fullwidth is-hoverable">
-              <thead>
+          </div>
+          <table className="table is-striped is-fullwidth is-hoverable">
+            <thead>
+              <tr>
+                <th>Consumer group ID</th>
+                <th>Num of members</th>
+                <th>Num of topics</th>
+                <th>Messages behind</th>
+                <th>Coordinator</th>
+                <th>State</th>
+              </tr>
+            </thead>
+            <tbody>
+              {consumerGroups
+                .filter(
+                  (consumerGroup) =>
+                    !searchText ||
+                    consumerGroup?.groupId?.indexOf(searchText) >= 0
+                )
+                .map((consumerGroup) => (
+                  <ListItem
+                    key={consumerGroup.groupId}
+                    consumerGroup={consumerGroup}
+                  />
+                ))}
+              {consumerGroups.length === 0 && (
                 <tr>
-                  <th>Consumer group ID</th>
-                  <th>Num of members</th>
-                  <th>Num of topics</th>
-                  <th>Messages behind</th>
-                  <th>Coordinator</th>
-                  <th>State</th>
+                  <td colSpan={10}>No active consumer groups</td>
                 </tr>
-              </thead>
-              <tbody>
-                {consumerGroups
-                  .filter(
-                    (consumerGroup) =>
-                      !searchText ||
-                      consumerGroup?.groupId?.indexOf(searchText) >= 0
-                  )
-                  .map((consumerGroup) => (
-                    <ListItem
-                      key={consumerGroup.groupId}
-                      consumerGroup={consumerGroup}
-                    />
-                  ))}
-              </tbody>
-            </table>
-          </div>
-        ) : (
-          'No active consumer groups'
-        )}
+              )}
+            </tbody>
+          </table>
+        </div>
       </div>
     </div>
   );

+ 46 - 0
kafka-ui-react-app/src/components/ConsumerGroups/List/__test__/List.spec.tsx

@@ -0,0 +1,46 @@
+import React from 'react';
+import { shallow, mount } from 'enzyme';
+import List from 'components/ConsumerGroups/List/List';
+
+describe('List', () => {
+  const mockConsumerGroups = [
+    {
+      groupId: 'groupId',
+      members: 0,
+      topics: 1,
+      simple: false,
+      partitionAssignor: '',
+      coordinator: {
+        id: 1,
+        host: 'host',
+      },
+      partitions: [
+        {
+          consumerId: null,
+          currentOffset: 0,
+          endOffset: 0,
+          host: null,
+          messagesBehind: 0,
+          partition: 1,
+          topic: 'topic',
+        },
+      ],
+    },
+  ];
+  const component = shallow(
+    <List consumerGroups={mockConsumerGroups} clusterName="cluster" />
+  );
+  const componentEmpty = mount(
+    <List consumerGroups={[]} clusterName="cluster" />
+  );
+
+  it('render empty List consumer Groups', () => {
+    expect(componentEmpty.find('td').text()).toEqual(
+      'No active consumer groups'
+    );
+  });
+
+  it('render List consumer Groups', () => {
+    expect(component.exists('.section')).toBeTruthy();
+  });
+});

+ 8 - 0
kafka-ui-react-app/src/components/ConsumerGroups/List/__test__/ListContainer.spec.tsx

@@ -0,0 +1,8 @@
+import React from 'react';
+import { containerRendersView } from 'lib/testHelpers';
+import ListContainer from 'components/ConsumerGroups/List/ListContainer';
+import List from 'components/ConsumerGroups/List/List';
+
+describe('ListContainer', () => {
+  containerRendersView(<ListContainer />, List);
+});

+ 33 - 0
kafka-ui-react-app/src/components/ConsumerGroups/List/__test__/ListItem.spec.tsx

@@ -0,0 +1,33 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import ListItem from 'components/ConsumerGroups/List/ListItem';
+
+describe('List', () => {
+  const mockConsumerGroup = {
+    groupId: 'groupId',
+    members: 0,
+    topics: 1,
+    simple: false,
+    partitionAssignor: '',
+    coordinator: {
+      id: 1,
+      host: 'host',
+    },
+    partitions: [
+      {
+        consumerId: null,
+        currentOffset: 0,
+        endOffset: 0,
+        host: null,
+        messagesBehind: 0,
+        partition: 1,
+        topic: 'topic',
+      },
+    ],
+  };
+  const component = shallow(<ListItem consumerGroup={mockConsumerGroup} />);
+
+  it('render empty ListItem', () => {
+    expect(component.exists('.is-clickable')).toBeTruthy();
+  });
+});

+ 5 - 0
kafka-ui-react-app/src/components/Schemas/Details/Details.tsx

@@ -124,6 +124,11 @@ const Details: React.FC<DetailsProps> = ({
                 {versions.map((version) => (
                   <SchemaVersion key={version.id} version={version} />
                 ))}
+                {versions.length === 0 && (
+                  <tr>
+                    <td colSpan={10}>No active Schema</td>
+                  </tr>
+                )}
               </tbody>
             </table>
           </div>

+ 7 - 0
kafka-ui-react-app/src/components/Schemas/Details/__test__/Details.spec.tsx

@@ -49,6 +49,13 @@ describe('Details', () => {
         {...props}
       />
     );
+    describe('empty table', () => {
+      it('render empty table', () => {
+        const component = shallow(setupWrapper());
+        expect(component.find('td').text()).toEqual('No active Schema');
+      });
+    });
+
     describe('Initial state', () => {
       it('should call fetchSchemaVersions every render', () => {
         mount(

+ 18 - 2
kafka-ui-react-app/src/components/Schemas/Details/__test__/__snapshots__/Details.spec.tsx.snap

@@ -110,7 +110,15 @@ exports[`Details View Initial state matches snapshot 1`] = `
           </th>
         </tr>
       </thead>
-      <tbody />
+      <tbody>
+        <tr>
+          <td
+            colSpan={10}
+          >
+            No active Schema
+          </td>
+        </tr>
+      </tbody>
     </table>
   </div>
 </div>
@@ -393,7 +401,15 @@ exports[`Details View when page with schema versions loaded when versions are em
           </th>
         </tr>
       </thead>
-      <tbody />
+      <tbody>
+        <tr>
+          <td
+            colSpan={10}
+          >
+            No active Schema
+          </td>
+        </tr>
+      </tbody>
     </table>
   </div>
 </div>

+ 31 - 30
kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/TopicConsumerGroups.tsx

@@ -34,38 +34,39 @@ const TopicConsumerGroups: React.FC<Props> = ({
 
   return (
     <div className="box">
-      {consumerGroups.length > 0 ? (
-        <table className="table is-striped is-fullwidth">
-          <thead>
+      <table className="table is-striped is-fullwidth">
+        <thead>
+          <tr>
+            <th>Consumer group ID</th>
+            <th>Num of members</th>
+            <th>Messages behind</th>
+            <th>Coordinator</th>
+            <th>State</th>
+          </tr>
+        </thead>
+        <tbody>
+          {consumerGroups.map((consumer) => (
+            <tr
+              key={consumer.groupId}
+              className="is-clickable"
+              onClick={() => goToConsumerGroupDetails(consumer)}
+            >
+              <td>{consumer.groupId}</td>
+              <td>{consumer.members}</td>
+              <td>{consumer.messagesBehind}</td>
+              <td>{consumer.coordinator?.id}</td>
+              <td>
+                <ConsumerGroupStateTag state={consumer.state} />
+              </td>
+            </tr>
+          ))}
+          {consumerGroups.length === 0 && (
             <tr>
-              <th>Consumer group ID</th>
-              <th>Num of members</th>
-              <th>Messages behind</th>
-              <th>Coordinator</th>
-              <th>State</th>
+              <td colSpan={10}>No active consumer groups</td>
             </tr>
-          </thead>
-          <tbody>
-            {consumerGroups.map((consumer) => (
-              <tr
-                key={consumer.groupId}
-                className="is-clickable"
-                onClick={() => goToConsumerGroupDetails(consumer)}
-              >
-                <td>{consumer.groupId}</td>
-                <td>{consumer.members}</td>
-                <td>{consumer.messagesBehind}</td>
-                <td>{consumer.coordinator?.id}</td>
-                <td>
-                  <ConsumerGroupStateTag state={consumer.state} />
-                </td>
-              </tr>
-            ))}
-          </tbody>
-        </table>
-      ) : (
-        'No active consumer groups'
-      )}
+          )}
+        </tbody>
+      </table>
     </div>
   );
 };

+ 2 - 4
kafka-ui-react-app/src/components/Topics/Topic/Details/ConsumerGroups/__test__/TopicConsumerGroups.spec.tsx

@@ -40,8 +40,7 @@ describe('Details', () => {
         topicName={mockTopicName}
       />
     );
-
-    expect(component.exists('.table')).toBeFalsy();
+    expect(component.find('td').text()).toEqual('No active consumer groups');
   });
 
   it('render ConsumerGroups in Topic', () => {
@@ -54,7 +53,6 @@ describe('Details', () => {
         topicName={mockTopicName}
       />
     );
-
-    expect(component.exists('.table')).toBeTruthy();
+    expect(component.exists('tbody')).toBeTruthy();
   });
 });

+ 42 - 43
kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/MessagesTable.tsx

@@ -9,51 +9,50 @@ export interface MessagesTableProp {
   onNext(event: React.MouseEvent<HTMLButtonElement>): void;
 }
 
-const MessagesTable: React.FC<MessagesTableProp> = ({ messages, onNext }) => {
-  if (!messages.length) {
-    return <div>No messages at selected topic</div>;
-  }
-
-  return (
-    <>
-      <table className="table is-fullwidth is-narrow">
-        <thead>
+const MessagesTable: React.FC<MessagesTableProp> = ({ messages, onNext }) => (
+  <>
+    <table className="table is-fullwidth is-narrow">
+      <thead>
+        <tr>
+          <th>Timestamp</th>
+          <th>Key</th>
+          <th>Offset</th>
+          <th>Partition</th>
+          <th>Content</th>
+          <th> </th>
+        </tr>
+      </thead>
+      <tbody>
+        {messages.map(
+          ({ partition, offset, timestamp, content, key }: TopicMessage) => (
+            <MessageItem
+              key={`message-${timestamp.getTime()}-${offset}`}
+              partition={partition}
+              offset={offset}
+              timestamp={timestamp}
+              content={content}
+              messageKey={key}
+            />
+          )
+        )}
+        {messages.length === 0 && (
           <tr>
-            <th>Timestamp</th>
-            <th>Key</th>
-            <th>Offset</th>
-            <th>Partition</th>
-            <th>Content</th>
-            <th> </th>
+            <td colSpan={10}>No messages at selected topic</td>
           </tr>
-        </thead>
-        <tbody>
-          {messages.map(
-            ({ partition, offset, timestamp, content, key }: TopicMessage) => (
-              <MessageItem
-                key={`message-${timestamp.getTime()}-${offset}`}
-                partition={partition}
-                offset={offset}
-                timestamp={timestamp}
-                content={content}
-                messageKey={key}
-              />
-            )
-          )}
-        </tbody>
-      </table>
-      <div className="columns">
-        <div className="column is-full">
-          <CustomParamButton
-            className="is-link is-pulled-right"
-            type="fa-chevron-right"
-            onClick={onNext}
-            btnText="Next"
-          />
-        </div>
+        )}
+      </tbody>
+    </table>
+    <div className="columns">
+      <div className="column is-full">
+        <CustomParamButton
+          className="is-link is-pulled-right"
+          type="fa-chevron-right"
+          onClick={onNext}
+          btnText="Next"
+        />
       </div>
-    </>
-  );
-};
+    </div>
+  </>
+);
 
 export default MessagesTable;

+ 3 - 3
kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/__test__/MessagesTable.spec.tsx

@@ -18,9 +18,9 @@ describe('MessagesTable', () => {
   describe('when topic is empty', () => {
     it('renders table row with JSONEditor', () => {
       const wrapper = shallow(setupWrapper());
-      expect(wrapper.exists('table')).toBeFalsy();
-      expect(wrapper.exists('CustomParamButton')).toBeFalsy();
-      expect(wrapper.text()).toEqual('No messages at selected topic');
+      expect(wrapper.find('td').text()).toEqual(
+        'No messages at selected topic'
+      );
     });
 
     it('matches snapshot', () => {

+ 51 - 3
kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/__test__/__snapshots__/MessagesTable.spec.tsx.snap

@@ -63,7 +63,55 @@ exports[`MessagesTable when topic contains messages matches snapshot 1`] = `
 `;
 
 exports[`MessagesTable when topic is empty matches snapshot 1`] = `
-<div>
-  No messages at selected topic
-</div>
+<Fragment>
+  <table
+    className="table is-fullwidth is-narrow"
+  >
+    <thead>
+      <tr>
+        <th>
+          Timestamp
+        </th>
+        <th>
+          Key
+        </th>
+        <th>
+          Offset
+        </th>
+        <th>
+          Partition
+        </th>
+        <th>
+          Content
+        </th>
+        <th>
+           
+        </th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td
+          colSpan={10}
+        >
+          No messages at selected topic
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  <div
+    className="columns"
+  >
+    <div
+      className="column is-full"
+    >
+      <CustomParamButton
+        btnText="Next"
+        className="is-link is-pulled-right"
+        onClick={[MockFunction]}
+        type="fa-chevron-right"
+      />
+    </div>
+  </div>
+</Fragment>
 `;

+ 5 - 0
kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/Overview.tsx

@@ -102,6 +102,11 @@ const Overview: React.FC<Props> = ({
                 </td>
               </tr>
             ))}
+            {partitions?.length === 0 && (
+              <tr>
+                <td colSpan={10}>No Partitions found</td>
+              </tr>
+            )}
           </tbody>
         </table>
       </div>

+ 15 - 0
kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx

@@ -38,5 +38,20 @@ describe('Overview', () => {
 
       expect(component.exists('Dropdown')).toBeTruthy();
     });
+
+    it('does not render Partitions', () => {
+      const componentEmpty = shallow(
+        <Overview
+          name={mockTopicName}
+          partitions={[]}
+          internal={mockInternal}
+          clusterName={mockClusterName}
+          topicName={mockTopicName}
+          clearTopicMessages={mockClearTopicMessages}
+        />
+      );
+
+      expect(componentEmpty.find('td').text()).toEqual('No Partitions found');
+    });
   });
 });