aesthetic changes to alarms modal - alarm definitions are properly rendered
Costa Tsaousis (ktsaou) committed
Aug 28, 2016 at 21:15 UTC
dcacca040adce290c56041c42b3b656d6b63273b
1 file changed
+134
-12
web/index.html
+134
-12
@@ -125,6 +125,13 @@
125
overflow: visible;
126
}
127
128
+ /* make accordion use the whole header bar for expand/collapse */
129
+ .panel-title a {
130
+ display: block;
131
+ padding: 10px 15px;
132
+ margin: -10px -15px;
133
+ }
134
+
135
/*
136
* Side navigation
137
*
@@ -2406,9 +2413,13 @@ function alarmsUpdateModal() {
2413
var active = '<h3>Raised Alarms</h3><table class="table">';
2414
var all = '<h3>All Running Alarms</h3><div class="panel-group" id="alarms_all_accordion" role="tablist" aria-multiselectable="true">';
2415
var log = '<h3>Alarm Log</h3><table class="table"><tr><th>When</th><th>Chart</th><th>Alarm</th><th>Status</th>';
2409
- var footer = '<hr/>These are <a href="https://github.com/firehol/netdata/wiki/Generating-Badges" target="_blank">netdata badges</a>. You can copy and paste their URLs to embed them in any web page. Their color indicates the state of the alarm: <b>red</b> is critical, <b>orange</b> is warning, <b>bright green</b> is ok, <b>light grey</b> is undefined (i.e. no data or no status), <b>black</b> is not initialized.';
2416
+ var footer = '<hr/><a href="https://github.com/firehol/netdata/wiki/Generating-Badges" target="_blank">netdata badges</a> refresh automatically. Their color indicates the state of the alarm: <span style="color: #e05d44"><b> red </b></span> is critical, <span style="color:#fe7d37"><b> orange </b></span> is warning, <span style="color: #4c1"><b> bright green </b></span> is ok, <span style="color: #9f9f9f"><b> light grey </b></span> is undefined (i.e. no data or no status), <span style="color: #000"><b> black </b></span> is not initialized. You can copy and paste their URLs to embed them in any web page.';
2417
2418
NETDATA.alarms.get('all', function(data) {
2419
+ options.alarm_families = new Array();
2420
+
2421
+ alarmsCallback(data);
2422
+
2423
if(data === null) {
2424
document.getElementById('alarms_active').innerHTML =
2425
document.getElementById('alarms_all').innerHTML =
@@ -2417,6 +2428,96 @@ function alarmsUpdateModal() {
2428
return;
2429
}
2430
2431
+ function frequency_text(seconds, sfx) {
2432
+ if(seconds === 0)
2433
+ return 'now';
2434
+
2435
+ var suffix = '';
2436
+ if(seconds < 0) {
2437
+ seconds = -seconds;
2438
+ if(sfx) suffix = ' ago';
2439
+ }
2440
+
2441
+ var hours = Math.floor(seconds / 3600);
2442
+ seconds -= (hours * 3600);
2443
+
2444
+ var minutes = Math.floor(seconds / 60);
2445
+ seconds -= (minutes * 60);
2446
+
2447
+ var txt = '';
2448
+
2449
+ if(hours > 1) txt += hours.toString() + ' hours';
2450
+ else if(hours === 1) txt += hours.toString() + ' hour';
2451
+
2452
+ if(hours > 0 && minutes > 0 && seconds == 0)
2453
+ txt += ' and ';
2454
+ else if(hours > 0 && minutes > 0 && seconds > 0)
2455
+ txt += ', ';
2456
+
2457
+ if(minutes > 1) txt += minutes.toString() + ' minutes';
2458
+ else if(minutes === 1) txt += minutes.toString() + ' minute';
2459
+
2460
+ if((minutes > 0 || minutes > 0) && seconds > 0)
2461
+ txt += ' and ';
2462
+
2463
+ if(seconds > 1) txt += seconds.toString() + ' seconds';
2464
+ else if(seconds === 1) txt += seconds.toString() + ' second';
2465
+
2466
+ return txt + suffix;
2467
+ }
2468
+
2469
+ function alarm_lookup_explain(alarm, chart) {
2470
+ var dimensions = '';
2471
+
2472
+ if(chart.dimensions.length > 1)
2473
+ dimensions = '(of the sum of all dimensions), ';
2474
+
2475
+ if(typeof alarm.lookup_dimensions !== 'undefined') {
2476
+ var d = alarm.lookup_dimensions.replace('|', ',');
2477
+ var x = d.split(',');
2478
+ if(x.length > 1)
2479
+ dimensions = 'of the sum of dimensions <code>' + alarm.lookup_dimensions + '</code>, ';
2480
+ else
2481
+ dimensions = 'of the dimension <code>' + alarm.lookup_dimensions + '</code>, ';
2482
+ }
2483
+
2484
+ return '<code>' + alarm.lookup_method + '</code> of all values '
2485
+ + dimensions
2486
+ + 'starting <code>' + frequency_text(alarm.lookup_after + alarm.lookup_before, true) + '</code> and up to <code>' + frequency_text(alarm.lookup_before, true) + '</code>'
2487
+ + ((alarm.lookup_options)?(', with options <code>' + alarm.lookup_options.replace(' ', ', ') + '</code>'):'')
2488
+ + '.';
2489
+ }
2490
+
2491
+ function alarm_to_html(alarm) {
2492
+ var chart = options.data.charts[alarm.chart];
2493
+ // console.log(alarm);
2494
+ return '<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></td>'
2495
+ + '<td><table class="table">'
2496
+ + ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
2497
+ + ((typeof alarm.calc !== 'undefined')?('<tr><td width="10%" style="text-align:right">calculation</td><td><code>' + alarm.calc + '</code></td></tr>'):'')
2498
+ + ((typeof alarm.warn !== 'undefined')?('<tr><td width="10%" style="text-align:right">warning when</td><td><code>' + alarm.warn + '</code></td></tr>'):'')
2499
+ + ((typeof alarm.crit !== 'undefined')?('<tr><td width="10%" style="text-align:right">critical when</td><td><code>' + alarm.crit + '</code></td></tr>'):'')
2500
+ + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
2501
+ + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'')
2502
+ + '<tr><td width="10%" style="text-align:right">check every</td><td>' + frequency_text(alarm.update_every) + '</td></tr>'
2503
+ + '<tr><td width="10%" style="text-align:right">source</td><td>' + alarm.source + '</td></tr>'
2504
+ + '</table></td></tr>';
2505
+ }
2506
+
2507
+ function alarm_family_show(id) {
2508
+ var html = '<table class="table">';
2509
+ var family = options.alarm_families[id];
2510
+ var len = family.arr.length;
2511
+ while(len--) {
2512
+ var alarm = family.arr[len];
2513
+ html += alarm_to_html(alarm);
2514
+ }
2515
+ html += '</table>';
2516
+
2517
+ $('#alarm_all_' + id.toString()).html(html);
2518
+ }
2519
+
2520
+ // find the proper family of each alarm
2521
var now = new Date().getTime();
2522
var x;
2523
var count_active = 0;
@@ -2447,31 +2548,36 @@ function alarmsUpdateModal() {
2548
families[family].arr.push(alarm);
2549
}
2550
2450
- function families_comparator(a, b) {
2551
+ // sort the families, like the dashboard menu does
2552
+ var families_sorted = families_sort.sort(function (a, b) {
2553
if (a.priority > b.priority) return -1;
2554
if (a.priority < b.priority) return 1;
2555
+ if (a.name < b.name) return 1;
2556
+ if (a.name > b.name) return -1;
2557
return 0;
2454
- }
2455
- var families_sorted = families_sort.sort(families_comparator);
2558
+ });
2559
2560
var fc = 0;
2561
var len = families_sorted.length;
2562
while(len--) {
2460
- fc++;
2563
var family = families_sorted[len].name;
2564
var active_family_added = false;
2565
var expanded = 'true';
2566
var collapsed = '';
2567
var cin = 'in';
2568
2467
- if(fc !== 1) {
2569
+ if(fc !== 0) {
2570
all += "</table></div></div></div>";
2571
expanded = 'false';
2572
collapsed = 'class="collapsed"'
2573
cin = '';
2574
}
2575
2474
- all += '<div class="panel panel-default"><div class="panel-heading" role="tab" id="alarm_all_heading_' + fc.toString() + '"><h4 class="panel-title"><a ' + collapsed + ' role="button" data-toggle="collapse" data-parent="#alarms_all_accordion" href="#alarm_all_' + fc.toString() + '" aria-expanded="' + expanded + '" aria-controls="alarm_all_' + fc.toString() + '">' + family.toString() + '</a></h4></div><div id="alarm_all_' + fc.toString() + '" class="panel-collapse collapse ' + cin + '" role="tabpanel" aria-labelledby="alarm_all_heading_' + fc.toString() + '"><div class="panel-body"><table class="table">';
2576
+ all += '<div class="panel panel-default"><div class="panel-heading" role="tab" id="alarm_all_heading_' + fc.toString() + '"><h4 class="panel-title"><a ' + collapsed + ' role="button" data-toggle="collapse" data-parent="#alarms_all_accordion" href="#alarm_all_' + fc.toString() + '" aria-expanded="' + expanded + '" aria-controls="alarm_all_' + fc.toString() + '">' + family.toString() + '</a></h4></div><div id="alarm_all_' + fc.toString() + '" class="panel-collapse collapse ' + cin + '" role="tabpanel" aria-labelledby="alarm_all_heading_' + fc.toString() + '" data-alarm-id="' + fc.toString() + '"><div class="panel-body" id="alarm_all_body_' + fc.toString() + '">';
2577
+
2578
+ options.alarm_families[fc] = families[family];
2579
+
2580
+ fc++;
2581
2582
var arr = families[family].arr;
2583
var c = arr.length;
@@ -2483,15 +2589,14 @@ function alarmsUpdateModal() {
2589
active += '<tr><th class="text-center"><h4>' + family + '</h4></th><th></th></tr>';
2590
}
2591
count_active++;
2486
- active += '<tr><td class="text-center" style="vertical-align:middle" width="40%"><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20" /></td><td><b>' + alarm.info + '</b><table>' + ((typeof alarm.warn !== 'undefined')?('<tr><td> warning when </td><td><code>' + alarm.warn + '</code></td></tr>'):'') + ((typeof alarm.crit !== 'undefined')?('<tr><td style="text-align:right"> critical when </td><td><code>' + alarm.crit + '</code></td></tr>'):'') + '<tr><td style="text-align:right"><small> source </small></td><td><small>' + alarm.source + '</small></td></tr></table></td></tr>';
2592
+ active += alarm_to_html(alarm);
2593
}
2594
2595
count_all++;
2490
- all += '<tr><td class="text-center" style="vertical-align:middle" width="40%"><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20" /></td><td><b>' + alarm.info + '</b><table>' + ((typeof alarm.warn !== 'undefined')?('<tr><td> warning when </td><td><code>' + alarm.warn + '</code></td></tr>'):'') + ((typeof alarm.crit !== 'undefined')?('<tr><td style="text-align:right"> critical when </td><td><code>' + alarm.crit + '</code></td></tr>'):'') + '<tr><td style="text-align:right"><small> source </small></td><td><small>' + alarm.source + '</small></td></tr></table></td></tr>';
2596
}
2597
}
2598
active += "</table>";
2494
- if(families_sorted.length > 0) all += "</table></div></div></div>";
2599
+ if(families_sorted.length > 0) all += "</div></div></div>";
2600
all += "</div>";
2601
2602
if(!count_active)
@@ -2507,6 +2612,20 @@ function alarmsUpdateModal() {
2612
document.getElementById('alarms_active').innerHTML = active;
2613
document.getElementById('alarms_all').innerHTML = all;
2614
2615
+ if(families_sorted.length > 0) alarm_family_show(0);
2616
+
2617
+ // register bootstrap events
2618
+ $('#alarms_all_accordion').on('show.bs.collapse', function (d) {
2619
+ var target = $(d.target);
2620
+ var id = $(target).data('alarm-id');
2621
+ alarm_family_show(id);
2622
+ });
2623
+ $('#alarms_all_accordion').on('hidden.bs.collapse', function (d) {
2624
+ var target = $(d.target);
2625
+ var id = $(target).data('alarm-id');
2626
+ $('#alarm_all_' + id.toString()).html('');
2627
+ });
2628
+
2629
NETDATA.alarms.get_log(function(data) {
2630
if(data === null) {
2631
document.getElementById('alarms_log').innerHTML =
@@ -2534,8 +2653,11 @@ function alarmsUpdateModal() {
2653
2654
function alarmsCallback(data) {
2655
var count = 0;
2537
- for(x in data.alarms)
2538
- count++;
2656
+ for(x in data.alarms) {
2657
+ var alarm = data.alarms[x];
2658
+ if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL')
2659
+ count++;
2660
+ }
2661
2662
if(count > 0)
2663
document.getElementById('alarms_count_badge').innerHTML = count.toString();