From 78e7114bb94a15540b8d01d4c327e644c62538dd Mon Sep 17 00:00:00 2001 From: Peter Rotich <peter@enhancesoft.com> Date: Thu, 27 Sep 2018 15:15:39 +0000 Subject: [PATCH] Make Primary Queues Buckets This commit makes Primary Queues buckets for sub queues with forced inheritance of criteria. Primary queues are now hidden unless there are no sub queues attached. Agents can still get to primary queue by clicking on it. The commit also adds default sub queues for Closed queue, utilizing DateTime periods. --- include/class.queue.php | 10 +- include/class.search.php | 2 +- include/i18n/en_US/queue.yaml | 445 ++++++++++++++++-- include/i18n/en_US/queue_column.yaml | 7 + include/i18n/en_US/queue_sort.yaml | 4 + include/staff/queue.inc.php | 87 ++-- .../advanced-search-criteria.tmpl.php | 2 +- .../staff/templates/queue-navigation.tmpl.php | 7 +- scp/queues.php | 2 +- 9 files changed, 476 insertions(+), 90 deletions(-) diff --git a/include/class.queue.php b/include/class.queue.php index 48f82c81f..5e9f3dcbf 100644 --- a/include/class.queue.php +++ b/include/class.queue.php @@ -998,7 +998,8 @@ class CustomQueue extends VerySimpleModel { } function inheritCriteria() { - return $this->flags & self::FLAG_INHERIT_CRITERIA; + return $this->flags & self::FLAG_INHERIT_CRITERIA && + $this->parent_id; } function inheritColumns() { @@ -1176,8 +1177,7 @@ class CustomQueue extends VerySimpleModel { // Set basic queue information $this->path = $this->buildPath(); - $this->setFlag(self::FLAG_INHERIT_CRITERIA, - $this->parent_id > 0 && isset($vars['inherit'])); + $this->setFlag(self::FLAG_INHERIT_CRITERIA, $this->parent_id); $this->setFlag(self::FLAG_INHERIT_COLUMNS, isset($vars['inherit-columns'])); $this->setFlag(self::FLAG_INHERIT_EXPORT, @@ -1392,8 +1392,10 @@ class CustomQueue extends VerySimpleModel { $queue = new static($vars); $queue->created = SqlFunction::NOW(); - if (!isset($vars['flags'])) + if (!isset($vars['flags'])) { + $queue->setFlag(self::FLAG_PUBLIC); $queue->setFlag(self::FLAG_QUEUE); + } return $queue; } diff --git a/include/class.search.php b/include/class.search.php index c32916504..469c3f5e0 100644 --- a/include/class.search.php +++ b/include/class.search.php @@ -855,7 +855,7 @@ class SavedQueue extends CustomQueue { $queues = SavedQueue::objects() ->filter(Q::any(array( - 'flags__hasbit' => CustomQueue::FLAG_PUBLIC, + 'flags__hasbit' => CustomQueue::FLAG_QUEUE, 'staff_id' => $agent->getId(), ))); diff --git a/include/i18n/en_US/queue.yaml b/include/i18n/en_US/queue.yaml index ab2b1a4bb..b7325620c 100644 --- a/include/i18n/en_US/queue.yaml +++ b/include/i18n/en_US/queue.yaml @@ -29,6 +29,7 @@ --- - id: 1 title: Open + parent_id: 0 flags: 0x03 sort: 1 root: T @@ -69,14 +70,17 @@ - sort_id: 2 - sort_id: 3 - sort_id: 4 + - sort_id: 6 + - sort_id: 7 - id: 2 - title: Answered + title: Open parent_id: 1 - flags: 0x03 + flags: 0x2b root: T - sort: 2 - config: '[["isanswered","set",null]]' + sort: 1 + sort_id: 4 + config: '{"criteria":[["isanswered","nset",null]],"conditions":[]}' columns: - column_id: 1 bits: 1 @@ -87,7 +91,7 @@ bits: 1 sort: 2 width: 150 - heading: Last Update + heading: Last Updated - column_id: 3 bits: 1 sort: 3 @@ -108,13 +112,93 @@ sort: 6 width: 160 heading: Assigned To - sorts: - - sort_id: 1 - - sort_id: 2 - - sort_id: 3 - - sort_id: 4 - id: 3 + title: Answered + parent_id: 1 + flags: 0x2b + root: T + sort: 1 + sort_id: 4 + config: '{"criteria":[["isanswered","set",null]],"conditions":[]}' + columns: + - column_id: 1 + bits: 1 + sort: 1 + width: 100 + heading: Ticket + - column_id: 10 + bits: 1 + sort: 2 + width: 150 + heading: Last Updated + - column_id: 3 + bits: 1 + sort: 3 + width: 300 + heading: Subject + - column_id: 4 + bits: 1 + sort: 4 + width: 185 + heading: From + - column_id: 5 + bits: 1 + sort: 5 + width: 85 + heading: Priority + - column_id: 8 + bits: 1 + sort: 6 + width: 160 + heading: Assigned To + +- id: 4 + title: Overdue + parent_id: 1 + flags: 0x2b + root: T + sort: 2 + sort_id: 4 + config: '{"criteria":[["isoverdue","set",null]],"conditions":[]}' + columns: + - column_id: 1 + bits: 1 + sort: 1 + width: 100 + heading: Ticket + - column_id: 9 + bits: 1 + sort: 1 + sort: 9 + width: 150 + heading: Due Date + - column_id: 3 + bits: 1 + sort: 1 + sort: 3 + width: 300 + heading: Subject + - column_id: 4 + bits: 1 + sort: 1 + sort: 4 + width: 185 + heading: From + - column_id: 5 + bits: 1 + sort: 1 + sort: 5 + width: 85 + heading: Priority + - column_id: 8 + bits: 1 + sort: 1 + sort: 6 + width: 160 + heading: Assigned To + +- id: 5 title: My Tickets parent_id: 0 flags: 0x03 @@ -157,25 +241,27 @@ - sort_id: 2 - sort_id: 3 - sort_id: 4 + - sort_id: 6 + - sort_id: 7 -- id: 4 - title: Closed - flags: 0x03 - sort: 4 +- id: 6 + title: Assigned to Me + parent_id: 5 + flags: 0x2b root: T - sort_id: 5 - config: '[["status__state","includes",{"closed":"Closed"}]]' + sort: 1 + config: '{"criteria":[["assignee","includes",{"M":"Me"}]],"conditions":[]}' columns: - column_id: 1 bits: 1 sort: 1 width: 100 heading: Ticket - - column_id: 7 + - column_id: 10 bits: 1 sort: 2 width: 150 - heading: Date Closed + heading: Last Update - column_id: 3 bits: 1 sort: 3 @@ -188,28 +274,29 @@ heading: From - column_id: 5 bits: 1 - sort: 1 sort: 5 width: 85 heading: Priority - - column_id: 8 + - column_id: 11 bits: 1 - sort: 1 sort: 6 width: 160 - heading: Closed By + heading: Department sorts: - - sort_id: 5 - sort_id: 1 - sort_id: 2 + - sort_id: 3 + - sort_id: 4 + - sort_id: 6 + - sort_id: 7 -- id: 5 - title: Assigned - parent_id: 1 - flags: 0x03 +- id: 7 + title: Assigned to Teams + parent_id: 5 + flags: 0x2b root: T - sort: 3 - config: '[["assignee","assigned",null]]' + sort: 2 + config: '{"criteria":[["assignee","!includes",{"M":"Me"}]],"conditions":[]}' columns: - column_id: 1 bits: 1 @@ -236,53 +323,323 @@ sort: 5 width: 85 heading: Priority + - column_id: 14 + bits: 1 + sort: 6 + width: 160 + heading: Team + sorts: + - sort_id: 1 + - sort_id: 2 + - sort_id: 3 + - sort_id: 4 + - sort_id: 6 + - sort_id: 7 + +- id: 8 + parent_id: 0 + title: Closed + flags: 0x03 + sort: 4 + root: T + sort_id: 5 + config: '{"criteria":[["status__state","includes",{"closed":"Closed"}]],"conditions":[]}' + columns: + - column_id: 1 + bits: 1 + sort: 1 + width: 100 + heading: Ticket + - column_id: 7 + bits: 1 + sort: 2 + width: 150 + heading: Date Closed + - column_id: 3 + bits: 1 + sort: 3 + width: 300 + heading: Subject + - column_id: 4 + bits: 1 + sort: 4 + width: 185 + heading: From - column_id: 8 bits: 1 + sort: 1 sort: 6 width: 160 - heading: Assigned To + heading: Closed By + sorts: + - sort_id: 5 + - sort_id: 1 + - sort_id: 2 + - sort_id: 3 + - sort_id: 4 + - sort_id: 6 + - sort_id: 7 -- id: 6 - title: Overdue - parent_id: 1 +- id: 9 + parent_id: 8 + title: Today flags: 0x2b + sort: 1 root: T - sort: 4 - sort_id: 4 - config: '[["isoverdue","set",null]]' + sort_id: 5 + config: '{"criteria":[["closed","period","td"]],"conditions":[]}' columns: - column_id: 1 bits: 1 sort: 1 width: 100 heading: Ticket - - column_id: 9 + - column_id: 7 + bits: 1 + sort: 2 + width: 150 + heading: Date Closed + - column_id: 3 + bits: 1 + sort: 3 + width: 300 + heading: Subject + - column_id: 4 + bits: 1 + sort: 4 + width: 185 + heading: From + - column_id: 8 bits: 1 sort: 1 - sort: 9 + sort: 6 + width: 160 + heading: Closed By + sorts: + - sort_id: 5 + - sort_id: 1 + - sort_id: 2 + - sort_id: 3 + - sort_id: 4 + - sort_id: 6 + - sort_id: 7 + +- id: 10 + parent_id: 8 + title: Yesterday + flags: 0x2b + sort: 2 + root: T + sort_id: 5 + config: '{"criteria":[["closed","period","yd"]],"conditions":[]}' + columns: + - column_id: 1 + bits: 1 + sort: 1 + width: 100 + heading: Ticket + - column_id: 7 + bits: 1 + sort: 2 width: 150 - heading: Due Date + heading: Date Closed + - column_id: 3 + bits: 1 + sort: 3 + width: 300 + heading: Subject + - column_id: 4 + bits: 1 + sort: 4 + width: 185 + heading: From + - column_id: 8 + bits: 1 + sort: 1 + sort: 6 + width: 160 + heading: Closed By + sorts: + - sort_id: 5 + - sort_id: 1 + - sort_id: 2 + - sort_id: 3 + - sort_id: 4 + - sort_id: 6 + - sort_id: 7 + +- id: 11 + parent_id: 8 + title: This Week + flags: 0x2b + sort: 3 + root: T + sort_id: 5 + config: '{"criteria":[["closed","period","tw"]],"conditions":[]}' + columns: + - column_id: 1 + bits: 1 + sort: 1 + width: 100 + heading: Ticket + - column_id: 7 + bits: 1 + sort: 2 + width: 150 + heading: Date Closed - column_id: 3 + bits: 1 + sort: 3 + width: 300 + heading: Subject + - column_id: 4 + bits: 1 + sort: 4 + width: 185 + heading: From + - column_id: 8 + bits: 1 + sort: 1 + sort: 6 + width: 160 + heading: Closed By + sorts: + - sort_id: 5 + - sort_id: 1 + - sort_id: 2 + - sort_id: 3 + - sort_id: 4 + - sort_id: 6 + - sort_id: 7 + +- id: 12 + parent_id: 8 + title: This Month + flags: 0x2b + sort: 4 + root: T + sort_id: 5 + config: '{"criteria":[["closed","period","tm"]],"conditions":[]}' + columns: + - column_id: 1 bits: 1 sort: 1 + width: 100 + heading: Ticket + - column_id: 7 + bits: 1 + sort: 2 + width: 150 + heading: Date Closed + - column_id: 3 + bits: 1 sort: 3 width: 300 heading: Subject - column_id: 4 + bits: 1 + sort: 4 + width: 185 + heading: From + - column_id: 8 bits: 1 sort: 1 + sort: 6 + width: 160 + heading: Closed By + sorts: + - sort_id: 5 + - sort_id: 1 + - sort_id: 2 + - sort_id: 3 + - sort_id: 4 + - sort_id: 6 + - sort_id: 7 + +- id: 13 + parent_id: 8 + title: This Quarter + flags: 0x2b + sort: 5 + root: T + sort_id: 6 + config: '{"criteria":[["closed","period","tq"]],"conditions":[]}' + columns: + - column_id: 1 + bits: 1 + sort: 1 + width: 100 + heading: Ticket + - column_id: 7 + bits: 1 + sort: 2 + width: 150 + heading: Date Closed + - column_id: 3 + bits: 1 + sort: 3 + width: 300 + heading: Subject + - column_id: 4 + bits: 1 sort: 4 width: 185 heading: From - - column_id: 5 + - column_id: 8 bits: 1 sort: 1 - sort: 5 - width: 85 - heading: Priority + sort: 6 + width: 160 + heading: Closed By + sorts: + - sort_id: 5 + - sort_id: 1 + - sort_id: 2 + - sort_id: 3 + - sort_id: 4 + - sort_id: 6 + - sort_id: 7 + +- id: 14 + parent_id: 8 + title: This Year + flags: 0x2b + sort: 6 + root: T + sort_id: 7 + config: '{"criteria":[["closed","period","ty"]],"conditions":[]}' + columns: + - column_id: 1 + bits: 1 + sort: 1 + width: 100 + heading: Ticket + - column_id: 7 + bits: 1 + sort: 2 + width: 150 + heading: Date Closed + - column_id: 3 + bits: 1 + sort: 3 + width: 300 + heading: Subject + - column_id: 4 + bits: 1 + sort: 4 + width: 185 + heading: From - column_id: 8 bits: 1 sort: 1 sort: 6 width: 160 - heading: Assigned To + heading: Closed By + sorts: + - sort_id: 5 + - sort_id: 1 + - sort_id: 2 + - sort_id: 3 + - sort_id: 4 + - sort_id: 6 + - sort_id: 7 diff --git a/include/i18n/en_US/queue_column.yaml b/include/i18n/en_US/queue_column.yaml index 6f7419a4a..03250da19 100644 --- a/include/i18n/en_US/queue_column.yaml +++ b/include/i18n/en_US/queue_column.yaml @@ -129,3 +129,10 @@ truncate: "wrap" annotations: "[]" conditions: "[]" + +- id: 14 + name: "Team" + primary: "team_id" + truncate: "wrap" + annotations: "[]" + conditions: "[]" diff --git a/include/i18n/en_US/queue_sort.yaml b/include/i18n/en_US/queue_sort.yaml index 09b0fb87f..35cd47d4a 100644 --- a/include/i18n/en_US/queue_sort.yaml +++ b/include/i18n/en_US/queue_sort.yaml @@ -27,3 +27,7 @@ - id: 6 name: Create Date columns: '["-created"]' + +- id: 7 + name: Update Date + columns: '["-lastupdate"]' diff --git a/include/staff/queue.inc.php b/include/staff/queue.inc.php index b936699df..fa9862bb8 100644 --- a/include/staff/queue.inc.php +++ b/include/staff/queue.inc.php @@ -4,10 +4,11 @@ if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied'); $info = $qs = array(); - +$parent = null; if (!$queue) { $queue = CustomQueue::create(array( 'flags' => CustomQueue::FLAG_QUEUE, + 'parent_id' => 0, )); } if ($queue->__new__) { @@ -16,6 +17,7 @@ if ($queue->__new__) { $submit_text=__('Create'); } else { + $parent = $queue->parent; $title=__('Manage Custom Queue'); $action='update'; $submit_text=__('Save Changes'); @@ -29,8 +31,6 @@ else { <input type="hidden" name="do" value="<?php echo $action; ?>"> <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>"> <input type="hidden" name="id" value="<?php echo $info['id']; ?>"> - <input type="hidden" name="root" value="<?php echo Format::htmlchars($_REQUEST['t']); ?>"> - <h2><a href="settings.php?t=tickets#queues"><?php echo __('Ticket Queues'); ?></a> <i class="icon-caret-right" style="color:rgba(0,0,0,.3);"></i> <?php echo $title; ?> <?php if (isset($queue->id)) { ?><small> @@ -63,20 +63,33 @@ else { <br/> <div class="error"><?php echo $errors['queue-name']; ?></div> <br/> + <div> + <div><strong><?php echo __("Parent Queue"); ?>:</strong></div> + <select name="parent_id" id="parent-id"> + <option value="0">— <?php echo __('Top-Level Queue'); ?> —</option> + <?php foreach (CustomQueue::queues() as $cq) { + // Queue cannot be a descendent of itself + if ($cq->id == $queue->id) + continue; + if (strpos($cq->path, "/{$queue->id}/") !== false) + continue; + ?> + <option value="<?php echo $cq->id; ?>" + <?php if ($cq->getId() == $queue->parent_id) echo 'selected="selected"'; ?> + ><?php echo $cq->getFullName(); ?></option> + <?php } ?> + </select> + <span class="error"><?php echo Format::htmlchars($errors['parent_id']); ?></span> + </div> + <div class="faded <?php echo $parent ? ' ': 'hidden'; ?>" + id="inherited-parent" style="margin-top: 1em;"> + <div><strong><i class="icon-caret-down"></i> <?php echo __('Inherited Criteria'); ?></strong></div> + <div id="parent-criteria"> + <?php echo $parent ? nl2br(Format::htmlchars($parent->describeCriteria())) : ''; ?> + </div> + </div> + <hr/> <div><strong><?php echo __("Queue Search Criteria"); ?></strong></div> - <label class="checkbox" style="line-height:1.3em"> - <input type="checkbox" class="checkbox" name="inherit" <?php - if ($queue->inheritCriteria()) echo 'checked="checked"'; - ?>/> - <?php echo __('Include parent search criteria'); - if ($queue->parent) { ?> - <span id="parent_q_crit" class="faded"> - <i class="icon-caret-right"></i> - <br/><?php - echo nl2br(Format::htmlchars($queue->parent->describeCriteria())); - ?></span> -<?php } ?> - </label> <hr/> <div class="error"><?php echo $errors['criteria']; ?></div> <div class="advanced-search"> @@ -89,27 +102,6 @@ else { </div> </td> <td style="width:35%; padding-left:40px; vertical-align:top"> - <div><strong><?php echo __("Parent Queue"); ?>:</strong></div> - <select name="parent_id" onchange="javascript: - $('#parent_q_crit').toggle($(this).find(':selected').val() - == <?php echo $queue->parent_id ?: 0; ?>);"> - <option value="0">— <?php echo __('Top-Level Queue'); ?> —</option> -<?php foreach (CustomQueue::queues() as $cq) { - // Queue cannot be a descendent of itself - if ($cq->id == $queue->id) - continue; - if (strpos($cq->path, "/{$queue->id}/") !== false) - continue; -?> - <option value="<?php echo $cq->id; ?>" - <?php if ($cq->getId() == $queue->parent_id) echo 'selected="selected"'; ?> - ><?php echo $cq->getFullName(); ?></option> -<?php } ?> - </select> - <div class="error"><?php echo Format::htmlchars($errors['parent_id']); ?></div> - - <br/> - <br/> <div><strong><?php echo __("Quick Filter"); ?></strong></div> <hr/> <select name="filter"> @@ -309,6 +301,27 @@ var Q = setInterval(function() { ); } ?> }, 25); +$('select#parent-id').change(function() { + var form = $(this).closest('form'); + var qid = parseInt($(this).val(), 10) || 0; + + if (qid > 0) { + $.ajax({ + type: "GET", + url: 'ajax.php/queue/'+qid, + dataType: 'json', + success: function(queue) { + $('#parent-name', form).html(queue.name); + $('#parent-criteria', form).html(queue.criteria); + $('#inherited-parent', form).fadeIn(); + } + }) + .done(function() { }) + .fail(function() { }); + } else { + $('#inherited-parent', form).fadeOut(); + } +}); }(); </script> </table> diff --git a/include/staff/templates/advanced-search-criteria.tmpl.php b/include/staff/templates/advanced-search-criteria.tmpl.php index 9348cf79b..309ce63cd 100644 --- a/include/staff/templates/advanced-search-criteria.tmpl.php +++ b/include/staff/templates/advanced-search-criteria.tmpl.php @@ -11,7 +11,7 @@ if (($search instanceof SavedQueue) && !$search->checkOwnership($thisstaff)) { echo '<div class="faded">'. nl2br(Format::htmlchars($search->describeCriteria())). '</div><br>'; // Show any supplemental filters - if ($matches && count($info)) { + if ($matches) { ?> <div id="ticket-flags" style="padding:5px; border-top: 1px dotted #777;"> diff --git a/include/staff/templates/queue-navigation.tmpl.php b/include/staff/templates/queue-navigation.tmpl.php index d1061c8d4..380e03af9 100644 --- a/include/staff/templates/queue-navigation.tmpl.php +++ b/include/staff/templates/queue-navigation.tmpl.php @@ -15,6 +15,9 @@ $selected = (!isset($_REQUEST['a']) && $_REQUEST['queue'] == $this_queue->getId <div class="customQ-dropdown"> <ul class="scroll-height"> <!-- Add top-level queue (with count) --> + + <?php + if (!$children) { ?> <li class="top-level"> <span class="pull-right newItemQ queue-count" data-queue-id="<?php echo $q->id; ?>"><span class="faded-more">-</span> @@ -25,9 +28,9 @@ $selected = (!isset($_REQUEST['a']) && $_REQUEST['queue'] == $this_queue->getId <?php echo Format::htmlchars($q->getName()); ?> </a> - </h4> </li> - + <?php + } ?> <!-- Start Dropdown and child queues --> <?php foreach ($childs as $_) { list($q, $children) = $_; diff --git a/scp/queues.php b/scp/queues.php index f02f4efc8..997fefa26 100644 --- a/scp/queues.php +++ b/scp/queues.php @@ -44,7 +44,7 @@ if ($_POST) { $queue = CustomQueue::create(array( 'staff_id' => 0, 'title' => $_POST['queue-name'], - 'root' => $_POST['root'] ?: 'T' + 'root' => 'T' )); if ($queue->update($_POST, $errors) && $queue->save(true)) { -- GitLab