Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/ui/tabs/generate_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from core.base_tab import BaseTab
from core.project_worker import ProjectWorker
from ui.components.accordion_expander import AccordionExpander
from ui.components.validation_footer import ValidationFooter
from ui.dialogs.success_dialog import SuccessDialog

Expand Down Expand Up @@ -111,7 +112,17 @@ def setup_ui(self):
content_layout.addWidget(ui_group)

self._modules_lbl = self._make_summary_label()
modules_group = self._make_section_group("Modules", self._modules_lbl)
self._modules_expander = AccordionExpander(
"",

Copilot AI Apr 4, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AccordionExpander is constructed with an empty title (""). In the current AccordionExpander implementation the title QLabel is always shown, so an empty title can still reserve vertical space and render as a blank header line. Consider providing a meaningful title (e.g. "Optional modules") or updating the component usage so the title label is hidden when the title is empty, to avoid awkward layout/UX.

Suggested change
"",
"Optional modules",

Copilot uses AI. Check for mistakes.
subtitle="Expand to review selected optional modules",
start_expanded=True,
)
self._modules_expander.body_layout.addWidget(self._modules_lbl)
modules_group = QGroupBox("Modules")
modules_inner = QVBoxLayout()
modules_inner.setContentsMargins(6, 6, 6, 6)
modules_inner.addWidget(self._modules_expander)
modules_group.setLayout(modules_inner)
Comment on lines +121 to +125

Copilot AI Apr 4, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Modules section is now created with a custom QGroupBox/QVBoxLayout block instead of reusing _make_section_group, which is used for the other sections. This introduces duplicated layout construction and different margin behavior for Modules vs the rest. Consider generalizing _make_section_group to accept a QWidget (not just QLabel) and optional margins/spacing, then reuse it here to keep section construction consistent and easier to maintain.

Copilot uses AI. Check for mistakes.
self._section_groups["Modules"] = modules_group
content_layout.addWidget(modules_group)

Expand Down Expand Up @@ -198,6 +209,7 @@ def reset(self) -> None:
icon.setToolTip("")
for group in self._section_groups.values():
group.setStyleSheet("")
self._modules_expander.set_expanded(True)
self._overall_status_lbl.setText("")
self._log_text.clear()
self._progress_bar.setValue(0)
Expand Down
57 changes: 57 additions & 0 deletions tests/test_generate_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pytest
from PySide6.QtWidgets import QApplication, QGroupBox, QScrollArea

from ui.components.accordion_expander import AccordionExpander
from ui.tabs.generate_tab import GenerateTab


Expand Down Expand Up @@ -570,3 +571,59 @@ def test_scroll_area_is_qscrollarea(self, generate_tab):
def test_section_groups_are_qgroupbox_instances(self, generate_tab):
for group in generate_tab._section_groups.values():
assert isinstance(group, QGroupBox)


class TestGenerateTabModulesAccordion:
"""The Modules section uses an AccordionExpander for expand/collapse."""

def test_modules_expander_attribute_exists(self, generate_tab):
assert hasattr(generate_tab, "_modules_expander")

def test_modules_expander_is_accordion_expander(self, generate_tab):
assert isinstance(generate_tab._modules_expander, AccordionExpander)

def test_modules_expander_starts_expanded(self, generate_tab):
assert generate_tab._modules_expander.is_expanded is True

def test_modules_expander_can_be_collapsed(self, generate_tab):
generate_tab._modules_expander.set_expanded(False)
assert generate_tab._modules_expander.is_expanded is False

def test_modules_expander_can_be_re_expanded(self, generate_tab):
generate_tab._modules_expander.set_expanded(False)
generate_tab._modules_expander.set_expanded(True)
assert generate_tab._modules_expander.is_expanded is True

def test_modules_expander_contains_modules_label(self, generate_tab):
# The body layout of the expander should contain _modules_lbl
body_layout = generate_tab._modules_expander.body_layout
found = False
for i in range(body_layout.count()):
item = body_layout.itemAt(i)
if item and item.widget() is generate_tab._modules_lbl:
found = True
break
assert found

def test_modules_label_contains_expected_content_after_config_update(self, generate_tab):
generate_tab.update_full_config(SAMPLE_CONFIG)
generate_tab._modules_expander.set_expanded(True)
assert "Moonbase" in generate_tab._modules_lbl.text()

def test_modules_section_group_wraps_expander(self, generate_tab):
modules_group = generate_tab._section_groups["Modules"]
# The QGroupBox layout must contain the AccordionExpander
layout = modules_group.layout()
found = False
for i in range(layout.count()):
item = layout.itemAt(i)
if item and item.widget() is generate_tab._modules_expander:
found = True
break
assert found

def test_reset_leaves_expander_expanded(self, generate_tab):
generate_tab._modules_expander.set_expanded(False)
generate_tab.reset()
# reset() should restore the expander to its default expanded state
assert generate_tab._modules_expander.is_expanded is True
Loading