mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-31 01:35:15 +02:00
Ivan - Add ticket view to admin dashboard [skip ci]
This commit is contained in:
parent
9b83fde4fc
commit
bcb83e52b6
@ -18,7 +18,9 @@ import Button from 'core-components/button';
|
|||||||
class TicketViewer extends React.Component {
|
class TicketViewer extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
ticket: React.PropTypes.object,
|
ticket: React.PropTypes.object,
|
||||||
editable: React.PropTypes.bool
|
onChange: React.PropTypes.func,
|
||||||
|
editable: React.PropTypes.bool,
|
||||||
|
assignmentAllowed: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@ -130,6 +132,17 @@ class TicketViewer extends React.Component {
|
|||||||
'high': 'HIGH'
|
'high': 'HIGH'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let ownerNode = null;
|
||||||
|
if (this.props.assignmentAllowed && _.isEmpty(ticket.owner)) {
|
||||||
|
ownerNode = (
|
||||||
|
<Button type="secondary" size="extra-small" onClick={this.onAssignClick.bind(this)}>
|
||||||
|
{i18n('ASSIGN_TO_ME')}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
ownerNode = i18n((ticket.closed) ? 'CLOSED' : 'OPENED');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ticket-viewer__headers">
|
<div className="ticket-viewer__headers">
|
||||||
<div className="ticket-viewer__info-row-header row">
|
<div className="ticket-viewer__info-row-header row">
|
||||||
@ -155,7 +168,7 @@ class TicketViewer extends React.Component {
|
|||||||
{(ticket.owner) ? ticket.owner.name : i18n('NONE')}
|
{(ticket.owner) ? ticket.owner.name : i18n('NONE')}
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-4">
|
<div className="col-md-4">
|
||||||
{i18n((ticket.closed) ? 'CLOSED' : 'OPENED')}
|
{ownerNode}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -182,11 +195,11 @@ class TicketViewer extends React.Component {
|
|||||||
data: {
|
data: {
|
||||||
ticketNumber: this.props.ticket.ticketNumber
|
ticketNumber: this.props.ticket.ticketNumber
|
||||||
}
|
}
|
||||||
});
|
}).then(this.onTicketModification.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
onCloseClick() {
|
onCloseClick() {
|
||||||
AreYouSure.openModal(null, this.toggleClose);
|
AreYouSure.openModal(null, this.toggleClose.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleClose() {
|
toggleClose() {
|
||||||
@ -195,7 +208,7 @@ class TicketViewer extends React.Component {
|
|||||||
data: {
|
data: {
|
||||||
ticketNumber: this.props.ticket.ticketNumber
|
ticketNumber: this.props.ticket.ticketNumber
|
||||||
}
|
}
|
||||||
});
|
}).then(this.onTicketModification.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
changeDepartment(index) {
|
changeDepartment(index) {
|
||||||
@ -205,7 +218,7 @@ class TicketViewer extends React.Component {
|
|||||||
ticketNumber: this.props.ticket.ticketNumber,
|
ticketNumber: this.props.ticket.ticketNumber,
|
||||||
departmentId: SessionStore.getDepartments()[index].id
|
departmentId: SessionStore.getDepartments()[index].id
|
||||||
}
|
}
|
||||||
});
|
}).then(this.onTicketModification.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
changePriority(index) {
|
changePriority(index) {
|
||||||
@ -221,7 +234,7 @@ class TicketViewer extends React.Component {
|
|||||||
ticketNumber: this.props.ticket.ticketNumber,
|
ticketNumber: this.props.ticket.ticketNumber,
|
||||||
priority: priorities[index]
|
priority: priorities[index]
|
||||||
}
|
}
|
||||||
});
|
}).then(this.onTicketModification.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit(formState) {
|
onSubmit(formState) {
|
||||||
@ -241,10 +254,8 @@ class TicketViewer extends React.Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
|
|
||||||
if(this.props.onComment) {
|
this.onTicketModification();
|
||||||
this.props.onComment();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onCommentFail() {
|
onCommentFail() {
|
||||||
@ -252,6 +263,12 @@ class TicketViewer extends React.Component {
|
|||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onTicketModification() {
|
||||||
|
if (this.props.onChange) {
|
||||||
|
this.props.onChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TicketViewer;
|
export default TicketViewer;
|
@ -1,8 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
import API from 'lib-app/api-call';
|
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 TicketViewer from 'app-components/ticket-viewer';
|
||||||
import Loading from 'core-components/loading';
|
import Loading from 'core-components/loading';
|
||||||
|
import Header from 'core-components/header';
|
||||||
|
|
||||||
class AdminPanelViewTicket extends React.Component {
|
class AdminPanelViewTicket extends React.Component {
|
||||||
|
|
||||||
@ -11,38 +16,56 @@ class AdminPanelViewTicket extends React.Component {
|
|||||||
ticket: {}
|
ticket: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.retrieveTicket();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="admin-panel-view-ticket">
|
||||||
|
<Header title={i18n('VIEW_TICKET')} description={i18n('TICKET_VIEW_DESCRIPTION')} />
|
||||||
{(this.state.loading) ? this.renderLoading() : this.renderView()}
|
{(this.state.loading) ? this.renderLoading() : this.renderView()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLoading() {
|
renderLoading() {
|
||||||
|
return (
|
||||||
|
<div className="admin-panel-view-ticket__loading">
|
||||||
|
<Loading size="large" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
renderView() {
|
renderView() {
|
||||||
return (this.props.ticket) ? this.renderNotFoundError() : this.renderTicketView();
|
return (_.isEmpty(this.state.ticket)) ? this.renderNoPermissionError() : this.renderTicketView();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderNotFoundError() {
|
renderNoPermissionError() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="admin-panel-view-ticket__error">
|
||||||
|
{i18n('NO_PERMISSION')}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTicketView() {
|
renderTicketView() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="admin-panel-view-ticket__ticket-view">
|
||||||
|
<TicketViewer {...this.getTicketViewProps()} />
|
||||||
</div>
|
</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() {
|
retrieveTicket() {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: true,
|
loading: true,
|
||||||
@ -54,7 +77,7 @@ class AdminPanelViewTicket extends React.Component {
|
|||||||
date: {
|
date: {
|
||||||
ticketNumber: this.props.params.ticketNumber
|
ticketNumber: this.props.params.ticketNumber
|
||||||
}
|
}
|
||||||
}).then(this.onRetrieveSuccess.bind(this))
|
}).then(this.onRetrieveSuccess.bind(this)).catch(this.onRetrieveFail.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
onRetrieveSuccess(result) {
|
onRetrieveSuccess(result) {
|
||||||
@ -63,6 +86,13 @@ class AdminPanelViewTicket extends React.Component {
|
|||||||
ticket: result.data
|
ticket: result.data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onRetrieveFail() {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
ticket: {}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AdminPanelViewTicket;
|
export default AdminPanelViewTicket;
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ class DashboardTicketPage extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="dashboard-ticket-page">
|
<div className="dashboard-ticket-page">
|
||||||
<TicketViewer ticket={this.getTicketData()} onComment={this.retrieveUserData.bind(this)}/>
|
<TicketViewer ticket={this.getTicketData()} onChange={this.retrieveUserData.bind(this)}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -77,5 +77,130 @@ module.exports = [
|
|||||||
data: {}
|
data: {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/ticket/get',
|
||||||
|
time: 1000,
|
||||||
|
response: function () {
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
data: {
|
||||||
|
ticketNumber: '118551',
|
||||||
|
title: 'Lorem ipsum door',
|
||||||
|
content: 'I had a problem with the installation of the php server',
|
||||||
|
department: {
|
||||||
|
id: 1,
|
||||||
|
name: 'Sales Support'
|
||||||
|
},
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
@ -70,6 +70,7 @@ export default {
|
|||||||
'RE_OPEN': 'Re open',
|
'RE_OPEN': 'Re open',
|
||||||
'ASSIGN_TO_ME': 'Assign to me',
|
'ASSIGN_TO_ME': 'Assign to me',
|
||||||
'UN_ASSIGN': 'Unassign',
|
'UN_ASSIGN': 'Unassign',
|
||||||
|
'VIEW_TICKET': 'View Ticket',
|
||||||
|
|
||||||
//VIEW DESCRIPTIONS
|
//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.',
|
'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.',
|
||||||
@ -79,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.',
|
'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.',
|
'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',
|
'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
|
//ERRORS
|
||||||
'EMAIL_OR_PASSWORD': 'Email or password invalid',
|
'EMAIL_OR_PASSWORD': 'Email or password invalid',
|
||||||
@ -92,6 +94,7 @@ export default {
|
|||||||
'PASSWORD_NOT_MATCH': 'Password does not match',
|
'PASSWORD_NOT_MATCH': 'Password does not match',
|
||||||
'INVALID_RECOVER': 'Invalid recover data',
|
'INVALID_RECOVER': 'Invalid recover data',
|
||||||
'TICKET_SENT_ERROR': 'An error occurred while trying to create the ticket.',
|
'TICKET_SENT_ERROR': 'An error occurred while trying to create the ticket.',
|
||||||
|
'NO_PERMISSION': 'You\'ve no permission to access to this page.',
|
||||||
|
|
||||||
//MESSAGES
|
//MESSAGES
|
||||||
'SIGNUP_SUCCESS': 'You have registered successfully in our support system.',
|
'SIGNUP_SUCCESS': 'You have registered successfully in our support system.',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user