You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by xi...@apache.org on 2017/02/22 01:15:33 UTC
[06/14] ambari git commit: AMBARI-19974. Test and fix new
Notifications/Alerts styles on Ambari.(xiwang)
AMBARI-19974. Test and fix new Notifications/Alerts styles on Ambari.(xiwang)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d8af6aba
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d8af6aba
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d8af6aba
Branch: refs/heads/trunk
Commit: d8af6aba46fe3c62b9b5a4d42b2f716b649c20bd
Parents: c7164d8
Author: Xi Wang <xi...@apache.org>
Authored: Fri Feb 10 14:13:13 2017 -0800
Committer: Xi Wang <xi...@apache.org>
Committed: Wed Feb 15 10:39:41 2017 -0800
----------------------------------------------------------------------
.../main/alert_definitions_controller.js | 14 +-
.../main/alerts/alert_instances_controller.js | 151 ---------------
ambari-web/app/messages.js | 5 +
.../app/styles/theme/bootstrap-ambari.css | 152 +++++++++++++++
ambari-web/app/styles/top-nav.less | 20 +-
ambari-web/app/templates/application.hbs | 57 +++---
.../main/alerts/alert_notifications_popup.hbs | 69 +++++++
ambari-web/app/views.js | 1 +
.../main/alerts/alert_instances_popup_view.js | 190 +++++++++++++++++++
.../alerts/alert_instances_controller_test.js | 33 ----
10 files changed, 480 insertions(+), 212 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/app/controllers/main/alert_definitions_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alert_definitions_controller.js b/ambari-web/app/controllers/main/alert_definitions_controller.js
index 0cfff21..5488fbb 100644
--- a/ambari-web/app/controllers/main/alert_definitions_controller.js
+++ b/ambari-web/app/controllers/main/alert_definitions_controller.js
@@ -119,7 +119,7 @@ App.MainAlertDefinitionsController = Em.ArrayController.extend({
},
/**
- * ========================== alerts popup dialog =========================
+ * ========================== alerts notifications dropdown dialog =========================
*/
/**
@@ -128,8 +128,18 @@ App.MainAlertDefinitionsController = Em.ArrayController.extend({
* @type {Number}
*/
unhealthyAlertInstancesCount: function () {
+ return this.get('criticalAlertInstancesCount') + this.get('warningAlertInstancesCount');
+ }.property('criticalAlertInstancesCount', 'warningAlertInstancesCount'),
+
+ criticalAlertInstancesCount: function () {
+ return this.get('content').map(function (alertDefinition) {
+ return alertDefinition.getWithDefault('summary.CRITICAL.count', 0);
+ }).reduce(Em.sum, 0);
+ }.property('content.@each.summary'),
+
+ warningAlertInstancesCount: function () {
return this.get('content').map(function (alertDefinition) {
- return alertDefinition.getWithDefault('summary.CRITICAL.count', 0) + alertDefinition.getWithDefault('summary.WARNING.count', 0);
+ return alertDefinition.getWithDefault('summary.WARNING.count', 0);
}).reduce(Em.sum, 0);
}.property('content.@each.summary'),
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts/alert_instances_controller.js b/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
index cbeb71a..30eb999 100644
--- a/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
+++ b/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
@@ -193,157 +193,6 @@ App.MainAlertInstancesController = Em.Controller.extend({
*/
getAlertInstancesErrorCallback: function () {
this.set('isLoaded', true);
- },
-
- /**
- * Onclick handler for alerts number located right to bg ops number (see application.hbs)
- * @method showPopup
- * @return {App.ModalPopup}
- */
- showPopup: function () {
-
- var self = this;
-
- return App.ModalPopup.show({
-
- alertsNumberBinding: 'App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount',
-
- header: Em.computed.i18nFormat('alerts.fastAccess.popup.header', 'alertsNumber'),
-
- classNames: ['common-modal-wrapper', 'alerts-popup'],
- modalDialogClasses: ['modal-lg'],
-
- secondary: Em.I18n.t('alerts.fastAccess.popup.body.showmore'),
-
- autoHeight: false,
-
- isHideBodyScroll: true,
-
- onSecondary: function () {
- this._super();
- App.router.transitionTo('main.alerts.index');
- },
-
- bodyClass: App.TableView.extend(App.TableServerViewMixin, {
-
- updaterBinding: 'App.router.updateController',
-
- templateName: require('templates/common/modal_popups/alerts_popup'),
-
- controller: self,
-
- isPaginate: true,
-
- willInsertElement: function () {
- this._super();
- this.updateAlertInstances();
- },
-
- /**
- * Number of all critical and warning alert instances
- * @type {Boolean}
- */
- filteredCount: Em.computed.alias('App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount'),
-
- content: function () {
- return this.get('controller.unhealthyAlertInstances');
- }.property('controller.unhealthyAlertInstances.@each.state'),
-
- isLoaded: Em.computed.bool('controller.unhealthyAlertInstances'),
-
- isAlertEmptyList: Em.computed.empty('content'),
-
- /**
- * Update list of shown alert instances
- * @method updateAlertInstances
- */
- updateAlertInstances: function () {
- var self = this,
- displayLength = this.get('displayLength'),
- startIndex = this.get('startIndex');
- if (!displayLength) return; // wait while table-info is loaded
- this.get('updater').set('queryParamsForUnhealthyAlertInstances', {
- from: startIndex - 1,
- page_size: displayLength
- });
- this.set('filteringComplete', false);
- this.get('updater').updateUnhealthyAlertInstances(function() {
- self.set('filteringComplete', true);
- });
- }.observes('displayLength', 'startIndex'),
-
- /**
- * Show spinner when filter/sorting request is in processing
- * @method overlayObserver
- */
- overlayObserver: function() {
- var $tbody = this.$('#alert-info'),
- $overlay = this.$('.table-overlay'),
- $spinner = $($overlay).find('.spinner');
- if (!this.get('filteringComplete')) {
- if (!$tbody) return;
- var tbodyPos = $tbody.position();
- if (!tbodyPos) return;
- $spinner.css('display', 'block');
- $overlay.css({
- top: tbodyPos.top + 1,
- left: tbodyPos.left + 1,
- width: $tbody.width() - 1,
- height: $tbody.height() - 1
- });
- }
- },
-
- /**
- * No filtering for alert definitions
- * @method filter
- */
- filter: function() {
- this.set('filteredContent', this.get('content'));
- }.observes('content.length'),
-
- /**
- * Router transition to alert definition details page
- * @param event
- */
- gotoAlertDetails: function (event) {
- if (event && event.context) {
- this.get('parentView').hide();
- var definition = App.AlertDefinition.find().findProperty('id', event.context.get('definitionId'));
- App.router.transitionTo('main.alerts.alertDetails', definition);
- }
- },
-
- /**
- * Router transition to service summary page
- * @param event
- */
- goToService: function (event) {
- if (event && event.context) {
- this.get('parentView').hide();
- App.router.transitionTo('main.services.service.summary', event.context);
- }
- },
-
- /**
- * Router transition to host level alerts page
- * @param event
- */
- goToHostAlerts: function (event) {
- if (event && event.context) {
- this.get('parentView').hide();
- App.router.transitionTo('main.hosts.hostDetails.alerts', event.context);
- }
- },
-
- didInsertElement: function () {
- this.filter();
- this.addObserver('filteringComplete', this, this.overlayObserver);
- this.overlayObserver();
- return this._super();
- }
- })
- });
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index cb88fda..6e58823 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1085,6 +1085,11 @@ Em.I18n.translations = {
'form.validator.alertNotificationName':'Invalid Alert Notification Name. Only alphanumerics, hyphens, spaces and underscores are allowed.',
'form.validator.configKey.specific':'"{0}" is invalid Key. Only alphanumerics, hyphens, underscores, asterisks and periods are allowed.',
+ 'alerts.dropdown.dialog.title': 'Notifications',
+ 'alerts.dropdown.dialog.filters.critical': 'Critical ({0})',
+ 'alerts.dropdown.dialog.filters.warning': 'Warning ({0})',
+ 'alerts.dropdown.dialog.filters.all': 'All ({0})',
+
'alerts.add.header': 'Create Alert',
'alerts.add.step1.header': 'Choose Alert Type',
'alerts.add.step1.header.description': 'Select the type of alert you want to create',
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/app/styles/theme/bootstrap-ambari.css
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/theme/bootstrap-ambari.css b/ambari-web/app/styles/theme/bootstrap-ambari.css
index d17e423..36a63a3 100644
--- a/ambari-web/app/styles/theme/bootstrap-ambari.css
+++ b/ambari-web/app/styles/theme/bootstrap-ambari.css
@@ -1037,6 +1037,7 @@ input.radio:checked + label:after {
.navigation-bar-container.collapsed ul.nav.side-nav-footer li.submenu-li.active > a {
padding-left: 19px;
}
+
.navigation-bar-fit-height {
position: fixed;
top: 0;
@@ -1059,6 +1060,157 @@ input.radio:checked + label:after {
.navigation-bar-fit-height .navigation-bar-container:not(.collapsed) .side-nav-menu {
overflow-y: auto;
}
+
+.notifications-group {
+ position: relative;
+ top: 1px;
+}
+#notifications-dropdown.dropdown-menu {
+ min-width: 300px;
+ max-width: 300px;
+ min-height: 150px;
+ padding: 0px;
+ z-index: 1000;
+ right: -50px;
+ left: auto;
+ top: 260%;
+ border: none;
+ -webkit-box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.29);
+ -moz-box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.29);
+ box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.29);
+}
+#notifications-dropdown.dropdown-menu .popup-arrow-up {
+ position: absolute;
+ right: 37px;
+ top: -40px;
+ width: 40px;
+ height: 40px;
+ overflow: hidden;
+}
+#notifications-dropdown.dropdown-menu .popup-arrow-up:after {
+ content: "";
+ position: absolute;
+ width: 20px;
+ height: 20px;
+ background: #fff;
+ transform: rotate(45deg);
+ top: 30px;
+ left: 10px;
+ box-shadow: -1px -1px 10px -2px rgba(0, 0, 0, 0.5);
+}
+#notifications-dropdown.dropdown-menu .notifications-header {
+ border-bottom: 1px solid #eee;
+ padding: 15px 20px;
+}
+#notifications-dropdown.dropdown-menu .notifications-header .notifications-title {
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 16px;
+}
+#notifications-dropdown.dropdown-menu .notifications-body {
+ padding: 0px 15px;
+ overflow: auto;
+ max-height: 500px;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .no-alert-text {
+ padding: 15px 5px;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table-controls {
+ padding: 10px 0px;
+ margin: 0px;
+ border-bottom: 1px solid #eee;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table-controls .state-filter {
+ padding: 0px;
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ font-size: 12px;
+ color: #666;
+ position: relative;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table-controls .state-filter .form-control.filter-select {
+ font-size: 12px;
+ color: #666;
+ height: 25px;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table {
+ margin-top: 0px;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody tr {
+ cursor: pointer;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover {
+ cursor: default;
+ border-color: transparent;
+ border-bottom-color: #eee;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover > td {
+ border-color: transparent;
+ background-color: white;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.status {
+ width: 9%;
+ padding: 15px 3px;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.status .alert-state-CRITICAL {
+ color: #EF6162;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.status .alert-state-WARNING {
+ color: #E98A41;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content {
+ width: 90%;
+ padding: 15px 3px 10px 3px;
+ font-family: 'Roboto', sans-serif;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ color: #333;
+ line-height: 1.3;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content .name {
+ font-weight: bold;
+ font-size: 12px;
+ color: #666;
+ margin-bottom: 5px;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content .description {
+ font-size: 12px;
+ color: #666;
+ margin-bottom: 4px;
+ display: block;
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ /* Break long urls*/
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ -ms-word-break: break-all;
+ word-break: break-all;
+ word-break: break-word;
+ /* Adds a hyphen where the word breaks*/
+ -ms-hyphens: auto;
+ -moz-hyphens: auto;
+ -webkit-hyphens: auto;
+ hyphens: auto;
+}
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content .timestamp {
+ text-align: right;
+ font-size: 11px;
+ color: #999;
+}
+#notifications-dropdown.dropdown-menu .notifications-footer {
+ border-top: 1px solid #eee;
+ padding: 15px;
+}
h1,
h2,
h3,
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/app/styles/top-nav.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/top-nav.less b/ambari-web/app/styles/top-nav.less
index d1c723a..78c804f 100644
--- a/ambari-web/app/styles/top-nav.less
+++ b/ambari-web/app/styles/top-nav.less
@@ -38,7 +38,13 @@
}
}
+ .cluster-notifications {
+ margin-top: 12px;
+ }
.navbar-text.brand-wrapper {
+ margin-top: 17px;
+ }
+ .navbar-text.brand-wrapper, .cluster-notifications {
color: @top-nav-brand-color;
font-size: 16px;
font-weight: normal;
@@ -51,6 +57,11 @@
position: relative;
}
+ span.alerts-label {
+ line-height: 20px;
+ cursor: pointer;
+ }
+
.numberCircle {
border-radius: 50%;
width: 20px;
@@ -94,9 +105,14 @@
a:hover {
text-decoration: none;
}
+ .top-nav-user {
+ margin-top: 2px;
+ }
}
- .top-nav-user {
- margin-top: 2px;
+ #notifications-dropdown.dropdown-menu {
+ .popup-arrow-up {
+ right: 75px;
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/application.hbs b/ambari-web/app/templates/application.hbs
index 25c3311..94d8337 100644
--- a/ambari-web/app/templates/application.hbs
+++ b/ambari-web/app/templates/application.hbs
@@ -127,16 +127,8 @@
{{/if}}
{{! user dropdown end }}
- <div class="navbar-nav navbar-text navbar-right brand-wrapper">
+ <div class="navbar-nav navbar-right cluster-notifications">
{{#if enableLinks}}
-
- {{! cluster name }}
- <a href="#" {{bindAttr title="clusterName"}} {{action "showPopup" target="App.router.backgroundOperationsController"}} class="cluster-name">
- {{#unless App.isClusterUser}}
- <span>{{clusterDisplayName}}</span>
- {{/unless}}
- </a>
- {{! cluster name end }}
{{! bg label }}
<a href="#" class="bg-label" {{action "showPopup" target="App.router.backgroundOperationsController"}}>
{{#with App.router.backgroundOperationsController}}
@@ -147,27 +139,44 @@
{{/with}}
</a>
{{! bg label end }}
- {{! alerts label }}
+
+ {{! new alerts label }}
{{#if App.router.clusterController.isAlertsLoaded}}
- <a href="#" class="alerts-label" {{action "showPopup" target="App.router.mainAlertInstancesController"}}>
- {{#if App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}}
+ <span class="notifications-group">
+ <span class="alerts-label dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-bell"></span>
- {{! alerts exist }}
- <span {{bindAttr class=":numberCircle App.router.mainAlertDefinitionsController.isCriticalAlerts:alert-crit-count:alert-warn-count"}}>
- {{App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}}
- </span>
- {{else}}
- {{! no alerts }}
- <span {{translateAttr title="titlebar.alerts.noAlerts"}} class="numberCircle alerts-none-count">
- {{App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}}
- </span>
- {{/if}}
- </a>
+ {{#if App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}}
+ {{! alerts exist }}
+ <span {{bindAttr class=":numberCircle App.router.mainAlertDefinitionsController.isCriticalAlerts:alert-crit-count:alert-warn-count"}}>
+ {{App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}}
+ </span>
+ {{else}}
+ {{! no alerts }}
+ <span {{translateAttr title="titlebar.alerts.noAlerts"}} class="numberCircle alerts-none-count">
+ {{App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}}
+ </span>
+ {{/if}}
+ </span>
+ <div id="notifications-dropdown" class="dropdown-menu row">
+ {{view App.AlertInstancesPopupView}}
+ </div>
+ </span>
{{/if}}
- {{! alerts label end }}
+ {{! alerts label end }}
{{/if}}
</div>
+ <div class="navbar-nav navbar-text navbar-right brand-wrapper">
+ {{#if enableLinks}}
+ {{! cluster name }}
+ <a href="#" {{bindAttr title="clusterName"}} {{action "showPopup" target="App.router.backgroundOperationsController"}} class="cluster-name">
+ {{#unless App.isClusterUser}}
+ <span>{{clusterDisplayName}}</span>
+ {{/unless}}
+ </a>
+ {{! cluster name end }}
+ {{/if}}
+ </div>
</div>
</nav>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/app/templates/main/alerts/alert_notifications_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/alerts/alert_notifications_popup.hbs b/ambari-web/app/templates/main/alerts/alert_notifications_popup.hbs
new file mode 100644
index 0000000..a5f2bf2
--- /dev/null
+++ b/ambari-web/app/templates/main/alerts/alert_notifications_popup.hbs
@@ -0,0 +1,69 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+
+<div class="popup-arrow-up"></div>
+<div class="notifications-header col-sm-12">
+ <div class="notifications-title">{{t alerts.dropdown.dialog.title}} ({{view.alertsNumber}})</div>
+</div>
+
+<div class="notifications-body col-sm-12">
+ {{#if view.isLoaded}}
+ <div class="table-controls row">
+ <div class="state-filter pull-right">
+ <span>{{t common.show}}: </span>
+ <div class="btn-group">
+ {{view Ember.Select
+ contentBinding="view.categories"
+ optionValuePath="content.value"
+ optionLabelPath="content.label"
+ selectionBinding="view.selectedCategory"
+ classNames="filter-select form-control"
+ }}
+ </div>
+ </div>
+ </div>
+ <table class="alerts-table table table-hover">
+ <tbody>
+ {{#if view.isAlertEmptyList}}
+ <tr class="no-alert-tr">
+ <td class="no-alert-text">{{t alerts.fastAccess.popup.body.noalerts}}</td>
+ </tr>
+ {{else}}
+ {{#each instance in view.pageContent}}
+ <tr {{action "gotoAlertDetails" instance target="view"}} {{bindAttr class="instance.isVisible::hidden"}}>
+ <td class="status">
+ <span {{bindAttr class="instance.stateClass :icon-circle"}}></span>
+ </td>
+ <td class="content">
+ <div class="name">{{instance.label}}</div>
+ <div class="description">{{instance.text}}</div>
+ <div class="timestamp">{{instance.lastTriggeredAgoFormatted}}</div>
+ </td>
+ </tr>
+ {{/each}}
+ {{/if}}
+ </tbody>
+ </table>
+ {{else}}
+ {{view App.SpinnerView}}
+ {{/if}}
+</div>
+
+<div class="notifications-footer col-sm-12">
+ <button type="button" class="btn btn-primary pull-right" {{action "gotoAllAlerts" target="view"}}>View All</button>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 77b5d5a..1a2a887 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -129,6 +129,7 @@ require('views/main/alerts/add_alert_definition/step2_view');
require('views/main/alerts/add_alert_definition/step3_view');
require('views/main/alerts');
require('views/main/alerts/manage_alert_groups_view');
+require('views/main/alerts/alert_instances_popup_view');
require('views/main/alerts/manage_alert_notifications_view');
require('views/main/charts');
require('views/main/views/details');
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/app/views/main/alerts/alert_instances_popup_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/alerts/alert_instances_popup_view.js b/ambari-web/app/views/main/alerts/alert_instances_popup_view.js
new file mode 100644
index 0000000..6524f30
--- /dev/null
+++ b/ambari-web/app/views/main/alerts/alert_instances_popup_view.js
@@ -0,0 +1,190 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+/**
+ * Option for "filter by state" drop down
+ * @typedef {object} categoryObject
+ * @property {string} value "all|warning|critical"
+ * @property {number} count number of items with <code>state</code> equal to <code>this.value</code>
+ * @property {string} labelPath key in the messages.js
+ * @property {string} label localized label
+ */
+var categoryObject = Em.Object.extend({
+ value: '',
+ count: 0,
+ labelPath: '',
+ label: function () {
+ return Em.I18n.t(this.get('labelPath')).format(this.get('count'));
+ }.property('count', 'labelPath')
+});
+
+App.AlertInstancesPopupView = App.TableView.extend(App.TableServerViewMixin, {
+
+ templateName: require('templates/main/alerts/alert_notifications_popup'),
+
+ updaterBinding: 'App.router.updateController',
+
+ controllerBinding: 'App.router.mainAlertInstancesController',
+
+ /**
+ * Number of all critical and warning alert instances
+ * @type {Boolean}
+ */
+ alertsNumberBinding: 'App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount',
+ criticalNumberBinding: 'App.router.mainAlertDefinitionsController.criticalAlertInstancesCount',
+ warningNumberBinding: 'App.router.mainAlertDefinitionsController.warningAlertInstancesCount',
+
+ isPaginate: false,
+
+ willInsertElement: function () {
+ this._super();
+ this.updateAlertInstances();
+ },
+
+ didInsertElement: function () {
+ this.filter();
+ this.addObserver('filteringComplete', this, this.overlayObserver);
+ this.overlayObserver();
+ $(".notifications-body .filter-select ").click(function(event){
+ event.stopPropagation();
+ });
+ return this._super();
+ },
+
+ content: function () {
+ return this.get('controller.unhealthyAlertInstances');
+ }.property('controller.unhealthyAlertInstances.@each.state'),
+
+ isLoaded: Em.computed.bool('controller.unhealthyAlertInstances'),
+
+ isAlertEmptyList: Em.computed.or('isAlertContentEmptyList', 'isAlertFilterdEmptyList'),
+ isAlertContentEmptyList: Em.computed.empty('content'),
+ isAlertFilterdEmptyList: Em.computed.everyBy('content', 'isVisible', false),
+
+ displayLength: 100,
+
+ /**
+ * Update list of shown alert instances
+ * @method updateAlertInstances
+ */
+ updateAlertInstances: function () {
+ var self = this,
+ displayLength = this.get('displayLength'),
+ startIndex = this.get('startIndex');
+ if (!displayLength) return; // wait while table-info is loaded
+ this.get('updater').set('queryParamsForUnhealthyAlertInstances', {
+ from: startIndex - 1,
+ page_size: displayLength
+ });
+ this.set('filteringComplete', false);
+ this.get('updater').updateUnhealthyAlertInstances(function() {
+ self.set('filteringComplete', true);
+ });
+ }.observes('displayLength', 'startIndex', 'alertsNumber'),
+
+ /**
+ * Show spinner when filter/sorting request is in processing
+ * @method overlayObserver
+ */
+ overlayObserver: function() {
+ var $tbody = this.$('.table.alerts-table'),
+ $overlay = this.$('.table-overlay'),
+ $spinner = $($overlay).find('.spinner');
+ if (!this.get('filteringComplete')) {
+ if (!$tbody) return;
+ var tbodyPos = $tbody.position();
+ if (!tbodyPos) return;
+ $spinner.css('display', 'block');
+ $overlay.css({
+ top: tbodyPos.top + 1,
+ left: tbodyPos.left + 1,
+ width: $tbody.width() - 1,
+ height: $tbody.height() - 1
+ });
+ }
+ },
+
+ categories: function () {
+ var allCnt = this.get('alertsNumber');
+ var criticalCnt = this.get('criticalNumber');
+ var warningCnt = this.get('warningNumber');
+ return [
+ categoryObject.create({
+ value: 'all',
+ labelPath: 'alerts.dropdown.dialog.filters.all',
+ count: allCnt
+ }),
+ categoryObject.create({
+ value: 'alert-state-CRITICAL',
+ labelPath: 'alerts.dropdown.dialog.filters.critical',
+ count: criticalCnt
+ }),
+ categoryObject.create({
+ value: 'alert-state-WARNING',
+ labelPath: 'alerts.dropdown.dialog.filters.warning',
+ count: warningCnt
+ })
+ ];
+ }.property('criticalNumber', 'warningNumber', 'alertsNumber'),
+
+ selectedCategory: null,
+
+ /**
+ * Filter notifications by state
+ * @method filter
+ */
+ filter: function() {
+ var selectedState = this.get('selectedCategory.value');
+ var content = this.get('content');
+ if (selectedState == 'all') {
+ content.setEach("isVisible", true);
+ this.set('filteredContent', content);
+ } else {
+ this.set('filteredContent', content.filter(function (item) {
+ if (item.get('stateClass') == selectedState) {
+ item.set('isVisible', true);
+ return true;
+ } else {
+ item.set('isVisible', false);
+ return false;
+ }
+ }));
+ }
+ }.observes('content.length', 'selectedCategory'),
+
+ /**
+ * Router transition to alert definition details page
+ * @param event
+ */
+ gotoAlertDetails: function (event) {
+ if (event && event.context) {
+ var definition = App.AlertDefinition.find().findProperty('id', event.context.get('definitionId'));
+ App.router.transitionTo('main.alerts.alertDetails', definition);
+ }
+ },
+
+ /**
+ * Router transition to alert definition page
+ */
+ gotoAllAlerts: function () {
+ App.router.transitionTo('main.alerts.index');
+ }
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8af6aba/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js b/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js
index 94653c7..5b53323 100644
--- a/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js
+++ b/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js
@@ -64,37 +64,4 @@ describe('App.MainAlertInstancesController', function () {
});
-
- describe('#showPopup', function () {
-
- describe('#bodyClass', function () {
-
- var bodyView;
-
- beforeEach(function () {
- controller.reopen({unhealthyAlertInstances: [
- App.AlertInstance.createRecord({state: 'CRITICAL'}),
- App.AlertInstance.createRecord({state: 'WARNING'}),
- App.AlertInstance.createRecord({state: 'WARNING'}),
- App.AlertInstance.createRecord({state: 'CRITICAL'})
- ]});
- bodyView = controller.showPopup().get('bodyClass').create();
- });
-
- it('#content', function () {
- expect(bodyView.get('content.length')).to.equal(4);
- });
-
- it('#isLoaded', function () {
- expect(bodyView.get('isLoaded')).to.be.true;
- });
-
- it('#isAlertEmptyList', function () {
- expect(bodyView.get('isAlertEmptyList')).to.be.false;
- });
-
- });
-
- });
-
});
\ No newline at end of file