Skip to content

Package Source Mapping Options UI#4847

Merged
donnie-msft merged 34 commits intodevfrom
dev-mcnallyella-packageSourceMappingOptions
Oct 13, 2022
Merged

Package Source Mapping Options UI#4847
donnie-msft merged 34 commits intodevfrom
dev-mcnallyella-packageSourceMappingOptions

Conversation

@donnie-msft
Copy link
Contributor

@donnie-msft donnie-msft commented Oct 5, 2022

Bug

Fixes: NuGet/Home#11362
Fixes: NuGet/Home#11363

Regression? Last working version:

Description

(Content copied from #4711 which this PR supersedes).

There is currently no support for package source mapping in the VS options UI. These changes allow the user to see all package source mappings in a new Package Source Mapping options dialog, and to Add, Remove, or Clear Remove All mappings. Here is a screenshot of this dialog showing the mappings for NuGet.sln:

image

When a user clicks Add, a new window appears, and the user can type in a package namespace and select from all the previously configured sources for that project to map to. Here is a screenshot showing this window:
image

There were some concerns about the modal dialog and the amount of whitespace in the ListView showing package source mappings, but the UX Board checked it and said it was okay.

PR Checklist

  • PR has a meaningful title

  • PR has a linked issue.

  • Described changes

  • Tests

    • Automated tests added - There are 4 tests for changes to the API. Most of this feature is UI, however, so I have not written tests. This feature currently passes all checks for Accessibility Insights but one. The one accessibility issue is that the ListView showing the package source mappings in the Package Source Mappings options dialog shows the wrong value for the IsOffScreen property for mappings not in view. This issue appears in other VS options dialogs that have a ListView and is mentioned in this issue: Inconsistent UIA IsOffscreen and ClickablePoint properties for WPF ListViewItems that are scrolled out of view dotnet/wpf#4631 , so I decided not to fix it.

AccessibilityInsights

Comment on lines +65 to +67
OnActivateAsync(e, CancellationToken);

}, Resources.PackageSourceMappingOptions_OnActivated);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For those curious, yes there's a UI for a slow loading Options page. It looks like this (with a forced thread delay to make the situation happen):
image


public override string ToString()
{
return ID + " " + SourcesString;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was unable to drill-in to the controls using Narrator or NVDA, but I think it's important to announce the Sources List when visiting a list item. Let me know any better suggestions. Our Package Sources page also announces both Source Name and URL in one take.

The way I'm implementing this is a string concatenation. Narrator and NVDA pause briefly between each comma in the sources list.

image

/// </summary>
public static string PackageSourceMappingOptions_OnActivated {
get {
return ResourceManager.GetString("PackageSourceMappingOptions_OnActivated", resourceCulture);
Copy link
Contributor Author

@donnie-msft donnie-msft Oct 5, 2022

Choose a reason for hiding this comment

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

See OnActivate comment if you're curious where this string actually gets used. #4847 (comment)

Dictionary<PackagePatternItem, PackagePatternItem> otherPatterns = packageSourceMappingSourceItem.Patterns.ToDictionary(c => c, c => c);
var immutablePatterns = new List<PackagePatternItem>(Patterns);
foreach (PackagePatternItem packagePatternItem in immutablePatterns)
var clonedPatterns = new List<PackagePatternItem>(Patterns);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

While reading this code, I realized that "immutable" isn't accurate.


var newValue = (e.RoutedEvent == CheckBox.CheckedEvent);
var oldValue = !newValue; // Assume the state has actually toggled.
AutomationPeer peer = UIElementAutomationPeer.FromElement(itemContainer);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tested that Toggle pattern is working correctly for adding new mappings. Added Newtonsoft.* mapped to nuget.org entirely with the keyboard:

image

image

Background="{Binding Path=(Window.Background), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
TextChanged="PackageID_TextChanged"/>
<StackPanel Orientation="Vertical" Grid.Row="1">
<nuget:ProjectsListView AutomationProperties.Name="Sources List"
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 control I needed to reuse was unfortunately named specifically for Projects list, but I'll refactor that in a separate PR: https://github.com/NuGet/Client.Engineering/issues/1903

var viewModel = new SourceMappingViewModel(packageID, uiSourceMappings[packageID]);
mappingsCollection.Add(viewModel);
}
mappingsCollection.Sort((a, b) => StringComparer.OrdinalIgnoreCase.Compare(a.ID, b.ID));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Decided to Sort the mappings by Package ID in the options page, since otherwise it's just a random order of how the IDs are read from the config.
image

Note that when adding new mappings, they appear initially at the bottom until "OK" is pressed. I think this is standard/expected behavior.

@donnie-msft donnie-msft marked this pull request as ready for review October 5, 2022 23:15
@donnie-msft donnie-msft requested a review from a team as a code owner October 5, 2022 23:15
@loic-sharma
Copy link
Contributor

loic-sharma commented Oct 6, 2022

Looks great! Some minor UI feedback:

  1. Should the Package Source Mappings pane provide some information as to what mappings are, how to use them? Should the Add New Package Source Mapping pane also provide some information? A Learn more link to docs would be great.
  2. The Add New Package Source Mapping pane's Add Valid Package ID placeholder doesn't indicate you can use package ID patterns. Maybe the placeholder could give a hint like Add Package ID Pattern. Ex: 'Newtonsoft.*'
  3. Should the Add New Package Source Mapping pane show both the source's name and URL? In your screenshot, it's hard to distinguish the vside_vs-impl and vside_vssdk sources.

@donnie-msft
Copy link
Contributor Author

Great to hear from you!

Looks great! Some minor UI feedback:

  1. Should the Package Source Mappings pane provide some information as to what mappings are, how to use them? Should the Add New Package Source Mapping pane also provide some information? A Learn more link to docs would be great.

Yes, in VS Options, we use a Help button "?" (see below), and that's why the Documentation section of this PR calls out creating a new Docs page:
image

  1. The Add New Package Source Mapping pane's Add Valid Package ID placeholder doesn't indicate you can use package ID patterns. Maybe the placeholder could give a hint like Add Package ID Pattern. Ex: 'Newtonsoft.*'

@nkolev92 did we agree that "package ID" implies pattern, or do we need to state the word pattern? I believe we discussed this, so I don't want to make last minute changes. Also consider that the docs will help explain how this works.

  1. Should the Add New Package Source Mapping pane show both the source's name and URL? In your screenshot, it's hard to distinguish the vside_vs-impl and vside_vssdk sources.

I'm not sure that adding lengthy URLs into the list is going to make anything easier to distinguish.
I'll see what UX thinks. Maybe a stronger separator between names would help?

@nkolev92
Copy link
Member

nkolev92 commented Oct 6, 2022

@nkolev92 did we agree that "package ID" implies pattern, or do we need to state the word pattern? I believe we discussed this, so I don't want to make last minute changes. Also consider that the docs will help explain how this works.

I think we should call it package pattern, https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping#package-pattern-syntax.

The docs call out Package ID pattern and Package Prefix Pattern.

I'll review the whole PR, but I'm pretty confident package pattern is the right one in this case, as it's what specifically came up with to be able to refer to both package id and package prefixes.
After all, the xml element is called package pattern

@loic-sharma
Copy link
Contributor

Has that help button always been there??? I've never noticed it before 🤯

I'm not sure that adding lengthy URLs into the list is going to make anything easier to distinguish.
I'll see what UX thinks. Maybe a stronger separator between names would help?

Hm, another potential alternative could be a tooltip on hover that adds more details.

Copy link
Contributor

@dominoFire dominoFire left a comment

Choose a reason for hiding this comment

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

Partial review. Please address AutomationProperties.Name comments. Thanks! Good job!

<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox AutomationProperties.Name="SourcesCheckBox"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<CheckBox AutomationProperties.Name="SourcesCheckBox"
<CheckBox AutomationProperties.Name={x:Static nuget:Resources.PackageSourceCheckBox_AccessibleName}

Copy link
Contributor Author

@donnie-msft donnie-msft Oct 11, 2022

Choose a reason for hiding this comment

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

I found 2 approaches in existing code:

  1. Package Items have a checkbox for the Updates tab. I decided to mimic this behavior. Narrator reads "Selected" when visiting the checkbox:

    AutomationProperties.Name="{x:Static nuget:Resources.CheckBox_Selected}"

  2. In the Projects List of Solution PMUI, we have a more complicated usage of AutomationProperties. The Name repeats the projectname. HelpText gives a sentence about what it means to select this item.
    I'm not sure if either is warranted for this checkbox. Result for Narrator when drilling-in to this checkbox, it announces "Selected checkbox (Un)Checked".

I feel approach 1 is a better first step given the intent of the window and the behavior of the checkbox are announced indirectly by the screen-reader. PMUI Package list works similarly. We can expand the verbosity of AutomationProperties, if necessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm good with Approach #1 as long as it's reviewed by A11y team.

@donnie-msft
Copy link
Contributor Author

Has that help button always been there??? I've never noticed it before 🤯

Yes! Although I think not all pages implement it, it used to be the de facto documentation button.

I'm not sure that adding lengthy URLs into the list is going to make anything easier to distinguish.
I'll see what UX thinks. Maybe a stronger separator between names would help?

Hm, another potential alternative could be a tooltip on hover that adds more details.

@loic-sharma These are good ideas; however, reviewing this with UX folks, they don't feel there's a problem with distinguishing between the comma-delimited list. They actually suggested an Edit dialog as a solution to that problem, which we have considered after this first iteration. The idea is if you can re-open the dialog to edit a Mapping, the user can see the checkbox-list of sources (more concrete than the list). Do you feel that would resolve your concern?

@donnie-msft donnie-msft force-pushed the dev-mcnallyella-packageSourceMappingOptions branch from 804eff1 to e99fd73 Compare October 8, 2022 00:46
@donnie-msft
Copy link
Contributor Author

Modified Watermark in textbox for adding a new mapping to include an example: e99fd73
image
The font color is also incorrect. Couldn't fix this with a quick attempt, so filed NuGet/Home#12141

I think we should call it package pattern, https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping#package-pattern-syntax.

The docs call out Package ID pattern and Package Prefix Pattern.

@nkolev92 please let me know if the new text adequately addresses your concern.

@donnie-msft
Copy link
Contributor Author

Changed "Clear" to "Remove All" based on UX feedback.
image

dominoFire
dominoFire previously approved these changes Oct 11, 2022
Copy link
Contributor

@dominoFire dominoFire left a comment

Choose a reason for hiding this comment

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

Signing off

@donnie-msft
Copy link
Contributor Author

Is there any harm in providing it here then?

"Fixing" the analyzer seems to be less noisy than suppressing it.

@nkolev92 - The harm is that it will wrap the call in a JTF.Run, which is not accomplishing anything logically.

https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.platformui.delegatecommand-1.-ctor?view=visualstudiosdk-2022

@donnie-msft donnie-msft merged commit f08ff09 into dev Oct 13, 2022
@donnie-msft donnie-msft deleted the dev-mcnallyella-packageSourceMappingOptions branch October 13, 2022 00:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

5 participants