Show install summary when configuration is valid (#4475)
* Show install summary when configuration is valid Previously the Install menu preview was empty when everything was valid, leaving the user with no "ready" signal. Now show "Ready to install" plus a two-column summary of the current configuration. - New _install_summary() composes an aligned key/value table with rows for disks+FS+LUKS, bootloader, kernel, profile, greeter, package count, network, locale and timezone. Column width adapts to the longest translated label so translations keep the alignment. - Rows whose underlying config is not set are skipped rather than rendered as empty. - base.pot / uk base.po: add new msgids for summary labels. * Move install summary into ConfigurationOutput The summary helper that renders the install preview's two-column configuration overview lived in GlobalMenu. Move it to ConfigurationOutput.as_summary() so it sits alongside the JSON output methods that share the same role. The preview now syncs menu state to ArchConfig and delegates rendering.
This commit is contained in:
parent
8cc35f41d8
commit
08cba236f6
|
|
@ -10,6 +10,8 @@ from archinstall.lib.args import ArchConfig
|
||||||
from archinstall.lib.crypt import encrypt
|
from archinstall.lib.crypt import encrypt
|
||||||
from archinstall.lib.menu.helpers import Confirmation, Selection
|
from archinstall.lib.menu.helpers import Confirmation, Selection
|
||||||
from archinstall.lib.menu.util import get_password, prompt_dir
|
from archinstall.lib.menu.util import get_password, prompt_dir
|
||||||
|
from archinstall.lib.models.bootloader import Bootloader
|
||||||
|
from archinstall.lib.models.network import NetworkConfiguration
|
||||||
from archinstall.lib.output import debug, logger, warn
|
from archinstall.lib.output import debug, logger, warn
|
||||||
from archinstall.lib.translationhandler import tr
|
from archinstall.lib.translationhandler import tr
|
||||||
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
|
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
|
||||||
|
|
@ -58,6 +60,70 @@ class ConfigurationOutput:
|
||||||
debug(' -- Chosen configuration --')
|
debug(' -- Chosen configuration --')
|
||||||
debug(self.user_config_to_json())
|
debug(self.user_config_to_json())
|
||||||
|
|
||||||
|
def as_summary(self) -> str:
|
||||||
|
"""
|
||||||
|
Render a concise two-column summary of the current configuration.
|
||||||
|
|
||||||
|
The left column holds section labels, the right column holds values.
|
||||||
|
Column width adapts to the longest translated label so translations
|
||||||
|
do not break the alignment. Rows whose underlying config is not set
|
||||||
|
are skipped.
|
||||||
|
|
||||||
|
Returns an empty string if nothing meaningful to show.
|
||||||
|
"""
|
||||||
|
rows: list[tuple[str, str]] = []
|
||||||
|
|
||||||
|
disk_config = self._config.disk_config
|
||||||
|
if disk_config and disk_config.device_modifications:
|
||||||
|
disk_parts: list[str] = []
|
||||||
|
for mod in disk_config.device_modifications:
|
||||||
|
path = str(mod.device_path)
|
||||||
|
root_part = mod.get_root_partition()
|
||||||
|
flags: list[str] = []
|
||||||
|
if root_part and root_part.fs_type:
|
||||||
|
flags.append(root_part.fs_type.value)
|
||||||
|
if disk_config.disk_encryption:
|
||||||
|
flags.append(tr('LUKS'))
|
||||||
|
disk_parts.append(f'{path} ({" + ".join(flags)})' if flags else path)
|
||||||
|
rows.append((tr('Disks'), ', '.join(disk_parts)))
|
||||||
|
|
||||||
|
bl_config = self._config.bootloader_config
|
||||||
|
if bl_config and bl_config.bootloader != Bootloader.NO_BOOTLOADER:
|
||||||
|
rows.append((tr('Bootloader'), bl_config.bootloader.value))
|
||||||
|
|
||||||
|
kernels = self._config.kernels
|
||||||
|
if kernels:
|
||||||
|
rows.append((tr('Kernel'), ', '.join(kernels)))
|
||||||
|
|
||||||
|
profile_config = self._config.profile_config
|
||||||
|
if profile_config and profile_config.profile:
|
||||||
|
names = profile_config.profile.current_selection_names()
|
||||||
|
rows.append((tr('Profile'), ', '.join(names) if names else profile_config.profile.name))
|
||||||
|
if profile_config.greeter:
|
||||||
|
rows.append((tr('Greeter'), profile_config.greeter.value))
|
||||||
|
|
||||||
|
packages = self._config.packages
|
||||||
|
if packages:
|
||||||
|
rows.append((tr('Packages'), str(len(packages))))
|
||||||
|
|
||||||
|
net_config = self._config.network_config
|
||||||
|
if isinstance(net_config, NetworkConfiguration):
|
||||||
|
rows.append((tr('Network'), net_config.type.display_msg()))
|
||||||
|
|
||||||
|
locale_config = self._config.locale_config
|
||||||
|
if locale_config:
|
||||||
|
rows.append((tr('Locale'), locale_config.sys_lang))
|
||||||
|
|
||||||
|
tz = self._config.timezone
|
||||||
|
if tz:
|
||||||
|
rows.append((tr('Timezone'), tz))
|
||||||
|
|
||||||
|
if not rows:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
label_width = max(len(label) for label, _ in rows) + 2
|
||||||
|
return '\n'.join(f'{label:<{label_width}}{value}' for label, value in rows)
|
||||||
|
|
||||||
async def confirm_config(self) -> bool:
|
async def confirm_config(self) -> bool:
|
||||||
header = f'{tr("The specified configuration will be applied")}. '
|
header = f'{tr("The specified configuration will be applied")}. '
|
||||||
header += tr('Would you like to continue?') + '\n'
|
header += tr('Would you like to continue?') + '\n'
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from archinstall.lib.args import ArchConfig
|
||||||
from archinstall.lib.authentication.authentication_menu import AuthenticationMenu
|
from archinstall.lib.authentication.authentication_menu import AuthenticationMenu
|
||||||
from archinstall.lib.bootloader.bootloader_menu import BootloaderMenu
|
from archinstall.lib.bootloader.bootloader_menu import BootloaderMenu
|
||||||
from archinstall.lib.bootloader.utils import validate_bootloader_layout
|
from archinstall.lib.bootloader.utils import validate_bootloader_layout
|
||||||
from archinstall.lib.configuration import save_config
|
from archinstall.lib.configuration import ConfigurationOutput, save_config
|
||||||
from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu
|
from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu
|
||||||
from archinstall.lib.general.general_menu import select_hostname, select_ntp, select_timezone
|
from archinstall.lib.general.general_menu import select_hostname, select_ntp, select_timezone
|
||||||
from archinstall.lib.general.system_menu import select_kernel, select_swap
|
from archinstall.lib.general.system_menu import select_kernel, select_swap
|
||||||
|
|
@ -504,7 +504,11 @@ class GlobalMenu(AbstractMenu[None]):
|
||||||
if error := self._validate_bootloader():
|
if error := self._validate_bootloader():
|
||||||
return tr(f'Invalid configuration: {error}')
|
return tr(f'Invalid configuration: {error}')
|
||||||
|
|
||||||
return None
|
self.sync_all_to_config()
|
||||||
|
summary = ConfigurationOutput(self._arch_config).as_summary()
|
||||||
|
if summary:
|
||||||
|
return f'{tr("Ready to install")}\n\n{summary}'
|
||||||
|
return tr('Ready to install')
|
||||||
|
|
||||||
def _prev_profile(self, item: MenuItem) -> str | None:
|
def _prev_profile(self, item: MenuItem) -> str | None:
|
||||||
profile_config: ProfileConfiguration | None = item.value
|
profile_config: ProfileConfiguration | None = item.value
|
||||||
|
|
|
||||||
|
|
@ -1248,6 +1248,21 @@ msgstr ""
|
||||||
msgid "Invalid configuration: {error}"
|
msgid "Invalid configuration: {error}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Ready to install"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disks"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Packages"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Network"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Locale"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1222,6 +1222,21 @@ msgstr "Модель"
|
||||||
msgid "Invalid configuration: {error}"
|
msgid "Invalid configuration: {error}"
|
||||||
msgstr "Неправильна конфігурація: {error}"
|
msgstr "Неправильна конфігурація: {error}"
|
||||||
|
|
||||||
|
msgid "Ready to install"
|
||||||
|
msgstr "Готово до встановлення"
|
||||||
|
|
||||||
|
msgid "Disks"
|
||||||
|
msgstr "Диски"
|
||||||
|
|
||||||
|
msgid "Packages"
|
||||||
|
msgstr "Пакети"
|
||||||
|
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Мережа"
|
||||||
|
|
||||||
|
msgid "Locale"
|
||||||
|
msgstr "Локаль"
|
||||||
|
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Тип"
|
msgstr "Тип"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue