docs(plans): template picker — live rig gate PASS (New Instance…, ?templateId prefill, picker reveal/search/cancel, Disable verb) + task status
Claude-Session: https://claude.ai/code/session_01G2GHPnbbKGvyyfbr2XBRVH
This commit is contained in:
@@ -732,4 +732,67 @@ Content: one paragraph under the Create-Instance bullet — template chosen thro
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
_(filled in by the executing session)_
|
**DONE — all 8 tasks complete, 2026-08-21.** Branch `feat/template-picker` (worktree
|
||||||
|
`~/Desktop/ScadaBridge-template-picker`), 8 commits.
|
||||||
|
|
||||||
|
| # | Task | Result |
|
||||||
|
|---|------|--------|
|
||||||
|
| 1 | `TemplatePathFormatter` | done — 4 tests |
|
||||||
|
| 2 | `TemplateFolderTree.RevealKeys` | done — 3 tests; `TreeViewTests` / `TemplatesPageTests` / `TransportExportPageTests` unaffected |
|
||||||
|
| 3 | `TemplatePickerDialog` | done — 7 tests |
|
||||||
|
| 4 | Create page picker field + `?templateId=` | done — 5 tests (first bUnit render of `InstanceCreate`) |
|
||||||
|
| 5 | Templates tree "New Instance…" | done — 2 tests (Deployer shows, Designer-only hides) |
|
||||||
|
| 6 | Topology Disable confirm pin | done — 3 tests, **PASS on first run** (no production change; `0db253b5` intact) |
|
||||||
|
| 7 | Docs | done — `Component-CentralUI.md` (Create-Instance + Templates-page + dialog-label bullets), this design doc → implemented, bindings design §3.2 superseded note |
|
||||||
|
| 8 | Build + sweep + live rig | **PASS** — see below |
|
||||||
|
|
||||||
|
### Deviations from the plan, and why
|
||||||
|
|
||||||
|
1. **Selection is tracked inside `TemplatePickerDialog`, not through `SelectedKeys`/`SelectedKeysChanged`.**
|
||||||
|
In `TreeViewSelectionMode.Single` the inner `TreeView` uses the *singular* `SelectedKey` /
|
||||||
|
`SelectedKeyChanged` pair; `TemplateFolderTree` forwards only the plural (Checkbox-mode) pair,
|
||||||
|
which `TreeView` reads for tri-state checkbox aggregation. The plan's wiring would therefore
|
||||||
|
never have highlighted a row and `OnSelectedKeysChanged` would never have fired. The dialog's own
|
||||||
|
`NodeContent` click/dblclick handlers own selection and the `text-primary` highlight — no change
|
||||||
|
to the shared tree's public surface.
|
||||||
|
2. **`[SupplyParameterFromQuery]` cannot be set as an ordinary bUnit parameter** ("only accepts
|
||||||
|
cascading values"). The Task-4 tests seed `BunitNavigationManager.NavigateTo(".../create?templateId=7")`
|
||||||
|
instead, matching `Pages/QueryStringDrillInTests.cs`.
|
||||||
|
3. **`…` in a Razor *attribute* is emitted literally** — the placeholder uses the real `…`.
|
||||||
|
4. **The Task-3 `Open()` helper needs a block-bodied `InvokeAsync` lambda.** An expression body
|
||||||
|
returning the pending `Task` binds to `InvokeAsync(Func<Task>)` and awaits the dialog itself;
|
||||||
|
every test hung until it was changed (comment left in the file).
|
||||||
|
|
||||||
|
### Task 8 — build, sweep, live rig gate
|
||||||
|
|
||||||
|
- `dotnet build ZB.MOM.WW.ScadaBridge.slnx -v q` → **0 warnings, 0 errors**.
|
||||||
|
- `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests` → **1154 / 1154 PASS**.
|
||||||
|
- Rig: `docker/build.sh` run from the worktree (tags `scadabridge:latest`), then
|
||||||
|
`docker compose -f docker/docker-compose.yml up -d --force-recreate` from the **primary
|
||||||
|
checkout** — deploying `deploy.sh` wholesale from a worktree would have rehomed every node's
|
||||||
|
bind-mounted appsettings to the worktree copy. `/health/ready` Healthy on all 8 nodes.
|
||||||
|
- Live check at `http://localhost:9000` as `multi-role`, **all PASS**:
|
||||||
|
1. `/design/templates` → right-click **Motor Controller** (inside folder `Test`) → the menu shows
|
||||||
|
**New Instance…** between its own dividers → lands on
|
||||||
|
`/deployment/instances/create?templateId=4` with the field reading **"Test / Motor Controller"**.
|
||||||
|
2. Site = *Test Plant A* → Connection Bindings card appears (30 attributes, 4 groups) — the
|
||||||
|
`?templateId` preselect does feed `OnTemplateOrSiteChangedAsync`.
|
||||||
|
3. **Choose…** → picker opens **expanded to and highlighting** Motor Controller, footer
|
||||||
|
"Selected: Test / Motor Controller", Select enabled. Search "Tank" narrows to one row.
|
||||||
|
**Cancel** left the field, the site and the card untouched.
|
||||||
|
4. Re-open → **double-click "Tank Monitor"** → dialog closes, field reads "Tank Monitor"
|
||||||
|
(root template ⇒ no folder prefix), card re-previews to 7 attributes / 2 groups.
|
||||||
|
5. `/deployment/instances/create` with no query → field blank with the placeholder, picker opens
|
||||||
|
**collapsed**, footer "Select a template", **Select disabled**; clicking a *folder* label leaves
|
||||||
|
it disabled.
|
||||||
|
6. `/deployment/topology` → right-click `rig-probe-1` (Enabled) → **Disable** → confirm button reads
|
||||||
|
**Disable** in red, body "Disable instance 'rig-probe-1'? …". Cancelled; instance still Enabled.
|
||||||
|
|
||||||
|
### Known limitation (pre-existing, not introduced here)
|
||||||
|
|
||||||
|
`TreeView.InitiallyExpanded` is applied **once** (`_initialExpansionApplied`). So in the picker, if a
|
||||||
|
preselected template reveals on first render and the operator *then* types a search, the filter's own
|
||||||
|
ancestor-expand does not re-apply — matches under a still-collapsed folder stay hidden until the
|
||||||
|
folder is opened by hand. Opening the picker with no preselect (the common case) is unaffected,
|
||||||
|
because nothing consumed the one-shot. Fixing it means resetting `_initialExpansionApplied` when
|
||||||
|
`InitiallyExpanded` changes identity, which touches every `TreeView` caller — out of scope here.
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
"subject": "Task 7: Docs",
|
"subject": "Task 7: Docs",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"blockedBy": [
|
"blockedBy": [
|
||||||
4,
|
4,
|
||||||
5,
|
5,
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
{
|
{
|
||||||
"id": 8,
|
"id": 8,
|
||||||
"subject": "Task 8: Solution build + CentralUI test sweep + live rig check",
|
"subject": "Task 8: Solution build + CentralUI test sweep + live rig check",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"blockedBy": [
|
"blockedBy": [
|
||||||
7
|
7
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user