diff options
Diffstat (limited to 'web/js/nms-ui-switch.js')
-rw-r--r-- | web/js/nms-ui-switch.js | 616 |
1 files changed, 325 insertions, 291 deletions
diff --git a/web/js/nms-ui-switch.js b/web/js/nms-ui-switch.js index 825ecd9..e2663d4 100644 --- a/web/js/nms-ui-switch.js +++ b/web/js/nms-ui-switch.js @@ -3,318 +3,352 @@ /* Basic editor for switches, and possibly networks and whatever. * This is the first real use of both the nmsBox and nmsType, so * expect changes as the need(s) arise. - * + * * The general idea is simple, though: Editing and adding is to be treated * as similar as possible, and there should be no hard-coding anywhere. If * we need a "one-off" for whatever, we should find a genric way of solving - * it to avoid complicating things. - * + * it to avoid complicating things. + * */ class nmsNewSwitch extends nmsPanel { - constructor() { - super("Add new switch") - this.add(new nmsModSwitch(undefined)) - this.nav.add(new nmsString("The only required field for adding a switch is the sysname, everything else will be filled in by the backend if you do not provide it. However, you should PROBABLY fill in managemnt IP and a few other fields.")); - } + constructor() { + super("Add new switch"); + this.add(new nmsModSwitch(undefined)); + this.nav.add( + new nmsString( + "The only required field for adding a switch is the sysname, everything else will be filled in by the backend if you do not provide it. However, you should PROBABLY fill in managemnt IP and a few other fields." + ) + ); + } } class nmsNewNet extends nmsPanel { - constructor() { - super("Add new network") - this.add(new nmsModNet(undefined)) - this.nav.add(new nmsString("Only the name is required, but you should probably fill in more.")); - } + constructor() { + super("Add new network"); + this.add(new nmsModNet(undefined)); + this.nav.add( + new nmsString( + "Only the name is required, but you should probably fill in more." + ) + ); + } } class nmsModThing extends nmsBox { - constructor(data) { - super("div"); - this.identifier = data.identifier; - this.invalidate = data.invalidate; - this.api = data.api; - this.item = data.item; - this.generateBaseTemplate() - this.populate() - var save = new nmsButton("Save","btn-primary"); - save.panel = this; - save.html.onclick = this.save; - this.add(save) - var del = new nmsButton("Delete","btn btn-danger"); - del.panel = this - del.html.onclick = this.del; - this.add(del) - } - commit(data) { - $.ajax({ - type: "POST", - url: this.api, - dataType: "text", - nmsBox:this, - data:JSON.stringify(data), - success: function (data, textStatus, jqXHR) { - var msg = new nmsString("Changed..."); - msg.attach(this.nmsBox._root); - msg.show() - this.nmsBox.destroy() - //nmsInfoBox.hide(); - for (var x of this.nmsBox.invalidate) { - nmsData.invalidate(x); - } - } - }); - } + constructor(data) { + super("div"); + this.identifier = data.identifier; + this.invalidate = data.invalidate; + this.api = data.api; + this.item = data.item; + this.generateBaseTemplate(); + this.populate(); + } + commit(data) { + $.ajax({ + type: "POST", + url: this.api, + dataType: "text", + nmsBox: this, + data: JSON.stringify(data), + success: function (data, textStatus, jqXHR) { + var msg = new nmsString("Changed..."); + msg.attach(this.nmsBox._root); + msg.show(); + this.nmsBox.destroy(); + //nmsInfoBox.hide(); + for (var x of this.nmsBox.invalidate) { + nmsData.invalidate(x); + } + }, + }); + } - del(e) { - if(confirm("This will delete the " + this.typeName + ":" + this.nmsBox.panel.item)) { - this.nmsBox.panel.commit([{'sysname': this.nmsBox.panel.item, 'deleted': true}]); - }; - } - save(e) { - var diff = this.nmsBox.panel.diff() - if (diff != undefined) { - this.nmsBox.panel.commit([diff]) - } - } - /* Pretty sure that the type-thing is OK, but what I want is to - * generate a nmsTemplate or something that can be used to get/set - * variables generically, and replaces nmsEditRow. Since right now, - * both the template and the row is fiddling with values, luckily - * all through the same actual object, but still.... - * This is because I wrote nmsEditRow before I added a type-system. - * - * The fundamental problem is that the row-rendering is obviously - * affected by the type, and the overall "template"/parent - * (nmsModSwitch right now) is also obviously affected by changes to - * the individual rows. - * - * Right now a change in a value means nmsEditRow will get the - * event, it will use the nmsType to validate, and ultimately set, - * but it ALSO has to store a text-representation of the value if it - * changes from other sources (e.g.: auto-complete), and we need to - * alert nmsModSwitch that a change has occurred so it can act - * approrpiately (e.g.: Enabling/disabling a save button). - * - * This means that nmsType instances, nmsEditRow instances and - * nmsModSwitch instance is tightly coupled in non-obvious ways. - * - * Which means bugs. - */ - populate() { - if (this.item != undefined) { - this._populateTemplate(this.item); - } - this.table = new nmsTable(); - this.rows = {} - for (var v in this._template) { - this.rows[v] = new nmsEditRow(v, this._template[v]); - this.rows[v].parent = this; - this.table.add(this.rows[v]); - } - this.add(this.table); - } - changed(row) { - this.title = "saw row change on " + row.name + " to " + row.value; - } - get value() { - var ret = {}; - for (var idx in this.rows) { - ret[idx] = this.rows[idx].value; - } - return ret; - } - diff() { - var ret = {}; - var changed = 0; - for (var idx in this.rows) { - if (this.rows[idx].value.toString() != this.rows[idx].original) { - ret[idx] = this.rows[idx].value.value; - changed++; - } - } - if (!changed) { - return undefined; - } - ret[this.identifier] = this.rows[this.identifier].value.value; - return ret; - } + del(e) { + if ( + confirm( + "This will delete the " + this.typeName + ":" + this.nmsBox.panel.item + ) + ) { + this.nmsBox.panel.commit([ + { sysname: this.nmsBox.panel.item, deleted: true }, + ]); + } + } + save(e) { + var diff = this.nmsBox.panel.diff(); + if (diff != undefined) { + this.nmsBox.panel.commit([diff]); + } + } + /* Pretty sure that the type-thing is OK, but what I want is to + * generate a nmsTemplate or something that can be used to get/set + * variables generically, and replaces nmsEditRow. Since right now, + * both the template and the row is fiddling with values, luckily + * all through the same actual object, but still.... + * This is because I wrote nmsEditRow before I added a type-system. + * + * The fundamental problem is that the row-rendering is obviously + * affected by the type, and the overall "template"/parent + * (nmsModSwitch right now) is also obviously affected by changes to + * the individual rows. + * + * Right now a change in a value means nmsEditRow will get the + * event, it will use the nmsType to validate, and ultimately set, + * but it ALSO has to store a text-representation of the value if it + * changes from other sources (e.g.: auto-complete), and we need to + * alert nmsModSwitch that a change has occurred so it can act + * approrpiately (e.g.: Enabling/disabling a save button). + * + * This means that nmsType instances, nmsEditRow instances and + * nmsModSwitch instance is tightly coupled in non-obvious ways. + * + * Which means bugs. + */ + populate() { + if (this.item != undefined) { + this._populateTemplate(this.item); + } + this.table = new nmsTable(); + this.rows = {}; + for (var v in this._template) { + this.rows[v] = new nmsEditRow(v, this._template[v]); + this.rows[v].parent = this; + this.table.add(this.rows[v]); + } + this.add(this.table); + } + changed(row) { + this.title = "saw row change on " + row.name + " to " + row.value; + } + get value() { + var ret = {}; + for (var idx in this.rows) { + ret[idx] = this.rows[idx].value; + } + return ret; + } + diff() { + var ret = {}; + var changed = 0; + for (var idx in this.rows) { + if (this.rows[idx].value.toString() != this.rows[idx].original) { + ret[idx] = this.rows[idx].value.value; + changed++; + } + } + if (!changed) { + return undefined; + } + ret[this.identifier] = this.rows[this.identifier].value.value; + return ret; + } } class nmsEditRow extends nmsBox { - constructor(text,value) { - super("tr") - // This should/could be smarter in the future. - console.assert(value instanceof nmsType) - this.name = text; - this._value = value; - this.original = value.toString(); - var td1 = new nmsBox("td") - var name = new nmsString(text+" "); - name.html.title = value.description; - td1.add(name) - this.add(td1); - td1.html.width="50%" - this._state = new nmsBox("span",{html:{className:"label label-default",textContent:"Original"}}) - this._valid = new nmsBox("span",{html:{className:"label label-default",textContent:"Not verified"}}) - name.add(this._state) - name.add(this._valid) - this._valid.hide() - this.changed(false) - var content = new nmsBox("td") - var input = new nmsBox("input") - input.html.value = value.toString(); - input.html.className = "form-control"; - input.html.type = "text"; - input.row = this; - if (value.ro) { - input.html.disabled = true; - input.html.title = "Read/only attribute"; - } - if (value instanceof nmsTypeSecret) { - input.html.type = "password" - input.html.autocomplete = "off" - input.html.onfocus = function f() { this.type = "text" } - input.html.oninput = function f() { this.type = "text" } - input.html.onblur = function f() { this.type = "password" } - } - input.html.onchange = function() { - this.nmsBox.row.value = this.value - } - input.html.oninput = function() { - this.nmsBox.row.value = this.value - } - this._input = input; - this._content = content; - content.add(input) - this.add(content) - } - get value() { - return this._value; - } - changed(val) { - if (val) { - this._state.show() - this._state.html.textContent = "Changed" - this._state.html.classList.remove("label-default") - this._state.html.classList.add("label-warning") - } else { - this._state.hide() - } - } - valid(val) { - this._valid.html.classList.remove("label-default") - this._valid.show() - if (val) { - this._valid.html.textContent = "Valid" - this._valid.html.classList.remove("label-danger") - this._valid.html.classList.add("label-success") - } else { - this._valid.html.textContent = "Invalid" - this._valid.html.classList.add("label-danger") - this._valid.html.classList.remove("label-success") - } - } + constructor(text, value) { + super("tr"); + // This should/could be smarter in the future. + console.assert(value instanceof nmsType); + this.name = text; + this._value = value; + this.original = value.toString(); + var td1 = new nmsBox("td"); + var name = new nmsString(text + " "); + name.html.title = value.description; + td1.add(name); + this.add(td1); + td1.html.width = "50%"; + this._state = new nmsBox("span", { + html: { className: "label label-default", textContent: "Original" }, + }); + this._valid = new nmsBox("span", { + html: { className: "label label-default", textContent: "Not verified" }, + }); + name.add(this._state); + name.add(this._valid); + this._valid.hide(); + this.changed(false); + var content = new nmsBox("td"); + var input = new nmsBox("input"); + input.html.value = value.toString(); + input.html.className = "form-control"; + input.html.type = "text"; + input.row = this; + input.html.disabled = true; + if (value instanceof nmsTypeSecret) { + input.html.type = "password"; + input.html.autocomplete = "off"; + input.html.onfocus = function f() { + this.type = "text"; + }; + input.html.oninput = function f() { + this.type = "text"; + }; + input.html.onblur = function f() { + this.type = "password"; + }; + } + input.html.onchange = function () { + this.nmsBox.row.value = this.value; + }; + input.html.oninput = function () { + this.nmsBox.row.value = this.value; + }; + this._input = input; + this._content = content; + content.add(input); + this.add(content); + } + get value() { + return this._value; + } + changed(val) { + if (val) { + this._state.show(); + this._state.html.textContent = "Changed"; + this._state.html.classList.remove("label-default"); + this._state.html.classList.add("label-warning"); + } else { + this._state.hide(); + } + } + valid(val) { + this._valid.html.classList.remove("label-default"); + this._valid.show(); + if (val) { + this._valid.html.textContent = "Valid"; + this._valid.html.classList.remove("label-danger"); + this._valid.html.classList.add("label-success"); + } else { + this._valid.html.textContent = "Invalid"; + this._valid.html.classList.add("label-danger"); + this._valid.html.classList.remove("label-success"); + } + } - - /* THIS IS A MESS */ - set value(value) { - if (!this._value.validate(value)) { - this.valid(false) - this._content.html.classList.add("has-error"); - return; - } else { - this.valid(true) - this._content.html.classList.remove("has-error"); - this._value.fromString(value); - } - if (this._input.html.value != this._value.toString()) { - this._input.html.value = this._value.toString() - } - if (this._value.toString() != this.original) { - this.changed(true) - this._content.html.classList.add("has-success"); - } else { - this.changed(false) - this._content.html.classList.remove("has-success"); - } - this.parent.changed(this) - } + /* THIS IS A MESS */ + set value(value) { + if (!this._value.validate(value)) { + this.valid(false); + this._content.html.classList.add("has-error"); + return; + } else { + this.valid(true); + this._content.html.classList.remove("has-error"); + this._value.fromString(value); + } + if (this._input.html.value != this._value.toString()) { + this._input.html.value = this._value.toString(); + } + if (this._value.toString() != this.original) { + this.changed(true); + this._content.html.classList.add("has-success"); + } else { + this.changed(false); + this._content.html.classList.remove("has-success"); + } + this.parent.changed(this); + } } class nmsModSwitch extends nmsModThing { - constructor(sw) { - super({item: sw, identifier: "sysname", invalidate: ["switches","smanagement"], api: "/api/write/switches"}) - } - generateBaseTemplate() { - this._template = { - sysname: new nmsTypeSysname("Unique systemname/switch name. Only required field. Read/only on existing equipment." ), - mgmt_v4_addr: new nmsTypeIP("Management address IPv4"), - mgmt_v6_addr: new nmsTypeIP("Management address IPv6"), - mgmt_vlan: new nmsTypeNetwork("Management VLAN"), - traffic_vlan: new nmsTypeNetwork("Traffic VLAN"), - distro_name: new nmsTypeSysnameReference("Distro switch upstream of this system. Required for provisioning."), - distro_phy_port: new nmsTypePort("Name of port we connect to at the distro switch. Used for provisioning, among other things."), - poll_frequency: new nmsTypeInterval("Poll frequency for SNMP (will use default from backend)"), - community: new nmsTypeSecret("SNMP community (will use default from backend)"), - placement: new nmsTypePlace("Map placement (If following a regular naming scheme, the backend will place it poperly, otherwise a random place will be chose)"), - tags: new nmsTypeTags("Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems.") - } - } - _populateTemplate(sw) { - var swi = []; - var swm = []; - try { - swi = nmsData.switches["switches"][sw]; - swm = nmsData.smanagement.switches[sw]; - } catch(e) {} + constructor(sw) { + super({ + item: sw, + identifier: "sysname", + invalidate: ["switches", "smanagement"], + api: "/api/write/switches", + }); + } + generateBaseTemplate() { + this._template = { + sysname: new nmsTypeSysname( + "Unique systemname/switch name. Only required field. Read/only on existing equipment." + ), + mgmt_v4_addr: new nmsTypeIP("Management address IPv4"), + mgmt_v6_addr: new nmsTypeIP("Management address IPv6"), + mgmt_vlan: new nmsTypeNetwork("Management VLAN"), + traffic_vlan: new nmsTypeNetwork("Traffic VLAN"), + distro_name: new nmsTypeSysnameReference( + "Distro switch upstream of this system. Required for provisioning." + ), + distro_phy_port: new nmsTypePort( + "Name of port we connect to at the distro switch. Used for provisioning, among other things." + ), + placement: new nmsTypePlace( + "Map placement (If following a regular naming scheme, the backend will place it poperly, otherwise a random place will be chose)" + ), + tags: new nmsTypeTags( + "Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems." + ), + }; + } + _populateTemplate(sw) { + var swi = []; + var swm = []; + try { + swi = nmsData.switches["switches"][sw]; + swm = nmsData.smanagement.switches[sw]; + } catch (e) {} - var template = {} - for (var v in swi) { - console.assert(this._template[v] instanceof nmsType) - if (swi[v] != null) { - this._template[v].initial(swi[v]); - } - } - for (var v in swm) { - if (v == "last_updated") { - continue; - } - console.assert(this._template[v] instanceof nmsType) - if (swm[v] != null) { - this._template[v].initial(swm[v]); - } - } - } + var template = {}; + for (var v in swi) { + console.assert(this._template[v] instanceof nmsType); + if (swi[v] != null) { + this._template[v].initial(swi[v]); + } + } + for (var v in swm) { + if (v == "last_updated") { + continue; + } + console.assert(this._template[v] instanceof nmsType); + if (swm[v] != null && this._template[v]) { + this._template[v].initial(swm[v]); + } + } + } } class nmsModNet extends nmsModThing { - constructor(net) { - super({item: net, identifier: "name", invalidate: ["networks","smanagement"], api: "/api/write/networks"}) - } - generateBaseTemplate() { - this._template = { - name: new nmsType("Unique networkname. Only required field. Read/only on existing nets."), - vlan: new nmsType("VLAN ID"), - gw4: new nmsTypeIP("Gateway address, IPv4"), - gw6: new nmsTypeIP("Gateway address, IPv6"), - subnet4: new nmsTypeCIDR("Subnet, IPv4"), - subnet6: new nmsTypeCIDR("Subnet, IPv6"), - router: new nmsTypeSysnameReference("Router where net is terminated. E.g.: r1.noc for floor traffic nets"), - tags: new nmsTypeTags("Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems.") - } - } - _populateTemplate(net) { - var nets = []; - try { - nets = nmsData.networks["networks"][net]; - } catch(e) {} + constructor(net) { + super({ + item: net, + identifier: "name", + invalidate: ["networks", "smanagement"], + api: "/api/write/networks", + }); + } + generateBaseTemplate() { + this._template = { + name: new nmsType( + "Unique networkname. Only required field. Read/only on existing nets." + ), + vlan: new nmsType("VLAN ID"), + gw4: new nmsTypeIP("Gateway address, IPv4"), + gw6: new nmsTypeIP("Gateway address, IPv6"), + subnet4: new nmsTypeCIDR("Subnet, IPv4"), + subnet6: new nmsTypeCIDR("Subnet, IPv6"), + router: new nmsTypeSysnameReference( + "Router where net is terminated. E.g.: r1.noc for floor traffic nets" + ), + tags: new nmsTypeTags( + "Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems." + ), + }; + } + _populateTemplate(net) { + var nets = []; + try { + nets = nmsData.networks["networks"][net]; + } catch (e) {} - var template = {} - for (var v in nets) { - console.assert(this._template[v] instanceof nmsType) - if (nets[v] != null) { - this._template[v].initial(nets[v]); - } - } - } + var template = {}; + for (var v in nets) { + console.assert(this._template[v] instanceof nmsType); + if (nets[v] != null) { + this._template[v].initial(nets[v]); + } + } + } } - - |