forked from enviPath/enviPy
Frontpage update (#179)
This PR introduces an overhaul for the front page and login features while keeping the rest of the application intact. ## Major Changes - TailwindCSS + DaisyUI Integration: Add modern CSS framework for component-based utility styling - Build System: Added pnpm for CSS building; can be extended for updated frontend builds in the future - Navbar + Footer: Redesigned and includable; old version retained for unstyled elements - Optimized Assets: Added minified and CSS-stylable logos ## New Features - Static Pages: Added comprehensive mockups of static pages (legal, privacy policy, terms of use, contact, etc.). **Note:** These have to be fixed before a public release, as their content is largely unreviewed and incorrect. Probably best to do in a separate PR that only contains updates to these. - Discourse API: Implement minimal features based on RestAPI for controllable results. ## Current bugs - [x] The static pages include the default navbar and footer on the login page. This will likely not work, as users need to access it before logging in; no good workaround so far (problem with Django templating system). - [ ] The front page predict link is currently non-functional; the redesigned page is almost ready but better done in a separate PR as it also touches Django code. - [x] Visual bug with the news cards. Still intend to fix for this PR Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#179 Reviewed-by: jebus <lorsbach@envipath.com> Co-authored-by: Tobias O <tobias.olenyi@envipath.com> Co-committed-by: Tobias O <tobias.olenyi@envipath.com>
This commit is contained in:
@ -1,186 +1,360 @@
|
||||
{% extends "framework.html" %}
|
||||
{% extends "framework_modern.html" %}
|
||||
{% load static %}
|
||||
{% block content %}
|
||||
<!-- TODO rename ids as well as remove pathways if modal is closed!-->
|
||||
<div class="modal fade" tabindex="-1" id="foundMatching" role="dialog" aria-labelledby="foundModal"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">
|
||||
<span aria-hidden="true">×</span>
|
||||
<span class="sr-only">Close</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="newPackMod">Found Pathway in Database</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>We found at least one pathway in the database with the given root
|
||||
compound. Do you want to open any of the existing pathways or
|
||||
predict a new one? To open an existing pathway, simply click
|
||||
on the pathway, to predict a new one, click Predict. The predicted
|
||||
pathway might differ from the ones in the database due to the
|
||||
settings used in the prediction.</p>
|
||||
<div id="foundPathways"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a id="modal-predict" class="btn btn-primary" href="#">Predict</a>
|
||||
<button type="button" id="cancel-predict" class="btn btn-default" data-dismiss="modal">Cancel
|
||||
</button>
|
||||
{% block main_content %}
|
||||
|
||||
<!-- Hero Section with Logo and Search -->
|
||||
<section class="hero h-fit max-w-5xl w-full shadow-none mx-auto relative">
|
||||
|
||||
<div 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;"
|
||||
>
|
||||
<div class="hero-overlay"></div>
|
||||
<!-- Predict Pathway text over the image -->
|
||||
<div class="absolute bottom-40 left-1/8 -translate-x-8 z-10">
|
||||
<h2 class="text-3xl text-base-100 text-shadow-lg text-left">Predict Your Pathway</h2>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="shadow-md max-w-5xl mx-auto bg-base-200">
|
||||
|
||||
<!-- Predict Pathway Section -->
|
||||
<div class="flex-col lg:flex-row-reverse w-full mx-auto -mt-32 relative z-20 mb-10 ">
|
||||
<div 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">
|
||||
<!-- Input Mode Toggle - Fixed position outside fieldset -->
|
||||
<div class="flex flex-row justify-start items-center h-fit ml-8 my-4">
|
||||
<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" />
|
||||
<svg aria-label="smiles mode" 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"
|
||||
>
|
||||
<path 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" clip-rule="evenodd" />
|
||||
</g>
|
||||
</svg>
|
||||
<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>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<fieldset class="fieldset transition-all duration-300 ease-in-out overflow-hidden">
|
||||
<form id="index-form" action="{{ meta.current_package.url }}/pathway" method="POST">
|
||||
{% csrf_token %}
|
||||
<div id="text-input-container" class="transition-all duration-300 ease-in-out opacity-100 transform scale-100">
|
||||
<div class="join w-full mx-auto">
|
||||
<input type="text" id="index-form-text-input" placeholder="canonical SMILES string" class="input grow input-md join-item" />
|
||||
<button class="btn btn-neutral join-item">Predict!</button>
|
||||
</div>
|
||||
<div class="label relative w-full mt-1" >
|
||||
<div class="flex gap-2">
|
||||
<a href="#" class="example-link cursor-pointer hover:text-primary"
|
||||
data-smiles="CN1C=NC2=C1C(=O)N(C(=O)N2C)C"
|
||||
title="load example">Caffeine</a>
|
||||
<a href="#" class="example-link cursor-pointer hover:text-primary"
|
||||
data-smiles="CC(C)CC1=CC=C(C=C1)C(C)C(=O)O"
|
||||
title="load example">Ibuprofen</a>
|
||||
</div>
|
||||
<a class="absolute top-0 left-[calc(100%-5.4rem)]" href="#">Advanced</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ketcher-container" class="hidden w-full transition-all duration-300 ease-in-out opacity-0 transform scale-95">
|
||||
<iframe id="index-ketcher" src="{% static '/js/ketcher2/ketcher.html' %}"
|
||||
width="100%" height="400" class="rounded-lg"></iframe>
|
||||
<button class="btn btn-lg bg-primary-950 text-primary-50 join-item w-full mt-2">Predict!</button>
|
||||
<a class="label mx-auto w-full mt-1" href="#">Advanced</a>
|
||||
</div>
|
||||
<input type="hidden" id="index-form-smiles" name="smiles" value="smiles">
|
||||
<input type="hidden" id="index-form-predict" name="predict" value="predict">
|
||||
<input type="hidden" id="current-action" value="predict">
|
||||
</form>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-8">
|
||||
<div class="jumbotron">
|
||||
<h1>
|
||||
<img id="image-logo-long" class="img-responsive" alt="enviPath" width="1000ex"
|
||||
src='{% static "/images/logo-long.svg" %}'/>
|
||||
</h1>
|
||||
<p>enviPath is a database and prediction system for the microbial
|
||||
biotransformation of organic environmental contaminants. The
|
||||
database provides the possibility to store and view experimentally
|
||||
observed biotransformation pathways. The pathway prediction system
|
||||
provides different relative reasoning models to predict likely biotransformation
|
||||
pathways and products. You can try it out below.
|
||||
</p>
|
||||
<p>
|
||||
<a class="btn" style="background-color:#222222;color:#9d9d9d" role="button" target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/Main_Page">Learn more >></a>
|
||||
</p>
|
||||
|
||||
|
||||
<!-- Community News Section -->
|
||||
<section class="py-16 bg-base-200 z-10 mx-8">
|
||||
<div class="max-w-7xl mx-auto px-4">
|
||||
<h2 class="h2 font-bold text-left mb-8">Community Updates</h2>
|
||||
|
||||
<div id="community-news-container" class="flex gap-4 justify-center">
|
||||
<!-- News cards will be populated here -->
|
||||
<div id="loading" class="flex justify-center w-full">
|
||||
<span class="loading loading-spinner loading-lg"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-right mt-6">
|
||||
<a href="https://community.envipath.org/c/announcements/10" target="_blank" class="btn btn-ghost btn-sm">
|
||||
Read More Announcements
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Discourse API integration -->
|
||||
<script src="{% static 'js/discourse-api.js' %}"></script>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Mission Statement Section -->
|
||||
<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="flex flex-row gap-4">
|
||||
<div class="w-1/3">
|
||||
<img src="{% static "/images/ep-rule-artwork.png" %}" alt="rule-based iterative tree greneration" class="w-full h-full object-contain" />
|
||||
</div>
|
||||
<div class="space-y-4 text-left w-2/3 mr-8">
|
||||
<h2 class="h2 font-bold mb-8">About enviPath</h2>
|
||||
<p class="">
|
||||
enviPath is a database and prediction system for the microbial
|
||||
biotransformation of organic environmental contaminants. The
|
||||
database provides the possibility to store and view experimentally
|
||||
observed biotransformation pathways.
|
||||
</p>
|
||||
<p class="">
|
||||
The pathway prediction system provides different relative reasoning models
|
||||
to predict likely biotransformation pathways and products. Explore our tools
|
||||
and contribute to advancing environmental biotransformation research.
|
||||
</p>
|
||||
<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-neutral">Publications</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="loading"></div>
|
||||
<div class="col-xs-4">
|
||||
<d-topics-list discourse-url="https://community.envipath.org" per-page="10" category="10"
|
||||
template="complete"></d-topics-list>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<form id="index-form" action="{{ meta.current_package.url }}/pathway" method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="input-group" id="index-form-bar">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li>
|
||||
<iframe id="index-form-ketcher" src="{% static '/js/ketcher2/ketcher.html' %}" width="100%"
|
||||
height="510"></iframe>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="text" class="form-control" id='index-form-text-input'
|
||||
placeholder="Enter a SMILES to predict a Pathway or type something to search">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false" id="action-button">Predict <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a id="dropdown-predict">Predict</a></li>
|
||||
<li><a id="dropdown-search">Search</a></li>
|
||||
</ul>
|
||||
<button class="btn" style="background-color:#222222;color:#9d9d9d" type="button" id="run-button">Go!
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Partners Section -->
|
||||
<section class="py-14 sm:py-12 bg-base-100">
|
||||
<div class="mx-auto px-6 lg:px-8">
|
||||
<div class="divider"><h2 class="text-center text-lg/8 font-semibold">Backed by Science</h2></div>
|
||||
<div class="mx-auto mt-10 grid max-w-lg grid-cols-4 items-center gap-x-8 gap-y-10 sm:max-w-xl sm:grid-cols-6 sm:gap-x-10 lg:mx-0 lg:max-w-none lg:grid-cols-3">
|
||||
<img src="{% static "/images/uoa-logo-small.png" %}" alt="The University of Auckland" class=" max-h-20 w-full object-contain lg:col-span-1" />
|
||||
<img src="{% static "/images/logo-eawag.svg" %}" alt="Eawag" class=" max-h-12 w-full object-contain lg:col-span-1" />
|
||||
<img src="{% static "/images/uzh-logo.svg" %}" alt="University of Zurich" class="2 max-h-16 w-full object-contain lg:col-span-1" />
|
||||
</div>
|
||||
<input type="hidden" id="index-form-smiles" name="smiles" value="smiles">
|
||||
<input type="hidden" id="index-form-predict" name="predict" value="predict">
|
||||
</form>
|
||||
</div>
|
||||
<p></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<script language="javascript">
|
||||
var currentPackage = "{{ meta.current_package.url }}";
|
||||
|
||||
function goButtonClicked() {
|
||||
$(this).prop("disabled", true);
|
||||
// Discourse API integration is now handled by discourse-api.js
|
||||
|
||||
var action = $('#action-button').text().trim();
|
||||
// Function to render Discourse topics into cards
|
||||
function renderDiscourseTopics(topics) {
|
||||
const container = document.getElementById('community-news-container');
|
||||
if (!container) return;
|
||||
|
||||
var textSmiles = $('#index-form-text-input').val().trim();
|
||||
// Clear container
|
||||
container.innerHTML = '';
|
||||
|
||||
if (textSmiles === '') {
|
||||
$(this).prop("disabled", false);
|
||||
return;
|
||||
}
|
||||
// Create cards for each topic
|
||||
topics.forEach(topic => {
|
||||
const card = createDiscourseCard(topic);
|
||||
container.insertAdjacentHTML('beforeend', card);
|
||||
});
|
||||
}
|
||||
|
||||
var ketcherSmiles = getKetcher('index-form-ketcher').getSmiles().trim();
|
||||
// Function to create HTML card for a topic
|
||||
function createDiscourseCard(topic) {
|
||||
const date = new Date(topic.created_at).toLocaleDateString();
|
||||
|
||||
if (action !== 'Search' && ketcherSmiles !== '' && textSmiles !== ketcherSmiles) {
|
||||
console.log("Ketcher and TextInput differ!");
|
||||
}
|
||||
return `
|
||||
<div class="card bg-white shadow-xs hover:shadow-lg transition-shadow duration-300 h-64 w-75 flex-shrink-0">
|
||||
<div class="card-body flex flex-col h-full">
|
||||
<h3 class="card-title leading-tight font-normal tracking-tight h-12 mb-2 line-clamp-2 text-ellipsis wrap-break-word overflow-hidden">
|
||||
<a href="${topic.url}" target="_blank" class="hover:text-primary">
|
||||
${topic.title}
|
||||
</a>
|
||||
</h3>
|
||||
<div class="text-sm line-clamp-4 break-words" >
|
||||
${topic.excerpt}
|
||||
</div>
|
||||
|
||||
if (action === 'Search') {
|
||||
var par = {};
|
||||
par['search'] = textSmiles;
|
||||
par['mode'] = 'text';
|
||||
var queryString = $.param(par, true);
|
||||
window.location.href = "/search?" + queryString;
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="avatar tooltip tooltip-right" data-tip="${topic.author}">
|
||||
<div class="w-8 rounded-full">
|
||||
<img src="${topic.author_avatar}" alt="${topic.author}" />
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-xs text-gray-500">${date}</span>
|
||||
</div>
|
||||
<a href="${topic.url}" target="_blank" class="btn btn-ghost text-neutral-500 rounded-full p-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 7v14"/>
|
||||
<path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Make render function globally available
|
||||
window.renderDiscourseTopics = renderDiscourseTopics;
|
||||
|
||||
// Toggle functionality with smooth animations
|
||||
function toggleInputMode() {
|
||||
const toggle = $('input[type="checkbox"]');
|
||||
const textContainer = $('#text-input-container');
|
||||
const ketcherContainer = $('#ketcher-container');
|
||||
const formCard = $('.card');
|
||||
const fieldset = $('.fieldset');
|
||||
|
||||
if (toggle.is(':checked')) {
|
||||
// Draw mode - show Ketcher, hide text input
|
||||
textContainer.addClass('opacity-0 transform scale-95');
|
||||
textContainer.removeClass('opacity-100 transform scale-100');
|
||||
|
||||
// Adjust fieldset padding for Ketcher mode - reduce padding and make more compact
|
||||
fieldset.removeClass('p-8');
|
||||
fieldset.addClass('p-4');
|
||||
|
||||
// Wait for fade out to complete, then hide and show new content
|
||||
setTimeout(() => {
|
||||
textContainer.addClass('hidden');
|
||||
ketcherContainer.removeClass('hidden opacity-0 transform scale-95');
|
||||
ketcherContainer.addClass('opacity-100 transform scale-100');
|
||||
|
||||
// Force re-evaluation of iframe size
|
||||
const iframe = document.getElementById('index-ketcher');
|
||||
if (iframe) {
|
||||
iframe.style.height = '400px';
|
||||
}
|
||||
}, 300);
|
||||
} else {
|
||||
$('#index-form-smiles').val(textSmiles);
|
||||
$('#index-form').submit();
|
||||
// SMILES mode - show text input, hide Ketcher
|
||||
ketcherContainer.addClass('opacity-0 transform scale-95');
|
||||
ketcherContainer.removeClass('opacity-100 transform scale-100');
|
||||
|
||||
// Restore fieldset padding for text input mode
|
||||
fieldset.removeClass('p-4');
|
||||
fieldset.addClass('p-8');
|
||||
|
||||
// Wait for fade out to complete, then hide and show new content
|
||||
setTimeout(() => {
|
||||
ketcherContainer.addClass('hidden');
|
||||
textContainer.removeClass('hidden opacity-0 transform scale-95');
|
||||
textContainer.addClass('opacity-100 transform scale-100');
|
||||
}, 300);
|
||||
|
||||
// Transfer SMILES from Ketcher to text input if available
|
||||
if (window.indexKetcher && window.indexKetcher.getSmiles) {
|
||||
const smiles = window.indexKetcher.getSmiles();
|
||||
if (smiles && smiles.trim() !== '') {
|
||||
$('#index-form-text-input').val(smiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function actionDropdownClicked() {
|
||||
var suffix = ' <span class="caret"></span>';
|
||||
var dropdownVal = $(this).text();
|
||||
|
||||
if (dropdownVal === 'Search') {
|
||||
$("#index-form").attr("action", '/search');
|
||||
$("#index-form").attr("method", 'GET');
|
||||
} else {
|
||||
$("#index-form").attr("action", currentPackage + "/pathway");
|
||||
}
|
||||
|
||||
$('#action-button').html(dropdownVal + suffix);
|
||||
}
|
||||
|
||||
function ketcherToTextInput() {
|
||||
$('#index-form-text-input').val(this.ketcher.getSmiles());
|
||||
// Ketcher integration
|
||||
function indexKetcherToTextInput() {
|
||||
$('#index-form-smiles').val(this.ketcher.getSmiles());
|
||||
}
|
||||
|
||||
$(function () {
|
||||
// Initialize fieldset with proper padding
|
||||
$('.fieldset').addClass('p-8');
|
||||
|
||||
$('#index-form').on("keydown", function (e) {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
goButtonClicked();
|
||||
}
|
||||
});
|
||||
// Toggle event listener
|
||||
$('input[type="checkbox"]').on('change', toggleInputMode);
|
||||
|
||||
// Code that should be executed once DOM is ready goes here
|
||||
$('#dropdown-predict').on('click', actionDropdownClicked);
|
||||
$('#dropdown-search').on('click', actionDropdownClicked);
|
||||
|
||||
$('#run-button').on('click', goButtonClicked);
|
||||
|
||||
// Update Ketcher Width
|
||||
var fullWidth = $('#index-form-bar').width();
|
||||
$('#index-form-ketcher').width(fullWidth);
|
||||
|
||||
// add a listener that gets triggered whenever the structure in ketcher has changed
|
||||
$('#index-form-ketcher').on('load', function () {
|
||||
// Ketcher iframe load handler
|
||||
$('#index-ketcher').on('load', function() {
|
||||
const checkKetcherReady = () => {
|
||||
win = this.contentWindow
|
||||
const win = this.contentWindow;
|
||||
if (win.ketcher && 'editor' in win.ketcher) {
|
||||
window.indexKetcher = win.ketcher;
|
||||
win.ketcher.editor.event.change.handlers.push({
|
||||
once: false,
|
||||
priority: 0,
|
||||
f: ketcherToTextInput,
|
||||
f: indexKetcherToTextInput,
|
||||
ketcher: win.ketcher
|
||||
});
|
||||
} else {
|
||||
setTimeout(checkKetcherReady, 100);
|
||||
}
|
||||
};
|
||||
|
||||
checkKetcherReady();
|
||||
});
|
||||
|
||||
// Handle example link clicks
|
||||
$('.example-link').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
const smiles = $(this).data('smiles');
|
||||
const title = $(this).attr('title');
|
||||
|
||||
// Check if we're in Ketcher mode or text input mode
|
||||
if ($('input[type="checkbox"]').is(':checked')) {
|
||||
// In Ketcher mode - set the SMILES in Ketcher
|
||||
if (window.indexKetcher && window.indexKetcher.setMolecule) {
|
||||
window.indexKetcher.setMolecule(smiles);
|
||||
}
|
||||
} else {
|
||||
// In text input mode - set the SMILES in the text input
|
||||
$('#index-form-text-input').val(smiles);
|
||||
}
|
||||
|
||||
// Show a brief feedback
|
||||
const originalText = $(this).text();
|
||||
$(this).text(`loaded!`);
|
||||
setTimeout(() => {
|
||||
$(this).text(originalText);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
// Handle form submission on Enter
|
||||
$('#index-form').on("submit", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var textSmiles = '';
|
||||
|
||||
// Check if we're in Ketcher mode and extract SMILES
|
||||
if ($('input[type="checkbox"]').is(':checked') && window.indexKetcher) {
|
||||
textSmiles = window.indexKetcher.getSmiles().trim();
|
||||
} else {
|
||||
textSmiles = $('#index-form-text-input').val().trim();
|
||||
}
|
||||
|
||||
if (textSmiles === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$('#index-form-smiles').val(textSmiles);
|
||||
$("#index-form").attr("action", currentPackage + "/pathway");
|
||||
$("#index-form").attr("method", 'POST');
|
||||
this.submit();
|
||||
});
|
||||
|
||||
// Discourse topics are now loaded automatically by discourse-api.js
|
||||
});
|
||||
</script>
|
||||
{% endblock content %}
|
||||
{% endblock main_content %}
|
||||
|
||||
Reference in New Issue
Block a user