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

fix: [M3-7249] - Linode Landing flickering #9836

Conversation

bnussman-akamai
Copy link
Member

@bnussman-akamai bnussman-akamai commented Oct 24, 2023

Description 📝

  • Fixes flickering on the Linodes landing page caused by the PreferenceToggle component
  • The rewrites the PreferenceToggle to not store duplicate state and rely on React Query for the state preference state directly.

Changes 🔄

  • Removed unused localStorageKey prop
  • No longer blocks PreferenceToggle.tsx's children from rendering if a preference value is

Preview 📷

Before After
Screen.Recording.2023-10-24.at.10.35.29.AM.mov
Screen.Recording.2023-10-24.at.10.35.50.AM.mov

How to test 🧪

Reproduction steps

  • Click the Akamai logo while on the Linode Landing page to see the flickering

Verification steps

  • Verify that the flickering no longer happens when you click on the Akamai logo
  • Verify that preferences are still loaded and retained normally (for example, if you group by tag and reload, it should retain the group by tag setting)
  • Go to http://localhost:3000/profile/settings?preferenceEditor=true and clear your preferences ({})
  • Verify that no flickering happens even when your preferences are empty

As an Author I have considered 🤔

  • 👀 Doing a self review
  • ❔ Our contribution guidelines
  • 🤏 Splitting feature into small PRs
  • ➕ Adding a changeset
  • 🧪 Providing/Improving test coverage
  • 🔐 Removing all sensitive information from the code and PR description
  • 🚩 Using a feature flag to protect the release
  • 👣 Providing comprehensive reproduction steps
  • 📑 Providing or updating our documentation
  • 🕛 Scheduling a pair reviewing session
  • 📱 Providing mobile support
  • ♿ Providing accessibility support

@bnussman-akamai bnussman-akamai added the Bug Fixes for regressions or bugs label Oct 24, 2023
@bnussman-akamai bnussman-akamai requested a review from a team as a code owner October 24, 2023 14:43
@bnussman-akamai bnussman-akamai self-assigned this Oct 24, 2023
@bnussman-akamai bnussman-akamai requested review from dwiley-akamai and abailly-akamai and removed request for a team October 24, 2023 14:43
@@ -188,7 +188,6 @@ class ListLinodes extends React.Component<CombinedProps, State> {
<DocumentTitleSegment segment="Linodes" />
<ProductInformationBanner bannerLocation="Linodes" />
<PreferenceToggle<boolean>
localStorageKey="GROUP_LINODES"
Copy link
Member Author

Choose a reason for hiding this comment

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

This prop was unused and did nothing

@bnussman-akamai bnussman-akamai marked this pull request as draft October 24, 2023 14:59
@bnussman-akamai bnussman-akamai marked this pull request as ready for review October 24, 2023 15:56
preferenceKey="linodes_group_by_tag"
preferenceOptions={[false, true]}
toggleCallbackFnDebounced={sendGroupByAnalytic}
Copy link
Member Author

@bnussman-akamai bnussman-akamai Oct 24, 2023

Choose a reason for hiding this comment

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

Because we now rely on React Query's state directly, we won't debounce because React Query performs optimistic updates. I don't think this is an issue considering how and where this component is used.

@@ -52,31 +43,3 @@ describe('checkPreferencesForBannerDismissal', () => {
expect(checkPreferencesForBannerDismissal({}, 'key1')).toBe(false);
});
});

describe('Databases menu item for a restricted user', () => {
it('should not render the menu item', async () => {
Copy link
Member Author

Choose a reason for hiding this comment

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

The intentions of this test are not clear. We have tests for this case in the PrimaryNav test and AddNewMenu so I'm not sure what this one was intended to check. It was flakey because it tries to render the entire app

@jdamore-linode
Copy link
Contributor

It looks like the test failure in managed-navigation.spec.ts is legitimate -- For Managed users, Cloud doesn't seem to be redirecting from / to /managed/summary and is always redirecting to /linodes instead.

@@ -142,6 +140,7 @@ export class AuthenticationWrapper extends React.Component<CombinedProps> {
/** We choose to do nothing, relying on the Redux error state. */
} finally {
this.props.markAppAsDoneLoading();
this.setState({ showChildren: true });
Copy link
Member Author

Choose a reason for hiding this comment

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

Fixes e2e failure @jdamore-linode mentioned.

PreferenceToggle use to render-block all children until preferences were loaded. Now we are render-blocking at this level, which makes more sense anyway.

Copy link
Contributor

Choose a reason for hiding this comment

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

/** We choose to do nothing, relying on the Redux error state. */

It's my first time visiting this code in a long time. I understand we to load content and render tree in the case of a fetching error, but what does the redux error do exactly? The user does not get any feedback something fails (ex: try blocking any API request). It's probably beyond the scope of this PR but wondering what your thoughts are about it.

@bnussman-akamai
Copy link
Member Author

I spun up devenv to verify that authentication still works as expected. I set the login expiry to 10 seconds to confirm Cloud Manager re-auths as expected

Screen.Recording.2023-10-24.at.6.30.15.PM.mov

Copy link
Contributor

@abailly-akamai abailly-akamai left a comment

Choose a reason for hiding this comment

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

Thanks for working on this! This is a sensitive area 💅

Flicker is gone and did not notice any bug/regression ✅

Will approve once getting some clarity on the items I commented about

@@ -90,8 +82,12 @@ export class AuthenticationWrapper extends React.Component<CombinedProps> {
render() {
const { children } = this.props;
const { showChildren } = this.state;
Copy link
Contributor

Choose a reason for hiding this comment

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

Any thoughts on renaming showChildren? Isn't this pretty much "renderTree"? wondering what could make a tad more clear the fact we're really loading the application.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was considering something more like isLoading but I decided to just leave as is for now. I definitely plan to follow this PR up with some others that improve our general render tree/ entry points. It's an absolute mess.

@@ -142,6 +140,7 @@ export class AuthenticationWrapper extends React.Component<CombinedProps> {
/** We choose to do nothing, relying on the Redux error state. */
} finally {
this.props.markAppAsDoneLoading();
this.setState({ showChildren: true });
Copy link
Contributor

Choose a reason for hiding this comment

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

/** We choose to do nothing, relying on the Redux error state. */

It's my first time visiting this code in a long time. I understand we to load content and render tree in the case of a fetching error, but what does the redux error do exactly? The user does not get any feedback something fails (ex: try blocking any API request). It's probably beyond the scope of this PR but wondering what your thoughts are about it.

setPreference(newPreferenceToSet);
updateUserPreferences({
[preferenceKey]: newPreferenceToSet,
}).catch(() => /** swallow the error */ null);
Copy link
Contributor

Choose a reason for hiding this comment

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

Swallow the error? What does it mean for the end user?

Copy link
Member Author

Choose a reason for hiding this comment

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

It means their updated preferences won't be sent to the API. (this is existing code)

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, and they won't know anything about it :( How about a TODO follow up item and associated ticket to display a toast (or whatever we decide) to handle this better?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, we could toast. I think we decided to swallow the errors because the idea of preferences is that is should be a low-impact failure if that makes any sense.

Copy link
Member Author

Choose a reason for hiding this comment

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

Created M3-7326

@bnussman-akamai
Copy link
Member Author

@abailly-akamai I think that comment refers to our Axios interceptors that populate something called "globalErrors" in redux. From there we unblock rendering and surface whatever the UI would show. We definitely should consider adding a fallback for cases when the account/profile fail to load. The neat thing is that the app still somewhat functions if these fail and other requests succeed.

@bnussman-akamai
Copy link
Member Author

I also confirmed this page still renders 👍🏼

Screenshot 2023-10-25 at 12 48 09 PM

@@ -0,0 +1,27 @@
import { apiMatcher } from 'support/util/intercepts';
Copy link
Contributor

@jdamore-linode jdamore-linode Oct 25, 2023

Choose a reason for hiding this comment

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

Awesome!!!

Edit: Whoops, meant for this to be for the entire file lol

Copy link
Contributor

@jdamore-linode jdamore-linode left a comment

Choose a reason for hiding this comment

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

Nice work, @bnussman-akamai

  • Not seeing any flickering
  • Cypress and Jest tests are passing

Really enthusiastic about the account activation test, too! Great idea!

@bnussman-akamai bnussman-akamai added the Add'tl Approval Needed Waiting on another approval! label Oct 25, 2023
Copy link
Contributor

@dwiley-akamai dwiley-akamai left a comment

Choose a reason for hiding this comment

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

Flickering no longer happens when you click on the Akamai logo ✅
Group by tag & Summary view preferences ✅
No flickering even when preferences are empty ✅
Code review ✅

packages/manager/src/IdentifyUser.tsx Outdated Show resolved Hide resolved
@bnussman-akamai
Copy link
Member Author

Planning to merge after the release is ✂️

@bnussman-akamai bnussman-akamai removed the Add'tl Approval Needed Waiting on another approval! label Oct 25, 2023
Co-authored-by: Dajahi Wiley <114682940+dwiley-akamai@users.noreply.github.com>
@mjac0bs mjac0bs added the Approved Multiple approvals and ready to merge! label Oct 25, 2023
@bnussman-akamai bnussman-akamai merged commit f26f788 into linode:develop Oct 25, 2023
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Approved Multiple approvals and ready to merge! Bug Fixes for regressions or bugs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants