feat(ui): Mission Control Recent Sessions mit verschachtelten Handoffs
Neue Tabelle mission_control_sessions (Migration AddMissionControlSessions), befuellt vom InteractiveLaunchSpecService bei Task-, Ad-hoc- und Handoff-Kacheln. Flyout im Mission-Control-Header listet die letzten 14 Tage / 50 Sessions, Handoffs eingerueckt unter ihrer Ursprungs-Session, mit Fortsetzen (--resume im gespeicherten cwd) und Brief anzeigen.
This commit is contained in:
@@ -48,6 +48,60 @@
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
<Button x:Name="RecentSessionsButton" Classes="icon-btn"
|
||||
ToolTip.Tip="{loc:Tr missionControl.recentSessions}">
|
||||
<PathIcon Data="{StaticResource Icon.Clock}" Width="15" Height="15"/>
|
||||
<Button.Flyout>
|
||||
<Flyout Placement="BottomEdgeAlignedRight" ShowMode="Standard" Opening="OnRecentSessionsFlyoutOpening">
|
||||
<StackPanel Width="380" Spacing="8" Margin="4">
|
||||
<TextBlock Classes="eyebrow"
|
||||
Text="{loc:Tr missionControl.recentSessions}"
|
||||
Foreground="{DynamicResource TextMuteBrush}"
|
||||
LetterSpacing="1.4" />
|
||||
<TextBlock Classes="meta"
|
||||
Text="{loc:Tr missionControl.recentSessionsEmpty}"
|
||||
IsVisible="{Binding !HasRecentSessions}"
|
||||
Foreground="{DynamicResource TextMuteBrush}" />
|
||||
<ScrollViewer MaxHeight="420">
|
||||
<ItemsControl x:Name="RecentSessionsList" ItemsSource="{Binding RecentSessions}">
|
||||
<ItemsControl.Styles>
|
||||
<Style Selector="Grid.handoff">
|
||||
<Setter Property="Margin" Value="{StaticResource NestedRowIndent}" />
|
||||
</Style>
|
||||
</ItemsControl.Styles>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:RecentSessionViewModel">
|
||||
<Grid ColumnDefinitions="*,Auto" Classes.handoff="{Binding IsHandoff}">
|
||||
<StackPanel Grid.Column="0" Spacing="2" Margin="0,4" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding Title}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
ToolTip.Tip="{Binding Title}"
|
||||
Foreground="{DynamicResource TextDimBrush}" />
|
||||
<TextBlock Classes="meta"
|
||||
Text="{Binding Meta}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
ToolTip.Tip="{Binding Meta}"
|
||||
Foreground="{DynamicResource TextMuteBrush}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="4"
|
||||
VerticalAlignment="Center">
|
||||
<Button Classes="btn"
|
||||
Content="{loc:Tr missionControl.showBrief}"
|
||||
Command="{Binding ShowBriefCommand}"
|
||||
IsVisible="{Binding HasBrief}" />
|
||||
<Button Classes="btn"
|
||||
Content="{loc:Tr missionControl.resumeSession}"
|
||||
Command="{Binding ResumeCommand}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
<Button Classes="icon-btn"
|
||||
Command="{Binding ToggleLayoutCommand}"
|
||||
ToolTip.Tip="{Binding LayoutToggleLabel}">
|
||||
|
||||
@@ -29,10 +29,14 @@ public partial class MissionControlView : UserControl
|
||||
InitializeComponent();
|
||||
DataContextChanged += OnDataContextChanged;
|
||||
QueueSplitter.DragCompleted += (_, _) => _queueWidth = BodyGrid.ColumnDefinitions[2].Width;
|
||||
// Resume/Brief buttons don't close a plain Flyout on their own.
|
||||
RecentSessionsList.AddHandler(Button.ClickEvent, (_, _) => RecentSessionsButton.Flyout?.Hide());
|
||||
}
|
||||
|
||||
private void OnSessionFlyoutOpening(object? sender, EventArgs e) => _ = _vm?.RefreshSessionTargetsAsync();
|
||||
|
||||
private void OnRecentSessionsFlyoutOpening(object? sender, EventArgs e) => _ = _vm?.RefreshRecentSessionsAsync();
|
||||
|
||||
// Ad-hoc ConPTY session: the view owns the folder picker, the VM only takes the chosen path.
|
||||
private async void BrowseForSessionAsync()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user