aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Lyngstol <kly@kly.no>2019-01-07 00:05:59 +0100
committerKristian Lyngstol <kly@kly.no>2019-01-07 00:05:59 +0100
commited9e8db8f953f3064c3e21d9da75c0802f21ab1b (patch)
tree05f733cd7eb2b4edcdac7caa089bb4830e12bc2a
parent0bd74cf3010de984d36eed04b6318b7b30e25373 (diff)
More big stuff: Re-do the oplog
This is still a bit of a mess, but I'm establishing a new way of doing things, it'll be awesome, I swear...
-rw-r--r--web/index.html13
-rw-r--r--web/js/nms-oplog.js317
-rw-r--r--web/js/nms-types.js7
-rw-r--r--web/js/nms-ui-boxes.js123
-rw-r--r--web/js/nms.js6
5 files changed, 337 insertions, 129 deletions
diff --git a/web/index.html b/web/index.html
index acb0fbf..f89a612 100644
--- a/web/index.html
+++ b/web/index.html
@@ -86,17 +86,6 @@
</div>
</li>
</ul>
- <div class="navbar-form navbar-right gondul-is-private">
- <div class="form-group">
- <input id="logbox-id" type="text" size="8" class="form-control" oninput='var x = document.getElementById("searchbox"); var y = document.getElementById("logbox-id"); x.value = y.value; x.oninput();' placeholder="System(s)" />
- </div>
- <div class="form-group">
- <input id="logbox" type="text" size="30" class="form-control" placeholder="Log entry" />
- </div>
- <button id="logbox-submit" class="btn btn-default" type="button" onclick="nmsOplog.commit();">Log</button>
- </div>
- <p onclick="nmsOplog.getUser(true);" id="logbook-name" class="navbar-text navbar-right"></p>
-
</div><!--/.nav-collapse -->
</div>
</nav>
@@ -322,6 +311,7 @@
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/moment.min.js" type="text/javascript"></script>
<script src="js/Chart.min.js" type="text/javascript"></script>
+ <script type="text/javascript" src="js/nms-ui-boxes.js"></script>
<script type="text/javascript" src="js/nms-data.js"></script>
<script type="text/javascript" src="js/nms-map.js"></script>
<script type="text/javascript" src="js/nms-info-box.js"></script>
@@ -336,7 +326,6 @@
<script type="text/javascript" src="js/nms-dhcp.js"></script>
<script type="text/javascript" src="js/nms-template.js"></script>
<script type="text/javascript" src="js/nms-draw-chart.js"></script>
- <script type="text/javascript" src="js/nms-ui-boxes.js"></script>
<script type="text/javascript" src="js/nms-types.js"></script>
<script type="text/javascript" src="js/nms-ui-switch.js"></script>
<script src="js/jquery.datetimepicker.full.js" type="text/javascript"></script>
diff --git a/web/js/nms-oplog.js b/web/js/nms-oplog.js
index cea75ca..eb0fd28 100644
--- a/web/js/nms-oplog.js
+++ b/web/js/nms-oplog.js
@@ -1,26 +1,80 @@
"use strict";
+/*
+ * Please note: I've started moving this to a new and better way of doing
+ * things and it is by no means a finished move. This means that this file is a
+ * mess of two different styles at the time of this writing. Fix incomming.
+ */
var nmsOplog = nmsOplog || {
table: {}
}
-
-nmsOplog.init = function() {
- nmsData.addHandler("oplog", "nmsOplogHandler", nmsOplog.updateComments);
+nmsOplog.init = function() {
+ nms.oplog = new nmsOplog2()
}
-
-nmsOplog._reset = function() {
- document.getElementById('logbox-id').value = "";
- document.getElementById('logbox').value = "";
- document.getElementById('searchbox').value = "";
- document.getElementById('searchbox').oninput();
+nmsOplog.getSwitchLogs = function(sw) {
+ var logs = [];
+ if (nmsData.oplog == undefined || nmsData['oplog']['oplog'] == undefined)
+ return [];
+ for (var v in nmsData['oplog']['oplog']) {
+ var log = nmsData['oplog']['oplog'][v];
+ if (log['systems'] != "" && log['systems'] != undefined) {
+ if (nmsSearch.searchTest(log['systems'],sw)) {
+ logs.push(log);
+ }
+ }
+ }
+ return logs;
}
-nmsOplog.getUser = function(force) {
- if (force == undefined)
- force = false;
- var user = nms.user;
- if (user == undefined || force) {
- user = prompt("Who are you? Short nick for the record.");
+// New-style-work-in-progress follows
+class nmsOplog2 {
+ constructor() {
+ this.logger = new nmsOplogInput()
+ this.logger.attach("navbar")
+ this.logger.show()
+ this.mini = new nmsLogTable()
+ this.full = new nmsLogTable("full", "large",0,0);
+ this.mini.attach("oplog-parent-mini")
+ this.full.attach("oplog-parent")
+ this.mini.show()
+ this.full.show()
+ nmsData.addHandler("oplog", "nmsOplogHandler", this.updateComments,this);
+ }
+ updateComments(x) {
+ x.mini.update()
+ x.full.update()
+ }
+}
+class nmsOplogInput extends nmsBox {
+ constructor() {
+ super("div",{html:{class: "navbar-form", classList:["navbar-form","navbar-right","gondul-is-private"]}})
+ var systemParent = new nmsBox("div",{html:{class:"form-group",classList:["form-group"]}});
+ this._systems = new nmsBox("input", {html:{class:"form-control",classList:["form-control"],type:"text",size:"8",placeholder:"System(s)"}});
+ this._systems.searchbox = document.getElementById("searchbox")
+ this._systems.html.oninput = function(e) {
+ this.nmsBox.searchbox.value = this.value;
+ this.nmsBox.searchbox.oninput();
+ }
+ systemParent.add(this._systems)
+ this.add(systemParent)
+ var entryParent = new nmsBox("div",{html:{class:"form-group",classList:["form-group"]}});
+ this._entry = new nmsBox("input", {html:{class:"form-control",classList:["form-control"],type:"text",size:"30",placeholder:"Log entry"}});
+ entryParent.add(this._entry)
+ this.add(entryParent)
+ var button = new nmsBox("button",{html:{classList:["btn","btn-default"],type:"button"}});
+ button.html.textContent = "Log";
+ button.container = this;
+ button.html.onclick = function(element) {
+ this.nmsBox.container.commit(element)
+ }
+ this.add(button);
+ }
+ /* Should be moved to nms.user probably */
+ get user() {
+ if (nms.user) {
+ return nms.user;
+ }
+ var user = prompt("Who are you? Short nick for the record.");
if (user == null || user == undefined || user == "") {
console.log("empty prompt");
alert("No cake for you.");
@@ -28,103 +82,170 @@ nmsOplog.getUser = function(force) {
}
nms.user = user;
saveSettings();
+ return nms.user;
}
- return nms.user;
-}
-
-nmsOplog.commit = function() {
- var s = document.getElementById('logbox-id').value;
- var d = document.getElementById('logbox').value;
- var user = nmsOplog.getUser();
- if (user == undefined) {
- nmsOplog._reset();
- return;
+ _empty(input) {
+ if (input == undefined || input == null || input == "") {
+ return "";
+ }
+ return input;
}
- if (d == undefined || d == null || d == "") {
- return;
+ get entry() {
+ return this._empty(this._entry.html.value)
}
-
- var myData = {"user": user, "systems": s, "log": d};
- myData = JSON.stringify(myData);
- $.ajax({
- type: "POST",
- url: "/api/write/oplog",
- dataType: "text",
- data:myData,
- success: function (data, textStatus, jqXHR) {
- nmsData.invalidate("oplog");
- }
- });
- nmsOplog._reset();
-}
-
-nmsOplog.updateComments = function() {
- nmsOplog._updateComments(10,"-mini","time",100);
- nmsOplog._updateComments(0,"","timestamp");
-}
-
-nmsOplog.getSwitchLogs = function(sw) {
- var logs = [];
- if (nmsData.oplog == undefined || nmsData['oplog']['oplog'] == undefined)
- return [];
- for (var v in nmsData['oplog']['oplog']) {
- var log = nmsData['oplog']['oplog'][v];
- if (log['systems'] != "" && log['systems'] != undefined) {
- if (nmsSearch.searchTest(log['systems'],sw)) {
- logs.push(log);
- }
+ get systems() {
+ return this._empty(this._systems.html.value)
+ }
+ commit(element) {
+ if (!this.user) {
+ console.log("need a user...")
+ return false;
+ }
+ if (this.entry == "") {
+ return false;
}
+ var myData = {"user": this.user, "systems": this.systems, "log": this.entry};
+ myData = JSON.stringify(myData);
+ $.ajax({
+ type: "POST",
+ url: "/api/write/oplog",
+ dataType: "text",
+ data:myData,
+ success: function (data, textStatus, jqXHR) {
+ nmsData.invalidate("oplog");
+ }
+ });
+ this.blank()
+ }
+ blank() {
+ this._entry.html.value = "";
+ this._systems.html.value = "";
+ this._systems.searchbox.value = "";
+ this._systems.searchbox.oninput()
}
- return logs;
}
+
/*
* This can be re-written now that it uses nmsBox... That rewrite was just a short
* test of nmsBox...
*/
-nmsOplog._updateComments = function(limit,prefix,timefield,cutoff) {
- var table = new nmsTable([]);
- var i = 0;
- for (var v in nmsData['oplog']['oplog']) {
- if (cutoff && nmsData.oplog.oplog[v]['username'] == "system") {
- continue;
+class nmsLogTable extends nmsTable {
+ constructor(mode = "small", timestyle = "small", cutoff = 100, limit = 10) {
+ super([]);
+ this.mode = mode;
+ this.timestyle = timestyle;
+ this.cutoff = cutoff;
+ this.limit = limit;
+ this.entries = {}
+ this.first = true;
+ }
+ /* This is a horrible implementation. BUT THAT'S WHAT YOU GET
+ */
+ syncToTable() {
+ var i = 1;
+ var pastCut = false;
+ var indexes = [];
+ for (var idx in this.entries) {
+ indexes.push(parseInt(idx))
+ }
+ // Testint to see what browsers I can break with exciting new
+ // syntax
+ indexes.sort((x,y) => y-x)
+ for (var idx in indexes) {
+ var entry = this.entries[indexes[idx]];
+ if (!pastCut) {
+ if (entry == undefined) {
+ console.log("wtf, empty?")
+ console.log(entry)
+ } else {
+ entry.build(this.cutoff,this.timestyle)
+ if(!this.includes(entry)) {
+ // FIXME: This is dumb. It assumes we only get one update.
+ if (this.first) {
+ this.add(entry)
+ } else {
+ this.insert(entry)
+ }
+ }
+ }
+ } else {
+ if(this.includes(entry)) {
+ this.remove(entry)
+ }
+ }
+ if(this.limit > 0 && ++i > this.limit) {
+ pastCut = true;
+ }
}
- var col1;
- var date = new Date(nmsData.oplog.oplog[v]['timestamp'].replace(" ","T").replace("+00",""));
- if (timefield == "time") {
- col1 = date.toTimeString().replace(/:\d\d .*$/,"");
+ this.first=false;
+ }
+ update() {
+ var candidates = nmsData['oplog']['oplog'];
+ for (var i in candidates) {
+ var candidate = candidates[i];
+ if (this.entries[candidate.id] != undefined) {
+ continue;
+ } else {
+ this.entries[candidate.id] = new nmsOplogEntry(candidate);
+ }
+ }
+ this.syncToTable();
+ }
+}
+
+class nmsOplogEntry extends nmsBox {
+ build(cutoff,timestyle) {
+ if (this.built) {
+ return true;
+ }
+ var td1 = new nmsBox("td")
+ var td2 = new nmsBox("td")
+ if(timestyle == "small") {
+ td1.add(new nmsString(this.shortTime()))
} else {
- var month = date.getMonth() + 1;
- var day = date.getDate();
- var tmp = (date.getYear() + 1900) + "-" + (month < 10 ? "0": "") + month + "-" + (day < 10 ? "0" : "") + day + " " + date.toTimeString().replace(/:\d\d .*$/,"");
- col1 = tmp;
- }
- var data = nmsData['oplog']['oplog'][v]['log'];
- var col2 = new nmsBox("p");
- if (cutoff && data.length > cutoff) {
- col2.html.title = data;
- data = data.slice(0,cutoff);
- data = data + "(...)";
- }
- col2.html.textContent = nmsData['oplog']['oplog'][v]['systems'] + " [" + nmsData['oplog']['oplog'][v]['username'] + "] " + data;
- col2.html.hiddenthing = v;
+ td1.add(new nmsString(this.longTime()))
+ }
+ var col2 = new nmsString(this.systems + " [" + this.username + "] " + this.getData(cutoff));
+ if (this.title != null) {
+ col2.html.title = this.title;
+ }
+ col2.searchbox = document.getElementById("searchbox")
+ col2.entry = this;
col2.html.onclick = function(e) {
var x = document.getElementById("searchbox");
var v = e.path[0].hiddenthing;
- x.value = nmsData['oplog']['oplog'][v]['systems'];
- x.oninput();
- }
- table.add([col1,col2]);
- if (++i == limit)
- break;
- }
- try {
- var old = document.getElementById("oplog-table" + prefix);
- old.parentElement.removeChild(old);
- } catch(e) {}
- var par = document.getElementById("oplog-parent" + prefix);
- table.html.id = "oplog-table" + prefix;
- par.appendChild(table.html);
- nmsOplog.table["x" + prefix] = table;
-};
+ this.nmsBox.searchbox.value = this.nmsBox.entry.systems;
+ this.nmsBox.searchbox.oninput()
+ }
+ this.add(td1)
+ td2.add(col2)
+ this.add(td2)
+ this.built = true;
+ }
+ constructor(entry) {
+ super("tr")
+ this.td1 = null;
+ this.td2 = null;
+ this.time = new Date(entry.timestamp.replace(" ","T"))
+ this.id = entry.id;
+ this.data = entry.log;
+ this.title = null;
+ this.systems = entry.systems;
+ this.username = entry.username;
+ }
+ longTime() {
+ return this.time.toISOString();
+ }
+ shortTime() {
+ return this.time.toTimeString().replace(/:\d\d .*$/,"");
+ }
+ getData(cutoff = 0) {
+ if (cutoff && this.data.length > cutoff) {
+ this.title = this.data;
+ return this.data.slice(0,cutoff) + "(...)";
+ }
+ return this.data;
+ }
+}
diff --git a/web/js/nms-types.js b/web/js/nms-types.js
index 254c00b..c077505 100644
--- a/web/js/nms-types.js
+++ b/web/js/nms-types.js
@@ -35,6 +35,13 @@ class nmsType {
validate(input) {
return true;
}
+ toString() {
+ if (this._value == null || this._value == undefined) {
+ return ""
+ } else {
+ return this._value.toString();
+ }
+ }
get value() {
return this._value;
}
diff --git a/web/js/nms-ui-boxes.js b/web/js/nms-ui-boxes.js
index ac4445e..385d601 100644
--- a/web/js/nms-ui-boxes.js
+++ b/web/js/nms-ui-boxes.js
@@ -61,16 +61,93 @@ class nmsBox {
}
add(box) {
this._boxes.push(box);
- this.html.appendChild(box.html);
+ box.attach(this.html)
+ box.show()
}
- close() {
- for (var x in this._boxes) {
- this._boxes[x].close();
+ insert(box) {
+ this._boxes.unshift(box)
+ box.attach(this.html)
+ box.show(true,-1)
+ }
+
+ /* This is provided so as to allow attaching to non-nmsBox-objects.
+ * E.g.: attach the root to a HTML element directly.
+ * If you just use foo = document.getElement...,
+ * foo.appendChild(box.html), then .hide() will work fine,
+ * but there's no way to do .show() afterwards.
+ *
+ * Be aware:
+ * - we want to AVOID the child knowing too much about the parent
+ * - HTML elements can only ever be part of a single parent
+ * element. This means that it is safe to attach(root1), .show(),
+ * atach(root2), show() ... The DOM object wil be removed from root1.
+ * - Due to the above, we should probably actually adress that, since
+ * there are valid reasons for showing the same nmsBox twice (e.g.:
+ * showing a list of tons of stuff, and also a "top 5")
+ */
+ attach(root) {
+ if (!(root instanceof HTMLElement)) {
+ root = document.getElementById(root)
+ }
+ console.assert(root instanceof HTMLElement)
+ this._root = root;
+ }
+ show(show = true,where=1) {
+ if (!show) {
+ this.hide()
+ return
+ }
+ if (this._root instanceof HTMLElement) {
+ if (where>0) {
+ this._root.appendChild(this.html);
+ } else {
+ this._root.insertBefore(this.html,this._root.firstElementChild)
+ }
+ }
+ }
+ _remove(source,box) {
+ source.html.removeChild(box.html)
+ if (box._root == source) {
+ box._root = undefined;
+ }
+ var x = source._boxes.indexOf(box)
+ delete source._boxes[x]
+ }
+ _includes(source,box) {
+ if (source._boxes.indexOf(box) >= 0) {
+ return true;
+ } else {
+ return false;
}
- if (this.html.parentElement != null) {
+ }
+ /*
+ * This redirect is to make it easier for subclasses that
+ * override add() to make it eaiser to add logical
+ * childs, e.g. adding to a table really adds to ._tbody,
+ * not the true top-element of the table.
+ */
+ remove(box) {
+ this._remove(this,box)
+ }
+ includes(box) {
+ return this._includes(this,box);
+ }
+ hide() {
+ if (this.html.parentElement instanceof HTMLElement) {
this.html.parentElement.removeChild(this.html);
}
}
+ destroy() {
+ this.hide()
+ for (var i in this._boxes) {
+ var x = this._boxes[i];
+ x.hide()
+ x.destroy()
+ delete this._boxes[i]
+ }
+ delete this.html;
+ delete this;
+ }
update() {
for (var x in this._boxes) {
this._boxes[x].update();
@@ -112,13 +189,15 @@ class nmsTable extends nmsBox {
this.add(content[v]);
}
}
- /* Can take either a single nmsBox-object that will be added as-is,
- * or an array of items that will be added as individual cells
- */
- add(content) {
+ remove(box) {
+ this._remove(this._tbody,box)
+ }
+ includes(box) {
+ return this._tbody.includes(box)
+ }
+ _makeBox(content) {
if (content instanceof nmsBox) {
- this._tbody.add(content)
- return;
+ return content;
}
var tr;
var td1;
@@ -138,7 +217,16 @@ class nmsTable extends nmsBox {
}
tr.add(td);
}
- this._tbody.add(tr);
+ return tr;
+ }
+ /* Can take either a single nmsBox-object that will be added as-is,
+ * or an array of items that will be added as individual cells
+ */
+ add(content) {
+ this._tbody.add(this._makeBox(content));
+ }
+ insert(box) {
+ this._tbody.insert(this._makeBox(box));
}
}
@@ -160,8 +248,15 @@ class nmsPanel extends nmsBox{
this._topBox.add(this.nav);
this._topBox.add(this._body);
super.add(this._topBox);
- this._root = document.getElementById("metaContainer");
- this._root.appendChild(this.html);
+ }
+ attach(root = document.getElementById("metaContainer")) {
+ super.attach(root)
+ }
+ show() {
+ if (!this._root) {
+ this.attach()
+ }
+ super.show()
}
/* Mainly just to make the constructor more readable. */
makeHeading(title) {
diff --git a/web/js/nms.js b/web/js/nms.js
index 7eb3dfd..c85e8fb 100644
--- a/web/js/nms.js
+++ b/web/js/nms.js
@@ -49,7 +49,6 @@ var nms = {
get user() { return this._user; },
set user(u) {
this._user = u;
- document.getElementById('logbook-name').textContent = u;
saveSettings();
},
/*
@@ -403,8 +402,6 @@ function initNMS() {
nmsData.registerSource("smanagement","/api/read/switches-management");
nmsData.registerSource("oplog", "/api/read/oplog");
nmsData.registerSource("networks","/api/read/networks");
- // setInterval(nmsUpdateNavbarGraph, 30000);
- // nmsUpdateNavbarGraph();
nmsOplog.init();
}
@@ -454,8 +451,7 @@ function setMenu()
function setOplog()
{
- var nav = document.getElementById("oplog-parent-mini");
- nav.style.display = nms.oplogShowing ? '' : 'none';
+ //nmsOplog.table["x-mini"].show(nms.oplogShowing)
}
function toggleMenu()