forked from enviPath/enviPy
Compare commits
1 Commits
fix/frontp
...
feature/le
| Author | SHA1 | Date | |
|---|---|---|---|
| 95d16690ef |
@ -1,15 +1,15 @@
|
|||||||
import csv
|
import csv
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
from typing import Any, Callable, List, Optional
|
from typing import Any, Callable, List, Optional
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from celery.utils.functional import LRUCache
|
from celery.utils.functional import LRUCache
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
from epdb.logic import SPathway
|
from epdb.logic import SPathway
|
||||||
from epdb.models import Edge, EPModel, JobLog, Node, Package, Pathway, Rule, Setting, User
|
from epdb.models import EPModel, JobLog, Node, Package, Pathway, Rule, Setting, User, Edge
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
ML_CACHE = LRUCache(3) # Cache the three most recent ML models to reduce load times.
|
ML_CACHE = LRUCache(3) # Cache the three most recent ML models to reduce load times.
|
||||||
@ -29,7 +29,7 @@ def dispatch_eager(user: "User", job: Callable, *args, **kwargs):
|
|||||||
log.task_id = uuid4()
|
log.task_id = uuid4()
|
||||||
log.job_name = job.__name__
|
log.job_name = job.__name__
|
||||||
log.status = "SUCCESS"
|
log.status = "SUCCESS"
|
||||||
log.done_at = timezone.now()
|
log.done_at = datetime.now()
|
||||||
log.task_result = str(x) if x else None
|
log.task_result = str(x) if x else None
|
||||||
log.save()
|
log.save()
|
||||||
|
|
||||||
|
|||||||
@ -178,23 +178,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Open search modal function
|
|
||||||
function openSearchModal() {
|
|
||||||
const searchModal = document.getElementById("search_modal");
|
|
||||||
if (searchModal) {
|
|
||||||
searchModal.showModal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Click handler for search badge
|
|
||||||
const searchTrigger = document.getElementById("search-trigger");
|
|
||||||
if (searchTrigger) {
|
|
||||||
searchTrigger.addEventListener("click", function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
openSearchModal();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Global keyboard shortcut for search (Cmd+K on Mac, Ctrl+K on Windows/Linux)
|
// Global keyboard shortcut for search (Cmd+K on Mac, Ctrl+K on Windows/Linux)
|
||||||
document.addEventListener("keydown", function (event) {
|
document.addEventListener("keydown", function (event) {
|
||||||
// Check if user is typing in an input field
|
// Check if user is typing in an input field
|
||||||
@ -215,7 +198,7 @@
|
|||||||
|
|
||||||
if (isCorrectModifier && event.key === "k") {
|
if (isCorrectModifier && event.key === "k") {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
openSearchModal();
|
search_modal.showModal();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<div class="navbar-end">
|
<div class="navbar-end">
|
||||||
{% if not public_mode %}
|
{% if not public_mode %}
|
||||||
<a id="search-trigger" role="button" class="cursor-pointer">
|
<a href="/search" role="button">
|
||||||
<div
|
<div
|
||||||
class="flex items-center badge badge-dash space-x-1 bg-base-200 text-base-content/50 p-2 m-1"
|
class="flex items-center badge badge-dash space-x-1 bg-base-200 text-base-content/50 p-2 m-1"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -2,86 +2,74 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% block main_content %}
|
{% block main_content %}
|
||||||
<!-- Hero Section with Logo and Search -->
|
<!-- Hero Section with Logo and Search -->
|
||||||
<section class="hero relative mx-auto h-fit w-full max-w-5xl shadow-none">
|
<section class="hero h-fit max-w-5xl w-full shadow-none mx-auto relative">
|
||||||
<div
|
<div
|
||||||
class="hero from-primary-800 to-primary-600 min-h-[calc(100vh*0.4)] bg-gradient-to-br"
|
class="hero min-h-[calc(100vh*0.4)] bg-gradient-to-br from-primary-800 to-primary-600"
|
||||||
style="background-image: url('{% static "/images/hero.png" %}'); background-size: cover; background-position: center;"
|
style="background-image: url('{% static "/images/hero.png" %}'); background-size: cover; background-position: center;"
|
||||||
>
|
>
|
||||||
<div class="hero-overlay"></div>
|
<div class="hero-overlay"></div>
|
||||||
<!-- Predict Pathway text over the image -->
|
<!-- Predict Pathway text over the image -->
|
||||||
<div class="absolute bottom-40 left-1/8 z-10 -translate-x-8">
|
<div class="absolute bottom-40 left-1/8 -translate-x-8 z-10">
|
||||||
<h2 class="text-base-100 text-left text-3xl text-shadow-lg">
|
<h2 class="text-3xl text-base-100 text-shadow-lg text-left">
|
||||||
Predict Your Pathway
|
Predict Your Pathway
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="bg-base-200 mx-auto max-w-5xl shadow-md">
|
<div class="shadow-md max-w-5xl mx-auto bg-base-200">
|
||||||
<!-- Predict Pathway Section -->
|
<!-- Predict Pathway Section -->
|
||||||
<div
|
<div
|
||||||
class="relative z-20 mx-auto -mt-32 mb-10 w-full flex-col lg:flex-row-reverse"
|
class="flex-col lg:flex-row-reverse w-full mx-auto -mt-32 relative z-20 mb-10 "
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="card bg-base-100 mx-auto w-3/4 shrink-0 shadow-xl transition-all duration-300 ease-in-out"
|
class="card bg-base-100 shrink-0 shadow-xl w-3/4 mx-auto transition-all duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="my-4 ml-8 flex h-fit flex-row items-center justify-start">
|
<!-- Input Mode Toggle - Fixed position outside fieldset -->
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex flex-row justify-start items-center h-fit ml-8 my-4">
|
||||||
<label class="swap btn btn-ghost btn-sm p-1" title="Input Mode">
|
<div class="flex items-center gap-2">
|
||||||
|
<!-- <span class="text-sm text-neutral-500">Input Mode:</span> -->
|
||||||
|
<label class="toggle text-base-content toggle-md">
|
||||||
<input type="checkbox" />
|
<input type="checkbox" />
|
||||||
<span class="swap-on flex items-center gap-1">
|
<svg
|
||||||
<div
|
aria-label="smiles mode"
|
||||||
class="bg-neutral/50 text-neutral-content flex items-center justify-center rounded-full p-1"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
class="size-5"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-width="2"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="none"
|
||||||
>
|
>
|
||||||
<svg
|
<path
|
||||||
aria-label="smiles mode"
|
fill-rule="evenodd"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
d="M8 2.75A.75.75 0 0 1 8.75 2h7.5a.75.75 0 0 1 0 1.5h-3.215l-4.483 13h2.698a.75.75 0 0 1 0 1.5h-7.5a.75.75 0 0 1 0-1.5h3.215l4.483-13H8.75A.75.75 0 0 1 8 2.75Z"
|
||||||
viewBox="0 0 20 20"
|
clip-rule="evenodd"
|
||||||
class="size-5"
|
/>
|
||||||
>
|
</g>
|
||||||
<g
|
</svg>
|
||||||
stroke-linejoin="round"
|
<svg
|
||||||
stroke-linecap="round"
|
aria-label="draw mode"
|
||||||
stroke-width="2"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="currentColor"
|
viewBox="0 0 20 20"
|
||||||
stroke="none"
|
fill="currentColor"
|
||||||
>
|
stroke="none"
|
||||||
<path
|
class="size-5"
|
||||||
fill-rule="evenodd"
|
>
|
||||||
d="M8 2.75A.75.75 0 0 1 8.75 2h7.5a.75.75 0 0 1 0 1.5h-3.215l-4.483 13h2.698a.75.75 0 0 1 0 1.5h-7.5a.75.75 0 0 1 0-1.5h3.215l4.483-13H8.75A.75.75 0 0 1 8 2.75Z"
|
<path
|
||||||
clip-rule="evenodd"
|
d="m2.695 14.762-1.262 3.155a.5.5 0 0 0 .65.65l3.155-1.262a4 4 0 0 0 1.343-.886L17.5 5.501a2.121 2.121 0 0 0-3-3L3.58 13.419a4 4 0 0 0-.885 1.343Z"
|
||||||
/>
|
/>
|
||||||
</g>
|
</svg>
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="ext-xs">SMILES</span>
|
|
||||||
</span>
|
|
||||||
<span class="swap-off flex items-center gap-1">
|
|
||||||
<div
|
|
||||||
class="bg-neutral/50 text-neutral-content flex items-center justify-center rounded-full p-1"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-label="draw mode"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="currentColor"
|
|
||||||
stroke="none"
|
|
||||||
class="size-5"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="m2.695 14.762-1.262 3.155a.5.5 0 0 0 .65.65l3.155-1.262a4 4 0 0 0 1.343-.886L17.5 5.501a2.121 2.121 0 0 0-3-3L3.58 13.419a4 4 0 0 0-.885 1.343Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="text-base/50 text-xs">Draw</span>
|
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<fieldset
|
<fieldset
|
||||||
class="fieldset overflow-hidden transition-all duration-300 ease-in-out"
|
class="fieldset transition-all duration-300 ease-in-out overflow-hidden"
|
||||||
>
|
>
|
||||||
<form
|
<form
|
||||||
id="index-form"
|
id="index-form"
|
||||||
@ -91,29 +79,29 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div
|
<div
|
||||||
id="text-input-container"
|
id="text-input-container"
|
||||||
class="scale-100 transform opacity-100 transition-all duration-300 ease-in-out"
|
class="transition-all duration-300 ease-in-out opacity-100 transform scale-100"
|
||||||
>
|
>
|
||||||
<div class="join mx-auto w-full">
|
<div class="join w-full mx-auto">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="index-form-text-input"
|
id="index-form-text-input"
|
||||||
placeholder="canonical SMILES string"
|
placeholder="canonical SMILES string"
|
||||||
class="input input-md join-item grow"
|
class="input grow input-md join-item"
|
||||||
/>
|
/>
|
||||||
<button class="btn btn-neutral join-item">Predict!</button>
|
<button class="btn btn-neutral join-item">Predict!</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="label relative mt-1 w-full">
|
<div class="label relative w-full mt-1">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="example-link hover:text-primary cursor-pointer"
|
class="example-link cursor-pointer hover:text-primary"
|
||||||
data-smiles="CN1C=NC2=C1C(=O)N(C(=O)N2C)C"
|
data-smiles="CN1C=NC2=C1C(=O)N(C(=O)N2C)C"
|
||||||
title="load example"
|
title="load example"
|
||||||
>Caffeine</a
|
>Caffeine</a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="example-link hover:text-primary cursor-pointer"
|
class="example-link cursor-pointer hover:text-primary"
|
||||||
data-smiles="CC(C)CC1=CC=C(C=C1)C(C)C(=O)O"
|
data-smiles="CC(C)CC1=CC=C(C=C1)C(C)C(=O)O"
|
||||||
title="load example"
|
title="load example"
|
||||||
>Ibuprofen</a
|
>Ibuprofen</a
|
||||||
@ -126,7 +114,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="ketcher-container"
|
id="ketcher-container"
|
||||||
class="hidden w-full scale-95 transform opacity-0 transition-all duration-300 ease-in-out"
|
class="hidden w-full transition-all duration-300 ease-in-out opacity-0 transform scale-95"
|
||||||
>
|
>
|
||||||
<iframe
|
<iframe
|
||||||
id="index-ketcher"
|
id="index-ketcher"
|
||||||
@ -136,13 +124,11 @@
|
|||||||
class="rounded-lg"
|
class="rounded-lg"
|
||||||
></iframe>
|
></iframe>
|
||||||
<button
|
<button
|
||||||
class="btn btn-lg bg-primary-950 text-primary-50 join-item mt-2 w-full"
|
class="btn btn-lg bg-primary-950 text-primary-50 join-item w-full mt-2"
|
||||||
>
|
>
|
||||||
Predict!
|
Predict!
|
||||||
</button>
|
</button>
|
||||||
<div class="mt-1 flex w-full justify-end">
|
<a class="label mx-auto w-full mt-1" href="#">Advanced</a>
|
||||||
<a class="label justify-end" href="/predict">Advanced</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
@ -164,18 +150,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Community News Section -->
|
<!-- Community News Section -->
|
||||||
<section class="bg-base-200 z-10 mx-8 py-16">
|
<section class="py-16 bg-base-200 z-10 mx-8">
|
||||||
<div class="mx-auto max-w-7xl px-4">
|
<div class="max-w-7xl mx-auto px-4">
|
||||||
<h2 class="h2 mb-8 text-left font-bold">Community Updates</h2>
|
<h2 class="h2 font-bold text-left mb-8">Community Updates</h2>
|
||||||
|
|
||||||
<div id="community-news-container" class="flex justify-center gap-4">
|
<div id="community-news-container" class="flex gap-4 justify-center">
|
||||||
<!-- News cards will be populated here -->
|
<!-- News cards will be populated here -->
|
||||||
<div id="loading" class="flex w-full justify-center">
|
<div id="loading" class="flex justify-center w-full">
|
||||||
<span class="loading loading-spinner loading-lg"></span>
|
<span class="loading loading-spinner loading-lg"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 text-right">
|
<div class="text-right mt-6">
|
||||||
<a
|
<a
|
||||||
href="https://community.envipath.org/c/announcements/10"
|
href="https://community.envipath.org/c/announcements/10"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@ -191,18 +177,18 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Mission Statement Section -->
|
<!-- Mission Statement Section -->
|
||||||
<section class="from-base-200 to-base-100 bg-gradient-to-b py-16">
|
<section class="py-16 from-base-200 to-base-100 bg-gradient-to-b">
|
||||||
<div class="mx-auto px-8 md:px-12">
|
<div class="mx-auto px-8 md:px-12">
|
||||||
<div class="flex flex-row gap-4">
|
<div class="flex flex-row gap-4">
|
||||||
<div class="w-1/3">
|
<div class="w-1/3">
|
||||||
<img
|
<img
|
||||||
src="{% static "/images/ep-rule-artwork.png" %}"
|
src="{% static "/images/ep-rule-artwork.png" %}"
|
||||||
alt="rule-based iterative tree greneration"
|
alt="rule-based iterative tree greneration"
|
||||||
class="h-full w-full object-contain"
|
class="w-full h-full object-contain"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mr-8 w-2/3 space-y-4 text-left">
|
<div class="space-y-4 text-left w-2/3 mr-8">
|
||||||
<h2 class="h2 mb-8 font-bold">About enviPath</h2>
|
<h2 class="h2 font-bold mb-8">About enviPath</h2>
|
||||||
<p class="">
|
<p class="">
|
||||||
enviPath is a database and prediction system for the microbial
|
enviPath is a database and prediction system for the microbial
|
||||||
biotransformation of organic environmental contaminants. The
|
biotransformation of organic environmental contaminants. The
|
||||||
@ -215,7 +201,7 @@
|
|||||||
products. Explore our tools and contribute to advancing
|
products. Explore our tools and contribute to advancing
|
||||||
environmental biotransformation research.
|
environmental biotransformation research.
|
||||||
</p>
|
</p>
|
||||||
<div class="float-right flex flex-row gap-4">
|
<div class="flex flex-row gap-4 float-right">
|
||||||
<a href="/about" class="btn btn-ghost-neutral">Read More</a>
|
<a href="/about" class="btn btn-ghost-neutral">Read More</a>
|
||||||
<a href="/about" class="btn btn-neutral">Publications</a>
|
<a href="/about" class="btn btn-neutral">Publications</a>
|
||||||
</div>
|
</div>
|
||||||
@ -225,7 +211,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Partners Section -->
|
<!-- Partners Section -->
|
||||||
<section class="bg-base-100 py-14 sm:py-12">
|
<section class="py-14 sm:py-12 bg-base-100">
|
||||||
<div class="mx-auto px-6 lg:px-8">
|
<div class="mx-auto px-6 lg:px-8">
|
||||||
<div class="divider">
|
<div class="divider">
|
||||||
<h2 class="text-center text-lg/8 font-semibold">Backed by Science</h2>
|
<h2 class="text-center text-lg/8 font-semibold">Backed by Science</h2>
|
||||||
@ -236,12 +222,12 @@
|
|||||||
<img
|
<img
|
||||||
src="{% static "/images/uoa-logo-small.png" %}"
|
src="{% static "/images/uoa-logo-small.png" %}"
|
||||||
alt="The University of Auckland"
|
alt="The University of Auckland"
|
||||||
class="max-h-20 w-full object-contain lg:col-span-1"
|
class=" max-h-20 w-full object-contain lg:col-span-1"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
src="{% static "/images/logo-eawag.svg" %}"
|
src="{% static "/images/logo-eawag.svg" %}"
|
||||||
alt="Eawag"
|
alt="Eawag"
|
||||||
class="max-h-12 w-full object-contain lg:col-span-1"
|
class=" max-h-12 w-full object-contain lg:col-span-1"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
src="{% static "/images/uzh-logo.svg" %}"
|
src="{% static "/images/uzh-logo.svg" %}"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
197
templates/search.html
Normal file
197
templates/search.html
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
{% extends "framework.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div id=searchContent>
|
||||||
|
<div id="packSelector">
|
||||||
|
<label>Select Packages</label><br>
|
||||||
|
<select id="selPackages" name="selPackages" data-actions-box='true' class="selPackages" multiple
|
||||||
|
data-width='100%'>
|
||||||
|
{% if unreviewed_objects %}
|
||||||
|
<option disabled>Reviewed Packages</option>
|
||||||
|
{% endif %}
|
||||||
|
{% for obj in reviewed_objects %}
|
||||||
|
<option value="{{ obj.url }}" selected>{{ obj.name|safe }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
{% if unreviewed_objects %}
|
||||||
|
<option disabled>Unreviewed Packages</option>
|
||||||
|
{% endif %}
|
||||||
|
{% for obj in unreviewed_objects %}
|
||||||
|
<option value="{{ obj.url }}">{{ obj.name|safe }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<p></p>
|
||||||
|
<div>
|
||||||
|
<label>Search Term</label><br>
|
||||||
|
<div class="input-group" id="index-form-bar">
|
||||||
|
<input type="text" class="form-control" id='searchbar' placeholder="Benfuracarb">
|
||||||
|
<div class="input-group-btn">
|
||||||
|
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
|
||||||
|
id="mode-button"
|
||||||
|
aria-haspopup="true" aria-expanded="false">Text <span class="caret"></span></button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li class="dropdown-header">Text</li>
|
||||||
|
<li><a id="dropdown-predict-text-text">Text</a></li>
|
||||||
|
<li class="dropdown-header">SMILES</li>
|
||||||
|
<li><a id="dropdown-search-smiles-default" data-toggle="tooltip">Default</a></li>
|
||||||
|
<li><a id="dropdown-search-smiles-canonical">Canonical</a></li>
|
||||||
|
<li><a id="dropdown-search-smiles-exact">Exact</a></li>
|
||||||
|
<li class="dropdown-header">InChI</li>
|
||||||
|
<li><a id="dropdown-search-inchi-inchikey">InChIKey</a></li>
|
||||||
|
</ul>
|
||||||
|
<button class="btn" style="background-color:#222222;color:#9d9d9d" type="button" id="search-button">
|
||||||
|
Go!
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p></p>
|
||||||
|
<div id="results"></div>
|
||||||
|
<p></p>
|
||||||
|
<div id="loading"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function modeDropdownClicked() {
|
||||||
|
var suffix = ' <span class="caret"></span>';
|
||||||
|
var dropdownVal = $(this).text();
|
||||||
|
$('#mode-button').html(dropdownVal + suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSearchResponse(id, data) {
|
||||||
|
content = `
|
||||||
|
<div class='panel-group' id='search-accordion'>
|
||||||
|
<div class='panel panel-default'>
|
||||||
|
<div class='panel-heading' id='headingPanel' style='font-size:2rem;height: 46px'>
|
||||||
|
Results
|
||||||
|
</div>
|
||||||
|
<div id='descDiv'></div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
function makeContent(objs) {
|
||||||
|
links = "";
|
||||||
|
for (idx in objs) {
|
||||||
|
obj = objs[idx];
|
||||||
|
links += `<a class='list-group-item' href='${obj.url}'>${obj.name}</a>`
|
||||||
|
}
|
||||||
|
return links;
|
||||||
|
}
|
||||||
|
|
||||||
|
allEmpty = true;
|
||||||
|
for (key in data) {
|
||||||
|
if (key === 'searchterm') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data[key].length < 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allEmpty = false;
|
||||||
|
content += `
|
||||||
|
<div class='panel panel-default panel-heading list-group-item' style='background-color:silver'>
|
||||||
|
<h4 class='panel-title'>
|
||||||
|
<a id='${key}_link' data-toggle='collapse' data-parent='#search-accordion' href='#${key}_panel'>
|
||||||
|
${key}
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div id='${key}_panel' class='panel-collapse collapse in'>
|
||||||
|
<div class='panel-body list-group-item'>
|
||||||
|
${makeContent(data[key])}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
if (allEmpty) {
|
||||||
|
$('#' + id).append('<div class="alert alert-danger" role="alert"><p>' + "No results..." + '</p></div>');
|
||||||
|
} else {
|
||||||
|
$('#' + id).append(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function search(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
query = $("#searchbar").val()
|
||||||
|
|
||||||
|
if (!query) {
|
||||||
|
// Nothing to search...
|
||||||
|
console.log("Search phrase empty, won't do search")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selPacks = [];
|
||||||
|
$("#selPackages :selected").each(function () {
|
||||||
|
var id = this.value;
|
||||||
|
selPacks.push(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (selPacks.length < 1) {
|
||||||
|
console.log("No package selected, won't do search")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mode = $('#mode-button').text().trim().toLowerCase();
|
||||||
|
|
||||||
|
var par = {};
|
||||||
|
par['packages'] = selPacks;
|
||||||
|
par['search'] = query;
|
||||||
|
par['mode'] = mode;
|
||||||
|
|
||||||
|
console.log(par);
|
||||||
|
|
||||||
|
var queryString = $.param(par, true);
|
||||||
|
|
||||||
|
makeLoadingGif("#loading", "{% static '/images/wait.gif' %}");
|
||||||
|
|
||||||
|
$("#results").empty();
|
||||||
|
|
||||||
|
$.getJSON("{{ SERVER_BASE }}/search?" + queryString, function (result) {
|
||||||
|
handleSearchResponse("results", result);
|
||||||
|
$("#loading").empty();
|
||||||
|
}).fail(function (d) {
|
||||||
|
$("#loading").empty();
|
||||||
|
console.log(d.responseText);
|
||||||
|
handleError(JSON.parse(d.responseText));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
tooltips = {
|
||||||
|
'dropdown-predict-text-text': 'The inserted pattern will be searched on all enviPath object names and descriptions',
|
||||||
|
'dropdown-search-smiles-default': 'Search by SMILES, stereochemistry and charge are ignored',
|
||||||
|
'dropdown-search-smiles-canonical': 'Search by SMILES, stereochemistry is ignored but charge is preserved',
|
||||||
|
'dropdown-search-smiles-exact': 'Search by SMILES, exact match for stereochemistry and charge',
|
||||||
|
'dropdown-search-inchi-inchikey': 'Search by InChIKey',
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(tooltips).forEach(key => {
|
||||||
|
$('#' + key).tooltip({
|
||||||
|
placement: "top",
|
||||||
|
title: tooltips[key]
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#' + key).on('click', modeDropdownClicked);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#selPackages").selectpicker();
|
||||||
|
$("#search-button").on("click", search);
|
||||||
|
|
||||||
|
$("#searchbar").on("keydown", function (e) {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
search(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
{% if search_result %}
|
||||||
|
$('#searchbar').val('{{ search_result.searchterm }}')
|
||||||
|
handleSearchResponse("results", {{ search_result|safe }});
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock content %}
|
||||||
Reference in New Issue
Block a user