diff options
author | Kristian Lyngstol <kly@kly.no> | 2019-01-07 00:05:59 +0100 |
---|---|---|
committer | Kristian Lyngstol <kly@kly.no> | 2019-01-07 00:05:59 +0100 |
commit | ed9e8db8f953f3064c3e21d9da75c0802f21ab1b (patch) | |
tree | 05f733cd7eb2b4edcdac7caa089bb4830e12bc2a | |
parent | 0bd74cf3010de984d36eed04b6318b7b30e25373 (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.html | 13 | ||||
-rw-r--r-- | web/js/nms-oplog.js | 317 | ||||
-rw-r--r-- | web/js/nms-types.js | 7 | ||||
-rw-r--r-- | web/js/nms-ui-boxes.js | 123 | ||||
-rw-r--r-- | web/js/nms.js | 6 |
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() |