/*
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 { Link } from 'react-router-dom'
import { observer } from 'mobx-react'
import styled, { css } from 'styled-components'
import autobind from 'autobind-decorator'
import Palette from '../../styleUtils/Palette'
import StyleProps from '../../styleUtils/StyleProps'
import { navigationMenu } from '../../../constants'
import type { User } from '../../../types/User'
import userImage from './images/user.svg'
import userWhiteImage from './images/user-white.svg'
import configLoader from '../../../utils/Config'
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-top: 8px;
`
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(Link)`
font-size: 16px;
color: ${Palette.black};
text-decoration: none;
${props => props.to === '' ? 'pointer-events: none;' : ''}
&:hover {color: ${Palette.primary};}
`
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 {
state = {
showDropdownList: false,
}
itemMouseDown: boolean
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 })
}
@autobind
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'
&& !configLoader.config.disabledPages.find(p => p === 'users') && (!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: 'About Coriolis',
value: 'about',
}, {
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