Merge lp:~teknico/juju-gui/charm-panel-docs into lp:juju-gui/experimental
- charm-panel-docs
- Merge into trunk
Proposed by
Nicola Larosa
Status: | Merged |
---|---|
Merged at revision: | 372 |
Proposed branch: | lp:~teknico/juju-gui/charm-panel-docs |
Merge into: | lp:juju-gui/experimental |
Diff against target: |
589 lines (+176/-46) 2 files modified
app/views/charm-panel.js (+176/-24) undocumented (+0/-22) |
To merge this branch: | bzr merge lp:~teknico/juju-gui/charm-panel-docs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju GUI Hackers | Pending | ||
Review via email: mp+147174@code.launchpad.net |
Commit message
Description of the change
Better charm panel docs.
Improve the charm panel comment blocks.
To post a comment you must log in.
Revision history for this message
Nicola Larosa (teknico) wrote : | # |
Revision history for this message
Gary Poster (gary) wrote : | # |
Revision history for this message
Madison Scott-Clary (makyo) wrote : | # |
Land as is. Thanks for the docs!
Revision history for this message
Nicola Larosa (teknico) wrote : | # |
*** Submitted:
Better charm panel docs.
Improve the charm panel comment blocks.
R=gary.poster, matthew.scott
CC=
https:/
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'app/views/charm-panel.js' |
2 | --- app/views/charm-panel.js 2013-01-30 12:38:03 +0000 |
3 | +++ app/views/charm-panel.js 2013-02-07 17:04:21 +0000 |
4 | @@ -1,9 +1,10 @@ |
5 | 'use strict'; |
6 | |
7 | /** |
8 | - * The charm panel view(s). |
9 | + * The charm panel views implement the various things shown in the right panel |
10 | + * when clicking on the "Charms" label in the title bar, or running a search. |
11 | * |
12 | - * @module views |
13 | + * @module charm-panel |
14 | */ |
15 | |
16 | YUI.add('juju-charm-panel', function(Y) { |
17 | @@ -16,6 +17,7 @@ |
18 | subscriptions = [], |
19 | // Singleton |
20 | _instance, |
21 | + |
22 | // See https://github.com/yui/yuidoc/issues/25 for issue tracking |
23 | // missing @function tag. |
24 | /** |
25 | @@ -46,6 +48,7 @@ |
26 | icon.replaceClass('chevron_up', 'chevron_down'); |
27 | } |
28 | }, |
29 | + |
30 | /** |
31 | * Given a container node and a total height available, set the height of |
32 | * a '.charm-panel' node to fill the remaining height available to it |
33 | @@ -68,6 +71,7 @@ |
34 | scrollContainer.setStyle('height', scrollHeight + 'px'); |
35 | } |
36 | }, |
37 | + |
38 | /** |
39 | * Given a set of entries as returned by the charm store "find" |
40 | * method (charms grouped by series), return the list filtered |
41 | @@ -84,6 +88,7 @@ |
42 | */ |
43 | filterEntries = function(entries, filter, services) { |
44 | var deployedCharms; |
45 | + |
46 | /** |
47 | * Filter to determine if a charm is a subordinate. |
48 | * |
49 | @@ -94,6 +99,7 @@ |
50 | function isSubFilter(charm) { |
51 | return !!charm.get('is_subordinate'); |
52 | } |
53 | + |
54 | /** |
55 | * Filter to determine if a charm is the same as any |
56 | * deployed services. |
57 | @@ -105,6 +111,7 @@ |
58 | function isDeployedFilter(charm) { |
59 | return deployedCharms.indexOf(charm.get('id')) !== -1; |
60 | } |
61 | + |
62 | var filter_fcn; |
63 | |
64 | if (filter === 'all') { |
65 | @@ -157,6 +164,7 @@ |
66 | }; |
67 | }); |
68 | }, |
69 | + |
70 | /** |
71 | * Given an array of interface data as stored in a charm's "required" |
72 | * and "provided" attributes, return an array of interface names. |
73 | @@ -179,7 +187,8 @@ |
74 | }; |
75 | |
76 | /** |
77 | - * Display a unit. |
78 | + * Charm collection view. Show a list of charms, each clickable through |
79 | + * for a description, or deployed directly with a "Deploy" button. |
80 | * |
81 | * @class CharmCollectionView |
82 | * @namespace views |
83 | @@ -190,12 +199,25 @@ |
84 | 'a.charm-detail': {click: 'showDetails'}, |
85 | '.charm-entry .btn.deploy': {click: 'showConfiguration'}, |
86 | '.charm-entry': { |
87 | + |
88 | + /** |
89 | + * Show the charm deploy button on mouse pointer enter. |
90 | + * |
91 | + * @method CharmCollectionView.events.mouseenter |
92 | + */ |
93 | mouseenter: function(ev) { |
94 | ev.currentTarget.all('.btn').transition({opacity: 1, duration: 0.25}); |
95 | }, |
96 | + |
97 | + /** |
98 | + * Hide the charm deploy button on mouse pointer leave. |
99 | + * |
100 | + * @method CharmCollectionView.events.mouseleave |
101 | + */ |
102 | mouseleave: function(ev) { |
103 | ev.currentTarget.all('.btn').transition({opacity: 0, duration: 0.25}); |
104 | } |
105 | + |
106 | }, |
107 | '.charm-filter-picker .picker-button': { |
108 | click: 'showCharmFilterPicker' |
109 | @@ -204,9 +226,15 @@ |
110 | click: 'hideCharmFilterPicker' |
111 | } |
112 | }, |
113 | - // Set searchText to cause the results to be found and rendered. |
114 | - // Set defaultSeries to cause all the results for the default series to be |
115 | - // found and rendered. |
116 | + |
117 | + /** |
118 | + * Set searchText to cause the results to be found and rendered. |
119 | + * |
120 | + * Set defaultSeries to cause all the results for the default series |
121 | + * to be found and rendered. |
122 | + * |
123 | + * @method CharmCollectionView.initializer |
124 | + */ |
125 | initializer: function() { |
126 | var self = this; |
127 | this.set('filter', 'all'); |
128 | @@ -224,6 +252,7 @@ |
129 | }); |
130 | } |
131 | }); |
132 | + |
133 | this.after('defaultSeriesChange', function(ev) { |
134 | this.set('defaultEntries', null); |
135 | if (ev.newVal) { |
136 | @@ -248,6 +277,10 @@ |
137 | }); |
138 | this.after('heightChange', this._setScroll); |
139 | }, |
140 | + |
141 | + /** |
142 | + * @method CharmCollectionView.render |
143 | + */ |
144 | render: function() { |
145 | var container = this.get('container'), |
146 | searchText = this.get('searchText'), |
147 | @@ -299,9 +332,10 @@ |
148 | this._setScroll(); |
149 | return this; |
150 | }, |
151 | + |
152 | /** |
153 | - * When the view's "height" attribute is set, adjust the internal scrollable |
154 | - * div to have the appropriate height. |
155 | + * When the view's "height" attribute is set, adjust the internal |
156 | + * scrollable div to have the appropriate height. |
157 | * |
158 | * @method _setScroll |
159 | * @protected |
160 | @@ -315,6 +349,7 @@ |
161 | scrollContainer.setStyle('height', height - 1 + 'px'); |
162 | } |
163 | }, |
164 | + |
165 | /** |
166 | * Fire an event indicating that the charm panel should switch to the |
167 | * "description" for a given charm. |
168 | @@ -330,6 +365,15 @@ |
169 | { name: 'description', |
170 | charmId: ev.target.getAttribute('href') }); |
171 | }, |
172 | + |
173 | + /** |
174 | + * Fire an event indicating that the charm panel should switch to the |
175 | + * "configuration" for a given charm. |
176 | + * |
177 | + * @method showConfiguration |
178 | + * @param {Object} ev An event object (with a `halt` method). |
179 | + * @return {undefined} Sends a signal only. |
180 | + */ |
181 | showConfiguration: function(ev) { |
182 | // Without the ev.halt the 'outside' click handler is getting |
183 | // called which immediately closes the panel. |
184 | @@ -339,8 +383,9 @@ |
185 | { name: 'configuration', |
186 | charmId: ev.currentTarget.getData('url')}); |
187 | }, |
188 | + |
189 | /** |
190 | - * Create a data structure friendly to the view |
191 | + * Create a data structure friendly to the view. |
192 | * |
193 | * @method normalizeCharms. |
194 | */ |
195 | @@ -389,6 +434,7 @@ |
196 | return {series: name, charms: hash[name]}; |
197 | }); |
198 | }, |
199 | + |
200 | /** |
201 | * Find charms that match a query. |
202 | * |
203 | @@ -419,6 +465,12 @@ |
204 | ); |
205 | }}}); |
206 | }, |
207 | + |
208 | + /** |
209 | + * Show errors on both console and notifications. |
210 | + * |
211 | + * @method _showErrors |
212 | + */ |
213 | _showErrors: function(e) { |
214 | console.error(e.error); |
215 | this.get('db').notifications.add( |
216 | @@ -463,7 +515,8 @@ |
217 | views.CharmCollectionView = CharmCollectionView; |
218 | |
219 | /** |
220 | - * Display a unit. |
221 | + * Charm description view. It describes a charm's features in detail, |
222 | + * together with a "Deploy" button. |
223 | * |
224 | * @class CharmDescriptionView |
225 | * @namespace views |
226 | @@ -478,10 +531,16 @@ |
227 | '.charm-section h4': {click: toggleSectionVisibility}, |
228 | 'a.charm-detail': {click: 'showDetails'} |
229 | }, |
230 | + /** |
231 | + * @method CharmDescriptionView.initializer |
232 | + */ |
233 | initializer: function() { |
234 | this.bindModelView(this.get('model')); |
235 | this.after('heightChange', this._setScroll); |
236 | }, |
237 | + /** |
238 | + * @method CharmDescriptionView.render |
239 | + */ |
240 | render: function() { |
241 | var container = this.get('container'), |
242 | charm = this.get('model'); |
243 | @@ -647,7 +706,9 @@ |
244 | views.CharmDescriptionView = CharmDescriptionView; |
245 | |
246 | /** |
247 | - * Display a charms configuration panel. |
248 | + * Display a charm's configuration panel. It shows editable fields for |
249 | + * the charm's configuration parameters, together with a "Cancel" and |
250 | + * a "Confirm" button for deployment. |
251 | * |
252 | * @class CharmConfigurationView |
253 | * @namespace views |
254 | @@ -657,10 +718,18 @@ |
255 | template: views.Templates['charm-pre-configuration'], |
256 | tooltip: null, |
257 | configFileContent: null, |
258 | + |
259 | + /** |
260 | + * @method CharmConfigurationView.initializer |
261 | + */ |
262 | initializer: function() { |
263 | this.bindModelView(this.get('model')); |
264 | this.after('heightChange', this._setScroll); |
265 | }, |
266 | + |
267 | + /** |
268 | + * @method CharmConfigurationView.render |
269 | + */ |
270 | render: function() { |
271 | var container = this.get('container'), |
272 | charm = this.get('model'), |
273 | @@ -684,6 +753,7 @@ |
274 | this._setScroll(); |
275 | return this; |
276 | }, |
277 | + |
278 | /** |
279 | * When the view's "height" attribute is set, adjust the internal |
280 | * scrollable div to have the appropriate height. |
281 | @@ -695,6 +765,7 @@ |
282 | _setScroll: function() { |
283 | setScroll(this.get('container'), this.get('height')); |
284 | }, |
285 | + |
286 | events: { |
287 | '.btn.cancel': {click: 'goBack'}, |
288 | '.btn.deploy': {click: 'onCharmDeployClicked'}, |
289 | @@ -706,8 +777,9 @@ |
290 | 'input.config-field[type=checkbox]': |
291 | {click: function(evt) {evt.target.focus();}} |
292 | }, |
293 | + |
294 | /** |
295 | - * Determines the Y coordinate that would center a tooltip on a field. |
296 | + * Determine the Y coordinate that would center a tooltip on a field. |
297 | * |
298 | * @static |
299 | * @param {Number} fieldY The current Y position of the tooltip. |
300 | @@ -720,8 +792,9 @@ |
301 | var y_offset = (tooltipHeight - fieldHeight) / 2; |
302 | return fieldY - y_offset; |
303 | }, |
304 | + |
305 | /** |
306 | - * Determines the X coordinate that would place a tooltip next to a |
307 | + * Determine the X coordinate that would place a tooltip next to a |
308 | * field. |
309 | * |
310 | * @static |
311 | @@ -733,6 +806,12 @@ |
312 | _calculateTooltipX: function(fieldX, tooltipWidth) { |
313 | return fieldX - tooltipWidth - 15; |
314 | }, |
315 | + |
316 | + /** |
317 | + * Move a tooltip to its predefined position. |
318 | + * |
319 | + * @method _moveTooltip |
320 | + */ |
321 | _moveTooltip: function() { |
322 | if (this.tooltip.field && |
323 | Y.DOM.inRegion( |
324 | @@ -759,6 +838,12 @@ |
325 | this.tooltip.hide(); |
326 | } |
327 | }, |
328 | + |
329 | + /** |
330 | + * Show the charm's description. |
331 | + * |
332 | + * @method showDescription |
333 | + */ |
334 | showDescription: function(evt) { |
335 | var controlGroup = evt.target.ancestor('.control-group'), |
336 | node = controlGroup.one('.control-description'), |
337 | @@ -772,10 +857,17 @@ |
338 | this.tooltip.panel.getDOMNode()); |
339 | this._moveTooltip(); |
340 | }, |
341 | + |
342 | + /** |
343 | + * Hide the charm's description. |
344 | + * |
345 | + * @method hideDescription |
346 | + */ |
347 | hideDescription: function(evt) { |
348 | this.tooltip.hide(); |
349 | delete this.tooltip.field; |
350 | }, |
351 | + |
352 | /** |
353 | * Pass clicks on the overlay on to the correct recipient. |
354 | * The recipient can be the upload widget or the file remove one. |
355 | @@ -792,6 +884,7 @@ |
356 | container.one('.config-file-upload-widget').getDOMNode().click(); |
357 | } |
358 | }, |
359 | + |
360 | /** |
361 | * Handle the file upload click event. |
362 | * Call onFileLoaded or onFileError if an error occurs during upload. |
363 | @@ -813,6 +906,7 @@ |
364 | container.one('.config-file-upload-overlay') |
365 | .setContent('Remove file'); |
366 | }, |
367 | + |
368 | /** |
369 | * Handle the file remove click event. |
370 | * Restore the file upload widget on click. |
371 | @@ -837,6 +931,7 @@ |
372 | overlay.ancestor('.collapsible') |
373 | .show('sizeIn', {duration: 0.25, width: null}); |
374 | }, |
375 | + |
376 | /** |
377 | * Callback called when a file is correctly uploaded. |
378 | * Hide the charm configuration section. |
379 | @@ -849,7 +944,7 @@ |
380 | this.configFileContent = evt.target.result; |
381 | |
382 | if (!this.configFileContent) { |
383 | - // Some file read errors don't go through the error handler as |
384 | + // Some file read errors do not go through the error handler as |
385 | // expected but instead return an empty string. Warn the user if |
386 | // this happens. |
387 | var db = this.get('db'); |
388 | @@ -863,6 +958,7 @@ |
389 | } |
390 | this.get('container').one('.charm-settings').hide(); |
391 | }, |
392 | + |
393 | /** |
394 | * Callback called when an error occurs during file upload. |
395 | * Hide the charm configuration section. |
396 | @@ -897,9 +993,11 @@ |
397 | } |
398 | return; |
399 | }, |
400 | + |
401 | /** |
402 | * Fires an event indicating that the charm panel should switch to the |
403 | - * "charms" search result view. |
404 | + * "charms" search result view. Called upon clicking the "Cancel" |
405 | + * button. |
406 | * |
407 | * @method goBack |
408 | * @param {Object} ev An event object (with a "halt" method). |
409 | @@ -909,6 +1007,14 @@ |
410 | ev.halt(); |
411 | this.fire('changePanel', { name: 'charms' }); |
412 | }, |
413 | + |
414 | + /** |
415 | + * Called upon clicking the "Confirm" button. |
416 | + * |
417 | + * @method onCharmDeployClicked |
418 | + * @param {Object} ev An event object (with a "halt" method). |
419 | + * @return {undefined} Sends a signal only. |
420 | + */ |
421 | onCharmDeployClicked: function(evt) { |
422 | var container = this.get('container'), |
423 | db = this.get('db'), |
424 | @@ -972,6 +1078,14 @@ |
425 | }); |
426 | this.goBack(evt); |
427 | }, |
428 | + |
429 | + /** |
430 | + * Setup the panel overlay. |
431 | + * |
432 | + * @method setupOverlay |
433 | + * @param {Object} container The container element. |
434 | + * @return {undefined} Side effects only. |
435 | + */ |
436 | setupOverlay: function(container) { |
437 | var self = this; |
438 | container.appendChild(Y.Node.create('<div/>')) |
439 | @@ -983,7 +1097,11 @@ |
440 | }); |
441 | views.CharmConfigurationView = CharmConfigurationView; |
442 | |
443 | - // Creates the "_instance" object |
444 | + /** |
445 | + * Create the "_instance" object. |
446 | + * |
447 | + * @method createInstance |
448 | + */ |
449 | function createInstance(config) { |
450 | |
451 | var charmStore = config.charm_store, |
452 | @@ -1030,6 +1148,11 @@ |
453 | Y.one(document.body).append(container); |
454 | container.hide(); |
455 | |
456 | + /** |
457 | + * Setup the panel data. |
458 | + * |
459 | + * @method setPanel |
460 | + */ |
461 | function setPanel(config) { |
462 | var newPanel = panels[config.name]; |
463 | if (!Y.Lang.isValue(newPanel)) { |
464 | @@ -1105,7 +1228,7 @@ |
465 | subscriptions.push(Y.on('afterPageSizeRecalculation', function() { |
466 | if (isPanelVisible) { |
467 | // We need to do this both in windowresize and here because |
468 | - // windowresize can only be fired with "on," and so we can't know |
469 | + // windowresize can only be fired with "on," and so we cannot know |
470 | // which handler will be fired first. |
471 | updatePanelPosition(); |
472 | } |
473 | @@ -1159,12 +1282,18 @@ |
474 | } |
475 | } |
476 | |
477 | + /** |
478 | + * Update the panel position. |
479 | + * |
480 | + * This should only be called when the popup is supposed to be visible. |
481 | + * We need to hide the popup before we calculate positions, so that it |
482 | + * does not cause scrollbars to appear while we are calculating |
483 | + * positions. The temporary scrollbars can cause the calculations to |
484 | + * be incorrect. |
485 | + * |
486 | + * @method updatePanelPosition |
487 | + */ |
488 | function updatePanelPosition() { |
489 | - // This should only be called when the popup is supposed to be visible. |
490 | - // We need to hide the popup before we calculate positions so that it |
491 | - // does not cause scrollbars to appear while we are calculating |
492 | - // positions. The temporary scrollbars can cause the calculations to be |
493 | - // incorrect. |
494 | container.setStyle('display', 'none'); |
495 | var pos = calculatePanelPosition(); |
496 | container.setStyle('display', 'block'); |
497 | @@ -1176,6 +1305,11 @@ |
498 | } |
499 | } |
500 | |
501 | + /** |
502 | + * Calculate the panel position. |
503 | + * |
504 | + * @method calculatePanelPosition |
505 | + */ |
506 | function calculatePanelPosition() { |
507 | var headerBox = Y.one('#charm-search-trigger-container'), |
508 | dimensions = utils.getEffectiveViewportSize(); |
509 | @@ -1200,12 +1334,18 @@ |
510 | subscriptions.push(searchField.on('keydown', handleKeyDown)); |
511 | } |
512 | |
513 | - // The public methods |
514 | + // The public methods. |
515 | return { |
516 | hide: hide, |
517 | toggle: toggle, |
518 | show: show, |
519 | node: container, |
520 | + |
521 | + /** |
522 | + * Set the default charm series in the search and description panels. |
523 | + * |
524 | + * @method setDefaultSeries |
525 | + */ |
526 | setDefaultSeries: function(series) { |
527 | charmsSearchPanel.set('defaultSeries', series); |
528 | descriptionPanel.set('defaultSeries', series); |
529 | @@ -1213,14 +1353,26 @@ |
530 | }; |
531 | } |
532 | |
533 | - // The public methods |
534 | + // The public methods. |
535 | views.CharmPanel = { |
536 | + |
537 | + /** |
538 | + * Get the instance, creating it if it does not yet exist. |
539 | + * |
540 | + * @method getInstance |
541 | + */ |
542 | getInstance: function(config) { |
543 | if (!_instance) { |
544 | _instance = createInstance(config); |
545 | } |
546 | return _instance; |
547 | }, |
548 | + |
549 | + /** |
550 | + * Destroy the instance and its node, detaching all subscriptions. |
551 | + * |
552 | + * @method getInstance |
553 | + */ |
554 | killInstance: function() { |
555 | while (subscriptions.length) { |
556 | var sub = subscriptions.pop(); |
557 | |
558 | === modified file 'undocumented' |
559 | --- undocumented 2013-01-31 00:02:54 +0000 |
560 | +++ undocumented 2013-02-07 17:04:21 +0000 |
561 | @@ -66,28 +66,6 @@ |
562 | app/views/utils.js:132 "native" |
563 | app/views/utils.js:795 "value" |
564 | app/views/environment.js:24 "initializer" |
565 | -app/views/charm-panel.js:1168 "calculatePanelPosition" |
566 | -app/views/charm-panel.js:476 "initializer" |
567 | -app/views/charm-panel.js:250 "render" |
568 | -app/views/charm-panel.js:901 "onCharmDeployClicked" |
569 | -app/views/charm-panel.js:976 "createInstance" |
570 | -app/views/charm-panel.js:764 "hideDescription" |
571 | -app/views/charm-panel.js:1022 "setPanel" |
572 | -app/views/charm-panel.js:332 "showConfiguration" |
573 | -app/views/charm-panel.js:1151 "updatePanelPosition" |
574 | -app/views/charm-panel.js:1213 "killInstance" |
575 | -app/views/charm-panel.js:655 "render" |
576 | -app/views/charm-panel.js:1198 "setDefaultSeries" |
577 | -app/views/charm-panel.js:195 "mouseleave" |
578 | -app/views/charm-panel.js:417 "_showErrors" |
579 | -app/views/charm-panel.js:651 "initializer" |
580 | -app/views/charm-panel.js:480 "render" |
581 | -app/views/charm-panel.js:751 "showDescription" |
582 | -app/views/charm-panel.js:725 "_moveTooltip" |
583 | -app/views/charm-panel.js:209 "initializer" |
584 | -app/views/charm-panel.js:964 "setupOverlay" |
585 | -app/views/charm-panel.js:192 "mouseenter" |
586 | -app/views/charm-panel.js:1207 "getInstance" |
587 | app/views/charm.js:32 "render" |
588 | app/views/charm.js:161 "on_results_change" |
589 | app/views/charm.js:118 "render" |
Reviewers: mp+147174_ code.launchpad. net,
Message:
Please take a look.
Description:
Better charm panel docs.
Improve the charm panel comment blocks.
https:/ /code.launchpad .net/~teknico/ juju-gui/ charm-panel- docs/+merge/ 147174
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/7307063/
Affected files: charm-panel. js
A [revision details]
M app/views/
M undocumented