Newer
Older
/*********************************************************************
ticket.js
Ticket utility loaded on ticket view!
Useful for UI config settings, ticket locking ...etc
Peter Rotich <peter@osticket.com>
http://www.osticket.com
Released under the GNU General Public License WITHOUT ANY WARRANTY.
vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
var autoLock = {
lastattemptTime: 0,
acquireTime: 0,
renewTime: 0,
renewFreq: 10000, //renewal frequency in seconds...based on returned lock time.
time: 0,
lockAttempts: 0, //Consecutive lock attempt errors
maxattempts: 2, //Maximum failed lock attempts before giving up.
warn: true,
retry: true,
addEvent: function(elm, evType, fn, useCapture) {
if(elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
}else if(elm.attachEvent) {
return elm.attachEvent('on' + evType, fn);
}else{
elm['on' + evType] = fn;
}
},
removeEvent: function(elm, evType, fn, useCapture) {
if(elm.removeEventListener) {
elm.removeEventListener(evType, fn, useCapture);
return true;
}else if(elm.detachEvent) {
return elm.detachEvent('on' + evType, fn);
}else {
elm['on' + evType] = null;
}
},
//Incoming event...
handleEvent: function(e) {
if(autoLock.lockId && !autoLock.lasteventTime) { //I hate nav away warnings..but
$(document).on('pjax:beforeSend.changed', function(e) {
return confirm(__("Any changes or info you've entered will be discarded!"));
$(window).bind('beforeunload', function(e) {
return __("Any changes or info you've entered will be discarded!");
// Handle events only every few seconds
var now = new Date().getTime(),
renewFreq = autoLock.renewFreq;
if (autoLock.lasteventTime && now - autoLock.lasteventTime < renewFreq)
return;
autoLock.lasteventTime = now;
if (!autoLock.lockId) {
// Retry every 5 seconds??
if (autoLock.retry)
autoLock.acquireLock(e,autoLock.warn);
} else {
autoLock.renewLock(e);
}
},
//Watch activity on individual form.
watchForm: function(fObj,fn) {
if(!fObj || !fObj.length)
return;
//Watch onSubmit event on the form.
autoLock.addEvent(fObj,'submit',autoLock.onSubmit,true);
//Watch activity on text + textareas + select fields.
for (var i=0; i<fObj.length; i++) {
switch(fObj[i].type) {
case 'textarea':
case 'text':
autoLock.addEvent(fObj[i],'keyup',autoLock.handleEvent,true);
break;
case 'select-one':
case 'select-multiple':
if(fObj.name!='reply') //Bug on double ajax call since select make it's own ajax call. TODO: fix it
autoLock.addEvent(fObj[i],'change',autoLock.handleEvent,true);
break;
default:
}
}
},
//Watch all the forms on the document.
watchDocument: function() {
//Watch forms of interest only.
for (var i=0; i<document.forms.length; i++) {
if(!document.forms[i].id.value || parseInt(document.forms[i].id.value)!=autoLock.tid)
continue;
autoLock.watchForm(document.forms[i],autoLock.checkLock);
}
},
Init: function(config) {
Peter Rotich
committed
//make sure we are on ticket view page & locking is enabled!
var fObj=$('form#note');
if(!fObj
|| !$(':input[name=id]',fObj).length
Peter Rotich
committed
|| !$(':input[name=locktime]',fObj).length
|| $(':input[name=locktime]',fObj).val()==0) {
return;
Peter Rotich
committed
void(autoLock.tid=parseInt($(':input[name=id]',fObj).val()));
void(autoLock.lockTime=parseInt($(':input[name=locktime]',fObj).val()));
autoLock.watchDocument();
autoLock.addEvent(window,'unload',autoLock.releaseLock,true); //Release lock regardless of any activity.
},
onSubmit: function(e) {
if(e.type=='submit') { //Submit. double check!
//remove nav away warning if any.
$(window).unbind('beforeunload');
//Only warn if we had a failed lock attempt.
if(autoLock.warn && !autoLock.lockId && autoLock.lasteventTime) {
var answer=confirm(__('Unable to acquire a lock on the ticket. Someone else could be working on the same ticket. Please confirm if you wish to continue anyways.'));
if(!answer) {
e.returnValue=false;
e.cancelBubble=true;
if(e.preventDefault) {
e.preventDefault();
}
return false;
}
}
}
return true;
},
if(!autoLock.tid) { return false; }
var warn = warn || false;
if(autoLock.lockId) {
autoLock.renewLock(e);
} else {
$.ajax({
url: 'ajax.php/tickets/'+autoLock.tid+'/lock',
dataType: 'json',
cache: false,
success: function(lock){
autoLock.setLock(lock,'acquire',warn);
}
//Renewal only happens on form activity..
if (!autoLock.lockId)
return false;
var now = new Date().getTime(),
renewFreq = autoLock.renewFreq;
if (autoLock.lastcheckTime && now - autoLock.lastcheckTime < renewFreq)
return;
autoLock.lastcheckTime = now;
$.ajax({
type: 'POST',
url: 'ajax.php/tickets/'+autoLock.tid+'/lock/'+autoLock.lockId+'/renew',
dataType: 'json',
cache: false,
success: function(lock){
autoLock.setLock(lock,'renew',autoLock.warn);
}
});
if (!autoLock.tid || !autoLock.lockId) { return false; }
url: 'ajax.php/tickets/'+autoLock.tid+'/lock/'+autoLock.lockId+'/release',
},
setLock: function(lock, action, warn) {
var warn = warn || false;
autoLock.lockId=lock.id; //override the lockid.
if (lock.code) {
autoLock.lockCode = lock.code;
// Update the lock code for the upcoming POST
var el = $('input[name=lockCode]').val(lock.code);
}
switch(action){
case 'renew':
if(!lock.id && lock.retry) {
autoLock.lockAttempts=1; //reset retries.
autoLock.acquireLock(e,false); //We lost the lock?? ..try to re acquire now.
}
break;
case 'acquire':
if(!lock.id) {
autoLock.lockAttempts++;
if(warn && (!lock.retry || autoLock.lockAttempts>=autoLock.maxattempts)) {
autoLock.retry=false;
alert(__('Unable to lock the ticket. Someone else could be working on the same ticket.'));
if (lock.id && lock.time) {
autoLock.resetTimer((lock.time - 10) * 1000);
}
e.returnValue=__("Any changes or info you've entered will be discarded!");
//TODO: Monitor events and elapsed time and warn user when the lock is about to expire.
$.sysAlert(
__('Your lock is expiring soon'),
__('The lock you hold on this ticket will expire soon. Would you like to renew the lock?'),
function() {
autoLock.renewLock();
}
);
},
clearTimer: function() {
clearTimeout(autoLock.timerId);
},
autoLock.timerId = setTimeout(
function () { autoLock.monitorEvents(); },
time || 30000
);
},
destroy: function() {
};
$.autoLock = autoLock;
$.showImagesInline = function(urls, thread_id) {
var selector = (thread_id == undefined)
? '.thread-body img[data-cid]'
: '.thread-body#thread-entry-'+thread_id+' img[data-cid]';
$(selector).each(function(i, el) {
var e = $(el),
cid = e.data('cid').toLowerCase(),
info = urls[cid];
if (info && !e.data('wrapped')) {
// Add a hover effect with the filename
var timeout, caption = $('<div class="image-hover">')
.css({'float':e.css('float')});
e.wrap(caption).parent()
.hover(
function() {
var self = this;
timeout = setTimeout(
function() { $(self).find('.caption').slideDown(250); },
500);
},
function() {
clearTimeout(timeout);
$(this).find('.caption').slideUp(250);
}
).append($('<div class="caption">')
.append('<span class="filename">'+info.filename+'</span>')
.append($('<a href="'+info.download_url+'" class="action-button pull-right no-pjax"><i class="icon-download-alt"></i> '+__('Download')+'</a>')
.attr('download', info.filename)
)
);
e.data('wrapped', true);
}
});
};
$.refreshTicketView = function(interval) {
var refresh =
window.ticket_refresh = setInterval(function() {
if ($('table.list input.ckb[name=tids\\[\\]]:checked').length)
// Skip the refresh b/c items are checked
return;
else if (0 < $('.dialog:visible').length)
// Dialog open — skip refresh
return;
clearInterval(refresh);
$.pjax({url: document.location.href, container:'#pjax-container'});
}, interval);
var ticket_onload = function($) {
if (0 === $('#ticketThread').length)
//Start watching the form for activity.
autoLock.Init();
/*** Ticket Actions **/
$('a#ticket-print').click(function(e) {
e.preventDefault();
$('#overlay').show();
return false;
});
$(document).off('.ticket-action');
$(document).on('click.ticket-action', 'a.ticket-action', function(e) {
var url = 'ajax.php/'
+$(this).attr('href').substr(1)
+'?_uid='+new Date().getTime();
var $options = $(this).data('dialog');
window.location.href = $redirect ? $redirect : window.location.href;
$(document).on('change', 'form[name=reply] select#emailreply', function(e) {
var $cc = $('form[name=reply] tbody#cc_sec');
if($(this).val() == 0)
$cc.hide();
else
$cc.show();
});
};
$(ticket_onload);
$(document).on('pjax:success', function() { ticket_onload(jQuery); });