fuel-web/nailgun/static/component_mixins.jsx

112 lines
4.6 KiB
JavaScript

/*
* Copyright 2014 Mirantis, Inc.
*
* Licensed 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.
**/
define(['jquery', 'underscore', 'backbone', 'dispatcher', 'react', 'react.backbone'], function($, _, Backbone, dispatcher, React) {
'use strict';
return {
backboneMixin: React.BackboneMixin,
dispatcherMixin: function(events, callback) {
return {
componentDidMount: function() {
dispatcher.on(events, _.isString(callback) ? this[callback] : callback, this);
},
componentWillUnmount: function() {
dispatcher.off(null, null, this);
}
};
},
pollingMixin: function(updateInterval, delayedStart) {
updateInterval = updateInterval * 1000;
return {
scheduleDataFetch: function() {
var shouldDataBeFetched = !_.isFunction(this.shouldDataBeFetched) || this.shouldDataBeFetched();
if (this.isMounted() && !this.activeTimeout && shouldDataBeFetched) {
this.activeTimeout = _.delay(this.startPolling, updateInterval);
}
},
startPolling: function(force) {
var shouldDataBeFetched = force || !_.isFunction(this.shouldDataBeFetched) || this.shouldDataBeFetched();
if (shouldDataBeFetched) {
this.stopPolling();
return this.fetchData().always(this.scheduleDataFetch);
}
},
stopPolling: function() {
if (this.activeTimeout) clearTimeout(this.activeTimeout);
delete this.activeTimeout;
},
componentDidMount: function() {
if (delayedStart) {
this.scheduleDataFetch();
} else {
this.startPolling();
}
},
componentWillUnmount: function() {
this.stopPolling();
}
};
},
outerClickMixin: {
propTypes: {
toggle: React.PropTypes.func.isRequired
},
getInitialState: function() {
return {
clickEventName: 'click.' + _.uniqueId('outer-click')
};
},
handleBodyClick: function(e) {
if (!$(e.target).closest(this.getDOMNode()).length) {
_.defer(_.partial(this.props.toggle, false));
}
},
componentDidMount: function() {
$('html').on(this.state.clickEventName, this.handleBodyClick);
Backbone.history.on('route', _.partial(this.props.toggle, false), this);
},
componentWillUnmount: function() {
$('html').off(this.state.clickEventName);
Backbone.history.off('route', null, this);
}
},
nodeConfigurationScreenMixin: {
goToNodeList: function(cluster) {
if (!cluster) cluster = this.props.cluster;
app.navigate('#cluster/' + cluster.id + '/nodes', {trigger: true, replace: true});
},
isLockedScreen: function() {
var nodesAvailableForChanges = this.props.nodes.any(function(node) {
return node.get('pending_addition') || node.get('status') == 'error';
});
return !nodesAvailableForChanges ||
this.props.cluster && !!this.props.cluster.tasks({group: 'deployment', status: 'running'}).length;
},
showDiscardChangesDialog: function() {
var dialogs = require('jsx!views/dialogs');
dialogs.DiscardSettingsChangesDialog.show({cb: this.goToNodeList});
},
returnToNodeList: function() {
if (this.hasChanges()) {
this.showDiscardChangesDialog();
} else {
this.goToNodeList();
}
}
}
};
});