Completed webapp collapse feature.
Ylian Saint-Hilaire committed
Dec 26, 2019 at 12:50 UTC
48d9592fb9b5abd07ac68f09fd3a3bd68c146211
2 files changed
+41
-16
public/styles/style.css
+4
@@ -15,6 +15,10 @@ body {
15
/* overflow-y: hidden; */
16
}
17
18
+.night .collapseImage {
19
+ filter: invert(100%);
20
+}
21
+
22
#container {
23
background-color: #fff;
24
width: 960px;
views/default.handlebars
+37
-16
@@ -2798,9 +2798,9 @@
2798
r += '<div class=DevSt style=width:100%;padding-top:4px><span style=float:right>';
2799
r += '<span id=DevxHeader' + deviceHeaderId + ' class=devHeaderx></span>' + extra;
2800
r += '</span>';
2801
- if ((view == 1) || (view == 3)) {
2801
+ if ((view == 1) || (view == 2) || (view == 3)) {
2802
var collapsed = CollapsedGroups[node.meshid];
2803
- 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
2803
+ r += '<img class=collapseImage 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 + '\",' + view + ')></img>'; // Collapse action
2804
}
2805
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>';
2806
if (view == 2) { r += '</div>'; }
@@ -2819,9 +2819,9 @@
2819
2820
if (view == 2) { r += '<tr><td>'; }
2821
r += '<div class=DevSt style=width:100%;padding-top:4px><span id=DevxHeader' + deviceHeaderId + ' class=devHeaderx style=float:right></span>';
2822
- if ((view == 1) || (view == 3)) {
2822
+ if ((view == 1) || (view == 2) || (view == 3)) {
2823
var collapsed = CollapsedGroups['pwr:' + pwr];
2824
- 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 + '\",\"pwr:' + pwr + '\")></img>'; // Collapse action
2824
+ r += '<img class=collapseImage 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 + '\",\"pwr:' + pwr + '\",' + view + ')></img>'; // Collapse action
2825
}
2826
r += '<span>' + PowerStateStr2(node.pwr) + '</span></div>';
2827
@@ -2856,7 +2856,12 @@
2856
if ((node.conn & 8) != 0) { states.push('<span title=\"' + "Mesh agent is reachable using another agent as relay." + '\">' + "Relay" + '</span>'); }
2857
if ((node.conn & 16) != 0) { states.push('<span title=\"' + "MQTT connection to the device is active." + '\">' + "MQTT" + '</span>'); }
2858
}
2859
- r += '<tr><td><div id=devs class=bar18 tabindex=0 onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=height:18px;width:100%;font-size:medium onkeypress="if (event.key==\'Enter\') gotoDevice(\'' + node._id + '\',null,null,event)">';
2859
+
2860
+ var collapseName = node.meshid;
2861
+ if (sort == 1) { collapseName = 'pwr:' + node.pwr; }
2862
+ else if (sort == 3) { collapseName = 'tag:**xx**xx*TaG*xx**xx**'; }
2863
+ var collapsed = (sort != 3) & CollapsedGroups[collapseName];
2864
+ r += '<tr name=DevxCol' + collapseName + (collapsed?' style=display:none':'') + '><td><div id=devs class=bar18 tabindex=0 onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=height:18px;width:100%;font-size:medium onkeypress="if (event.key==\'Enter\') gotoDevice(\'' + node._id + '\',null,null,event)">';
2865
r += '<div class=deviceBarCheckbox><input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox></div>';
2866
r += '<div class=deviceBarIcon onclick=gotoDevice(\'' + node._id + '\',null,null,event)><div class=\"j' + icon + '\" style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>';
2867
r += '<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>';
@@ -2882,7 +2887,9 @@
2887
if (node.tags) {
2888
for (var j in node.tags) {
2889
var tag = node.tags[j];
2885
- if (groups[tag] == null) { groups[tag] = r; groupCount[tag] = 1; } else { groups[tag] += r; groupCount[tag] += 1; }
2890
+ var collapsed = CollapsedGroups['tag:' + tag];
2891
+ var r2 = r.replace('**xx**xx*TaG*xx**xx**', tag + (collapsed?' style=display:none':''));
2892
+ if (groups[tag] == null) { groups[tag] = r2; groupCount[tag] = 1; } else { groups[tag] += r2; groupCount[tag] += 1; }
2893
if (view == 3) break;
2894
}
2895
}
@@ -2907,17 +2914,20 @@
2914
for (var j in groupNames) {
2915
var i = groupNames[j];
2916
if (view == 2) {
2910
- r += '<tr><td colspan=4><div class=DevSt style=width:100%;padding-top:4px><span class=devHeaderx style=float:right>' + groupCount[i] + ' node' + ((groupCount[i] > 1) ? 's' : '') + '</span><span>' + i + '</span></div>' + groups[i];
2917
+ r += '<tr><td colspan=4><div class=DevSt style=width:100%;padding-top:4px>';
2918
+ var collapsed = CollapsedGroups['tag:' + i];
2919
+ r += '<img class=collapseImage id=\"DevxColImg' + tagDeviceHeaderId + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + tagDeviceHeaderId + '\",\"tag:' + i + '\",2)></img>'; // Collapse action
2920
+ r += '<span class=devHeaderx style=float:right>' + groupCount[i] + ' node' + ((groupCount[i] > 1) ? 's' : '') + '</span><span>' + i + '</span></div>' + groups[i];
2921
} else {
2922
r += '<div class=DevSt style=width:100%;padding-top:4px><span class=devHeaderx style=float:right>' + groupCount[i] + ' node' + ((groupCount[i] > 1) ? 's' : '') + '</span>';
2923
var collapsed = CollapsedGroups['tag:' + i];
2914
- r += '<img id=\"DevxColImg' + tagDeviceHeaderId + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + tagDeviceHeaderId + '\",\"tag:' + i + '\")></img>'; // Collapse action
2924
+ r += '<img class=collapseImage id=\"DevxColImg' + tagDeviceHeaderId + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + tagDeviceHeaderId + '\",\"tag:' + i + '\")></img>'; // Collapse action
2925
r += '<span>' + i + '</span></div>';
2926
r += '<div id=DevxCol' + tagDeviceHeaderId + ((collapsed === true)?' style=display:none':'') + '>'; // Open collapse div
2927
r += groups[i];
2928
r += '</div>';
2919
- tagDeviceHeaderId++;
2929
}
2930
+ tagDeviceHeaderId++;
2931
}
2932
}
2933
@@ -2946,7 +2956,7 @@
2956
// Collapsing header & start collapsing area
2957
deviceHeaderId2++;
2958
var collapsed = CollapsedGroups[mesh._id];
2949
- 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
2959
+ r += '<img class=collapseImage 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
2960
2961
r += '<span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span><span>';
2962
r += getMeshActions(mesh, meshrights);
@@ -2957,12 +2967,12 @@
2967
}
2968
if (mesh.mtype == 2) {
2969
r += '<td>';
2960
- if (view == 1) { r += '<div id=DevxCol' + deviceHeaderId2 + ((collapsed === true)?' style=display:none':'') + '>'; } // Open collapse div
2970
+ r += '<div id=DevxCol' + deviceHeaderId2 + ((collapsed === true)?' style=display:none':'') + '>'; // Open collapse div
2971
r += '<div style=padding:10px><i>' + "No devices in this group";
2972
if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; }
2973
}
2974
r += '.</i></div></td>';
2965
- if (view == 1) { r += '</div>'; } // End collapsing area
2975
+ r += '</div>'; // End collapsing area
2976
2977
current = mesh._id;
2978
count++;
@@ -3074,11 +3084,22 @@
3084
oldviewmode = view;
3085
}
3086
3077
- function toggleCollapseGroup(id, id2) {
3078
- var x = (QS('DevxCol' + id)['display'] == 'none');
3079
- if (x) { delete CollapsedGroups[id2]; } else { CollapsedGroups[id2] = true; }
3087
+ function toggleCollapseGroup(id, id2, type) {
3088
+ var x;
3089
+ if (type == 2) {
3090
+ // Table rows collapse
3091
+ var rows = document.getElementsByName('DevxCol' + id2);
3092
+ if (rows.length == 0) return;
3093
+ x = (rows[0].style['display'] == 'none');
3094
+ if (x) { delete CollapsedGroups[id2]; } else { CollapsedGroups[id2] = true; }
3095
+ for (var i = 0; i < rows.length; i++) { rows[i].style['display'] = (x ? '' : 'none'); }
3096
+ } else {
3097
+ // Simple DIV collapse
3098
+ x = (QS('DevxCol' + id)['display'] == 'none');
3099
+ if (x) { delete CollapsedGroups[id2]; } else { CollapsedGroups[id2] = true; }
3100
+ QV('DevxCol' + id, x);
3101
+ }
3102
Q('DevxColImg' + id).src = x?'images/c2.png':'images/c1.png';
3081
- QV('DevxCol' + id, x);
3103
putstore('_collapse', JSON.stringify(CollapsedGroups));
3104
}
3105