浏览代码

Make broker table row clickable (#2151)

* Added click functionality to the row

* Clickablerow moved to separate file

Co-authored-by: Oleg Shur <workshur@gmail.com>
Kirill Morozov 3 年之前
父节点
当前提交
3c922bc470

+ 5 - 0
kafka-ui-react-app/src/components/Brokers/BrokersList/BrokersList.style.ts

@@ -0,0 +1,5 @@
+import styled from 'styled-components';
+
+export const ClickableRow = styled.tr`
+  cursor: pointer;
+`;

+ 10 - 4
kafka-ui-react-app/src/components/Brokers/BrokersList/BrokersList.tsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import React from 'react';
 import { ClusterName } from 'redux/interfaces';
 import { ClusterName } from 'redux/interfaces';
 import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
 import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
-import { NavLink } from 'react-router-dom';
+import { NavLink, useNavigate } from 'react-router-dom';
 import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell';
 import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell';
 import { Table } from 'components/common/table/Table/Table.styled';
 import { Table } from 'components/common/table/Table/Table.styled';
 import PageHeading from 'components/common/PageHeading/PageHeading';
 import PageHeading from 'components/common/PageHeading/PageHeading';
@@ -10,7 +10,10 @@ import useAppParams from 'lib/hooks/useAppParams';
 import useBrokers from 'lib/hooks/useBrokers';
 import useBrokers from 'lib/hooks/useBrokers';
 import useClusterStats from 'lib/hooks/useClusterStats';
 import useClusterStats from 'lib/hooks/useClusterStats';
 
 
+import { ClickableRow } from './BrokersList.style';
+
 const BrokersList: React.FC = () => {
 const BrokersList: React.FC = () => {
+  const navigate = useNavigate();
   const { clusterName } = useAppParams<{ clusterName: ClusterName }>();
   const { clusterName } = useAppParams<{ clusterName: ClusterName }>();
   const { data: clusterStats } = useClusterStats(clusterName);
   const { data: clusterStats } = useClusterStats(clusterName);
   const { data: brokers } = useBrokers(clusterName);
   const { data: brokers } = useBrokers(clusterName);
@@ -58,7 +61,6 @@ const BrokersList: React.FC = () => {
               onlinePartitionCount
               onlinePartitionCount
             )}
             )}
             <Metrics.LightText>
             <Metrics.LightText>
-              {' '}
               of {(onlinePartitionCount || 0) + (offlinePartitionCount || 0)}
               of {(onlinePartitionCount || 0) + (offlinePartitionCount || 0)}
             </Metrics.LightText>
             </Metrics.LightText>
           </Metrics.Indicator>
           </Metrics.Indicator>
@@ -114,8 +116,12 @@ const BrokersList: React.FC = () => {
             diskUsage.length !== 0 &&
             diskUsage.length !== 0 &&
             diskUsage.map(({ brokerId, segmentSize, segmentCount }) => {
             diskUsage.map(({ brokerId, segmentSize, segmentCount }) => {
               const brokerItem = brokers?.find(({ id }) => id === brokerId);
               const brokerItem = brokers?.find(({ id }) => id === brokerId);
+
               return (
               return (
-                <tr key={brokerId}>
+                <ClickableRow
+                  key={brokerId}
+                  onClick={() => navigate(`${brokerId}`)}
+                >
                   <td>
                   <td>
                     <NavLink to={`${brokerId}`} role="link">
                     <NavLink to={`${brokerId}`} role="link">
                       {brokerId}
                       {brokerId}
@@ -127,7 +133,7 @@ const BrokersList: React.FC = () => {
                   <td>{segmentCount}</td>
                   <td>{segmentCount}</td>
                   <td>{brokerItem?.port}</td>
                   <td>{brokerItem?.port}</td>
                   <td>{brokerItem?.host}</td>
                   <td>{brokerItem?.host}</td>
-                </tr>
+                </ClickableRow>
               );
               );
             })}
             })}
         </tbody>
         </tbody>

+ 25 - 0
kafka-ui-react-app/src/components/Brokers/BrokersList/__test__/BrokersList.spec.tsx

@@ -9,6 +9,14 @@ import {
   brokersPayload,
   brokersPayload,
   clusterStatsPayload,
   clusterStatsPayload,
 } from 'components/Brokers/__test__/fixtures';
 } from 'components/Brokers/__test__/fixtures';
+import userEvent from '@testing-library/user-event';
+
+const mockedUsedNavigate = jest.fn();
+
+jest.mock('react-router-dom', () => ({
+  ...jest.requireActual('react-router-dom'),
+  useNavigate: () => mockedUsedNavigate,
+}));
 
 
 describe('BrokersList Component', () => {
 describe('BrokersList Component', () => {
   afterEach(() => fetchMock.reset());
   afterEach(() => fetchMock.reset());
@@ -53,6 +61,22 @@ describe('BrokersList Component', () => {
       expect(rows.length).toEqual(3);
       expect(rows.length).toEqual(3);
     });
     });
 
 
+    it('opens broker when row clicked', async () => {
+      const fetchStatsMock = fetchMock.get(fetchStatsUrl, clusterStatsPayload);
+      await act(() => {
+        renderComponent();
+      });
+      await waitFor(() => expect(fetchStatsMock.called()).toBeTruthy());
+      await act(() => {
+        userEvent.click(screen.getByRole('cell', { name: '0' }));
+      });
+
+      await waitFor(() => {
+        expect(mockedUsedNavigate).toBeCalled();
+        expect(mockedUsedNavigate).toBeCalledWith('0');
+      });
+    });
+
     it('shows warning when offlinePartitionCount > 0', async () => {
     it('shows warning when offlinePartitionCount > 0', async () => {
       const fetchStatsMock = fetchMock.getOnce(fetchStatsUrl, {
       const fetchStatsMock = fetchMock.getOnce(fetchStatsUrl, {
         ...clusterStatsPayload,
         ...clusterStatsPayload,
@@ -93,6 +117,7 @@ describe('BrokersList Component', () => {
       expect(onlineWidgetDef).toBeInTheDocument();
       expect(onlineWidgetDef).toBeInTheDocument();
       expect(onlineWidget).toBeInTheDocument();
       expect(onlineWidget).toBeInTheDocument();
     });
     });
+
     it('shows right count when inSyncReplicasCount: undefined outOfSyncReplicasCount: 1', async () => {
     it('shows right count when inSyncReplicasCount: undefined outOfSyncReplicasCount: 1', async () => {
       const fetchStatsMock = fetchMock.getOnce(fetchStatsUrl, {
       const fetchStatsMock = fetchMock.getOnce(fetchStatsUrl, {
         ...clusterStatsPayload,
         ...clusterStatsPayload,