Ivan - Fixes for Deploy

This commit is contained in:
ivan 2016-11-20 23:01:38 -03:00
parent 79dcbe030e
commit 9aceff4313
15 changed files with 82 additions and 40 deletions

View File

@ -32,7 +32,7 @@ export default {
}; };
}, },
retrieveAllTickets(page) { retrieveAllTickets(page = 1) {
return { return {
type: 'ALL_TICKETS', type: 'ALL_TICKETS',
payload: API.call({ payload: API.call({
@ -42,7 +42,7 @@ export default {
}; };
}, },
searchTickets(query, page) { searchTickets(query, page = 1) {
return { return {
type: 'ALL_TICKETS', type: 'ALL_TICKETS',
payload: API.call({ payload: API.call({

View File

@ -161,7 +161,7 @@ class TicketList extends React.Component {
} }
gerTicketTableObject(ticket) { gerTicketTableObject(ticket) {
let titleText = (ticket.unread) ? ticket.title + ' (1)' : ticket.title; let titleText = (this.isTicketUnread(ticket)) ? ticket.title + ' (1)' : ticket.title;
return { return {
number: ( number: (
@ -178,8 +178,8 @@ class TicketList extends React.Component {
department: ticket.department.name, department: ticket.department.name,
author: ticket.author.name, author: ticket.author.name,
date: DateTransformer.transformToString(ticket.date), date: DateTransformer.transformToString(ticket.date),
unread: ticket.unread, unread: this.isTicketUnread(ticket),
highlighted: ticket.unread highlighted: this.isTicketUnread(ticket)
}; };
} }
@ -231,6 +231,10 @@ class TicketList extends React.Component {
} }
return row1.closed ? -1 : 1; return row1.closed ? -1 : 1;
} }
isTicketUnread(ticket) {
return (this.props.type === 'primary' && ticket.unread) || (this.props.type === 'secondary' && ticket.unreadStaff);
}
} }

View File

@ -18,6 +18,10 @@
text-align: right; text-align: right;
} }
&__author {
text-align: center;
}
&__date { &__date {
text-align: right; text-align: right;
} }

View File

@ -54,16 +54,7 @@ class TicketViewer extends React.Component {
<div className="ticket-viewer__comments"> <div className="ticket-viewer__comments">
{ticket.events && ticket.events.map(this.renderTicketEvent.bind(this))} {ticket.events && ticket.events.map(this.renderTicketEvent.bind(this))}
</div> </div>
<div className="ticket-viewer__response"> {(!this.props.ticket.closed && (this.props.editable || !this.props.assignmentAllowed)) ? this.renderResponseField() : null}
<div className="ticket-viewer__response-title row">{i18n('RESPOND')}</div>
{this.renderCustomResponses()}
<div className="ticket-viewer__response-field row">
<Form {...this.getCommentFormProps()}>
<FormField name="content" validation="TEXT_AREA" required field="textarea" />
<SubmitButton>{i18n('RESPOND_TICKET')}</SubmitButton>
</Form>
</div>
</div>
</div> </div>
); );
} }
@ -173,7 +164,7 @@ class TicketViewer extends React.Component {
</Button> </Button>
); );
} else { } else {
ownerNode = i18n((this.props.closed) ? 'CLOSED' : 'OPENED'); ownerNode = i18n((this.props.ticket.closed) ? 'CLOSED' : 'OPENED');
} }
return ownerNode; return ownerNode;
@ -185,6 +176,21 @@ class TicketViewer extends React.Component {
); );
} }
renderResponseField() {
return (
<div className="ticket-viewer__response">
<div className="ticket-viewer__response-title row">{i18n('RESPOND')}</div>
{this.renderCustomResponses()}
<div className="ticket-viewer__response-field row">
<Form {...this.getCommentFormProps()}>
<FormField name="content" validation="TEXT_AREA" required field="textarea" />
<SubmitButton>{i18n('RESPOND_TICKET')}</SubmitButton>
</Form>
</div>
</div>
);
}
renderCustomResponses() { renderCustomResponses() {
let customResponsesNode = null; let customResponsesNode = null;

View File

@ -52,7 +52,11 @@ class AdminPanelAllTickets extends React.Component {
onSearch(query) { onSearch(query) {
this.setState({query, page: 1}); this.setState({query, page: 1});
this.props.dispatch(AdminDataAction.searchTickets(query)); if (query) {
this.props.dispatch(AdminDataAction.searchTickets(query));
} else {
this.props.dispatch(AdminDataAction.retrieveAllTickets());
}
} }
onPageChange(event) { onPageChange(event) {

View File

@ -153,7 +153,7 @@ class AdminPanelCustomResponses extends React.Component {
API.call({ API.call({
path: '/ticket/edit-custom-response', path: '/ticket/edit-custom-response',
data: { data: {
id: this.state.selectedIndex, id: this.props.items[this.state.selectedIndex].id,
name: form.name, name: form.name,
content: form.content, content: form.content,
language: form.language language: form.language
@ -161,7 +161,7 @@ class AdminPanelCustomResponses extends React.Component {
}).then(() => { }).then(() => {
this.setState({formLoading: false}); this.setState({formLoading: false});
this.retrieveCustomResponses(); this.retrieveCustomResponses();
}); }).catch(this.onItemChange.bind(this, -1));
} else { } else {
API.call({ API.call({
path: '/ticket/add-custom-response', path: '/ticket/add-custom-response',
@ -171,17 +171,19 @@ class AdminPanelCustomResponses extends React.Component {
language: form.language language: form.language
} }
}).then(() => { }).then(() => {
this.setState({formLoading: false});
this.retrieveCustomResponses(); this.retrieveCustomResponses();
}); this.onItemChange(-1);
}).catch(this.onItemChange.bind(this, -1));
} }
} }
onDiscardChangesClick() { onDiscardChangesClick(event) {
event.preventDefault();
this.onItemChange(this.state.selectedIndex); this.onItemChange(this.state.selectedIndex);
} }
onDeleteClick() { onDeleteClick(event) {
event.preventDefault();
AreYouSure.openModal(i18n('WILL_DELETE_CUSTOM_RESPONSE'), this.deleteCustomResponse.bind(this)); AreYouSure.openModal(i18n('WILL_DELETE_CUSTOM_RESPONSE'), this.deleteCustomResponse.bind(this));
} }
@ -189,9 +191,12 @@ class AdminPanelCustomResponses extends React.Component {
API.call({ API.call({
path: '/ticket/delete-custom-response', path: '/ticket/delete-custom-response',
data: { data: {
id: this.state.selectedIndex id: this.props.items[this.state.selectedIndex].id
} }
}).then(this.retrieveCustomResponses.bind(this)); }).then(() => {
this.retrieveCustomResponses();
this.onItemChange(-1);
});
} }
updateForm(index) { updateForm(index) {
@ -204,6 +209,7 @@ class AdminPanelCustomResponses extends React.Component {
this.setState({ this.setState({
selectedIndex: index, selectedIndex: index,
edited: false, edited: false,
formLoading: false,
form: form, form: form,
errors: {} errors: {}
}); });
@ -211,6 +217,9 @@ class AdminPanelCustomResponses extends React.Component {
retrieveCustomResponses() { retrieveCustomResponses() {
this.props.dispatch(AdminDataActions.retrieveCustomResponses()); this.props.dispatch(AdminDataActions.retrieveCustomResponses());
this.setState({
edited: false
});
} }
} }

View File

@ -64,7 +64,7 @@ class AdminPanelViewTicket extends React.Component {
onChange: this.retrieveTicket.bind(this), onChange: this.retrieveTicket.bind(this),
assignmentAllowed: true, assignmentAllowed: true,
customResponses: this.props.customResponses, customResponses: this.props.customResponses,
editable: _.get(this.state.ticket, 'owner.id') === SessionStore.getUserData().id editable: this.state.ticket.owner && this.state.ticket.owner.id == SessionStore.getSessionData().userId
}; };
} }
@ -89,7 +89,7 @@ class AdminPanelViewTicket extends React.Component {
data: { data: {
ticketNumber: this.props.params.ticketNumber ticketNumber: this.props.params.ticketNumber
} }
}) });
} }
} }

View File

@ -23,6 +23,8 @@ class DashboardTicketPage extends React.Component {
data: { data: {
ticketNumber: ticket.ticketNumber ticketNumber: ticket.ticketNumber
} }
}).then(() => {
this.retrieveUserData();
}); });
} }
} }

View File

@ -5,6 +5,8 @@ DataValidator::with('CustomValidations', true);
class TicketGetController extends Controller { class TicketGetController extends Controller {
const PATH = '/get'; const PATH = '/get';
private $ticket;
public function validations() { public function validations() {
return [ return [
'permission' => 'user', 'permission' => 'user',
@ -18,14 +20,19 @@ class TicketGetController extends Controller {
} }
public function handler() { public function handler() {
$ticketNumber = Controller::request('ticketNumber'); $this->ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
$ticket = Ticket::getByTicketNumber($ticketNumber); if ($this->shouldDenyPermission()) {
Response::respondError(ERRORS::NO_PERMISSION);
if ($ticket->author->id != Controller::getLoggedUser()->id) {
Response::respondError(ERRORS::INVALID_TICKET);
} else { } else {
Response::respondSuccess($ticket->toArray()); Response::respondSuccess($this->ticket->toArray());
} }
} }
private function shouldDenyPermission() {
$user = Controller::getLoggedUser();
return (!Controller::isStaffLogged() && $this->ticket->author->id !== $user->id) ||
(Controller::isStaffLogged() && $this->ticket->owner && $this->ticket->owner->id !== $user->id);
}
} }

View File

@ -13,6 +13,7 @@ class CustomResponse extends DataStore {
public function toArray() { public function toArray() {
return [ return [
'id' => $this->id,
'name' => $this->name, 'name' => $this->name,
'language' => $this->language, 'language' => $this->language,
'content' => $this->content, 'content' => $this->content,

View File

@ -16,7 +16,10 @@ class Department extends DataStore {
$departmentsNameList = []; $departmentsNameList = [];
foreach($departmentsList as $department) { foreach($departmentsList as $department) {
$departmentsNameList[] = $department->name; $departmentsNameList[] = [
'id' => $department->id,
'name' => $department->name
];
} }
return $departmentsNameList; return $departmentsNameList;

View File

@ -74,6 +74,7 @@ class Ticket extends DataStore {
'file' => $this->file, 'file' => $this->file,
'language' => $this->language, 'language' => $this->language,
'unread' => !!$this->unread, 'unread' => !!$this->unread,
'unreadStaff' => !!$this->unreadStaff,
'closed' => !!$this->closed, 'closed' => !!$this->closed,
'priority' => $this->priority, 'priority' => $this->priority,
'author' => $this->authorToArray(), 'author' => $this->authorToArray(),
@ -106,7 +107,7 @@ class Ticket extends DataStore {
'email' => $owner->email 'email' => $owner->email
]; ];
} else { } else {
return []; return null;
} }
} }
@ -128,6 +129,7 @@ class Ticket extends DataStore {
'id'=> $author->id, 'id'=> $author->id,
'name' => $author->name, 'name' => $author->name,
'email' =>$author->email, 'email' =>$author->email,
'profilePic' => ($author instanceof Staff) ? $author->profilePic : null,
'staff' => $author instanceof Staff 'staff' => $author instanceof Staff
]; ];
} }

View File

@ -4,8 +4,8 @@ describe '/system/get-settings' do
(result['status']).should.equal('success') (result['status']).should.equal('success')
(result['data']['language']).should.equal('en') (result['data']['language']).should.equal('en')
(result['data']['departments'][0]).should.equal('Tech Support') (result['data']['departments'][0]['name']).should.equal('Tech Support')
(result['data']['departments'][1]).should.equal('Suggestions') (result['data']['departments'][1]['name']).should.equal('Suggestions')
(result['data']['departments'][2]).should.equal('Sales and Subscriptions') (result['data']['departments'][2]['name']).should.equal('Sales and Subscriptions')
end end
end end

View File

@ -75,7 +75,7 @@ describe '/ticket/get/' do
(result['data']['unread']).should.equal(false) (result['data']['unread']).should.equal(false)
(result['data']['author']['name']).should.equal('Cersei Lannister') (result['data']['author']['name']).should.equal('Cersei Lannister')
(result['data']['author']['email']).should.equal('cersei@os4.com') (result['data']['author']['email']).should.equal('cersei@os4.com')
(result['data']['owner']).should.equal([]) (result['data']['owner']).should.equal(nil)
(result['data']['events'].size).should.equal(1) (result['data']['events'].size).should.equal(1)
(result['data']['events'][0]['type']).should.equal('COMMENT') (result['data']['events'][0]['type']).should.equal('COMMENT')
(result['data']['events'][0]['content']).should.equal('some valid comment made') (result['data']['events'][0]['content']).should.equal('some valid comment made')

View File

@ -51,7 +51,7 @@ describe '/user/get' do
(ticketFromUser['unread']).should.equal(false) (ticketFromUser['unread']).should.equal(false)
(ticketFromUser['author']['name']).should.equal('User Get') (ticketFromUser['author']['name']).should.equal('User Get')
(ticketFromUser['author']['email']).should.equal('user_get@os4.com') (ticketFromUser['author']['email']).should.equal('user_get@os4.com')
(ticketFromUser['owner']).should.equal([]) (ticketFromUser['owner']).should.equal(nil)
(ticketFromUser['events']).should.equal([]) (ticketFromUser['events']).should.equal([])
end end
end end