[Libreoffice-commits] online.git: loleaflet/build loleaflet/dist

Pranav Kant pranavk at collabora.com
Mon Mar 21 14:33:47 UTC 2016


 loleaflet/build/build.js                 |    2 
 loleaflet/dist/admin.html                |  128 -----
 loleaflet/dist/admin/admin-src.js        |  710 +++++++++++++++++++++++++++++++
 loleaflet/dist/admin/admin.html          |  129 +++++
 loleaflet/dist/admin/adminAnalytics.html |  100 ++++
 loleaflet/dist/admin/adminSettings.html  |  107 ++++
 6 files changed, 1047 insertions(+), 129 deletions(-)

New commits:
commit 3a09c992f71f5dfee12386f289c520737c224436
Author: Pranav Kant <pranavk at collabora.com>
Date:   Sun Mar 20 19:26:20 2016 +0530

    loleaflet: Move admin console related files to dist/admin
    
    Better to put all admin related content in a separate directory
    rather than mixing it with other files in dist/
    
    Change-Id: I328ff95cf23251ff91bb438c3b9be923ccc2017f

diff --git a/loleaflet/build/build.js b/loleaflet/build/build.js
index db7e536..bf41ee2 100644
--- a/loleaflet/build/build.js
+++ b/loleaflet/build/build.js
@@ -121,7 +121,7 @@ exports.build = function (callback, version, compsBase32, buildName) {
 	// Also combine and copy the admin JS files
 	// TODO: Also minify if admin complexity increases in future
 	var adminNewSrc = combineFiles(getAdminFiles()),
-	    adminPath = 'dist/admin-src.js',
+	    adminPath = 'dist/admin/admin-src.js',
 	    adminOldSrc = loadSilently(adminPath);
 
 	if (adminNewSrc != adminOldSrc) {
diff --git a/loleaflet/dist/admin/admin-src.js b/loleaflet/dist/admin/admin-src.js
new file mode 100644
index 0000000..26de51f
--- /dev/null
+++ b/loleaflet/dist/admin/admin-src.js
@@ -0,0 +1,710 @@
+/*
+	Base.js, version 1.1a
+	Copyright 2006-2010, Dean Edwards
+	License: http://www.opensource.org/licenses/mit-license.php
+*/
+
+var Base = function() {
+	// dummy
+};
+
+Base.extend = function(_instance, _static) { // subclass
+	var extend = Base.prototype.extend;
+
+	// build the prototype
+	Base._prototyping = true;
+	var proto = new this;
+	extend.call(proto, _instance);
+  proto.base = function() {
+    // call this method from any other method to invoke that method's ancestor
+  };
+	delete Base._prototyping;
+
+	// create the wrapper for the constructor function
+	//var constructor = proto.constructor.valueOf(); //-dean
+	var constructor = proto.constructor;
+	var klass = proto.constructor = function() {
+		if (!Base._prototyping) {
+			if (this._constructing || this.constructor == klass) { // instantiation
+				this._constructing = true;
+				constructor.apply(this, arguments);
+				delete this._constructing;
+			} else if (arguments[0] != null) { // casting
+				return (arguments[0].extend || extend).call(arguments[0], proto);
+			}
+		}
+	};
+
+	// build the class interface
+	klass.ancestor = this;
+	klass.extend = this.extend;
+	klass.forEach = this.forEach;
+	klass.implement = this.implement;
+	klass.prototype = proto;
+	klass.toString = this.toString;
+	klass.valueOf = function(type) {
+		//return (type == "object") ? klass : constructor; //-dean
+		return (type == "object") ? klass : constructor.valueOf();
+	};
+	extend.call(klass, _static);
+	// class initialisation
+	if (typeof klass.init == "function") klass.init();
+	return klass;
+};
+
+Base.prototype = {
+	extend: function(source, value) {
+		if (arguments.length > 1) { // extending with a name/value pair
+			var ancestor = this[source];
+			if (ancestor && (typeof value == "function") && // overriding a method?
+				// the valueOf() comparison is to avoid circular references
+				(!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
+				/\bbase\b/.test(value)) {
+				// get the underlying method
+				var method = value.valueOf();
+				// override
+				value = function() {
+					var previous = this.base || Base.prototype.base;
+					this.base = ancestor;
+					var returnValue = method.apply(this, arguments);
+					this.base = previous;
+					return returnValue;
+				};
+				// point to the underlying method
+				value.valueOf = function(type) {
+					return (type == "object") ? value : method;
+				};
+				value.toString = Base.toString;
+			}
+			this[source] = value;
+		} else if (source) { // extending with an object literal
+			var extend = Base.prototype.extend;
+			// if this object has a customised extend method then use it
+			if (!Base._prototyping && typeof this != "function") {
+				extend = this.extend || extend;
+			}
+			var proto = {toSource: null};
+			// do the "toString" and other methods manually
+			var hidden = ["constructor", "toString", "valueOf"];
+			// if we are prototyping then include the constructor
+			var i = Base._prototyping ? 0 : 1;
+			while (key = hidden[i++]) {
+				if (source[key] != proto[key]) {
+					extend.call(this, key, source[key]);
+
+				}
+			}
+			// copy each of the source object's properties to this object
+			for (var key in source) {
+				if (!proto[key]) extend.call(this, key, source[key]);
+			}
+		}
+		return this;
+	}
+};
+
+// initialise
+Base = Base.extend({
+	constructor: function() {
+		this.extend(arguments[0]);
+	}
+}, {
+	ancestor: Object,
+	version: "1.1",
+
+	forEach: function(object, block, context) {
+		for (var key in object) {
+			if (this.prototype[key] === undefined) {
+				block.call(context, object[key], key, object);
+			}
+		}
+	},
+
+	implement: function() {
+		for (var i = 0; i < arguments.length; i++) {
+			if (typeof arguments[i] == "function") {
+				// if it's a function, call it
+				arguments[i](this.prototype);
+			} else {
+				// add the interface using the extend method
+				this.prototype.extend(arguments[i]);
+			}
+		}
+		return this;
+	},
+
+	toString: function() {
+		return String(this.valueOf());
+	}
+});
+
+
+
+/*
+	Utility class
+*/
+/* global Base */
+var Util = Base.extend({
+	constructor: null
+
+}, { // class itnerface
+
+	humanize: function humanFileSize(kbytes) {
+		var unit = 1000;
+		var units = ['kB', 'MB', 'GB', 'TB'];
+		for (var i = 0; Math.abs(kbytes) >= unit && i < units.length; i++) {
+			kbytes /= unit;
+		}
+
+		return kbytes.toFixed(1) + ' ' + units[i];
+	}
+});
+
+
+/*
+	Abstract class
+*/
+
+/* global vex Base */
+/* exported AdminSocketBase */
+var AdminSocketBase = Base.extend({
+	socket: null,
+
+	constructor: function(host) {
+		// because i am abstract
+		if (this.constructor === AdminSocketBase) {
+			throw new Error('Cannot instantiate abstract class');
+		}
+
+		// We do not allow such child class to instantiate websocket that do not implement
+		// onSocketMessage and onSocketOpen.
+		if (typeof this.onSocketMessage === 'function' && typeof this.onSocketOpen === 'function') {
+			this.socket = new WebSocket(host);
+			this.socket.onopen = this.onSocketOpen.bind(this);
+			this.socket.onclose = this.onSocketClose.bind(this);
+			this.socket.onmessage = this.onSocketMessage.bind(this);
+			this.socket.onerror = this.onSocketError.bind(this);
+			this.socket.binaryType = 'arraybuffer';
+		}
+	},
+
+	onSocketOpen: function() {
+		/* Implemented by child */
+	},
+
+	onSocketMessage: function() {
+		/* Implemented by child */
+	},
+
+	onSocketClose: function() {
+		this.socket.onerror = function() {};
+		this.socket.onclose = function() {};
+		this.socket.onmessage = function() {};
+		this.socket.close();
+	},
+
+	onSocketError: function() {
+		vex.dialog.alert('Connection error');
+	}
+});
+
+
+/*
+	Socket to be intialized on opening the overview page in Admin console
+*/
+/* global vex $ Util AdminSocketBase */
+var AdminSocketOverview = AdminSocketBase.extend({
+	constructor: function(host) {
+		this.base(host);
+	},
+
+	_basicStatsIntervalId: 0,
+
+	_getBasicStats: function() {
+		this.socket.send('total_mem');
+		this.socket.send('active_docs_count');
+		this.socket.send('active_users_count');
+	},
+
+	onSocketOpen: function() {
+		this.socket.send('documents');
+		this.socket.send('subscribe document addview rmview rmdoc');
+
+		this._getBasicStats();
+		var socketOverview = this;
+		this._basicStatsIntervalId =
+		setInterval(function() {
+			return socketOverview._getBasicStats();
+		}, 5000);
+
+		// Allow table rows to have a context menu for killing children
+		$('body').on('contextmenu', 'table tr', function(ev) {
+			$('#rowContextMenu').css({
+				display: 'block',
+				left: ev.pageX,
+				top: ev.pageY
+			})
+			.data('rowToKill', ev.target.parentElement.id);
+
+			return false;
+		})
+		.click(function() {
+			$('#rowContextMenu').hide();
+		});
+
+		$('#rowContextMenu').on('click', 'a', function() {
+			vex.dialog.confirm({
+				message: 'Are you sure you want to kill this child ?',
+				callback: function(value) {
+					if (value) {
+						var killPid = ($('#rowContextMenu').data('rowToKill')).substring('doc'.length);
+						socketOverview.socket.send('kill ' + killPid);
+					}
+					$('#rowContextMenu').hide();
+				}
+			});
+		});
+	},
+
+	onSocketMessage: function(e) {
+		var textMsg;
+		if (typeof e.data === 'string') {
+			textMsg = e.data;
+		}
+		else {
+			textMsg = '';
+		}
+
+		var tableContainer = document.getElementById('doclist');
+		var rowContainer;
+		var pidEle, urlEle, viewsEle, memEle, docEle;
+		var nViews, nTotalViews;
+		var docProps, sPid, sUrl, sViews, sMem;
+		if (textMsg.startsWith('documents')) {
+			var documents = textMsg.substring('documents'.length);
+			documents = documents.trim().split('\n');
+			for (var i = 0; i < documents.length; i++) {
+				if (documents[i] === '') {
+					continue;
+				}
+				docProps = documents[i].trim().split(' ');
+				sPid = docProps[0];
+				sUrl = docProps[1];
+				sViews = docProps[2];
+				sMem = docProps[3];
+				if (sUrl === '0') {
+					continue;
+				}
+				rowContainer = document.createElement('tr');
+				rowContainer.id = 'doc' + sPid;
+				tableContainer.appendChild(rowContainer);
+
+				pidEle = document.createElement('td');
+				pidEle.innerHTML = sPid;
+				rowContainer.appendChild(pidEle);
+
+				urlEle = document.createElement('td');
+				urlEle.innerHTML = sUrl;
+				rowContainer.appendChild(urlEle);
+
+				viewsEle = document.createElement('td');
+				viewsEle.id = 'docview' + sPid;
+				viewsEle.innerHTML = sViews;
+				rowContainer.appendChild(viewsEle);
+
+				memEle = document.createElement('td');
+				memEle.innerHTML = Util.humanize(parseInt(sMem));
+				rowContainer.appendChild(memEle);
+			}
+		}
+		else if (textMsg.startsWith('addview')) {
+			sPid = textMsg.substring('addview'.length).trim().split(' ')[0];
+			nViews = parseInt(document.getElementById('docview' + sPid).innerHTML);
+			document.getElementById('docview' + sPid).innerHTML = nViews + 1;
+			nTotalViews = parseInt(document.getElementById('active_users_count').innerHTML);
+			document.getElementById('active_users_count').innerHTML = nTotalViews + 1;
+		}
+		else if (textMsg.startsWith('rmview')) {
+			sPid = textMsg.substring('addview'.length).trim().split(' ')[0];
+			nViews = parseInt(document.getElementById('docview' + sPid).innerHTML);
+			document.getElementById('docview' + sPid).innerHTML = nViews - 1;
+			nTotalViews = parseInt(document.getElementById('active_users_count').innerHTML);
+			document.getElementById('active_users_count').innerHTML = nTotalViews - 1;
+		}
+		else if (textMsg.startsWith('document')) {
+			textMsg = textMsg.substring('document'.length);
+			docProps = textMsg.trim().split(' ');
+			sPid = docProps[0];
+			sUrl = docProps[1];
+			sMem = docProps[2];
+
+			docEle = document.getElementById('doc' + sPid);
+			if (docEle) {
+				tableContainer.removeChild(docEle);
+			}
+			if (sUrl === '0') {
+				return;
+			}
+
+			rowContainer = document.createElement('tr');
+			rowContainer.id = 'doc' + docProps[0];
+			tableContainer.appendChild(rowContainer);
+
+			pidEle = document.createElement('td');
+			pidEle.innerHTML = docProps[0];
+			rowContainer.appendChild(pidEle);
+
+			urlEle = document.createElement('td');
+			urlEle.innerHTML = docProps[1];
+			rowContainer.appendChild(urlEle);
+
+			viewsEle = document.createElement('td');
+			viewsEle.innerHTML = 0;
+			viewsEle.id = 'docview' + docProps[0];
+			rowContainer.appendChild(viewsEle);
+
+			memEle = document.createElement('td');
+			memEle.innerHTML = Util.humanize(parseInt(sMem));
+			rowContainer.appendChild(memEle);
+
+			var totalUsersEle = document.getElementById('active_docs_count');
+			totalUsersEle.innerHTML = parseInt(totalUsersEle.innerHTML) + 1;
+		}
+		else if (textMsg.startsWith('total_mem') ||
+			textMsg.startsWith('active_docs_count') ||
+			textMsg.startsWith('active_users_count'))
+		{
+			textMsg = textMsg.split(' ');
+			var sCommand = textMsg[0];
+			var nData = parseInt(textMsg[1]);
+
+			if (sCommand === 'total_mem') {
+				nData = Util.humanize(nData);
+			}
+			document.getElementById(sCommand).innerHTML = nData;
+		}
+		else if (textMsg.startsWith('rmdoc')) {
+			textMsg = textMsg.substring('rmdoc'.length);
+			docProps = textMsg.trim().split(' ');
+			sPid = docProps[0];
+			docEle = document.getElementById('doc' + sPid);
+			if (docEle) {
+				tableContainer.removeChild(docEle);
+			}
+		}
+	},
+
+	onSocketClose: function() {
+		clearInterval(this._basicStatsIntervalId);
+	}
+});
+
+
+/*
+	Socket to be intialized on opening the analytics page in Admin console
+	containing various graphs to show to the user on specified interval
+*/
+
+/* global d3 Util AdminSocketBase */
+var AdminSocketAnalytics = AdminSocketBase.extend({
+	constructor: function(host) {
+		this.base(host);
+	},
+
+	_memStatsData: [],
+	_cpuStatsData: [],
+
+	_memStatsSize: 0,
+	_memStatsInterval: 0,
+
+	_cpuStatsSize: 0,
+	_cpuStatsInterval: 0,
+
+	_initMemStatsData: function(memStatsSize, memStatsInterval, reset) {
+		if (reset) {
+			this._memStatsData = [];
+		}
+
+		var offset = this._memStatsData.length * memStatsInterval;
+		for (var i = 0; i < memStatsSize; i++) {
+			this._memStatsData.unshift({time: -(offset), value: 0});
+			offset += memStatsInterval;
+		}
+	},
+
+	_initCpuStatsData: function() {
+		for (var i = 0; i < this._cpuStatsSize; i++) {
+			this._cpuStatsData.push({time: -((this._cpuStatsSize - i - 1) * this._cpuStatsInterval), value: 0});
+		}
+	},
+
+	onSocketOpen: function() {
+		this.socket.send('subscribe mem_stats cpu_stats settings');
+		this.socket.send('settings');
+		this.socket.send('mem_stats');
+	},
+
+	_createMemData: function() {
+		for (var i = this._memStatsRawData.length - 1, j = this._memStatsData.length - 1; i >= 0 && j >= 0; i--, j--) {
+			this._memStatsData[j].value = parseInt(this._memStatsRawData[i]);
+		}
+	},
+
+	_d3xAxis: null,
+	_d3yAxis: null,
+	_d3line: null,
+	_xScale: null,
+	_yScale: null,
+
+	_graphWidth: 1000,
+	_graphHeight: 500,
+	_graphMargins: {
+		top: 20,
+		right: 20,
+		bottom: 20,
+		left: 100
+	},
+
+	_setUpAxis: function() {
+		this._xScale = d3.scale.linear().range([this._graphMargins.left, this._graphWidth - this._graphMargins.right]).domain([d3.min(this._memStatsData, function(d) {
+				return d.time;
+			}), d3.max(this._memStatsData, function(d) {
+				return d.time;
+			})]);
+
+
+		this._yScale = d3.scale.linear().range([this._graphHeight - this._graphMargins.bottom, this._graphMargins.top]).domain([d3.min(this._memStatsData, function(d) {
+			return d.value;
+		}), d3.max(this._memStatsData, function(d) {
+			return d.value;
+		})]);
+
+		this._d3xAxis = d3.svg.axis()
+			.scale(this._xScale)
+			.tickFormat(function(d) {
+				d = Math.abs(d / 1000);
+				var units = ['s', 'min', 'hr'];
+				for (var i = 0; i < units.length && Math.abs(d) >= 60; i++) {
+					d = parseInt(d / 60);
+				}
+				return parseInt(d) + units[i] + ' ago';
+			});
+
+		this._d3yAxis = d3.svg.axis()
+			.scale(this._yScale)
+			.tickFormat(function (d) {
+				return Util.humanize(d);
+			})
+			.orient('left');
+
+		var xScale = this._xScale;
+		var yScale = this._yScale;
+
+		this._d3line = d3.svg.line()
+			.x(function(d) {
+				return xScale(d.time);
+			})
+			.y(function(d) {
+				return yScale(d.value);
+			});
+	},
+
+	_createMemGraph: function() {
+		var vis = d3.select('#visualisation');
+
+		this._setUpAxis();
+
+		vis.append('svg:g')
+		.attr('class', 'x-axis')
+		.attr('transform', 'translate(0,' + (this._graphHeight - this._graphMargins.bottom) + ')')
+		.call(this._d3xAxis);
+
+		vis.append('svg:g')
+		.attr('class', 'y-axis')
+		.attr('transform', 'translate(' + this._graphMargins.left + ',0)')
+		.call(this._d3yAxis);
+
+		vis.append('svg:path')
+			.attr('d', this._d3line(this._memStatsData))
+			.attr('class', 'line')
+			.attr('stroke', 'blue')
+			.attr('stroke-width', 2)
+			.attr('fill', 'none');
+	},
+
+	_addNewMemData: function(data) {
+		// make a space for new data
+		for (var i = this._memStatsData.length - 1; i > 0; i--) {
+			this._memStatsData[i].time = this._memStatsData[i - 1].time;
+		}
+
+		// push new data at time '0'
+		this._memStatsData.push({time: 0, value: parseInt(data)});
+
+		// remove extra items
+		if (this._memStatsData.length > this._memStatsSize) {
+			this._memStatsData.shift();
+		}
+	},
+
+	_updateMemGraph: function() {
+		var svg = d3.select('#visualisation');
+
+		this._setUpAxis();
+
+		svg.select('.line')
+		.attr('d', this._d3line(this._memStatsData));
+
+		svg.select('.x-axis')
+		.call(this._d3xAxis);
+
+		svg.select('.y-axis')
+		.call(this._d3yAxis);
+	},
+
+	onSocketMessage: function(e) {
+		var textMsg;
+		if (typeof e.data === 'string') {
+			textMsg = e.data;
+		}
+		else {
+			textMsg = '';
+		}
+
+
+		if (textMsg.startsWith('settings')) {
+			textMsg = textMsg.substring('settings '.length);
+			textMsg = textMsg.split(' ');
+
+			//TODO: Add CPU statistics
+			var memStatsSize, memStatsInterval, cpuStatsSize, cpuStatsInterval;
+			var i, j, data;
+			memStatsSize = this._memStatsSize;
+			memStatsInterval = this._memStatsInterval;
+			cpuStatsSize = this._cpuStatsSize;
+			cpuStatsInterval = this._cpuStatsInterval;
+			for (i = 0; i < textMsg.length; i++) {
+				var setting = textMsg[i].split('=');
+				if (setting[0] === 'mem_stats_size') {
+					memStatsSize = parseInt(setting[1]);
+				}
+				else if (setting[0] === 'mem_stats_interval') {
+					memStatsInterval = parseInt(setting[1]);
+				}
+				else if (setting[0] === 'cpu_stats_size') {
+					cpuStatsSize = parseInt(setting[1]);
+				}
+				else if (setting[0] === 'cpu_stats_interval') {
+					cpuStatsInterval = parseInt(setting[1]);
+				}
+			}
+
+			// Fix the axes according to changed data
+			if (memStatsInterval !== this._memStatsInterval) {
+				// We can possibly reuse the data with a bit of work
+				this._initMemStatsData(memStatsSize, memStatsInterval, true);
+			}
+			else if (memStatsSize > this._memStatsSize) {
+				this._initMemStatsData(memStatsSize - this._memStatsSize, memStatsInterval, false);
+			}
+			else {
+				// just strip the extra items
+				for (i = 0; i < this._memStatsSize - memStatsSize; i++) {
+					this._memStatsData.shift();
+				}
+			}
+
+			this._memStatsSize = memStatsSize;
+			this._memStatsInterval = memStatsInterval;
+			this._cpuStatsSize = cpuStatsSize;
+			this._cpuStatsInterval = cpuStatsInterval;
+		}
+		else if (textMsg.startsWith('mem_stats') ||
+			textMsg.startsWith('cpu_stats')) {
+			textMsg = textMsg.split(' ')[1];
+			if (textMsg.endsWith(',')) {
+				// This is the result of query, not notification
+				data = textMsg.substring(0, textMsg.length - 1).split(',');
+				for (i = this._memStatsData.length - 1, j = data.length - 1; i >= 0 && j >= 0; i--, j--) {
+					this._memStatsData[i].value = parseInt(data[j]);
+				}
+
+				//this._createMemData(data);
+				this._createMemGraph();
+			}
+			else {
+				// this is a notification data; append to _memStatsData
+				data = textMsg.trim();
+				this._addNewMemData(data);
+				this._updateMemGraph();
+			}
+		}
+	},
+
+	onSocketClose: function() {
+		clearInterval(this._basicStatsIntervalId);
+	}
+});
+
+
+/*
+	Socket to be intialized on opening the settings page in Admin console
+*/
+/* global $ AdminSocketBase */
+var AdminSocketSettings = AdminSocketBase.extend({
+	constructor: function(host) {
+		this.base(host);
+		this._init();
+	},
+
+	_init: function() {
+		var socketSettings = this.socket;
+		$(document).ready(function() {
+			$('#admin_settings').on('submit', function(e) {
+				e.preventDefault();
+				var memStatsSize = $('#mem_stats_size').val();
+				var memStatsInterval = $('#mem_stats_interval').val();
+				var cpuStatsSize = $('#cpu_stats_size').val();
+				var cpuStatsInterval = $('#cpu_stats_interval').val();
+				var command = 'set';
+				command += ' mem_stats_size=' + memStatsSize;
+				command += ' mem_stats_interval=' + memStatsInterval;
+				command += ' cpu_stats_size=' + cpuStatsSize;
+				command += ' cpu_stats_interval=' + cpuStatsInterval;
+				socketSettings.send(command);
+			});
+		});
+	},
+
+	onSocketOpen: function() {
+		this.socket.send('subscribe settings');
+		this.socket.send('settings');
+	},
+
+    onSocketMessage: function(e) {
+		var textMsg;
+		if (typeof e.data === 'string') {
+			textMsg = e.data;
+		}
+		else {
+			textMsg = '';
+		}
+
+		if (textMsg.startsWith('settings')) {
+			textMsg = textMsg.substring('settings '.length);
+			var settings = textMsg.split(' ');
+			for (var i = 0; i < settings.length; i++) {
+				var setting = settings[i].split('=');
+				var settingKey = setting[0];
+				var settingVal = setting[1];
+				document.getElementById(settingKey).value = settingVal;
+			}
+		}
+	},
+
+	onSocketClose: function() {
+		clearInterval(this._basicStatsIntervalId);
+	}
+});
+
+
diff --git a/loleaflet/dist/admin.html b/loleaflet/dist/admin/admin.html
similarity index 50%
rename from loleaflet/dist/admin.html
rename to loleaflet/dist/admin/admin.html
index 806d54d..647b31b 100644
--- a/loleaflet/dist/admin.html
+++ b/loleaflet/dist/admin/admin.html
@@ -11,13 +11,16 @@
     <title>LibreOffice Online - Admin console</title>
 
     <!-- Bootstrap core CSS -->
-    <link href="/loleaflet/dist/bootstrap/css/bootstrap.min.css" rel="stylesheet">
+    <link href="../bootstrap/css/bootstrap.min.css" rel="stylesheet">
 
     <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
-    <link href="/loleaflet/dist/bootstrap/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
+    <link href="../bootstrap/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
 
     <!-- Custom styles for this template -->
-    <link href="/loleaflet/dist/bootstrap/dashboard.css" rel="stylesheet">
+    <link href="../bootstrap/dashboard.css" rel="stylesheet">
+
+    <link rel="stylesheet" href="../dialog/vex.css" />
+    <link rel="stylesheet" href="../dialog/vex-theme-plain.css" />
 
     <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
     <!--[if lt IE 9]>
@@ -27,58 +30,52 @@
   </head>
 
   <body>
-    <script src="/loleaflet/dist/admin-src.js"></script>
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
+    <script>window.jQuery || document.write('<script src="bootstrap/assets/js/vendor/jquery.min.js"><\/script>')</script>
+    <script src="../dialog/vex.combined.min.js"></script>
+    <script src="admin-src.js"></script>
+    <script>vex.defaultOptions.className = 'vex-theme-plain';</script>
     <script>
 
-	function getParameterByName(name) {
-		name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
-		var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
-		results = regex.exec(location.search);
-		return results === null ? "" : results[1].replace(/\+/g, " ");
-	}
-
-	var host = getParameterByName('host');
+	host = 'wss://' + window.location.hostname + ':9989';
 	new AdminSocketOverview(host);
 
     </script>
 
     <nav class="navbar navbar-inverse navbar-fixed-top">
       <div class="container-fluid">
-	<div class="navbar-header">
-	  <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
-	    <span class="sr-only">Toggle navigation</span>
-	    <span class="icon-bar"></span>
-	    <span class="icon-bar"></span>
-	    <span class="icon-bar"></span>
-	  </button>
-	  <a class="navbar-brand" href="#">LibreOffice Online - Admin console</a>
-	</div>
-	<div id="navbar" class="navbar-collapse collapse">
-	  <ul class="nav navbar-nav navbar-right">
-	    <li><a href="#">Dashboard</a></li>
-	    <li><a href="#">Settings</a></li>
-	    <li><a href="#">Profile</a></li>
-	    <li><a href="#">Help</a></li>
-	  </ul>
-	  <form class="navbar-form navbar-right">
-	    <input type="text" class="form-control" placeholder="Search...">
-	  </form>
-	</div>
+        <div class="navbar-header">
+          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
+            <span class="sr-only">Toggle navigation</span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+          </button>
+          <a class="navbar-brand" href="#">LibreOffice Online - Admin console</a>
+        </div>
+        <div id="navbar" class="navbar-collapse collapse">
+          <ul class="nav navbar-nav navbar-right">
+            <li><a href="admin.html">Dashboard</a></li>
+            <li><a href="adminSettings.html">Settings</a></li>
+            <li><a href="#">Help</a></li>
+          </ul>
+          <form class="navbar-form navbar-right">
+            <input type="text" class="form-control" placeholder="Search...">
+          </form>
+        </div>
       </div>
     </nav>
 
     <div class="container-fluid">
       <div class="row">
-	<div class="col-sm-3 col-md-2 sidebar">
-	  <ul class="nav nav-sidebar">
-	    <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
-	    <li><a href="#">Reports</a></li>
-	    <li><a href="#">Analytics</a></li>
-	    <li><a href="#">Export</a></li>
-	  </ul>
-	</div>
-	<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
-	  <h1 class="page-header">Dashboard</h1>
+        <div class="col-sm-3 col-md-2 sidebar">
+          <ul class="nav nav-sidebar">
+            <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
+            <li><a href="adminAnalytics.html">Analytics</a></li>
+          </ul>
+        </div>
+        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
+          <h1 class="page-header">Dashboard</h1>
 
 	  <div class="row placeholders">
 	    <div class="col-xs-6 col-sm-3 placeholder">
@@ -114,15 +111,19 @@
       </div>
     </div>
 
+    <div id="rowContextMenu" class="dropdown clearfix">
+      <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;">
+        <li><a tabindex="-1" href="#">Kill</a></li>
+      </ul>
+    </div>
+
     <!-- Bootstrap core JavaScript
     ================================================== -->
     <!-- Placed at the end of the document so the pages load faster -->
-    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
-    <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
-    <script src="../../dist/bootstrap/js/bootstrap.min.js"></script>
+    <script src="../bootstrap/js/bootstrap.min.js"></script>
     <!-- Just to make our placeholder images work. Don't actually copy the next line! -->
-    <script src="../../dist/bootstrap/assets/js/vendor/holder.min.js"></script>
+    <script src="../bootstrap/assets/js/vendor/holder.min.js"></script>
     <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
-    <script src="../../dist/bootstrap/assets/js/ie10-viewport-bug-workaround.js"></script>
+    <script src="../bootstrap/assets/js/ie10-viewport-bug-workaround.js"></script>
   </body>
 </html>
diff --git a/loleaflet/dist/admin/adminAnalytics.html b/loleaflet/dist/admin/adminAnalytics.html
new file mode 100644
index 0000000..5f4fb67
--- /dev/null
+++ b/loleaflet/dist/admin/adminAnalytics.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
+    <meta name="description" content="">
+    <meta name="author" content="">
+
+    <title>LibreOffice Online - Admin console</title>
+
+    <!-- Bootstrap core CSS -->
+    <link href="../bootstrap/css/bootstrap.min.css" rel="stylesheet">
+
+    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
+    <link href="../bootstrap/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
+
+    <!-- Custom styles for this template -->
+    <link href="../bootstrap/dashboard.css" rel="stylesheet">
+
+    <link rel="stylesheet" href="../dialog/vex.css" />
+    <link rel="stylesheet" href="../dialog/vex-theme-plain.css" />
+
+    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
+    <!--[if lt IE 9]>
+      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
+      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
+    <![endif]-->
+  </head>
+
+  <body>
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
+    <script>window.jQuery || document.write('<script src="../bootstrap/assets/js/vendor/jquery.min.js"><\/script>')</script>
+    <script src="../dialog/vex.combined.min.js"></script>
+    <script>vex.defaultOptions.className = 'vex-theme-plain';</script>
+    <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
+    <script src="admin-src.js"></script>
+    <script>
+
+	host = 'wss://' + window.location.hostname + ':9989';
+	new AdminSocketAnalytics(host);
+
+    </script>
+
+    <nav class="navbar navbar-inverse navbar-fixed-top">
+      <div class="container-fluid">
+        <div class="navbar-header">
+          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
+            <span class="sr-only">Toggle navigation</span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+          </button>
+          <a class="navbar-brand" href="#">LibreOffice Online - Admin console</a>
+        </div>
+        <div id="navbar" class="navbar-collapse collapse">
+          <ul class="nav navbar-nav navbar-right">
+	    <li><a href="admin.html?host=ws://localhost:9989">Dashboard</a></li>
+            <li><a href="adminSettings.html?host=ws://localhost:9989">Settings</a></li>
+            <li><a href="#">Help</a></li>
+          </ul>
+          <form class="navbar-form navbar-right">
+            <input type="text" class="form-control" placeholder="Search...">
+          </form>
+        </div>
+      </div>
+    </nav>
+
+    <div class="container-fluid">
+      <div class="row">
+        <div class="col-sm-3 col-md-2 sidebar">
+          <ul class="nav nav-sidebar">
+            <li><a href="admin.html">Overview <span class="sr-only">(current)</span></a></li>
+            <li class="active"><a href="adminAnalytics.html">Analytics</a></li>
+          </ul>
+        </div>
+        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
+          <h1 class="page-header">Graphs</h1>
+		        <div class="graph-container">
+		          <div class="jumbotron">
+		            <svg id="visualisation" width="1000" height="500"></svg>
+		          </div>
+		        </div>
+	      </div>
+      </div>
+    </div>
+
+    <!-- Bootstrap core JavaScript
+    ================================================== -->
+    <!-- Placed at the end of the document so the pages load faster -->
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
+    <script>window.jQuery || document.write('<script src="../bootstrap/js/vendor/jquery.min.js"><\/script>')</script>
+    <script src="../bootstrap/js/bootstrap.min.js"></script>
+    <!-- Just to make our placeholder images work. Don't actually copy the next line! -->
+    <script src="../bootstrap/assets/js/vendor/holder.min.js"></script>
+    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
+    <script src="../bootstrap/assets/js/ie10-viewport-bug-workaround.js"></script>
+  </body>
+</html>
diff --git a/loleaflet/dist/admin/adminSettings.html b/loleaflet/dist/admin/adminSettings.html
new file mode 100644
index 0000000..1db8279
--- /dev/null
+++ b/loleaflet/dist/admin/adminSettings.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
+    <meta name="description" content="">
+    <meta name="author" content="">
+
+    <title>LibreOffice Online - Admin console</title>
+
+    <!-- Bootstrap core CSS -->
+    <link href="../bootstrap/css/bootstrap.min.css" rel="stylesheet">
+
+    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
+    <link href="../bootstrap/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
+
+    <!-- Custom styles for this template -->
+    <link href="../bootstrap/dashboard.css" rel="stylesheet">
+
+    <link rel="stylesheet" href="../dialog/vex.css" />
+    <link rel="stylesheet" href="../dialog/vex-theme-plain.css" />
+
+    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
+    <!--[if lt IE 9]>
+      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
+      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
+    <![endif]-->
+  </head>
+
+  <body>
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
+    <script>window.jQuery || document.write('<script src="../bootstrap/assets/js/vendor/jquery.min.js"><\/script>')</script>
+    <script src="../dialog/vex.combined.min.js"></script>
+    <script>vex.defaultOptions.className = 'vex-theme-plain';</script>
+    <script src="admin-src.js"></script>
+    <script>
+
+	host = 'wss://' + window.location.hostname + ':9989';
+	new AdminSocketSettings(host);
+
+    </script>
+
+    <nav class="navbar navbar-inverse navbar-fixed-top">
+      <div class="container-fluid">
+        <div class="navbar-header">
+          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
+            <span class="sr-only">Toggle navigation</span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+          </button>
+          <a class="navbar-brand" href="#">LibreOffice Online - Admin console</a>
+        </div>
+        <div id="navbar" class="navbar-collapse collapse">
+          <ul class="nav navbar-nav navbar-right">
+            <li><a href="admin.html">Dashboard</a></li>
+            <li><a href="adminSettings.html">Settings</a></li>
+            <li><a href="#">Help</a></li>
+          </ul>
+          <form class="navbar-form navbar-right">
+            <input type="text" class="form-control" placeholder="Search...">
+          </form>
+        </div>
+      </div>
+    </nav>
+
+    <div class="container-fluid">
+      <div class="row">
+        <div class="col-sm-3 col-md-2 sidebar">
+          <ul class="nav nav-sidebar">
+            <li><a href="admin.html">Overview <span class="sr-only">(current)</span></a></li>
+            <li><a href="adminAnalytics.html">Analytics</a></li>
+          </ul>
+        </div>
+        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
+          <h1 class="page-header">Settings</h1>
+	  <form id="admin_settings">
+	    <label for="mem_stats_size">Memory Stats Cache size</label>
+	    <input type="text" id="mem_stats_size" name="Memory Stats Size"><br/>
+	    <label for="mem_stats_interval">Memory Stats Interval (in ms)</label>
+	    <input type="text" id="mem_stats_interval" name="Memory Stats Interval"><br/>
+
+	    <label for="cpu_stats_size">Cpu Stats Cache size</label>
+	    <input type="text" id="cpu_stats_size" name="Cpu Stats Size"><br/>
+	    <label for="cpu_stats_interval">Cpu Stats Interval (in ms)</label>
+	    <input type="text" id="cpu_stats_interval" name="Cpu Stats Interval"><br/>
+	    <input type="submit" value="Save"/><br/>
+	  </form>
+	</div>
+      </div>
+      </div>
+    </div>
+
+    <!-- Bootstrap core JavaScript
+    ================================================== -->
+    <!-- Placed at the end of the document so the pages load faster -->
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
+    <script>window.jQuery || document.write('<script src="../bootstrap/assets/js/vendor/jquery.min.js"><\/script>')</script>
+    <script src="../bootstrap/js/bootstrap.min.js"></script>
+    <!-- Just to make our placeholder images work. Don't actually copy the next line! -->
+    <script src="../bootstrap/assets/js/vendor/holder.min.js"></script>
+    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
+    <script src="../bootstrap/assets/js/ie10-viewport-bug-workaround.js"></script>
+  </body>
+</html>


More information about the Libreoffice-commits mailing list