OLD | NEW |
1 'use strict'; | 1 'use strict'; |
2 | 2 |
3 | 3 |
4 YUI.add('subapp-browser-charmview', function(Y) { | 4 YUI.add('subapp-browser-charmview', function(Y) { |
5 var ns = Y.namespace('juju.browser.views'), | 5 var ns = Y.namespace('juju.browser.views'), |
6 views = Y.namespace('juju.views'), | 6 views = Y.namespace('juju.views'), |
7 widgets = Y.namespace('juju.widgets'); | 7 widgets = Y.namespace('juju.widgets'); |
8 | 8 |
9 | 9 |
10 /** | 10 /** |
11 * View for the Charm details UI. | 11 * View for the Charm details UI. |
12 * | 12 * |
13 * @class CharmView | 13 * @class CharmView |
14 * @extends {Y.View} | 14 * @extends {Y.View} |
15 * | 15 * |
16 */ | 16 */ |
17 ns.BrowserCharmView = Y.Base.create('browser-view-charmview', Y.View, [ | 17 ns.BrowserCharmView = Y.Base.create('browser-view-charmview', Y.View, [ |
18 widgets.browser.IndicatorManager], { | 18 widgets.browser.IndicatorManager], { |
19 | 19 |
20 template: views.Templates.browser_charm, | 20 template: views.Templates.browser_charm, |
| 21 qatemplate: views.Templates.browser_qa, |
21 | 22 |
22 /** | 23 /** |
23 * List the DOM based events to watch for in the container. | 24 * List the DOM based events to watch for in the container. |
24 * @attribute events | 25 * @attribute events |
25 * | 26 * |
26 */ | 27 */ |
27 events: { | 28 events: { |
28 '.changelog .toggle': { | 29 '.changelog .toggle': { |
29 click: '_toggleLog' | 30 click: '_toggleLog' |
30 }, | 31 }, |
(...skipping 13 matching lines...) Expand all Loading... |
44 * @param {Event} ev the event from the click handler. | 45 * @param {Event} ev the event from the click handler. |
45 * @private | 46 * @private |
46 * | 47 * |
47 */ | 48 */ |
48 _addCharmEnvironment: function(ev) { | 49 _addCharmEnvironment: function(ev) { |
49 console.log('add the charm to the environment'); | 50 console.log('add the charm to the environment'); |
50 ev.preventDefault(); | 51 ev.preventDefault(); |
51 }, | 52 }, |
52 | 53 |
53 /** | 54 /** |
| 55 * The API retuns the questions and the scores. Combine the data into a |
| 56 * single source to make looping in the handlebars templates nicer. |
| 57 * |
| 58 * @method _buildQAData |
| 59 * @param {Object} responseData the qa data from the store. |
| 60 * |
| 61 */ |
| 62 _buildQAData: function(responseData) { |
| 63 var questions = responseData.result.questions, |
| 64 scores = responseData.scores, |
| 65 totalAvailable = 0, |
| 66 totalScore = 0; |
| 67 |
| 68 Y.Array.each(questions, function(category) { |
| 69 var sum = 0; |
| 70 |
| 71 Y.Array.each(category.questions, function(question, idx) { |
| 72 var categoryName = category.name, |
| 73 questionIndex = categoryName + '_' + idx; |
| 74 |
| 75 if (scores[categoryName] && scores[categoryName][questionIndex]) { |
| 76 var score = parseInt(scores[categoryName][questionIndex], 10); |
| 77 sum += score; |
| 78 category.questions[idx].score = score; |
| 79 } else { |
| 80 category.questions[idx].score = undefined; |
| 81 } |
| 82 }); |
| 83 |
| 84 category.score = sum; |
| 85 totalAvailable += category.questions.length; |
| 86 totalScore += sum; |
| 87 }); |
| 88 |
| 89 return { |
| 90 questions: questions, |
| 91 totalAvailable: totalAvailable, |
| 92 totalScore: totalScore |
| 93 }; |
| 94 }, |
| 95 |
| 96 /** |
| 97 * Watch the tab control for change events and dispatch accordingly. |
| 98 * |
| 99 * @method _bindTabEvents |
| 100 * @param {TabView} tab the tab control to monitor. |
| 101 * |
| 102 */ |
| 103 _dispatchTabEvents: function(tab) { |
| 104 this._events.push(tab.after('selectionChange', function(ev) { |
| 105 var tab = ev.newVal.get('content'); |
| 106 switch (tab) { |
| 107 // @todo to be added later. Placed in now to make the linter happy |
| 108 // with the switch statement. |
| 109 case 'Configuration': |
| 110 console.log('not implemented config handler'); |
| 111 break; |
| 112 case 'Interfaces': |
| 113 console.log('not implemented interfaces handler'); |
| 114 break; |
| 115 case 'Quality': |
| 116 this._loadQAContent(); |
| 117 break; |
| 118 default: |
| 119 break; |
| 120 } |
| 121 }, this)); |
| 122 }, |
| 123 |
| 124 /** |
54 * Event handler for clicking on a hook filename to load that file. | 125 * Event handler for clicking on a hook filename to load that file. |
55 * | 126 * |
56 * @method _loadHookContent | 127 * @method _loadHookContent |
57 * @param {Event} ev the click event created. | 128 * @param {Event} ev the click event created. |
58 * | 129 * |
59 */ | 130 */ |
60 _loadHookContent: function(ev) { | 131 _loadHookContent: function(ev) { |
61 var filename = ev.currentTarget.get('text'), | 132 var filename = ev.currentTarget.get('text'), |
62 node = this.get('container').one('#bws_hooks .filecontent'); | 133 node = this.get('container').one('#bws_hooks .filecontent'); |
63 | 134 |
64 // Load the file, but make sure we prettify the code. | 135 // Load the file, but make sure we prettify the code. |
65 this._loadFile(node, filename, true); | 136 this._loadFile(node, filename, true); |
66 }, | 137 }, |
67 | 138 |
68 /** | 139 /** |
| 140 * Load the charm's QA data and fill it into the tab when selected. |
| 141 * |
| 142 * @method _loadQAContent |
| 143 * |
| 144 */ |
| 145 _loadQAContent: function() { |
| 146 var node = Y.one('#bws_qa'); |
| 147 this.showIndicator(node); |
| 148 // Only load the QA data once. |
| 149 if (!this._qaLoaded) { |
| 150 this.get('store').qa( |
| 151 this.get('charm').get('id'), { |
| 152 'success': function(data) { |
| 153 data = this._buildQAData(data); |
| 154 node.setHTML(this.qatemplate(data)); |
| 155 this.hideIndicator(node); |
| 156 }, |
| 157 'failure': function(data, request) { |
| 158 |
| 159 } |
| 160 }, this); |
| 161 } |
| 162 }, |
| 163 |
| 164 /** |
69 * The readme file in a charm can be upper/lower/etc. This helps find a | 165 * The readme file in a charm can be upper/lower/etc. This helps find a |
70 * readme from the list of files in a charm. | 166 * readme from the list of files in a charm. |
71 * | 167 * |
72 * @method _locateReadme | 168 * @method _locateReadme |
73 * @private | 169 * @private |
74 * | 170 * |
75 */ | 171 */ |
76 _locateReadme: function() { | 172 _locateReadme: function() { |
77 var files = this.get('charm').get('files'), | 173 var files = this.get('charm').get('files'), |
78 match = 'readme'; | 174 match = 'readme'; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 /** | 244 /** |
149 * Clean up after ourselves. | 245 * Clean up after ourselves. |
150 * | 246 * |
151 * @method destructor | 247 * @method destructor |
152 * | 248 * |
153 */ | 249 */ |
154 destructor: function() { | 250 destructor: function() { |
155 if (this.tabview) { | 251 if (this.tabview) { |
156 this.tabview.destroy(); | 252 this.tabview.destroy(); |
157 } | 253 } |
| 254 |
| 255 Y.Array.each(this._events, function(ev) { |
| 256 ev.detach(); |
| 257 }); |
158 }, | 258 }, |
159 | 259 |
160 /** | 260 /** |
161 * Generic YUI initializer. Make sure we track indicators for cleanup. | 261 * Generic YUI initializer. Make sure we track indicators for cleanup. |
162 * | 262 * |
163 * @method initializer | 263 * @method initializer |
164 * @param {Object} cfg configuration object. | 264 * @param {Object} cfg configuration object. |
165 * | 265 * |
166 */ | 266 */ |
167 initializer: function(cfg) { | 267 initializer: function(cfg) { |
168 // Hold onto references of the indicators used so we can clean them all | 268 // Hold onto references of the indicators used so we can clean them all |
169 // up. Indicators are keyed on their yuiid so we don't dupe them. | 269 // up. Indicators are keyed on their yuiid so we don't dupe them. |
170 this.indicators = {}; | 270 this.indicators = {}; |
| 271 this._events = []; |
171 }, | 272 }, |
172 | 273 |
173 /** | 274 /** |
174 * Render out the view to the DOM. | 275 * Render out the view to the DOM. |
175 * | 276 * |
176 * @method render | 277 * @method render |
177 * @param {Node} container optional specific container to render out to. | 278 * @param {Node} container optional specific container to render out to. |
178 * | 279 * |
179 */ | 280 */ |
180 render: function(container) { | 281 render: function(container) { |
181 var tpl = this.template(this.get('charm').getAttrs()), | 282 var tpl = this.template(this.get('charm').getAttrs()), |
182 tplNode = Y.Node.create(tpl); | 283 tplNode = Y.Node.create(tpl); |
183 | 284 |
184 container.setHTML(tplNode); | 285 container.setHTML(tplNode); |
185 | 286 |
186 // Allow for specifying the container to use. This should reset the | 287 // Allow for specifying the container to use. This should reset the |
187 // events. | 288 // events. |
188 if (container) { | 289 if (container) { |
189 this.set('container', container); | 290 this.set('container', container); |
190 } | 291 } |
191 | 292 |
192 this.tabview = new widgets.browser.TabView({ | 293 this.tabview = new widgets.browser.TabView({ |
193 srcNode: tplNode.one('.tabs') | 294 srcNode: tplNode.one('.tabs') |
194 }); | 295 }); |
195 this.tabview.render(); | 296 this.tabview.render(); |
| 297 this._dispatchTabEvents(this.tabview); |
196 | 298 |
197 // Start loading the readme so it's ready to go. | 299 // Start loading the readme so it's ready to go. |
198 var readme = this._locateReadme(); | 300 var readme = this._locateReadme(); |
199 | 301 |
200 if (readme) { | 302 if (readme) { |
201 this._loadFile(tplNode.one('#bws_readme'), | 303 this._loadFile(tplNode.one('#bws_readme'), |
202 readme | 304 readme |
203 ); | 305 ); |
204 } else { | 306 } else { |
205 this._noReadme(tplNode.one('#bws_readme')); | 307 this._noReadme(tplNode.one('#bws_readme')); |
(...skipping 28 matching lines...) Expand all Loading... |
234 requires: [ | 336 requires: [ |
235 'browser-overlay-indicator', | 337 'browser-overlay-indicator', |
236 'browser-tabview', | 338 'browser-tabview', |
237 'gallery-markdown', | 339 'gallery-markdown', |
238 'juju-templates', | 340 'juju-templates', |
239 'juju-views', | 341 'juju-views', |
240 'prettify', | 342 'prettify', |
241 'view' | 343 'view' |
242 ] | 344 ] |
243 }); | 345 }); |
OLD | NEW |