diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index 248ee66d2210156f25ce120e18e603af91484c3e..6869fe7076d668b578d097490dc464553b40b8a3 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -611,5 +611,51 @@ class TicketsAjaxAPI extends AjaxController { } + function manageForms($ticket_id) { + include(STAFFINC_DIR . 'templates/form-manage.tmpl.php'); + } + + function updateForms($ticket_id) { + global $thisstaff; + + if (!$thisstaff) + Http::response(403, "Login required"); + elseif (!($ticket = Ticket::lookup($ticket_id))) + Http::response(404, "No such ticket"); + elseif (!$ticket->checkStaffAccess($thisstaff)) + Http::response(403, "Access Denied"); + elseif (!isset($_POST['forms'])) + Http::response(422, "Send updated forms list"); + + // Add new forms + $forms = DynamicFormEntry::forTicket($ticket_id); + foreach ($_POST['forms'] as $sort => $id) { + $found = false; + foreach ($forms as $e) { + if ($e->get('form_id') == $id) { + $e->set('sort', $sort); + $e->save(); + $found = true; + break; + } + } + // New form added + if (!$found && ($new = DynamicForm::lookup($id))) { + $f = $new->instanciate(); + $f->set('sort', $sort); + $f->setTicketId($ticket_id); + $f->save(); + } + } + + // Deleted forms + foreach ($forms as $idx => $e) { + if (!in_array($e->get('form_id'), $_POST['forms'])) + $e->delete(); + } + + Http::response(201, 'Successfully managed'); + } + } ?> diff --git a/include/staff/templates/form-manage.tmpl.php b/include/staff/templates/form-manage.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..5e59011df9c12931f013395dbaa11920e0a1214f --- /dev/null +++ b/include/staff/templates/form-manage.tmpl.php @@ -0,0 +1,77 @@ +<h3><i class="icon-paste"></i> Manage Forms</i></h3> +<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b> +<hr/> +Sort the forms on this ticket by click and dragging on them. Use the box +below the forms list to add new forms to the ticket. +<br/> +<br/> +<form method="post" action="#tickets/<?php echo $ticket_id; ?>/forms/manage"> +<div id="ticket-entries"> +<?php +$current_list = array(); +foreach (DynamicFormEntry::forTicket($ticket_id) as $e) { ?> +<div class="sortable-row-item" data-id="<?php echo $e->get('id'); ?>"> + <input type="hidden" name="forms[]" value="<?php echo $e->get('form_id'); ?>" /> + <i class="icon-reorder"></i> <?php echo $e->getForm()->getTitle(); + $current_list[] = $e->get('form_id'); + if ($e->getForm()->get('type') == 'G') { ?> + <div class="delete"><a href="#"><i class="icon-trash"></i></a></div> + <?php } ?> +</div> +<?php } ?> +</div> +<hr/> +<i class="icon-plus"></i> +<select name="new-form" onchange="javascript: + var $sel = $(this).find('option:selected'); + $('#ticket-entries').append($('<div></div>').addClass('sortable-row-item') + .text(' '+$sel.text()) + .data('id', $sel.val()) + .prepend($('<i>').addClass('icon-reorder')) + .append($('<input/>').attr({name:'forms[]', type:'hidden'}).val($sel.val())) + .append($('<div></div>').addClass('delete') + .append($('<a href=\'#\'>').append($('<i>').addClass('icon-trash'))) + ) + ); + $sel.prop('disabled',true);"> +<option selected="selected" disabled="disabled">Add a new form to this ticket</option> +<?php foreach (DynamicForm::objects()->filter(array( + 'type'=>'G')) as $f +) { + if (in_array($f->get('id'), $current_list)) + continue; + ?><option value="<?php echo $f->get('id'); ?>"><?php + echo $f->getTitle(); ?></option><?php +} ?> +</select> +<div id="delete-warning" style="display:none"> +<hr> + <div id="msg_warning"> + Clicking <strong>Save Changes</strong> will permanently delete data + associated with the deleted forms + </div> +</div> + <hr> + <p class="full-width"> + <span class="buttons" style="float:left"> + <input type="reset" value="Reset"> + <input type="button" name="cancel" class="<?php echo $user ? 'cancel' : 'close' ?>" value="Cancel"> + </span> + <span class="buttons" style="float:right"> + <input type="submit" value="Save Changes"> + </span> + </p> + +<script type="text/javascript"> +$(function() { + $('#ticket-entries').sortable({containment:'parent',tolerance:'pointer'}); + $('#ticket-entries .delete a').live('click', function() { + var $div = $(this).closest('.sortable-row-item'); + $('select[name=new-form]').find('option[data-id='+$div.data('id')+']') + .prop('disabled',false); + $div.remove(); + $('#delete-warning').show(); + return false; + }) +}); +</script> diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index fc636f515dee5388adaa6ee20d554137238f3b0a..d2c8ebe9a72cc4c88c2ef56ab230bf9236b0814b 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -107,9 +107,14 @@ if($ticket->isOverdue()) <li><a class="confirm-action" id="ticket-answered" href="#answered"><i class="icon-circle-arrow-right"></i> Mark as Answered</a></li> <?php } - } + } ?> + <li><a href="#ajax.php/tickets/<?php echo $ticket->getId(); + ?>/forms/manage" onclick="javascript: + $.dialog($(this).attr('href').substr(1), 201); + return false" + ><i class="icon-paste"></i> Manage Forms</a></li> - if($thisstaff->canBanEmails()) { +<?php if($thisstaff->canBanEmails()) { if(!$emailBanned) {?> <li><a class="confirm-action" id="ticket-banemail" href="#banemail"><i class="icon-ban-circle"></i> Ban Email (<?php echo $ticket->getEmail(); ?>)</a></li> diff --git a/scp/ajax.php b/scp/ajax.php index 6be3aadd48656c68a1021813aecc1a6aa439a35c..5d12a8b43ebc215fce392f197b203bf842cfd1ec 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -118,7 +118,9 @@ $dispatcher = patterns('', url_get('^(?P<tid>\d+)/add-collaborator/auth:(?P<bk>\w+):(?P<id>.+)$', 'addRemoteCollaborator'), url('^(?P<tid>\d+)/add-collaborator$', 'addCollaborator'), url_get('^lookup', 'lookup'), - url_get('^search', 'search') + url_get('^search', 'search'), + url_get('^(?P<tid>\d+)/forms/manage$', 'manageForms'), + url_post('^(?P<tid>\d+)/forms/manage$', 'updateForms') )), url('^/collaborators/', patterns('ajax.tickets.php:TicketsAjaxAPI', url_get('^(?P<cid>\d+)/view$', 'viewCollaborator'), diff --git a/scp/css/scp.css b/scp/css/scp.css index c6554afb966cc6b6118a8fe67c21bfa8130551d1..d94b3d0b48d49548c6ca0de48136f46bfc6916d4 100644 --- a/scp/css/scp.css +++ b/scp/css/scp.css @@ -1577,7 +1577,8 @@ div.selected-signature .inner { } .action-button.danger { color: #999 !important; - background-color: rgba(220,220,220,0.5); + background: transparent; + border: 1px solid rgba(0,0,0,0.5); opacity: 0.6; } @@ -1587,3 +1588,44 @@ div.selected-signature .inner { top: 4px; right: 5px; } + +.sortable-row-item { + border: 1px solid rgba(0, 0, 0, 0.7); + padding: 9px; + cursor: crosshair; + position: relative; +} +.sortable-row-item:hover { + background: rgba(0, 0, 0, 0.1); +} +.sortable-row-item:active { + background: rgba(0, 0, 0, 0.3); +} +.sortable-row-item:first-child { + border-top-right-radius: 5px; + border-top-left-radius: 5px; +} +.sortable-row-item:last-child { + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; +} +.sortable-row-item + .sortable-row-item { + margin-top: -1px; +} + +.sortable-row-item .delete { + border-left: 1px solid rgba(0, 0, 0, 0.7); + border-top-right-radius: inherit; + border-bottom-right-radius: inherit; + position: absolute; + top: 0px; + right: 0; + padding: 9px; + padding-left: 12px; + font-size: 105%; +} + +.sortable-row-item .delete:hover { + background: #fc9f41; /* Old browsers */ + color: rgba(255,255,255,0.8) !important; +}