From 43f79291aad8448a72af60818613856a926b8c7c Mon Sep 17 00:00:00 2001 From: Stephan Porada Date: Wed, 8 Jul 2020 11:35:47 +0200 Subject: [PATCH] Unify job input tables --- web/app/jobs/tables.py | 28 ------------ web/app/jobs/views.py | 14 +++--- web/app/static/js/nopaque.lists.js | 69 +++++++++++++++++++++++++++--- web/app/templates/jobs/job.html.j2 | 34 +++++++-------- 4 files changed, 82 insertions(+), 63 deletions(-) delete mode 100644 web/app/jobs/tables.py diff --git a/web/app/jobs/tables.py b/web/app/jobs/tables.py deleted file mode 100644 index aeac3319..00000000 --- a/web/app/jobs/tables.py +++ /dev/null @@ -1,28 +0,0 @@ -from flask_table import Table, Col, LinkCol - - -class JobInputTable(Table): - """ - Declares the table describing colum by column. - """ - classes = ['highlight', 'responsive-table'] - filename = Col('Filename', column_html_attrs={'class': 'filename'}, - th_html_attrs={'class': 'sort', - 'data-sort': 'filename'}) - url = LinkCol('Download', 'jobs.download_job_input', - url_kwargs=dict(job_id='job.id', - job_input_id='input_id'), - anchor_attrs={'class': 'waves-effect waves-light btn-floating', - 'download': ''}, - text_fallback='file_download') - - -class JobInputItem(object): - """ - Describes one item like one row per table. - """ - - def __init__(self, filename, job, input_id): - self.filename = filename - self.job = job - self.input_id = input_id diff --git a/web/app/jobs/views.py b/web/app/jobs/views.py index 6e66b211..f8f9f6a9 100644 --- a/web/app/jobs/views.py +++ b/web/app/jobs/views.py @@ -3,10 +3,8 @@ from flask import (abort, current_app, flash, redirect, render_template, from flask_login import current_user, login_required from . import jobs from . import tasks -from . tables import JobInputItem, JobInputTable from ..models import Job, JobInput, JobResult import os -import html @jobs.route('/') @@ -15,15 +13,13 @@ def job(job_id): job = Job.query.get_or_404(job_id) if not (job.creator == current_user or current_user.is_administrator()): abort(403) - items = [JobInputItem(input.filename, job, input.id) - for input in job.inputs] - # Convert table object to html string and unescape <>& for al little hack to use icons in buttons - job_input_table = html.unescape(JobInputTable(items).__html__()) - # Add class "list" to tbody element. Needed for "List.js" - job_input_table = job_input_table.replace('tbody', 'tbody class="list"', 1) + job_inputs = [dict(filename=input.filename, + id=input.id, + job_id=job.id) + for input in job.inputs] return render_template('jobs/job.html.j2', job=job, - job_input_table=job_input_table, + job_inputs=job_inputs, title='Job') diff --git a/web/app/static/js/nopaque.lists.js b/web/app/static/js/nopaque.lists.js index 2c3aeb6c..a2584e71 100644 --- a/web/app/static/js/nopaque.lists.js +++ b/web/app/static/js/nopaque.lists.js @@ -1,6 +1,6 @@ class RessourceList extends List { constructor(idOrElement, subscriberList, type, options={}) { - if (!["corpus", "job", "result", "user"].includes(type)) { + if (!["corpus", "job", "result", "user", "job_input"].includes(type)) { console.error("Unknown Type!"); return; } @@ -63,6 +63,15 @@ class RessourceList extends List { RessourceList.dataMapper = { + // ### Mapping Genera Info + //The Mapping describes entitys rendered per row. One key value pair holds + // the data to be rendered in the list.js table. Key has to correspond + // with the ValueNames defined below in RessourceList.options ValueNames. + // Links are declared with double ticks(") around them. The key for links + // have to correspond with the class of an element in the + // RessourceList.options item blueprint. + + // Mapping for corpus entities shown in the dashboard table. corpus: corpus => ({creation_date: corpus.creation_date, description: corpus.description, id: corpus.id, @@ -70,6 +79,7 @@ RessourceList.dataMapper = { "edit-link": `/corpora/${corpus.id}`, status: corpus.status, title: corpus.title}), + // Mapping for job entities shown in the dashboard table. job: job => ({creation_date: job.creation_date, description: job.description, id: job.id, @@ -77,6 +87,12 @@ RessourceList.dataMapper = { service: job.service, status: job.status, title: job.title}), + // Mapping for job input files shown in table on every job page + job_input: job_input => ({filename: job_input.filename, + id: job_input.job_id, + "download-link": `${job_input.job_id}/inputs/${job_input.id}/download`}), + // Mapping for imported result entities from corpus analysis. + // Shown in imported results table result: result => ({ query: result.query, match_count: result.match_count, corpus_name: result.corpus_name, @@ -86,6 +102,7 @@ RessourceList.dataMapper = { "details-link": `${result.id}/details`, "inspect-link": `${result.id}/inspect`, "delete-modal": `delete-result-${result.id}-modal`}), + // Mapping for user entities shown in admin table user: user => ({username: user.username, email: user.email, role_id: user.role_id, @@ -96,7 +113,9 @@ RessourceList.dataMapper = { RessourceList.options = { + // common list.js options for 4 rows per page etc. common: {page: 4, pagination: {innerWindow: 8, outerWindow: 1}}, + // extended list.js options for 10 rows per page etc. extended: {page: 10, pagination: [ { @@ -111,6 +130,8 @@ RessourceList.options = { outerWindow: 1 } ]}, + // Corpus entity blueprint setting html strucuture per entity per row + // Link classes have to correspond with Links defined in the Mapping process corpus: {item: ` @@ -134,11 +155,18 @@ RessourceList.options = { `, - valueNames: ["creation_date", "description", "title", + // Corpus Value Names per column. Have to correspond with the keys from the + // Mapping step above. + valueNames: ["creation_date", + "description", + "title", {data: ["id"]}, {name: "analyse-link", attr: "href"}, {name: "edit-link", attr: "href"}, - {name: "status", attr: "data-status"}]}, + {name: "status", attr: "data-status"}] + }, + // Job entity blueprint setting html strucuture per entity per row + // Link classes have to correspond with Links defined in the Mapping process job: {item: ` @@ -158,11 +186,30 @@ RessourceList.options = { `, - valueNames: ["creation_date", "description", "title", + // Job Value Names per column. Have to correspond with the keys from the + // Mapping step above. + valueNames: ["creation_date", + "description", + "title", {data: ["id"]}, {name: "link", attr: "href"}, {name: "service", attr: "data-service"}, - {name: "status", attr: "data-status"}]}, + {name: "status", attr: "data-status"}] + }, + job_input: {item : ` + + + file_download + + + `, + valueNames: ["filename", + "id", + {name: "download-link", attr: "href"}] + }, + // Result (imported from corpus analysis) entity blueprint setting html + // strucuture per entity per row + // Link classes have to correspond with Links defined in the Mapping process result: {item: ` @@ -179,6 +226,8 @@ RessourceList.options = { `, + // Result Value Names per column. Have to correspond with keys from the + // Mapping step above. valueNames: ["query", "match_count", "corpus_name", @@ -187,7 +236,10 @@ RessourceList.options = { "corpus_type", {name: "details-link", attr: "href"}, {name: "inspect-link", attr: "href"}, - {name: "delete-modal", attr: "data-target"}]}, + {name: "delete-modal", attr: "data-target"}] + }, + // User entity blueprint setting html strucuture per entity per row + // Link classes have to correspond with Links defined in the Mapping process user: {item: ` @@ -199,12 +251,15 @@ RessourceList.options = { `, + // User Value Names per column. Have to correspond with keys from the + // Mapping step above. valueNames: ["username", "email", "role_id", "confirmed", "id", - {name: "profile-link", attr: "href"}]} + {name: "profile-link", attr: "href"}] + } }; diff --git a/web/app/templates/jobs/job.html.j2 b/web/app/templates/jobs/job.html.j2 index bc146caa..b264cb52 100644 --- a/web/app/templates/jobs/job.html.j2 +++ b/web/app/templates/jobs/job.html.j2 @@ -86,9 +86,18 @@

Original input files.

-
+
    - {{ job_input_table }} + + + + + + + + + +
    Filename{# Actions #}
      @@ -149,23 +158,10 @@