Skip to content

Commit 27c6d1e

Browse files
suratdaspashidlos
andauthored
Issue 280 : Implement frontend help/guide in the UI (#221)
* Issue 280 : Implement frontend help/guide in the UI * Fixed review comments. * Fixed Codacy errors. * Removed extra click on beakon and help button style change. * Help context refactor propose * Update test.moun.helper.tsx * Moved all help locator and texts to a separate file. * steps are moved to constants * Update Header.spec.tsx Co-authored-by: Pavel Strunkin <[email protected]>
1 parent c54a263 commit 27c6d1e

19 files changed

+419
-55
lines changed

package-lock.json

Lines changed: 99 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"react-debounce-input": "^3.2.2",
2222
"react-dom": "^16.13.1",
2323
"react-hotkeys-hook": "^2.4.0",
24+
"react-joyride": "^2.3.1",
2425
"react-konva": "^16.13.0-3",
2526
"react-material-ui-form-validator": "^2.1.1",
2627
"react-router-dom": "^5.2.0",

src/App.jsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
BuildProvider,
99
TestRunProvider,
1010
SocketProvider,
11+
HelpProvider,
1112
} from "./contexts";
1213
import Router from "./Router";
1314

@@ -19,12 +20,14 @@ function App() {
1920
<BuildProvider>
2021
<TestRunProvider>
2122
<SocketProvider>
22-
<Box height="10%">
23-
<Header />
24-
</Box>
25-
<Box height="90%">
26-
<Router />
27-
</Box>
23+
<HelpProvider>
24+
<Box height="10%">
25+
<Header />
26+
</Box>
27+
<Box height="90%">
28+
<Router />
29+
</Box>
30+
</HelpProvider>
2831
</SocketProvider>
2932
</TestRunProvider>
3033
</BuildProvider>

src/_test/test.moun.helper.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
UserProvider,
66
BuildProvider,
77
TestRunProvider,
8+
HelpProvider,
89
} from "../contexts";
910
import { MemoryRouter, Route } from "react-router-dom";
1011
import { MemoryRouterProps } from "react-router";
@@ -26,7 +27,9 @@ export const mountVrtComponent = ({
2627
<UserProvider>
2728
<ProjectProvider>
2829
<BuildProvider>
29-
<TestRunProvider>{component}</TestRunProvider>
30+
<HelpProvider>
31+
<TestRunProvider>{component}</TestRunProvider>
32+
</HelpProvider>
3033
</BuildProvider>
3134
</ProjectProvider>
3235
</UserProvider>

src/components/BuildDetails.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import { BuildStatusChip } from "./BuildStatusChip";
1010
import { formatDateTime } from "../_helpers/format.helper";
1111
import { useBuildState } from "../contexts";
12+
import { LOCATOR_BUILD_DETAILS } from '../constants/help';
1213

1314
const BuildDetails: React.FunctionComponent = () => {
1415
const { selectedBuild } = useBuildState();
@@ -20,7 +21,7 @@ const BuildDetails: React.FunctionComponent = () => {
2021
const loadingAnimation = selectedBuild.isRunning && <LinearProgress />;
2122

2223
return (
23-
<Grid container direction="column">
24+
<Grid container direction="column" id={LOCATOR_BUILD_DETAILS}>
2425
<Grid item>
2526
<Box m={0.5}>
2627
<Grid container spacing={1} alignItems="center">

src/components/Filters.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from "@material-ui/core";
1111
import { TestRun, TestVariation } from "../types";
1212
import { DebounceInput } from "react-debounce-input";
13+
import { LOCATOR_RESET_FILTER } from "../constants/help";
1314

1415
interface IProps {
1516
items: (TestRun | TestVariation)[];
@@ -239,7 +240,7 @@ const Filters: React.FunctionComponent<IProps> = ({
239240
)}
240241
{branchNameList && branchNameList.length > 0 && (
241242
<Grid item xs>
242-
<FormControl fullWidth>
243+
<FormControl fullWidth id={LOCATOR_RESET_FILTER}>
243244
<InputLabel shrink id="filter_branchName">
244245
Branch
245246
</InputLabel>

src/components/GuidedTour.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React, { FunctionComponent } from "react";
2+
import Joyride, { CallBackProps, STATUS } from "react-joyride";
3+
import { IconButton, Avatar } from "@material-ui/core";
4+
import { HelpOutline } from "@material-ui/icons";
5+
import { useHelpState } from "../contexts";
6+
7+
const GuidedTour: FunctionComponent = () => {
8+
const [run, setRun] = React.useState(false);
9+
const { helpSteps } = useHelpState();
10+
11+
const getHelpSteps = React.useCallback(() => {
12+
const firstStep = helpSteps[0];
13+
//Below line is to prevent application breaking if element is not present for any reason (e.g. if the user deletes build or if there is no data.)
14+
if (
15+
firstStep &&
16+
document.getElementById(firstStep.target.toString().slice(1))
17+
) {
18+
helpSteps.forEach((e) => {
19+
e.disableBeacon = true;
20+
e.hideCloseButton = true;
21+
});
22+
return helpSteps;
23+
}
24+
return [];
25+
}, [helpSteps]);
26+
27+
const handleJoyrideCallback = (data: CallBackProps) => {
28+
const { status } = data;
29+
const finishedStatuses: string[] = [STATUS.FINISHED, STATUS.SKIPPED];
30+
31+
if (finishedStatuses.includes(status)) {
32+
setRun(false);
33+
}
34+
};
35+
36+
const handleClickStart = (e: React.MouseEvent<HTMLElement>) => {
37+
e.preventDefault();
38+
setRun(true);
39+
};
40+
41+
return (
42+
<React.Fragment>
43+
<IconButton onClick={handleClickStart}>
44+
<Avatar>
45+
<HelpOutline />
46+
<Joyride
47+
callback={handleJoyrideCallback}
48+
continuous={true}
49+
run={run}
50+
scrollToFirstStep={true}
51+
showProgress={true}
52+
showSkipButton={true}
53+
steps={getHelpSteps()}
54+
disableCloseOnEsc={true}
55+
styles={{
56+
options: {
57+
zIndex: 10000,
58+
},
59+
buttonNext: { color: "#3f51b5", backgroundColor: "" },
60+
buttonBack: { color: "#3f51b5" },
61+
}}
62+
/>
63+
</Avatar>
64+
</IconButton>
65+
</React.Fragment>
66+
);
67+
};
68+
69+
export default GuidedTour;

src/components/Header.spec.tsx

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,25 @@
11
/* global cy */
22
import React from "react";
3-
import { mount } from "@cypress/react";
43
import Header from "./Header";
5-
import { UserProvider } from "../contexts";
6-
import { BrowserRouter } from "react-router-dom";
74
import { haveUserLogged } from "../_test/precondition.helper";
8-
import { TEST_USER } from "../_test/test.data.helper";
5+
import { TEST_PROJECT, TEST_USER } from "../_test/test.data.helper";
6+
import { mountVrtComponent } from "../_test/test.moun.helper";
7+
import { projectStub } from "../_test/stub.helper";
98

109
describe("Header", () => {
1110
describe("image", () => {
1211
it("Guest", () => {
1312
localStorage.clear();
14-
mount(
15-
<BrowserRouter>
16-
<UserProvider>
17-
<Header />
18-
</UserProvider>
19-
</BrowserRouter>
20-
);
13+
mountVrtComponent({ component: <Header /> });
2114

2215
cy.get("#__cy_root").vrtTrack("Header. Guest");
2316
});
2417

2518
it("Logged", () => {
2619
haveUserLogged(TEST_USER);
27-
mount(
28-
<BrowserRouter>
29-
<UserProvider>
30-
<Header />
31-
</UserProvider>
32-
</BrowserRouter>
33-
);
20+
projectStub.getAll([TEST_PROJECT]);
21+
22+
mountVrtComponent({ component: <Header /> });
3423

3524
cy.get("#__cy_root").vrtTrack("Header. Logged");
3625
});

0 commit comments

Comments
 (0)