Fix React warnings

Avoid passing all the props and states to child component
to prevent passing redundant props and make the code more strict and explicit.

Closes-Bug: #1624332

Change-Id: I67f59ac0323e0ce3d67e477a95e87a900688a7c7
This commit is contained in:
Julia Aranovich 2016-09-15 18:15:28 +03:00
parent b0049d4bd6
commit 06f658bb55
8 changed files with 83 additions and 64 deletions

View File

@ -61,25 +61,21 @@ var NetworkModelManipulationMixin = {
var NetworkInputsMixin = {
composeProps(attribute, isRange, isInteger) {
var {network, disabled, cluster, verificationErrorField} = this.props;
var {network, disabled, verificationErrorField} = this.props;
var ns = network ? networkTabNS + 'network.' : parametersNS;
var error = this.getError(attribute) || null;
// in case of verification error we need to pass an empty string to highlight the field only
// but not overwriting validation error
if (!error && _.includes(verificationErrorField, attribute)) {
error = '';
}
if (!error && _.includes(verificationErrorField, attribute)) error = '';
return {
key: attribute,
onChange: _.partialRight(this.setValue, {isInteger: isInteger}),
onChange: _.partialRight(this.setValue, {isInteger}),
name: attribute,
label: i18n(ns + attribute),
value: this.getModel().get(attribute),
wrapperClassName: isRange ? attribute : false,
network,
cluster,
disabled,
error
};
@ -393,7 +389,8 @@ var VlanTagInput = React.createClass({
</Tooltip>
}
</label>
<Input {...this.props}
<Input
{... _.pick(this.props, 'name', 'label', 'value')}
onChange={this.onTaggingChange}
type='checkbox'
checked={!_.isNull(value)}
@ -402,7 +399,8 @@ var VlanTagInput = React.createClass({
label={null}
/>
{!_.isNull(value) &&
<Input {...this.props}
<Input
{... _.pick(this.props, 'name', 'label', 'value', 'error')}
ref={name}
onChange={this.onInputChange}
type='text'
@ -428,17 +426,16 @@ var CidrControl = React.createClass({
<div className='form-group cidr'>
<label>{i18n(networkTabNS + 'network.cidr')}</label>
<Input
{...this.props}
{... _.pick(this.props, 'name', 'value', 'error', 'disabled')}
type='text'
label={null}
onChange={this.onCidrChange}
wrapperClassName='pull-left'
/>
<Input
{... _.pick(this.props, 'disabled')}
type='checkbox'
checked={this.props.network.get('meta').notation === 'cidr'}
label={i18n(networkTabNS + 'network.use_whole_cidr')}
disabled={this.props.disabled}
onChange={this.props.changeNetworkNotation}
wrapperClassName='pull-left'
/>
@ -1280,11 +1277,13 @@ var Network = React.createClass({
<div className='network-description'>{i18n('network.descriptions.' + networkName)}</div>
<CidrControl
{... this.composeProps('cidr')}
{... _.pick(this.props, 'cluster', 'network')}
changeNetworkNotation={this.changeNetworkNotation}
autoUpdateParameters={this.autoUpdateParameters}
/>
<Range
{...ipRangeProps}
{... _.pick(this.props, 'cluster', 'network')}
disabled={ipRangeProps.disabled || meta.notation === 'cidr'}
rowsClassName='ip-ranges-rows'
verificationError={_.includes(verificationErrorField, 'ip_ranges')}
@ -1298,6 +1297,7 @@ var Network = React.createClass({
}
<VlanTagInput
{... this.composeProps('vlan_start')}
{... _.pick(this.props, 'cluster', 'network')}
label={i18n(networkTabNS + 'network.use_vlan_tagging')}
value={network.get('vlan_start')}
configurationTemplateExists={configurationTemplateExists}

View File

@ -643,8 +643,11 @@ var EditNodeInterfacesScreen = React.createClass({
);
}
var {nodes, interfaces, viewModes} = this.props;
var {interfacesByIndex, indexByInterface, viewMode} = this.state;
var {nodes, cluster, interfaces, viewModes, bondingConfig} = this.props;
var {
interfacesByIndex, indexByInterface, viewMode, actionInProgress,
interfacesErrors, initialInterfaces
} = this.state;
var nodeNames = nodes.map('name');
var locked = this.isLocked();
var configurationTemplateExists = this.configurationTemplateExists();
@ -688,8 +691,8 @@ var EditNodeInterfacesScreen = React.createClass({
var hasChanges = this.hasChanges();
var slaveInterfaceNames = _.map(_.flatten(_.filter(interfaces.map('slaves'))), 'name');
var loadDefaultsEnabled = !this.state.actionInProgress;
var revertChangesEnabled = !this.state.actionInProgress && hasChanges;
var loadDefaultsEnabled = !actionInProgress;
var revertChangesEnabled = !actionInProgress && hasChanges;
var invalidSpeedsForBonding = bondingPossible &&
this.validateSpeedsForBonding(checkedBonds.concat(checkedInterfaces)) ||
@ -783,23 +786,23 @@ var EditNodeInterfacesScreen = React.createClass({
if (!_.includes(slaveInterfaceNames, ifcName)) {
return (
<NodeInterfaceDropTarget
{...this.props}
{... _.pick(this.props, 'cluster', 'nodes', 'interfaces', 'configModels')}
key={'interface-' + ifcName}
interface={ifc}
limitations={limitations}
nodesInterfaces={nodesInterfaces[index]}
hasChanges={
!_.isEqual(
_.find(this.state.initialInterfaces, {name: ifcName}),
_.find(initialInterfaces, {name: ifcName}),
_.omit(ifc.toJSON(), 'state')
)
}
locked={locked}
configurationTemplateExists={configurationTemplateExists}
errors={this.state.interfacesErrors[ifcName]}
errors={interfacesErrors[ifcName]}
validate={this.validate}
removeInterfaceFromBond={this.removeInterfaceFromBond}
bondingProperties={this.props.bondingConfig.properties}
bondingProperties={bondingConfig.properties}
availableBondingTypes={availableBondingTypes[ifcName]}
getAvailableBondingTypes={this.getAvailableBondingTypes}
interfaceSpeeds={interfaceSpeeds[index]}
@ -815,8 +818,8 @@ var EditNodeInterfacesScreen = React.createClass({
<div className='btn-group'>
<Link
className='btn btn-default'
to={'/cluster/' + this.props.cluster.id + '/nodes'}
disabled={this.state.actionInProgress}
to={'/cluster/' + cluster.id + '/nodes'}
disabled={!!actionInProgress}
>
{i18n('cluster_page.nodes_tab.back_to_nodes_button')}
</Link>
@ -827,7 +830,7 @@ var EditNodeInterfacesScreen = React.createClass({
className='btn btn-default btn-defaults'
onClick={this.loadDefaults}
disabled={!loadDefaultsEnabled}
progress={this.state.actionInProgress === 'load_defaults'}
progress={actionInProgress === 'load_defaults'}
>
{i18n('common.load_defaults_button')}
</ProgressButton>
@ -842,7 +845,7 @@ var EditNodeInterfacesScreen = React.createClass({
className='btn btn-success btn-apply'
onClick={this.applyChanges}
disabled={!this.isSavingPossible()}
progress={this.state.actionInProgress === 'apply_changes'}
progress={actionInProgress === 'apply_changes'}
>
{i18n('common.apply_button')}
</ProgressButton>

View File

@ -534,7 +534,7 @@ NodeListScreenContent = React.createClass({
return result;
},
render() {
var {cluster, nodes, selectedNodeIds, search, activeFilters, showRolePanel} = this.props;
var {cluster, nodes, selectedNodeIds, search, activeFilters, showRolePanel, mode} = this.props;
var locked = !!cluster && !!cluster.task({group: 'deployment', active: true});
var processedRoleData = cluster ? this.processRoleLimits() : {};
@ -570,29 +570,32 @@ NodeListScreenContent = React.createClass({
});
var screenNodesLabels = this.getNodeLabels();
return (
<div>
{this.props.mode === 'edit' &&
{mode === 'edit' &&
<div className='alert alert-warning'>
{i18n('cluster_page.nodes_tab.disk_configuration_reset_warning')}
</div>
}
<ManagementPanel
{...this.props}
{... _.pick(this,
'addSorting',
'removeSorting',
'resetSorters',
'changeSortingOrder',
'addFilter',
'changeFilter',
'removeFilter',
'resetFilters',
'getFilterOptions',
'changeSearch',
'toggleLabelsPanel'
{... _.pick(this.props,
'cluster', 'mode', 'showBatchActionButtons',
'viewMode', 'changeViewMode', 'showViewModeButtons',
'search', 'updateSearch',
'activeSorters', 'availableSorters', 'defaultSorting',
'activeFilters', 'availableFilters', 'defaultFilters',
'showLabelManagementButton'
)}
isLabelsPanelOpen={this.state.isLabelsPanelOpen}
{... _.pick(this,
'addSorting', 'removeSorting', 'resetSorters', 'changeSortingOrder',
'addFilter', 'changeFilter', 'removeFilter', 'resetFilters', 'getFilterOptions',
'changeSearch',
'toggleLabelsPanel',
'revertChanges',
'selectNodes'
)}
{... _.pick(this.state, 'isLabelsPanelOpen')}
labelSorters={screenNodesLabels.map((name) => new Sorter(name, 'asc', true))}
labelFilters={screenNodesLabels.map((name) => new Filter(name, [], true))}
nodes={selectedNodes}
@ -601,8 +604,6 @@ NodeListScreenContent = React.createClass({
selectedNodeLabels={selectedNodeLabels}
hasChanges={this.hasChanges()}
locked={locked}
revertChanges={this.revertChanges}
selectNodes={this.selectNodes}
/>
{showRolePanel &&
<RolePanel
@ -2037,7 +2038,12 @@ NodeList = React.createClass({
}
<div className='col-xs-12 content-elements'>
{groups.map((group) => {
return <NodeGroup {...this.props}
return <NodeGroup
{... _.pick(this.props,
'cluster', 'clusters', 'nodeNetworkGroups', 'locked',
'selectNodes', 'selectedNodeIds', 'nodeActionsAvailable',
'mode', 'viewMode'
)}
key={group[0]}
label={group[0]}
nodes={group[1]}

View File

@ -225,13 +225,14 @@ var SettingSection = React.createClass({
.compact()
.value();
return (
<RadioGroup {...this.props}
<RadioGroup
key={settingKey}
name={settingName}
label={setting.label}
values={values}
error={error}
tooltipText={showSettingWarning && settingWarning}
{... _.pick(this.props, 'onChange')}
/>
);
},

View File

@ -752,11 +752,13 @@ export var SelectNodesDialog = React.createClass({
},
renderBody() {
return <NodeListScreen
{...this.props}
{... _.pick(this.props,
'nodes', 'cluster', 'nodeNetworkGroups', 'roles', 'selectedNodeIds', 'statusesToFilter'
)}
{... _.pick(this.state, 'selectedNodeIds')}
{... _.pick(this, 'selectNodes')}
ref='screen'
mode='list'
selectedNodeIds={this.state.selectedNodeIds}
selectNodes={this.selectNodes}
showBatchActionButtons={false}
showLabelManagementButton={false}
nodeActionsAvailable={false}

View File

@ -113,10 +113,11 @@ EquipmentPage = React.createClass({
<PluginLinks links={this.props.links} />
<NodeListScreen
ref='screen'
{...this.props}
selectedNodeIds={this.state.selectedNodeIds}
selectNodes={this.selectNodes}
updateUISettings={this.updateUISettings}
{... _.pick(this.props,
'nodes', 'clusters', 'nodeNetworkGroups', 'roles', 'uiSettings'
)}
{... _.pick(this.state, 'selectedNodeIds')}
{... _.pick(this, 'selectNodes', 'updateUISettings')}
showBatchActionButtons={false}
/>
</div>

View File

@ -218,7 +218,7 @@ var LanguagePopover = React.createClass({
render() {
var currentLocale = i18n.getCurrentLocale();
return (
<Popover {...this.props} className='language-popover'>
<Popover toggle={this.props.toggle} className='language-popover'>
<ul className='nav nav-pills nav-stacked'>
{_.map(i18n.getAvailableLocales(), (locale) => {
return (
@ -238,17 +238,18 @@ var LanguagePopover = React.createClass({
var StatisticsPopover = React.createClass({
mixins: [backboneMixin('statistics')],
render() {
var {toggle, statistics} = this.props;
return (
<Popover {...this.props} className='statistics-popover'>
<Popover toggle={toggle} className='statistics-popover'>
<div className='list-group'>
<li className='list-group-item'>
<span className='badge'>{this.props.statistics.get('unallocated')}</span>
{i18n('navbar.stats.unallocated', {count: this.props.statistics.get('unallocated')})}
<span className='badge'>{statistics.get('unallocated')}</span>
{i18n('navbar.stats.unallocated', {count: statistics.get('unallocated')})}
</li>
<li className='list-group-item text-success font-semibold'>
<span className='badge bg-green'>{this.props.statistics.get('total')}</span>
<span className='badge bg-green'>{statistics.get('total')}</span>
<Link to='/equipment'>
{i18n('navbar.stats.total', {count: this.props.statistics.get('total')})}
{i18n('navbar.stats.total', {count: statistics.get('total')})}
</Link>
</li>
</div>
@ -268,10 +269,11 @@ var UserPopover = React.createClass({
app.logout();
},
render() {
var {toggle, user} = this.props;
return (
<Popover {...this.props} className='user-popover'>
<Popover toggle={toggle} className='user-popover'>
<div className='username'>{i18n('common.username')}:</div>
<h3 className='name'>{this.props.user.get('username')}</h3>
<h3 className='name'>{user.get('username')}</h3>
<div className='clearfix'>
<button
className='btn btn-default btn-sm pull-left'
@ -351,10 +353,10 @@ var NotificationsPopover = React.createClass({
},
render() {
var showMore = Backbone.history.getHash() !== 'notifications';
var notifications = this.props.notifications.take(this.props.displayCount);
var {notifications, displayCount, toggle} = this.props;
return (
<Popover {...this.props} className='notifications-popover'>
{_.map(notifications, this.renderNotification)}
<Popover toggle={toggle} className='notifications-popover'>
{_.map(notifications.take(displayCount), this.renderNotification)}
{showMore &&
<div className='show-more'>
<Link to='/notifications'>{i18n('notifications_popover.view_all_button')}</Link>

View File

@ -75,9 +75,13 @@ var RootComponent = React.createClass({
key='navbar'
ref='navbar'
activeElement={Page.navbarActiveElement}
{...this.props}
{... _.pick(this.props, 'version', 'user', 'statistics', 'notifications')}
/>,
<Breadcrumbs
key='breadcrumbs'
ref='breadcrumbs'
{... _.pick(this.state, 'Page', 'pageOptions')}
/>,
<Breadcrumbs key='breadcrumbs' ref='breadcrumbs' {...this.state} />,
showDefaultPasswordWarning &&
<DefaultPasswordWarning
key='password-warning'