Attempt at javascript.
This commit is contained in:
@@ -1207,7 +1207,7 @@ class ProcedureType(BaseClass):
|
|||||||
# NOTE: An overly complicated list comprehension create a list of sample locations
|
# NOTE: An overly complicated list comprehension create a list of sample locations
|
||||||
# NOTE: next will return a blank cell if no value found for row/column
|
# NOTE: next will return a blank cell if no value found for row/column
|
||||||
env = jinja_template_loading()
|
env = jinja_template_loading()
|
||||||
template = env.get_template("plate_map.html")
|
template = env.get_template("support/plate_map.html")
|
||||||
html = template.render(plate_rows=self.plate_rows, plate_columns=self.plate_columns, samples=sample_dicts, vw=vw)
|
html = template.render(plate_rows=self.plate_rows, plate_columns=self.plate_columns, samples=sample_dicts, vw=vw)
|
||||||
return html + "<br/>"
|
return html + "<br/>"
|
||||||
|
|
||||||
|
|||||||
@@ -682,7 +682,7 @@ class Run(BaseClass, LogMixin):
|
|||||||
for row in rows
|
for row in rows
|
||||||
for column in columns]
|
for column in columns]
|
||||||
env = jinja_template_loading()
|
env = jinja_template_loading()
|
||||||
template = env.get_template("plate_map.html")
|
template = env.get_template("support/plate_map.html")
|
||||||
html = template.render(samples=output_samples, PLATE_ROWS=plate_rows, PLATE_COLUMNS=plate_columns)
|
html = template.render(samples=output_samples, PLATE_ROWS=plate_rows, PLATE_COLUMNS=plate_columns)
|
||||||
return html + "<br/>"
|
return html + "<br/>"
|
||||||
|
|
||||||
@@ -1626,7 +1626,7 @@ class ClientSubmissionSampleAssociation(BaseClass):
|
|||||||
# NOTE: Since there is no PCR, negliable result is necessary.
|
# NOTE: Since there is no PCR, negliable result is necessary.
|
||||||
sample = self.to_sub_dict()
|
sample = self.to_sub_dict()
|
||||||
env = jinja_template_loading()
|
env = jinja_template_loading()
|
||||||
template = env.get_template("tooltip.html")
|
template = env.get_template("support/tooltip.html")
|
||||||
tooltip_text = template.render(fields=sample)
|
tooltip_text = template.render(fields=sample)
|
||||||
try:
|
try:
|
||||||
control = self.sample.control
|
control = self.sample.control
|
||||||
@@ -1880,7 +1880,7 @@ class RunSampleAssociation(BaseClass):
|
|||||||
# NOTE: Since there is no PCR, negliable result is necessary.
|
# NOTE: Since there is no PCR, negliable result is necessary.
|
||||||
sample = self.to_sub_dict()
|
sample = self.to_sub_dict()
|
||||||
env = jinja_template_loading()
|
env = jinja_template_loading()
|
||||||
template = env.get_template("tooltip.html")
|
template = env.get_template("support/tooltip.html")
|
||||||
tooltip_text = template.render(fields=sample)
|
tooltip_text = template.render(fields=sample)
|
||||||
try:
|
try:
|
||||||
control = self.sample.control
|
control = self.sample.control
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
import sys, logging
|
import sys, logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
@@ -15,7 +17,7 @@ from typing import TYPE_CHECKING, Any
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from backend.db.models import Run, ProcedureType
|
from backend.db.models import Run, ProcedureType
|
||||||
from tools import jinja_template_loading, get_application_from_parent
|
from tools import jinja_template_loading, get_application_from_parent, render_details_template
|
||||||
from backend.validators import PydProcedure
|
from backend.validators import PydProcedure
|
||||||
|
|
||||||
logger = logging.getLogger(f"submissions.{__name__}")
|
logger = logging.getLogger(f"submissions.{__name__}")
|
||||||
@@ -54,13 +56,15 @@ class ProcedureCreation(QDialog):
|
|||||||
self.webview.page().setWebChannel(self.channel)
|
self.webview.page().setWebChannel(self.channel)
|
||||||
|
|
||||||
def set_html(self):
|
def set_html(self):
|
||||||
env = jinja_template_loading()
|
html = render_details_template(
|
||||||
template = env.get_template("procedure_creation.html")
|
template_name="procedure_creation",
|
||||||
template_path = Path(template.environment.loader.__getattribute__("searchpath")[0])
|
# css_in=['new_context_menu'],
|
||||||
with open(template_path.joinpath("css", "styles.css"), "r") as f:
|
js_in=["procedure_form", "grid_drag", "context_menu"],
|
||||||
css = f.read()
|
proceduretype=self.proceduretype.as_dict,
|
||||||
html = template.render(proceduretype=self.proceduretype.as_dict, run=self.run.to_dict(),
|
run=self.run.to_dict(),
|
||||||
procedure=self.created_procedure.__dict__, plate_map=self.plate_map, css=css)
|
procedure=self.created_procedure.__dict__,
|
||||||
|
plate_map=self.plate_map
|
||||||
|
)
|
||||||
with open("procedure.html", "w") as f:
|
with open("procedure.html", "w") as f:
|
||||||
f.write(html)
|
f.write(html)
|
||||||
self.webview.setHtml(html)
|
self.webview.setHtml(html)
|
||||||
@@ -86,21 +90,9 @@ class ProcedureCreation(QDialog):
|
|||||||
def rearrange_plate(self, sample_list: list):
|
def rearrange_plate(self, sample_list: list):
|
||||||
self.created_procedure.update_samples(sample_list=sample_list)
|
self.created_procedure.update_samples(sample_list=sample_list)
|
||||||
|
|
||||||
@pyqtSlot(str, str)
|
@pyqtSlot(str)
|
||||||
def log_drag(self, source_well: str, destination_well: str):
|
def log(self, logtext: str):
|
||||||
logger.debug(f"Source Index: {source_well} Destination Index: {destination_well}")
|
logger.debug(logtext)
|
||||||
# source_well = source_well.split("-")
|
|
||||||
# destination_well = destination_well.split("-")
|
|
||||||
# source_row = int(source_well[0])
|
|
||||||
# source_column = int(source_well[1])
|
|
||||||
# destination_row = int(destination_well[0])
|
|
||||||
# destination_column = int(destination_well[1])
|
|
||||||
# self.created_procedure.shuffle_samples(
|
|
||||||
# source_row=source_row,
|
|
||||||
# source_column=source_column,
|
|
||||||
# destination_row=destination_row,
|
|
||||||
# destination_column=destination_column
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
# class ProcedureWebViewer(QWebEngineView):
|
# class ProcedureWebViewer(QWebEngineView):
|
||||||
|
|||||||
@@ -115,6 +115,9 @@ div.gallery {
|
|||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
background-color: rgba(229, 231, 228, 0.7);
|
||||||
|
border-radius: 2px;
|
||||||
|
border-color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.context-menu--active {
|
.context-menu--active {
|
||||||
|
|||||||
@@ -5,7 +5,10 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
{% if css %}
|
{% if css %}
|
||||||
<style>
|
<style>
|
||||||
{{ css }}
|
{% for c in css %}
|
||||||
|
{{ c }}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
</style>
|
</style>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
|
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
|
||||||
@@ -18,12 +21,12 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block signing_button %}{% endblock %}
|
{% block signing_button %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
<script>
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
var backend;
|
{% for j in js%}
|
||||||
new QWebChannel(qt.webChannelTransport, function (channel) {
|
<script>
|
||||||
backend = channel.objects.backend;
|
{{ j }}
|
||||||
});
|
|
||||||
{% endblock %}
|
|
||||||
</script>
|
</script>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
</html>
|
</html>
|
||||||
260
src/submissions/templates/js/context_menu.js
Normal file
260
src/submissions/templates/js/context_menu.js
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
//function openMulti() {
|
||||||
|
// if (document.querySelector(".selectWrapper").style.pointerEvents == "all") {
|
||||||
|
// document.querySelector(".selectWrapper").style.opacity = 0;
|
||||||
|
// document.querySelector(".selectWrapper").style.pointerEvents = "none";
|
||||||
|
// resetAllMenus();
|
||||||
|
// } else {
|
||||||
|
// document.querySelector(".selectWrapper").style.opacity = 1;
|
||||||
|
// document.querySelector(".selectWrapper").style.pointerEvents = "all";
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//function nextMenu(e) {
|
||||||
|
// menuIndex = eval(event.target.parentNode.id.slice(-1));
|
||||||
|
// document.querySelectorAll(".multiSelect")[menuIndex].style.transform =
|
||||||
|
// "translateX(-100%)";
|
||||||
|
// // document.querySelectorAll(".multiSelect")[menuIndex].style.clipPath = "polygon(0 0, 0 0, 0 100%, 0% 100%)";
|
||||||
|
// document.querySelectorAll(".multiSelect")[menuIndex].style.clipPath =
|
||||||
|
// "polygon(100% 0, 100% 0, 100% 100%, 100% 100%)";
|
||||||
|
// document.querySelectorAll(".multiSelect")[menuIndex + 1].style.transform =
|
||||||
|
// "translateX(0)";
|
||||||
|
// document.querySelectorAll(".multiSelect")[menuIndex + 1].style.clipPath =
|
||||||
|
// "polygon(0 0, 100% 0, 100% 100%, 0% 100%)";
|
||||||
|
//}
|
||||||
|
//function prevMenu(e) {
|
||||||
|
// menuIndex = eval(event.target.parentNode.id.slice(-1));
|
||||||
|
// document.querySelectorAll(".multiSelect")[menuIndex].style.transform =
|
||||||
|
// "translateX(100%)";
|
||||||
|
// document.querySelectorAll(".multiSelect")[menuIndex].style.clipPath =
|
||||||
|
// "polygon(0 0, 0 0, 0 100%, 0% 100%)";
|
||||||
|
// document.querySelectorAll(".multiSelect")[menuIndex - 1].style.transform =
|
||||||
|
// "translateX(0)";
|
||||||
|
// document.querySelectorAll(".multiSelect")[menuIndex - 1].style.clipPath =
|
||||||
|
// "polygon(0 0, 100% 0, 100% 100%, 0% 100%)";
|
||||||
|
//}
|
||||||
|
//function resetAllMenus() {
|
||||||
|
// setTimeout(function () {
|
||||||
|
// var x = document.getElementsByClassName("multiSelect");
|
||||||
|
// var i;
|
||||||
|
// for (i = 1; i < x.length; i++) {
|
||||||
|
// x[i].style.transform = "translateX(100%)";
|
||||||
|
// x[i].style.clipPath = "polygon(0 0, 0 0, 0 100%, 0% 100%)";
|
||||||
|
// }
|
||||||
|
// document.querySelectorAll(".multiSelect")[0].style.transform =
|
||||||
|
// "translateX(0)";
|
||||||
|
// document.querySelectorAll(".multiSelect")[0].style.clipPath =
|
||||||
|
// "polygon(0 0, 100% 0, 100% 100%, 0% 100%)";
|
||||||
|
// }, 300);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
///////////////////////////////////////
|
||||||
|
//
|
||||||
|
// H E L P E R F U N C T I O N S
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
function clickInsideElement( e, className ) {
|
||||||
|
var el = e.srcElement || e.target;
|
||||||
|
if ( el.classList.contains(className) ) {
|
||||||
|
return el;
|
||||||
|
} else {
|
||||||
|
while ( el = el.parentNode ) {
|
||||||
|
if ( el.classList && el.classList.contains(className) ) {
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPosition(e) {
|
||||||
|
var posx = 0;
|
||||||
|
var posy = 0;
|
||||||
|
if (!e) var e = window.event;
|
||||||
|
if (e.pageX || e.pageY) {
|
||||||
|
posx = e.pageX;
|
||||||
|
posy = e.pageY;
|
||||||
|
} else if (e.clientX || e.clientY) {
|
||||||
|
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
|
||||||
|
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
x: posx,
|
||||||
|
y: posy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// updated positionMenu function
|
||||||
|
function positionMenu(e) {
|
||||||
|
clickCoords = getPosition(e);
|
||||||
|
clickCoordsX = clickCoords.x;
|
||||||
|
clickCoordsY = clickCoords.y;
|
||||||
|
menuWidth = menu.offsetWidth + 4;
|
||||||
|
menuHeight = menu.offsetHeight + 4;
|
||||||
|
windowWidth = window.innerWidth;
|
||||||
|
windowHeight = window.innerHeight;
|
||||||
|
if ( (windowWidth - clickCoordsX) < menuWidth ) {
|
||||||
|
menu.style.left = windowWidth - menuWidth + "px";
|
||||||
|
} else {
|
||||||
|
menu.style.left = clickCoordsX + "px";
|
||||||
|
}
|
||||||
|
if ( (windowHeight - clickCoordsY) < menuHeight ) {
|
||||||
|
menu.style.top = windowHeight - menuHeight + "px";
|
||||||
|
} else {
|
||||||
|
menu.style.top = clickCoordsY + "px";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function menuItemListener( link ) {
|
||||||
|
const contextIndex = [...gridContainer.children].indexOf(taskItemInContext);
|
||||||
|
const task_id = taskItemInContext.getAttribute("id")
|
||||||
|
backend.log("Task action - " + link.getAttribute("data-action"))
|
||||||
|
switch (link.getAttribute("data-action")) {
|
||||||
|
case "InsertSample":
|
||||||
|
insertSample(contextIndex, task_id);
|
||||||
|
break;
|
||||||
|
case "InsertControl":
|
||||||
|
insertControl(contextIndex);
|
||||||
|
break;
|
||||||
|
case "RemoveSample":
|
||||||
|
removeSample(contextIndex);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
backend.log("default");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
toggleMenuOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
///////////////////////////////////////
|
||||||
|
//
|
||||||
|
// C O R E F U N C T I O N S
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
///////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Variables.
|
||||||
|
*/
|
||||||
|
var contextMenuClassName = "context-menu";
|
||||||
|
var contextMenuItemClassName = "context-menu__item";
|
||||||
|
var contextMenuLinkClassName = "context-menu__link";
|
||||||
|
var contextMenuActive = "context-menu--active";
|
||||||
|
var taskItemClassName = "well";
|
||||||
|
var taskItemInContext;
|
||||||
|
var clickCoords;
|
||||||
|
var clickCoordsX;
|
||||||
|
var clickCoordsY;
|
||||||
|
var menu = document.getElementById(contextMenuClassName);
|
||||||
|
var menuItems = menu.getElementsByClassName(contextMenuItemClassName);
|
||||||
|
var menuHeader = document.getElementById("menu-header");
|
||||||
|
var menuState = 0;
|
||||||
|
var menuWidth;
|
||||||
|
var menuHeight;
|
||||||
|
var menuPosition;
|
||||||
|
var menuPositionX;
|
||||||
|
var menuPositionY;
|
||||||
|
var windowWidth;
|
||||||
|
var windowHeight;
|
||||||
|
/**
|
||||||
|
* Initialise our application's code.
|
||||||
|
*/
|
||||||
|
function init() {
|
||||||
|
contextListener();
|
||||||
|
clickListener();
|
||||||
|
keyupListener();
|
||||||
|
resizeListener();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Listens for contextmenu events.
|
||||||
|
*/
|
||||||
|
function contextListener() {
|
||||||
|
document.addEventListener( "contextmenu", function(e) {
|
||||||
|
taskItemInContext = clickInsideElement( e, taskItemClassName );
|
||||||
|
if ( taskItemInContext ) {
|
||||||
|
e.preventDefault();
|
||||||
|
menuHeader.innerText = taskItemInContext.id;
|
||||||
|
toggleMenuOn();
|
||||||
|
positionMenu(e);
|
||||||
|
} else {
|
||||||
|
taskItemInContext = null;
|
||||||
|
menuHeader.text = "";
|
||||||
|
toggleMenuOff();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for click events.
|
||||||
|
*/
|
||||||
|
function clickListener() {
|
||||||
|
document.addEventListener( "click", function(e) {
|
||||||
|
var clickeElIsLink = clickInsideElement( e, contextMenuLinkClassName );
|
||||||
|
if ( clickeElIsLink ) {
|
||||||
|
e.preventDefault();
|
||||||
|
menuItemListener( clickeElIsLink );
|
||||||
|
} else {
|
||||||
|
var button = e.which || e.button;
|
||||||
|
if ( button === 1 ) {
|
||||||
|
toggleMenuOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Listens for keyup events.
|
||||||
|
*/
|
||||||
|
function keyupListener() {
|
||||||
|
window.onkeyup = function(e) {
|
||||||
|
if ( e.keyCode === 27 ) {
|
||||||
|
toggleMenuOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Turns the custom context menu on.
|
||||||
|
*/
|
||||||
|
function toggleMenuOn() {
|
||||||
|
if ( menuState !== 1 ) {
|
||||||
|
menuState = 1;
|
||||||
|
menu.classList.add(contextMenuActive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function toggleMenuOff() {
|
||||||
|
if ( menuState !== 0 ) {
|
||||||
|
menuState = 0;
|
||||||
|
menu.classList.remove(contextMenuActive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
///////////////////////////////////////
|
||||||
|
//
|
||||||
|
// B A C K E N D F U N C T I O N S
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
function insertSample( index ) {
|
||||||
|
backend.log( "Index - " + index + ", InsertSample");
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertControl( index ) {
|
||||||
|
backend.log( "Index - " + index + ", InsertEN");
|
||||||
|
var existing_ens = document.getElementsByClassName("EN");
|
||||||
|
backend.log(existing_ens.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeSample( index ) {
|
||||||
|
backend.log( "Index - " + index + ", RemoveSample");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the app.
|
||||||
|
*/
|
||||||
|
init();
|
||||||
|
|
||||||
|
|
||||||
4
src/submissions/templates/js/details.js
Normal file
4
src/submissions/templates/js/details.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var backend;
|
||||||
|
new QWebChannel(qt.webChannelTransport, function (channel) {
|
||||||
|
backend = channel.objects.backend;
|
||||||
|
});
|
||||||
51
src/submissions/templates/js/grid_drag.js
Normal file
51
src/submissions/templates/js/grid_drag.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
|
||||||
|
|
||||||
|
const gridContainer = document.getElementById("plate-container");
|
||||||
|
let draggedItem = null;
|
||||||
|
|
||||||
|
//Handle Drag start
|
||||||
|
gridContainer.addEventListener("dragstart", (e) => {
|
||||||
|
draggedItem = e.target;
|
||||||
|
draggedItem.style.opacity = "0.5";
|
||||||
|
});
|
||||||
|
|
||||||
|
//Handle Drag End
|
||||||
|
gridContainer.addEventListener("dragend", (e) => {
|
||||||
|
e.target.style.opacity = "1";
|
||||||
|
draggedItem = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
//handle dragging ove grid items
|
||||||
|
gridContainer.addEventListener("dragover", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
//Handle Drop
|
||||||
|
gridContainer.addEventListener("drop", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const targetItem = e.target;
|
||||||
|
if (
|
||||||
|
targetItem &&
|
||||||
|
targetItem !== draggedItem &&
|
||||||
|
targetItem.classList.contains("well")
|
||||||
|
) {
|
||||||
|
const draggedIndex = [...gridContainer.children].indexOf(draggedItem);
|
||||||
|
const targetIndex = [...gridContainer.children].indexOf(targetItem);
|
||||||
|
if (draggedIndex < targetIndex) {
|
||||||
|
backend.log_drag(draggedIndex.toString(), targetIndex.toString() + " Lesser");
|
||||||
|
gridContainer.insertBefore(draggedItem, targetItem.nextSibling);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
backend.log_drag(draggedIndex.toString(), targetIndex.toString() + " Greater");
|
||||||
|
gridContainer.insertBefore(draggedItem, targetItem);
|
||||||
|
|
||||||
|
}
|
||||||
|
output = [];
|
||||||
|
fullGrid = [...gridContainer.children];
|
||||||
|
fullGrid.forEach(function(item, index) {
|
||||||
|
output.push({sample_id: item.id, index: index + 1})
|
||||||
|
});
|
||||||
|
backend.rearrange_plate(output);
|
||||||
|
}
|
||||||
|
});
|
||||||
19
src/submissions/templates/js/procedure_form.js
Normal file
19
src/submissions/templates/js/procedure_form.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
document.getElementById("kittype").addEventListener("change", function() {
|
||||||
|
backend.update_kit(this.value);
|
||||||
|
})
|
||||||
|
|
||||||
|
var formchecks = document.getElementsByClassName('form_check');
|
||||||
|
|
||||||
|
for(let i = 0; i < formchecks.length; i++) {
|
||||||
|
formchecks[i].addEventListener("change", function() {
|
||||||
|
backend.check_toggle(formchecks[i].id, formchecks[i].checked);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
var formtexts = document.getElementsByClassName('form_text');
|
||||||
|
|
||||||
|
for(let i = 0; i < formtexts.length; i++) {
|
||||||
|
formtexts[i].addEventListener("input", function() {
|
||||||
|
backend.text_changed(formtexts[i].id, formtexts[i].value);
|
||||||
|
})
|
||||||
|
};
|
||||||
@@ -44,114 +44,15 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% include 'support/context_menu.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<nav class="context-menu">
|
|
||||||
<ul class="context-menu__items">
|
|
||||||
<li class="context-menu__item">
|
|
||||||
<a href="#" class="context-menu__link">
|
|
||||||
<i class="fa fa-eye"></i> View Task
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="context-menu__item">
|
|
||||||
<a href="#" class="context-menu__link">
|
|
||||||
<i class="fa fa-edit"></i> Edit Task
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="context-menu__item">
|
|
||||||
<a href="#" class="context-menu__link">
|
|
||||||
<i class="fa fa-times"></i> Delete Task
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</body>
|
</body>
|
||||||
<script>
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
|
|
||||||
document.getElementById("kittype").addEventListener("change", function() {
|
|
||||||
backend.update_kit(this.value);
|
|
||||||
})
|
|
||||||
|
|
||||||
var formchecks = document.getElementsByClassName('form_check');
|
|
||||||
|
|
||||||
for(let i = 0; i < formchecks.length; i++) {
|
|
||||||
formchecks[i].addEventListener("change", function() {
|
|
||||||
backend.check_toggle(formchecks[i].id, formchecks[i].checked);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
var formtexts = document.getElementsByClassName('form_text');
|
|
||||||
|
|
||||||
for(let i = 0; i < formtexts.length; i++) {
|
|
||||||
formtexts[i].addEventListener("input", function() {
|
|
||||||
backend.text_changed(formtexts[i].id, formtexts[i].value);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
const gridContainer = document.getElementById("plate-container");
|
|
||||||
let draggedItem = null;
|
|
||||||
|
|
||||||
//Handle Drag start
|
|
||||||
gridContainer.addEventListener("dragstart", (e) => {
|
|
||||||
draggedItem = e.target;
|
|
||||||
draggedItem.style.opacity = "0.5";
|
|
||||||
});
|
|
||||||
|
|
||||||
//Handle Drag End
|
|
||||||
gridContainer.addEventListener("dragend", (e) => {
|
|
||||||
e.target.style.opacity = "1";
|
|
||||||
draggedItem = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
//handle dragging ove grid items
|
|
||||||
gridContainer.addEventListener("dragover", (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
//Handle Drop
|
|
||||||
gridContainer.addEventListener("drop", (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const targetItem = e.target;
|
|
||||||
if (
|
|
||||||
targetItem &&
|
|
||||||
targetItem !== draggedItem &&
|
|
||||||
targetItem.classList.contains("well")
|
|
||||||
) {
|
|
||||||
const draggedIndex = [...gridContainer.children].indexOf(draggedItem);
|
|
||||||
const targetIndex = [...gridContainer.children].indexOf(targetItem);
|
|
||||||
if (draggedIndex < targetIndex) {
|
|
||||||
backend.log_drag(draggedIndex.toString(), targetIndex.toString() + " Lesser");
|
|
||||||
gridContainer.insertBefore(draggedItem, targetItem.nextSibling);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
backend.log_drag(draggedIndex.toString(), targetIndex.toString() + " Greater");
|
|
||||||
gridContainer.insertBefore(draggedItem, targetItem);
|
|
||||||
|
|
||||||
}
|
|
||||||
output = [];
|
|
||||||
fullGrid = [...gridContainer.children];
|
|
||||||
fullGrid.forEach(function(item, index) {
|
|
||||||
output.push({sample_id: item.id, index: index + 1})
|
|
||||||
});
|
|
||||||
backend.rearrange_plate(output);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Context Menu Functionality
|
|
||||||
var wells = document.querySelectorAll(".well");
|
|
||||||
for ( var i = 0, len = wells.length; i < len; i++ ) {
|
|
||||||
var welloi = wells[i];
|
|
||||||
|
|
||||||
welloi.addEventListener( "contextmenu", function(e) {
|
|
||||||
well = e.target
|
|
||||||
backend.log_drag(well.id, "el");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
20
src/submissions/templates/support/context_menu.html
Normal file
20
src/submissions/templates/support/context_menu.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<nav class="context-menu" id="context-menu">
|
||||||
|
<h4 id="menu-header"></h4>
|
||||||
|
<ul class="context-menu__items">
|
||||||
|
<li class="context-menu__item">
|
||||||
|
<a href="#" class="context-menu__link" data-action="InsertSample">
|
||||||
|
<i class="fa fa-eye"></i> Insert Sample
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="context-menu__item">
|
||||||
|
<a href="#" class="context-menu__link" data-action="InsertControl">
|
||||||
|
<i class="fa fa-edit"></i> Insert EN
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="context-menu__item">
|
||||||
|
<a href="#" class="context-menu__link" data-action="RemoveSample">
|
||||||
|
<i class="fa fa-times"></i> Remove Sample
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
@@ -443,6 +443,30 @@ def jinja_template_loading() -> Environment:
|
|||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
||||||
|
def render_details_template(template_name:str, css_in:List[str]|str=[], js_in:List[str]|str=[], **kwargs) -> str:
|
||||||
|
if isinstance(css_in, str):
|
||||||
|
css_in = [css_in]
|
||||||
|
css_in = ["styles"] + css_in
|
||||||
|
css_in = [project_path.joinpath("src", "submissions", "templates", "css", f"{c}.css") for c in css_in]
|
||||||
|
if isinstance(js_in, str):
|
||||||
|
js_in = [js_in]
|
||||||
|
js_in = ["details"] + js_in
|
||||||
|
js_in = [project_path.joinpath("src", "submissions", "templates", "js", f"{j}.js") for j in js_in]
|
||||||
|
env = jinja_template_loading()
|
||||||
|
template = env.get_template(f"{template_name}.html")
|
||||||
|
# template_path = Path(template.environment.loader.__getattribute__("searchpath")[0])
|
||||||
|
css_out = []
|
||||||
|
for css in css_in:
|
||||||
|
with open(css, "r") as f:
|
||||||
|
css_out.append(f.read())
|
||||||
|
js_out = []
|
||||||
|
for js in js_in:
|
||||||
|
with open(js, "r") as f:
|
||||||
|
js_out.append(f.read())
|
||||||
|
return template.render(css=css_out, js=js_out, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def convert_well_to_row_column(input_str: str) -> Tuple[int, int]:
|
def convert_well_to_row_column(input_str: str) -> Tuple[int, int]:
|
||||||
"""
|
"""
|
||||||
Converts typical alphanumeric (i.e. "A2") to row, column
|
Converts typical alphanumeric (i.e. "A2") to row, column
|
||||||
|
|||||||
Reference in New Issue
Block a user