Merged in os-84-frontend-ticket-events (pull request #69)

Os 85 Frontend - Staff Ticket view
This commit is contained in:
Ivan Diaz 2016-10-21 19:40:18 +00:00
commit 61ecc00faf
16 changed files with 531 additions and 110 deletions

View File

@ -4,7 +4,7 @@ import classNames from 'classnames';
import i18n from 'lib-app/i18n';
import Icon from 'core-components/icon';
class TicketAction extends React.Component {
class TicketEvent extends React.Component {
static propTypes = {
type: React.PropTypes.oneOf([
'COMMENT',
@ -31,12 +31,12 @@ class TicketAction extends React.Component {
return (
<div className={this.getClass()}>
<span className="ticket-action__connector" />
<span className="ticket-event__connector" />
<div className="col-md-1">
{iconNode}
</div>
<div className="col-md-11">
{this.renderActionDescription()}
{this.renderEventDescription()}
</div>
</div>
);
@ -44,21 +44,21 @@ class TicketAction extends React.Component {
renderStaffPic() {
return (
<div className="ticket-action__staff-pic">
<img src={this.props.author.profilePic} className="ticket-action__staff-pic-img" />
<div className="ticket-event__staff-pic">
<img src={this.props.author.profilePic} className="ticket-event__staff-pic-img" />
</div>
);
}
renderIcon() {
return (
<div className="ticket-action__icon">
<div className="ticket-event__icon">
<Icon {...this.getIconProps()}/>
</div>
);
}
renderActionDescription() {
renderEventDescription() {
const renders = {
'COMMENT': this.renderComment.bind(this),
'ASSIGN': this.renderAssignment.bind(this),
@ -74,14 +74,14 @@ class TicketAction extends React.Component {
renderComment() {
return (
<div className="ticket-action__comment">
<span className="ticket-action__comment-pointer" />
<div className="ticket-action__comment-author">
<span className="ticket-action__comment-author-name">{this.props.author.name}</span>
<span className="ticket-action__comment-author-type">({i18n((this.props.author.staff) ? 'STAFF' : 'CUSTOMER')})</span>
<div className="ticket-event__comment">
<span className="ticket-event__comment-pointer" />
<div className="ticket-event__comment-author">
<span className="ticket-event__comment-author-name">{this.props.author.name}</span>
<span className="ticket-event__comment-author-type">({i18n((this.props.author.staff) ? 'STAFF' : 'CUSTOMER')})</span>
</div>
<div className="ticket-action__comment-date">{this.props.date}</div>
<div className="ticket-action__comment-content" dangerouslySetInnerHTML={{__html: this.props.content}}></div>
<div className="ticket-event__comment-date">{this.props.date}</div>
<div className="ticket-event__comment-content" dangerouslySetInnerHTML={{__html: this.props.content}}></div>
{this.renderFileRow(this.props.file)}
</div>
);
@ -89,62 +89,62 @@ class TicketAction extends React.Component {
renderAssignment() {
return (
<div className="ticket-action__circled">
<span className="ticket-action__circled-author">{this.props.author.name}</span>
<span className="ticket-action__circled-text"> assigned this ticket</span>
<span className="ticket-action__circled-date"> on {this.props.date}</span>
<div className="ticket-event__circled">
<span className="ticket-event__circled-author">{this.props.author.name}</span>
<span className="ticket-event__circled-text"> assigned this ticket</span>
<span className="ticket-event__circled-date"> on {this.props.date}</span>
</div>
)
}
renderUnAssignment() {
return (
<div className="ticket-action__circled">
<span className="ticket-action__circled-author">{this.props.author.name}</span>
<span className="ticket-action__circled-text"> unassigned this ticket</span>
<span className="ticket-action__circled-date"> on {this.props.date}</span>
<div className="ticket-event__circled">
<span className="ticket-event__circled-author">{this.props.author.name}</span>
<span className="ticket-event__circled-text"> unassigned this ticket</span>
<span className="ticket-event__circled-date"> on {this.props.date}</span>
</div>
)
}
renderClosed() {
return (
<div className="ticket-action__circled">
<span className="ticket-action__circled-author">{this.props.author.name}</span>
<span className="ticket-action__circled-text"> closed this ticket</span>
<span className="ticket-action__circled-date"> on {this.props.date}</span>
<div className="ticket-event__circled">
<span className="ticket-event__circled-author">{this.props.author.name}</span>
<span className="ticket-event__circled-text"> closed this ticket</span>
<span className="ticket-event__circled-date"> on {this.props.date}</span>
</div>
)
}
renderReOpened() {
return (
<div className="ticket-action__circled">
<span className="ticket-action__circled-author">{this.props.author.name}</span>
<span className="ticket-action__circled-text"> reopen this ticket</span>
<span className="ticket-action__circled-date"> on {this.props.date}</span>
<div className="ticket-event__circled">
<span className="ticket-event__circled-author">{this.props.author.name}</span>
<span className="ticket-event__circled-text"> reopen this ticket</span>
<span className="ticket-event__circled-date"> on {this.props.date}</span>
</div>
);
}
renderDepartmentChange() {
return (
<div className="ticket-action__circled">
<span className="ticket-action__circled-author">{this.props.author.name}</span>
<span className="ticket-action__circled-text"> change department to</span>
<span className="ticket-action__circled-indication"> {this.props.content}</span>
<span className="ticket-action__circled-date"> on {this.props.date}</span>
<div className="ticket-event__circled">
<span className="ticket-event__circled-author">{this.props.author.name}</span>
<span className="ticket-event__circled-text"> change department to</span>
<span className="ticket-event__circled-indication"> {this.props.content}</span>
<span className="ticket-event__circled-date"> on {this.props.date}</span>
</div>
);
}
renderPriorityChange() {
return (
<div className="ticket-action__circled">
<span className="ticket-action__circled-author">{this.props.author.name}</span>
<span className="ticket-action__circled-text"> change priority to</span>
<span className="ticket-action__circled-indication"> {this.props.content}</span>
<span className="ticket-action__circled-date"> on {this.props.date}</span>
<div className="ticket-event__circled">
<span className="ticket-event__circled-author">{this.props.author.name}</span>
<span className="ticket-event__circled-text"> change priority to</span>
<span className="ticket-event__circled-indication"> {this.props.content}</span>
<span className="ticket-event__circled-date"> on {this.props.date}</span>
</div>
);
}
@ -177,14 +177,14 @@ class TicketAction extends React.Component {
};
const classes = {
'row': true,
'ticket-action': true,
'ticket-action_staff': this.props.author && this.props.author.staff,
'ticket-action_circled': circledTypes[this.props.type],
'ticket-action_unassignment': this.props.type === 'UN_ASSIGN',
'ticket-action_close': this.props.type === 'CLOSE',
'ticket-action_reopen': this.props.type === 'RE_OPEN',
'ticket-action_department': this.props.type === 'DEPARTMENT_CHANGED',
'ticket-action_priority': this.props.type === 'PRIORITY_CHANGED'
'ticket-event': true,
'ticket-event_staff': this.props.author && this.props.author.staff,
'ticket-event_circled': circledTypes[this.props.type],
'ticket-event_unassignment': this.props.type === 'UN_ASSIGN',
'ticket-event_close': this.props.type === 'CLOSE',
'ticket-event_reopen': this.props.type === 'RE_OPEN',
'ticket-event_department': this.props.type === 'DEPARTMENT_CHANGED',
'ticket-event_priority': this.props.type === 'PRIORITY_CHANGED'
};
return classNames(classes);
@ -225,4 +225,4 @@ class TicketAction extends React.Component {
}
}
export default TicketAction;
export default TicketEvent;

View File

@ -1,6 +1,6 @@
@import "../scss/vars";
.ticket-action {
.ticket-event {
margin-top: 20px;
text-align: left;
position: relative;
@ -91,11 +91,11 @@
}
&_staff {
.ticket-action__icon {
.ticket-event__icon {
background-color: $primary-blue;
}
.ticket-action__comment-author-type {
.ticket-event__comment-author-type {
color: $primary-blue;
}
}
@ -104,11 +104,11 @@
margin-top: 35px;
margin-bottom: 30px;
.ticket-action__connector {
.ticket-event__connector {
top: 28px;
}
.ticket-action__icon {
.ticket-event__icon {
background-color: white;
color: $primary-black;
border: 3px solid $light-grey;
@ -121,48 +121,48 @@
margin-top: -8px;
}
.ticket-action__circled {
.ticket-event__circled {
color: $primary-black;
font-size: $font-size--sm;
margin-top: 1px;
}
.ticket-action__circled-author {
.ticket-event__circled-author {
color: $secondary-blue;
}
.ticket-action__circled-indication {
.ticket-event__circled-indication {
color: $primary-green;
}
}
&_unassignment {
.ticket-action__icon {
.ticket-event__icon {
padding-left: 6px;
}
}
&_close {
.ticket-action__icon {
.ticket-event__icon {
padding-left: 9px;
}
}
&_reopen {
.ticket-action__icon {
.ticket-event__icon {
padding-left: 9px;
padding-top: 5px;
}
}
&_department {
.ticket-action__icon {
.ticket-event__icon {
padding-left: 6px;
}
}
&_priority {
.ticket-action__icon {
.ticket-event__icon {
padding-left: 11px;
padding-top: 5px;
}

View File

@ -4,19 +4,27 @@ import _ from 'lodash';
import i18n from 'lib-app/i18n';
import API from 'lib-app/api-call';
import store from 'app/store';
import SessionStore from 'lib-app/session-store';
import SessionActions from 'actions/session-actions';
import TicketAction from 'app-components/ticket-action';
import TicketEvent from 'app-components/ticket-event';
import AreYouSure from 'app-components/are-you-sure';
import Form from 'core-components/form';
import FormField from 'core-components/form-field';
import SubmitButton from 'core-components/submit-button';
import DropDown from 'core-components/drop-down';
import Button from 'core-components/button';
class TicketViewer extends React.Component {
static propTypes = {
ticket: React.PropTypes.object
ticket: React.PropTypes.object,
onChange: React.PropTypes.func,
editable: React.PropTypes.bool,
assignmentAllowed: React.PropTypes.bool
};
static defaultProps = {
editable: false,
ticket: {
author: {},
department: {},
@ -32,7 +40,6 @@ class TicketViewer extends React.Component {
};
}
render() {
const ticket = this.props.ticket;
@ -42,21 +49,12 @@ class TicketViewer extends React.Component {
<span className="ticket-viewer__number">#{ticket.ticketNumber}</span>
<span className="ticket-viewer__title">{ticket.title}</span>
</div>
<div className="ticket-viewer__info-row-header row">
<div className="ticket-viewer__department col-md-4">{i18n('DEPARTMENT')}</div>
<div className="ticket-viewer__author col-md-4">{i18n('AUTHOR')}</div>
<div className="ticket-viewer__date col-md-4">{i18n('DATE')}</div>
</div>
<div className="ticket-viewer__info-row-values row">
<div className="ticket-viewer__department col-md-4">{ticket.department.name}</div>
<div className="ticket-viewer__author col-md-4">{ticket.author.name}</div>
<div className="ticket-viewer__date col-md-4">{ticket.date}</div>
</div>
{this.props.editable ? this.renderEditableHeaders() : this.renderHeaders()}
<div className="ticket-viewer__content">
<TicketAction type="COMMENT" author={ticket.author} content={ticket.content} date={ticket.date} file={ticket.file}/>
<TicketEvent type="COMMENT" author={ticket.author} content={ticket.content} date={ticket.date} file={ticket.file}/>
</div>
<div className="ticket-viewer__comments">
{ticket.actions && ticket.actions.map(this.renderAction.bind(this))}
{ticket.events && ticket.events.map(this.renderTicketEvent.bind(this))}
</div>
<div className="ticket-viewer__response">
<div className="ticket-viewer__response-title row">{i18n('RESPOND')}</div>
@ -71,12 +69,179 @@ class TicketViewer extends React.Component {
);
}
renderAction(action, index) {
renderEditableHeaders() {
const ticket = this.props.ticket;
const departments = SessionStore.getDepartments();
const priorities = {
'low': 0,
'medium': 1,
'high': 2
};
const priorityList = [
{content: i18n('LOW')},
{content: i18n('MEDIUM')},
{content: i18n('HIGH')}
];
return (
<TicketAction {...action} key={index} />
<div className="ticket-viewer__headers">
<div className="ticket-viewer__info-row-header row">
<div className="col-md-4">{i18n('DEPARTMENT')}</div>
<div className=" col-md-4">{i18n('AUTHOR')}</div>
<div className="col-md-4">{i18n('DATE')}</div>
</div>
<div className="ticket-viewer__info-row-values row">
<div className="col-md-4">
<DropDown className="ticket-viewer__editable-dropdown"
items={departments.map((department) => {return {content: department.name}})}
selectedIndex={_.findIndex(departments, {id: this.props.ticket.department.id})}
onChange={this.onDepartmentDropdownChanged.bind(this)} />
</div>
<div className="col-md-4">{ticket.author.name}</div>
<div className="col-md-4">{ticket.date}</div>
</div>
<div className="ticket-viewer__info-row-header row">
<div className="col-md-4">{i18n('PRIORITY')}</div>
<div className="col-md-4">{i18n('OWNED')}</div>
<div className="col-md-4">{i18n('STATUS')}</div>
</div>
<div className="ticket-viewer__info-row-values row">
<div className="col-md-4">
<DropDown className="ticket-viewer__editable-dropdown" items={priorityList} selectedIndex={priorities[ticket.priority]} onChange={this.onPriorityDropdownChanged.bind(this)} />
</div>
<div className="col-md-4">
<Button type={(ticket.owner) ? 'primary' : 'secondary'} size="extra-small" onClick={this.onAssignClick.bind(this)}>
{i18n(ticket.owner ? 'UN_ASSIGN' : 'ASSIGN_TO_ME')}
</Button>
</div>
<div className="col-md-4">
<Button type={(ticket.closed) ? 'secondary' : 'primary'} size="extra-small" onClick={this.onCloseClick.bind(this)}>
{i18n(ticket.closed ? 'RE_OPEN' : 'CLOSE')}
</Button>
</div>
</div>
</div>
);
}
renderHeaders() {
const ticket = this.props.ticket;
const priorities = {
'low': 'LOW',
'medium': 'MEDIUM',
'high': 'HIGH'
};
return (
<div className="ticket-viewer__headers">
<div className="ticket-viewer__info-row-header row">
<div className="ticket-viewer__department col-md-4">{i18n('DEPARTMENT')}</div>
<div className="ticket-viewer__author col-md-4">{i18n('AUTHOR')}</div>
<div className="ticket-viewer__date col-md-4">{i18n('DATE')}</div>
</div>
<div className="ticket-viewer__info-row-values row">
<div className="ticket-viewer__department col-md-4">{ticket.department.name}</div>
<div className="ticket-viewer__author col-md-4">{ticket.author.name}</div>
<div className="ticket-viewer__date col-md-4">{ticket.date}</div>
</div>
<div className="ticket-viewer__info-row-header row">
<div className="ticket-viewer__department col-md-4">{i18n('PRIORITY')}</div>
<div className="ticket-viewer__author col-md-4">{i18n('OWNER')}</div>
<div className="ticket-viewer__date col-md-4">{i18n('STATUS')}</div>
</div>
<div className="ticket-viewer__info-row-values row">
<div className="col-md-4">
{i18n(priorities[this.props.ticket.priority || 'low'])}
</div>
<div className="col-md-4">
{(ticket.owner) ? ticket.owner.name : i18n('NONE')}
</div>
<div className="col-md-4">
{this.renderOwnerNode()}
</div>
</div>
</div>
);
}
renderOwnerNode() {
let ownerNode = null;
if (this.props.assignmentAllowed && _.isEmpty(this.props.ticket.owner)) {
ownerNode = (
<Button type="secondary" size="extra-small" onClick={this.onAssignClick.bind(this)}>
{i18n('ASSIGN_TO_ME')}
</Button>
);
} else {
ownerNode = i18n((this.props.closed) ? 'CLOSED' : 'OPENED');
}
return ownerNode;
}
renderTicketEvent(options, index) {
return (
<TicketEvent {...options} key={index} />
);
}
onDepartmentDropdownChanged(event) {
AreYouSure.openModal(null, this.changeDepartment.bind(this, event.index));
}
onPriorityDropdownChanged(event) {
AreYouSure.openModal(null, this.changePriority.bind(this, event.index));
}
onAssignClick() {
API.call({
path: (this.props.ticket.owner) ? '/staff/un-assign-ticket' : '/staff/assign-ticket',
data: {
ticketNumber: this.props.ticket.ticketNumber
}
}).then(this.onTicketModification.bind(this));
}
onCloseClick() {
AreYouSure.openModal(null, this.toggleClose.bind(this));
}
toggleClose() {
API.call({
path: (this.props.ticket.closed) ? '/ticket/re-open' : '/ticket/close',
data: {
ticketNumber: this.props.ticket.ticketNumber
}
}).then(this.onTicketModification.bind(this));
}
changeDepartment(index) {
API.call({
path: '/ticket/change-department',
data: {
ticketNumber: this.props.ticket.ticketNumber,
departmentId: SessionStore.getDepartments()[index].id
}
}).then(this.onTicketModification.bind(this));
}
changePriority(index) {
const priorities = [
'low',
'medium',
'high'
];
API.call({
path: '/ticket/change-priority',
data: {
ticketNumber: this.props.ticket.ticketNumber,
priority: priorities[index]
}
}).then(this.onTicketModification.bind(this));
}
onSubmit(formState) {
this.setState({
loading: true
@ -94,8 +259,8 @@ class TicketViewer extends React.Component {
this.setState({
loading: false
});
store.dispatch(SessionActions.getUserData());
this.onTicketModification();
}
onCommentFail() {
@ -103,6 +268,12 @@ class TicketViewer extends React.Component {
loading: false
});
}
onTicketModification() {
if (this.props.onChange) {
this.props.onChange();
}
}
}
export default TicketViewer;

View File

@ -28,18 +28,15 @@
&__info-row-values {
background-color: $light-grey;
color: $secondary-blue;
padding-bottom: 10px;
}
&__date {
}
&__author {
}
&__department {
&__editable-dropdown {
margin: auto;
.drop-down__current-item {
background-color: $very-light-grey;
}
}
&__content {

View File

@ -84,7 +84,7 @@ export default (
<Route path="new-tickets" component={AdminPanelNewTickets} />
<Route path="all-tickets" component={AdminPanelAllTickets} />
<Route path="custom-responses" component={AdminPanelCustomResponses} />
<Route path="view-ticket" component={AdminPanelViewTicket} />
<Route path="view-ticket/:ticketNumber" component={AdminPanelViewTicket} />
</Route>
<Route path="users">

View File

@ -1,14 +1,98 @@
import React from 'react';
import _ from 'lodash';
import API from 'lib-app/api-call';
import i18n from 'lib-app/i18n';
import SessionStore from 'lib-app/session-store';
import TicketViewer from 'app-components/ticket-viewer';
import Loading from 'core-components/loading';
import Header from 'core-components/header';
class AdminPanelViewTicket extends React.Component {
state = {
loading: true,
ticket: {}
};
componentDidMount() {
this.retrieveTicket();
}
render() {
return (
<div>
/admin/panel/tickets/view-ticket
<div className="admin-panel-view-ticket">
<Header title={i18n('VIEW_TICKET')} description={i18n('TICKET_VIEW_DESCRIPTION')} />
{(this.state.loading) ? this.renderLoading() : this.renderView()}
</div>
);
}
renderLoading() {
return (
<div className="admin-panel-view-ticket__loading">
<Loading size="large" />
</div>
)
};
renderView() {
return (_.isEmpty(this.state.ticket)) ? this.renderNoPermissionError() : this.renderTicketView();
}
renderNoPermissionError() {
return (
<div className="admin-panel-view-ticket__error">
{i18n('NO_PERMISSION')}
</div>
);
}
renderTicketView() {
return (
<div className="admin-panel-view-ticket__ticket-view">
<TicketViewer {...this.getTicketViewProps()} />
</div>
);
}
getTicketViewProps() {
return {
ticket: this.state.ticket,
onChange: this.retrieveTicket.bind(this),
assignmentAllowed: true,
editable: _.get(this.state.ticket, 'owner.id') === SessionStore.getUserData().id
};
}
retrieveTicket() {
this.setState({
loading: true,
ticket: {}
});
API.call({
path: '/ticket/get',
date: {
ticketNumber: this.props.params.ticketNumber
}
}).then(this.onRetrieveSuccess.bind(this)).catch(this.onRetrieveFail.bind(this))
}
onRetrieveSuccess(result) {
this.setState({
loading: false,
ticket: result.data
});
}
onRetrieveFail() {
this.setState({
loading: false,
ticket: {}
});
}
}
export default AdminPanelViewTicket;

View File

@ -0,0 +1,18 @@
@import '../../../../scss/vars';
.admin-panel-view-ticket {
margin: 10px;
&__loading {
background-color: $grey;
height: 400px;
}
&__error {
}
&__ticket-view {
margin: 20px 30px;
}
}

View File

@ -42,8 +42,8 @@ class CreateTicketForm extends React.Component {
{(!this.props.userLogged) ? this.renderEmailAndName() : null}
<div className="row">
<FormField className="col-md-7" label="Title" name="title" validation="TITLE" required field="input" fieldProps={{size: 'large'}}/>
<FormField className="col-md-5" label="Department" name="departmentId" field="select" fieldProps={{
items: SessionStore.getDepartments().map((department) => {return {content: department}}),
<FormField className="col-md-5" label="Department" name="departmentIndex" field="select" fieldProps={{
items: SessionStore.getDepartments().map((department) => {return {content: department.name}}),
size: 'medium'
}} />
</div>
@ -92,7 +92,7 @@ class CreateTicketForm extends React.Component {
API.call({
path: '/ticket/create',
data: _.extend({}, formState, {
departmentId: formState.departmentId + 1
departmentId: SessionStore.getDepartments()[formState.departmentIndex].id
})
}).then(this.onTicketSuccess.bind(this)).catch(this.onTicketFail.bind(this));
}

View File

@ -2,6 +2,7 @@ import React from 'react';
import _ from 'lodash';
import {connect} from 'react-redux';
import SessionActions from 'actions/session-actions';
import TicketViewer from 'app-components/ticket-viewer';
class DashboardTicketPage extends React.Component {
@ -13,7 +14,7 @@ class DashboardTicketPage extends React.Component {
render() {
return (
<div className="dashboard-ticket-page">
<TicketViewer ticket={this.getTicketData()} />
<TicketViewer ticket={this.getTicketData()} onChange={this.retrieveUserData.bind(this)}/>
</div>
);
}
@ -21,6 +22,10 @@ class DashboardTicketPage extends React.Component {
getTicketData() {
return _.find(this.props.tickets, {ticketNumber: this.props.params.ticketNumber});
}
retrieveUserData() {
this.props.dispatch(SessionActions.getUserData());
}
}
export default connect((store) => {

View File

@ -18,6 +18,7 @@ class Button extends React.Component {
static propTypes = {
children: React.PropTypes.node,
size: React.PropTypes.oneOf([
'extra-small',
'small',
'medium',
'large',
@ -76,6 +77,7 @@ class Button extends React.Component {
'button_clean': (this.props.type === 'clean'),
'button_link': (this.props.type === 'link'),
'button_extra-small': (this.props.size === 'extra-small'),
'button_small': (this.props.size === 'small'),
'button_medium': (this.props.size === 'medium'),
'button_large': (this.props.size === 'large'),

View File

@ -47,6 +47,12 @@
}
}
&_extra-small {
text-transform: none;
width: 130px;
height: 30px;
}
&_small {
width: 100px;
height: 47px;

View File

@ -27,7 +27,7 @@
&__list-container {
position: absolute;
width: 150px;
z-index: 5;
z-index: 100;
}
&_closed {

View File

@ -9,9 +9,9 @@ module.exports = [
'language': 'en',
'reCaptchaKey': '6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS',
'departments': [
'Sales Support',
'Technical Issues',
'System and Administration'
{id: 1, name: 'Sales Support'},
{id: 2, name: 'Technical Issues'},
{id: 3, name: 'System and Administration'}
]
}
};

View File

@ -77,5 +77,130 @@ module.exports = [
data: {}
};
}
},
{
path: '/ticket/get',
time: 1000,
response: function () {
return {
status: 'success',
data: {
ticketNumber: '878552',
title: 'Lorem ipsum door',
content: 'I had a problem with the installation of the php server',
department: {
id: 1,
name: 'Sales Support'
},
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
}
}
]
}
};
}
}
];

View File

@ -43,7 +43,7 @@ module.exports = [
return {
status: 'success',
data: {
sessionActive: false
sessionActive: true
}
};
}
@ -140,7 +140,7 @@ module.exports = [
content: 'I had a problem with the installation of the php server',
department: {
id: 2,
name: 'Environment Setup'
name: 'Technical Issues'
},
date: '20160416',
file: 'http://www.opensupports.com/some_file.zip',
@ -158,7 +158,7 @@ module.exports = [
name: 'Steve Jobs',
email: 'steve@jobs.com'
},
actions: [
events: [
{
type: 'ASSIGN',
date: '20150409',
@ -258,8 +258,8 @@ module.exports = [
title: 'Lorem ipsum door',
content: 'I had a problem with the installation of the php server',
department: {
id: 2,
name: 'Environment Setup'
id: 1,
name: 'Sales Support'
},
date: '20160415',
file: 'http://www.opensupports.com/some_file.zip',
@ -274,7 +274,7 @@ module.exports = [
owner: {
name: 'Steve Jobs'
},
actions: [
events: [
{
type: 'ASSIGN',
date: '20150409',
@ -374,8 +374,8 @@ module.exports = [
title: 'Lorem ipsum door',
content: 'I had a problem with the installation of the php server',
department: {
id: 2,
name: 'Environment Setup'
id: 1,
name: 'Sales Support'
},
date: '20150409',
file: 'http://www.opensupports.com/some_file.zip',
@ -390,7 +390,7 @@ module.exports = [
owner: {
name: 'Steve Jobs'
},
actions: [
events: [
{
type: 'ASSIGN',
date: '20150409',

View File

@ -60,6 +60,17 @@ export default {
'DISCARD_CHANGES': 'Discard changes',
'DELETE': 'Delete',
'LANGUAGE': 'Language',
'OWNER': 'Owner',
'OWNED': 'Owned',
'STATUS': 'Status',
'NONE': 'None',
'OPENED': 'Opened',
'CLOSED': 'Closed',
'CLOSE': 'Close',
'RE_OPEN': 'Re open',
'ASSIGN_TO_ME': 'Assign to me',
'UN_ASSIGN': 'Unassign',
'VIEW_TICKET': 'View Ticket',
//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.',
@ -69,6 +80,7 @@ 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',
'TICKET_VIEW_DESCRIPTION': 'This ticket has been sent by a customer. Here you can respond or assign the ticket',
//ERRORS
'EMAIL_OR_PASSWORD': 'Email or password invalid',
@ -82,6 +94,7 @@ export default {
'PASSWORD_NOT_MATCH': 'Password does not match',
'INVALID_RECOVER': 'Invalid recover data',
'TICKET_SENT_ERROR': 'An error occurred while trying to create the ticket.',
'NO_PERMISSION': 'You\'ve no permission to access to this page.',
//MESSAGES
'SIGNUP_SUCCESS': 'You have registered successfully in our support system.',