Started work on global map
Ylian Saint-Hilaire committed
Aug 28, 2017 at 15:57 UTC
95f88d112578098937e9bf81f07c2ce1a5f4dcd5
2 files changed
+132
-111
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.0.6-p",
3
+ "version": "0.0.6-q",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
views/default.handlebars
+131
-110
@@ -102,29 +102,32 @@
102
<div id=p1 style=display:none>
103
<h1>My Devices</h1>
104
<div style=width:100%;height:24px;background-color:#d3d9d6>
105
- <div class=style7 style=width:84px;height:100%;float:left> </div>
105
<div class=h1 style=height:100%;float:left> </div>
107
- <div class=style14 style=height:100%;float:left>
106
+ <div id=devListToolbar class=style14 style=height:100%;float:left>
107
<input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All" />
108
<input type="button" id="GroupActionButton" disabled="disabled" value="Group Action" onclick="groupActionFunction();" />
109
<input id="SearchInput" type="text" style=width:120px placeholder=Search onchange="onSearchInputChanged()" onkeyup="onSearchInputChanged()" autocomplete=off onfocus="onSearchFocus(1)" onblur="onSearchFocus(0)" />
110
<input type="checkbox" id="HostnameCheckBox" onclick="onHostnameCheckBox()" /><span title="Show device hostnames">Hostname</span>
111
</div>
112
<div class="auto-style1" style="height: 100%; float: right">
114
- <div style="height: 100%; width: 4px; float: right; background-color: #ffffff"></div>
115
- <div class="h2" style="height: 100%; float: right;"> </div>
116
- <div style="float: right">
113
+ <div style="height:100%;width:4px;float:right;background-color:#ffffff"></div>
114
+ <div class=h2 style="height:100%;float:right"> </div>
115
+ <div style=float:right>
116
+ View
117
+ <select id=viewselect onchange=onDeviceViewChange()>
118
+ <option value=1>3 wide</option>
119
+ <option value=2>List</option>
120
+ <option value=3>Map</option>
121
+ </select>
122
+ </div>
123
+ <div style=float:right id=devListToolbarSort>
124
Sort
125
<select id=sortselect onchange=onSortSelectChange()>
126
<option>Mesh</option>
127
<option>Power</option>
128
<option>Device</option>
129
</select>
123
- View
124
- <select id=viewselect onchange=onDeviceViewChange()>
125
- <option value=1>3 wide</option>
126
- <option value=2>List</option>
127
- </select>
130
+
131
</div>
132
</div>
133
</div>
@@ -142,6 +145,7 @@
145
<p></p>
146
</div>
147
<div id="xdevices" style="max-height:calc(100vh - 228px);overflow-y:auto;-webkit-overflow-scrolling:touch"></div>
148
+ <div id="xdevicesmap" style="height:500px;width:100%;overflow:hidden"></div>
149
</div>
150
<div id=p2 style=display:none>
151
<h1>My Account</h1>
@@ -596,6 +600,7 @@
600
var features = {{{features}}};
601
var serverPublicNamePort = "{{{serverDnsName}}}:{{{serverPublicPort}}}";
602
var amtScanResults = null;
603
+ var xxmap = null;
604
605
function startup() {
606
// Guard against other site's top frames (web bugs).
@@ -657,6 +662,13 @@
662
var x = '';
663
for (var c = 1; c < 27; c++) x += "<option value='" + c + "'>Ctrl-" + String.fromCharCode(64 + c) + " (" + c + ")</option>";
664
QH('specialkeylist', x);
665
+
666
+ // Setup the map
667
+ xxmap = new ol.Map({
668
+ target: 'xdevicesmap',
669
+ layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ],
670
+ view: new ol.View({ center: ol.proj.fromLonLat([0, 0]), zoom: 1.8, minZoom: 1.8 })
671
+ });
672
}
673
674
function getNodeFromId(id) {
@@ -1134,119 +1146,128 @@
1146
var deviceHeaderId = 0;
1147
var deviceHeaderCount;
1148
var deviceHeaders = {};
1137
-
1149
function updateDevices() {
1150
var r = "", c = 0, current = null, count = 0, displayedMeshes = {}, view = Q('viewselect').value;
1140
- deviceHeaderId = 0;
1141
- deviceHeaderCount = {};
1142
- deviceHeaderTotal = 0;
1143
- deviceHeaders = {};
1144
- deviceHeadersTitles = {};
1145
-
1146
- // Save the list of currently checked nodeid's
1147
- var checkedNodeids = [], elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
1148
- for (var i in elements) { if (elements[i].checked) { checkedNodeids.push(elements[i].value); } }
1149
-
1150
- // Go thru the list of nodes and display them
1151
- for (var i in nodes) {
1152
- if (nodes[i].v == false) continue;
1153
- var mesh2 = meshes[nodes[i].meshid], meshlinks = mesh2.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()];
1154
- if (meshlinks == undefined) continue;
1155
- if (sort == 0) {
1156
- // Mesh header
1157
- if (nodes[i].meshid != current) {
1158
- deviceHeaderSet();
1159
- var extra = '';
1160
- if (meshes[nodes[i].meshid].mtype == 1) { extra = '<span class=devHeaderx>, Intel® AMT only</span>'; }
1161
- var meshrights = meshlinks.rights;
1162
- if ((view == 1) && (current != null)) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } r += '</tr></table>'; }
1163
- r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span style=float:right>';
1164
- r += getMeshActions(mesh2, meshrights);
1165
- r += '</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + nodes[i].meshid + '")>' + EscapeHtml(meshes[nodes[i].meshid].name) + '</span>' + extra + '<span id=DevxHeader' + deviceHeaderId + ' class=devHeaderx></span></td></tr><tr>';
1166
- current = nodes[i].meshid;
1167
- displayedMeshes[current] = 1;
1168
- c = 0;
1169
- }
1170
- } else if (sort == 1) {
1171
- // Power header
1172
- if (nodes[i].pwr !== current) {
1173
- deviceHeaderSet();
1174
- if ((view == 1) && (current !== null)) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } r += '</tr></table>'; }
1175
- r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span>' + PowerStateStr2(nodes[i].pwr) + '</span><span id=DevxHeader' + deviceHeaderId + ' class="devHeaderx"></span></td></tr><tr>';
1176
- current = nodes[i].pwr;
1177
- c = 0;
1151
+ QV('xdevices', view < 3);
1152
+ QV('xdevicesmap', view == 3);
1153
+ QV('devListToolbar', view < 3);
1154
+ QV('devListToolbarSort', view < 3);
1155
+ if (view == 3) {
1156
+ setTimeout( function() { xxmap.updateSize();}, 200);
1157
+ // TODO
1158
+ } else {
1159
+ // 3 wide or list view
1160
+ deviceHeaderId = 0;
1161
+ deviceHeaderCount = {};
1162
+ deviceHeaderTotal = 0;
1163
+ deviceHeaders = {};
1164
+ deviceHeadersTitles = {};
1165
+
1166
+ // Save the list of currently checked nodeid's
1167
+ var checkedNodeids = [], elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
1168
+ for (var i in elements) { if (elements[i].checked) { checkedNodeids.push(elements[i].value); } }
1169
+
1170
+ // Go thru the list of nodes and display them
1171
+ for (var i in nodes) {
1172
+ if (nodes[i].v == false) continue;
1173
+ var mesh2 = meshes[nodes[i].meshid], meshlinks = mesh2.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()];
1174
+ if (meshlinks == undefined) continue;
1175
+ if (sort == 0) {
1176
+ // Mesh header
1177
+ if (nodes[i].meshid != current) {
1178
+ deviceHeaderSet();
1179
+ var extra = '';
1180
+ if (meshes[nodes[i].meshid].mtype == 1) { extra = '<span class=devHeaderx>, Intel® AMT only</span>'; }
1181
+ var meshrights = meshlinks.rights;
1182
+ if ((view == 1) && (current != null)) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } r += '</tr></table>'; }
1183
+ r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span style=float:right>';
1184
+ r += getMeshActions(mesh2, meshrights);
1185
+ r += '</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + nodes[i].meshid + '")>' + EscapeHtml(meshes[nodes[i].meshid].name) + '</span>' + extra + '<span id=DevxHeader' + deviceHeaderId + ' class=devHeaderx></span></td></tr><tr>';
1186
+ current = nodes[i].meshid;
1187
+ displayedMeshes[current] = 1;
1188
+ c = 0;
1189
+ }
1190
+ } else if (sort == 1) {
1191
+ // Power header
1192
+ if (nodes[i].pwr !== current) {
1193
+ deviceHeaderSet();
1194
+ if ((view == 1) && (current !== null)) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } r += '</tr></table>'; }
1195
+ r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span>' + PowerStateStr2(nodes[i].pwr) + '</span><span id=DevxHeader' + deviceHeaderId + ' class="devHeaderx"></span></td></tr><tr>';
1196
+ current = nodes[i].pwr;
1197
+ c = 0;
1198
+ }
1199
+ } else if (sort == 2) {
1200
+ // Device header
1201
+ if (current == null) { r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr>'; current = '1'; }
1202
}
1179
- } else if (sort == 2) {
1180
- // Device header
1181
- if (current == null) { r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr>'; current = '1'; }
1182
- }
1183
-
1184
- // Node positioning
1185
- if ((view == 1) && (c > 2)) { r += '</tr><tr>'; c = 0; }
1186
- c++;
1187
- count++;
1203
1189
- var title = EscapeHtml(nodes[i].name);
1190
- if (title.length == 0) { title = '<i>None</i>'; }
1191
- if ((nodes[i].host != undefined) && (nodes[i].host.length > 0)) { title += " / " + EscapeHtml(nodes[i].host); }
1192
- var name = EscapeHtml(nodes[i].name);
1193
- if (showHostnames == true && nodes[i].host != undefined) name = EscapeHtml(nodes[i].host);
1194
- if (name.length == 0) { name = '<i>None</i>'; }
1195
-
1196
- // Node
1197
- var icon = nodes[i].icon;
1198
- var nodestate = NodeStateStr(nodes[i]);
1199
- if ((!nodes[i].conn) || (nodes[i].conn == 0)) { icon += ' gray'; }
1200
- if (view == 1) {
1201
- r += '<td><div id=devs style=width:301px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\')><div class="i' + icon + '" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 title="' + title + '">' + name + '</div><div>' + nodestate + '</div></div><div class=g2></div></div></div></div></td>';
1202
- } else {
1203
- r += '<td><div id=devs style=width:924px;height:20px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:2px><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\')><div class="j' + icon + '" style=width:16px;float:left;margin-top:3px></div><div style=height:100%><div class=g1></div><div class=e2 style=width:858px><div style=float:right;margin-top:1px>' + nodestate + '</div><div style=margin-top:1px title="' + title + '">' + name + '</div></div><div class=g2></div></div></div></div></td></tr><tr>';
1204
+ // Node positioning
1205
+ if ((view == 1) && (c > 2)) { r += '</tr><tr>'; c = 0; }
1206
+ c++;
1207
+ count++;
1208
+
1209
+ var title = EscapeHtml(nodes[i].name);
1210
+ if (title.length == 0) { title = '<i>None</i>'; }
1211
+ if ((nodes[i].host != undefined) && (nodes[i].host.length > 0)) { title += " / " + EscapeHtml(nodes[i].host); }
1212
+ var name = EscapeHtml(nodes[i].name);
1213
+ if (showHostnames == true && nodes[i].host != undefined) name = EscapeHtml(nodes[i].host);
1214
+ if (name.length == 0) { name = '<i>None</i>'; }
1215
+
1216
+ // Node
1217
+ var icon = nodes[i].icon;
1218
+ var nodestate = NodeStateStr(nodes[i]);
1219
+ if ((!nodes[i].conn) || (nodes[i].conn == 0)) { icon += ' gray'; }
1220
+ if (view == 1) {
1221
+ r += '<td><div id=devs style=width:301px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\')><div class="i' + icon + '" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 title="' + title + '">' + name + '</div><div>' + nodestate + '</div></div><div class=g2></div></div></div></div></td>';
1222
+ } else {
1223
+ r += '<td><div id=devs style=width:924px;height:20px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:2px><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\')><div class="j' + icon + '" style=width:16px;float:left;margin-top:3px></div><div style=height:100%><div class=g1></div><div class=e2 style=width:858px><div style=float:right;margin-top:1px>' + nodestate + '</div><div style=margin-top:1px title="' + title + '">' + name + '</div></div><div class=g2></div></div></div></div></td></tr><tr>';
1224
+ }
1225
+ deviceHeaderTotal++;
1226
+ if (typeof deviceHeaderCount[nodes[i].state] == 'undefined') { deviceHeaderCount[nodes[i].state] = 1; } else { deviceHeaderCount[nodes[i].state]++; }
1227
}
1205
- deviceHeaderTotal++;
1206
- if (typeof deviceHeaderCount[nodes[i].state] == 'undefined') { deviceHeaderCount[nodes[i].state] = 1; } else { deviceHeaderCount[nodes[i].state]++; }
1207
- }
1228
1209
- if ((view == 1) && (c == 2)) r += '<td><div style=width:301px></div></td>'; // Adds device padding
1210
-
1211
- // Display all empty meshes, we need to do this because users can add devices to these at any time.
1212
- if (sort == 0 && Q('SearchInput').value == '') {
1213
- for (var i in meshes) {
1214
- var mesh = meshes[i], meshlink = mesh.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()];
1215
- if (meshlink != undefined) {
1216
- var meshrights = meshlink.rights;
1217
- if (displayedMeshes[mesh._id] == undefined) {
1218
- if (current != '') { r += '</tr></table>'; }
1219
- r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span style=float:right>';
1220
- r += getMeshActions(mesh, meshrights);
1221
- r += '</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span></td></tr><tr>';
1222
- if (mesh.mtype == 1) {
1223
- r += '<td><div style=padding:10px><i>No Intel® AMT devices in this mesh';
1224
- if ((meshrights & 4) != 0) { r += ', <a style=cursor:pointer onclick=addDeviceToMesh(\"' + mesh._id + '\")>add one</a>'; }
1225
- }
1226
- if (mesh.mtype == 2) {
1227
- r += '<td><div style=padding:10px><i>No devices in this mesh';
1228
- if ((meshrights & 4) != 0) { r += ', <a style=cursor:pointer onclick=addAgentToMesh(\"' + mesh._id + '\")>add one</a>'; }
1229
+ if ((view == 1) && (c == 2)) r += '<td><div style=width:301px></div></td>'; // Adds device padding
1230
+
1231
+ // Display all empty meshes, we need to do this because users can add devices to these at any time.
1232
+ if (sort == 0 && Q('SearchInput').value == '') {
1233
+ for (var i in meshes) {
1234
+ var mesh = meshes[i], meshlink = mesh.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()];
1235
+ if (meshlink != undefined) {
1236
+ var meshrights = meshlink.rights;
1237
+ if (displayedMeshes[mesh._id] == undefined) {
1238
+ if (current != '') { r += '</tr></table>'; }
1239
+ r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span style=float:right>';
1240
+ r += getMeshActions(mesh, meshrights);
1241
+ r += '</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span></td></tr><tr>';
1242
+ if (mesh.mtype == 1) {
1243
+ r += '<td><div style=padding:10px><i>No Intel® AMT devices in this mesh';
1244
+ if ((meshrights & 4) != 0) { r += ', <a style=cursor:pointer onclick=addDeviceToMesh(\"' + mesh._id + '\")>add one</a>'; }
1245
+ }
1246
+ if (mesh.mtype == 2) {
1247
+ r += '<td><div style=padding:10px><i>No devices in this mesh';
1248
+ if ((meshrights & 4) != 0) { r += ', <a style=cursor:pointer onclick=addAgentToMesh(\"' + mesh._id + '\")>add one</a>'; }
1249
+ }
1250
+ r += '.</i></div></td>';
1251
+ current = mesh._id;
1252
+ count++;
1253
}
1230
- r += '.</i></div></td>';
1231
- current = mesh._id;
1232
- count++;
1254
}
1255
}
1256
}
1236
- }
1237
- r += '</tr></table><div style=height:1px></div>'; // This height of 1 div fixes a problem in Linux firefox browsers
1257
+ r += '</tr></table><div style=height:1px></div>'; // This height of 1 div fixes a problem in Linux firefox browsers
1258
1239
- QH('xdevices', r);
1240
- deviceHeaderSet();
1241
- QV('NoNodesPanel', count == 0);
1259
+ QH('xdevices', r);
1260
+ deviceHeaderSet();
1261
+ QV('NoNodesPanel', count == 0);
1262
1243
- // Re-check nodeid's
1244
- var elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
1245
- for (var i in elements) { elements[i].checked = (checkedNodeids.indexOf(elements[i].value) >= 0); }
1263
+ // Re-check nodeid's
1264
+ var elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
1265
+ for (var i in elements) { elements[i].checked = (checkedNodeids.indexOf(elements[i].value) >= 0); }
1266
1247
- for (var i in deviceHeaders) { QH(i, deviceHeaders[i]); }
1248
- for (var i in deviceHeadersTitles) { Q(i).title = deviceHeadersTitles[i]; }
1249
- p1updateInfo();
1267
+ for (var i in deviceHeaders) { QH(i, deviceHeaders[i]); }
1268
+ for (var i in deviceHeadersTitles) { Q(i).title = deviceHeadersTitles[i]; }
1269
+ p1updateInfo();
1270
+ }
1271
}
1272
1273
function getMeshActions(mesh, meshrights) {