Repository: provectus/kafka-ui
Issue: Display In Sync Replicas (ISR) by Partition on Topic overview
Labels: type/enhancement
good first issue
scope/frontend
status/accepted

### Which version of the app are you running?
0.4.0 for production use
Tu.10.2022 06:31:55 (c961344) for test and evaluation

### Is your proposal related to a problem?

It is helpful to identify which partitions for topics are not replicating properly, causing the In Sync Replicas number to be reduced in an otherwise normally functioning cluster (i.e. no brokers are down).

### Describe the solution you'd like

Currently, when viewing a topic that has under replicated partitions, the metrics at the topic highlight this by show the number of URP and ISR.

![image](https://user-images.githubusercontent.com/18301427/194098806-0d6929f2-fb3c-4870-bf0f-51689a5ac988.png)

On the latest build, on the Partition list for a topic, there is a Replicas column, with green showing which broker is the leader for that partition. 

![image](https://user-images.githubusercontent.com/18301427/194099133-196ee221-7cad-42e2-9635-edba167b5378.png)

If we could add a column that showed which replicas for each partition are in sync, it could highlight those that are out of sync, like this (taken from a different Kafka tool).

![image](https://user-images.githubusercontent.com/18301427/194099470-c2699447-f168-4cb7-8f23-2cafa596f509.png)

This helps identify if all the out of sync replicas are from a single broker, which they were in my case.  All URP issues were on broker 1, so we were able to focus our attention there.



Issue comments:
@Haarolean, we already return if replica is sync or not from backend. So, we can easily implement it in UI. As for design - I think the simplest way is to highlight non-synced replicates with bold red. 
- make the whole line red in case when the leader is offline?

Pull request review comments:

Patch that resolved the issue:
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Overview/Overview.styled.ts b/kafka-ui-react-app/src/components/Topics/Topic/Overview/Overview.styled.ts
index a64db26117e..d274a1ba9d9 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Overview/Overview.styled.ts
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Overview/Overview.styled.ts
@@ -2,9 +2,15 @@ import styled from 'styled-components';
 
 export const Replica = styled.span.attrs({ 'aria-label': 'replica-info' })<{
   leader?: boolean;
+  outOfSync?: boolean;
 }>`
-  color: ${({ leader, theme }) =>
-    leader ? theme.topicMetaData.liderReplica.color : null};
+  color: ${({ leader, outOfSync, theme }) => {
+    if (outOfSync) return theme.topicMetaData.outOfSync.color;
+    if (leader) return theme.topicMetaData.liderReplica.color;
+    return null;
+  }};
+
+  font-weight: ${({ outOfSync }) => (outOfSync ? '500' : null)};
 
   &:after {
     content: ', ';
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Overview/Overview.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Overview/Overview.tsx
index cada465548f..f0c2ddfd61b 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Overview/Overview.tsx
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Overview/Overview.tsx
@@ -51,9 +51,10 @@ const Overview: React.FC = () => {
           if (replicas === undefined || replicas.length === 0) {
             return 0;
           }
-          return replicas?.map(({ broker, leader }: Replica) => (
+          return replicas?.map(({ broker, leader, inSync }: Replica) => (
             <S.Replica
               leader={leader}
+              outOfSync={!inSync}
               key={broker}
               title={leader ? 'Leader' : ''}
             >
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Overview/__test__/Overview.spec.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Overview/__test__/Overview.spec.tsx
index 3f10635df52..0857de9a6f5 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Overview/__test__/Overview.spec.tsx
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Overview/__test__/Overview.spec.tsx
@@ -69,6 +69,19 @@ describe('Overview', () => {
     );
   });
 
+  describe('when replicas out of sync', () => {
+    it('should be the appropriate color', () => {
+      render(<Replica outOfSync />);
+      const element = screen.getByLabelText('replica-info');
+      expect(element).toBeInTheDocument();
+      expect(element).toHaveStyleRule(
+        'color',
+        theme.topicMetaData.outOfSync.color
+      );
+      expect(element).toHaveStyleRule('font-weight', '500');
+    });
+  });
+
   describe('when it has internal flag', () => {
     it('renders the Action button for Topic', () => {
       renderComponent({
diff --git a/kafka-ui-react-app/src/theme/theme.ts b/kafka-ui-react-app/src/theme/theme.ts
index 33c8b2959c8..8684f043774 100644
--- a/kafka-ui-react-app/src/theme/theme.ts
+++ b/kafka-ui-react-app/src/theme/theme.ts
@@ -516,6 +516,9 @@ const theme = {
     liderReplica: {
       color: Colors.green[60],
     },
+    outOfSync: {
+      color: Colors.red[50],
+    },
   },
   dangerZone: {
     borderColor: Colors.neutral[10],


Test patch: