launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #17963
[Merge] lp:~thomir/launchpad/devel-fix-editemails-link into lp:launchpad
Thomi Richards has proposed merging lp:~thomir/launchpad/devel-fix-editemails-link into lp:launchpad.
Commit message:
Add new page to manage mailing list subscriptions.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~thomir/launchpad/devel-fix-editemails-link/+merge/251176
This branch splits the +editemails page in 'twain:
* +editemails continues to be the place to add email addresses to an account, and to configure your preferred contact address. It requires a fresh login, since this is changing your login credentials.
* +editmailinglists is a new page which allows you to configure the mailing lists you're subscribed to, as well as set your mailing list auto-subscribe policy.
This branch fixes two bugs:
https://bugs.launchpad.net/launchpad/+bug/1425646 (it's too hard to find the +editemails page & configure mailing lists)
and
https://bugs.launchpad.net/launchpad/+bug/1425649 (it's too easy to click the wrong form button on +editemails, resulting in your settings not being saved).
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~thomir/launchpad/devel-fix-editemails-link into lp:launchpad.
=== modified file 'lib/lp/registry/browser/configure.zcml'
--- lib/lp/registry/browser/configure.zcml 2015-02-06 13:37:58 +0000
+++ lib/lp/registry/browser/configure.zcml 2015-02-26 21:41:09 +0000
@@ -1009,6 +1009,14 @@
name="+editemails"
template="../templates/person-editemails.pt"/>
</browser:pages>
+ <browser:pages
+ for="lp.registry.interfaces.person.IPerson"
+ permission="launchpad.Edit"
+ class="lp.registry.browser.person.PersonEditMailingListsView">
+ <browser:page
+ name="+editmailinglists"
+ template="../templates/person-editmailinglists.pt"/>
+ </browser:pages>
<browser:page
name="+oauth-tokens"
for="lp.registry.interfaces.person.IPerson"
=== modified file 'lib/lp/registry/browser/person.py'
--- lib/lp/registry/browser/person.py 2015-02-06 13:37:58 +0000
+++ lib/lp/registry/browser/person.py 2015-02-26 21:41:09 +0000
@@ -723,6 +723,7 @@
'branding',
'editemailaddresses',
'editlanguages',
+ 'editmailinglists',
'editircnicknames',
'editjabberids',
'editsshkeys',
@@ -782,6 +783,12 @@
return Link(target, text, icon='edit')
@enabled_with_permission('launchpad.Edit')
+ def editmailinglists(self):
+ target = '+editmailinglists'
+ text = 'Manage mailing list subscriptions'
+ return Link(target, text, icon='edit')
+
+ @enabled_with_permission('launchpad.Edit')
def editircnicknames(self):
target = '+editircnicknames'
text = 'Update IRC nicknames'
@@ -2722,8 +2729,6 @@
orientation='vertical')
custom_widget('UNVALIDATED_SELECTED', LaunchpadRadioWidget,
orientation='vertical')
- custom_widget('mailing_list_auto_subscribe_policy',
- LaunchpadRadioWidgetWithDescription)
label = 'Change your e-mail settings'
@@ -2746,9 +2751,7 @@
self.form_fields = (self._validated_emails_field() +
self._unvalidated_emails_field() +
FormFields(TextLine(__name__='newemail',
- title=u'Add a new address'))
- + self._mailing_list_fields()
- + self._autosubscribe_policy_fields())
+ title=u'Add a new address')))
@property
def initial_values(self):
@@ -2769,20 +2772,8 @@
unvalidated = self.unvalidated_addresses
if len(unvalidated) > 0:
unvalidated = unvalidated.pop()
- initial = dict(VALIDATED_SELECTED=validated,
- UNVALIDATED_SELECTED=unvalidated)
-
- # Defaults for the mailing list autosubscribe buttons.
- policy = self.context.mailing_list_auto_subscribe_policy
- initial.update(mailing_list_auto_subscribe_policy=policy)
-
- return initial
-
- def setUpWidgets(self, context=None):
- """See `LaunchpadFormView`."""
- super(PersonEditEmailsView, self).setUpWidgets(context)
- widget = self.widgets['mailing_list_auto_subscribe_policy']
- widget.display_label = False
+ return dict(VALIDATED_SELECTED=validated,
+ UNVALIDATED_SELECTED=unvalidated)
def _validated_emails_field(self):
"""Create a field with a vocabulary of validated emails.
@@ -2824,75 +2815,6 @@
source=SimpleVocabulary(terms)),
custom_widget=self.custom_widgets['UNVALIDATED_SELECTED'])
- def _mailing_list_subscription_type(self, mailing_list):
- """Return the context user's subscription type for the given list.
-
- This is 'Preferred address' if the user is subscribed using her
- preferred address and 'Don't subscribe' if the user is not
- subscribed at all. Otherwise it's the EmailAddress under
- which the user is subscribed to this mailing list.
- """
- subscription = mailing_list.getSubscription(self.context)
- if subscription is None:
- return "Don't subscribe"
- elif subscription.email_address is None:
- return 'Preferred address'
- else:
- return subscription.email_address
-
- def _mailing_list_fields(self):
- """Creates a field for each mailing list the user can subscribe to.
-
- If a team doesn't have a mailing list, or the mailing list
- isn't usable, it's not included.
- """
- mailing_list_set = getUtility(IMailingListSet)
- fields = []
- terms = [
- SimpleTerm("Preferred address"),
- SimpleTerm("Don't subscribe"),
- ]
- for email in self.validated_addresses:
- terms.append(SimpleTerm(email, email.email))
- for team in self.context.teams_participated_in:
- mailing_list = mailing_list_set.get(team.name)
- if mailing_list is not None and mailing_list.is_usable:
- name = 'subscription.%s' % team.name
- value = self._mailing_list_subscription_type(mailing_list)
- field = Choice(__name__=name,
- title=team.name,
- source=SimpleVocabulary(terms), default=value)
- fields.append(field)
- return FormFields(*fields)
-
- def _autosubscribe_policy_fields(self):
- """Create a field for each mailing list auto-subscription option."""
- return FormFields(
- Choice(__name__='mailing_list_auto_subscribe_policy',
- title=_('When should Launchpad automatically subscribe '
- 'you to a team’s mailing list?'),
- source=MailingListAutoSubscribePolicy))
-
- @property
- def mailing_list_widgets(self):
- """Return all the mailing list subscription widgets."""
- mailing_list_set = getUtility(IMailingListSet)
- widgets = []
- for widget in self.widgets:
- if widget.name.startswith('field.subscription.'):
- team_name = widget.label
- mailing_list = mailing_list_set.get(team_name)
- assert mailing_list is not None, 'Missing mailing list'
- widget_dict = dict(
- team=mailing_list.team,
- widget=widget,
- )
- widgets.append(widget_dict)
- # We'll put the label in the first column, so don't include it
- # in the second column.
- widget.display_label = False
- return widgets
-
def _validate_selected_address(self, data, field='VALIDATED_SELECTED'):
"""A generic validator for this view's actions.
@@ -3125,6 +3047,139 @@
"message for up to an hour or two.)" % newemail)
self.next_url = self.action_url
+
+class PersonEditMailingListsView(LaunchpadFormView):
+ """A view for editing a person's mailing list subscriptions."""
+
+ implements(IPersonEditMenu)
+
+ schema = IEmailAddress
+
+ custom_widget('mailing_list_auto_subscribe_policy',
+ LaunchpadRadioWidgetWithDescription)
+
+ label = 'Change your mailing list subscriptions'
+
+ def initialize(self):
+ if self.context.is_team:
+ # +editmailinglists is not available on teams.
+ name = self.request['PATH_INFO'].split('/')[-1]
+ raise NotFound(self, name, request=self.request)
+ super(PersonEditMailingListsView, self).initialize()
+
+ def setUpFields(self):
+ """Set up fields for this view.
+
+ The main fields of interest are the selection fields with custom
+ vocabularies for the lists of validated and unvalidated email
+ addresses.
+ """
+ super(PersonEditMailingListsView, self).setUpFields()
+ self.form_fields = (self._mailing_list_fields()
+ + self._autosubscribe_policy_fields())
+
+ @property
+ def initial_values(self):
+ """Set up default values for the radio widgets.
+
+ A radio widget must have a selected value, so we select the
+ first unvalidated and validated email addresses in the lists
+ to be the default for the corresponding widgets.
+
+ The only exception is if the user has a preferred email
+ address: then, that address is used as the default validated
+ email address.
+ """
+ # Defaults for the mailing list autosubscribe buttons.
+ return dict(mailing_list_auto_subscribe_policy=
+ self.context.mailing_list_auto_subscribe_policy)
+
+ def setUpWidgets(self, context=None):
+ """See `LaunchpadFormView`."""
+ super(PersonEditMailingListsView, self).setUpWidgets(context)
+ widget = self.widgets['mailing_list_auto_subscribe_policy']
+ widget.display_label = False
+
+ def _mailing_list_subscription_type(self, mailing_list):
+ """Return the context user's subscription type for the given list.
+
+ This is 'Preferred address' if the user is subscribed using her
+ preferred address and 'Don't subscribe' if the user is not
+ subscribed at all. Otherwise it's the EmailAddress under
+ which the user is subscribed to this mailing list.
+ """
+ subscription = mailing_list.getSubscription(self.context)
+ if subscription is None:
+ return "Don't subscribe"
+ elif subscription.email_address is None:
+ return 'Preferred address'
+ else:
+ return subscription.email_address
+
+ def _mailing_list_fields(self):
+ """Creates a field for each mailing list the user can subscribe to.
+
+ If a team doesn't have a mailing list, or the mailing list
+ isn't usable, it's not included.
+ """
+ mailing_list_set = getUtility(IMailingListSet)
+ fields = []
+ terms = [
+ SimpleTerm("Preferred address"),
+ SimpleTerm("Don't subscribe"),
+ ]
+ for email in self.validated_addresses:
+ terms.append(SimpleTerm(email, email.email))
+ for team in self.context.teams_participated_in:
+ mailing_list = mailing_list_set.get(team.name)
+ if mailing_list is not None and mailing_list.is_usable:
+ name = 'subscription.%s' % team.name
+ value = self._mailing_list_subscription_type(mailing_list)
+ field = Choice(__name__=name,
+ title=team.name,
+ source=SimpleVocabulary(terms), default=value)
+ fields.append(field)
+ return FormFields(*fields)
+
+ def _autosubscribe_policy_fields(self):
+ """Create a field for each mailing list auto-subscription option."""
+ return FormFields(
+ Choice(__name__='mailing_list_auto_subscribe_policy',
+ title=_('When should Launchpad automatically subscribe '
+ 'you to a team’s mailing list?'),
+ source=MailingListAutoSubscribePolicy))
+
+ @property
+ def mailing_list_widgets(self):
+ """Return all the mailing list subscription widgets."""
+ mailing_list_set = getUtility(IMailingListSet)
+ widgets = []
+ for widget in self.widgets:
+ if widget.name.startswith('field.subscription.'):
+ team_name = widget.label
+ mailing_list = mailing_list_set.get(team_name)
+ assert mailing_list is not None, 'Missing mailing list'
+ widget_dict = dict(
+ team=mailing_list.team,
+ widget=widget,
+ )
+ widgets.append(widget_dict)
+ # We'll put the label in the first column, so don't include it
+ # in the second column.
+ widget.display_label = False
+ return widgets
+
+ @property
+ def validated_addresses(self):
+ """All of this person's validated email addresses, including
+ their preferred address (if any).
+ """
+ addresses = []
+ if self.context.preferredemail:
+ addresses.append(self.context.preferredemail)
+ addresses += [email for email in self.context.validatedemails]
+ return addresses
+
def validate_action_update_subscriptions(self, action, data):
"""Make sure the user is subscribing using a valid address.
=== modified file 'lib/lp/registry/browser/tests/test_person.py'
--- lib/lp/registry/browser/tests/test_person.py 2014-11-29 00:21:14 +0000
+++ lib/lp/registry/browser/tests/test_person.py 2015-02-26 21:41:09 +0000
@@ -683,6 +683,13 @@
browser = setupBrowserForUser(user=self.person)
self.assertRaises(NotFound, browser.open, url)
+ def test_team_editmailinglists_not_found(self):
+ """Teams should not have a +editmailinglists page."""
+ team = self.factory.makeTeam(owner=self.person, members=[self.person])
+ url = '%s/+editmailinglists' % canonical_url(team)
+ browser = setupBrowserForUser(user=self.person)
+ self.assertRaises(NotFound, browser.open, url)
+
def test_email_string_validation_no_email_prodvided(self):
"""+editemails should warn if no email is provided."""
no_email = ''
=== modified file 'lib/lp/registry/doc/teammembership-email-notification.txt'
--- lib/lp/registry/doc/teammembership-email-notification.txt 2012-08-13 19:34:10 +0000
+++ lib/lp/registry/doc/teammembership-email-notification.txt 2015-02-26 21:41:09 +0000
@@ -818,7 +818,7 @@
<BLANKLINE>
If you would like to subscribe to the team list, use the link below
to update your Mailing List Subscription preferences.
- <http://launchpad.dev/people/+me/+editemails>
+ <http://launchpad.dev/people/+me/+editmailinglists>
<BLANKLINE>
-- =
<BLANKLINE>
@@ -843,7 +843,7 @@
<BLANKLINE>
If you would like to subscribe to the team list, use the link below
to update your Mailing List Subscription preferences.
- <http://launchpad.dev/people/+me/+editemails>
+ <http://launchpad.dev/people/+me/+editmailinglists>
<BLANKLINE>
-- =
<BLANKLINE>
=== modified file 'lib/lp/registry/mail/notification.py'
--- lib/lp/registry/mail/notification.py 2012-11-26 18:50:14 +0000
+++ lib/lp/registry/mail/notification.py 2015-02-26 21:41:09 +0000
@@ -148,7 +148,7 @@
'team-list-subscribe-block.txt', app='registry')
editemails_url = urlappend(
canonical_url(getUtility(ILaunchpadRoot)),
- 'people/+me/+editemails')
+ 'people/+me/+editmailinglists')
list_instructions = template % dict(editemails_url=editemails_url)
else:
list_instructions = ''
@@ -257,7 +257,7 @@
headers = {}
subject = "New Mailing List for %s" % team.displayname
template = get_email_template('new-mailing-list.txt', app='registry')
- editemails_url = '%s/+editemails'
+ editemails_url = '%s/+editmailinglists'
for person in team.allmembers:
if person.is_team or person.preferredemail is None:
=== modified file 'lib/lp/registry/stories/mailinglists/subscriptions.txt'
--- lib/lp/registry/stories/mailinglists/subscriptions.txt 2014-01-30 15:04:06 +0000
+++ lib/lp/registry/stories/mailinglists/subscriptions.txt 2015-02-26 21:41:09 +0000
@@ -69,7 +69,7 @@
>>> logout()
>>> no_team_browser = setupBrowserFreshLogin(person)
- >>> no_team_browser.open('http://launchpad.dev/people/+me/+editemails')
+ >>> no_team_browser.open('http://launchpad.dev/people/+me/+editmailinglists')
>>> rosetta_admins = no_team_browser.getControl(
... name='field.subscription.rosetta-admins')
>>> rosetta_admins.displayOptions
@@ -89,11 +89,11 @@
>>> logout()
>>> carlos_browser = setupBrowserFreshLogin(carlos)
>>> carlos_browser.open('http://launchpad.dev/~carlos')
- >>> carlos_browser.getLink(url="+editemails").click()
+ >>> carlos_browser.getLink(url="+editmailinglists").click()
>>> from lp.services.helpers import backslashreplace
>>> print backslashreplace(carlos_browser.title)
- Change your e-mail settings...
+ Change your mailing list subscriptions...
>>> admins = carlos_browser.getControl(name='field.subscription.admins')
>>> rosetta_admins = carlos_browser.getControl(
@@ -198,9 +198,9 @@
Admins team, and he should know if the list is available.
>>> carlos_browser.open('http://launchpad.dev/~carlos')
- >>> carlos_browser.getLink(url="+editemails").click()
+ >>> carlos_browser.getLink(url="+editmailinglists").click()
>>> print backslashreplace(carlos_browser.title)
- Change your e-mail settings...
+ Change your mailing list subscriptions...
>>> rosetta_admins = carlos_browser.getControl(
... name='field.subscription.rosetta-admins')
@@ -236,9 +236,9 @@
>>> logout()
>>> jdub_browser = setupBrowserFreshLogin(jdub)
>>> jdub_browser.open('http://launchpad.dev/~jdub')
- >>> jdub_browser.getLink(url="+editemails").click()
+ >>> jdub_browser.getLink(url="+editmailinglists").click()
>>> print jdub_browser.title
- Change your e-mail settings...
+ Change your mailing list subscriptions...
>>> jdub_browser.getControl(
... name='field.subscription.rosetta-admins')
@@ -260,9 +260,9 @@
His mailing list subscription is now available to be managed.
>>> jdub_browser.open('http://launchpad.dev/~jdub')
- >>> jdub_browser.getLink(url="+editemails").click()
+ >>> jdub_browser.getLink(url="+editmailinglists").click()
>>> print jdub_browser.title
- Change your e-mail settings...
+ Change your mailing list subscriptions...
>>> rosetta_team = jdub_browser.getControl(
... name='field.subscription.rosetta-admins')
@@ -327,14 +327,14 @@
>>> carlos_browser.open('http://launchpad.dev/~admins')
>>> carlos_browser.getLink('Subscribe to mailing list').click()
>>> print carlos_browser.url
- http://launchpad.dev/~carlos/+editemails
+ http://launchpad.dev/~carlos/+editmailinglists
The unsubscribe link is visible for the rosetta admins team, which
has an active mailing list.
# Subscribe to the list using the normal technique.
>>> carlos_browser.open('http://launchpad.dev/~carlos')
- >>> carlos_browser.getLink(url="+editemails").click()
+ >>> carlos_browser.getLink(url="+editmailinglists").click()
>>> rosetta_admins = carlos_browser.getControl(
... name='field.subscription.rosetta-admins')
>>> rosetta_admins.value = ['Preferred address']
@@ -469,9 +469,9 @@
list based on a setting in the person's Email preferences page.
>>> carlos_browser.open('http://launchpad.dev/~carlos')
- >>> carlos_browser.getLink(url="+editemails").click()
+ >>> carlos_browser.getLink(url="+editmailinglists").click()
>>> print backslashreplace(carlos_browser.title)
- Change your e-mail settings...
+ Change your mailing list subscriptions...
Carlos's default setting, 'Ask me when I join a team', is still in place.
@@ -549,7 +549,7 @@
>>> logout()
>>> browser = setupBrowserFreshLogin(james)
>>> browser.open('http://launchpad.dev/~jblack')
- >>> browser.getLink(url="+editemails").click()
+ >>> browser.getLink(url="+editmailinglists").click()
>>> print_radio_button_field(browser.contents,
... 'mailing_list_auto_subscribe_policy')
( ) Never subscribe to mailing lists
@@ -566,7 +566,7 @@
# Change James' setting
>>> browser.open('http://launchpad.dev/~jblack')
- >>> browser.getLink(url="+editemails").click()
+ >>> browser.getLink(url="+editmailinglists").click()
>>> set_autosubscribe_policy_and_submit('ALWAYS', browser)
( ) Never subscribe to mailing lists
( ) Ask me when I join a team
@@ -582,7 +582,7 @@
# Change James' setting
>>> browser.open('http://launchpad.dev/~jblack')
- >>> browser.getLink(url="+editemails").click()
+ >>> browser.getLink(url="+editmailinglists").click()
>>> set_autosubscribe_policy_and_submit('NEVER', browser)
(*) Never subscribe to mailing lists
( ) Ask me when I join a team
=== modified file 'lib/lp/registry/stories/team/xx-team-membership.txt'
--- lib/lp/registry/stories/team/xx-team-membership.txt 2012-01-15 11:06:57 +0000
+++ lib/lp/registry/stories/team/xx-team-membership.txt 2015-02-26 21:41:09 +0000
@@ -247,7 +247,7 @@
>>> user_browser.getLink('Register a team')
<Link ... url='http://.../people/+newteam'>
>>> user_browser.getLink('Change mailing list subscriptions')
- <Link ... url='http://.../~no-priv/+editemails'>
+ <Link ... url='http://.../~no-priv/+editmailinglists'>
Teams also have a participation page, but it does not include a mailing
list column.
=== modified file 'lib/lp/registry/templates/person-editemails.pt'
--- lib/lp/registry/templates/person-editemails.pt 2012-06-28 01:47:35 +0000
+++ lib/lp/registry/templates/person-editemails.pt 2015-02-26 21:41:09 +0000
@@ -19,6 +19,10 @@
id="no-contact-address">
Currently you don't have a contact address in Launchpad.
</p>
+ <p>Looking to <a
+ tal:define="link context/menu:overview/editmailinglists"
+ tal:attributes="href link/target"
+ >configure your mailing list subscriptions?</a></p>
</metal:extra-info>
<metal:widgets fill-slot="widgets">
@@ -70,79 +74,6 @@
</metal:widgets>
<metal:widgets fill-slot="buttons" />
</div>
-
-
- <form action=""
- method="post" enctype="multipart/form-data"
- accept-charset="UTF-8" tal:condition="view/mailing_list_widgets">
-
- <h2>Mailing list subscriptions</h2>
-
- <p>You're a member of one or more teams with active mailing
- lists. You can subscribe to a team's mailing list using any of
- your verified email addresses.</p>
-
- <table class="listing" style="width: 45em;">
- <thead>
- <th style="white-space:nowrap;">For mailing list</th>
- <th>Subscribe with</th>
- </thead>
- <tbody>
- <tr tal:repeat="widget view/mailing_list_widgets">
- <td tal:content="structure widget/team/fmt:link">Team</td>
- <td tal:content="structure widget/widget">Widget</td>
- </tr>
- </tbody>
- </table>
- <div style="padding-top: 1em; padding-bottom: 1em;">
- <input tal:replace="structure view/action_update_subscriptions/render" />
- </div>
- </form>
-
- <form action=""
- method="post" enctype="multipart/form-data"
- accept-charset="UTF-8">
-
- <h2>Automatic subscription to mailing lists</h2>
-
- <div id="notification-info">When a team you are a member of creates a new
- mailing list, you will receive an email notification offering you the
- opportunity to join the new mailing list. Launchpad can also
- automatically subscribe you to a team's mailing list whenever you
- join a team.</div>
-
- <tal:widget
- define="widget nocall:view/widgets/mailing_list_auto_subscribe_policy">
- <table class="form">
-
- <thead>
- <tr>
- <th style="white-space:nowrap; text-align:left;">
- <div style="margin-bottom: 1em;">
- <label tal:attributes="for widget/name"
- tal:content="structure widget/label" />
- </div>
- </th>
- <td></td>
- </tr>
- </thead>
-
- <tbody>
- <metal:block use-macro="context/@@launchpad_form/widget_row" />
- <tr>
- <td>
- <input
- tal:replace="structure
- view/action_update_autosubscribe_policy/render" />
- </td>
- <td></td>
- </tr>
- </tbody>
-
- </table>
- </tal:widget>
- </form>
-
</div>
</body>
</html>
=== added file 'lib/lp/registry/templates/person-editmailinglists.pt'
--- lib/lp/registry/templates/person-editmailinglists.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/registry/templates/person-editmailinglists.pt 2015-02-26 21:41:09 +0000
@@ -0,0 +1,88 @@
+<html
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:tal="http://xml.zope.org/namespaces/tal"
+ xmlns:metal="http://xml.zope.org/namespaces/metal"
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+ metal:use-macro="view/macro:page/main_only"
+ i18n:domain="launchpad"
+>
+ <body>
+<div metal:fill-slot="main">
+ <form action=""
+ method="post" enctype="multipart/form-data"
+ accept-charset="UTF-8" tal:condition="view/mailing_list_widgets">
+
+ <h2>Mailing list subscriptions</h2>
+
+ <p>You're a member of one or more teams with active mailing
+ lists. You can subscribe to a team's mailing list using any of
+ your verified email addresses. You can <a
+ tal:define="link context/menu:overview/editemailaddresses"
+ tal:attributes="href link/target"
+ >configure your verified email addresses here</a>.
+ </p>
+
+ <table class="listing" style="width: 45em;">
+ <thead>
+ <th style="white-space:nowrap;">For mailing list</th>
+ <th>Subscribe with</th>
+ </thead>
+ <tbody>
+ <tr tal:repeat="widget view/mailing_list_widgets">
+ <td tal:content="structure widget/team/fmt:link">Team</td>
+ <td tal:content="structure widget/widget">Widget</td>
+ </tr>
+ </tbody>
+ </table>
+ <div style="padding-top: 1em; padding-bottom: 1em;">
+ <input tal:replace="structure view/action_update_subscriptions/render" />
+ </div>
+ </form>
+
+ <form action=""
+ method="post" enctype="multipart/form-data"
+ accept-charset="UTF-8">
+
+ <h2>Automatic subscription to mailing lists</h2>
+
+ <div id="notification-info">When a team you are a member of creates a new
+ mailing list, you will receive an email notification offering you the
+ opportunity to join the new mailing list. Launchpad can also
+ automatically subscribe you to a team's mailing list whenever you
+ join a team.</div>
+
+ <tal:widget
+ define="widget nocall:view/widgets/mailing_list_auto_subscribe_policy">
+ <table class="form">
+
+ <thead>
+ <tr>
+ <th style="white-space:nowrap; text-align:left;">
+ <div style="margin-bottom: 1em;">
+ <label tal:attributes="for widget/name"
+ tal:content="structure widget/label" />
+ </div>
+ </th>
+ <td></td>
+ </tr>
+ </thead>
+
+ <tbody>
+ <metal:block use-macro="context/@@launchpad_form/widget_row" />
+ <tr>
+ <td>
+ <input
+ tal:replace="structure
+ view/action_update_autosubscribe_policy/render" />
+ </td>
+ <td></td>
+ </tr>
+ </tbody>
+
+ </table>
+ </tal:widget>
+ </form>
+
+</div>
+</body>
+</html>
=== modified file 'lib/lp/registry/templates/person-portlet-contact-details.pt'
--- lib/lp/registry/templates/person-portlet-contact-details.pt 2012-06-15 16:23:50 +0000
+++ lib/lp/registry/templates/person-portlet-contact-details.pt 2015-02-26 21:41:09 +0000
@@ -15,9 +15,7 @@
<dd tal:content="context/name"/>
</dl>
<dl id="email-addresses">
- <dt>Email:
- <a tal:replace="structure overview_menu/editemailaddresses/fmt:icon" />
- </dt>
+ <dt>Email:</dt>
<dd
tal:attributes="title view/visible_email_address_description">
<tal:not_logged_in
@@ -49,6 +47,16 @@
</span>
</tal:emails>
</dd>
+ <dd>
+ <a
+ tal:define="link context/menu:overview/editemailaddresses"
+ tal:condition="link/enabled"
+ tal:content="structure link/fmt:link" /><br />
+ <a
+ tal:define="link context/menu:overview/editmailinglists"
+ tal:condition="link/enabled"
+ tal:content="structure link/fmt:link" />
+ </dd>
</dl>
=== modified file 'lib/lp/registry/templates/team-portlet-mailinglist.pt'
--- lib/lp/registry/templates/team-portlet-mailinglist.pt 2012-07-06 06:02:33 +0000
+++ lib/lp/registry/templates/team-portlet-mailinglist.pt 2015-02-26 21:41:09 +0000
@@ -22,7 +22,7 @@
<tal:can-subscribe-to-list
condition="view/user_can_subscribe_to_list">
<a id="link-list-subscribe" class="sprite add"
- href="/people/+me/+editemails">Subscribe to mailing list</a>
+ href="/people/+me/+editmailinglists">Subscribe to mailing list</a>
<br />
</tal:can-subscribe-to-list>
<tal:subscribed-to-list
=== modified file 'lib/lp/registry/tests/test_mailinglist.py'
--- lib/lp/registry/tests/test_mailinglist.py 2013-01-11 01:05:14 +0000
+++ lib/lp/registry/tests/test_mailinglist.py 2015-02-26 21:41:09 +0000
@@ -169,7 +169,7 @@
self.assertEqual(
'New Mailing List for Team', notifications[0]['subject'])
self.assertTextMatchesExpressionIgnoreWhitespace(
- '.*To subscribe:.*http://launchpad.dev/~.*/\+editemails.*',
+ '.*To subscribe:.*http://launchpad.dev/~.*/\+editmailinglists.*',
notifications[0].get_payload())
def test_startConstructing_from_APPROVED(self):
Follow ups