aboutsummaryrefslogtreecommitdiffstats
path: root/web/js/nms-ui-boxes.js
diff options
context:
space:
mode:
authorKristian Lyngstol <kly@kly.no>2019-01-06 01:51:17 +0100
committerKristian Lyngstol <kly@kly.no>2019-01-06 01:51:17 +0100
commit8d63fa675264ae0d809f86ee036e081519b88299 (patch)
tree433b6e01951e2fbbeab306739660d25666779f7d /web/js/nms-ui-boxes.js
parent4558d453f06a233a3df020223786071f007f9e2c (diff)
Introduce nms-ui-boxes, a big step for GUI
nmsBox is a new class for generic HTML-based elements, and will eventually be used to replace nms-info-box. The idea is simple: a generic way to deal with containers that are usually represented in HTML too. To test it, I've re-implemented the GUI for the oplog. This rewrite didn't really utilize the new benefits of the framework, but was a small step. I've also added nms-ui-switch, which isn't exposed anywhere yet and isn't done, but is a good start. nms-ui-switch will be the new way to add and edit switches in the future, it will probably be made more generic over time and thus can be reused for networks too. Note how x = nmsUiSwitch() will allow you to do x.row["community"].value to both get and set the value, and setting will visually update and run any verifier that will be relevant, and alert the parent. This can then be used for simple stuff like json-verification, but also for stuff like auto-complete or whatnot. God only knows. Obviously I will continue to work on this over the next few days...
Diffstat (limited to 'web/js/nms-ui-boxes.js')
-rw-r--r--web/js/nms-ui-boxes.js191
1 files changed, 191 insertions, 0 deletions
diff --git a/web/js/nms-ui-boxes.js b/web/js/nms-ui-boxes.js
new file mode 100644
index 0000000..3ed65cd
--- /dev/null
+++ b/web/js/nms-ui-boxes.js
@@ -0,0 +1,191 @@
+"use strict";
+
+/*
+ * An attempt at breaking up nms-info-box into something that works better.
+ * The idea is to retain the ability to fiddle with html, but solve common
+ * problems such as "I need to show a box that looks good" and "I need to
+ * update the content of this field in this box when something happens".
+ *
+ * Seeing as how it's 2019, I figured I'd try to use this whole "class"
+ * thing :D
+ *
+ * Eventually, everything in nms-info-box.js should use this, but more over,
+ * if a need to write some code that needs a UI element arises, the general
+ * problem should be solved here, while the implementation: elsewhere.
+ *
+ * Example: Adding a new switch or network should not be closely tied in
+ * here.
+ *
+ * I expect this code to change dramatically as I start using it.
+ */
+
+class nmsBox {
+ constructor(type,settings) {
+ this.type = type;
+ this._boxes = []
+ this.html = document.createElement(type);
+ this.html.nmsBox = this;
+ if (settings) {
+ this.applySettings(settings);
+ }
+ }
+ get value() {
+ var values = [];
+ for (var x in this._boxes) {
+ var tmp = this._boxes[x].value;
+ if (tmp != undefined && !((tmp instanceof Array) && tmp.length == 0)) {
+ values.push(tmp)
+ }
+ }
+ return values;
+ }
+
+ applySettings(settings) {
+ if (settings.html) {
+ for (var x in settings.html) {
+ if (settings.html[x] instanceof Array) {
+ /* If you just sett classList = array it will end up being
+ * classList = "panel,panel-default,foo", instead of
+ * classList = ["panel","panel-default","foo"] ...
+ * Not sure if this applies to all arrays in a html
+ * object, but we'll see.
+ */
+ for (var y in settings.html[x]) {
+ this.html[x].add(settings.html[x][y]);
+ }
+ } else {
+ this.html[x] = settings.html[x];
+ }
+ }
+ }
+ }
+ add(box) {
+ this._boxes.push(box);
+ this.html.appendChild(box.html);
+ }
+ close() {
+ for (var x in this._boxes) {
+ this._boxes[x].close();
+ }
+ if (this.html.parentElement != null) {
+ this.html.parentElement.removeChild(this.html);
+ }
+ }
+ update() {
+ for (var x in this._boxes) {
+ this._boxes[x].update();
+ }
+ }
+};
+
+
+class nmsString extends nmsBox {
+ constructor(content,type) {
+ type = type ? type : "p";
+ super(type,{ html: { textContent: content }})
+ }
+ set value(input) {
+ this.html.textContent = input;
+ }
+ get value() {
+ return this.html.textContent;
+ }
+}
+/*
+ * A general-purpose table. It can be created in one go, or
+ * as-you-go.
+ */
+class nmsTable extends nmsBox {
+ constructor(content, caption) {
+ super("table");
+ this.html.className = "table";
+ this.html.classList.add("table");
+ this.html.classList.add("table-condensed");
+ if (caption != undefined) {
+ var cap = new nmsBox("caption");
+ cap.html.textContent = caption;
+ super.add(cap);
+ }
+ this._tbody = new nmsBox("tbody");
+ super.add(this._tbody);
+ for (var v in content) {
+ 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) {
+ if (content instanceof nmsBox) {
+ this._tbody.add(content)
+ return;
+ }
+ var tr;
+ var td1;
+ var td2;
+ tr = new nmsBox("tr");
+ tr.html.className = content[0].toLowerCase().replace(/[^a-z0-9_]/g,"");
+ for (var x in content) {
+ var td = new nmsBox("td");
+ var child = content[x];
+ if (x == 0) {
+ td.html.classList.add("left");
+ }
+ if (child instanceof nmsBox) {
+ td.add(child);
+ } else {
+ td.add(new nmsString(child));
+ }
+ tr.add(td);
+ }
+ this._tbody.add(tr);
+ }
+}
+
+/*
+ * Basic panel. Rooted at the 'metaContainer' as of now, but that MIGHT CHANGE.
+ * Draws a nice box with a background, title, close-button and whatnot.
+ * Usage:
+ * var myThing = new nmsPanel("initial title");
+ * myThing.add(nmsString("whatever"))
+ * myThing.title = "blah...."
+ */
+class nmsPanel extends nmsBox{
+ constructor(title){
+ super("div",{html: { classList: ["col-sm-8","col-md-6","col-lg-5","genericBox"]}});
+ this._topBox = new nmsBox("div",{ html: { classList: ["panel","panel-default"]}});
+ this._body = new nmsBox("div",{html:{classList: ["panel-body"]}});
+ this.nav = new nmsBox("div",{html:{classList: ["panel-body"]}});
+ this._topBox.add(this.makeHeading(title));
+ this._topBox.add(this.nav);
+ this._topBox.add(this._body);
+ super.add(this._topBox);
+ this._root = document.getElementById("metaContainer");
+ this._root.appendChild(this.html);
+ }
+ /* Mainly just to make the constructor more readable. */
+ makeHeading(title) {
+ var titleObject = new nmsBox("div",{html:{classList: ["panel-heading"]}});
+ this._titleText = new nmsBox("p",{html:{textContent: title}});
+ var closeButton = new nmsBox("button");
+ closeButton.html.className = "close";
+ closeButton.panel = this;
+ closeButton.html.onclick = function() {
+ this.nmsBox.panel.close();
+ }
+ closeButton.html.style = "float: right;";
+ closeButton.add(new nmsString("X","span"));
+ titleObject.add(closeButton);
+ titleObject.add(this._titleText);
+ return titleObject;
+ }
+ add(item) {
+ this._body.add(item)
+ }
+ set title(input) {
+ this._titleText.html.textContent = input;
+ }
+ get title() {
+ this._titleText.html.textContent;
+ }
+}