diff --git a/include/ajax.tasks.php b/include/ajax.tasks.php index cd1f58e50f303fdc376abc6428e316c658f5391b..8181b4eaea1646aba8e229a96a6ac8fd9d2755b2 100644 --- a/include/ajax.tasks.php +++ b/include/ajax.tasks.php @@ -22,6 +22,46 @@ require_once(INCLUDE_DIR.'class.task.php'); class TasksAjaxAPI extends AjaxController { + function add() { + global $thisstaff; + + $info=$errors=array(); + if ($_POST) { + Draft::deleteForNamespace('task.add', $thisstaff->getId()); + // Default form + $form = TaskForm::getInstance(); + $form->setSource($_POST); + // Internal form + $iform = TaskForm::getInternalForm($_POST); + $isvalid = true; + if (!$iform->isValid()) + $isvalid = false; + if (!$form->isValid()) + $isvalid = false; + + if ($isvalid) { + $vars = $_POST; + $vars['default_formdata'] = $form->getClean(); + $vars['internal_formdata'] = $iform->getClean(); + $desc = $form->getField('description'); + if ($desc + && $desc->isAttachmentsEnabled() + && ($attachments=$desc->getWidget()->getAttachments())) + $vars['cannedattachments'] = $attachments->getClean(); + $vars['staffId'] = $thisstaff->getId(); + $vars['poster'] = $thisstaff; + $vars['ip_address'] = $_SERVER['REMOTE_ADDR']; + if (($task=Task::create($vars, $errors))) + Http::response(201, $task->getId()); + } + + $info['error'] = __('Error adding task - try again!'); + } + + include STAFFINC_DIR . 'templates/task.tmpl.php'; + } + + function preview($tid) { global $thisstaff; @@ -67,6 +107,12 @@ class TasksAjaxAPI extends AjaxController { 'delete' => array( 'verbed' => __('deleted'), ), + 'reopen' => array( + 'verbed' => __('reopen'), + ), + 'close' => array( + 'verbed' => __('closed'), + ), ); if (!isset($actions[$action])) @@ -88,53 +134,92 @@ class TasksAjaxAPI extends AjaxController { switch ($action) { case 'assign': $inc = 'task-assign.tmpl.php'; - if ($_POST && !$errors) { - if (!isset($_POST['staff_id']) || !is_numeric($_POST['staff_id'])) - $errors['staff_id'] = __('Assignee selection required'); - else { - foreach ($_POST['tids'] as $tid) { - if (($t=Task::lookup($tid)) - && $t->getDeptId() != $_POST['dept_id'] - // Make sure the agent is allowed to - // access and assign the task. - && $t->checkStaffPerm($thisstaff, Task::PERM_ASSIGN) - // Do the transfer - && $t->assign($_POST, $e) - ) - $i++; - } + $form = AssignmentForm::instantiate($_POST); + if ($_POST && $form->isValid()) { + foreach ($_POST['tids'] as $tid) { + if (($t=Task::lookup($tid)) + // Make sure the agent is allowed to + // access and assign the task. + && $t->checkStaffPerm($thisstaff, Task::PERM_ASSIGN) + // Do the transfer + && $t->assign($form, $e) + ) + $i++; + } - if (!$i) { - $info['error'] = sprintf( - __('Unable to %1$s %2$s'), - __('assign'), - _N('selected task', 'selected tasks', $count)); - } + if (!$i) { + $info['error'] = sprintf( + __('Unable to %1$s %2$s'), + __('assign'), + _N('selected task', 'selected tasks', $count)); } } break; case 'transfer': $inc = 'task-transfer.tmpl.php'; + $form = TransferForm::instantiate($_POST); + if ($_POST && $form->isValid()) { + foreach ($_POST['tids'] as $tid) { + if (($t=Task::lookup($tid)) + // Make sure the agent is allowed to + // access and transfer the task. + && $t->checkStaffPerm($thisstaff, Task::PERM_TRANSFER) + // Do the transfer + && $t->transfer($form, $e) + ) + $i++; + } + + if (!$i) { + $info['error'] = sprintf( + __('Unable to %1$s %2$s'), + __('transfer'), + _N('selected task', 'selected tasks', $count)); + } + } + break; + case 'reopen': + $info['status'] = 'open'; + case 'close': + $inc = 'task-status.tmpl.php'; + $info['status'] = $info['status'] ?: 'closed'; + $perm = ''; + switch ($info['status']) { + case 'open': + // If an agent can create a task then they're allowed to + // reopen closed ones. + $perm = Task::PERM_CREATE; + break; + case 'closed': + $perm = Task::PERM_CLOSE; + break; + default: + $errors['err'] = __('Unknown action'); + } + // Check generic permissions -- department specific permissions + // will be checked below. + if ($perm && !$thisstaff->hasPerm($perm)) + $errors['err'] = sprintf( + __('You do not have permission to %s %s'), + __($action), + __('tasks')); + if ($_POST && !$errors) { - if (!isset($_POST['dept_id']) || !is_numeric($_POST['dept_id'])) - $errors['dept_id'] = __('Department selection required'); + if (!$_POST['status'] + || !in_array($_POST['status'], array('open', 'closed'))) + $errors['status'] = __('Status selection required'); else { foreach ($_POST['tids'] as $tid) { if (($t=Task::lookup($tid)) - && $t->getDeptId() != $_POST['dept_id'] - // Make sure the agent is allowed to - // access and transfer the task. - && $t->checkStaffPerm($thisstaff, Task::PERM_TRANSFER) - // Do the transfer - && $t->transfer($_POST, $e) + && $t->checkStaffPerm($thisstaff, $perm ?: null) + && $t->setStatus($_POST['status'], $_POST['comments']) ) $i++; } if (!$i) { $info['error'] = sprintf( - __('Unable to %1$s %2$s'), - __('transfer'), + __('Unable to change status of %1$s'), _N('selected task', 'selected tasks', $count)); } } @@ -198,7 +283,7 @@ class TasksAjaxAPI extends AjaxController { } elseif($_POST && !isset($info['error'])) { $info['error'] = $errors['err'] ?: sprintf( __('Unable to %1$s %2$s'), - $actions[$action]['verbed'], + __('process'), _N('selected task', 'selected tasks', $count)); } @@ -242,8 +327,9 @@ class TasksAjaxAPI extends AjaxController { $task->getId()) ); - if ($_POST) { - if ($task->transfer($_POST, $errors)) { + $form = $task->getTransferForm($_POST); + if ($_POST && $form->isValid()) { + if ($task->transfer($form, $errors)) { $_SESSION['::sysmsgs']['msg'] = sprintf( __('%s successfully'), sprintf( @@ -255,7 +341,7 @@ class TasksAjaxAPI extends AjaxController { Http::response(201, $task->getId()); } - $info = array_merge($info, Format::htmlchars($_POST)); + $form->addErrors($errors); $info['error'] = $errors['err'] ?: __('Unable to transfer task'); } @@ -281,26 +367,29 @@ class TasksAjaxAPI extends AjaxController { ':action' => sprintf('#tasks/%d/assign', $task->getId()), ); - if ($_POST) { - if ($task->assign($_POST, $errors)) { + if ($task->isAssigned()) { + $info['notice'] = sprintf(__('%s is currently assigned to %s'), + __('Task'), + $task->getAssigned()); + } + + $form = $task->getAssignmentForm($_POST); + if ($_POST && $form->isValid()) { + if ($task->assign($form, $errors)) { $_SESSION['::sysmsgs']['msg'] = sprintf( __('%s successfully'), sprintf( __('%s assigned to %s'), __('Task'), - $task->getStaff() - ) + $form->getAssignee()) ); - Http::response(201, $task->getId()); } - $info = array_merge($info, Format::htmlchars($_POST)); + $form->addErrors($errors); $info['error'] = $errors['err'] ?: __('Unable to assign task'); } - $info['staff_id'] = $info['staff_id'] ?: $task->getStaffId(); - include STAFFINC_DIR . 'templates/task-assign.tmpl.php'; } @@ -367,14 +456,14 @@ class TasksAjaxAPI extends AjaxController { switch ($_POST['a']) { case 'postnote': $vars = $_POST; - $attachments = $task_note_form->getField('attachments')->getClean(); + $attachments = $note_form->getField('attachments')->getClean(); $vars['cannedattachments'] = array_merge( $vars['cannedattachments'] ?: array(), $attachments); if(($note=$task->postNote($vars, $errors, $thisstaff))) { $msg=__('Note posted successfully'); // Clear attachment list - $task_note_form->setSource(array()); - $task_note_form->getField('attachments')->reset(); + $note_form->setSource(array()); + $note_form->getField('attachments')->reset(); Draft::deleteForNamespace('task.note.'.$task->getId(), $thisstaff->getId()); } else { diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index 28ed7d2b4fbfcd6de7af37038c6321d02dc3e628..d1ea440c0495351edb894f76acccb13599d670be 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -924,7 +924,8 @@ class TicketsAjaxAPI extends AjaxController { sprintf('ticket.%d.task', $ticket->getId()), $thisstaff->getId()); // Default form - $form = TaskForm::getDefaultForm()->getForm($_POST); + $form = TaskForm::getInstance(); + $form->setSource($_POST); // Internal form $iform = TaskForm::getInternalForm($_POST); $isvalid = true; @@ -963,5 +964,51 @@ class TicketsAjaxAPI extends AjaxController { include STAFFINC_DIR . 'templates/task.tmpl.php'; } + + function task($tid, $id) { + global $thisstaff; + + if (!($ticket=Ticket::lookup($tid)) + || !$ticket->checkStaffPerm($thisstaff)) + Http::response(404, 'Unknown ticket'); + + // Lookup task and check access + if (!($task=Task::lookup($id)) + || !$task->checkStaffPerm($thisstaff)) + Http::response(404, 'Unknown task'); + + $info=$errors=array(); + $note_form = new SimpleForm(array( + 'attachments' => new FileUploadField(array('id'=>'attach', + 'name'=>'attach:note', + 'configuration' => array('extensions'=>''))) + )); + + if ($_POST) { + switch ($_POST['a']) { + case 'postnote': + $vars = $_POST; + $attachments = $note_form->getField('attachments')->getClean(); + $vars['cannedattachments'] = array_merge( + $vars['cannedattachments'] ?: array(), $attachments); + if(($note=$task->postNote($vars, $errors, $thisstaff))) { + $msg=__('Note posted successfully'); + // Clear attachment list + $note_form->setSource(array()); + $note_form->getField('attachments')->reset(); + Draft::deleteForNamespace('task.note.'.$task->getId(), + $thisstaff->getId()); + } else { + if(!$errors['err']) + $errors['err'] = __('Unable to post the note - missing or invalid data.'); + } + break; + default: + $errors['err'] = __('Unknown action'); + } + } + + include STAFFINC_DIR . 'templates/task-view.tmpl.php'; + } } ?> diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php index 06d0c461afb6fbb020ec949b0fb2841f13b26374..c2c90a3a78510b85886801992bcaf6f43af2321d 100644 --- a/include/class.dynamic_forms.php +++ b/include/class.dynamic_forms.php @@ -116,7 +116,7 @@ class DynamicForm extends VerySimpleModel { if ($source) $this->reset(); $fields = $this->getFields(); - $form = new Form($fields, $source, array( + $form = new SimpleForm($fields, $source, array( 'title' => $this->getLocal('title'), 'instructions' => $this->getLocal('instructions')) ); @@ -287,7 +287,7 @@ class DynamicForm extends VerySimpleModel { if (!$cdata || !$cdata['table'] || !($e = $answer->getEntry()) - || $e->getForm()->get('type') != $cdata['object_type']) + || $e->form->get('type') != $cdata['object_type']) return; // $record = array(); @@ -315,10 +315,10 @@ class DynamicForm extends VerySimpleModel { static function updateDynamicFormEntryAnswer($answer, $data) { if (!$answer || !($e = $answer->getEntry()) - || !$e->getForm()) + || !$e->form) return; - switch ($e->getForm()->get('type')) { + switch ($e->form->get('type')) { case 'T': return TicketForm::updateDynamicDataView($answer, $data); case 'A': @@ -328,10 +328,10 @@ class DynamicForm extends VerySimpleModel { } static function updateDynamicFormField($field, $data) { - if (!$field || !$field->getForm()) + if (!$field || !$field->form) return; - switch ($field->getForm()->get('type')) { + switch ($field->form->get('type')) { case 'T': return TicketForm::dropDynamicDataView(TicketForm::$cdata['table']); case 'A': @@ -985,7 +985,7 @@ class DynamicFormEntry extends VerySimpleModel { function getForm() { if (!isset($this->_form)) { // XXX: Should source be $this? - $form = new Form($this->getFields(), $this->getSource(), + $form = new SimpleForm($this->getFields(), $this->getSource(), array( 'title' => $this->getTitle(), 'instructions' => $this->getInstructions(), diff --git a/include/class.forms.php b/include/class.forms.php index 3b532cca6c210e6dfd2a4c0f1b93bfa5b1309266..75acdbd92a89fca54b6c751fad420b7384f0d32f 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -31,13 +31,8 @@ class Form { var $_errors = null; var $_source = false; - function __construct($fields=array(), $source=null, $options=array()) { - $this->fields = $fields; - foreach ($fields as $k=>$f) { - $f->setForm($this); - if (!$f->get('name') && $k && !is_numeric($k)) - $f->set('name', $k); - } + function __construct($source=null, $options=array()) { + if (isset($options['title'])) $this->title = $options['title']; if (isset($options['instructions'])) @@ -67,7 +62,7 @@ class Form { $this->fields = $fields; foreach ($fields as $k=>$f) { $f->setForm($this); - if (!$f->get('name') && $k) + if (!$f->get('name') && $k && !is_numeric($k)) $f->set('name', $k); } } @@ -3394,7 +3389,7 @@ class TransferForm extends Form { 'default'=>'', 'configuration' => array( 'html' => true, - 'size' => 'large', + 'size' => 'small', 'placeholder' => __('Optional reason for the transfer'), ), ) diff --git a/include/class.task.php b/include/class.task.php index f081eb0d13540fa9e847157568b096d0d08d8101..c629379f6e88470408ab6eab9e36467576a38958 100644 --- a/include/class.task.php +++ b/include/class.task.php @@ -39,8 +39,8 @@ class TaskModel extends VerySimpleModel { ), 'thread' => array( 'constraint' => array( - 'id' => 'ThreadModel.object_id', - "'A'" => 'ThreadModel.object_type', + 'id' => 'TaskThread.object_id', + "'A'" => 'TaskThread.object_type', ), 'list' => false, 'null' => false, @@ -189,7 +189,7 @@ class Task extends TaskModel { var $_entries; function getStatus() { - return $this->isOpen() ? _('Open') : _('Closed'); + return $this->isOpen() ? __('Open') : __('Completed'); } function getTitle() { @@ -222,6 +222,34 @@ class Task extends TaskModel { return $role->hasPerm($perm); } + function getAssignee() { + + if (!$this->isOpen() || !$this->isAssigned()) + return false; + + if ($this->staff) + return $this->staff; + + if ($this->team) + return $this->team; + + return null; + } + + function getAssigneeId() { + + if (!($assignee=$this->getAssignee())) + return null; + + $id = ''; + if ($assignee instanceof Staff) + $id = 's'.$assignee->getId(); + elseif ($assignee instanceof Team) + $id = 't'.$assignee->getId(); + + return $id; + } + function getAssignees() { $assignees=array(); @@ -242,15 +270,7 @@ class Task extends TaskModel { } function getThread() { - - //FIXME: use $this->thread once thread classes get ORMed. - if (!$this->_thread) - $this->_thread = TaskThread::lookup(array( - 'object_id' => $this->getId(), - 'object_type' => ObjectModel::OBJECT_TYPE_TASK) - ); - - return $this->_thread; + return $this->thread; } function getThreadEntry($id) { @@ -285,6 +305,23 @@ class Task extends TaskModel { return $this->form; } + function getAssignmentForm($source=null) { + + if (!$source) + $source = array('assignee' => array($this->getAssigneeId())); + + return AssignmentForm::instantiate($source, + array('dept' => $this->getDept())); + } + + function getTransferForm($source=null) { + + if (!$source) + $source = array('dept' => array($this->getDeptId())); + + return TransferForm::instantiate($source); + } + function addDynamicData($data) { $tf = TaskForm::getInstance($this->id, true); @@ -311,6 +348,40 @@ class Task extends TaskModel { return $this->_entries ?: array(); } + function setStatus($status, $comments='') { + global $thisstaff; + + switch($status) { + case 'open': + if ($this->isOpen()) + return false; + + $this->reopen(); + break; + case 'closed': + if ($this->isClosed()) + return false; + $this->close(); + break; + default: + return false; + } + + $this->save(true); + if ($comments) { + $errors = array(); + $this->postNote(array( + 'note' => $comments, + 'title' => sprintf( + __('Status changed to %s'), + $this->getStatus()) + ), + $errors, + $thisstaff); + } + + return true; + } function to_json() { @@ -326,13 +397,13 @@ class Task extends TaskModel { foreach ($this->getDynamicData() as $e) { // Make sure the form type matches - if (!$e->getForm() - || ($ftype && $ftype != $e->getForm()->get('type'))) + if (!$e->form + || ($ftype && $ftype != $e->form->get('type'))) continue; // Get the named field and return the answer - if ($f = $e->getForm()->getField($field)) - return $f->getAnswer(); + if ($a = $e->getAnswer($field)) + return $a; } return null; @@ -343,44 +414,82 @@ class Task extends TaskModel { } /* util routines */ - function assign($vars, &$errors) { - global $thisstaff; + function assign(AssignmentForm $form, &$errors, $alert=true) { + + $assignee = $form->getAssignee(); + if ($assignee instanceof Staff) { + if ($this->getStaffId() == $assignee->getId()) { + $errors['assignee'] = sprintf(__('%s already assigned to %s'), + __('Task'), + __('the agent') + ); + } elseif(!$assignee->isAvailable()) { + $errors['assignee'] = __('Agent is unavailable for assignment'); + } else { + $this->staff_id = $assignee->getId(); + } + } elseif ($assignee instanceof Team) { + if ($this->getTeamId() == $assignee->getId()) { + $errors['assignee'] = sprintf(__('%s already assigned to %s'), + __('Task'), + __('the team') + ); + } else { + $this->team_id = $assignee->getId(); - if (!isset($vars['staff_id']) || !($staff=Staff::lookup($vars['staff_id']))) - $errors['staff_id'] = __('Agent selection required'); - elseif ($staff->getid() == $this->getStaffId()) - $errors['dept_id'] = __('Task already assigned to agent'); - else - $this->staff_id = $staff->getId(); + } + } else { + $errors['assignee'] = __('Unknown assignee'); + } - if ($errors || !$this->save()) + if ($errors || !$this->save(true)) return false; - // Transfer completed... post internal note. + $this->onAssignment($assignee, + $form->getField('comments')->getClean(), + $alert); + + return true; + } + + function onAssignment($assignee, $note='', $alert=true) { + global $thisstaff; + + if (!is_object($assignee)) + return false; + + $assigner = $thisstaff ?: __('SYSTEM (Auto Assignment)'); + //Assignment completed... post internal note. $title = sprintf(__('Task assigned to %s'), - $staff->getName()); - if ($vars['comments']) { - $note = $vars['comments']; - } else { + (string) $assignee); + + if (!$note) { $note = $title; $title = ''; } - $this->postNote( + $errors = array(); + $note = $this->postNote( array('note' => $note, 'title' => $title), $errors, - $thisstaff); + $assigner, + false); + + // Send alerts out + if (!$alert) + return false; return true; } - function transfer($vars, &$errors) { + function transfer(TransferForm $form, &$errors, $alert=true) { global $thisstaff; - if (!isset($vars['dept_id']) || !($dept=Dept::lookup($vars['dept_id']))) - $errors['dept_id'] = __('Department selection required'); + $dept = $form->getDept(); + if (!$dept || !($dept instanceof Dept)) + $errors['dept'] = __('Department selection required'); elseif ($dept->getid() == $this->getDeptId()) - $errors['dept_id'] = __('Task already in the department'); + $errors['dept'] = __('Task already in the department'); else $this->dept_id = $dept->getId(); @@ -391,17 +500,21 @@ class Task extends TaskModel { $title = sprintf(__('%s transferred to %s department'), __('Task'), $dept->getName()); - if ($vars['comments']) { - $note = $vars['comments']; - } else { + + $note = $form->getField('comments')->getClean(); + if (!$note) { $note = $title; $title = ''; } - - $this->postNote( + $_errors = array(); + $note = $this->postNote( array('note' => $note, 'title' => $title), - $errors, - $thisstaff); + $_errors, $thisstaff, false); + + // Send alerts if requested && enabled. + if (!$alert) + return true; + return true; } @@ -421,14 +534,8 @@ class Task extends TaskModel { if (!($note=$this->getThread()->addNote($vars, $errors))) return null; - if (isset($vars['task_status'])) { - if ($vars['task_status']) - $this->reopen(); - else - $this->close(); - - $this->save(true); - } + if (isset($vars['task_status'])) + $this->setStatus($vars['task_status']); return $note; } @@ -582,6 +689,13 @@ class Task extends TaskModel { return $stats; } + + static function getAgentActions($agent, $options=array()) { + if (!$agent) + return; + + require STAFFINC_DIR.'templates/tasks-actions.tmpl.php'; + } } diff --git a/include/class.ticket.php b/include/class.ticket.php index c275127847b51731ed838b4240d7d56d8bd594e1..cbb51b4143eca41bdfdf9570835237d5e51db4be 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -876,10 +876,11 @@ implements RestrictedAccess, Threadable, TemplateVariable { } function getThreadEntries($type=false) { - $thread = $this->getThread()->getEntries(); + $entries = $this->getThread()->getEntries(); if ($type && is_array($type)) - $thread->filter(array('type__in' => $type)); - return $thread; + $entries->filter(array('type__in' => $type)); + + return $entries; } //Collaborators diff --git a/include/staff/templates/dynamic-form.tmpl.php b/include/staff/templates/dynamic-form.tmpl.php index 7fac7eb1209eb21ad978e27c937c02c24d165e1f..ef18c8bd01c5a988f063d80caea823da0f857ca1 100644 --- a/include/staff/templates/dynamic-form.tmpl.php +++ b/include/staff/templates/dynamic-form.tmpl.php @@ -65,7 +65,7 @@ if (isset($options['entry']) && $options['mode'] == 'edit') { ?> <span class="error">*</span> <?php } - if (($a = $field->getAnswer()) && $a->isDeleted()) { + if ($field->isStorable() && ($a = $field->getAnswer()) && $a->isDeleted()) { ?><a class="action-button float-right danger overlay" title="Delete this data" href="#delete-answer" onclick="javascript:if (confirm('<?php echo __('You sure?'); ?>')) diff --git a/include/staff/templates/task-assign.tmpl.php b/include/staff/templates/task-assign.tmpl.php index 48d389b933d8311526e8850864d2cbbd345e3ecb..7019fa49a2b1d12fdb03039921f0f65b7f9d367c 100644 --- a/include/staff/templates/task-assign.tmpl.php +++ b/include/staff/templates/task-assign.tmpl.php @@ -1,6 +1,8 @@ <?php global $cfg; +$form = $form ?: AssignmentForm::instantiate($info); + if (!$info[':title']) $info[':title'] = sprintf(__('%s Selected Tasks'), __('Assign')); @@ -24,15 +26,17 @@ if ($info['error']) { $action = $info[':action'] ?: ('#tasks/mass/assign'); ?> -<div id="ticket-status" style="display:block; margin:5px;"> -<form class="mass-action" method="post" name="transfer" id="transfer" +<div style="display:block; margin:5px;"> +<form class="mass-action" method="post" + name="assign" + id="<?php echo $form->getId(); ?>" action="<?php echo $action; ?>"> <table width="100%"> <?php - if ($info['extra']) { + if ($info[':extra']) { ?> <tbody> - <tr><td colspan="2"><strong><?php echo $info['extra']; + <tr><td colspan="2"><strong><?php echo $info[':extra']; ?></strong></td> </tr> </tbody> <?php @@ -40,45 +44,12 @@ $action = $info[':action'] ?: ('#tasks/mass/assign'); ?> <tbody> <tr><td colspan=2> - <span> - <strong><?php echo __('Agent') ?>: </strong> - <select name="staff_id"> - <option value=""><?php - echo __('Select Assignee'); ?></option> - <?php - foreach (Staff::getAvailableStaffMembers() as $id => $name) { - if ($task && $task->getStaffId() == $id) - $name .= sprintf(' (%s) ', __('current')); - - echo sprintf('<option value="%d" %s>%s</option>', - $id, - ($info['staff_id'] == $id) - ? 'selected="selected"' : '', - $name - ); - } - ?> - </select> - <font class="error">* <?php echo - $errors['staff_id']; ?></font> - </span> + <?php + $options = array('template' => 'simple', 'form_id' => 'assign'); + $form->render($options); + ?> </td> </tr> </tbody> - <tbody> - <tr> - <td colspan="2"> - <?php - $placeholder = $info['placeholder'] ?: __('Optional reason for the assignment'); - ?> - <textarea name="comments" id="comments" - cols="50" rows="3" wrap="soft" style="width:100%" - class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext'; - ?> no-bar" - placeholder="<?php echo $placeholder; ?>"><?php - echo $info['comments']; ?></textarea> - </td> - </tr> - </tbody> </table> <hr> <p class="full-width"> diff --git a/include/staff/templates/task-status.tmpl.php b/include/staff/templates/task-status.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..b711e6f91c71f2e8b46a6d353ca5ef2e859d5e39 --- /dev/null +++ b/include/staff/templates/task-status.tmpl.php @@ -0,0 +1,101 @@ +<?php +global $cfg; + +if (!$info[':title']) + $info[':title'] = __('Change Tasks 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'] ?: ('#tasks/mass/'. $action); +?> +<div style="display:block; margin:5px;"> + <form method="post" name="status" id="status" + action="<?php echo $action; ?>" + class="mass-action"> + <table width="100%"> + <?php + if ($info[':extra']) { + ?> + <tbody> + <tr><td colspan="2"><strong><?php echo $info[':extra']; + ?></strong></td> </tr> + </tbody> + <?php + } + ?> + <tbody> + <tr> + <td colspan=2> + <span> + <strong><?php echo __('Status') ?>: </strong> + <select name="status"> + <?php + $statuses = array( + 'open' => __('Open'), + 'closed' => __('Closed')); + + if (!$info['status']) + echo '<option value=""> '. __('Select One') + .' </option>'; + foreach ($statuses as $k => $status) { + echo sprintf('<option value="%s" %s>%s</option>', + $k, + ($info['status'] == $k) + ? 'selected="selected"' : '', + $status + ); + } + ?> + </select> + <font class="error">* <?php echo + $errors['status']; ?></font> + </span> + </td> + </tr> + </tbody> + <tbody> + <tr> + <td colspan="2"> + <?php + $placeholder = $info[':placeholder'] ?: __('Optional reason for status change (internal note)'); + ?> + <textarea name="comments" id="comments" + cols="50" rows="3" wrap="soft" style="width:100%" + class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext'; + ?> no-bar" + placeholder="<?php echo $placeholder; ?>"><?php + echo $info['comments']; ?></textarea> + </td> + </tr> + </tbody> + </table> + <hr> + <p class="full-width"> + <span class="buttons pull-left"> + <input type="reset" value="<?php echo __('Reset'); ?>"> + <input type="button" name="cancel" class="close" + value="<?php echo __('Cancel'); ?>"> + </span> + <span class="buttons pull-right"> + <input type="submit" value="<?php + echo $verb ?: __('Submit'); ?>"> + </span> + </p> + </form> +</div> +<div class="clear"></div> diff --git a/include/staff/templates/task-transfer.tmpl.php b/include/staff/templates/task-transfer.tmpl.php index 462714bb8a431ad8236d42b580464ee3f7129c12..a45311f7f991b4fba4e0522272401edde44c376b 100644 --- a/include/staff/templates/task-transfer.tmpl.php +++ b/include/staff/templates/task-transfer.tmpl.php @@ -1,6 +1,8 @@ <?php global $cfg; +$form = $form ?: TransferForm::instantiate($info); + if (!$info[':title']) $info[':title'] = sprintf(__('%s Selected Tasks'), __('Tranfer')); @@ -41,43 +43,12 @@ $action = $info[':action'] ?: ('#tasks/mass/transfer'); ?> <tbody> <tr><td colspan=2> - <span> - <strong><?php echo __('Department') ?>: </strong> - <select name="dept_id"> - <?php - foreach (Dept::getDepartments() as $id => $name) { - if ($task && $task->getDeptId() == $id) - $name .= sprintf(' (%s) ', __('current')); - - echo sprintf('<option value="%d" %s>%s</option>', - $id, - ($info['dept_id'] == $id) - ? 'selected="selected"' : '', - $name - ); - } - ?> - </select> - <font class="error">* <?php echo - $errors['dept_id']; ?></font> - </span> + <?php + $options = array('template' => 'simple', 'form_id' => 'transfer'); + $form->render($options); + ?> </td> </tr> </tbody> - <tbody> - <tr> - <td colspan="2"> - <?php - $placeholder = $info[':placeholder'] ?: __('Optional reason for the transfer'); - ?> - <textarea name="comments" id="comments" - cols="50" rows="3" wrap="soft" style="width:100%" - class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext'; - ?> no-bar" - placeholder="<?php echo $placeholder; ?>"><?php - echo $info['comments']; ?></textarea> - </td> - </tr> - </tbody> </table> <hr> <p class="full-width"> diff --git a/include/staff/templates/task.tmpl.php b/include/staff/templates/task.tmpl.php index bf1355bc0ac77b94c672f322eee7e1389674ccf4..d92da014f9f53e7367f67daecbfe3f41b517c45b 100644 --- a/include/staff/templates/task.tmpl.php +++ b/include/staff/templates/task.tmpl.php @@ -3,6 +3,10 @@ if (!$info['title']) $info['title'] = __('New Task'); +$namespace = 'task.add'; +if ($ticket) + $namespace = sprintf('ticket.%d.task', $ticket->getId()); + ?> <div id="task-form"> <h3><?php echo $info['title']; ?></h3> @@ -24,9 +28,7 @@ if ($info['error']) { $form = $form ?: TaskForm::getInstance(); $form->render(true, __('Create New Task'), - array( - 'draft-namespace' => sprintf('ticket.%d.task', - $ticket->getId())) + array('draft-namespace' => $namespace) ); ?> <tr><th colspan=2><em><?php diff --git a/include/staff/templates/tasks-actions.tmpl.php b/include/staff/templates/tasks-actions.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..306cd6ea9ab29c390f4dd01c3bca570890b7a2fe --- /dev/null +++ b/include/staff/templates/tasks-actions.tmpl.php @@ -0,0 +1,139 @@ +<?php +// Tasks' mass actions based on logged in agent + +$actions = array(); + +if ($agent->hasPerm(Task::PERM_CLOSE)) { + + if (isset($options['status'])) { + $status = $options['status']; + ?> + <span + class="action-button" + data-dropdown="#action-dropdown-tasks-status"> + <i class="icon-caret-down pull-right"></i> + <a class="tasks-status-action" + href="#statuses"><i + class="icon-flag"></i> <?php + echo __('Change Status'); ?></a> + </span> + <div id="action-dropdown-tasks-status" + class="action-dropdown anchor-right"> + <ul> + <?php + if (!$status || !strcasecmp($status, 'closed')) { ?> + <li> + <a class="no-pjax tasks-action" + href="#tasks/mass/reopen"><i + class="icon-fixed-width icon-undo"></i> <?php + echo __('Reopen Tasks');?> </a> + </li> + <?php + } + if (!$status || !strcasecmp($status, 'open')) { + ?> + <li> + <a class="no-pjax tasks-action" + href="#tasks/mass/close"><i + class="icon-fixed-width icon-ok-circle"></i> <?php + echo __('Close Tasks');?> </a> + </li> + <?php + } ?> + </ul> + </div> +<?php + } else { + + $actions += array( + 'reopen' => array( + 'icon' => 'icon-undo', + 'action' => __('Reopen Tasks') + )); + + $actions += array( + 'close' => array( + 'icon' => 'icon-ok-circle', + 'action' => __('Close Tasks') + )); + } +} + +if ($agent->hasPerm(Task::PERM_ASSIGN)) { + $actions += array( + 'assign' => array( + 'icon' => 'icon-user', + 'action' => __('Assign Tasks') + )); +} + +if ($agent->hasPerm(Task::PERM_TRANSFER)) { + $actions += array( + 'transfer' => array( + 'icon' => 'icon-share', + 'action' => __('Transfer Tasks') + )); +} + +if ($agent->hasPerm(Task::PERM_DELETE)) { + $actions += array( + 'delete' => array( + 'icon' => 'icon-trash', + 'action' => __('Delete Tasks') + )); +} +if ($actions) { + $more = $options['morelabel'] ?: __('More'); + ?> + <span + class="action-button" + data-dropdown="#action-dropdown-moreoptions"> + <i class="icon-caret-down pull-right"></i> + <a class="tasks-action" + href="#moreoptions"><i + class="icon-reorder"></i> <?php + echo $more; ?></a> + </span> + <div id="action-dropdown-moreoptions" + class="action-dropdown anchor-right"> + <ul> + <?php foreach ($actions as $a => $action) { ?> + <li> + <a class="no-pjax tasks-action" + <?php + if ($action['dialog']) + echo sprintf("data-dialog='%s'", $action['dialog']); + if ($action['redirect']) + echo sprintf("data-redirect='%s'", $action['redirect']); + ?> + href="<?php + echo sprintf('#tasks/mass/%s', $a); ?>" + ><i class="icon-fixed-width <?php + echo $action['icon'] ?: 'icon-tag'; ?>"></i> <?php + echo $action['action']; ?></a> + </li> + <?php + } ?> + </ul> + </div> + <?php + } ?> +<script type="text/javascript"> +$(function() { + $(document).off('.tasks'); + $(document).on('click.tasks', 'a.tasks-action', function(e) { + e.preventDefault(); + var count = checkbox_checker($('form#tasks'), 1); + if (count) { + var url = 'ajax.php/' + +$(this).attr('href').substr(1) + +'?count='+count + +'&_uid='+new Date().getTime(); + $.dialog(url, [201], function (xhr) { + $.pjax.reload('#pjax-container'); + }); + } + return false; + }); +}); +</script> diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php index 8f6a86ce857528594c9e6ee2c607d2ecdcb5485c..bc10b928410dc25aeace52771f34910f7e5c5a35 100644 --- a/include/staff/tickets.inc.php +++ b/include/staff/tickets.inc.php @@ -390,11 +390,10 @@ $_SESSION[':Q:tickets'] = $orig_tickets; <tbody> <?php // Setup Subject field for display - $subject_field = TicketForm::objects()->one()->getField('subject'); + $subject_field = TicketForm::getInstance()->getField('subject'); $class = "row1"; $total=0; $ids=($errors && $_POST['tids'] && is_array($_POST['tids']))?$_POST['tids']:null; - $subject_field = TicketForm::objects()->one()->getField('subject'); foreach ($tickets as $T) { $total += 1; $tag=$T['staff_id']?'assigned':'openticket';