feat: unified Devices pane matching design philosophy#484
Conversation
Redesigns the Devices tab as a tile grid with an inline settings drawer, replacing the ListView + MahApps DevicesFlyout. Follows the Channels pane pattern from #479: dark surfaces, USB (cyan) / WiFi (purple) type-coded stripes, direct tile click opens a right-side drawer with Information / Data Acquisition / Network / Firmware / Actions sections. Shell-owned state (firmware path/progress, logging mode, SD format) is exposed via a Shell passthrough on DevicesPaneViewModel so the drawer binds directly without cross-VM hops. Removes the now-dead IsDeviceSettingsOpen flag and OpenDeviceSettings command from DaqifiViewModel. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The MahApps Light.Blue theme paints the default ComboBox toggle button white regardless of the Background setter, so the NETWORK MODE / SECURITY (and SD format) combos were rendering light against the dark drawer. Replaces the ControlTemplate with a full dark version sourced from the drawer palette, matches the chevron to TextSecondary, routes popup items through a dark ComboBoxItem style with SurfaceActive hover, and adds Accent focus + BorderBright hover borders for consistency with the other drawer inputs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Review Summary by QodoUnified Devices pane with tile grid and inline settings drawer
WalkthroughsDescription• Redesigns Devices tab from ListView to unified tile grid with inline settings drawer • Mirrors Channels pane design: dark surfaces, USB (cyan) / WiFi (purple) type-coded stripes • New DevicesPaneViewModel + DeviceTileViewModel own pane and tile state; shell passthrough for shared commands • Drawer sections: Information, Data Acquisition, Network, Firmware, Actions with full dark ComboBox template • Removes dead IsDeviceSettingsOpen flag and OpenDeviceSettings command from DaqifiViewModel Diagramflowchart LR
A["Old ListView + DevicesFlyout"] -->|Replace| B["DevicesPanePrototype"]
B --> C["DevicesPaneViewModel"]
C --> D["DeviceTileViewModel Collection"]
C --> E["Shell Passthrough"]
E --> F["Firmware/Network/Logging Commands"]
B --> G["Settings Drawer"]
G --> H["Information Panel"]
G --> I["Data Acquisition Panel"]
G --> J["Network Panel"]
G --> K["Firmware Panel"]
G --> L["Actions Panel"]
File Changes1. Daqifi.Desktop/View/Flyouts/DevicesFlyout.xaml.cs
|
Code Review by Qodo
1.
|
DeviceSettingsViewModel had no remaining references — no bindings, no instantiations, no tests — and was throwing an MVVMTK0033 warning for using [ObservableObject] without an ObservableObject base. All of its state (SelectedDevice, IsLoggingToDevice, CanAccessSdCard, SdCard message) is provided by the shell view-model and the new DevicesPaneViewModel. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Replace the LoggingMode_Click code-behind with a RelayCommand<string> on DevicesPaneViewModel (SetLoggingModeCommand) and bind the RadioButtons to it via CommandParameter. Removes the Click handler (which also had a non-PascalCase name) and keeps all interaction in the view-model. - Route the frequency slider through a new DevicesPaneViewModel.FrequencyHz proxy that reads from SelectedDevice.StreamingFrequency but writes through DaqifiViewModel.SelectedStreamingFrequency. That shell setter already blocks changes while LoggingManager.Active and surfaces an error dialog — so the drawer can no longer silently bypass the mid-session guard. - Guard DaqifiViewModel.UpdateNetworkConfiguration against null SelectedDevice and disconnected devices, and wrap the call in try/catch so a transport failure surfaces as an error dialog instead of propagating out of the RelayCommand. - Declare SelectedTile's dependent-property notifications via [NotifyPropertyChangedFor] attributes (SelectedDevice, SelectedDeviceSupportsFirmwareUpdate, FrequencyHz) and trim the partial to only the CanExecute bookkeeping the source generator can't emit. - Add missing XML docs on DevicesPanePrototype and its constructor. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
📊 Code Coverage ReportSummarySummary
CoverageDAQiFi - 16.7%
Daqifi.Desktop.Common - 30.8%
Daqifi.Desktop.IO - 100%
Coverage report generated by ReportGenerator • View full report in build artifacts |
|
Thanks @qodo-code-review — replies to the items in the summary that weren't covered by the inline threads: #4 #5 #6 #7 XML docs on class and constructor — Fixed in d3cd857. Class-level #8 DI vs |
Replaces the MahApps MetroWindow settings dialog with a right-side settings drawer at the app-window level, matching the Channels (#479) and Devices (#484) panes. Preferences are a genuine separate surface but not a destructive fork, so the drawer pattern fits the design philosophy better than a modal. - New IsAppSettingsOpen + AppSettings property on DaqifiViewModel, and Toggle/Close commands replacing ShowDAQiFiSettingsDialogCommand - Drawer appended to MainWindow root Grid at ZIndex=20 so it overlays tab content and in-pane drawers; scrim click and X dismiss - CSV delimiter uses a segmented COMMA/SEMICOLON toggle instead of a ComboBox — only two options and direct manipulation reads better - SettingsViewModel upgraded to ObservableObject with bool selectors so the segmented toggle binds two-way - Deletes SettingsDialog.xaml/.cs and the dialog-service invocation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Redesigns the left tab strip to match the Channels (#479) and Devices (#484) panes: dark surface (#0D0F12), 3px accent stripe on selected, restrained icon/label pairs, no decorative white borders. Uses the same color tokens documented in docs/design-philosophy.md. - Selected: surface lifts to #171A20, stripe fades in over 120ms, text and icon brighten to primary - Hover (unselected only): surface lifts to #13161C, text/icon brighten, cursor becomes Hand - Focus visual: subtle 1px dashed border for keyboard users - Drops the Label wrapper + IsEnabled=False hack that was greying labels - Icons 30 -> 24px, labels 11pt Pane contents for Live Graph / Logged Data / Profiles are unchanged — they stay on MahApps light chrome until redesigned per Principle 9 (legacy areas are transition states). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Summary
DevicesFlyout. Mirrors the Channels pane pattern from feat: unified Channels pane + design philosophy #479: dark surfaces, USB (cyan) / WiFi (purple) type-coded stripes, and a single direct-manipulation interaction model per the design philosophy.DevicesPaneViewModel+DeviceTileViewModelown pane state and tile presentation; shell-owned state (firmware path/progress, logging mode, SD format) and commands (firmware upload, network apply, disconnect/reboot) are reached through aShellpassthrough so the drawer binds directly without cross-DataContext hops.IsDeviceSettingsOpenflag andOpenDeviceSettingscommand fromDaqifiViewModelalong with the deletedDevicesFlyout.xaml/.cs.ControlTemplatefor the drawer ComboBoxes — the MahApps Light.Blue theme was painting the default toggle button white regardless of the Background setter, which left MODE/SECURITY/DATA FORMAT rendering light against the dark drawer.Test plan
DaqifiViewModel.SelectedLoggingMode; LOG TO DEVICE is disabled for WiFi devices with a tooltipSelectedDevice.StreamingFrequency(500 ms delay on commit)SelectedSdCardLogFormatSelectedDevice.NetworkConfiguration; APPLY callsUpdateNetworkConfigurationCommandFirmwareFilePath; UPDATE runs the upload and the progress bar updates🤖 Generated with Claude Code