Merge lp:~adeuring/launchpad/bug-344054 into lp:launchpad
- bug-344054
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Gavin Panella |
Approved revision: | not available |
Merged at revision: | not available |
Proposed branch: | lp:~adeuring/launchpad/bug-344054 |
Merge into: | lp:launchpad |
Diff against target: |
231 lines (+111/-56) 4 files modified
lib/lp/bugs/browser/bug.py (+16/-1) lib/lp/bugs/stories/bugattachments/20-edit-bug-attachment.txt (+46/-30) lib/lp/bugs/stories/bugs/xx-bug-index.txt (+3/-3) lib/lp/bugs/templates/bug-portlet-attachments.pt (+46/-22) |
To merge this branch: | bzr merge lp:~adeuring/launchpad/bug-344054 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Albisetti (community) | ui | Approve | |
Curtis Hovey (community) | ui* | Approve | |
Gavin Panella (community) | code | Approve | |
Review via email: mp+15857@code.launchpad.net |
Commit message
Description of the change
Abel Deuring (adeuring) wrote : | # |
Gavin Panella (allenap) wrote : | # |
As discussed on IRC, the new properties are probably better off as
view properties.
<allenap> adeuring: My gut feeling is that regular_attachments and
patches should be view properties rather than model
properties. Did you consider that?
<adeuring> allenap: right, good idea. didn't think about that
<allenap> adeuring: My feeling is that they should not be exported
in any case. If you're a consumer of the API, I think it's better
to get the list of all attachments and split it up from there; the
criteria for a patch are unambiguous and easy to test. Exporting
two (well, three) attachment fields, we also encourage people to
make multiple API calls.
<adeuring> allenap: yeah; I'll use browser methods
Gavin Panella (allenap) wrote : | # |
Looks good :)
These are UI comments really, but the renamed "Add attachment or patch" links seem too prominent in the portlets. I wonder if we need them at all, or if just the green plus icon could be shown next to the portlet title, or if they could remain as simple "Add" or "Add another". Anyway, those are considerations for a UI reviewer really.
Should the titles remain as "Add attachment or patch", perhaps the link below the comment form in the body of the bugs page should also be changed to match? It currently says just "Add attachment".
Curtis Hovey (sinzui) wrote : | # |
Hi Abel.
I tried your branch. This is what I saw after uploading an attachment and a patch.
http://
I also noted that the comment form reads
(+) Add an attachment
But the portlets reads
(+) Add attachment or patch
Since the add attachment link is crafted, I think we should make the actions we expected the user to perform clear. We avoid the use of articles like 'a' and 'an' in our links, I think we should fix the link at the bottom of the page:
Page:
(+) Add attachment or patch
Bug attachment portlet:
(+) Add attachment
Patch portlet:
(+) Add patch
Abel Deuring (adeuring) wrote : | # |
Hi Curtis,
changes applied.
Abel
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -234,7 +234,7 @@
def addcomment(self):
"""Return the 'Comment or attach file' Link."""
- text = 'Add an attachment'
+ text = 'Add attachment or patch'
return Link('+addcomment', text, icon='add')
def addbranch(self):
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -127,10 +127,10 @@
>>> print user_browser.
http://
-There's also a link on the page that will take the user to the "Add an
-attachment" page, for use when JavaScript isn't available.
+There's also a link on the page that will take the user to the "Add
+attachment or patch" page, for use when JavaScript isn't available.
- >>> print user_browser.
+ >>> print user_browser.
http://
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -22,7 +22,7 @@
<ul>
<li>
<a tal:attributes=
- class="sprite add">Add attachment or patch</a>
+ class="sprite add">Add attachment</a>
</li>
</ul>
</div>
@@ -44,7 +44,7 @@
<ul>
<li>
<a tal:attributes=
- class="sprite add">Add attachment or patch</a>
+ class="sprite add">Add patch</a>
</li>
</ul>
</div>
Curtis Hovey (sinzui) wrote : | # |
Hi Abel.
This looks good. Martin or Michael should provide their opinion too.
Martin Albisetti (beuno) wrote : | # |
Curtis nailed it.
Preview Diff
1 | === modified file 'lib/lp/bugs/browser/bug.py' | |||
2 | --- lib/lp/bugs/browser/bug.py 2009-11-26 14:50:55 +0000 | |||
3 | +++ lib/lp/bugs/browser/bug.py 2009-12-09 16:34:16 +0000 | |||
4 | @@ -52,6 +52,7 @@ | |||
5 | 52 | from canonical.launchpad.interfaces._schema_circular_imports import IBug | 52 | from canonical.launchpad.interfaces._schema_circular_imports import IBug |
6 | 53 | from canonical.launchpad.webapp.interfaces import ILaunchBag, NotFoundError | 53 | from canonical.launchpad.webapp.interfaces import ILaunchBag, NotFoundError |
7 | 54 | from lp.bugs.interfaces.bug import IBugSet | 54 | from lp.bugs.interfaces.bug import IBugSet |
8 | 55 | from lp.bugs.interfaces.bugattachment import BugAttachmentType | ||
9 | 55 | from lp.bugs.interfaces.bugtask import ( | 56 | from lp.bugs.interfaces.bugtask import ( |
10 | 56 | BugTaskSearchParams, BugTaskStatus, IBugTask, IFrontPageBugTaskSearch) | 57 | BugTaskSearchParams, BugTaskStatus, IBugTask, IFrontPageBugTaskSearch) |
11 | 57 | from lp.bugs.interfaces.bugwatch import IBugWatchSet | 58 | from lp.bugs.interfaces.bugwatch import IBugWatchSet |
12 | @@ -233,7 +234,7 @@ | |||
13 | 233 | 234 | ||
14 | 234 | def addcomment(self): | 235 | def addcomment(self): |
15 | 235 | """Return the 'Comment or attach file' Link.""" | 236 | """Return the 'Comment or attach file' Link.""" |
17 | 236 | text = 'Add an attachment' | 237 | text = 'Add attachment or patch' |
18 | 237 | return Link('+addcomment', text, icon='add') | 238 | return Link('+addcomment', text, icon='add') |
19 | 238 | 239 | ||
20 | 239 | def addbranch(self): | 240 | def addbranch(self): |
21 | @@ -461,6 +462,20 @@ | |||
22 | 461 | else: | 462 | else: |
23 | 462 | return 'subscribed-false %s' % dup_class | 463 | return 'subscribed-false %s' % dup_class |
24 | 463 | 464 | ||
25 | 465 | @property | ||
26 | 466 | def regular_attachments(self): | ||
27 | 467 | """The list of bug attachments that are not patches.""" | ||
28 | 468 | return [attachment | ||
29 | 469 | for attachment in self.context.attachments | ||
30 | 470 | if attachment.type != BugAttachmentType.PATCH] | ||
31 | 471 | |||
32 | 472 | @property | ||
33 | 473 | def patches(self): | ||
34 | 474 | """The list of bug attachments that are patches.""" | ||
35 | 475 | return [attachment | ||
36 | 476 | for attachment in self.context.attachments | ||
37 | 477 | if attachment.type == BugAttachmentType.PATCH] | ||
38 | 478 | |||
39 | 464 | 479 | ||
40 | 465 | class BugView(LaunchpadView, BugViewMixin): | 480 | class BugView(LaunchpadView, BugViewMixin): |
41 | 466 | """View class for presenting information about an `IBug`. | 481 | """View class for presenting information about an `IBug`. |
42 | 467 | 482 | ||
43 | === modified file 'lib/lp/bugs/stories/bugattachments/20-edit-bug-attachment.txt' | |||
44 | --- lib/lp/bugs/stories/bugattachments/20-edit-bug-attachment.txt 2009-08-31 20:03:29 +0000 | |||
45 | +++ lib/lp/bugs/stories/bugattachments/20-edit-bug-attachment.txt 2009-12-09 16:34:17 +0000 | |||
46 | @@ -1,44 +1,60 @@ | |||
47 | 1 | We can also edit the attachment details, let's navigate to that page. | 1 | We can also edit the attachment details, let's navigate to that page. |
48 | 2 | 2 | ||
53 | 3 | >>> user_browser.open('http://bugs.launchpad.dev/firefox/+bug/1') | 3 | >>> user_browser.open('http://bugs.launchpad.dev/firefox/+bug/1') |
54 | 4 | >>> user_browser.getLink(url='+attachment/1').click() | 4 | >>> user_browser.getLink(url='+attachment/1').click() |
55 | 5 | >>> user_browser.url | 5 | >>> user_browser.url |
56 | 6 | 'http://bugs.launchpad.dev/firefox/+bug/1/+attachment/1' | 6 | 'http://bugs.launchpad.dev/firefox/+bug/1/+attachment/1' |
57 | 7 | 7 | ||
60 | 8 | >>> 'Bug #1 - Edit attachment' in user_browser.contents | 8 | >>> 'Bug #1 - Edit attachment' in user_browser.contents |
61 | 9 | True | 9 | True |
62 | 10 | 10 | ||
63 | 11 | There's also an option to cancel, which takes you back to the bug | 11 | There's also an option to cancel, which takes you back to the bug |
64 | 12 | page, maintaining the firefox context. | 12 | page, maintaining the firefox context. |
65 | 13 | 13 | ||
68 | 14 | >>> user_browser.getLink('Cancel') | 14 | >>> user_browser.getLink('Cancel') |
69 | 15 | <Link text='Cancel' url='http://bugs.launchpad.dev/firefox/+bug/1'> | 15 | <Link text='Cancel' url='http://bugs.launchpad.dev/firefox/+bug/1'> |
70 | 16 | 16 | ||
71 | 17 | After editing the attachment details (we leave some leading and trailing | 17 | After editing the attachment details (we leave some leading and trailing |
72 | 18 | whitespace to test that's correctly stripped)... | 18 | whitespace to test that's correctly stripped)... |
73 | 19 | 19 | ||
77 | 20 | >>> user_browser.getControl('Title').value = ' Another title ' | 20 | >>> user_browser.getControl('Title').value = ' Another title ' |
78 | 21 | >>> user_browser.getControl('Content Type').value = 'text/html' | 21 | >>> user_browser.getControl('Content Type').value = 'text/html' |
79 | 22 | >>> user_browser.getControl('Change').click() | 22 | >>> user_browser.getControl('Change').click() |
80 | 23 | 23 | ||
81 | 24 | ...we're redirected to the bug page | 24 | ...we're redirected to the bug page |
82 | 25 | 25 | ||
102 | 26 | >>> user_browser.url | 26 | >>> user_browser.url |
103 | 27 | 'http://bugs.launchpad.dev/firefox/+bug/1' | 27 | 'http://bugs.launchpad.dev/firefox/+bug/1' |
104 | 28 | 28 | ||
105 | 29 | >>> 'Another title' in user_browser.contents | 29 | >>> 'Another title' in user_browser.contents |
106 | 30 | True | 30 | True |
107 | 31 | 31 | ||
108 | 32 | And if we edit it to be a patch the content type will be automatically | 32 | We can edit the attachment to be a patch. |
109 | 33 | changed to be text/plain. | 33 | |
110 | 34 | 34 | >>> user_browser.getLink(url='+attachment/1').click() | |
111 | 35 | >>> user_browser.getLink(url='+attachment/1').click() | 35 | >>> user_browser.getControl('This attachment is a patch').selected = True |
112 | 36 | >>> user_browser.getControl('This attachment is a patch').selected = True | 36 | >>> user_browser.getControl('Change').click() |
113 | 37 | >>> user_browser.getControl('Change').click() | 37 | |
114 | 38 | 38 | >>> user_browser.url | |
115 | 39 | >>> user_browser.url | 39 | 'http://bugs.launchpad.dev/firefox/+bug/1' |
116 | 40 | 'http://bugs.launchpad.dev/firefox/+bug/1' | 40 | |
117 | 41 | 41 | The attachment that became a patch is now shown in the portlet "Patches"... | |
118 | 42 | >>> user_browser.getLink(url='+attachment/1').click() | 42 | |
119 | 43 | >>> user_browser.getControl('Content Type').value | 43 | >>> patches = find_portlet(user_browser.contents, 'Patches') |
120 | 44 | 'text/plain' | 44 | >>> for li_tag in patches.findAll('li', 'download-attachment'): |
121 | 45 | ... print li_tag.a.renderContents() | ||
122 | 46 | Another title | ||
123 | 47 | |||
124 | 48 | ...while it is gone from the portlet "Bug attachments". | ||
125 | 49 | |||
126 | 50 | >>> attachments = find_portlet(user_browser.contents, 'Bug attachments') | ||
127 | 51 | >>> for li_tag in attachments.findAll('li', 'download-attachment'): | ||
128 | 52 | ... print li_tag.a.renderContents() | ||
129 | 53 | bar.txt | ||
130 | 54 | |||
131 | 55 | The content type of a patch is automatically changed to text/plain. | ||
132 | 56 | |||
133 | 57 | >>> user_browser.getLink(url='+attachment/1').click() | ||
134 | 58 | >>> user_browser.getControl('Content Type').value | ||
135 | 59 | 'text/plain' | ||
136 | 60 | |||
137 | 45 | 61 | ||
138 | === modified file 'lib/lp/bugs/stories/bugs/xx-bug-index.txt' | |||
139 | --- lib/lp/bugs/stories/bugs/xx-bug-index.txt 2009-09-23 11:10:00 +0000 | |||
140 | +++ lib/lp/bugs/stories/bugs/xx-bug-index.txt 2009-12-09 16:34:17 +0000 | |||
141 | @@ -127,10 +127,10 @@ | |||
142 | 127 | >>> print user_browser.getLink('List open bugs').url | 127 | >>> print user_browser.getLink('List open bugs').url |
143 | 128 | http://launchpad.dev/ubuntu/+source/mozilla-firefox/+bugs | 128 | http://launchpad.dev/ubuntu/+source/mozilla-firefox/+bugs |
144 | 129 | 129 | ||
147 | 130 | There's also a link on the page that will take the user to the "Add an | 130 | There's also a link on the page that will take the user to the "Add |
148 | 131 | attachment" page, for use when JavaScript isn't available. | 131 | attachment or patch" page, for use when JavaScript isn't available. |
149 | 132 | 132 | ||
151 | 133 | >>> print user_browser.getLink('Add an attachment').url | 133 | >>> print user_browser.getLink('Add attachment or patch').url |
152 | 134 | http://bugs.launchpad.dev/ubuntu/+source/.../+bug/1/+addcomment | 134 | http://bugs.launchpad.dev/ubuntu/+source/.../+bug/1/+addcomment |
153 | 135 | 135 | ||
154 | 136 | 136 | ||
155 | 137 | 137 | ||
156 | === modified file 'lib/lp/bugs/templates/bug-portlet-attachments.pt' | |||
157 | --- lib/lp/bugs/templates/bug-portlet-attachments.pt 2009-09-22 16:35:00 +0000 | |||
158 | +++ lib/lp/bugs/templates/bug-portlet-attachments.pt 2009-12-09 16:34:17 +0000 | |||
159 | @@ -2,26 +2,50 @@ | |||
160 | 2 | xmlns:tal="http://xml.zope.org/namespaces/tal" | 2 | xmlns:tal="http://xml.zope.org/namespaces/tal" |
161 | 3 | xmlns:metal="http://xml.zope.org/namespaces/metal" | 3 | xmlns:metal="http://xml.zope.org/namespaces/metal" |
162 | 4 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" | 4 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
185 | 5 | class="portlet" id="portlet-attachments" | 5 | tal:omit-tag=""> |
186 | 6 | tal:condition="context/attachments"> | 6 | <div tal:condition="view/regular_attachments" class="portlet" |
187 | 7 | <h2>Bug attachments</h2> | 7 | id="portlet-attachments"> |
188 | 8 | <ul> | 8 | <h2>Bug attachments</h2> |
189 | 9 | <li class="download-attachment" | 9 | <ul> |
190 | 10 | tal:repeat="attachment context/attachments"> | 10 | <li class="download-attachment" |
191 | 11 | <a tal:attributes="href attachment/libraryfile/http_url" | 11 | tal:repeat="attachment view/regular_attachments"> |
192 | 12 | tal:content="attachment/title" | 12 | <a tal:attributes="href attachment/libraryfile/http_url" |
193 | 13 | class="sprite download-icon"> | 13 | tal:content="attachment/title" |
194 | 14 | Attachment Title | 14 | class="sprite download-icon"> |
195 | 15 | </a> | 15 | Attachment Title |
196 | 16 | <small> | 16 | </a> |
197 | 17 | (<a tal:attributes="href attachment/fmt:url">edit</a>) | 17 | <small> |
198 | 18 | </small> | 18 | (<a tal:attributes="href attachment/fmt:url">edit</a>) |
199 | 19 | </li> | 19 | </small> |
200 | 20 | </ul> | 20 | </li> |
201 | 21 | <ul> | 21 | </ul> |
202 | 22 | <li> | 22 | <ul> |
203 | 23 | <a tal:attributes="href view/current_bugtask/fmt:url/+addcomment" | 23 | <li> |
204 | 24 | class="sprite add">Add</a> | 24 | <a tal:attributes="href view/current_bugtask/fmt:url/+addcomment" |
205 | 25 | </li> | 25 | class="sprite add">Add attachment</a> |
206 | 26 | </ul> | 26 | </li> |
207 | 27 | </ul> | ||
208 | 28 | </div> | ||
209 | 29 | <div tal:condition="view/patches" class="portlet" id="portlet-patches"> | ||
210 | 30 | <h2>Patches</h2> | ||
211 | 31 | <ul> | ||
212 | 32 | <li class="download-attachment" | ||
213 | 33 | tal:repeat="attachment view/patches"> | ||
214 | 34 | <a tal:attributes="href attachment/libraryfile/http_url" | ||
215 | 35 | tal:content="attachment/title" | ||
216 | 36 | class="sprite download-icon"> | ||
217 | 37 | Attachment Title | ||
218 | 38 | </a> | ||
219 | 39 | <small> | ||
220 | 40 | (<a tal:attributes="href attachment/fmt:url">edit</a>) | ||
221 | 41 | </small> | ||
222 | 42 | </li> | ||
223 | 43 | </ul> | ||
224 | 44 | <ul> | ||
225 | 45 | <li> | ||
226 | 46 | <a tal:attributes="href view/current_bugtask/fmt:url/+addcomment" | ||
227 | 47 | class="sprite add">Add patch</a> | ||
228 | 48 | </li> | ||
229 | 49 | </ul> | ||
230 | 50 | </div> | ||
231 | 27 | </div> | 51 | </div> |
This branch adds a separate portlet to show patches on a bug page; the portlet does no longer show them (bug 344054).
The implementation is quite straightfoward, I think:
- the template lib/lp/ bugs/templates/ bug-portlet- attachments. pt now creates two portlets instead of one
- class Bug has two new properties returning the list of patches and non-patch attachmentsm respectively
- doc test for the new properties
- changed pagetest.
test: ./bin/test -vv -f lp.bugs bugattachments
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: bugs/configure. zcml bugs/doc/ bugattachments. txt bugs/interfaces /bug.py bugs/model/ bug.py bugs/stories/ bugattachments/ 20-edit- bug-attachment. txt bugs/templates/ bug-portlet- attachments. pt
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
== Pylint notices ==
lib/lp/ bugs/interfaces /bug.py declarations' (No module named restful) fields' (No module named restful) interface' (No module named restful) TextLine( ), is_patch=Bool(), type=TextLine( ), description=Text()) factory_ operation( IBugAttachment, []) owner, data, comment, filename, is_patch=False, type=None, description=None): ions] Operator not preceded by a space =List( _("Nominations to search through."), type=Reference( schema= Interface) , # IBugNomination False)) returns_ collection_ of(Interface) # IBugNomination read_operation( ) target= None, nominations=None): fected] Operator not preceded by a space with(user= REQUEST_ USER) write_operation () d(user, affected=True): Visibility] Operator not preceded by a space Bool(title= _('Show this comment?'), required=True)) with(user= REQUEST_ USER) write_operation () ility(user, comment_number, visible): ission] Operator not preceded by a space write_operation () n(submission) : bmission] Operator not preceded by a space write_operation () ion(submission) :
49: [F0401] Unable to import 'lazr.restful.
55: [F0401] Unable to import 'lazr.restful.
56: [F0401] Unable to import 'lazr.restful.
476: [C0322, IBug.addAttachment] Operator not preceded by a space
comment=Text(), filename=
^
content_
@export_
def addAttachment(
content_
611: [C0322, IBug.getNominat
nominations
^
title=
value_
required=
@operation_
@export_
def getNominations(
691: [C0322, IBug.markUserAf
required=False, default=True))
^
@call_
@export_
def markUserAffecte
706: [C0322, IBug.setComment
required=True),
^
visible=
@call_
@export_
def setCommentVisib
718: [C0322, IBug.linkHWSubm
Interface, title=_('A HWDB submission'), required=True))
^
@export_
def linkHWSubmissio
725: [C0322, IBug.unlinkHWSu
Interface, title=_('A HWDB submission'), required=True))
^
@export_
def unlinkHWSubmiss
lib/lp/ bugs/model/ bug.py .event' (No module named lifecycle)
25: [F0401] Unable to import 'email.Utils' (No module named Utils)
38: [F0401] Unable to import 'lazr.lifecycle
40: [F0401] Unable to import 'lazr.lifecyc...