/**
* 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');
/**
* Mixin for host select view on step 5 install wizard
* Implements base login for select, input types
* Each view which use this mixin should redefine method changeHandler
(with
* observing controller.hostNameCheckTrigger
)
*
* @type {Ember.Mixin}
*/
App.SelectHost = Em.Mixin.create({
/**
* Element of controller.servicesMasters
* Binded from template
* @type {object}
*/
component: null,
/**
* List of avaiable host names
* @type {string[]}
*/
content: [],
/**
* Host component name
* @type {string}
*/
componentName: null,
/**
* Handler for selected value change
* Triggers changeHandler
execution
* @method change
*/
change: function () {
if ('destroyed' === this.get('state')) return;
this.set('controller.lastChangedComponent', this.get('component.component_name'));
this.get('controller').toggleProperty('hostNameCheckTrigger');
},
/**
* Add or remove error
class from parent div-element
* @param {bool} flag true - add class, false - remove
* @method updateErrorStatus
*/
updateErrorStatus: function(flag) {
var parentBlock = this.$().parent('div');
/* istanbul ignore next */
if (flag) {
parentBlock.removeClass('error');
}
else {
parentBlock.addClass('error');
}
},
/**
* If component is multiple (defined in controller.multipleComponents
),
* should update controller.componentToRebalance
and trigger rebalancing
* @method tryTriggerRebalanceForMultipleComponents
*/
tryTriggerRebalanceForMultipleComponents: function() {
var componentIsMultiple = this.get('controller.multipleComponents').contains(this.get("component.component_name"));
if(componentIsMultiple) {
this.get('controller').set('componentToRebalance', this.get("component.component_name"));
this.get('controller').incrementProperty('rebalanceComponentHostsCounter');
}
},
/**
* Handler for value changing
* Should be redeclared in child views
* Each redeclarion should contains code:
*
* if (!this.shouldChangeHandlerBeCalled()) return;
*
* @method changeHandler
*/
changeHandler: function() {}.observes('controller.hostNameCheckTrigger'),
/**
* If view is destroyed or not current component's host name was changed we should do nothing
* This method should be called from changeHandler
:
*
* changeHandler: function() {
* if (!this.shouldChangeHandlerBeCalled()) return;
* // your code
* }.observes(...)
*
* @returns {boolean}
* @method shouldChangeHandlerBeCalled
*/
shouldChangeHandlerBeCalled: function() {
return !(('destroyed' === this.get('state')) || (this.get('controller.lastChangedComponent') !== this.get("component.component_name")));
},
/**
* If component.isHostNameValid
was changed,
* error status should be updated according to new value
* @method isHostNameValidObs
*/
isHostNameValidObs: function() {
this.updateErrorStatus(this.get('component.isHostNameValid'));
}.observes('component.isHostNameValid'),
/**
* Recalculate available hosts
* This should be done only once per Ember loop
* @method rebalanceComponentHosts
*/
rebalanceComponentHosts: function () {
Em.run.once(this, 'rebalanceComponentHostsOnce');
}.observes('controller.rebalanceComponentHostsCounter'),
/**
* Recalculate available hosts
* @method rebalanceComponentHostsOnce
*/
rebalanceComponentHostsOnce: function() {
if (this.get('component.component_name') === this.get('controller.componentToRebalance')) {
this.initContent();
}
},
/**
* Get available hosts
* multipleComponents component can be assigned to multiple hosts,
* shared hosts among the same component should be filtered out
* @return {string[]}
* @method getAvailableHosts
*/
getAvailableHosts: function () {
var hosts = this.get('controller.hosts').slice(),
componentName = this.get('component.component_name'),
multipleComponents = this.get('controller.multipleComponents'),
occupiedHosts = this.get('controller.selectedServicesMasters')
.filterProperty('component_name', componentName)
.mapProperty('selectedHost')
.without(this.get('component.selectedHost'));
if (multipleComponents.contains(componentName)) {
return hosts.filter(function (host) {
return !occupiedHosts.contains(host.get('host_name'));
}, this);
}
return hosts;
},
/**
* Extract hosts from controller,
* filter out available to selection and
* push them into form element content
* @method initContent
*/
initContent: function () {
this.set("content", this.getAvailableHosts());
}
});