You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The fix for #127 adds a status pill (Immediate / Queued / Held) to the group header in AgentChatInputQueueControl.axaml. This creates near-identical structural XAML duplicated across two files:
Both blocks have the same structure: a Border Classes="queue-status-pill dynamic" containing a Button with a MenuFlyout holding three MenuItems (Immediate / Queued / Held), and a StackPanel with a label TextBlock and a caret TextBlock. The only differences are the binding paths and the IsVisible condition.
Because the markup is inlined in two separate files, any future change to the pill's layout, styling tokens, or accessibility attributes must be applied in both places — a fragile maintenance burden.
Design
1. Extract a shared interface IQueueImmediacyViewModel
Rename SubmitStatusOption → SelectedImmediacyOption and SetQueueImmediacyCommand → SetImmediacyCommand so the class satisfies IQueueImmediacyViewModel without adapters. Both InputQueueGroupViewModel and QueueComposerViewModel then share the same public surface for immediacy.
Add : IQueueImmediacyViewModel to class declaration
Controls/QueueStatusPillControl.axaml
New — extracted pill UserControl
Controls/QueueStatusPillControl.axaml.cs
New — code-behind (empty, standard pattern)
Controls/QueueComposerControl.axaml
Replace inline pill block with <controls:QueueStatusPillControl>
Controls/AgentChatInputQueueControl.axaml
Replace inline pill block with <controls:QueueStatusPillControl>
Tests
Tests in Phantom.Workspaces.Agent.Gui.Tests:
MainWindowAxamlTests
QueueStatusPillControl_ContainsSingleDefinitionOfPillMarkup — reads QueueStatusPillControl.axaml and asserts it contains exactly one queue-status-pill class, one SetImmediacyCommand binding, one SelectedImmediacyOption.Label binding, and all three immediacy CommandParameter bindings.
QueueComposerControl_StatusPill_UsesQueueStatusPillControl — reads QueueComposerControl.axaml and asserts it references QueueStatusPillControl (not an inline queue-status-pill Border), with IsVisible="{Binding IsDefaultComposer}".
Problem
The fix for #127 adds a status pill (Immediate / Queued / Held) to the group header in
AgentChatInputQueueControl.axaml. This creates near-identical structural XAML duplicated across two files:Controls/QueueComposerControl.axamlSetQueueImmediacyCommand,SubmitStatusOption.LabelControls/AgentChatInputQueueControl.axamlSetImmediacyCommand,SelectedImmediacyOption.LabelBoth blocks have the same structure: a
Border Classes="queue-status-pill dynamic"containing aButtonwith aMenuFlyoutholding threeMenuItems (Immediate / Queued / Held), and aStackPanelwith a labelTextBlockand a caretTextBlock. The only differences are the binding paths and theIsVisiblecondition.Because the markup is inlined in two separate files, any future change to the pill's layout, styling tokens, or accessibility attributes must be applied in both places — a fragile maintenance burden.
Design
1. Extract a shared interface
IQueueImmediacyViewModel2. Align
QueueComposerViewModelto the interfaceRename
SubmitStatusOption→SelectedImmediacyOptionandSetQueueImmediacyCommand→SetImmediacyCommandso the class satisfiesIQueueImmediacyViewModelwithout adapters. BothInputQueueGroupViewModelandQueueComposerViewModelthen share the same public surface for immediacy.InputQueueGroupViewModelalready uses the target names — no changes needed there beyond addingIQueueImmediacyViewModelto itsimplementsclause.3. New
QueueStatusPillControlUserControl4. Call-site changes
QueueComposerControl.axaml— replace the inline pill (lines 48–82) with:AgentChatInputQueueControl.axaml— replace the inline pill (lines 26–54) with:Files to change
ViewModels/IQueueImmediacyViewModel.csViewModels/QueueComposerViewModel.csSubmitStatusOption→SelectedImmediacyOptionandSetQueueImmediacyCommand→SetImmediacyCommand; add: IQueueImmediacyViewModelViewModels/InputQueueGroupViewModel.cs: IQueueImmediacyViewModelto class declarationControls/QueueStatusPillControl.axamlControls/QueueStatusPillControl.axaml.csControls/QueueComposerControl.axaml<controls:QueueStatusPillControl>Controls/AgentChatInputQueueControl.axaml<controls:QueueStatusPillControl>Tests
Tests in
Phantom.Workspaces.Agent.Gui.Tests:MainWindowAxamlTestsQueueStatusPillControl_ContainsSingleDefinitionOfPillMarkup— readsQueueStatusPillControl.axamland asserts it contains exactly onequeue-status-pillclass, oneSetImmediacyCommandbinding, oneSelectedImmediacyOption.Labelbinding, and all three immediacyCommandParameterbindings.QueueComposerControl_StatusPill_UsesQueueStatusPillControl— readsQueueComposerControl.axamland asserts it referencesQueueStatusPillControl(not an inlinequeue-status-pillBorder), withIsVisible="{Binding IsDefaultComposer}".AgentChatInputQueueControl_StatusPill_UsesQueueStatusPillControl— readsAgentChatInputQueueControl.axamland asserts it referencesQueueStatusPillControlwithIsVisible="{Binding !IsDefault}", replacing the old tests added for Bug: non-default queues don't show their status (immediate/queued/held) when composer is collapsed #127.InputQueueViewModelTestsSubmitStatusOptionreferences toSelectedImmediacyOptionandSetQueueImmediacyCommandreferences toSetImmediacyCommandin existing tests.All tests: deterministic, no
Task.Delay, no Moq.