mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-28 00:04:31 +02:00
Merged in OS-78-My-tickets-view (pull request #74)
OS-78 my tickets view
This commit is contained in:
commit
cc1b5785fa
@ -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: {}
|
||||
})
|
||||
};
|
||||
}
|
||||
};
|
188
client/src/app-components/__tests__/ticket-list-test.js
Normal file
188
client/src/app-components/__tests__/ticket-list-test.js
Normal file
@ -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(
|
||||
<TicketList tickets={tickets} {...props}/>
|
||||
);
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
@ -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 (
|
||||
<div className="ticket-list">
|
||||
<Table headers={this.getTableHeaders()} rows={this.getTableRows()} pageSize={10} comp={this.compareFunction} />
|
||||
{(this.props.type === 'secondary') ? this.renderDepartmentsDropDown() : null}
|
||||
<Table loading={this.props.loading} headers={this.getTableHeaders()} rows={this.getTableRows()} pageSize={10} comp={this.compareFunction} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderDepartmentsDropDown() {
|
||||
return (
|
||||
<div className="ticket-list__department-selector">
|
||||
<DropDown {...this.getDepartmentDropdownProps()} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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 {
|
||||
</Tooltip>
|
||||
),
|
||||
title: (
|
||||
<Button className="ticket-list__title-link" type="clean" route={{to: '/dashboard/ticket/' + ticket.ticketNumber}}>
|
||||
<Button className="ticket-list__title-link" type="clean" route={{to: this.props.ticketPath + ticket.ticketNumber}}>
|
||||
{titleText}
|
||||
</Button>
|
||||
),
|
||||
@ -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;
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
.ticket-list {
|
||||
|
||||
&__department-selector {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
&__number {
|
||||
text-align: left;
|
||||
}
|
@ -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 (
|
||||
<div>
|
||||
/admin/panel/tickets/all-tickets
|
||||
<div className="admin-panel-my-tickets">
|
||||
<Header title={i18n('ALL_TICKETS')} description={i18n('ALL_TICKETS_DESCRIPTION')} />
|
||||
<TicketList {...this.getProps()}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
export default connect((store) => {
|
||||
return {
|
||||
departments: store.session.userDepartments,
|
||||
tickets: store.adminData.allTickets,
|
||||
loading: !store.adminData.allTicketsLoaded
|
||||
};
|
||||
})(AdminPanelAllTickets);
|
||||
|
@ -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 (
|
||||
<div>
|
||||
/admin/panel/tickets/my-tickets
|
||||
<div className="admin-panel-my-tickets">
|
||||
<Header title={i18n('MY_TICKETS')} description={i18n('MY_TICKETS_DESCRIPTION')} />
|
||||
<TicketList {...this.getProps()}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
export default connect((store) => {
|
||||
return {
|
||||
departments: store.session.userDepartments,
|
||||
tickets: store.adminData.myTickets,
|
||||
loading: !store.adminData.myTicketsLoaded
|
||||
};
|
||||
})(AdminPanelMyTickets);
|
||||
|
@ -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 (
|
||||
<div>
|
||||
/admin/panel/tickets/new-tickets
|
||||
<div className="admin-panel-my-tickets">
|
||||
<Header title={i18n('NEW_TICKETS')} description={i18n('NEW_TICKETS_DESCRIPTION')} />
|
||||
<TicketList {...this.getProps()}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
export default connect((store) => {
|
||||
return {
|
||||
departments: store.session.userDepartments,
|
||||
tickets: store.adminData.newTickets,
|
||||
loading: !store.adminData.newTicketsLoaded
|
||||
};
|
||||
})(AdminPanelNewTickets);
|
||||
|
@ -51,6 +51,8 @@
|
||||
|
||||
&__loading-wrapper {
|
||||
min-height: 200px;
|
||||
position: relative;
|
||||
background-color: $grey;
|
||||
}
|
||||
|
||||
&__loading {
|
||||
|
@ -17,6 +17,7 @@
|
||||
background-color: #F7F7F7;
|
||||
color: black;
|
||||
padding: 10px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
&__pointer {
|
||||
|
@ -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: []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
@ -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
|
||||
|
@ -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();
|
Loading…
x
Reference in New Issue
Block a user