From c1553d9cd4cce05070d59af429e54c9b229f0553 Mon Sep 17 00:00:00 2001 From: Tobias O Date: Wed, 12 Nov 2025 02:38:57 +1300 Subject: [PATCH] [Feature] Add Predict Pathway Page in Modern UI (#188) ## Major Changes - Predict Pathway is now a separate view as it is meant as adavanced prediction interface ## Current status ![image.png](/attachments/c5bc3f5c-cf30-4b5f-acb3-a70117a96dae) Co-authored-by: Tim Lorsbach Reviewed-on: https://git.envipath.com/enviPath/enviPy/pulls/188 Co-authored-by: Tobias O Co-committed-by: Tobias O --- epdb/urls.py | 1 + epdb/views.py | 20 +- templates/actions/collections/pathway.html | 4 +- templates/framework.html | 573 +++++++++++------- templates/framework_modern.html | 8 +- templates/includes/navbar.html | 14 +- templates/index/index.html | 659 ++++++++++++--------- templates/predict_pathway.html | 188 ++++++ templates/static/login.html | 2 +- 9 files changed, 939 insertions(+), 530 deletions(-) create mode 100644 templates/predict_pathway.html diff --git a/epdb/urls.py b/epdb/urls.py index b4bdb9f2..151cfb51 100644 --- a/epdb/urls.py +++ b/epdb/urls.py @@ -48,6 +48,7 @@ urlpatterns = [ re_path(r"^user$", v.users, name="users"), re_path(r"^group$", v.groups, name="groups"), re_path(r"^search$", v.search, name="search"), + re_path(r"^predict$", v.predict_pathway, name="predict_pathway"), # User Detail re_path(rf"^user/(?P{UUID})", v.user, name="user"), # Group Detail diff --git a/epdb/views.py b/epdb/views.py index 306d2e0a..74406671 100644 --- a/epdb/views.py +++ b/epdb/views.py @@ -362,6 +362,18 @@ def index(request): return render(request, "index/index.html", context) +def predict_pathway(request): + """Top-level predict pathway view using user's default package.""" + if request.method != "GET": + return HttpResponseNotAllowed(["GET"]) + + context = get_base_context(request) + context["title"] = "enviPath - Predict Pathway" + context["meta"]["current_package"] = context["meta"]["user"].default_package + + return render(request, "predict_pathway.html", context) + + def packages(request): current_user = _anonymous_or_real(request) @@ -1301,7 +1313,7 @@ def package_compound_structures(request, package_uuid, compound_uuid): elif request.method == "POST": structure_name = request.POST.get("structure-name") - structure_smiles = request.POST.get("structure-smiles").strip() + structure_smiles = request.POST.get("structure-smiles") structure_description = request.POST.get("structure-description") try: @@ -1483,11 +1495,11 @@ def package_rules(request, package_uuid): # Obtain parameters as required by rule type if rule_type == "SimpleAmbitRule": - params["smirks"] = request.POST.get("rule-smirks").strip() + params["smirks"] = request.POST.get("rule-smirks") params["reactant_filter_smarts"] = request.POST.get("rule-reactant-smarts") params["product_filter_smarts"] = request.POST.get("rule-product-smarts") elif rule_type == "SimpleRDKitRule": - params["reaction_smarts"] = request.POST.get("rule-reaction-smarts").strip() + params["reaction_smarts"] = request.POST.get("rule-reaction-smarts") elif rule_type == "ParallelRule": pass elif rule_type == "SequentialRule": @@ -1684,7 +1696,7 @@ def package_reactions(request, package_uuid): elif request.method == "POST": reaction_name = request.POST.get("reaction-name") reaction_description = request.POST.get("reaction-description") - reactions_smirks = request.POST.get("reaction-smirks").strip() + reactions_smirks = request.POST.get("reaction-smirks") educts = reactions_smirks.split(">>")[0].split(".") products = reactions_smirks.split(">>")[1].split(".") diff --git a/templates/actions/collections/pathway.html b/templates/actions/collections/pathway.html index bcfc043c..fce48c86 100644 --- a/templates/actions/collections/pathway.html +++ b/templates/actions/collections/pathway.html @@ -1,6 +1,6 @@ {% if meta.can_edit %}
  • - + New Pathway
  • -{% endif %} \ No newline at end of file +{% endif %} diff --git a/templates/framework.html b/templates/framework.html index 516d8194..ecedc8fc 100644 --- a/templates/framework.html +++ b/templates/framework.html @@ -1,11 +1,15 @@ - + -{% load static %} - + {% load static %} + {{ title }} - + {# Favicon #} - + {# Tailwind CSS disabled for legacy Bootstrap framework #} {# Pages using this framework will be migrated to framework_modern.html incrementally #} @@ -13,36 +17,45 @@ {# Legacy Bootstrap 3.3.7 - scoped to .legacy-bootstrap #} - + - - + + {# Bootstrap compatibility styles #} @@ -50,40 +63,44 @@ - {# General EP JS #} {# Modal Steps for Stepwise Modal Wizards #} {% if not debug %} - - - + + + {% endif %} - - - - -
    - -
    - + -
    - {% if breadcrumbs %} +
    + {% if breadcrumbs %}
    - +
    - {% endif %} - {% if message %} -
    - {{ message }} -
    - {% endif %} - {% block content %} - {% endblock content %} - {% if meta.url_contains_package and meta.current_package.license %} + {% endif %} + {% if message %} +
    {{ message }}
    + {% endif %} + {% block content %} + {% endblock content %} + {% if meta.url_contains_package and meta.current_package.license %}

    -
    -
    - License -
    +
    + -
    -
    - - - -
    +
    +
    + +
    - {% endif %} -
    - - -
    -
    -
    -
    -
    - -
    + {% endif %}
    -
    -
    -
    - +
    +
    -
    -
    - + - -{% block modals %} - {% include "modals/cite_modal.html" %} - {% include "modals/predict_modal.html" %} - {% include "modals/batch_predict_modal.html" %} -{% endblock %} - + }); + + {% block modals %} + {% include "modals/cite_modal.html" %} + {% include "modals/predict_modal.html" %} + {% include "modals/batch_predict_modal.html" %} + {% endblock %} + diff --git a/templates/framework_modern.html b/templates/framework_modern.html index bd7ffce2..b808550c 100644 --- a/templates/framework_modern.html +++ b/templates/framework_modern.html @@ -72,7 +72,7 @@ {% endif %} - + {% include "includes/navbar.html" %} {# Main Content Area #} @@ -81,7 +81,7 @@ {# Breadcrumbs - outside main content, optional #} {% if breadcrumbs %}
    -