Merge branch 'development' of gitlab.ub.uni-bielefeld.de:sfb1288inf/opaque into development

This commit is contained in:
Stephan Porada 2020-05-15 15:07:50 +02:00
commit 6e81e424c4

View File

@ -1,130 +1,125 @@
{% extends "nopaque.html.j2" %} {% extends "nopaque.html.j2" %}
{% set headline = '<i class="material-icons left service" data-service="{service}" style="font-size: inherit;"></i>Job'.format(service=job.service) %} {% set headline = '<i class="left material-icons service" data-service="{service}" style="font-size: inherit;"></i>Job view'.format(service=job.service) %}
{% block page_content %} {% block page_content %}
<div class="col s12 m4"> <div class="col s12">
<h3 id="title">{{ job.title }}</h3> <div class="card">
<p id="description">{{ job.description }}</p> <div class="card-content">
<div class="active preloader-wrapper small" id="progress-indicator"> <div class="row">
<div class="spinner-layer spinner-blue-only"> <div class="col s8 m9 l10">
<div class="circle-clipper left"> <span class="card-title title">{{ job.title }}</span>
<div class="circle"></div> </div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
<span class="chip status white-text" id="status"></span>
</div>
<div class="col s4 m3 l2 right-align">
<span class="chip status white-text"></span>
<div class="active preloader-wrapper small" id="progress-indicator">
<div class="spinner-layer spinner-blue-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>
<div class="col s12 m8"> <div class="col s12">
<ul class="collapsible expandable" id="job-list"> <p class="description">{{ job.description }}</p>
<li class="active"> </div>
<div class="collapsible-header">
<i class="material-icons">input</i>Input files
</div>
<div class="collapsible-body">
<table class="highlight responsive-table">
<thead>
<tr>
<th>Filename</th>
<th>Download</th>
</tr>
</thead>
<tbody id="inputs">
{% for input in job.inputs|sort(attribute="id", reverse=true) %}
<tr>
<td id="input-{{ input.id }}-filename">{{ input.filename }}</td>
<td id="input-{{ input.id }}-download">
<a class="waves-effect waves-light btn-small" download href="{{ url_for('jobs.download_job_input', job_id=job.id, job_input_id=input.id) }}">
<i class="material-icons">file_download</i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</li>
<li>
<div class="collapsible-header"><i class="material-icons">done</i>Result files</div>
<div class="collapsible-body">
<table class="highlight responsive-table">
<thead>
<tr>
<th>Bundlename</th>
<th>Download</th>
</tr>
</thead>
<tbody id="results"></tbody>
</table>
</div>
</li>
<li>
<div class="collapsible-header"><i class="material-icons">settings</i>Settings</div>
<div class="collapsible-body">
<div class="row">
<div class="col s12">Chronometrics</div>
<div class="col s12 m6">
<div class="input-field">
<input disabled value="{{ job.creation_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}" 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 class="col s12">Ressource allocations</div> <div class="col s12">&nbsp;</div>
<div class="col s12 m6">
<div class="input-field">
<input disabled value="{{ job.mem_mb }}" 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="{{ job.n_cores }}" id="n-cores" type="text" class="validate">
<label for="n-cores">CPU cores</label>
</div>
</div>
<div class="col s12">Service informations</div> <div class="col s12 m6">
<div class="col s12 m4"> <div class="input-field">
<div class="input-field"> <input disabled id="creation-date" type="text" value="{{ job.creation_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}">
<input disabled value="{{ job.service }}" id="service" type="text" class="validate"> <label for="creation-date">Creation date</label>
<label for="service">Service</label>
</div>
</div> </div>
<div class="col s12 m4"> </div>
<div class="input-field">
<input disabled value="{{ job.service_args|e }}" id="service-args" type="text" class="validate"> <div class="col s12 m6">
<label for="service-args">Service arguments</label> <div class="input-field">
</div> <input class="end-date" disabled id="end-date" type="text" value="">
<label for="end-date">End date</label>
</div> </div>
<div class="col s12 m4"> </div>
<div class="input-field">
<input disabled value="{{ job.service_version }}" id="service-version" type="text" class="validate"> <div class="col s12 m4">
<label for="service-version">Service version</label> <div class="input-field">
</div> <input disabled id="service" type="text" value="{{ job.service }}">
<label for="service">Service</label>
</div> </div>
<div class="col s12 right-align"> </div>
<a href="#" class="waves-effect waves-light btn"><i class="material-icons left">settings</i>Export Parameters</a>
<a data-target="delete-job-modal" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete</a> <div class="col s12 m4">
<div class="input-field">
<input disabled id="service-args" type="text" value="{{ job.service_args|e }}">
<label for="service-args">Service arguments</label>
</div>
</div>
<div class="col s12 m4">
<div class="input-field">
<input disabled id="service-version" type="text" value="{{ job.service_version }}">
<label for="service-version">Service version</label>
</div> </div>
</div> </div>
</div> </div>
</li> </div>
</ul> <div class="card-action right-align">
<a href="#" class="btn disabled waves-effect waves-light"><i class="material-icons left">settings</i>Export Parameters</a>
<a data-target="delete-job-modal" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete</a>
</div>
</div>
</div>
<div class="col s12">
<div class="card">
<div class="card-content">
<div class="row">
<div class="col s12 m2">
<span class="card-title"><i class="left material-icons" style="font-size: inherit;">input</i>Inputs</span>
<p>Original input files.</p>
</div>
<div class="col s12 m10">
<div class="inputs row">
{% for input in job.inputs %}
<div class="col s12 m6">
<a class="btn waves-effect waves-light" download href="{{ url_for('jobs.download_job_input', job_id=job.id, job_input_id=input.id) }}">
<i class="material-icons left">file_download</i>{{ input.filename }}
</a>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="card">
<div class="card-content">
<div class="row">
<div class="col s12 m2">
<span class="card-title"><i class="left material-icons" style="font-size: inherit;">done</i>Results</span>
<p>Processed result files.</p>
</div>
<div class="col s12 m10">
<div class="results row">
<div class="show-if-only-child">
<span class="card-title"><i class="left material-icons" style="font-size: inherit;">file_download</i>Nothing here...</span>
<p>No results available (yet). Is the job already completed?</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
@ -132,7 +127,7 @@
<div id="delete-job-modal" class="modal"> <div id="delete-job-modal" class="modal">
<div class="modal-content"> <div class="modal-content">
<h4>Confirm deletion</h4> <h4>Confirm deletion</h4>
<p>Do you really want to delete the job {{job.title}}? All associated files will be permanently deleted.</p> <p>Do you really want to delete the job {{ job.title }}? All associated files will be permanently deleted.</p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a> <a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a>
@ -159,14 +154,12 @@
job = (this.foreignJobFlag ? nopaque.foreignUser.jobs[this.jobId] job = (this.foreignJobFlag ? nopaque.foreignUser.jobs[this.jobId]
: nopaque.user.jobs[this.jobId]); : nopaque.user.jobs[this.jobId]);
// Results
this.addResults(job.results);
// End date // End date
this.setEndDate(job.end_date); this.setEndDate(job.end_date);
// Status // Status
this.setStatus(job.status); this.setStatus(job.status);
// End date
if (job.end_date) {this.setEndDate(job.end_date);}
// Results
if (job.results) {this.setResults(job.results);}
} }
_update(patch) { _update(patch) {
@ -179,7 +172,7 @@
switch(operation.op) { switch(operation.op) {
case "add": case "add":
if (pathArray[1] === "results") { if (pathArray[1] === "results") {
this.setResults([operation.value]); this.addResults([operation.value]);
} }
break; break;
case "delete": case "delete":
@ -198,51 +191,61 @@
} }
} }
setEndDate(timestamp) { addResults(results) {
let end_date; let resultsArray, resultsElements, resultsHTML, resultType;
resultsArray = Object.values(results);
if (timestamp === null) {
end_date = "N.a.";
} else {
end_date = new Date(timestamp * 1000).toLocaleString("en-US");
}
document.getElementById("end-date").value = end_date;
M.updateTextFields();
}
setResults(results) {
let resultsArray, resultsElement;
resultsArray = Object.values(results)
resultsArray.sort(function (a, b) { resultsArray.sort(function (a, b) {
if (a.filename < b.filename) {return -1;} if (a.filename < b.filename) {return -1;}
if (a.filename > b.filename) {return 1;} if (a.filename > b.filename) {return 1;}
return 0; return 0;
}); });
resultsElement = document.getElementById("results"); resultsHTML = "";
for (let result of resultsArray) { for (let result of resultsArray) {
resultsElement.insertAdjacentHTML( if (result.filename.endsWith(".pdf.zip")) {
"beforeend", resultType = "PDF";
`<tr> } else if (result.filename.endsWith(".txt.zip")) {
<td>${result.filename}</td> resultType = "TXT";
<td> } else if (result.filename.endsWith(".vrt.zip")) {
<a class="btn-small waves-effect waves-light" download href="/jobs/${result.job_id}/results/${result.id}/download"> resultType = "VRT";
<i class="material-icons">file_download</i> } else if (result.filename.endsWith(".xml.zip")) {
</a> resultType = "XML";
</td> } else {
</tr>` resultType = "ALL";
); }
resultsHTML += `<div class="col s4 m3 l2">
<a class="btn waves-effect waves-light" download href="/jobs/${result.job_id}/results/${result.id}/download">
<i class="material-icons left">file_download</i>${resultType}
</a>
</div>`;
}
resultsElements = document.querySelectorAll(".results");
for (let resultsElement of resultsElements) {
resultsElement.innerHTML += resultsHTML;
} }
} }
setEndDate(timestamp) {
let endDate;
if (timestamp === null) {
endDate = "N.a.";
} else {
endDate = new Date(timestamp * 1000).toLocaleString("en-US");
}
document.getElementById("end-date").value = endDate;
M.updateTextFields();
}
setStatus(status) { setStatus(status) {
let progressIndicator, statusElement; let progressIndicator, statusElements;
if (status === "complete") { if (status === "complete") {
progressIndicator = document.getElementById("progress-indicator"); progressIndicator = document.getElementById("progress-indicator");
progressIndicator.classList.add("hide"); progressIndicator.classList.add("hide");
M.Collapsible.getInstance(document.getElementById("job-list")).open(1);
} }
statusElement = document.getElementById("status"); statusElements = document.querySelectorAll(".status");
statusElement.dataset.status = status; for (let statusElement of statusElements) {
statusElement.dataset.status = status;
}
} }
} }