chore(ui): remove dead Mission Control monitor-pane stack
Auto-seeding of monitor tiles was disabled in 724814f; Mission Control now only shows ConPTY panes. Removes Monitors/EnsureMonitor/SeedActive, the detach/re-dock machinery, MonitorPaneView and the detached monitor window, plus their tests and orphaned localization keys. TaskMonitorViewModel itself stays: DetailsIslandViewModel still uses it as the backing state for the task Log/AgentState/AskUser-question UI, so only its Mission-Control-only members (Title/DisplayTitle, detach, cancel command, IMissionControlPane) were stripped. IMissionControlPane/Panes were kept (now a 1:1 mirror of ConPtySessions) rather than dissolved, to avoid churning the still-live ConPTY pane tests and AXAML for a single-implementer interface. Visual verification still open: Mission Control with several open ConPTY tiles, and the Focus/Overview toggle.
This commit is contained in:
@@ -81,8 +81,7 @@
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Question prompt (AskUser): answer the running task's question inline, mirroring
|
||||
the Mission Control banner. State is shared via the same TaskMonitorViewModel. -->
|
||||
<!-- Question prompt (AskUser): answer the running task's question inline. -->
|
||||
<Border DockPanel.Dock="Top"
|
||||
IsVisible="{Binding Monitor.HasPendingQuestion}"
|
||||
Margin="0,0,0,10" Padding="12,8"
|
||||
|
||||
@@ -1,24 +1,17 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:ClaudeDo.Ui.ViewModels"
|
||||
xmlns:vmi="using:ClaudeDo.Ui.ViewModels.Islands"
|
||||
xmlns:vmm="using:ClaudeDo.Ui.ViewModels.MissionControl"
|
||||
xmlns:mc="using:ClaudeDo.Ui.Views.MissionControl"
|
||||
xmlns:loc="using:ClaudeDo.Ui.Localization"
|
||||
x:DataType="vm:MissionControlViewModel"
|
||||
x:Class="ClaudeDo.Ui.Views.MissionControl.MissionControlView">
|
||||
<UserControl.DataTemplates>
|
||||
<!-- Polymorphic pane templates: both the grid ItemsControl and the focus-mode TabControl
|
||||
resolve per-item content through these (no explicit ItemTemplate on either). -->
|
||||
<DataTemplate DataType="vmi:TaskMonitorViewModel">
|
||||
<mc:MonitorPaneView Margin="6" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="vmm:ConPtyPaneViewModel">
|
||||
<mc:ConPtyPaneView Margin="6" />
|
||||
</DataTemplate>
|
||||
</UserControl.DataTemplates>
|
||||
<DockPanel LastChildFill="True" Background="{DynamicResource VoidBrush}"
|
||||
DragDrop.AllowDrop="True">
|
||||
<DockPanel LastChildFill="True" Background="{DynamicResource VoidBrush}">
|
||||
|
||||
<!-- Header -->
|
||||
<Border DockPanel.Dock="Top"
|
||||
@@ -50,9 +43,6 @@
|
||||
<PathIcon Data="{StaticResource Icon.Settings}" Width="15" Height="15"
|
||||
Foreground="{DynamicResource TextMuteBrush}"/>
|
||||
</Button>
|
||||
<Button Classes="btn"
|
||||
Content="{loc:Tr missionControl.clearFinished}"
|
||||
Command="{Binding ClearFinishedCommand}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -1,25 +1,15 @@
|
||||
using System.Linq;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.VisualTree;
|
||||
using ClaudeDo.Ui.ViewModels;
|
||||
using ClaudeDo.Ui.ViewModels.Islands;
|
||||
|
||||
namespace ClaudeDo.Ui.Views.MissionControl;
|
||||
|
||||
public partial class MissionControlView : UserControl
|
||||
{
|
||||
// Shared with MonitorPaneView (the drag source).
|
||||
public static readonly DataFormat<string> PaneFormat =
|
||||
DataFormat.CreateStringApplicationFormat("claudedo-monitor-pane");
|
||||
|
||||
public MissionControlView()
|
||||
{
|
||||
InitializeComponent();
|
||||
AddHandler(DragDrop.DragOverEvent, OnPaneDragOver);
|
||||
AddHandler(DragDrop.DropEvent, OnPaneDrop);
|
||||
}
|
||||
|
||||
// Ad-hoc ConPTY session: the view owns the folder picker, the VM only takes the chosen path.
|
||||
@@ -38,31 +28,4 @@ public partial class MissionControlView : UserControl
|
||||
|
||||
await vm.OpenAdHocConPtySessionAsync(folders[0].Path.LocalPath);
|
||||
}
|
||||
|
||||
private void OnPaneDragOver(object? sender, DragEventArgs e)
|
||||
{
|
||||
var dt = e.DataTransfer;
|
||||
e.DragEffects = (dt?.Contains(PaneFormat) ?? false) ? DragDropEffects.Move : DragDropEffects.None;
|
||||
}
|
||||
|
||||
private void OnPaneDrop(object? sender, DragEventArgs e)
|
||||
{
|
||||
if (DataContext is not MissionControlViewModel vm) return;
|
||||
var dt = e.DataTransfer;
|
||||
if (dt is null) return;
|
||||
|
||||
// A pane dragged within the grid → reorder. (Drag-to-queue from the main app now arrives
|
||||
// via the custom ghost drag's screen hit-test, not an OLE drop.)
|
||||
var draggedId = dt.TryGetValue(PaneFormat);
|
||||
if (string.IsNullOrEmpty(draggedId)) return;
|
||||
if (e.Source is not Avalonia.Visual src) return;
|
||||
|
||||
var targetPane = src.FindAncestorOfType<MonitorPaneView>();
|
||||
if (targetPane?.DataContext is not TaskMonitorViewModel target) return;
|
||||
|
||||
var dragged = vm.Monitors.FirstOrDefault(m => m.SubscribedTaskId == draggedId);
|
||||
if (dragged is null) return;
|
||||
|
||||
vm.MoveMonitor(dragged, target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
<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:loc="using:ClaudeDo.Ui.Localization"
|
||||
x:DataType="vm:TaskMonitorViewModel"
|
||||
x:Class="ClaudeDo.Ui.Views.MissionControl.MonitorPaneView">
|
||||
<Border Classes="monitor-pane"
|
||||
DragDrop.AllowDrop="True"
|
||||
Classes.mon-review="{Binding IsWaitingForReview}"
|
||||
Classes.mon-done="{Binding IsDone}"
|
||||
Classes.mon-roadblock="{Binding HasRoadblock}"
|
||||
Classes.mon-failed="{Binding IsFailed}"
|
||||
BorderThickness="1" CornerRadius="10" ClipToBounds="True">
|
||||
<DockPanel LastChildFill="True">
|
||||
|
||||
<!-- Header: per-task action icons -->
|
||||
<Border DockPanel.Dock="Top"
|
||||
Background="{DynamicResource Surface2Brush}"
|
||||
BorderBrush="{DynamicResource LineBrush}"
|
||||
BorderThickness="0,0,0,1" Padding="6,3"
|
||||
PointerPressed="OnHeaderPressed">
|
||||
<StackPanel Orientation="Horizontal" Spacing="2"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center">
|
||||
<Button Classes="title-ctrl"
|
||||
Command="{Binding OpenInAppCommand}"
|
||||
ToolTip.Tip="{loc:Tr missionControl.openInApp}">
|
||||
<PathIcon Data="{StaticResource Icon.ArrowOut}" Width="12" Height="12"/>
|
||||
</Button>
|
||||
<Button Classes="title-ctrl"
|
||||
Command="{Binding DetachCommand}"
|
||||
ToolTip.Tip="{Binding DetachTooltip}">
|
||||
<PathIcon Data="{StaticResource Icon.WinMax}" Width="12" Height="12"/>
|
||||
</Button>
|
||||
<Button Classes="title-ctrl"
|
||||
Command="{Binding CancelTaskCommand}"
|
||||
IsVisible="{Binding IsRunning}"
|
||||
ToolTip.Tip="{loc:Tr missionControl.cancel}">
|
||||
<PathIcon Data="{StaticResource Icon.WinClose}" Width="12" Height="12"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Roadblock banner (amber) -->
|
||||
<Border DockPanel.Dock="Top"
|
||||
IsVisible="{Binding HasRoadblock}"
|
||||
Background="{DynamicResource RoadblockTintBrush}"
|
||||
BorderBrush="{DynamicResource AmberBrush}"
|
||||
BorderThickness="0,0,0,1" Padding="12,6">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<PathIcon Data="{StaticResource Icon.Warning}"
|
||||
Foreground="{DynamicResource AmberBrush}"
|
||||
Width="13" Height="13" VerticalAlignment="Center" />
|
||||
<TextBlock Classes="meta" Text="{Binding Roadblocks}"
|
||||
Foreground="{DynamicResource AmberBrush}"
|
||||
TextWrapping="Wrap" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Failure banner (red) -->
|
||||
<Border DockPanel.Dock="Top"
|
||||
IsVisible="{Binding ShowRoadblock}"
|
||||
Background="{DynamicResource ErrorTintBrush}"
|
||||
BorderBrush="{DynamicResource BloodBrush}"
|
||||
BorderThickness="0,0,0,1" Padding="12,6">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<PathIcon Data="{StaticResource Icon.Warning}"
|
||||
Foreground="{DynamicResource BloodBrush}"
|
||||
Width="13" Height="13" VerticalAlignment="Center" />
|
||||
<TextBlock Classes="meta" Text="{Binding RoadblockMessage}"
|
||||
Foreground="{DynamicResource BloodBrush}"
|
||||
TextWrapping="Wrap" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Question prompt (AskUser): answer a running task's question inline -->
|
||||
<Border DockPanel.Dock="Top"
|
||||
IsVisible="{Binding HasPendingQuestion}"
|
||||
Background="{DynamicResource AccentSoftBrush}"
|
||||
BorderBrush="{DynamicResource AccentBrush}"
|
||||
BorderThickness="0,0,0,1" Padding="12,8">
|
||||
<StackPanel Spacing="6">
|
||||
<TextBlock Classes="meta"
|
||||
Text="{loc:Tr missionControl.question.title}"
|
||||
Foreground="{DynamicResource AccentBrush}" FontWeight="SemiBold" />
|
||||
<TextBlock Text="{Binding PendingQuestion}" TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource TextBrush}" />
|
||||
<Grid ColumnDefinitions="*,Auto" ColumnSpacing="6">
|
||||
<TextBox Grid.Column="0"
|
||||
Text="{Binding AnswerDraft, UpdateSourceTrigger=PropertyChanged}"
|
||||
PlaceholderText="{loc:Tr missionControl.question.placeholder}"
|
||||
AcceptsReturn="False">
|
||||
<TextBox.KeyBindings>
|
||||
<KeyBinding Gesture="Enter" Command="{Binding SubmitAnswerCommand}" />
|
||||
</TextBox.KeyBindings>
|
||||
</TextBox>
|
||||
<Button Grid.Column="1"
|
||||
Content="{loc:Tr missionControl.question.send}"
|
||||
Command="{Binding SubmitAnswerCommand}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Console body: reuse SessionTerminalView -->
|
||||
<islands:SessionTerminalView
|
||||
Entries="{Binding Log}"
|
||||
Label="{Binding DisplayTitle}"
|
||||
IsRunning="{Binding IsRunning}"
|
||||
IsDone="{Binding IsDone}"
|
||||
IsFailed="{Binding IsFailed}" />
|
||||
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -1,26 +0,0 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.VisualTree;
|
||||
using ClaudeDo.Ui.ViewModels.Islands;
|
||||
|
||||
namespace ClaudeDo.Ui.Views.MissionControl;
|
||||
|
||||
public partial class MonitorPaneView : UserControl
|
||||
{
|
||||
public MonitorPaneView() => InitializeComponent();
|
||||
|
||||
private async void OnHeaderPressed(object? sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (DataContext is not TaskMonitorViewModel m || m.SubscribedTaskId is not { } id) return;
|
||||
if (e.Source is not Avalonia.Visual src) return;
|
||||
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return;
|
||||
|
||||
// Don't start a drag when the press landed on a header action button.
|
||||
var button = src as Button ?? src.FindAncestorOfType<Button>();
|
||||
if (button is not null) return;
|
||||
|
||||
var data = new DataTransfer();
|
||||
data.Add(DataTransferItem.Create(MissionControlView.PaneFormat, id));
|
||||
await DragDrop.DoDragDropAsync(e, data, DragDropEffects.Move);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:ClaudeDo.Ui.ViewModels.Islands"
|
||||
xmlns:mc="using:ClaudeDo.Ui.Views.MissionControl"
|
||||
x:Class="ClaudeDo.Ui.Views.MissionControl.TaskMonitorWindow"
|
||||
x:DataType="vm:TaskMonitorViewModel"
|
||||
Title="{Binding DisplayTitle}"
|
||||
Width="560" Height="620" MinWidth="360" MinHeight="320"
|
||||
Background="{DynamicResource VoidBrush}"
|
||||
Icon="avares://ClaudeDo.Ui/Assets/ClaudeTask.ico">
|
||||
<mc:MonitorPaneView />
|
||||
</Window>
|
||||
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace ClaudeDo.Ui.Views.MissionControl;
|
||||
|
||||
public partial class TaskMonitorWindow : Window
|
||||
{
|
||||
public TaskMonitorWindow() => InitializeComponent();
|
||||
|
||||
protected override void OnOpened(EventArgs e)
|
||||
{
|
||||
base.OnOpened(e);
|
||||
if (DataContext is ClaudeDo.Ui.ViewModels.Islands.TaskMonitorViewModel vm)
|
||||
vm.CloseWindowRequested = Close;
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
if (DataContext is ClaudeDo.Ui.ViewModels.Islands.TaskMonitorViewModel vm)
|
||||
vm.CloseWindowRequested = null;
|
||||
base.OnClosed(e);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ using Avalonia.Media;
|
||||
using ClaudeDo.Ui.Services;
|
||||
using ClaudeDo.Ui.ViewModels;
|
||||
using ClaudeDo.Ui.ViewModels.Conflicts;
|
||||
using ClaudeDo.Ui.ViewModels.Islands;
|
||||
using ClaudeDo.Ui.ViewModels.Modals;
|
||||
using ClaudeDo.Ui.Views.Conflicts;
|
||||
using ClaudeDo.Ui.Views.MissionControl;
|
||||
@@ -146,13 +145,6 @@ public sealed class WindowDialogService : IDialogService
|
||||
_missionControl.Activate(); // bring to front / focus
|
||||
}
|
||||
|
||||
public void ShowDetachedMonitor(TaskMonitorViewModel monitor, Action onClosed)
|
||||
{
|
||||
var win = new TaskMonitorWindow { DataContext = monitor };
|
||||
win.Closed += (_, _) => onClosed(); // closing re-docks into the grid
|
||||
win.Show(); // modeless, independent
|
||||
}
|
||||
|
||||
public Task<bool> ConfirmAsync(string message)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
|
||||
Reference in New Issue
Block a user