Confirm logout when pending requests, try to purge offline.outbox
authorAlexandre Segura <mex.zktk@gmail.com>
Thu, 29 Jun 2017 17:02:21 +0200
changeset 107 e6f85e26b08c
parent 106 fffefefed507
child 108 732adc46c8b8
Confirm logout when pending requests, try to purge offline.outbox
client/src/actions/authActions.js
client/src/components/Navbar.js
client/src/constants/actionTypes.js
client/src/reducers/index.js
client/src/reducers/miscReducer.js
--- a/client/src/actions/authActions.js	Thu Jun 29 12:06:48 2017 +0200
+++ b/client/src/actions/authActions.js	Thu Jun 29 17:02:21 2017 +0200
@@ -34,3 +34,8 @@
     group,
   };
 }
+
+
+export const purgeOutbox = () => {
+  return { type: types.OFFLINE_PURGE_OUTBOX }
+}
--- a/client/src/components/Navbar.js	Thu Jun 29 12:06:48 2017 +0200
+++ b/client/src/components/Navbar.js	Thu Jun 29 17:02:21 2017 +0200
@@ -4,33 +4,26 @@
 import { withRouter } from 'react-router';
 import { bindActionCreators } from 'redux';
 // import logo from './logo.svg';
-import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
+import { Navbar, Nav, NavItem, NavDropdown, MenuItem, Modal, Button } from 'react-bootstrap';
 import * as authActions from '../actions/authActions';
 
-const LoginNav = ({isAuthenticated, currentUser, history, authActions}) => {
+const LoginNav = ({isAuthenticated, currentUser, history, authActions, onLogout}) => {
 
   const onClickSettings = (e) => {
     e.preventDefault();
     history.push('/settings');
   }
 
-  const onClickLogout = (e) => {
-    e.preventDefault();
-    authActions.logout();
-    history.push('/');
-  }
-
   const onClickLogin = (e) => {
     e.preventDefault();
     history.push('/login');
   }
 
-
   if (isAuthenticated) {
     return (
       <NavDropdown title={ currentUser.get('username') } id="user-dropdown">
         <MenuItem onClick={onClickSettings}>Settings</MenuItem>
-        <MenuItem onClick={onClickLogout}>Logout</MenuItem>
+        <MenuItem onClick={onLogout}>Logout</MenuItem>
       </NavDropdown>
     );
   }
@@ -49,11 +42,47 @@
 
 class AppNavbar extends Component {
 
+  state = {
+    showModal: false
+  }
+
+  closeModal = () => {
+    this.setState({ showModal: false });
+  }
+
   onClickHome = (e) => {
     e.preventDefault();
     this.props.history.push('/');
   }
 
+  isOutboxEmpty = () => {
+    return this.props.offline.outbox.length === 0;
+  }
+
+  onClickLogout = (e) => {
+    e.preventDefault();
+    const isOutboxEmpty = this.isOutboxEmpty();
+    if (isOutboxEmpty) {
+      this.logout();
+    } else {
+      this.setState({ showModal: true })
+    }
+  }
+
+  confirmLogout = () => {
+    const isOutboxEmpty = this.isOutboxEmpty();
+    if (!isOutboxEmpty) {
+      this.props.authActions.purgeOutbox();
+    }
+    this.logout();
+    this.closeModal();
+  }
+
+  logout = () => {
+    this.props.authActions.logout();
+    this.props.history.push('/');
+  }
+
   onClickSessions = (e) => {
     e.preventDefault();
     this.props.history.push('/sessions');
@@ -74,9 +103,22 @@
           </Nav>
           <Nav pullRight>
             <Online {...this.props} />
-            <LoginNav {...this.props} />
+            <LoginNav {...this.props} onLogout={this.onClickLogout} />
           </Nav>
         </Navbar.Collapse>
+        <Modal show={this.state.showModal} onHide={this.closeModal}>
+          <Modal.Body>
+            <p className="text-center">
+              Some data is not synchronized with server.
+              <br />
+              If you continue, it will be lost.
+            </p>
+          </Modal.Body>
+          <Modal.Footer>
+            <Button bsStyle="primary" onClick={this.confirmLogout}>Confirm</Button>
+            <Button onClick={this.closeModal}>Close</Button>
+          </Modal.Footer>
+        </Modal>
       </Navbar>
     );
   }
--- a/client/src/constants/actionTypes.js	Thu Jun 29 12:06:48 2017 +0200
+++ b/client/src/constants/actionTypes.js	Thu Jun 29 17:02:21 2017 +0200
@@ -17,6 +17,8 @@
 export const AUTH_REGISTER_REQUEST = 'AUTH_REGISTER_REQUEST';
 export const AUTH_REGISTER_ERROR = 'AUTH_REGISTER_ERROR';
 
+export const OFFLINE_PURGE_OUTBOX = 'OFFLINE_PURGE_OUTBOX';
+
 // Used both by login & register
 export const AUTH_LOGIN_SUCCESS = 'AUTH_LOGIN_SUCCESS';
 
--- a/client/src/reducers/index.js	Thu Jun 29 12:06:48 2017 +0200
+++ b/client/src/reducers/index.js	Thu Jun 29 17:02:21 2017 +0200
@@ -5,7 +5,7 @@
 import notes from './notesReducer';
 import { sessions } from './sessionsReducer';
 import { isAuthenticated, currentUser, login, register, token, groups, createGroup } from './authReducer';
-import { autoSubmit } from './miscReducer';
+import { autoSubmit, outbox } from './miscReducer';
 
 const rootReducer = combineReducers({
   sessions,
@@ -18,7 +18,10 @@
   router: routerReducer,
   autoSubmit,
   groups,
-  createGroup
+  createGroup,
+  offline: combineReducers({
+    outbox
+  })
 });
 
 export default rootReducer;
--- a/client/src/reducers/miscReducer.js	Thu Jun 29 12:06:48 2017 +0200
+++ b/client/src/reducers/miscReducer.js	Thu Jun 29 17:02:21 2017 +0200
@@ -9,4 +9,14 @@
   }
 }
 
-
+export const outbox = (state = [], action) => {
+  switch (action.type) {
+    case types.OFFLINE_PURGE_OUTBOX:
+      // FIXME Does not work
+      // Need to find a way to purge outbox
+      // @see https://github.com/jevakallio/redux-offline/issues/68
+      return state;
+    default:
+      return state;
+  }
+}