Add medicine management functionality with UI and data handling

- Implemented MedicineManagementWindow for adding, editing, and removing medicines.
- Created MedicineManager to handle medicine configurations, including loading and saving to JSON.
- Updated UIManager to dynamically generate medicine-related UI components based on the MedicineManager.
- Enhanced test suite with mock objects for MedicineManager to ensure proper functionality in DataManager tests.
- Added validation for medicine input fields in the UI.
- Introduced default medicine configurations for initial setup.
This commit is contained in:
William Valentin
2025-07-30 16:01:02 -07:00
parent ea30cb88c9
commit d7d4b332d4
34 changed files with 1370 additions and 2576 deletions

View File

@@ -7,30 +7,43 @@ import pandas as pd
from matplotlib.axes import Axes
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from medicine_manager import MedicineManager
class GraphManager:
"""Handle all graph-related operations for the application."""
def __init__(self, parent_frame: ttk.LabelFrame) -> None:
def __init__(
self, parent_frame: ttk.LabelFrame, medicine_manager: MedicineManager
) -> None:
self.parent_frame: ttk.LabelFrame = parent_frame
self.medicine_manager = medicine_manager
# Configure graph frame to expand
self.parent_frame.grid_rowconfigure(0, weight=1)
self.parent_frame.grid_columnconfigure(0, weight=1)
# Initialize toggle variables for chart elements
self._initialize_toggle_vars()
self._setup_ui()
def _initialize_toggle_vars(self) -> None:
"""Initialize toggle variables for chart elements."""
# Initialize symptom toggles (always shown by default)
self.toggle_vars: dict[str, tk.BooleanVar] = {
"depression": tk.BooleanVar(value=True),
"anxiety": tk.BooleanVar(value=True),
"sleep": tk.BooleanVar(value=True),
"appetite": tk.BooleanVar(value=True),
"bupropion": tk.BooleanVar(value=False),
"hydroxyzine": tk.BooleanVar(value=False),
"gabapentin": tk.BooleanVar(value=False),
"propranolol": tk.BooleanVar(value=False),
"quetiapine": tk.BooleanVar(value=False),
}
# Add medicine toggles dynamically
for medicine_key in self.medicine_manager.get_medicine_keys():
medicine = self.medicine_manager.get_medicine(medicine_key)
default_value = medicine.default_enabled if medicine else False
self.toggle_vars[medicine_key] = tk.BooleanVar(value=default_value)
def _setup_ui(self) -> None:
"""Set up the UI components."""
# Create control frame for toggles
self.control_frame: ttk.Frame = ttk.Frame(self.parent_frame)
self.control_frame.grid(row=0, column=0, sticky="ew", padx=5, pady=5)
@@ -84,26 +97,20 @@ class GraphManager:
)
checkbox.pack(side="left", padx=3)
# Medicines toggles
# Medicines toggles - dynamic based on medicine manager
medicines_frame = ttk.LabelFrame(self.control_frame, text="Medicines")
medicines_frame.pack(side="left", padx=5, pady=2)
medicine_configs = [
("bupropion", "Bupropion"),
("hydroxyzine", "Hydroxyzine"),
("gabapentin", "Gabapentin"),
("propranolol", "Propranolol"),
("quetiapine", "Quetiapine"),
]
for key, label in medicine_configs:
checkbox = ttk.Checkbutton(
medicines_frame,
text=label,
variable=self.toggle_vars[key],
command=self._handle_toggle_changed,
)
checkbox.pack(side="left", padx=3)
for medicine_key in self.medicine_manager.get_medicine_keys():
medicine = self.medicine_manager.get_medicine(medicine_key)
if medicine:
checkbox = ttk.Checkbutton(
medicines_frame,
text=medicine.display_name,
variable=self.toggle_vars[medicine_key],
command=self._handle_toggle_changed,
)
checkbox.pack(side="left", padx=3)
def _handle_toggle_changed(self) -> None:
"""Handle toggle changes by replotting the graph."""
@@ -147,13 +154,8 @@ class GraphManager:
has_plotted_series = True
# Plot medicine dose data
medicine_colors = {
"bupropion": "#FF6B6B", # Red
"hydroxyzine": "#4ECDC4", # Teal
"gabapentin": "#45B7D1", # Blue
"propranolol": "#96CEB4", # Green
"quetiapine": "#FFEAA7", # Yellow
}
# Get medicine colors from medicine manager
medicine_colors = self.medicine_manager.get_graph_colors()
medicines = [
"bupropion",