client/src/components/Navbar.js
changeset 129 d48946d164c6
parent 107 e6f85e26b08c
child 130 78246db1cbac
equal deleted inserted replaced
128:34a75bd8d0b9 129:d48946d164c6
     4 import { withRouter } from 'react-router';
     4 import { withRouter } from 'react-router';
     5 import { bindActionCreators } from 'redux';
     5 import { bindActionCreators } from 'redux';
     6 // import logo from './logo.svg';
     6 // import logo from './logo.svg';
     7 import { Navbar, Nav, NavItem, NavDropdown, MenuItem, Modal, Button } from 'react-bootstrap';
     7 import { Navbar, Nav, NavItem, NavDropdown, MenuItem, Modal, Button } from 'react-bootstrap';
     8 import * as authActions from '../actions/authActions';
     8 import * as authActions from '../actions/authActions';
       
     9 import { forceSync } from '../actions/networkActions';
       
    10 import { ActionEnum } from '../constants';
     9 
    11 
    10 const LoginNav = ({isAuthenticated, currentUser, history, authActions, onLogout}) => {
    12 const LoginNav = ({isAuthenticated, currentUser, history, authActions, onLogout}) => {
    11 
    13 
    12   const onClickSettings = (e) => {
    14   const onClickSettings = (e) => {
    13     e.preventDefault();
    15     e.preventDefault();
    30   return (
    32   return (
    31     <NavItem onClick={onClickLogin} href="/login">Login</NavItem>
    33     <NavItem onClick={onClickLogin} href="/login">Login</NavItem>
    32   );
    34   );
    33 }
    35 }
    34 
    36 
    35 const Online = ({ offline }) => {
    37 const Online = ({ online }) => {
    36   return (
    38   return (
    37     <NavItem>
    39     <NavItem>
    38       <span className="material-icons" style={{ color: offline.online ? '#2ECC71' : '#E74C3C' }}>signal_wifi_4_bar</span>
    40       <span className="material-icons" style={{ color: online ? '#2ECC71' : '#E74C3C' }}>signal_wifi_4_bar</span>
       
    41     </NavItem>
       
    42   )
       
    43 }
       
    44 
       
    45 const SyncButton = ({ onSyncClick, isSynchronizing }) => {
       
    46   return (
       
    47     <NavItem onClick={onSyncClick}>
       
    48       Sync
       
    49       {isSynchronizing && <span className="material-icons">&#xE627;</span>}
    39     </NavItem>
    50     </NavItem>
    40   )
    51   )
    41 }
    52 }
    42 
    53 
    43 class AppNavbar extends Component {
    54 class AppNavbar extends Component {
    53   onClickHome = (e) => {
    64   onClickHome = (e) => {
    54     e.preventDefault();
    65     e.preventDefault();
    55     this.props.history.push('/');
    66     this.props.history.push('/');
    56   }
    67   }
    57 
    68 
    58   isOutboxEmpty = () => {
    69   isSynchronized = () => {
    59     return this.props.offline.outbox.length === 0;
    70     return this.props.isSynchronized;
    60   }
    71   }
    61 
    72 
    62   onClickLogout = (e) => {
    73   onClickLogout = (e) => {
    63     e.preventDefault();
    74     e.preventDefault();
    64     const isOutboxEmpty = this.isOutboxEmpty();
    75     const isSynchronized = this.isSynchronized();
    65     if (isOutboxEmpty) {
    76     if (isSynchronized) {
    66       this.logout();
    77       this.logout();
    67     } else {
    78     } else {
    68       this.setState({ showModal: true })
    79       this.setState({ showModal: true })
    69     }
    80     }
    70   }
    81   }
    71 
    82 
    72   confirmLogout = () => {
    83   confirmLogout = () => {
    73     const isOutboxEmpty = this.isOutboxEmpty();
    84     const isSynchronized = this.isSynchronized();
    74     if (!isOutboxEmpty) {
    85     if (!isSynchronized) {
    75       this.props.authActions.purgeOutbox();
    86       this.props.authActions.resetAll();
    76     }
    87     }
    77     this.logout();
    88     this.logout();
    78     this.closeModal();
    89     this.closeModal();
    79   }
    90   }
    80 
    91 
    84   }
    95   }
    85 
    96 
    86   onClickSessions = (e) => {
    97   onClickSessions = (e) => {
    87     e.preventDefault();
    98     e.preventDefault();
    88     this.props.history.push('/sessions');
    99     this.props.history.push('/sessions');
       
   100   }
       
   101 
       
   102   onSyncClick = (e) => {
       
   103     e.preventDefault();
       
   104     this.props.networkActions.forceSync();
    89   }
   105   }
    90 
   106 
    91   render() {
   107   render() {
    92     return (
   108     return (
    93       <Navbar fluid inverse fixedTop>
   109       <Navbar fluid inverse fixedTop>
   100         <Navbar.Collapse>
   116         <Navbar.Collapse>
   101           <Nav>
   117           <Nav>
   102             <NavItem onClick={this.onClickSessions} href="/sessions">Sessions</NavItem>
   118             <NavItem onClick={this.onClickSessions} href="/sessions">Sessions</NavItem>
   103           </Nav>
   119           </Nav>
   104           <Nav pullRight>
   120           <Nav pullRight>
       
   121             <SyncButton onSyncClick={this.onSyncClick} isSynchronizing={this.props.isSynchronizing}/>
   105             <Online {...this.props} />
   122             <Online {...this.props} />
   106             <LoginNav {...this.props} onLogout={this.onClickLogout} />
   123             <LoginNav {...this.props} onLogout={this.onClickLogout} />
   107           </Nav>
   124           </Nav>
   108         </Navbar.Collapse>
   125         </Navbar.Collapse>
   109         <Modal show={this.state.showModal} onHide={this.closeModal}>
   126         <Modal show={this.state.showModal} onHide={this.closeModal}>
   128   isAuthenticated: PropTypes.bool.isRequired
   145   isAuthenticated: PropTypes.bool.isRequired
   129 };
   146 };
   130 
   147 
   131 function mapStateToProps(state, props) {
   148 function mapStateToProps(state, props) {
   132   return {
   149   return {
   133     isAuthenticated: state['isAuthenticated'],
   150     isAuthenticated: state.getIn(['authStatus', 'isAuthenticated']),
   134     currentUser: state['currentUser'],
   151     currentUser: state.getIn(['authStatus', 'currentUser']),
   135     offline: state['offline']
   152     online: state.getIn(['status', 'online']),
       
   153     isSynchronizing: state.getIn(['status', 'isSynchronizing']),
       
   154     isSynchronized: state.get('notes').every((n) => n.get('action')===ActionEnum.NONE) &&
       
   155       state.get('sessions').every((n) => n.get('action')===ActionEnum.NONE)
   136   };
   156   };
   137 }
   157 }
   138 
   158 
   139 function mapDispatchToProps(dispatch) {
   159 function mapDispatchToProps(dispatch) {
   140   return {
   160   return {
   141     authActions: bindActionCreators(authActions, dispatch),
   161     authActions: bindActionCreators(authActions, dispatch),
       
   162     networkActions: bindActionCreators({ forceSync }, dispatch)
   142   }
   163   }
   143 }
   164 }
   144 
   165 
   145 export default connect(mapStateToProps, mapDispatchToProps)(withRouter(AppNavbar));
   166 export default connect(mapStateToProps, mapDispatchToProps)(withRouter(AppNavbar));