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

[Feature] Render package README from local storage in the PM UI #6110

Merged
merged 15 commits into from
Oct 29, 2024

Conversation

jgonz120
Copy link
Contributor

@jgonz120 jgonz120 commented Oct 21, 2024

Bug

Fixes: https://github.com/NuGet/Client.Engineering/issues/2793

Description

Update the PM UI to render package README for packages found locally. To avoid confusion the README only renders in the Installed, Update, and Consolidate tabs. A new feature flag was added, NUGET_RENDER_README_IN_PMUI, that can be used to disable this feature. This was reviewed as a feature branch and the changes previously reviewed are listed below

Screenshots

Package has a README
image

Package has no README defined
image

Browse tab
image

PLOC

image
image
image

Accessibility Tests

image
image

Previous PRs

#6012
#6014
#6029
#6094

Rebase Changes

Due to conflicts the following files were changed during the rebase.
Conflicts:
.vsixinclude
.vsixignore
Directory.Packages.props
NuGet.Protocol\PublicApi\net472\PublicApi.Unshipped.txt
NuGet.Protocol\PublicApi\netstandard2.0\PublicApi.Unshipped.txt
NuGet.Protocol\PublicApi\net8.0\PublicApi.Unshipped.txt
Automerged:
PackageSearchMetadataContextInfo.cs

I also had to update RecommendedPackageSearchMetadata.cs to implement the ReadmeFileUrl property on the IPackageSearchMetadata interface.

PR Checklist

  • Meaningful title, helpful description and a linked NuGet/Home issue
  • Added tests
  • Link to an issue or pull request to update docs if this PR changes settings, environment variables, new feature, etc.

jgonz120 and others added 4 commits October 21, 2024 11:52
…6012)

This package will be used for rendering markdown in the PM UI
Adds the ReadmeFileUrl field to IPackageSearchMetadata and implements the ability to get the URL for local packages. Future PRs will include implementations for getting the URL for remote READMEs and downloading them.

---------

Co-authored-by: Andy Zivkovic <zivkan@users.noreply.github.com>
)

Adds a new ViewModel for getting the README contents, leveraging the NuGetPackageFileService to get the file from the package.

---------

Co-authored-by: Jean-Pierre Briedé <jebriede@microsoft.com>
…ils pane. (#6094)

* Add ReadmeFileUrl field to IPackageSearchMetadata (#6014)

Adds the ReadmeFileUrl field to IPackageSearchMetadata and implements the ability to get the URL for local packages. Future PRs will include implementations for getting the URL for remote READMEs and downloading them.

---------

Co-authored-by: Andy Zivkovic <zivkan@users.noreply.github.com>

* Added new user controls, updated details

* Adjust readme viewmodel name

* update views

* Ensured ReadmefileUrl is set when merging sources

* Fix delegation, update ux to render properly

* Limit local readme rendering to excluse browse tab

* ensure no readme found message for local packages. Added tests

* update property count

* lock url

* fix rebase weirdness.

* PR comments

* Simplify

* Move model to viewmodel

* Renamed controls so they're less confusing

* Switched to templates for tabs

* fix typo

* Update src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/PackageFeeds/MultiSourcePackageMetadataProvider.cs

Co-authored-by: Donnie Goodson <49205731+donnie-msft@users.noreply.github.com>

* PR comment

* rename

* rename tests

* change spacing to make pr easier to see

* more spacing

* Update src/NuGet.Clients/NuGet.PackageManagement.UI/ViewModels/PackageDetailsTabViewModel.cs

Co-authored-by: Donnie Goodson <49205731+donnie-msft@users.noreply.github.com>

* Revert "Update src/NuGet.Clients/NuGet.PackageManagement.UI/ViewModels/PackageDetailsTabViewModel.cs"

This reverts commit add1b00.

* IsVisible rename

* add is visible

* extra line

* rename tsts

* Reduce tab dependencies

* pr comments

* Adjust how selected tab is set

* rename loaded/unloaded

* avoid setting visibility, make tabs more generic

* create conversion for vm to enum

* pr comments

* Update src/NuGet.Clients/NuGet.PackageManagement.UI/ViewModels/PackageDetailsTabViewModel.cs

Co-authored-by: Jean-Pierre Briedé <jebriede@microsoft.com>

---------

Co-authored-by: Andy Zivkovic <zivkan@users.noreply.github.com>
Co-authored-by: Donnie Goodson <49205731+donnie-msft@users.noreply.github.com>
Co-authored-by: Jean-Pierre Briedé <jebriede@microsoft.com>
@jgonz120 jgonz120 force-pushed the dev-feature-ReadMeRenderingInPMUI branch from 8dba8d2 to 2c9fde3 Compare October 21, 2024 18:57
@jgonz120 jgonz120 changed the title Dev feature read me rendering in pm UI [Feature] Render package README from local storage in the PM UI Oct 21, 2024
@jgonz120 jgonz120 marked this pull request as ready for review October 21, 2024 20:10
@jgonz120 jgonz120 requested a review from a team as a code owner October 21, 2024 20:10
Copy link
Contributor

@donnie-msft donnie-msft left a comment

Choose a reason for hiding this comment

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

It's all coming together!

I know at one point we talked about PLOC and Accessibility testing. Have those been performed on the latest commits? Please add screenshots and comments about this in the description. Our UI Guidelines are here: https://github.com/NuGet/NuGet.Client/blob/dev/docs/ui-guidelines.md
Let me know if you have any questions about these processes.

src/NuGet.Clients/NuGet.VisualStudio.Client/.vsixinclude Outdated Show resolved Hide resolved

public DetailControlModel DetailControlModel { get; private set; }

public ObservableCollection<TitledPageViewModelBase> Tabs { get; private set; }
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe last week in your feature branch PR I suggested making this an IReadOnlyList. Can you help me understand why this collection needs to be dynamic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh sorry, if I make the tab a ReadonlyList then I cannot make changes to the items in the tabs, they need to be instantiated in the constructor. Right now, I'm instantiating the VM in the constructor of the view, so I don't have all the components necessary to instantiate the VM. I think once we refactor the DetailControlModel it can handle creating the VM.

</Grid.ColumnDefinitions>

Copy link
Contributor

Choose a reason for hiding this comment

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

undo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

there are some locations where we do an extra line after the ColumnDefinitions, is there a style guide for this?

Copy link
Contributor

Choose a reason for hiding this comment

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

An extra line is ok but the extra spaces don't need to be there.

@@ -678,7 +686,8 @@ public void SaveSettings()
FileConflictAction = _detailModel.Options.SelectedFileConflictAction.Action,
IncludePrerelease = _topPanel.CheckboxPrerelease.IsChecked == true,
SelectedFilter = _topPanel.Filter,
OptionsExpanded = _packageDetail._optionsControl.IsExpanded
OptionsExpanded = _packageDetail._optionsControl.IsExpanded,
SelectedPackageMetadataTab = PackageDetailsTabViewModel.ConvertFromTabType(_packageDetail._packageDetailsTabControl.PackageDetailsTabViewModel.SelectedTab)
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe I mentioned this in previous PR reviews, but it's not clear why the PackageManagerControl needs to be directly involved with the details pane's tabs. There are multiple models and ViewModels between this control and the tab controls. Could you explain design at a high level so I know the reasoning behind this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is where the user settings are being saved. I need to get the current selected metadata tab in order to preserve the selected tab when the PM UI is opened again.

@@ -1269,6 +1278,7 @@ private void Filter_SelectionChanged(object sender, FilterChangedEventArgs e)

NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
await _packageDetail._packageDetailsTabControl.PackageDetailsTabViewModel.SetCurrentFilterAsync(_topPanel.Filter);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't recall this change before but am curious about the design choice of passing the topPanel's tab to be stored and managed inside the PackageDetailsTabViewModel.
It's already available in the PackageManagerControl which is at the top of the hierarchy that creates these TabViewModels. It can just be passed with Control.ActiveFilter or with some refactoring it could be part of one of the parent ViewModels.

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 current tab is used to determine if local readmes are being rendered. I switched it to use ActiveFilter, but I do think it's necessary for the ReadmePreviewViewModel to know what the current tab is so it can handle rendering. @jebriede and I discussed how this would be better met with an event that the VM would listen to and can update itself but that would require a refactoring that feels outside of the scope of this PR.

Copy link
Contributor

@jebriede jebriede Oct 21, 2024

Choose a reason for hiding this comment

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

I don't recall this change before but am curious about the design choice of passing the topPanel's tab to be stored and managed inside the PackageDetailsTabViewModel. It's already available in the PackageManagerControl which is at the top of the hierarchy that creates these TabViewModels. It can just be passed with Control.ActiveFilter or with some refactoring it could be part of one of the parent ViewModels.

I agree with this idea. I also think it's a good idea not to manage a copy of the state of the top panel in a view model that pertains to something else. If the view model needs to react to a change in the top panel's selected tab (ideally through a state change in the model or view model, not directly responding to the UI change, although I know we don't currently have a VM for that panel that tracks this state), it can do that, but storing it requires it to manage the state of its internal representation of what the top panel's tab is and that's introducing the need to synchronize the state of that variable with whatever the top panel is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thinking about this for now I want to leave the control of the visibility of the Readme tab inside of ReadmePreviewViewModel.

I am changing the name of the function to ItemFilterChangedAsync which I think is more accurate to what we want. The VM doesn't need to store the current state it just needs to respond to when the filter changes. Since this view is the one that currently updates the filter on the DetailControlModel, I think it makes sense to let it also set the filter for the ReadmePreviewViewModel. Though I changed it so it fires the change directly on ReadmePreviewViewModel instead of a method inside of the PackageDetailsTabViewModel.

jebriede
jebriede previously approved these changes Oct 22, 2024
Copy link
Contributor

@jebriede jebriede left a comment

Choose a reason for hiding this comment

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

Approving with suggestions

jebriede
jebriede previously approved these changes Oct 22, 2024
nkolev92
nkolev92 previously approved these changes Oct 22, 2024
Copy link
Contributor

@donnie-msft donnie-msft left a comment

Choose a reason for hiding this comment

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

Thank you for adding the Accessibility FastPass results, PLOC testing, and the UI screenshots.

From the responses to my MVVM suggestions it seems like the plan is to iterate on that in upcoming previews. I agree with that approach to be MVVM-forward now and to continue improving it in future VS Previews.

I see 2 blockings issues even for Preview 1 at the moment:

  1. The owner profile hyperlinks are no longer rendering in the Details pane, even in the Browse tab.
    image

  2. While the FastPass succeeded, my testing of Narrator shows that the 'Package Details' tab is not named properly. It should have an accessible name property like our other controls so that the default ToString isn't used by screen readers (eg, now screenreaders announce something like "PackageMetadata custom, (full namespace of the new tab control).

</ColumnDefinition>
<ColumnDefinition Width="auto" />
<ColumnDefinition
Width="67*">
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 only seeing a couple minor changes to values here, but this diff is large since there's so many whitespace changes. Please revert all the whitespace changes in this file.

@jgonz120 jgonz120 dismissed stale reviews from nkolev92 and jebriede via fa91f76 October 23, 2024 01:04
Copy link
Contributor

@donnie-msft donnie-msft left a comment

Choose a reason for hiding this comment

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

We've been working together offline and gotten both of the original issues I reported resolved. Thank you for working diligently on those issues!

There are 2 new issues:

  1. JAWS is reading the entire contents of the Package Details pane when first visiting it. All labels are read for some reason (eg, "Description Version colon"). I've not seen this before so will take some time to advise on what's happening.
    image
  2. The focus border is being truncated on the package details contents
    image

Copy link
Contributor

@donnie-msft donnie-msft left a comment

Choose a reason for hiding this comment

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

Thanks again for the quick offline discussion and addressing the feedback.

I've decided that the remaining issues can be addressed in separate PRs since this is going into Preview 1 and there's ample time to address them.

These are the follow-ups:
NuGet/Home#13878
NuGet/Home#13879
NuGet/Home#13880

@donnie-msft donnie-msft merged commit dddfdd8 into dev Oct 29, 2024
30 of 32 checks passed
@donnie-msft donnie-msft deleted the dev-feature-ReadMeRenderingInPMUI branch October 29, 2024 21:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants