From abd1fa33cf916f3ecc16c64a97333d5c16e5b517 Mon Sep 17 00:00:00 2001 From: William Valentin Date: Fri, 1 Aug 2025 14:41:58 -0700 Subject: [PATCH] refactor: Simplify UI creation methods by removing dynamic variants and consolidating functionality --- Makefile | 17 +-- src/ui_manager.py | 349 +--------------------------------------------- 2 files changed, 7 insertions(+), 359 deletions(-) diff --git a/Makefile b/Makefile index a55402d..8b28ec9 100644 --- a/Makefile +++ b/Makefile @@ -121,21 +121,6 @@ test-watch: ## Run tests in watch mode test-debug: ## Run tests with debug output @echo "Running tests with debug output..." .venv/bin/python -m pytest tests/ -v -s --tb=long --cov=src -test-dose-tracking: ## Test the dose tracking functionality - @echo "Testing dose tracking functionality..." - .venv/bin/python scripts/test_dose_tracking.py -test-scrollable-input: ## Test the scrollable input frame UI - @echo "Testing scrollable input frame..." - .venv/bin/python scripts/test_scrollable_input.py -test-edit-functionality: ## Test the enhanced edit functionality - @echo "Testing edit functionality..." - .venv/bin/python scripts/test_edit_functionality.py -test-edit-window: $(VENV_ACTIVATE) ## Test edit window functionality (save and delete) - @echo "Running edit window functionality test..." - $(PYTHON) scripts/test_edit_window_functionality.py -test-dose-editing: $(VENV_ACTIVATE) ## Test dose editing functionality in edit window - @echo "Running dose editing functionality test..." - $(PYTHON) scripts/test_dose_editing_functionality.py lint: ## Run the linter @echo "Running the linter..." docker-compose exec ${TARGET} pipenv run pre-commit run --all-files @@ -157,4 +142,4 @@ commit-emergency: ## Emergency commit (bypasses pre-commit hooks) - USE SPARINGL @read -p "Enter commit message: " msg; \ git add . && git commit --no-verify -m "$$msg" @echo "✅ Emergency commit completed. Please run tests manually when possible." -.PHONY: install clean reinstall check-env build attach deploy run start stop test lint format shell requirements commit-emergency test-dose-tracking test-scrollable-input test-edit-functionality test-edit-window test-dose-editing migrate-csv help +.PHONY: install clean reinstall check-env build attach deploy run start stop test lint format shell requirements commit-emergency help diff --git a/src/ui_manager.py b/src/ui_manager.py index a91fb32..fd0f5b2 100644 --- a/src/ui_manager.py +++ b/src/ui_manager.py @@ -417,8 +417,8 @@ class UIManager: # Extract note (should be the last value) note = values_list[-1] if len(values_list) > 0 else "" - # Create improved UI sections dynamically - vars_dict = self._create_edit_ui_dynamic( + # Create improved UI sections + vars_dict = self._create_edit_ui( main_container, date, pathology_values, @@ -443,7 +443,7 @@ class UIManager: return edit_win - def _create_edit_ui_dynamic( + def _create_edit_ui( self, parent: ttk.Frame, date: str, @@ -500,7 +500,7 @@ class UIManager: meds_frame.grid_columnconfigure(0, weight=1) # Create medicine checkboxes dynamically - med_vars = self._create_medicine_section_dynamic(meds_frame, medicine_values) + med_vars = self._create_medicine_section(meds_frame, medicine_values) vars_dict.update(med_vars) row += 1 @@ -510,7 +510,7 @@ class UIManager: dose_frame.grid(row=row, column=0, sticky="ew", pady=(0, 15)) dose_frame.grid_columnconfigure(0, weight=1) - dose_vars = self._create_dose_tracking_dynamic(dose_frame, medicine_doses) + dose_vars = self._create_dose_tracking(dose_frame, medicine_doses) vars_dict.update(dose_vars) row += 1 @@ -543,111 +543,6 @@ class UIManager: return vars_dict - def _create_edit_ui( - self, - parent: ttk.Frame, - date: str, - dep: int, - anx: int, - slp: int, - app: int, - bup: int, - hydro: int, - gaba: int, - prop: int, - quet: int, - note: str, - dose_data: dict[str, str], - ) -> dict[str, Any]: - """Create UI layout for edit window with organized sections.""" - vars_dict = {} - row = 0 - - # Header with entry date - header_frame = ttk.Frame(parent) - header_frame.grid(row=row, column=0, sticky="ew", pady=(0, 20)) - header_frame.grid_columnconfigure(1, weight=1) - - ttk.Label( - header_frame, text="Editing Entry for:", font=("TkDefaultFont", 12, "bold") - ).grid(row=0, column=0, sticky="w") - - vars_dict["date"] = tk.StringVar(value=str(date)) - date_entry = ttk.Entry( - header_frame, - textvariable=vars_dict["date"], - font=("TkDefaultFont", 12), - width=15, - ) - date_entry.grid(row=0, column=1, sticky="w", padx=(10, 0)) - - row += 1 - - # Symptoms section - symptoms_frame = ttk.LabelFrame( - parent, text="Daily Symptoms (0-10 scale)", padding="15" - ) - symptoms_frame.grid(row=row, column=0, sticky="ew", pady=(0, 15)) - symptoms_frame.grid_columnconfigure(1, weight=1) - - # Create symptom scales with better layout - symptoms = [ - ("Depression", "depression", dep), - ("Anxiety", "anxiety", anx), - ("Sleep Quality", "sleep", slp), - ("Appetite", "appetite", app), - ] - - for i, (label, key, value) in enumerate(symptoms): - self._create_symptom_scale(symptoms_frame, i, label, key, value, vars_dict) - - row += 1 - - # Medications section - meds_frame = ttk.LabelFrame(parent, text="Medications Taken", padding="15") - meds_frame.grid(row=row, column=0, sticky="ew", pady=(0, 15)) - meds_frame.grid_columnconfigure(0, weight=1) - - # Create medicine checkboxes with better styling - med_vars = self._create_medicine_section( - meds_frame, bup, hydro, gaba, prop, quet - ) - vars_dict.update(med_vars) - - row += 1 - - # Dose tracking section - dose_frame = ttk.LabelFrame(parent, text="Dose Tracking", padding="15") - dose_frame.grid(row=row, column=0, sticky="ew", pady=(0, 15)) - dose_frame.grid_columnconfigure(0, weight=1) - - dose_vars = self._create_dose_tracking(dose_frame, dose_data) - vars_dict.update(dose_vars) - - row += 1 - - # Notes section - notes_frame = ttk.LabelFrame(parent, text="Notes", padding="15") - notes_frame.grid(row=row, column=0, sticky="ew", pady=(0, 20)) - notes_frame.grid_columnconfigure(0, weight=1) - - vars_dict["note"] = tk.StringVar(value=str(note)) - note_text = tk.Text( - notes_frame, height=4, wrap=tk.WORD, font=("TkDefaultFont", 10) - ) - note_text.grid(row=0, column=0, sticky="ew") - note_text.insert(1.0, str(note)) - vars_dict["note_text"] = note_text - - # Add scrollbar for notes - note_scroll = ttk.Scrollbar( - notes_frame, orient="vertical", command=note_text.yview - ) - note_scroll.grid(row=0, column=1, sticky="ns") - note_text.configure(yscrollcommand=note_scroll.set) - - return vars_dict - def _create_symptom_scale( self, parent: ttk.Frame, @@ -734,91 +629,6 @@ class UIManager: scale.bind("", update_value_label) update_value_label() # Set initial color - def _create_enhanced_symptom_scale( - self, - parent: ttk.Frame, - row: int, - label: str, - key: str, - value: int, - vars_dict: dict[str, tk.IntVar], - ) -> None: - """Create enhanced symptom scale for new entry form (like edit window).""" - # Ensure value is properly converted - try: - value = int(float(value)) if value not in ["", None] else 0 - except (ValueError, TypeError): - value = 0 - - # Label - label_widget = ttk.Label( - parent, text=f"{label} (0-10):", font=("TkDefaultFont", 10, "bold") - ) - label_widget.grid(row=row, column=0, sticky="w", padx=5, pady=8) - - # Scale container - scale_container = ttk.Frame(parent) - scale_container.grid(row=row, column=1, sticky="ew", padx=(20, 5), pady=8) - scale_container.grid_columnconfigure(0, weight=1) - - # Scale with value labels - scale_frame = ttk.Frame(scale_container) - scale_frame.grid(row=0, column=0, sticky="ew") - scale_frame.grid_columnconfigure(1, weight=1) - - # Current value display - value_label = ttk.Label( - scale_frame, - text=str(value), - font=("TkDefaultFont", 12, "bold"), - foreground="#2E86AB", - width=3, - ) - value_label.grid(row=0, column=0, padx=(0, 10)) - - # Scale widget - scale = ttk.Scale( - scale_frame, - from_=0, - to=10, - variable=vars_dict[key], - orient=tk.HORIZONTAL, - length=250, # Slightly smaller than edit window to fit better - ) - scale.grid(row=0, column=1, sticky="ew") - - # Scale labels (0, 5, 10) - labels_frame = ttk.Frame(scale_container) - labels_frame.grid(row=1, column=0, sticky="ew", pady=(5, 0)) - - ttk.Label(labels_frame, text="0", font=("TkDefaultFont", 8)).grid( - row=0, column=0, sticky="w" - ) - labels_frame.grid_columnconfigure(1, weight=1) - ttk.Label(labels_frame, text="5", font=("TkDefaultFont", 8)).grid( - row=0, column=1 - ) - ttk.Label(labels_frame, text="10", font=("TkDefaultFont", 8)).grid( - row=0, column=2, sticky="e" - ) - - # Update label when scale changes - def update_value_label(event=None): - current_val = vars_dict[key].get() - value_label.configure(text=str(current_val)) - # Change color based on value - if current_val <= 3: - value_label.configure(foreground="#28A745") # Green for low/good - elif current_val <= 6: - value_label.configure(foreground="#FFC107") # Yellow for medium - else: - value_label.configure(foreground="#DC3545") # Red for high/bad - - scale.bind("", update_value_label) - scale.bind("", update_value_label) - scale.bind("", update_value_label) - update_value_label() # Set initial color - def _create_enhanced_pathology_scale( self, parent: ttk.Frame, @@ -928,153 +738,6 @@ class UIManager: update_value_label_pathology() # Set initial color def _create_medicine_section( - self, parent: ttk.Frame, bup: int, hydro: int, gaba: int, prop: int, quet: int - ) -> dict[str, tk.IntVar]: - """Create medicine checkboxes with organized layout.""" - vars_dict = {} - - # Create a grid layout for medicines - medicines = [ - ("bupropion", bup, "Bupropion", "150/300 mg", "#E8F4FD"), - ("hydroxyzine", hydro, "Hydroxyzine", "25 mg", "#FFF2E8"), - ("gabapentin", gaba, "Gabapentin", "100 mg", "#F0F8E8"), - ("propranolol", prop, "Propranolol", "10 mg", "#FCE8F3"), - ("quetiapine", quet, "Quetiapine", "25 mg", "#E8F0FF"), - ] - - # Create medicine cards in a 2-column layout - for i, (key, value, name, dose, _bg_color) in enumerate(medicines): - row = i // 2 - col = i % 2 - - # Medicine card frame - med_card = ttk.Frame(parent, relief="solid", borderwidth=1) - med_card.grid(row=row, column=col, sticky="ew", padx=5, pady=5) - parent.grid_columnconfigure(col, weight=1) - - vars_dict[key] = tk.IntVar(value=int(value)) - - # Checkbox with medicine name - check_frame = ttk.Frame(med_card) - check_frame.pack(fill="x", padx=10, pady=8) - - checkbox = ttk.Checkbutton( - check_frame, - text=f"{name} ({dose})", - variable=vars_dict[key], - style="Medicine.TCheckbutton", - ) - checkbox.pack(anchor="w") - - return vars_dict - - def _create_dose_tracking( - self, parent: ttk.Frame, dose_data: dict[str, str] - ) -> dict[str, Any]: - """Create dose tracking interface.""" - vars_dict = {} - - # Create notebook for organized dose tracking - notebook = ttk.Notebook(parent) - notebook.pack(fill="both", expand=True) - - medicines = [ - ("bupropion", "Bupropion"), - ("hydroxyzine", "Hydroxyzine"), - ("gabapentin", "Gabapentin"), - ("propranolol", "Propranolol"), - ("quetiapine", "Quetiapine"), - ] - - for med_key, med_name in medicines: - # Create tab for each medicine - tab_frame = ttk.Frame(notebook) - notebook.add(tab_frame, text=med_name) - - # Configure tab layout - tab_frame.grid_columnconfigure(0, weight=1) - - # Quick dose entry section - entry_frame = ttk.LabelFrame(tab_frame, text="Add New Dose", padding="10") - entry_frame.grid(row=0, column=0, sticky="ew", padx=10, pady=5) - entry_frame.grid_columnconfigure(1, weight=1) - - ttk.Label(entry_frame, text="Dose amount:").grid( - row=0, column=0, sticky="w" - ) - - dose_entry_var = tk.StringVar() - vars_dict[f"{med_key}_entry_var"] = dose_entry_var - - dose_entry = ttk.Entry(entry_frame, textvariable=dose_entry_var, width=15) - dose_entry.grid(row=0, column=1, sticky="w", padx=(10, 10)) - - # Quick dose buttons - quick_frame = ttk.Frame(entry_frame) - quick_frame.grid(row=0, column=2, sticky="w") - - # Common dose amounts (customize per medicine) - quick_doses = self._get_quick_doses(med_key) - for i, dose in enumerate(quick_doses): - ttk.Button( - quick_frame, - text=dose, - width=8, - command=lambda d=dose, var=dose_entry_var: var.set(d), - ).grid(row=0, column=i, padx=2) - - # Take dose button - def create_take_dose_command(med_name, entry_var, med_key): - def take_dose(): - self._take_dose(med_name, entry_var, med_key, vars_dict) - - return take_dose - - take_button = ttk.Button( - entry_frame, - text=f"Take {med_name}", - style="Accent.TButton", - command=create_take_dose_command(med_name, dose_entry_var, med_key), - ) - take_button.grid(row=1, column=0, columnspan=3, pady=(10, 0), sticky="ew") - - # Dose history section - history_frame = ttk.LabelFrame( - tab_frame, text="Today's Doses", padding="10" - ) - history_frame.grid(row=1, column=0, sticky="ew", padx=10, pady=5) - history_frame.grid_columnconfigure(0, weight=1) - - # Dose history display with fixed height to prevent excessive expansion - dose_text = tk.Text( - history_frame, - height=4, # Reduced height to fit better in scrollable window - wrap=tk.WORD, - font=("Consolas", 10), - state="normal", # Start enabled - ) - dose_text.grid(row=0, column=0, sticky="ew") - - # Store raw dose string in a variable - doses_str = dose_data.get(med_key, "") - dose_str_var = tk.StringVar(value=doses_str) - vars_dict[f"{med_key}_doses_str"] = dose_str_var - - # Populate with existing doses - self._populate_dose_history(dose_text, dose_str_var.get()) - - vars_dict[f"{med_key}_doses_text"] = dose_text - - # Scrollbar for dose history - dose_scroll = ttk.Scrollbar( - history_frame, orient="vertical", command=dose_text.yview - ) - dose_scroll.grid(row=0, column=1, sticky="ns") - dose_text.configure(yscrollcommand=dose_scroll.set) - - return vars_dict - - def _create_medicine_section_dynamic( self, parent: ttk.Frame, medicine_values: dict[str, int] ) -> dict[str, tk.IntVar]: """Create medicine checkboxes dynamically.""" @@ -1121,7 +784,7 @@ class UIManager: return vars_dict - def _create_dose_tracking_dynamic( + def _create_dose_tracking( self, parent: ttk.Frame, medicine_doses: dict[str, str] ) -> dict[str, Any]: """Create dose tracking interface dynamically."""