/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var App = require('app'); var arrayUtils = require('utils/array_utils'); /** * @typedef {Em.Object} StackType * @property {string} stackName * @property {App.Stack[]} stacks * @property {boolean} isSelected * @property {boolean} defaultStackAllowedToSelect */ /** * @type {Em.Object} */ var StackType = Em.Object.extend({ stackName: '', stacks: [], isSelected: Em.computed.someBy('stacks', 'isSelected', true), defaultStackAllowedToSelect: Em.computed.equal('stacks.length', 1), visibleStacks: function () { var stacks = this.get('stacks'); return this.get('defaultStackAllowedToSelect') ? stacks : stacks.filterProperty('stackDefault', false); }.property('defaultStackAllowedToSelect', 'stacks.[]') }); App.WizardStep1Controller = Em.Controller.extend({ name: 'wizardStep1Controller', /** * Skip repo-validation * * @type {bool} */ skipValidationChecked: false, /** * @type {App.Stack} */ selectedStack: Em.computed.findBy('content.stacks', 'isSelected', true), /** * @type {App.ServiceSimple[]} */ servicesForSelectedStack: Em.computed.filterBy('selectedStack.stackServices', 'isHidden', false), /** * Some network issues exist if there is no stack with stackDefault = false * * @type {boolean} */ networkIssuesExist: Em.computed.everyBy('content.stacks', 'stackDefault', true), optionsToSelect: { 'usePublicRepo': { index: 0, isSelected: true }, 'useLocalRepo': { index: 1, isSelected: false, 'uploadFile': { index: 0, name: 'uploadFile', file: '', hasError: false, isSelected: true }, 'enterUrl': { index: 1, name: 'enterUrl', url: '', placeholder: Em.I18n.t('installer.step1.useLocalRepo.enterUrl.placeholder'), hasError: false, isSelected: false } } }, /** * Checks if user selected to input url or upload file but didn't do it * true - url-radio is checked but url-field is empty * - file-radio is checked but file is not selected * false - otherwise * * @type {boolean} */ readInfoIsNotProvided: function () { var useLocalRepo = this.get('optionsToSelect.useLocalRepo'); if(Em.get(useLocalRepo, 'uploadFile.isSelected')) { return !Em.get(useLocalRepo, 'uploadFile.file'); } if (Em.get(useLocalRepo, 'enterUrl.isSelected')) { return !Em.get(useLocalRepo, 'enterUrl.url'); } return false; }.property('optionsToSelect.useLocalRepo.isSelected', 'optionsToSelect.useLocalRepo.uploadFile.isSelected', 'optionsToSelect.useLocalRepo.uploadFile.file', 'optionsToSelect.useLocalRepo.enterUrl.url'), /** * List of stacks grouped by stackNameVersion * * @type {StackType[]} */ availableStackTypes: function () { var stacks = this.get('content.stacks'); return stacks ? stacks.mapProperty('stackNameVersion').uniq().sort().reverse().map(function (stackName) { return StackType.create({ stackName: stackName, stacks: stacks.filterProperty('stackNameVersion', stackName).sort(arrayUtils.sortByIdAsVersion).reverse() }) }) : []; }.property('content.stacks.@each.stackNameVersion'), /** * @type {StackType} */ selectedStackType: Em.computed.findBy('availableStackTypes', 'isSelected', true), /** * Load selected file to current page content */ readVersionInfo: function () { var data = {}; var isXMLdata = false; if (this.get("optionsToSelect.useLocalRepo.enterUrl.isSelected")) { var url = this.get("optionsToSelect.useLocalRepo.enterUrl.url"); data = { VersionDefinition: { version_url: url } }; App.db.setLocalRepoVDFData(url); } else { if (this.get("optionsToSelect.useLocalRepo.uploadFile.isSelected")) { isXMLdata = true; // load from file browser data = this.get("optionsToSelect.useLocalRepo.uploadFile.file"); App.db.setLocalRepoVDFData(data); } } return App.router.get('installerController').postVersionDefinitionFile(isXMLdata, data); }, /** * On click handler for removing OS */ removeOS: function (event) { if (this.get('selectedStack.useRedhatSatellite')) { return; } var osToRemove = event.context; Em.set(osToRemove, 'isSelected', false); }, /** * On click handler for adding new OS */ addOS: function (event) { var osToAdd = event.context; Em.set(osToAdd, 'isSelected', true); }, /** * Use Local Repo if some network issues exist */ onNetworkIssuesExist: function() { if (this.get('networkIssuesExist')) { this.useLocalRepo(); } }.observes('networkIssuesExist'), /** * Select stack with field equal to the value * Example: *
   *   selectStackBy('id', 'HDP-2.5-2.5.0.0'); // select stack with id = 'HDP-2.5-2.5.0.0'
   *   selectStackBy('stackNameVersion', 'HDP-2.5'); // select first stack with stackNameVersion = 'HDP-2.5'
   * 
* * @param {string} field * @param {string} value */ selectStackBy: function (field, value) { this.get('content.stacks').setEach('isSelected', false); this.get('content.stacks').findProperty(field, value).set('isSelected', true); }, /** * Restore base urls for selected stack when user select to use public repository */ usePublicRepo: function () { var selectedStack = this.get('selectedStack'); if (selectedStack) { selectedStack.setProperties({ useRedhatSatellite: false, usePublicRepo: true, useLocalRepo: false }); selectedStack.restoreReposBaseUrls(); } }, /** * Clean base urls for selected stack when user select to use local repository */ useLocalRepo: function () { var selectedStack = this.get('selectedStack'); if (selectedStack) { selectedStack.setProperties({ usePublicRepo: false, useLocalRepo: true }); selectedStack.cleanReposBaseUrls(); } }, /** * Restores url value to be its default value. * @method doRestoreDefaultValue */ doRestoreDefaultValue: function (event) { var repo = event.contexts[0]; repo.set('baseUrl', repo.get('latestBaseUrl')); }, /** * Restores url value to empty string. * @method doRestoreToEmpty */ doRestoreToEmpty: function (event) { var repo = event.contexts[0]; repo.set('baseUrl', ''); }, /** * Click-handler for left-tabs with stack types * Select first available stack with stackName equal to chosen * * @param {{context: StackType}} event */ selectRepoInList: function (event) { var id = this.get('availableStackTypes').findProperty('stackName', event.context.stackName).get('stacks.firstObject.id'); this.selectStackBy('id', id); }, /** * Click-handler for StackVersion-tabs * * @param {{context: App.Stack}} event */ changeVersion: function (event) { this.selectStackBy('id', event.context.get('id')); }, /** * Show popup with options to upload new version * * @returns {App.ModalPopup} */ uploadVdf: function () { return App.ModalPopup.show({ controller: this, header: Em.I18n.t('installer.step1.changeVersion.title'), primary: Em.I18n.t('installer.step1.useLocalRepo.readButton'), disablePrimary: Em.computed.alias('controller.readInfoIsNotProvided'), /** * Try to read version info from the url or file (if provided) */ onPrimary: function () { var controller = this.get('controller'); controller.readVersionInfo().done(function (response) { // load successfully, so make this local stack repo as selectedStack var newStackId = response.stackNameVersion + '-' + response.actualVersion; var oldStackNameVersion = controller.get('selectedStack.stackNameVersion'); controller.selectStackBy('id', newStackId); if (oldStackNameVersion && oldStackNameVersion !== response.stackNameVersion) { App.showAlertPopup(Em.I18n.t('common.warning'), Em.I18n.t('installer.step1.addVersion.stackChanged.popup.body').format(oldStackNameVersion, response.stackNameVersion)); } Ember.run.next(function () { $("[rel=skip-validation-tooltip]").tooltip({placement: 'right'}); $("[rel=use-redhat-tooltip]").tooltip({placement: 'right'}); }); }); this.restoreUploadOptions(); this._super(); }, /** * Disable url/file fields on popup-close */ onSecondary: function () { this.restoreUploadOptions(); this._super(); }, /** * Disable url/file fields on popup-close */ onClose: function () { this.restoreUploadOptions(); this._super(); }, /** * Deselect file/url radio */ restoreUploadOptions: function () { this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', false); this.set('controller.optionsToSelect.useLocalRepo.enterUrl.url', ''); this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', true); this.set('controller.optionsToSelect.useLocalRepo.uploadFile.file', ''); }, bodyClass: Em.View.extend({ controller: this, templateName: require('templates/wizard/step1/vdf_upload'), /** * Wrapper for 'upload-file' elements * * @type {Em.View} */ uploadFileView: Em.View.extend({ classNames: ['clearfix'], /** * Checkbox for Use local Repo > Upload VDF file * * @type {Ember.Checkbox} */ uploadFileRadioButton: Em.Checkbox.extend({ attributeBindings: ['type', 'checked'], checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected'), type: 'radio' }), /** * Is File API available * * @type {bool} */ isFileApi: window.File && window.FileReader && window.FileList, /** * Upload file is disabled when some stack is selected or url-field is selected * * @type {boolean} */ fileBrowserDisabled: Em.computed.alias('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected'), /** * Input to select vdf-file * * @type {Em.View} */ fileInputView: Em.View.extend({ template: Em.Handlebars.compile(''), classNames: ['vdf-input-indentation'], change: function (e) { var self = this; if (e.target.files && e.target.files.length === 1) { var file = e.target.files[0]; var reader = new FileReader(); reader.onload = (function () { return function (event) { self.set('controller.optionsToSelect.useLocalRepo.uploadFile.file', event.target.result); }; })(file); reader.readAsText(file); } } }), click: function () { if (!this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected')) { this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', false); this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', true); this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false); this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false); } } }), /** * Wrapper for 'enter-url' elements * * @type {Em.View} */ enterUrlView: Em.View.extend({ /** * Url-field is disable when some stack is selected or upload file is selected * * @type {boolean} */ enterUrlFieldDisabled: Em.computed.alias('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected'), /** * Input for file upload * * @type {Em.TextField} */ enterUrlField: Em.TextField.extend({ classNameBindings: [':input-block-level', 'controller.optionsToSelect.useLocalRepo.uploadFile.isSelected:disabled'] }), /** * Checkbox for Use local Repo > Enter Url of VDF file * * @type {Ember.Checkbox} */ enterUrlRadioButton: Em.Checkbox.extend({ attributeBindings: [ 'type', 'checked' ], checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected'), type: 'radio', }), click: function () { if (!this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected')) { this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', true); this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', false); this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false); this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false); } } }) }) }); } });