First version with collapsable device groups
Ylian Saint-Hilaire committed
Dec 23, 2019 at 17:40 UTC
81fd0451a7affbcc23e7a939891236e3ddd4dcf0
4 files changed
+31
-4
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.4.6-m",
3
+ "version": "0.4.6-n",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
public/images/c1.png
Binary files /dev/null and b/public/images/c1.png differ
public/images/c2.png
Binary files /dev/null and b/public/images/c2.png differ
views/default.handlebars
+30
-3
@@ -2785,6 +2785,7 @@
2785
if (sort == 0) {
2786
// Mesh header
2787
if (node.meshid != current) {
2788
+ if ((view == 1) && (current != null)) { r += '</div>'; } // Close collapse div
2789
deviceHeaderSet();
2790
var extra = '';
2791
if (view == 2) { r += '<tr><td colspan=5>'; }
@@ -2793,11 +2794,15 @@
2794
if (view == 2) { r += '<div>'; }
2795
r += '<div class=DevSt style=width:100%;padding-top:4px><span style=float:right>';
2796
r += '<span id=DevxHeader' + deviceHeaderId + ' class=devHeaderx></span>' + extra;
2796
- r += '</span><span id=MxMESH tabindex=0 style=cursor:pointer onclick=gotoMesh("' + node.meshid + '") onkeypress="if (event.key==\'Enter\') gotoMesh(\'' + node.meshid + '\')">' + EscapeHtml(meshes[node.meshid].name) + '</span>' + getMeshActions(mesh2, meshrights) + '</div>';
2797
+ r += '</span>';
2798
+ var collapsed = CollapsedGroups[node.meshid];
2799
+ r += '<img id=\"DevxColImg' + deviceHeaderId + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + deviceHeaderId + '\",\"' + node.meshid + '\")></img>'; // Collapse action
2800
+ r += '<span id=MxMESH tabindex=0 style=cursor:pointer onclick=gotoMesh("' + node.meshid + '") onkeypress="if (event.key==\'Enter\') gotoMesh(\'' + node.meshid + '\')">' + EscapeHtml(meshes[node.meshid].name) + '</span>' + getMeshActions(mesh2, meshrights) + '</div>';
2801
if (view == 2) { r += '</div>'; }
2802
current = node.meshid;
2803
displayedMeshes[current] = 1;
2804
c = 0;
2805
+ if (view == 1) { r += '<div id=DevxCol' + deviceHeaderId + ((collapsed === true)?' style=display:none':'') + '>'; } // Open collapse div
2806
}
2807
} else if (sort == 1) {
2808
// Power header
@@ -2876,6 +2881,8 @@
2881
if (typeof deviceHeaderCount[node.state] == 'undefined') { deviceHeaderCount[node.state] = 1; } else { deviceHeaderCount[node.state]++; }
2882
}
2883
2884
+ if ((view == 1) && (current != null)) { r += '</div>'; } // Close collapse div
2885
+
2886
// Above 32 devices, gray out the auto connect feature.
2887
if (kvmDivs.length >= 32) { Q('autoConnectDesktopCheckbox').checked = false; }
2888
QE('autoConnectDesktopCheckbox', kvmDivs.length < 32);
@@ -2908,13 +2915,21 @@
2915
2916
// Display all empty device groups, we need to do this because users can add devices to these at any time.
2917
if ((sort == 0) && (Q('SearchInput').value == '') && (view < 3)) {
2918
+ var deviceHeaderId2 = deviceHeaderId;
2919
for (var i in meshes) {
2920
var mesh = meshes[i], meshlink = mesh.links[userinfo._id];
2921
if (meshlink != null) {
2922
var meshrights = meshlink.rights;
2923
if (displayedMeshes[mesh._id] == null) {
2924
if ((current != '') && (r != '')) { r += '</tr></table>'; }
2917
- r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span><span>';
2925
+ r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt>';
2926
+
2927
+ // Collapsing header & start collapsing area
2928
+ deviceHeaderId2++;
2929
+ var collapsed = CollapsedGroups[mesh._id];
2930
+ r += '<img id=\"DevxColImg' + deviceHeaderId2 + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + deviceHeaderId2 + '\",\"' + mesh._id + '\")></img>'; // Collapse action
2931
+
2932
+ r += '<span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span><span>';
2933
r += getMeshActions(mesh, meshrights);
2934
r += '</span></td></tr><tr>';
2935
if (mesh.mtype == 1) {
@@ -2922,10 +2937,14 @@
2937
if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; }
2938
}
2939
if (mesh.mtype == 2) {
2925
- r += '<td><div style=padding:10px><i>' + "No devices in this group";
2940
+ r += '<td>';
2941
+ if (view == 1) { r += '<div id=DevxCol' + deviceHeaderId2 + ((collapsed === true)?' style=display:none':'') + '>'; } // Open collapse div
2942
+ r += '<div style=padding:10px><i>' + "No devices in this group";
2943
if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; }
2944
}
2945
r += '.</i></div></td>';
2946
+ if (view == 1) { r += '</div>'; } // End collapsing area
2947
+
2948
current = mesh._id;
2949
count++;
2950
}
@@ -3036,6 +3055,14 @@
3055
oldviewmode = view;
3056
}
3057
3058
+ var CollapsedGroups = {};
3059
+ function toggleCollapseGroup(id, id2) {
3060
+ var x = (QS('DevxCol' + id)['display'] == 'none');
3061
+ if (x) { delete CollapsedGroups[id2]; } else { CollapsedGroups[id2] = true; }
3062
+ Q('DevxColImg' + id).src = x?'images/c2.png':'images/c1.png';
3063
+ QV('DevxCol' + id, x);
3064
+ }
3065
+
3066
function toggleKvmDevice(node) {
3067
if (typeof node == 'string') { node = getNodeFromId(node); } // Convert nodeid to node if needed
3068
var mesh = meshes[node.meshid], meshrights = mesh.links[userinfo._id].rights;