Skip to content

fix: ghost checkboxes, DNS elevation banner, startup column width, shredder empty state#502

Merged
laurentiu021 merged 1 commit into
mainfrom
fix/ui-round2
May 22, 2026
Merged

fix: ghost checkboxes, DNS elevation banner, startup column width, shredder empty state#502
laurentiu021 merged 1 commit into
mainfrom
fix/ui-round2

Conversation

@laurentiu021
Copy link
Copy Markdown
Owner

@laurentiu021 laurentiu021 commented May 22, 2026

Fixes

  1. Ghost checkbox in Uninstaller/Windows Update — added CanUserAddRows="False" to DataGrids (WPF default adds empty "new item" row)
  2. DNS & Hosts missing elevation banner — added consistent Surface2 banner with "Run as administrator" button (same pattern as Privacy/Features)
  3. File Shredder empty headers — hide DataGrid headers when Items.Count == 0 via DataTrigger
  4. Startup Manager last column cut — widened "Open" button column from 40px to 60px

Test plan

  • CI passes
  • No ghost checkbox rows in any DataGrid
  • DNS & Hosts shows elevation banner with working button
  • File Shredder shows no table when empty
  • Startup "Open" button fully visible

Summary by CodeRabbit

  • New Features

    • Added an elevation banner with a "Run as administrator" button for DNS Hosts management.
  • UI/UX Improvements

    • Enabled column resizing across multiple data tables for better layout control.
    • Data tables now auto-hide headers when empty, disallow manual row addition, and include improved row styling.
    • Increased action-button column width in the startup table for better touch/click targets.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

Adds a RelaunchElevated RelayCommand and an elevation banner UI to the DNS hosts view; standardizes multiple DataGrid properties across several views (column resizing, header visibility styling, row addition, row backgrounds, and a template column width).

Changes

DNS Admin Elevation UI and Relaunch

Layer / File(s) Summary
RelaunchElevated command and elevation banner UI
SysManager/SysManager/ViewModels/DnsHostsViewModel.cs, SysManager/SysManager/Views/DnsHostsView.xaml
New RelayCommand RelaunchElevated() calls AdminHelper.RelaunchAsAdmin() and shuts down the WPF application on success. DnsHostsView adds an Auto row, inserts an elevation banner with a "Run as administrator" button bound to RelaunchElevatedCommand, and repositions the Hosts File card from Grid.Row="2" to Grid.Row="3".

DataGrid UI Refinements Across Views

Layer / File(s) Summary
DataGrid header visibility styling and row/column refinements
SysManager/SysManager/Views/FileShredderView.xaml, SysManager/SysManager/Views/UninstallerView.xaml, SysManager/SysManager/Views/WindowsUpdateView.xaml, SysManager/SysManager/Views/StartupView.xaml, SysManager/SysManager/Views/AppUpdatesView.xaml, SysManager/SysManager/Views/ContextMenuView.xaml, SysManager/SysManager/Views/DriversView.xaml, SysManager/SysManager/Views/ServicesView.xaml, SysManager/SysManager/Views/ShortcutCleanerView.xaml, SysManager/SysManager/Views/WindowsFeaturesView.xaml
Enables CanUserResizeColumns="True" on multiple DataGrids; FileShredderView moves HeadersVisibility="Column" into a DataGrid.Style and adds a DataTrigger to set headers to None when Items.Count==0; UninstallerView adds CanUserAddRows="False" and explicit row/alternating row backgrounds while removing a visibility binding; StartupView increases a DataGridTemplateColumn width from 40 to 60; WindowsUpdateView adds CanUserAddRows="False".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 A banner pops where admin rights belong,
A button hops — "Run as administrator" strong,
Grids stretch columns, headers hide when bare,
Layouts shift gently, styled with care,
The rabbit cheers: tidy UI everywhere!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: ghost checkboxes, DNS elevation banner, startup column width, and shredder empty state handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ui-round2

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@SysManager/SysManager/ViewModels/DnsHostsViewModel.cs`:
- Around line 239-244: Wrap the RelaunchElevated method body in a try-catch that
calls AdminHelper.RelaunchAsAdmin() and only calls
System.Windows.Application.Current?.Shutdown() when the relaunch returns true,
and on any exception catch update the ViewModel's StatusMessage or HostsStatus
with a user-friendly error (and optionally log the exception) instead of letting
the exception propagate; reference the RelaunchElevated method,
AdminHelper.RelaunchAsAdmin(), System.Windows.Application.Current?.Shutdown(),
and the StatusMessage/HostsStatus properties when making the change.
- Around line 239-244: RelaunchElevated currently calls
AdminHelper.RelaunchAsAdmin() and immediately shuts down, risking loss of
unsaved HostEntries; update RelaunchElevated to first detect unsaved changes
(e.g. compare current HostEntries to last saved state or use an existing/added
"IsDirty" flag set by AddEntryCommand/RemoveEntryCommand), then either auto-save
by invoking the existing Save command/method or show a confirmation dialog
prompting the user to Save/Discard/Cancel; only call
AdminHelper.RelaunchAsAdmin() and Application.Current?.Shutdown() after the user
has saved or explicitly chosen to discard changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d765dcdd-0aa8-4866-bbe7-ec566999ad76

📥 Commits

Reviewing files that changed from the base of the PR and between 20ffcf0 and bfa03bf.

📒 Files selected for processing (6)
  • SysManager/SysManager/ViewModels/DnsHostsViewModel.cs
  • SysManager/SysManager/Views/DnsHostsView.xaml
  • SysManager/SysManager/Views/FileShredderView.xaml
  • SysManager/SysManager/Views/StartupView.xaml
  • SysManager/SysManager/Views/UninstallerView.xaml
  • SysManager/SysManager/Views/WindowsUpdateView.xaml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: UI automation tests
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (7)
SysManager/SysManager/Views/DnsHostsView.xaml (1)

13-18: LGTM!

Also applies to: 27-41, 44-44, 79-79

SysManager/SysManager/ViewModels/DnsHostsViewModel.cs (1)

239-244: Confirm AdminHelper.RelaunchAsAdmin() launch + return semantics used by DnsHostsViewModel.RelaunchElevated.

AdminHelper.RelaunchAsAdmin() requests UAC elevation by starting the current executable with ProcessStartInfo.UseShellExecute = true and Verb = "runas" (passing argumentHint via Arguments). It returns true when Process.Start(psi) is successfully called, and false when exePath is missing or when UAC/process start fails (caught InvalidOperationException/Win32Exception). This matches the if (AdminHelper.RelaunchAsAdmin()) ... Shutdown(); conditional (shutdown only after the elevated launch request is issued).

SysManager/SysManager/Views/FileShredderView.xaml (1)

69-78: LGTM!

SysManager/SysManager/Views/UninstallerView.xaml (1)

65-69: LGTM!

SysManager/SysManager/Views/WindowsUpdateView.xaml (1)

129-129: LGTM!

SysManager/SysManager/Views/StartupView.xaml (2)

102-102: AI summary inconsistency: This is the last column, not the first.

The AI summary states "the first (icon/selection) DataGridTemplateColumn header column is resized" but the actual change is to the last column (line 102) containing the "Open" button. The first column at line 53 with the checkbox remains Width="40".

The code change itself is correct and matches the PR description.


102-102: LGTM!

Comment on lines +239 to +244
[RelayCommand]
private void RelaunchElevated()
{
if (AdminHelper.RelaunchAsAdmin())
System.Windows.Application.Current?.Shutdown();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add error handling for the relaunch flow.

If AdminHelper.RelaunchAsAdmin() throws an exception (e.g., file not found, access denied), or if Application.Current?.Shutdown() fails, the exception will propagate uncaught. This could leave the app in an inconsistent state or crash without user feedback.

Wrap the calls in a try-catch block and update StatusMessage or HostsStatus on failure.

🛡️ Proposed error handling
 [RelayCommand]
 private void RelaunchElevated()
 {
+    try
+    {
         if (AdminHelper.RelaunchAsAdmin())
             System.Windows.Application.Current?.Shutdown();
+        else
+            HostsStatus = "Failed to relaunch as administrator.";
+    }
+    catch (Exception ex)
+    {
+        HostsStatus = $"Error relaunching: {ex.Message}";
+        Log.Warning(ex, "Failed to relaunch elevated");
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/ViewModels/DnsHostsViewModel.cs` around lines 239 -
244, Wrap the RelaunchElevated method body in a try-catch that calls
AdminHelper.RelaunchAsAdmin() and only calls
System.Windows.Application.Current?.Shutdown() when the relaunch returns true,
and on any exception catch update the ViewModel's StatusMessage or HostsStatus
with a user-friendly error (and optionally log the exception) instead of letting
the exception propagate; reference the RelaunchElevated method,
AdminHelper.RelaunchAsAdmin(), System.Windows.Application.Current?.Shutdown(),
and the StatusMessage/HostsStatus properties when making the change.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Prevent data loss from unsaved hosts file changes.

The RelaunchElevated method immediately shuts down the application without checking whether the user has unsaved modifications to HostEntries. If a user adds or removes entries (via AddEntryCommand/RemoveEntryCommand) but hasn't clicked "Save" before clicking "Run as administrator," those changes will be lost.

Consider checking for unsaved changes and either:

  1. Auto-save before relaunching, or
  2. Prompt the user to save, or
  3. Block relaunch and display a message directing the user to save first.
🛡️ Suggested approach to detect unsaved changes

One approach is to track a "dirty" flag:

+[ObservableProperty] private bool _hasUnsavedHostChanges;

 [RelayCommand]
 private void AddEntry()
 {
     try
     {
         var entry = _hostsService.AddEntry(NewIp, NewHostname);
         HostEntries.Add(entry);
+        HasUnsavedHostChanges = true;
         NewIp = "";
         NewHostname = "";
         HostsStatus = $"Added {entry.Hostname} ({entry.IpAddress}).";
     }
     catch (ArgumentException ex)
     {
         HostsStatus = ex.Message;
     }
 }

 [RelayCommand]
 private void RemoveEntry(HostsEntry? entry)
 {
     if (entry is null) return;
     HostEntries.Remove(entry);
+    HasUnsavedHostChanges = true;
     HostsStatus = $"Removed {entry.Hostname}.";
 }

 [RelayCommand]
 private void SaveHosts()
 {
     if (!IsElevated)
     {
         HostsStatus = "Saving hosts file requires administrator privileges.";
         return;
     }

     try
     {
         _hostsService.SaveHosts(HostEntries.ToList());
+        HasUnsavedHostChanges = false;
         HostsStatus = $"Saved {HostEntries.Count} entries. Backup created at hosts.bak.";
         Log.Information("Hosts file saved with {Count} entries", HostEntries.Count);
     }
     catch (UnauthorizedAccessException)
     {
         HostsStatus = "Access denied — run as administrator to save hosts file.";
     }
     catch (IOException ex)
     {
         HostsStatus = $"Error saving hosts file: {ex.Message}";
         Log.Error(ex, "Failed to save hosts file");
     }
 }

 [RelayCommand]
 private void RelaunchElevated()
 {
+    if (HasUnsavedHostChanges)
+    {
+        HostsStatus = "Please save your hosts file changes before relaunching.";
+        return;
+    }
     if (AdminHelper.RelaunchAsAdmin())
         System.Windows.Application.Current?.Shutdown();
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/ViewModels/DnsHostsViewModel.cs` around lines 239 -
244, RelaunchElevated currently calls AdminHelper.RelaunchAsAdmin() and
immediately shuts down, risking loss of unsaved HostEntries; update
RelaunchElevated to first detect unsaved changes (e.g. compare current
HostEntries to last saved state or use an existing/added "IsDirty" flag set by
AddEntryCommand/RemoveEntryCommand), then either auto-save by invoking the
existing Save command/method or show a confirmation dialog prompting the user to
Save/Discard/Cancel; only call AdminHelper.RelaunchAsAdmin() and
Application.Current?.Shutdown() after the user has saved or explicitly chosen to
discard changes.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
SysManager/SysManager/ViewModels/DnsHostsViewModel.cs (1)

239-244: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle relaunch failures and exceptions in the command.

Line 242 currently only handles the success path; if relaunch fails or throws, users get no feedback and the command can fail noisily. Wrap the call in try/catch and set HostsStatus on failure paths.

Proposed patch
 [RelayCommand]
 private void RelaunchElevated()
 {
-    if (AdminHelper.RelaunchAsAdmin())
-        System.Windows.Application.Current?.Shutdown();
+    try
+    {
+        if (AdminHelper.RelaunchAsAdmin())
+        {
+            System.Windows.Application.Current?.Shutdown();
+        }
+        else
+        {
+            HostsStatus = "Failed to relaunch as administrator.";
+        }
+    }
+    catch (Exception ex)
+    {
+        HostsStatus = $"Error relaunching: {ex.Message}";
+        Log.Warning(ex, "Failed to relaunch elevated");
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/ViewModels/DnsHostsViewModel.cs` around lines 239 -
244, The RelaunchElevated command currently only handles the success path;
update the RelaunchElevated method to wrap the call to
AdminHelper.RelaunchAsAdmin() in a try/catch, set the HostsStatus property to an
appropriate failure message when RelaunchAsAdmin returns false, and in the catch
block set HostsStatus to the caught exception message (and optionally log it) so
the UI shows feedback on failures or exceptions instead of failing silently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@SysManager/SysManager/ViewModels/DnsHostsViewModel.cs`:
- Around line 239-244: The RelaunchElevated command currently only handles the
success path; update the RelaunchElevated method to wrap the call to
AdminHelper.RelaunchAsAdmin() in a try/catch, set the HostsStatus property to an
appropriate failure message when RelaunchAsAdmin returns false, and in the catch
block set HostsStatus to the caught exception message (and optionally log it) so
the UI shows feedback on failures or exceptions instead of failing silently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f2135e68-4590-4e51-9413-b080736caefe

📥 Commits

Reviewing files that changed from the base of the PR and between bfa03bf and e8fb979.

📒 Files selected for processing (12)
  • SysManager/SysManager/ViewModels/DnsHostsViewModel.cs
  • SysManager/SysManager/Views/AppUpdatesView.xaml
  • SysManager/SysManager/Views/ContextMenuView.xaml
  • SysManager/SysManager/Views/DnsHostsView.xaml
  • SysManager/SysManager/Views/DriversView.xaml
  • SysManager/SysManager/Views/FileShredderView.xaml
  • SysManager/SysManager/Views/ServicesView.xaml
  • SysManager/SysManager/Views/ShortcutCleanerView.xaml
  • SysManager/SysManager/Views/StartupView.xaml
  • SysManager/SysManager/Views/UninstallerView.xaml
  • SysManager/SysManager/Views/WindowsFeaturesView.xaml
  • SysManager/SysManager/Views/WindowsUpdateView.xaml
✅ Files skipped from review due to trivial changes (3)
  • SysManager/SysManager/Views/ContextMenuView.xaml
  • SysManager/SysManager/Views/ShortcutCleanerView.xaml
  • SysManager/SysManager/Views/ServicesView.xaml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build & unit tests
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (8)
SysManager/SysManager/Views/DnsHostsView.xaml (1)

14-17: LGTM!

Also applies to: 27-42, 44-44, 79-79

SysManager/SysManager/Views/AppUpdatesView.xaml (1)

66-74: LGTM!

SysManager/SysManager/Views/DriversView.xaml (1)

46-55: LGTM!

SysManager/SysManager/Views/FileShredderView.xaml (1)

65-79: LGTM!

SysManager/SysManager/Views/StartupView.xaml (1)

49-50: LGTM!

Also applies to: 103-103

SysManager/SysManager/Views/UninstallerView.xaml (1)

65-70: LGTM!

SysManager/SysManager/Views/WindowsFeaturesView.xaml (1)

85-87: LGTM!

SysManager/SysManager/Views/WindowsUpdateView.xaml (1)

128-131: LGTM!

@laurentiu021 laurentiu021 merged commit 010e4ac into main May 22, 2026
5 checks passed
@laurentiu021 laurentiu021 deleted the fix/ui-round2 branch May 22, 2026 11:03
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