fix(ui/templates): expand composition leaves to show cascaded slots
Composition leaves were rendered flat — the cascaded inner derived templates existed in the DB but the tree only showed the outer slot name (e.g. "Tank Monitor > DrivePump") with no way to see DrivePump's own TempSensor + AlarmSensor slots. BuildCompositionLeaves now recurses: for each composition under a template, look up the composed template (which after derive-on-compose is a derived row carrying its own Compositions) and build its slot leaves as children. HasChildrenSelector loses the "not a composition" guard so nested leaves render with the expand chevron.
This commit is contained in:
@@ -81,7 +81,7 @@
|
||||
<div style="max-height: calc(100vh - 160px); overflow-y: auto; padding: 4px;">
|
||||
<TreeView @ref="_tree" TItem="TmplNode" Items="_treeRoots"
|
||||
ChildrenSelector="n => n.Children"
|
||||
HasChildrenSelector="n => n.Kind != TmplNodeKind.Composition && n.Children.Count > 0"
|
||||
HasChildrenSelector="n => n.Children.Count > 0"
|
||||
KeySelector="n => (object)n.Key"
|
||||
StorageKey="templates-tree">
|
||||
<NodeContent Context="node">
|
||||
@@ -178,22 +178,13 @@
|
||||
|
||||
// 3. Template nodes with composition leaves. Derived templates are
|
||||
// slot-owned and reached via their parent's composition leaf — never
|
||||
// shown as standalone tree nodes.
|
||||
// shown as standalone tree nodes. Composition leaves recurse so a
|
||||
// composite slot (e.g. Pump composed with TempSensor) reveals its own
|
||||
// child slots when expanded.
|
||||
var templatesById = _templates.ToDictionary(t => t.Id);
|
||||
foreach (var t in _templates.Where(t => !t.IsDerived).OrderBy(t => t.Name, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var compChildren = t.Compositions
|
||||
.OrderBy(c => c.InstanceName, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(c => new TmplNode(
|
||||
Key: $"c:{c.Id}",
|
||||
Kind: TmplNodeKind.Composition,
|
||||
EntityId: c.Id,
|
||||
Label: c.InstanceName,
|
||||
ParentFolderId: null,
|
||||
OwnerTemplateId: t.Id,
|
||||
Template: null,
|
||||
Composition: c,
|
||||
Children: new List<TmplNode>()))
|
||||
.ToList();
|
||||
var compChildren = BuildCompositionLeaves(t, templatesById);
|
||||
|
||||
var tNode = new TmplNode(
|
||||
Key: $"t:{t.Id}",
|
||||
@@ -220,6 +211,33 @@
|
||||
_treeRoots = roots;
|
||||
}
|
||||
|
||||
// Recursive: each composition leaf's children are the composed-template's
|
||||
// own composition leaves. Cascaded derived templates carry their slot
|
||||
// compositions, so walking ComposedTemplateId surfaces the full nested
|
||||
// structure.
|
||||
private static List<TmplNode> BuildCompositionLeaves(Template owner, IReadOnlyDictionary<int, Template> templatesById)
|
||||
{
|
||||
var result = new List<TmplNode>();
|
||||
foreach (var c in owner.Compositions.OrderBy(c => c.InstanceName, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var nestedChildren = templatesById.TryGetValue(c.ComposedTemplateId, out var composed)
|
||||
? BuildCompositionLeaves(composed, templatesById)
|
||||
: new List<TmplNode>();
|
||||
|
||||
result.Add(new TmplNode(
|
||||
Key: $"c:{c.Id}",
|
||||
Kind: TmplNodeKind.Composition,
|
||||
EntityId: c.Id,
|
||||
Label: c.InstanceName,
|
||||
ParentFolderId: null,
|
||||
OwnerTemplateId: owner.Id,
|
||||
Template: null,
|
||||
Composition: c,
|
||||
Children: nestedChildren));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SortChildren(List<TmplNode> children)
|
||||
{
|
||||
children.Sort((a, b) =>
|
||||
|
||||
Reference in New Issue
Block a user