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.

+
+{%endblock%} diff --git a/uploader/templates/jobs/sui-job-error.html b/uploader/templates/jobs/sui-job-error.html new file mode 100644 index 0000000..1a839a6 --- /dev/null +++ b/uploader/templates/jobs/sui-job-error.html @@ -0,0 +1,17 @@ +{%extends "sui-base.html"%} + +{%from "flash_messages.html" import flash_all_messages%} + +{%block title%}Background Jobs: Error{%endblock%} + +{%block pagetitle%}Background Jobs: Error{%endblock%} + +{%block contents%} + +

Background Jobs: Error

+

Job {{job["job_id"]}} failed!

+

The error details are in the "STDERR" section below.

+ +

STDERR

+
{{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"]}}

+ +

STDOUT

+
{{job["stdout"]}}
+ +

STDERR

+
{{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%} +
+

{{dataset.FullName}} ({{dataset.Name}})

+

upload progress

+
+
+

Process Status: {{job.status}}

+ {%if metadata%} + + + + + + + + + + + + {%for file,meta in metadata.items()%} + + + + + + + {%endfor%} + +
FileStatusLines ProcessedTotal Errors
{{file}}{{meta.status}}{{meta.linecount}}{{meta["total-errors"]}}
+ {%endif%} +
+ +
+ {%if job.status in ("completed:success", "success")%} +

+ {%if errors | length == 0%} + Continue + {%else%} + + Cannot continue due to errors. Please fix the errors first. + + {%endif%} +

+ {%endif%} +
+ +

upload errors

+
+ {%if errors | length == 0 %} +

+ + No errors found so far +

+ {%else%} + + + + + + + + + + + + + {%for error in errors%} + + + + + + + + {%endfor%} + +
FileRowColumnValueMessage
{{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%} +
+ {%endif%} +
+ +
+ {{cli_output(job, "stdout")}} +
+ +
+ {{cli_output(job, "stderr")}} +
+ +{%else%} +
+

No Such Job

+

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.

+
+{%endif%} +{%endblock%} diff --git a/uploader/templates/phenotypes/sui-load-phenotypes-success.html b/uploader/templates/phenotypes/sui-load-phenotypes-success.html new file mode 100644 index 0000000..dff0682 --- /dev/null +++ b/uploader/templates/phenotypes/sui-load-phenotypes-success.html @@ -0,0 +1,26 @@ +{%extends "phenotypes/sui-base.html"%} +{%from "flash_messages.html" import flash_all_messages%} +{%from "macro-table-pagination.html" import table_pagination%} + +{%block title%}Phenotypes{%endblock%} + +{%block pagetitle%}Phenotypes{%endblock%} + +{%block contents%} +{{super()}} + +
+

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.

+
+{%endblock%} + + +{%block more_javascript%}{%endblock%} diff --git a/uploader/templates/phenotypes/sui-review-job-data.html b/uploader/templates/phenotypes/sui-review-job-data.html new file mode 100644 index 0000000..ea4183d --- /dev/null +++ b/uploader/templates/phenotypes/sui-review-job-data.html @@ -0,0 +1,121 @@ +{%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%} +{%from "phenotypes/macro-display-pheno-dataset-card.html" import display_pheno_dataset_card%} + +{%block extrameta%} +{%if not job%} + +{%endif%} +{%endblock%} + +{%block title%}Phenotypes{%endblock%} + +{%block pagetitle%}Phenotypes{%endblock%} + +{%block lvl4_breadcrumbs%} + +{%endblock%} + +{%block contents%} + +{%if job%} +
+

Data Review

+

+ 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:

+ + + +
+ + +
+
+{%else%} +
+

Invalid Job

+

+ 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 + +

+
+{%endif%} +{%endblock%} + + +{%block javascript%} + +{%endblock%} -- cgit 1.4.1