lazy toolbox: keep hidden placements in the integrated panel

This commit is contained in:
mvdbeek
2026-07-28 17:27:47 +02:00
parent c5111b1b33
commit 266a39ac92
2 changed files with 42 additions and 4 deletions
+17 -4
View File
@@ -708,16 +708,29 @@ class LazyToolBox(ToolBox):
return [placement for placement in placements if placement.tool_id in keep]
def _latest_panel_tool_ids(self, tool_ids: list[str]) -> list[str]:
"""Collapse each lineage's placements to its newest version's id.
Hidden and visible entries collapse independently (the lineage key
carries ``entry.hidden``): :meth:`_place_stub` mirrors every
placement into the integrated panel — hidden included — but only
visible ones into the live panel. Dropping hidden entries here (as an
earlier revision did) kept their placements from ever reaching
``_place_stub``, so a fast-path boot persisted
``integrated_tool_panel.xml`` without hidden tools, losing their
positions. Keeping the latest hidden lineage member routes its
placement to the integrated projection while a visible sibling in the
same lineage still reaches the live panel.
"""
if self._tool_index is None:
return tool_ids
ordered_lineages: list[tuple[str | None, str]] = []
latest_by_lineage: dict[tuple[str | None, str], ToolIndexEntry] = {}
ordered_lineages: list[tuple[str | None, str, bool]] = []
latest_by_lineage: dict[tuple[str | None, str, bool], ToolIndexEntry] = {}
for tool_id in tool_ids:
entry = self._tool_index.entries.get(tool_id)
if entry is None or entry.hidden:
if entry is None:
continue
lineage_id = remove_version_from_guid(entry.id) or entry.id
lineage_key = (entry.panel_section_id, lineage_id)
lineage_key = (entry.panel_section_id, lineage_id, entry.hidden)
current = latest_by_lineage.get(lineage_key)
if current is None:
ordered_lineages.append(lineage_key)
+25
View File
@@ -715,3 +715,28 @@ def test_invalidate_index_cache_keeps_materialised_tool_when_content_unchanged()
box.invalidate_index_cache()
assert box.get_tool("tool1") is original
def test_fast_path_places_hidden_entry_in_integrated_panel_only():
box = _registry_box()
visible = _entry(
id="visible_tool", version="1.0", hidden=False, panel_section_id="sec1", panel_section_name="Section 1"
)
hidden = _entry(
id="hidden_tool", version="1.0", hidden=True, panel_section_id="sec1", panel_section_name="Section 1"
)
box._tool_index.add_entry(visible)
box._tool_index.add_entry(hidden)
placements = box._index_panel_items()
assert {p.tool_id for p in placements} == {"visible_tool", "hidden_tool"}
for placement in placements:
stub = box._register_lazy_entry(box._tool_index.entries[placement.tool_id], place_in_panel=False)
box._place_stub(stub, placement.section_id, placement.section_name, hidden=placement.hidden)
integrated = box._integrated_tool_panel["sec1"].elems
assert integrated.has_tool_with_id("hidden_tool")
assert integrated.has_tool_with_id("visible_tool")
live = box._tool_panel["sec1"].elems
assert live.has_tool_with_id("visible_tool")
assert not live.has_tool_with_id("hidden_tool")