diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index e4fdafcc25a8a72fa2d0eb0cb721eebafd5feae5..9c13bd5e4affb8cb17d6e5e7c42cc428509f1d4f 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -695,5 +695,274 @@ class TicketsAjaxAPI extends AjaxController { return $canned->getFormattedResponse($format, $varReplacer); } + + function changeTicketStatus($tid, $status) { + global $thisstaff; + + if (!$thisstaff) + Http::response(403, 'Access denied'); + elseif (!$tid + || !($ticket=Ticket::lookup($tid)) + || !$ticket->checkStaffAccess($thisstaff)) + Http::response(404, 'Unknown ticket #'); + + $info = array(); + switch($status) { + case 'open': + case 'reopen': + $state = 'open'; + $info['title'] = __('Reopen'); + break; + case 'resolve': + $state = 'resolved'; + $info['title'] = __('Resolve'); + break; + case 'close': + if (!$thisstaff->canCloseTickets()) + Http::response(403, 'Access denied'); + $state = 'closed'; + $info['title'] = __('Close'); + break; + case 'archive': + if (!$thisstaff->canCloseTickets()) + Http::response(403, 'Access denied'); + + $state = 'archived'; + $info['title'] = __('Archive'); + break; + case 'delete': + if (!$thisstaff->canDeleteTickets()) + Http::response(403, 'Access denied'); + $state = 'deleted'; + $info = array( + 'title' => __('Delete'), + 'warn' => sprintf(__('Are you sure you want to DELETE %s?'), + __('this ticket')), + //TODO: remove message below once we ship data retention plug + 'extra' => sprintf('<strong>%s</strong>', + __('Deleted tickets CANNOT be recovered, + including any associated attachments.'))); + break; + default: + Http::response(404, 'Unknown status/action'); + } + + $info['action'] = sprintf('#tickets/%d/status/%s', $ticket->getId(), $status); + $info['title'] .= sprintf(' %s #%s', __('Ticket'), $ticket->getNumber()); + $info['status_id'] = $_REQUEST['status_id'] ?: $ticket->getStatusId(); + + return self::_setStatus($state, $info); + } + + function setTicketStatus($tid, $state) { + global $thisstaff, $ost; + + if (!$thisstaff) + Http::response(403, 'Access denied'); + elseif (!$tid + || !($ticket=Ticket::lookup($tid)) + || !$ticket->checkStaffAccess($thisstaff)) + Http::response(404, 'Unknown ticket #'); + + if (!($status= TicketStatus::lookup($_REQUEST['status_id']))) + $errors['status_id'] = sprintf('%s %s', + __('Unknown or invalid'), __('status')); + elseif (!$errors) { + // Make sure the agent has permission to set the status + switch(mb_strtolower($status->getState())) { + case 'open': + if (!$thisstaff->canCloseTickets() + && !$thisstaff->canCreateTickets()) + $errors['err'] = sprintf(__('You do not have + permission to %s.'), + __('reopen tickets')); + break; + case 'resolved': + case 'closed': + if (!$thisstaff->canCloseTickets()) + $errors['err'] = sprintf(__('You do not have + permission to %s.'), + __('resolve/close tickets')); + break; + case 'archived': + case 'deleted': + if (!$thisstaff->canDeleteTickets()) + $errors['err'] = sprintf(__('You do not have + permission to %s.'), + __('archive/delete tickets')); + break; + } + } + + if ($ticket->setStatus($status, $_REQUEST['comments'])) { + $_SESSION['::sysmsgs']['msg'] = sprintf( + __('Successfully updated status to %s'), + $status->getName()); + Http::response(201, 'Successfully processed'); + } + + $errors['err'] = __('Error updating ticket status'); + $info['errors'] = $errors; + return self::_setStatus($state, $info); + } + function changeTicketsStatus($status, $id=0) { + global $thisstaff, $cfg; + + if (!$thisstaff) + Http::response(403, 'Access denied'); + + $state = null; + $info = array(); + switch($status) { + case 'open': + case 'reopen': + $state = 'open'; + $info = array( + 'title' => sprintf('%s %s', + __('Reopen'), __('Tickets')) + ); + break; + case 'resolve': + $state = 'resolved'; + $info = array( + 'title' => sprintf('%s %s', + __('Resolve'), __('Tickets')) + ); + break; + case 'close': + if (!$thisstaff->canCloseTickets()) + Http::response(403, 'Access denied'); + $state = 'closed'; + $info = array( + 'title' => sprintf('%s %s', + __('Close'), __('Tickets')) + ); + break; + case 'archive': + if (!$thisstaff->canCloseTickets()) + Http::response(403, 'Access denied'); + + $state = 'archived'; + $info = array( + 'title' => sprintf('%s %s', + __('Archive'), __('Tickets')), + ); + break; + case 'delete': + if (!$thisstaff->canDeleteTickets()) + Http::response(403, 'Access denied'); + + $state = 'deleted'; + $info = array( + 'title' => sprintf('%s %s', + __('Delete'), __('Tickets')), + 'warn' => sprintf(__('Are you sure you want to DELETE %s?'), + _N('selected ticket', 'selected tickets', $_REQUEST['count'])), + //TODO: remove message below once we ship data retention plug + 'extra' => sprintf('<strong>%s</strong>', + __('Deleted tickets CANNOT be recovered, + including any associated attachments.'))); + break; + default: + Http::response(404, 'Unknown status/action'); + } + + if ($_REQUEST['count']) + $info['title'] .= sprintf(' — %d selected', $_REQUEST['count']); + + $info['status_id'] = $id; + + return self::_setStatus($state, $info); + } + + function setTicketsStatus($state) { + global $thisstaff, $ost; + + $errors = array(); + if (!$thisstaff || !$thisstaff->canManageTickets()) + $errors['err']=__('You do not have permission to mass manage tickets. Contact admin for such access'); + elseif (!$_REQUEST['tids'] || !count($_REQUEST['tids'])) + $errors['err']=sprintf(__('You must select at least %s.'), + __('one ticket')); + elseif (!($status= TicketStatus::lookup($_REQUEST['status_id']))) + $errors['status_id'] = sprintf('%s %s', + __('Unknown or invalid'), __('status')); + elseif (!$errors) { + // Make sure the agent has permission to set the status + switch(mb_strtolower($status->getState())) { + case 'open': + if (!$thisstaff->canCloseTickets() + && !$thisstaff->canCreateTickets()) + $errors['err'] = sprintf(__('You do not have + permission to %s.'), + __('reopen tickets')); + break; + case 'resolved': + case 'closed': + if (!$thisstaff->canCloseTickets()) + $errors['err'] = sprintf(__('You do not have + permission to %s.'), + __('resolve/close tickets')); + break; + case 'archived': + case 'deleted': + if (!$thisstaff->canDeleteTickets()) + $errors['err'] = sprintf(__('You do not have + permission to %s.'), + __('archive/delete tickets')); + break; + } + } + + if (!$errors) { + $i = 0; + $count = count($_REQUEST['tids']); + $comments = $_REQUEST['comments']; + foreach ($_REQUEST['tids'] as $tid) { + if (($ticket=Ticket::lookup($tid)) + && $ticket->getStatusId() != $status->getId() + && $ticket->checkStaffAccess($thisstaff) + && $ticket->setStatus($status, $comments)) + $i++; + } + + if (!$i) + $errors['err'] = sprintf(__('Unable to set status for %s'), + _N('selected ticket', 'selected tickets', $count)); + else { + // Assume success + if ($i==$count) { + $_SESSION['::sysmsgs']['msg'] = sprintf( + __('Successfully updated %s status to %s'), + _N('selected ticket', 'selected tickets', + $count), + $status->getName()); + } else { + $_SESSION['::sysmsgs']['warn'] = sprintf( + __('%1$d of %2$d %3$s status updated to %4$s'),$i, $count, + _N('selected ticket', 'selected tickets', + $count), + $status->getName()); + } + + Http::response(201, 'Successfully processed'); + } + } + + $info['errors'] = $errors; + return self::_setStatus($state, $info); + } + + function _setStatus($state, $info=array()) { + + $errors = array(); + if ($info && isset($info['errors'])) + $errors = $info['errors']; + + if (!$info['error'] && isset($errors['err'])) + $info['error'] = $errors['err']; + + include(STAFFINC_DIR . 'templates/ticket-status.tmpl.php'); + } } ?> diff --git a/include/class.list.php b/include/class.list.php index 326afa828fe7c96a5a005de687d755fbefde0834..03ac2a2d1fde3fb20b2ee7e55548da1614bd5ae3 100644 --- a/include/class.list.php +++ b/include/class.list.php @@ -999,9 +999,9 @@ class TicketStatus extends VerySimpleModel implements CustomListItem { return $status; } -} - - - + static function options() { + include(STAFFINC_DIR . 'templates/status-options.tmpl.php'); + } +} ?> diff --git a/include/staff/templates/status-options.tmpl.php b/include/staff/templates/status-options.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..5b383e31d46a4ecf97b91e46ff7fd9990deb2035 --- /dev/null +++ b/include/staff/templates/status-options.tmpl.php @@ -0,0 +1,71 @@ +<?php +$actions= array( + 'delete' => array( + 'action' => __('Delete'), + 'icon' => 'icon-trash', + 'states' => array('deleted'), + ), + 'archive' => array( + 'action' => __('Archive'), + 'icon' => 'icon-archive', + 'states' => array('archived') + ), + 'close' => array( + 'action' => __('Close'), + 'icon' => 'icon-repeat', + 'states' => array('closed') + ), + 'resolve' => array( + 'action' => __('Resolve'), + 'icon' => 'icon-ok-circle', + 'states' => array('resolved') + ), + 'reopen' => array( + 'action' => __('Reopen'), + 'icon' => 'icon-undo', + 'states' => array('open') + ), + ); + +foreach($actions as $k => $v) { + $criteria = array('states' => $v['states']); + if (!($statuses = TicketStatusList::getStatuses($criteria)->all())) + continue; + + if ($statuses && count($statuses) > 1) { + ?> + <span + class="action-button" + data-dropdown="#action-dropdown-<?php echo $k; ?>"> + <a id="tickets-<?php echo $k; ?>" + class="tickets-action" + href="#tickets/status/<?php echo $k; ?>"><i + class="<?php echo $v['icon']; ?>"></i> <?php echo $v['action']; ?></a> + <i class="icon-caret-down"></i> + </span> + <div id="action-dropdown-<?php echo $k; ?>" + class="action-dropdown anchor-right"> + <ul> + <?php + foreach ($statuses as $s) { + ?> + + <li> + <a class="no-pjax tickets-action" + href="#tickets/status/<?php echo $k; ?>/<?php + echo $s->getId(); ?>"> <i + class="icon-tag"></i> <?php echo $s->getName(); ?></a> </li> + <?php + } ?> + </ul> + </div> + <?php + } else { + ?> + <a id="tickets-<?php echo $k; ?>" class="action-button tickets-action" + href="#tickets/status/<?php echo $k; ?>"><i + class="<?php echo $v['icon']; ?>"></i> <?php echo $v['action']; ?></a> +<?php + } +} +?> diff --git a/include/staff/templates/ticket-status.tmpl.php b/include/staff/templates/ticket-status.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..6703ca1b017cfb5bf69710062ae923ffdbad78ba --- /dev/null +++ b/include/staff/templates/ticket-status.tmpl.php @@ -0,0 +1,116 @@ +<?php +global $cfg; + +if (!$info['title']) + $info['title'] = 'Change Tickets Status'; + +?> +<h3><?php echo $info['title']; ?></h3> +<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b> +<div class="clear"></div> +<hr/> +<?php +if ($info['error']) { + echo sprintf('<p id="msg_error">%s</p>', $info['error']); +} elseif ($info['warn']) { + echo sprintf('<p id="msg_warning">%s</p>', $info['warn']); +} elseif ($info['msg']) { + echo sprintf('<p id="msg_notice">%s</p>', $info['msg']); +} elseif ($info['notice']) { + echo sprintf('<p id="msg_info"><i class="icon-info-sign"></i> %s</p>', + $info['notice']); +} + + +$action = $info['action'] ?: ('#tickets/status/'. $state); +?> +<div id="ticket-status" style="display:block; margin:5px;"> + <form method="post" name="status" id="status" + action="<?php echo $action; ?>"> + <table width="100%"> + <?php + if ($info['extra']) { + ?> + <tbody> + <tr><td colspan="2"><strong><?php echo $info['extra']; + ?></strong></td> </tr> + <tr><td colspan="2"> </td></tr> + </tbody> + <?php + } + if ($state) + $statuses = TicketStatusList::getStatuses(array('states'=>array($state)))->all(); + + if ($statuses) { + ?> + <tbody> + <tr> + <td colspan=2> + <span> + <?php echo __('Status') ?>: + <?php + if (count($statuses) > 1) { ?> + <select name="status_id"> + <?php + foreach ($statuses as $s) { + echo sprintf('<option value="%d" %s>%s</option>', + $s->getId(), + ($info['status_id'] == $s->getId()) + ? 'selected="selected"' : '', + $s->getName() + ); + } + ?> + </select> + <font class="error">* <?php echo $errors['status_id']; ?></font> + <?php + } elseif ($statuses[0]) { + echo __($statuses[0]->getName()); + echo "<input type='hidden' name='status_id' value={$statuses[0]->getId()} />"; + } ?> + </span> + </td> + </tr> + </tbody> + <?php + } ?> + <tbody> + <tr> + <td colspan="2"> + <em>Reasons for status change (internal note): Optional but highly recommended.</em> + </td> + </tr> + <tr> + <td colspan="2"> + <textarea name="comments" id="comments" + cols="50" rows="3" wrap="soft" style="width:100%" + class="richtext ifhtml no-bar"><?php + echo $info['notes']; ?></textarea> + </td> + </tr> + </tbody> + </table> + <hr> + <p class="full-width"> + <span class="buttons" style="float:left"> + <input type="reset" value="<?php echo __('Reset'); ?>"> + <input type="button" name="cancel" class="close" + value="<?php echo __('Cancel'); ?>"> + </span> + <span class="buttons" style="float:right"> + <input type="submit" value="<?php echo __('Submit'); ?>"> + </span> + </p> + </form> +</div> +<div class="clear"></div> +<script type="text/javascript"> +$(function() { + // Copy checked tickets to status form. + $('form#tickets input[name="tids[]"]:checkbox:checked') + .clone() + .prop('type', 'hidden') + .removeAttr('class') + .appendTo('form#status'); + }); +</script> diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index 07c57c2678658728f7568bfcee663d0ed4a17d8a..cd0099386886315d69f03eff4c5ef922cf19effe 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -56,17 +56,17 @@ if($ticket->isOverdue()) </span> <?php } - if ($thisstaff->canDeleteTickets()) { ?> - <a id="ticket-delete" class="action-button confirm-action" href="#delete"><i class="icon-trash"></i> <?php - echo __('Delete'); ?></a> - <?php - } if($thisstaff->canCloseTickets()) { if($ticket->isOpen()) {?> - <a id="ticket-close" class="action-button" href="#close"><i class="icon-remove-circle"></i> <?php echo __('Close');?></a> + <a class="action-button ticket-action" + href="#tickets/<?php echo $ticket->getId() + ?>/status/close"><i class="icon-remove-circle"></i> <?php echo __('Close');?></a> <?php } else { ?> - <a id="ticket-reopen" class="action-button" href="#reopen"><i class="icon-undo"></i> <?php echo __('Reopen');?></a> + <a class="action-button ticket-action" + href="#tickets/<?php echo $ticket->getId() + ?>/status/reopen"><i class="icon-undo"></i> <?php echo + __('Reopen');?></a> <?php } } @@ -100,7 +100,19 @@ if($ticket->isOverdue()) if($thisstaff->canEditTickets()) { ?> <li><a class="change-user" href="#tickets/<?php echo $ticket->getId(); ?>/change-user"><i class="icon-user"></i> <?php - echo __('Change Ticket Owner'); ?></a></li> + echo __('Change Owner'); ?></a></li> + <?php + } + if($thisstaff->canDeleteTickets()) { + if (!$ticket->isArchived()) { ?> + <li><a class="ticket-action" href="#tickets/<?php + echo $ticket->getId(); ?>/status/archive"><i class="icon-archive"></i> <?php + echo __('Archive Ticket'); ?></a></li> + <?php + } ?> + <li><a class="ticket-action" href="#tickets/<?php + echo $ticket->getId(); ?>/status/delete"><i class="icon-trash"></i> <?php + echo __('Delete Ticket'); ?></a></li> <?php } if($ticket->isOpen() && ($dept && $dept->isManager($thisstaff))) { @@ -932,67 +944,6 @@ $tcount+= $ticket->getNumNotes(); </form> <div class="clear"></div> </div> -<div style="display:none;" class="dialog" id="ticket-status"> - <h3><?php echo sprintf($ticket->isClosed() ? __('Reopen Ticket #%s') : __('Close Ticket #%s'), - $ticket->getNumber()); ?></h3> - <a class="close" href=""><i class="icon-remove-circle"></i></a> - <hr/> - <?php - echo sprintf(__('Are you sure you want to <b>%s</b> this ticket?'), - $ticket->isClosed()?__('REOPEN'):__('CLOSE')); - $action = $ticket->isClosed() ? 'reopen': 'close'; - ?> - <br><br> - <form action="tickets.php?id=<?php echo $ticket->getId(); ?>" method="post" id="status-form" name="status-form"> - <?php csrf_token(); ?> - <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>"> - <input type="hidden" name="a" value="process"> - <input type="hidden" name="do" value="<?php echo $action; ?>"> - <fieldset> - <div><strong>Ticket Status </strong> - <select name="status_id"> - <?php - $statusId = $info['status_id'] ?: 0; - if (!$ticket->isOpen()) - $states = array('open'); - else - $states = array('resolved', 'closed'); - - foreach (TicketStatusList::getAll($states) as $s) { - if (!$s->isEnabled()) continue; - echo sprintf('<option value="%d" %s>%s</option>', - $s->getId(), - ($statusId == $s->getId()) - ? 'selected="selected"' : '', - $s->getName() - ); - } - ?> - </select> - <span class='error'>* <?php echo $errors['status_id']; ?></span> - </div> - </fieldset> - <fieldset> - <div style="margin-bottom:0.5em"> - <em><?php echo __('Reasons for status change (internal note). Optional but highly recommended.');?></em><br> - </div> - <textarea name="ticket_status_notes" id="ticket_status_notes" cols="50" rows="5" wrap="soft" - style="width:100%" - class="richtext ifhtml no-bar"><?php echo $info['ticket_status_notes']; ?></textarea> - </fieldset> - <hr style="margin-top:1em"/> - <p class="full-width"> - <span class="buttons pull-left"> - <input type="reset" value="<?php echo __('Reset');?>"> - <input type="button" value="<?php echo __('Cancel');?>" class="close"> - </span> - <span class="buttons pull-right"> - <input type="submit" value="<?php echo $ticket->isClosed()?__('Reopen'):__('Close'); ?>"> - </span> - </p> - </form> - <div class="clear"></div> -</div> <div style="display:none;" class="dialog" id="confirm-action"> <h3><?php echo __('Please Confirm');?></h3> <a class="close" href=""><i class="icon-remove-circle"></i></a> diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php index 094d28ded43cf56a50280d5e0413f682f8f9613f..dd739c2c0c2cb0b1d16845528024e84d028f8c91 100644 --- a/include/staff/tickets.inc.php +++ b/include/staff/tickets.inc.php @@ -327,10 +327,24 @@ if ($results) { </div> <!-- SEARCH FORM END --> <div class="clear"></div> -<div style="margin-bottom:20px"> -<form action="tickets.php" method="POST" name='tickets'> +<div style="margin-bottom:20px; padding-top:3px;"> +<table width="940" cellpadding="1" cellspacing="0" border="0"> + <tr> + <td width="20%"> + <h2><a href="<?php echo Format::htmlchars($_SERVER['REQUEST_URI']); ?>" + title="Reload"><i class="icon-refresh"></i></a></h2> + </td> + <td width="80%" class="right_align"> + <?php + if ($res && $results && $thisstaff->canManageTickets()) { + echo TicketStatus::options(); + } + ?> + </td> + </tr> +</table> +<form action="tickets.php" method="POST" name='tickets' id="tickets"> <?php csrf_token(); ?> - <a class="refresh pull-right" href="<?php echo Format::htmlchars($_SERVER['REQUEST_URI']); ?>"><?php echo __('Refresh'); ?></a> <input type="hidden" name="a" value="mass_process" > <input type="hidden" name="do" id="action" value="" > <input type="hidden" name="status" value="<?php echo Format::htmlchars($_REQUEST['status']); ?>" > @@ -427,7 +441,8 @@ if ($results) { $sel=true; ?> <td align="center" class="nohover"> - <input class="ckb" type="checkbox" name="tids[]" value="<?php echo $row['ticket_id']; ?>" <?php echo $sel?'checked="checked"':''; ?>> + <input class="ckb" type="checkbox" name="tids[]" + value="<?php echo $row['ticket_id']; ?>" <?php echo $sel?'checked="checked"':''; ?>> </td> <?php } ?> <td title="<?php echo $row['email']; ?>" nowrap> @@ -490,42 +505,6 @@ if ($results) { echo '<div> '.__('Page').':'.$pageNav->getPageLinks().' '; echo '<a class="export-csv no-pjax" href="?a=export&h=' .$hash.'&status='.$_REQUEST['status'] .'">'.__('Export').'</a> <i class="help-tip icon-question-sign" href="#export"></i></div>'; - ?> - <?php - if($thisstaff->canManageTickets()) { ?> - <p class="centered" id="actions"> - <?php - $status=$_REQUEST['status']?$_REQUEST['status']:$status; - switch (strtolower($status)) { - case 'closed': ?> - <input class="button" type="submit" name="reopen" value="<?php echo __('Reopen');?>" > - <?php - break; - case 'open': - case 'answered': - case 'assigned': - ?> - <input class="button" type="submit" name="mark_overdue" value="<?php echo __('Overdue');?>" > - <input class="button" type="submit" name="close" value="<?php echo __('Close');?>"> - <?php - break; - case 'overdue': - ?> - <input class="button" type="submit" name="close" value="<?php echo __('Close');?>"> - <?php - break; - default: //search?? - ?> - <input class="button" type="submit" name="close" value="<?php echo __('Close');?>" > - <input class="button" type="submit" name="reopen" value="<?php echo __('Reopen');?>"> - <?php - } - if($thisstaff->canDeleteTickets()) { ?> - <input class="button" type="submit" name="delete" value="<?php echo __('Delete');?>"> - <?php } ?> - </p> - <?php - } } ?> </form> </div> @@ -534,20 +513,9 @@ if ($results) { <h3><?php echo __('Please Confirm');?></h3> <a class="close" href=""><i class="icon-remove-circle"></i></a> <hr/> - <p class="confirm-action" style="display:none;" id="close-confirm"> - <?php echo __('Are you sure want to <b>close</b> selected open tickets?');?> - </p> - <p class="confirm-action" style="display:none;" id="reopen-confirm"> - <?php echo __('Are you sure want to <b>reopen</b> selected closed tickets?');?> - </p> <p class="confirm-action" style="display:none;" id="mark_overdue-confirm"> <?php echo __('Are you sure want to flag the selected tickets as <font color="red"><b>overdue</b></font>?');?> </p> - <p class="confirm-action" style="display:none;" id="delete-confirm"> - <font color="red"><strong><?php echo sprintf(__('Are you sure you want to DELETE %s?'), - _N('selected ticket', 'selected tickets', 2));?></strong></font> - <br><br><?php echo __('Deleted tickets CANNOT be recovered, including any associated attachments.');?> - </p> <div><?php echo __('Please confirm to continue.');?></div> <hr style="margin-top:1em"/> <p class="full-width"> @@ -683,3 +651,22 @@ if ($results) { </p> </form> </div> +<script type="text/javascript"> +$(function() { + $(document).off('.tickets'); + $(document).on('click.tickets', 'a.tickets-action', function(e) { + e.preventDefault(); + var count = checkbox_checker($('form#tickets'), 1); + if (count) { + var url = 'ajax.php/' + +$(this).attr('href').substr(1) + +'?count='+count + +'&_uid='+new Date().getTime(); + $.dialog(url, [201], function (xhr) { + window.location.href = window.location.href; + }); + } + return false; + }); +}); +</script> diff --git a/scp/ajax.php b/scp/ajax.php index 664e12566b00bbcb03ab2e33511b7396b18caa55..cdeec76d9bb1f7ef5b5e3ae3b86fb009b47e4fe9 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -135,11 +135,15 @@ $dispatcher = patterns('', url_get('^(?P<tid>\d+)/add-collaborator/(?P<uid>\d+)$', 'addCollaborator'), url_get('^(?P<tid>\d+)/add-collaborator/auth:(?P<bk>\w+):(?P<id>.+)$', 'addRemoteCollaborator'), url('^(?P<tid>\d+)/add-collaborator$', 'addCollaborator'), - url_get('^lookup', 'lookup'), - url_get('^search', 'search'), url_get('^(?P<tid>\d+)/forms/manage$', 'manageForms'), url_post('^(?P<tid>\d+)/forms/manage$', 'updateForms'), - url_get('^(?P<tid>\d+)/canned-resp/(?P<cid>\w+).(?P<format>json|txt)', 'cannedResponse') + url_get('^(?P<tid>\d+)/canned-resp/(?P<cid>\w+).(?P<format>json|txt)', 'cannedResponse'), + url_get('^(?P<tid>\d+)/status/(?P<status>\w+)$', 'changeTicketStatus'), + url_post('^(?P<tid>\d+)/status/(?P<status>\w+)$', 'setTicketStatus'), + url_get('^status/(?P<status>\w+)(?:/(?P<sid>\d+))?$', 'changeTicketsStatus'), + url_post('^status/(?P<state>\w+)$', 'setTicketsStatus'), + url_get('^lookup', 'lookup'), + url_get('^search', 'search') )), url('^/collaborators/', patterns('ajax.tickets.php:TicketsAjaxAPI', url_get('^(?P<cid>\d+)/view$', 'viewCollaborator'), diff --git a/scp/js/ticket.js b/scp/js/ticket.js index ba70ec2df65f1a77b6f76cbf65163383c9979e19..afbf1ecc9c53b73703f33e0839f8ed5808f36b8a 100644 --- a/scp/js/ticket.js +++ b/scp/js/ticket.js @@ -381,7 +381,7 @@ var ticket_onload = function($) { autoLock.Init(); /*** Ticket Actions **/ - //print options + //print options TODO: move to backend $('a#ticket-print').click(function(e) { e.preventDefault(); $('#overlay').show(); @@ -389,11 +389,17 @@ var ticket_onload = function($) { return false; }); - //ticket status (close & reopen) xxx: move to backend ticket-action - $('a#ticket-close, a#ticket-reopen').click(function(e) { + + $(document).off('.ticket-action'); + $(document).on('click.ticket-action', 'a.ticket-action', function(e) { e.preventDefault(); - $('#overlay').show(); - $('.dialog#ticket-status').show(); + var url = 'ajax.php/' + +$(this).attr('href').substr(1) + +'?_uid='+new Date().getTime(); + $.dialog(url, [201], function (xhr) { + window.location.href = window.location.href; + }); + return false; }); diff --git a/scp/tickets.php b/scp/tickets.php index f3502c96a2666cfcbdd8868d0a276ad03055c4cd..7fb3e3872ff7af834c633225b3ba7dc39a5c96b2 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -201,52 +201,6 @@ if($_POST && !$errors): break; case 'process': switch(strtolower($_POST['do'])): - case 'close': - if(!$thisstaff->canCloseTickets()) { - $errors['err'] = __('Permission Denied. You are not allowed to close tickets.'); - } elseif($ticket->isClosed()) { - $errors['err'] = __('Ticket is already closed!'); - } elseif (!($status=TicketStatus::lookup($_POST['status_id']))) { - $errors['err'] = __('Unknown status'); - } elseif (!in_array($status->getState(), array('resolved', 'closed'))) { - $errors['err'] = __('Invalid status'); - } elseif ($ticket->setStatus($status)) { - $msg=sprintf(__('Ticket #%s status set to CLOSED'),$ticket->getNumber()); - if($_POST['ticket_status_notes']) { - $ticket->logNote( - __('Ticket Closed'), - $_POST['ticket_status_notes'], - $thisstaff); - } - //Going back to main listing. - TicketLock::removeStaffLocks($thisstaff->getId(), $ticket->getId()); - $page=$ticket=null; - } else { - $errors['err']=__('Problems closing the ticket. Try again'); - } - break; - case 'reopen': - //if staff can close or create tickets ...then assume they can reopen. - if (!$thisstaff->canCloseTickets() && !$thisstaff->canCreateTickets()) { - $errors['err']=__('Permission Denied. You are not allowed to reopen tickets.'); - } elseif ($ticket->isOpen()) { - $errors['err'] = __('Ticket is already open!'); - } elseif (!($status=TicketStatus::lookup($_POST['status_id']))) { - $errors['err'] = __('Unknown status'); - } elseif (strcasecmp($status->getState(), 'open')) { - $errors['err'] = __('Invalid status'); - } elseif ($ticket->setStatus($status)) { - $msg=__('Ticket Reopened'); - if($_POST['ticket_status_notes']) { - $ticket->logNote( - __('Ticket Reopened'), - $_POST['ticket_status_notes'], - $thisstaff); - } - } else { - $errors['err']=__('Problems reopening the ticket. Try again'); - } - break; case 'release': if(!$ticket->isAssigned() || !($assigned=$ticket->getAssigned())) { $errors['err'] = __('Ticket is not assigned!'); @@ -336,21 +290,6 @@ if($_POST && !$errors): $errors['err'] = 'Unable to change tiket ownership. Try again'; } break; - case 'delete': // Dude what are you trying to hide? bad customer support?? - if(!$thisstaff->canDeleteTickets()) { - $errors['err']=__('Permission Denied. You are not allowed to DELETE tickets!!'); - } elseif($ticket->delete()) { - $msg=sprintf(__('Ticket #%s deleted successfully'),$ticket->getNumber()); - //Log a debug note - $ost->logDebug(sprintf(__('Ticket #%s deleted'),$ticket->getNumber()), - sprintf(__('Ticket #%1$s deleted by %2$s'), - $ticket->getNumber(), $thisstaff->getName()) - ); - $ticket=null; //clear the object. - } else { - $errors['err']=__('Problems deleting the ticket. Try again'); - } - break; default: $errors['err']=__('You must select action to perform'); endswitch; @@ -363,90 +302,6 @@ if($_POST && !$errors): }elseif($_POST['a']) { switch($_POST['a']) { - case 'mass_process': - if(!$thisstaff->canManageTickets()) - $errors['err']=__('You do not have permission to mass manage tickets. Contact admin for such access'); - elseif(!$_POST['tids'] || !is_array($_POST['tids'])) - $errors['err']=sprintf(__('You must select at least %s.'), - __('one ticket')); - else { - $count=count($_POST['tids']); - $i = 0; - switch(strtolower($_POST['do'])) { - case 'reopen': - if($thisstaff->canCloseTickets() || $thisstaff->canCreateTickets()) { - $note=sprintf(__('Ticket reopened by %s'),$thisstaff->getName()); - foreach($_POST['tids'] as $k=>$v) { - if(($t=Ticket::lookup($v)) && $t->isClosed() && @$t->reopen()) { - $i++; - $t->logNote(__('Ticket Reopened'), $note, $thisstaff); - } - } - - if($i==$count) - $msg = sprintf(__('Successfully reopened %s'), - _N('selected ticket', 'selected tickets', $count)); - elseif($i) - $warn = sprintf(__('%1$d of %2$d %3$s reopened'),$i, $count, - _N('selected ticket', 'selected tickets', $count)); - else - $errors['err'] = sprintf(__('Unable to reopen %s'), - _N('selected ticket', 'selected tickets', $count)); - } else { - $errors['err'] = __('You do not have permission to reopen tickets'); - } - break; - case 'close': - $errors['err'] = 'Support coming soon!'; - break; - case 'mark_overdue': - $note=sprintf(__('Ticket flagged as overdue by %s'),$thisstaff->getName()); - foreach($_POST['tids'] as $k=>$v) { - if(($t=Ticket::lookup($v)) && !$t->isOverdue() && $t->markOverdue()) { - $i++; - $t->logNote(__('Ticket Marked Overdue'), $note, $thisstaff); - } - } - - if($i==$count) - $msg = sprintf(__('Selected tickets (%d) marked overdue'), $i); - elseif($i) - $warn = sprintf(__('%1$d of %2$d selected tickets marked overdue'), $i, $count); - else - $errors['err'] = __('Unable to flag selected tickets as overdue'); - break; - case 'delete': - if($thisstaff->canDeleteTickets()) { - foreach($_POST['tids'] as $k=>$v) { - if(($t=Ticket::lookup($v)) && @$t->delete()) $i++; - } - - //Log a warning - if($i) { - $log = sprintf(_S('%1$s (%2$s) just deleted %3$d ticket(s)'), - $thisstaff->getName(), $thisstaff->getUserName(), $i); - $ost->logWarning(_S('Tickets deleted'), $log, false); - - } - - if($i==$count) - $msg = sprintf(__('Successfully deleted %s'), - _N('selected ticket', 'selected tickets', $count)); - elseif($i) - $warn = sprintf(__('%1$d of %2$d %3$s deleted'),$i, $count, - _N('selected ticket', 'selected tickets', $count)); - else - $errors['err'] = sprintf(__('Unable to delete %s'), - _N('selected ticket', 'selected tickets', $count)); - } else { - $errors['err'] = __('You do not have permission to delete tickets'); - } - break; - default: - $errors['err']=__('Unknown action - get technical help.'); - } - } - break; case 'open': $ticket=null; if(!$thisstaff || !$thisstaff->canCreateTickets()) {