// global namespace
var NETDATA = window.NETDATA || {};
+ NETDATA.name2id = function(s) {
+ return s
+ .replace(/ /g, '_')
+ .replace(/\(/g, '_')
+ .replace(/\)/g, '_')
+ .replace(/\./g, '_')
+ .replace(/\//g, '_');
+ };
+
// ----------------------------------------------------------------------------------------------------------------
// Detect the netdata server
// Registry of netdata hosts
NETDATA.alarms = {
- notifications: false, // when true, the browser supports notifications (may not be granted though)
- last_notification_id: 0, // the id of the last alarm_log we have raised an alarm for
+ onclick: null, // the callback to handle the click - it will be called with the alarm log entry
+ chart_div_offset: 100, // give that space above the chart when scrolling to it
+ chart_div_id_prefix: 'chart_', // the chart DIV IDs have this prefix (they should be NETDATA.name2id(chart.id))
+ chart_div_animation_duration: 0,// the duration of the animation while scrolling to a chart
+
+ ms_penalty: 0, // the time penalty of the next alarm
+ ms_between_notifications: 500, // firefox moves the alarms off-screen (above, outside the top of the screen)
+ // if alarms are shown faster than: one per 500ms
+
+ notifications: false, // when true, the browser supports notifications (may not be granted though)
+ last_notification_id: 0, // the id of the last alarm_log we have raised an alarm for
// notifications_shown: new Array(),
- server: null, // the server to connect to for fetching alarms
- current: null, // the list of raised alarms - updated in the background
- callback: null, // a callback function to call every time the list of raised alarms is refreshed
+ server: null, // the server to connect to for fetching alarms
+ current: null, // the list of raised alarms - updated in the background
+ callback: null, // a callback function to call every time the list of raised alarms is refreshed
notify: function(entry) {
// console.log('alarm ' + entry.unique_id);
*/
if(show === true) {
- // show this notification
- // console.log('new notification: ' + title);
- var n = new Notification(title, {
- body: entry.hostname + ' - ' + entry.chart + ' (' + entry.family + ') - ' + status + ': ' + entry.info,
- tag: tag,
- requireInteraction: interaction,
- icon: NETDATA.serverDefault + icon,
- data: data
- // FIXME: does not seem to work on any web browser
- // onclick: function(event) {
- // event.preventDefault();
- // console.log('clicked: ');
- // console.log(event);
- //}
- });
- // console.log(n);
- // NETDATA.alarms.notifications_shown.push(n);
- // console.log(entry);
+ setTimeout(function() {
+ // show this notification
+ // console.log('new notification: ' + title);
+ var n = new Notification(title, {
+ body: entry.hostname + ' - ' + entry.chart + ' (' + entry.family + ') - ' + status + ': ' + entry.info,
+ tag: tag,
+ requireInteraction: interaction,
+ icon: NETDATA.serverDefault + icon,
+ data: data
+ });
+
+ n.onclick = function(event) {
+ event.preventDefault();
+ NETDATA.alarms.onclick(event.target.data);
+ };
+
+ // console.log(n);
+ // NETDATA.alarms.notifications_shown.push(n);
+ // console.log(entry);
+ }, NETDATA.alarms.ms_penalty);
+
+ NETDATA.alarms.ms_penalty += NETDATA.alarms.ms_between_notifications;
}
},
+ scrollToChart: function(chart_id) {
+ if(typeof chart_id === 'string') {
+ var offset = $('#' + NETDATA.alarms.chart_div_id_prefix + NETDATA.name2id(chart_id)).offset();
+ if(typeof offset !== 'undefined') {
+ $('html, body').animate({ scrollTop: offset.top - NETDATA.alarms.chart_div_offset }, NETDATA.alarms.chart_div_animation_duration);
+ return true;
+ }
+ }
+ return false;
+ },
+
+ scrollToAlarm: function(alarm) {
+ if(typeof alarm === 'object') {
+ var ret = NETDATA.alarms.scrollToChart(alarm.chart);
+
+ if(ret === true && NETDATA.options.page_is_visible === false)
+ window.focus();
+ // alert('netdata dashboard will now scroll to chart: ' + alarm.chart + '\n\nThis alarm opened to bring the browser window in front of the screen. Click on the dashboard to prevent it from appearing again.');
+ }
+
+ },
+
notifyAll: function() {
// console.log('FETCHING ALARM LOG');
NETDATA.alarms.get_log(NETDATA.alarms.last_notification_id, function(data) {
return 0;
});
+ NETDATA.alarms.ms_penalty = 0;
+
var len = data.length;
while(len--) {
if(data[len].unique_id > NETDATA.alarms.last_notification_id) {
host = host.substring(0, host.length - 1);
NETDATA.alarms.server = host;
+ if(NETDATA.alarms.onclick === null)
+ NETDATA.alarms.onclick = NETDATA.alarms.scrollToAlarm;
+
if(netdataShowAlarms === true) {
NETDATA.alarms.update_forever();
</script>
<!-- load the dashboard manager - it will do the rest -->
- <script type="text/javascript" src="dashboard.js?v50"></script>
+ <script type="text/javascript" src="dashboard.js?v51"></script>
</head>
<body data-spy="scroll" data-target="#sidebar">
<div id="loadOverlay" class="loadOverlay" style="background-color: #888; color: #888;">
// ----------------------------------------------------------------------------
-function name2id(s) {
- return s
- .replace(/ /g, '_')
- .replace(/\(/g, '_')
- .replace(/\)/g, '_')
- .replace(/\./g, '_')
- .replace(/\//g, '_');
-}
-
function headMain(charts, duration) {
var head = '';
// generate an entry at the main menu
- var menuid = name2id(menu);
+ var menuid = NETDATA.name2id('menu_' + menu);
sidebar += '<li class=""><a href="#' + menuid + '" onClick="return scrollToId(\'' + menuid + '\');">' + menus[menu].icon + ' ' + menus[menu].title + '</a><ul class="nav">';
- html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div id="menu_' + menuid + '" role="document">';
+ html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div role="document">';
if(menus[menu].info !== null)
html += menus[menu].info;
var submenu = sub[si++];
// generate an entry at the submenu
- var submenuid = name2id(menu + '_' + submenu);
+ var submenuid = NETDATA.name2id('menu_' + menu + '_submenu_' + submenu);
sidebar += '<li class><a href="#' + submenuid + '" onClick="return scrollToId(\'' + submenuid + '\');">' + menus[menu].submenus[submenu].title + '</a></li>';
- shtml += '<div class="netdata-group-container" id="submenu_' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
+ shtml += '<div class="netdata-group-container" id="' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
if(menus[menu].submenus[submenu].info !== null)
shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
head += generateHeadCharts('heads', chart, duration);
// generate the chart
- chtml += chartInfo(chart.context) + '<div data-netdata="' + chart.id + '"'
+ chtml += chartInfo(chart.context) + '<div id="chart_' + NETDATA.name2id(chart.id) + '" data-netdata="' + chart.id + '"'
+ ' data-width="' + pcent_width.toString() + '%"'
+ ' data-height="' + chartHeight(chart.context, options.chartsHeight).toString() + 'px"'
+ ' data-before="0"'
+ ' data-after="-' + duration.toString() + '"'
- + ' data-id="' + name2id(options.hostname + '/' + chart.id) + '"'
+ + ' data-id="' + NETDATA.name2id(options.hostname + '/' + chart.id) + '"'
+ ' data-colors="' + anyAttribute(chartData, 'colors', chart.context, '') + '"'
+ ' role="application"></div>';
// console.log(urlOptions.chart + ' === ' + c);
if(urlOptions.chart === c) {
- urlOptions.hash = '#' + name2id(charts[c].menu + '_' + charts[c].submenu)
+ urlOptions.hash = '#' + NETDATA.name2id(charts[c].menu + '_' + charts[c].submenu)
// console.log('hash = ' + urlOptions.hash);
}
}
function alarm_to_html(alarm, full) {
var chart = options.data.charts[alarm.chart];
- var html = '<tr><td class="text-center" style="vertical-align:middle" width="40%"><b>' + alarm.chart + '</b><br/> <br/><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20" /><br/> <br/><span style="font-size: 18px">' + alarm.info + '</span><br/> <br/>role: <b>' + alarm.recipient + '</b></td>'
+ var html = '<tr><td class="text-center" style="vertical-align:middle" width="40%"><b>' + alarm.chart + '</b><br/> <br/><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20"/><br/> <br/><span style="font-size: 18px">' + alarm.info + '</span><br/> <br/>role: <b>' + alarm.recipient + '</b><br/> <br/><b><i class="fa fa-line-chart" aria-hidden="true"></i></b><small> <a href="#" onClick="NETDATA.alarms.scrollToChart(\'' + alarm.chart + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;">jump to chart</a></small></td>'
+ '<td><table class="table">'
+ ((typeof alarm.warn !== 'undefined')?('<tr><td width="10%" style="text-align:right">warning when</td><td><span style="font-family: monospace; color:#fe7d37; font-weight: bold;">' + alarm.warn + '</span></td></tr>'):'')
+ ((typeof alarm.crit !== 'undefined')?('<tr><td width="10%" style="text-align:right">critical when</td><td><span style="font-family: monospace; color: #e05d44; font-weight: bold;">' + alarm.crit + '</span></td></tr>'):'');
document.getElementById('alarms_count_badge').innerHTML = '';
}
-function downloadAllCharts(netdata_url) {
+function initializeDynamicDashboard(netdata_url) {
if(typeof netdata_url === 'undefined' || netdata_url === null)
netdata_url = NETDATA.serverDefault;
+ // initialize clickable alarms
+ NETDATA.alarms.chart_div_offset = 100;
+ NETDATA.alarms.chart_div_id_prefix = 'chart_';
+ NETDATA.alarms.chart_div_animation_d0uration = 0;
+
NETDATA.pause(function() {
$("#loadOverlay").css("display","none");
// change the URL based on the current position of the screen
$('#sidebar').on('activate.bs.scrollspy', function (e) {
+ // console.log(e);
var el = $(e.target);
- if(el.find('ul').size() == 0) {
- var hash = el.find('a').attr('href');
- if(typeof hash === 'string' && hash.substring(0, 1) == '#') {
- urlOptions.hash = hash;
- // console.log(urlOptions.hash);
- netdataHashUpdate();
- }
+ //if(el.find('ul').size() == 0) {
+ var hash = el.find('a').attr('href');
+ if(typeof hash === 'string' && hash.substring(0, 1) === '#' && urlOptions.hash.startsWith(hash + '_submenu_') === false) {
+ urlOptions.hash = hash;
+ console.log(urlOptions.hash);
+ netdataHashUpdate();
}
+ else console.log('hash: not accepting ' + hash);
+ //}
+ //else console.log('el.find(): not found');
});
document.getElementById('footer').style.display = 'block';
netdataReload();
}
-downloadAllCharts();
+initializeDynamicDashboard();
</script>