Merge lp:~allenap/launchpad/ui-convert-filebug-3.0-bug-415263-search into lp:launchpad

Proposed by Gavin Panella
Status: Merged
Merged at revision: not available
Proposed branch: lp:~allenap/launchpad/ui-convert-filebug-3.0-bug-415263-search
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~allenap/launchpad/ui-convert-filebug-3.0-bug-415263-search
Reviewer Review Type Date Requested Status
Michael Nelson (community) ui Approve
Martin Albisetti (community) ui Approve
Brad Crittenden (community) code Approve
Review via email: mp+10321@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

This converts the +filebug search page to the 3.0 layout, using the
main_only layout. This included removing the "Most frequently reported
bugs" area, which, after discussion with noodles, wgrant and beuno, is
basically not very useful, especially in comparison with the more
accurate, detailed and useful duplicate listing shown on the following
page.

Test: ./bin/test -vvt filebug

Lint free.

lib/lp/bugs/browser/bugtarget.py

  Removed the most_common_bugs and found_possible_duplicates
  properties. The first, most_common_bugs, was only used by the "Most
  frequently reported bugs" area, and found_possible_duplicates was
  already unused.

  Also, I removed a little lint.

lib/lp/bugs/doc/minimizing-duplicate-bug-reports.txt

  I also removed the IBugTarget.getMostCommonBugs() method because,
  list the most_common_bugs property above, was only used for the
  +filebug search page. This test was entirely about
  getMostCommonBugs(), so I removed it too.

lib/lp/bugs/interfaces/bugtarget.py
lib/lp/bugs/model/bugtarget.py

  getMostCommonBugs() removed.

lib/lp/bugs/stories/guided-filebug/xx-displaying-similar-bugs.txt
lib/lp/bugs/stories/guided-filebug/xx-distro-guided-filebug.txt
lib/lp/bugs/stories/guided-filebug/xx-distro-sourcepackage-guided-filebug.txt
lib/lp/bugs/stories/guided-filebug/xx-product-guided-filebug.txt

  "Most frequently reported bugs" area removed, so tests for it
  removed too.

lib/lp/bugs/templates/bugtarget-filebug-search.pt

  Template converted. The only interesting thing here was the extra
  condition around the not_uses_malone macro call. The not_uses_malone
  macro already checks the same condition, but I think that the
  condition should be checked in the calling template instead. Once
  the other templates that use the not_uses_malone macro have been
  converted to follow this style, the condition in the macro will be
  removed.

lib/lp/bugs/tests/bug.py

  The print_bugs_table() helper was only used in one place. That place
  has now gone, so the helper goes too.

lib/lp/registry/configure.zcml

  Remove getMostCommonBugs.

Revision history for this message
Michael Nelson (michael.nelson) wrote :
Download full text (3.9 KiB)

Hi Gavin,

It looks *so* much friendlier!

As I mentioned via irc, I had a few things that I was uncertain about - so I'll need to defer to Martin or Curtis:

1. At first I thought that you should be using the default <h2>context.title</h2> in the 'heading' slot - but then you rightly pointed out that this would fall into the case of the same heading twice - so we think that overriding with the h1 heading is correct (fits with Curtis' email "because showing two identical titles is stupid" but the page_title is *not* the same as the context.title here - hence the uncertainty).

2. Since you are (currently) over-riding the heading slot with an h1, you will not define view.label, otherwise the form machinery will add a second h1 to the page.

3. I'm aware that the way we designate privacy generally has changed (see base-layout.pt), but in your case you're indicating that the future bug to be created will be private - I don't know if this needs to follow the same style? Martin?

Sorry - that wasn't much help in terms of a review :/

<noodles775> Thanks allenap.... initial thoughts - it looks *much* friendlier!
<allenap> noodles775: The diff generated is complete rubbish :( I forget to target the branch to devel.
<noodles775> np.
<allenap> noodles775: But, yeah, it does look much better :)
<allenap> noodles775: I'm going to recreate the mp, so don't comment on it yet.
<noodles775> ok
* sinzui has quit (Remote closed the connection)
<allenap> noodles775: https://code.edge.launchpad.net/~allenap/launchpad/ui-convert-filebug-3.0-bug-415263-search/+merge/10321
<noodles775> allenap: have you made ff a private project for that screenshot? Or why is the report private by default there (I saw that it's not locally)
<allenap> noodles775: I set bugs private by default for ff.
<noodles775> allenap: OK, so it looks great, but there are two things I'm uncertain about.
<allenap> noodles775: Hit me with the bad news!
<noodles775> allenap: first, you've used <h1>Report a bug</h1> in the 'heading' slot, where as, if I've understood sinzui's email correctly, that should be displaying the default h2 context.title there,
<noodles775> allenap: and your h1 should be displayed by lpform macro automatically (if you define view.label).
<noodles775> allenap: secondly, I haven't seen the latest discussions on the privacy indicators, but I thought we were using a global privacy indicator, rather than custom ones like you've put into the 'heading' slot there?
* noodles775 checks the template.
<allenap> noodles775: The first point - displaying context.title in the heading slot - seems strange. The title is already on the page, just above.
<allenap> noodles775: The second point - view.label - I'll look into now.
* jtv has quit ("Leaving.")
<allenap> noodles775: The privacy indicator was preserved from the old version of the template. I don't know what the new style is for private things, but I'm happy to adopt it :)
<noodles775> allenap: the view.label for forms is described in the email on lp-dev.
<noodles775> allenap: and yes, with the first point, I think you're right - it fits into the case where displaying the same heading twice is silly :)
* henninge has quit ("Ex-Chat")
...

Read more...

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

I meant to save the previous one with Needs Information.

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

> Hi Gavin,
>
> It looks *so* much friendlier!
>
> As I mentioned via irc, I had a few things that I was uncertain about - so
> I'll need to defer to Martin or Curtis:
>
> 1. At first I thought that you should be using the default
> <h2>context.title</h2> in the 'heading' slot - but then you rightly pointed
> out that this would fall into the case of the same heading twice - so we think
> that overriding with the h1 heading is correct (fits with Curtis' email
> "because showing two identical titles is stupid" but the page_title is *not*
> the same as the context.title here - hence the uncertainty).
>

But:

noodles775> allenap: actually, I just realised - you've got two h1's there - as the heading in the branding is already h1 - so you should definitely be using an h2 in the 'heading' fill-slot.
<noodles775> Here's a good example to work from: https://edge.launchpad.net/ubuntu/+search
<noodles775> (Curtis did that one :) ).

And looking at some other approved landings:

https://edge.launchpad.net/ubuntu/+ppas

it looks like you should be using the default h2 for the breadcrumb heading even though it repeats the heading, and the form's view.label defining the h1 heading in the main content.

Again, I'm sorry that I can't yet be more definitive :/.

Revision history for this message
Brad Crittenden (bac) wrote :

The code looks good Gavin.

review: Approve (code)
Revision history for this message
Martin Albisetti (beuno) wrote :

Hi Gavin,

This looks so much better without that initial list. Good call.
I do have, however, comments:

- The second step of the bug report shows me the old UI, even though it appears to be the same URL. Could you make sure that this only lands with both steps using the same UI?
- How about moving the "continue" button right next to the input, and maybe rename it to "next", like in our 3.0 mockup? https://wiki.canonical.com/Launchpad/UI/Bugs/ThreeDotO/FileBug
- You have 2 h1's on the page. There should only be 1, in this case, the "Report a bug". The projects' name should be an h2. Talk to Curtis if you're not sure how to fix that

Otherwise, looking forward to this landing.

review: Needs Fixing (ui)
Revision history for this message
Gavin Panella (allenap) wrote :

> Hi Gavin,
>
> This looks so much better without that initial list. Good call.
> I do have, however, comments:

Thanks for looking at it :)

>
> - The second step of the bug report shows me the old UI, even though it
> appears to be the same URL. Could you make sure that this only lands with both
> steps using the same UI?

Sure. I already have a follow-on branch that does this, so I'll land
them together.

> - How about moving the "continue" button right next to the input, and maybe
> rename it to "next", like in our 3.0 mockup?
> https://wiki.canonical.com/Launchpad/UI/Bugs/ThreeDotO/FileBug

The form is being rendered by launchpad-form, which does not allow
more than one widget per row. To get the button to display on the same
row means either doing big work on launchpad-form, or bypassing it,
which would lose us a lot and adds a big maintenance overhead.

Also, as Bjorn has just mentioned in our stand-up call, we very much
need to pick up the pace of template conversions, so I'd like to leave
these kinds of changes for the second round.

Can we leave this for now, and perhaps schedule some work on
launchpad-form?

> - You have 2 h1's on the page. There should only be 1, in this case, the
> "Report a bug". The projects' name should be an h2. Talk to Curtis if you're
> not sure how to fix that

This seems to be a rule in the location_heading formatter:

        if not IHasLogo.providedBy(context):
            context = nearest(context, IHasLogo)
            heading = 'h2'
        else:
            heading = 'h1'

On the +filebug page, the context is the project (or distribution,
etc), so this is always going to end up as an h1. I'll talk to Curtis
about it.

For now, I've changed the "Report a bug" to an h2, which noodles
suggested.

Gavin.

Revision history for this message
Martin Albisetti (beuno) wrote :

> The form is being rendered by launchpad-form, which does not allow
> more than one widget per row. To get the button to display on the same
> row means either doing big work on launchpad-form, or bypassing it,
> which would lose us a lot and adds a big maintenance overhead.

I really hate these zope forms.

> Also, as Bjorn has just mentioned in our stand-up call, we very much
> need to pick up the pace of template conversions, so I'd like to leave
> these kinds of changes for the second round.
>
> Can we leave this for now, and perhaps schedule some work on
> launchpad-form?

Yes, go for it.

> For now, I've changed the "Report a bug" to an h2, which noodles
> suggested.

Great, thank you.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/bugs/browser/bugtarget.py'
--- lib/lp/bugs/browser/bugtarget.py 2009-08-17 17:09:23 +0000
+++ lib/lp/bugs/browser/bugtarget.py 2009-08-18 11:14:07 +0000
@@ -463,7 +463,6 @@
463 security_related = data.get("security_related", False)463 security_related = data.get("security_related", False)
464 distribution = data.get(464 distribution = data.get(
465 "distribution", getUtility(ILaunchBag).distribution)465 "distribution", getUtility(ILaunchBag).distribution)
466 product = getUtility(ILaunchBag).product
467466
468 context = self.context467 context = self.context
469 if distribution is not None:468 if distribution is not None:
@@ -897,20 +896,6 @@
897896
898 return search_context897 return search_context
899898
900 @cachedproperty
901 def most_common_bugs(self):
902 """Return a list of the most duplicated bugs."""
903 search_context = self.search_context
904 if search_context is None:
905 return []
906 else:
907 return search_context.getMostCommonBugs(
908 self.user, limit=self._MATCHING_BUGS_LIMIT)
909
910 @property
911 def found_possible_duplicates(self):
912 return self.similar_bugs or self.most_common_bugs
913
914 @property899 @property
915 def search_text(self):900 def search_text(self):
916 """Return the search string entered by the user."""901 """Return the search string entered by the user."""
@@ -972,18 +957,6 @@
972 " product the user selected.")957 " product the user selected.")
973 return self.widgets['product'].getInputValue()958 return self.widgets['product'].getInputValue()
974959
975 @cachedproperty
976 def most_common_bugs(self):
977 """Return a list of the most duplicated bugs."""
978 # We can only discover the most common bugs when a product has
979 # been selected.
980 if self.widgets['product'].hasValidInput():
981 selected_product = self._getSelectedProduct()
982 return selected_product.getMostCommonBugs(
983 self.user, limit=self._MATCHING_BUGS_LIMIT)
984 else:
985 return []
986
987 def getSecurityContext(self):960 def getSecurityContext(self):
988 """See FileBugViewBase."""961 """See FileBugViewBase."""
989 return self._getSelectedProduct()962 return self._getSelectedProduct()
@@ -1098,7 +1071,7 @@
1098 """See FileBugViewBase."""1071 """See FileBugViewBase."""
1099 try:1072 try:
1100 bugtarget = self.widgets['bugtarget'].getInputValue()1073 bugtarget = self.widgets['bugtarget'].getInputValue()
1101 except InputErrors, error:1074 except InputErrors:
1102 return None1075 return None
1103 if IDistributionSourcePackage.providedBy(bugtarget):1076 if IDistributionSourcePackage.providedBy(bugtarget):
1104 return bugtarget.distribution1077 return bugtarget.distribution
11051078
=== removed file 'lib/lp/bugs/doc/minimizing-duplicate-bug-reports.txt'
--- lib/lp/bugs/doc/minimizing-duplicate-bug-reports.txt 2009-06-12 16:36:02 +0000
+++ lib/lp/bugs/doc/minimizing-duplicate-bug-reports.txt 1970-01-01 00:00:00 +0000
@@ -1,95 +0,0 @@
1Minimizing Duplicate Bug Reports
2================================
3
4Malone does its best to discourage duplicate bug report filing. The
5default filebug workflow, for example, guides the user through a search
6for duplicate bugs before allowing the bug to actually be filed.
7
8IBugTarget has a getMostCommonBugs() method which returns a list of bugs
9ordered by number of dupes, most-duped to least-duped.
10
11(First, let's add some more duplicate bug sample data.)
12
13 >>> from zope.component import getUtility
14 >>> from canonical.database.sqlbase import flush_database_updates
15 >>> from canonical.launchpad.interfaces import (
16 ... IBugSet, CreateBugParams, IDistributionSet, IProductSet,
17 ... ILaunchBag)
18
19 >>> login("no-priv@canonical.com")
20
21 >>> bugset = getUtility(IBugSet)
22 >>> bug_five = bugset.get(5)
23 >>> bug_one = bugset.get(1)
24
25 >>> firefox = getUtility(IProductSet).getByName("firefox")
26 >>> ubuntu = getUtility(IDistributionSet).getByName("ubuntu")
27 >>> ubuntu_firefox = ubuntu.getSourcePackage("mozilla-firefox")
28 >>> current_user = getUtility(ILaunchBag).user
29 >>> params = CreateBugParams(
30 ... owner=current_user, title="a duplicate bug",
31 ... comment="this bug is a duplicate")
32 >>> bug_five_dupe = firefox.createBug(params)
33 >>> bug_five_dupe.duplicateof = bug_five
34 >>> bug_one_dupe = firefox.createBug(params)
35 >>> bug_one_dupe.duplicateof = bug_one
36
37 >>> flush_database_updates()
38
39By default, 10 bugs are returned by getMostCommonBugs().
40
41 >>> for bug in firefox.getMostCommonBugs(current_user):
42 ... print "%s, %s" % (bug.title, bug.duplicates.count())
43 Firefox install instructions should be complete, 2
44 Firefox does not support SVG, 1
45
46 >>> for bug in ubuntu_firefox.getMostCommonBugs(current_user):
47 ... print "%s, %s" % (bug.title, bug.duplicates.count())
48 Firefox does not support SVG, 1
49
50If we ask for just one bug, we get only one.
51
52 >>> for bug in firefox.getMostCommonBugs(current_user, limit=1):
53 ... print "%s, %s" % (bug.title, bug.duplicates.count())
54 Firefox install instructions should be complete, 2
55
56getMostCommonBugs() is also privacy aware. If bug one is marked
57private, we will no longer see it in the results, because no-priv is
58not subscribed to the bug. Note that setPrivate adds all indirect
59subscribers as direct subscribers to the bug so we must unsubscribe
60immediately.
61
62 >>> print current_user.name
63 no-priv
64
65 >>> bug_one.isSubscribed(current_user)
66 False
67 >>> bug_one.setPrivate(True, current_user)
68 True
69 >>> bug_one.isSubscribed(current_user)
70 True
71 >>> bug_one.unsubscribe(current_user, current_user)
72 >>> flush_database_updates()
73
74 >>> for bug in firefox.getMostCommonBugs(current_user):
75 ... print "%s, %s" % (bug.title, bug.duplicates.count())
76 Firefox install instructions should be complete, 2
77
78An admin will, of course, see the private bug.
79
80 >>> login("foo.bar@canonical.com")
81
82 >>> current_user = getUtility(ILaunchBag).user
83
84 >>> for bug in firefox.getMostCommonBugs(current_user):
85 ... print "%s, %s" % (bug.title, bug.duplicates.count())
86 Firefox install instructions should be complete, 2
87 Firefox does not support SVG, 1
88
89When the context has no duplicate bugs, an empty list is returned.
90
91 >>> from canonical.launchpad.interfaces import IDistributionSet
92
93 >>> kubuntu = getUtility(IDistributionSet).getByName("kubuntu")
94 >>> kubuntu.getMostCommonBugs(current_user)
95 []
960
=== modified file 'lib/lp/bugs/interfaces/bugtarget.py'
--- lib/lp/bugs/interfaces/bugtarget.py 2009-07-17 00:26:05 +0000
+++ lib/lp/bugs/interfaces/bugtarget.py 2009-08-18 11:12:06 +0000
@@ -244,13 +244,6 @@
244 required=False,244 required=False,
245 max_length=50000))245 max_length=50000))
246246
247 def getMostCommonBugs(user, limit=10):
248 """Return the list of most commonly-reported bugs.
249
250 This is the list of bugs that have the most dupes, ordered from
251 most to least duped.
252 """
253
254 def createBug(bug_params):247 def createBug(bug_params):
255 """Create a new bug on this target.248 """Create a new bug on this target.
256249
257250
=== modified file 'lib/lp/bugs/model/bugtarget.py'
--- lib/lp/bugs/model/bugtarget.py 2009-07-17 00:26:05 +0000
+++ lib/lp/bugs/model/bugtarget.py 2009-08-18 11:14:07 +0000
@@ -162,7 +162,6 @@
162 statuses = BugTaskStatus.items162 statuses = BugTaskStatus.items
163 statuses = list(statuses)163 statuses = list(statuses)
164164
165 from_tables = ['BugTask', 'Bug']
166 count_column = """165 count_column = """
167 COUNT (CASE WHEN BugTask.status = %s166 COUNT (CASE WHEN BugTask.status = %s
168 THEN BugTask.id ELSE NULL END)"""167 THEN BugTask.id ELSE NULL END)"""
@@ -190,37 +189,6 @@
190189
191 All IBugTargets should inherit from this class.190 All IBugTargets should inherit from this class.
192 """191 """
193 def getMostCommonBugs(self, user, limit=10):
194 """See canonical.launchpad.interfaces.IBugTarget."""
195 constraints = []
196 bug_privacy_clause = get_bug_privacy_filter(user)
197 if bug_privacy_clause:
198 constraints.append(bug_privacy_clause)
199 constraints.append(self._getBugTaskContextWhereClause())
200 c = cursor()
201 c.execute("""
202 SELECT duplicateof, COUNT(duplicateof)
203 FROM Bug
204 WHERE duplicateof IN (
205 SELECT DISTINCT(Bug.id)
206 FROM Bug, BugTask
207 WHERE BugTask.bug = Bug.id AND
208 %s)
209 GROUP BY duplicateof
210 ORDER BY COUNT(duplicateof) DESC
211 LIMIT %d
212 """ % ("AND\n".join(constraints), limit))
213
214 common_bug_ids = [
215 str(bug_id) for (bug_id, dupe_count) in c.fetchall()]
216
217 if not common_bug_ids:
218 return []
219 # import this database class here, in order to avoid
220 # circular dependencies.
221 from lp.bugs.model.bug import Bug
222 return list(
223 Bug.select("Bug.id IN (%s)" % ", ".join(common_bug_ids)))
224192
225193
226class OfficialBugTagTargetMixin:194class OfficialBugTagTargetMixin:
227195
=== modified file 'lib/lp/bugs/stories/guided-filebug/xx-displaying-similar-bugs.txt'
--- lib/lp/bugs/stories/guided-filebug/xx-displaying-similar-bugs.txt 2009-07-31 17:30:34 +0000
+++ lib/lp/bugs/stories/guided-filebug/xx-displaying-similar-bugs.txt 2009-08-18 11:04:38 +0000
@@ -28,8 +28,6 @@
28the summary entered (assuming some are found).28the summary entered (assuming some are found).
2929
30 >>> user_browser.open("http://bugs.launchpad.dev/firefox/+filebug")30 >>> user_browser.open("http://bugs.launchpad.dev/firefox/+filebug")
31 >>> print find_tag_by_id(user_browser.contents, 'frequent-bugs')
32 <h2 id="frequent-bugs">Most frequently reported bugs</h2>
33 >>> user_browser.getControl("Summary").value = 'a'31 >>> user_browser.getControl("Summary").value = 'a'
34 >>> user_browser.getControl("Continue").click()32 >>> user_browser.getControl("Continue").click()
3533
3634
=== modified file 'lib/lp/bugs/stories/guided-filebug/xx-distro-guided-filebug.txt'
--- lib/lp/bugs/stories/guided-filebug/xx-distro-guided-filebug.txt 2009-07-15 13:22:29 +0000
+++ lib/lp/bugs/stories/guided-filebug/xx-distro-guided-filebug.txt 2009-08-18 11:04:38 +0000
@@ -5,14 +5,6 @@
55
6 >>> user_browser.open("http://launchpad.dev/ubuntu/+filebug")6 >>> user_browser.open("http://launchpad.dev/ubuntu/+filebug")
77
8There are no duplicate bugs reported in Ubuntu so the most common bugs
9table is not shown.
10
11 >>> most_common_bugs_table = find_tag_by_id(
12 ... user_browser.contents, "most-common-bugs")
13 >>> print most_common_bugs_table
14 None
15
16Submitting a bug title...8Submitting a bug title...
179
18 >>> user_browser.getControl("Summary").value = (10 >>> user_browser.getControl("Summary").value = (
1911
=== modified file 'lib/lp/bugs/stories/guided-filebug/xx-distro-sourcepackage-guided-filebug.txt'
--- lib/lp/bugs/stories/guided-filebug/xx-distro-sourcepackage-guided-filebug.txt 2009-06-12 16:36:02 +0000
+++ lib/lp/bugs/stories/guided-filebug/xx-distro-sourcepackage-guided-filebug.txt 2009-08-18 11:04:38 +0000
@@ -22,13 +22,6 @@
22 <...22 <...
23 No similar bug reports were found...23 No similar bug reports were found...
2424
25And no duplicated bugs in this package.
26
27 >>> most_common_bugs_table = find_tag_by_id(
28 ... user_browser.contents, "most-common-bugs")
29 >>> most_common_bugs_table is None
30 True
31
32The filebug form looks similar to the normal distro form, but the25The filebug form looks similar to the normal distro form, but the
33package name is prepopulated.26package name is prepopulated.
3427
3528
=== modified file 'lib/lp/bugs/stories/guided-filebug/xx-product-guided-filebug.txt'
--- lib/lp/bugs/stories/guided-filebug/xx-product-guided-filebug.txt 2009-07-15 13:22:29 +0000
+++ lib/lp/bugs/stories/guided-filebug/xx-product-guided-filebug.txt 2009-08-18 11:04:38 +0000
@@ -7,14 +7,6 @@
7 >>> user_browser.open("http://bugs.launchpad.dev/firefox")7 >>> user_browser.open("http://bugs.launchpad.dev/firefox")
8 >>> user_browser.getLink('Report a bug').click()8 >>> user_browser.getLink('Report a bug').click()
99
10On this page and the user is shown a table of the most common bugs in
11the current context.
12
13 >>> from lp.bugs.tests.bug import print_bugs_table
14
15 >>> print_bugs_table(user_browser.contents, "most-common-bugs")
16 5 Firefox install instructions should be complete
17
18If no title is entered, the user is asked to supply one.10If no title is entered, the user is asked to supply one.
1911
20 >>> user_browser.getControl('Summary').value12 >>> user_browser.getControl('Summary').value
2113
=== modified file 'lib/lp/bugs/templates/bugtarget-filebug-search.pt'
--- lib/lp/bugs/templates/bugtarget-filebug-search.pt 2009-07-31 17:30:34 +0000
+++ lib/lp/bugs/templates/bugtarget-filebug-search.pt 2009-08-18 11:04:38 +0000
@@ -1,90 +1,60 @@
1<html1<filebug-search
2 xmlns="http://www.w3.org/1999/xhtml"2 xmlns="http://www.w3.org/1999/xhtml"
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"7
8 dir="ltr"8 <div metal:fill-slot="heading">
9 metal:use-macro="view/macro:page/onecolumn"9 <div tal:condition="view/isPrivate" id="privacy" class="aside private">
10>10 This report will be private, though you can disclose it later.
11<body>11 </div>
1212 <h1>Report a bug</h1>
13<metal:leftportlets fill-slot="portlets_one">13 </div>
14 <div tal:replace="structure context/@@+portlet-latestbugs|nothing" />14
15</metal:leftportlets>15 <div metal:fill-slot="main">
1616 <div class="yui-g">
17<div metal:fill-slot="main">17
1818 <tal:does-not-use-malone condition="not: view/contextUsesMalone">
19 <div tal:condition="view/isPrivate" id="privacy" class="aside private"19 <div class="top-portlet">
20 >This report will be private, though you can disclose it later.</div>20 <metal:not_uses_malone
21 <h1>Report a bug</h1>21 use-macro="context/@@+filebug-macros/not_uses_malone" />
2222 </div>
23<metal:not_uses_malone23 </tal:does-not-use-malone>
24 use-macro="context/@@+filebug-macros/not_uses_malone" />24
2525 <tal:uses-malone tal:condition="view/contextUsesMalone">
26<tal:uses_malone tal:condition="view/contextUsesMalone">26 <div class="top-portlet">
27 <div metal:use-macro="context/@@launchpad_form/form">27 <div metal:use-macro="context/@@launchpad_form/form">
28 <table class="form" metal:fill-slot="widgets">28 <table class="form" metal:fill-slot="widgets">
2929 <tal:product_widget
30 <tal:product_widget30 tal:define="widget nocall:view/widgets/product|nothing"
31 tal:define="widget nocall:view/widgets/product|nothing"31 tal:condition="widget">
32 tal:condition="widget">32 <metal:widget metal:use-macro="context/@@launchpad_form/widget_row" />
33 <metal:widget metal:use-macro="context/@@launchpad_form/widget_row" />33 </tal:product_widget>
34 </tal:product_widget>34 <tal:bugtarget
3535 tal:define="widget nocall:view/widgets/bugtarget|nothing"
36 <tal:bugtarget36 tal:condition="widget">
37 tal:define="widget nocall:view/widgets/bugtarget|nothing"37 <metal:widget metal:use-macro="context/@@launchpad_form/widget_row" />
38 tal:condition="widget">38 </tal:bugtarget>
39 <metal:widget metal:use-macro="context/@@launchpad_form/widget_row" />39 <tal:hidden_tags tal:replace="structure view/widgets/tags/hidden" />
40 </tal:bugtarget>40 <tr>
4141 <td colspan="2">
42 <tal:hidden_tags tal:replace="structure view/widgets/tags/hidden" />42 Please describe the bug in a few words, for example,
4343 "weather applet crashes on logout":
44 <tr>44 </td>
45 <td colspan="2">45 </tr>
46 <p>46 <tal:title_widget tal:define="widget nocall:view/widgets/title">
47 Please describe the bug in a few words, for example, "weather47 <metal:widget use-macro="context/@@launchpad_form/widget_row" />
48 applet crashes on logout":48 </tal:title_widget>
49 </p>49 </table>
50 </td>50 <div class="actions" metal:fill-slot="buttons">
51 </tr>51 <input tal:replace="structure view/actions/field.actions.search/render" />
52 <tal:title_widget tal:define="widget nocall:view/widgets/title">52 </div>
53 <metal:widget use-macro="context/@@launchpad_form/widget_row" />53 </div>
54 </tal:title_widget>54 </div>
55 </table>55 </tal:uses-malone>
5656
57 <div class="actions" metal:fill-slot="buttons">57 </div>
58 <input tal:replace="structure view/actions/field.actions.search/render" />58 </div>
59 </div>59
60 </div>60</filebug-search>
61
62 <tal:most-common-bugs condition="view/most_common_bugs">
63 <h2 id="frequent-bugs">Most frequently reported bugs</h2>
64
65 <table class="listing" id="most-common-bugs">
66 <thead>
67 <tr><th colspan="2">Summary</th></tr>
68 </thead>
69 <tbody>
70 <tr tal:repeat="bug view/most_common_bugs"
71 tal:attributes="title bug/description/fmt:shorten/150"
72 title="bug description goes here">
73 <td class="amount" tal:content="bug/id" width="10%">1</td>
74 <td>
75 <a href="#"
76 tal:content="bug/title"
77 tal:attributes="href bug/fmt:url">
78 Firefox doesn't work
79 </a>
80 </td>
81 </tr>
82 </tbody>
83 </table>
84 </tal:most-common-bugs>
85</tal:uses_malone>
86
87
88 </div>
89 </body>
90</html>
9161
=== modified file 'lib/lp/bugs/tests/bug.py'
--- lib/lp/bugs/tests/bug.py 2009-06-25 00:40:31 +0000
+++ lib/lp/bugs/tests/bug.py 2009-08-18 11:04:38 +0000
@@ -90,21 +90,6 @@
90 print target, extract_text(span.findNext('a'))90 print target, extract_text(span.findNext('a'))
9191
9292
93def print_bugs_table(content, table_id):
94 """Print the bugs table with the given ID.
95
96 The table is assumed to consist of rows of bugs whose first column
97 is a bug ID, and whose second column is a bug title.
98 """
99 bugs_table = find_tag_by_id(content, table_id)
100
101 for tr in bugs_table("tr"):
102 if not tr.td:
103 continue
104 bug_id, bug_title = tr("td", limit=2)
105 print bug_id.string, bug_title.a.string
106
107
108def print_bugs_list(content, list_id):93def print_bugs_list(content, list_id):
109 """Print the bugs list with the given ID.94 """Print the bugs list with the given ID.
11095
11196
=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml 2009-08-12 05:09:36 +0000
+++ lib/lp/registry/configure.zcml 2009-08-18 11:12:06 +0000
@@ -387,7 +387,6 @@
387 getUsedBugTagsWithOpenCounts387 getUsedBugTagsWithOpenCounts
388 bugtargetdisplayname388 bugtargetdisplayname
389 bugtargetname389 bugtargetname
390 getMostCommonBugs
391 getBugCounts390 getBugCounts
392 bug_subscriptions391 bug_subscriptions
393 getSubscriptions392 getSubscriptions