step1_controller.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  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. var arrayUtils = require('utils/array_utils');
  20. /**
  21. * @typedef {Em.Object} StackType
  22. * @property {string} stackName
  23. * @property {App.Stack[]} stacks
  24. * @property {boolean} isSelected
  25. * @property {boolean} defaultStackAllowedToSelect
  26. */
  27. /**
  28. * @type {Em.Object}
  29. */
  30. var StackType = Em.Object.extend({
  31. stackName: '',
  32. stacks: [],
  33. isSelected: Em.computed.someBy('stacks', 'isSelected', true),
  34. defaultStackAllowedToSelect: Em.computed.equal('stacks.length', 1),
  35. visibleStacks: function () {
  36. var stacks = this.get('stacks');
  37. return this.get('defaultStackAllowedToSelect') ? stacks : stacks.filterProperty('stackDefault', false);
  38. }.property('defaultStackAllowedToSelect', 'stacks.[]')
  39. });
  40. App.WizardStep1Controller = Em.Controller.extend({
  41. name: 'wizardStep1Controller',
  42. /**
  43. * Skip repo-validation
  44. *
  45. * @type {bool}
  46. */
  47. skipValidationChecked: false,
  48. /**
  49. * @type {App.Stack}
  50. */
  51. selectedStack: Em.computed.findBy('content.stacks', 'isSelected', true),
  52. /**
  53. * @type {App.ServiceSimple[]}
  54. */
  55. servicesForSelectedStack: Em.computed.filterBy('selectedStack.stackServices', 'isHidden', false),
  56. /**
  57. * Some network issues exist if there is no stack with <code>stackDefault</code> = false
  58. *
  59. * @type {boolean}
  60. */
  61. networkIssuesExist: Em.computed.everyBy('content.stacks', 'stackDefault', true),
  62. optionsToSelect: {
  63. 'usePublicRepo': {
  64. index: 0,
  65. isSelected: true
  66. },
  67. 'useLocalRepo': {
  68. index: 1,
  69. isSelected: false,
  70. 'uploadFile': {
  71. index: 0,
  72. name: 'uploadFile',
  73. file: '',
  74. hasError: false,
  75. isSelected: true
  76. },
  77. 'enterUrl': {
  78. index: 1,
  79. name: 'enterUrl',
  80. url: '',
  81. placeholder: Em.I18n.t('installer.step1.useLocalRepo.enterUrl.placeholder'),
  82. hasError: false,
  83. isSelected: false
  84. }
  85. }
  86. },
  87. /**
  88. * Checks if user selected to input url or upload file but didn't do it
  89. * true - url-radio is checked but url-field is empty
  90. * - file-radio is checked but file is not selected
  91. * false - otherwise
  92. *
  93. * @type {boolean}
  94. */
  95. readInfoIsNotProvided: function () {
  96. var useLocalRepo = this.get('optionsToSelect.useLocalRepo');
  97. if(Em.get(useLocalRepo, 'uploadFile.isSelected')) {
  98. return !Em.get(useLocalRepo, 'uploadFile.file');
  99. }
  100. if (Em.get(useLocalRepo, 'enterUrl.isSelected')) {
  101. return !Em.get(useLocalRepo, 'enterUrl.url');
  102. }
  103. return false;
  104. }.property('optionsToSelect.useLocalRepo.isSelected', 'optionsToSelect.useLocalRepo.uploadFile.isSelected',
  105. 'optionsToSelect.useLocalRepo.uploadFile.file', 'optionsToSelect.useLocalRepo.enterUrl.url'),
  106. /**
  107. * List of stacks grouped by <code>stackNameVersion</code>
  108. *
  109. * @type {StackType[]}
  110. */
  111. availableStackTypes: function () {
  112. var stacks = this.get('content.stacks');
  113. return stacks ? stacks.mapProperty('stackNameVersion').uniq().sort().reverse().map(function (stackName) {
  114. return StackType.create({
  115. stackName: stackName,
  116. stacks: stacks.filterProperty('stackNameVersion', stackName).sort(arrayUtils.sortByIdAsVersion).reverse()
  117. })
  118. }) : [];
  119. }.property('content.stacks.@each.stackNameVersion'),
  120. /**
  121. * @type {StackType}
  122. */
  123. selectedStackType: Em.computed.findBy('availableStackTypes', 'isSelected', true),
  124. /**
  125. * Load selected file to current page content
  126. */
  127. readVersionInfo: function () {
  128. var data = {};
  129. var isXMLdata = false;
  130. if (this.get("optionsToSelect.useLocalRepo.enterUrl.isSelected")) {
  131. var url = this.get("optionsToSelect.useLocalRepo.enterUrl.url");
  132. data = {
  133. VersionDefinition: {
  134. version_url: url
  135. }
  136. };
  137. App.db.setLocalRepoVDFData(url);
  138. }
  139. else {
  140. if (this.get("optionsToSelect.useLocalRepo.uploadFile.isSelected")) {
  141. isXMLdata = true;
  142. // load from file browser
  143. data = this.get("optionsToSelect.useLocalRepo.uploadFile.file");
  144. App.db.setLocalRepoVDFData(data);
  145. }
  146. }
  147. return App.router.get('installerController').postVersionDefinitionFile(isXMLdata, data);
  148. },
  149. /**
  150. * On click handler for removing OS
  151. */
  152. removeOS: function (event) {
  153. if (this.get('selectedStack.useRedhatSatellite')) {
  154. return;
  155. }
  156. var osToRemove = event.context;
  157. Em.set(osToRemove, 'isSelected', false);
  158. },
  159. /**
  160. * On click handler for adding new OS
  161. */
  162. addOS: function (event) {
  163. var osToAdd = event.context;
  164. Em.set(osToAdd, 'isSelected', true);
  165. },
  166. /**
  167. * Use Local Repo if some network issues exist
  168. */
  169. onNetworkIssuesExist: function() {
  170. if (this.get('networkIssuesExist')) {
  171. this.useLocalRepo();
  172. }
  173. }.observes('networkIssuesExist'),
  174. /**
  175. * Select stack with field equal to the value
  176. * Example:
  177. * <pre>
  178. * selectStackBy('id', 'HDP-2.5-2.5.0.0'); // select stack with id = 'HDP-2.5-2.5.0.0'
  179. * selectStackBy('stackNameVersion', 'HDP-2.5'); // select first stack with stackNameVersion = 'HDP-2.5'
  180. * </pre>
  181. *
  182. * @param {string} field
  183. * @param {string} value
  184. */
  185. selectStackBy: function (field, value) {
  186. this.get('content.stacks').setEach('isSelected', false);
  187. this.get('content.stacks').findProperty(field, value).set('isSelected', true);
  188. },
  189. /**
  190. * Restore base urls for selected stack when user select to use public repository
  191. */
  192. usePublicRepo: function () {
  193. var selectedStack = this.get('selectedStack');
  194. if (selectedStack) {
  195. selectedStack.setProperties({
  196. useRedhatSatellite: false,
  197. usePublicRepo: true,
  198. useLocalRepo: false
  199. });
  200. selectedStack.restoreReposBaseUrls();
  201. }
  202. },
  203. /**
  204. * Clean base urls for selected stack when user select to use local repository
  205. */
  206. useLocalRepo: function () {
  207. var selectedStack = this.get('selectedStack');
  208. if (selectedStack) {
  209. selectedStack.setProperties({
  210. usePublicRepo: false,
  211. useLocalRepo: true
  212. });
  213. selectedStack.cleanReposBaseUrls();
  214. }
  215. },
  216. /**
  217. * Restores url value to be its default value.
  218. * @method doRestoreDefaultValue
  219. */
  220. doRestoreDefaultValue: function (event) {
  221. var repo = event.contexts[0];
  222. repo.set('baseUrl', repo.get('latestBaseUrl'));
  223. },
  224. /**
  225. * Restores url value to empty string.
  226. * @method doRestoreToEmpty
  227. */
  228. doRestoreToEmpty: function (event) {
  229. var repo = event.contexts[0];
  230. repo.set('baseUrl', '');
  231. },
  232. /**
  233. * Click-handler for left-tabs with stack types
  234. * Select first available stack with stackName equal to chosen
  235. *
  236. * @param {{context: StackType}} event
  237. */
  238. selectRepoInList: function (event) {
  239. var id = this.get('availableStackTypes').findProperty('stackName', event.context.stackName).get('stacks.firstObject.id');
  240. this.selectStackBy('id', id);
  241. },
  242. /**
  243. * Click-handler for StackVersion-tabs
  244. *
  245. * @param {{context: App.Stack}} event
  246. */
  247. changeVersion: function (event) {
  248. this.selectStackBy('id', event.context.get('id'));
  249. },
  250. /**
  251. * Show popup with options to upload new version
  252. *
  253. * @returns {App.ModalPopup}
  254. */
  255. uploadVdf: function () {
  256. return App.ModalPopup.show({
  257. controller: this,
  258. header: Em.I18n.t('installer.step1.changeVersion.title'),
  259. primary: Em.I18n.t('installer.step1.useLocalRepo.readButton'),
  260. disablePrimary: Em.computed.alias('controller.readInfoIsNotProvided'),
  261. /**
  262. * Try to read version info from the url or file (if provided)
  263. */
  264. onPrimary: function () {
  265. var controller = this.get('controller');
  266. controller.readVersionInfo().done(function (response) {
  267. // load successfully, so make this local stack repo as selectedStack
  268. var newStackId = response.stackNameVersion + '-' + response.actualVersion;
  269. var oldStackNameVersion = controller.get('selectedStack.stackNameVersion');
  270. controller.selectStackBy('id', newStackId);
  271. if (oldStackNameVersion && oldStackNameVersion !== response.stackNameVersion) {
  272. App.showAlertPopup(Em.I18n.t('common.warning'), Em.I18n.t('installer.step1.addVersion.stackChanged.popup.body').format(oldStackNameVersion, response.stackNameVersion));
  273. }
  274. Ember.run.next(function () {
  275. $("[rel=skip-validation-tooltip]").tooltip({placement: 'right'});
  276. $("[rel=use-redhat-tooltip]").tooltip({placement: 'right'});
  277. });
  278. });
  279. this.restoreUploadOptions();
  280. this._super();
  281. },
  282. /**
  283. * Disable url/file fields on popup-close
  284. */
  285. onSecondary: function () {
  286. this.restoreUploadOptions();
  287. this._super();
  288. },
  289. /**
  290. * Disable url/file fields on popup-close
  291. */
  292. onClose: function () {
  293. this.restoreUploadOptions();
  294. this._super();
  295. },
  296. /**
  297. * Deselect file/url radio
  298. */
  299. restoreUploadOptions: function () {
  300. this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', false);
  301. this.set('controller.optionsToSelect.useLocalRepo.enterUrl.url', '');
  302. this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', true);
  303. this.set('controller.optionsToSelect.useLocalRepo.uploadFile.file', '');
  304. },
  305. bodyClass: Em.View.extend({
  306. controller: this,
  307. templateName: require('templates/wizard/step1/vdf_upload'),
  308. /**
  309. * Wrapper for 'upload-file' elements
  310. *
  311. * @type {Em.View}
  312. */
  313. uploadFileView: Em.View.extend({
  314. classNames: ['clearfix'],
  315. /**
  316. * Checkbox for Use local Repo > Upload VDF file
  317. *
  318. * @type {Ember.Checkbox}
  319. */
  320. uploadFileRadioButton: Em.Checkbox.extend({
  321. attributeBindings: ['type', 'checked'],
  322. checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected'),
  323. type: 'radio'
  324. }),
  325. /**
  326. * Is File API available
  327. *
  328. * @type {bool}
  329. */
  330. isFileApi: window.File && window.FileReader && window.FileList,
  331. /**
  332. * Upload file is disabled when some stack is selected or url-field is selected
  333. *
  334. * @type {boolean}
  335. */
  336. fileBrowserDisabled: Em.computed.alias('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected'),
  337. /**
  338. * Input to select vdf-file
  339. *
  340. * @type {Em.View}
  341. */
  342. fileInputView: Em.View.extend({
  343. template: Em.Handlebars.compile('<input type="file" {{bindAttr class="controller.optionsToSelect.useLocalRepo.enterUrl.isSelected:disabled"}} />'),
  344. classNames: ['vdf-input-indentation'],
  345. change: function (e) {
  346. var self = this;
  347. if (e.target.files && e.target.files.length === 1) {
  348. var file = e.target.files[0];
  349. var reader = new FileReader();
  350. reader.onload = (function () {
  351. return function (event) {
  352. self.set('controller.optionsToSelect.useLocalRepo.uploadFile.file', event.target.result);
  353. };
  354. })(file);
  355. reader.readAsText(file);
  356. }
  357. }
  358. }),
  359. click: function () {
  360. if (!this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected')) {
  361. this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', false);
  362. this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', true);
  363. this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false);
  364. this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false);
  365. }
  366. }
  367. }),
  368. /**
  369. * Wrapper for 'enter-url' elements
  370. *
  371. * @type {Em.View}
  372. */
  373. enterUrlView: Em.View.extend({
  374. /**
  375. * Url-field is disable when some stack is selected or upload file is selected
  376. *
  377. * @type {boolean}
  378. */
  379. enterUrlFieldDisabled: Em.computed.alias('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected'),
  380. /**
  381. * Input for file upload
  382. *
  383. * @type {Em.TextField}
  384. */
  385. enterUrlField: Em.TextField.extend({
  386. classNameBindings: [':input-block-level', 'controller.optionsToSelect.useLocalRepo.uploadFile.isSelected:disabled']
  387. }),
  388. /**
  389. * Checkbox for Use local Repo > Enter Url of VDF file
  390. *
  391. * @type {Ember.Checkbox}
  392. */
  393. enterUrlRadioButton: Em.Checkbox.extend({
  394. attributeBindings: [ 'type', 'checked' ],
  395. checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected'),
  396. type: 'radio',
  397. }),
  398. click: function () {
  399. if (!this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected')) {
  400. this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', true);
  401. this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', false);
  402. this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false);
  403. this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false);
  404. }
  405. }
  406. })
  407. })
  408. });
  409. }
  410. });