Kontext: src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs ist mit 1431 Zeilen ein God-VM mit ~12 Concerns (Log-Streaming, Titel/Description-Editing, Subtasks, Child-Outcomes, Merge-Preview/-Targets, Diff, Agent-Settings-Overrides, Notes-Mode, Prep-Mode, Tabs, Session-Outcome/Roadblocks, Worktree-Info). Jedes neue Feature landet dort. Änderungen — drei klar abgrenzbare Sektionen als ei ClaudeDo-Task: 483e419f-1ec8-46ba-986b-8b90d6596b49
128 lines
5.8 KiB
XML
128 lines
5.8 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:vm="using:ClaudeDo.Ui.ViewModels.Islands"
|
|
xmlns:islands="using:ClaudeDo.Ui.Views.Islands"
|
|
xmlns:detail="using:ClaudeDo.Ui.Views.Islands.Detail"
|
|
xmlns:loc="using:ClaudeDo.Ui.Localization"
|
|
x:Class="ClaudeDo.Ui.Views.Islands.DetailsIslandView"
|
|
x:DataType="vm:DetailsIslandViewModel">
|
|
<DockPanel>
|
|
|
|
<!-- ── Metadata footer (sticky bottom) — created-at + close — task detail only ── -->
|
|
<Border DockPanel.Dock="Bottom"
|
|
IsVisible="{Binding IsTaskDetailVisible}"
|
|
BorderBrush="{DynamicResource LineBrush}"
|
|
BorderThickness="0,1,0,0"
|
|
Padding="14,8">
|
|
<Grid ColumnDefinitions="*,Auto">
|
|
<TextBlock Grid.Column="0"
|
|
Classes="meta"
|
|
Text="{Binding Task.CreatedAtFormatted}"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"/>
|
|
<Button Grid.Column="1" Classes="icon-btn"
|
|
Command="{Binding CloseDetailsCommand}"
|
|
ToolTip.Tip="{loc:Tr details.closeTip}"
|
|
VerticalAlignment="Center">
|
|
<PathIcon Data="{StaticResource Icon.X}" Width="14" Height="14"/>
|
|
</Button>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- ── Header (sticky top): id · title · trash/skull · gear — task detail only ── -->
|
|
<Border DockPanel.Dock="Top" Classes="island-header"
|
|
IsVisible="{Binding IsTaskDetailVisible}">
|
|
<detail:TaskHeaderBar/>
|
|
</Border>
|
|
|
|
<!-- ── Body: task details (normal), notes editor (notes mode), or prep log (prep mode) ── -->
|
|
<Grid>
|
|
|
|
<!-- Task detail: description/steps card (upper) + pinned work console (lower) -->
|
|
<Grid x:Name="DetailBodyGrid"
|
|
IsVisible="{Binding IsTaskDetailVisible}"
|
|
Margin="14,12,14,12">
|
|
<Grid.RowDefinitions>
|
|
<!-- Auto: the description sizes to its content so the console takes
|
|
every spare pixel when it's short. Row limits are proportional
|
|
and set in code-behind (UpdateRowLimits): the description row is
|
|
capped at 2/3 of the island and the console row floored at 1/3,
|
|
so the console can be dragged down to (but not below) 1/3 and a
|
|
long description never spills over the footer. -->
|
|
<RowDefinition Height="Auto" MinHeight="90"/>
|
|
<RowDefinition Height="*"/>
|
|
</Grid.RowDefinitions>
|
|
<detail:DescriptionStepsCard x:Name="DescriptionCard" Grid.Row="0"/>
|
|
|
|
<!-- Console row also hosts the roadblock card (docked above the console)
|
|
so it surfaces at a glance between Details and Output. Keeping it
|
|
inside row 1 leaves the desc/console resize model untouched. -->
|
|
<DockPanel Grid.Row="1" Margin="0,10,0,0">
|
|
<Border DockPanel.Dock="Top"
|
|
IsVisible="{Binding ShowRoadblockCard}"
|
|
Margin="0,0,0,10" Padding="12,10"
|
|
Background="{DynamicResource ReviewTintBrush}"
|
|
BorderBrush="{DynamicResource ReviewTintBorderBrush}"
|
|
BorderThickness="1" CornerRadius="10">
|
|
<StackPanel Spacing="6">
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<PathIcon Data="{StaticResource Icon.Warning}"
|
|
Foreground="{DynamicResource StatusReviewBrush}"
|
|
Width="14" Height="14" VerticalAlignment="Center"/>
|
|
<TextBlock Classes="section-label" Text="ROADBLOCK"
|
|
Foreground="{DynamicResource StatusReviewBrush}"
|
|
VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
<SelectableTextBlock Text="{Binding Roadblocks}"
|
|
TextWrapping="Wrap"
|
|
Foreground="{DynamicResource TextDimBrush}"/>
|
|
</StackPanel>
|
|
</Border>
|
|
<detail:WorkConsole/>
|
|
</DockPanel>
|
|
|
|
<!-- Resize by dragging the console's top edge — a transparent splitter
|
|
over the gap above the console; no standalone separator bar.
|
|
Stays draggable while maximized. -->
|
|
<GridSplitter x:Name="DetailSplitter" Grid.Row="1"
|
|
VerticalAlignment="Top"
|
|
Height="10"
|
|
HorizontalAlignment="Stretch"
|
|
ResizeDirection="Rows"
|
|
Background="Transparent"
|
|
DragStarted="OnSplitterDragStarted"
|
|
DragCompleted="OnSplitterDragCompleted"/>
|
|
</Grid>
|
|
|
|
<!-- Notes mode -->
|
|
<Panel IsVisible="{Binding IsNotesMode}">
|
|
<islands:NotesEditorView DataContext="{Binding Notes}"/>
|
|
</Panel>
|
|
|
|
<!-- Daily-prep mode -->
|
|
<Panel IsVisible="{Binding IsPrepMode}">
|
|
<DockPanel>
|
|
<Border DockPanel.Dock="Top" Padding="12,8">
|
|
<Button Classes="btn primary"
|
|
Command="{Binding Prep.PlanDayCommand}"
|
|
IsEnabled="{Binding !Prep.IsPrepRunning}"
|
|
Content="{loc:Tr details.planDay}"/>
|
|
</Border>
|
|
<Panel>
|
|
<islands:SessionTerminalView
|
|
Margin="18,8,18,0"
|
|
Entries="{Binding Prep.PrepLog}" Label="daily-prep"
|
|
IsRunning="{Binding Prep.IsPrepRunning}"/>
|
|
<TextBlock IsVisible="{Binding Prep.ShowPrepEmptyState}"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
Foreground="{DynamicResource TextMuteBrush}"
|
|
Text="{loc:Tr details.prepEmpty}"/>
|
|
</Panel>
|
|
</DockPanel>
|
|
</Panel>
|
|
|
|
</Grid>
|
|
|
|
</DockPanel>
|
|
</UserControl>
|