Merge lp:~wallyworld/launchpad/picker-wiring-812255 into lp:launchpad
Status: | Merged |
---|---|
Approved by: | Curtis Hovey |
Approved revision: | no longer in the source branch. |
Merged at revision: | 13532 |
Proposed branch: | lp:~wallyworld/launchpad/picker-wiring-812255 |
Merge into: | lp:launchpad |
Diff against target: | 0 lines |
To merge this branch: | bzr merge lp:~wallyworld/launchpad/picker-wiring-812255 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Curtis Hovey (community) | code | Approve | |
Review via email:
|
Commit message
[r=sinzui][bug=812255,812257] Fix person picker "Assign me" and "Remove" link behaviour and add test coverage.
Description of the change
This branch fixes a few picker bugs as well as performing as significant refactor and adding extra yui test coverage for person pickers.
Bugs 812255 and 812257 were the main focus but work was also done to implement a better fix for bug 798778 (which was previously closed).
A previously implemented hack to control the creation of the new PersonPicker widget was also removed.
== Implementation ==
There are 2 ways of instantiating a picker:
Y.lp.app.
Y.lp.app.
The first way is used to create a picker invoked from the little yellow edit icon; the second way creates a picker from the Choose... link.
The root cause of the bugs was that code existed in the addPickerPatcher() method to wire up the "Assign me" and "Remove" links. This code was different from that used by the create() method and so if a PersonPicker was instantiated using create(), things weren't wired up properly. Besides all that, the code in question implements functionality which really does belong in the PersonPicker implementation.
The main work involved:
- moving the code for the "Assign Me" and "Remove" links to the PersonPicker
- add a picker_type property to the picker view classes to allow the Javascript hack to be removed
- add a new "selected_value" attribute to the core Picker widget
- control the rendering of the "Assign me" and "Remove" links based on this new selected_value attribute
- use an onChange event handler for the new "selected_value" attribute to update the links when the user makes a new selection using the picker
- delete unnecessary and improperly placed code by removing config for the "Assign me" and "Remove" links from the core picker implementation
The use of the selected_value attribute removes the need to "screen scrape" to read the picker value from the associated form widget and is a much cleaner implementation.
Bug 798778 was previously fixed by hiding the "Assign me" and "Remove" links when a search was done. This was not the best approach, in part because once a search was done, the "Remove" link was made invisible and could *never* be accessed again without a page refresh. The solution in this branch is to move the "Assign me" and "Remove" links above the search box - this separates them from the search results as requested in the bug and avoids the issues with the current solution.
When the picker is created using the Choose... link, the "Remove" link is hidden. It adds little value in this case since all that needs to be done is to clear the associated text field, and having the "Remove" link is not clear as to exactly what it does in this case.
== Tests ==
Relevant tests for the "Assign me" and "Remove links" were moved from test_picker_
YUI tests run:
test_picker.js
test_
test_
In the absence of windmill tests, bug task assigning, branch reviewer editing, and recipe owner editing were tested by hand - these use cases cover the different application scenarios where a person picker is used.
== Lint ==
Linting changed files:
lib/canonical
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
./lib/lp/
13: 'PersonPicker' has not been fully defined yet.
81: Expected '!==' and instead saw '!='.
83: Expected '===' and instead saw '=='.
84: Expected '===' and instead saw '=='.
./lib/lp/
67: 'Picker' has not been fully defined yet.
258: Move 'var' declarations to the top of the function.
258: Stopping. (24% scanned).
-1: JSLINT had a fatal error.
598: Line exceeds 78 characters.
./lib/lp/
70: Expected '!==' and instead saw '!='.
355: Expected '!==' and instead saw '!='.
./lib/lp/
344: Expected '!==' and instead saw '!='.
./lib/lp/
196: Move 'var' declarations to the top of the function.
196: Stopping. (20% scanned).
-1: JSLINT had a fatal error.
49: Line exceeds 78 characters.
465: Line exceeds 78 characters.
516: Line exceeds 78 characters.
960: Line exceeds 78 characters.
./lib/lp/
839: Expected '===' and instead saw '=='.
I take lint issues seriously. I fixed a few null-undefined issues that were masked by !=/==. Lint also failed to complete the check of some files because it hates the definition of a var in a for-loop.
> === modified file 'lib/lp/ app/browser/ lazrjs. py' app/browser/ lazrjs. py 2011-07-18 00:45:28 +0000 app/browser/ lazrjs. py 2011-07-21 05:12:40 +0000 value(self) : self.context, self.exported_ field._ _name__ )
> --- lib/lp/
> +++ lib/lp/
...
> @@ -283,20 +275,35 @@
...
> @property
> + def selected_
> + """ String representation of field value associated with the picker.
> +
> + Default implementation is to return the 'name' attribute.
> + """
> + val = getattr(
> + if val is not None and hasattr(val, 'name'):
Use safe_hasattr which will honour keyboard and system interrupts. lazr.utils import safe_hasattr
from canonical.
=== modified file 'lib/lp/ app/javascript/ picker/ person_ picker. js' app/javascript/ picker/ person_ picker. js 2011-07-19 03:27:34 +0000 app/javascript/ picker/ person_ picker. js 2011-07-21 05:12:40 +0000
--- lib/lp/
+++ lib/lp/
> @@ -59,13 +58,50 @@ r.superclass. show.call( this); button_ text: function() { person_ text; 'selected_ value_metadata' ) === 'team') { team_text; button. set('text' , link_text); 'selected_ value') ; button) { button. addClass( 'yui3-picker- hidden' ); button. removeClass( 'yui3-picker- hidden' ); button_ text(); me_button) {
> this.constructo
> },
>
> + _update_
> + var link_text = this._remove_
> + if (this.get(
> + link_text = this._remove_
> + }
> + this.remove_
> + },
> +
> + _show_hide_buttons: function () {
> + var selected_value = this.get(
> + if (this.remove_
> + if (selected_value === null) {
> + this.remove_
> + } else {
> + this.remove_
> + this._update_
> + }
> + }
> +
> + if (this.assign_
> + if ((selected_value != null
This looks like one of the lint issue reported. We do not use coercive
operators. You many want to write this as
if ((selected_value
> + && LP.links. me.match( '~'+selected_ value + "$")
> + == '~'+selected_value)
use space between the operators.
> === modified file 'lib/lp/ app/javascript/ picker/ picker. js' app/javascript/ picker/ picker. js 2011-07-19 15:16:37 +0000 app/javascript/ picker/ picker. js 2011-07-21 05:12:40 +0000 'save', function (e) { Picker. SAVE_RESULT] ; 'host') .set(SELECTED_ VALUE_METADATA, result.metadata); 'host') .set(SELECTED_ VALUE, result.value);
> --- lib/lp/
> +++ lib/lp/
...
> @@ -1016,16 +1041,24 @@
> this.doAfter(
> var result = e.details[
> this.get(
> - input.set("value", result.value);
> + this.get(
> + if (result.value != null) {
Do you mean null? Can this be undefined? I think link reported this issue.
since I think we want a value below, may Y.Lang.isValue is better?
> + input.set("value", result.value);
> + } else {
> + input.set("value", '');
> + }
We do not see this form very often in Lp code, but it avoids ...