From fb24dca019b83fd8f7b6eaa3067e499416d60c99 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Sun, 12 Mar 2017 23:52:31 +0000 Subject: [PATCH] Add JSON Expression editor --- editor/js/ui/common/typedInput.js | 26 ++++++++- editor/js/ui/editor.js | 91 ++++++++++++++++++++++++++++++- editor/templates/index.mst | 11 ++++ 3 files changed, 125 insertions(+), 3 deletions(-) diff --git a/editor/js/ui/common/typedInput.js b/editor/js/ui/common/typedInput.js index 5cf02086a..3b0a56753 100644 --- a/editor/js/ui/common/typedInput.js +++ b/editor/js/ui/common/typedInput.js @@ -21,7 +21,31 @@ str: {value:"str",label:"string",icon:"red/images/typedInput/az.png"}, num: {value:"num",label:"number",icon:"red/images/typedInput/09.png",validate:/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/}, bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.png",options:["true","false"]}, - json: {value:"json",label:"JSON",icon:"red/images/typedInput/json.png", validate: function(v) { try{JSON.parse(v);return true;}catch(e){return false;}}}, + json: { + value:"json", + label:"JSON", + icon:"red/images/typedInput/json.png", + validate: function(v) { try{JSON.parse(v);return true;}catch(e){return false;}}, + expand: function() { + var that = this; + var value = this.value(); + try { + value = JSON.stringify(JSON.parse(value),null,4); + } catch(err) { + } + RED.editor.editJSON({ + value: value, + complete: function(v) { + var value = v; + try { + value = JSON.stringify(JSON.parse(v)); + } catch(err) { + } + that.value(value); + } + }) + } + }, re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.png"}, date: {value:"date",label:"timestamp",hasValue:false}, jsonata: { diff --git a/editor/js/ui/editor.js b/editor/js/ui/editor.js index f3485ee82..9c873a313 100644 --- a/editor/js/ui/editor.js +++ b/editor/js/ui/editor.js @@ -493,7 +493,9 @@ RED.editor = (function() { var node = editStack[i]; var label = node.type; if (node.type === '_expression') { - label = "Expression editor"; + label = "Expression editor"; // TODO: nls + } else if (node.type === '_json') { + label = "JSON editor"; // TODO: nls } else if (node.type === 'subflow') { label = RED._("subflow.editSubflow",{name:node.name}) } else if (node.type.indexOf("subflow:")===0) { @@ -1730,7 +1732,91 @@ RED.editor = (function() { var snippet = jsonata.getFunctionSnippet(f); expressionEditor.insertSnippet(snippet); expressionEditor.focus(); - }) + }); + $("#node-input-expression-reformat").click(function(evt) { + evt.preventDefault(); + var v = expressionEditor.getValue()||""; + try { + v = jsonata.format(v); + } catch(err) { + // TODO: do an optimistic auto-format + } + expressionEditor.getSession().setValue(v||"",-1); + }); + }, + close: function() { + editStack.pop(); + }, + show: function() {} + } + if (editTrayWidthCache.hasOwnProperty(type)) { + trayOptions.width = editTrayWidthCache[type]; + } + RED.tray.show(trayOptions); + } + + + function editJSON(options) { + var value = options.value; + var onComplete = options.complete; + var type = "_json" + editStack.push({type:type}); + RED.view.state(RED.state.EDITING); + var expressionEditor; + + var trayOptions = { + title: getEditStackTitle(), + buttons: [ + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + text: RED._("common.label.done"), + class: "primary", + click: function() { + onComplete(expressionEditor.getValue()); + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + editTrayWidthCache[type] = dimensions.width; + + var rows = $("#dialog-form>div:not(.node-text-editor-row)"); + var editorRow = $("#dialog-form>div.node-text-editor-row"); + var height = $("#dialog-form").height(); + for (var i=0;i +