Upgrade JS libraries

LoDash 3.10.1 to 4.13.0
Backbone 1.2 to 1.3.3
Babel modules to 6.9.0 or latest available
Webpack from 0.12 to 0.13

Change-Id: Id77c6cb2f32ada94dba7a0cd3b61d33eeccf90aa
This commit is contained in:
Nikolay Bogdanov 2016-05-05 15:35:22 +03:00 committed by Vitaly Kramskikh
parent 50fad38d19
commit b2fcad75b6
15 changed files with 1698 additions and 2277 deletions

3823
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
"url": "https://github.com/openstack/fuel-ui.git"
},
"engines": {
"node": ">=0.10.0"
"node": ">=0.10.40"
},
"scripts": {
"start": "gulp dev-server",
@ -19,14 +19,14 @@
},
"dependencies": {
"autoprefixer": "5.2.0",
"babel-core": "6.7.2",
"babel-core": "6.9.0",
"babel-loader": "6.2.4",
"babel-plugin-transform-es2015-modules-commonjs": "6.7.4",
"babel-plugin-transform-runtime": "6.6.0",
"babel-preset-es2015-webpack": "6.4.0",
"babel-plugin-transform-es2015-modules-commonjs": "6.8.0",
"babel-plugin-transform-runtime": "6.9.0",
"babel-preset-es2015-webpack": "6.4.1",
"babel-preset-react": "6.5.0",
"babel-runtime": "6.6.1",
"backbone": "1.2.1",
"babel-runtime": "6.9.0",
"backbone": "1.3.3",
"backbone.routefilter": "1.0.0",
"bootstrap": "3.3.4",
"classnames": "1.1.4",
@ -48,7 +48,7 @@
"json-loader": "0.5.3",
"less": "2.4.0",
"less-loader": "2.2.1",
"lodash": "3.10.1",
"lodash": "4.13.0",
"minimist": "1.1.1",
"open-sans-fontface": "1.4.0",
"postcss-loader": "0.5.1",
@ -65,7 +65,7 @@
"rimraf": "2.2.8",
"run-sequence": "1.0.2",
"style-loader": "0.12.4",
"webpack": "1.12.9",
"webpack": "1.13.1",
"whatwg-fetch": "0.11.0"
},
"devDependencies": {

View File

@ -53,7 +53,7 @@ var collectionMethods = [
'findKey', 'findLastKey',
'find', 'findLast',
'filter', 'reject',
'every', 'some',
'every', 'some', 'invokeMap',
'partition'
];
@ -65,9 +65,7 @@ _.each(collectionMethods, (method) => {
if (_.isPlainObject(source)) {
args[0] = (model) => _.isMatch(model.attributes, source);
}
args.unshift(this.models);
return _[method](...args);
};
});
@ -493,7 +491,7 @@ models.Node = BaseModel.extend({
return status === 'discover' || status === 'error';
},
getRolesSummary(releaseRoles) {
return _.map(this.sortedRoles(releaseRoles.pluck('name')),
return _.map(this.sortedRoles(releaseRoles.map('name')),
(role) => releaseRoles.find({name: role}).get('label')
).join(', ');
},
@ -549,7 +547,7 @@ models.Nodes = BaseCollection.extend({
],
viewModes: ['standard', 'compact'],
hasChanges() {
return _.some(this.invoke('hasChanges'));
return _.some(this.invokeMap('hasChanges'));
},
nodesAfterDeployment() {
return this.filter((node) => !node.get('pending_deletion'));
@ -558,10 +556,10 @@ models.Nodes = BaseCollection.extend({
return _.filter(this.nodesAfterDeployment(), (node) => node.hasRole(role));
},
resources(resourceName) {
return _.reduce(this.invoke('resource', resourceName), (sum, n) => sum + n, 0);
return _.reduce(this.invokeMap('resource', resourceName), (sum, n) => sum + n, 0);
},
getLabelValues(label) {
return this.invoke('getLabel', label);
return this.invokeMap('getLabel', label);
},
areDisksConfigurable() {
if (!this.length) return false;
@ -575,7 +573,7 @@ models.Nodes = BaseCollection.extend({
},
areInterfacesConfigurable() {
if (!this.length) return false;
return _.uniq(this.invoke('resource', 'interfaces')).length === 1;
return _.uniq(this.invokeMap('resource', 'interfaces')).length === 1;
}
});
@ -654,7 +652,7 @@ models.Tasks = BaseCollection.extend({
model: models.Task,
url: '/api/tasks',
toJSON() {
return this.pluck('id');
return this.map('id');
},
comparator: 'id',
filterTasks(filters) {
@ -958,7 +956,7 @@ models.Interface = Backbone.DeepModel
var errors = {};
var networkErrors = [];
var networks = new models.Networks(this.get('assigned_networks')
.invoke('getFullNetwork', attrs.networks));
.invokeMap('getFullNetwork', attrs.networks));
var untaggedNetworks = networks.filter((network) => {
return _.isNull(network.getVlanRange(attrs.networkingParameters));
});
@ -973,7 +971,7 @@ models.Interface = Backbone.DeepModel
_.extend(errors, this.validateInterfaceProperties(options));
// check interface networks have the same vlan id
var vlans = _.reject(networks.pluck('vlan_start'), _.isNull);
var vlans = _.reject(networks.map('vlan_start'), _.isNull);
if (_.uniq(vlans).length < vlans.length) {
networkErrors.push(i18n(ns + 'networks_with_the_same_vlan'));
}
@ -998,7 +996,7 @@ models.Interface = Backbone.DeepModel
if (
this.get('interface_properties').dpdk.enabled &&
!_.isEqual(networks.pluck('name'), ['private'])
!_.isEqual(networks.map('name'), ['private'])
) {
networkErrors.push(i18n(ns + 'dpdk_placement_error'));
}
@ -1265,7 +1263,7 @@ models.NetworkConfiguration = BaseModel.extend(cacheMixin).extend({
var fixedNetworkVlan = parameters.get('fixed_networks_vlan_start');
var fixedNetworkVlanError = utils.validateVlan(
fixedNetworkVlan,
networks.pluck('vlan_start'),
networks.map('vlan_start'),
'fixed_networks_vlan_start',
manager === 'VlanManager'
);
@ -1281,7 +1279,7 @@ models.NetworkConfiguration = BaseModel.extend(cacheMixin).extend({
);
if (_.isEmpty(fixedNetworkVlanError)) {
var vlanIntersection = _.some(_.compact(networks.pluck('vlan_start')),
var vlanIntersection = _.some(_.compact(networks.map('vlan_start')),
(vlan) => utils.validateVlanRange(
fixedNetworkVlan,
fixedNetworkVlan + fixedNetworksAmount - 1, vlan
@ -1308,7 +1306,7 @@ models.NetworkConfiguration = BaseModel.extend(cacheMixin).extend({
var idRangeErrors = this.validateNeutronSegmentationIdRange(
_.map(parameters.get(idRangeAttributeName), Number),
isVlanSegmentation,
_.compact(networks.pluck('vlan_start'))
_.compact(networks.map('vlan_start'))
);
if (idRangeErrors[0] || idRangeErrors[1]) errors[idRangeAttributeName] = idRangeErrors;
@ -1725,7 +1723,7 @@ models.ComponentsCollection = BaseCollection.extend({
restoreDefaultValues(types) {
types = types || this.allTypes;
var components = _.filter(this.models, (model) => _.includes(types, model.get('type')));
_.invoke(components, 'restoreDefaultValue');
_.invokeMap(components, 'restoreDefaultValue');
},
toJSON() {
return _.compact(_.map(this.models, (model) => model.toJSON()));

View File

@ -101,7 +101,7 @@ var BaseCollection = Backbone.Collection
return _.isEmpty(errors) ? null : errors;
},
testRestrictions() {
_.invoke(this.models, 'testRestrictions', restrictionModels);
_.invokeMap(this.models, 'testRestrictions', restrictionModels);
}
});
@ -148,8 +148,8 @@ var NovaComputes = BaseCollection.extend({
this._super('validate', arguments);
var keys = {vsphere_clusters: {}, service_names: {}};
this.invoke('checkDuplicates', keys);
this.invoke('checkEmptyTargetNode');
this.invokeMap('checkDuplicates', keys);
this.invokeMap('checkEmptyTargetNode');
var errors = _.compact(this.map('validationError'));
return _.isEmpty(errors) ? null : errors;

View File

@ -37,7 +37,7 @@ var utils = {
return _.map(options, (value, key) => key + ':' + value).join(';');
},
deserializeTabOptions(serializedOptions) {
return _.object(_.map((serializedOptions || '').split(';'), (option) => option.split(':')));
return _.fromPairs(_.map((serializedOptions || '').split(';'), (option) => option.split(':')));
},
getNodeListFromTabOptions(options) {
var nodeIds = utils.deserializeTabOptions(options.screenOptions[0]).nodes;

View File

@ -93,7 +93,7 @@ var DashboardTab = React.createClass({
title: i18n(ns + 'horizon'),
description: i18n(ns + 'horizon_description')
}].concat(
cluster.get('pluginLinks').invoke('pick', 'url', 'title', 'description')
cluster.get('pluginLinks').invokeMap('pick', 'url', 'title', 'description')
);
return (
@ -368,7 +368,7 @@ var ClusterActionsPanel = React.createClass({
validate(action) {
return _.reduce(
this.validations(action),
(accumulator, validator) => _.merge(
(accumulator, validator) => _.mergeWith(
accumulator,
validator.call(this, this.props.cluster),
(a, b) => a.concat(_.compact(b))
@ -492,10 +492,10 @@ var ClusterActionsPanel = React.createClass({
var validRoleModels = roleModels.filter(
(role) => !role.checkRestrictions(configModels).result
);
var limitValidations = _.zipObject(validRoleModels.map(
var limitValidations = _.fromPairs(validRoleModels.map(
(role) => [role.get('name'), role.checkLimits(configModels, cluster.get('nodes'))]
));
var limitRecommendations = _.zipObject(validRoleModels.map(
var limitRecommendations = _.fromPairs(validRoleModels.map(
(role) => [
role.get('name'),
role.checkLimits(configModels, cluster.get('nodes'), true, ['recommended'])
@ -1033,7 +1033,7 @@ var ClusterInfo = React.createClass({
getNumberOfNodesWithRole(field) {
var nodes = this.props.cluster.get('nodes');
if (field === 'total') return nodes.length;
return _.filter(nodes.invoke('hasRole', field)).length;
return _.filter(nodes.invokeMap('hasRole', field)).length;
},
getNumberOfNodesWithStatus(field) {
var nodes = this.props.cluster.get('nodes');
@ -1080,7 +1080,7 @@ var ClusterInfo = React.createClass({
},
renderStatistics() {
var {cluster} = this.props;
var roles = _.union(['total'], cluster.get('roles').pluck('name'));
var roles = _.union(['total'], cluster.get('roles').map('name'));
var statuses = _.without(models.Node.prototype.statuses, 'discover');
return (
<div className='row statistics-block'>

View File

@ -126,7 +126,7 @@ var HealthcheckTabContent = React.createClass({
this.setState({credentialsVisible: !this.state.credentialsVisible});
},
handleSelectAllClick(name, value) {
this.props.tests.invoke('set', {checked: value});
this.props.tests.invokeMap('set', {checked: value});
},
handleInputChange(name, value) {
var credentials = this.state.credentials;
@ -204,7 +204,7 @@ var HealthcheckTabContent = React.createClass({
actionInProgress: true,
stoppingTestsInProgress: true
});
testruns.invoke('set', {status: 'stopped'});
testruns.invokeMap('set', {status: 'stopped'});
testruns.toJSON = function() {
return this.map((testrun) =>
_.pick(testrun.attributes, 'id', 'status')
@ -331,13 +331,13 @@ var TestSet = React.createClass({
],
handleTestSetCheck(name, value) {
this.props.testset.set('checked', value);
this.props.tests.invoke('set', {checked: value});
this.props.tests.invokeMap('set', {checked: value});
},
componentWillUnmount() {
this.props.tests.invoke('off', 'change:checked', this.updateTestsetCheckbox, this);
this.props.tests.invokeMap('off', 'change:checked', this.updateTestsetCheckbox, this);
},
componentWillMount() {
this.props.tests.invoke('on', 'change:checked', this.updateTestsetCheckbox, this);
this.props.tests.invokeMap('on', 'change:checked', this.updateTestsetCheckbox, this);
},
updateTestsetCheckbox() {
this.props.testset.set(

View File

@ -63,7 +63,7 @@ var EditNodeDisksScreen = React.createClass({
},
isLocked() {
return !!this.props.cluster.task({group: 'deployment', active: true}) ||
!_.every(this.props.nodes.invoke('areDisksConfigurable'));
!_.every(this.props.nodes.invokeMap('areDisksConfigurable'));
},
updateInitialData() {
this.setState({initialDisks: _.cloneDeep(this.props.nodes.at(0).disks.toJSON())});

View File

@ -169,7 +169,7 @@ var EditNodeInterfacesScreen = React.createClass({
},
isLocked() {
return !!this.props.cluster.task({group: 'deployment', active: true}) ||
!_.every(this.props.nodes.invoke('areInterfacesConfigurable'));
!_.every(this.props.nodes.invokeMap('areInterfacesConfigurable'));
},
interfacesPickFromJSON(json) {
// Pick certain interface fields that have influence on hasChanges.
@ -205,14 +205,14 @@ var EditNodeInterfacesScreen = React.createClass({
// Do not compare offloading modes if they differ
if (!_.get(limitations, 'offloading_modes.equal', false)) return false;
// otherwise remove set states before it
return !_.isEqual(..._.invoke(
return !_.isEqual(..._.invokeMap(
[data, interfacesData[index][attribute]],
(value) => utils.deepOmit(value, ['state']))
);
}
case 'interface_properties': {
// Omit restricted parameters from the comparison
return !_.isEqual(..._.invoke(
return !_.isEqual(..._.invokeMap(
[data, interfacesData[index][attribute]],
_.omit, omittedProperties)
);
@ -319,8 +319,8 @@ var EditNodeInterfacesScreen = React.createClass({
// determining slaves using bonding map
_.each(nodeBonds, (bond, bondIndex) => {
var slaveIndexes = bondingMap[bondIndex];
var slaveInterfaces = _.map(slaveIndexes, node.interfaces.at, node.interfaces);
bond.set({slaves: _.invoke(slaveInterfaces, 'pick', 'name')});
var slaveInterfaces = _.map(slaveIndexes, (index) => node.interfaces.at(index));
bond.set({slaves: _.invokeMap(slaveInterfaces, 'pick', 'name')});
});
// Assigning networks according to user choice and interface properties
@ -418,7 +418,7 @@ var EditNodeInterfacesScreen = React.createClass({
name: bondName,
mode: bondMode,
assigned_networks: new models.InterfaceNetworks(),
slaves: _.invoke(interfaces, 'pick', 'name'),
slaves: _.invokeMap(interfaces, 'pick', 'name'),
bond_properties: {
mode: bondMode,
type__: bondType
@ -449,7 +449,7 @@ var EditNodeInterfacesScreen = React.createClass({
);
}
bond.set({
slaves: bond.get('slaves').concat(_.invoke(interfaces, 'pick', 'name')),
slaves: bond.get('slaves').concat(_.invokeMap(interfaces, 'pick', 'name')),
offloading_modes: this.getIntersectedOffloadingModes(interfaces.concat(bond)),
interface_properties: bondProperties
});
@ -470,7 +470,7 @@ var EditNodeInterfacesScreen = React.createClass({
});
},
mergeLimitations(limitation1, limitation2) {
return _.merge(limitation1, limitation2, (value1, value2, interfaceProperty) => {
return _.mergeWith(limitation1, limitation2, (value1, value2, interfaceProperty) => {
switch (interfaceProperty) {
case 'mtu':
case 'offloading_modes':
@ -557,7 +557,7 @@ var EditNodeInterfacesScreen = React.createClass({
var networkConfiguration = cluster.get('networkConfiguration');
var networkingParameters = networkConfiguration.get('networking_parameters');
var networks = networkConfiguration.get('networks');
var slaveInterfaceNames = _.map(_.flatten(_.filter(interfaces.pluck('slaves'))), 'name');
var slaveInterfaceNames = _.map(_.flatten(_.filter(interfaces.map('slaves'))), 'name');
interfaces.each((ifc) => {
if (!_.includes(slaveInterfaceNames, ifc.get('name'))) {
@ -574,8 +574,8 @@ var EditNodeInterfacesScreen = React.createClass({
}
},
validateSpeedsForBonding(interfaces) {
var slaveInterfaces = _.flatten(_.invoke(interfaces, 'getSlaveInterfaces'), true);
var speeds = _.invoke(slaveInterfaces, 'get', 'current_speed');
var slaveInterfaces = _.flatten(_.invokeMap(interfaces, 'getSlaveInterfaces'), true);
var speeds = _.invokeMap(slaveInterfaces, 'get', 'current_speed');
// warn if not all speeds are the same or there are interfaces with unknown speed
return _.uniq(speeds).length > 1 || !_.compact(speeds).length;
},
@ -609,7 +609,7 @@ var EditNodeInterfacesScreen = React.createClass({
render() {
var {nodes, interfaces} = this.props;
var {interfacesByIndex, indexByInterface} = this.state;
var nodeNames = nodes.pluck('name');
var nodeNames = nodes.map('name');
var locked = this.isLocked();
var configurationTemplateExists = this.configurationTemplateExists();
@ -651,7 +651,7 @@ var EditNodeInterfacesScreen = React.createClass({
var unbondingPossible = !checkedInterfaces.length && !!checkedBonds.length;
var hasChanges = this.hasChanges();
var slaveInterfaceNames = _.map(_.flatten(_.filter(interfaces.pluck('slaves'))), 'name');
var slaveInterfaceNames = _.map(_.flatten(_.filter(interfaces.map('slaves'))), 'name');
var loadDefaultsEnabled = !this.state.actionInProgress;
var revertChangesEnabled = !this.state.actionInProgress && hasChanges;

View File

@ -524,7 +524,7 @@ var Node = React.createClass({
var ns = 'cluster_page.nodes_tab.node.';
var isSelectable = node.isSelectable() && !locked && mode !== 'edit';
var status = node.getStatusSummary();
var roles = cluster ? node.sortedRoles(cluster.get('roles').pluck('name')) : [];
var roles = cluster ? node.sortedRoles(cluster.get('roles').map('name')) : [];
var nodePanelClasses = {
node: true,

View File

@ -81,7 +81,7 @@ class Filter {
if (this.isNumberRange) {
var limits = [0, 0];
if (nodes.length) {
var resources = nodes.invoke('resource', this.name);
var resources = nodes.invokeMap('resource', this.name);
limits = [_.min(resources), _.max(resources)];
if (this.name === 'hdd' || this.name === 'ram') {
limits = [
@ -142,7 +142,7 @@ NodeListScreen = React.createClass({
)
:
Filter.fromObject(defaultFilters, false);
_.invoke(activeFilters, 'updateLimits', nodes, false);
_.invokeMap(activeFilters, 'updateLimits', nodes, false);
var availableSorters = sorters.map((name) => new Sorter(name, 'asc', false));
var activeSorters = this.props.saveUISettings ?
@ -166,7 +166,7 @@ NodeListScreen = React.createClass({
// additonal Nodes tab states (Cluster page)
var settings = cluster.get('settings');
var roles = cluster.get('roles').pluck('name');
var roles = cluster.get('roles').map('name');
var selectedRoles = nodes.length ?
_.filter(roles, (role) => !nodes.some((node) => !node.hasRole(role)))
:
@ -203,8 +203,8 @@ NodeListScreen = React.createClass({
return this.props.nodes.fetch();
},
calculateFilterLimits() {
_.invoke(this.state.availableFilters, 'updateLimits', this.props.nodes, true);
_.invoke(this.state.activeFilters, 'updateLimits', this.props.nodes, false);
_.invokeMap(this.state.availableFilters, 'updateLimits', this.props.nodes, true);
_.invokeMap(this.state.activeFilters, 'updateLimits', this.props.nodes, false);
},
normalizeAppliedFilters(checkStandardNodeFilters = false) {
if (!this.props.cluster || this.props.mode !== 'add') {
@ -292,7 +292,7 @@ NodeListScreen = React.createClass({
},
updateInitialRoles() {
this.initialRoles = _.zipObject(this.props.nodes.map('id'),
this.props.nodes.pluck('pending_roles'));
this.props.nodes.map('pending_roles'));
},
checkRoleAssignment(node, roles, options) {
if (!options.assign) node.set({pending_roles: node.previous('pending_roles')}, {assign: true});
@ -387,10 +387,10 @@ NodeListScreen = React.createClass({
});
break;
case 'roles':
options = this.props.roles.invoke('pick', 'name', 'label');
options = this.props.roles.invokeMap('pick', 'name', 'label');
break;
case 'group_id':
options = _.uniq(this.props.nodes.pluck('group_id')).map((groupId) => {
options = _.uniq(this.props.nodes.map('group_id')).map((groupId) => {
var nodeNetworkGroup = this.props.nodeNetworkGroups.get(groupId);
return {
name: groupId,
@ -407,7 +407,7 @@ NodeListScreen = React.createClass({
});
break;
case 'cluster':
options = _.uniq(this.props.nodes.pluck('cluster')).map((clusterId) => {
options = _.uniq(this.props.nodes.map('cluster')).map((clusterId) => {
return {
name: clusterId,
label: clusterId ? this.props.clusters.get(clusterId).get('name') :
@ -474,7 +474,7 @@ NodeListScreen = React.createClass({
});
},
getNodeLabels() {
return _.chain(this.props.nodes.pluck('labels')).flatten().map(_.keys).flatten().uniq().value();
return _.chain(this.props.nodes.map('labels')).flatten().map(_.keys).flatten().uniq().value();
},
getFilterResults(filter, node) {
var result;
@ -512,7 +512,7 @@ NodeListScreen = React.createClass({
var selectedNodes = new models.Nodes(this.props.nodes.filter((node) => {
return this.props.selectedNodeIds[node.id];
}));
var selectedNodeLabels = _.chain(selectedNodes.pluck('labels'))
var selectedNodeLabels = _.chain(selectedNodes.map('labels'))
.flatten()
.map(_.keys)
.flatten()
@ -1222,7 +1222,7 @@ ManagementPanel = React.createClass({
>
{disksConflict && <i className='glyphicon glyphicon-danger-sign' />}
{i18n('dialog.show_node.disk_configuration' +
(_.every(nodes.invoke('areDisksConfigurable')) ? '_action' : ''))
(_.every(nodes.invokeMap('areDisksConfigurable')) ? '_action' : ''))
}
</button>
<button
@ -1232,7 +1232,7 @@ ManagementPanel = React.createClass({
>
{interfaceConflict && <i className='glyphicon glyphicon-danger-sign' />}
{i18n('dialog.show_node.network_configuration' +
(_.every(nodes.invoke('areInterfacesConfigurable')) ? '_action' : ''))
(_.every(nodes.invokeMap('areInterfacesConfigurable')) ? '_action' : ''))
}
</button>
</div>,
@ -2011,7 +2011,7 @@ NodeList = React.createClass({
return (sorterNameFormatters[sorter.name] || sorterNameFormatters.default)();
})).join('; ');
};
var groups = _.pairs(_.groupBy(this.props.nodes, groupingMethod));
var groups = _.toPairs(_.groupBy(this.props.nodes, groupingMethod));
// sort grouped nodes by name, mac or ip
var formattedSorters = _.compact(_.map(this.props.activeSorters, (sorter) => {
@ -2028,7 +2028,7 @@ NodeList = React.createClass({
}
// sort grouped nodes by other applied sorters
var preferredRolesOrder = this.props.roles.pluck('name');
var preferredRolesOrder = this.props.roles.map('name');
return groups.sort((group1, group2) => {
var result;
_.each(this.props.activeSorters, (sorter) => {
@ -2106,7 +2106,7 @@ NodeList = React.createClass({
},
render() {
var groups = this.groupNodes();
var rolesWithLimitReached = _.keys(_.omit(this.props.processedRoleLimits,
var rolesWithLimitReached = _.keys(_.omitBy(this.props.processedRoleLimits,
(roleLimit, roleName) => {
return roleLimit.valid || !_.includes(this.props.selectedRoles, roleName);
}

View File

@ -30,7 +30,7 @@ var SettingSection = React.createClass({
// FIXME: hack for #1442475 to lock images_ceph in env with controllers
if (settingName === 'images_ceph') {
if (_.includes(_.flatten(this.props.cluster.get('nodes').pluck('pending_roles')),
if (_.includes(_.flatten(this.props.cluster.get('nodes').map('pending_roles')),
'controller')) {
result = true;
messages.push(i18n('cluster_page.settings_tab.images_ceph_warning'));

View File

@ -279,7 +279,7 @@ var SettingsTab = React.createClass({
}
}
});
groupedSettings = _.omit(groupedSettings, _.isEmpty);
groupedSettings = _.omitBy(groupedSettings, _.isEmpty);
return (
<div key={this.state.key} className={utils.classNames(classes)}>

View File

@ -38,8 +38,8 @@ NotificationsPage = React.createClass({
},
checkDateIsToday(date) {
var today = new Date();
var day = _.padLeft(today.getDate(), 2, '0');
var month = _.padLeft(today.getMonth() + 1, 2, '0');
var day = _.padStart(today.getDate(), 2, '0');
var month = _.padStart(today.getMonth() + 1, 2, '0');
return [day, month, today.getFullYear()].join('-') === date;
},
render() {

View File

@ -766,8 +766,8 @@ var CreateClusterWizard = React.createClass({
this.components = new models.ComponentsCollection([], {releaseId: releaseId});
this.wizard.set({components: this.components});
this.components.fetch().then(() => {
this.components.invoke('expandWildcards', this.components);
this.components.invoke('restoreDefaultValue', this.components);
this.components.invokeMap('expandWildcards', this.components);
this.components.invokeMap('restoreDefaultValue', this.components);
this.setState({loading: false});
});
},