Dashboard.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import React, { useEffect, useMemo } from 'react';
  2. import PageHeading from 'components/common/PageHeading/PageHeading';
  3. import * as Metrics from 'components/common/Metrics';
  4. import { Tag } from 'components/common/Tag/Tag.styled';
  5. import Switch from 'components/common/Switch/Switch';
  6. import { useClusters } from 'lib/hooks/api/clusters';
  7. import { Cluster, ResourceType, ServerStatus } from 'generated-sources';
  8. import { ColumnDef } from '@tanstack/react-table';
  9. import Table, { SizeCell } from 'components/common/NewTable';
  10. import useBoolean from 'lib/hooks/useBoolean';
  11. import { clusterNewConfigPath } from 'lib/paths';
  12. import { GlobalSettingsContext } from 'components/contexts/GlobalSettingsContext';
  13. import { useNavigate } from 'react-router-dom';
  14. import { ActionCanButton } from 'components/common/ActionComponent';
  15. import { useGetUserInfo } from 'lib/hooks/api/roles';
  16. import * as S from './Dashboard.styled';
  17. import ClusterName from './ClusterName';
  18. import ClusterTableActionsCell from './ClusterTableActionsCell';
  19. const Dashboard: React.FC = () => {
  20. const { data } = useGetUserInfo();
  21. const clusters = useClusters();
  22. const { value: showOfflineOnly, toggle } = useBoolean(false);
  23. const appInfo = React.useContext(GlobalSettingsContext);
  24. const navigate = useNavigate();
  25. const config = React.useMemo(() => {
  26. const clusterList = clusters.data || [];
  27. const offlineClusters = clusterList.filter(
  28. ({ status }) => status === ServerStatus.OFFLINE
  29. );
  30. return {
  31. list: showOfflineOnly ? offlineClusters : clusterList,
  32. online: clusterList.length - offlineClusters.length,
  33. offline: offlineClusters.length,
  34. };
  35. }, [clusters, showOfflineOnly]);
  36. const columns = React.useMemo<ColumnDef<Cluster>[]>(() => {
  37. const initialColumns: ColumnDef<Cluster>[] = [
  38. { header: 'Cluster name', accessorKey: 'name', cell: ClusterName },
  39. { header: 'Version', accessorKey: 'version' },
  40. { header: 'Brokers count', accessorKey: 'brokerCount' },
  41. { header: 'Partitions', accessorKey: 'onlinePartitionCount' },
  42. { header: 'Topics', accessorKey: 'topicCount' },
  43. { header: 'Production', accessorKey: 'bytesInPerSec', cell: SizeCell },
  44. { header: 'Consumption', accessorKey: 'bytesOutPerSec', cell: SizeCell },
  45. ];
  46. if (appInfo.hasDynamicConfig) {
  47. initialColumns.push({
  48. header: '',
  49. id: 'actions',
  50. cell: ClusterTableActionsCell,
  51. });
  52. }
  53. return initialColumns;
  54. }, []);
  55. useEffect(() => {
  56. if (appInfo.hasDynamicConfig && !clusters.data) {
  57. navigate(clusterNewConfigPath);
  58. }
  59. }, [clusters, appInfo.hasDynamicConfig]);
  60. const isApplicationConfig = useMemo(() => {
  61. return !!data?.userInfo?.permissions.some(
  62. (permission) => permission.resource === ResourceType.APPLICATIONCONFIG
  63. );
  64. }, [data]);
  65. return (
  66. <>
  67. <PageHeading text="Dashboard" />
  68. <Metrics.Wrapper>
  69. <Metrics.Section>
  70. <Metrics.Indicator label={<Tag color="green">Online</Tag>}>
  71. <span>{config.online || 0}</span>{' '}
  72. <Metrics.LightText>clusters</Metrics.LightText>
  73. </Metrics.Indicator>
  74. <Metrics.Indicator label={<Tag color="gray">Offline</Tag>}>
  75. <span>{config.offline || 0}</span>{' '}
  76. <Metrics.LightText>clusters</Metrics.LightText>
  77. </Metrics.Indicator>
  78. </Metrics.Section>
  79. </Metrics.Wrapper>
  80. <S.Toolbar>
  81. <div>
  82. <Switch
  83. name="switchRoundedDefault"
  84. checked={showOfflineOnly}
  85. onChange={toggle}
  86. />
  87. <label>Only offline clusters</label>
  88. </div>
  89. {appInfo.hasDynamicConfig && (
  90. <ActionCanButton
  91. buttonType="primary"
  92. buttonSize="M"
  93. to={clusterNewConfigPath}
  94. canDoAction={isApplicationConfig}
  95. >
  96. Configure new cluster
  97. </ActionCanButton>
  98. )}
  99. </S.Toolbar>
  100. <Table
  101. columns={columns}
  102. data={config?.list}
  103. enableSorting
  104. emptyMessage={clusters.isFetched ? 'No clusters found' : 'Loading...'}
  105. />
  106. </>
  107. );
  108. };
  109. export default Dashboard;