This commit is contained in:
2026-01-23 16:46:48 -08:00
parent 797b5fee40
commit b3a4ba14e5
5 changed files with 193 additions and 106 deletions

View File

@@ -5,7 +5,8 @@ from textual.widgets import Static, Button, Input, Label, ListView, ListItem, Ru
from textual import on, work
from typing import Any
from SYS.config import load_config, save_config, global_config
from SYS.config import load_config, save_config, reload_config, global_config
from SYS.logger import log
from Store.registry import _discover_store_classes, _required_keys_for
from ProviderCore.registry import list_providers
from TUI.modalscreen.selection_modal import SelectionModal
@@ -526,11 +527,15 @@ class ConfigModal(ModalScreen):
self.editing_item_type = None
self.refresh_view()
elif bid == "save-btn":
self._synchronize_inputs_to_config()
if not self.validate_current_editor():
return
try:
self.save_all()
self.notify("Configuration saved!")
saved = self.save_all()
msg = f"Configuration saved ({saved} entries)"
if saved == 0:
msg = "Configuration saved (no rows changed)"
self.notify(msg)
# Return to the main list view within the current category
self.editing_item_name = None
self.editing_item_type = None
@@ -557,8 +562,11 @@ class ConfigModal(ModalScreen):
removed = True
if removed:
try:
self.save_all()
self.notify("Configuration saved!")
saved = self.save_all()
msg = f"Configuration saved ({saved} entries)"
if saved == 0:
msg = "Configuration saved (no rows changed)"
self.notify(msg)
except Exception as exc:
self.notify(f"Save failed: {exc}", severity="error", timeout=10)
self.refresh_view()
@@ -707,8 +715,19 @@ class ConfigModal(ModalScreen):
key = self._input_id_map[widget_id]
# Try to preserve boolean/integer types
processed_value = value
if isinstance(value, str):
low = value.lower()
if low == "true":
processed_value = True
elif low == "false":
processed_value = False
elif value.isdigit():
processed_value = int(value)
if widget_id.startswith("global-"):
self.config_data[key] = value
self.config_data[key] = processed_value
elif widget_id.startswith("item-") and self.editing_item_name:
it = str(self.editing_item_type or "")
inm = str(self.editing_item_name or "")
@@ -722,14 +741,41 @@ class ConfigModal(ModalScreen):
self.config_data["store"][stype] = {}
if inm not in self.config_data["store"][stype]:
self.config_data["store"][stype][inm] = {}
self.config_data["store"][stype][inm][key] = value
# Special case: Renaming the store via the NAME field
if key.upper() == "NAME" and processed_value and str(processed_value) != inm:
new_inm = str(processed_value)
# Move the whole dictionary to the new key
self.config_data["store"][stype][new_inm] = self.config_data["store"][stype].pop(inm)
# Update editing_item_name so further changes to this screen hit the new key
self.editing_item_name = new_inm
inm = new_inm
self.config_data["store"][stype][inm][key] = processed_value
else:
# Provider or other top-level sections
if it not in self.config_data:
self.config_data[it] = {}
if inm not in self.config_data[it]:
self.config_data[it][inm] = {}
self.config_data[it][inm][key] = value
self.config_data[it][inm][key] = processed_value
def _synchronize_inputs_to_config(self) -> None:
"""Capture current input/select values before saving."""
widgets = list(self.query(Input)) + list(self.query(Select))
for widget in widgets:
widget_id = widget.id
if not widget_id or widget_id not in self._input_id_map:
continue
if isinstance(widget, Select):
if widget.value == Select.BLANK:
continue
value = widget.value
else:
value = widget.value
self._update_config_value(widget_id, value)
@on(Input.Changed)
def on_input_changed(self, event: Input.Changed) -> None:
@@ -743,8 +789,12 @@ class ConfigModal(ModalScreen):
if event.value != Select.BLANK:
self._update_config_value(event.select.id, event.value)
def save_all(self) -> None:
save_config(self.config_data)
def save_all(self) -> int:
self._synchronize_inputs_to_config()
entries = save_config(self.config_data)
self.config_data = reload_config()
log(f"ConfigModal saved {entries} configuration entries")
return entries
def validate_current_editor(self) -> bool:
"""Ensure all required fields for the current item are filled."""