Add auto-complete functionality to the Depends On field
Review Request #8434 — Created Sept. 24, 2016 and submitted
For the ReviewRequestEditorView page:
Goal: To add autocomplete functionality to the Depends On field.This was accomplished by:
Implementing basic autocomplete to the depends on field.
Implementing autocomplete to use the search api.
Properly determining correct data from search results.
Formatting and Displaying correct data to the correct field.
- Verified results using existing autocomplete tests
- Added additional tests to verify dependson results
- Verify existence of autocomplete
- Verify autocomplete results
- Addionally tested by hand:
- Id and Summary tested for Depends On
Description | From | Last Updated |
---|---|---|
One comment I've seen repeated is that our request description should kind've "tell a story" with respect to the project. … |
RS rswanson | |
Can you rewrite your summary in the imperitive mood? i.e, "Add auto-complete functionality to the Depends On field" |
brennie | |
Can you add screenshots? |
brennie | |
Looking at the code now, I think we can make a major simplification. Right now, we have two iterations over … |
david | |
This is a good time to ask, if we can leave comments in a request. I think they should be … |
LA larmiej | |
this can use the operator "===" for extra security |
LA larmiej | |
if changing the operator to "===" is okay with you |
LA larmiej | |
Fix indentation. |
brennie | |
Can you remove the spacing between the parentheses? |
brennie | |
Undo this change. |
brennie | |
This can be a one line comment. I'm not sure if its necessary, though. |
brennie | |
Undo this. |
brennie | |
Is this intentional? |
brennie | |
space after colon |
brennie | |
Undo this. |
brennie | |
Undo this. |
brennie | |
Undo this. |
brennie | |
Undo this. |
brennie | |
Remove this line. |
brennie | |
Undo this. |
brennie | |
Undo this. |
brennie | |
Remove this line. |
brennie | |
Is this still WIP |
brennie | |
This file is all third-party code. I don't think we want to make any style fixes in here, and even … |
david | |
It's probably a little silly to define two new variables when these are only used once. In fact, this whole … |
david | |
Please undo this change. |
david | |
What are these changes? |
david | |
It's okay to explicitly compare against true in cases where this could take other falsy values, but we should at … |
david | |
The var statement should be the first thing in the function body. |
david | |
In es5 code (which this is, since we haven't yet ported it to es6), the var statement should be the … |
david | |
There's still a bunch of style changes in this file which are obscuring your functional changes. Please go through until … |
david | |
Multi-line comments should use /* ... */. |
david | |
Trailing whitespace. |
david | |
Braces. |
brennie | |
Prefer: var data; if (!options.matchCase && typeof term === 'string') { term = term.toLowerCase(); } data = cache.load(term); We want … |
brennie | |
!==, 'string' |
brennie | |
blank line. |
brennie | |
This needn't be two conditions: if (options.fieldName === 'review_requests' && !data.public) { return false; } |
brennie | |
I'm not sure I'm comfortable with this here. The code using autocomplete should be the one responsible for supplying strings. |
chipx86 | |
Similarly here. I don't think we should be enforcing strings here. |
chipx86 | |
No space after function. |
chipx86 | |
A couple of stylistic comments: * Must be 4 space indentation. * The if line is too long. Lines should … |
chipx86 | |
Variables with values should come before variables without. |
chipx86 | |
We don't want to have field-specific logic here. Instead, we want the code registering a field to be able to … |
chipx86 | |
No space after function. |
chipx86 | |
Instead of $($field.children()[0]), you can do $field.children().eq(0), etc. Also, we should fetch $field.children() only once. |
chipx86 | |
A few things here. First, javascript variables should be camelCase. Secondly, combine this into one var statement: var unwrappedData = … |
brennie | |
We always use /* block comments */. |
brennie | |
['public'] as public is a reserved word and will break in IE. |
brennie | |
i-- |
brennie | |
Reformat as: unwrappedData[i].id = unwrappedData[i] .id .toString(); |
brennie | |
No trailing comma (will break IE) |
brennie | |
We don't need to add this. We should be setting display_name for the results instead in the caller. |
chipx86 | |
Space after : |
chipx86 | |
This function can be written much more simply: function(data, options) { return data.search[options.fieldName] .filter(function(datum) { return !datum['public']; }) .map(function(datum) { … |
brennie | |
We should never have private reviews here, under any circumstances. The API must return only public results. |
chipx86 | |
We access unwrappedData[i] a lot. let's pull that out once. |
chipx86 | |
if (!unwrappedData[i]['public']) { |
brennie | |
Once unwrappedData[i] is pulled out, this can/should be one line. |
chipx86 | |
Shouldn't this be return unwrappedData? |
david | |
Indentation is still wrong. |
chipx86 | |
We shouldn't be touching this code. Only the new field should be modified. |
chipx86 | |
Same here. |
chipx86 | |
You got rid of itemsLen. There's no way this code works. Please make sure this is all very properly tested. |
chipx86 | |
Can we pull out unwrappedData[i] into another variable, say datum and use that here? |
brennie | |
Can we call it item instead of value? |
brennie | |
I don't think this extra level of nesting is required. You're not adding beforeEach or afterEach. |
brennie | |
Indentation is off by 1 space for the for loop here. |
david | |
Your indentation is still funky here (the for loop and everything in it needs to be indented 1 more space). |
david | |
One nice way to clean this up would be to make it so options.fieldName could be either a function or … |
david |
-
Tool: PEP8 Style Checker Processed Files: reviewboard/webapi/resources/search.py Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/lib/js/ui.autocomplete.js Tool: Pyflakes Processed Files: reviewboard/webapi/resources/search.py Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/lib/js/ui.autocomplete.js
- Description:
-
Added partially working autocomplete to depends on field.
Switched user and group autocomplete to use search api. ~ Modified autocomplete to handle integer inputs for review ids ~ Modified autocomplete to handle integer inputs for review ids + Modified autocomplete to handle text inputs for review summaries.
- Description:
-
~ Added partially working autocomplete to depends on field.
~ Switched user and group autocomplete to use search api. ~ Modified autocomplete to handle integer inputs for review ids ~ Modified autocomplete to handle text inputs for review summaries. ~ For the ReviewRequestEditorView page:
~ Goal: To add autocomplete functionality to the Depends On field. ~ Secondary Goal: To implement search api for Groups and People. ~ + This was accomplished by:
+ Implementing basic autocomplete to the depends on field. + Redirecting existing autocompletes to use the search api. + Properly determining correct data from search results. + Formatting and Displaying correct data to the correct field. - Testing Done:
-
+ -Verified results using existing autocomplete tests
+ -Added additional tests to verify dependson results + -Verify existence of autocomplete + -Verify autocomplete results + -Addionally tested by hand + -Username, firstname, lastname and full name tested for users + -Group name and group creator tested for Groups + -Id and Summary tested for Depends On - Commit:
-
0590ba12fe3f09ce5d45a6911ede292256716937d01dd9b52f3c0b389f92f7e2b1ecb6913d920200
-
Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
- Change Summary:
-
Fixing formatting issues.
- Commit:
-
d01dd9b52f3c0b389f92f7e2b1ecb6913d920200fdd937bd15e288a45e97188d4099db1271a83d56
- Diff:
-
Revision 4 (+205 -119)
- Added Files:
-
Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
- Change Summary:
-
Fixed summary and added screenshot.
- Summary:
-
Adding autocomplete functionality to Depends On field.Add auto-complete functionality to the Depends On field
- Description:
-
For the ReviewRequestEditorView page:
Goal: To add autocomplete functionality to the Depends On field. ~ Secondary Goal: To implement search api for Groups and People. ~ Secondary Goal: To implement search api for Groups and People fields. This was accomplished by:
Implementing basic autocomplete to the depends on field. Redirecting existing autocompletes to use the search api. Properly determining correct data from search results. Formatting and Displaying correct data to the correct field. - Added Files:
-
-
This file is all third-party code. I don't think we want to make any style fixes in here, and even if we did, they should be in a separate change so they don't obscure the few changes you did make to the code.
That said, I don't think any changes should be required in here. If they are, we definitely need to look at them closely.
-
It's probably a little silly to define two new variables when these are only used once. In fact, this whole function could be:
cmp: function(term, a, b) { return b.data.id - a.data.id; }
-
-
-
It's okay to explicitly compare against
true
in cases where this could take other falsy values, but we should at least use!==
instead of!=
because!=
will implicitly cast, which makes the explicit comparison moot. -
-
In es5 code (which this is, since we haven't yet ported it to es6), the
var
statement should be the first thing in the function. That means we need to postpone the assignment of a few of these:var parsed = [], items, value, i; if (options.resourceName === 'search') { data = data.search; } items = data[options.fieldName]; for (i = 0; i < items.length; i++) { ... }
Note that I've removed the kind of useless
itemsLen
variable. I'd also like the "search" special case to be commented explaining why it's there.
- Change Summary:
-
Reverted changes where bracket spaces were removed. Fixed extra/missing whitespaces. Moved var assignments to follow es5. Simplified if statement. Removed extra events.
- Commit:
-
fdd937bd15e288a45e97188d4099db1271a83d568c036fde9bad1bb0b4aeb86afc9953cb71185a55
-
Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
- Change Summary:
-
Removed extra blank lines
- Commit:
-
8c036fde9bad1bb0b4aeb86afc9953cb71185a554dfa0bc1cebbc31f7a8b19b7ee688233cf436450
-
Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
- Change Summary:
-
Reverted other style changes.
- Commit:
-
4dfa0bc1cebbc31f7a8b19b7ee688233cf436450b6308bfbb08294fd3efd43b8fa5da22fdb55675c
-
Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
- Change Summary:
-
Small fixes, fixed markdown style.
- Testing Done:
-
~ -Verified results using existing autocomplete tests
~ -Added additional tests to verify dependson results ~ -Verify existence of autocomplete ~ - Verified results using existing autocomplete tests
~ - Added additional tests to verify dependson results
- Verify existence of autocomplete
- Verify autocomplete results
~ - Addionally tested by hand:
- Username, firstname, lastname and full name tested for users
- Group name and group creator tested for Groups
- Id and Summary tested for Depends On
- -Verify autocomplete results - -Addionally tested by hand - -Username, firstname, lastname and full name tested for users - -Group name and group creator tested for Groups - -Id and Summary tested for Depends On - Commit:
-
b6308bfbb08294fd3efd43b8fa5da22fdb55675c0091bdcb7fcc233d37d2411380d54f19459d2109
-
Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
- Change Summary:
-
Removed extra whitespace
- Commit:
-
0091bdcb7fcc233d37d2411380d54f19459d210968165e86e36ab9daf3ae87b9103a3557c787d0c2
-
Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
-
Good job so far. My biggest concern is that there are changes made that are too global.
I'm not sure you need to make any modifications to
ui.autocomplete.js
. Instead, the code working with the autocomplete widget should be responsible for returning the appropriate data types. By casting to a string, you can alter behavior that might conceivably exist in other use cases, and make it harder to eventually move away from this widget (as the data type casting behavior is "hidden" from the caller's code).I also have some suggestions for the
if
checks in the autocomplete invocation inreviewRequestEditorView.js
, intended to keep from adding field-specific behavior here (fields are pluggable and we don't want to hard-code things if we can help it). -
I'm not sure I'm comfortable with this here. The code using autocomplete should be the one responsible for supplying strings.
-
-
-
A couple of stylistic comments: * Must be 4 space indentation. * The
if
line is too long. Lines should not exceed 79 characters. This should wrap after&&
.The bigger thing is that this begins a precedent of field-specific logic in here. We don't want that. Fields are pluggable, and we want extensions to be able to provide their own fields.
In this particular case, what we're saying is "hide any private review requests." We shouldn't even be getting these in the result to begin with. What you instead need to do is modify the API request to exclude any private review requests for this field, so they never come through to begin with. We can then safely display anything that we get back.
This is very important. Imagine if we only get 20 results back and the first 18 are private. That'd mean we only get 2 public review requests to display, instead of 20. That'd be a confusing experience.
-
-
We don't want to have field-specific logic here. Instead, we want the code registering a field to be able to parse the result.
If you look at
registerField
, you'll see where fields get registered. There's an option (which sadly is not documented there, but you can see usage insetupFieldEditor
) that indicates if autocomplete behavior should be used. This is a dictionary of things likefieldName
,nameKey
, etc.What I'd recommend is adding another optional thing in that dictionary:
parseResultList
. This would be a function that takes thedata
and return the list of items. If that exists in the dictionary, it'd be called, and if not, the defaultitems = data[options.fieldName]
would be used.Then the Depends On handler could provide its own implementation, removing the hard-coded support for
data.search
. -
-
Instead of
$($field.children()[0])
, you can do$field.children().eq(0)
, etc.Also, we should fetch
$field.children()
only once.
- Change Summary:
-
Reverted most changes to ui.autocomplete.js and instead implemented a parseResultList optional field to handle the results from using the search api and to allow custom fields.
- Commit:
-
68165e86e36ab9daf3ae87b9103a3557c787d0c23790e76526d9840cae06a3125b95bcf0fa257b84
-
Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
-
-
A few things here.
First, javascript variables should be
camelCase
.Secondly, combine this into one
var
statement:var unwrappedData = data.search[options.fieldName], i;
(because of
var
hoisting) -
-
-
-
-
- Change Summary:
-
Fixes for IE and formatting.
- Commit:
-
3790e76526d9840cae06a3125b95bcf0fa257b84b9a5e896084369cd41eba7e22355ee9a223b7a7a
-
Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
- Change Summary:
-
Removed all changes from ui.autocomplete.js.
Added display_name to parseResultsList. - Commit:
-
b9a5e896084369cd41eba7e22355ee9a223b7a7a264f90c88a4b0dcf425c146ee00a1abc7a947cb4
-
Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/reviewRequestEditorView.js reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/lib/js/ui.autocomplete.js
- Change Summary:
-
White space fix.
- Commit:
-
264f90c88a4b0dcf425c146ee00a1abc7a947cb4a50032f63661a7894d3a286ac79037f0e7c244e8
-
Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/rb/js/views/reviewRequestEditorView.js Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/rb/js/views/reviewRequestEditorView.js
- Change Summary:
-
Style Fixes
- Commit:
-
a50032f63661a7894d3a286ac79037f0e7c244e8fb97709d76741b22e30cf384cbf368dca04c34ee
-
Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/rb/js/views/reviewRequestEditorView.js Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/rb/js/views/reviewRequestEditorView.js
-
-
Looking at the code now, I think we can make a major simplification.
Right now, we have two iterations over the list of items--one in
parseResultList
, and one inparse
. A simpler approach would be to have an optionalparseItem
method which would modify an individual item in the results, looking something like:parseItem: function(item) { item.id = item.id.toString(); item.display_name = item.summary; return item; }
Inside parse, you'd then do something like:
for (i = 0; i < items.length; i++) { item = items[i]; if (options.parseItem) { item = options.parseItem(item); } parsed.push({ ... }); }
-
Your indentation is still funky here (the for loop and everything in it needs to be indented 1 more space).
- Change Summary:
-
Removed parseResultsList and replaced it with parseItem and formatData for efficiency.
- Commit:
-
fb97709d76741b22e30cf384cbf368dca04c34eeec40eb0a6552d1331918c30fa02ec33b66fd7b03
-
Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/rb/js/views/reviewRequestEditorView.js Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/rb/js/views/reviewRequestEditorView.js
- Change Summary:
-
Updated description to properly reflect changes
- Description:
-
For the ReviewRequestEditorView page:
~ Goal: To add autocomplete functionality to the Depends On field. ~ Goal: To add autocomplete functionality to the Depends On field. - Secondary Goal: To implement search api for Groups and People fields. This was accomplished by:
Implementing basic autocomplete to the depends on field. ~ Redirecting existing autocompletes to use the search api. ~ Implementing autocomplete to use the search api. Properly determining correct data from search results. Formatting and Displaying correct data to the correct field. - Testing Done:
-
- Verified results using existing autocomplete tests
- Added additional tests to verify dependson results
- Verify existence of autocomplete
- Verify autocomplete results
~ - Addionally tested by hand:
- Username, firstname, lastname and full name tested for users
- Group name and group creator tested for Groups
- Id and Summary tested for Depends On
~ - Addionally tested by hand:
- Id and Summary tested for Depends On
-
-
One nice way to clean this up would be to make it so
options.fieldName
could be either a function or an actual field name. This would then be:if (_.isFunction(options.fieldName)) { items = options.fieldName(data); } else { items = data[options.fieldName]; }
and the
fieldName
for the depends_on field would be:fieldName: function(data) { return data.search.review_requests; }
That way we don't have to have both
fieldName
and the newformatData
function.
- Change Summary:
-
Moved formatData functionality to fieldName
- Commit:
-
ec40eb0a6552d1331918c30fa02ec33b66fd7b033aee79d43551223070d90cb7a8b43298c9dbc171
-
Tool: PEP8 Style Checker Ignored Files: reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/rb/js/views/reviewRequestEditorView.js Tool: Pyflakes Ignored Files: reviewboard/static/rb/js/views/tests/reviewRequestEditorViewTests.js reviewboard/static/rb/js/views/reviewRequestEditorView.js