generated from dopt-python/py311
added page for consulting sessions with dynamic table
This commit is contained in:
+411
-98
@@ -28,7 +28,7 @@ from PySide6.QtCore import (
|
||||
Signal,
|
||||
qInstallMessageHandler,
|
||||
)
|
||||
from PySide6.QtGui import QAction
|
||||
from PySide6.QtGui import QAction, QFont
|
||||
from PySide6.QtWidgets import (
|
||||
QAbstractItemView,
|
||||
QApplication,
|
||||
@@ -77,6 +77,7 @@ from wce_crm.logging import (
|
||||
logger_auto_form,
|
||||
logger_get_data,
|
||||
logger_gui,
|
||||
logger_page_consulting,
|
||||
)
|
||||
from wce_crm.types import ExtMaId, InitRecId, UserId
|
||||
|
||||
@@ -2883,29 +2884,40 @@ class MasterDataFormWidget(QWidget):
|
||||
|
||||
@dc.dataclass(slots=True)
|
||||
class Session:
|
||||
user_id: UserId | None = None
|
||||
user_name: str | None = None
|
||||
user_id: UserId
|
||||
user_name: str
|
||||
|
||||
|
||||
@dc.dataclass(slots=True)
|
||||
class ConsultingSession:
|
||||
user_id: UserId
|
||||
user_name: str
|
||||
timestamp: datetime.datetime
|
||||
partner: str
|
||||
interaction_scheme: str
|
||||
topic: str # TODO should be linked to something, target unclear (need specification by customer)
|
||||
notes: str
|
||||
response: str
|
||||
class Page_Consulting_ConsultingSession_State:
|
||||
user_id: UserId # must be set with the session (always known)
|
||||
user_name: str # must be set with the session (always known)
|
||||
cons_session_id: int | None = None # known and not known entries
|
||||
timestamp: datetime.datetime = dc.field(
|
||||
default_factory=lambda: datetime.datetime.now(tz=datetime.UTC)
|
||||
)
|
||||
partner: str = ""
|
||||
interaction_scheme: str = "" # set string like in other dropdowns or use integer (enum)
|
||||
topic: str = "" # TODO should be linked to something, target unclear (need specification by customer)
|
||||
notes: str = ""
|
||||
response: str = ""
|
||||
|
||||
|
||||
@dc.dataclass(slots=True)
|
||||
class Page_Consulting_Table_State:
|
||||
rows: list[Page_Consulting_ConsultingSession] = dc.field(default_factory=list)
|
||||
row_states: list[Page_Consulting_ConsultingSession_State] = dc.field(default_factory=list)
|
||||
|
||||
|
||||
@dc.dataclass(slots=True)
|
||||
class Page_Consulting_State:
|
||||
session: Session | None = None
|
||||
session: Session
|
||||
un_id: InitRecId | None = None
|
||||
pers_id: InitRecId | None = None
|
||||
cons_type: ConsultingType | None = None
|
||||
cons_sessions: list[ConsultingSession] = dc.field(default_factory=list)
|
||||
cons_sessions: list[Page_Consulting_ConsultingSession_State] = dc.field(
|
||||
default_factory=list
|
||||
)
|
||||
|
||||
|
||||
class Page_Consulting(QWidget):
|
||||
@@ -2920,10 +2932,8 @@ class Page_Consulting(QWidget):
|
||||
session: Session,
|
||||
):
|
||||
super().__init__()
|
||||
self.session = session
|
||||
|
||||
# state management
|
||||
self.STATE = Page_Consulting_State()
|
||||
self.STATE = Page_Consulting_State(session=session)
|
||||
|
||||
# self.current_id: InitRecId = -1
|
||||
# self.COMPANY_FETAURES_MASTER_DATA: dict[str, str] = {
|
||||
@@ -2951,7 +2961,7 @@ class Page_Consulting(QWidget):
|
||||
# --- HEADER ---
|
||||
header_container = QWidget()
|
||||
header_container.setMinimumWidth(700)
|
||||
header_container.setMaximumWidth(1200)
|
||||
header_container.setMaximumWidth(1500)
|
||||
header_container.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
header_layout = QVBoxLayout(header_container)
|
||||
header_layout.setContentsMargins(0, 0, 0, 10)
|
||||
@@ -2984,7 +2994,7 @@ class Page_Consulting(QWidget):
|
||||
scroll_area = QScrollArea()
|
||||
scroll_area.setWidgetResizable(True)
|
||||
scroll_area.setMinimumWidth(700)
|
||||
scroll_area.setMaximumWidth(1200)
|
||||
scroll_area.setMaximumWidth(1500)
|
||||
scroll_area.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||
# optional: remove frame to look more modern
|
||||
scroll_area.setFrameShape(QFrame.Shape.NoFrame)
|
||||
@@ -3009,6 +3019,9 @@ class Page_Consulting(QWidget):
|
||||
# layout_change_title.addWidget(change_title_btn)
|
||||
# change_title_btn.clicked.connect(self.set_company_name)
|
||||
# container_layout.addLayout(layout_change_title)
|
||||
btn_get_data_table = QPushButton("Call 'get_data' from table")
|
||||
btn_get_data_table.clicked.connect(self._debug_get_data_table)
|
||||
container_layout.addWidget(btn_get_data_table)
|
||||
|
||||
separator2 = QFrame()
|
||||
separator2.setFrameShape(QFrame.Shape.HLine)
|
||||
@@ -3033,24 +3046,28 @@ class Page_Consulting(QWidget):
|
||||
type_layout.addWidget(self.type_pauschal_btn)
|
||||
type_layout.addWidget(self.type_individual_btn)
|
||||
|
||||
container_layout.addSpacing(20)
|
||||
# container_layout.addSpacing(50)
|
||||
table_state = Page_Consulting_Table_State()
|
||||
self.table_sessions = Page_Consulting_Table(site_state=self.STATE, state=table_state)
|
||||
container_layout.addWidget(self.table_sessions)
|
||||
# container_layout.addSpacing(50)
|
||||
|
||||
self.layout_sessions = QVBoxLayout()
|
||||
self.layout_sessions.setContentsMargins(0, 0, 0, 0)
|
||||
container_layout.addLayout(self.layout_sessions)
|
||||
self.btn_add_cons_session = QPushButton("+ Hinzufügen")
|
||||
self.btn_add_cons_session.setStyleSheet(
|
||||
"color: #0369a1; font-weight: bold; border: 1px dashed #0369a1; padding: 5px;"
|
||||
)
|
||||
self.btn_add_cons_session.clicked.connect(self.add_cons_entry)
|
||||
self.layout_sessions.addWidget(self.btn_add_cons_session)
|
||||
self.layout_sessions.addStretch(1)
|
||||
# self.layout_sessions = QVBoxLayout()
|
||||
# self.layout_sessions.setContentsMargins(0, 0, 0, 0)
|
||||
# container_layout.addLayout(self.layout_sessions)
|
||||
# self.btn_add_cons_session = QPushButton("+ Hinzufügen")
|
||||
# self.btn_add_cons_session.setStyleSheet(
|
||||
# "color: #0369a1; font-weight: bold; border: 1px dashed #0369a1; padding: 5px;"
|
||||
# )
|
||||
# self.btn_add_cons_session.clicked.connect(self.add_cons_entry)
|
||||
# self.layout_sessions.addWidget(self.btn_add_cons_session)
|
||||
# self.layout_sessions.addStretch(1)
|
||||
|
||||
self.cons_entries: list[QWidget] = []
|
||||
# self.cons_entries: list[QWidget] = []
|
||||
|
||||
# self.layout_sessions.addStretch()
|
||||
|
||||
container_layout.addStretch()
|
||||
# container_layout.addStretch()
|
||||
|
||||
# --- STYLE ---
|
||||
self.setStyleSheet("""
|
||||
@@ -3084,45 +3101,53 @@ class Page_Consulting(QWidget):
|
||||
# }
|
||||
# """)
|
||||
|
||||
def add_cons_entry(self) -> None:
|
||||
logger_gui.debug("[Consulting Page] Adding entry...")
|
||||
# def add_cons_entry(self) -> None:
|
||||
# logger_gui.debug("[Consulting Page] Adding entry...")
|
||||
|
||||
row_widget = QWidget()
|
||||
entry_row = QHBoxLayout(row_widget)
|
||||
entry_fields = QHBoxLayout()
|
||||
entry_row.addLayout(entry_fields)
|
||||
# row_widget = QWidget()
|
||||
# entry_row = QHBoxLayout(row_widget)
|
||||
# entry_fields = QHBoxLayout()
|
||||
# entry_row.addLayout(entry_fields)
|
||||
|
||||
txt1 = QLineEdit()
|
||||
txt2 = QPlainTextEdit()
|
||||
txt2.setMaximumHeight(100)
|
||||
entry_fields.addWidget(txt1)
|
||||
entry_fields.addWidget(txt2)
|
||||
# txt1 = QLineEdit()
|
||||
# txt2 = QPlainTextEdit()
|
||||
# txt2.setMaximumHeight(100)
|
||||
# entry_fields.addWidget(txt1)
|
||||
# entry_fields.addWidget(txt2)
|
||||
|
||||
del_btn = QPushButton("🗑️")
|
||||
del_btn.setFixedSize(30, 30)
|
||||
# Lambda with default parameter to delete exactly this(!) box
|
||||
del_btn.clicked.connect(
|
||||
lambda checked=False, widget=row_widget: self.remove_cons_entry(widget)
|
||||
)
|
||||
entry_row.addWidget(del_btn)
|
||||
# del_btn = QPushButton("🗑️")
|
||||
# del_btn.setFixedSize(30, 30)
|
||||
# # Lambda with default parameter to delete exactly this(!) box
|
||||
# del_btn.clicked.connect(
|
||||
# lambda checked=False, widget=row_widget: self.remove_cons_entry(widget)
|
||||
# )
|
||||
# entry_row.addWidget(del_btn)
|
||||
|
||||
row_widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
|
||||
# row_widget.setMaximumHeight(200)
|
||||
# row_widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
|
||||
# # row_widget.setMaximumHeight(200)
|
||||
|
||||
self.cons_entries.append(row_widget)
|
||||
self.layout_sessions.insertWidget(self.layout_sessions.count() - 2, row_widget)
|
||||
# self.cons_entries.append(row_widget)
|
||||
# self.layout_sessions.insertWidget(self.layout_sessions.count() - 2, row_widget)
|
||||
|
||||
def remove_cons_entry(
|
||||
self,
|
||||
row_widget: QWidget,
|
||||
) -> None:
|
||||
logger_gui.debug("[Consulting Page]: Delete clicked...")
|
||||
self.layout_sessions.removeWidget(row_widget)
|
||||
row_widget.deleteLater()
|
||||
self.cons_entries.remove(row_widget)
|
||||
# def remove_cons_entry(
|
||||
# self,
|
||||
# row_widget: QWidget,
|
||||
# ) -> None:
|
||||
# logger_gui.debug("[Consulting Page]: Delete clicked...")
|
||||
# self.layout_sessions.removeWidget(row_widget)
|
||||
# row_widget.deleteLater()
|
||||
# self.cons_entries.remove(row_widget)
|
||||
|
||||
def _debug_get_data_table(self) -> None:
|
||||
self.table_sessions.get_data()
|
||||
|
||||
# TODO placeholder, check if needed
|
||||
def _sync_state_to_ui(self) -> None: ...
|
||||
def _sync_state_to_ui(self) -> None:
|
||||
match self.STATE.cons_type:
|
||||
case ConsultingType.PAUSCHAL:
|
||||
self.type_pauschal_btn.setChecked(True)
|
||||
case ConsultingType.INDIVIUAL:
|
||||
self.type_individual_btn.setChecked(True)
|
||||
|
||||
def _sync_ui_to_state(self) -> None: ...
|
||||
|
||||
@@ -3154,49 +3179,337 @@ class Page_Consulting(QWidget):
|
||||
self.STATE.pers_id = req.pers_id
|
||||
self.STATE.cons_type = req.cons_type
|
||||
|
||||
# def set_company_name(self, name: str) -> None:
|
||||
# if not name:
|
||||
# name = self.change_title_text.text()
|
||||
# if not name:
|
||||
# name = "n.v."
|
||||
self._sync_state_to_ui()
|
||||
|
||||
# txt = f"Unternehmen: {name}"
|
||||
# self.title_company_name.setText(txt)
|
||||
|
||||
# def load_from_id(
|
||||
# self,
|
||||
# id_: InitRecId,
|
||||
# ) -> None:
|
||||
# assert id_ is not None, "tried to load with InitRecId None"
|
||||
# logger_gui.debug(f"Called function to load with ID: {id_}")
|
||||
class Page_Consulting_ConsultingSession(QWidget):
|
||||
"""child of 'Page_Consulting_DynamicTable'"""
|
||||
|
||||
# if id_ < 0:
|
||||
# # just clear and do nothing else
|
||||
# logger_gui.debug("just reset with ID < 0")
|
||||
# self.table_master_data.reset()
|
||||
# self.set_company_name("")
|
||||
# self.current_id = id_
|
||||
# return
|
||||
delete_request = Signal(QWidget)
|
||||
|
||||
# if id_ == self.current_id:
|
||||
# logger_gui.debug("ID did not change. Do nothing")
|
||||
# self.current_id = id_
|
||||
# return
|
||||
def __init__(
|
||||
self,
|
||||
site_state: Page_Consulting_State,
|
||||
state: Page_Consulting_ConsultingSession_State,
|
||||
) -> None:
|
||||
super().__init__()
|
||||
assert isinstance(site_state, Page_Consulting_State)
|
||||
assert isinstance(state, Page_Consulting_ConsultingSession_State)
|
||||
self.SITE_STATE = site_state
|
||||
self.STATE = state
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(0, 2, 0, 2) # Sehr kompakt
|
||||
layout.setSpacing(10)
|
||||
layout.setAlignment(Qt.AlignmentFlag.AlignVCenter)
|
||||
ROW_HEIGHT = 70
|
||||
|
||||
# init_rec = backend.initrec_company_get_initial_recording(id_)
|
||||
# ma_id = cast(ExtMaId, init_rec["Partnersuche__un_suche"])
|
||||
# assert ma_id is not None, "no ma_id obtained"
|
||||
# comp_info = backend.initrec_comp_search_get_info(ma_id)
|
||||
self.user_field = QLineEdit(
|
||||
placeholderText="wird über aktiven Nutzer bei Anlage gesetzt"
|
||||
)
|
||||
self.timestamp = QLineEdit() # TODO change to custom date field
|
||||
|
||||
# data: dict[str, Any] = {}
|
||||
self.contact = QLineEdit(placeholderText="Freitext")
|
||||
self.contact_type = QLineEdit(placeholderText="sollte Dropdown sein") # Dropdown
|
||||
self.crm_link = QLineEdit(placeholderText="CRM Links")
|
||||
|
||||
# for feature, value in comp_info.items():
|
||||
# if feature in self.COMPANY_FETAURES_MASTER_DATA:
|
||||
# data[self.COMPANY_FETAURES_MASTER_DATA[feature]] = value
|
||||
self.plain_text = QPlainTextEdit()
|
||||
self.response = QPlainTextEdit()
|
||||
|
||||
# self.table_master_data.load_data(data)
|
||||
# self.set_company_name(data["Name:"])
|
||||
# self.current_id = id_
|
||||
self.btn_delete = QPushButton("✕")
|
||||
self.btn_delete.setFlat(True) # Entfernt den blockigen Rahmen
|
||||
self.btn_delete.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||
|
||||
self.btn_delete.setStyleSheet("color: #cc0000; font-weight: bold;")
|
||||
self.btn_delete.clicked.connect(lambda: self.delete_request.emit(self))
|
||||
self.btn_delete.setFixedWidth(30)
|
||||
|
||||
widgets = (
|
||||
self.user_field,
|
||||
self.timestamp,
|
||||
self.contact,
|
||||
self.contact_type,
|
||||
self.crm_link,
|
||||
self.plain_text,
|
||||
self.response,
|
||||
self.btn_delete,
|
||||
)
|
||||
for widget in widgets:
|
||||
widget.setFixedHeight(ROW_HEIGHT)
|
||||
layout.addWidget(widget)
|
||||
|
||||
# column stretching: must be matched with header
|
||||
num_widgets = len(widgets)
|
||||
for i, widget in enumerate(widgets):
|
||||
stretch: int
|
||||
if i == (num_widgets - 1):
|
||||
stretch = 0
|
||||
else:
|
||||
if "plaintext" in widget.__class__.__name__.lower():
|
||||
stretch = 2
|
||||
else:
|
||||
stretch = 1
|
||||
|
||||
layout.setStretch(i, stretch)
|
||||
|
||||
self.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
||||
self._sync_state_to_gui() # ?? only needed if entry is from database?
|
||||
|
||||
def _sync_state_to_gui(self) -> None:
|
||||
# TODO set correct timestamp
|
||||
logger_page_consulting.debug(
|
||||
"[Page Consulting -- Consulting Session]: State = %s", self.STATE
|
||||
)
|
||||
set_widget_value(self.user_field, self.STATE.user_name)
|
||||
set_widget_value(self.timestamp, self.STATE.timestamp)
|
||||
set_widget_value(self.contact, self.STATE.partner)
|
||||
set_widget_value(self.contact_type, self.STATE.interaction_scheme)
|
||||
set_widget_value(self.crm_link, self.STATE.topic)
|
||||
set_widget_value(self.plain_text, self.STATE.notes)
|
||||
set_widget_value(self.response, self.STATE.response)
|
||||
|
||||
def _sync_gui_to_state(self) -> None:
|
||||
# TODO: get timestamp from custom field self.STATE.timestamp
|
||||
self.STATE.timestamp = datetime.datetime.strptime(
|
||||
self.timestamp.text(), "%d.%m.%Y %H:%M:%S"
|
||||
)
|
||||
self.STATE.partner = self.contact.text()
|
||||
self.STATE.interaction_scheme = self.contact_type.text()
|
||||
self.STATE.topic = self.crm_link.text() # TODO: change to correct link
|
||||
self.STATE.notes = self.plain_text.toPlainText()
|
||||
self.STATE.response = self.response.toPlainText()
|
||||
|
||||
def get_data(self) -> Page_Consulting_ConsultingSession_State:
|
||||
self._sync_gui_to_state()
|
||||
|
||||
return self.STATE
|
||||
|
||||
|
||||
class Page_Consulting_Table(QWidget):
|
||||
"""child of 'Page_Consulting'"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
site_state: Page_Consulting_State,
|
||||
state: Page_Consulting_Table_State,
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.setWindowTitle("Native Dynamische Liste")
|
||||
self.resize(600, 400)
|
||||
|
||||
self.STATE = state
|
||||
self.SITE_STATE = site_state
|
||||
|
||||
main_layout = QVBoxLayout(self)
|
||||
main_layout.setContentsMargins(0, 15, 0, 15)
|
||||
main_layout.setSpacing(10)
|
||||
|
||||
# --- BUTTON (ADD) ---
|
||||
self.btn_add = QPushButton("+ Neuen Eintrag hinzufügen")
|
||||
self.btn_add.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||
self.btn_add.setObjectName("BlueAddButton") # ID vergeben
|
||||
main_layout.addWidget(self.btn_add)
|
||||
self.btn_add.clicked.connect(lambda: self.add_row(None))
|
||||
|
||||
self.btn_add.setStyleSheet("""
|
||||
#BlueAddButton {
|
||||
background-color: #007acc;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
padding: 8px 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
#BlueAddButton:hover {
|
||||
background-color: #0098ff;
|
||||
}
|
||||
""")
|
||||
|
||||
# --- HEADER ---
|
||||
header_widget = QWidget()
|
||||
header_layout = QHBoxLayout(header_widget)
|
||||
header_layout.setContentsMargins(0, 5, 0, 5)
|
||||
header_layout.setSpacing(10)
|
||||
|
||||
lbl_user_field = QLabel("Wer")
|
||||
lbl_timestamp = QLabel("Wann")
|
||||
lbl_contact = QLabel("Mit wem")
|
||||
lbl_contact_type = QLabel("Wie")
|
||||
lbl_crm_link = QLabel("Was")
|
||||
lbl_plain_text = QLabel("Anmerkungen")
|
||||
lbl_response = QLabel("Rückmeldung")
|
||||
lbl_action_delete = QLabel("")
|
||||
lbl_action_delete.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
lbl_action_delete.setFixedWidth(30)
|
||||
|
||||
labels = (
|
||||
lbl_user_field,
|
||||
lbl_timestamp,
|
||||
lbl_contact,
|
||||
lbl_contact_type,
|
||||
lbl_crm_link,
|
||||
lbl_plain_text,
|
||||
lbl_response,
|
||||
lbl_action_delete,
|
||||
)
|
||||
|
||||
header_font = QFont()
|
||||
header_font.setBold(True)
|
||||
for lbl in labels:
|
||||
lbl.setFont(header_font)
|
||||
lbl.setStyleSheet("color: #666666;")
|
||||
lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
header_layout.addWidget(lbl)
|
||||
|
||||
plaintext_labels = {lbl_plain_text, lbl_response}
|
||||
|
||||
num_labels = len(labels)
|
||||
for i, widget in enumerate(labels):
|
||||
stretch: int
|
||||
if i == (num_labels - 1):
|
||||
stretch = 0
|
||||
else:
|
||||
if widget in plaintext_labels:
|
||||
stretch = 2
|
||||
else:
|
||||
stretch = 1
|
||||
|
||||
header_layout.setStretch(i, stretch)
|
||||
|
||||
main_layout.addWidget(header_widget)
|
||||
|
||||
separator = QFrame()
|
||||
separator.setFrameShape(QFrame.Shape.HLine)
|
||||
separator.setFrameShadow(QFrame.Shadow.Sunken)
|
||||
main_layout.addWidget(separator)
|
||||
|
||||
self.scroll_area = QScrollArea()
|
||||
self.scroll_area.setWidgetResizable(True)
|
||||
self.scroll_area.setFrameShape(QScrollArea.Shape.NoFrame)
|
||||
|
||||
self.container_widget = QWidget()
|
||||
self.container_layout = QVBoxLayout(self.container_widget)
|
||||
self.container_layout.setContentsMargins(0, 5, 0, 5)
|
||||
self.container_layout.setSpacing(6)
|
||||
self.container_layout.addStretch()
|
||||
|
||||
self.scroll_area.setWidget(self.container_widget)
|
||||
main_layout.addWidget(self.scroll_area)
|
||||
|
||||
# --- STYLING (QSS) ---
|
||||
# self.setStyleSheet("""
|
||||
# QWidget {
|
||||
# background-color: #1e1e24;
|
||||
# color: #e0e0e6;
|
||||
# font-family: 'Segoe UI', sans-serif;
|
||||
# font-size: 13px;
|
||||
# }
|
||||
# #HeaderWidget QLabel {
|
||||
# font-weight: bold;
|
||||
# color: #888892;
|
||||
# font-size: 11px;
|
||||
# letter-spacing: 1px;
|
||||
# }
|
||||
# QLineEdit {
|
||||
# background-color: #2a2a32;
|
||||
# border: 1px solid #3f3f4a;
|
||||
# border-radius: 6px;
|
||||
# padding: 6px 10px;
|
||||
# color: white;
|
||||
# }
|
||||
# QLineEdit:focus {
|
||||
# border: 1px solid #007acc;
|
||||
# }
|
||||
# QPushButton {
|
||||
# background-color: #007acc;
|
||||
# color: white;
|
||||
# border: none;
|
||||
# border-radius: 6px;
|
||||
# padding: 8px 15px;
|
||||
# font-weight: bold;
|
||||
# }
|
||||
# QPushButton:hover {
|
||||
# background-color: #0098ff;
|
||||
# }
|
||||
# #DeleteButton {
|
||||
# background-color: transparent;
|
||||
# color: #ff5555;
|
||||
# border: 1px solid #3f3f4a;
|
||||
# font-size: 14px;
|
||||
# padding: 4px;
|
||||
# }
|
||||
# #DeleteButton:hover {
|
||||
# background-color: #ff3333;
|
||||
# color: white;
|
||||
# border-color: #ff3333;
|
||||
# }
|
||||
# QScrollArea {
|
||||
# background-color: transparent;
|
||||
# }
|
||||
# """)
|
||||
|
||||
if DEBUG:
|
||||
# add rows for debugging
|
||||
self.add_row()
|
||||
self.add_row()
|
||||
|
||||
def add_row(
|
||||
self,
|
||||
row_state: Page_Consulting_ConsultingSession_State | None = None,
|
||||
) -> None:
|
||||
if row_state is None:
|
||||
row_state = Page_Consulting_ConsultingSession_State(
|
||||
user_id=self.SITE_STATE.session.user_id,
|
||||
user_name=self.SITE_STATE.session.user_name,
|
||||
)
|
||||
|
||||
row = Page_Consulting_ConsultingSession(site_state=self.SITE_STATE, state=row_state)
|
||||
row.delete_request.connect(self.remove_row)
|
||||
|
||||
index = self.container_layout.count() - 1
|
||||
self.container_layout.insertWidget(index, row)
|
||||
self.STATE.rows.append(row)
|
||||
|
||||
def remove_row(
|
||||
self,
|
||||
table_row_widget: Page_Consulting_ConsultingSession,
|
||||
) -> None:
|
||||
self.container_layout.removeWidget(table_row_widget)
|
||||
self.STATE.rows.remove(table_row_widget)
|
||||
table_row_widget.deleteLater()
|
||||
|
||||
def reset(self) -> None:
|
||||
while self.STATE.rows:
|
||||
self.remove_row(self.STATE.rows[0])
|
||||
|
||||
def _sync_state_to_gui(self) -> None:
|
||||
for row_state in self.STATE.row_states:
|
||||
self.add_row(row_state)
|
||||
|
||||
def _sync_gui_to_state(self) -> None:
|
||||
row_data: list[Page_Consulting_ConsultingSession_State] = []
|
||||
|
||||
for i in range(self.container_layout.count() - 1):
|
||||
item = self.container_layout.itemAt(i)
|
||||
assert item, "item not found"
|
||||
widget = item.widget()
|
||||
assert widget, "no widget obtained"
|
||||
|
||||
if isinstance(widget, Page_Consulting_ConsultingSession):
|
||||
row_data.append(widget.get_data())
|
||||
|
||||
assert len(row_data) == len(self.STATE.rows), "mismatch in row count and data length"
|
||||
self.STATE.row_states = row_data
|
||||
|
||||
def get_data(self) -> Page_Consulting_Table_State:
|
||||
logger_page_consulting.debug("[Page Consulting -- Table] Syncing GUI to state...")
|
||||
self._sync_gui_to_state()
|
||||
|
||||
logger_page_consulting.debug("[Page Consulting -- Table]: State = %s", self.STATE)
|
||||
|
||||
return self.STATE
|
||||
|
||||
|
||||
####################################################################
|
||||
|
||||
|
||||
def clear_layout(
|
||||
|
||||
Reference in New Issue
Block a user