Merge lp:~sinzui/launchpad/project-packages-portlet-ui into lp:launchpad

Proposed by Curtis Hovey
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~sinzui/launchpad/project-packages-portlet-ui
Merge into: lp:launchpad
Diff against target: 348 lines (+127/-40)
5 files modified
lib/lp/registry/browser/product.py (+32/-9)
lib/lp/registry/browser/tests/product-portlet-packages-view.txt (+83/-14)
lib/lp/registry/browser/tests/product-views.txt (+2/-1)
lib/lp/registry/stories/product/xx-product-index.txt (+4/-3)
lib/lp/registry/templates/product-portlet-packages.pt (+6/-13)
To merge this branch: bzr merge lp:~sinzui/launchpad/project-packages-portlet-ui
Reviewer Review Type Date Requested Status
Michael Nelson (community) ui Approve
Paul Hummer (community) ui* Approve
Gavin Panella (community) Approve
Canonical Launchpad Engineering ui Pending
Review via email: mp+23360@code.launchpad.net

Description of the change

This is my branch to simplify the project package portlet suggestion form.

    lp:~sinzui/launchpad/project-packages-portlet-ui
    Diff size: 314
    Launchpad bug: https://bugs.launchpad.net/bugs/550642
                   https://bugs.launchpad.net/bugs/556534
    Test command: ./bin/test -vv \
        -t product-portlet-packages-view -t xx-product-index
    Pre-implementation: bac, james_w
    Target release: 10.04

Simplify the project package portlet suggestion form
--------------------------------------------------------------------

Bug #550642 [The form in +product-portlet-packages is shown to anonymous users]
    As an anonymous user, I was show the form to link /gdp to a sourcepackage.
    As an anonymous user, I should never be asked to complete a form. Note
    that the link to +ubuntupkg was not rendered because it does require
    launchpad.View, so I saw the form ending with the "or".

Bug #556534 [Suggestion to link to an Ubuntu package is repetitive]
    it says:

        [ Link to this Ubuntu Package ] or (+) Link to Ubuntu package

    which is a little repetitive and took me two readings to notice why there
    were two links.

    This problem must be solved because we need to add a third action to
    allow the user to state the project is not packaged in Ubuntu.

Rules
-----

    * Do not show the form to anonymous users.
    * Replace the link to +ubuntupkg with an option that states what will
      happen next: Choose another Ubuntu package
      * This allows us to add a "This is not packaged in Ubuntu"

UI
--

There are two presentations to accommodate when there are suggestions, and
when there are none.

    http://people.canonical.com/~curtis/project-with-package-suggestions.png
    http://people.canonical.com/~curtis/project-without-package-suggestions.png

QA
--

    * Visit https://edge.launchpad.net/gdp
    * Verify that several packages are listed, and the last option is
      "Choose another Ubuntu package"
    * Visit https://edge.launchpad.net/gedit-class-browser
    * Verify there is only one option listed
    * Select "Choose another Ubuntu package" and submit.
    * Verify you are on the +ubuntupkg form.

Lint
----

Linting changed files:
  lib/lp/registry/browser/product.py
  lib/lp/registry/browser/tests/product-portlet-packages-view.txt
  lib/lp/registry/stories/product/xx-product-index.txt
  lib/lp/registry/templates/product-portlet-packages.pt

Test
----

    * lib/lp/registry/browser/tests/product-portlet-packages-view.txt
      * Updated the test to reflect the new labels for the form.
      * Added a test to verify that anonymous users are not show the form.
      * Added a test to verify the form works.
      * Revised the test to show that selecting "Choose another Ubuntu
        package" redirects to +ubuntupkg. Removed the verification of the link
        to the form.
    * lib/lp/registry/stories/product/xx-product-index.txt
      * Updated the test to verify what the user sees.

Implementation
--------------

    * lib/lp/registry/browser/product.py
      * Updated can_show_portlet to return False when there is no user.
      * Refactored package_field_name so that the string was defined once.
        and updated the label to make it clear that the suggestions are
        from the current Ubuntu development series.
      * Added other_package to the vocabulary and made it the default value.
      * Updated the form action label to accommodate the case were the
        user has another step. This will also work for the case where the
        user needs to say the project is not packaged.
    * lib/lp/registry/templates/product-portlet-packages.pt
      * Removed the link to +ubuntupkg.
      * Moved the paragraph about no matches into the first form so that
        the second form could be removed.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

Nice :)

Log from IRC:

<allenap> sinzui: In http://people.canonical.com/~curtis/project-without-package-suggestions.png it might work even better if no radio buttons (or the title) appeared, just the button.
<sinzui> allenap, there will also be an option to say it is not packaged.
<sinzui> allenap, The previous UI proposal did have button...
<allenap> sinzui: Okay. Also, can_show_portlet() can return True if there are sourcepackages even when user is None. Is that right?
<sinzui> Correct, that is what you see now...https://edge.launchpad.net/gedit
<sinzui> The feature we are refining suggests packages when we do not know about them
<sinzui> There can be a list like this: https://edge.launchpad.net/gdp
<sinzui> allenap, https://edge.launchpad.net/gedit-class-browser shows just the link to choose another package, but the correct answer is Not packaged.
<sinzui> allenap, The UI to support a list or packages, choose another package, or not packaged became very complicated and abentley, james_w, bac, and I agreed that we should try a single list and button
<allenap> sinzui: Okay, that makes sense, thanks.
<allenap> sinzui: Line 43 in the diff, is it safe to use 'OTHER_PACKAGE' because package.name can never be upper-case? If so, can you add a tiny comment to explain.
<sinzui> hmm
<sinzui> You are correct, but I think I got lucky in my name. I did not think about it
<james_w> name can never have an underscore
<sinzui> allenap, I was cargo culting a style I have reviewed in the past when Object() was used to create a unique and use all-caps to define the field name
<sinzui> james_w, you meana source package name cannot contain underscores?
<james_w> correct
<james_w> for Debian/Ubuntu at least
<james_w> "Package names (both source and binary, see Package, Section 5.6.7) must consist only of lower case letters (a-z), digits (0-9), plus (+) and minus (-) signs, and periods (.). They must be at least two characters long and must start with an alphanumeric character."
<sinzui> ah yes, I recall someone wanted to create a gentoo package with an '/' in it

review: Approve
Revision history for this message
Paul Hummer (rockstar) wrote :

<sinzui> EdwinGrubbs, rockstar: can either you you comment on the UI of my branch https://code.edge.launchpad.net/~sinzui/launchpad/project-packages-portlet-ui/+merge/23360
<rockstar> sinzui, looking
<rockstar> sinzui, that's pretty straightforward. How many package suggestions can a project have?
<sinzui> That's a good question. that I do not know the answer to
<sinzui> I would say too much because I think I have seen 10 and I tuned out
<sinzui> rockstar, 20
<sinzui> rockstar, the number and test are easy to adjust
<rockstar> sinzui, I fear what it might look like with 10 different suggestions.
* sinzui think 10 is the limit
<sinzui> rockstar, no need to speculate: https://edge.launchpad.net/launchpad
<sinzui> We will alway have to an option to choose another package, or say it is not packaged. I think 8 is the most we should suggest
<rockstar> sinzui, I agree. Is there code to limit the suggestions currently?
<sinzui> yes, 20. The value and test are trivial fixes I can do now
* sinzui has them open
<rockstar> sinzui, great. With those changes, ui=me*

review: Approve (ui*)
Revision history for this message
Michael Nelson (michael.nelson) wrote :

Thanks Gavin and Paul for including all the info. My initial thought (similar to Gavin) that it seems strange having a single radio (http://people.canonical.com/~curtis/project-without-package-suggestions.png), but Curtis, you said:

<sinzui> allenap, there will also be an option to say it is not packaged.

Will this be part of this branch? (running locally still shows the single radio + submit button). If not, can we remove the "Ubuntu Hoary packages" title, radio and submit and replace it with the current link (just until the "Not packaged" option is present). I personally don't think it should land in this intermediate state... what do you think Curtis?

Great points Paul about the limit change.

review: Needs Information (ui)
Revision history for this message
Curtis Hovey (sinzui) wrote :

On Thu, 2010-04-15 at 10:28 +0000, Michael Nelson wrote:
> Review: Needs Information ui
> Thanks Gavin and Paul for including all the info. My initial thought
> (similar to Gavin) that it seems strange having a single radio
> (http://people.canonical.com/~curtis/project-without-package-suggestions.png), but Curtis, you said:
>
> <sinzui> allenap, there will also be an option to say it is not packaged.

This UI branch came from the branch that allows users to say "This is
not packaged in Ubuntu". There will always be two radio items. The
additional option will land Friday or Monday. The not-packaged branch
was blocked over the model implementation, so I decided to extract the
UI and apply the UI suggestions from abently, james_w, Edwin, and bac,

> Will this be part of this branch? (running locally still shows the
> single radio + submit button). If not, can we remove the "Ubuntu Hoary
> packages" title, radio and submit and replace it with the current link
> (just until the "Not packaged" option is present). I personally don't
> think it should land in this intermediate state... what do you think
> Curtis?

I really do not want to do this. I do not want to design something that
will exist for two days. This feature has a lock on it It will not be
released to lpnet until we land a branch that removed the !- lp_net.

The "Ubuntu Hoary packages" label was added from Edwin's UI review of
the not-packages branch. He was correct in pointing out that the
packages and the operation is about the current development series.

--
__Curtis C. Hovey_________
http://launchpad.net/

Revision history for this message
Michael Nelson (michael.nelson) wrote :

> On Thu, 2010-04-15 at 10:28 +0000, Michael Nelson wrote:
> > Review: Needs Information ui
> > Thanks Gavin and Paul for including all the info. My initial thought
> > (similar to Gavin) that it seems strange having a single radio
> > (http://people.canonical.com/~curtis/project-without-package-
> suggestions.png), but Curtis, you said:
> >
> > <sinzui> allenap, there will also be an option to say it is not packaged.
>
> This UI branch came from the branch that allows users to say "This is
> not packaged in Ubuntu". There will always be two radio items. The
> additional option will land Friday or Monday. The not-packaged branch
> was blocked over the model implementation, so I decided to extract the
> UI and apply the UI suggestions from abently, james_w, Edwin, and bac,

Great, that's all I needed to know :)

> The "Ubuntu Hoary packages" label was added from Edwin's UI review of
> the not-packages branch. He was correct in pointing out that the
> packages and the operation is about the current development series.

Yep, I think the label is great when there is a selection to make.

Thanks!

review: Approve (ui)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/browser/product.py'
2--- lib/lp/registry/browser/product.py 2010-04-12 23:10:39 +0000
3+++ lib/lp/registry/browser/product.py 2010-04-14 21:02:45 +0000
4@@ -1041,10 +1041,12 @@
5 """View class for product packaging portlet."""
6
7 schema = Interface
8+ package_field_name = 'distributionsourcepackage'
9 custom_widget(
10- 'distributionsourcepackage', LaunchpadRadioWidget,
11- orientation='vertical')
12+ package_field_name, LaunchpadRadioWidget, orientation='vertical')
13 suggestions = None
14+ max_suggestions = 8
15+ other_package = object()
16
17 @cachedproperty
18 def sourcepackages(self):
19@@ -1058,7 +1060,17 @@
20 @cachedproperty
21 def can_show_portlet(self):
22 """Are there packages, or can packages be suggested."""
23- return len(self.sourcepackages) > 0 or not config.launchpad.is_lpnet
24+ if len(self.sourcepackages) > 0:
25+ return True
26+ if self.user is None or config.launchpad.is_lpnet:
27+ return False
28+ else:
29+ return True
30+
31+ @property
32+ def initial_values(self):
33+ """See `LaunchpadFormView`."""
34+ return {self.package_field_name: self.other_package}
35
36 def setUpFields(self):
37 """See `LaunchpadFormView`."""
38@@ -1071,7 +1083,7 @@
39 # term descriptions that include a link to the source package.
40 self.suggestions = []
41 vocab_terms = []
42- for package in distro_source_packages[:20]:
43+ for package in distro_source_packages[:self.max_suggestions]:
44 if package.development_version.currentrelease is not None:
45 self.suggestions.append(package)
46 item_url = canonical_url(package)
47@@ -1079,20 +1091,31 @@
48 item_url, escape(package.name))
49 vocab_terms.append(
50 SimpleTerm(package, package.name, description))
51+ # Add an option to represent the user's decision to choose a
52+ # different package. Note that source packages cannot have uppercase
53+ # names with underscores, so the name is safe to use.
54+ description = 'Choose another Ubuntu package'
55+ vocab_terms.append(
56+ SimpleTerm(self.other_package, 'OTHER_PACKAGE', description))
57 vocabulary = SimpleVocabulary(vocab_terms)
58 self.form_fields = form.Fields(
59- Choice(__name__='distributionsourcepackage',
60- title=_('Ubuntu packages'),
61+ Choice(__name__=self.package_field_name,
62+ title=_('Ubuntu %s packages' %
63+ ubuntu.currentseries.displayname),
64 default=None,
65 vocabulary=vocabulary,
66 required=True))
67
68- @action(_('Link to this Ubuntu Package'), name='link')
69+ @action(_('Set Ubuntu package information'), name='link')
70 def link(self, action, data):
71 product = self.context
72- dsp = data.get('distributionsourcepackage')
73- assert dsp is not None, "distributionsourcepackage was not specified"
74+ dsp = data.get(self.package_field_name)
75 product_series = product.development_focus
76+ if dsp is self.other_package:
77+ # The user wants to link an alternate package to this project.
78+ self.next_url = canonical_url(
79+ product_series, view_name="+ubuntupkg")
80+ return
81 ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
82 product_series.setPackaging(ubuntu.currentseries,
83 dsp.sourcepackagename,
84
85=== modified file 'lib/lp/registry/browser/tests/product-portlet-packages-view.txt'
86--- lib/lp/registry/browser/tests/product-portlet-packages-view.txt 2010-04-06 20:25:12 +0000
87+++ lib/lp/registry/browser/tests/product-portlet-packages-view.txt 2010-04-14 21:02:45 +0000
88@@ -27,7 +27,7 @@
89 ... transaction.commit()
90 ... reconnect_stores(config.statistician.dbuser)
91 ... ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
92- ... updated = ubuntu.updateCompleteSourcePackageCache(
93+ ... ignore = ubuntu.updateCompleteSourcePackageCache(
94 ... archive=ubuntu.main_archive, log=logger, ztm=transaction)
95 ... transaction.commit()
96 ... reconnect_stores('launchpad')
97@@ -39,7 +39,6 @@
98 ... login(ANONYMOUS)
99 ... return (ubuntu, product, spn)
100
101-
102 Let's create a test project.
103
104 >>> product = factory.makeProduct(name="bingo")
105@@ -63,8 +62,8 @@
106 translations efficiently.
107 There are no unlinked source packages that are a good match. Can you
108 suggest one?
109- Link to Ubuntu package
110-
111+ Ubuntu Hoary packages:
112+ Choose another Ubuntu package
113
114 A distribution source package in a distribution other than ubuntu will
115 not be suggested.
116@@ -93,8 +92,9 @@
117 >>> view = create_initialized_view(
118 ... product, name="+portlet-packages",
119 ... principal=product.owner)
120- >>> for dsp in view.suggestions:
121- ... print dsp.name
122+ >>> view.suggestions
123+ []
124+
125
126 A source package that does NOT have a publishing history in the PENDING
127 or PUBLISHED statuses will NOT be suggested.
128@@ -111,7 +111,8 @@
129 ... print dsp.name
130
131 A source package that does have a publishing history for the current
132-Ubuntu series in the PUBLISHED status will be suggested.
133+Ubuntu series will be suggested. The view as a distributionsourcepackage
134+field.
135
136 >>> spph = factory.makeSourcePackagePublishingHistory(
137 ... sourcepackagename=spn, distroseries=ubuntu.currentseries,
138@@ -123,9 +124,14 @@
139 ... print dsp.name
140 bingo
141
142+ >>> for field in view.form_fields:
143+ ... print field.__name__
144+ distributionsourcepackage
145+
146 And the user is presented with a form to select the distribution
147 source package.
148
149+ >>> login_person(product.owner)
150 >>> content = find_tag_by_id(view.render(), 'portlet-packages')
151
152 >>> print extract_text(content)
153@@ -135,7 +141,7 @@
154 provides. Links from distribution packages to upstream projects
155 let distribution and upstream maintainers share bugs, patches, and
156 translations efficiently.
157- Ubuntu packages:
158+ Ubuntu Hoary packages:
159 bingo...
160
161 A distribution series with a matching name in the Ubuntu current
162@@ -161,6 +167,7 @@
163 >>> spph = factory.makeSourcePackagePublishingHistory(
164 ... sourcepackagename=spn, distroseries=ubuntu.currentseries)
165 >>> (ubuntu, product, spn) = updateCache()
166+ >>> login_person(product.owner)
167 >>> view = create_initialized_view(
168 ... product, name="+portlet-packages",
169 ... principal=product.owner)
170@@ -177,10 +184,15 @@
171 provides. Links from distribution packages to upstream projects
172 let distribution and upstream maintainers share bugs, patches, and
173 translations efficiently.
174- Ubuntu packages:
175+ Ubuntu Hoary packages:
176 bingo
177 ba-bingo...
178
179+But the limit is 8 packages.
180+
181+ >>> view.max_suggestions
182+ 8
183+
184 If a package matches by name but is already linked to an Ubuntu
185 package then it will not be shown as one of the suggestions.
186
187@@ -198,6 +210,17 @@
188 ... print dsp.name
189 bingo
190
191+The view is not rendered when there are no source packages and the user is
192+anonymous.
193+
194+ >>> login(ANONYMOUS)
195+ >>> view = create_initialized_view(
196+ ... product, name="+portlet-packages", principal=product.owner)
197+ >>> view.sourcepackages
198+ []
199+ >>> view.can_show_portlet
200+ False
201+
202 The can_show_portlet property indicates that the portlet can be rendered. The
203 portlet is not rendered if there are no source packages and the environment
204 is lpnet.
205@@ -205,6 +228,9 @@
206 >>> config.launchpad.is_lpnet
207 False
208
209+ >>> login_person(product.owner)
210+ >>> view = create_initialized_view(
211+ ... product, name="+portlet-packages", principal=product.owner)
212 >>> view.sourcepackages
213 []
214
215@@ -233,15 +259,58 @@
216
217 >>> ignore = config.pop('test_data')
218
219+The +portlet-packages view can create a Packaging link.
220+
221+ >>> product.sourcepackages
222+ []
223+
224+ >>> form = {
225+ ... 'field.distributionsourcepackage': 'bingo',
226+ ... 'field.actions.link': 'Set Ubuntu package information',
227+ ... }
228+ >>> view = create_initialized_view(
229+ ... product, name="+portlet-packages", form=form)
230+ >>> view.errors
231+ []
232+
233+ >>> for sp in product.sourcepackages:
234+ ... print sp.name
235+ bingo
236+
237+ >>> from lp.registry.interfaces.packaging import (
238+ ... IPackagingUtil, PackagingType)
239+
240+ >>> packaging_util = getUtility(IPackagingUtil)
241+ >>> packaging_util.deletePackaging(
242+ ... product.development_focus,
243+ ... getUtility(ISourcePackageNameSet)['bingo'],
244+ ... ubuntu.currentseries)
245+
246+Choosing the other_package option issues a redirect to the +ubuntupkg. The
247+option is the default value.
248+
249+ >>> view.initial_values['distributionsourcepackage'] is view.other_package
250+ True
251+
252+ >>> form = {
253+ ... 'field.distributionsourcepackage': 'OTHER_PACKAGE',
254+ ... 'field.actions.link': 'Set Ubuntu package information',
255+ ... }
256+ >>> view = create_initialized_view(
257+ ... product, name="+portlet-packages", form=form)
258+ >>> view.errors
259+ []
260+
261+ >>> product.sourcepackages
262+ []
263+
264+ >>> print view.next_url
265+ http://launchpad.dev/bingo/trunk/+ubuntupkg
266+
267 The view's sourcepackages property filters out obsolete packages and
268 reverses the order so that the latest packages for the current ubuntu
269 series are shown first.
270
271- >>> from lp.registry.interfaces.packaging import (
272- ... IPackagingUtil, PackagingType)
273-
274- >>> packaging_util = getUtility(IPackagingUtil)
275- >>> series = ubuntu.currentseries
276 >>> spn = factory.makeSourcePackageName(name="a-obsolete-package")
277 >>> packaging_util.createPackaging(
278 ... product.development_focus, spn, ubuntu.currentseries,
279
280=== modified file 'lib/lp/registry/browser/tests/product-views.txt'
281--- lib/lp/registry/browser/tests/product-views.txt 2010-04-12 17:16:10 +0000
282+++ lib/lp/registry/browser/tests/product-views.txt 2010-04-14 21:02:45 +0000
283@@ -506,7 +506,8 @@
284 translations efficiently.
285 There are no unlinked source packages that are a good match.
286 Can you suggest one?
287- Link to Ubuntu package
288+ Ubuntu Hoary packages:
289+ Choose another Ubuntu package
290
291 >>> spn = factory.makeSourcePackageName(name="bingo")
292 >>> from canonical.launchpad.interfaces.launchpad import (
293
294=== modified file 'lib/lp/registry/stories/product/xx-product-index.txt'
295--- lib/lp/registry/stories/product/xx-product-index.txt 2010-03-26 16:12:55 +0000
296+++ lib/lp/registry/stories/product/xx-product-index.txt 2010-04-14 21:02:45 +0000
297@@ -373,10 +373,11 @@
298 ... find_tag_by_id(user_browser.contents, 'portlet-packages'))
299 All packages...
300 Packages in Ubuntu...
301- Ubuntu packages:
302+ Ubuntu Hoary packages:
303 pmount...
304
305- >>> user_browser.getControl(name='field.distributionsourcepackage').value = ['pmount']
306- >>> user_browser.getControl('Link to this Ubuntu Package').click()
307+ >>> user_browser.getControl(
308+ ... name='field.distributionsourcepackage').value = ['pmount']
309+ >>> user_browser.getControl('Set Ubuntu package information').click()
310 >>> print_feedback_messages(user_browser.contents)
311 This project was linked to the source package "pmount in ubuntu"
312
313=== modified file 'lib/lp/registry/templates/product-portlet-packages.pt'
314--- lib/lp/registry/templates/product-portlet-packages.pt 2010-03-26 16:12:55 +0000
315+++ lib/lp/registry/templates/product-portlet-packages.pt 2010-04-14 21:02:45 +0000
316@@ -43,26 +43,19 @@
317 let distribution and upstream maintainers share bugs, patches, and
318 translations efficiently.
319 </p>
320- <div id="suggestions" tal:condition="view/suggestions">
321+ <div id="suggestions">
322+ <p tal:condition="not:view/suggestions">
323+ There are no unlinked source packages that are a good match.
324+ Can you suggest one?
325+ </p>
326+
327 <div metal:use-macro="context/@@launchpad_form/form">
328 <div class="actions" metal:fill-slot="buttons">
329 <input tal:replace="structure view/link/render"/>
330- &nbsp;or&nbsp;
331- <a tal:replace="structure
332- context/development_focus/menu:overview/ubuntupkg/fmt:link" />
333 </div>
334 </div>
335 </div>
336
337- <div id="suggestions" tal:condition="not:view/suggestions">
338- <p>
339- There are no unlinked source packages that are a good match.
340- Can you suggest one?
341- </p>
342- <a tal:replace="structure
343- context/development_focus/menu:overview/ubuntupkg/fmt:link" />
344- </div>
345-
346 </tal:has_no_packages>
347 </div>
348 </tal:root>