Added drag & drop file support on the remote desktop tab.

Ylian Saint-Hilaire committed Aug 20, 2022 at 13:19 UTC 93efc2e6a02cb47918ae7a8d0f307b510adc4537
2 files changed +95 -51
public/styles/style.css
+4 -24
@@ -1152,7 +1152,7 @@ NoMeshesPanel img {
1152 padding: 4px;
1153 }
1154
1155 -#bigok {
1155 +#bigok, #p11bigok, #p13bigok {
1156 width: 256px;
1157 overflow: hidden;
1158 position: absolute;
@@ -1161,9 +1161,10 @@ NoMeshesPanel img {
1161 text-align: center;
1162 font-size: 1600%;
1163 color: #AAAAAA;
1164 + z-index: 99999;
1165 }
1166
1166 -#bigfail {
1167 +#bigfail, #p11bigfail, #p13bigfail {
1168 width: 256px;
1169 overflow: hidden;
1170 position: absolute;
@@ -1172,6 +1173,7 @@ NoMeshesPanel img {
1173 text-align: center;
1174 font-size: 1600%;
1175 color: #AAAAAA;
1176 + z-index: 99999;
1177 }
1178
1179 .chartViewCanvas {
@@ -2760,28 +2762,6 @@ a {
2762 height: calc(100vh - 349px);
2763 }
2764
2763 -#p13bigok {
2764 - width: 256px;
2765 - overflow: hidden;
2766 - position: absolute;
2767 - left: 337px;
2768 - top: 200px;
2769 - text-align: center;
2770 - font-size: 1600%;
2771 - color: #AAA;
2772 -}
2773 -
2774 -#p13bigfail {
2775 - width: 256px;
2776 - overflow: hidden;
2777 - position: absolute;
2778 - left: 337px;
2779 - top: 200px;
2780 - text-align: center;
2781 - font-size: 1600%;
2782 - color: #AAA;
2783 -}
2784 -
2765 .fulldesk #p14title {
2766 margin-left: 16px;
2767 margin-right: 16px;
views/default.handlebars
+91 -27
@@ -670,6 +670,8 @@
670 </div>
671 </div>
672 <div id=deskarea3x>
673 + <div id="p11bigok" style="display:none"><b>&checkmark;</b></div>
674 + <div id="p11bigfail" style="display:none"><b>&#10007;</b></div>
675 <div id=DeskFocus oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></div>
676 <div id=DeskParent>
677 <canvas id=Desk width=640 height=480 oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event) onmousewheel=dmousewheel(event)></canvas>
@@ -1631,7 +1633,7 @@
1633 for (var j = 1; j < 5; j++) { Q('devViewButton' + j).classList.remove('viewSelectorSel'); }
1634 Q('devViewButton' + Q('viewselect').value).classList.add('viewSelectorSel');
1635
1634 - // Setup upload drag & drop
1636 + // Setup upload drag & drop for server files
1637 Q('p5filetable').addEventListener('drop', p5fileDragDrop, false);
1638 Q('p5filetable').addEventListener('dragover', p5fileDragOver, false);
1639 Q('p5filetable').addEventListener('dragleave', p5fileDragLeave, false);
@@ -1639,7 +1641,12 @@
1641 //Q('p5fileCatchAllInput').addEventListener('dragover', p5fileDragOver, false);
1642 //Q('p5fileCatchAllInput').addEventListener('dragleave', p5fileDragLeave, false);
1643
1642 - // Setup upload drag & drop
1644 + // Setup drag & drop for device desktop
1645 + Q('deskarea0').addEventListener('drop', p11fileDragDrop, false);
1646 + Q('deskarea0').addEventListener('dragover', p11fileDragOver, false);
1647 + Q('deskarea0').addEventListener('dragleave', p11fileDragLeave, false);
1648 +
1649 + // Setup upload drag & drop for device files
1650 Q('p13filetable').addEventListener('drop', p13fileDragDrop, false);
1651 Q('p13filetable').addEventListener('dragover', p13fileDragOver, false);
1652 Q('p13filetable').addEventListener('dragleave', p13fileDragLeave, false);
@@ -5731,13 +5738,23 @@
5738 var wintype = false, linuxtype = false, agenttype = false;
5739 for (var i in options.nodeids) {
5740 var n = getNodeFromId(options.nodeids[i]);
5734 - if (n.agent) { if ((GetNodeRights(n) & 24) == 24) { agenttype = true; } if ((n.agent.id > 0) && (n.agent.id < 5)) { wintype = true; } else { linuxtype = true; } }
5741 + if (n.agent) { if ((GetNodeRights(n) & 24) == 24) { agenttype = true; }
5742 + if ((n.agent.id > 0) && (n.agent.id < 5)) { wintype = true; } else { linuxtype = true; } }
5743 }
5744 if ((wintype == true) || (linuxtype == true) || (agenttype == true)) {
5745 // Fetch run options
5746 var runopt = { type:1, runAs:0, source:1, cmd:'' };
5747 try { runopt = JSON.parse(getstore('runopt', runopt)); } catch (ex) {}
5748
5749 + if (options.selectedFile) {
5750 + var filename = options.selectedFile.name.toLowerCase();
5751 + console.log('filename', filename);
5752 + if (filename.endsWith('.bat')) { runopt.type = 1; }
5753 + if (filename.endsWith('.ps1')) { runopt.type = 2; }
5754 + if (filename.endsWith('.sh')) { runopt.type = 3; }
5755 + if (filename.endsWith('.agentconsole')) { runopt.type = 4; }
5756 + }
5757 +
5758 var x = '';
5759 if (options.title) { x += options.title + '<br />'; }
5760 x += '<select id=d2cmdtype onclick=d2runCommandValidate() style=width:100%;margin-bottom:4px;margin-top:4px>';
@@ -5746,48 +5763,59 @@
5763 if (agenttype == true) { x += '<option value=4' + ((runopt.type == 4)?' selected':'') + '>' + "Agent Console" + '</option>'; } // MESHRIGHT_REMOTECONTROL & MESHRIGHT_AGENTCONSOLE are needed
5764 x += '</select>';
5765 x += '<select id=d2cmduser style=width:100%;margin-bottom:4px><option value=0' + ((runopt.runAs == 0)?' selected':'') + '>' + "Run as agent" + '</option><option value=1' + ((runopt.runAs == 1)?' selected':'') + '>' + "Run as user, agent if no user" + '</option><option value=2' + ((runopt.runAs == 2)?' selected':'') + '>' + "Must run as user" + '</option></select>';
5749 - x += '<select id=d2cmdsource onclick=d2runCommandValidate() style=width:100%;margin-bottom:4px><option value=0' + ((runopt.source == 0)?' selected':'') + '>' + "Commands from text box" + '</option><option value=1' + ((runopt.source == 1)?' selected':'') + '>' + "Commands from file" + '</option>';
5750 - if (userinfo.siteadmin & 8) { x += '<option value=2' + ((runopt.source == 2)?' selected':'') + '>' + "Commands from file on server" + '</option>'; }
5751 - x += '</select><textarea id=d2runcmd onkeyup=d2runCommandValidate() style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll>' + (runopt.cmd ? EscapeHtml(decodeURIComponent(runopt.cmd)) : '') + '</textarea>';
5752 - x += '<div id=d2runfile style=display:none><input id=d2runfileex type=file onchange=d2runCommandValidate() id=d2localFile name=files onchange=d2runCommandValidate() /></div>';
5753 - if (userinfo.siteadmin & 8) { x += '<div id=d2runsfile style=display:none><div id=d2serveraction valign=bottom><input type=button id=p2FolderUp disabled="disabled" onclick=d3folderup() value="Up" />&nbsp;<span id=p2CurrentFolder></span></div><div id=d2serverfiles></div></div>'; }
5766 + if (options.selectedFile == null) {
5767 + x += '<select id=d2cmdsource onclick=d2runCommandValidate() style=width:100%;margin-bottom:4px><option value=0' + ((runopt.source == 0)?' selected':'') + '>' + "Commands from text box" + '</option><option value=1' + ((runopt.source == 1)?' selected':'') + '>' + "Commands from file" + '</option>';
5768 + if (userinfo.siteadmin & 8) { x += '<option value=2' + ((runopt.source == 2)?' selected':'') + '>' + "Commands from file on server" + '</option>'; }
5769 + x += '</select><textarea id=d2runcmd onkeyup=d2runCommandValidate() style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll>' + (runopt.cmd ? EscapeHtml(decodeURIComponent(runopt.cmd)) : '') + '</textarea>';
5770 + x += '<div id=d2runfile style=display:none><input id=d2runfileex type=file onchange=d2runCommandValidate() id=d2localFile name=files onchange=d2runCommandValidate() /></div>';
5771 + if (userinfo.siteadmin & 8) { x += '<div id=d2runsfile style=display:none><div id=d2serveraction valign=bottom><input type=button id=p2FolderUp disabled="disabled" onclick=d3folderup() value="Up" />&nbsp;<span id=p2CurrentFolder></span></div><div id=d2serverfiles></div></div>'; }
5772 + }
5773 setDialogMode(2, "Run Commands", 3, d2groupActionFunctionRunCommands, x, options);
5755 - Q('d2runcmd').focus();
5774 + if (options.selectedFile == null) {
5775 + Q('d2runcmd').focus();
5776 + if (userinfo.siteadmin & 8) { d3fileoptions = { dialog: 2, files: 'd2serverfiles', folderup: 'p2FolderUp', currentFolder: 'p2CurrentFolder', func: null }; d3updatefiles(); } // Update the server files
5777 + }
5778 d2runCommandValidate();
5757 - if (userinfo.siteadmin & 8) { d3fileoptions = { dialog: 2, files: 'd2serverfiles', folderup: 'p2FolderUp', currentFolder: 'p2CurrentFolder', func: null }; d3updatefiles(); } // Update the server files
5779 }
5780 }
5781
5782 function d2runCommandValidate() {
5783 QV('d2cmduser', Q('d2cmdtype').value < 4);
5763 - QV('d2runcmd', Q('d2cmdsource').value == 0);
5764 - QV('d2runfile', Q('d2cmdsource').value == 1);
5765 - QV('d2runsfile', Q('d2cmdsource').value == 2);
5766 - var ok = false;
5767 - if (Q('d2cmdsource').value == 0) { if (Q('d2runcmd').value.length > 0) { ok = true; } } // From text box
5768 - if (Q('d2cmdsource').value == 1) { if (Q('d2runfileex').files.length == 1) { ok = true; } } // From file
5769 - if (Q('d2cmdsource').value == 2) { ok = false; } // From server file
5770 - QE('idx_dlgOkButton', ok);
5784 + if (xxdialogTag.selectedFile == null) {
5785 + QV('d2runcmd', Q('d2cmdsource').value == 0);
5786 + QV('d2runfile', Q('d2cmdsource').value == 1);
5787 + QV('d2runsfile', Q('d2cmdsource').value == 2);
5788 + var ok = false;
5789 + if (Q('d2cmdsource').value == 0) { if (Q('d2runcmd').value.length > 0) { ok = true; } } // From text box
5790 + if (Q('d2cmdsource').value == 1) { if (Q('d2runfileex').files.length == 1) { ok = true; } } // From file
5791 + if (Q('d2cmdsource').value == 2) { ok = false; } // From server file
5792 + QE('idx_dlgOkButton', ok);
5793 + } else {
5794 + QE('idx_dlgOkButton', true);
5795 + }
5796 }
5797
5798 function d2groupActionFunctionRunCommands(b, options) {
5799 var type = 3;
5800 try { type = parseInt(Q('d2cmdtype').value); } catch (ex) { }
5776 - putstore('runopt', JSON.stringify({ type: type, runAs: parseInt(Q('d2cmduser').value), source: parseInt(Q('d2cmdsource').value), cmd: encodeURIComponent(Q('d2runcmd').value) })); // Save run options
5801 + if (options.selectedFile == null) { putstore('runopt', JSON.stringify({ type: type, runAs: parseInt(Q('d2cmduser').value), source: parseInt(Q('d2cmdsource').value), cmd: encodeURIComponent(Q('d2runcmd').value) })); } // Save run options
5802 var cmd = { action: 'runcommands', nodeids: options.nodeids, type: type, runAsUser: parseInt(Q('d2cmduser').value) };
5778 - if (Q('d2cmdsource').value == 0) {
5803 + if (options.selectedFile) {
5804 + // Drag & drop file
5805 + var reader = new FileReader();
5806 + reader.onload = function (e) { cmd.cmds = e.target.result; meshserver.send(cmd); if (options.func) { options.func(); } }
5807 + reader.readAsText(options.selectedFile);
5808 + } else if (Q('d2cmdsource').value == 0) {
5809 // From text box
5810 cmd.cmds = Q('d2runcmd').value;
5811 meshserver.send(cmd);
5812 if (options.func) { options.func(); }
5783 - }
5784 - if (Q('d2cmdsource').value == 1) {
5813 + } else if (Q('d2cmdsource').value == 1) {
5814 // From file
5815 var reader = new FileReader();
5816 reader.onload = function (e) { cmd.cmds = e.target.result; meshserver.send(cmd); if (options.func) { options.func(); } }
5817 reader.readAsText(Q('d2runfileex').files[0]);
5789 - }
5790 - if (Q('d2cmdsource').value == 2) {
5818 + } else if (Q('d2cmdsource').value == 2) {
5819 // From server file
5820 var files = d3getFileSel();
5821 if (files.length != 1) return;
@@ -7706,7 +7734,7 @@
7734 }
7735
7736 // Run commands on current device
7709 - function runDeviceCmd(nodeid) { if (xxdialogMode) return; d2runCommandDialog({ nodeids: [ decodeURIComponent(nodeid ? nodeid : currentNode._id) ] }); }
7737 + function runDeviceCmd(nodeid) { if (xxdialogMode) return; d2runCommandDialog({ nodeids: [ nodeid ? decodeURIComponent(nodeid) : currentNode._id ] }); }
7738
7739 function writeDeviceEvent(nodeid) {
7740 if (xxdialogMode) return;
@@ -9312,6 +9340,42 @@
9340 }
9341 }
9342
9343 + function p11fileDragDrop(e) {
9344 + haltEvent(e);
9345 + QV('p11bigfail', false);
9346 + QV('p11bigok', false);
9347 + if ((xxdialogMode != null) || (desktop == null) || (desktop.State != 3) || (e.dataTransfer == null) || (e.dataTransfer.files.length == 0)) return;
9348 +
9349 + var file = e.dataTransfer.files[0];
9350 + var filename = file.name.toLowerCase();
9351 + if (filename.endsWith('.bat') || filename.endsWith('.ps1') || filename.endsWith('.sh') || filename.endsWith('.agentconsole')) {
9352 + d2runCommandDialog({ nodeids: [ currentNode._id ], selectedFile: file });
9353 + } else if (filename.endsWith('.txt')) {
9354 + var reader = new FileReader();
9355 + reader.onload = function (e) { showDeskType(e.target.result); }
9356 + reader.readAsText(file);
9357 + }
9358 + }
9359 +
9360 + var p11dragtimer = null;
9361 + function p11fileDragOver(e) {
9362 + haltEvent(e);
9363 + if (p11dragtimer != null) { clearTimeout(p11dragtimer); p11dragtimer = null; }
9364 + var ac = ((xxdialogMode == null) && (desktop != null) && (desktop.State == 3));
9365 + QV('p11bigok', ac);
9366 + QV('p11bigfail', !ac);
9367 + }
9368 +
9369 + function p11fileDragLeave(e) {
9370 + haltEvent(e);
9371 + if (e.target.id != 'Desk') {
9372 + QV('p11bigfail', false);
9373 + QV('p11bigok', false);
9374 + } else {
9375 + p11dragtimer = setTimeout(function () { QV('p11bigfail',false); QV('p11bigok',false); p11dragtimer = null; }, 10);
9376 + }
9377 + }
9378 +
9379 //
9380 // Desktop Shortcut Keys
9381 //
@@ -9557,11 +9621,11 @@
9621 }
9622
9623 // Remote desktop typing
9560 - function showDeskType() {
9624 + function showDeskType(text) {
9625 if (xxdialogMode || desktop == null || desktop.State != 3) return;
9626 Q('DeskType').blur();
9627 var x = '<div>' + "Enter text and click OK to remotely type it. Make sure to place the remote cursor at the correct position before proceeding." + '<div>';
9564 - x += '<textarea id=d2typeText style="margin-top:5px;width:100%;height:184px;resize:none" maxlength=2000></textarea>';
9628 + x += '<textarea id=d2typeText style="margin-top:5px;width:100%;height:184px;resize:none" maxlength=2000>' + (text ? EscapeHtml(text) : '') + '</textarea>';
9629 setDialogMode(2, "Remote Keyboard Entry", 3, showDeskTypeEx, x);
9630 Q('d2typeText').focus();
9631 }