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

Improve experience with recoverable modules for view-only users. #5465

Merged
merged 18 commits into from
Jun 29, 2022

Conversation

techanvil
Copy link
Collaborator

@techanvil techanvil commented Jun 28, 2022

Summary

Addresses issue:

Relevant technical choices

  • Added a check for the recoverableModules feature flag being enabled to avoid calling getRecoverableModules() when the feature is not enabled and logging an error as a result.
  • Memoized the result of getRecoverableModules in order to help prevent an issue with unwanted rerendering.
  • As discussed here Improve experience with recoverable modules for view-only users #5376 (comment), serialized moduleSlugs as metadata.moduleSlug in order to play nicely with the existing logic in combineWidgets() -> shouldCombineAllWidgets().

PR Author Checklist

  • My code is tested and passes existing unit tests.
  • My code has an appropriate set of unit tests which all pass.
  • My code is backward-compatible with WordPress 4.7 and PHP 5.6.
  • My code follows the WordPress coding standards.
  • My code has proper inline documentation.
  • I have added a QA Brief on the issue linked above.
  • I have signed the Contributor License Agreement (see https://cla.developers.google.com/).

Do not alter or remove anything below. The following sections will be managed by moderators only.

Code Reviewer Checklist

  • Run the code.
  • Ensure the acceptance criteria are satisfied.
  • Reassess the implementation with the IB.
  • Ensure no unrelated changes are included.
  • Ensure CI checks pass.
  • Check Storybook where applicable.
  • Ensure there is a QA Brief.

Merge Reviewer Checklist

  • Ensure the PR has the correct target branch.
  • Double-check that the PR is okay to be merged.
  • Ensure the corresponding issue has a ZenHub release assigned.
  • Add a changelog message to the issue.

@github-actions
Copy link

github-actions bot commented Jun 28, 2022

Size Change: +2.59 kB (0%)

Total Size: 1.34 MB

Filename Size Change
./dist/assets/js/googlesitekit-activation-********************.js 27.4 kB +3 B (0%)
./dist/assets/js/googlesitekit-adminbar-********************.js 37.2 kB +387 B (+1%)
./dist/assets/js/googlesitekit-api-********************.js 9.15 kB -1 B (0%)
./dist/assets/js/googlesitekit-base-********************.js 1.13 kB -1 B (0%)
./dist/assets/js/googlesitekit-dashboard-********************.js 61.7 kB +522 B (+1%)
./dist/assets/js/googlesitekit-dashboard-details-********************.js 55.1 kB +574 B (+1%)
./dist/assets/js/googlesitekit-dashboard-splash-********************.js 70.5 kB +211 B (0%)
./dist/assets/js/googlesitekit-datastore-forms-********************.js 8.78 kB +1 B (0%)
./dist/assets/js/googlesitekit-datastore-site-********************.js 14.5 kB -4 B (0%)
./dist/assets/js/googlesitekit-datastore-ui-********************.js 8.88 kB +1 B (0%)
./dist/assets/js/googlesitekit-datastore-user-********************.js 21.3 kB +4 B (0%)
./dist/assets/js/googlesitekit-idea-hub-post-list-********************.js 25.5 kB +1 B (0%)
./dist/assets/js/googlesitekit-modules-********************.js 19.4 kB +25 B (0%)
./dist/assets/js/googlesitekit-modules-adsense-********************.js 66.4 kB +279 B (0%)
./dist/assets/js/googlesitekit-modules-analytics-********************.js 68.9 kB +72 B (0%)
./dist/assets/js/googlesitekit-modules-analytics-4-********************.js 19 kB -4 B (0%)
./dist/assets/js/googlesitekit-modules-idea-hub-********************.js 27.8 kB -2 B (0%)
./dist/assets/js/googlesitekit-modules-optimize-********************.js 19.3 kB -6 B (0%)
./dist/assets/js/googlesitekit-modules-pagespeed-insights-********************.js 18.3 kB -9 B (0%)
./dist/assets/js/googlesitekit-modules-search-console-********************.js 38.8 kB +8 B (0%)
./dist/assets/js/googlesitekit-modules-tagmanager-********************.js 30.5 kB -10 B (0%)
./dist/assets/js/googlesitekit-modules-thank-with-google-********************.js 17.7 kB +4 B (0%)
./dist/assets/js/googlesitekit-polyfills-********************.js 380 B +1 B (0%)
./dist/assets/js/googlesitekit-settings-********************.js 50.4 kB +26 B (0%)
./dist/assets/js/googlesitekit-user-input-********************.js 44.7 kB -7 B (0%)
./dist/assets/js/googlesitekit-vendor-********************.js 323 kB +12 B (0%)
./dist/assets/js/googlesitekit-widgets-********************.js 19 kB +245 B (+1%)
./dist/assets/js/googlesitekit-wp-dashboard-********************.js 60.4 kB +262 B (0%)
./dist/assets/js/runtime-********************.js 1.22 kB -1 B (0%)
ℹ️ View Unchanged
Filename Size
./dist/assets/css/googlesitekit-admin-css-********************.min.css 45.5 kB
./dist/assets/css/googlesitekit-adminbar-css-********************.min.css 10.9 kB
./dist/assets/css/googlesitekit-wp-dashboard-css-********************.min.css 6.32 kB
./dist/assets/js/31-********************.js 51.9 kB
./dist/assets/js/32-********************.js 3.12 kB
./dist/assets/js/analytics-advanced-tracking-********************.js 769 B
./dist/assets/js/googlesitekit-data-********************.js 2.09 kB
./dist/assets/js/googlesitekit-datastore-location-********************.js 2.09 kB
./dist/assets/js/googlesitekit-i18n-********************.js 3.92 kB
./dist/assets/js/googlesitekit-idea-hub-notice-********************.js 45.1 kB

compressed-size-action

Copy link
Collaborator

@aaemnnosttv aaemnnosttv left a comment

Choose a reason for hiding this comment

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

Thanks @techanvil, this looks and works great! Just a few minor things to address and this should be good to go. Nice work!

setupRegistry: setupRegistry( {
recoverableModules: [ 'search-console' ],
} ),
viewContext: VIEW_CONTEXT_DASHBOARD_VIEW_ONLY,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's also make sure the inverse of this is covered – in a non-view-only context widgets for recoverable modules should be output as normal.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, good shout - I've added another test case.

// Here we serialize to `moduleSlug` for compatibility with the logic in
// `combineWidgets()`. In future we may wish to take a less "hacky" approach.
// See https://github.com/google/site-kit-wp/issues/5376#issuecomment-1165771399.
moduleSlug: JSON.stringify( moduleSlugs.sort() ),
Copy link
Collaborator

Choose a reason for hiding this comment

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

We shouldn't call sort on the moduleSlugs prop directly because it will mutate the input.

Also, let's use join instead of stringify because the result for a module that only relies on a single module will be only the one module's slug rather than a JSON string of the array.

Suggested change
moduleSlug: JSON.stringify( moduleSlugs.sort() ),
moduleSlug: [ ...moduleSlugs ].sort().join(),

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, good spot on the sort mutation!

I've fixed that and used join rather than JSON.stringify. I joined using a comma to make the value a bit more coherent and avoid an obscure edge case...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Great thanks! join() uses a comma by default but good to be explicit I suppose. You can also do [1,2,3].toString() which will be comma-separated as well 😉

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Well, thanks for another reminder of the basics. Mutable sort was an oversight on my part, but I had completely forgotten join defaults to a comma! Regardless, I do prefer the explicit version (probably evident from the fact I had forgotten about the default), for the sake of, well, being explicit. :)

/**
* External dependencies
*/
import { getByText } from '@testing-library/dom';
Copy link
Collaborator

Choose a reason for hiding this comment

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

This shouldn't be necessary as this query is returned by render

Copy link
Collaborator Author

@techanvil techanvil Jun 29, 2022

Choose a reason for hiding this comment

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

This is a deliberate choice, as I want to use the version of getByText which accepts a container as the first argument, rather than the bound version returned by render.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks! I'm aware of the difference, the part that isn't obvious is why this would be intentionally used/needed instead?

Copy link
Collaborator Author

@techanvil techanvil Jun 29, 2022

Choose a reason for hiding this comment

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

Well, in the test where it's used, I am asserting that the visible widget contains the text rendered by RecoverableModules:

expect(
getByText(
container.firstChild.querySelector( visibleWidgetSelector ),
'Search Console data was previously shared by an admin who no longer has access. Please contact another admin to restore it.'
)
).toBeInTheDocument();

If I use the bound version and omit the container, this test fails, because RecoverableModules is in fact rendered three times into the DOM, twice within the scope of a .googlesitekit-hidden class (as evident in the corresponding snapshot), and getByText throws an error if there is more than one match for the text.

So, I want to use the non-bound version with the container to scope getByText to the visible widget.

There are of course other ways to code this assertion, but this seemed good enough to me at the time of writing the test...

assets/js/googlesitekit/modules/datastore/modules.js Outdated Show resolved Hide resolved
Comment on lines +114 to +123
Object.values( modules ).reduce( ( recoverable, module ) => {
if ( recoverableModules.includes( module.slug ) ) {
return {
...recoverable,
[ module.slug ]: module,
};
}

return recoverable;
}, {} )
Copy link
Collaborator

Choose a reason for hiding this comment

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

This would be more efficient to iterate over the recoverable slugs as there will always be less of these than all the modules (simply because not all modules are shareable). We could also then check if modules[recoverableSlug] rather than the list search when reducing.

The sets are so small that this probably doesn't matter at all but worth mentioning.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, this did cross my mind too. As I was simply moving this code, I thought it might cloud the issue if I also rewrote it. Besides, as you've pointed out the sets are small, and likely to stay that way, so it would arguably be a case of premature optimization to rewrite it...

@techanvil
Copy link
Collaborator Author

Thanks @aaemnnosttv, I have addressed your comments 👍

Copy link
Collaborator

@aaemnnosttv aaemnnosttv left a comment

Choose a reason for hiding this comment

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

Great, thanks @techanvil !

@aaemnnosttv aaemnnosttv merged commit 82be6e1 into develop Jun 29, 2022
@aaemnnosttv aaemnnosttv deleted the enhancement/5376-view-only-recoverable-modules branch June 29, 2022 16:04
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.

2 participants