feat(ui): add TaskHeaderBar detail component
Standalone UserControl for the task detail island redesign. Grid layout: id badge + editable title | trash/skull toggle | gear flyout. Skull geometry added to IslandStyles.axaml (Icon.Skull, EvenOdd fill). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,9 @@
|
|||||||
<!-- Icon.Settings (gear) -->
|
<!-- Icon.Settings (gear) -->
|
||||||
<StreamGeometry x:Key="Icon.Settings">M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8z M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65a.5.5 0 0 0 .12-.64l-2-3.46a.5.5 0 0 0-.61-.22l-2.49 1a7.03 7.03 0 0 0-1.69-.98l-.38-2.65a.5.5 0 0 0-.5-.42h-4a.5.5 0 0 0-.5.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1a.5.5 0 0 0-.61.22l-2 3.46a.5.5 0 0 0 .12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65a.5.5 0 0 0-.12.64l2 3.46a.5.5 0 0 0 .61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65a.5.5 0 0 0 .5.42h4a.5.5 0 0 0 .5-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1a.5.5 0 0 0 .61-.22l2-3.46a.5.5 0 0 0-.12-.64l-2.11-1.65z</StreamGeometry>
|
<StreamGeometry x:Key="Icon.Settings">M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8z M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65a.5.5 0 0 0 .12-.64l-2-3.46a.5.5 0 0 0-.61-.22l-2.49 1a7.03 7.03 0 0 0-1.69-.98l-.38-2.65a.5.5 0 0 0-.5-.42h-4a.5.5 0 0 0-.5.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1a.5.5 0 0 0-.61.22l-2 3.46a.5.5 0 0 0 .12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65a.5.5 0 0 0-.12.64l2 3.46a.5.5 0 0 0 .61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65a.5.5 0 0 0 .5.42h4a.5.5 0 0 0 .5-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1a.5.5 0 0 0 .61-.22l2-3.46a.5.5 0 0 0-.12-.64l-2.11-1.65z</StreamGeometry>
|
||||||
|
|
||||||
|
<!-- Icon.Skull — filled silhouette: rounded cranium + eye holes (EvenOdd) + jaw -->
|
||||||
|
<StreamGeometry x:Key="Icon.Skull">F0 M12 2 C7 2 4 5.5 4 10 C4 13.5 6 16 8 17.5 L8 19 C8 20 8.9 21 10 21 L10 18.5 L14 18.5 L14 21 C15.1 21 16 20 16 19 L16 17.5 C18 16 20 13.5 20 10 C20 5.5 17 2 12 2 Z M8.5 8 L8.5 12 L11 12 L11 8 Z M13 8 L13 12 L15.5 12 L15.5 8 Z</StreamGeometry>
|
||||||
|
|
||||||
<!-- Badge brushes -->
|
<!-- Badge brushes -->
|
||||||
<SolidColorBrush x:Key="DraftBadgeBrush" Color="{StaticResource TextMuteColor}"/>
|
<SolidColorBrush x:Key="DraftBadgeBrush" Color="{StaticResource TextMuteColor}"/>
|
||||||
<SolidColorBrush x:Key="PlanningBadgeBrush" Color="{StaticResource PeatColor}"/>
|
<SolidColorBrush x:Key="PlanningBadgeBrush" Color="{StaticResource PeatColor}"/>
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
|
||||||
|
namespace ClaudeDo.Ui.ViewModels.Islands.Detail;
|
||||||
|
|
||||||
|
public record AgentOption(string Name);
|
||||||
|
|
||||||
|
public partial class TaskHeaderBarViewModel : ViewModelBase
|
||||||
|
{
|
||||||
|
[ObservableProperty] private string _taskIdBadge = "#T42";
|
||||||
|
[ObservableProperty] private string _editableTitle = "Refactor diff viewer";
|
||||||
|
|
||||||
|
// Change to true to preview skull icon
|
||||||
|
[ObservableProperty] private bool _isRunning = false;
|
||||||
|
[ObservableProperty] private bool _isAgentSectionEnabled = true;
|
||||||
|
|
||||||
|
[ObservableProperty] private ObservableCollection<string> _taskModelOptions =
|
||||||
|
new() { "claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5" };
|
||||||
|
[ObservableProperty] private string? _taskModelSelection;
|
||||||
|
[ObservableProperty] private string? _modelBadge = "inherited · Global";
|
||||||
|
[ObservableProperty] private string? _modelInheritedHint = "claude-opus-4-5";
|
||||||
|
|
||||||
|
[ObservableProperty] private decimal? _taskMaxTurns;
|
||||||
|
[ObservableProperty] private string? _turnsBadge = "inherited · List";
|
||||||
|
[ObservableProperty] private string? _turnsInheritedHint = "40";
|
||||||
|
|
||||||
|
[ObservableProperty] private string? _taskSystemPrompt;
|
||||||
|
[ObservableProperty] private string? _effectiveSystemPromptHint = "You are a senior .NET developer…";
|
||||||
|
|
||||||
|
[ObservableProperty] private ObservableCollection<AgentOption> _taskAgentOptions =
|
||||||
|
new() { new("default"), new("code-reviewer"), new("test-writer") };
|
||||||
|
[ObservableProperty] private AgentOption? _taskSelectedAgent;
|
||||||
|
[ObservableProperty] private string? _agentBadge;
|
||||||
|
|
||||||
|
[RelayCommand] private void DeleteTask() { }
|
||||||
|
[RelayCommand] private void KillSession() { }
|
||||||
|
[RelayCommand] private void ResetTaskModel() { }
|
||||||
|
[RelayCommand] private void ResetTaskTurns() { }
|
||||||
|
[RelayCommand] private void ResetTaskAgent() { }
|
||||||
|
}
|
||||||
127
src/ClaudeDo.Ui/Views/Islands/Detail/TaskHeaderBar.axaml
Normal file
127
src/ClaudeDo.Ui/Views/Islands/Detail/TaskHeaderBar.axaml
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:vm="using:ClaudeDo.Ui.ViewModels.Islands.Detail"
|
||||||
|
xmlns:ctl="using:ClaudeDo.Ui.Views.Controls"
|
||||||
|
xmlns:loc="using:ClaudeDo.Ui.Localization"
|
||||||
|
x:Class="ClaudeDo.Ui.Views.Islands.Detail.TaskHeaderBar"
|
||||||
|
x:DataType="vm:TaskHeaderBarViewModel">
|
||||||
|
|
||||||
|
<Design.DataContext>
|
||||||
|
<vm:TaskHeaderBarViewModel/>
|
||||||
|
</Design.DataContext>
|
||||||
|
|
||||||
|
<Grid ColumnDefinitions="*,Auto,Auto">
|
||||||
|
|
||||||
|
<!-- Column 0: id badge + editable title -->
|
||||||
|
<StackPanel Grid.Column="0" Spacing="0">
|
||||||
|
<TextBlock Classes="meta"
|
||||||
|
Text="{Binding TaskIdBadge}"
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Cursor="Hand"/>
|
||||||
|
<TextBox Text="{Binding EditableTitle, Mode=TwoWay}"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderThickness="0"
|
||||||
|
FontSize="{StaticResource FontSizeTaskTitle}"
|
||||||
|
FontWeight="Medium"
|
||||||
|
Foreground="{DynamicResource TextBrush}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
AcceptsReturn="False"
|
||||||
|
Padding="0"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Column 1: trash button (not running) -->
|
||||||
|
<Button Grid.Column="1" Classes="icon-btn"
|
||||||
|
Command="{Binding DeleteTaskCommand}"
|
||||||
|
ToolTip.Tip="Delete task"
|
||||||
|
IsVisible="{Binding !IsRunning}"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="6,0,0,0">
|
||||||
|
<PathIcon Data="{StaticResource Icon.Trash}" Width="14" Height="14"
|
||||||
|
Foreground="{DynamicResource BloodBrush}"/>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<!-- Column 1: skull button (running) -->
|
||||||
|
<Button Grid.Column="1" Classes="icon-btn"
|
||||||
|
Command="{Binding KillSessionCommand}"
|
||||||
|
ToolTip.Tip="Kill session"
|
||||||
|
IsVisible="{Binding IsRunning}"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="6,0,0,0">
|
||||||
|
<PathIcon Data="{StaticResource Icon.Skull}" Width="14" Height="14"
|
||||||
|
Foreground="{DynamicResource BloodBrush}"/>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<!-- Column 2: gear button with agent settings flyout -->
|
||||||
|
<Button Grid.Column="2" Classes="icon-btn"
|
||||||
|
ToolTip.Tip="{loc:Tr details.agentSettingsTip}"
|
||||||
|
IsEnabled="{Binding IsAgentSectionEnabled}"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="6,0,0,0">
|
||||||
|
<TextBlock Text="⚙" FontSize="{StaticResource FontSizeTaskTitle}"/>
|
||||||
|
<Button.Flyout>
|
||||||
|
<Flyout Placement="BottomEdgeAlignedRight" ShowMode="Standard">
|
||||||
|
<StackPanel Width="340" Spacing="10" Margin="4">
|
||||||
|
<TextBlock Text="{loc:Tr details.agentSettingsHeading}" FontWeight="SemiBold"/>
|
||||||
|
|
||||||
|
<StackPanel Spacing="2">
|
||||||
|
<Grid ColumnDefinitions="Auto,Auto,*,Auto" ColumnSpacing="6">
|
||||||
|
<TextBlock Grid.Column="0" Classes="field-label" Text="{loc:Tr details.modelLabel}" VerticalAlignment="Center"/>
|
||||||
|
<ctl:InheritedBadge Grid.Column="1" BadgeText="{Binding ModelBadge}"/>
|
||||||
|
<Button Grid.Column="3" Classes="icon-btn" Content="↺" ToolTip.Tip="{loc:Tr settings.inherit.resetToInherited}"
|
||||||
|
Command="{Binding ResetTaskModelCommand}"/>
|
||||||
|
</Grid>
|
||||||
|
<ComboBox ItemsSource="{Binding TaskModelOptions}"
|
||||||
|
SelectedItem="{Binding TaskModelSelection, Mode=TwoWay}"
|
||||||
|
PlaceholderText="{Binding ModelInheritedHint}"
|
||||||
|
HorizontalAlignment="Stretch"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Spacing="2">
|
||||||
|
<Grid ColumnDefinitions="Auto,Auto,*,Auto" ColumnSpacing="6">
|
||||||
|
<TextBlock Grid.Column="0" Classes="field-label" Text="{loc:Tr details.maxTurnsLabel}" VerticalAlignment="Center"/>
|
||||||
|
<ctl:InheritedBadge Grid.Column="1" BadgeText="{Binding TurnsBadge}"/>
|
||||||
|
<Button Grid.Column="3" Classes="icon-btn" Content="↺" ToolTip.Tip="{loc:Tr settings.inherit.resetToInherited}"
|
||||||
|
Command="{Binding ResetTaskTurnsCommand}"/>
|
||||||
|
</Grid>
|
||||||
|
<NumericUpDown Value="{Binding TaskMaxTurns, Mode=TwoWay}"
|
||||||
|
PlaceholderText="{Binding TurnsInheritedHint}"
|
||||||
|
Minimum="1" Maximum="200" Increment="1" FormatString="0"
|
||||||
|
HorizontalAlignment="Stretch"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Spacing="2">
|
||||||
|
<TextBlock Classes="field-label" Text="{loc:Tr details.systemPromptLabel}"/>
|
||||||
|
<TextBox Text="{Binding TaskSystemPrompt, Mode=TwoWay}"
|
||||||
|
AcceptsReturn="True" TextWrapping="Wrap" MinHeight="70"/>
|
||||||
|
<TextBlock Classes="meta" Opacity="0.6"
|
||||||
|
Text="{loc:Tr details.systemPromptPrepended}"
|
||||||
|
IsVisible="{Binding EffectiveSystemPromptHint, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||||
|
<TextBlock Classes="meta" Opacity="0.6" TextWrapping="Wrap"
|
||||||
|
Text="{Binding EffectiveSystemPromptHint}"
|
||||||
|
IsVisible="{Binding EffectiveSystemPromptHint, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Spacing="2">
|
||||||
|
<Grid ColumnDefinitions="Auto,Auto,*,Auto" ColumnSpacing="6">
|
||||||
|
<TextBlock Grid.Column="0" Classes="field-label" Text="{loc:Tr details.agentFileLabel}" VerticalAlignment="Center"/>
|
||||||
|
<ctl:InheritedBadge Grid.Column="1" BadgeText="{Binding AgentBadge}"/>
|
||||||
|
<Button Grid.Column="3" Classes="icon-btn" Content="↺" ToolTip.Tip="{loc:Tr settings.inherit.resetToInherited}"
|
||||||
|
Command="{Binding ResetTaskAgentCommand}"/>
|
||||||
|
</Grid>
|
||||||
|
<ComboBox ItemsSource="{Binding TaskAgentOptions}"
|
||||||
|
SelectedItem="{Binding TaskSelectedAgent, Mode=TwoWay}"
|
||||||
|
HorizontalAlignment="Stretch">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding Name}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Flyout>
|
||||||
|
</Button.Flyout>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
11
src/ClaudeDo.Ui/Views/Islands/Detail/TaskHeaderBar.axaml.cs
Normal file
11
src/ClaudeDo.Ui/Views/Islands/Detail/TaskHeaderBar.axaml.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace ClaudeDo.Ui.Views.Islands.Detail;
|
||||||
|
|
||||||
|
public partial class TaskHeaderBar : UserControl
|
||||||
|
{
|
||||||
|
public TaskHeaderBar()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user