ClustersWidget.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import React from 'react';
  2. import { chunk } from 'lodash';
  3. import { v4 } from 'uuid';
  4. import * as Metrics from 'components/common/Metrics';
  5. import { Cluster } from 'generated-sources';
  6. import { Tag } from 'components/common/Tag/Tag.styled';
  7. import { Table } from 'components/common/table/Table/Table.styled';
  8. import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell';
  9. import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
  10. import { NavLink } from 'react-router-dom';
  11. import { clusterTopicsPath } from 'lib/paths';
  12. import Switch from 'components/common/Switch/Switch';
  13. import * as S from './ClustersWidget.styled';
  14. interface Props {
  15. clusters: Cluster[];
  16. onlineClusters: Cluster[];
  17. offlineClusters: Cluster[];
  18. }
  19. interface ChunkItem {
  20. id: string;
  21. data: Cluster[];
  22. }
  23. const ClustersWidget: React.FC<Props> = ({
  24. clusters,
  25. onlineClusters,
  26. offlineClusters,
  27. }) => {
  28. const [showOfflineOnly, setShowOfflineOnly] = React.useState<boolean>(false);
  29. const clusterList: ChunkItem[] = React.useMemo(() => {
  30. let list = clusters;
  31. if (showOfflineOnly) {
  32. list = offlineClusters;
  33. }
  34. return chunk(list, 2).map((data) => ({
  35. id: v4(),
  36. data,
  37. }));
  38. }, [clusters, offlineClusters, showOfflineOnly]);
  39. const handleSwitch = () => setShowOfflineOnly(!showOfflineOnly);
  40. return (
  41. <>
  42. <Metrics.Wrapper>
  43. <Metrics.Section>
  44. <Metrics.Indicator label={<Tag color="green">Online</Tag>}>
  45. <span data-testid="onlineCount">{onlineClusters.length}</span>{' '}
  46. <Metrics.LightText>clusters</Metrics.LightText>
  47. </Metrics.Indicator>
  48. <Metrics.Indicator label={<Tag color="gray">Offline</Tag>}>
  49. <span data-testid="offlineCount">{offlineClusters.length}</span>{' '}
  50. <Metrics.LightText>clusters</Metrics.LightText>
  51. </Metrics.Indicator>
  52. </Metrics.Section>
  53. </Metrics.Wrapper>
  54. <S.SwitchWrapper>
  55. <Switch
  56. name="switchRoundedDefault"
  57. checked={showOfflineOnly}
  58. onChange={handleSwitch}
  59. />
  60. <label>Only offline clusters</label>
  61. </S.SwitchWrapper>
  62. {clusterList.map((chunkItem) => (
  63. <Table key={chunkItem.id} isFullwidth>
  64. <thead>
  65. <tr>
  66. <TableHeaderCell title="Cluster name" />
  67. <TableHeaderCell title="Version" />
  68. <TableHeaderCell title="Brokers count" />
  69. <TableHeaderCell title="Partitions" />
  70. <TableHeaderCell title="Topics" />
  71. <TableHeaderCell title="Production" />
  72. <TableHeaderCell title="Consumption" />
  73. </tr>
  74. </thead>
  75. <tbody>
  76. {chunkItem.data.map((cluster) => (
  77. <tr key={cluster.name}>
  78. <td>
  79. {cluster.readOnly && <Tag color="blue">readonly</Tag>}{' '}
  80. {cluster.name}
  81. </td>
  82. <td>{cluster.version}</td>
  83. <td>{cluster.brokerCount}</td>
  84. <td>{cluster.onlinePartitionCount}</td>
  85. <td>
  86. <NavLink to={clusterTopicsPath(cluster.name)}>
  87. {cluster.topicCount}
  88. </NavLink>
  89. </td>
  90. <td>
  91. <BytesFormatted value={cluster.bytesInPerSec} />
  92. </td>
  93. <td>
  94. <BytesFormatted value={cluster.bytesOutPerSec} />
  95. </td>
  96. </tr>
  97. ))}
  98. </tbody>
  99. </Table>
  100. ))}
  101. </>
  102. );
  103. };
  104. export default ClustersWidget;