diff --git a/static/models.js b/static/models.js
index 5fe973096..70a53b09b 100644
--- a/static/models.js
+++ b/static/models.js
@@ -951,6 +951,10 @@ models.Settings = BaseModel
}
});
this.isValid({models});
+ },
+ sortAttributes({weight: weight1, label: label1}, {weight: weight2, label: label2}) {
+ if (weight1 !== weight2) return weight1 - weight2;
+ return utils.natsort(label1, label2);
}
});
diff --git a/static/views/cluster_page_tabs/network_tab.js b/static/views/cluster_page_tabs/network_tab.js
index cddfb269a..fa24b01a3 100644
--- a/static/views/cluster_page_tabs/network_tab.js
+++ b/static/views/cluster_page_tabs/network_tab.js
@@ -1569,47 +1569,49 @@ var NetworkSettings = React.createClass({
return (
{
- _.chain(settings.attributes)
- .keys()
- .filter(
- (sectionName) => {
- var section = settings.get(sectionName);
- return (section.metadata.group === 'network' ||
- _.some(section, {group: 'network'})) &&
- !this.checkRestrictions('hide', section.metadata).result;
- }
+ _.chain(
+ _.keys(settings.attributes).sort(
+ (sectionName1, sectionName2) => settings.sortAttributes(
+ settings.get(sectionName1 + '.metadata'),
+ settings.get(sectionName2 + '.metadata')
+ )
)
- .sortBy((sectionName) => {
- var {weight, label} = settings.get(sectionName + '.metadata');
- return [weight, label];
- })
- .map(
- (sectionName) => {
- var section = settings.get(sectionName);
- var settingsToDisplay = _.compact(_.map(section, (setting, settingName) =>
- (section.metadata.group || setting.group === 'network') &&
- settings.isSettingVisible(setting, settingName, this.props.configModels) &&
- settingName
- ));
- if (_.isEmpty(settingsToDisplay) && !settings.isPlugin(section)) return null;
- return ;
- }
- )
- .value()
+ )
+ .filter(
+ (sectionName) => {
+ var section = settings.get(sectionName);
+ return (section.metadata.group === 'network' ||
+ _.some(section, {group: 'network'})) &&
+ !this.checkRestrictions('hide', section.metadata).result;
+ }
+ )
+ .map(
+ (sectionName) => {
+ var section = settings.get(sectionName);
+ var settingsToDisplay = _.compact(_.map(section, (setting, settingName) =>
+ (section.metadata.group || setting.group === 'network') &&
+ settings.isSettingVisible(setting, settingName, this.props.configModels) &&
+ settingName
+ ));
+ if (_.isEmpty(settingsToDisplay) && !settings.isPlugin(section)) return null;
+ return ;
+ }
+ )
+ .value()
}
);
diff --git a/static/views/cluster_page_tabs/nodes_tab_screens/edit_node_interfaces_screen.js b/static/views/cluster_page_tabs/nodes_tab_screens/edit_node_interfaces_screen.js
index 83b402af3..b097500e9 100644
--- a/static/views/cluster_page_tabs/nodes_tab_screens/edit_node_interfaces_screen.js
+++ b/static/views/cluster_page_tabs/nodes_tab_screens/edit_node_interfaces_screen.js
@@ -1206,11 +1206,13 @@ var NodeInterface = React.createClass({
attributes.get(utils.makePath(sectionName, 'metadata'))
).result
)
- .sortBy((sectionName) => {
- var {weight, label} = attributes.get(sectionName + '.metadata');
- return [weight, label];
- })
- .value();
+ .value()
+ .sort(
+ (sectionName1, sectionName2) => attributes.sortAttributes(
+ attributes.get(sectionName1 + '.metadata'),
+ attributes.get(sectionName2 + '.metadata')
+ )
+ );
var bondingPossible = !!availableBondingTypes.length && !configurationTemplateExists && !locked;
var networkErrors = (_.flatten((errors || {}).networks || [])).join(', ');
@@ -1565,19 +1567,19 @@ var NodeInterfaceAttributes = React.createClass({
// the following code provides the following suggestion:
// first setting in NIC's attribute section should be a checkbox
// that reflects enableness of the section on the particular NIC
- var name = _.chain(_.keys(attributes.get(sectionName)))
- .sortBy((settingName) => {
- var {weight, label} = attributes.get(utils.makePath(sectionName, settingName));
- return [weight, label];
- })
- .find(
- (settingName) => attributes.isSettingVisible(
- attributes.get(utils.makePath(sectionName, settingName)),
- settingName,
- configModels
+ var name = _.find(
+ _.keys(attributes.get(sectionName)).sort(
+ (settingName1, settingName2) => attributes.sortAttributes(
+ attributes.get(utils.makePath(sectionName, settingName1)),
+ attributes.get(utils.makePath(sectionName, settingName2))
)
+ ),
+ (settingName) => attributes.isSettingVisible(
+ attributes.get(utils.makePath(sectionName, settingName)),
+ settingName,
+ configModels
)
- .value();
+ );
var value = attributes.get(utils.makePath(sectionName, name, 'value'));
if (_.isBoolean(value)) {
diff --git a/static/views/cluster_page_tabs/setting_section.js b/static/views/cluster_page_tabs/setting_section.js
index 6c57edba8..f3d21d909 100644
--- a/static/views/cluster_page_tabs/setting_section.js
+++ b/static/views/cluster_page_tabs/setting_section.js
@@ -269,10 +269,12 @@ var SettingSection = React.createClass({
var isPluginWithLegacyTasksLocked = isPlugin && metadata.contains_legacy_tasks &&
!settings.get('common.propagate_task_deploy.value');
- var sortedSettings = _.sortBy(settingsToDisplay, (settingName) => {
- var {weight, label} = section[settingName];
- return [weight, label];
- });
+ var sortedSettings = settingsToDisplay.sort(
+ (settingName1, settingName2) => settings.sortAttributes(
+ section[settingName1],
+ section[settingName2]
+ )
+ );
var processedGroupRestrictions = this.processRestrictions(metadata);
var processedGroupDependencies = this.checkDependencies(sectionName, 'metadata');
var isGroupDisabled = locked ||
diff --git a/static/views/cluster_page_tabs/settings_tab.js b/static/views/cluster_page_tabs/settings_tab.js
index 8cd8a6301..3df56a87c 100644
--- a/static/views/cluster_page_tabs/settings_tab.js
+++ b/static/views/cluster_page_tabs/settings_tab.js
@@ -304,10 +304,12 @@ var SettingsTab = React.createClass({
{_.map(groupedSettings, (selectedGroup, groupName) => {
if (groupName !== activeSettingsSectionName) return null;
- var sortedSections = _.sortBy(_.keys(selectedGroup), (sectionName) => {
- var {weight, label} = settings.get(sectionName + '.metadata');
- return [weight, label];
- });
+ var sortedSections = _.keys(selectedGroup).sort(
+ (sectionName1, sectionName2) => settings.sortAttributes(
+ settings.get(sectionName1 + '.metadata'),
+ settings.get(sectionName2 + '.metadata')
+ )
+ );
return (
{_.map(sortedSections, (sectionName) => {
diff --git a/static/views/dialogs.js b/static/views/dialogs.js
index cd55e59ed..5b2073323 100644
--- a/static/views/dialogs.js
+++ b/static/views/dialogs.js
@@ -1678,7 +1678,14 @@ export var ShowNodeInfoDialog = React.createClass({
var isLocked = !node.get('pending_addition') || actionInProgress;
- var attributes = _.chain(_.keys(nodeAttributes.attributes))
+ var attributes = _.chain(
+ _.keys(nodeAttributes.attributes).sort(
+ (sectionName1, sectionName2) => nodeAttributes.sortAttributes(
+ nodeAttributes.get(sectionName1 + '.metadata'),
+ nodeAttributes.get(sectionName2 + '.metadata')
+ )
+ )
+ )
.filter(
(sectionName) => !nodeAttributes.checkRestrictions(
configModels,
@@ -1686,10 +1693,6 @@ export var ShowNodeInfoDialog = React.createClass({
nodeAttributes.get(sectionName).metadata
).result
)
- .sortBy((sectionName) => {
- var {weight, label} = nodeAttributes.get(sectionName + '.metadata');
- return [weight, label];
- })
.map(
(sectionName) => {
var metadata = nodeAttributes.get(utils.makePath(sectionName, 'metadata'));