diff --git a/include/ajax.search.php b/include/ajax.search.php index 4edad32cac5b6c6acea5666cf5fc1426838940c9..d433963a362df731084c631fa4d66251e0b1e889 100644 --- a/include/ajax.search.php +++ b/include/ajax.search.php @@ -132,7 +132,7 @@ class SearchAjaxAPI extends AjaxController { $form = $search->getForm($data); $form->setSource($data); if (!$data || !$form->isValid()) { - Http::response(422, 'Validation errors exist on form'); + Http::response(422, 'Validation errors exist on criteria'); } $search->config = JsonDataEncoder::encode($form->getState()); @@ -227,15 +227,14 @@ class SearchAjaxAPI extends AjaxController { $queue = CustomQueue::create(); } - $form = $queue->getForm($_POST); - - // TODO: Update queue columns (but without save) + // Update queue columns (but without save) foreach ($_POST['columns'] as $colid) { $col = QueueColumn::create(array("id" => $colid, "queue" => $queue)); $col->update($_POST); $queue->addColumn($col); } + $form = $queue->getForm($_POST); $tickets = $queue->getQuery($form); $count = 10; // count($queue->getBasicQuery($form)); diff --git a/include/class.queue.php b/include/class.queue.php index d0aa1c64563d3c4ba32507bd385d843a8c055c94..c3a4d202ae3e884c2cd133c75d9f2ca656ffebb7 100644 --- a/include/class.queue.php +++ b/include/class.queue.php @@ -22,6 +22,11 @@ class CustomQueue extends SavedSearch { 'columns' => array( 'reverse' => 'QueueColumn.queue', ), + 'staff' => array( + 'constraint' => array( + 'staff_id' => 'Staff.staff_id', + ) + ) ), ); @@ -31,8 +36,8 @@ class CustomQueue extends SavedSearch { )); } - static function getDecorations($root) { - // Ticket decorations + static function getAnnotations($root) { + // Ticket annotations return array( 'TicketThreadCount', 'ThreadAttachmentCount', @@ -93,10 +98,18 @@ class CustomQueue extends SavedSearch { $col->queue = $this; } + function getId() { + return $this->id; + } + function getRoot() { return 'Ticket'; } + function getStatus() { + return 'bogus'; + } + function getBasicQuery($form=false) { $root = $this->getRoot(); $query = $root::objects(); @@ -118,9 +131,60 @@ class CustomQueue extends SavedSearch { } return $query; } + + function update($vars, &$errors) { + // TODO: Move this to SavedSearch::update() and adjust + // AjaxSearch::_saveSearch() + $form = $this->getForm($vars); + $form->setSource($vars); + if (!$vars || !$form->isValid()) { + $errors['criteria'] = __('Validation errors exist on criteria'); + } + else { + $this->config = JsonDataEncoder::encode($form->getState()); + } + + // Set basic queue information + $this->title = $vars['name']; + + // Update queue columns (but without save) + if (isset($vars['columns'])) { + foreach ($vars['columns'] as $sort=>$colid) { + // Try and find the column in this queue, if it's a new one, + // add it to the columns list + if (!($col = $this->columns->findFirst(array('id' => $colid)))) { + $col = QueueColumn::create(array("id" => $colid, "queue" => $this)); + $this->addColumn($col); + } + $col->set('sort', $sort+1); + $col->update($vars, $errors); + } + // Re-sort the in-memory columns array + $this->columns->sort(function($c) { return $c->sort; }); + } + return 0 === count($errors); + } + + function save($refetch=false) { + if (!($rv = parent::save($refetch))) + return $rv; + + return $this->columns->saveAll(); + } + + static function create($vars=false) { + global $thisstaff; + + $queue = parent::create($vars); + $queue->setFlag(SavedSearch::FLAG_QUEUE); + if ($thisstaff) + $queue->staff_id = $thisstaff->getId(); + + return $queue; + } } -abstract class QueueDecoration { +abstract class QueueColumnAnnotation { static $icon = false; static $desc = ''; @@ -167,7 +231,7 @@ abstract class QueueDecoration { } // Render the annotation with the database record $row. $text is the - // text of the cell before decorations were applied. + // text of the cell before annotations were applied. function render($row, $cell) { if ($decoration = $this->getDecoration($row, $cell)) return $this->decorate($cell, $decoration); @@ -185,10 +249,14 @@ abstract class QueueDecoration { function getPosition() { return strtolower($this->config['p']) ?: 'a'; } + + function getClassName() { + return @$this->config['c'] ?: get_class(); + } } class TicketThreadCount -extends QueueDecoration { +extends QueueColumnAnnotation { static $icon = 'comments-alt'; static $qname = '_thread_count'; static $desc = /* @trans */ 'Thread Count'; @@ -214,7 +282,7 @@ extends QueueDecoration { } class ThreadAttachmentCount -extends QueueDecoration { +extends QueueColumnAnnotation { static $icon = 'paperclip'; static $qname = '_att_count'; static $desc = /* @trans */ 'Attachment Count'; @@ -240,7 +308,7 @@ extends QueueDecoration { } class OverdueFlagDecoration -extends QueueDecoration { +extends QueueColumnAnnotation { static $icon = 'exclamation'; static $desc = /* @trans */ 'Overdue Icon'; @@ -255,7 +323,7 @@ extends QueueDecoration { } class TicketSourceDecoration -extends QueueDecoration { +extends QueueColumnAnnotation { static $icon = 'phone'; static $desc = /* @trans */ 'Ticket Source'; @@ -308,22 +376,36 @@ class QueueColumnCondition { )); } + function getField() { + // FIXME + #$root = $this->getColumn()->getQueue()->getRoot(); + $root = 'Ticket'; + $searchable = SavedSearch::getSearchableFields($root); + list($name, $method, $value) = $this->config['crit']; + + // Lookup the field to search this condition + if (isset($searchable[$name])) + return $searchable[$name]; + } + + function getFieldName() { + list($name) = $this->config['crit']; + return $name; + } + function getSearchQ() { - // FIXME - #$root = $this->getColumn()->getQueue()->getRoot(); - $root = 'Ticket'; - $searchable = SavedSearch::getSearchableFields($root); list($name, $method, $value) = $this->config['crit']; - // Lookup the field to search this condition - if (!isset($searchable[$name])) - return null; - $field = $searchable[$name]; - // Fetch a criteria Q for the query - return $field->getSearchQ($method, $value, $name); + if ($field = $this->getField()) + return $field->getSearchQ($method, $value, $name); } + /** + * Take the criteria from the SavedSearch fields setup and isolate the + * field name being search, the method used for searhing, and the method- + * specific data entered in the UI. + */ static function isolateCriteria($criteria, $root='Ticket') { $searchable = SavedSearch::getSearchableFields($root); foreach ($criteria as $k=>$v) { @@ -456,40 +538,26 @@ extends ChoiceField { /** - * Object version of JSON-serialized column array which has several - * properties: + * A column of a custom queue. Columns have many customizable features + * including: * - * { - * "heading": "Header Text", - * "primary": "user__name", - * "secondary": null, - * "width": 100, - * "link": 'ticket', - * "truncate": "wrap", - * "filter": "UsersName" - * "annotations": [ - * { - * "c": "ThreadCollabCount", - * "p": ">" - * } - * ], - * "conditions": [ - * { - * "crit": { - * "created+method": {"ndaysago": "in the last n days"}, "created+ndaysago": {"until":"7"} - * }, - * "prop": { - * "font-weight": "bold" - * } - * } - * ] - * } + * * Data Source (primary and secondary) + * * Heading + * * Link (to an object like the ticket) + * * Size and truncate settings + * * annotations (like counts and flags) + * * Conditions (which change the formatting like bold text) + * + * Columns are stored in a separate table from the queue itself, but other + * breakout items for the annotations and conditions, for instance, are stored + * as JSON text in the QueueColumn model. */ class QueueColumn extends VerySimpleModel { static $meta = array( 'table' => QUEUE_COLUMN_TABLE, 'pk' => array('id'), + 'ordering' => array('sort'), 'joins' => array( 'queue' => array( 'constraint' => array('queue_id' => 'CustomQueue.id'), @@ -497,17 +565,23 @@ extends VerySimpleModel { ), ); - var $_decorations = array(); + var $_annotations = array(); var $_conditions = array(); function __onload() { - if ($this->annotations) { - foreach ($this->annotations as $D) - $this->_decorations[] = QueueDecoration::fromJson($D) ?: array(); + if ($this->annotations + && ($anns = JsonDataParser::decode($this->annotations)) + ) { + foreach ($anns as $D) + if ($T = QueueColumnAnnotation::fromJson($D)) + $this->_annotations[] = $T; } - if ($this->conditions) { - foreach ($this->conditions as $C) - $this->_conditions[] = QueueColumnCondition::fromJson($C) ?: array(); + if ($this->conditions + && ($conds = JsonDataParser::decode($this->conditions)) + ) { + foreach ($conds as $C) + if ($T = QueueColumnCondition::fromJson($C)) + $this->_conditions[] = $T; } } @@ -554,8 +628,8 @@ extends VerySimpleModel { $text = sprintf('<a href="%s">%s</a>', $link, $text); } - // Decorations and conditions - foreach ($this->_decorations as $D) { + // annotations and conditions + foreach ($this->_annotations as $D) { $text = $D->render($row, $text); } foreach ($this->_conditions as $C) { @@ -615,8 +689,8 @@ extends VerySimpleModel { break; } - // Decorations - foreach ($this->_decorations as $D) { + // annotations + foreach ($this->_annotations as $D) { $query = $D->annotate($query); } @@ -637,8 +711,8 @@ extends VerySimpleModel { return $name; } - function getDecorations() { - return $this->_decorations; + function getAnnotations() { + return $this->_annotations; } function getConditions() { @@ -651,7 +725,7 @@ extends VerySimpleModel { */ static function create($vars=array()) { $inst = parent::create($vars); - // TODO: Convert decorations and conditions + // TODO: Convert annotations and conditions return $inst; } @@ -660,65 +734,78 @@ extends VerySimpleModel { foreach ($form->getClean() as $k=>$v) $this->set($k, $v); - // Do the decorations - $this->_decorations = $this->decorations = array(); - foreach (@$vars['decorations'] as $i=>$class) { - if (!class_exists($class) || !is_subclass_of($class, 'QueueDecoration')) - continue; - if ($vars['deco_column'][$i] != $this->id) - continue; - $json = array('c' => $class, 'p' => $vars['deco_pos'][$i]); - $this->_decorations[] = QueueDecoration::fromJson($json); - $this->decorations[] = $json; + // Do the annotations + $this->_annotations = $annotations = array(); + if (isset($vars['annotations'])) { + foreach (@$vars['annotations'] as $i=>$class) { + if ($vars['deco_column'][$i] != $this->id) + continue; + if (!class_exists($class) || !is_subclass_of($class, 'QueueColumnAnnotation')) + continue; + $json = array('c' => $class, 'p' => $vars['deco_pos'][$i]); + $annotations[] = $json; + $this->_annotations[] = QueueColumnAnnotation::fromJson($json); + } } // Do the conditions - $this->_conditions = $this->conditions = array(); - foreach (@$vars['conditions'] as $i=>$id) { - if ($vars['condition_column'][$i] != $this->id) - // Not a condition for this column - continue; - // Determine the criteria - $name = $vars['condition_field'][$i]; - $fields = SavedSearch::getSearchableFields($this->getQueue()->getRoot()); - if (!isset($fields[$name])) - // No such field exists for this queue root type - continue; - $field = $fields[$name]; - $parts = SavedSearch::getSearchField($field, $name); - $search_form = new SimpleForm($parts, $vars, array('id' => $id)); - $search_form->getField("{$name}+search")->value = true; - $crit = $search_form->getClean(); - // Check the box to enable searching on the field - $crit["{$name}+search"] = true; - - // Convert search criteria to a Q instance - $crit = QueueColumnCondition::isolateCriteria($crit); - - // Determine the properties - $props = array(); - foreach ($vars['properties'] as $i=>$cid) { - if ($cid != $id) - // Not a property for this condition + $this->_conditions = $conditions = array(); + if (isset($vars['conditions'])) { + foreach (@$vars['conditions'] as $i=>$id) { + if ($vars['condition_column'][$i] != $this->id) + // Not a condition for this column continue; - - // Determine the property configuration - $prop = $vars['property_name'][$i]; - if (!($F = QueueColumnConditionProperty::getField($prop))) { - // Not a valid property + // Determine the criteria + $name = $vars['condition_field'][$i]; + $fields = SavedSearch::getSearchableFields($this->getQueue()->getRoot()); + if (!isset($fields[$name])) + // No such field exists for this queue root type continue; + $field = $fields[$name]; + $parts = SavedSearch::getSearchField($field, $name); + $search_form = new SimpleForm($parts, $vars, array('id' => $id)); + $search_form->getField("{$name}+search")->value = true; + $crit = $search_form->getClean(); + // Check the box to enable searching on the field + $crit["{$name}+search"] = true; + + // Isolate only the critical parts of the criteria + $crit = QueueColumnCondition::isolateCriteria($crit); + + // Determine the properties + $props = array(); + foreach ($vars['properties'] as $i=>$cid) { + if ($cid != $id) + // Not a property for this condition + continue; + + // Determine the property configuration + $prop = $vars['property_name'][$i]; + if (!($F = QueueColumnConditionProperty::getField($prop))) { + // Not a valid property + continue; + } + $prop_form = new SimpleForm(array($F), $vars, array('id' => $cid)); + $props[$prop] = $prop_form->getField($prop)->getClean(); } - $prop_form = new SimpleForm(array($F), $vars, array('id' => $cid)); - $props[$prop] = $prop_form->getClean(); + $json = array('crit' => $crit, 'prop' => $props); + $this->_conditions[] = QueueColumnCondition::fromJson($json); + $conditions[] = $json; } - $json = array('crit' => $crit, 'prop' => $props); - $this->_conditions[] = QueueColumnCondition::fromJson($json); - $this->conditions[] = $json; } // Store as JSON array - $this->decorations = JsonDataEncoder::encode($this->decorations); - $this->conditions = JsonDataEncoder::encode($this->conditions); + $this->annotations = JsonDataEncoder::encode($annotations); + $this->conditions = JsonDataEncoder::encode($conditions); + } + + function save($refetch=false) { + if ($this->__new__ && isset($this->id)) + // The ID is used to synchrize the POST data with the forms API. + // It should not be assumed to be a valid or unique database ID + // number + unset($this->id); + return parent::save($refetch); } } diff --git a/include/class.search.php b/include/class.search.php index 674533e2a531748f9bfb8a562d34777ed45b4bee..91c19f3c38886df2dd8384de29be7354be355445 100644 --- a/include/class.search.php +++ b/include/class.search.php @@ -675,12 +675,12 @@ class SavedSearch extends VerySimpleModel { } function getName() { - return $this->name; + return $this->title; } function getSearchForm() { - if ($state = JsonDataParser::parse($search->config)) { - $form = $search->loadFromState($state); + if ($state = JsonDataParser::parse($this->config)) { + $form = $this->loadFromState($state); $form->loadState($state); return $form; } diff --git a/include/staff/queue.inc.php b/include/staff/queue.inc.php index d322a912554b6bc65e91462834a1609e9f3abd27..0c5b36a0a6ba82220eefac1410d04055110ca0d9 100644 --- a/include/staff/queue.inc.php +++ b/include/staff/queue.inc.php @@ -5,18 +5,15 @@ if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access $info = $qs = array(); -if ($_REQUEST['a']=='add'){ - if (!$queue) { - $queue = CustomQueue::create(array( - 'flags' => CustomQueue::FLAG_QUEUE, - )); - } +if (!$queue) { + $queue = CustomQueue::create(array( + 'flags' => CustomQueue::FLAG_QUEUE, + )); $title=__('Add New Queue'); $action='create'; $submit_text=__('Create'); } else { - //Editing Department. $title=__('Manage Custom Queue'); $action='update'; $submit_text=__('Save Changes'); @@ -30,6 +27,7 @@ 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><?php echo __('Ticket Queues'); ?> // <?php echo $title; ?> <?php if (isset($queue->id)) { ?><small> @@ -59,6 +57,7 @@ else { <br/> <div><strong><?php echo __("Queue Search Criteria"); ?></strong></div> <hr/> + <div class="error"><?php echo $errors['criteria']; ?></div> <div class="advanced-search"> <?php $form = $queue->getSearchForm(); @@ -128,7 +127,7 @@ else { config.append($(json.config)).insertAfter(columns.append(div)); $this.data('nextId', nextId+1); } - }); + }); "> <option value="">— <?php echo __('Add a column'); ?> —</option> <?php foreach (SavedSearch::getSearchableFields('Ticket') as $path=>$f) { ?> @@ -140,12 +139,13 @@ else { <?php foreach ($queue->getColumns() as $column) { $colid = $column->getId(); $maxcolid = max(@$maxcolid ?: 0, $colid); - echo sprintf('<div data-id="%s" data-col-id="colconfig-%s" class="column-header" ' - .'data-width="%s">%s' + echo sprintf('<div data-id="%1$s" data-col-id="colconfig-%1$s" class="column-header" ' + .'data-width="%2$s">%3$s' .'<i class="icon-ellipsis-vertical ui-resizable-handle ui-resizable-handle-e"></i>' - .'<input type="hidden" name="columns[]" value="%s"/>' + .'<input type="hidden" name="columns[]" value="%1$s"/>' .'</div>', - $colid, $colid, $column->getWidth(), $column->getHeading(), $colid); + $colid, $column->getWidth(), $column->getHeading(), + $column->sort ?: 1); } ?> </div> <script> diff --git a/include/staff/queues-ticket.inc.php b/include/staff/queues-ticket.inc.php index 170edafed6e22445c3a6b2ce74edea5103468272..620ae915897a20a35f690179942bbbb06ee283c2 100644 --- a/include/staff/queues-ticket.inc.php +++ b/include/staff/queues-ticket.inc.php @@ -1,38 +1,38 @@ - +<?php +require_once INCLUDE_DIR . 'class.queue.php'; +?> <form action="queues.php?t=tickets" method="POST" name="keys"> - <div class="sticky bar opaque"> - <div class="content"> - <div class="pull-right"> - <a href="queues.php?t=tickets&a=add" class="green button action-button"><i class="icon-plus-sign"></i> <?php echo __('Add New Queue');?></a> - <span class="action-button" data-dropdown="#action-dropdown-more"> - <i class="icon-caret-down pull-right"></i> - <span ><i class="icon-cog"></i> <?php echo __('More');?></span> - </span> - <div id="action-dropdown-more" class="action-dropdown anchor-right"> - <ul id="actions"> - <li> - <a class="confirm" data-name="enable" href="queues.php?t=tickets&a=enable"> - <i class="icon-ok-sign icon-fixed-width"></i> - <?php echo __( 'Enable'); ?> - </a> - </li> - <li> - <a class="confirm" data-name="disable" href="queues.php?t=tickets&a=disable"> - <i class="icon-ban-circle icon-fixed-width"></i> - <?php echo __( 'Disable'); ?> - </a> - </li> - <li class="danger"> - <a class="confirm" data-name="delete" href="queues.php?t=tickets&a=delete#queues"> - <i class="icon-trash icon-fixed-width"></i> - <?php echo __( 'Delete'); ?> - </a> - </li> - </ul> - </div> + <div> + <div class="pull-right"> + <a href="queues.php?t=tickets&a=add" class="green button action-button"><i class="icon-plus-sign"></i> <?php echo __('Add New Queue');?></a> + <span class="action-button" data-dropdown="#action-dropdown-more"> + <i class="icon-caret-down pull-right"></i> + <span ><i class="icon-cog"></i> <?php echo __('More');?></span> + </span> + <div id="action-dropdown-more" class="action-dropdown anchor-right"> + <ul id="actions"> + <li> + <a class="confirm" data-name="enable" href="queues.php?t=tickets&a=enable"> + <i class="icon-ok-sign icon-fixed-width"></i> + <?php echo __( 'Enable'); ?> + </a> + </li> + <li> + <a class="confirm" data-name="disable" href="queues.php?t=tickets&a=disable"> + <i class="icon-ban-circle icon-fixed-width"></i> + <?php echo __( 'Disable'); ?> + </a> + </li> + <li class="danger"> + <a class="confirm" data-name="delete" href="queues.php?t=tickets&a=delete#queues"> + <i class="icon-trash icon-fixed-width"></i> + <?php echo __( 'Delete'); ?> + </a> + </li> + </ul> </div> - <h3><?php echo __('Ticket Queues');?></h3> </div> + <h3><?php echo __('Ticket Queues');?></h3> </div> <div class="clear"></div> <?php csrf_token(); ?> @@ -49,6 +49,16 @@ </tr> </thead> <tbody> +<?php foreach (CustomQueue::objects() as $q) { ?> + <tr> + <td><input type="checkbox" class="checkbox" name="ckb[]"></td> + <td><a href="queues.php?id=<?php echo $q->getId(); ?>"><?php + echo Format::htmlchars($q->getName()); ?></a></td> + <td><?php echo Format::htmlchars($q->staff->getName()); ?></td> + <td><?php echo Format::htmlchars($q->getStatus()); ?></td> + <td><?php echo Format::date($q->created); ?></td> + </tr> +<?php } ?> </tbody> </table> </form> diff --git a/include/staff/templates/queue-column-condition.tmpl.php b/include/staff/templates/queue-column-condition.tmpl.php index 1c1684b43b62491d2e7e92b5e813d45f2d808d97..659158d06fb547c46146eb5441cd9eaf57c99d0c 100644 --- a/include/staff/templates/queue-column-condition.tmpl.php +++ b/include/staff/templates/queue-column-condition.tmpl.php @@ -2,7 +2,6 @@ // Calling convention: // // $field - field for the condition (Ticket / Last Update) -// $properties - currently-configured properties for the condition // $condition - <QueueColumnCondition> instance for this condition // $column - <QueueColumn> to which the condition belongs // $id - temporary ID number for the condition @@ -25,7 +24,8 @@ $parts = SavedSearch::getSearchField($field, $field_name); unset($parts["{$field_name}+search"]); foreach ($parts as $name=>$F) { if (substr($name, -7) == '+method') - // XXX: Hack + // XXX: Hack — drop visibility connection between the method drop-down + // and the enabled checkbox unset($F->ht['visibility']); } $form = new SimpleForm($parts, false, array('id' => $id)); diff --git a/include/staff/templates/queue-column.tmpl.php b/include/staff/templates/queue-column.tmpl.php index 5d2f23e6f57c6ef5c5ecfbe39c8230049f7e6400..d8d9f6de7b3b5284a73ab48ffeb6efc7928c135b 100644 --- a/include/staff/templates/queue-column.tmpl.php +++ b/include/staff/templates/queue-column.tmpl.php @@ -9,7 +9,7 @@ $data_form = $column->getDataConfigForm($_POST); ?> <ul class="alt tabs"> <li class="active"><a href="#<?php echo $colid; ?>-data"><?php echo __('Data'); ?></a></li> - <li><a href="#<?php echo $colid; ?>-decorations"><?php echo __('Decorations'); ?></a></li> + <li><a href="#<?php echo $colid; ?>-annotations"><?php echo __('Annotations'); ?></a></li> <li><a href="#<?php echo $colid; ?>-conditions"><?php echo __('Conditions'); ?></a></li> </ul> @@ -20,31 +20,31 @@ $data_form = $column->getDataConfigForm($_POST); </div> <div class="hidden tab_content" data-col-id="<?php echo $colid; ?>" - id="<?php echo $colid; ?>-decorations" style="max-width: 400px"> + id="<?php echo $colid; ?>-annotations" style="max-width: 400px"> <div class="empty placeholder" style="margin-left: 20px"> - <em><?php echo __('No decorations for this field'); ?></em> + <em><?php echo __('No annotations for this field'); ?></em> </div> <div style="margin: 0 20px;"> - <div class="decoration clear template hidden"> - <input data-field="input" data-name="decorations[]" value="" type="hidden" /> + <div class="annotation clear template hidden"> + <input data-field="input" data-name="annotations[]" value="" type="hidden" /> <input data-field="column" data-name="deco_column[]" value="" type="hidden" /> <i data-field="icon"></i> <span data-field="name"></span> <div class="pull-right"> <select data-field="position" data-name="deco_pos[]"> -<?php foreach (QueueDecoration::getPositions() as $key=>$desc) { +<?php foreach (QueueColumnAnnotation::getPositions() as $key=>$desc) { echo sprintf('<option value="%s">%s</option>', $key, Format::htmlchars($desc)); } ?> </select> <a href="#" data-field="delete" title="<?php echo __('Delete'); ?>" - onclick="javascript: + onclick="javascript: var tab = $(this).closest('.tab_content'), - decoration = $(this).closest('.decoration'), - klass = decoration.find('input[data-field=input]').val(), - select = $('select.add-decoration', tab); + annotation = $(this).closest('.annotation'), + klass = annotation.find('input[data-field=input]').val(), + select = $('select.add-annotation', tab); select.find('option[value=' + klass + ']').prop('disabled', false); - decoration.remove(); - if (tab.find('.decoration:not(.template)').length === 0) + annotation.remove(); + if (tab.find('.annotation:not(.template)').length === 0) tab.find('.empty.placeholder').show() return false;"><i class="icon-trash"></i></a> </div> @@ -52,9 +52,9 @@ $data_form = $column->getDataConfigForm($_POST); <div style="margin-top: 20px"> <i class="icon-plus-sign"></i> - <select class="add-decoration"> - <option>— <?php echo __("Add a decoration"); ?> —</option> -<?php foreach (CustomQueue::getDecorations('Ticket') as $class) { + <select class="add-annotation"> + <option>— <?php echo __("Add a annotation"); ?> —</option> +<?php foreach (CustomQueue::getAnnotations('Ticket') as $class) { echo sprintf('<option data-icon="%s" value="%s">%s</option>', $class::$icon, $class, $class::getDescription()); } ?> @@ -63,8 +63,8 @@ $data_form = $column->getDataConfigForm($_POST); <script> $(function() { - var addDecoration = function(type, desc, icon, pos) { - var template = $('.decoration.template', '#<?php echo $colid; ?>-decorations'), + var addAnnotation = function(type, desc, icon, pos) { + var template = $('.annotation.template', '#<?php echo $colid; ?>-annotations'), clone = template.clone().show().removeClass('template').insertBefore(template), input = clone.find('[data-field=input]'), colid = clone.closest('.tab_content').data('colId'), @@ -81,19 +81,20 @@ $data_form = $column->getDataConfigForm($_POST); position.val(pos); template.closest('.tab_content').find('.empty').hide(); }; - $('select.add-decoration', '#<?php echo $colid; ?>-decorations').change(function() { + $('select.add-annotation', '#<?php echo $colid; ?>-annotations').change(function() { var selected = $(this).find(':selected'); - addDecoration(selected.val(), selected.text(), selected.data('icon')); + addAnnotation(selected.val(), selected.text(), selected.data('icon')); selected.prop('disabled', true); }); - $('#<?php echo $colid; ?>-decorations').click('a[data-field=delete]', + $('#<?php echo $colid; ?>-annotations').click('a[data-field=delete]', function() { - var tab = $('#<?php echo $colid; ?>-decorations'); - if ($('.decoration', tab).length === 0) + var tab = $('#<?php echo $colid; ?>-annotations'); + if ($('.annotation', tab).length === 0) tab.find('.empty').show(); }); - <?php foreach ($column->getDecorations() as $d) { - echo sprintf('addDecoration(%s, %s, %s);', + <?php foreach ($column->getAnnotations() as $d) { + echo sprintf('addAnnotation(%s, %s, %s, %s);', + JsonDataEncoder::encode($d->getClassName()), JsonDataEncoder::encode($d::getDescription()), JsonDataEncoder::encode($d::getIcon()), JsonDataEncoder::encode($d->getPosition()) @@ -108,8 +109,15 @@ $data_form = $column->getDataConfigForm($_POST); <div style="margin: 0 20px"><?php echo __("Conditions are used to change the view of the data in a row based on some conditions of the data. For instance, a column might be shown bold if some condition is met."); ?></div> <div class="conditions" style="margin: 20px; max-width: 400px"> -<?php foreach ($column->getConditions() as $condition) { +<?php +if ($column->getConditions()) { + $fields = SavedSearch::getSearchableFields($column->getQueue()->getRoot()); + foreach ($column->getConditions() as $i=>$condition) { + $id = $column->getId() * 40 + $i; + $field = $condition->getField(); + $field_name = $condition->getFieldName(); include STAFFINC_DIR . 'templates/queue-column-condition.tmpl.php'; + } } ?> <div style="margin-top: 20px"> <i class="icon-plus-sign"></i> diff --git a/scp/queues.php b/scp/queues.php index d348d570503e54c51dd17358dc0421645ceb7e5c..dc95a569764f0df20832efec6e5108a0fb23fea3 100644 --- a/scp/queues.php +++ b/scp/queues.php @@ -20,6 +20,43 @@ require('admin.inc.php'); require_once INCLUDE_DIR . 'class.queue.php'; $nav->setTabActive('settings', 'settings.php?t='.urlencode($_GET['t'])); +$errors = array(); + +if ($_REQUEST['id']) { + $queue = CustomQueue::lookup($_REQUEST['id']); +} + +if ($_POST) { + switch (strtolower($_POST['do'])) { + case 'update': + if (!$queue) { + $errors['err'] = ''; + break; + } + if ($queue->update($_POST, $errors) && $queue->save()) { + $msg = sprintf(__('Successfully updated %s'), Format::htmlchars($_POST['name'])); + } + elseif (!$errors['err']) { + $errors['err']=sprintf(__('Unable to udpate %s. Correct error(s) below and try again.'), + __('this queue')); + } + break; + + case 'create': + $queue = CustomQueue::create(array( + 'root' => $_POST['root'] ?: 'Ticket' + )); + + if ($queue->update($_POST, $errors) && $queue->save(true)) { + $msg = sprintf(__('Successfully added %s'), Format::htmlchars($_POST['name'])); + } + elseif (!$errors['err']) { + $errors['err']=sprintf(__('Unable to add %s. Correct error(s) below and try again.'), + __('this queue')); + } + break; + } +} require_once(STAFFINC_DIR.'header.inc.php'); include_once(STAFFINC_DIR."queue.inc.php");