Ivan - Use ES6 Classes in app components and fix session issues [skip ci]

This commit is contained in:
ivan 2016-08-13 17:23:40 -03:00
parent eaef9b42db
commit 04396db948
20 changed files with 114 additions and 108 deletions

View File

@ -31,7 +31,7 @@ export default {
logout() {
return {
type: 'LOG_OUT',
type: 'LOGOUT',
payload: API.call({
path: '/user/logout',
data: {}
@ -48,7 +48,9 @@ export default {
}).then((result) => {
if (!result.data.sessionActive) {
if (sessionStore.isRememberDataExpired()) {
store.dispatch(this.logout());
store.dispatch({
type: 'LOGOUT_FULFILLED'
});
} else {
store.dispatch(this.autoLogin());
}

View File

@ -1,6 +1,7 @@
import React from 'react';
import _ from 'lodash';
import { connect } from 'react-redux'
import { browserHistory } from 'react-router';
class App extends React.Component {
static contextTypes = {
@ -8,36 +9,12 @@ class App extends React.Component {
location: React.PropTypes.object
};
constructor(props, context) {
super(props, context);
if (_.includes(props.location.pathname, '/app/dashboard') && !props.config.logged) {
context.router.push('/app');
}
if (!_.includes(props.location.pathname, '/app/dashboard') && props.config.logged) {
context.router.push('/app/dashboard');
}
componentWillMount() {
this.redirectIfPathIsNotValid(this.props);
}
componentWillReceiveProps(nextProps) {
const validations = {
languageChanged: nextProps.config.language !== this.props.config.language,
loggedIn: nextProps.session.logged && !this.props.session.logged,
loggedOut: !nextProps.session.logged && this.props.session.logged
};
if (validations.languageChanged) {
this.context.router.push(this.props.location.pathname);
}
if (validations.loggedIn) {
this.context.router.push('/app/dashboard');
}
if (validations.loggedOut) {
this.context.router.push('/app');
}
this.redirectIfPathIsNotValid(nextProps);
}
render() {
@ -47,6 +24,26 @@ class App extends React.Component {
</div>
);
}
redirectIfPathIsNotValid(props) {
const validations = {
languageChanged: props.config.language !== this.props.config.language,
loggedIn: !_.includes(props.location.pathname, '/app/dashboard') && props.session.logged,
loggedOut: _.includes(props.location.pathname, '/app/dashboard') && !props.session.logged
};
if (validations.languageChanged) {
browserHistory.push(props.location.pathname);
}
if (validations.loggedOut) {
browserHistory.push('/app');
}
if (validations.loggedIn) {
browserHistory.push('/app/dashboard');
}
}
}
export default connect((store) => {

View File

@ -1,27 +1,27 @@
const React = require('react');
const {Router, Route, IndexRoute, browserHistory} = require('react-router');
import React from 'react';
import {Router, Route, IndexRoute, browserHistory} from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import store from 'app/store';
const App = require('app/App');
const DemoPage = require('app/demo/components-demo-page');
import App from 'app/App';
import DemoPage from 'app/demo/components-demo-page';
const MainLayout = require('app/main/main-layout');
const MainHomePage = require('app/main/main-home/main-home-page');
const MainSignUpPage = require('app/main/main-signup/main-signup-page');
const MainRecoverPasswordPage = require('app/main/main-recover-password/main-recover-password-page');
import MainLayout from 'app/main/main-layout';
import MainHomePage from 'app/main/main-home/main-home-page';
import MainSignUpPage from 'app/main/main-signup/main-signup-page';
import MainRecoverPasswordPage from 'app/main/main-recover-password/main-recover-password-page';
const DashboardLayout = require('app/main/dashboard/dashboard-layout');
import DashboardLayout from 'app/main/dashboard/dashboard-layout';
const DashboardListTicketsPage = require('app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page');
const DashboardListArticlesPage = require('app/main/dashboard/dashboard-list-articles/dashboard-list-articles-page');
import DashboardListTicketsPage from 'app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page';
import DashboardListArticlesPage from 'app/main/dashboard/dashboard-list-articles/dashboard-list-articles-page';
const DashboardCreateTicketPage = require('app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page');
const DashboardEditProfilePage = require('app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page');
import DashboardCreateTicketPage from 'app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page';
import DashboardEditProfilePage from 'app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page';
const DashboardArticlePage = require('app/main/dashboard/dashboard-article/dashboard-article-page');
const DashboardTicketPage = require('app/main/dashboard/dashboard-ticket/dashboard-ticket-page');
import DashboardArticlePage from 'app/main/dashboard/dashboard-article/dashboard-article-page';
import DashboardTicketPage from 'app/main/dashboard/dashboard-ticket/dashboard-ticket-page';
const history = syncHistoryWithStore(browserHistory, store);

View File

@ -18,7 +18,7 @@ if (noFixtures === 'disabled') {
let renderApplication = function () {
render(<Provider store={store}>{routes}</Provider>, document.getElementById('app'));
};
window.store = store;
store.dispatch(SessionActions.initSession());
let unsubscribe = store.subscribe(() => {

View File

@ -1,6 +1,6 @@
import React from 'react';
const DashboardArticlePage = React.createClass({
class DashboardArticlePage extends React.Component {
render() {
return (
@ -9,6 +9,6 @@ const DashboardArticlePage = React.createClass({
</div>
);
}
});
}
export default DashboardArticlePage;

View File

@ -1,6 +1,6 @@
import React from 'react';
const DashboardCreateTicketPage = React.createClass({
class DashboardCreateTicketPage extends React.Component {
render() {
return (
@ -9,6 +9,6 @@ const DashboardCreateTicketPage = React.createClass({
</div>
);
}
});
}
export default DashboardCreateTicketPage;

View File

@ -1,6 +1,6 @@
import React from 'react';
const DashboardEditProfilePage = React.createClass({
class DashboardEditProfilePage extends React.Component {
render() {
return (
@ -9,6 +9,6 @@ const DashboardEditProfilePage = React.createClass({
</div>
);
}
});
}
export default DashboardEditProfilePage;

View File

@ -3,7 +3,7 @@ import {connect} from 'react-redux';
import DashboardMenu from 'app/main/dashboard/dashboard-menu';
const DashboardLayout = React.createClass({
class DashboardLayout extends React.Component {
render() {
return (this.props.session.logged) ? (
@ -13,7 +13,7 @@ const DashboardLayout = React.createClass({
</div>
) : null;
}
});
}
export default connect((store) => {
return {

View File

@ -1,6 +1,6 @@
import React from 'react';
const DashboardListArticlesPage = React.createClass({
class DashboardListArticlesPage extends React.Component {
render() {
return (
@ -9,6 +9,6 @@ const DashboardListArticlesPage = React.createClass({
</div>
);
}
});
}
export default DashboardListArticlesPage;

View File

@ -1,6 +1,6 @@
import React from 'react';
const DashboardListTicketsPage = React.createClass({
class DashboardListTicketsPage extends React.Component {
render() {
return (
@ -9,6 +9,6 @@ const DashboardListTicketsPage = React.createClass({
</div>
);
}
});
}
export default DashboardListTicketsPage;

View File

@ -10,48 +10,48 @@ let dashboardRoutes = [
{ path: '/app/dashboard/edit-profile', text: 'Edit Profile' }
];
const DashboardMenu = React.createClass({
contextTypes: {
class DashboardMenu extends React.Component {
static contextTypes = {
router: React.PropTypes.object
},
};
propTypes: {
static propTypes = {
location: React.PropTypes.object
},
};
render() {
return (
<Menu {...this.getProps()} />
);
},
}
getProps() {
return {
items: this.getMenuItems(),
selectedIndex: this.getSelectedIndex(),
onItemClick: this.goToPathByIndex
onItemClick: this.goToPathByIndex.bind(this)
};
},
}
getMenuItems: function () {
return dashboardRoutes.map(this.getMenuItem);
},
getMenuItems() {
return dashboardRoutes.map(this.getMenuItem.bind(this));
}
getMenuItem(item) {
return {
content: item.text
};
},
}
getSelectedIndex() {
let pathname = this.props.location.pathname;
return _.findIndex(dashboardRoutes, {path: pathname});
},
}
goToPathByIndex(itemIndex) {
this.context.router.push(dashboardRoutes[itemIndex].path);
}
});
}
export default DashboardMenu;

View File

@ -1,6 +1,6 @@
import React from 'react';
const DashboardTicketPage = React.createClass({
class DashboardTicketPage extends React.Component {
render() {
return (
@ -9,6 +9,6 @@ const DashboardTicketPage = React.createClass({
</div>
);
}
});
}
export default DashboardTicketPage;

View File

@ -1,9 +1,9 @@
const React = require('react');
const classNames = require('classnames');
import React from 'react';
import classNames from 'classnames';
const Widget = require('core-components/widget');
import Widget from 'core-components/widget';
const MainHomePagePortal = React.createClass({
class MainHomePagePortal extends React.Component {
render() {
return (
<Widget className={classNames('main-home-page-portal', this.props.className)}>
@ -11,6 +11,6 @@ const MainHomePagePortal = React.createClass({
</Widget>
);
}
});
}
export default MainHomePagePortal;

View File

@ -3,7 +3,7 @@ import React from 'react';
import MainHomePageLoginWidget from 'app/main/main-home/main-home-page-login-widget';
import MainHomePagePortal from 'app/main/main-home/main-home-page-portal';
const MainHomePage = React.createClass({
class MainHomePage extends React.Component {
render() {
return (
@ -13,6 +13,6 @@ const MainHomePage = React.createClass({
</div>
);
}
});
}
export default MainHomePage;

View File

@ -1,6 +1,6 @@
import React from 'react';
let MainLayoutFooter = React.createClass({
class MainLayoutFooter extends React.Component {
render() {
return (
@ -11,6 +11,6 @@ let MainLayoutFooter = React.createClass({
</div>
);
}
});
}
export default MainLayoutFooter;

View File

@ -36,7 +36,7 @@ class MainLayoutHeader extends React.Component {
result = (
<div className="main-layout-header--login-links">
Welcome, John
<Button type="clean" onClick={this.logout}>(Close Session)</Button>
<Button type="clean" onClick={this.logout.bind(this)}>(Close Session)</Button>
</div>
);
} else {

View File

@ -3,22 +3,19 @@ import React from 'react';
import MainHeader from 'app/main/main-layout-header';
import MainFooter from 'app/main/main-layout-footer';
let MainLayout = React.createClass({
class MainLayout extends React.Component {
render() {
return (
<div className="main-layout">
<MainHeader />
<div className="main-layout--content">
{this.props.children}
</div>
<MainFooter />
</div>
);
}
});
}
export default MainLayout;

View File

@ -90,7 +90,7 @@ class CheckBox extends React.Component {
if (event.keyCode == 32) {
event.preventDefault();
callback(this.handleChange, this.props.onChange)({
callback(this.handleChange.bind(this), this.props.onChange)({
target: {
checked: !this.state.checked
}

View File

@ -5,14 +5,14 @@ module.exports = [
response: function (data) {
let response;
if (data.password === 'valid' || (data.rememberToken === 'aa41efe0a1b3eeb9bf303e4561ff8392' && data.userId === 12)) {
if (data.password === 'valid' || (data.rememberToken === 'aa41efe0a1b3eeb9bf303e4561ff8392' && data.userId == 12)) {
response = {
status: 'success',
data: {
'userId': 12,
'token': 'cc6b4921e6733d6aafe284ec0d7be57e',
'rememberToken': (data.remember) ? 'aa41efe0a1b3eeb9bf303e4561ff8392' : null,
'rememberExpiration': (data.remember) ? 2018 : 0
'rememberExpiration': (data.remember) ? 20180806 : 0
}
};
} else {
@ -42,7 +42,7 @@ module.exports = [
return {
status: 'success',
data: {
sessionActive: true
sessionActive: false
}
};
}

View File

@ -16,12 +16,12 @@ class SessionReducer extends Reducer {
getTypeHandlers() {
return {
'LOGIN_PENDING': this.onLoginPending,
'LOGIN_FULFILLED': this.onLoginCompleted,
'LOGIN_FULFILLED': this.onLoginCompleted.bind(this),
'LOGIN_REJECTED': this.onLoginFailed,
'LOGOUT_FULFILLED': this.onLogout,
'CHECK_SESSION_REJECTED': (state) => { return _.extend({}, state, {initDone: true})},
'SESSION_CHECKED': (state) => { return _.extend({}, state, {initDone: true})},
'LOGIN_AUTO_FULFILLED': this.onAutoLogin,
'SESSION_CHECKED': (state) => { return _.extend({}, state, {initDone: true, logged: true})},
'LOGIN_AUTO_FULFILLED': this.onAutoLogin.bind(this),
'LOGIN_AUTO_REJECTED': this.onAutoLoginFail
};
}
@ -35,16 +35,8 @@ class SessionReducer extends Reducer {
}
onLoginCompleted(state, payload) {
if (payload.data.rememberToken) {
sessionStore.storeRememberData({
token: payload.data.rememberToken,
userId: payload.data.userId,
expiration: payload.data.rememberExpiration
});
} else {
sessionStore.createSession(payload.data.userId, payload.data.token);
}
this.storeLoginResultData(payload.data);
return _.extend({}, state, {
logged: true,
pending: false,
@ -65,19 +57,25 @@ class SessionReducer extends Reducer {
sessionStore.clearRememberData();
return _.extend({}, state, {
initDone: true,
logged: false,
pending: false,
failed: false
});
}
onAutoLogin() {
onAutoLogin(state, payload) {
this.storeLoginResultData(payload.data);
return _.extend({}, state, {
initDone: true
initDone: true,
logged: true,
pending: false,
failed: false
});
}
onAutoLoginFail() {
onAutoLoginFail(state) {
sessionStore.closeSession();
sessionStore.clearRememberData();
@ -85,6 +83,18 @@ class SessionReducer extends Reducer {
initDone: true
});
}
storeLoginResultData(resultData) {
if (resultData.rememberToken) {
sessionStore.storeRememberData({
token: resultData.rememberToken,
userId: resultData.userId,
expiration: resultData.rememberExpiration
});
} else {
sessionStore.createSession(resultData.userId, resultData.token);
}
}
}
export default SessionReducer.getInstance();