Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SLVS-1512 Improve UX #5742

Merged
merged 11 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ public void ProjectSearchTerm_RaisesEvents()
viewModel.ProjectSearchTerm = searchTerm;

eventHandler.Received().Invoke(viewModel, Arg.Is<PropertyChangedEventArgs>(x => x.PropertyName == nameof(viewModel.NoProjectExists)));
eventHandler.Received().Invoke(viewModel, Arg.Is<PropertyChangedEventArgs>(x => x.PropertyName == nameof(viewModel.HasSearchTerm)));
}

[TestMethod]
Expand Down Expand Up @@ -277,6 +278,27 @@ public async Task AdapterGetAllProjectsAsync_ReturnsResponseFromAdapter(bool exp
response.ResponseData.Should().BeEquivalentTo(expectedServerProjects);
}

[TestMethod]
[DataRow(null)]
[DataRow("")]
public void ProjectSearchTerm_SearchTermNullOrEmpty_ReturnsFalse(string searchTerm)
{
testSubject.ProjectSearchTerm = searchTerm;

testSubject.HasSearchTerm.Should().BeFalse();
}

[TestMethod]
[DataRow("abc")]
[DataRow(" ")]
[DataRow("\t")]
Comment on lines +293 to +294
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to Trim the search term and count those cases as empty

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HasSearchTerm property is used to determine what text we should show when the list of projects is entered. If the user enters an empty string " " and there are no projects found for that, then we should show the message accordingly. So when " " is entered the text should say "no project was found for the entered search term" and not "No project exists"

We can trim the SearchTerm property before sending it to SlCore, but I am expecting that the search is optimized for this cases, so I don't think it is needed from our side for now.

public void ProjectSearchTerm_SearchTermNotNullNorEmpty_ReturnsTrue(string searchTerm)
{
testSubject.ProjectSearchTerm = searchTerm;

testSubject.HasSearchTerm.Should().BeTrue();
}

private void MockInitializedProjects(List<ServerProject> serverProjects)
{
testSubject.InitProjects(new AdapterResponseWithData<List<ServerProject>>(true, serverProjects));
Expand Down
46 changes: 34 additions & 12 deletions src/ConnectedMode/UI/ProjectSelection/ProjectSelectionDialog.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
xmlns:res="clr-namespace:SonarLint.VisualStudio.ConnectedMode.UI.Resources"
xmlns:ui="clr-namespace:SonarLint.VisualStudio.ConnectedMode.UI"
xmlns:wpf="clr-namespace:SonarLint.VisualStudio.Core.WPF;assembly=SonarLint.VisualStudio.Core"
xmlns:vsimagecatalog="clr-namespace:Microsoft.VisualStudio.Imaging;assembly=Microsoft.VisualStudio.ImageCatalog"
xmlns:imaging="clr-namespace:Microsoft.VisualStudio.Imaging;assembly=Microsoft.VisualStudio.Imaging"
Title="{x:Static res:UiResources.ProjectSelectionDialogTitle}"
WindowStartupLocation="CenterOwner"
Loaded="ProjectSelectionDialog_OnLoaded"
Expand Down Expand Up @@ -52,34 +54,54 @@
<TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Static res:UiResources.ExistingProjectsLabel}" Style="{StaticResource HeaderTextBlock}"
Margin="0,10"/>
<TextBox Grid.Row="1"
x:Name="ProjectSearchTextBox"
VerticalAlignment="Top"
Text="{Binding ProjectSearchTerm, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Grid.Row="1" IsHitTestVisible="False"
Text="{x:Static res:UiResources.SearchForProjectPlaceholder}" VerticalAlignment="Center"
HorizontalAlignment="Left" Margin="5,0,0,0" Foreground="DarkGray">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
Text="{Binding ProjectSearchTerm, UpdateSourceTrigger=PropertyChanged, Delay=500}" />
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=ProjectSearchTextBox}" Value="">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel.Style>
<imaging:CrispImage IsHitTestVisible="False"
Width="16" Height="16" Moniker="{x:Static vsimagecatalog:KnownMonikers.Search}"
HorizontalAlignment="Left" Margin="5,0,0,0"/>
<TextBlock IsHitTestVisible="False"
Text="{x:Static res:UiResources.SearchForProjectPlaceholder}"
HorizontalAlignment="Left" Margin="5,0,0,0" Foreground="DarkGray" />
</StackPanel>

<ListBox Grid.Row="2"
Margin="0, 10, 0, 10"
ItemsSource="{Binding ProjectResults}"
SelectedItem="{Binding SelectedProject}"
ItemTemplate="{StaticResource NameAndKeyListBoxItem}" />
ItemTemplate="{StaticResource NameAndKeyListBoxItem}"
VirtualizingPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True"/>

<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{x:Static res:UiResources.NoProjectsExistLabel}"
Visibility="{Binding Path=NoProjectExists, Converter={StaticResource TrueToVisibleConverter}}"/>
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center"
Visibility="{Binding Path=NoProjectExists, Converter={StaticResource TrueToVisibleConverter}}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=HasSearchTerm}" Value="True">
<Setter Property="Text" Value="{x:Static res:UiResources.NoProjectsFoundForSearchTermLabel}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=HasSearchTerm}" Value="False">
<Setter Property="Text" Value="{x:Static res:UiResources.NoProjectsExistLabel}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>

<ui:ProgressAndErrorHandlerComponent Grid.Row="3" Grid.ColumnSpan="3" Margin="0,10" ProgressReporterViewModel="{Binding Path=ProgressReporterViewModel}"/>
<ui:ProgressAndErrorHandlerComponent Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,10" ProgressReporterViewModel="{Binding Path=ProgressReporterViewModel}"/>

<Button Grid.Column="1" Grid.Row="4" Content="{x:Static res:UiResources.SelectButton}"
HorizontalAlignment="Right"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class ProjectSelectionViewModel(
public IProgressReporterViewModel ProgressReporterViewModel { get; } = progressReporterViewModel;

public bool NoProjectExists => ProjectResults.Count == 0;
public bool HasSearchTerm => !string.IsNullOrEmpty(ProjectSearchTerm);

public string ProjectSearchTerm
{
Expand All @@ -47,6 +48,7 @@ public string ProjectSearchTerm
projectSearchTerm = value;
SearchForProject();
RaisePropertyChanged();
RaisePropertyChanged(nameof(HasSearchTerm));
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/ConnectedMode/UI/Resources/UiResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/ConnectedMode/UI/Resources/UiResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -413,4 +413,7 @@ Please manually add the credentials for the connection and then try again.</valu
<data name="SearchingProjectInProgressText" xml:space="preserve">
<value>Searching for project...</value>
</data>
<data name="NoProjectsFoundForSearchTermLabel" xml:space="preserve">
<value>Your search did not match any project</value>
</data>
</root>