You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eagle.apache.org by ji...@apache.org on 2017/02/28 06:38:09 UTC
eagle git commit: [EAGLE-930] UI Notification support
Repository: eagle
Updated Branches:
refs/heads/master 7bfe55de7 -> 1c90aa46d
[EAGLE-930] UI Notification support
Support alert auto detect and popup notification of current eagle application.
Author: zombieJ <sm...@gmail.com>
Closes #845 from zombieJ/EAGLE-930.
Project: http://git-wip-us.apache.org/repos/asf/eagle/repo
Commit: http://git-wip-us.apache.org/repos/asf/eagle/commit/1c90aa46
Tree: http://git-wip-us.apache.org/repos/asf/eagle/tree/1c90aa46
Diff: http://git-wip-us.apache.org/repos/asf/eagle/diff/1c90aa46
Branch: refs/heads/master
Commit: 1c90aa46d23e8ed2f35bddc37e34900392060dac
Parents: 7bfe55d
Author: zombieJ <sm...@gmail.com>
Authored: Tue Feb 28 14:37:56 2017 +0800
Committer: zombieJ <sm...@gmail.com>
Committed: Tue Feb 28 14:37:56 2017 +0800
----------------------------------------------------------------------
eagle-server/src/main/webapp/app/dev/index.html | 28 ++++
.../src/main/webapp/app/dev/public/js/app.js | 7 +-
.../app/dev/public/js/services/alertSrv.js | 65 +++++++++
.../dev/public/js/services/notificationSrv.js | 144 +++++++++++++++++++
4 files changed, 243 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/eagle/blob/1c90aa46/eagle-server/src/main/webapp/app/dev/index.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/index.html b/eagle-server/src/main/webapp/app/dev/index.html
index b4dfea6..3408842 100644
--- a/eagle-server/src/main/webapp/app/dev/index.html
+++ b/eagle-server/src/main/webapp/app/dev/index.html
@@ -64,6 +64,7 @@
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
+ <!-- Time Picker -->
<li class="dropdown time-picker" ng-if="Time.pickerType === Time.TIME_RANGE_PICKER">
<a data-toggle="dropdown" aria-expanded="false">
<span class="fa fa-{{Time.autoRefresh ? 'refresh' : 'calendar'}}"></span>
@@ -84,6 +85,8 @@
</li>
</ul>
</li>
+
+ <!-- Site -->
<li class="hover-dropdown">
<a>
<span ng-if="!Site.current()">
@@ -105,6 +108,29 @@
</li>
</ul>
</li>
+
+ <!-- Notification -->
+ <li class="hover-dropdown">
+ <a>
+ <i class="fa fa-bell"></i>
+ <span ng-if="$notification.list.length" class="label label-warning">
+ {{$notification.list.length}}
+ </span>
+ </a>
+
+ <ul class="dropdown-menu">
+ <li ng-repeat="notification in $notification.list track by $index">
+ <a href="{{notification.url}}" ng-click="$notification.trigger(notification, $event)">
+ {{notification.content}}
+ </a>
+ </li>
+ <li ng-if="!$notification.list.length" class="disabled">
+ <a class="text-gray">No Notification</a>
+ </li>
+ </ul>
+ </li>
+
+ <!-- FAQ -->
<li>
<a data-toggle="dropdown" aria-expanded="false">
<i class="glyphicon glyphicon-question-sign"></i>
@@ -277,6 +303,8 @@
<script src="public/js/services/applicationSrv.js" type="text/javascript" charset="utf-8"></script>
<script src="public/js/services/uiSrv.js" type="text/javascript" charset="utf-8"></script>
<script src="public/js/services/policySrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/notificationSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/alertSrv.js" type="text/javascript" charset="utf-8"></script>
<!-- Components -->
<script src="public/js/components/main.js" type="text/javascript" charset="utf-8"></script>
http://git-wip-us.apache.org/repos/asf/eagle/blob/1c90aa46/eagle-server/src/main/webapp/app/dev/public/js/app.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/app.js b/eagle-server/src/main/webapp/app/dev/public/js/app.js
index a05ac92..e5b87e8 100644
--- a/eagle-server/src/main/webapp/app/dev/public/js/app.js
+++ b/eagle-server/src/main/webapp/app/dev/public/js/app.js
@@ -273,7 +273,10 @@ var app = {};
// ======================================================================================
// = Main Controller =
// ======================================================================================
- eagleApp.controller('MainCtrl', function ($scope, $wrapState, $urlRouter, Server, PageConfig, Portal, Widget, Entity, CompatibleEntity, Site, Application, UI, Time, Policy) {
+ eagleApp.controller('MainCtrl', function (
+ $scope, $wrapState, $urlRouter, $notification,
+ Server, PageConfig, Portal, Widget, Entity, CompatibleEntity,
+ Site, Application, UI, Time, Policy, Alert) {
window._WrapState = $scope.$wrapState = $wrapState;
window._Server = $scope.Server = Server;
window._PageConfig = $scope.PageConfig = PageConfig;
@@ -286,6 +289,8 @@ var app = {};
window._UI = $scope.UI = UI;
window._Time = $scope.Time = Time;
window._Policy = $scope.Policy = Policy;
+ window._Notification = $scope.$notification = $notification;
+ window._Alert = $scope.Alert = Alert;
$scope.common = common;
$scope._TRS = window._TRS();
http://git-wip-us.apache.org/repos/asf/eagle/blob/1c90aa46/eagle-server/src/main/webapp/app/dev/public/js/services/alertSrv.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/services/alertSrv.js b/eagle-server/src/main/webapp/app/dev/public/js/services/alertSrv.js
new file mode 100644
index 0000000..9905fa0
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/js/services/alertSrv.js
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+(function() {
+ 'use strict';
+
+ var ALERT_FETCH_LIMIT = 1000 * 60 * 60 * 12;
+ var ALERT_REFRESH_INTERVAL = 1000 * 10;
+ var ALERT_TEMPLATE = '#/site/${siteId}/alert/detail/${alertId}?timestamp=${timestamp}';
+
+ var serviceModule = angular.module('eagle.service');
+
+ serviceModule.service('Alert', function ($notification, Time, CompatibleEntity) {
+ var Alert = {
+ list: null,
+ };
+
+ $notification.getPromise().then(function () {
+ function queryAlerts() {
+ var endTime = new Time();
+ var list = CompatibleEntity.query("LIST", {
+ query: "AlertService",
+ startTime: endTime.clone().subtract(ALERT_FETCH_LIMIT, 'ms'),
+ endTime: endTime
+ });
+ list._then(function () {
+ if (!Alert.list) {
+ Alert.list = list;
+ return;
+ }
+
+ var subList = common.array.minus(list, Alert.list, ['encodedRowkey'], ['encodedRowkey']);
+ Alert.list = list;
+ $.each(subList, function (i, alert) {
+ $notification(alert.alertSubject, common.template(ALERT_TEMPLATE, {
+ siteId: alert.tags.siteId,
+ alertId: alert.tags.alertId,
+ timestamp: alert.timestamp,
+ }));
+ });
+ });
+ }
+
+ queryAlerts();
+ setInterval(queryAlerts, ALERT_REFRESH_INTERVAL);
+ });
+
+ return Alert;
+ });
+})();
http://git-wip-us.apache.org/repos/asf/eagle/blob/1c90aa46/eagle-server/src/main/webapp/app/dev/public/js/services/notificationSrv.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/services/notificationSrv.js b/eagle-server/src/main/webapp/app/dev/public/js/services/notificationSrv.js
new file mode 100644
index 0000000..76f9c45
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/js/services/notificationSrv.js
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+
+(function() {
+ 'use strict';
+
+ var REFRESH_TIME_LIMIT = 5 * 1000;
+ var PREEMPTIVE_TIME_LIMIT = 8 * 1000;
+ var MAX_NOTIFICATION_COUNT = 100;
+ var serviceModule = angular.module('eagle.service');
+
+ serviceModule.service('$notification', function ($q, $rootScope) {
+ var deferred = $q.defer();
+ var promised = false;
+ var id = +new Date();
+ var lastHookTime = +new Date();
+ var instanceId = 0;
+ var lastInstance;
+
+ function notification(content, url) {
+ if (!promised) return;
+
+ instanceId += 1;
+
+ // Add notification in queue
+ var config = {
+ content: content,
+ url: url,
+ id: instanceId,
+ };
+ notification.list.push(config);
+ notification.list = notification.list.slice(0, MAX_NOTIFICATION_COUNT);
+
+ // Popup notification
+ var count = notification.list.length;
+ var instance = new Notification((count > 1 ? '[' + count + '] ' : '') + 'Apache Eagle:', {
+ tag: 'eagle',
+ body: content,
+ icon: 'public/images/favicon.png',
+ renotify: true,
+ });
+ instance.onclick = function () {
+ window.focus();
+ notification.trigger(config);
+
+ if (lastInstance === instance) lastInstance = null;
+ instance.close();
+
+ $rootScope.$apply();
+ };
+
+ // Close notification
+ setTimeout(function () {
+ if (lastInstance === instance) {
+ lastInstance = null;
+ instance.close();
+ }
+ }, 5000);
+ lastInstance = instance;
+ }
+
+ function uniqueNotification() {
+ function loopListener() {
+ var hooker = common.parseJSON(localStorage.getItem('notificationId'), null);
+ if (promised || !hooker || (+new Date()) - (hooker.lastHookTime || 0) > PREEMPTIVE_TIME_LIMIT) {
+ promised = true;
+ deferred.resolve();
+ lastHookTime = +new Date();
+ localStorage.setItem('notificationId', JSON.stringify({
+ id: id,
+ lastHookTime: lastHookTime,
+ }));
+ }
+ }
+
+ setInterval(loopListener, REFRESH_TIME_LIMIT);
+ loopListener();
+
+ $(window).bind("beforeunload", function() {
+ var hooker = common.parseJSON(localStorage.getItem('notificationId'), {});
+ if (hooker.id === id) {
+ localStorage.removeItem('notificationId');
+ }
+ if (lastInstance) {
+ lastInstance.close();
+ lastInstance = null;
+ }
+ });
+ }
+
+ if (!'Notification' in window || !'localStorage' in window) {
+ // Notification not support
+ console.warn('Browser do not support Notification api. Ignore...');
+ } else {
+ // Check notification state;
+ if (Notification.permission === 'granted') {
+ // promised = true;
+ uniqueNotification();
+ } else if (Notification.permission !== 'denied') {
+ Notification.requestPermission().then(function(permission) {
+ if (permission === "granted") {
+ uniqueNotification();
+ } else {
+ console.warn('User deny the notification.');
+ }
+ });
+ } else {
+ console.warn('Web Notification initialization denied. Ignore eagle web notification.');
+ }
+ }
+
+ notification.list = [];
+
+ notification.trigger = function (config, event) {
+ notification.list = common.array.remove(config.id, notification.list, ['id']);
+
+ if (!event || !event.ctrlKey) {
+ location.href = config.url;
+ if (event) event.preventDefault();
+ }
+ };
+
+ notification.getPromise = function () {
+ return deferred.promise;
+ };
+
+ return notification;
+ });
+})();