Prior to updating queries to use query alias.
This commit is contained in:
@@ -6,31 +6,40 @@ from pprint import pformat
|
||||
from typing import Any, Tuple
|
||||
from pydantic import BaseModel
|
||||
from PyQt6.QtWidgets import (
|
||||
QLabel, QDialog, QWidget, QLineEdit, QGridLayout, QComboBox, QDialogButtonBox, QDateEdit, QSpinBox, QDoubleSpinBox
|
||||
QLabel, QDialog, QWidget, QLineEdit, QGridLayout, QComboBox, QDialogButtonBox, QDateEdit, QSpinBox, QDoubleSpinBox,
|
||||
QCheckBox
|
||||
)
|
||||
from sqlalchemy import String, TIMESTAMP, INTEGER, FLOAT
|
||||
from sqlalchemy import String, TIMESTAMP, INTEGER, FLOAT, JSON, BLOB
|
||||
from sqlalchemy.orm import InstrumentedAttribute, ColumnProperty
|
||||
import logging
|
||||
from sqlalchemy.orm.relationships import _RelationshipDeclared
|
||||
from tools import Report, report_result
|
||||
from backend import db
|
||||
|
||||
logger = logging.getLogger(f"submissions.{__name__}")
|
||||
|
||||
|
||||
class AddEdit(QDialog):
|
||||
|
||||
def __init__(self, parent, instance: Any | None = None, manager: str = ""):
|
||||
def __init__(self, parent, instance: Any | None = None, managers: set = set()):
|
||||
super().__init__(parent)
|
||||
logger.debug(f"Managers: {managers}")
|
||||
self.instance = instance
|
||||
self.object_type = instance.__class__
|
||||
self.managers = managers
|
||||
if instance.level < 2:
|
||||
try:
|
||||
self.managers.add(self.parent().instance)
|
||||
except AttributeError:
|
||||
pass
|
||||
logger.debug(f"Managers: {managers}")
|
||||
self.layout = QGridLayout(self)
|
||||
QBtn = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||
self.buttonBox = QDialogButtonBox(QBtn)
|
||||
self.buttonBox.accepted.connect(self.accept)
|
||||
self.buttonBox.rejected.connect(self.reject)
|
||||
fields = {key: dict(class_attr=getattr(self.object_type, key), instance_attr=getattr(self.instance, key))
|
||||
for key in dir(self.object_type) if isinstance(getattr(self.object_type, key), InstrumentedAttribute)
|
||||
and "id" not in key and key != manager}
|
||||
logger.debug(f"Fields: {pformat(self.instance.omnigui_dict)}")
|
||||
fields = {k: v for k, v in self.instance.omnigui_dict.items() if "id" not in k}
|
||||
# NOTE: Move 'name' to the front
|
||||
try:
|
||||
fields = {'name': fields.pop('name'), **fields}
|
||||
@@ -52,15 +61,17 @@ class AddEdit(QDialog):
|
||||
self.layout.addWidget(widget, self.layout.rowCount(), 0)
|
||||
height_counter += 1
|
||||
self.layout.addWidget(self.buttonBox)
|
||||
self.setWindowTitle(f"Add/Edit {self.object_type.__name__}")
|
||||
self.setWindowTitle(f"Add/Edit {self.object_type.__name__} - Manager: {self.managers}")
|
||||
self.setMinimumSize(600, 50 * height_counter)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
@report_result
|
||||
def parse_form(self) -> Tuple[BaseModel, Report]:
|
||||
from backend.validators import pydant
|
||||
report = Report()
|
||||
parsed = {result[0].strip(":"): result[1] for result in [item.parse_form() for item in self.findChildren(EditProperty)] if result[0]}
|
||||
# logger.debug(parsed)
|
||||
parsed = {result[0].strip(":"): result[1] for result in
|
||||
[item.parse_form() for item in self.findChildren(EditProperty)] if result[0]}
|
||||
logger.debug(f"Parsed form: {parsed}")
|
||||
model = self.object_type.pydantic_model
|
||||
# NOTE: Hand-off to pydantic model for validation.
|
||||
# NOTE: Also, why am I not just using the toSQL method here. I could write one for contacts.
|
||||
@@ -75,23 +86,42 @@ class EditProperty(QWidget):
|
||||
self.name = key
|
||||
self.label = QLabel(key.title().replace("_", " "))
|
||||
self.layout = QGridLayout()
|
||||
self.layout.addWidget(self.label, 0, 0, 1, 1)
|
||||
self.setObjectName(key)
|
||||
try:
|
||||
self.property_class = column_type['class_attr'].property.entity.class_
|
||||
except AttributeError:
|
||||
self.property_class = None
|
||||
try:
|
||||
self.is_list = column_type['class_attr'].property.uselist
|
||||
except AttributeError:
|
||||
self.is_list = False
|
||||
match column_type['class_attr'].property:
|
||||
case ColumnProperty():
|
||||
self.column_property_set(column_type, value=value)
|
||||
case _RelationshipDeclared():
|
||||
self.relationship_property_set(column_type, value=value)
|
||||
if not self.property_class.skip_on_edit:
|
||||
self.relationship_property_set(column_type, value=value)
|
||||
else:
|
||||
return
|
||||
case _:
|
||||
logger.error(f"{column_type} not a supported type.")
|
||||
return
|
||||
# if not self.is_list:
|
||||
self.layout.addWidget(self.label, 0, 0, 1, 1)
|
||||
self.layout.addWidget(self.widget, 0, 1, 1, 3)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def relationship_property_set(self, relationship_property, value=None):
|
||||
self.property_class = relationship_property['class_attr'].property.entity.class_
|
||||
self.is_list = relationship_property['class_attr'].property.uselist
|
||||
choices = [""] + [item.name for item in self.property_class.query()]
|
||||
def relationship_property_set(self, relationship, value=None):
|
||||
self.widget = QComboBox()
|
||||
logger.debug(self.parent().managers)
|
||||
for manager in self.parent().managers:
|
||||
if self.name in manager.aliases:
|
||||
logger.debug(f"Name: {self.name} is in aliases: {manager.aliases}")
|
||||
choices = [manager.name]
|
||||
self.widget.setEnabled(False)
|
||||
break
|
||||
else:
|
||||
choices = [""] + [item.name for item in self.property_class.query()]
|
||||
try:
|
||||
instance_value = getattr(self.parent().instance, self.objectName())
|
||||
except AttributeError:
|
||||
@@ -102,21 +132,25 @@ class EditProperty(QWidget):
|
||||
instance_value = next((item.name for item in instance_value), None)
|
||||
if instance_value:
|
||||
choices.insert(0, choices.pop(choices.index(instance_value)))
|
||||
self.widget = QComboBox()
|
||||
self.widget.addItems(choices)
|
||||
|
||||
def column_property_set(self, column_property, value=None):
|
||||
logger.debug(f"Column Property: {column_property['class_attr'].expression} {column_property}, Value: {value}")
|
||||
match column_property['class_attr'].expression.type:
|
||||
case String():
|
||||
if not value:
|
||||
if value is None:
|
||||
value = ""
|
||||
self.widget = QLineEdit(self)
|
||||
self.widget.setText(value)
|
||||
case INTEGER():
|
||||
if not value:
|
||||
value = 1
|
||||
self.widget = QSpinBox()
|
||||
self.widget.setValue(value)
|
||||
if isinstance(column_property['instance_attr'], bool):
|
||||
self.widget = QCheckBox()
|
||||
self.widget.setChecked(value)
|
||||
else:
|
||||
if value is None:
|
||||
value = 1
|
||||
self.widget = QSpinBox()
|
||||
self.widget.setValue(value)
|
||||
case FLOAT():
|
||||
if not value:
|
||||
value = 1.0
|
||||
@@ -127,6 +161,10 @@ class EditProperty(QWidget):
|
||||
if not value:
|
||||
value = date.today()
|
||||
self.widget.setDate(value)
|
||||
case JSON():
|
||||
self.widget = QLabel("JSON Under construction")
|
||||
case BLOB():
|
||||
self.widget = QLabel("BLOB Under construction")
|
||||
case _:
|
||||
logger.error(f"{column_property} not a supported property.")
|
||||
self.widget = None
|
||||
@@ -151,10 +189,10 @@ class EditProperty(QWidget):
|
||||
value = self.widget.currentText()
|
||||
case QSpinBox() | QDoubleSpinBox():
|
||||
value = self.widget.value()
|
||||
# if self.is_list:
|
||||
# value = [self.property_class.query(name=prelim)]
|
||||
# else:
|
||||
# value = self.property_class.query(name=prelim)
|
||||
case QCheckBox():
|
||||
value = self.widget.isChecked()
|
||||
case _:
|
||||
value = None
|
||||
return self.objectName(), value
|
||||
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@ from PyQt6.QtCore import QSortFilterProxyModel, Qt
|
||||
from PyQt6.QtGui import QAction, QCursor
|
||||
from PyQt6.QtWidgets import (
|
||||
QLabel, QDialog,
|
||||
QTableView, QWidget, QLineEdit, QGridLayout, QComboBox, QPushButton, QDialogButtonBox, QDateEdit, QMenu
|
||||
QTableView, QWidget, QLineEdit, QGridLayout, QComboBox, QPushButton, QDialogButtonBox, QDateEdit, QMenu,
|
||||
QDoubleSpinBox, QSpinBox, QCheckBox
|
||||
)
|
||||
from sqlalchemy import String, TIMESTAMP
|
||||
from sqlalchemy import String, TIMESTAMP, FLOAT, INTEGER, JSON, BLOB
|
||||
from sqlalchemy.orm import InstrumentedAttribute
|
||||
from sqlalchemy.orm.collections import InstrumentedList
|
||||
from sqlalchemy.orm.properties import ColumnProperty
|
||||
@@ -28,10 +29,16 @@ class ManagerWindow(QDialog):
|
||||
Initially this is a window to manage Organization Contacts, but hope to abstract it more later.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, object_type: Any, extras: List[str], **kwargs):
|
||||
def __init__(self, parent, object_type: Any, extras: List[str], managers: set = set(), **kwargs):
|
||||
super().__init__(parent)
|
||||
self.object_type = self.original_type = object_type
|
||||
self.instance = None
|
||||
self.managers = managers
|
||||
try:
|
||||
self.managers.add(self.parent().instance)
|
||||
except AttributeError:
|
||||
pass
|
||||
logger.debug(f"Managers: {managers}")
|
||||
self.extras = extras
|
||||
self.context = kwargs
|
||||
self.layout = QGridLayout(self)
|
||||
@@ -55,7 +62,7 @@ class ManagerWindow(QDialog):
|
||||
self.options.setObjectName("options")
|
||||
self.update_options()
|
||||
self.setLayout(self.layout)
|
||||
self.setWindowTitle(f"Manage {self.object_type.__name__}")
|
||||
self.setWindowTitle(f"Manage {self.object_type.__name__} - Managers: {self.managers}")
|
||||
|
||||
def update_options(self) -> None:
|
||||
"""
|
||||
@@ -63,8 +70,15 @@ class ManagerWindow(QDialog):
|
||||
"""
|
||||
if self.sub_class:
|
||||
self.object_type = getattr(db, self.sub_class.currentText())
|
||||
options = [item.name for item in self.object_type.query()]
|
||||
logger.debug(f"self.instance: {self.instance}")
|
||||
logger.debug(f"From update options, managers: {self.managers}")
|
||||
try:
|
||||
query_kwargs = {self.parent().instance.query_alias: self.parent().instance}
|
||||
except AttributeError as e:
|
||||
logger.debug(f"Couldn't set query kwargs due to: {e}")
|
||||
query_kwargs = {}
|
||||
logger.debug(f"Query kwargs: {query_kwargs}")
|
||||
options = [item.name for item in self.object_type.query(**query_kwargs)]
|
||||
logger.debug(f"self.object_type: {self.object_type}")
|
||||
if self.instance:
|
||||
options.insert(0, options.pop(options.index(self.instance.name)))
|
||||
self.options.clear()
|
||||
@@ -92,21 +106,24 @@ class ManagerWindow(QDialog):
|
||||
for item in deletes:
|
||||
item.setParent(None)
|
||||
# NOTE: Find the instance this manager will update
|
||||
self.instance = self.object_type.query(name=self.options.currentText())
|
||||
fields = {k: v for k, v in self.object_type.__dict__.items() if
|
||||
isinstance(v, InstrumentedAttribute) and k != "id"}
|
||||
logger.debug(f"Querying with {self.options.currentText()}")
|
||||
self.instance = self.object_type.query(name=self.options.currentText(), limit=1)
|
||||
logger.debug(f"Instance: {self.instance}")
|
||||
fields = {k: v for k, v in self.instance.omnigui_dict.items() if
|
||||
isinstance(v['class_attr'], InstrumentedAttribute) and k != "id"}
|
||||
# logger.debug(f"Instance fields: {fields}")
|
||||
for key, field in fields.items():
|
||||
match field.property:
|
||||
match field['class_attr'].property:
|
||||
# NOTE: ColumnProperties will be directly edited.
|
||||
case ColumnProperty():
|
||||
# NOTE: field.property.expression.type gives db column type eg. STRING or TIMESTAMP
|
||||
widget = EditProperty(self, key=key, column_type=field.property.expression.type,
|
||||
widget = EditProperty(self, key=key, column_type=field,
|
||||
value=getattr(self.instance, key))
|
||||
# NOTE: RelationshipDeclareds will be given a list of existing related objects.
|
||||
case _RelationshipDeclared():
|
||||
if key != "submissions":
|
||||
# NOTE: field.comparator.entity.class_ gives the relationship class
|
||||
widget = EditRelationship(self, key=key, entity=field.comparator.entity.class_,
|
||||
widget = EditRelationship(self, key=key, entity=field['class_attr'].comparator.entity.class_,
|
||||
value=getattr(self.instance, key))
|
||||
else:
|
||||
continue
|
||||
@@ -132,7 +149,7 @@ class ManagerWindow(QDialog):
|
||||
return self.instance
|
||||
|
||||
def add_new(self):
|
||||
dlg = AddEdit(parent=self, instance=self.object_type(), manager=self.object_type.__name__.lower())
|
||||
dlg = AddEdit(parent=self, instance=self.object_type(), managers=self.managers)
|
||||
if dlg.exec():
|
||||
new_pyd = dlg.parse_form()
|
||||
new_instance = new_pyd.to_sql()
|
||||
@@ -148,13 +165,33 @@ class EditProperty(QWidget):
|
||||
self.label = QLabel(key.title().replace("_", " "))
|
||||
self.layout = QGridLayout()
|
||||
self.layout.addWidget(self.label, 0, 0, 1, 1)
|
||||
match column_type:
|
||||
logger.debug(f"Column type: {column_type}")
|
||||
match column_type['class_attr'].property.expression.type:
|
||||
case String():
|
||||
self.widget = QLineEdit(self)
|
||||
self.widget.setText(value)
|
||||
case INTEGER():
|
||||
if isinstance(column_type['instance_attr'], bool):
|
||||
self.widget = QCheckBox()
|
||||
self.widget.setChecked(value)
|
||||
else:
|
||||
if value is None:
|
||||
value = 1
|
||||
self.widget = QSpinBox()
|
||||
self.widget.setValue(value)
|
||||
case FLOAT():
|
||||
if not value:
|
||||
value = 1.0
|
||||
self.widget = QDoubleSpinBox()
|
||||
self.widget.setMaximum(999.99)
|
||||
self.widget.setValue(value)
|
||||
case TIMESTAMP():
|
||||
self.widget = QDateEdit(self)
|
||||
self.widget.setDate(value)
|
||||
case JSON():
|
||||
self.widget = QLabel("JSON Under construction")
|
||||
case BLOB():
|
||||
self.widget = QLabel("BLOB Under construction")
|
||||
case _:
|
||||
self.widget = None
|
||||
self.layout.addWidget(self.widget, 0, 1, 1, 3)
|
||||
@@ -175,7 +212,7 @@ class EditRelationship(QWidget):
|
||||
|
||||
def __init__(self, parent, key: str, entity: Any, value):
|
||||
super().__init__(parent)
|
||||
self.entity = entity
|
||||
self.entity = entity #: The class of interest
|
||||
self.data = value
|
||||
self.label = QLabel(key.title().replace("_", " "))
|
||||
self.setObjectName(key)
|
||||
@@ -184,10 +221,11 @@ class EditRelationship(QWidget):
|
||||
self.add_button.clicked.connect(self.add_new)
|
||||
self.existing_button = QPushButton("Add Existing")
|
||||
self.existing_button.clicked.connect(self.add_existing)
|
||||
self.existing_button.setEnabled(self.entity.level == 1)
|
||||
self.layout = QGridLayout()
|
||||
self.layout.addWidget(self.label, 0, 0, 1, 5)
|
||||
self.layout.addWidget(self.table, 1, 0, 1, 8)
|
||||
self.layout.addWidget(self.add_button, 0, 6, 1, 1, alignment=Qt.AlignmentFlag.AlignRight)
|
||||
self.layout.addWidget(self.add_button, 0, 6, 1, 1, alignment=Qt.AlignmentFlag.AlignRight)
|
||||
self.layout.addWidget(self.existing_button, 0, 7, 1, 1, alignment=Qt.AlignmentFlag.AlignRight)
|
||||
self.setLayout(self.layout)
|
||||
self.set_data()
|
||||
@@ -205,17 +243,30 @@ class EditRelationship(QWidget):
|
||||
self.add_edit(instance=object)
|
||||
|
||||
def add_new(self, instance: Any = None):
|
||||
# NOTE: if an existing instance is not being edited, create a new instance
|
||||
if not instance:
|
||||
instance = self.entity()
|
||||
dlg = AddEdit(self, instance=instance, manager=self.parent().object_type.__name__.lower())
|
||||
# if self.parent().object_type.level == 2:
|
||||
managers = self.parent().managers
|
||||
# else:
|
||||
# managers = self.parent().managers + [self.parent().instance]
|
||||
match instance.level:
|
||||
case 1:
|
||||
dlg = AddEdit(self.parent(), instance=instance, managers=managers)
|
||||
case 2:
|
||||
dlg = ManagerWindow(self.parent(), object_type=instance.__class__, extras=[], managers=managers)
|
||||
case _:
|
||||
return
|
||||
if dlg.exec():
|
||||
new_instance = dlg.parse_form()
|
||||
new_instance, result = new_instance.to_sql()
|
||||
new_instance = new_instance.to_sql()
|
||||
logger.debug(f"New instance: {new_instance}")
|
||||
addition = getattr(self.parent().instance, self.objectName())
|
||||
if isinstance(addition, InstrumentedList):
|
||||
addition.append(new_instance)
|
||||
self.parent().instance.save()
|
||||
logger.debug(f"Addition: {addition}")
|
||||
# NOTE: Saving currently disabled
|
||||
# if isinstance(addition, InstrumentedList):
|
||||
# addition.append(new_instance)
|
||||
# self.parent().instance.save()
|
||||
self.parent().update_data()
|
||||
|
||||
def add_existing(self):
|
||||
@@ -223,11 +274,15 @@ class EditRelationship(QWidget):
|
||||
if dlg.exec():
|
||||
rows = dlg.return_selected_rows()
|
||||
for row in rows:
|
||||
logger.debug(f"Querying with {row}")
|
||||
instance = self.entity.query(**row)
|
||||
logger.debug(f"Queried instance: {instance}")
|
||||
addition = getattr(self.parent().instance, self.objectName())
|
||||
if isinstance(addition, InstrumentedList):
|
||||
addition.append(instance)
|
||||
self.parent().instance.save()
|
||||
logger.debug(f"Addition: {addition}")
|
||||
# NOTE: Saving currently disabled
|
||||
# if isinstance(addition, InstrumentedList):
|
||||
# addition.append(instance)
|
||||
# self.parent().instance.save()
|
||||
self.parent().update_data()
|
||||
|
||||
def set_data(self) -> None:
|
||||
@@ -235,7 +290,11 @@ class EditRelationship(QWidget):
|
||||
sets data in model
|
||||
"""
|
||||
# logger.debug(self.data)
|
||||
self.data = DataFrame.from_records([item.omnigui_dict for item in self.data])
|
||||
if not isinstance(self.data, list):
|
||||
self.data = [self.data]
|
||||
records = [{k: v['instance_attr'] for k, v in item.omnigui_dict.items()} for item in self.data]
|
||||
# logger.debug(f"Records: {records}")
|
||||
self.data = DataFrame.from_records(records)
|
||||
try:
|
||||
self.columns_of_interest = [dict(name=item, column=self.data.columns.get_loc(item)) for item in self.extras]
|
||||
except (KeyError, AttributeError):
|
||||
@@ -261,8 +320,13 @@ class EditRelationship(QWidget):
|
||||
event (_type_): the item of interest
|
||||
"""
|
||||
id = self.table.selectionModel().currentIndex()
|
||||
id = int(id.sibling(id.row(), 0).data())
|
||||
object = self.entity.query(id=id)
|
||||
# NOTE: the overly complicated {column_name: row_value} dictionary construction
|
||||
row_data = {self.data.columns[column]: self.table.model().index(id.row(), column).data() for column in
|
||||
range(self.table.model().columnCount())}
|
||||
object = self.entity.query(**row_data)
|
||||
if isinstance(object, list):
|
||||
object = object[0]
|
||||
logger.debug(object)
|
||||
self.menu = QMenu(self)
|
||||
action = QAction(f"Remove {object.name}", self)
|
||||
action.triggered.connect(lambda: self.remove_item(object=object))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Search box that performs fuzzy search for various object types
|
||||
"""
|
||||
from copy import deepcopy
|
||||
from pprint import pformat
|
||||
from typing import Tuple, Any, List, Generator
|
||||
from pandas import DataFrame
|
||||
@@ -22,7 +23,8 @@ class SearchBox(QDialog):
|
||||
|
||||
def __init__(self, parent, object_type: Any, extras: List[dict], returnable: bool = False, **kwargs):
|
||||
super().__init__(parent)
|
||||
self.object_type = self.original_type = object_type
|
||||
self.object_type = object_type
|
||||
self.original_type = object_type
|
||||
self.extras = extras
|
||||
self.context = kwargs
|
||||
self.layout = QGridLayout(self)
|
||||
@@ -43,7 +45,7 @@ class SearchBox(QDialog):
|
||||
self.setLayout(self.layout)
|
||||
self.setWindowTitle(f"Search {self.object_type.__name__}")
|
||||
self.update_widgets()
|
||||
self.update_data()
|
||||
# self.update_data()
|
||||
if returnable:
|
||||
QBtn = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||
self.buttonBox = QDialogButtonBox(QBtn)
|
||||
@@ -57,21 +59,30 @@ class SearchBox(QDialog):
|
||||
"""
|
||||
Changes form inputs based on sample type
|
||||
"""
|
||||
search_fields = []
|
||||
logger.debug(f"Search fields: {search_fields}")
|
||||
deletes = [item for item in self.findChildren(FieldSearch)]
|
||||
for item in deletes:
|
||||
item.setParent(None)
|
||||
# NOTE: Handle any subclasses
|
||||
if not self.sub_class:
|
||||
logger.warning(f"No subclass selected.")
|
||||
self.update_data()
|
||||
return
|
||||
else:
|
||||
if self.sub_class.currentText() == "Any":
|
||||
self.object_type = self.original_type
|
||||
else:
|
||||
self.object_type = self.original_type.find_regular_subclass(self.sub_class.currentText())
|
||||
try:
|
||||
search_fields = self.object_type.searchables
|
||||
except AttributeError:
|
||||
search_fields = []
|
||||
# logger.debug(f"Object type: {self.object_type} - {self.object_type.searchables}")
|
||||
# logger.debug(f"Original type: {self.original_type} - {self.original_type.searchables}")
|
||||
for item in self.object_type.searchables:
|
||||
if item['field'] in [item['field'] for item in search_fields]:
|
||||
logger.debug(f"Already have {item['field']}")
|
||||
continue
|
||||
else:
|
||||
search_fields.append(item)
|
||||
logger.debug(f"Search fields: {search_fields}")
|
||||
for iii, searchable in enumerate(search_fields):
|
||||
widget = FieldSearch(parent=self, label=searchable['label'], field_name=searchable['field'])
|
||||
widget.setObjectName(searchable['field'])
|
||||
@@ -120,6 +131,7 @@ class FieldSearch(QWidget):
|
||||
|
||||
def __init__(self, parent, label, field_name):
|
||||
super().__init__(parent)
|
||||
self.setParent(parent)
|
||||
self.layout = QVBoxLayout(self)
|
||||
label_widget = QLabel(label)
|
||||
self.layout.addWidget(label_widget)
|
||||
@@ -158,9 +170,8 @@ class SearchResults(QTableView):
|
||||
self.context = kwargs
|
||||
self.parent = parent
|
||||
self.object_type = object_type
|
||||
|
||||
try:
|
||||
self.extras = extras + self.object_type.searchables
|
||||
self.extras = extras + [item for item in deepcopy(self.object_type.searchables)]
|
||||
except AttributeError:
|
||||
self.extras = extras
|
||||
logger.debug(f"Extras: {self.extras}")
|
||||
|
||||
@@ -684,7 +684,7 @@ class SubmissionFormWidget(QWidget):
|
||||
message=f"Couldn't find reagent type {self.reagent.role}: {lot} in the database.\n\nWould you like to add it?")
|
||||
|
||||
if dlg.exec():
|
||||
wanted_reagent = self.parent().parent().new_add_reagent(instance=wanted_reagent)
|
||||
wanted_reagent = self.parent.parent().add_reagent(instance=wanted_reagent)
|
||||
return wanted_reagent, report
|
||||
else:
|
||||
# NOTE: In this case we will have an empty reagent and the submission will fail kit integrity check
|
||||
|
||||
Reference in New Issue
Block a user