Commit 8f6fadb9 authored by Alain Takoudjou's avatar Alain Takoudjou

Monitoring

First commit of monitoring renderjs application in erp5.
Monitoring is a render js application which uses jio to sync slapos instance promises result and display on web browser.

/reviewed-on nexedi/erp5!347
parent 54c4874a
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Graph</title>
<!-- custom css -->
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="dygraph.js" type="text/javascript"></script>
<script src="gadget_erp5_graph.js" type="text/javascript"></script>
</head>
<body>
<div class="custom-grid-wrap">
<div class="custom-grid ui-corner-all ui-body-inherit ui-shadow ui-corner-all"></div>
</div>
</body>
</html>
\ No newline at end of file
/*global window, rJS, console, RSVP, Dygraph */
/*jslint indent: 2, maxerr: 3 */
(function(rJS, window, RSVP, Dygraph) {
"use strict";
// Custom Interaction Model for synchronised graphs
var customInteractionModel = Dygraph.Interaction.defaultModel;
customInteractionModel.touchend = function(event, g, context) {
Dygraph.Interaction.endTouch(event, g, context);
var viewWindow = g.xAxisRange();
g.getFunctionOption("zoomCallback").call(g, viewWindow[0], viewWindow[1], g.yAxisRanges());
};
/*customInteractionModel.touchmove = function(event, g, context) {
Dygraph.Interaction.moveTouch(event, g, context);
var viewWindow = g.xAxisRange();
g.getFunctionOption("zoomCallback").call(g, viewWindow[0], viewWindow[1], g.yAxisRanges());
};
customInteractionModel.mousemove = function(event, g, context) {
if (context.isPanning) {
var viewWindow = g.xAxisRange();
g.getFunctionOption("zoomCallback").call(g, viewWindow[0], viewWindow[1], g.yAxisRanges());
}
}*/
customInteractionModel.mouseup = function(event, g, context) {
if (context.isPanning) {
var viewWindow = g.xAxisRange();
g.getFunctionOption("zoomCallback").call(g, viewWindow[0], viewWindow[1], g.yAxisRanges());
}
};
rJS(window)
.setState({graph: ""})
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
.ready(function(gadget) {
return;
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('getColors', function() {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.state.graph.getColors();
});
})
.declareMethod('setVisibility', function(num, value) {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.state.graph.setVisibility(num, value);
});
})
.declareMethod('updateOptions', function(options, ndarray) {
var gadget = this;
return new RSVP.Queue()
.push(function () {
gadget.state.graph.ndarray = ndarray;
return gadget.state.graph.updateOptions(options);
});
})
.declareMethod('resize', function(width, height) {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.state.graph.resize(width, height);
});
})
// render gadget
.declareMethod('render', function(data, option_dict, interactionModel) {
var gadget = this;
if (interactionModel === "customInteractionModel") {
option_dict.interactionModel = customInteractionModel;
}
return new RSVP.Queue()
.push(function () {
return gadget.changeState({
graph: new Dygraph(
gadget.element,
data,
option_dict
)
});
});
});
}(rJS, window, RSVP, Dygraph));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Monitoring Panel Gadget</title>
<link rel="stylesheet" href="magnific-popup.css">
<link href="gadget_monitoring_custom.css" rel="stylesheet" type="text/css"/>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script>
<script src="jquery.js" type="text/javascript"></script>
<script src="jquerymobile.js" type="text/javascript"></script>
<script id="panel-template-header" type="text/x-handlebars-template">
<div data-role="header" class="ui-bar-inherit">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-left">
<div class="ui-controlgroup-controls">
<form action="#" method="post">
<input type="submit" data-i18n="[value]Close" data-icon="delete" data-iconpos="notext" value="Close" />
</form>
</div>
</div>
<img class="ui-title" alt="SlapOS Monitoring" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAB2klEQVRIS62V8TkDURDEZyughKhAVEAqQAXoICoQFaACOkAFkgpEB1EBKhjf7+zL90SORG7/SXLZN7M7s/su1BK2tyUdSupVKTNJk4jgc6WIxSzbAF5JOvoF4UHSZURM/2L5RmD7VNJtHvqQtAWQpAtJj9lReU7aWUTc/UYyJ7A9zMpfJEH0JOkmIka2LWkgqZ9kfAd4NzsZtZE0BLaR414S4AeSIDuNiJ5tQJ9LtbbR/y6Jx5L2JR1HBLL9iELAIUwFjANUVJu7eJB8ciaS8OEtInaWElS6kwgoRATaU+F7dnCeYBTBEBD8BxnPlvoRttHyRBLmIQ0HniKi9geiYZka283vBMYvYoxsi11AUCrvM9+2SWr0/2sEV/kfAiaEVstMA8xIXqc0RbJV8EoOeHsUXAiQpyagbaaJ+ceLdYICkZxFHEGA5ixUw5gSoXFDUHuxCottzrFDc4JiMm1h3GsCdUZQlgxg9KYbNrUbgtzkspEAoyG/8WFziZKgXAcYzcJM04tuCJKk3KTNiHXaQZmOnAAuLXzpzoN6/PJNxiMmij2AaJ1Abpb0a0zbTlbzvA54nTuIiHErQWX+f66KWXlvLyWwTYu8rTaNSRsBF2An0UbAFGHWpjH9BL0Y7d/fY0bVAAAAAElFTkSuQmCC"/>
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">
<div class="ui-controlgroup-controls">
<a href="#" class="ui-btn ui-btn-icon-notext ui-icon-home" data-i18n="Home">Home</a>
</div>
</div>
</div>
</script>
<script id="panel-template-body" type="text/x-handlebars-template">
<div class="ui-content">
<ul data-role="listview" class="ui-listview">
<li><a href="#page=status_list"><i class="fa fa-th-list"></i><span data-i18n="Promises Status">Promises Status</span></a></li>
<li><a href="#page=software_instance_list"><i class="fa fa-cube"></i><span data-i18n="Software Instances">Software Instances</span></a></li>
<li><a href="#page=hosting_subscription_list"><i class="fa fa-globe"></i><span data-i18n="Hosting Subscriptions">Hosting Subscriptions</span></a></li>
<li><a href="#page=settings_configurator"><i class="fa fa-cog"></i><span data-i18n="Monitoring Configuration">Monitoring Configuration</span></a></li>
<li><a href="#page=import_export"><i class="fa fa-exchange"></i><span data-i18n="Import / Export">Import / Export</span></a></li>
</ul>
</div>
</script>
<!-- custom script -->
<script src="gadget_monitoring_application_panel.js" type="text/javascript"></script>
</head>
<body>
<div class="jqm-navmenu-panel"></div>
</body>
</html>
\ No newline at end of file
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, rJS, Handlebars, jQuery, RSVP, loopEventListener */
(function (window, rJS, Handlebars, $, RSVP, loopEventListener) {
"use strict";
var gadget_klass = rJS(window),
source_header = gadget_klass.__template_element
.getElementById("panel-template-header")
.innerHTML,
panel_template_header = Handlebars.compile(source_header),
source_body = gadget_klass.__template_element
.getElementById("panel-template-body")
.innerHTML,
panel_template_body = Handlebars.compile(source_body);
gadget_klass
.declareAcquiredMethod("translateHtml", "translateHtml")
// Assign the element to a variable
// Init local properties
.ready(function (g) {
g.props = {};
})
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.jelement = $(element.querySelector("div"));
});
})
.ready(function (g) {
g.props.jelement.panel({
display: "overlay",
position: "left",
theme: "b"
// animate: false
});
})
.ready(function (g) {
/*return g.translateHtml(panel_template_header() + panel_template_body())
.push(function (my_translated_or_plain_html) {
g.props.jelement.html(my_translated_or_plain_html);
g.props.jelement.trigger("create");
});*/
var plain_html = panel_template_header() + panel_template_body();
g.props.jelement.html(plain_html);
g.props.jelement.trigger("create");
})
.declareMethod('toggle', function () {
this.props.jelement.panel("toggle");
})
.declareMethod('close', function () {
this.props.jelement.panel("close");
})
.declareMethod('render', function () {
return;
})
/////////////////////////////////////////////////////////////////
// declared services
/////////////////////////////////////////////////////////////////
.declareService(function () {
var panel_gadget,
form_list,
event_list,
i,
len;
function formSubmit() {
panel_gadget.toggle();
}
panel_gadget = this;
form_list = panel_gadget.props.element.querySelectorAll('form');
event_list = [];
// XXX: not robust - Will break when search field is active
for (i = 0, len = form_list.length; i < len; i += 1) {
event_list[i] = loopEventListener(
form_list[i],
'submit',
false,
formSubmit
);
}
return new RSVP.Queue()
.push(function () {
return RSVP.all(event_list);
});
});
}(window, rJS, Handlebars, jQuery, RSVP, loopEventListener));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Monitoring Breadcrumb</title>
<!-- renderjs -->
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script id="breadcrumb-template" type="text/x-handlebars-template">
{{#if icon }}
<i class="fa fa-{{icon}}" aria-hidden="true"></i>
{{/if}}
{{#each url_list}}
{{#if url }}
<span><a href="{{url}}" title="{{title}}">{{title}}</a></span><span>&gt;</span>
{{else}}
<span>{{ title }}</span>
{{/if}}
{{/each}}
</script>
<!-- custom script -->
<script src="gadget_monitoring_breadcrumb.js" type="text/javascript"></script>
</head>
<body>
<div class="monitoring-breadcrumb"></div>
</body>
</html>
\ No newline at end of file
/*global document, window, rJS, Handlebars */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, document, rJS, Handlebars) {
"use strict";
var gadget_klass = rJS(window),
templater = gadget_klass.__template_element,
breadcrumb_template = Handlebars.compile(
templater.getElementById("breadcrumb-template").innerHTML
);
gadget_klass
.declareMethod("render", function (options) {
var gadget = this,
i,
content;
if (options.url_list === undefined) {
options.url_list = [];
}
content = breadcrumb_template({
url_list: options.url_list,
icon: options.icon || ''
});
gadget.element.querySelector('.monitoring-breadcrumb')
.innerHTML = content;
return;
});
}(window, document, rJS, Handlebars));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Monitoring Document Edit Page</title>
<link rel="stylesheet" href="magnific-popup.css">
<link href="gadget_monitoring_custom.css" rel="stylesheet" type="text/css"/>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script id="login-toltip-template" type="text/x-handlebars-template">
</script>
<!-- magnific-popup -->
<script src="jquery.magnific-popup.min.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_monitoring_document_edit.js" type="text/javascript"></script>
</head>
<body>
<div data-gadget-url="gadget_monitoring_jio.html" data-gadget-scope="jio_gadget" data-gadget-sandbox="public"></div>
<div data-gadget-url="gadget_monitoring_login_widget.html" data-gadget-scope="login_gadget" data-gadget-sandbox="public"></div>
<div class="white-popup mfp-hide">
<div class="ui-promise-title"><h2 style="font-size: 1.1em;"></h2></div>
<form>
<div data-role="content">
<div class="form-controlgroup">
</div>
</div>
<div class="padding-5">
<span class="ui-text-error"></span>
</div>
<div>
<button type="button" class="ui-btn ui-corner-all ui-btn-inline cancel"><i class="fa fa-times"></i> Cancel</button>
<button type="submit" class="ui-btn ui-corner-all ui-btn-inline save"><i class="fa fa-floppy-o"></i> Save</button>
<div class="ui-content-hidden spinner">
<i class="fa fa-spinner fa-spin"></i>
</div>
</div>
</form>
</div>
</body>
</html>
\ No newline at end of file
/*global document, window, rJS, $ */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, document, rJS, $) {
"use strict";
var gadget_klass = rJS(window),
templater = gadget_klass.__template_element,
hashCode = new Rusha().digestFromString;
/*function getHtmlFromJson(parameter_list) {
var i,
html_content = '';
for (i = 0; i < parameter_list.length; i += 1) {
html_content += '<span class="label-text">' + parameter_list[i].title + ':</span>\n';
if (parameter_list[i].key) {
html_content += '<input type="text" name="' + parameter_list[i].key +
'" placeholder="' + parameter_list[i].title + '" value="' +
parameter_list[i].value +'" data-mini="true">\n';
} else {
html_content += '<input type="text" name="' + parameter_list[i].key +
'" placeholder="' + parameter_list[i].title + '" value="'+
parameter_list[i].value +'" data-mini="true" disabled="disabled">\n';
}
}
return html_content;
}
function getFormDataList(formElement, parameter_list) {
var i,
formData_list = [];
for (i = 0; i < parameter_list.length; i += 1) {
formData_list.push(parameter_list[i]);
if (parameter_list[i].key) {
// Editable fields
if (formElement.querySelector('input[name="' + parameter_list[i].key + '"]').value !== undefined) {
formData_list[i].value = formElement.querySelector('input[name="' + parameter_list[i].key + '"]').value;
}
}
}
return formData_list;
}
function saveDocument(gadget, jio_document) {
// Authenticate before save
return gadget.props.login_gadget.getUrlInfo(
hashCode(gadget.props.options.url)
)
.push(function (cred) {
var url = gadget.props.options.url;
if (gadget.props.options.path) {
url += (url.endsWith('/') ? '':'/') + gadget.props.options.path;
}
if (cred === undefined) {
cred = {};
}
gadget.props.jio_gadget.createJio({
type: "query",
sub_storage: {
type: "drivetojiomapping",
sub_storage: {
type: "dav",
url: url,
basic_login: cred.hash
}
}
}, false);
return gadget.props.jio_gadget.put(gadget.props.options.key, jio_document);
})
.push(function (result) {
return {status: 'OK'};
}, function (error) {
console.log(error);
return {status: 'ERROR', code: error.target.status};
});
}*/
gadget_klass
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.deferred = RSVP.defer();
});
})
.ready(function (gadget) {
return gadget.getDeclaredGadget("jio_gadget")
.push(function (jio_gadget) {
gadget.props.jio_gadget = jio_gadget;
});
})
.ready(function (gadget) {
return gadget.getDeclaredGadget("login_gadget")
.push(function (login_gadget) {
gadget.props.login_gadget = login_gadget;
});
})
.declareMethod("render", function (options) {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.deferred.resolve();
});
})
.declareMethod("popupEdit", function (options, updateMethod) {
var gadget = this,
title = 'Edit ' + (options.title || 'Monitoring Parameters'),
html_form = '';
gadget.props.options = options;
/*html_form = getHtmlFromJson(options.parameters || []);
gadget.props.element.querySelector('.form-controlgroup')
.innerHTML = html_form;
gadget.props.element.querySelector('.ui-promise-title h2')
.innerHTML = title;*/
return new RSVP.Queue()
/*.push(function () {
return $.magnificPopup.open({
items: {
src: '.white-popup',
type: 'inline'
},
closeBtnInside: true,
callbacks: {
open: function() {
return new RSVP.Queue()
.push(function () {
return $('.white-popup form').trigger("create");
})
.push(function () {
var promise_list = [];
promise_list.push(loopEventListener(
document.querySelector('.mfp-content form .cancel'),
'click',
false,
function (evt) {
return $.magnificPopup.close();
}
));
promise_list.push(loopEventListener(
document.querySelector('.mfp-content form .save'),
'click',
false,
function (evt) {
var data = getFormDataList(document.querySelector('.mfp-content form'), options.parameters);
return new RSVP.Queue()
.push(function () {
$(document.querySelector('.mfp-content spinner')).toggleClass('ui-content-hidden');
return RSVP.all([saveDocument(gadget, data)]);
})
.push(function (result) {
if (result[0].status === 'ERROR') {
document.querySelector('.mfp-content .ui-text-error')
.innerHTML = 'ERROR ' + result[0].code + ': Failed to save your document! ' +
"Parameters cannot be saved in Offline mode.";
} else {
$.magnificPopup.close();
return updateMethod(data);}
})
.push(function () {
$(document.querySelector('.mfp-content spinner')).toggleClass('ui-content-hidden');
});
}
));
return RSVP.all(promise_list);
});
},
close: function() {
// Will fire when popup is closed
$('.white-popup').remove();
}
}
});
})*/
.push(function () {
return gadget.props.deferred.resolve();
});
})
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.deferred.promise;
})
.push(function () {
});
});
}(window, document, rJS, $));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>OfficeJS Header</title>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_monitoring_header.js" type="text/javascript"></script>
<script id="header-title-link-template" type="text/x-handlebars-template"><a data-i18n="{{title}}" class="ui-btn ui-btn-icon-left ui-icon-arrow-down" href="{{url}}">{{title}}</a></script>
<script id="header-title-template" type="text/x-handlebars-template"><span data-i18n="{{title}}" class="ui-title-bold">{{title}}</span></script>
<script id="header-link-template" type="text/x-handlebars-template">
{{#if url}}
<a role="button" data-i18n="{{title}}" href="{{url}}" class="responsive ui-btn ui-icon-{{icon}} ui-btn-icon-left ui-first-child ui-last-child {{class}}">{{title}}</a>
{{else}}
<button data-i18n="{{title}}" class='responsive ui-btn ui-icon-{{icon}} ui-btn-icon-left ui-first-child ui-last-child {{class}}'>{{title}}</button>
{{/if}}
</script>
<script id="header-button-template" type="text/x-handlebars-template">
<form><button name='{{name}}' data-i18n="{{title}}" type='submit' class='responsive ui-btn ui-icon-{{icon}} ui-btn-icon-left ui-first-child ui-last-child {{class}}'>{{title}}</button></form>
</script>
</head>
<body>
<div data-gadget-url="gadget_monitoring_sync.html" data-gadget-scope="sync_gadget" data-gadget-sandbox="public"></div>
<!--div data-role="header" data-theme="a" class="ui-header ui-bar-a" data-position="fixed" data-tap-toggle="false"-->
<div data-role="header" data-position="fixed" data-theme="a" class="ui-header ui-bar-a" data-tap-toggle="false">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-left">
<div class="ui-controlgroup-controls">
</div>
</div>
<h1 class="ui-title"></h1>
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">
<div class="ui-controlgroup-controls">
</div>
</div>
</div>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment