diff --git a/locales/en/messages.json b/locales/en/messages.json index d7aaeedd2eb..1a2229f17b4 100755 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -3255,6 +3255,12 @@ "cliConfirmSnippetBtn": { "message": "Execute" }, + "cliPanelTitle": { + "message": "Command Line Interface" + }, + "cliCommand": { + "message": "Enter Command" + }, "loggingNote": { "message": "Data will be logged in this tab only, leaving the tab will cancel logging and application will return to its normal \"configurator\" state.
You are free to select the global update period, data will be written into the log file every 1 second for performance reasons." }, diff --git a/src/index.html b/src/index.html index c08d3b4fa9f..cba9aed8e81 100644 --- a/src/index.html +++ b/src/index.html @@ -279,5 +279,27 @@

+ + +

+
+ + +
+ +
+ +
+
+ +
+ + +
+ +
+ +
+
diff --git a/src/js/gui.js b/src/js/gui.js index d0bf56a8d07..605935a8113 100644 --- a/src/js/gui.js +++ b/src/js/gui.js @@ -422,6 +422,29 @@ class GuiControl { dialog[0].showModal(); }); } + showInteractiveDialog(interactiveDialogSettings) { + // interactiveDialogSettings: + // title, text, buttonConfirmText, buttonCancelText, buttonConfirmCallback, buttonCancelCallback + return new Promise(resolve => { + const dialog = $(".dialogInteractive"); + const title = dialog.find(".dialogInteractiveTitle"); + const content = dialog.find(".dialogInteractiveContent"); + const buttonClose = dialog.find(".dialogInteractive-closeButton"); + + title.html(interactiveDialogSettings.title); + content.html(interactiveDialogSettings.text); + buttonClose.html(interactiveDialogSettings.buttonCloseText); + + buttonClose.off("click"); + + buttonClose.on("click", () => { + dialog[0].close(); + resolve(); + }); + + dialog[0].showModal(); + }); + } escapeHtml(unsafe) { return unsafe .replace(/&/g, "&") @@ -435,6 +458,37 @@ class GuiControl { $(this).attr('target', '_blank'); }); } + showCliPanel() { + function set_cli_response(response) { + const eol = '\n'; + let output = `${eol}`; + for (const line of response) { + output += `${line}${eol}`; + } + // gui_log(output.split(eol).join('
')); + $('#cli-response').text(output); + $("#cli-command").val(''); + } + + // cli-command button hook + $('input#cli-command').change(function () { + const _self = $(this); + const command = _self.val(); + if (!command) { + return; + } + MSP.send_cli_command(command, function (response) { + set_cli_response(response); + }); + }); + + const cliPanelDialog = { + title : i18n.getMessage("cliPanelTitle"), + buttonCloseText: i18n.getMessage("Close"), + }; + + this.showInteractiveDialog(cliPanelDialog); + } } function GUI_checkOperatingSystem() { diff --git a/src/js/main.js b/src/js/main.js index e6826222a16..f95511262cb 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -366,8 +366,30 @@ function startProcess() { if (whitelist.indexOf(e.keyCode) === -1) { e.preventDefault(); } + + if (e.keyCode === 190 || e.keyCode === 110) { + // only allow one decimal point + if ($(this).val().indexOf('.') !== -1) { + e.preventDefault(); + } + } + + if (e.keyCode === 189 || e.keyCode === 109) { + // only allow minus sign at the beginning + if ($(this).val().indexOf('-') !== -1 || $(this).prop('selectionStart') !== 0) { + e.preventDefault(); + } + } }); + // show interactive CLI on Control+C + document.onkeydown = function (e) { + if (e.ctrlKey && e.keyCode === 67) { + console.log('Interactive CLI requested'); + GUI.showCliPanel(); + } + }; + $("#content").on('change', 'input[type="number"]', function () { const element = $(this); const min = parseFloat(element.prop('min'));