diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.styled.ts b/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.styled.ts index f89903a1c5..ac281e951b 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.styled.ts +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.styled.ts @@ -6,3 +6,13 @@ export const DropdownExtraMessage = styled.div` width: 100%; margin-top: 10px; `; + +export const ReplicaCell = styled.span.attrs({ 'aria-label': 'replica-info' })<{ + leader: boolean | undefined; +}>` + ${this} ~ ${this}::before { + color: black; + content: ', '; + } + color: ${(props) => (props.leader ? 'orange' : null)}; +`; diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/Overview.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/Overview.tsx index d66d93131a..12434e6224 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/Overview.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/Overview.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Topic, TopicDetails } from 'generated-sources'; +import { Partition, Replica, Topic, TopicDetails } from 'generated-sources'; import { ClusterName, TopicName } from 'redux/interfaces'; import Dropdown from 'components/common/Dropdown/Dropdown'; import DropdownItem from 'components/common/Dropdown/DropdownItem'; @@ -10,6 +10,7 @@ import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeader import VerticalElipsisIcon from 'components/common/Icons/VerticalElipsisIcon'; import * as Metrics from 'components/common/Metrics'; import { Tag } from 'components/common/Tag/Tag.styled'; +import { ReplicaCell } from 'components/Topics/Topic/Details/Details.styled'; export interface Props extends Topic, TopicDetails { clusterName: ClusterName; @@ -100,7 +101,7 @@ const Overview: React.FC = ({ - + @@ -108,13 +109,22 @@ const Overview: React.FC = ({ - {partitions?.map(({ partition, leader, offsetMin, offsetMax }) => ( - - {partition} - {leader} - {offsetMin} - {offsetMax} - {offsetMax - offsetMin} + {partitions?.map((partition: Partition) => ( + + {partition.partition} + + {partition.replicas?.map((replica: Replica) => ( + + {replica.broker} + + ))} + + {partition.offsetMin} + {partition.offsetMax} + {partition.offsetMax - partition.offsetMin} {!internal && !isReadOnly && cleanUpPolicy === 'DELETE' ? ( } right> @@ -123,7 +133,7 @@ const Overview: React.FC = ({ clearTopicMessages({ clusterName, topicName, - partitions: [partition], + partitions: [partition.partition], }) } danger diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx index daa1ef7010..0d3fb36368 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Overview/__test__/Overview.spec.tsx @@ -8,8 +8,10 @@ import theme from 'theme/theme'; import { CleanUpPolicy } from 'generated-sources'; import ClusterContext from 'components/contexts/ClusterContext'; import userEvent from '@testing-library/user-event'; +import { ReplicaCell } from 'components/Topics/Topic/Details/Details.styled'; describe('Overview', () => { + const getReplicaCell = () => screen.getByLabelText('replica-info'); const mockClusterName = 'local'; const mockTopicName = 'topic'; const mockClearTopicMessages = jest.fn(); @@ -20,7 +22,7 @@ describe('Overview', () => { replicas: [ { broker: 1, - leader: false, + leader: true, inSync: true, }, ], @@ -66,6 +68,22 @@ describe('Overview', () => { mockClearTopicMessages.mockClear(); }); + it('at least one replica was rendered', () => { + setupComponent({ + ...defaultProps, + underReplicatedPartitions: 0, + inSyncReplicas: 1, + replicas: 1, + }); + expect(getReplicaCell()).toBeInTheDocument(); + }); + + it('renders replica cell with props', () => { + render(); + expect(getReplicaCell()).toBeInTheDocument(); + expect(getReplicaCell()).toHaveStyleRule('color', 'orange'); + }); + describe('when it has internal flag', () => { it('does not render the Action button a Topic', () => { setupComponent({