step3_view.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. App.WizardStep3View = App.TableView.extend({
  20. templateName: require('templates/wizard/step3'),
  21. /**
  22. * List of hosts
  23. * Same to <code>controller.hosts</code>
  24. * @type {Ember.Enumerable}
  25. */
  26. content:function () {
  27. return this.get('controller.hosts');
  28. }.property('controller.hosts.length'),
  29. /**
  30. * Message with info about registration result
  31. * @type {string}
  32. */
  33. message:'',
  34. /**
  35. * Text to link for hosts' warnings popup
  36. * @type {string}
  37. */
  38. linkText: '',
  39. /**
  40. * Registration status
  41. * @type {string}
  42. */
  43. status: '',
  44. /**
  45. * Active category
  46. * @type {string}
  47. */
  48. selectedCategory: function() {
  49. return this.get('categories').findProperty('isActive');
  50. }.property('categories.@each.isActive'),
  51. /**
  52. * Message about other registered hosts (not included in current registration)
  53. * @type {string}
  54. */
  55. registeredHostsMessage: '',
  56. /**
  57. * Number of visible hosts on page
  58. * @type {string}
  59. */
  60. displayLength: "25",
  61. /**
  62. * All checkboxes on page are checked
  63. * @type {bool}
  64. */
  65. pageChecked: false,
  66. /**
  67. * bootStatus category object
  68. * @type {Ember.Object}
  69. */
  70. categoryObject: Em.Object.extend({
  71. hostsCount: 0,
  72. label: function () {
  73. return "%@ (%@)".fmt(this.get('value'), this.get('hostsCount'));
  74. }.property('value', 'hostsCount'),
  75. isActive: false,
  76. itemClass: function () {
  77. return this.get('isActive') ? 'active' : '';
  78. }.property('isActive')
  79. }),
  80. /**
  81. * List of bootStatus categories
  82. * @type {categoryObject[]}
  83. */
  84. categories: function () {
  85. return [
  86. this.categoryObject.create({value: Em.I18n.t('common.all'), hostsBootStatus: 'ALL', isActive: true}),
  87. this.categoryObject.create({value: Em.I18n.t('installer.step3.hosts.status.installing'), hostsBootStatus: 'RUNNING'}),
  88. this.categoryObject.create({value: Em.I18n.t('installer.step3.hosts.status.registering'), hostsBootStatus: 'REGISTERING'}),
  89. this.categoryObject.create({value: Em.I18n.t('common.success'), hostsBootStatus: 'REGISTERED' }),
  90. this.categoryObject.create({value: Em.I18n.t('common.fail'), hostsBootStatus: 'FAILED', last: true })
  91. ];
  92. }.property(),
  93. didInsertElement: function () {
  94. this.get('controller').loadStep();
  95. },
  96. /**
  97. * Select checkboxes of hosts on page
  98. * @method onPageChecked
  99. */
  100. onPageChecked: function () {
  101. if (this.get('selectionInProgress')) return;
  102. this.get('pageContent').setEach('isChecked', this.get('pageChecked'));
  103. }.observes('pageChecked'),
  104. /**
  105. * Select checkboxes of all hosts
  106. * @method selectAll
  107. */
  108. selectAll: function () {
  109. this.get('content').setEach('isChecked', true);
  110. },
  111. /**
  112. * Reset checkbox of all hosts
  113. * @method unSelectAll
  114. */
  115. unSelectAll: function() {
  116. this.get('content').setEach('isChecked', false);
  117. },
  118. /**
  119. * Call <code>watchSelection</code> only once
  120. * @method watchSelectionOnce
  121. */
  122. watchSelectionOnce: function () {
  123. Em.run.once(this, 'watchSelection');
  124. }.observes('content.@each.isChecked', 'pageContent'),
  125. /**
  126. * Watch selection and calculate such flags as:
  127. * <ul>
  128. * <li>noHostsSelected</li>
  129. * <li>selectedHostsCount</li>
  130. * <li>pageChecked</li>
  131. * </ul>
  132. * @method watchSelection
  133. */
  134. watchSelection: function() {
  135. this.set('selectionInProgress', true);
  136. this.set('pageChecked', !!this.get('pageContent.length') && this.get('pageContent').everyProperty('isChecked', true));
  137. this.set('selectionInProgress', false);
  138. var noHostsSelected = true;
  139. var selectedHostsCount = 0;
  140. this.get('content').forEach(function(host){
  141. selectedHostsCount += host.get('isChecked') ? 1 : 0;
  142. noHostsSelected = (noHostsSelected) ? !host.get('isChecked') : noHostsSelected;
  143. });
  144. this.set('noHostsSelected', noHostsSelected);
  145. this.set('selectedHostsCount', selectedHostsCount);
  146. },
  147. /**
  148. * Update <code>registeredHostsMessage</code> according to <code>controller.registeredHots.length</code>
  149. * @method setRegisteredHosts
  150. */
  151. setRegisteredHosts: function(){
  152. this.set('registeredHostsMessage',Em.I18n.t('installer.step3.warning.registeredHosts').format(this.get('controller.registeredHosts').length));
  153. }.observes('controller.registeredHosts'),
  154. /**
  155. * Call filters and counters one time
  156. * @method hostBootStatusObserver
  157. */
  158. hostBootStatusObserver: function(){
  159. Em.run.once(this, 'countCategoryHosts');
  160. Em.run.once(this, 'filter');
  161. Em.run.once(this, 'monitorStatuses');
  162. }.observes('content.@each.bootStatus'),
  163. /**
  164. * Calculate host count grouped by <code>bootStatus</code>
  165. * @method countCategoryHosts
  166. */
  167. countCategoryHosts: function () {
  168. var counters = {
  169. "RUNNING": 0,
  170. "REGISTERING": 0,
  171. "REGISTERED": 0,
  172. "FAILED": 0
  173. };
  174. this.get('content').forEach(function (host) {
  175. if (!Em.isNone(counters[host.get('bootStatus')])) {
  176. counters[host.get('bootStatus')]++;
  177. }
  178. }, this);
  179. counters["ALL"] = this.get('content.length');
  180. this.get('categories').forEach(function(category) {
  181. category.set('hostsCount', counters[category.get('hostsBootStatus')]);
  182. }, this);
  183. },
  184. /**
  185. * Filter hosts by category
  186. * @method filter
  187. */
  188. filter: function () {
  189. var self = this;
  190. Em.run.next(function () {
  191. self.doFilter();
  192. });
  193. }.observes('selectedCategory'),
  194. /**
  195. * Real filter-method
  196. * Called from <code>filter</code> in Em.run.next-wrapper
  197. * @method doFilter
  198. */
  199. doFilter: function() {
  200. var result = [];
  201. var selectedCategory = this.get('selectedCategory');
  202. if (!selectedCategory || selectedCategory.get('hostsBootStatus') === 'ALL') {
  203. result = this.get('content');
  204. } else {
  205. result = this.get('content').filterProperty('bootStatus', this.get('selectedCategory.hostsBootStatus'));
  206. }
  207. this.set('filteredContent', result);
  208. },
  209. /**
  210. * Trigger on Category click
  211. * @param {Object} event
  212. * @method selectCategory
  213. */
  214. selectCategory: function (event) {
  215. var categoryStatus = event.context.get('hostsBootStatus');
  216. this.get('categories').forEach(function (category) {
  217. category.set('isActive', (category.get('hostsBootStatus') === categoryStatus));
  218. });
  219. this.watchSelection();
  220. },
  221. /**
  222. * Select "All" hosts category
  223. * run registration of failed hosts again
  224. * @method retrySelectedHosts
  225. */
  226. retrySelectedHosts: function () {
  227. var eventObject = {context: Em.Object.create({hostsBootStatus: 'ALL'})};
  228. this.selectCategory(eventObject);
  229. this.get('controller').retrySelectedHosts();
  230. },
  231. /**
  232. * Update <code>status</code>, <code>linkText</code>, <code>message</code> according to hosts statuses
  233. * @method monitorStatuses
  234. */
  235. monitorStatuses: function() {
  236. var hosts = this.get('controller.bootHosts');
  237. var failedHosts = hosts.filterProperty('bootStatus', 'FAILED').length;
  238. if (hosts.length === 0) {
  239. this.set('status', 'alert-warn');
  240. this.set('linkText', '');
  241. this.set('message', Em.I18n.t('installer.step3.warnings.missingHosts'));
  242. }
  243. else {
  244. if (!this.get('controller.isWarningsLoaded')) {
  245. this.set('status', 'alert-info');
  246. this.set('linkText', '');
  247. this.set('message', Em.I18n.t('installer.step3.warning.loading'));
  248. }
  249. else {
  250. if (this.get('controller.isHostHaveWarnings') || this.get('controller.repoCategoryWarnings.length') || this.get('controller.diskCategoryWarnings.length')) {
  251. this.set('status', 'alert-warn');
  252. this.set('linkText', Em.I18n.t('installer.step3.warnings.linkText'));
  253. this.set('message', Em.I18n.t('installer.step3.warnings.fails').format(hosts.length - failedHosts));
  254. }
  255. else {
  256. this.set('status', 'alert-success');
  257. this.set('linkText', Em.I18n.t('installer.step3.noWarnings.linkText'));
  258. if (failedHosts == 0) {
  259. // all are ok
  260. this.set('message', Em.I18n.t('installer.step3.warnings.noWarnings').format(hosts.length));
  261. }
  262. else {
  263. if (failedHosts == hosts.length) {
  264. // all failed
  265. this.set('status', 'alert-warn');
  266. this.set('linkText', '');
  267. this.set('message', Em.I18n.t('installer.step3.warnings.allFailed').format(failedHosts));
  268. }
  269. else {
  270. // some failed
  271. this.set('message', Em.I18n.t('installer.step3.warnings.someWarnings').format((hosts.length - failedHosts), failedHosts));
  272. }
  273. }
  274. }
  275. }
  276. }
  277. }.observes('controller.isWarningsLoaded', 'controller.isHostHaveWarnings', 'controller.repoCategoryWarnings', 'controller.diskCategoryWarnings')
  278. });
  279. //todo: move it inside WizardStep3View
  280. App.WizardHostView = Em.View.extend({
  281. tagName: 'tr',
  282. classNameBindings: ['hostInfo.bootStatus'],
  283. /**
  284. * Host from parent view
  285. * @type {Object}
  286. */
  287. hostInfo: null,
  288. /**
  289. * @type {bool}
  290. */
  291. isRetryable: function() {
  292. // return ['FAILED'].contains(this.get('hostInfo.bootStatus'));
  293. return false;
  294. }.property('hostInfo.bootStatus'),
  295. /**
  296. * Remove selected host
  297. * @method remove
  298. */
  299. remove: function () {
  300. this.get('controller').removeHost(this.get('hostInfo'));
  301. },
  302. /**
  303. * Retry register selected host
  304. * @method retry
  305. */
  306. retry: function() {
  307. this.get('controller').retryHost(this.get('hostInfo'));
  308. }
  309. });