From c42325c359744035a8ee922d07bb91a8fb8b6d24 Mon Sep 17 00:00:00 2001 From: Jared Hancock <jared@osticket.com> Date: Wed, 4 Mar 2015 14:25:08 -0600 Subject: [PATCH] queue: Make sort options relevant to current queue --- include/class.search.php | 3 +- include/staff/tickets.inc.php | 123 ++++++++++++++++++++++++++++------ scp/js/scp.js | 2 +- 3 files changed, 104 insertions(+), 24 deletions(-) diff --git a/include/class.search.php b/include/class.search.php index 84d3bbbcd..355feb072 100644 --- a/include/class.search.php +++ b/include/class.search.php @@ -304,7 +304,7 @@ class MysqlSearchBackend extends SearchBackend { $key = 'COALESCE(Z1.ticket_id, Z2.ticket_id)'; $criteria->extra(array( 'select' => array( - 'key' => $key, + 'ticket_id' => $key, 'relevance'=>'`search`.`relevance`', ), 'order_by' => array(new SqlCode('`relevance`')), @@ -702,6 +702,7 @@ class SavedSearch extends VerySimpleModel { function mangleQuerySet(QuerySet $qs, $form=false) { $form = $form ?: $this->getForm(); $searchable = $this->getCurrentSearchFields($form->getSource()); + $qs = clone $qs; // Figure out fields to search on foreach ($form->getFields() as $f) { diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php index 45ee6847b..7b953b9da 100644 --- a/include/staff/tickets.inc.php +++ b/include/staff/tickets.inc.php @@ -16,6 +16,20 @@ unset($args['a']); $refresh_url = $path . '?' . http_build_query($args); +$sort_options = array( + 'priority,updated' => __('Priority + Most Recently Updated'), + 'updated' => __('Most Recently Updated'), + 'priority,created' => __('Priority + Most Recently Created'), + 'due' => __('Due Soon'), + 'priority,due' => __('Priority + Due Soon'), + 'number' => __('Ticket Number'), + 'answered' => __('Most Recently Answered'), + 'closed' => __('Most Recently Closed'), + 'hot' => __('Longest Thread'), + 'relevance' => __('Relevance'), +); +$use_subquery = true; + $queue_name = strtolower($_GET['status'] ?: $_GET['a']); //Status is overloaded switch ($queue_name) { case 'closed': @@ -23,23 +37,31 @@ case 'closed': $results_type=__('Closed Tickets'); $showassigned=true; //closed by. $tickets->values('staff__firstname', 'staff__lastname', 'team__name', 'team_id'); + $queue_sort_options = array('closed', 'priority,due', 'due', + 'number', 'priority,updated', 'priority,created', 'answered', 'hot'); break; case 'overdue': $status='open'; $results_type=__('Overdue Tickets'); $tickets->filter(array('isoverdue'=>1)); + $queue_sort_options = array('priority,due', 'due', 'priority,updated', + 'updated', 'priority,created', 'number', 'answered', 'hot'); break; case 'assigned': $status='open'; $staffId=$thisstaff->getId(); $results_type=__('My Tickets'); $tickets->filter(array('staff_id'=>$thisstaff->getId())); + $queue_sort_options = array('updated', 'priority,updated', 'priority,created', 'priority,due', + 'due', 'answered', 'number', 'hot'); break; case 'answered': $status='open'; $showanswered=true; $results_type=__('Answered Tickets'); $tickets->filter(array('isanswered'=>1)); + $queue_sort_options = array('answered', 'priority,updated', 'updated', + 'priority,created', 'priority,due', 'due', 'number', 'hot'); break; default: case 'search': @@ -67,6 +89,23 @@ case 'search': $view_all_tickets = $thisstaff->getRole()->hasPerm(SearchBackend::PERM_EVERYTHING); $results_type=__('Advanced Search') . '<a class="action-button" href="?clear_filter"><i class="icon-ban-circle"></i> <em>' . __('clear') . '</em></a>'; + $queue_sort_options = array('priority,due', 'due', 'priority,updated', + 'updated', 'priority,created', 'number', 'answered', 'closed', 'hot'); + $has_relevance = false; + foreach ($tickets->getSortFields() as $sf) { + if ($sf instanceof SqlCode && $sf->code == '`relevance`') { + $has_relevance = true; + break; + } + } + if ($has_relevance) { + $use_subquery = false; + array_unshift($queue_sort_options, 'relevance'); + } + elseif ($_SESSION[$queue_sort_key] == 'relevance') { + unset($_SESSION[$queue_sort_key]); + } + break; } // Fall-through and show open tickets @@ -80,6 +119,8 @@ case 'open': $tickets->filter(Q::any(array('staff_id'=>0, 'team_id'=>0))); else $tickets->values('staff__firstname', 'staff__lastname', 'team__name'); + $queue_sort_options = array('priority,updated', 'updated', 'priority,created', 'priority,due', + 'due', 'number', 'answered', 'hot'); break; } @@ -111,10 +152,7 @@ if (!$view_all_tickets) { $tickets->filter(Q::any($visibility)); } -// Apply requested quick filter - -// Rewrite $tickets to use a nested query, which will include the LIMIT part -// in order to speed the result +// TODO :: Apply requested quick filter // Apply requested pagination $page=($_GET['p'] && is_numeric($_GET['p']))?$_GET['p']:1; @@ -122,20 +160,29 @@ $pageNav = new Pagenate($tickets->count(), $page, PAGE_LIMIT); $pageNav->setURL('tickets.php', $args); $tickets = $pageNav->paginate($tickets); -$tickets2 = TicketModel::objects(); - // Apply requested sorting $queue_sort_key = sprintf(':Q:%s:sort', $queue_name); -if (isset($_GET['sort'])) +if (isset($_GET['sort'])) { $_SESSION[$queue_sort_key] = $_GET['sort']; +} +elseif (!isset($_SESSION[$queue_sort_key])) { + $_SESSION[$queue_sort_key] = $queue_sort_options[0]; +} + switch ($_SESSION[$queue_sort_key]) { case 'number': $tickets->extra(array( 'order_by'=>array(SqlExpression::times(new SqlField('number'), 1)) )); break; + +case 'priority,created': + $tickets->order_by('cdata__:priority__priority_urgency'); + // Fall through to columns for `created` case 'created': + $date_header = __('Date Created'); + $date_col = 'created'; $tickets->order_by('-created'); break; @@ -150,18 +197,53 @@ case 'due': $tickets->order_by('est_duedate'); break; +case 'closed': + $date_header = __('Date Closed'); + $date_col = 'closed'; + $tickets->order_by('-closed'); + break; + +case 'answered': + $date_header = __('Last Response'); + $date_col = 'lastupdate'; + $tickets->order_by('-lastupdate'); + break; + +case 'hot': + $tickets->order_by('-thread_count'); + $tickets->annotate(array( + 'thread_count' => SqlAggregate::COUNT('thread__entries'), + )); + break; + +case 'relevance': + $tickets->order_by(new SqlCode('relevance')); + break; + default: +case 'priority,updated': + $tickets->order_by('cdata__:priority__priority_urgency'); + // Fall through for columns defined for `updated` case 'updated': - $tickets->order_by('cdata__:priority__priority_urgency', '-lastupdate'); + $date_header = __('Last Updated'); + $date_col = 'lastupdate'; + $tickets->order_by('-lastupdate'); break; } -$tickets2 = TicketModel::objects(); -$tickets2->filter(array('ticket_id__in' => $tickets->values_flat('ticket_id'))); -// Transfer the order_by from the original tickets -$tickets2->order_by($tickets->getSortFields()); -$tickets = $tickets2; +// Rewrite $tickets to use a nested query, which will include the LIMIT part +// in order to speed the result +// +// ATM, advanced search with keywords doesn't support the subquery approach +if ($use_subquery) { + $tickets2 = TicketModel::objects(); + $tickets2->filter(array('ticket_id__in' => $tickets->values_flat('ticket_id'))); + + // Transfer the order_by from the original tickets + $tickets2->order_by($tickets->getSortFields()); + $tickets = $tickets2; +} TicketForm::ensureDynamicDataView(); @@ -211,14 +293,11 @@ $_SESSION[':Q:tickets'] = $tickets; <div class="pull-right flush-right"> <span style="display:inline-block"> <span style="vertical-align: baseline">Sort:</span> - <select name="sort" onchange="javascript:addSearchParam('sort', $(this).val());"> -<?php foreach (array( - 'updated' => __('Most Recently Updated'), - 'created' => __('Most Recently Created'), - 'due' => __('Due Soon'), - 'priority,due' => __('Priority + Due Soon'), - 'number' => __('Ticket Number'), -) as $mode => $desc) { ?> + <select name="sort" onchange="javascript: $.pjax({ + url:'?' + addSearchParam('sort', $(this).val()), + container: '#pjax-container'});"> +<?php foreach ($queue_sort_options as $mode) { + $desc = $sort_options[$mode]; ?> <option value="<?php echo $mode; ?>" <?php if ($mode == $_SESSION[$queue_sort_key]) echo 'selected="selected"'; ?>><?php echo $desc; ?></option> <?php } ?> </select> @@ -251,7 +330,7 @@ $_SESSION[':Q:tickets'] = $tickets; <th width="70"> <?php echo __('Ticket'); ?></th> <th width="100"> - <?php echo $date_header ?: __('Date'); ?></th> + <?php echo $date_header ?: __('Date Created'); ?></th> <th width="280"> <?php echo __('Subject'); ?></th> <th width="170"> diff --git a/scp/js/scp.js b/scp/js/scp.js index 0a0e577a8..79d14e3da 100644 --- a/scp/js/scp.js +++ b/scp/js/scp.js @@ -901,5 +901,5 @@ function addSearchParam(key, value) { if(i<0) {kvp[kvp.length] = [key,value].join('=');} //this will reload the page, it's likely better to store this until finished - document.location.search = kvp.join('&'); + return kvp.join('&'); } -- GitLab