Keep QuickOpenModal resultCount in bounds #8134
Keep QuickOpenModal resultCount in bounds #8134
Conversation
So I think the fix to use depends on if we want to use a result count of more than the limit (100) to do some computations and/or show in the interface. For instance, do we want to show "172 results" somewhere in the UI, even though we only show and give access to the first 100 results? Option 1: slice results in stateIf we're okay with clipping to 100 for all intents and purposes, the simpler fix would be to clip the results before we add them to the component's state, here: debugger/src/components/QuickOpenModal.js Line 124 in 94b063e
Basically changing this.setState({ results: results.slice(0, maxResults) }); And removing the corresponding code in debugger/src/components/QuickOpenModal.js Line 377 in 94b063e
Option 2: keep full results in stateNow if we want to keep the full results array in the component's state but make calculations against its length or the limit, whichever is smallest, then the technique you used is alright. In that scenario, we definitely need a single Nitpick: you can probably simplify your condition a bit by using Math.min: const resultCount = Math.min(this.getResultCount(), maxResults); |
Thank you @jasonLaster and @fvsch. I had the same question about whether the full results were needed elsewhere in the UI. Your suggestions make a lot of sense. I'm happy to go either direction depending on what's needed. As an additional option, my first instinct was a simple change of maxResults (set in the filter function, line 75) from 1000 to 100.
This solved the problem, and I thought was much cleaner than my initial solution, but it failed three tests that rely on maxResults: 1000 ... QuickOpenModal.spec.js - lines 212, 233, 260. If only 100 results are ever needed, the filter could be set at 100, the tests run with maxResults: 100, and all other behavior/tests work as expected. |
@fvsch and @jasonLaster great suggestions! I've got three workable solutions based on your advice. Keep Full Results In State
Slice Results In State searchSources: (line 120)
render: (line 378)
render: (line 401)
Limit Results In Filter filter function: (line 72)
I feel like if we want to clip all results, changing Thanks for all your help! |
Given that it's a "quick open" feature, not "what's the exact count of sources that match this query" feature, I believe we should just limit the number of results we deal with. Can you try the "Limit Results In Filter" approach? |
I think I agree with @fvsch on that we should just limit the results returned from the searchSymbols = (query: string) => {
const {
symbols: { functions }
} = this.props;
let results = functions;
results = results.filter(result => result.title !== "anonymous");
if (query === "@" || query === "#") {
return this.setState({ results }); <--- this could be more than 100 results
}
this.setState({ results: filter(results, query.slice(1)) }); <--- If the query is not empty it will use filter
}; I'll include a reproduction of that.
Great work so far @arosenfeld2003 - you are asking great questions. I like the filter approach, but I think there are just a few cases that doesn't cover that we should watch out for. |
@WenInCode, great catch. The edge case above can be handled by slicing results in the searchSymbols method: searchSymbols = (query: string) => { const { symbols: { functions } } = this.props; let results = functions; results = results .filter(result => result.title !== "anonymous") .slice(0, 100); if (query === "@" || query === "#") { return this.setState({ results }); } this.setState({ results: filter(results, query.slice(1)) }); }; This seems straightforward, and passes all jest tests locally. I found four methods in QuickOpenModal where Otherwise, I'm happy to amend my PR with the above changes if you think they are agreeable? Thank you again for all your help @WenInCode , @fvsch, @jasonLaster. |
@arosenfeld2003 seems good to me 👌 |
Sounds like a good approach. If we're doing |
Good suggestion @fvsch. I think it's ok for now, since we don't actually have to call To catch the edge case above with an empty symbol query, we can slice before searchSymbols = (query: string) => { const { symbols: { functions } } = this.props; let results = functions; results = results .filter(result => result.title !== "anonymous") .slice(0, 100); if (query === "@" || query === "#") { return this.setState({ results }); } this.setState({ results: filter(results, query.slice(1)) }); }; In showTopSources, we set this.setState({ results: sources.slice(0, 100) }) All the help is much appreciated! |
I'm hoping this is now good to go? Please let me know if anything else is needed. Thanks again. |
Two things:
setResults = (results) => {
if (Array.isArray(results) && results.length > maxResults) {
results = results.slice(0, maxResults);
}
this.setState({ results })
} |
Thanks so much for the detailed suggestions @fvsch! I now understand what you mean. I think I've got a good solution that creates/calls a I did get a Flow(InferError) Unfortunately this is also causing a failed CI. I tried to determine the cause, but after investigation I'm not quite sure what direction to go. I thought that the type for results was being set here:
I would definitely appreciate a nudge in the right direction here... Thank you again for all your time, @fvsch, @WenInCode, @jasonLaster. |
Are you familiar with Flow type annotations? You can read up on them here. I think here you need to tell Flow that |
Wow, this looks great @arosenfeld2003 ! Just a quick rebase and it'll be good to merge! |
42b45d3
to
5326f5e
Compare
Thank you all so much @fvsch @WenInCode @jasonLaster @darkwing ... did a rebase, hopefully it's good to go. |
Hello @arosenfeld2003! I fixed our CI (Travis) so one more quick rebase and this will be super green! :) |
087249a
to
8eb92ef
Compare
@darkwing just checking if I need to do anything further here? Thanks again for your help! |
Excellent, thank you @arosenfeld2003 ! |
Fixes #8119
Here's the Pull Request Doc
https://firefox-dev.tools/debugger/docs/pull-requests.html
Summary of Changes
Added a conditional to keep resultCount (number returned from getResultCount) at 100 or less.
This is contained in the traverseResults method, within QuickOpenModal.js.
Test Plan
Tested behavior based upon expected behavior described by @fvsch.
Example test plan:
Screenshots/Videos (OPTIONAL)
This is my first code PR, so greatly appreciate any and all feedback.
Sorry for the extraneous commits (issues with git).
Thanks!