Merge "[Upgrading to ES2015 syntax] Switch to named exports for modules"

This commit is contained in:
Jenkins 2016-01-14 14:37:19 +00:00 committed by Gerrit Code Review
commit ab94af2f45
31 changed files with 364 additions and 374 deletions

View File

@ -21,9 +21,9 @@ import Backbone from 'backbone';
import React from 'react';
import ReactDOM from 'react-dom';
import models from 'models';
import {NailgunUnavailabilityDialog} from 'views/dialogs';
import KeystoneClient from 'keystone_client';
import RootComponent from 'views/root';
import dialogs from 'views/dialogs';
import LoginPage from 'views/login_page.js';
import WelcomePage from 'views/welcome_page';
import ClusterPage from 'views/cluster_page';
@ -198,7 +198,7 @@ import './styles/main.less';
return $.Deferred().resolve();
} else {
this.mountNode.empty();
dialogs.NailgunUnavailabilityDialog.show({}, {preventDuplicate: true});
NailgunUnavailabilityDialog.show({}, {preventDuplicate: true});
}
})
.then(() => Backbone.history.start());

View File

@ -18,14 +18,14 @@ import _ from 'underscore';
import Backbone from 'backbone';
import i18n from 'i18n';
import React from 'react';
import dispatcher from 'dispatcher';
import ReactDOM from 'react-dom';
import dispatcher from 'dispatcher';
import {DiscardSettingsChangesDialog} from 'views/dialogs';
import 'react.backbone';
import dialogs from 'views/dialogs';
var componentMixins = {
backboneMixin: React.BackboneMixin,
dispatcherMixin(events, callback) {
export var backboneMixin = React.BackboneMixin;
export function dispatcherMixin(events, callback) {
return {
componentDidMount() {
dispatcher.on(events, _.isString(callback) ? this[callback] : callback, this);
@ -34,8 +34,9 @@ import dialogs from 'views/dialogs';
dispatcher.off(null, null, this);
}
};
},
unsavedChangesMixin: {
}
export var unsavedChangesMixin = {
onBeforeunloadEvent() {
if (this.hasChanges()) return _.result(this, 'getStayMessage') || i18n('dialog.dismiss_settings.default_message');
},
@ -53,7 +54,7 @@ import dialogs from 'views/dialogs';
if (Backbone.history.getHash() != href.substr(1) && _.result(this, 'hasChanges')) {
e.preventDefault();
dialogs.DiscardSettingsChangesDialog
DiscardSettingsChangesDialog
.show({
isDiscardingPossible: _.result(this, 'isDiscardingPossible'),
isSavingPossible: _.result(this, 'isSavingPossible'),
@ -64,8 +65,9 @@ import dialogs from 'views/dialogs';
});
}
}
},
pollingMixin(updateInterval, delayedStart) {
};
export function pollingMixin(updateInterval, delayedStart) {
updateInterval = updateInterval * 1000;
return {
scheduleDataFetch() {
@ -96,8 +98,9 @@ import dialogs from 'views/dialogs';
this.stopPolling();
}
};
},
outerClickMixin: {
}
export var outerClickMixin = {
propTypes: {
toggle: React.PropTypes.func.isRequired
},
@ -119,8 +122,9 @@ import dialogs from 'views/dialogs';
$('html').off(this.state.clickEventName);
Backbone.history.off('route', null, this);
}
},
renamingMixin(refname) {
};
export function renamingMixin(refname) {
return {
getInitialState() {
return {
@ -151,6 +155,3 @@ import dialogs from 'views/dialogs';
}
};
}
};
export default componentMixins;

View File

@ -18,8 +18,8 @@ import $ from 'jquery';
import i18n from 'i18n';
import _ from 'underscore';
import dispatcher from 'dispatcher';
import controls from 'views/controls';
import componentMixins from 'component_mixins';
import {Input, Tooltip} from 'views/controls';
import {unsavedChangesMixin} from 'component_mixins';
import VmWareModels from 'plugins/vmware/vmware_models';
var Field = React.createClass({
@ -39,7 +39,7 @@ import VmWareModels from 'plugins/vmware/vmware_models';
var metadata = this.props.metadata,
value = this.props.model.get(metadata.name);
return (
<controls.Input
<Input
{... _.pick(metadata, 'name', 'type', 'label', 'description')}
value={metadata.type == 'select' ? value.current.id : value}
checked={value}
@ -51,7 +51,7 @@ import VmWareModels from 'plugins/vmware/vmware_models';
{metadata.type == 'select' && value.options.map((value) => {
return <option key={value.id} value={value.id}>{value.label}</option>;
})}
</controls.Input>
</Input>
);
}
});
@ -87,9 +87,9 @@ import VmWareModels from 'plugins/vmware/vmware_models';
<h3>
{this.props.title}
{this.props.tooltipText &&
<controls.Tooltip text={this.props.tooltipText} placement='right'>
<Tooltip text={this.props.tooltipText} placement='right'>
<i className='glyphicon glyphicon-warning-sign tooltip-icon' />
</controls.Tooltip>
</Tooltip>
}
</h3>
<FieldGroup model={this.props.model} disabled={this.props.disabled}/>
@ -226,9 +226,9 @@ import VmWareModels from 'plugins/vmware/vmware_models';
<h3>
{i18n('vmware.availability_zones')}
{this.props.tooltipText &&
<controls.Tooltip text={this.props.tooltipText} placement='right'>
<Tooltip text={this.props.tooltipText} placement='right'>
<i className='glyphicon glyphicon-warning-sign tooltip-icon' />
</controls.Tooltip>
</Tooltip>
}
</h3>
{this.props.collection.map(function(model) {
@ -269,7 +269,7 @@ import VmWareModels from 'plugins/vmware/vmware_models';
var VmWareTab = React.createClass({
mixins: [
componentMixins.unsavedChangesMixin
unsavedChangesMixin
],
statics: {
isVisible(cluster) {

View File

@ -13,11 +13,12 @@
* License for the specific language governing permissions and limitations
* under the License.
**/
import controls from 'views/controls';
import {Input} from 'views/controls';
var input;
suite('File Control', () => {
setup(() => {
input = new controls.Input({
input = new Input({
type: 'file',
name: 'some_file',
label: 'Please select some file',

View File

@ -22,7 +22,7 @@ import naturalSort from 'javascript-natural-sort';
import Expression from 'expression';
import ModelPath from 'expression/objects';
import IP from 'ip';
import dialogs from 'views/dialogs';
import {ErrorDialog} from 'views/dialogs';
import models from 'models';
var utils = {
@ -100,7 +100,7 @@ import models from 'models';
showErrorDialog(options) {
options.message = options.response ? utils.getResponseText(options.response) :
options.message || i18n('dialog.error_dialog.server_error');
dialogs.ErrorDialog.show(options);
ErrorDialog.show(options);
},
showBandwidth(bandwidth) {
bandwidth = parseInt(bandwidth, 10);

View File

@ -18,13 +18,13 @@ import _ from 'underscore';
import i18n from 'i18n';
import React from 'react';
import models from 'models';
import componentMixins from 'component_mixins';
import controls from 'views/controls';
import {backboneMixin, pollingMixin} from 'component_mixins';
import {ProgressBar, Table} from 'views/controls';
var CapacityPage = React.createClass({
mixins: [
componentMixins.backboneMixin('capacityLog'),
componentMixins.pollingMixin(2)
backboneMixin('capacityLog'),
pollingMixin(2)
],
statics: {
title: i18n('capacity_page.title'),
@ -53,7 +53,7 @@ import controls from 'views/controls';
{!capacityLog.isNew() ?
<LicenseUsage capacityLog={capacityLog} />
:
<controls.ProgressBar />
<ProgressBar />
}
</div>
</div>
@ -69,26 +69,26 @@ import controls from 'views/controls';
return (
<div>
<h3>{i18n('capacity_page.license_usage')}</h3>
<controls.Table
<Table
head={[{label: i18n('capacity_page.fuel_version'), className: headClassName},
{label: i18n('capacity_page.fuel_uuid')}]}
body={[[capacityReport.fuel_data.release, capacityReport.fuel_data.uuid]]}
tableClassName={tableClassName}
/>
<controls.Table
<Table
head={[{label: i18n('capacity_page.env_name'), className: headClassName},
{label: i18n('capacity_page.node_count')}]}
body={_.map(capacityReport.environment_stats, _.values)}
tableClassName={tableClassName}
/>
<controls.Table
<Table
head={[{label: i18n('capacity_page.total_number_alloc_nodes'), className: headClassName},
{label: i18n('capacity_page.total_number_unalloc_nodes')}]}
body={[[capacityReport.allocation_stats.allocated,
capacityReport.allocation_stats.unallocated]]}
tableClassName={tableClassName}
/>
<controls.Table
<Table
head={[{label: i18n('capacity_page.node_role'), className: headClassName},
{label: i18n('capacity_page.nodes_with_config')}]}
body={_.zip(_.keys(capacityReport.roles_stat),

View File

@ -20,7 +20,7 @@ import React from 'react';
import utils from 'utils';
import models from 'models';
import dispatcher from 'dispatcher';
import componentMixins from 'component_mixins';
import {backboneMixin, pollingMixin, dispatcherMixin} from 'component_mixins';
import DashboardTab from 'views/cluster_page_tabs/dashboard_tab';
import NodesTab from 'views/cluster_page_tabs/nodes_tab';
import NetworkTab from 'views/cluster_page_tabs/network_tab';
@ -31,24 +31,24 @@ import {VmWareTab, VmWareModels} from 'plugins/vmware/vmware';
var ClusterPage = React.createClass({
mixins: [
componentMixins.pollingMixin(5),
componentMixins.backboneMixin('cluster', 'change:name change:is_customized change:release'),
componentMixins.backboneMixin({
pollingMixin(5),
backboneMixin('cluster', 'change:name change:is_customized change:release'),
backboneMixin({
modelOrCollection(props) {return props.cluster.get('nodes');}
}),
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {return props.cluster.get('tasks');},
renderOn: 'update change'
}),
componentMixins.dispatcherMixin('networkConfigurationUpdated', 'removeFinishedNetworkTasks'),
componentMixins.dispatcherMixin('deploymentTasksUpdated', 'removeFinishedDeploymentTasks'),
componentMixins.dispatcherMixin('deploymentTaskStarted', function() {
dispatcherMixin('networkConfigurationUpdated', 'removeFinishedNetworkTasks'),
dispatcherMixin('deploymentTasksUpdated', 'removeFinishedDeploymentTasks'),
dispatcherMixin('deploymentTaskStarted', function() {
this.refreshCluster().always(this.startPolling);
}),
componentMixins.dispatcherMixin('networkVerificationTaskStarted', function() {
dispatcherMixin('networkVerificationTaskStarted', function() {
this.startPolling();
}),
componentMixins.dispatcherMixin('deploymentTaskFinished', function() {
dispatcherMixin('deploymentTaskFinished', function() {
this.refreshCluster().always(() => dispatcher.trigger('updateNotifications'));
})
],

View File

@ -20,31 +20,31 @@ import React from 'react';
import ReactDOM from 'react-dom';
import utils from 'utils';
import dispatcher from 'dispatcher';
import controls from 'views/controls';
import dialogs from 'views/dialogs';
import componentMixins from 'component_mixins';
import {Input, ProgressBar, Tooltip} from 'views/controls';
import {DiscardNodeChangesDialog, DeployChangesDialog, ProvisionVMsDialog, RemoveClusterDialog, ResetEnvironmentDialog, StopDeploymentDialog} from 'views/dialogs';
import {backboneMixin, pollingMixin, renamingMixin} from 'component_mixins';
var namespace = 'cluster_page.dashboard_tab.';
var DashboardTab = React.createClass({
mixins: [
// this is needed to somehow handle the case when verification is in progress and user pressed Deploy
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {
return props.cluster.get('tasks');
},
renderOn: 'update change'
}),
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {return props.cluster.get('nodes');},
renderOn: 'update change'
}),
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {return props.cluster.get('pluginLinks');},
renderOn: 'update change'
}),
componentMixins.backboneMixin('cluster', 'change'),
componentMixins.pollingMixin(20, true)
backboneMixin('cluster', 'change'),
pollingMixin(20, true)
],
fetchData() {
return this.props.cluster.get('nodes').fetch();
@ -202,17 +202,17 @@ import componentMixins from 'component_mixins';
</strong>
{i18n('cluster_page.' + taskName) + '...'}
</h4>
<controls.ProgressBar progress={!isInfiniteTask && taskProgress} />
<ProgressBar progress={!isInfiniteTask && taskProgress} />
{showStopButton &&
<controls.Tooltip text={i18n('cluster_page.stop_deployment_button')}>
<Tooltip text={i18n('cluster_page.stop_deployment_button')}>
<button
className='btn btn-danger btn-xs pull-right stop-deployment-btn'
onClick={_.partial(this.showDialog, dialogs.StopDeploymentDialog)}
onClick={_.partial(this.showDialog, StopDeploymentDialog)}
disabled={!task.isStoppable()}
>
{i18n(namespace + 'stop')}
</button>
</controls.Tooltip>
</Tooltip>
}
</div>
</div>
@ -311,13 +311,13 @@ import componentMixins from 'component_mixins';
var DeployReadinessBlock = React.createClass({
mixins: [
// this is needed to somehow handle the case when verification is in progress and user pressed Deploy
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {
return props.cluster.get('tasks');
},
renderOn: 'update change'
}),
componentMixins.backboneMixin('cluster', 'change')
backboneMixin('cluster', 'change')
],
ns: 'dialog.display_changes.',
getConfigModels() {
@ -454,7 +454,7 @@ import componentMixins from 'component_mixins';
{i18n('dialog.display_changes.' + dictKey, {count: nodes.length})}
<button
className='btn btn-link btn-discard-changes'
onClick={_.partial(this.showDialog, dialogs.DiscardNodeChangesDialog, {nodes: nodes})}
onClick={_.partial(this.showDialog, DiscardNodeChangesDialog, {nodes: nodes})}
>
<i className='discard-changes-icon' />
</button>
@ -485,7 +485,7 @@ import componentMixins from 'component_mixins';
{isVMsProvisioningAvailable ?
<button
className='btn btn-primary deploy-btn'
onClick={_.partial(this.showDialog, dialogs.ProvisionVMsDialog)}
onClick={_.partial(this.showDialog, ProvisionVMsDialog)}
>
<div className='deploy-icon' />
{i18n('cluster_page.provision_vms')}
@ -496,7 +496,7 @@ import componentMixins from 'component_mixins';
'btn btn-primary deploy-btn': true,
'btn-warning': _.isEmpty(alerts.blocker) && (!_.isEmpty(alerts.error) || !_.isEmpty(alerts.warning))
})}
onClick={_.partial(this.showDialog, dialogs.DeployChangesDialog)}
onClick={_.partial(this.showDialog, DeployChangesDialog)}
disabled={!isDeploymentPossible}
>
<div className='deploy-icon' />
@ -546,7 +546,7 @@ import componentMixins from 'component_mixins';
});
var ClusterInfo = React.createClass({
mixins: [componentMixins.renamingMixin('clustername')],
mixins: [renamingMixin('clustername')],
getClusterValue(fieldName) {
var cluster = this.props.cluster,
settings = cluster.get('settings');
@ -858,7 +858,7 @@ import componentMixins from 'component_mixins';
return (
<div className={utils.classNames(classes)}>
<div className='action-body' onKeyDown={this.handleKeyDown}>
<controls.Input
<Input
type='text'
disabled={this.state.disabled}
className={utils.classNames({'form-control': true, error: this.state.error})}
@ -881,8 +881,8 @@ import componentMixins from 'component_mixins';
var ResetEnvironmentAction = React.createClass({
mixins: [
componentMixins.backboneMixin('cluster'),
componentMixins.backboneMixin('task')
backboneMixin('cluster'),
backboneMixin('task')
],
getDescriptionKey() {
if (this.props.task) {
@ -894,7 +894,7 @@ import componentMixins from 'component_mixins';
},
applyAction(e) {
e.preventDefault();
dialogs.ResetEnvironmentDialog.show({cluster: this.props.cluster});
ResetEnvironmentDialog.show({cluster: this.props.cluster});
},
render() {
var isLocked = this.props.cluster.get('status') == 'new' || !!this.props.task;
@ -907,13 +907,13 @@ import componentMixins from 'component_mixins';
>
{i18n(namespace + 'reset_environment')}
</button>
<controls.Tooltip
<Tooltip
key='reset-tooltip'
placement='right'
text={!isLocked ? i18n(namespace + 'reset_environment_warning') : i18n(namespace + this.getDescriptionKey())}
>
<i className='glyphicon glyphicon-info-sign' />
</controls.Tooltip>
</Tooltip>
</div>
);
}
@ -922,7 +922,7 @@ import componentMixins from 'component_mixins';
var DeleteEnvironmentAction = React.createClass({
applyAction(e) {
e.preventDefault();
dialogs.RemoveClusterDialog.show({cluster: this.props.cluster});
RemoveClusterDialog.show({cluster: this.props.cluster});
},
render() {
return (
@ -933,13 +933,13 @@ import componentMixins from 'component_mixins';
>
{i18n(namespace + 'delete_environment')}
</button>
<controls.Tooltip
<Tooltip
key='delete-tooltip'
placement='right'
text={i18n(namespace + 'alert_delete')}
>
<i className='glyphicon glyphicon-info-sign' />
</controls.Tooltip>
</Tooltip>
</div>
);
}

View File

@ -20,16 +20,16 @@ import Backbone from 'backbone';
import React from 'react';
import utils from 'utils';
import models from 'models';
import controls from 'views/controls';
import componentMixins from 'component_mixins';
import {Input} from 'views/controls';
import {backboneMixin, pollingMixin} from 'component_mixins';
var HealthCheckTab = React.createClass({
mixins: [
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {return props.cluster.get('tasks');},
renderOn: 'update change:status'
}),
componentMixins.backboneMixin('cluster', 'change:status')
backboneMixin('cluster', 'change:status')
],
statics: {
fetchData(options) {
@ -80,10 +80,10 @@ import componentMixins from 'component_mixins';
var HealthcheckTabContent = React.createClass({
mixins: [
componentMixins.backboneMixin('tests', 'update change'),
componentMixins.backboneMixin('testsets', 'update change:checked'),
componentMixins.backboneMixin('testruns', 'update change'),
componentMixins.pollingMixin(3)
backboneMixin('tests', 'update change'),
backboneMixin('testsets', 'update change:checked'),
backboneMixin('testruns', 'update change'),
pollingMixin(3)
],
shouldDataBeFetched() {
return this.props.testruns.any({status: 'running'});
@ -203,7 +203,7 @@ import componentMixins from 'component_mixins';
{!disabledState &&
<div className='healthcheck-controls row well well-sm'>
<div className='pull-left'>
<controls.Input
<Input
type='checkbox'
name='selectAll'
onChange={this.handleSelectAllClick}
@ -275,7 +275,7 @@ import componentMixins from 'component_mixins';
{i18n('cluster_page.healthcheck_tab.credentials_description')}
</div>
{_.map(inputFields, function(name) {
return (<controls.Input
return (<Input
key={name}
type={(name == 'password') ? 'password' : 'text'}
name={name}
@ -296,8 +296,8 @@ import componentMixins from 'component_mixins';
var TestSet = React.createClass({
mixins: [
componentMixins.backboneMixin('tests'),
componentMixins.backboneMixin('testset')
backboneMixin('tests'),
backboneMixin('testset')
],
handleTestSetCheck(name, value) {
this.props.testset.set('checked', value);
@ -322,7 +322,7 @@ import componentMixins from 'component_mixins';
<thead>
<tr>
<th>
<controls.Input
<Input
type='checkbox'
id={'testset-checkbox-' + this.props.testset.id}
name={this.props.testset.get('name')}
@ -368,7 +368,7 @@ import componentMixins from 'component_mixins';
var Test = React.createClass({
mixins: [
componentMixins.backboneMixin('test')
backboneMixin('test')
],
handleTestCheck(name, value) {
this.props.test.set('checked', value);
@ -390,7 +390,7 @@ import componentMixins from 'component_mixins';
return (
<tr>
<td>
<controls.Input
<Input
type='checkbox'
id={'test-checkbox-' + test.id}
name={test.get('name')}

View File

@ -19,14 +19,14 @@ import i18n from 'i18n';
import React from 'react';
import utils from 'utils';
import models from 'models';
import controls from 'views/controls';
import componentMixins from 'component_mixins';
import {Input, ProgressBar} from 'views/controls';
import {pollingMixin} from 'component_mixins';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ReactFragment from 'react-addons-create-fragment';
var LogsTab = React.createClass({
mixins: [
componentMixins.pollingMixin(5)
pollingMixin(5)
],
shouldDataBeFetched() {
return this.state.to && this.state.logsEntries;
@ -116,7 +116,7 @@ import ReactFragment from 'react-addons-create-fragment';
{this.state.loadingError}
</div>
}
{this.state.loading == 'loading' && <controls.ProgressBar />}
{this.state.loading == 'loading' && <ProgressBar />}
{this.state.logsEntries &&
<LogsTable
logsEntries={this.state.logsEntries}
@ -280,7 +280,7 @@ import ReactFragment from 'react-addons-create-fragment';
return <option value={type[0]} key={type[0]}>{type[1]}</option>;
});
return <div className='col-md-2 col-sm-3'>
<controls.Input
<Input
type='select'
label={i18n('cluster_page.logs_tab.logs')}
value={this.state.type}
@ -298,7 +298,7 @@ import ReactFragment from 'react-addons-create-fragment';
});
return <div className='col-md-2 col-sm-3'>
<controls.Input
<Input
type='select'
label={i18n('cluster_page.logs_tab.node')}
value={this.state.node}
@ -312,7 +312,7 @@ import ReactFragment from 'react-addons-create-fragment';
renderSourceSelect() {
var sourceOptions = this.state.type == 'local' ? this.getLocalSources() : this.getRemoteSources();
return <div className='col-md-2 col-sm-3'>
<controls.Input
<Input
type='select'
label={i18n('cluster_page.logs_tab.source')}
value={this.state.source}
@ -332,7 +332,7 @@ import ReactFragment from 'react-addons-create-fragment';
});
}
return <div className='col-md-2 col-sm-3'>
<controls.Input
<Input
type='select'
label={i18n('cluster_page.logs_tab.min_level')}
value={this.state.level}

View File

@ -22,9 +22,9 @@ import ReactDOM from 'react-dom';
import utils from 'utils';
import models from 'models';
import dispatcher from 'dispatcher';
import dialogs from 'views/dialogs';
import componentMixins from 'component_mixins';
import controls from 'views/controls';
import {CreateNodeNetworkGroupDialog, RemoveNodeNetworkGroupDialog} from 'views/dialogs';
import {backboneMixin, dispatcherMixin, unsavedChangesMixin, renamingMixin} from 'component_mixins';
import {Input, RadioGroup, Table} from 'views/controls';
import SettingSection from 'views/cluster_page_tabs/setting_section';
import CSSTransitionGroup from 'react-addons-transition-group';
@ -83,7 +83,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
},
renderInput(attribute, isInteger, additionalProps = {}) {
return (
<controls.Input
<Input
{...additionalProps}
{...this.composeProps(attribute, false, isInteger)}
type='text'
@ -252,7 +252,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
var rangeError = _.findWhere(error, {index: index}) || {};
return (
<div className='range-row clearfix' key={index}>
<controls.Input
<Input
{...this.getRangeProps()}
error={(rangeError.start || verificationError) ? '' : null}
value={range[0]}
@ -261,7 +261,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
inputClassName='start'
placeholder={rangeError.start ? '' : this.props.placeholder}
/>
<controls.Input
<Input
{...this.getRangeProps(true)}
error={rangeError.end ? '' : null}
value={range[1]}
@ -281,13 +281,13 @@ import CSSTransitionGroup from 'react-addons-transition-group';
}, this)
:
<div className='range-row clearfix'>
<controls.Input
<Input
{...this.getRangeProps()}
value={ranges[0]}
error={startInputError ? '' : null}
inputClassName='start'
/>
<controls.Input
<Input
{...this.getRangeProps(true)}
disabled={this.props.disabled || !!this.props.autoIncreaseWith}
value={ranges[1]}
@ -329,7 +329,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
return (
<div className={'vlan-tagging form-group ' + this.props.name}>
<label className='vlan-tag-label'>{this.props.label}</label>
<controls.Input {...this.props}
<Input {...this.props}
onChange={this.onTaggingChange}
type='checkbox'
checked={!_.isNull(this.props.value)}
@ -337,7 +337,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
label={null}
/>
{!_.isNull(this.props.value) &&
<controls.Input {...this.props}
<Input {...this.props}
ref={this.props.name}
onChange={this.onInputChange}
type='text'
@ -361,14 +361,14 @@ import CSSTransitionGroup from 'react-addons-transition-group';
return (
<div className='form-group cidr'>
<label>{i18n(networkTabNS + 'network.cidr')}</label>
<controls.Input
<Input
{...this.props}
type='text'
label={null}
onChange={this.onCidrChange}
wrapperClassName='pull-left'
/>
<controls.Input
<Input
type='checkbox'
checked={this.props.network.get('meta').notation == 'cidr'}
label={i18n(networkTabNS + 'network.use_whole_cidr')}
@ -460,7 +460,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
var inputError = (this.props.error || {})[index];
return (
<div className='range-row clearfix' key={attributeName + index}>
<controls.Input
<Input
type='text'
disabled={this.props.disabled}
name={attributeName}
@ -485,39 +485,39 @@ import CSSTransitionGroup from 'react-addons-transition-group';
mixins: [
NetworkInputsMixin,
NetworkModelManipulationMixin,
componentMixins.backboneMixin('cluster', 'change:status'),
componentMixins.backboneMixin('nodeNetworkGroups', 'change update'),
componentMixins.backboneMixin({
backboneMixin('cluster', 'change:status'),
backboneMixin('nodeNetworkGroups', 'change update'),
backboneMixin({
modelOrCollection(props) {
return props.cluster.get('networkConfiguration').get('networking_parameters');
},
renderOn: 'change'
}),
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {
return props.cluster.get('networkConfiguration').get('networks');
},
renderOn: 'change reset update'
}),
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {
return props.cluster.get('tasks');
},
renderOn: 'update change:status'
}),
componentMixins.dispatcherMixin('hideNetworkVerificationResult', function() {
dispatcherMixin('hideNetworkVerificationResult', function() {
this.setState({hideVerificationResult: true});
}),
componentMixins.dispatcherMixin('networkConfigurationUpdated', function() {
dispatcherMixin('networkConfigurationUpdated', function() {
this.setState({hideVerificationResult: false});
}),
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {
return props.cluster.get('settings');
},
renderOn: 'change invalid'
}),
componentMixins.unsavedChangesMixin
unsavedChangesMixin
],
statics: {
fetchData(options) {
@ -799,7 +799,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
},
removeNodeNetworkGroup() {
var nodeNetworkGroup = this.nodeNetworkGroups.find({name: this.props.activeNetworkSectionName});
dialogs.RemoveNodeNetworkGroupDialog
RemoveNodeNetworkGroupDialog
.show({
showUnsavedChangesWarning: this.hasChanges()
})
@ -825,7 +825,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
});
return;
}
dialogs.CreateNodeNetworkGroupDialog
CreateNodeNetworkGroupDialog
.show({
clusterId: this.props.cluster.id,
nodeNetworkGroups: this.nodeNetworkGroups
@ -921,7 +921,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
</div>
{isNovaEnvironment &&
<div className='col-xs-12 forms-box nova-managers'>
<controls.RadioGroup
<RadioGroup
key='net_provider'
name='net_provider'
values={managers}
@ -1146,7 +1146,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
var NodeNetworkGroupTitle = React.createClass({
mixins: [
componentMixins.renamingMixin('node-group-title-input')
renamingMixin('node-group-title-input')
],
onNodeNetworkGroupNameKeyDown(e) {
this.setState({nodeNetworkGroupNameChangingError: null});
@ -1200,7 +1200,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
return (
<div className={utils.classNames(classes)} key={currentNodeNetworkGroup.id}>
{this.state.isRenaming ?
<controls.Input
<Input
type='text'
ref='node-group-title-input'
name='new-name'
@ -1271,7 +1271,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
verificationError={_.contains(this.props.verificationErrorField, 'ip_ranges')}
/>
{meta.use_gateway &&
<controls.Input
<Input
{...gatewayProps}
type='text'
disabled={gatewayProps.disabled || meta.notation == 'cidr'}
@ -1313,7 +1313,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
{this.renderInput('fixed_networks_cidr')}
{(manager == 'VlanManager') ?
<div>
<controls.Input
<Input
{...this.composeProps('fixed_network_size', false, true)}
type='select'
children={_.map(fixedNetworkSizeValues, (value) => {
@ -1598,7 +1598,7 @@ import CSSTransitionGroup from 'react-addons-transition-group';
}
{(task && !!task.get('result').length) &&
<div className='verification-result-table col-xs-12'>
<controls.Table
<Table
tableClassName='table table-condensed enable-selection'
noStripes
head={_.map(['node_name', 'node_mac_address', 'node_interface', 'expected_vlan'],

View File

@ -18,7 +18,7 @@ import $ from 'jquery';
import _ from 'underscore';
import React from 'react';
import ReactDOM from 'react-dom';
import controls from 'views/controls';
import {ProgressBar} from 'views/controls';
import ClusterNodesScreen from 'views/cluster_page_tabs/nodes_tab_screens/cluster_nodes_screen';
import AddNodesScreen from 'views/cluster_page_tabs/nodes_tab_screens/add_nodes_screen';
import EditNodesScreen from 'views/cluster_page_tabs/nodes_tab_screens/edit_nodes_screen';
@ -134,7 +134,7 @@ import ReactTransitionGroup from 'react-addons-transition-group';
if (this.props.loading) return (
<div className='row'>
<div className='col-xs-12' style={{paddingTop: '40px'}}>
<controls.ProgressBar />
<ProgressBar />
</div>
</div>
);

View File

@ -21,15 +21,15 @@ import React from 'react';
import ReactDOM from 'react-dom';
import utils from 'utils';
import models from 'models';
import ComponentMixins from 'component_mixins';
import controls from 'views/controls';
import {backboneMixin, unsavedChangesMixin} from 'component_mixins';
import {Input} from 'views/controls';
var EditNodeDisksScreen = React.createClass({
mixins: [
ComponentMixins.backboneMixin('cluster', 'change:status change:nodes sync'),
ComponentMixins.backboneMixin('nodes', 'change sync'),
ComponentMixins.backboneMixin('disks', 'reset change'),
ComponentMixins.unsavedChangesMixin
backboneMixin('cluster', 'change:status change:nodes sync'),
backboneMixin('nodes', 'change sync'),
backboneMixin('disks', 'reset change'),
unsavedChangesMixin
],
statics: {
fetchData(options) {
@ -329,14 +329,14 @@ import controls from 'views/controls';
{volume.get('label')}
</label>
<div className='col-xs-4 volume-group-range'>
<controls.Input {...props}
<Input {...props}
type='range'
ref={'range-' + volumeName}
onChange={_.partialRight(this.updateDisk)}
value={value}
/>
</div>
<controls.Input {...props}
<Input {...props}
type='number'
wrapperClassName='col-xs-3 volume-group-input'
onChange={_.partialRight(this.updateDisk)}

View File

@ -21,19 +21,19 @@ import i18n from 'i18n';
import utils from 'utils';
import models from 'models';
import dispatcher from 'dispatcher';
import controls from 'views/controls';
import ComponentMixins from 'component_mixins';
import OffloadingModes from 'views/cluster_page_tabs/nodes_tab_screens/offloading_modes_control';
import {Input} from 'views/controls';
import {backboneMixin, unsavedChangesMixin} from 'component_mixins';
import {DragSource, DropTarget} from 'react-dnd';
var ns = 'cluster_page.nodes_tab.configure_interfaces.';
var EditNodeInterfacesScreen = React.createClass({
mixins: [
ComponentMixins.backboneMixin('interfaces', 'change reset update'),
ComponentMixins.backboneMixin('cluster'),
ComponentMixins.backboneMixin('nodes', 'change reset update'),
ComponentMixins.unsavedChangesMixin
backboneMixin('interfaces', 'change reset update'),
backboneMixin('cluster'),
backboneMixin('nodes', 'change reset update'),
unsavedChangesMixin
],
statics: {
fetchData(options) {
@ -530,8 +530,8 @@ import {DragSource, DropTarget} from 'react-dnd';
}
},
mixins: [
ComponentMixins.backboneMixin('interface'),
ComponentMixins.backboneMixin({
backboneMixin('interface'),
backboneMixin({
modelOrCollection(props) {
return props.interface.get('assigned_networks');
}
@ -661,7 +661,7 @@ import {DragSource, DropTarget} from 'react-dnd';
'no-checkbox': !bondingPossible
})}>
{bondingPossible ?
<controls.Input
<Input
type='checkbox'
label={ifc.get('name')}
onChange={this.bondingChanged}
@ -671,7 +671,7 @@ import {DragSource, DropTarget} from 'react-dnd';
: ifc.get('name')
}
</div>
<controls.Input
<Input
type='select'
disabled={!bondingPossible}
onChange={this.bondingModeChanged}
@ -681,7 +681,7 @@ import {DragSource, DropTarget} from 'react-dnd';
wrapperClassName='pull-right'
/>
{this.isHashPolicyNeeded() &&
<controls.Input
<Input
type='select'
value={bondProperties.xmit_hash_policy}
disabled={!bondingPossible}
@ -692,7 +692,7 @@ import {DragSource, DropTarget} from 'react-dnd';
/>
}
{this.isLacpRateAvailable() &&
<controls.Input
<Input
type='select'
value={bondProperties.lacp_rate}
disabled={!bondingPossible}
@ -709,7 +709,7 @@ import {DragSource, DropTarget} from 'react-dnd';
<div className='col-xs-3'>
<div className='ifc-checkbox pull-left'>
{!ifc.isBond() && bondingPossible ?
<controls.Input
<Input
type='checkbox'
onChange={this.bondingChanged}
checked={ifc.get('checked')}
@ -773,7 +773,7 @@ import {DragSource, DropTarget} from 'react-dnd';
{interfaceProperties &&
<div className='ifc-properties clearfix forms-box'>
<controls.Input
<Input
type='text'
label={i18n(ns + 'mtu')}
value={interfaceProperties.mtu || ''}

View File

@ -20,12 +20,12 @@ import React from 'react';
import utils from 'utils';
import models from 'models';
import dispatcher from 'dispatcher';
import controls from 'views/controls';
import dialogs from 'views/dialogs';
import componentMixins from 'component_mixins';
import {Input, Popover, Tooltip} from 'views/controls';
import {DeleteNodesDialog, RemoveOfflineNodeDialog, ShowNodeInfoDialog} from 'views/dialogs';
import {renamingMixin} from 'component_mixins';
var Node = React.createClass({
mixins: [componentMixins.renamingMixin('name')],
mixins: [renamingMixin('name')],
getInitialState() {
return {
actionInProgress: false,
@ -88,7 +88,7 @@ import componentMixins from 'component_mixins';
removeNode(e) {
e.preventDefault();
if (this.props.viewMode == 'compact') this.toggleExtendedNodePanel();
dialogs.RemoveOfflineNodeDialog
RemoveOfflineNodeDialog
.show()
.done(() => {
// sync('delete') is used instead of node.destroy() because we want
@ -121,7 +121,7 @@ import componentMixins from 'component_mixins';
showNodeDetails(e) {
e.preventDefault();
if (this.state.extendedView) this.toggleExtendedNodePanel();
dialogs.ShowNodeInfoDialog.show({
ShowNodeInfoDialog.show({
node: this.props.node,
cluster: this.props.cluster,
nodeNetworkGroup: this.props.nodeNetworkGroups.get(this.props.node.get('group_id')),
@ -134,7 +134,7 @@ import componentMixins from 'component_mixins';
},
renderNameControl() {
if (this.state.isRenaming) return (
<controls.Input
<Input
ref='name'
type='text'
name='node-name'
@ -148,11 +148,11 @@ import componentMixins from 'component_mixins';
/>
);
return (
<controls.Tooltip text={i18n('cluster_page.nodes_tab.node.edit_name')}>
<Tooltip text={i18n('cluster_page.nodes_tab.node.edit_name')}>
<p onClick={!this.state.actionInProgress && this.startRenaming}>
{this.props.node.get('name') || this.props.node.get('mac')}
</p>
</controls.Tooltip>
</Tooltip>
);
},
renderStatusLabel(status) {
@ -192,16 +192,16 @@ import componentMixins from 'component_mixins';
},
renderLogsLink(iconRepresentation) {
return (
<controls.Tooltip key='logs' text={iconRepresentation ? i18n('cluster_page.nodes_tab.node.view_logs') : null}>
<Tooltip key='logs' text={iconRepresentation ? i18n('cluster_page.nodes_tab.node.view_logs') : null}>
<a className={'btn-view-logs ' + (iconRepresentation ? 'icon icon-logs' : 'btn')} href={this.getNodeLogsLink()}>
{!iconRepresentation && i18n('cluster_page.nodes_tab.node.view_logs')}
</a>
</controls.Tooltip>
</Tooltip>
);
},
renderNodeCheckbox() {
return (
<controls.Input
<Input
type='checkbox'
name={this.props.node.id}
checked={this.props.checked}
@ -237,7 +237,7 @@ import componentMixins from 'component_mixins';
showDeleteNodesDialog(e) {
e.preventDefault();
if (this.props.viewMode == 'compact') this.toggleExtendedNodePanel();
dialogs.DeleteNodesDialog
DeleteNodesDialog
.show({
nodes: new models.Nodes(this.props.node),
cluster: this.props.cluster
@ -340,7 +340,7 @@ import componentMixins from 'component_mixins';
</label>
</div>
{this.state.extendedView &&
<controls.Popover className='node-popover' toggle={this.toggleExtendedNodePanel}>
<Popover className='node-popover' toggle={this.toggleExtendedNodePanel}>
<div>
<div className='node-name clearfix'>
{this.renderNodeCheckbox()}
@ -400,7 +400,7 @@ import componentMixins from 'component_mixins';
<button className='btn btn-default node-settings' onClick={this.showNodeDetails}>Details</button>
</div>
</div>
</controls.Popover>
</Popover>
}
</div>
);
@ -426,16 +426,16 @@ import componentMixins from 'component_mixins';
</button>
}
{this.state.labelsPopoverVisible &&
<controls.Popover className='node-labels-popover' toggle={this.toggleLabelsPopover}>
<Popover className='node-labels-popover' toggle={this.toggleLabelsPopover}>
{this.renderLabels()}
</controls.Popover>
</Popover>
}
</div>
<div className='node-action'>
{[
!!node.get('cluster') && this.renderLogsLink(true),
this.props.renderActionButtons && node.hasChanges() && !this.props.locked &&
<controls.Tooltip
<Tooltip
key={'pending_addition_' + node.id}
text={i18n(ns + (node.get('pending_deletion') ? 'discard_deletion' : 'delete_node'))}
>
@ -443,7 +443,7 @@ import componentMixins from 'component_mixins';
className='icon btn-discard'
onClick={node.get('pending_deletion') ? this.discardNodeDeletion : this.showDeleteNodesDialog}
/>
</controls.Tooltip>
</Tooltip>
]}
</div>
<div className={utils.classNames(statusClasses)}>

View File

@ -22,9 +22,9 @@ import ReactDOM from 'react-dom';
import utils from 'utils';
import models from 'models';
import dispatcher from 'dispatcher';
import controls from 'views/controls';
import dialogs from 'views/dialogs';
import componentMixins from 'component_mixins';
import {Input, Popover, Tooltip} from 'views/controls';
import {DeleteNodesDialog} from 'views/dialogs';
import {backboneMixin, pollingMixin, dispatcherMixin, unsavedChangesMixin} from 'component_mixins';
import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
var NodeListScreen, MultiSelectControl, NumberRangeControl, ManagementPanel, NodeLabelsPanel, RolePanel, SelectAllMixin, NodeList, NodeGroup;
@ -87,14 +87,14 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
NodeListScreen = React.createClass({
mixins: [
componentMixins.pollingMixin(20, true),
componentMixins.backboneMixin('cluster', 'change:status'),
componentMixins.backboneMixin('nodes', 'update change'),
componentMixins.backboneMixin({
pollingMixin(20, true),
backboneMixin('cluster', 'change:status'),
backboneMixin('nodes', 'update change'),
backboneMixin({
modelOrCollection(props) {return props.cluster && props.cluster.get('tasks');},
renderOn: 'update change:status'
}),
componentMixins.dispatcherMixin('labelsConfigurationUpdated', 'normalizeAppliedFilters')
dispatcherMixin('labelsConfigurationUpdated', 'normalizeAppliedFilters')
],
getDefaultProps() {
return {
@ -598,11 +598,11 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
{label} <span className='caret'></span>
</button>
{this.props.isOpen &&
<controls.Popover toggle={this.props.toggle}>
<Popover toggle={this.props.toggle}>
{!this.props.dynamicValues ?
<div>
<div key='all'>
<controls.Input
<Input
type='checkbox'
label={i18n('cluster_page.nodes_tab.node_management_panel.select_all')}
name='all'
@ -612,7 +612,7 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
</div>
<div key='divider' className='divider' />
{_.map(this.props.options, function(option) {
return <controls.Input {...optionProps(option)}
return <Input {...optionProps(option)}
label={option.label}
checked={_.contains(this.props.values, option.name)}
onChange={this.onChange}
@ -622,21 +622,21 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
:
<div>
{_.map(attributes, function(option) {
return <controls.Input {...optionProps(option)}
return <Input {...optionProps(option)}
checked={_.contains(this.props.values, option.name)}
onChange={_.partialRight(this.onChange, false)}
/>;
}, this)}
{!!attributes.length && !!labels.length && <div key='divider' className='divider' />}
{_.map(labels, function(option) {
return <controls.Input {...optionProps(option)}
return <Input {...optionProps(option)}
key={'label-' + option.name}
onChange={_.partialRight(this.onChange, true)}
/>;
}, this)}
</div>
}
</controls.Popover>
</Popover>
}
{this.props.extraContent}
</div>
@ -690,22 +690,22 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
{this.props.label + ': ' + _.uniq(this.props.values).join(' - ')} <span className='caret'></span>
</button>
{this.props.isOpen &&
<controls.Popover toggle={this.props.toggle}>
<Popover toggle={this.props.toggle}>
<div className='clearfix'>
<controls.Input {...props}
<Input {...props}
name='start'
value={this.props.values[0]}
onChange={_.partialRight(this.changeValue, 0)}
autoFocus
/>
<span className='pull-left'> &mdash; </span>
<controls.Input {...props}
<Input {...props}
name='end'
value={this.props.values[1]}
onChange={_.partialRight(this.changeValue, 1)}
/>
</div>
</controls.Popover>
</Popover>
}
{this.props.extraContent}
</div>
@ -714,7 +714,7 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
});
ManagementPanel = React.createClass({
mixins: [componentMixins.unsavedChangesMixin],
mixins: [unsavedChangesMixin],
getInitialState() {
return {
actionInProgress: false,
@ -742,7 +742,7 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
this.changeScreen(action, true);
},
showDeleteNodesDialog() {
dialogs.DeleteNodesDialog.show({nodes: this.props.nodes, cluster: this.props.cluster})
DeleteNodesDialog.show({nodes: this.props.nodes, cluster: this.props.cluster})
.done(_.partial(this.props.selectNodes, _.pluck(this.props.nodes.where({status: 'ready'}), 'id'), null, true));
},
hasChanges() {
@ -947,7 +947,7 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
<div className='btn-group' data-toggle='buttons'>
{_.map(models.Nodes.prototype.viewModes, function(mode) {
return (
<controls.Tooltip key={mode + '-view'} text={i18n(ns + mode + '_mode_tooltip')}>
<Tooltip key={mode + '-view'} text={i18n(ns + mode + '_mode_tooltip')}>
<label
className={utils.classNames(managementButtonClasses(mode == this.props.viewMode, mode))}
onClick={mode != this.props.viewMode && _.partial(this.props.changeViewMode, 'view_mode', mode)}
@ -961,13 +961,13 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
})}
/>
</label>
</controls.Tooltip>
</Tooltip>
);
}, this)}
</div>
</div>
{this.props.mode != 'edit' && [
<controls.Tooltip wrap key='labels-btn' text={i18n(ns + 'labels_tooltip')}>
<Tooltip wrap key='labels-btn' text={i18n(ns + 'labels_tooltip')}>
<button
disabled={!this.props.nodes.length}
onClick={this.props.nodes.length && this.toggleLabelsPanel}
@ -975,8 +975,8 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
>
<i className='glyphicon glyphicon-tag' />
</button>
</controls.Tooltip>,
<controls.Tooltip wrap key='sorters-btn' text={i18n(ns + 'sort_tooltip')}>
</Tooltip>,
<Tooltip wrap key='sorters-btn' text={i18n(ns + 'sort_tooltip')}>
<button
disabled={!this.props.screenNodes.length}
onClick={this.toggleSorters}
@ -984,8 +984,8 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
>
<i className='glyphicon glyphicon-sort' />
</button>
</controls.Tooltip>,
<controls.Tooltip wrap key='filters-btn' text={i18n(ns + 'filter_tooltip')}>
</Tooltip>,
<Tooltip wrap key='filters-btn' text={i18n(ns + 'filter_tooltip')}>
<button
disabled={!this.props.screenNodes.length}
onClick={this.toggleFilters}
@ -993,9 +993,9 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
>
<i className='glyphicon glyphicon-filter' />
</button>
</controls.Tooltip>,
</Tooltip>,
!this.state.activeSearch && (
<controls.Tooltip wrap key='search-btn' text={i18n(ns + 'search_tooltip')}>
<Tooltip wrap key='search-btn' text={i18n(ns + 'search_tooltip')}>
<button
disabled={!this.props.screenNodes.length}
onClick={this.activateSearch}
@ -1003,11 +1003,11 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
>
<i className='glyphicon glyphicon-search' />
</button>
</controls.Tooltip>
</Tooltip>
),
this.state.activeSearch && (
<div className='search pull-left' key='search'>
<controls.Input
<Input
type='text'
name='search'
ref='search'
@ -1276,7 +1276,7 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
});
NodeLabelsPanel = React.createClass({
mixins: [componentMixins.unsavedChangesMixin],
mixins: [unsavedChangesMixin],
getInitialState() {
var labels = _.map(this.props.labels, function(label) {
var labelValues = this.props.nodes.getLabelValues(label),
@ -1445,14 +1445,14 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
var showControlLabels = index == 0;
return (
<div className={utils.classNames({clearfix: true, 'has-label': showControlLabels})} key={index}>
<controls.Input
<Input
type='checkbox'
ref={labelData.key}
checked={labelData.checked}
onChange={_.partial(this.changeLabelState, index)}
wrapperClassName='pull-left'
/>
<controls.Input
<Input
type='text'
maxLength='100'
label={showControlLabels && i18n(ns + 'label_key')}
@ -1462,7 +1462,7 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
wrapperClassName='label-key-control'
autoFocus={index == this.state.labels.length - 1}
/>
<controls.Input {...labelValueProps}
<Input {...labelValueProps}
type='text'
maxLength='100'
label={showControlLabels && i18n(ns + 'label_value')}
@ -1566,7 +1566,7 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
var name = role.get('name'),
processedRestrictions = this.props.nodes.length ? this.processRestrictions(role, this.props.configModels) : {};
return (
<controls.Input
<Input
key={name}
ref={name}
type='checkbox'
@ -1597,7 +1597,7 @@ import Node from 'views/cluster_page_tabs/nodes_tab_screens/node';
renderSelectAllCheckbox() {
var checked = this.props.mode == 'edit' || (this.props.nodes.length && !_.any(this.props.nodes, function(node) {return !this.props.selectedNodeIds[node.id];}, this));
return (
<controls.Input
<Input
ref='select-all'
name='select-all'
type='checkbox'

View File

@ -18,7 +18,7 @@ import i18n from 'i18n';
import utils from 'utils';
import React from 'react';
import Expression from 'expression';
import controls from 'views/controls';
import {Input, RadioGroup} from 'views/controls';
import customControls from 'views/custom_controls';
var SettingSection = React.createClass({
@ -182,7 +182,7 @@ import customControls from 'views/custom_controls';
<div className={'setting-section setting-section-' + sectionName}>
<h3>
{metadata.toggleable ?
<controls.Input
<Input
type='checkbox'
name='metadata'
label={metadata.label || sectionName}
@ -198,7 +198,7 @@ import customControls from 'views/custom_controls';
<div>
{isPlugin &&
<div className='plugin-versions clearfix'>
<controls.RadioGroup
<RadioGroup
key={metadata.chosen_id}
name={sectionName}
label={i18n('cluster_page.settings_tab.plugin_versions')}
@ -252,7 +252,7 @@ import customControls from 'views/custom_controls';
}, this)
.compact()
.value();
if (setting.type == 'radio') return <controls.RadioGroup {...this.props}
if (setting.type == 'radio') return <RadioGroup {...this.props}
key={settingKey}
name={settingName}
label={setting.label}
@ -264,7 +264,7 @@ import customControls from 'views/custom_controls';
var settingDescription = setting.description &&
<span dangerouslySetInnerHTML={{__html: utils.urlify(_.escape(setting.description))}} />;
return <controls.Input
return <Input
{... _.pick(setting, 'type', 'label')}
key={settingKey}
name={settingName}

View File

@ -19,26 +19,26 @@ import i18n from 'i18n';
import React from 'react';
import utils from 'utils';
import models from 'models';
import componentMixins from 'component_mixins';
import {backboneMixin, unsavedChangesMixin} from 'component_mixins';
import SettingSection from 'views/cluster_page_tabs/setting_section';
import CSSTransitionGroup from 'react-addons-transition-group';
var SettingsTab = React.createClass({
mixins: [
componentMixins.backboneMixin('cluster', 'change:status'),
componentMixins.backboneMixin({
backboneMixin('cluster', 'change:status'),
backboneMixin({
modelOrCollection(props) {
return props.cluster.get('settings');
},
renderOn: 'change invalid'
}),
componentMixins.backboneMixin({modelOrCollection(props) {
backboneMixin({modelOrCollection(props) {
return props.cluster.get('tasks');
}}),
componentMixins.backboneMixin({modelOrCollection(props) {
backboneMixin({modelOrCollection(props) {
return props.cluster.task({group: 'deployment', active: true});
}}),
componentMixins.unsavedChangesMixin
unsavedChangesMixin
],
statics: {
fetchData(options) {

View File

@ -21,7 +21,7 @@ import React from 'react';
import utils from 'utils';
import models from 'models';
import dispatcher from 'dispatcher';
import componentMixins from 'component_mixins';
import {backboneMixin, pollingMixin} from 'component_mixins';
import CreateClusterWizard from 'views/wizard';
var ClustersPage, ClusterList, Cluster;
@ -56,7 +56,7 @@ import CreateClusterWizard from 'views/wizard';
});
ClusterList = React.createClass({
mixins: [componentMixins.backboneMixin('clusters')],
mixins: [backboneMixin('clusters')],
createCluster() {
CreateClusterWizard.show({clusters: this.props.clusters, modalClass: 'wizard', backdrop: 'static'});
},
@ -78,17 +78,17 @@ import CreateClusterWizard from 'views/wizard';
Cluster = React.createClass({
mixins: [
componentMixins.backboneMixin('cluster'),
componentMixins.backboneMixin({modelOrCollection(props) {
backboneMixin('cluster'),
backboneMixin({modelOrCollection(props) {
return props.cluster.get('nodes');
}}),
componentMixins.backboneMixin({modelOrCollection(props) {
backboneMixin({modelOrCollection(props) {
return props.cluster.get('tasks');
}}),
componentMixins.backboneMixin({modelOrCollection(props) {
backboneMixin({modelOrCollection(props) {
return props.cluster.task({group: 'deployment', active: true});
}}),
componentMixins.pollingMixin(3)
pollingMixin(3)
],
shouldDataBeFetched() {
return this.props.cluster.task({group: 'deployment', active: true}) ||

View File

@ -26,11 +26,9 @@ import i18n from 'i18n';
import React from 'react';
import ReactDOM from 'react-dom';
import utils from 'utils';
import componentMixins from 'component_mixins';
import {outerClickMixin} from 'component_mixins';
var controls = {};
controls.Input = React.createClass({
export var Input = React.createClass({
propTypes: {
type: React.PropTypes.oneOf(['text', 'password', 'textarea', 'checkbox', 'radio', 'select', 'hidden', 'number', 'range', 'file']).isRequired,
name: React.PropTypes.node,
@ -150,7 +148,7 @@ import componentMixins from 'component_mixins';
<input
className='form-control file-name'
type='text'
placeholder={i18n('controls.file.placeholder')}
placeholder={i18n('file.placeholder')}
value={this.state.fileName && '[' + utils.showSize(this.state.content.length) + '] ' + this.state.fileName}
onClick={this.pickFile}
disabled={this.props.disabled}
@ -178,9 +176,9 @@ import componentMixins from 'component_mixins';
{children}
{this.props.label}
{this.props.tooltipText &&
<controls.Tooltip text={this.props.tooltipText} placement={this.props.tooltipPlacement}>
<Tooltip text={this.props.tooltipText} placement={this.props.tooltipPlacement}>
<i className={utils.classNames('glyphicon tooltip-icon', this.props.tooltipIcon)} />
</controls.Tooltip>
</Tooltip>
}
</label>
);
@ -215,7 +213,7 @@ import componentMixins from 'component_mixins';
}
});
controls.RadioGroup = React.createClass({
export var RadioGroup = React.createClass({
propTypes: {
name: React.PropTypes.string,
values: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
@ -229,14 +227,14 @@ import componentMixins from 'component_mixins';
<h4>
{this.props.label}
{this.props.tooltipText &&
<controls.Tooltip text={this.props.tooltipText} placement='right'>
<Tooltip text={this.props.tooltipText} placement='right'>
<i className='glyphicon glyphicon-warning-sign tooltip-icon' />
</controls.Tooltip>
</Tooltip>
}
</h4>
}
{_.map(this.props.values, function(value) {
return <controls.Input
return <Input
{...this.props}
{...value}
type='radio'
@ -249,7 +247,7 @@ import componentMixins from 'component_mixins';
}
});
controls.ProgressBar = React.createClass({
export var ProgressBar = React.createClass({
propTypes: {
wrapperClassName: React.PropTypes.node,
progress: React.PropTypes.number
@ -280,7 +278,7 @@ import componentMixins from 'component_mixins';
}
});
controls.Table = React.createClass({
export var Table = React.createClass({
propTypes: {
tableClassName: React.PropTypes.node,
head: React.PropTypes.array,
@ -314,8 +312,8 @@ import componentMixins from 'component_mixins';
}
});
controls.Popover = React.createClass({
mixins: [componentMixins.outerClickMixin],
export var Popover = React.createClass({
mixins: [outerClickMixin],
propTypes: {
className: React.PropTypes.node,
placement: React.PropTypes.node
@ -336,7 +334,7 @@ import componentMixins from 'component_mixins';
}
});
controls.Tooltip = React.createClass({
export var Tooltip = React.createClass({
propTypes: {
container: React.PropTypes.node,
placement: React.PropTypes.node,
@ -384,5 +382,3 @@ import componentMixins from 'component_mixins';
);
}
});
export default controls;

View File

@ -17,7 +17,7 @@ import _ from 'underscore';
import i18n from 'i18n';
import React from 'react';
import utils from 'utils';
import controls from 'views/controls';
import {Input} from 'views/controls';
var customControls = {};
@ -141,7 +141,7 @@ import controls from 'views/controls';
};
return (
<div className='form-inline' key={'repo-' + index}>
<controls.Input
<Input
{...props}
defaultValue={repo.name}
error={error && error.name}
@ -150,7 +150,7 @@ import controls from 'views/controls';
label={index == 0 && i18n(ns + 'labels.name')}
debounce
/>
<controls.Input
<Input
{...props}
defaultValue={this.constructor.repoToString(repo, os)}
error={error && (error.uri ? error.name ? '' : error.uri : null)}
@ -159,7 +159,7 @@ import controls from 'views/controls';
wrapperClassName='repo-uri'
debounce
/>
<controls.Input
<Input
{...props}
defaultValue={repo.priority}
error={error && (error.priority ? (error.name || error.uri) ? '' : error.priority : null)}

View File

@ -23,12 +23,10 @@ import Backbone from 'backbone';
import utils from 'utils';
import models from 'models';
import dispatcher from 'dispatcher';
import controls from 'views/controls';
import componentMixins from 'component_mixins';
import {Input, ProgressBar} from 'views/controls';
import {backboneMixin, renamingMixin} from 'component_mixins';
import LinkedStateMixin from 'react-addons-linked-state-mixin';
var dialogs = {};
function getActiveDialog() {
return app.dialog;
}
@ -41,7 +39,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
}
var dialogMixin = dialogs.dialogMixin = {
export var dialogMixin = {
propTypes: {
title: React.PropTypes.node,
message: React.PropTypes.node,
@ -191,14 +189,14 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
};
dialogs.ErrorDialog = React.createClass({
export var ErrorDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {
return {error: true};
}
});
dialogs.NailgunUnavailabilityDialog = React.createClass({
export var NailgunUnavailabilityDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {
return {
@ -293,7 +291,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.DiscardNodeChangesDialog = React.createClass({
export var DiscardNodeChangesDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {
return {
@ -341,11 +339,11 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.DeployChangesDialog = React.createClass({
export var DeployChangesDialog = React.createClass({
mixins: [
dialogMixin,
// this is needed to somehow handle the case when verification is in progress and user pressed Deploy
componentMixins.backboneMixin({
backboneMixin({
modelOrCollection(props) {
return props.cluster.get('tasks');
},
@ -410,7 +408,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.ProvisionVMsDialog = React.createClass({
export var ProvisionVMsDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {return {title: i18n('dialog.provision_vms.title')};},
startProvisioning() {
@ -439,7 +437,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.StopDeploymentDialog = React.createClass({
export var StopDeploymentDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {return {title: i18n('dialog.stop_deployment.title')};},
stopDeployment() {
@ -470,7 +468,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.RemoveClusterDialog = React.createClass({
export var RemoveClusterDialog = React.createClass({
mixins: [dialogMixin],
getInitialState() {
return {confirmation: false};
@ -519,7 +517,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
{this.state.confirmation &&
<div className='confirm-deletion-form'>
{i18n('dialog.remove_cluster.enter_environment_name', {name: clusterName})}
<controls.Input
<Input
type='text'
disabled={this.state.actionInProgress}
onChange={(name, value) => this.setState({confirmationError: value != clusterName})}
@ -548,7 +546,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
// FIXME: the code below neeeds deduplication
// extra confirmation logic should be moved out to dialog mixin
dialogs.ResetEnvironmentDialog = React.createClass({
export var ResetEnvironmentDialog = React.createClass({
mixins: [dialogMixin],
getInitialState() {
return {confirmation: false};
@ -578,7 +576,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
{this.state.confirmation &&
<div className='confirm-reset-form'>
{i18n('dialog.reset_environment.enter_environment_name', {name: clusterName})}
<controls.Input
<Input
type='text'
name='name'
disabled={this.state.actionInProgress}
@ -611,11 +609,11 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.ShowNodeInfoDialog = React.createClass({
export var ShowNodeInfoDialog = React.createClass({
mixins: [
dialogMixin,
componentMixins.backboneMixin('node'),
componentMixins.renamingMixin('hostname')
backboneMixin('node'),
renamingMixin('hostname')
],
getDefaultProps() {
return {modalClass: 'always-show-scrollbar'};
@ -768,7 +766,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
renderBody() {
var node = this.props.node,
meta = node.get('meta');
if (!meta) return <controls.ProgressBar />;
if (!meta) return <ProgressBar />;
var groupOrder = ['system', 'cpu', 'memory', 'disks', 'interfaces'],
groups = _.sortBy(_.keys(meta), (group) => _.indexOf(groupOrder, group)),
sortOrder = {
@ -797,7 +795,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
<div className='change-hostname'>
<strong>{i18n('dialog.show_node.hostname_label')}: </strong>
{this.state.isRenaming ?
<controls.Input
<Input
ref='hostname'
type='text'
defaultValue={node.get('hostname')}
@ -880,7 +878,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
{group == 'config' &&
<div className='vms-config'>
<controls.Input
<Input
ref='vms-config'
type='textarea'
label={i18n('node_details.vms_config_msg')}
@ -935,7 +933,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.DiscardSettingsChangesDialog = React.createClass({
export var DiscardSettingsChangesDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {return {title: i18n('dialog.dismiss_settings.title')};},
proceedWith(method) {
@ -994,7 +992,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.RemoveOfflineNodeDialog = React.createClass({
export var RemoveOfflineNodeDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {
return {
@ -1022,7 +1020,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.DeleteNodesDialog = React.createClass({
export var DeleteNodesDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {return {title: i18n('dialog.delete_nodes.title')};},
renderBody() {
@ -1077,7 +1075,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.ChangePasswordDialog = React.createClass({
export var ChangePasswordDialog = React.createClass({
mixins: [
dialogMixin,
LinkedStateMixin
@ -1112,7 +1110,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
return (
<div className='forms-box'>
{_.map(fields, function(name, index) {
return <controls.Input
return <Input
key={name}
name={name}
ref={name}
@ -1181,11 +1179,11 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.RegistrationDialog = React.createClass({
export var RegistrationDialog = React.createClass({
mixins: [
dialogMixin,
registrationResponseErrorMixin,
componentMixins.backboneMixin('registrationForm', 'change invalid')
backboneMixin('registrationForm', 'change invalid')
],
getInitialState() {
return {
@ -1277,7 +1275,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
},
renderBody() {
var registrationForm = this.props.registrationForm;
if (this.state.loading) return <controls.ProgressBar />;
if (this.state.loading) return <ProgressBar />;
var fieldsList = registrationForm.attributes.credentials,
actionInProgress = this.state.actionInProgress,
error = this.state.error,
@ -1288,7 +1286,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
halfWidthField = ['first_name', 'last_name', 'company', 'phone', 'country', 'region'];
return (
<div className='registration-form tracking'>
{actionInProgress && <controls.ProgressBar />}
{actionInProgress && <ProgressBar />}
{error &&
<div className='text-danger'>
<i className='glyphicon glyphicon-danger-sign' />
@ -1310,7 +1308,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
'col-md-6': _.contains(halfWidthField, inputName),
'text-center': inputName == 'agree'
};
return <controls.Input
return <Input
ref={inputName}
key={inputName}
name={inputName}
@ -1344,11 +1342,11 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.RetrievePasswordDialog = React.createClass({
export var RetrievePasswordDialog = React.createClass({
mixins: [
dialogMixin,
registrationResponseErrorMixin,
componentMixins.backboneMixin('remoteRetrievePasswordForm', 'change invalid')
backboneMixin('remoteRetrievePasswordForm', 'change invalid')
],
getInitialState() {
return {loading: true};
@ -1395,7 +1393,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
renderBody() {
var ns = 'dialog.retrieve_password.',
remoteRetrievePasswordForm = this.props.remoteRetrievePasswordForm;
if (this.state.loading) return <controls.ProgressBar />;
if (this.state.loading) return <ProgressBar />;
var error = this.state.error,
actionInProgress = this.state.actionInProgress,
input = (remoteRetrievePasswordForm.get('credentials') || {}).email,
@ -1404,7 +1402,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
<div className='retrieve-password-content'>
{!this.state.passwordSent ?
<div>
{actionInProgress && <controls.ProgressBar />}
{actionInProgress && <ProgressBar />}
{error &&
<div className='text-danger'>
<i className='glyphicon glyphicon-danger-sign' />
@ -1414,7 +1412,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
{input &&
<div>
<p>{i18n(ns + 'submit_email')}</p>
<controls.Input
<Input
{... _.pick(input, 'type', 'value', 'description')}
onChange={this.onChange}
error={inputError}
@ -1453,7 +1451,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.CreateNodeNetworkGroupDialog = React.createClass({
export var CreateNodeNetworkGroupDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {
return {
@ -1469,7 +1467,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
renderBody() {
return (
<div className='node-network-group-creation'>
<controls.Input
<Input
name='node-network-group-name'
type='text'
label={i18n(this.props.ns + 'node_network_group_name')}
@ -1534,7 +1532,7 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
}
});
dialogs.RemoveNodeNetworkGroupDialog = React.createClass({
export var RemoveNodeNetworkGroupDialog = React.createClass({
mixins: [dialogMixin],
getDefaultProps() {
return {title: i18n('dialog.remove_node_network_group.title')};
@ -1565,5 +1563,3 @@ import LinkedStateMixin from 'react-addons-linked-state-mixin';
]);
}
});
export default dialogs;

View File

@ -19,13 +19,13 @@ import _ from 'underscore';
import i18n from 'i18n';
import React from 'react';
import models from 'models';
import componentMixins from 'component_mixins';
import {backboneMixin} from 'component_mixins';
import NodeListScreen from 'views/cluster_page_tabs/nodes_tab_screens/node_list_screen';
var EquipmentPage, PluginLinks;
EquipmentPage = React.createClass({
mixins: [componentMixins.backboneMixin('nodes')],
mixins: [backboneMixin('nodes')],
statics: {
title: i18n('equipment_page.title'),
navbarActiveElement: 'equipment',

View File

@ -21,21 +21,19 @@ import Backbone from 'backbone';
import React from 'react';
import utils from 'utils';
import models from 'models';
import componentMixins from 'component_mixins';
import controls from 'views/controls';
import dialogs from 'views/dialogs';
import {backboneMixin, pollingMixin, dispatcherMixin} from 'component_mixins';
import {Popover} from 'views/controls';
import {ChangePasswordDialog, ShowNodeInfoDialog} from 'views/dialogs';
var components = {};
components.Navbar = React.createClass({
export var Navbar = React.createClass({
mixins: [
componentMixins.dispatcherMixin('updateNodeStats', 'updateNodeStats'),
componentMixins.dispatcherMixin('updateNotifications', 'updateNotifications'),
componentMixins.backboneMixin('user'),
componentMixins.backboneMixin('version'),
componentMixins.backboneMixin('statistics'),
componentMixins.backboneMixin('notifications', 'update change:status'),
componentMixins.pollingMixin(20)
dispatcherMixin('updateNodeStats', 'updateNodeStats'),
dispatcherMixin('updateNotifications', 'updateNotifications'),
backboneMixin('user'),
backboneMixin('version'),
backboneMixin('statistics'),
backboneMixin('notifications', 'update change:status'),
pollingMixin(20)
],
togglePopover(popoverName) {
return _.memoize((visible) => {
@ -205,7 +203,7 @@ import dialogs from 'views/dialogs';
render() {
var currentLocale = i18n.getCurrentLocale();
return (
<controls.Popover {...this.props} className='language-popover'>
<Popover {...this.props} className='language-popover'>
<ul className='nav nav-pills nav-stacked'>
{_.map(i18n.getAvailableLocales(), function(locale) {
return (
@ -217,16 +215,16 @@ import dialogs from 'views/dialogs';
);
}, this)}
</ul>
</controls.Popover>
</Popover>
);
}
});
var StatisticsPopover = React.createClass({
mixins: [componentMixins.backboneMixin('statistics')],
mixins: [backboneMixin('statistics')],
render() {
return (
<controls.Popover {...this.props} className='statistics-popover'>
<Popover {...this.props} className='statistics-popover'>
<div className='list-group'>
<li className='list-group-item'>
<span className='badge'>{this.props.statistics.get('unallocated')}</span>
@ -239,16 +237,16 @@ import dialogs from 'views/dialogs';
</a>
</li>
</div>
</controls.Popover>
</Popover>
);
}
});
var UserPopover = React.createClass({
mixins: [componentMixins.backboneMixin('user')],
mixins: [backboneMixin('user')],
showChangePasswordDialog() {
this.props.toggle(false);
dialogs.ChangePasswordDialog.show();
ChangePasswordDialog.show();
},
logout() {
this.props.toggle(false);
@ -256,7 +254,7 @@ import dialogs from 'views/dialogs';
},
render() {
return (
<controls.Popover {...this.props} className='user-popover'>
<Popover {...this.props} className='user-popover'>
<div className='username'>{i18n('common.username')}:</div>
<h3 className='name'>{this.props.user.get('username')}</h3>
<div className='clearfix'>
@ -269,18 +267,18 @@ import dialogs from 'views/dialogs';
{i18n('common.logout')}
</button>
</div>
</controls.Popover>
</Popover>
);
}
});
var NotificationsPopover = React.createClass({
mixins: [componentMixins.backboneMixin('notifications')],
mixins: [backboneMixin('notifications')],
showNodeInfo(id) {
this.props.toggle(false);
var node = new models.Node({id: id});
node.fetch();
dialogs.ShowNodeInfoDialog.show({node: node});
ShowNodeInfoDialog.show({node: node});
},
markAsRead() {
var notificationsToMark = new models.Notifications(this.props.notifications.where({status: 'unread'}));
@ -330,20 +328,20 @@ import dialogs from 'views/dialogs';
var showMore = Backbone.history.getHash() != 'notifications';
var notifications = this.props.notifications.take(this.props.displayCount);
return (
<controls.Popover {...this.props} className='notifications-popover'>
<Popover {...this.props} className='notifications-popover'>
{_.map(notifications, this.renderNotification)}
{showMore &&
<div className='show-more'>
<a href='#notifications'>{i18n('notifications_popover.view_all_button')}</a>
</div>
}
</controls.Popover>
</Popover>
);
}
});
components.Footer = React.createClass({
mixins: [componentMixins.backboneMixin('version')],
export var Footer = React.createClass({
mixins: [backboneMixin('version')],
render() {
var version = this.props.version;
return (
@ -358,9 +356,9 @@ import dialogs from 'views/dialogs';
}
});
components.Breadcrumbs = React.createClass({
export var Breadcrumbs = React.createClass({
mixins: [
componentMixins.dispatcherMixin('updatePageLayout', 'refresh')
dispatcherMixin('updatePageLayout', 'refresh')
],
getInitialState() {
return {path: this.getBreadcrumbsPath()};
@ -394,7 +392,7 @@ import dialogs from 'views/dialogs';
}
});
components.DefaultPasswordWarning = React.createClass({
export var DefaultPasswordWarning = React.createClass({
render() {
return (
<div className='alert global-alert alert-warning'>
@ -405,7 +403,7 @@ import dialogs from 'views/dialogs';
}
});
components.BootstrapError = React.createClass({
export var BootstrapError = React.createClass({
render() {
return (
<div className='alert global-alert alert-danger'>
@ -414,5 +412,3 @@ import dialogs from 'views/dialogs';
);
}
});
export default components;

View File

@ -18,13 +18,13 @@ import i18n from 'i18n';
import React from 'react';
import utils from 'utils';
import models from 'models';
import dialogs from 'views/dialogs';
import componentMixins from 'component_mixins';
import {ShowNodeInfoDialog} from 'views/dialogs';
import {backboneMixin} from 'component_mixins';
var NotificationsPage, Notification;
NotificationsPage = React.createClass({
mixins: [componentMixins.backboneMixin('notifications')],
mixins: [backboneMixin('notifications')],
statics: {
title: i18n('notifications_page.title'),
navbarActiveElement: null,
@ -70,11 +70,11 @@ import componentMixins from 'component_mixins';
});
Notification = React.createClass({
mixins: [componentMixins.backboneMixin('notification')],
mixins: [backboneMixin('notification')],
showNodeInfo(id) {
var node = new models.Node({id: id});
node.fetch();
dialogs.ShowNodeInfoDialog.show({node: node});
ShowNodeInfoDialog.show({node: node});
},
markAsRead() {
var notification = this.props.notification;

View File

@ -16,11 +16,11 @@
import _ from 'underscore';
import i18n from 'i18n';
import React from 'react';
import controls from 'views/controls';
import componentMixins from 'component_mixins';
import {Table} from 'views/controls';
import {backboneMixin} from 'component_mixins';
var ReleasesPage = React.createClass({
mixins: [componentMixins.backboneMixin('releases')],
mixins: [backboneMixin('releases')],
getDefaultProps() {
return {columns: ['name', 'version', 'state']};
},
@ -50,7 +50,7 @@ import componentMixins from 'component_mixins';
<div className='content-box'>
<div className='row'>
<div className='col-xs-12 content-elements'>
<controls.Table
<Table
head={_.map(this.props.columns, (column) => {
return ({label: i18n('release_page.' + column), className: column});
})}

View File

@ -17,18 +17,18 @@
import _ from 'underscore';
import i18n from 'i18n';
import React from 'react';
import utils from 'utils';
import layoutComponents from 'views/layout';
import dispatcher from 'dispatcher';
import componentMixins from 'component_mixins';
import utils from 'utils';
import {dispatcherMixin} from 'component_mixins';
import {Navbar, Breadcrumbs, DefaultPasswordWarning, BootstrapError, Footer} from 'views/layout';
import {DragDropContext} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
var RootComponent = React.createClass({
mixins: [
componentMixins.dispatcherMixin('updatePageLayout', 'updateTitle'),
componentMixins.dispatcherMixin('showDefaultPasswordWarning', 'showDefaultPasswordWarning'),
componentMixins.dispatcherMixin('hideDefaultPasswordWarning', 'hideDefaultPasswordWarning')
dispatcherMixin('updatePageLayout', 'updateTitle'),
dispatcherMixin('showDefaultPasswordWarning', 'showDefaultPasswordWarning'),
dispatcherMixin('hideDefaultPasswordWarning', 'hideDefaultPasswordWarning')
],
showDefaultPasswordWarning() {
this.setState({showDefaultPasswordWarning: true});
@ -68,17 +68,17 @@ import HTML5Backend from 'react-dnd-html5-backend';
<div id='content-wrapper'>
<div className={utils.classNames(layoutClasses)}>
{!Page.hiddenLayout && [
<layoutComponents.Navbar key='navbar' ref='navbar' activeElement={Page.navbarActiveElement} {...this.props} />,
<layoutComponents.Breadcrumbs key='breadcrumbs' ref='breadcrumbs' {...this.state} />,
showDefaultPasswordWarning && <layoutComponents.DefaultPasswordWarning key='password-warning' close={this.hideDefaultPasswordWarning} />,
fuelSettings.get('bootstrap.error.value') && <layoutComponents.BootstrapError key='bootstrap-error' text={fuelSettings.get('bootstrap.error.value')} />
<Navbar key='navbar' ref='navbar' activeElement={Page.navbarActiveElement} {...this.props} />,
<Breadcrumbs key='breadcrumbs' ref='breadcrumbs' {...this.state} />,
showDefaultPasswordWarning && <DefaultPasswordWarning key='password-warning' close={this.hideDefaultPasswordWarning} />,
fuelSettings.get('bootstrap.error.value') && <BootstrapError key='bootstrap-error' text={fuelSettings.get('bootstrap.error.value')} />
]}
<div id='content'>
<Page ref='page' {...this.state.pageOptions} />
</div>
{!Page.hiddenLayout && <div id='footer-spacer'></div>}
</div>
{!Page.hiddenLayout && <layoutComponents.Footer version={version} />}
{!Page.hiddenLayout && <Footer version={version} />}
</div>
);
}

View File

@ -18,8 +18,8 @@ import i18n from 'i18n';
import React from 'react';
import utils from 'utils';
import models from 'models';
import controls from 'views/controls';
import dialogs from 'views/dialogs';
import {Input, ProgressBar} from 'views/controls';
import {RegistrationDialog, RetrievePasswordDialog} from 'views/dialogs';
export default {
propTypes: {
@ -132,7 +132,7 @@ import dialogs from 'views/dialogs';
if (this.checkRestrictions('metadata', 'hide').result || this.checkRestrictions(settingName, 'hide').result || setting.type == 'hidden') return null;
var error = this.getError(model, settingName),
disabled = this.checkRestrictions('metadata').result || this.checkRestrictions(settingName).result || disabledState;
return <controls.Input
return <Input
key={settingName}
type={setting.type}
name={settingName}
@ -245,9 +245,9 @@ import dialogs from 'views/dialogs';
</div>
}
<div className='connection-form'>
{showProgressBar && <controls.ProgressBar />}
{showProgressBar && <ProgressBar />}
{_.map(sortedFields, function(inputName) {
return <controls.Input
return <Input
ref={inputName}
key={inputName}
name={inputName}
@ -270,7 +270,7 @@ import dialogs from 'views/dialogs';
);
},
showRegistrationDialog() {
dialogs.RegistrationDialog.show({
RegistrationDialog.show({
registrationForm: this.state.registrationForm,
setConnected: this.setConnected,
settings: this.props.settings,
@ -279,7 +279,7 @@ import dialogs from 'views/dialogs';
});
},
showRetrievePasswordDialog() {
dialogs.RetrievePasswordDialog.show({
RetrievePasswordDialog.show({
remoteRetrievePasswordForm: this.state.remoteRetrievePasswordForm
});
}

View File

@ -18,12 +18,12 @@ import _ from 'underscore';
import i18n from 'i18n';
import React from 'react';
import models from 'models';
import componentMixins from 'component_mixins';
import {backboneMixin, pollingMixin, unsavedChangesMixin} from 'component_mixins';
import statisticsMixin from 'views/statistics_mixin';
var SupportPage = React.createClass({
mixins: [
componentMixins.backboneMixin('tasks')
backboneMixin('tasks')
],
statics: {
title: i18n('support_page.title'),
@ -112,7 +112,7 @@ import statisticsMixin from 'views/statistics_mixin';
var RegistrationInfo = React.createClass({
mixins: [
statisticsMixin,
componentMixins.backboneMixin('tracking', 'change invalid')
backboneMixin('tracking', 'change invalid')
],
render() {
if (this.state.isConnected)
@ -157,8 +157,8 @@ import statisticsMixin from 'views/statistics_mixin';
var StatisticsSettings = React.createClass({
mixins: [
statisticsMixin,
componentMixins.backboneMixin('statistics'),
componentMixins.unsavedChangesMixin
backboneMixin('statistics'),
unsavedChangesMixin
],
hasChanges() {
var initialData = this.props.settings.get('statistics'),
@ -225,8 +225,8 @@ import statisticsMixin from 'views/statistics_mixin';
var DiagnosticSnapshot = React.createClass({
mixins: [
componentMixins.backboneMixin('task'),
componentMixins.pollingMixin(2)
backboneMixin('task'),
pollingMixin(2)
],
getInitialState() {
return {generating: this.isDumpTaskActive()};

View File

@ -17,13 +17,13 @@ import _ from 'underscore';
import i18n from 'i18n';
import React from 'react';
import models from 'models';
import componentMixins from 'component_mixins';
import {backboneMixin} from 'component_mixins';
import statisticsMixin from 'views/statistics_mixin';
var WelcomePage = React.createClass({
mixins: [
statisticsMixin,
componentMixins.backboneMixin('tracking', 'change invalid')
backboneMixin('tracking', 'change invalid')
],
statics: {
title: i18n('welcome_page.title'),

View File

@ -21,8 +21,8 @@ import ReactDOM from 'react-dom';
import Backbone from 'backbone';
import models from 'models';
import utils from 'utils';
import dialogs from 'views/dialogs';
import controls from 'views/controls';
import {dialogMixin} from 'views/dialogs';
import {Input, ProgressBar} from 'views/controls';
var AVAILABILITY_STATUS_ICONS = {
compatible: 'glyphicon-ok-sign',
@ -41,7 +41,7 @@ import controls from 'views/controls';
_.map(this.props.components, (component) => {
var icon = AVAILABILITY_STATUS_ICONS[component.get('availability')];
return (
<controls.Input
<Input
key={component.id}
type='checkbox'
name={component.id}
@ -86,7 +86,7 @@ import controls from 'views/controls';
_.map(this.props.components, (component) => {
var icon = AVAILABILITY_STATUS_ICONS[component.get('availability')];
return (
<controls.Input
<Input
key={component.id}
type='radio'
name={this.props.groupName}
@ -285,7 +285,7 @@ import controls from 'views/controls';
connectivityAlert = i18n('dialog.create_cluster_wizard.name_release.' + os + '_connectivity_alert');
return (
<div className='create-cluster-form name-and-release'>
<controls.Input
<Input
type='text'
name='name'
autoComplete='off'
@ -294,7 +294,7 @@ import controls from 'views/controls';
error={nameError}
onChange={this.props.onChange}
/>
<controls.Input
<Input
type='select'
name='release'
label={i18n('dialog.create_cluster_wizard.name_release.release_label')}
@ -309,7 +309,7 @@ import controls from 'views/controls';
return <option key={release.id} value={release.id}>{release.get('name')}</option>;
})
}
</controls.Input>
</Input>
<div className='help-block'>
{connectivityAlert &&
<div className='alert alert-warning'>{connectivityAlert}</div>
@ -524,7 +524,7 @@ import controls from 'views/controls';
];
var CreateClusterWizard = React.createClass({
mixins: [dialogs.dialogMixin],
mixins: [dialogMixin],
getInitialState() {
return {
title: i18n('dialog.create_cluster_wizard.title'),
@ -741,7 +741,7 @@ import controls from 'views/controls';
</div>
{!this.components &&
<div className='pane-content col-xs-9 pane-progress-bar'>
<controls.ProgressBar/>
<ProgressBar/>
</div>
}
{this.components &&