mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge branch 'master' into dev
This commit is contained in:
commit
c6129b44a1
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@ -27,6 +27,9 @@ jobs:
|
||||
with:
|
||||
node-version: '12'
|
||||
- run: node ./node-red/.github/scripts/update-node-red-docker.js
|
||||
with:
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
- name: Create Docker Pull Request
|
||||
uses: peter-evans/create-pull-request@v2
|
||||
with:
|
||||
|
32
CHANGELOG.md
32
CHANGELOG.md
@ -1,3 +1,35 @@
|
||||
### 1.2.5: Maintenance Release
|
||||
|
||||
Editor
|
||||
|
||||
- Fix import of config nodes with unknown z property
|
||||
|
||||
Runtime
|
||||
|
||||
- Set ACTIONS_ALLOW_UNSECURE_COMMANDS in GH Action
|
||||
|
||||
### 1.2.4: Maintenance Release
|
||||
|
||||
Editor
|
||||
|
||||
- Support bigint types in Debug sidebar
|
||||
- Clear retained status of deleted nodes
|
||||
- Prevent needless retention of node status messages
|
||||
- Update projects dialogs to use TypedInput-cred input
|
||||
- Restore cursor position in TypedInput cred-mode
|
||||
- Ensure config nodes with invalid z are imported somewhere
|
||||
- Ensure user keyboard shortcuts override defaults Fixes #2753
|
||||
|
||||
Runtime
|
||||
|
||||
- Disable projects when flowFile passed into grunt dev
|
||||
- Add Russian Locale (#2761) (#2531) (@alexk111)
|
||||
- Add Japanese translation for http-in node (#2758) (@kazuhitoyokoi)
|
||||
|
||||
Nodes
|
||||
|
||||
- CSV: Fix CSV node repeating array output
|
||||
|
||||
### 1.2.3: Maintenance Release
|
||||
|
||||
Editor
|
||||
|
@ -24,6 +24,7 @@ module.exports = function(grunt) {
|
||||
var flowFile = grunt.option('flowFile');
|
||||
if (flowFile) {
|
||||
nodemonArgs.push(flowFile);
|
||||
process.env.NODE_RED_ENABLE_PROJECTS=false;
|
||||
}
|
||||
var userDir = grunt.option('userDir');
|
||||
if (userDir) {
|
||||
|
@ -55,8 +55,8 @@
|
||||
"media-typer": "1.1.0",
|
||||
"memorystore": "1.6.4",
|
||||
"mime": "2.4.6",
|
||||
"moment-timezone": "^0.5.31",
|
||||
"mqtt": "4.2.4",
|
||||
"moment-timezone": "0.5.32",
|
||||
"mqtt": "4.2.5",
|
||||
"multer": "1.4.2",
|
||||
"mustache": "4.0.1",
|
||||
"node-red-admin": "^0.2.6",
|
||||
@ -73,7 +73,7 @@
|
||||
"request": "2.88.0",
|
||||
"semver": "6.3.0",
|
||||
"tar": "6.0.5",
|
||||
"uglify-js": "3.11.4",
|
||||
"uglify-js": "3.11.6",
|
||||
"when": "3.7.8",
|
||||
"ws": "6.2.1",
|
||||
"xml2js": "0.4.23"
|
||||
@ -104,7 +104,7 @@
|
||||
"grunt-simple-nyc": "^3.0.1",
|
||||
"http-proxy": "1.18.1",
|
||||
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
||||
"marked": "1.2.2",
|
||||
"marked": "1.2.4",
|
||||
"minami": "1.2.3",
|
||||
"mocha": "^5.2.0",
|
||||
"node-red-node-test-helper": "^0.2.5",
|
||||
|
@ -33,8 +33,6 @@ var activeConnections = [];
|
||||
|
||||
var anonymousUser;
|
||||
|
||||
var retained = {};
|
||||
|
||||
var heartbeatTimer;
|
||||
var lastSentTime;
|
||||
|
||||
|
@ -42,7 +42,8 @@
|
||||
"loadNodeCatalogs": "Загрузка каталогов узлов",
|
||||
"loadNodes": "Загрузка узлов __count__",
|
||||
"loadFlows": "Загрузка потоков",
|
||||
"importFlows": "Добавление потоков в рабочую область"
|
||||
"importFlows": "Добавление потоков в рабочую область",
|
||||
"importError": "<p>Ошибка добавления потоков</p><p>__message__</p>"
|
||||
},
|
||||
"workspace": {
|
||||
"defaultName": "Поток __number__",
|
||||
@ -214,6 +215,9 @@
|
||||
"importUnrecognised": "Импортирован неопознанный тип:",
|
||||
"importUnrecognised_plural_2": "Импортированы неопознанные типы:",
|
||||
"importUnrecognised_plural_5": "Импортированы неопознанные типы:",
|
||||
"importDuplicate": "Импортирован дубликат узла:",
|
||||
"importDuplicate_plural_2": "Импортированы дубликаты узлов:",
|
||||
"importDuplicate_plural_5": "Импортированы дубликаты узлов:",
|
||||
"nodesExported": "Узлы экспортированы в буфер обмена",
|
||||
"nodesImported": "Импортированы:",
|
||||
"nodeCopied": "__count__ узел скопирован",
|
||||
|
@ -1359,6 +1359,10 @@ RED.nodes = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (n.z && !workspaces[n.z]) {
|
||||
n.z = activeWorkspace;
|
||||
}
|
||||
}
|
||||
|
||||
if (!existingConfigNode || existingConfigNode._def.exclusive) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode.z !== n.z) {
|
||||
|
@ -773,6 +773,9 @@ RED.clipboard = (function() {
|
||||
// representation or null
|
||||
return null;
|
||||
}
|
||||
if (value.type === 'bigint') {
|
||||
return value.data.toString();
|
||||
}
|
||||
if (value.type === 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -173,6 +173,7 @@
|
||||
valueLabel: function(container,value) {
|
||||
var that = this;
|
||||
container.css("pointer-events","none");
|
||||
container.css("flex-grow",0);
|
||||
this.elementDiv.hide();
|
||||
var buttons = $('<div>').css({
|
||||
position: "absolute",
|
||||
@ -184,22 +185,25 @@
|
||||
width:"20px"
|
||||
}).appendTo(buttons).on("click", function(evt) {
|
||||
evt.preventDefault();
|
||||
var cursorPosition = that.input[0].selectionStart;
|
||||
var currentType = that.input.attr("type");
|
||||
if (currentType === "text") {
|
||||
that.input.attr("type","password");
|
||||
eyeCon.removeClass("fa-eye-slash").addClass("fa-eye");
|
||||
setTimeout(function() {
|
||||
that.input.focus();
|
||||
that.input[0].setSelectionRange(cursorPosition, cursorPosition);
|
||||
},50);
|
||||
} else {
|
||||
that.input.attr("type","text");
|
||||
eyeCon.removeClass("fa-eye").addClass("fa-eye-slash");
|
||||
setTimeout(function() {
|
||||
that.input.focus();
|
||||
that.input[0].setSelectionRange(cursorPosition, cursorPosition);
|
||||
},50);
|
||||
}
|
||||
}).hide();
|
||||
var eyeCon = $('<i class="fa fa-eye"></i>').css("margin-left","-1px").appendTo(eyeButton);
|
||||
var eyeCon = $('<i class="fa fa-eye"></i>').css("margin-left","-2px").appendTo(eyeButton);
|
||||
|
||||
if (value === "__PWRD__") {
|
||||
var innerContainer = $('<div><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i></div>').css({
|
||||
@ -284,7 +288,7 @@
|
||||
this.input.css('width','100%');
|
||||
this.uiSelect.width(m[1]);
|
||||
this.uiWidth = null;
|
||||
} else {
|
||||
} else if (this.uiWidth !== 0){
|
||||
this.uiSelect.width(this.uiWidth);
|
||||
}
|
||||
["Right","Left"].forEach(function(d) {
|
||||
@ -304,7 +308,11 @@
|
||||
|
||||
this.element.attr('type','hidden');
|
||||
|
||||
if (!this.options.types && this.options.type) {
|
||||
this.options.types = [this.options.type]
|
||||
} else {
|
||||
this.options.types = this.options.types||Object.keys(allOptions);
|
||||
}
|
||||
|
||||
this.selectTrigger = $('<button class="red-ui-typedInput-type-select" tabindex="0"></button>').prependTo(this.uiSelect);
|
||||
$('<i class="red-ui-typedInput-icon fa fa-caret-down"></i>').toggle(this.options.types.length > 1).appendTo(this.selectTrigger);
|
||||
@ -872,6 +880,9 @@
|
||||
this.elementDiv.hide();
|
||||
this.valueLabelContainer.hide();
|
||||
} else if (opt.valueLabel) {
|
||||
// Reset any CSS the custom label may have set
|
||||
this.valueLabelContainer.css("pointer-events","");
|
||||
this.valueLabelContainer.css("flex-grow",1);
|
||||
this.valueLabelContainer.show();
|
||||
this.valueLabelContainer.empty();
|
||||
this.elementDiv.hide();
|
||||
|
@ -1033,7 +1033,7 @@ RED.projects.settings = (function() {
|
||||
|
||||
var credentialSecretExistingRow = $('<div class="red-ui-settings-row red-ui-settings-row-credentials"></div>').appendTo(credentialFormRows);
|
||||
$('<label for=""></label>').text(RED._("sidebar.project.projectSettings.currentKey")).appendTo(credentialSecretExistingRow);
|
||||
var credentialSecretExistingInput = $('<input type="password">').appendTo(credentialSecretExistingRow)
|
||||
var credentialSecretExistingInput = $('<input type="text">').appendTo(credentialSecretExistingRow).typedInput({type:"cred"})
|
||||
.on("change keyup paste",function() {
|
||||
if (popover) {
|
||||
popover.close();
|
||||
@ -1046,7 +1046,7 @@ RED.projects.settings = (function() {
|
||||
|
||||
|
||||
$('<label for=""></label>').text(RED._("sidebar.project.projectSettings.newKey")).appendTo(credentialSecretNewRow);
|
||||
var credentialSecretNewInput = $('<input type="password">').appendTo(credentialSecretNewRow).on("change keyup paste",checkFiles);
|
||||
var credentialSecretNewInput = $('<input type="text">').appendTo(credentialSecretNewRow).typedInput({type:"cred"}).on("change keyup paste",checkFiles);
|
||||
|
||||
var credentialResetWarning = $('<div class="form-tips form-warning" style="margin: 10px;"><i class="fa fa-warning"></i>' + RED._("sidebar.project.projectSettings.credentialsAlert") + '</div>').hide().appendTo(credentialFormRows);
|
||||
|
||||
|
@ -81,8 +81,8 @@ RED.projects = (function() {
|
||||
$('<p>').text(RED._("projects.welcome.desc2")).appendTo(body);
|
||||
|
||||
var row = $('<div style="text-align: center"></div>').appendTo(body);
|
||||
var createAsEmpty = $('<button data-type="empty" class="red-ui-button red-ui-projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.welcome.create")+'</button>').appendTo(row);
|
||||
var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.welcome.clone")+'</button>').appendTo(row);
|
||||
var createAsEmpty = $('<button data-type="empty" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.welcome.create")+'</button>').appendTo(row);
|
||||
var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.welcome.clone")+'</button>').appendTo(row);
|
||||
|
||||
createAsEmpty.on("click", function(e) {
|
||||
e.preventDefault();
|
||||
@ -511,7 +511,8 @@ RED.projects = (function() {
|
||||
|
||||
subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
|
||||
$('<label for="red-ui-projects-dialog-screen-create-project-repo-pass">'+RED._("projects.clone-project.passwd")+'</label>').appendTo(subrow);
|
||||
projectRepoPasswordInput = $('<input id="red-ui-projects-dialog-screen-create-project-repo-pass" type="password"></input>').appendTo(subrow);
|
||||
projectRepoPasswordInput = $('<input style="width:100%" id="red-ui-projects-dialog-screen-create-project-repo-pass" type="password"></input>').appendTo(subrow);
|
||||
projectRepoPasswordInput.typedInput({type:"cred"});
|
||||
// -----------------------------------------------------
|
||||
|
||||
// Repo credentials - key/passphrase -------------------
|
||||
@ -539,12 +540,12 @@ RED.projects = (function() {
|
||||
subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
|
||||
$('<label for="red-ui-projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.clone-project.passphrase")+'</label>').appendTo(subrow);
|
||||
projectRepoPassphrase = $('<input id="red-ui-projects-dialog-screen-create-project-repo-passphrase" type="password"></input>').appendTo(subrow);
|
||||
|
||||
projectRepoPassphrase.typedInput({type:"cred"});
|
||||
subrow = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-sshkey"></div>').appendTo(cloneAuthRows);
|
||||
var sshwarningRow = $('<div class="red-ui-projects-dialog-screen-create-row-auth-error-no-keys"></div>').hide().appendTo(subrow);
|
||||
$('<div class="form-row"><i class="fa fa-warning"></i> '+RED._("projects.clone-project.ssh-key-desc")+'</div>').appendTo(sshwarningRow);
|
||||
subrow = $('<div style="text-align: center">').appendTo(sshwarningRow);
|
||||
$('<button class="red-ui-button">'+RED._("projects.clone-project.ssh-key-add")+'</button>').appendTo(subrow).on("click", function(e) {
|
||||
$('<button class="red-ui-button red-ui-projects-dialog-button">'+RED._("projects.clone-project.ssh-key-add")+'</button>').appendTo(subrow).on("click", function(e) {
|
||||
e.preventDefault();
|
||||
dialog.dialog( "close" );
|
||||
RED.userSettings.show('gitconfig');
|
||||
@ -558,8 +559,8 @@ RED.projects = (function() {
|
||||
// Secret - clone
|
||||
row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-clone"></div>').appendTo(body);
|
||||
$('<label>'+RED._("projects.clone-project.credential-key")+'</label>').appendTo(row);
|
||||
projectSecretInput = $('<input type="password"></input>').appendTo(row);
|
||||
|
||||
projectSecretInput = $('<input style="width: 100%" type="password"></input>').appendTo(row);
|
||||
projectSecretInput.typedInput({type:"cred"});
|
||||
|
||||
|
||||
return container;
|
||||
@ -894,6 +895,7 @@ RED.projects = (function() {
|
||||
$('<label class="red-ui-projects-edit-form-inline-label" style="margin-left: 5px"><input type="radio" style="vertical-align: middle; margin-top:0; margin-right: 10px;" value="custom" name="projects-encryption-key"> <span style="vertical-align: middle;">'+RED._("projects.encryption-config.use-custom")+'</span></label>').appendTo(row);
|
||||
row = $('<div class="projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox);
|
||||
emptyProjectCredentialInput = $('<input disabled type="password" style="margin-left: 25px; width: calc(100% - 30px);"></input>').appendTo(row);
|
||||
emptyProjectCredentialInput.typedInput({type:"cred"});
|
||||
emptyProjectCredentialInput.on("change keyup paste", validateForm);
|
||||
|
||||
row = $('<div class="form-row projects-encryption-disabled-row"></div>').hide().appendTo(credentialsRightBox);
|
||||
@ -1169,11 +1171,11 @@ RED.projects = (function() {
|
||||
|
||||
row = $('<div class="form-row button-group"></div>').appendTo(container);
|
||||
|
||||
var openProject = $('<button data-type="open" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-folder-open"></i><br/>'+RED._("projects.create.open")+'</button>').appendTo(row);
|
||||
var createAsEmpty = $('<button data-type="empty" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.create.create")+'</button>').appendTo(row);
|
||||
// var createAsCopy = $('<button data-type="copy" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i class="fa fa-long-arrow-right fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Copy existing</button>').appendTo(row);
|
||||
var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.create.clone")+'</button>').appendTo(row);
|
||||
// var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-git fa-2x"></i><i class="fa fa-arrows-h fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Clone Repository</button>').appendTo(row);
|
||||
var openProject = $('<button data-type="open" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-folder-open"></i><br/>'+RED._("projects.create.open")+'</button>').appendTo(row);
|
||||
var createAsEmpty = $('<button data-type="empty" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.create.create")+'</button>').appendTo(row);
|
||||
// var createAsCopy = $('<button data-type="copy" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i class="fa fa-long-arrow-right fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Copy existing</button>').appendTo(row);
|
||||
var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.create.clone")+'</button>').appendTo(row);
|
||||
// var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-git fa-2x"></i><i class="fa fa-arrows-h fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Clone Repository</button>').appendTo(row);
|
||||
row.find(".red-ui-projects-dialog-screen-create-type").on("click", function(evt) {
|
||||
evt.preventDefault();
|
||||
container.find(".red-ui-projects-dialog-screen-create-type").removeClass('selected');
|
||||
@ -1298,6 +1300,7 @@ RED.projects = (function() {
|
||||
$('<label class="red-ui-projects-edit-form-inline-label">'+RED._("projects.create.encryption-key")+'</label>').appendTo(row);
|
||||
// row = $('<div class="projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox);
|
||||
emptyProjectCredentialInput = $('<input type="password"></input>').appendTo(row);
|
||||
emptyProjectCredentialInput.typedInput({type:"cred"});
|
||||
emptyProjectCredentialInput.on("change keyup paste", validateForm);
|
||||
$('<label class="red-ui-projects-edit-form-sublabel"><small>'+RED._("projects.create.desc0")+'</small></label>').appendTo(row);
|
||||
|
||||
@ -1356,7 +1359,8 @@ RED.projects = (function() {
|
||||
|
||||
subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
|
||||
$('<label for="red-ui-projects-dialog-screen-create-project-repo-pass">'+RED._("projects.create.password")+'</label>').appendTo(subrow);
|
||||
projectRepoPasswordInput = $('<input id="red-ui-projects-dialog-screen-create-project-repo-pass" type="password"></input>').appendTo(subrow);
|
||||
projectRepoPasswordInput = $('<input style="width:100%" id="red-ui-projects-dialog-screen-create-project-repo-pass" type="password"></input>').appendTo(subrow);
|
||||
projectRepoPasswordInput.typedInput({type:"cred"});
|
||||
// -----------------------------------------------------
|
||||
|
||||
// Repo credentials - key/passphrase -------------------
|
||||
@ -1384,12 +1388,13 @@ RED.projects = (function() {
|
||||
subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
|
||||
$('<label for="red-ui-projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.create.passphrase")+'</label>').appendTo(subrow);
|
||||
projectRepoPassphrase = $('<input id="red-ui-projects-dialog-screen-create-project-repo-passphrase" type="password"></input>').appendTo(subrow);
|
||||
projectRepoPassphrase.typedInput({type:"cred"});
|
||||
|
||||
subrow = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-sshkey"></div>').appendTo(cloneAuthRows);
|
||||
var sshwarningRow = $('<div class="red-ui-projects-dialog-screen-create-row-auth-error-no-keys"></div>').hide().appendTo(subrow);
|
||||
$('<div class="form-row"><i class="fa fa-warning"></i> '+RED._("projects.create.desc2")+'</div>').appendTo(sshwarningRow);
|
||||
subrow = $('<div style="text-align: center">').appendTo(sshwarningRow);
|
||||
$('<button class="red-ui-button">'+RED._("projects.create.add-ssh-key")+'</button>').appendTo(subrow).on("click", function(e) {
|
||||
$('<button class="red-ui-button red-ui-projects-dialog-button">'+RED._("projects.create.add-ssh-key")+'</button>').appendTo(subrow).on("click", function(e) {
|
||||
e.preventDefault();
|
||||
$('#red-ui-projects-dialog-cancel').trigger("click");
|
||||
RED.userSettings.show('gitconfig');
|
||||
@ -1403,8 +1408,8 @@ RED.projects = (function() {
|
||||
// Secret - clone
|
||||
row = $('<div class="hide form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-clone"></div>').appendTo(container);
|
||||
$('<label>'+RED._("projects.create.credentials-encryption-key")+'</label>').appendTo(row);
|
||||
projectSecretInput = $('<input type="password"></input>').appendTo(row);
|
||||
|
||||
projectSecretInput = $('<input style="width:100%" type="password"></input>').appendTo(row);
|
||||
projectSecretInput.typedInput({type:"cred"});
|
||||
|
||||
switch(options.screen||"empty") {
|
||||
case "empty": createAsEmpty.trigger("click"); break;
|
||||
@ -1617,14 +1622,14 @@ RED.projects = (function() {
|
||||
function deleteProject(row,name,done) {
|
||||
var cover = $('<div class="red-ui-projects-dialog-project-list-entry-delete-confirm"></div>').on("click", function(evt) { evt.stopPropagation(); }).appendTo(row);
|
||||
$('<span>').text(RED._("projects.delete.confirm")).appendTo(cover);
|
||||
$('<button class="red-ui-button">'+RED._("common.label.cancel")+'</button>')
|
||||
$('<button class="red-ui-button red-ui-projects-dialog-button">'+RED._("common.label.cancel")+'</button>')
|
||||
.appendTo(cover)
|
||||
.on("click", function(e) {
|
||||
e.stopPropagation();
|
||||
cover.remove();
|
||||
done(true);
|
||||
});
|
||||
$('<button class="red-ui-button primary">'+RED._("common.label.delete")+'</button>')
|
||||
$('<button class="red-ui-button red-ui-projects-dialog-button primary">'+RED._("common.label.delete")+'</button>')
|
||||
.appendTo(cover)
|
||||
.on("click", function(e) {
|
||||
e.stopPropagation();
|
||||
@ -1808,7 +1813,7 @@ RED.projects = (function() {
|
||||
header.addClass("selectable");
|
||||
|
||||
var tools = $('<div class="red-ui-projects-dialog-project-list-entry-tools"></div>').appendTo(header);
|
||||
$('<button class="red-ui-button red-ui-button-small" style="float: right;"><i class="fa fa-trash"></i></button>')
|
||||
$('<button class="red-ui-button red-ui-projects-dialog-button red-ui-button-small" style="float: right;"><i class="fa fa-trash"></i></button>')
|
||||
.appendTo(tools)
|
||||
.on("click", function(e) {
|
||||
e.stopPropagation();
|
||||
@ -1962,7 +1967,8 @@ RED.projects = (function() {
|
||||
var isSSH = false;
|
||||
if (/^https?:\/\//.test(url)) {
|
||||
$('<div class="form-row"><label for="projects-user-auth-username">'+RED._("projects.send-req.username")+'</label><input id="projects-user-auth-username" type="text"></input></div>'+
|
||||
'<div class="form-row"><label for=projects-user-auth-password">'+RED._("projects.send-req.password")+'</label><input id="projects-user-auth-password" type="password"></input></div>').appendTo(message);
|
||||
'<div class="form-row"><label for="projects-user-auth-password">'+RED._("projects.send-req.password")+'</label><input id="projects-user-auth-password" type="password"></input></div>').appendTo(message);
|
||||
message.find("#projects-user-auth-password").typedInput({type:"cred"})
|
||||
} else if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(url)) {
|
||||
isSSH = true;
|
||||
var row = $('<div class="form-row"></div>').appendTo(message);
|
||||
@ -1980,7 +1986,7 @@ RED.projects = (function() {
|
||||
});
|
||||
row = $('<div class="form-row"></div>').appendTo(message);
|
||||
$('<label for="projects-user-auth-passphrase">'+RED._("projects.send-req.passphrase")+'</label>').appendTo(row);
|
||||
$('<input id="projects-user-auth-passphrase" type="password"></input>').appendTo(row);
|
||||
$('<input id="projects-user-auth-passphrase" type="password"></input>').appendTo(row).typedInput({type:"cred"});
|
||||
}
|
||||
|
||||
var notification = RED.notify(message,{
|
||||
|
@ -60,7 +60,7 @@ RED.utils = (function() {
|
||||
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('array['+value.length+']');
|
||||
} else if (value.hasOwnProperty('type') && value.type === 'function') {
|
||||
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('function');
|
||||
} else if (value.hasOwnProperty('type') && value.type === 'number') {
|
||||
} else if (value.hasOwnProperty('type') && (value.type === 'number' || value.type === 'bigint')) {
|
||||
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-number"></span>').text(value.data);
|
||||
} else {
|
||||
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta">object</span>');
|
||||
@ -352,7 +352,7 @@ RED.utils = (function() {
|
||||
$('<span class="red-ui-debug-msg-type-null">'+obj+'</span>').appendTo(entryObj);
|
||||
} else if (obj.__enc__ && obj.type === 'undefined') {
|
||||
$('<span class="red-ui-debug-msg-type-null">undefined</span>').appendTo(entryObj);
|
||||
} else if (obj.__enc__ && obj.type === 'number') {
|
||||
} else if (obj.__enc__ && (obj.type === 'number' || obj.type === 'bigint')) {
|
||||
e = $('<span class="red-ui-debug-msg-type-number red-ui-debug-msg-object-header"></span>').text(obj.data).appendTo(entryObj);
|
||||
} else if (typeHint === "function" || (obj.__enc__ && obj.type === 'function')) {
|
||||
e = $('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-header"></span>').text("function").appendTo(entryObj);
|
||||
|
@ -90,7 +90,7 @@
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
button.red-ui-button {
|
||||
button.red-ui-button.red-ui-projects-dialog-button {
|
||||
width: calc(50% - 80px);
|
||||
margin: 20px;
|
||||
height: auto;
|
||||
|
@ -18,6 +18,7 @@
|
||||
border: 1px solid $form-input-border-color;
|
||||
border-radius: 4px;
|
||||
height: 34px;
|
||||
line-height: 14px;
|
||||
display: inline-flex;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
@ -21,8 +21,11 @@ module.exports = function(RED) {
|
||||
this.tosidebar = n.tosidebar;
|
||||
if (this.tosidebar === undefined) { this.tosidebar = true; }
|
||||
this.active = (n.active === null || typeof n.active === "undefined") || n.active;
|
||||
if (this.tostatus) { this.status({fill:"grey", shape:"ring"}); }
|
||||
else { this.status({}); }
|
||||
if (this.tostatus) {
|
||||
this.status({fill:"grey", shape:"ring"});
|
||||
this.oldState = "{}";
|
||||
}
|
||||
|
||||
var hasStatExpression = (n.statusType === "jsonata");
|
||||
var statExpression = hasStatExpression ? n.statusVal : null;
|
||||
|
||||
@ -97,7 +100,11 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.on("close", function() {
|
||||
if (this.oldState) {
|
||||
this.status({});
|
||||
}
|
||||
})
|
||||
this.on("input", function(msg, send, done) {
|
||||
if (msg.hasOwnProperty("status") && msg.status.hasOwnProperty("source") && msg.status.source.hasOwnProperty("id") && (msg.status.source.id === node.id)) {
|
||||
done();
|
||||
@ -202,13 +209,8 @@ module.exports = function(RED) {
|
||||
function setNodeState(node,state) {
|
||||
if (state) {
|
||||
node.active = true;
|
||||
if (node.tostatus) { node.status({fill:"grey", shape:"dot"}); }
|
||||
} else {
|
||||
node.active = false;
|
||||
if (node.tostatus && node.hasOwnProperty("oldStatus")) {
|
||||
node.oldStatus.shape = "dot";
|
||||
node.status(node.oldStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,8 @@ module.exports = function(RED) {
|
||||
node.topic = n.topic;
|
||||
node.outstandingTimers = [];
|
||||
node.outstandingIntervals = [];
|
||||
node.clearStatus = false;
|
||||
|
||||
var sandbox = {
|
||||
console:console,
|
||||
util:util,
|
||||
@ -163,6 +165,7 @@ module.exports = function(RED) {
|
||||
node.on.apply(node, arguments);
|
||||
},
|
||||
status: function() {
|
||||
node.clearStatus = true;
|
||||
node.status.apply(node, arguments);
|
||||
}
|
||||
},
|
||||
@ -389,7 +392,9 @@ module.exports = function(RED) {
|
||||
while (node.outstandingIntervals.length > 0) {
|
||||
clearInterval(node.outstandingIntervals.pop());
|
||||
}
|
||||
if (node.clearStatus) {
|
||||
node.status({});
|
||||
}
|
||||
});
|
||||
|
||||
promise.then(function (v) {
|
||||
|
@ -46,7 +46,7 @@
|
||||
При преобразовании в CSV шаблон столбцов используется для определения того, какие свойства извлекать из объекта и в каком порядке.
|
||||
</p>
|
||||
<p>
|
||||
Если шаблон пуст, то узел может использовать простой список свойств, разделенных запятыми, предоставленных в <code>msg.columns</code>, чтобы определить, что извлечь. Если этого нет, то все свойства объекта выводятся в том порядке, в котором они были найдены.
|
||||
Если шаблон пуст, то узел может использовать простой список свойств, разделенных запятыми, предоставленных в <code>msg.columns</code>, чтобы определить, что извлечь. Если этого нет, то все свойства объекта выводятся в том порядке, в котором они были найдены в первой строке.
|
||||
</p>
|
||||
<p>
|
||||
Если входные данные являются массивом, то шаблон столбцов используется только для необязательного генерирования строки с заголовками столбцов.
|
||||
|
@ -31,7 +31,7 @@
|
||||
"is-utf8": "0.2.1",
|
||||
"js-yaml": "3.14.0",
|
||||
"media-typer": "1.1.0",
|
||||
"mqtt": "4.2.4",
|
||||
"mqtt": "4.2.5",
|
||||
"multer": "1.4.2",
|
||||
"mustache": "4.0.1",
|
||||
"on-headers": "1.0.2",
|
||||
|
@ -19,7 +19,7 @@
|
||||
"@node-red/util": "1.3.0-beta.1",
|
||||
"semver": "6.3.0",
|
||||
"tar": "6.0.5",
|
||||
"uglify-js": "3.11.4",
|
||||
"uglify-js": "3.11.6",
|
||||
"when": "3.7.8"
|
||||
}
|
||||
}
|
||||
|
@ -38,12 +38,20 @@ function handleCommsEvent(event) {
|
||||
publish(event.topic,event.data,event.retain);
|
||||
}
|
||||
function handleStatusEvent(event) {
|
||||
if (!event.status) {
|
||||
delete retained["status/"+event.id]
|
||||
} else if (!event.status.text && !event.status.fill && !event.status.shape) {
|
||||
if (retained["status/"+event.id]) {
|
||||
publish("status/"+event.id,{},false);
|
||||
}
|
||||
} else {
|
||||
var status = {
|
||||
text: event.status.text,
|
||||
fill: event.status.fill,
|
||||
shape: event.status.shape
|
||||
};
|
||||
publish("status/"+event.id,status,true);
|
||||
}
|
||||
}
|
||||
function handleRuntimeEvent(event) {
|
||||
runtime.log.trace("runtime event: "+JSON.stringify(event));
|
||||
|
@ -319,6 +319,11 @@ class Flow {
|
||||
node.error(err);
|
||||
}
|
||||
}
|
||||
if (removedMap[stopList[i]]) {
|
||||
events.emit("node-status",{
|
||||
id: node.id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return Promise.all(promises);
|
||||
|
@ -18,6 +18,7 @@ const clone = require("clone");
|
||||
const Flow = require('./Flow').Flow;
|
||||
const context = require('../nodes/context');
|
||||
const util = require("util");
|
||||
const events = require("../events");
|
||||
|
||||
const redUtil = require("@node-red/util").util;
|
||||
const flowUtil = require("./util");
|
||||
@ -308,7 +309,26 @@ class Subflow extends Flow {
|
||||
super.start(diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop this subflow.
|
||||
* The `stopList` argument helps define what needs to be stopped in the case
|
||||
* of a modified-nodes/flows type deploy.
|
||||
* @param {[type]} stopList [description]
|
||||
* @param {[type]} removedList [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
stop(stopList, removedList) {
|
||||
const nodes = Object.keys(this.activeNodes);
|
||||
return super.stop(stopList, removedList).then(res => {
|
||||
nodes.forEach(id => {
|
||||
events.emit("node-status",{
|
||||
id: id
|
||||
});
|
||||
})
|
||||
return res;
|
||||
})
|
||||
|
||||
}
|
||||
/**
|
||||
* Get environment variable of subflow
|
||||
* @param {String} name name of env var
|
||||
|
13
packages/node_modules/@node-red/util/lib/util.js
vendored
13
packages/node_modules/@node-red/util/lib/util.js
vendored
@ -774,6 +774,12 @@ function encodeObject(msg,opts) {
|
||||
data: value.toString()
|
||||
}
|
||||
}
|
||||
} else if (typeof value === 'bigint') {
|
||||
value = {
|
||||
__enc__: true,
|
||||
type: 'bigint',
|
||||
data: value.toString()
|
||||
}
|
||||
} else if (value && value.constructor) {
|
||||
if (value.type === "Buffer") {
|
||||
value.__enc__ = true;
|
||||
@ -808,6 +814,13 @@ function encodeObject(msg,opts) {
|
||||
} else if (msgType === "number") {
|
||||
msg.format = "number";
|
||||
msg.msg = msg.msg.toString();
|
||||
} else if (msgType === "bigint") {
|
||||
msg.format = "bigint";
|
||||
msg.msg = {
|
||||
__enc__: true,
|
||||
type: 'bigint',
|
||||
data: msg.msg.toString()
|
||||
};
|
||||
} else if (msg.msg === null || msgType === "undefined") {
|
||||
msg.format = (msg.msg === null)?"null":"undefined";
|
||||
msg.msg = "(undefined)";
|
||||
|
@ -20,7 +20,7 @@
|
||||
"json-stringify-safe": "5.0.1",
|
||||
"jsonata": "1.8.4",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"moment-timezone": "^0.5.31",
|
||||
"moment-timezone": "0.5.32",
|
||||
"when": "3.7.8"
|
||||
}
|
||||
}
|
||||
|
@ -211,6 +211,82 @@ describe("runtime-api/comms", function() {
|
||||
});
|
||||
}).catch(done);
|
||||
})
|
||||
it('retains non-blank status message',function(done){
|
||||
eventHandlers['node-status']({
|
||||
id: "node1234",
|
||||
status: {text:"hello"}
|
||||
})
|
||||
messages.should.have.length(0);
|
||||
comms.addConnection({client: clientConnection}).then(function() {
|
||||
return comms.subscribe({client: clientConnection, topic: "status/#"}).then(function() {
|
||||
messages.should.have.length(1);
|
||||
messages[0].should.have.property("topic","status/node1234");
|
||||
messages[0].should.have.property("data",{text:"hello", fill: undefined, shape: undefined});
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
})
|
||||
it('does not retain blank status message',function(done){
|
||||
eventHandlers['node-status']({
|
||||
id: "node1234",
|
||||
status: {}
|
||||
})
|
||||
messages.should.have.length(0);
|
||||
comms.addConnection({client: clientConnection}).then(function() {
|
||||
return comms.subscribe({client: clientConnection, topic: "status/#"}).then(function() {
|
||||
messages.should.have.length(0);
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
})
|
||||
it('does not send blank status if first status',function(done){
|
||||
messages.should.have.length(0);
|
||||
comms.addConnection({client: clientConnection}).then(function() {
|
||||
return comms.subscribe({client: clientConnection, topic: "status/#"}).then(function() {
|
||||
eventHandlers['node-status']({
|
||||
id: "node5678",
|
||||
status: {}
|
||||
})
|
||||
messages.should.have.length(0);
|
||||
done()
|
||||
})
|
||||
}).catch(done);
|
||||
});
|
||||
it('sends blank status if replacing retained',function(done){
|
||||
eventHandlers['node-status']({
|
||||
id: "node5678",
|
||||
status: {text:"hello"}
|
||||
})
|
||||
messages.should.have.length(0);
|
||||
comms.addConnection({client: clientConnection}).then(function() {
|
||||
return comms.subscribe({client: clientConnection, topic: "status/#"}).then(function() {
|
||||
messages.should.have.length(1);
|
||||
eventHandlers['node-status']({
|
||||
id: "node5678",
|
||||
status: {}
|
||||
})
|
||||
messages.should.have.length(2);
|
||||
done()
|
||||
})
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('does not retain initial status blank message',function(done){
|
||||
eventHandlers['node-status']({
|
||||
id: "my-event",
|
||||
status: {}
|
||||
})
|
||||
messages.should.have.length(0);
|
||||
comms.addConnection({client: clientConnection}).then(function() {
|
||||
return comms.subscribe({client: clientConnection, topic: "my-event"}).then(function() {
|
||||
messages.should.have.length(1);
|
||||
messages[0].should.have.property("topic","my-event");
|
||||
messages[0].should.have.property("data","my-payload");
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
})
|
||||
|
||||
it('retained messages get cleared',function(done) {
|
||||
eventHandlers['comms']({
|
||||
topic: "my-event",
|
||||
|
Loading…
Reference in New Issue
Block a user