Ui interface updates.
This commit is contained in:
@@ -13,6 +13,7 @@ from sqlalchemy import Column, INTEGER, String, JSON
|
|||||||
from sqlalchemy.ext.associationproxy import AssociationProxy
|
from sqlalchemy.ext.associationproxy import AssociationProxy
|
||||||
from sqlalchemy.orm import DeclarativeMeta, declarative_base, Query, Session, InstrumentedAttribute, ColumnProperty
|
from sqlalchemy.orm import DeclarativeMeta, declarative_base, Query, Session, InstrumentedAttribute, ColumnProperty
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
from sqlalchemy.exc import ArgumentError
|
from sqlalchemy.exc import ArgumentError
|
||||||
from typing import Any, List, ClassVar
|
from typing import Any, List, ClassVar
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -237,10 +238,10 @@ class BaseClass(Base):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def query_or_create(cls, **kwargs) -> Tuple[Any, bool]:
|
def query_or_create(cls, **kwargs) -> Tuple[Any, bool]:
|
||||||
new = False
|
new = False
|
||||||
allowed = [k for k, v in cls.__dict__.items() if isinstance(v, InstrumentedAttribute)]
|
allowed = [k for k, v in cls.__dict__.items() if isinstance(v, InstrumentedAttribute) or isinstance(v, hybrid_property)]
|
||||||
# and not isinstance(v.property, _RelationshipDeclared)]
|
# and not isinstance(v.property, _RelationshipDeclared)]
|
||||||
sanitized_kwargs = {k: v for k, v in kwargs.items() if k in allowed}
|
sanitized_kwargs = {k: v for k, v in kwargs.items() if k in allowed}
|
||||||
# logger.debug(f"Sanitized kwargs: {sanitized_kwargs}")
|
logger.debug(f"Sanitized kwargs: {sanitized_kwargs}")
|
||||||
instance = cls.query(**sanitized_kwargs)
|
instance = cls.query(**sanitized_kwargs)
|
||||||
if not instance or isinstance(instance, list):
|
if not instance or isinstance(instance, list):
|
||||||
instance = cls()
|
instance = cls()
|
||||||
@@ -273,7 +274,7 @@ class BaseClass(Base):
|
|||||||
return cls.execute_query(**kwargs)
|
return cls.execute_query(**kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def execute_query(cls, query: Query = None, model=None, limit: int = 0, **kwargs) -> Any | List[Any]:
|
def execute_query(cls, query: Query = None, model=None, limit: int = 0, offset:int|None=None, **kwargs) -> Any | List[Any]:
|
||||||
"""
|
"""
|
||||||
Execute sqlalchemy query with relevant defaults.
|
Execute sqlalchemy query with relevant defaults.
|
||||||
|
|
||||||
@@ -291,22 +292,32 @@ class BaseClass(Base):
|
|||||||
# logger.debug(f"Model: {model}")
|
# logger.debug(f"Model: {model}")
|
||||||
if query is None:
|
if query is None:
|
||||||
query: Query = cls.__database_session__.query(cls)
|
query: Query = cls.__database_session__.query(cls)
|
||||||
|
else:
|
||||||
|
logger.debug(f"Incoming query: {query}")
|
||||||
singles = cls.get_default_info('singles')
|
singles = cls.get_default_info('singles')
|
||||||
for k, v in kwargs.items():
|
for k, v in kwargs.items():
|
||||||
|
logger.info(f"Using key: {k} with value: {v} against {cls}")
|
||||||
logger.info(f"Using key: {k} with value: {v}")
|
|
||||||
try:
|
try:
|
||||||
attr = getattr(cls, k)
|
attr = getattr(cls, k)
|
||||||
|
except (ArgumentError, AttributeError) as e:
|
||||||
|
logger.error(f"Attribute {k} unavailable due to:\n\t{e}\n.")
|
||||||
|
continue
|
||||||
# NOTE: account for attrs that use list.
|
# NOTE: account for attrs that use list.
|
||||||
if attr.property.uselist:
|
try:
|
||||||
|
check = attr.property.uselist
|
||||||
|
except AttributeError:
|
||||||
|
check = False
|
||||||
|
if check:
|
||||||
|
logger.debug("Got uselist")
|
||||||
query = query.filter(attr.contains(v))
|
query = query.filter(attr.contains(v))
|
||||||
else:
|
else:
|
||||||
|
logger.debug("Single item.")
|
||||||
query = query.filter(attr == v)
|
query = query.filter(attr == v)
|
||||||
except (ArgumentError, AttributeError) as e:
|
|
||||||
logger.error(f"Attribute {k} unavailable due to:\n\t{e}\nSkipping.")
|
|
||||||
if k in singles:
|
if k in singles:
|
||||||
logger.warning(f"{k} is in singles. Returning only one value.")
|
logger.warning(f"{k} is in singles. Returning only one value.")
|
||||||
limit = 1
|
limit = 1
|
||||||
|
if offset:
|
||||||
|
query.offset(offset)
|
||||||
with query.session.no_autoflush:
|
with query.session.no_autoflush:
|
||||||
match limit:
|
match limit:
|
||||||
case 0:
|
case 0:
|
||||||
@@ -476,13 +487,13 @@ class BaseClass(Base):
|
|||||||
# logger.debug(f"Attempting to set: {key} to {value}")
|
# logger.debug(f"Attempting to set: {key} to {value}")
|
||||||
if key.startswith("_"):
|
if key.startswith("_"):
|
||||||
return super().__setattr__(key, value)
|
return super().__setattr__(key, value)
|
||||||
try:
|
# try:
|
||||||
check = not hasattr(self, key)
|
check = not hasattr(self, key)
|
||||||
except:
|
# except:
|
||||||
return
|
# return
|
||||||
if check:
|
if check:
|
||||||
try:
|
try:
|
||||||
json.dumps(value)
|
value = json.dumps(value)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
value = str(value)
|
value = str(value)
|
||||||
self._misc_info.update({key: value})
|
self._misc_info.update({key: value})
|
||||||
@@ -612,6 +623,7 @@ class BaseClass(Base):
|
|||||||
if dlg.exec():
|
if dlg.exec():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class LogMixin(Base):
|
class LogMixin(Base):
|
||||||
tracking_exclusion: ClassVar = ['artic_technician', 'clientsubmissionsampleassociation',
|
tracking_exclusion: ClassVar = ['artic_technician', 'clientsubmissionsampleassociation',
|
||||||
'submission_reagent_associations', 'submission_equipment_associations',
|
'submission_reagent_associations', 'submission_equipment_associations',
|
||||||
|
|||||||
@@ -149,12 +149,14 @@ class ClientSubmission(BaseClass, LogMixin):
|
|||||||
pass
|
pass
|
||||||
# query = query.order_by(cls.submitted_date.desc())
|
# query = query.order_by(cls.submitted_date.desc())
|
||||||
# NOTE: Split query results into pages of size {page_size}
|
# NOTE: Split query results into pages of size {page_size}
|
||||||
if page_size > 0:
|
if page_size > 0 and limit == 0:
|
||||||
query = query.limit(page_size)
|
limit = page_size
|
||||||
page = page - 1
|
page = page - 1
|
||||||
if page is not None:
|
if page is not None:
|
||||||
query = query.offset(page * page_size)
|
offset = page * page_size
|
||||||
return cls.execute_query(query=query, limit=limit, **kwargs)
|
else:
|
||||||
|
offset = None
|
||||||
|
return cls.execute_query(query=query, limit=limit, offset=offset, **kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def submissions_to_df(cls, submissiontype: str | None = None, limit: int = 0,
|
def submissions_to_df(cls, submissiontype: str | None = None, limit: int = 0,
|
||||||
@@ -269,7 +271,9 @@ class ClientSubmission(BaseClass, LogMixin):
|
|||||||
try:
|
try:
|
||||||
assert isinstance(sample, Sample)
|
assert isinstance(sample, Sample)
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
|
logger.warning(f"Converting {sample} to sql.")
|
||||||
sample = sample.to_sql()
|
sample = sample.to_sql()
|
||||||
|
logger.debug(sample.__dict__)
|
||||||
try:
|
try:
|
||||||
row = sample._misc_info['row']
|
row = sample._misc_info['row']
|
||||||
except (KeyError, AttributeError):
|
except (KeyError, AttributeError):
|
||||||
@@ -278,10 +282,12 @@ class ClientSubmission(BaseClass, LogMixin):
|
|||||||
column = sample._misc_info['column']
|
column = sample._misc_info['column']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
column = 0
|
column = 0
|
||||||
|
logger.debug(f"Sample: {sample}")
|
||||||
|
submission_rank = sample._misc_info['submission_rank']
|
||||||
assoc = ClientSubmissionSampleAssociation(
|
assoc = ClientSubmissionSampleAssociation(
|
||||||
sample=sample,
|
sample=sample,
|
||||||
submission=self,
|
submission=self,
|
||||||
submission_rank=sample._misc_info['submission_rank'],
|
submission_rank=submission_rank,
|
||||||
row=row,
|
row=row,
|
||||||
column=column
|
column=column
|
||||||
)
|
)
|
||||||
@@ -310,6 +316,7 @@ class ClientSubmission(BaseClass, LogMixin):
|
|||||||
for sample in active_samples:
|
for sample in active_samples:
|
||||||
sample = sample.to_sql()
|
sample = sample.to_sql()
|
||||||
logger.debug(f"Sample: {sample.id}")
|
logger.debug(f"Sample: {sample.id}")
|
||||||
|
if sample not in run.sample:
|
||||||
assoc = run.add_sample(sample)
|
assoc = run.add_sample(sample)
|
||||||
assoc.save()
|
assoc.save()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -43,9 +43,10 @@ class DefaultParser(object):
|
|||||||
"""
|
"""
|
||||||
self.proceduretype = proceduretype
|
self.proceduretype = proceduretype
|
||||||
try:
|
try:
|
||||||
self._pyd_object = getattr(pydant, f"Pyd{self.__class__.__name__.replace('Parser', '')}")
|
self._pyd_object = getattr(pydant, f"Pyd{self.__class__.__name__.replace('Parser', '').replace('Info', '')}")
|
||||||
except AttributeError:
|
except AttributeError as e:
|
||||||
self._pyd_object = pydant.PydResults
|
logger.error(f"Couldn't get pyd object: Pyd{self.__class__.__name__.replace('Parser', '').replace('Info', '')}")
|
||||||
|
self._pyd_object = getattr(pydant, self.__class__.pyd_name)
|
||||||
self.workbook = load_workbook(self.filepath, data_only=True)
|
self.workbook = load_workbook(self.filepath, data_only=True)
|
||||||
if not range_dict:
|
if not range_dict:
|
||||||
self.range_dict = self.__class__.default_range_dict
|
self.range_dict = self.__class__.default_range_dict
|
||||||
@@ -118,7 +119,7 @@ class DefaultTABLEParser(DefaultParser):
|
|||||||
if isinstance(key, str):
|
if isinstance(key, str):
|
||||||
key = key.lower().replace(" ", "_")
|
key = key.lower().replace(" ", "_")
|
||||||
key = re.sub(r"_(\(.*\)|#)", "", key)
|
key = re.sub(r"_(\(.*\)|#)", "", key)
|
||||||
logger.debug(f"Row {ii} values: {key}: {value}")
|
# logger.debug(f"Row {ii} values: {key}: {value}")
|
||||||
output[key] = value
|
output[key] = value
|
||||||
yield output
|
yield output
|
||||||
|
|
||||||
@@ -126,4 +127,4 @@ class DefaultTABLEParser(DefaultParser):
|
|||||||
return [self._pyd_object(**output) for output in self.parsed_info]
|
return [self._pyd_object(**output) for output in self.parsed_info]
|
||||||
|
|
||||||
from .clientsubmission_parser import *
|
from .clientsubmission_parser import *
|
||||||
from backend.excel.parsers.results_parsers.pcr_results_parser import *
|
from backend.excel.parsers.results_parsers.pcr_results_parser import PCRInfoParser, PCRSampleParser
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ class ClientSubmissionInfoParser(DefaultKEYVALUEParser, SubmissionTyperMixin):
|
|||||||
Object for retrieving submitter info from "sample list" sheet
|
Object for retrieving submitter info from "sample list" sheet
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
pyd_name = "PydClientSubmission"
|
||||||
|
|
||||||
default_range_dict = [dict(
|
default_range_dict = [dict(
|
||||||
start_row=2,
|
start_row=2,
|
||||||
end_row=18,
|
end_row=18,
|
||||||
@@ -110,6 +112,8 @@ class ClientSubmissionSampleParser(DefaultTABLEParser, SubmissionTyperMixin):
|
|||||||
Object for retrieving submitter samples from "sample list" sheet
|
Object for retrieving submitter samples from "sample list" sheet
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
pyd_name = "PydSample"
|
||||||
|
|
||||||
default_range_dict = [dict(
|
default_range_dict = [dict(
|
||||||
header_row=19,
|
header_row=19,
|
||||||
end_row=115,
|
end_row=115,
|
||||||
@@ -126,7 +130,7 @@ class ClientSubmissionSampleParser(DefaultTABLEParser, SubmissionTyperMixin):
|
|||||||
def parsed_info(self) -> Generator[dict, None, None]:
|
def parsed_info(self) -> Generator[dict, None, None]:
|
||||||
output = super().parsed_info
|
output = super().parsed_info
|
||||||
for ii, sample in enumerate(output):
|
for ii, sample in enumerate(output):
|
||||||
logger.debug(f"Parsed info sample: {sample}")
|
# logger.debug(f"Parsed info sample: {sample}")
|
||||||
if isinstance(sample["row"], str) and sample["row"].lower() in ascii_lowercase[0:8]:
|
if isinstance(sample["row"], str) and sample["row"].lower() in ascii_lowercase[0:8]:
|
||||||
try:
|
try:
|
||||||
sample["row"] = row_keys[sample["row"]]
|
sample["row"] = row_keys[sample["row"]]
|
||||||
|
|||||||
@@ -290,6 +290,16 @@ class PydSample(PydBaseClass):
|
|||||||
value = row_keys[value]
|
value = row_keys[value]
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def improved_dict(self, dictionaries: bool = True) -> dict:
|
||||||
|
output = super().improved_dict(dictionaries=dictionaries)
|
||||||
|
output['name'] = self.sample_id
|
||||||
|
del output['sampletype']
|
||||||
|
return output
|
||||||
|
|
||||||
|
def to_sql(self):
|
||||||
|
sql = super().to_sql()
|
||||||
|
sql._misc_info["submission_rank"] = self.submission_rank
|
||||||
|
return sql
|
||||||
|
|
||||||
class PydTips(BaseModel):
|
class PydTips(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class ProcedureCreation(QDialog):
|
|||||||
plate_map=self.plate_map,
|
plate_map=self.plate_map,
|
||||||
edit=self.edit
|
edit=self.edit
|
||||||
)
|
)
|
||||||
with open("web.html", "w") as f:
|
with open("procedure_creation_rendered.html", "w") as f:
|
||||||
f.write(html)
|
f.write(html)
|
||||||
self.webview.setHtml(html)
|
self.webview.setHtml(html)
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,9 @@ from PyQt6.QtCore import Qt, pyqtSlot
|
|||||||
from PyQt6.QtWebChannel import QWebChannel
|
from PyQt6.QtWebChannel import QWebChannel
|
||||||
from PyQt6.QtWebEngineWidgets import QWebEngineView
|
from PyQt6.QtWebEngineWidgets import QWebEngineView
|
||||||
from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QGridLayout
|
from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QGridLayout
|
||||||
|
|
||||||
from backend.db.models import ClientSubmission
|
from backend.db.models import ClientSubmission
|
||||||
from backend.validators import PydSample, RSLNamer
|
from backend.validators import PydSample, RSLNamer
|
||||||
from tools import get_application_from_parent, jinja_template_loading
|
from tools import get_application_from_parent, jinja_template_loading, render_details_template
|
||||||
|
|
||||||
|
|
||||||
env = jinja_template_loading()
|
env = jinja_template_loading()
|
||||||
|
|
||||||
@@ -24,6 +22,7 @@ class SampleChecker(QDialog):
|
|||||||
self.rsl_plate_number = RSLNamer.construct_new_plate_name(clientsubmission.to_dict())
|
self.rsl_plate_number = RSLNamer.construct_new_plate_name(clientsubmission.to_dict())
|
||||||
else:
|
else:
|
||||||
self.rsl_plate_number = clientsubmission
|
self.rsl_plate_number = clientsubmission
|
||||||
|
logger.debug(f"RSL Plate number: {self.rsl_plate_number}")
|
||||||
self.samples = samples
|
self.samples = samples
|
||||||
self.setWindowTitle(title)
|
self.setWindowTitle(title)
|
||||||
self.app = get_application_from_parent(parent)
|
self.app = get_application_from_parent(parent)
|
||||||
@@ -38,22 +37,27 @@ class SampleChecker(QDialog):
|
|||||||
# NOTE: Used to maintain javascript functions.
|
# NOTE: Used to maintain javascript functions.
|
||||||
template = env.get_template("sample_checker.html")
|
template = env.get_template("sample_checker.html")
|
||||||
template_path = Path(template.environment.loader.__getattribute__("searchpath")[0])
|
template_path = Path(template.environment.loader.__getattribute__("searchpath")[0])
|
||||||
with open(template_path.joinpath("css", "styles.css"), "r") as f:
|
# with open(template_path.joinpath("css", "styles.css"), "r") as f:
|
||||||
css = f.read()
|
# css = [f.read()]
|
||||||
try:
|
try:
|
||||||
samples = self.formatted_list
|
samples = self.formatted_list
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
logger.error(f"Problem getting sample list: {e}")
|
logger.error(f"Problem getting sample list: {e}")
|
||||||
samples = []
|
samples = []
|
||||||
html = template.render(samples=samples, css=css, rsl_plate_number=self.rsl_plate_number)
|
# html = template.render(samples=samples, css=css, rsl_plate_number=self.rsl_plate_number)
|
||||||
|
html = render_details_template(template_name="sample_checker", samples=samples, rsl_plate_number=self.rsl_plate_number)
|
||||||
self.webview.setHtml(html)
|
self.webview.setHtml(html)
|
||||||
|
self.webview.page().setWebChannel(self.channel)
|
||||||
QBtn = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
QBtn = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||||
self.buttonBox = QDialogButtonBox(QBtn)
|
self.buttonBox = QDialogButtonBox(QBtn)
|
||||||
self.buttonBox.accepted.connect(self.accept)
|
self.buttonBox.accepted.connect(self.accept)
|
||||||
self.buttonBox.rejected.connect(self.reject)
|
self.buttonBox.rejected.connect(self.reject)
|
||||||
self.layout.addWidget(self.buttonBox, 11, 9, 1, 1, alignment=Qt.AlignmentFlag.AlignRight)
|
self.layout.addWidget(self.buttonBox, 11, 9, 1, 1, alignment=Qt.AlignmentFlag.AlignRight)
|
||||||
self.setLayout(self.layout)
|
self.setLayout(self.layout)
|
||||||
self.webview.page().setWebChannel(self.channel)
|
|
||||||
|
with open("sample_checker_rendered.html", "w") as f:
|
||||||
|
f.write(html)
|
||||||
|
logger.debug(f"HTML sample checker written!")
|
||||||
|
|
||||||
@pyqtSlot(str, str, str)
|
@pyqtSlot(str, str, str)
|
||||||
def text_changed(self, submission_rank: str, key: str, new_value: str):
|
def text_changed(self, submission_rank: str, key: str, new_value: str):
|
||||||
@@ -65,8 +69,8 @@ class SampleChecker(QDialog):
|
|||||||
return
|
return
|
||||||
item.__setattr__(key, new_value)
|
item.__setattr__(key, new_value)
|
||||||
|
|
||||||
@pyqtSlot(str, bool)
|
@pyqtSlot(int, bool)
|
||||||
def enable_sample(self, submission_rank: str, enabled: bool):
|
def enable_sample(self, submission_rank: int, enabled: bool):
|
||||||
logger.debug(f"Name: {submission_rank}, Enabled: {enabled}")
|
logger.debug(f"Name: {submission_rank}, Enabled: {enabled}")
|
||||||
try:
|
try:
|
||||||
item = next((sample for sample in self.samples if int(submission_rank) == sample.submission_rank))
|
item = next((sample for sample in self.samples if int(submission_rank) == sample.submission_rank))
|
||||||
|
|||||||
@@ -325,8 +325,9 @@ class SubmissionsTree(QTreeView):
|
|||||||
"""
|
"""
|
||||||
indexes = self.selectedIndexes()
|
indexes = self.selectedIndexes()
|
||||||
dicto = next((item.data(1) for item in indexes if item.data(1)))
|
dicto = next((item.data(1) for item in indexes if item.data(1)))
|
||||||
|
logger.debug(f"Dicto: {pformat(dicto)}")
|
||||||
query_obj = dicto['item_type'].query(name=dicto['query_str'], limit=1)
|
query_obj = dicto['item_type'].query(name=dicto['query_str'], limit=1)
|
||||||
logger.debug(query_obj)
|
logger.debug(f"Querying: {query_obj}")
|
||||||
# NOTE: Convert to data in id column (i.e. column 0)
|
# NOTE: Convert to data in id column (i.e. column 0)
|
||||||
# id = id.sibling(id.row(), 0).data()
|
# id = id.sibling(id.row(), 0).data()
|
||||||
# logger.debug(id.model().query_group_object(id.row()))
|
# logger.debug(id.model().query_group_object(id.row()))
|
||||||
|
|||||||
@@ -141,6 +141,11 @@ class SubmissionFormContainer(QWidget):
|
|||||||
checker = SampleChecker(self, "Sample Checker", self.pydsamples)
|
checker = SampleChecker(self, "Sample Checker", self.pydsamples)
|
||||||
if checker.exec():
|
if checker.exec():
|
||||||
# logger.debug(pformat(self.pydclientsubmission.sample))
|
# logger.debug(pformat(self.pydclientsubmission.sample))
|
||||||
|
try:
|
||||||
|
assert isinstance(self.pydclientsubmission, PydClientSubmission)
|
||||||
|
except AssertionError as e:
|
||||||
|
logger.error(f"Got wrong type for {self.pydclientsubmission}: {type(self.pydclientsubmission)}")
|
||||||
|
raise e
|
||||||
self.form = self.pydclientsubmission.to_form(parent=self)
|
self.form = self.pydclientsubmission.to_form(parent=self)
|
||||||
self.form.samples = self.pydsamples
|
self.form.samples = self.pydsamples
|
||||||
self.layout().addWidget(self.form)
|
self.layout().addWidget(self.form)
|
||||||
|
|||||||
@@ -24,23 +24,23 @@
|
|||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{% if not child %}
|
{% if not child %}
|
||||||
<script>
|
<!--<script>-->
|
||||||
var coll = document.getElementsByClassName("collapsible");
|
<!--var coll = document.getElementsByClassName("collapsible");-->
|
||||||
var i;
|
<!--var i;-->
|
||||||
|
|
||||||
for (i = 0; i < coll.length; i++) {
|
<!--for (i = 0; i < coll.length; i++) {-->
|
||||||
coll[i].addEventListener("click", function() {
|
<!-- coll[i].addEventListener("click", function() {-->
|
||||||
this.classList.toggle("active");
|
<!-- this.classList.toggle("active");-->
|
||||||
var content = this.nextElementSibling;
|
<!-- var content = this.nextElementSibling;-->
|
||||||
if (content.style.display === "block") {
|
<!-- if (content.style.display === "block") {-->
|
||||||
content.style.display = "none";
|
<!-- content.style.display = "none";-->
|
||||||
} else {
|
<!-- } else {-->
|
||||||
content.style.display = "block";
|
<!-- content.style.display = "block";-->
|
||||||
}
|
<!-- }-->
|
||||||
});
|
<!-- });-->
|
||||||
}
|
<!--}-->
|
||||||
</script>
|
<!--</script>-->
|
||||||
{% endif %}
|
<!--{% endif %}-->
|
||||||
{% for j in js%}
|
{% for j in js%}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
{% extends "details.html" %}
|
{% extends "details.html" %}
|
||||||
<head>
|
<html>
|
||||||
|
<head>
|
||||||
{% block head %}
|
{% block head %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<title>Sample Checker</title>
|
<title>Sample Checker</title>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h2><u>Sample Checker</u></h2>
|
<h2><u>Sample Checker</u></h2>
|
||||||
<br>
|
<br>
|
||||||
{% if rsl_plate_num %}
|
{% if rsl_plate_number %}
|
||||||
<label for="rsl_plate_number">RSL Plate Number:</label><br>
|
<label for="rsl_plate_number">RSL Plate Number:</label><br>
|
||||||
<input type="text" id="rsl_plate_number" name="sample_id" value="{{ rsl_plate_number }}" size="40">
|
<input type="text" id="rsl_plate_number" name="sample_id" value="{{ rsl_plate_number }}" size="40">
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br>
|
<br>
|
||||||
<p>Take a moment to verify sample names.</p>
|
<p>Take a moment to verify sample names.</p>
|
||||||
@@ -20,35 +20,41 @@
|
|||||||
<form>
|
<form>
|
||||||
  Submitter ID<br/><!--              Row           Column<br/>-->
|
  Submitter ID<br/><!--              Row           Column<br/>-->
|
||||||
{% for sample in samples %}
|
{% for sample in samples %}
|
||||||
{% if rsl_plate_num %}<input type="checkbox" id="{{ sample['submission_rank'] }}_enabled" name="vehicle1" value="Bike" {% if sample['enabled'] %}checked{% endif %}>{% endif %}
|
{% if rsl_plate_number %}<input type="checkbox" id="{{ sample['submission_rank'] }}_enabled" name="vehicle1" value="Bike" {% if sample['enabled'] %}checked{% endif %}>{% endif %}
|
||||||
{{ '%02d' % sample['submission_rank'] }}
|
{{ '%02d' % sample['submission_rank'] }}
|
||||||
<input type="text" id="{{ sample['submission_rank'] }}_id" name="sample_id" value="{{ sample['sample_id'] }}" size="40" style="color:{{ sample['color'] }};" {% if rsl_plate_num %}disabled{% endif %}>
|
<input type="text" id="{{ sample['submission_rank'] }}_id" name="sample_id" value="{{ sample['sample_id'] }}" size="40" style="color:{{ sample['color'] }};" {% if rsl_plate_number %}disabled{% endif %}>
|
||||||
<!-- <input type="number" id="{{ sample['submission_rank'] }}_row" name="row" value="{{ sample['row'] }}" size="5", min="1">-->
|
|
||||||
<!-- <input type="number" id="{{ sample['submission_rank'] }}_col" name="column" value="{{ sample['column'] }}" size="5", min="1">-->
|
|
||||||
<br/>
|
<br/>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{{ super() }}
|
|
||||||
<script>
|
<script>
|
||||||
{% for sample in samples %}
|
{% for sample in samples %}
|
||||||
document.getElementById("{{ sample['submission_rank'] }}_id").addEventListener("input", function(){
|
document.getElementById("{{ sample['submission_rank'] }}_id").addEventListener("input", function(){
|
||||||
backend.text_changed("{{ sample['submission_rank'] }}", this.name, this.value);
|
backend.text_changed("{{ sample['submission_rank'] }}", this.name, this.value);
|
||||||
});
|
});
|
||||||
{% if rsl_plate_num %}
|
{% if rsl_plate_number %}
|
||||||
document.getElementById("{{ sample['submission_rank'] }}_enabled").addEventListener("input", function(){
|
document.getElementById("{{ sample['submission_rank'] }}_enabled").addEventListener("change", function(){
|
||||||
backend.enable_sample("{{ sample['submission_rank'] }}", this.checked);
|
console.log(typeof({{ sample['submission_rank'] }}) + " " + typeof(this.checked));
|
||||||
|
backend.enable_sample({{ sample['submission_rank'] }}, this.checked);
|
||||||
});
|
});
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
document.getElementById("rsl_plate_number").addEventListener("input", function(){
|
||||||
|
console.log(this.value);
|
||||||
|
console.log(typeof(this.value));
|
||||||
|
backend.set_rsl_plate_number(this.value);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
backend.activate_export(false);
|
backend.activate_export(false);
|
||||||
}, false);
|
}, false);
|
||||||
document.getElementById("rsl_plate_num").addEventListener("input", function(){
|
|
||||||
backend.set_rsl_plate_num(this.value);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
{{ super() }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user