Skip to content
Snippets Groups Projects
Commit bb2acd50 authored by Peter Rotich's avatar Peter Rotich
Browse files

tasks: Add tasks support to tickets

Introduce the initial concept of adding tasks to a ticket.
parent 94b342b4
Branches
Tags
No related merge requests found
<?php
/*********************************************************************
ajax.tasks.php
AJAX interface for tasks
Peter Rotich <peter@osticket.com>
Copyright (c) 20014 osTicket
http://www.osticket.com
Released under the GNU General Public License WITHOUT ANY WARRANTY.
See LICENSE.TXT for details.
vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
if(!defined('INCLUDE_DIR')) die('403');
include_once(INCLUDE_DIR.'class.ticket.php');
require_once(INCLUDE_DIR.'class.ajax.php');
require_once(INCLUDE_DIR.'class.task.php');
class TasksAjaxAPI extends AjaxController {
function preview($tid) {
global $thisstaff;
// TODO: check staff's access.
if(!$thisstaff || !($task=Task::lookup($tid)))
Http::response(404, __('No such task'));
include STAFFINC_DIR . 'templates/task-preview.tmpl.php';
}
function task($tid) {
global $thisstaff;
// TODO: check staff's access.
if (!$thisstaff || !($task=Task::lookup($tid)))
Http::response(404, __('No such task'));
$info=$errors=array();
$task_note_form = new Form(array(
'attachments' => new FileUploadField(array('id'=>'attach',
'name'=>'attach:note',
'configuration' => array('extensions'=>'')))
));
if ($_POST) {
switch ($_POST['a']) {
case 'postnote':
$vars = $_POST;
$attachments = $task_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();
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';
}
}
?>
...@@ -854,5 +854,47 @@ class TicketsAjaxAPI extends AjaxController { ...@@ -854,5 +854,47 @@ class TicketsAjaxAPI extends AjaxController {
include(STAFFINC_DIR . 'templates/ticket-status.tmpl.php'); include(STAFFINC_DIR . 'templates/ticket-status.tmpl.php');
} }
function tasks($tid) {
global $thisstaff;
if (!($ticket=Ticket::lookup($tid))
|| !$ticket->checkStaffAccess($thisstaff))
Http::response(404, 'Unknown ticket');
include STAFFINC_DIR . 'ticket-tasks.inc.php';
}
function addTask($tid) {
global $thisstaff;
if (!($ticket=Ticket::lookup($tid))
|| !$ticket->checkStaffAccess($thisstaff))
Http::response(404, 'Unknown ticket');
$info = array();
if ($_POST) {
/*
Draft::deleteForNamespace(
sprintf('ticket.%d.task', $ticket->getId()),
$thisstaff->getId());
*/
$form = TaskForm::getDefaultForm()->getForm($_POST);
if ($form && ($task = Task::create($form, $ticket)))
Http::response(201, $task->to_json());
$info['error'] = __('Error adding task - try again!');
}
$info['action'] = sprintf('#tickets/%d/add-task', $ticket->getId());
$info['title'] = sprintf(
__( 'Ticket #%1$s: %2$s'),
$ticket->getNumber(),
_('Add New Task')
);
include STAFFINC_DIR . 'templates/task.tmpl.php';
}
} }
?> ?>
...@@ -31,6 +31,7 @@ $showing=$pageNav->showing().' '._N('form','forms',$count); ...@@ -31,6 +31,7 @@ $showing=$pageNav->showing().' '._N('form','forms',$count);
$forms = array( $forms = array(
'U' => 'icon-user', 'U' => 'icon-user',
'T' => 'icon-ticket', 'T' => 'icon-ticket',
'A' => 'icon-tasks',
'C' => 'icon-building', 'C' => 'icon-building',
'O' => 'icon-group', 'O' => 'icon-group',
); );
......
<?php
$error=$msg=$warn=null;
if($lock && $lock->getStaffId()==$thisstaff->getId())
$warn.='&nbsp;<span class="Icon lockedTicket">'
.sprintf(__('Ticket is locked by %s'), $lock->getStaffName()).'</span>';
elseif($task->isOverdue())
$warn.='&nbsp;<span class="Icon overdueTicket">'.__('Marked overdue!').'</span>';
echo sprintf(
'<div style="width:600px; padding: 2px 2px 0 5px;" id="t%s">
<h2>'.__('Task #%s').': %s</h2><br>',
$task->getNumber(),
$task->getNumber(),
Format::htmlchars($task->getTitle()));
if($error)
echo sprintf('<div id="msg_error">%s</div>',$error);
elseif($msg)
echo sprintf('<div id="msg_notice">%s</div>',$msg);
elseif($warn)
echo sprintf('<div id="msg_warning">%s</div>',$warn);
echo '<ul class="tabs" id="ticket-preview">';
echo '
<li><a id="preview_tab" href="#preview" class="active"
><i class="icon-list-alt"></i>&nbsp;'.__('Task Summary').'</a></li>';
if (0 && $task->getNumCollaborators()) {
echo sprintf('
<li><a id="collab_tab" href="#collab"
><i class="icon-fixed-width icon-group
faded"></i>&nbsp;'.__('Collaborators (%d)').'</a></li>',
$task->getNumCollaborators());
}
echo '</ul>';
echo '<div id="ticket-preview_container">';
echo '<div class="tab_content" id="preview_tab_content">';
echo '<table border="0" cellspacing="" cellpadding="1" width="100%" class="ticket_info">';
$status=sprintf('<span>%s</span>',ucfirst($task->getStatus()));
echo sprintf('
<tr>
<th width="100">'.__('Status').':</th>
<td>%s</td>
</tr>
<tr>
<th>'.__('Created').':</th>
<td>%s</td>
</tr>',$status,
Format::db_datetime($task->getCreateDate()));
if (0 && $task->isOpen() && $task->getEstDueDate()) {
echo sprintf('
<tr>
<th>'.__('Due Date').':</th>
<td>%s</td>
</tr>',
Format::db_datetime($task->getEstDueDate()));
}
echo '</table>';
echo '<hr>
<table border="0" cellspacing="" cellpadding="1" width="100%" class="ticket_info">';
if(0 && $ticket->isOpen()) {
echo sprintf('
<tr>
<th width="100">'.__('Assigned To').':</th>
<td>%s</td>
</tr>',$ticket->isAssigned()?implode('/', $ticket->getAssignees()):' <span class="faded">&mdash; '.__('Unassigned').' &mdash;</span>');
}
echo sprintf(
'
<tr>
<th width="100">'.__('Department').':</th>
<td>%s</td>
</tr>',
Format::htmlchars('Dept. HERE')
);
echo '
</table>';
echo '</div>';
?>
<div class="tab_content" id="collab_tab_content" style="display:none;">
<table border="0" cellspacing="" cellpadding="1">
<colgroup><col style="min-width: 250px;"></col></colgroup>
<?php
if (0 && ($collabs=$task->getCollaborators())) {?>
<?php
foreach($collabs as $collab) {
echo sprintf('<tr><td %s><i class="icon-%s"></i>
<a href="users.php?id=%d" class="no-pjax">%s</a> <em>&lt;%s&gt;</em></td></tr>',
($collab->isActive()? '' : 'class="faded"'),
($collab->isActive()? 'comments' : 'comment-alt'),
$collab->getUserId(),
$collab->getName(),
$collab->getEmail());
}
} else {
echo __("Task doesn't have any collaborators.");
}?>
</table>
<br>
<?php
echo sprintf('<span><a class="collaborators"
href="#tasks/%d/collaborators">%s</a></span>',
$task->getId(),
0
? __('Manage Collaborators') : __('Add Collaborator')
);
?>
</div>
</div>
<?php
$options = array();
$options[]=array('action'=>sprintf(__('Thread (%d)'),
$task->getThread()->getNumEntries()),
'url'=>"tickets.php?id=$tid");
if ($thisstaff->canAssignTickets())
$options[]=array('action'=>($task->isAssigned()?__('Reassign'):__('Assign')),'url'=>"tickets.php?id=$tid#assign");
if ($thisstaff->canTransferTickets())
$options[]=array('action'=>'Transfer','url'=>"tickets.php?id=$tid#transfer");
if ($thisstaff->canEditTickets())
$options[]=array('action'=>'Edit Task','url'=>"tickets.php?id=$tid&a=edit");
if ($options) {
echo '<ul class="tip_menu">';
foreach($options as $option)
echo sprintf('<li><a href="%s">%s</a></li>',$option['url'],$option['action']);
echo '</ul>';
}
echo '</div>';
?>
<?php
if (!defined('OSTSCPINC') || !$thisstaff || !is_object($task))
die('Invalid path');
//Make sure the staff is allowed to access this task
/*
if (!@$thisstaff->isStaff() || !$task->checkStaffAccess($thisstaff))
die('Access Denied');
*/
//Re-use the post info on error...savekeyboards.org (Why keyboard? -> some people care about objects than users!!)
$info=($_POST && $errors)?Format::input($_POST):array();
/*
$dept = $task->getDept(); //Dept
$staff = $task->getStaff(); //Assigned or closed by..
$team = $task->getTeam(); //Assigned team.
*/
$id = $task->getId(); //Ticket ID.
if ($task->isOverdue())
$warn.='&nbsp;&nbsp;<span class="Icon overdueTicket">'.__('Marked overdue!').'</span>';
?>
<table width="940" cellpadding="2" cellspacing="0" border="0">
<tr>
<td width="20%" class="has_bottom_border">
<h3><a href="#tasks/<?php echo $task->getId(); ?>/view"
id="reload-task"><i class="icon-refresh"></i> <?php
echo sprintf(__('Task #%s'), $task->getNumber()); ?></a>
</h3>
</td>
<td width="auto" class="flush-right has_bottom_border">
<span>
<i class="icon-list"></i>
<select name="task-action">
<option value="" selected="selected">
<?php echo _('Task Options'); ?>
</option>
</select>
</span>
</td>
</tr>
</table>
<table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0">
<tr>
<td width="50%">
<table border="0" cellspacing="" cellpadding="4" width="100%">
<tr>
<th width="100"><?php echo __('Status');?>:</th>
<td><?php echo $task->getStatus(); ?></td>
</tr>
<tr>
<th><?php echo __('Department');?>:</th>
<td><?php echo Format::htmlchars( (string) $task->getDept()); ?></td>
</tr>
<tr>
<th><?php echo __('Create Date');?>:</th>
<td><?php echo Format::db_datetime($task->getCreateDate()); ?></td>
</tr>
</table>
</td>
<td width="50%" style="vertical-align:top">
<table cellspacing="0" cellpadding="4" width="100%" border="0">
<?php
if ($task->isOpen()) { ?>
<tr>
<th width="100"><?php echo __('Assigned To');?>:</th>
<td>
<?php
if ( 0 && $ticket->isAssigned())
echo Format::htmlchars(implode('/', $ticket->getAssignees()));
else
echo '<span class="faded">&mdash; '.__('Unassigned').' &mdash;</span>';
?>
</td>
</tr>
<?php
} else { ?>
<tr>
<th width="100"><?php echo __('Closed By');?>:</th>
<td>
<?php
if (0 && ($staff = $task->getStaff()))
echo Format::htmlchars($staff->getName());
else
echo '<span class="faded">&mdash; '.__('Unknown').' &mdash;</span>';
?>
</td>
</tr>
<?php
} ?>
<tr>
<th><?php echo __('SLA Plan');?>:</th>
<td><?php echo $sla?Format::htmlchars($sla->getName()):'<span class="faded">&mdash; '.__('None').' &mdash;</span>'; ?></td>
</tr>
<?php
if($task->isOpen()){ ?>
<tr>
<th><?php echo __('Due Date');?>:</th>
<td><?php echo 'here'; //Format::db_datetime($ticket->getEstDueDate()); ?></td>
</tr>
<?php
}else { ?>
<tr>
<th><?php echo __('Close Date');?>:</th>
<td><?php echo 0 ?
Format::db_datetime($task->getCloseDate()) : ' recently! '; ?></td>
</tr>
<?php
}
?>
</table>
</td>
</tr>
</table>
<br>
<br>
<table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0">
<?php
$idx = 0;
foreach (DynamicFormEntry::forObject($task->getId(),
ObjectModel::OBJECT_TYPE_TASK) as $form) {
$answers = array_filter($form->getAnswers(), function ($a) {
return $a->getField()->isStorable();
});
if (count($answers) == 0)
continue;
?>
<tr>
<td colspan="2">
<table cellspacing="0" cellpadding="4" width="100%" border="0">
<?php foreach($answers as $a) {
if (!($v = $a->display())) continue; ?>
<tr>
<th width="100"><?php
echo $a->getField()->get('label');
?>:</th>
<td><?php
echo $v;
?></td>
</tr>
<?php
} ?>
</table>
</td>
</tr>
<?php
$idx++;
} ?>
</table>
<div class="clear"></div>
<div id="task_thread_container">
<div id="task_thread_content">
<?php
$threadTypes=array('M'=>'message','R'=>'response', 'N'=>'note');
/* -------- Messages & Responses & Notes (if inline)-------------*/
$types = array('M', 'R', 'N');
if(($thread=$task->getThreadEntries($types))) {
foreach($thread as $entry) { ?>
<table class="thread-entry <?php echo $threadTypes[$entry['type']]; ?>" cellspacing="0" cellpadding="1" width="940" border="0">
<tr>
<th colspan="4" width="100%">
<div>
<span class="pull-left">
<span style="display:inline-block"><?php
echo Format::db_datetime($entry['created']);?></span>
<span style="display:inline-block;padding:0 1em" class="faded title"><?php
echo Format::truncate($entry['title'], 100); ?></span>
</span>
<span class="pull-right" style="white-space:no-wrap;display:inline-block">
<span style="vertical-align:middle;" class="textra"></span>
<span style="vertical-align:middle;"
class="tmeta faded title"><?php
echo Format::htmlchars($entry['name'] ?: $entry['poster']); ?></span>
</span>
</div>
</th>
</tr>
<tr><td colspan="4" class="thread-body" id="thread-id-<?php
echo $entry['id']; ?>"><div><?php
echo $entry['body']->toHtml(); ?></div></td></tr>
<?php
$urls = null;
if($entry['attachments']
&& ($tentry = $task->getThreadEntry($entry['id']))
&& ($urls = $tentry->getAttachmentUrls())
&& ($links = $tentry->getAttachmentsLinks())) {?>
<tr>
<td class="info" colspan="4"><?php echo $links; ?></td>
</tr> <?php
}
if ($urls) { ?>
<script type="text/javascript">
$('#thread-id-<?php echo $entry['id']; ?>')
.data('urls', <?php
echo JsonDataEncoder::encode($urls); ?>)
.data('id', <?php echo $entry['id']; ?>);
</script>
<?php
} ?>
</table>
<?php
if ($entry['type'] == 'M')
$msgId = $entry['id'];
}
} else {
echo '<p>'.__('Error fetching thread - get technical help.').'</p>';
}?>
</div>
</div>
<div class="clear" style="padding-bottom:10px;"></div>
<?php if($errors['err']) { ?>
<div id="msg_error"><?php echo $errors['err']; ?></div>
<?php }elseif($msg) { ?>
<div id="msg_notice"><?php echo $msg; ?></div>
<?php }elseif($warn) { ?>
<div id="msg_warning"><?php echo $warn; ?></div>
<?php } ?>
<div id="response_options">
<ul class="tabs"></ul>
<form id="task_note"
action="#tasks/<? echo $task->getId(); ?>"
name="task_note"
method="post" enctype="multipart/form-data">
<?php csrf_token(); ?>
<input type="hidden" name="id" value="<?php echo $task->getId(); ?>">
<input type="hidden" name="a" value="postnote">
<table width="100%" border="0" cellspacing="0" cellpadding="3">
<tr>
<td>
<div>
<div class="faded" style="padding-left:0.15em"><?php
echo __('Note title - summary of the note (optional)'); ?></div>
<input type="text" name="title" id="title" size="60" value="<?php echo $info['title']; ?>" >
<br/>
<span class="error">&nbsp;<?php echo $errors['title']; ?></span>
</div>
<div>
<label><strong><?php echo __('Internal Note'); ?></strong><span class='error'>&nbsp;* <?php echo $errors['note']; ?></span></label>
</div>
<textarea name="note" id="internal_note" cols="80"
placeholder="<?php echo __('Note details'); ?>"
rows="9" wrap="soft" data-draft-namespace="task.note"
data-draft-object-id="<?php echo $task->getId(); ?>"
class="richtext ifhtml draft draft-delete"><?php
echo $info['note'];
?></textarea>
<div class="attachments">
<?php
if ($task_note_form)
print $task_note_form->getField('attachments')->render();
?>
</div>
</td>
</tr>
<tr>
<td>
<div><?php echo __('Task Status');?>
<span class="faded"> - </span>
<select name="task_status">
<option value="1" <?php
echo $task->isOpen() ?
'selected="selected"': ''; ?>> <?php
echo _('Open'); ?></option>
<option value="0" <?php
echo $task->isClosed() ?
'selected="selected"': ''; ?>> <?php
echo _('Closed'); ?></option>
</select>
&nbsp;<span class='error'><?php echo
$errors['task_status']; ?></span>
</div>
</td>
</tr>
</table>
<p style="padding-left:165px;">
<input class="btn_sm" type="submit" value="<?php echo __('Post Note');?>">
<input class="btn_sm" type="reset" value="<?php echo __('Reset');?>">
</p>
</form>
</div>
<script type="text/javascript">
$(function() {
$(document).on('click', 'a.active#ticket_tasks', function(e) {
e.preventDefault();
$('div#task_content').hide().empty();
$('div#tasks_content').show();
return false;
});
$(document).off('.tf');
$(document).on('submit.tf', 'form#task_note', function(e) {
e.preventDefault();
var $form = $(this);
var $container = $('div#task_content');
$.ajax({
type: $form.attr('method'),
url: 'ajax.php/'+$form.attr('action').substr(1),
data: $form.serialize(),
cache: false,
success: function(resp, status, xhr) {
$container.html(resp);
$('#msg_notice, #msg_error',$container)
.delay(5000)
.slideUp();
}
})
.done(function() { })
.fail(function() { });
});
});
</script>
<?php
if (!$info['title'])
$info['title'] = __('New Task');
?>
<div id="task-form">
<h3><?php echo $info['title']; ?></h3>
<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
<hr/>
<?php
if ($info['error']) {
echo sprintf('<p id="msg_error">%s</p>', $info['error']);
} elseif ($info['warning']) {
echo sprintf('<p id="msg_warning">%s</p>', $info['warning']);
} elseif ($info['msg']) {
echo sprintf('<p id="msg_notice">%s</p>', $info['msg']);
} ?>
<div id="new-task-form" style="display:block;">
<form method="post" class="org" action="<?php echo $info['action'] ?: '#tasks/add'; ?>">
<table width="100%" class="fixed">
<?php
if (!$form) $form = TaskForm::getInstance();
$form->render(true,
__('Create New Task'),
array(
'draft-namespace' => sprintf('ticket.%d.task',
$ticket->getId()))
); ?>
</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 __('Create Task'); ?>">
</span>
</p>
</form>
</div>
<div class="clear"></div>
</div>
<?php
//TODO: Make it ORM based once we marge other models.
$select ='SELECT task.*, dept.dept_name '
.' ,CONCAT_WS(" ", staff.firstname, staff.lastname) as staff, team.name as team '
.' ,IF(staff.staff_id IS NULL,team.name,CONCAT_WS(" ", staff.lastname, staff.firstname)) as assigned ';
$from =' FROM '.TASK_TABLE.' task '
.' LEFT JOIN '.DEPT_TABLE.' dept ON task.dept_id=dept.dept_id '
.' LEFT JOIN '.STAFF_TABLE.' staff ON (task.staff_id=staff.staff_id) '
.' LEFT JOIN '.TEAM_TABLE.' team ON (task.team_id=team.team_id) ';
if ($ticket)
$where = 'WHERE task.object_type="T" AND task.object_id = '.db_input($ticket->getId());
$query ="$select $from $where ORDER BY task.created DESC";
// Fetch the results
$results = array();
$res = db_query($query);
while ($row = db_fetch_array($res))
$results[$row['id']] = $row;
?>
<div id="tasks_content" style="display:block;">
<div style="width:700px; float:left;">
<?php
if ($results) {
echo '<strong>'.sprintf(_N('Showing %d Task', 'Showing %d Tasks',
count($results)), count($results)).'</strong>';
} else {
echo sprintf(__('%s does not have any tasks'), $ticket? 'Ticket' :
'System');
}
?>
</div>
<div style="float:right;text-align:right;padding-right:5px;">
<?php
if ($ticket) { ?>
<a
class="Icon newTicket ticket-action"
data-dialog='{"size":"large"}'
href="#tickets/<?php
echo $ticket->getId(); ?>/add-task"> <?php
print __('Add New Task'); ?></a>
<?php
} ?>
</div>
<br/>
<div>
<?php
if ($results) { ?>
<form action="tickets.php?id=<?php echo $ticket->getId(); ?>" method="POST" name='tasks' style="padding-top:10px;">
<?php csrf_token(); ?>
<input type="hidden" name="a" value="mass_process" >
<input type="hidden" name="do" id="action" value="" >
<table class="list" border="0" cellspacing="1" cellpadding="2" width="940">
<thead>
<tr>
<?php
if (0) {?>
<th width="8px">&nbsp;</th>
<?php
} ?>
<th width="70"><?php echo __('Number'); ?></th>
<th width="100"><?php echo __('Date'); ?></th>
<th width="100"><?php echo __('Status'); ?></th>
<th width="300"><?php echo __('Title'); ?></th>
<th width="200"><?php echo __('Department'); ?></th>
<th width="200"><?php echo __('Assignee'); ?></th>
</tr>
</thead>
<tbody class="tasks">
<?php
foreach($results as $row) {
if (!($task = Task::lookup($row['id'])))
continue;
$flag=null;
if ($row['lock_id'])
$flag='locked';
elseif ($row['isoverdue'])
$flag='overdue';
$assigned='';
if ($row['staff_id'])
$assigned=sprintf('<span class="Icon staffAssigned">%s</span>',Format::truncate($row['staff'],40));
elseif ($row['team_id'])
$assigned=sprintf('<span class="Icon teamAssigned">%s</span>',Format::truncate($row['team'],40));
else
$assigned=' ';
$status = $task->isOpen() ? '<strong>open</strong>': 'closed';
$tid=$row['number'];
$title = Format::htmlchars(Format::truncate($task->getTitle(),40));
$threadcount= $task->getThread()->getNumEntries();
?>
<tr id="<?php echo $row['id']; ?>">
<?php
//Implement mass action....if need be.
if (0) { ?>
<td align="center" class="nohover">
<input class="ckb" type="checkbox" name="tids[]"
value="<?php echo $row['id']; ?>" <?php echo $sel?'checked="checked"':''; ?>>
</td>
<?php
} ?>
<td align="center" nowrap>
<a class="Icon no-pjax preview"
title="<?php echo __('Preview Task'); ?>"
href="#tasks/<?php echo $task->getId(); ?>/view"
data-preview="#tasks/<?php echo $task->getId(); ?>/preview"
><?php echo $task->getNumber(); ?></a></td>
<td align="center" nowrap><?php echo
Format::db_datetime($row['created']); ?></td>
<td><?php echo $status; ?></td>
<td><a <?php if ($flag) { ?> class="no-pjax"
title="<?php echo ucfirst($flag); ?> Task" <?php } ?>
href="#tasks/<?php echo $task->getId(); ?>/view"><?php
echo $title; ?></a>
<?php
if ($threadcount>1)
echo "<small>($threadcount)</small>&nbsp;".'<i
class="icon-fixed-width icon-comments-alt"></i>&nbsp;';
if ($row['collaborators'])
echo '<i class="icon-fixed-width icon-group faded"></i>&nbsp;';
if ($row['attachments'])
echo '<i class="icon-fixed-width icon-paperclip"></i>&nbsp;';
?>
</td>
<td><?php echo Format::truncate($row['dept_name'], 40); ?></td>
<td>&nbsp;<?php echo $assigned; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</form>
<?php
} ?>
</div>
</div>
<div id="task_content" style="display:none;">
</div>
<script type="text/javascript">
$(function() {
$(document).on('click.tasks', 'tbody.tasks a, a#reload-task', function(e) {
e.preventDefault();
var url = 'ajax.php/'+$(this).attr('href').substr(1);
var $container = $('div#task_content');
$container.load(url, function () {
$('.tip_box').remove();
$('div#tasks_content').hide();
}).show();
return false;
});
});
</script>
...@@ -378,6 +378,12 @@ $tcount+= $ticket->getNumNotes(); ...@@ -378,6 +378,12 @@ $tcount+= $ticket->getNumNotes();
?> ?>
<ul class="tabs threads" id="ticket_tabs" > <ul class="tabs threads" id="ticket_tabs" >
<li><a class="active" href="#ticket_thread"><?php echo sprintf(__('Ticket Thread (%d)'), $tcount); ?></a></li> <li><a class="active" href="#ticket_thread"><?php echo sprintf(__('Ticket Thread (%d)'), $tcount); ?></a></li>
<li><a id="ticket_tasks" href="<?php
echo sprintf('#tickets/%d/tasks', $ticket->getId()); ?>"><?php
echo __('Tasks');
if ($ticket->getNumTasks())
echo sprintf('&nbsp;(%d)', $ticket->getNumTasks());
?></a></li>
</ul> </ul>
<div id="ticket_tabs_container"> <div id="ticket_tabs_container">
<div id="ticket_thread" class="tab_content"> <div id="ticket_thread" class="tab_content">
......
...@@ -144,6 +144,8 @@ $dispatcher = patterns('', ...@@ -144,6 +144,8 @@ $dispatcher = patterns('',
url_post('^(?P<tid>\d+)/status$', 'setTicketStatus'), url_post('^(?P<tid>\d+)/status$', 'setTicketStatus'),
url_get('^status/(?P<status>\w+)(?:/(?P<sid>\d+))?$', 'changeSelectedTicketsStatus'), url_get('^status/(?P<status>\w+)(?:/(?P<sid>\d+))?$', 'changeSelectedTicketsStatus'),
url_post('^status/(?P<state>\w+)$', 'setSelectedTicketsStatus'), url_post('^status/(?P<state>\w+)$', 'setSelectedTicketsStatus'),
url_get('^(?P<tid>\d+)/tasks$', 'tasks'),
url('^(?P<tid>\d+)/add-task$', 'addTask'),
url_get('^lookup', 'lookup'), url_get('^lookup', 'lookup'),
url('^search', patterns('ajax.search.php:SearchAjaxAPI', url('^search', patterns('ajax.search.php:SearchAjaxAPI',
url_get('^$', 'getAdvancedSearchDialog'), url_get('^$', 'getAdvancedSearchDialog'),
...@@ -156,6 +158,11 @@ $dispatcher = patterns('', ...@@ -156,6 +158,11 @@ $dispatcher = patterns('',
url_get('^/field/(?P<id>[\w_!:]+)$', 'addField') url_get('^/field/(?P<id>[\w_!:]+)$', 'addField')
)) ))
)), )),
url('^/tasks/', patterns('ajax.tasks.php:TasksAjaxAPI',
url_get('^(?P<tid>\d+)/preview$', 'preview'),
url_get('^(?P<tid>\d+)/view$', 'task'),
url_post('^(?P<tid>\d+)$', 'task')
)),
url('^/collaborators/', patterns('ajax.tickets.php:TicketsAjaxAPI', url('^/collaborators/', patterns('ajax.tickets.php:TicketsAjaxAPI',
url_get('^(?P<cid>\d+)/view$', 'viewCollaborator'), url_get('^(?P<cid>\d+)/view$', 'viewCollaborator'),
url_post('^(?P<cid>\d+)$', 'updateCollaborator') url_post('^(?P<cid>\d+)$', 'updateCollaborator')
......
...@@ -459,7 +459,7 @@ table.list thead th { ...@@ -459,7 +459,7 @@ table.list thead th {
color:#000; color:#000;
text-align:left; text-align:left;
vertical-align:top; vertical-align:top;
padding: 2px 4px; padding: 4px 5px;
} }
table.list th a { table.list th a {
...@@ -468,7 +468,7 @@ table.list th a { ...@@ -468,7 +468,7 @@ table.list th a {
color:#000; color:#000;
} }
table.list thead th a { padding: 3px; padding-right: 15px; display: block; white-space: nowrap; color: #000; background: url('../images/asc_desc.gif') 100% 50% no-repeat; } table.list thead th a { padding-right: 15px; display: block; white-space: nowrap; color: #000; background: url('../images/asc_desc.gif') 100% 50% no-repeat; }
table.list thead th a.asc { background: url('../images/asc.gif') 100% 50% no-repeat #cfe6ff; } table.list thead th a.asc { background: url('../images/asc.gif') 100% 50% no-repeat #cfe6ff; }
table.list thead th a.desc { background: url('../images/desc.gif') 100% 50% no-repeat #cfe6ff; } table.list thead th a.desc { background: url('../images/desc.gif') 100% 50% no-repeat #cfe6ff; }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment