feat(ui): expose conflict-resolver factory and dialog seam for integrator

This commit is contained in:
mika kuns
2026-06-05 11:00:37 +02:00
parent 8cafad370e
commit 72687e9b30
3 changed files with 29 additions and 1 deletions

View File

@@ -132,6 +132,9 @@ sealed class Program
sc.AddTransient<Func<RepoImportModalViewModel>>(sp => () => sp.GetRequiredService<RepoImportModalViewModel>()); sc.AddTransient<Func<RepoImportModalViewModel>>(sp => () => sp.GetRequiredService<RepoImportModalViewModel>());
sc.AddTransient<WeeklyReportModalViewModel>(); sc.AddTransient<WeeklyReportModalViewModel>();
sc.AddTransient<Func<WeeklyReportModalViewModel>>(sp => () => sp.GetRequiredService<WeeklyReportModalViewModel>()); sc.AddTransient<Func<WeeklyReportModalViewModel>>(sp => () => sp.GetRequiredService<WeeklyReportModalViewModel>());
sc.AddSingleton<Func<string, ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel>>(sp =>
taskId => new ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel(
sp.GetRequiredService<WorkerClient>(), taskId));
// Islands shell VMs // Islands shell VMs
sc.AddSingleton<ListsIslandViewModel>(sp => sc.AddSingleton<ListsIslandViewModel>(sp =>
@@ -149,7 +152,13 @@ sealed class Program
sp.GetRequiredService<WorkerClient>(), sp.GetRequiredService<WorkerClient>(),
sp, sp,
sp.GetRequiredService<INotesApi>())); sp.GetRequiredService<INotesApi>()));
sc.AddSingleton<IslandsShellViewModel>(); sc.AddSingleton<IslandsShellViewModel>(sp =>
{
var shell = ActivatorUtilities.CreateInstance<IslandsShellViewModel>(sp);
shell.ConflictResolverFactory =
sp.GetRequiredService<Func<string, ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel>>();
return shell;
});
return sc.BuildServiceProvider(); return sc.BuildServiceProvider();
} }

View File

@@ -44,6 +44,20 @@ public sealed partial class IslandsShellViewModel : ViewModelBase
// Set by MainWindow to open the conflict resolution dialog. // Set by MainWindow to open the conflict resolution dialog.
public Func<ConflictResolutionViewModel, Task>? ShowConflictDialog { get; set; } public Func<ConflictResolutionViewModel, Task>? ShowConflictDialog { get; set; }
// Layer C seam: composition root sets the factory; MainWindow sets the dialog opener.
// The integrator connects Layer A/B's RequestConflictResolution(taskId, target) to this method.
public Func<string, ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel>? ConflictResolverFactory { get; set; }
public Func<ClaudeDo.Ui.ViewModels.Conflicts.ConflictResolverViewModel, Task>? ShowConflictResolver { get; set; }
public async Task RequestConflictResolutionAsync(string taskId, string targetBranch)
{
if (ConflictResolverFactory is null || ShowConflictResolver is null) return;
var vm = ConflictResolverFactory(taskId);
var hasConflicts = await vm.OpenAsync(targetBranch);
if (hasConflicts)
await ShowConflictResolver(vm);
}
// Set by MainWindow to open the About dialog. // Set by MainWindow to open the About dialog.
public Func<AboutModalViewModel, Task>? ShowAboutModal { get; set; } public Func<AboutModalViewModel, Task>? ShowAboutModal { get; set; }

View File

@@ -95,6 +95,11 @@ public partial class MainWindow : Window
connVm.CloseAction = () => dlg.Close(); connVm.CloseAction = () => dlg.Close();
await dlg.ShowDialog(this); await dlg.ShowDialog(this);
}; };
vm.ShowConflictResolver = async (resolverVm) =>
{
var dlg = new ClaudeDo.Ui.Views.Conflicts.ConflictResolverView { DataContext = resolverVm };
await dlg.ShowDialog(this);
};
} }
} }