www/secretary/workbench/public/tasklist.js (106 lines of code) (raw):
var tasks = $('h3');
var spinner = $('<img src="../spinner.gif"/>');
var disposition = null;
var headers = null;
// Load fetch shim, if needed (e.g., by Safari)
if (typeof fetch === 'undefined') {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '../fetch.js';
$('head').append(script);
};
// Conditionally process next task in the list
function nexttask(proceed) {
if (proceed && tasks.length) {
// remove first task from list
var task = tasks.slice(0,1);
tasks = tasks.slice(1);
// extract task name, add to the parameter list
params.task = task.text();
// add/move spinner to this task
task.parent().append(spinner);
// build fetch options
options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(params),
credentials: 'include'
}
// perform fetch operation
fetch('', options).then(function(response) {
// display output
response.json().then(function(json) {
// remove all but the heading
task.parent().empty().append(task);
if (json.transcript) {
var pre = $('<pre>');
pre.text(json.transcript.join("\n"));
// highlight commands
pre.html(("\n" + pre.html()).replace(/\n(\$ \w+ .*)/g,
"\n<b>$1</b>").trim());
// append results
task.parent().append(pre);
}
if (json.message) {
var pre = $('<pre class="bg-info">');
pre.text(json.message);
task.append(pre);
}
if (json.exception) {
var pre = $('<pre class="bg-danger">');
if (json.backtrace) {
json.exception += "\n " + json.backtrace.join("\n ");
}
pre.text(json.exception);
task.append(pre);
}
if (json.disposition) disposition = json.disposition;
if (json.headers) headers = json.headers;
// conditionally proceed to the next task
nexttask(response.ok ||
confirm(response.statusText + "; continue?"));
});
}).catch(function(error) {
nexttask(confirm(error.message + "; continue?"));
});
} else { // done
spinner.remove();
if (!proceed) {
$('h1').removeClass('bg-info').addClass('bg-danger').
text('Processing Aborted');
message = {status: 'aborted'};
$('button#proceed').text('resume').prop('disabled', false);
} else {
$('h1').removeClass('bg-info').addClass('bg-success').
text('Processing Complete');
$('button#cancel').remove();
$('button#proceed').html('return to<br>mail index').
prop('disabled', false);
message = {status: disposition || 'complete'};
}
if (headers) message.headers = headers;
window.parent.frames[0].postMessage(message, '*')
}
};
// start the process when the proceed button is clicked
$('button#proceed').on('click', function(event) {
if (tasks.length) {
$('h1').removeClass('bg-warning').addClass('bg-info').
text('Request Status');
$(this).prop('disabled', true);
$('button#cancel').prop('disabled', true);
nexttask(true);
} else {
window.parent.location.href = '..';
}
});
// end the process when the cancel button is clicked
$('button#cancel').on('click', function(event) {
$(this).prop('disabled', true);
$('button#proceed').prop('disabled', true);
message = {status: 'cancelled'};
window.parent.frames[0].postMessage(message, '*');
$('ul')[0].style.opacity = '0.5';
$('h1').removeClass('bg-info').addClass('bg-danger').
text('Operation cancelled');
});
// have delete and up keys return to index
$(document).on('keypress', function(event) {
if (event.keyCode == 8 || event.keyCode == 46) { // backspace or delete
var tag = event.target.tagName.toLowerCase();
if (tag != 'input' && tag != 'textarea') {
window.parent.location.href = '..';
}
} else if (event.keyCode == 38) { // up
window.parent.location.href = '..';
}
});
// reenable form on exit of page
window.addEventListener('unload', function(){
message = {status: 'exit'};
window.parent.frames[0].postMessage(message, '*');
});