diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs index 7ca80ba..97e98c1 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs @@ -28,12 +28,21 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase [ObservableProperty] private string _workingDir = ""; [ObservableProperty] private string _defaultCommitType = CommitTypeRegistry.DefaultType; - [ObservableProperty] private string _selectedModel = ModelRegistry.ListDefaultSentinel; + [ObservableProperty] private string? _selectedModel; // null = inherit from global + [ObservableProperty] private decimal? _maxTurns; // null = inherit from global + [ObservableProperty] private string _modelInheritedHint = ""; // resolved value placeholder, e.g. "sonnet" + [ObservableProperty] private string _modelBadge = ""; + [ObservableProperty] private string _turnsInheritedHint = ""; + [ObservableProperty] private string _turnsBadge = ""; + [ObservableProperty] private string _agentBadge = ""; + [ObservableProperty] private string _systemPrompt = ""; [ObservableProperty] private AgentInfo? _selectedAgent; - public ObservableCollection ModelOptions { get; } = new( - new[] { ModelRegistry.ListDefaultSentinel }.Concat(ModelRegistry.Aliases)); + private string _globalModel = ModelRegistry.DefaultAlias; + private int _globalMaxTurns = 100; + + public ObservableCollection ModelOptions { get; } = new(ModelRegistry.Aliases); public ObservableCollection CommitTypeOptions { get; } = new(CommitTypeRegistry.Types); @@ -47,6 +56,34 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase _dbFactory = dbFactory; } + partial void OnSelectedModelChanged(string? value) => RecomputeModelBadge(); + partial void OnMaxTurnsChanged(decimal? value) => RecomputeTurnsBadge(); + partial void OnSelectedAgentChanged(AgentInfo? value) => RecomputeAgentBadge(); + + private void RecomputeModelBadge() + { + ModelInheritedHint = _globalModel; + ModelBadge = !string.IsNullOrWhiteSpace(SelectedModel) + ? Loc.T("settings.inherit.overrideBadge") + : Loc.T("settings.inherit.inheritedFromGlobal"); + } + + private void RecomputeTurnsBadge() + { + TurnsInheritedHint = _globalMaxTurns.ToString(); + TurnsBadge = MaxTurns is not null + ? Loc.T("settings.inherit.overrideBadge") + : Loc.T("settings.inherit.inheritedFromGlobal"); + } + + private void RecomputeAgentBadge() + { + var overridden = SelectedAgent is not null && !string.IsNullOrWhiteSpace(SelectedAgent.Path); + AgentBadge = overridden + ? Loc.T("settings.inherit.overrideBadge") + : Loc.T("settings.inherit.inheritedFromGlobal"); + } + public async Task LoadAsync( string listId, string name, @@ -65,19 +102,30 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase foreach (var a in agents) Agents.Add(a); var config = await _worker.GetListConfigAsync(listId); - SelectedModel = string.IsNullOrWhiteSpace(config?.Model) ? ModelRegistry.ListDefaultSentinel : config!.Model!; + + var app = await _worker.GetAppSettingsAsync(); + _globalModel = app?.DefaultModel ?? ModelRegistry.DefaultAlias; + _globalMaxTurns = app?.DefaultMaxTurns ?? 100; + + SelectedModel = string.IsNullOrWhiteSpace(config?.Model) ? null : config!.Model!; + MaxTurns = config?.MaxTurns is int mt ? mt : (decimal?)null; SystemPrompt = config?.SystemPrompt ?? ""; SelectedAgent = string.IsNullOrWhiteSpace(config?.AgentPath) ? Agents[0] : (Agents.FirstOrDefault(a => a.Path == config!.AgentPath) ?? Agents[0]); + + RecomputeModelBadge(); + RecomputeTurnsBadge(); + RecomputeAgentBadge(); } [RelayCommand] private async Task SaveAsync() { - var model = SelectedModel == ModelRegistry.ListDefaultSentinel ? null : SelectedModel; + var model = string.IsNullOrWhiteSpace(SelectedModel) ? null : SelectedModel; var sp = string.IsNullOrWhiteSpace(SystemPrompt) ? null : SystemPrompt; var ap = SelectedAgent is null || string.IsNullOrWhiteSpace(SelectedAgent.Path) ? null : SelectedAgent.Path; + var turns = MaxTurns is decimal d ? (int?)d : null; await _worker.UpdateListAsync(new UpdateListDto( ListId, @@ -85,8 +133,7 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase string.IsNullOrWhiteSpace(WorkingDir) ? null : WorkingDir, DefaultCommitType)); - await _worker.UpdateListConfigAsync(new UpdateListConfigDto( - ListId, model, sp, ap)); + await _worker.UpdateListConfigAsync(new UpdateListConfigDto(ListId, model, sp, ap, turns)); CloseAction?.Invoke(); } @@ -125,10 +172,15 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase [RelayCommand] private void Cancel() => CloseAction?.Invoke(); + [RelayCommand] private void ResetModel() => SelectedModel = null; + [RelayCommand] private void ResetTurns() => MaxTurns = null; + [RelayCommand] private void ResetAgent() => SelectedAgent = Agents.Count > 0 ? Agents[0] : null; + [RelayCommand] private void ResetAgentSettings() { - SelectedModel = ModelRegistry.ListDefaultSentinel; + SelectedModel = null; + MaxTurns = null; SystemPrompt = ""; SelectedAgent = Agents.Count > 0 ? Agents[0] : null; } diff --git a/src/ClaudeDo.Ui/Views/Modals/ListSettingsModalView.axaml b/src/ClaudeDo.Ui/Views/Modals/ListSettingsModalView.axaml index 94271db..ad13ff4 100644 --- a/src/ClaudeDo.Ui/Views/Modals/ListSettingsModalView.axaml +++ b/src/ClaudeDo.Ui/Views/Modals/ListSettingsModalView.axaml @@ -74,12 +74,31 @@ - + + + +