# Conflicts: # docs/open.md # src/ClaudeDo.Installer/CLAUDE.md # src/ClaudeDo.Installer/Pages/SystemCheckPage/SystemCheckPageView.xaml # src/ClaudeDo.Installer/Pages/SystemCheckPage/SystemCheckPageViewModel.cs
112 lines
4.3 KiB
C#
112 lines
4.3 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Windows.Controls;
|
|
using ClaudeDo.Installer.Checks;
|
|
using ClaudeDo.Installer.Core;
|
|
using ClaudeDo.Installer.Localization;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
namespace ClaudeDo.Installer.Pages.SystemCheckPage;
|
|
|
|
public partial class SystemCheckPageViewModel : ObservableObject, IInstallerPage
|
|
{
|
|
private readonly InstallContext _context;
|
|
private readonly ClaudeHelpLauncher _claudeHelpLauncher;
|
|
private SystemCheckPageView? _view;
|
|
private bool _hasStarted;
|
|
|
|
public string Title => TrExtension.Localizer?["installer.systemCheck.title"] ?? "System Check";
|
|
public string Icon => "";
|
|
public int Order => 1;
|
|
public bool ShowInWizard => true;
|
|
public bool ShowInSettings => false;
|
|
public UserControl View => _view ??= new SystemCheckPageView { DataContext = this };
|
|
|
|
public CheckListViewModel Checks { get; }
|
|
|
|
// Pass-through to the shared check-run logic — kept so this page's UI/tests can bind
|
|
// directly on it, matching the pre-extraction API.
|
|
public ObservableCollection<CheckRowViewModel> Rows => Checks.Rows;
|
|
public bool IsRunning => Checks.IsRunning;
|
|
public bool HasRun => Checks.HasRun;
|
|
public bool HasBlockingError => Checks.HasBlockingError;
|
|
public string Summary => Checks.Summary;
|
|
public IAsyncRelayCommand RunChecksCommand => Checks.RunChecksCommand;
|
|
|
|
public bool BlocksNavigation => Checks.IsRunning || Checks.HasBlockingError;
|
|
|
|
[ObservableProperty] private string? _claudeHelpError;
|
|
|
|
public bool ClaudeCliOk =>
|
|
Checks.LastReport?.Results.FirstOrDefault(r => r.Id == ClaudeCliCheck.CheckId)?.Status == CheckStatus.Ok;
|
|
|
|
public bool ClaudeAuthFailed =>
|
|
Checks.LastReport?.Results.FirstOrDefault(r => r.Id == ClaudeAuthCheck.CheckId)?.Status == CheckStatus.Failed;
|
|
|
|
public bool CanStartClaudeHelp => ClaudeCliOk && !ClaudeAuthFailed;
|
|
|
|
public string ClaudeHelpTooltip
|
|
{
|
|
get
|
|
{
|
|
var loc = TrExtension.Localizer;
|
|
if (!ClaudeCliOk)
|
|
return loc?["installer.systemCheck.claudeHelp.tooltip.cliMissing"] ?? "The Claude CLI was not found.";
|
|
if (ClaudeAuthFailed)
|
|
return loc?["installer.systemCheck.claudeHelp.tooltip.notLoggedIn"] ?? "Claude is not logged in.";
|
|
return loc?["installer.systemCheck.claudeHelp.tooltip.ready"]
|
|
?? "Start an interactive Claude session to help troubleshoot your setup.";
|
|
}
|
|
}
|
|
|
|
public SystemCheckPageViewModel(
|
|
InstallContext context,
|
|
Func<EnvironmentCheckService> checkServiceFactory,
|
|
ClaudeHelpLauncher claudeHelpLauncher)
|
|
{
|
|
_context = context;
|
|
_claudeHelpLauncher = claudeHelpLauncher;
|
|
Checks = new CheckListViewModel(context, checkServiceFactory);
|
|
// The wizard listens for PropertyChanged on this page to re-evaluate "Next" — bubble
|
|
// any change from the composed check list up so a live recheck can flip it back, and so
|
|
// the Claude-Help gating re-reads the fresh report.
|
|
Checks.PropertyChanged += (_, _) =>
|
|
{
|
|
OnPropertyChanged(nameof(BlocksNavigation));
|
|
OnPropertyChanged(nameof(ClaudeCliOk));
|
|
OnPropertyChanged(nameof(ClaudeAuthFailed));
|
|
OnPropertyChanged(nameof(CanStartClaudeHelp));
|
|
OnPropertyChanged(nameof(ClaudeHelpTooltip));
|
|
StartClaudeHelpCommand.NotifyCanExecuteChanged();
|
|
};
|
|
}
|
|
|
|
public Task LoadAsync()
|
|
{
|
|
if (!_hasStarted)
|
|
{
|
|
_hasStarted = true;
|
|
_ = Checks.RunChecksCommand.ExecuteAsync(null);
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task ApplyAsync() => Task.CompletedTask;
|
|
|
|
public bool Validate() => !HasBlockingError;
|
|
|
|
[RelayCommand(CanExecute = nameof(CanStartClaudeHelp))]
|
|
private async Task StartClaudeHelpAsync()
|
|
{
|
|
if (Checks.LastReport is null) return;
|
|
|
|
ClaudeHelpError = null;
|
|
var result = await _claudeHelpLauncher.LaunchAsync(Checks.LastReport, _context, CancellationToken.None);
|
|
if (!result.Success)
|
|
{
|
|
ClaudeHelpError = TrExtension.Localizer?.Get("installer.systemCheck.claudeHelp.error", result.ErrorMessage ?? "")
|
|
?? $"Could not start the Claude session: {result.ErrorMessage}";
|
|
}
|
|
}
|
|
}
|