Skip to content

Refactor ElementPickerSubsystem and enhance Query dialog functionality#14

Merged
Malcolmnixon merged 11 commits into
mainfrom
feature/query-dialog
Jul 21, 2026
Merged

Refactor ElementPickerSubsystem and enhance Query dialog functionality#14
Malcolmnixon merged 11 commits into
mainfrom
feature/query-dialog

Conversation

@Malcolmnixon

Copy link
Copy Markdown
Member

This pull request expands the SysML2Workbench design documentation and review coverage to include the new QueryDialog and ElementPickerSubsystem components. It also refactors the ViewBuilder dialog’s documentation to describe its new integration with the shared element picker. The main changes are:

Review Coverage and Documentation Structure:

  • Added new review sections for QueryDialog (AppShellSubsystem), ElementPickerSubsystem, and its subcomponents (ElementPicker, ElementFilter) to .reviewmark.yaml, specifying their design, requirements, verification, source, and test files.
  • Updated the introduction and AppShellSubsystem documentation to include the new QueryDialog and ElementPickerSubsystem as part of the system/subsystem/unit breakdown. [1] [2] [3]

QueryDialog Design Documentation:

  • Added a comprehensive design document for QueryDialog, detailing its UI, data model, key methods, error handling, dependencies, and integration points. This includes how query types are selected, how results are computed and displayed, and how clipboard operations are handled.

ViewBuilderDialog Refactor:

  • Refactored the ViewBuilder dialog documentation to describe the use of the shared ElementPickerSubsystem.ElementPickerViewModel for the "Expose Targets" picker, replacing the prior ad-hoc filtering and selection logic with the new reusable picker. [1] [2]

These changes ensure that both the documentation and the review process are up to date with the latest subsystems and their shared components, and that the new picker is consistently described and used across dialogs.

Copilot CLI and others added 11 commits July 20, 2026 22:10
Factor the OR-then-AND type-filter chip / substring search / candidate list logic out of ViewBuilderDialogViewModel into a reusable, dialog-agnostic ElementPickerViewModel + ElementPickerView UserControl and a static ElementTypeLabeler. The new Query dialog (added in a later commit) needs the exact same picker with a different candidate set and a different default chip, so keeping the logic embedded in the ViewBuilder dialog would force either duplication or an awkward multi-consumer coupling on ViewDefinitionModel. Composition through the new ExposeTargetPicker property preserves every observable behavior of the ViewBuilder expose-targets tab, and the existing unit tests are adapted (not deleted) to reach through the composed picker.
beta.15 promotes DemaConsulting.SysML2Tools.Query (QueryEngine, QueryOptions, QueryResult, QueryResultRenderer, QueryVerb) to the public NuGet surface. The upcoming Query dialog consumes those types directly, so the workbench must reference the beta.15 packages before the dialog code can compile. Restore + full build both succeed.
Adds a new top-level _Query menu between View and Help with a single Run Query... entry that opens a new modal QueryDialog. The dialog composes two ElementPicker instances (Browse tab / Element Query tab), dispatches element-scoped verbs through DemaConsulting.SysML2Tools.Query.QueryEngine.Execute, and copies results as Markdown or JSON via QueryResultRenderer through the same AvaloniaClipboardService pattern DiagramDocumentView uses. Every recoverable failure surface (no workspace, no selection, engine argument rejection) is reported through an observable StatusMessage rather than by throwing, matching the plan's graceful-handling contract. The Browse tab is a purely-client-side filter (no QueryEngine.List/Find call) that builds a QueryResult inline so the same shared results panel renders it. Companion unit tests cover verb-specific option construction, engine dispatch, no-selection / no-workspace handling, and clipboard write parity with QueryResultRenderer's output; a new Avalonia-headless end-to-end test exercises the real menu -> dialog -> Describe -> Copy-as-Markdown flow against the real clipboard.
…QueryDialog and ElementPickerSubsystem

The prior three commits shipped the QueryDialog feature and the extracted
ElementPickerSubsystem as source code and tests, but left the companion
architecture artifacts for those units unwritten. This commit adds them so
the sysml2tools / reqstream / reviewmark / markdownlint / dotnet-format
gates all pass with the new units fully registered.

Adds a new eighth SysML2Workbench subsystem, ElementPickerSubsystem,
containing one unit ElementPicker; adds a new fifth AppShellSubsystem
unit, QueryDialog. Each new unit gets a full artifact set (sysml, design,
reqstream, verification), a reviewmark review set entry, and a top-level
requirements.yaml include entry. Updates existing docs (introduction, the
AppShellSubsystem design, the ViewBuilderDialog design, and the user
guide) to reflect the new units and the ViewBuilderDialog''s new
composition through ExposeTargetPicker. Adds one subsystem-level test
(ElementPickerSubsystemTests) that composes the labeler and view model
together, mirroring the sibling subsystems'' precedent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the two-tab Browse/Element-Query Query dialog with a single
adaptive form: an 11-entry Query Type combo (List merged with Find,
Describe, Uses, UsedBy, Dependencies, Impact, Hierarchy, Requirements,
Interface, Connections, States) drives a single always-visible
ElementPickerView instance. There is no Run button; every change
(query type, chip filters, search text, element selection, hierarchy
direction, walk depth, include-stdlib) immediately recomputes and
displays results.

- List builds results client-side from the picker's DisplayedItems
  (never calls QueryEngine.List/Find); the other 10 verbs require a
  selected element, show a friendly prompt when none is selected, and
  call QueryEngine.Execute otherwise, catching ArgumentException.
- Replace the results-panel Copy as Markdown/JSON toolbar buttons with
  a right-click context menu wired to the existing copy methods.
- Fix the results table header contrast bug (unreadable foreground on
  the light #F0F0F0 header background in the app's dark theme).
- Rewrite QueryDialogViewModelTests.cs and the Avalonia headless
  end-to-end test in AvaloniaTests.cs to cover the new auto-recompute,
  single-picker behavior.
- Update design, verification, reqstream, sysml2 model doc comment,
  and user guide documentation to describe the new single-form UX.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…posing ElementPickerViewModel

Replaces the temporary IsCandidateListVisible hack in the Query dialog's
List query type with a proper architectural split: a new selection-free
ElementFilterViewModel/ElementFilterView owns the chip+search filtering
concern, and ElementPickerViewModel now composes it while adding its own
SelectedQualifiedName selection concept. QueryDialogViewModel/View use
two distinct sibling instances (FilterOnly/ListFilterView for List mode,
Picker/ElementQueryPickerView for the other 10 query verbs) so the
selectable list is never silently ignored.

- New ElementFilterViewModel/ElementFilterView (chips + search, no selection)
- ElementPickerViewModel refactored to compose Filter + add SelectedQualifiedName,
  preserving its full existing public API for ViewBuilderDialogViewModel/View
- QueryDialogViewModel/View updated to use FilterOnly + Picker as separate controls
- Added ElementFilterViewModelTests.cs; updated QueryDialogViewModelTests.cs and
  AvaloniaTests.cs for the new two-control layout
- Updated design/verification docs, SysML2 model, reqstream, and reviewmark
  registrations for the new ElementFilter unit

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…onia DataGrid

- Restructured the results panel so the summary caption and table header are
  pinned above a scrollable rows area instead of scrolling away with the rows.
- Replaced the hand-rolled Grid+ItemsControl table with Avalonia's real
  DataGrid control (Avalonia.Controls.DataGrid package), which provides pinned
  headers, resizable columns, and row virtualization out of the box. The
  Direction column's visibility and the per-row Notes tooltip are preserved.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… DataGrid switch

The results panel's real Avalonia DataGrid captures the pointer for its own
cell-selection/column-drag handling; that capture wasn't always released cleanly
once a row was selected and the ContextMenu popup had opened and closed over it,
silently swallowing every right-click after the first.

Intercept the right mouse button during the pointer-pressed tunnel phase (before
the DataGrid's own bubble-phase handlers run), release any stray pointer capture,
and open the ContextMenu explicitly instead of relying on Avalonia's automatic
ContextRequested routing.

Extend the existing Query dialog Avalonia e2e test to open the context menu a
second time and copy as JSON, verifying the fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Picks up the upstream fix for the describe verb's Children-count mismatch and
the new verb-specific bold-text entries label/'no entries' fallback in
QueryResultRenderer.RenderMarkdown (e.g. '**Children**'/'_No children._' for
describe, '**Uses**'/'_No outgoing references._' for uses). No workbench code
changes needed: the Query dialog's Markdown/JSON copy tests compute their
expected text by calling QueryResultRenderer directly rather than asserting
hardcoded strings, so they automatically reflect the new format.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…yDialog requirements

ReqStream matches the tests: list entries by bare method name only (per
docs/reqstream/README and empirical verification), not by ClassName.MethodName.
The requirement files for ElementPickerSubsystem and AppShellSubsystem-QueryDialog
had accidentally qualified their test entries with the containing class name to
disambiguate identically-named tests across ElementPickerViewModelTests and
ElementFilterViewModelTests, which meant ReqStream could never find a matching
TRX entry and reported these 16 requirements as unsatisfied. Strip the class-name
prefix so the bare method names match, restoring full local reqstream --enforce
satisfaction (107/107 non-platform-specific requirements).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…karound

Per csharp-testing.md, unit test names must follow
{ClassName}_{MethodUnderTest}_{Scenario}_{ExpectedBehavior}. The previous commit
worked around ReqStream's bare-method-name matching by stripping the ClassName
qualifier from tests: entries, but that left ElementPickerViewModelTests and
ElementFilterViewModelTests with identically-named methods (e.g.
SetCandidates_NullCandidates_Throws in both), so evidence for one class's
requirements could be silently satisfied by the other class's test outcome.

Rename every test method in ElementPickerViewModelTests, ElementFilterViewModelTests,
ElementTypeLabelerTests, and QueryDialogViewModelTests to embed the class name
(ElementPickerViewModel_..., ElementFilterViewModel_..., ElementTypeLabeler_...,
QueryDialogViewModel_...), restoring global test-name uniqueness, and update the
corresponding docs/reqstream/**/*.yaml tests: entries to match. 279/279 tests
still pass; reqstream --enforce still reports 107/110 satisfied locally (only
the CI-matrix Platform-Windows/Ubuntu/MacOS requirements remain, as expected).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Malcolmnixon
Malcolmnixon merged commit a480354 into main Jul 21, 2026
12 of 18 checks passed
@Malcolmnixon
Malcolmnixon deleted the feature/query-dialog branch July 21, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant