From b2eddd9713a96c1f8707164a238327ebfbf7c240 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 11 May 2026 21:29:32 -0400 Subject: [PATCH] feat(ui/templates): derived-template action and slimmer composition row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Right-click a template now offers "New Derived Template" — opens TemplateCreate with the parent pre-selected via a new ?parentId query parameter. Composition rows in the tree drop the trailing "→ TargetName" muted text; the kind glyph plus the instance name carry enough meaning, and the composed template is one click away from the row's right-click menu. --- .../2026-05-11-templates-folder-hierarchy-design.md | 8 ++++---- docs/requirements/Component-TreeView.md | 9 ++------- .../Components/Pages/Design/TemplateCreate.razor | 5 +++++ .../Components/Pages/Design/Templates.razor | 8 ++------ tests/ScadaLink.CentralUI.Tests/TemplatesPageTests.cs | 4 +++- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/docs/plans/2026-05-11-templates-folder-hierarchy-design.md b/docs/plans/2026-05-11-templates-folder-hierarchy-design.md index 9656d31..df20fce 100644 --- a/docs/plans/2026-05-11-templates-folder-hierarchy-design.md +++ b/docs/plans/2026-05-11-templates-folder-hierarchy-design.md @@ -29,7 +29,7 @@ Inheritance is **not** rendered as tree nesting in the image, and it is not rend | Root-level templates | Allowed (`FolderId` nullable). Existing templates migrate with `FolderId = null`. | | Folder delete with contents | Blocked; structured error lists child counts. | | Page layout | **Tree browser only** — no split-pane editor. Selecting a template navigates to `/design/templates/{id}` (TemplateEdit page); creating navigates to `/design/templates/create`. | -| Tree node visuals | Per `Component-TreeView.md` Visual Design Guide V7: Bootstrap Icons (`bi-folder` / `bi-folder2-open` / `bi-file-earmark-text` / `bi-arrow-return-right`), name-only labels (no count/inherit badges on template nodes), folder child-count pill, composition `→ $Target` muted secondary text. | +| Tree node visuals | Per `Component-TreeView.md` Visual Design Guide V7: Bootstrap Icons (`bi-folder` / `bi-folder2-open` / `bi-file-earmark-text` / `bi-arrow-return-right`), name-only labels (no count/inherit badges on template nodes; composition rows also name-only — the glyph signals the kind), folder child-count pill. | ## Data model @@ -144,7 +144,7 @@ private record TmplNode( **Inline node labels** (see `Component-TreeView.md` V7 for the canonical recipe): - Folder: `` (closed) or `` (expanded) + name (semibold when has children) + count-pill badge of direct children. - Template: `` + `$Name` (semibold when has compositions). **No** inheritance hint, **no** attr/alarm/script count, **no** composition count on the node. -- Composition: `` + composition instance name + muted `→ $ComposedTemplateName` secondary text. +- Composition: `` + composition instance name only. The composed template name is intentionally omitted from the tree — open the owning template's edit page to see/manage compositions. **Search/filter:** out of scope for v1; the underlying component supports external filtering (per `Component-TreeView.md` R8) so it can be added later without component changes. @@ -160,8 +160,8 @@ private record TmplNode( | ▶ 📁 _Default Templates | | ▼ 📂 Dev | | 📄 $TestMachine | -| ↪ DelmiaReceiver → $DelmiaSvc | -| ↪ MESReceiver → $MesSvc | +| ↪ DelmiaReceiver | +| ↪ MESReceiver | | 📄 $TestObject | | ▶ 📁 System | | 📄 $UnfiledTemplate | diff --git a/docs/requirements/Component-TreeView.md b/docs/requirements/Component-TreeView.md index 6d327ba..7efb214 100644 --- a/docs/requirements/Component-TreeView.md +++ b/docs/requirements/Component-TreeView.md @@ -425,7 +425,7 @@ Three node kinds; concrete recipes following V1–V6. |---|---|---|---|---|---| | Folder | `bi-folder` | `bi-folder2-open` | folder name (semibold when has children, regular otherwise) | — | count of direct children (subtle pill), only if ≥ 1 | | Template | `bi-file-earmark-text` | same (templates with compositions still use the same glyph — chevron carries state) | `$Name` (semibold when has compositions, regular otherwise) | — | none | -| Composition | `bi-arrow-return-right` | n/a (leaf, no expanded state) | composition instance name (regular weight) | `→ $TargetName` | none | +| Composition | `bi-arrow-return-right` | n/a (leaf, no expanded state) | composition instance name (regular weight) | — | none | **`NodeContent` fragment** for the templates page (replaces the current `RenderNodeLabel` in `Templates.razor`): @@ -452,13 +452,8 @@ Three node kinds; concrete recipes following V1–V6. break; case TmplNodeKind.Composition: - var composedName = _templates.FirstOrDefault(t => t.Id == node.Composition!.ComposedTemplateId)?.Name - ?? $"#{node.Composition!.ComposedTemplateId}"; - - @node.Label - → @composedName - + @node.Label break; } ``` diff --git a/src/ScadaLink.CentralUI/Components/Pages/Design/TemplateCreate.razor b/src/ScadaLink.CentralUI/Components/Pages/Design/TemplateCreate.razor index d8551a2..7af0213 100644 --- a/src/ScadaLink.CentralUI/Components/Pages/Design/TemplateCreate.razor +++ b/src/ScadaLink.CentralUI/Components/Pages/Design/TemplateCreate.razor @@ -57,6 +57,7 @@ @code { [SupplyParameterFromQuery] public int? FolderId { get; set; } + [SupplyParameterFromQuery] public int? ParentId { get; set; } private List