Update of Reagent usage ui
This commit is contained in:
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())
|
||||
|
||||
Reference in New Issue
Block a user