Merge lp:~dooferlad/launchpad/upcomingwork-expand-all into lp:launchpad
- upcomingwork-expand-all
- Merge into devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Curtis Hovey | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 15410 | ||||
Proposed branch: | lp:~dooferlad/launchpad/upcomingwork-expand-all | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
543 lines (+476/-12) 4 files modified
lib/lp/blueprints/javascript/tests/test_workitems.html (+211/-0) lib/lp/blueprints/javascript/tests/test_workitems.js (+153/-0) lib/lp/blueprints/javascript/workitems.js (+94/-0) lib/lp/registry/templates/person-upcomingwork.pt (+18/-12) |
||||
To merge this branch: | bzr merge lp:~dooferlad/launchpad/upcomingwork-expand-all | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Curtis Hovey (community) | code | Approve | |
James Tunnicliffe (community) | Needs Resubmitting | ||
Review via email: mp+107083@code.launchpad.net |
Commit message
Upcoming work page should have expand all links
Description of the change
-- Summary
Feature Request: Upcoming work page should have expand all links. I also added collapse all and set back to default links since these seemed like logical extensions of the same feature (and likely to be requested if they weren’t present).
-- Proposed fix
Add JavaScript links to upcoming work view to expand / collapse / restore all work item lists for a blueprint.
-- Pre-implementation notes
None.
-- Implementation details
person-
-- LOC Rationale
Added a few lines because of new functionality. These will be more than offset by:
https:/
-- Tests
None.
-- Demo and Q/A
1. In a dev instance run http://
2. Visit https:/
-- Lint
None.
James Tunnicliffe (dooferlad) wrote : | # |
Thanks for the review.
I haven't started on tests yet, but I have moved the existing code around as requested (I hope), so feedback on that is welcome.
Curtis Hovey (sinzui) wrote : | # |
Thank you for extracting the code.
Consider using
!Y.
for
expanders[
The code needs an array. or just use
!Y.Lang.
if you just want to be sure there is something.
James Tunnicliffe (dooferlad) wrote : | # |
Hi,
I am not sure how best to proceed with testing. I have got a test JS and HTML set up with a bit of example layout in the HTML for the JS to search through. It is my intention to run setUpWorkItemEx
Other tests would start using the same template but simulate clicks to test each on click function is run when expected.
So, to do this I would need to pass in Y.lp.app.
One odd thing is that the JS console at the moment (in Chrome) contains:
TestRunner: Testing began at Fri May 25 2012 15:53:01 GMT+0100 (BST).
TestRunner: Test suite "lp.workitems.
TestRunner: Testing began at Fri May 25 2012 15:53:01 GMT+0100 (BST).
TestRunner: Test suite "yuitests133795
TestRunner: Test case "setUpWorkItemE
TestRunner: Test suite "yuitests133795
Passed:0 Failed:0 Total:0 (0 ignored)
TestRunner: Testing completed at Fri May 25 2012 15:53:01 GMT+0100 (BST).
Passed:0 Failed:0 Total:0 (0 ignored)
TestRunner: test_setUpWorkI
Unexpected error: Cannot call method 'reversible_
TestRunner: Test case "setUpWorkItemE
Passed:0 Failed:1 Total:1 (0 ignored)
TestRunner: Test suite "lp.workitems.
Passed:0 Failed:1 Total:1 (0 ignored)
TestRunner: Testing completed at Fri May 25 2012 15:53:03 GMT+0100 (BST).
Passed:0 Failed:1 Total:1 (0 ignored)
I don't know where the Test suite "yuitests<random number>" came from. Only they are visible in the browser based console. I have pushed my branch so you can have a look at it, if you want to.
Curtis Hovey (sinzui) wrote : | # |
You can ignore the random numbers. YUI assigns a unique id to every node it creates.
The test-suite should only test the functions in the code you wrote. We want to verify that the correct function is wired to the correct element. Since the functions are anonymous, I imagine we want to test that the element has or does not have the "hidden" class.
According to the module you created, it only requires lp.app.
The html file is not setup to be reset by the test. Take a look at
lib/
Which uses the 'type="
test_util.js is testing several setup functions that also do hide and show (but not expanders). You might find this test helpful because it illustrates how to verify a method was called during an event, then checks the final state of the element. I think this style of test could be adapted by passing in an example expander config.
James Tunnicliffe (dooferlad) wrote : | # |
I believe I have addressed the previous comments. Please re-review.
Thanks!
Curtis Hovey (sinzui) wrote : | # |
Lines 256 and 269 are missing the space between the keyword and the predicate:
if(
should be
if (
This looks good. I can land this once you fix the space.
James Tunnicliffe (dooferlad) wrote : | # |
Done.
Preview Diff
1 | === added directory 'lib/lp/blueprints/javascript' | |||
2 | === added directory 'lib/lp/blueprints/javascript/tests' | |||
3 | === added file 'lib/lp/blueprints/javascript/tests/test_workitems.html' | |||
4 | --- lib/lp/blueprints/javascript/tests/test_workitems.html 1970-01-01 00:00:00 +0000 | |||
5 | +++ lib/lp/blueprints/javascript/tests/test_workitems.html 2012-06-13 15:31:25 +0000 | |||
6 | @@ -0,0 +1,211 @@ | |||
7 | 1 | <!DOCTYPE html> | ||
8 | 2 | <!-- | ||
9 | 3 | Copyright 2012 Canonical Ltd. This software is licensed under the | ||
10 | 4 | GNU Affero General Public License version 3 (see the file LICENSE). | ||
11 | 5 | --> | ||
12 | 6 | |||
13 | 7 | <html> | ||
14 | 8 | <head> | ||
15 | 9 | <title>Test Work Item Expanders</title> | ||
16 | 10 | |||
17 | 11 | <!-- YUI and test setup --> | ||
18 | 12 | <script type="text/javascript" | ||
19 | 13 | src="../../../../../build/js/yui/yui/yui.js"> | ||
20 | 14 | </script> | ||
21 | 15 | <link rel="stylesheet" | ||
22 | 16 | href="../../../../../build/js/yui/console/assets/console-core.css" /> | ||
23 | 17 | <link rel="stylesheet" | ||
24 | 18 | href="../../../../../build/js/yui/console/assets/skins/sam/console.css" /> | ||
25 | 19 | <link rel="stylesheet" | ||
26 | 20 | href="../../../../../build/js/yui/test/assets/skins/sam/test.css" /> | ||
27 | 21 | |||
28 | 22 | <script type="text/javascript" | ||
29 | 23 | src="../../../../../build/js/lp/app/testing/testrunner.js"></script> | ||
30 | 24 | |||
31 | 25 | <link rel="stylesheet" href="../../../app/javascript/testing/test.css" /> | ||
32 | 26 | |||
33 | 27 | <!-- Dependencies --> | ||
34 | 28 | <script type="text/javascript" | ||
35 | 29 | src="../../../../../build/js/lp/app/effects/effects.js"></script> | ||
36 | 30 | <script type="text/javascript" | ||
37 | 31 | src="../../../../../build/js/lp/app/expander.js"></script> | ||
38 | 32 | |||
39 | 33 | <!-- The module under test. --> | ||
40 | 34 | <script type="text/javascript" src="../workitems.js"></script> | ||
41 | 35 | |||
42 | 36 | <!-- The test suite. --> | ||
43 | 37 | <script type="text/javascript" src="test_workitems.js"></script> | ||
44 | 38 | |||
45 | 39 | </head> | ||
46 | 40 | <body class="yui3-skin-sam"> | ||
47 | 41 | <ul id="suites"> | ||
48 | 42 | <li>lp.workitems.expanders</li> | ||
49 | 43 | </ul> | ||
50 | 44 | <!-- Example markup required by test suite --> | ||
51 | 45 | <div id="test-root"> | ||
52 | 46 | <div id="fixture"></div> | ||
53 | 47 | |||
54 | 48 | <script type="text/x-template" id="work-items-test-0"> | ||
55 | 49 | <div class="workitems-group" id="milestone_0"> | ||
56 | 50 | <table class="listing"> | ||
57 | 51 | <thead> | ||
58 | 52 | <tr> | ||
59 | 53 | <th> | ||
60 | 54 | <div style="float: left; font-weight: normal;">All: | ||
61 | 55 | <a href="#expandall" class="expandall_link" | ||
62 | 56 | id="expand_milestone_0">Expand</a> | ||
63 | 57 | <a href="#collapseall" class="collapseall_link" | ||
64 | 58 | id="collapse_milestone_0">Collapse</a> | ||
65 | 59 | <a href="#defaultall" class="defaultall_link" | ||
66 | 60 | id="default_milestone_0">Default</a> | ||
67 | 61 | </div> | ||
68 | 62 | </th> | ||
69 | 63 | </tr> | ||
70 | 64 | </thead> | ||
71 | 65 | |||
72 | 66 | <tbody> | ||
73 | 67 | <tr class="expandable"> | ||
74 | 68 | <td> | ||
75 | 69 | <a href="#" class="expander">.</a> | ||
76 | 70 | </td> | ||
77 | 71 | </tr> | ||
78 | 72 | </tbody> | ||
79 | 73 | |||
80 | 74 | <tbody class="collapsible-body default-collapsed"> | ||
81 | 75 | <tr class="padded"> | ||
82 | 76 | <td> | ||
83 | 77 | Content. | ||
84 | 78 | </td> | ||
85 | 79 | </tr> | ||
86 | 80 | </tbody> | ||
87 | 81 | |||
88 | 82 | <tbody> | ||
89 | 83 | <tr class="expandable"> | ||
90 | 84 | <td> | ||
91 | 85 | <a href="#" class="expander">.</a> | ||
92 | 86 | </td> | ||
93 | 87 | </tr> | ||
94 | 88 | </tbody> | ||
95 | 89 | |||
96 | 90 | <tbody class="collapsible-body default-expanded"> | ||
97 | 91 | <tr class="padded"> | ||
98 | 92 | <td> | ||
99 | 93 | Content. | ||
100 | 94 | </td> | ||
101 | 95 | </tr> | ||
102 | 96 | </tbody> | ||
103 | 97 | |||
104 | 98 | </table> | ||
105 | 99 | </div> | ||
106 | 100 | </script> | ||
107 | 101 | |||
108 | 102 | <script type="text/x-template" id="work-items-test-default-collapsed"> | ||
109 | 103 | <div class="workitems-group" id="milestone_1"> | ||
110 | 104 | <table class="listing"> | ||
111 | 105 | <thead> | ||
112 | 106 | <tr> | ||
113 | 107 | <th> | ||
114 | 108 | <div style="float: left; font-weight: normal;">All: | ||
115 | 109 | <a href="#expandall" class="expandall_link" | ||
116 | 110 | id="expand_milestone_1">Expand</a> | ||
117 | 111 | <a href="#collapseall" class="collapseall_link" | ||
118 | 112 | id="collapse_milestone_1">Collapse</a> | ||
119 | 113 | <a href="#defaultall" class="defaultall_link" | ||
120 | 114 | id="default_milestone_1">Default</a> | ||
121 | 115 | </div> | ||
122 | 116 | </th> | ||
123 | 117 | </tr> | ||
124 | 118 | </thead> | ||
125 | 119 | |||
126 | 120 | <tbody> | ||
127 | 121 | <tr class="expandable"> | ||
128 | 122 | <td> | ||
129 | 123 | <a href="#" class="expander">.</a> | ||
130 | 124 | </td> | ||
131 | 125 | </tr> | ||
132 | 126 | </tbody> | ||
133 | 127 | |||
134 | 128 | <tbody class="collapsible-body default-collapsed"> | ||
135 | 129 | <tr class="padded"> | ||
136 | 130 | <td> | ||
137 | 131 | Content. | ||
138 | 132 | </td> | ||
139 | 133 | </tr> | ||
140 | 134 | </tbody> | ||
141 | 135 | |||
142 | 136 | <tbody> | ||
143 | 137 | <tr class="expandable"> | ||
144 | 138 | <td> | ||
145 | 139 | <a href="#" class="expander">.</a> | ||
146 | 140 | </td> | ||
147 | 141 | </tr> | ||
148 | 142 | </tbody> | ||
149 | 143 | |||
150 | 144 | <tbody class="collapsible-body default-collapsed"> | ||
151 | 145 | <tr class="padded"> | ||
152 | 146 | <td> | ||
153 | 147 | Content. | ||
154 | 148 | </td> | ||
155 | 149 | </tr> | ||
156 | 150 | </tbody> | ||
157 | 151 | |||
158 | 152 | </table> | ||
159 | 153 | </div> | ||
160 | 154 | </script> | ||
161 | 155 | |||
162 | 156 | <script type="text/x-template" id="work-items-test-default-expanded"> | ||
163 | 157 | <div class="workitems-group" id="milestone_2"> | ||
164 | 158 | <table class="listing"> | ||
165 | 159 | <thead> | ||
166 | 160 | <tr> | ||
167 | 161 | <th> | ||
168 | 162 | <div style="float: left; font-weight: normal;">All: | ||
169 | 163 | <a href="#expandall" class="expandall_link" | ||
170 | 164 | id="expand_milestone_2">Expand</a> | ||
171 | 165 | <a href="#collapseall" class="collapseall_link" | ||
172 | 166 | id="collapse_milestone_2">Collapse</a> | ||
173 | 167 | <a href="#defaultall" class="defaultall_link" | ||
174 | 168 | id="default_milestone_2">Default</a> | ||
175 | 169 | </div> | ||
176 | 170 | </th> | ||
177 | 171 | </tr> | ||
178 | 172 | </thead> | ||
179 | 173 | |||
180 | 174 | <tbody> | ||
181 | 175 | <tr class="expandable"> | ||
182 | 176 | <td> | ||
183 | 177 | <a href="#" class="expander">.</a> | ||
184 | 178 | </td> | ||
185 | 179 | </tr> | ||
186 | 180 | </tbody> | ||
187 | 181 | |||
188 | 182 | <tbody class="collapsible-body default-expanded"> | ||
189 | 183 | <tr class="padded"> | ||
190 | 184 | <td> | ||
191 | 185 | Content. | ||
192 | 186 | </td> | ||
193 | 187 | </tr> | ||
194 | 188 | </tbody> | ||
195 | 189 | |||
196 | 190 | <tbody> | ||
197 | 191 | <tr class="expandable"> | ||
198 | 192 | <td> | ||
199 | 193 | <a href="#" class="expander">.</a> | ||
200 | 194 | </td> | ||
201 | 195 | </tr> | ||
202 | 196 | </tbody> | ||
203 | 197 | |||
204 | 198 | <tbody class="collapsible-body default-expanded"> | ||
205 | 199 | <tr class="padded"> | ||
206 | 200 | <td> | ||
207 | 201 | Content. | ||
208 | 202 | </td> | ||
209 | 203 | </tr> | ||
210 | 204 | </tbody> | ||
211 | 205 | |||
212 | 206 | </table> | ||
213 | 207 | </div> | ||
214 | 208 | </script> | ||
215 | 209 | </div> | ||
216 | 210 | </body> | ||
217 | 211 | </html> | ||
218 | 0 | 212 | ||
219 | === added file 'lib/lp/blueprints/javascript/tests/test_workitems.js' | |||
220 | --- lib/lp/blueprints/javascript/tests/test_workitems.js 1970-01-01 00:00:00 +0000 | |||
221 | +++ lib/lp/blueprints/javascript/tests/test_workitems.js 2012-06-13 15:31:25 +0000 | |||
222 | @@ -0,0 +1,153 @@ | |||
223 | 1 | YUI().use('lp.testing.runner', 'test', 'console', 'node', 'lazr.picker', | ||
224 | 2 | 'lp.workitems.expanders', | ||
225 | 3 | 'event', 'node-event-simulate', 'dump', function(Y) { | ||
226 | 4 | |||
227 | 5 | var suite = new Y.Test.Suite("lp.workitems.expanders Tests"); | ||
228 | 6 | var module = Y.lp.workitems.expanders; | ||
229 | 7 | |||
230 | 8 | suite.add(new Y.Test.Case({ | ||
231 | 9 | name: 'setUpWorkItemExpanders test', | ||
232 | 10 | |||
233 | 11 | setUp: function() { | ||
234 | 12 | this.fixture = Y.one("#fixture"); | ||
235 | 13 | module.test__ping_called = false; | ||
236 | 14 | }, | ||
237 | 15 | |||
238 | 16 | tearDown: function () { | ||
239 | 17 | if (this.fixture !== null) { | ||
240 | 18 | this.fixture.empty(); | ||
241 | 19 | } | ||
242 | 20 | delete this.fixture; | ||
243 | 21 | delete module.test__ping_called; | ||
244 | 22 | }, | ||
245 | 23 | |||
246 | 24 | _setup_fixture: function(template_selector) { | ||
247 | 25 | var template = Y.one(template_selector).getContent(); | ||
248 | 26 | var test_node = Y.Node.create(template); | ||
249 | 27 | this.fixture.append(test_node); | ||
250 | 28 | }, | ||
251 | 29 | |||
252 | 30 | _all_expanders_are_closed: function(){ | ||
253 | 31 | var found_open = false; | ||
254 | 32 | Y.all('.collapsible-body').each(function(e) { | ||
255 | 33 | found_collapsible_body = true; | ||
256 | 34 | if (!e.hasClass('unseen')) | ||
257 | 35 | { | ||
258 | 36 | found_open = true; | ||
259 | 37 | return; | ||
260 | 38 | } | ||
261 | 39 | }); | ||
262 | 40 | return found_open === false; | ||
263 | 41 | }, | ||
264 | 42 | |||
265 | 43 | _all_expanders_are_open: function(){ | ||
266 | 44 | var found_closed = false; | ||
267 | 45 | Y.all('.collapsible-body').each(function(e) { | ||
268 | 46 | found_collapsible_body = true; | ||
269 | 47 | if (e.hasClass('unseen')) | ||
270 | 48 | { | ||
271 | 49 | found_closed = true; | ||
272 | 50 | return; | ||
273 | 51 | } | ||
274 | 52 | }); | ||
275 | 53 | return found_closed === false; | ||
276 | 54 | }, | ||
277 | 55 | |||
278 | 56 | test_setUpWorkItemExpanders: function() { | ||
279 | 57 | this._setup_fixture('#work-items-test-0'); | ||
280 | 58 | |||
281 | 59 | Y.all('.collapsible-body').each(function(e) { | ||
282 | 60 | Y.Assert.isFalse(e.hasClass('lazr-closed')); | ||
283 | 61 | }); | ||
284 | 62 | |||
285 | 63 | Y.all('[class=expandable]').each(function(e) { | ||
286 | 64 | module._add_expanders(e); | ||
287 | 65 | }); | ||
288 | 66 | |||
289 | 67 | Y.all('.collapsible-body').each(function(e) { | ||
290 | 68 | // For some reason lazr-closed is attached when expander bodies are | ||
291 | 69 | // in their default state. Once clicked open they get lazr-open | ||
292 | 70 | // and clicked closed they get the classes lazr-closed and unseen. | ||
293 | 71 | // This assert is more encapsulating in case this changes. | ||
294 | 72 | Y.Assert.isTrue(e.hasClass('lazr-closed') || | ||
295 | 73 | e.hasClass('lazr-open')); | ||
296 | 74 | }); | ||
297 | 75 | }, | ||
298 | 76 | |||
299 | 77 | attach_ping_catcher: function(event){ | ||
300 | 78 | module._attach_handler(event, function(){ | ||
301 | 79 | module.test__ping_called = true; | ||
302 | 80 | }); | ||
303 | 81 | }, | ||
304 | 82 | |||
305 | 83 | test_attach_handler: function() { | ||
306 | 84 | // Test that _attach_handler attaches a function as expected. This | ||
307 | 85 | // covers expand, collapse and default functions. | ||
308 | 86 | this._setup_fixture('#work-items-test-0'); | ||
309 | 87 | |||
310 | 88 | // Call the expander attach handler function | ||
311 | 89 | Y.all('.expandall_link').on("click", this.attach_ping_catcher); | ||
312 | 90 | |||
313 | 91 | // Check that it attached correctly | ||
314 | 92 | Y.one('.expandall_link').simulate('click'); | ||
315 | 93 | Y.Assert.isTrue(module.test__ping_called); | ||
316 | 94 | }, | ||
317 | 95 | |||
318 | 96 | test_default_closed: function() { | ||
319 | 97 | // Test that clicking the default link restores expanders to their | ||
320 | 98 | // initial state. | ||
321 | 99 | |||
322 | 100 | this._setup_fixture('#work-items-test-default-collapsed'); | ||
323 | 101 | module.setUpWorkItemExpanders({ no_animation: true }); | ||
324 | 102 | |||
325 | 103 | // The test document should have all expanders collapsed. Check this. | ||
326 | 104 | Y.Assert.isTrue(this._all_expanders_are_closed()); | ||
327 | 105 | |||
328 | 106 | // Expand everything | ||
329 | 107 | Y.one('.expandall_link').simulate('click'); | ||
330 | 108 | Y.Assert.isTrue(this._all_expanders_are_open()); | ||
331 | 109 | |||
332 | 110 | // Return to default (collapsed) | ||
333 | 111 | Y.one('.defaultall_link').simulate('click'); | ||
334 | 112 | Y.Assert.isTrue(this._all_expanders_are_closed()); | ||
335 | 113 | |||
336 | 114 | // Collapse everything (should be no change) | ||
337 | 115 | Y.one('.collapseall_link').simulate('click'); | ||
338 | 116 | Y.Assert.isTrue(this._all_expanders_are_closed()); | ||
339 | 117 | |||
340 | 118 | // Check default link leaves everything closed | ||
341 | 119 | Y.one('.defaultall_link').simulate('click'); | ||
342 | 120 | Y.Assert.isTrue(this._all_expanders_are_closed()); | ||
343 | 121 | }, | ||
344 | 122 | |||
345 | 123 | test_default_open: function() { | ||
346 | 124 | // Test that clicking the default link restores expanders to their | ||
347 | 125 | // initial state. | ||
348 | 126 | |||
349 | 127 | this._setup_fixture('#work-items-test-default-expanded'); | ||
350 | 128 | module.setUpWorkItemExpanders({ no_animation: true }); | ||
351 | 129 | |||
352 | 130 | // The test document should have all expanders collapsed. Check this. | ||
353 | 131 | Y.Assert.isTrue(this._all_expanders_are_closed()); | ||
354 | 132 | |||
355 | 133 | // Expand everything | ||
356 | 134 | Y.one('.expandall_link').simulate('click'); | ||
357 | 135 | Y.Assert.isTrue(this._all_expanders_are_open()); | ||
358 | 136 | |||
359 | 137 | // Set to default (should be no change) | ||
360 | 138 | Y.one('.defaultall_link').simulate('click'); | ||
361 | 139 | Y.Assert.isTrue(this._all_expanders_are_open()); | ||
362 | 140 | |||
363 | 141 | // Collapse everything | ||
364 | 142 | Y.one('.collapseall_link').simulate('click'); | ||
365 | 143 | Y.Assert.isTrue(this._all_expanders_are_closed()); | ||
366 | 144 | |||
367 | 145 | // Check default link opens everything back up | ||
368 | 146 | Y.one('.defaultall_link').simulate('click'); | ||
369 | 147 | Y.Assert.isTrue(this._all_expanders_are_open()); | ||
370 | 148 | } | ||
371 | 149 | })); | ||
372 | 150 | |||
373 | 151 | Y.lp.testing.Runner.run(suite); | ||
374 | 152 | |||
375 | 153 | }); | ||
376 | 0 | 154 | ||
377 | === added file 'lib/lp/blueprints/javascript/workitems.js' | |||
378 | --- lib/lp/blueprints/javascript/workitems.js 1970-01-01 00:00:00 +0000 | |||
379 | +++ lib/lp/blueprints/javascript/workitems.js 2012-06-13 15:31:25 +0000 | |||
380 | @@ -0,0 +1,94 @@ | |||
381 | 1 | /* Copyright 2012 Canonical Ltd. This software is licensed under the | ||
382 | 2 | * GNU Affero General Public License version 3 (see the file LICENSE). | ||
383 | 3 | * | ||
384 | 4 | * Setup for managing subscribers list for bugs. | ||
385 | 5 | * | ||
386 | 6 | * @module workitems | ||
387 | 7 | * @submodule expanders | ||
388 | 8 | */ | ||
389 | 9 | |||
390 | 10 | YUI.add('lp.workitems.expanders', function(Y) { | ||
391 | 11 | |||
392 | 12 | var namespace = Y.namespace('lp.workitems.expanders'); | ||
393 | 13 | |||
394 | 14 | /** | ||
395 | 15 | * Record of all expanders and their default state. | ||
396 | 16 | */ | ||
397 | 17 | var expanders = []; | ||
398 | 18 | |||
399 | 19 | function expander_expand(expander, i){ | ||
400 | 20 | expander[0].render(true, false); | ||
401 | 21 | } | ||
402 | 22 | namespace._expander_expand = expander_expand; | ||
403 | 23 | |||
404 | 24 | function expander_collapse(expander, i){ | ||
405 | 25 | expander[0].render(false, false); | ||
406 | 26 | } | ||
407 | 27 | namespace._expander_collapse = expander_collapse; | ||
408 | 28 | |||
409 | 29 | function expander_restore_default_state(expander, i){ | ||
410 | 30 | expander[0].render(expander[1], false); | ||
411 | 31 | } | ||
412 | 32 | namespace._expander_restore_default_state = expander_restore_default_state; | ||
413 | 33 | |||
414 | 34 | /** | ||
415 | 35 | * Attach an expander to each expandable in the page. | ||
416 | 36 | */ | ||
417 | 37 | function setUpWorkItemExpanders(expander_config){ | ||
418 | 38 | Y.all('[class=expandable]').each(function(e) { | ||
419 | 39 | add_expanders(e, expander_config); | ||
420 | 40 | }); | ||
421 | 41 | |||
422 | 42 | Y.all('.expandall_link').on("click", function(event){ | ||
423 | 43 | attach_handler(event, expander_expand); | ||
424 | 44 | }); | ||
425 | 45 | |||
426 | 46 | Y.all('.collapseall_link').on("click", function(event){ | ||
427 | 47 | attach_handler(event, expander_collapse); | ||
428 | 48 | }); | ||
429 | 49 | |||
430 | 50 | Y.all('.defaultall_link').on("click", function(event){ | ||
431 | 51 | attach_handler(event, expander_restore_default_state); | ||
432 | 52 | }); | ||
433 | 53 | } | ||
434 | 54 | namespace.setUpWorkItemExpanders = setUpWorkItemExpanders; | ||
435 | 55 | |||
436 | 56 | function add_expanders(e, expander_config){ | ||
437 | 57 | var expander_icon = e.one('[class=expander]'); | ||
438 | 58 | // Our parent's first sibling is the tbody we want to collapse. | ||
439 | 59 | var widget_body = e.ancestor().next(); | ||
440 | 60 | |||
441 | 61 | if (Y.Lang.isUndefined(expander_config)) | ||
442 | 62 | { | ||
443 | 63 | expander_config = {}; | ||
444 | 64 | } | ||
445 | 65 | |||
446 | 66 | var expander = new Y.lp.app.widgets.expander.Expander(expander_icon, | ||
447 | 67 | widget_body, | ||
448 | 68 | expander_config); | ||
449 | 69 | expander.setUp(true); | ||
450 | 70 | |||
451 | 71 | var index = e.ancestor('[class=workitems-group]').get('id'); | ||
452 | 72 | |||
453 | 73 | // We record the expanders so we can reference them later | ||
454 | 74 | // First we have an array indexed by each milestone | ||
455 | 75 | if (!Y.Lang.isValue(expanders[index])){ | ||
456 | 76 | expanders[index] = []; | ||
457 | 77 | } | ||
458 | 78 | |||
459 | 79 | // For each milestone, store an array containing the expander | ||
460 | 80 | // object and the default state for it | ||
461 | 81 | default_expanded = widget_body.hasClass('default-expanded'); | ||
462 | 82 | expanders[index].push(new Array(expander, default_expanded)); | ||
463 | 83 | } | ||
464 | 84 | namespace._add_expanders = add_expanders; | ||
465 | 85 | |||
466 | 86 | function attach_handler(event, func){ | ||
467 | 87 | var index = event.currentTarget.get('id'); | ||
468 | 88 | index = index.match(/milestone_\d+/)[0]; | ||
469 | 89 | Y.Array.forEach(expanders[index], func); | ||
470 | 90 | } | ||
471 | 91 | namespace._attach_handler = attach_handler; | ||
472 | 92 | |||
473 | 93 | }, "0.1", {"requires": ["lp.app.widgets.expander"]}); | ||
474 | 94 | |||
475 | 0 | 95 | ||
476 | === modified file 'lib/lp/registry/templates/person-upcomingwork.pt' | |||
477 | --- lib/lp/registry/templates/person-upcomingwork.pt 2012-05-31 02:20:41 +0000 | |||
478 | +++ lib/lp/registry/templates/person-upcomingwork.pt 2012-06-13 15:31:25 +0000 | |||
479 | @@ -10,16 +10,9 @@ | |||
480 | 10 | <head> | 10 | <head> |
481 | 11 | <tal:block metal:fill-slot="head_epilogue"> | 11 | <tal:block metal:fill-slot="head_epilogue"> |
482 | 12 | <script type="text/javascript"> | 12 | <script type="text/javascript"> |
484 | 13 | LPJS.use('node', 'event', 'lp.app.widgets.expander', function(Y) { | 13 | LPJS.use('node', 'event', 'lp.app.widgets.expander', 'lp.workitems.expanders', function(Y) { |
485 | 14 | Y.on('domready', function() { | 14 | Y.on('domready', function() { |
494 | 15 | Y.all('[class=expandable]').each(function(e) { | 15 | Y.lp.workitems.expanders.setUpWorkItemExpanders(); |
487 | 16 | var expander_icon = e.one('[class=expander]'); | ||
488 | 17 | // Our parent's first sibling is the tbody we want to collapse. | ||
489 | 18 | var widget_body = e.ancestor().next(); | ||
490 | 19 | var expander = new Y.lp.app.widgets.expander.Expander( | ||
491 | 20 | expander_icon, widget_body); | ||
492 | 21 | expander.setUp(true); | ||
493 | 22 | }) | ||
495 | 23 | }) | 16 | }) |
496 | 24 | }); | 17 | }); |
497 | 25 | </script> | 18 | </script> |
498 | @@ -38,7 +31,8 @@ | |||
499 | 38 | 31 | ||
500 | 39 | <div metal:fill-slot="main"> | 32 | <div metal:fill-slot="main"> |
501 | 40 | 33 | ||
503 | 41 | <div tal:repeat="pair view/work_item_containers" class="workitems-group"> | 34 | <div tal:repeat="pair view/work_item_containers" class="workitems-group" |
504 | 35 | tal:attributes="id string:milestone_${repeat/pair/index}"> | ||
505 | 42 | <div tal:define="date python: pair[0]; containers python: pair[1]"> | 36 | <div tal:define="date python: pair[0]; containers python: pair[1]"> |
506 | 43 | <h2>Work items due in <span tal:replace="date/fmt:date" /></h2> | 37 | <h2>Work items due in <span tal:replace="date/fmt:date" /></h2> |
507 | 44 | 38 | ||
508 | @@ -78,7 +72,17 @@ | |||
509 | 78 | <table class="listing"> | 72 | <table class="listing"> |
510 | 79 | <thead> | 73 | <thead> |
511 | 80 | <tr> | 74 | <tr> |
513 | 81 | <th>Blueprint</th> | 75 | <th> |
514 | 76 | <div style="float: right; font-weight: normal;">All: | ||
515 | 77 | <a href="#expandall" class="expandall_link" | ||
516 | 78 | tal:attributes="id string:expand_milestone_${repeat/pair/index}">Expand</a> | ||
517 | 79 | <a href="#collapseall" class="collapseall_link" | ||
518 | 80 | tal:attributes="id string:collapse_milestone_${repeat/pair/index}">Collapse</a> | ||
519 | 81 | <a href="#defaultall" class="defaultall_link" | ||
520 | 82 | tal:attributes="id string:default_milestone_${repeat/pair/index}">Default</a> | ||
521 | 83 | </div> | ||
522 | 84 | Blueprint | ||
523 | 85 | </th> | ||
524 | 82 | <th>Target</th> | 86 | <th>Target</th> |
525 | 83 | <th>Assignee</th> | 87 | <th>Assignee</th> |
526 | 84 | <th>Priority</th> | 88 | <th>Priority</th> |
527 | @@ -111,13 +115,15 @@ | |||
528 | 111 | 115 | ||
529 | 112 | <tal:conditional condition="container/has_incomplete_work"> | 116 | <tal:conditional condition="container/has_incomplete_work"> |
530 | 113 | <tal:block define="global upcoming_work_class_name string:expanded"/> | 117 | <tal:block define="global upcoming_work_class_name string:expanded"/> |
531 | 118 | <tal:block define="global expander_init_state string:default-expanded"/> | ||
532 | 114 | </tal:conditional> | 119 | </tal:conditional> |
533 | 115 | 120 | ||
534 | 116 | <tal:conditional condition="not: container/has_incomplete_work"> | 121 | <tal:conditional condition="not: container/has_incomplete_work"> |
535 | 117 | <tal:block define="global upcoming_work_class_name string:"/> | 122 | <tal:block define="global upcoming_work_class_name string:"/> |
536 | 123 | <tal:block define="global expander_init_state string:default-collapsed"/> | ||
537 | 118 | </tal:conditional> | 124 | </tal:conditional> |
538 | 119 | 125 | ||
540 | 120 | <tbody tal:attributes="class string:collapsible-body ${upcoming_work_class_name}"> | 126 | <tbody tal:attributes="class string:collapsible-body ${upcoming_work_class_name} ${expander_init_state}"> |
541 | 121 | <tr tal:repeat="workitem container/items" class="padded"> | 127 | <tr tal:repeat="workitem container/items" class="padded"> |
542 | 122 | <td> | 128 | <td> |
543 | 123 | <span tal:condition="not: container/spec|nothing" | 129 | <span tal:condition="not: container/spec|nothing" |
This JavaScript belongs in a module and requires a YUI test to verify it works. The lint report of the module will catch errors that commonly break older browsers as well as pointing out style issue. JavaScript uses 4-space identation
Avoid
var things = new Array();
Use
var things = [];
The floated div must be before the text "Blueprint" to display consistently across browsers. There is leading white-space.
I think this template is creating non-unique ids. This breaks many browsers. A proper test would catch this.