Merge lp:~benji/launchpad/bug-753152 into lp:launchpad

Proposed by Benji York
Status: Merged
Approved by: Benji York
Approved revision: no longer in the source branch.
Merged at revision: 12828
Proposed branch: lp:~benji/launchpad/bug-753152
Merge into: lp:launchpad
Diff against target: 224 lines (+72/-21)
4 files modified
lib/lp/bugs/browser/tests/test_bug_context_menu.py (+18/-0)
lib/lp/bugs/help/subscription-mute.html (+30/-0)
lib/lp/bugs/javascript/bugtask_index_portlets.js (+17/-17)
lib/lp/bugs/templates/bug-portlet-subscribers.pt (+7/-4)
To merge this branch: bzr merge lp:~benji/launchpad/bug-753152
Reviewer Review Type Date Requested Status
Gary Poster (community) Approve
Review via email: mp+57553@code.launchpad.net

Commit message

[r=gary][bug=753152][no-qa] add a help link to the mute/unmute link

Description of the change

This branch addresses bug 753152 by adding a help link explaining what
mute/unmute does.

Lots of lint was fixed in bugtask_index_portlets.js. The only
substantive change made to that file was this:

     function setup_portlet(transactionid, response, args) {
         hide_spinner();
- var portlet = Y.one('#portlet-subscribers');
- portlet.set('innerHTML',
- portlet.get('innerHTML') + response.responseText);
+ Y.one('#portlet-subscribers')
+ .appendChild(Y.Node.create(response.responseText));

To post a comment you must log in.
Revision history for this message
Gary Poster (gary) wrote :

This is a good fix. As we discussed, it wasn't actually what I intended to bring up in bug 753152, but this direct subscription muting is a parallel problem, and worthy of explaining. The JS lint and innerHTML changes look nice too.

Approved, with the following changes:

 - Move lib/lp/bugs/help/structural-subscription-mute.html to lib/lp/bugs/help/subscription-mute.html or similar.
 - fix typo "abotu"
 - land as incremental fix for the bug (or new bug as you wish) and then make another branch to fix the structural subscription version of the bug.

Thank you,

Gary

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/bugs/browser/tests/test_bug_context_menu.py'
--- lib/lp/bugs/browser/tests/test_bug_context_menu.py 2011-03-09 14:07:35 +0000
+++ lib/lp/bugs/browser/tests/test_bug_context_menu.py 2011-04-13 18:44:47 +0000
@@ -8,16 +8,20 @@
8from zope.component import getUtility8from zope.component import getUtility
99
10from canonical.launchpad.webapp.interfaces import IOpenLaunchBag10from canonical.launchpad.webapp.interfaces import IOpenLaunchBag
11from canonical.launchpad.webapp.servers import LaunchpadTestRequest
11from canonical.testing.layers import DatabaseFunctionalLayer12from canonical.testing.layers import DatabaseFunctionalLayer
1213
13from lp.bugs.browser.bug import BugContextMenu14from lp.bugs.browser.bug import BugContextMenu
14from lp.bugs.enum import BugNotificationLevel15from lp.bugs.enum import BugNotificationLevel
16from lp.services.features import get_relevant_feature_controller
15from lp.testing import (17from lp.testing import (
16 feature_flags,18 feature_flags,
17 person_logged_in,19 person_logged_in,
18 set_feature_flag,20 set_feature_flag,
19 TestCaseWithFactory,21 TestCaseWithFactory,
20 )22 )
23from lp.testing.views import create_initialized_view
24
2125
22class TestBugContextMenu(TestCaseWithFactory):26class TestBugContextMenu(TestCaseWithFactory):
2327
@@ -65,3 +69,17 @@
65 person, person, level=BugNotificationLevel.NOTHING)69 person, person, level=BugNotificationLevel.NOTHING)
66 link = self.context_menu.mute_subscription()70 link = self.context_menu.mute_subscription()
67 self.assertEqual("Unmute bug mail", link.text)71 self.assertEqual("Unmute bug mail", link.text)
72
73 def test_mute_help_available(self):
74 # There is a help link available next to the mute/unmute button.
75 person = self.factory.makePerson()
76 with feature_flags():
77 with person_logged_in(person):
78 self.bug.subscribe(
79 person, person, level=BugNotificationLevel.NOTHING)
80 request = LaunchpadTestRequest()
81 request.features = get_relevant_feature_controller()
82 view = create_initialized_view(
83 self.bug, name="+portlet-subscribers", request=request)
84 html = view.render()
85 self.assertTrue('class="sprite maybe mute-help"' in html)
6886
=== added file 'lib/lp/bugs/help/subscription-mute.html'
--- lib/lp/bugs/help/subscription-mute.html 1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/help/subscription-mute.html 2011-04-13 18:44:47 +0000
@@ -0,0 +1,30 @@
1<html>
2 <head>
3 <title>What happens when I "mute" or "unmute" a bug?</title>
4 <link rel="stylesheet" type="text/css"
5 href="/+icing/yui/cssreset/reset.css" />
6 <link rel="stylesheet" type="text/css"
7 href="/+icing/yui/cssfonts/fonts.css" />
8 <link rel="stylesheet" type="text/css"
9 href="/+icing/yui/cssbase/base.css" />
10 </head>
11 <body>
12 <h1>What happens when I "mute" a bug?</h1>
13
14 <p>
15 You may have a subscription to a bug target that sends email
16 notifications about bug activity. However, you may not be interested in
17 a particular bug. In that case you can "mute" the bug and you will not
18 recieve notifications about it.
19 </p>
20 <p>
21 When "unmuting" a bug you are asked what kinds of messages you would
22 like to recieve about the bug.
23 </p>
24 <p>
25 If you are subscribed via a team, but the team delivers its bug messages
26 via a mailing list or some other preferred email, the mute will not be
27 honored because doing so would prevent the other team members from
28 recieving the notifications.
29 </body>
30</html>
031
=== modified file 'lib/lp/bugs/javascript/bugtask_index_portlets.js'
--- lib/lp/bugs/javascript/bugtask_index_portlets.js 2011-03-24 14:13:45 +0000
+++ lib/lp/bugs/javascript/bugtask_index_portlets.js 2011-04-13 18:44:47 +0000
@@ -84,9 +84,8 @@
8484
85 function setup_portlet(transactionid, response, args) {85 function setup_portlet(transactionid, response, args) {
86 hide_spinner();86 hide_spinner();
87 var portlet = Y.one('#portlet-subscribers');87 Y.one('#portlet-subscribers')
88 portlet.set('innerHTML',88 .appendChild(Y.Node.create(response.responseText));
89 portlet.get('innerHTML') + response.responseText);
9089
91 // Fire a custom portlet loaded event to notify when90 // Fire a custom portlet loaded event to notify when
92 // it's safe to setup subscriber link callbacks.91 // it's safe to setup subscriber link callbacks.
@@ -194,7 +193,7 @@
194 };193 };
195 lp_client.named_post(bug_repr.self_link, 'subscribe', config);194 lp_client.named_post(bug_repr.self_link, 'subscribe', config);
196 });195 });
197}196};
198197
199function load_subscriber_ids() {198function load_subscriber_ids() {
200 function on_success(transactionid, response, args) {199 function on_success(transactionid, response, args) {
@@ -523,7 +522,7 @@
523 var is_dupe;522 var is_dupe;
524 var icon_parent_div = icon_parent.get('parentNode');523 var icon_parent_div = icon_parent.get('parentNode');
525 var dupe_id = 'dupe-' + person.get('css_name');524 var dupe_id = 'dupe-' + person.get('css_name');
526 if (icon_parent_div.get('id') == dupe_id) {525 if (icon_parent_div.get('id') === dupe_id) {
527 is_dupe = true;526 is_dupe = true;
528 } else {527 } else {
529 is_dupe = false;528 is_dupe = false;
@@ -680,8 +679,8 @@
680 subscription_overlay.show();679 subscription_overlay.show();
681 }680 }
682 var config = {681 var config = {
683 on: {success: on_success, failure: on_failure},682 on: {success: on_success, failure: on_failure}
684 }683 };
685 Y.io(subscription_link_url, config);684 Y.io(subscription_link_url, config);
686}685}
687686
@@ -1033,7 +1032,7 @@
1033 var all_subscribers = Y.all('#subscribers-links div');1032 var all_subscribers = Y.all('#subscribers-links div');
1034 if (all_subscribers.size() > 0) {1033 if (all_subscribers.size() > 0) {
1035 all_subscribers.each(function(sub_link) {1034 all_subscribers.each(function(sub_link) {
1036 if (sub_link.getAttribute('id') != 'temp-username') {1035 if (sub_link.getAttribute('id') !== 'temp-username') {
1037 // User's displayname is found via the link's "name"1036 // User's displayname is found via the link's "name"
1038 // attribute.1037 // attribute.
1039 var sub_link_name = sub_link.one('a').getAttribute('name');1038 var sub_link_name = sub_link.one('a').getAttribute('name');
@@ -1077,7 +1076,7 @@
1077 } else if (can_be_unsubscribed) {1076 } else if (can_be_unsubscribed) {
1078 // If the user belongs in the first list, loop the list for position.1077 // If the user belongs in the first list, loop the list for position.
1079 for (i=0; i<unsubscribables.length; i++) {1078 for (i=0; i<unsubscribables.length; i++) {
1080 if (unsubscribables[i] == full_name) {1079 if (unsubscribables[i] === full_name) {
1081 if (i+1 < unsubscribables.length) {1080 if (i+1 < unsubscribables.length) {
1082 return nodes_by_name[unsubscribables[i+1]];1081 return nodes_by_name[unsubscribables[i+1]];
1083 // If the current link should go at the end of the first1082 // If the current link should go at the end of the first
@@ -1092,7 +1091,7 @@
1092 } else if (!can_be_unsubscribed) {1091 } else if (!can_be_unsubscribed) {
1093 // If user belongs in the second list, loop the list for position.1092 // If user belongs in the second list, loop the list for position.
1094 for (i=0; i<not_unsubscribables.length; i++) {1093 for (i=0; i<not_unsubscribables.length; i++) {
1095 if (not_unsubscribables[i] == full_name) {1094 if (not_unsubscribables[i] === full_name) {
1096 if (i+1 < not_unsubscribables.length) {1095 if (i+1 < not_unsubscribables.length) {
1097 return nodes_by_name[not_unsubscribables[i+1]];1096 return nodes_by_name[not_unsubscribables[i+1]];
1098 } else {1097 } else {
@@ -1120,7 +1119,7 @@
11201119
1121 // Strip the domain off. We just want a path.1120 // Strip the domain off. We just want a path.
1122 var host_start = user_uri.indexOf('//');1121 var host_start = user_uri.indexOf('//');
1123 if (host_start != -1) {1122 if (host_start !== -1) {
1124 var host_end = user_uri.indexOf('/', host_start+2);1123 var host_end = user_uri.indexOf('/', host_start+2);
1125 return user_uri.substring(host_end, user_uri.length);1124 return user_uri.substring(host_end, user_uri.length);
1126 }1125 }
@@ -1218,7 +1217,7 @@
1218 form_data['field.bug_notification_level']);1217 form_data['field.bug_notification_level']);
1219 subscribe_current_user(subscription);1218 subscribe_current_user(subscription);
1220 } else if (1219 } else if (
1221 form_data['field.subscription'] == 'update-subscription') {1220 form_data['field.subscription'] === 'update-subscription') {
1222 // The user is already subscribed or is muted and wants to1221 // The user is already subscribed or is muted and wants to
1223 // update their subscription.1222 // update their subscription.
1224 setup_client_and_bug();1223 setup_client_and_bug();
@@ -1235,7 +1234,7 @@
1235 }1234 }
1236 lp_subscription.set(1235 lp_subscription.set(
1237 'bug_notification_level',1236 'bug_notification_level',
1238 form_data['field.bug_notification_level'][0])1237 form_data['field.bug_notification_level'][0]);
1239 save_config = {1238 save_config = {
1240 on: {1239 on: {
1241 success: function(e) {1240 success: function(e) {
@@ -1265,11 +1264,11 @@
1265 anim.run();1264 anim.run();
1266 }1265 }
1267 }1266 }
1268 }1267 };
1269 lp_subscription.lp_save(save_config);1268 lp_subscription.lp_save(save_config);
1270 }1269 }
1271 }1270 }
1272 }1271 };
1273 lp_client.get(subscription_url, config);1272 lp_client.get(subscription_url, config);
1274 } else {1273 } else {
1275 // The user is already subscribed and wants to unsubscribe.1274 // The user is already subscribed and wants to unsubscribe.
@@ -1338,8 +1337,9 @@
1338 on: {1337 on: {
1339 success: function(result) {1338 success: function(result) {
1340 var team_member = false;1339 var team_member = false;
1341 for (var i=0; i<result.entries.length; i++) {1340 var i;
1342 if (result.entries[i].member_link ==1341 for (i=0; i<result.entries.length; i++) {
1342 if (result.entries[i].member_link ===
1343 Y.lp.client.get_absolute_uri(1343 Y.lp.client.get_absolute_uri(
1344 subscription.get(1344 subscription.get(
1345 'subscriber').get('uri'))) {1345 'subscriber').get('uri'))) {
13461346
=== modified file 'lib/lp/bugs/templates/bug-portlet-subscribers.pt'
--- lib/lp/bugs/templates/bug-portlet-subscribers.pt 2011-04-05 17:55:44 +0000
+++ lib/lp/bugs/templates/bug-portlet-subscribers.pt 2011-04-13 18:44:47 +0000
@@ -16,10 +16,13 @@
16 <div tal:condition="request/features/malone.advanced-structural-subscriptions.enabled"16 <div tal:condition="request/features/malone.advanced-structural-subscriptions.enabled"
17 tal:content="structure context_menu/editsubscriptions/render" />17 tal:content="structure context_menu/editsubscriptions/render" />
18 <tal:show-mute condition="view/user_should_see_mute_link">18 <tal:show-mute condition="view/user_should_see_mute_link">
19 <div19 <div tal:attributes="class view/current_user_mute_class">
20 tal:attributes="class view/current_user_mute_class"20 <span tal:replace="structure context_menu/mute_subscription/render"/>
21 tal:content="structure context_menu/mute_subscription/render" />21 <a target="help" class="sprite maybe mute-help"
22 <div id="mute-unmute-spinner">Unmuting...</div>22 href="/+help/subscription-mute.html"
23 >&nbsp;<span class="invisible-link">Mute help</span></a>
24 <div style="float: left" id="mute-unmute-spinner">Unmuting...</div>
25 </div>
23 </tal:show-mute>26 </tal:show-mute>
24 </div>27 </div>
25 <a id="subscribers-ids-link"28 <a id="subscribers-ids-link"