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

Add whenInViewContext higher-order component (HOC) to allow simplification of code that should only run inside some view contexts #8723

Open
15 tasks
tofumatt opened this issue May 16, 2024 · 3 comments
Labels
P2 Low priority Type: Enhancement Improvement of an existing feature Type: Infrastructure Engineering infrastructure & tooling

Comments

@tofumatt
Copy link
Collaborator

tofumatt commented May 16, 2024

Feature Description

There are places in the codebase where we don't want to render a component or want to render a fallback in certain view contexts. Mostly, this is when we don't want a component to render on a view-only dashboard. Example:

if (
viewOnly ||
isDismissed ||
! analyticsAndAdsenseConnectedAndLinked
) {
return null;
}

Because some selectors will actually error on view-only dashboards (because a view-only user doesn't have access to the API routes/etc.), we have to guard every selector call, which is wasteful.

Similar to our whenActive higher-order component, we should create a whenInViewContext HOC that allows us to only render a component in certain view contexts, and use that component to refactor existing components like GA4AdSenseLinkedNotification.


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

Acceptance criteria

  • A whenInViewContext HOC should be created that behaves similarly to the whenActive and whenScopesGranted HOCs, except it should render/not render based on arguments supplied:
    • allViewOnly, which when true should render the component when useViewOnly() returns true
    • allNonViewOnly which when true should render the component when useViewOnly() returns false
    • includeList which is an array of view contexts that the component should render when present
    • excludeList which is an array of view contexts that the component should render when not present
    • Supplying any mutually exclusive arguments (eg. includeList and excludeList) should throw an error
  • The GA4AdSenseLinkedNotification.js component should be refactored to use this new HOC and remove any (now-redundant) checks from its useSelect calls (example:
    if ( ! dashboardType || viewOnly ) {
    return null;
    }
    )

Implementation Brief

whenInViewContext HOC

  • Create a new component, whenInViewContext, in the file assets/js/util/whenInViewContext.js:
    • The HOC should accept the four props specified in the AC.
      • Add invariant call, with the props: !(!! includeList && !! excludeList) and the message: 'include and exclude lists cannot both be provided'.
      • Add invariant call, with the props: !(!! allViewOnly && !! allNonViewOnly) and the message: 'view only and non view only lists cannot both be true'.
    • The HOC should return ( WrappedComponent ) => {:
      • This should define a function: function WhenInViewContext( props ) {
        • Get the viewOnly value using const isViewOnly = useViewOnly();
          • If props.allViewOnly is true and isViewOnly is false, return null.
          • If props.allNonViewOnly is true and isViewOnly is true, return null.
        • Get the current view context using const viewContext = useViewContext();
          • If !! includeList and ! includeList.includes( viewContext ), return null.
          • If !! excludeList and includeList.includes( viewContext ), return null.
        • At the end of the function return <WrappedComponent { ...props } />;

Update GA4AdSenseLinkedNotification

  • Update assets/js/components/notifications/GA4AdSenseLinkedNotification.js, wrapping the export of the component with the new whenInViewContext HOC, passing the props: { allViewOnly: true }.
    • Remove all uses of the viewOnly hook within the component and test to confirm that the component is not rendered and selectors are not called in the view only context as expected.

Test Coverage

  • Create a new file, assets/js/util/whenInViewContext.test.js, to test each case in the AC + the invariant conditions.

QA Brief

Changelog entry

@tofumatt tofumatt self-assigned this May 16, 2024
@tofumatt tofumatt added Type: Enhancement Improvement of an existing feature Type: Infrastructure Engineering infrastructure & tooling labels May 16, 2024
@tofumatt tofumatt removed their assignment May 16, 2024
@tofumatt tofumatt added the P2 Low priority label May 16, 2024
@benbowler benbowler self-assigned this May 28, 2024
@benbowler
Copy link
Collaborator

Created the IB. Some possible additions/questions:

  • We could add something like invariant if the user passes invalid prop combinations like both and include and exclude list or both view only and non view only?
  • I assumed we weren't using this new HOC yet in this ticket? Otherwise we could add a case/some cases to refactor as part of this work.

@benbowler benbowler removed their assignment May 29, 2024
@tofumatt tofumatt self-assigned this May 29, 2024
@tofumatt
Copy link
Collaborator Author

@benbowler Adding invariant checks makes sense, let's do that too 👍🏻

Also, while it wasn't in the ACs, let's add it to at least one component so we can QA it properly 👍🏻 I've added refactoring [GA4AdSenseLinkedNotification.js](https://github.com/google/site-kit-wp/blob/4cce042da8831b2ec8663e4d9767bc0610ae4e5a/assets/js/components/notifications/GA4AdSenseLinkedNotification.js#L115-L121) to the ACs 🙂

@tofumatt tofumatt assigned benbowler and unassigned tofumatt May 29, 2024
@benbowler benbowler assigned tofumatt and unassigned benbowler May 30, 2024
@tofumatt
Copy link
Collaborator Author

Looks good to me 👍🏻

IB ✅

@tofumatt tofumatt removed their assignment May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 Low priority Type: Enhancement Improvement of an existing feature Type: Infrastructure Engineering infrastructure & tooling
Projects
None yet
Development

No branches or pull requests

2 participants