Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit a3d95c4

Browse files
committed
Hook up commands and validator, tweak creation
1 parent 48feb0b commit a3d95c4

File tree

9 files changed

+124
-35
lines changed

9 files changed

+124
-35
lines changed

src/GitHub.App/SampleData/PullRequestCreationViewModelDesigner.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
using GitHub.ViewModels;
33
using System.Collections.Generic;
44
using GitHub.Models;
5+
using GitHub.Validation;
6+
using System;
7+
using System.Windows.Input;
58

69
namespace GitHub.SampleData
710
{
@@ -35,5 +38,13 @@ public PullRequestCreationViewModelDesigner()
3538

3639
public string SelectedAssignee { get; set; }
3740
public List<string> Users { get; set; }
41+
42+
public ICommand CreatePullRequest { get; }
43+
44+
public string PRTitle { get; set; }
45+
46+
public ReactivePropertyValidator TitleValidator { get; }
47+
48+
public ReactivePropertyValidator BranchValidator { get; }
3849
}
3950
}

src/GitHub.App/Services/ModelService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,15 @@ public ITrackingCollection<IRepositoryModel> GetRepositories(ITrackingCollection
199199
return collection;
200200
}
201201

202-
public IObservable<IPullRequestModel> CreatePullRequest(IPullRequestModel pr, ISimpleRepositoryModel repository)
202+
public IObservable<IPullRequestModel> CreatePullRequest(ISimpleRepositoryModel repository, string title, IBranch source, IBranch target)
203203
{
204204
var keyobs = GetUserFromCache()
205205
.Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, user.Login, repository.Name));
206206

207207
return Observable.Defer(() => keyobs
208208
.SelectMany(key =>
209209
hostCache.PutAndUpdateIndex(key, () =>
210-
apiClient.CreatePullRequest(new NewPullRequest(pr.Title, pr.Head.Name, pr.Base.Name),
210+
apiClient.CreatePullRequest(new NewPullRequest(title, source.Name, target.Name),
211211
repository.CloneUrl.Owner,
212212
repository.CloneUrl.RepositoryName)
213213
.Select(PullRequestCacheItem.Create),

src/GitHub.App/Services/PullRequestService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ namespace GitHub.Services
88
[PartCreationPolicy(CreationPolicy.Shared)]
99
public class PullRequestService : IPullRequestService
1010
{
11-
public IObservable<IPullRequestModel> CreatePullRequest(IRepositoryHost host, ISimpleRepositoryModel repository, IPullRequestModel pullRequest)
11+
public IObservable<IPullRequestModel> CreatePullRequest(IRepositoryHost host, ISimpleRepositoryModel repository, string title, IBranch source, IBranch target)
1212
{
13-
return host.ModelService.CreatePullRequest(pullRequest, repository);
13+
return host.ModelService.CreatePullRequest(repository, title, source, target);
1414
}
1515
}
1616
}

src/GitHub.App/ViewModels/PullRequestCreationViewModel.cs

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
using GitHub.Extensions.Reactive;
1111
using GitHub.UI;
1212
using System.Linq;
13+
using System.Windows.Input;
14+
using GitHub.Validation;
15+
using GitHub.Extensions;
1316

1417
namespace GitHub.ViewModels
1518
{
@@ -19,11 +22,12 @@ public class PullRequestCreationViewModel : BaseViewModel, IPullRequestCreationV
1922
{
2023
[ImportingConstructor]
2124
PullRequestCreationViewModel(
22-
IConnectionRepositoryHostMap connectionRepositoryHostMap, ITeamExplorerServiceHolder teservice)
23-
: this(connectionRepositoryHostMap.CurrentRepositoryHost, teservice.ActiveRepo)
25+
IConnectionRepositoryHostMap connectionRepositoryHostMap, ITeamExplorerServiceHolder teservice,
26+
IPullRequestService service)
27+
: this(connectionRepositoryHostMap.CurrentRepositoryHost, teservice.ActiveRepo, service)
2428
{}
2529

26-
public PullRequestCreationViewModel(IRepositoryHost repositoryHost, ISimpleRepositoryModel activeRepo)
30+
public PullRequestCreationViewModel(IRepositoryHost repositoryHost, ISimpleRepositoryModel activeRepo, IPullRequestService service)
2731
{
2832
repositoryHost.ModelService.GetBranches(activeRepo)
2933
.ToReadOnlyList()
@@ -35,6 +39,32 @@ public PullRequestCreationViewModel(IRepositoryHost repositoryHost, ISimpleRepos
3539

3640
// what do we do if there's no master?
3741
TargetBranch = new BranchModel { Name = "master" };
42+
var titleObs = this.WhenAny(x => x.PRTitle, x => x.Value).WhereNotNull();
43+
TitleValidator = ReactivePropertyValidator.ForObservable(titleObs)
44+
.IfNullOrEmpty("Please enter a title for the Pull Request");
45+
46+
var branchObs = this.WhenAny(
47+
x => x.SourceBranch,
48+
x => x.TargetBranch,
49+
(source, target) => source.Value.Name == target.Value.Name);
50+
51+
BranchValidator = ReactivePropertyValidator.ForObservable(branchObs)
52+
.IfTrue(x => x, "Source and target branch cannot be the same");
53+
54+
var whenAnyValidationResultChanges = this.WhenAny(
55+
x => x.TitleValidator.ValidationResult.IsValid,
56+
x => x.BranchValidator.ValidationResult.IsValid,
57+
(x, y) => x.Value && y.Value);
58+
59+
createPullRequest = ReactiveCommand.CreateAsyncObservable(whenAnyValidationResultChanges,
60+
_ => service.CreatePullRequest(repositoryHost, activeRepo, PRTitle, SourceBranch, TargetBranch)
61+
);
62+
createPullRequest.ThrownExceptions.Subscribe(ex =>
63+
{
64+
if (!ex.IsCriticalException())
65+
{
66+
}
67+
});
3868
}
3969

4070
IBranch targetBranch;
@@ -57,5 +87,29 @@ public IReadOnlyList<IBranch> Branches
5787
get { return branches; }
5888
set { this.RaiseAndSetIfChanged(ref branches, value); }
5989
}
90+
91+
IReactiveCommand createPullRequest;
92+
public ICommand CreatePullRequest => createPullRequest;
93+
94+
string title;
95+
public string PRTitle
96+
{
97+
get { return title; }
98+
set { this.RaiseAndSetIfChanged(ref title, value); }
99+
}
100+
101+
ReactivePropertyValidator titleValidator;
102+
public ReactivePropertyValidator TitleValidator
103+
{
104+
get { return titleValidator; }
105+
private set { this.RaiseAndSetIfChanged(ref titleValidator, value); }
106+
}
107+
108+
ReactivePropertyValidator branchValidator;
109+
public ReactivePropertyValidator BranchValidator
110+
{
111+
get { return branchValidator; }
112+
private set { this.RaiseAndSetIfChanged(ref branchValidator, value); }
113+
}
60114
}
61115
}

src/GitHub.Exports.Reactive/Services/IModelService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public interface IModelService : IDisposable
2020
IObservable<LicenseItem> GetLicenses();
2121
IObservable<GitIgnoreItem> GetGitIgnoreTemplates();
2222
ITrackingCollection<IPullRequestModel> GetPullRequests(ISimpleRepositoryModel repo, ITrackingCollection<IPullRequestModel> collection);
23-
IObservable<IPullRequestModel> CreatePullRequest(IPullRequestModel pr, ISimpleRepositoryModel repository);
23+
IObservable<IPullRequestModel> CreatePullRequest(ISimpleRepositoryModel repository, string title, IBranch source, IBranch target);
2424
IObservable<IBranch> GetBranches(ISimpleRepositoryModel repo);
2525
IObservable<Unit> InvalidateAll();
2626
}

src/GitHub.Exports.Reactive/Services/IPullRequestService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ namespace GitHub.Services
1010
{
1111
public interface IPullRequestService
1212
{
13-
IObservable<IPullRequestModel> CreatePullRequest(IRepositoryHost host, ISimpleRepositoryModel repository, IPullRequestModel pullRequest);
13+
IObservable<IPullRequestModel> CreatePullRequest(IRepositoryHost host, ISimpleRepositoryModel repository, string title, IBranch source, IBranch target);
1414
}
1515
}

src/GitHub.Exports.Reactive/ViewModels/IPullRequestCreationViewModel.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using GitHub.Models;
22
using GitHub.UI;
33
using System.Collections.Generic;
4+
using System.Windows.Input;
5+
using GitHub.Validation;
46

57
namespace GitHub.ViewModels
68
{
@@ -9,5 +11,9 @@ public interface IPullRequestCreationViewModel : IReactiveViewModel
911
IBranch SourceBranch { get; set; }
1012
IBranch TargetBranch { get; set; }
1113
IReadOnlyList<IBranch> Branches { get; }
14+
ICommand CreatePullRequest { get; }
15+
string PRTitle { get; set; }
16+
ReactivePropertyValidator TitleValidator { get; }
17+
ReactivePropertyValidator BranchValidator { get; }
1218
}
1319
}

src/GitHub.VisualStudio/UI/Views/PullRequestCreationView.xaml

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
99
xmlns:sampleData="clr-namespace:GitHub.SampleData;assembly=GitHub.App"
1010
xmlns:ui="clr-namespace:GitHub.UI;assembly=GitHub.UI"
11+
xmlns:uirx="clr-namespace:GitHub.UI;assembly=GitHub.UI.Reactive"
1112
xmlns:vsui="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.14.0"
1213
d:DesignHeight="450"
1314
d:DesignWidth="300"
@@ -85,6 +86,29 @@
8586
<ColumnDefinition Width="*" />
8687
</Grid.ColumnDefinitions>
8788

89+
<Popup x:Name="branchPopup"
90+
AllowsTransparency="True"
91+
Placement="Bottom"
92+
PlacementTarget="{Binding ElementName=branchSelection}"
93+
StaysOpen="False">
94+
<Border Style="{DynamicResource GitHubComboBoxBorder}">
95+
<DockPanel Width="100" Style="{DynamicResource GitHubComboBoxDockPanelContainer}">
96+
<ListBox x:Name="branches"
97+
DisplayMemberPath="Name"
98+
DockPanel.Dock="Top"
99+
ItemsSource="{Binding Branches}"
100+
SelectedItem="{Binding SourceBranch}"
101+
Style="{DynamicResource GitHubPopupThing}">
102+
<i:Interaction.Triggers>
103+
<i:EventTrigger EventName="SelectionChanged">
104+
<ui:ClosePopupAction TargetName="branchPopup" />
105+
</i:EventTrigger>
106+
</i:Interaction.Triggers>
107+
</ListBox>
108+
</DockPanel>
109+
</Border>
110+
</Popup>
111+
88112
<StackPanel Grid.Column="0" Orientation="Horizontal">
89113
<ui:OcticonImage Foreground="{DynamicResource GitHubVsGrayText}" Icon="git_branch" />
90114
<ui:GitHubActionLink x:Name="branchSelectionButton"
@@ -101,10 +125,11 @@
101125
<TextBlock Foreground="{DynamicResource GitHubVsGrayText}" Text="{Binding TargetBranch}" />
102126
</StackPanel>
103127

104-
<ui:GitHubActionLink Grid.Column="1" x:Name="branchSelection"
128+
<ui:GitHubActionLink x:Name="sourceBranch"
129+
Grid.Column="1"
105130
Margin="5,0"
106131
VerticalAlignment="Center"
107-
Content="{Binding SelectedBranch.Name}"
132+
Content="{Binding SourceBranch.Name}"
108133
HasDropDown="True"
109134
ToolTip="Select a branch">
110135
<i:Interaction.Triggers>
@@ -113,31 +138,14 @@
113138
</i:EventTrigger>
114139
</i:Interaction.Triggers>
115140
</ui:GitHubActionLink>
141+
</Grid>
116142

117-
<Popup x:Name="branchPopup"
118-
AllowsTransparency="True"
119-
Placement="Bottom"
120-
PlacementTarget="{Binding ElementName=branchSelection}"
121-
StaysOpen="False">
122-
<Border Style="{DynamicResource GitHubComboBoxBorder}">
123-
<DockPanel Width="100" Style="{DynamicResource GitHubComboBoxDockPanelContainer}">
124-
<ListBox x:Name="branches"
125-
DockPanel.Dock="Top"
126-
ItemsSource="{Binding Branches}"
127-
DisplayMemberPath="Name"
128-
SelectedItem="{Binding SelectedBranch}"
129-
Style="{DynamicResource GitHubPopupThing}">
130-
<i:Interaction.Triggers>
131-
<i:EventTrigger EventName="SelectionChanged">
132-
<ui:ClosePopupAction TargetName="branchPopup" />
133-
</i:EventTrigger>
134-
</i:Interaction.Triggers>
135-
</ListBox>
136-
</DockPanel>
137-
</Border>
138-
</Popup>
143+
<uirx:ValidationMessage x:Name="branchValidationMessage"
144+
DockPanel.Dock="Bottom"
145+
Fill="{StaticResource GitHubWarningBrush}"
146+
Icon="alert"
147+
ValidatesControl="{Binding ElementName=sourceBranch}" />
139148

140-
</Grid>
141149
</DockPanel>
142150

143151
<TabControl Grid.Row="1"
@@ -146,9 +154,16 @@
146154
<TabItem Header="Details" Style="{DynamicResource GitHubPRDetailsTabItem}">
147155
<ScrollViewer VerticalScrollBarVisibility="Auto">
148156
<StackPanel Orientation="Vertical">
149-
<ui:PromptTextBox Margin="10,5"
157+
<ui:PromptTextBox x:Name="title" Margin="10,5"
150158
PromptText="Title"
151159
Style="{DynamicResource GitHubVsPromptTextBox}" />
160+
161+
<uirx:ValidationMessage x:Name="titleValidationMessage"
162+
DockPanel.Dock="Bottom"
163+
Fill="{StaticResource GitHubWarningBrush}"
164+
Icon="alert"
165+
ValidatesControl="{Binding ElementName=title}" />
166+
152167
<ui:PromptTextBox Height="100"
153168
Margin="10,5"
154169
AcceptsReturn="True"
@@ -325,6 +340,7 @@
325340
<Button Grid.Column="1"
326341
Margin="6,0,0,0"
327342
HorizontalAlignment="Right"
343+
Command="{Binding CreatePullRequest}"
328344
Content="Create pull request"
329345
Style="{StaticResource GitHubVsPrimaryActionButton}" />
330346
</Grid>

src/GitHub.VisualStudio/UI/Views/PullRequestCreationView.xaml.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public PullRequestCreationView()
2121

2222
this.WhenActivated(d =>
2323
{
24+
d(this.OneWayBind(ViewModel, vm => vm.BranchValidator, v => v.branchValidationMessage.ReactiveValidator));
25+
d(this.OneWayBind(ViewModel, vm => vm.TitleValidator, v => v.titleValidationMessage.ReactiveValidator));
2426
d(ViewModel.CancelCommand.Subscribe(_ => NotifyCancel()));
2527
});
2628
}

0 commit comments

Comments
 (0)