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, '*'); });