Skip to content

Commit

Permalink
addRepo improvements (#2298)
Browse files Browse the repository at this point in the history
* USing tags

* Can clone repos again.

* Changing visibility to bool.

* More changes

* Account combobox is reset.

* Adding some comments.

* Combobox placeholder

* Final touches

* Fixing a comment.

* Fixing SDk version

* Ignoring a test

* Update tools/SetupFlow/DevHome.SetupFlow/ViewModels/AddRepoViewModel.cs

Co-authored-by: Kristen Schau <[email protected]>

* Update tools/SetupFlow/DevHome.SetupFlow/ViewModels/AddRepoViewModel.cs

Co-authored-by: Kristen Schau <[email protected]>

* Update tools/SetupFlow/DevHome.SetupFlow/Views/AddRepoDialog.xaml

Co-authored-by: Kristen Schau <[email protected]>

* Changes

* Removing prefixes for uid

* Moving more things into the ViewModel.

* Getting loginUI and provider name not null.

* Ignoring anotehr test because making a new frame throws an exception.

* Adding -async

---------

Co-authored-by: Darren Hoehna <[email protected]>
Co-authored-by: Kristen Schau <[email protected]>
  • Loading branch information
3 people committed Mar 4, 2024
1 parent 951b106 commit 28e3043
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 195 deletions.
10 changes: 5 additions & 5 deletions tools/SetupFlow/DevHome.SetupFlow.UnitTest/AddRepoDialogTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ public void SwitchToUrlScreenTest()
[Ignore("IextensionService uses Application.Current and tests break when Application.Current is used. Ignore until fixed.")]
public async Task SwitchToAccountScreenTest()
{
var addRepoViewModel = new AddRepoViewModel(TestHost.GetService<ISetupFlowStringResource>(), new List<CloningInformation>(), TestHost, Guid.NewGuid(), string.Empty, null);
addRepoViewModel.ChangeToRepoPage(new());
Assert.AreEqual(Visibility.Collapsed, addRepoViewModel.ShowUrlPage);
Assert.AreEqual(Visibility.Collapsed, addRepoViewModel.ShowAccountPage);
Assert.AreEqual(Visibility.Visible, addRepoViewModel.ShowRepoPage);
var addRepoViewModel = new AddRepoViewModel(TestHost.GetService<ISetupFlowStringResource>(), new List<CloningInformation>(), TestHost, Guid.NewGuid(), null, TestHost.GetService<IDevDriveManager>());
await addRepoViewModel.ChangeToAccountPageAsync();
Assert.AreEqual(false, addRepoViewModel.ShowUrlPage);
Assert.AreEqual(true, addRepoViewModel.ShowAccountPage);
Assert.AreEqual(false, addRepoViewModel.ShowRepoPage);
Assert.IsFalse(addRepoViewModel.ShouldShowLoginUi);
}
}
180 changes: 104 additions & 76 deletions tools/SetupFlow/DevHome.SetupFlow/ViewModels/AddRepoViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,8 @@ public partial class AddRepoViewModel : ObservableObject
private readonly List<CloningInformation> _previouslySelectedRepos;

/// <summary>
/// Holds all the currently executing tasks to GetRepositories.
/// Used to match a Task against _taskToUseForResults to make sure the results of the most recently executed task
/// is shows in the UI.
/// </summary>
private readonly List<Task> _runningGetReposTasks = new();

/// <summary>
/// Because logic is split between the back-end and the view model, incrementally migrating code from the view
/// to the view model is impossible.
/// Because logic is split between the back-end and the view model, migrating code from the view
/// in one PR to the view model is too much work.
/// This member is here to support this partial migration. Once all the code-behind logic is out of the view
/// _addRepoDialog can be removed.
/// </summary>
Expand Down Expand Up @@ -179,13 +172,6 @@ public List<CloningInformation> EverythingToClone
[ObservableProperty]
private bool _showRepoPage;

/// <summary>
/// If the extension implements IRepositoryProvider2 users can navigate to this page
/// allowing users to define a simple search query to narrow down the repos returned from the extension.
/// </summary>
[ObservableProperty]
private bool _shouldShowSelectingSearchTerms;

/// <summary>
/// Should the error text be shown?
/// </summary>
Expand Down Expand Up @@ -268,44 +254,47 @@ public List<CloningInformation> EverythingToClone
private bool _isCancelling;

/// <summary>
/// The remote path to the repo. Example, at a minimum each repo has a path of [server]/[RepoName]
/// Everything before [RepoName] is in this string.
/// Used to figure out what button is pressed for the split button.
/// This determines the UI elements shown/hidden.
/// </summary>
[ObservableProperty]
private string _pathToRepos;

/// <summary>
/// The last path part before [RepoName]. All strings in here will be in a combobox.
/// </summary>
[ObservableProperty]
private ObservableCollection<string> _lastPathPartsList;

[ObservableProperty]
private string _lastPathPartPlaceholderText;
private enum SegmentedItemTag
{
Account,
URL,
}

/// <summary>
/// Don't show the oath selector UI when querying repos and when selecting search terms.
/// Hides/Shows UI elements for the selected button.
/// </summary>
[ObservableProperty]
private bool _shouldShowPathSelector;
/// <param name="selectedItem">The button the user clicked on.</param>
[RelayCommand]
public async Task ChangePage(SegmentedItem selectedItem)
{
if (selectedItem.Tag == null)
{
return;
}

/// <summary>
/// The accounts the user is logged into is stored here.
/// </summary>
[ObservableProperty]
private MenuFlyout _accountsToShow;
if (!Enum.TryParse<SegmentedItemTag>(selectedItem.Tag.ToString(), out var pageToGoTo))
{
return;
}

[ObservableProperty]
private bool _shouldShowPathGrid;
if (pageToGoTo == SegmentedItemTag.Account)
{
await ChangeToAccountPageAsync();
return;
}

[ObservableProperty]
private bool _shouldShowChangePathHyperlinkButton;
if (pageToGoTo == SegmentedItemTag.URL)
{
ChangeToUrlPage();
return;
}

/// <summary>
/// IRepositoryProvider2 supports search queries when fetching repos. Each extension has the option to
/// implement IRepositoryProvider2 or not. this needs to be updated when a provider is selected.
/// </summary>
private bool _isSearchingEnabled;
// enum did not match. Don't change.
return;
}

/// <summary>
/// Indicates if the ListView is currently filtering items. A result of manually filtering a list view
Expand Down Expand Up @@ -384,6 +373,24 @@ private void CancelButtonPressed()
IsCancelling = true;
}

/// <summary>
/// The accounts the user is logged into is stored here.
/// </summary>
[ObservableProperty]
private MenuFlyout _accountsToShow;

/// <summary>
/// Used to show the login UI.
/// </summary>
[ObservableProperty]
private Frame _loginUiContent;

/// <summary>
/// Soley used to reset the account drop down when the account page is navigated to.
/// </summary>
[ObservableProperty]
private int _accountIndex;

/// <summary>
/// Switches the repos shown to the account selected.
/// </summary>
Expand All @@ -401,7 +408,20 @@ private void MenuItemClick(string selectedItemName)
}

[RelayCommand]
private void LastPathPartChanged(string selectedItem)
private async Task OpenFolderPicker()
{
await FolderPickerViewModel.ChooseCloneLocation();
ToggleCloneButton();
}

/// <summary>
/// Makes the MenuFlyout object used to display multple accounts in the repo tool.
/// </summary>
/// <returns>The MenuFlyout to display.</returns>
/// <remarks>
/// The layout is a list of added accounts. A line seperator. One menu item to add an account.
/// </remarks>
private MenuFlyout ConstructFlyout()
{
if (selectedItem == null)
{
Expand Down Expand Up @@ -557,9 +577,41 @@ public AddRepoViewModel(
var defaultClonePath = Path.Join(userFolder, "source", "repos");
FolderPickerViewModel.CloneLocation = defaultClonePath;

PathToRepos = string.Empty;
LastPathPartsList = new();
LastPathPartPlaceholderText = string.Empty;
EditDevDriveViewModel = new EditDevDriveViewModel(devDriveManager);

EditDevDriveViewModel.DevDriveClonePathUpdated += (_, updatedDevDriveRootPath) =>
{
FolderPickerViewModel.CloneLocationAlias = EditDevDriveViewModel.GetDriveDisplayName(DevDriveDisplayNameKind.FormattedDriveLabelKind);
FolderPickerViewModel.CloneLocation = updatedDevDriveRootPath;
};

ChangeToUrlPage();

// override changes ChangeToUrlPage to correctly set the state.
UrlParsingError = string.Empty;
ShouldShowUrlError = false;
ShowErrorTextBox = false;
_accountIndex = -1;
}

/// <summary>
/// Toggles the clone button. Make sure other view models have correct information.
/// </summary>
public void ToggleCloneButton()
{
var isEverythingGood = ValidateRepoInformation() && FolderPickerViewModel.ValidateCloneLocation();
if (EditDevDriveViewModel.DevDrive != null && EditDevDriveViewModel.DevDrive.State != DevDriveState.ExistsOnSystem)
{
isEverythingGood &= EditDevDriveViewModel.IsDevDriveValid();
}

ShouldEnablePrimaryButton = isEverythingGood;

// Fill in EverythingToClone with the location
if (isEverythingGood)
{
SetCloneLocation(FolderPickerViewModel.CloneLocation);
}
}

/// <summary>
Expand Down Expand Up @@ -602,7 +654,6 @@ public void ChangeToUrlPage()
ShowUrlPage = true;
ShowAccountPage = false;
ShowRepoPage = false;
ShouldShowSelectingSearchTerms = false;
IsUrlAccountButtonChecked = true;
IsAccountToggleButtonChecked = false;
CurrentPage = PageKind.AddViaUrl;
Expand All @@ -614,17 +665,7 @@ public void ChangeToUrlPage()

public async Task ChangeToAccountPageAsync()
{
Log.Logger?.ReportInfo(Log.Component.RepoConfig, "Changing to Account page");
ShouldShowUrlError = Visibility.Collapsed;
ShowUrlPage = false;
ShowAccountPage = true;
ShowRepoPage = false;
ShouldShowSelectingSearchTerms = false;
IsUrlAccountButtonChecked = false;
IsAccountToggleButtonChecked = true;
CurrentPage = PageKind.AddViaAccount;
PrimaryButtonText = _stringResource.GetLocalized(StringResourceKey.RepoAccountPagePrimaryButtonText);
ShouldShowLoginUi = false;
AccountIndex = -1;

// List of extensions needs to be refreshed before accessing
GetExtensions();
Expand Down Expand Up @@ -663,7 +704,7 @@ public async Task ChangeToAccountPageAsync()
ToggleCloneButton();
}

public void ChangeToRepoPage(Dictionary<string, string> searchInputs)
public async Task ChangeToRepoPageAsync()
{
await GetAccountsAsync(_selectedRepoProvider, LoginUiContent);
if (Accounts.Any())
Expand All @@ -678,19 +719,6 @@ public void ChangeToRepoPage(Dictionary<string, string> searchInputs)
ShowUrlPage = false;
ShowAccountPage = false;
ShowRepoPage = true;

ShouldShowSelectingSearchTerms = false;
ShouldShowPathGrid = false;

if (_isSearchingEnabled)
{
ShouldShowPathSelector = true;
}
else
{
ShouldShowPathSelector = false;
}

CurrentPage = PageKind.Repositories;
PrimaryButtonText = _stringResource.GetLocalized(StringResourceKey.RepoEverythingElsePrimaryButtonText);
ShouldShowLoginUi = false;
Expand Down
63 changes: 4 additions & 59 deletions tools/SetupFlow/DevHome.SetupFlow/Views/AddRepoDialog.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,56 +103,13 @@

<!-- Show Repositories -->
<StackPanel x:Name="ShowRepositoriesStackPanel" Visibility="{x:Bind AddRepoViewModel.ShowRepoPage, Mode=OneWay}" Orientation="Vertical" HorizontalAlignment="Stretch" Spacing="10">
<Grid ColumnSpacing="8">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid ColumnSpacing="8" RowSpacing="10">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid x:Name="AccountAndFilterGrid" Padding="0, 0, 0, 15" ColumnSpacing="5" Grid.Row="0" Grid.ColumnSpan="2" BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}" BorderThickness="0, 0, 0, 1" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1.5*"/>
</Grid.ColumnDefinitions>
<SplitButton x:Name="AccountSplitButton"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
Grid.Row="0"
Content="{x:Bind AddRepoViewModel.SelectedAccount, Mode=OneWay}"
Flyout="{x:Bind AddRepoViewModel.AccountsToShow, Mode=OneWay}"/>
<TextBox x:Name="FilterTextBox"
IsEnabled="{x:Bind AddRepoViewModel.IsFetchingRepos, Mode=OneWay, Converter={StaticResource NegateBoolConverter}}"
Grid.Column="1"
TextChanged="FilterTextBox_TextChanged"
x:Uid="ms-resource:///DevHome.SetupFlow/Resources/RepoTool_FilterTextBox" />
</Grid>
<Grid x:Name="PathAndChangePathGrid" Grid.Row="1" Visibility="{x:Bind AddRepoViewModel.ShouldShowPathGrid, Mode=OneWay}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="1" FontSize="{StaticResource SmallFontSize}" Foreground="{ThemeResource TextFillColorSecondary}" Text="{x:Bind AddRepoViewModel.PathToRepos, Mode=OneWay}" VerticalAlignment="Center" HorizontalAlignment="Left" TextTrimming="CharacterEllipsis"/>
<ComboBox x:Name="LastPathPartComboBox" Grid.Row="1" Grid.Column="1" ItemsSource="{x:Bind AddRepoViewModel.LastPathPartsList, Mode=OneWay}" BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Center" PlaceholderText="{x:Bind AddRepoViewModel.LastPathPartPlaceholderText, Mode=OneWay}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="x:String">
<TextBlock Text="{x:Bind}" TextTrimming="CharacterEllipsis"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="SelectionChanged">
<ic:InvokeCommandAction Command="{x:Bind AddRepoViewModel.LastPathPartChangedCommand}" CommandParameter="{x:Bind LastPathPartComboBox.SelectedItem, Mode=OneWay}"/>
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
</ComboBox>
</Grid>
<HyperlinkButton Visibility="{x:Bind AddRepoViewModel.ShouldShowChangePathHyperlinkButton, Mode=OneWay}" Grid.Row="1" Grid.Column="2" Click="ChangeToSearchInputViewAsync" Content="Change Path" HorizontalAlignment="Right"/>
<SplitButton x:Name="AccountSplitButton" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" Grid.Row="0" Content="{x:Bind AddRepoViewModel.SelectedAccount, Mode=OneWay}" Flyout="{x:Bind AddRepoViewModel.AccountsToShow, Mode=OneWay}" IsEnabled="{x:Bind AddRepoViewModel.IsFetchingRepos, Mode=OneWay, Converter={StaticResource BoolToNegationConverter}}"/>
<TextBox x:Name="FilterTextBox" Grid.Column="1" TextChanged="FilterTextBox_TextChanged" x:Uid="RepoTool_FilterTextBox" IsEnabled="{x:Bind AddRepoViewModel.IsFetchingRepos, Mode=OneWay, Converter={StaticResource BoolToNegationConverter}}" />
</Grid>
<Grid Visibility="{x:Bind AddRepoViewModel.IsFetchingRepos, Mode=OneWay}" Height="300" Width="300">
<Grid.RowDefinitions>
Expand Down Expand Up @@ -192,19 +149,7 @@
</ListView.ItemTemplate>
</ListView>
</StackPanel>

<Grid x:Name="SearchForMoreReposGrid" Visibility="{x:Bind AddRepoViewModel.ShouldShowSelectingSearchTerms, Mode=OneWay}">
<Grid x:Name="GatheringSearchValuesGrid">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<ProgressRing x:Name="SearchForMoreReposWaitingProgressRing" Grid.Row="0" HorizontalAlignment="Center"/>
</Grid>
<Grid x:Name="ShowingSearchTermsGrid"/>
</Grid>

<TextBlock x:Name="ErrorTextBlock" Style="{ThemeResource BodyStrongTextBlockStyle}" Visibility="{x:Bind AddRepoViewModel.ShowErrorTextBox, Mode=OneWay}" x:Uid="ms-resource:///DevHome.SetupFlow/Resources/Repo_ToolClonePathError"/>
<TextBlock x:Name="ErrorTextBlock" Style="{ThemeResource BodyStrongTextBlockStyle}" Visibility="{x:Bind AddRepoViewModel.ShowErrorTextBox, Mode=OneWay}" x:Uid="Repo_ToolClonePathError"/>
<!-- Repo page and URL page both have clonepath + dev drive check box-->
<Grid Visibility="{x:Bind AddRepoViewModel.FolderPickerViewModel.ShouldShowFolderPicker, Mode=OneWay}">
<Grid.ColumnDefinitions>
Expand Down
Loading

0 comments on commit 28e3043

Please sign in to comment.