1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
"use strict";
/* 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.
*
*/
class nmsModSwitch extends nmsPanel {
constructor(sw) {
var title;
if (sw == undefined) {
title = "Add new switch"
} else {
title = "Edit " + sw;
}
super(title)
this._sw = sw;
this.nav.add(new nmsString("Adding and editing stuff has immediate effects and blah blah blah, insert sensible help-text here."));
this.generateBaseTemplate()
this.populate()
}
/* 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.
*/
generateBaseTemplate() {
this._template = {
sysname: new nmsTypeSysname("Unique systemname/switch name. Only required field." ),
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"][this._sw];
} catch(e) {}
try {
swm = nmsData.smanagement.switches[this._sw];
} catch(e) {}
var template = {}
for (var v in swi) {
console.assert(this._template[v] instanceof nmsType)
this._template[v].value = swi[v];
}
for (var v in swm) {
if (v == "last_updated") {
continue;
}
console.assert(this._template[v] instanceof nmsType)
this._template[v].value = swm[v];
}
}
populate() {
if (this._sw != undefined) {
this._populateTemplate(this._sw);
}
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() {
return this.table.value;
}
}
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.value;
var td1 = new nmsBox("td")
var name = new nmsString(text);
name.html.title = value.description;
td1.add(name)
this.add(td1);
var td2 = new nmsBox("td")
var input = new nmsBox("input")
input.html.value = value.value;
input.html.className = "form-control";
input.html.type = "text";
input.row = this;
input.html.onchange = function() {
this.nmsBox.row.value = this.value
}
input.html.oninput = function() {
this.nmsBox.row.value = this.value
}
this._input = input;
this._td2 = td2;
td2.add(input)
this.add(td2)
}
get value() {
return this._value.value;
}
/* THIS IS A MESS */
set value(value) {
if (!this._value.validate(value)) {
this._td2.html.classList.add("has-error");
return;
} else {
this._td2.html.classList.remove("has-error");
this._value.value = value;
}
if (this._input.html.value != this._value.value) {
this._input.html.value = this._value.value
}
if (this._value.value != this.original) {
this._td2.html.classList.add("has-success");
} else {
this._td2.html.classList.remove("has-success");
}
this.parent.changed(this)
}
}
|