Merge lp://staging/~henninge/launchpad/bug-434055-combined into lp://staging/launchpad
- bug-434055-combined
- Merge into devel
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Brad Crittenden | ||||||||
Approved revision: | no longer in the source branch. | ||||||||
Merged at revision: | not available | ||||||||
Proposed branch: | lp://staging/~henninge/launchpad/bug-434055-combined | ||||||||
Merge into: | lp://staging/launchpad | ||||||||
Diff against target: | None lines | ||||||||
To merge this branch: | bzr merge lp://staging/~henninge/launchpad/bug-434055-combined | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brad Crittenden (community) | release-critical | Approve | |
Graham Binns (community) | code | Approve | |
Review via email:
|
Commit message
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Henning Eggers (henninge) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Henning Eggers (henninge) wrote : | # |
=== modified file 'lib/canonical/
--- lib/canonical/
+++ lib/canonical/
@@ -402,13 +402,6 @@
hasannouncemen
-def hasspecificatio
- """Return the secifications title for the context."""
- if IPerson.
- return "Blueprints involving %s" % context.title
- else:
- return "Blueprints for %s" % context.title
-
hassprints_sprints = ContextTitle(
# launchpad_debug doesn't need a title.
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -30,6 +30,7 @@
"""
label = "Set feature goals"
+ page_title = "Feature goals"
@cachedpro
def spec_filter(self):
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -6,6 +6,7 @@
__metaclass__ = type
__all__ = [
+ 'HasSpecificati
'HasSpecif
'RegisterA
'Specifica
@@ -30,7 +31,7 @@
from canonical.config import config
from canonical.launchpad import _
-from canonical.
+from canonical.
from canonical.
from canonical.
from canonical.
@@ -39,6 +40,48 @@
from canonical.
+class HasSpecificatio
+
+ def listall(self):
+ """Return a link to show all blueprints."""
+ text = 'List all blueprints'
+ return Link('+
+
+ def listaccepted(self):
+ """Return a link to show the approved goals."""
+ text = 'List approved blueprints'
+ return Link('+
+
+ def listproposed(self):
+ """Return a link to show the proposed goals."""
+ text = 'List proposed blueprints'
+ return Link('+
+
+ def listdeclined(self):
+ """Return a link to show the declined goals."""
+ text = 'List declined blueprints'
+ return Link('+
+
+ def doc(self):
+ text = 'List documentation'
+ return Link('+
+
+ def setgoals(self):
+ """Return a link to set the series goals."""
+ text = 'Set series goals'
+ return Link('+setgoals', text, icon='edit')
+
+ def assignments(self):
+ """Return a link to show the people assigned to the blueprint."""
+ text = 'Assignments'
+ return Link('+
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Graham Binns (gmb) wrote : | # |
I'm happy for this to land once the no-arg methods of HasSpecificatio
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Brad Crittenden (bac) : | # |
Preview Diff
1 | === modified file 'lib/canonical/launchpad/pagetitles.py' | |||
2 | --- lib/canonical/launchpad/pagetitles.py 2009-09-20 19:40:47 +0000 | |||
3 | +++ lib/canonical/launchpad/pagetitles.py 2009-09-22 15:10:46 +0000 | |||
4 | @@ -402,13 +402,6 @@ | |||
5 | 402 | 402 | ||
6 | 403 | hasannouncements_index = ContextDisplayName('%s news and announcements') | 403 | hasannouncements_index = ContextDisplayName('%s news and announcements') |
7 | 404 | 404 | ||
8 | 405 | def hasspecifications_specs(context, view): | ||
9 | 406 | """Return the secifications title for the context.""" | ||
10 | 407 | if IPerson.providedBy(context): | ||
11 | 408 | return "Blueprints involving %s" % context.title | ||
12 | 409 | else: | ||
13 | 410 | return "Blueprints for %s" % context.title | ||
14 | 411 | |||
15 | 412 | hassprints_sprints = ContextTitle("Events related to %s") | 405 | hassprints_sprints = ContextTitle("Events related to %s") |
16 | 413 | 406 | ||
17 | 414 | # launchpad_debug doesn't need a title. | 407 | # launchpad_debug doesn't need a title. |
18 | @@ -848,8 +841,6 @@ | |||
19 | 848 | """Return the page title for a specificationtarget.""" | 841 | """Return the page title for a specificationtarget.""" |
20 | 849 | return view.title | 842 | return view.title |
21 | 850 | 843 | ||
22 | 851 | specificationtarget_assignments = ContextTitle('Blueprint assignments for %s') | ||
23 | 852 | |||
24 | 853 | specificationtarget_workload = ContextTitle('Blueprint workload in %s') | 844 | specificationtarget_workload = ContextTitle('Blueprint workload in %s') |
25 | 854 | 845 | ||
26 | 855 | sprint_attend = ContextTitle('Register your attendance at %s') | 846 | sprint_attend = ContextTitle('Register your attendance at %s') |
27 | 856 | 847 | ||
28 | === modified file 'lib/lp/blueprints/browser/configure.zcml' | |||
29 | --- lib/lp/blueprints/browser/configure.zcml 2009-09-21 12:39:15 +0000 | |||
30 | +++ lib/lp/blueprints/browser/configure.zcml 2009-09-22 10:20:47 +0000 | |||
31 | @@ -56,13 +56,17 @@ | |||
32 | 56 | name="+specs" | 56 | name="+specs" |
33 | 57 | template="../templates/hasspecifications-specs.pt"/> | 57 | template="../templates/hasspecifications-specs.pt"/> |
34 | 58 | <browser:page | 58 | <browser:page |
35 | 59 | name="+assignments" | ||
36 | 60 | template="../templates/specificationtarget-assignments.pt"/> | ||
37 | 61 | <browser:page | ||
38 | 62 | name="+portlet-latestspecs" | 59 | name="+portlet-latestspecs" |
39 | 63 | template="../templates/specificationtarget-portlet-latestspecs.pt"/> | 60 | template="../templates/specificationtarget-portlet-latestspecs.pt"/> |
40 | 64 | </browser:pages> | 61 | </browser:pages> |
41 | 65 | <browser:page | 62 | <browser:page |
42 | 63 | name="+assignments" | ||
43 | 64 | for="lp.blueprints.interfaces.sprint.ISprint" | ||
44 | 65 | class="canonical.launchpad.browser.SpecificationAssignmentsView" | ||
45 | 66 | facet="specifications" | ||
46 | 67 | permission="zope.Public" | ||
47 | 68 | template="../templates/specificationtarget-assignments.pt"/> | ||
48 | 69 | <browser:page | ||
49 | 66 | name="+edit" | 70 | name="+edit" |
50 | 67 | for="lp.blueprints.interfaces.sprint.ISprint" | 71 | for="lp.blueprints.interfaces.sprint.ISprint" |
51 | 68 | class="lp.blueprints.browser.sprint.SprintEditView" | 72 | class="lp.blueprints.browser.sprint.SprintEditView" |
52 | @@ -537,13 +541,16 @@ | |||
53 | 537 | name="+specs" | 541 | name="+specs" |
54 | 538 | template="../templates/hasspecifications-specs.pt"/> | 542 | template="../templates/hasspecifications-specs.pt"/> |
55 | 539 | <browser:page | 543 | <browser:page |
56 | 540 | name="+assignments" | ||
57 | 541 | template="../templates/specificationtarget-assignments.pt"/> | ||
58 | 542 | <browser:page | ||
59 | 543 | name="+portlet-latestspecs" | 544 | name="+portlet-latestspecs" |
60 | 544 | template="../templates/specificationtarget-portlet-latestspecs.pt"/> | 545 | template="../templates/specificationtarget-portlet-latestspecs.pt"/> |
61 | 545 | </browser:pages> | 546 | </browser:pages> |
62 | 546 | <browser:page | 547 | <browser:page |
63 | 548 | name="+assignments" | ||
64 | 549 | for="lp.blueprints.interfaces.specificationtarget.IHasSpecifications" | ||
65 | 550 | class="lp.blueprints.browser.specificationtarget.SpecificationAssignmentsView" | ||
66 | 551 | permission="zope.Public" | ||
67 | 552 | template="../templates/specificationtarget-assignments.pt"/> | ||
68 | 553 | <browser:page | ||
69 | 547 | name="+register-a-blueprint-button" | 554 | name="+register-a-blueprint-button" |
70 | 548 | for="lp.blueprints.interfaces.specificationtarget.ISpecificationTarget" | 555 | for="lp.blueprints.interfaces.specificationtarget.ISpecificationTarget" |
71 | 549 | class="lp.blueprints.browser.specificationtarget.RegisterABlueprintButtonView" | 556 | class="lp.blueprints.browser.specificationtarget.RegisterABlueprintButtonView" |
72 | @@ -585,12 +592,16 @@ | |||
73 | 585 | name="+specs" | 592 | name="+specs" |
74 | 586 | template="../templates/hasspecifications-specs.pt"/> | 593 | template="../templates/hasspecifications-specs.pt"/> |
75 | 587 | <browser:page | 594 | <browser:page |
76 | 588 | name="+assignments" | ||
77 | 589 | template="../templates/specificationtarget-assignments.pt"/> | ||
78 | 590 | <browser:page | ||
79 | 591 | name="+portlet-latestspecs" | 595 | name="+portlet-latestspecs" |
80 | 592 | template="../templates/specificationtarget-portlet-latestspecs.pt"/> | 596 | template="../templates/specificationtarget-portlet-latestspecs.pt"/> |
81 | 593 | </browser:pages> | 597 | </browser:pages> |
82 | 598 | <browser:page | ||
83 | 599 | name="+assignments" | ||
84 | 600 | for="lp.registry.interfaces.project.IProject" | ||
85 | 601 | class="lp.blueprints.browser.specificationtarget.SpecificationAssignmentsView" | ||
86 | 602 | facet="specifications" | ||
87 | 603 | permission="zope.Public" | ||
88 | 604 | template="../templates/specificationtarget-assignments.pt"/> | ||
89 | 594 | 605 | ||
90 | 595 | <browser:page | 606 | <browser:page |
91 | 596 | name="+addspec" | 607 | name="+addspec" |
92 | 597 | 608 | ||
93 | === modified file 'lib/lp/blueprints/browser/specificationgoal.py' | |||
94 | --- lib/lp/blueprints/browser/specificationgoal.py 2009-09-18 19:47:24 +0000 | |||
95 | +++ lib/lp/blueprints/browser/specificationgoal.py 2009-09-22 15:02:41 +0000 | |||
96 | @@ -30,6 +30,7 @@ | |||
97 | 30 | """ | 30 | """ |
98 | 31 | 31 | ||
99 | 32 | label = "Set feature goals" | 32 | label = "Set feature goals" |
100 | 33 | page_title = "Feature goals" | ||
101 | 33 | 34 | ||
102 | 34 | @cachedproperty | 35 | @cachedproperty |
103 | 35 | def spec_filter(self): | 36 | def spec_filter(self): |
104 | 36 | 37 | ||
105 | === modified file 'lib/lp/blueprints/browser/specificationtarget.py' | |||
106 | --- lib/lp/blueprints/browser/specificationtarget.py 2009-09-17 21:20:14 +0000 | |||
107 | +++ lib/lp/blueprints/browser/specificationtarget.py 2009-09-22 15:02:41 +0000 | |||
108 | @@ -6,8 +6,10 @@ | |||
109 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
110 | 7 | 7 | ||
111 | 8 | __all__ = [ | 8 | __all__ = [ |
112 | 9 | 'HasSpecificationsMenuMixin', | ||
113 | 9 | 'HasSpecificationsView', | 10 | 'HasSpecificationsView', |
114 | 10 | 'RegisterABlueprintButtonView', | 11 | 'RegisterABlueprintButtonView', |
115 | 12 | 'SpecificationAssignmentsView', | ||
116 | 11 | 'SpecificationDocumentationView', | 13 | 'SpecificationDocumentationView', |
117 | 12 | ] | 14 | ] |
118 | 13 | 15 | ||
119 | @@ -29,7 +31,7 @@ | |||
120 | 29 | 31 | ||
121 | 30 | from canonical.config import config | 32 | from canonical.config import config |
122 | 31 | from canonical.launchpad import _ | 33 | from canonical.launchpad import _ |
124 | 32 | from canonical.launchpad.webapp import LaunchpadView | 34 | from canonical.launchpad.webapp import LaunchpadView, Link |
125 | 33 | from canonical.launchpad.webapp.batching import BatchNavigator | 35 | from canonical.launchpad.webapp.batching import BatchNavigator |
126 | 34 | from canonical.launchpad.webapp.breadcrumb import Breadcrumb | 36 | from canonical.launchpad.webapp.breadcrumb import Breadcrumb |
127 | 35 | from canonical.launchpad.helpers import shortlist | 37 | from canonical.launchpad.helpers import shortlist |
128 | @@ -38,6 +40,48 @@ | |||
129 | 38 | from canonical.lazr.utils import smartquote | 40 | from canonical.lazr.utils import smartquote |
130 | 39 | 41 | ||
131 | 40 | 42 | ||
132 | 43 | class HasSpecificationsMenuMixin(object): | ||
133 | 44 | |||
134 | 45 | def listall(self): | ||
135 | 46 | """Return a link to show all blueprints.""" | ||
136 | 47 | text = 'List all blueprints' | ||
137 | 48 | return Link('+specs?show=all', text, icon='blueprint') | ||
138 | 49 | |||
139 | 50 | def listaccepted(self): | ||
140 | 51 | """Return a link to show the approved goals.""" | ||
141 | 52 | text = 'List approved blueprints' | ||
142 | 53 | return Link('+specs?acceptance=accepted', text, icon='blueprint') | ||
143 | 54 | |||
144 | 55 | def listproposed(self): | ||
145 | 56 | """Return a link to show the proposed goals.""" | ||
146 | 57 | text = 'List proposed blueprints' | ||
147 | 58 | return Link('+specs?acceptance=proposed', text, icon='blueprint') | ||
148 | 59 | |||
149 | 60 | def listdeclined(self): | ||
150 | 61 | """Return a link to show the declined goals.""" | ||
151 | 62 | text = 'List declined blueprints' | ||
152 | 63 | return Link('+specs?acceptance=declined', text, icon='blueprint') | ||
153 | 64 | |||
154 | 65 | def doc(self): | ||
155 | 66 | text = 'List documentation' | ||
156 | 67 | return Link('+documentation', text, icon='info') | ||
157 | 68 | |||
158 | 69 | def setgoals(self): | ||
159 | 70 | """Return a link to set the series goals.""" | ||
160 | 71 | text = 'Set series goals' | ||
161 | 72 | return Link('+setgoals', text, icon='edit') | ||
162 | 73 | |||
163 | 74 | def assignments(self): | ||
164 | 75 | """Return a link to show the people assigned to the blueprint.""" | ||
165 | 76 | text = 'Assignments' | ||
166 | 77 | return Link('+assignments', text, icon='person') | ||
167 | 78 | |||
168 | 79 | def new(self): | ||
169 | 80 | """Return a link to register a blueprint.""" | ||
170 | 81 | text = 'Register a blueprint' | ||
171 | 82 | return Link('+addspec', text, icon='add') | ||
172 | 83 | |||
173 | 84 | |||
174 | 41 | class HasSpecificationsView(LaunchpadView): | 85 | class HasSpecificationsView(LaunchpadView): |
175 | 42 | """Base class for several context-specific views that involve lists of | 86 | """Base class for several context-specific views that involve lists of |
176 | 43 | specifications. | 87 | specifications. |
177 | @@ -77,7 +121,6 @@ | |||
178 | 77 | # replacing the conditional execution with polymorphism. | 121 | # replacing the conditional execution with polymorphism. |
179 | 78 | # See https://bugs.launchpad.net/blueprint/+bug/173972. | 122 | # See https://bugs.launchpad.net/blueprint/+bug/173972. |
180 | 79 | def initialize(self): | 123 | def initialize(self): |
181 | 80 | mapping = {'name': self.context.displayname} | ||
182 | 81 | if IPerson.providedBy(self.context): | 124 | if IPerson.providedBy(self.context): |
183 | 82 | self.is_person = True | 125 | self.is_person = True |
184 | 83 | elif (IDistribution.providedBy(self.context) or | 126 | elif (IDistribution.providedBy(self.context) or |
185 | @@ -104,11 +147,6 @@ | |||
186 | 104 | else: | 147 | else: |
187 | 105 | raise AssertionError, 'Unknown blueprint listing site' | 148 | raise AssertionError, 'Unknown blueprint listing site' |
188 | 106 | 149 | ||
189 | 107 | if self.is_person: | ||
190 | 108 | self.title = _('Specifications involving $name', mapping=mapping) | ||
191 | 109 | else: | ||
192 | 110 | self.title = _('Specifications for $name', mapping=mapping) | ||
193 | 111 | |||
194 | 112 | if IHasDrivers.providedBy(self.context): | 150 | if IHasDrivers.providedBy(self.context): |
195 | 113 | self.has_drivers = True | 151 | self.has_drivers = True |
196 | 114 | 152 | ||
197 | @@ -116,6 +154,14 @@ | |||
198 | 116 | self.specs, self.request, | 154 | self.specs, self.request, |
199 | 117 | size=config.launchpad.default_batch_size) | 155 | size=config.launchpad.default_batch_size) |
200 | 118 | 156 | ||
201 | 157 | @property | ||
202 | 158 | def label(self): | ||
203 | 159 | mapping = {'name': self.context.displayname} | ||
204 | 160 | if self.is_person: | ||
205 | 161 | return _('Blueprints involving $name', mapping=mapping) | ||
206 | 162 | else: | ||
207 | 163 | return _('Blueprints for $name', mapping=mapping) | ||
208 | 164 | |||
209 | 119 | def mdzCsv(self): | 165 | def mdzCsv(self): |
210 | 120 | """Quick hack for mdz, to get csv dump of specs.""" | 166 | """Quick hack for mdz, to get csv dump of specs.""" |
211 | 121 | import csv | 167 | import csv |
212 | @@ -313,8 +359,19 @@ | |||
213 | 313 | quantity=quantity, prejoin_people=False) | 359 | quantity=quantity, prejoin_people=False) |
214 | 314 | 360 | ||
215 | 315 | 361 | ||
216 | 362 | class SpecificationAssignmentsView(HasSpecificationsView): | ||
217 | 363 | """View for +assignments pages.""" | ||
218 | 364 | page_title = "Assignments" | ||
219 | 365 | |||
220 | 366 | @property | ||
221 | 367 | def label(self): | ||
222 | 368 | return smartquote( | ||
223 | 369 | 'Blueprint assignments for "%s"' % self.context.displayname) | ||
224 | 370 | |||
225 | 371 | |||
226 | 316 | class SpecificationDocumentationView(HasSpecificationsView): | 372 | class SpecificationDocumentationView(HasSpecificationsView): |
227 | 317 | """View for blueprints +documentation page.""" | 373 | """View for blueprints +documentation page.""" |
228 | 374 | page_title = "Documentation" | ||
229 | 318 | 375 | ||
230 | 319 | @property | 376 | @property |
231 | 320 | def label(self): | 377 | def label(self): |
232 | @@ -344,17 +401,7 @@ | |||
233 | 344 | """ % canonical_url(target, rootsite='blueprints') | 401 | """ % canonical_url(target, rootsite='blueprints') |
234 | 345 | 402 | ||
235 | 346 | 403 | ||
250 | 347 | class HasSpecificationsOnBlueprintsVHostBreadcrumb(Breadcrumb): | 404 | class BlueprintsVHostBreadcrumb(Breadcrumb): |
251 | 348 | rootsite = 'blueprints' | 405 | rootsite = 'blueprints' |
252 | 349 | 406 | text = 'Blueprints' | |
253 | 350 | @property | 407 | |
240 | 351 | def text(self): | ||
241 | 352 | return 'Blueprints for %s' % self.context.title | ||
242 | 353 | |||
243 | 354 | |||
244 | 355 | class PersonOnBlueprintsVHostBreadcrumb(Breadcrumb): | ||
245 | 356 | rootsite = 'blueprints' | ||
246 | 357 | |||
247 | 358 | @property | ||
248 | 359 | def text(self): | ||
249 | 360 | return 'Blueprints involving %s' % self.context.displayname | ||
254 | 361 | 408 | ||
255 | === modified file 'lib/lp/blueprints/browser/sprint.py' | |||
256 | --- lib/lp/blueprints/browser/sprint.py 2009-09-21 12:39:15 +0000 | |||
257 | +++ lib/lp/blueprints/browser/sprint.py 2009-09-22 15:02:41 +0000 | |||
258 | @@ -46,7 +46,7 @@ | |||
259 | 46 | 46 | ||
260 | 47 | from lp.app.interfaces.headings import IMajorHeadingView | 47 | from lp.app.interfaces.headings import IMajorHeadingView |
261 | 48 | from lp.blueprints.browser.specificationtarget import ( | 48 | from lp.blueprints.browser.specificationtarget import ( |
263 | 49 | HasSpecificationsView) | 49 | HasSpecificationsMenuMixin, HasSpecificationsView) |
264 | 50 | from lp.blueprints.interfaces.specification import ( | 50 | from lp.blueprints.interfaces.specification import ( |
265 | 51 | SpecificationDefinitionStatus, SpecificationFilter, SpecificationPriority, | 51 | SpecificationDefinitionStatus, SpecificationFilter, SpecificationPriority, |
266 | 52 | SpecificationSort) | 52 | SpecificationSort) |
267 | @@ -110,32 +110,16 @@ | |||
268 | 110 | return Link('+branding', text, summary, icon='edit') | 110 | return Link('+branding', text, summary, icon='edit') |
269 | 111 | 111 | ||
270 | 112 | 112 | ||
273 | 113 | class SprintSpecificationsMenu(ApplicationMenu): | 113 | class SprintSpecificationsMenu(NavigationMenu, |
274 | 114 | 114 | HasSpecificationsMenuMixin): | |
275 | 115 | usedfor = ISprint | 115 | usedfor = ISprint |
276 | 116 | facet = 'specifications' | 116 | facet = 'specifications' |
288 | 117 | links = ['assignments', 'declined', 'settopics', 'addspec'] | 117 | links = ['assignments', 'listdeclined', 'settopics', 'new'] |
278 | 118 | |||
279 | 119 | def assignments(self): | ||
280 | 120 | text = 'Assignments' | ||
281 | 121 | summary = 'View the specification assignments' | ||
282 | 122 | return Link('+assignments', text, summary, icon='info') | ||
283 | 123 | |||
284 | 124 | def declined(self): | ||
285 | 125 | text = 'List declined blueprints' | ||
286 | 126 | summary = 'Show topics that were not accepted for discussion' | ||
287 | 127 | return Link('+specs?acceptance=declined', text, summary, icon='info') | ||
289 | 128 | 118 | ||
290 | 129 | @enabled_with_permission('launchpad.Driver') | 119 | @enabled_with_permission('launchpad.Driver') |
291 | 130 | def settopics(self): | 120 | def settopics(self): |
292 | 131 | text = 'Set agenda' | 121 | text = 'Set agenda' |
300 | 132 | summary = 'Approve or defer topics for discussion' | 122 | return Link('+settopics', text, icon='edit') |
294 | 133 | return Link('+settopics', text, summary, icon='edit') | ||
295 | 134 | |||
296 | 135 | def addspec(self): | ||
297 | 136 | text = 'Register a blueprint' | ||
298 | 137 | summary = 'Register a new blueprint for this meeting' | ||
299 | 138 | return Link('+addspec', text, summary, icon='info') | ||
301 | 139 | 123 | ||
302 | 140 | 124 | ||
303 | 141 | class SprintSetNavigation(GetitemNavigation): | 125 | class SprintSetNavigation(GetitemNavigation): |
304 | 142 | 126 | ||
305 | === modified file 'lib/lp/blueprints/browser/tests/test_breadcrumbs.py' | |||
306 | --- lib/lp/blueprints/browser/tests/test_breadcrumbs.py 2009-09-16 03:37:47 +0000 | |||
307 | +++ lib/lp/blueprints/browser/tests/test_breadcrumbs.py 2009-09-22 15:02:41 +0000 | |||
308 | @@ -29,16 +29,14 @@ | |||
309 | 29 | self.product_specs_url, [self.root, self.product]) | 29 | self.product_specs_url, [self.root, self.product]) |
310 | 30 | last_crumb = crumbs[-1] | 30 | last_crumb = crumbs[-1] |
311 | 31 | self.assertEquals(last_crumb.url, self.product_specs_url) | 31 | self.assertEquals(last_crumb.url, self.product_specs_url) |
314 | 32 | self.assertEquals( | 32 | self.assertEquals(last_crumb.text, 'Blueprints') |
313 | 33 | last_crumb.text, 'Blueprints for %s' % self.product.title) | ||
315 | 34 | 33 | ||
316 | 35 | def test_person(self): | 34 | def test_person(self): |
317 | 36 | crumbs = self._getBreadcrumbs( | 35 | crumbs = self._getBreadcrumbs( |
318 | 37 | self.person_specs_url, [self.root, self.person]) | 36 | self.person_specs_url, [self.root, self.person]) |
319 | 38 | last_crumb = crumbs[-1] | 37 | last_crumb = crumbs[-1] |
320 | 39 | self.assertEquals(last_crumb.url, self.person_specs_url) | 38 | self.assertEquals(last_crumb.url, self.person_specs_url) |
323 | 40 | self.assertEquals(last_crumb.text, | 39 | self.assertEquals(last_crumb.text, 'Blueprints') |
322 | 41 | 'Blueprints involving %s' % self.person.displayname) | ||
324 | 42 | 40 | ||
325 | 43 | 41 | ||
326 | 44 | class TestSpecificationBreadcrumb(BaseBreadcrumbTestCase): | 42 | class TestSpecificationBreadcrumb(BaseBreadcrumbTestCase): |
327 | 45 | 43 | ||
328 | === modified file 'lib/lp/blueprints/configure.zcml' | |||
329 | --- lib/lp/blueprints/configure.zcml 2009-09-16 03:37:47 +0000 | |||
330 | +++ lib/lp/blueprints/configure.zcml 2009-09-22 15:02:41 +0000 | |||
331 | @@ -236,12 +236,12 @@ | |||
332 | 236 | name="blueprints" | 236 | name="blueprints" |
333 | 237 | provides="canonical.launchpad.webapp.interfaces.IBreadcrumb" | 237 | provides="canonical.launchpad.webapp.interfaces.IBreadcrumb" |
334 | 238 | for="lp.blueprints.interfaces.specificationtarget.IHasSpecifications" | 238 | for="lp.blueprints.interfaces.specificationtarget.IHasSpecifications" |
336 | 239 | factory="lp.blueprints.browser.specificationtarget.HasSpecificationsOnBlueprintsVHostBreadcrumb" | 239 | factory="lp.blueprints.browser.specificationtarget.BlueprintsVHostBreadcrumb" |
337 | 240 | permission="zope.Public"/> | 240 | permission="zope.Public"/> |
338 | 241 | <adapter | 241 | <adapter |
339 | 242 | name="blueprints" | 242 | name="blueprints" |
340 | 243 | provides="canonical.launchpad.webapp.interfaces.IBreadcrumb" | 243 | provides="canonical.launchpad.webapp.interfaces.IBreadcrumb" |
341 | 244 | for="lp.registry.interfaces.person.IPerson" | 244 | for="lp.registry.interfaces.person.IPerson" |
343 | 245 | factory="lp.blueprints.browser.specificationtarget.PersonOnBlueprintsVHostBreadcrumb" | 245 | factory="lp.blueprints.browser.specificationtarget.BlueprintsVHostBreadcrumb" |
344 | 246 | permission="zope.Public"/> | 246 | permission="zope.Public"/> |
345 | 247 | </configure> | 247 | </configure> |
346 | 248 | 248 | ||
347 | === modified file 'lib/lp/blueprints/stories/blueprints/01-creation.txt' | |||
348 | --- lib/lp/blueprints/stories/blueprints/01-creation.txt 2009-09-19 01:54:04 +0000 | |||
349 | +++ lib/lp/blueprints/stories/blueprints/01-creation.txt 2009-09-22 15:02:41 +0000 | |||
350 | @@ -64,7 +64,7 @@ | |||
351 | 64 | ... user_browser.contents, 'menu-link-new'): | 64 | ... user_browser.contents, 'menu-link-new'): |
352 | 65 | ... print tag | 65 | ... print tag |
353 | 66 | <a href="http://blueprints.launchpad.dev/ubuntu/+addspec" | 66 | <a href="http://blueprints.launchpad.dev/ubuntu/+addspec" |
355 | 67 | class="menu-link-new" ...>Register a blueprint</a> | 67 | class="menu-link-new...>Register a blueprint</a> |
356 | 68 | 68 | ||
357 | 69 | 69 | ||
358 | 70 | === From a distribution series === | 70 | === From a distribution series === |
359 | @@ -85,7 +85,7 @@ | |||
360 | 85 | ... user_browser.contents, 'menu-link-new'): | 85 | ... user_browser.contents, 'menu-link-new'): |
361 | 86 | ... print tag | 86 | ... print tag |
362 | 87 | <a href="http://blueprints.launchpad.dev/ubuntu/hoary/+addspec" | 87 | <a href="http://blueprints.launchpad.dev/ubuntu/hoary/+addspec" |
364 | 88 | class="menu-link-new" ...>Register a blueprint</a> | 88 | class="menu-link-new...>Register a blueprint</a> |
365 | 89 | 89 | ||
366 | 90 | 90 | ||
367 | 91 | === From a product === | 91 | === From a product === |
368 | @@ -106,7 +106,7 @@ | |||
369 | 106 | ... user_browser.contents, 'menu-link-new'): | 106 | ... user_browser.contents, 'menu-link-new'): |
370 | 107 | ... print tag | 107 | ... print tag |
371 | 108 | <a href="http://blueprints.launchpad.dev/bzr/+addspec" | 108 | <a href="http://blueprints.launchpad.dev/bzr/+addspec" |
373 | 109 | class="menu-link-new" ...>Register a blueprint</a> | 109 | class="menu-link-new...>Register a blueprint</a> |
374 | 110 | 110 | ||
375 | 111 | For products without any blueprints, users can follow the special "register | 111 | For products without any blueprints, users can follow the special "register |
376 | 112 | it here as a blueprint" link: | 112 | it here as a blueprint" link: |
377 | @@ -137,7 +137,7 @@ | |||
378 | 137 | ... user_browser.contents, 'menu-link-new'): | 137 | ... user_browser.contents, 'menu-link-new'): |
379 | 138 | ... print tag | 138 | ... print tag |
380 | 139 | <a href="http://blueprints.launchpad.dev/firefox/1.0/+addspec" | 139 | <a href="http://blueprints.launchpad.dev/firefox/1.0/+addspec" |
382 | 140 | class="menu-link-new" ...>Register a blueprint</a> | 140 | class="menu-link-new...>Register a blueprint</a> |
383 | 141 | 141 | ||
384 | 142 | 142 | ||
385 | 143 | === From a project === | 143 | === From a project === |
386 | @@ -158,7 +158,7 @@ | |||
387 | 158 | ... user_browser.contents, 'menu-link-new'): | 158 | ... user_browser.contents, 'menu-link-new'): |
388 | 159 | ... print tag | 159 | ... print tag |
389 | 160 | <a href="http://blueprints.launchpad.dev/mozilla/+addspec" | 160 | <a href="http://blueprints.launchpad.dev/mozilla/+addspec" |
391 | 161 | class="menu-link-new" ...>Register a blueprint</a> | 161 | class="menu-link-new...>Register a blueprint</a> |
392 | 162 | 162 | ||
393 | 163 | 163 | ||
394 | 164 | === From a sprint === | 164 | === From a sprint === |
395 | @@ -176,10 +176,10 @@ | |||
396 | 176 | Users can also follow the textual "Register a blueprint" link: | 176 | Users can also follow the textual "Register a blueprint" link: |
397 | 177 | 177 | ||
398 | 178 | >>> for tag in find_tags_by_class( | 178 | >>> for tag in find_tags_by_class( |
400 | 179 | ... user_browser.contents, 'menu-link-addspec'): | 179 | ... user_browser.contents, 'menu-link-new'): |
401 | 180 | ... print tag | 180 | ... print tag |
402 | 181 | <a href="http://blueprints.launchpad.dev/sprints/futurista/+addspec" | 181 | <a href="http://blueprints.launchpad.dev/sprints/futurista/+addspec" |
404 | 182 | class="menu-link-addspec" ...>Register a blueprint</a> | 182 | class="menu-link-new...>Register a blueprint</a> |
405 | 183 | 183 | ||
406 | 184 | 184 | ||
407 | 185 | == Registering a blueprint == | 185 | == Registering a blueprint == |
408 | 186 | 186 | ||
409 | === modified file 'lib/lp/blueprints/stories/blueprints/07-milestones.txt' | |||
410 | --- lib/lp/blueprints/stories/blueprints/07-milestones.txt 2009-09-21 19:15:03 +0000 | |||
411 | +++ lib/lp/blueprints/stories/blueprints/07-milestones.txt 2009-09-22 15:02:41 +0000 | |||
412 | @@ -17,7 +17,7 @@ | |||
413 | 17 | >>> admin_browser.getLink('Target milestone').click() | 17 | >>> admin_browser.getLink('Target milestone').click() |
414 | 18 | >>> print admin_browser.title | 18 | >>> print admin_browser.title |
415 | 19 | Target to a milestone : Support <canvas> Objects : | 19 | Target to a milestone : Support <canvas> Objects : |
417 | 20 | Blueprints for Mozilla Firefox : Mozilla Firefox | 20 | Blueprints : Mozilla Firefox |
418 | 21 | >>> back_link = admin_browser.getLink('Support <canvas> Objects') | 21 | >>> back_link = admin_browser.getLink('Support <canvas> Objects') |
419 | 22 | >>> back_link.url | 22 | >>> back_link.url |
420 | 23 | 'http://blueprints.launchpad.dev/firefox/+spec/canvas' | 23 | 'http://blueprints.launchpad.dev/firefox/+spec/canvas' |
421 | 24 | 24 | ||
422 | === modified file 'lib/lp/blueprints/stories/blueprints/xx-overview.txt' | |||
423 | --- lib/lp/blueprints/stories/blueprints/xx-overview.txt 2009-09-21 19:15:03 +0000 | |||
424 | +++ lib/lp/blueprints/stories/blueprints/xx-overview.txt 2009-09-22 15:02:41 +0000 | |||
425 | @@ -44,6 +44,7 @@ | |||
426 | 44 | >>> main = find_main_content(user_browser.contents) | 44 | >>> main = find_main_content(user_browser.contents) |
427 | 45 | >>> print extract_text(main).encode('ascii', 'backslashreplace') | 45 | >>> print extract_text(main).encode('ascii', 'backslashreplace') |
428 | 46 | Blueprints for 1.0 | 46 | Blueprints for 1.0 |
429 | 47 | ... | ||
430 | 47 | Launchpad lets projects track the features they intend to implement... | 48 | Launchpad lets projects track the features they intend to implement... |
431 | 48 | 49 | ||
432 | 49 | Let's target an existing Mozilla Firefox blueprint to the 1.0 series: | 50 | Let's target an existing Mozilla Firefox blueprint to the 1.0 series: |
433 | @@ -144,6 +145,7 @@ | |||
434 | 144 | >>> main = find_main_content(user_browser.contents) | 145 | >>> main = find_main_content(user_browser.contents) |
435 | 145 | >>> print extract_text(main).encode('ascii', 'backslashreplace') | 146 | >>> print extract_text(main).encode('ascii', 'backslashreplace') |
436 | 146 | Blueprints for Grumpy | 147 | Blueprints for Grumpy |
437 | 148 | ... | ||
438 | 147 | Launchpad lets projects track the features they intend to implement... | 149 | Launchpad lets projects track the features they intend to implement... |
439 | 148 | 150 | ||
440 | 149 | Let's target an existing Ubuntu blueprint to the Grumpy series: | 151 | Let's target an existing Ubuntu blueprint to the Grumpy series: |
441 | 150 | 152 | ||
442 | === modified file 'lib/lp/blueprints/stories/blueprints/xx-personviews.txt' | |||
443 | --- lib/lp/blueprints/stories/blueprints/xx-personviews.txt 2009-09-18 12:47:26 +0000 | |||
444 | +++ lib/lp/blueprints/stories/blueprints/xx-personviews.txt 2009-09-22 15:02:41 +0000 | |||
445 | @@ -8,8 +8,8 @@ | |||
446 | 8 | involving that person. | 8 | involving that person. |
447 | 9 | 9 | ||
448 | 10 | >>> browser.open('http://blueprints.launchpad.dev/~name16') | 10 | >>> browser.open('http://blueprints.launchpad.dev/~name16') |
451 | 11 | >>> browser.title | 11 | >>> print browser.title |
452 | 12 | 'Blueprints involving Foo Bar' | 12 | Blueprints : Foo Bar |
453 | 13 | >>> soup = find_main_content(browser.contents) | 13 | >>> soup = find_main_content(browser.contents) |
454 | 14 | >>> soup('h1') | 14 | >>> soup('h1') |
455 | 15 | [<h1>Blueprints involving Foo Bar</h1>] | 15 | [<h1>Blueprints involving Foo Bar</h1>] |
456 | @@ -73,9 +73,10 @@ | |||
457 | 73 | are part of the workload for the team. It then shows the workloads | 73 | are part of the workload for the team. It then shows the workloads |
458 | 74 | for each member of the team, using batching. | 74 | for each member of the team, using batching. |
459 | 75 | 75 | ||
460 | 76 | >>> from canonical.launchpad.helpers import backslashreplace | ||
461 | 76 | >>> browser.open('http://blueprints.launchpad.dev/~admins') | 77 | >>> browser.open('http://blueprints.launchpad.dev/~admins') |
464 | 77 | >>> browser.title | 78 | >>> print backslashreplace(browser.title) |
465 | 78 | 'Blueprints involving Launchpad Administrators' | 79 | Blueprints : \u201cLaunchpad Administrators\u201d team |
466 | 79 | >>> browser.getLink('Workload').click() | 80 | >>> browser.getLink('Workload').click() |
467 | 80 | >>> browser.url | 81 | >>> browser.url |
468 | 81 | '.../~admins/+specworkload' | 82 | '.../~admins/+specworkload' |
469 | 82 | 83 | ||
470 | === modified file 'lib/lp/blueprints/stories/sprints/15-sprint-tabular-view.txt' | |||
471 | --- lib/lp/blueprints/stories/sprints/15-sprint-tabular-view.txt 2009-05-11 18:19:21 +0000 | |||
472 | +++ lib/lp/blueprints/stories/sprints/15-sprint-tabular-view.txt 2009-09-22 00:13:14 +0000 | |||
473 | @@ -1,12 +1,12 @@ | |||
474 | 1 | We should be able to see the workload of a sprint: | 1 | We should be able to see the workload of a sprint: |
475 | 2 | 2 | ||
476 | 3 | >>> anon_browser.open('http://launchpad.dev/sprints/ubz/+assignments') | 3 | >>> anon_browser.open('http://launchpad.dev/sprints/ubz/+assignments') |
479 | 4 | >>> anon_browser.title | 4 | >>> print anon_browser.title |
480 | 5 | 'Blueprint assignments for Ubuntu Below Zero' | 5 | Assignments : Ubuntu Below Zero : Meetings |
481 | 6 | 6 | ||
482 | 7 | We should be able to see the spec assignment table of a sprint: | 7 | We should be able to see the spec assignment table of a sprint: |
483 | 8 | 8 | ||
485 | 9 | >>> mainarea = find_tag_by_id(anon_browser.contents, 'mainarea') | 9 | >>> mainarea = find_main_content(anon_browser.contents) |
486 | 10 | >>> for header in mainarea.findAll('th'): | 10 | >>> for header in mainarea.findAll('th'): |
487 | 11 | ... print header.renderContents() | 11 | ... print header.renderContents() |
488 | 12 | Priority | 12 | Priority |
489 | @@ -21,6 +21,7 @@ | |||
490 | 21 | no spec assigned to people. | 21 | no spec assigned to people. |
491 | 22 | 22 | ||
492 | 23 | >>> anon_browser.open('http://launchpad.dev/sprints/ltsponsteroids/+assignments') | 23 | >>> anon_browser.open('http://launchpad.dev/sprints/ltsponsteroids/+assignments') |
495 | 24 | >>> 'No blueprints to display' in anon_browser.contents | 24 | >>> notice = find_tag_by_id(anon_browser.contents, 'no-blueprints') |
496 | 25 | True | 25 | >>> print extract_text(notice) |
497 | 26 | There are no open blueprints. | ||
498 | 26 | 27 | ||
499 | 27 | 28 | ||
500 | === modified file 'lib/lp/blueprints/stories/sprints/sprint-settopics.txt' | |||
501 | --- lib/lp/blueprints/stories/sprints/sprint-settopics.txt 2009-09-21 12:43:33 +0000 | |||
502 | +++ lib/lp/blueprints/stories/sprints/sprint-settopics.txt 2009-09-22 15:02:41 +0000 | |||
503 | @@ -70,7 +70,7 @@ | |||
504 | 70 | 70 | ||
505 | 71 | >>> print cprov_browser.title | 71 | >>> print cprov_browser.title |
506 | 72 | Review discussion topics for “Ubuntu DevSummit Guacamole” sprint : | 72 | Review discussion topics for “Ubuntu DevSummit Guacamole” sprint : |
508 | 73 | Blueprints for Ubuntu DevSummit Guacamole : | 73 | Blueprints : |
509 | 74 | Ubuntu DevSummit Guacamole : | 74 | Ubuntu DevSummit Guacamole : |
510 | 75 | Meetings | 75 | Meetings |
511 | 76 | 76 | ||
512 | 77 | 77 | ||
513 | === modified file 'lib/lp/blueprints/templates/hasspecifications-specs.pt' | |||
514 | --- lib/lp/blueprints/templates/hasspecifications-specs.pt 2009-07-17 17:59:07 +0000 | |||
515 | +++ lib/lp/blueprints/templates/hasspecifications-specs.pt 2009-09-22 15:02:41 +0000 | |||
516 | @@ -3,18 +3,16 @@ | |||
517 | 3 | xmlns:tal="http://xml.zope.org/namespaces/tal" | 3 | xmlns:tal="http://xml.zope.org/namespaces/tal" |
518 | 4 | xmlns:metal="http://xml.zope.org/namespaces/metal" | 4 | xmlns:metal="http://xml.zope.org/namespaces/metal" |
519 | 5 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" | 5 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
524 | 6 | xml:lang="en" | 6 | metal:use-macro="view/macro:page/main_side" |
521 | 7 | lang="en" | ||
522 | 8 | dir="ltr" | ||
523 | 9 | metal:use-macro="context/@@main_template/master" | ||
525 | 10 | i18n:domain="launchpad" | 7 | i18n:domain="launchpad" |
526 | 11 | > | 8 | > |
527 | 12 | 9 | ||
528 | 13 | <body> | 10 | <body> |
529 | 14 | 11 | ||
533 | 15 | <metal:portlets fill-slot="portlets"> | 12 | <tal:side metal:fill-slot="side"> |
534 | 16 | <div tal:replace="structure context/@@+portlet-latestspecs" /> | 13 | <tal:menu replace="structure context/@@+global-actions" /> |
535 | 17 | </metal:portlets> | 14 | <div tal:replace="structure context/@@+portlet-latestspecs" /> |
536 | 15 | </tal:side> | ||
537 | 18 | 16 | ||
538 | 19 | <div metal:fill-slot="main" | 17 | <div metal:fill-slot="main" |
539 | 20 | tal:define="specs view/specs; | 18 | tal:define="specs view/specs; |
540 | @@ -33,11 +31,6 @@ | |||
541 | 33 | </tal:block> | 31 | </tal:block> |
542 | 34 | </tal:block> | 32 | </tal:block> |
543 | 35 | 33 | ||
544 | 36 | <h1 tal:condition="view/is_person" | ||
545 | 37 | >Blueprints involving <tal:person replace="context/title" /></h1> | ||
546 | 38 | <h1 tal:condition="not:view/is_person" | ||
547 | 39 | >Blueprints for <tal:software replace="context/displayname" /></h1> | ||
548 | 40 | |||
549 | 41 | <div style="float: right;" | 34 | <div style="float: right;" |
550 | 42 | tal:content="structure context/@@+register-a-blueprint-button|nothing" /> | 35 | tal:content="structure context/@@+register-a-blueprint-button|nothing" /> |
551 | 43 | 36 | ||
552 | 44 | 37 | ||
553 | === modified file 'lib/lp/blueprints/templates/specificationtarget-assignments.pt' | |||
554 | --- lib/lp/blueprints/templates/specificationtarget-assignments.pt 2009-07-17 17:59:07 +0000 | |||
555 | +++ lib/lp/blueprints/templates/specificationtarget-assignments.pt 2009-09-22 15:02:41 +0000 | |||
556 | @@ -3,91 +3,95 @@ | |||
557 | 3 | xmlns:tal="http://xml.zope.org/namespaces/tal" | 3 | xmlns:tal="http://xml.zope.org/namespaces/tal" |
558 | 4 | xmlns:metal="http://xml.zope.org/namespaces/metal" | 4 | xmlns:metal="http://xml.zope.org/namespaces/metal" |
559 | 5 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" | 5 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
564 | 6 | xml:lang="en" | 6 | metal:use-macro="view/macro:page/main_side" |
561 | 7 | lang="en" | ||
562 | 8 | dir="ltr" | ||
563 | 9 | metal:use-macro="context/@@main_template/master" | ||
565 | 10 | i18n:domain="launchpad" | 7 | i18n:domain="launchpad" |
566 | 11 | > | 8 | > |
567 | 12 | 9 | ||
568 | 13 | <body> | 10 | <body> |
569 | 14 | 11 | ||
571 | 15 | <metal:leftportlets fill-slot="portlets_one"> | 12 | <tal:side metal:fill-slot="side"> |
572 | 13 | <tal:menu replace="structure context/@@+global-actions" /> | ||
573 | 16 | <div tal:replace="structure context/@@+portlet-latestspecs" /> | 14 | <div tal:replace="structure context/@@+portlet-latestspecs" /> |
579 | 17 | </metal:leftportlets> | 15 | </tal:side> |
575 | 18 | |||
576 | 19 | <metal:heading fill-slot="pageheading"> | ||
577 | 20 | <h1>Assignment of work on blueprints</h1> | ||
578 | 21 | </metal:heading> | ||
580 | 22 | 16 | ||
581 | 23 | <div metal:fill-slot="main"> | 17 | <div metal:fill-slot="main"> |
582 | 24 | 18 | ||
649 | 25 | <p class="informational message" tal:condition="not: view/specs"> | 19 | <p class="portlet" tal:condition="not: view/specs" id="no-blueprints"> |
650 | 26 | No blueprints to display. | 20 | There are no open blueprints. |
651 | 27 | </p> | 21 | </p> |
652 | 28 | 22 | ||
653 | 29 | <table class="listing sortable" tal:condition="view/specs" id="work"> | 23 | <div tal:condition="view/specs" class="portlet"> |
654 | 30 | <thead> | 24 | <p> |
655 | 31 | <tr> | 25 | This listing shows the assignment of work for |
656 | 32 | <th>Priority</th> | 26 | blueprints currently associated with |
657 | 33 | <th>Name</th> | 27 | <span tal:replace="context/displayname">Mozilla</span>. |
658 | 34 | <th>Definition</th> | 28 | The drafter is responsible for getting the specification correctly |
659 | 35 | <th>Delivery</th> | 29 | written up and approved. |
660 | 36 | <th>Assignee</th> | 30 | The approver is usually the person who would |
661 | 37 | <th>Drafter</th> | 31 | sign off on the specification. |
662 | 38 | <th>Approver</th> | 32 | </p> |
663 | 39 | </tr> | 33 | |
664 | 40 | </thead> | 34 | <table class="listing sortable" id="work"> |
665 | 41 | <tbody class="lesser"> | 35 | <thead> |
666 | 42 | <tr tal:repeat="spec view/specs"> | 36 | <tr> |
667 | 43 | <td> | 37 | <th>Priority</th> |
668 | 44 | <span class="sortkey" tal:content="spec/priority/sortkey" /> | 38 | <th>Name</th> |
669 | 45 | <span tal:content="spec/priority/title" | 39 | <th>Definition</th> |
670 | 46 | tal:attributes=" | 40 | <th>Delivery</th> |
671 | 47 | class string:specpriority${spec/priority/name}">High</span> | 41 | <th>Assignee</th> |
672 | 48 | </td> | 42 | <th>Drafter</th> |
673 | 49 | <td><a tal:content="spec/name/fmt:shorten/35" | 43 | <th>Approver</th> |
674 | 50 | tal:attributes=" | 44 | </tr> |
675 | 51 | href spec/fmt:url; | 45 | </thead> |
676 | 52 | title spec/title">foo-bar-baz</a> | 46 | <tbody class="lesser"> |
677 | 53 | <img src="/@@/info" alt="Informational" | 47 | <tr tal:repeat="spec view/specs"> |
678 | 54 | tal:condition="spec/informational" /> | 48 | <td> |
679 | 55 | </td> | 49 | <span class="sortkey" tal:content="spec/priority/sortkey" /> |
680 | 56 | <td> | 50 | <span tal:content="spec/priority/title" |
681 | 57 | <span class="sortkey" tal:content="spec/definition_status/sortkey" /> | 51 | tal:attributes=" |
682 | 58 | <span tal:content="spec/definition_status/title" | 52 | class string:specpriority${spec/priority/name}">High</span> |
683 | 59 | tal:attributes=" | 53 | </td> |
684 | 60 | class string:specstatus${spec/definition_status/name}">Approved</span> | 54 | <td> |
685 | 61 | </td> | 55 | <a tal:replace="structure spec/fmt:link">Better mousetrap</a> |
686 | 62 | <td> | 56 | <span tal:condition="spec/informational" |
687 | 63 | <span class="sortkey" tal:content="spec/implementation_status/sortkey" /> | 57 | class="info sprite" |
688 | 64 | <span tal:content="spec/implementation_status/title" | 58 | alt="Informational" /> |
689 | 65 | tal:attributes=" | 59 | </td> |
690 | 66 | class string:specdelivery${spec/implementation_status/name}">Slow | 60 | <td> |
691 | 67 | </span> | 61 | <span class="sortkey" tal:content="spec/definition_status/sortkey" /> |
692 | 68 | </td> | 62 | <span tal:content="spec/definition_status/title" |
693 | 69 | <td><a tal:condition="spec/assignee" | 63 | tal:attributes=" |
694 | 70 | tal:content="spec/assignee/name" | 64 | class string:specstatus${spec/definition_status/name}">Approved</span> |
695 | 71 | tal:attributes="href spec/assignee/fmt:url">Assignee Bar</a></td> | 65 | </td> |
696 | 72 | <td><a tal:condition="spec/drafter" | 66 | <td> |
697 | 73 | tal:content="spec/drafter/name" | 67 | <span class="sortkey" tal:content="spec/implementation_status/sortkey" /> |
698 | 74 | tal:attributes="href spec/drafter/fmt:url">Drafter Baz</a></td> | 68 | <span tal:content="spec/implementation_status/title" |
699 | 75 | <td><a tal:condition="spec/approver" | 69 | tal:attributes=" |
700 | 76 | tal:content="spec/approver/name" | 70 | class string:specdelivery${spec/implementation_status/name}">Slow |
701 | 77 | tal:attributes="href spec/approver/fmt:url">Approver Foo</a></td> | 71 | </span> |
702 | 78 | </tr> | 72 | </td> |
703 | 79 | </tbody> | 73 | <td> |
704 | 80 | </table> | 74 | <a tal:condition="spec/assignee" |
705 | 81 | 75 | tal:replace="structure spec/assignee/fmt:link"> | |
706 | 82 | <p tal:condition="view/specs"> | 76 | Assignee Bar |
707 | 83 | This listing shows the assignment of work for | 77 | </a> |
708 | 84 | blueprints currently associated with | 78 | </td> |
709 | 85 | <span tal:replace="context/displayname">Mozilla</span>. | 79 | <td> |
710 | 86 | The drafter is responsible for getting the specification correctly | 80 | <a tal:condition="spec/drafter" |
711 | 87 | written up and approved. | 81 | tal:replace="structure spec/drafter/fmt:link"> |
712 | 88 | The approver is usually the person who would | 82 | Drafter Baz |
713 | 89 | sign off on the specification. | 83 | </a> |
714 | 90 | </p> | 84 | </td> |
715 | 85 | <td> | ||
716 | 86 | <a tal:condition="spec/approver" | ||
717 | 87 | tal:replace="structure spec/approver/fmt:link"> | ||
718 | 88 | Approver Foo | ||
719 | 89 | </a> | ||
720 | 90 | </td> | ||
721 | 91 | </tr> | ||
722 | 92 | </tbody> | ||
723 | 93 | </table> | ||
724 | 94 | </div> | ||
725 | 91 | 95 | ||
726 | 92 | </div> | 96 | </div> |
727 | 93 | </body> | 97 | </body> |
728 | 94 | 98 | ||
729 | === modified file 'lib/lp/registry/browser/distribution.py' | |||
730 | --- lib/lp/registry/browser/distribution.py 2009-09-16 00:40:53 +0000 | |||
731 | +++ lib/lp/registry/browser/distribution.py 2009-09-22 15:02:41 +0000 | |||
732 | @@ -47,6 +47,8 @@ | |||
733 | 47 | from zope.security.interfaces import Unauthorized | 47 | from zope.security.interfaces import Unauthorized |
734 | 48 | 48 | ||
735 | 49 | from canonical.cachedproperty import cachedproperty | 49 | from canonical.cachedproperty import cachedproperty |
736 | 50 | from lp.blueprints.browser.specificationtarget import ( | ||
737 | 51 | HasSpecificationsMenuMixin) | ||
738 | 50 | from lp.registry.browser.announcement import HasAnnouncementsView | 52 | from lp.registry.browser.announcement import HasAnnouncementsView |
739 | 51 | from lp.registry.browser.menu import ( | 53 | from lp.registry.browser.menu import ( |
740 | 52 | IRegistryCollectionNavigationMenu, RegistryCollectionActionMenuBase) | 54 | IRegistryCollectionNavigationMenu, RegistryCollectionActionMenuBase) |
741 | @@ -454,31 +456,12 @@ | |||
742 | 454 | return Link('+subscribe', text, icon='edit') | 456 | return Link('+subscribe', text, icon='edit') |
743 | 455 | 457 | ||
744 | 456 | 458 | ||
747 | 457 | class DistributionSpecificationsMenu(ApplicationMenu): | 459 | class DistributionSpecificationsMenu(NavigationMenu, |
748 | 458 | 460 | HasSpecificationsMenuMixin): | |
749 | 459 | usedfor = IDistribution | 461 | usedfor = IDistribution |
750 | 460 | facet = 'specifications' | 462 | facet = 'specifications' |
751 | 461 | links = ['listall', 'doc', 'assignments', 'new'] | 463 | links = ['listall', 'doc', 'assignments', 'new'] |
752 | 462 | 464 | ||
753 | 463 | def listall(self): | ||
754 | 464 | text = 'List all blueprints' | ||
755 | 465 | return Link('+specs?show=all', text, icon='info') | ||
756 | 466 | |||
757 | 467 | def assignments(self): | ||
758 | 468 | text = 'Assignments' | ||
759 | 469 | return Link('+assignments', text, icon='info') | ||
760 | 470 | |||
761 | 471 | def doc(self): | ||
762 | 472 | text = 'Documentation' | ||
763 | 473 | summary = 'List all complete informational specifications' | ||
764 | 474 | return Link('+documentation', text, summary, | ||
765 | 475 | icon='info') | ||
766 | 476 | |||
767 | 477 | def new(self): | ||
768 | 478 | text = 'Register a blueprint' | ||
769 | 479 | summary = 'Register a new blueprint for %s' % self.context.title | ||
770 | 480 | return Link('+addspec', text, summary, icon='add') | ||
771 | 481 | |||
772 | 482 | 465 | ||
773 | 483 | class DistributionPackageSearchView(PackageSearchViewBase): | 466 | class DistributionPackageSearchView(PackageSearchViewBase): |
774 | 484 | """Customised PackageSearchView for Distribution""" | 467 | """Customised PackageSearchView for Distribution""" |
775 | 485 | 468 | ||
776 | === modified file 'lib/lp/registry/browser/distroseries.py' | |||
777 | --- lib/lp/registry/browser/distroseries.py 2009-09-15 01:17:46 +0000 | |||
778 | +++ lib/lp/registry/browser/distroseries.py 2009-09-22 15:02:41 +0000 | |||
779 | @@ -28,6 +28,8 @@ | |||
780 | 28 | from canonical.database.constants import UTC_NOW | 28 | from canonical.database.constants import UTC_NOW |
781 | 29 | from canonical.launchpad import _ | 29 | from canonical.launchpad import _ |
782 | 30 | from canonical.launchpad import helpers | 30 | from canonical.launchpad import helpers |
783 | 31 | from lp.blueprints.browser.specificationtarget import ( | ||
784 | 32 | HasSpecificationsMenuMixin) | ||
785 | 31 | from lp.bugs.browser.bugtask import BugTargetTraversalMixin | 33 | from lp.bugs.browser.bugtask import BugTargetTraversalMixin |
786 | 32 | from lp.soyuz.browser.build import BuildRecordsView | 34 | from lp.soyuz.browser.build import BuildRecordsView |
787 | 33 | from canonical.launchpad.browser.packagesearch import PackageSearchViewBase | 35 | from canonical.launchpad.browser.packagesearch import PackageSearchViewBase |
788 | @@ -49,7 +51,7 @@ | |||
789 | 49 | from canonical.launchpad.webapp.launchpadform import ( | 51 | from canonical.launchpad.webapp.launchpadform import ( |
790 | 50 | LaunchpadEditFormView, LaunchpadFormView) | 52 | LaunchpadEditFormView, LaunchpadFormView) |
791 | 51 | from canonical.launchpad.webapp.menu import ( | 53 | from canonical.launchpad.webapp.menu import ( |
793 | 52 | ApplicationMenu, Link, enabled_with_permission) | 54 | ApplicationMenu, Link, NavigationMenu, enabled_with_permission) |
794 | 53 | from canonical.launchpad.webapp.publisher import ( | 55 | from canonical.launchpad.webapp.publisher import ( |
795 | 54 | canonical_url, stepthrough, stepto) | 56 | canonical_url, stepthrough, stepto) |
796 | 55 | from canonical.widgets.itemswidgets import LaunchpadDropdownWidget | 57 | from canonical.widgets.itemswidgets import LaunchpadDropdownWidget |
797 | @@ -225,43 +227,12 @@ | |||
798 | 225 | return Link('+subscribe', 'Subscribe to bug mail') | 227 | return Link('+subscribe', 'Subscribe to bug mail') |
799 | 226 | 228 | ||
800 | 227 | 229 | ||
802 | 228 | class DistroSeriesSpecificationsMenu(ApplicationMenu): | 230 | class DistroSeriesSpecificationsMenu(NavigationMenu, |
803 | 231 | HasSpecificationsMenuMixin): | ||
804 | 229 | 232 | ||
805 | 230 | usedfor = IDistroSeries | 233 | usedfor = IDistroSeries |
806 | 231 | facet = 'specifications' | 234 | facet = 'specifications' |
840 | 232 | links = ['listall', 'table', 'setgoals', 'listdeclined', 'new'] | 235 | links = ['listall', 'listdeclined', 'assignments', 'setgoals', 'new'] |
808 | 233 | |||
809 | 234 | def listall(self): | ||
810 | 235 | text = 'List all blueprints' | ||
811 | 236 | return Link('+specs?show=all', text, icon='info') | ||
812 | 237 | |||
813 | 238 | def listapproved(self): | ||
814 | 239 | text = 'List approved blueprints' | ||
815 | 240 | return Link('+specs?acceptance=accepted', text, icon='info') | ||
816 | 241 | |||
817 | 242 | def listproposed(self): | ||
818 | 243 | text = 'List proposed blueprints' | ||
819 | 244 | return Link('+specs?acceptance=proposed', text, icon='info') | ||
820 | 245 | |||
821 | 246 | def listdeclined(self): | ||
822 | 247 | text = 'List declined blueprints' | ||
823 | 248 | summary = 'Show the goals which have been declined' | ||
824 | 249 | return Link('+specs?acceptance=declined', text, icon='info') | ||
825 | 250 | |||
826 | 251 | def setgoals(self): | ||
827 | 252 | text = 'Set series goals' | ||
828 | 253 | summary = 'Approve or decline feature goals that have been proposed' | ||
829 | 254 | return Link('+setgoals', text, icon='info') | ||
830 | 255 | |||
831 | 256 | def table(self): | ||
832 | 257 | text = 'Assignments' | ||
833 | 258 | summary = 'Show the assignee, drafter and approver of these specs' | ||
834 | 259 | return Link('+assignments', text, icon='info') | ||
835 | 260 | |||
836 | 261 | def new(self): | ||
837 | 262 | text = 'Register a blueprint' | ||
838 | 263 | summary = 'Register a new blueprint for %s' % self.context.title | ||
839 | 264 | return Link('+addspec', text, summary, icon='add') | ||
841 | 265 | 236 | ||
842 | 266 | 237 | ||
843 | 267 | class DistroSeriesPackageSearchView(PackageSearchViewBase): | 238 | class DistroSeriesPackageSearchView(PackageSearchViewBase): |
844 | 268 | 239 | ||
845 | === modified file 'lib/lp/registry/browser/person.py' | |||
846 | --- lib/lp/registry/browser/person.py 2009-09-20 07:13:52 +0000 | |||
847 | +++ lib/lp/registry/browser/person.py 2009-09-22 15:02:41 +0000 | |||
848 | @@ -775,7 +775,7 @@ | |||
849 | 775 | return Link('+commentedbugs', text, summary=summary) | 775 | return Link('+commentedbugs', text, summary=summary) |
850 | 776 | 776 | ||
851 | 777 | 777 | ||
853 | 778 | class PersonSpecsMenu(ApplicationMenu): | 778 | class PersonSpecsMenu(NavigationMenu): |
854 | 779 | 779 | ||
855 | 780 | usedfor = IPerson | 780 | usedfor = IPerson |
856 | 781 | facet = 'specifications' | 781 | facet = 'specifications' |
857 | @@ -786,28 +786,28 @@ | |||
858 | 786 | def registrant(self): | 786 | def registrant(self): |
859 | 787 | text = 'Registrant' | 787 | text = 'Registrant' |
860 | 788 | summary = 'List specs registered by %s' % self.context.displayname | 788 | summary = 'List specs registered by %s' % self.context.displayname |
862 | 789 | return Link('+specs?role=registrant', text, summary, icon='spec') | 789 | return Link('+specs?role=registrant', text, summary, icon='blueprint') |
863 | 790 | 790 | ||
864 | 791 | def approver(self): | 791 | def approver(self): |
865 | 792 | text = 'Approver' | 792 | text = 'Approver' |
866 | 793 | summary = 'List specs with %s is supposed to approve' % ( | 793 | summary = 'List specs with %s is supposed to approve' % ( |
867 | 794 | self.context.displayname) | 794 | self.context.displayname) |
869 | 795 | return Link('+specs?role=approver', text, summary, icon='spec') | 795 | return Link('+specs?role=approver', text, summary, icon='blueprint') |
870 | 796 | 796 | ||
871 | 797 | def assignee(self): | 797 | def assignee(self): |
872 | 798 | text = 'Assignee' | 798 | text = 'Assignee' |
873 | 799 | summary = 'List specs for which %s is the assignee' % ( | 799 | summary = 'List specs for which %s is the assignee' % ( |
874 | 800 | self.context.displayname) | 800 | self.context.displayname) |
876 | 801 | return Link('+specs?role=assignee', text, summary, icon='spec') | 801 | return Link('+specs?role=assignee', text, summary, icon='blueprint') |
877 | 802 | 802 | ||
878 | 803 | def drafter(self): | 803 | def drafter(self): |
879 | 804 | text = 'Drafter' | 804 | text = 'Drafter' |
880 | 805 | summary = 'List specs drafted by %s' % self.context.displayname | 805 | summary = 'List specs drafted by %s' % self.context.displayname |
882 | 806 | return Link('+specs?role=drafter', text, summary, icon='spec') | 806 | return Link('+specs?role=drafter', text, summary, icon='blueprint') |
883 | 807 | 807 | ||
884 | 808 | def subscriber(self): | 808 | def subscriber(self): |
885 | 809 | text = 'Subscriber' | 809 | text = 'Subscriber' |
887 | 810 | return Link('+specs?role=subscriber', text, icon='spec') | 810 | return Link('+specs?role=subscriber', text, icon='blueprint') |
888 | 811 | 811 | ||
889 | 812 | def feedback(self): | 812 | def feedback(self): |
890 | 813 | text = 'Feedback requests' | 813 | text = 'Feedback requests' |
891 | 814 | 814 | ||
892 | === modified file 'lib/lp/registry/browser/product.py' | |||
893 | --- lib/lp/registry/browser/product.py 2009-09-18 01:34:06 +0000 | |||
894 | +++ lib/lp/registry/browser/product.py 2009-09-22 15:02:41 +0000 | |||
895 | @@ -58,6 +58,8 @@ | |||
896 | 58 | from canonical.launchpad import _ | 58 | from canonical.launchpad import _ |
897 | 59 | from canonical.launchpad.fields import PillarAliases, PublicPersonChoice | 59 | from canonical.launchpad.fields import PillarAliases, PublicPersonChoice |
898 | 60 | from lp.app.interfaces.headings import IEditableContextTitle | 60 | from lp.app.interfaces.headings import IEditableContextTitle |
899 | 61 | from lp.blueprints.browser.specificationtarget import ( | ||
900 | 62 | HasSpecificationsMenuMixin) | ||
901 | 61 | from lp.bugs.interfaces.bugtask import RESOLVED_BUGTASK_STATUSES | 63 | from lp.bugs.interfaces.bugtask import RESOLVED_BUGTASK_STATUSES |
902 | 62 | from lp.bugs.interfaces.bugwatch import IBugTracker | 64 | from lp.bugs.interfaces.bugwatch import IBugTracker |
903 | 63 | from lp.services.worlddata.interfaces.country import ICountry | 65 | from lp.services.worlddata.interfaces.country import ICountry |
904 | @@ -475,32 +477,11 @@ | |||
905 | 475 | return Link('+subscribe', text, icon='edit') | 477 | return Link('+subscribe', text, icon='edit') |
906 | 476 | 478 | ||
907 | 477 | 479 | ||
910 | 478 | class ProductSpecificationsMenu(ApplicationMenu): | 480 | class ProductSpecificationsMenu(NavigationMenu, |
911 | 479 | 481 | HasSpecificationsMenuMixin): | |
912 | 480 | usedfor = IProduct | 482 | usedfor = IProduct |
913 | 481 | facet = 'specifications' | 483 | facet = 'specifications' |
936 | 482 | links = ['listall', 'doc', 'table', 'new'] | 484 | links = ['listall', 'doc', 'assignments', 'new'] |
915 | 483 | |||
916 | 484 | def listall(self): | ||
917 | 485 | text = 'List all blueprints' | ||
918 | 486 | summary = 'Show all specifications for %s' % self.context.title | ||
919 | 487 | return Link('+specs?show=all', text, summary, icon='info') | ||
920 | 488 | |||
921 | 489 | def doc(self): | ||
922 | 490 | text = 'List documentation' | ||
923 | 491 | summary = 'List all complete informational specifications' | ||
924 | 492 | return Link('+documentation', text, summary, | ||
925 | 493 | icon='info') | ||
926 | 494 | |||
927 | 495 | def table(self): | ||
928 | 496 | text = 'Assignments' | ||
929 | 497 | summary = 'Show the full assignment of work, drafting and approving' | ||
930 | 498 | return Link('+assignments', text, summary, icon='info') | ||
931 | 499 | |||
932 | 500 | def new(self): | ||
933 | 501 | text = 'Register a blueprint' | ||
934 | 502 | summary = 'Register a new blueprint for %s' % self.context.title | ||
935 | 503 | return Link('+addspec', text, summary, icon='add') | ||
937 | 504 | 485 | ||
938 | 505 | 486 | ||
939 | 506 | def _sort_distros(a, b): | 487 | def _sort_distros(a, b): |
940 | 507 | 488 | ||
941 | === modified file 'lib/lp/registry/browser/productseries.py' | |||
942 | --- lib/lp/registry/browser/productseries.py 2009-09-15 02:16:19 +0000 | |||
943 | +++ lib/lp/registry/browser/productseries.py 2009-09-22 15:02:41 +0000 | |||
944 | @@ -39,6 +39,8 @@ | |||
945 | 39 | from canonical.cachedproperty import cachedproperty | 39 | from canonical.cachedproperty import cachedproperty |
946 | 40 | from canonical.launchpad import _ | 40 | from canonical.launchpad import _ |
947 | 41 | from lp.code.browser.branchref import BranchRef | 41 | from lp.code.browser.branchref import BranchRef |
948 | 42 | from lp.blueprints.browser.specificationtarget import ( | ||
949 | 43 | HasSpecificationsMenuMixin) | ||
950 | 42 | from lp.blueprints.interfaces.specification import ( | 44 | from lp.blueprints.interfaces.specification import ( |
951 | 43 | ISpecificationSet, SpecificationImplementationStatus) | 45 | ISpecificationSet, SpecificationImplementationStatus) |
952 | 44 | from lp.bugs.interfaces.bugtask import BugTaskStatus | 46 | from lp.bugs.interfaces.bugtask import BugTaskStatus |
953 | @@ -247,7 +249,8 @@ | |||
954 | 247 | return Link('+subscribe', 'Subscribe to bug mail') | 249 | return Link('+subscribe', 'Subscribe to bug mail') |
955 | 248 | 250 | ||
956 | 249 | 251 | ||
958 | 250 | class ProductSeriesSpecificationsMenu(ApplicationMenu): | 252 | class ProductSeriesSpecificationsMenu(NavigationMenu, |
959 | 253 | HasSpecificationsMenuMixin): | ||
960 | 251 | """Specs menu for ProductSeries. | 254 | """Specs menu for ProductSeries. |
961 | 252 | 255 | ||
962 | 253 | This menu needs to keep track of whether we are showing all the | 256 | This menu needs to keep track of whether we are showing all the |
963 | @@ -258,46 +261,7 @@ | |||
964 | 258 | 261 | ||
965 | 259 | usedfor = IProductSeries | 262 | usedfor = IProductSeries |
966 | 260 | facet = 'specifications' | 263 | facet = 'specifications' |
1007 | 261 | links = ['listall', 'table', 'setgoals', 'listdeclined', 'new'] | 264 | links = ['listall', 'assignments', 'setgoals', 'listdeclined', 'new'] |
968 | 262 | |||
969 | 263 | def listall(self): | ||
970 | 264 | """Return a link to show all blueprints.""" | ||
971 | 265 | text = 'List all blueprints' | ||
972 | 266 | return Link('+specs?show=all', text, icon='info') | ||
973 | 267 | |||
974 | 268 | def listaccepted(self): | ||
975 | 269 | """Return a link to show the approved goals.""" | ||
976 | 270 | text = 'List approved blueprints' | ||
977 | 271 | return Link('+specs?acceptance=accepted', text, icon='info') | ||
978 | 272 | |||
979 | 273 | def listproposed(self): | ||
980 | 274 | """Return a link to show the proposed goals.""" | ||
981 | 275 | text = 'List proposed blueprints' | ||
982 | 276 | return Link('+specs?acceptance=proposed', text, icon='info') | ||
983 | 277 | |||
984 | 278 | def listdeclined(self): | ||
985 | 279 | """Return a link to show the declined goals.""" | ||
986 | 280 | text = 'List declined blueprints' | ||
987 | 281 | summary = 'Show the goals which have been declined' | ||
988 | 282 | return Link('+specs?acceptance=declined', text, summary, icon='info') | ||
989 | 283 | |||
990 | 284 | def setgoals(self): | ||
991 | 285 | """Return a link to set the series goals.""" | ||
992 | 286 | text = 'Set series goals' | ||
993 | 287 | summary = 'Approve or decline feature goals that have been proposed' | ||
994 | 288 | return Link('+setgoals', text, summary, icon='edit') | ||
995 | 289 | |||
996 | 290 | def table(self): | ||
997 | 291 | """Return a link to show the people assigned to the blueprint.""" | ||
998 | 292 | text = 'Assignments' | ||
999 | 293 | summary = 'Show the assignee, drafter and approver of these specs' | ||
1000 | 294 | return Link('+assignments', text, summary, icon='info') | ||
1001 | 295 | |||
1002 | 296 | def new(self): | ||
1003 | 297 | """Return a link to register a blueprint.""" | ||
1004 | 298 | text = 'Register a blueprint' | ||
1005 | 299 | summary = 'Register a new blueprint for %s' % self.context.title | ||
1006 | 300 | return Link('+addspec', text, summary, icon='add') | ||
1008 | 301 | 265 | ||
1009 | 302 | 266 | ||
1010 | 303 | class ProductSeriesOverviewNavigationMenu(NavigationMenu): | 267 | class ProductSeriesOverviewNavigationMenu(NavigationMenu): |
1011 | 304 | 268 | ||
1012 | === modified file 'lib/lp/registry/browser/project.py' | |||
1013 | --- lib/lp/registry/browser/project.py 2009-09-15 20:41:36 +0000 | |||
1014 | +++ lib/lp/registry/browser/project.py 2009-09-22 15:02:41 +0000 | |||
1015 | @@ -44,6 +44,8 @@ | |||
1016 | 44 | from canonical.launchpad import _ | 44 | from canonical.launchpad import _ |
1017 | 45 | from canonical.launchpad.webapp.interfaces import NotFoundError | 45 | from canonical.launchpad.webapp.interfaces import NotFoundError |
1018 | 46 | from canonical.launchpad.webapp.menu import NavigationMenu | 46 | from canonical.launchpad.webapp.menu import NavigationMenu |
1019 | 47 | from lp.blueprints.browser.specificationtarget import ( | ||
1020 | 48 | HasSpecificationsMenuMixin) | ||
1021 | 47 | from lp.registry.interfaces.product import IProductSet | 49 | from lp.registry.interfaces.product import IProductSet |
1022 | 48 | from lp.registry.interfaces.project import ( | 50 | from lp.registry.interfaces.project import ( |
1023 | 49 | IProject, IProjectSeries, IProjectSet) | 51 | IProject, IProjectSeries, IProjectSet) |
1024 | @@ -267,30 +269,12 @@ | |||
1025 | 267 | links = ('branding', 'reassign', 'driver', 'administer') | 269 | links = ('branding', 'reassign', 'driver', 'administer') |
1026 | 268 | 270 | ||
1027 | 269 | 271 | ||
1030 | 270 | class ProjectSpecificationsMenu(ApplicationMenu): | 272 | class ProjectSpecificationsMenu(NavigationMenu, |
1031 | 271 | 273 | HasSpecificationsMenuMixin): | |
1032 | 272 | usedfor = IProject | 274 | usedfor = IProject |
1033 | 273 | facet = 'specifications' | 275 | facet = 'specifications' |
1034 | 274 | links = ['listall', 'doc', 'assignments', 'new'] | 276 | links = ['listall', 'doc', 'assignments', 'new'] |
1035 | 275 | 277 | ||
1036 | 276 | def listall(self): | ||
1037 | 277 | text = 'List all blueprints' | ||
1038 | 278 | return Link('+specs?show=all', text, icon='info') | ||
1039 | 279 | |||
1040 | 280 | def doc(self): | ||
1041 | 281 | text = 'List documentation' | ||
1042 | 282 | summary = 'Show all completed informational specifications' | ||
1043 | 283 | return Link('+documentation', text, summary, icon="info") | ||
1044 | 284 | |||
1045 | 285 | def assignments(self): | ||
1046 | 286 | text = 'Assignments' | ||
1047 | 287 | return Link('+assignments', text, icon='info') | ||
1048 | 288 | |||
1049 | 289 | def new(self): | ||
1050 | 290 | text = 'Register a blueprint' | ||
1051 | 291 | summary = 'Register a new blueprint for %s' % self.context.title | ||
1052 | 292 | return Link('+addspec', text, summary, icon='add') | ||
1053 | 293 | |||
1054 | 294 | 278 | ||
1055 | 295 | class ProjectAnswersMenu(QuestionCollectionAnswersMenu): | 279 | class ProjectAnswersMenu(QuestionCollectionAnswersMenu): |
1056 | 296 | """Menu for the answers facet of projects.""" | 280 | """Menu for the answers facet of projects.""" |
= Summary =
Bug 434055 and bug 434195. s-specs. pt' to 3.0 design. Convert specificationst arget-assignmen ts to UI 3.0.
Convert 'hasspefication
This is a combined branch, jtv's part for bug 434195 has already been reviewed.
== Implementation details ==
The trouble with hasspecificaito ns-spece. pt was that it is used in many different contexts and that each hat its own ApplicationMenu. The menus shared most links in varying combinations, so I aggregated the links into one Mixin that is now used in all Menus.
I converted the ApplicationMenus to NavigationMenus to use them as global-actions. This was the most straight-forward way of conversion without loosing any functionality. I also changed that for specificationst arget-assignmen ts where jtv had removed the menu completely.
I fixed the Breadcrumb for the specifications vhost as it was repeating the context name (like "Foo Bar >> Specifications involving Foo Bar", now it's "Foo Bar >> Blueprints") and I normalized on using the term "blueprint" ;-)
Some label and page_title work was also done.
Did I forget to mention anything?
== Code ==
I will paste a separate diff to show the differences to jtv's branch.