Merge lp:~salgado/launchpad/polls-three-o into lp:launchpad

Proposed by Guilherme Salgado
Status: Superseded
Proposed branch: lp:~salgado/launchpad/polls-three-o
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~salgado/launchpad/polls-three-o
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Needs Fixing
Review via email: mp+10343@code.launchpad.net

This proposal has been superseded by a proposal from 2009-08-19.

To post a comment you must log in.
Revision history for this message
Guilherme Salgado (salgado) wrote :

= Summary =

Convert a few poll pages to 3.0

== Proposed fix ==

Convert the easy edit pages and turn the action menu into a related
pages section at the bottom.

before/after screenshots at
https://devpad.canonical.com/~salgado/poll-shots/

== Pre-implementation notes ==

== Implementation details ==

== Tests ==

./bin/test -vvt stories.team-polls

== Demo and Q/A ==

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/registry/browser/configure.zcml
  lib/lp/registry/templates/poll-newoption.pt
  lib/lp/registry/stories/team-polls/edit-options.txt
  lib/lp/registry/templates/team-polls.pt
  lib/lp/registry/templates/polloption-edit.pt
  lib/lp/registry/browser/poll.py
  lib/lp/registry/templates/poll-edit.pt
  lib/lp/registry/stories/team-polls/create-poll-options.txt

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Hi Salgado,

I stubbed my toe a few times looking at the UI changes, until I realized
that I'm really missing a breadcrumb for the poll. Once you've drilled
down into a poll, everything you do in there refers back to the team.
On the edit-option page I found no reference to the poll whatsoever:
it's like you're editing a direct property of the team itself. Having
the poll shown as a first-class entity would make a big difference, I
think. But that's not for a template conversion to fix.

There were a few small inconsistencies, or at least things that I think
are inconsistent: adding an option gives me "Show options" and "Change
details" as related pages, plus a Save button, but editing one gives me
Save plus the Cancel link. Is there a reason why these are so
different?

Something that may force the issue is that the "Change details" link on
the new-option page is for the poll. Had I not known where this UI
element came from, I might have expected it to apply to the option I'm
adding. So I think it'd be more intuitive to remove these "related
pages" links from the new-option page and add a Cancel link back to the
poll instead.

Similarly, unless Martin has a rule against it, I think the poll edit
form should have a Cancel link. Right now there's no direct way back to
the poll page.

(The same goes for the options overview by the way, which is the only
place where I would really expect to be able to add or edit options. It
looks to me as though the options page wants to be integrated into the
poll page, with an "Add new option" link inline and without any remnants
of this old actions menu anywhere. Maybe that's what you have planned
anyway.)

Another very minor annoyance is that some of the page headings look a
little redundant. Sometimes they include the poll name, sometimes they
don't. Where they do, they duplicate the poll title displayed in small
font right above the heading. But I don't see any way of fixing that
without either removing that small title (which seems to be baked into
the application menu above it) or removing the poll name from the page
title--both of which sound like bad alternatives.

Speaking of headings: your branch sets the label for the poll edit form
to "Edit poll details." What exactly that text should read is an
ongoing discussion (started by Curtis on the mailing list), but more to
the point, I don't see it show up anywhere! If you provide a page_title
in this view it'll get picked up (and the one in pagetitles.py will no
longer be needed), but label doesn't seem to be.

Apart from that, the code as such looks good to me. Nice use of a mixin
for the navigation menu, though in this case I'd leave it out altogether
instead of migrating it to the 3.0 setup.

Jeroen

review: Needs Fixing
Revision history for this message
Guilherme Salgado (salgado) wrote :
Download full text (4.2 KiB)

On Wed, 2009-08-19 at 08:13 +0000, Jeroen T. Vermeulen wrote:
> Review: Needs Fixing
> Hi Salgado,
>
> I stubbed my toe a few times looking at the UI changes, until I realized
> that I'm really missing a breadcrumb for the poll. Once you've drilled
> down into a poll, everything you do in there refers back to the team.
> On the edit-option page I found no reference to the poll whatsoever:
> it's like you're editing a direct property of the team itself. Having
> the poll shown as a first-class entity would make a big difference, I
> think. But that's not for a template conversion to fix.

I think everybody who's used polls had a similar experience to yours.
They were written a long time ago and were left mostly untouched since
then, even when we redesigned navigation/UI for 1.0 and 2.0

>
> There were a few small inconsistencies, or at least things that I think
> are inconsistent: adding an option gives me "Show options" and "Change
> details" as related pages, plus a Save button, but editing one gives me
> Save plus the Cancel link. Is there a reason why these are so
> different?

That's because URL of these related pages are relative, so they work on
IPoll pages (like +newoption) but not on IPollOption ones (like
+option/id). The Cancel link was added there only to make it possible
to return to the +options page, but all forms should have a Cancel link.

>
> Something that may force the issue is that the "Change details" link on
> the new-option page is for the poll. Had I not known where this UI
> element came from, I might have expected it to apply to the option I'm
> adding. So I think it'd be more intuitive to remove these "related
> pages" links from the new-option page and add a Cancel link back to the
> poll instead.

I think that's a good thing to do.

>
> Similarly, unless Martin has a rule against it, I think the poll edit
> form should have a Cancel link. Right now there's no direct way back to
> the poll page.

They all should have a Cancel button.

>
> (The same goes for the options overview by the way, which is the only
> place where I would really expect to be able to add or edit options. It
> looks to me as though the options page wants to be integrated into the
> poll page, with an "Add new option" link inline and without any remnants
> of this old actions menu anywhere. Maybe that's what you have planned
> anyway.)

In fact, my only plan is to migrate these pages without making things
any worse than they already are and spend the least possible amount of
time doing so.

But I really liked your suggestion, so I filed
https://bugs.edge.launchpad.net/bugs/415896

>
> Another very minor annoyance is that some of the page headings look a
> little redundant. Sometimes they include the poll name, sometimes they
> don't. Where they do, they duplicate the poll title displayed in small
> font right above the heading. But I don't see any way of fixing that
> without either removing that small title (which seems to be baked into
> the application menu above it) or removing the poll name from the page
> title--both of which sound like bad alternatives.
>
> Speaking of headings: your branch sets the label for the pol...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/registry/browser/configure.zcml'
--- lib/lp/registry/browser/configure.zcml 2009-08-18 04:57:21 +0000
+++ lib/lp/registry/browser/configure.zcml 2009-08-18 20:24:56 +0000
@@ -600,7 +600,8 @@
600 <browser:menus600 <browser:menus
601 module="lp.registry.browser.poll"601 module="lp.registry.browser.poll"
602 classes="602 classes="
603 PollContextMenu"/>603 PollContextMenu
604 PollEditNavigationMenu"/>
604 <browser:defaultView605 <browser:defaultView
605 for="lp.registry.interfaces.poll.IPoll"606 for="lp.registry.interfaces.poll.IPoll"
606 name="+index"/>607 name="+index"/>
607608
=== modified file 'lib/lp/registry/browser/poll.py'
--- lib/lp/registry/browser/poll.py 2009-06-25 04:06:00 +0000
+++ lib/lp/registry/browser/poll.py 2009-08-18 20:24:56 +0000
@@ -7,6 +7,7 @@
7 'BasePollView',7 'BasePollView',
8 'PollAddView',8 'PollAddView',
9 'PollContextMenu',9 'PollContextMenu',
10 'PollEditNavigationMenu',
10 'PollEditView',11 'PollEditView',
11 'PollNavigation',12 'PollNavigation',
12 'PollOptionAddView',13 'PollOptionAddView',
@@ -17,13 +18,14 @@
1718
18from zope.event import notify19from zope.event import notify
19from zope.component import getUtility20from zope.component import getUtility
21from zope.interface import implements, Interface
20from zope.lifecycleevent import ObjectCreatedEvent22from zope.lifecycleevent import ObjectCreatedEvent
21from zope.app.form.browser import TextWidget23from zope.app.form.browser import TextWidget
2224
23from canonical.launchpad.webapp import (25from canonical.launchpad.webapp import (
24 action, canonical_url, ContextMenu, custom_widget,26 action, canonical_url, ContextMenu, custom_widget,
25 enabled_with_permission, LaunchpadEditFormView, LaunchpadFormView, Link,27 enabled_with_permission, LaunchpadEditFormView, LaunchpadFormView, Link,
26 Navigation, stepthrough)28 Navigation, NavigationMenu, stepthrough)
27from canonical.launchpad.webapp.interfaces import ILaunchBag29from canonical.launchpad.webapp.interfaces import ILaunchBag
28from lp.registry.interfaces.poll import (30from lp.registry.interfaces.poll import (
29 IPoll, IPollOption, IPollOptionSet, IPollSubset, IVoteSet, PollAlgorithm,31 IPoll, IPollOption, IPollOptionSet, IPollSubset, IVoteSet, PollAlgorithm,
@@ -31,13 +33,10 @@
31from canonical.launchpad.helpers import shortlist33from canonical.launchpad.helpers import shortlist
3234
3335
34class PollContextMenu(ContextMenu):36class PollEditLinksMixin:
35
36 usedfor = IPoll
37 links = ['showall', 'addnew', 'edit']
3837
39 def showall(self):38 def showall(self):
40 text = 'Show option details'39 text = 'Show options'
41 return Link('+options', text, icon='info')40 return Link('+options', text, icon='info')
4241
43 @enabled_with_permission('launchpad.Edit')42 @enabled_with_permission('launchpad.Edit')
@@ -51,6 +50,21 @@
51 return Link('+edit', text, icon='edit')50 return Link('+edit', text, icon='edit')
5251
5352
53class PollContextMenu(ContextMenu, PollEditLinksMixin):
54 usedfor = IPoll
55 links = ['showall', 'addnew', 'edit']
56
57
58class IPollEditMenu(Interface):
59 """A marker interface for the 'Change details' navigation menu."""
60
61
62class PollEditNavigationMenu(NavigationMenu, PollEditLinksMixin):
63 usedfor = IPollEditMenu
64 facet = 'overview'
65 links = ['showall', 'addnew', 'edit']
66
67
54class PollNavigation(Navigation):68class PollNavigation(Navigation):
5569
56 usedfor = IPoll70 usedfor = IPoll
@@ -353,6 +367,7 @@
353367
354class PollEditView(LaunchpadEditFormView):368class PollEditView(LaunchpadEditFormView):
355369
370 implements(IPollEditMenu)
356 schema = IPoll371 schema = IPoll
357 label = "Edit poll details"372 label = "Edit poll details"
358 field_names = ["name", "title", "proposition", "allowspoilt", "dateopens",373 field_names = ["name", "title", "proposition", "allowspoilt", "dateopens",
@@ -372,6 +387,11 @@
372 field_names = ["name", "title"]387 field_names = ["name", "title"]
373 custom_widget("title", TextWidget, width=30)388 custom_widget("title", TextWidget, width=30)
374389
390 @property
391 def cancel_url(self):
392 """See `LaunchpadFormView`."""
393 return canonical_url(self.context.poll, view_name='+options')
394
375 @action("Save", name="save")395 @action("Save", name="save")
376 def save_action(self, action, data):396 def save_action(self, action, data):
377 self.updateContextFromData(data)397 self.updateContextFromData(data)
@@ -381,6 +401,7 @@
381class PollOptionAddView(LaunchpadFormView):401class PollOptionAddView(LaunchpadFormView):
382 """Create a new option in a given poll."""402 """Create a new option in a given poll."""
383403
404 implements(IPollEditMenu)
384 schema = IPollOption405 schema = IPollOption
385 label = "Create new poll option"406 label = "Create new poll option"
386 field_names = ["name", "title"]407 field_names = ["name", "title"]
387408
=== modified file 'lib/lp/registry/stories/team-polls/create-poll-options.txt'
--- lib/lp/registry/stories/team-polls/create-poll-options.txt 2009-04-17 10:32:16 +0000
+++ lib/lp/registry/stories/team-polls/create-poll-options.txt 2009-08-18 20:24:56 +0000
@@ -37,7 +37,7 @@
37And here we see the option listed as one of the active options for this37And here we see the option listed as one of the active options for this
38poll.38poll.
3939
40 >>> team_admin_browser.getLink('Show option details').click()40 >>> team_admin_browser.getLink('Show options').click()
41 >>> team_admin_browser.url41 >>> team_admin_browser.url
42 'http://launchpad.dev/~ubuntu-team/+poll/dpl-2080/+options'42 'http://launchpad.dev/~ubuntu-team/+poll/dpl-2080/+options'
4343
4444
=== modified file 'lib/lp/registry/stories/team-polls/edit-options.txt'
--- lib/lp/registry/stories/team-polls/edit-options.txt 2008-10-15 17:56:31 +0000
+++ lib/lp/registry/stories/team-polls/edit-options.txt 2009-08-18 20:24:56 +0000
@@ -7,7 +7,7 @@
7 >>> user_browser.getLink('A public poll that never closes').click()7 >>> user_browser.getLink('A public poll that never closes').click()
8 >>> user_browser.url8 >>> user_browser.url
9 'http://launchpad.dev/~ubuntu-team/+poll/never-closes4'9 'http://launchpad.dev/~ubuntu-team/+poll/never-closes4'
10 >>> user_browser.getLink('Show option details').click()10 >>> user_browser.getLink('Show options').click()
11 >>> user_browser.url11 >>> user_browser.url
12 'http://launchpad.dev/~ubuntu-team/+poll/never-closes4/+options'12 'http://launchpad.dev/~ubuntu-team/+poll/never-closes4/+options'
13 >>> user_browser.getLink('Edit')13 >>> user_browser.getLink('Edit')
@@ -21,7 +21,7 @@
21 >>> browser = setupBrowser(21 >>> browser = setupBrowser(
22 ... auth='Basic jeff.waugh@ubuntulinux.com:jdub')22 ... auth='Basic jeff.waugh@ubuntulinux.com:jdub')
23 >>> browser.open('http://launchpad.dev/~ubuntu-team/+poll/never-closes4')23 >>> browser.open('http://launchpad.dev/~ubuntu-team/+poll/never-closes4')
24 >>> browser.getLink('Show option details').click()24 >>> browser.getLink('Show options').click()
25 >>> browser.url25 >>> browser.url
26 'http://launchpad.dev/~ubuntu-team/+poll/never-closes4/+options'26 'http://launchpad.dev/~ubuntu-team/+poll/never-closes4/+options'
27 >>> browser.getLink('[Edit]').click()27 >>> browser.getLink('[Edit]').click()
@@ -43,7 +43,7 @@
43 >>> browser.url43 >>> browser.url
44 'http://launchpad.dev/~ubuntu-team/+poll/not-yet-opened'44 'http://launchpad.dev/~ubuntu-team/+poll/not-yet-opened'
4545
46 >>> browser.getLink('Show option details').click()46 >>> browser.getLink('Show options').click()
47 >>> browser.url47 >>> browser.url
48 'http://launchpad.dev/~ubuntu-team/+poll/not-yet-opened/+options'48 'http://launchpad.dev/~ubuntu-team/+poll/not-yet-opened/+options'
4949
5050
=== modified file 'lib/lp/registry/templates/poll-edit.pt'
--- lib/lp/registry/templates/poll-edit.pt 2009-07-17 17:59:07 +0000
+++ lib/lp/registry/templates/poll-edit.pt 2009-08-18 20:24:56 +0000
@@ -3,19 +3,12 @@
3 xmlns:tal="http://xml.zope.org/namespaces/tal"3 xmlns:tal="http://xml.zope.org/namespaces/tal"
4 xmlns:metal="http://xml.zope.org/namespaces/metal"4 xmlns:metal="http://xml.zope.org/namespaces/metal"
5 xmlns:i18n="http://xml.zope.org/namespaces/i18n"5 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
6 xml:lang="en"6 metal:use-macro="view/macro:page/main_only"
7 lang="en"
8 dir="ltr"
9 metal:use-macro="context/@@main_template/master"
10 i18n:domain="launchpad"7 i18n:domain="launchpad"
11>8>
129
13<body>10<body>
1411
15 <metal:portlets fill-slot="portlets">
16 <div tal:replace="structure context/@@+portlet-details" />
17 </metal:portlets>
18
19 <div metal:fill-slot="main">12 <div metal:fill-slot="main">
2013
21 <div tal:condition="context/isNotYetOpened">14 <div tal:condition="context/isNotYetOpened">
@@ -33,6 +26,8 @@
33 opens it can't be edited anymore.</p>26 opens it can't be edited anymore.</p>
34 </div>27 </div>
35 28
29 <tal:menu replace="structure view/@@+related-pages" />
30
36 </div>31 </div>
3732
38</body>33</body>
3934
=== modified file 'lib/lp/registry/templates/poll-newoption.pt'
--- lib/lp/registry/templates/poll-newoption.pt 2009-07-17 17:59:07 +0000
+++ lib/lp/registry/templates/poll-newoption.pt 2009-08-18 20:24:56 +0000
@@ -3,19 +3,12 @@
3 xmlns:tal="http://xml.zope.org/namespaces/tal"3 xmlns:tal="http://xml.zope.org/namespaces/tal"
4 xmlns:metal="http://xml.zope.org/namespaces/metal"4 xmlns:metal="http://xml.zope.org/namespaces/metal"
5 xmlns:i18n="http://xml.zope.org/namespaces/i18n"5 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
6 xml:lang="en"6 metal:use-macro="view/macro:page/main_only"
7 lang="en"
8 dir="ltr"
9 metal:use-macro="context/@@main_template/master"
10 i18n:domain="launchpad"7 i18n:domain="launchpad"
11>8>
129
13<body>10<body>
1411
15 <metal:portlets fill-slot="portlets">
16 <div tal:replace="structure context/@@+portlet-details" />
17 </metal:portlets>
18
19 <div metal:fill-slot="main">12 <div metal:fill-slot="main">
2013
21 <tal:block condition="context/isNotYetOpened">14 <tal:block condition="context/isNotYetOpened">
@@ -37,6 +30,8 @@
37 </p>30 </p>
38 </tal:block>31 </tal:block>
3932
33 <tal:menu replace="structure view/@@+related-pages" />
34
40 </div>35 </div>
4136
42</body>37</body>
4338
=== modified file 'lib/lp/registry/templates/polloption-edit.pt'
--- lib/lp/registry/templates/polloption-edit.pt 2009-07-17 17:59:07 +0000
+++ lib/lp/registry/templates/polloption-edit.pt 2009-08-18 20:24:56 +0000
@@ -3,19 +3,12 @@
3 xmlns:tal="http://xml.zope.org/namespaces/tal"3 xmlns:tal="http://xml.zope.org/namespaces/tal"
4 xmlns:metal="http://xml.zope.org/namespaces/metal"4 xmlns:metal="http://xml.zope.org/namespaces/metal"
5 xmlns:i18n="http://xml.zope.org/namespaces/i18n"5 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
6 xml:lang="en"6 metal:use-macro="view/macro:page/main_only"
7 lang="en"
8 dir="ltr"
9 metal:use-macro="context/@@main_template/master"
10 i18n:domain="launchpad"7 i18n:domain="launchpad"
11>8>
129
13<body>10<body>
1411
15 <metal:portlets fill-slot="portlets">
16 <div tal:replace="structure context/poll/@@+portlet-details" />
17 </metal:portlets>
18
19 <div metal:fill-slot="main">12 <div metal:fill-slot="main">
2013
21 <tal:block condition="context/poll/isNotYetOpened">14 <tal:block condition="context/poll/isNotYetOpened">
2215
=== modified file 'lib/lp/registry/templates/team-polls.pt'
--- lib/lp/registry/templates/team-polls.pt 2009-07-17 17:59:07 +0000
+++ lib/lp/registry/templates/team-polls.pt 2009-08-18 20:24:56 +0000
@@ -78,8 +78,8 @@
7878
79 <br />79 <br />
80 <tal:block tal:condition="request/lp:person">80 <tal:block tal:condition="request/lp:person">
81 <ul class="add" tal:condition="context/required:launchpad.Edit">81 <ul tal:condition="context/required:launchpad.Edit">
82 <li><a href="+newpoll">Set up a new poll</a></li>82 <li><a class="sprite add" href="+newpoll">Set up a new poll</a></li>
83 </ul>83 </ul>
84 </tal:block>84 </tal:block>
8585
8686