You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2014/01/06 14:18:47 UTC
[3/5] AMBARI-4227. New ability to filter hosts based on "Maintenance"
status. (onechiporenko)
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/assets/font/fontawesome-webfont.woff
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/font/fontawesome-webfont.woff b/ambari-web/app/assets/font/fontawesome-webfont.woff
index 09f2469..b9bd17e 100644
Binary files a/ambari-web/app/assets/font/fontawesome-webfont.woff and b/ambari-web/app/assets/font/fontawesome-webfont.woff differ
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/assets/licenses/NOTICE.txt
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/licenses/NOTICE.txt b/ambari-web/app/assets/licenses/NOTICE.txt
index 7a464dc..d2aa8f8 100644
--- a/ambari-web/app/assets/licenses/NOTICE.txt
+++ b/ambari-web/app/assets/licenses/NOTICE.txt
@@ -30,9 +30,10 @@ Copyright (c) 2012, Michael Bostock.
This product includes bootstrap-datepicker.js (http://www.eyecon.ro/bootstrap-datepicker - Apache License, Version 2.0)
Copyright (c) 2012 Stefan Petre
-This product includes Font Awesome 2.0 (http://fortawesome.github.com/Font-Awesome - Creative Commons 3.0)
+This product includes Font Awesome 3.2.1 (http://fortawesome.github.com/Font-Awesome - Creative Commons 3.0)
+Copyright (c) 2013 Dave Gandy
-This product incudes Rickshaw 1.1.2 (http://code.shutterstock.com/rickshaw/ - MIT License)
+This product includes Rickshaw 1.1.2 (http://code.shutterstock.com/rickshaw/ - MIT License)
Copyright (C) 2011 by Shutterstock Images, LLC
This product includes Timeago (http://timeago.yarp.com/ - MIT License)
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/controllers/main/host.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host.js b/ambari-web/app/controllers/main/host.js
index c037e3b..65f9981 100644
--- a/ambari-web/app/controllers/main/host.js
+++ b/ambari-web/app/controllers/main/host.js
@@ -32,6 +32,7 @@ App.MainHostController = Em.ArrayController.extend({
/**
* Components which will be shown in component filter
+ * @returns {Array}
*/
componentsForFilter:function() {
var installedComponents = componentHelper.getInstalledComponents();
@@ -39,21 +40,33 @@ App.MainHostController = Em.ArrayController.extend({
return installedComponents;
}.property('App.router.clusterController.isLoaded'),
+ /**
+ * Master components
+ * @returns {Array}
+ */
masterComponents:function () {
return this.get('componentsForFilter').filterProperty('isMaster', true);
}.property('componentsForFilter'),
+ /**
+ * Slave components
+ * @returns {Array}
+ */
slaveComponents:function () {
return this.get('componentsForFilter').filterProperty('isSlave', true);
}.property('componentsForFilter'),
+ /**
+ * Client components
+ * @returns {Array}
+ */
clientComponents: function() {
return this.get('componentsForFilter').filterProperty('isClient', true);
}.property('componentsForFilter'),
/**
* Filter hosts by componentName of <code>component</code>
- * @param component App.HostComponent
+ * @param {App.HostComponent} component
*/
filterByComponent:function (component) {
if(!component)
@@ -99,9 +112,6 @@ App.MainHostController = Em.ArrayController.extend({
templateName: require('templates/main/host/alerts_popup')
}),
primary: Em.I18n.t('common.close'),
- onPrimary: function() {
- this.hide();
- },
secondary : null,
didInsertElement: function () {
this.$().find('.modal-footer').addClass('align-center');
@@ -125,7 +135,7 @@ App.MainHostController = Em.ArrayController.extend({
/**
* remove hosts with id equal host_id
- * @param host_id
+ * @param {String} host_id
*/
checkRemoved:function (host_id) {
var hosts = this.get('content');
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 532a1eb..8ded97d 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -164,6 +164,7 @@ Em.I18n.translations = {
'common.restart': 'Restart',
'common.discard': 'Discard',
'common.actions': 'Actions',
+ 'common.maintenance': 'Maintenance',
'requestInfo.installComponents':'Install Components',
'requestInfo.installServices':'Install Services',
@@ -1303,6 +1304,9 @@ Em.I18n.translations = {
'hosts.table.restartComponents.withNames':'Restart {0}',
'hosts.table.restartComponents.withoutNames':'{0} components should be restarted',
+ 'hosts.table.componentsInMaintenance.withNames':'{0} in maintenance mode',
+ 'hosts.table.componentsInMaintenance.withoutNames':'{0} components in maintenance mode',
+
'hosts.selectHostsDialog.title': 'Select Configuration Group Hosts',
'hosts.selectHostsDialog.message': 'Select hosts that should belong to this {0} Configuration Group. All hosts belonging to this group will have the same set of {0} configurations.',
'hosts.selectHostsDialog.filter.placeHolder': 'Filter...',
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/models/host.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/host.js b/ambari-web/app/models/host.js
index 91fe812..c215b73 100644
--- a/ambari-web/app/models/host.js
+++ b/ambari-web/app/models/host.js
@@ -44,61 +44,104 @@ App.Host = DS.Model.extend({
cpuSystem:DS.attr('number'),
cpuUser:DS.attr('number'),
+ /**
+ * Overall CPU usage (system and user)
+ * @returns {Number}
+ */
cpuUsage: function () {
- if (this.get('cpuSystem') && this.get('cpu_user')) {
- return this.get('cpuSystem') + this.get('cpu_user');
+ if (this.get('cpuSystem') && this.get('cpuUser')) {
+ return this.get('cpuSystem') + this.get('cpuUser');
}
+ return 0;
}.property('cpuSystem', 'cpuUser'),
+ /**
+ * Percent value of used memory
+ * @returns {Number}
+ */
memoryUsage: function () {
if (this.get('memFree') && this.get('memTotal')) {
var memUsed = this.get('memTotal') - this.get('memFree');
return (100 * memUsed) / this.get('memTotal');
}
+ return 0;
}.property('memTotal', 'memFree'),
+ /**
+ * Get count of critical alerts for current host
+ * @returns {Number}
+ */
criticalAlertsCount: function () {
return App.router.get('clusterController.alertsHostMap')[this.get('hostName')];
}.property('App.router.clusterController.alerts.length'),
+ /**
+ * Get count of host components with stale configs
+ * @returns {Number}
+ */
componentsWithStaleConfigsCount: function() {
return this.get('hostComponents').filterProperty('staleConfigs', true).length;
}.property('hostComponents.@each.staleConfigs'),
+ /**
+ * Get count of host components in maintenance mode
+ * @returns {Number}
+ */
+ componentsInMaintenanceCount: function() {
+ return this.get('hostComponents').filterProperty('workStatus', App.HostComponentStatus.maintenance).length;
+ }.property('hostsComponents.@each.workStatus').volatile(),
+
+ /**
+ * Truncate hostName if it longer than 43 symbols
+ * @returns {String}
+ */
publicHostNameFormatted: function() {
return this.get('publicHostName').length < 43 ? this.get('publicHostName') : this.get('publicHostName').substr(0, 40) + '...';
}.property('publicHostName'),
+ /**
+ * Count of mounted on host disks
+ * @returns {Number}
+ */
disksMounted: function() {
return this.get('diskInfo.length');
}.property('diskInfo.length'),
/**
* API return diskTotal and diskFree. Need to save their different
+ * @returns {Number}
*/
diskUsed: function(){
return this.get('diskTotal') - this.get('diskFree');
}.property('diskFree', 'diskTotal'),
+
/**
* Format diskUsed value to float with 2 digits (also convert to GB)
+ * @returns {String} Format: '*** GB'
*/
diskUsedFormatted: function() {
return Math.round(this.get('diskUsed') * Math.pow(10, 2)) / Math.pow(10, 2) + 'GB';
}.property('diskUsed'),
+
/**
* Format diskTotal value to float with 2 digits (also convert to GB)
+ * @returns {String} Format: '*** GB'
*/
diskTotalFormatted: function() {
return Math.round(this.get('diskTotal') * Math.pow(10, 2)) / Math.pow(10, 2) + 'GB';
}.property('diskTotal'),
+
/**
* Percent value of used disk space
+ * @returns {Number}
*/
diskUsage: function() {
return (this.get('diskUsed')) / this.get('diskTotal') * 100;
}.property('diskUsed', 'diskTotal'),
+
/**
* Format diskUsage to float with 2 digits
+ * @returns {String} Format: '**.** %'
*/
diskUsageFormatted: function() {
if (isNaN(this.get('diskUsage')) || this.get('diskUsage') < 0) {
@@ -111,6 +154,10 @@ App.Host = DS.Model.extend({
return s + '%';
}.property('diskUsage'),
+ /**
+ * Formatted string with data about disk usage
+ * @returns {String}
+ */
diskInfoBar: function() {
if (isNaN(this.get('diskUsage')) || this.get('diskUsage') < 0) {
return this.get('diskUsageFormatted');
@@ -118,25 +165,39 @@ App.Host = DS.Model.extend({
return this.get('diskUsedFormatted') + '/' + this.get('diskTotalFormatted') + ' (' + this.get('diskUsageFormatted')
+ ' ' + Em.I18n.t('services.service.summary.diskInfoBar.used') + ')';
}.property('diskUsedFormatted', 'diskTotalFormatted'),
+
/**
- * formatted bytes to appropriate value
+ * Formatted bytes to appropriate value
+ * @returns {String}
*/
memoryFormatted: function () {
return misc.formatBandwidth(this.get('memory') * 1024);
}.property('memory'),
+
/**
* Return true if the host has not sent heartbeat within the last 180 seconds
+ * @returns {bool}
*/
isNotHeartBeating : function() {
return (App.testMode) ? false : ((new Date()).getTime() - this.get('lastHeartBeatTime')) > 180 * 1000;
}.property('lastHeartBeatTime'),
+ /**
+ * Average load
+ * @returns {Number}
+ */
loadAvg: function() {
if (this.get('loadOne') != null) return this.get('loadOne').toFixed(2);
if (this.get('loadFive') != null) return this.get('loadFive').toFixed(2);
if (this.get('loadFifteen') != null) return this.get('loadFifteen').toFixed(2);
+ return null;
}.property('loadOne', 'loadFive', 'loadFifteen'),
+ /**
+ * Host health indicator
+ * Based on <code>healthStatus</code>
+ * @returns {String}
+ */
healthClass: function(){
var statusMap = {
'UNKNOWN': 'health-status-DEAD-YELLOW',
@@ -147,6 +208,11 @@ App.Host = DS.Model.extend({
return statusMap[this.get('healthStatus')] || 'health-status-DEAD-YELLOW';
}.property('healthStatus'),
+ /**
+ * Tooltip for host indicator
+ * Contains affected host components names (based on <code>healthClass</code>)
+ * @returns {String}
+ */
healthToolTip: function(){
var hostComponents = this.get('hostComponents').filter(function(item){
if(item.get('workStatus') !== App.HostComponentStatus.started){
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/models/host_component.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/host_component.js b/ambari-web/app/models/host_component.js
index f94446b..081442c 100644
--- a/ambari-web/app/models/host_component.js
+++ b/ambari-web/app/models/host_component.js
@@ -26,6 +26,10 @@ App.HostComponent = DS.Model.extend({
staleConfigs: DS.attr('boolean'),
host: DS.belongsTo('App.Host'),
service: DS.belongsTo('App.Service'),
+ /**
+ * Determine if component is client
+ * @returns {bool}
+ */
isClient:function () {
if(['PIG', 'SQOOP', 'HCAT', 'MAPREDUCE2_CLIENT'].contains(this.get('componentName'))){
return true;
@@ -33,12 +37,27 @@ App.HostComponent = DS.Model.extend({
return Boolean(this.get('componentName').match(/_client/gi));
}.property('componentName'),
+ /**
+ * Determine if component is running now
+ * Based on <code>workStatus</code>
+ * @returns {bool}
+ */
isRunning: function(){
return (this.get('workStatus') == 'STARTED' || this.get('workStatus') == 'STARTING');
}.property('workStatus'),
+
+ /**
+ * Formatted <code>componentName</code>
+ * @returns {String}
+ */
displayName: function () {
return App.format.role(this.get('componentName'));
}.property('componentName'),
+
+ /**
+ * Determine if component is master
+ * @returns {bool}
+ */
isMaster: function () {
switch (this.get('componentName')) {
case 'NAMENODE':
@@ -64,6 +83,11 @@ App.HostComponent = DS.Model.extend({
return false;
}
}.property('componentName'),
+
+ /**
+ * Determine if component is slave
+ * @returns {bool}
+ */
isSlave: function(){
switch (this.get('componentName')) {
case 'DATANODE':
@@ -82,6 +106,7 @@ App.HostComponent = DS.Model.extend({
* They include some from master components,
* some from slave components, and rest from
* client components.
+ * @returns {bool}
*/
isDeletable: function() {
var canDelete = false;
@@ -104,6 +129,7 @@ App.HostComponent = DS.Model.extend({
/**
* A host-component is decommissioning when it is in HDFS service's list of
* decomNodes.
+ * @returns {bool}
*/
isDecommissioning: function () {
var decommissioning = false;
@@ -119,6 +145,7 @@ App.HostComponent = DS.Model.extend({
}.property('componentName', 'host.hostName', 'App.router.clusterController.isLoaded', 'App.router.updateController.isUpdated'),
/**
* User friendly host component status
+ * @returns {String}
*/
componentTextStatus: function () {
return App.HostComponentStatus.getTextStatus(this.get("workStatus"));
@@ -138,6 +165,11 @@ App.HostComponentStatus = {
maintenance: "MAINTENANCE",
unknown: "UNKNOWN",
+ /**
+ * Get host component status in "machine" format
+ * @param {String} value
+ * @returns {String}
+ */
getKeyName:function(value){
switch(value){
case this.started:
@@ -162,6 +194,11 @@ App.HostComponentStatus = {
return 'Unknown';
},
+ /**
+ * Get user-friendly host component status
+ * @param {String} value
+ * @returns {String}
+ */
getTextStatus: function (value) {
switch (value) {
case this.installing:
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 1c25d2d..05531cf 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -2691,6 +2691,9 @@ table.graphs {
background-image: @status-dead-yellow-marker;
.status-dot-position;
}
+ .maintenance {
+ color: #000;
+ }
.host-name-search {
position: relative;
top: 0px;
@@ -2715,6 +2718,7 @@ table.graphs {
.health-status-bar {
font-size: 0.9em;
margin-left: 0;
+ margin-bottom: 15px;
min-width: 790px;
color: #b4b4b4;
.health-status {
@@ -2778,7 +2782,7 @@ table.graphs {
.col0,
td:first-child,
th:first-child {
- width: 3%;
+ width: 2%;
min-width:13px!important;
}
.col1,
@@ -2786,15 +2790,15 @@ table.graphs {
th:first-child + th{
width: 19%;
}
- .col2,
+ .col2, .col3,
td:first-child + td + td,
- th:first-child + th + th{
- width:3%;
+ th:first-child + th + th,
+ td:first-child + td + td + td,
+ th:first-child + th + th + th,{
+ width:2%;
min-width:13px!important;
}
- .col3,.col4,.col5,.col6,.col7,
- td:first-child + td + td + td,
- th:first-child + th + th + th,
+ .col4,.col5,.col6,.col7,.col8,
td:first-child + td + td + td + td,
th:first-child + th + th + th + th,
td:first-child + td + td + td + td + td,
@@ -2802,12 +2806,14 @@ table.graphs {
td:first-child + td + td + td + td + td + td,
th:first-child + th + th + th + th + th + th,
td:first-child + td + td + td + td + td + td + td,
- th:first-child + th + th + th + th + th + th + th{
- width: 12%;
- }
- .col8,
+ th:first-child + th + th + th + th + th + th + th,
td:first-child + td + td + td + td + td + td + td + td,
th:first-child + th + th + th + th + th + th + th + th{
+ width: 12%;
+ }
+ .col9,
+ td:first-child + td + td + td + td + td + td + td + td + td,
+ th:first-child + th + th + th + th + th + th + th + th + th{
width: 15%;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/templates/main/host.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host.hbs b/ambari-web/app/templates/main/host.hbs
index fcadc6f..8962ec7 100644
--- a/ambari-web/app/templates/main/host.hbs
+++ b/ambari-web/app/templates/main/host.hbs
@@ -27,16 +27,24 @@
{{#view view.statusFilter categoriesBinding="view.categories"}}
{{#each category in view.categories}}
{{#if category.isVisible}}
- |
+ {{#if category.alerts}}
+ <br /><br />
+ {{else}}
+ |
+ {{/if}}
<span {{bindAttr class="aaa :category-item category.itemClass"}}>
<a {{action selectCategory category target="view"}} href="#">
{{#if category.alerts}}
<span class="label label-important">{{t hosts.host.alerts.st}}</span>
{{else}}
{{#if category.restart}}
- <span class="muted icon-refresh"></span>
+ <span class="icon-refresh"></span>
{{else}}
- <span {{bindAttr class=":health-status category.healthStatusValue"}}> </span>
+ {{#if category.maintenance}}
+ <span class="maintenance icon-medkit"></span>
+ {{else}}
+ <span {{bindAttr class=":health-status category.healthStatusValue"}}> </span>
+ {{/if}}
{{/if}}
{{/if}}
{{category.label}}
@@ -63,6 +71,7 @@
<th class="first"> </th>
{{view view.parentView.nameSort}}
<th> </th>
+ <th> </th>
{{view view.parentView.ipSort}}
{{view view.parentView.cpuSort}}
{{view view.parentView.memorySort}}
@@ -74,6 +83,7 @@
<th class="first"> </th>
<th>{{view view.nameFilterView}}</th>
<th> </th>
+ <th> </th>
<th>{{view view.ipFilterView}}</th>
<th>{{view view.cpuFilterView}}</th>
<th>{{view view.ramFilterView}}</th>
@@ -102,6 +112,11 @@
<span class="muted icon-refresh" rel="ComponentsTooltip" {{bindAttr title="view.restartRequiredComponentsMessage"}}></span>
{{/if}}
</td>
+ <td class="maintenance">
+ {{#if host.componentsInMaintenanceCount}}
+ <span class="icon-medkit" rel="ComponentsTooltip" {{bindAttr title="view.componentsInMaintenanceMessage"}}></span>
+ {{/if}}
+ </td>
<td>{{host.ip}}</td>
<td>{{host.cpu}}</td>
<td>{{host.memoryFormatted}}</td>
@@ -114,7 +129,7 @@
<td>{{host.loadAvg}}</td>
<td>
- <a href="#" class="host-components-expander" {{action toggleComponents target="view"}}> <span class="caret right"></span>{{view.componentsMessage}}</a>
+ <a href="#" class="host-components-expander" {{action toggleComponents target="view"}}> <span class="caret right"></span>{{view.content.hostComponents.length}} {{pluralize view.content.hostComponents.length singular="t:common.component" plural="t:common.components"}}</a>
<div id="host-{{unbound host.hostName}}" class="host-components">
{{{view.labels}}}
</div>
@@ -124,7 +139,7 @@
{{else}}
<tr>
<td class="first"></td>
- <td colspan="8">
+ <td colspan="9">
{{t hosts.table.noHosts}}
</td>
</tr>
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/views/common/table_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/table_view.js b/ambari-web/app/views/common/table_view.js
index e80c4d8..ecbf7d9 100644
--- a/ambari-web/app/views/common/table_view.js
+++ b/ambari-web/app/views/common/table_view.js
@@ -348,6 +348,7 @@ App.TableView = Em.View.extend({
var filterConditions = this.get('filterConditions');
if (!filterConditions.length) {
this.set('filtersUsed', false);
+ return;
}
var filtersUsed = false;
filterConditions.forEach(function(filterCondition) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/a440c0a8/ambari-web/app/views/main/host.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host.js b/ambari-web/app/views/main/host.js
index 4e455f7..110d9c2 100644
--- a/ambari-web/app/views/main/host.js
+++ b/ambari-web/app/views/main/host.js
@@ -44,6 +44,7 @@ App.MainHostView = App.TableView.extend({
didInsertElement: function() {
this.addObserver('controller.clearFilters', this, this.clearFiltersObs);
this.clearFiltersObs();
+ this.addObserver('content.@each.hostComponents.@each', this, this.filter);
},
sortView: sort.wrapperView,
@@ -93,16 +94,10 @@ App.MainHostView = App.TableView.extend({
this.$('.host-components').toggle();
},
- componentsMessage: function() {
- var count = this.get('content.hostComponents.length');
- if (count == 1) {
- return count + ' ' + Em.I18n.t('common.component');
- }
- else {
- return count + ' ' + Em.I18n.t('common.components');
- }
- }.property('content.hostComponents.@each'),
-
+ /**
+ * Tooltip message for "Restart Required" icon
+ * @returns {String}
+ */
restartRequiredComponentsMessage: function() {
var restartRequiredComponents = this.get('content.hostComponents').filterProperty('staleConfigs', true);
var count = restartRequiredComponents.length;
@@ -113,10 +108,31 @@ App.MainHostView = App.TableView.extend({
return Em.I18n.t('hosts.table.restartComponents.withoutNames').format(count);
}.property('content.hostComponents.@each.staleConfigs'),
+ /**
+ * Tooltip message for "Maintenance" icon
+ * @returns {String}
+ */
+ componentsInMaintenanceMessage: function() {
+ var componentsInMaintenance = this.get('content.hostComponents').filterProperty('workStatus', App.HostComponentStatus.maintenance);
+ var count = componentsInMaintenance.length;
+ if (count <= 5) {
+ return Em.I18n.t('hosts.table.componentsInMaintenance.withNames').format(componentsInMaintenance.getEach('displayName').join(', '));
+ }
+ return Em.I18n.t('hosts.table.componentsInMaintenance.withoutNames').format(count);
+ }.property('content.hostComponents.@each.workStatus'),
+
+ /**
+ * String with list of host components <code>displayName</code>
+ * @returns {String}
+ */
labels: function() {
return this.get('content.hostComponents').getEach('displayName').join("<br />");
}.property('content.hostComponents.@each'),
+ /**
+ * CSS value for disk usage bar
+ * @returns {String}
+ */
usageStyle:function () {
return "width:" + this.get('content.diskUsage') + "%";
}.property('content.diskUsage')
@@ -132,6 +148,7 @@ App.MainHostView = App.TableView.extend({
var statusString = this.get('healthStatusValue');
var alerts = this.get('alerts');
var restart = this.get('restart');
+ var maintenance = this.get('maintenance');
if(alerts) {
return this.get('view.content').filterProperty('criticalAlertsCount').get('length');
}
@@ -140,15 +157,20 @@ App.MainHostView = App.TableView.extend({
return this.get('view.content').filterProperty('componentsWithStaleConfigsCount').get('length');
}
else {
- if (statusString == "") {
- return this.get('view.content').get('length');
+ if (maintenance) {
+ return this.get('view.content').filterProperty('componentsInMaintenanceCount').get('length');
}
else {
- return this.get('view.content').filterProperty('healthClass', statusString ).get('length');
+ if (statusString == "") {
+ return this.get('view.content').get('length');
+ }
+ else {
+ return this.get('view.content').filterProperty('healthClass', statusString ).get('length');
+ }
}
}
}
- }.property('view.content.@each.healthClass', 'view.content.@each.criticalAlertsCount', 'view.content.@each.hostComponents.@each.staleConfigs'),
+ }.property('view.content.@each.healthClass', 'view.content.@each.criticalAlertsCount', 'view.content.@each.componentsInMaintenanceCount', 'view.content.@each.hostComponents.@each.staleConfigs'),
label: function () {
return "%@ (%@)".fmt(this.get('value'), this.get('hostsCount'));
@@ -172,7 +194,8 @@ App.MainHostView = App.TableView.extend({
self.categoryObject.create({value: Em.I18n.t('hosts.host.healthStatusCategory.orange'), healthStatusValue: 'health-status-DEAD-ORANGE', isVisible: true}),
self.categoryObject.create({value: Em.I18n.t('hosts.host.healthStatusCategory.yellow'), healthStatusValue: 'health-status-DEAD-YELLOW', isVisible: true}),
self.categoryObject.create({value: Em.I18n.t('hosts.host.alerts.label'), healthStatusValue: 'health-status-WITH-ALERTS', alerts: true, isVisible: true }),
- self.categoryObject.create({value: Em.I18n.t('common.restart'), healthStatusValue: 'health-status-RESTART', restart: true, last: true, isVisible: true })
+ self.categoryObject.create({value: Em.I18n.t('common.restart'), healthStatusValue: 'health-status-RESTART', restart: true, isVisible: true }),
+ self.categoryObject.create({value: Em.I18n.t('common.maintenance'), healthStatusValue: 'health-status-MAINTENANCE', maintenance: true, last: true, isVisible: true })
];
return categories;
@@ -203,17 +226,29 @@ App.MainHostView = App.TableView.extend({
this.get('parentView').updateFilter(0, '', 'string');
this.get('parentView').updateFilter(7, '>0', 'number');
this.get('parentView').updateFilter(8, '', 'number');
+ this.get('parentView').updateFilter(9, '', 'number');
}
else {
if(category.get('restart')) {
this.get('parentView').updateFilter(0, '', 'string');
this.get('parentView').updateFilter(7, '', 'number');
this.get('parentView').updateFilter(8, '>0', 'number');
+ this.get('parentView').updateFilter(9, '', 'number');
+
}
else {
- this.get('parentView').updateFilter(7, '', 'number');
- this.get('parentView').updateFilter(8, '', 'number');
- this.get('parentView').updateFilter(0, category.get('healthStatusValue'), 'string');
+ if(category.get('maintenance')) {
+ this.get('parentView').updateFilter(0, '', 'string');
+ this.get('parentView').updateFilter(7, '', 'number');
+ this.get('parentView').updateFilter(8, '', 'number');
+ this.get('parentView').updateFilter(9, '>0', 'number');
+ }
+ else {
+ this.get('parentView').updateFilter(0, category.get('healthStatusValue'), 'string');
+ this.get('parentView').updateFilter(7, '', 'number');
+ this.get('parentView').updateFilter(8, '', 'number');
+ this.get('parentView').updateFilter(9, '', 'number');
+ }
}
}
},
@@ -259,6 +294,23 @@ App.MainHostView = App.TableView.extend({
}),
/**
+ * view of the maintenance filter implemented as a category of host statuses
+ */
+ maintenanceFilter: Em.View.extend({
+ column: 9,
+ value: null,
+ classNames: ['noDisplay'],
+ showClearFilter: function(){
+ var mockEvent = {
+ context: this.get('parentView.categories').findProperty('healthStatusValue', 'health-status-MAINTENANCE')
+ };
+ if(this.get('value')) {
+ this.get('parentView.childViews').findProperty('column', 0).selectCategory(mockEvent);
+ }
+ }
+ }),
+
+ /**
* Filter view for name column
* Based on <code>filters</code> library
*/
@@ -453,6 +505,7 @@ App.MainHostView = App.TableView.extend({
associations[6] = 'hostComponents';
associations[7] = 'criticalAlertsCount';
associations[8] = 'componentsWithStaleConfigsCount';
+ associations[9] = 'componentsInMaintenanceCount';
return associations;
}.property()
});
\ No newline at end of file