Skip to content

Commit beb00f9

Browse files
authored
Merge pull request #4109 from RedisInsight/be/feature/RI-6321
#RI-6321 - set my tutorials collapsed by default
2 parents 797972a + bdb48d8 commit beb00f9

File tree

10 files changed

+149
-14
lines changed

10 files changed

+149
-14
lines changed

redisinsight/api/src/__mocks__/custom-tutorial.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export const globalCustomTutorialManifest = {
143143
_actions: [CustomTutorialActions.CREATE],
144144
args: {
145145
withBorder: true,
146-
initialIsOpen: true,
146+
initialIsOpen: false,
147147
},
148148
children: [
149149
mockCustomTutorialManifest,

redisinsight/api/src/modules/custom-tutorial/custom-tutorial.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export class CustomTutorialService {
145145
_actions: [CustomTutorialActions.CREATE],
146146
args: {
147147
withBorder: true,
148-
initialIsOpen: true,
148+
initialIsOpen: false,
149149
},
150150
children,
151151
};

redisinsight/api/test/api/custom-tutorials/POST-custom-tutorials.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const globalManifest = {
101101
'create',
102102
],
103103
args: {
104-
initialIsOpen: true,
104+
initialIsOpen: false,
105105
withBorder: true,
106106
},
107107
children: [],

redisinsight/ui/src/components/side-panels/panels/enablement-area/EnablementArea/components/Group/Group.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,15 @@ const Group = (props: Props) => {
7373
}
7474

7575
const handleOpen = (isOpen: boolean) => {
76+
if (forceState === 'open') return
77+
7678
setIsGroupOpen(isOpen)
7779
onToggle?.(isOpen)
7880
}
7981

8082
const actionsContent = (
8183
<>
82-
{actions?.includes(EAItemActions.Create) && (
84+
{actions?.includes(EAItemActions.Create) && (isGroupOpen || forceState === 'open') && (
8385
<OnboardingTour
8486
options={ONBOARDING_FEATURES.EXPLORE_CUSTOM_TUTORIALS}
8587
anchorPosition="downLeft"

redisinsight/ui/src/components/side-panels/panels/enablement-area/EnablementArea/components/Navigation/Navigation.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1-
import React, { useState } from 'react'
1+
import React, { useEffect, useState } from 'react'
22
import cx from 'classnames'
33
import { EuiListGroup } from '@elastic/eui'
44
import { isArray } from 'lodash'
55
import { useParams } from 'react-router-dom'
6-
import { useDispatch } from 'react-redux'
6+
import { useDispatch, useSelector } from 'react-redux'
77
import { EnablementAreaComponent, IEnablementAreaItem } from 'uiSrc/slices/interfaces'
88

99
import { ApiEndpoints, EAItemActions, EAManifestFirstKey } from 'uiSrc/constants'
1010
import { sendEventTelemetry, TELEMETRY_EMPTY_VALUE, TelemetryEvent } from 'uiSrc/telemetry'
11-
import { deleteCustomTutorial, uploadCustomTutorial } from 'uiSrc/slices/workbench/wb-custom-tutorials'
11+
import {
12+
deleteCustomTutorial,
13+
setWbCustomTutorialsState,
14+
uploadCustomTutorial
15+
} from 'uiSrc/slices/workbench/wb-custom-tutorials'
1216

1317
import UploadWarning from 'uiSrc/components/upload-warning'
18+
import { appFeatureOnboardingSelector } from 'uiSrc/slices/app/features'
19+
import { OnboardingSteps } from 'uiSrc/constants/onboarding'
1420
import {
1521
FormValues
1622
} from '../UploadTutorialForm/UploadTutorialForm'
@@ -41,12 +47,19 @@ const PATHS = {
4147

4248
const Navigation = (props: Props) => {
4349
const { tutorials, customTutorials, isInternalPageVisible } = props
50+
const { currentStep, isActive } = useSelector(appFeatureOnboardingSelector)
4451

4552
const [isCreateOpen, setIsCreateOpen] = useState(false)
4653

4754
const dispatch = useDispatch()
4855
const { instanceId = '' } = useParams<{ instanceId: string }>()
4956

57+
const isCustomTutorialsOnboarding = currentStep === OnboardingSteps.CustomTutorials && isActive
58+
59+
useEffect(() => () => {
60+
dispatch(setWbCustomTutorialsState())
61+
}, [])
62+
5063
const submitCreate = ({ file, link }: FormValues) => {
5164
const formData = new FormData()
5265

@@ -66,7 +79,10 @@ const Navigation = (props: Props) => {
6679

6780
dispatch(uploadCustomTutorial(
6881
formData,
69-
() => setIsCreateOpen(false),
82+
() => {
83+
setIsCreateOpen(false)
84+
dispatch(setWbCustomTutorialsState(true))
85+
},
7086
))
7187
}
7288

@@ -111,6 +127,7 @@ const Navigation = (props: Props) => {
111127
onCreate={() => setIsCreateOpen((v) => !v)}
112128
onDelete={onDeleteCustomTutorial}
113129
isPageOpened={isInternalPageVisible}
130+
forceState={isCustomTutorials && isCustomTutorialsOnboarding ? 'open' : undefined}
114131
{...args}
115132
>
116133
{isCustomTutorials && actions?.includes(EAItemActions.Create) && (

redisinsight/ui/src/constants/mocks/mock-custom-tutorials.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ export const MOCK_CUSTOM_TUTORIALS_ITEMS: IEnablementAreaItem[] = [
66
label: 'MY TUTORIALS',
77
type: EnablementAreaComponent.Group,
88
_actions: ['create'],
9+
args: {
10+
initialIsOpen: true
11+
},
912
children: [
1013
{
1114
id: '12mfp-rem',

redisinsight/ui/src/slices/tests/workbench/wb-custom-tutorials.spec.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import reducer, {
2828
uploadDataBulkFailed,
2929
uploadDataBulkAction,
3030
defaultItems,
31+
setWbCustomTutorialsState,
3132
} from '../../workbench/wb-custom-tutorials'
3233

3334
let store: typeof mockedStore
@@ -371,6 +372,85 @@ describe('slices', () => {
371372

372373
expect(workbenchCustomTutorialsSelector(rootState)).toEqual(state)
373374
})
375+
376+
describe('setWbCustomTutorialsState', () => {
377+
it('should properly set open state', () => {
378+
// Arrange
379+
const currentState = {
380+
...initialState,
381+
items: [{
382+
...defaultItems[0],
383+
args: {
384+
initialIsOpen: false
385+
},
386+
children: MOCK_TUTORIALS_ITEMS
387+
}]
388+
}
389+
390+
const state = {
391+
...initialState,
392+
items: [{
393+
...defaultItems[0],
394+
args: {
395+
defaultInitialIsOpen: false,
396+
initialIsOpen: true
397+
},
398+
children: MOCK_TUTORIALS_ITEMS
399+
}]
400+
}
401+
402+
// Act
403+
const nextState = reducer(currentState, setWbCustomTutorialsState(true))
404+
405+
// Assert
406+
const rootState = Object.assign(initialStateDefault, {
407+
workbench: {
408+
customTutorials: nextState,
409+
},
410+
})
411+
412+
expect(workbenchCustomTutorialsSelector(rootState)).toEqual(state)
413+
})
414+
415+
it('should properly return open state', () => {
416+
// Arrange
417+
const currentState = {
418+
...initialState,
419+
items: [{
420+
...defaultItems[0],
421+
args: {
422+
defaultInitialIsOpen: false,
423+
initialIsOpen: true
424+
},
425+
children: MOCK_TUTORIALS_ITEMS
426+
}]
427+
}
428+
429+
const state = {
430+
...initialState,
431+
items: [{
432+
...defaultItems[0],
433+
args: {
434+
defaultInitialIsOpen: false,
435+
initialIsOpen: false
436+
},
437+
children: MOCK_TUTORIALS_ITEMS
438+
}]
439+
}
440+
441+
// Act
442+
const nextState = reducer(currentState, setWbCustomTutorialsState())
443+
444+
// Assert
445+
const rootState = Object.assign(initialStateDefault, {
446+
workbench: {
447+
customTutorials: nextState,
448+
},
449+
})
450+
451+
expect(workbenchCustomTutorialsSelector(rootState)).toEqual(state)
452+
})
453+
})
374454
})
375455

376456
// thunks

redisinsight/ui/src/slices/workbench/wb-custom-tutorials.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { createSlice } from '@reduxjs/toolkit'
2-
import { remove } from 'lodash'
1+
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
2+
import { isUndefined, remove } from 'lodash'
33
import { AxiosError } from 'axios'
44
import { ApiEndpoints } from 'uiSrc/constants'
5-
import { getApiErrorMessage, getUrl, isStatusSuccessful, } from 'uiSrc/utils'
5+
import { getApiErrorMessage, getUrl, isStatusSuccessful, Maybe, } from 'uiSrc/utils'
66
import { apiService } from 'uiSrc/services'
77
import {
88
EnablementAreaComponent,
@@ -86,7 +86,19 @@ const workbenchCustomTutorialsSlice = createSlice({
8686
},
8787
uploadDataBulkFailed: (state, { payload }) => {
8888
remove(state.bulkUpload.pathsInProgress, (p) => p === payload)
89-
}
89+
},
90+
setWbCustomTutorialsState: (state, { payload }: PayloadAction<Maybe<boolean>>) => {
91+
if (state.items[0].args) {
92+
const { defaultInitialIsOpen, initialIsOpen } = state.items[0].args
93+
if (isUndefined(payload)) {
94+
state.items[0].args.initialIsOpen = defaultInitialIsOpen ?? initialIsOpen
95+
return
96+
}
97+
98+
state.items[0].args.defaultInitialIsOpen = initialIsOpen
99+
state.items[0].args.initialIsOpen = payload
100+
}
101+
},
90102
}
91103
})
92104

@@ -108,6 +120,7 @@ export const {
108120
uploadDataBulk,
109121
uploadDataBulkSuccess,
110122
uploadDataBulkFailed,
123+
setWbCustomTutorialsState,
111124
} = workbenchCustomTutorialsSlice.actions
112125

113126
// The reducer

tests/e2e/pageObjects/components/explore-tab.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ export class ExploreTab {
5757
* Run code
5858
* @param block Name of the block
5959
*/
60-
async runBlockCode(block: string): Promise<void> {
60+
async runBlockCode(block: string): Promise<void> {
6161
const runButton = Selector(this.runMask.replace(/\$name/g, block));
6262
await t.scrollIntoView(runButton);
6363
await t.click(runButton);
64-
if(await this.tutorialPopoverConfirmRunButton.exists){
64+
if (await this.tutorialPopoverConfirmRunButton.exists) {
6565
await t.click(this.tutorialPopoverConfirmRunButton);
6666
}
6767
}
@@ -138,6 +138,7 @@ export class ExploreTab {
138138
if (await this.closeEnablementPage.exists) {
139139
await t.click(this.closeEnablementPage);
140140
}
141+
await this.toggleMyTutorialPanel();
141142
await t.click(deleteTutorialBtn);
142143
await t.click(this.tutorialDeleteButton);
143144
}
@@ -149,4 +150,15 @@ export class ExploreTab {
149150
getTutorialByName(name: string): Selector {
150151
return Selector('div').withText(name);
151152
}
153+
154+
/**
155+
* Expand/Collapse My tutorial Panel
156+
* @param state State of panel
157+
*/
158+
async toggleMyTutorialPanel(state: boolean = true): Promise<void> {
159+
const currentState = await this.customTutorials.getAttribute('aria-expanded') === 'true';
160+
if (currentState !== state) {
161+
await t.click(this.customTutorials);
162+
}
163+
}
152164
}

tests/e2e/tests/web/regression/insights/import-tutorials.e2e.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ test
7373
const tutorials = await browserPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
7474

7575
await t.expect(tutorials.customTutorials.visible).ok('custom tutorials sections is not visible');
76+
// Verify that user can see "My Tutorials" tab is collapsed by default in tutorials
77+
await t.expect(tutorials.customTutorials.getAttribute('aria-expanded')).eql('false', 'My tutorials not closed by default');
78+
79+
// Expand My tutorials
80+
await tutorials.toggleMyTutorialPanel();
7681
await t.click(tutorials.tutorialOpenUploadButton);
7782
await t.expect(tutorials.tutorialSubmitButton.hasAttribute('disabled')).ok('submit button is not disabled');
7883

@@ -138,6 +143,7 @@ test
138143

139144
await workbenchPage.NavigationHeader.togglePanel(true);
140145
const tutorials = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
146+
await tutorials.toggleMyTutorialPanel();
141147
await t.click(tutorials.tutorialOpenUploadButton);
142148
// Verify that user can upload tutorials using a URL
143149
await t.typeText(tutorials.tutorialLinkField, link);
@@ -199,6 +205,7 @@ test
199205
// Upload custom tutorial
200206
await workbenchPage.NavigationHeader.togglePanel(true);
201207
const tutorials = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
208+
await tutorials.toggleMyTutorialPanel();
202209
await t
203210
.click(tutorials.tutorialOpenUploadButton)
204211
.setFilesToUpload(tutorials.tutorialImport, [zipFilePath])
@@ -269,6 +276,7 @@ test
269276
// Upload custom tutorial
270277
await workbenchPage.NavigationHeader.togglePanel(true);
271278
const tutorials = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
279+
await tutorials.toggleMyTutorialPanel();
272280
await t
273281
.click(tutorials.tutorialOpenUploadButton)
274282
.setFilesToUpload(tutorials.tutorialImport, [zipFilePath])

0 commit comments

Comments
 (0)