Clearing the text box to type a new value sets Value to null, which the TwoWay binding then wrote into an int/decimal target -- InvalidCastException on the normal way of editing eight settings fields. KeepLastNumberConverter maps that null to BindingOperations.DoNothing so the source keeps its last value.
546 lines
36 KiB
XML
546 lines
36 KiB
XML
<Window xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:vm="using:ClaudeDo.Ui.ViewModels.Modals"
|
|
xmlns:settings="using:ClaudeDo.Ui.ViewModels.Modals.Settings"
|
|
xmlns:ui="using:ClaudeDo.Ui"
|
|
xmlns:agent="using:ClaudeDo.Ui.ViewModels.Agent"
|
|
xmlns:services="using:ClaudeDo.Ui.Services"
|
|
xmlns:ctl="using:ClaudeDo.Ui.Views.Controls"
|
|
xmlns:loc="using:ClaudeDo.Ui.Localization"
|
|
xmlns:locm="using:ClaudeDo.Localization"
|
|
x:Class="ClaudeDo.Ui.Views.Modals.SettingsModalView"
|
|
x:DataType="vm:SettingsModalViewModel"
|
|
Title="{loc:Tr settings.title}"
|
|
Width="580" Height="760" MinWidth="480" MinHeight="520"
|
|
CanResize="True"
|
|
WindowDecorations="BorderOnly"
|
|
ExtendClientAreaToDecorationsHint="True"
|
|
ExtendClientAreaTitleBarHeightHint="-1"
|
|
WindowStartupLocation="CenterOwner"
|
|
Background="{DynamicResource SurfaceBrush}">
|
|
|
|
<Window.KeyBindings>
|
|
<KeyBinding Gesture="Escape" Command="{Binding CancelCommand}"/>
|
|
</Window.KeyBindings>
|
|
|
|
|
|
<ctl:ModalShell Title="{loc:Tr settings.title}" CloseCommand="{Binding CancelCommand}">
|
|
<ctl:ModalShell.Footer>
|
|
<StackPanel Orientation="Horizontal" Spacing="8"
|
|
HorizontalAlignment="Right" VerticalAlignment="Center">
|
|
<Button Classes="btn" Content="{loc:Tr settings.cancel}" Command="{Binding CancelCommand}" MinWidth="90"/>
|
|
<Button Content="{loc:Tr settings.save}" Classes="primary"
|
|
Command="{Binding SaveCommand}"
|
|
IsEnabled="{Binding !IsBusy}" MinWidth="90"/>
|
|
</StackPanel>
|
|
</ctl:ModalShell.Footer>
|
|
|
|
<!-- Body: tabs + bottom validation/status strip -->
|
|
<DockPanel>
|
|
<StackPanel DockPanel.Dock="Bottom" Margin="20,0,20,8" Spacing="2">
|
|
<TextBlock Classes="meta" Text="{Binding ValidationError}"
|
|
Foreground="{DynamicResource BloodBrush}"
|
|
IsVisible="{Binding ValidationError, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
<TextBlock Classes="meta" Text="{Binding StatusMessage}"
|
|
IsVisible="{Binding StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
</StackPanel>
|
|
|
|
<TabControl Padding="20,16" TabStripPlacement="Top">
|
|
|
|
<TabItem Header="{loc:Tr settings.tabGeneral}">
|
|
<ScrollViewer>
|
|
<StackPanel Spacing="12" Margin="0,8,0,0">
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.language}"/>
|
|
<ComboBox ItemsSource="{Binding General.Languages}"
|
|
SelectedItem="{Binding General.SelectedLanguage, Mode=TwoWay}"
|
|
HorizontalAlignment="Left" Width="220">
|
|
<ComboBox.ItemTemplate>
|
|
<DataTemplate x:DataType="locm:LanguageOption">
|
|
<TextBlock Text="{Binding Name}"/>
|
|
</DataTemplate>
|
|
</ComboBox.ItemTemplate>
|
|
</ComboBox>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.accentPreset}"/>
|
|
<ItemsControl ItemsSource="{Binding General.AccentPresetSwatches}">
|
|
<ItemsControl.ItemsPanel>
|
|
<ItemsPanelTemplate>
|
|
<StackPanel Orientation="Horizontal" Spacing="8"/>
|
|
</ItemsPanelTemplate>
|
|
</ItemsControl.ItemsPanel>
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate x:DataType="ui:AccentPresetSwatchViewModel">
|
|
<Button Padding="6,4"
|
|
Command="{Binding $parent[ItemsControl].((vm:SettingsModalViewModel)DataContext).General.SelectAccentPresetCommand}"
|
|
CommandParameter="{Binding Preset}">
|
|
<StackPanel Spacing="4">
|
|
<Grid Width="32" Height="32">
|
|
<Border Width="32" Height="32" CornerRadius="16"
|
|
BorderBrush="{DynamicResource AccentBrush}" BorderThickness="2"
|
|
IsVisible="{Binding IsSelected}"/>
|
|
<Ellipse Width="22" Height="22"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<Ellipse.Fill>
|
|
<SolidColorBrush Color="{Binding DisplayColor}"/>
|
|
</Ellipse.Fill>
|
|
</Ellipse>
|
|
</Grid>
|
|
<TextBlock Text="{Binding DisplayName}"
|
|
HorizontalAlignment="Center" FontSize="11"/>
|
|
</StackPanel>
|
|
</Button>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.defaultInstructions}"/>
|
|
<TextBox AcceptsReturn="True" TextWrapping="Wrap" Height="110"
|
|
PlaceholderText="{loc:Tr settings.general.defaultInstructionsPlaceholder}"
|
|
Text="{Binding General.DefaultClaudeInstructions, Mode=TwoWay}"/>
|
|
</StackPanel>
|
|
<Grid ColumnDefinitions="*,12,*">
|
|
<StackPanel Grid.Column="0" Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.model}"/>
|
|
<ComboBox ItemsSource="{Binding General.Models}"
|
|
SelectedItem="{Binding General.DefaultModel, Mode=TwoWay}"
|
|
HorizontalAlignment="Stretch"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2" Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.permission}"/>
|
|
<ComboBox ItemsSource="{Binding General.PermissionModes}"
|
|
SelectedItem="{Binding General.DefaultPermissionMode, Mode=TwoWay}"
|
|
HorizontalAlignment="Stretch"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<!-- Per-model run defaults: replaces the single global "max turns" field. -->
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.modelPresets}"/>
|
|
<TextBlock Text="{loc:Tr settings.general.modelPresetsHint}"
|
|
Opacity="0.6" FontSize="12" TextWrapping="Wrap"/>
|
|
<Grid ColumnDefinitions="90,12,*,12,110" Margin="0,4,0,0">
|
|
<TextBlock Grid.Column="0" Classes="eyebrow" Text="{loc:Tr settings.general.model}"/>
|
|
<TextBlock Grid.Column="2" Classes="eyebrow" Text="{loc:Tr settings.general.effort}"/>
|
|
<TextBlock Grid.Column="4" Classes="eyebrow" Text="{loc:Tr settings.general.maxTurns}"/>
|
|
</Grid>
|
|
<ItemsControl ItemsSource="{Binding General.ModelPresets}">
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate x:DataType="settings:ModelPresetRowViewModel">
|
|
<StackPanel Spacing="2" Margin="0,0,0,6">
|
|
<Grid ColumnDefinitions="90,12,*,12,110">
|
|
<TextBlock Grid.Column="0" Text="{Binding Model}" VerticalAlignment="Center"/>
|
|
<ComboBox Grid.Column="2" ItemsSource="{Binding EffortLevels}"
|
|
SelectedItem="{Binding Effort, Mode=TwoWay}"
|
|
HorizontalAlignment="Stretch"/>
|
|
<NumericUpDown Grid.Column="4" Value="{Binding MaxTurns, Mode=TwoWay, Converter={StaticResource KeepLastNumber}}"
|
|
Minimum="1" Maximum="200" Increment="1" FormatString="0"/>
|
|
</Grid>
|
|
<TextBlock Classes="meta" Opacity="0.6" TextWrapping="Wrap"
|
|
Text="{Binding ClampHint}"
|
|
IsVisible="{Binding ClampHint, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
</StackPanel>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
<StackPanel Spacing="4" Margin="0,4,0,0">
|
|
<TextBlock Classes="eyebrow" Text="{loc:Tr settings.general.maxTurnsCeiling}"/>
|
|
<NumericUpDown Value="{Binding General.MaxTurnsCeiling, Mode=TwoWay, Converter={StaticResource KeepLastNumber}}"
|
|
Minimum="1" Maximum="200" Increment="10" FormatString="0"
|
|
HorizontalAlignment="Left" Width="140"/>
|
|
<TextBlock Text="{loc:Tr settings.general.maxTurnsCeilingHint}"
|
|
Opacity="0.6" FontSize="12" TextWrapping="Wrap"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.maxParallelExecutions}"/>
|
|
<NumericUpDown Value="{Binding General.MaxParallelExecutions, Mode=TwoWay, Converter={StaticResource KeepLastNumber}}"
|
|
Minimum="1" Maximum="20" Increment="1" FormatString="0"
|
|
HorizontalAlignment="Left" Width="140"/>
|
|
<TextBlock Text="{loc:Tr settings.general.maxParallelExecutionsHint}"
|
|
Opacity="0.6" FontSize="12"/>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.usageGateHeading}"/>
|
|
<TextBlock Text="{loc:Tr settings.general.usageGateHint}"
|
|
Opacity="0.6" FontSize="12" TextWrapping="Wrap"/>
|
|
<StackPanel Orientation="Horizontal" Spacing="16">
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="eyebrow" Text="{loc:Tr settings.general.usageGateFiveHourPct}"/>
|
|
<NumericUpDown Value="{Binding General.UsageGateFiveHourPct, Mode=TwoWay, Converter={StaticResource KeepLastNumber}}"
|
|
Minimum="0" Maximum="100" Increment="5" FormatString="0"
|
|
HorizontalAlignment="Left" Width="140"/>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="eyebrow" Text="{loc:Tr settings.general.usageGateSevenDayPct}"/>
|
|
<NumericUpDown Value="{Binding General.UsageGateSevenDayPct, Mode=TwoWay, Converter={StaticResource KeepLastNumber}}"
|
|
Minimum="0" Maximum="100" Increment="5" FormatString="0"
|
|
HorizontalAlignment="Left" Width="140"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.reportExcludedPaths}"/>
|
|
<TextBox AcceptsReturn="True" MinHeight="60" Text="{Binding General.ReportExcludedPaths, Mode=TwoWay}"/>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.standupWeekday}"/>
|
|
<ComboBox SelectedIndex="{Binding General.StandupWeekday, Mode=TwoWay}" HorizontalAlignment="Left">
|
|
<ComboBoxItem Content="{loc:Tr settings.general.weekdaySunday}"/>
|
|
<ComboBoxItem Content="{loc:Tr settings.general.weekdayMonday}"/>
|
|
<ComboBoxItem Content="{loc:Tr settings.general.weekdayTuesday}"/>
|
|
<ComboBoxItem Content="{loc:Tr settings.general.weekdayWednesday}"/>
|
|
<ComboBoxItem Content="{loc:Tr settings.general.weekdayThursday}"/>
|
|
<ComboBoxItem Content="{loc:Tr settings.general.weekdayFriday}"/>
|
|
<ComboBoxItem Content="{loc:Tr settings.general.weekdaySaturday}"/>
|
|
</ComboBox>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.general.sessionSkills}"/>
|
|
<TextBlock Classes="meta" Opacity="0.6" TextWrapping="Wrap"
|
|
Text="{loc:Tr settings.general.sessionSkillsHint}"/>
|
|
<ItemsControl ItemsSource="{Binding General.SessionSkills}">
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate x:DataType="agent:SelectableSkillViewModel">
|
|
<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" Content="{Binding Name}"
|
|
ToolTip.Tip="{Binding Description}"/>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
|
|
<TabItem Header="{loc:Tr settings.tabWorktrees}">
|
|
<ScrollViewer>
|
|
<StackPanel Spacing="12" Margin="0,8,0,0">
|
|
<Grid ColumnDefinitions="*,12,2*">
|
|
<StackPanel Grid.Column="0" Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.worktrees.strategy}"/>
|
|
<ComboBox ItemsSource="{Binding Worktrees.WorktreeStrategies}"
|
|
SelectedItem="{Binding Worktrees.WorktreeStrategy, Mode=TwoWay}"
|
|
HorizontalAlignment="Stretch"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2" Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.worktrees.centralWorktreeRoot}"/>
|
|
<TextBox Text="{Binding Worktrees.CentralWorktreeRoot, Mode=TwoWay}"
|
|
PlaceholderText="e.g. C:\worktrees"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<CheckBox IsChecked="{Binding Worktrees.WorktreeAutoCleanupEnabled, Mode=TwoWay}"
|
|
Content="{loc:Tr settings.worktrees.autoCleanup}"
|
|
VerticalAlignment="Center"/>
|
|
<NumericUpDown Value="{Binding Worktrees.WorktreeAutoCleanupDays, Mode=TwoWay, Converter={StaticResource KeepLastNumber}}"
|
|
Width="130" Minimum="1" Maximum="365" Increment="1" FormatString="0"
|
|
IsEnabled="{Binding Worktrees.WorktreeAutoCleanupEnabled}"/>
|
|
<TextBlock Classes="body" Text="{loc:Tr settings.worktrees.days}" VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
<Border BorderBrush="{DynamicResource LineBrush}" BorderThickness="0,1,0,0" Margin="0,4,0,0"/>
|
|
<StackPanel Spacing="8">
|
|
<Button Classes="btn" Content="{loc:Tr settings.worktrees.cleanupFinished}"
|
|
Command="{Binding Worktrees.CleanupWorktreesCommand}"
|
|
HorizontalAlignment="Left"/>
|
|
<StackPanel>
|
|
<Button Content="{loc:Tr settings.worktrees.forceRemoveAll}" Classes="danger"
|
|
Command="{Binding Worktrees.RequestResetConfirmCommand}"
|
|
HorizontalAlignment="Left"
|
|
IsVisible="{Binding !Worktrees.ShowResetConfirm}"/>
|
|
<Border Classes="danger-box"
|
|
IsVisible="{Binding Worktrees.ShowResetConfirm}">
|
|
<StackPanel Spacing="8">
|
|
<TextBlock Text="{loc:Tr settings.worktrees.confirmRemoveAll}"
|
|
Foreground="{DynamicResource TextBrush}" TextWrapping="Wrap"/>
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<Button Classes="btn" Content="{loc:Tr settings.cancel}" Command="{Binding Worktrees.CancelResetConfirmCommand}"/>
|
|
<Button Content="{loc:Tr settings.worktrees.removeAll}" Classes="danger"
|
|
Command="{Binding Worktrees.ConfirmResetAllCommand}"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
<TextBlock Classes="meta" Text="{Binding Worktrees.StatusMessage}"
|
|
IsVisible="{Binding Worktrees.StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
|
|
<TabItem Header="{loc:Tr settings.tabFiles}">
|
|
<ScrollViewer>
|
|
<StackPanel Spacing="12" Margin="0,8,0,0">
|
|
<StackPanel Spacing="6">
|
|
<TextBlock Classes="section-label" Text="{loc:Tr settings.files.agentsSection}"/>
|
|
<TextBlock Classes="meta" Text="{loc:Tr settings.files.agentsHint}"
|
|
TextWrapping="Wrap"/>
|
|
<Button Classes="btn" Content="{loc:Tr settings.files.restoreDefaultAgents}"
|
|
Command="{Binding Files.RestoreDefaultAgentsCommand}"
|
|
IsEnabled="{Binding !Files.IsBusy}"
|
|
HorizontalAlignment="Left"/>
|
|
</StackPanel>
|
|
<StackPanel Spacing="6">
|
|
<TextBlock Classes="section-label" Text="{loc:Tr settings.files.promptsSection}"/>
|
|
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto" ColumnDefinitions="120,*,Auto" RowSpacing="8">
|
|
<TextBlock Grid.Row="0" Grid.Column="0" Classes="field-label" Text="{loc:Tr settings.files.systemPrompt}" VerticalAlignment="Center"/>
|
|
<TextBlock Grid.Row="0" Grid.Column="1" Classes="path-mono" Text="{Binding Files.SystemPromptPath}" VerticalAlignment="Center"/>
|
|
<Button Classes="btn" Grid.Row="0" Grid.Column="2" Content="{loc:Tr settings.files.viewPrompt}"
|
|
Command="{Binding Files.ViewPromptCommand}" CommandParameter="System"/>
|
|
<TextBlock Grid.Row="1" Grid.Column="0" Classes="field-label" Text="{loc:Tr settings.files.planningPrompt}" VerticalAlignment="Center"/>
|
|
<TextBlock Grid.Row="1" Grid.Column="1" Classes="path-mono" Text="{Binding Files.PlanningPromptPath}" VerticalAlignment="Center"/>
|
|
<Button Classes="btn" Grid.Row="1" Grid.Column="2" Content="{loc:Tr settings.files.viewPrompt}"
|
|
Command="{Binding Files.ViewPromptCommand}" CommandParameter="Planning"/>
|
|
<TextBlock Grid.Row="2" Grid.Column="0" Classes="field-label" Text="{loc:Tr settings.files.planningInitialPrompt}" VerticalAlignment="Center"/>
|
|
<TextBlock Grid.Row="2" Grid.Column="1" Classes="path-mono" Text="{Binding Files.PlanningInitialPromptPath}" VerticalAlignment="Center"/>
|
|
<Button Classes="btn" Grid.Row="2" Grid.Column="2" Content="{loc:Tr settings.files.viewPrompt}"
|
|
Command="{Binding Files.ViewPromptCommand}" CommandParameter="PlanningInitial"/>
|
|
<TextBlock Grid.Row="3" Grid.Column="0" Classes="field-label" Text="{loc:Tr settings.files.retryPrompt}" VerticalAlignment="Center"/>
|
|
<TextBlock Grid.Row="3" Grid.Column="1" Classes="path-mono" Text="{Binding Files.RetryPromptPath}" VerticalAlignment="Center"/>
|
|
<Button Classes="btn" Grid.Row="3" Grid.Column="2" Content="{loc:Tr settings.files.viewPrompt}"
|
|
Command="{Binding Files.ViewPromptCommand}" CommandParameter="Retry"/>
|
|
<TextBlock Grid.Row="4" Grid.Column="0" Classes="field-label" Text="{loc:Tr settings.files.dailyPrepPrompt}" VerticalAlignment="Center"/>
|
|
<TextBlock Grid.Row="4" Grid.Column="1" Classes="path-mono" Text="{Binding Files.DailyPrepPromptPath}" VerticalAlignment="Center"/>
|
|
<Button Classes="btn" Grid.Row="4" Grid.Column="2" Content="{loc:Tr settings.files.viewPrompt}"
|
|
Command="{Binding Files.ViewPromptCommand}" CommandParameter="DailyPrep"/>
|
|
<TextBlock Grid.Row="5" Grid.Column="0" Classes="field-label" Text="{loc:Tr settings.files.weeklyReportPrompt}" VerticalAlignment="Center"/>
|
|
<TextBlock Grid.Row="5" Grid.Column="1" Classes="path-mono" Text="{Binding Files.WeeklyReportPromptPath}" VerticalAlignment="Center"/>
|
|
<Button Classes="btn" Grid.Row="5" Grid.Column="2" Content="{loc:Tr settings.files.viewPrompt}"
|
|
Command="{Binding Files.ViewPromptCommand}" CommandParameter="WeeklyReport"/>
|
|
</Grid>
|
|
</StackPanel>
|
|
<StackPanel Spacing="6" IsVisible="{Binding Files.ViewedKindName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}">
|
|
<TextBlock Classes="section-label" Text="{Binding Files.ViewedKindName}"/>
|
|
<Border BorderBrush="{DynamicResource LineBrush}" BorderThickness="1" CornerRadius="6" Padding="10"
|
|
Background="{DynamicResource DeepBrush}">
|
|
<ScrollViewer MaxHeight="260">
|
|
<ctl:MarkdownView Markdown="{Binding Files.ViewedContent}"/>
|
|
</ScrollViewer>
|
|
</Border>
|
|
</StackPanel>
|
|
<StackPanel Spacing="6" IsVisible="{Binding Files.HasCustomizedPrompts}">
|
|
<TextBlock Classes="section-label" Text="{loc:Tr settings.files.customizedSection}"/>
|
|
<TextBlock Classes="meta" Text="{loc:Tr settings.files.customizedHint}" TextWrapping="Wrap"/>
|
|
<ItemsControl ItemsSource="{Binding Files.CustomizedPrompts}">
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate>
|
|
<StackPanel Spacing="4" Margin="0,0,0,10">
|
|
<Grid ColumnDefinitions="*,Auto">
|
|
<TextBlock Grid.Column="0" Classes="field-label" Text="{Binding KindName}" VerticalAlignment="Center"/>
|
|
<Button Grid.Column="1" Classes="btn" Content="{loc:Tr settings.files.resetToDefault}"
|
|
Command="{Binding ResetCommand}"/>
|
|
</Grid>
|
|
<TextBlock Classes="path-mono" Text="{Binding DiffPreview}" TextWrapping="Wrap"/>
|
|
</StackPanel>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
</StackPanel>
|
|
<TextBlock Classes="meta" Text="{Binding Files.StatusMessage}"
|
|
IsVisible="{Binding Files.StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
|
|
<TabItem Header="{loc:Tr settings.tabPrime}">
|
|
<ScrollViewer>
|
|
<StackPanel Spacing="12" Margin="0,8,0,0">
|
|
<TextBlock Classes="meta" TextWrapping="Wrap"
|
|
Text="{loc:Tr settings.prime.description}"/>
|
|
<ItemsControl ItemsSource="{Binding Prime.Rows}">
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate x:DataType="settings:PrimeScheduleRowViewModel">
|
|
<Border BorderBrush="{DynamicResource LineBrush}" BorderThickness="1"
|
|
CornerRadius="6" Padding="10,8" Margin="0,0,0,8"
|
|
Background="{DynamicResource DeepBrush}">
|
|
<Grid ColumnDefinitions="Auto,*,Auto,Auto,Auto" ColumnSpacing="8">
|
|
<CheckBox Grid.Column="0" IsChecked="{Binding Enabled, Mode=TwoWay}" VerticalAlignment="Center"/>
|
|
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="4" VerticalAlignment="Center">
|
|
<ToggleButton Classes="day-toggle" Content="{loc:Tr settings.prime.dayMo}" IsChecked="{Binding Monday, Mode=TwoWay}"/>
|
|
<ToggleButton Classes="day-toggle" Content="{loc:Tr settings.prime.dayTu}" IsChecked="{Binding Tuesday, Mode=TwoWay}"/>
|
|
<ToggleButton Classes="day-toggle" Content="{loc:Tr settings.prime.dayWe}" IsChecked="{Binding Wednesday, Mode=TwoWay}"/>
|
|
<ToggleButton Classes="day-toggle" Content="{loc:Tr settings.prime.dayTh}" IsChecked="{Binding Thursday, Mode=TwoWay}"/>
|
|
<ToggleButton Classes="day-toggle" Content="{loc:Tr settings.prime.dayFr}" IsChecked="{Binding Friday, Mode=TwoWay}"/>
|
|
<ToggleButton Classes="day-toggle" Content="{loc:Tr settings.prime.daySa}" IsChecked="{Binding Saturday, Mode=TwoWay}"/>
|
|
<ToggleButton Classes="day-toggle" Content="{loc:Tr settings.prime.daySu}" IsChecked="{Binding Sunday, Mode=TwoWay}"/>
|
|
</StackPanel>
|
|
<TextBox Grid.Column="2"
|
|
Text="{Binding TimeText, Mode=TwoWay}"
|
|
PlaceholderText="HH:mm" MaxLength="5"
|
|
Width="68" VerticalAlignment="Center"/>
|
|
<TextBlock Classes="meta" Grid.Column="3" Text="{Binding LastRunLabel}" VerticalAlignment="Center"
|
|
MinWidth="80"/>
|
|
<Button Classes="icon-btn" Grid.Column="4" Content="✕"
|
|
ToolTip.Tip="{loc:Tr settings.prime.removeScheduleTip}"
|
|
Command="{Binding $parent[ItemsControl].((vm:SettingsModalViewModel)DataContext).Prime.RemoveScheduleCommand}"
|
|
CommandParameter="{Binding}"/>
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
<Button Classes="btn" Content="{loc:Tr settings.prime.addSchedule}" Command="{Binding Prime.AddScheduleCommand}" HorizontalAlignment="Left"/>
|
|
<StackPanel Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.prime.dailyPrepMaxTasks}" VerticalAlignment="Center"/>
|
|
<NumericUpDown Minimum="1" Maximum="50" Increment="1" Width="100" FormatString="0"
|
|
Value="{Binding Prime.DailyPrepMaxTasks, Mode=TwoWay, Converter={StaticResource KeepLastNumber}}"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
|
|
<TabItem Header="{loc:Tr settings.onlineInbox.tabHeader}">
|
|
<ScrollViewer>
|
|
<StackPanel Spacing="14" Margin="0,8,0,0">
|
|
|
|
<!-- Enable toggle + restart hint -->
|
|
<StackPanel Spacing="4">
|
|
<CheckBox IsChecked="{Binding OnlineInbox.Enabled, Mode=TwoWay}"
|
|
Content="{loc:Tr settings.onlineInbox.enabledLabel}"/>
|
|
<TextBlock Classes="meta" Text="{loc:Tr settings.onlineInbox.restartHint}"
|
|
TextWrapping="Wrap" Opacity="0.6"/>
|
|
</StackPanel>
|
|
|
|
<Border BorderBrush="{DynamicResource LineBrush}" BorderThickness="0,1,0,0" Margin="0,2,0,0"/>
|
|
|
|
<!-- Auth status section -->
|
|
<StackPanel Spacing="8">
|
|
<TextBlock Classes="section-label" Text="{loc:Tr settings.onlineInbox.statusSection}"/>
|
|
<StackPanel Orientation="Horizontal" Spacing="10" VerticalAlignment="Center"
|
|
IsVisible="{Binding OnlineInbox.SignedIn}">
|
|
<Border Width="8" Height="8" CornerRadius="4"
|
|
Background="{DynamicResource StatusRunningBrush}"/>
|
|
<TextBlock Classes="body" VerticalAlignment="Center"
|
|
Text="{loc:Tr settings.onlineInbox.signedInStatus}"/>
|
|
</StackPanel>
|
|
<StackPanel Orientation="Horizontal" Spacing="10" VerticalAlignment="Center"
|
|
IsVisible="{Binding !OnlineInbox.SignedIn}">
|
|
<Border Width="8" Height="8" CornerRadius="4"
|
|
Background="{DynamicResource StatusIdleBrush}"/>
|
|
<TextBlock Classes="body" VerticalAlignment="Center"
|
|
Text="{loc:Tr settings.onlineInbox.signedOutStatus}"/>
|
|
</StackPanel>
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<Button Classes="btn"
|
|
Content="{loc:Tr settings.onlineInbox.signInButton}"
|
|
Command="{Binding OnlineInbox.SignInCommand}"
|
|
IsEnabled="{Binding !OnlineInbox.IsBusy}"
|
|
IsVisible="{Binding !OnlineInbox.SignedIn}"/>
|
|
<Button Classes="btn danger"
|
|
Content="{loc:Tr settings.onlineInbox.signOutButton}"
|
|
Command="{Binding OnlineInbox.SignOutCommand}"
|
|
IsEnabled="{Binding !OnlineInbox.IsBusy}"
|
|
IsVisible="{Binding OnlineInbox.SignedIn}"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
<Border BorderBrush="{DynamicResource LineBrush}" BorderThickness="0,1,0,0" Margin="0,2,0,0"/>
|
|
|
|
<!-- Config fields -->
|
|
<StackPanel Spacing="10">
|
|
<TextBlock Classes="section-label" Text="{loc:Tr settings.onlineInbox.configSection}"/>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.onlineInbox.apiBaseUrlLabel}"/>
|
|
<TextBox Text="{Binding OnlineInbox.ApiBaseUrl, Mode=TwoWay}"
|
|
PlaceholderText="{loc:Tr settings.onlineInbox.apiBaseUrlPlaceholder}"/>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.onlineInbox.authorityLabel}"/>
|
|
<TextBox Text="{Binding OnlineInbox.Authority, Mode=TwoWay}"
|
|
PlaceholderText="{loc:Tr settings.onlineInbox.authorityPlaceholder}"/>
|
|
</StackPanel>
|
|
<Grid ColumnDefinitions="*,12,*">
|
|
<StackPanel Grid.Column="0" Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.onlineInbox.clientIdLabel}"/>
|
|
<TextBox Text="{Binding OnlineInbox.ClientId, Mode=TwoWay}"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2" Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.onlineInbox.scopesLabel}"/>
|
|
<TextBox Text="{Binding OnlineInbox.Scopes, Mode=TwoWay}"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.onlineInbox.redirectUriLabel}"/>
|
|
<TextBox Text="{Binding OnlineInbox.RedirectUri, Mode=TwoWay}"/>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Classes="field-label" Text="{loc:Tr settings.onlineInbox.pollIntervalLabel}"/>
|
|
<NumericUpDown Value="{Binding OnlineInbox.PollIntervalSeconds, Mode=TwoWay, Converter={StaticResource KeepLastNumber}}"
|
|
Minimum="10" Maximum="3600" Increment="10" FormatString="0"
|
|
HorizontalAlignment="Left" Width="140"/>
|
|
</StackPanel>
|
|
<Button Classes="btn"
|
|
Content="{loc:Tr settings.onlineInbox.saveButton}"
|
|
Command="{Binding OnlineInbox.SaveCommand}"
|
|
IsEnabled="{Binding !OnlineInbox.IsBusy}"
|
|
HorizontalAlignment="Left"/>
|
|
</StackPanel>
|
|
|
|
<TextBlock Classes="meta" Text="{Binding OnlineInbox.StatusMessage}"
|
|
IsVisible="{Binding OnlineInbox.StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
|
|
<TabItem Header="{loc:Tr settings.tabSkills}">
|
|
<ScrollViewer>
|
|
<StackPanel Spacing="12" Margin="0,8,0,0">
|
|
<StackPanel Spacing="6">
|
|
<TextBlock Classes="section-label" Text="{loc:Tr settings.skills.installSection}"/>
|
|
<Grid ColumnDefinitions="*,Auto" ColumnSpacing="8">
|
|
<TextBox Grid.Column="0" Text="{Binding SessionSkills.InstallUrl, Mode=TwoWay}"
|
|
PlaceholderText="{loc:Tr settings.skills.installUrlPlaceholder}"/>
|
|
<Button Grid.Column="1" Classes="btn" Content="{loc:Tr settings.skills.installButton}"
|
|
Command="{Binding SessionSkills.InstallCommand}"
|
|
IsEnabled="{Binding !SessionSkills.IsBusy}"/>
|
|
</Grid>
|
|
</StackPanel>
|
|
|
|
<Border BorderBrush="{DynamicResource LineBrush}" BorderThickness="0,1,0,0" Margin="0,2,0,0"/>
|
|
|
|
<StackPanel Spacing="6">
|
|
<TextBlock Classes="section-label" Text="{loc:Tr settings.skills.installedSection}"/>
|
|
<ItemsControl ItemsSource="{Binding SessionSkills.Skills}">
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate x:DataType="services:SessionSkillDto">
|
|
<Border BorderBrush="{DynamicResource LineBrush}" BorderThickness="1"
|
|
CornerRadius="6" Padding="10,8" Margin="0,0,0,8"
|
|
Background="{DynamicResource DeepBrush}">
|
|
<StackPanel Spacing="4">
|
|
<Grid ColumnDefinitions="*,Auto,Auto">
|
|
<TextBlock Grid.Column="0" Classes="title" Text="{Binding Name}"/>
|
|
<Button Grid.Column="1" Classes="btn" Content="{loc:Tr settings.skills.updateButton}"
|
|
Margin="0,0,6,0"
|
|
Command="{Binding $parent[ItemsControl].((vm:SettingsModalViewModel)DataContext).SessionSkills.UpdateCommand}"
|
|
CommandParameter="{Binding SourceUrl}"/>
|
|
<Button Grid.Column="2" Classes="btn danger" Content="{loc:Tr settings.skills.removeButton}"
|
|
Command="{Binding $parent[ItemsControl].((vm:SettingsModalViewModel)DataContext).SessionSkills.RemoveCommand}"
|
|
CommandParameter="{Binding SourceUrl}"/>
|
|
</Grid>
|
|
<TextBlock Classes="meta" Text="{Binding Description}" TextWrapping="Wrap"
|
|
IsVisible="{Binding Description, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
<TextBlock Classes="meta" Opacity="0.6" Text="{Binding PinnedRef}"/>
|
|
<TextBlock Classes="path-mono" Text="{Binding SourceUrl}" TextTrimming="PrefixCharacterEllipsis"/>
|
|
</StackPanel>
|
|
</Border>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
<TextBlock Classes="meta" Opacity="0.6" TextWrapping="Wrap"
|
|
Text="{loc:Tr settings.skills.emptyState}"
|
|
IsVisible="{Binding SessionSkills.IsEmpty}"/>
|
|
</StackPanel>
|
|
|
|
<TextBlock Classes="meta" Text="{Binding SessionSkills.StatusMessage}"
|
|
IsVisible="{Binding SessionSkills.StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
|
|
</TabControl>
|
|
</DockPanel>
|
|
|
|
</ctl:ModalShell>
|
|
</Window>
|