diff --git a/SYS/config.py b/SYS/config.py index c5c33cc..dc930d1 100644 --- a/SYS/config.py +++ b/SYS/config.py @@ -14,6 +14,18 @@ SCRIPT_DIR = Path(__file__).resolve().parent _CONFIG_CACHE: Dict[str, Dict[str, Any]] = {} +def global_config() -> List[Dict[str, Any]]: + """Return configuration schema for global settings.""" + return [ + { + "key": "debug", + "label": "Debug Output", + "default": "false", + "choices": ["true", "false"] + } + ] + + def clear_config_cache() -> None: """Clear the configuration cache.""" _CONFIG_CACHE.clear() diff --git a/TUI/modalscreen/config_modal.py b/TUI/modalscreen/config_modal.py index ccc8e94..a80053e 100644 --- a/TUI/modalscreen/config_modal.py +++ b/TUI/modalscreen/config_modal.py @@ -9,7 +9,7 @@ import os import json from pathlib import Path -from SYS.config import load_config, save_config +from SYS.config import load_config, save_config, global_config from Store.registry import _discover_store_classes, _required_keys_for from ProviderCore.registry import list_providers from TUI.modalscreen.selection_modal import SelectionModal @@ -73,7 +73,7 @@ class ConfigModal(ModalScreen): } .item-row { - height: 3; + height: 5; margin-bottom: 1; padding: 0 1; border: solid $surface; @@ -81,12 +81,13 @@ class ConfigModal(ModalScreen): .item-label { width: 1fr; + height: 3; content-align: left middle; } .item-row Button { - width: 15; - margin-left: 1; + width: 16; + height: 3; } Button { @@ -166,9 +167,50 @@ class ConfigModal(ModalScreen): def render_globals(self, container: ScrollableContainer) -> None: container.mount(Label("General Configuration", classes="config-label")) + + # Get global schema + schema_map = {f["key"].lower(): f for f in global_config()} + existing_keys_lower = set() + idx = 0 + # Show fields defined in schema first + for key_lower, field_def in schema_map.items(): + existing_keys_lower.add(key_lower) + label_text = field_def.get("label") or field_def["key"] + choices = field_def.get("choices") + + # Find current value (case-insensitive) + current_val = None + found_key = field_def["key"] + for k, v in self.config_data.items(): + if k.lower() == key_lower: + current_val = str(v) + found_key = k + break + + if current_val is None: + current_val = str(field_def.get("default") or "") + + container.mount(Label(label_text)) + inp_id = f"global-{idx}" + self._input_id_map[inp_id] = found_key + + if choices: + select_options = [(str(c), str(c)) for c in choices] + if current_val not in [str(c) for c in choices]: + select_options.insert(0, (current_val, current_val)) + sel = Select(select_options, value=current_val, id=inp_id) + container.mount(sel) + else: + container.mount(Input(value=current_val, id=inp_id, classes="config-input")) + idx += 1 + + # Show any other top-level keys not in schema for k, v in self.config_data.items(): if not isinstance(v, dict) and not k.startswith("_"): + if k.lower() in existing_keys_lower: + continue + inp_id = f"global-{idx}" self._input_id_map[inp_id] = k container.mount(Label(k))