From 2b79adc2f765a4fc40a8c20854d273da3aea811c Mon Sep 17 00:00:00 2001 From: Tobias O Date: Wed, 12 Nov 2025 01:52:41 +1300 Subject: [PATCH] [Feature] Implement Search modal in Modern UI (#185) Implementing a search modal (stretching the level of dynamic that is possible without going to frameworks). ## Major Change - Search needs packages and is available everywhere now; so had to add reviewed and user packages to global context. Co-authored-by: Tim Lorsbach Reviewed-on: https://git.envipath.com/enviPath/enviPy/pulls/185 Co-authored-by: Tobias O Co-committed-by: Tobias O --- envipath/settings.py | 1 + epdb/context_processors.py | 32 ++ epdb/views.py | 6 +- static/css/input.css | 1 + templates/framework.html | 1 - templates/framework_modern.html | 280 ++++++++------- templates/includes/navbar.html | 196 +++++++---- templates/modals/search_modal.html | 535 +++++++++++++++++++++++++++++ templates/modals/signup_modal.html | 110 ------ 9 files changed, 863 insertions(+), 299 deletions(-) create mode 100644 epdb/context_processors.py create mode 100644 templates/modals/search_modal.html delete mode 100644 templates/modals/signup_modal.html diff --git a/envipath/settings.py b/envipath/settings.py index dd6491d0..095105a3 100644 --- a/envipath/settings.py +++ b/envipath/settings.py @@ -87,6 +87,7 @@ TEMPLATES = [ "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", + "epdb.context_processors.package_context", ], }, }, diff --git a/epdb/context_processors.py b/epdb/context_processors.py new file mode 100644 index 00000000..77a971b3 --- /dev/null +++ b/epdb/context_processors.py @@ -0,0 +1,32 @@ +""" +Context processors for enviPy application. + +Context processors automatically make variables available to all templates. +""" + +from .logic import PackageManager +from .models import Package + + +def package_context(request): + """ + Provides package data for the search modal which is included globally + in framework_modern.html. + + Returns: + dict: Context dictionary with reviewed and unreviewed packages + """ + current_user = request.user + + reviewed_package_qs = PackageManager.get_reviewed_packages() + + unreviewed_package_qs = Package.objects.none() + + # Only get user-specific packages if user is authenticated + if current_user.is_authenticated: + unreviewed_package_qs = PackageManager.get_all_readable_packages(current_user) + + return { + "reviewed_packages": reviewed_package_qs, + "unreviewed_packages": unreviewed_package_qs, + } diff --git a/epdb/views.py b/epdb/views.py index 08134917..306d2e0a 100644 --- a/epdb/views.py +++ b/epdb/views.py @@ -682,7 +682,6 @@ def search(request): if request.method == "GET": package_urls = request.GET.getlist("packages") searchterm = request.GET.get("search", "").strip() - mode = request.GET.get("mode") # add HTTP_ACCEPT check to differentiate between index and ajax call @@ -783,6 +782,7 @@ def package_models(request, package_uuid): elif request.method == "POST": log_post_params(request) + name = request.POST.get("model-name") description = request.POST.get("model-description") @@ -1174,7 +1174,7 @@ def package_compounds(request, package_uuid): elif request.method == "POST": compound_name = request.POST.get("compound-name") - compound_smiles = request.POST.get("compound-smiles").strip() + compound_smiles = request.POST.get("compound-smiles") compound_description = request.POST.get("compound-description") c = Compound.create(current_package, compound_smiles, compound_name, compound_description) @@ -1684,7 +1684,6 @@ 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() educts = reactions_smirks.split(">>")[0].split(".") products = reactions_smirks.split(">>")[1].split(".") @@ -2259,6 +2258,7 @@ def package_pathway_edges(request, package_uuid, pathway_uuid): elif request.method == "POST": log_post_params(request) + edge_name = request.POST.get("edge-name") edge_description = request.POST.get("edge-description") diff --git a/static/css/input.css b/static/css/input.css index 43ad742b..98ad1678 100644 --- a/static/css/input.css +++ b/static/css/input.css @@ -30,6 +30,7 @@ /* Import DaisyUI plugin */ @plugin "daisyui" { logs: true; + exclude: rootscrollgutter; } @import "./daisyui-theme.css"; diff --git a/templates/framework.html b/templates/framework.html index 2f6ea7da..516d8194 100644 --- a/templates/framework.html +++ b/templates/framework.html @@ -286,7 +286,6 @@ {% block modals %} {% include "modals/cite_modal.html" %} - {% include "modals/signup_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 87f008c9..bd7ffce2 100644 --- a/templates/framework_modern.html +++ b/templates/framework_modern.html @@ -1,38 +1,49 @@ - + -{% load static %} - + {% load static %} + {{ title }} - + - + {# Favicon #} - + {# Tailwind CSS + DaisyUI Output #} - + {# jQuery - Keep for compatibility with existing JS #} {# Font Awesome #} - + {# Discourse embed for community #} {# General EP JS #} @@ -41,136 +52,155 @@ {% if not debug %} - - - + + + {% endif %} - - + + {% include "includes/navbar.html" %} {# Main Content Area #}
- {% block main_content %} - {# Breadcrumbs - outside main content, optional #} - {% if breadcrumbs %} -
- -
- {% endif %} - - {# Main content container - paper effect on medium+ screens #} -
- {# Messages - inside paper #} - {% if message %} -
- {{ message }} -
- {% endif %} - - {# Page content - no enforced styles #} - {% block content %} - {% endblock content %} - - {# License - inside paper if present #} - {% if meta.url_contains_package and meta.current_package.license %} -
- -
- License -
-
- - License - -
-
- {% endif %} + {% block main_content %} + {# Breadcrumbs - outside main content, optional #} + {% if breadcrumbs %} +
+ - {% endblock main_content %} +
+ {% endif %} + + {# Main content container - paper effect on medium+ screens #} +
+ {# Messages - inside paper #} + {% if message %} +
{{ message }}
+ {% endif %} + + {# Page content - no enforced styles #} + {% block content %} + {% endblock content %} + + {# License - inside paper if present #} + {% if meta.url_contains_package and meta.current_package.license %} +
+ +
License
+
+ + License + +
+
+ {% endif %} +
+ {% endblock main_content %}
{% include "includes/footer.html" %} {# Floating Help Tab #} {% if not public_mode %} - {% endif %} - {# Modals - TODO: Convert these to DaisyUI modals #} {% block modals %} - {# Note: These modals still use Bootstrap markup and will need conversion #} - {% include "modals/cite_modal.html" %} - {% include "modals/signup_modal.html" %} - {% include "modals/predict_modal.html" %} - {% include "modals/batch_predict_modal.html" %} + {% include "modals/search_modal.html" %} {% endblock %} - + diff --git a/templates/includes/navbar.html b/templates/includes/navbar.html index 6b79815b..b2d59a88 100644 --- a/templates/includes/navbar.html +++ b/templates/includes/navbar.html @@ -1,71 +1,147 @@ {% load static %} {# Modern DaisyUI Navbar #} diff --git a/templates/modals/search_modal.html b/templates/modals/search_modal.html new file mode 100644 index 00000000..a22623e9 --- /dev/null +++ b/templates/modals/search_modal.html @@ -0,0 +1,535 @@ +{% load static %} + + + + + + + + diff --git a/templates/modals/signup_modal.html b/templates/modals/signup_modal.html deleted file mode 100644 index 8f20b01f..00000000 --- a/templates/modals/signup_modal.html +++ /dev/null @@ -1,110 +0,0 @@ -