/*
Copyright (C) 2017 Cloudbase Solutions SRL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
// @flow
import React from 'react'
import { observer } from 'mobx-react'
import styled, { css } from 'styled-components'
import Palette from '../../styleUtils/Palette'
import StyleProps from '../../styleUtils/StyleProps'
import { navigationMenu } from '../../../config'
import type { User } from '../../../types/User'
import userImage from './images/user.svg'
import userWhiteImage from './images/user-white.svg'
const Wrapper = styled.div`
position: relative;
`
const Icon = styled.div`
position: relative;
cursor: pointer;
width: 32px;
height: 32px;
transition: all ${StyleProps.animations.swift};
background: url('${props => props.white ? userWhiteImage : userImage}') no-repeat center;
&:hover {
opacity: 0.8;
}
`
const List = styled.div`
background: ${Palette.grayscale[1]};
border-radius: ${StyleProps.borderRadius};
position: absolute;
right: 0;
top: 45px;
padding: 16px;
display: flex;
flex-direction: column;
z-index: 10;
`
const ListItem = styled.div`
padding: 8px 0;
&:last-child {
padding-bottom: 0;
}
`
const Label = styled.div`
display: inline-block;
white-space: nowrap;
${props => props.selectable ? css`
cursor: pointer;
&:hover {
color: ${Palette.primary};
}
` : ''}
`
const ListHeader = styled.div`
position: relative;
&:after {
content: ' ';
position: absolute;
width: 10px;
height: 10px;
background: ${Palette.grayscale[1]};
border: 1px solid ${Palette.grayscale[1]};
border-color: transparent transparent ${Palette.grayscale[1]} ${Palette.grayscale[1]};
transform: rotate(135deg);
right: -6px;
top: -22px;
transition: all ${StyleProps.animations.swift};
}
`
const Username = styled.a`
font-size: 16px;
color: ${Palette.black};
text-decoration: none;
&:hover {
color: ${props => props.href ? Palette.primary : 'inherit'};
}
`
const Email = styled.div`
font-size: 10px;
color: ${Palette.grayscale[4]};
margin-top: 8px;
padding-bottom: 8px;
border-bottom: 1px solid ${Palette.grayscale[3]};
`
type DictItem = { label: string, value: string }
type Props = {
onItemClick: (item: DictItem) => void,
user: ?User,
white?: boolean,
}
type State = {
showDropdownList: boolean,
}
@observer
class UserDropdown extends React.Component {
itemMouseDown: boolean
constructor() {
super()
this.state = {
showDropdownList: false,
}
// $FlowIssue
this.handlePageClick = this.handlePageClick.bind(this)
}
componentDidMount() {
window.addEventListener('mousedown', this.handlePageClick, false)
}
componentWillUnmount() {
window.removeEventListener('mousedown', this.handlePageClick, false)
}
handleItemClick(item: DictItem) {
if (this.props.onItemClick) {
this.props.onItemClick(item)
}
this.setState({ showDropdownList: false })
}
handlePageClick() {
if (!this.itemMouseDown) {
this.setState({ showDropdownList: false })
}
}
handleButtonClick() {
this.setState({ showDropdownList: !this.state.showDropdownList })
}
renderNoUser() {
if (this.props.user) {
return null
}
return
}
renderListHeader() {
if (!this.props.user) {
return null
}
let href: ?string
let isAdmin = this.props.user.isAdmin
if (isAdmin && navigationMenu.find(m => m.value === 'users' && !m.disabled && (!m.requiresAdmin || isAdmin))) {
href = `#/user/${this.props.user.id}`
}
return (
{ this.itemMouseDown = true }}
onMouseUp={() => { this.itemMouseDown = false }}
>
{this.props.user.name}
{this.props.user.email}
)
}
renderList() {
if (!this.state.showDropdownList) {
return null
}
let items = [{
label: 'Sign Out',
value: 'signout',
}]
let list = (
{this.renderListHeader()}
{this.renderNoUser()}
{this.props.user ? items.map(item => {
return (
{ this.itemMouseDown = true }}
onMouseUp={() => { this.itemMouseDown = false }}
>
)
}) : null}
)
return list
}
render() {
return (
{ this.itemMouseDown = true }}
onMouseUp={() => { this.itemMouseDown = false }}
onClick={() => this.handleButtonClick()}
white={this.props.white}
data-test-id="userDropdown-button"
/>
{this.renderList()}
)
}
}
export default UserDropdown