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: useTruncation infinite loop, reenable dashboard cross links on ChartList #27701

Merged
merged 9 commits into from
Apr 9, 2024

Conversation

kgabryje
Copy link
Member

@kgabryje kgabryje commented Mar 27, 2024

SUMMARY

Due to a bug in useChildElementTruncation, there was an edge case which could trigger an infinite loop of rerenders. The bug occurs when the difference in width of subsequent numbers after the plus sign (e.g. +4 and +5) is just big enough to change the truncation state to the other number. This PR ensures that the calculation is performed only once, and if the edge case is triggered, we simply accept the off-by-one error.
This PR also implements a ResizeObserver which recalculates the truncations if the container size changes. Previously we relied on the width values from references in useLayoutEffect's dependency array, which was not a correct approach, since the changes of those values would not trigger a rerender.

This change allowed us to bring back the feature that relied on the truncation logic, which is dashboard cross links on Chart List page. The feature adds a column to the list which displays the dashboards that given chart is added to.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before (occurred long ago when "dashboards added to" column was not yet hidden):

image

After:

image

TESTING INSTRUCTIONS

  1. Visit ChartList
  2. Verify that "Dashboards added to" column is visible and that it correctly displays the dashboards. Dashboard names should be clickable and navigate to given dashboard. Truncated dashboards should appear in a tooltip

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

Copy link

codecov bot commented Mar 27, 2024

Codecov Report

Attention: Patch coverage is 97.91667% with 1 lines in your changes are missing coverage. Please review.

Project coverage is 69.79%. Comparing base (951d7d6) to head (62932b3).

Files Patch % Lines
...d/components/nativeFilters/FilterCard/ScopeRow.tsx 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #27701      +/-   ##
==========================================
+ Coverage   69.78%   69.79%   +0.01%     
==========================================
  Files        1911     1914       +3     
  Lines       75024    75103      +79     
  Branches     8355     8390      +35     
==========================================
+ Hits        52352    52415      +63     
- Misses      20622    20624       +2     
- Partials     2050     2064      +14     
Flag Coverage Δ
javascript 57.52% <97.91%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kgabryje kgabryje requested a review from villebro March 27, 2024 14:32
@kgabryje kgabryje force-pushed the fix/useTruncation-infinite-loop branch from e9830f9 to 08827ca Compare March 27, 2024 14:36
@@ -157,6 +157,20 @@ const StyledActions = styled.div`
color: ${({ theme }) => theme.colors.grayscale.base};
`;

const DashboardCrossLinks = React.memo(
Copy link
Member

Choose a reason for hiding this comment

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

It appears to be more beneficial to create a dedicated file specifically for this component.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@kgabryje kgabryje force-pushed the fix/useTruncation-infinite-loop branch from 49f24f0 to 62932b3 Compare March 28, 2024 13:10
@kgabryje
Copy link
Member Author

kgabryje commented Apr 3, 2024

@justinpark would you be able to do another pass?

@kgabryje
Copy link
Member Author

kgabryje commented Apr 3, 2024

/testenv up

Copy link
Contributor

github-actions bot commented Apr 3, 2024

@kgabryje Ephemeral environment spinning up at http://34.220.216.100:8080. Credentials are admin/admin. Please allow several minutes for bootstrapping and startup.

Comment on lines +46 to +47
// "..." is around 6px wide
const truncationWidth = 6;
Copy link
Member

Choose a reason for hiding this comment

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

I thought we had a function for computing the width of a given element? Can we use something like element.getBoundingClientRect().width to get the exact width of the ellipsis rendered in an invisible element?

Copy link
Member Author

@kgabryje kgabryje Apr 4, 2024

Choose a reason for hiding this comment

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

Not really - the ellipsis is not something that we can grab, because it's not an element in the DOM. What we could do to get a more precise measurement is render <span>...</span> somewhere off screen, measure the width, remove that element and use that width here.
To be honest I'm not sure if it's worth it, the worst thing that can happen here is an off-by-one error in some edge cases

Copy link
Member Author

Choose a reason for hiding this comment

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

Here's what ChatGPT has to say about this:

image

Comment on lines +86 to +88
return () => {
obs.disconnect();
};
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return () => {
obs.disconnect();
};
return obs.disconnect;

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh good point! Though to be fair, I’m not sure about readability - I was halfway through writing a comment about how we should return a cleanup function rather than returning obs.disconnect()… but it’s early morning, so maybe it’s my fault 😉

Copy link
Member

Choose a reason for hiding this comment

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

I'm almost 50-50 here, but I'm leaning in the direction of @betodealmeida here, so I'd say +1 for changing to return obs.disconnect;

Copy link
Member Author

Choose a reason for hiding this comment

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

2 vs 1, request for change has passed 🙂

Copy link
Member Author

Choose a reason for hiding this comment

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

@villebro @betodealmeida With return obs.disconnect, the page is crashing with illegal invocation error. To be honest I don't know why it doesn't work, but it does work with return () => { obs.disconnect(); } so I'm going with that

image

@@ -31,8 +31,7 @@ export const NameRow = ({
hidePopover,
}: FilterCardRowProps & { hidePopover: () => void }) => {
const theme = useTheme();
const filterNameRef = useRef<HTMLElement>(null);
const [elementsTruncated] = useTruncation(filterNameRef);
const [filterNameRef, , elementsTruncated] = useTruncation();
Copy link
Member

Choose a reason for hiding this comment

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

#TIL

Copy link
Member

@villebro villebro left a comment

Choose a reason for hiding this comment

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

In addition to the fix, very nice cleanup work here 👍 A non-blocking comment on the column name + supporting Beto's change request.

Comment on lines +86 to +88
return () => {
obs.disconnect();
};
Copy link
Member

Choose a reason for hiding this comment

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

I'm almost 50-50 here, but I'm leaning in the direction of @betodealmeida here, so I'd say +1 for changing to return obs.disconnect;

cy.getBySel('sort-header').eq(4).contains('Owners');
cy.getBySel('sort-header').eq(5).contains('Last modified');
cy.getBySel('sort-header').eq(6).contains('Actions');
cy.getBySel('sort-header').eq(4).contains('Dashboards added to');
Copy link
Member

Choose a reason for hiding this comment

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

This is maybe out of scope, but I feel Dashboards added to is too verbose, and I think just going with Dashboards or On dashboards makes more 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.

Copy link
Member Author

Choose a reason for hiding this comment

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

@kasiazjc says that "On dashboards" sounds fine. I changed it here (in charts list) and also in Explore for consistence

@kgabryje kgabryje merged commit ae0f2ce into apache:master Apr 9, 2024
29 checks passed
Copy link
Contributor

github-actions bot commented Apr 9, 2024

Ephemeral environment shutdown and build artifacts deleted.

@michael-s-molina michael-s-molina added the v4.0 Label added by the release manager to track PRs to be included in the 4.0 branch label Apr 11, 2024
EnxDev pushed a commit to EnxDev/superset that referenced this pull request Apr 15, 2024
michael-s-molina pushed a commit that referenced this pull request Apr 16, 2024
betodealmeida pushed a commit that referenced this pull request Apr 25, 2024
qleroy pushed a commit to qleroy/superset that referenced this pull request Apr 28, 2024
jzhao62 pushed a commit to jzhao62/superset that referenced this pull request May 16, 2024
@mistercrunch mistercrunch added 🍒 4.0.1 🍒 4.0.2 🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels labels Jul 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels packages size/L v4.0 Label added by the release manager to track PRs to be included in the 4.0 branch 🍒 4.0.1 🍒 4.0.2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants