diff --git a/client/src/actions/__tests__/session-actions-test.js b/client/src/actions/__tests__/session-actions-test.js index 642f1fa4..432970a9 100644 --- a/client/src/actions/__tests__/session-actions-test.js +++ b/client/src/actions/__tests__/session-actions-test.js @@ -11,42 +11,55 @@ const SessionActions = requireUnit('actions/session-actions', { }); describe('Session Actions,', function () { - APICallMock.call.returns('API_RESULT'); describe('login action', function () { - it('should return LOGIN with with API_RESULT promise', function () { - APICallMock.call.reset(); + it('should return LOGIN with with a result promise', function () { + APICallMock.call.returns({ + then: function (resolve) { + resolve({ + data: { + userId: 14 + } + }); + } + }); + let loginData = { email: 'SOME_EMAIL', password: 'SOME_PASSWORD', remember: false }; - expect(SessionActions.login(loginData)).to.deep.equal({ - type: 'LOGIN', - payload: 'API_RESULT' - }); - + expect(SessionActions.login(loginData).type).to.equal('LOGIN'); + expect(storeMock.dispatch).to.have.been.calledWithMatch({type: 'USER_DATA'}); expect(APICallMock.call).to.have.been.calledWith({ - path: '/user/login', - data: loginData + path: '/user/get', + data: { + userId: 14 + } }); }); }); describe('autoLogin action', function () { it('should return LOGIN_AUTO with remember data from sessionStore', function () { - APICallMock.call.reset(); + APICallMock.call.returns({ + then: function (resolve) { + resolve({ + data: { + userId: 14 + } + }); + } + }); sessionStoreMock.getRememberData.returns({ token: 'SOME_TOKEN', userId: 'SOME_ID', expiration: 'SOME_EXPIRATION' }); - expect(SessionActions.autoLogin()).to.deep.equal({ - type: 'LOGIN_AUTO', - payload: 'API_RESULT' - }); + expect(SessionActions.autoLogin().type).to.equal('LOGIN_AUTO'); + expect(storeMock.dispatch).to.have.been.calledWithMatch({type: 'USER_DATA'}); expect(APICallMock.call).to.have.been.calledWith({ path: '/user/login', data: { @@ -60,6 +73,7 @@ describe('Session Actions,', function () { describe('logout action', function () { it('should return LOGOUT and call /user/logout', function () { + APICallMock.call.returns('API_RESULT'); APICallMock.call.reset(); expect(SessionActions.logout()).to.deep.equal({ diff --git a/client/src/actions/session-actions.js b/client/src/actions/session-actions.js index f4ca14fc..ed9490b4 100644 --- a/client/src/actions/session-actions.js +++ b/client/src/actions/session-actions.js @@ -9,6 +9,10 @@ export default { payload: API.call({ path: '/user/login', data: loginData + }).then((result) => { + store.dispatch(this.getUserData(result.data.userId)); + + return result; }) }; }, @@ -25,6 +29,10 @@ export default { rememberToken: rememberData.token, isAutomatic: true } + }).then((result) => { + store.dispatch(this.getUserData(result.data.userId)); + + return result; }) }; }, @@ -39,6 +47,18 @@ export default { }; }, + getUserData(userId) { + return { + type: 'USER_DATA', + payload: API.call({ + path: '/user/get', + data: { + userId: userId + } + }) + } + }, + initSession() { return { type: 'CHECK_SESSION', diff --git a/client/src/app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page.js b/client/src/app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page.js index c38befbb..184bf375 100644 --- a/client/src/app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page.js +++ b/client/src/app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page.js @@ -1,90 +1,16 @@ import React from 'react'; +import {connect} from 'react-redux'; + import Table from 'core-components/table'; import Button from 'core-components/button'; -let mockTickets = [ - { - ticketNumber: '445441', - title: 'Problem with installation', - content: 'I had a problem with the installation of the php server', - department: 'Environment Setup', - date: '15 Apr 2016', - file: 'http://www.opensupports.com/some_file.zip', - language: 'en', - unread: true, - closed: false, - author: { - name: 'John Smith', - email: 'john@smith.com' - }, - owner: { - name: 'Steve Jobs' - }, - comments: [ - { - content: 'Do you have apache installed? It generally happens if you dont have apache.', - author: { - name: 'Steve Jobs', - email: 'jobs@steve.com', - staff: true - } - }, - { - content: 'I have already installed apache, but the problem persists', - author: { - name: 'John Smith', - steve: 'john@smith.com', - staff: false - } - } - ] - }, - { - ticketNumber: '87852', - title: 'Lorem ipsum door', - content: 'I had a problem with the installation of the php server', - department: 'Environment Setup', - date: '15 Apr 2016', - file: 'http://www.opensupports.com/some_file.zip', - language: 'en', - unread: false, - closed: false, - author: { - name: 'John Smith', - email: 'john@smith.com' - }, - owner: { - name: 'Steve Jobs' - }, - comments: [ - { - content: 'Do you have apache installed? It generally happens if you dont have apache.', - author: { - name: 'Steve Jobs', - email: 'jobs@steve.com', - staff: true - } - }, - { - content: 'I have already installed apache, but the problem persists', - author: { - name: 'John Smith', - steve: 'john@smith.com', - staff: false - } - } - ] - } -]; - - class DashboardListTicketsPage extends React.Component { static propTypes = { tickets: React.PropTypes.arrayOf(React.PropTypes.object) }; static defaultProps = { - tickets: mockTickets.concat([mockTickets[1], mockTickets[1]]) + tickets: [] }; render() { @@ -135,11 +61,16 @@ class DashboardListTicketsPage extends React.Component { {titleText} ), - department: ticket.department, + department: ticket.department.name, date: ticket.date, highlighted: ticket.unread }; } } -export default DashboardListTicketsPage; + +export default connect((store) => { + return { + tickets: store.session.userTickets + }; +})(DashboardListTicketsPage); diff --git a/client/src/app/main/dashboard/dashboard-menu.js b/client/src/app/main/dashboard/dashboard-menu.js index e0a656b1..a44c470f 100644 --- a/client/src/app/main/dashboard/dashboard-menu.js +++ b/client/src/app/main/dashboard/dashboard-menu.js @@ -1,14 +1,11 @@ import React from 'react'; import _ from 'lodash'; -import Menu from 'core-components/menu'; +import {dispatch} from 'app/store'; +import SessionActions from 'actions/session-actions'; +import i18n from 'lib-app/i18n'; -let dashboardRoutes = [ - { path: '/dashboard', text: 'Ticket List', icon: 'file-text-o' }, - { path: '/dashboard/create-ticket', text: 'Create Ticket', icon: 'plus' }, - { path: '/dashboard/articles', text: 'View Articles', icon: 'book' }, - { path: '/dashboard/edit-profile', text: 'Edit Profile', icon: 'pencil' } -]; +import Menu from 'core-components/menu'; class DashboardMenu extends React.Component { static contextTypes = { @@ -30,14 +27,18 @@ class DashboardMenu extends React.Component { header: 'Dashboard', items: this.getMenuItems(), selectedIndex: this.getSelectedIndex(), - onItemClick: this.goToPathByIndex.bind(this), + onItemClick: this.onItemClick.bind(this), tabbable: true, type: 'secondary' }; } getMenuItems() { - return dashboardRoutes.map(this.getMenuItem.bind(this)); + let items = this.getDashboardRoutes().map(this.getMenuItem.bind(this)); + + items.push(this.getCloseSessionItem()); + + return items; } getMenuItem(item) { @@ -47,14 +48,38 @@ class DashboardMenu extends React.Component { }; } + getCloseSessionItem() { + return { + content: i18n('CLOSE_SESSION'), + icon: 'lock' + } + } + getSelectedIndex() { let pathname = this.props.location.pathname; - return _.findIndex(dashboardRoutes, {path: pathname}); + return _.findIndex(this.getDashboardRoutes(), {path: pathname}); + } + + onItemClick(itemIndex) { + if (itemIndex < this.getDashboardRoutes().length) { + this.goToPathByIndex(itemIndex) + } else { + dispatch(SessionActions.logout()); + } } goToPathByIndex(itemIndex) { - this.context.router.push(dashboardRoutes[itemIndex].path); + this.context.router.push(this.getDashboardRoutes()[itemIndex].path); + } + + getDashboardRoutes() { + return [ + { path: '/dashboard', text: i18n('TICKET_LIST'), icon: 'file-text-o' }, + { path: '/dashboard/create-ticket', text: i18n('CREATE_TICKET'), icon: 'plus' }, + { path: '/dashboard/articles', text: i18n('VIEW_ARTICLES'), icon: 'book' }, + { path: '/dashboard/edit-profile', text: i18n('EDIT_PROFILE'), icon: 'pencil' } + ]; } } diff --git a/client/src/app/main/main-layout-header.js b/client/src/app/main/main-layout-header.js index de7138fe..43bc7e45 100644 --- a/client/src/app/main/main-layout-header.js +++ b/client/src/app/main/main-layout-header.js @@ -34,14 +34,14 @@ class MainLayoutHeader extends React.Component { if (this.props.session.logged) { result = ( -