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

Commit 1fb69b1

Browse files
committed
Display progress of enterprise probe.
Added an `IconContent` property to `PromptTextBox` to display an icon on the right-hand-side of the textbox. In this area, display the status of the enterprise probe when trying to log in.
1 parent b2a6db5 commit 1fb69b1

File tree

6 files changed

+90
-24
lines changed

6 files changed

+90
-24
lines changed

src/GitHub.App/ViewModels/Dialog/LoginToGitHubForEnterpriseViewModel.cs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ public string EnterpriseUrl
8484
set { this.RaiseAndSetIfChanged(ref enterpriseUrl, value); }
8585
}
8686

87-
bool? isEnterpriseInstance;
88-
public bool? IsEnterpriseInstance
87+
EnterpriseProbeStatus probeStatus;
88+
public EnterpriseProbeStatus ProbeStatus
8989
{
90-
get { return isEnterpriseInstance; }
91-
private set { this.RaiseAndSetIfChanged(ref isEnterpriseInstance, value); }
90+
get { return probeStatus; }
91+
private set { this.RaiseAndSetIfChanged(ref probeStatus, value); }
9292
}
9393

9494
bool? supportsUserNameAndPassword;
@@ -115,33 +115,38 @@ protected override async Task ResetValidation()
115115

116116
async void EnterpriseUrlChanged(string url, bool valid)
117117
{
118+
if (!valid)
119+
{
120+
// The EnterpriseUrlValidator will display an adorner in this case so don't show anything.
121+
ProbeStatus = EnterpriseProbeStatus.None;
122+
return;
123+
}
124+
118125
var enterpriseInstance = false;
119126
var passwordAuth = (bool?)null;
120127

121128
try
122129
{
123-
if (!string.IsNullOrWhiteSpace(url) && valid)
124-
{
125-
IsEnterpriseInstance = SupportsUserNameAndPassword = null;
130+
ProbeStatus = EnterpriseProbeStatus.Checking;
131+
SupportsUserNameAndPassword = null;
126132

127-
if (await enterpriseProbe.Probe(new Uri(url)) == EnterpriseProbeResult.Ok)
128-
{
129-
var client = await apiClientFactory.Create(new UriString(url));
130-
var meta = await client.GetMetadata();
133+
if (await enterpriseProbe.Probe(new Uri(url)) == EnterpriseProbeResult.Ok)
134+
{
135+
var client = await apiClientFactory.Create(new UriString(url));
136+
var meta = await client.GetMetadata();
131137

132-
enterpriseInstance = true;
133-
passwordAuth = meta.VerifiablePasswordAuthentication;
134-
}
138+
enterpriseInstance = true;
139+
passwordAuth = meta.VerifiablePasswordAuthentication;
135140
}
136141
}
137142
catch
138143
{
139-
enterpriseInstance = false;
144+
ProbeStatus = EnterpriseProbeStatus.Invalid;
140145
}
141146

142147
if (url == EnterpriseUrl)
143148
{
144-
IsEnterpriseInstance = enterpriseInstance;
149+
ProbeStatus = enterpriseInstance ? EnterpriseProbeStatus.Valid : EnterpriseProbeStatus.Invalid;
145150
SupportsUserNameAndPassword = passwordAuth;
146151
}
147152
}

src/GitHub.Exports.Reactive/ViewModels/Dialog/ILoginToGitHubForEnterpriseViewModel.cs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,32 @@
44

55
namespace GitHub.ViewModels.Dialog
66
{
7+
/// <summary>
8+
/// Details the possible values for <see cref="ILoginToGitHubForEnterpriseViewModel.ProbeStatus"/>.
9+
/// </summary>
10+
public enum EnterpriseProbeStatus
11+
{
12+
/// <summary>
13+
/// No checking is underway.
14+
/// </summary>
15+
None,
16+
17+
/// <summary>
18+
/// A probe is underway to see if the URL is a valid enterprise instance.
19+
/// </summary>
20+
Checking,
21+
22+
/// <summary>
23+
/// A valid enterprise instance was found.
24+
/// </summary>
25+
Valid,
26+
27+
/// <summary>
28+
/// A valid enterprise instance was not found.
29+
/// </summary>
30+
Invalid
31+
}
32+
733
/// <summary>
834
/// Represents a view model responsible for authenticating a user
935
/// against a GitHub Enterprise instance.
@@ -16,10 +42,9 @@ public interface ILoginToGitHubForEnterpriseViewModel : ILoginToHostViewModel
1642
string EnterpriseUrl { get; set; }
1743

1844
/// <summary>
19-
/// Gets a value indicating whether a GitHub Enterprise instance was found at
20-
/// <see cref="EnterpriseUrl"/>.
45+
/// Gets the status of the enterprise probe.
2146
/// </summary>
22-
bool? IsEnterpriseInstance { get; }
47+
EnterpriseProbeStatus ProbeStatus { get; }
2348

2449
/// <summary>
2550
/// Gets a value indcating whether the GitHub Enterprise instance at <see cref="EnterpriseUrl"/>

src/GitHub.UI/Assets/TextBlocks.xaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@
7272
</Border>
7373

7474
<Grid Margin="1,2,0,0">
75+
<Grid.ColumnDefinitions>
76+
<ColumnDefinition Width="*"/>
77+
<ColumnDefinition Width="Auto"/>
78+
</Grid.ColumnDefinitions>
7579
<ScrollViewer x:Name="PART_ContentHost" Padding="{TemplateBinding Padding}" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" VerticalAlignment="Top" Margin="0"/>
7680
<Label x:Name="PromptLabel" HorizontalAlignment="Left"
7781
Foreground="{DynamicResource GHTextBrush}"
@@ -81,6 +85,10 @@
8185
VerticalAlignment="Top">
8286
<TextBlock Text="{TemplateBinding PromptText}" TextTrimming="CharacterEllipsis" />
8387
</Label>
88+
<ContentControl Grid.Column="1"
89+
Content="{TemplateBinding IconContent}"
90+
ContentTemplate="{TemplateBinding IconContentTemplate}"
91+
Foreground="{TemplateBinding Foreground}"/>
8492
</Grid>
8593
</Grid>
8694

@@ -96,7 +104,6 @@
96104
</Trigger>
97105
<DataTrigger Binding="{Binding Text.Length, RelativeSource={RelativeSource Self}}" Value="0">
98106
<Setter Property="Opacity" TargetName="PromptLabel" Value="0.7" />
99-
<Setter Property="Foreground" Value="Transparent" />
100107
</DataTrigger>
101108
</ControlTemplate.Triggers>
102109

src/GitHub.UI/Controls/PromptTextBox.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,24 @@ namespace GitHub.UI
66
{
77
public class PromptTextBox : TextBox, IShortcutContainer
88
{
9+
public static readonly DependencyProperty IconContentProperty =
10+
DependencyProperty.RegisterAttached(nameof(IconContent), typeof(object), typeof(PromptTextBox));
11+
public static readonly DependencyProperty IconContentTemplateProperty =
12+
DependencyProperty.RegisterAttached(nameof(IconContentTemplate), typeof(DataTemplate), typeof(PromptTextBox));
913
public static readonly DependencyProperty PromptTextProperty =
10-
DependencyProperty.Register("PromptText", typeof(string), typeof(PromptTextBox), new UIPropertyMetadata(""));
14+
DependencyProperty.Register(nameof(PromptText), typeof(string), typeof(PromptTextBox), new UIPropertyMetadata(""));
15+
16+
public object IconContent
17+
{
18+
get { return GetValue(IconContentProperty); }
19+
set { SetValue(IconContentProperty, value); }
20+
}
21+
22+
public object IconContentTemplate
23+
{
24+
get { return GetValue(IconContentTemplateProperty); }
25+
set { SetValue(IconContentTemplateProperty, value); }
26+
}
1127

1228
[Localizability(LocalizationCategory.Text)]
1329
[DefaultValue("")]

src/GitHub.VisualStudio/Views/Dialog/LoginCredentialsView.xaml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:ui="clr-namespace:GitHub.UI;assembly=GitHub.UI"
7+
xmlns:uic="clr-namespace:GitHub.UI.Controls;assembly=GitHub.UI"
78
xmlns:uirx="clr-namespace:GitHub.UI;assembly=GitHub.UI.Reactive"
89
xmlns:helpers="clr-namespace:GitHub.Helpers;assembly=GitHub.UI"
910
xmlns:cache="clr-namespace:GitHub.UI.Helpers;assembly=GitHub.UI"
1011
xmlns:prop="clr-namespace:GitHub.VisualStudio.UI;assembly=GitHub.VisualStudio.UI"
1112
xmlns:local="clr-namespace:GitHub.VisualStudio.Views.Dialog"
13+
xmlns:vm="clr-namespace:GitHub.ViewModels.Dialog;assembly=GitHub.Exports.Reactive"
1214
xmlns:automation="clr-namespace:GitHub.UI.TestAutomation;assembly=GitHub.UI"
1315
mc:Ignorable="d"
1416
d:DesignWidth="414"
@@ -151,8 +153,18 @@
151153

152154
<ui:PromptTextBox x:Name="enterpriseUrl"
153155
PromptText="{x:Static prop:Resources.enterpriseUrlPromptText}"
154-
Margin="0,0,0,10"
155-
AutomationProperties.AutomationId="{x:Static automation:AutomationIDs.EnterpriseServerAddressTextBox}" />
156+
Margin="0,0,0,10"
157+
AutomationProperties.AutomationId="{x:Static automation:AutomationIDs.EnterpriseServerAddressTextBox}">
158+
<ui:PromptTextBox.IconContentTemplate>
159+
<DataTemplate DataType="{x:Type vm:EnterpriseProbeStatus}">
160+
<Grid Margin="4,0">
161+
<uic:Spinner Margin="0,4" Visibility="{Binding Converter={ui:EqualsToVisibilityConverter Checking}}"/>
162+
<ui:OcticonImage Icon="check" Visibility="{Binding Converter={ui:EqualsToVisibilityConverter Valid}}"/>
163+
<ui:OcticonImage Icon="x" Visibility="{Binding Converter={ui:EqualsToVisibilityConverter Invalid}}"/>
164+
</Grid>
165+
</DataTemplate>
166+
</ui:PromptTextBox.IconContentTemplate>
167+
</ui:PromptTextBox>
156168

157169
<StackPanel Name="enterpriseValidUrlPanel" Style="{StaticResource FormFieldStackPanel}">
158170
<StackPanel Name="enterpriseUsernamePasswordPanel">

src/GitHub.VisualStudio/Views/Dialog/LoginCredentialsView.xaml.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ void SetupDotComBindings(Action<IDisposable> d)
8989
void SetupEnterpriseBindings(Action<IDisposable> d)
9090
{
9191
d(this.OneWayBind(ViewModel, vm => vm.EnterpriseLogin.IsLoggingIn, x => x.enterpriseloginControlsPanel.IsEnabled, x => x == false));
92-
d(this.OneWayBind(ViewModel, vm => vm.EnterpriseLogin.IsEnterpriseInstance, x => x.enterpriseValidUrlPanel.Visibility, x => x == true ? Visibility.Visible : Visibility.Collapsed));
92+
d(this.OneWayBind(ViewModel, vm => vm.EnterpriseLogin.ProbeStatus, x => x.enterpriseUrl.IconContent));
93+
d(this.OneWayBind(ViewModel, vm => vm.EnterpriseLogin.ProbeStatus, x => x.enterpriseValidUrlPanel.Visibility, x => x == EnterpriseProbeStatus.Valid ? Visibility.Visible : Visibility.Collapsed));
9394
d(this.OneWayBind(ViewModel, vm => vm.EnterpriseLogin.SupportsUserNameAndPassword, x => x.enterpriseUsernamePasswordPanel.Visibility, x => x == true ? Visibility.Visible : Visibility.Collapsed));
9495

9596
d(this.Bind(ViewModel, vm => vm.EnterpriseLogin.UsernameOrEmail, x => x.enterpriseUserNameOrEmail.Text));

0 commit comments

Comments
 (0)