diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index a142fc1056deab841b3cbf5f590a19295313ac80..c9c98b04001d05cf428c14c6600de8df2952ddae 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -448,5 +448,113 @@ class TicketsAjaxAPI extends AjaxController { return $resp; } + + //Collaborators utils + function addCollaborator($tid) { + global $thisstaff; + + if (!($ticket=Ticket::lookup($tid)) + || !$ticket->checkStaffAccess($thisstaff)) + Http::response(404, 'No such ticket'); + + $errors = $info = array(); + $user = null; + $form = UserForm::getInstance(); + if ($form->isValid()) + $user = User::fromForm($form->getClean()); + + if ($user && ($c=$ticket->addCollaborator($user, $errors))) { + $info +=array('msg' => sprintf('%s added as a collaborator', + $c->getName())); + $form = null; + } elseif($errors && $errors['err']) { + $info +=array('add_error' => $errors['err']); + } else { + $info +=array('add_error' =>'Errors occurred - try again'); + } + + return self::_collaborators($ticket, $form, $info); + } + + function updateCollaborator($cid) { + global $thisstaff; + + if(!($c=Collaborator::lookup($cid)) + || !($user=$c->getUser()) + || !($ticket=$c->getTicket()) + || !$ticket->checkStaffAccess($thisstaff) + ) + Http::response(404, 'Unknown collaborator'); + + $errors = array(); + if(!$user->updateInfo($_POST, $errors)) + return self::_collaborator($c ,$user->getForms($_POST), $errors); + + $info = array('msg' => sprintf('%s updated successfully', + $c->getName())); + + return self::_collaborators($ticket, null, $info); + } + + function viewCollaborator($cid) { + global $thisstaff; + + if(!($collaborator=Collaborator::lookup($cid)) + || !($ticket=$collaborator->getTicket()) + || !$ticket->checkStaffAccess($thisstaff)) + Http::response(404, 'Unknown collaborator'); + + return self::_collaborator($collaborator); + } + + function showCollaborators($tid) { + global $thisstaff; + + if(!($ticket=Ticket::lookup($tid)) + || !$ticket->checkStaffAccess($thisstaff)) + Http::response(404, 'No such ticket'); + + return self::_collaborators($ticket); + } + + + function updateCollaborators($tid) { + global $thisstaff; + + if(!($ticket=Ticket::lookup($tid)) + || !$ticket->checkStaffAccess($thisstaff)) + Http::response(404, 'No such ticket'); + + $errors = $info = array(); + if ($ticket->updateCollaborators($_POST, $errors)) { + $info +=array('msg' => 'Collaborators updated successfully'); + } elseif($errors && $errors['err']) { + $info +=array('error' => $errors['err']); + } + + return self::_collaborators($ticket, null, $info); + } + + + + function _collaborator($collaborator, $form=null, $errors=array()) { + + ob_start(); + include(STAFFINC_DIR . 'templates/collaborator.tmpl.php'); + $resp = ob_get_contents(); + ob_end_clean(); + + return $resp; + } + + function _collaborators($ticket, $form=null, $info=array()) { + + ob_start(); + include(STAFFINC_DIR . 'templates/collaborators.tmpl.php'); + $resp = ob_get_contents(); + ob_end_clean(); + + return $resp; + } } ?> diff --git a/include/staff/templates/collaborator.tmpl.php b/include/staff/templates/collaborator.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..307a7795c2805f1c21f4edba476e5c76898f2ed2 --- /dev/null +++ b/include/staff/templates/collaborator.tmpl.php @@ -0,0 +1,30 @@ +<h3>Update Collaborator: <?php echo $collaborator->getName(); ?></h3> +<b><a class="close" href="#">×</a></b> +<?php +if($errors && $errors['err']) { + echo sprintf('<div><p id="msg_error">%s</p></div>', $errors['err']); +} ?> +<hr/> +<div> +<div>Please note that updates will be reflected system-wide.</div> +<form method="post" class="collaborators" action="#collaborators/<?php echo $collaborator->getId(); ?>"> + <table width="100%"> + <?php + if(!$forms) $forms = $collaborator->getForms(); + foreach($forms as$form) + $form->render(); ?> + </table> + <hr style="margin-top:1em"/> + <p class="full-width"> + <span class="buttons" style="float:left"> + <input type="reset" value="Reset"> + <input type="button" name="cancel" class="cancel" + data-href="#tickets/<?php echo $collaborator->getTicketId(); ?>/collaborators/manage" value="Cancel"> + </span> + <span class="buttons" style="float:right"> + <input type="submit" value="Update"> + </span> + </p> +</form> +<div class="clear"></div> +</div> diff --git a/include/staff/templates/collaborators.tmpl.php b/include/staff/templates/collaborators.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..a3a6f99ade775b38940c3a9b8833245ec9810bdb --- /dev/null +++ b/include/staff/templates/collaborators.tmpl.php @@ -0,0 +1,80 @@ +<h3>Ticket Collaborators</h3> +<b><a class="close" href="#">×</a></b> +<?php +if($info && $info['msg']) { + echo sprintf('<p id="msg_notice" style="padding-top:2px;">%s</p>', $info['msg']); +} ?> +<hr/> +<?php +if(($users=$ticket->getCollaborators())) {?> +<div id="manage_collaborators" <?php echo $form? 'style="display:none;"' : ''; ?>> +<form method="post" class="collaborators" action="#tickets/<?php echo $ticket->getId(); ?>/collaborators"> + <table border="0" cellspacing="1" cellpadding="1" width="100%"> + <?php + foreach($users as $user) { + $checked = $user->isActive() ? 'checked="checked"' : ''; + echo sprintf('<tr> + <td> + <input type="checkbox" name="cid[]" id="c%d" value="%d" %s> + <a class="editcollaborator" href="#collaborators/%d/view">%s</a> + <span class="faded"><em>%s</em></span></td> + <td width="10"> + <input type="hidden" name="del[]" id="d%d" value=""> + <a class="remove" href="#d%d">×</a></td> + <td width="30"> </td> + </tr>', + $user->getId(), + $user->getId(), + $checked, + $user->getId(), + $user->getName(), + $user->getEmail(), + $user->getId(), + $user->getId()); + } + ?> + </table> + <hr style="margin-top:1em"/> + <div><a id="addcollaborator" href="#" >Add New Collaborator</a></div> + <div id="savewarning" style="display:none; padding-top:2px;"><p id="msg_warning">You have made changes that you need to save.</p></div> + <p class="full-width"> + <span class="buttons" style="float:left"> + <input type="reset" value="Reset"> + <input type="button" value="Done" class="close"> + </span> + <span class="buttons" style="float:right"> + <input type="submit" value="Save Changes"> + </span> + </p> +</form> +<div class="clear"></div> +</div> +<?php +} +?> +<div id="add_collaborator" <?php echo ($users && !$form)? 'style="display:none;"' : ''; ?>> +<?php +if($info && $info['add_error']) { ?> +<p id="msg_error"><?php echo $info['add_error']; ?></p> +<?php +} ?> +<div>Please complete the form below to add a new collaborator.</div> +<form method="post" class="collaborators" action="#tickets/<?php echo $ticket->getId(); ?>/collaborators/add"> + <table width="100%"> + <?php + if(!$form) $form = UserForm::getInstance(); + $form->render(); ?> + </table> + <hr style="margin-top:1em"/> + <p class="full-width"> + <span class="buttons" style="float:left"> + <input type="reset" value="Reset"> + <input type="button" name="cancel" class="<?php echo !$users ? 'close': 'cancel'; ?>" value="Cancel"> + </span> + <span class="buttons" style="float:right"> + <input type="submit" value="Add"> + </span> + </p> +</form> +<div class="clear"></div> +</div> diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index 77003277411ca85485fdb137e283a4b1a6a69bfd..e980c672a73bd48c59b12d37ba4bedbfff193c63 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -818,6 +818,9 @@ $tcount+= $ticket->getNumNotes(); <?php } ?> </div> +<div style="display:none;width:650px;" class="dialog draggable collaborators"> + <div class="body"></div> +</div> <div style="display:none;" class="dialog draggable" id="user-info"> <div class="body"></div> </div> diff --git a/scp/ajax.php b/scp/ajax.php index 26d4e21a1cc58cd8da129dcd683cfc01916e19aa..464becac1d5d3bcd79b8bf644b3fcb9dffbf13c8 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -68,9 +68,16 @@ $dispatcher = patterns('', url_post('^(?P<tid>\d+)/lock', 'acquireLock'), url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/renew', 'renewLock'), url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/release', 'releaseLock'), + url_get('^(?P<tid>\d+)/collaborators/manage$', 'showCollaborators'), + url_post('^(?P<tid>\d+)/collaborators$', 'updateCollaborators'), + url_post('^(?P<tid>\d+)/collaborators/add$', 'addCollaborator'), url_get('^lookup', 'lookup'), url_get('^search', 'search') )), + url('^/collaborators/', patterns('ajax.tickets.php:TicketsAjaxAPI', + url_get('^(?P<cid>\d+)/view$', 'viewCollaborator'), + url_post('^(?P<cid>\d+)$', 'updateCollaborator') + )), url('^/draft/', patterns('ajax.draft.php:DraftAjaxAPI', url_post('^(?P<id>\d+)$', 'updateDraft'), url_delete('^(?P<id>\d+)$', 'deleteDraft'), diff --git a/scp/js/ticket.js b/scp/js/ticket.js index 619becddfc5f5029ebeeb3d64f2a489336432814..78f7ff75d058b4bf430fb057d548ea4240978280 100644 --- a/scp/js/ticket.js +++ b/scp/js/ticket.js @@ -363,6 +363,93 @@ jQuery(function($) { return false; }); + //Collaborators + $(document).on('click', 'a#managecollaborators, a#addcollaborators, a.editcollaborator', function(e) { + e.preventDefault(); + var target = $(this).attr('href').substr(1); + $('.dialog.collaborators .body').load('ajax.php/'+target, function () { + $('#overlay').show(); + $('.dialog.collaborators').show(); + }); + + return false; + }); + + $(document).on('click', 'form.collaborators a#addcollaborator', function (e) { + e.preventDefault(); + $('div#manage_collaborators').hide(); + $('div#add_collaborator').fadeIn(); + return false; + }); + + $(document).on('click', 'form.collaborators a.remove', function (e) { + e.preventDefault(); + var fObj = $(this).closest('form'); + $('input'+$(this).attr('href')) + .val($(this).attr('href').substr(2)) + .trigger('change'); + $(this).closest('tr').addClass('strike'); + + return false; + }); + + $(document).on('change', 'form.collaborators input:checkbox, input[name="del[]"]', function (e) { + var fObj = $(this).closest('form'); + $('div#savewarning', fObj).fadeIn(); + $('input:submit', fObj).css('color', 'red'); + }); + + $(document).on('click', 'form.collaborators input:reset', function(e) { + var fObj = $(this).closest('form'); + fObj.find('input[name="del[]"]').val(''); + fObj.find('tr').removeClass('strike'); + $('div#savewarning', fObj).hide(); + $('input:submit', fObj).removeAttr('style'); + }); + + + $(document).on('click', 'form.collaborators input.cancel', function (e) { + e.preventDefault(); + var $elem = $(this); + + if($elem.attr('data-href')) { + var href = $elem.data('href').substr(1); + $('.dialog.collaborators .body').load('ajax.php/'+href, function () { + }); + } else { + + $('div#manage_collaborators').show(); + $('div#add_collaborator').hide(); + } + return false; + }); + + $(document).on('change', 'form#reply select#emailreply', function(e) { + var $cc = $('form#reply tbody#cc_sec'); + if($(this).val() == 0) + $cc.hide(); + else + $cc.show(); + }); + + $(document).on('submit', 'form.collaborators', function(e) { + e.preventDefault(); + var fObj = $(this); + $.ajax({ + type: "POST", + url: 'ajax.php/'+fObj.attr('action').substr(1), + data: fObj.serialize(), + cache: false, + success: function(resp){ + $('.dialog.collaborators .body').html(resp); + $('#msg_notice, #msg_error').delay(5000).fadeOut(); + } + }) + .done(function() { }) + .fail(function() { }); + return false; + }); + var showNonLocalImage = function(div) { var $div = $(div), $img = $div.append($('<img>')