mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
146 Commits
2.1.0-beta
...
Json-try-p
Author | SHA1 | Date | |
---|---|---|---|
|
6ae42eb787 | ||
|
7cd3e49f04 | ||
|
173e75175e | ||
|
800006dd76 | ||
|
a824b6910a | ||
|
dcea382b38 | ||
|
d9f976baea | ||
|
1fa13efe19 | ||
|
33af5cd7c6 | ||
|
7cb8f97ef1 | ||
|
bf965a9cde | ||
|
17ffff685a | ||
|
ae76271cff | ||
|
8f3a96d615 | ||
|
30e750dfe5 | ||
|
682dff7c6f | ||
|
85415eb8a8 | ||
|
68a80b9244 | ||
|
c331da7323 | ||
|
04ffa06221 | ||
|
1f0690c6ec | ||
|
711467abcd | ||
|
9439cd0e3d | ||
|
314c19650d | ||
|
ed6afcd802 | ||
|
082d4fe8e1 | ||
|
cd23b44506 | ||
|
46b6b024b9 | ||
|
cb88cc35e5 | ||
|
75c0c44809 | ||
|
a091b82ba9 | ||
|
a3b8f022e6 | ||
|
279fcb7c51 | ||
|
49a9376073 | ||
|
96840ede56 | ||
|
7e7f481f99 | ||
|
3edbf52bc6 | ||
|
fba6e801fc | ||
|
720a163273 | ||
|
6ac0c0a367 | ||
|
300402d253 | ||
|
0d9bfae503 | ||
|
bfe0d3b8a3 | ||
|
5fdd9c0546 | ||
|
b6570a16b8 | ||
|
8e2d3ea16f | ||
|
bc2c81f058 | ||
|
3e0f080ea7 | ||
|
679e07189d | ||
|
a38ebef100 | ||
|
b8ad6475e1 | ||
|
0f0cb3ac6d | ||
|
d3efb9d7cc | ||
|
84a237d3f5 | ||
|
e6de52eede | ||
|
98aee964d7 | ||
|
570e5442e0 | ||
|
b77a2dc353 | ||
|
87af31de20 | ||
|
cfe201dbe1 | ||
|
6ccdab35e0 | ||
|
55b9f36b45 | ||
|
fbcb1130c9 | ||
|
d4f7a6d2bc | ||
|
8a19f71abe | ||
|
fb153757b5 | ||
|
4f175fc93e | ||
|
2d4ca7cec0 | ||
|
bf0ea89969 | ||
|
073f0c2a20 | ||
|
ba83be9062 | ||
|
2e7188ea4f | ||
|
5a012182d9 | ||
|
b855438af6 | ||
|
2ffea143e7 | ||
|
61d85b49e6 | ||
|
35f617e96c | ||
|
6b6ad47c35 | ||
|
e57183ed0e | ||
|
ecfd61a822 | ||
|
153f87704b | ||
|
836f7d2163 | ||
|
d4d6f71cf4 | ||
|
42a9da006e | ||
|
2bd5c4f527 | ||
|
6a49b5c106 | ||
|
23e14d1b72 | ||
|
f4f11c8884 | ||
|
2b220abdb7 | ||
|
c1d947ebe3 | ||
|
d695cf392e | ||
|
21304a695c | ||
|
fa51b06c46 | ||
|
7560bb8d7b | ||
|
fc9d65abcc | ||
|
a7413cccd0 | ||
|
7610353f07 | ||
|
d3f978c90c | ||
|
b55a8ef62a | ||
|
8d79deffb5 | ||
|
8158487c3e | ||
|
0cc061196d | ||
|
d0ec055222 | ||
|
ae12ddd32b | ||
|
31da3adaa9 | ||
|
9fd5213f13 | ||
|
de882f5849 | ||
|
fded1e0021 | ||
|
6cb06c146d | ||
|
b8f1386ad0 | ||
|
2b38b5ea50 | ||
|
2f707a6b16 | ||
|
d4c2fcd559 | ||
|
082970cdb7 | ||
|
fe97c78977 | ||
|
79394aa69f | ||
|
21fd6e3c21 | ||
|
de4944cd83 | ||
|
3fde5c27ed | ||
|
e1d492813e | ||
|
48d0ee3b6d | ||
|
eebb64901c | ||
|
60e0ed2af6 | ||
|
f030694ef4 | ||
|
e9ed13459a | ||
|
af1e38fdf7 | ||
|
b12900e680 | ||
|
44aa1f4a5e | ||
|
9425548a85 | ||
|
bfd4fc81fe | ||
|
439af2a325 | ||
|
3204b04455 | ||
|
bed1be14ba | ||
|
7cd92faf0d | ||
|
be7e28af5d | ||
|
8eaa762ec5 | ||
|
953a9f7cd4 | ||
|
36f099d68b | ||
|
c8fd5090bd | ||
|
155e1be494 | ||
|
cf5e125cb3 | ||
|
764fc8477d | ||
|
d35e62f8cf | ||
|
904babdd13 | ||
|
154d3842a8 | ||
|
edb8a120bd |
122
CHANGELOG.md
122
CHANGELOG.md
@@ -1,3 +1,123 @@
|
|||||||
|
#### 2.2.0-beta.1: Beta Release
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 2.1.4: Maintenance Release
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- fix env var access using $parent for groups (#3278) @HiroyasuNishiyama
|
||||||
|
- Add proper error handling for 404 errors when serving debug files (#3277) @knolleary
|
||||||
|
- Add Japanese translations for Node-RED v2.1.0-beta.1 (#3179) @kazuhitoyokoi
|
||||||
|
- Include full user object on login audit events (#3269) @knolleary
|
||||||
|
- Remove styling from de locale files (#3237) @knolleary
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Change tab hide button icon to an eye and add search option (#3282) @knolleary
|
||||||
|
- Fix i18n handling of namespaces with spaces in (#3281) @knolleary
|
||||||
|
- Trigger change event when autoComplete fills in input (#3280) @knolleary
|
||||||
|
- Apply CN i18n fix (#3279) @knolleary
|
||||||
|
- fix select menu label of config node to use paletteLabel (#3273) @HiroyasuNishiyama
|
||||||
|
- fix removed tab not to cause node conflict (#3275) @HiroyasuNishiyama
|
||||||
|
- Group diff fix (#3239) @knolleary
|
||||||
|
- Only toggle disabled workspace flag if on activeWorkspace (#3252) @knolleary
|
||||||
|
- Do not show status for disabled nodes (#3253) @knolleary
|
||||||
|
- Set dimension value for tour guide (#3265) @kazuhitoyokoi
|
||||||
|
- Avoid redundant initialisation of TypedInput type (#3263) @knolleary
|
||||||
|
- Don't let themes change flow port label color (#3270) @bonanitech
|
||||||
|
- Fix treeList gutter calculation to handle floating gutters (#3238) @knolleary
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- Debug: Handle RegExp types in Debug sidebar (#3251) @knolleary
|
||||||
|
- Delay: fix 2nd output when in rate limit per topic modes (#3261) @dceejay
|
||||||
|
- Link: fix to show link target when selected (#3267) @HiroyasuNishiyama
|
||||||
|
- Inject: Do not modify inject node props in oneditprepare (#3242) @knolleary
|
||||||
|
- HTTP Request: HTTP Basic Auth should always add : between username and password even if empty (#3236) @hardillb
|
||||||
|
|
||||||
|
#### 2.1.3: Maintenance Release
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- Update gen-publish script to update 'next' tag for main releases
|
||||||
|
- Add environment variable to enable/disable tours (#3221) @hardillb
|
||||||
|
- Fix loading non-default language files leaving runtime in wrong locale (#3225) @knolleary
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Refresh editor settings whenever a node is added or enabled (#3227) @knolleary
|
||||||
|
- Revert spinner css change that made it shrink in some cases (#3229) @knolleary
|
||||||
|
- Fix import notification message when importing config nodes (#3224) @knolleary
|
||||||
|
- Handle changing types of TypedInput repeatedly (#3223) @knolleary
|
||||||
|
|
||||||
|
|
||||||
|
#### 2.1.2: Maintenance Release
|
||||||
|
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- node-red-pi: Remove bash dependency (#3216) @a16bitsysop
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Improved regex for markdown renderer (#3213) @GerwinvBeek
|
||||||
|
- Fix TypedInput initialisation (#3220) @knolleary
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- MQTT: fix datatype in node config not used. fixes #3215 (#3219) @Steve-Mcl
|
||||||
|
|
||||||
|
#### 2.1.1: Maintenance Release
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Ensure tourGuide popover doesn't fall offscreen (#3212) @knolleary
|
||||||
|
- Fix issue with old inject nodes that migrated topic to 'string' type (#3210) @knolleary
|
||||||
|
- Add cache-busting query params to index.mst (#3211) @knolleary
|
||||||
|
- Fix TypedInput validation of type without options (#3207) @knolleary
|
||||||
|
|
||||||
|
#### 2.1.0: Milestone Release
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Position popover properly on a scrolled page
|
||||||
|
- Fixes from 2.1.0-beta.2 (#3202) @knolleary
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- Link Out: Fix saving link out node links (#3201) @knolleary
|
||||||
|
- Switch: Refix #3170 - copy switch rule type when adding new rule
|
||||||
|
- TCP Request: Add string option to TCP request node output (#3204) @dceejay
|
||||||
|
|
||||||
|
#### 2.1.0-beta.2: Beta Release
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Fix switching projects (#3199) @knolleary
|
||||||
|
- Use locale setting when installing/enabling node (#3198) @knolleary
|
||||||
|
- Do not show projects-wecome dialog until welcome tour completes (#3197) @knolleary
|
||||||
|
- Fix converting selection to subflow (#3196) @knolleary
|
||||||
|
- Avoid conflicts with native browser cmd-ctrl type shortcuts (#3195) @knolleary
|
||||||
|
- Ensure message tools stay attached to top-level entry in Debug/Context (#3186) @knolleary
|
||||||
|
- Ensure tab state updates properly when toggling enable state (#3175) @knolleary
|
||||||
|
- Improve handling of long labels in TreeList (#3176) @knolleary
|
||||||
|
- Shift-click tab scroll arrows to jump to start/end (#3177) @knolleary
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- Update package dependencies
|
||||||
|
- Update to latest node-red-admin
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- Dynamic MQTT connections (#3189)
|
||||||
|
- Link: Filter out Link Out Return nodes in Link In edit dialog Fixes #3187
|
||||||
|
- Link: Fix link call label (#3200) @knolleary
|
||||||
|
- Debug: Redesign debug filter options and make them persistant (#3183) @knolleary
|
||||||
|
- Inject: Widen Inject interval box for >1 digit (#3184) @knolleary
|
||||||
|
- Switch: Fix rule focus when switch 'otherwise' rule is used (#3185) @knolleary
|
||||||
|
|
||||||
#### 2.1.0-beta.1: Beta Release
|
#### 2.1.0-beta.1: Beta Release
|
||||||
|
|
||||||
Editor
|
Editor
|
||||||
@@ -46,7 +166,7 @@ Nodes
|
|||||||
- Switch: Copy previous rule type when adding rule to switch node (#3170) @knolleary
|
- Switch: Copy previous rule type when adding rule to switch node (#3170) @knolleary
|
||||||
- Delay node: add option to send intermediate messages on separate output (#3166) @knolleary
|
- Delay node: add option to send intermediate messages on separate output (#3166) @knolleary
|
||||||
- Typo in http request set method translation (#3173) @mailsvb
|
- Typo in http request set method translation (#3173) @mailsvb
|
||||||
|
|
||||||
#### 2.0.6: Maintenance Release
|
#### 2.0.6: Maintenance Release
|
||||||
|
|
||||||
Editor
|
Editor
|
||||||
|
@@ -583,7 +583,7 @@ module.exports = function(grunt) {
|
|||||||
grunt.registerMultiTask('attachCopyright', function() {
|
grunt.registerMultiTask('attachCopyright', function() {
|
||||||
var files = this.data.src;
|
var files = this.data.src;
|
||||||
var copyright = "/**\n"+
|
var copyright = "/**\n"+
|
||||||
" * Copyright JS Foundation and other contributors, http://js.foundation\n"+
|
" * Copyright OpenJS Foundation and other contributors, https://openjsf.org/\n"+
|
||||||
" *\n"+
|
" *\n"+
|
||||||
" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"+
|
" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"+
|
||||||
" * you may not use this file except in compliance with the License.\n"+
|
" * you may not use this file except in compliance with the License.\n"+
|
||||||
|
30
package.json
30
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "2.1.0-beta.1",
|
"version": "2.2.0-beta.1",
|
||||||
"description": "Low-code programming for event-driven applications",
|
"description": "Low-code programming for event-driven applications",
|
||||||
"homepage": "http://nodered.org",
|
"homepage": "http://nodered.org",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -26,9 +26,9 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "8.5.0",
|
"acorn": "8.6.0",
|
||||||
"acorn-walk": "8.2.0",
|
"acorn-walk": "8.2.0",
|
||||||
"ajv": "8.6.3",
|
"ajv": "8.8.2",
|
||||||
"async-mutex": "0.3.2",
|
"async-mutex": "0.3.2",
|
||||||
"basic-auth": "2.0.1",
|
"basic-auth": "2.0.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"content-type": "1.0.4",
|
"content-type": "1.0.4",
|
||||||
"cookie": "0.4.1",
|
"cookie": "0.4.1",
|
||||||
"cookie-parser": "1.4.5",
|
"cookie-parser": "1.4.6",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"cronosjs": "1.7.1",
|
"cronosjs": "1.7.1",
|
||||||
"denque": "2.0.1",
|
"denque": "2.0.1",
|
||||||
@@ -46,11 +46,11 @@
|
|||||||
"form-data": "4.0.0",
|
"form-data": "4.0.0",
|
||||||
"fs-extra": "10.0.0",
|
"fs-extra": "10.0.0",
|
||||||
"fs.notify": "0.0.4",
|
"fs.notify": "0.0.4",
|
||||||
"got": "11.8.2",
|
"got": "11.8.3",
|
||||||
"hash-sum": "2.0.0",
|
"hash-sum": "2.0.0",
|
||||||
"hpagent": "0.1.2",
|
"hpagent": "0.1.2",
|
||||||
"https-proxy-agent": "5.0.0",
|
"https-proxy-agent": "5.0.0",
|
||||||
"i18next": "21.2.4",
|
"i18next": "21.5.4",
|
||||||
"iconv-lite": "0.6.3",
|
"iconv-lite": "0.6.3",
|
||||||
"is-utf8": "0.2.1",
|
"is-utf8": "0.2.1",
|
||||||
"js-yaml": "3.14.1",
|
"js-yaml": "3.14.1",
|
||||||
@@ -60,22 +60,22 @@
|
|||||||
"media-typer": "1.1.0",
|
"media-typer": "1.1.0",
|
||||||
"memorystore": "1.6.6",
|
"memorystore": "1.6.6",
|
||||||
"mime": "2.5.2",
|
"mime": "2.5.2",
|
||||||
"moment-timezone": "0.5.33",
|
"moment-timezone": "0.5.34",
|
||||||
"mqtt": "4.2.8",
|
"mqtt": "4.2.8",
|
||||||
"multer": "1.4.3",
|
"multer": "1.4.3",
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
"node-red-admin": "^2.2.0",
|
"node-red-admin": "^2.2.1",
|
||||||
"nopt": "5.0.0",
|
"nopt": "5.0.0",
|
||||||
"oauth2orize": "1.11.0",
|
"oauth2orize": "1.11.1",
|
||||||
"on-headers": "1.0.2",
|
"on-headers": "1.0.2",
|
||||||
"passport": "0.5.0",
|
"passport": "0.5.0",
|
||||||
"passport-http-bearer": "1.0.1",
|
"passport-http-bearer": "1.0.1",
|
||||||
"passport-oauth2-client-password": "0.1.2",
|
"passport-oauth2-client-password": "0.1.2",
|
||||||
"raw-body": "2.4.1",
|
"raw-body": "2.4.2",
|
||||||
"semver": "7.3.5",
|
"semver": "7.3.5",
|
||||||
"tar": "6.1.11",
|
"tar": "6.1.11",
|
||||||
"tough-cookie": "4.0.0",
|
"tough-cookie": "4.0.0",
|
||||||
"uglify-js": "3.14.2",
|
"uglify-js": "3.14.4",
|
||||||
"uuid": "8.3.2",
|
"uuid": "8.3.2",
|
||||||
"ws": "7.5.1",
|
"ws": "7.5.1",
|
||||||
"xml2js": "0.4.23"
|
"xml2js": "0.4.23"
|
||||||
@@ -107,13 +107,13 @@
|
|||||||
"i18next-http-backend": "1.3.1",
|
"i18next-http-backend": "1.3.1",
|
||||||
"jquery-i18next": "1.2.1",
|
"jquery-i18next": "1.2.1",
|
||||||
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
||||||
"marked": "3.0.4",
|
"marked": "3.0.7",
|
||||||
"minami": "1.2.3",
|
"minami": "1.2.3",
|
||||||
"mocha": "9.1.2",
|
"mocha": "9.1.3",
|
||||||
"node-red-node-test-helper": "^0.2.7",
|
"node-red-node-test-helper": "^0.2.7",
|
||||||
"nodemon": "2.0.13",
|
"nodemon": "2.0.15",
|
||||||
"proxy": "^1.0.2",
|
"proxy": "^1.0.2",
|
||||||
"sass": "1.42.1",
|
"sass": "1.44.0",
|
||||||
"should": "13.2.3",
|
"should": "13.2.3",
|
||||||
"sinon": "11.1.2",
|
"sinon": "11.1.2",
|
||||||
"stoppable": "^1.1.0",
|
"stoppable": "^1.1.0",
|
||||||
|
@@ -141,7 +141,7 @@ function completeVerify(profile,done) {
|
|||||||
Users.authenticate(profile).then(function(user) {
|
Users.authenticate(profile).then(function(user) {
|
||||||
if (user) {
|
if (user) {
|
||||||
Tokens.create(user.username,"node-red-editor",user.permissions).then(function(tokens) {
|
Tokens.create(user.username,"node-red-editor",user.permissions).then(function(tokens) {
|
||||||
log.audit({event: "auth.login",username:user.username,scope:user.permissions});
|
log.audit({event: "auth.login",user,username:user.username,scope:user.permissions});
|
||||||
user.tokens = tokens;
|
user.tokens = tokens;
|
||||||
done(null,user);
|
done(null,user);
|
||||||
});
|
});
|
||||||
|
@@ -93,7 +93,7 @@ var passwordTokenExchange = function(client, username, password, scope, done) {
|
|||||||
return logEntry.user !== username;
|
return logEntry.user !== username;
|
||||||
});
|
});
|
||||||
Tokens.create(username,client.id,scope).then(function(tokens) {
|
Tokens.create(username,client.id,scope).then(function(tokens) {
|
||||||
log.audit({event: "auth.login",username:username,client:client.id,scope:scope});
|
log.audit({event: "auth.login",user,username:username,client:client.id,scope:scope});
|
||||||
done(null,tokens.accessToken,null,{expires_in:tokens.expires_in});
|
done(null,tokens.accessToken,null,{expires_in:tokens.expires_in});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@@ -48,9 +48,10 @@ module.exports = {
|
|||||||
var prevLang = i18n.i.language;
|
var prevLang = i18n.i.language;
|
||||||
// Trigger a load from disk of the language if it is not the default
|
// Trigger a load from disk of the language if it is not the default
|
||||||
i18n.i.changeLanguage(lang, function(){
|
i18n.i.changeLanguage(lang, function(){
|
||||||
var catalog = loadResource(lang, namespace);
|
i18n.i.changeLanguage(prevLang, function() {
|
||||||
res.json(catalog||{});
|
var catalog = loadResource(lang, namespace);
|
||||||
|
res.json(catalog||{});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
i18n.i.changeLanguage(prevLang);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,8 @@ var defaultContext = {
|
|||||||
tabicon: {
|
tabicon: {
|
||||||
icon: "red/images/node-red-icon-black.svg",
|
icon: "red/images/node-red-icon-black.svg",
|
||||||
colour: "#8f0000"
|
colour: "#8f0000"
|
||||||
}
|
},
|
||||||
|
version: require(path.join(__dirname,"../../package.json")).version
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
title: "Node-RED",
|
title: "Node-RED",
|
||||||
@@ -227,6 +228,11 @@ module.exports = {
|
|||||||
if (theme.theme) {
|
if (theme.theme) {
|
||||||
themeSettings.theme = theme.theme;
|
themeSettings.theme = theme.theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (theme.hasOwnProperty("tours")) {
|
||||||
|
themeSettings.tours = theme.tours;
|
||||||
|
}
|
||||||
|
|
||||||
return themeApp;
|
return themeApp;
|
||||||
},
|
},
|
||||||
context: async function() {
|
context: async function() {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-api",
|
"name": "@node-red/editor-api",
|
||||||
"version": "2.1.0-beta.1",
|
"version": "2.2.0-beta.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/util": "2.1.0-beta.1",
|
"@node-red/util": "2.2.0-beta.1",
|
||||||
"@node-red/editor-client": "2.1.0-beta.1",
|
"@node-red/editor-client": "2.2.0-beta.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"body-parser": "1.19.0",
|
"body-parser": "1.19.0",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"mime": "2.5.2",
|
"mime": "2.5.2",
|
||||||
"multer": "1.4.3",
|
"multer": "1.4.3",
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
"oauth2orize": "1.11.0",
|
"oauth2orize": "1.11.1",
|
||||||
"passport-http-bearer": "1.0.1",
|
"passport-http-bearer": "1.0.1",
|
||||||
"passport-oauth2-client-password": "0.1.2",
|
"passport-oauth2-client-password": "0.1.2",
|
||||||
"passport": "0.5.0",
|
"passport": "0.5.0",
|
||||||
|
@@ -59,6 +59,8 @@
|
|||||||
"hideOtherFlows": "Hide other flows",
|
"hideOtherFlows": "Hide other flows",
|
||||||
"showAllFlows": "Show all flows",
|
"showAllFlows": "Show all flows",
|
||||||
"hideAllFlows": "Hide all flows",
|
"hideAllFlows": "Hide all flows",
|
||||||
|
"hiddenFlows": "List __count__ hidden flow",
|
||||||
|
"hiddenFlows_plural": "List __count__ hidden flows",
|
||||||
"showLastHiddenFlow": "Show last hidden flow",
|
"showLastHiddenFlow": "Show last hidden flow",
|
||||||
"listFlows": "List flows",
|
"listFlows": "List flows",
|
||||||
"listSubflows": "List subflows",
|
"listSubflows": "List subflows",
|
||||||
@@ -90,6 +92,7 @@
|
|||||||
"palette": {
|
"palette": {
|
||||||
"show": "Show palette"
|
"show": "Show palette"
|
||||||
},
|
},
|
||||||
|
"edit": "Edit",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"userSettings": "User Settings",
|
"userSettings": "User Settings",
|
||||||
"nodes": "Nodes",
|
"nodes": "Nodes",
|
||||||
@@ -668,7 +671,8 @@
|
|||||||
"unusedConfigNodes": "Unused configuration nodes",
|
"unusedConfigNodes": "Unused configuration nodes",
|
||||||
"invalidNodes": "Invalid nodes",
|
"invalidNodes": "Invalid nodes",
|
||||||
"uknownNodes": "Unknown nodes",
|
"uknownNodes": "Unknown nodes",
|
||||||
"unusedSubflows": "Unused subflows"
|
"unusedSubflows": "Unused subflows",
|
||||||
|
"hiddenFlows": "Hidden flows"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
@@ -1135,6 +1139,7 @@
|
|||||||
"defaultValue": "Default value"
|
"defaultValue": "Default value"
|
||||||
},
|
},
|
||||||
"tourGuide": {
|
"tourGuide": {
|
||||||
|
"takeATour": "Take a tour",
|
||||||
"start": "Start",
|
"start": "Start",
|
||||||
"next": "Next"
|
"next": "Next"
|
||||||
},
|
},
|
||||||
|
@@ -54,7 +54,14 @@
|
|||||||
"delete": "本当に '__label__' を削除しますか?",
|
"delete": "本当に '__label__' を削除しますか?",
|
||||||
"dropFlowHere": "ここにフローをドロップしてください",
|
"dropFlowHere": "ここにフローをドロップしてください",
|
||||||
"addFlow": "フローの追加",
|
"addFlow": "フローの追加",
|
||||||
|
"addFlowToRight": "右側にフローを追加",
|
||||||
|
"hideFlow": "フローを非表示",
|
||||||
|
"hideOtherFlows": "他のフローを非表示",
|
||||||
|
"showAllFlows": "全てのフローを表示",
|
||||||
|
"hideAllFlows": "全てのフローを非表示",
|
||||||
|
"showLastHiddenFlow": "最後に非表示にしたフローを表示",
|
||||||
"listFlows": "フロー一覧",
|
"listFlows": "フロー一覧",
|
||||||
|
"listSubflows": "サブフロー一覧",
|
||||||
"status": "状態",
|
"status": "状態",
|
||||||
"enabled": "有効",
|
"enabled": "有効",
|
||||||
"disabled": "無効",
|
"disabled": "無効",
|
||||||
@@ -83,6 +90,7 @@
|
|||||||
"palette": {
|
"palette": {
|
||||||
"show": "パレットを表示"
|
"show": "パレットを表示"
|
||||||
},
|
},
|
||||||
|
"edit": "編集",
|
||||||
"settings": "設定",
|
"settings": "設定",
|
||||||
"userSettings": "ユーザ設定",
|
"userSettings": "ユーザ設定",
|
||||||
"nodes": "ノード",
|
"nodes": "ノード",
|
||||||
@@ -105,6 +113,7 @@
|
|||||||
"editPalette": "パレットの管理",
|
"editPalette": "パレットの管理",
|
||||||
"other": "その他",
|
"other": "その他",
|
||||||
"showTips": "ヒントを表示",
|
"showTips": "ヒントを表示",
|
||||||
|
"showWelcomeTours": "新バージョンのガイドツアーを表示",
|
||||||
"help": "Node-REDウェブサイト",
|
"help": "Node-REDウェブサイト",
|
||||||
"projects": "プロジェクト",
|
"projects": "プロジェクト",
|
||||||
"projects-new": "新規",
|
"projects-new": "新規",
|
||||||
@@ -116,7 +125,20 @@
|
|||||||
"groupSelection": "選択部分をグループ化",
|
"groupSelection": "選択部分をグループ化",
|
||||||
"ungroupSelection": "選択部分をグループ解除",
|
"ungroupSelection": "選択部分をグループ解除",
|
||||||
"groupMergeSelection": "選択部分をマージ",
|
"groupMergeSelection": "選択部分をマージ",
|
||||||
"groupRemoveSelection": "グループから削除"
|
"groupRemoveSelection": "グループから削除",
|
||||||
|
"arrange": "配置",
|
||||||
|
"alignLeft": "左揃え",
|
||||||
|
"alignCenter": "左右中央揃え",
|
||||||
|
"alignRight": "右揃え",
|
||||||
|
"alignTop": "上揃え",
|
||||||
|
"alignMiddle": "上下中央揃え",
|
||||||
|
"alignBottom": "下揃え",
|
||||||
|
"distributeHorizontally": "左右に整列",
|
||||||
|
"distributeVertically": "上下に整列",
|
||||||
|
"moveToBack": "最背面へ移動",
|
||||||
|
"moveToFront": "最前面へ移動",
|
||||||
|
"moveBackwards": "背面へ移動",
|
||||||
|
"moveForwards": "前面へ移動"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -451,7 +473,8 @@
|
|||||||
"global": "グローバル",
|
"global": "グローバル",
|
||||||
"workspace": "ワークスペース",
|
"workspace": "ワークスペース",
|
||||||
"selectAll": "全てのノードを選択",
|
"selectAll": "全てのノードを選択",
|
||||||
"selectAllConnected": "接続された全てのノードを選択",
|
"selectNone": "選択を外す",
|
||||||
|
"selectAllConnected": "接続されたノードを選択",
|
||||||
"addRemoveNode": "ノードの選択、選択解除",
|
"addRemoveNode": "ノードの選択、選択解除",
|
||||||
"editSelected": "選択したノードを編集",
|
"editSelected": "選択したノードを編集",
|
||||||
"deleteSelected": "選択したノードや接続を削除",
|
"deleteSelected": "選択したノードや接続を削除",
|
||||||
@@ -461,10 +484,13 @@
|
|||||||
"moveNode": "選択したノードを移動(移動量大)",
|
"moveNode": "選択したノードを移動(移動量大)",
|
||||||
"toggleSidebar": "サイドバーの表示/非表示",
|
"toggleSidebar": "サイドバーの表示/非表示",
|
||||||
"togglePalette": "パレットの表示/非表示",
|
"togglePalette": "パレットの表示/非表示",
|
||||||
"copyNode": "選択したノードをコピー",
|
"copyNode": "ノードをコピー",
|
||||||
"cutNode": "選択したノードを切り取り",
|
"cutNode": "ノードを切り取り",
|
||||||
"pasteNode": "ノードを貼り付け",
|
"pasteNode": "ノードを貼り付け",
|
||||||
|
"copyGroupStyle": "グループ様式をコピー",
|
||||||
|
"pasteGroupStyle": "グループ様式を貼り付け",
|
||||||
"undoChange": "変更操作を戻す",
|
"undoChange": "変更操作を戻す",
|
||||||
|
"redoChange": "変更操作をやり直し",
|
||||||
"searchBox": "ノードを検索",
|
"searchBox": "ノードを検索",
|
||||||
"managePalette": "パレットの管理",
|
"managePalette": "パレットの管理",
|
||||||
"actionList": "動作一覧"
|
"actionList": "動作一覧"
|
||||||
@@ -519,7 +545,8 @@
|
|||||||
"nodeEnabled_plural": "ノードを有効化しました:",
|
"nodeEnabled_plural": "ノードを有効化しました:",
|
||||||
"nodeDisabled": "ノードを無効化しました:",
|
"nodeDisabled": "ノードを無効化しました:",
|
||||||
"nodeDisabled_plural": "ノードを無効化しました:",
|
"nodeDisabled_plural": "ノードを無効化しました:",
|
||||||
"nodeUpgraded": "ノードモジュール __module__ をバージョン __version__ へ更新しました"
|
"nodeUpgraded": "ノードモジュール __module__ をバージョン __version__ へ更新しました",
|
||||||
|
"unknownNodeRegistered": "ノードの読み込みエラー: <ul><li>__type__<br>__error__</li></ul>"
|
||||||
},
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"title": "パレットの管理",
|
"title": "パレットの管理",
|
||||||
@@ -1108,6 +1135,11 @@
|
|||||||
"preview": "UIプレビュー",
|
"preview": "UIプレビュー",
|
||||||
"defaultValue": "デフォルト値"
|
"defaultValue": "デフォルト値"
|
||||||
},
|
},
|
||||||
|
"tourGuide": {
|
||||||
|
"takeATour": "ツアーを開始",
|
||||||
|
"start": "開始",
|
||||||
|
"next": "次へ"
|
||||||
|
},
|
||||||
"languages": {
|
"languages": {
|
||||||
"de": "ドイツ語",
|
"de": "ドイツ語",
|
||||||
"en-US": "英語",
|
"en-US": "英語",
|
||||||
|
@@ -225,7 +225,7 @@
|
|||||||
"compact": "紧凑",
|
"compact": "紧凑",
|
||||||
"formatted": "已格式化",
|
"formatted": "已格式化",
|
||||||
"copy": "导出到剪贴板",
|
"copy": "导出到剪贴板",
|
||||||
"export": "到处到库",
|
"export": "导出到库",
|
||||||
"exportAs": "导出为",
|
"exportAs": "导出为",
|
||||||
"overwrite": "替换",
|
"overwrite": "替换",
|
||||||
"exists": "<p><b>\"__file__\"</b>已存在</p><p>是否要替换它?</p>"
|
"exists": "<p><b>\"__file__\"</b>已存在</p><p>是否要替换它?</p>"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-client",
|
"name": "@node-red/editor-client",
|
||||||
"version": "2.1.0-beta.1",
|
"version": "2.2.0-beta.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@@ -38,6 +38,8 @@ RED.i18n = (function() {
|
|||||||
defaultNS: "editor",
|
defaultNS: "editor",
|
||||||
fallbackLng: ['en-US'],
|
fallbackLng: ['en-US'],
|
||||||
returnObjects: true,
|
returnObjects: true,
|
||||||
|
keySeparator: ".",
|
||||||
|
nsSeparator: ":",
|
||||||
interpolation: {
|
interpolation: {
|
||||||
unescapeSuffix: 'HTML',
|
unescapeSuffix: 'HTML',
|
||||||
escapeValue: false,
|
escapeValue: false,
|
||||||
|
@@ -266,8 +266,8 @@ RED.nodes = (function() {
|
|||||||
},
|
},
|
||||||
moveNode: function(n, newZ) {
|
moveNode: function(n, newZ) {
|
||||||
api.removeNode(n);
|
api.removeNode(n);
|
||||||
tabMap[newZ] = tabMap[newZ] || [];
|
n.z = newZ;
|
||||||
tabMap[newZ].push(n);
|
api.addNode(n)
|
||||||
},
|
},
|
||||||
moveNodesForwards: function(nodes) {
|
moveNodesForwards: function(nodes) {
|
||||||
var result = [];
|
var result = [];
|
||||||
@@ -719,29 +719,29 @@ RED.nodes = (function() {
|
|||||||
moveGroupToTab(node,z);
|
moveGroupToTab(node,z);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var oldZ = node.z;
|
||||||
allNodes.moveNode(node,z);
|
allNodes.moveNode(node,z);
|
||||||
var nl = nodeLinks[node.id];
|
var nl = nodeLinks[node.id];
|
||||||
if (nl) {
|
if (nl) {
|
||||||
nl.in.forEach(function(l) {
|
nl.in.forEach(function(l) {
|
||||||
var idx = linkTabMap[node.z].indexOf(l);
|
var idx = linkTabMap[oldZ].indexOf(l);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
linkTabMap[node.z].splice(idx, 1);
|
linkTabMap[oldZ].splice(idx, 1);
|
||||||
}
|
}
|
||||||
if ((l.source.z === z) && linkTabMap[z]) {
|
if ((l.source.z === z) && linkTabMap[z]) {
|
||||||
linkTabMap[z].push(l);
|
linkTabMap[z].push(l);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
nl.out.forEach(function(l) {
|
nl.out.forEach(function(l) {
|
||||||
var idx = linkTabMap[node.z].indexOf(l);
|
var idx = linkTabMap[oldZ].indexOf(l);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
linkTabMap[node.z].splice(idx, 1);
|
linkTabMap[oldZ].splice(idx, 1);
|
||||||
}
|
}
|
||||||
if ((l.target.z === z) && linkTabMap[z]) {
|
if ((l.target.z === z) && linkTabMap[z]) {
|
||||||
linkTabMap[z].push(l);
|
linkTabMap[z].push(l);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
node.z = z;
|
|
||||||
RED.events.emit("nodes:change",node);
|
RED.events.emit("nodes:change",node);
|
||||||
}
|
}
|
||||||
function moveGroupToTab(group, z) {
|
function moveGroupToTab(group, z) {
|
||||||
@@ -805,7 +805,6 @@ RED.nodes = (function() {
|
|||||||
var removedGroups = [];
|
var removedGroups = [];
|
||||||
if (ws) {
|
if (ws) {
|
||||||
delete workspaces[id];
|
delete workspaces[id];
|
||||||
allNodes.removeTab(id);
|
|
||||||
delete linkTabMap[id];
|
delete linkTabMap[id];
|
||||||
workspacesOrder.splice(workspacesOrder.indexOf(id),1);
|
workspacesOrder.splice(workspacesOrder.indexOf(id),1);
|
||||||
var i;
|
var i;
|
||||||
@@ -843,6 +842,7 @@ RED.nodes = (function() {
|
|||||||
for (i=removedGroups.length-1; i>=0; i--) {
|
for (i=removedGroups.length-1; i>=0; i--) {
|
||||||
removeGroup(removedGroups[i]);
|
removeGroup(removedGroups[i]);
|
||||||
}
|
}
|
||||||
|
allNodes.removeTab(id);
|
||||||
RED.events.emit('flows:remove',ws);
|
RED.events.emit('flows:remove',ws);
|
||||||
}
|
}
|
||||||
return {nodes:removedNodes,links:removedLinks, groups: removedGroups};
|
return {nodes:removedNodes,links:removedLinks, groups: removedGroups};
|
||||||
@@ -1097,6 +1097,11 @@ RED.nodes = (function() {
|
|||||||
// Until we know how that can happen, add a filter here to remove them
|
// Until we know how that can happen, add a filter here to remove them
|
||||||
node.nodes = node.nodes.filter(function(n) { return !!n }).map(function(n) { return n.id });
|
node.nodes = node.nodes.filter(function(n) { return !!n }).map(function(n) { return n.id });
|
||||||
}
|
}
|
||||||
|
if (n.type === "tab" || n.type === "group") {
|
||||||
|
if (node.env && node.env.length === 0) {
|
||||||
|
delete node.env;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (n._def.category != "config") {
|
if (n._def.category != "config") {
|
||||||
node.x = n.x;
|
node.x = n.x;
|
||||||
node.y = n.y;
|
node.y = n.y;
|
||||||
@@ -2384,7 +2389,6 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clear() {
|
function clear() {
|
||||||
allNodes.clear();
|
|
||||||
links = [];
|
links = [];
|
||||||
linkTabMap = {};
|
linkTabMap = {};
|
||||||
nodeLinks = {};
|
nodeLinks = {};
|
||||||
@@ -2405,6 +2409,8 @@ RED.nodes = (function() {
|
|||||||
initialLoad = null;
|
initialLoad = null;
|
||||||
workspaces = {};
|
workspaces = {};
|
||||||
|
|
||||||
|
allNodes.clear();
|
||||||
|
|
||||||
RED.nodes.dirty(false);
|
RED.nodes.dirty(false);
|
||||||
RED.view.redraw(true, true);
|
RED.view.redraw(true, true);
|
||||||
RED.palette.refresh();
|
RED.palette.refresh();
|
||||||
|
@@ -201,6 +201,7 @@ var RED = (function() {
|
|||||||
RED.projects.refresh(function(activeProject) {
|
RED.projects.refresh(function(activeProject) {
|
||||||
loadFlows(function() {
|
loadFlows(function() {
|
||||||
RED.sidebar.info.refresh()
|
RED.sidebar.info.refresh()
|
||||||
|
var showProjectWelcome = false;
|
||||||
if (!activeProject) {
|
if (!activeProject) {
|
||||||
// Projects enabled but no active project
|
// Projects enabled but no active project
|
||||||
RED.menu.setDisabled('menu-item-projects-open',true);
|
RED.menu.setDisabled('menu-item-projects-open',true);
|
||||||
@@ -208,10 +209,10 @@ var RED = (function() {
|
|||||||
if (activeProject === false) {
|
if (activeProject === false) {
|
||||||
// User previously decline the migration to projects.
|
// User previously decline the migration to projects.
|
||||||
} else { // null/undefined
|
} else { // null/undefined
|
||||||
RED.projects.showStartup();
|
showProjectWelcome = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
completeLoad();
|
completeLoad(showProjectWelcome);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -251,6 +252,9 @@ var RED = (function() {
|
|||||||
if (/^#flow\/.+$/.test(currentHash)) {
|
if (/^#flow\/.+$/.test(currentHash)) {
|
||||||
RED.workspaces.show(currentHash.substring(6),true);
|
RED.workspaces.show(currentHash.substring(6),true);
|
||||||
}
|
}
|
||||||
|
if (RED.workspaces.active() === 0 && RED.workspaces.count() > 0) {
|
||||||
|
RED.workspaces.show(RED.nodes.getWorkspaceOrder()[0])
|
||||||
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.warn(err);
|
console.warn(err);
|
||||||
RED.notify(
|
RED.notify(
|
||||||
@@ -267,7 +271,7 @@ var RED = (function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function completeLoad() {
|
function completeLoad(showProjectWelcome) {
|
||||||
var persistentNotifications = {};
|
var persistentNotifications = {};
|
||||||
RED.comms.subscribe("notification/#",function(topic,msg) {
|
RED.comms.subscribe("notification/#",function(topic,msg) {
|
||||||
var parts = topic.split("/");
|
var parts = topic.split("/");
|
||||||
@@ -471,22 +475,33 @@ var RED = (function() {
|
|||||||
var typeList;
|
var typeList;
|
||||||
var info;
|
var info;
|
||||||
if (topic == "notification/node/added") {
|
if (topic == "notification/node/added") {
|
||||||
var addedTypes = [];
|
RED.settings.refreshSettings(function(err, data) {
|
||||||
msg.forEach(function(m) {
|
var addedTypes = [];
|
||||||
var id = m.id;
|
msg.forEach(function(m) {
|
||||||
RED.nodes.addNodeSet(m);
|
var id = m.id;
|
||||||
addedTypes = addedTypes.concat(m.types);
|
RED.nodes.addNodeSet(m);
|
||||||
RED.i18n.loadNodeCatalog(id, function() {
|
addedTypes = addedTypes.concat(m.types);
|
||||||
$.get('nodes/'+id, function(data) {
|
RED.i18n.loadNodeCatalog(id, function() {
|
||||||
appendNodeConfig(data);
|
var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
|
||||||
|
$.ajax({
|
||||||
|
headers: {
|
||||||
|
"Accept":"text/html",
|
||||||
|
"Accept-Language": lang
|
||||||
|
},
|
||||||
|
cache: false,
|
||||||
|
url: 'nodes/'+id,
|
||||||
|
success: function(data) {
|
||||||
|
appendNodeConfig(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
if (addedTypes.length) {
|
||||||
if (addedTypes.length) {
|
typeList = "<ul><li>"+addedTypes.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
|
||||||
typeList = "<ul><li>"+addedTypes.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
|
RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
|
||||||
RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
|
}
|
||||||
}
|
loadIconList();
|
||||||
loadIconList();
|
})
|
||||||
} else if (topic == "notification/node/removed") {
|
} else if (topic == "notification/node/removed") {
|
||||||
for (i=0;i<msg.length;i++) {
|
for (i=0;i<msg.length;i++) {
|
||||||
m = msg[i];
|
m = msg[i];
|
||||||
@@ -499,18 +514,29 @@ var RED = (function() {
|
|||||||
loadIconList();
|
loadIconList();
|
||||||
} else if (topic == "notification/node/enabled") {
|
} else if (topic == "notification/node/enabled") {
|
||||||
if (msg.types) {
|
if (msg.types) {
|
||||||
info = RED.nodes.getNodeSet(msg.id);
|
RED.settings.refreshSettings(function(err, data) {
|
||||||
if (info.added) {
|
info = RED.nodes.getNodeSet(msg.id);
|
||||||
RED.nodes.enableNodeSet(msg.id);
|
if (info.added) {
|
||||||
typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
|
RED.nodes.enableNodeSet(msg.id);
|
||||||
RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
|
|
||||||
} else {
|
|
||||||
$.get('nodes/'+msg.id, function(data) {
|
|
||||||
appendNodeConfig(data);
|
|
||||||
typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
|
typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
|
||||||
RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
|
RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
|
||||||
});
|
} else {
|
||||||
}
|
var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
|
||||||
|
$.ajax({
|
||||||
|
headers: {
|
||||||
|
"Accept":"text/html",
|
||||||
|
"Accept-Language": lang
|
||||||
|
},
|
||||||
|
cache: false,
|
||||||
|
url: 'nodes/'+msg.id,
|
||||||
|
success: function(data) {
|
||||||
|
appendNodeConfig(data);
|
||||||
|
typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
|
||||||
|
RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (topic == "notification/node/disabled") {
|
} else if (topic == "notification/node/disabled") {
|
||||||
if (msg.types) {
|
if (msg.types) {
|
||||||
@@ -535,18 +561,24 @@ var RED = (function() {
|
|||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
loader.end();
|
loader.end();
|
||||||
checkFirstRun();
|
checkFirstRun(function() {
|
||||||
|
if (showProjectWelcome) {
|
||||||
|
RED.projects.showStartup();
|
||||||
|
}
|
||||||
|
});
|
||||||
},100);
|
},100);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkFirstRun() {
|
function checkFirstRun(done) {
|
||||||
if (RED.settings.theme("tours") === false) {
|
if (RED.settings.theme("tours") === false) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!RED.settings.get("editor.view.view-show-welcome-tours", true)) {
|
if (!RED.settings.get("editor.view.view-show-welcome-tours", true)) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RED.actions.invoke("core:show-welcome-tour", RED.settings.get("editor.tours.welcome"));
|
RED.actions.invoke("core:show-welcome-tour", RED.settings.get("editor.tours.welcome"), done);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildMainMenu() {
|
function buildMainMenu() {
|
||||||
@@ -558,7 +590,7 @@ var RED = (function() {
|
|||||||
{id:"menu-item-projects-settings",label:RED._("menu.label.projects-settings"),disabled:false,onselect:"core:show-project-settings"}
|
{id:"menu-item-projects-settings",label:RED._("menu.label.projects-settings"),disabled:false,onselect:"core:show-project-settings"}
|
||||||
]});
|
]});
|
||||||
}
|
}
|
||||||
menuOptions.push({id:"menu-item-edit-menu", label:"Edit", options: [
|
menuOptions.push({id:"menu-item-edit-menu", label:RED._("menu.label.edit"), options: [
|
||||||
{id: "menu-item-edit-undo", label:RED._("keyboard.undoChange"), disabled: true, onselect: "core:undo"},
|
{id: "menu-item-edit-undo", label:RED._("keyboard.undoChange"), disabled: true, onselect: "core:undo"},
|
||||||
{id: "menu-item-edit-redo", label:RED._("keyboard.redoChange"), disabled: true, onselect: "core:redo"},
|
{id: "menu-item-edit-redo", label:RED._("keyboard.redoChange"), disabled: true, onselect: "core:redo"},
|
||||||
null,
|
null,
|
||||||
|
@@ -125,7 +125,7 @@ RED.settings = (function () {
|
|||||||
load(done);
|
load(done);
|
||||||
}
|
}
|
||||||
|
|
||||||
var load = function(done) {
|
var refreshSettings = function(done) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
headers: {
|
headers: {
|
||||||
"Accept": "application/json"
|
"Accept": "application/json"
|
||||||
@@ -135,6 +135,23 @@ RED.settings = (function () {
|
|||||||
url: 'settings',
|
url: 'settings',
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
setProperties(data);
|
setProperties(data);
|
||||||
|
done(null, data);
|
||||||
|
},
|
||||||
|
error: function(jqXHR,textStatus,errorThrown) {
|
||||||
|
if (jqXHR.status === 401) {
|
||||||
|
if (/[?&]access_token=(.*?)(?:$|&)/.test(window.location.search)) {
|
||||||
|
window.location.search = "";
|
||||||
|
}
|
||||||
|
RED.user.login(function() { refreshSettings(done); });
|
||||||
|
} else {
|
||||||
|
console.log("Unexpected error loading settings:",jqXHR.status,textStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var load = function(done) {
|
||||||
|
refreshSettings(function(err, data) {
|
||||||
|
if (!err) {
|
||||||
if (!RED.settings.user || RED.settings.user.anonymous) {
|
if (!RED.settings.user || RED.settings.user.anonymous) {
|
||||||
RED.settings.remove("auth-tokens");
|
RED.settings.remove("auth-tokens");
|
||||||
}
|
}
|
||||||
@@ -147,18 +164,8 @@ RED.settings = (function () {
|
|||||||
console.log("D3",d3.version);
|
console.log("D3",d3.version);
|
||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
loadUserSettings(done);
|
loadUserSettings(done);
|
||||||
},
|
|
||||||
error: function(jqXHR,textStatus,errorThrown) {
|
|
||||||
if (jqXHR.status === 401) {
|
|
||||||
if (/[?&]access_token=(.*?)(?:$|&)/.test(window.location.search)) {
|
|
||||||
window.location.search = "";
|
|
||||||
}
|
|
||||||
RED.user.login(function() { load(done); });
|
|
||||||
} else {
|
|
||||||
console.log("Unexpected error loading settings:",jqXHR.status,textStatus);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadUserSettings(done) {
|
function loadUserSettings(done) {
|
||||||
@@ -234,6 +241,7 @@ RED.settings = (function () {
|
|||||||
init: init,
|
init: init,
|
||||||
load: load,
|
load: load,
|
||||||
loadUserSettings: loadUserSettings,
|
loadUserSettings: loadUserSettings,
|
||||||
|
refreshSettings: refreshSettings,
|
||||||
set: set,
|
set: set,
|
||||||
get: get,
|
get: get,
|
||||||
remove: remove,
|
remove: remove,
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
* value: String : the value to insert if selected
|
* value: String : the value to insert if selected
|
||||||
* label: String|DOM Element : the label to display in the dropdown.
|
* label: String|DOM Element : the label to display in the dropdown.
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$.widget( "nodered.autoComplete", {
|
$.widget( "nodered.autoComplete", {
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
maxHeight: 200,
|
maxHeight: 200,
|
||||||
class: "red-ui-autoComplete-container",
|
class: "red-ui-autoComplete-container",
|
||||||
options: completions,
|
options: completions,
|
||||||
onselect: (opt) => { this.element.val(opt.value); this.element.focus() },
|
onselect: (opt) => { this.element.val(opt.value); this.element.focus(); this.element.trigger("change") },
|
||||||
onclose: () => { this.completionMenuShown = false; delete this.menu; this.element.focus()}
|
onclose: () => { this.completionMenuShown = false; delete this.menu; this.element.focus()}
|
||||||
});
|
});
|
||||||
this.menu.show({
|
this.menu.show({
|
||||||
|
@@ -436,18 +436,17 @@ RED.popover = (function() {
|
|||||||
return {
|
return {
|
||||||
create: createPopover,
|
create: createPopover,
|
||||||
tooltip: function(target,content, action) {
|
tooltip: function(target,content, action) {
|
||||||
var label = content;
|
var label = function() {
|
||||||
if (action) {
|
var label = content;
|
||||||
label = function() {
|
if (action) {
|
||||||
var label = content;
|
|
||||||
var shortcut = RED.keyboard.getShortcut(action);
|
var shortcut = RED.keyboard.getShortcut(action);
|
||||||
if (shortcut && shortcut.key) {
|
if (shortcut && shortcut.key) {
|
||||||
label = $('<span>'+content+' <span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span></span>');
|
label = $('<span>'+content+' <span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span></span>');
|
||||||
}
|
}
|
||||||
return label;
|
|
||||||
}
|
}
|
||||||
|
return label;
|
||||||
}
|
}
|
||||||
return RED.popover.create({
|
var popover = RED.popover.create({
|
||||||
tooltip: true,
|
tooltip: true,
|
||||||
target:target,
|
target:target,
|
||||||
trigger: "hover",
|
trigger: "hover",
|
||||||
@@ -456,6 +455,14 @@ RED.popover = (function() {
|
|||||||
content: label,
|
content: label,
|
||||||
delay: { show: 750, hide: 50 }
|
delay: { show: 750, hide: 50 }
|
||||||
});
|
});
|
||||||
|
popover.setContent = function(newContent) {
|
||||||
|
content = newContent;
|
||||||
|
}
|
||||||
|
popover.setAction = function(newAction) {
|
||||||
|
action = newAction;
|
||||||
|
}
|
||||||
|
return popover;
|
||||||
|
|
||||||
},
|
},
|
||||||
menu: function(options) {
|
menu: function(options) {
|
||||||
var list = $('<ul class="red-ui-menu"></ul>');
|
var list = $('<ul class="red-ui-menu"></ul>');
|
||||||
@@ -596,7 +603,7 @@ RED.popover = (function() {
|
|||||||
var panelWidth = panel.width();
|
var panelWidth = panel.width();
|
||||||
|
|
||||||
var top = (targetHeight+pos.top) + offset[1];
|
var top = (targetHeight+pos.top) + offset[1];
|
||||||
if (top+panelHeight > $(window).height()) {
|
if (top+panelHeight-$(document).scrollTop() > $(window).height()) {
|
||||||
top -= (top+panelHeight)-$(window).height() + 5;
|
top -= (top+panelHeight)-$(window).height() + 5;
|
||||||
}
|
}
|
||||||
if (top < 0) {
|
if (top < 0) {
|
||||||
|
@@ -117,6 +117,8 @@ RED.tabs = (function() {
|
|||||||
menuOptions = options.menu()
|
menuOptions = options.menu()
|
||||||
} else if (Array.isArray(options.menu)) {
|
} else if (Array.isArray(options.menu)) {
|
||||||
menuOptions = options.menu;
|
menuOptions = options.menu;
|
||||||
|
} else if (typeof options.menu === 'function') {
|
||||||
|
menuOptions = options.menu();
|
||||||
}
|
}
|
||||||
menu = RED.menu.init({options: menuOptions});
|
menu = RED.menu.init({options: menuOptions});
|
||||||
menu.attr("id",options.id+"-menu");
|
menu.attr("id",options.id+"-menu");
|
||||||
@@ -164,9 +166,9 @@ RED.tabs = (function() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
scrollLeft = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-left"><a href="#" style="display:none;"><i class="fa fa-caret-left"></i></a></div>').appendTo(wrapper).find("a");
|
scrollLeft = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-left"><a href="#" style="display:none;"><i class="fa fa-caret-left"></i></a></div>').appendTo(wrapper).find("a");
|
||||||
scrollLeft.on('mousedown',function(evt) { scrollEventHandler(evt,'-=150') }).on('click',function(evt){ evt.preventDefault();});
|
scrollLeft.on('mousedown',function(evt) {scrollEventHandler(evt, evt.shiftKey?('-='+scrollContainer.scrollLeft()):'-=150') }).on('click',function(evt){ evt.preventDefault();});
|
||||||
scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a");
|
scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a");
|
||||||
scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') }).on('click',function(evt){ evt.preventDefault();});
|
scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,evt.shiftKey?('+='+(scrollContainer[0].scrollWidth - scrollContainer.width()-scrollContainer.scrollLeft())):'+=150') }).on('click',function(evt){ evt.preventDefault();});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.collapsible) {
|
if (options.collapsible) {
|
||||||
@@ -809,15 +811,18 @@ RED.tabs = (function() {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
removeTab(tab.id);
|
removeTab(tab.id);
|
||||||
});
|
});
|
||||||
|
RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
|
||||||
}
|
}
|
||||||
if (tab.hideable) {
|
if (tab.hideable) {
|
||||||
li.addClass("red-ui-tabs-closeable")
|
li.addClass("red-ui-tabs-closeable")
|
||||||
var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li);
|
var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close red-ui-tab-hide"}).appendTo(li);
|
||||||
closeLink.append('<i class="fa fa-times" />');
|
closeLink.append('<i class="fa fa-eye" />');
|
||||||
|
closeLink.append('<i class="fa fa-eye-slash" />');
|
||||||
closeLink.on("click",function(event) {
|
closeLink.on("click",function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
hideTab(tab.id);
|
hideTab(tab.id);
|
||||||
});
|
});
|
||||||
|
RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
|
||||||
}
|
}
|
||||||
|
|
||||||
var badges = $('<span class="red-ui-tabs-badges"></span>').appendTo(li);
|
var badges = $('<span class="red-ui-tabs-badges"></span>').appendTo(li);
|
||||||
@@ -826,7 +831,8 @@ RED.tabs = (function() {
|
|||||||
$('<i class="red-ui-tabs-badge-selected fa fa-check-circle"></i>').appendTo(badges);
|
$('<i class="red-ui-tabs-badge-selected fa fa-check-circle"></i>').appendTo(badges);
|
||||||
}
|
}
|
||||||
|
|
||||||
link.attr("title",tab.label);
|
// link.attr("title",tab.label);
|
||||||
|
RED.popover.tooltip(link,function() { return tab.label})
|
||||||
|
|
||||||
if (options.onadd) {
|
if (options.onadd) {
|
||||||
options.onadd(tab);
|
options.onadd(tab);
|
||||||
@@ -945,7 +951,6 @@ RED.tabs = (function() {
|
|||||||
renameTab: function(id,label) {
|
renameTab: function(id,label) {
|
||||||
tabs[id].label = label;
|
tabs[id].label = label;
|
||||||
var tab = ul.find("a[href='#"+id+"']");
|
var tab = ul.find("a[href='#"+id+"']");
|
||||||
tab.attr("title",label);
|
|
||||||
tab.find("span.red-ui-text-bidi-aware").text(label).attr('dir', RED.text.bidi.resolveBaseTextDir(label));
|
tab.find("span.red-ui-text-bidi-aware").text(label).attr('dir', RED.text.bidi.resolveBaseTextDir(label));
|
||||||
updateTabWidths();
|
updateTabWidths();
|
||||||
},
|
},
|
||||||
|
@@ -24,6 +24,9 @@
|
|||||||
* - rootSortable: boolean - if 'sortable' is set, then setting this to
|
* - rootSortable: boolean - if 'sortable' is set, then setting this to
|
||||||
* false, prevents items being sorted to the
|
* false, prevents items being sorted to the
|
||||||
* top level of the tree
|
* top level of the tree
|
||||||
|
* - autoSelect: boolean - default true - triggers item selection when navigating
|
||||||
|
* list by keyboard. If the list has checkboxed items
|
||||||
|
* you probably want to set this to false
|
||||||
*
|
*
|
||||||
* methods:
|
* methods:
|
||||||
* - data(items) - clears existing items and replaces with new data
|
* - data(items) - clears existing items and replaces with new data
|
||||||
@@ -50,6 +53,7 @@
|
|||||||
* deferBuild: true/false, // don't build any ui elements for the item's children
|
* deferBuild: true/false, // don't build any ui elements for the item's children
|
||||||
* until it is expanded by the user.
|
* until it is expanded by the user.
|
||||||
* element: // custom dom element to use for the item - ignored if `label` is set
|
* element: // custom dom element to use for the item - ignored if `label` is set
|
||||||
|
* collapsible: true/false, // prevent a parent item from being collapsed. default true.
|
||||||
* }
|
* }
|
||||||
* ]
|
* ]
|
||||||
*
|
*
|
||||||
@@ -90,77 +94,99 @@
|
|||||||
$.widget( "nodered.treeList", {
|
$.widget( "nodered.treeList", {
|
||||||
_create: function() {
|
_create: function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
var autoSelect = true;
|
||||||
|
if (that.options.autoSelect === false) {
|
||||||
|
autoSelect = false;
|
||||||
|
}
|
||||||
this.element.addClass('red-ui-treeList');
|
this.element.addClass('red-ui-treeList');
|
||||||
this.element.attr("tabIndex",0);
|
this.element.attr("tabIndex",0);
|
||||||
var wrapper = $('<div>',{class:'red-ui-treeList-container'}).appendTo(this.element);
|
var wrapper = $('<div>',{class:'red-ui-treeList-container'}).appendTo(this.element);
|
||||||
this.element.on('keydown', function(evt) {
|
this.element.on('keydown', function(evt) {
|
||||||
var selected = that._topList.find(".selected").parent().data('data');
|
var focussed = that._topList.find(".focus").parent().data('data');
|
||||||
if (!selected && (evt.keyCode === 40 || evt.keyCode === 38)) {
|
if (!focussed && (evt.keyCode === 40 || evt.keyCode === 38)) {
|
||||||
that.select(that._data[0]);
|
if (that._data[0]) {
|
||||||
|
if (autoSelect) {
|
||||||
|
that.select(that._data[0]);
|
||||||
|
} else {
|
||||||
|
that._topList.find(".focus").removeClass("focus")
|
||||||
|
}
|
||||||
|
that._data[0].treeList.label.addClass('focus')
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var target;
|
var target;
|
||||||
switch(evt.keyCode) {
|
switch(evt.keyCode) {
|
||||||
|
case 32: // SPACE
|
||||||
case 13: // ENTER
|
case 13: // ENTER
|
||||||
|
if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) {
|
||||||
|
return
|
||||||
|
}
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
if (selected.children) {
|
if (focussed.checkbox) {
|
||||||
if (selected.treeList.container.hasClass("expanded")) {
|
focussed.treeList.checkbox.trigger("click");
|
||||||
selected.treeList.collapse()
|
} else if (focussed.radio) {
|
||||||
|
focussed.treeList.radio.trigger("click");
|
||||||
|
} else if (focussed.children) {
|
||||||
|
if (focussed.treeList.container.hasClass("expanded")) {
|
||||||
|
focussed.treeList.collapse()
|
||||||
} else {
|
} else {
|
||||||
selected.treeList.expand()
|
focussed.treeList.expand()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
that._trigger("confirm",null,selected)
|
that._trigger("confirm",null,focussed)
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 37: // LEFT
|
case 37: // LEFT
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
if (selected.children&& selected.treeList.container.hasClass("expanded")) {
|
if (focussed.children&& focussed.treeList.container.hasClass("expanded")) {
|
||||||
selected.treeList.collapse()
|
focussed.treeList.collapse()
|
||||||
} else if (selected.parent) {
|
} else if (focussed.parent) {
|
||||||
target = selected.parent;
|
target = focussed.parent;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 38: // UP
|
case 38: // UP
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
target = that._getPreviousSibling(selected);
|
target = that._getPreviousSibling(focussed);
|
||||||
if (target) {
|
if (target) {
|
||||||
target = that._getLastDescendant(target);
|
target = that._getLastDescendant(target);
|
||||||
}
|
}
|
||||||
if (!target && selected.parent) {
|
if (!target && focussed.parent) {
|
||||||
target = selected.parent;
|
target = focussed.parent;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 39: // RIGHT
|
case 39: // RIGHT
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
if (selected.children) {
|
if (focussed.children) {
|
||||||
if (!selected.treeList.container.hasClass("expanded")) {
|
if (!focussed.treeList.container.hasClass("expanded")) {
|
||||||
selected.treeList.expand()
|
focussed.treeList.expand()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 40: //DOWN
|
case 40: //DOWN
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
if (selected.children && Array.isArray(selected.children) && selected.children.length > 0 && selected.treeList.container.hasClass("expanded")) {
|
if (focussed.children && Array.isArray(focussed.children) && focussed.children.length > 0 && focussed.treeList.container.hasClass("expanded")) {
|
||||||
target = selected.children[0];
|
target = focussed.children[0];
|
||||||
} else {
|
} else {
|
||||||
target = that._getNextSibling(selected);
|
target = that._getNextSibling(focussed);
|
||||||
while (!target && selected.parent) {
|
while (!target && focussed.parent) {
|
||||||
selected = selected.parent;
|
focussed = focussed.parent;
|
||||||
target = that._getNextSibling(selected);
|
target = that._getNextSibling(focussed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if (target) {
|
if (target) {
|
||||||
that.select(target);
|
if (autoSelect) {
|
||||||
|
that.select(target);
|
||||||
|
} else {
|
||||||
|
that._topList.find(".focus").removeClass("focus")
|
||||||
|
}
|
||||||
|
target.treeList.label.addClass('focus')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this._data = [];
|
this._data = [];
|
||||||
@@ -314,7 +340,7 @@
|
|||||||
if (child.depth !== parent.depth+1) {
|
if (child.depth !== parent.depth+1) {
|
||||||
child.depth = parent.depth+1;
|
child.depth = parent.depth+1;
|
||||||
// var labelPaddingWidth = ((child.gutter ? child.gutter[0].offsetWidth + 2 : 0) + (child.depth * 20));
|
// var labelPaddingWidth = ((child.gutter ? child.gutter[0].offsetWidth + 2 : 0) + (child.depth * 20));
|
||||||
var labelPaddingWidth = ((child.gutter?child.gutter.width()+2:0)+(child.depth*20));
|
var labelPaddingWidth = (((child.gutter&&!child.gutter.hasClass("red-ui-treeList-gutter-float"))?child.gutter.width()+2:0)+(child.depth*20));
|
||||||
child.treeList.labelPadding.width(labelPaddingWidth+'px');
|
child.treeList.labelPadding.width(labelPaddingWidth+'px');
|
||||||
if (child.element) {
|
if (child.element) {
|
||||||
$(child.element).css({
|
$(child.element).css({
|
||||||
@@ -463,6 +489,9 @@
|
|||||||
container.addClass("expanded");
|
container.addClass("expanded");
|
||||||
}
|
}
|
||||||
item.treeList.collapse = function() {
|
item.treeList.collapse = function() {
|
||||||
|
if (item.collapsible === false) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!item.children) {
|
if (!item.children) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -533,10 +562,12 @@
|
|||||||
}).appendTo(label)
|
}).appendTo(label)
|
||||||
|
|
||||||
}
|
}
|
||||||
// var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20);
|
|
||||||
var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (depth * 20)
|
var labelPaddingWidth = ((item.gutter&&!item.gutter.hasClass("red-ui-treeList-gutter-float"))?item.gutter.width()+2:0)+(depth*20);
|
||||||
|
|
||||||
item.treeList.labelPadding = $('<span>').css({
|
item.treeList.labelPadding = $('<span>').css({
|
||||||
display: "inline-block",
|
display: "inline-block",
|
||||||
|
"flex-shrink": 0,
|
||||||
width: labelPaddingWidth+'px'
|
width: labelPaddingWidth+'px'
|
||||||
}).appendTo(label);
|
}).appendTo(label);
|
||||||
|
|
||||||
@@ -582,7 +613,7 @@
|
|||||||
// Already a parent because we've got the angle-right icon
|
// Already a parent because we've got the angle-right icon
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$('<i class="fa fa-angle-right" />').appendTo(treeListIcon);
|
$('<i class="fa fa-angle-right" />').toggleClass("hide",item.collapsible === false).appendTo(treeListIcon);
|
||||||
treeListIcon.on("click.red-ui-treeList-expand", function(e) {
|
treeListIcon.on("click.red-ui-treeList-expand", function(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -633,6 +664,8 @@
|
|||||||
label.on("click", function(e) {
|
label.on("click", function(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
cb.trigger("click");
|
cb.trigger("click");
|
||||||
|
that._topList.find(".focus").removeClass("focus")
|
||||||
|
label.addClass('focus')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
item.treeList.select = function(v) {
|
item.treeList.select = function(v) {
|
||||||
@@ -640,6 +673,7 @@
|
|||||||
cb.trigger("click");
|
cb.trigger("click");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
item.treeList.checkbox = cb;
|
||||||
selectWrapper.appendTo(label)
|
selectWrapper.appendTo(label)
|
||||||
} else if (item.radio) {
|
} else if (item.radio) {
|
||||||
var selectWrapper = $('<span class="red-ui-treeList-icon"></span>');
|
var selectWrapper = $('<span class="red-ui-treeList-icon"></span>');
|
||||||
@@ -668,6 +702,8 @@
|
|||||||
label.on("click", function(e) {
|
label.on("click", function(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
cb.trigger("click");
|
cb.trigger("click");
|
||||||
|
that._topList.find(".focus").removeClass("focus")
|
||||||
|
label.addClass('focus')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
item.treeList.select = function(v) {
|
item.treeList.select = function(v) {
|
||||||
@@ -676,6 +712,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectWrapper.appendTo(label)
|
selectWrapper.appendTo(label)
|
||||||
|
item.treeList.radio = cb;
|
||||||
} else {
|
} else {
|
||||||
label.on("click", function(e) {
|
label.on("click", function(e) {
|
||||||
if (!that.options.multi) {
|
if (!that.options.multi) {
|
||||||
@@ -683,10 +720,14 @@
|
|||||||
}
|
}
|
||||||
label.addClass("selected");
|
label.addClass("selected");
|
||||||
that._selected.add(item);
|
that._selected.add(item);
|
||||||
|
that._topList.find(".focus").removeClass("focus")
|
||||||
|
label.addClass('focus')
|
||||||
|
|
||||||
that._trigger("select",e,item)
|
that._trigger("select",e,item)
|
||||||
})
|
})
|
||||||
label.on("dblclick", function(e) {
|
label.on("dblclick", function(e) {
|
||||||
|
that._topList.find(".focus").removeClass("focus")
|
||||||
|
label.addClass('focus')
|
||||||
if (!item.children) {
|
if (!item.children) {
|
||||||
that._trigger("confirm",e,item);
|
that._trigger("confirm",e,item);
|
||||||
}
|
}
|
||||||
@@ -834,6 +875,9 @@
|
|||||||
if (item.treeList.label) {
|
if (item.treeList.label) {
|
||||||
item.treeList.label.addClass("selected");
|
item.treeList.label.addClass("selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
that._topList.find(".focus").removeClass("focus");
|
||||||
|
|
||||||
if (triggerEvent !== false) {
|
if (triggerEvent !== false) {
|
||||||
this._trigger("select",null,item)
|
this._trigger("select",null,item)
|
||||||
}
|
}
|
||||||
@@ -841,6 +885,9 @@
|
|||||||
clearSelection: function() {
|
clearSelection: function() {
|
||||||
this._selected.forEach(function(item) {
|
this._selected.forEach(function(item) {
|
||||||
item.selected = false;
|
item.selected = false;
|
||||||
|
if (item.treeList.checkbox) {
|
||||||
|
item.treeList.checkbox.prop('checked',false)
|
||||||
|
}
|
||||||
if (item.treeList.label) {
|
if (item.treeList.label) {
|
||||||
item.treeList.label.removeClass("selected")
|
item.treeList.label.removeClass("selected")
|
||||||
}
|
}
|
||||||
|
@@ -345,6 +345,47 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For a type with options, check value is a valid selection
|
||||||
|
// If !opt.multiple, returns the valid option object
|
||||||
|
// if opt.multiple, returns an array of valid option objects
|
||||||
|
// If not valid, returns null;
|
||||||
|
|
||||||
|
function isOptionValueValid(opt, currentVal) {
|
||||||
|
if (!opt.multiple) {
|
||||||
|
for (var i=0;i<opt.options.length;i++) {
|
||||||
|
op = opt.options[i];
|
||||||
|
if (typeof op === "string" && op === currentVal) {
|
||||||
|
return {value:currentVal}
|
||||||
|
} else if (op.value === currentVal) {
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Check to see if value is a valid csv of
|
||||||
|
// options.
|
||||||
|
var currentValues = {};
|
||||||
|
var selected = [];
|
||||||
|
currentVal.split(",").forEach(function(v) {
|
||||||
|
if (v) {
|
||||||
|
currentValues[v] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (var i=0;i<opt.options.length;i++) {
|
||||||
|
op = opt.options[i];
|
||||||
|
var val = typeof op === "string" ? op : op.value;
|
||||||
|
if (currentValues.hasOwnProperty(val)) {
|
||||||
|
delete currentValues[val];
|
||||||
|
selected.push(typeof op === "string" ? {value:op} : op.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$.isEmptyObject(currentValues)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return selected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var nlsd = false;
|
var nlsd = false;
|
||||||
|
|
||||||
$.widget( "nodered.typedInput", {
|
$.widget( "nodered.typedInput", {
|
||||||
@@ -378,7 +419,8 @@
|
|||||||
}
|
}
|
||||||
nlsd = true;
|
nlsd = true;
|
||||||
var that = this;
|
var that = this;
|
||||||
|
this.identifier = this.element.attr('id') || "TypedInput-"+Math.floor(Math.random()*100);
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"Create",{defaultType:this.options.default, value:this.element.val()}) }
|
||||||
this.disarmClick = false;
|
this.disarmClick = false;
|
||||||
this.input = $('<input class="red-ui-typedInput-input" type="text"></input>');
|
this.input = $('<input class="red-ui-typedInput-input" type="text"></input>');
|
||||||
this.input.insertAfter(this.element);
|
this.input.insertAfter(this.element);
|
||||||
@@ -408,6 +450,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.defaultInputType = this.input.attr('type');
|
this.defaultInputType = this.input.attr('type');
|
||||||
|
// Used to remember selections per-type to restore them when switching between types
|
||||||
|
this.oldValues = {};
|
||||||
|
|
||||||
this.uiSelect.addClass("red-ui-typedInput-container");
|
this.uiSelect.addClass("red-ui-typedInput-container");
|
||||||
|
|
||||||
@@ -490,9 +534,9 @@
|
|||||||
// explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline'
|
// explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline'
|
||||||
this.optionSelectTrigger = $('<button tabindex="0" class="red-ui-typedInput-option-trigger" style="display:inline-block"><span class="red-ui-typedInput-option-caret"><i class="red-ui-typedInput-icon fa fa-caret-down"></i></span></button>').appendTo(this.uiSelect);
|
this.optionSelectTrigger = $('<button tabindex="0" class="red-ui-typedInput-option-trigger" style="display:inline-block"><span class="red-ui-typedInput-option-caret"><i class="red-ui-typedInput-icon fa fa-caret-down"></i></span></button>').appendTo(this.uiSelect);
|
||||||
this.optionSelectLabel = $('<span class="red-ui-typedInput-option-label"></span>').prependTo(this.optionSelectTrigger);
|
this.optionSelectLabel = $('<span class="red-ui-typedInput-option-label"></span>').prependTo(this.optionSelectTrigger);
|
||||||
RED.popover.tooltip(this.optionSelectLabel,function() {
|
// RED.popover.tooltip(this.optionSelectLabel,function() {
|
||||||
return that.optionValue;
|
// return that.optionValue;
|
||||||
});
|
// });
|
||||||
this.optionSelectTrigger.on("click", function(event) {
|
this.optionSelectTrigger.on("click", function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@@ -512,10 +556,8 @@
|
|||||||
this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"></button>').appendTo(this.uiSelect);
|
this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"></button>').appendTo(this.uiSelect);
|
||||||
this.optionExpandButtonIcon = $('<i class="red-ui-typedInput-icon fa fa-ellipsis-h"></i>').appendTo(this.optionExpandButton);
|
this.optionExpandButtonIcon = $('<i class="red-ui-typedInput-icon fa fa-ellipsis-h"></i>').appendTo(this.optionExpandButton);
|
||||||
|
|
||||||
// Used to remember selections per-type to restore them when switching between types
|
this.type(this.typeField.val() || this.options.default||this.typeList[0].value);
|
||||||
this.oldValues = {};
|
this.typeChanged = !!this.options.default;
|
||||||
|
|
||||||
this.type(this.options.default||this.typeList[0].value);
|
|
||||||
}catch(err) {
|
}catch(err) {
|
||||||
console.log(err.stack);
|
console.log(err.stack);
|
||||||
}
|
}
|
||||||
@@ -763,6 +805,7 @@
|
|||||||
var that = this;
|
var that = this;
|
||||||
var currentType = this.type();
|
var currentType = this.type();
|
||||||
this.typeMap = {};
|
this.typeMap = {};
|
||||||
|
var firstCall = (this.typeList === undefined);
|
||||||
this.typeList = types.map(function(opt) {
|
this.typeList = types.map(function(opt) {
|
||||||
var result;
|
var result;
|
||||||
if (typeof opt === 'string') {
|
if (typeof opt === 'string') {
|
||||||
@@ -787,10 +830,14 @@
|
|||||||
}
|
}
|
||||||
this.menu = this._createMenu(this.typeList,{},function(v) { that.type(v) });
|
this.menu = this._createMenu(this.typeList,{},function(v) { that.type(v) });
|
||||||
if (currentType && !this.typeMap.hasOwnProperty(currentType)) {
|
if (currentType && !this.typeMap.hasOwnProperty(currentType)) {
|
||||||
this.type(this.typeList[0].value);
|
if (!firstCall) {
|
||||||
|
this.type(this.typeList[0].value);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.propertyType = null;
|
this.propertyType = null;
|
||||||
this.type(currentType);
|
if (!firstCall) {
|
||||||
|
this.type(currentType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.typeList.length === 1 && !this.typeList[0].icon && (!this.typeList[0].label || this.typeList[0].showLabel === false)) {
|
if (this.typeList.length === 1 && !this.typeList[0].icon && (!this.typeList[0].label || this.typeList[0].showLabel === false)) {
|
||||||
this.selectTrigger.hide()
|
this.selectTrigger.hide()
|
||||||
@@ -806,7 +853,10 @@
|
|||||||
},
|
},
|
||||||
value: function(value) {
|
value: function(value) {
|
||||||
var that = this;
|
var that = this;
|
||||||
var opt = this.typeMap[this.propertyType];
|
// If the default type has been set to an invalid type, then on first
|
||||||
|
// creation, the current propertyType will not exist. Default to an
|
||||||
|
// empty object on the assumption the corrent type will be set shortly
|
||||||
|
var opt = this.typeMap[this.propertyType] || {};
|
||||||
if (!arguments.length) {
|
if (!arguments.length) {
|
||||||
var v = this.input.val();
|
var v = this.input.val();
|
||||||
if (opt.export) {
|
if (opt.export) {
|
||||||
@@ -814,27 +864,38 @@
|
|||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
} else {
|
} else {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"----- SET VALUE ------",value) }
|
||||||
var selectedOption = [];
|
var selectedOption = [];
|
||||||
|
var valueToCheck = value;
|
||||||
if (opt.options) {
|
if (opt.options) {
|
||||||
var checkValues = [value];
|
if (opt.hasValue && opt.parse) {
|
||||||
|
var parts = opt.parse(value);
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"new parse",parts) }
|
||||||
|
value = parts.value;
|
||||||
|
valueToCheck = parts.option || parts.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkValues = [valueToCheck];
|
||||||
if (opt.multiple) {
|
if (opt.multiple) {
|
||||||
selectedOption = [];
|
selectedOption = [];
|
||||||
checkValues = value.split(",");
|
checkValues = valueToCheck.split(",");
|
||||||
}
|
}
|
||||||
checkValues.forEach(function(value) {
|
checkValues.forEach(function(valueToCheck) {
|
||||||
for (var i=0;i<opt.options.length;i++) {
|
for (var i=0;i<opt.options.length;i++) {
|
||||||
var op = opt.options[i];
|
var op = opt.options[i];
|
||||||
if (typeof op === "string") {
|
if (typeof op === "string") {
|
||||||
if (op === value || op === ""+value) {
|
if (op === valueToCheck || op === ""+valueToCheck) {
|
||||||
selectedOption.push(that.activeOptions[op]);
|
selectedOption.push(that.activeOptions[op]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (op.value === value) {
|
} else if (op.value === valueToCheck) {
|
||||||
selectedOption.push(op);
|
selectedOption.push(op);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"set value to",value) }
|
||||||
|
|
||||||
this.input.val(value);
|
this.input.val(value);
|
||||||
if (!opt.multiple) {
|
if (!opt.multiple) {
|
||||||
if (selectedOption.length === 0) {
|
if (selectedOption.length === 0) {
|
||||||
@@ -859,23 +920,56 @@
|
|||||||
return this.propertyType;
|
return this.propertyType;
|
||||||
} else {
|
} else {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"----- SET TYPE -----",type) }
|
||||||
|
var previousValue = null;
|
||||||
var opt = this.typeMap[type];
|
var opt = this.typeMap[type];
|
||||||
if (opt && this.propertyType !== type) {
|
if (opt && this.propertyType !== type) {
|
||||||
// If previousType is !null, then this is a change of the type, rather than the initialisation
|
// If previousType is !null, then this is a change of the type, rather than the initialisation
|
||||||
var previousType = this.typeMap[this.propertyType];
|
var previousType = this.typeMap[this.propertyType];
|
||||||
var typeChanged = !!previousType;
|
previousValue = this.input.val();
|
||||||
|
|
||||||
if (typeChanged) {
|
if (previousType && this.typeChanged) {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"typeChanged",{previousType,previousValue}) }
|
||||||
if (previousType.options && opt.hasValue !== true) {
|
if (previousType.options && opt.hasValue !== true) {
|
||||||
this.oldValues[previousType.value] = this.input.val();
|
this.oldValues[previousType.value] = previousValue;
|
||||||
} else if (previousType.hasValue === false) {
|
} else if (previousType.hasValue === false) {
|
||||||
this.oldValues[previousType.value] = this.input.val();
|
this.oldValues[previousType.value] = previousValue;
|
||||||
} else {
|
} else {
|
||||||
this.oldValues["_"] = this.input.val();
|
this.oldValues["_"] = previousValue;
|
||||||
}
|
}
|
||||||
if ((opt.options && opt.hasValue !== true) || opt.hasValue === false) {
|
if ((opt.options && opt.hasValue !== true) || opt.hasValue === false) {
|
||||||
this.input.val(this.oldValues.hasOwnProperty(opt.value)?this.oldValues[opt.value]:(opt.default||[]).join(","))
|
if (this.oldValues.hasOwnProperty(opt.value)) {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"restored previous (1)",this.oldValues[opt.value]) }
|
||||||
|
this.input.val(this.oldValues[opt.value]);
|
||||||
|
} else if (opt.options) {
|
||||||
|
// No old value for the option type.
|
||||||
|
// It is possible code has called 'value' then 'type'
|
||||||
|
// to set the selected option. This is what the Inject/Switch/Change
|
||||||
|
// nodes did before 2.1.
|
||||||
|
// So we need to be careful to not reset the value if it is a valid option.
|
||||||
|
var validOptions = isOptionValueValid(opt,previousValue);
|
||||||
|
if (this.options.debug) { console.log(this.identifier,{previousValue,opt,validOptions}) }
|
||||||
|
if ((previousValue || previousValue === '') && validOptions) {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"restored previous (2)") }
|
||||||
|
this.input.val(previousValue);
|
||||||
|
} else {
|
||||||
|
if (typeof opt.default === "string") {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"restored previous (3)",opt.default) }
|
||||||
|
this.input.val(opt.default);
|
||||||
|
} else if (Array.isArray(opt.default)) {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"restored previous (4)",opt.default.join(",")) }
|
||||||
|
this.input.val(opt.default.join(","))
|
||||||
|
} else {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"restored previous (5)") }
|
||||||
|
this.input.val("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"restored default/blank",opt.default||"") }
|
||||||
|
this.input.val(opt.default||"")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"restored old/default/blank") }
|
||||||
this.input.val(this.oldValues.hasOwnProperty("_")?this.oldValues["_"]:(opt.default||""))
|
this.input.val(this.oldValues.hasOwnProperty("_")?this.oldValues["_"]:(opt.default||""))
|
||||||
}
|
}
|
||||||
if (previousType.autoComplete) {
|
if (previousType.autoComplete) {
|
||||||
@@ -883,6 +977,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.propertyType = type;
|
this.propertyType = type;
|
||||||
|
this.typeChanged = true;
|
||||||
if (this.typeField) {
|
if (this.typeField) {
|
||||||
this.typeField.val(type);
|
this.typeField.val(type);
|
||||||
}
|
}
|
||||||
@@ -951,22 +1046,12 @@
|
|||||||
|
|
||||||
var op;
|
var op;
|
||||||
if (!opt.hasValue) {
|
if (!opt.hasValue) {
|
||||||
var validValue = false;
|
// Check the value is valid for the available options
|
||||||
var currentVal = this.input.val();
|
var validValues = isOptionValueValid(opt,this.input.val());
|
||||||
if (!opt.multiple) {
|
if (!opt.multiple) {
|
||||||
for (var i=0;i<opt.options.length;i++) {
|
if (validValues) {
|
||||||
op = opt.options[i];
|
that._updateOptionSelectLabel(validValues)
|
||||||
if (typeof op === "string" && op === currentVal) {
|
} else {
|
||||||
that._updateOptionSelectLabel({value:currentVal});
|
|
||||||
validValue = true;
|
|
||||||
break;
|
|
||||||
} else if (op.value === currentVal) {
|
|
||||||
that._updateOptionSelectLabel(op);
|
|
||||||
validValue = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!validValue) {
|
|
||||||
op = opt.options[0];
|
op = opt.options[0];
|
||||||
if (typeof op === "string") {
|
if (typeof op === "string") {
|
||||||
this.value(op);
|
this.value(op);
|
||||||
@@ -977,31 +1062,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check to see if value is a valid csv of
|
if (!validValues) {
|
||||||
// options.
|
validValues = (opt.default || []).map(function(v) {
|
||||||
var currentValues = {};
|
return typeof v === "string"?v:v.value
|
||||||
var selected = [];
|
});
|
||||||
currentVal.split(",").forEach(function(v) {
|
this.value(validValues.join(","));
|
||||||
if (v) {
|
|
||||||
selected.push(v);
|
|
||||||
currentValues[v] = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
for (var i=0;i<opt.options.length;i++) {
|
|
||||||
op = opt.options[i];
|
|
||||||
delete currentValues[op.value||op];
|
|
||||||
}
|
}
|
||||||
if (!$.isEmptyObject(currentValues)) {
|
that._updateOptionSelectLabel(validValues);
|
||||||
selected = opt.default || [];
|
|
||||||
// Invalid, set to default/empty
|
|
||||||
this.value(selected.join(","));
|
|
||||||
}
|
|
||||||
that._updateOptionSelectLabel(selected);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var selectedOption = this.optionValue||opt.options[0];
|
var selectedOption = this.optionValue||opt.options[0];
|
||||||
if (opt.parse) {
|
if (opt.parse) {
|
||||||
var parts = opt.parse(this.input.val(),selectedOption);
|
var selectedOptionObj = typeof selectedOption === "string"?{value:selectedOption}:selectedOption
|
||||||
|
var parts = opt.parse(this.input.val(),selectedOptionObj);
|
||||||
if (parts.option) {
|
if (parts.option) {
|
||||||
selectedOption = parts.option;
|
selectedOption = parts.option;
|
||||||
if (!this.activeOptions.hasOwnProperty(selectedOption)) {
|
if (!this.activeOptions.hasOwnProperty(selectedOption)) {
|
||||||
@@ -1025,6 +1098,7 @@
|
|||||||
this._updateOptionSelectLabel(this.activeOptions[selectedOption]);
|
this._updateOptionSelectLabel(this.activeOptions[selectedOption]);
|
||||||
}
|
}
|
||||||
} else if (selectedOption) {
|
} else if (selectedOption) {
|
||||||
|
if (this.options.debug) { console.log(this.identifier,"HERE",{optionValue:selectedOption.value}) }
|
||||||
this.optionValue = selectedOption.value;
|
this.optionValue = selectedOption.value;
|
||||||
this._updateOptionSelectLabel(selectedOption);
|
this._updateOptionSelectLabel(selectedOption);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -554,6 +554,8 @@ RED.diff = (function() {
|
|||||||
color: "#DDAA99",
|
color: "#DDAA99",
|
||||||
defaults:{name:{value:""}}
|
defaults:{name:{value:""}}
|
||||||
}
|
}
|
||||||
|
} else if (node.type === "group") {
|
||||||
|
def = RED.group.def;
|
||||||
} else {
|
} else {
|
||||||
def = {};
|
def = {};
|
||||||
}
|
}
|
||||||
@@ -763,16 +765,15 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (node.hasOwnProperty('x')) {
|
if (node.hasOwnProperty('x')) {
|
||||||
if (localNode) {
|
if (localNode) {
|
||||||
if (localNode.x !== node.x || localNode.y !== node.y) {
|
if (localNode.x !== node.x || localNode.y !== node.y || localNode.w !== node.w || localNode.h !== node.h ) {
|
||||||
localChanged = true;
|
localChanged = true;
|
||||||
localChanges++;
|
localChanges++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (remoteNode) {
|
if (remoteNode) {
|
||||||
if (remoteNode.x !== node.x || remoteNode.y !== node.y) {
|
if (remoteNode.x !== node.x || remoteNode.y !== node.y|| remoteNode.w !== node.w || remoteNode.h !== node.h) {
|
||||||
remoteChanged = true;
|
remoteChanged = true;
|
||||||
remoteChanges++;
|
remoteChanges++;
|
||||||
}
|
}
|
||||||
@@ -790,7 +791,12 @@ RED.diff = (function() {
|
|||||||
localCell.addClass("red-ui-diff-status-"+(localChanged?"changed":"unchanged"));
|
localCell.addClass("red-ui-diff-status-"+(localChanged?"changed":"unchanged"));
|
||||||
$('<span class="red-ui-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell);
|
$('<span class="red-ui-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell);
|
||||||
element = $('<span class="red-ui-diff-list-element"></span>').appendTo(localCell);
|
element = $('<span class="red-ui-diff-list-element"></span>').appendTo(localCell);
|
||||||
propertyElements['local.position'] = RED.utils.createObjectElement({x:localNode.x,y:localNode.y},
|
var localPosition = {x:localNode.x,y:localNode.y};
|
||||||
|
if (localNode.hasOwnProperty('w')) {
|
||||||
|
localPosition.w = localNode.w;
|
||||||
|
localPosition.h = localNode.h;
|
||||||
|
}
|
||||||
|
propertyElements['local.position'] = RED.utils.createObjectElement(localPosition,
|
||||||
{
|
{
|
||||||
path: "position",
|
path: "position",
|
||||||
exposeApi: true,
|
exposeApi: true,
|
||||||
@@ -811,7 +817,12 @@ RED.diff = (function() {
|
|||||||
if (remoteNode) {
|
if (remoteNode) {
|
||||||
$('<span class="red-ui-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell);
|
$('<span class="red-ui-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell);
|
||||||
element = $('<span class="red-ui-diff-list-element"></span>').appendTo(remoteCell);
|
element = $('<span class="red-ui-diff-list-element"></span>').appendTo(remoteCell);
|
||||||
propertyElements['remote.position'] = RED.utils.createObjectElement({x:remoteNode.x,y:remoteNode.y},
|
var remotePosition = {x:remoteNode.x,y:remoteNode.y};
|
||||||
|
if (remoteNode.hasOwnProperty('w')) {
|
||||||
|
remotePosition.w = remoteNode.w;
|
||||||
|
remotePosition.h = remoteNode.h;
|
||||||
|
}
|
||||||
|
propertyElements['remote.position'] = RED.utils.createObjectElement(remotePosition,
|
||||||
{
|
{
|
||||||
path: "position",
|
path: "position",
|
||||||
exposeApi: true,
|
exposeApi: true,
|
||||||
@@ -883,11 +894,11 @@ RED.diff = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var properties = Object.keys(node).filter(function(p) { return p!='inputLabels'&&p!='outputLabels'&&p!='z'&&p!='wires'&&p!=='x'&&p!=='y'&&p!=='id'&&p!=='type'&&(!def.defaults||!def.defaults.hasOwnProperty(p))});
|
var properties = Object.keys(node).filter(function(p) { return p!='inputLabels'&&p!='outputLabels'&&p!='z'&&p!='wires'&&p!=='x'&&p!=='y'&&p!=='w'&&p!=='h'&&p!=='id'&&p!=='type'&&(!def.defaults||!def.defaults.hasOwnProperty(p))});
|
||||||
if (def.defaults) {
|
if (def.defaults) {
|
||||||
properties = properties.concat(Object.keys(def.defaults));
|
properties = properties.concat(Object.keys(def.defaults));
|
||||||
}
|
}
|
||||||
if (node.type !== 'tab') {
|
if (node.type !== 'tab' && node.type !== "group") {
|
||||||
properties = properties.concat(['inputLabels','outputLabels']);
|
properties = properties.concat(['inputLabels','outputLabels']);
|
||||||
}
|
}
|
||||||
if ( ((localNode && localNode.hasOwnProperty('icon')) || (remoteNode && remoteNode.hasOwnProperty('icon'))) &&
|
if ( ((localNode && localNode.hasOwnProperty('icon')) || (remoteNode && remoteNode.hasOwnProperty('icon'))) &&
|
||||||
|
@@ -744,7 +744,16 @@ RED.editor = (function() {
|
|||||||
delete cn.__label__;
|
delete cn.__label__;
|
||||||
});
|
});
|
||||||
|
|
||||||
select.append('<option value="_ADD_"'+(value===""?" selected":"")+'>'+RED._("editor.addNewType", {type:type})+'</option>');
|
var label = type;
|
||||||
|
if (typeof node_def.paletteLabel !== "undefined") {
|
||||||
|
try {
|
||||||
|
label = RED.utils.sanitize((typeof node_def.paletteLabel === "function" ? node_def.paletteLabel.call(node_def) : node_def.paletteLabel)||type);
|
||||||
|
} catch(err) {
|
||||||
|
console.log("Definition error: "+type+".paletteLabel",err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select.append('<option value="_ADD_"'+(value===""?" selected":"")+'>'+RED._("editor.addNewType", {type:label})+'</option>');
|
||||||
window.setTimeout(function() { select.trigger("change");},50);
|
window.setTimeout(function() { select.trigger("change");},50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1755,8 +1764,12 @@ RED.editor = (function() {
|
|||||||
editState.changes.disabled = workspace.disabled;
|
editState.changes.disabled = workspace.disabled;
|
||||||
editState.changed = true;
|
editState.changed = true;
|
||||||
workspace.disabled = disabled;
|
workspace.disabled = disabled;
|
||||||
}
|
|
||||||
|
|
||||||
|
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
|
||||||
|
if (workspace.id === RED.workspaces.active()) {
|
||||||
|
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (editState.changed) {
|
if (editState.changed) {
|
||||||
var historyEvent = {
|
var historyEvent = {
|
||||||
|
@@ -56,8 +56,12 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!isSameObj(old_env, new_env)) {
|
if (!isSameObj(old_env, new_env)) {
|
||||||
node.env = new_env;
|
|
||||||
editState.changes.env = node.env;
|
editState.changes.env = node.env;
|
||||||
|
if (new_env.length === 0) {
|
||||||
|
delete node.env;
|
||||||
|
} else {
|
||||||
|
node.env = new_env;
|
||||||
|
}
|
||||||
editState.changed = true;
|
editState.changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -243,7 +243,13 @@ RED.keyboard = (function() {
|
|||||||
|
|
||||||
function resolveKeyEvent(evt) {
|
function resolveKeyEvent(evt) {
|
||||||
var slot = partialState||handlers;
|
var slot = partialState||handlers;
|
||||||
if (evt.ctrlKey || evt.metaKey) {
|
// We cheat with MacOS CMD key and consider it the same as Ctrl.
|
||||||
|
// That means we don't have to have separate keymaps for different OS.
|
||||||
|
// It mostly works.
|
||||||
|
// One exception is shortcuts that include both Cmd and Ctrl. We don't
|
||||||
|
// support them - but we need to make sure we don't block browser-specific
|
||||||
|
// shortcuts (such as Cmd-Ctrl-F for fullscreen).
|
||||||
|
if ((evt.ctrlKey || evt.metaKey) && (evt.ctrlKey !== evt.metaKey)) {
|
||||||
slot = slot.ctrl;
|
slot = slot.ctrl;
|
||||||
}
|
}
|
||||||
if (slot && evt.shiftKey) {
|
if (slot && evt.shiftKey) {
|
||||||
|
@@ -2387,6 +2387,7 @@ RED.projects = (function() {
|
|||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
showStartup: function() {
|
showStartup: function() {
|
||||||
|
console.warn("showStartup")
|
||||||
if (!RED.user.hasPermission("projects.write")) {
|
if (!RED.user.hasPermission("projects.write")) {
|
||||||
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
||||||
return;
|
return;
|
||||||
|
@@ -105,6 +105,7 @@ RED.search = (function() {
|
|||||||
val = extractFlag(val,"unused",flags);
|
val = extractFlag(val,"unused",flags);
|
||||||
val = extractFlag(val,"config",flags);
|
val = extractFlag(val,"config",flags);
|
||||||
val = extractFlag(val,"subflow",flags);
|
val = extractFlag(val,"subflow",flags);
|
||||||
|
val = extractFlag(val,"hidden",flags);
|
||||||
// uses:<node-id>
|
// uses:<node-id>
|
||||||
val = extractValue(val,"uses",flags);
|
val = extractValue(val,"uses",flags);
|
||||||
|
|
||||||
@@ -150,7 +151,15 @@ RED.search = (function() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (flags.hasOwnProperty("hidden")) {
|
||||||
|
// Only tabs can be hidden
|
||||||
|
if (node.node.type !== 'tab') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!RED.workspaces.isHidden(node.node.id)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
if (flags.hasOwnProperty("unused")) {
|
if (flags.hasOwnProperty("unused")) {
|
||||||
var isUnused = (node.node.type === 'subflow' && node.node.instances.length === 0) ||
|
var isUnused = (node.node.type === 'subflow' && node.node.instances.length === 0) ||
|
||||||
(isConfigNode && node.node.users.length === 0)
|
(isConfigNode && node.node.users.length === 0)
|
||||||
|
@@ -379,7 +379,7 @@ RED.sidebar.help = (function() {
|
|||||||
var currentVersionParts = RED.settings.version.split(".");
|
var currentVersionParts = RED.settings.version.split(".");
|
||||||
var tourVersionParts = tour.version.split(".");
|
var tourVersionParts = tour.version.split(".");
|
||||||
if (tourVersionParts[0] === currentVersionParts[0] && tourVersionParts[1] === currentVersionParts[1]) {
|
if (tourVersionParts[0] === currentVersionParts[0] && tourVersionParts[1] === currentVersionParts[1]) {
|
||||||
tourHeader = '<div><button type="button" onclick="RED.actions.invoke(\'core:show-welcome-tour\')" class="red-ui-button">Take a tour</button></div>'
|
tourHeader = '<div><button type="button" onclick="RED.actions.invoke(\'core:show-welcome-tour\')" class="red-ui-button">' + RED._("tourGuide.takeATour") + '</button></div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var aboutHeader = '<div style="text-align:center;">'+tourHeader+'</div>'
|
var aboutHeader = '<div style="text-align:center;">'+tourHeader+'</div>'
|
||||||
@@ -393,10 +393,12 @@ RED.sidebar.help = (function() {
|
|||||||
treeList.treeList("select","changelog");
|
treeList.treeList("select","changelog");
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
function showWelcomeTour(lastSeenVersion) {
|
function showWelcomeTour(lastSeenVersion, done) {
|
||||||
|
done = done || function() {};
|
||||||
RED.tourGuide.load("./tours/welcome.js", function(err, tour) {
|
RED.tourGuide.load("./tours/welcome.js", function(err, tour) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.warn("Failed to load welcome tour",err);
|
console.warn("Failed to load welcome tour",err);
|
||||||
|
done()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var currentVersionParts = RED.settings.version.split(".");
|
var currentVersionParts = RED.settings.version.split(".");
|
||||||
@@ -405,6 +407,7 @@ RED.sidebar.help = (function() {
|
|||||||
// Only display the tour if its MAJ.MIN versions the current version
|
// Only display the tour if its MAJ.MIN versions the current version
|
||||||
// This means if we update MAJ/MIN without updating the tour, the old tour won't get shown
|
// This means if we update MAJ/MIN without updating the tour, the old tour won't get shown
|
||||||
if (tourVersionParts[0] !== currentVersionParts[0] || tourVersionParts[1] !== currentVersionParts[1]) {
|
if (tourVersionParts[0] !== currentVersionParts[0] || tourVersionParts[1] !== currentVersionParts[1]) {
|
||||||
|
done()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,26 +415,31 @@ RED.sidebar.help = (function() {
|
|||||||
// Previously displayed a welcome tour.
|
// Previously displayed a welcome tour.
|
||||||
if (lastSeenVersion === RED.settings.version) {
|
if (lastSeenVersion === RED.settings.version) {
|
||||||
// Exact match - don't show the tour
|
// Exact match - don't show the tour
|
||||||
|
done()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var lastSeenParts = lastSeenVersion.split(".");
|
var lastSeenParts = lastSeenVersion.split(".");
|
||||||
if (currentVersionParts[0] < lastSeenParts[0] || (currentVersionParts[0] === lastSeenParts[0] && currentVersionParts[1] < lastSeenParts[1])) {
|
if (currentVersionParts[0] < lastSeenParts[0] || (currentVersionParts[0] === lastSeenParts[0] && currentVersionParts[1] < lastSeenParts[1])) {
|
||||||
// Running an *older* version than last displayed tour.
|
// Running an *older* version than last displayed tour.
|
||||||
|
done()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (currentVersionParts[0] === lastSeenParts[0] && currentVersionParts[1] === lastSeenParts[1]) {
|
if (currentVersionParts[0] === lastSeenParts[0] && currentVersionParts[1] === lastSeenParts[1]) {
|
||||||
if (lastSeenParts.length === 3 && currentVersionParts.length === 3) {
|
if (lastSeenParts.length === 3 && currentVersionParts.length === 3) {
|
||||||
// Matching non-beta MAJ.MIN - don't repeat tour
|
// Matching non-beta MAJ.MIN - don't repeat tour
|
||||||
|
done()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (currentVersionParts.length === 4 && (lastSeenParts.length === 3 || currentVersionParts[3] < lastSeenParts[3])) {
|
if (currentVersionParts.length === 4 && (lastSeenParts.length === 3 || currentVersionParts[3] < lastSeenParts[3])) {
|
||||||
// Running an *older* beta than last displayed tour.
|
// Running an *older* beta than last displayed tour.
|
||||||
|
done()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RED.tourGuide.run("./tours/welcome.js", function(err) {
|
RED.tourGuide.run("./tours/welcome.js", function(err) {
|
||||||
RED.settings.set("editor.tours.welcome", RED.settings.version)
|
RED.settings.set("editor.tours.welcome", RED.settings.version)
|
||||||
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -175,6 +175,7 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
n.d = true;
|
n.d = true;
|
||||||
}
|
}
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
|
n.dirtyStatus = true;
|
||||||
n.changed = true;
|
n.changed = true;
|
||||||
RED.events.emit("nodes:change",n);
|
RED.events.emit("nodes:change",n);
|
||||||
groupHistoryEvent.events.push(historyEvent);
|
groupHistoryEvent.events.push(historyEvent);
|
||||||
@@ -203,6 +204,7 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
n.d = true;
|
n.d = true;
|
||||||
}
|
}
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
|
n.dirtyStatus = true;
|
||||||
n.changed = true;
|
n.changed = true;
|
||||||
RED.events.emit("nodes:change",n);
|
RED.events.emit("nodes:change",n);
|
||||||
RED.history.push(historyEvent);
|
RED.history.push(historyEvent);
|
||||||
@@ -272,6 +274,7 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
{label:RED._("sidebar.info.search.invalidNodes"), value: "is:invalid"},
|
{label:RED._("sidebar.info.search.invalidNodes"), value: "is:invalid"},
|
||||||
{label:RED._("sidebar.info.search.uknownNodes"), value: "type:unknown"},
|
{label:RED._("sidebar.info.search.uknownNodes"), value: "type:unknown"},
|
||||||
{label:RED._("sidebar.info.search.unusedSubflows"), value:"is:subflow is:unused"},
|
{label:RED._("sidebar.info.search.unusedSubflows"), value:"is:subflow is:unused"},
|
||||||
|
{label:RED._("sidebar.info.search.hiddenFlows"), value:"is:hidden"},
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -287,11 +290,11 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
var node = RED.nodes.node(item.id) || RED.nodes.group(item.id);
|
var node = RED.nodes.node(item.id) || RED.nodes.group(item.id);
|
||||||
if (node) {
|
if (node) {
|
||||||
if (node.type === 'group' || node._def.category !== "config") {
|
if (node.type === 'group' || node._def.category !== "config") {
|
||||||
RED.view.select({nodes:[node]})
|
// RED.view.select({nodes:[node]})
|
||||||
} else if (node._def.category === "config") {
|
} else if (node._def.category === "config") {
|
||||||
RED.sidebar.info.refresh(node);
|
RED.sidebar.info.refresh(node);
|
||||||
} else {
|
} else {
|
||||||
RED.view.select({nodes:[]})
|
// RED.view.select({nodes:[]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -563,7 +566,7 @@ RED.sidebar.info.outliner = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getGutter(n) {
|
function getGutter(n) {
|
||||||
var span = $("<span>",{class:"red-ui-info-outline-gutter"});
|
var span = $("<span>",{class:"red-ui-info-outline-gutter red-ui-treeList-gutter-float"});
|
||||||
var revealButton = $('<button type="button" class="red-ui-info-outline-item-control-reveal red-ui-button red-ui-button-small"><i class="fa fa-search"></i></button>').appendTo(span).on("click",function(evt) {
|
var revealButton = $('<button type="button" class="red-ui-info-outline-item-control-reveal red-ui-button red-ui-button-small"><i class="fa fa-search"></i></button>').appendTo(span).on("click",function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
|
@@ -348,7 +348,12 @@ RED.tourGuide = (function() {
|
|||||||
maxWidth: maxWidth+"px",
|
maxWidth: maxWidth+"px",
|
||||||
direction: direction,
|
direction: direction,
|
||||||
})
|
})
|
||||||
|
setTimeout(function() {
|
||||||
|
var pos = popover.element.position()
|
||||||
|
if (pos.left < 0) {
|
||||||
|
popover.element.css({left: 0});
|
||||||
|
}
|
||||||
|
},100);
|
||||||
if (nextButton) {
|
if (nextButton) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
nextButton.focus();
|
nextButton.focus();
|
||||||
@@ -359,6 +364,8 @@ RED.tourGuide = (function() {
|
|||||||
if (step.fallback) {
|
if (step.fallback) {
|
||||||
focus.one("mouseenter", function(evt) {
|
focus.one("mouseenter", function(evt) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
var pos = targetElement[0].getBoundingClientRect();
|
||||||
|
var dimension = Math.max(50, Math.max(pos.width,pos.height)*1.5);
|
||||||
focus.css({
|
focus.css({
|
||||||
width: (4*dimension)+"px",
|
width: (4*dimension)+"px",
|
||||||
height: (4*dimension)+"px"
|
height: (4*dimension)+"px"
|
||||||
|
@@ -27,7 +27,7 @@ RED.utils = (function() {
|
|||||||
level: 'block', // Is this a block-level or inline-level tokenizer?
|
level: 'block', // Is this a block-level or inline-level tokenizer?
|
||||||
start(src) {
|
start(src) {
|
||||||
if (!src) { return null; }
|
if (!src) { return null; }
|
||||||
let m = src.match(/:[^:\n]/);
|
let m = src.match(/:[^:\n]/g);
|
||||||
return m && m.index; // Hint to Marked.js to stop and check for a match
|
return m && m.index; // Hint to Marked.js to stop and check for a match
|
||||||
},
|
},
|
||||||
tokenizer(src, tokens) {
|
tokenizer(src, tokens) {
|
||||||
@@ -39,12 +39,12 @@ RED.utils = (function() {
|
|||||||
type: 'descriptionList', // Should match "name" above
|
type: 'descriptionList', // Should match "name" above
|
||||||
raw: match[0], // Text to consume from the source
|
raw: match[0], // Text to consume from the source
|
||||||
text: match[0].trim(), // Additional custom properties
|
text: match[0].trim(), // Additional custom properties
|
||||||
tokens: this.inlineTokens(match[0].trim()) // inlineTokens to process **bold**, *italics*, etc.
|
tokens: this.lexer.inlineTokens(match[0].trim()) // inlineTokens to process **bold**, *italics*, etc.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
renderer(token) {
|
renderer(token) {
|
||||||
return `<dl class="message-properties">${this.parseInline(token.tokens)}\n</dl>`; // parseInline to turn child tokens into HTML
|
return `<dl class="message-properties">${this.parser.parseInline(token.tokens)}\n</dl>`; // parseInline to turn child tokens into HTML
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ RED.utils = (function() {
|
|||||||
level: 'inline', // Is this a block-level or inline-level tokenizer?
|
level: 'inline', // Is this a block-level or inline-level tokenizer?
|
||||||
start(src) {
|
start(src) {
|
||||||
if (!src) { return null; }
|
if (!src) { return null; }
|
||||||
let m = src.match(/:/);
|
let m = src.match(/:/g);
|
||||||
return m && m.index; // Hint to Marked.js to stop and check for a match
|
return m && m.index; // Hint to Marked.js to stop and check for a match
|
||||||
},
|
},
|
||||||
tokenizer(src, tokens) {
|
tokenizer(src, tokens) {
|
||||||
@@ -64,14 +64,14 @@ RED.utils = (function() {
|
|||||||
return { // Token to generate
|
return { // Token to generate
|
||||||
type: 'description', // Should match "name" above
|
type: 'description', // Should match "name" above
|
||||||
raw: match[0], // Text to consume from the source
|
raw: match[0], // Text to consume from the source
|
||||||
dt: this.inlineTokens(match[1].trim()), // Additional custom properties
|
dt: this.lexer.inlineTokens(match[1].trim()), // Additional custom properties
|
||||||
types: this.inlineTokens(match[2].trim()),
|
types: this.lexer.inlineTokens(match[2].trim()),
|
||||||
dd: this.inlineTokens(match[3].trim()),
|
dd: this.lexer.inlineTokens(match[3].trim()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
renderer(token) {
|
renderer(token) {
|
||||||
return `\n<dt>${this.parseInline(token.dt)}<span class="property-type">${this.parseInline(token.types)}</span></dt><dd>${this.parseInline(token.dd)}</dd>`;
|
return `\n<dt>${this.parser.parseInline(token.dt)}<span class="property-type">${this.parser.parseInline(token.types)}</span></dt><dd>${this.parser.parseInline(token.dd)}</dd>`;
|
||||||
},
|
},
|
||||||
childTokens: ['dt', 'dd'], // Any child tokens to be visited by walkTokens
|
childTokens: ['dt', 'dd'], // Any child tokens to be visited by walkTokens
|
||||||
walkTokens(token) { // Post-processing on the completed token tree
|
walkTokens(token) { // Post-processing on the completed token tree
|
||||||
@@ -142,6 +142,8 @@ RED.utils = (function() {
|
|||||||
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('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' || value.type === 'bigint')) {
|
} 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);
|
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-number"></span>').text(value.data);
|
||||||
|
} else if (value.hasOwnProperty('type') && value.type === 'regexp') {
|
||||||
|
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-string"></span>').text(value.data);
|
||||||
} else {
|
} else {
|
||||||
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta">object</span>');
|
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta">object</span>');
|
||||||
}
|
}
|
||||||
@@ -440,6 +442,8 @@ RED.utils = (function() {
|
|||||||
$('<span class="red-ui-debug-msg-type-null">undefined</span>').appendTo(entryObj);
|
$('<span class="red-ui-debug-msg-type-null">undefined</span>').appendTo(entryObj);
|
||||||
} else if (obj.__enc__ && (obj.type === 'number' || obj.type === 'bigint')) {
|
} 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);
|
e = $('<span class="red-ui-debug-msg-type-number red-ui-debug-msg-object-header"></span>').text(obj.data).appendTo(entryObj);
|
||||||
|
} else if (typeHint === "regexp" || (obj.__enc__ && obj.type === 'regexp')) {
|
||||||
|
e = $('<span class="red-ui-debug-msg-type-string red-ui-debug-msg-object-header"></span>').text((typeof obj === "string")?obj:obj.data).appendTo(entryObj);
|
||||||
} else if (typeHint === "function" || (obj.__enc__ && obj.type === 'function')) {
|
} 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);
|
e = $('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-header"></span>').text("function").appendTo(entryObj);
|
||||||
} else if (typeHint === "internal" || (obj.__enc__ && obj.type === 'internal')) {
|
} else if (typeHint === "internal" || (obj.__enc__ && obj.type === 'internal')) {
|
||||||
@@ -563,7 +567,8 @@ RED.utils = (function() {
|
|||||||
expandPaths: expandPaths,
|
expandPaths: expandPaths,
|
||||||
ontoggle: ontoggle,
|
ontoggle: ontoggle,
|
||||||
exposeApi: exposeApi,
|
exposeApi: exposeApi,
|
||||||
tools: tools
|
// tools: tools // Do not pass tools down as we
|
||||||
|
// keep them attached to the top-level header
|
||||||
}
|
}
|
||||||
).appendTo(row);
|
).appendTo(row);
|
||||||
}
|
}
|
||||||
@@ -592,7 +597,8 @@ RED.utils = (function() {
|
|||||||
expandPaths: expandPaths,
|
expandPaths: expandPaths,
|
||||||
ontoggle: ontoggle,
|
ontoggle: ontoggle,
|
||||||
exposeApi: exposeApi,
|
exposeApi: exposeApi,
|
||||||
tools: tools
|
// tools: tools // Do not pass tools down as we
|
||||||
|
// keep them attached to the top-level header
|
||||||
}
|
}
|
||||||
).appendTo(row);
|
).appendTo(row);
|
||||||
}
|
}
|
||||||
@@ -647,7 +653,8 @@ RED.utils = (function() {
|
|||||||
expandPaths: expandPaths,
|
expandPaths: expandPaths,
|
||||||
ontoggle: ontoggle,
|
ontoggle: ontoggle,
|
||||||
exposeApi: exposeApi,
|
exposeApi: exposeApi,
|
||||||
tools: tools
|
// tools: tools // Do not pass tools down as we
|
||||||
|
// keep them attached to the top-level header
|
||||||
}
|
}
|
||||||
).appendTo(row);
|
).appendTo(row);
|
||||||
}
|
}
|
||||||
|
@@ -3675,7 +3675,11 @@ RED.view = (function() {
|
|||||||
nodeEl = document.getElementById(d.id);
|
nodeEl = document.getElementById(d.id);
|
||||||
}
|
}
|
||||||
if (nodeEl) {
|
if (nodeEl) {
|
||||||
if (!showStatus || !d.status) {
|
// Do not show node status if:
|
||||||
|
// - global flag set
|
||||||
|
// - node has no status
|
||||||
|
// - node is disabled
|
||||||
|
if (!showStatus || !d.status || d.d === true) {
|
||||||
nodeEl.__statusGroup__.style.display = "none";
|
nodeEl.__statusGroup__.style.display = "none";
|
||||||
} else {
|
} else {
|
||||||
nodeEl.__statusGroup__.style.display = "inline";
|
nodeEl.__statusGroup__.style.display = "inline";
|
||||||
@@ -4006,10 +4010,10 @@ RED.view = (function() {
|
|||||||
var labelParts;
|
var labelParts;
|
||||||
if (d.resize || this.__hideLabel__ !== hideLabel || this.__label__ !== label || this.__outputs__.length !== d.outputs) {
|
if (d.resize || this.__hideLabel__ !== hideLabel || this.__label__ !== label || this.__outputs__.length !== d.outputs) {
|
||||||
labelParts = getLabelParts(label, "red-ui-flow-node-label");
|
labelParts = getLabelParts(label, "red-ui-flow-node-label");
|
||||||
this.__label__ = label;
|
if (labelParts.lines.length !== this.__labelLineCount__ || this.__label__ !== label) {
|
||||||
if (labelParts.lines.length !== this.__labelLineCount__) {
|
|
||||||
d.resize = true;
|
d.resize = true;
|
||||||
}
|
}
|
||||||
|
this.__label__ = label;
|
||||||
this.__labelLineCount__ = labelParts.lines.length;
|
this.__labelLineCount__ = labelParts.lines.length;
|
||||||
|
|
||||||
if (hideLabel) {
|
if (hideLabel) {
|
||||||
@@ -4421,6 +4425,9 @@ RED.view = (function() {
|
|||||||
n.selected = true;
|
n.selected = true;
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
movingSet.add(n);
|
movingSet.add(n);
|
||||||
|
if (targets.length === 1) {
|
||||||
|
RED.view.reveal(n.id);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
updateSelection();
|
updateSelection();
|
||||||
redraw();
|
redraw();
|
||||||
@@ -4957,7 +4964,7 @@ RED.view = (function() {
|
|||||||
counts.push(RED._("clipboard.group",{count:newGroupCount}));
|
counts.push(RED._("clipboard.group",{count:newGroupCount}));
|
||||||
}
|
}
|
||||||
if (newConfigNodeCount > 0) {
|
if (newConfigNodeCount > 0) {
|
||||||
counts.push(RED._("clipboard.configNode",{count:newNodeCount}));
|
counts.push(RED._("clipboard.configNode",{count:newConfigNodeCount}));
|
||||||
}
|
}
|
||||||
if (new_subflows.length > 0) {
|
if (new_subflows.length > 0) {
|
||||||
counts.push(RED._("clipboard.subflow",{count:new_subflows.length}));
|
counts.push(RED._("clipboard.subflow",{count:new_subflows.length}));
|
||||||
@@ -5029,6 +5036,7 @@ RED.view = (function() {
|
|||||||
delete node.d;
|
delete node.d;
|
||||||
}
|
}
|
||||||
node.dirty = true;
|
node.dirty = true;
|
||||||
|
node.dirtyStatus = true;
|
||||||
node.changed = true;
|
node.changed = true;
|
||||||
RED.events.emit("nodes:change",node);
|
RED.events.emit("nodes:change",node);
|
||||||
}
|
}
|
||||||
|
@@ -218,55 +218,64 @@ RED.workspaces = (function() {
|
|||||||
scrollable: true,
|
scrollable: true,
|
||||||
addButton: "core:add-flow",
|
addButton: "core:add-flow",
|
||||||
addButtonCaption: RED._("workspace.addFlow"),
|
addButtonCaption: RED._("workspace.addFlow"),
|
||||||
menu: [
|
menu: function() {
|
||||||
{
|
var menuItems = [
|
||||||
id:"red-ui-tabs-menu-option-search-flows",
|
{
|
||||||
label: RED._("workspace.listFlows"),
|
id:"red-ui-tabs-menu-option-search-flows",
|
||||||
onselect: "core:list-flows"
|
label: RED._("workspace.listFlows"),
|
||||||
},
|
onselect: "core:list-flows"
|
||||||
{
|
},
|
||||||
id:"red-ui-tabs-menu-option-search-subflows",
|
{
|
||||||
label: RED._("workspace.listSubflows"),
|
id:"red-ui-tabs-menu-option-search-subflows",
|
||||||
onselect: "core:list-subflows"
|
label: RED._("workspace.listSubflows"),
|
||||||
},
|
onselect: "core:list-subflows"
|
||||||
null,
|
},
|
||||||
{
|
null,
|
||||||
id:"red-ui-tabs-menu-option-add-flow",
|
{
|
||||||
label: RED._("workspace.addFlow"),
|
id:"red-ui-tabs-menu-option-add-flow",
|
||||||
onselect: "core:add-flow"
|
label: RED._("workspace.addFlow"),
|
||||||
},
|
onselect: "core:add-flow"
|
||||||
{
|
},
|
||||||
id:"red-ui-tabs-menu-option-add-flow-right",
|
{
|
||||||
label: RED._("workspace.addFlowToRight"),
|
id:"red-ui-tabs-menu-option-add-flow-right",
|
||||||
onselect: "core:add-flow-to-right"
|
label: RED._("workspace.addFlowToRight"),
|
||||||
},
|
onselect: "core:add-flow-to-right"
|
||||||
null,
|
},
|
||||||
{
|
null,
|
||||||
id:"red-ui-tabs-menu-option-add-hide-flows",
|
{
|
||||||
label: RED._("workspace.hideFlow"),
|
id:"red-ui-tabs-menu-option-add-hide-flows",
|
||||||
onselect: "core:hide-flow"
|
label: RED._("workspace.hideFlow"),
|
||||||
},
|
onselect: "core:hide-flow"
|
||||||
{
|
},
|
||||||
id:"red-ui-tabs-menu-option-add-hide-other-flows",
|
{
|
||||||
label: RED._("workspace.hideOtherFlows"),
|
id:"red-ui-tabs-menu-option-add-hide-other-flows",
|
||||||
onselect: "core:hide-other-flows"
|
label: RED._("workspace.hideOtherFlows"),
|
||||||
},
|
onselect: "core:hide-other-flows"
|
||||||
{
|
},
|
||||||
id:"red-ui-tabs-menu-option-add-show-all-flows",
|
{
|
||||||
label: RED._("workspace.showAllFlows"),
|
id:"red-ui-tabs-menu-option-add-show-all-flows",
|
||||||
onselect: "core:show-all-flows"
|
label: RED._("workspace.showAllFlows"),
|
||||||
},
|
onselect: "core:show-all-flows"
|
||||||
{
|
},
|
||||||
id:"red-ui-tabs-menu-option-add-hide-all-flows",
|
{
|
||||||
label: RED._("workspace.hideAllFlows"),
|
id:"red-ui-tabs-menu-option-add-hide-all-flows",
|
||||||
onselect: "core:hide-all-flows"
|
label: RED._("workspace.hideAllFlows"),
|
||||||
},
|
onselect: "core:hide-all-flows"
|
||||||
{
|
},
|
||||||
id:"red-ui-tabs-menu-option-add-show-last-flow",
|
{
|
||||||
label: RED._("workspace.showLastHiddenFlow"),
|
id:"red-ui-tabs-menu-option-add-show-last-flow",
|
||||||
onselect: "core:show-last-hidden-flow"
|
label: RED._("workspace.showLastHiddenFlow"),
|
||||||
|
onselect: "core:show-last-hidden-flow"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
if (hideStack.length > 0) {
|
||||||
|
menuItems.unshift({
|
||||||
|
label: RED._("workspace.hiddenFlows",{count: hideStack.length}),
|
||||||
|
onselect: "core:list-hidden-flows"
|
||||||
|
})
|
||||||
}
|
}
|
||||||
]
|
return menuItems;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
workspaceTabCount = 0;
|
workspaceTabCount = 0;
|
||||||
}
|
}
|
||||||
@@ -406,7 +415,9 @@ RED.workspaces = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
RED.actions.add("core:list-hidden-flows",function() {
|
||||||
|
RED.actions.invoke("core:search","is:hidden ");
|
||||||
|
})
|
||||||
RED.actions.add("core:list-flows",function() {
|
RED.actions.add("core:list-flows",function() {
|
||||||
RED.actions.invoke("core:search","type:tab ");
|
RED.actions.invoke("core:search","type:tab ");
|
||||||
})
|
})
|
||||||
@@ -450,7 +461,7 @@ RED.workspaces = (function() {
|
|||||||
var changes = { disabled: workspace.disabled };
|
var changes = { disabled: workspace.disabled };
|
||||||
workspace.disabled = disabled;
|
workspace.disabled = disabled;
|
||||||
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
|
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
|
||||||
if (id === activeWorkspace) {
|
if (!id || (id === activeWorkspace)) {
|
||||||
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
|
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
|
||||||
}
|
}
|
||||||
var historyEvent = {
|
var historyEvent = {
|
||||||
@@ -536,6 +547,9 @@ RED.workspaces = (function() {
|
|||||||
RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
|
RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isHidden: function(id) {
|
||||||
|
return hideStack.includes(id)
|
||||||
|
},
|
||||||
show: function(id,skipStack,unhideOnly) {
|
show: function(id,skipStack,unhideOnly) {
|
||||||
if (!workspace_tabs.contains(id)) {
|
if (!workspace_tabs.contains(id)) {
|
||||||
var sf = RED.nodes.subflow(id);
|
var sf = RED.nodes.subflow(id);
|
||||||
|
@@ -197,6 +197,7 @@ $view-select-mode-background: $secondary-background-selected;
|
|||||||
$view-grid-color: #eee;
|
$view-grid-color: #eee;
|
||||||
|
|
||||||
$node-label-color: #333;
|
$node-label-color: #333;
|
||||||
|
$node-port-label-color: #888;
|
||||||
$node-border: #999;
|
$node-border: #999;
|
||||||
$node-border-unknown: #f33;
|
$node-border-unknown: #f33;
|
||||||
$node-border-placeholder: #aaa;
|
$node-border-placeholder: #aaa;
|
||||||
|
@@ -43,12 +43,24 @@
|
|||||||
border-bottom: 1px solid $secondary-border-color;
|
border-bottom: 1px solid $secondary-border-color;
|
||||||
box-shadow: 0 2px 6px $shadow;
|
box-shadow: 0 2px 6px $shadow;
|
||||||
}
|
}
|
||||||
.red-ui-debug-filter-row {
|
#red-ui-sidebar-debug-filter-node-list-row {
|
||||||
.red-ui-nodeList {
|
.red-ui-treeList-label.disabled {
|
||||||
margin: 10px 0;
|
font-style: italic;
|
||||||
|
color: $secondary-text-color-disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-treeList-label {
|
||||||
|
&.selected, &.selected .red-ui-treeList-sublabel-text {
|
||||||
|
background: inherit;
|
||||||
|
}
|
||||||
|
&.selected, &.selected .red-ui-treeList-sublabel-text {
|
||||||
|
background: inherit;
|
||||||
|
}
|
||||||
|
&.focus, &.focus .red-ui-treeList-sublabel-text {
|
||||||
|
background: $list-item-background-hover !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-debug-msg {
|
.red-ui-debug-msg {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-bottom: 1px solid $debug-message-border;
|
border-bottom: 1px solid $debug-message-border;
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
.red-ui-flow-port-label {
|
.red-ui-flow-port-label {
|
||||||
stroke-width: 0;
|
stroke-width: 0;
|
||||||
fill: $secondary-text-color;
|
fill: $node-port-label-color;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
dominant-baseline: middle;
|
dominant-baseline: middle;
|
||||||
text-anchor: middle;
|
text-anchor: middle;
|
||||||
|
@@ -187,7 +187,7 @@
|
|||||||
ul.red-ui-menu-dropdown {
|
ul.red-ui-menu-dropdown {
|
||||||
background: $header-menu-background;
|
background: $header-menu-background;
|
||||||
border: 1px solid $header-menu-background;
|
border: 1px solid $header-menu-background;
|
||||||
width: 250px !important;
|
width: 260px !important;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
li a {
|
li a {
|
||||||
color: $header-menu-color;
|
color: $header-menu-color;
|
||||||
|
@@ -137,10 +137,10 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
border: 1px solid $form-input-border-color;
|
border: 1px solid $form-input-border-color;
|
||||||
}
|
}
|
||||||
.ui-spinner input[type=text] {
|
.ui-spinner input {
|
||||||
background: $form-input-background;
|
background: $form-input-background;
|
||||||
margin: 0 17px 0 0;
|
margin: 0 17px 0 0;
|
||||||
padding: 8px;
|
padding: 6px;
|
||||||
border: none;
|
border: none;
|
||||||
border-top-right-radius: 0px;
|
border-top-right-radius: 0px;
|
||||||
border-bottom-right-radius: 0px;
|
border-bottom-right-radius: 0px;
|
||||||
|
@@ -73,13 +73,13 @@
|
|||||||
.red-ui-projects-dialog-screen-start {
|
.red-ui-projects-dialog-screen-start {
|
||||||
.red-ui-projects-dialog-screen-start-hero {
|
.red-ui-projects-dialog-screen-start-hero {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 2em;
|
font-size: 1.4em;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
min-height: 60px;
|
min-height: 40px;
|
||||||
color: $primary-text-color;
|
color: $primary-text-color;
|
||||||
}
|
}
|
||||||
.red-ui-projects-dialog-screen-start-body {
|
.red-ui-projects-dialog-screen-start-body {
|
||||||
min-height: 400px;
|
min-height: 300px;
|
||||||
line-height: 1.6em;
|
line-height: 1.6em;
|
||||||
p {
|
p {
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
}
|
}
|
||||||
button.red-ui-button.red-ui-projects-dialog-button {
|
button.red-ui-button.red-ui-projects-dialog-button {
|
||||||
width: calc(50% - 80px);
|
width: calc(50% - 80px);
|
||||||
margin: 20px;
|
margin: 10px 20px;
|
||||||
height: auto;
|
height: auto;
|
||||||
line-height: 2em;
|
line-height: 2em;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
.red-ui-sidebar-info {
|
.red-ui-sidebar-info {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.red-ui-sidebar-info hr {
|
.red-ui-sidebar-info hr {
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
@@ -433,16 +434,19 @@ div.red-ui-info-table {
|
|||||||
}
|
}
|
||||||
.red-ui-info-outline-item-controls {
|
.red-ui-info-outline-item-controls {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top:0;
|
top:1px;
|
||||||
bottom: 0;
|
bottom: 1px;
|
||||||
right: 0px;
|
right: 1px;
|
||||||
padding: 2px 3px 0 1px;
|
padding: 1px 2px 0 1px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
background: $list-item-background;
|
background: $list-item-background;
|
||||||
|
|
||||||
.red-ui-treeList-label:hover & {
|
.red-ui-treeList-label:hover & {
|
||||||
background: $list-item-background-hover;
|
background: $list-item-background-hover;
|
||||||
}
|
}
|
||||||
|
.red-ui-treeList-label.focus & {
|
||||||
|
background: $list-item-background-hover;
|
||||||
|
}
|
||||||
.red-ui-treeList-label.selected & {
|
.red-ui-treeList-label.selected & {
|
||||||
background: $list-item-background-selected;
|
background: $list-item-background-selected;
|
||||||
}
|
}
|
||||||
|
@@ -389,7 +389,19 @@ i.red-ui-tab-icon {
|
|||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.red-ui-tab-hide {
|
||||||
|
.fa-eye-slash {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.fa-eye-slash {
|
||||||
|
display: inline
|
||||||
|
}
|
||||||
|
.fa-eye {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.red-ui-tab-close {
|
.red-ui-tab-close {
|
||||||
display: none;
|
display: none;
|
||||||
background: $tab-background-inactive;
|
background: $tab-background-inactive;
|
||||||
|
@@ -89,6 +89,12 @@
|
|||||||
color: $list-item-color;
|
color: $list-item-color;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
&.focus, &.focus .red-ui-treeList-sublabel-text {
|
||||||
|
background: $list-item-background-hover;
|
||||||
|
outline: 1px solid $form-input-focus-color !important;
|
||||||
|
outline-offset: -1px;
|
||||||
|
color: $list-item-color;
|
||||||
|
}
|
||||||
&.selected, &.selected .red-ui-treeList-sublabel-text {
|
&.selected, &.selected .red-ui-treeList-sublabel-text {
|
||||||
background: $list-item-background-selected;
|
background: $list-item-background-selected;
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -102,6 +108,8 @@
|
|||||||
}
|
}
|
||||||
.red-ui-treeList-label-text {
|
.red-ui-treeList-label-text {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
&:empty {
|
&:empty {
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
}
|
}
|
||||||
@@ -121,6 +129,7 @@
|
|||||||
|
|
||||||
.red-ui-treeList-icon {
|
.red-ui-treeList-icon {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
flex-shrink: 0;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,23 @@
|
|||||||
export default {
|
export default {
|
||||||
steps: [
|
steps: [
|
||||||
{
|
{
|
||||||
title: "Create your first flow",
|
title: {
|
||||||
|
'en-US': 'Create your first flow',
|
||||||
|
'ja': 'はじめてのフローを作成'
|
||||||
|
},
|
||||||
width: 400,
|
width: 400,
|
||||||
description: 'This tutorial will guide you through creating your first flow',
|
description: {
|
||||||
|
'en-US': 'This tutorial will guide you through creating your first flow',
|
||||||
|
'ja': '本チュートリアルでは、はじめてのフローを作成する方法について説明します。'
|
||||||
|
},
|
||||||
nextButton: 'start'
|
nextButton: 'start'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
element: "#red-ui-workspace .red-ui-tab-button.red-ui-tabs-add",
|
element: "#red-ui-workspace .red-ui-tab-button.red-ui-tabs-add",
|
||||||
description: 'To add a new tab, click the <i class="fa fa-plus"></i> button',
|
description: {
|
||||||
|
'en-US': 'To add a new tab, click the <i class="fa fa-plus"></i> button',
|
||||||
|
'ja': '新しいタブを追加するため、 <i class="fa fa-plus"></i> ボタンをクリックします。'
|
||||||
|
},
|
||||||
wait: {
|
wait: {
|
||||||
type: "dom-event",
|
type: "dom-event",
|
||||||
event: "click",
|
event: "click",
|
||||||
@@ -18,7 +27,10 @@ export default {
|
|||||||
{
|
{
|
||||||
element: '.red-ui-palette-node[data-palette-type="inject"]',
|
element: '.red-ui-palette-node[data-palette-type="inject"]',
|
||||||
direction: 'right',
|
direction: 'right',
|
||||||
description: 'The palette lists all of the nodes available to use. Drag a new Inject node into the workspace.',
|
description: {
|
||||||
|
'en-US': 'The palette lists all of the nodes available to use. Drag a new Inject node into the workspace.',
|
||||||
|
'ja': 'パレットには、利用できる全てのノードが一覧表示されます。injectノードをワークスペースにドラッグします。'
|
||||||
|
},
|
||||||
fallback: 'inset-bottom-right',
|
fallback: 'inset-bottom-right',
|
||||||
wait: {
|
wait: {
|
||||||
type: "nr-event",
|
type: "nr-event",
|
||||||
@@ -38,7 +50,10 @@ export default {
|
|||||||
{
|
{
|
||||||
element: '.red-ui-palette-node[data-palette-type="debug"]',
|
element: '.red-ui-palette-node[data-palette-type="debug"]',
|
||||||
direction: 'right',
|
direction: 'right',
|
||||||
description: 'Next, drag a new Debug node into the workspace.',
|
description: {
|
||||||
|
'en-US': 'Next, drag a new Debug node into the workspace.',
|
||||||
|
'ja': '次に、debugノードをワークスペースにドラッグします。'
|
||||||
|
},
|
||||||
fallback: 'inset-bottom-right',
|
fallback: 'inset-bottom-right',
|
||||||
wait: {
|
wait: {
|
||||||
type: "nr-event",
|
type: "nr-event",
|
||||||
@@ -57,7 +72,10 @@ export default {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
element: function() { return $("#"+this.injectNode.id+" .red-ui-flow-port") },
|
element: function() { return $("#"+this.injectNode.id+" .red-ui-flow-port") },
|
||||||
description: 'Add a wire from the output of the Inject node to the input of the Debug node',
|
description: {
|
||||||
|
'en-US': 'Add a wire from the output of the Inject node to the input of the Debug node',
|
||||||
|
'ja': 'injectノードの出力から、debugノードの入力へワイヤーで接続します。'
|
||||||
|
},
|
||||||
fallback: 'inset-bottom-right',
|
fallback: 'inset-bottom-right',
|
||||||
wait: {
|
wait: {
|
||||||
type: "nr-event",
|
type: "nr-event",
|
||||||
@@ -69,7 +87,10 @@ export default {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
element: "#red-ui-header-button-deploy",
|
element: "#red-ui-header-button-deploy",
|
||||||
description: 'Deploy your changes so the flow is active in the runtime',
|
description: {
|
||||||
|
'en-US': 'Deploy your changes so the flow is active in the runtime',
|
||||||
|
'ja': 'フローをランタイムで実行させるため、変更をデプロイします。'
|
||||||
|
},
|
||||||
width: 200,
|
width: 200,
|
||||||
wait: {
|
wait: {
|
||||||
type: "dom-event",
|
type: "dom-event",
|
||||||
|
@@ -3,48 +3,79 @@ export default {
|
|||||||
steps: [
|
steps: [
|
||||||
{
|
{
|
||||||
titleIcon: "fa fa-map-o",
|
titleIcon: "fa fa-map-o",
|
||||||
title: { "en-US": "Welcome to Node-RED 2.1!" },
|
title: {
|
||||||
description: { "en-US": "Let's take a moment to discover the new features in this release." }
|
"en-US": "Welcome to Node-RED 2.1!",
|
||||||
|
"ja": "Node-RED 2.1へようこそ!"
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
"en-US": "Let's take a moment to discover the new features in this release.",
|
||||||
|
"ja": "本リリースの新機能を見つけてみましょう。"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: { "en-US": "A new Tour Guide" },
|
title: {
|
||||||
description: { "en-US": "<p>First, as you've already found, we now have this tour of new features. We'll only show the tour the first time you open the editor for each new version of Node-RED.</p>"+
|
"en-US": "A new Tour Guide",
|
||||||
"<p>You can choose not to see this tour in the future by disabling it under the View tab of User Settings.</p>" }
|
"ja": "新しいツアーガイド"
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
"en-US": "<p>First, as you've already found, we now have this tour of new features. We'll only show the tour the first time you open the editor for each new version of Node-RED.</p>" +
|
||||||
|
"<p>You can choose not to see this tour in the future by disabling it under the View tab of User Settings.</p>",
|
||||||
|
"ja": "<p>最初に、既に見つけている様に、新機能の本ツアーがあります。本ツアーは、新バージョンのNode-REDフローエディタを初めて開いた時のみ表示されます。</p>" +
|
||||||
|
"<p>ユーザ設定の表示タブの中で、この機能を無効化することで、本ツアーを表示しないようにすることもできます。</p>"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: { "en-US": "New Edit menu" },
|
title: {
|
||||||
|
"en-US": "New Edit menu",
|
||||||
|
"ja": "新しい編集メニュー"
|
||||||
|
},
|
||||||
prepare() {
|
prepare() {
|
||||||
$("#red-ui-header-button-sidemenu").trigger("click");
|
$("#red-ui-header-button-sidemenu").trigger("click");
|
||||||
$("#menu-item-edit-menu").parent().addClass("open")
|
$("#menu-item-edit-menu").parent().addClass("open");
|
||||||
},
|
},
|
||||||
complete() {
|
complete() {
|
||||||
$("#menu-item-edit-menu").parent().removeClass("open")
|
$("#menu-item-edit-menu").parent().removeClass("open");
|
||||||
},
|
},
|
||||||
element: "#menu-item-edit-menu-submenu",
|
element: "#menu-item-edit-menu-submenu",
|
||||||
interactive: false,
|
interactive: false,
|
||||||
direction: "left",
|
direction: "left",
|
||||||
description: { "en-US": "<p>The main menu has been updated with a new 'Edit' section. This includes all of the familar options, like cut/paste and undo/redo.</p>"+
|
description: {
|
||||||
"<p>The menu now displays keyboard shortcuts for the options.</p>" }
|
"en-US": "<p>The main menu has been updated with a new 'Edit' section. This includes all of the familar options, like cut/paste and undo/redo.</p>" +
|
||||||
|
"<p>The menu now displays keyboard shortcuts for the options.</p>",
|
||||||
|
"ja": "<p>メインメニューに「編集」セクションが追加されました。本セクションには、切り取り/貼り付けや、変更操作を戻す/やり直しの様な使い慣れたオプションが含まれています。</p>" +
|
||||||
|
"<p>本メニューには、オプションのためのキーボードショートカットも表示されるようになりました。</p>"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: { "en-US": "Arranging nodes" },
|
title: {
|
||||||
|
"en-US": "Arranging nodes",
|
||||||
|
"ja": "ノードの配置"
|
||||||
|
},
|
||||||
prepare() {
|
prepare() {
|
||||||
$("#red-ui-header-button-sidemenu").trigger("click");
|
$("#red-ui-header-button-sidemenu").trigger("click");
|
||||||
$("#menu-item-arrange-menu").parent().addClass("open")
|
$("#menu-item-arrange-menu").parent().addClass("open");
|
||||||
},
|
},
|
||||||
complete() {
|
complete() {
|
||||||
$("#menu-item-arrange-menu").parent().removeClass("open")
|
$("#menu-item-arrange-menu").parent().removeClass("open");
|
||||||
},
|
},
|
||||||
element: "#menu-item-arrange-menu-submenu",
|
element: "#menu-item-arrange-menu-submenu",
|
||||||
interactive: false,
|
interactive: false,
|
||||||
direction: "left",
|
direction: "left",
|
||||||
description: { "en-US": "<p>The new 'Arrange' section of the menu provides new options to help arrange your nodes. You can align them to a common edge, spread them out evenly or change their order.</p>" },
|
description: {
|
||||||
|
"en-US": "<p>The new 'Arrange' section of the menu provides new options to help arrange your nodes. You can align them to a common edge, spread them out evenly or change their order.</p>",
|
||||||
|
"ja": "<p>メニューの新しい「配置」セクションには、ノードの配置を助ける新しいオプションが提供されています。ノードの端を揃えたり、均等に配置したり、表示順序を変更したりできます。</p>"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: { "en-US": "Hiding tabs" },
|
title: {
|
||||||
|
"en-US": "Hiding tabs",
|
||||||
|
"ja": "タブの非表示"
|
||||||
|
},
|
||||||
element: "#red-ui-workspace-tabs > li.active",
|
element: "#red-ui-workspace-tabs > li.active",
|
||||||
description: { "en-US": '<p>Tabs can now be hidden by clicking their <i class="fa fa-times"></i> icon.</p><p>The Info Sidebar will still list all of your tabs, and tell you which ones are currently hidden.' },
|
description: {
|
||||||
|
"en-US": '<p>Tabs can now be hidden by clicking their <i class="fa fa-times"></i> icon.</p><p>The Info Sidebar will still list all of your tabs, and tell you which ones are currently hidden.',
|
||||||
|
"ja": '<p><i class="fa fa-times"></i> アイコンをクリックすることで、タブを非表示にできます。</p><p>情報サイドバーには、全てのタブが一覧表示されており、現在非表示になっているタブを確認できます。'
|
||||||
|
},
|
||||||
interactive: false,
|
interactive: false,
|
||||||
prepare() {
|
prepare() {
|
||||||
$("#red-ui-workspace-tabs > li.active .red-ui-tab-close").css("display","block");
|
$("#red-ui-workspace-tabs > li.active .red-ui-tab-close").css("display","block");
|
||||||
@@ -54,9 +85,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: { "en-US": "Tab menu" },
|
title: {
|
||||||
|
"en-US": "Tab menu",
|
||||||
|
"ja": "タブメニュー"
|
||||||
|
},
|
||||||
element: "#red-ui-workspace-tabs-menu",
|
element: "#red-ui-workspace-tabs-menu",
|
||||||
description: { "en-US": '<p>The new tab menu also provides lots of new options for your tabs.</p>' },
|
description: {
|
||||||
|
"en-US": "<p>The new tab menu also provides lots of new options for your tabs.</p>",
|
||||||
|
"ja": "<p>新しいタブメニューには、タブに関する沢山の新しいオプションが提供されています。</p>"
|
||||||
|
},
|
||||||
interactive: false,
|
interactive: false,
|
||||||
direction: "left",
|
direction: "left",
|
||||||
prepare() {
|
prepare() {
|
||||||
@@ -67,10 +104,16 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: { "en-US": "Flow and Group level environment variables" },
|
title: {
|
||||||
|
"en-US": "Flow and Group level environment variables",
|
||||||
|
"ja": "フローとグループの環境変数"
|
||||||
|
},
|
||||||
element: "#red-ui-workspace-tabs > li.active",
|
element: "#red-ui-workspace-tabs > li.active",
|
||||||
interactive: false,
|
interactive: false,
|
||||||
description: { "en-US": "<p>Flows and Groups can now have their own environment variables that can be referenced by nodes inside them.</p>" },
|
description: {
|
||||||
|
"en-US": "<p>Flows and Groups can now have their own environment variables that can be referenced by nodes inside them.</p>",
|
||||||
|
"ja": "<p>フローとグループには、内部のノードから参照できる環境変数を設定できるようになりました。</p>"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prepare(done) {
|
prepare(done) {
|
||||||
@@ -78,44 +121,86 @@ export default {
|
|||||||
setTimeout(done,700);
|
setTimeout(done,700);
|
||||||
},
|
},
|
||||||
element: "#red-ui-tab-editor-tab-envProperties-link-button",
|
element: "#red-ui-tab-editor-tab-envProperties-link-button",
|
||||||
description: { "en-US": "<p>Their edit dialogs have a new Environment Variables section.</p>" },
|
description: {
|
||||||
|
"en-US": "<p>Their edit dialogs have a new Environment Variables section.</p>",
|
||||||
|
"ja": "<p>編集ダイアログに環境変数セクションが追加されました。</p>"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
element: ".node-input-env-container-row",
|
element: ".node-input-env-container-row",
|
||||||
direction: "left",
|
direction: "left",
|
||||||
description: { "en-US": '<p>The environment variables are listed in this table and new ones can be added by clicking the <i class="fa fa-plus"></i> button.</p>' },
|
description: {
|
||||||
|
"en-US": '<p>The environment variables are listed in this table and new ones can be added by clicking the <i class="fa fa-plus"></i> button.</p>',
|
||||||
|
"ja": '<p>この表に環境変数が一覧表示されており、<i class="fa fa-plus"></i>ボタンをクリックすることで新しい変数を追加できます。</p>'
|
||||||
|
},
|
||||||
complete(done) {
|
complete(done) {
|
||||||
$("#node-dialog-cancel").trigger("click");
|
$("#node-dialog-cancel").trigger("click");
|
||||||
setTimeout(done,500);
|
setTimeout(done,500);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: {"en-US":"Link Call node added"},
|
title: {
|
||||||
|
"en-US": "Link Call node added",
|
||||||
|
"ja": "Link Callノードを追加"
|
||||||
|
},
|
||||||
prepare(done) {
|
prepare(done) {
|
||||||
|
this.paletteWasClosed = $("#red-ui-main-container").hasClass("red-ui-palette-closed");
|
||||||
|
RED.actions.invoke("core:toggle-palette",true)
|
||||||
$('[data-palette-type="link call"]')[0].scrollIntoView({block:"center"})
|
$('[data-palette-type="link call"]')[0].scrollIntoView({block:"center"})
|
||||||
setTimeout(done,100);
|
setTimeout(done,100);
|
||||||
},
|
},
|
||||||
element: '[data-palette-type="link call"]',
|
element: '[data-palette-type="link call"]',
|
||||||
direction: "right",
|
direction: "right",
|
||||||
description: { "en-US": '<p>The <code>Link Call</code> node lets you call another flow that begins with a <code>Link In</code> node and get the result back when the message reaches a <code>Link Out</code> node.</p>' },
|
description: {
|
||||||
|
"en-US": "<p>The <code>Link Call</code> node lets you call another flow that begins with a <code>Link In</code> node and get the result back when the message reaches a <code>Link Out</code> node.</p>",
|
||||||
|
"ja": "<p><code>Link Call</code>ノードを用いることで、<code>Link In</code>ノードから始まるフローを呼び出し、<code>Link Out</code>ノードに到達した時に、結果を取得できます。</p>"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: {"en-US":"File nodes renamed"},
|
title: {
|
||||||
|
"en-US": "MQTT nodes support dynamic connections",
|
||||||
|
"ja": "MQTTノードが動的接続をサポート"
|
||||||
|
},
|
||||||
prepare(done) {
|
prepare(done) {
|
||||||
$('[data-palette-type="file"]')[0].scrollIntoView({block:"center"})
|
$('[data-palette-type="mqtt out"]')[0].scrollIntoView({block:"center"})
|
||||||
setTimeout(done,100);
|
setTimeout(done,100);
|
||||||
},
|
},
|
||||||
|
element: '[data-palette-type="mqtt out"]',
|
||||||
|
direction: "right",
|
||||||
|
description: {
|
||||||
|
"en-US": '<p>The <code>MQTT</code> nodes now support creating their connections and subscriptions dynamically.</p>',
|
||||||
|
"ja": '<p><code>MQTT</code>ノードは、動的な接続や購読ができるようになりました。</p>'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: {
|
||||||
|
"en-US": "File nodes renamed",
|
||||||
|
"ja": "ファイルノードの名前変更"
|
||||||
|
},
|
||||||
|
prepare(done) {
|
||||||
|
$('[data-palette-type="file"]')[0].scrollIntoView({block:"center"});
|
||||||
|
setTimeout(done,100);
|
||||||
|
},
|
||||||
|
complete() {
|
||||||
|
if (this.paletteWasClosed) {
|
||||||
|
RED.actions.invoke("core:toggle-palette",false)
|
||||||
|
}
|
||||||
|
},
|
||||||
element: '[data-palette-type="file"]',
|
element: '[data-palette-type="file"]',
|
||||||
direction: "right",
|
direction: "right",
|
||||||
description: { "en-US": '<p>The file nodes have been renamed to make it clearer which node does what.</p>' },
|
description: {
|
||||||
|
"en-US": "<p>The file nodes have been renamed to make it clearer which node does what.</p>",
|
||||||
|
"ja": "<p>fileノードの名前が変更され、どのノードが何を行うかが明確になりました。</p>"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: {"en-US":"Deep copy option on Change node"},
|
title: {
|
||||||
|
"en-US": "Deep copy option on Change node",
|
||||||
|
"ja": "Changeノードのディープコピーオプション"
|
||||||
|
},
|
||||||
prepare(done) {
|
prepare(done) {
|
||||||
var def = RED.nodes.getType('change')
|
var def = RED.nodes.getType('change');
|
||||||
RED.editor.edit({id:"test",type:"change",rules:[{t:'set',p:'payload',pt:'msg', tot:'msg',to:"anotherProperty"}],_def:def, _:def._})
|
RED.editor.edit({id:"test",type:"change",rules:[{t:"set",p:"payload",pt:"msg", tot:"msg",to:"anotherProperty"}],_def:def, _:def._});
|
||||||
setTimeout(done,700);
|
setTimeout(done,700);
|
||||||
},
|
},
|
||||||
complete(done) {
|
complete(done) {
|
||||||
@@ -123,13 +208,22 @@ export default {
|
|||||||
setTimeout(done,500);
|
setTimeout(done,500);
|
||||||
},
|
},
|
||||||
element: function() {
|
element: function() {
|
||||||
return $(".node-input-rule-property-deepCopy").next()
|
return $(".node-input-rule-property-deepCopy").next();
|
||||||
},
|
},
|
||||||
description: { "en-US": '<p>The Set rule has a new option to create a deep copy of the value. This ensures a complete copy is made, rather than using a reference.</p>' },
|
description: {
|
||||||
|
"en-US": "<p>The Set rule has a new option to create a deep copy of the value. This ensures a complete copy is made, rather than using a reference.</p>",
|
||||||
|
"ja": "<p>値を代入に、値のディープコピーを作成するオプションが追加されました。これによって参照ではなく、完全なコピーが作成されます。</p>"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: { "en-US": "And that's not all..." },
|
title: {
|
||||||
description: { "en-US": "<p>There are many more smaller changes, including:</p><ul><li>Auto-complete suggestions in the <code>msg</code> TypedInput.</li><li>Support for <code>msg.resetTimeout</code> in the <code>Join</code> node.</li><li>Pushing messages to the front of the queue in the <code>Delay</code> node's rate limiting mode.</li><li>An optional second output on the <code>Delay</code> node for rate limited messages.</li></ul>" }
|
"en-US": "And that's not all...",
|
||||||
|
"ja": "これが全てではありません..."
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
"en-US": "<p>There are many more smaller changes, including:</p><ul><li>Auto-complete suggestions in the <code>msg</code> TypedInput.</li><li>Support for <code>msg.resetTimeout</code> in the <code>Join</code> node.</li><li>Pushing messages to the front of the queue in the <code>Delay</code> node's rate limiting mode.</li><li>An optional second output on the <code>Delay</code> node for rate limited messages.</li></ul>",
|
||||||
|
"ja": "<p>以下の様な小さな変更が沢山あります:</p><ul><li><code>msg</code> TypedInputの自動補完提案</li><li><code>Join</code>ノードで<code>msg.resetTimeout</code>のサポート</li><li><code>Delay</code>ノードの流量制御モードにおいて先頭メッセージをキューに追加</li><li><code>Delay</code>ノードで流量制限されたメッセージ向けの任意の2つ目の出力</li></ul>"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="mobile-web-app-capable" content="yes">
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<!--
|
<!--
|
||||||
Copyright JS Foundation and other contributors, http://js.foundation
|
Copyright OpenJS Foundation and other contributors, https://openjsf.org/
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -24,24 +24,24 @@
|
|||||||
<title>{{ page.title }}</title>
|
<title>{{ page.title }}</title>
|
||||||
<link rel="icon" type="image/png" href="{{ page.favicon }}">
|
<link rel="icon" type="image/png" href="{{ page.favicon }}">
|
||||||
<link rel="mask-icon" href="{{ page.tabicon.icon }}" color="{{ page.tabicon.colour }}">
|
<link rel="mask-icon" href="{{ page.tabicon.icon }}" color="{{ page.tabicon.colour }}">
|
||||||
<link rel="stylesheet" href="vendor/jquery/css/base/jquery-ui.min.css">
|
<link rel="stylesheet" href="vendor/jquery/css/base/jquery-ui.min.css?v={{ page.version }}">
|
||||||
<link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css">
|
<link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css?v={{ page.version }}">
|
||||||
<link rel="stylesheet" href="red/style.min.css">
|
<link rel="stylesheet" href="red/style.min.css?v={{ page.version }}">
|
||||||
{{#page.css}}
|
{{#page.css}}
|
||||||
<link rel="stylesheet" href="{{.}}">
|
<link rel="stylesheet" href="{{.}}">
|
||||||
{{/page.css}}
|
{{/page.css}}
|
||||||
{{#asset.vendorMonaco}}
|
{{#asset.vendorMonaco}}
|
||||||
<link rel="stylesheet" href="vendor/monaco/style.css">
|
<link rel="stylesheet" href="vendor/monaco/style.css?v={{ page.version }}">
|
||||||
{{/asset.vendorMonaco}}
|
{{/asset.vendorMonaco}}
|
||||||
</head>
|
</head>
|
||||||
<body spellcheck="false">
|
<body spellcheck="false">
|
||||||
<div id="red-ui-editor"></div>
|
<div id="red-ui-editor"></div>
|
||||||
<script src="vendor/vendor.js"></script>
|
<script src="vendor/vendor.js?v={{ page.version }}"></script>
|
||||||
{{#asset.vendorMonaco}}
|
{{#asset.vendorMonaco}}
|
||||||
<script src="{{ asset.vendorMonaco }}"></script>
|
<script src="{{ asset.vendorMonaco }}?v={{ page.version }}"></script>
|
||||||
{{/asset.vendorMonaco}}
|
{{/asset.vendorMonaco}}
|
||||||
<script src="{{ asset.red }}"></script>
|
<script src="{{ asset.red }}?v={{ page.version }}"></script>
|
||||||
<script src="{{ asset.main }}"></script>
|
<script src="{{ asset.main }}?v={{ page.version }}"></script>
|
||||||
{{# page.scripts }}
|
{{# page.scripts }}
|
||||||
<script src="{{.}}"></script>
|
<script src="{{.}}"></script>
|
||||||
{{/ page.scripts }}
|
{{/ page.scripts }}
|
||||||
|
@@ -143,7 +143,8 @@
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
.inject-time-count {
|
.inject-time-count {
|
||||||
width: 40px !important;
|
padding-left: 3px !important;
|
||||||
|
width: 80px !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@@ -352,14 +353,16 @@
|
|||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
var node = this;
|
var node = this;
|
||||||
|
var payloadType = node.payloadType;
|
||||||
|
|
||||||
if (node.payloadType == null) {
|
if (node.payloadType == null) {
|
||||||
if (node.payload == "") {
|
if (node.payload == "") {
|
||||||
node.payloadType = "date";
|
payloadType = "date";
|
||||||
} else {
|
} else {
|
||||||
node.payloadType = "str";
|
payloadType = "str";
|
||||||
}
|
}
|
||||||
} else if (node.payloadType === 'string' || node.payloadType === 'none') {
|
} else if (node.payloadType === 'string' || node.payloadType === 'none') {
|
||||||
node.payloadType = "str";
|
payloadType = "str";
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#inject-time-type-select").on("change", function() {
|
$("#inject-time-type-select").on("change", function() {
|
||||||
@@ -538,12 +541,10 @@
|
|||||||
var propertyValue = $('<input/>',{class:"node-input-prop-property-value",type:"text"})
|
var propertyValue = $('<input/>',{class:"node-input-prop-property-value",type:"text"})
|
||||||
.css("width","calc(70% - 30px)")
|
.css("width","calc(70% - 30px)")
|
||||||
.appendTo(row)
|
.appendTo(row)
|
||||||
.typedInput({default:'str',types:['flow','global','str','num','bool','json','bin','date','jsonata','env','msg']});
|
.typedInput({default:prop.vt || 'str',types:['flow','global','str','num','bool','json','bin','date','jsonata','env','msg']});
|
||||||
|
|
||||||
propertyName.typedInput('value',prop.p);
|
propertyName.typedInput('value',prop.p);
|
||||||
|
|
||||||
propertyValue.typedInput('value',prop.v);
|
propertyValue.typedInput('value',prop.v);
|
||||||
propertyValue.typedInput('type',prop.vt);
|
|
||||||
},
|
},
|
||||||
removable: true,
|
removable: true,
|
||||||
sortable: true
|
sortable: true
|
||||||
@@ -558,12 +559,12 @@
|
|||||||
var payload = {
|
var payload = {
|
||||||
p:'payload',
|
p:'payload',
|
||||||
v: node.payload ? node.payload : '',
|
v: node.payload ? node.payload : '',
|
||||||
vt:node.payloadType ? node.payloadType : 'date'
|
vt:payloadType ? payloadType : 'date'
|
||||||
};
|
};
|
||||||
var topic = {
|
var topic = {
|
||||||
p:'topic',
|
p:'topic',
|
||||||
v: node.topic ? node.topic : '',
|
v: node.topic ? node.topic : '',
|
||||||
vt:'string'
|
vt:'str'
|
||||||
}
|
}
|
||||||
node.props = [payload,topic];
|
node.props = [payload,topic];
|
||||||
}
|
}
|
||||||
@@ -574,11 +575,16 @@
|
|||||||
if (newProp.v === undefined) {
|
if (newProp.v === undefined) {
|
||||||
if (prop.p === 'payload') {
|
if (prop.p === 'payload') {
|
||||||
newProp.v = node.payload ? node.payload : '';
|
newProp.v = node.payload ? node.payload : '';
|
||||||
newProp.vt = node.payloadType ? node.payloadType : 'date';
|
newProp.vt = payloadType ? payloadType : 'date';
|
||||||
} else if (prop.p === 'topic' && prop.vt === "str") {
|
} else if (prop.p === 'topic' && prop.vt === "str") {
|
||||||
newProp.v = node.topic ? node.topic : '';
|
newProp.v = node.topic ? node.topic : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (newProp.vt === "string") {
|
||||||
|
// Fix bug in pre 2.1 where an old Inject node might have
|
||||||
|
// a migrated rule with type 'string' not 'str'
|
||||||
|
newProp.vt = "str";
|
||||||
|
}
|
||||||
eList.editableList('addItem',newProp);
|
eList.editableList('addItem',newProp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -292,6 +292,7 @@
|
|||||||
};
|
};
|
||||||
RED.events.on("project:change", this.clearMessageList);
|
RED.events.on("project:change", this.clearMessageList);
|
||||||
RED.actions.add("core:clear-debug-messages", function() { RED.debug.clearMessageList(true) });
|
RED.actions.add("core:clear-debug-messages", function() { RED.debug.clearMessageList(true) });
|
||||||
|
RED.actions.add("core:clear-filtered-debug-messages", function() { RED.debug.clearMessageList(true, true) });
|
||||||
|
|
||||||
RED.actions.add("core:activate-selected-debug-nodes", function() { setDebugNodeState(getSelectedDebugNodes(true), true); });
|
RED.actions.add("core:activate-selected-debug-nodes", function() { setDebugNodeState(getSelectedDebugNodes(true), true); });
|
||||||
RED.actions.add("core:activate-all-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(true, true),true); });
|
RED.actions.add("core:activate-all-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(true, true),true); });
|
||||||
|
@@ -280,6 +280,18 @@ module.exports = function(RED) {
|
|||||||
root: path.join(__dirname,"lib","debug"),
|
root: path.join(__dirname,"lib","debug"),
|
||||||
dotfiles: 'deny'
|
dotfiles: 'deny'
|
||||||
};
|
};
|
||||||
res.sendFile(req.params[0], options);
|
try {
|
||||||
|
res.sendFile(
|
||||||
|
req.params[0],
|
||||||
|
options,
|
||||||
|
err => {
|
||||||
|
if (err) {
|
||||||
|
res.sendStatus(404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch(err) {
|
||||||
|
res.sendStatus(404);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@@ -52,7 +52,7 @@
|
|||||||
treeList = $("<div>")
|
treeList = $("<div>")
|
||||||
.css({width: "100%", height: "100%"})
|
.css({width: "100%", height: "100%"})
|
||||||
.appendTo(".node-input-link-row")
|
.appendTo(".node-input-link-row")
|
||||||
.treeList({})
|
.treeList({autoSelect:false})
|
||||||
.on('treelistitemmouseover',function(e,item) {
|
.on('treelistitemmouseover',function(e,item) {
|
||||||
if (item.node) {
|
if (item.node) {
|
||||||
item.node.highlighted = true;
|
item.node.highlighted = true;
|
||||||
@@ -68,6 +68,8 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
var candidateNodes = RED.nodes.filterNodes({type:targetType});
|
var candidateNodes = RED.nodes.filterNodes({type:targetType});
|
||||||
|
var candidateNodesCount = 0;
|
||||||
|
|
||||||
var search = $("#node-input-link-target-filter").searchBox({
|
var search = $("#node-input-link-target-filter").searchBox({
|
||||||
style: "compact",
|
style: "compact",
|
||||||
delay: 300,
|
delay: 300,
|
||||||
@@ -80,7 +82,7 @@
|
|||||||
var count = treeList.treeList("filter", function(item) {
|
var count = treeList.treeList("filter", function(item) {
|
||||||
return item.label.toLowerCase().indexOf(val) > -1 || (item.node && item.node.type.toLowerCase().indexOf(val) > -1)
|
return item.label.toLowerCase().indexOf(val) > -1 || (item.node && item.node.type.toLowerCase().indexOf(val) > -1)
|
||||||
});
|
});
|
||||||
search.searchBox("count",count+" / "+candidateNodes.length);
|
search.searchBox("count",count+" / "+candidateNodesCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -113,6 +115,11 @@
|
|||||||
|
|
||||||
candidateNodes.forEach(function(n) {
|
candidateNodes.forEach(function(n) {
|
||||||
if (flowMap[n.z]) {
|
if (flowMap[n.z]) {
|
||||||
|
if (targetType === "link out" && n.mode === 'return') {
|
||||||
|
// Link In nodes looking for Link Out nodes should not
|
||||||
|
// include return-mode nodes.
|
||||||
|
return
|
||||||
|
}
|
||||||
var isChecked = false;
|
var isChecked = false;
|
||||||
isChecked = (node.links.indexOf(n.id) !== -1) || (n.links||[]).indexOf(node.id) !== -1;
|
isChecked = (node.links.indexOf(n.id) !== -1) || (n.links||[]).indexOf(node.id) !== -1;
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
@@ -126,6 +133,7 @@
|
|||||||
checkbox: node.type !== "link call",
|
checkbox: node.type !== "link call",
|
||||||
radio: node.type === "link call"
|
radio: node.type === "link call"
|
||||||
})
|
})
|
||||||
|
candidateNodesCount++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
flows = flows.filter(function(f) { return f.children.length > 0 })
|
flows = flows.filter(function(f) { return f.children.length > 0 })
|
||||||
@@ -149,7 +157,7 @@
|
|||||||
function onEditSave(node) {
|
function onEditSave(node) {
|
||||||
var flows = treeList.treeList('data');
|
var flows = treeList.treeList('data');
|
||||||
node.links = [];
|
node.links = [];
|
||||||
if (node.type !== "link out" || $("node-input-mode").val() === 'link') {
|
if (node.type !== "link out" || $("#node-input-mode").val() === 'link') {
|
||||||
flows.forEach(function(f) {
|
flows.forEach(function(f) {
|
||||||
f.children.forEach(function(n) {
|
f.children.forEach(function(n) {
|
||||||
if (n.selected) {
|
if (n.selected) {
|
||||||
@@ -234,6 +242,12 @@
|
|||||||
},
|
},
|
||||||
oneditsave: function() {
|
oneditsave: function() {
|
||||||
onEditSave(this);
|
onEditSave(this);
|
||||||
|
// In case the name has changed, ensure any link call nodes on this
|
||||||
|
// tab are redrawn with the updated name
|
||||||
|
var localCallNodes = RED.nodes.filterNodes({z:RED.workspaces.active(), type:"link call"});
|
||||||
|
localCallNodes.forEach(function(node) {
|
||||||
|
node.dirty = true;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
onadd: onAdd,
|
onadd: onAdd,
|
||||||
oneditresize: resizeNodeList
|
oneditresize: resizeNodeList
|
||||||
@@ -259,12 +273,12 @@
|
|||||||
}
|
}
|
||||||
if (this.links.length > 0) {
|
if (this.links.length > 0) {
|
||||||
var targetNode = RED.nodes.node(this.links[0]);
|
var targetNode = RED.nodes.node(this.links[0]);
|
||||||
return targetNode && (targetNode.name || targetNode.id);
|
return targetNode && (targetNode.name || this._("link.linkCall"));
|
||||||
}
|
}
|
||||||
return this._("link.linkCall");
|
return this._("inject.none");
|
||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
return (this.name || this.links.length > 0)?"node_label_italic":"";
|
return this.name?"node_label_italic":"";
|
||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
onEditPrepare(this,"link in");
|
onEditPrepare(this,"link in");
|
||||||
@@ -275,7 +289,6 @@
|
|||||||
oneditresize: resizeNodeList
|
oneditresize: resizeNodeList
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
RED.nodes.registerType('link out',{
|
RED.nodes.registerType('link out',{
|
||||||
category: 'common',
|
category: 'common',
|
||||||
color:"#ddd",//"#87D8CF",
|
color:"#ddd",//"#87D8CF",
|
||||||
|
@@ -31,24 +31,22 @@ RED.debug = (function() {
|
|||||||
var activeWorkspace;
|
var activeWorkspace;
|
||||||
var numMessages = 100; // Hardcoded number of message to show in debug window scrollback
|
var numMessages = 100; // Hardcoded number of message to show in debug window scrollback
|
||||||
|
|
||||||
var filterVisible = false;
|
var debugNodeTreeList;
|
||||||
|
|
||||||
var debugNodeList;
|
|
||||||
var debugNodeListExpandedFlows = {};
|
|
||||||
|
|
||||||
function init(_config) {
|
function init(_config) {
|
||||||
config = _config;
|
config = _config;
|
||||||
|
|
||||||
var content = $("<div>").css({"position":"relative","height":"100%"});
|
var content = $("<div>").css({"position":"relative","height":"100%"});
|
||||||
var toolbar = $('<div class="red-ui-sidebar-header">'+
|
var toolbar = $('<div class="red-ui-sidebar-header">'+
|
||||||
'<span class="button-group"><a id="red-ui-sidebar-debug-filter" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span></a></span>'+
|
'<span class="button-group">'+
|
||||||
'<span class="button-group"><a id="red-ui-sidebar-debug-clear" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-trash"></i></a></span></div>').appendTo(content);
|
'<a id="red-ui-sidebar-debug-filter" style="padding-right: 5px" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span> <i style="padding-left: 5px;" class="fa fa-caret-down"></i></a>'+
|
||||||
|
'</span>'+
|
||||||
|
'<span class="button-group">'+
|
||||||
|
'<a id="red-ui-sidebar-debug-clear" style="border-right: none; padding-right: 6px" class="red-ui-sidebar-header-button" href="#" data-clear-type="all"><i class="fa fa-trash"></i> <span>all</span></a>' +
|
||||||
|
'<a id="red-ui-sidebar-debug-clear-opts" style="padding: 5px; border-left: none;" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-caret-down"></i></a>'+
|
||||||
|
'</span></div>').appendTo(content);
|
||||||
|
|
||||||
var footerToolbar = $('<div>'+
|
var footerToolbar = $('<div>'+
|
||||||
// '<span class="button-group">'+
|
|
||||||
// '<a class="red-ui-footer-button-toggle text-button selected" id="red-ui-sidebar-debug-view-list" href="#"><span data-i18n="">list</span></a>'+
|
|
||||||
// '<a class="red-ui-footer-button-toggle text-button" id="red-ui-sidebar-debug-view-table" href="#"><span data-i18n="">table</span></a> '+
|
|
||||||
// '</span>'+
|
|
||||||
'<span class="button-group"><a id="red-ui-sidebar-debug-open" class="red-ui-footer-button" href="#"><i class="fa fa-desktop"></i></a></span> ' +
|
'<span class="button-group"><a id="red-ui-sidebar-debug-open" class="red-ui-footer-button" href="#"><i class="fa fa-desktop"></i></a></span> ' +
|
||||||
'</div>');
|
'</div>');
|
||||||
|
|
||||||
@@ -56,85 +54,100 @@ RED.debug = (function() {
|
|||||||
sbc = messageList[0];
|
sbc = messageList[0];
|
||||||
messageTable = $('<div class="red-ui-debug-content red-ui-debug-content-table hide"/>').appendTo(content);
|
messageTable = $('<div class="red-ui-debug-content red-ui-debug-content-table hide"/>').appendTo(content);
|
||||||
|
|
||||||
var filterDialog = $('<div class="red-ui-debug-filter-box hide">'+
|
var filterDialogCloseTimeout;
|
||||||
'<div class="red-ui-debug-filter-row">'+
|
var filterDialogShown = false;
|
||||||
'<span class="button-group">'+
|
var filterDialog = $('<div class="red-ui-debug-filter-box hide"></div>').appendTo(toolbar);//content);
|
||||||
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option selected" id="red-ui-sidebar-debug-filterAll" href="#"><span data-i18n="node-red:debug.sidebar.filterAll"></span></a>'+
|
filterDialog.on('mouseleave' ,function(evt) {
|
||||||
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterSelected" href="#"><span data-i18n="node-red:debug.sidebar.filterSelected"></span></a>'+
|
if (filterDialogShown) {
|
||||||
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterCurrent" href="#"><span data-i18n="node-red:debug.sidebar.filterCurrent"></span></a> '+
|
filterDialogCloseTimeout = setTimeout(function() {
|
||||||
|
filterDialog.slideUp(200);
|
||||||
|
filterDialogShown = false;
|
||||||
|
},500)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
filterDialog.on('mouseenter' ,function(evt) {
|
||||||
|
clearTimeout(filterDialogCloseTimeout)
|
||||||
|
})
|
||||||
|
var filterToolbar = $('<div style="margin-bottom: 3px; display: flex;">'+
|
||||||
|
'<span style="flex-grow:1; text-align: left;">'+
|
||||||
|
'<span class="button-group"><button type="button" id="red-ui-sidebar-filter-select-all" class="red-ui-sidebar-header-button red-ui-button-small" data-i18n="node-red:debug.sidebar.selectAll"></button></span>' +
|
||||||
|
'<span class="button-group"><button type="button" id="red-ui-sidebar-filter-select-none" class="red-ui-sidebar-header-button red-ui-button-small" data-i18n="node-red:debug.sidebar.selectNone"></button></span>' +
|
||||||
'</span>'+
|
'</span>'+
|
||||||
'</div>'+
|
'<span class="button-group"><button type="button" id="red-ui-sidebar-filter-select-close" class="red-ui-sidebar-header-button red-ui-button-small"><i class="fa fa-times"></i></button></span>'+
|
||||||
'</div>').appendTo(toolbar);//content);
|
'</div>').appendTo(filterDialog);
|
||||||
|
|
||||||
// var filterTypeRow = $('<div class="red-ui-debug-filter-row"></div>').appendTo(filterDialog);
|
filterToolbar.find("#red-ui-sidebar-filter-select-close").on('click', function(evt) {
|
||||||
// $('<select><option>Show all debug nodes</option><option>Show selected debug nodes</option><option>Show current flow only</option></select>').appendTo(filterTypeRow);
|
clearTimeout(filterDialogCloseTimeout)
|
||||||
|
filterDialogShown = false;
|
||||||
|
filterDialog.slideUp(200);
|
||||||
|
})
|
||||||
|
|
||||||
var debugNodeListRow = $('<div class="red-ui-debug-filter-row hide" id="red-ui-sidebar-debug-filter-node-list-row"></div>').appendTo(filterDialog);
|
filterToolbar.find("#red-ui-sidebar-filter-select-all").on('click', function(evt) {
|
||||||
var flowCheckboxes = {};
|
evt.preventDefault();
|
||||||
var debugNodeListHeader = $('<div><span data-i18n="node-red:debug.sidebar.debugNodes"></span><span></span></div>');
|
var data = debugNodeTreeList.treeList('data');
|
||||||
var headerCheckbox = $('<input type="checkbox">').appendTo(debugNodeListHeader.find("span")[1]).checkboxSet();
|
data.forEach(function(flow) {
|
||||||
|
if (!flow.selected) {
|
||||||
debugNodeList = $('<ol>',{style:"text-align: left; min-height: 250px; max-height: 250px"}).appendTo(debugNodeListRow).editableList({
|
if (flow.treeList.checkbox) {
|
||||||
header: debugNodeListHeader,
|
flow.treeList.checkbox.trigger('click')
|
||||||
class: 'red-ui-nodeList',
|
|
||||||
addItem: function(container,i,node) {
|
|
||||||
var row = $("<div>").appendTo(container);
|
|
||||||
row.attr('id','debug-filter-node-list-node-'+node.id.replace(/\./g,"_"));
|
|
||||||
if (node.type === 'tab') {
|
|
||||||
container.parent().addClass('red-ui-editableList-section-header');
|
|
||||||
if (!debugNodeListExpandedFlows.hasOwnProperty(node.id)) {
|
|
||||||
debugNodeListExpandedFlows[node.id] = true;
|
|
||||||
}
|
}
|
||||||
var chevron = $('<i class="fa fa-angle-right"></i>').appendTo(row);
|
|
||||||
$('<span>').text(RED.utils.getNodeLabel(node,node.id)).appendTo(row);
|
|
||||||
var muteControl = $('<input type="checkbox">').appendTo($('<span class="meta">').appendTo(row));
|
|
||||||
muteControl.checkboxSet({
|
|
||||||
parent: headerCheckbox
|
|
||||||
});
|
|
||||||
flowCheckboxes[node.id] = muteControl;
|
|
||||||
row.on("click", function(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
debugNodeListExpandedFlows[node.id] = !debugNodeListExpandedFlows[node.id];
|
|
||||||
row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]);
|
|
||||||
debugNodeList.editableList('filter');
|
|
||||||
})
|
|
||||||
row.addClass("expandable");
|
|
||||||
if (node.disabled) {
|
|
||||||
container.addClass('disabled');
|
|
||||||
muteControl.checkboxSet('disable');
|
|
||||||
debugNodeListExpandedFlows[node.id] = false;
|
|
||||||
}
|
|
||||||
row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]);
|
|
||||||
} else {
|
} else {
|
||||||
$('<span>',{style: "margin-left: 20px"}).text(RED.utils.getNodeLabel(node,node.id)).appendTo(row);
|
flow.children.forEach(function(item) {
|
||||||
row.on("mouseenter",function() {
|
if (!item.selected) {
|
||||||
config.messageMouseEnter(node.id);
|
item.treeList.select();
|
||||||
});
|
}
|
||||||
row.on("mouseleave",function() {
|
})
|
||||||
config.messageMouseLeave(node.id);
|
}
|
||||||
});
|
});
|
||||||
var muteControl = $('<input type="checkbox">').prop('checked',!filteredNodes[node.id]).appendTo($('<span class="meta">').appendTo(row));
|
refreshMessageList();
|
||||||
muteControl.checkboxSet({
|
})
|
||||||
parent: flowCheckboxes[node.z]
|
|
||||||
}).on("change", function(e) {
|
filterToolbar.find("#red-ui-sidebar-filter-select-none").on('click', function(evt) {
|
||||||
filteredNodes[node.id] = !$(this).prop('checked');
|
evt.preventDefault();
|
||||||
$(".red-ui-debug-msg-node-"+node.id.replace(/\./g,"_")).toggleClass('hide',filteredNodes[node.id]);
|
debugNodeTreeList.treeList('clearSelection');
|
||||||
});
|
var data = debugNodeTreeList.treeList('data');
|
||||||
if ((node.hasOwnProperty("active") && !node.active) || RED.nodes.workspace(node.z).disabled) {
|
data.forEach(function(flow) {
|
||||||
container.addClass('disabled');
|
if (flow.children) {
|
||||||
muteControl.checkboxSet('disable');
|
flow.children.forEach(function(item) {
|
||||||
|
filteredNodes[item.node.id] = true;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
|
||||||
|
refreshMessageList();
|
||||||
|
})
|
||||||
|
var debugNodeListRow = $('<div class="red-ui-debug-filter-row" id="red-ui-sidebar-debug-filter-node-list-row"></div>').appendTo(filterDialog);
|
||||||
|
debugNodeTreeList = $("<div></div>").appendTo(debugNodeListRow).css({width: "100%", height: "300px"})
|
||||||
|
.treeList({autoSelect: false}).on("treelistitemmouseover", function(e, item) {
|
||||||
|
if (item.node) {
|
||||||
|
item.node.highlighted = true;
|
||||||
|
item.node.dirty = true;
|
||||||
|
RED.view.redraw();
|
||||||
|
}
|
||||||
|
}).on("treelistitemmouseout", function(e, item) {
|
||||||
|
if (item.node) {
|
||||||
|
item.node.highlighted = false;
|
||||||
|
item.node.dirty = true;
|
||||||
|
RED.view.redraw();
|
||||||
|
}
|
||||||
|
}).on("treelistselect", function(e, item) {
|
||||||
|
if (item.children) {
|
||||||
|
item.children.forEach(function(child) {
|
||||||
|
if (child.checkbox) {
|
||||||
|
child.treeList.select(item.selected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (item.node) {
|
||||||
|
if (item.selected) {
|
||||||
|
delete filteredNodes[item.node.id]
|
||||||
|
} else {
|
||||||
|
filteredNodes[item.node.id] = true;
|
||||||
|
}
|
||||||
|
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
|
||||||
|
refreshMessageList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
addButton: false,
|
|
||||||
scrollOnAdd: false,
|
|
||||||
filter: function(node) {
|
|
||||||
return (node.type === 'tab' || debugNodeListExpandedFlows[node.z] )
|
|
||||||
},
|
|
||||||
sort: function(A,B) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
content.i18n();
|
content.i18n();
|
||||||
@@ -144,85 +157,95 @@ RED.debug = (function() {
|
|||||||
|
|
||||||
toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll'));
|
toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll'));
|
||||||
|
|
||||||
var filterButtonHandler = function(type) {
|
|
||||||
return function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
if (filterType !== type) {
|
|
||||||
$('.red-ui-sidebar-debug-filter-option').removeClass('selected');
|
|
||||||
$(this).addClass('selected');
|
|
||||||
if (filterType === 'filterSelected') {
|
|
||||||
debugNodeListRow.slideUp();
|
|
||||||
}
|
|
||||||
filterType = type;
|
|
||||||
if (filterType === 'filterSelected') {
|
|
||||||
debugNodeListRow.slideDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType));
|
|
||||||
refreshMessageList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filterDialog.find('#red-ui-sidebar-debug-filterAll').on("click",filterButtonHandler('filterAll'));
|
|
||||||
filterDialog.find('#red-ui-sidebar-debug-filterSelected').on("click",filterButtonHandler('filterSelected'));
|
|
||||||
filterDialog.find('#red-ui-sidebar-debug-filterCurrent').on("click",filterButtonHandler('filterCurrent'));
|
|
||||||
|
|
||||||
|
|
||||||
// $('#red-ui-sidebar-debug-view-list').on("click",function(e) {
|
|
||||||
// e.preventDefault();
|
|
||||||
// if (!$(this).hasClass('selected')) {
|
|
||||||
// $(this).addClass('selected');
|
|
||||||
// $('#red-ui-sidebar-debug-view-table').removeClass('selected');
|
|
||||||
// showMessageList();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// $('#red-ui-sidebar-debug-view-table').on("click",function(e) {
|
|
||||||
// e.preventDefault();
|
|
||||||
// if (!$(this).hasClass('selected')) {
|
|
||||||
// $(this).addClass('selected');
|
|
||||||
// $('#red-ui-sidebar-debug-view-list').removeClass('selected');
|
|
||||||
// showMessageTable();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
var hideFilterTimeout;
|
|
||||||
toolbar.on('mouseleave',function() {
|
|
||||||
if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) {
|
|
||||||
clearTimeout(hideFilterTimeout);
|
|
||||||
hideFilterTimeout = setTimeout(function() {
|
|
||||||
filterVisible = false;
|
|
||||||
$('#red-ui-sidebar-debug-filter').removeClass('selected');
|
|
||||||
filterDialog.slideUp(200);
|
|
||||||
},300);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
toolbar.on('mouseenter',function() {
|
|
||||||
if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) {
|
|
||||||
clearTimeout(hideFilterTimeout);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
toolbar.find('#red-ui-sidebar-debug-filter').on("click",function(e) {
|
toolbar.find('#red-ui-sidebar-debug-filter').on("click",function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if ($(this).hasClass('selected')) {
|
var options = [
|
||||||
filterVisible = false;
|
{ label: $('<span data-i18n="[append]node-red:debug.sidebar.filterAll"><input type="radio" value="filterAll" name="filter-type" style="margin-top:0"> </span>').i18n() , value: "filterAll" },
|
||||||
$(this).removeClass('selected');
|
{ label: $('<span><span data-i18n="[append]node-red:debug.sidebar.filterSelected"><input type="radio" value="filterSelected" name="filter-type" style="margin-top:0"> </span>...</span>').i18n(), value: "filterSelected" },
|
||||||
clearTimeout(hideFilterTimeout);
|
{ label: $('<span data-i18n="[append]node-red:debug.sidebar.filterCurrent"><input type="radio" value="filterCurrent" name="filter-type" style="margin-top:0"> </span>').i18n(), value: "filterCurrent" }
|
||||||
filterDialog.slideUp(200);
|
]
|
||||||
} else {
|
var menu = RED.popover.menu({
|
||||||
$(this).addClass('selected');
|
options: options,
|
||||||
filterVisible = true;
|
onselect: function(item) {
|
||||||
refreshDebugNodeList();
|
if (item.value !== filterType) {
|
||||||
filterDialog.slideDown(200);
|
filterType = item.value;
|
||||||
}
|
$('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType));
|
||||||
|
refreshMessageList();
|
||||||
|
RED.settings.set("debug.filter",filterType)
|
||||||
|
}
|
||||||
|
if (filterType === 'filterSelected') {
|
||||||
|
refreshDebugNodeList();
|
||||||
|
filterDialog.slideDown(200);
|
||||||
|
filterDialogShown = true;
|
||||||
|
debugNodeTreeList.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.show({
|
||||||
|
target: $("#red-ui-sidebar-debug-filter"),
|
||||||
|
align: "left",
|
||||||
|
offset: [$("#red-ui-sidebar-debug-filter").outerWidth()-2, -1]
|
||||||
|
})
|
||||||
|
$('input[name="filter-type"][value="'+RED.settings.get("debug.filter","filterAll")+'"]').prop("checked", true)
|
||||||
});
|
});
|
||||||
RED.popover.tooltip(toolbar.find('#red-ui-sidebar-debug-filter'),RED._('node-red:debug.sidebar.filterLog'));
|
RED.popover.tooltip(toolbar.find('#red-ui-sidebar-debug-filter'),RED._('node-red:debug.sidebar.filterLog'));
|
||||||
|
|
||||||
toolbar.find("#red-ui-sidebar-debug-clear").on("click", function(e) {
|
toolbar.find("#red-ui-sidebar-debug-clear").on("click", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
clearMessageList(false);
|
var action = RED.settings.get("debug.clearType","all")
|
||||||
|
clearMessageList(false, action === 'filtered');
|
||||||
});
|
});
|
||||||
RED.popover.tooltip(toolbar.find("#red-ui-sidebar-debug-clear"),RED._('node-red:debug.sidebar.clearLog'),"core:clear-debug-messages");
|
var clearTooltip = RED.popover.tooltip(toolbar.find("#red-ui-sidebar-debug-clear"),RED._('node-red:debug.sidebar.clearLog'),"core:clear-debug-messages");
|
||||||
|
toolbar.find("#red-ui-sidebar-debug-clear-opts").on("click", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var options = [
|
||||||
|
{ label: $('<span data-i18n="[append]node-red:debug.sidebar.clearLog"><input type="radio" value="all" name="clear-type" style="margin-top:0"> </span>').i18n() , value: "all" },
|
||||||
|
{ label: $('<span data-i18n="[append]node-red:debug.sidebar.clearFilteredLog"><input type="radio" value="filtered" name="clear-type" style="margin-top:0"> </span>').i18n(), value: "filtered" }
|
||||||
|
]
|
||||||
|
var menu = RED.popover.menu({
|
||||||
|
options: options,
|
||||||
|
onselect: function(item) {
|
||||||
|
if (item.value === "all") {
|
||||||
|
$("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.all'));
|
||||||
|
clearTooltip.setAction("core:clear-debug-messages");
|
||||||
|
clearTooltip.setContent(RED._('node-red:debug.sidebar.clearLog'))
|
||||||
|
RED.settings.set("debug.clearType","all")
|
||||||
|
} else {
|
||||||
|
$("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.filtered'));
|
||||||
|
clearTooltip.setAction("core:clear-filtered-debug-messages");
|
||||||
|
clearTooltip.setContent(RED._('node-red:debug.sidebar.clearFilteredLog'))
|
||||||
|
RED.settings.set("debug.clearType","filtered")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.show({
|
||||||
|
target: $("#red-ui-sidebar-debug-clear-opts"),
|
||||||
|
align: "left",
|
||||||
|
offset: [$("#red-ui-sidebar-debug-clear-opts").outerWidth()-2, -1]
|
||||||
|
})
|
||||||
|
$('input[name="clear-type"][value="'+RED.settings.get("debug.clearType","all")+'"]').prop("checked", true)
|
||||||
|
})
|
||||||
|
|
||||||
|
var clearType = RED.settings.get("debug.clearType","all");
|
||||||
|
if (clearType === "all") {
|
||||||
|
toolbar.find("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.all'));
|
||||||
|
clearTooltip.setAction("core:clear-debug-messages");
|
||||||
|
clearTooltip.setContent(RED._('node-red:debug.sidebar.clearLog'))
|
||||||
|
} else {
|
||||||
|
toolbar.find("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.filtered'));
|
||||||
|
clearTooltip.setAction("core:clear-filtered-debug-messages");
|
||||||
|
clearTooltip.setContent(RED._('node-red:debug.sidebar.clearFilteredLog'))
|
||||||
|
}
|
||||||
|
|
||||||
|
filterType = RED.settings.get("debug.filter","filterAll")
|
||||||
|
var filteredNodeList = RED.settings.get("debug.filteredNodes",[]);
|
||||||
|
filteredNodes = {}
|
||||||
|
filteredNodeList.forEach(function(id) {
|
||||||
|
filteredNodes[id] = true
|
||||||
|
})
|
||||||
|
toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType));
|
||||||
|
refreshMessageList();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: content,
|
content: content,
|
||||||
@@ -254,8 +277,6 @@ RED.debug = (function() {
|
|||||||
|
|
||||||
|
|
||||||
function refreshDebugNodeList() {
|
function refreshDebugNodeList() {
|
||||||
debugNodeList.editableList('empty');
|
|
||||||
|
|
||||||
var workspaceOrder = RED.nodes.getWorkspaceOrder();
|
var workspaceOrder = RED.nodes.getWorkspaceOrder();
|
||||||
var workspaceOrderMap = {};
|
var workspaceOrderMap = {};
|
||||||
workspaceOrder.forEach(function(ws,i) {
|
workspaceOrder.forEach(function(ws,i) {
|
||||||
@@ -320,15 +341,45 @@ RED.debug = (function() {
|
|||||||
return labelA.localeCompare(labelB);
|
return labelA.localeCompare(labelB);
|
||||||
});
|
});
|
||||||
var currentWs = null;
|
var currentWs = null;
|
||||||
var nodeList = [];
|
var data = [];
|
||||||
|
var currentFlow;
|
||||||
|
var currentSelectedCount = 0;
|
||||||
candidateNodes.forEach(function(node) {
|
candidateNodes.forEach(function(node) {
|
||||||
if (currentWs !== node.z) {
|
if (currentWs !== node.z) {
|
||||||
|
if (currentFlow && currentFlow.checkbox) {
|
||||||
|
currentFlow.selected = currentSelectedCount === currentFlow.children.length
|
||||||
|
}
|
||||||
|
currentSelectedCount = 0;
|
||||||
currentWs = node.z;
|
currentWs = node.z;
|
||||||
nodeList.push(RED.nodes.workspace(node.z));
|
var parent = RED.nodes.workspace(currentWs) || RED.nodes.subflow(currentWs);
|
||||||
|
currentFlow = {
|
||||||
|
label: RED.utils.getNodeLabel(parent, currentWs),
|
||||||
|
}
|
||||||
|
if (!parent.disabled) {
|
||||||
|
currentFlow.children = [];
|
||||||
|
currentFlow.checkbox = true;
|
||||||
|
} else {
|
||||||
|
currentFlow.class = "disabled"
|
||||||
|
}
|
||||||
|
data.push(currentFlow);
|
||||||
|
}
|
||||||
|
if (currentFlow.children) {
|
||||||
|
if (!filteredNodes[node.id]) {
|
||||||
|
currentSelectedCount++;
|
||||||
|
}
|
||||||
|
currentFlow.children.push({
|
||||||
|
label: RED.utils.getNodeLabel(node,node.id),
|
||||||
|
node: node,
|
||||||
|
checkbox: true,
|
||||||
|
selected: !filteredNodes[node.id]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
nodeList.push(node);
|
|
||||||
});
|
});
|
||||||
debugNodeList.editableList('addItems',nodeList);
|
if (currentFlow && currentFlow.checkbox) {
|
||||||
|
currentFlow.selected = currentSelectedCount === currentFlow.children.length
|
||||||
|
}
|
||||||
|
|
||||||
|
debugNodeTreeList.treeList("data", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTimestamp() {
|
function getTimestamp() {
|
||||||
@@ -340,7 +391,16 @@ RED.debug = (function() {
|
|||||||
return m.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
return m.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var refreshTimeout;
|
||||||
function refreshMessageList(_activeWorkspace) {
|
function refreshMessageList(_activeWorkspace) {
|
||||||
|
if (refreshTimeout) {
|
||||||
|
clearTimeout(refreshTimeout);
|
||||||
|
}
|
||||||
|
refreshTimeout = setTimeout(function() {
|
||||||
|
_refreshMessageList(_activeWorkspace);
|
||||||
|
},200);
|
||||||
|
}
|
||||||
|
function _refreshMessageList(_activeWorkspace) {
|
||||||
if (_activeWorkspace) {
|
if (_activeWorkspace) {
|
||||||
activeWorkspace = _activeWorkspace.replace(/\./g,"_");
|
activeWorkspace = _activeWorkspace.replace(/\./g,"_");
|
||||||
}
|
}
|
||||||
@@ -415,6 +475,7 @@ RED.debug = (function() {
|
|||||||
});
|
});
|
||||||
delete filteredNodes[sourceId];
|
delete filteredNodes[sourceId];
|
||||||
$("#red-ui-sidebar-debug-filterSelected").trigger("click");
|
$("#red-ui-sidebar-debug-filterSelected").trigger("click");
|
||||||
|
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
|
||||||
refreshMessageList();
|
refreshMessageList();
|
||||||
}},
|
}},
|
||||||
{id:"red-ui-debug-msg-menu-item-clear-filter",label:RED._("node-red:debug.messageMenu.clearFilter"),onselect:function(){
|
{id:"red-ui-debug-msg-menu-item-clear-filter",label:RED._("node-red:debug.messageMenu.clearFilter"),onselect:function(){
|
||||||
@@ -601,8 +662,12 @@ RED.debug = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearMessageList(clearFilter) {
|
function clearMessageList(clearFilter, filteredOnly) {
|
||||||
$(".red-ui-debug-msg").remove();
|
if (!filteredOnly) {
|
||||||
|
$(".red-ui-debug-msg").remove();
|
||||||
|
} else {
|
||||||
|
$(".red-ui-debug-msg:not(.hide)").remove();
|
||||||
|
}
|
||||||
config.clear();
|
config.clear();
|
||||||
if (!!clearFilter) {
|
if (!!clearFilter) {
|
||||||
clearFilterSettings();
|
clearFilterSettings();
|
||||||
@@ -613,10 +678,9 @@ RED.debug = (function() {
|
|||||||
function clearFilterSettings() {
|
function clearFilterSettings() {
|
||||||
filteredNodes = {};
|
filteredNodes = {};
|
||||||
filterType = 'filterAll';
|
filterType = 'filterAll';
|
||||||
$('.red-ui-sidebar-debug-filter-option').removeClass('selected');
|
RED.settings.set("debug.filter",filterType);
|
||||||
$('#red-ui-sidebar-debug-filterAll').addClass('selected');
|
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
|
||||||
$('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll'));
|
$('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll'));
|
||||||
$('#red-ui-sidebar-debug-filter-node-list-row').slideUp();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@@ -15,18 +15,22 @@ $(function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var uiComponents = RED.debug.init(options);
|
try {
|
||||||
|
var uiComponents = RED.debug.init(options);
|
||||||
|
$(".red-ui-debug-window").append(uiComponents.content);
|
||||||
|
|
||||||
$(".red-ui-debug-window").append(uiComponents.content);
|
window.addEventListener('message',function(evt) {
|
||||||
|
if (evt.data.event === "message") {
|
||||||
|
RED.debug.handleDebugMessage(evt.data.msg);
|
||||||
|
} else if (evt.data.event === "workspaceChange") {
|
||||||
|
RED.debug.refreshMessageList(evt.data.activeWorkspace);
|
||||||
|
} else if (evt.data.event === "projectChange") {
|
||||||
|
RED.debug.clearMessageList(true);
|
||||||
|
}
|
||||||
|
},false);
|
||||||
|
} catch(err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
|
||||||
window.addEventListener('message',function(evt) {
|
|
||||||
if (evt.data.event === "message") {
|
|
||||||
RED.debug.handleDebugMessage(evt.data.msg);
|
|
||||||
} else if (evt.data.event === "workspaceChange") {
|
|
||||||
RED.debug.refreshMessageList(evt.data.activeWorkspace);
|
|
||||||
} else if (evt.data.event === "projectChange") {
|
|
||||||
RED.debug.clearMessageList(true);
|
|
||||||
}
|
|
||||||
},false);
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@@ -117,30 +117,35 @@
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createValueField(row){
|
function createValueField(row, defaultType){
|
||||||
return $('<input/>',{class:"node-input-rule-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
return $('<input/>',{class:"node-input-rule-value",type:"text",style:"width: 100%;"}).appendTo(row)
|
||||||
|
.typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createNumValueField(row){
|
function createNumValueField(row, defaultType){
|
||||||
return $('<input/>',{class:"node-input-rule-num-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'num',types:['flow','global','num','jsonata','env']});
|
return $('<input/>',{class:"node-input-rule-num-value",type:"text",style:"width: 100%;"}).appendTo(row)
|
||||||
|
.typedInput({default:defaultType||'num',types:['flow','global','num','jsonata','env']});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createExpValueField(row){
|
function createExpValueField(row){
|
||||||
return $('<input/>',{class:"node-input-rule-exp-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'jsonata',types:['jsonata']});
|
return $('<input/>',{class:"node-input-rule-exp-value",type:"text",style:"width: 100%;"}).appendTo(row)
|
||||||
|
.typedInput({default:'jsonata',types:['jsonata']});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBtwnValueField(row){
|
function createBtwnValueField(row, defaultType){
|
||||||
return $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
return $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"width: 100%;"}).appendTo(row)
|
||||||
|
.typedInput({default:defaultType||'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBtwnValue2Field(row3, andLabel){
|
function createBtwnValue2Field(row3, andLabel, defaultType){
|
||||||
$('<div/>',{class:"node-input-rule-btwn-label", style:"width: 120px; text-align: right;"}).text(" "+andLabel+" ").appendTo(row3);
|
$('<div/>',{class:"node-input-rule-btwn-label", style:"width: 120px; text-align: right;"}).text(" "+andLabel+" ").appendTo(row3);
|
||||||
var row3InputCell = $('<div/>',{style:"flex-grow:1; margin-left: 5px;"}).appendTo(row3);
|
var row3InputCell = $('<div/>',{style:"flex-grow:1; margin-left: 5px;"}).appendTo(row3);
|
||||||
return $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"width: 100%"}).appendTo(row3InputCell).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
return $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"width: 100%"}).appendTo(row3InputCell)
|
||||||
|
.typedInput({default:defaultType||'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTypeValueField(){
|
function createTypeValueField(row, defaultType){
|
||||||
return $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'string',types:[
|
return $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:defaultType || 'string',types:[
|
||||||
{value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.png"},
|
{value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.png"},
|
||||||
{value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.png"},
|
{value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.png"},
|
||||||
{value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.png"},
|
{value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.png"},
|
||||||
@@ -211,6 +216,7 @@
|
|||||||
var lastRule = $("#node-input-rule-container").editableList('getItemAt',i-1);
|
var lastRule = $("#node-input-rule-container").editableList('getItemAt',i-1);
|
||||||
var exportedRule = exportRule(lastRule.element);
|
var exportedRule = exportRule(lastRule.element);
|
||||||
opt.r.vt = exportedRule.vt;
|
opt.r.vt = exportedRule.vt;
|
||||||
|
opt.r.v = "";
|
||||||
// We could copy the value over as well and preselect it (see the 'activeElement' code below)
|
// We could copy the value over as well and preselect it (see the 'activeElement' code below)
|
||||||
// But not sure that feels right. Is copying over the last value 'expected' behaviour?
|
// But not sure that feels right. Is copying over the last value 'expected' behaviour?
|
||||||
// It would make sense for an explicit 'copy' action, but not sure where the copy button would
|
// It would make sense for an explicit 'copy' action, but not sure where the copy button would
|
||||||
@@ -278,24 +284,12 @@
|
|||||||
selectField.on("change", function() {
|
selectField.on("change", function() {
|
||||||
var fieldToFocus;
|
var fieldToFocus;
|
||||||
var type = selectField.val();
|
var type = selectField.val();
|
||||||
if (valueField){
|
if (valueField) { valueField.typedInput('hide'); }
|
||||||
valueField.typedInput('hide');
|
if (expValueField) { expValueField.typedInput('hide'); }
|
||||||
}
|
if (numValueField) { numValueField.typedInput('hide'); }
|
||||||
if (expValueField){
|
if (typeValueField) { typeValueField.typedInput('hide'); }
|
||||||
expValueField.typedInput('hide');
|
if (btwnValueField) { btwnValueField.typedInput('hide'); }
|
||||||
}
|
if (btwnValue2Field) { btwnValue2Field.typedInput('hide'); }
|
||||||
if (numValueField){
|
|
||||||
numValueField.typedInput('hide');
|
|
||||||
}
|
|
||||||
if (typeValueField){
|
|
||||||
typeValueField.typedInput('hide');
|
|
||||||
}
|
|
||||||
if (btwnValueField){
|
|
||||||
btwnValueField.typedInput('hide');
|
|
||||||
}
|
|
||||||
if (btwnValue2Field){
|
|
||||||
btwnValue2Field.typedInput('hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((type === "btwn") || (type === "index")) {
|
if ((type === "btwn") || (type === "index")) {
|
||||||
if (!btwnValueField){
|
if (!btwnValueField){
|
||||||
@@ -318,7 +312,7 @@
|
|||||||
|
|
||||||
} else if (type === "istype") {
|
} else if (type === "istype") {
|
||||||
if (!typeValueField){
|
if (!typeValueField){
|
||||||
typeValueField = createTypeValueField();
|
typeValueField = createTypeValueField(rowInputCell);
|
||||||
}
|
}
|
||||||
typeValueField.typedInput('show');
|
typeValueField.typedInput('show');
|
||||||
fieldToFocus = typeValueField;
|
fieldToFocus = typeValueField;
|
||||||
@@ -351,7 +345,9 @@
|
|||||||
} else {
|
} else {
|
||||||
selectField.width("auto")
|
selectField.width("auto")
|
||||||
}
|
}
|
||||||
fieldToFocus.typedInput("focus");
|
if (fieldToFocus) {
|
||||||
|
fieldToFocus.typedInput("focus");
|
||||||
|
}
|
||||||
// Preselect the contents of the element
|
// Preselect the contents of the element
|
||||||
// if (focusValueField && document.activeElement) {
|
// if (focusValueField && document.activeElement) {
|
||||||
// document.activeElement.selectionStart = 0;
|
// document.activeElement.selectionStart = 0;
|
||||||
@@ -359,48 +355,26 @@
|
|||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
selectField.val(rule.t);
|
selectField.val(rule.t);
|
||||||
if ((rule.t == "btwn") || (rule.t == "index")) {
|
|
||||||
if (!btwnValueField){
|
|
||||||
btwnValueField = createBtwnValueField(rowInputCell);
|
|
||||||
}
|
|
||||||
btwnValueField.typedInput('value',rule.v);
|
|
||||||
btwnValueField.typedInput('type',rule.vt||'num');
|
|
||||||
|
|
||||||
if (!btwnValue2Field){
|
if ((rule.t == "btwn") || (rule.t == "index")) {
|
||||||
btwnValue2Field = createBtwnValue2Field(row3, andLabel);
|
btwnValueField = createBtwnValueField(rowInputCell,rule.vt||'num');
|
||||||
}
|
btwnValueField.typedInput('value',rule.v);
|
||||||
|
btwnValue2Field = createBtwnValue2Field(row3, andLabel,rule.v2t||'num');
|
||||||
btwnValue2Field.typedInput('value',rule.v2);
|
btwnValue2Field.typedInput('value',rule.v2);
|
||||||
btwnValue2Field.typedInput('type',rule.v2t||'num');
|
|
||||||
} else if ((rule.t === "head") || (rule.t === "tail")) {
|
} else if ((rule.t === "head") || (rule.t === "tail")) {
|
||||||
if (!numValueField){
|
numValueField = createNumValueField(rowInputCell,rule.vt||'num');
|
||||||
numValueField = createNumValueField(row);
|
|
||||||
}
|
|
||||||
numValueField.typedInput('value',rule.v);
|
numValueField.typedInput('value',rule.v);
|
||||||
numValueField.typedInput('type',rule.vt||'num');
|
|
||||||
} else if (rule.t === "istype") {
|
} else if (rule.t === "istype") {
|
||||||
if (!typeValueField){
|
typeValueField = createTypeValueField(rowInputCell,rule.vt);
|
||||||
typeValueField =createTypeValueField();
|
|
||||||
}
|
|
||||||
typeValueField.typedInput('value',rule.vt);
|
typeValueField.typedInput('value',rule.vt);
|
||||||
typeValueField.typedInput('type',rule.vt);
|
|
||||||
} else if (rule.t === "jsonata_exp") {
|
} else if (rule.t === "jsonata_exp") {
|
||||||
if (!expValueField){
|
expValueField = createExpValueField(rowInputCell,rule.vt||'jsonata');
|
||||||
expValueField = createExpValueField(row);
|
|
||||||
}
|
|
||||||
expValueField.typedInput('value',rule.v);
|
expValueField.typedInput('value',rule.v);
|
||||||
expValueField.typedInput('type',rule.vt||'jsonata');
|
|
||||||
} else if (typeof rule.v != "undefined") {
|
} else if (typeof rule.v != "undefined") {
|
||||||
if (!valueField){
|
valueField = createValueField(rowInputCell,rule.vt||'str');
|
||||||
valueField = createValueField(rowInputCell);
|
|
||||||
}
|
|
||||||
valueField.typedInput('value',rule.v);
|
valueField.typedInput('value',rule.v);
|
||||||
valueField.typedInput('type',rule.vt||'str');
|
|
||||||
}
|
|
||||||
if (rule.case) {
|
|
||||||
caseSensitive.prop('checked',true);
|
|
||||||
} else {
|
|
||||||
caseSensitive.prop('checked',false);
|
|
||||||
}
|
}
|
||||||
|
caseSensitive.prop('checked',!!rule.case);
|
||||||
selectField.change();
|
selectField.change();
|
||||||
|
|
||||||
var currentOutputs = JSON.parse(outputCount.val()||"{}");
|
var currentOutputs = JSON.parse(outputCount.val()||"{}");
|
||||||
|
@@ -115,12 +115,12 @@
|
|||||||
var regex = this._("change.label.regex");
|
var regex = this._("change.label.regex");
|
||||||
var deepCopyLabel = this._("change.label.deepCopy");
|
var deepCopyLabel = this._("change.label.deepCopy");
|
||||||
|
|
||||||
function createPropertyValue(row2_1,row2_2) {
|
function createPropertyValue(row2_1, row2_2, defaultType) {
|
||||||
var propValInput = $('<input/>',{class:"node-input-rule-property-value",type:"text"})
|
var propValInput = $('<input/>',{class:"node-input-rule-property-value",type:"text"})
|
||||||
.appendTo(row2_1)
|
.appendTo(row2_1)
|
||||||
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']});
|
.typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']});
|
||||||
|
|
||||||
var dcLabel = $('<label style="padding-left: 130px; display: flex; align-items: center "></label>').appendTo(row2_2);
|
var dcLabel = $('<label style="padding-left: 130px;"></label>').appendTo(row2_2);
|
||||||
var deepCopy = $('<input type="checkbox" class="node-input-rule-property-deepCopy" style="width: auto; margin: 0 6px 0 0">').appendTo(dcLabel)
|
var deepCopy = $('<input type="checkbox" class="node-input-rule-property-deepCopy" style="width: auto; margin: 0 6px 0 0">').appendTo(dcLabel)
|
||||||
$('<span>').text(deepCopyLabel).appendTo(dcLabel)
|
$('<span>').text(deepCopyLabel).appendTo(dcLabel)
|
||||||
|
|
||||||
@@ -129,20 +129,20 @@
|
|||||||
})
|
})
|
||||||
return [propValInput, deepCopy];
|
return [propValInput, deepCopy];
|
||||||
}
|
}
|
||||||
function createFromValue(row3_1) {
|
function createFromValue(row3_1, defaultType) {
|
||||||
return $('<input/>',{class:"node-input-rule-property-search-value",type:"text"})
|
return $('<input/>',{class:"node-input-rule-property-search-value",type:"text"})
|
||||||
.appendTo(row3_1)
|
.appendTo(row3_1)
|
||||||
.typedInput({default:'str',types:['msg','flow','global','str','re','num','bool','env']});
|
.typedInput({default:defaultType||'str',types:['msg','flow','global','str','re','num','bool','env']});
|
||||||
}
|
}
|
||||||
function createToValue(row3_2) {
|
function createToValue(row3_2, defaultType) {
|
||||||
return $('<input/>',{class:"node-input-rule-property-replace-value",type:"text"})
|
return $('<input/>',{class:"node-input-rule-property-replace-value",type:"text"})
|
||||||
.appendTo(row3_2)
|
.appendTo(row3_2)
|
||||||
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','env']});
|
.typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','env']});
|
||||||
}
|
}
|
||||||
function createMoveValue(row4) {
|
function createMoveValue(row4, defaultType) {
|
||||||
return $('<input/>',{class:"node-input-rule-property-move-value",type:"text"})
|
return $('<input/>',{class:"node-input-rule-property-move-value",type:"text"})
|
||||||
.appendTo(row4)
|
.appendTo(row4)
|
||||||
.typedInput({default:'msg',types:['msg','flow','global']});
|
.typedInput({default:defaultType||'msg',types:['msg','flow','global']});
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#node-input-rule-container').css('min-height','150px').css('min-width','450px').editableList({
|
$('#node-input-rule-container').css('min-height','150px').css('min-width','450px').editableList({
|
||||||
@@ -268,33 +268,22 @@
|
|||||||
propertyName.typedInput('value',rule.p);
|
propertyName.typedInput('value',rule.p);
|
||||||
propertyName.typedInput('type',rule.pt);
|
propertyName.typedInput('type',rule.pt);
|
||||||
if (rule.t == "set") {
|
if (rule.t == "set") {
|
||||||
if(!propertyValue) {
|
var parts = createPropertyValue(row2_1, row2_2, rule.tot);
|
||||||
var parts = createPropertyValue(row2_1, row2_2);
|
propertyValue = parts[0];
|
||||||
propertyValue = parts[0];
|
deepCopy = parts[1];
|
||||||
deepCopy = parts[1];
|
|
||||||
}
|
|
||||||
propertyValue.typedInput('value',rule.to);
|
propertyValue.typedInput('value',rule.to);
|
||||||
propertyValue.typedInput('type',rule.tot);
|
|
||||||
deepCopy.prop("checked", !!rule.dc);
|
deepCopy.prop("checked", !!rule.dc);
|
||||||
}
|
}
|
||||||
if (rule.t == "move") {
|
if (rule.t == "move") {
|
||||||
if(!moveValue) {
|
moveValue = createMoveValue(row4,rule.tot);
|
||||||
moveValue = createMoveValue(row4);
|
|
||||||
}
|
|
||||||
moveValue.typedInput('value',rule.to);
|
moveValue.typedInput('value',rule.to);
|
||||||
moveValue.typedInput('type',rule.tot);
|
|
||||||
}
|
}
|
||||||
if (rule.t == "change") {
|
if (rule.t == "change") {
|
||||||
if(!fromValue) {
|
fromValue = createFromValue(row3_1, rule.fromt);
|
||||||
fromValue = createFromValue(row3_1);
|
|
||||||
}
|
|
||||||
fromValue.typedInput('value',rule.from);
|
fromValue.typedInput('value',rule.from);
|
||||||
fromValue.typedInput('type',rule.fromt);
|
|
||||||
if (!toValue) {
|
toValue = createToValue(row3_2,rule.tot);
|
||||||
toValue = createToValue(row3_2);
|
|
||||||
}
|
|
||||||
toValue.typedInput('value',rule.to);
|
toValue.typedInput('value',rule.to);
|
||||||
toValue.typedInput('type',rule.tot);
|
|
||||||
}
|
}
|
||||||
selectField.change();
|
selectField.change();
|
||||||
container[0].appendChild(fragment);
|
container[0].appendChild(fragment);
|
||||||
|
@@ -372,6 +372,7 @@ module.exports = function(RED) {
|
|||||||
hit = false;
|
hit = false;
|
||||||
for (var b in node.buffer) { // check if already in queue
|
for (var b in node.buffer) { // check if already in queue
|
||||||
if (msg.topic === node.buffer[b].msg.topic) {
|
if (msg.topic === node.buffer[b].msg.topic) {
|
||||||
|
if (node.outputs === 2) { send([null,node.buffer[b].msg]) }
|
||||||
node.buffer[b].done();
|
node.buffer[b].done();
|
||||||
node.buffer[b] = {msg, send, done}; // if so - replace existing entry
|
node.buffer[b] = {msg, send, done}; // if so - replace existing entry
|
||||||
hit = true;
|
hit = true;
|
||||||
|
@@ -54,6 +54,18 @@
|
|||||||
width: 15px;
|
width: 15px;
|
||||||
height: 15px;
|
height: 15px;
|
||||||
}
|
}
|
||||||
|
.form-row-mqtt5 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.form-row-mqtt5.form-row-mqtt5-active:not(.form-row-mqtt-static-disabled) {
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
.form-row-mqtt-static-disabled {
|
||||||
|
display: none;
|
||||||
|
/* opacity: 0.3;
|
||||||
|
pointer-events: none; */
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script type="text/html" data-template-name="mqtt in">
|
<script type="text/html" data-template-name="mqtt in">
|
||||||
@@ -62,10 +74,18 @@
|
|||||||
<input type="text" id="node-input-broker">
|
<input type="text" id="node-input-broker">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
|
<label for="node-input-topicType" data-i18n="mqtt.label.action"></label>
|
||||||
|
<select id="node-input-topicType" style="width: 70%">
|
||||||
|
<option value="topic" data-i18n="mqtt.label.staticTopic"></option>
|
||||||
|
<option value="dynamic" data-i18n="mqtt.label.dynamicTopic"></option>
|
||||||
|
</select>
|
||||||
|
<input type="hidden" id="node-input-inputs">
|
||||||
|
</div>
|
||||||
|
<div class="form-row form-row-mqtt-static">
|
||||||
<label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
|
<label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
|
||||||
<input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic">
|
<input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row form-row-mqtt-static">
|
||||||
<label for="node-input-qos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label>
|
<label for="node-input-qos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label>
|
||||||
<select id="node-input-qos" style="width:125px !important">
|
<select id="node-input-qos" style="width:125px !important">
|
||||||
<option value="0">0</option>
|
<option value="0">0</option>
|
||||||
@@ -73,17 +93,7 @@
|
|||||||
<option value="2">2</option>
|
<option value="2">2</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row mqtt-flags-row form-row-mqtt5 form-row-mqtt-static">
|
||||||
<label for="node-input-datatype"><i class="fa fa-sign-out"></i> <span data-i18n="mqtt.label.output"></span></label>
|
|
||||||
<select id="node-input-datatype" style="width:70%;">
|
|
||||||
<option value="auto" data-i18n="mqtt.output.auto"></option>
|
|
||||||
<option value="buffer" data-i18n="mqtt.output.buffer"></option>
|
|
||||||
<option value="utf8" data-i18n="mqtt.output.string"></option>
|
|
||||||
<option value="json" data-i18n="mqtt.output.json"></option>
|
|
||||||
<option value="base64" data-i18n="mqtt.output.base64"></option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="form-row mqtt-flags-row mqtt5">
|
|
||||||
<label for="node-input-nl" ><i class="fa fa-flag"></i> <span data-i18n="mqtt.label.flags">Flags</span></label>
|
<label for="node-input-nl" ><i class="fa fa-flag"></i> <span data-i18n="mqtt.label.flags">Flags</span></label>
|
||||||
<div class="mqtt-flags">
|
<div class="mqtt-flags">
|
||||||
<div class="mqtt-flag">
|
<div class="mqtt-flag">
|
||||||
@@ -100,7 +110,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row mqtt5">
|
<div class="form-row form-row-mqtt5 form-row-mqtt-static">
|
||||||
<label for="node-input-rh" style="width:100%"><i class="fa fa-tag"></i> <span data-i18n="mqtt.label.rh"></span></label>
|
<label for="node-input-rh" style="width:100%"><i class="fa fa-tag"></i> <span data-i18n="mqtt.label.rh"></span></label>
|
||||||
<select id="node-input-rh" style="margin-left: 104px; width: 70%">
|
<select id="node-input-rh" style="margin-left: 104px; width: 70%">
|
||||||
<option value="0" data-i18n="mqtt.label.rh0"></option>
|
<option value="0" data-i18n="mqtt.label.rh0"></option>
|
||||||
@@ -108,6 +118,16 @@
|
|||||||
<option value="2" data-i18n="mqtt.label.rh2"></option>
|
<option value="2" data-i18n="mqtt.label.rh2"></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-datatype"><i class="fa fa-sign-out"></i> <span data-i18n="mqtt.label.output"></span></label>
|
||||||
|
<select id="node-input-datatype" style="width:70%;">
|
||||||
|
<option value="auto" data-i18n="mqtt.output.auto"></option>
|
||||||
|
<option value="buffer" data-i18n="mqtt.output.buffer"></option>
|
||||||
|
<option value="utf8" data-i18n="mqtt.output.string"></option>
|
||||||
|
<option value="json" data-i18n="mqtt.output.json"></option>
|
||||||
|
<option value="base64" data-i18n="mqtt.output.base64"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
@@ -185,6 +205,10 @@
|
|||||||
<label for="node-config-input-port" style="margin-left:20px; width:43px; "> <span data-i18n="mqtt.label.port"></span></label>
|
<label for="node-config-input-port" style="margin-left:20px; width:43px; "> <span data-i18n="mqtt.label.port"></span></label>
|
||||||
<input type="text" id="node-config-input-port" data-i18n="[placeholder]mqtt.label.port" style="width:55px">
|
<input type="text" id="node-config-input-port" data-i18n="[placeholder]mqtt.label.port" style="width:55px">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row" style="margin-bottom:0">
|
||||||
|
<input type="checkbox" id="node-config-input-autoConnect" style="margin: 0 5px 0 104px; display: inline-block; width: auto;">
|
||||||
|
<label for="node-config-input-autoConnect" style="width: auto"><span data-i18n="mqtt.label.auto-connect"></span></label>
|
||||||
|
</div>
|
||||||
<div class="form-row" style="height: 34px;">
|
<div class="form-row" style="height: 34px;">
|
||||||
<input type="checkbox" id="node-config-input-usetls" style="height: 34px; margin: 0 5px 0 104px; display: inline-block; width: auto; vertical-align: top;">
|
<input type="checkbox" id="node-config-input-usetls" style="height: 34px; margin: 0 5px 0 104px; display: inline-block; width: auto; vertical-align: top;">
|
||||||
<label for="node-config-input-usetls" style="width: 100px; line-height: 34px;"><span data-i18n="mqtt.label.use-tls"></span></label>
|
<label for="node-config-input-usetls" style="width: 100px; line-height: 34px;"><span data-i18n="mqtt.label.use-tls"></span></label>
|
||||||
@@ -434,6 +458,7 @@
|
|||||||
return (this.cleansession===undefined || this.cleansession) || (v||"").length > 0;
|
return (this.cleansession===undefined || this.cleansession) || (v||"").length > 0;
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
|
autoConnect: {value: true},
|
||||||
usetls: {value: false},
|
usetls: {value: false},
|
||||||
verifyservercert: { value: false},
|
verifyservercert: { value: false},
|
||||||
compatmode: { value: false},
|
compatmode: { value: false},
|
||||||
@@ -558,6 +583,10 @@
|
|||||||
this.usetls = false;
|
this.usetls = false;
|
||||||
$("#node-config-input-usetls").prop("checked",false);
|
$("#node-config-input-usetls").prop("checked",false);
|
||||||
}
|
}
|
||||||
|
if (typeof this.autoConnect === 'undefined') {
|
||||||
|
this.autoConnect = true;
|
||||||
|
$("#node-config-input-autoConnect").prop("checked",true);
|
||||||
|
}
|
||||||
if (this.compatmode === 'true' || this.compatmode === true) {
|
if (this.compatmode === 'true' || this.compatmode === true) {
|
||||||
delete this.compatmode;
|
delete this.compatmode;
|
||||||
this.protocolVersion = 4;
|
this.protocolVersion = 4;
|
||||||
@@ -704,11 +733,22 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
RED.nodes.registerType('mqtt in',{
|
RED.nodes.registerType('mqtt in',{
|
||||||
category: 'network',
|
category: 'network',
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
topic: {value:"",required:true,validate: RED.validators.regex(/^(#$|(\+|[^+#]*)(\/(\+|[^+#]*))*(\/(\+|#|[^+#]*))?$)/)},
|
topic: {
|
||||||
|
value:"",
|
||||||
|
validate: function(v) {
|
||||||
|
var isDynamic = this.inputs === 1;
|
||||||
|
var topicTypeSelect = $("#node-input-topicType");
|
||||||
|
if (topicTypeSelect.length) {
|
||||||
|
isDynamic = topicTypeSelect.val()==='dynamic'
|
||||||
|
}
|
||||||
|
return isDynamic || ((!!v) && RED.validators.regex(/^(#$|(\+|[^+#]*)(\/(\+|[^+#]*))*(\/(\+|#|[^+#]*))?$)/)(v));
|
||||||
|
}
|
||||||
|
},
|
||||||
qos: {value: "2"},
|
qos: {value: "2"},
|
||||||
datatype: {value:"auto",required:true},
|
datatype: {value:"auto",required:true},
|
||||||
broker: {type:"mqtt-broker", required:true},
|
broker: {type:"mqtt-broker", required:true},
|
||||||
@@ -716,33 +756,64 @@
|
|||||||
nl: {value:false},
|
nl: {value:false},
|
||||||
rap: {value:true},
|
rap: {value:true},
|
||||||
rh: {value:0},
|
rh: {value:0},
|
||||||
|
inputs: {value:0},
|
||||||
},
|
},
|
||||||
color:"#d8bfd8",
|
color:"#d8bfd8",
|
||||||
inputs:0,
|
inputs:0,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
icon: "bridge.svg",
|
icon: "bridge.svg",
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.name||this.topic||"mqtt";
|
var label = "mqtt";
|
||||||
|
if(this.topicType !== "dynamic" && this.topic) {
|
||||||
|
label = this.topic;
|
||||||
|
}
|
||||||
|
return this.name || label;
|
||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
return this.name?"node_label_italic":"";
|
return this.name?"node_label_italic":"";
|
||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
$("#node-input-broker").on("change",function(d){
|
const node = this;
|
||||||
|
const isV5Broker = function() {
|
||||||
var confNode = RED.nodes.node($("#node-input-broker").val());
|
var confNode = RED.nodes.node($("#node-input-broker").val());
|
||||||
var v5 = confNode && confNode.protocolVersion == "5";
|
return confNode && confNode.protocolVersion === "5";
|
||||||
if(v5) {
|
}
|
||||||
$("div.form-row.mqtt5").show();
|
const isDynamic = function() {
|
||||||
} else {
|
return $('#node-input-topicType').val() === "dynamic";
|
||||||
$("div.form-row.mqtt5").hide();
|
}
|
||||||
}
|
const updateVisibility = function() {
|
||||||
|
var v5 = isV5Broker();
|
||||||
|
var dynamic = isDynamic();
|
||||||
|
$("div.form-row-mqtt5").toggleClass("form-row-mqtt5-active",!!v5);
|
||||||
|
$("div.form-row.form-row-mqtt-static").toggleClass("form-row-mqtt-static-disabled", !!dynamic)
|
||||||
|
}
|
||||||
|
$("#node-input-broker").on("change",function(d){
|
||||||
|
updateVisibility();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#node-input-topicType').on("change", function () {
|
||||||
|
$("#node-input-inputs").val(isDynamic() ? 1 : 0);
|
||||||
|
updateVisibility();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.inputs === 1) {
|
||||||
|
$('#node-input-topicType').val('dynamic')
|
||||||
|
} else {
|
||||||
|
$('#node-input-topicType').val('topic')
|
||||||
|
}
|
||||||
|
$('#node-input-topicType').trigger("change");
|
||||||
|
|
||||||
if (this.qos === undefined) {
|
if (this.qos === undefined) {
|
||||||
$("#node-input-qos").val("2");
|
$("#node-input-qos").val("2");
|
||||||
}
|
}
|
||||||
if (this.datatype === undefined) {
|
if (this.datatype === undefined) {
|
||||||
$("#node-input-datatype").val("auto");
|
$("#node-input-datatype").val("auto");
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
oneditsave: function() {
|
||||||
|
if ($('#node-input-topicType').val() === "dynamic") {
|
||||||
|
$('#node-input-topic').val("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -298,18 +298,14 @@ in your Node-RED user directory (${RED.settings.userDir}).
|
|||||||
}
|
}
|
||||||
if (Object.keys(this.credentials).length != 0) {
|
if (Object.keys(this.credentials).length != 0) {
|
||||||
if (this.authType === "basic") {
|
if (this.authType === "basic") {
|
||||||
// Workaround for https://github.com/sindresorhus/got/issues/1169
|
// Workaround for https://github.com/sindresorhus/got/issues/1169 (fixed in got v12)
|
||||||
var cred = ""
|
// var cred = ""
|
||||||
if (this.credentials.user) {
|
if (this.credentials.user || this.credentials.password) {
|
||||||
// opts.username = this.credentials.user;
|
// cred = `${this.credentials.user}:${this.credentials.password}`;
|
||||||
cred = this.credentials.user
|
opts.headers.Authorization = "Basic " + Buffer.from(`${this.credentials.user}:${this.credentials.password}`).toString("base64");
|
||||||
}
|
|
||||||
if (this.credentials.password) {
|
|
||||||
// opts.password = this.credentials.password;
|
|
||||||
cred += ":" + this.credentials.password
|
|
||||||
}
|
}
|
||||||
// build own basic auth header
|
// build own basic auth header
|
||||||
opts.headers.Authorization = "Basic " + Buffer.from(cred).toString("base64");
|
// opts.headers.Authorization = "Basic " + Buffer.from(cred).toString("base64");
|
||||||
} else if (this.authType === "digest") {
|
} else if (this.authType === "digest") {
|
||||||
let digestCreds = this.credentials;
|
let digestCreds = this.credentials;
|
||||||
let sentCreds = false;
|
let sentCreds = false;
|
||||||
|
@@ -196,6 +196,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-out"><i class="fa fa-sign-out"></i> <span data-i18n="tcpin.label.return"></span></label>
|
<label for="node-input-out"><i class="fa fa-sign-out"></i> <span data-i18n="tcpin.label.return"></span></label>
|
||||||
|
<select type="text" id="node-input-ret" style="width:54%;">
|
||||||
|
<option value="buffer" data-i18n="tcpin.output.buffer"></option>
|
||||||
|
<option value="string" data-i18n="tcpin.output.string"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-out"> </label>
|
||||||
<select type="text" id="node-input-out" style="width:54%;">
|
<select type="text" id="node-input-out" style="width:54%;">
|
||||||
<option value="time" data-i18n="tcpin.return.timeout"></option>
|
<option value="time" data-i18n="tcpin.return.timeout"></option>
|
||||||
<option value="char" data-i18n="tcpin.return.character"></option>
|
<option value="char" data-i18n="tcpin.return.character"></option>
|
||||||
@@ -220,6 +227,7 @@
|
|||||||
server: {value:""},
|
server: {value:""},
|
||||||
port: {value:"",validate:RED.validators.regex(/^(\d*|)$/)},
|
port: {value:"",validate:RED.validators.regex(/^(\d*|)$/)},
|
||||||
out: {value:"time",required:true},
|
out: {value:"time",required:true},
|
||||||
|
ret: {value:"buffer"},
|
||||||
splitc: {value:"0",required:true},
|
splitc: {value:"0",required:true},
|
||||||
name: {value:""}
|
name: {value:""}
|
||||||
},
|
},
|
||||||
@@ -234,6 +242,10 @@
|
|||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
var previous = null;
|
var previous = null;
|
||||||
|
if ($("#node-input-ret").val() == undefined) {
|
||||||
|
$("#node-input-ret").val("buffer");
|
||||||
|
this.ret = "buffer";
|
||||||
|
}
|
||||||
$("#node-input-out").on('focus', function () { previous = this.value; }).on("change", function() {
|
$("#node-input-out").on('focus', function () { previous = this.value; }).on("change", function() {
|
||||||
$("#node-input-splitc").show();
|
$("#node-input-splitc").show();
|
||||||
if (previous === null) { previous = $("#node-input-out").val(); }
|
if (previous === null) { previous = $("#node-input-out").val(); }
|
||||||
|
@@ -311,7 +311,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
setupTcpClient();
|
setupTcpClient();
|
||||||
|
|
||||||
node.on("input", function(msg,nodeSend,nodeDone) {
|
node.on("input", function(msg, nodeSend, nodeDone) {
|
||||||
if (node.connected && msg.payload != null) {
|
if (node.connected && msg.payload != null) {
|
||||||
if (Buffer.isBuffer(msg.payload)) {
|
if (Buffer.isBuffer(msg.payload)) {
|
||||||
client.write(msg.payload);
|
client.write(msg.payload);
|
||||||
@@ -444,6 +444,7 @@ module.exports = function(RED) {
|
|||||||
this.server = n.server;
|
this.server = n.server;
|
||||||
this.port = Number(n.port);
|
this.port = Number(n.port);
|
||||||
this.out = n.out;
|
this.out = n.out;
|
||||||
|
this.ret = n.ret || "buffer";
|
||||||
this.splitc = n.splitc;
|
this.splitc = n.splitc;
|
||||||
|
|
||||||
if (this.out === "immed") { this.splitc = -1; this.out = "time"; }
|
if (this.out === "immed") { this.splitc = -1; this.out = "time"; }
|
||||||
@@ -488,7 +489,7 @@ module.exports = function(RED) {
|
|||||||
connected: false,
|
connected: false,
|
||||||
connecting: false
|
connecting: false
|
||||||
};
|
};
|
||||||
enqueue(clients[connection_id].msgQueue, {msg:msg,nodeSend:nodeSend, nodeDone: nodeDone});
|
enqueue(clients[connection_id].msgQueue, {msg:msg, nodeSend:nodeSend, nodeDone:nodeDone});
|
||||||
clients[connection_id].lastMsg = msg;
|
clients[connection_id].lastMsg = msg;
|
||||||
|
|
||||||
if (!clients[connection_id].connecting && !clients[connection_id].connected) {
|
if (!clients[connection_id].connecting && !clients[connection_id].connected) {
|
||||||
@@ -532,8 +533,12 @@ module.exports = function(RED) {
|
|||||||
if (node.out === "sit") { // if we are staying connected just send the buffer
|
if (node.out === "sit") { // if we are staying connected just send the buffer
|
||||||
if (clients[connection_id]) {
|
if (clients[connection_id]) {
|
||||||
const msg = clients[connection_id].lastMsg || {};
|
const msg = clients[connection_id].lastMsg || {};
|
||||||
msg.payload = data;
|
msg.payload = RED.util.cloneMessage(data);
|
||||||
nodeSend(RED.util.cloneMessage(msg));
|
if (node.ret === "string") {
|
||||||
|
try { msg.payload = msg.payload.toString(); }
|
||||||
|
catch(e) { node.error("Failed to create string", msg); }
|
||||||
|
}
|
||||||
|
nodeSend(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else if (node.splitc === 0) {
|
// else if (node.splitc === 0) {
|
||||||
@@ -556,6 +561,10 @@ module.exports = function(RED) {
|
|||||||
const msg = clients[connection_id].lastMsg || {};
|
const msg = clients[connection_id].lastMsg || {};
|
||||||
msg.payload = Buffer.alloc(i+1);
|
msg.payload = Buffer.alloc(i+1);
|
||||||
buf.copy(msg.payload,0,0,i+1);
|
buf.copy(msg.payload,0,0,i+1);
|
||||||
|
if (node.ret === "string") {
|
||||||
|
try { msg.payload = msg.payload.toString(); }
|
||||||
|
catch(e) { node.error("Failed to create string", msg); }
|
||||||
|
}
|
||||||
nodeSend(msg);
|
nodeSend(msg);
|
||||||
if (clients[connection_id].client) {
|
if (clients[connection_id].client) {
|
||||||
node.status({});
|
node.status({});
|
||||||
@@ -578,6 +587,10 @@ module.exports = function(RED) {
|
|||||||
const msg = clients[connection_id].lastMsg || {};
|
const msg = clients[connection_id].lastMsg || {};
|
||||||
msg.payload = Buffer.alloc(i);
|
msg.payload = Buffer.alloc(i);
|
||||||
buf.copy(msg.payload,0,0,i);
|
buf.copy(msg.payload,0,0,i);
|
||||||
|
if (node.ret === "string") {
|
||||||
|
try { msg.payload = msg.payload.toString(); }
|
||||||
|
catch(e) { node.error("Failed to create string", msg); }
|
||||||
|
}
|
||||||
nodeSend(msg);
|
nodeSend(msg);
|
||||||
if (clients[connection_id].client) {
|
if (clients[connection_id].client) {
|
||||||
node.status({});
|
node.status({});
|
||||||
@@ -597,6 +610,10 @@ module.exports = function(RED) {
|
|||||||
const msg = clients[connection_id].lastMsg || {};
|
const msg = clients[connection_id].lastMsg || {};
|
||||||
msg.payload = Buffer.alloc(i);
|
msg.payload = Buffer.alloc(i);
|
||||||
buf.copy(msg.payload,0,0,i);
|
buf.copy(msg.payload,0,0,i);
|
||||||
|
if (node.ret === "string") {
|
||||||
|
try { msg.payload = msg.payload.toString(); }
|
||||||
|
catch(e) { node.error("Failed to create string", msg); }
|
||||||
|
}
|
||||||
nodeSend(msg);
|
nodeSend(msg);
|
||||||
if (clients[connection_id].client) {
|
if (clients[connection_id].client) {
|
||||||
node.status({});
|
node.status({});
|
||||||
|
@@ -49,7 +49,11 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
var value = RED.util.getMessageProperty(msg,node.property);
|
var value = RED.util.getMessageProperty(msg,node.property);
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string" || Buffer.isBuffer(value)) {
|
||||||
|
// if (Buffer.isBuffer(value) && node.action !== "obj") {
|
||||||
|
// node.warn(RED._("json.errors.dropped")); done();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
if (node.action === "" || node.action === "obj") {
|
if (node.action === "" || node.action === "obj") {
|
||||||
try {
|
try {
|
||||||
RED.util.setMessageProperty(msg,node.property,JSON.parse(value));
|
RED.util.setMessageProperty(msg,node.property,JSON.parse(value));
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
<dd>Optional nutzbare Nachrichten-Eigenschaft.</dd>
|
<dd>Optional nutzbare Nachrichten-Eigenschaft.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
<p>Der <span style="background-color:Gainsboro">inject</span>-Node kann einen Flow mit einstellbaren Nutzdaten (Payload) starten.
|
<p>Der inject-Node kann einen Flow mit einstellbaren Nutzdaten (Payload) starten.
|
||||||
Der voreingestellte Payload ist die aktuelle Zeit als Zeitstempel in Millisekunden
|
Der voreingestellte Payload ist die aktuelle Zeit als Zeitstempel in Millisekunden
|
||||||
seit Beginn der Unix-Zeitrechnung (1. Januar 1970 UTC).</p>
|
seit Beginn der Unix-Zeitrechnung (1. Januar 1970 UTC).</p>
|
||||||
<p>Der Node unterstützt auch die Injektion von Zeichenfolgen, Zahlenwerten, Booleschen Werten,
|
<p>Der Node unterstützt auch die Injektion von Zeichenfolgen, Zahlenwerten, Booleschen Werten,
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
Er kann auch in regelmäßigen Intervallen oder nach einem Zeitplan injizieren.</p>
|
Er kann auch in regelmäßigen Intervallen oder nach einem Zeitplan injizieren.</p>
|
||||||
<p>Er kann auch so eingestellt werden, dass er jedes Mal einen Wert injiziert, wenn der Flow gestartet wird.</p>
|
<p>Er kann auch so eingestellt werden, dass er jedes Mal einen Wert injiziert, wenn der Flow gestartet wird.</p>
|
||||||
<p>Das maximal einstellbare Intervall beträgt etwa 596 Stunden bzw. 24 Tage.
|
<p>Das maximal einstellbare Intervall beträgt etwa 596 Stunden bzw. 24 Tage.
|
||||||
Wenn jedoch Intervalle größer als 24h benötigt werden, sollte ein <span style="background-color:Gainsboro">scheduler</span>-Node verwendet werden,
|
Wenn jedoch Intervalle größer als 24h benötigt werden, sollte ein scheduler-Node verwendet werden,
|
||||||
der mit Stromausfällen und Neustarts besser umgehen kann.</p>
|
der mit Stromausfällen und Neustarts besser umgehen kann.</p>
|
||||||
<p><b>Hinweis</b>: Die Optionen <i>"Intervall zwischen Uhrzeiten"</i> und <i>"Täglicher Zeitpunkt"</i>
|
<p><b>Hinweis</b>: Die Optionen <i>"Intervall zwischen Uhrzeiten"</i> und <i>"Täglicher Zeitpunkt"</i>
|
||||||
verwenden das Standard-Cron-System.</p>
|
verwenden das Standard-Cron-System.</p>
|
||||||
|
@@ -23,10 +23,10 @@
|
|||||||
<p>JavaScript-Objekte und -Arrays können nach Bedarf ein- und ausgeblendet werden.
|
<p>JavaScript-Objekte und -Arrays können nach Bedarf ein- und ausgeblendet werden.
|
||||||
Binäre Puffer-Objekte (buffer objects) können nach Möglichkeit als Rohdaten oder als Zeichenfolge (string) angezeigt werden.</p>
|
Binäre Puffer-Objekte (buffer objects) können nach Möglichkeit als Rohdaten oder als Zeichenfolge (string) angezeigt werden.</p>
|
||||||
<p>Neben der eigentlichen Nachricht werden im Debug-Tab auch der Empfangszeitpunkt,
|
<p>Neben der eigentlichen Nachricht werden im Debug-Tab auch der Empfangszeitpunkt,
|
||||||
der empfangende <span style="background-color:Gainsboro">debug</span>-Node, sowie Name und Typ der Nachricht protokolliert.
|
der empfangende debug-Node, sowie Name und Typ der Nachricht protokolliert.
|
||||||
Durch Klicken auf die Node-ID wird der entsprechende <span style="background-color:Gainsboro">debug</span>-Node im Arbeitsbereich angezeigt.</p>
|
Durch Klicken auf die Node-ID wird der entsprechende debug-Node im Arbeitsbereich angezeigt.</p>
|
||||||
<p>Die Schaltfläche des <span style="background-color:Gainsboro">debug</span>-Nodes kann verwendet werden, um die Debug-Ausgabe ein- und auszuschalten.
|
<p>Die Schaltfläche des debug-Nodes kann verwendet werden, um die Debug-Ausgabe ein- und auszuschalten.
|
||||||
Es ist empfehlenswert, alle nicht verwendeten <span style="background-color:Gainsboro">debug</span>-Nodes zu deaktivieren oder gleich zu entfernen.</p>
|
Es ist empfehlenswert, alle nicht verwendeten debug-Nodes zu deaktivieren oder gleich zu entfernen.</p>
|
||||||
<p>Der <span style="background-color:Gainsboro">debug</span>-Node kann auch so eingestellt werden, dass außerdem alle Nachrichten in der Systemkonsole ausgegeben und/oder
|
<p>Der debug-Node kann auch so eingestellt werden, dass außerdem alle Nachrichten in der Systemkonsole ausgegeben und/oder
|
||||||
als kurze Statustexte (max. 32 Zeichen) unter dem <span style="background-color:Gainsboro">debug</span>-Node angezeigt werden.</p>
|
als kurze Statustexte (max. 32 Zeichen) unter dem debug-Node angezeigt werden.</p>
|
||||||
</script>
|
</script>
|
||||||
|
@@ -18,11 +18,11 @@
|
|||||||
<p>Anstoß eines weiteren Flows, wenn ein anderer Node seine Nachrichtenbearbeitung abgeschlossen hat.</p>
|
<p>Anstoß eines weiteren Flows, wenn ein anderer Node seine Nachrichtenbearbeitung abgeschlossen hat.</p>
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
<p>Wenn ein Node die Bearbeitung seiner Nachrichten abgeschlossen hat,
|
<p>Wenn ein Node die Bearbeitung seiner Nachrichten abgeschlossen hat,
|
||||||
kann der <span style="background-color:Gainsboro">complete</span>-Node dazu benutzt werden, einen weiteren Flow anzustoßen.</p>
|
kann der complete-Node dazu benutzt werden, einen weiteren Flow anzustoßen.</p>
|
||||||
<p>Der Node kann z.B. mit einem anderen Node ohne Ausgang verknüpft werden
|
<p>Der Node kann z.B. mit einem anderen Node ohne Ausgang verknüpft werden
|
||||||
(z.B. E-Mail-Sende-Node), um den Flow fortzusetzen.</p>
|
(z.B. E-Mail-Sende-Node), um den Flow fortzusetzen.</p>
|
||||||
<p>Im Node werden dazu die zu überwachenden Nodes des selben Flows ausgewählt.
|
<p>Im Node werden dazu die zu überwachenden Nodes des selben Flows ausgewählt.
|
||||||
Im Gegensatz zum <span style="background-color:Gainsboro">catch</span>-Node besteht hier jedoch nicht die Auswahlmöglichkeit aller Nodes des Flows.</p>
|
Im Gegensatz zum catch-Node besteht hier jedoch nicht die Auswahlmöglichkeit aller Nodes des Flows.</p>
|
||||||
<p>Nicht alle Nodes können diesen Node anstoßen.
|
<p>Nicht alle Nodes können diesen Node anstoßen.
|
||||||
Es hängt davon ab, ob die auslösenden Knoten diese Funktion unterstützen,
|
Es hängt davon ab, ob die auslösenden Knoten diese Funktion unterstützen,
|
||||||
welche erst mit Node-RED 1.0 eingeführt wurde.</p>
|
welche erst mit Node-RED 1.0 eingeführt wurde.</p>
|
||||||
|
@@ -29,13 +29,13 @@
|
|||||||
</dl>
|
</dl>
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
<p>Wenn ein Node bei der Verarbeitung einer Nachricht einen Fehler verursacht, wird der Flow in der Regel angehalten.
|
<p>Wenn ein Node bei der Verarbeitung einer Nachricht einen Fehler verursacht, wird der Flow in der Regel angehalten.
|
||||||
Der <span style="background-color:Gainsboro">catch</span>-Node kann verwendet werden, um diese Fehler abzufangen und sie mit einem dedizierten Flow zu bearbeiten.</p>
|
Der catch-Node kann verwendet werden, um diese Fehler abzufangen und sie mit einem dedizierten Flow zu bearbeiten.</p>
|
||||||
<p>Der Node fängt standardmäßig die Fehler aller Nodes im selben Flow ab.
|
<p>Der Node fängt standardmäßig die Fehler aller Nodes im selben Flow ab.
|
||||||
Alternativ kann er auch an bestimmte Nodes gebunden werden.</p>
|
Alternativ kann er auch an bestimmte Nodes gebunden werden.</p>
|
||||||
<p>Wenn ein Fehler ausgelöst wird, empfangen alle angebundenen <span style="background-color:Gainsboro">catch</span>-Nodes die Fehlermeldung.</p>
|
<p>Wenn ein Fehler ausgelöst wird, empfangen alle angebundenen catch-Nodes die Fehlermeldung.</p>
|
||||||
<p>Wenn ein Fehler in einem Subflow ausgelöst wird, wird der Fehler von einem <span style="background-color:Gainsboro">catch</span>-Node
|
<p>Wenn ein Fehler in einem Subflow ausgelöst wird, wird der Fehler von einem catch-Node
|
||||||
innerhalb des Subflows abgefangen.
|
innerhalb des Subflows abgefangen.
|
||||||
Wenn im Subflow keine <span style="background-color:Gainsboro">catch</span>-Nodes vorhanden sind, wird die Fehlermeldung eine Ebene höher zum Flow weitergereicht,
|
Wenn im Subflow keine catch-Nodes vorhanden sind, wird die Fehlermeldung eine Ebene höher zum Flow weitergereicht,
|
||||||
in der sich die Subflow-Instanz befindet.</p>
|
in der sich die Subflow-Instanz befindet.</p>
|
||||||
<p>Wenn die Nachricht bereits über eine <code>error</code>-Eigenschaft verfügt, wird sie nach <code>_error</code> kopiert.</p>
|
<p>Wenn die Nachricht bereits über eine <code>error</code>-Eigenschaft verfügt, wird sie nach <code>_error</code> kopiert.</p>
|
||||||
</script>
|
</script>
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
<script type="text/html" data-help-name="link in">
|
<script type="text/html" data-help-name="link in">
|
||||||
<p>Erstellung virtueller Verbindungen (Links) zwischen Flows.</p>
|
<p>Erstellung virtueller Verbindungen (Links) zwischen Flows.</p>
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
<p>Der Node kann mit jedem beliebigen <span style="background-color:Gainsboro">link out</span>-Node in einen beliebigen Flow-Tab verlinkt werden.
|
<p>Der Node kann mit jedem beliebigen link out-Node in einen beliebigen Flow-Tab verlinkt werden.
|
||||||
Sobald sie verlinkt sind, verhalten sie sich so, als wären sie direkt miteinander verbunden.</p>
|
Sobald sie verlinkt sind, verhalten sie sich so, als wären sie direkt miteinander verbunden.</p>
|
||||||
<p>Die Links zwischen Link-Nodes werden nur angezeigt, wenn ein Link-Node ausgewählt ist.
|
<p>Die Links zwischen Link-Nodes werden nur angezeigt, wenn ein Link-Node ausgewählt ist.
|
||||||
Wenn Links zu anderen Flow-Tabs vorhanden sind, werden virtuelle Link-Nodes als Gegenparts angezeigt,
|
Wenn Links zu anderen Flow-Tabs vorhanden sind, werden virtuelle Link-Nodes als Gegenparts angezeigt,
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<script type="text/html" data-help-name="link out">
|
<script type="text/html" data-help-name="link out">
|
||||||
<p>Erstellung virtueller Verbindungen (Links) zwischen Flows.</p>
|
<p>Erstellung virtueller Verbindungen (Links) zwischen Flows.</p>
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
<p>Der Node kann mit jedem beliebigen <span style="background-color:Gainsboro">link in</span>-Node in einen beliebigen Flow-Tab verlinkt werden.
|
<p>Der Node kann mit jedem beliebigen link in-Node in einen beliebigen Flow-Tab verlinkt werden.
|
||||||
Sobald sie verlinkt sind, verhalten sie sich so, als wären sie direkt miteinander verbunden.</p>
|
Sobald sie verlinkt sind, verhalten sie sich so, als wären sie direkt miteinander verbunden.</p>
|
||||||
<p>Die Links zwischen Link-Nodes werden nur angezeigt, wenn ein Link-Node ausgewählt ist.
|
<p>Die Links zwischen Link-Nodes werden nur angezeigt, wenn ein Link-Node ausgewählt ist.
|
||||||
Wenn Links zu anderen Flow-Tabs vorhanden sind, werden virtuelle Link-Nodes als Gegenparts angezeigt,
|
Wenn Links zu anderen Flow-Tabs vorhanden sind, werden virtuelle Link-Nodes als Gegenparts angezeigt,
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
<li><code>node.error("Fehlermeldungstext")</code></li>
|
<li><code>node.error("Fehlermeldungstext")</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
<p>Der <span style="background-color:Gainsboro">catch</span>-Node kann auch zur Bearbeitung von Fehlern verwendet werden.
|
<p>Der catch-Node kann auch zur Bearbeitung von Fehlern verwendet werden.
|
||||||
Er wird aufgerufen, indem <code>msg</code> als zweites Argument an <code>node.error</code> übergeben wird:</p>
|
Er wird aufgerufen, indem <code>msg</code> als zweites Argument an <code>node.error</code> übergeben wird:</p>
|
||||||
<pre>node.error("Fehlermeldungstext" ,msg);</pre>
|
<pre>node.error("Fehlermeldungstext" ,msg);</pre>
|
||||||
<h4><b>Zugriff auf Node-Informationen</b></h4>
|
<h4><b>Zugriff auf Node-Informationen</b></h4>
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
<ol>
|
<ol>
|
||||||
<li><b>value rules</b>: Regeln werden hinsichtlich einer eingestellten Eigenschaft ausgewertet</li>
|
<li><b>value rules</b>: Regeln werden hinsichtlich einer eingestellten Eigenschaft ausgewertet</li>
|
||||||
<li><b>sequence rules</b>: Regeln beziehen sich auf Nachrichtensequenzen,
|
<li><b>sequence rules</b>: Regeln beziehen sich auf Nachrichtensequenzen,
|
||||||
wie sie beispielsweise durch den <span style="background-color:Gainsboro">split</span>-Node erzeugt werden</li>
|
wie sie beispielsweise durch den split-Node erzeugt werden</li>
|
||||||
<li>Ein <b>JSONata-Ausdruck</b> kann die gesamte Eingangsnachricht auswerten und einen <code>true</code>-Wert zurückliefern,
|
<li>Ein <b>JSONata-Ausdruck</b> kann die gesamte Eingangsnachricht auswerten und einen <code>true</code>-Wert zurückliefern,
|
||||||
um eine Regelerfüllung zu signalisieren</li>
|
um eine Regelerfüllung zu signalisieren</li>
|
||||||
<li>Die <b>ansonsten</b>-Regel wird angewendet, wenn keine vorhergehende Regel übereinstimmt</li>
|
<li>Die <b>ansonsten</b>-Regel wird angewendet, wenn keine vorhergehende Regel übereinstimmt</li>
|
||||||
|
@@ -25,9 +25,9 @@
|
|||||||
<dt class="optional">payload <span class="property-type">string</span></dt>
|
<dt class="optional">payload <span class="property-type">string</span></dt>
|
||||||
<dd>Wird an auszuführenden Befehl angehängt, sofern im Node aktiviert.</dd>
|
<dd>Wird an auszuführenden Befehl angehängt, sofern im Node aktiviert.</dd>
|
||||||
<dt class="optional">kill <span class="property-type">string</span></dt>
|
<dt class="optional">kill <span class="property-type">string</span></dt>
|
||||||
<dd>Typ des Kill-Signals, das an den zu beendenden <span style="background-color:Gainsboro">exec</span>-Node-Prozess gesendet wird.</dd>
|
<dd>Typ des Kill-Signals, das an den zu beendenden exec-Node-Prozess gesendet wird.</dd>
|
||||||
<dt class="optional">pid <span class="property-type">number | string</span></dt>
|
<dt class="optional">pid <span class="property-type">number | string</span></dt>
|
||||||
<dd>Prozess-ID des zu beendenden <span style="background-color:Gainsboro">exec</span>-Node-Prozesses.</dd>
|
<dd>Prozess-ID des zu beendenden exec-Node-Prozesses.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<h3>Ausgangsdaten</h3>
|
<h3>Ausgangsdaten</h3>
|
||||||
<ol class="node-ports">
|
<ol class="node-ports">
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
<p>Die zurückgegebenen Daten (Payload) sind in der Regel eine <i>Zeichenfolge (string)</i>,
|
<p>Die zurückgegebenen Daten (Payload) sind in der Regel eine <i>Zeichenfolge (string)</i>,
|
||||||
außer es werden nicht UTF-8-Zeichen wie bei einem <i>binären Puffer (buffer)</i> erkannt.</p>
|
außer es werden nicht UTF-8-Zeichen wie bei einem <i>binären Puffer (buffer)</i> erkannt.</p>
|
||||||
<p>Bei einem aktiven Node werden Status und die PID angezeigt.
|
<p>Bei einem aktiven Node werden Status und die PID angezeigt.
|
||||||
Änderungen können mittels <span style="background-color:Gainsboro">status</span>-Node gelesen werden.</p>
|
Änderungen können mittels status-Node gelesen werden.</p>
|
||||||
<h4><b>Prozesse beenden</b></h4>
|
<h4><b>Prozesse beenden</b></h4>
|
||||||
<p>Durch Senden von <code>msg.kill</code> wird ein einzelner aktiver Prozess beendet.
|
<p>Durch Senden von <code>msg.kill</code> wird ein einzelner aktiver Prozess beendet.
|
||||||
<code>msg.kill</code> sollte als Zeichenfolge (string) den Signaltyp enthalten,
|
<code>msg.kill</code> sollte als Zeichenfolge (string) den Signaltyp enthalten,
|
||||||
|
@@ -94,7 +94,7 @@
|
|||||||
"label": {
|
"label": {
|
||||||
"source": "Fehler abfangen von",
|
"source": "Fehler abfangen von",
|
||||||
"selectAll": "Alles auswählen",
|
"selectAll": "Alles auswählen",
|
||||||
"uncaught": "Fehler ignorieren, die von anderen <span style=\"background-color:Gainsboro\">catch</span>-Nodes behandelt wurden"
|
"uncaught": "Fehler ignorieren, die von anderen catch-Nodes behandelt wurden"
|
||||||
},
|
},
|
||||||
"scope": {
|
"scope": {
|
||||||
"all": "allen Nodes",
|
"all": "allen Nodes",
|
||||||
@@ -475,12 +475,12 @@
|
|||||||
"json": "Ein parsed JSON-Objekt",
|
"json": "Ein parsed JSON-Objekt",
|
||||||
"tip": {
|
"tip": {
|
||||||
"in": "Die URL ist relativ zu ",
|
"in": "Die URL ist relativ zu ",
|
||||||
"res": "Die an diesen Node gesendeten Nachrichten <b>müssen</b> von einem <span style=\"background-color:Gainsboro\">http in</span>-Node stammen",
|
"res": "Die an diesen Node gesendeten Nachrichten <b>müssen</b> von einem http in-Node stammen",
|
||||||
"req": "Tipp: Wenn die JSON-Syntax-Analyse fehlschlägt, wird die abgerufene Zeichenfolge zurückgegeben, wie sie ist."
|
"req": "Tipp: Wenn die JSON-Syntax-Analyse fehlschlägt, wird die abgerufene Zeichenfolge zurückgegeben, wie sie ist."
|
||||||
},
|
},
|
||||||
"httpreq": "http request",
|
"httpreq": "http request",
|
||||||
"errors": {
|
"errors": {
|
||||||
"not-created": "<span style=\"background-color:Gainsboro\">http in</span>-Node kann nicht erstellt werden, wenn httpNodeRoot auf 'false' gesetzt ist.",
|
"not-created": "http in-Node kann nicht erstellt werden, wenn httpNodeRoot auf 'false' gesetzt ist.",
|
||||||
"missing-path": "Fehlender Pfad",
|
"missing-path": "Fehlender Pfad",
|
||||||
"no-response": "Kein Antwort-Objekt",
|
"no-response": "Kein Antwort-Objekt",
|
||||||
"json-error": "JSON-Parse-Fehler",
|
"json-error": "JSON-Parse-Fehler",
|
||||||
@@ -684,7 +684,7 @@
|
|||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"invalid-expr": "Ungültiger JSONata-Ausdruck: __error__",
|
"invalid-expr": "Ungültiger JSONata-Ausdruck: __error__",
|
||||||
"too-many": "Zu viele anstehende Nachrichten im <span style=\"background-color:Gainsboro\">switch</span>-Node"
|
"too-many": "Zu viele anstehende Nachrichten im switch-Node"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"change": {
|
"change": {
|
||||||
@@ -851,7 +851,6 @@
|
|||||||
"outputas": "Ausgabe",
|
"outputas": "Ausgabe",
|
||||||
"breakchunks": "In Chunks aufteilen",
|
"breakchunks": "In Chunks aufteilen",
|
||||||
"breaklines": "In Linien aufteilen",
|
"breaklines": "In Linien aufteilen",
|
||||||
"filelabel": "file",
|
|
||||||
"sendError": "Nachricht bei Fehler senden (herkömmlicher Modus)",
|
"sendError": "Nachricht bei Fehler senden (herkömmlicher Modus)",
|
||||||
"encoding": "Kodierung",
|
"encoding": "Kodierung",
|
||||||
"deletelabel": "lösche __file__",
|
"deletelabel": "lösche __file__",
|
||||||
@@ -940,8 +939,8 @@
|
|||||||
"afterTimeout": "Bei Zeitablauf nach erster Nachricht von",
|
"afterTimeout": "Bei Zeitablauf nach erster Nachricht von",
|
||||||
"seconds": "Sekunden",
|
"seconds": "Sekunden",
|
||||||
"complete": "Nach Nachricht mit <code>msg.complete</code>-Eigenschaft",
|
"complete": "Nach Nachricht mit <code>msg.complete</code>-Eigenschaft",
|
||||||
"tip": "Dieser Modus setzt voraus, dass dieser Node entweder mit einem <span style=\"background-color:Gainsboro\">split</span>-Node kombiniert ist oder dass die empfangenen Nachrichten über eine ordnungsgemäß konfigurierte <code>msg.parts</code>-Eigenschaft verfügen.",
|
"tip": "Dieser Modus setzt voraus, dass dieser Node entweder mit einem split-Node kombiniert ist oder dass die empfangenen Nachrichten über eine ordnungsgemäß konfigurierte <code>msg.parts</code>-Eigenschaft verfügen.",
|
||||||
"too-many": "Zu viele anstehende Nachrichten im <span style=\"background-color:Gainsboro\">join</span>-Node",
|
"too-many": "Zu viele anstehende Nachrichten im join-Node",
|
||||||
"merge": {
|
"merge": {
|
||||||
"topics-label": "Zusammengeführte Topics",
|
"topics-label": "Zusammengeführte Topics",
|
||||||
"topics": "Topics",
|
"topics": "Topics",
|
||||||
@@ -970,9 +969,9 @@
|
|||||||
"ascending": "aufsteigend",
|
"ascending": "aufsteigend",
|
||||||
"descending": "absteigend",
|
"descending": "absteigend",
|
||||||
"as-number": "als Zahlenwert",
|
"as-number": "als Zahlenwert",
|
||||||
"invalid-exp": "Ungültiger JSONata-Ausdruck in <span style=\"background-color:Gainsboro\">sort</span>-Node: __message__",
|
"invalid-exp": "Ungültiger JSONata-Ausdruck in sort-Node: __message__",
|
||||||
"too-many": "Zu viele anstehende Nachrichten in <span style=\"background-color:Gainsboro\">sort</span>-Node",
|
"too-many": "Zu viele anstehende Nachrichten in sort-Node",
|
||||||
"clear": "Anstehende Nachricht in <span style=\"background-color:Gainsboro\">sort</span>-Node löschen"
|
"clear": "Anstehende Nachricht in sort-Node löschen"
|
||||||
},
|
},
|
||||||
"batch": {
|
"batch": {
|
||||||
"batch": "batch",
|
"batch": "batch",
|
||||||
@@ -997,7 +996,7 @@
|
|||||||
"topics-label": "Topics",
|
"topics-label": "Topics",
|
||||||
"topic": "Topic"
|
"topic": "Topic"
|
||||||
},
|
},
|
||||||
"too-many": "Zu viele anstehende Nachrichten im <span style=\"background-color:Gainsboro\">batch</span>-Node",
|
"too-many": "Zu viele anstehende Nachrichten im batch-Node",
|
||||||
"unexpected": "Unerwarteter Modus",
|
"unexpected": "Unerwarteter Modus",
|
||||||
"no-parts": "Keine parts-Eigenschaft in Nachricht"
|
"no-parts": "Keine parts-Eigenschaft in Nachricht"
|
||||||
},
|
},
|
||||||
|
@@ -94,8 +94,8 @@
|
|||||||
<script type="text/html" data-help-name="mqtt-broker">
|
<script type="text/html" data-help-name="mqtt-broker">
|
||||||
<p>Konfiguration der Verbindung zu einem MQTT-Broker.</p>
|
<p>Konfiguration der Verbindung zu einem MQTT-Broker.</p>
|
||||||
<p>Diese Konfiguration erstellt eine einzelne Verbindung zu einem Broker,
|
<p>Diese Konfiguration erstellt eine einzelne Verbindung zu einem Broker,
|
||||||
welche anschließend von den <span style="background-color:Gainsboro">mqtt in</span>- und
|
welche anschließend von den mqtt in- und
|
||||||
<span style="background-color:Gainsboro">mqtt out</span>-Nodes verwendet werden.</p>
|
mqtt out-Nodes verwendet werden.</p>
|
||||||
<p>Der Node generiert eine beliebige Client-ID, falls sie nicht vorgegeben ist und der
|
<p>Der Node generiert eine beliebige Client-ID, falls sie nicht vorgegeben ist und der
|
||||||
Node eine bereinigte Sitzung (clean session) verwenden soll.
|
Node eine bereinigte Sitzung (clean session) verwenden soll.
|
||||||
Wenn eine Client-ID vorgegeben wird, muss sie für den Broker eindeutig sein, zu dem die Verbindung hergestellt werden soll.</p>
|
Wenn eine Client-ID vorgegeben wird, muss sie für den Broker eindeutig sein, zu dem die Verbindung hergestellt werden soll.</p>
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
<dt>res <span class="property-type">object</span></dt>
|
<dt>res <span class="property-type">object</span></dt>
|
||||||
<dd>HTTP-Antwortobjekt.<br/>
|
<dd>HTTP-Antwortobjekt.<br/>
|
||||||
Diese Eigenschaft sollte nicht direkt verwendet werden.
|
Diese Eigenschaft sollte nicht direkt verwendet werden.
|
||||||
Im <span style="background-color:Gainsboro">http response</span>-Node ist dokumentiert, wie auf eine Anforderung reagiert wird.
|
Im http response-Node ist dokumentiert, wie auf eine Anforderung reagiert wird.
|
||||||
Diese Eigenschaft muss an der Nachricht angehängt bleiben, die an den Antwort-Node übergeben wird.</dd>
|
Diese Eigenschaft muss an der Nachricht angehängt bleiben, die an den Antwort-Node übergeben wird.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
@@ -50,12 +50,12 @@
|
|||||||
<p>Wenn der Inhaltstyp der Anforderung ermittelt werden kann, wird der Hauptteil als passender Typ analysiert.
|
<p>Wenn der Inhaltstyp der Anforderung ermittelt werden kann, wird der Hauptteil als passender Typ analysiert.
|
||||||
Z.B. <code>application/json</code> wird zu einem JavaScript-Objekt analysiert.</p>
|
Z.B. <code>application/json</code> wird zu einem JavaScript-Objekt analysiert.</p>
|
||||||
<p><b>Hinweis</b>: Dieser Node sendet keine Antwort an die Anforderung.
|
<p><b>Hinweis</b>: Dieser Node sendet keine Antwort an die Anforderung.
|
||||||
Der Flow muss einen <span style="background-color:Gainsboro">http response</span>-Node enthalten,
|
Der Flow muss einen http response-Node enthalten,
|
||||||
um die Anforderung zu vervollständigen.</p>
|
um die Anforderung zu vervollständigen.</p>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="http response">
|
<script type="text/html" data-help-name="http response">
|
||||||
<p>Senden von Antworten auf Anforderungen, die von einem <span style="background-color:Gainsboro">http in</span>-Node empfangen wurden.</p>
|
<p>Senden von Antworten auf Anforderungen, die von einem http in-Node empfangen wurden.</p>
|
||||||
<h3>Eingangsdaten</h3>
|
<h3>Eingangsdaten</h3>
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
<dt>payload <span class="property-type">string</span></dt>
|
<dt>payload <span class="property-type">string</span></dt>
|
||||||
|
@@ -34,17 +34,17 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
<dt>schemaError <span class="property-type">array</span></dt>
|
<dt>schemaError <span class="property-type">array</span></dt>
|
||||||
<dd>Wenn die JSON-Schema-Validierung fehlschlägt, wird für den <span style="background-color:Gainsboro">catch</span>-Node eine <code>schemaError</code>-Eigenschaft erstellt,
|
<dd>Wenn die JSON-Schema-Validierung fehlschlägt, wird für den catch-Node eine <code>schemaError</code>-Eigenschaft erstellt,
|
||||||
die ein Array von Fehlern enthält.</dd>
|
die ein Array von Fehlern enthält.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
<p>Standardmäßig verarbeitet der Node <code>msg.payload</code>,
|
<p>Standardmäßig verarbeitet der Node <code>msg.payload</code>,
|
||||||
kann aber auch eine beliebige Nachrichteneigenschaft konvertieren.</p>
|
kann aber auch eine beliebige Nachrichteneigenschaft konvertieren.</p>
|
||||||
<p>Die Konvertierungsrichtung kann im Node auch vorgegeben werden, um eine bestimmte Ziel-Kodierung sicherzustellen.
|
<p>Die Konvertierungsrichtung kann im Node auch vorgegeben werden, um eine bestimmte Ziel-Kodierung sicherzustellen.
|
||||||
Dies kann z.B. zusammen mit dem <span style="background-color:Gainsboro">http in</span>-Node benutzt werden, um sicherzustellen,
|
Dies kann z.B. zusammen mit dem http in-Node benutzt werden, um sicherzustellen,
|
||||||
dass die Nutzdaten (Payload) ein analysiertes (parsed) Objekt ist,
|
dass die Nutzdaten (Payload) ein analysiertes (parsed) Objekt ist,
|
||||||
auch wenn eine eingehende Anfrage seinen Inhaltstyp nicht korrekt eingestellt hat,
|
auch wenn eine eingehende Anfrage seinen Inhaltstyp nicht korrekt eingestellt hat,
|
||||||
damit der <span style="background-color:Gainsboro">http in</span>-Node die Konvertierung durchführen kann.</p>
|
damit der http in-Node die Konvertierung durchführen kann.</p>
|
||||||
<p>Wenn der Node auf Zeichenfolgen-Eingang (string) eingestellt ist und es einen String empfängt,
|
<p>Wenn der Node auf Zeichenfolgen-Eingang (string) eingestellt ist und es einen String empfängt,
|
||||||
werden keine weiteren Prüfungen der Eigenschaft durchgeführt.
|
werden keine weiteren Prüfungen der Eigenschaft durchgeführt.
|
||||||
Der Node prüft weder, ob die Zeichenfolge (string) ein gültiges JSON enthält, noch wird er ihn neu formatieren,
|
Der Node prüft weder, ob die Zeichenfolge (string) ein gültiges JSON enthält, noch wird er ihn neu formatieren,
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
<dt>parts <span class="property-type">object</span></dt>
|
<dt>parts <span class="property-type">object</span></dt>
|
||||||
<dd>Diese Eigenschaft enthält Informationen darüber, wie die Nachricht von der ursprünglichen Nachricht abgeteilt wurde.
|
<dd>Diese Eigenschaft enthält Informationen darüber, wie die Nachricht von der ursprünglichen Nachricht abgeteilt wurde.
|
||||||
Bei Übergabe an ein <span style="background-color:Gainsboro">join</span>-Node kann die Sequenz wieder zu einer einzigen Nachricht zusammengeführt werden.
|
Bei Übergabe an ein join-Node kann die Sequenz wieder zu einer einzigen Nachricht zusammengeführt werden.
|
||||||
Diese Eigenschaft hat die folgenden Eigenschaften:
|
Diese Eigenschaft hat die folgenden Eigenschaften:
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>id</code>: Identifikator der Nachrichten-Gruppe</li>
|
<li><code>id</code>: Identifikator der Nachrichten-Gruppe</li>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
</dl>
|
</dl>
|
||||||
<h3>Details</h3>
|
<h3>Details</h3>
|
||||||
<p>Dieser Node macht es einfach, einen Flow zu erstellen, der gemeinsame Aktionen über eine Sequenz von Nachrichten ausführt,
|
<p>Dieser Node macht es einfach, einen Flow zu erstellen, der gemeinsame Aktionen über eine Sequenz von Nachrichten ausführt,
|
||||||
bevor die Sequenz mittels <span style="background-color:Gainsboro">join</span>-Node wieder zu einer einzigen Nachricht neu kombiniert wird.</p>
|
bevor die Sequenz mittels join-Node wieder zu einer einzigen Nachricht neu kombiniert wird.</p>
|
||||||
<p>Der Node verwendet die <code>msg.parts</code>-Eigenschaft, um die einzelnen Sequenzteile nachzuverfolgen.</p>
|
<p>Der Node verwendet die <code>msg.parts</code>-Eigenschaft, um die einzelnen Sequenzteile nachzuverfolgen.</p>
|
||||||
<h4><b>Streaming-Modus</b></h4>
|
<h4><b>Streaming-Modus</b></h4>
|
||||||
<p>Der Node kann auch zum Aufbereiten eines Nachrichtenstroms verwendet werden.
|
<p>Der Node kann auch zum Aufbereiten eines Nachrichtenstroms verwendet werden.
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
so wird es im Node aufbewahrt und der nächsten empfangenen Nachricht vorangestellt.</p>
|
so wird es im Node aufbewahrt und der nächsten empfangenen Nachricht vorangestellt.</p>
|
||||||
<p>In diesem Modus wird die <code>msg.parts.count</code>-Eigenschaft nicht gesetzt,
|
<p>In diesem Modus wird die <code>msg.parts.count</code>-Eigenschaft nicht gesetzt,
|
||||||
da die Anzahl der zu erwartenden Nachrichten im Stream unbekannt ist.
|
da die Anzahl der zu erwartenden Nachrichten im Stream unbekannt ist.
|
||||||
Das bedeutet, dass ein nachfolgender <span style="background-color:Gainsboro">join</span>-Node nicht im Automatikmodus verwendet werden kann.</p>
|
Das bedeutet, dass ein nachfolgender join-Node nicht im Automatikmodus verwendet werden kann.</p>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="join">
|
<script type="text/html" data-help-name="join">
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
<p>Es sind drei Modi verfügbar:</p>
|
<p>Es sind drei Modi verfügbar:</p>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Automatisch</dt>
|
<dt>Automatisch</dt>
|
||||||
<dd>In Kombination mit dem <span style="background-color:Gainsboro">split</span>-Node verbindet es automatisch die Nachrichten, um die zuvor durchgeführte Aufteilung rückgängig zu machen.</dd>
|
<dd>In Kombination mit dem split-Node verbindet es automatisch die Nachrichten, um die zuvor durchgeführte Aufteilung rückgängig zu machen.</dd>
|
||||||
<dt>Manuell</dt>
|
<dt>Manuell</dt>
|
||||||
<dd>Die Nachrichtensequenzen können auf verschiedene Weisen verbunden werden.</dd>
|
<dd>Die Nachrichtensequenzen können auf verschiedene Weisen verbunden werden.</dd>
|
||||||
<dt>Sequenz reduzieren</dt>
|
<dt>Sequenz reduzieren</dt>
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
<dt class="optional">parts <span class="property-type">object</span></dt>
|
<dt class="optional">parts <span class="property-type">object</span></dt>
|
||||||
<dd>Zur automatischen Verbindung einer Nachrichtensequenz sollten alle über diese Eigenschaft verfügen.
|
<dd>Zur automatischen Verbindung einer Nachrichtensequenz sollten alle über diese Eigenschaft verfügen.
|
||||||
Der <span style="background-color:Gainsboro">split</span>-Node erzeugt diese Eigenschaft, sie kann aber auch manuell erstellt werden.
|
Der split-Node erzeugt diese Eigenschaft, sie kann aber auch manuell erstellt werden.
|
||||||
Sie hat die folgenden Eigenschaften:
|
Sie hat die folgenden Eigenschaften:
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>id</code>: Identifikator der Nachrichten-Gruppe</li>
|
<li><code>id</code>: Identifikator der Nachrichten-Gruppe</li>
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
<h4><b>Automatischer Modus</b></h4>
|
<h4><b>Automatischer Modus</b></h4>
|
||||||
<p>Der automatische Modus verwendet die <code>parts</code>-Eigenschaften der eingehenden Nachrichten,
|
<p>Der automatische Modus verwendet die <code>parts</code>-Eigenschaften der eingehenden Nachrichten,
|
||||||
um die Sequenz in richtiger Reihenfolge zu verknüpften.
|
um die Sequenz in richtiger Reihenfolge zu verknüpften.
|
||||||
Dies ermöglicht die Aufteilung des <span style="background-color:Gainsboro">split</span>-Nodes automatisch rückgängig zu machen.</p>
|
Dies ermöglicht die Aufteilung des split-Nodes automatisch rückgängig zu machen.</p>
|
||||||
|
|
||||||
<h4><b>Manueller Modus</b></h4>
|
<h4><b>Manueller Modus</b></h4>
|
||||||
<p>Im manuellen Modus werden Nachrichtensequenzen auf verschiedenen Arten zusammengefügt:</p>
|
<p>Im manuellen Modus werden Nachrichtensequenzen auf verschiedenen Arten zusammengefügt:</p>
|
||||||
|
@@ -26,8 +26,8 @@
|
|||||||
<p>Für Zahlenwerte kann die numerische Sortierreihenfolge festgelegt werden.</p>
|
<p>Für Zahlenwerte kann die numerische Sortierreihenfolge festgelegt werden.</p>
|
||||||
<p>Der Sortierschlüssel kann ein Elementwert oder ein JSONata-Ausdruck beim Sortieren einer Nachrichteneigenschaft
|
<p>Der Sortierschlüssel kann ein Elementwert oder ein JSONata-Ausdruck beim Sortieren einer Nachrichteneigenschaft
|
||||||
bzw. eine Nachrichteneigenschaft oder ein JSONata-Ausdruck beim Sortieren einer Nachrichtensequenz sein.<p>
|
bzw. eine Nachrichteneigenschaft oder ein JSONata-Ausdruck beim Sortieren einer Nachrichtensequenz sein.<p>
|
||||||
<p>Zum Sortieren einer Nachrichtensequenz benötigt der <span style="background-color:Gainsboro">sort</span>-Node die gesetzte <code>msg.parts</code>-Eigenschaft bei den empfangenen Nachrichten.
|
<p>Zum Sortieren einer Nachrichtensequenz benötigt der sort-Node die gesetzte <code>msg.parts</code>-Eigenschaft bei den empfangenen Nachrichten.
|
||||||
Diese Eigenschaft wird vom <span style="background-color:Gainsboro">split</span>-Node erzeugt und kann aber auch manuell erzeugt werden.
|
Diese Eigenschaft wird vom split-Node erzeugt und kann aber auch manuell erzeugt werden.
|
||||||
Sie hat die folgenden Eigenschaften:</p>
|
Sie hat die folgenden Eigenschaften:</p>
|
||||||
<p>
|
<p>
|
||||||
<ul>
|
<ul>
|
||||||
|
@@ -58,5 +58,5 @@
|
|||||||
aber typischerweise 64k (Linux/Mac) oder 41k (Windows).</p>
|
aber typischerweise 64k (Linux/Mac) oder 41k (Windows).</p>
|
||||||
<p>Bei Aufteilung in mehrere Nachrichten besitzt jede eine <code>parts</code>-Eigenschaft,
|
<p>Bei Aufteilung in mehrere Nachrichten besitzt jede eine <code>parts</code>-Eigenschaft,
|
||||||
welche eine komplette Nachrichten-Sequenz bildet.</p>
|
welche eine komplette Nachrichten-Sequenz bildet.</p>
|
||||||
<p>Fehler sollten mittels <span style="background-color:Gainsboro">catch</span>-Nodes abgefangen und behandelt werden.</p>
|
<p>Fehler sollten mittels catch-Nodes abgefangen und behandelt werden.</p>
|
||||||
</script>
|
</script>
|
||||||
|
@@ -143,12 +143,17 @@
|
|||||||
"filterSelected": "selected nodes",
|
"filterSelected": "selected nodes",
|
||||||
"filterCurrent": "current flow",
|
"filterCurrent": "current flow",
|
||||||
"debugNodes": "Debug nodes",
|
"debugNodes": "Debug nodes",
|
||||||
"clearLog": "Clear log",
|
"clearLog": "Clear messages",
|
||||||
"filterLog": "Filter log",
|
"clearFilteredLog": "Clear filtered messages",
|
||||||
|
"filterLog": "Filter messages",
|
||||||
"openWindow": "Open in new window",
|
"openWindow": "Open in new window",
|
||||||
"copyPath": "Copy path",
|
"copyPath": "Copy path",
|
||||||
"copyPayload": "Copy value",
|
"copyPayload": "Copy value",
|
||||||
"pinPath": "Pin open"
|
"pinPath": "Pin open",
|
||||||
|
"selectAll": "select all",
|
||||||
|
"selectNone": "select none",
|
||||||
|
"all": "all",
|
||||||
|
"filtered": "filtered"
|
||||||
},
|
},
|
||||||
"messageMenu": {
|
"messageMenu": {
|
||||||
"collapseAll": "Collapse all paths",
|
"collapseAll": "Collapse all paths",
|
||||||
@@ -411,7 +416,11 @@
|
|||||||
"maximumPacketSize": "Max Packet Size",
|
"maximumPacketSize": "Max Packet Size",
|
||||||
"receiveMaximum": "Receive Max",
|
"receiveMaximum": "Receive Max",
|
||||||
"session": "Session",
|
"session": "Session",
|
||||||
"delay": "Delay"
|
"delay": "Delay",
|
||||||
|
"action": "Action",
|
||||||
|
"staticTopic": "Subscribe to single topic",
|
||||||
|
"dynamicTopic": "Dynamic subscription",
|
||||||
|
"auto-connect": "Connect automatically"
|
||||||
},
|
},
|
||||||
"sections-label":{
|
"sections-label":{
|
||||||
"birth-message": "Message sent on connection (birth message)",
|
"birth-message": "Message sent on connection (birth message)",
|
||||||
@@ -452,7 +461,10 @@
|
|||||||
"invalid-topic": "Invalid topic specified",
|
"invalid-topic": "Invalid topic specified",
|
||||||
"nonclean-missingclientid": "No client ID set, using clean session",
|
"nonclean-missingclientid": "No client ID set, using clean session",
|
||||||
"invalid-json-string": "Invalid JSON string",
|
"invalid-json-string": "Invalid JSON string",
|
||||||
"invalid-json-parse": "Failed to parse JSON string"
|
"invalid-json-parse": "Failed to parse JSON string",
|
||||||
|
"invalid-action-action": "Invalid action specified",
|
||||||
|
"invalid-action-alreadyconnected": "Disconnect from broker before connecting",
|
||||||
|
"invalid-action-badsubscription": "msg.topic is missing or invalid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"httpin": {
|
"httpin": {
|
||||||
|
@@ -40,6 +40,38 @@
|
|||||||
<p>This node requires a connection to a MQTT broker to be configured. This is configured by clicking
|
<p>This node requires a connection to a MQTT broker to be configured. This is configured by clicking
|
||||||
the pencil icon.</p>
|
the pencil icon.</p>
|
||||||
<p>Several MQTT nodes (in or out) can share the same broker connection if required.</p>
|
<p>Several MQTT nodes (in or out) can share the same broker connection if required.</p>
|
||||||
|
<h4>Dynamic Subscription</h4>
|
||||||
|
The node can be configured to dynamically control the MQTT connection and its subscriptions. When
|
||||||
|
enabled, the node will have an input and can be controlled by passing it messages.
|
||||||
|
<h3>Inputs</h3>
|
||||||
|
<p>These only apply when the node has been configured for dynamic subscriptions.</p>
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>action <span class="property-type">string</span></dt>
|
||||||
|
<dd>the name of the action the node should perform. Available actions are: <code>"connect"</code>,
|
||||||
|
<code>"disconnect"</code>, <code>"subscribe"</code> and <code>"unsubscribe"</code>.</dd>
|
||||||
|
<dt class="optional">topic <span class="property-type">string|object|array</span></dt>
|
||||||
|
<dd>For the <code>"subscribe"</code> and <code>"unsubscribe"</code> actions, this property
|
||||||
|
provides the topic. It can be set as either:<ul>
|
||||||
|
<li>a String continaing the topic filter</li>
|
||||||
|
<li>an Object containing <code>topic</code> and <code>qos</code> properties</li>
|
||||||
|
<li>an array of either strings or objects to handle multiple topics in one</li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
<dt class="optional">broker <span class="property-type">broker</span> </dt>
|
||||||
|
<dd>For the <code>"connect"</code> action, this property can override any
|
||||||
|
of the individual broker configuration settings, including: <ul>
|
||||||
|
<li><code>broker</code></li>
|
||||||
|
<li><code>port</code></li>
|
||||||
|
<li><code>url</code> - overrides broker/port to provide a complete connection url</li>
|
||||||
|
<li><code>username</code></li>
|
||||||
|
<li><code>password</code></li>
|
||||||
|
</ul>
|
||||||
|
<p>If this property is set and the broker is already connected an error
|
||||||
|
will be logged unless it has the <code>force</code> property set - in which case it will
|
||||||
|
disconnect from the broker, apply the new settings and reconnect.</p>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="mqtt out">
|
<script type="text/html" data-help-name="mqtt out">
|
||||||
@@ -78,6 +110,30 @@
|
|||||||
<p>This node requires a connection to a MQTT broker to be configured. This is configured by clicking
|
<p>This node requires a connection to a MQTT broker to be configured. This is configured by clicking
|
||||||
the pencil icon.</p>
|
the pencil icon.</p>
|
||||||
<p>Several MQTT nodes (in or out) can share the same broker connection if required.</p>
|
<p>Several MQTT nodes (in or out) can share the same broker connection if required.</p>
|
||||||
|
|
||||||
|
<h4>Dynamic Control</h4>
|
||||||
|
The connection shared by the node can be controlled dynamically. If the node receives
|
||||||
|
one of the following control messages, it will not publish the message payload as well.
|
||||||
|
<h3>Inputs</h3>
|
||||||
|
<dl class="message-properties">
|
||||||
|
<dt>action <span class="property-type">string</span></dt>
|
||||||
|
<dd>the name of the action the node should perform. Available actions are: <code>"connect"</code>,
|
||||||
|
and <code>"disconnect"</code>.</dd>
|
||||||
|
<dt class="optional">broker <span class="property-type">broker</span> </dt>
|
||||||
|
<dd>For the <code>"connect"</code> action, this property can override any
|
||||||
|
of the individual broker configuration settings, including: <ul>
|
||||||
|
<li><code>broker</code></li>
|
||||||
|
<li><code>port</code></li>
|
||||||
|
<li><code>url</code> - overrides broker/port to provide a complete connection url</li>
|
||||||
|
<li><code>username</code></li>
|
||||||
|
<li><code>password</code></li>
|
||||||
|
</ul>
|
||||||
|
<p>If this property is set and the broker is already connected an error
|
||||||
|
will be logged unless it has the <code>force</code> property set - in which case it will
|
||||||
|
disconnect from the broker, apply the new settings and reconnect.</p>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" data-help-name="mqtt-broker">
|
<script type="text/html" data-help-name="mqtt-broker">
|
||||||
|
@@ -29,3 +29,12 @@
|
|||||||
<p>linkノード間のリンクはlinkノードを選択した場合にのみ表示されます。他のタブへのリンクがある場合には、仮想的なノードを表示します。この仮想的ノードをクリックすると、対応するタブに移動できます。</p>
|
<p>linkノード間のリンクはlinkノードを選択した場合にのみ表示されます。他のタブへのリンクがある場合には、仮想的なノードを表示します。この仮想的ノードをクリックすると、対応するタブに移動できます。</p>
|
||||||
<p><b>注: </b>サブフローの外から中、もしくは、中から外へのリンクを作成することはできません。</p>
|
<p><b>注: </b>サブフローの外から中、もしくは、中から外へのリンクを作成することはできません。</p>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" data-help-name="link call">
|
||||||
|
<p><code>link in</code> で始まり、応答を返すフローを呼び出します。</p>
|
||||||
|
<h3>詳細</h3>
|
||||||
|
<p>本ノードは、任意のタブ内に存在する <code>link in</code> ノードに接続できます。 接続先のフローは、`返却`モードが設定された <code>link out</code> ノードで終了する必要があります。</p>
|
||||||
|
<p>本ノードはメッセージを受信すると、メッセージを接続した <code>link in</code> ノードへ渡します。
|
||||||
|
その後、応答を待った後にメッセージを送信します。</o>
|
||||||
|
<p>もし、設定したタイムアウト(デフォルト30秒)以内に応答がない場合は、<code>catch</code> ノードを用いてエラーをログに記録することもできます。</p>
|
||||||
|
</script>
|
||||||
|
@@ -144,11 +144,16 @@
|
|||||||
"filterCurrent": "現在のフロー",
|
"filterCurrent": "現在のフロー",
|
||||||
"debugNodes": "debugノード",
|
"debugNodes": "debugノード",
|
||||||
"clearLog": "ログを削除",
|
"clearLog": "ログを削除",
|
||||||
|
"clearFilteredLog": "選択したメッセージを削除",
|
||||||
"filterLog": "ログのフィルタリング",
|
"filterLog": "ログのフィルタリング",
|
||||||
"openWindow": "新しいウィンドウで開く",
|
"openWindow": "新しいウィンドウで開く",
|
||||||
"copyPath": "パスをコピー",
|
"copyPath": "パスをコピー",
|
||||||
"copyPayload": "値をコピー",
|
"copyPayload": "値をコピー",
|
||||||
"pinPath": "展開を固定"
|
"pinPath": "展開を固定",
|
||||||
|
"selectAll": "全てを選択",
|
||||||
|
"selectNone": "選択を外す",
|
||||||
|
"all": "全て",
|
||||||
|
"filtered": "選択したメッセージ"
|
||||||
},
|
},
|
||||||
"messageMenu": {
|
"messageMenu": {
|
||||||
"collapseAll": "全パスを折りたたむ",
|
"collapseAll": "全パスを折りたたむ",
|
||||||
@@ -159,7 +164,15 @@
|
|||||||
},
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"linkIn": "link in",
|
"linkIn": "link in",
|
||||||
"linkOut": "link out"
|
"linkOut": "link out",
|
||||||
|
"linkCall": "link call",
|
||||||
|
"linkOutReturn": "link return",
|
||||||
|
"outMode": "モード",
|
||||||
|
"sendToAll": "接続された全てのlinkノードへ送信",
|
||||||
|
"returnToCaller": "link callノードへ返却",
|
||||||
|
"error": {
|
||||||
|
"missingReturn": "返却するノードの情報が存在しません"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"tls": {
|
"tls": {
|
||||||
"tls": "TLS設定",
|
"tls": "TLS設定",
|
||||||
@@ -282,7 +295,9 @@
|
|||||||
"and": "回/",
|
"and": "回/",
|
||||||
"rate": "流量",
|
"rate": "流量",
|
||||||
"msgper": "メッセージ/",
|
"msgper": "メッセージ/",
|
||||||
|
"queuemsg": "中間メッセージをキューに追加",
|
||||||
"dropmsg": "中間メッセージを削除",
|
"dropmsg": "中間メッセージを削除",
|
||||||
|
"sendmsg": "2番目の出力で中間メッセージを送信",
|
||||||
"allowrate": "msg.rate(ミリ秒単位)で流量値を上書き",
|
"allowrate": "msg.rate(ミリ秒単位)で流量値を上書き",
|
||||||
"label": {
|
"label": {
|
||||||
"delay": "delay",
|
"delay": "delay",
|
||||||
@@ -401,7 +416,11 @@
|
|||||||
"maximumPacketSize": "最大パケット長",
|
"maximumPacketSize": "最大パケット長",
|
||||||
"receiveMaximum": "最大受信数",
|
"receiveMaximum": "最大受信数",
|
||||||
"session": "セッション",
|
"session": "セッション",
|
||||||
"delay": "遅延"
|
"delay": "遅延",
|
||||||
|
"action": "動作",
|
||||||
|
"staticTopic": "1つのトピックを購読",
|
||||||
|
"dynamicTopic": "動的な購読",
|
||||||
|
"auto-connect": "自動接続"
|
||||||
},
|
},
|
||||||
"sections-label": {
|
"sections-label": {
|
||||||
"birth-message": "接続時の送信メッセージ(Birthメッセージ)",
|
"birth-message": "接続時の送信メッセージ(Birthメッセージ)",
|
||||||
@@ -442,7 +461,10 @@
|
|||||||
"invalid-topic": "不正なトピックが設定されています",
|
"invalid-topic": "不正なトピックが設定されています",
|
||||||
"nonclean-missingclientid": "「セッションの初期化」使用時に、クライアントIDが設定されていません",
|
"nonclean-missingclientid": "「セッションの初期化」使用時に、クライアントIDが設定されていません",
|
||||||
"invalid-json-string": "不正なJSON文字列",
|
"invalid-json-string": "不正なJSON文字列",
|
||||||
"invalid-json-parse": "JSON文字列のパースに失敗しました"
|
"invalid-json-parse": "JSON文字列のパースに失敗しました",
|
||||||
|
"invalid-action-action": "指定された動作が不正です",
|
||||||
|
"invalid-action-alreadyconnected": "接続する前にブローカから切断してください",
|
||||||
|
"invalid-action-badsubscription": "msg.topicが存在しないか不正です"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"httpin": {
|
"httpin": {
|
||||||
@@ -478,6 +500,7 @@
|
|||||||
"proxy-config": "プロキシ設定",
|
"proxy-config": "プロキシ設定",
|
||||||
"use-proxyauth": "プロキシ認証を使用",
|
"use-proxyauth": "プロキシ認証を使用",
|
||||||
"noproxy-hosts": "例外ホスト",
|
"noproxy-hosts": "例外ホスト",
|
||||||
|
"senderr": "2xx以外の応答をcatchノードへ送信",
|
||||||
"utf8": "UTF8文字列",
|
"utf8": "UTF8文字列",
|
||||||
"binary": "バイナリバッファ",
|
"binary": "バイナリバッファ",
|
||||||
"json": "JSONオブジェクト",
|
"json": "JSONオブジェクト",
|
||||||
@@ -703,13 +726,15 @@
|
|||||||
"delete": "delete __property__",
|
"delete": "delete __property__",
|
||||||
"move": "move __property__",
|
"move": "move __property__",
|
||||||
"changeCount": "change: __count__ rules",
|
"changeCount": "change: __count__ rules",
|
||||||
"regex": "正規表現を使用"
|
"regex": "正規表現を使用",
|
||||||
|
"deepCopy": "値のディープコピー"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"set": "値の代入",
|
"set": "値の代入",
|
||||||
"change": "値の置換",
|
"change": "値の置換",
|
||||||
"delete": "値の削除",
|
"delete": "値の削除",
|
||||||
"move": "値の移動",
|
"move": "値の移動",
|
||||||
|
"toValue": "対象の値",
|
||||||
"to": "対象の値",
|
"to": "対象の値",
|
||||||
"search": "検索する文字列",
|
"search": "検索する文字列",
|
||||||
"replace": "置換後の文字列"
|
"replace": "置換後の文字列"
|
||||||
@@ -851,6 +876,8 @@
|
|||||||
},
|
},
|
||||||
"file": {
|
"file": {
|
||||||
"label": {
|
"label": {
|
||||||
|
"write": "write file",
|
||||||
|
"read": "read file",
|
||||||
"filename": "ファイル名",
|
"filename": "ファイル名",
|
||||||
"action": "動作",
|
"action": "動作",
|
||||||
"addnewline": "メッセージの入力のたびに改行を追加",
|
"addnewline": "メッセージの入力のたびに改行を追加",
|
||||||
@@ -858,7 +885,6 @@
|
|||||||
"outputas": "出力形式",
|
"outputas": "出力形式",
|
||||||
"breakchunks": "チャンクへ分割",
|
"breakchunks": "チャンクへ分割",
|
||||||
"breaklines": "行へ分割",
|
"breaklines": "行へ分割",
|
||||||
"filelabel": "file",
|
|
||||||
"sendError": "エラーメッセージを送信(互換モード)",
|
"sendError": "エラーメッセージを送信(互換モード)",
|
||||||
"encoding": "文字コード",
|
"encoding": "文字コード",
|
||||||
"deletelabel": "delete __file__",
|
"deletelabel": "delete __file__",
|
||||||
|
@@ -771,7 +771,6 @@
|
|||||||
"outputas": "출력형식",
|
"outputas": "출력형식",
|
||||||
"breakchunks": "청크로 분할",
|
"breakchunks": "청크로 분할",
|
||||||
"breaklines": "행으로 분할",
|
"breaklines": "행으로 분할",
|
||||||
"filelabel": "file",
|
|
||||||
"sendError": "에러메세지를 송신(호환모드)",
|
"sendError": "에러메세지를 송신(호환모드)",
|
||||||
"deletelabel": "delete __file__",
|
"deletelabel": "delete __file__",
|
||||||
"utf8String": "UTF8문자열",
|
"utf8String": "UTF8문자열",
|
||||||
|
@@ -816,7 +816,6 @@
|
|||||||
"outputas": "Выход",
|
"outputas": "Выход",
|
||||||
"breakchunks": "Разбить файл на части",
|
"breakchunks": "Разбить файл на части",
|
||||||
"breaklines": "Разбить на строки",
|
"breaklines": "Разбить на строки",
|
||||||
"filelabel": "файл",
|
|
||||||
"sendError": "Отправлять сообщение при ошибке (устаревший режим)",
|
"sendError": "Отправлять сообщение при ошибке (устаревший режим)",
|
||||||
"encoding": "Кодировка",
|
"encoding": "Кодировка",
|
||||||
"deletelabel": "удалить __file__",
|
"deletelabel": "удалить __file__",
|
||||||
|
@@ -804,7 +804,6 @@
|
|||||||
"outputas": "输出",
|
"outputas": "输出",
|
||||||
"breakchunks": "分拆成块",
|
"breakchunks": "分拆成块",
|
||||||
"breaklines": "分拆成行",
|
"breaklines": "分拆成行",
|
||||||
"filelabel": "文件",
|
|
||||||
"sendError": "发生错误时发送消息(传统模式)",
|
"sendError": "发生错误时发送消息(传统模式)",
|
||||||
"encoding": "编码",
|
"encoding": "编码",
|
||||||
"deletelabel": "删除 __file__",
|
"deletelabel": "删除 __file__",
|
||||||
|
@@ -809,7 +809,6 @@
|
|||||||
"outputas": "輸出",
|
"outputas": "輸出",
|
||||||
"breakchunks": "分拆成塊",
|
"breakchunks": "分拆成塊",
|
||||||
"breaklines": "分拆成行",
|
"breaklines": "分拆成行",
|
||||||
"filelabel": "文件",
|
|
||||||
"sendError": "發生錯誤時發送消息(傳統模式)",
|
"sendError": "發生錯誤時發送消息(傳統模式)",
|
||||||
"encoding": "編碼",
|
"encoding": "編碼",
|
||||||
"deletelabel": "刪除 __file__",
|
"deletelabel": "刪除 __file__",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/nodes",
|
"name": "@node-red/nodes",
|
||||||
"version": "2.1.0-beta.1",
|
"version": "2.2.0-beta.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -15,13 +15,13 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "8.5.0",
|
"acorn": "8.6.0",
|
||||||
"acorn-walk": "8.2.0",
|
"acorn-walk": "8.2.0",
|
||||||
"ajv": "8.6.3",
|
"ajv": "8.8.2",
|
||||||
"body-parser": "1.19.0",
|
"body-parser": "1.19.0",
|
||||||
"cheerio": "1.0.0-rc.10",
|
"cheerio": "1.0.0-rc.10",
|
||||||
"content-type": "1.0.4",
|
"content-type": "1.0.4",
|
||||||
"cookie-parser": "1.4.5",
|
"cookie-parser": "1.4.6",
|
||||||
"cookie": "0.4.1",
|
"cookie": "0.4.1",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"cronosjs": "1.7.1",
|
"cronosjs": "1.7.1",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"form-data": "4.0.0",
|
"form-data": "4.0.0",
|
||||||
"fs-extra": "10.0.0",
|
"fs-extra": "10.0.0",
|
||||||
"fs.notify": "0.0.4",
|
"fs.notify": "0.0.4",
|
||||||
"got": "11.8.2",
|
"got": "11.8.3",
|
||||||
"hash-sum": "2.0.0",
|
"hash-sum": "2.0.0",
|
||||||
"hpagent": "0.1.2",
|
"hpagent": "0.1.2",
|
||||||
"https-proxy-agent": "5.0.0",
|
"https-proxy-agent": "5.0.0",
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
"multer": "1.4.3",
|
"multer": "1.4.3",
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
"on-headers": "1.0.2",
|
"on-headers": "1.0.2",
|
||||||
"raw-body": "2.4.1",
|
"raw-body": "2.4.2",
|
||||||
"tough-cookie": "4.0.0",
|
"tough-cookie": "4.0.0",
|
||||||
"uuid": "8.3.2",
|
"uuid": "8.3.2",
|
||||||
"ws": "7.5.1",
|
"ws": "7.5.1",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/registry",
|
"name": "@node-red/registry",
|
||||||
"version": "2.1.0-beta.1",
|
"version": "2.2.0-beta.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -16,11 +16,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/util": "2.1.0-beta.1",
|
"@node-red/util": "2.2.0-beta.1",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"fs-extra": "10.0.0",
|
"fs-extra": "10.0.0",
|
||||||
"semver": "7.3.5",
|
"semver": "7.3.5",
|
||||||
"tar": "6.1.11",
|
"tar": "6.1.11",
|
||||||
"uglify-js": "3.14.2"
|
"uglify-js": "3.14.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -439,8 +439,6 @@ class Flow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [env.name, env];
|
return [env.name, env];
|
||||||
|
|
||||||
return [env.name, env];
|
|
||||||
});
|
});
|
||||||
group._env = Object.fromEntries(entries);
|
group._env = Object.fromEntries(entries);
|
||||||
}
|
}
|
||||||
@@ -457,24 +455,24 @@ class Flow {
|
|||||||
const val
|
const val
|
||||||
= ((value === "true") ||
|
= ((value === "true") ||
|
||||||
(value === true));
|
(value === true));
|
||||||
return {
|
return [{
|
||||||
val: val
|
val: val
|
||||||
};
|
}, null];
|
||||||
}
|
}
|
||||||
if (type === "cred") {
|
if (type === "cred") {
|
||||||
return {
|
return [{
|
||||||
val: value
|
val: value
|
||||||
};
|
}, null];
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
var val = redUtil.evaluateNodeProperty(value, type, node, null, null);
|
var val = redUtil.evaluateNodeProperty(value, type, node, null, null);
|
||||||
return {
|
return [{
|
||||||
val: val
|
val: val
|
||||||
};
|
}, null];
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
this.error(e);
|
this.error(e);
|
||||||
return null;
|
return [null, null];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -488,7 +486,7 @@ class Flow {
|
|||||||
return this.getGroupEnvSetting(node, parent, name);
|
return this.getGroupEnvSetting(node, parent, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return [null, name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -545,6 +543,9 @@ class Flow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
key = key.substring(8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this.parent.getSetting(key);
|
return this.parent.getSetting(key);
|
||||||
}
|
}
|
||||||
|
@@ -373,10 +373,11 @@ class Subflow extends Flow {
|
|||||||
const node = this.subflowInstance;
|
const node = this.subflowInstance;
|
||||||
if (node.g) {
|
if (node.g) {
|
||||||
const group = this.getGroupNode(node.g);
|
const group = this.getGroupNode(node.g);
|
||||||
const result = this.getGroupEnvSetting(node, group, name);
|
const [result, newName] = this.getGroupEnvSetting(node, group, name);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result.val;
|
return result.val;
|
||||||
}
|
}
|
||||||
|
name = newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/runtime",
|
"name": "@node-red/runtime",
|
||||||
"version": "2.1.0-beta.1",
|
"version": "2.2.0-beta.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/registry": "2.1.0-beta.1",
|
"@node-red/registry": "2.2.0-beta.1",
|
||||||
"@node-red/util": "2.1.0-beta.1",
|
"@node-red/util": "2.2.0-beta.1",
|
||||||
"async-mutex": "0.3.2",
|
"async-mutex": "0.3.2",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
|
@@ -136,8 +136,6 @@ function getCurrentLocale() {
|
|||||||
|
|
||||||
function init(settings) {
|
function init(settings) {
|
||||||
if (!initPromise) {
|
if (!initPromise) {
|
||||||
// Keep this as a 'when' promise as top-level red.js uses 'otherwise'
|
|
||||||
// and embedded users of NR may have copied that.
|
|
||||||
initPromise = new Promise((resolve,reject) => {
|
initPromise = new Promise((resolve,reject) => {
|
||||||
i18n.use(MessageFileLoader);
|
i18n.use(MessageFileLoader);
|
||||||
var opt = {
|
var opt = {
|
||||||
@@ -146,6 +144,8 @@ function init(settings) {
|
|||||||
defaultNS: "runtime",
|
defaultNS: "runtime",
|
||||||
ns: [],
|
ns: [],
|
||||||
fallbackLng: defaultLang,
|
fallbackLng: defaultLang,
|
||||||
|
keySeparator: ".",
|
||||||
|
nsSeparator: ":",
|
||||||
interpolation: {
|
interpolation: {
|
||||||
unescapeSuffix: 'HTML',
|
unescapeSuffix: 'HTML',
|
||||||
escapeValue: false,
|
escapeValue: false,
|
||||||
|
12
packages/node_modules/@node-red/util/lib/util.js
vendored
12
packages/node_modules/@node-red/util/lib/util.js
vendored
@@ -526,10 +526,11 @@ function getSetting(node, name, flow_) {
|
|||||||
if (flow) {
|
if (flow) {
|
||||||
if (node && node.g) {
|
if (node && node.g) {
|
||||||
const group = flow.getGroupNode(node.g);
|
const group = flow.getGroupNode(node.g);
|
||||||
const result = flow.getGroupEnvSetting(node, group, name);
|
const [result, newName] = flow.getGroupEnvSetting(node, group, name);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result.val;
|
return result.val;
|
||||||
}
|
}
|
||||||
|
name = newName;
|
||||||
}
|
}
|
||||||
return flow.getSetting(name);
|
return flow.getSetting(name);
|
||||||
}
|
}
|
||||||
@@ -842,6 +843,9 @@ function encodeObject(msg,opts) {
|
|||||||
length: msg.msg.size
|
length: msg.msg.size
|
||||||
}
|
}
|
||||||
needsStringify = true;
|
needsStringify = true;
|
||||||
|
} else if (msg.msg && msg.msg.constructor.name === "RegExp") {
|
||||||
|
msg.format = 'regexp';
|
||||||
|
msg.msg = msg.msg.toString();
|
||||||
}
|
}
|
||||||
if (needsStringify || (msg.format === "Object")) {
|
if (needsStringify || (msg.format === "Object")) {
|
||||||
msg.msg = safeJSONStringify(msg.msg, function(key, value) {
|
msg.msg = safeJSONStringify(msg.msg, function(key, value) {
|
||||||
@@ -907,6 +911,12 @@ function encodeObject(msg,opts) {
|
|||||||
data: Object.fromEntries(Array.from(value.entries()).slice(0,debuglength)),
|
data: Object.fromEntries(Array.from(value.entries()).slice(0,debuglength)),
|
||||||
length: value.size
|
length: value.size
|
||||||
}
|
}
|
||||||
|
} else if (value.constructor.name === "RegExp") {
|
||||||
|
value = {
|
||||||
|
__enc__: true,
|
||||||
|
type: "regexp",
|
||||||
|
data: value.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (value === undefined) {
|
} else if (value === undefined) {
|
||||||
value = {
|
value = {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/util",
|
"name": "@node-red/util",
|
||||||
"version": "2.1.0-beta.1",
|
"version": "2.2.0-beta.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -16,10 +16,10 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs-extra": "10.0.0",
|
"fs-extra": "10.0.0",
|
||||||
"i18next": "21.2.4",
|
"i18next": "21.5.4",
|
||||||
"json-stringify-safe": "5.0.1",
|
"json-stringify-safe": "5.0.1",
|
||||||
"jsonata": "1.8.5",
|
"jsonata": "1.8.5",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"moment-timezone": "0.5.33"
|
"moment-timezone": "0.5.34"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
packages/node_modules/node-red/bin/node-red-pi
vendored
19
packages/node_modules/node-red/bin/node-red-pi
vendored
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Copyright JS Foundation and other contributors, http://js.foundation
|
# Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
#
|
#
|
||||||
@@ -29,15 +29,16 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Find the real location of this script
|
# Find the real location of this script
|
||||||
CURRENT_PATH=`pwd`
|
CURRENT_PATH=$(pwd)
|
||||||
SCRIPT_PATH="${BASH_SOURCE[0]}";
|
SCRIPT_PATH=$(readlink -f "$0")
|
||||||
while [ -h "${SCRIPT_PATH}" ]; do
|
while [ -h "${SCRIPT_PATH}" ]; do
|
||||||
cd "`dirname "${SCRIPT_PATH}"`"
|
cd "$(dirname "${SCRIPT_PATH}")" || exit 1
|
||||||
SCRIPT_PATH="$(readlink "`basename "${SCRIPT_PATH}"`")";
|
P=$(basename "${SCRIPT_PATH}")
|
||||||
|
SCRIPT_PATH=$(readlink "${P}")
|
||||||
done
|
done
|
||||||
cd "`dirname "${SCRIPT_PATH}"`" > /dev/null
|
cd "$(dirname "${SCRIPT_PATH}")" > /dev/null || exit 1
|
||||||
SCRIPT_PATH="`pwd`";
|
SCRIPT_PATH=$(pwd)
|
||||||
cd $CURRENT_PATH
|
cd "$CURRENT_PATH" || exit 1
|
||||||
|
|
||||||
# Run Node-RED
|
# Run Node-RED
|
||||||
exec /usr/bin/env node $OPTIONS $SCRIPT_PATH/../red.js $ARGS
|
exec /usr/bin/env node ${OPTIONS} ${SCRIPT_PATH}/../red.js ${ARGS}
|
||||||
|
12
packages/node_modules/node-red/package.json
vendored
12
packages/node_modules/node-red/package.json
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "2.1.0-beta.1",
|
"version": "2.2.0-beta.1",
|
||||||
"description": "Low-code programming for event-driven applications",
|
"description": "Low-code programming for event-driven applications",
|
||||||
"homepage": "http://nodered.org",
|
"homepage": "http://nodered.org",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -31,15 +31,15 @@
|
|||||||
"flow"
|
"flow"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/editor-api": "2.1.0-beta.1",
|
"@node-red/editor-api": "2.2.0-beta.1",
|
||||||
"@node-red/runtime": "2.1.0-beta.1",
|
"@node-red/runtime": "2.2.0-beta.1",
|
||||||
"@node-red/util": "2.1.0-beta.1",
|
"@node-red/util": "2.2.0-beta.1",
|
||||||
"@node-red/nodes": "2.1.0-beta.1",
|
"@node-red/nodes": "2.2.0-beta.1",
|
||||||
"basic-auth": "2.0.1",
|
"basic-auth": "2.0.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"fs-extra": "10.0.0",
|
"fs-extra": "10.0.0",
|
||||||
"node-red-admin": "^2.2.0",
|
"node-red-admin": "^2.2.1",
|
||||||
"nopt": "5.0.0",
|
"nopt": "5.0.0",
|
||||||
"semver": "7.3.5"
|
"semver": "7.3.5"
|
||||||
},
|
},
|
||||||
|
5
packages/node_modules/node-red/red.js
vendored
5
packages/node_modules/node-red/red.js
vendored
@@ -194,6 +194,11 @@ if (process.env.NODE_RED_ENABLE_PROJECTS) {
|
|||||||
settings.editorTheme.projects.enabled = !/^false$/i.test(process.env.NODE_RED_ENABLE_PROJECTS);
|
settings.editorTheme.projects.enabled = !/^false$/i.test(process.env.NODE_RED_ENABLE_PROJECTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.env.NODE_RED_ENABLE_TOURS) {
|
||||||
|
settings.editorTheme = settings.editorTheme || {};
|
||||||
|
settings.editorTheme.tours = !/^false$/i.test(process.env.NODE_RED_ENABLE_TOURS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var defaultServerSettings = {
|
var defaultServerSettings = {
|
||||||
"x-powered-by": false
|
"x-powered-by": false
|
||||||
|
@@ -9,29 +9,36 @@ const LATEST = "2";
|
|||||||
function generateScript() {
|
function generateScript() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const packages = [
|
const packages = [
|
||||||
"node-red-util",
|
"@node-red/util",
|
||||||
"node-red-runtime",
|
"@node-red/runtime",
|
||||||
"node-red-registry",
|
"@node-red/registry",
|
||||||
"node-red-nodes",
|
"@node-red/nodes",
|
||||||
"node-red-editor-client",
|
"@node-red/editor-client",
|
||||||
"node-red-editor-api",
|
"@node-red/editor-api",
|
||||||
"node-red"
|
"node-red"
|
||||||
];
|
];
|
||||||
const rootPackage = require(path.join(__dirname,"..","package.json"));
|
const rootPackage = require(path.join(__dirname,"..","package.json"));
|
||||||
const version = rootPackage.version;
|
const version = rootPackage.version;
|
||||||
|
|
||||||
const versionParts = version.split(".");
|
const versionParts = version.split(".");
|
||||||
|
let updateNextToLatest = false;
|
||||||
let tagArg = "";
|
let tagArg = "";
|
||||||
if (versionParts[0] !== LATEST) {
|
if (versionParts[0] !== LATEST) {
|
||||||
tagArg = `--tag v${versionParts[0]}-maintenance`
|
tagArg = `--tag v${versionParts[0]}-maintenance`
|
||||||
} else if (/-/.test(version)) {
|
} else if (/-/.test(version)) {
|
||||||
tagArg = "--tag next"
|
tagArg = "--tag next"
|
||||||
|
} else {
|
||||||
|
updateNextToLatest = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lines = [];
|
const lines = [];
|
||||||
|
|
||||||
packages.forEach(name => {
|
packages.forEach(name => {
|
||||||
lines.push(`npm publish ${name}-${version}.tgz ${tagArg}\n`);
|
const tarName = name.replace(/@/,"").replace(/\//,"-")
|
||||||
|
lines.push(`npm publish ${tarName}-${version}.tgz ${tagArg}\n`);
|
||||||
|
if (updateNextToLatest) {
|
||||||
|
lines.push(`npm dist-tag add ${name}@${version} next\n`);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
resolve(lines.join(""))
|
resolve(lines.join(""))
|
||||||
});
|
});
|
||||||
|
@@ -60,9 +60,9 @@ describe('TCP Request Node', function() {
|
|||||||
n2.on("input", function(msg) {
|
n2.on("input", function(msg) {
|
||||||
try {
|
try {
|
||||||
if (typeof val1 === 'object') {
|
if (typeof val1 === 'object') {
|
||||||
msg.should.have.properties(Object.assign({}, val1, {payload: Buffer(val1.payload)}));
|
msg.should.have.properties(Object.assign({}, val1, {payload: Buffer.from(val1.payload)}));
|
||||||
} else {
|
} else {
|
||||||
msg.should.have.property('payload', Buffer(val1));
|
msg.should.have.property('payload', Buffer.from(val1));
|
||||||
}
|
}
|
||||||
done();
|
done();
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@@ -84,9 +84,9 @@ describe('TCP Request Node', function() {
|
|||||||
n2.on("input", msg => {
|
n2.on("input", msg => {
|
||||||
try {
|
try {
|
||||||
if (typeof result === 'object') {
|
if (typeof result === 'object') {
|
||||||
msg.should.have.properties(Object.assign({}, result, {payload: Buffer(result.payload)}));
|
msg.should.have.properties(Object.assign({}, result, {payload: Buffer.from(result.payload)}));
|
||||||
} else {
|
} else {
|
||||||
msg.should.have.property('payload', Buffer(result));
|
msg.should.have.property('payload', Buffer.from(result));
|
||||||
}
|
}
|
||||||
done();
|
done();
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
@@ -50,6 +50,24 @@ describe('JSON node', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should convert a buffer of a valid json string to a javascript object', function(done) {
|
||||||
|
var flow = [{id:"jn1",type:"json",action:"obj",wires:[["jn2"]]},
|
||||||
|
{id:"jn2", type:"helper"}];
|
||||||
|
helper.load(jsonNode, flow, function() {
|
||||||
|
var jn1 = helper.getNode("jn1");
|
||||||
|
var jn2 = helper.getNode("jn2");
|
||||||
|
jn2.on("input", function(msg) {
|
||||||
|
msg.should.have.property('topic', 'bar');
|
||||||
|
msg.payload.should.have.property('employees');
|
||||||
|
msg.payload.employees[0].should.have.property('firstName', 'John');
|
||||||
|
msg.payload.employees[0].should.have.property('lastName', 'Smith');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
var jsonString = Buffer.from('{"employees":[{"firstName":"John", "lastName":"Smith"}]}');
|
||||||
|
jn1.receive({payload:jsonString,topic: "bar"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should convert a javascript object to a json string', function(done) {
|
it('should convert a javascript object to a json string', function(done) {
|
||||||
var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
||||||
{id:"jn2", type:"helper"}];
|
{id:"jn2", type:"helper"}];
|
||||||
@@ -166,29 +184,55 @@ describe('JSON node', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log an error if asked to parse something thats not json or js', function(done) {
|
it('should log an error if asked to parse an invalid json string in a buffer', function(done) {
|
||||||
var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
var flow = [{id:"jn1",type:"json",action:"obj",wires:[["jn2"]]},
|
||||||
{id:"jn2", type:"helper"}];
|
{id:"jn2", type:"helper"}];
|
||||||
helper.load(jsonNode, flow, function() {
|
helper.load(jsonNode, flow, function() {
|
||||||
var jn1 = helper.getNode("jn1");
|
try {
|
||||||
var jn2 = helper.getNode("jn2");
|
var jn1 = helper.getNode("jn1");
|
||||||
setTimeout(function() {
|
var jn2 = helper.getNode("jn2");
|
||||||
try {
|
jn1.receive({payload:Buffer.from('{"name":foo}'),topic: "bar"});
|
||||||
var logEvents = helper.log().args.filter(function(evt) {
|
setTimeout(function() {
|
||||||
return evt[0].type == "json";
|
try {
|
||||||
});
|
var logEvents = helper.log().args.filter(function(evt) {
|
||||||
logEvents.should.have.length(1);
|
return evt[0].type == "json";
|
||||||
logEvents[0][0].should.have.a.property('msg');
|
});
|
||||||
logEvents[0][0].msg.toString().should.eql('json.errors.dropped-object');
|
logEvents.should.have.length(1);
|
||||||
done();
|
logEvents[0][0].should.have.a.property('msg');
|
||||||
} catch(err) {
|
logEvents[0][0].msg.should.startWith("Unexpected token o");
|
||||||
done(err);
|
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
|
||||||
}
|
done();
|
||||||
},50);
|
} catch(err) { done(err) }
|
||||||
jn1.receive({payload:Buffer.from("a")});
|
},20);
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// it('should log an error if asked to parse something thats not json or js and not in force object mode', function(done) {
|
||||||
|
// var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
||||||
|
// {id:"jn2", type:"helper"}];
|
||||||
|
// helper.load(jsonNode, flow, function() {
|
||||||
|
// var jn1 = helper.getNode("jn1");
|
||||||
|
// var jn2 = helper.getNode("jn2");
|
||||||
|
// setTimeout(function() {
|
||||||
|
// try {
|
||||||
|
// var logEvents = helper.log().args.filter(function(evt) {
|
||||||
|
// return evt[0].type == "json";
|
||||||
|
// });
|
||||||
|
// logEvents.should.have.length(1);
|
||||||
|
// logEvents[0][0].should.have.a.property('msg');
|
||||||
|
// logEvents[0][0].msg.toString().should.eql('json.errors.dropped');
|
||||||
|
// done();
|
||||||
|
// } catch(err) {
|
||||||
|
// done(err);
|
||||||
|
// }
|
||||||
|
// },50);
|
||||||
|
// jn1.receive({payload:Buffer.from("abcd")});
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
it('should pass straight through if no payload set', function(done) {
|
it('should pass straight through if no payload set', function(done) {
|
||||||
var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
||||||
{id:"jn2", type:"helper"}];
|
{id:"jn2", type:"helper"}];
|
||||||
|
@@ -1275,6 +1275,52 @@ describe('Flow', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
it("can access environment variable property using $parent", function (done) {
|
||||||
|
try {
|
||||||
|
after(function() {
|
||||||
|
delete process.env.V0;
|
||||||
|
delete process.env.V1;
|
||||||
|
})
|
||||||
|
process.env.V0 = "gv0";
|
||||||
|
process.env.V1 = "gv1";
|
||||||
|
var config = flowUtils.parseConfig([
|
||||||
|
{id:"t1",type:"tab",env:[
|
||||||
|
{"name": "V0", value: "v0", type: "str"}
|
||||||
|
]},
|
||||||
|
{id:"g1",type:"group",z:"t1",env:[
|
||||||
|
{"name": "V0", value: "v1", type: "str"},
|
||||||
|
{"name": "V1", value: "v2", type: "str"}
|
||||||
|
]},
|
||||||
|
{id:"g2",type:"group",z:"t1",g:"g1",env:[
|
||||||
|
{"name": "V1", value: "v3", type: "str"}
|
||||||
|
]},
|
||||||
|
{id:"1",x:10,y:10,z:"t1",type:"test",foo:"${$parent.V0}",wires:[]},
|
||||||
|
{id:"2",x:10,y:10,z:"t1",g:"g1",type:"test",foo:"${$parent.V0}",wires:[]},
|
||||||
|
{id:"3",x:10,y:10,z:"t1",g:"g1",type:"test",foo:"${$parent.V1}",wires:[]},
|
||||||
|
{id:"4",x:10,y:10,z:"t1",g:"g2",type:"test",foo:"${$parent.V1}",wires:[]},
|
||||||
|
{id:"5",x:10,y:10,z:"t1",type:"test",foo:"${$parent.V1}",wires:[]},
|
||||||
|
]);
|
||||||
|
var flow = Flow.create({getSetting:v=>process.env[v]},config,config.flows["t1"]);
|
||||||
|
flow.start();
|
||||||
|
|
||||||
|
var activeNodes = flow.getActiveNodes();
|
||||||
|
|
||||||
|
activeNodes["1"].foo.should.equal("gv0");
|
||||||
|
activeNodes["2"].foo.should.equal("v0");
|
||||||
|
activeNodes["3"].foo.should.equal("gv1");
|
||||||
|
activeNodes["4"].foo.should.equal("v2");
|
||||||
|
activeNodes["5"].foo.should.equal("gv1");
|
||||||
|
|
||||||
|
flow.stop().then(function() {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log(e.stack);
|
||||||
|
done(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user