Merge lp:~wallyworld/launchpad/milestone-ajax-batch-nav into lp:launchpad

Proposed by Ian Booth
Status: Work in progress
Proposed branch: lp:~wallyworld/launchpad/milestone-ajax-batch-nav
Merge into: lp:launchpad
Prerequisite: lp:~wallyworld/launchpad/batch-nav-ajax
Diff against target: 633 lines (+294/-143)
11 files modified
lib/lp/app/browser/tests/test_macro_view.py (+0/-1)
lib/lp/bugs/browser/bugtask.py (+1/-1)
lib/lp/registry/browser/configure.zcml (+9/-5)
lib/lp/registry/browser/milestone.py (+90/-10)
lib/lp/registry/interfaces/milestone.py (+9/-0)
lib/lp/registry/templates/milestone-bugtask-listing.pt (+86/-0)
lib/lp/registry/templates/milestone-bugtasks-table.pt (+3/-0)
lib/lp/registry/templates/milestone-index.pt (+10/-61)
lib/lp/registry/templates/milestone-macros.pt (+0/-65)
lib/lp/registry/templates/milestone-specification-listing.pt (+83/-0)
lib/lp/registry/templates/milestone-specifications-table.pt (+3/-0)
To merge this branch: bzr merge lp:~wallyworld/launchpad/milestone-ajax-batch-nav
Reviewer Review Type Date Requested Status
Launchpad code reviewers Pending
Review via email: mp+79052@code.launchpad.net
To post a comment you must log in.
14114. By Ian Booth

Revert rename

Unmerged revisions

14114. By Ian Booth

Revert rename

14113. By Ian Booth

Add ajax batch nav to milestones

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/app/browser/tests/test_macro_view.py'
2--- lib/lp/app/browser/tests/test_macro_view.py 2011-09-01 14:36:10 +0000
3+++ lib/lp/app/browser/tests/test_macro_view.py 2011-10-12 02:44:27 +0000
4@@ -41,7 +41,6 @@
5 '+bmq-macros',
6 '+announcement-macros',
7 '+person-macros',
8- '+milestone-macros',
9 '+distributionmirror-macros',
10 '+timeline-macros',
11 '+macros',
12
13=== modified file 'lib/lp/bugs/browser/bugtask.py'
14--- lib/lp/bugs/browser/bugtask.py 2011-10-12 02:44:27 +0000
15+++ lib/lp/bugs/browser/bugtask.py 2011-10-12 02:44:27 +0000
16@@ -2464,7 +2464,7 @@
17 "columns to show.")
18
19 bugtask_table_template = ViewPageTemplateFile(
20- '../templates/bugs-table-include.pt')
21+ '../templates/bugs-listing-table-include.pt')
22
23 @property
24 def template(self):
25
26=== modified file 'lib/lp/registry/browser/configure.zcml'
27--- lib/lp/registry/browser/configure.zcml 2011-10-04 08:46:11 +0000
28+++ lib/lp/registry/browser/configure.zcml 2011-10-12 02:44:27 +0000
29@@ -1338,11 +1338,15 @@
30 rootsite="mainsite"
31 attribute_to_parent="target"/>
32 <browser:page
33- for="*"
34- name="+milestone-macros"
35- permission="zope.Public"
36- template="../templates/milestone-macros.pt"
37- class="lp.app.browser.launchpad.Macro"/>
38+ for="lp.registry.interfaces.milestone.IMilestoneBugtaskListingBatchNavigator"
39+ name="+listing"
40+ template="../templates/milestone-bugtask-listing.pt"
41+ permission="zope.Public"/>
42+ <browser:page
43+ for="lp.registry.interfaces.milestone.IMilestoneSpecificationListingBatchNavigator"
44+ name="+listing"
45+ template="../templates/milestone-specification-listing.pt"
46+ permission="zope.Public"/>
47 <browser:pages
48 for="lp.registry.interfaces.milestone.IMilestone"
49 class="lp.registry.browser.milestone.MilestoneView"
50
51=== modified file 'lib/lp/registry/browser/milestone.py'
52--- lib/lp/registry/browser/milestone.py 2011-04-18 14:57:42 +0000
53+++ lib/lp/registry/browser/milestone.py 2011-10-12 02:44:27 +0000
54@@ -21,6 +21,8 @@
55 ]
56
57
58+import urlparse
59+from z3c.ptcompat import ViewPageTemplateFile
60 from zope.component import getUtility
61 from zope.formlib import form
62 from zope.interface import (
63@@ -40,6 +42,7 @@
64 from canonical.launchpad.webapp.authorization import (
65 precache_permission_for_objects,
66 )
67+from canonical.launchpad.webapp.batching import TableBatchNavigator
68 from canonical.launchpad.webapp.breadcrumb import Breadcrumb
69 from canonical.launchpad.webapp.menu import (
70 ApplicationMenu,
71@@ -72,6 +75,8 @@
72 IMilestone,
73 IMilestoneSet,
74 IProjectGroupMilestone,
75+ IMilestoneBugtaskListingBatchNavigator,
76+ IMilestoneSpecificationListingBatchNavigator,
77 )
78 from lp.registry.interfaces.person import IPersonSet
79 from lp.registry.interfaces.product import IProduct
80@@ -183,6 +188,49 @@
81 links = ('edit', )
82
83
84+class MilestoneBugTaskListingBatchNavigator(TableBatchNavigator):
85+ """Batch up the milestone bugtask listings."""
86+ implements(IMilestoneBugtaskListingBatchNavigator)
87+
88+ def __init__(self, view):
89+ TableBatchNavigator.__init__(
90+ self, view._bugtasks, view.request)
91+ self.view = view
92+
93+ @cachedproperty
94+ def bugtasks(self):
95+ return [self.view._getListingItem(bugtask)
96+ for bugtask in self.currentBatch()]
97+
98+ @property
99+ def table_class(self):
100+ if self.has_multiple_pages:
101+ return "listing"
102+ else:
103+ return "listing sortable"
104+
105+
106+class MilestoneSpecificationListingBatchNavigator(TableBatchNavigator):
107+ """Batch up the milestone specification listings."""
108+ implements(IMilestoneSpecificationListingBatchNavigator)
109+
110+ def __init__(self, view):
111+ TableBatchNavigator.__init__(
112+ self, view._specifications, view.request)
113+ self.view = view
114+
115+ @cachedproperty
116+ def specifications(self):
117+ return self.currentBatch()
118+
119+ @property
120+ def table_class(self):
121+ if self.has_multiple_pages:
122+ return "listing"
123+ else:
124+ return "listing sortable"
125+
126+
127 class MilestoneView(LaunchpadView, ProductDownloadFileMixin):
128 """A View for listing milestones and releases."""
129 # XXX sinzui 2009-05-29 bug=381672: Extract the BugTaskListingItem rules
130@@ -216,6 +264,23 @@
131 expose_structural_subscription_data_to_js(
132 self.context, self.request, self.user)
133
134+ bugtask_table_template = ViewPageTemplateFile(
135+ '../templates/milestone-bugtasks-table.pt')
136+ specification_table_template = ViewPageTemplateFile(
137+ '../templates/milestone-specifications-table.pt')
138+
139+ @property
140+ def template(self):
141+ query_string = self.request.get('QUERY_STRING', '')
142+ query_params = urlparse.parse_qs(query_string)
143+ batch_request_param = query_params.get('batch_request', None)
144+ if batch_request_param is None:
145+ return super(MilestoneView, self).template
146+ elif 'bugtask_batch' in batch_request_param:
147+ return self.bugtask_table_template
148+ else:
149+ return self.specification_table_template
150+
151 @property
152 def expire_cache_minutes(self):
153 """Active milestone caches expires sooner than non-active ones."""
154@@ -249,11 +314,16 @@
155 # to avoid making the same query over and over again when evaluating in
156 # the template.
157 @cachedproperty
158- def specifications(self):
159+ def _specifications(self):
160 """The list of specifications targeted to this milestone."""
161 return list(self.context.specifications)
162
163 @cachedproperty
164+ def specifications(self):
165+ """The list of specifications targeted to this milestone."""
166+ return MilestoneSpecificationListingBatchNavigator(self)
167+
168+ @cachedproperty
169 def product_release_files(self):
170 """Files associated with this milestone."""
171 return list(self.release.files)
172@@ -300,12 +370,12 @@
173 @cachedproperty
174 def bugtasks(self):
175 """The list of bugtasks targeted to this milestone for listing."""
176- return [self._getListingItem(bugtask) for bugtask in self._bugtasks]
177+ return MilestoneBugTaskListingBatchNavigator(self)
178
179 @property
180 def bugtask_count_text(self):
181 """The formatted count of bugs for this milestone."""
182- count = len(self.bugtasks)
183+ count = len(self._bugtasks)
184 if count == 1:
185 return '1 bug'
186 else:
187@@ -314,12 +384,12 @@
188 @property
189 def bugtask_status_counts(self):
190 """A list StatusCounts summarising the targeted bugtasks."""
191- return get_status_counts(self.bugtasks, 'status')
192+ return get_status_counts(self._bugtasks, 'status')
193
194 @property
195 def specification_count_text(self):
196 """The formatted count of specifications for this milestone."""
197- count = len(self.specifications)
198+ count = len(self._specifications)
199 if count == 1:
200 return '1 blueprint'
201 else:
202@@ -328,12 +398,12 @@
203 @property
204 def specification_status_counts(self):
205 """A list StatusCounts summarising the targeted specification."""
206- return get_status_counts(self.specifications, 'implementation_status')
207+ return get_status_counts(self._specifications, 'implementation_status')
208
209 @cachedproperty
210 def assignment_counts(self):
211 """The counts of the items assigned to users."""
212- all_assignments = self.bugtasks + self.specifications
213+ all_assignments = self._bugtasks + self._specifications
214 return get_status_counts(
215 all_assignments, 'assignee', key='displayname')
216
217@@ -343,7 +413,7 @@
218 all_assignments = []
219 if self.user:
220 for status_count in get_status_counts(
221- self.specifications, 'assignee', key='displayname'):
222+ self._specifications, 'assignee', key='displayname'):
223 if status_count.status == self.user:
224 if status_count.count == 1:
225 status_count.status = 'blueprint'
226@@ -351,7 +421,7 @@
227 status_count.status = 'blueprints'
228 all_assignments.append(status_count)
229 for status_count in get_status_counts(
230- self.bugtasks, 'assignee', key='displayname'):
231+ self._bugtasks, 'assignee', key='displayname'):
232 if status_count.status == self.user:
233 if status_count.count == 1:
234 status_count.status = 'bug'
235@@ -386,7 +456,17 @@
236 @property
237 def has_bugs_or_specs(self):
238 """Does the milestone have any bugtasks and specifications?"""
239- return len(self.bugtasks) > 0 or len(self.specifications) > 0
240+ return self.has_bugs or self.has_specifications
241+
242+ @property
243+ def has_bugs(self):
244+ """Does the milestone have any bugtasks?"""
245+ return len(self._bugtasks) > 0
246+
247+ @property
248+ def has_specifications(self):
249+ """Does the milestone have any specifications?"""
250+ return len(self._specifications) > 0
251
252
253 class MilestoneWithoutCountsView(MilestoneView):
254
255=== modified file 'lib/lp/registry/interfaces/milestone.py'
256--- lib/lp/registry/interfaces/milestone.py 2011-03-23 13:51:39 +0000
257+++ lib/lp/registry/interfaces/milestone.py 2011-10-12 02:44:27 +0000
258@@ -12,6 +12,8 @@
259 'IHasMilestones',
260 'IMilestone',
261 'IMilestoneSet',
262+ 'IMilestoneBugtaskListingBatchNavigator',
263+ 'IMilestoneSpecificationListingBatchNavigator',
264 'IProjectGroupMilestone',
265 ]
266
267@@ -49,6 +51,7 @@
268 from canonical.launchpad.components.apihelpers import (
269 patch_plain_parameter_type,
270 )
271+from canonical.launchpad.webapp.interfaces import ITableBatchNavigator
272 from lp.app.validators.name import name_validator
273 from lp.bugs.interfaces.bugtarget import (
274 IHasBugs,
275@@ -291,3 +294,9 @@
276 IMilestone['target'].schema = IHasMilestones
277 IMilestone['series_target'].schema = IHasMilestones
278 IProductRelease['milestone'].schema = IMilestone
279+
280+class IMilestoneBugtaskListingBatchNavigator(ITableBatchNavigator):
281+ """A marker interface for registering the appropriate listings."""
282+
283+class IMilestoneSpecificationListingBatchNavigator(ITableBatchNavigator):
284+ """A marker interface for registering the appropriate listings."""
285
286=== added file 'lib/lp/registry/templates/milestone-bugtask-listing.pt'
287--- lib/lp/registry/templates/milestone-bugtask-listing.pt 1970-01-01 00:00:00 +0000
288+++ lib/lp/registry/templates/milestone-bugtask-listing.pt 2011-10-12 02:44:27 +0000
289@@ -0,0 +1,86 @@
290+<div id="bugtask-table-listing"
291+ xmlns:tal="http://xml.zope.org/namespaces/tal"
292+ xmlns:metal="http://xml.zope.org/namespaces/metal"
293+>
294+ <tal:needs-batch condition="context/has_multiple_pages">
295+ <div id="bugtask-batch-links-upper">
296+ <tal:navigation replace="structure context/@@+navigation-links-upper" />
297+ </div>
298+ </tal:needs-batch>
299+
300+ <table tal:attributes="class context/table_class" id="milestone_bugtasks">
301+ <thead>
302+ <tr>
303+ <th colspan="4">Bug report</th>
304+ <th style="width: 14em"
305+ tal:condition="context/view/is_project_milestone">
306+ Project
307+ </th>
308+ <th style="width: 9em;">Importance</th>
309+ <th style="width: 14em;">Assignee</th>
310+ <th style="width: 10em;">Status</th>
311+ </tr>
312+ </thead>
313+ <tbody>
314+ <tr tal:repeat="bugtask context/bugtasks">
315+ <td class="icon left">
316+ <span class="sortkey" tal:content="bugtask/bug/id" />
317+ <span tal:content="structure bugtask/image:icon" />
318+ </td>
319+ <td tal:content="string:#${bugtask/bug/id}" class="amount">12345</td>
320+ <td>
321+ <a tal:attributes="href bugtask/bug/fmt:url"
322+ tal:content="bugtask/bug/title">
323+ Bug Title Here
324+ </a>
325+ </td>
326+ <td style="padding-right: 5px; text-align:right">
327+ <img src="/@@/info" tal:replace="structure bugtask/image:badges" />
328+ </td>
329+ <td tal:condition="context/view/is_project_milestone">
330+ <span class="sortkey" tal:content="bugtask/target/displayname" />
331+ <a tal:attributes="href bugtask/milestone/fmt:url"
332+ tal:content="bugtask/target/displayname" />
333+ </td>
334+ <td>
335+ <span class="sortkey" tal:content="bugtask/importance/sortkey" />
336+ <span tal:content="bugtask/importance/title"
337+ tal:attributes="
338+ class string:importance${bugtask/importance/name}">High</span>
339+ </td>
340+ <td>
341+ <a tal:condition="bugtask/assignee"
342+ tal:replace="structure bugtask/assignee/fmt:link" />&nbsp;
343+ </td>
344+ <td
345+ tal:attributes="title bugtask/last_significant_change_date/fmt:displaydate">
346+ <span class="sortkey" tal:content="bugtask/status/sortkey" />
347+ <span
348+ tal:content="bugtask/status/title"
349+ tal:attributes="
350+ class string:status${bugtask/status/name}">High</span>
351+ </td>
352+ </tr>
353+ </tbody>
354+ </table>
355+
356+ <div id="bugtask-batch-links-lower">
357+ <tal:navigation replace="structure context/@@+navigation-links-lower" />
358+ </div>
359+
360+ <tal:comment
361+ tal:condition="request/features/ajax.batch_navigator.enabled"
362+ replace='structure string:&lt;script type="text/javascript"&gt;
363+ LPS.use("lp.app.batchnavigator",
364+ function(Y) {
365+ Y.on("domready", function () {
366+ var config = {
367+ contentBox: "#bugtask-table-listing",
368+ query_parameter: "bugtask_batch"
369+ };
370+ new Y.lp.app.batchnavigator.BatchNavigatorHooks(config);
371+ });
372+ });
373+ &lt;/script&gt;'/>
374+
375+</div>
376
377=== added file 'lib/lp/registry/templates/milestone-bugtasks-table.pt'
378--- lib/lp/registry/templates/milestone-bugtasks-table.pt 1970-01-01 00:00:00 +0000
379+++ lib/lp/registry/templates/milestone-bugtasks-table.pt 2011-10-12 02:44:27 +0000
380@@ -0,0 +1,3 @@
381+<div tal:define="bugtasks view/bugtasks">
382+ <tal:bugtasklisting content="structure bugtasks/@@+listing" />
383+</div>
384
385=== modified file 'lib/lp/registry/templates/milestone-index.pt'
386--- lib/lp/registry/templates/milestone-index.pt 2011-06-16 13:50:58 +0000
387+++ lib/lp/registry/templates/milestone-index.pt 2011-10-12 02:44:27 +0000
388@@ -219,69 +219,18 @@
389 targeted
390 </h2>
391
392- <tal:has_specs condition="specs"
393+ <tal:has_specs condition="view/has_specifications"
394 tal:content="cache:anonymous, view/expire_cache_minutes minute">
395- <table class="listing sortable" id="milestone_specs"
396- style="margin-bottom: 2em;">
397- <thead>
398- <tr>
399- <th colspan="2">Blueprint</th>
400- <th style="width: 14em"
401- tal:condition="view/is_project_milestone">
402- Project
403- </th>
404- <th style="width: 9em;">Priority</th>
405- <th style="width: 14em;">Assignee</th>
406- <th style="width: 10em;">Delivery</th>
407- </tr>
408- </thead>
409- <tbody>
410- <tr tal:repeat="spec specs">
411- <td class="icon left">
412- <span tal:content="structure spec/image:icon" />
413- </td>
414- <td>
415- <a tal:content="spec/title/fmt:shorten/100"
416- tal:attributes="
417- href spec/fmt:url;
418- title spec/summary/fmt:shorten/400">Foo Bar Baz</a>
419- <img src="/@@/info" alt="Informational"
420- tal:condition="spec/informational" />
421- </td>
422- <td tal:condition="view/is_project_milestone">
423- <span class="sortkey" tal:content="spec/product/displayname" />
424- <a tal:attributes="href spec/milestone/fmt:url"
425- tal:content="spec/product/displayname" />
426- </td>
427- <td>
428- <span class="sortkey" tal:content="spec/priority/sortkey" />
429- <span tal:content="spec/priority/title"
430- tal:attributes="
431- class string:specpriority${spec/priority/name}">High</span>
432- </td>
433- <td>
434- <a tal:condition="spec/assignee"
435- tal:replace="structure spec/assignee/fmt:link" />&nbsp;
436- </td>
437- <td>
438- <span class="sortkey"
439- tal:content="spec/implementation_status/sortkey" />
440- <span tal:content="spec/implementation_status/title"
441- tal:attributes="
442- class string:specdelivery${spec/implementation_status/name}">
443- Deployment
444- </span>
445- </td>
446- </tr>
447- </tbody>
448- </table>
449+ <div tal:define="specifications view/specifications">
450+ <tal:bugtasklisting content="structure specifications/@@+listing" />
451+ </div>
452 </tal:has_specs>
453-
454- <tal:has_bugtasks condition="bugtasks">
455- <tal:cache content="cache:anonymous, view/expire_cache_minutes minute">
456- <tal:milestone-bugtasks
457- metal:use-macro="context/@@+milestone-macros/milestone_bugtasks" />
458- </tal:cache>
459+ <p style="margin-bottom: 2em;"></p>
460+ <tal:has_bugtasks condition="view/has_bugs"
461+ tal:content="cache:anonymous, view/expire_cache_minutes minute">
462+ <div tal:define="bugtasks view/bugtasks">
463+ <tal:bugtasklisting content="structure bugtasks/@@+listing" />
464+ </div>
465 </tal:has_bugtasks>
466
467 <tal:neither_bugs_nor_specs condition="not: view/has_bugs_or_specs">
468
469=== removed file 'lib/lp/registry/templates/milestone-macros.pt'
470--- lib/lp/registry/templates/milestone-macros.pt 2010-05-27 04:10:17 +0000
471+++ lib/lp/registry/templates/milestone-macros.pt 1970-01-01 00:00:00 +0000
472@@ -1,65 +0,0 @@
473-<tal:root
474- xmlns:tal="http://xml.zope.org/namespaces/tal"
475- xmlns:metal="http://xml.zope.org/namespaces/metal"
476- omit-tag="">
477-
478-
479-
480- <tal:milestone-bugtasks metal:define-macro="milestone_bugtasks">
481- <table class="listing sortable" id="milestone_bugtasks">
482- <thead>
483- <tr>
484- <th colspan="4">Bug report</th>
485- <th style="width: 14em"
486- tal:condition="view/is_project_milestone">
487- Project
488- </th>
489- <th style="width: 9em;">Importance</th>
490- <th style="width: 14em;">Assignee</th>
491- <th style="width: 10em;">Status</th>
492- </tr>
493- </thead>
494- <tbody>
495- <tr tal:repeat="bugtask bugtasks">
496- <td class="icon left">
497- <span class="sortkey" tal:content="bugtask/bug/id" />
498- <span tal:content="structure bugtask/image:icon" />
499- </td>
500- <td tal:content="string:#${bugtask/bug/id}" class="amount">12345</td>
501- <td>
502- <a tal:attributes="href bugtask/bug/fmt:url"
503- tal:content="bugtask/bug/title">
504- Bug Title Here
505- </a>
506- </td>
507- <td style="padding-right: 5px; text-align:right">
508- <img src="/@@/info" tal:replace="structure bugtask/image:badges" />
509- </td>
510- <td tal:condition="view/is_project_milestone">
511- <span class="sortkey" tal:content="bugtask/target/displayname" />
512- <a tal:attributes="href bugtask/milestone/fmt:url"
513- tal:content="bugtask/target/displayname" />
514- </td>
515- <td>
516- <span class="sortkey" tal:content="bugtask/importance/sortkey" />
517- <span tal:content="bugtask/importance/title"
518- tal:attributes="
519- class string:importance${bugtask/importance/name}">High</span>
520- </td>
521- <td>
522- <a tal:condition="bugtask/assignee"
523- tal:replace="structure bugtask/assignee/fmt:link" />&nbsp;
524- </td>
525- <td
526- tal:attributes="title bugtask/last_significant_change_date/fmt:displaydate">
527- <span class="sortkey" tal:content="bugtask/status/sortkey" />
528- <span
529- tal:content="bugtask/status/title"
530- tal:attributes="
531- class string:status${bugtask/status/name}">High</span>
532- </td>
533- </tr>
534- </tbody>
535- </table>
536- </tal:milestone-bugtasks>
537-</tal:root>
538
539=== added file 'lib/lp/registry/templates/milestone-specification-listing.pt'
540--- lib/lp/registry/templates/milestone-specification-listing.pt 1970-01-01 00:00:00 +0000
541+++ lib/lp/registry/templates/milestone-specification-listing.pt 2011-10-12 02:44:27 +0000
542@@ -0,0 +1,83 @@
543+<div id="specification-table-listing"
544+ xmlns:tal="http://xml.zope.org/namespaces/tal"
545+ xmlns:metal="http://xml.zope.org/namespaces/metal"
546+>
547+ <tal:needs-batch condition="context/has_multiple_pages">
548+ <div id="specification-batch-links-upper">
549+ <tal:navigation replace="structure context/@@+navigation-links-upper" />
550+ </div>
551+ </tal:needs-batch>
552+
553+ <table tal:attributes="class context/table_class" id="milestone_specifications">
554+ <thead>
555+ <tr>
556+ <th colspan="2">Blueprint</th>
557+ <th style="width: 14em"
558+ tal:condition="context/view/is_project_milestone">
559+ Project
560+ </th>
561+ <th style="width: 9em;">Priority</th>
562+ <th style="width: 14em;">Assignee</th>
563+ <th style="width: 10em;">Delivery</th>
564+ </tr>
565+ </thead>
566+ <tbody>
567+ <tr tal:repeat="spec context/specifications">
568+ <td class="icon left">
569+ <span tal:content="structure spec/image:icon" />
570+ </td>
571+ <td>
572+ <a tal:content="spec/title/fmt:shorten/100"
573+ tal:attributes="
574+ href spec/fmt:url;
575+ title spec/summary/fmt:shorten/400">Foo Bar Baz</a>
576+ <img src="/@@/info" alt="Informational"
577+ tal:condition="spec/informational" />
578+ </td>
579+ <td tal:condition="context/view/is_project_milestone">
580+ <span class="sortkey" tal:content="spec/product/displayname" />
581+ <a tal:attributes="href spec/milestone/fmt:url"
582+ tal:content="spec/product/displayname" />
583+ </td>
584+ <td>
585+ <span class="sortkey" tal:content="spec/priority/sortkey" />
586+ <span tal:content="spec/priority/title"
587+ tal:attributes="
588+ class string:specpriority${spec/priority/name}">High</span>
589+ </td>
590+ <td>
591+ <a tal:condition="spec/assignee"
592+ tal:replace="structure spec/assignee/fmt:link" />&nbsp;
593+ </td>
594+ <td>
595+ <span class="sortkey"
596+ tal:content="spec/implementation_status/sortkey" />
597+ <span tal:content="spec/implementation_status/title"
598+ tal:attributes="
599+ class string:specdelivery${spec/implementation_status/name}">
600+ Deployment
601+ </span>
602+ </td>
603+ </tr>
604+ </tbody>
605+ </table>
606+
607+ <div id="specification-batch-links-lower">
608+ <tal:navigation replace="structure context/@@+navigation-links-lower" />
609+ </div>
610+
611+ <tal:comment
612+ tal:condition="request/features/ajax.batch_navigator.enabled"
613+ replace='structure string:&lt;script type="text/javascript"&gt;
614+ LPS.use("lp.app.batchnavigator",
615+ function(Y) {
616+ Y.on("domready", function () {
617+ var config = {
618+ contentBox: "#specification-table-listing",
619+ query_parameter: "specification_batch"
620+ };
621+ new Y.lp.app.batchnavigator.BatchNavigatorHooks(config);
622+ });
623+ });
624+ &lt;/script&gt;'/>
625+</div>
626
627=== added file 'lib/lp/registry/templates/milestone-specifications-table.pt'
628--- lib/lp/registry/templates/milestone-specifications-table.pt 1970-01-01 00:00:00 +0000
629+++ lib/lp/registry/templates/milestone-specifications-table.pt 2011-10-12 02:44:27 +0000
630@@ -0,0 +1,3 @@
631+<div tal:define="specifications view/specifications">
632+ <tal:specificationlisting content="structure specifications/@@+listing" />
633+</div>