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 a search filter to the timeline track context menu #3634

Merged
merged 10 commits into from
Nov 22, 2021

Conversation

canova
Copy link
Member

@canova canova commented Nov 2, 2021

Fixes #3575.

This PR adds a search filter to the track context menu. And also changes the "show all tracks" button to "show all tracks below" when a search text is entered. This should help on showing a subset of tracks more easily.

The new search filter:
Screenshot from 2021-11-03 10-50-03

Some example profiles to test it with:
Profile 1
Profile 2
Profile 3

@canova canova requested a review from a team as a code owner November 2, 2021 18:07
@codecov
Copy link

codecov bot commented Nov 2, 2021

Codecov Report

Merging #3634 (8a759e5) into main (7b4ea84) will decrease coverage by 0.13%.
The diff coverage is 76.21%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3634      +/-   ##
==========================================
- Coverage   88.91%   88.77%   -0.14%     
==========================================
  Files         258      259       +1     
  Lines       21545    21746     +201     
  Branches     5507     5564      +57     
==========================================
+ Hits        19156    19305     +149     
- Misses       2214     2262      +48     
- Partials      175      179       +4     
Impacted Files Coverage Δ
src/selectors/url-state.js 98.48% <ø> (+0.53%) ⬆️
src/components/shared/TrackSearchField.js 53.33% <53.33%> (ø)
src/profile-logic/tracks.js 85.90% <62.85%> (-7.23%) ⬇️
src/components/timeline/TrackContextMenu.js 91.22% <91.89%> (+0.19%) ⬆️
src/reducers/url-state.js 97.87% <92.85%> (-0.23%) ⬇️
src/utils/string.js 96.87% <92.85%> (-3.13%) ⬇️
src/actions/profile-view.js 85.39% <100.00%> (+0.12%) ⬆️
src/reducers/app.js 99.32% <100.00%> (+<0.01%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7b4ea84...8a759e5. Read the comment docs.

Copy link
Contributor

@flodolo flodolo left a comment

Choose a reason for hiding this comment

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

(for the FTL bits)

@canova
Copy link
Member Author

canova commented Nov 4, 2021

@julienw I've added two more commits now and I believe this is ready for review. Could you take a look at it?

Also, about the last commit(0809704): I'm didn't like my solution that much, but I couldn't find another way and it looks like there are some codes that does the same (like in FlameGraph). I had to go in this direction instead of autofocus property because it doesn't work with this prop since this component is already rendered and hidden at the page load. When you click on the context menu button, it simply steals the focus and makes the autofocus useless.

Copy link
Contributor

@julienw julienw left a comment

Choose a reason for hiding this comment

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

Praise: this is all working pretty well!

I have quite a strong concern about storing this data to Redux and persisting it in the URL, and that's why I'm marking the patch with "request changes". But the rest of the code looks great!

focus = () => {
// Allow time for React to let the event bubble up. Otherwise clicked button
// will steal the focus.
requestAnimationFrame(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

have you tried using a simple setTimeout ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also I believe this rAF/setTimeout should rather be in TrackContextMenu's _onShow function than here.

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 don't think there is a difference in terms of the result of both setTimeout or rAF. And there are other use cases in our codebase with rAF, so I wanted to use it. For example:

requestAnimationFrame(() => {
// Restore focus, but not during a React setState call, otherwise this triggers
// a React warning:
// "unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering."
focusAfterClosed.focus();
});

Copy link
Contributor

@julienw julienw Nov 19, 2021

Choose a reason for hiding this comment

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

yeah, Greg is a big fan of rAF ;-)

My main concern with rAF is that they're tied with the graphics ticks, and so I'm not so sure this is the right tool for the job for focus calls. Here the only thing we want is to be asynchronous, that's why setTimeout seems to be a better tool.

I'm not sure this does a real difference in this specific case. Though it's important to understand fully the behaviors and interactions for all these functions with callbacks.

And TBH I'm not so sure myself, so I might even be wrong here!

@@ -1214,6 +1214,16 @@ export function changeNetworkSearchString(searchString: string): Action {
};
}

/**
Copy link
Contributor

Choose a reason for hiding this comment

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

(This is a comment for the complete 2nd commit about adding a redux state)
I'm not convinced that this information should go to the redux state and to the URL. This is confusing because this input is local to the menu. Also I wouldn't want the context menu to be automatically filtered when I load a profiler URL.

I'd agree for an input that would control the display of the tracks in the timeline, but here that's not the case, it's really local to this menu and IMO this should stay in a local state in the menu. So I'd move everything from the reducer and the action and the selector back to the TrackContextMenu component. Most of the selector code is in tracks so we just need to call it from here instead of from the selector. This won't be memoized then but I think it's fine (and if we need memoization to happen for perf reason we could still do it explicitely).

BTW I also believe it should be empty each time we open the menu.

What do you think?

(BTW the current code has a "nice" bug because of this: 1. add some filtering terms, 2. right click on a track name in the timeline => tracks are still filtered out).

Copy link
Contributor

Choose a reason for hiding this comment

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

Also if it's not in Redux anymore, I'd love to see if we need the IdleSearchInput, or whether a plain normal input wouldn't work. Of course the IdleSearchInput brings some nice things like the clear button, so I'm not opposed to keeping it, but maybe lowering the debouncing delay could be nice.

* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

.trackSearchField form.idleSearchField {
width: 100%;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this width necessary? I'm not so sure.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it is needed because otherwise it doesn't contain 100% of the width.

src/components/shared/TrackSearch.css Outdated Show resolved Hide resolved
src/components/shared/TrackSearch.js Outdated Show resolved Hide resolved
Comment on lines 112 to 115
showProvidedTracks(
searchFilteredGlobalTracks,
searchFilteredLocalTracksByPid
);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think I'd prefer most (if not all) of the code in the action showProvidedTracks to be moved here. In the past we've put too much code in thunk actions and I'd like, if possible, that we try to avoid it. In this case I believe we have all the necessary objects in this component already.

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, I guess it's better to move the logic inside the component instead of the thunk action. I mostly did it to follow the current style, but don't mind moving it. Did it.

src/test/components/TrackContextMenu.test.js Outdated Show resolved Hide resolved
src/test/components/TrackContextMenu.test.js Outdated Show resolved Hide resolved
src/components/timeline/TrackContextMenu.js Outdated Show resolved Hide resolved
src/profile-logic/tracks.js Show resolved Hide resolved
@canova canova force-pushed the track-search branch 3 times, most recently from cf46f3d to f13f3cb Compare November 18, 2021 15:13
Copy link
Member Author

@canova canova 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 the review Julien. It took me some time to come back to this PR. I've addressed your review comments. Removed the redux state and made the search filter a state instead. I also had to merge some of the commits to make the huge changes work. Hope it's not going to be make the review harder.

* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

.trackSearchField form.idleSearchField {
width: 100%;
Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it is needed because otherwise it doesn't contain 100% of the width.

Comment on lines 112 to 115
showProvidedTracks(
searchFilteredGlobalTracks,
searchFilteredLocalTracksByPid
);
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, I guess it's better to move the logic inside the component instead of the thunk action. I mostly did it to follow the current style, but don't mind moving it. Did it.

src/components/timeline/TrackContextMenu.js Show resolved Hide resolved
focus = () => {
// Allow time for React to let the event bubble up. Otherwise clicked button
// will steal the focus.
requestAnimationFrame(() => {
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 don't think there is a difference in terms of the result of both setTimeout or rAF. And there are other use cases in our codebase with rAF, so I wanted to use it. For example:

requestAnimationFrame(() => {
// Restore focus, but not during a React setState call, otherwise this triggers
// a React warning:
// "unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering."
focusAfterClosed.focus();
});

src/profile-logic/tracks.js Show resolved Hide resolved
Copy link
Contributor

@julienw julienw 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 this work, I think this will be a wonderful addition!

I'm approving now because that's mostly nits and comment changes. If you do the change to prevent "enter" from closing the menu, I'd like to see the code again though :-)

Also if you want to ask a review again after the changes, I can also have another look! In that case please do not change the existing commits, and instead add all changes in 1 or more separate commits :-)

Thanks again

src/app-logic/url-handling.js Outdated Show resolved Hide resolved
src/test/components/TrackContextMenu.test.js Show resolved Hide resolved
src/test/components/TrackContextMenu.test.js Outdated Show resolved Hide resolved
src/test/components/TrackContextMenu.test.js Outdated Show resolved Hide resolved
src/components/shared/TrackSearchField.css Outdated Show resolved Hide resolved
src/components/timeline/TrackContextMenu.js Outdated Show resolved Hide resolved
src/components/timeline/TrackContextMenu.js Outdated Show resolved Hide resolved
src/components/timeline/TrackContextMenu.js Outdated Show resolved Hide resolved
src/components/timeline/TrackContextMenu.js Outdated Show resolved Hide resolved
src/components/timeline/TrackContextMenu.js Show resolved Hide resolved
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.

Add a search filter inside the track context menu
3 participants