[Feature] Modern UI roll out (#236)

This PR moves all the collection pages into the new UI in a rough push.
I did not put the same amount of care into these as into search, index, and predict.

## Major changes

- All modals are now migrated to a state based alpine.js implementation.
- jQuery is no longer present in the base layout; ajax is replace by native fetch api
- most of the pps.js is now obsolte (as I understand it; the code is not referenced any more @jebus  please double check)
- in-memory pagination for large result lists (set to 50; we can make that configurable later; performance degrades at around 1k) stukk a bit rough tracked in #235

## Minor things

- Sarch and index also use alpine now
- The loading spinner is now CSS animated (not sure if it currently gets correctly called)

## Not done

- Ihave not even cheked the admin pages. Not sure If these need migrations
- The temporary migration pages still use the old template. Not sure what is supposed to happen with those? @jebus

## What I did to test

- opend all pages in browse, and user ; plus all pages reachable from there.
- Interacted and tested the functionality of each modal superfically with exception of the API key modal (no functional test).

---
This PR is massive sorry for that; just did not want to push half-brokenn state.
@jebus @liambrydon I would be glad if you could click around and try to break it :)

Finally closes #133

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#236
Co-authored-by: Tobias O <tobias.olenyi@envipath.com>
Co-committed-by: Tobias O <tobias.olenyi@envipath.com>
This commit is contained in:
2025-11-26 23:16:44 +13:00
committed by jebus
parent 7f6f209b4a
commit 1a2c9bb543
110 changed files with 10784 additions and 9465 deletions

View File

@ -158,11 +158,12 @@
}
function predictKetcherToTextInput() {
$("#predict-smiles").val(this.ketcher.getSmiles());
document.getElementById("predict-smiles").value = this.ketcher.getSmiles();
}
$(function () {
$("#predict-ketcher").on("load", function () {
document.addEventListener("DOMContentLoaded", function () {
const predictKetcher = document.getElementById("predict-ketcher");
predictKetcher.addEventListener("load", function () {
const checkKetcherReady = () => {
const win = this.contentWindow;
if (win.ketcher && "editor" in win.ketcher) {
@ -181,14 +182,16 @@
checkKetcherReady();
});
$("#predict-submit-button").on("click", function (e) {
const submitButton = document.getElementById("predict-submit-button");
submitButton.addEventListener("click", function (e) {
e.preventDefault();
const button = $(this);
button.prop("disabled", true);
button.text("Predicting...");
const button = this;
button.disabled = true;
button.textContent = "Predicting...";
// Get SMILES from either input or Ketcher
let smiles = $("#predict-smiles").val().trim();
const smilesInput = document.getElementById("predict-smiles");
let smiles = smilesInput.value.trim();
// If SMILES input is empty, try to get from Ketcher
if (!smiles) {
@ -197,13 +200,13 @@
try {
smiles = ketcher.getSmiles().trim();
if (smiles) {
$("#predict-smiles").val(smiles);
smilesInput.value = smiles;
}
} catch (err) {
console.error("Failed to get SMILES from Ketcher:", err);
alert("Unable to extract structure from the drawing editor. Please enter a SMILES string instead.");
button.prop("disabled", false);
button.text("Predict");
button.disabled = false;
button.textContent = "Predict";
return;
}
}
@ -212,13 +215,13 @@
// Basic validation
if (!smiles) {
alert("Please enter a SMILES string or draw a structure.");
button.prop("disabled", false);
button.text("Predict");
button.disabled = false;
button.textContent = "Predict";
return;
}
// Submit form
$("#predict_form").submit();
document.getElementById("predict_form").submit();
});
});
</script>