From d287b8867b21d20770bf2a57e39202bf2b138eba Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Fri, 8 Dec 2023 15:28:49 +0900 Subject: [PATCH 01/26] Add Japanese translations for v3.1.3 --- .../@node-red/editor-client/locales/ja/editor.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json index ceb001a10..41cbab80b 100644 --- a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json @@ -130,6 +130,11 @@ "editPalette": "パレットの管理", "other": "その他", "showTips": "ヒントを表示", + "showNodeHelp": "ノードのヘルプを表示", + "enableSelectedNodes": "選択したノードを有効化", + "disableSelectedNodes": "選択したノードを無効化", + "showSelectedNodeLabels": "選択したノードのラベル表示", + "hideSelectedNodeLabels": "選択したノードのラベル非表示", "showWelcomeTours": "新バージョンのガイドツアーを表示", "help": "Node-REDウェブサイト", "projects": "プロジェクト", @@ -1215,6 +1220,7 @@ "validator": { "errors": { "invalid-json": "JSONデータが不正: __error__", + "invalid-expr": "不正なJSONata式: __error__", "invalid-prop": "プロパティ式が不正", "invalid-num": "数値が不正", "invalid-regexp": "入力パターンが不正", @@ -1226,6 +1232,7 @@ } }, "contextMenu": { + "showActionList": "動作一覧を表示", "insert": "挿入", "node": "ノード", "junction": "分岐点", From b5e955bd5e0c4106246c757812700ad87842e3fb Mon Sep 17 00:00:00 2001 From: Gerrit Riessen Date: Wed, 13 Dec 2023 17:29:39 +0100 Subject: [PATCH 02/26] Update index.mst Avoid escaping slashes (`/`) in asset paths. Content is currently generated as: ``` Node-RED
``` It still works of course, so feel free to ignore this change. --- .../@node-red/editor-client/templates/index.mst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/templates/index.mst b/packages/node_modules/@node-red/editor-client/templates/index.mst index 01bf06545..6d204cd5c 100644 --- a/packages/node_modules/@node-red/editor-client/templates/index.mst +++ b/packages/node_modules/@node-red/editor-client/templates/index.mst @@ -23,7 +23,7 @@ --> {{ page.title }} - + @@ -40,8 +40,8 @@ {{#asset.vendorMonaco}} {{/asset.vendorMonaco}} - - + + {{# page.scripts }} {{/ page.scripts }} From e1f2e0656b15b7d1de564295a5afdf6feeae6d7a Mon Sep 17 00:00:00 2001 From: Gerrit Riessen Date: Fri, 15 Dec 2023 10:54:11 +0100 Subject: [PATCH 03/26] Client Events: fix off-in-on pattern emulating once This fixes an issue when RED.events.off(..) is called in a RED.events.on(..) callback: ``` let cb = () => { RED.events.off("event-name", cb) .... } RED.events.on("event-name", cb) ``` This pattern emulates a once(..), i.e., execute a callback once-only for an event. Discussed in [Forum](https://discourse.nodered.org/t/event-offing-an-on-event-to-perform-only-once/83726) --- .../node_modules/@node-red/editor-client/src/js/events.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/events.js b/packages/node_modules/@node-red/editor-client/src/js/events.js index bd2abd8d0..943854393 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/events.js +++ b/packages/node_modules/@node-red/editor-client/src/js/events.js @@ -39,15 +39,16 @@ console.warn(evt,args); } if (handlers[evt]) { - for (var i=0;i Date: Fri, 15 Dec 2023 11:32:26 +0100 Subject: [PATCH 04/26] Update index.mst Update two additional path specifications --- .../node_modules/@node-red/editor-client/templates/index.mst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/templates/index.mst b/packages/node_modules/@node-red/editor-client/templates/index.mst index 6d204cd5c..2d9c376cb 100644 --- a/packages/node_modules/@node-red/editor-client/templates/index.mst +++ b/packages/node_modules/@node-red/editor-client/templates/index.mst @@ -22,7 +22,7 @@ limitations under the License. --> {{ page.title }} - + @@ -38,7 +38,7 @@
{{#asset.vendorMonaco}} - + {{/asset.vendorMonaco}} From 70ea5c839af7b1f26f8f19cdce1ac049f5b3e70d Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sat, 16 Dec 2023 17:02:18 +0900 Subject: [PATCH 05/26] Add handling to disable items on context menu --- .../@node-red/editor-client/src/js/ui/contextMenu.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js index cf3e56f8c..d29998c75 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js @@ -31,7 +31,9 @@ RED.contextMenu = (function () { const canEdit = !RED.workspaces.isLocked() const canRemoveFromGroup = hasSelection && !!selection.nodes[0].g const isAllGroups = hasSelection && selection.nodes.filter(n => n.type !== 'group').length === 0 - const hasGroup = hasSelection && selection.nodes.filter(n => n.type === 'group' ).length > 0 + const hasGroup = hasSelection && selection.nodes.filter(n => n.type === 'group').length > 0 + const hasDisabledNode = hasSelection && selection.nodes.filter(e => e.d).length > 0; + const hasEnabledNode = hasSelection && selection.nodes.filter(e => !e.d).length > 0; const offset = $("#red-ui-workspace-chart").offset() let addX = options.x - offset.left + $("#red-ui-workspace-chart").scrollLeft() @@ -113,8 +115,8 @@ RED.contextMenu = (function () { ) } nodeOptions.push( - { onselect: 'core:enable-selected-nodes', label: RED._('menu.label.enableSelectedNodes') }, - { onselect: 'core:disable-selected-nodes', label: RED._('menu.label.disableSelectedNodes') }, + { onselect: 'core:enable-selected-nodes', label: RED._('menu.label.enableSelectedNodes'), disabled: !hasDisabledNode }, + { onselect: 'core:disable-selected-nodes', label: RED._('menu.label.disableSelectedNodes'), disabled: !hasEnabledNode }, null, { onselect: 'core:show-selected-node-labels', label: RED._('menu.label.showSelectedNodeLabels') }, { onselect: 'core:hide-selected-node-labels', label: RED._('menu.label.hideSelectedNodeLabels') } From 1828d8a279a2bdfe961ed2af269fe4aba562e21f Mon Sep 17 00:00:00 2001 From: GogoVega <92022724+GogoVega@users.noreply.github.com> Date: Sun, 17 Dec 2023 19:59:16 +0100 Subject: [PATCH 06/26] Add missing validation messages --- .../@node-red/editor-client/locales/en-US/editor.json | 1 + .../node_modules/@node-red/editor-client/locales/fr/editor.json | 1 + .../node_modules/@node-red/editor-client/locales/ja/editor.json | 1 + .../@node-red/editor-client/locales/pt-BR/editor.json | 1 + .../@node-red/editor-client/locales/zh-CN/editor.json | 1 + 5 files changed, 5 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json index 1836b6a9e..709048a39 100644 --- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json @@ -1223,6 +1223,7 @@ "invalid-expr": "Invalid JSONata expression: __error__", "invalid-prop": "Invalid property expression", "invalid-num": "Invalid number", + "invalid-num-prop": "__prop__: invalid number", "invalid-regexp": "Invalid input pattern", "invalid-regex-prop": "__prop__: invalid input pattern", "missing-required-prop": "__prop__: property value missing", diff --git a/packages/node_modules/@node-red/editor-client/locales/fr/editor.json b/packages/node_modules/@node-red/editor-client/locales/fr/editor.json index b58bed283..ca9cefe18 100644 --- a/packages/node_modules/@node-red/editor-client/locales/fr/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/fr/editor.json @@ -1218,6 +1218,7 @@ "invalid-expr": "Expression JSONata invalide : __error__", "invalid-prop": "Expression de propriété invalide", "invalid-num": "Numéro invalide", + "invalid-num-prop": "__prop__: numéro invalide", "invalid-regexp": "Modèle d'entrée non valide", "invalid-regex-prop": "__prop__: modèle d'entrée non valide", "missing-required-prop": "__prop__: valeur de la propriété manquante", diff --git a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json index ceb001a10..20c2647cb 100644 --- a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json @@ -1217,6 +1217,7 @@ "invalid-json": "JSONデータが不正: __error__", "invalid-prop": "プロパティ式が不正", "invalid-num": "数値が不正", + "invalid-num-prop": "__prop__: 数値が不正", "invalid-regexp": "入力パターンが不正", "invalid-regex-prop": "__prop__: 入力パターンが不正", "missing-required-prop": "__prop__: プロパティが未設定", diff --git a/packages/node_modules/@node-red/editor-client/locales/pt-BR/editor.json b/packages/node_modules/@node-red/editor-client/locales/pt-BR/editor.json index f65ec62e9..48d3ce931 100644 --- a/packages/node_modules/@node-red/editor-client/locales/pt-BR/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/pt-BR/editor.json @@ -1188,6 +1188,7 @@ "invalid-json": "Dados JSON inválidos: __error__", "invalid-prop": "Expressão de propriedade inválida", "invalid-num": "Número inválido", + "invalid-num-prop": "__prop__: número inválido", "invalid-regexp": "Padrão de entrada inválido", "invalid-regex-prop": "__prop__: Padrão de entrada inválido", "missing-required-prop": "__prop__: valor de propriedade ausente", diff --git a/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json b/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json index 271326d05..d1df9bb25 100644 --- a/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json @@ -1221,6 +1221,7 @@ "invalid-expr": "无效的 JSONata 表达式: __error__", "invalid-prop": "无效的属性表达式", "invalid-num": "无效的数字", + "invalid-num-prop": "__prop__: 无效的数字", "invalid-regexp": "输入格式无效", "invalid-regex-prop": "__prop__: 输入格式无效", "missing-required-prop": "__prop__: 缺少属性值", From c31e6221601c2b05452037806140e25eb07709a0 Mon Sep 17 00:00:00 2001 From: Ralph Wetzel Date: Wed, 20 Dec 2023 17:14:12 +0100 Subject: [PATCH 07/26] Fix icon scaling for non .svg icons --- .../node_modules/@node-red/editor-client/src/js/ui/view.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js index 56a29e421..fa20f3f61 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js @@ -4155,10 +4155,15 @@ RED.view = (function() { scaleFactor = 30/largestEdge; } var width = img.width * scaleFactor; + if (width > 20) { + scalefactor *= 20/width; + width = 20; + } var height = img.height * scaleFactor; icon.attr("width",width); icon.attr("height",height); icon.attr("x",15-width/2); + icon.attr("y",(30-height)/2); } icon.attr("xlink:href",iconUrl); icon.style("display",null); From 74ff0599d155cbad15f5ad21c65ceef38c4024d6 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sat, 23 Dec 2023 19:51:57 +0900 Subject: [PATCH 08/26] Fix location of subflow ports in palette --- .../node_modules/@node-red/editor-client/src/js/ui/palette.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js index db915fd8b..6b9beb326 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js @@ -484,7 +484,8 @@ RED.palette = (function() { var currentLabel = paletteNode.attr("data-palette-label"); var currentInfo = paletteNode.attr("data-palette-info"); - if (currentLabel !== sf.name || currentInfo !== sf.info) { + if (currentLabel !== sf.name || currentInfo !== sf.info + || sf.in.length > 0 || sf.out.length > 0) { paletteNode.attr("data-palette-info",sf.info); setLabel(sf.type+":"+sf.id,paletteNode,sf.name,RED.utils.renderMarkdown(sf.info||"")); } From 8f5ebfcede1daa85cd65ae48fa5cbda651fa3eb5 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Fri, 29 Dec 2023 15:41:40 +0900 Subject: [PATCH 09/26] Update Japanese translation for v3.1.3 --- .../node_modules/@node-red/editor-client/locales/ja/editor.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json index 41cbab80b..7602d7f70 100644 --- a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json @@ -516,7 +516,7 @@ "selectAllConnected": "接続されたノードを選択", "addRemoveNode": "ノードの選択、選択解除", "editSelected": "選択したノードを編集", - "deleteSelected": "選択したノードや接続を削除", + "deleteSelected": "選択部分を削除", "deleteReconnect": "削除と再接続", "importNode": "フローの読み込み", "exportNode": "フローの書き出し", From aaed9882b89d2dc0a44539de8875660db47f4cd7 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Fri, 29 Dec 2023 17:51:03 +0900 Subject: [PATCH 10/26] Add handling to disable items on context menu for node labels --- .../@node-red/editor-client/src/js/ui/contextMenu.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js index d29998c75..63fb04a28 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js @@ -34,6 +34,8 @@ RED.contextMenu = (function () { const hasGroup = hasSelection && selection.nodes.filter(n => n.type === 'group').length > 0 const hasDisabledNode = hasSelection && selection.nodes.filter(e => e.d).length > 0; const hasEnabledNode = hasSelection && selection.nodes.filter(e => !e.d).length > 0; + const hasUnlabeledNode = hasSelection && selection.nodes.filter(e => e.l === false).length > 0; + const hasLabeledNode = hasSelection && selection.nodes.filter(e => e.l || e.l === undefined).length > 0; const offset = $("#red-ui-workspace-chart").offset() let addX = options.x - offset.left + $("#red-ui-workspace-chart").scrollLeft() @@ -118,8 +120,8 @@ RED.contextMenu = (function () { { onselect: 'core:enable-selected-nodes', label: RED._('menu.label.enableSelectedNodes'), disabled: !hasDisabledNode }, { onselect: 'core:disable-selected-nodes', label: RED._('menu.label.disableSelectedNodes'), disabled: !hasEnabledNode }, null, - { onselect: 'core:show-selected-node-labels', label: RED._('menu.label.showSelectedNodeLabels') }, - { onselect: 'core:hide-selected-node-labels', label: RED._('menu.label.hideSelectedNodeLabels') } + { onselect: 'core:show-selected-node-labels', label: RED._('menu.label.showSelectedNodeLabels'), disabled: !hasUnlabeledNode }, + { onselect: 'core:hide-selected-node-labels', label: RED._('menu.label.hideSelectedNodeLabels'), disabled: !hasLabeledNode } ) menuItems.push({ label: RED._('sidebar.info.node'), From 8365310ca7cd8095382c39c7562e4eb8598386de Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Fri, 29 Dec 2023 20:32:14 +0900 Subject: [PATCH 11/26] Put the changed code on one line to avoid jshint error --- .../node_modules/@node-red/editor-client/src/js/ui/palette.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js index 6b9beb326..23f30fc61 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js @@ -484,8 +484,7 @@ RED.palette = (function() { var currentLabel = paletteNode.attr("data-palette-label"); var currentInfo = paletteNode.attr("data-palette-info"); - if (currentLabel !== sf.name || currentInfo !== sf.info - || sf.in.length > 0 || sf.out.length > 0) { + if (currentLabel !== sf.name || currentInfo !== sf.info || sf.in.length > 0 || sf.out.length > 0) { paletteNode.attr("data-palette-info",sf.info); setLabel(sf.type+":"+sf.id,paletteNode,sf.name,RED.utils.renderMarkdown(sf.info||"")); } From 7f24de442f997e376b512b79258f083c6010a12e Mon Sep 17 00:00:00 2001 From: GogoVega <92022724+GogoVega@users.noreply.github.com> Date: Mon, 1 Jan 2024 15:33:39 +0100 Subject: [PATCH 12/26] Replace 'rename' with 'edit' for the flow label --- .../node_modules/@node-red/editor-client/locales/de/editor.json | 1 - .../@node-red/editor-client/locales/en-US/editor.json | 1 - .../node_modules/@node-red/editor-client/locales/fr/editor.json | 1 - .../node_modules/@node-red/editor-client/locales/ja/editor.json | 1 - .../node_modules/@node-red/editor-client/locales/ko/editor.json | 1 - .../@node-red/editor-client/locales/pt-BR/editor.json | 1 - .../node_modules/@node-red/editor-client/locales/ru/editor.json | 1 - .../@node-red/editor-client/locales/zh-CN/editor.json | 1 - .../@node-red/editor-client/locales/zh-TW/editor.json | 1 - packages/node_modules/@node-red/editor-client/src/js/red.js | 2 +- 10 files changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/locales/de/editor.json b/packages/node_modules/@node-red/editor-client/locales/de/editor.json index f2955c266..bb811eae4 100644 --- a/packages/node_modules/@node-red/editor-client/locales/de/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/de/editor.json @@ -109,7 +109,6 @@ "selectionToSubflow": "Auswahl in Subflow umwandeln", "flows": "Flow", "add": "Hinzufügen", - "rename": "Umbenennen", "delete": "Löschen", "keyboardShortcuts": "Tastenkürzel", "login": "Anmelden", diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json index 1836b6a9e..68e89366e 100644 --- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json @@ -122,7 +122,6 @@ "selectionToSubflow": "Selection to Subflow", "flows": "Flows", "add": "Add", - "rename": "Rename", "delete": "Delete", "keyboardShortcuts": "Keyboard shortcuts", "login": "Login", diff --git a/packages/node_modules/@node-red/editor-client/locales/fr/editor.json b/packages/node_modules/@node-red/editor-client/locales/fr/editor.json index b58bed283..35c1de246 100644 --- a/packages/node_modules/@node-red/editor-client/locales/fr/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/fr/editor.json @@ -122,7 +122,6 @@ "selectionToSubflow": "Convertir en sous-flux", "flows": "Flux", "add": "Ajouter", - "rename": "Renommer", "delete": "Supprimer", "keyboardShortcuts": "Raccourcis clavier", "login": "Se connecter", diff --git a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json index ceb001a10..05dd1b93e 100644 --- a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json @@ -122,7 +122,6 @@ "selectionToSubflow": "選択部分をサブフロー化", "flows": "フロー", "add": "フローを新規追加", - "rename": "フロー名を変更", "delete": "フローを削除", "keyboardShortcuts": "ショートカットキーの説明", "login": "ログイン", diff --git a/packages/node_modules/@node-red/editor-client/locales/ko/editor.json b/packages/node_modules/@node-red/editor-client/locales/ko/editor.json index ad4f4354f..4de2cb5d2 100644 --- a/packages/node_modules/@node-red/editor-client/locales/ko/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/ko/editor.json @@ -79,7 +79,6 @@ "selectionToSubflow": "서브 플로우 선택", "flows": "플로우", "add": "추가", - "rename": "이름변경", "delete": "삭제", "keyboardShortcuts": "단축키", "login": "로그인", diff --git a/packages/node_modules/@node-red/editor-client/locales/pt-BR/editor.json b/packages/node_modules/@node-red/editor-client/locales/pt-BR/editor.json index f65ec62e9..cb43e1051 100644 --- a/packages/node_modules/@node-red/editor-client/locales/pt-BR/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/pt-BR/editor.json @@ -109,7 +109,6 @@ "selectionToSubflow": "Seleção para subfluxo", "flows": "Fluxos", "add": "Adicionar", - "rename": "Renomear", "delete": "Apagar", "keyboardShortcuts": "Atalhos do teclado", "login": "Ingressar", diff --git a/packages/node_modules/@node-red/editor-client/locales/ru/editor.json b/packages/node_modules/@node-red/editor-client/locales/ru/editor.json index 8cfea1bde..69562f806 100644 --- a/packages/node_modules/@node-red/editor-client/locales/ru/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/ru/editor.json @@ -95,7 +95,6 @@ "selectionToSubflow": "Выделение в подпоток", "flows": "Потоки", "add": "Добавить", - "rename": "Переименовать", "delete": "Удалить", "keyboardShortcuts": "Сочетания клавиш", "login": "Войти", diff --git a/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json b/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json index 271326d05..9d98ef8af 100644 --- a/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json @@ -120,7 +120,6 @@ "selectionToSubflow": "将选择部分更改为子流程", "flows": "流程", "add": "增加", - "rename": "重命名", "delete": "删除", "keyboardShortcuts": "键盘快捷方式", "login": "登录", diff --git a/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json b/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json index 022205a70..485ce3c2f 100644 --- a/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json @@ -120,7 +120,6 @@ "selectionToSubflow": "將選擇部分更改為子流程", "flows": "流程", "add": "增加", - "rename": "重新命名", "delete": "刪除", "keyboardShortcuts": "鍵盤快速鍵", "login": "登入", diff --git a/packages/node_modules/@node-red/editor-client/src/js/red.js b/packages/node_modules/@node-red/editor-client/src/js/red.js index 3878965e3..d13d7ca24 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/red.js +++ b/packages/node_modules/@node-red/editor-client/src/js/red.js @@ -722,7 +722,7 @@ var RED = (function() { menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:"core:show-config-tab"}); menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[ {id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:"core:add-flow"}, - {id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:"core:edit-flow"}, + {id:"menu-item-workspace-edit",label:RED._("menu.label.edit"),onselect:"core:edit-flow"}, {id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:"core:remove-flow"} ]}); menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [ From d7345d5bc6033e0231ae77bb3e49741d3d318b74 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 5 Jan 2024 23:13:30 +0000 Subject: [PATCH 13/26] Restore caching busting functionality without using explict version number Fixes #4503 --- .../@node-red/editor-api/lib/editor/ui.js | 4 ++++ .../@node-red/editor-client/templates/index.mst | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/ui.js b/packages/node_modules/@node-red/editor-api/lib/editor/ui.js index 998816f5e..00e32dd5f 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/ui.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/ui.js @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +const crypto = require('crypto') var express = require('express'); var fs = require("fs"); var path = require("path"); @@ -28,6 +29,8 @@ var editorClientDir = path.dirname(require.resolve("@node-red/editor-client")); var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.svg"); var editorTemplatePath = path.join(editorClientDir,"templates","index.mst"); var editorTemplate; +const version = require(path.join(editorClientDir,"package.json")).version +const cacheBuster = crypto.createHash('md5').update(version).digest("hex").substring(0,12) module.exports = { init: function(_runtimeAPI) { @@ -99,6 +102,7 @@ module.exports = { } res.send(Mustache.render(editorTemplate,{ sessionMessages, + cacheBuster, ...await theme.context() })); }, diff --git a/packages/node_modules/@node-red/editor-client/templates/index.mst b/packages/node_modules/@node-red/editor-client/templates/index.mst index 01bf06545..748a54bab 100644 --- a/packages/node_modules/@node-red/editor-client/templates/index.mst +++ b/packages/node_modules/@node-red/editor-client/templates/index.mst @@ -24,24 +24,24 @@ {{ page.title }} - - - + + + {{#page.css}} {{/page.css}} {{#asset.vendorMonaco}} - + {{/asset.vendorMonaco}}
- + {{#asset.vendorMonaco}} - + {{/asset.vendorMonaco}} - - + + {{# page.scripts }} {{/ page.scripts }} From 84ed88c8ddda29ef33f86ead0790fc2ff506d24d Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sun, 7 Jan 2024 18:40:39 +0900 Subject: [PATCH 14/26] Use single `forEach` instead of multiple `filter` --- .../editor-client/src/js/ui/contextMenu.js | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js index 63fb04a28..9286cc547 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js @@ -30,12 +30,26 @@ RED.contextMenu = (function () { const isGroup = hasSelection && selection.nodes.length === 1 && selection.nodes[0].type === 'group' const canEdit = !RED.workspaces.isLocked() const canRemoveFromGroup = hasSelection && !!selection.nodes[0].g - const isAllGroups = hasSelection && selection.nodes.filter(n => n.type !== 'group').length === 0 - const hasGroup = hasSelection && selection.nodes.filter(n => n.type === 'group').length > 0 - const hasDisabledNode = hasSelection && selection.nodes.filter(e => e.d).length > 0; - const hasEnabledNode = hasSelection && selection.nodes.filter(e => !e.d).length > 0; - const hasUnlabeledNode = hasSelection && selection.nodes.filter(e => e.l === false).length > 0; - const hasLabeledNode = hasSelection && selection.nodes.filter(e => e.l || e.l === undefined).length > 0; + let hasGroup, isAllGroups = true, hasDisabledNode, hasEnabledNode, hasLabeledNode, hasUnlabeledNode; + if (hasSelection) { + selection.nodes.forEach(n => { + if (n.type === 'group') { + hasGroup = true; + } else { + isAllGroups = false; + } + if (n.d) { + hasDisabledNode = true; + } else { + hasEnabledNode = true; + } + if (n.l === undefined || n.l) { + hasLabeledNode = true; + } else { + hasUnlabeledNode = true; + } + }); + } const offset = $("#red-ui-workspace-chart").offset() let addX = options.x - offset.left + $("#red-ui-workspace-chart").scrollLeft() From 6c64ba45c259763a9c9fb1f118c1e64b49ec1425 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sun, 7 Jan 2024 20:46:50 +0900 Subject: [PATCH 15/26] Focus Quick Add dialog from context menu --- .../@node-red/editor-client/src/js/ui/contextMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js index cf3e56f8c..11f6ed09d 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js @@ -55,7 +55,7 @@ RED.contextMenu = (function () { onselect: function () { RED.view.showQuickAddDialog({ position: [addX, addY], - touchTrigger: true, + touchTrigger: 'ontouchstart' in window, splice: isSingleLink ? selection.links[0] : undefined, // spliceMultiple: isMultipleLinks }) From 59ea7a4f7027d685e553467159d10a88c476ce53 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Mon, 8 Jan 2024 03:12:36 +0900 Subject: [PATCH 16/26] Fix subflow ports in Quick Add dialog --- .../@node-red/editor-client/src/js/ui/typeSearch.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js b/packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js index 872169828..3d05fd1c8 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js @@ -186,8 +186,15 @@ RED.typeSearch = (function() { var iconContainer = $('
',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); RED.utils.createIconElement(icon_url, iconContainer, false); - - if (!/^_action_:/.test(object.type) && object.type !== "junction") { + if (/^subflow:/.test(object.type)) { + var sf = RED.nodes.subflow(object.type.substring(8)); + if (sf.in.length > 0) { + $('
',{class:"red-ui-search-result-node-port"}).appendTo(nodeDiv); + } + if (sf.out.length > 0) { + $('
',{class:"red-ui-search-result-node-port red-ui-search-result-node-output"}).appendTo(nodeDiv); + } + } else if (!/^_action_:/.test(object.type) && object.type !== "junction") { if (def.inputs > 0) { $('
',{class:"red-ui-search-result-node-port"}).appendTo(nodeDiv); } From 3a6b1e86dc55be0b431cb8769f1e8a4a7881898b Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 8 Jan 2024 20:56:17 +0000 Subject: [PATCH 17/26] Clone objects types when getting env values Fixes #4479 --- .../node_modules/@node-red/runtime/lib/flows/Flow.js | 2 +- .../node_modules/@node-red/runtime/lib/flows/Group.js | 2 +- .../@node-red/runtime/lib/flows/Subflow.js | 2 +- .../node_modules/@node-red/runtime/lib/flows/util.js | 11 +++++++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js index 2833341c6..b541a9d95 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js @@ -485,7 +485,7 @@ class Flow { } if (!key.startsWith("$parent.")) { if (this._env.hasOwnProperty(key)) { - return this._env[key] + return (Object.hasOwn(this._env[key], 'value') && this._env[key].__clone__) ? clone(this._env[key].value) : this._env[key] } } else { key = key.substring(8); diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Group.js b/packages/node_modules/@node-red/runtime/lib/flows/Group.js index dc05211a1..521b6ceda 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/Group.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/Group.js @@ -41,7 +41,7 @@ class Group { } if (!key.startsWith("$parent.")) { if (this._env.hasOwnProperty(key)) { - return this._env[key] + return (Object.hasOwn(this._env[key], 'value') && this._env[key].__clone__) ? clone(this._env[key].value) : this._env[key] } } else { key = key.substring(8); diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js b/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js index 15d8d6c37..031e75c36 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js @@ -375,7 +375,7 @@ class Subflow extends Flow { } if (!key.startsWith("$parent.")) { if (this._env.hasOwnProperty(key)) { - return this._env[key] + return (Object.hasOwn(this._env[key], 'value') && this._env[key].__clone__) ? clone(this._env[key].value) : this._env[key] } } else { key = key.substring(8); diff --git a/packages/node_modules/@node-red/runtime/lib/flows/util.js b/packages/node_modules/@node-red/runtime/lib/flows/util.js index 2559fd1da..76dbe2223 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/util.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/util.js @@ -102,6 +102,9 @@ async function evaluateEnvProperties(flow, env, credentials) { pendingEvaluations.push(new Promise((resolve, _) => { redUtil.evaluateNodeProperty(value, 'jsonata', {_flow: flow}, null, (err, result) => { if (!err) { + if (typeof result === 'object') { + result = { value: result, __clone__: true} + } evaluatedEnv[name] = result } resolve() @@ -109,6 +112,9 @@ async function evaluateEnvProperties(flow, env, credentials) { })) } else { value = redUtil.evaluateNodeProperty(value, type, {_flow: flow}, null, null); + if (typeof value === 'object') { + value = { value: value, __clone__: true} + } } evaluatedEnv[name] = value } @@ -138,8 +144,13 @@ async function evaluateEnvProperties(flow, env, credentials) { } }}, null, null); } + if (typeof value === 'object' && !value.__clone__) { + value = { value: value, __clone__: true} + } evaluatedEnv[name] = value + } + // console.log(evaluatedEnv) return evaluatedEnv } From 50627cd697367cfc047d8c68f3501ee83f0763e4 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 8 Jan 2024 23:27:14 +0000 Subject: [PATCH 18/26] Generate instanceId and include in hash for cache busting --- .../@node-red/editor-api/lib/editor/index.js | 2 +- .../@node-red/editor-api/lib/editor/ui.js | 13 ++++++++++--- .../node_modules/@node-red/runtime/lib/index.js | 11 ++++++++--- .../unit/@node-red/editor-api/lib/editor/ui_spec.js | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/index.js b/packages/node_modules/@node-red/editor-api/lib/editor/index.js index 42be1f270..648daa09b 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/index.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/index.js @@ -51,7 +51,7 @@ module.exports = { var ui = require("./ui"); - ui.init(runtimeAPI); + ui.init(settings, runtimeAPI); const editorApp = apiUtil.createExpressApp(settings) diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/ui.js b/packages/node_modules/@node-red/editor-api/lib/editor/ui.js index 00e32dd5f..e7bf15069 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/ui.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/ui.js @@ -25,15 +25,16 @@ var apiUtils = require("../util"); var theme = require("./theme"); var runtimeAPI; +let settings; var editorClientDir = path.dirname(require.resolve("@node-red/editor-client")); var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.svg"); var editorTemplatePath = path.join(editorClientDir,"templates","index.mst"); var editorTemplate; -const version = require(path.join(editorClientDir,"package.json")).version -const cacheBuster = crypto.createHash('md5').update(version).digest("hex").substring(0,12) +let cacheBuster module.exports = { - init: function(_runtimeAPI) { + init: function(_settings, _runtimeAPI) { + settings = _settings; runtimeAPI = _runtimeAPI; editorTemplate = fs.readFileSync(editorTemplatePath,"utf8"); Mustache.parse(editorTemplate); @@ -94,6 +95,12 @@ module.exports = { }, editor: async function(req,res) { + if (!cacheBuster) { + // settings.instanceId is set asynchronously to the editor-api + // being initiaised. So we defer calculating the cacheBuster hash + // until the first load of the editor + cacheBuster = crypto.createHash('md5').update(`${settings.version || 'version'}-${settings.instanceId || 'instanceId'}`).digest("hex").substring(0,12) + } let sessionMessages; if (req.session && req.session.messages) { diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index 74f03c55c..1bae5e99f 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -27,6 +27,7 @@ var express = require("express"); var path = require('path'); var fs = require("fs"); var os = require("os"); +const crypto = require("crypto") const {log,i18n,events,exec,util,hooks} = require("@node-red/util"); @@ -51,7 +52,7 @@ var adminApi = { var nodeApp; var adminApp; var server; - +let userSettings; /** * Initialise the runtime module. @@ -61,8 +62,9 @@ var server; * better abstracted. * @memberof @node-red/runtime */ -function init(userSettings,httpServer,_adminApi) { +function init(_userSettings,httpServer,_adminApi) { server = httpServer; + userSettings = _userSettings if (server && server.on) { // Add a listener to the upgrade event so that we can properly timeout connection @@ -134,7 +136,10 @@ function start() { .then(function() { return settings.load(storage)}) .then(function() { return library.init(runtime)}) .then(function() { - + if (settings.get('instanceId') === undefined) { + settings.set('instanceId', crypto.randomBytes(8).toString('hex')) + } + userSettings.instanceId = settings.get('instanceId') || '' if (log.metric()) { runtimeMetricInterval = setInterval(function() { reportMetrics(); diff --git a/test/unit/@node-red/editor-api/lib/editor/ui_spec.js b/test/unit/@node-red/editor-api/lib/editor/ui_spec.js index 0380adcde..beb562650 100644 --- a/test/unit/@node-red/editor-api/lib/editor/ui_spec.js +++ b/test/unit/@node-red/editor-api/lib/editor/ui_spec.js @@ -29,7 +29,7 @@ describe("api/editor/ui", function() { var app; before(function() { - ui.init({ + ui.init({}, { nodes: { getIcon: function(opts) { return new Promise(function(resolve,reject) { From d876146ea546ea6a288c985f57cc09eae30f2ac7 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 8 Jan 2024 23:37:44 +0000 Subject: [PATCH 19/26] Guard settings access --- packages/node_modules/@node-red/runtime/lib/index.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index 1bae5e99f..39b2025c5 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -136,10 +136,12 @@ function start() { .then(function() { return settings.load(storage)}) .then(function() { return library.init(runtime)}) .then(function() { - if (settings.get('instanceId') === undefined) { - settings.set('instanceId', crypto.randomBytes(8).toString('hex')) + if (settings.available()) { + if (settings.get('instanceId') === undefined) { + settings.set('instanceId', crypto.randomBytes(8).toString('hex')) + } + userSettings.instanceId = settings.get('instanceId') || '' } - userSettings.instanceId = settings.get('instanceId') || '' if (log.metric()) { runtimeMetricInterval = setInterval(function() { reportMetrics(); From eb2f57fc0d3addcf0893c7bfc0d012256dd8a786 Mon Sep 17 00:00:00 2001 From: Gerrit Riessen Date: Thu, 11 Jan 2024 12:03:28 +0100 Subject: [PATCH 20/26] removed unused code --- .../nodes/core/network/21-httprequest.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js b/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js index fbdf284fc..62b4d396b 100644 --- a/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js +++ b/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js @@ -141,15 +141,7 @@ in your Node-RED user directory (${RED.settings.userDir}). }); } } - /** - * @param {Object} headersObject - * @param {string} name - * @return {any} value - */ - const getHeaderValue = (headersObject, name) => { - const asLowercase = name.toLowercase(); - return headersObject[Object.keys(headersObject).find(k => k.toLowerCase() === asLowercase)]; - } + this.on("input",function(msg,nodeSend,nodeDone) { checkNodeAgentPatch(); //reset redirectList on each request @@ -300,7 +292,7 @@ in your Node-RED user directory (${RED.settings.userDir}). } opts.headers = {}; - //add msg.headers + //add msg.headers //NOTE: ui headers will take precidence over msg.headers if (msg.headers) { if (msg.headers.hasOwnProperty('x-node-red-request-node')) { @@ -633,7 +625,7 @@ in your Node-RED user directory (${RED.settings.userDir}). msg.payload = msg.payload.toString('utf8'); // txt if (node.ret === "obj") { - if (msg.statusCode == 204){msg.payload= "{}"}; + if (msg.statusCode == 204){msg.payload= "{}"}; try { msg.payload = JSON.parse(msg.payload); } // obj catch(e) { node.warn(RED._("httpin.errors.json-error")); } } @@ -740,7 +732,7 @@ in your Node-RED user directory (${RED.settings.userDir}). * * If the algorithm directive's value ends with "-sess", then HA1 is * HA1=digestCompute(digestCompute(username:realm:password):nonce:cnonce) - * + * * If the algorithm directive's value does not end with "-sess", then HA1 is * HA1=digestCompute(username:realm:password) */ From 58e2fcbeee66f3f9096e9e434d4b69d975ddaac3 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 15 Jan 2024 16:44:43 +0000 Subject: [PATCH 21/26] Ensure global-config credential env vars are merged on deploy Fixes #4508 --- .../editor-client/src/js/ui/env-var.js | 2 +- .../runtime/lib/nodes/credentials.js | 25 ++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/env-var.js b/packages/node_modules/@node-red/editor-client/src/js/ui/env-var.js index 998484858..79c626af4 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/env-var.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/env-var.js @@ -71,7 +71,7 @@ RED.envVar = (function() { }; if (item.name.trim() !== "") { new_env.push(item); - if ((item.type === "cred") && (item.value !== "__PWRD__")) { + if (item.type === "cred") { credentials.map[item.name] = item.value; credentials.map["has_"+item.name] = (item.value !== ""); item.value = "__PWRD__"; diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js b/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js index 73567f7c4..856e5561b 100644 --- a/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js +++ b/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js @@ -384,10 +384,27 @@ var api = module.exports = { } } } else if (nodeType === "global-config") { - if (JSON.stringify(savedCredentials.map) !== JSON.stringify(newCreds.map)) { - savedCredentials.map = newCreds.map; - dirty = true; - } + const existingCredentialKeys = Object.keys(savedCredentials?.map || []) + const newCredentialKeys = Object.keys(newCreds?.map || []) + existingCredentialKeys.forEach(key => { + if (!newCreds.map?.[key]) { + // This key doesn't exist in the new credentials list - remove + delete savedCredentials.map[key] + delete savedCredentials.map[`has_${key}`] + dirty = true + } + }) + newCredentialKeys.forEach(key => { + if (!/^has_/.test(key)) { + if (!savedCredentials.map?.[key] || newCreds.map[key] !== '__PWRD__') { + // This key either doesn't exist in current saved, or the + // value has been changed + savedCredentials.map[key] = newCreds.map[key] + savedCredentials.map[`has_${key}`] = newCreds.map[`has_${key}`] + dirty = true + } + } + }) } else { var dashedType = nodeType.replace(/\s+/g, '-'); var definition = credentialsDef[dashedType]; From 8a8245b560c22335ea7f7341dcf579cc05d5e97d Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 15 Jan 2024 16:54:16 +0000 Subject: [PATCH 22/26] Include top level property name when copying path from context Fixes #4485 --- .../@node-red/editor-client/src/js/ui/tab-context.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js index 0d8ba103f..6cb034ccc 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js @@ -232,7 +232,7 @@ RED.sidebar.context = (function() { typeHint: data.format, sourceId: id+"."+k, tools: tools, - path: "" + path: k }).appendTo(propRow.children()[1]); } }) @@ -278,7 +278,7 @@ RED.sidebar.context = (function() { typeHint: data.format, sourceId: id+"."+k, tools: tools, - path: "" + path: k }).appendTo(propRow.children()[1]); } }); @@ -299,7 +299,7 @@ RED.sidebar.context = (function() { typeHint: v.format, sourceId: id+"."+k, tools: tools, - path: "" + path: k }).appendTo(propRow.children()[1]); if (contextStores.length > 1) { $("",{class:"red-ui-sidebar-context-property-storename"}).text(v.store).appendTo($(propRow.children()[0])) From 8600f4131e1bc146c60a4253c1bc0a2d0bd7f2d5 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 15 Jan 2024 17:11:54 +0000 Subject: [PATCH 23/26] Modify node users info in config editor footer Fixes #4497 --- .../@node-red/editor-client/src/js/ui/editor.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js index 4908373c7..11fdac279 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js @@ -1231,7 +1231,11 @@ RED.editor = (function() { }) if (node_def.hasUsers !== false) { - $(' ').css("margin-left", "10px").appendTo(trayFooterLeft); + // $(' ').css("margin-left", "10px").appendTo(trayFooterLeft); + $('').on('click', function() { + RED.sidebar.info.outliner.search('uses:'+editing_config_node.id) + RED.sidebar.info.show() + }).appendTo(trayFooterLeft); } trayFooter.append(''); @@ -1289,7 +1293,8 @@ RED.editor = (function() { }); } if (node_def.hasUsers !== false) { - $("#red-ui-editor-config-user-count").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show(); + $("#red-ui-editor-config-user-count").text(editing_config_node.users.length).parent().show(); + RED.popover.tooltip($("#red-ui-editor-config-user-count").parent(), function() { return RED._('editor.nodesUse',{count:editing_config_node.users.length})}); } trayBody.i18n(); trayFooter.i18n(); From 89c2efe17d4750b16f761c78a373a01e7c34dee1 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 15 Jan 2024 17:49:17 +0000 Subject: [PATCH 24/26] Highlight errors in config node sidebar Fixes #4397 --- .../@node-red/editor-client/src/js/ui/tab-config.js | 4 ++++ .../@node-red/editor-client/src/sass/tab-config.scss | 3 +++ 2 files changed, 7 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js index 90ecf6093..16d02456c 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js @@ -158,6 +158,10 @@ RED.sidebar.config = (function() { entry.data('node',node.id); nodeDiv.data('node',node.id); var label = $('
').text(labelText).appendTo(nodeDiv); + + if (!node.valid) { + nodeDiv.addClass("red-ui-palette-node-config-invalid") + } if (node.d) { nodeDiv.addClass("red-ui-palette-node-config-disabled"); $('').prependTo(label); diff --git a/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss b/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss index c1f151ca6..6161cbb82 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss @@ -113,6 +113,9 @@ ul.red-ui-sidebar-node-config-list li.red-ui-palette-node-config-type { margin-right: 5px; } } +.red-ui-palette-node-config-invalid { + border-color: var(--red-ui-node-border-unknown) +} .red-ui-sidebar-node-config-filter-info { position: absolute; top: 0; From b0086edcf909a32696323b890aba2f196a253ec4 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 15 Jan 2024 20:16:18 +0000 Subject: [PATCH 25/26] Update packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss Co-authored-by: Mauricio Bonani --- .../@node-red/editor-client/src/sass/tab-config.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss b/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss index 6161cbb82..52a2bc4e2 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss @@ -114,7 +114,7 @@ ul.red-ui-sidebar-node-config-list li.red-ui-palette-node-config-type { } } .red-ui-palette-node-config-invalid { - border-color: var(--red-ui-node-border-unknown) + border-color: var(--red-ui-form-input-border-error-color) } .red-ui-sidebar-node-config-filter-info { position: absolute; From 6620679008037027b0f07665a29700922d3182fe Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 16 Jan 2024 17:35:50 +0000 Subject: [PATCH 26/26] Show standard validation triangle on config nodes --- .../editor-client/src/js/ui/tab-config.js | 17 ++++++++++++++--- .../editor-client/src/sass/tab-config.scss | 8 +++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js index 16d02456c..e2c8185cb 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js @@ -159,9 +159,6 @@ RED.sidebar.config = (function() { nodeDiv.data('node',node.id); var label = $('
').text(labelText).appendTo(nodeDiv); - if (!node.valid) { - nodeDiv.addClass("red-ui-palette-node-config-invalid") - } if (node.d) { nodeDiv.addClass("red-ui-palette-node-config-disabled"); $('').prependTo(label); @@ -183,6 +180,20 @@ RED.sidebar.config = (function() { nodeDiv.addClass("red-ui-palette-node-config-unused"); } } + + if (!node.valid) { + nodeDiv.addClass("red-ui-palette-node-config-invalid") + const nodeDivAnnotations = $('').appendTo(nodeDiv) + const errorBadge = document.createElementNS("http://www.w3.org/2000/svg","path"); + errorBadge.setAttribute("d","M 0,9 l 10,0 -5,-8 z"); + nodeDivAnnotations.append($(errorBadge)) + RED.popover.tooltip(nodeDivAnnotations, function () { + if (node.validationErrors && node.validationErrors.length > 0) { + return RED._("editor.errors.invalidProperties")+"
- "+node.validationErrors.join("
- ") + } + }) + } + nodeDiv.on('click',function(e) { e.stopPropagation(); RED.view.select(false); diff --git a/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss b/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss index 52a2bc4e2..9d678daa1 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss @@ -36,7 +36,7 @@ ul.red-ui-sidebar-node-config-list { text-align: center; } .red-ui-palette-node { - overflow: hidden; + // overflow: hidden; cursor: default; &.selected { border-color: transparent; @@ -116,6 +116,12 @@ ul.red-ui-sidebar-node-config-list li.red-ui-palette-node-config-type { .red-ui-palette-node-config-invalid { border-color: var(--red-ui-form-input-border-error-color) } +.red-ui-palette-node-annotations { + position: absolute; + left: calc(100% - 15px); + top: -8px; + display: block; +} .red-ui-sidebar-node-config-filter-info { position: absolute; top: 0;