Skip to content

Commit 82ad714

Browse files
Leshe4kaLeshe4kaHaaroleanVladSenyuta
authored
UX: Custom colored cluster menu (kafbat#398)
Co-authored-by: Leshe4ka <[email protected]> Co-authored-by: Roman Zabaluev <[email protected]> Co-authored-by: Vlad Senyuta <[email protected]>
1 parent add8ef2 commit 82ad714

File tree

20 files changed

+329
-45
lines changed

20 files changed

+329
-45
lines changed

build.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,14 @@ subprojects {
2828

2929
boolean resolveBooleanProperty(String propertyName, boolean defaultValue = false) {
3030
def propertyValueStr = findProperty(propertyName)
31-
return propertyValueStr == null ? defaultValue : propertyValueStr.toBoolean();
31+
return propertyValueStr == null ? defaultValue : propertyValueStr.toBoolean()
3232
}
3333

3434
ext {
3535
release = resolveBooleanProperty("release")
3636
includeFrontend = resolveBooleanProperty("include-frontend", release)
3737
buildDockerImages = resolveBooleanProperty("build-docker-images", release)
3838
runE2e = resolveBooleanProperty("run-e2e")
39-
e2eHeadlessOff = resolveBooleanProperty("e2e-headless-off")
40-
e2eSelenoidOff = resolveBooleanProperty("e2e-selenoid-off")
4139
}
4240

4341
sonar {

e2e-tests/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ docker-compose -f documentation/compose/e2e-tests.yaml up -d
4040
2. To run test suite select its name (options: `regression`, `sanity`, `smoke`) and put it instead %s into command below
4141

4242
```
43-
./mvnw -Dsurefire.suiteXmlFiles='src/test/resources/%s.xml' -f 'e2e-tests' test -Pprod
43+
./gradlew :e2e-tests:test -Prun-e2e=true -Psuite_name=%s
4444
```
4545

4646
### Reporting

e2e-tests/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ test {
5252
suiteXmlFiles = [suitePath.toFile()]
5353
}
5454

55-
systemProperty "headless", e2eHeadlessOff
56-
systemProperty "selenoid", e2eSelenoidOff
5755
systemProperty "allure.results.directory",
5856
project.layout.buildDirectory.dir("allure-results").get().getAsFile().getAbsolutePath()
5957
}

e2e-tests/src/main/java/io/kafbat/ui/screens/connectors/ConnectorDetails.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class ConnectorDetails extends BasePage {
2121
@Step
2222
public ConnectorDetails waitUntilScreenReady() {
2323
waitUntilSpinnerDisappear();
24-
dotMenuBtn.shouldBe(Condition.visible);
24+
taskTab.shouldBe(Condition.visible);
2525
return this;
2626
}
2727

@@ -48,7 +48,7 @@ public ConnectorDetails clickSubmitButton() {
4848

4949
@Step
5050
public ConnectorDetails openDotMenu() {
51-
WebUtil.clickByJavaScript(dotMenuBtn);
51+
WebUtil.clickByActions(dotMenuBtn);
5252
return this;
5353
}
5454

e2e-tests/src/main/java/io/kafbat/ui/screens/schemas/SchemaDetails.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public SchemaDetails openCompareVersionMenu() {
6161

6262
@Step
6363
public SchemaDetails removeSchema() {
64-
WebUtil.clickByJavaScript(dotMenuBtn);
64+
WebUtil.clickByActions(dotMenuBtn);
6565
removeBtn.shouldBe(Condition.enabled).click();
6666
schemaConfirmBtn.shouldBe(Condition.visible).click();
6767
schemaConfirmBtn.shouldBe(Condition.disappear);

e2e-tests/src/main/java/io/kafbat/ui/screens/topics/TopicDetails.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public String getSettingsGridValueByKey(String key) {
9191

9292
@Step
9393
public TopicDetails openDotMenu() {
94-
WebUtil.clickByJavaScript(dotMenuBtn);
94+
WebUtil.clickByActions(dotMenuBtn);
9595
return this;
9696
}
9797

e2e-tests/src/main/java/io/kafbat/ui/settings/BaseSource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
public abstract class BaseSource {
88

99
public static final boolean HEADLESS = parseBoolean(getOptionalString(TRUE, System.getProperty("headless")));
10+
public static final boolean SELENOID = parseBoolean(getOptionalString(TRUE, System.getProperty("selenoid")));
1011
public static final String CLUSTER_NAME = "local";
1112
public static final String CONNECT_NAME = "first";
1213
private static final String LOCAL_HOST = "localhost";
1314
public static final String REMOTE_URL = String.format("http://%s:4444/wd/hub", LOCAL_HOST);
1415
public static final String BASE_API_URL = String.format("http://%s:8080", LOCAL_HOST);
15-
public static final String BASE_HOST = "host.docker.internal";
16+
public static final String BASE_HOST = SELENOID ? "host.docker.internal" : LOCAL_HOST;
1617
public static final String BASE_UI_URL = String.format("http://%s:8080", BASE_HOST);
1718
}

e2e-tests/src/main/java/io/kafbat/ui/settings/drivers/WebDriver.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ public static void browserSetup() {
3838
.addArguments("--disable-gpu")
3939
.addArguments("--no-sandbox")
4040
.addArguments("--lang=en_US");
41-
42-
Configuration.remote = BaseSource.REMOTE_URL;
43-
Configuration.remoteConnectionTimeout = 180000;
44-
Configuration.remoteReadTimeout = 180000;
45-
Map<String, Object> selenoidOptions = new HashMap<>();
46-
selenoidOptions.put("enableVNC", true);
47-
selenoidOptions.put("enableLog", true);
48-
selenoidOptions.put("enableVideo", false);
49-
selenoidOptions.put("sessionTimeout", "30m");
50-
chromeOptions.setCapability("selenoid:options", selenoidOptions);
51-
41+
if (BaseSource.SELENOID) {
42+
Configuration.remote = BaseSource.REMOTE_URL;
43+
Configuration.remoteConnectionTimeout = 180000;
44+
Configuration.remoteReadTimeout = 180000;
45+
Map<String, Object> selenoidOptions = new HashMap<>();
46+
selenoidOptions.put("enableVNC", true);
47+
selenoidOptions.put("enableLog", true);
48+
selenoidOptions.put("enableVideo", false);
49+
selenoidOptions.put("sessionTimeout", "30m");
50+
chromeOptions.setCapability("selenoid:options", selenoidOptions);
51+
}
5252
Configuration.browserCapabilities = chromeOptions;
5353
}
5454

frontend/src/components/Nav/ClusterMenu/ClusterMenu.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import {
2020
clusterTopicsRelativePath,
2121
} from 'lib/paths';
2222
import { useLocation } from 'react-router-dom';
23+
import { useLocalStorage } from 'lib/hooks/useLocalStorage';
24+
import { ClusterColorKey } from 'theme/theme';
2325

2426
interface ClusterMenuProps {
2527
name: Cluster['name'];
@@ -38,17 +40,22 @@ const ClusterMenu: FC<ClusterMenuProps> = ({
3840
features?.includes(key);
3941
const [isOpen, setIsOpen] = useState(!!singleMode);
4042
const location = useLocation();
43+
const [colorKey, setColorKey] = useLocalStorage<ClusterColorKey>(
44+
`clusterColor-${name}`,
45+
'transparent'
46+
);
4147

4248
const getIsMenuItemActive = (path: string) =>
4349
location.pathname.includes(path);
4450

4551
return (
46-
<ul role="menu">
52+
<S.ClusterList role="menu" $colorKey={colorKey}>
4753
<MenuTab
4854
title={name}
4955
status={status}
5056
isOpen={isOpen}
5157
toggleClusterMenu={() => setIsOpen((prev) => !prev)}
58+
setColorKey={setColorKey}
5259
/>
5360
{isOpen && (
5461
<S.List>
@@ -98,7 +105,7 @@ const ClusterMenu: FC<ClusterMenuProps> = ({
98105
)}
99106
</S.List>
100107
)}
101-
</ul>
108+
</S.ClusterList>
102109
);
103110
};
104111

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import styled from 'styled-components';
2+
import { ClusterColorKey } from 'theme/theme';
3+
4+
export const Container = styled.div`
5+
display: grid;
6+
grid-template-columns: repeat(5, 1fr);
7+
grid-template-rows: repeat(2, auto);
8+
padding: 0 8px;
9+
gap: 8px;
10+
border-radius: 8px;
11+
cursor: auto;
12+
`;
13+
14+
export const ColorCircle = styled.div<{ $colorKey: ClusterColorKey }>`
15+
width: 16px;
16+
height: 16px;
17+
border-radius: 50%;
18+
margin: 4px;
19+
background-color: ${({ $colorKey, theme }) =>
20+
theme.clusterColorPicker.backgroundColor[$colorKey]};
21+
cursor: pointer;
22+
display: flex;
23+
align-items: center;
24+
justify-content: center;
25+
26+
&:hover {
27+
outline: ${({ theme }) => `1px solid ${theme.clusterColorPicker.outline}`};
28+
}
29+
30+
&:active {
31+
outline: ${({ theme }) => `2px solid ${theme.clusterColorPicker.outline}`};
32+
}
33+
34+
${({ $colorKey, theme }) =>
35+
$colorKey === 'transparent' &&
36+
`
37+
border: 1px solid ${theme.clusterColorPicker.transparentCircle.border};
38+
&:before {
39+
content: '\\2716';
40+
font-size: 8px;
41+
color: ${theme.clusterColorPicker.transparentCircle.cross};
42+
}
43+
&:hover {
44+
border: none;
45+
}
46+
&:active {
47+
border: none;
48+
}
49+
`}
50+
`;

0 commit comments

Comments
 (0)