Skip to content

Commit 0173a48

Browse files
authored
[UI] Allow to hide the Tour panel (#2816)
* [UI] Allow to hide the Tour panel #286 * [UI] Allow to hide the Tour panel #286 Fixes after review
1 parent c5c7edb commit 0173a48

File tree

5 files changed

+85
-12
lines changed

5 files changed

+85
-12
lines changed

frontend/src/App/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export const AUTH_DATA_STORAGE_KEY = 'authData';
22
export const MODE_STORAGE_KEY = 'mode';
3+
export const TUTORIAL_SHOW_STARTUP_STORAGE_KEY = 'tutorial-show-startup';

frontend/src/App/slice.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import type { RootState } from 'store';
22
import { applyMode, Mode } from '@cloudscape-design/global-styles';
33
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
44

5-
import { AUTH_DATA_STORAGE_KEY, MODE_STORAGE_KEY } from './constants';
5+
import { AUTH_DATA_STORAGE_KEY, MODE_STORAGE_KEY, TUTORIAL_SHOW_STARTUP_STORAGE_KEY } from './constants';
66
import { getThemeMode } from './helpers';
77

88
import { IAppState, ToolsTabs } from './types';
99

1010
const getInitialState = (): IAppState => {
1111
let authData = null;
1212
let storageData = null;
13+
let hideStartUp: null | boolean = null;
1314
let activeMode = getThemeMode();
1415

1516
try {
@@ -18,6 +19,18 @@ const getInitialState = (): IAppState => {
1819
console.log(e);
1920
}
2021

22+
try {
23+
hideStartUp = (() => {
24+
if (!localStorage.getItem(TUTORIAL_SHOW_STARTUP_STORAGE_KEY)) {
25+
return null;
26+
}
27+
28+
return localStorage.getItem(TUTORIAL_SHOW_STARTUP_STORAGE_KEY) === 'true';
29+
})();
30+
} catch (e) {
31+
console.log(e);
32+
}
33+
2134
try {
2235
const modeStorageData = localStorage.getItem(MODE_STORAGE_KEY);
2336

@@ -53,6 +66,7 @@ const getInitialState = (): IAppState => {
5366
discordCompleted: false,
5467
tallyCompleted: false,
5568
quickStartCompleted: false,
69+
hideStartUp,
5670
},
5771
};
5872
};
@@ -138,6 +152,19 @@ export const appSlice = createSlice({
138152
...action.payload,
139153
};
140154
},
155+
156+
setHideAtStartup: (state, action: PayloadAction<boolean>) => {
157+
state.tutorialPanel = {
158+
...state.tutorialPanel,
159+
hideStartUp: action.payload,
160+
};
161+
162+
try {
163+
localStorage.setItem(TUTORIAL_SHOW_STARTUP_STORAGE_KEY, JSON.stringify(action.payload));
164+
} catch (e) {
165+
console.log(e);
166+
}
167+
},
141168
},
142169
});
143170

@@ -152,6 +179,7 @@ export const {
152179
setToolsTab,
153180
openTutorialPanel,
154181
updateTutorialPanelState,
182+
setHideAtStartup,
155183
} = appSlice.actions;
156184
export const selectUserData = (state: RootState) => state.app.userData;
157185
export const selectAuthToken = (state: RootState) => state.app.authData?.token;

frontend/src/App/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ export interface IAppState {
3737
discordCompleted: boolean;
3838
tallyCompleted: boolean;
3939
quickStartCompleted: boolean;
40+
hideStartUp: boolean | null;
4041
};
4142
}

frontend/src/layouts/AppLayout/TutorialPanel/hooks.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const useTutorials = () => {
2929
const dispatch = useAppDispatch();
3030
const { billingUrl } = useSideNavigation();
3131
const useName = useAppSelector(selectUserName);
32-
const { billingCompleted, configureCLICompleted, discordCompleted, tallyCompleted, quickStartCompleted } =
32+
const { billingCompleted, configureCLICompleted, discordCompleted, tallyCompleted, quickStartCompleted, hideStartUp } =
3333
useAppSelector(selectTutorialPanel);
3434

3535
const { data: userBillingData } = useGetUserBillingInfoQuery({ username: useName ?? '' }, { skip: !useName });
@@ -41,14 +41,19 @@ export const useTutorials = () => {
4141

4242
useEffect(() => {
4343
if (userBillingData && runsData && !completeIsChecked.current) {
44-
dispatch(
45-
updateTutorialPanelState({
46-
billingCompleted: userBillingData.balance > 0,
47-
configureCLICompleted: runsData.length > 0,
48-
}),
49-
);
50-
51-
if ((userBillingData.balance <= 0 || runsData.length === 0) && process.env.UI_VERSION === 'sky') {
44+
const billingCompleted = userBillingData.balance > 0;
45+
const configureCLICompleted = runsData.length > 0;
46+
47+
let tempHideStartUp = hideStartUp;
48+
49+
if (hideStartUp === null) {
50+
tempHideStartUp = billingCompleted && configureCLICompleted;
51+
}
52+
53+
// Set hideStartUp without updating localstorage
54+
dispatch(updateTutorialPanelState({ billingCompleted, configureCLICompleted, hideStartUp: tempHideStartUp }));
55+
56+
if (!tempHideStartUp && process.env.UI_VERSION === 'sky') {
5257
dispatch(openTutorialPanel());
5358
}
5459

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
import React from 'react';
1+
import React, { useLayoutEffect, useRef } from 'react';
2+
import { createRoot, Root } from 'react-dom/client';
23

3-
import { TutorialPanel as TutorialPanelGeneric, TutorialPanelProps } from 'components';
4+
import { Box, Toggle, TutorialPanel as TutorialPanelGeneric, TutorialPanelProps } from 'components';
5+
6+
import { useAppDispatch, useAppSelector } from 'hooks';
7+
8+
import { selectTutorialPanel, setHideAtStartup } from 'App/slice';
49

510
import { tutorialPanelI18nStrings } from './constants';
611
import { useTutorials } from './hooks';
@@ -10,7 +15,40 @@ export interface Props extends Partial<TutorialPanelProps> {
1015
}
1116

1217
export const TutorialPanel: React.FC<Props> = () => {
18+
const dispatch = useAppDispatch();
1319
const { tutorials } = useTutorials();
20+
const tutorialRootRef = useRef<Root>(null);
21+
const { hideStartUp } = useAppSelector(selectTutorialPanel);
22+
23+
const onChangeShowStartUp = (value: boolean) => {
24+
dispatch(setHideAtStartup(!value));
25+
};
26+
27+
const renderShowAtStartup = () => {
28+
return (
29+
<Box padding={{ vertical: 'm' }}>
30+
<Toggle onChange={({ detail }) => onChangeShowStartUp(detail.checked)} checked={!hideStartUp}>
31+
Show at startup
32+
</Toggle>
33+
</Box>
34+
);
35+
};
36+
37+
useLayoutEffect(() => {
38+
const tutorialPanelElement = document.querySelector('[class*="awsui_tutorial-panel"]');
39+
40+
if (tutorialPanelElement && !tutorialRootRef.current) {
41+
const divElement = document.createElement('div');
42+
tutorialPanelElement.appendChild(divElement);
43+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
44+
// @ts-ignore
45+
tutorialRootRef.current = createRoot(divElement);
46+
}
47+
48+
if (tutorialRootRef.current) {
49+
tutorialRootRef.current.render(renderShowAtStartup());
50+
}
51+
}, [hideStartUp]);
1452

1553
return <TutorialPanelGeneric i18nStrings={tutorialPanelI18nStrings} tutorials={tutorials} />;
1654
};

0 commit comments

Comments
 (0)