diff --git a/archinstall/tui/components.py b/archinstall/tui/components.py index 03349c9022..7e752f02db 100644 --- a/archinstall/tui/components.py +++ b/archinstall/tui/components.py @@ -55,6 +55,34 @@ def _translate_bindings(source: BindingsMap | None, target: BindingsMap) -> None target.key_to_bindings[key] = [replace(b, description=tr(b.description)) if b.description else b for b in bindings] +def _val_is_empty(val: Any) -> bool: + if val is None: + return True + if isinstance(val, (list, dict, set, tuple, str)) and len(val) == 0: + return True + if hasattr(val, '__dict__') and all(_val_is_empty(v) for v in vars(val).values()): + return True + return False + + +def _get_status_prefix(item: MenuItem) -> str: + """ + Returns a rich-formatted status prefix icon depending on item state: + - Space for configured items + - ! (Yellow) for unconfigured items + """ + + is_special_key = item.text in ['← ' + tr('Back'), tr('Save configuration'), tr('Install'), tr('Abort')] + + if item.read_only or is_special_key: + return '' + + if item.has_value() and not _val_is_empty(item.value): + return ' ' + else: + return '[bold yellow]![/bold yellow] ' + + class BaseScreen(Screen[Result[ValueT]]): BINDINGS: ClassVar = [ Binding('escape', 'cancel_operation', 'Cancel', show=True), @@ -287,7 +315,8 @@ def _get_options(self) -> list[Option]: for item in self._group.get_enabled_items(): disabled = True if item.read_only else False - options.append(Option(item.text, id=item.get_id(), disabled=disabled)) + option_text = _get_status_prefix(item) + item.text + options.append(Option(option_text, id=item.get_id(), disabled=disabled)) return options @@ -520,7 +549,8 @@ def _get_selections(self) -> list[Selection[MenuItem]]: for item in self._group.get_enabled_items(): is_selected = item in self._selected_items - selection = Selection(item.text, item, is_selected) + selection_text = _get_status_prefix(item) + item.text + selection = Selection(selection_text, item, is_selected) selections.append(selection) return selections