feat(ui): detach a monitor into its own window
This commit is contained in:
@@ -142,6 +142,12 @@ public sealed partial class TaskMonitorViewModel : ViewModelBase, IDisposable
|
||||
// Set by the host (e.g. Mission Control) to navigate the main app to this task.
|
||||
public Action<string>? OpenInAppRequested { get; set; }
|
||||
|
||||
// Set by the host (Mission Control) to pop this monitor out into its own window.
|
||||
public Action<TaskMonitorViewModel>? DetachRequested { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private void Detach() => DetachRequested?.Invoke(this);
|
||||
|
||||
[RelayCommand]
|
||||
private void OpenInApp()
|
||||
{
|
||||
|
||||
@@ -213,6 +213,7 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
|
||||
Lists = lists; Tasks = tasks; Details = details; Worker = worker;
|
||||
MissionControl = missionControl;
|
||||
MissionControl.OpenInApp = id => _ = RevealTaskAsync(id);
|
||||
MissionControl.ShowDetached = (monitor, reDock) => Dialogs?.ShowDetachedMonitor(monitor, reDock);
|
||||
_updateCheck = updateCheck;
|
||||
_installerLocator = installerLocator;
|
||||
_workerLocator = workerLocator;
|
||||
|
||||
@@ -33,6 +33,10 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
// View-layer seam: show a detached monitor in its own window. Second arg is the re-dock callback
|
||||
// invoked when that window closes.
|
||||
public Action<TaskMonitorViewModel, Action>? ShowDetached { get; set; }
|
||||
|
||||
public bool HasMonitors => Monitors.Count > 0;
|
||||
|
||||
public MissionControlViewModel(IDbContextFactory<ClaudeDoDbContext> dbFactory, IWorkerClient worker)
|
||||
@@ -65,10 +69,24 @@ public sealed partial class MissionControlViewModel : ViewModelBase, IDisposable
|
||||
var monitor = new TaskMonitorViewModel(_dbFactory, _worker);
|
||||
monitor.SetTaskId(taskId);
|
||||
monitor.OpenInAppRequested = _openInApp;
|
||||
monitor.DetachRequested = Detach;
|
||||
Monitors.Add(monitor);
|
||||
_ = HydrateAsync(monitor, taskId);
|
||||
}
|
||||
|
||||
private void Detach(TaskMonitorViewModel monitor)
|
||||
{
|
||||
if (!Monitors.Contains(monitor)) return;
|
||||
Monitors.Remove(monitor); // drop from grid — do NOT dispose; it keeps streaming
|
||||
ShowDetached?.Invoke(monitor, () => ReDock(monitor));
|
||||
}
|
||||
|
||||
private void ReDock(TaskMonitorViewModel monitor)
|
||||
{
|
||||
if (!Monitors.Contains(monitor) && monitor.SubscribedTaskId is not null)
|
||||
Monitors.Add(monitor); // back into the grid
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task HydrateAsync(TaskMonitorViewModel monitor, string taskId)
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user