From 98993dc0be542b377e62c97031f29f63e83f7ed4 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Tue, 16 Dec 2025 13:30:46 -0600 Subject: Add "Streamlined UI" templates for phenotype upload sub-features. --- uploader/background_jobs.py | 17 ++- uploader/phenotypes/views.py | 10 +- .../background-jobs/sui-default-success-page.html | 17 +++ uploader/templates/jobs/sui-job-error.html | 17 +++ uploader/templates/jobs/sui-job-not-found.html | 11 ++ uploader/templates/jobs/sui-job-status.html | 24 ++++ uploader/templates/phenotypes/sui-job-status.html | 140 +++++++++++++++++++++ .../phenotypes/sui-load-phenotypes-success.html | 26 ++++ .../templates/phenotypes/sui-review-job-data.html | 121 ++++++++++++++++++ 9 files changed, 374 insertions(+), 9 deletions(-) create mode 100644 uploader/templates/background-jobs/sui-default-success-page.html create mode 100644 uploader/templates/jobs/sui-job-error.html create mode 100644 uploader/templates/jobs/sui-job-not-found.html create mode 100644 uploader/templates/jobs/sui-job-status.html create mode 100644 uploader/templates/phenotypes/sui-job-status.html create mode 100644 uploader/templates/phenotypes/sui-load-phenotypes-success.html create mode 100644 uploader/templates/phenotypes/sui-review-job-data.html diff --git a/uploader/background_jobs.py b/uploader/background_jobs.py index d33c498..a9c0345 100644 --- a/uploader/background_jobs.py +++ b/uploader/background_jobs.py @@ -5,7 +5,7 @@ from typing import Callable from functools import partial from flask import ( - url_for, + request, redirect, Response, Blueprint, @@ -16,6 +16,7 @@ from gn_libs import jobs from gn_libs import sqlite3 from gn_libs.jobs.jobs import JobNotFound +from uploader.flask_extensions import url_for from uploader.authorisation import require_login background_jobs_bp = Blueprint("background-jobs", __name__) @@ -76,7 +77,9 @@ def handler(job: dict, handler_type: str) -> HandlerType: ).get(handler_type) if bool(_handler): return _handler(job) - return render_template("background-jobs/default-success-page.html", job=job) + _sui = "sui-" if request.args.get("streamlined_ui") else "" + return render_template(f"background-jobs/{_sui}default-success-page.html", + job=job) error_handler = partial(handler, handler_type="error") @@ -87,6 +90,7 @@ success_handler = partial(handler, handler_type="success") @require_login def job_status(job_id: uuid.UUID): """View the job status.""" + _sui = "sui-" if request.args.get("streamlined_ui") else "" with sqlite3.connection(app.config["ASYNCHRONOUS_JOBS_SQLITE_DB"]) as conn: try: job = jobs.job(conn, job_id, fulldetails=True) @@ -99,10 +103,10 @@ def job_status(job_id: uuid.UUID): if status == "completed": return success_handler(job) - return render_template("jobs/job-status.html", job=job) + return render_template(f"jobs/{_sui}job-status.html", job=job) except JobNotFound as _jnf: return render_template( - "jobs/job-not-found.html", + f"jobs/{_sui}job-not-found.html", job_id=job_id) @@ -110,9 +114,10 @@ def job_status(job_id: uuid.UUID): @require_login def job_error(job_id: uuid.UUID): """Handle job errors in a generic manner.""" + _sui = "sui-" if request.args.get("streamlined_ui") else "" with sqlite3.connection(app.config["ASYNCHRONOUS_JOBS_SQLITE_DB"]) as conn: try: job = jobs.job(conn, job_id, fulldetails=True) - return render_template("jobs/job-error.html", job=job) + return render_template(f"jobs/{_sui}job-error.html", job=job) except JobNotFound as _jnf: - return render_template("jobs/job-not-found.html", job_id=job_id) + return render_template(f"jobs/{_sui}job-not-found.html", job_id=job_id) diff --git a/uploader/phenotypes/views.py b/uploader/phenotypes/views.py index c4fd7fd..364fc79 100644 --- a/uploader/phenotypes/views.py +++ b/uploader/phenotypes/views.py @@ -513,7 +513,9 @@ def job_status( job = jobs.job(rconn, jobs.jobsnamespace(), str(job_id)) except jobs.JobNotFound as _jnf: job = None - return render_template("phenotypes/job-status.html", + + _sui = "sui-" if bool(request.args.get("streamlined_ui")) else "" + return render_template(f"phenotypes/{_sui}job-status.html", species=species, population=population, dataset=dataset, @@ -593,7 +595,8 @@ def review_job_data( for filetype,meta in metadata.items() } _job_metadata = json.loads(job["job-metadata"]) - return render_template("phenotypes/review-job-data.html", + _sui = "sui-" if bool(request.args.get("streamlined_ui")) else "" + return render_template(f"phenotypes/{_sui}review-job-data.html", species=species, population=population, dataset=dataset, @@ -983,7 +986,8 @@ def load_data_success( _publication["Authors"], (_publication["Title"] or "")) if item != "") - return render_template("phenotypes/load-phenotypes-success.html", + _sui="sui-" if request.args.get("streamlined_ui") else "" + return render_template(f"phenotypes/{_sui}load-phenotypes-success.html", species=species, population=population, dataset=dataset, diff --git a/uploader/templates/background-jobs/sui-default-success-page.html b/uploader/templates/background-jobs/sui-default-success-page.html new file mode 100644 index 0000000..5732456 --- /dev/null +++ b/uploader/templates/background-jobs/sui-default-success-page.html @@ -0,0 +1,17 @@ +{%extends "phenotypes/base.html"%} +{%from "flash_messages.html" import flash_all_messages%} + +{%block title%}Background Jobs: Success{%endblock%} + +{%block pagetitle%}Background Jobs: Success{%endblock%} + +{%block contents%} +{{flash_all_messages()}} + +
Job {{job.job_id}}, + {%if job.get("metadata", {}).get("job-type")%} + of type '{{job.metadata["job-type"]}} + {%endif%}' completed successfully.
+Job {{job["job_id"]}} failed!
+The error details are in the "STDERR" section below.
+ +{{job["stderr"]}}
+{%endblock%}
diff --git a/uploader/templates/jobs/sui-job-not-found.html b/uploader/templates/jobs/sui-job-not-found.html
new file mode 100644
index 0000000..96c8586
--- /dev/null
+++ b/uploader/templates/jobs/sui-job-not-found.html
@@ -0,0 +1,11 @@
+{%extends "sui-base.html"%}
+
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}Background Jobs{%endblock%}
+
+{%block pagetitle%}Background Jobs{%endblock%}
+
+{%block contents%}
+Could not find job with ID: {{job_id}}
+{%endblock%} diff --git a/uploader/templates/jobs/sui-job-status.html b/uploader/templates/jobs/sui-job-status.html new file mode 100644 index 0000000..fc5e532 --- /dev/null +++ b/uploader/templates/jobs/sui-job-status.html @@ -0,0 +1,24 @@ +{%extends "sui-base.html"%} + +{%from "flash_messages.html" import flash_all_messages%} + +{%block extrameta%} + +{%endblock%} + +{%block title%}Background Jobs{%endblock%} + +{%block pagetitle%}Background Jobs{%endblock%} + +{%block contents%} + +Status: {{job["metadata"]["status"]}}
+Job Type: {{job["metadata"]["job-type"]}}
+ +{{job["stdout"]}}
+
+{{job["stderr"]}}
+
+{%endblock%}
diff --git a/uploader/templates/phenotypes/sui-job-status.html b/uploader/templates/phenotypes/sui-job-status.html
new file mode 100644
index 0000000..bca87d5
--- /dev/null
+++ b/uploader/templates/phenotypes/sui-job-status.html
@@ -0,0 +1,140 @@
+{%extends "phenotypes/sui-base.html"%}
+{%from "cli-output.html" import cli_output%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+
+{%block extrameta%}
+{%if job and job.status not in ("success", "completed:success", "error", "completed:error")%}
+
+{%endif%}
+{%endblock%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block contents%}
+
+{%if job%}
+Process Status: {{job.status}}
+ {%if metadata%} +| File | +Status | +Lines Processed | +Total Errors | +
|---|---|---|---|
| {{file}} | +{{meta.status}} | +{{meta.linecount}} | +{{meta["total-errors"]}} | +
+ {%if errors | length == 0%} + Continue + {%else%} + + Cannot continue due to errors. Please fix the errors first. + + {%endif%} +
+ {%endif%} ++ + No errors found so far +
+ {%else%} +| File | +Row | +Column | +Value | +Message | +
|---|---|---|---|---|
| {{error.filename}} | +{{error.rowtitle}} | +{{error.coltitle}} | +{%if error.cellvalue is not none and error.cellvalue | length > 25%} + {{error.cellvalue[0:24]}}… + {%else%} + {{error.cellvalue}} + {%endif%} + | ++ {%if error.message | length > 250 %} + {{error.message[0:249]}}… + {%else%} + {{error.message}} + {%endif%} + | +
Could not find a job with the ID: {{job_id}}
++ Please go back to + + the '{{dataset.Name}}' dataset page + to upload new phenotypes or edit existing ones.
+You have successfully loaded + your + new phenotypes into the database.
+ + +View your data + on GeneNetwork2. + You might need to login to GeneNetwork2 to view specific traits.
++ The data has NOT been added/saved yet. Review the details below + and click "Continue" to save the data.
+The “{{dataset.FullName}}” dataset from the + “{{population.FullName}}” population of the + species “{{species.SpeciesName}} ({{species.FullName}})” + will be updated as follows:
+ ++ Could not find a job with the ID: {{job_id}}.
+You will be redirected in + 20 second(s)
++ + If you are not redirected, please + click here to continue + +
+