diff --git a/client/src/app-components/ticket-viewer.js b/client/src/app-components/ticket-viewer.js index 919ad429..182d4718 100644 --- a/client/src/app-components/ticket-viewer.js +++ b/client/src/app-components/ticket-viewer.js @@ -18,7 +18,9 @@ import Button from 'core-components/button'; class TicketViewer extends React.Component { static propTypes = { ticket: React.PropTypes.object, - editable: React.PropTypes.bool + onChange: React.PropTypes.func, + editable: React.PropTypes.bool, + assignmentAllowed: React.PropTypes.bool }; static defaultProps = { @@ -130,6 +132,17 @@ class TicketViewer extends React.Component { 'high': 'HIGH' }; + let ownerNode = null; + if (this.props.assignmentAllowed && _.isEmpty(ticket.owner)) { + ownerNode = ( + + ); + } else { + ownerNode = i18n((ticket.closed) ? 'CLOSED' : 'OPENED'); + } + return (
@@ -155,7 +168,7 @@ class TicketViewer extends React.Component { {(ticket.owner) ? ticket.owner.name : i18n('NONE')}
- {i18n((ticket.closed) ? 'CLOSED' : 'OPENED')} + {ownerNode}
@@ -182,11 +195,11 @@ class TicketViewer extends React.Component { data: { ticketNumber: this.props.ticket.ticketNumber } - }); + }).then(this.onTicketModification.bind(this)); } onCloseClick() { - AreYouSure.openModal(null, this.toggleClose); + AreYouSure.openModal(null, this.toggleClose.bind(this)); } toggleClose() { @@ -195,7 +208,7 @@ class TicketViewer extends React.Component { data: { ticketNumber: this.props.ticket.ticketNumber } - }); + }).then(this.onTicketModification.bind(this)); } changeDepartment(index) { @@ -205,7 +218,7 @@ class TicketViewer extends React.Component { ticketNumber: this.props.ticket.ticketNumber, departmentId: SessionStore.getDepartments()[index].id } - }); + }).then(this.onTicketModification.bind(this)); } changePriority(index) { @@ -221,7 +234,7 @@ class TicketViewer extends React.Component { ticketNumber: this.props.ticket.ticketNumber, priority: priorities[index] } - }); + }).then(this.onTicketModification.bind(this)); } onSubmit(formState) { @@ -241,10 +254,8 @@ class TicketViewer extends React.Component { this.setState({ loading: false }); - - if(this.props.onComment) { - this.props.onComment(); - } + + this.onTicketModification(); } onCommentFail() { @@ -252,6 +263,12 @@ class TicketViewer extends React.Component { loading: false }); } + + onTicketModification() { + if (this.props.onChange) { + this.props.onChange(); + } + } } export default TicketViewer; \ No newline at end of file diff --git a/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js b/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js index a1b2b2bc..141938f9 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js +++ b/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js @@ -1,8 +1,13 @@ 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 { @@ -11,38 +16,56 @@ class AdminPanelViewTicket extends React.Component { ticket: {} }; + componentDidMount() { + this.retrieveTicket(); + } + render() { return ( -
+
+
{(this.state.loading) ? this.renderLoading() : this.renderView()}
); } renderLoading() { - + return ( +
+ +
+ ) }; renderView() { - return (this.props.ticket) ? this.renderNotFoundError() : this.renderTicketView(); + return (_.isEmpty(this.state.ticket)) ? this.renderNoPermissionError() : this.renderTicketView(); } - renderNotFoundError() { + renderNoPermissionError() { return ( -
- +
+ {i18n('NO_PERMISSION')}
); } renderTicketView() { return ( -
- +
+
); } + 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, @@ -54,7 +77,7 @@ class AdminPanelViewTicket extends React.Component { date: { ticketNumber: this.props.params.ticketNumber } - }).then(this.onRetrieveSuccess.bind(this)) + }).then(this.onRetrieveSuccess.bind(this)).catch(this.onRetrieveFail.bind(this)) } onRetrieveSuccess(result) { @@ -63,6 +86,13 @@ class AdminPanelViewTicket extends React.Component { ticket: result.data }); } + + onRetrieveFail() { + this.setState({ + loading: false, + ticket: {} + }); + } } export default AdminPanelViewTicket; \ No newline at end of file diff --git a/client/src/app/admin/panel/tickets/admin-panel-view-ticket.scss b/client/src/app/admin/panel/tickets/admin-panel-view-ticket.scss new file mode 100644 index 00000000..bdb36b07 --- /dev/null +++ b/client/src/app/admin/panel/tickets/admin-panel-view-ticket.scss @@ -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; + } +} \ No newline at end of file diff --git a/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.js b/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.js index 57faa0d2..c6ea17bc 100644 --- a/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.js +++ b/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.js @@ -14,7 +14,7 @@ class DashboardTicketPage extends React.Component { render() { return (
- +
); } diff --git a/client/src/data/fixtures/ticket-fixtures.js b/client/src/data/fixtures/ticket-fixtures.js index f589dd78..3d64bf2b 100644 --- a/client/src/data/fixtures/ticket-fixtures.js +++ b/client/src/data/fixtures/ticket-fixtures.js @@ -77,5 +77,130 @@ module.exports = [ 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 + } + } + ] + } + }; + } } ]; \ No newline at end of file diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index 5f2f4fdd..aa7b778f 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -70,6 +70,7 @@ export default { '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.', @@ -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.', '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', @@ -92,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.',