/* 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