Skip to content
This repository has been archived by the owner on Dec 13, 2020. It is now read-only.

Commit

Permalink
Merge pull request #775 from metasfresh/dev-767
Browse files Browse the repository at this point in the history
#767 Notification SockJS client enclosured to service
  • Loading branch information
damianprzygodzki committed May 22, 2017
2 parents 57198b9 + 62e2cb2 commit ed0c7a6
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 94 deletions.
51 changes: 22 additions & 29 deletions src/actions/AppActions.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,32 @@
import * as types from '../constants/ActionTypes'
import axios from 'axios';
import {replace} from 'react-router-redux';
import SockJs from 'sockjs-client';
import Stomp from 'stompjs/lib/stomp.min.js';

export function loginSuccess() {
export function loginSuccess(auth) {
return dispatch => {
localStorage.setItem('isLogged', true);

dispatch(getNotificationsEndpoint()).then(topic => {
let sock = new SockJs(config.WS_URL);
let client = Stomp.Stomp.over(sock);
client.debug = null;

client.connect({}, () => {
client.subscribe(topic.data, msg => {
const notification = JSON.parse(msg.body);

if(notification.eventType === 'Read'){
dispatch(updateNotification(
notification.notification, notification.unreadCount
));
}else if(notification.eventType === 'New'){
dispatch(newNotification(
notification.notification, notification.unreadCount
));
const notif = notification.notification;
if(notif.important){
dispatch(addNotification(
'Important notification', notif.message, 5000,
'primary'
))
}
auth.initNotificationClient(topic, msg => {
const notification = JSON.parse(msg.body);

if(notification.eventType === 'Read'){
dispatch(updateNotification(
notification.notification, notification.unreadCount
));
}else if(notification.eventType === 'New'){
dispatch(newNotification(
notification.notification, notification.unreadCount
));
const notif = notification.notification;
if(notif.important){
dispatch(addNotification(
'Important notification', notif.message, 5000,
'primary'
))
}
});
})
}
});
})

dispatch(getNotifications()).then(response => {
Expand All @@ -46,8 +38,9 @@ export function loginSuccess() {
}
}

export function logoutSuccess() {
export function logoutSuccess(auth) {
return () => {
auth.closeNotificationClient();
localStorage.removeItem('isLogged');
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/app/LoginForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class LoginForm extends Component {
}

handleLogin = () => {
const {dispatch} = this.props;
const {dispatch, auth} = this.props;
const {roleSelect, role} = this.state;

this.setState({
Expand All @@ -85,7 +85,7 @@ class LoginForm extends Component {
if(roleSelect){
return dispatch(loginCompletionRequest(role))
.then(() => {
dispatch(loginSuccess());
dispatch(loginSuccess(auth));
this.handleSuccess();
})
}
Expand Down
122 changes: 65 additions & 57 deletions src/containers/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { getRoutes } from '../routes.js';
import { syncHistoryWithStore, push } from 'react-router-redux';
import { Router, browserHistory } from 'react-router';

import Auth from '../services/Auth';

import Moment from 'moment';

import NotificationHandler
Expand All @@ -29,68 +31,74 @@ import '../assets/css/styles.css';
const store = configureStore(browserHistory);
const history = syncHistoryWithStore(browserHistory, store);

axios.defaults.withCredentials = true;

axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
if(!error.response){
store.dispatch(noConnection(true));
}

/*
* Authorization error
*/
if(error.response.status == 401){
store.dispatch(setProcessSaved());
store.dispatch(logoutSuccess());
store.dispatch(push('/login?redirect=true'));
}else if(error.response.status != 404){
if(localStorage.isLogged){
const errorMessenger = (code) => {
switch(code){
case 500:
return 'Server error';
case 400:
return 'Client error';
}
}
const {
data, status
} = error.response;
export default class App extends Component {
constructor() {
super();

const errorTitle = errorMessenger(status);
this.auth = new Auth();

console.error(data.message);
axios.defaults.withCredentials = true;

// Chart disabled notifications
if(error.response.request.responseURL.includes('silentError=true')){
return;
axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
if(!error.response){
store.dispatch(noConnection(true));
}

store.dispatch(addNotification(
'Error: ' + data.message.split(' ', 4).join(' ') + '...',
data.message, 5000, 'error', errorTitle)
);
}
}
if(error.response.request.responseURL.includes('showError=true')){
const {
data
} = error.response;

store.dispatch(addNotification(
'Error: ' + data.message.split(' ', 4).join(' ') + '...',
data.message, 5000, 'error', '')
);
} else {
return Promise.reject(error);
}
});
/*
* Authorization error
*/
if(error.response.status == 401){
store.dispatch(setProcessSaved());
store.dispatch(logoutSuccess(this.auth));
store.dispatch(push('/login?redirect=true'));
}else if(error.response.status != 404){
if(localStorage.isLogged){
const errorMessenger = (code) => {
switch(code){
case 500:
return 'Server error';
case 400:
return 'Client error';
}
}
const {
data, status
} = error.response;

const errorTitle = errorMessenger(status);

console.error(data.message);

// Chart disabled notifications
if(
error.response.request.responseURL
.includes('silentError=true')
){
return;
}

store.dispatch(addNotification(
'Error: ' + data.message.split(' ', 4).join(' ') +
'...', data.message, 5000, 'error', errorTitle)
);
}
}

export default class App extends Component {
constructor() {
super();
if(error.response.request.responseURL.includes('showError=true')){
const {
data
} = error.response;

store.dispatch(addNotification(
'Error: ' + data.message.split(' ', 4).join(' ') + '...',
data.message, 5000, 'error', '')
);
} else {
return Promise.reject(error);
}
}.bind(this));

store.dispatch(getAvailableLang()).then(response => {
const {defaultValue, values} = response.data;
Expand All @@ -110,7 +118,7 @@ export default class App extends Component {
<NotificationHandler>
<Router
history={history}
routes={getRoutes(store)}
routes={getRoutes(store, this.auth)}
/>
</NotificationHandler>
</Provider>
Expand Down
4 changes: 2 additions & 2 deletions src/containers/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ class Login extends Component {
}

render() {
const {redirect} = this.props;
const {redirect, auth} = this.props;
const isYourBrowserSupported = this.browserSupport('chrome');
return (
<div className="fullscreen">
<div className="login-container">
<LoginForm
redirect={redirect}
{...{redirect, auth}}
/>
{! isYourBrowserSupported &&
<div className="browser-warning">
Expand Down
9 changes: 5 additions & 4 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import {
createWindow
} from './actions/WindowActions';

export const getRoutes = (store) => {
export const getRoutes = (store, auth) => {
const authRequired = (nextState, replace, callback) => {
if( !localStorage.isLogged ){
store.dispatch(localLoginRequest()).then((resp) => {
if(resp.data){
store.dispatch(loginSuccess());
store.dispatch(loginSuccess(auth));
callback(null, nextState.location.pathname);
}else{
//redirect tells that there should be
Expand All @@ -35,14 +35,14 @@ export const getRoutes = (store) => {
}
})
}else{
store.dispatch(loginSuccess());
store.dispatch(loginSuccess(auth));
callback();
}
}

const logout = () => {
store.dispatch(logoutRequest()).then(()=>
store.dispatch(logoutSuccess())
store.dispatch(logoutSuccess(auth))
).then(()=>
store.dispatch(push('/login'))
);
Expand Down Expand Up @@ -79,6 +79,7 @@ export const getRoutes = (store) => {
<Login
redirect={nextState.location.query.redirect}
logged={localStorage.isLogged}
{...{auth}}
/>
} />
<Route path="*" component={NoMatch} />
Expand Down
26 changes: 26 additions & 0 deletions src/services/Auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import SockJs from 'sockjs-client';
import Stomp from 'stompjs/lib/stomp.min.js';

class Auth {
constructor() {
this.notificationClient = null;
}

initNotificationClient = (topic, cb) => {
const sock = new SockJs(config.WS_URL);
this.notificationClient = Stomp.Stomp.over(sock);
this.notificationClient.debug = null;
this.notificationClient.connect({}, () => {
this.notificationClient.connected &&
this.notificationClient.subscribe(topic.data, msg => {
cb && cb(msg);
});
});
}

closeNotificationClient = () => {
this.notificationClient && this.notificationClient.disconnect();
}
}

export default Auth;

0 comments on commit ed0c7a6

Please sign in to comment.