浏览代码

FE: Redesign connector actions (#3197)

* redesign connector actions

* remove xpect(dropDownButton.length).toEqual(2) from Actions.spec.tsx

---------

Co-authored-by: davitbejanyan <dbejanyan@provectus.com>
Co-authored-by: Roman Zabaluev <rzabaluev@provectus.com>
David 2 年之前
父节点
当前提交
ea348102c2

+ 23 - 0
kafka-ui-react-app/src/components/Connect/Details/Actions/Action.styled.ts

@@ -0,0 +1,23 @@
+import styled from 'styled-components';
+
+export const ConnectorActionsWrapperStyled = styled.div`
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: 8px;
+`;
+export const ButtonLabel = styled.span`
+  margin-right: 11.5px;
+`;
+export const RestartButton = styled.div`
+  padding: 0 12px;
+  border: none;
+  border-radius: 4px;
+  display: flex;
+  -webkit-align-items: center;
+  background: #e8e8fc;
+  color: #171a1c;
+  font-size: 14px;
+  font-weight: 500;
+  height: 32px;
+`;

+ 14 - 11
kafka-ui-react-app/src/components/Connect/Details/Actions/Actions.tsx

@@ -1,5 +1,4 @@
 import React from 'react';
-import styled from 'styled-components';
 import { useNavigate } from 'react-router-dom';
 import { useIsMutating } from '@tanstack/react-query';
 import {
@@ -21,13 +20,9 @@ import {
 import { useConfirm } from 'lib/hooks/useConfirm';
 import { Dropdown } from 'components/common/Dropdown';
 import { ActionDropdownItem } from 'components/common/ActionComponent';
+import ChevronDownIcon from 'components/common/Icons/ChevronDownIcon';
 
-const ConnectorActionsWrapperStyled = styled.div`
-  display: flex;
-  flex-wrap: wrap;
-  align-items: center;
-  gap: 8px;
-`;
+import * as S from './Action.styled';
 
 const Actions: React.FC = () => {
   const navigate = useNavigate();
@@ -66,10 +61,16 @@ const Actions: React.FC = () => {
     stateMutation.mutateAsync(ConnectorAction.PAUSE);
   const resumeConnectorHandler = () =>
     stateMutation.mutateAsync(ConnectorAction.RESUME);
-
   return (
-    <ConnectorActionsWrapperStyled>
-      <Dropdown>
+    <S.ConnectorActionsWrapperStyled>
+      <Dropdown
+        label={
+          <S.RestartButton>
+            <S.ButtonLabel>Restart</S.ButtonLabel>
+            <ChevronDownIcon />
+          </S.RestartButton>
+        }
+      >
         {connector?.status.state === ConnectorState.RUNNING && (
           <ActionDropdownItem
             onClick={pauseConnectorHandler}
@@ -129,6 +130,8 @@ const Actions: React.FC = () => {
         >
           Restart Failed Tasks
         </ActionDropdownItem>
+      </Dropdown>
+      <Dropdown>
         <ActionDropdownItem
           onClick={deleteConnectorHandler}
           disabled={isMutating}
@@ -142,7 +145,7 @@ const Actions: React.FC = () => {
           Delete
         </ActionDropdownItem>
       </Dropdown>
-    </ConnectorActionsWrapperStyled>
+    </S.ConnectorActionsWrapperStyled>
   );
 };
 

+ 18 - 15
kafka-ui-react-app/src/components/Connect/Details/Actions/__tests__/Actions.spec.tsx

@@ -35,8 +35,11 @@ const expectActionButtonsExists = () => {
 };
 const afterClickDropDownButton = async () => {
   const dropDownButton = screen.getAllByRole('button');
-  expect(dropDownButton.length).toEqual(1);
-  await userEvent.click(dropDownButton[0]);
+  await userEvent.click(dropDownButton[1]);
+};
+const afterClickRestartButton = async () => {
+  const dropDownButton = screen.getByText('Restart');
+  await userEvent.click(dropDownButton);
 };
 describe('Actions', () => {
   afterEach(() => {
@@ -66,8 +69,8 @@ describe('Actions', () => {
         data: set({ ...connector }, 'status.state', ConnectorState.PAUSED),
       }));
       renderComponent();
-      await afterClickDropDownButton();
-      expect(screen.getAllByRole('menuitem').length).toEqual(5);
+      await afterClickRestartButton();
+      expect(screen.getAllByRole('menuitem').length).toEqual(4);
       expect(screen.getByText('Resume')).toBeInTheDocument();
       expect(screen.queryByText('Pause')).not.toBeInTheDocument();
       expectActionButtonsExists();
@@ -78,8 +81,8 @@ describe('Actions', () => {
         data: set({ ...connector }, 'status.state', ConnectorState.FAILED),
       }));
       renderComponent();
-      await afterClickDropDownButton();
-      expect(screen.getAllByRole('menuitem').length).toEqual(4);
+      await afterClickRestartButton();
+      expect(screen.getAllByRole('menuitem').length).toEqual(3);
       expect(screen.queryByText('Resume')).not.toBeInTheDocument();
       expect(screen.queryByText('Pause')).not.toBeInTheDocument();
       expectActionButtonsExists();
@@ -90,8 +93,8 @@ describe('Actions', () => {
         data: set({ ...connector }, 'status.state', ConnectorState.UNASSIGNED),
       }));
       renderComponent();
-      await afterClickDropDownButton();
-      expect(screen.getAllByRole('menuitem').length).toEqual(4);
+      await afterClickRestartButton();
+      expect(screen.getAllByRole('menuitem').length).toEqual(3);
       expect(screen.queryByText('Resume')).not.toBeInTheDocument();
       expect(screen.queryByText('Pause')).not.toBeInTheDocument();
       expectActionButtonsExists();
@@ -102,8 +105,8 @@ describe('Actions', () => {
         data: set({ ...connector }, 'status.state', ConnectorState.RUNNING),
       }));
       renderComponent();
-      await afterClickDropDownButton();
-      expect(screen.getAllByRole('menuitem').length).toEqual(5);
+      await afterClickRestartButton();
+      expect(screen.getAllByRole('menuitem').length).toEqual(4);
       expect(screen.queryByText('Resume')).not.toBeInTheDocument();
       expect(screen.getByText('Pause')).toBeInTheDocument();
       expectActionButtonsExists();
@@ -131,7 +134,7 @@ describe('Actions', () => {
           mutateAsync: restartConnector,
         }));
         renderComponent();
-        await afterClickDropDownButton();
+        await afterClickRestartButton();
         await userEvent.click(
           screen.getByRole('menuitem', { name: 'Restart Connector' })
         );
@@ -144,7 +147,7 @@ describe('Actions', () => {
           mutateAsync: restartAllTasks,
         }));
         renderComponent();
-        await afterClickDropDownButton();
+        await afterClickRestartButton();
         await userEvent.click(
           screen.getByRole('menuitem', { name: 'Restart All Tasks' })
         );
@@ -159,7 +162,7 @@ describe('Actions', () => {
           mutateAsync: restartFailedTasks,
         }));
         renderComponent();
-        await afterClickDropDownButton();
+        await afterClickRestartButton();
         await userEvent.click(
           screen.getByRole('menuitem', { name: 'Restart Failed Tasks' })
         );
@@ -174,7 +177,7 @@ describe('Actions', () => {
           mutateAsync: pauseConnector,
         }));
         renderComponent();
-        await afterClickDropDownButton();
+        await afterClickRestartButton();
         await userEvent.click(screen.getByRole('menuitem', { name: 'Pause' }));
         expect(pauseConnector).toHaveBeenCalledWith(ConnectorAction.PAUSE);
       });
@@ -188,7 +191,7 @@ describe('Actions', () => {
           mutateAsync: resumeConnector,
         }));
         renderComponent();
-        await afterClickDropDownButton();
+        await afterClickRestartButton();
         await userEvent.click(screen.getByRole('menuitem', { name: 'Resume' }));
         expect(resumeConnector).toHaveBeenCalledWith(ConnectorAction.RESUME);
       });

+ 4 - 2
kafka-ui-react-app/src/components/common/Button/Button.styled.ts

@@ -58,8 +58,10 @@ const StyledButton = styled.button<ButtonProps>`
     color: ${(props) => props.theme.button.primary.color};
   }
 
-  & svg {
-    margin-right: 7px;
+  & :first-of-type {
+    svg {
+      margin-right: 7px;
+    }
   }
 `;
 

+ 24 - 0
kafka-ui-react-app/src/components/common/Icons/ChevronDownIcon.tsx

@@ -0,0 +1,24 @@
+import React from 'react';
+import { useTheme } from 'styled-components';
+
+const ChevronDownIcon: React.FC = () => {
+  const theme = useTheme();
+  return (
+    <svg
+      width="10"
+      height="6"
+      viewBox="0 0 10 6"
+      fill="none"
+      xmlns="http://www.w3.org/2000/svg"
+    >
+      <path
+        fillRule="evenodd"
+        clipRule="evenodd"
+        d="M0.646447 0.646447C0.841709 0.451184 1.15829 0.451184 1.35355 0.646447L5 4.29289L8.64645 0.646447C8.84171 0.451184 9.15829 0.451184 9.35355 0.646447C9.54882 0.841709 9.54882 1.15829 9.35355 1.35355L5.35355 5.35355C5.15829 5.54882 4.84171 5.54882 4.64645 5.35355L0.646447 1.35355C0.451184 1.15829 0.451184 0.841709 0.646447 0.646447Z"
+        fill={theme.icons.chevronDownIcon}
+      />
+    </svg>
+  );
+};
+
+export default ChevronDownIcon;

+ 1 - 0
kafka-ui-react-app/src/theme/theme.ts

@@ -547,6 +547,7 @@ const theme = {
     },
   },
   icons: {
+    chevronDownIcon: Colors.neutral[90],
     closeIcon: Colors.neutral[30],
     deleteIcon: Colors.red[20],
     warningIcon: Colors.yellow[20],