nopaque/app/templates/main/jobs/job.html.j2

344 lines
12 KiB
Django/Jinja

{% extends "limited_width.html.j2" %}
{% block page_content %}
<script>
var job_user_id = {{ job.user_id|tojson|safe }}
socket.emit('inspect_user', job_user_id);
</script>
<script>
var JOB_ID = {{ job.id|tojson|safe }}
var foreignJobFlag;
{% if current_user.id == job.user_id %}
foreignJobFlag = false;
{% else %}
foreignJobFlag = true;
{% endif %}
class InformationUpdater {
constructor(jobId) {
this.jobId = jobId;
if (foreignJobFlag) {
foreignJobsSubscribers.push(this);
} else {
jobsSubscribers.push(this);
}
}
_init() {
var creationDateElement, descriptionElement, endDateElement,
memMbElement, nCoresElement, serviceElement, serviceArgsElement,
serviceVersionElement, statusColor, statusElement, titleElement;
if (foreignJobFlag) {
this.job = foreignJobs[this.jobId];
} else {
this.job = jobs[this.jobId];
}
// Title
this.setTitle(this.job.title);
// Description
this.setDescription(this.job.description);
// Status
this.setStatus(this.job.status);
// Creation date
this.setCreationDate(this.job.creation_date);
// End date
if (this.job.end_date) {this.setEndDate(this.job.end_date);}
// Memory
this.setMemMb(this.job.mem_mb);
// CPU cores
this.setNCores(this.job.n_cores);
// Service
this.setService(this.job.service);
// Service arguments
this.setServiceArgs(this.job.service_args);
// Service version
this.setServiceVersion(this.job.service_version);
var filesElement, input, inputDownloadElement, inputElement,
inputFilenameElement, inputResultsElement;
filesElement = document.getElementById("files");
for (input of this.job.inputs) {
// Data row
inputElement = document.createElement("tr");
filesElement.append(inputElement);
// Input filename
inputFilenameElement = document.createElement("td");
inputFilenameElement.id = `input-${input.id}-filename`;
inputElement.append(inputFilenameElement);
// Input download
inputDownloadElement = document.createElement("td");
inputDownloadElement.id = `input-${input.id}-download`;
inputElement.append(inputDownloadElement);
// Third column for input result file download buttons
inputResultsElement = document.createElement("td");
inputResultsElement.id = `input-${input.id}-results`;
inputElement.append(inputResultsElement);
this.setInputFilename(input);
this.setInputDownload(input);
this.setInputResults(input);
}
}
setInputDownload(input) {
var inputDownloadButtonElement, inputDownloadButtonIconElement,
inputDownloadElement;
inputDownloadElement = document.getElementById(`input-${input.id}-download`);
inputDownloadButtonElement = document.createElement("a");
inputDownloadButtonElement.classList.add("waves-effect", "waves-light", "btn-small");
inputDownloadButtonElement.href = `${this.jobId}/download?file=${input.filename}`;
inputDownloadButtonElement.setAttribute("download", "");
inputDownloadButtonIconElement = document.createElement("i");
inputDownloadButtonIconElement.classList.add("material-icons");
inputDownloadButtonIconElement.innerText = "file_download";
inputDownloadButtonElement.append(inputDownloadButtonIconElement);
inputDownloadElement.append(inputDownloadButtonElement);
}
setInputFilename(input) {
var inputFilenameElement;
inputFilenameElement = document.getElementById(`input-${input.id}-filename`);
inputFilenameElement.innerText = input.filename;
}
_update(patch) {
var input, operation, pathArray;
for (operation of patch) {
/* "/jobId/valueName" -> ["jobId", "valueName"] */
pathArray = operation.path.split("/").slice(1);
if (pathArray[0] != this.jobId) {continue;}
switch(operation.op) {
case "add":
if (pathArray[1] === "inputs" && pathArray[3] === "results") {
console.log(operation.value);
this.setInputResult(operation.value);
}
break;
case "delete":
location.reload();
break;
case "replace":
switch(pathArray[1]) {
case "end_date":
this.setEndDate(operation.value);
break;
case "status":
this.setStatus(operation.value);
break;
default:
break;
}
break;
default:
break;
}
}
}
setTitle(title) {
var titleElement;
titleElement = document.getElementById("title");
titleElement.innerText = title;
}
setDescription(description) {
var descriptionElement;
descriptionElement = document.getElementById("description");
descriptionElement.innerText = description;
}
setStatus(status) {
var statusColor, statusElement;
statusElement = document.getElementById("status");
for (statusColor of Object.values(JobList.STATUS_COLORS)) {
statusElement.classList.remove(statusColor);
}
statusElement.classList.add(JobList.STATUS_COLORS[status] || JobList.STATUS_COLORS['default']);
statusElement.innerText = status;
}
setCreationDate(timestamp) {
var creationDateElement;
creationDateElement = document.getElementById("creation-date");
creationDateElement.value = new Date(timestamp * 1000).toLocaleString();
M.updateTextFields();
}
setEndDate(timestamp) {
var endDateElement;
endDateElement = document.getElementById("end-date");
endDateElement.value = new Date(timestamp * 1000).toLocaleString();
M.updateTextFields();
}
setMemMb(memMb) {
var memMbElement;
memMbElement = document.getElementById("mem-mb");
memMbElement.value = memMb;
M.updateTextFields();
}
setNCores(nCores) {
var nCoresElement;
nCoresElement = document.getElementById("n-cores");
nCoresElement.value = nCores;
M.updateTextFields();
}
setService(service) {
var serviceElement;
serviceElement = document.getElementById("service");
serviceElement.value = service;
M.updateTextFields();
}
setServiceArgs(serviceArgs) {
var serviceArgsElement;
serviceArgsElement = document.getElementById("service-args");
serviceArgsElement.value = serviceArgs;
M.updateTextFields();
}
setServiceVersion(serviceVersion) {
var serviceVersionElement;
serviceVersionElement = document.getElementById("service-version");
serviceVersionElement.value = serviceVersion;
M.updateTextFields();
}
setInputResults(input) {
var result;
for (result of input.results) {
this.setInputResult(result);
}
}
setInputResult(result) {
var inputResultsElement, resultDownloadButtonElement,
resultDownloadButtonIconElement;
inputResultsElement = document.getElementById(`input-${result.job_input_id}-results`);
resultDownloadButtonElement = document.createElement("a");
resultDownloadButtonElement.classList.add("waves-effect", "waves-light", "btn-small");
var resultFile = `${result.dir}/${result.filename}`;
resultFile = resultFile.substring(resultFile.indexOf("output/"));
resultDownloadButtonElement.href = `${this.jobId}/download?file=${resultFile}`;
resultDownloadButtonElement.innerText = result.filename.split(".").reverse()[0];
resultDownloadButtonElement.setAttribute("download", "");
resultDownloadButtonIconElement = document.createElement("i");
resultDownloadButtonIconElement.classList.add("material-icons", "left");
resultDownloadButtonIconElement.innerText = "file_download";
resultDownloadButtonElement.prepend(resultDownloadButtonIconElement);
inputResultsElement.append(resultDownloadButtonElement);
inputResultsElement.append(" ");
}
}
var informationUpdater = new InformationUpdater(JOB_ID);
</script>
<div class="col s12 m4">
<h3 id="title"></h3>
<p id="description"></p>
<a class="waves-effect waves-light btn" id="status"></a>
<h2>Actions:</h2>
<!-- Confirm deletion of job with modal dialogue
Modal Trigger-->
<a href="#modal-confirm-delete" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete Job</a>
<a href="#" class="waves-effect waves-light btn"><i class="material-icons left">settings</i>Export Parameters</a>
<!-- Modal Strucutre -->
<div id="modal-confirm-delete" class="modal">
<div class="modal-content">
<h4>Confirm deletion</h4>
<p>Do you really want to delete the job {{job.title}}?
All iput and output files will be permanently deleted.</p>
</div>
<div class="modal-footer">
<a href="{{ url_for('main.delete_job', job_id=job.id) }}" class="modal-close waves-effect waves-green btn red"><i class="material-icons left">delete</i>Delete Job</a>
<a href="#!" class="modal-close waves-effect waves-green btn cancel">Cancel</a>
</div>
</div>
</div>
<div class="col s12 m8">
<div class="card">
<div class="card-content">
<span class="card-title">Chronometrics</span>
<div class="row">
<div class="col s12 m6">
<div class="input-field">
<input disabled value="" id="creation-date" type="text" class="validate">
<label for="creation-date">Creation date</label>
</div>
</div>
<div class="col s12 m6">
<div class="input-field">
<input disabled value="" id="end-date" type="text" class="validate">
<label for="end-date">End date</label>
</div>
</div>
</div>
<span class="card-title">Ressource allocations</span>
<div class="row">
<div class="col s12 m6">
<div class="input-field">
<input disabled value="" id="mem-mb" type="text" class="validate">
<label for="mem-mb">Memory</label>
</div>
</div>
<div class="col s12 m6">
<div class="input-field">
<input disabled value="" id="n-cores" type="text" class="validate">
<label for="n-cores">CPU cores</label>
</div>
</div>
</div>
<span class="card-title">Service informations</span>
<div class="row">
<div class="col s12 m4">
<div class="input-field">
<input disabled value="" id="service" type="text" class="validate">
<label for="service">Service</label>
</div>
</div>
<div class="col s12 m4">
<div class="input-field">
<input disabled value="" id="service-args" type="text" class="validate">
<label for="service-args">Service arguments</label>
</div>
</div>
<div class="col s12 m4">
<div class="input-field">
<input disabled value="" id="service-version" type="text" class="validate">
<label for="service-version">Service version</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">Files</span>
<table class="highlight responsive-table">
<thead>
<tr>
<th>File</th>
<th>Input</th>
<th>Results</th>
</tr>
</thead>
<tbody id="files"></tbody>
</table>
</div>
</div>
</div>
{% endblock %}