The Problem –
We have three SUSI Web Clients namely
And it’s important to keep the design guidelines in sync across all the clients, StaticAppBar is a component which forms the header of all the pages and thus it is important to keep it uniform in all clients which was clearly missing before. There is also a lot of code duplication of the AppBar component (in accounts app) since it is used on all the pages so our approach will be to prepare a single component and render it on all routes.
Tackling the problem – Since the StaticAppBar component is present on all the clients we simply make the menu items uniform across all the clients and apply a check on those menu items on which are a premium feature or should appear only once the user is logged in.
Building blocks of the StaticAppBar component
- AppBar
- SUSI logo on the left end
- Drop down hamburger menu on the right
Here’s how the JSX for the StaticAppBar component in CMS looks like, it uses an AppBar component from the material-ui library and has several props and styling as per the requirement.
<AppBar className='topAppBar' id='appBar' title={<div id='rightIconButton' ><Link to='/' style={{ float: 'left', marginTop: '-10px',height:'25px',width:'122px' }}> <img src={susiWhite} alt='susi-logo' className='siteTitle' /></Link></div>} style={{ backgroundColor: colors.header, height: '46px', boxShadow: 'none', margin: '0 auto', }} iconStyleRight={{ marginTop: '-2px' }} iconElementRight={<TopRightMenu />} />
TopRightMenu is a function that returns JSX for the hamburger dropdown and is rendered in the AppBar as depicted below. It is a conditional menubar meaning some menu items are only rendered when the user is logged in and thus this helps cover those features which should only be available to logged in users. After that we use a popover component which shows up when the 3 dots or the expander on the top right is clicked. Almost all of the components in material ui has a style prop so styling is easy for the components moreover the workflow for the popover click goes like once the expander is clicked a boolean state variable named showOptions is toggled which in turn toggles the opening or closing state of the Popover as per the open prop.
let TopRightMenu = (props) => ( <div onScroll={this.handleScroll}> <div> {cookies.get('loggedIn') ? (<label style={{color: 'white', fontSize: '16px', verticalAlign:'super'}}> {cookies.get('emailId')} </label>) : (<label> </label>) } <IconMenu {...props} iconButtonElement={ <IconButton iconStyle={{ fill: 'white' }}><MoreVertIcon /></IconButton> } targetOrigin={{ horizontal: 'right', vertical: 'top' }} anchorOrigin={{ horizontal: 'right', vertical: 'top' }} onTouchTap={this.showOptions} > </IconMenu> <Popover {...props} animated={false} style={{ float: 'right', position: 'relative', marginTop: '46px', marginLeft: leftGap }} open={this.state.showOptions} anchorEl={this.state.anchorEl} anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} targetOrigin={{ horizontal: 'right', vertical: 'top' }} onRequestClose={this.closeOptions} > <TopRightMenuItems /> {cookies.get('loggedIn') ? (<MenuItem primaryText='Botbuilder' containerElement={<Link to='/botbuilder' />} rightIcon={<Extension />} />) : null } <MenuItem primaryText='Settings' containerElement={<Link to='/settings' />} rightIcon={<Settings />} /> {cookies.get('loggedIn') ? (<MenuItem primaryText='Logout' containerElement={<Link to='/logout' />} rightIcon={<Exit />} />) : (<MenuItem primaryText='Login' onTouchTap={this.handleLogin} rightIcon={<LoginIcon />} />) } </Popover> </div> </div> );
Handling the conditional display of menu items based on the user session
Some features are to be offered to only those who are logged in and thus we need to display them depending on the user session i.e they should be visible when the user is logged in and hidden when the user is logged out. User state is stored in the browser’s cookies and using that we can achieve the desired result.
{ cookies.get('loggedIn') ? (<MenuItem primaryText="Botbuilder" href="https://skills.susi.ai/botbuilder" rightIcon={<Extension/>}/>): null }
So I hope after going through this blog you have a much more clearer insight to how the StaticAppBar is implemented.