Merge lp:~danilo/launchpad/bug-761257 into lp:launchpad

Proposed by Данило Шеган
Status: Merged
Approved by: Данило Шеган
Approved revision: no longer in the source branch.
Merged at revision: 12909
Proposed branch: lp:~danilo/launchpad/bug-761257
Merge into: lp:launchpad
Diff against target: 167 lines (+86/-26)
2 files modified
lib/lp/bugs/javascript/bug_subscription.js (+10/-4)
lib/lp/bugs/javascript/bugtask_index_portlets.js (+76/-22)
To merge this branch: bzr merge lp:~danilo/launchpad/bug-761257
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code Approve
Review via email: mp+58801@code.launchpad.net

Commit message

[r=bac][bug=761257] Allow teams to be unsubscribed from the advanced subscription overlay.

Description of the change

= Bug 761257 =

Advanced bug subscription overlay UI shows an option to unsubscribe any of the teams that you have privileges for. However, choosing those options doesn't really work.

== Proposed fix ==

We need to factor handle_advanced_subscription_overlay to actually properly handle all the possible cases:
 a. updating existing subscription
 b. unmuting and subscribing with a different notification level
 c. unmuting
 d. unsubscribing teams

Case b. is equivalent to a. and is treated as such, so we've got only a conditional for a/c/d.

== Implementation details ==

I also fixed a very jumpy animation (it always slided out a list of bug notification levels when you had a bug muted), and (not so) accidentally fixed the case of "unmuting" not really allowing to set a bug notification level even if the UI offered it.

== Tests ==

No tests. I am doing a refactoring branch that will include tests for this separately.

== Demo and Q/A ==

https://bugs.launchpad.dev/debian/+source/mozilla-firefox/+bug/3
https://bugs.launchpad.dev/debian/+source/mozilla-firefox/+bug/3/+subscribe

The demo at
  https://devpad.canonical.com/~danilo/screencasts/bug-subscription-advanced.ogv
shows approximatelly what steps need to be taken for proper QA. Refreshing between steps will help ensure you've got the data updated (and not just the UI), and will avoid a bug in existing code that when you get rid of all subscribers, subscribing someone else stops working.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/bugs/javascript/bug_subscription.js
  lib/lp/bugs/javascript/bugtask_index_portlets.js

To post a comment you must log in.
Revision history for this message
Brad Crittenden (bac) wrote :

Hi Danilos thanks for fixing this bug. I'm especially happy since it is one I opened.

On IRC we identified some issues that can be addressed in your follow-on branch:

- In the overlay form, change the value of the teams to have the '/~' prefixed which will prevent any future clashes between valid team names and the other checkbox values in the form.

- Rename and change the description of 'unsubscribe_current_user' to reflect the larger scope of what it is doing. In this case you're using it to unsubscribe a team.

With the promised follow-on branch work this one is ok.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/bugs/javascript/bug_subscription.js'
2--- lib/lp/bugs/javascript/bug_subscription.js 2011-04-19 15:16:58 +0000
3+++ lib/lp/bugs/javascript/bug_subscription.js 2011-04-22 12:29:31 +0000
4@@ -42,13 +42,19 @@
5 visibility: 'visible'
6 });
7 });
8+ var checked_box = subscription_radio_buttons.filter(':checked').pop();
9+ var current_value = checked_box.get('value');
10 slide_in_anim.run();
11 Y.each(subscription_radio_buttons, function(subscription_button) {
12 subscription_button.on('click', function(e) {
13- if(e.target.get('value') === 'update-subscription') {
14- slide_out_anim.run();
15- } else {
16- slide_in_anim.run();
17+ var value = e.target.get('value');
18+ if (value !== current_value) {
19+ if(value === 'update-subscription') {
20+ slide_out_anim.run();
21+ } else {
22+ slide_in_anim.run();
23+ }
24+ current_value = value;
25 }
26 });
27 });
28
29=== modified file 'lib/lp/bugs/javascript/bugtask_index_portlets.js'
30--- lib/lp/bugs/javascript/bugtask_index_portlets.js 2011-04-14 16:37:22 +0000
31+++ lib/lp/bugs/javascript/bugtask_index_portlets.js 2011-04-22 12:29:31 +0000
32@@ -379,6 +379,30 @@
33 return subscription;
34 }
35
36+
37+/*
38+ * Set up and return a Subscription object for the team subscription
39+ * link.
40+ */
41+function get_team_subscription(team_uri) {
42+ setup_client_and_bug();
43+ var subscription = new Y.lp.bugs.subscriber.Subscription({
44+ link: Y.one('.menu-link-subscription'),
45+ spinner: Y.one('#sub-unsub-spinner'),
46+ subscriber: new Y.lp.bugs.subscriber.Subscriber({
47+ uri: team_uri,
48+ subscriber_ids: subscriber_ids
49+ })
50+ });
51+
52+ subscription.set('is_direct', true);
53+ subscription.set('has_dupes', false);
54+ subscription.set('can_be_unsubscribed', true);
55+ subscription.set('person', subscription.get('subscriber'));
56+ subscription.set('is_team', true);
57+ return subscription;
58+}
59+
60 /*
61 * Initialize callbacks for subscribe/unsubscribe links.
62 *
63@@ -777,6 +801,8 @@
64 Y.lp.app.errors.display_error(subscription_link, error_msg);
65 };
66
67+ var subscriber_link = Y.lp.client.get_absolute_uri(
68+ subscriber.get('escaped_uri'));
69 var config = {
70 on: {
71 success: function(client) {
72@@ -815,9 +841,11 @@
73 },
74
75 failure: error_handler.getFailureHandler()
76- }
77+ },
78+
79+ parameters: { person: subscriber_link }
80 };
81- if (subscription.is_direct_subscription()) {
82+ if (subscription.is_direct_subscription() || subscription.is_team()) {
83 lp_client.named_post(bug_repr.self_link, 'unsubscribe', config);
84 } else {
85 lp_client.named_post(
86@@ -1211,22 +1239,36 @@
87 * @param form_data {Object} The data from the submitted form.
88 */
89 function handle_advanced_subscription_overlay(form_data) {
90- var subscription = get_subscribe_self_subscription();
91+ var subscription;
92+ var mute_subscription = get_mute_subscription();
93+ var is_muted = (!Y.Lang.isNull(mute_subscription) &&
94+ mute_subscription.get('is_muted'));
95+ var requested_subscriber;
96+ var request_for_self = false;
97+ // XXX Danilo 20110422: this is a very lousy "special string"
98+ // that will make it break for a team/person named 'update-subscription'.
99+ // We should probably use special characters not allowed in team names
100+ // (maybe all-uppercase would work).
101+ var UPDATE_ACTION = 'update-subscription';
102+
103+ if (form_data['field.subscription'][0] === UPDATE_ACTION) {
104+ requested_subscriber = LP.links.me;
105+ request_for_self = true;
106+ } else {
107+ requested_subscriber = '/~' + form_data['field.subscription'][0];
108+ if (requested_subscriber === LP.links.me) {
109+ request_for_self = true;
110+ }
111+ }
112+ if (request_for_self) {
113+ subscription = get_subscribe_self_subscription();
114+ } else {
115+ subscription = get_team_subscription(requested_subscriber);
116+ }
117 var link = subscription.get('link');
118 var link_parent = link.get('parentNode');
119- var mute_subscription = get_mute_subscription();
120- var is_muted = (!Y.Lang.isNull(mute_subscription) &&
121- mute_subscription.get('is_muted'));
122- if (link_parent.hasClass('subscribed-false') &&
123- link_parent.hasClass('dup-subscribed-false') &&
124- !is_muted) {
125- // The user isn't subscribed or muted, so subscribe them.
126- subscription.set(
127- 'bug_notification_level',
128- form_data['field.bug_notification_level']);
129- subscribe_current_user(subscription);
130- } else if (
131- form_data['field.subscription'] === 'update-subscription') {
132+
133+ if (form_data['field.subscription'][0] === UPDATE_ACTION) {
134 // The user is already subscribed or is muted and wants to
135 // update their subscription.
136 setup_client_and_bug();
137@@ -1279,13 +1321,25 @@
138 }
139 };
140 lp_client.get(subscription_url, config);
141+
142+ } else if (link_parent.hasClass('subscribed-false') &&
143+ link_parent.hasClass('dup-subscribed-false') &&
144+ !is_muted && request_for_self) {
145+ // The user isn't subscribed or muted, and the request is
146+ // for himself (iow, not for a team).
147+ subscription.set(
148+ 'bug_notification_level',
149+ form_data['field.bug_notification_level']);
150+ subscribe_current_user(subscription);
151+ } else if (is_muted && request_for_self) {
152+ // When a person has a bug muted, we show 2+ options:
153+ // a. unmute, b. unmute and subscribe, c. unsubscribe team1...
154+ // "b" is treated as 'update-subscription' case, and for any
155+ // of the teams, request_for_self won't be true.
156+ unmute_current_user(mute_subscription);
157 } else {
158- // The user is already subscribed and wants to unsubscribe.
159- if (is_muted) {
160- unmute_current_user(mute_subscription);
161- } else {
162- unsubscribe_current_user(subscription);
163- }
164+ // Unsubscribe this person/team.
165+ unsubscribe_current_user(subscription);
166 }
167 }
168