fix(centralui): surface inherited compositions in the templates tree (followup #9)
The templates tree rendered a derived/composed member (e.g. LeftReactorSide, derived from ReactorSide) as a flat leaf, omitting compositions it inherits from its base (e.g. LeakTest composed onto ReactorSide). BuildCompositionLeavesFor recursed only over a template's OWN composition rows; an inherited composition row lives on the ancestor, and TemplateComposition has no IsInherited placeholder (unlike attributes/alarms/scripts/native-sources), so the child's own Compositions was empty. Same 'derived templates don't surface inherited members' family as followups #1/#2, but for compositions. Deploy/flatten was always correct (TemplateResolver.ResolveAllMembers walks the chain) — display-only. Fix: - BuildCompositionLeavesFor now renders the EFFECTIVE composition set (own + inherited) via EffectiveCompositionsFor, which walks the inheritance chain (leaf->root, child wins on InstanceName), mirroring the resolver. - Inherited slots are flagged (TemplateTreeNode.IsInherited), badged 'inherited' in the label, and their context menu offers only 'Open composed template' (Rename/Delete edit the ancestor's slot, so suppressed on inherited nodes). - The same inherited row can appear under several derived members (LeakTest under both LeftReactorSide and RightReactorSide), so composition nodes use a path-qualified KeyOverride to keep TreeView selection/expansion keys unique; recursion is cycle-guarded. Tests: +1 bUnit (TemplatesPageTests.Renders_InheritedComposition_UnderDerivedComposedMember); CentralUI suite 867 green; full solution builds 0/0. Docs: Component-CentralUI.md (effective composition set in tree); known-issues tracker #9 recorded + resolved. Note: CentralUI change — shows on wonder-app-vd03 only after that host is redeployed.
This commit is contained in:
@@ -31,8 +31,26 @@ public sealed class TemplateTreeNode
|
||||
/// <summary>Child nodes (sub-folders, templates, or composition slots).</summary>
|
||||
public List<TemplateTreeNode> Children { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// True when this composition node is <em>inherited</em> — its underlying
|
||||
/// <c>TemplateComposition</c> row belongs to an ancestor of the template it is
|
||||
/// rendered under, not to that template itself (followup #9). Inherited nodes are
|
||||
/// badged read-only and their context menu suppresses Rename/Delete (those edit the
|
||||
/// base). Always false for folders and templates.
|
||||
/// </summary>
|
||||
public bool IsInherited { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Explicit, path-qualified key override. The same inherited composition row can
|
||||
/// surface under several derived members (e.g. LeakTest under both LeftReactorSide
|
||||
/// and RightReactorSide), so a plain <c>c:{Id}</c> key would collide and break the
|
||||
/// TreeView's selection/expansion tracking. Composition nodes set this to a
|
||||
/// parent-path-qualified value; folders/templates leave it null and use the default.
|
||||
/// </summary>
|
||||
public string? KeyOverride { get; init; }
|
||||
|
||||
/// <summary>Stable key for TreeView selection / expansion tracking.</summary>
|
||||
public string Key => Kind switch
|
||||
public string Key => KeyOverride ?? Kind switch
|
||||
{
|
||||
TemplateTreeNodeKind.Folder => $"f:{Id}",
|
||||
TemplateTreeNodeKind.Template => $"t:{Id}",
|
||||
|
||||
Reference in New Issue
Block a user