Moments before disaster.

This commit is contained in:
lwark
2024-12-06 12:02:39 -06:00
parent 5fc02ffeec
commit 80527355d1
23 changed files with 157 additions and 325 deletions

View File

@@ -1,7 +1,6 @@
"""
Constructs main application.
"""
import os
from pprint import pformat
from PyQt6.QtCore import qInstallMessageHandler
from PyQt6.QtWidgets import (
@@ -18,12 +17,11 @@ from tools import check_if_app, Settings, Report, jinja_template_loading, check_
from .functions import select_save_file, select_open_file
from datetime import date
from .pop_ups import HTMLPop, AlertPop
from .misc import LogParser, Pagifier
from .misc import Pagifier
import logging, webbrowser, sys, shutil
from .submission_table import SubmissionsSheet
from .submission_widget import SubmissionFormContainer
from .controls_chart import ControlsViewer
# from .sample_search import SampleSearchBox
from .summary import Summary
from .turnaround import TurnaroundTime
from .omni_search import SearchBox
@@ -84,7 +82,7 @@ class App(QMainWindow):
fileMenu.addAction(self.importAction)
fileMenu.addAction(self.yamlExportAction)
fileMenu.addAction(self.yamlImportAction)
methodsMenu.addAction(self.searchLog)
# methodsMenu.addAction(self.searchLog)
methodsMenu.addAction(self.searchSample)
maintenanceMenu.addAction(self.joinExtractionAction)
maintenanceMenu.addAction(self.joinPCRAction)
@@ -98,8 +96,8 @@ class App(QMainWindow):
toolbar = QToolBar("My main toolbar")
self.addToolBar(toolbar)
toolbar.addAction(self.addReagentAction)
toolbar.addAction(self.addKitAction)
toolbar.addAction(self.addOrgAction)
# toolbar.addAction(self.addKitAction)
# toolbar.addAction(self.addOrgAction)
def _createActions(self):
"""
@@ -108,13 +106,13 @@ class App(QMainWindow):
# logger.debug(f"Creating actions...")
self.importAction = QAction("&Import Submission", self)
self.addReagentAction = QAction("Add Reagent", self)
self.addKitAction = QAction("Import Kit", self)
self.addOrgAction = QAction("Import Org", self)
# self.addKitAction = QAction("Import Kit", self)
# self.addOrgAction = QAction("Import Org", self)
self.joinExtractionAction = QAction("Link Extraction Logs")
self.joinPCRAction = QAction("Link PCR Logs")
self.helpAction = QAction("&About", self)
self.docsAction = QAction("&Docs", self)
self.searchLog = QAction("Search Log", self)
# self.searchLog = QAction("Search Log", self)
self.searchSample = QAction("Search Sample", self)
self.githubAction = QAction("Github", self)
self.yamlExportAction = QAction("Export Type Example", self)
@@ -132,14 +130,13 @@ class App(QMainWindow):
self.joinPCRAction.triggered.connect(self.table_widget.sub_wid.link_pcr)
self.helpAction.triggered.connect(self.showAbout)
self.docsAction.triggered.connect(self.openDocs)
self.searchLog.triggered.connect(self.runSearch)
# self.searchLog.triggered.connect(self.runSearch)
self.searchSample.triggered.connect(self.runSampleSearch)
self.githubAction.triggered.connect(self.openGithub)
self.yamlExportAction.triggered.connect(self.export_ST_yaml)
self.yamlImportAction.triggered.connect(self.import_ST_yaml)
self.table_widget.pager.current_page.textChanged.connect(self.update_data)
self.editReagentAction.triggered.connect(self.edit_reagent)
self.destroyed.connect(self.final_commit)
def showAbout(self):
"""
@@ -180,15 +177,14 @@ class App(QMainWindow):
instr = HTMLPop(html=html, title="Instructions")
instr.exec()
def runSearch(self):
dlg = LogParser(self)
dlg.exec()
# def runSearch(self):
# dlg = LogParser(self)
# dlg.exec()
def runSampleSearch(self):
"""
Create a search for samples.
"""
# dlg = SampleSearchBox(self)
dlg = SearchBox(self, object_type=BasicSample, extras=[])
dlg.exec()
@@ -244,7 +240,6 @@ class App(QMainWindow):
st = SubmissionType.import_from_json(filepath=fname)
if st:
# NOTE: Do not delete the print statement below.
# print(pformat(st.to_export_dict()))
choice = input("Save the above submission type? [y/N]: ")
if choice.lower() == "y":
pass
@@ -254,9 +249,6 @@ class App(QMainWindow):
def update_data(self):
self.table_widget.sub_wid.setData(page=self.table_widget.pager.page_anchor, page_size=page_size)
def final_commit(self):
logger.debug("Running final commit")
self.ctx.database_session.commit()
class AddSubForm(QWidget):

View File

@@ -10,9 +10,10 @@ from PyQt6.QtWidgets import (
from PyQt6.QtCore import QSignalBlocker
from backend.db import ControlType, IridaControl
import logging
from tools import Report, report_result
from tools import Report, report_result, Result
from frontend.visualizations import CustomFigure
from .misc import StartEndDatePicker
from .info_tab import InfoPane
logger = logging.getLogger(f"submissions.{__name__}")
@@ -37,11 +38,11 @@ class ControlsViewer(QWidget):
# NOTE: fetch types of controls
con_sub_types = [item for item in self.archetype.targets.keys()]
self.control_sub_typer.addItems(con_sub_types)
# NOTE: create custom widget to get types of analysis
# NOTE: create custom widget to get types of analysis -- disabled by PCR control
self.mode_typer = QComboBox()
mode_types = IridaControl.get_modes()
self.mode_typer.addItems(mode_types)
# NOTE: create custom widget to get subtypes of analysis
# NOTE: create custom widget to get subtypes of analysis -- disabled by PCR control
self.mode_sub_typer = QComboBox()
self.mode_sub_typer.setEnabled(False)
# NOTE: add widgets to tab2 layout
@@ -83,15 +84,15 @@ class ControlsViewer(QWidget):
pass
# NOTE: correct start date being more recent than end date and rerun
if self.datepicker.start_date.date() > self.datepicker.end_date.date():
logger.warning("Start date after end date is not allowed!")
threemonthsago = self.datepicker.end_date.date().addDays(-60)
# NOTE: block signal that will rerun controls getter and set start date
# Without triggering this function again
msg = f"Start date after end date is not allowed! Setting to {threemonthsago.toString()}."
logger.warning(msg)
# NOTE: block signal that will rerun controls getter and set start date Without triggering this function again
with QSignalBlocker(self.datepicker.start_date) as blocker:
self.datepicker.start_date.setDate(threemonthsago)
self.controls_getter()
self.report.add_result(report)
return
self.controls_getter_function()
report.add_result(Result(owner=self.__str__(), msg=msg, status="Warning"))
return report
# NOTE: convert to python useable date objects
self.start_date = self.datepicker.start_date.date().toPyDate()
self.end_date = self.datepicker.end_date.date().toPyDate()
@@ -167,4 +168,3 @@ class ControlsViewer(QWidget):
self.webengineview.update()
# logger.debug("Figure updated... I hope.")
return report

View File

@@ -1,7 +1,6 @@
'''
Creates forms that the user can enter equipment info into.
'''
import time
from pprint import pformat
from PyQt6.QtCore import Qt, QSignalBlocker
from PyQt6.QtWidgets import (QDialog, QComboBox, QCheckBox,

View File

@@ -66,7 +66,6 @@ class GelBox(QDialog):
layout.addWidget(self.imv, 0, 1, 20, 20)
# NOTE: setting this widget as central widget of the main window
try:
# control_info = sorted(self.submission.gel_controls, key=lambda d: d['location'])
control_info = sorted(self.submission.gel_controls, key=itemgetter('location'))
except KeyError:
control_info = None
@@ -79,7 +78,6 @@ class GelBox(QDialog):
layout.addWidget(self.buttonBox, 23, 1, 1, 1)
self.setLayout(layout)
def parse_form(self) -> Tuple[str, str | Path, list]:
"""
Get relevant values from self/form
@@ -124,7 +122,6 @@ class ControlsForm(QWidget):
self.layout.addWidget(label, iii, 1, 1, 1)
for iii in range(3):
for jjj in range(3):
# widge = QLineEdit()
widge = QComboBox()
widge.addItems(['Neg', 'Pos'])
widge.setCurrentIndex(0)

View File

@@ -1,6 +1,11 @@
"""
A pane to show info e.g. cost reports and turnaround times.
TODO: Can I merge this with the controls chart pane?
"""
from PyQt6.QtCore import QSignalBlocker
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtWidgets import QWidget, QGridLayout, QPushButton
from tools import Report
from PyQt6.QtWidgets import QWidget, QGridLayout
from tools import Report, report_result, Result
from .misc import StartEndDatePicker, save_pdf
from .functions import select_save_file
import logging
@@ -17,22 +22,29 @@ class InfoPane(QWidget):
self.report = Report()
self.datepicker = StartEndDatePicker(default_start=-31)
self.webview = QWebEngineView()
self.datepicker.start_date.dateChanged.connect(self.date_changed)
self.datepicker.end_date.dateChanged.connect(self.date_changed)
self.datepicker.start_date.dateChanged.connect(self.update_data)
self.datepicker.end_date.dateChanged.connect(self.update_data)
self.layout = QGridLayout(self)
self.layout.addWidget(self.datepicker, 0, 0, 1, 2)
self.save_excel_button = QPushButton("Save Excel", parent=self)
self.save_excel_button.pressed.connect(self.save_excel)
self.save_pdf_button = QPushButton("Save PDF", parent=self)
self.save_pdf_button.pressed.connect(self.save_pdf)
self.layout.addWidget(self.save_excel_button, 0, 2, 1, 1)
self.layout.addWidget(self.save_pdf_button, 0, 3, 1, 1)
self.layout.addWidget(self.webview, 2, 0, 1, 4)
self.setLayout(self.layout)
def date_changed(self):
@report_result
def update_data(self, *args, **kwargs):
report = Report()
self.start_date = self.datepicker.start_date.date().toPyDate()
self.end_date = self.datepicker.end_date.date().toPyDate()
if self.datepicker.start_date.date() > self.datepicker.end_date.date():
lastmonth = self.datepicker.end_date.date().addDays(-31)
msg = f"Start date after end date is not allowed! Setting to {lastmonth.toString()}."
logger.warning(msg)
# NOTE: block signal that will rerun controls getter and set start date
# Without triggering this function again
with QSignalBlocker(self.datepicker.start_date) as blocker:
self.datepicker.start_date.setDate(lastmonth)
self.update_data()
report.add_result(Result(owner=self.__str__(), msg=msg, status="Warning"))
return report
def save_excel(self):
fname = select_save_file(self, default_name=f"Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}", extension="xlsx")
@@ -42,4 +54,10 @@ class InfoPane(QWidget):
fname = select_save_file(obj=self,
default_name=f"Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}",
extension="pdf")
save_pdf(obj=self.webview, filename=fname)
save_pdf(obj=self.webview, filename=fname)
def save_png(self):
fname = select_save_file(obj=self,
default_name=f"Plotly {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}",
extension="png")
self.fig.write_image(fname.absolute().__str__(), engine="kaleido")

View File

@@ -14,8 +14,6 @@ from PyQt6.QtCore import Qt, QDate, QSize, QMarginsF
from tools import jinja_template_loading
from backend.db.models import *
import logging
from .pop_ups import AlertPop
from .functions import select_open_file
logger = logging.getLogger(f"submissions.{__name__}")
@@ -114,55 +112,6 @@ class AddReagentForm(QDialog):
self.name_input.addItems(list(set([item.name for item in lookup])))
class LogParser(QDialog):
def __init__(self, parent):
super().__init__(parent)
self.app = self.parent()
self.filebutton = QPushButton(self)
self.filebutton.setText("Import File")
self.phrase_looker = QComboBox(self)
self.phrase_looker.setEditable(True)
self.btn = QPushButton(self)
self.btn.setText("Search")
self.layout = QFormLayout(self)
self.layout.addRow(self.tr("&File:"), self.filebutton)
self.layout.addRow(self.tr("&Search Term:"), self.phrase_looker)
self.layout.addRow(self.btn)
self.filebutton.clicked.connect(self.filelookup)
self.btn.clicked.connect(self.runsearch)
self.setMinimumWidth(400)
def filelookup(self):
"""
Select file to search
"""
self.fname = select_open_file(self, "tabular")
def runsearch(self):
"""
Gets total/percent occurences of string in tabular file.
"""
count: int = 0
total: int = 0
# logger.debug(f"Current search term: {self.phrase_looker.currentText()}")
try:
with open(self.fname, "r") as f:
for chunk in readInChunks(fileObj=f):
total += len(chunk)
for line in chunk:
if self.phrase_looker.currentText().lower() in line.lower():
count += 1
percent = (count / total) * 100
msg = f"I found {count} instances of the search phrase out of {total} = {percent:.2f}%."
status = "Information"
except AttributeError:
msg = f"No file was selected."
status = "Error"
dlg = AlertPop(message=msg, status=status)
dlg.exec()
class StartEndDatePicker(QWidget):
"""
custom widget to pick start and end dates for controls graphs

View File

@@ -16,6 +16,9 @@ logger = logging.getLogger(f"submissions.{__name__}")
class SearchBox(QDialog):
"""
The full search widget.
"""
def __init__(self, parent, object_type: Any, extras: List[str], **kwargs):
super().__init__(parent)
@@ -36,7 +39,7 @@ class SearchBox(QDialog):
else:
self.sub_class = None
self.results = SearchResults(parent=self, object_type=self.object_type, extras=self.extras, **kwargs)
logger.debug(f"results: {self.results}")
# logger.debug(f"results: {self.results}")
self.layout.addWidget(self.results, 5, 0)
self.setLayout(self.layout)
self.setWindowTitle(f"Search {self.object_type.__name__}")
@@ -51,6 +54,7 @@ class SearchBox(QDialog):
# logger.debug(deletes)
for item in deletes:
item.setParent(None)
# NOTE: Handle any subclasses
if not self.sub_class:
self.update_data()
else:
@@ -89,6 +93,9 @@ class SearchBox(QDialog):
class FieldSearch(QWidget):
"""
Search bar.
"""
def __init__(self, parent, label, field_name):
super().__init__(parent)
@@ -115,6 +122,9 @@ class FieldSearch(QWidget):
class SearchResults(QTableView):
"""
Results table.
"""
def __init__(self, parent: SearchBox, object_type: Any, extras: List[str], **kwargs):
super().__init__()
@@ -146,7 +156,6 @@ class SearchResults(QTableView):
context = {item['name']: x.sibling(x.row(), item['column']).data() for item in self.columns_of_interest}
logger.debug(f"Context: {context}")
try:
# object = self.object_type.query(**{self.object_type.searchables: context[self.object_type.searchables]})
object = self.object_type.query(**context)
except KeyError:
object = None

View File

@@ -42,7 +42,7 @@ class SubmissionDetails(QDialog):
# NOTE: button to export a pdf version
self.btn = QPushButton("Export PDF")
self.btn.setFixedWidth(775)
self.btn.clicked.connect(self.export)
self.btn.clicked.connect(self.save_pdf)
self.back = QPushButton("Back")
self.back.setFixedWidth(100)
# self.back.clicked.connect(self.back_function)
@@ -181,7 +181,7 @@ class SubmissionDetails(QDialog):
submission.save()
self.submission_details(submission=self.rsl_plate_num)
def export(self):
def save_pdf(self):
"""
Renders submission to html, then creates and saves .pdf file to user selected file.
"""

View File

@@ -83,6 +83,7 @@ class SubmissionsSheet(QTableView):
self.resizeRowsToContents()
self.setSortingEnabled(True)
self.doubleClicked.connect(lambda x: BasicSubmission.query(id=x.sibling(x.row(), 0).data()).show_details(self))
# NOTE: Have to run native query here because mine just returns results?
self.total_count = BasicSubmission.__database_session__.query(BasicSubmission).count()
def setData(self, page: int = 1, page_size: int = 250) -> None:

View File

@@ -1,15 +1,13 @@
'''
Contains all submission related frontend functions
'''
import sys
from PyQt6.QtWidgets import (
QWidget, QPushButton, QVBoxLayout,
QComboBox, QDateEdit, QLineEdit, QLabel
)
from PyQt6.QtCore import pyqtSignal, Qt
from . import select_open_file, select_save_file
import logging, difflib
import logging
from pathlib import Path
from tools import Report, Result, check_not_nan, main_form_style, report_result
from backend.excel.parser import SheetParser
@@ -187,6 +185,8 @@ class SubmissionFormContainer(QWidget):
class SubmissionFormWidget(QWidget):
update_reagent_fields = ['extraction_kit']
def __init__(self, parent: QWidget, submission: PydSubmission, disable: list | None = None) -> None:
super().__init__(parent)
# logger.debug(f"Disable: {disable}")
@@ -203,7 +203,7 @@ class SubmissionFormWidget(QWidget):
# logger.debug(f"Attempting to extend ignore list with {self.pyd.submission_type['value']}")
self.layout = QVBoxLayout()
for k in list(self.pyd.model_fields.keys()) + list(self.pyd.model_extra.keys()):
logger.debug(f"Creating widget: {k}")
# logger.debug(f"Creating widget: {k}")
if k in self.ignore:
logger.warning(f"{k} in form_ignore {self.ignore}, not creating widget")
continue
@@ -225,10 +225,10 @@ class SubmissionFormWidget(QWidget):
sub_obj=st, disable=check)
if add_widget is not None:
self.layout.addWidget(add_widget)
if k == "extraction_kit":
# if k == "extraction_kit":
if k in self.__class__.update_reagent_fields:
add_widget.input.currentTextChanged.connect(self.scrape_reagents)
self.setStyleSheet(main_form_style)
# self.scrape_reagents(self.pyd.extraction_kit)
self.scrape_reagents(self.extraction_kit)
def create_widget(self, key: str, value: dict | PydReagent, submission_type: str | SubmissionType | None = None,
@@ -293,9 +293,8 @@ class SubmissionFormWidget(QWidget):
if isinstance(reagent, self.ReagentFormWidget) or isinstance(reagent, QPushButton):
reagent.setParent(None)
reagents, integrity_report = self.pyd.check_kit_integrity(extraction_kit=self.extraction_kit)
logger.debug(f"Got reagents: {pformat(reagents)}")
# logger.debug(f"Got reagents: {pformat(reagents)}")
for reagent in reagents:
# add_widget = self.ReagentFormWidget(parent=self, reagent=reagent, extraction_kit=self.pyd.extraction_kit)
add_widget = self.ReagentFormWidget(parent=self, reagent=reagent, extraction_kit=self.extraction_kit)
self.layout.addWidget(add_widget)
report.add_result(integrity_report)
@@ -334,10 +333,6 @@ class SubmissionFormWidget(QWidget):
query = [widget for widget in query if widget.objectName() == object_name]
return query
# def update_pyd(self):
# results = self.parse_form()
# logger.debug(pformat(results))
@report_result
def submit_new_sample_function(self, *args) -> Report:
"""
@@ -538,19 +533,14 @@ class SubmissionFormWidget(QWidget):
except (TypeError, KeyError):
pass
obj = parent.parent().parent()
logger.debug(f"Object: {obj}")
logger.debug(f"Parent: {parent.parent()}")
# logger.debug(f"Object: {obj}")
# logger.debug(f"Parent: {parent.parent()}")
# logger.debug(f"Creating widget for: {key}")
match key:
case 'submitting_lab':
add_widget = MyQComboBox(scrollWidget=parent)
# NOTE: lookup organizations suitable for submitting_lab (ctx: self.InfoItem.SubmissionFormWidget.SubmissionFormContainer.AddSubForm )
labs = [item.name for item in Organization.query()]
# NOTE: try to set closest match to top of list
# try:
# labs = difflib.get_close_matches(value, labs, len(labs), 0)
# except (TypeError, ValueError):
# pass
if isinstance(value, dict):
value = value['value']
if isinstance(value, Organization):
@@ -559,7 +549,7 @@ class SubmissionFormWidget(QWidget):
looked_up_lab = Organization.query(name=value, limit=1)
except AttributeError:
looked_up_lab = None
logger.debug(f"\n\nLooked up lab: {looked_up_lab}")
# logger.debug(f"\n\nLooked up lab: {looked_up_lab}")
if looked_up_lab:
try:
labs.remove(str(looked_up_lab.name))
@@ -579,7 +569,6 @@ class SubmissionFormWidget(QWidget):
add_widget = MyQComboBox(scrollWidget=parent)
# NOTE: lookup existing kits by 'submission_type' decided on by sheetparser
# logger.debug(f"Looking up kits used for {submission_type}")
# uses = [item.name for item in KitType.query(used_for=submission_type)]
uses = [item.name for item in submission_type.kit_types]
obj.uses = uses
# logger.debug(f"Kits received for {submission_type}: {uses}")

View File

@@ -1,12 +1,11 @@
from PyQt6.QtCore import QSignalBlocker
from PyQt6.QtWebEngineWidgets import QWebEngineView
"""
Pane to hold information e.g. cost summary.
"""
from .info_tab import InfoPane
from PyQt6.QtWidgets import QWidget, QGridLayout, QPushButton, QLabel
from PyQt6.QtWidgets import QWidget, QLabel, QPushButton
from backend.db import Organization
from backend.excel import ReportMaker
from tools import Report
from .misc import StartEndDatePicker, save_pdf, CheckableComboBox
from .functions import select_save_file
from .misc import CheckableComboBox
import logging
logger = logging.getLogger(f"submissions.{__name__}")
@@ -16,32 +15,27 @@ class Summary(InfoPane):
def __init__(self, parent: QWidget) -> None:
super().__init__(parent)
self.save_excel_button = QPushButton("Save Excel", parent=self)
self.save_excel_button.pressed.connect(self.save_excel)
self.save_pdf_button = QPushButton("Save PDF", parent=self)
self.save_pdf_button.pressed.connect(self.save_pdf)
self.layout.addWidget(self.save_excel_button, 0, 2, 1, 1)
self.layout.addWidget(self.save_pdf_button, 0, 3, 1, 1)
self.org_select = CheckableComboBox()
self.org_select.setEditable(False)
self.org_select.addItem("Select", header=True)
for org in [org.name for org in Organization.query()]:
self.org_select.addItem(org)
self.org_select.model().itemChanged.connect(self.date_changed)
self.org_select.model().itemChanged.connect(self.update_data)
self.layout.addWidget(QLabel("Client"), 1, 0, 1, 1)
self.layout.addWidget(self.org_select, 1, 1, 1, 3)
self.date_changed()
self.update_data()
def date_changed(self):
def update_data(self):
super().update_data()
orgs = [self.org_select.itemText(i) for i in range(self.org_select.count()) if self.org_select.itemChecked(i)]
if self.datepicker.start_date.date() > self.datepicker.end_date.date():
logger.warning("Start date after end date is not allowed!")
lastmonth = self.datepicker.end_date.date().addDays(-31)
# NOTE: block signal that will rerun controls getter and set start date
# Without triggering this function again
with QSignalBlocker(self.datepicker.start_date) as blocker:
self.datepicker.start_date.setDate(lastmonth)
self.date_changed()
return
# NOTE: convert to python useable date objects
# self.start_date = self.datepicker.start_date.date().toPyDate()
# self.end_date = self.datepicker.end_date.date().toPyDate()
super().date_changed()
logger.debug(f"Getting report from {self.start_date} to {self.end_date} using {orgs}")
# logger.debug(f"Getting report from {self.start_date} to {self.end_date} using {orgs}")
self.report_obj = ReportMaker(start_date=self.start_date, end_date=self.end_date, organizations=orgs)
self.webview.setHtml(self.report_obj.html)
if self.report_obj.subs:
@@ -50,13 +44,3 @@ class Summary(InfoPane):
else:
self.save_pdf_button.setEnabled(False)
self.save_excel_button.setEnabled(False)
# def save_excel(self):
# fname = select_save_file(self, default_name=f"Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}", extension="xlsx")
# self.report_obj.write_report(fname, obj=self)
#
# def save_pdf(self):
# fname = select_save_file(obj=self,
# default_name=f"Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}",
# extension="pdf")
# save_pdf(obj=self.webview, filename=fname)

View File

@@ -15,28 +15,25 @@ class TurnaroundTime(InfoPane):
def __init__(self, parent: QWidget):
super().__init__(parent)
self.chart = None
self.save_button = QPushButton("Save Chart", parent=self)
self.save_button.pressed.connect(self.save_png)
self.layout.addWidget(self.save_button, 0, 2, 1, 1)
self.export_button = QPushButton("Save Data", parent=self)
self.export_button.pressed.connect(self.save_excel)
self.layout.addWidget(self.export_button, 0, 3, 1, 1)
self.fig = None
self.report_object = None
self.submission_typer = QComboBox(self)
subs = ["Any"] + [item.name for item in SubmissionType.query()]
subs = ["All"] + [item.name for item in SubmissionType.query()]
self.submission_typer.addItems(subs)
self.layout.addWidget(self.submission_typer, 1, 1, 1, 3)
self.submission_typer.currentTextChanged.connect(self.date_changed)
self.date_changed()
self.submission_typer.currentTextChanged.connect(self.update_data)
self.update_data()
def date_changed(self):
if self.datepicker.start_date.date() > self.datepicker.end_date.date():
logger.warning("Start date after end date is not allowed!")
lastmonth = self.datepicker.end_date.date().addDays(-31)
# NOTE: block signal that will rerun controls getter and set start date
# Without triggering this function again
with QSignalBlocker(self.datepicker.start_date) as blocker:
self.datepicker.start_date.setDate(lastmonth)
self.date_changed()
return
super().date_changed()
def update_data(self):
super().update_data()
chart_settings = dict(start_date=self.start_date, end_date=self.end_date)
if self.submission_typer.currentText() == "Any":
if self.submission_typer.currentText() == "All":
submission_type = None
subtype_obj = None
else:
@@ -47,5 +44,5 @@ class TurnaroundTime(InfoPane):
threshold = subtype_obj.defaults['turnaround_time'] + 0.5
else:
threshold = None
self.chart = TurnaroundChart(df=self.report_obj.df, settings=chart_settings, modes=[], threshold=threshold)
self.webview.setHtml(self.chart.to_html())
self.fig = TurnaroundChart(df=self.report_obj.df, settings=chart_settings, modes=[], threshold=threshold)
self.webview.setHtml(self.fig.to_html())