UNPKG

optimizely-oui

Version:

Optimizely's Component Library.

209 lines (196 loc) 7.92 kB
/** * Main component of Current User Menu to manage Links, * Profile Pic and Account Switcher */ import React from "react"; import PropTypes from "prop-types"; import classNames from "classnames"; import BlockList from "../../BlockList"; import Dropdown from "../../Dropdown"; import Link from "../../Link"; import OverlayWrapper from "../../OverlayWrapper"; import Popover from "../../Popover"; import Button from "../../Button"; import AccountSwitcher from "./AccountSwitcher"; import Avatar from "../../Avatar"; class CurrentUserMenu extends React.Component { static propTypes = { /** Account Settings Url */ accountSettingsUrl: PropTypes.string.isRequired, /** Function Called to Switch Account */ accountSwitcherHandler: PropTypes.func.isRequired, /** An array of elements containing the following account data * text: String * url: String * description: String * isCurrent: Bool */ accountSwitcherItems: PropTypes.arrayOf( PropTypes.shape({ text: PropTypes.string.isRequired, description: PropTypes.string.isRequired, url: PropTypes.string.isRequired, isCurrent: PropTypes.bool.isRequired, }) ).isRequired, /** True if Navbar is Open, False if collapsed */ isOpen: PropTypes.bool, /** Account Log Out Url */ logoutUrl: PropTypes.string.isRequired, /** Function called when Emulate is clicked */ onEmulateClick: PropTypes.func.isRequired, /** Account Profile Avatar Url */ profileAvatarUrl: PropTypes.string, /** Account Profile Url */ profileUrl: PropTypes.string.isRequired, /** Show Emulate Link */ showEmulate: PropTypes.bool, /** Account User name to display */ userName: PropTypes.string.isRequired, }; static defaultProps = { isOpen: true, showEmulate: false, }; renderActivator = ({ buttonRef, onClick, onBlur }) => { const { userName } = this.props; return ( <div ref={buttonRef} onClick={onClick} onBlur={onBlur} data-test-section="account-switcher-dropdown-activator" title={userName} className={classNames("link--reverse", "micro", "flex", "flex-align--center")} > <span className="display--block truncate" data-test-section="nav-bar-user-name"> {userName} </span> <div className="flex--1 push-half--left"> <span className="oui-arrow-inline--down oui-arrow-inline--small vertical-align--middle" /> </div> </div> ); }; renderEmulate = () => { const { isOpen, onEmulateClick } = this.props; return ( <li className={classNames({ "root-nav__faded__link truncate": isOpen, "soft-half--sides": !isOpen, })} > <Button onClick={onEmulateClick} style="unstyled" testSection="nav-bar-close-emulate"> <span className="admin--color">Emulate</span> </Button> </li> ); }; renderLinks = () => { const { isOpen, accountSettingsUrl, profileUrl, logoutUrl } = this.props; const linkClass = isOpen ? "root-nav__faded__link truncate" : "soft-half--sides"; const linkStyle = isOpen ? "reverse" : "default"; return ( <React.Fragment> <li className={linkClass}> <Link href={accountSettingsUrl} style={linkStyle}> Account Settings </Link> </li> <li className={linkClass}> <Link href={profileUrl} style={linkStyle}> Profile </Link> </li> <li className={linkClass}> <Link href={logoutUrl} style={linkStyle}> Log Out </Link> </li> </React.Fragment> ); }; renderCurrentUserMenu = () => { const { userName, profileAvatarUrl, accountSwitcherItems, showEmulate, accountSwitcherHandler } = this.props; const shouldShowAccountList = accountSwitcherItems.length > 1; return [ <Avatar key="profile-pic-wrapper" isEmulating={showEmulate} testSection="profile-pic-wrapper-nav-open" size="small" imageUrl={profileAvatarUrl} />, <ul className="push--left flex--1" key="current-user-links"> {shouldShowAccountList && ( <li> <Dropdown placement="right-start" renderActivator={this.renderActivator}> <Dropdown.Contents direction="up" minWidth="250px"> <div data-test-section="account-switcher-dropdown-content"> <BlockList> <AccountSwitcher accountSwitcherItems={accountSwitcherItems} accountSwitcherHandler={accountSwitcherHandler} /> </BlockList> </div> </Dropdown.Contents> </Dropdown> </li> )} {!shouldShowAccountList && ( <div className="display--block truncate" data-test-section="nav-bar-user-name"> {userName} </div> )} {showEmulate && this.renderEmulate()} {this.renderLinks()} </ul>, ]; }; renderCollapsedCurrentUserMenu = () => { const { profileAvatarUrl, accountSwitcherItems, showEmulate, accountSwitcherHandler } = this.props; return ( <OverlayWrapper horizontalAttachment="left" horizontalTargetAttachment="right" verticalAttachment="top" verticalTargetAttachment="top" shouldHideOnClick={true} testSection="account-switcher-popover" overlay={ <Popover padding="hard" testSection="navbar-account-switcher-popover-content"> <BlockList> <AccountSwitcher accountSwitcherItems={accountSwitcherItems} accountSwitcherHandler={accountSwitcherHandler} /> </BlockList> <ul className="soft"> {showEmulate && this.renderEmulate()} {this.renderLinks()} </ul> </Popover> } > <Avatar imageUrl={profileAvatarUrl} isEmulating={showEmulate} size="small" testSection="profile-pic-wrapper-nav-close" /> </OverlayWrapper> ); }; render() { const { isOpen } = this.props; return ( <div> <div className="root-nav__user root-nav__link root-nav__link--tertiary"> {isOpen ? this.renderCurrentUserMenu() : this.renderCollapsedCurrentUserMenu()} </div> </div> ); } } export default CurrentUserMenu;