prepare search in contact list as dynamic widget

This commit is contained in:
2026-05-20 13:05:16 +02:00
parent e97999713e
commit 92ea12d847

View File

@@ -12,7 +12,7 @@ import uuid
from collections.abc import Sequence
from pathlib import Path
from pprint import pprint
from typing import Annotated, Any, Protocol, TypeAlias, TypedDict
from typing import Annotated, Any, Protocol, TypeAlias, TypedDict, cast
import babel
from pydantic import BaseModel, ConfigDict, EmailStr, Field, ValidationError, field_validator
@@ -199,6 +199,92 @@ def pprint_registry(widget_registry: WidgetRegistry) -> None:
print(f"\tfield type: {entry['form_field'].type}")
class FormFieldType(enum.StrEnum):
GROUP = enum.auto()
TEXT = enum.auto()
LONGTEXT = enum.auto()
DATE = enum.auto()
DATETIME = enum.auto()
DROPDOWN = enum.auto()
EXTENDED_DROPDOWN = enum.auto()
DYNAMIC_LIST = enum.auto()
DYNAMIC_DROPDOWN = enum.auto()
TEXT_SEARCH = enum.auto()
@dc.dataclass(slots=True)
class DropdownOption:
label: str
_data: dc.InitVar[Any | None] = None
data: Any = dc.field(init=False)
def __post_init__(
self,
_data: Any | None,
) -> None:
if _data is None:
self.data = self.label
else:
self.data = _data
@dc.dataclass(slots=True)
class FormField:
label: str
type: FormFieldType
children: Sequence[FormField] = dc.field(default_factory=list)
parent: FormField | None = None
required: bool = False
placeholder: str = ""
fill_value: str = ""
readonly: bool = False
options: dc.InitVar[Sequence[tuple[str, Any]]] = tuple()
dropdown_options: Sequence[DropdownOption] = dc.field(default=tuple(), init=False)
key: str = ""
tooltip: str = ""
info: str = ""
init_label: str = dc.field(init=False)
def __post_init__(
self,
options: Sequence[tuple[str, Any]],
) -> None:
if not self.key:
self.key = str(uuid.uuid4())
self.label = self.label.strip()
self.init_label = self.label.replace("*", "").replace(":", "")
if not self.label.endswith(":") and self.type is not FormFieldType.GROUP:
self.label += ":"
if self.required:
self.label += "*"
# if (
# self.type in (FormFieldType.DROPDOWN, FormFieldType.EXTENDED_DROPDOWN)
# and not options
# ):
# raise ValueError("Invalid field definition: Dropdown requires options")
if self.type in (FormFieldType.DROPDOWN, FormFieldType.EXTENDED_DROPDOWN):
self.dropdown_options = tuple(DropdownOption(op[0], op[1]) for op in options)
if self.children:
self.required = any((child.required for child in self.children))
for child in self.children:
child.parent = self
def enhanced_label(
self,
add_text: str,
) -> str:
enhanced_label = self.init_label + f" {add_text}"
if not enhanced_label.endswith(":") and self.type is not FormFieldType.GROUP:
enhanced_label += ":"
if self.required:
enhanced_label += "*"
return enhanced_label
class CustomForm(Protocol):
def get_form_data(self) -> dict[str, Any]: ...
@@ -254,6 +340,30 @@ def _build_ui_recursively(
else:
parent_layout.addRow(field.label, widget)
case FormFieldType.TEXT_SEARCH:
widget = QLineEdit()
if field.placeholder:
widget.setPlaceholderText(field.placeholder)
else:
widget.setPlaceholderText("Tippen zum Suchen...")
search_completer = QCompleter()
search_completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
search_completer.setFilterMode(Qt.MatchFlag.MatchContains)
widget.setCompleter(search_completer)
widget_registry[full_key] = {
"widget": widget,
"form_field": field,
}
widget.installEventFilter(no_scroll_filter)
if field.tooltip:
tooltip_layout = _add_tooltip(widget, field.tooltip)
parent_layout.addRow(field.label, tooltip_layout)
else:
parent_layout.addRow(field.label, widget)
case FormFieldType.LONGTEXT:
widget = QPlainTextEdit()
widget.setMaximumHeight(80)
@@ -319,7 +429,6 @@ def _build_ui_recursively(
case FormFieldType.DROPDOWN:
widget = QComboBox()
assert field.dropdown_options
widget.addItem(DROPDOWN_DEFAULT, None)
for option in field.dropdown_options:
widget.addItem(option.label, option.data)
@@ -356,7 +465,6 @@ def _build_ui_recursively(
completer.setFilterMode(Qt.MatchFlag.MatchContains)
completer.setCompletionMode(QCompleter.CompletionMode.PopupCompletion)
assert field.dropdown_options
widget.addItem(DROPDOWN_DEFAULT, None)
for option in field.dropdown_options:
widget.addItem(option.label, option.data)
@@ -438,6 +546,8 @@ def reset_form(
widget = registry_entry["widget"]
form_field = registry_entry["form_field"]
# TODO check if this behaviour is correct in other contexts, deactivated because of
# TODO company search widget
if form_field.readonly:
continue
@@ -554,9 +664,7 @@ def get_form_data(
# pprint(form_data)
elif isinstance(widget, DynamicDropdownWidget):
# this is a special data structure with some assumptions of the widget's structure
form_data = widget.get_form_data()
value = form_data
# value = [val for val in form_data.values()]
value = widget.get_form_data()
# print(">>>>>>>>> Key: ", key)
# print(">>>>>>>>> Form Data after call:")
# pprint(form_data)
@@ -789,7 +897,7 @@ class Grunderfassung_Sprachen(BaseModel):
SP_datum_nachweis: datetime.date | None
class CompanyForm_Search(QWidget):
class CompanyForm_Search_old(QWidget):
company_selected = Signal(int)
def __init__(self):
@@ -885,6 +993,602 @@ class CompanyForm_Search(QWidget):
self.company_selected.emit(ma_id)
class CompanyForm_Search_Data(TypedDict):
ma_id: int
class Grunderfassung_Suche(QWidget):
# company_selected = Signal(int)
def __init__(
self,
# form_fields: Sequence[FormField],
label: str = "Suche",
prefix: str = "",
):
super().__init__()
# self.form_fields = form_fields
self.label = label
self.prefix = prefix
# self.widget_registry: WidgetRegistry = {}
self.export_data: CompanyForm_Search_Data = {"ma_id": -1}
self.PROPERTY_MA_ID = "user_ma_id"
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
form_layout = QFormLayout()
form_layout.setSpacing(10)
# TODO: remove title?
title = QLabel(self.label)
title.setStyleSheet("font-size: 14px; font-weight: bold;")
main_layout.addWidget(title)
# --- SEARCH ---
self.company_search_input = QLineEdit(placeholderText="Tippen zum Suchen...")
form_layout.addRow("Suche:", self.company_search_input)
self.company_search_completer = QCompleter()
self.company_search_completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
self.company_search_completer.setFilterMode(Qt.MatchFlag.MatchContains)
self.company_search_input.setCompleter(self.company_search_completer)
self.company_search_completer.activated[QModelIndex].connect( # type: ignore
self._selected_company_on_completer
)
self.company_search_input.textChanged.connect(self._search_company_change_manually)
# --- FILLED FIELDS ---
# name
self.company_name = QLineEdit(placeholderText="Name des Partners")
form_layout.addRow("Name Unternehmen/Netzwerkpartner:", self.company_name)
# street
street_layout = QHBoxLayout()
street_layout.setContentsMargins(0, 0, 0, 0)
street_layout.setSpacing(10)
self.company_street = QLineEdit(placeholderText="Straße")
self.company_streetnumber = QLineEdit(placeholderText="Nr.")
self.company_streetnumber.setMaximumWidth(80)
street_layout.addWidget(self.company_street, stretch=3)
street_layout.addWidget(self.company_streetnumber, stretch=1)
form_layout.addRow("Straße / Nr.:", street_layout)
# ZIP, city
# --- 3. Kombinierte Zeile: PLZ & Ort ---
city_layout = QHBoxLayout()
city_layout.setContentsMargins(0, 0, 0, 0)
city_layout.setSpacing(10)
self.company_zip = QLineEdit(placeholderText="PLZ")
self.company_city = QLineEdit(placeholderText="Ort")
self.company_zip.setMaximumWidth(100) # PLZ ist immer relativ kurz
city_layout.addWidget(self.company_zip, stretch=1)
city_layout.addWidget(self.company_city, stretch=3)
form_layout.addRow("PLZ / Ort:", city_layout)
# !! -------------------------------------------------------------------
# Integration of person search
# TODO: remove title
spacing_layout = QVBoxLayout()
spacing_layout.addSpacing(15)
form_layout.addRow(spacing_layout)
title = QLabel("--- Suche Nutzer ---")
title.setStyleSheet("font-size: 14px; font-weight: bold;")
main_layout.addWidget(title)
# --- SEARCH ---
self.person_search_input = QComboBox()
self.person_search_input.setEditable(True)
self.person_search_input.setInsertPolicy(QComboBox.InsertPolicy.NoInsert)
line_edit = self.person_search_input.lineEdit()
assert line_edit
line_edit.setPlaceholderText("Suchen...")
# --- FILLED FIELDS ---
form_layout.addRow("Suche Ansprechpartner:", self.person_search_input)
self.person_completer = self.person_search_input.completer()
assert self.person_completer
self.person_completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
self.person_completer.setFilterMode(Qt.MatchFlag.MatchContains)
self.person_completer.setCompletionMode(QCompleter.CompletionMode.PopupCompletion)
# self.person_search_input.activated.connect(self._selected_person_on_completer)
self.person_search_input.currentIndexChanged.connect(
self._selected_person_on_completer
)
# salutation
self.person_titel = QLineEdit()
self.person_anrede = QLineEdit()
hor_layout = QHBoxLayout()
hor_layout.addWidget(self.person_anrede, stretch=1)
hor_layout.addWidget(self.person_titel, stretch=1)
form_layout.addRow("Anrede / Titel:", hor_layout)
# names
self.person_nachname = QLineEdit()
self.person_vorname = QLineEdit()
hor_layout = QHBoxLayout()
hor_layout.addWidget(self.person_nachname, stretch=1)
hor_layout.addWidget(self.person_vorname, stretch=1)
form_layout.addRow("Nachname / Vorname:", hor_layout)
# phones
phone_layout = QHBoxLayout()
phone_layout.setContentsMargins(0, 0, 0, 0)
phone_layout.setSpacing(10)
self.person_landline_number = QLineEdit()
self.person_mobile_number = QLineEdit()
phone_layout.addWidget(self.person_landline_number, stretch=1)
phone_layout.addWidget(self.person_mobile_number, stretch=1)
form_layout.addRow("Telefon Festnetz / Mobil:", phone_layout)
# additional
self.person_email = QLineEdit()
form_layout.addRow("E-Mail:", self.person_email)
self.person_funktion = QLineEdit()
form_layout.addRow("Funktion:", self.person_funktion)
# ------------------------------------------------------------------------
# add fom layout
main_layout.addLayout(form_layout)
main_layout.addSpacing(20)
main_layout.addWidget(
QLabel('>>>> Platzhalter "Wie sind Sie auf uns aufmerksam geworden?"')
)
self.autofilled_fields: tuple[QLineEdit, ...] = (
self.company_name,
self.company_street,
self.company_streetnumber,
self.company_zip,
self.company_city,
self.person_titel,
self.person_anrede,
self.person_nachname,
self.person_vorname,
self.person_landline_number,
self.person_mobile_number,
self.person_email,
self.person_funktion,
)
for field in self.autofilled_fields:
field.setReadOnly(True)
field.setProperty("styleClass", "stempel")
self.update_company_data()
# self.update_person_data(None)
def fill_out_company(self, comp_info: be_init_rec.CompanyInfo):
self.company_name.setText(comp_info["ma_unternehmensname"])
self.company_street.setText(comp_info["ma_strasse"])
self.company_streetnumber.setText(comp_info["ma_hausnummer"])
self.company_zip.setText(comp_info["ma_plz"])
self.company_city.setText(comp_info["ma_ort"])
def fill_out(
self,
info: be_init_rec.ContactPersonInfo,
) -> None:
self.person_titel.setText(info["an_titel"])
self.person_anrede.setText(info["an_anrede"])
self.person_nachname.setText(info["an_nachname"])
self.person_vorname.setText(info["an_vorname"])
self.person_landline_number.setText(info["an_festnetz"])
self.person_mobile_number.setText(info["an_mobil"])
self.person_email.setText(info["an_mail"])
self.person_funktion.setText(info["an_position"])
def clear_autofilled_fields(self) -> None:
self.company_search_input.clear()
self.person_search_input.clear()
for field in self.autofilled_fields:
field.clear()
def update_company_data(self) -> None:
self.clear_autofilled_fields()
search_items = QStandardItemModel()
search_choices = be_init_rec.comp_search_choices()
for item, db_index in search_choices:
qitem = QStandardItem(item)
qitem.setData(db_index, Qt.ItemDataRole.UserRole)
search_items.appendRow(qitem)
self.company_search_completer.setModel(search_items)
def update_person_data(
self,
ma_id: int | None,
) -> None:
self.clear_autofilled_fields()
search_choices = be_init_rec.contact_person_search_choices(ma_id, True)
for item, db_index in search_choices:
self.person_search_input.addItem(item, db_index)
self.person_search_input.setCurrentIndex(0)
def _selected_company_on_completer(
self,
index: QModelIndex,
) -> None:
ma_id = index.data(Qt.ItemDataRole.UserRole)
comp_info = be_init_rec.comp_search_get_info(
ma_id=ma_id,
)
self.company_search_input.setProperty(self.PROPERTY_MA_ID, ma_id)
self.fill_out_company(comp_info)
# self.company_selected.emit(ma_id)
self.update_person_data(ma_id)
def _selected_person_on_completer(
self,
index: int,
):
an_id = self.person_search_input.itemData(index)
comp_info = be_init_rec.contact_person_search_get_info(
an_id=an_id,
)
self.fill_out(comp_info)
def _search_company_change_manually(
self,
_: str,
) -> None:
self.company_search_input.setProperty(self.PROPERTY_MA_ID, -1)
def get_form_data(self) -> CompanyForm_Search_Data:
ma_id = self.company_search_input.property(self.PROPERTY_MA_ID)
self.export_data["ma_id"] = ma_id
return self.export_data
def set_form_data(
self,
ma_id: int,
) -> None:
comp_info = be_init_rec.comp_search_get_info(
ma_id=ma_id,
)
self.company_search_input.setText(comp_info["ma_unternehmensname"])
self.fill_out_company(comp_info)
# self.company_selected.emit(ma_id)
FORM_FIELDS_SEARCH_HEAD = [
FormField(
"Suche",
FormFieldType.TEXT_SEARCH,
required=False,
key="kontaktliste_un_suche",
),
FormField(
"Name Unternehmen/Netzwerkpartner",
FormFieldType.TEXT,
required=False,
key="kontaktliste_un_name",
readonly=True,
info="ma_unternehmensname",
),
FormField(
"Straße",
FormFieldType.TEXT,
required=False,
key="kontaktliste_un_straße",
readonly=True,
info="ma_strasse",
),
FormField(
"Hausnummer",
FormFieldType.TEXT,
required=False,
key="kontaktliste_un_hausnummer",
readonly=True,
info="ma_hausnummer",
),
FormField(
"PLZ",
FormFieldType.TEXT,
required=False,
key="kontaktliste_un_PLZ",
readonly=True,
info="ma_plz",
),
FormField(
"Ort",
FormFieldType.TEXT,
required=False,
key="kontaktliste_un_ort",
readonly=True,
info="ma_ort",
),
FormField(
"Suche Ansprechpartner",
FormFieldType.EXTENDED_DROPDOWN,
required=False,
key="kontaktliste_person_suche",
info="ma_ort",
),
FormField(
"Titel",
FormFieldType.TEXT,
required=False,
key="kontaktliste_person_titel",
readonly=True,
info="an_titel",
),
FormField(
"Anrede",
FormFieldType.TEXT,
required=False,
key="kontaktliste_person_anrede",
readonly=True,
info="an_anrede",
),
FormField(
"Name",
FormFieldType.TEXT,
required=False,
key="kontaktliste_person_name",
readonly=True,
info="an_nachname",
),
FormField(
"Vorname",
FormFieldType.TEXT,
required=False,
key="kontaktliste_person_vorname",
readonly=True,
info="an_vorname",
),
FormField(
"Telefon",
FormFieldType.TEXT,
required=False,
key="kontaktliste_person_telefon",
readonly=True,
info="an_festnetz",
),
FormField(
"Mobil",
FormFieldType.TEXT,
required=False,
key="kontaktliste_person_mobilfunk",
readonly=True,
info="an_mobil",
),
FormField(
"E-Mail",
FormFieldType.TEXT,
required=False,
key="kontaktliste_person_email",
readonly=True,
info="an_mail",
),
FormField(
"Funktion im Unternehmen",
FormFieldType.TEXT,
required=False,
key="kontaktliste_person_funktion",
readonly=True,
info="an_position",
),
FormField(
"Wie sind Sie auf uns aufmerksam geworden?",
FormFieldType.DROPDOWN,
required=False,
key="kontaktliste_kanal_aufmerksamkeit",
options=[
("Agentur für Arbeit", None),
("Ausländerbehörde", None),
("Jobcenter", None),
("Freunde/Familie", None),
("Anerkennungsstelle", None),
("Beratungsstelle", None),
("Internet", None),
("Arbeitgeber", None),
("Bildungsdienstleister", None),
("Welcome-Mappe", None),
("Newsletter WFE", None),
("Newsletter RM", None),
("Sonstiges", None),
],
),
]
class Grunderfassung_Suche_new(QWidget):
def __init__(
self,
form_fields: Sequence[FormField],
label: str = "Suche",
prefix: str = "",
):
super().__init__()
self.form_fields = form_fields
self.label = label
self.prefix = prefix
self.widget_registry: WidgetRegistry = {}
self.export_data: CompanyForm_Search_Data = {"ma_id": -1}
self.PROPERTY_MA_ID = "user_ma_id"
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
self.form_layout = QFormLayout()
self.form_layout.setSpacing(10)
main_layout.addLayout(self.form_layout)
_build_ui_recursively(
self.form_fields,
self.form_layout,
self.widget_registry,
self.prefix,
)
lookup = search_widgets_by_key(self.widget_registry, "kontaktliste_un_suche")
assert len(lookup) == 1
self.company_search_input = cast(QLineEdit, lookup[0]["widget"])
self.company_search_completer = self.company_search_input.completer()
self.company_search_completer.activated[QModelIndex].connect( # type: ignore
self._selected_company_on_completer
)
self.company_search_input.textChanged.connect(self._search_company_change_manually)
lookup = search_widgets_by_key(self.widget_registry, "kontaktliste_person_suche")
assert len(lookup) == 1
self.person_search_input = cast(QComboBox, lookup[0]["widget"])
self.person_search_input.currentIndexChanged.connect(
self._selected_person_on_completer
)
# self.company_search_completer = self.company_search_input.completer()
self.company_widgets: dict[str, QWidget] = {}
self.person_widgets: dict[str, QWidget] = {}
self.properties_company: tuple[str, ...] = (
"ma_unternehmensname",
"ma_strasse",
"ma_hausnummer",
"ma_plz",
"ma_ort",
)
self.properties_person: tuple[str, ...] = (
"an_titel",
"an_anrede",
"an_nachname",
"an_vorname",
"an_festnetz",
"an_mobil",
"an_mail",
"an_position",
)
for entry in self.widget_registry.values():
field = entry["form_field"]
widget = entry["widget"]
if field.info in self.properties_company:
self.company_widgets[field.info] = widget
elif field.info in self.properties_person:
self.person_widgets[field.info] = widget
button = QPushButton("Print Registry")
button.clicked.connect(self.print_registry)
main_layout.addWidget(button)
button = QPushButton("Reset form")
button.clicked.connect(self.reset_form)
main_layout.addWidget(button)
self.update_company_data()
def print_registry(self) -> None:
pprint_registry(self.widget_registry)
def fill_out_company(
self,
data: be_init_rec.CompanyInfo,
) -> None:
for key, widget in self.company_widgets.items():
if key not in data:
raise KeyError(
(
f"Key: {key} not found in company info. Add the key "
f"to the info property in the form field definition"
)
)
set_widget_value(widget, data[key])
def fill_out_person(
self,
data: be_init_rec.ContactPersonInfo,
) -> None:
for key, widget in self.person_widgets.items():
if key not in data:
raise KeyError(
(
f"Key: {key} not found in company info. Add the key "
f"to the info property in the form field definition"
)
)
set_widget_value(widget, data[key])
def reset_form(self) -> None:
reset_form(self.widget_registry)
self._clear_company_fields()
self._clear_person_fields()
def _clear_company_fields(self) -> None:
for widget in self.company_widgets.values():
widget = cast(QLineEdit, widget)
widget.clear()
def _clear_person_fields(self) -> None:
for widget in self.person_widgets.values():
widget = cast(QLineEdit, widget)
widget.clear()
def update_company_data(self) -> None:
# self.reset_form()
self.company_search_input.clear()
self._clear_company_fields()
search_items = QStandardItemModel()
search_choices = be_init_rec.comp_search_choices()
for item, db_index in search_choices:
qitem = QStandardItem(item)
qitem.setData(db_index, Qt.ItemDataRole.UserRole)
search_items.appendRow(qitem)
self.company_search_completer.setModel(search_items)
def update_person_data(
self,
ma_id: int | None,
) -> None:
# self.reset_form()
self.person_search_input.clear()
self.person_search_input.addItem(DROPDOWN_DEFAULT, None)
search_choices = be_init_rec.contact_person_search_choices(ma_id, True)
for item, db_index in search_choices:
self.person_search_input.addItem(item, db_index)
self.person_search_input.setCurrentIndex(0)
def _selected_company_on_completer(
self,
index: QModelIndex,
) -> None:
ma_id = index.data(Qt.ItemDataRole.UserRole)
data = be_init_rec.comp_search_get_info(
ma_id=ma_id,
)
self.company_search_input.setProperty(self.PROPERTY_MA_ID, ma_id)
self.fill_out_company(data)
# self.company_selected.emit(ma_id)
self.update_person_data(ma_id)
def _selected_person_on_completer(
self,
index: int,
) -> None:
an_id = self.person_search_input.itemData(index)
if an_id is None:
self._clear_person_fields()
return
data = be_init_rec.contact_person_search_get_info(
an_id=an_id,
)
self.fill_out_person(data)
def _search_company_change_manually(
self,
_: str,
) -> None:
self.company_search_input.setProperty(self.PROPERTY_MA_ID, -1)
def get_form_data(self) -> CompanyForm_Search_Data:
# TODO decide if value is checked here or later in the Pydantic validation
ma_id = self.company_search_input.property(self.PROPERTY_MA_ID)
self.export_data["ma_id"] = ma_id
return self.export_data
# def set_form_data(
# self,
# ma_id: int,
# ) -> None:
# comp_info = be_init_rec.comp_search_get_info(
# ma_id=ma_id,
# )
# self.company_search_input.setText(comp_info["ma_unternehmensname"])
# self.fill_out_company(comp_info)
class ContactPersonForm_Search(QWidget):
def __init__(self):
super().__init__()
@@ -961,7 +1665,10 @@ class ContactPersonForm_Search(QWidget):
self.update_search_data(None)
def fill_out(self, info: be_init_rec.ContactPersonInfo):
def fill_out(
self,
info: be_init_rec.ContactPersonInfo,
) -> None:
self.gui_titel.setText(info["an_titel"])
self.gui_anrede.setText(info["an_anrede"])
self.gui_nachname.setText(info["an_nachname"])
@@ -996,90 +1703,6 @@ class ContactPersonForm_Search(QWidget):
self.search_input.addItem(item, db_index)
class FormFieldType(enum.StrEnum):
GROUP = enum.auto()
TEXT = enum.auto()
LONGTEXT = enum.auto()
DATE = enum.auto()
DATETIME = enum.auto()
DROPDOWN = enum.auto()
EXTENDED_DROPDOWN = enum.auto()
DYNAMIC_LIST = enum.auto()
DYNAMIC_DROPDOWN = enum.auto()
@dc.dataclass(slots=True)
class DropdownOption:
label: str
_data: dc.InitVar[Any | None] = None
data: Any = dc.field(init=False)
def __post_init__(
self,
_data: Any | None,
) -> None:
if _data is None:
self.data = self.label
else:
self.data = _data
@dc.dataclass(slots=True)
class FormField:
label: str
type: FormFieldType
children: Sequence[FormField] = dc.field(default_factory=list)
parent: FormField | None = None
required: bool = False
placeholder: str = ""
fill_value: str = ""
readonly: bool = False
options: dc.InitVar[Sequence[tuple[str, Any]]] = tuple()
dropdown_options: Sequence[DropdownOption] = dc.field(default=tuple(), init=False)
key: str = ""
tooltip: str = ""
init_label: str = dc.field(init=False)
def __post_init__(
self,
options: Sequence[tuple[str, Any]],
) -> None:
if not self.key:
self.key = str(uuid.uuid4())
self.label = self.label.strip()
self.init_label = self.label.replace("*", "").replace(":", "")
if not self.label.endswith(":") and self.type is not FormFieldType.GROUP:
self.label += ":"
if self.required:
self.label += "*"
if (
self.type in (FormFieldType.DROPDOWN, FormFieldType.EXTENDED_DROPDOWN)
and not options
):
raise ValueError("Invalid field definition: Dropdown requires options")
elif self.type in (FormFieldType.DROPDOWN, FormFieldType.EXTENDED_DROPDOWN):
self.dropdown_options = tuple(DropdownOption(op[0], op[1]) for op in options)
if self.children:
self.required = any((child.required for child in self.children))
for child in self.children:
child.parent = self
def enhanced_label(
self,
add_text: str,
) -> str:
enhanced_label = self.init_label + f" {add_text}"
if not enhanced_label.endswith(":") and self.type is not FormFieldType.GROUP:
enhanced_label += ":"
if self.required:
enhanced_label += "*"
return enhanced_label
def enhanced_label(
base_label: str,
add_text: str,
@@ -2560,41 +3183,42 @@ class SearchFormPage(QWidget):
container_layout.addSpacing(10)
# --- SUCHE MIT NAMEN ---
self.company_search = CompanyForm_Search()
# self.company_search = Grunderfassung_Suche()
self.company_search = Grunderfassung_Suche_new(FORM_FIELDS_SEARCH_HEAD)
container_layout.addWidget(self.company_search)
self.contact_person_search = ContactPersonForm_Search()
container_layout.addWidget(self.contact_person_search)
hor_layout = QHBoxLayout()
label = QLabel("Wie sind Sie auf uns aufmerksam geworden?")
combo = QComboBox()
combo.addItems(
[
"--- Bitte wählen ---",
"Agentur für Arbeit",
"Ausländerbehörde",
"Jobcenter",
"Freunde/Familie",
"Anerkennungsstelle",
"Beratungsstelle",
"Internet",
"Arbeitgeber",
"Bildungsdienstleister",
"Welcome-Mappe",
"Newsletter WFE",
"Newsletter RM",
"Sonstiges",
]
)
combo.setPlaceholderText("Bitte auswählen")
combo.model().item(0).setEnabled(False) # type: ignore
hor_layout.addWidget(label)
hor_layout.addWidget(combo, stretch=1)
container_layout.addLayout(hor_layout)
# self.contact_person_search = ContactPersonForm_Search()
# container_layout.addWidget(self.contact_person_search)
# hor_layout = QHBoxLayout()
# label = QLabel("Wie sind Sie auf uns aufmerksam geworden?")
# combo = QComboBox()
# combo.addItems(
# [
# "--- Bitte wählen ---",
# "Agentur für Arbeit",
# "Ausländerbehörde",
# "Jobcenter",
# "Freunde/Familie",
# "Anerkennungsstelle",
# "Beratungsstelle",
# "Internet",
# "Arbeitgeber",
# "Bildungsdienstleister",
# "Welcome-Mappe",
# "Newsletter WFE",
# "Newsletter RM",
# "Sonstiges",
# ]
# )
# combo.setPlaceholderText("Bitte auswählen")
# combo.model().item(0).setEnabled(False) # type: ignore
# hor_layout.addWidget(label)
# hor_layout.addWidget(combo, stretch=1)
# container_layout.addLayout(hor_layout)
container_layout.addWidget(
QLabel('Platzhalter "Wie sind Sie auf uns aufmerksam geworden?"')
)
self.company_search.company_selected.connect(self.update_contact_persons)
# container_layout.addWidget(
# QLabel('Platzhalter "Wie sind Sie auf uns aufmerksam geworden?"')
# )
# self.company_search.company_selected.connect(self.update_contact_persons)
container_layout.addSpacing(10)
@@ -2608,11 +3232,11 @@ class SearchFormPage(QWidget):
container_layout.addSpacing(30)
def update_contact_persons(
self,
company_id: int,
) -> None:
self.contact_person_search.update_search_data(company_id)
# def update_contact_persons(
# self,
# company_id: int,
# ) -> None:
# self.contact_person_search.update_search_data(company_id)
# 2. Das Hauptfenster mit dem Grid-Layout