Overview.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import React from 'react';
  2. import { Topic, TopicDetails } from 'generated-sources';
  3. import { ClusterName, TopicName } from 'redux/interfaces';
  4. import Dropdown from 'components/common/Dropdown/Dropdown';
  5. import DropdownItem from 'components/common/Dropdown/DropdownItem';
  6. import ClusterContext from 'components/contexts/ClusterContext';
  7. import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
  8. import { Table } from 'components/common/table/Table/Table.styled';
  9. import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell';
  10. import VerticalElipsisIcon from 'components/common/Icons/VerticalElipsisIcon';
  11. import * as Metrics from 'components/common/Metrics';
  12. import { Tag } from 'components/common/Tag/Tag.styled';
  13. export interface Props extends Topic, TopicDetails {
  14. clusterName: ClusterName;
  15. topicName: TopicName;
  16. clearTopicMessages(params: {
  17. clusterName: ClusterName;
  18. topicName: TopicName;
  19. partitions?: number[];
  20. }): void;
  21. }
  22. const Overview: React.FC<Props> = ({
  23. partitions,
  24. underReplicatedPartitions,
  25. inSyncReplicas,
  26. replicas,
  27. partitionCount,
  28. internal,
  29. replicationFactor,
  30. segmentSize,
  31. segmentCount,
  32. clusterName,
  33. topicName,
  34. cleanUpPolicy,
  35. clearTopicMessages,
  36. }) => {
  37. const { isReadOnly } = React.useContext(ClusterContext);
  38. const messageCount = React.useMemo(() => {
  39. return (partitions || []).reduce((memo, partition) => {
  40. return memo + partition.offsetMax - partition.offsetMin;
  41. }, 0);
  42. }, [partitions]);
  43. return (
  44. <>
  45. <Metrics.Wrapper>
  46. <Metrics.Section>
  47. <Metrics.Indicator label="Partitions">
  48. {partitionCount}
  49. </Metrics.Indicator>
  50. <Metrics.Indicator label="Replication Factor">
  51. {replicationFactor}
  52. </Metrics.Indicator>
  53. <Metrics.Indicator
  54. label="URP"
  55. title="Under replicated partitions"
  56. isAlert
  57. alertType={underReplicatedPartitions === 0 ? 'success' : 'error'}
  58. >
  59. {underReplicatedPartitions === 0 ? (
  60. <Metrics.LightText>{underReplicatedPartitions}</Metrics.LightText>
  61. ) : (
  62. <Metrics.RedText>{underReplicatedPartitions}</Metrics.RedText>
  63. )}
  64. </Metrics.Indicator>
  65. <Metrics.Indicator
  66. label="In Sync Replicas"
  67. isAlert
  68. alertType={inSyncReplicas === replicas ? 'success' : 'error'}
  69. >
  70. {inSyncReplicas && replicas && inSyncReplicas < replicas ? (
  71. <Metrics.RedText>{inSyncReplicas}</Metrics.RedText>
  72. ) : (
  73. inSyncReplicas
  74. )}
  75. <Metrics.LightText> of {replicas}</Metrics.LightText>
  76. </Metrics.Indicator>
  77. <Metrics.Indicator label="Type">
  78. <Tag color="gray">{internal ? 'Internal' : 'External'}</Tag>
  79. </Metrics.Indicator>
  80. <Metrics.Indicator label="Segment Size" title="">
  81. <BytesFormatted value={segmentSize} />
  82. </Metrics.Indicator>
  83. <Metrics.Indicator label="Segment Count">
  84. {segmentCount}
  85. </Metrics.Indicator>
  86. <Metrics.Indicator label="Clean Up Policy">
  87. <Tag color="gray">{cleanUpPolicy || 'Unknown'}</Tag>
  88. </Metrics.Indicator>
  89. <Metrics.Indicator label="Message Count">
  90. {messageCount}
  91. </Metrics.Indicator>
  92. </Metrics.Section>
  93. </Metrics.Wrapper>
  94. <div>
  95. <Table isFullwidth>
  96. <thead>
  97. <tr>
  98. <TableHeaderCell title="Partition ID" />
  99. <TableHeaderCell title="Broker Leader" />
  100. <TableHeaderCell title="First Offset" />
  101. <TableHeaderCell title="Next Offset" />
  102. <TableHeaderCell title="Message Count" />
  103. <TableHeaderCell title=" " />
  104. </tr>
  105. </thead>
  106. <tbody>
  107. {partitions?.map(({ partition, leader, offsetMin, offsetMax }) => (
  108. <tr key={`partition-list-item-key-${partition}`}>
  109. <td>{partition}</td>
  110. <td>{leader}</td>
  111. <td>{offsetMin}</td>
  112. <td>{offsetMax}</td>
  113. <td>{offsetMax - offsetMin}</td>
  114. <td style={{ width: '5%' }}>
  115. {!internal && !isReadOnly && cleanUpPolicy === 'DELETE' ? (
  116. <Dropdown label={<VerticalElipsisIcon />} right>
  117. <DropdownItem
  118. onClick={() =>
  119. clearTopicMessages({
  120. clusterName,
  121. topicName,
  122. partitions: [partition],
  123. })
  124. }
  125. danger
  126. >
  127. Clear Messages
  128. </DropdownItem>
  129. </Dropdown>
  130. ) : null}
  131. </td>
  132. </tr>
  133. ))}
  134. {partitions?.length === 0 && (
  135. <tr>
  136. <td colSpan={10}>No Partitions found</td>
  137. </tr>
  138. )}
  139. </tbody>
  140. </Table>
  141. </div>
  142. </>
  143. );
  144. };
  145. export default Overview;