/*
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 styled from 'styled-components'
import { observer } from 'mobx-react'
import type { User } from '../../../types/User'
import type { Project } from '../../../types/Project'
import Dropdown from '../../molecules/Dropdown'
import NewItemDropdown from '../../molecules/NewItemDropdown'
import type { ItemType } from '../../molecules/NewItemDropdown'
import NotificationDropdown from '../../molecules/NotificationDropdown'
import UserDropdown from '../../molecules/UserDropdown'
import Modal from '../../molecules/Modal'
import ChooseProvider from '../../organisms/ChooseProvider'
import Endpoint from '../../organisms/Endpoint'
import UserModal from '../../organisms/UserModal'
import ProjectModal from '../../organisms/ProjectModal'
import AboutModal from '../../pages/AboutModal'
import projectStore from '../../../stores/ProjectStore'
import userStore from '../../../stores/UserStore'
import notificationStore from '../../../stores/NotificationStore'
import providerStore from '../../../stores/ProviderStore'
import Palette from '../../styleUtils/Palette'
import StyleProps from '../../styleUtils/StyleProps'
const Wrapper = styled.div`
display: flex;
margin: 48px 0;
align-items: center;
`
const Title = styled.div`
color: ${Palette.black};
font-size: 32px;
font-weight: ${StyleProps.fontWeights.light};
flex-grow: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
`
const Controls = styled.div`
display: flex;
& > div {
margin-left: 16px;
}
`
type Props = {
title: string,
onProjectChange?: (project: Project) => void,
onModalOpen?: () => void,
onModalClose?: () => void,
}
type State = {
showChooseProviderModal: boolean,
showEndpointModal: boolean,
showUserModal: boolean,
showProjectModal: boolean,
showAbout: boolean,
providerType: ?string,
}
@observer
class PageHeader extends React.Component {
state = {
showChooseProviderModal: false,
showEndpointModal: false,
showUserModal: false,
showProjectModal: false,
providerType: null,
showAbout: false,
}
pollTimeout: TimeoutID
stopPolling: boolean
componentWillMount() {
this.stopPolling = false
this.pollData()
}
componentWillUnmount() {
clearTimeout(this.pollTimeout)
this.stopPolling = true
}
getCurrentProject() {
let project = userStore.loggedUser && userStore.loggedUser.project ? userStore.loggedUser.project : null
if (project) {
return projectStore.projects.find(p => p.id === project.id)
}
return null
}
handleUserItemClick(item: { value: string }) {
switch (item.value) {
case 'about':
this.setState({ showAbout: true })
if (this.props.onModalOpen) {
this.props.onModalOpen()
}
return
case 'signout':
userStore.logout()
break
default:
}
}
handleNewItem(item: ItemType) {
switch (item.value) {
case 'endpoint':
providerStore.loadProviders()
if (this.props.onModalOpen) {
this.props.onModalOpen()
}
this.setState({ showChooseProviderModal: true })
break
case 'user':
projectStore.getProjects()
if (this.props.onModalOpen) {
this.props.onModalOpen()
}
this.setState({ showUserModal: true })
break
case 'project':
if (this.props.onModalOpen) {
this.props.onModalOpen()
}
this.setState({ showProjectModal: true })
break
default:
}
}
handleNotificationsClose() {
notificationStore.saveSeen()
}
handleCloseChooseProviderModal() {
if (this.props.onModalClose) {
this.props.onModalClose()
}
this.setState({ showChooseProviderModal: false })
}
handleProviderClick(providerType: string) {
this.setState({
showChooseProviderModal: false,
showEndpointModal: true,
providerType,
})
}
handleCloseEndpointModal() {
if (this.props.onModalClose) {
this.props.onModalClose()
}
this.setState({ showEndpointModal: false })
}
handleBackEndpointModal(options?: { autoClose?: boolean }) {
this.setState({ showChooseProviderModal: !options || !options.autoClose, showEndpointModal: false })
}
async handleProjectChange(project: Project) {
await userStore.switchProject(project.id)
projectStore.getProjects()
notificationStore.loadData()
if (this.props.onProjectChange) {
this.props.onProjectChange(project)
}
}
handleUserModalClose() {
if (this.props.onModalClose) {
this.props.onModalClose()
}
this.setState({ showUserModal: false })
}
async handleUserUpdateClick(user: User) {
await userStore.add(user)
if (this.props.onModalClose) {
this.props.onModalClose()
}
this.setState({ showUserModal: false })
}
handleProjectModalClose() {
if (this.props.onModalClose) {
this.props.onModalClose()
}
this.setState({ showProjectModal: false })
}
async handleProjectModalUpdateClick(project: Project) {
await projectStore.add(project)
if (this.props.onModalClose) {
this.props.onModalClose()
}
this.setState({ showProjectModal: false })
}
async pollData() {
if (
this.stopPolling ||
this.state.showChooseProviderModal ||
this.state.showEndpointModal ||
this.state.showProjectModal ||
this.state.showUserModal ||
this.state.showAbout
) {
return
}
await notificationStore.loadData()
this.pollTimeout = setTimeout(() => { this.pollData() }, 5000)
}
render() {
return (
{this.props.title}
{ this.handleProjectChange(project) }}
noItemsMessage="Loading..."
labelField="name"
/>
{ this.handleNewItem(item) }} />
this.handleNotificationsClose()}
/>
{ this.handleUserItemClick(item) }} />
{ this.handleCloseChooseProviderModal() }}
>
{ this.handleCloseChooseProviderModal() }}
providers={providerStore.providerNames}
loading={providerStore.providersLoading}
onProviderClick={providerName => { this.handleProviderClick(providerName) }}
/>
{ this.handleCloseEndpointModal() }}
>
{ this.handleBackEndpointModal(options) }}
/>
{this.state.showUserModal ? (
{ this.handleUserModalClose() }}
onUpdateClick={user => { this.handleUserUpdateClick(user) }}
/>
) : null}
{this.state.showProjectModal ? (
{ this.handleProjectModalClose() }}
onUpdateClick={project => { this.handleProjectModalUpdateClick(project) }}
/>
) : null}
{this.state.showAbout ? (
{
this.setState({ showAbout: false })
if (this.props.onModalClose) {
this.props.onModalClose()
}
}}
/>
) : null}
)
}
}
export default PageHeader