11import { css , cx } from '@emotion/css' ;
22import { FocusScope } from '@react-aria/focus' ;
3+ import { useTour } from '@reactour/tour' ;
34import { cloneDeep } from 'lodash' ;
4- import React , { useState } from 'react' ;
5+ import React , { useEffect , useState } from 'react' ;
56import { useDispatch , useSelector } from 'react-redux' ;
67import { useLocation } from 'react-router-dom' ;
78
@@ -11,6 +12,7 @@ import { Icon, useTheme2 } from '@grafana/ui';
1112import { updateNavIndex } from 'app/core/actions' ;
1213import { Branding } from 'app/core/components/Branding/Branding' ;
1314import { getKioskMode } from 'app/core/navigation/kiosk' ;
15+ import { initialState , updateNavTree } from 'app/core/reducers/navBarTree' ;
1416import { getPerconaSettings , getPerconaUser } from 'app/percona/shared/core/selectors' ;
1517import { KioskMode , StoreState } from 'app/types' ;
1618
@@ -39,9 +41,10 @@ import {
3941 buildIntegratedAlertingMenuItem ,
4042 buildInventoryAndSettings ,
4143 enrichConfigItems ,
44+ enrichWithClickDispatch ,
4245 enrichWithInteractionTracking ,
4346 getActiveItem ,
44- isMatchOrChildMatch ,
47+ isMatchOrInnerMatch ,
4548 isSearchActive ,
4649 SEARCH_ITEM_ID ,
4750} from './utils' ;
@@ -54,16 +57,18 @@ export const NavBar = React.memo(() => {
5457 const navBarTree = useSelector ( ( state : StoreState ) => state . navBarTree ) ;
5558 const theme = useTheme2 ( ) ;
5659 const styles = getStyles ( theme ) ;
60+ const dispatchOffset = theme . transitions . duration . standard ;
5761 const location = useLocation ( ) ;
5862 const dispatch = useDispatch ( ) ;
5963 const kiosk = getKioskMode ( ) ;
6064 const { result } = useSelector ( getPerconaSettings ) ;
61- const { sttEnabled , alertingEnabled, dbaasEnabled , backupEnabled } = result ! ;
65+ const { alertingEnabled } = result ! ;
6266 const { isPlatformUser, isAuthorized } = useSelector ( getPerconaUser ) ;
6367 const [ showSwitcherModal , setShowSwitcherModal ] = useState ( false ) ;
6468 const [ menuOpen , setMenuOpen ] = useState ( false ) ;
6569 const [ menuAnimationInProgress , setMenuAnimationInProgress ] = useState ( false ) ;
66- const [ menuIdOpen , setMenuIdOpen ] = useState < string | undefined > ( undefined ) ;
70+ const [ menuIdOpen , setMenuIdOpen ] = useState < string | undefined > ( ) ;
71+ const { isOpen : isTourOpen } = useTour ( ) ;
6772
6873 const toggleSwitcherModal = ( ) => {
6974 setShowSwitcherModal ( ! showSwitcherModal ) ;
@@ -94,15 +99,19 @@ export const NavBar = React.memo(() => {
9499
95100 const coreItems = navTree
96101 . filter ( ( item ) => item . section === NavSection . Core )
97- . map ( ( item ) => enrichWithInteractionTracking ( item , menuOpen ) ) ;
102+ . map ( ( item ) => enrichWithInteractionTracking ( item , menuOpen ) )
103+ . map ( ( item ) => enrichWithClickDispatch ( item , dispatch , dispatchOffset ) ) ;
98104 const pluginItems = navTree
99105 . filter ( ( item ) => item . section === NavSection . Plugin )
100- . map ( ( item ) => enrichWithInteractionTracking ( item , menuOpen ) ) ;
106+ . map ( ( item ) => enrichWithInteractionTracking ( item , menuOpen ) )
107+ . map ( ( item ) => enrichWithClickDispatch ( item , dispatch , dispatchOffset ) ) ;
101108 const configItems = enrichConfigItems (
102109 navTree . filter ( ( item ) => item . section === NavSection . Config ) ,
103110 location ,
104111 toggleSwitcherModal
105- ) . map ( ( item ) => enrichWithInteractionTracking ( item , menuOpen ) ) ;
112+ )
113+ . map ( ( item ) => enrichWithInteractionTracking ( item , menuOpen ) )
114+ . map ( ( item ) => enrichWithClickDispatch ( item , dispatch , dispatchOffset ) ) ;
106115
107116 const activeItem = isSearchActive ( location ) ? searchItem : getActiveItem ( navTree , location . pathname ) ;
108117
@@ -120,32 +129,42 @@ export const NavBar = React.memo(() => {
120129 dispatch ( updateNavIndex ( PMM_ENVIRONMENT_OVERVIEW_PAGE ) ) ;
121130
122131 // @PERCONA
123- if ( isPlatformUser ) {
124- coreItems . push ( PMM_ENTITLEMENTS_PAGE ) ;
125- coreItems . push ( PMM_TICKETS_PAGE ) ;
126- coreItems . push ( PMM_ENVIRONMENT_OVERVIEW_PAGE ) ;
127- }
132+ useEffect ( ( ) => {
133+ const updatedNavTree = cloneDeep ( initialState ) ;
128134
129- // @PERCONA
130- if ( isAuthorized ) {
131- buildInventoryAndSettings ( configItems ) ;
135+ const { sttEnabled, alertingEnabled, dbaasEnabled, backupEnabled } = result ! ;
132136
133- if ( alertingEnabled ) {
134- buildIntegratedAlertingMenuItem ( coreItems ) ;
137+ // @PERCONA
138+ if ( isPlatformUser ) {
139+ updatedNavTree . push ( PMM_ENTITLEMENTS_PAGE ) ;
140+ updatedNavTree . push ( PMM_TICKETS_PAGE ) ;
141+ updatedNavTree . push ( PMM_ENVIRONMENT_OVERVIEW_PAGE ) ;
135142 }
136143
137- if ( sttEnabled ) {
138- coreItems . push ( PMM_STT_PAGE ) ;
139- }
144+ // @PERCONA
145+ if ( isAuthorized ) {
146+ buildInventoryAndSettings ( updatedNavTree ) ;
140147
141- if ( dbaasEnabled ) {
142- coreItems . push ( PMM_DBAAS_PAGE ) ;
143- }
148+ if ( alertingEnabled ) {
149+ buildIntegratedAlertingMenuItem ( updatedNavTree ) ;
150+ }
144151
145- if ( backupEnabled ) {
146- coreItems . push ( PMM_BACKUP_PAGE ) ;
152+ if ( sttEnabled ) {
153+ updatedNavTree . push ( PMM_STT_PAGE ) ;
154+ }
155+
156+ if ( dbaasEnabled ) {
157+ updatedNavTree . push ( PMM_DBAAS_PAGE ) ;
158+ }
159+
160+ if ( backupEnabled ) {
161+ updatedNavTree . push ( PMM_BACKUP_PAGE ) ;
162+ }
147163 }
148- }
164+
165+ dispatch ( updateNavTree ( { items : updatedNavTree } ) ) ;
166+ // eslint-disable-next-line react-hooks/exhaustive-deps
167+ } , [ result , isAuthorized , isPlatformUser ] ) ;
149168
150169 if ( kiosk !== KioskMode . Off ) {
151170 return null ;
@@ -155,7 +174,8 @@ export const NavBar = React.memo(() => {
155174 < nav className = { cx ( styles . sidemenu , 'sidemenu' ) } data-testid = "sidemenu" aria-label = "Main menu" >
156175 < NavBarContext . Provider
157176 value = { {
158- menuIdOpen : menuIdOpen ,
177+ // Show MySQL item during onboarding tour
178+ menuIdOpen : isTourOpen ? 'mysql' : menuIdOpen ,
159179 setMenuIdOpen : setMenuIdOpen ,
160180 } }
161181 >
@@ -192,7 +212,7 @@ export const NavBar = React.memo(() => {
192212 { coreItems . map ( ( link , index ) => (
193213 < NavBarItem
194214 key = { `${ link . id } -${ index } ` }
195- isActive = { isMatchOrChildMatch ( link , activeItem ) }
215+ isActive = { isMatchOrInnerMatch ( link , activeItem ) }
196216 link = { { ...link , subTitle : undefined } }
197217 />
198218 ) ) }
@@ -201,15 +221,15 @@ export const NavBar = React.memo(() => {
201221 pluginItems . map ( ( link , index ) => (
202222 < NavBarItem
203223 key = { `${ link . id } -${ index } ` }
204- isActive = { isMatchOrChildMatch ( link , activeItem ) }
224+ isActive = { isMatchOrInnerMatch ( link , activeItem ) }
205225 link = { link }
206226 />
207227 ) ) }
208228
209229 { configItems . map ( ( link , index ) => (
210230 < NavBarItem
211231 key = { `${ link . id } -${ index } ` }
212- isActive = { isMatchOrChildMatch ( link , activeItem ) }
232+ isActive = { isMatchOrInnerMatch ( link , activeItem ) }
213233 reverseMenuDirection
214234 link = { link }
215235 className = { cx ( { [ styles . verticalSpacer ] : index === 0 } ) }
0 commit comments