mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
refactor of the notification service, it now exposes a createNotifier() factory to create a mini notification manager that will label errors with the location they originated (optionally allowing more customization of the services behavior
This commit is contained in:
parent
d06d490405
commit
85f9912c68
5 changed files with 184 additions and 159 deletions
|
@ -18,7 +18,10 @@ define(function (require) {
|
|||
appendToBody: false
|
||||
});
|
||||
})
|
||||
.controller('kibana', function ($scope, courier, config, configFile, notify, $timeout) {
|
||||
.controller('kibana', function ($scope, courier, config, configFile, createNotifier, $timeout) {
|
||||
var notify = createNotifier({
|
||||
location: 'Kibana Controller'
|
||||
});
|
||||
$scope.apps = configFile.apps;
|
||||
|
||||
$scope.$on('$locationChangeSuccess', function (event, uri) {
|
||||
|
@ -123,4 +126,4 @@ define(function (require) {
|
|||
courier.start();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* main app level module
|
||||
*/
|
||||
define(function (require) {
|
||||
|
||||
var angular = require('angular');
|
||||
var $ = require('jquery');
|
||||
var _ = require('lodash');
|
||||
|
@ -50,7 +49,7 @@ define(function (require) {
|
|||
notify.lifecycle('bootstrap');
|
||||
angular
|
||||
.bootstrap(document, ['kibana'])
|
||||
.invoke(function (notify) {
|
||||
.invoke(function () {
|
||||
notify.lifecycle('bootstrap', true);
|
||||
$(document.body).children().show();
|
||||
});
|
||||
|
@ -61,4 +60,4 @@ define(function (require) {
|
|||
});
|
||||
|
||||
return kibana;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,6 +2,11 @@ define(function (require) {
|
|||
var _ = require('lodash');
|
||||
var $ = require('jquery');
|
||||
|
||||
var notifs = [];
|
||||
var setTO = setTimeout;
|
||||
var clearTO = clearTimeout;
|
||||
var log = (typeof KIBANA_DIST === 'undefined') ? _.bindKey(console, 'log') : _.noop;
|
||||
|
||||
var fatalToastTemplate = (function lazyTemplate(tmpl) {
|
||||
var compiled;
|
||||
return function (vars) {
|
||||
|
@ -10,154 +15,174 @@ define(function (require) {
|
|||
};
|
||||
}(require('text!./partials/fatal.html')));
|
||||
|
||||
/**
|
||||
* Functionality to check that
|
||||
*/
|
||||
function NotifyManager() {
|
||||
|
||||
var applicationBooted;
|
||||
var notifs = this._notifs = [];
|
||||
var setTO = setTimeout;
|
||||
var clearTO = clearTimeout;
|
||||
|
||||
function now() {
|
||||
if (window.performance && window.performance.now) {
|
||||
return window.performance.now();
|
||||
}
|
||||
return Date.now();
|
||||
function now() {
|
||||
if (window.performance && window.performance.now) {
|
||||
return window.performance.now();
|
||||
}
|
||||
return Date.now();
|
||||
}
|
||||
|
||||
var log = (typeof KIBANA_DIST === 'undefined') ? _.bindKey(console, 'log') : _.noop;
|
||||
|
||||
function closeNotif(cb, key) {
|
||||
return function () {
|
||||
// this === notif
|
||||
var i = notifs.indexOf(this);
|
||||
if (i !== -1) notifs.splice(i, 1);
|
||||
if (this.timerId) this.timerId = clearTO(this.timerId);
|
||||
if (typeof cb === 'function') cb(key);
|
||||
};
|
||||
}
|
||||
|
||||
function add(notif, cb) {
|
||||
if (notif.lifetime !== Infinity) {
|
||||
notif.timerId = setTO(function () {
|
||||
closeNotif(cb, 'ignore').call(notif);
|
||||
}, notif.lifetime);
|
||||
}
|
||||
|
||||
if (notif.actions) {
|
||||
notif.actions.forEach(function (action) {
|
||||
notif[action] = closeNotif(cb, action);
|
||||
});
|
||||
}
|
||||
|
||||
notifs.push(notif);
|
||||
}
|
||||
|
||||
this._setTimerFns = function (set, clear) {
|
||||
setTO = set;
|
||||
clearTO = clear;
|
||||
};
|
||||
|
||||
/**
|
||||
* Notify the serivce of app lifecycle events
|
||||
* @type {[type]}
|
||||
*/
|
||||
var lifecycleEvents = window.kibanaLifecycleEvents = {};
|
||||
this.lifecycle = function (name, success) {
|
||||
var status;
|
||||
if (name === 'bootstrap' && success === true) applicationBooted = true;
|
||||
|
||||
if (success === void 0) {
|
||||
// start
|
||||
lifecycleEvents[name] = now();
|
||||
} else {
|
||||
// end
|
||||
if (success) {
|
||||
lifecycleEvents[name] = now() - (lifecycleEvents[name] || 0);
|
||||
status = lifecycleEvents[name].toFixed(2) + ' ms';
|
||||
} else {
|
||||
lifecycleEvents[name] = false;
|
||||
status = 'failure';
|
||||
}
|
||||
}
|
||||
|
||||
log('KBN: ' + name + (status ? ' - ' + status : ''));
|
||||
};
|
||||
|
||||
/**
|
||||
* Kill the page, and display an error
|
||||
* @param {Error} err - The fatal error that occured
|
||||
*/
|
||||
this.fatal = function (err) {
|
||||
var html = fatalToastTemplate({
|
||||
msg: err instanceof Error ? err.message : err,
|
||||
stack: err.stack
|
||||
});
|
||||
|
||||
var $container = $('#fatal-splash-screen');
|
||||
if ($container.size()) {
|
||||
$container.append(html);
|
||||
return;
|
||||
}
|
||||
|
||||
$container = $();
|
||||
|
||||
// in case the app has not completed boot
|
||||
$(document.body)
|
||||
.removeAttr('ng-cloak')
|
||||
.html('<div id="fatal-splash-screen" class="container-fuild">' + html + '</div>');
|
||||
};
|
||||
|
||||
/**
|
||||
* Alert the user of an error that occured
|
||||
* @param {Error|String} err
|
||||
*/
|
||||
this.error = function (err, cb) {
|
||||
add({
|
||||
type: 'danger',
|
||||
content: err instanceof Error ? err.message : err,
|
||||
icon: 'warning',
|
||||
title: 'Error',
|
||||
lifetime: Infinity,
|
||||
actions: ['report', 'accept']
|
||||
}, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* Warn the user abort something
|
||||
* @param {[type]} msg [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
this.warning = function (msg, cb) {
|
||||
add({
|
||||
type: 'warning',
|
||||
content: msg,
|
||||
icon: 'warning',
|
||||
title: 'Warning',
|
||||
lifetime: 7000,
|
||||
actions: ['accept']
|
||||
}, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* Display a debug message
|
||||
* @param {String} msg [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
this.info = function (msg, cb) {
|
||||
add({
|
||||
type: 'info',
|
||||
content: msg,
|
||||
icon: 'info-circle',
|
||||
title: 'Debug',
|
||||
lifetime: 7000,
|
||||
actions: ['accept']
|
||||
}, cb);
|
||||
function closeNotif(cb, key) {
|
||||
return function () {
|
||||
// this === notif
|
||||
var i = notifs.indexOf(this);
|
||||
if (i !== -1) notifs.splice(i, 1);
|
||||
if (this.timerId) this.timerId = clearTO(this.timerId);
|
||||
if (typeof cb === 'function') cb(key);
|
||||
};
|
||||
}
|
||||
|
||||
return NotifyManager;
|
||||
function add(notif, cb) {
|
||||
if (notif.lifetime !== Infinity) {
|
||||
notif.timerId = setTO(function () {
|
||||
closeNotif(cb, 'ignore').call(notif);
|
||||
}, notif.lifetime);
|
||||
}
|
||||
|
||||
});
|
||||
if (notif.actions) {
|
||||
notif.actions.forEach(function (action) {
|
||||
notif[action] = closeNotif(cb, action);
|
||||
});
|
||||
}
|
||||
|
||||
notifs.push(notif);
|
||||
}
|
||||
|
||||
function formatMsg(msg, from) {
|
||||
var rtn = '';
|
||||
if (from) {
|
||||
rtn += from + ': ';
|
||||
}
|
||||
|
||||
if (typeof msg === 'string') {
|
||||
rtn += msg;
|
||||
} else if (msg instanceof Error) {
|
||||
rtn += msg.message;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Track application lifecycle events
|
||||
* @type {[type]}
|
||||
*/
|
||||
var lifecycleEvents = window.kibanaLifecycleEvents = {};
|
||||
|
||||
var applicationBooted;
|
||||
|
||||
/**
|
||||
* Functionality to check that
|
||||
*/
|
||||
function NotifyManager(opts) {
|
||||
opts = opts || {};
|
||||
|
||||
// label type thing to say where notifications came from
|
||||
this.from = opts.location;
|
||||
|
||||
// attach the global notification list
|
||||
this._notifs = notifs;
|
||||
}
|
||||
|
||||
NotifyManager.prototype.lifecycle = function (name, success) {
|
||||
var status;
|
||||
if (name === 'bootstrap' && success === true) applicationBooted = true;
|
||||
|
||||
if (success === void 0) {
|
||||
// start
|
||||
lifecycleEvents[name] = now();
|
||||
} else {
|
||||
// end
|
||||
if (success) {
|
||||
lifecycleEvents[name] = now() - (lifecycleEvents[name] || 0);
|
||||
status = lifecycleEvents[name].toFixed(2) + ' ms';
|
||||
} else {
|
||||
lifecycleEvents[name] = false;
|
||||
status = 'failure';
|
||||
}
|
||||
}
|
||||
|
||||
log('KBN: ' + name + (status ? ' - ' + status : ''));
|
||||
};
|
||||
|
||||
/**
|
||||
* Kill the page, and display an error
|
||||
* @param {Error} err - The fatal error that occured
|
||||
*/
|
||||
NotifyManager.prototype.fatal = function (err) {
|
||||
var html = fatalToastTemplate({
|
||||
msg: formatMsg(err, this.from),
|
||||
stack: err.stack
|
||||
});
|
||||
|
||||
var $container = $('#fatal-splash-screen');
|
||||
if ($container.size()) {
|
||||
$container.append(html);
|
||||
return;
|
||||
}
|
||||
|
||||
$container = $();
|
||||
|
||||
// in case the app has not completed boot
|
||||
$(document.body)
|
||||
.removeAttr('ng-cloak')
|
||||
.html('<div id="fatal-splash-screen" class="container-fuild">' + html + '</div>');
|
||||
|
||||
console.error(err.stack);
|
||||
};
|
||||
|
||||
/**
|
||||
* Alert the user of an error that occured
|
||||
* @param {Error|String} err
|
||||
*/
|
||||
NotifyManager.prototype.error = function (err, cb) {
|
||||
add({
|
||||
type: 'danger',
|
||||
content: formatMsg(err, this.from),
|
||||
icon: 'warning',
|
||||
title: 'Error',
|
||||
lifetime: Infinity,
|
||||
actions: ['report', 'accept']
|
||||
}, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* Warn the user abort something
|
||||
* @param {[type]} msg [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
NotifyManager.prototype.warning = function (msg, cb) {
|
||||
add({
|
||||
type: 'warning',
|
||||
content: formatMsg(msg, this.from),
|
||||
icon: 'warning',
|
||||
title: 'Warning',
|
||||
lifetime: 7000,
|
||||
actions: ['accept']
|
||||
}, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* Display a debug message
|
||||
* @param {String} msg [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
NotifyManager.prototype.info = function (msg, cb) {
|
||||
add({
|
||||
type: 'info',
|
||||
content: formatMsg(msg),
|
||||
icon: 'info-circle',
|
||||
title: 'Debug',
|
||||
lifetime: 7000,
|
||||
actions: ['accept']
|
||||
}, cb);
|
||||
};
|
||||
|
||||
// set the timer functions that all notification managers will use
|
||||
NotifyManager.prototype._setTimerFns = function (set, clear) {
|
||||
setTO = set;
|
||||
clearTO = clear;
|
||||
};
|
||||
|
||||
return NotifyManager;
|
||||
});
|
||||
|
|
|
@ -10,12 +10,10 @@ define(function (require) {
|
|||
|
||||
require('./directives');
|
||||
|
||||
module.service('notify', function () {
|
||||
var service = this;
|
||||
// modify the service to have bound proxies to the manager
|
||||
_.forOwn(manager, function (val, key) {
|
||||
service[key] = typeof val === 'function' ? _.bindKey(manager, key) : val;
|
||||
});
|
||||
module.factory('createNotifier', function () {
|
||||
return function (opts) {
|
||||
return new NotifyManager(opts);
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -90,4 +88,4 @@ define(function (require) {
|
|||
|
||||
return manager;
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -37,7 +37,7 @@ define(function (require) {
|
|||
|
||||
angular
|
||||
.bootstrap(appEl, ['setup'])
|
||||
.invoke(function (es, config, notify) {
|
||||
.invoke(function (es, config) {
|
||||
// init the setup module
|
||||
async.series([
|
||||
async.apply(checkForES, es),
|
||||
|
@ -136,4 +136,4 @@ define(function (require) {
|
|||
});
|
||||
});
|
||||
};
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue