diff --git a/client/src/actions/admin-data-actions.js b/client/src/actions/admin-data-actions.js index 624f0b82..f9ac73f7 100644 --- a/client/src/actions/admin-data-actions.js +++ b/client/src/actions/admin-data-actions.js @@ -10,5 +10,35 @@ export default { data: {} }) }; + }, + + retrieveMyTickets() { + return { + type: 'MY_TICKETS', + payload: API.call({ + path: '/staff/get-tickets', + data: {} + }) + }; + }, + + retrieveNewTickets() { + return { + type: 'NEW_TICKETS', + payload: API.call({ + path: '/staff/get-new-tickets', + data: {} + }) + }; + }, + + retrieveAllTickets() { + return { + type: 'ALL_TICKETS', + payload: API.call({ + path: '/staff/get-all-tickets', + data: {} + }) + }; } }; \ No newline at end of file diff --git a/client/src/app-components/__tests__/ticket-list-test.js b/client/src/app-components/__tests__/ticket-list-test.js new file mode 100644 index 00000000..8e591a48 --- /dev/null +++ b/client/src/app-components/__tests__/ticket-list-test.js @@ -0,0 +1,188 @@ +const _ = require('lodash'); +const TicketInfo = ReactMock(); +const Table = ReactMock(); +const Button = ReactMock(); +const Tooltip = ReactMock(); +const Dropdown = ReactMock(); +const i18n = stub().returnsArg(0); + +const TicketList = requireUnit('app-components/ticket-list', { + 'app-components/ticket-info': TicketInfo, + 'core-components/table': Table, + 'core-components/button': Button, + 'core-components/tooltip': Tooltip, + 'core-components/drop-down': Dropdown, + 'lib-app/i18n': i18n +}); + +describe('TicketList component', function () { + let ticketList, table, dropdown; + let tickets = (function() { + let ticket = { + unread: false, + closed: false, + title: 'This is not working', + ticketNumber: 123124, + date: '20160215', + department: { + id: 1, + name: 'Sales Support' + }, + priority: 'low', + author: { + id: 3, + name: 'Francisco Villegas' + } + }; + let list = _.range(5).map(() => ticket); + + list = list.concat(_.range(5).map(() => { + return _.extend({}, ticket, { + department: { + id: 2, + name: 'Tech Help' + } + }) + })); + + return list; + })(); + + function renderTicketList(props = {}) { + ticketList = TestUtils.renderIntoDocument( + + ); + + table = TestUtils.scryRenderedComponentsWithType(ticketList, Table); + dropdown = TestUtils.scryRenderedComponentsWithType(ticketList, Dropdown); + } + + it('should pass correct props to Table', function () { + renderTicketList(); + expect(table[0].props.loading).to.equal(false); + expect(table[0].props.pageSize).to.equal(10); + expect(table[0].props.headers).to.deep.equal([ + { + key: 'number', + value: i18n('NUMBER'), + className: 'ticket-list__number col-md-1' + }, + { + key: 'title', + value: i18n('TITLE'), + className: 'ticket-list__title col-md-6' + }, + { + key: 'department', + value: i18n('DEPARTMENT'), + className: 'ticket-list__department col-md-3' + }, + { + key: 'date', + value: i18n('DATE'), + className: 'ticket-list__date col-md-2' + } + ]); + }); + + it('should pass loading to Table', function () { + renderTicketList({loading: true}); + expect(table[0].props.loading).to.equal(true); + }); + + it('should pass correct compare function to Table', function () { + let minCompare = table[0].props.comp; + + let row1 = { + closed: false, + unread: false, + date: '20160405' + }; + let row2 = { + closed: false, + unread: false, + date: '20160406' + }; + expect(minCompare(row1, row2)).to.equal(1); + + row1.unread = true; + expect(minCompare(row1, row2)).to.equal(-1); + + row2.unread = true; + expect(minCompare(row1, row2)).to.equal(1); + + row2.date = '20160401'; + expect(minCompare(row1, row2)).to.equal(-1); + }); + + describe('when using secondary type', function () { + beforeEach(function () { + renderTicketList({ + type: 'secondary', + departments: [ + {id: 1, name: 'Sales Support'}, + {id: 2, name: 'Tech Help'} + ] + }); + }); + + it('should pass correct props to Table', function () { + expect(table[0].props.headers).to.deep.equal([ + { + key: 'number', + value: i18n('NUMBER'), + className: 'ticket-list__number col-md-1' + }, + { + key: 'title', + value: i18n('TITLE'), + className: 'ticket-list__title col-md-4' + }, + { + key: 'priority', + value: i18n('PRIORITY'), + className: 'ticket-list__priority col-md-1' + }, + { + key: 'department', + value: i18n('DEPARTMENT'), + className: 'ticket-list__department col-md-2' + }, + { + key: 'author', + value: i18n('AUTHOR'), + className: 'ticket-list__author col-md-2' + }, + { + key: 'date', + value: i18n('DATE'), + className: 'ticket-list__date col-md-2' + } + ]); + }); + + it('should pass correct props to dropdown', function () { + expect(dropdown[0].props.items).to.deep.equal([ + {content: i18n('ALL_DEPARTMENTS')}, + {content: 'Sales Support'}, + {content: 'Tech Help'} + ]); + expect(dropdown[0].props.size).to.equal('medium'); + }); + + it('should filter tickets by department when DropDown changes', function () { + dropdown[0].props.onChange({index: 1}); + _.forEach(table[0].props.rows, function (row) { + expect(row.department).to.equal('Sales Support'); + }); + + dropdown[0].props.onChange({index: 2}); + _.forEach(table[0].props.rows, function (row) { + expect(row.department).to.equal('Tech Help'); + }); + + dropdown[0].props.onChange({index: 0}); + expect(table[0].props.rows.length).to.equal(10); + }); + }); +}); \ No newline at end of file diff --git a/client/src/app-components/ticket-list.js b/client/src/app-components/ticket-list.js index 14b8a99f..3f9b2e61 100644 --- a/client/src/app-components/ticket-list.js +++ b/client/src/app-components/ticket-list.js @@ -1,16 +1,20 @@ import React from 'react'; +import _ from 'lodash'; import i18n from 'lib-app/i18n'; +import DateTransformer from 'lib-core/date-transformer'; +import TicketInfo from 'app-components/ticket-info'; import Table from 'core-components/table'; import Button from 'core-components/button'; import Tooltip from 'core-components/tooltip'; -import TicketInfo from 'app-components/ticket-info'; - -import DateTransformer from 'lib-core/date-transformer'; +import DropDown from 'core-components/drop-down'; class TicketList extends React.Component { static propTypes = { + departments: React.PropTypes.array, + loading: React.PropTypes.bool, + ticketPath: React.PropTypes.string, tickets: React.PropTypes.arrayOf(React.PropTypes.object), type: React.PropTypes.oneOf([ 'primary', @@ -19,18 +23,58 @@ class TicketList extends React.Component { }; static defaultProps = { + loading: false, tickets: [], + departments: [], + ticketPath: '/dashboard/ticket/', type: 'primary' }; + state = { + selectedDepartment: 0 + }; + render() { return (
- + {(this.props.type === 'secondary') ? this.renderDepartmentsDropDown() : null} +
); } + renderDepartmentsDropDown() { + return ( +
+ +
+ ); + } + + getDepartmentDropdownProps() { + return { + items: this.getDepartments(), + onChange: (event) => { + this.setState({ + selectedDepartment: event.index && this.props.departments[event.index - 1].id + }); + }, + size: 'medium' + }; + } + + getDepartments() { + let departments = this.props.departments.map((department) => { + return {content: department.name}; + }); + + departments.unshift({ + content: i18n('ALL_DEPARTMENTS') + }); + + return departments; + } + getTableHeaders() { if (this.props.type == 'primary' ) { return [ @@ -92,7 +136,13 @@ class TicketList extends React.Component { } getTableRows() { - return this.props.tickets.map(this.gerTicketTableObject.bind(this)); + return this.getTickets().map(this.gerTicketTableObject.bind(this)); + } + + getTickets() { + return (this.state.selectedDepartment) ? _.filter(this.props.tickets, (ticket) => { + return ticket.department.id == this.state.selectedDepartment + }) : this.props.tickets; } gerTicketTableObject(ticket) { @@ -105,7 +155,7 @@ class TicketList extends React.Component { ), title: ( - ), @@ -137,8 +187,6 @@ class TicketList extends React.Component { } compareFunction(row1, row2) { - let ans = 0; - if (row1.closed == row2.closed) { if (row1.unread == row2.unread) { let s1 = row1.date; diff --git a/client/src/app-components/tiket-list.scss b/client/src/app-components/ticket-list.scss similarity index 92% rename from client/src/app-components/tiket-list.scss rename to client/src/app-components/ticket-list.scss index 2355c6e4..416d55c5 100644 --- a/client/src/app-components/tiket-list.scss +++ b/client/src/app-components/ticket-list.scss @@ -2,6 +2,10 @@ .ticket-list { + &__department-selector { + margin-bottom: 25px; + } + &__number { text-align: left; } diff --git a/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js index 93a4f327..490a15cf 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js @@ -1,14 +1,47 @@ import React from 'react'; +import {connect} from 'react-redux'; + +import i18n from 'lib-app/i18n'; + +import AdminDataAction from 'actions/admin-data-actions'; +import Header from 'core-components/header'; +import TicketList from 'app-components/ticket-list'; class AdminPanelAllTickets extends React.Component { + static defaultProps = { + departments: [], + tickets: [] + }; + + componentDidMount() { + this.props.dispatch(AdminDataAction.retrieveAllTickets()); + } + render() { return ( -
- /admin/panel/tickets/all-tickets +
+
+
); } + + getProps() { + return { + departments: this.props.departments, + tickets: this.props.tickets, + type: 'secondary', + loading: this.props.loading, + ticketPath: '/admin/panel/tickets/view-ticket/' + }; + } } -export default AdminPanelAllTickets; \ No newline at end of file +export default connect((store) => { + return { + departments: store.session.userDepartments, + tickets: store.adminData.allTickets, + loading: !store.adminData.allTicketsLoaded + }; +})(AdminPanelAllTickets); diff --git a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js index 03a0ffa2..512454b1 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js @@ -1,14 +1,47 @@ import React from 'react'; +import {connect} from 'react-redux'; + +import i18n from 'lib-app/i18n'; + +import AdminDataAction from 'actions/admin-data-actions'; +import Header from 'core-components/header'; +import TicketList from 'app-components/ticket-list'; class AdminPanelMyTickets extends React.Component { + static defaultProps = { + departments: [], + tickets: [] + }; + + componentDidMount() { + this.props.dispatch(AdminDataAction.retrieveMyTickets()); + } + render() { return ( -
- /admin/panel/tickets/my-tickets +
+
+
); } + + getProps() { + return { + departments: this.props.departments, + tickets: this.props.tickets, + type: 'secondary', + loading: this.props.loading, + ticketPath: '/admin/panel/tickets/view-ticket/' + }; + } } -export default AdminPanelMyTickets; \ No newline at end of file +export default connect((store) => { + return { + departments: store.session.userDepartments, + tickets: store.adminData.myTickets, + loading: !store.adminData.myTicketsLoaded + }; +})(AdminPanelMyTickets); diff --git a/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js index 42d250a8..819e9b56 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js @@ -1,14 +1,47 @@ import React from 'react'; +import {connect} from 'react-redux'; + +import i18n from 'lib-app/i18n'; + +import AdminDataAction from 'actions/admin-data-actions'; +import Header from 'core-components/header'; +import TicketList from 'app-components/ticket-list'; class AdminPanelNewTickets extends React.Component { + static defaultProps = { + departments: [], + tickets: [] + }; + + componentDidMount() { + this.props.dispatch(AdminDataAction.retrieveNewTickets()); + } + render() { return ( -
- /admin/panel/tickets/new-tickets +
+
+
); } + + getProps() { + return { + departments: this.props.departments, + tickets: this.props.tickets, + type: 'secondary', + loading: this.props.loading, + ticketPath: '/admin/panel/tickets/view-ticket/' + }; + } } -export default AdminPanelNewTickets; \ No newline at end of file +export default connect((store) => { + return { + departments: store.session.userDepartments, + tickets: store.adminData.newTickets, + loading: !store.adminData.newTicketsLoaded + }; +})(AdminPanelNewTickets); diff --git a/client/src/core-components/table.scss b/client/src/core-components/table.scss index 62dd409c..54a73615 100644 --- a/client/src/core-components/table.scss +++ b/client/src/core-components/table.scss @@ -51,6 +51,8 @@ &__loading-wrapper { min-height: 200px; + position: relative; + background-color: $grey; } &__loading { diff --git a/client/src/core-components/tooltip.scss b/client/src/core-components/tooltip.scss index 50bd126d..bbe42bdb 100644 --- a/client/src/core-components/tooltip.scss +++ b/client/src/core-components/tooltip.scss @@ -17,6 +17,7 @@ background-color: #F7F7F7; color: black; padding: 10px; + z-index: 1000; } &__pointer { diff --git a/client/src/data/fixtures/staff-fixtures.js b/client/src/data/fixtures/staff-fixtures.js index ea6afbcd..4d1686cd 100644 --- a/client/src/data/fixtures/staff-fixtures.js +++ b/client/src/data/fixtures/staff-fixtures.js @@ -13,11 +13,576 @@ module.exports = [ staff: true, departments: [ {id: 1, name: 'Sales Support'}, - {id: 2, name: 'Technical Issues'}, - {id: 3, name: 'System and Administration'} + {id: 2, name: 'Technical Issues'} ] } }; } + }, + { + path: '/staff/get-tickets', + time: 300, + response: function () { + return { + status: 'success', + data: [ + { + ticketNumber: '445441', + title: 'Problem with installation', + content: 'I had a problem with the installation of the php server', + department: { + id: 2, + name: 'Technical Issues' + }, + date: '20160416', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: true, + closed: false, + priority: 'low', + author: { + id: 12, + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + id: 15, + name: 'Steve Jobs', + email: 'steve@jobs.com' + }, + events: [ + { + type: 'ASSIGN', + date: '20150409', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'COMMENT', + date: '20150409', + content: 'Do you have apache installed? It generally happens if you dont have apache.', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'UN_ASSIGN', + date: '20150410', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'DEPARTMENT_CHANGED', + date: '20150411', + content: 'System support', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'COMMENT', + date: '20150412', + content: 'I have already installed apache, but the problem persists', + author: { + name: 'Haskell Curry', + steve: 'haskell@lambda.com', + staff: false + } + }, + { + type: 'PRIORITY_CHANGED', + date: '20150413', + content: 'MEDIUM', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'COMMENT', + date: '20150511', + content: 'Thanks!, I solved it by myself', + author: { + name: 'Haskell Curry', + steve: 'haskell@lambda.com', + staff: false + } + }, + { + type: 'CLOSE', + date: '20150513', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'RE_OPEN', + date: '20151018', + author: { + name: 'Haskell Curry', + email: 'haskell@lambda.com', + staff: false + } + } + ] + }, + { + ticketNumber: '878552', + title: 'Lorem ipsum door', + content: 'I had a problem with the installation of the php server', + department: { + id: 2, + name: 'Technical Issues' + }, + date: '20160415', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: false, + closed: false, + priority: 'medium', + author: { + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + name: 'Steve Jobs' + }, + events: [ + { + type: 'ASSIGN', + date: '20150409', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'COMMENT', + date: '20150409', + content: 'Do you have apache installed? It generally happens if you dont have apache.', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'UN_ASSIGN', + date: '20150410', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'DEPARTMENT_CHANGED', + date: '20150411', + content: 'System support', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'COMMENT', + date: '20150412', + content: 'I have already installed apache, but the problem persists', + author: { + name: 'Haskell Curry', + steve: 'haskell@lambda.com', + staff: false + } + }, + { + type: 'PRIORITY_CHANGED', + date: '20150413', + content: 'MEDIUM', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'COMMENT', + date: '20150511', + content: 'Thanks!, I soved it by myself', + author: { + name: 'Haskell Curry', + steve: 'haskell@lambda.com', + staff: false + } + }, + { + type: 'CLOSE', + date: '20150513', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'RE_OPEN', + date: '20151018', + author: { + name: 'Haskell Curry', + email: 'haskell@lambda.com', + staff: false + } + } + ] + }, + { + ticketNumber: '118551', + title: 'Lorem ipsum door', + content: 'I had a problem with the installation of the php server', + department: { + id: 2, + name: 'Technical Issues' + }, + date: '20150409', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: false, + closed: false, + priority: 'high', + author: { + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + name: 'Steve Jobs' + }, + events: [ + { + type: 'ASSIGN', + date: '20150409', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'COMMENT', + date: '20150409', + content: 'Do you have apache installed? It generally happens if you dont have apache.', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'UN_ASSIGN', + date: '20150410', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'DEPARTMENT_CHANGED', + date: '20150411', + content: 'System support', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'COMMENT', + date: '20150412', + content: 'I have already installed apache, but the problem persists', + author: { + name: 'Haskell Curry', + steve: 'haskell@lambda.com', + staff: false + } + }, + { + type: 'PRIORITY_CHANGED', + date: '20150413', + content: 'MEDIUM', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'COMMENT', + date: '20150511', + content: 'Thanks!, I soved it by myself', + author: { + name: 'Haskell Curry', + steve: 'haskell@lambda.com', + staff: false + } + }, + { + type: 'CLOSE', + date: '20150513', + author: { + name: 'Emilia Clarke', + email: 'jobs@steve.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + staff: true + } + }, + { + type: 'RE_OPEN', + date: '20151018', + author: { + name: 'Haskell Curry', + email: 'haskell@lambda.com', + staff: false + } + } + ] + }, + { + ticketNumber: '445441', + title: 'Inscription ACM ICPC', + content: 'I had a problem with the installation of the php server', + department: { + id: 1, + name: 'Sales Support' + }, + date: '20160416', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: false, + closed: false, + priority: 'low', + author: { + id: 12, + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + id: 15, + name: 'Steve Jobs', + email: 'steve@jobs.com' + }, + events: [] + } + ] + } + } + }, + { + path: '/staff/get-new-tickets', + time: 300, + response: function () { + return { + status: 'success', + data: [ + { + ticketNumber: '445441', + title: 'Inscription ACM ICPC', + content: 'I had a problem with the installation of the php server', + department: { + id: 1, + name: 'Sales Support' + }, + date: '20160416', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: true, + closed: false, + priority: 'low', + author: { + id: 12, + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + id: 15, + name: 'Steve Jobs', + email: 'steve@jobs.com' + }, + events: [] + }, + { + ticketNumber: '445441', + title: 'Inscription ACM ICPC', + content: 'I had a problem with the installation of the php server', + department: { + id: 1, + name: 'Sales Support' + }, + date: '20160416', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: true, + closed: false, + priority: 'low', + author: { + id: 12, + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + id: 15, + name: 'Steve Jobs', + email: 'steve@jobs.com' + }, + events: [] + }, + { + ticketNumber: '445441', + title: 'Code jam is awesome', + content: 'I had a problem with the installation of the php server', + department: { + id: 2, + name: 'Technical Issues' + }, + date: '20160416', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: true, + closed: false, + priority: 'low', + author: { + id: 12, + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + id: 15, + name: 'Steve Jobs', + email: 'steve@jobs.com' + }, + events: [] + } + ] + } + } + }, + { + path: '/staff/get-all-tickets', + time: 300, + response: function () { + return { + status: 'success', + data: [ + { + ticketNumber: '445441', + title: 'Inscription ACM ICPC', + content: 'I had a problem with the installation of the php server', + department: { + id: 1, + name: 'Sales Support' + }, + date: '20160416', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: true, + closed: false, + priority: 'low', + author: { + id: 12, + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + id: 15, + name: 'Steve Jobs', + email: 'steve@jobs.com' + }, + events: [] + }, + { + ticketNumber: '445441', + title: 'Inscription ACM ICPC', + content: 'I had a problem with the installation of the php server', + department: { + id: 1, + name: 'Sales Support' + }, + date: '20160416', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: true, + closed: false, + priority: 'low', + author: { + id: 12, + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + id: 15, + name: 'Steve Jobs', + email: 'steve@jobs.com' + }, + events: [] + }, + { + ticketNumber: '445441', + title: 'Code jam is awesome', + content: 'I had a problem with the installation of the php server', + department: { + id: 2, + name: 'Technical Issues' + }, + date: '20160416', + file: 'http://www.opensupports.com/some_file.zip', + language: 'en', + unread: true, + closed: false, + priority: 'low', + author: { + id: 12, + name: 'Haskell Curry', + email: 'haskell@lambda.com' + }, + owner: { + id: 15, + name: 'Steve Jobs', + email: 'steve@jobs.com' + }, + events: [] + } + ] + } + } } ]; \ No newline at end of file diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index 556666fc..e964ceec 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -74,6 +74,7 @@ export default { 'SELECT_CUSTOM_RESPONSE': 'Select a custom response...', 'WARNING': 'Warning', 'INFO': 'Information', + 'ALL_DEPARTMENTS': 'All Departments', //VIEW DESCRIPTIONS 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', @@ -83,6 +84,9 @@ export default { 'ACCOUNT_DESCRIPTION': 'All your tickets are stored in your accounts\'s profile. Keep track off all your tickets you send to our staff team.', 'SUPPORT_CENTER_DESCRIPTION': 'Welcome to our support center. You can contact us through a tickets system. Your tickets will be answered by our staff.', 'CUSTOM_RESPONSES_DESCRIPTION': 'Custom responses are automated responses for common problems', + 'MY_TICKETS_DESCRIPTION': 'Here you can view the tickets you are responsible for.', + 'NEW_TICKETS_DESCRIPTION': 'Here you can view all the new tickets that are not assigned by anyone.', + 'ALL_TICKETS_DESCRIPTION': 'Here you can view the tickets of the departments you are assigned.', 'TICKET_VIEW_DESCRIPTION': 'This ticket has been sent by a customer. Here you can respond or assign the ticket', //ERRORS diff --git a/client/src/reducers/admin-data-reducer.js b/client/src/reducers/admin-data-reducer.js index 2aeb295b..6ed135ee 100644 --- a/client/src/reducers/admin-data-reducer.js +++ b/client/src/reducers/admin-data-reducer.js @@ -8,14 +8,26 @@ class AdminDataReducer extends Reducer { getInitialState() { return { customResponses: [], - customResponsesLoaded: false + customResponsesLoaded: false, + myTickets: [], + myTicketsLoaded: false, + newTickets: [], + newTicketsLoaded: false, + allTickets: [], + allTicketsLoaded: false }; } getTypeHandlers() { return { 'CUSTOM_RESPONSES_FULFILLED': this.onCustomResponses, - 'SESSION_CHECKED': this.onSessionChecked + 'SESSION_CHECKED': this.onSessionChecked, + 'MY_TICKETS_FULFILLED': this.onMyTicketsRetrieved, + 'MY_TICKETS_PENDING': this.onMyTicketsPending, + 'NEW_TICKETS_FULFILLED': this.onNewTicketsRetrieved, + 'NEW_TICKETS_PENDING': this.onNewTicketsPending, + 'ALL_TICKETS_FULFILLED': this.onAllTicketsRetrieved, + 'ALL_TICKETS_PENDING': this.onAllTicketsPending }; } @@ -36,6 +48,45 @@ class AdminDataReducer extends Reducer { customResponsesLoaded: true }); } + + onMyTicketsRetrieved(state, payload) { + return _.extend({}, state, { + myTickets: payload.data, + myTicketsLoaded: true + }) + } + + onMyTicketsPending(state) { + return _.extend({}, state, { + myTicketsLoaded: false + }) + } + + onNewTicketsRetrieved(state, payload) { + return _.extend({}, state, { + newTickets: payload.data, + newTicketsLoaded: true + }) + } + + onNewTicketsPending(state) { + return _.extend({}, state, { + newTicketsLoaded: false + }) + } + + onAllTicketsRetrieved(state, payload) { + return _.extend({}, state, { + allTickets: payload.data, + allTicketsLoaded: true + }) + } + + onAllTicketsPending(state) { + return _.extend({}, state, { + allTicketsLoaded: false + }) + } } export default AdminDataReducer.getInstance(); \ No newline at end of file