From 5b4a27b23e4f9d00464b15325ad2aa09ddf59d8b Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Fri, 21 Aug 2026 07:42:14 -0400 Subject: [PATCH] feat(centralui): Create Instance picks its template from the folder tree (+ ?templateId preselect) Claude-Session: https://claude.ai/code/session_01G2GHPnbbKGvyyfbr2XBRVH --- .../2026-08-21-template-picker.md.tasks.json | 67 +++++- .../Pages/Deployment/InstanceCreate.razor | 66 +++++- .../InstanceCreateTemplateFieldTests.cs | 215 ++++++++++++++++++ 3 files changed, 327 insertions(+), 21 deletions(-) create mode 100644 tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Deployment/InstanceCreateTemplateFieldTests.cs diff --git a/docs/plans/2026-08-21-template-picker.md.tasks.json b/docs/plans/2026-08-21-template-picker.md.tasks.json index 29f45041..715cc599 100644 --- a/docs/plans/2026-08-21-template-picker.md.tasks.json +++ b/docs/plans/2026-08-21-template-picker.md.tasks.json @@ -1,14 +1,61 @@ { "planPath": "docs/plans/2026-08-21-template-picker.md", "tasks": [ - {"id": 1, "subject": "Task 1: TemplatePathFormatter (pure helper)", "status": "pending"}, - {"id": 2, "subject": "Task 2: TemplateFolderTree.RevealKeys (additive)", "status": "pending"}, - {"id": 3, "subject": "Task 3: TemplatePickerDialog component", "status": "pending", "blockedBy": [1, 2]}, - {"id": 4, "subject": "Task 4: Create page — picker field + ?templateId= preselect", "status": "pending", "blockedBy": [3]}, - {"id": 5, "subject": "Task 5: Templates page — New Instance… menu item (Deployer-gated)", "status": "pending"}, - {"id": 6, "subject": "Task 6: Pin the Topology Disable confirm label", "status": "pending"}, - {"id": 7, "subject": "Task 7: Docs", "status": "pending", "blockedBy": [4, 5, 6]}, - {"id": 8, "subject": "Task 8: Solution build + CentralUI test sweep + live rig check", "status": "pending", "blockedBy": [7]} + { + "id": 1, + "subject": "Task 1: TemplatePathFormatter (pure helper)", + "status": "completed" + }, + { + "id": 2, + "subject": "Task 2: TemplateFolderTree.RevealKeys (additive)", + "status": "completed" + }, + { + "id": 3, + "subject": "Task 3: TemplatePickerDialog component", + "status": "completed", + "blockedBy": [ + 1, + 2 + ] + }, + { + "id": 4, + "subject": "Task 4: Create page \u2014 picker field + ?templateId= preselect", + "status": "pending", + "blockedBy": [ + 3 + ] + }, + { + "id": 5, + "subject": "Task 5: Templates page \u2014 New Instance\u2026 menu item (Deployer-gated)", + "status": "pending" + }, + { + "id": 6, + "subject": "Task 6: Pin the Topology Disable confirm label", + "status": "pending" + }, + { + "id": 7, + "subject": "Task 7: Docs", + "status": "pending", + "blockedBy": [ + 4, + 5, + 6 + ] + }, + { + "id": 8, + "subject": "Task 8: Solution build + CentralUI test sweep + live rig check", + "status": "pending", + "blockedBy": [ + 7 + ] + } ], - "lastUpdated": "2026-08-21T12:00:00Z" -} + "lastUpdated": "2026-08-21T00:00:00Z" +} \ No newline at end of file diff --git a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceCreate.razor b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceCreate.razor index 34c43e75..93f56781 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceCreate.razor +++ b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceCreate.razor @@ -9,6 +9,7 @@ @using ZB.MOM.WW.ScadaBridge.TemplateEngine.Services @using ZB.MOM.WW.ScadaBridge.DeploymentManager @using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Dialogs +@using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared @using ZB.MOM.WW.ScadaBridge.CentralUI.Services @attribute [Authorize(Policy = AuthorizationPolicies.RequireDeployment)] @inject ITemplateEngineRepository TemplateEngineRepository @@ -18,6 +19,7 @@ @inject IFlatteningPipeline FlatteningPipeline @inject AuthenticationStateProvider AuthStateProvider @inject NavigationManager NavigationManager +@inject IDialogService Dialog
@@ -39,15 +41,22 @@
- +
+ + +
+ @if (_templates.Count == 0) + { +
No templates exist yet — create one on the Templates page.
+ } + else if (_templateHint is not null) + { +
@_templateHint
+ }
@@ -228,11 +237,21 @@
@code { + /// Query preselect: the template the operator picked elsewhere (e.g. the Templates tree's "New Instance…"). + [SupplyParameterFromQuery] public int? TemplateId { get; set; } [SupplyParameterFromQuery] public int? SiteId { get; set; } [SupplyParameterFromQuery] public int? AreaId { get; set; } private List _sites = new(); private List