- Add "muncollapse" template (the template formerly known as munstrap4).
Lots of changes: * Fix the README * Add a makefile to fetch bootstrap, lazyload, jquery, the munin logo, and the munin favicon * Mostly re-write dynazoom. It works very much like the stock one now, with a few extra quick buttons, and of course the bootstrap styling * Remove all minified versions of scripts / css - The includes are minimal, it was not much of cost savings * Add sample images * Rename template to "muncollapse"
|
@ -0,0 +1,6 @@
|
|||
static/img/
|
||||
static/css/bootstrap.min.css
|
||||
static/js/bootstrap.min.js
|
||||
static/js/jquery.min.js
|
||||
static/js/lazysizes.min.js
|
||||
static/js/typeahead.bundle.min.js
|
|
@ -0,0 +1,54 @@
|
|||
# MunCollapsible
|
||||
#
|
||||
# Makefile for the MunCollapsible template.
|
||||
|
||||
# HTTP Fetch program to use. Called as $(HTTP_FETCH) <output_file> <input_url>
|
||||
#
|
||||
# Swap the comments to use curl instead.
|
||||
HTTP_FETCH = wget -nv -O
|
||||
#HTTP_FETCH = curl -s -w "%{http_code} - %{filename_effective} - %{size_download} bytes\n" -o
|
||||
|
||||
|
||||
# The versions of the external libraries to use.
|
||||
BOOTSTRAP_VERSION = 4.4.1
|
||||
JQUERY_VERSION = 3.4.1.slim
|
||||
TYPEAHEAD_VERSION = latest
|
||||
|
||||
FAVICON_FILES := android-chrome-144x144.png android-chrome-192x192.png android-chrome-36x36.png android-chrome-48x48.png android-chrome-72x72.png android-chrome-96x96.png apple-touch-icon-114x114.png apple-touch-icon-120x120.png apple-touch-icon-144x144.png apple-touch-icon-152x152.png apple-touch-icon-180x180.png apple-touch-icon-57x57.png apple-touch-icon-60x60.png apple-touch-icon-72x72.png apple-touch-icon-76x76.png apple-touch-icon-precomposed.png apple-touch-icon.png browserconfig.xml favicon-16x16.png favicon-194x194.png favicon-32x32.png favicon-96x96.png favicon.ico manifest.json mstile-144x144.png mstile-150x150.png mstile-310x150.png mstile-310x310.png mstile-70x70.png
|
||||
FAVICON_BASEURL = https://raw.githubusercontent.com/munin-monitoring/munin/master/web/static/img/favicons/
|
||||
|
||||
LOGO_URL = https://raw.githubusercontent.com/munin-monitoring/munin/master/web/static/img/logo-h.png
|
||||
|
||||
BOOTSTRAP_CSS_URL = https://stackpath.bootstrapcdn.com/bootstrap/$(BOOTSTRAP_VERSION)/css/bootstrap.min.css
|
||||
BOOTSTRAP_JS_URL = https://stackpath.bootstrapcdn.com/bootstrap/$(BOOTSTRAP_VERSION)/js/bootstrap.bundle.min.js
|
||||
JQUERY_JS_URL = https://code.jquery.com/jquery-$(JQUERY_VERSION).min.js
|
||||
TYPEAHEAD_JS_URL = https://twitter.github.io/typeahead.js/releases/$(TYPEAHEAD_VERSION)/typeahead.bundle.js
|
||||
LAZYSIZES_URL = http://afarkas.github.io/lazysizes/lazysizes.min.js
|
||||
|
||||
CWD := $(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
|
||||
|
||||
|
||||
main:
|
||||
@echo $(CWD)
|
||||
@echo Downloading External Libraries...
|
||||
|
||||
$(HTTP_FETCH) $(CWD)/static/css/bootstrap.min.css $(BOOTSTRAP_CSS_URL)
|
||||
$(HTTP_FETCH) $(CWD)/static/js/bootstrap.min.js $(BOOTSTRAP_JS_URL)
|
||||
$(HTTP_FETCH) $(CWD)/static/js/jquery.min.js $(JQUERY_JS_URL)
|
||||
$(HTTP_FETCH) $(CWD)/static/js/typeahead.bundle.min.js $(TYPEAHEAD_JS_URL)
|
||||
$(HTTP_FETCH) $(CWD)/static/js/lazysizes.min.js $(LAZYSIZES_URL)
|
||||
|
||||
@echo Downloading Logo...
|
||||
@mkdir -p $(CWD)/static/img
|
||||
$(HTTP_FETCH) $(CWD)/static/img/logo-munin.png $(LOGO_URL)
|
||||
|
||||
@echo Downloading Favicon Files...
|
||||
|
||||
@mkdir -p $(CWD)/static/img/favicon
|
||||
@for file in ${FAVICON_FILES}; do \
|
||||
eval $(HTTP_FETCH) $(CWD)/static/img/favicon/$${file} $(FAVICON_BASEURL)$${file}; \
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
# MunCollapse
|
||||
|
||||
Alternative Munin 2.x templates based on Twitter Bootstrap using collapsibles.
|
||||
|
||||
Based on some of the work of "Munstrap" by [Jonny McCullagh](https://github.com/jonnymccullagh), [munin-monitoring/contrib](https://github.com/munin-monitoring/contrib/tree/master/templates/munstrap) repo.
|
||||
|
||||
#### Overview Sample Image
|
||||
<a href="sample-image/sample-home.png"><img src="sample-image/sample-home.png" style="max-width: 1229px; display:block; margin-left: auto; margin-right: auto; width: 75%" /></a>
|
||||
|
||||
[Semi-Live Demo](https://jtsage.dev/munin-demo/) - For the purposes of this demo only, the data is static and the zoom functionality is disabled.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Clone the munin-monitoring/contrib repo to a temporary location:
|
||||
|
||||
```
|
||||
$ cd /opt
|
||||
$ git clone https://github.com/munin-monitoring/contrib.git
|
||||
```
|
||||
|
||||
### 2. Fetch the template libraries
|
||||
|
||||
```
|
||||
$ cd /opt/contrib/templates/muncollapse/
|
||||
$ make
|
||||
```
|
||||
|
||||
### 3. Place the template in an appropriate safe place
|
||||
|
||||
Ubuntu shown - other distros may prefer ```/usr/local/share/munin/...```
|
||||
|
||||
```
|
||||
$ mkdir /usr/share/munin/template
|
||||
$ mkdir /usr/share/munin/template/muncollapse
|
||||
```
|
||||
__NOTE__: If this step fails, your munin installation may use ```/usr/local/share/munin/...``` instead!
|
||||
|
||||
```
|
||||
$ cp -r /opt/contrib/templates/muncollapse/templates /usr/share/munin/template/muncollapse/
|
||||
$ cp -r /opt/contrib/templates/muncollapse/static /usr/share/munin/template/muncollapse/
|
||||
```
|
||||
|
||||
### 4. Edit your ```munin.conf``` file.
|
||||
|
||||
Typically located at ```/etc/munin.conf```
|
||||
|
||||
__FIND AND CHANGE:__ (near the top of the file)
|
||||
|
||||
```
|
||||
# Where to look for the HTML templates
|
||||
#
|
||||
#tmpldir /etc/munin/templates
|
||||
|
||||
# Where to look for the static www files
|
||||
#
|
||||
#staticdir /etc/munin/static
|
||||
```
|
||||
|
||||
__TO:__
|
||||
```
|
||||
# Where to look for the HTML templates
|
||||
#
|
||||
tmpldir /usr/share/munin/template/muncollapse/templates
|
||||
|
||||
# Where to look for the static www files
|
||||
#
|
||||
staticdir /usr/share/munin/template/muncollapse/static
|
||||
```
|
||||
|
||||
### 5. [Optional / Recommended] Clean out the old generated files.
|
||||
|
||||
This isn't really required, but there will likely be orphaned files. The location of these files can be found in your ```munin.conf``` file, with the ```htmldir``` directive.
|
||||
|
||||
__NOTE:__ Ubuntu shown, other distributions may be in ```/var/www/munin/```
|
||||
|
||||
```
|
||||
$ rm -rf /var/cache/munin/www/*
|
||||
```
|
||||
|
||||
### 6. Wait Patiently
|
||||
|
||||
```munin-update``` will regenerate the files the next time it runs. By default, this is on the :05 minute tick for most installations. If you do not have new files within 10 minutes, be sure to check ```munin-update.log``` and find out what went wrong.
|
||||
|
||||
---
|
||||
|
||||
## Revert to Official Munin Template
|
||||
|
||||
### 1. Edit your ```munin.conf``` file.
|
||||
|
||||
Typically located at ```/etc/munin.conf```
|
||||
|
||||
__FIND AND CHANGE:__ (near the top of the file - comment these lines out!)
|
||||
|
||||
# Where to look for the HTML templates
|
||||
#
|
||||
#tmpldir /usr/share/munin/template/muncollapse/templates
|
||||
|
||||
# Where to look for the static www files
|
||||
#
|
||||
#staticdir /usr/share/munin/template/muncollapse/static
|
||||
|
||||
### 2. [Optional / Recommended] Clean up
|
||||
|
||||
Remove the files from step #1 & #3 above, and repeat step #5 & #6.
|
||||
|
||||
---
|
||||
|
||||
## Samples
|
||||
|
||||
#### View of a group:
|
||||
<a href="sample-image/sample-group.png"><img src="sample-image/sample-group.png" style="max-width: 1229px; display:block; margin-left: auto; margin-right: auto; width: 75%" /></a>
|
||||
|
||||
#### View of a specific node:
|
||||
<a href="sample-image/sample-node.png"><img src="sample-image/sample-node.png" style="max-width: 1229px; display:block; margin-left: auto; margin-right: auto; width: 75%" /></a>
|
||||
|
||||
|
||||
#### Zoom feature:
|
||||
<a href="sample-image/sample-zoom.png"><img src="sample-image/sample-zoom.png" style="max-width: 1229px; display:block; margin-left: auto; margin-right: auto; width: 75%" /></a>
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Munin Compatibility
|
||||
|
||||
a/n: I am unsure of the compatibility with Munin 3. Most things will work from what I've read, but the navigation may be slightly funky.
|
||||
|
||||
---
|
||||
|
||||
### Browser Compatibility
|
||||
|
||||
For this template set, Internet Explorer support has been dropped for the dynamic zoom functions. Everything else should work across all browsers.
|
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 153 KiB |
|
@ -18,7 +18,7 @@ div.service-alert {
|
|||
}
|
||||
|
||||
img#zoom_image {
|
||||
margin-bottom: 15px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
ul.groupview, ul.groupview ul {
|
||||
|
@ -27,11 +27,9 @@ ul.groupview, ul.groupview ul {
|
|||
|
||||
.munin-icon {
|
||||
background: url(../img/logo-munin.png) left top;
|
||||
margin-top: -6px;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
width: 115px;
|
||||
height: 30px;
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
/* MunCollapse Template DynaZoom JavaScript File
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* - No Internet Explorer support (uses "URLSearchParams")
|
||||
* - This is not even really a fork of the upstream version any more
|
||||
* - Drops upstream requirement of "QueryString" include (URL.URLSearchParams)
|
||||
* - Drops upstream requirement of "FormatDate" include (Date.toISOString())
|
||||
*/
|
||||
|
||||
URLSearchParams.prototype.getDefault = function ( name, value ) {
|
||||
// Overload URLSearchParams to allow "default" values.
|
||||
return ( this.get( name ) === null ) ? value : this.get( name );
|
||||
};
|
||||
|
||||
function refreshZoom( query, form, image ) {
|
||||
//INIT
|
||||
var qs = new URLSearchParams( query.split( "\?" )[ 1 ] );
|
||||
|
||||
init();
|
||||
|
||||
refreshImg();
|
||||
|
||||
var start_epoch = parseInt( qs.getDefault( "rst_start_epoch", form.start_epoch.value ), 10 );
|
||||
var stop_epoch = parseInt( qs.getDefault( "rst_stop_epoch", form.stop_epoch.value ), 10 );
|
||||
|
||||
var highLighter = document.getElementById( "image-overlay" );
|
||||
var gutterOffsetLeft = 66;
|
||||
var highlightStartX = 0;
|
||||
var clickCounter = 0;
|
||||
var relativeStartX = 0;
|
||||
var graph_shown_width;
|
||||
var epoch_shown_start;
|
||||
var epoch_shown_stop;
|
||||
var eachPixelEpoch;
|
||||
|
||||
form.plugin_name.onblur = refreshImg;
|
||||
form.start_iso8601.onblur = majDates;
|
||||
form.stop_iso8601.onblur = majDates;
|
||||
form.start_epoch.onblur = function() { refreshImg(); updateStartStop(); };
|
||||
form.stop_epoch.onblur = function() { refreshImg(); updateStartStop(); };
|
||||
form.lower_limit.onblur = refreshImg;
|
||||
form.upper_limit.onblur = refreshImg;
|
||||
form.size_x.onblur = refreshImg;
|
||||
form.size_y.onblur = refreshImg;
|
||||
form.btnReset.onclick = reset;
|
||||
form.btnShowDay.onclick = function() { showPeriod( 1 ); };
|
||||
form.btnShowWeek.onclick = function() { showPeriod( 2 ); };
|
||||
form.btnShowMonth.onclick = function() { showPeriod( 3 ); };
|
||||
form.btnShowYear.onclick = function() { showPeriod( 4 ); };
|
||||
form.onsubmit = function() { document.activeElement.blur(); refreshImg(); return false; };
|
||||
|
||||
// Sets the onClick handler
|
||||
image.onclick = click;
|
||||
|
||||
//FUNCTIONS
|
||||
function init() {
|
||||
form.plugin_name.value = qs.getDefault( "plugin_name", "localdomain/localhost.localdomain/if_eth0" );
|
||||
form.start_epoch.value = qs.getDefault( "start_epoch", "1236561663" );
|
||||
form.stop_epoch.value = qs.getDefault( "stop_epoch", "1237561663" );
|
||||
form.lower_limit.value = qs.getDefault( "lower_limit", "" );
|
||||
form.upper_limit.value = qs.getDefault( "upper_limit", "" );
|
||||
form.size_x.value = qs.getDefault( "size_x", "" );
|
||||
form.size_y.value = qs.getDefault( "size_y", "" );
|
||||
|
||||
updateStartStop();
|
||||
}
|
||||
|
||||
function reset( event ) {
|
||||
init();
|
||||
|
||||
//Can be not the initial ones in case of manual refresh
|
||||
form.start_epoch.value = start_epoch;
|
||||
form.stop_epoch.value = stop_epoch;
|
||||
updateStartStop();
|
||||
|
||||
//Redraw
|
||||
scale = refreshImg();
|
||||
|
||||
//Reset gui
|
||||
clickCounter = 0;
|
||||
image.onmousemove = undefined;
|
||||
form.start_iso8601.disabled = false;
|
||||
form.stop_iso8601.disabled = false;
|
||||
form.start_epoch.disabled = false;
|
||||
form.stop_epoch.disabled = false;
|
||||
highLighter.style.left = "0px";
|
||||
highLighter.style.width = "2px";
|
||||
highLighter.style.display = "none";
|
||||
|
||||
document.activeElement.blur();
|
||||
return false;
|
||||
}
|
||||
|
||||
function refreshImg(event) {
|
||||
image.src = qs.getDefault( "cgiurl_graph", "/munin-cgi/munin-cgi-graph" ) + "/" +
|
||||
form.plugin_name.value +
|
||||
"-pinpoint=" + parseInt( form.start_epoch.value, 10 ) + "," + parseInt( form.stop_epoch.value, 10 ) +
|
||||
".png" + "?" +
|
||||
"&lower_limit=" + form.lower_limit.value +
|
||||
"&upper_limit=" + form.upper_limit.value +
|
||||
"&size_x=" + form.size_x.value +
|
||||
"&size_y=" + form.size_y.value;
|
||||
}
|
||||
|
||||
function updateStartStop() {
|
||||
form.start_iso8601.value = new Date( form.start_epoch.value * 1000 ).toISOString();
|
||||
form.stop_iso8601.value = new Date( form.stop_epoch.value * 1000 ).toISOString();
|
||||
}
|
||||
|
||||
function majDates( event ) {
|
||||
var lowLimit = new Date(),
|
||||
topLimit = new Date(),
|
||||
date_parsed = null;
|
||||
|
||||
lowLimit.setFullYear( lowLimit.getFullYear() - 1 );
|
||||
|
||||
date_parsed = new Date( Date.parse( form.start_iso8601.value ) || lowLimit.getTime() );
|
||||
form.start_epoch.value = Math.floor( date_parsed.getTime() / 1000 );
|
||||
|
||||
date_parsed = new Date( Date.parse( form.stop_iso8601.value) || topLimit.getTime() );
|
||||
form.stop_epoch.value = Math.floor( date_parsed.getTime() / 1000 );
|
||||
|
||||
updateStartStop();
|
||||
|
||||
refreshImg();
|
||||
}
|
||||
|
||||
function click( event ) {
|
||||
var relativeClickX = getClickLocation( event ),
|
||||
thisEpoch = null;
|
||||
|
||||
switch ( ( clickCounter++ ) % 3 ) {
|
||||
case 0: // First click of the displayed graph
|
||||
graph_shown_width = parseInt( form.size_x.value, 10) ;
|
||||
epoch_shown_start = parseInt( form.start_epoch.value,10 );
|
||||
epoch_shown_stop = parseInt( form.stop_epoch.value, 10 );
|
||||
eachPixelEpoch = ( ( epoch_shown_stop - epoch_shown_start ) / graph_shown_width );
|
||||
relativeStartX = ( relativeClickX < 0 ? 0 : relativeClickX );
|
||||
|
||||
form.start_iso8601.disabled = true;
|
||||
form.stop_iso8601.disabled = true;
|
||||
form.start_epoch.disabled = true;
|
||||
form.stop_epoch.disabled = true;
|
||||
|
||||
highlightStartX = event.pageX;
|
||||
highLighter.style.left = ( relativeStartX + gutterOffsetLeft + image.offsetLeft ) + "px";
|
||||
highLighter.style.display = "block";
|
||||
|
||||
form.start_epoch.value = offsetEpoch( relativeClickX );
|
||||
updateStartStop();
|
||||
|
||||
image.onmousemove = divMouseMove;
|
||||
|
||||
break;
|
||||
case 1: // Second (end) click of the displayed graph
|
||||
thisEpoch = offsetEpoch( relativeClickX );
|
||||
|
||||
image.onmousemove = undefined;
|
||||
form.start_iso8601.disabled = false;
|
||||
form.stop_iso8601.disabled = false;
|
||||
form.start_epoch.disabled = false;
|
||||
form.stop_epoch.disabled = false;
|
||||
|
||||
// For negative values, assume we want a new start point and the old end point.
|
||||
// If it's not, set it.
|
||||
if ( thisEpoch > form.start_epoch.value ) {
|
||||
form.stop_epoch.value = thisEpoch;
|
||||
} else {
|
||||
form.stop_epoch.value = Math.floor( epoch_shown_stop );
|
||||
highLighter.style.width = ( graph_shown_width - relativeStartX ) + "px";
|
||||
}
|
||||
updateStartStop();
|
||||
|
||||
break;
|
||||
case 2: // Nevermind or Do It.
|
||||
thisEpoch = offsetEpoch( relativeClickX );
|
||||
|
||||
if ( thisEpoch >= form.start_epoch.value && thisEpoch <= form.stop_epoch.value ) {
|
||||
refreshImg();
|
||||
} else {
|
||||
form.start_epoch.value = epoch_shown_start;
|
||||
form.stop_epoch.value = epoch_shown_stop;
|
||||
updateStartStop();
|
||||
}
|
||||
|
||||
highLighter.style.left = "0px";
|
||||
highLighter.style.width = "2px";
|
||||
highLighter.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function divMouseMove( event ) {
|
||||
var diff = event.pageX - highlightStartX,
|
||||
maxDiff = graph_shown_width - relativeStartX,
|
||||
relativeClickX = getClickLocation( event );
|
||||
|
||||
form.stop_epoch.value = offsetEpoch( relativeClickX );
|
||||
updateStartStop();
|
||||
|
||||
highLighter.style.width = ( ( diff < 2 ) ? 2 : ( diff > maxDiff ? maxDiff : diff ) ) + "px";
|
||||
}
|
||||
|
||||
function offsetEpoch( clickX ) {
|
||||
if ( clickX < 0 ) { return Math.floor( epoch_shown_start ); }
|
||||
|
||||
if ( clickX > graph_shown_width ) { return Math.floor( epoch_shown_stop ); }
|
||||
|
||||
return Math.floor( epoch_shown_start + ( clickX * eachPixelEpoch ) );
|
||||
}
|
||||
|
||||
function getClickLocation( event ) {
|
||||
return ( event.pageX - image.getBoundingClientRect().x - gutterOffsetLeft );
|
||||
}
|
||||
|
||||
function showPeriod( period ) {
|
||||
var now = new Date(),
|
||||
past = new Date();
|
||||
|
||||
switch (period) {
|
||||
case 1:
|
||||
past.setDate( past.getDate() - 1 ); break;
|
||||
case 2:
|
||||
past.setDate( past.getDate() - 7 ); break;
|
||||
case 3:
|
||||
past.setMonth( past.getMonth() - 1 ); break;
|
||||
case 4:
|
||||
past.setFullYear( past.getFullYear() - 1 ); break;
|
||||
}
|
||||
|
||||
form.start_epoch.value = Math.floor( past.getTime() / 1000 );
|
||||
form.stop_epoch.value = Math.floor( now.getTime() / 1000 );
|
||||
|
||||
updateStartStop();
|
||||
refreshImg();
|
||||
document.activeElement.blur();
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
<TMPL_INCLUDE NAME="partial/head.tmpl" />
|
||||
|
||||
<h2 class="mb-3">Comparison: by day</h2>
|
||||
|
||||
<TMPL_INCLUDE NAME="partial/compare_navigation.tmpl" />
|
||||
|
||||
<!--
|
||||
File: munin-comparison-day.tmpl
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
<TMPL_INCLUDE NAME="partial/head.tmpl" />
|
||||
|
||||
<h2 class="mb-3">Comparison: by month</h2>
|
||||
|
||||
<TMPL_INCLUDE NAME="partial/compare_navigation.tmpl" />
|
||||
|
||||
<!--
|
||||
File: munin-comparison-monthy.tmpl
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
<TMPL_INCLUDE NAME="partial/head.tmpl" />
|
||||
|
||||
<h2 class="mb-3">Comparison: by week</h2>
|
||||
|
||||
<TMPL_INCLUDE NAME="partial/compare_navigation.tmpl" />
|
||||
|
||||
<!--
|
||||
File: munin-comparison-week.tmpl
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
<TMPL_INCLUDE NAME="partial/head.tmpl" />
|
||||
|
||||
<h2 class="mb-3">Comparison: by year</h2>
|
||||
|
||||
<TMPL_INCLUDE NAME="partial/compare_navigation.tmpl" />
|
||||
|
||||
<!--
|
||||
File: munin-comparison-year.tmpl
|
||||
|
|
@ -7,20 +7,20 @@
|
|||
-->
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.custom-collapse').on('click', function() {
|
||||
$(this).parent().find('.collapse').collapse('toggle');
|
||||
$( document ).ready( function() {
|
||||
$( ".custom-collapse" ).on( "click", function() {
|
||||
$( this ).parent().find( ".collapse" ).collapse( "toggle" );
|
||||
return false;
|
||||
});
|
||||
$('.custom-collapse-all').on('click', function() {
|
||||
if ( $(this).hasClass('all-hide') ) {
|
||||
$(this).parent().parent().find('.collapse').collapse('hide');
|
||||
} );
|
||||
$( ".custom-collapse-all" ).on( "click", function() {
|
||||
if ( $( this ).hasClass( "all-hide" ) ) {
|
||||
$( this ).parent().parent().find( ".collapse" ).collapse( "hide" );
|
||||
} else {
|
||||
$(this).parent().parent().find('.collapse').collapse('show');
|
||||
$( this ).parent().parent().find( ".collapse" ).collapse( "show" );
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
</script>
|
||||
|
||||
<div class="btn-group w-100 mb-3">
|
|
@ -13,84 +13,77 @@
|
|||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function (){
|
||||
$( document ).ready( function () {
|
||||
// Should we auto-scroll when a service category is opened?
|
||||
window.doScroll = false;
|
||||
// Store display status of graph periods
|
||||
window.gsets = {
|
||||
window.gsets = {
|
||||
"day" : true,
|
||||
"week" : true,
|
||||
"month" : false,
|
||||
"year" : false
|
||||
};
|
||||
|
||||
$('.graph-click').on('click', function(){
|
||||
$( ".graph-click" ).on( "click", function() {
|
||||
// This shows / hides graph periods.
|
||||
var gset = $(this).data("gset");
|
||||
var newState = ! gsets[gset];
|
||||
gsets[gset] = newState;
|
||||
$(this)
|
||||
.toggleClass("btn-outline-success btn-outline-secondary")
|
||||
.find(".gset-state")
|
||||
.text((newState ? "Shown" : "Hidden"));
|
||||
$('.graph-' + gset).toggleClass("d-none");
|
||||
return false;
|
||||
});
|
||||
$('.tab-click').on('click', function() {
|
||||
window.doScroll = true; // Do scroll when we click a tab header
|
||||
var theCollapse = '#' + $(this).data("target") + "_coll";
|
||||
var gset = $( this ).data( "gset" ),
|
||||
newState = ! gsets[ gset ];
|
||||
|
||||
if ( $(theCollapse).hasClass('show') ) {
|
||||
gsets[ gset ] = newState;
|
||||
|
||||
$(this)
|
||||
.toggleClass( "btn-outline-success btn-outline-secondary" )
|
||||
.find( ".gset-state" )
|
||||
.text( ( newState ? "Shown" : "Hidden" ) );
|
||||
|
||||
$( ".graph-" + gset ).toggleClass( "d-none" );
|
||||
|
||||
return false;
|
||||
} );
|
||||
|
||||
$( ".tab-click" ).on( "click", function() {
|
||||
var theCollapse = $( "#" + $( this ).data( "target" ) + "_coll" );
|
||||
|
||||
window.doScroll = true; // Do scroll when we click a tab header
|
||||
|
||||
if ( theCollapse.hasClass( "show" ) ) {
|
||||
// Already open, lets just trigger the event.
|
||||
$(theCollapse).trigger('shown.bs.collapse');
|
||||
theCollapse.trigger( "shown.bs.collapse" );
|
||||
} else {
|
||||
// Close all
|
||||
$(".card-collapse.collapse").collapse("hide");
|
||||
// Open the one we want
|
||||
$(theCollapse).collapse('show');
|
||||
// Close all and open the one we want
|
||||
$( ".card-collapse.collapse" ).collapse( "hide" );
|
||||
theCollapse.collapse( "show" );
|
||||
}
|
||||
// Do nothing with the click otherwise.
|
||||
return false;
|
||||
});
|
||||
} );
|
||||
|
||||
// Actual scroll function
|
||||
$('.collapse').on('shown.bs.collapse', function(e) {
|
||||
$( ".collapse" ).on( "shown.bs.collapse", function( e ) {
|
||||
if ( window.doScroll ) {
|
||||
var $card = $(this).closest('.card');
|
||||
$('html,body').animate({
|
||||
scrollTop: $card.offset().top
|
||||
}, 500);
|
||||
$( document ).scrollTop( $( this ).closest( ".card" ).offset().top );
|
||||
window.doScroll = false;
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
|
||||
// If we came here with a hash, open that category and scroll to it.
|
||||
if ( location.hash != "" ) {
|
||||
window.doScroll = true;
|
||||
$(location.hash + "_coll" + '.collapse').collapse('show');
|
||||
$( location.hash + "_coll" + ".collapse" ).collapse( "show" );
|
||||
}
|
||||
|
||||
// Alternatively, if something changed the hash (looking at you search feature), we should
|
||||
// pretend that the user clicked on the link for that category.
|
||||
$( window ).on( 'hashchange', function( e ) {
|
||||
$( window ).on( "hashchange", function( e ) {
|
||||
var newPlace = window.location.hash.substr(1);;
|
||||
$(".tab-click[data-target='" + newPlace + "']").trigger("click");
|
||||
$( ".tab-click[data-target='" + newPlace + "']" ).trigger( "click" );
|
||||
} );
|
||||
|
||||
// If there is only one service group, show it by default.
|
||||
if ( $(".card-collapse.collapse").length < 2 ) {
|
||||
$(".card-collapse.collapse").collapse('show');
|
||||
}
|
||||
if ( $( ".card-collapse.collapse" ).length < 2 ) { $( ".card-collapse.collapse" ).collapse( "show" ); }
|
||||
|
||||
$(".close-all-tabs").on("click", function(){
|
||||
$('.card-collapse.collapse').collapse('hide');
|
||||
return false;
|
||||
});
|
||||
$(".open-all-tabs").on("click", function() {
|
||||
$('.card-collapse.collapse').collapse('show');
|
||||
return false;
|
||||
});
|
||||
$( ".close-all-tabs" ).on( "click", function() { $( ".card-collapse.collapse" ).collapse( "hide" ); return false; } );
|
||||
$( ".open-all-tabs" ).on( "click", function() { $( ".card-collapse.collapse" ).collapse( "show" ); return false; } );
|
||||
});
|
||||
</script>
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<!-- <TMPL_VAR NAME="ZOOMDAY"> -->
|
||||
<img data-href="<TMPL_VAR NAME='ZOOMDAY' />" src="<TMPL_VAR NAME='IMGDAY' />"
|
||||
alt="daily graph"
|
||||
class="img-fluid img-zoom i<TMPL_IF NAME='STATE_WARNING'> warn</TMPL_IF><TMPL_IF NAME='STATE_CRITICAL'> crit</TMPL_IF>"
|
||||
|
@ -109,62 +110,63 @@
|
|||
</TMPL_LOOP>
|
||||
|
||||
<div id="zoom" class="modal fade">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<img alt="Zoom Image - Requires munin-cgi-graph" id="zoom_image" class="img-fluid"/>
|
||||
<img alt="Zoom Image - Requires munin-cgi-graph" id="zoom_image" class="no-refresh d-block mx-auto"/>
|
||||
<div id="image-overlay" style="position: absolute; top: 33px; left: 0; background-color: rgba(3, 50, 109, 0.3); width: 2px; height: 400px; display:none; pointer-events: none;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-12">
|
||||
<form class="form-horizontal" role="form" name="zoom_form" id="zoom_form">
|
||||
<div class="form-group row">
|
||||
<label for="plugin_name" class="col-sm-2 control-label">Plugin Name</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" name="plugin_name" id="plugin_name">
|
||||
<input type="text" class="form-control form-control-sm" name="plugin_name" id="plugin_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="start_iso8601" class="col-sm-2 control-label">Time Start/Stop</label>
|
||||
<div class="col-sm-5">
|
||||
<input type="text" class="form-control" name="start_iso8601" id="start_iso8601">
|
||||
<input type="text" class="form-control form-control-sm" name="start_iso8601" id="start_iso8601">
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<input type="text" class="form-control" name="stop_iso8601" id="stop_iso8601">
|
||||
<input type="text" class="form-control form-control-sm" name="stop_iso8601" id="stop_iso8601">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="start_epoch" class="col-sm-2 control-label">Epoch Start/Stop</label>
|
||||
<div class="col-sm-5">
|
||||
<input type="text" class="form-control" name="start_epoch" id="start_epoch">
|
||||
<input type="text" class="form-control form-control-sm" name="start_epoch" id="start_epoch">
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<input type="text" class="form-control" name="stop_epoch" id="stop_epoch">
|
||||
<input type="text" class="form-control form-control-sm" name="stop_epoch" id="stop_epoch">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="lower_limit" class="col-sm-2 control-label">Limit Low/High</label>
|
||||
<div class="col-sm-5">
|
||||
<input type="text" class="form-control" name="lower_limit" id="lower_limit">
|
||||
<input type="text" class="form-control form-control-sm" name="lower_limit" id="lower_limit">
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<input type="text" class="form-control" name="upper_limit" id="upper_limit">
|
||||
<input type="text" class="form-control form-control-sm" name="upper_limit" id="upper_limit">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="size_x" class="col-sm-2 control-label">Width/Height</label>
|
||||
<div class="col-sm-5">
|
||||
<div class="input-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control" name="size_x" id="size_x">
|
||||
<span class="input-group-append"><span class="input-group-text">px</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="input-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control" name="size_y" id="size_y">
|
||||
<span class="input-group-append"><span class="input-group-text">px</span></span>
|
||||
</div>
|
||||
|
@ -173,10 +175,17 @@
|
|||
<div class="form-group row">
|
||||
<input type=hidden name="cgiurl_graph"/>
|
||||
<div class="btn-group w-100 mx-3">
|
||||
<button type="submit" class="btn btn-outline-success">Refresh</button>
|
||||
<button type="button" class="btn btn-outline-primary" name="btnReset">Reset</button>
|
||||
<button type="button" class="btn btn-outline-primary" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-outline-primary" name="btnReset">↺ Reset to Initial</button>
|
||||
<button type="button" class="btn btn-outline-info" name="btnShowDay">⏱ Show Today</button>
|
||||
<button type="button" class="btn btn-outline-info" name="btnShowWeek">⏱ Show Week</button>
|
||||
<button type="button" class="btn btn-outline-info" name="btnShowMonth">⏱ Show Month</button>
|
||||
<button type="button" class="btn btn-outline-info" name="btnShowYear">⏱ Show Year</button>
|
||||
</div>
|
||||
<div class="btn-group w-100 mx-3 mt-2">
|
||||
<button type="button" class="btn btn-outline-danger w-100" data-dismiss="modal">× Close</button>
|
||||
</div>
|
||||
<button type="submit" class="d-none">Hidden Submit Button - "onsubmit" needs this to exist.</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -185,13 +194,14 @@
|
|||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-info">
|
||||
<p>Zooming is very easy, it's done in 3 clicks (regular clicks, no drag&drop):</p>
|
||||
<p>Zooming is very easy, it's done in 3 clicks ( regular clicks, no drag & drop ):</p>
|
||||
<ol>
|
||||
<li>Click to define the start of zoom.</li>
|
||||
<li>Click to define the ending of zoom.</li>
|
||||
<li>Refresh.</li>
|
||||
<li>Click inside shaded area to zoom, outside to cancel.</li>
|
||||
</ol>
|
||||
<p>You can use the interactive form too.</p>
|
||||
<p><em>Shortcut:</em> To just set a new start of zoom, click before your start point for your second click.</p>
|
||||
<p class="mb-1">You can use the interactive form too.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -202,36 +212,18 @@
|
|||
|
||||
<TMPL_INCLUDE NAME="partial/footer_pre.tmpl" />
|
||||
|
||||
<script src="<TMPL_VAR NAME='R_PATH'>/static/js/formatdate.min.js"></script>
|
||||
<script src="<TMPL_VAR NAME='R_PATH'>/static/js/querystring.min.js"></script>
|
||||
<script src="<TMPL_VAR NAME='R_PATH'>/static/js/dynazoom.min.js"></script>
|
||||
|
||||
<script src="<TMPL_VAR NAME='R_PATH'>/static/js/dynazoom.js"></script>
|
||||
<script type="text/javascript">
|
||||
//Zoom modal opening
|
||||
$('.img-zoom').click(function(){
|
||||
var query = $(this).attr('data-href');
|
||||
var form = document.getElementById("zoom_form");
|
||||
var image = document.getElementById("zoom_image");
|
||||
|
||||
form.onsubmit = function(){//Submit catching
|
||||
var qs = new Querystring(query);
|
||||
var src = "cgiurl_graph=" + qs.get("cgiurl_graph", "/munin-cgi/munin-cgi-graph")
|
||||
+ "&plugin_name=" + form.plugin_name.value
|
||||
+ "&start_epoch=" + form.start_epoch.value
|
||||
+ "&stop_epoch=" + form.stop_epoch.value
|
||||
+ "&rst_start_epoch=" + qs.get("start_epoch", "")
|
||||
+ "&rst_stop_epoch=" + qs.get("stop_epoch", "")
|
||||
+ "&lower_limit=" + form.lower_limit.value
|
||||
+ "&upper_limit=" + form.upper_limit.value
|
||||
+ "&size_x=" + form.size_x.value
|
||||
+ "&size_y=" + form.size_y.value
|
||||
;
|
||||
refreshZoom(src, form, image);
|
||||
return false;
|
||||
};
|
||||
$( ".img-zoom" ).click(function(){
|
||||
var query = $(this).attr( "data-href" );
|
||||
var form = document.getElementById( "zoom_form" );
|
||||
var image = document.getElementById( "zoom_image" );
|
||||
|
||||
refreshZoom(query, form, image);
|
||||
$('#zoom').modal('show');
|
||||
$( "#zoom" ).modal( "show" );
|
||||
});
|
||||
</script>
|
||||
|
||||
<TMPL_INCLUDE NAME="partial/footer.tmpl" />
|
||||
<TMPL_INCLUDE NAME="partial/footer.tmpl" />
|
|
@ -5,52 +5,40 @@
|
|||
-->
|
||||
|
||||
<script>
|
||||
$(document).ready(function (){
|
||||
$( document ).ready( function (){
|
||||
// Should we auto-scroll when a service category is opened?
|
||||
window.doScroll = false;
|
||||
|
||||
$('.tab-click').on('click', function() {
|
||||
$( ".tab-click" ).on( "click", function() {
|
||||
window.doScroll = true; // Do scroll when we click a tab header
|
||||
var theCollapse = '#' + $(this).data("target") + "_coll";
|
||||
var theCollapse = $( "#" + $( this ).data( "target" ) + "_coll" );
|
||||
|
||||
if ( $(theCollapse).hasClass('show') ) {
|
||||
if ( theCollapse.hasClass( "show" ) ) {
|
||||
// Already open, lets just trigger the event.
|
||||
$(theCollapse).trigger('shown.bs.collapse');
|
||||
theCollapse.trigger( "shown.bs.collapse" );
|
||||
} else {
|
||||
// Close all
|
||||
$(".card-collapse.collapse").collapse("hide");
|
||||
// Open the one we want
|
||||
$(theCollapse).collapse('show');
|
||||
// Close all, and open the one we want
|
||||
$( ".card-collapse.collapse" ).collapse("hide" );
|
||||
theCollapse.collapse( "show" );
|
||||
}
|
||||
// Do nothing with the click otherwise.
|
||||
return false;
|
||||
});
|
||||
|
||||
// Actual scroll function
|
||||
$('.collapse').on('shown.bs.collapse', function(e) {
|
||||
$( ".collapse" ).on( "shown.bs.collapse", function( e ) {
|
||||
if ( window.doScroll ) {
|
||||
var $card = $(this).closest('.card');
|
||||
$('html,body').animate({
|
||||
scrollTop: $card.offset().top
|
||||
}, 500);
|
||||
$( document ).scrollTop( $( this ).closest( ".card" ).offset().top );
|
||||
window.doScroll = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// If there is only one service group, show it by default.
|
||||
if ( $(".card-collapse.collapse").length < 2 ) {
|
||||
$(".card-collapse.collapse").collapse('show');
|
||||
}
|
||||
if ( $( ".card-collapse.collapse" ).length < 2 ) { $( ".card-collapse.collapse" ).collapse( "show" ); }
|
||||
|
||||
$(".close-all-tabs").on("click", function(){
|
||||
$('.card-collapse.collapse').collapse('hide');
|
||||
return false;
|
||||
});
|
||||
$(".open-all-tabs").on("click", function() {
|
||||
$('.card-collapse.collapse').collapse('show');
|
||||
return false;
|
||||
});
|
||||
$( ".close-all-tabs" ).on( "click", function() { $( ".card-collapse.collapse" ).collapse( "hide" ); return false; } );
|
||||
$( ".open-all-tabs" ).on( "click", function() { $( ".card-collapse.collapse" ).collapse( "show" ); return false; } );
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!--
|
||||
File: partial/footer.tmpl
|
||||
|
||||
Used: All views, called after partial/footer.tmpl
|
||||
-->
|
||||
<script>
|
||||
// Lightweight Cookie Library.
|
||||
!function(e){var n;if("function"==typeof define&&define.amd&&(define(e),n=!0),"object"==typeof exports&&(module.exports=e(),n=!0),!n){var t=window.Cookies,o=window.Cookies=e();o.noConflict=function(){return window.Cookies=t,o}}}(function(){function e(){for(var e=0,n={};e<arguments.length;e++){var t=arguments[e];for(var o in t)n[o]=t[o]}return n}function n(e){return e.replace(/(%[0-9A-Z]{2})+/g,decodeURIComponent)}return function t(o){function r(){}function i(n,t,i){if("undefined"!=typeof document){"number"==typeof(i=e({path:"/"},r.defaults,i)).expires&&(i.expires=new Date(1*new Date+864e5*i.expires)),i.expires=i.expires?i.expires.toUTCString():"";try{var c=JSON.stringify(t);/^[\{\[]/.test(c)&&(t=c)}catch(e){}t=o.write?o.write(t,n):encodeURIComponent(String(t)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),n=encodeURIComponent(String(n)).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent).replace(/[\(\)]/g,escape);var f="";for(var u in i)i[u]&&(f+="; "+u,!0!==i[u]&&(f+="="+i[u].split(";")[0]));return document.cookie=n+"="+t+f}}function c(e,t){if("undefined"!=typeof document){for(var r={},i=document.cookie?document.cookie.split("; "):[],c=0;c<i.length;c++){var f=i[c].split("="),u=f.slice(1).join("=");t||'"'!==u.charAt(0)||(u=u.slice(1,-1));try{var a=n(f[0]);if(u=(o.read||o)(u,a)||n(u),t)try{u=JSON.parse(u)}catch(e){}if(r[a]=u,e===a)break}catch(e){}}return e?r[e]:r}}return r.set=i,r.get=function(e){return c(e,!1)},r.getJSON=function(e){return c(e,!0)},r.remove=function(n,t){i(n,"",e(t,{expires:-1}))},r.defaults={},r.withConverter=t,r}(function(){})});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -10,9 +10,10 @@
|
|||
<span class="text-muted"><small>
|
||||
This page was generated by <a href="http://www.munin-monitoring.org/">Munin</a>
|
||||
version <TMPL_VAR NAME="MUNIN_VERSION"> at <TMPL_VAR NAME="TIMESTAMP">
|
||||
with <a href="https://github.com/munin-monitoring/contrib/tree/master/templates/munstrap4/">MunStrap4</a> template.
|
||||
with <a href="https://github.com/munin-monitoring/contrib/tree/master/templates/muncollapse/">MunCollapse</a> template.
|
||||
</small></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
<script src="<TMPL_VAR NAME='R_PATH' />/static/js/lazysizes.min.js" async></script>
|
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<!--
|
||||
File: partial/head.tmpl
|
||||
|
||||
Used: All views, called before anything else
|
||||
-->
|
||||
|
||||
<head>
|
||||
<title>
|
||||
<TMPL_IF NAME="NAME"><TMPL_VAR ESCAPE="HTML" NAME="NAME"> (</TMPL_IF>Munin<TMPL_LOOP NAME="PATH"><TMPL_IF NAME="pathname"> :: <TMPL_VAR ESCAPE="HTML" NAME="pathname"></TMPL_IF></TMPL_LOOP><TMPL_IF NAME="NAME">)</TMPL_IF>
|
||||
</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="Auto-generated by Munin">
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/favicon-194x194.png" sizes="194x194">
|
||||
<link rel="icon" type="image/png" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/manifest.json" crossorigin="use-credentials">
|
||||
<link rel="shortcut icon" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/favicon.ico">
|
||||
<meta name="msapplication-TileColor" content="#00a300">
|
||||
<meta name="msapplication-TileImage" content="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="<TMPL_VAR NAME='R_PATH' />/static/img/favicon/browserconfig.xml">
|
||||
<meta name="theme-color" content="#076202">
|
||||
|
||||
<link href="<TMPL_VAR NAME='R_PATH' />/static/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="<TMPL_VAR NAME='R_PATH' />/static/css/style-munstrap.css" rel="stylesheet" />
|
||||
|
||||
<script src="<TMPL_VAR NAME='R_PATH' />/static/js/jquery.min.js"></script>
|
||||
<script src="<TMPL_VAR NAME='R_PATH' />/static/js/bootstrap.min.js"></script>
|
||||
<script src="<TMPL_VAR NAME='R_PATH' />/static/js/typeahead.bundle.min.js"></script>
|
||||
|
||||
<TMPL_INCLUDE NAME="search_and_reload.tmpl">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-3">
|
||||
<a class="navbar-brand" href="<TMPL_VAR NAME='R_PATH' />"><span class="munin-icon"></span></a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<TMPL_VAR NAME='R_PATH' />">Home</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarProblems" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Problems
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarProblems">
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/problems.html#critical"><span class="badge alert-danger mr-2"><TMPL_VAR NAME="NCRITICAL"></span>Critical</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/problems.html#warnings"><span class="badge alert-warning mr-2"><TMPL_VAR NAME="NWARNING"></span>Warning</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/problems.html#unknowns"><span class="badge alert-info mr-2"><TMPL_VAR NAME="NUNKNOWN"></span>Unknown</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarGroups" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Groups
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarGroups">
|
||||
<TMPL_LOOP NAME="ROOTGROUPS">
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL'>"><TMPL_VAR NAME="NAME"></a>
|
||||
</TMPL_LOOP>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarHosts" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Hosts
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarHosts">
|
||||
<TMPL_LOOP NAME="ROOTGROUPS">
|
||||
<TMPL_LOOP NAME="GROUPS">
|
||||
<TMPL_IF NAME="NCATEGORIES">
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL'>"><TMPL_VAR ESCAPE="HTML" NAME="NAME"></a>
|
||||
</TMPL_IF>
|
||||
</TMPL_LOOP>
|
||||
</TMPL_LOOP>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarCats" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Categories
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarCats">
|
||||
<TMPL_LOOP NAME="GLOBALCATS">
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLDAY'>"><TMPL_VAR NAME="NAME"> - Day</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLWEEK'>"><TMPL_VAR NAME="NAME"> - Week</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLMONTH'>"><TMPL_VAR NAME="NAME"> - Month</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLYEAR'>"><TMPL_VAR NAME="NAME"> - Year</a>
|
||||
<TMPL_IF NAME="__first__"><div class="dropdown-divider"></div></TMPL_IF>
|
||||
<TMPL_IF NAME="__inner__"><div class="dropdown-divider"></div></TMPL_IF>
|
||||
</TMPL_LOOP>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<form id="formy1" class="form-inline my-2 my-lg-0 w-25">
|
||||
<input class="form-control mr-sm-2 w-100" type="text" id="findthehost" placeholder="Host or Service" aria-label="Search">
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<TMPL_INCLUDE NAME="logo_navigation.tmpl">
|
||||
|
|
@ -4,25 +4,6 @@
|
|||
Used: All views, called after from head.
|
||||
-->
|
||||
|
||||
<!-- TEST DATA :: BEGIN -->
|
||||
<!-- a/n: IF THE NAVIGATION LOOKS WIERD, PLEASE INCLUDE THIS INFO WHEN ASKING FOR HELP FIXING. -->
|
||||
<TMPL_IF NAME="PATH"><TMPL_LOOP NAME="PATH">
|
||||
<!-- PATH <TMPL_VAR NAME="PATHNAME"> -->
|
||||
</TMPL_LOOP>
|
||||
<TMPL_ELSE>
|
||||
<!-- SHIT -->
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="CATEGORY" >
|
||||
<!-- CAT: <TMPL_VAR ESCAPE="HTML" NAME="CATEGORY" /> -->
|
||||
</TMPL_IF>
|
||||
<TMPL_IF NAME="NAME">
|
||||
<!-- NAME <TMPL_VAR ESCAPE="HTML" NAME="NAME"> -->
|
||||
<TMPL_ELSE>
|
||||
<!-- NO NAME -->
|
||||
</TMPL_IF>
|
||||
<!-- TEST DATA :: END -->
|
||||
|
||||
<TMPL_IF NAME="PATH">
|
||||
<nav aria-label="breadcrumb pt1">
|
||||
<ol class="breadcrumb">
|
||||
|
@ -43,6 +24,10 @@
|
|||
</TMPL_IF>
|
||||
</li>
|
||||
</TMPL_LOOP>
|
||||
<div class="custom-control custom-switch ml-auto mr-0">
|
||||
<input type="checkbox" class="custom-control-input" id="autorefimg">
|
||||
<label class="custom-control-label" for="autorefimg">Auto-refresh Images</label>
|
||||
</div>
|
||||
</ol>
|
||||
</nav>
|
||||
<TMPL_ELSE>
|
||||
|
@ -50,7 +35,7 @@
|
|||
<ol class="breadcrumb">
|
||||
<TMPL_IF NAME="NAME">
|
||||
<!-- 2.0.37 - Shouldn't get hit with new HTML generator -->
|
||||
<li class="breadcrumb-item"><a href="<TMPL_VAR NAME='R_PATH'>">Home</a></li>
|
||||
<li class="breadcrumb-item"><a href="<TMPL_VAR NAME='R_PATH' />">Home</a></li>
|
||||
<li class="breadcrumb-item"><TMPL_VAR NAME="NAME" /></li>
|
||||
<TMPL_ELSE>
|
||||
<li class="breadcrumb-item">Home</li>
|
||||
|
@ -60,5 +45,25 @@
|
|||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="PEERS">
|
||||
<TMPL_INCLUDE NAME="bottom_navigation.tmpl">
|
||||
<TMPL_INCLUDE NAME="bottom_navigation.tmpl" />
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="COMPARISON-DAY">
|
||||
<h2 class="mb-3">Comparison: by day</h2>
|
||||
<TMPL_INCLUDE NAME="compare_navigation.tmpl" />
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="COMPARISON-WEEK">
|
||||
<h2 class="mb-3">Comparison: by week</h2>
|
||||
<TMPL_INCLUDE NAME="compare_navigation.tmpl" />
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="COMPARISON-MONTH">
|
||||
<h2 class="mb-3">Comparison: by month</h2>
|
||||
<TMPL_INCLUDE NAME="compare_navigation.tmpl" />
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="COMPARISON-YEAR">
|
||||
<h2 class="mb-3">Comparison: by year</h2>
|
||||
<TMPL_INCLUDE NAME="compare_navigation.tmpl" />
|
||||
</TMPL_IF>
|
|
@ -0,0 +1,160 @@
|
|||
|
||||
<!--
|
||||
File: partial/search_and_reload.tmpl
|
||||
|
||||
Used: All views, generates the search functionality, and the auto-reload stuff.
|
||||
-->
|
||||
|
||||
<script>
|
||||
// $('img').each(function(){ if (this.src.length > 0) {
|
||||
// console.log(this.src);
|
||||
// } });
|
||||
|
||||
|
||||
|
||||
// This is used to build the navigation quick search - there is no backend, so we have to do
|
||||
// it all client side.
|
||||
//
|
||||
// As a curious side note, commenting out the template loops and whatnot allows vscode to parse
|
||||
// the javascript - so please note that the commented out TMPL directives STILL FUNCTION.
|
||||
var gen_basegroups = {
|
||||
// <TMPL_LOOP NAME="ROOTGROUPS">
|
||||
"<TMPL_VAR NAME='NAME' />" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL'>",
|
||||
"compare" : {
|
||||
// <TMPL_IF NAME="COMPARE">
|
||||
"Day" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_LOOP NAME='PATH' /><TMPL_IF NAME='pathname'><TMPL_VAR ESCAPE='URL' NAME='PATHNAME' />/</TMPL_IF></TMPL_LOOP>comparison-day.html",
|
||||
"Week" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_LOOP NAME='PATH' /><TMPL_IF NAME='pathname'><TMPL_VAR ESCAPE='URL' NAME='PATHNAME' />/</TMPL_IF></TMPL_LOOP>comparison-week.html",
|
||||
"Month" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_LOOP NAME='PATH' /><TMPL_IF NAME='pathname'><TMPL_VAR ESCAPE='URL' NAME='PATHNAME' />/</TMPL_IF></TMPL_LOOP>comparison-month.html",
|
||||
"Year" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_LOOP NAME='PATH' /><TMPL_IF NAME='pathname'><TMPL_VAR ESCAPE='URL' NAME='PATHNAME' />/</TMPL_IF></TMPL_LOOP>comparison-year.html"
|
||||
// </TMPL_IF>
|
||||
}
|
||||
},
|
||||
// </TMPL_LOOP>
|
||||
};
|
||||
var gen_hosts = {
|
||||
// <TMPL_LOOP NAME="ROOTGROUPS">
|
||||
// <TMPL_LOOP NAME="GROUPS">
|
||||
// <TMPL_IF NAME="NCATEGORIES">
|
||||
"<TMPL_VAR ESCAPE='HTML' NAME='NAME' />" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL'>",
|
||||
"services" : {
|
||||
// <TMPL_LOOP NAME="CATEGORIES">
|
||||
"<TMPL_VAR ESCAPE='HTML' NAME='NAME' />" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL' />",
|
||||
// </TMPL_LOOP>
|
||||
}
|
||||
},
|
||||
// </TMPL_IF>
|
||||
// </TMPL_LOOP>
|
||||
// </TMPL_LOOP>
|
||||
};
|
||||
var gen_cats = {
|
||||
// <TMPL_LOOP NAME="GLOBALCATS">
|
||||
"Category :: <TMPL_VAR NAME='NAME'> :: Day" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLDAY'>"
|
||||
},
|
||||
"Category :: <TMPL_VAR NAME='NAME'> :: Week" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLWEEK'>"
|
||||
},
|
||||
"Category :: <TMPL_VAR NAME='NAME'> :: Month" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLMONTH'>"
|
||||
},
|
||||
"Category :: <TMPL_VAR NAME='NAME'> :: Year" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLYEAR'>"
|
||||
},
|
||||
// </TMPL_LOOP>
|
||||
};
|
||||
|
||||
function absolute(p,o){var t=p.split("/"),n=o.split("/");t.pop();for(var r=0;r<n.length;r++)"."!=n[r]&&(".."==n[r]?t.pop():t.push(n[r]));return t.join("/")}
|
||||
|
||||
var navMap = [];
|
||||
|
||||
$.each( gen_cats, function( name, obby ) {
|
||||
navMap.push( { "name" : name, "link" : absolute( location.href, obby.baseurl ) } );
|
||||
});
|
||||
|
||||
$.each( gen_hosts, function( name, obby ) {
|
||||
var host_name = name;
|
||||
navMap.push( { "name" : "Host :: " + name, "link" : absolute( location.href, obby.baseurl ) } );
|
||||
$.each( obby.services, function( svcname, url ) {
|
||||
navMap.push( { "name" : "Service :: " + host_name + " :: " + svcname, "link" : absolute( location.href, url ) } );
|
||||
});
|
||||
});
|
||||
|
||||
$.each( gen_basegroups, function( name, obby ) {
|
||||
var host_name = name;
|
||||
navMap.push( { "name" : "Host :: " + name, "link" : absolute( location.href, obby.baseurl ) } );
|
||||
$.each( obby.compare, function( svcname, url ) {
|
||||
navMap.push( { "name" : "Compare :: " + host_name + " :: " + svcname, "link" : absolute(location.href, url) } );
|
||||
});
|
||||
});
|
||||
|
||||
var navMapB = new Bloodhound({
|
||||
datumTokenizer: function ( d ) { return Bloodhound.tokenizers.whitespace( d.name ); },
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
identify: function ( obj ) { return obj.link; },
|
||||
local: navMap
|
||||
});
|
||||
|
||||
$(document).ready(function(){
|
||||
$( "#findthehost" ).typeahead({
|
||||
hint : true,
|
||||
highlight : true,
|
||||
minLength : 2,
|
||||
},
|
||||
{
|
||||
name : "navMap",
|
||||
limit : 10,
|
||||
display : "link",
|
||||
source : navMapB,
|
||||
templates : {
|
||||
suggestion : function ( data ) {
|
||||
return "<div>" + data.name + "</div>";
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$( "#findthehost" ).on( "typeahead:select", function() { $( "#formy1" ).submit(); } );
|
||||
|
||||
$( "#formy1" ).on( "submit", function() {
|
||||
inputVal = $( "#findthehost" ).val();
|
||||
|
||||
if ( inputVal.substring( 0, 4 ) == "http" ) {
|
||||
window.location.href = inputVal;
|
||||
} else {
|
||||
$( "#findthehost" ).typeahead( "val", "" );
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
function autoRefImages() {
|
||||
$( "img" ).each(function () {
|
||||
if ( this.src.length > 0 && (! $( this ).hasClass( "no-refresh" )) ) {
|
||||
var thisURL = new URL( this.src );
|
||||
thisURL.searchParams.set( "tt", new Date().getTime() );
|
||||
this.src = thisURL.href;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$( document ).ready( function() {
|
||||
if ( Cookies.get( "autorefreshimg" ) == 0 ) {
|
||||
$( "#autorefimg" ).prop( "checked", false );
|
||||
} else {
|
||||
$( "#autorefimg" ).prop( "checked", true);
|
||||
Cookies.set("autorefreshimg", "1", { expires: 60 });
|
||||
window.autoreftimeout = setInterval( autoRefImages, 300000 );
|
||||
}
|
||||
|
||||
$( "#autorefimg" ).on( "change", function() {
|
||||
Cookies.set( "autorefreshimg", "0", { expires: 60 } )
|
||||
clearInterval( window.autoreftimeout );
|
||||
if ( $( "#autorefimg" ).is( ":checked" ) ) {
|
||||
Cookies.set( "autorefreshimg", "1", { expires: 60 } );
|
||||
window.autoreftimeout = setInterval( autoRefImages, 300000 );
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
|
@ -1,114 +0,0 @@
|
|||
# Munstrap4
|
||||
|
||||
Alternative Munin 2.x templates based on Twitter Bootstrap 4.
|
||||
|
||||
Based on "Munstrap" by [Jonny McCullagh](https://github.com/jonnymccullagh), [munin-monitoring/contrib](https://github.com/munin-monitoring/contrib/tree/master/templates/munstrap) repo.
|
||||
|
||||
#### Overview Sample Image
|
||||
<a href="https://jtsage.dev/munstrap4/sample-home.png"><img src="https://jtsage.dev/munstrap4/sample-home.png" style="max-width: 1229px; display:block; margin-left: auto; margin-right: auto; width: 75%" /></a>
|
||||
|
||||
|
||||
#### [Semi-Live Demo](https://jtsage.dev/munin-demo/)
|
||||
Zoom functionality for this demo has been disabled, and the data will never update, but it's a decent visual reference.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Clone the munin-monitoring/contrib repo to a temporary location:
|
||||
|
||||
```
|
||||
$ cd /opt
|
||||
$ git clone https://github.com/munin-monitoring/contrib.git
|
||||
```
|
||||
|
||||
### 2. Place the template in an appropriate safe place
|
||||
|
||||
Ubuntu shown - other distros may prefer ```/usr/local/share/munin/...```
|
||||
|
||||
```
|
||||
$ mkdir /usr/share/munin/template
|
||||
$ mkdir /usr/share/munin/template/munstrap4
|
||||
```
|
||||
__NOTE__: If this step fails, your munin installation may use ```/usr/local/share/munin/...``` instead!
|
||||
|
||||
```
|
||||
$ cp -r /opt/contrib/templates/munstrap4/templates /usr/share/munin/template/munstrap4/
|
||||
$ cp -r /opt/contrib/templates/munstrap4/static /usr/share/munin/template/munstrap4/
|
||||
```
|
||||
|
||||
### 3. Edit your ```munin.conf``` file.
|
||||
|
||||
Typically located at ```/etc/munin.conf```
|
||||
|
||||
__FIND AND CHANGE:__ (near the top of the file)
|
||||
|
||||
```
|
||||
# Where to look for the HTML templates
|
||||
#
|
||||
#tmpldir /etc/munin/templates
|
||||
|
||||
# Where to look for the static www files
|
||||
#
|
||||
#staticdir /etc/munin/static
|
||||
```
|
||||
|
||||
__TO:__
|
||||
```
|
||||
# Where to look for the HTML templates
|
||||
#
|
||||
tmpldir /usr/share/munin/template/munstrap4/templates
|
||||
|
||||
# Where to look for the static www files
|
||||
#
|
||||
staticdir /usr/share/munin/template/munstrap4/static
|
||||
```
|
||||
|
||||
### 4. [Optional / Recommended] Clean out the old generated files.
|
||||
|
||||
This isn't really required, and is totally not nessesary if you are using `munin-httpd`. The location of these files can be found in your ```munin.conf``` file, with the ```htmldir``` directive.
|
||||
|
||||
__NOTE:__ Ubuntu shown, other distributions may be in ```/var/www/munin/```
|
||||
|
||||
```
|
||||
$ rm -rf /var/cache/munin/www/*
|
||||
```
|
||||
|
||||
### 5. Wait Patiently
|
||||
|
||||
```munin-update``` will regenerate the files the next time it runs. By default, this is on the :05 minute tick for most installations. If you do not have new files within 10 minutes, be sure to check ```munin-update.log``` and find out what went wrong.
|
||||
|
||||
---
|
||||
|
||||
## Revert to Official Munin Template
|
||||
|
||||
### 1. Edit your ```munin.conf``` file.
|
||||
|
||||
Typically located at ```/etc/munin.conf```
|
||||
|
||||
__FIND AND CHANGE:__ (near the top of the file - comment these lines out!)
|
||||
|
||||
### 2. [Optional / Recommended] Clean up
|
||||
|
||||
Remove the files from step #1 & #2 above, and repeat step #4 & #5.
|
||||
|
||||
---
|
||||
|
||||
## Samples
|
||||
|
||||
#### View of a group:
|
||||
<a href="https://jtsage.dev/munstrap4/sample-group.png"><img src="https://jtsage.dev/munstrap4/sample-group.png" style="max-width: 1229px; display:block; margin-left: auto; margin-right: auto; width: 75%" /></a>
|
||||
|
||||
#### View of a specific node:
|
||||
<a href="https://jtsage.dev/munstrap4/sample-node.png"><img src="https://jtsage.dev/munstrap4/sample-node.png" style="max-width: 1229px; display:block; margin-left: auto; margin-right: auto; width: 75%" /></a>
|
||||
|
||||
|
||||
#### Zoom feature:
|
||||
<a href="https://jtsage.dev/munstrap4/sample-zoom.png"><img src="https://jtsage.dev/munstrap4/sample-zoom.png" style="max-width: 1229px; display:block; margin-left: auto; margin-right: auto; width: 75%" /></a>
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Compatibility
|
||||
|
||||
a/n: I am unsure of the compatibility with the next major version of munin. Most things will work from what I've read, but the navigation may be slightly funky.
|
|
@ -1 +0,0 @@
|
|||
@media(min-width:992px){.modal-lg{width:940px!important}}img.i{display:block;margin:10px auto}img.img-zoom{cursor:pointer}div.service-alert{margin-top:10px}img#zoom_image{margin-bottom:15px}ul.groupview,ul.groupview ul{list-style-type:none}.munin-icon{background:url(../img/logo-munin.png) left top;margin-top:-6px;width:35px;height:35px;display:block;float:left}img{box-sizing:content-box;border:2px solid transparent}img.warn{border:2px solid #8a6d3b}img.crit{border:2px solid #a94442}img.unkn{border:2px solid #fa0}html{position:relative;min-height:100%}body{margin-bottom:75px}.footer{position:absolute;bottom:0;width:100%;height:60px;line-height:60px;background-color:#f5f5f5}.breadcrumb-item-svc::before{display:inline-block;color:#6c757d;content:"["}.breadcrumb-item-svc::after{display:inline-block;padding-right:.5rem;color:#6c757d;content:"]"}.custom-collapse{color:#6c757d;font-size:75%}.custom-collapse::before{display:inline-block;color:#6c757d;content:"["}.custom-collapse::after{display:inline-block;padding-right:.5rem;color:#6c757d;content:"]"}.custom-collapse-all{color:#6c757d;font-size:75%}.custom-collapse-all::before{display:inline-block;color:#6c757d;content:"["}.custom-collapse-all::after{display:inline-block;padding-right:.5rem;color:#6c757d;content:"]"}.cat-list::before{display:inline-block;color:#6c757d;content:"[ "}.cat-list::after{display:inline-block;color:#6c757d;content:" ]"}span.twitter-typeahead .tt-menu{cursor:pointer}span.twitter-typeahead .tt-menu{position:absolute;top:100%;left:0;width:100%;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:1rem;color:#373a3c;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.15);border-radius:.25rem;overflow:hidden}span.twitter-typeahead .tt-suggestion{display:block;width:100%;padding:3px 20px;clear:both;font-weight:normal;line-height:1.5;color:#373a3c;text-align:inherit;white-space:nowrap;background:0;border:0}span.twitter-typeahead .tt-suggestion:focus,.dropdown-item:hover,span.twitter-typeahead .tt-suggestion:hover{color:#2b2d2f;text-decoration:none;background-color:#f5f5f5}span.twitter-typeahead .active.tt-suggestion,span.twitter-typeahead .tt-suggestion.tt-cursor,span.twitter-typeahead .active.tt-suggestion:focus,span.twitter-typeahead .tt-suggestion.tt-cursor:focus,span.twitter-typeahead .active.tt-suggestion:hover,span.twitter-typeahead .tt-suggestion.tt-cursor:hover{color:#fff;text-decoration:none;background-color:#0275d8;outline:0}span.twitter-typeahead .disabled.tt-suggestion,span.twitter-typeahead .disabled.tt-suggestion:focus,span.twitter-typeahead .disabled.tt-suggestion:hover{color:#818a91}span.twitter-typeahead{width:100%}.input-group span.twitter-typeahead{display:block!important}.input-group span.twitter-typeahead .tt-menu{top:2.375rem!important}span.hangindent2{padding-left:1em}span.hangindent3{padding-left:2em}span.hangindent4{padding-left:3em}span.hangindent5{padding-left:4em}span.hangindent6{padding-left:5em}
|
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,199 +0,0 @@
|
|||
function refreshZoom(query, form, image, divOverlay) {
|
||||
//INIT
|
||||
var qs = new Querystring(query);
|
||||
init();
|
||||
|
||||
var scale = refreshImg();
|
||||
var start_epoch = (+qs.get("rst_start_epoch", form.start_epoch.value));
|
||||
var stop_epoch = (+qs.get("rst_stop_epoch", form.stop_epoch.value));
|
||||
var initial_left;
|
||||
var initial_top;
|
||||
|
||||
//form.btnMaj.onclick = majDates;
|
||||
form.plugin_name.onblur = refreshImg;
|
||||
form.start_iso8601.onblur = majDates;
|
||||
form.stop_iso8601.onblur = majDates;
|
||||
form.start_epoch.onblur = refreshImg;
|
||||
form.stop_epoch.onblur = refreshImg;
|
||||
form.lower_limit.onblur = refreshImg;
|
||||
form.upper_limit.onblur = refreshImg;
|
||||
form.size_x.onblur = refreshImg;
|
||||
form.size_y.onblur = refreshImg;
|
||||
form.btnReset.onclick = reset;
|
||||
|
||||
// Sets the onClick handler
|
||||
image.onclick = click;
|
||||
var clickCounter = 0;
|
||||
|
||||
//FUNCTIONS
|
||||
function init() {
|
||||
form.plugin_name.value = qs.get("plugin_name", "localdomain/localhost.localdomain/if_eth0");
|
||||
form.start_epoch.value = qs.get("start_epoch", "1236561663");
|
||||
form.stop_epoch.value = qs.get("stop_epoch", "1237561663");
|
||||
form.lower_limit.value = qs.get("lower_limit", "");
|
||||
form.upper_limit.value = qs.get("upper_limit", "");
|
||||
form.size_x.value = qs.get("size_x", "");
|
||||
form.size_y.value = qs.get("size_y", "");
|
||||
|
||||
updateStartStop();
|
||||
}
|
||||
|
||||
function reset(event) {
|
||||
init();
|
||||
|
||||
//Can be not the initial ones in case of manual refresh
|
||||
form.start_epoch.value = start_epoch;
|
||||
form.stop_epoch.value = stop_epoch;
|
||||
updateStartStop();
|
||||
|
||||
//Redraw
|
||||
scale = refreshImg();
|
||||
|
||||
//Reset gui
|
||||
clickCounter = 0;
|
||||
initial_left = 0;
|
||||
initial_top = 0;
|
||||
|
||||
image.onmousemove = undefined;
|
||||
form.start_iso8601.disabled = false;
|
||||
form.stop_iso8601.disabled = false;
|
||||
form.start_epoch.disabled = false;
|
||||
form.stop_epoch.disabled = false;
|
||||
}
|
||||
|
||||
function refreshImg(event) {
|
||||
image.src = qs.get("cgiurl_graph", "/munin-cgi/munin-cgi-graph") + "/"
|
||||
+ form.plugin_name.value
|
||||
+ "-pinpoint=" + parseInt(form.start_epoch.value) + "," + parseInt(form.stop_epoch.value)
|
||||
+ ".png"
|
||||
+ "?"
|
||||
+ "&lower_limit=" + form.lower_limit.value
|
||||
+ "&upper_limit=" + form.upper_limit.value
|
||||
+ "&size_x=" + form.size_x.value
|
||||
+ "&size_y=" + form.size_y.value
|
||||
;
|
||||
|
||||
return ((+form.stop_epoch.value) - (+form.start_epoch.value)) / (+form.size_x.value);
|
||||
}
|
||||
|
||||
function updateStartStop() {
|
||||
form.start_iso8601.value = new Date(form.start_epoch.value * 1000).formatDate(Date.DATE_ISO8601);
|
||||
form.stop_iso8601.value = new Date(form.stop_epoch.value * 1000).formatDate(Date.DATE_ISO8601);
|
||||
}
|
||||
|
||||
function divMouseMove(event) {
|
||||
var delta_x;
|
||||
var size_x;
|
||||
|
||||
// Handling the borders (X1>X2 ou X1<X2)
|
||||
var posX = getCoordinatesOnImage(event)[0];
|
||||
var current_width = posX - initial_left;
|
||||
if (current_width < 0) {
|
||||
delta_x = posX - 63; // the Y Axis is 63px from the left border
|
||||
size_x = -current_width;
|
||||
} else {
|
||||
delta_x = initial_left - 63; // the Y Axis is 63px from the left border
|
||||
size_x = current_width;
|
||||
}
|
||||
|
||||
// Compute the epochs UNIX (only for horizontal)
|
||||
form.start_epoch.value = start_epoch + scale * delta_x;
|
||||
form.stop_epoch.value = start_epoch + scale * ( delta_x + size_x );
|
||||
|
||||
// update !
|
||||
updateStartStop();
|
||||
}
|
||||
|
||||
function startZoom(event) {
|
||||
var pos = getCoordinatesOnImage(event);
|
||||
initial_left = pos[0];
|
||||
initial_top = pos[1];
|
||||
|
||||
// Fix the handles
|
||||
form.start_iso8601.disabled = true;
|
||||
form.stop_iso8601.disabled = true;
|
||||
form.start_epoch.disabled = true;
|
||||
form.stop_epoch.disabled = true;
|
||||
image.onmousemove = divMouseMove;
|
||||
}
|
||||
|
||||
function endZoom(event) {
|
||||
image.onmousemove = undefined;
|
||||
form.start_iso8601.disabled = false;
|
||||
form.stop_iso8601.disabled = false;
|
||||
form.start_epoch.disabled = false;
|
||||
form.stop_epoch.disabled = false;
|
||||
}
|
||||
|
||||
function fillDate(date, default_date) {
|
||||
return date + default_date.substring(date.length, default_date.length);
|
||||
}
|
||||
|
||||
function majDates(event) {
|
||||
var default_date = "2009-01-01T00:00:00+0100";
|
||||
|
||||
var start_manual = fillDate(form.start_iso8601.value, default_date);
|
||||
var stop_manual = fillDate(form.stop_iso8601.value, default_date);
|
||||
|
||||
var dateRegex = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).(\d{4})/;
|
||||
|
||||
if (dateRegex.test(start_manual)) {
|
||||
var date_parsed = new Date(start_manual.replace(dateRegex, "$2 $3, $1 $4:$5:$6"));
|
||||
form.start_epoch.value = date_parsed.getTime() / 1000;
|
||||
}
|
||||
|
||||
if (dateRegex.test(stop_manual)) {
|
||||
var date_parsed = new Date(stop_manual.replace(dateRegex, "$2 $3, $1 $4:$5:$6"));
|
||||
form.stop_epoch.value = date_parsed.getTime() / 1000;
|
||||
}
|
||||
|
||||
//form.submit();
|
||||
refreshImg();
|
||||
}
|
||||
|
||||
function click(event) {
|
||||
switch ((clickCounter++) % 2) {
|
||||
case 0:
|
||||
startZoom(event);
|
||||
break;
|
||||
case 1:
|
||||
endZoom(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Coordinates on image
|
||||
function findPosition(oElement) {
|
||||
if (typeof( oElement.offsetParent ) != "undefined") {
|
||||
for (var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent) {
|
||||
posX += oElement.offsetLeft;
|
||||
posY += oElement.offsetTop;
|
||||
}
|
||||
return [posX, posY];
|
||||
}
|
||||
else {
|
||||
return [oElement.x, oElement.y];
|
||||
}
|
||||
}
|
||||
|
||||
function getCoordinatesOnImage(event) {
|
||||
var posX = 0;
|
||||
var posY = 0;
|
||||
var imgPos;
|
||||
imgPos = findPosition(image);
|
||||
if (!event) var event = window.event;
|
||||
if (event.pageX || event.pageY) {
|
||||
posX = event.pageX;
|
||||
posY = event.pageY;
|
||||
}
|
||||
else if (event.clientX || event.clientY) {
|
||||
posX = event.clientX + document.body.scrollLeft
|
||||
+ document.documentElement.scrollLeft;
|
||||
posY = event.clientY + document.body.scrollTop
|
||||
+ document.documentElement.scrollTop;
|
||||
}
|
||||
posX = posX - imgPos[0];
|
||||
posY = posY - imgPos[1];
|
||||
return [posX, posY];
|
||||
}
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
function refreshZoom(query,form,image,divOverlay){var qs=new Querystring(query);init();var scale=refreshImg();var start_epoch=+qs.get("rst_start_epoch",form.start_epoch.value);var stop_epoch=+qs.get("rst_stop_epoch",form.stop_epoch.value);var initial_left;var initial_top;form.plugin_name.onblur=refreshImg;form.start_iso8601.onblur=majDates;form.stop_iso8601.onblur=majDates;form.start_epoch.onblur=refreshImg;form.stop_epoch.onblur=refreshImg;form.lower_limit.onblur=refreshImg;form.upper_limit.onblur=refreshImg;form.size_x.onblur=refreshImg;form.size_y.onblur=refreshImg;form.btnReset.onclick=reset;image.onclick=click;var clickCounter=0;function init(){form.plugin_name.value=qs.get("plugin_name","localdomain/localhost.localdomain/if_eth0");form.start_epoch.value=qs.get("start_epoch","1236561663");form.stop_epoch.value=qs.get("stop_epoch","1237561663");form.lower_limit.value=qs.get("lower_limit","");form.upper_limit.value=qs.get("upper_limit","");form.size_x.value=qs.get("size_x","");form.size_y.value=qs.get("size_y","");updateStartStop()}function reset(event){init();form.start_epoch.value=start_epoch;form.stop_epoch.value=stop_epoch;updateStartStop();scale=refreshImg();clickCounter=0;initial_left=0;initial_top=0;image.onmousemove=undefined;form.start_iso8601.disabled=false;form.stop_iso8601.disabled=false;form.start_epoch.disabled=false;form.stop_epoch.disabled=false}function refreshImg(event){image.src=qs.get("cgiurl_graph","/munin-cgi/munin-cgi-graph")+"/"+form.plugin_name.value+"-pinpoint="+parseInt(form.start_epoch.value)+","+parseInt(form.stop_epoch.value)+".png"+"?"+"&lower_limit="+form.lower_limit.value+"&upper_limit="+form.upper_limit.value+"&size_x="+form.size_x.value+"&size_y="+form.size_y.value;return(+form.stop_epoch.value-+form.start_epoch.value)/+form.size_x.value}function updateStartStop(){form.start_iso8601.value=new Date(form.start_epoch.value*1e3).formatDate(Date.DATE_ISO8601);form.stop_iso8601.value=new Date(form.stop_epoch.value*1e3).formatDate(Date.DATE_ISO8601)}function divMouseMove(event){var delta_x;var size_x;var posX=getCoordinatesOnImage(event)[0];var current_width=posX-initial_left;if(current_width<0){delta_x=posX-63;size_x=-current_width}else{delta_x=initial_left-63;size_x=current_width}form.start_epoch.value=start_epoch+scale*delta_x;form.stop_epoch.value=start_epoch+scale*(delta_x+size_x);updateStartStop()}function startZoom(event){var pos=getCoordinatesOnImage(event);initial_left=pos[0];initial_top=pos[1];form.start_iso8601.disabled=true;form.stop_iso8601.disabled=true;form.start_epoch.disabled=true;form.stop_epoch.disabled=true;image.onmousemove=divMouseMove}function endZoom(event){image.onmousemove=undefined;form.start_iso8601.disabled=false;form.stop_iso8601.disabled=false;form.start_epoch.disabled=false;form.stop_epoch.disabled=false}function fillDate(date,default_date){return date+default_date.substring(date.length,default_date.length)}function majDates(event){var default_date="2009-01-01T00:00:00+0100";var start_manual=fillDate(form.start_iso8601.value,default_date);var stop_manual=fillDate(form.stop_iso8601.value,default_date);var dateRegex=/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).(\d{4})/;if(dateRegex.test(start_manual)){var date_parsed=new Date(start_manual.replace(dateRegex,"$2 $3, $1 $4:$5:$6"));form.start_epoch.value=date_parsed.getTime()/1e3}if(dateRegex.test(stop_manual)){var date_parsed=new Date(stop_manual.replace(dateRegex,"$2 $3, $1 $4:$5:$6"));form.stop_epoch.value=date_parsed.getTime()/1e3}refreshImg()}function click(event){switch(clickCounter++%2){case 0:startZoom(event);break;case 1:endZoom(event);break}}function findPosition(oElement){if(typeof oElement.offsetParent!="undefined"){for(var posX=0,posY=0;oElement;oElement=oElement.offsetParent){posX+=oElement.offsetLeft;posY+=oElement.offsetTop}return[posX,posY]}else{return[oElement.x,oElement.y]}}function getCoordinatesOnImage(event){var posX=0;var posY=0;var imgPos;imgPos=findPosition(image);if(!event)var event=window.event;if(event.pageX||event.pageY){posX=event.pageX;posY=event.pageY}else if(event.clientX||event.clientY){posX=event.clientX+document.body.scrollLeft+document.documentElement.scrollLeft;posY=event.clientY+document.body.scrollTop+document.documentElement.scrollTop}posX=posX-imgPos[0];posY=posY-imgPos[1];return[posX,posY]}}
|
|
@ -1,363 +0,0 @@
|
|||
// formatDate :
|
||||
// a PHP date like function, for formatting date strings
|
||||
// authored by Svend Tofte <www.svendtofte.com>
|
||||
// the code is in the public domain
|
||||
//
|
||||
// see http://www.svendtofte.com/javascript/javascript-date-string-formatting/
|
||||
// and http://www.php.net/date
|
||||
//
|
||||
// thanks to
|
||||
// - Daniel Berlin <mail@daniel-berlin.de>,
|
||||
// major overhaul and improvements
|
||||
// - Matt Bannon,
|
||||
// correcting some stupid bugs in my days-in-the-months list!
|
||||
// - levon ghazaryan. pointing out an error in z switch.
|
||||
// - Andy Pemberton. pointing out error in c switch
|
||||
//
|
||||
// input : format string
|
||||
// time : epoch time (seconds, and optional)
|
||||
//
|
||||
// if time is not passed, formatting is based on
|
||||
// the current "this" date object's set time.
|
||||
//
|
||||
// supported switches are
|
||||
// a, A, B, c, d, D, F, g, G, h, H, i, I (uppercase i), j, l (lowecase L),
|
||||
// L, m, M, n, N, O, P, r, s, S, t, U, w, W, y, Y, z, Z
|
||||
//
|
||||
// unsupported (as compared to date in PHP 5.1.3)
|
||||
// T, e, o
|
||||
|
||||
Date.prototype.formatDate = function (input,time) {
|
||||
|
||||
var daysLong = ["Sunday", "Monday", "Tuesday", "Wednesday",
|
||||
"Thursday", "Friday", "Saturday"];
|
||||
var daysShort = ["Sun", "Mon", "Tue", "Wed",
|
||||
"Thu", "Fri", "Sat"];
|
||||
var monthsShort = ["Jan", "Feb", "Mar", "Apr",
|
||||
"May", "Jun", "Jul", "Aug", "Sep",
|
||||
"Oct", "Nov", "Dec"];
|
||||
var monthsLong = ["January", "February", "March", "April",
|
||||
"May", "June", "July", "August", "September",
|
||||
"October", "November", "December"];
|
||||
|
||||
var switches = { // switches object
|
||||
|
||||
a : function () {
|
||||
// Lowercase Ante meridiem and Post meridiem
|
||||
return date.getHours() > 11? "pm" : "am";
|
||||
},
|
||||
|
||||
A : function () {
|
||||
// Uppercase Ante meridiem and Post meridiem
|
||||
return (this.a().toUpperCase ());
|
||||
},
|
||||
|
||||
B : function (){
|
||||
// Swatch internet time. code simply grabbed from ppk,
|
||||
// since I was feeling lazy:
|
||||
// http://www.xs4all.nl/~ppk/js/beat.html
|
||||
var off = (date.getTimezoneOffset() + 60)*60;
|
||||
var theSeconds = (date.getHours() * 3600) +
|
||||
(date.getMinutes() * 60) +
|
||||
date.getSeconds() + off;
|
||||
var beat = Math.floor(theSeconds/86.4);
|
||||
if (beat > 1000) beat -= 1000;
|
||||
if (beat < 0) beat += 1000;
|
||||
if ((String(beat)).length == 1) beat = "00"+beat;
|
||||
if ((String(beat)).length == 2) beat = "0"+beat;
|
||||
return beat;
|
||||
},
|
||||
|
||||
c : function () {
|
||||
// ISO 8601 date (e.g.: "2004-02-12T15:19:21+00:00"), as per
|
||||
// http://www.cl.cam.ac.uk/~mgk25/iso-time.html
|
||||
return (this.Y() + "-" + this.m() + "-" + this.d() + "T" +
|
||||
this.H() + ":" + this.i() + ":" + this.s() + this.P());
|
||||
},
|
||||
|
||||
d : function () {
|
||||
// Day of the month, 2 digits with leading zeros
|
||||
var j = String(this.j());
|
||||
return (j.length == 1 ? "0"+j : j);
|
||||
},
|
||||
|
||||
D : function () {
|
||||
// A textual representation of a day, three letters
|
||||
return daysShort[date.getDay()];
|
||||
},
|
||||
|
||||
F : function () {
|
||||
// A full textual representation of a month
|
||||
return monthsLong[date.getMonth()];
|
||||
},
|
||||
|
||||
g : function () {
|
||||
// 12-hour format of an hour without leading zeros, 1 through 12!
|
||||
if (date.getHours() == 0) {
|
||||
return 12;
|
||||
} else {
|
||||
return date.getHours()>12 ? date.getHours()-12 : date.getHours();
|
||||
}
|
||||
},
|
||||
|
||||
G : function () {
|
||||
// 24-hour format of an hour without leading zeros
|
||||
return date.getHours();
|
||||
},
|
||||
|
||||
h : function () {
|
||||
// 12-hour format of an hour with leading zeros
|
||||
var g = String(this.g());
|
||||
return (g.length == 1 ? "0"+g : g);
|
||||
},
|
||||
|
||||
H : function () {
|
||||
// 24-hour format of an hour with leading zeros
|
||||
var G = String(this.G());
|
||||
return (G.length == 1 ? "0"+G : G);
|
||||
},
|
||||
|
||||
i : function () {
|
||||
// Minutes with leading zeros
|
||||
var min = String (date.getMinutes ());
|
||||
return (min.length == 1 ? "0" + min : min);
|
||||
},
|
||||
|
||||
I : function () {
|
||||
// Whether or not the date is in daylight saving time (DST)
|
||||
// note that this has no bearing in actual DST mechanics,
|
||||
// and is just a pure guess. buyer beware.
|
||||
var noDST = new Date ("January 1 " + this.Y() + " 00:00:00");
|
||||
return (noDST.getTimezoneOffset () ==
|
||||
date.getTimezoneOffset () ? 0 : 1);
|
||||
},
|
||||
|
||||
j : function () {
|
||||
// Day of the month without leading zeros
|
||||
return date.getDate();
|
||||
},
|
||||
|
||||
l : function () {
|
||||
// A full textual representation of the day of the week
|
||||
return daysLong[date.getDay()];
|
||||
},
|
||||
|
||||
L : function () {
|
||||
// leap year or not. 1 if leap year, 0 if not.
|
||||
// the logic should match iso's 8601 standard.
|
||||
// http://www.uic.edu/depts/accc/software/isodates/leapyear.html
|
||||
var Y = this.Y();
|
||||
if (
|
||||
(Y % 4 == 0 && Y % 100 != 0) ||
|
||||
(Y % 4 == 0 && Y % 100 == 0 && Y % 400 == 0)
|
||||
) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
|
||||
m : function () {
|
||||
// Numeric representation of a month, with leading zeros
|
||||
var n = String(this.n());
|
||||
return (n.length == 1 ? "0"+n : n);
|
||||
},
|
||||
|
||||
M : function () {
|
||||
// A short textual representation of a month, three letters
|
||||
return monthsShort[date.getMonth()];
|
||||
},
|
||||
|
||||
n : function () {
|
||||
// Numeric representation of a month, without leading zeros
|
||||
return date.getMonth()+1;
|
||||
},
|
||||
|
||||
N : function () {
|
||||
// ISO-8601 numeric representation of the day of the week
|
||||
var w = this.w();
|
||||
return (w == 0 ? 7 : w);
|
||||
},
|
||||
|
||||
O : function () {
|
||||
// Difference to Greenwich time (GMT) in hours
|
||||
var os = Math.abs(date.getTimezoneOffset());
|
||||
var h = String(Math.floor(os/60));
|
||||
var m = String(os%60);
|
||||
h.length == 1? h = "0"+h:1;
|
||||
m.length == 1? m = "0"+m:1;
|
||||
return date.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m;
|
||||
},
|
||||
|
||||
P : function () {
|
||||
// Difference to GMT, with colon between hours and minutes
|
||||
var O = this.O();
|
||||
return (O.substr(0, 3) + ":" + O.substr(3, 2));
|
||||
},
|
||||
|
||||
r : function () {
|
||||
// RFC 822 formatted date
|
||||
var r; // result
|
||||
// Thu , 21 Dec 2000
|
||||
r = this.D() + ", " + this.d() + " " + this.M() + " " + this.Y() +
|
||||
// 16 : 01 : 07 0200
|
||||
" " + this.H() + ":" + this.i() + ":" + this.s() + " " + this.O();
|
||||
return r;
|
||||
},
|
||||
|
||||
s : function () {
|
||||
// Seconds, with leading zeros
|
||||
var sec = String (date.getSeconds ());
|
||||
return (sec.length == 1 ? "0" + sec : sec);
|
||||
},
|
||||
|
||||
S : function () {
|
||||
// English ordinal suffix for the day of the month, 2 characters
|
||||
switch (date.getDate ()) {
|
||||
case 1: return ("st");
|
||||
case 2: return ("nd");
|
||||
case 3: return ("rd");
|
||||
case 21: return ("st");
|
||||
case 22: return ("nd");
|
||||
case 23: return ("rd");
|
||||
case 31: return ("st");
|
||||
default: return ("th");
|
||||
}
|
||||
},
|
||||
|
||||
t : function () {
|
||||
// thanks to Matt Bannon for some much needed code-fixes here!
|
||||
var daysinmonths = [null,31,28,31,30,31,30,31,31,30,31,30,31];
|
||||
if (this.L()==1 && this.n()==2) return 29; // ~leap day
|
||||
return daysinmonths[this.n()];
|
||||
},
|
||||
|
||||
U : function () {
|
||||
// Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
|
||||
return Math.round(date.getTime()/1000);
|
||||
},
|
||||
|
||||
w : function () {
|
||||
// Numeric representation of the day of the week
|
||||
return date.getDay();
|
||||
},
|
||||
|
||||
W : function () {
|
||||
// Weeknumber, as per ISO specification:
|
||||
// http://www.cl.cam.ac.uk/~mgk25/iso-time.html
|
||||
|
||||
var DoW = this.N ();
|
||||
var DoY = this.z ();
|
||||
|
||||
// If the day is 3 days before New Year's Eve and is Thursday or earlier,
|
||||
// it's week 1 of next year.
|
||||
var daysToNY = 364 + this.L () - DoY;
|
||||
if (daysToNY <= 2 && DoW <= (3 - daysToNY)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If the day is within 3 days after New Year's Eve and is Friday or later,
|
||||
// it belongs to the old year.
|
||||
if (DoY <= 2 && DoW >= 5) {
|
||||
return new Date (this.Y () - 1, 11, 31).formatDate ("W");
|
||||
}
|
||||
|
||||
var nyDoW = new Date (this.Y (), 0, 1).getDay ();
|
||||
nyDoW = nyDoW != 0 ? nyDoW - 1 : 6;
|
||||
|
||||
if (nyDoW <= 3) { // First day of the year is a Thursday or earlier
|
||||
return (1 + Math.floor ((DoY + nyDoW) / 7));
|
||||
} else { // First day of the year is a Friday or later
|
||||
return (1 + Math.floor ((DoY - (7 - nyDoW)) / 7));
|
||||
}
|
||||
},
|
||||
|
||||
y : function () {
|
||||
// A two-digit representation of a year
|
||||
var y = String(this.Y());
|
||||
return y.substring(y.length-2,y.length);
|
||||
},
|
||||
|
||||
Y : function () {
|
||||
// A full numeric representation of a year, 4 digits
|
||||
|
||||
// we first check, if getFullYear is supported. if it
|
||||
// is, we just use that. ppks code is nice, but won't
|
||||
// work with dates outside 1900-2038, or something like that
|
||||
if (date.getFullYear) {
|
||||
var newDate = new Date("January 1 2001 00:00:00 +0000");
|
||||
var x = newDate .getFullYear();
|
||||
if (x == 2001) {
|
||||
// i trust the method now
|
||||
return date.getFullYear();
|
||||
}
|
||||
}
|
||||
// else, do this:
|
||||
// codes thanks to ppk:
|
||||
// http://www.xs4all.nl/~ppk/js/introdate.html
|
||||
var x = date.getYear();
|
||||
var y = x % 100;
|
||||
y += (y < 38) ? 2000 : 1900;
|
||||
return y;
|
||||
},
|
||||
|
||||
|
||||
z : function () {
|
||||
// The day of the year, zero indexed! 0 through 366
|
||||
var s = "January 1 " + this.Y() + " 00:00:00 GMT" + this.O();
|
||||
var t = new Date(s);
|
||||
var diff = date.getTime() - t.getTime();
|
||||
return Math.floor(diff/1000/60/60/24);
|
||||
},
|
||||
|
||||
Z : function () {
|
||||
// Timezone offset in seconds
|
||||
return (date.getTimezoneOffset () * -60);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getSwitch(str) {
|
||||
if (switches[str] != undefined) {
|
||||
return switches[str]();
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
var date;
|
||||
if (time) {
|
||||
var date = new Date (time);
|
||||
} else {
|
||||
var date = this;
|
||||
}
|
||||
|
||||
var formatString = input.split("");
|
||||
var i = 0;
|
||||
while (i < formatString.length) {
|
||||
if (formatString[i] == "%") {
|
||||
// this is our way of allowing users to escape stuff
|
||||
formatString.splice(i,1);
|
||||
} else {
|
||||
formatString[i] = getSwitch(formatString[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return formatString.join("");
|
||||
}
|
||||
|
||||
|
||||
// Some (not all) predefined format strings from PHP 5.1.1, which
|
||||
// offer standard date representations.
|
||||
// See: http://www.php.net/manual/en/ref.datetime.php#datetime.constants
|
||||
//
|
||||
|
||||
// Atom "2005-08-15T15:52:01+00:00"
|
||||
Date.DATE_ATOM = "Y-m-d%TH:i:sP";
|
||||
// ISO-8601 "2005-08-15T15:52:01+0000"
|
||||
Date.DATE_ISO8601 = "Y-m-d%TH:i:sO";
|
||||
// RFC 2822 "Mon, 15 Aug 2005 15:52:01 +0000"
|
||||
Date.DATE_RFC2822 = "D, d M Y H:i:s O";
|
||||
// W3C "2005-08-15 15:52:01+00:00"
|
||||
Date.DATE_W3C = "Y-m-d%TH:i:sP";
|
|
@ -1 +0,0 @@
|
|||
Date.prototype.formatDate=function(input,time){var daysLong=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var daysShort=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];var monthsShort=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];var monthsLong=["January","February","March","April","May","June","July","August","September","October","November","December"];var switches={a:function(){return date.getHours()>11?"pm":"am"},A:function(){return this.a().toUpperCase()},B:function(){var off=(date.getTimezoneOffset()+60)*60;var theSeconds=date.getHours()*3600+date.getMinutes()*60+date.getSeconds()+off;var beat=Math.floor(theSeconds/86.4);if(beat>1e3)beat-=1e3;if(beat<0)beat+=1e3;if(String(beat).length==1)beat="00"+beat;if(String(beat).length==2)beat="0"+beat;return beat},c:function(){return this.Y()+"-"+this.m()+"-"+this.d()+"T"+this.H()+":"+this.i()+":"+this.s()+this.P()},d:function(){var j=String(this.j());return j.length==1?"0"+j:j},D:function(){return daysShort[date.getDay()]},F:function(){return monthsLong[date.getMonth()]},g:function(){if(date.getHours()==0){return 12}else{return date.getHours()>12?date.getHours()-12:date.getHours()}},G:function(){return date.getHours()},h:function(){var g=String(this.g());return g.length==1?"0"+g:g},H:function(){var G=String(this.G());return G.length==1?"0"+G:G},i:function(){var min=String(date.getMinutes());return min.length==1?"0"+min:min},I:function(){var noDST=new Date("January 1 "+this.Y()+" 00:00:00");return noDST.getTimezoneOffset()==date.getTimezoneOffset()?0:1},j:function(){return date.getDate()},l:function(){return daysLong[date.getDay()]},L:function(){var Y=this.Y();if(Y%4==0&&Y%100!=0||Y%4==0&&Y%100==0&&Y%400==0){return 1}else{return 0}},m:function(){var n=String(this.n());return n.length==1?"0"+n:n},M:function(){return monthsShort[date.getMonth()]},n:function(){return date.getMonth()+1},N:function(){var w=this.w();return w==0?7:w},O:function(){var os=Math.abs(date.getTimezoneOffset());var h=String(Math.floor(os/60));var m=String(os%60);h.length==1?h="0"+h:1;m.length==1?m="0"+m:1;return date.getTimezoneOffset()<0?"+"+h+m:"-"+h+m},P:function(){var O=this.O();return O.substr(0,3)+":"+O.substr(3,2)},r:function(){var r;r=this.D()+", "+this.d()+" "+this.M()+" "+this.Y()+" "+this.H()+":"+this.i()+":"+this.s()+" "+this.O();return r},s:function(){var sec=String(date.getSeconds());return sec.length==1?"0"+sec:sec},S:function(){switch(date.getDate()){case 1:return"st";case 2:return"nd";case 3:return"rd";case 21:return"st";case 22:return"nd";case 23:return"rd";case 31:return"st";default:return"th"}},t:function(){var daysinmonths=[null,31,28,31,30,31,30,31,31,30,31,30,31];if(this.L()==1&&this.n()==2)return 29;return daysinmonths[this.n()]},U:function(){return Math.round(date.getTime()/1e3)},w:function(){return date.getDay()},W:function(){var DoW=this.N();var DoY=this.z();var daysToNY=364+this.L()-DoY;if(daysToNY<=2&&DoW<=3-daysToNY){return 1}if(DoY<=2&&DoW>=5){return new Date(this.Y()-1,11,31).formatDate("W")}var nyDoW=new Date(this.Y(),0,1).getDay();nyDoW=nyDoW!=0?nyDoW-1:6;if(nyDoW<=3){return 1+Math.floor((DoY+nyDoW)/7)}else{return 1+Math.floor((DoY-(7-nyDoW))/7)}},y:function(){var y=String(this.Y());return y.substring(y.length-2,y.length)},Y:function(){if(date.getFullYear){var newDate=new Date("January 1 2001 00:00:00 +0000");var x=newDate.getFullYear();if(x==2001){return date.getFullYear()}}var x=date.getYear();var y=x%100;y+=y<38?2e3:1900;return y},z:function(){var s="January 1 "+this.Y()+" 00:00:00 GMT"+this.O();var t=new Date(s);var diff=date.getTime()-t.getTime();return Math.floor(diff/1e3/60/60/24)},Z:function(){return date.getTimezoneOffset()*-60}};function getSwitch(str){if(switches[str]!=undefined){return switches[str]()}else{return str}}var date;if(time){var date=new Date(time)}else{var date=this}var formatString=input.split("");var i=0;while(i<formatString.length){if(formatString[i]=="%"){formatString.splice(i,1)}else{formatString[i]=getSwitch(formatString[i])}i++}return formatString.join("")};Date.DATE_ATOM="Y-m-d%TH:i:sP";Date.DATE_ISO8601="Y-m-d%TH:i:sO";Date.DATE_RFC2822="D, d M Y H:i:s O";Date.DATE_W3C="Y-m-d%TH:i:sP";
|
|
@ -1,42 +0,0 @@
|
|||
/* Client-side access to querystring name=value pairs
|
||||
Version 1.3
|
||||
28 May 2008
|
||||
|
||||
License (Simplified BSD):
|
||||
http://adamv.com/dev/javascript/qslicense.txt
|
||||
*/
|
||||
function Querystring(qs) { // optionally pass a querystring to parse
|
||||
this.params = {};
|
||||
|
||||
var query_string = window.location.search;
|
||||
|
||||
if (qs == null) qs = query_string.substring(1, query_string.length);
|
||||
if (qs.length == 0) return;
|
||||
|
||||
// Turn <plus> back to <space>
|
||||
// See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
|
||||
qs = qs.replace(/\+/g, ' ');
|
||||
var args = qs.split('&'); // parse out name/value pairs separated via &
|
||||
|
||||
// split out each name=value pair
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
var pair = args[i].split('=');
|
||||
var name = decodeURIComponent(pair[0]);
|
||||
|
||||
var value = (pair.length==2)
|
||||
? decodeURIComponent(pair[1])
|
||||
: name;
|
||||
|
||||
this.params[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
Querystring.prototype.get = function(key, default_) {
|
||||
var value = this.params[key];
|
||||
return (value != null) ? value : default_;
|
||||
}
|
||||
|
||||
Querystring.prototype.contains = function(key) {
|
||||
var value = this.params[key];
|
||||
return (value != null);
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
function Querystring(qs){this.params={};var query_string=window.location.search;if(qs==null)qs=query_string.substring(1,query_string.length);if(qs.length==0)return;qs=qs.replace(/\+/g," ");var args=qs.split("&");for(var i=0;i<args.length;i++){var pair=args[i].split("=");var name=decodeURIComponent(pair[0]);var value=pair.length==2?decodeURIComponent(pair[1]):name;this.params[name]=value}}Querystring.prototype.get=function(key,default_){var value=this.params[key];return value!=null?value:default_};Querystring.prototype.contains=function(key){var value=this.params[key];return value!=null};
|
|
@ -1,8 +0,0 @@
|
|||
<!--
|
||||
File: partial/footer.tmpl
|
||||
|
||||
Used: All views, called after partial/footer.tmpl
|
||||
-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,240 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<!--
|
||||
File: partial/head.tmpl
|
||||
|
||||
Used: All views, called before anything else
|
||||
-->
|
||||
|
||||
<head>
|
||||
<title>
|
||||
<TMPL_IF NAME="NAME"><TMPL_VAR ESCAPE="HTML" NAME="NAME"> (</TMPL_IF>Munin<TMPL_LOOP NAME="PATH"><TMPL_IF NAME="pathname"> :: <TMPL_VAR ESCAPE="HTML" NAME="pathname"></TMPL_IF></TMPL_LOOP><TMPL_IF NAME="NAME">)</TMPL_IF>
|
||||
</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="Auto-generated by Munin">
|
||||
<TMPL_UNLESS NAME="SHOW_ZOOM_JS">
|
||||
<meta http-equiv="refresh" content="300" />
|
||||
</TMPL_UNLESS>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon.ico" />
|
||||
<link rel="icon" type="image/png" href="<TMPL_VAR NAME='R_PATH' />/static/img/favicon.png" />
|
||||
<link href="<TMPL_VAR NAME='R_PATH' />/static/css/bootstrap4.min.css" rel="stylesheet" />
|
||||
<link href="<TMPL_VAR NAME='R_PATH' />/static/css/style-munstrap.min.css" rel="stylesheet" />
|
||||
|
||||
<script src="<TMPL_VAR NAME='R_PATH' />/static/js/jquery.min.js"></script>
|
||||
<script src="<TMPL_VAR NAME='R_PATH' />/static/js/lazysizes.min.js" async></script>
|
||||
<script src="<TMPL_VAR NAME='R_PATH' />/static/js/bootstrap4.min.js"></script>
|
||||
<script src="<TMPL_VAR NAME='R_PATH' />/static/js/typeahead.bundle.min.js"></script>
|
||||
<script>
|
||||
// This is used to build the navigation quick search - there is no backend, so we have to do
|
||||
// it all client side.
|
||||
//
|
||||
// As a curious side note, commenting out the template loops and whatnot allows vscode to parse
|
||||
// the javascript - so please note that the commented out TMPL directives STILL FUNCTION.
|
||||
var gen_basegroups = {
|
||||
// <TMPL_LOOP NAME="ROOTGROUPS">
|
||||
"<TMPL_VAR NAME='NAME' />" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL'>",
|
||||
"compare" : {
|
||||
// <TMPL_IF NAME="COMPARE">
|
||||
"Day" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_LOOP NAME='PATH' /><TMPL_IF NAME='pathname'><TMPL_VAR ESCAPE='URL' NAME='PATHNAME' />/</TMPL_IF></TMPL_LOOP>comparison-day.html",
|
||||
"Week" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_LOOP NAME='PATH' /><TMPL_IF NAME='pathname'><TMPL_VAR ESCAPE='URL' NAME='PATHNAME' />/</TMPL_IF></TMPL_LOOP>comparison-week.html",
|
||||
"Month" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_LOOP NAME='PATH' /><TMPL_IF NAME='pathname'><TMPL_VAR ESCAPE='URL' NAME='PATHNAME' />/</TMPL_IF></TMPL_LOOP>comparison-month.html",
|
||||
"Year" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_LOOP NAME='PATH' /><TMPL_IF NAME='pathname'><TMPL_VAR ESCAPE='URL' NAME='PATHNAME' />/</TMPL_IF></TMPL_LOOP>comparison-year.html"
|
||||
// </TMPL_IF>
|
||||
}
|
||||
},
|
||||
// </TMPL_LOOP>
|
||||
};
|
||||
var gen_hosts = {
|
||||
// <TMPL_LOOP NAME="ROOTGROUPS">
|
||||
// <TMPL_LOOP NAME="GROUPS">
|
||||
// <TMPL_IF NAME="NCATEGORIES">
|
||||
"<TMPL_VAR ESCAPE='HTML' NAME='NAME' />" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL'>",
|
||||
"services" : {
|
||||
// <TMPL_LOOP NAME="CATEGORIES">
|
||||
"<TMPL_VAR ESCAPE='HTML' NAME='NAME' />" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL' />",
|
||||
// </TMPL_LOOP>
|
||||
}
|
||||
},
|
||||
// </TMPL_IF>
|
||||
// </TMPL_LOOP>
|
||||
// </TMPL_LOOP>
|
||||
};
|
||||
var gen_cats = {
|
||||
// <TMPL_LOOP NAME="GLOBALCATS">
|
||||
"Category :: <TMPL_VAR NAME='NAME'> :: Day" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLDAY'>"
|
||||
},
|
||||
"Category :: <TMPL_VAR NAME='NAME'> :: Week" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLWEEK'>"
|
||||
},
|
||||
"Category :: <TMPL_VAR NAME='NAME'> :: Month" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLMONTH'>"
|
||||
},
|
||||
"Category :: <TMPL_VAR NAME='NAME'> :: Year" : {
|
||||
"baseurl" : "<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLYEAR'>"
|
||||
},
|
||||
// </TMPL_LOOP>
|
||||
};
|
||||
|
||||
function absolute(base, relative) {
|
||||
var stack = base.split("/"),
|
||||
parts = relative.split("/");
|
||||
|
||||
stack.pop(); // remove current file name (or empty string)
|
||||
|
||||
// (omit if "base" is the current folder without trailing slash)
|
||||
|
||||
for (var i=0; i<parts.length; i++) {
|
||||
if (parts[i] == ".") { continue; }
|
||||
|
||||
if (parts[i] == "..") {
|
||||
stack.pop();
|
||||
} else {
|
||||
stack.push(parts[i]);
|
||||
}
|
||||
}
|
||||
return stack.join("/");
|
||||
}
|
||||
|
||||
var navMap = [];
|
||||
|
||||
$.each(gen_cats, function(name, obby) {
|
||||
navMap.push( { "name" : name, "link" : absolute(location.href, obby.baseurl) } );
|
||||
});
|
||||
|
||||
$.each(gen_hosts, function(name, obby) {
|
||||
var host_name = name;
|
||||
navMap.push( { "name" : "Host :: " + name, "link" : absolute(location.href, obby.baseurl) });
|
||||
$.each(obby.services, function(svcname, url){
|
||||
navMap.push( { "name" : "Service :: " + host_name + " :: " + svcname, "link" : absolute(location.href, url) });
|
||||
});
|
||||
});
|
||||
|
||||
$.each(gen_basegroups, function(name, obby) {
|
||||
var host_name = name;
|
||||
navMap.push( { "name" : "Host :: " + name, "link" : absolute(location.href, obby.baseurl) });
|
||||
$.each(obby.compare, function(svcname, url){
|
||||
navMap.push( { "name" : "Compare :: " + host_name + " :: " + svcname, "link" : absolute(location.href, url) });
|
||||
});
|
||||
});
|
||||
|
||||
var navMapB = new Bloodhound({
|
||||
datumTokenizer: function (d) { return Bloodhound.tokenizers.whitespace(d.name); },
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
identify: function (obj) { return obj.link; },
|
||||
local: navMap
|
||||
});
|
||||
|
||||
$(document).ready(function(){
|
||||
$('#findthehost').typeahead({
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 2,
|
||||
},
|
||||
{
|
||||
name: 'navMap',
|
||||
limit: 10,
|
||||
display: 'link',
|
||||
source: navMapB,
|
||||
templates: {
|
||||
suggestion: function (data) {
|
||||
return '<div>' + data.name + '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
//$('#findthehost').on('typeahead:change',function(){ $('#formy1').submit(); });
|
||||
$('#findthehost').on('typeahead:select',function(){ $('#formy1').submit(); });
|
||||
|
||||
$('#formy1').on('submit', function(){
|
||||
inputVal = $('#findthehost').val();
|
||||
if ( inputVal.substring(0, 4) == "http" ) {
|
||||
window.location.href = inputVal;
|
||||
} else {
|
||||
$('#findthehost').typeahead('val', '');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-3">
|
||||
<a class="navbar-brand" href="<TMPL_VAR NAME='R_PATH' />"><span class="munin-icon"></span> MUNIN</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<TMPL_VAR NAME='R_PATH' />">Home</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarProblems" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Problems
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarProblems">
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/problems.html#critical"><span class="badge alert-danger mr-2"><TMPL_VAR NAME="NCRITICAL"></span>Critical</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/problems.html#warnings"><span class="badge alert-warning mr-2"><TMPL_VAR NAME="NWARNING"></span>Warning</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/problems.html#unknowns"><span class="badge alert-info mr-2"><TMPL_VAR NAME="NUNKNOWN"></span>Unknown</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarGroups" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Groups
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarGroups">
|
||||
<TMPL_LOOP NAME="ROOTGROUPS">
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL'>"><TMPL_VAR NAME="NAME"></a>
|
||||
</TMPL_LOOP>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarHosts" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Hosts
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarHosts">
|
||||
<TMPL_LOOP NAME="ROOTGROUPS">
|
||||
<TMPL_LOOP NAME="GROUPS">
|
||||
<TMPL_IF NAME="NCATEGORIES">
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URL'>"><TMPL_VAR ESCAPE="HTML" NAME="NAME"></a>
|
||||
</TMPL_IF>
|
||||
</TMPL_LOOP>
|
||||
</TMPL_LOOP>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarCats" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Categories
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarCats">
|
||||
<TMPL_LOOP NAME="GLOBALCATS">
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLDAY'>"><TMPL_VAR NAME="NAME"> - Day</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLWEEK'>"><TMPL_VAR NAME="NAME"> - Week</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLMONTH'>"><TMPL_VAR NAME="NAME"> - Month</a>
|
||||
<a class="dropdown-item" href="<TMPL_VAR NAME='R_PATH' />/<TMPL_VAR NAME='URLYEAR'>"><TMPL_VAR NAME="NAME"> - Year</a>
|
||||
<TMPL_IF NAME="__first__"><div class="dropdown-divider"></div></TMPL_IF>
|
||||
<TMPL_IF NAME="__inner__"><div class="dropdown-divider"></div></TMPL_IF>
|
||||
</TMPL_LOOP>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<form id="formy1" class="form-inline my-2 my-lg-0 w-25">
|
||||
<input class="form-control mr-sm-2 w-100" type="text" id="findthehost" placeholder="Host or Service" aria-label="Search">
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<TMPL_INCLUDE NAME="logo_navigation.tmpl">
|