{% extends "limited_width.html.j2" %} {% block page_content %} <script> var job_user_id = {{ job.user_id }} socket.emit('inspect_user', job_user_id); </script> <script> var JOB_ID = {{ job.id }} 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() { if (foreignJobFlag) { this.job = foreignJobs[this.jobId]; } else { this.job = jobs[this.jobId]; } // Status this.setStatus(this.job.status); // End date if (this.job.end_date) {this.setEndDate(this.job.end_date);} // Input results for (let input of this.job.inputs) { for (let result of input.results) { this.setResult(result); } } } _update(patch) { var pathArray; for (let 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") { this.setResult(operation.value); } break; case "delete": location.reload(); break; case "replace": if (pathArray[1] === "end_date") { this.setEndDate(operation.value); } else if (pathArray[1] === "status") { this.setStatus(operation.value); } break; default: break; } } } setEndDate(timestamp) { document.getElementById("end-date").value = new Date(timestamp * 1000).toLocaleString(); M.updateTextFields(); } setResult(result) { var resultsElement, resultDownloadButtonElement, resultDownloadButtonIconElement; resultsElement = document.getElementById(`input-${result.job_input_id}-results`); resultDownloadButtonElement = document.createElement("a"); resultDownloadButtonElement.classList.add("waves-effect", "waves-light", "btn-small"); resultDownloadButtonElement.href = `/jobs/${this.jobId}/download?ressource_id=${result.id}&ressource_type=result`; 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); resultsElement.append(resultDownloadButtonElement); resultsElement.append(" "); } setStatus(status) { var statusElement; statusElement = document.getElementById("status"); statusElement.classList.remove(...Object.values(JobList.STATUS_COLORS)); statusElement.classList.add(JobList.STATUS_COLORS[status] || JobList.STATUS_COLORS['default']); statusElement.innerText = status; } } var informationUpdater = new InformationUpdater(JOB_ID); </script> <div class="col s12 m4"> <h3 id="title">{{ job.title }}</h3> <p id="description">{{ job.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="{{ 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> <span class="card-title">Ressource allocations</span> <div class="row"> <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> <span class="card-title">Service informations</span> <div class="row"> <div class="col s12 m4"> <div class="input-field"> <input disabled value="{{ job.service }}" 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="{{ job.service_args|e }}" 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="{{ job.service_version }}" 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>Filename</th> <th>Download</th> <th>Results</th> </tr> </thead> <tbody> {% for input in job.inputs %} <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('main.job_download', job_id=job.id, ressource_id=input.id, ressource_type='input') }}"> <i class="material-icons">file_download</i> </a> </td> <td id="input-{{ input.id }}-results"></td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> {% endblock %}