Repository: provectus/kafka-ui
Issue: Display number of messages & size in topic list
Labels: type/enhancement
good first issue
scope/frontend

### Describe the solution you'd like

Display columns Number of messages & size in topic list page

Number of messages could be calculated from partitions:
backend provide list of partitions with min/max offset, 
number of messages = sum(partition max offset - partition min offset)
size - field segmentSize (it's in bytes, let's display it KB/MB/GB...)



Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/kafka-ui-react-app/src/components/Topics/List/List.tsx b/kafka-ui-react-app/src/components/Topics/List/List.tsx
index 99784bb869f..8bc231a98d9 100644
--- a/kafka-ui-react-app/src/components/Topics/List/List.tsx
+++ b/kafka-ui-react-app/src/components/Topics/List/List.tsx
@@ -135,6 +135,8 @@ const List: React.FC<Props> = ({
                   orderBy={orderBy}
                   setOrderBy={setTopicsOrderBy}
                 />
+                <th>Number of messages</th>
+                <th>Size</th>
                 <th>Type</th>
                 <th> </th>
               </tr>
diff --git a/kafka-ui-react-app/src/components/Topics/List/ListItem.tsx b/kafka-ui-react-app/src/components/Topics/List/ListItem.tsx
index 07074be71fa..6a086771a91 100644
--- a/kafka-ui-react-app/src/components/Topics/List/ListItem.tsx
+++ b/kafka-ui-react-app/src/components/Topics/List/ListItem.tsx
@@ -10,6 +10,7 @@ import DropdownItem from 'components/common/Dropdown/DropdownItem';
 import Dropdown from 'components/common/Dropdown/Dropdown';
 import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
 import ClusterContext from 'components/contexts/ClusterContext';
+import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
 
 export interface ListItemProps {
   topic: TopicWithDetailedInfo;
@@ -19,7 +20,7 @@ export interface ListItemProps {
 }
 
 const ListItem: React.FC<ListItemProps> = ({
-  topic: { name, internal, partitions },
+  topic: { name, internal, partitions, segmentSize },
   deleteTopic,
   clusterName,
   clearTopicMessages,
@@ -29,15 +30,27 @@ const ListItem: React.FC<ListItemProps> = ({
   const [isDeleteTopicConfirmationVisible, setDeleteTopicConfirmationVisible] =
     React.useState(false);
 
-  const outOfSyncReplicas = React.useMemo(() => {
+  const { outOfSyncReplicas, numberOfMessages } = React.useMemo(() => {
     if (partitions === undefined || partitions.length === 0) {
-      return 0;
+      return {
+        outOfSyncReplicas: 0,
+        numberOfMessages: 0,
+      };
     }
 
-    return partitions.reduce((memo: number, { replicas }) => {
-      const outOfSync = replicas?.filter(({ inSync }) => !inSync);
-      return memo + (outOfSync?.length || 0);
-    }, 0);
+    return partitions.reduce(
+      (memo, { replicas, offsetMax, offsetMin }) => {
+        const outOfSync = replicas?.filter(({ inSync }) => !inSync);
+        return {
+          outOfSyncReplicas: memo.outOfSyncReplicas + (outOfSync?.length || 0),
+          numberOfMessages: memo.numberOfMessages + (offsetMax - offsetMin),
+        };
+      },
+      {
+        outOfSyncReplicas: 0,
+        numberOfMessages: 0,
+      }
+    );
   }, [partitions]);
 
   const deleteTopicHandler = React.useCallback(() => {
@@ -62,6 +75,10 @@ const ListItem: React.FC<ListItemProps> = ({
       </td>
       <td>{partitions?.length}</td>
       <td>{outOfSyncReplicas}</td>
+      <td>{numberOfMessages}</td>
+      <td>
+        <BytesFormatted value={segmentSize} />
+      </td>
       <td>
         <div className={cx('tag', internal ? 'is-light' : 'is-primary')}>
           {internal ? 'Internal' : 'External'}
diff --git a/kafka-ui-react-app/src/components/Topics/List/__tests__/__snapshots__/List.spec.tsx.snap b/kafka-ui-react-app/src/components/Topics/List/__tests__/__snapshots__/List.spec.tsx.snap
index 27706ba2831..17a86b1f2fe 100644
--- a/kafka-ui-react-app/src/components/Topics/List/__tests__/__snapshots__/List.spec.tsx.snap
+++ b/kafka-ui-react-app/src/components/Topics/List/__tests__/__snapshots__/List.spec.tsx.snap
@@ -205,6 +205,12 @@ exports[`List when it does not have readonly flag matches the snapshot 1`] = `
                     </span>
                   </th>
                 </ListHeaderCell>
+                <th>
+                  Number of messages
+                </th>
+                <th>
+                  Size
+                </th>
                 <th>
                   Type
                 </th>


Test patch: