Merge lp:~rharding/juju-gui/help-dropdown into lp:juju-gui/experimental
- help-dropdown
- Merge into trunk
Proposed by
Richard Harding
Status: | Merged |
---|---|
Merged at revision: | 1198 |
Proposed branch: | lp:~rharding/juju-gui/help-dropdown |
Merge into: | lp:juju-gui/experimental |
Diff against target: |
1292 lines (+673/-259) 23 files modified
app/app.js (+22/-1) app/assets/javascripts/view-dropdown-extension.js (+92/-0) app/index.html (+4/-10) app/modules-debug.js (+9/-0) app/subapps/browser/browser.js (+13/-5) app/templates/help-dropdown.handlebars (+29/-0) app/templates/notifications.handlebars (+28/-24) app/templates/onboarding.handlebars (+1/-1) app/templates/overview.handlebars (+0/-4) app/views/help-dropdown.js (+113/-0) app/views/notifications.js (+15/-62) app/views/onboarding.js (+13/-0) bin/merge-files (+1/-0) lib/views/browser/onboarding.less (+5/-0) lib/views/dropdown.less (+110/-54) lib/views/stylesheet.less (+6/-69) test/index.html (+2/-0) test/test_browser_app.js (+17/-0) test/test_dropdown_extension.js (+80/-0) test/test_help_dropdown.js (+97/-0) test/test_notifications.js (+1/-28) test/test_onboarding.js (+15/-0) undocumented (+0/-1) |
To merge this branch: | bzr merge lp:~rharding/juju-gui/help-dropdown |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju GUI Hackers | Pending | ||
Review via email: mp+195116@code.launchpad.net |
Commit message
Description of the change
A dropdown view extension.
This is a refactoring of Huw's branch which created a dropdown widget
and a "Help & Feedback" dropdown on the header bar.
original: https:/
original original: https:/
To post a comment you must log in.
Revision history for this message
Richard Harding (rharding) wrote : | # |
Revision history for this message
Richard Harding (rharding) wrote : | # |
Revision history for this message
Richard Harding (rharding) wrote : | # |
*** Submitted:
A dropdown view extension.
This is a refactoring of Huw's branch which created a dropdown widget
and a "Help & Feedback" dropdown on the header bar.
original: https:/
original original: https:/
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'app/app.js' |
2 | --- app/app.js 2013-11-07 21:10:06 +0000 |
3 | +++ app/app.js 2013-11-13 18:41:54 +0000 |
4 | @@ -126,7 +126,6 @@ |
5 | type: 'juju.views.NotificationsView', |
6 | preserve: true |
7 | } |
8 | - |
9 | }, |
10 | |
11 | /* |
12 | @@ -534,6 +533,7 @@ |
13 | } else { |
14 | this.dispatch(); |
15 | } |
16 | + this._renderHelpDropdownView(); |
17 | }, this); |
18 | |
19 | // Halt the default navigation on the juju logo to allow us to show |
20 | @@ -613,6 +613,23 @@ |
21 | }, |
22 | |
23 | /** |
24 | + * Handles rendering the help dropdown view on application load. |
25 | + * |
26 | + * @method _renderHelpDropdownView |
27 | + */ |
28 | + _renderHelpDropdownView: function() { |
29 | + this.helpDropdown = new views.HelpDropdownView({ |
30 | + container: Y.one('#help-dropdown'), |
31 | + env: this.db.environment |
32 | + }).render(); |
33 | + // pass in onboarding when we no longer need to support |
34 | + // fullscreen mode and interact with it directly |
35 | + this.helpDropdown.on('navigate', function(e) { |
36 | + this.navigate(e.url); |
37 | + }, this); |
38 | + }, |
39 | + |
40 | + /** |
41 | Calls the deployer import method with the bundle data |
42 | to deploy the bundle to the environment. |
43 | |
44 | @@ -674,6 +691,9 @@ |
45 | @method destructor |
46 | */ |
47 | destructor: function() { |
48 | + if (this.helpDropdown) { |
49 | + this.helpDropdown.destroy(); |
50 | + } |
51 | if (this._keybindings) { |
52 | this._keybindings.detach(); |
53 | } |
54 | @@ -1344,6 +1364,7 @@ |
55 | 'juju-ghost-inspector', |
56 | 'juju-view-bundle', |
57 | 'viewmode-controls', |
58 | + 'help-dropdown', |
59 | 'bundle-import-extension' |
60 | ] |
61 | }); |
62 | |
63 | === added file 'app/assets/javascripts/view-dropdown-extension.js' |
64 | --- app/assets/javascripts/view-dropdown-extension.js 1970-01-01 00:00:00 +0000 |
65 | +++ app/assets/javascripts/view-dropdown-extension.js 2013-11-13 18:41:54 +0000 |
66 | @@ -0,0 +1,92 @@ |
67 | +/* |
68 | +This file is part of the Juju GUI, which lets users view and manage Juju |
69 | +environments within a graphical interface (https://launchpad.net/juju-gui). |
70 | +Copyright (C) 2012-2013 Canonical Ltd. |
71 | + |
72 | +This program is free software: you can redistribute it and/or modify it under |
73 | +the terms of the GNU Affero General Public License version 3, as published by |
74 | +the Free Software Foundation. |
75 | + |
76 | +This program is distributed in the hope that it will be useful, but WITHOUT |
77 | +ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
78 | +SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero |
79 | +General Public License for more details. |
80 | + |
81 | +You should have received a copy of the GNU Affero General Public License along |
82 | +with this program. If not, see <http://www.gnu.org/licenses/>. |
83 | +*/ |
84 | + |
85 | +'use strict'; |
86 | + |
87 | + |
88 | +YUI.add('view-dropdown-extension', function(Y) { |
89 | + |
90 | + /** |
91 | + * Extension for a Y.View derrived class. Adds the dropdown |
92 | + * functionality to the view. You need to call the _addDropdownFunc |
93 | + * from the render method of the view to trigger because |
94 | + * Y.View's do not offer any render event. |
95 | + * |
96 | + * @namespace juju |
97 | + * @class Dropdown |
98 | + */ |
99 | + function Dropdown() {} |
100 | + |
101 | + Dropdown.prototype = { |
102 | + /** |
103 | + * Toggle the visibility of the dropdown panel. |
104 | + * |
105 | + * @method _toggleDropdown |
106 | + * @param {Event} ev the click event from the control. |
107 | + */ |
108 | + __toggleDropdown: function(ev) { |
109 | + ev.halt(); |
110 | + this.get('container').toggleClass('open'); |
111 | + }, |
112 | + |
113 | + /** |
114 | + * Hide the dropdown panel. |
115 | + * |
116 | + * @method close |
117 | + */ |
118 | + __close: function() { |
119 | + this.get('container').removeClass('open'); |
120 | + }, |
121 | + |
122 | + /** |
123 | + * Sets up events and binds them to listeners. |
124 | + * |
125 | + * @method __bindUI |
126 | + * @param {Y.Node} container The views container element. |
127 | + */ |
128 | + __bindUI: function(container) { |
129 | + this.addEvent( |
130 | + container.one('.menu-link').on( |
131 | + 'click', this.__toggleDropdown, this)); |
132 | + this.addEvent( |
133 | + container.on( |
134 | + 'clickoutside', this.__close, this)); |
135 | + }, |
136 | + |
137 | + /** |
138 | + * Sets up the DOM nodes and renders them to the DOM. |
139 | + * |
140 | + * @method _addDropdownFunc |
141 | + */ |
142 | + _addDropdownFunc: function() { |
143 | + var container = this.get('container'); |
144 | + if (container) { |
145 | + container.addClass('dropdown-menu'); |
146 | + this.__bindUI(container); |
147 | + } |
148 | + } |
149 | + }; |
150 | + |
151 | + Y.namespace('juju').Dropdown = Dropdown; |
152 | + |
153 | +}, '0.1.0', { |
154 | + requires: [ |
155 | + 'event-tracker', |
156 | + 'view' |
157 | + ] |
158 | +}); |
159 | |
160 | === modified file 'app/index.html' |
161 | --- app/index.html 2013-11-07 16:50:47 +0000 |
162 | +++ app/index.html 2013-11-13 18:41:54 +0000 |
163 | @@ -147,19 +147,13 @@ |
164 | </a> |
165 | </li> |
166 | <li class="notifications-nav"> |
167 | - <div id="notifications"></div> |
168 | - <div class="notifier-box"></div> |
169 | + <span id="notifications"></span> |
170 | + <span class="notifier-box"></span> |
171 | </li> |
172 | </ul> |
173 | <ul class="right-nav"> |
174 | - <li class="help-dropdown"> |
175 | - <a href=""> |
176 | - Help & Feedback |
177 | - <span class="expand"> |
178 | - <i class="sprite chevron_down more"></i> |
179 | - <i class="sprite chevron_up less hidden"></i> |
180 | - </span> |
181 | - </a> |
182 | + <li> |
183 | + <span id="help-dropdown"></span> |
184 | </li> |
185 | <li> |
186 | <a href="" id="logout-trigger" class="button inverse">Logout</a> |
187 | |
188 | === modified file 'app/modules-debug.js' |
189 | --- app/modules-debug.js 2013-11-07 15:49:57 +0000 |
190 | +++ app/modules-debug.js 2013-11-13 18:41:54 +0000 |
191 | @@ -185,6 +185,10 @@ |
192 | fullpath: '/juju-ui/assets/javascripts/bundle-import-extension.js' |
193 | }, |
194 | |
195 | + 'view-dropdown-extension': { |
196 | + fullpath: '/juju-ui/assets/javascripts/view-dropdown-extension.js' |
197 | + }, |
198 | + |
199 | 'sub-app': { |
200 | fullpath: '/juju-ui/assets/javascripts/sub-app.js' |
201 | }, |
202 | @@ -233,6 +237,10 @@ |
203 | fullpath: '/juju-ui/views/notifications.js' |
204 | }, |
205 | |
206 | + 'juju-help-dropdown': { |
207 | + fullpath: '/juju-ui/views/help-dropdown.js' |
208 | + }, |
209 | + |
210 | 'juju-view-environment': { |
211 | fullpath: '/juju-ui/views/environment.js' |
212 | }, |
213 | @@ -267,6 +275,7 @@ |
214 | 'd3-components', |
215 | 'juju-templates', |
216 | 'juju-notifications', |
217 | + 'juju-help-dropdown', |
218 | 'juju-view-utils', |
219 | 'juju-topology', |
220 | 'juju-view-environment', |
221 | |
222 | === modified file 'app/subapps/browser/browser.js' |
223 | --- app/subapps/browser/browser.js 2013-11-05 18:10:05 +0000 |
224 | +++ app/subapps/browser/browser.js 2013-11-13 18:41:54 +0000 |
225 | @@ -626,13 +626,18 @@ |
226 | * Create a 'welcome' message walkthrough for new users. |
227 | * |
228 | * @method renderOnboarding |
229 | + * @param {Boolean} force Whether it should force render the onboarding. |
230 | */ |
231 | - renderOnboarding: function() { |
232 | + renderOnboarding: function(force) { |
233 | // Need to check onboarding exists due to the double dispatch bug. |
234 | this._onboarding = new Y.juju.views.OnboardingView({ |
235 | 'container': '#onboarding' |
236 | }); |
237 | |
238 | + if (force) { |
239 | + this._onboarding.reset(); |
240 | + } |
241 | + |
242 | if (!this._onboarding.get('seen')) { |
243 | this._onboarding.render(); |
244 | } |
245 | @@ -861,10 +866,13 @@ |
246 | // Only show the onboarding messaging if we're hitting the sidebar view |
247 | // without any extra url bits to the user. It's meant for a fresh user |
248 | // to see, not someone doing what they know they want to do. |
249 | - if (!this._onboarding) { |
250 | - if (!this._viewState.search && |
251 | - !this._viewState.charmID) { |
252 | - this.renderOnboarding(); |
253 | + var force = localStorage.getItem('force-onboarding'); |
254 | + // Reset force-onboarding so that the next request to /sidebar acts normal |
255 | + localStorage.setItem('force-onboarding', ''); |
256 | + |
257 | + if (!this._onboarding || force) { |
258 | + if (!this._viewState.search && !this._viewState.charmID) { |
259 | + this.renderOnboarding(force); |
260 | } |
261 | } |
262 | |
263 | |
264 | === added file 'app/templates/help-dropdown.handlebars' |
265 | --- app/templates/help-dropdown.handlebars 1970-01-01 00:00:00 +0000 |
266 | +++ app/templates/help-dropdown.handlebars 2013-11-13 18:41:54 +0000 |
267 | @@ -0,0 +1,29 @@ |
268 | +<a href="" class="menu-link"> |
269 | + Help & feedback |
270 | + <span class="expand"> |
271 | + <i class="sprite chevron_down more"></i> |
272 | + <i class="sprite chevron_up less"></i> |
273 | + </span> |
274 | +</a> |
275 | +<span class="dropdown right narrow"> |
276 | + <ul> |
277 | + <li> |
278 | + <a href="" class="start-onboarding">Tutorial</a> |
279 | + </li> |
280 | + <li> |
281 | + <a href="http://juju.ubuntu.com/" |
282 | + target="_blank">Visit: juju.ubuntu.com</a> |
283 | + </li> |
284 | + <li> |
285 | + <a href="http://juju.ubuntu.com/docs" |
286 | + target="_blank">Read the documentation</a> |
287 | + </li> |
288 | + <li> |
289 | + <a href="https://www.surveymonkey.com/s/jujugui" |
290 | + target="_blank">Take the survey</a> |
291 | + </li> |
292 | + <li class="landscape-url hidden"> |
293 | + <a href="">Landscape</a> |
294 | + </li> |
295 | + </ul> |
296 | +</span> |
297 | |
298 | === modified file 'app/templates/notifications.handlebars' |
299 | --- app/templates/notifications.handlebars 2013-10-24 18:02:16 +0000 |
300 | +++ app/templates/notifications.handlebars 2013-11-13 18:41:54 +0000 |
301 | @@ -1,25 +1,29 @@ |
302 | -<span class="{{open}}"> |
303 | - <a href="" id="notify-indicator" data-target="notify-list"> |
304 | - {{count}} |
305 | - </a> |
306 | - <span id="notify-list" class="dropdown"> |
307 | - <h3> |
308 | - {{count}} notifications |
309 | - </h3> |
310 | - <ul> |
311 | - {{#notifications}} |
312 | - <li id="{{clientId}}" class="notice"> |
313 | - <div> |
314 | - <h4>{{title}}</h4> |
315 | - <div> |
316 | - {{message}} |
317 | - </div> |
318 | - <small data-timestamp="{{timestamp}}" |
319 | - class="timestamp">{{humanizeTime timestamp}}</small> |
320 | - </div> |
321 | - </li> |
322 | - {{/notifications}} |
323 | - </ul> |
324 | - </span> |
325 | - Notifications |
326 | +<a href="" class="menu-link"> |
327 | + <span id="notify-indicator">{{ count }}</span> |
328 | + Notifications |
329 | + <span class="expand"> |
330 | + <i class="sprite chevron_down more"></i> |
331 | + <i class="sprite chevron_up less"></i> |
332 | + </span> |
333 | +</a> |
334 | +<span class="dropdown"> |
335 | + <header> |
336 | + {{count}} notifications |
337 | + </header> |
338 | + {{#if notifications}} |
339 | + <ul> |
340 | + {{#notifications}} |
341 | + <li id="{{clientId}}" class="notice"> |
342 | + <h4>{{title}}</h4> |
343 | + {{message}} |
344 | + <small data-timestamp="{{timestamp}}"> |
345 | + {{humanizeTime timestamp}} |
346 | + </small> |
347 | + </li> |
348 | + {{/notifications}} |
349 | + </ul> |
350 | + {{else}} |
351 | + <p>No notifications</p> |
352 | + {{/if}} |
353 | + <footer></footer> |
354 | </span> |
355 | |
356 | === modified file 'app/templates/onboarding.handlebars' |
357 | --- app/templates/onboarding.handlebars 2013-10-23 18:09:52 +0000 |
358 | +++ app/templates/onboarding.handlebars 2013-11-13 18:41:54 +0000 |
359 | @@ -5,7 +5,7 @@ |
360 | </div> |
361 | <div id="onboarding-screen-mask"></div> |
362 | <div id="onboarding-message"> |
363 | - <a class="onboarding-cross sprite close-inspector-normal" href="" ></a> |
364 | + <button class="onboarding-cross sprite close-inspector-normal" href="" ></button> |
365 | <div class="panel panel-0"> |
366 | <h3 class="header type3">Welcome to Juju</h3> |
367 | <p class="text type11">Use Juju to quickly create, configure and deploy your application architectures to public clouds like EC2, Azure and HP, any OpenStack cloud and even your own Ubuntu based laptop with Charms.</p> |
368 | |
369 | === modified file 'app/templates/overview.handlebars' |
370 | --- app/templates/overview.handlebars 2013-10-18 16:47:34 +0000 |
371 | +++ app/templates/overview.handlebars 2013-11-13 18:41:54 +0000 |
372 | @@ -22,10 +22,6 @@ |
373 | <div class="menu-title">Select relation type:</div> |
374 | <ul/> |
375 | </div> |
376 | - <div id="feedback-box"> |
377 | - <a target="_blank" |
378 | - href="https://www.surveymonkey.com/s/jujugui">Feedback</a> |
379 | - </div> |
380 | {{> right-sidebar }} |
381 | </div> |
382 | <div id="rmrelation-modal-panel"></div> |
383 | |
384 | === added file 'app/views/help-dropdown.js' |
385 | --- app/views/help-dropdown.js 1970-01-01 00:00:00 +0000 |
386 | +++ app/views/help-dropdown.js 2013-11-13 18:41:54 +0000 |
387 | @@ -0,0 +1,113 @@ |
388 | +/* |
389 | +This file is part of the Juju GUI, which lets users view and manage Juju |
390 | +environments within a graphical interface (https://launchpad.net/juju-gui). |
391 | +Copyright (C) 2012-2013 Canonical Ltd. |
392 | + |
393 | +This program is free software: you can redistribute it and/or modify it under |
394 | +the terms of the GNU Affero General Public License version 3, as published by |
395 | +the Free Software Foundation. |
396 | + |
397 | +This program is distributed in the hope that it will be useful, but WITHOUT |
398 | +ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
399 | +SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero |
400 | +General Public License for more details. |
401 | + |
402 | +You should have received a copy of the GNU Affero General Public License along |
403 | +with this program. If not, see <http://www.gnu.org/licenses/>. |
404 | +*/ |
405 | + |
406 | +'use strict'; |
407 | + |
408 | +/** |
409 | + * Provide the help dropdown view. |
410 | + * |
411 | + * @module views |
412 | + */ |
413 | + |
414 | +YUI.add('help-dropdown', function(Y) { |
415 | + |
416 | + var views = Y.namespace('juju.views'), |
417 | + widgets = Y.namespace('juju.widgets'), |
418 | + Templates = views.Templates; |
419 | + |
420 | + /** |
421 | + * The view associated with the help dropdown. |
422 | + * |
423 | + * @class HelpDropdownView |
424 | + */ |
425 | + var HelpDropdownView = Y.Base.create('HelpDropdownView', Y.View, |
426 | + [ |
427 | + Y.juju.Dropdown, |
428 | + Y.Event.EventTracker |
429 | + ], { |
430 | + template: Templates['help-dropdown'], |
431 | + |
432 | + events: { |
433 | + '.start-onboarding': { |
434 | + click: '_startOnboarding' |
435 | + } |
436 | + }, |
437 | + |
438 | + /** |
439 | + * Start the onboarding tutorial. |
440 | + * |
441 | + * @method _startOnboarding |
442 | + * @param {Event} ev the click event from the control. |
443 | + * @private |
444 | + */ |
445 | + _startOnboarding: function(ev) { |
446 | + ev.halt(); |
447 | + // Added by the view-dropdown-extension.js |
448 | + this.__close(); // Closes itself |
449 | + // Because we need the app to be in sidebar mode when |
450 | + // the user views the onboarding we navigate to it. |
451 | + // Once fullscreen is removed we can interact with |
452 | + // onboarding here instead of in browser.js |
453 | + localStorage.setItem('force-onboarding', true); |
454 | + this.fire('navigate', { url: '/sidebar' }); |
455 | + }, |
456 | + |
457 | + /** |
458 | + * Show the Landscape URL if available. |
459 | + * |
460 | + * @method _displayLandscapeURL |
461 | + * @private |
462 | + */ |
463 | + _displayLandscapeURL: function() { |
464 | + var env = this.get('env'), |
465 | + url = this.get('container').one('.landscape-url'), |
466 | + baseLandscapeURL = views.utils.getLandscapeURL(env); |
467 | + |
468 | + if (baseLandscapeURL) { |
469 | + url.one('a').setAttribute('href', baseLandscapeURL); |
470 | + url.removeClass('hidden'); |
471 | + } |
472 | + }, |
473 | + |
474 | + /** |
475 | + * Sets up the DOM nodes and renders them to the DOM. |
476 | + * |
477 | + * @method render |
478 | + */ |
479 | + render: function() { |
480 | + var container = this.get('container'); |
481 | + container.setHTML(this.template()); |
482 | + this._displayLandscapeURL(); |
483 | + // Added by the view-dropdown-extension.js |
484 | + this._addDropdownFunc(); |
485 | + return this; |
486 | + } |
487 | + }); |
488 | + |
489 | + views.HelpDropdownView = HelpDropdownView; |
490 | + |
491 | +}, '0.1.0', { |
492 | + requires: [ |
493 | + 'view', |
494 | + 'juju-view-utils', |
495 | + 'event-tracker', |
496 | + 'node', |
497 | + 'handlebars', |
498 | + 'view-dropdown-extension' |
499 | + ] |
500 | +}); |
501 | |
502 | === modified file 'app/views/notifications.js' |
503 | --- app/views/notifications.js 2013-11-07 21:10:06 +0000 |
504 | +++ app/views/notifications.js 2013-11-13 18:41:54 +0000 |
505 | @@ -90,38 +90,6 @@ |
506 | }, |
507 | |
508 | /** |
509 | - * Event handler for clicking the notification icon. |
510 | - * |
511 | - * @method notifyToggle |
512 | - */ |
513 | - notifyToggle: function(evt) { |
514 | - evt.halt(); |
515 | - var container = this.get('container'), |
516 | - notifications = this.get('notifications'), |
517 | - target = evt.target.getAttribute('data-target'), |
518 | - el = container.one('#' + target), |
519 | - parent = el.ancestor(); |
520 | - |
521 | - if (notifications.size() === 0) { |
522 | - return; |
523 | - } |
524 | - |
525 | - if (parent && parent.hasClass('open')) { |
526 | - el.hide(true); |
527 | - } |
528 | - else { |
529 | - el.show(true); |
530 | - } |
531 | - |
532 | - if (parent) { |
533 | - parent.toggleClass('open'); |
534 | - } |
535 | - |
536 | - el.toggleClass('active'); |
537 | - |
538 | - }, |
539 | - |
540 | - /** |
541 | * Select/click on a notice. Currently this just removes it from the |
542 | * model_list. |
543 | * |
544 | @@ -230,7 +198,11 @@ |
545 | * @class NotificationsView |
546 | */ |
547 | var NotificationsView = Y.Base.create('NotificationsView', |
548 | - NotificationsBaseView, [], { |
549 | + NotificationsBaseView, |
550 | + [ |
551 | + Y.Event.EventTracker, |
552 | + Y.juju.Dropdown |
553 | + ], { |
554 | template: Templates.notifications, |
555 | |
556 | /* |
557 | @@ -244,12 +216,6 @@ |
558 | seen: false |
559 | }, |
560 | |
561 | - events: { |
562 | - '#notify-indicator': { |
563 | - click: 'notifyToggle' |
564 | - } |
565 | - }, |
566 | - |
567 | /** |
568 | * @method getShowable |
569 | */ |
570 | @@ -262,30 +228,15 @@ |
571 | }); |
572 | }, |
573 | |
574 | - close: function() { |
575 | - var container = this.get('container'); |
576 | - if (!container) { |
577 | - return; |
578 | - } |
579 | - |
580 | - var indicator = container.one('#notify-indicator'), |
581 | - list = container.one('#notify-list'); |
582 | - |
583 | - if (!indicator) { |
584 | - return; |
585 | - } |
586 | - var parent = indicator.ancestor(); |
587 | - |
588 | - if (parent && parent.hasClass('open')) { |
589 | - indicator.ancestor().removeClass('open'); |
590 | - list.hide(); |
591 | - indicator.removeClass('active'); |
592 | - } |
593 | - }, |
594 | - |
595 | + /** |
596 | + Renders the notification view and the dropdown widget. |
597 | + |
598 | + @method render |
599 | + */ |
600 | render: function() { |
601 | NotificationsView.superclass.render.apply(this, arguments); |
602 | - this.get('container').on('clickoutside', this.close, this); |
603 | + // Added by the view-dropdown-extension.js |
604 | + this._addDropdownFunc(); |
605 | return this; |
606 | } |
607 | |
608 | @@ -298,6 +249,8 @@ |
609 | 'juju-view-utils', |
610 | 'node', |
611 | 'handlebars', |
612 | - 'notifier' |
613 | + 'notifier', |
614 | + 'view-dropdown-extension', |
615 | + 'event-tracker' |
616 | ] |
617 | }); |
618 | |
619 | === modified file 'app/views/onboarding.js' |
620 | --- app/views/onboarding.js 2013-10-21 23:05:08 +0000 |
621 | +++ app/views/onboarding.js 2013-11-13 18:41:54 +0000 |
622 | @@ -72,6 +72,7 @@ |
623 | var container = this.get('container'); |
624 | container.hide(); |
625 | Y.one('#environment-help').removeClass('hidden'); |
626 | + localStorage.setItem('force-onboarding', ''); |
627 | }, |
628 | |
629 | /** |
630 | @@ -182,6 +183,18 @@ |
631 | }, |
632 | |
633 | /** |
634 | + Sets the onboarding index back to 0, and the localstorage onboarding |
635 | + flag to undefined. |
636 | + |
637 | + @method reset |
638 | + */ |
639 | + reset: function() { |
640 | + this.onboardingIndex = 0; |
641 | + localStorage.setItem('onboarding', ''); |
642 | + this.get('container').empty(); |
643 | + }, |
644 | + |
645 | + /** |
646 | * Render the page. |
647 | * |
648 | * Reveal the mask element, and show the onboarding window. |
649 | |
650 | === modified file 'bin/merge-files' |
651 | --- bin/merge-files 2013-11-07 15:49:57 +0000 |
652 | +++ bin/merge-files 2013-11-13 18:41:54 +0000 |
653 | @@ -89,6 +89,7 @@ |
654 | 'app/assets/javascripts/app-subapp-extension.js', |
655 | 'app/assets/javascripts/app-cookies-extension.js', |
656 | 'app/assets/javascripts/bundle-import-extension.js', |
657 | + 'app/assets/javascripts/view-dropdown-extension.js', |
658 | 'app/assets/javascripts/d3-components.js', |
659 | 'app/assets/javascripts/d3.min.js', |
660 | 'app/assets/javascripts/d3.status.js', |
661 | |
662 | === modified file 'lib/views/browser/onboarding.less' |
663 | --- lib/views/browser/onboarding.less 2013-10-29 02:29:58 +0000 |
664 | +++ lib/views/browser/onboarding.less 2013-11-13 18:41:54 +0000 |
665 | @@ -58,6 +58,11 @@ |
666 | color: @inspector-text-color; |
667 | } |
668 | |
669 | + button { |
670 | + border: none; |
671 | + padding: 0; |
672 | + } |
673 | + |
674 | img { |
675 | position: absolute; |
676 | } |
677 | |
678 | === modified file 'lib/views/dropdown.less' |
679 | --- lib/views/dropdown.less 2013-10-29 03:07:12 +0000 |
680 | +++ lib/views/dropdown.less 2013-11-13 18:41:54 +0000 |
681 | @@ -1,62 +1,118 @@ |
682 | -.dropdown { |
683 | - .customize-scrollbar; |
684 | - display: none; |
685 | - position: absolute; |
686 | - z-index: 1000; |
687 | - top: @navbar-height; |
688 | - left: 0; |
689 | - width: 290px; |
690 | - background-color: #eee; |
691 | - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); |
692 | - |
693 | - &.active { |
694 | +.dropdown-menu { |
695 | + position: relative; |
696 | + display: block; |
697 | + margin: -20px -20px 0 -20px; |
698 | + |
699 | + &.open { |
700 | + .menu-link { |
701 | + background-color: #000; |
702 | + |
703 | + .expand { |
704 | + .more { |
705 | + display: none; |
706 | + } |
707 | + .less { |
708 | + display: inline-block; |
709 | + } |
710 | + } |
711 | + } |
712 | + .dropdown { |
713 | + display: block; |
714 | + } |
715 | + } |
716 | + .menu-link { |
717 | + .border-box; |
718 | display: block; |
719 | - } |
720 | - a, |
721 | - li { |
722 | - color: #333; |
723 | - } |
724 | - h3 { |
725 | - padding: 11px 20px; |
726 | - background-color: #000; |
727 | - color: #f2f2e6; |
728 | - font-size: 16px; |
729 | - font-weight: 300; |
730 | - } |
731 | - ul { |
732 | - max-height: 500px; |
733 | - overflow-y: auto; |
734 | - |
735 | + height: @navbar-height; |
736 | + padding: 20px 20px 0 20px; |
737 | + color: #d7d3d0; |
738 | + |
739 | + .expand { |
740 | + margin-left: 5px; |
741 | + |
742 | + .less { |
743 | + display: none; |
744 | + } |
745 | + } |
746 | + } |
747 | + .dropdown { |
748 | + .customize-scrollbar; |
749 | + display: none; |
750 | + position: absolute; |
751 | + z-index: 1000; |
752 | + top: @navbar-height; |
753 | + left: 0; |
754 | + width: 290px; |
755 | + background-color: #eee; |
756 | + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); |
757 | + |
758 | + &.right { |
759 | + left: auto; |
760 | + right: 0; |
761 | + text-align: right; |
762 | + } |
763 | + &.narrow { |
764 | + width: 230px; |
765 | + } |
766 | + a, |
767 | + p, |
768 | li { |
769 | - border-top: 1px solid #efefef; |
770 | - border-bottom: 1px solid #e2e2e2; |
771 | + color: @text-colour; |
772 | + } |
773 | + p { |
774 | + padding: 11px 20px; |
775 | + } |
776 | + header, |
777 | + footer { |
778 | + background-color: #000; |
779 | + } |
780 | + header { |
781 | + padding: 11px 20px; |
782 | + color: #f2f2e6; |
783 | + font-size: 16px; |
784 | + font-weight: 300; |
785 | + } |
786 | + footer { |
787 | padding: 20px; |
788 | - |
789 | - &:first-child { |
790 | - border-top: none; |
791 | - } |
792 | - &:last-child { |
793 | - border-bottom: none; |
794 | - } |
795 | + border-radius: 0 0 @border-radius @border-radius; |
796 | } |
797 | - // Notification items |
798 | - .notice { |
799 | - h4 { |
800 | - font-weight: normal; |
801 | - margin-bottom: 10px; |
802 | - } |
803 | - small { |
804 | - display: block; |
805 | - margin-top: 5px; |
806 | - font-size: 10px; |
807 | - color: #d0d0d0; |
808 | - } |
809 | - .error { |
810 | - background-color: rgba(255, 0, 0, 0.1); |
811 | + ul { |
812 | + max-height: 500px; |
813 | + overflow-y: auto; |
814 | + |
815 | + li { |
816 | + border-top: 1px solid #efefef; |
817 | + border-bottom: 1px solid #e2e2e2; |
818 | + |
819 | + &:first-child { |
820 | + border-top: none; |
821 | + } |
822 | + &:last-child { |
823 | + border-bottom: none; |
824 | + } |
825 | + a { |
826 | + display: block; |
827 | + padding: 15px 20px; |
828 | + |
829 | + &:hover { |
830 | + background-color: #e2e2e2; |
831 | + } |
832 | + } |
833 | + } |
834 | + // Notification items |
835 | + .notice { |
836 | + padding: 20px; |
837 | + |
838 | + h4 { |
839 | + margin-bottom: 10px; |
840 | + } |
841 | + small { |
842 | + display: block; |
843 | + margin-top: 5px; |
844 | + font-size: 11px; |
845 | + color: #aaa; |
846 | + } |
847 | } |
848 | } |
849 | } |
850 | } |
851 | -.open .dropdown { |
852 | - display: block; |
853 | -} |
854 | |
855 | === modified file 'lib/views/stylesheet.less' |
856 | --- lib/views/stylesheet.less 2013-11-07 15:49:57 +0000 |
857 | +++ lib/views/stylesheet.less 2013-11-13 18:41:54 +0000 |
858 | @@ -175,16 +175,13 @@ |
859 | */ |
860 | .navbar { |
861 | min-width: 800px; |
862 | - // Need to subtract the bottom-border-height. |
863 | height: @navbar-height; |
864 | margin: -@navbar-height 0 0 0; |
865 | background-color: #221e1b; |
866 | |
867 | &, |
868 | - a { |
869 | + & > ul > li > a { |
870 | color: #d7d3d0; |
871 | - font-size: 14px; |
872 | - font-weight: 300; |
873 | } |
874 | |
875 | ul { |
876 | @@ -277,24 +274,11 @@ |
877 | } |
878 | &.notifications-nav { |
879 | position: relative; |
880 | - padding: 0; |
881 | - |
882 | - #notifications { |
883 | - & > span { |
884 | - .border-box; |
885 | - display: block; |
886 | - height: @navbar-height; |
887 | - padding: 15px 20px 0 20px; |
888 | - |
889 | - &.open { |
890 | - background-color: #000; |
891 | - } |
892 | - #notify-indicator { |
893 | - .button; |
894 | - margin: 0 9px 0 0; |
895 | - padding: 6px 12px; |
896 | - } |
897 | - } |
898 | + |
899 | + #notify-indicator { |
900 | + .button; |
901 | + margin: -5px 9px 0 0; |
902 | + padding: 6px 12px; |
903 | } |
904 | } |
905 | } |
906 | @@ -314,18 +298,6 @@ |
907 | background-color: #1f1b18; |
908 | } |
909 | } |
910 | - .help-dropdown { |
911 | - display: none; |
912 | - position: relative; |
913 | - |
914 | - .expand { |
915 | - margin-left: 5px; |
916 | - |
917 | - .hidden { |
918 | - display: none; |
919 | - } |
920 | - } |
921 | - } |
922 | } |
923 | } |
924 | #content { |
925 | @@ -717,41 +689,6 @@ |
926 | } |
927 | |
928 | /* |
929 | - * Feedback box |
930 | - * Appears as a tab on the side of the canvas. |
931 | - */ |
932 | -#feedback-box { |
933 | - position: absolute; |
934 | - right: -40px; |
935 | - bottom: 100px; |
936 | - /* Up the z-index so the feedback box will overlay the zoom slider as it |
937 | - * expands when hovered over */ |
938 | - z-index: 10; |
939 | - |
940 | - a { |
941 | - color: #fff; |
942 | - background-color: @charm-panel-orange; |
943 | - display: block; |
944 | - line-height: 30px; |
945 | - height: 40px; |
946 | - font-weight: 500; |
947 | - font-size: 16px; |
948 | - padding: 0 10px; |
949 | - margin-right: 3px; |
950 | - -webkit-transition: all 0.15s ease-in-out; |
951 | - -moz-transition: all 0.15s ease-in-out; |
952 | - transition: all 0.15s ease-in-out; |
953 | - .rotate(-90deg); |
954 | - |
955 | - &:hover { |
956 | - text-decoration: none; |
957 | - background-color: #df6920; |
958 | - margin-right: 13px; |
959 | - } |
960 | - } |
961 | -} |
962 | - |
963 | -/* |
964 | * Canvas zoom control |
965 | */ |
966 | .zoom-controls { |
967 | |
968 | === modified file 'test/index.html' |
969 | --- test/index.html 2013-10-31 14:16:29 +0000 |
970 | +++ test/index.html 2013-11-13 18:41:54 +0000 |
971 | @@ -70,6 +70,7 @@ |
972 | <script src="test_databinding.js"></script> |
973 | <script src="test_d3_components.js"></script> |
974 | <script src="test_d3_status.js"></script> |
975 | + <script src="test_dropdown_extension.js"></script> |
976 | <script src="test_endpoints.js"></script> |
977 | <script src="test_env.js"></script> |
978 | <script src="test_env_go.js"></script> |
979 | @@ -79,6 +80,7 @@ |
980 | <script src="test_fakebackend.js"></script> |
981 | <script src="test_filter_widget.js"></script> |
982 | <script src="test_ghost_inspector.js"></script> |
983 | + <script src="test_help_dropdown.js"></script> |
984 | <script src="test_inspector_charm.js"></script> |
985 | <script src="test_inspector_constraints.js"></script> |
986 | <script src="test_inspector_overview.js"></script> |
987 | |
988 | === modified file 'test/test_browser_app.js' |
989 | --- test/test_browser_app.js 2013-11-05 18:10:05 +0000 |
990 | +++ test/test_browser_app.js 2013-11-13 18:41:54 +0000 |
991 | @@ -1324,6 +1324,23 @@ |
992 | assert.deepEqual(hits, expected); |
993 | }); |
994 | |
995 | + it('onboarding is rendered with force-onboarding query', function(done) { |
996 | + var req = { |
997 | + path: '/sidebar' |
998 | + }; |
999 | + |
1000 | + localStorage.setItem('force-onboarding', true); |
1001 | + |
1002 | + browser.renderOnboarding = function(force) { |
1003 | + assert.equal(force, 'true'); |
1004 | + assert.equal(localStorage.getItem('force-onboarding'), ''); |
1005 | + assert.deepEqual(hits.sidebar, true); |
1006 | + done(); |
1007 | + }; |
1008 | + |
1009 | + browser.routeView(req, undefined, function() {}); |
1010 | + }); |
1011 | + |
1012 | it('/minimized dispatches correctly', function() { |
1013 | var req = { |
1014 | path: '/minimized', |
1015 | |
1016 | === added file 'test/test_dropdown_extension.js' |
1017 | --- test/test_dropdown_extension.js 1970-01-01 00:00:00 +0000 |
1018 | +++ test/test_dropdown_extension.js 2013-11-13 18:41:54 +0000 |
1019 | @@ -0,0 +1,80 @@ |
1020 | +/* |
1021 | +This file is part of the Juju GUI, which lets users view and manage Juju |
1022 | +environments within a graphical interface (https://launchpad.net/juju-gui). |
1023 | +Copyright (C) 2012-2013 Canonical Ltd. |
1024 | + |
1025 | +This program is free software: you can redistribute it and/or modify it under |
1026 | +the terms of the GNU Affero General Public License version 3, as published by |
1027 | +the Free Software Foundation. |
1028 | + |
1029 | +This program is distributed in the hope that it will be useful, but WITHOUT |
1030 | +ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
1031 | +SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero |
1032 | +General Public License for more details. |
1033 | + |
1034 | +You should have received a copy of the GNU Affero General Public License along |
1035 | +with this program. If not, see <http://www.gnu.org/licenses/>. |
1036 | +*/ |
1037 | + |
1038 | +'use strict'; |
1039 | + |
1040 | + |
1041 | +describe('dropdown view extension', function() { |
1042 | + var Y, container, view, View; |
1043 | + |
1044 | + before(function(done) { |
1045 | + Y = YUI(GlobalConfig).use(['view-dropdown-extension', |
1046 | + 'juju-tests-utils', |
1047 | + 'event-simulate', |
1048 | + 'node-event-simulate', |
1049 | + 'node'], function(Y) { |
1050 | + |
1051 | + View = Y.Base.create('dropdown', Y.View, [ |
1052 | + Y.juju.Dropdown, |
1053 | + Y.Event.EventTracker |
1054 | + ], { |
1055 | + template: '<a href="" class="menu-link"></a>' + |
1056 | + '<div class="dropdown"></div>', |
1057 | + |
1058 | + render: function() { |
1059 | + this.get('container').setHTML(this.template); |
1060 | + this._addDropdownFunc(); |
1061 | + return this; |
1062 | + } |
1063 | + }); |
1064 | + done(); |
1065 | + }); |
1066 | + }); |
1067 | + |
1068 | + beforeEach(function() { |
1069 | + container = Y.namespace('juju-tests.utils').makeContainer(); |
1070 | + view = new View({ container: container }).render(); |
1071 | + }); |
1072 | + |
1073 | + afterEach(function() { |
1074 | + view.destroy(); |
1075 | + container.remove().destroy(true); |
1076 | + }); |
1077 | + |
1078 | + it('should add the dropdown-menu class to the views container', function() { |
1079 | + assert.isTrue(container.hasClass('dropdown-menu')); |
1080 | + }); |
1081 | + |
1082 | + it('should open when the primary link is clicked', function(done) { |
1083 | + var link = container.one('.menu-link'); |
1084 | + link.after('click', function() { |
1085 | + assert.isTrue(container.hasClass('open')); |
1086 | + done(); |
1087 | + }); |
1088 | + link.simulate('click'); |
1089 | + }); |
1090 | + |
1091 | + it('should close when clicking outside the view', function() { |
1092 | + container.one('.menu-link').simulate('click'); |
1093 | + assert.isTrue(container.hasClass('open')); |
1094 | + |
1095 | + Y.one('body').simulate('click'); |
1096 | + assert.isFalse(container.hasClass('open')); |
1097 | + }); |
1098 | + |
1099 | +}); |
1100 | |
1101 | === added file 'test/test_help_dropdown.js' |
1102 | --- test/test_help_dropdown.js 1970-01-01 00:00:00 +0000 |
1103 | +++ test/test_help_dropdown.js 2013-11-13 18:41:54 +0000 |
1104 | @@ -0,0 +1,97 @@ |
1105 | +/* |
1106 | +This file is part of the Juju GUI, which lets users view and manage Juju |
1107 | +environments within a graphical interface (https://launchpad.net/juju-gui). |
1108 | +Copyright (C) 2012-2013 Canonical Ltd. |
1109 | + |
1110 | +This program is free software: you can redistribute it and/or modify it under |
1111 | +the terms of the GNU Affero General Public License version 3, as published by |
1112 | +the Free Software Foundation. |
1113 | + |
1114 | +This program is distributed in the hope that it will be useful, but WITHOUT |
1115 | +ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
1116 | +SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero |
1117 | +General Public License for more details. |
1118 | + |
1119 | +You should have received a copy of the GNU Affero General Public License along |
1120 | +with this program. If not, see <http://www.gnu.org/licenses/>. |
1121 | +*/ |
1122 | + |
1123 | +'use strict'; |
1124 | + |
1125 | +describe('help dropdown view', function() { |
1126 | + |
1127 | + var db, envAnno, helpView, views, landscape, models, viewNode, Y; |
1128 | + |
1129 | + before(function(done) { |
1130 | + Y = YUI(GlobalConfig).use(['node', |
1131 | + 'juju-landscape', |
1132 | + 'juju-models', |
1133 | + 'juju-views', |
1134 | + 'help-dropdown', |
1135 | + 'juju-tests-utils'], function(Y) { |
1136 | + |
1137 | + views = Y.namespace('juju.views'); |
1138 | + models = Y.namespace('juju.models'); |
1139 | + |
1140 | + db = new models.Database(); |
1141 | + landscape = new views.Landscape(); |
1142 | + landscape.set('db', db); |
1143 | + |
1144 | + done(); |
1145 | + }); |
1146 | + }); |
1147 | + |
1148 | + beforeEach(function() { |
1149 | + envAnno = db.environment.get('annotations'); |
1150 | + viewNode = Y.namespace('juju-tests.utils').makeContainer('help-dropdown'); |
1151 | + }); |
1152 | + |
1153 | + afterEach(function() { |
1154 | + viewNode.remove().destroy(true); |
1155 | + if (helpView) { |
1156 | + helpView.destroy(); |
1157 | + } |
1158 | + }); |
1159 | + |
1160 | + it('renders the basic list', function() { |
1161 | + helpView = new views.HelpDropdownView({ |
1162 | + container: viewNode, |
1163 | + env: db.environment |
1164 | + }).render(); |
1165 | + // Landscape url should be hidden |
1166 | + var container = helpView.get('container'); |
1167 | + assert.equal( |
1168 | + container.one('.landscape-url').getStyle('display'), 'none'); |
1169 | + assert.equal(container.all('li').size(), 5); |
1170 | + }); |
1171 | + |
1172 | + it('should display the Landscape menu item', function() { |
1173 | + envAnno['landscape-url'] = 'http://landscape.example.com'; |
1174 | + envAnno['landscape-computers'] = '/computers/criteria/environment:test'; |
1175 | + new views.HelpDropdownView({ |
1176 | + container: viewNode, |
1177 | + env: db.environment |
1178 | + }).render(); |
1179 | + |
1180 | + assert.equal( |
1181 | + viewNode.one('.landscape-url').getStyle('display'), 'list-item'); |
1182 | + assert.equal( |
1183 | + viewNode.one('.landscape-url a').get('href'), |
1184 | + 'http://landscape.example.com/computers/criteria/environment:test/'); |
1185 | + }); |
1186 | + |
1187 | + it('can start the onboarding visualization', function(done) { |
1188 | + helpView = new views.HelpDropdownView({ |
1189 | + container: viewNode, |
1190 | + env: db.environment |
1191 | + }); |
1192 | + helpView.on('navigate', function(e) { |
1193 | + assert.equal(e.url, '/sidebar'); |
1194 | + assert.equal(localStorage.getItem('force-onboarding'), 'true'); |
1195 | + done(); |
1196 | + }); |
1197 | + helpView.render(); |
1198 | + var ob = helpView.get('container').one('.start-onboarding'); |
1199 | + ob.simulate('click'); |
1200 | + }); |
1201 | +}); |
1202 | |
1203 | === modified file 'test/test_notifications.js' |
1204 | --- test/test_notifications.js 2013-10-29 23:10:25 +0000 |
1205 | +++ test/test_notifications.js 2013-11-13 18:41:54 +0000 |
1206 | @@ -159,7 +159,7 @@ |
1207 | nsRouter: nsRouter}); |
1208 | view.render(); |
1209 | // Verify the expected elements appear in the view |
1210 | - container.one('#notify-list').should.not.equal(undefined); |
1211 | + container.one('.dropdown').should.not.equal(undefined); |
1212 | container.destroy(); |
1213 | }); |
1214 | |
1215 | @@ -330,33 +330,6 @@ |
1216 | notice.get('message').should.equal(''); |
1217 | }); |
1218 | |
1219 | - |
1220 | - it('should open on click and close on clickoutside', function(done) { |
1221 | - var container = Y.Node.create( |
1222 | - '<div id="test-container" style="display: none" class="container"/>'), |
1223 | - notifications = new models.NotificationList(), |
1224 | - env = juju.newEnvironment(), |
1225 | - view = new views.NotificationsView({ |
1226 | - container: container, |
1227 | - notifications: notifications, |
1228 | - env: env, |
1229 | - nsRouter: nsRouter}).render(), |
1230 | - indicator; |
1231 | - |
1232 | - Y.one('body').append(container); |
1233 | - notifications.add({title: 'testing', 'level': 'error'}); |
1234 | - indicator = container.one('#notify-indicator'); |
1235 | - |
1236 | - indicator.simulate('click'); |
1237 | - indicator.ancestor().hasClass('open').should.equal(true); |
1238 | - |
1239 | - Y.one('body').simulate('click'); |
1240 | - indicator.ancestor().hasClass('open').should.equal(false); |
1241 | - |
1242 | - container.remove(); |
1243 | - done(); |
1244 | - }); |
1245 | - |
1246 | }); |
1247 | |
1248 | |
1249 | |
1250 | === modified file 'test/test_onboarding.js' |
1251 | --- test/test_onboarding.js 2013-10-23 00:12:47 +0000 |
1252 | +++ test/test_onboarding.js 2013-11-13 18:41:54 +0000 |
1253 | @@ -158,6 +158,7 @@ |
1254 | onboard.closeHandler({halt: function() {}}); |
1255 | assert.equal(container.getComputedStyle('display'), 'none'); |
1256 | assert.isFalse(env_help.hasClass('hidden')); |
1257 | + assert.equal(localStorage.getItem('force-onboarding'), ''); |
1258 | }); |
1259 | |
1260 | it('should not be shown if seen before', function() { |
1261 | @@ -171,5 +172,19 @@ |
1262 | assert.isTrue(background instanceof Y.Node); |
1263 | }); |
1264 | |
1265 | + it('sets index to 0, clears out local storage on reset', function() { |
1266 | + var onboard = new OnboardingView({ |
1267 | + container: container |
1268 | + }).render(); |
1269 | + onboard.nextHandler({halt: function() {}}); |
1270 | + assert.equal(onboard.onboardingIndex, 1); |
1271 | + |
1272 | + localStorage.setItem('onboarding', true); |
1273 | + |
1274 | + onboard.reset(); |
1275 | + assert.equal(onboard.onboardingIndex, 0); |
1276 | + assert.equal(localStorage.getItem('onboarding'), ''); |
1277 | + }); |
1278 | + |
1279 | }); |
1280 | })(); |
1281 | |
1282 | === modified file 'undocumented' |
1283 | --- undocumented 2013-10-02 16:26:20 +0000 |
1284 | +++ undocumented 2013-11-13 18:41:54 +0000 |
1285 | @@ -71,7 +71,6 @@ |
1286 | app/views/notifications.js:42 "initializer" |
1287 | app/views/notifications.js:286 "render" |
1288 | app/views/notifications.js:173 "render" |
1289 | -app/views/notifications.js:265 "close" |
1290 | app/views/databinding.js:81 "keyfunc" |
1291 | app/views/topology/panzoom.js:91 "renderSlider" |
1292 | app/views/topology/panzoom.js:265 "renderedHandler" |
Reviewers: mp+195116_ code.launchpad. net,
Message:
Please take a look.
Description:
A dropdown view extension.
This is a refactoring of Huw's branch which created a dropdown widget
and a "Help & Feedback" dropdown on the header bar.
original: https:/ /codereview. appspot. com/23410043/
original original: https:/ /codereview. appspot. com/25390043/
https:/ /code.launchpad .net/~rharding/ juju-gui/ help-dropdown/ +merge/ 195116
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/26200043/
Affected files (+675, -259 lines): javascripts/ view-dropdown- extension. js debug.js browser/ browser. js help-dropdown. handlebars notifications. handlebars onboarding. handlebars overview. handlebars help-dropdown. js notifications. js onboarding. js browser/ onboarding. less dropdown. less stylesheet. less browser_ app.js dropdown_ extension. js help_dropdown. js notifications. js onboarding. js
A [revision details]
M app/app.js
A app/assets/
M app/index.html
M app/modules-
M app/subapps/
A app/templates/
M app/templates/
M app/templates/
M app/templates/
A app/views/
M app/views/
M app/views/
M bin/merge-files
M lib/views/
M lib/views/
M lib/views/
M test/index.html
M test/test_
A test/test_
A test/test_
M test/test_
M test/test_
M undocumented