Update of Reagent usage ui
This commit is contained in:
@@ -1450,7 +1450,7 @@ class Procedure(BaseClass):
|
||||
def edit(self, obj):
|
||||
from frontend.widgets.procedure_creation import ProcedureCreation
|
||||
logger.debug("Edit!")
|
||||
dlg = ProcedureCreation(parent=obj, procedure=self.to_pydantic())
|
||||
dlg = ProcedureCreation(parent=obj, procedure=self.to_pydantic(), edit=True)
|
||||
if dlg.exec():
|
||||
logger.debug("Edited")
|
||||
|
||||
|
||||
@@ -1486,10 +1486,11 @@ class PydProcedure(PydBaseClass, arbitrary_types_allowed=True):
|
||||
if isinstance(kittype, str):
|
||||
kittype_obj = KitType.query(name=kittype)
|
||||
try:
|
||||
self.reagentrole = {item.name: item.get_reagents(kittype=kittype_obj) for item in
|
||||
self.reagentrole = {item.name: item.get_reagents(kittype=kittype_obj) + ["New"] for item in
|
||||
kittype_obj.get_reagents(proceduretype=self.proceduretype)}
|
||||
except AttributeError:
|
||||
self.reagentrole = {}
|
||||
|
||||
self.kittype['value'] = kittype
|
||||
self.possible_kits.insert(0, self.possible_kits.pop(self.possible_kits.index(kittype)))
|
||||
|
||||
|
||||
129
src/submissions/frontend/widgets/equipment_usage_2.py
Normal file
129
src/submissions/frontend/widgets/equipment_usage_2.py
Normal file
@@ -0,0 +1,129 @@
|
||||
'''
|
||||
Creates forms that the user can enter equipment info into.
|
||||
'''
|
||||
from pprint import pformat
|
||||
from PyQt6.QtCore import Qt, QSignalBlocker, pyqtSlot
|
||||
from PyQt6.QtWebChannel import QWebChannel
|
||||
from PyQt6.QtWebEngineWidgets import QWebEngineView
|
||||
from PyQt6.QtWidgets import (
|
||||
QDialog, QComboBox, QCheckBox, QLabel, QWidget, QVBoxLayout, QDialogButtonBox, QGridLayout
|
||||
)
|
||||
from backend.db.models import Equipment, Run, Process, Procedure, Tips
|
||||
from backend.validators.pydant import PydEquipment, PydEquipmentRole, PydTips, PydProcedure
|
||||
import logging
|
||||
from typing import Generator
|
||||
|
||||
from tools import get_application_from_parent, render_details_template, flatten_list
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
class EquipmentUsage(QDialog):
|
||||
|
||||
def __init__(self, parent, procedure: PydProcedure):
|
||||
super().__init__(parent)
|
||||
self.procedure = procedure
|
||||
self.setWindowTitle(f"Equipment Checklist - {procedure.name}")
|
||||
self.used_equipment = self.procedure.equipment
|
||||
self.kit = self.procedure.kittype
|
||||
self.opt_equipment = procedure.proceduretype.get_equipment()
|
||||
self.layout = QVBoxLayout()
|
||||
self.app = get_application_from_parent(parent)
|
||||
self.webview = QWebEngineView(parent=self)
|
||||
self.webview.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu)
|
||||
self.webview.setMinimumSize(1200, 800)
|
||||
self.webview.setMaximumWidth(1200)
|
||||
# NOTE: Decide if exporting should be allowed.
|
||||
# self.webview.loadFinished.connect(self.activate_export)
|
||||
self.layout = QGridLayout()
|
||||
# NOTE: button to export a pdf version
|
||||
self.layout.addWidget(self.webview, 1, 0, 10, 10)
|
||||
self.setLayout(self.layout)
|
||||
self.setFixedWidth(self.webview.width() + 20)
|
||||
# NOTE: setup channel
|
||||
self.channel = QWebChannel()
|
||||
self.channel.registerObject('backend', self)
|
||||
html = self.construct_html(procedure=procedure)
|
||||
self.webview.setHtml(html)
|
||||
self.webview.page().setWebChannel(self.channel)
|
||||
QBtn = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||
self.buttonBox = QDialogButtonBox(QBtn)
|
||||
self.buttonBox.accepted.connect(self.accept)
|
||||
self.buttonBox.rejected.connect(self.reject)
|
||||
self.layout.addWidget(self.buttonBox, 11, 1, 1, 1)
|
||||
|
||||
@classmethod
|
||||
def construct_html(cls, procedure: PydProcedure, child: bool = False):
|
||||
proceduretype = procedure.proceduretype
|
||||
proceduretype_dict = proceduretype.details_dict()
|
||||
run = procedure.run
|
||||
proceduretype_dict['equipment_json'] = flatten_list([item['equipment_json'] for item in proceduretype_dict['equipment']])
|
||||
# proceduretype_dict['equipment_json'] = [
|
||||
# {'name': 'Liquid Handler', 'equipment': [
|
||||
# {'name': 'Other', 'asset_number': 'XXX', 'processes': [
|
||||
# {'name': 'Trust Me', 'tips': ['Blah']},
|
||||
# {'name': 'No Me', 'tips': ['Blah', 'Crane']}
|
||||
# ]
|
||||
# },
|
||||
# {'name': 'Biomek', 'asset_number': '5015530', 'processes': [
|
||||
# {'name': 'Sample Addition', 'tips': ['Axygen 20uL']
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
# ]
|
||||
# if procedure.equipment:
|
||||
# for equipmentrole in proceduretype_dict['equipment']:
|
||||
# # NOTE: Check if procedure equipment is present and move to head of the list if so.
|
||||
# try:
|
||||
# relevant_procedure_item = next((equipment for equipment in procedure.equipment if
|
||||
# equipment.equipmentrole == equipmentrole['name']))
|
||||
# except StopIteration:
|
||||
# continue
|
||||
# item_in_er_list = next((equipment for equipment in equipmentrole['equipment'] if
|
||||
# equipment['name'] == relevant_procedure_item.name))
|
||||
# equipmentrole['equipment'].insert(0, equipmentrole['equipment'].pop(
|
||||
# equipmentrole['equipment'].index(item_in_er_list)))
|
||||
html = render_details_template(
|
||||
template_name="support/equipment_usage",
|
||||
css_in=[],
|
||||
js_in=[],
|
||||
proceduretype=proceduretype_dict,
|
||||
run=run.details_dict(),
|
||||
procedure=procedure.__dict__,
|
||||
child=child
|
||||
)
|
||||
return html
|
||||
|
||||
@pyqtSlot(str, str, str, str)
|
||||
def update_equipment(self, equipmentrole: str, equipment: str, process: str, tips: str):
|
||||
try:
|
||||
equipment_of_interest = next(
|
||||
(item for item in self.procedure.equipment if item.equipmentrole == equipmentrole))
|
||||
except StopIteration:
|
||||
equipment_of_interest = None
|
||||
equipment = Equipment.query(name=equipment)
|
||||
if equipment_of_interest:
|
||||
eoi = self.procedure.equipment.pop(self.procedure.equipment.index(equipment_of_interest))
|
||||
else:
|
||||
eoi = equipment.to_pydantic(proceduretype=self.procedure.proceduretype)
|
||||
eoi.name = equipment.name
|
||||
eoi.asset_number = equipment.asset_number
|
||||
eoi.nickname = equipment.nickname
|
||||
process = next((prcss for prcss in equipment.process if prcss.name == process))
|
||||
eoi.process = process.to_pydantic()
|
||||
tips = next((tps for tps in equipment.tips if tps.name == tips))
|
||||
eoi.tips = tips.to_pydantic()
|
||||
self.procedure.equipment.append(eoi)
|
||||
logger.debug(f"Updated equipment: {self.procedure.equipment}")
|
||||
|
||||
def save_procedure(self):
|
||||
sql, _ = self.procedure.to_sql()
|
||||
logger.debug(pformat(sql.__dict__))
|
||||
# import pickle
|
||||
# with open("sql.pickle", "wb") as f:
|
||||
# pickle.dump(sql, f)
|
||||
# with open("pyd.pickle", "wb") as f:
|
||||
# pickle.dump(self.procedure, f)
|
||||
sql.save()
|
||||
@@ -14,23 +14,24 @@ from PyQt6.QtWebChannel import QWebChannel
|
||||
from PyQt6.QtWebEngineWidgets import QWebEngineView
|
||||
from PyQt6.QtWidgets import QDialog, QGridLayout, QMenu, QDialogButtonBox
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from backend.db.models import Run, Procedure
|
||||
from backend.validators import PydProcedure
|
||||
from tools import jinja_template_loading, get_application_from_parent, render_details_template
|
||||
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
class ProcedureCreation(QDialog):
|
||||
|
||||
def __init__(self, parent, procedure: PydProcedure):
|
||||
def __init__(self, parent, procedure: PydProcedure, edit: bool = False):
|
||||
super().__init__(parent)
|
||||
self.edit = edit
|
||||
self.run = procedure.run
|
||||
self.procedure = procedure
|
||||
self.proceduretype = procedure.proceduretype
|
||||
self.setWindowTitle(f"New {self.proceduretype.name} for { self.run.rsl_plate_number }")
|
||||
self.setWindowTitle(f"New {self.proceduretype.name} for {self.run.rsl_plate_number}")
|
||||
# self.created_procedure = self.proceduretype.construct_dummy_procedure(run=self.run)
|
||||
self.procedure.update_kittype_reagentroles(kittype=self.procedure.possible_kits[0])
|
||||
# self.created_procedure.samples = self.run.constuct_sample_dicts_for_proceduretype(proceduretype=self.proceduretype)
|
||||
@@ -63,16 +64,20 @@ class ProcedureCreation(QDialog):
|
||||
|
||||
def set_html(self):
|
||||
from .equipment_usage_2 import EquipmentUsage
|
||||
logger.debug(f"Edit: {self.edit}")
|
||||
proceduretype_dict = self.proceduretype.details_dict()
|
||||
if self.procedure.equipment:
|
||||
for equipmentrole in proceduretype_dict['equipment']:
|
||||
# NOTE: Check if procedure equipment is present and move to head of the list if so.
|
||||
try:
|
||||
relevant_procedure_item = next((equipment for equipment in self.procedure.equipment if equipment.equipmentrole == equipmentrole['name']))
|
||||
relevant_procedure_item = next((equipment for equipment in self.procedure.equipment if
|
||||
equipment.equipmentrole == equipmentrole['name']))
|
||||
except StopIteration:
|
||||
continue
|
||||
item_in_er_list = next((equipment for equipment in equipmentrole['equipment'] if equipment['name'] == relevant_procedure_item.name))
|
||||
equipmentrole['equipment'].insert(0, equipmentrole['equipment'].pop(equipmentrole['equipment'].index(item_in_er_list)))
|
||||
item_in_er_list = next((equipment for equipment in equipmentrole['equipment'] if
|
||||
equipment['name'] == relevant_procedure_item.name))
|
||||
equipmentrole['equipment'].insert(0, equipmentrole['equipment'].pop(
|
||||
equipmentrole['equipment'].index(item_in_er_list)))
|
||||
proceduretype_dict['equipment_section'] = EquipmentUsage.construct_html(procedure=self.procedure, child=True)
|
||||
html = render_details_template(
|
||||
template_name="procedure_creation",
|
||||
@@ -81,15 +86,22 @@ class ProcedureCreation(QDialog):
|
||||
proceduretype=proceduretype_dict,
|
||||
run=self.run.details_dict(),
|
||||
procedure=self.procedure.__dict__,
|
||||
plate_map=self.plate_map
|
||||
plate_map=self.plate_map,
|
||||
edit=self.edit
|
||||
)
|
||||
with open("web.html", "w") as f:
|
||||
f.write(html)
|
||||
self.webview.setHtml(html)
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
def text_changed(self, key: str, new_value: str):
|
||||
logger.debug(f"New value for {key}: {new_value}")
|
||||
attribute = getattr(self.procedure, key)
|
||||
attribute['value'] = new_value.strip('\"')
|
||||
match key:
|
||||
case "rsl_plate_num":
|
||||
setattr(self.procedure.run, key, new_value)
|
||||
case _:
|
||||
attribute = getattr(self.procedure, key)
|
||||
attribute['value'] = new_value.strip('\"')
|
||||
|
||||
@pyqtSlot(str, bool)
|
||||
def check_toggle(self, key: str, ischecked: bool):
|
||||
@@ -113,16 +125,15 @@ class ProcedureCreation(QDialog):
|
||||
def return_sql(self):
|
||||
return self.procedure.to_sql()
|
||||
|
||||
|
||||
# class ProcedureWebViewer(QWebEngineView):
|
||||
#
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# super().__init__(*args, **kwargs)
|
||||
#
|
||||
# def contextMenuEvent(self, event: QContextMenuEvent):
|
||||
# self.menu = self.page().createStandardContextMenu()
|
||||
# self.menu = self.createStandardContextMenu()
|
||||
# add_sample = QAction("Add Sample")
|
||||
# self.menu = QMenu()
|
||||
# self.menu.addAction(add_sample)
|
||||
# self.menu.popup(event.globalPos())
|
||||
# self.menu = self.page().createStandardContextMenu()
|
||||
# self.menu = self.createStandardContextMenu()
|
||||
# add_sample = QAction("Add Sample")
|
||||
# self.menu = QMenu()
|
||||
# self.menu.addAction(add_sample)
|
||||
# self.menu.popup(event.globalPos())
|
||||
|
||||
119
src/submissions/templates/css/new_context_menu.css
Normal file
119
src/submissions/templates/css/new_context_menu.css
Normal file
@@ -0,0 +1,119 @@
|
||||
.flexDiv {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: fit-content;
|
||||
margin: 32px;
|
||||
}
|
||||
.selectWrapper {
|
||||
display: none;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
transition: opacity 100ms linear 0s;
|
||||
filter: drop-shadow(0 6px 26px rgba(0, 0, 0, 0.24));
|
||||
padding-top: calc(var(--sizeVar) / 2);
|
||||
}
|
||||
.multiSelect {
|
||||
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
|
||||
border: 1px solid var(--borderColor);
|
||||
box-sizing: border-box;
|
||||
border-radius: calc(var(--sizeVar) / 2);
|
||||
position: absolute;
|
||||
width: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow: hidden;
|
||||
background: #ffffff;
|
||||
transition: transform 300ms ease-in-out 0s, clip-path 300ms ease-in-out 0s;
|
||||
}
|
||||
.multiSelect div {
|
||||
color: var(--textPrimary);
|
||||
padding: 16px;
|
||||
width: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
.multiSelect div:hover {
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
.bottomBorder {
|
||||
border-bottom: 1px solid var(--borderColor);
|
||||
}
|
||||
.topBorder {
|
||||
border-top: 1px solid var(--borderColor);
|
||||
}
|
||||
.iconDiv {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.noSpace {
|
||||
justify-content: flex-start;
|
||||
gap: 6px;
|
||||
}
|
||||
.titleDiv {
|
||||
pointer-events: none;
|
||||
font-weight: 700;
|
||||
}
|
||||
.justHover i {
|
||||
opacity: 0;
|
||||
}
|
||||
.justHover:hover i {
|
||||
opacity: 1;
|
||||
}
|
||||
.multiSelect .placeholder {
|
||||
color: var(--textSecondary);
|
||||
font-style: italic;
|
||||
}
|
||||
.multiSelect .narrow {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.multiSelect i {
|
||||
color: var(--textSecondary);
|
||||
}
|
||||
.multiSelect {
|
||||
transform: translateX(100%);
|
||||
clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%);
|
||||
}
|
||||
.multiSelect:nth-of-type(1) {
|
||||
transform: translateX(0);
|
||||
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
|
||||
}
|
||||
.sec_btn {
|
||||
--bgColor: #869cff;
|
||||
}
|
||||
button {
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-size: calc(var(--sizeVar) * 1.75);
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: var(--sizeVar) calc(var(--sizeVar) * 2);
|
||||
border-radius: calc(var(--sizeVar) / 2);
|
||||
cursor: pointer;
|
||||
background-color: var(--bgColor);
|
||||
color: var(--txtColor);
|
||||
box-shadow: 0 0 0 1px var(--borColor) inset;
|
||||
}
|
||||
button:focus {
|
||||
--borColor: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
button:hover {
|
||||
--bgColor: #1fcc9e;
|
||||
}
|
||||
.sec_btn:hover {
|
||||
--bgColor: #6279e7;
|
||||
}
|
||||
.tri_btn:hover {
|
||||
--bgColor: #f8f7f8;
|
||||
}
|
||||
button:active {
|
||||
--bgColor: #1db284;
|
||||
}
|
||||
.sec_btn:active {
|
||||
--bgColor: #5468c7;
|
||||
}
|
||||
.tri_btn:active {
|
||||
--bgColor: #e7e7e7;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ div.procedure_creation_leftright div.right {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form_text {
|
||||
.form_text.full {
|
||||
width: 97%;
|
||||
}
|
||||
|
||||
|
||||
47
src/submissions/templates/js/new_context_menu.js
Normal file
47
src/submissions/templates/js/new_context_menu.js
Normal file
@@ -0,0 +1,47 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
|
||||
|
||||
document.getElementById("kittype").addEventListener("change", function() {
|
||||
backend.update_kit(this.value);
|
||||
})
|
||||
@@ -17,3 +20,71 @@ for(let i = 0; i < formtexts.length; i++) {
|
||||
backend.text_changed(formtexts[i].id, formtexts[i].value);
|
||||
})
|
||||
};
|
||||
|
||||
var reagentRoles = document.getElementsByClassName("reagentrole");
|
||||
|
||||
for(let i = 0; i < reagentRoles.length; i++) {
|
||||
reagentRoles[i].addEventListener("change", function() {
|
||||
if (reagentRoles[i].value === "New") {
|
||||
|
||||
var br = document.createElement("br");
|
||||
var new_reg = document.getElementById("new_" + reagentRoles[i].id);
|
||||
console.log(new_reg.id);
|
||||
var new_form = document.createElement("form");
|
||||
|
||||
var rr_name = document.createElement("input");
|
||||
rr_name.setAttribute("type", "text");
|
||||
rr_name.setAttribute("id", "new_" + reagentRoles[i].id + "_name");
|
||||
|
||||
var rr_name_label = document.createElement("label");
|
||||
rr_name_label.setAttribute("for", "new_" + reagentRoles[i].id + "_name");
|
||||
rr_name_label.innerHTML = "Name:";
|
||||
|
||||
var rr_lot = document.createElement("input");
|
||||
rr_lot.setAttribute("type", "text");
|
||||
rr_lot.setAttribute("id", "new_" + reagentRoles[i].id + "_lot");
|
||||
|
||||
var rr_lot_label = document.createElement("label");
|
||||
rr_lot_label.setAttribute("for", "new_" + reagentRoles[i].id + "_lot");
|
||||
rr_lot_label.innerHTML = "Lot:";
|
||||
|
||||
var rr_expiry = document.createElement("input");
|
||||
rr_expiry.setAttribute("type", "date");
|
||||
rr_expiry.setAttribute("id", "new_" + reagentRoles[i].id + "_expiry");
|
||||
|
||||
var rr_expiry_label = document.createElement("label");
|
||||
rr_expiry_label.setAttribute("for", "new_" + reagentRoles[i].id + "_expiry");
|
||||
rr_expiry_label.innerHTML = "Expiry:";
|
||||
|
||||
var submit_btn = document.createElement("input");
|
||||
submit_btn.setAttribute("type", "submit");
|
||||
submit_btn.setAttribute("value", "Submit");
|
||||
|
||||
new_form.appendChild(br.cloneNode());
|
||||
new_form.appendChild(rr_name_label);
|
||||
new_form.appendChild(rr_name);
|
||||
new_form.appendChild(br.cloneNode());
|
||||
new_form.appendChild(rr_lot_label);
|
||||
new_form.appendChild(rr_lot);
|
||||
new_form.appendChild(br.cloneNode());
|
||||
new_form.appendChild(rr_expiry_label);
|
||||
new_form.appendChild(rr_expiry);
|
||||
new_form.appendChild(br.cloneNode());
|
||||
new_form.appendChild(submit_btn);
|
||||
new_form.appendChild(br.cloneNode());
|
||||
|
||||
new_form.onsubmit = function(event) {
|
||||
event.preventDefault();
|
||||
alert(reagentRoles[i].id);
|
||||
name = document.getElementById("new_" + reagentRoles[i].id + "_name").value;
|
||||
lot = document.getElementById("new_" + reagentRoles[i].id + "_lot").value;
|
||||
expiry = document.getElementById("new_" + reagentRoles[i].id + "_expiry").value;
|
||||
alert("Submitting: " + name + ", " + lot);
|
||||
backend.log(name + " " + lot + " " + expiry);
|
||||
}
|
||||
|
||||
new_reg.appendChild(new_form);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -4,18 +4,24 @@
|
||||
<head>
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<title> New {{ proceduretype['name'] }} for {{ run['plate_number'] }}</title>
|
||||
<title>{% if edit %}Edit{% else %}New{% endif %} {{ proceduretype['name'] }} for {{ run['plate_number'] }}</title>
|
||||
{% endblock %}
|
||||
</head>
|
||||
<!-- Is this working? -->
|
||||
<body>
|
||||
{% block body %}
|
||||
<h1>New {{ proceduretype['name'] }} for {{ run['plate_number'] }}</h1><br><br>
|
||||
<h1>{% if edit %}Edit{% else %}New{% endif %} {{ proceduretype['name'] }} for
|
||||
{% if run['plate_number'] %}
|
||||
<a style="height:30px; font-size:30px" id="rsl_plate_num">{{ run['plate_number'] }}</a>
|
||||
{% else %}
|
||||
<input style="height:30px; font-size:30px" type="text" id="rsl_plate_num" value="RSL-XX-YYYYMMDD-P">
|
||||
{% endif %}
|
||||
</h1><br><br>
|
||||
<div class="procedure_creation_leftright">
|
||||
<div class="left">
|
||||
<form>
|
||||
<label for="technician">Technician:</label><br>
|
||||
<input type="text" class="form_text" id="technician" name="technician" width="100%" value="{{ procedure['technician']['value'] }}" background-color="{{ procedure['technician']['colour'] }}"><br><br>
|
||||
<input type="text" class="form_text full" id="technician" name="technician" width="100%" value="{{ procedure['technician']['value'] }}" background-color="{{ procedure['technician']['colour'] }}"><br><br>
|
||||
<label for="repeat">Repeat:</label>
|
||||
<input type="checkbox" class="form_check" id="repeat" name="repeat" value="{{ procedure['repeat'] }}"><br><br>
|
||||
<label>Kit Type:</label><br>
|
||||
@@ -33,6 +39,7 @@
|
||||
<option value="{{ reagent }}">{{ reagent }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="new_reagent" id="new_{{ key }}"></div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</form>
|
||||
@@ -44,9 +51,9 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% with proceduretype=proceduretype, child=True %}
|
||||
{% include "support/equipment_usage.html" %}
|
||||
{% endwith %}
|
||||
{% if proceduretype['equipment_section'] %}
|
||||
{{ proceduretype['equipment_section'] }}
|
||||
{% endif %}
|
||||
{% include 'support/context_menu.html' %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
33
src/submissions/templates/support/new_context_menu.html
Normal file
33
src/submissions/templates/support/new_context_menu.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<nav class="context-menu" id="context-menu">
|
||||
<!-- <button class="sec_btn" onclick="openMulti();">Add to feature vector</button>-->
|
||||
<div class="selectWrapper">
|
||||
<div class="multiSelect context-menu__items" id="menu-0">
|
||||
<ul class="bottomBorder" id="menu-header"></ul>
|
||||
<div class="context-menu__item">
|
||||
<a href="" class="context-menu__link" data-action="insertSample">Insert Sample</a>
|
||||
</div>
|
||||
<div class="context-menu__link">
|
||||
<div onclick="openMulti();">myVector</div>
|
||||
</div>
|
||||
<div class="context-menu__link">
|
||||
<div onclick="openMulti();">featureVector</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="multiSelect" id="menu-1">-->
|
||||
<!-- <div class="bottomBorder iconDiv noSpace narrow placeholder"><i class="material-icons">search</i>Search</div>-->
|
||||
<!-- <div class="iconDiv justHover" onclick="nextMenu(event);">Project Example<i class="material-icons">arrow_right</i></div>-->
|
||||
<!-- <div class="iconDiv justHover" onclick="nextMenu(event);">David’s project<i class="material-icons">arrow_right</i></div>-->
|
||||
<!-- <div class="iconDiv justHover" onclick="nextMenu(event);">Project Idan<i class="material-icons">arrow_right</i></div>-->
|
||||
<!-- <div class="iconDiv justHover" onclick="nextMenu(event);">Manhattan<i class="material-icons">arrow_right</i></div>-->
|
||||
<!-- <div class="topBorder iconDiv noSpace" onclick="prevMenu(event);"><i class="material-icons">arrow_back</i>Back</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="multiSelect" id="menu-2">-->
|
||||
<!-- <div class="bottomBorder titleDiv">Project Idan</div>-->
|
||||
<!-- <div onclick="openMulti();">Idan Vector</div>-->
|
||||
<!-- <div onclick="openMulti();">Testings</div>-->
|
||||
<!-- <div onclick="openMulti();">Features_120</div>-->
|
||||
<!-- <div onclick="openMulti();">Aggregators</div>-->
|
||||
<!-- <div id="menu-1" class="topBorder iconDiv noSpace" onclick="prevMenu(event);"><i class="material-icons">arrow_back</i>Back</div>-->
|
||||
<!-- </div>-->
|
||||
</nav>
|
||||
@@ -29,7 +29,7 @@ from functools import wraps
|
||||
|
||||
timezone = tz("America/Winnipeg")
|
||||
|
||||
logger = logging.getLogger(f"procedure.{__name__}")
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
logger.info(f"Package dir: {project_path}")
|
||||
|
||||
@@ -463,6 +463,7 @@ def render_details_template(template_name:str, css_in:List[str]|str=[], js_in:Li
|
||||
for js in js_in:
|
||||
with open(js, "r") as f:
|
||||
js_out.append(f.read())
|
||||
logger.debug(f"Kwargs: {kwargs}")
|
||||
return template.render(css=css_out, js=js_out, **kwargs)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user