Skip to content

Commit ea34810

Browse files
FE: Redesign connector actions (#3197)
* redesign connector actions * remove xpect(dropDownButton.length).toEqual(2) from Actions.spec.tsx --------- Co-authored-by: davitbejanyan <[email protected]> Co-authored-by: Roman Zabaluev <[email protected]>
1 parent 526b291 commit ea34810

File tree

6 files changed

+84
-28
lines changed

6 files changed

+84
-28
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import styled from 'styled-components';
2+
3+
export const ConnectorActionsWrapperStyled = styled.div`
4+
display: flex;
5+
flex-wrap: wrap;
6+
align-items: center;
7+
gap: 8px;
8+
`;
9+
export const ButtonLabel = styled.span`
10+
margin-right: 11.5px;
11+
`;
12+
export const RestartButton = styled.div`
13+
padding: 0 12px;
14+
border: none;
15+
border-radius: 4px;
16+
display: flex;
17+
-webkit-align-items: center;
18+
background: #e8e8fc;
19+
color: #171a1c;
20+
font-size: 14px;
21+
font-weight: 500;
22+
height: 32px;
23+
`;

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

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react';
2-
import styled from 'styled-components';
32
import { useNavigate } from 'react-router-dom';
43
import { useIsMutating } from '@tanstack/react-query';
54
import {
@@ -21,13 +20,9 @@ import {
2120
import { useConfirm } from 'lib/hooks/useConfirm';
2221
import { Dropdown } from 'components/common/Dropdown';
2322
import { ActionDropdownItem } from 'components/common/ActionComponent';
23+
import ChevronDownIcon from 'components/common/Icons/ChevronDownIcon';
2424

25-
const ConnectorActionsWrapperStyled = styled.div`
26-
display: flex;
27-
flex-wrap: wrap;
28-
align-items: center;
29-
gap: 8px;
30-
`;
25+
import * as S from './Action.styled';
3126

3227
const Actions: React.FC = () => {
3328
const navigate = useNavigate();
@@ -66,10 +61,16 @@ const Actions: React.FC = () => {
6661
stateMutation.mutateAsync(ConnectorAction.PAUSE);
6762
const resumeConnectorHandler = () =>
6863
stateMutation.mutateAsync(ConnectorAction.RESUME);
69-
7064
return (
71-
<ConnectorActionsWrapperStyled>
72-
<Dropdown>
65+
<S.ConnectorActionsWrapperStyled>
66+
<Dropdown
67+
label={
68+
<S.RestartButton>
69+
<S.ButtonLabel>Restart</S.ButtonLabel>
70+
<ChevronDownIcon />
71+
</S.RestartButton>
72+
}
73+
>
7374
{connector?.status.state === ConnectorState.RUNNING && (
7475
<ActionDropdownItem
7576
onClick={pauseConnectorHandler}
@@ -129,6 +130,8 @@ const Actions: React.FC = () => {
129130
>
130131
Restart Failed Tasks
131132
</ActionDropdownItem>
133+
</Dropdown>
134+
<Dropdown>
132135
<ActionDropdownItem
133136
onClick={deleteConnectorHandler}
134137
disabled={isMutating}
@@ -142,7 +145,7 @@ const Actions: React.FC = () => {
142145
Delete
143146
</ActionDropdownItem>
144147
</Dropdown>
145-
</ConnectorActionsWrapperStyled>
148+
</S.ConnectorActionsWrapperStyled>
146149
);
147150
};
148151

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

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ const expectActionButtonsExists = () => {
3535
};
3636
const afterClickDropDownButton = async () => {
3737
const dropDownButton = screen.getAllByRole('button');
38-
expect(dropDownButton.length).toEqual(1);
39-
await userEvent.click(dropDownButton[0]);
38+
await userEvent.click(dropDownButton[1]);
39+
};
40+
const afterClickRestartButton = async () => {
41+
const dropDownButton = screen.getByText('Restart');
42+
await userEvent.click(dropDownButton);
4043
};
4144
describe('Actions', () => {
4245
afterEach(() => {
@@ -66,8 +69,8 @@ describe('Actions', () => {
6669
data: set({ ...connector }, 'status.state', ConnectorState.PAUSED),
6770
}));
6871
renderComponent();
69-
await afterClickDropDownButton();
70-
expect(screen.getAllByRole('menuitem').length).toEqual(5);
72+
await afterClickRestartButton();
73+
expect(screen.getAllByRole('menuitem').length).toEqual(4);
7174
expect(screen.getByText('Resume')).toBeInTheDocument();
7275
expect(screen.queryByText('Pause')).not.toBeInTheDocument();
7376
expectActionButtonsExists();
@@ -78,8 +81,8 @@ describe('Actions', () => {
7881
data: set({ ...connector }, 'status.state', ConnectorState.FAILED),
7982
}));
8083
renderComponent();
81-
await afterClickDropDownButton();
82-
expect(screen.getAllByRole('menuitem').length).toEqual(4);
84+
await afterClickRestartButton();
85+
expect(screen.getAllByRole('menuitem').length).toEqual(3);
8386
expect(screen.queryByText('Resume')).not.toBeInTheDocument();
8487
expect(screen.queryByText('Pause')).not.toBeInTheDocument();
8588
expectActionButtonsExists();
@@ -90,8 +93,8 @@ describe('Actions', () => {
9093
data: set({ ...connector }, 'status.state', ConnectorState.UNASSIGNED),
9194
}));
9295
renderComponent();
93-
await afterClickDropDownButton();
94-
expect(screen.getAllByRole('menuitem').length).toEqual(4);
96+
await afterClickRestartButton();
97+
expect(screen.getAllByRole('menuitem').length).toEqual(3);
9598
expect(screen.queryByText('Resume')).not.toBeInTheDocument();
9699
expect(screen.queryByText('Pause')).not.toBeInTheDocument();
97100
expectActionButtonsExists();
@@ -102,8 +105,8 @@ describe('Actions', () => {
102105
data: set({ ...connector }, 'status.state', ConnectorState.RUNNING),
103106
}));
104107
renderComponent();
105-
await afterClickDropDownButton();
106-
expect(screen.getAllByRole('menuitem').length).toEqual(5);
108+
await afterClickRestartButton();
109+
expect(screen.getAllByRole('menuitem').length).toEqual(4);
107110
expect(screen.queryByText('Resume')).not.toBeInTheDocument();
108111
expect(screen.getByText('Pause')).toBeInTheDocument();
109112
expectActionButtonsExists();
@@ -131,7 +134,7 @@ describe('Actions', () => {
131134
mutateAsync: restartConnector,
132135
}));
133136
renderComponent();
134-
await afterClickDropDownButton();
137+
await afterClickRestartButton();
135138
await userEvent.click(
136139
screen.getByRole('menuitem', { name: 'Restart Connector' })
137140
);
@@ -144,7 +147,7 @@ describe('Actions', () => {
144147
mutateAsync: restartAllTasks,
145148
}));
146149
renderComponent();
147-
await afterClickDropDownButton();
150+
await afterClickRestartButton();
148151
await userEvent.click(
149152
screen.getByRole('menuitem', { name: 'Restart All Tasks' })
150153
);
@@ -159,7 +162,7 @@ describe('Actions', () => {
159162
mutateAsync: restartFailedTasks,
160163
}));
161164
renderComponent();
162-
await afterClickDropDownButton();
165+
await afterClickRestartButton();
163166
await userEvent.click(
164167
screen.getByRole('menuitem', { name: 'Restart Failed Tasks' })
165168
);
@@ -174,7 +177,7 @@ describe('Actions', () => {
174177
mutateAsync: pauseConnector,
175178
}));
176179
renderComponent();
177-
await afterClickDropDownButton();
180+
await afterClickRestartButton();
178181
await userEvent.click(screen.getByRole('menuitem', { name: 'Pause' }));
179182
expect(pauseConnector).toHaveBeenCalledWith(ConnectorAction.PAUSE);
180183
});
@@ -188,7 +191,7 @@ describe('Actions', () => {
188191
mutateAsync: resumeConnector,
189192
}));
190193
renderComponent();
191-
await afterClickDropDownButton();
194+
await afterClickRestartButton();
192195
await userEvent.click(screen.getByRole('menuitem', { name: 'Resume' }));
193196
expect(resumeConnector).toHaveBeenCalledWith(ConnectorAction.RESUME);
194197
});

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ const StyledButton = styled.button<ButtonProps>`
5858
color: ${(props) => props.theme.button.primary.color};
5959
}
6060
61-
& svg {
62-
margin-right: 7px;
61+
& :first-of-type {
62+
svg {
63+
margin-right: 7px;
64+
}
6365
}
6466
`;
6567

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
import { useTheme } from 'styled-components';
3+
4+
const ChevronDownIcon: React.FC = () => {
5+
const theme = useTheme();
6+
return (
7+
<svg
8+
width="10"
9+
height="6"
10+
viewBox="0 0 10 6"
11+
fill="none"
12+
xmlns="http://www.w3.org/2000/svg"
13+
>
14+
<path
15+
fillRule="evenodd"
16+
clipRule="evenodd"
17+
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"
18+
fill={theme.icons.chevronDownIcon}
19+
/>
20+
</svg>
21+
);
22+
};
23+
24+
export default ChevronDownIcon;

kafka-ui-react-app/src/theme/theme.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ const theme = {
547547
},
548548
},
549549
icons: {
550+
chevronDownIcon: Colors.neutral[90],
550551
closeIcon: Colors.neutral[30],
551552
deleteIcon: Colors.red[20],
552553
warningIcon: Colors.yellow[20],

0 commit comments

Comments
 (0)