mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
348 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
42b5635485 | ||
|
a8fc5b01f3 | ||
|
ead841d844 | ||
|
67d7930aef | ||
|
6f69995f4e | ||
|
05252fa239 | ||
|
1377439bb0 | ||
|
407123a280 | ||
|
750dd590c8 | ||
|
44112a9d18 | ||
|
b220bf0d99 | ||
|
d0d93d7070 | ||
|
4117961236 | ||
|
68a3d71ee6 | ||
|
bf5d741f0d | ||
|
55a33bc408 | ||
|
3ec35ed119 | ||
|
3d8d6953ec | ||
|
528db67c34 | ||
|
b847e962aa | ||
|
bbb9a3c63b | ||
|
322cebc48c | ||
|
1cceb3d880 | ||
|
effc64db9a | ||
|
7e5bd5f2c1 | ||
|
e32cc4d1af | ||
|
09a3cd850e | ||
|
b0c876019a | ||
|
6725f870d2 | ||
|
0e5adc1f0a | ||
|
57ebb93dc0 | ||
|
05dc0bfa1d | ||
|
2d0264116c | ||
|
3938550ea8 | ||
|
9f0c567794 | ||
|
8672fcd2bb | ||
|
3f2a92e801 | ||
|
771e43583a | ||
|
9353d5c1c4 | ||
|
5e462f0f02 | ||
|
a25f6fec9f | ||
|
519edce0ed | ||
|
0bc7702d95 | ||
|
18be0d6d26 | ||
|
1d4a435f20 | ||
|
34e46fc6d3 | ||
|
50956c51f7 | ||
|
dd7bb28b6a | ||
|
8516f41ba8 | ||
|
15c3cc60f6 | ||
|
716bca211b | ||
|
8179813fe1 | ||
|
d355de509b | ||
|
b04a2d4c08 | ||
|
6d3232a4f0 | ||
|
2753075180 | ||
|
d0166b25e4 | ||
|
73ee657d74 | ||
|
45913e5ee8 | ||
|
e6369820a9 | ||
|
22a5b339f7 | ||
|
2cea3b6435 | ||
|
5d2d06fb3e | ||
|
0dd7bc7fb9 | ||
|
0b0005337c | ||
|
d26fb02bb9 | ||
|
af683835d9 | ||
|
c43647ca86 | ||
|
6d02e70025 | ||
|
5498c6f87d | ||
|
11f59bc3ac | ||
|
94cb7de79f | ||
|
838f45775b | ||
|
1c1422e4b5 | ||
|
cd8ca6fc62 | ||
|
b7a0a9d7c2 | ||
|
7822ab113a | ||
|
e250a91f09 | ||
|
92a65dcda5 | ||
|
4b129d94e4 | ||
|
e7960d1d44 | ||
|
95589307cd | ||
|
20a0e4f3e0 | ||
|
6a9213da64 | ||
|
7a89e3cf33 | ||
|
64607df929 | ||
|
a62a1012fa | ||
|
14efd0b2f9 | ||
|
7ad2192df8 | ||
|
3cb5cbd8d5 | ||
|
cc9011cd68 | ||
|
dc3d89008d | ||
|
1893642187 | ||
|
a9ece5772d | ||
|
cf34716a57 | ||
|
1337831061 | ||
|
757e72100d | ||
|
a75b819858 | ||
|
da4a0f09ed | ||
|
87d847a074 | ||
|
84711beec0 | ||
|
f3cf58c8ff | ||
|
cf40497e6e | ||
|
dfebc4b78d | ||
|
15f41a2e7c | ||
|
ad6e55ca17 | ||
|
6b466d217a | ||
|
00dcb304c7 | ||
|
c6fb3d6f41 | ||
|
ac3143811f | ||
|
7e27dd7678 | ||
|
c2508296a5 | ||
|
a9b50ce6fc | ||
|
eac98a6d4d | ||
|
7e2b2a9a02 | ||
|
353de471eb | ||
|
85fc20b52d | ||
|
cc25a781f8 | ||
|
fc3012ba72 | ||
|
d93a92c1c8 | ||
|
f7f795f58a | ||
|
2700f8cdd2 | ||
|
6310de0d20 | ||
|
218794be77 | ||
|
af71ae649b | ||
|
9bc72c1a06 | ||
|
8d7c157751 | ||
|
558a66fbe5 | ||
|
f95b414d22 | ||
|
e793a1e1aa | ||
|
b76010cb5a | ||
|
52475df783 | ||
|
1f3f32d377 | ||
|
3f5ba10354 | ||
|
25f4a018d9 | ||
|
a11a279c00 | ||
|
fd4fdb31b5 | ||
|
1921796d6d | ||
|
543a2b9dc7 | ||
|
dd23e03342 | ||
|
5307c74f85 | ||
|
d701c406e2 | ||
|
3ba56a0a65 | ||
|
4adafb6d1e | ||
|
4453a51211 | ||
|
14429d2943 | ||
|
1a62a7831b | ||
|
242e35c212 | ||
|
ea763fdfd5 | ||
|
e762b7ff48 | ||
|
298068b2b9 | ||
|
cb4120ec4b | ||
|
5cfbb87bee | ||
|
9e472ed83c | ||
|
ebca753fc4 | ||
|
548f45cd56 | ||
|
8ffabf1813 | ||
|
1f40d4f941 | ||
|
41582045d0 | ||
|
fd9e3fc03a | ||
|
8c42b2bdb4 | ||
|
7b1787fdbb | ||
|
71fee0025d | ||
|
1204cf1ba0 | ||
|
7bd8d8c3ae | ||
|
2c4d5fa38d | ||
|
bedb2d943e | ||
|
a3640bd9bf | ||
|
7c0b9ffe06 | ||
|
161c7d30ca | ||
|
4ff6e792cd | ||
|
af5df890a5 | ||
|
9ba011003a | ||
|
bb168d35a8 | ||
|
3306d30094 | ||
|
6516e0dfd2 | ||
|
00a396014b | ||
|
13356047dc | ||
|
8a6488b067 | ||
|
1c2ea56f42 | ||
|
1d7ae300e2 | ||
|
6013e186ed | ||
|
207d3d3340 | ||
|
5a6cde1446 | ||
|
63f7d826bc | ||
|
ff8773f6bd | ||
|
a868cb97d9 | ||
|
915d73e6f2 | ||
|
5f4f6e37b5 | ||
|
9c350311e8 | ||
|
3c6ba72a2a | ||
|
816442f5f0 | ||
|
3b51d18ce7 | ||
|
6696b6661a | ||
|
8c87478636 | ||
|
d870b072d7 | ||
|
2ea2af7d2a | ||
|
f737ea96f3 | ||
|
05f90394db | ||
|
c24b0c6bb4 | ||
|
e07a4dc7ba | ||
|
fc6748a46b | ||
|
7697c46652 | ||
|
ed52e5afd1 | ||
|
33a5b84181 | ||
|
c09a407f4c | ||
|
d35784ec61 | ||
|
53e012f296 | ||
|
2a9d0a5e7d | ||
|
474f4572f2 | ||
|
bf57cb209f | ||
|
9bc41c1709 | ||
|
fe10b8650f | ||
|
3a311c9584 | ||
|
d1106f53e0 | ||
|
a3a1bba5ef | ||
|
028d66befc | ||
|
bb59cd5742 | ||
|
604e3068b2 | ||
|
27f1d3b704 | ||
|
d007623347 | ||
|
6a5cf7a1fa | ||
|
3adfe249b0 | ||
|
923893e160 | ||
|
256e5360d4 | ||
|
304c597a2f | ||
|
f86d3a69d2 | ||
|
d7c8adfd82 | ||
|
55cd069043 | ||
|
3ca0e9c420 | ||
|
1dd4323613 | ||
|
d78916f85f | ||
|
1840d15397 | ||
|
b98d1216b1 | ||
|
27db727321 | ||
|
3f6b1f6ccb | ||
|
6d633b372a | ||
|
91352e855a | ||
|
8bb9b594cf | ||
|
6d2fd2e641 | ||
|
422fbcb0b7 | ||
|
afce106186 | ||
|
f21c8154ed | ||
|
3988a648d6 | ||
|
1b632894d3 | ||
|
5e128f89f6 | ||
|
fff0b15ae5 | ||
|
a7e14f1093 | ||
|
94eeaeb8d3 | ||
|
64191e8303 | ||
|
21cfb71617 | ||
|
806457063f | ||
|
b9213b73bd | ||
|
d7f0102aa2 | ||
|
f09e61a59a | ||
|
d426aaa88a | ||
|
19e45389e1 | ||
|
6d2389945b | ||
|
14c48253f6 | ||
|
e5ff25b92d | ||
|
5c88888e02 | ||
|
10057de9b3 | ||
|
cc88ebd2b9 | ||
|
6baedf909d | ||
|
f39d9d6f1b | ||
|
ab61a95f83 | ||
|
10ceed30c6 | ||
|
2b9aa94f3a | ||
|
848fb975ed | ||
|
d7f59dac84 | ||
|
dd47e615ee | ||
|
8f2f7ea1a5 | ||
|
80a8efd8ce | ||
|
d9dce77ef4 | ||
|
ce7053a1fe | ||
|
0db1530171 | ||
|
3745504107 | ||
|
57533fd831 | ||
|
f57a0d4d6b | ||
|
22772ca33e | ||
|
dba6ff1d51 | ||
|
40146dedaf | ||
|
387b822f53 | ||
|
b9a3563e5b | ||
|
3d6468326a | ||
|
298e37ec53 | ||
|
5b137c457b | ||
|
5218a3fbac | ||
|
4569cb432d | ||
|
611e598756 | ||
|
937d79d28f | ||
|
23c2a771d3 | ||
|
58a890e836 | ||
|
6a869e120c | ||
|
ae7c298b1a | ||
|
53bfe12ac1 | ||
|
140ea683a6 | ||
|
0634a97598 | ||
|
3479c794de | ||
|
89cad116f7 | ||
|
19c84eb694 | ||
|
eae390acf5 | ||
|
10567afbb9 | ||
|
51bad3bf3c | ||
|
9134d8841d | ||
|
e9a026c131 | ||
|
9a2fd0e2b2 | ||
|
522f7e6844 | ||
|
cb4f46decc | ||
|
81256279a8 | ||
|
039bd1ddc0 | ||
|
0791d4797f | ||
|
6a06142e1e | ||
|
ef53dca062 | ||
|
6ce761edda | ||
|
d8fd218409 | ||
|
edc2310599 | ||
|
b1cd13d629 | ||
|
b81940351f | ||
|
a42e99c4aa | ||
|
ff40b521b7 | ||
|
85392496e7 | ||
|
29cae9975e | ||
|
170d6b28f8 | ||
|
9a8b404054 | ||
|
41af5187aa | ||
|
a844ca161f | ||
|
e09efba313 | ||
|
96a0dbea2d | ||
|
5b3b5271ad | ||
|
d7d13c12fe | ||
|
54220d0e71 | ||
|
4a2e3586f1 | ||
|
f808e85da9 | ||
|
1671d1f580 | ||
|
7de1bf9d95 | ||
|
7368b0cefb | ||
|
4af43d676a | ||
|
67dc848b2d | ||
|
7ec8f0d26b | ||
|
eaf08a9971 | ||
|
5bdb9e972e | ||
|
d4d87054c4 | ||
|
0f93929544 | ||
|
1c0e794f87 | ||
|
8dcc114873 | ||
|
8cc9aeba4a | ||
|
ba0823c38c |
30
.github/ISSUE_TEMPLATE.md
vendored
Normal file
30
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
## Before you hit that Submit button....
|
||||
|
||||
This issue tracker is for problems with the Node-RED runtime, the editor or the core nodes.
|
||||
|
||||
If your issue is:
|
||||
- a general 'how-to' type question,
|
||||
- a feature request or suggestion for a change,
|
||||
- or problems with 3rd party (`node-red-contrib-`) nodes
|
||||
|
||||
please use the [mailing list](https://groups.google.com/forum/#!forum/node-red), [slack team](https://nodered.org/slack) or ask a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/node-red) and tag it `node-red`.
|
||||
|
||||
That way the whole Node-RED user community can help, rather than rely on the core development team.
|
||||
|
||||
## So you have a real issue to raise...
|
||||
|
||||
To help us understand the issue, please fill-in as much of the following information as you can:
|
||||
|
||||
### What are the steps to reproduce?
|
||||
|
||||
### What happens?
|
||||
|
||||
### What do you expect to happen?
|
||||
|
||||
### Please tell us about your environment:
|
||||
|
||||
- [ ] Node-RED version:
|
||||
- [ ] node.js version:
|
||||
- [ ] npm version:
|
||||
- [ ] Platform/OS:
|
||||
- [ ] Browser:
|
30
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
30
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
## Before you hit that Submit button....
|
||||
|
||||
Please read our [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md)
|
||||
before submitting a pull-request.
|
||||
|
||||
## Types of changes
|
||||
|
||||
What types of changes does your code introduce?
|
||||
_Put an `x` in the boxes that apply_
|
||||
|
||||
- [ ] Bugfix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
|
||||
If you want to raise a pull-request with a new feature, or a refactoring
|
||||
of existing code, it **may well get rejected** if it hasn't been discussed on
|
||||
the [mailing list](https://groups.google.com/forum/#!forum/node-red) or
|
||||
[slack team](https://nodered.org/slack) first.
|
||||
|
||||
|
||||
## Proposed changes
|
||||
|
||||
Describe the nature of this change. What problem does it address?
|
||||
|
||||
## Checklist
|
||||
_Put an `x` in the boxes that apply_
|
||||
|
||||
- [ ] I have read the [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md)
|
||||
- [ ] For non-bugfix PRs, I have discussed this change on the mailing list/slack team.
|
||||
- [ ] I have run `grunt` to verify the unit tests pass
|
||||
- [ ] I have added suitable unit tests to cover the new/changed functionality
|
@@ -11,7 +11,6 @@ addons:
|
||||
- gcc-4.8
|
||||
node_js:
|
||||
- "8"
|
||||
- "7"
|
||||
- "6"
|
||||
- "4"
|
||||
script:
|
||||
|
131
CHANGELOG.md
131
CHANGELOG.md
@@ -1,3 +1,98 @@
|
||||
#### 0.18.1: Maintenance Release
|
||||
|
||||
Projects
|
||||
|
||||
- Handle more repo clone error cases
|
||||
- Relax validation of git urls
|
||||
- Revalidate project name on return to project-details view
|
||||
- Avoid unnecessary project refresh on branch-switch Fixes #1597
|
||||
- Add support for file:// git urls
|
||||
- Handle project first-run without existing flow file
|
||||
- Handle delete of last remote in project settings
|
||||
- Add git_pull_unrelated_history handling
|
||||
- Fix pull/push when no tracked branch
|
||||
- Remember to disable projects in editor when git not found
|
||||
|
||||
Node Fixes
|
||||
|
||||
- Trigger node migration - ensure bytopic not blank
|
||||
- Add HEAD to list of methods with no body in http req node #1598
|
||||
- Do not include payload in GET requests Fixes #1598
|
||||
- Update sort/batch docs Fixes #1601
|
||||
- Don't assume node has defaults when exporting icon property
|
||||
|
||||
|
||||
#### 0.18: Milestone Release
|
||||
|
||||
Runtime
|
||||
|
||||
- Beta: Projects - must be enabled in settings file
|
||||
- Allow port zero for Express (#1363)
|
||||
- Better error reporting when module provides duplicate type
|
||||
- Update jsonata to 1.5.0
|
||||
- add express-session memorystore without leaks (#1435)
|
||||
- Allow adminAuth.user to be a Function Fixes #1461
|
||||
- Ensure RED.server is set even if admin api disabled
|
||||
- Ensure strategy login button uses relative URL Fixes #1481
|
||||
- ignore `_msgid` when merging full objects
|
||||
- Move node install to spawn to allow for big stdout Fixes #1488
|
||||
- SIGINT handler should wait for stop to complete before exit
|
||||
|
||||
Editor
|
||||
|
||||
- allow a node's icon to be set dynamically (#1490)
|
||||
- Batch messages sent over comms to increase throughput
|
||||
- Migrate deploy confirmations to notifications
|
||||
- `oneditdelete` should be available to all node types Closes #1346
|
||||
- Sort typeSearch results based on position of match
|
||||
- Update ACE to test and add python highlighter (#1373)
|
||||
- Clear mouse state when typeSearch cancelled Fixes #1517
|
||||
- Handle scoped modules via palette editor
|
||||
- TypedInput: handle user defined value/labels options Fixes #1549
|
||||
|
||||
Nodes
|
||||
|
||||
- add msg. select to range and yaml nodes
|
||||
- add property choice to xml, sentiment nodes
|
||||
- mqtt: Add 'name' to mqtt-broker node, and label it by this if it is set. (#1364)
|
||||
- Add option to JSON node to ensure particular encoding
|
||||
- add parts support for HTML node (#1495)
|
||||
- Add passphrase to TLS node
|
||||
- Add rc property to exec node outputs 1 and 2 (#1401)
|
||||
- Add skip first n lines capability to csv node (#1535)
|
||||
- Add support for rejectUnauthorized msg property
|
||||
- Add TLS options to WebSocket client
|
||||
- Added parsed YAML support for template node (#1443)
|
||||
- Allow delay node in rate-limit mode to be reset Fixes #1360
|
||||
- Allow setTimeout in Function node to be promisified in node 8
|
||||
- Debug to status option (#1499)
|
||||
- enable template config via msg.template for stored or generated templates (#1503)
|
||||
- HTTP REQUEST: Adding PROPPATCH and PROPFIND http methods (#1531)
|
||||
- Initial support of merge & reduce mode for JOIN node (#1546)
|
||||
- Initial support of new BATCH node (#1548)
|
||||
- Initial support of sequence rules for SWITCH node (#1545)
|
||||
- initial support of SORT node (#1500)
|
||||
- Inject node - let once delay be editable (#1541)
|
||||
- Introduce `nodeMaxMessageBufferLength` setting for msg sequence nodes
|
||||
- Let CSV correct parts if we remove header row.
|
||||
- let default apply if msg.delay not set in override mode. (#1397)
|
||||
- let trigger node be reset by boolean message (#1554)
|
||||
- Let trigger node support per topic mode (#1398)
|
||||
- let HTML node return empty array for no matching input (#1582)
|
||||
- MQTT node - if Server/URL config contains '//' use it as a complete url; enabled ws:// and wss://
|
||||
- clone messages before delayed send (#1474)
|
||||
- Decrement connected client count rather than show disconnected
|
||||
- Don't end mqtt client on first error Fixes #1566
|
||||
- File out - create dirs synchronously to ensure they exist Fixes #1489
|
||||
- Fix debug message format for Buffer (#1444)
|
||||
- Fix global.keys() bug in function node (#1417)
|
||||
- Handle escape characters in template node which uses Mustache format and JSON output mode (#1377)
|
||||
- Move all node.send to end of timer functions in trigger node (issue #1527) (#1539)
|
||||
- Publish null/undefined to mqtt as blank not toString Fixes #1521
|
||||
- remove inject node at specific time spinner
|
||||
- restrict inject interval to less that 2^31 millisecs
|
||||
- tag UDP ports in use properly so they get closed correctly (#1508)
|
||||
|
||||
#### 0.17.5: Maintenance Release
|
||||
|
||||
- Add express-session missing dependency for oauth
|
||||
@@ -889,7 +984,7 @@ Fixes
|
||||
#### 0.10.10: Maintenance Release
|
||||
|
||||
- Fix permissions issue with packaged nrgpio script
|
||||
- Add better help message if deprecated node missing
|
||||
- Add better help message if deprecated node missing
|
||||
|
||||
|
||||
|
||||
@@ -901,16 +996,16 @@ Fix packaging of bin scripts
|
||||
|
||||
#### 0.10.8: Maintenance Release
|
||||
|
||||
- Nodes moved out of core
|
||||
- still included as a dependency: twitter, serial, email, feedparser
|
||||
- Nodes moved out of core
|
||||
- still included as a dependency: twitter, serial, email, feedparser
|
||||
- no longer included: mongo, arduino, irc, redis
|
||||
- node icon defn can be a function
|
||||
- http_proxy support
|
||||
- httpNodeMiddleware setting
|
||||
- Trigger node ui refresh
|
||||
- editorTheme setting
|
||||
- Warn on deploy of unused config nodes
|
||||
- catch node prevents error loops
|
||||
- node icon defn can be a function
|
||||
- http_proxy support
|
||||
- httpNodeMiddleware setting
|
||||
- Trigger node ui refresh
|
||||
- editorTheme setting
|
||||
- Warn on deploy of unused config nodes
|
||||
- catch node prevents error loops
|
||||
|
||||
|
||||
|
||||
@@ -933,14 +1028,14 @@ Changes:
|
||||
|
||||
Changes:
|
||||
|
||||
- http request node passes on request url as msg.url
|
||||
- handle config nodes appearing out of order in flow file - don't assume they are always at the start
|
||||
- move subflow palette category to the top, to make it more obvious
|
||||
- fix labelling of Raspberry Pi pins
|
||||
- allow email node to mark mail as read
|
||||
- fix saving library content
|
||||
- add node-red and node-red-pi start scripts
|
||||
- use $HOME/.node-red for user data unless specified otherwise (or existing data is found in install dir)
|
||||
- http request node passes on request url as msg.url
|
||||
- handle config nodes appearing out of order in flow file - don't assume they are always at the start
|
||||
- move subflow palette category to the top, to make it more obvious
|
||||
- fix labelling of Raspberry Pi pins
|
||||
- allow email node to mark mail as read
|
||||
- fix saving library content
|
||||
- add node-red and node-red-pi start scripts
|
||||
- use $HOME/.node-red for user data unless specified otherwise (or existing data is found in install dir)
|
||||
|
||||
|
||||
|
||||
|
@@ -9,7 +9,7 @@ We welcome contributions, but request you follow these guidelines.
|
||||
|
||||
This project adheres to the [Contributor Covenant 1.4](http://contributor-covenant.org/version/1/4/).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable
|
||||
behavior to any of the [project's core team](https://github.com/orgs/node-red/teams/core).
|
||||
behavior to the project's core team at team@nodered.org.
|
||||
|
||||
## Raising issues
|
||||
|
||||
|
26
Gruntfile.js
26
Gruntfile.js
@@ -41,16 +41,23 @@ module.exports = function(grunt) {
|
||||
core: { src: ["test/_spec.js","test/red/**/*_spec.js"]},
|
||||
nodes: { src: ["test/nodes/**/*_spec.js"]}
|
||||
},
|
||||
webdriver: {
|
||||
all: {
|
||||
configFile: 'test/editor/wdio.conf.js'
|
||||
}
|
||||
},
|
||||
mocha_istanbul: {
|
||||
options: {
|
||||
globals: ['expect'],
|
||||
timeout: 3000,
|
||||
ignoreLeaks: false,
|
||||
ui: 'bdd',
|
||||
reportFormats: ['lcov'],
|
||||
reportFormats: ['lcov','html'],
|
||||
print: 'both'
|
||||
},
|
||||
coverage: { src: ['test/**/*_spec.js'] }
|
||||
all: { src: ['test/**/*_spec.js'] },
|
||||
core: { src: ["test/_spec.js","test/red/**/*_spec.js"]},
|
||||
nodes: { src: ["test/nodes/**/*_spec.js"]}
|
||||
},
|
||||
jshint: {
|
||||
options: {
|
||||
@@ -151,6 +158,10 @@ module.exports = function(grunt) {
|
||||
"editor/js/ui/typeSearch.js",
|
||||
"editor/js/ui/subflow.js",
|
||||
"editor/js/ui/userSettings.js",
|
||||
"editor/js/ui/projects/projects.js",
|
||||
"editor/js/ui/projects/projectSettings.js",
|
||||
"editor/js/ui/projects/projectUserSettings.js",
|
||||
"editor/js/ui/projects/tab-versionControl.js",
|
||||
"editor/js/ui/touch/radialMenu.js"
|
||||
],
|
||||
dest: "public/red/red.js"
|
||||
@@ -413,6 +424,7 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-chmod');
|
||||
grunt.loadNpmTasks('grunt-jsonlint');
|
||||
grunt.loadNpmTasks('grunt-mocha-istanbul');
|
||||
grunt.loadNpmTasks('grunt-webdriver');
|
||||
|
||||
grunt.registerMultiTask('attachCopyright', function() {
|
||||
var files = this.data.src;
|
||||
@@ -466,15 +478,19 @@ module.exports = function(grunt) {
|
||||
|
||||
grunt.registerTask('test-core',
|
||||
'Runs code style check and unit tests on core runtime code',
|
||||
['jshint:core','simplemocha:core']);
|
||||
['build','mocha_istanbul:core']);
|
||||
|
||||
grunt.registerTask('test-editor',
|
||||
'Runs code style check on editor code',
|
||||
['jshint:editor']);
|
||||
|
||||
grunt.registerTask('test-ui',
|
||||
'Builds editor content then runs unit tests on editor ui',
|
||||
['build','jshint:editor','webdriver:all']);
|
||||
|
||||
grunt.registerTask('test-nodes',
|
||||
'Runs unit tests on core nodes',
|
||||
['simplemocha:nodes']);
|
||||
['build','mocha_istanbul:nodes']);
|
||||
|
||||
grunt.registerTask('build',
|
||||
'Builds editor content',
|
||||
@@ -490,5 +506,5 @@ module.exports = function(grunt) {
|
||||
|
||||
grunt.registerTask('coverage',
|
||||
'Run Istanbul code test coverage task',
|
||||
['build','mocha_istanbul']);
|
||||
['build','mocha_istanbul:all']);
|
||||
};
|
||||
|
@@ -14,7 +14,7 @@ A visual tool for wiring the Internet of Things.
|
||||
Check out http://nodered.org/docs/getting-started/ for full instructions on getting
|
||||
started.
|
||||
|
||||
1. `sudo npm install -g node-red`
|
||||
1. `sudo npm install -g --unsafe-perm node-red`
|
||||
2. `node-red`
|
||||
3. Open <http://localhost:1880>
|
||||
|
||||
@@ -56,7 +56,7 @@ Before raising a pull-request, please read our
|
||||
|
||||
This project adheres to the [Contributor Covenant 1.4](http://contributor-covenant.org/version/1/4/).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable
|
||||
behavior to any of the [project's core team](https://github.com/orgs/node-red/teams/core).
|
||||
behavior to any of the project's core team at team@nodered.org.
|
||||
|
||||
## Authors
|
||||
|
||||
|
BIN
editor/icons/batch.png
Normal file
BIN
editor/icons/batch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 712 B |
BIN
editor/icons/sort.png
Normal file
BIN
editor/icons/sort.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 793 B |
@@ -64,27 +64,31 @@ RED.comms = (function() {
|
||||
}
|
||||
}
|
||||
ws.onmessage = function(event) {
|
||||
var msg = JSON.parse(event.data);
|
||||
if (pendingAuth && msg.auth) {
|
||||
if (msg.auth === "ok") {
|
||||
pendingAuth = false;
|
||||
completeConnection();
|
||||
} else if (msg.auth === "fail") {
|
||||
// anything else is an error...
|
||||
active = false;
|
||||
RED.user.login({updateMenu:true},function() {
|
||||
connectWS();
|
||||
})
|
||||
var message = JSON.parse(event.data);
|
||||
for (var m = 0; m < message.length; m++) {
|
||||
var msg = message[m];
|
||||
if (pendingAuth && msg.auth) {
|
||||
if (msg.auth === "ok") {
|
||||
pendingAuth = false;
|
||||
completeConnection();
|
||||
} else if (msg.auth === "fail") {
|
||||
// anything else is an error...
|
||||
active = false;
|
||||
RED.user.login({updateMenu:true},function() {
|
||||
connectWS();
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if (msg.topic) {
|
||||
for (var t in subscriptions) {
|
||||
if (subscriptions.hasOwnProperty(t)) {
|
||||
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
|
||||
if (re.test(msg.topic)) {
|
||||
var subscribers = subscriptions[t];
|
||||
if (subscribers) {
|
||||
for (var i=0;i<subscribers.length;i++) {
|
||||
subscribers[i](msg.topic,msg.data);
|
||||
else if (msg.topic) {
|
||||
for (var t in subscriptions) {
|
||||
if (subscriptions.hasOwnProperty(t)) {
|
||||
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
|
||||
if (re.test(msg.topic)) {
|
||||
var subscribers = subscriptions[t];
|
||||
if (subscribers) {
|
||||
for (var i=0;i<subscribers.length;i++) {
|
||||
subscribers[i](msg.topic,msg.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -321,6 +321,9 @@ RED.history = (function() {
|
||||
},
|
||||
peek: function() {
|
||||
return undo_history[undo_history.length-1];
|
||||
},
|
||||
clear: function() {
|
||||
undo_history = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,11 @@
|
||||
"ctrl-e": "core:show-export-dialog",
|
||||
"ctrl-i": "core:show-import-dialog",
|
||||
"ctrl-space": "core:toggle-sidebar",
|
||||
"ctrl-,": "core:show-user-settings"
|
||||
"ctrl-,": "core:show-user-settings",
|
||||
|
||||
"ctrl-alt-n": "core:new-project",
|
||||
"ctrl-alt-o": "core:open-project",
|
||||
"ctrl-g v": "core:show-version-control-tab"
|
||||
},
|
||||
"workspace": {
|
||||
"backspace": "core:delete-selection",
|
||||
|
@@ -24,7 +24,25 @@
|
||||
url: 'nodes',
|
||||
success: function(data) {
|
||||
RED.nodes.setNodeList(data);
|
||||
RED.i18n.loadNodeCatalogs(loadNodes);
|
||||
RED.i18n.loadNodeCatalogs(function() {
|
||||
loadIconList(loadNodes);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadIconList(done) {
|
||||
$.ajax({
|
||||
headers: {
|
||||
"Accept":"application/json"
|
||||
},
|
||||
cache: false,
|
||||
url: 'icons',
|
||||
success: function(data) {
|
||||
RED.nodes.setIconSets(data);
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -42,12 +60,32 @@
|
||||
$("#palette > .palette-spinner").hide();
|
||||
$(".palette-scroll").removeClass("hide");
|
||||
$("#palette-search").removeClass("hide");
|
||||
loadFlows();
|
||||
loadFlows(function() {
|
||||
if (RED.settings.theme("projects.enabled",false)) {
|
||||
RED.projects.refresh(function(activeProject) {
|
||||
RED.sidebar.info.refresh()
|
||||
if (!activeProject) {
|
||||
// Projects enabled but no active project
|
||||
RED.menu.setDisabled('menu-item-projects-open',true);
|
||||
if (activeProject === false) {
|
||||
// User previously decline the migration to projects.
|
||||
} else { // null/undefined
|
||||
RED.projects.showStartup();
|
||||
}
|
||||
}
|
||||
completeLoad();
|
||||
});
|
||||
} else {
|
||||
// Projects disabled by the user
|
||||
RED.sidebar.info.refresh()
|
||||
completeLoad();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadFlows() {
|
||||
function loadFlows(done) {
|
||||
$.ajax({
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
@@ -55,114 +93,218 @@
|
||||
cache: false,
|
||||
url: 'flows',
|
||||
success: function(nodes) {
|
||||
var currentHash = window.location.hash;
|
||||
RED.nodes.version(nodes.rev);
|
||||
RED.nodes.import(nodes.flows);
|
||||
RED.nodes.dirty(false);
|
||||
RED.view.redraw(true);
|
||||
if (/^#flow\/.+$/.test(currentHash)) {
|
||||
RED.workspaces.show(currentHash.substring(6));
|
||||
if (nodes) {
|
||||
var currentHash = window.location.hash;
|
||||
RED.nodes.version(nodes.rev);
|
||||
RED.nodes.import(nodes.flows);
|
||||
RED.nodes.dirty(false);
|
||||
RED.view.redraw(true);
|
||||
if (/^#flow\/.+$/.test(currentHash)) {
|
||||
RED.workspaces.show(currentHash.substring(6));
|
||||
}
|
||||
}
|
||||
|
||||
var persistentNotifications = {};
|
||||
RED.comms.subscribe("notification/#",function(topic,msg) {
|
||||
var parts = topic.split("/");
|
||||
var notificationId = parts[1];
|
||||
if (notificationId === "runtime-deploy") {
|
||||
// handled in ui/deploy.js
|
||||
return;
|
||||
}
|
||||
if (notificationId === "node") {
|
||||
// handled below
|
||||
return;
|
||||
}
|
||||
if (msg.text) {
|
||||
var text = RED._(msg.text,{default:msg.text});
|
||||
if (!persistentNotifications.hasOwnProperty(notificationId)) {
|
||||
persistentNotifications[notificationId] = RED.notify(text,msg.type,msg.timeout === undefined,msg.timeout);
|
||||
} else {
|
||||
persistentNotifications[notificationId].update(text,msg.timeout);
|
||||
}
|
||||
} else if (persistentNotifications.hasOwnProperty(notificationId)) {
|
||||
persistentNotifications[notificationId].close();
|
||||
delete persistentNotifications[notificationId];
|
||||
}
|
||||
});
|
||||
RED.comms.subscribe("status/#",function(topic,msg) {
|
||||
var parts = topic.split("/");
|
||||
var node = RED.nodes.node(parts[1]);
|
||||
if (node) {
|
||||
if (msg.hasOwnProperty("text")) {
|
||||
if (msg.text[0] !== ".") {
|
||||
msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()});
|
||||
}
|
||||
}
|
||||
node.status = msg;
|
||||
node.dirty = true;
|
||||
RED.view.redraw();
|
||||
}
|
||||
});
|
||||
RED.comms.subscribe("notification/node/#",function(topic,msg) {
|
||||
var i,m;
|
||||
var typeList;
|
||||
var info;
|
||||
if (topic == "notification/node/added") {
|
||||
var addedTypes = [];
|
||||
msg.forEach(function(m) {
|
||||
var id = m.id;
|
||||
RED.nodes.addNodeSet(m);
|
||||
addedTypes = addedTypes.concat(m.types);
|
||||
RED.i18n.loadCatalog(id, function() {
|
||||
$.get('nodes/'+id, function(data) {
|
||||
$("body").append(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
if (addedTypes.length) {
|
||||
typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
|
||||
}
|
||||
} else if (topic == "notification/node/removed") {
|
||||
for (i=0;i<msg.length;i++) {
|
||||
m = msg[i];
|
||||
info = RED.nodes.removeNodeSet(m.id);
|
||||
if (info.added) {
|
||||
typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success");
|
||||
}
|
||||
}
|
||||
} else if (topic == "notification/node/enabled") {
|
||||
if (msg.types) {
|
||||
info = RED.nodes.getNodeSet(msg.id);
|
||||
if (info.added) {
|
||||
RED.nodes.enableNodeSet(msg.id);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
|
||||
} else {
|
||||
$.get('nodes/'+msg.id, function(data) {
|
||||
$("body").append(data);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (topic == "notification/node/disabled") {
|
||||
if (msg.types) {
|
||||
RED.nodes.disableNodeSet(msg.id);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeDisabled", {count:msg.types.length})+typeList,"success");
|
||||
}
|
||||
} else if (topic == "node/upgraded") {
|
||||
RED.notify(RED._("palette.event.nodeUpgraded", {module:msg.module,version:msg.version}),"success");
|
||||
RED.nodes.registry.setModulePendingUpdated(msg.module,msg.version);
|
||||
}
|
||||
// Refresh flow library to ensure any examples are updated
|
||||
RED.library.loadFlowLibrary();
|
||||
});
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function completeLoad() {
|
||||
var persistentNotifications = {};
|
||||
RED.comms.subscribe("notification/#",function(topic,msg) {
|
||||
var parts = topic.split("/");
|
||||
var notificationId = parts[1];
|
||||
if (notificationId === "runtime-deploy") {
|
||||
// handled in ui/deploy.js
|
||||
return;
|
||||
}
|
||||
if (notificationId === "node") {
|
||||
// handled below
|
||||
return;
|
||||
}
|
||||
if (notificationId === "project-update") {
|
||||
RED.nodes.clear();
|
||||
RED.history.clear();
|
||||
RED.view.redraw(true);
|
||||
RED.projects.refresh(function() {
|
||||
loadFlows(function() {
|
||||
var project = RED.projects.getActiveProject();
|
||||
var message = {
|
||||
"change-branch":"Change to local branch '"+project.git.branches.local+"'",
|
||||
"abort-merge":"Git merge aborted",
|
||||
"loaded":"Project '"+msg.project+"' loaded",
|
||||
"updated":"Project '"+msg.project+"' updated",
|
||||
"pull":"Project '"+msg.project+"' reloaded",
|
||||
"revert": "Project '"+msg.project+"' reloaded"
|
||||
}[msg.action];
|
||||
RED.notify("<p>"+message+"</p>");
|
||||
RED.sidebar.info.refresh()
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.text) {
|
||||
msg.default = msg.text;
|
||||
var text = RED._(msg.text,msg);
|
||||
var options = {
|
||||
type: msg.type,
|
||||
fixed: msg.timeout === undefined,
|
||||
timeout: msg.timeout,
|
||||
id: notificationId
|
||||
}
|
||||
if (notificationId === "runtime-state") {
|
||||
if (msg.error === "missing-types") {
|
||||
text+="<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
if (!!RED.projects.getActiveProject()) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Manage project dependencies",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.projects.settings.show('deps');
|
||||
}
|
||||
}
|
||||
]
|
||||
// } else if (RED.settings.theme('palette.editable') !== false) {
|
||||
} else {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Close",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "credentials_load_failed") {
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Setup credentials",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.projects.showCredentialsPrompt();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "missing_flow_file") {
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Setup project files",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.projects.showFilesPrompt();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "project_empty") {
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "No thanks",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "Create default project files",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.projects.createDefaultFileSet();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!persistentNotifications.hasOwnProperty(notificationId)) {
|
||||
persistentNotifications[notificationId] = RED.notify(text,options);
|
||||
} else {
|
||||
persistentNotifications[notificationId].update(text,options);
|
||||
}
|
||||
} else if (persistentNotifications.hasOwnProperty(notificationId)) {
|
||||
persistentNotifications[notificationId].close();
|
||||
delete persistentNotifications[notificationId];
|
||||
}
|
||||
});
|
||||
RED.comms.subscribe("status/#",function(topic,msg) {
|
||||
var parts = topic.split("/");
|
||||
var node = RED.nodes.node(parts[1]);
|
||||
if (node) {
|
||||
if (msg.hasOwnProperty("text")) {
|
||||
if (msg.text[0] !== ".") {
|
||||
msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()});
|
||||
}
|
||||
}
|
||||
node.status = msg;
|
||||
node.dirty = true;
|
||||
RED.view.redraw();
|
||||
}
|
||||
});
|
||||
RED.comms.subscribe("notification/node/#",function(topic,msg) {
|
||||
var i,m;
|
||||
var typeList;
|
||||
var info;
|
||||
if (topic == "notification/node/added") {
|
||||
var addedTypes = [];
|
||||
msg.forEach(function(m) {
|
||||
var id = m.id;
|
||||
RED.nodes.addNodeSet(m);
|
||||
addedTypes = addedTypes.concat(m.types);
|
||||
RED.i18n.loadCatalog(id, function() {
|
||||
$.get('nodes/'+id, function(data) {
|
||||
$("body").append(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
if (addedTypes.length) {
|
||||
typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
|
||||
}
|
||||
loadIconList();
|
||||
} else if (topic == "notification/node/removed") {
|
||||
for (i=0;i<msg.length;i++) {
|
||||
m = msg[i];
|
||||
info = RED.nodes.removeNodeSet(m.id);
|
||||
if (info.added) {
|
||||
typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success");
|
||||
}
|
||||
}
|
||||
loadIconList();
|
||||
} else if (topic == "notification/node/enabled") {
|
||||
if (msg.types) {
|
||||
info = RED.nodes.getNodeSet(msg.id);
|
||||
if (info.added) {
|
||||
RED.nodes.enableNodeSet(msg.id);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
|
||||
} else {
|
||||
$.get('nodes/'+msg.id, function(data) {
|
||||
$("body").append(data);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (topic == "notification/node/disabled") {
|
||||
if (msg.types) {
|
||||
RED.nodes.disableNodeSet(msg.id);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeDisabled", {count:msg.types.length})+typeList,"success");
|
||||
}
|
||||
} else if (topic == "node/upgraded") {
|
||||
RED.notify(RED._("palette.event.nodeUpgraded", {module:msg.module,version:msg.version}),"success");
|
||||
RED.nodes.registry.setModulePendingUpdated(msg.module,msg.version);
|
||||
}
|
||||
// Refresh flow library to ensure any examples are updated
|
||||
RED.library.loadFlowLibrary();
|
||||
});
|
||||
}
|
||||
|
||||
function showAbout() {
|
||||
$.get('red/about', function(data) {
|
||||
var aboutHeader = '<div style="text-align:center;">'+
|
||||
@@ -176,6 +318,14 @@
|
||||
|
||||
function loadEditor() {
|
||||
var menuOptions = [];
|
||||
if (RED.settings.theme("projects.enabled",false)) {
|
||||
menuOptions.push({id:"menu-item-projects-menu",label:"Projects",options:[
|
||||
{id:"menu-item-projects-new",label:"New...",disabled:false,onselect:"core:new-project"},
|
||||
{id:"menu-item-projects-open",label:"Open...",disabled:false,onselect:"core:open-project"}
|
||||
]});
|
||||
}
|
||||
|
||||
|
||||
menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[
|
||||
// {id:"menu-item-view-show-grid",setting:"view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:"core:toggle-show-grid"},
|
||||
// {id:"menu-item-view-snap-grid",setting:"view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"},
|
||||
@@ -219,12 +369,12 @@
|
||||
menuOptions.push(null);
|
||||
}
|
||||
|
||||
menuOptions.push({id:"menu-item-user-settings",label:RED._("menu.label.userSettings"),onselect:"core:show-user-settings"});
|
||||
menuOptions.push({id:"menu-item-user-settings",label:RED._("menu.label.settings"),onselect:"core:show-user-settings"});
|
||||
menuOptions.push(null);
|
||||
|
||||
menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:"core:show-help"});
|
||||
menuOptions.push({id:"menu-item-help",
|
||||
label: RED.settings.theme("menu.menu-item-help.label","Node-RED website"),
|
||||
label: RED.settings.theme("menu.menu-item-help.label",RED._("menu.label.help")),
|
||||
href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")
|
||||
});
|
||||
menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: "core:show-about" });
|
||||
@@ -238,9 +388,18 @@
|
||||
RED.palette.init();
|
||||
if (RED.settings.theme('palette.editable') !== false) {
|
||||
RED.palette.editor.init();
|
||||
} else {
|
||||
console.log("Palette editor disabled");
|
||||
}
|
||||
|
||||
RED.sidebar.init();
|
||||
|
||||
if (RED.settings.theme("projects.enabled",false)) {
|
||||
RED.projects.init();
|
||||
} else {
|
||||
console.log("Projects disabled");
|
||||
}
|
||||
|
||||
RED.subflow.init();
|
||||
RED.workspaces.init();
|
||||
RED.clipboard.init();
|
||||
@@ -251,6 +410,7 @@
|
||||
RED.menu.init({id:"btn-sidemenu",options: menuOptions});
|
||||
|
||||
RED.deploy.init(RED.settings.theme("deployButton",null));
|
||||
RED.notifications.init();
|
||||
|
||||
RED.actions.add("core:show-about", showAbout);
|
||||
RED.nodes.init();
|
||||
|
@@ -40,6 +40,16 @@ RED.nodes = (function() {
|
||||
var nodeSets = {};
|
||||
var typeToId = {};
|
||||
var nodeDefinitions = {};
|
||||
var iconSets = {};
|
||||
|
||||
nodeDefinitions['tab'] = {
|
||||
defaults: {
|
||||
label: {value:""},
|
||||
disabled: {value: false},
|
||||
info: {value: ""}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var exports = {
|
||||
setModulePendingUpdated: function(module,version) {
|
||||
@@ -161,6 +171,12 @@ RED.nodes = (function() {
|
||||
},
|
||||
getNodeType: function(nt) {
|
||||
return nodeDefinitions[nt];
|
||||
},
|
||||
setIconSets: function(sets) {
|
||||
iconSets = sets;
|
||||
},
|
||||
getIconSets: function() {
|
||||
return iconSets;
|
||||
}
|
||||
};
|
||||
return exports;
|
||||
@@ -256,10 +272,19 @@ RED.nodes = (function() {
|
||||
if (updatedConfigNode) {
|
||||
RED.workspaces.refresh();
|
||||
}
|
||||
try {
|
||||
if (node._def.oneditdelete) {
|
||||
node._def.oneditdelete.call(node);
|
||||
}
|
||||
} catch(err) {
|
||||
console.log("oneditdelete",node.id,node.type,err.toString());
|
||||
}
|
||||
RED.events.emit('nodes:remove',node);
|
||||
}
|
||||
}
|
||||
if (node && node._def.onremove) {
|
||||
// Deprecated: never documented but used by some early nodes
|
||||
console.log("Deprecated API warning: node type ",node.type," has an onremove function - should be oneditremove - please report");
|
||||
node._def.onremove.call(n);
|
||||
}
|
||||
return {links:removedLinks,nodes:removedNodes};
|
||||
@@ -274,14 +299,7 @@ RED.nodes = (function() {
|
||||
|
||||
function addWorkspace(ws) {
|
||||
workspaces[ws.id] = ws;
|
||||
ws._def = {
|
||||
defaults: {
|
||||
label: {value:""},
|
||||
disabled: {value: false},
|
||||
info: {value: ""}
|
||||
}
|
||||
};
|
||||
|
||||
ws._def = RED.nodes.getType('tab');
|
||||
workspacesOrder.push(ws.id);
|
||||
}
|
||||
function getWorkspace(id) {
|
||||
@@ -483,6 +501,12 @@ RED.nodes = (function() {
|
||||
if (n.outputs > 0 && n.outputLabels && !/^\s*$/.test(n.outputLabels.join(""))) {
|
||||
node.outputLabels = n.outputLabels.slice();
|
||||
}
|
||||
if ((!n._def.defaults || !n._def.defaults.hasOwnProperty("icon")) && n.icon) {
|
||||
var defIcon = RED.utils.getDefaultNodeIcon(n._def, n);
|
||||
if (n.icon !== defIcon.module+"/"+defIcon.file) {
|
||||
node.icon = n.icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -699,7 +723,9 @@ RED.nodes = (function() {
|
||||
if (!$.isArray(newNodes)) {
|
||||
newNodes = [newNodes];
|
||||
}
|
||||
var isInitialLoad = false;
|
||||
if (!initialLoad) {
|
||||
isInitialLoad = true;
|
||||
initialLoad = JSON.parse(JSON.stringify(newNodes));
|
||||
}
|
||||
var unknownTypes = [];
|
||||
@@ -720,7 +746,7 @@ RED.nodes = (function() {
|
||||
}
|
||||
|
||||
}
|
||||
if (unknownTypes.length > 0) {
|
||||
if (!isInitialLoad && unknownTypes.length > 0) {
|
||||
var typeList = "<ul><li>"+unknownTypes.join("</li><li>")+"</li></ul>";
|
||||
var type = "type"+(unknownTypes.length > 1?"s":"");
|
||||
RED.notify("<strong>"+RED._("clipboard.importUnrecognised",{count:unknownTypes.length})+"</strong>"+typeList,"error",false,10000);
|
||||
@@ -817,7 +843,7 @@ RED.nodes = (function() {
|
||||
|
||||
// Add a tab if there isn't one there already
|
||||
if (defaultWorkspace == null) {
|
||||
defaultWorkspace = { type:"tab", id:getID(), label:RED._('workspace.defaultName',{number:1})};
|
||||
defaultWorkspace = { type:"tab", id:getID(), disabled: false, info:"", label:RED._('workspace.defaultName',{number:1})};
|
||||
addWorkspace(defaultWorkspace);
|
||||
RED.workspaces.add(defaultWorkspace);
|
||||
new_workspaces.push(defaultWorkspace);
|
||||
@@ -870,7 +896,7 @@ RED.nodes = (function() {
|
||||
|
||||
}
|
||||
|
||||
if (!existingConfigNode) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode._def.exclusive || existingConfigNode.z !== n.z) {
|
||||
if (!existingConfigNode || existingConfigNode._def.exclusive) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode.z !== n.z) {
|
||||
configNode = {id:n.id, z:n.z, type:n.type, users:[], _config:{}};
|
||||
for (d in def.defaults) {
|
||||
if (def.defaults.hasOwnProperty(d)) {
|
||||
@@ -913,6 +939,7 @@ RED.nodes = (function() {
|
||||
wires:n.wires,
|
||||
inputLabels: n.inputLabels,
|
||||
outputLabels: n.outputLabels,
|
||||
icon: n.icon,
|
||||
changed:false,
|
||||
_config:{}
|
||||
};
|
||||
@@ -1198,12 +1225,13 @@ RED.nodes = (function() {
|
||||
RED.workspaces.remove(workspaces[id]);
|
||||
});
|
||||
defaultWorkspace = null;
|
||||
|
||||
RED.nodes.dirty(true);
|
||||
initialLoad = null;
|
||||
RED.nodes.dirty(false);
|
||||
RED.view.redraw(true);
|
||||
RED.palette.refresh();
|
||||
RED.workspaces.refresh();
|
||||
RED.sidebar.config.refresh();
|
||||
RED.sidebar.info.refresh();
|
||||
|
||||
// var node_defs = {};
|
||||
// var nodes = [];
|
||||
@@ -1270,6 +1298,9 @@ RED.nodes = (function() {
|
||||
enableNodeSet: registry.enableNodeSet,
|
||||
disableNodeSet: registry.disableNodeSet,
|
||||
|
||||
setIconSets: registry.setIconSets,
|
||||
getIconSets: registry.getIconSets,
|
||||
|
||||
registerType: registry.registerNodeType,
|
||||
getType: registry.getNodeType,
|
||||
convertNode: convertNode,
|
||||
|
@@ -18,6 +18,9 @@
|
||||
RED.settings = (function () {
|
||||
|
||||
var loadedSettings = {};
|
||||
var userSettings = {};
|
||||
var settingsDirty = false;
|
||||
var pendingSave;
|
||||
|
||||
var hasLocalStorage = function () {
|
||||
try {
|
||||
@@ -31,7 +34,12 @@ RED.settings = (function () {
|
||||
if (!hasLocalStorage()) {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
if (key === "auth-tokens") {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
} else {
|
||||
userSettings[key] = value;
|
||||
saveUserSettings();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -44,14 +52,23 @@ RED.settings = (function () {
|
||||
if (!hasLocalStorage()) {
|
||||
return undefined;
|
||||
}
|
||||
return JSON.parse(localStorage.getItem(key));
|
||||
if (key === "auth-tokens") {
|
||||
return JSON.parse(localStorage.getItem(key));
|
||||
} else {
|
||||
return userSettings[key];
|
||||
}
|
||||
};
|
||||
|
||||
var remove = function (key) {
|
||||
if (!hasLocalStorage()) {
|
||||
return;
|
||||
}
|
||||
localStorage.removeItem(key);
|
||||
if (key === "auth-tokens") {
|
||||
localStorage.removeItem(key);
|
||||
} else {
|
||||
delete userSettings[key];
|
||||
saveUserSettings();
|
||||
}
|
||||
};
|
||||
|
||||
var setProperties = function(data) {
|
||||
@@ -68,6 +85,10 @@ RED.settings = (function () {
|
||||
loadedSettings = data;
|
||||
};
|
||||
|
||||
var setUserSettings = function(data) {
|
||||
userSettings = data;
|
||||
}
|
||||
|
||||
var init = function (done) {
|
||||
var accessTokenMatch = /[?&]access_token=(.*?)(?:$|&)/.exec(window.location.search);
|
||||
if (accessTokenMatch) {
|
||||
@@ -106,7 +127,7 @@ RED.settings = (function () {
|
||||
RED.settings.remove("auth-tokens");
|
||||
}
|
||||
console.log("Node-RED: " + data.version);
|
||||
done();
|
||||
loadUserSettings(done);
|
||||
},
|
||||
error: function(jqXHR,textStatus,errorThrown) {
|
||||
if (jqXHR.status === 401) {
|
||||
@@ -115,12 +136,52 @@ RED.settings = (function () {
|
||||
}
|
||||
RED.user.login(function() { load(done); });
|
||||
} else {
|
||||
console.log("Unexpected error:",jqXHR.status,textStatus);
|
||||
console.log("Unexpected error loading settings:",jqXHR.status,textStatus);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function loadUserSettings(done) {
|
||||
$.ajax({
|
||||
headers: {
|
||||
"Accept": "application/json"
|
||||
},
|
||||
dataType: "json",
|
||||
cache: false,
|
||||
url: 'settings/user',
|
||||
success: function (data) {
|
||||
setUserSettings(data);
|
||||
done();
|
||||
},
|
||||
error: function(jqXHR,textStatus,errorThrown) {
|
||||
console.log("Unexpected error loading user settings:",jqXHR.status,textStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function saveUserSettings() {
|
||||
if (RED.user.hasPermission("settings.write")) {
|
||||
if (pendingSave) {
|
||||
clearTimeout(pendingSave);
|
||||
}
|
||||
pendingSave = setTimeout(function() {
|
||||
pendingSave = null;
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
contentType: 'application/json',
|
||||
url: 'settings/user',
|
||||
data: JSON.stringify(userSettings),
|
||||
success: function (data) {
|
||||
},
|
||||
error: function(jqXHR,textStatus,errorThrown) {
|
||||
console.log("Unexpected error saving user settings:",jqXHR.status,textStatus);
|
||||
}
|
||||
});
|
||||
},300);
|
||||
}
|
||||
}
|
||||
|
||||
function theme(property,defaultValue) {
|
||||
if (!RED.settings.editorTheme) {
|
||||
return defaultValue;
|
||||
@@ -143,10 +204,10 @@ RED.settings = (function () {
|
||||
return {
|
||||
init: init,
|
||||
load: load,
|
||||
loadUserSettings: loadUserSettings,
|
||||
set: set,
|
||||
get: get,
|
||||
remove: remove,
|
||||
theme: theme
|
||||
}
|
||||
})
|
||||
();
|
||||
})();
|
||||
|
@@ -203,7 +203,8 @@ RED.clipboard = (function() {
|
||||
var nodes = null;
|
||||
if (type === 'export-range-selected') {
|
||||
var selection = RED.view.selection();
|
||||
nodes = RED.nodes.createExportableNodeSet(selection.nodes);
|
||||
// Don't include the subflow meta-port nodes in the exported selection
|
||||
nodes = RED.nodes.createExportableNodeSet(selection.nodes.filter(function(n) { return n.type !== 'subflow'}));
|
||||
} else if (type === 'export-range-flow') {
|
||||
var activeWorkspace = RED.workspaces.active();
|
||||
nodes = RED.nodes.filterNodes({z:activeWorkspace});
|
||||
|
@@ -75,7 +75,7 @@
|
||||
addLabel = 'add';
|
||||
}
|
||||
}
|
||||
$('<a href="#" class="editor-button editor-button-small" style="margin-top: 4px;"><i class="fa fa-plus"></i> '+addLabel+'</a>')
|
||||
$('<a href="#" class="editor-button editor-button-small red-ui-editableList-addButton" style="margin-top: 4px;"><i class="fa fa-plus"></i> '+addLabel+'</a>')
|
||||
.appendTo(this.topContainer)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@@ -85,7 +85,7 @@
|
||||
if (this.element.css("position") === "absolute") {
|
||||
["top","left","bottom","right"].forEach(function(s) {
|
||||
var v = that.element.css(s);
|
||||
if (s!=="auto" && s!=="") {
|
||||
if (v!=="auto" && v!=="") {
|
||||
that.topContainer.css(s,v);
|
||||
that.uiContainer.css(s,"0");
|
||||
that.element.css(s,'auto');
|
||||
@@ -116,6 +116,11 @@
|
||||
this.uiContainer.css("minHeight",minHeight);
|
||||
this.element.css("minHeight",0);
|
||||
}
|
||||
var maxHeight = this.element.css("maxHeight");
|
||||
if (maxHeight !== '0px') {
|
||||
this.uiContainer.css("maxHeight",maxHeight);
|
||||
this.element.css("maxHeight",null);
|
||||
}
|
||||
if (this.options.height !== 'auto') {
|
||||
this.uiContainer.css("overflow-y","scroll");
|
||||
if (!isNaN(this.options.height)) {
|
||||
|
@@ -23,7 +23,7 @@ RED.popover = (function() {
|
||||
},
|
||||
"small": {
|
||||
top: 5,
|
||||
leftRight: 8,
|
||||
leftRight: 17,
|
||||
leftLeft: 16
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ RED.popover = (function() {
|
||||
var trigger = options.trigger;
|
||||
var content = options.content;
|
||||
var delay = options.delay;
|
||||
var autoClose = options.autoClose;
|
||||
var width = options.width||"auto";
|
||||
var size = options.size||"default";
|
||||
if (!deltaSizes[size]) {
|
||||
@@ -43,7 +44,7 @@ RED.popover = (function() {
|
||||
var active;
|
||||
var div;
|
||||
|
||||
var openPopup = function() {
|
||||
var openPopup = function(instant) {
|
||||
if (active) {
|
||||
div = $('<div class="red-ui-popover red-ui-popover-'+direction+'"></div>').appendTo("body");
|
||||
if (size !== "default") {
|
||||
@@ -62,7 +63,6 @@ RED.popover = (function() {
|
||||
var targetPos = target.offset();
|
||||
var targetWidth = target.width();
|
||||
var targetHeight = target.height();
|
||||
|
||||
var divHeight = div.height();
|
||||
var divWidth = div.width();
|
||||
if (direction === 'right') {
|
||||
@@ -70,23 +70,29 @@ RED.popover = (function() {
|
||||
} else if (direction === 'left') {
|
||||
div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left-deltaSizes[size].leftLeft-divWidth});
|
||||
}
|
||||
|
||||
div.fadeIn("fast");
|
||||
if (instant) {
|
||||
div.show();
|
||||
} else {
|
||||
div.fadeIn("fast");
|
||||
}
|
||||
}
|
||||
}
|
||||
var closePopup = function() {
|
||||
var closePopup = function(instant) {
|
||||
if (!active) {
|
||||
if (div) {
|
||||
div.fadeOut("fast",function() {
|
||||
if (instant) {
|
||||
$(this).remove();
|
||||
});
|
||||
} else {
|
||||
div.fadeOut("fast",function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
div = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trigger === 'hover') {
|
||||
|
||||
target.on('mouseenter',function(e) {
|
||||
clearTimeout(timer);
|
||||
active = true;
|
||||
@@ -110,18 +116,26 @@ RED.popover = (function() {
|
||||
openPopup();
|
||||
}
|
||||
});
|
||||
} else if (autoClose) {
|
||||
setTimeout(function() {
|
||||
active = false;
|
||||
closePopup();
|
||||
},autoClose);
|
||||
}
|
||||
var res = {
|
||||
setContent: function(_content) {
|
||||
content = _content;
|
||||
return res;
|
||||
},
|
||||
open: function () {
|
||||
open: function (instant) {
|
||||
active = true;
|
||||
openPopup();
|
||||
openPopup(instant);
|
||||
return res;
|
||||
},
|
||||
close: function () {
|
||||
close: function (instant) {
|
||||
active = false;
|
||||
closePopup();
|
||||
closePopup(instant);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@@ -17,11 +17,31 @@
|
||||
RED.stack = (function() {
|
||||
function createStack(options) {
|
||||
var container = options.container;
|
||||
|
||||
container.addClass("red-ui-stack");
|
||||
var contentHeight = 0;
|
||||
var entries = [];
|
||||
|
||||
var visible = true;
|
||||
// TODO: make this a singleton function - and watch out for stacks no longer
|
||||
// in the DOM
|
||||
var resizeStack = function() {
|
||||
if (entries.length > 0) {
|
||||
var headerHeight = 0;
|
||||
entries.forEach(function(entry) {
|
||||
headerHeight += entry.header.outerHeight();
|
||||
});
|
||||
|
||||
var height = container.innerHeight();
|
||||
contentHeight = height - headerHeight - (entries.length-1);
|
||||
entries.forEach(function(e) {
|
||||
e.contentWrap.height(contentHeight);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (options.fill && options.singleExpanded) {
|
||||
$(window).resize(resizeStack);
|
||||
$(window).focus(resizeStack);
|
||||
}
|
||||
return {
|
||||
add: function(entry) {
|
||||
entries.push(entry);
|
||||
@@ -30,7 +50,12 @@ RED.stack = (function() {
|
||||
entry.container.hide();
|
||||
}
|
||||
var header = $('<div class="palette-header"></div>').appendTo(entry.container);
|
||||
entry.content = $('<div></div>').appendTo(entry.container);
|
||||
entry.header = header;
|
||||
entry.contentWrap = $('<div></div>',{style:"position:relative"}).appendTo(entry.container);
|
||||
if (options.fill) {
|
||||
entry.contentWrap.css("height",contentHeight);
|
||||
}
|
||||
entry.content = $('<div></div>').appendTo(entry.contentWrap);
|
||||
if (entry.collapsible !== false) {
|
||||
header.click(function() {
|
||||
if (options.singleExpanded) {
|
||||
@@ -49,11 +74,13 @@ RED.stack = (function() {
|
||||
var icon = $('<i class="fa fa-angle-down"></i>').appendTo(header);
|
||||
|
||||
if (entry.expanded) {
|
||||
entry.container.addClass("palette-category-expanded");
|
||||
icon.addClass("expanded");
|
||||
} else {
|
||||
entry.content.hide();
|
||||
entry.contentWrap.hide();
|
||||
}
|
||||
} else {
|
||||
$('<i style="opacity: 0.5;" class="fa fa-angle-down expanded"></i>').appendTo(header);
|
||||
header.css("cursor","default");
|
||||
}
|
||||
entry.title = $('<span></span>').html(entry.title).appendTo(header);
|
||||
@@ -74,24 +101,35 @@ RED.stack = (function() {
|
||||
if (entry.onexpand) {
|
||||
entry.onexpand.call(entry);
|
||||
}
|
||||
if (options.singleExpanded) {
|
||||
entries.forEach(function(e) {
|
||||
if (e !== entry) {
|
||||
e.collapse();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
icon.addClass("expanded");
|
||||
entry.content.slideDown(200);
|
||||
entry.container.addClass("palette-category-expanded");
|
||||
entry.contentWrap.slideDown(200);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
entry.collapse = function() {
|
||||
if (entry.isExpanded()) {
|
||||
icon.removeClass("expanded");
|
||||
entry.content.slideUp(200);
|
||||
entry.container.removeClass("palette-category-expanded");
|
||||
entry.contentWrap.slideUp(200);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
entry.isExpanded = function() {
|
||||
return icon.hasClass("expanded");
|
||||
return entry.container.hasClass("palette-category-expanded");
|
||||
};
|
||||
|
||||
if (options.fill && options.singleExpanded) {
|
||||
resizeStack();
|
||||
}
|
||||
return entry;
|
||||
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
@@ -108,9 +146,13 @@ RED.stack = (function() {
|
||||
entry.container.show();
|
||||
});
|
||||
return this;
|
||||
},
|
||||
resize: function() {
|
||||
if (resizeStack) {
|
||||
resizeStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
@@ -99,7 +99,7 @@
|
||||
this.uiSelect = this.elementDiv.wrap( "<div>" ).parent();
|
||||
var attrStyle = this.element.attr('style');
|
||||
var m;
|
||||
if ((m = /width\s*:\s*(\d+(%|px))/i.exec(attrStyle)) !== null) {
|
||||
if ((m = /width\s*:\s*(calc\s*\(.*\)|\d+(%|px))/i.exec(attrStyle)) !== null) {
|
||||
this.element.css('width','100%');
|
||||
this.uiSelect.width(m[1]);
|
||||
this.uiWidth = null;
|
||||
@@ -354,10 +354,27 @@
|
||||
return this.element.val();
|
||||
} else {
|
||||
if (this.typeMap[this.propertyType].options) {
|
||||
if (this.typeMap[this.propertyType].options.indexOf(value) === -1) {
|
||||
value = "";
|
||||
var validValue = false;
|
||||
var label;
|
||||
for (var i=0;i<this.typeMap[this.propertyType].options.length;i++) {
|
||||
var op = this.typeMap[this.propertyType].options[i];
|
||||
if (typeof op === "string") {
|
||||
if (op === value) {
|
||||
label = value;
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
} else if (op.value === value) {
|
||||
label = op.label||op.value;
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.optionSelectLabel.text(value);
|
||||
if (!validValue) {
|
||||
value = "";
|
||||
label = "";
|
||||
}
|
||||
this.optionSelectLabel.text(label);
|
||||
}
|
||||
this.element.val(value);
|
||||
this.element.trigger('change',this.type(),value);
|
||||
@@ -394,11 +411,31 @@
|
||||
that.value(v);
|
||||
});
|
||||
var currentVal = this.element.val();
|
||||
if (opt.options.indexOf(currentVal) !== -1) {
|
||||
this.optionSelectLabel.text(currentVal);
|
||||
} else {
|
||||
this.value(opt.options[0]);
|
||||
var validValue = false;
|
||||
var op;
|
||||
for (var i=0;i<opt.options.length;i++) {
|
||||
op = opt.options[i];
|
||||
if (typeof op === "string") {
|
||||
if (op === currentVal) {
|
||||
this.optionSelectLabel.text(currentVal);
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
} else if (op.value === currentVal) {
|
||||
this.optionSelectLabel.text(op.label||op.value);
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!validValue) {
|
||||
op = opt.options[0];
|
||||
if (typeof op === "string") {
|
||||
this.value(op);
|
||||
} else {
|
||||
this.value(op.value);
|
||||
}
|
||||
}
|
||||
console.log(validValue);
|
||||
}
|
||||
} else {
|
||||
if (this.optionMenu) {
|
||||
|
@@ -97,113 +97,6 @@ RED.deploy = (function() {
|
||||
|
||||
RED.actions.add("core:deploy-flows",save);
|
||||
|
||||
$( "#node-dialog-confirm-deploy" ).dialog({
|
||||
title: RED._('deploy.confirm.button.confirm'),
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 550,
|
||||
height: "auto",
|
||||
buttons: [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-review",
|
||||
text: RED._("deploy.confirm.button.review"),
|
||||
class: "primary disabled",
|
||||
click: function() {
|
||||
if (!$("#node-dialog-confirm-deploy-review").hasClass('disabled')) {
|
||||
RED.diff.showRemoteDiff();
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-merge",
|
||||
text: RED._("deploy.confirm.button.merge"),
|
||||
class: "primary disabled",
|
||||
click: function() {
|
||||
RED.diff.mergeDiff(currentDiff);
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-deploy",
|
||||
text: RED._("deploy.confirm.button.confirm"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
|
||||
var ignoreChecked = $( "#node-dialog-confirm-deploy-hide" ).prop("checked");
|
||||
if (ignoreChecked) {
|
||||
ignoreDeployWarnings[$( "#node-dialog-confirm-deploy-type" ).val()] = true;
|
||||
}
|
||||
save(true,/conflict/.test($("#node-dialog-confirm-deploy-type" ).val()));
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-overwrite",
|
||||
text: RED._("deploy.confirm.button.overwrite"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
save(true,/conflict/.test($("#node-dialog-confirm-deploy-type" ).val()));
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
],
|
||||
create: function() {
|
||||
$("#node-dialog-confirm-deploy").parent().find("div.ui-dialog-buttonpane")
|
||||
.prepend('<div style="height:0; vertical-align: middle; display:inline-block; margin-top: 13px; float:left;">'+
|
||||
'<input style="vertical-align:top;" type="checkbox" id="node-dialog-confirm-deploy-hide">'+
|
||||
'<label style="display:inline;" for="node-dialog-confirm-deploy-hide"> do not warn about this again</label>'+
|
||||
'<input type="hidden" id="node-dialog-confirm-deploy-type">'+
|
||||
'</div>');
|
||||
},
|
||||
open: function() {
|
||||
var deployType = $("#node-dialog-confirm-deploy-type" ).val();
|
||||
if (/conflict/.test(deployType)) {
|
||||
$( "#node-dialog-confirm-deploy" ).dialog('option','title', RED._('deploy.confirm.button.review'));
|
||||
$("#node-dialog-confirm-deploy-deploy").hide();
|
||||
$("#node-dialog-confirm-deploy-review").addClass('disabled').show();
|
||||
$("#node-dialog-confirm-deploy-merge").addClass('disabled').show();
|
||||
$("#node-dialog-confirm-deploy-overwrite").toggle(deployType === "deploy-conflict");
|
||||
currentDiff = null;
|
||||
$("#node-dialog-confirm-deploy-conflict-checking").show();
|
||||
$("#node-dialog-confirm-deploy-conflict-auto-merge").hide();
|
||||
$("#node-dialog-confirm-deploy-conflict-manual-merge").hide();
|
||||
|
||||
var now = Date.now();
|
||||
RED.diff.getRemoteDiff(function(diff) {
|
||||
var ellapsed = Math.max(1000 - (Date.now()-now), 0);
|
||||
currentDiff = diff;
|
||||
setTimeout(function() {
|
||||
$("#node-dialog-confirm-deploy-conflict-checking").hide();
|
||||
var d = Object.keys(diff.conflicts);
|
||||
if (d.length === 0) {
|
||||
$("#node-dialog-confirm-deploy-conflict-auto-merge").show();
|
||||
$("#node-dialog-confirm-deploy-merge").removeClass('disabled')
|
||||
} else {
|
||||
$("#node-dialog-confirm-deploy-conflict-manual-merge").show();
|
||||
}
|
||||
$("#node-dialog-confirm-deploy-review").removeClass('disabled')
|
||||
},ellapsed);
|
||||
})
|
||||
|
||||
|
||||
$("#node-dialog-confirm-deploy-hide").parent().hide();
|
||||
} else {
|
||||
$( "#node-dialog-confirm-deploy" ).dialog('option','title', RED._('deploy.confirm.button.confirm'));
|
||||
$("#node-dialog-confirm-deploy-deploy").show();
|
||||
$("#node-dialog-confirm-deploy-overwrite").hide();
|
||||
$("#node-dialog-confirm-deploy-review").hide();
|
||||
$("#node-dialog-confirm-deploy-merge").hide();
|
||||
$("#node-dialog-confirm-deploy-hide").parent().show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
RED.events.on('nodes:change',function(state) {
|
||||
if (state.dirty) {
|
||||
@@ -224,24 +117,30 @@ RED.deploy = (function() {
|
||||
if (currentRev === null || deployInflight || currentRev === msg.revision) {
|
||||
return;
|
||||
}
|
||||
var message = $('<div>'+RED._('deploy.confirm.backgroundUpdate')+
|
||||
'<br><br><div class="ui-dialog-buttonset">'+
|
||||
'<button>'+RED._('deploy.confirm.button.ignore')+'</button>'+
|
||||
'<button class="primary">'+RED._('deploy.confirm.button.review')+'</button>'+
|
||||
'</div></div>');
|
||||
$(message.find('button')[0]).click(function(evt) {
|
||||
evt.preventDefault();
|
||||
activeNotifyMessage.close();
|
||||
activeNotifyMessage = null;
|
||||
})
|
||||
$(message.find('button')[1]).click(function(evt) {
|
||||
evt.preventDefault();
|
||||
activeNotifyMessage.close();
|
||||
var nns = RED.nodes.createCompleteNodeSet();
|
||||
resolveConflict(nns,false);
|
||||
activeNotifyMessage = null;
|
||||
})
|
||||
activeNotifyMessage = RED.notify(message,null,true);
|
||||
var message = $('<p>').text(RED._('deploy.confirm.backgroundUpdate'));
|
||||
activeNotifyMessage = RED.notify(message,{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons: [
|
||||
{
|
||||
text: RED._('deploy.confirm.button.ignore'),
|
||||
click: function() {
|
||||
activeNotifyMessage.close();
|
||||
activeNotifyMessage = null;
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._('deploy.confirm.button.review'),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
activeNotifyMessage.close();
|
||||
var nns = RED.nodes.createCompleteNodeSet();
|
||||
resolveConflict(nns,false);
|
||||
activeNotifyMessage = null;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -271,16 +170,99 @@ RED.deploy = (function() {
|
||||
}
|
||||
|
||||
function resolveConflict(currentNodes, activeDeploy) {
|
||||
$( "#node-dialog-confirm-deploy-config" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-unknown" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-unused" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-conflict" ).show();
|
||||
$( "#node-dialog-confirm-deploy-type" ).val(activeDeploy?"deploy-conflict":"background-conflict");
|
||||
$( "#node-dialog-confirm-deploy" ).dialog( "open" );
|
||||
}
|
||||
var message = $('<div>');
|
||||
$('<p data-i18n="deploy.confirm.conflict"></p>').appendTo(message);
|
||||
var conflictCheck = $('<div id="node-dialog-confirm-deploy-conflict-checking" class="node-dialog-confirm-conflict-row">'+
|
||||
'<img src="red/images/spin.svg"/><div data-i18n="deploy.confirm.conflictChecking"></div>'+
|
||||
'</div>').appendTo(message);
|
||||
var conflictAutoMerge = $('<div class="node-dialog-confirm-conflict-row">'+
|
||||
'<i style="color: #3a3;" class="fa fa-check"></i><div data-i18n="deploy.confirm.conflictAutoMerge"></div>'+
|
||||
'</div>').hide().appendTo(message);
|
||||
var conflictManualMerge = $('<div id="node-dialog-confirm-deploy-conflict-manual-merge" class="node-dialog-confirm-conflict-row">'+
|
||||
'<i style="color: #999;" class="fa fa-exclamation"></i><div data-i18n="deploy.confirm.conflictManualMerge"></div>'+
|
||||
'</div>').hide().appendTo(message);
|
||||
|
||||
message.i18n();
|
||||
currentDiff = null;
|
||||
var buttons = [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
conflictNotification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-review",
|
||||
text: RED._("deploy.confirm.button.review"),
|
||||
class: "primary disabled",
|
||||
click: function() {
|
||||
if (!$("#node-dialog-confirm-deploy-review").hasClass('disabled')) {
|
||||
RED.diff.showRemoteDiff();
|
||||
conflictNotification.close();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-merge",
|
||||
text: RED._("deploy.confirm.button.merge"),
|
||||
class: "primary disabled",
|
||||
click: function() {
|
||||
if (!$("#node-dialog-confirm-deploy-merge").hasClass('disabled')) {
|
||||
RED.diff.mergeDiff(currentDiff);
|
||||
conflictNotification.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
if (activeDeploy) {
|
||||
buttons.push({
|
||||
id: "node-dialog-confirm-deploy-overwrite",
|
||||
text: RED._("deploy.confirm.button.overwrite"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
save(true,activeDeploy);
|
||||
conflictNotification.close();
|
||||
}
|
||||
})
|
||||
}
|
||||
var conflictNotification = RED.notify(message,{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
width: 600,
|
||||
buttons: buttons
|
||||
});
|
||||
|
||||
var now = Date.now();
|
||||
RED.diff.getRemoteDiff(function(diff) {
|
||||
var ellapsed = Math.max(1000 - (Date.now()-now), 0);
|
||||
currentDiff = diff;
|
||||
setTimeout(function() {
|
||||
conflictCheck.hide();
|
||||
var d = Object.keys(diff.conflicts);
|
||||
if (d.length === 0) {
|
||||
conflictAutoMerge.show();
|
||||
$("#node-dialog-confirm-deploy-merge").removeClass('disabled')
|
||||
} else {
|
||||
conflictManualMerge.show();
|
||||
}
|
||||
$("#node-dialog-confirm-deploy-review").removeClass('disabled')
|
||||
},ellapsed);
|
||||
})
|
||||
}
|
||||
function cropList(list) {
|
||||
if (list.length > 5) {
|
||||
var remainder = list.length - 5;
|
||||
list = list.slice(0,5);
|
||||
list.push(RED._("deploy.confirm.plusNMore",{count:remainder}));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
function save(skipValidation,force) {
|
||||
if (!$("#btn-deploy").hasClass("disabled")) {
|
||||
if (!RED.user.hasPermission("flows.write")) {
|
||||
RED.notify(RED._("user.errors.deploy"),"error");
|
||||
return;
|
||||
}
|
||||
if (!skipValidation) {
|
||||
var hasUnknown = false;
|
||||
var hasInvalid = false;
|
||||
@@ -310,39 +292,62 @@ RED.deploy = (function() {
|
||||
}
|
||||
});
|
||||
|
||||
$( "#node-dialog-confirm-deploy-config" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-unknown" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-unused" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-conflict" ).hide();
|
||||
|
||||
var showWarning = false;
|
||||
|
||||
var notificationMessage;
|
||||
var notificationButtons = [];
|
||||
var notification;
|
||||
if (hasUnknown && !ignoreDeployWarnings.unknown) {
|
||||
showWarning = true;
|
||||
$( "#node-dialog-confirm-deploy-type" ).val("unknown");
|
||||
$( "#node-dialog-confirm-deploy-unknown" ).show();
|
||||
$( "#node-dialog-confirm-deploy-unknown-list" )
|
||||
.html("<li>"+unknownNodes.join("</li><li>")+"</li>");
|
||||
notificationMessage = "<p>"+RED._('deploy.confirm.unknown')+"</p>"+
|
||||
'<ul class="node-dialog-configm-deploy-list"><li>'+cropList(unknownNodes).join("</li><li>")+"</li></ul><p>"+
|
||||
RED._('deploy.confirm.confirm')+
|
||||
"</p>";
|
||||
|
||||
notificationButtons= [
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-deploy",
|
||||
text: RED._("deploy.confirm.button.confirm"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
save(true);
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
];
|
||||
} else if (hasInvalid && !ignoreDeployWarnings.invalid) {
|
||||
showWarning = true;
|
||||
$( "#node-dialog-confirm-deploy-type" ).val("invalid");
|
||||
$( "#node-dialog-confirm-deploy-config" ).show();
|
||||
invalidNodes.sort(sortNodeInfo);
|
||||
$( "#node-dialog-confirm-deploy-invalid-list" )
|
||||
.html("<li>"+invalidNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"}).join("</li><li>")+"</li>");
|
||||
|
||||
} else if (hasUnusedConfig && !ignoreDeployWarnings.unusedConfig) {
|
||||
// showWarning = true;
|
||||
// $( "#node-dialog-confirm-deploy-type" ).val("unusedConfig");
|
||||
// $( "#node-dialog-confirm-deploy-unused" ).show();
|
||||
//
|
||||
// unusedConfigNodes.sort(sortNodeInfo);
|
||||
// $( "#node-dialog-confirm-deploy-unused-list" )
|
||||
// .html("<li>"+unusedConfigNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"}).join("</li><li>")+"</li>");
|
||||
notificationMessage = "<p>"+RED._('deploy.confirm.improperlyConfigured')+"</p>"+
|
||||
'<ul class="node-dialog-configm-deploy-list"><li>'+cropList(invalidNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"})).join("</li><li>")+"</li></ul><p>"+
|
||||
RED._('deploy.confirm.confirm')+
|
||||
"</p>";
|
||||
notificationButtons= [
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-deploy",
|
||||
text: RED._("deploy.confirm.button.confirm"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
save(true);
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
if (showWarning) {
|
||||
$( "#node-dialog-confirm-deploy-hide" ).prop("checked",false);
|
||||
$( "#node-dialog-confirm-deploy" ).dialog( "open" );
|
||||
notificationButtons.unshift(
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
);
|
||||
notification = RED.notify(notificationMessage,{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons:notificationButtons
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -382,7 +387,7 @@ RED.deploy = (function() {
|
||||
'<p>'+RED._("deploy.successfulDeploy")+'</p>'+
|
||||
'<p>'+RED._("deploy.unusedConfigNodes")+' <a href="#" onclick="RED.sidebar.config.show(true); return false;">'+RED._("deploy.unusedConfigNodesLink")+'</a></p>',"success",false,6000);
|
||||
} else {
|
||||
RED.notify(RED._("deploy.successfulDeploy"),"success");
|
||||
RED.notify('<p>'+RED._("deploy.successfulDeploy")+'</p>',"success");
|
||||
}
|
||||
RED.nodes.eachNode(function(node) {
|
||||
if (node.changed) {
|
||||
@@ -437,6 +442,10 @@ RED.deploy = (function() {
|
||||
}
|
||||
}
|
||||
return {
|
||||
init: init
|
||||
init: init,
|
||||
setDeployInflight: function(state) {
|
||||
deployInflight = state;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
1304
editor/js/ui/diff.js
1304
editor/js/ui/diff.js
File diff suppressed because it is too large
Load Diff
@@ -108,6 +108,17 @@ RED.editor = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.icon) {
|
||||
var iconPath = RED.utils.separateIconPath(node.icon);
|
||||
if (!iconPath.module) {
|
||||
return isValid;
|
||||
}
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
var iconFileList = iconSets[iconPath.module];
|
||||
if (!iconFileList || iconFileList.indexOf(iconPath.file) === -1) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
@@ -159,6 +170,23 @@ RED.editor = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node._def.hasOwnProperty("defaults") && !node._def.defaults.hasOwnProperty("icon") && node.icon) {
|
||||
var iconPath = RED.utils.separateIconPath(node.icon);
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
var iconFileList = iconSets[iconPath.module];
|
||||
var iconModule = $("#node-settings-icon-module");
|
||||
var iconFile = $("#node-settings-icon-file");
|
||||
if (!iconFileList) {
|
||||
iconModule.addClass("input-error");
|
||||
iconFile.removeClass("input-error");
|
||||
} else if (iconFileList.indexOf(iconPath.file) === -1) {
|
||||
iconModule.removeClass("input-error");
|
||||
iconFile.addClass("input-error");
|
||||
} else {
|
||||
iconModule.removeClass("input-error");
|
||||
iconFile.removeClass("input-error");
|
||||
}
|
||||
}
|
||||
}
|
||||
function validateNodeEditorProperty(node,defaults,property,prefix) {
|
||||
var input = $("#"+prefix+"-"+property);
|
||||
@@ -489,13 +517,16 @@ RED.editor = (function() {
|
||||
|
||||
function getEditStackTitle() {
|
||||
var title = '<ul class="editor-tray-breadcrumbs">';
|
||||
for (var i=0;i<editStack.length;i++) {
|
||||
var label;
|
||||
for (var i=editStack.length-1;i<editStack.length;i++) {
|
||||
var node = editStack[i];
|
||||
var label = node.type;
|
||||
label = node.type;
|
||||
if (node.type === '_expression') {
|
||||
label = RED._("expressionEditor.title");
|
||||
} else if (node.type === '_json') {
|
||||
label = RED._("jsonEditor.title");
|
||||
} else if (node.type === '_markdown') {
|
||||
label = RED._("markdownEditor.title");
|
||||
} else if (node.type === '_buffer') {
|
||||
label = RED._("bufferEditor.title");
|
||||
} else if (node.type === 'subflow') {
|
||||
@@ -522,7 +553,7 @@ RED.editor = (function() {
|
||||
title += '<li>'+label+'</li>';
|
||||
}
|
||||
title += '</ul>';
|
||||
return title;
|
||||
return label;
|
||||
}
|
||||
|
||||
function buildEditForm(container,formId,type,ns) {
|
||||
@@ -660,7 +691,7 @@ RED.editor = (function() {
|
||||
function buildLabelRow(type, index, value, placeHolder) {
|
||||
var result = $('<div>',{class:"node-label-form-row"});
|
||||
if (type === undefined) {
|
||||
$('<span>').html("none").appendTo(result);
|
||||
$('<span>').html(RED._("editor.noDefaultLabel")).appendTo(result);
|
||||
result.addClass("node-label-form-none");
|
||||
} else {
|
||||
result.addClass("");
|
||||
@@ -710,10 +741,88 @@ RED.editor = (function() {
|
||||
} else {
|
||||
buildLabelRow().appendTo(outputsDiv);
|
||||
}
|
||||
|
||||
if (!node._def.defaults.hasOwnProperty("icon")) {
|
||||
$('<div class="form-row"><div id="node-settings-icon"></div></div>').appendTo(dialogForm);
|
||||
var iconDiv = $("#node-settings-icon");
|
||||
$('<label data-i18n="editor.settingIcon">').appendTo(iconDiv);
|
||||
var iconForm = $('<div>',{class:"node-label-form-row"});
|
||||
iconForm.appendTo(iconDiv);
|
||||
$('<label>').appendTo(iconForm);
|
||||
|
||||
var selectIconModule = $('<select id="node-settings-icon-module"><option value=""></option></select>').appendTo(iconForm);
|
||||
var iconPath;
|
||||
if (node.icon) {
|
||||
iconPath = RED.utils.separateIconPath(node.icon);
|
||||
} else {
|
||||
iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||
}
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
Object.keys(iconSets).forEach(function(moduleName) {
|
||||
selectIconModule.append($("<option></option>").val(moduleName).text(moduleName));
|
||||
});
|
||||
if (iconPath.module && !iconSets[iconPath.module]) {
|
||||
selectIconModule.append($("<option disabled></option>").val(iconPath.module).text(iconPath.module));
|
||||
}
|
||||
selectIconModule.val(iconPath.module);
|
||||
var iconModuleHidden = $('<input type="hidden" id="node-settings-icon-module-hidden"></input>').appendTo(iconForm);
|
||||
iconModuleHidden.val(iconPath.module);
|
||||
|
||||
var selectIconFile = $('<select id="node-settings-icon-file"><option value=""></option></select>').appendTo(iconForm);
|
||||
selectIconModule.change(function() {
|
||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, true);
|
||||
});
|
||||
var iconFileHidden = $('<input type="hidden" id="node-settings-icon-file-hidden"></input>').appendTo(iconForm);
|
||||
iconFileHidden.val(iconPath.file);
|
||||
selectIconFile.change(function() {
|
||||
selectIconFile.removeClass("input-error");
|
||||
var fileName = selectIconFile.val();
|
||||
iconFileHidden.val(fileName);
|
||||
});
|
||||
var clear = $('<button class="editor-button editor-button-small"><i class="fa fa-times"></i></button>').appendTo(iconForm);
|
||||
clear.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||
selectIconModule.val(iconPath.module);
|
||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, true);
|
||||
selectIconFile.removeClass("input-error");
|
||||
selectIconFile.val(iconPath.file);
|
||||
iconFileHidden.val(iconPath.file);
|
||||
});
|
||||
|
||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, false);
|
||||
var iconFileList = iconSets[selectIconModule.val()];
|
||||
if (!iconFileList || iconFileList.indexOf(iconPath.file) === -1) {
|
||||
selectIconFile.append($("<option disabled></option>").val(iconPath.file).text(iconPath.file));
|
||||
}
|
||||
selectIconFile.val(iconPath.file);
|
||||
}
|
||||
}
|
||||
|
||||
function moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, updateIconFile) {
|
||||
selectIconFile.children().remove();
|
||||
var moduleName = selectIconModule.val();
|
||||
if (moduleName !== null) {
|
||||
iconModuleHidden.val(moduleName);
|
||||
}
|
||||
var iconFileList = iconSets[moduleName];
|
||||
if (iconFileList) {
|
||||
iconFileList.forEach(function(fileName) {
|
||||
if (updateIconFile) {
|
||||
updateIconFile = false;
|
||||
iconFileHidden.val(fileName);
|
||||
}
|
||||
selectIconFile.append($("<option></option>").val(fileName).text(fileName));
|
||||
});
|
||||
}
|
||||
selectIconFile.prop("disabled", !iconFileList);
|
||||
selectIconModule.removeClass("input-error");
|
||||
}
|
||||
|
||||
function showEditDialog(node) {
|
||||
var editing_node = node;
|
||||
var isDefaultIcon;
|
||||
var defaultIcon;
|
||||
editStack.push(node);
|
||||
RED.view.state(RED.state.EDITING);
|
||||
var type = node.type;
|
||||
@@ -882,6 +991,8 @@ RED.editor = (function() {
|
||||
if (outputsChanged) {
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
newValue = parseInt(newValue);
|
||||
}
|
||||
}
|
||||
if (editing_node[d] != newValue) {
|
||||
@@ -960,6 +1071,33 @@ RED.editor = (function() {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (!editing_node._def.defaults.hasOwnProperty("icon")) {
|
||||
var iconModule = $("#node-settings-icon-module-hidden").val();
|
||||
var iconFile = $("#node-settings-icon-file-hidden").val();
|
||||
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
|
||||
if (!isDefaultIcon) {
|
||||
if (icon !== editing_node.icon) {
|
||||
changes.icon = editing_node.icon;
|
||||
editing_node.icon = icon;
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
if (icon !== defaultIcon) {
|
||||
changes.icon = editing_node.icon;
|
||||
editing_node.icon = icon;
|
||||
changed = true;
|
||||
} else {
|
||||
var iconPath = RED.utils.getDefaultNodeIcon(editing_node._def, editing_node);
|
||||
var currentDefaultIcon = iconPath.module+"/"+iconPath.file;
|
||||
if (defaultIcon !== currentDefaultIcon) {
|
||||
changes.icon = editing_node.icon;
|
||||
editing_node.icon = currentDefaultIcon;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
var wasChanged = editing_node.changed;
|
||||
editing_node.changed = true;
|
||||
@@ -1051,6 +1189,13 @@ RED.editor = (function() {
|
||||
} else {
|
||||
ns = node._def.set.id;
|
||||
}
|
||||
var iconPath = RED.utils.getDefaultNodeIcon(node._def,node);
|
||||
defaultIcon = iconPath.module+"/"+iconPath.file;
|
||||
if (node.icon && node.icon !== defaultIcon) {
|
||||
isDefaultIcon = false;
|
||||
} else {
|
||||
isDefaultIcon = true;
|
||||
}
|
||||
buildEditForm(nodeProperties.content,"dialog-form",type,ns);
|
||||
buildLabelForm(portLabels.content,node);
|
||||
|
||||
@@ -1680,6 +1825,7 @@ RED.editor = (function() {
|
||||
|
||||
var trayOptions = {
|
||||
title: getEditStackTitle(),
|
||||
width: "inherit",
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
@@ -1838,12 +1984,12 @@ RED.editor = (function() {
|
||||
|
||||
tabs.addTab({
|
||||
id: 'expression-help',
|
||||
label: 'Function reference',
|
||||
label: RED._('expressionEditor.functionReference'),
|
||||
content: $("#node-input-expression-tab-help")
|
||||
});
|
||||
tabs.addTab({
|
||||
id: 'expression-tests',
|
||||
label: 'Test',
|
||||
label: RED._('expressionEditor.test'),
|
||||
content: $("#node-input-expression-tab-test")
|
||||
});
|
||||
testDataEditor = RED.editor.createEditor({
|
||||
@@ -1963,9 +2109,6 @@ RED.editor = (function() {
|
||||
},
|
||||
show: function() {}
|
||||
}
|
||||
if (editTrayWidthCache.hasOwnProperty(type)) {
|
||||
trayOptions.width = editTrayWidthCache[type];
|
||||
}
|
||||
RED.tray.show(trayOptions);
|
||||
}
|
||||
|
||||
@@ -1977,9 +2120,104 @@ RED.editor = (function() {
|
||||
editStack.push({type:type});
|
||||
RED.view.state(RED.state.EDITING);
|
||||
var expressionEditor;
|
||||
var changeTimer;
|
||||
|
||||
var checkValid = function() {
|
||||
var v = expressionEditor.getValue();
|
||||
try {
|
||||
JSON.parse(v);
|
||||
$("#node-dialog-ok").removeClass('disabled');
|
||||
return true;
|
||||
} catch(err) {
|
||||
$("#node-dialog-ok").addClass('disabled');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var trayOptions = {
|
||||
title: options.title || getEditStackTitle(),
|
||||
width: "inherit",
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
RED.tray.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-ok",
|
||||
text: RED._("common.label.done"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
if (options.requireValid && !checkValid()) {
|
||||
return;
|
||||
}
|
||||
onComplete(expressionEditor.getValue());
|
||||
RED.tray.close();
|
||||
}
|
||||
}
|
||||
],
|
||||
resize: function(dimensions) {
|
||||
editTrayWidthCache[type] = dimensions.width;
|
||||
|
||||
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
|
||||
var editorRow = $("#dialog-form>div.node-text-editor-row");
|
||||
var height = $("#dialog-form").height();
|
||||
for (var i=0;i<rows.size();i++) {
|
||||
height -= $(rows[i]).outerHeight(true);
|
||||
}
|
||||
height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom")));
|
||||
$(".node-text-editor").css("height",height+"px");
|
||||
expressionEditor.resize();
|
||||
},
|
||||
open: function(tray) {
|
||||
var trayBody = tray.find('.editor-tray-body');
|
||||
var dialogForm = buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor');
|
||||
expressionEditor = RED.editor.createEditor({
|
||||
id: 'node-input-json',
|
||||
value: "",
|
||||
mode:"ace/mode/json"
|
||||
});
|
||||
expressionEditor.getSession().setValue(value||"",-1);
|
||||
if (options.requireValid) {
|
||||
expressionEditor.getSession().on('change', function() {
|
||||
clearTimeout(changeTimer);
|
||||
changeTimer = setTimeout(checkValid,200);
|
||||
});
|
||||
checkValid();
|
||||
}
|
||||
$("#node-input-json-reformat").click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var v = expressionEditor.getValue()||"";
|
||||
try {
|
||||
v = JSON.stringify(JSON.parse(v),null,4);
|
||||
} catch(err) {
|
||||
// TODO: do an optimistic auto-format
|
||||
}
|
||||
expressionEditor.getSession().setValue(v||"",-1);
|
||||
});
|
||||
dialogForm.i18n();
|
||||
},
|
||||
close: function() {
|
||||
editStack.pop();
|
||||
expressionEditor.destroy();
|
||||
},
|
||||
show: function() {}
|
||||
}
|
||||
RED.tray.show(trayOptions);
|
||||
}
|
||||
|
||||
function editMarkdown(options) {
|
||||
var value = options.value;
|
||||
var onComplete = options.complete;
|
||||
var type = "_markdown"
|
||||
editStack.push({type:type});
|
||||
RED.view.state(RED.state.EDITING);
|
||||
var expressionEditor;
|
||||
|
||||
var trayOptions = {
|
||||
title: getEditStackTitle(),
|
||||
title: options.title || getEditStackTitle(),
|
||||
width: "inherit",
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
@@ -2015,21 +2253,14 @@ RED.editor = (function() {
|
||||
var trayBody = tray.find('.editor-tray-body');
|
||||
var dialogForm = buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor');
|
||||
expressionEditor = RED.editor.createEditor({
|
||||
id: 'node-input-json',
|
||||
value: "",
|
||||
mode:"ace/mode/json"
|
||||
});
|
||||
expressionEditor.getSession().setValue(value||"",-1);
|
||||
$("#node-input-json-reformat").click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var v = expressionEditor.getValue()||"";
|
||||
try {
|
||||
v = JSON.stringify(JSON.parse(v),null,4);
|
||||
} catch(err) {
|
||||
// TODO: do an optimistic auto-format
|
||||
}
|
||||
expressionEditor.getSession().setValue(v||"",-1);
|
||||
id: 'node-input-markdown',
|
||||
value: value,
|
||||
mode:"ace/mode/markdown"
|
||||
});
|
||||
if (options.header) {
|
||||
options.header.appendTo(tray.find('#node-input-markdown-title'));
|
||||
}
|
||||
|
||||
dialogForm.i18n();
|
||||
},
|
||||
close: function() {
|
||||
@@ -2038,9 +2269,6 @@ RED.editor = (function() {
|
||||
},
|
||||
show: function() {}
|
||||
}
|
||||
if (editTrayWidthCache.hasOwnProperty(type)) {
|
||||
trayOptions.width = editTrayWidthCache[type];
|
||||
}
|
||||
RED.tray.show(trayOptions);
|
||||
}
|
||||
|
||||
@@ -2083,6 +2311,7 @@ RED.editor = (function() {
|
||||
|
||||
var trayOptions = {
|
||||
title: getEditStackTitle(),
|
||||
width: "inherit",
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
@@ -2225,9 +2454,6 @@ RED.editor = (function() {
|
||||
},
|
||||
show: function() {}
|
||||
}
|
||||
if (editTrayWidthCache.hasOwnProperty(type)) {
|
||||
trayOptions.width = editTrayWidthCache[type];
|
||||
}
|
||||
RED.tray.show(trayOptions);
|
||||
}
|
||||
|
||||
@@ -2248,15 +2474,26 @@ RED.editor = (function() {
|
||||
editSubflow: showEditSubflowDialog,
|
||||
editExpression: editExpression,
|
||||
editJSON: editJSON,
|
||||
editMarkdown: editMarkdown,
|
||||
editBuffer: editBuffer,
|
||||
validateNode: validateNode,
|
||||
updateNodeProperties: updateNodeProperties, // TODO: only exposed for edit-undo
|
||||
|
||||
|
||||
createEditor: function(options) {
|
||||
var editor = ace.edit(options.id);
|
||||
var editor = ace.edit(options.id||options.element);
|
||||
editor.setTheme("ace/theme/tomorrow");
|
||||
var session = editor.getSession();
|
||||
session.on("changeAnnotation", function () {
|
||||
var annotations = session.getAnnotations() || [];
|
||||
var i = annotations.length;
|
||||
var len = annotations.length;
|
||||
while (i--) {
|
||||
if (/doctype first\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
|
||||
else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
|
||||
}
|
||||
if (len > annotations.length) { session.setAnnotations(annotations); }
|
||||
});
|
||||
if (options.mode) {
|
||||
session.setMode(options.mode);
|
||||
}
|
||||
@@ -2287,7 +2524,7 @@ RED.editor = (function() {
|
||||
if (options.globals) {
|
||||
setTimeout(function() {
|
||||
if (!!session.$worker) {
|
||||
session.$worker.send("setOptions", [{globals: options.globals, esversion:6}]);
|
||||
session.$worker.send("setOptions", [{globals: options.globals, esversion:6, sub:true, asi:true, maxerr:1000}]);
|
||||
}
|
||||
},100);
|
||||
}
|
||||
|
@@ -57,8 +57,24 @@ RED.keyboard = (function() {
|
||||
173:189
|
||||
}
|
||||
|
||||
function migrateOldKeymap() {
|
||||
if ('localStorage' in window && window['localStorage'] !== null) {
|
||||
var oldKeyMap = localStorage.getItem("keymap");
|
||||
if (oldKeyMap !== null) {
|
||||
localStorage.removeItem("keymap");
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.keymap = JSON.parse(oldKeyMap);
|
||||
RED.settings.set('editor',currentEditorSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
function init() {
|
||||
var userKeymap = RED.settings.get('keymap') || {};
|
||||
// Migrate from pre-0.18
|
||||
migrateOldKeymap();
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
var userKeymap = currentEditorSettings.keymap || {};
|
||||
|
||||
$.getJSON("red/keymap.json",function(data) {
|
||||
for (var scope in data) {
|
||||
if (data.hasOwnProperty(scope)) {
|
||||
@@ -67,12 +83,12 @@ RED.keyboard = (function() {
|
||||
if (keys.hasOwnProperty(key)) {
|
||||
if (!userKeymap.hasOwnProperty(keys[key])) {
|
||||
addHandler(scope,key,keys[key],false);
|
||||
defaultKeyMap[keys[key]] = {
|
||||
scope:scope,
|
||||
key:key,
|
||||
user:false
|
||||
};
|
||||
}
|
||||
defaultKeyMap[keys[key]] = {
|
||||
scope:scope,
|
||||
key:key,
|
||||
user:false
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +105,7 @@ RED.keyboard = (function() {
|
||||
|
||||
RED.userSettings.add({
|
||||
id:'keyboard',
|
||||
title: 'Keyboard',
|
||||
title: RED._("keyboard.keyboard"),
|
||||
get: getSettingsPane,
|
||||
focus: function() {
|
||||
setTimeout(function() {
|
||||
@@ -350,7 +366,8 @@ RED.keyboard = (function() {
|
||||
$(this).toggleClass("input-error",!valid);
|
||||
})
|
||||
|
||||
var scopeSelect = $('<select><option value="*">global</option><option value="workspace">workspace</option></select>').appendTo(scope);
|
||||
var scopeSelect = $('<select><option value="*" data-i18n="keyboard.global"></option><option value="workspace" data-i18n="keyboard.workspace"></option></select>').appendTo(scope);
|
||||
scopeSelect.i18n();
|
||||
scopeSelect.val(object.scope||'*');
|
||||
|
||||
var div = $('<div class="keyboard-shortcut-edit button-group-vertical"></div>').appendTo(scope);
|
||||
@@ -368,8 +385,11 @@ RED.keyboard = (function() {
|
||||
container.removeClass('keyboard-shortcut-entry-expanded');
|
||||
var shortcut = RED.keyboard.getShortcut(object.id);
|
||||
var userKeymap = RED.settings.get('keymap') || {};
|
||||
delete userKeymap[object.id];
|
||||
RED.settings.set('keymap',userKeymap);
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
var userKeymap = currentEditorSettings.keymap || {};
|
||||
userKeymap[object.id] = null;
|
||||
RED.settings.set('editor',currentEditorSettings);
|
||||
|
||||
var obj = {
|
||||
id:object.id,
|
||||
@@ -418,9 +438,11 @@ RED.keyboard = (function() {
|
||||
object.scope = scope;
|
||||
RED.keyboard.add(object.scope,object.key,object.id,true);
|
||||
}
|
||||
var userKeymap = RED.settings.get('keymap') || {};
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
var userKeymap = currentEditorSettings.keymap || {};
|
||||
userKeymap[object.id] = RED.keyboard.getShortcut(object.id);
|
||||
RED.settings.set('keymap',userKeymap);
|
||||
RED.settings.set('editor',currentEditorSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,9 +490,9 @@ RED.keyboard = (function() {
|
||||
var pane = $('<div id="user-settings-tab-keyboard"></div>');
|
||||
|
||||
$('<div class="keyboard-shortcut-entry keyboard-shortcut-list-header">'+
|
||||
'<div class="keyboard-shortcut-entry-key keyboard-shortcut-entry-text"><input id="user-settings-tab-keyboard-filter" type="text" placeholder="filter actions"></div>'+
|
||||
'<div class="keyboard-shortcut-entry-key">shortcut</div>'+
|
||||
'<div class="keyboard-shortcut-entry-scope">scope</div>'+
|
||||
'<div class="keyboard-shortcut-entry-key keyboard-shortcut-entry-text"><input id="user-settings-tab-keyboard-filter" type="text" data-i18n="[placeholder]keyboard.filterActions"></div>'+
|
||||
'<div class="keyboard-shortcut-entry-key" data-i18n="keyboard.shortcut"></div>'+
|
||||
'<div class="keyboard-shortcut-entry-scope" data-i18n="keyboard.scope"></div>'+
|
||||
'</div>').appendTo(pane);
|
||||
|
||||
pane.find("input").searchBox({
|
||||
|
@@ -38,7 +38,7 @@ RED.library = (function() {
|
||||
li.className = "dropdown-submenu pull-left";
|
||||
a = document.createElement("a");
|
||||
a.href="#";
|
||||
var label = i.replace(/^node-red-contrib-/,"").replace(/^node-red-node-/,"").replace(/-/," ").replace(/_/," ");
|
||||
var label = i.replace(/^@.*\//,"").replace(/^node-red-contrib-/,"").replace(/^node-red-node-/,"").replace(/-/," ").replace(/_/," ");
|
||||
a.innerHTML = label;
|
||||
li.appendChild(a);
|
||||
li.appendChild(buildMenu(data.d[i],root+(root!==""?"/":"")+i));
|
||||
|
@@ -13,10 +13,49 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
RED.notify = (function() {
|
||||
RED.notifications = (function() {
|
||||
|
||||
/*
|
||||
// Example usage for a modal dialog with buttons
|
||||
var myNotification = RED.notify("This is the message to display",{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
type: 'warning',
|
||||
buttons: [
|
||||
{
|
||||
text: "cancel",
|
||||
click: function(e) {
|
||||
myNotification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "okay",
|
||||
class:"primary",
|
||||
click: function(e) {
|
||||
myNotification.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
*/
|
||||
|
||||
var persistentNotifications = {};
|
||||
|
||||
var currentNotifications = [];
|
||||
var c = 0;
|
||||
return function(msg,type,fixed,timeout) {
|
||||
function notify(msg,type,fixed,timeout) {
|
||||
var options = {};
|
||||
if (type !== null && typeof type === 'object') {
|
||||
options = type;
|
||||
fixed = options.fixed;
|
||||
timeout = options.timeout;
|
||||
type = options.type;
|
||||
}
|
||||
|
||||
if (options.modal) {
|
||||
$("#full-shade").show();
|
||||
}
|
||||
|
||||
if (currentNotifications.length > 4) {
|
||||
var ll = currentNotifications.length;
|
||||
for (var i = 0;ll > 4 && i<currentNotifications.length;i+=1) {
|
||||
@@ -35,38 +74,123 @@ RED.notify = (function() {
|
||||
if (type) {
|
||||
n.className = "notification notification-"+type;
|
||||
}
|
||||
if (options.width) {
|
||||
var parentWidth = $("#notifications").width();
|
||||
if (options.width > parentWidth) {
|
||||
var margin = -(options.width-parentWidth)/2;
|
||||
$(n).css({
|
||||
width: options.width+"px",
|
||||
marginLeft: margin+"px"
|
||||
})
|
||||
}
|
||||
}
|
||||
n.style.display = "none";
|
||||
if (typeof msg === "string") {
|
||||
if (!/<p>/i.test(msg)) {
|
||||
msg = "<p>"+msg+"</p>";
|
||||
}
|
||||
n.innerHTML = msg;
|
||||
} else {
|
||||
$(n).append(msg);
|
||||
}
|
||||
if (options.buttons) {
|
||||
var buttonSet = $('<div style="margin-top: 20px;" class="ui-dialog-buttonset"></div>').appendTo(n)
|
||||
options.buttons.forEach(function(buttonDef) {
|
||||
var b = $('<button>').html(buttonDef.text).click(buttonDef.click).appendTo(buttonSet);
|
||||
if (buttonDef.id) {
|
||||
b.attr('id',buttonDef.id);
|
||||
}
|
||||
if (buttonDef.class) {
|
||||
b.addClass(buttonDef.class);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
$("#notifications").append(n);
|
||||
$(n).slideDown(300);
|
||||
n.close = (function() {
|
||||
var nn = n;
|
||||
return function() {
|
||||
if (nn.closed) {
|
||||
return;
|
||||
}
|
||||
nn.closed = true;
|
||||
currentNotifications.splice(currentNotifications.indexOf(nn),1);
|
||||
if (options.id) {
|
||||
delete persistentNotifications[options.id];
|
||||
if (Object.keys(persistentNotifications).length === 0) {
|
||||
notificationButtonWrapper.hide();
|
||||
}
|
||||
}
|
||||
$(nn).slideUp(300, function() {
|
||||
nn.parentNode.removeChild(nn);
|
||||
});
|
||||
if (options.modal) {
|
||||
$("#full-shade").hide();
|
||||
}
|
||||
};
|
||||
})();
|
||||
n.hideNotification = (function() {
|
||||
var nn = n;
|
||||
return function() {
|
||||
if (nn.closed) {
|
||||
return
|
||||
}
|
||||
nn.hidden = true;
|
||||
$(nn).slideUp(300);
|
||||
}
|
||||
})();
|
||||
n.showNotification = (function() {
|
||||
var nn = n;
|
||||
return function() {
|
||||
if (nn.closed || !nn.hidden) {
|
||||
return
|
||||
}
|
||||
nn.hidden = false;
|
||||
$(nn).slideDown(300);
|
||||
}
|
||||
})();
|
||||
|
||||
n.update = (function() {
|
||||
var nn = n;
|
||||
return function(msg,timeout) {
|
||||
return function(msg,options) {
|
||||
if (typeof msg === "string") {
|
||||
if (!/<p>/i.test(msg)) {
|
||||
msg = "<p>"+msg+"</p>";
|
||||
}
|
||||
nn.innerHTML = msg;
|
||||
} else {
|
||||
$(nn).empty().append(msg);
|
||||
}
|
||||
var timeout;
|
||||
if (typeof options === 'number') {
|
||||
timeout = options;
|
||||
} else if (options !== undefined) {
|
||||
timeout = options.timeout;
|
||||
if (options.buttons) {
|
||||
var buttonSet = $('<div style="margin-top: 20px;" class="ui-dialog-buttonset"></div>').appendTo(nn)
|
||||
options.buttons.forEach(function(buttonDef) {
|
||||
var b = $('<button>').html(buttonDef.text).click(buttonDef.click).appendTo(buttonSet);
|
||||
if (buttonDef.id) {
|
||||
b.attr('id',buttonDef.id);
|
||||
}
|
||||
if (buttonDef.class) {
|
||||
b.addClass(buttonDef.class);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if (timeout !== undefined && timeout > 0) {
|
||||
window.clearTimeout(nn.timeoutid);
|
||||
nn.timeoutid = window.setTimeout(nn.close,timeout);
|
||||
} else {
|
||||
window.clearTimeout(nn.timeoutid);
|
||||
}
|
||||
if (nn.hidden) {
|
||||
nn.showNotification();
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -78,10 +202,48 @@ RED.notify = (function() {
|
||||
window.clearTimeout(nn.timeoutid);
|
||||
};
|
||||
})());
|
||||
n.timeoutid = window.setTimeout(n.close,timeout||3000);
|
||||
n.timeoutid = window.setTimeout(n.close,timeout||5000);
|
||||
}
|
||||
currentNotifications.push(n);
|
||||
if (options.id) {
|
||||
persistentNotifications[options.id] = n;
|
||||
notificationButtonWrapper.show();
|
||||
}
|
||||
c+=1;
|
||||
return n;
|
||||
}
|
||||
|
||||
RED.notify = notify;
|
||||
|
||||
|
||||
function hidePersistent() {
|
||||
for(var i in persistentNotifications) {
|
||||
if (persistentNotifications.hasOwnProperty(i)) {
|
||||
persistentNotifications[i].hideNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
function showPersistent() {
|
||||
for(var i in persistentNotifications) {
|
||||
if (persistentNotifications.hasOwnProperty(i)) {
|
||||
persistentNotifications[i].showNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var notificationButtonWrapper;
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
notificationButtonWrapper = $('<li>'+
|
||||
'<a id="btn-notifications" class="button" href="#">'+
|
||||
'<i class="fa fa-warning"></i>'+
|
||||
'</a>'+
|
||||
'</li>').prependTo(".header-toolbar").hide();
|
||||
$('#btn-notifications').click(function() {
|
||||
showPersistent();
|
||||
})
|
||||
},
|
||||
notify: notify
|
||||
}
|
||||
})();
|
||||
|
@@ -75,27 +75,21 @@ RED.palette.editor = (function() {
|
||||
});
|
||||
})
|
||||
}
|
||||
function installNodeModule(id,version,shade,callback) {
|
||||
function installNodeModule(id,version,callback) {
|
||||
var requestBody = {
|
||||
module: id
|
||||
};
|
||||
if (callback === undefined) {
|
||||
callback = shade;
|
||||
shade = version;
|
||||
} else {
|
||||
if (version) {
|
||||
requestBody.version = version;
|
||||
}
|
||||
shade.show();
|
||||
$.ajax({
|
||||
url:"nodes",
|
||||
type: "POST",
|
||||
data: JSON.stringify(requestBody),
|
||||
contentType: "application/json; charset=utf-8"
|
||||
}).done(function(data,textStatus,xhr) {
|
||||
shade.hide();
|
||||
callback();
|
||||
}).fail(function(xhr,textStatus,err) {
|
||||
shade.hide();
|
||||
callback(xhr);
|
||||
});
|
||||
}
|
||||
@@ -423,7 +417,7 @@ RED.palette.editor = (function() {
|
||||
|
||||
RED.userSettings.add({
|
||||
id:'palette',
|
||||
title: 'Palette',
|
||||
title: RED._("palette.editor.palette"),
|
||||
get: getSettingsPane,
|
||||
close: function() {
|
||||
settingsPane.detach();
|
||||
@@ -604,24 +598,7 @@ RED.palette.editor = (function() {
|
||||
if ($(this).hasClass('disabled')) {
|
||||
return;
|
||||
}
|
||||
$("#palette-module-install-confirm").data('module',entry.name);
|
||||
$("#palette-module-install-confirm").data('version',loadedIndex[entry.name].version);
|
||||
$("#palette-module-install-confirm").data('shade',shade);
|
||||
|
||||
$("#palette-module-install-confirm-body").html(entry.local?
|
||||
RED._("palette.editor.confirm.update.body"):
|
||||
RED._("palette.editor.confirm.cannotUpdate.body")
|
||||
);
|
||||
$(".palette-module-install-confirm-button-install").hide();
|
||||
$(".palette-module-install-confirm-button-remove").hide();
|
||||
if (entry.local) {
|
||||
$(".palette-module-install-confirm-button-update").show();
|
||||
} else {
|
||||
$(".palette-module-install-confirm-button-update").hide();
|
||||
}
|
||||
$("#palette-module-install-confirm")
|
||||
.dialog('option', 'title',RED._("palette.editor.confirm.update.title"))
|
||||
.dialog('open');
|
||||
update(entry,loadedIndex[entry.name].version,container,function(err){});
|
||||
})
|
||||
|
||||
|
||||
@@ -629,16 +606,7 @@ RED.palette.editor = (function() {
|
||||
removeButton.attr('id','up_'+Math.floor(Math.random()*1000000000));
|
||||
removeButton.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
$("#palette-module-install-confirm").data('module',entry.name);
|
||||
$("#palette-module-install-confirm").data('shade',shade);
|
||||
$("#palette-module-install-confirm-body").html(RED._("palette.editor.confirm.remove.body"));
|
||||
$(".palette-module-install-confirm-button-install").hide();
|
||||
$(".palette-module-install-confirm-button-remove").show();
|
||||
$(".palette-module-install-confirm-button-update").hide();
|
||||
$("#palette-module-install-confirm")
|
||||
.dialog('option', 'title', RED._("palette.editor.confirm.remove.title"))
|
||||
.dialog('open');
|
||||
remove(entry,container,function(err){});
|
||||
})
|
||||
if (!entry.local) {
|
||||
removeButton.hide();
|
||||
@@ -836,22 +804,11 @@ RED.palette.editor = (function() {
|
||||
$('<span class="palette-module-updated"><i class="fa fa-calendar"></i> '+formatUpdatedAt(entry.updated_at)+'</span>').appendTo(metaRow);
|
||||
var buttonRow = $('<div>',{class:"palette-module-meta"}).appendTo(headerRow);
|
||||
var buttonGroup = $('<div>',{class:"palette-module-button-group"}).appendTo(buttonRow);
|
||||
var shade = $('<div class="palette-module-shade hide"><img src="red/images/spin.svg" class="palette-spinner"/></div>').appendTo(container);
|
||||
var installButton = $('<a href="#" class="editor-button editor-button-small"></a>').html(RED._('palette.editor.install')).appendTo(buttonGroup);
|
||||
installButton.click(function(e) {
|
||||
e.preventDefault();
|
||||
if (!$(this).hasClass('disabled')) {
|
||||
$("#palette-module-install-confirm").data('module',entry.id);
|
||||
$("#palette-module-install-confirm").data('version',entry.version);
|
||||
$("#palette-module-install-confirm").data('url',entry.url);
|
||||
$("#palette-module-install-confirm").data('shade',shade);
|
||||
$("#palette-module-install-confirm-body").html(RED._("palette.editor.confirm.install.body"));
|
||||
$(".palette-module-install-confirm-button-install").show();
|
||||
$(".palette-module-install-confirm-button-remove").hide();
|
||||
$(".palette-module-install-confirm-button-update").hide();
|
||||
$("#palette-module-install-confirm")
|
||||
.dialog('option', 'title', RED._("palette.editor.confirm.install.title"))
|
||||
.dialog('open');
|
||||
install(entry,container,function(xhr) {});
|
||||
}
|
||||
})
|
||||
if (nodeEntries.hasOwnProperty(entry.id)) {
|
||||
@@ -869,88 +826,126 @@ RED.palette.editor = (function() {
|
||||
});
|
||||
|
||||
$('<div id="palette-module-install-shade" class="palette-module-shade hide"><div class="palette-module-shade-status"></div><img src="red/images/spin.svg" class="palette-spinner"/></div>').appendTo(installTab);
|
||||
|
||||
$('<div id="palette-module-install-confirm" class="hide"><form class="form-horizontal"><div id="palette-module-install-confirm-body" class="node-dialog-confirm-row"></div></form></div>').appendTo(document.body);
|
||||
$("#palette-module-install-confirm").dialog({
|
||||
title: RED._('palette.editor.confirm.title'),
|
||||
}
|
||||
function update(entry,version,container,done) {
|
||||
if (RED.settings.theme('palette.editable') === false) {
|
||||
done(new Error('Palette not editable'));
|
||||
return;
|
||||
}
|
||||
var notification = RED.notify(RED._("palette.editor.confirm.update.body",{module:entry.name}),{
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 550,
|
||||
height: "auto",
|
||||
fixed: true,
|
||||
buttons: [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.review"),
|
||||
class: "primary palette-module-install-confirm-button-install",
|
||||
click: function() {
|
||||
var url = $(this).data('url');
|
||||
window.open(url);
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.install"),
|
||||
class: "primary palette-module-install-confirm-button-install",
|
||||
click: function() {
|
||||
var id = $(this).data('module');
|
||||
var version = $(this).data('version');
|
||||
var shade = $(this).data('shade');
|
||||
installNodeModule(id,version,shade,function(xhr) {
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.installFailed',{module: id,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
});
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.remove"),
|
||||
class: "primary palette-module-install-confirm-button-remove",
|
||||
click: function() {
|
||||
var id = $(this).data('module');
|
||||
var shade = $(this).data('shade');
|
||||
shade.show();
|
||||
removeNodeModule(id, function(xhr) {
|
||||
shade.hide();
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.removeFailed',{module: id,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$( this ).dialog( "close" );
|
||||
notification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.update"),
|
||||
class: "primary palette-module-install-confirm-button-update",
|
||||
click: function() {
|
||||
var id = $(this).data('module');
|
||||
var version = $(this).data('version');
|
||||
var shade = $(this).data('shade');
|
||||
shade.show();
|
||||
installNodeModule(id,version,shade,function(xhr) {
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.updateFailed',{module: id,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
var spinner = RED.utils.addSpinnerOverlay(container, true);
|
||||
installNodeModule(entry.name,version,function(xhr) {
|
||||
spinner.remove();
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.updateFailed',{module: entry.name,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
done(xhr);
|
||||
});
|
||||
$( this ).dialog( "close" );
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
function remove(entry,container,done) {
|
||||
if (RED.settings.theme('palette.editable') === false) {
|
||||
done(new Error('Palette not editable'));
|
||||
return;
|
||||
}
|
||||
var notification = RED.notify(RED._("palette.editor.confirm.remove.body",{module:entry.name}),{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons: [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
notification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.remove"),
|
||||
class: "primary palette-module-install-confirm-button-remove",
|
||||
click: function() {
|
||||
var spinner = RED.utils.addSpinnerOverlay(container, true);
|
||||
removeNodeModule(entry.name, function(xhr) {
|
||||
spinner.remove();
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.removeFailed',{module: entry.name,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
})
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
function install(entry,container,done) {
|
||||
if (RED.settings.theme('palette.editable') === false) {
|
||||
done(new Error('Palette not editable'));
|
||||
return;
|
||||
}
|
||||
var buttons = [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
];
|
||||
if (entry.url) {
|
||||
buttons.push({
|
||||
text: RED._("palette.editor.confirm.button.review"),
|
||||
class: "primary palette-module-install-confirm-button-install",
|
||||
click: function() {
|
||||
var url = entry.url||"";
|
||||
window.open(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
buttons.push({
|
||||
text: RED._("palette.editor.confirm.button.install"),
|
||||
class: "primary palette-module-install-confirm-button-install",
|
||||
click: function() {
|
||||
var spinner = RED.utils.addSpinnerOverlay(container, true);
|
||||
installNodeModule(entry.id,entry.version,function(xhr) {
|
||||
spinner.remove();
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.installFailed',{module: entry.id,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
done(xhr);
|
||||
});
|
||||
notification.close();
|
||||
}
|
||||
});
|
||||
|
||||
var notification = RED.notify(RED._("palette.editor.confirm.install.body",{module:entry.id}),{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons: buttons
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
init: init
|
||||
init: init,
|
||||
install: install
|
||||
}
|
||||
})();
|
||||
|
@@ -21,7 +21,7 @@ RED.palette = (function() {
|
||||
|
||||
var categoryContainers = {};
|
||||
|
||||
function createCategoryContainer(category, label){
|
||||
function createCategoryContainer(category, label) {
|
||||
label = (label || category).replace(/_/g, " ");
|
||||
var catDiv = $('<div id="palette-container-'+category+'" class="palette-category palette-close hide">'+
|
||||
'<div id="palette-header-'+category+'" class="palette-header"><i class="expanded fa fa-angle-down"></i><span>'+label+'</span></div>'+
|
||||
@@ -206,11 +206,11 @@ RED.palette = (function() {
|
||||
RED.view.focus();
|
||||
var helpText;
|
||||
if (nt.indexOf("subflow:") === 0) {
|
||||
helpText = marked(RED.nodes.subflow(nt.substring(8)).info||"");
|
||||
helpText = marked(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
} else {
|
||||
helpText = $("script[data-help-name='"+d.type+"']").html()||"";
|
||||
helpText = $("script[data-help-name='"+d.type+"']").html()||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
}
|
||||
RED.sidebar.info.set(helpText);
|
||||
RED.sidebar.info.set(helpText,RED._("sidebar.info.nodeHelp"));
|
||||
});
|
||||
var chart = $("#chart");
|
||||
var chartOffset = chart.offset();
|
||||
@@ -325,14 +325,26 @@ RED.palette = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hideNodeType(nt) {
|
||||
var nodeTypeId = escapeNodeType(nt);
|
||||
$("#palette_node_"+nodeTypeId).hide();
|
||||
var paletteNode = $("#palette_node_"+nodeTypeId);
|
||||
paletteNode.hide();
|
||||
var categoryNode = paletteNode.closest(".palette-category");
|
||||
var cl = categoryNode.find(".palette_node");
|
||||
var c = 0;
|
||||
for (var i = 0; i < cl.length; i++) {
|
||||
if ($(cl[i]).css('display') === 'none') { c += 1; }
|
||||
}
|
||||
if (c === cl.length) { categoryNode.hide(); }
|
||||
}
|
||||
|
||||
function showNodeType(nt) {
|
||||
var nodeTypeId = escapeNodeType(nt);
|
||||
$("#palette_node_"+nodeTypeId).show();
|
||||
var paletteNode = $("#palette_node_"+nodeTypeId);
|
||||
var categoryNode = paletteNode.closest(".palette-category");
|
||||
categoryNode.show();
|
||||
paletteNode.show();
|
||||
}
|
||||
|
||||
function refreshNodeTypes() {
|
||||
@@ -396,21 +408,21 @@ RED.palette = (function() {
|
||||
RED.events.on('registry:node-type-removed', function(nodeType) {
|
||||
removeNodeType(nodeType);
|
||||
});
|
||||
|
||||
RED.events.on('registry:node-set-enabled', function(nodeSet) {
|
||||
for (var j=0;j<nodeSet.types.length;j++) {
|
||||
showNodeType(nodeSet.types[j]);
|
||||
var def = RED.nodes.getType(nodeSet.types[j]);
|
||||
if (def.onpaletteadd && typeof def.onpaletteadd === "function") {
|
||||
if (def && def.onpaletteadd && typeof def.onpaletteadd === "function") {
|
||||
def.onpaletteadd.call(def);
|
||||
}
|
||||
}
|
||||
});
|
||||
RED.events.on('registry:node-set-disabled', function(nodeSet) {
|
||||
console.log(nodeSet);
|
||||
for (var j=0;j<nodeSet.types.length;j++) {
|
||||
hideNodeType(nodeSet.types[j]);
|
||||
var def = RED.nodes.getType(nodeSet.types[j]);
|
||||
if (def.onpaletteremove && typeof def.onpaletteremove === "function") {
|
||||
if (def && def.onpaletteremove && typeof def.onpaletteremove === "function") {
|
||||
def.onpaletteremove.call(def);
|
||||
}
|
||||
}
|
||||
@@ -420,14 +432,13 @@ RED.palette = (function() {
|
||||
for (var j=0;j<nodeSet.types.length;j++) {
|
||||
removeNodeType(nodeSet.types[j]);
|
||||
var def = RED.nodes.getType(nodeSet.types[j]);
|
||||
if (def.onpaletteremove && typeof def.onpaletteremove === "function") {
|
||||
if (def && def.onpaletteremove && typeof def.onpaletteremove === "function") {
|
||||
def.onpaletteremove.call(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$("#palette > .palette-spinner").show();
|
||||
|
||||
$("#palette-search input").searchBox({
|
||||
|
1498
editor/js/ui/projects/projectSettings.js
Normal file
1498
editor/js/ui/projects/projectSettings.js
Normal file
File diff suppressed because it is too large
Load Diff
418
editor/js/ui/projects/projectUserSettings.js
Normal file
418
editor/js/ui/projects/projectUserSettings.js
Normal file
@@ -0,0 +1,418 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
RED.projects.userSettings = (function() {
|
||||
|
||||
var gitUsernameInput;
|
||||
var gitEmailInput;
|
||||
|
||||
function createGitUserSection(pane) {
|
||||
|
||||
var currentGitSettings = RED.settings.get('git') || {};
|
||||
currentGitSettings.user = currentGitSettings.user || {};
|
||||
|
||||
var title = $('<h3></h3>').text("Committer Details").appendTo(pane);
|
||||
|
||||
var gitconfigContainer = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||
$('<div style="color:#aaa;"></div>').appendTo(gitconfigContainer).text("Leave blank to use system default");
|
||||
|
||||
var row = $('<div class="user-settings-row"></div>').appendTo(gitconfigContainer);
|
||||
$('<label for=""></label>').text('Username').appendTo(row);
|
||||
gitUsernameInput = $('<input type="text">').appendTo(row);
|
||||
gitUsernameInput.val(currentGitSettings.user.name||"");
|
||||
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(gitconfigContainer);
|
||||
$('<label for=""></label>').text('Email').appendTo(row);
|
||||
gitEmailInput = $('<input type="text">').appendTo(row);
|
||||
gitEmailInput.val(currentGitSettings.user.email||"");
|
||||
}
|
||||
|
||||
|
||||
function createSSHKeySection(pane) {
|
||||
var container = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||
var popover;
|
||||
var title = $('<h3></h3>').text("SSH Keys").appendTo(container);
|
||||
var subtitle = $('<div style="color:#aaa;"></div>').appendTo(container).text("Allows you to create secure connections to remote git repositories.");
|
||||
|
||||
var addKeyButton = $('<button id="user-settings-gitconfig-add-key" class="editor-button editor-button-small" style="float: right; margin-right: 10px;">add key</button>')
|
||||
.appendTo(subtitle)
|
||||
.click(function(evt) {
|
||||
addKeyButton.attr('disabled',true);
|
||||
saveButton.attr('disabled',true);
|
||||
// bg.children().removeClass("selected");
|
||||
// addLocalButton.click();
|
||||
addKeyDialog.slideDown(200);
|
||||
keyNameInput.focus();
|
||||
});
|
||||
|
||||
var validateForm = function() {
|
||||
var valid = /^[a-zA-Z0-9\-_]+$/.test(keyNameInput.val());
|
||||
keyNameInput.toggleClass('input-error',keyNameInputChanged&&!valid);
|
||||
|
||||
// var selectedButton = bg.find(".selected");
|
||||
// if (selectedButton[0] === addLocalButton[0]) {
|
||||
// valid = valid && localPublicKeyPathInput.val().length > 0 && localPrivateKeyPathInput.val().length > 0;
|
||||
// } else if (selectedButton[0] === uploadButton[0]) {
|
||||
// valid = valid && publicKeyInput.val().length > 0 && privateKeyInput.val().length > 0;
|
||||
// } else if (selectedButton[0] === generateButton[0]) {
|
||||
var passphrase = passphraseInput.val();
|
||||
var validPassphrase = passphrase.length === 0 || passphrase.length >= 8;
|
||||
passphraseInput.toggleClass('input-error',!validPassphrase);
|
||||
if (!validPassphrase) {
|
||||
passphraseInputSubLabel.text("Passphrase too short");
|
||||
} else if (passphrase.length === 0) {
|
||||
passphraseInputSubLabel.text("Optional");
|
||||
} else {
|
||||
passphraseInputSubLabel.text("");
|
||||
}
|
||||
valid = valid && validPassphrase;
|
||||
// }
|
||||
|
||||
saveButton.attr('disabled',!valid);
|
||||
|
||||
if (popover) {
|
||||
popover.close();
|
||||
popover = null;
|
||||
}
|
||||
};
|
||||
|
||||
var row = $('<div class="user-settings-row"></div>').appendTo(container);
|
||||
var addKeyDialog = $('<div class="projects-dialog-list-dialog"></div>').hide().appendTo(row);
|
||||
$('<div class="projects-dialog-list-dialog-header">').text('Add SSH Key').appendTo(addKeyDialog);
|
||||
var addKeyDialogBody = $('<div>').appendTo(addKeyDialog);
|
||||
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
|
||||
$('<div style="color:#aaa;"></div>').appendTo(row).text("Generate a new public/private key pair");
|
||||
// var bg = $('<div></div>',{class:"button-group", style:"text-align: center"}).appendTo(row);
|
||||
// var addLocalButton = $('<button class="editor-button toggle selected">use local key</button>').appendTo(bg);
|
||||
// var uploadButton = $('<button class="editor-button toggle">upload key</button>').appendTo(bg);
|
||||
// var generateButton = $('<button class="editor-button toggle">generate key</button>').appendTo(bg);
|
||||
// bg.children().click(function(e) {
|
||||
// e.preventDefault();
|
||||
// if ($(this).hasClass("selected")) {
|
||||
// return;
|
||||
// }
|
||||
// bg.children().removeClass("selected");
|
||||
// $(this).addClass("selected");
|
||||
// if (this === addLocalButton[0]) {
|
||||
// addLocalKeyPane.show();
|
||||
// generateKeyPane.hide();
|
||||
// uploadKeyPane.hide();
|
||||
// } else if (this === uploadButton[0]) {
|
||||
// addLocalKeyPane.hide();
|
||||
// generateKeyPane.hide();
|
||||
// uploadKeyPane.show();
|
||||
// } else if (this === generateButton[0]){
|
||||
// addLocalKeyPane.hide();
|
||||
// generateKeyPane.show();
|
||||
// uploadKeyPane.hide();
|
||||
// }
|
||||
// validateForm();
|
||||
// })
|
||||
|
||||
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
|
||||
$('<label for=""></label>').text('Name').appendTo(row);
|
||||
var keyNameInputChanged = false;
|
||||
var keyNameInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
|
||||
keyNameInputChanged = true;
|
||||
validateForm();
|
||||
});
|
||||
$('<label class="projects-edit-form-sublabel"><small>Must contain only A-Z 0-9 _ -</small></label>').appendTo(row).find("small");
|
||||
|
||||
var generateKeyPane = $('<div>').appendTo(addKeyDialogBody);
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(generateKeyPane);
|
||||
$('<label for=""></label>').text('Passphrase').appendTo(row);
|
||||
var passphraseInput = $('<input type="password">').appendTo(row).on("change keyup paste",validateForm);
|
||||
var passphraseInputSubLabel = $('<label class="projects-edit-form-sublabel"><small>Optional</small></label>').appendTo(row).find("small");
|
||||
|
||||
// var addLocalKeyPane = $('<div>').hide().appendTo(addKeyDialogBody);
|
||||
// row = $('<div class="user-settings-row"></div>').appendTo(addLocalKeyPane);
|
||||
// $('<label for=""></label>').text('Public key').appendTo(row);
|
||||
// var localPublicKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm);
|
||||
// $('<label class="projects-edit-form-sublabel"><small>Public key file path, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small");
|
||||
// row = $('<div class="user-settings-row"></div>').appendTo(addLocalKeyPane);
|
||||
// $('<label for=""></label>').text('Private key').appendTo(row);
|
||||
// var localPrivateKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm);
|
||||
// $('<label class="projects-edit-form-sublabel"><small>Private key file path, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small");
|
||||
//
|
||||
// var uploadKeyPane = $('<div>').hide().appendTo(addKeyDialogBody);
|
||||
// row = $('<div class="user-settings-row"></div>').appendTo(uploadKeyPane);
|
||||
// $('<label for=""></label>').text('Public key').appendTo(row);
|
||||
// var publicKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm);
|
||||
// $('<label class="projects-edit-form-sublabel"><small>Paste in public key contents, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small");
|
||||
// row = $('<div class="user-settings-row"></div>').appendTo(uploadKeyPane);
|
||||
// $('<label for=""></label>').text('Private key').appendTo(row);
|
||||
// var privateKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm);
|
||||
// $('<label class="projects-edit-form-sublabel"><small>Paste in private key contents, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small");
|
||||
|
||||
|
||||
|
||||
|
||||
var hideEditForm = function() {
|
||||
addKeyButton.attr('disabled',false);
|
||||
addKeyDialog.hide();
|
||||
|
||||
keyNameInput.val("");
|
||||
keyNameInputChanged = false;
|
||||
passphraseInput.val("");
|
||||
// localPublicKeyPathInput.val("");
|
||||
// localPrivateKeyPathInput.val("");
|
||||
// publicKeyInput.val("");
|
||||
// privateKeyInput.val("");
|
||||
if (popover) {
|
||||
popover.close();
|
||||
popover = null;
|
||||
}
|
||||
}
|
||||
var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>').appendTo(addKeyDialog);
|
||||
$('<button class="editor-button">Cancel</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
hideEditForm();
|
||||
});
|
||||
var saveButton = $('<button class="editor-button">Generate key</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var spinner = utils.addSpinnerOverlay(addKeyDialog).addClass('projects-dialog-spinner-contain');
|
||||
var payload = {
|
||||
name: keyNameInput.val()
|
||||
};
|
||||
|
||||
// var selectedButton = bg.find(".selected");
|
||||
// if (selectedButton[0] === addLocalButton[0]) {
|
||||
// payload.type = "local";
|
||||
// payload.publicKeyPath = localPublicKeyPathInput.val();
|
||||
// payload.privateKeyPath = localPrivateKeyPathInput.val();
|
||||
// } else if (selectedButton[0] === uploadButton[0]) {
|
||||
// payload.type = "upload";
|
||||
// payload.publicKey = publicKeyInput.val();
|
||||
// payload.privateKey = privateKeyInput.val();
|
||||
// } else if (selectedButton[0] === generateButton[0]) {
|
||||
payload.type = "generate";
|
||||
payload.comment = gitEmailInput.val();
|
||||
payload.password = passphraseInput.val();
|
||||
payload.size = 4096;
|
||||
// }
|
||||
var done = function(err) {
|
||||
spinner.remove();
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
hideEditForm();
|
||||
}
|
||||
// console.log(JSON.stringify(payload,null,4));
|
||||
RED.deploy.setDeployInflight(true);
|
||||
utils.sendRequest({
|
||||
url: "settings/user/keys",
|
||||
type: "POST",
|
||||
responses: {
|
||||
0: function(error) {
|
||||
done(error);
|
||||
},
|
||||
200: function(data) {
|
||||
refreshSSHKeyList(payload.name);
|
||||
done();
|
||||
},
|
||||
400: {
|
||||
'unexpected_error': function(error) {
|
||||
console.log(error);
|
||||
done(error);
|
||||
}
|
||||
},
|
||||
}
|
||||
},payload);
|
||||
});
|
||||
|
||||
row = $('<div class="user-settings-row projects-dialog-list"></div>').appendTo(container);
|
||||
var emptyItem = { empty: true };
|
||||
var expandKey = function(container,entry) {
|
||||
var row = $('<div class="projects-dialog-ssh-public-key">',{style:"position:relative"}).appendTo(container);
|
||||
var keyBox = $('<pre>',{style:"min-height: 80px"}).appendTo(row);
|
||||
var spinner = utils.addSpinnerOverlay(keyBox).addClass('projects-dialog-spinner-contain');
|
||||
var options = {
|
||||
url: 'settings/user/keys/'+entry.name,
|
||||
type: "GET",
|
||||
responses: {
|
||||
200: function(data) {
|
||||
keyBox.text(data.publickey);
|
||||
spinner.remove();
|
||||
},
|
||||
400: {
|
||||
'unexpected_error': function(error) {
|
||||
console.log(error);
|
||||
spinner.remove();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
utils.sendRequest(options);
|
||||
|
||||
var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>').appendTo(row);
|
||||
$('<button class="editor-button editor-button-small">Copy public key to clipboard</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
try {
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
document.getSelection().selectAllChildren(keyBox[0]);
|
||||
var ret = document.execCommand('copy');
|
||||
document.getSelection().empty();
|
||||
} catch(err) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return row;
|
||||
}
|
||||
var keyList = $('<ol class="projects-dialog-ssh-key-list">').appendTo(row).editableList({
|
||||
height: 'auto',
|
||||
addButton: false,
|
||||
scrollOnAdd: false,
|
||||
addItem: function(row,index,entry) {
|
||||
var container = $('<div class="projects-dialog-list-entry">').appendTo(row);
|
||||
if (entry.empty) {
|
||||
container.addClass('red-ui-search-empty');
|
||||
container.text("No SSH keys");
|
||||
return;
|
||||
}
|
||||
var topRow = $('<div class="projects-dialog-ssh-key-header">').appendTo(container);
|
||||
$('<span class="entry-icon"><i class="fa fa-key"></i></span>').appendTo(topRow);
|
||||
$('<span class="entry-name">').text(entry.name).appendTo(topRow);
|
||||
var tools = $('<span class="button-row entry-tools">').appendTo(topRow);
|
||||
var expandedRow;
|
||||
topRow.click(function(e) {
|
||||
if (expandedRow) {
|
||||
expandedRow.slideUp(200,function() {
|
||||
expandedRow.remove();
|
||||
expandedRow = null;
|
||||
})
|
||||
} else {
|
||||
expandedRow = expandKey(container,entry);
|
||||
}
|
||||
})
|
||||
if (!entry.system) {
|
||||
$('<button class="editor-button editor-button-small"><i class="fa fa-trash"></i></button>')
|
||||
.appendTo(tools)
|
||||
.click(function(e) {
|
||||
e.stopPropagation();
|
||||
var spinner = utils.addSpinnerOverlay(row).addClass('projects-dialog-spinner-contain');
|
||||
var notification = RED.notify("Are you sure you want to delete the SSH key '"+entry.name+"'? This cannot be undone.", {
|
||||
type: 'warning',
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons: [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
spinner.remove();
|
||||
notification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "Delete key",
|
||||
click: function() {
|
||||
notification.close();
|
||||
var url = "settings/user/keys/"+entry.name;
|
||||
var options = {
|
||||
url: url,
|
||||
type: "DELETE",
|
||||
responses: {
|
||||
200: function(data) {
|
||||
row.fadeOut(200,function() {
|
||||
keyList.editableList('removeItem',entry);
|
||||
setTimeout(spinner.remove, 100);
|
||||
if (keyList.editableList('length') === 0) {
|
||||
keyList.editableList('addItem',emptyItem);
|
||||
}
|
||||
});
|
||||
},
|
||||
400: {
|
||||
'unexpected_error': function(error) {
|
||||
console.log(error);
|
||||
spinner.remove();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
utils.sendRequest(options);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
}
|
||||
if (entry.expand) {
|
||||
expandedRow = expandKey(container,entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var refreshSSHKeyList = function(justAdded) {
|
||||
$.getJSON("settings/user/keys",function(result) {
|
||||
if (result.keys) {
|
||||
result.keys.sort(function(A,B) {
|
||||
return A.name.localeCompare(B.name);
|
||||
});
|
||||
keyList.editableList('empty');
|
||||
result.keys.forEach(function(key) {
|
||||
if (key.name === justAdded) {
|
||||
key.expand = true;
|
||||
}
|
||||
keyList.editableList('addItem',key);
|
||||
});
|
||||
if (keyList.editableList('length') === 0) {
|
||||
keyList.editableList('addItem',emptyItem);
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
refreshSSHKeyList();
|
||||
|
||||
}
|
||||
|
||||
function createSettingsPane(activeProject) {
|
||||
var pane = $('<div id="user-settings-tab-gitconfig" class="project-settings-tab-pane node-help"></div>');
|
||||
createGitUserSection(pane);
|
||||
createSSHKeySection(pane);
|
||||
return pane;
|
||||
}
|
||||
|
||||
var utils;
|
||||
function init(_utils) {
|
||||
utils = _utils;
|
||||
RED.userSettings.add({
|
||||
id:'gitconfig',
|
||||
title: "Git config", // TODO: nls
|
||||
get: createSettingsPane,
|
||||
close: function() {
|
||||
var currentGitSettings = RED.settings.get('git') || {};
|
||||
currentGitSettings.user = currentGitSettings.user || {};
|
||||
currentGitSettings.user.name = gitUsernameInput.val();
|
||||
currentGitSettings.user.email = gitEmailInput.val();
|
||||
RED.settings.set('git', currentGitSettings);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
};
|
||||
})();
|
1899
editor/js/ui/projects/projects.js
Normal file
1899
editor/js/ui/projects/projects.js
Normal file
File diff suppressed because it is too large
Load Diff
1289
editor/js/ui/projects/tab-versionControl.js
Normal file
1289
editor/js/ui/projects/tab-versionControl.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -125,7 +125,7 @@ RED.search = (function() {
|
||||
function createDialog() {
|
||||
dialog = $("<div>",{id:"red-ui-search",class:"red-ui-search"}).appendTo("#main-container");
|
||||
var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog);
|
||||
searchInput = $('<input type="text" placeholder="search your flows">').appendTo(searchDiv).searchBox({
|
||||
searchInput = $('<input type="text" data-i18n="[placeholder]menu.label.searchInput">').appendTo(searchDiv).searchBox({
|
||||
delay: 200,
|
||||
change: function() {
|
||||
search($(this).val());
|
||||
@@ -166,6 +166,7 @@ RED.search = (function() {
|
||||
}
|
||||
}
|
||||
});
|
||||
searchInput.i18n();
|
||||
|
||||
var searchResultsDiv = $("<div>",{class:"red-ui-search-results-container"}).appendTo(dialog);
|
||||
searchResults = $('<ol>',{id:"search-result-list", style:"position: absolute;top: 5px;bottom: 5px;left: 5px;right: 5px;"}).appendTo(searchResultsDiv).editableList({
|
||||
|
@@ -35,7 +35,8 @@ RED.sidebar = (function() {
|
||||
tab.onremove.call(tab);
|
||||
}
|
||||
},
|
||||
minimumActiveTabWidth: 110
|
||||
minimumActiveTabWidth: 70
|
||||
// scrollable: true
|
||||
});
|
||||
|
||||
var knownTabs = {
|
||||
|
@@ -50,13 +50,15 @@ RED.sidebar.info = (function() {
|
||||
}).hide();
|
||||
|
||||
nodeSection = sections.add({
|
||||
title: "Node",
|
||||
collapsible: false
|
||||
title: RED._("sidebar.info.info"),
|
||||
collapsible: true
|
||||
});
|
||||
nodeSection.expand();
|
||||
infoSection = sections.add({
|
||||
title: "Information",
|
||||
collapsible: false
|
||||
title: RED._("sidebar.info.nodeHelp"),
|
||||
collapsible: true
|
||||
});
|
||||
infoSection.expand();
|
||||
infoSection.content.css("padding","6px");
|
||||
infoSection.container.css("border-bottom","none");
|
||||
|
||||
@@ -96,23 +98,7 @@ RED.sidebar.info = (function() {
|
||||
RED.sidebar.show("info");
|
||||
}
|
||||
|
||||
function jsonFilter(key,value) {
|
||||
if (key === "") {
|
||||
return value;
|
||||
}
|
||||
var t = typeof value;
|
||||
if ($.isArray(value)) {
|
||||
return "[array:"+value.length+"]";
|
||||
} else if (t === "object") {
|
||||
return "[object]"
|
||||
} else if (t === "string") {
|
||||
if (value.length > 30) {
|
||||
return value.substring(0,30)+" ...";
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// TODO: DRY - projects.js
|
||||
function addTargetToExternalLinks(el) {
|
||||
$(el).find("a").each(function(el) {
|
||||
var href = $(this).attr('href');
|
||||
@@ -123,76 +109,42 @@ RED.sidebar.info = (function() {
|
||||
return el;
|
||||
}
|
||||
function refresh(node) {
|
||||
if (node === undefined) {
|
||||
refreshSelection();
|
||||
return;
|
||||
}
|
||||
sections.show();
|
||||
$(nodeSection.content).empty();
|
||||
$(infoSection.content).empty();
|
||||
|
||||
var table = $('<table class="node-info"></table>');
|
||||
var tableBody = $('<tbody>').appendTo(table);
|
||||
var propRow;
|
||||
|
||||
var table = $('<table class="node-info"></table>').appendTo(nodeSection.content);
|
||||
var tableBody = $('<tbody>').appendTo(table);
|
||||
var subflowNode;
|
||||
if (node.type === "tab") {
|
||||
nodeSection.title.html("Flow");
|
||||
propRow = $('<tr class="node-info-node-row"><td>Name</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).html(' '+(node.label||""))
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.id")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
propRow = $('<tr class="node-info-node-row"><td>Status</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).html((!!!node.disabled)?"Enabled":"Disabled")
|
||||
var subflowUserCount;
|
||||
|
||||
var activeProject = RED.projects.getActiveProject();
|
||||
if (activeProject) {
|
||||
propRow = $('<tr class="node-info-node-row"><td>Project</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(activeProject.name||"");
|
||||
$('<tr class="node-info-property-expand blank"><td colspan="2"></td></tr>').appendTo(tableBody);
|
||||
$('<button class="editor-button editor-button-small" style="position:absolute;right:2px;"><i class="fa fa-ellipsis-h"></i></button>')
|
||||
.appendTo(propRow.children()[1])
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
RED.projects.editProject();
|
||||
});
|
||||
}
|
||||
infoSection.container.show();
|
||||
if (node === null) {
|
||||
return;
|
||||
} else if (Array.isArray(node)) {
|
||||
infoSection.container.hide();
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.selection")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(RED._("sidebar.info.nodes",{count:node.length}))
|
||||
} else {
|
||||
nodeSection.title.html("Node");
|
||||
if (node.type !== "subflow" && node.name) {
|
||||
$('<tr class="node-info-node-row"><td>'+RED._("common.label.name")+'</td><td> <span class="bidiAware" dir="'+RED.text.bidi.resolveBaseTextDir(node.name)+'">'+node.name+'</span></td></tr>').appendTo(tableBody);
|
||||
}
|
||||
$('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.type")+"</td><td> "+node.type+"</td></tr>").appendTo(tableBody);
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.id")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
|
||||
var m = /^subflow(:(.+))?$/.exec(node.type);
|
||||
|
||||
if (!m && node.type != "subflow" && node.type != "comment") {
|
||||
if (node._def) {
|
||||
var count = 0;
|
||||
var defaults = node._def.defaults;
|
||||
for (var n in defaults) {
|
||||
if (n != "name" && defaults.hasOwnProperty(n)) {
|
||||
var val = node[n];
|
||||
var type = typeof val;
|
||||
count++;
|
||||
propRow = $('<tr class="node-info-property-row'+(expandedSections.property?"":" hide")+'"><td>'+n+"</td><td></td></tr>").appendTo(tableBody);
|
||||
if (defaults[n].type) {
|
||||
var configNode = RED.nodes.node(val);
|
||||
if (!configNode) {
|
||||
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
|
||||
} else {
|
||||
var configLabel = RED.utils.getNodeLabel(configNode,val);
|
||||
var container = propRow.children()[1];
|
||||
|
||||
var div = $('<span>',{class:""}).appendTo(container);
|
||||
var nodeDiv = $('<div>',{class:"palette_node palette_node_small"}).appendTo(div);
|
||||
var colour = configNode._def.color;
|
||||
var icon_url = RED.utils.getNodeIcon(configNode._def);
|
||||
nodeDiv.css({'backgroundColor':colour, "cursor":"pointer"});
|
||||
var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
||||
$('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer);
|
||||
var nodeContainer = $('<span></span>').css({"verticalAlign":"top","marginLeft":"6px"}).html(configLabel).appendTo(container);
|
||||
|
||||
nodeDiv.on('dblclick',function() {
|
||||
RED.editor.editConfig("", configNode.type, configNode.id);
|
||||
})
|
||||
|
||||
}
|
||||
} else {
|
||||
RED.utils.createObjectElement(val).appendTo(propRow.children()[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
$('<tr class="node-info-property-expand blank"><td colspan="2"><a href="#" class=" node-info-property-header'+(expandedSections.property?" expanded":"")+'"><span class="node-info-property-show-more">show more</span><span class="node-info-property-show-less">show less</span> <i class="fa fa-caret-down"></i></a></td></tr>').appendTo(tableBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m) {
|
||||
if (m[2]) {
|
||||
subflowNode = RED.nodes.subflow(m[2]);
|
||||
@@ -200,49 +152,120 @@ RED.sidebar.info = (function() {
|
||||
subflowNode = node;
|
||||
}
|
||||
|
||||
$('<tr class="blank"><th colspan="2">'+RED._("sidebar.info.subflow")+'</th></tr>').appendTo(tableBody);
|
||||
|
||||
var userCount = 0;
|
||||
subflowUserCount = 0;
|
||||
var subflowType = "subflow:"+subflowNode.id;
|
||||
RED.nodes.eachNode(function(n) {
|
||||
if (n.type === subflowType) {
|
||||
userCount++;
|
||||
subflowUserCount++;
|
||||
}
|
||||
});
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("common.label.name")+'</td><td><span class="bidiAware" dir=\"'+RED.text.bidi.resolveBaseTextDir(subflowNode.name)+'">'+subflowNode.name+'</span></td></tr>').appendTo(tableBody);
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+userCount+'</td></tr>').appendTo(tableBody);
|
||||
}
|
||||
if (node.type === "tab" || node.type === "subflow") {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info."+(node.type==='tab'?'flow':'subflow'))+'</td><td></td></tr>').appendTo(tableBody);
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.tabName")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(node.label||node.name||"");
|
||||
if (node.type === "tab") {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.status")+'</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).html((!!!node.disabled)?RED._("sidebar.info.enabled"):RED._("sidebar.info.disabled"))
|
||||
}
|
||||
} else {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.node")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
|
||||
|
||||
if (node.type !== "subflow" && node.name) {
|
||||
$('<tr class="node-info-node-row"><td>'+RED._("common.label.name")+'</td><td><span class="bidiAware" dir="'+RED.text.bidi.resolveBaseTextDir(node.name)+'">'+node.name+'</span></td></tr>').appendTo(tableBody);
|
||||
}
|
||||
if (!m) {
|
||||
$('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.type")+"</td><td>"+node.type+"</td></tr>").appendTo(tableBody);
|
||||
}
|
||||
|
||||
if (!m && node.type != "subflow" && node.type != "comment") {
|
||||
if (node._def) {
|
||||
var count = 0;
|
||||
var defaults = node._def.defaults;
|
||||
for (var n in defaults) {
|
||||
if (n != "name" && defaults.hasOwnProperty(n)) {
|
||||
var val = node[n];
|
||||
var type = typeof val;
|
||||
count++;
|
||||
propRow = $('<tr class="node-info-property-row'+(expandedSections.property?"":" hide")+'"><td>'+n+"</td><td></td></tr>").appendTo(tableBody);
|
||||
if (defaults[n].type) {
|
||||
var configNode = RED.nodes.node(val);
|
||||
if (!configNode) {
|
||||
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
|
||||
} else {
|
||||
var configLabel = RED.utils.getNodeLabel(configNode,val);
|
||||
var container = propRow.children()[1];
|
||||
|
||||
var div = $('<span>',{class:""}).appendTo(container);
|
||||
var nodeDiv = $('<div>',{class:"palette_node palette_node_small"}).appendTo(div);
|
||||
var colour = configNode._def.color;
|
||||
var icon_url = RED.utils.getNodeIcon(configNode._def);
|
||||
nodeDiv.css({'backgroundColor':colour, "cursor":"pointer"});
|
||||
var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
||||
$('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer);
|
||||
var nodeContainer = $('<span></span>').css({"verticalAlign":"top","marginLeft":"6px"}).html(configLabel).appendTo(container);
|
||||
|
||||
nodeDiv.on('dblclick',function() {
|
||||
RED.editor.editConfig("", configNode.type, configNode.id);
|
||||
})
|
||||
|
||||
}
|
||||
} else {
|
||||
RED.utils.createObjectElement(val).appendTo(propRow.children()[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
$('<tr class="node-info-property-expand blank"><td colspan="2"><a href="#" class=" node-info-property-header'+(expandedSections.property?" expanded":"")+'"><span class="node-info-property-show-more">'+RED._("sidebar.info.showMore")+'</span><span class="node-info-property-show-less">'+RED._("sidebar.info.showLess")+'</span> <i class="fa fa-caret-down"></i></a></td></tr>').appendTo(tableBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.type !== 'tab') {
|
||||
if (m) {
|
||||
$('<tr class="blank"><th colspan="2">'+RED._("sidebar.info.subflow")+'</th></tr>').appendTo(tableBody);
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("common.label.name")+'</td><td><span class="bidiAware" dir=\"'+RED.text.bidi.resolveBaseTextDir(subflowNode.name)+'">'+subflowNode.name+'</span></td></tr>').appendTo(tableBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m) {
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+subflowUserCount+'</td></tr>').appendTo(tableBody);
|
||||
}
|
||||
|
||||
var infoText = "";
|
||||
if (!subflowNode && node.type !== "comment" && node.type !== "tab") {
|
||||
infoSection.title.html(RED._("sidebar.info.nodeHelp"));
|
||||
var helpText = $("script[data-help-name='"+node.type+"']").html()||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
infoText = helpText;
|
||||
} else if (node.type === "tab") {
|
||||
infoSection.title.html(RED._("sidebar.info.flowDesc"));
|
||||
infoText = marked(node.info||"")||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
}
|
||||
|
||||
if (subflowNode) {
|
||||
infoText = infoText + (marked(subflowNode.info||"")||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
||||
infoSection.title.html(RED._("sidebar.info.subflowDesc"));
|
||||
} else if (node._def && node._def.info) {
|
||||
infoSection.title.html(RED._("sidebar.info.nodeHelp"));
|
||||
var info = node._def.info;
|
||||
var textInfo = (typeof info === "function" ? info.call(node) : info);
|
||||
// TODO: help
|
||||
infoText = infoText + marked(textInfo);
|
||||
}
|
||||
if (infoText) {
|
||||
setInfoText(infoText);
|
||||
}
|
||||
|
||||
|
||||
$(".node-info-property-header").click(function(e) {
|
||||
e.preventDefault();
|
||||
expandedSections["property"] = !expandedSections["property"];
|
||||
$(this).toggleClass("expanded",expandedSections["property"]);
|
||||
$(".node-info-property-row").toggle(expandedSections["property"]);
|
||||
});
|
||||
}
|
||||
$(table).appendTo(nodeSection.content);
|
||||
|
||||
var infoText = "";
|
||||
|
||||
if (!subflowNode && node.type !== "comment" && node.type !== "tab") {
|
||||
var helpText = $("script[data-help-name='"+node.type+"']").html()||"";
|
||||
infoText = helpText;
|
||||
} else if (node.type === "tab") {
|
||||
infoText = marked(node.info||"");
|
||||
}
|
||||
|
||||
if (subflowNode) {
|
||||
infoText = infoText + marked(subflowNode.info||"");
|
||||
} else if (node._def && node._def.info) {
|
||||
var info = node._def.info;
|
||||
var textInfo = (typeof info === "function" ? info.call(node) : info);
|
||||
// TODO: help
|
||||
infoText = infoText + marked(textInfo);
|
||||
}
|
||||
if (infoText) {
|
||||
setInfoText(infoText);
|
||||
}
|
||||
|
||||
|
||||
$(".node-info-property-header").click(function(e) {
|
||||
e.preventDefault();
|
||||
expandedSections["property"] = !expandedSections["property"];
|
||||
$(this).toggleClass("expanded",expandedSections["property"]);
|
||||
$(".node-info-property-row").toggle(expandedSections["property"]);
|
||||
});
|
||||
}
|
||||
function setInfoText(infoText) {
|
||||
var info = addTargetToExternalLinks($('<div class="node-help"><span class="bidiAware" dir=\"'+RED.text.bidi.resolveBaseTextDir(infoText)+'">'+infoText+'</span></div>')).appendTo(infoSection.content);
|
||||
@@ -342,22 +365,25 @@ RED.sidebar.info = (function() {
|
||||
})();
|
||||
|
||||
function clear() {
|
||||
sections.hide();
|
||||
//
|
||||
// sections.hide();
|
||||
refresh(null);
|
||||
}
|
||||
|
||||
function set(html) {
|
||||
function set(html,title) {
|
||||
// tips.stop();
|
||||
sections.show();
|
||||
nodeSection.container.hide();
|
||||
// sections.show();
|
||||
// nodeSection.container.hide();
|
||||
infoSection.title.text(title||"");
|
||||
refresh(null);
|
||||
$(infoSection.content).empty();
|
||||
setInfoText(html);
|
||||
$(".sidebar-node-info-stack").scrollTop(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RED.events.on("view:selection-changed",function(selection) {
|
||||
function refreshSelection(selection) {
|
||||
if (selection === undefined) {
|
||||
selection = RED.view.selection();
|
||||
}
|
||||
if (selection.nodes) {
|
||||
if (selection.nodes.length == 1) {
|
||||
var node = selection.nodes[0];
|
||||
@@ -366,6 +392,8 @@ RED.sidebar.info = (function() {
|
||||
} else {
|
||||
refresh(node);
|
||||
}
|
||||
} else {
|
||||
refresh(selection.nodes);
|
||||
}
|
||||
} else {
|
||||
var activeWS = RED.workspaces.active();
|
||||
@@ -378,11 +406,15 @@ RED.sidebar.info = (function() {
|
||||
if (workspace && workspace.info) {
|
||||
refresh(workspace);
|
||||
} else {
|
||||
clear();
|
||||
refresh(null)
|
||||
// clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
RED.events.on("view:selection-changed",refreshSelection);
|
||||
|
||||
return {
|
||||
init: init,
|
||||
|
@@ -32,7 +32,15 @@ RED.tray = (function() {
|
||||
// var growButton = $('<a class="editor-tray-resize-button" style="cursor: w-resize;"><i class="fa fa-angle-left"></i></a>').appendTo(resizer);
|
||||
// var shrinkButton = $('<a class="editor-tray-resize-button" style="cursor: e-resize;"><i style="margin-left: 1px;" class="fa fa-angle-right"></i></a>').appendTo(resizer);
|
||||
if (options.title) {
|
||||
$('<div class="editor-tray-titlebar">'+options.title+'</div>').appendTo(header);
|
||||
var titles = stack.map(function(e) { return e.options.title });
|
||||
titles.push(options.title);
|
||||
var title = '<ul class="editor-tray-breadcrumbs"><li>'+titles.join("</li><li>")+'</li></ul>';
|
||||
|
||||
$('<div class="editor-tray-titlebar">'+title+'</div>').appendTo(header);
|
||||
}
|
||||
if (options.width === Infinity) {
|
||||
options.maximized = true;
|
||||
resizer.addClass('editor-tray-resize-maximised');
|
||||
}
|
||||
var buttonBar = $('<div class="editor-tray-toolbar"></div>').appendTo(header);
|
||||
var primaryButton;
|
||||
@@ -74,7 +82,8 @@ RED.tray = (function() {
|
||||
};
|
||||
stack.push(tray);
|
||||
|
||||
el.draggable({
|
||||
if (!options.maximized) {
|
||||
el.draggable({
|
||||
handle: resizer,
|
||||
axis: "x",
|
||||
start:function(event,ui) {
|
||||
@@ -103,16 +112,17 @@ RED.tray = (function() {
|
||||
tray.width = -ui.position.left;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function finishBuild() {
|
||||
$("#header-shade").show();
|
||||
$("#editor-shade").show();
|
||||
$("#palette-shade").show();
|
||||
$(".sidebar-shade").show();
|
||||
|
||||
tray.preferredWidth = Math.max(el.width(),500);
|
||||
body.css({"minWidth":tray.preferredWidth-40});
|
||||
|
||||
if (!options.maximized) {
|
||||
body.css({"minWidth":tray.preferredWidth-40});
|
||||
}
|
||||
if (options.width) {
|
||||
if (options.width > $("#editor-stack").position().left-8) {
|
||||
options.width = $("#editor-stack").position().left-8;
|
||||
@@ -175,7 +185,7 @@ RED.tray = (function() {
|
||||
var tray = stack[stack.length-1];
|
||||
var trayHeight = tray.tray.height()-tray.header.outerHeight()-tray.footer.outerHeight();
|
||||
tray.body.height(trayHeight);
|
||||
if (tray.width > $("#editor-stack").position().left-8) {
|
||||
if (tray.options.maximized || tray.width > $("#editor-stack").position().left-8) {
|
||||
tray.width = $("#editor-stack").position().left-8;
|
||||
tray.tray.width(tray.width);
|
||||
// tray.body.parent().width(tray.width);
|
||||
@@ -204,8 +214,11 @@ RED.tray = (function() {
|
||||
});
|
||||
},
|
||||
show: function show(options) {
|
||||
if (stack.length > 0) {
|
||||
if (stack.length > 0 && !options.overlay) {
|
||||
var oldTray = stack[stack.length-1];
|
||||
if (options.width === "inherit") {
|
||||
options.width = oldTray.tray.width();
|
||||
}
|
||||
oldTray.tray.css({
|
||||
right: -(oldTray.tray.width()+10)+"px"
|
||||
});
|
||||
@@ -232,14 +245,21 @@ RED.tray = (function() {
|
||||
tray.tray.remove();
|
||||
if (stack.length > 0) {
|
||||
var oldTray = stack[stack.length-1];
|
||||
oldTray.tray.appendTo("#editor-stack");
|
||||
setTimeout(function() {
|
||||
if (!oldTray.options.overlay) {
|
||||
oldTray.tray.appendTo("#editor-stack");
|
||||
setTimeout(function() {
|
||||
handleWindowResize();
|
||||
oldTray.tray.css({right:0});
|
||||
if (oldTray.options.show) {
|
||||
oldTray.options.show();
|
||||
}
|
||||
},0);
|
||||
} else {
|
||||
handleWindowResize();
|
||||
oldTray.tray.css({right:0});
|
||||
if (oldTray.options.show) {
|
||||
oldTray.options.show();
|
||||
}
|
||||
},0);
|
||||
}
|
||||
}
|
||||
if (done) {
|
||||
done();
|
||||
|
@@ -12,12 +12,14 @@ RED.typeSearch = (function() {
|
||||
|
||||
var activeFilter = "";
|
||||
var addCallback;
|
||||
var cancelCallback;
|
||||
|
||||
var typesUsed = {};
|
||||
|
||||
function search(val) {
|
||||
activeFilter = val.toLowerCase();
|
||||
var visible = searchResults.editableList('filter');
|
||||
searchResults.editableList('sort');
|
||||
setTimeout(function() {
|
||||
selected = 0;
|
||||
searchResults.children().removeClass('selected');
|
||||
@@ -100,6 +102,23 @@ RED.typeSearch = (function() {
|
||||
}
|
||||
return (activeFilter==="")||(data.index.indexOf(activeFilter) > -1);
|
||||
},
|
||||
sort: function(A,B) {
|
||||
if (activeFilter === "") {
|
||||
return A.i - B.i;
|
||||
}
|
||||
var Ai = A.index.indexOf(activeFilter);
|
||||
var Bi = B.index.indexOf(activeFilter);
|
||||
if (Ai === -1) {
|
||||
return 1;
|
||||
}
|
||||
if (Bi === -1) {
|
||||
return -1;
|
||||
}
|
||||
if (Ai === Bi) {
|
||||
return sortTypeLabels(A,B);
|
||||
}
|
||||
return Ai-Bi;
|
||||
},
|
||||
addItem: function(container,i,object) {
|
||||
var def = object.def;
|
||||
object.index = object.type.toLowerCase();
|
||||
@@ -155,11 +174,19 @@ RED.typeSearch = (function() {
|
||||
t = t.parent();
|
||||
}
|
||||
hide(true);
|
||||
if (cancelCallback) {
|
||||
cancelCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
function show(opts) {
|
||||
if (!visible) {
|
||||
RED.keyboard.add("*","escape",function(){hide()});
|
||||
RED.keyboard.add("*","escape",function(){
|
||||
hide();
|
||||
if (cancelCallback) {
|
||||
cancelCallback();
|
||||
}
|
||||
});
|
||||
if (dialog === null) {
|
||||
createDialog();
|
||||
}
|
||||
@@ -175,6 +202,7 @@ RED.typeSearch = (function() {
|
||||
}
|
||||
refreshTypeList();
|
||||
addCallback = opts.add;
|
||||
closeCallback = opts.close;
|
||||
RED.events.emit("type-search:open");
|
||||
//shade.show();
|
||||
dialog.css({left:opts.x+"px",top:opts.y+"px"}).show();
|
||||
@@ -215,7 +243,17 @@ RED.typeSearch = (function() {
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
function sortTypeLabels(a,b) {
|
||||
var al = a.label.toLowerCase();
|
||||
var bl = b.label.toLowerCase();
|
||||
if (al < bl) {
|
||||
return -1;
|
||||
} else if (al === bl) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
function refreshTypeList() {
|
||||
var i;
|
||||
searchResults.editableList('empty');
|
||||
@@ -236,41 +274,37 @@ RED.typeSearch = (function() {
|
||||
var items = [];
|
||||
RED.nodes.registry.getNodeTypes().forEach(function(t) {
|
||||
var def = RED.nodes.getType(t);
|
||||
if (def.category !== 'config' && t !== 'unknown') {
|
||||
if (def.category !== 'config' && t !== 'unknown' && t !== 'tab') {
|
||||
items.push({type:t,def: def, label:getTypeLabel(t,def)});
|
||||
}
|
||||
});
|
||||
items.sort(function(a,b) {
|
||||
var al = a.label.toLowerCase();
|
||||
var bl = b.label.toLowerCase();
|
||||
if (al < bl) {
|
||||
return -1;
|
||||
} else if (al === bl) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
})
|
||||
items.sort(sortTypeLabels);
|
||||
|
||||
var commonCount = 0;
|
||||
var item;
|
||||
var index = 0;
|
||||
for(i=0;i<common.length;i++) {
|
||||
item = {
|
||||
type: common[i],
|
||||
common: true,
|
||||
def: RED.nodes.getType(common[i])
|
||||
};
|
||||
item.label = getTypeLabel(item.type,item.def);
|
||||
if (i === common.length-1) {
|
||||
item.separator = true;
|
||||
var itemDef = RED.nodes.getType(common[i]);
|
||||
if (itemDef) {
|
||||
item = {
|
||||
type: common[i],
|
||||
common: true,
|
||||
def: itemDef,
|
||||
i: index++
|
||||
};
|
||||
item.label = getTypeLabel(item.type,item.def);
|
||||
if (i === common.length-1) {
|
||||
item.separator = true;
|
||||
}
|
||||
searchResults.editableList('addItem', item);
|
||||
}
|
||||
searchResults.editableList('addItem', item);
|
||||
}
|
||||
for(i=0;i<Math.min(5,recentlyUsed.length);i++) {
|
||||
item = {
|
||||
type:recentlyUsed[i],
|
||||
def: RED.nodes.getType(recentlyUsed[i]),
|
||||
recent: true
|
||||
recent: true,
|
||||
i: index++
|
||||
};
|
||||
item.label = getTypeLabel(item.type,item.def);
|
||||
if (i === recentlyUsed.length-1) {
|
||||
@@ -279,6 +313,7 @@ RED.typeSearch = (function() {
|
||||
searchResults.editableList('addItem', item);
|
||||
}
|
||||
for (i=0;i<items.length;i++) {
|
||||
items[i].i = index++;
|
||||
searchResults.editableList('addItem', items[i]);
|
||||
}
|
||||
setTimeout(function() {
|
||||
|
@@ -29,11 +29,15 @@ RED.userSettings = (function() {
|
||||
if (settingsVisible) {
|
||||
return;
|
||||
}
|
||||
if (!RED.user.hasPermission("settings.write")) {
|
||||
RED.notify(RED._("user.errors.settings"),"error");
|
||||
return;
|
||||
}
|
||||
settingsVisible = true;
|
||||
var tabContainer;
|
||||
|
||||
var trayOptions = {
|
||||
title: "User Settings",
|
||||
title: RED._("menu.label.userSettings"),
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-ok",
|
||||
@@ -100,7 +104,7 @@ RED.userSettings = (function() {
|
||||
|
||||
var viewSettings = [
|
||||
{
|
||||
title: "Grid",
|
||||
title: "menu.label.view.grid",
|
||||
options: [
|
||||
{setting:"view-show-grid",oldSetting:"menu-menu-item-view-show-grid",label:"menu.label.view.showGrid",toggle:true,onchange:"core:toggle-show-grid"},
|
||||
{setting:"view-snap-grid",oldSetting:"menu-menu-item-view-snap-grid",label:"menu.label.view.snapGrid",toggle:true,onchange:"core:toggle-snap-grid"},
|
||||
@@ -108,13 +112,13 @@ RED.userSettings = (function() {
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Nodes",
|
||||
title: "menu.label.nodes",
|
||||
options: [
|
||||
{setting:"view-node-status",oldSetting:"menu-menu-item-status",label:"menu.label.displayStatus",default: true, toggle:true,onchange:"core:toggle-status"}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Other",
|
||||
title: "menu.label.other",
|
||||
options: [
|
||||
{setting:"view-show-tips",oldSettings:"menu-menu-item-show-tips",label:"menu.label.showTips",toggle:true,default:true,onchange:"core:toggle-show-tips"}
|
||||
]
|
||||
@@ -127,10 +131,13 @@ RED.userSettings = (function() {
|
||||
|
||||
var pane = $('<div id="user-settings-tab-view" class="node-help"></div>');
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.view = currentEditorSettings.view || {};
|
||||
|
||||
viewSettings.forEach(function(section) {
|
||||
$('<h3></h3>').text(section.title).appendTo(pane);
|
||||
$('<h3></h3>').text(RED._(section.title)).appendTo(pane);
|
||||
section.options.forEach(function(opt) {
|
||||
var initialState = RED.settings.get(opt.setting);
|
||||
var initialState = currentEditorSettings.view[opt.setting];
|
||||
var row = $('<div class="user-settings-row"></div>').appendTo(pane);
|
||||
var input;
|
||||
if (opt.toggle) {
|
||||
@@ -147,7 +154,10 @@ RED.userSettings = (function() {
|
||||
|
||||
function setSelected(id, value) {
|
||||
var opt = allSettings[id];
|
||||
RED.settings.set(opt.setting,value);
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.view = currentEditorSettings.view || {};
|
||||
currentEditorSettings.view[opt.setting] = value;
|
||||
RED.settings.set('editor', currentEditorSettings);
|
||||
var callback = opt.onchange;
|
||||
if (typeof callback === 'string') {
|
||||
callback = RED.actions.get(callback);
|
||||
@@ -158,8 +168,9 @@ RED.userSettings = (function() {
|
||||
}
|
||||
function toggle(id) {
|
||||
var opt = allSettings[id];
|
||||
var state = RED.settings.get(opt.setting);
|
||||
setSelected(id,!state);
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.view = currentEditorSettings.view || {};
|
||||
setSelected(id,!currentEditorSettings.view[opt.setting]);
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +180,7 @@ RED.userSettings = (function() {
|
||||
|
||||
addPane({
|
||||
id:'view',
|
||||
title: 'View',
|
||||
title: RED._("menu.label.view.view"),
|
||||
get: createViewPane,
|
||||
close: function() {
|
||||
viewSettings.forEach(function(section) {
|
||||
@@ -185,21 +196,26 @@ RED.userSettings = (function() {
|
||||
}
|
||||
})
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.view = currentEditorSettings.view || {};
|
||||
var editorSettingsChanged = false;
|
||||
viewSettings.forEach(function(section) {
|
||||
section.options.forEach(function(opt) {
|
||||
if (opt.oldSetting) {
|
||||
var oldValue = RED.settings.get(opt.oldSetting);
|
||||
if (oldValue !== undefined && oldValue !== null) {
|
||||
RED.settings.set(opt.setting,oldValue);
|
||||
currentEditorSettings.view[opt.setting] = oldValue;
|
||||
editorSettingsChanged = true;
|
||||
RED.settings.remove(opt.oldSetting);
|
||||
}
|
||||
}
|
||||
allSettings[opt.setting] = opt;
|
||||
if (opt.onchange) {
|
||||
var value = RED.settings.get(opt.setting);
|
||||
if (value === null && opt.hasOwnProperty('default')) {
|
||||
var value = currentEditorSettings.view[opt.setting];
|
||||
if ((value === null || value === undefined) && opt.hasOwnProperty('default')) {
|
||||
value = opt.default;
|
||||
RED.settings.set(opt.setting,value);
|
||||
currentEditorSettings.view[opt.setting] = value;
|
||||
editorSettingsChanged = true;
|
||||
}
|
||||
|
||||
var callback = opt.onchange;
|
||||
@@ -212,6 +228,9 @@ RED.userSettings = (function() {
|
||||
}
|
||||
});
|
||||
});
|
||||
if (editorSettingsChanged) {
|
||||
RED.settings.set('editor',currentEditorSettings);
|
||||
}
|
||||
|
||||
}
|
||||
return {
|
||||
|
@@ -50,24 +50,58 @@ RED.utils = (function() {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function makeExpandable(el,onexpand,expand) {
|
||||
function makeExpandable(el,onbuild,ontoggle,expand) {
|
||||
el.addClass("debug-message-expandable");
|
||||
el.prop('toggle',function() {
|
||||
return function(state) {
|
||||
var parent = el.parent();
|
||||
if (parent.hasClass('collapsed')) {
|
||||
if (state) {
|
||||
if (onbuild && !parent.hasClass('built')) {
|
||||
onbuild();
|
||||
parent.addClass('built');
|
||||
}
|
||||
parent.removeClass('collapsed');
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!state) {
|
||||
parent.addClass('collapsed');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
el.click(function(e) {
|
||||
var parent = $(this).parent();
|
||||
if (parent.hasClass('collapsed')) {
|
||||
if (onexpand && !parent.hasClass('built')) {
|
||||
onexpand();
|
||||
parent.addClass('built');
|
||||
var currentState = !parent.hasClass('collapsed');
|
||||
if ($(this).prop('toggle')(!currentState)) {
|
||||
if (ontoggle) {
|
||||
ontoggle(!currentState);
|
||||
}
|
||||
parent.removeClass('collapsed');
|
||||
} else {
|
||||
parent.addClass('collapsed');
|
||||
}
|
||||
// if (parent.hasClass('collapsed')) {
|
||||
// if (onbuild && !parent.hasClass('built')) {
|
||||
// onbuild();
|
||||
// parent.addClass('built');
|
||||
// }
|
||||
// if (ontoggle) {
|
||||
// ontoggle(true);
|
||||
// }
|
||||
// parent.removeClass('collapsed');
|
||||
// } else {
|
||||
// parent.addClass('collapsed');
|
||||
// if (ontoggle) {
|
||||
// ontoggle(false);
|
||||
// }
|
||||
// }
|
||||
e.preventDefault();
|
||||
});
|
||||
if (expand) {
|
||||
el.click();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var pinnedPaths = {};
|
||||
@@ -137,7 +171,7 @@ RED.utils = (function() {
|
||||
}
|
||||
|
||||
function formatNumber(element,obj,sourceId,path,cycle,initialFormat) {
|
||||
var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path]) || initialFormat || "dec";
|
||||
var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path] && formattedPaths[sourceId][path]['number']) || initialFormat || "dec";
|
||||
if (cycle) {
|
||||
if (format === 'dec') {
|
||||
if ((obj.toString().length===13) && (obj<=2147483647000)) {
|
||||
@@ -153,10 +187,12 @@ RED.utils = (function() {
|
||||
format = 'dec';
|
||||
}
|
||||
formattedPaths[sourceId] = formattedPaths[sourceId]||{};
|
||||
formattedPaths[sourceId][path] = format;
|
||||
formattedPaths[sourceId][path] = formattedPaths[sourceId][path]||{};
|
||||
formattedPaths[sourceId][path]['number'] = format;
|
||||
} else if (initialFormat !== undefined){
|
||||
formattedPaths[sourceId] = formattedPaths[sourceId]||{};
|
||||
formattedPaths[sourceId][path] = format;
|
||||
formattedPaths[sourceId][path] = formattedPaths[sourceId][path]||{};
|
||||
formattedPaths[sourceId][path]['number'] = format;
|
||||
}
|
||||
if (format === 'dec') {
|
||||
element.text(""+obj);
|
||||
@@ -170,7 +206,7 @@ RED.utils = (function() {
|
||||
}
|
||||
|
||||
function formatBuffer(element,button,sourceId,path,cycle) {
|
||||
var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path]) || "raw";
|
||||
var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path] && formattedPaths[sourceId][path]['buffer']) || "raw";
|
||||
if (cycle) {
|
||||
if (format === 'raw') {
|
||||
format = 'string';
|
||||
@@ -178,7 +214,8 @@ RED.utils = (function() {
|
||||
format = 'raw';
|
||||
}
|
||||
formattedPaths[sourceId] = formattedPaths[sourceId]||{};
|
||||
formattedPaths[sourceId][path] = format;
|
||||
formattedPaths[sourceId][path] = formattedPaths[sourceId][path]||{};
|
||||
formattedPaths[sourceId][path]['buffer'] = format;
|
||||
}
|
||||
if (format === 'raw') {
|
||||
button.text('raw');
|
||||
@@ -189,10 +226,23 @@ RED.utils = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
function buildMessageElement(obj,key,typeHint,hideKey,path,sourceId,rootPath,expandPaths) {
|
||||
function buildMessageElement(obj,options) {
|
||||
options = options || {};
|
||||
var key = options.key;
|
||||
var typeHint = options.typeHint;
|
||||
var hideKey = options.hideKey;
|
||||
var path = options.path;
|
||||
var sourceId = options.sourceId;
|
||||
var rootPath = options.rootPath;
|
||||
var expandPaths = options.expandPaths;
|
||||
var ontoggle = options.ontoggle;
|
||||
var exposeApi = options.exposeApi;
|
||||
|
||||
var subElements = {};
|
||||
var i;
|
||||
var e;
|
||||
var entryObj;
|
||||
var expandableHeader;
|
||||
var header;
|
||||
var headerHead;
|
||||
var value;
|
||||
@@ -257,7 +307,7 @@ RED.utils = (function() {
|
||||
$('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html(typeHint||'string').appendTo(header);
|
||||
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element);
|
||||
$('<pre class="debug-message-type-string"></pre>').text(obj).appendTo(row);
|
||||
},checkExpanded(strippedKey,expandPaths));
|
||||
},function(state) {if (ontoggle) { ontoggle(path,state);}}, checkExpanded(strippedKey,expandPaths));
|
||||
}
|
||||
e = $('<span class="debug-message-type-string debug-message-object-header"></span>').html('"'+formatString(sanitize(obj))+'"').appendTo(entryObj);
|
||||
if (/^#[0-9a-f]{6}$/i.test(obj)) {
|
||||
@@ -356,7 +406,20 @@ RED.utils = (function() {
|
||||
if (fullLength <= 10) {
|
||||
for (i=0;i<fullLength;i++) {
|
||||
row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(arrayRows);
|
||||
buildMessageElement(data[i],""+i,type==='buffer'?'hex':false,false,path+"["+i+"]",sourceId,rootPath,expandPaths).appendTo(row);
|
||||
subElements[path+"["+i+"]"] = buildMessageElement(
|
||||
data[i],
|
||||
{
|
||||
key: ""+i,
|
||||
typeHint: type==='buffer'?'hex':false,
|
||||
hideKey: false,
|
||||
path: path+"["+i+"]",
|
||||
sourceId: sourceId,
|
||||
rootPath: rootPath,
|
||||
expandPaths: expandPaths,
|
||||
ontoggle: ontoggle,
|
||||
exposeApi: exposeApi
|
||||
}
|
||||
).appendTo(row);
|
||||
}
|
||||
} else {
|
||||
for (i=0;i<fullLength;i+=10) {
|
||||
@@ -371,17 +434,35 @@ RED.utils = (function() {
|
||||
return function() {
|
||||
for (var i=min;i<=max;i++) {
|
||||
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(parent);
|
||||
buildMessageElement(data[i],""+i,type==='buffer'?'hex':false,false,path+"["+i+"]",sourceId,rootPath,expandPaths).appendTo(row);
|
||||
subElements[path+"["+i+"]"] = buildMessageElement(
|
||||
data[i],
|
||||
{
|
||||
key: ""+i,
|
||||
typeHint: type==='buffer'?'hex':false,
|
||||
hideKey: false,
|
||||
path: path+"["+i+"]",
|
||||
sourceId: sourceId,
|
||||
rootPath: rootPath,
|
||||
expandPaths: expandPaths,
|
||||
ontoggle: ontoggle,
|
||||
exposeApi: exposeApi
|
||||
|
||||
}
|
||||
).appendTo(row);
|
||||
}
|
||||
}
|
||||
})(),checkExpanded(strippedKey,expandPaths,minRange,Math.min(fullLength-1,(minRange+9))));
|
||||
})(),
|
||||
(function() { var path = path+"["+i+"]"; return function(state) {if (ontoggle) { ontoggle(path,state);}}})(),
|
||||
checkExpanded(strippedKey,expandPaths,minRange,Math.min(fullLength-1,(minRange+9))));
|
||||
$('<span class="debug-message-object-key"></span>').html("["+minRange+" … "+Math.min(fullLength-1,(minRange+9))+"]").appendTo(header);
|
||||
}
|
||||
if (fullLength < originalLength) {
|
||||
$('<div class="debug-message-object-entry collapsed"><span class="debug-message-object-key">['+fullLength+' … '+originalLength+']</span></div>').appendTo(arrayRows);
|
||||
}
|
||||
}
|
||||
},checkExpanded(strippedKey,expandPaths));
|
||||
},
|
||||
function(state) {if (ontoggle) { ontoggle(path,state);}},
|
||||
checkExpanded(strippedKey,expandPaths));
|
||||
}
|
||||
} else if (typeof obj === 'object') {
|
||||
element.addClass('collapsed');
|
||||
@@ -395,17 +476,35 @@ RED.utils = (function() {
|
||||
for (i=0;i<keys.length;i++) {
|
||||
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element);
|
||||
var newPath = path;
|
||||
if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(keys[i])) {
|
||||
newPath += (newPath.length > 0?".":"")+keys[i];
|
||||
} else {
|
||||
newPath += "[\""+keys[i].replace(/"/,"\\\"")+"\"]"
|
||||
if (newPath) {
|
||||
if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(keys[i])) {
|
||||
newPath += (newPath.length > 0?".":"")+keys[i];
|
||||
} else {
|
||||
newPath += "[\""+keys[i].replace(/"/,"\\\"")+"\"]"
|
||||
}
|
||||
}
|
||||
buildMessageElement(obj[keys[i]],keys[i],false,false,newPath,sourceId,rootPath,expandPaths).appendTo(row);
|
||||
subElements[newPath] = buildMessageElement(
|
||||
obj[keys[i]],
|
||||
{
|
||||
key: keys[i],
|
||||
typeHint: false,
|
||||
hideKey: false,
|
||||
path: newPath,
|
||||
sourceId: sourceId,
|
||||
rootPath: rootPath,
|
||||
expandPaths: expandPaths,
|
||||
ontoggle: ontoggle,
|
||||
exposeApi: exposeApi
|
||||
|
||||
}
|
||||
).appendTo(row);
|
||||
}
|
||||
if (keys.length === 0) {
|
||||
$('<div class="debug-message-object-entry debug-message-type-meta collapsed"></div>').text("empty").appendTo(element);
|
||||
}
|
||||
},checkExpanded(strippedKey,expandPaths));
|
||||
},
|
||||
function(state) {if (ontoggle) { ontoggle(path,state);}},
|
||||
checkExpanded(strippedKey,expandPaths));
|
||||
}
|
||||
if (key) {
|
||||
$('<span class="debug-message-type-meta"></span>').html('object').appendTo(entryObj);
|
||||
@@ -432,6 +531,28 @@ RED.utils = (function() {
|
||||
} else {
|
||||
$('<span class="debug-message-type-other"></span>').text(""+obj).appendTo(entryObj);
|
||||
}
|
||||
if (exposeApi) {
|
||||
element.prop('expand', function() { return function(targetPath, state) {
|
||||
if (path === targetPath) {
|
||||
if (header.prop('toggle')) {
|
||||
header.prop('toggle')(state);
|
||||
}
|
||||
} else if (subElements[targetPath] && subElements[targetPath].prop('expand') ) {
|
||||
subElements[targetPath].prop('expand')(targetPath,state);
|
||||
} else {
|
||||
for (var p in subElements) {
|
||||
if (subElements.hasOwnProperty(p)) {
|
||||
if (targetPath.indexOf(p) === 0) {
|
||||
if (subElements[p].prop('expand') ) {
|
||||
subElements[p].prop('expand')(targetPath,state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}});
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@@ -571,14 +692,21 @@ RED.utils = (function() {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getNodeIcon(def,node) {
|
||||
if (def.category === 'config') {
|
||||
return "icons/node-red/cog.png"
|
||||
} else if (node && node.type === 'tab') {
|
||||
return "icons/node-red/subflow.png"
|
||||
} else if (node && node.type === 'unknown') {
|
||||
return "icons/node-red/alert.png"
|
||||
function separateIconPath(icon) {
|
||||
var result = {module: "", file: ""};
|
||||
if (icon) {
|
||||
var index = icon.indexOf('/');
|
||||
if (index !== -1) {
|
||||
result.module = icon.slice(0, index);
|
||||
result.file = icon.slice(index + 1);
|
||||
} else {
|
||||
result.file = icon;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getDefaultNodeIcon(def,node) {
|
||||
var icon_url;
|
||||
if (typeof def.icon === "function") {
|
||||
try {
|
||||
@@ -590,7 +718,34 @@ RED.utils = (function() {
|
||||
} else {
|
||||
icon_url = def.icon;
|
||||
}
|
||||
return "icons/"+def.set.module+"/"+icon_url;
|
||||
|
||||
var iconPath = separateIconPath(icon_url);
|
||||
if (!iconPath.module) {
|
||||
iconPath.module = def.set.module;
|
||||
}
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
function getNodeIcon(def,node) {
|
||||
if (def.category === 'config') {
|
||||
return "icons/node-red/cog.png"
|
||||
} else if (node && node.type === 'tab') {
|
||||
return "icons/node-red/subflow.png"
|
||||
} else if (node && node.type === 'unknown') {
|
||||
return "icons/node-red/alert.png"
|
||||
} else if (node && node.type === 'subflow') {
|
||||
return "icons/node-red/subflow.png"
|
||||
} else if (node && node.icon) {
|
||||
var iconPath = separateIconPath(node.icon);
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
var iconFileList = iconSets[iconPath.module];
|
||||
if (iconFileList && iconFileList.indexOf(iconPath.file) !== -1) {
|
||||
return "icons/" + node.icon;
|
||||
}
|
||||
}
|
||||
|
||||
var iconPath = getDefaultNodeIcon(def, node);
|
||||
return "icons/"+iconPath.module+"/"+iconPath.file;
|
||||
}
|
||||
|
||||
function getNodeLabel(node,defaultLabel) {
|
||||
@@ -610,12 +765,23 @@ RED.utils = (function() {
|
||||
return RED.text.bidi.enforceTextDirectionWithUCC(l);
|
||||
}
|
||||
|
||||
function addSpinnerOverlay(container,contain) {
|
||||
var spinner = $('<div class="projects-dialog-spinner "><img src="red/images/spin.svg"/></div>').appendTo(container);
|
||||
if (contain) {
|
||||
spinner.addClass('projects-dialog-spinner-contain');
|
||||
}
|
||||
return spinner;
|
||||
}
|
||||
|
||||
return {
|
||||
createObjectElement: buildMessageElement,
|
||||
getMessageProperty: getMessageProperty,
|
||||
normalisePropertyExpression: normalisePropertyExpression,
|
||||
validatePropertyExpression: validatePropertyExpression,
|
||||
separateIconPath: separateIconPath,
|
||||
getDefaultNodeIcon: getDefaultNodeIcon,
|
||||
getNodeIcon: getNodeIcon,
|
||||
getNodeLabel: getNodeLabel,
|
||||
addSpinnerOverlay: addSpinnerOverlay
|
||||
}
|
||||
})();
|
||||
|
@@ -81,6 +81,9 @@ RED.view = (function() {
|
||||
.style("cursor","crosshair")
|
||||
.on("mousedown", function() {
|
||||
focusView();
|
||||
})
|
||||
.on("contextmenu", function(){
|
||||
d3.event.preventDefault();
|
||||
});
|
||||
|
||||
var vis = outer
|
||||
@@ -396,10 +399,10 @@ RED.view = (function() {
|
||||
}
|
||||
});
|
||||
$("#chart").focus(function() {
|
||||
$("#workspace-tabs").addClass("workspace-focussed")
|
||||
$("#workspace-tabs").addClass("workspace-focussed");
|
||||
});
|
||||
$("#chart").blur(function() {
|
||||
$("#workspace-tabs").removeClass("workspace-focussed")
|
||||
$("#workspace-tabs").removeClass("workspace-focussed");
|
||||
});
|
||||
|
||||
RED.actions.add("core:copy-selection-to-internal-clipboard",copySelection);
|
||||
@@ -546,6 +549,9 @@ RED.view = (function() {
|
||||
RED.typeSearch.show({
|
||||
x:d3.event.clientX-mainPos.left-node_width/2,
|
||||
y:d3.event.clientY-mainPos.top-node_height/2,
|
||||
cancel: function() {
|
||||
resetMouseVars();
|
||||
},
|
||||
add: function(type) {
|
||||
var result = addNode(type);
|
||||
if (!result) {
|
||||
@@ -683,7 +689,7 @@ RED.view = (function() {
|
||||
var mousePos;
|
||||
if (mouse_mode == RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) {
|
||||
// update drag line
|
||||
if (drag_lines.length === 0) {
|
||||
if (drag_lines.length === 0 && mousedown_port_type !== null) {
|
||||
if (d3.event.shiftKey) {
|
||||
// Get all the wires we need to detach.
|
||||
var links = [];
|
||||
@@ -1141,7 +1147,6 @@ RED.view = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var selectionJSON = activeWorkspace+":"+JSON.stringify(selection,function(key,value) {
|
||||
if (key === 'nodes') {
|
||||
return value.map(function(n) { return n.id })
|
||||
@@ -1348,7 +1353,7 @@ RED.view = (function() {
|
||||
mouseup_node = null;
|
||||
mousedown_link = null;
|
||||
mouse_mode = 0;
|
||||
mousedown_port_type = PORT_TYPE_OUTPUT;
|
||||
mousedown_port_type = null;
|
||||
activeSpliceLink = null;
|
||||
spliceActive = false;
|
||||
d3.select(".link_splice").classed("link_splice",false);
|
||||
@@ -1390,7 +1395,7 @@ RED.view = (function() {
|
||||
|
||||
function portMouseUp(d,portType,portIndex) {
|
||||
var i;
|
||||
if (mouse_mode === RED.state.QUICK_JOINING) {
|
||||
if (mouse_mode === RED.state.QUICK_JOINING && drag_lines.length > 0) {
|
||||
if (drag_lines[0].node===d) {
|
||||
return
|
||||
}
|
||||
@@ -2767,7 +2772,7 @@ RED.view = (function() {
|
||||
if (v === undefined) {
|
||||
return gridSize;
|
||||
} else {
|
||||
gridSize = v;
|
||||
gridSize = Math.max(5,v);
|
||||
updateGrid();
|
||||
}
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ RED.workspaces = (function() {
|
||||
workspaceIndex += 1;
|
||||
} while ($("#workspace-tabs a[title='"+RED._('workspace.defaultName',{number:workspaceIndex})+"']").size() !== 0);
|
||||
|
||||
ws = {type:"tab",id:tabId,label:RED._('workspace.defaultName',{number:workspaceIndex})};
|
||||
ws = {type:"tab",id:tabId,disabled: false,info:"",label:RED._('workspace.defaultName',{number:workspaceIndex})};
|
||||
RED.nodes.addWorkspace(ws);
|
||||
workspace_tabs.addTab(ws);
|
||||
workspace_tabs.activateTab(tabId);
|
||||
@@ -244,10 +244,16 @@ RED.workspaces = (function() {
|
||||
if (tab.disabled) {
|
||||
$("#red-ui-tab-"+(tab.id.replace(".","-"))).addClass('workspace-disabled');
|
||||
}
|
||||
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() == 1);
|
||||
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() <= 1);
|
||||
if (workspace_tabs.count() === 1) {
|
||||
showWorkspace();
|
||||
}
|
||||
},
|
||||
onremove: function(tab) {
|
||||
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() == 1);
|
||||
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() <= 1);
|
||||
if (workspace_tabs.count() === 0) {
|
||||
hideWorkspace();
|
||||
}
|
||||
},
|
||||
onreorder: function(oldOrder, newOrder) {
|
||||
RED.history.push({t:'reorder',order:oldOrder,dirty:RED.nodes.dirty()});
|
||||
@@ -261,6 +267,16 @@ RED.workspaces = (function() {
|
||||
}
|
||||
});
|
||||
}
|
||||
function showWorkspace() {
|
||||
$("#workspace .red-ui-tabs").show()
|
||||
$("#chart").show()
|
||||
$("#workspace-footer").children().show()
|
||||
}
|
||||
function hideWorkspace() {
|
||||
$("#workspace .red-ui-tabs").hide()
|
||||
$("#chart").hide()
|
||||
$("#workspace-footer").children().hide()
|
||||
}
|
||||
|
||||
function init() {
|
||||
createWorkspaceTabs();
|
||||
@@ -280,6 +296,8 @@ RED.workspaces = (function() {
|
||||
RED.actions.add("core:add-flow",addWorkspace);
|
||||
RED.actions.add("core:edit-flow",editWorkspace);
|
||||
RED.actions.add("core:remove-flow",removeWorkspace);
|
||||
|
||||
hideWorkspace();
|
||||
}
|
||||
|
||||
function editWorkspace(id) {
|
||||
@@ -294,6 +312,9 @@ RED.workspaces = (function() {
|
||||
workspace_tabs.removeTab(ws.id);
|
||||
}
|
||||
}
|
||||
if (ws.id === activeWorkspace) {
|
||||
activeWorkspace = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function setWorkspaceOrder(order) {
|
||||
|
@@ -50,7 +50,7 @@ RED.user = (function() {
|
||||
for (;i<data.prompts.length;i++) {
|
||||
var field = data.prompts[i];
|
||||
var row = $("<div/>",{class:"form-row"});
|
||||
$('<label for="node-dialog-login-'+field.id+'">'+field.label+':</label><br/>').appendTo(row);
|
||||
$('<label for="node-dialog-login-'+field.id+'">'+RED._(field.label)+':</label><br/>').appendTo(row);
|
||||
var input = $('<input style="width: 100%" id="node-dialog-login-'+field.id+'" type="'+field.type+'" tabIndex="'+(i+1)+'"/>').appendTo(row);
|
||||
|
||||
if (i<data.prompts.length-1) {
|
||||
@@ -188,6 +188,7 @@ RED.user = (function() {
|
||||
RED.settings.load(function() {
|
||||
RED.notify(RED._("user.loggedInAs",{name:RED.settings.user.username}),"success");
|
||||
updateUserMenu();
|
||||
RED.events.emit("login",RED.settings.user.username);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -230,10 +231,66 @@ RED.user = (function() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var readRE = /^((.+)\.)?read$/
|
||||
var writeRE = /^((.+)\.)?write$/
|
||||
|
||||
function hasPermission(permission) {
|
||||
if (permission === "") {
|
||||
return true;
|
||||
}
|
||||
if (!RED.settings.user) {
|
||||
return true;
|
||||
}
|
||||
return checkPermission(RED.settings.user.permissions||"",permission);
|
||||
}
|
||||
function checkPermission(userScope,permission) {
|
||||
if (permission === "") {
|
||||
return true;
|
||||
}
|
||||
var i;
|
||||
|
||||
if (Array.isArray(permission)) {
|
||||
// Multiple permissions requested - check each one
|
||||
for (i=0;i<permission.length;i++) {
|
||||
if (!checkPermission(userScope,permission[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// All permissions check out
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Array.isArray(userScope)) {
|
||||
if (userScope.length === 0) {
|
||||
return false;
|
||||
}
|
||||
for (i=0;i<userScope.length;i++) {
|
||||
if (checkPermission(userScope[i],permission)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (userScope === "*" || userScope === permission) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userScope === "read" || userScope === "*.read") {
|
||||
return readRE.test(permission);
|
||||
} else if (userScope === "write" || userScope === "*.write") {
|
||||
return writeRE.test(permission);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
init: init,
|
||||
login: login,
|
||||
logout: logout
|
||||
logout: logout,
|
||||
hasPermission: hasPermission
|
||||
}
|
||||
|
||||
})();
|
||||
|
@@ -66,4 +66,4 @@ $editor-button-background-primary-hover: #6E0A1E;
|
||||
$editor-button-color: #999;
|
||||
$editor-button-background: #fff;
|
||||
|
||||
$shade-color: rgba(200,200,200,0.5);
|
||||
$shade-color: rgba(160,160,160,0.5);
|
||||
|
@@ -15,17 +15,15 @@
|
||||
**/
|
||||
|
||||
|
||||
#node-dialog-view-diff {
|
||||
height: 600px;
|
||||
|
||||
.node-dialog-view-diff-panel {
|
||||
.red-ui-editableList-container {
|
||||
border-radius:1px;
|
||||
padding:0;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
#node-dialog-view-diff-diff {
|
||||
.node-dialog-view-diff-diff {
|
||||
position: absolute;
|
||||
top:80px;
|
||||
top:30px;
|
||||
bottom:10px;
|
||||
left:10px;
|
||||
right:10px;
|
||||
@@ -35,28 +33,45 @@
|
||||
border: none;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
}
|
||||
.red-ui-editableList-item-content {
|
||||
padding: 5px;
|
||||
// padding-bottom: 5px;
|
||||
}
|
||||
&.node-dialog-view-diff-panel-merge {
|
||||
.node-dialog-view-diff-diff {
|
||||
top: 80px
|
||||
}
|
||||
.node-dialog-view-diff-headers {
|
||||
top: 55px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#node-dialog-view-diff-headers {
|
||||
|
||||
.node-dialog-view-diff-headers {
|
||||
position: absolute;
|
||||
left:17px;
|
||||
right:32px;
|
||||
top: 55px;
|
||||
left:237px;
|
||||
right:18px;
|
||||
top: 5px;
|
||||
height: 25px;
|
||||
.node-diff-node-entry-cell:not(:first-child) {
|
||||
div {
|
||||
height: 25px;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
padding-top: 2px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
width: 50%;
|
||||
background: #f9f9f9;
|
||||
text-align: center;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
border-color:$secondary-border-color;
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
}
|
||||
.node-diff-node-entry-cell:last-child {
|
||||
div:last-child {
|
||||
border-right: 1px solid $secondary-border-color;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,10 +121,10 @@
|
||||
font-size: 0.9em;
|
||||
|
||||
&:first-child {
|
||||
border-top: 1px solid #eee;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid $secondary-border-color;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
@@ -132,14 +147,21 @@
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
table-layout:fixed;
|
||||
|
||||
// Fix for table-layout: fixed on safari:
|
||||
max-width: none;
|
||||
width: auto;
|
||||
min-width: 100%;
|
||||
width: calc(100% - 20px);
|
||||
margin-left: 20px;
|
||||
}
|
||||
col:first-child {
|
||||
width: 180px;
|
||||
}
|
||||
col:not(:first-child) {
|
||||
width: 100%;
|
||||
}
|
||||
td, th {
|
||||
border: 1px solid $secondary-border-color;
|
||||
border-top: 1px solid #f3f3f3;
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
&:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
padding: 0 0 0 3px;
|
||||
text-align: left;
|
||||
overflow-x: auto;
|
||||
@@ -150,13 +172,12 @@
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
}
|
||||
&:hover {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
}
|
||||
td:first-child {
|
||||
width: 140px;
|
||||
}
|
||||
td:not(:first-child) {
|
||||
width: calc( 100% - 140px);
|
||||
}
|
||||
|
||||
td {
|
||||
.node-diff-status {
|
||||
margin-left: 0;
|
||||
@@ -179,8 +200,8 @@
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
td:not(:first-child) {
|
||||
width: calc( (100% - 140px) / 2);
|
||||
col:not(:first-child) {
|
||||
width:50%;
|
||||
}
|
||||
|
||||
.node-diff-node-entry {
|
||||
@@ -210,6 +231,9 @@
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
// background: #f6f6f6;
|
||||
&:hover {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
}
|
||||
.node-diff-tab-title-meta {
|
||||
vertical-align: middle;
|
||||
@@ -218,6 +242,9 @@
|
||||
}
|
||||
.node-diff-node-entry-header {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
}
|
||||
.node-diff-node-entry-node {
|
||||
vertical-align: middle;
|
||||
@@ -247,6 +274,9 @@
|
||||
}
|
||||
.node-diff-tab-title {
|
||||
cursor: default;
|
||||
&:hover {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.node-diff-node-deleted {
|
||||
@@ -301,7 +331,7 @@
|
||||
}
|
||||
}
|
||||
.node-diff-node-entry-properties {
|
||||
margin: 5px ;
|
||||
margin: 0;
|
||||
color: #666;
|
||||
}
|
||||
.node-diff-status {
|
||||
@@ -313,6 +343,10 @@
|
||||
margin-bottom: 6px;
|
||||
text-align: center;
|
||||
}
|
||||
.node-diff-element {
|
||||
display: inline-block;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.node-diff-node-description {
|
||||
color: $form-text-color;
|
||||
@@ -337,6 +371,7 @@
|
||||
.node-diff-added { color: #009900}
|
||||
.node-diff-deleted { color: #f80000}
|
||||
.node-diff-changed { color: #f89406}
|
||||
.node-diff-unchanged { color: #bbb}
|
||||
.node-diff-conflicted { color: purple}
|
||||
|
||||
|
||||
@@ -346,7 +381,7 @@
|
||||
box-sizing: border-box;
|
||||
width: calc( (100% - 20px) / 2);
|
||||
height: 32px;
|
||||
border-left: 1px solid #eee;
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
padding-top: 2px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -480,37 +515,169 @@
|
||||
}
|
||||
|
||||
|
||||
#node-dialog-confirm-deploy {
|
||||
.node-dialog-confirm-row {
|
||||
text-align: left; padding-top: 10px;
|
||||
ul.node-dialog-configm-deploy-list {
|
||||
font-size: 0.9em;
|
||||
width: 400px;
|
||||
margin: 10px auto;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.node-dialog-confirm-conflict-row {
|
||||
img {
|
||||
vertical-align:middle;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
ul {
|
||||
font-size: 0.9em;
|
||||
width: 400px;
|
||||
margin: 10px auto;
|
||||
text-align: left;
|
||||
i {
|
||||
vertical-align:middle;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
width: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.node-dialog-confirm-conflict-row {
|
||||
img {
|
||||
vertical-align:middle;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
i {
|
||||
vertical-align:middle;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
width: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
div {
|
||||
vertical-align: middle;
|
||||
width: calc(100% - 60px);
|
||||
display:inline-block;
|
||||
}
|
||||
div {
|
||||
vertical-align: middle;
|
||||
width: calc(100% - 60px);
|
||||
display:inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
#node-diff-toolbar-resolved-conflicts .node-diff-status {
|
||||
margin:0;
|
||||
}
|
||||
.node-diff-text-diff-button {
|
||||
float: right;
|
||||
margin: 2px 3px;
|
||||
line-height: 14px;
|
||||
height: 16px;
|
||||
|
||||
}
|
||||
.node-text-diff {
|
||||
height: 100%;
|
||||
overflow-y:auto;
|
||||
table {
|
||||
margin: 10px;
|
||||
border: 1px solid $secondary-border-color;
|
||||
border-radius: 3px;
|
||||
table-layout: fixed;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
td {
|
||||
vertical-align: top;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
td.lineno {
|
||||
font-family: monospace;
|
||||
text-align: right;
|
||||
color: #aaa;
|
||||
background: #f6f6f6;
|
||||
padding: 1px 5px;
|
||||
}
|
||||
td.lineno:nth-child(3) {
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
}
|
||||
td.linetext {
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
padding: 1px 5px;
|
||||
span.prefix {
|
||||
width: 30px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
td.blank {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
td.added {
|
||||
background: #eefaee;
|
||||
}
|
||||
td.removed {
|
||||
background: #fadddd;
|
||||
}
|
||||
tr.mergeHeader td {
|
||||
color: #800080;
|
||||
background: #e5f9ff;
|
||||
height: 26px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
tr.mergeHeader-separator td {
|
||||
color: #800080;
|
||||
background: darken(#e5f9ff, 10%);
|
||||
height: 0px;
|
||||
}
|
||||
tr.mergeHeader-ours td {
|
||||
border-top: 2px solid darken(#e5f9ff, 10%);
|
||||
}
|
||||
tr.mergeHeader-theirs td {
|
||||
border-bottom: 2px solid darken(#e5f9ff, 10%);
|
||||
}
|
||||
td.unchanged {
|
||||
color: #999;
|
||||
}
|
||||
tr.unchanged {
|
||||
background: #fefefe;
|
||||
}
|
||||
tr.start-block {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
tr.end-block {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
tr.node-text-diff-file-header td {
|
||||
.filename {
|
||||
font-family: monospace;
|
||||
}
|
||||
background: #f3f3f3;
|
||||
padding: 5px 10px 5px 0;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
i.node-diff-chevron {
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
tr.node-text-diff-file-header.collapsed {
|
||||
td i.node-diff-chevron {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
tr.node-text-diff-commit-header td {
|
||||
background: #f3f3f3;
|
||||
padding: 5px 10px;
|
||||
color: #333;
|
||||
h3 {
|
||||
font-size: 1.4em;
|
||||
margin: 0;
|
||||
}
|
||||
.commit-summary {
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
padding-top: 5px;
|
||||
color: #999;
|
||||
}
|
||||
.commit-body {
|
||||
margin-bottom:15px;
|
||||
white-space: pre;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
tr.node-text-diff-header td {
|
||||
font-family: monospace;
|
||||
padding: 5px 10px;
|
||||
text-align: left;
|
||||
color: #666;
|
||||
background: #ffd;
|
||||
height: 30px;
|
||||
vertical-align: middle;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
tr.node-text-diff-expand td {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #ffc;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -132,6 +132,11 @@
|
||||
cursor: col-resize;
|
||||
border-left: 1px solid $primary-border-color;
|
||||
box-shadow: -1px 0 6px rgba(0,0,0,0.1);
|
||||
|
||||
&.editor-tray-resize-maximised {
|
||||
background: $background-color;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
.editor-tray-resize-button {
|
||||
@include workspace-button;
|
||||
@@ -153,7 +158,10 @@
|
||||
top: -1px;
|
||||
bottom: -1px;
|
||||
}
|
||||
|
||||
#full-shade {
|
||||
@include shade;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
.dialog-form,#dialog-form, #node-config-dialog-edit-form {
|
||||
height: 100%;
|
||||
@@ -191,12 +199,16 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.form-warning {
|
||||
border-color: #d6615f;
|
||||
}
|
||||
|
||||
.node-text-editor {
|
||||
border:1px solid #ccc;
|
||||
border-radius:5px;
|
||||
overflow: hidden;
|
||||
font-size: 14px !important;
|
||||
font-family: monospace !important;
|
||||
font-family: Menlo, Consolas, 'DejaVu Sans Mono', Courier, monospace !important;
|
||||
}
|
||||
|
||||
.editor-button {
|
||||
@@ -204,8 +216,10 @@
|
||||
height: 34px;
|
||||
line-height: 32px;
|
||||
font-size: 13px;
|
||||
border-radius: 4px;
|
||||
border-radius: 2px;
|
||||
padding: 0 10px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
&.toggle {
|
||||
@include workspace-button-toggle;
|
||||
}
|
||||
@@ -214,6 +228,7 @@
|
||||
|
||||
.editor-button-small {
|
||||
height: 20px;
|
||||
min-width: 20px;
|
||||
line-height: 18px;
|
||||
font-size: 10px;
|
||||
border-radius: 2px;
|
||||
@@ -315,6 +330,13 @@
|
||||
input {
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
#node-settings-icon-module {
|
||||
width: calc(55% - 50px);
|
||||
}
|
||||
#node-settings-icon-file {
|
||||
width: calc(45% - 55px);
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
.node-label-form-none {
|
||||
span {
|
||||
|
@@ -501,6 +501,11 @@ textarea.span1,
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
label.disabled {
|
||||
color: #bbb !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
input[disabled],
|
||||
select[disabled],
|
||||
textarea[disabled],
|
||||
|
@@ -79,6 +79,7 @@
|
||||
font-size: 14px;
|
||||
padding: 6px 14px;
|
||||
margin-right: 8px;
|
||||
border-radius: 2px;
|
||||
color: $editor-button-color;
|
||||
background: $editor-button-background;
|
||||
|
||||
@@ -142,3 +143,10 @@
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ui-widget-overlay {
|
||||
@include shade;
|
||||
z-index: 100;
|
||||
opacity: 1;
|
||||
}
|
||||
|
@@ -48,29 +48,30 @@
|
||||
text-decoration: none;
|
||||
cursor:pointer;
|
||||
|
||||
&.disabled {
|
||||
&.disabled, &:disabled {
|
||||
cursor: default;
|
||||
color: $workspace-button-color-disabled !important;
|
||||
}
|
||||
&:hover, &:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
&:not(.disabled):hover {
|
||||
&:not(.disabled):not(:disabled):hover, {
|
||||
color: $workspace-button-color-hover !important;
|
||||
background: $workspace-button-background-hover;
|
||||
}
|
||||
&:not(.disabled):focus {
|
||||
&:not(.disabled):not(:disabled):focus {
|
||||
color: $workspace-button-color-focus !important;
|
||||
}
|
||||
&:not(.disabled):active {
|
||||
&:not(.disabled):not(:disabled):active {
|
||||
color: $workspace-button-color-active !important;
|
||||
background: $workspace-button-background-active;
|
||||
text-decoration: none;
|
||||
}
|
||||
&.selected:not(.disabled) {
|
||||
color: $workspace-button-color-selected !important;
|
||||
background: $workspace-button-background-active;
|
||||
}
|
||||
// &.selected:not(.disabled):not(:disabled) {
|
||||
// color: $workspace-button-color-selected !important;
|
||||
// background: $workspace-button-background-active;
|
||||
// background: #9f9;
|
||||
// }
|
||||
.button-group &:not(:first-child) {
|
||||
border-left: none;
|
||||
border-top-left-radius: 0;
|
||||
@@ -94,9 +95,30 @@
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.button-row &:not(:first-child) {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 1px solid $workspace-button-color-focus-outline;
|
||||
}
|
||||
|
||||
&.primary {
|
||||
border-color: $editor-button-background-primary;
|
||||
color: $editor-button-color-primary !important;
|
||||
background: $editor-button-background-primary;
|
||||
&.disabled, &.ui-state-disabled {
|
||||
background: none;
|
||||
color: $editor-button-color !important;
|
||||
border-color: $form-input-border-color;
|
||||
}
|
||||
&:not(.disabled):not(.ui-button-disabled):hover {
|
||||
border-color: $editor-button-background-primary-hover;
|
||||
background: $editor-button-background-primary-hover;
|
||||
color: $editor-button-color-primary !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.button-group-vertical {
|
||||
display: inline-block;
|
||||
@@ -132,21 +154,21 @@
|
||||
color: $editor-button-color !important;
|
||||
background: $editor-button-background;
|
||||
|
||||
&.primary {
|
||||
border-color: $editor-button-background-primary;
|
||||
color: $editor-button-color-primary !important;
|
||||
background: $editor-button-background-primary;
|
||||
&.disabled, &.ui-state-disabled {
|
||||
background: none;
|
||||
color: $editor-button-color !important;
|
||||
border-color: $form-input-border-color;
|
||||
}
|
||||
&:not(.disabled):not(.ui-button-disabled):hover {
|
||||
border-color: $editor-button-background-primary-hover;
|
||||
background: $editor-button-background-primary-hover;
|
||||
color: $editor-button-color-primary !important;
|
||||
}
|
||||
}
|
||||
// &.primary {
|
||||
// border-color: $editor-button-background-primary;
|
||||
// color: $editor-button-color-primary !important;
|
||||
// background: $editor-button-background-primary;
|
||||
// &.disabled, &.ui-state-disabled {
|
||||
// background: none;
|
||||
// color: $editor-button-color !important;
|
||||
// border-color: $form-input-border-color;
|
||||
// }
|
||||
// &:not(.disabled):not(.ui-button-disabled):hover {
|
||||
// border-color: $editor-button-background-primary-hover;
|
||||
// background: $editor-button-background-primary-hover;
|
||||
// color: $editor-button-color-primary !important;
|
||||
// }
|
||||
// }
|
||||
&:not(.disabled):hover {
|
||||
//color: $editor-button-color;
|
||||
}
|
||||
@@ -224,4 +246,8 @@
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: $shade-color;
|
||||
z-index: 5;
|
||||
}
|
||||
.component-shade {
|
||||
@include shade
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
**/
|
||||
|
||||
#notifications {
|
||||
z-index: 10000;
|
||||
z-index: 100;
|
||||
width: 500px;
|
||||
margin-left: -250px;
|
||||
left: 50%;
|
||||
@@ -34,6 +34,10 @@
|
||||
border-left-width: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.notification p:first-child {
|
||||
font-size: 1.1em;
|
||||
font-weight: 400;
|
||||
}
|
||||
.notification a {
|
||||
text-decoration: none;
|
||||
&:hover {
|
||||
|
@@ -76,48 +76,9 @@
|
||||
border-bottom: 1px solid $primary-border-color;
|
||||
text-align: right;
|
||||
}
|
||||
.palette-module-button-group {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
.palette-module-shade {
|
||||
@include shade;
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
#palette-module-install-shade {
|
||||
padding-top: 80px;
|
||||
}
|
||||
.palette-module-shade-status {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.palette-module-meta {
|
||||
color: #666;
|
||||
position: relative;
|
||||
&.disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.fa {
|
||||
width: 15px;
|
||||
text-align: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.palette-module-name {
|
||||
white-space: nowrap;
|
||||
@include enable-selection;
|
||||
}
|
||||
.palette-module-version, .palette-module-updated, .palette-module-link {
|
||||
font-style:italic;
|
||||
font-size: 0.8em;
|
||||
@include enable-selection;
|
||||
}
|
||||
.palette-module-updated {
|
||||
margin-left: 10px;
|
||||
}
|
||||
@@ -224,3 +185,48 @@
|
||||
}
|
||||
|
||||
}
|
||||
.palette-module-meta {
|
||||
color: #666;
|
||||
position: relative;
|
||||
&.disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.fa {
|
||||
width: 15px;
|
||||
text-align: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.palette-module-name {
|
||||
white-space: nowrap;
|
||||
@include enable-selection;
|
||||
}
|
||||
.palette-module-version, .palette-module-updated, .palette-module-link {
|
||||
font-style:italic;
|
||||
font-size: 0.8em;
|
||||
@include enable-selection;
|
||||
}
|
||||
.palette-module-section {
|
||||
padding:0 !important;
|
||||
background: #f9f9f9 !important;
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
|
||||
}
|
||||
.palette-module-button-group {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
.palette-module-shade {
|
||||
@include shade;
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
#palette-module-install-shade {
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
@@ -95,7 +95,7 @@
|
||||
text-overflow: ellipsis;
|
||||
|
||||
}
|
||||
.palette-header i {
|
||||
.palette-header > i {
|
||||
margin: 3px 10px 3px 3px;
|
||||
-webkit-transition: all 0.2s ease-in-out;
|
||||
-moz-transition: all 0.2s ease-in-out;
|
||||
|
875
editor/sass/projects.scss
Normal file
875
editor/sass/projects.scss
Normal file
@@ -0,0 +1,875 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
#projects-dialog {
|
||||
.red-ui-editableList-container {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
}
|
||||
#project-settings-tab-settings {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.sidebar-version-control-shade {
|
||||
background: #f3f3f3;
|
||||
}
|
||||
|
||||
.projects-edit-form form {
|
||||
margin: 0;
|
||||
.form-row {
|
||||
margin-bottom: 15px;
|
||||
label {
|
||||
color: #555;
|
||||
width: 100%;
|
||||
display: block;
|
||||
&.projects-edit-form-inline-label {
|
||||
font-weight: normal;
|
||||
color: inherit;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
input[type=text], input[type=password],textarea {
|
||||
width: 100%;
|
||||
}
|
||||
input[type=checkbox], input[type=radio] {
|
||||
width: auto;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.projects-edit-form-sublabel {
|
||||
color: #999;
|
||||
text-align: right;
|
||||
margin-bottom: -15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.project-settings-tab-pane {
|
||||
& * .projects-edit-form-sublabel {
|
||||
margin-right: 50px;
|
||||
margin-top: -10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
.projects-dialog-spinner {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
bottom: 1px;
|
||||
left: 1px;
|
||||
right: 1px;
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
background: white;
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
margin-right: -0.25em;
|
||||
}
|
||||
img {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 80px;
|
||||
}
|
||||
&.projects-dialog-spinner-sidebar {
|
||||
background: white;
|
||||
padding:0;
|
||||
img {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
&.projects-version-control-spinner-sidebar {
|
||||
background: white;
|
||||
padding:0;
|
||||
img {
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&.projects-dialog-spinner-contain {
|
||||
padding: 0;
|
||||
img {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
max-height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.projects-dialog-screen-start {
|
||||
.projects-dialog-screen-start-hero {
|
||||
// background: url(https://nodered.org/images/title-wave.png) no-repeat 0% 100% #8f0000;
|
||||
// background-size: contain;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
padding: 10px;
|
||||
min-height: 60px;
|
||||
color: #555;
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #f0f0f0;
|
||||
font-size: 2em;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
.projects-dialog-screen-start-body {
|
||||
min-height: 400px;
|
||||
line-height: 1.6em;
|
||||
p {
|
||||
font-size: 1.1em;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
p:first-child {
|
||||
font-weight: 500;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
button.editor-button {
|
||||
width: calc(50% - 40px);
|
||||
margin: 20px;
|
||||
height: 175px;
|
||||
line-height: 2em;
|
||||
font-size: 1.5em !important;
|
||||
i {
|
||||
color: #ccc;
|
||||
}
|
||||
&:hover i {
|
||||
color: #aaa;
|
||||
}
|
||||
}
|
||||
.button-group {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.projects-dialog-screen-create {
|
||||
min-height: 500px;
|
||||
button.projects-dialog-screen-create-type {
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
|
||||
}
|
||||
.button-group {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-screen-secret {
|
||||
min-height: auto;
|
||||
}
|
||||
.projects-dialog-project-list-container {
|
||||
border: 1px solid $secondary-border-color;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.projects-dialog-project-list-inner-container {
|
||||
height: 300px;
|
||||
overflow-y: scroll;
|
||||
position:relative;
|
||||
.red-ui-editableList-border {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
.projects-dialog-project-list {
|
||||
li {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
.projects-dialog-project-list-entry {
|
||||
padding: 12px 0;
|
||||
border-left: 3px solid #fff;
|
||||
border-right: 3px solid #fff;
|
||||
&.projects-list-entry-current {
|
||||
&:not(.selectable) {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
i {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
&.selectable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f3f3f3;
|
||||
// border-left-color: #aaa;
|
||||
// border-right-color: #aaa;
|
||||
}
|
||||
}
|
||||
.projects-dialog-project-list-entry-icon {
|
||||
i {
|
||||
color: #ccc;
|
||||
font-size: 2em;
|
||||
|
||||
}
|
||||
}
|
||||
&.selected {
|
||||
background: #efefef;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.projects-dialog-project-list-entry-icon {
|
||||
margin: 0 10px 0 5px;
|
||||
}
|
||||
.projects-dialog-project-list-entry-name {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.projects-dialog-project-list-entry-current {
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
font-size: 0.9em;
|
||||
color: #999;
|
||||
padding-top: 4px;
|
||||
}
|
||||
.projects-dialog-project-list-entry-tools {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 30px;
|
||||
display: none;
|
||||
color: #999;
|
||||
}
|
||||
&:hover {
|
||||
.projects-dialog-project-list-entry-tools {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
.projects-dialog-screen-create-type.editor-button.toggle.selected:not(.disabled):not(:disabled) {
|
||||
background: #fff !important;
|
||||
color: #666 !important;
|
||||
}
|
||||
.projects-dialog-screen-input-status {
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 8px;
|
||||
width: 70px;
|
||||
height: 30px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.sidebar-version-control {
|
||||
height: 100%;
|
||||
}
|
||||
.sidebar-version-control-stack-info {
|
||||
height: 100px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid $secondary-border-color;
|
||||
color: #333;
|
||||
i {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-stack {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow: hidden;
|
||||
|
||||
.palette-category {
|
||||
&:not(.palette-category-expanded) button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#project-settings-tab-deps {
|
||||
.red-ui-editableList-container {
|
||||
padding: 0;
|
||||
}
|
||||
.red-ui-editableList-border {
|
||||
border-radius: 0;
|
||||
}
|
||||
.red-ui-editableList-item-content {
|
||||
padding: 0px 6px;
|
||||
}
|
||||
.palette-module-header {
|
||||
padding: 6px 4px;
|
||||
}
|
||||
.palette-module-button {
|
||||
float: right;
|
||||
}
|
||||
.palette-module-unused {
|
||||
& > * {
|
||||
color: #bbb;
|
||||
}
|
||||
// border: 1px dashed #bbb;
|
||||
}
|
||||
.palette-module-unknown {
|
||||
border: 1px dashed #aaa;
|
||||
background: #fafafa;
|
||||
}
|
||||
.palette-module-not-installed {
|
||||
border: 1px dashed #b07575;
|
||||
background: #fee;
|
||||
i.fa-warning {
|
||||
color: #b07575; //#b72828;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.project-settings-tab-pane {
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
overflow-y: auto;
|
||||
padding: 8px 20px 20px;
|
||||
}
|
||||
.sidebar-version-control {
|
||||
.red-ui-editableList-container {
|
||||
background: #f9f9f9;
|
||||
padding: 0;
|
||||
li {
|
||||
padding:0;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
.red-ui-editableList-border {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-version-control-change-container {
|
||||
position: relative;
|
||||
height: 50%;
|
||||
box-sizing: border-box;
|
||||
transition: height 0.2s ease-in-out;
|
||||
&:first-child {
|
||||
// border-bottom: 1px solid $primary-border-color;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-merging {
|
||||
.sidebar-version-control-change-container {
|
||||
height: 33%;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-slide-box {
|
||||
position:absolute;
|
||||
bottom: 0;
|
||||
left:0;
|
||||
right:0;
|
||||
height:0;
|
||||
transition: height 0.2s ease-in-out;
|
||||
background: #f6f6f6;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
&.sidebar-version-control-slide-box-top {
|
||||
z-index: 4;
|
||||
top: 0px;
|
||||
left: auto;
|
||||
width: 100%;
|
||||
max-width: 280px;
|
||||
border-left: 1px solid $primary-border-color;
|
||||
border-right: 1px solid $primary-border-color;
|
||||
border-bottom: 1px solid $primary-border-color;
|
||||
box-shadow: 1px 1px 4px rgba(0,0,0,0.2);
|
||||
|
||||
color: #666;
|
||||
background: #f6f6f6;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
|
||||
}
|
||||
&.sidebar-version-control-slide-box-bottom {
|
||||
bottom: 0px;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 110px;
|
||||
margin: 10px;
|
||||
width: calc(100% - 20px);
|
||||
box-sizing: border-box;
|
||||
border-radius: 1px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
}
|
||||
.projects-branch-list {
|
||||
position: relative;
|
||||
.red-ui-searchBox-container {
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
border-right: 1px solid $secondary-border-color;
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.red-ui-editableList {
|
||||
border: 1px solid $secondary-border-color;
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
& > .red-ui-editableList-border {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
}
|
||||
.red-ui-editableList-container {
|
||||
padding: 0;
|
||||
li {
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.uneditable-input .projects-branch-list {
|
||||
.red-ui-editableList {
|
||||
border-left: none;
|
||||
border-bottom: none;
|
||||
border-right: none;
|
||||
}
|
||||
.red-ui-searchBox-container {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-slide-box-header {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.sidebar-version-control-slide-box-toolbar {
|
||||
padding: 0 20px;
|
||||
text-align: right;
|
||||
}
|
||||
.sidebar-version-control-branch-list-entry {
|
||||
padding: 5px 8px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
&.selected {
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
border-left: 2px solid #fff;
|
||||
border-right: 2px solid #fff;
|
||||
margin: 0 1px;
|
||||
i { width: 16px; text-align: center}
|
||||
&.input-error {
|
||||
cursor: default;
|
||||
}
|
||||
&:not(.input-error):hover {
|
||||
background: #f3f3f3;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
span.current {
|
||||
float: right;
|
||||
font-size: 0.8em;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-version-control-change-entry {
|
||||
height: 20px;
|
||||
padding: 5px 10px;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
span {
|
||||
margin: 0 6px;
|
||||
}
|
||||
a {
|
||||
color: currentColor;
|
||||
&.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-change-entry-tools {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
display: none;
|
||||
}
|
||||
button {
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.sidebar-version-control-change-entry-tools {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
&.node-info-none {
|
||||
text-align: center;
|
||||
background: #fefefe;
|
||||
white-space: normal;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-version-control-commit-entry {
|
||||
min-height: 20px;
|
||||
padding: 5px 10px;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-commit-more {
|
||||
color: #999;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
font-style: italic;
|
||||
}
|
||||
.sidebar-version-control-commit-sha {
|
||||
float: right;
|
||||
font-family: monospace;
|
||||
color: #c38888;
|
||||
display: inline-block;
|
||||
font-size: 0.85em;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.sidebar-version-control-commit-subject {
|
||||
color: #666;
|
||||
}
|
||||
.sidebar-version-control-commit-refs {
|
||||
min-height: 22px;
|
||||
}
|
||||
.sidebar-version-control-commit-ref {
|
||||
color: #aaa;
|
||||
font-size: 0.7em;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 10px;
|
||||
padding: 2px 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.sidebar-version-control-commit-date {
|
||||
color: #999;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
.sidebar-version-control-commit-user {
|
||||
float: right;
|
||||
color: #999;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
.sidebar-version-control-commit-head {
|
||||
}
|
||||
.sidebar-version-control-change-header {
|
||||
color: #666;
|
||||
background: #f6f6f6;
|
||||
padding: 4px 10px;
|
||||
height: 30px;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
border-bottom: 1px solid $secondary-border-color;
|
||||
i {
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-repo-toolbar {
|
||||
color: #666;
|
||||
background: #f6f6f6;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.sidebar-version-control-repo-count {
|
||||
margin-right: 8px;
|
||||
display: none;
|
||||
}
|
||||
.sidebar-version-control-repo-action {
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
.sidebar-version-control-repo-sub-action {
|
||||
width: calc(50% - 5px);
|
||||
margin-right: 5px;
|
||||
&:not(:first-child) {
|
||||
margin-right: 0;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.project-file-listing-container > .red-ui-editableList > .red-ui-editableList-border {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
|
||||
}
|
||||
.red-ui-editableList-container .projects-dialog-file-list {
|
||||
.red-ui-editableList-border {
|
||||
border: none;
|
||||
}
|
||||
li {
|
||||
padding: 0 !important;
|
||||
border: none;
|
||||
}
|
||||
.red-ui-editableList-container {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.projects-dialog-file-list-entry {
|
||||
padding: 3px 0;
|
||||
border-left: 2px solid #fff;
|
||||
border-right: 2px solid #fff;
|
||||
&.projects-list-entry-current {
|
||||
&:not(.selectable) {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
i {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
&.selectable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f3f3f3;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
}
|
||||
&.unselectable {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
i {
|
||||
color: #999;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
&.selected {
|
||||
background: #efefef;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.projects-dialog-file-list-entry-folder {
|
||||
margin: 0 10px 0 0px;
|
||||
|
||||
.fa-angle-right {
|
||||
color: #333;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
}
|
||||
}
|
||||
.projects-dialog-file-list-entry-file {
|
||||
margin: 0 10px 0 20px;
|
||||
}
|
||||
.projects-dialog-file-list-entry-name {
|
||||
font-size: 1em;
|
||||
}
|
||||
&.expanded .fa-angle-right {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
.projects-dialog-file-list-entry-file-type-git { color: #999 }
|
||||
|
||||
.projects-dialog-remote-list {
|
||||
.red-ui-editableList-container {
|
||||
padding: 0;
|
||||
li {
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-sshkey-list {
|
||||
li {
|
||||
padding: 0 !important;
|
||||
}
|
||||
&.projects-dialog-sshkey-list-small {
|
||||
.projects-dialog-sshkey-list-entry {
|
||||
padding: 6px 0;
|
||||
i {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-name {
|
||||
font-size: 1em;
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-current {
|
||||
margin-right: 10px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.red-ui-editableList-container {
|
||||
.projects-dialog-sshkey-list {
|
||||
li:last-child {
|
||||
border-bottom: 0px none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry {
|
||||
padding: 12px 0;
|
||||
border-left: 3px solid #fff;
|
||||
border-right: 3px solid #fff;
|
||||
&.sshkey-list-entry-current {
|
||||
&:not(.selectable) {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
i {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
&.selectable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f3f3f3;
|
||||
border-left-color: #aaa;
|
||||
border-right-color: #aaa;
|
||||
}
|
||||
}
|
||||
i {
|
||||
color: #ccc;
|
||||
font-size: 2em;
|
||||
|
||||
}
|
||||
&.selected {
|
||||
background: #efefef;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-icon {
|
||||
margin: 0 10px 0 5px;
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-name {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-current {
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
font-size: 0.9em;
|
||||
color: #999;
|
||||
padding-top: 4px;
|
||||
}
|
||||
.projects-dialog-sshkey-list-button-remove {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
div.projects-dialog-ssh-public-key {
|
||||
position: relative;
|
||||
padding: 15px 20px 0;
|
||||
pre {
|
||||
position: relative;
|
||||
word-break: break-all;
|
||||
}
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-ssh-key-list {
|
||||
li {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.projects-dialog-ssh-key-header {
|
||||
padding: 10px 5px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f3f3f3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-list {
|
||||
position: relative;
|
||||
.red-ui-editableList-container {
|
||||
padding: 1px;
|
||||
background: #f6f6f6;
|
||||
li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-list-entry {
|
||||
&.red-ui-search-empty {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
}
|
||||
.entry-icon {
|
||||
text-align: center;
|
||||
min-width: 30px;
|
||||
vertical-align: top;
|
||||
color: #999;
|
||||
}
|
||||
.entry-name {
|
||||
min-width: 250px;
|
||||
}
|
||||
&.current .entry-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
.entry-detail {
|
||||
color: #aaa;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.entry-remote-name {
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
|
||||
.entry-tools {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.projects-dialog-list-dialog {
|
||||
position: relative;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
border: 1px solid $secondary-border-color;
|
||||
.projects-edit-form-sublabel {
|
||||
margin-top: -8px !important;
|
||||
display: block !important;
|
||||
width: auto !important;
|
||||
}
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.projects-dialog-list-dialog-header {
|
||||
font-weight: bold;
|
||||
background: #f3f3f3;
|
||||
margin-top: 0 !important;
|
||||
padding: 5px 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
@@ -48,12 +48,15 @@
|
||||
|
||||
@import "userSettings";
|
||||
|
||||
@import "projects";
|
||||
|
||||
|
||||
@import "ui/common/editableList";
|
||||
@import "ui/common/searchBox";
|
||||
@import "ui/common/typedInput";
|
||||
@import "ui/common/nodeList";
|
||||
@import "ui/common/checkboxSet";
|
||||
@import "ui/common/stack";
|
||||
|
||||
@import "dragdrop";
|
||||
|
||||
|
@@ -87,17 +87,22 @@ table.node-info tr.blank {
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.node-info-none {
|
||||
font-style: italic;
|
||||
color: #aaa;
|
||||
}
|
||||
table.node-info tr:not(.blank) td:first-child{
|
||||
color: #666;
|
||||
color: #444;
|
||||
vertical-align: top;
|
||||
width: 90px;
|
||||
padding: 3px 3px 3px 6px;
|
||||
background:#f9f9f9;
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
table.node-info tr:not(.blank) td:last-child{
|
||||
padding: 3px 3px 3px 6px;
|
||||
color: #666;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
div.node-info {
|
||||
margin: 5px;
|
||||
|
26
editor/sass/ui/common/stack.scss
Normal file
26
editor/sass/ui/common/stack.scss
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
.red-ui-stack {
|
||||
background: white;
|
||||
.palette-category {
|
||||
background: white;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
@@ -38,17 +38,26 @@
|
||||
label {
|
||||
display: inline-block;
|
||||
min-width: 100px;
|
||||
vertical-align: top;
|
||||
margin-top: 5px;
|
||||
input {
|
||||
vertical-align: top;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
input {
|
||||
margin-bottom: 0;
|
||||
input, div.uneditable-input {
|
||||
//margin-bottom: 0;
|
||||
}
|
||||
div.uneditable-input {
|
||||
position: relative;
|
||||
}
|
||||
input[type='number'] {
|
||||
width: 60px;
|
||||
}
|
||||
h4 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#user-settings-tab-view {
|
||||
@@ -57,3 +66,18 @@
|
||||
.user-settings-row {
|
||||
padding: 5px 10px 2px;
|
||||
}
|
||||
.user-settings-section {
|
||||
position: relative;
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
.uneditable-input, input, textarea {
|
||||
width: calc(100% - 150px);
|
||||
}
|
||||
textarea {
|
||||
resize: none;
|
||||
height: 10em;
|
||||
}
|
||||
}
|
||||
|
@@ -77,35 +77,11 @@
|
||||
<div id="sidebar-separator"></div>
|
||||
|
||||
</div>
|
||||
<div id="full-shade" class="hide"></div>
|
||||
|
||||
<div id="notifications"></div>
|
||||
<div id="dropTarget"><div data-i18n="[append]workspace.dropFlowHere"><br/><i class="fa fa-download"></i></div></div>
|
||||
|
||||
<div id="node-dialog-confirm-deploy" class="hide">
|
||||
<form class="form-horizontal">
|
||||
<div id="node-dialog-confirm-deploy-config" class="node-dialog-confirm-row" data-i18n="[prepend]deploy.confirm.improperlyConfigured;[append]deploy.confirm.confirm">
|
||||
<ul id="node-dialog-confirm-deploy-invalid-list"></ul>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-unknown" class="node-dialog-confirm-row" data-i18n="[prepend]deploy.confirm.unknown;[append]deploy.confirm.confirm">
|
||||
<ul id="node-dialog-confirm-deploy-unknown-list"></ul>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-conflict" class="node-dialog-confirm-row">
|
||||
<div style="margin-left: 40px; margin-bottom: 10px;">
|
||||
<span data-i18n="deploy.confirm.conflict"></span>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-conflict-checking" class="node-dialog-confirm-conflict-row">
|
||||
<img src="red/images/spin.svg"/><div data-i18n="deploy.confirm.conflictChecking"></div>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-conflict-auto-merge" class="node-dialog-confirm-conflict-row">
|
||||
<i style="color: #3a3;" class="fa fa-check"></i><div data-i18n="deploy.confirm.conflictAutoMerge"></div>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-conflict-manual-merge" class="node-dialog-confirm-conflict-row">
|
||||
<i style="color: #999;" class="fa fa-exclamation"></i><div data-i18n="deploy.confirm.conflictManualMerge"></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="node-dialog-library-save-confirm" class="hide">
|
||||
<form class="form-horizontal">
|
||||
<div style="text-align: center; padding-top: 30px;" id="node-dialog-library-save-content">
|
||||
@@ -209,6 +185,14 @@
|
||||
<div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div>
|
||||
</div>
|
||||
</script>
|
||||
<script type="text/x-red" data-template-name="_markdown">
|
||||
<div class="form-row" id="node-input-markdown-title" style="margin-bottom: 3px; text-align: right;">
|
||||
|
||||
</div>
|
||||
<div class="form-row node-text-editor-row">
|
||||
<div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-markdown"></div>
|
||||
</div>
|
||||
</script>
|
||||
<script type="text/x-red" data-template-name="_buffer">
|
||||
<div id="node-input-buffer-panels">
|
||||
<div id="node-input-buffer-panel-str" class="red-ui-panel">
|
||||
@@ -226,7 +210,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script src="vendor/vendor.js"></script>
|
||||
<script src="vendor/jsonata/jsonata.min.js"></script>
|
||||
<script src="vendor/ace/ace.js"></script>
|
||||
|
2
editor/vendor/ace/ace.js
vendored
Executable file → Normal file
2
editor/vendor/ace/ace.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/ext-language_tools.js
vendored
Executable file → Normal file
2
editor/vendor/ace/ext-language_tools.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/ext-searchbox.js
vendored
Executable file → Normal file
2
editor/vendor/ace/ext-searchbox.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-css.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-css.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-handlebars.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-handlebars.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-html.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-html.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-javascript.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-javascript.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-json.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-json.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-markdown.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-markdown.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
0
editor/vendor/ace/mode-properties.js
vendored
Executable file → Normal file
0
editor/vendor/ace/mode-properties.js
vendored
Executable file → Normal file
1
editor/vendor/ace/mode-python.js
vendored
Normal file
1
editor/vendor/ace/mode-python.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ace.define("ace/mode/python_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield|async|await",t="True|False|None|NotImplemented|Ellipsis|__debug__",n="abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern",r=this.createKeywordMapper({"invalid.deprecated":"debugger","support.function":n,"constant.language":t,keyword:e},"identifier"),i="(?:r|u|ur|R|U|UR|Ur|uR)?",s="(?:(?:[1-9]\\d*)|(?:0))",o="(?:0[oO]?[0-7]+)",u="(?:0[xX][\\dA-Fa-f]+)",a="(?:0[bB][01]+)",f="(?:"+s+"|"+o+"|"+u+"|"+a+")",l="(?:[eE][+-]?\\d+)",c="(?:\\.\\d+)",h="(?:\\d+)",p="(?:(?:"+h+"?"+c+")|(?:"+h+"\\.))",d="(?:(?:"+p+"|"+h+")"+l+")",v="(?:"+d+"|"+p+")",m="\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:i+'"{3}',next:"qqstring3"},{token:"string",regex:i+'"(?=.)',next:"qqstring"},{token:"string",regex:i+"'{3}",next:"qstring3"},{token:"string",regex:i+"'(?=.)",next:"qstring"},{token:"constant.numeric",regex:"(?:"+v+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:v},{token:"constant.numeric",regex:f+"[lL]\\b"},{token:"constant.numeric",regex:f+"\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qqstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],qstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}]}};r.inherits(s,i),t.PythonHighlightRules=s}),ace.define("ace/mode/folding/pythonic",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e){this.foldingStartMarker=new RegExp("([\\[{])(?:\\s*)$|("+e+")(?:\\s*)(?:#.*)?$")};r.inherits(s,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i=r.match(this.foldingStartMarker);if(i)return i[1]?this.openingBracketBlock(e,i[1],n,i.index):i[2]?this.indentationBlock(e,n,i.index+i[2].length):this.indentationBlock(e,n)}}.call(s.prototype)}),ace.define("ace/mode/python",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/python_highlight_rules","ace/mode/folding/pythonic","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./python_highlight_rules").PythonHighlightRules,o=e("./folding/pythonic").FoldMode,u=e("../range").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o("\\:"),this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new u(n,r.length-i.length,n,r.length))},this.$id="ace/mode/python"}.call(a.prototype),t.Mode=a})
|
0
editor/vendor/ace/mode-sql.js
vendored
Executable file → Normal file
0
editor/vendor/ace/mode-sql.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-swift.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-swift.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-yaml.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-yaml.js
vendored
Executable file → Normal file
@@ -1 +1 @@
|
||||
ace.define("ace/mode/yaml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"list.markup",regex:/^(?:-{3}|\.{3})\s*(?=#|$)/},{token:"list.markup",regex:/^\s*[\-?](?:$|\s)/},{token:"constant",regex:"!![\\w//]+"},{token:"constant.language",regex:"[&\\*][a-zA-Z0-9-_]+"},{token:["meta.tag","keyword"],regex:/^(\s*\w.*?)(:(?:\s+|$))/},{token:["meta.tag","keyword"],regex:/(\w+?)(\s*:(?:\s+|$))/},{token:"keyword.operator",regex:"<<\\w*:\\w*"},{token:"keyword.operator",regex:"-\\s*(?=[{])"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:/[|>][-+\d\s]*$/,onMatch:function(e,t,n,r){var i=/^\s*/.exec(r)[0];return n.length<1?n.push(this.next):n[0]="mlString",n.length<2?n.push(i.length):n[1]=i.length,this.token},next:"mlString"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:/(\b|[+\-\.])[\d_]+(?:(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)/},{token:"constant.numeric",regex:/[+\-]?\.inf\b|NaN\b|0x[\dA-Fa-f_]+|0b[10_]+/},{token:"constant.language.boolean",regex:"\\b(?:true|false|TRUE|FALSE|True|False|yes|no)\\b"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"}],mlString:[{token:"indent",regex:/^\s*$/},{token:"indent",regex:/^\s*/,onMatch:function(e,t,n){var r=n[1];return r>=e.length?(this.next="start",n.splice(0)):this.next="mlString",this.token},next:"mlString"},{token:"string",regex:".+"}]},this.normalizeRules()};r.inherits(s,i),t.YamlHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/yaml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/yaml_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./yaml_highlight_rules").YamlHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./folding/coffee").FoldMode,a=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new u,this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);if(e=="start"){var i=t.match(/^.*[\{\(\[]\s*$/);i&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/yaml"}.call(a.prototype),t.Mode=a})
|
||||
ace.define("ace/mode/yaml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"list.markup",regex:/^(?:-{3}|\.{3})\s*(?=#|$)/},{token:"list.markup",regex:/^\s*[\-?](?:$|\s)/},{token:"constant",regex:"!![\\w//]+"},{token:"constant.language",regex:"[&\\*][a-zA-Z0-9-_]+"},{token:["meta.tag","keyword"],regex:/^(\s*\w.*?)(:(?=\s|$))/},{token:["meta.tag","keyword"],regex:/(\w+?)(\s*:(?=\s|$))/},{token:"keyword.operator",regex:"<<\\w*:\\w*"},{token:"keyword.operator",regex:"-\\s*(?=[{])"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:/[|>][-+\d\s]*$/,onMatch:function(e,t,n,r){var i=/^\s*/.exec(r)[0];return n.length<1?n.push(this.next):n[0]="mlString",n.length<2?n.push(i.length):n[1]=i.length,this.token},next:"mlString"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:/(\b|[+\-\.])[\d_]+(?:(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)(?=[^\d-\w]|$)/},{token:"constant.numeric",regex:/[+\-]?\.inf\b|NaN\b|0x[\dA-Fa-f_]+|0b[10_]+/},{token:"constant.language.boolean",regex:"\\b(?:true|false|TRUE|FALSE|True|False|yes|no)\\b"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:/[^\s,:\[\]\{\}]+/}],mlString:[{token:"indent",regex:/^\s*$/},{token:"indent",regex:/^\s*/,onMatch:function(e,t,n){var r=n[1];return r>=e.length?(this.next="start",n.splice(0)):this.next="mlString",this.token},next:"mlString"},{token:"string",regex:".+"}]},this.normalizeRules()};r.inherits(s,i),t.YamlHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/yaml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/yaml_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./yaml_highlight_rules").YamlHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./folding/coffee").FoldMode,a=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new u,this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart=["#","//"],this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);if(e=="start"){var i=t.match(/^.*[\{\(\[]\s*$/);i&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/yaml"}.call(a.prototype),t.Mode=a})
|
0
editor/vendor/ace/snippets/css.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/css.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/handlebars.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/handlebars.js
vendored
Executable file → Normal file
836
editor/vendor/ace/snippets/html.js
vendored
Executable file → Normal file
836
editor/vendor/ace/snippets/html.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
0
editor/vendor/ace/snippets/javascript.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/javascript.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/markdown.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/markdown.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/properties.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/properties.js
vendored
Executable file → Normal file
1
editor/vendor/ace/snippets/python.js
vendored
Normal file
1
editor/vendor/ace/snippets/python.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ace.define("ace/snippets/python",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet #!\n #!/usr/bin/env python\nsnippet imp\n import ${1:module}\nsnippet from\n from ${1:package} import ${2:module}\n# Module Docstring\nsnippet docs\n \'\'\'\n File: ${1:FILENAME:file_name}\n Author: ${2:author}\n Description: ${3}\n \'\'\'\nsnippet wh\n while ${1:condition}:\n ${2:# TODO: write code...}\n# dowh - does the same as do...while in other languages\nsnippet dowh\n while True:\n ${1:# TODO: write code...}\n if ${2:condition}:\n break\nsnippet with\n with ${1:expr} as ${2:var}:\n ${3:# TODO: write code...}\n# New Class\nsnippet cl\n class ${1:ClassName}(${2:object}):\n """${3:docstring for $1}"""\n def __init__(self, ${4:arg}):\n ${5:super($1, self).__init__()}\n self.$4 = $4\n ${6}\n# New Function\nsnippet def\n def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n """${3:docstring for $1}"""\n ${4:# TODO: write code...}\nsnippet deff\n def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n ${3:# TODO: write code...}\n# New Method\nsnippet defs\n def ${1:mname}(self, ${2:arg}):\n ${3:# TODO: write code...}\n# New Property\nsnippet property\n def ${1:foo}():\n doc = "${2:The $1 property.}"\n def fget(self):\n ${3:return self._$1}\n def fset(self, value):\n ${4:self._$1 = value}\n# Ifs\nsnippet if\n if ${1:condition}:\n ${2:# TODO: write code...}\nsnippet el\n else:\n ${1:# TODO: write code...}\nsnippet ei\n elif ${1:condition}:\n ${2:# TODO: write code...}\n# For\nsnippet for\n for ${1:item} in ${2:items}:\n ${3:# TODO: write code...}\n# Encodes\nsnippet cutf8\n # -*- coding: utf-8 -*-\nsnippet clatin1\n # -*- coding: latin-1 -*-\nsnippet cascii\n # -*- coding: ascii -*-\n# Lambda\nsnippet ld\n ${1:var} = lambda ${2:vars} : ${3:action}\nsnippet .\n self.\nsnippet try Try/Except\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\nsnippet try Try/Except/Else\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n else:\n ${5:# TODO: write code...}\nsnippet try Try/Except/Finally\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n finally:\n ${5:# TODO: write code...}\nsnippet try Try/Except/Else/Finally\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n else:\n ${5:# TODO: write code...}\n finally:\n ${6:# TODO: write code...}\n# if __name__ == \'__main__\':\nsnippet ifmain\n if __name__ == \'__main__\':\n ${1:main()}\n# __magic__\nsnippet _\n __${1:init}__${2}\n# python debugger (pdb)\nsnippet pdb\n import pdb; pdb.set_trace()\n# ipython debugger (ipdb)\nsnippet ipdb\n import ipdb; ipdb.set_trace()\n# ipython debugger (pdbbb)\nsnippet pdbbb\n import pdbpp; pdbpp.set_trace()\nsnippet pprint\n import pprint; pprint.pprint(${1})${2}\nsnippet "\n """\n ${1:doc}\n """\n# test function/method\nsnippet test\n def test_${1:description}(${2:self}):\n ${3:# TODO: write code...}\n# test case\nsnippet testcase\n class ${1:ExampleCase}(unittest.TestCase):\n \n def test_${2:description}(self):\n ${3:# TODO: write code...}\nsnippet fut\n from __future__ import ${1}\n#getopt\nsnippet getopt\n try:\n # Short option syntax: "hv:"\n # Long option syntax: "help" or "verbose="\n opts, args = getopt.getopt(sys.argv[1:], "${1:short_options}", [${2:long_options}])\n \n except getopt.GetoptError, err:\n # Print debug info\n print str(err)\n ${3:error_action}\n\n for option, argument in opts:\n if option in ("-h", "--help"):\n ${4}\n elif option in ("-v", "--verbose"):\n verbose = argument\n',t.scope="python"})
|
0
editor/vendor/ace/snippets/text.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/text.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/yaml.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/yaml.js
vendored
Executable file → Normal file
0
editor/vendor/ace/theme-chrome.js
vendored
Executable file → Normal file
0
editor/vendor/ace/theme-chrome.js
vendored
Executable file → Normal file
0
editor/vendor/ace/theme-tomorrow.js
vendored
Executable file → Normal file
0
editor/vendor/ace/theme-tomorrow.js
vendored
Executable file → Normal file
2
editor/vendor/ace/worker-html.js
vendored
Executable file → Normal file
2
editor/vendor/ace/worker-html.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/worker-javascript.js
vendored
Executable file → Normal file
2
editor/vendor/ace/worker-javascript.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/worker-json.js
vendored
Executable file → Normal file
2
editor/vendor/ace/worker-json.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
9
editor/vendor/jsonata/formatter.js
vendored
9
editor/vendor/jsonata/formatter.js
vendored
@@ -120,6 +120,11 @@
|
||||
'$exists':{ args:[ 'arg' ]},
|
||||
'$filter':{ args:[ 'array', 'function' ]},
|
||||
'$floor':{ args:[ 'number' ]},
|
||||
'$flowContext': {args:['string']},
|
||||
'$formatBase': {args:['number','radix']},
|
||||
'$formatNumber': {args:['number', 'picture', 'options']},
|
||||
'$fromMillis': {args:['number']},
|
||||
'$globalContext': {args:['string']},
|
||||
'$join':{ args:[ 'array', 'separator' ]},
|
||||
'$keys':{ args:[ 'object' ]},
|
||||
'$length':{ args:[ 'str' ]},
|
||||
@@ -128,10 +133,13 @@
|
||||
'$map':{ args:[ 'array', 'function' ]},
|
||||
'$match':{ args:[ 'str', 'pattern', 'limit' ]},
|
||||
'$max':{ args:[ 'array' ]},
|
||||
'$merge':{ args:[ 'array' ]},
|
||||
'$millis':{ args:[ ]},
|
||||
'$min':{ args:[ 'array' ]},
|
||||
'$not':{ args:[ 'arg' ]},
|
||||
'$now':{ args:[ ]},
|
||||
'$number':{ args:[ 'arg' ]},
|
||||
'$pad': {args:['str', 'width','char']},
|
||||
'$power':{ args:[ 'base', 'exponent' ]},
|
||||
'$random':{ args:[ ]},
|
||||
'$reduce':{ args:[ 'array', 'function' , 'init' ]},
|
||||
@@ -149,6 +157,7 @@
|
||||
'$substringAfter':{ args:[ 'str', 'chars' ]},
|
||||
'$substringBefore':{ args:[ 'str', 'chars' ]},
|
||||
'$sum':{ args:[ 'array' ]},
|
||||
'$toMillis':{args:['timestamp']}, // <-------------
|
||||
'$trim':{ args:[ 'str' ]},
|
||||
'$uppercase':{ args:[ 'str' ]},
|
||||
'$zip':{ args:[ 'array1' ]}
|
||||
|
@@ -1,20 +1,9 @@
|
||||
<!--
|
||||
Copyright JS Foundation and other contributors, http://js.foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="sentiment">
|
||||
<div class="form-row">
|
||||
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
||||
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<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">
|
||||
@@ -22,7 +11,7 @@
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="sentiment">
|
||||
<p>Analyses the <code>payload</code> and adds a <code>sentiment</code> object.</p>
|
||||
<p>Analyses the chosen property, default <code>payload</code>, and adds a <code>sentiment</code> object.</p>
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>sentiment <span class="property-type">object</span></dt>
|
||||
@@ -47,6 +36,7 @@
|
||||
color:"#E6E0F8",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
property: {value:"payload",required:true}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
@@ -56,6 +46,12 @@
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
if (this.property === undefined) {
|
||||
$("#node-input-property").val("payload");
|
||||
}
|
||||
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@@ -1,18 +1,3 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
@@ -20,16 +5,18 @@ module.exports = function(RED) {
|
||||
|
||||
function SentimentNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.property = n.property||"payload";
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
if (msg.hasOwnProperty("payload")) {
|
||||
sentiment(msg.payload, msg.overrides || null, function (err, result) {
|
||||
var value = RED.util.getMessageProperty(msg,node.property);
|
||||
if (value !== undefined) {
|
||||
sentiment(value, msg.overrides || null, function (err, result) {
|
||||
msg.sentiment = result;
|
||||
node.send(msg);
|
||||
});
|
||||
}
|
||||
else { node.send(msg); } // If no payload - just pass it on.
|
||||
else { node.send(msg); } // If no matching property - just pass it on.
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("sentiment",SentimentNode);
|
||||
|
@@ -26,6 +26,14 @@
|
||||
<input type="text" id="node-input-topic">
|
||||
</div>
|
||||
|
||||
<div class="form-row" id="node-once">
|
||||
<label for="node-input-once"> </label>
|
||||
<input type="checkbox" id="node-input-once" style="display:inline-block; width:15px; vertical-align:baseline;">
|
||||
<span data-i18n="inject.onstart"></span>
|
||||
<input type="text" id="node-input-onceDelay" placeholder="0.1" style="width:45px; height:28px;">
|
||||
<span data-i18n="inject.onceDelay"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<label for=""><i class="fa fa-repeat"></i> <span data-i18n="inject.label.repeat"></span></label>
|
||||
<select id="inject-time-type-select">
|
||||
@@ -41,7 +49,7 @@
|
||||
<div class="form-row inject-time-row hidden" id="inject-time-row-interval">
|
||||
<span data-i18n="inject.every"></span>
|
||||
<input id="inject-time-interval-count" class="inject-time-count" value="1"></input>
|
||||
<select style="width: 100px" id="inject-time-interval-units">
|
||||
<select style="width:100px" id="inject-time-interval-units">
|
||||
<option value="s" data-i18n="inject.seconds"></option>
|
||||
<option value="m" data-i18n="inject.minutes"></option>
|
||||
<option value="h" data-i18n="inject.hours"></option>
|
||||
@@ -49,7 +57,7 @@
|
||||
</div>
|
||||
|
||||
<div class="form-row inject-time-row hidden" id="inject-time-row-interval-time">
|
||||
<span data-i18n="inject.every"></span> <select style="width:90px" id="inject-time-interval-time-units" class="inject-time-int-count" value="1">
|
||||
<span data-i18n="inject.every"></span> <select style="width:90px; margin-left:20px;" id="inject-time-interval-time-units" class="inject-time-int-count" value="1">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
@@ -65,8 +73,8 @@
|
||||
</select> <span data-i18n="inject.minutes"></span><br/>
|
||||
<span data-i18n="inject.between"></span> <select id="inject-time-interval-time-start" class="inject-time-times"></select>
|
||||
<span data-i18n="inject.and"></span> <select id="inject-time-interval-time-end" class="inject-time-times"></select><br/>
|
||||
<div id="inject-time-interval-time-days" class="inject-time-days">
|
||||
<div style="display: inline-block; vertical-align: top;margin-right:5px;" data-i18n="inject.on">on</div>
|
||||
<div id="inject-time-interval-time-days" class="inject-time-days" style="margin-top:5px">
|
||||
<div style="display:inline-block; vertical-align:top; margin-right:5px;" data-i18n="inject.on">on</div>
|
||||
<div style="display:inline-block;">
|
||||
<div>
|
||||
<label><input type='checkbox' checked value='1'/> <span data-i18n="inject.days.0"></span></label>
|
||||
@@ -86,9 +94,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-row inject-time-row hidden" id="inject-time-row-time">
|
||||
<span data-i18n="inject.at"></span> <input id="inject-time-time" value="12:00"></input><br/>
|
||||
<span data-i18n="inject.at"></span> <input type="text" id="inject-time-time" value="12:00"></input><br/>
|
||||
<div id="inject-time-time-days" class="inject-time-days">
|
||||
<div style="display: inline-block; vertical-align: top;margin-right: 5px;" data-i18n="inject.on"></div>
|
||||
<div style="display:inline-block; vertical-align:top; margin-right:5px;" data-i18n="inject.on"></div>
|
||||
<div style="display:inline-block;">
|
||||
<div>
|
||||
<label><input type='checkbox' checked value='1'/> <span data-i18n="inject.days.0"></span></label>
|
||||
@@ -106,13 +114,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row" id="node-once">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-once" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-once" style="width: 70%;" data-i18n="inject.onstart"></label>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<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">
|
||||
@@ -133,17 +134,20 @@
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
vertical-align: top;
|
||||
vertical-align: baseline;
|
||||
width: 100px;
|
||||
}
|
||||
.inject-time-days input {
|
||||
width: auto;
|
||||
}
|
||||
.inject-time-days input {
|
||||
width: auto;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.inject-time-times {
|
||||
width: 90px;
|
||||
}
|
||||
#inject-time-time {
|
||||
width: 75px;
|
||||
margin-left: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.inject-time-count {
|
||||
width: 40px !important;
|
||||
@@ -166,6 +170,8 @@ The default payload is a timestamp of the current time in millisecs since Januar
|
||||
<p>By default, the node is triggered manually by clicking on its button within the editor. It can also be set to
|
||||
inject at regular intervals or according to a schedule.</p>
|
||||
<p>It can also be configured to inject once each time the flows are started.</p>
|
||||
<p>The maximum <i>Interval</i> that can be specified is about 596 hours / 24 days. However if you are looking at intervals
|
||||
greater than one day you should consider using a scheduler node that can cope with power outages and restarts.</p>
|
||||
<p><b>Note</b>: The <i>"Interval between times"</i> and <i>"at a specific time"</i> options use the standard cron system.
|
||||
This means that 20 minutes will be at the next hour, 20 minutes past and 40 minutes past - not in 20 minutes time.
|
||||
If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
@@ -181,9 +187,10 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
topic: {value:""},
|
||||
payload: {value:"", validate: RED.validators.typedInput("payloadType")},
|
||||
payloadType: {value:"date"},
|
||||
repeat: {value:""},
|
||||
repeat: {value:"", validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 2147483))) }},
|
||||
crontab: {value:""},
|
||||
once: {value:false}
|
||||
once: {value:false},
|
||||
onceDelay: {value:0.1}
|
||||
},
|
||||
icon: "inject.png",
|
||||
inputs:0,
|
||||
@@ -273,6 +280,10 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
}
|
||||
});
|
||||
|
||||
$("#node-input-once").change(function() {
|
||||
$("#node-input-onceDelay").attr('disabled', !$("#node-input-once").prop('checked'));
|
||||
})
|
||||
|
||||
$(".inject-time-times").each(function() {
|
||||
for (var i=0; i<24; i++) {
|
||||
var l = (i<10?"0":"")+i+":00";
|
||||
@@ -301,35 +312,6 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
min:1
|
||||
});
|
||||
|
||||
$.widget( "ui.injecttimespinner", $.ui.spinner, {
|
||||
options: {
|
||||
// seconds
|
||||
step: 60 * 1000,
|
||||
// hours
|
||||
page: 60
|
||||
},
|
||||
_parse: function( value ) {
|
||||
if ( typeof value === "string" ) {
|
||||
// already a timestamp
|
||||
if ( Number( value ) == value ) {
|
||||
return Number( value );
|
||||
}
|
||||
var p = value.split(":");
|
||||
var offset = new Date().getTimezoneOffset();
|
||||
return ((Number(p[0])*60)+Number(p[1])+offset)*60*1000;
|
||||
}
|
||||
return value;
|
||||
},
|
||||
_format: function( value ) {
|
||||
var d = new Date(value);
|
||||
var h = d.getHours();
|
||||
var m = d.getMinutes();
|
||||
return ((h < 10)?"0":"")+h+":"+((m < 10)?"0":"")+m;
|
||||
}
|
||||
});
|
||||
|
||||
$("#inject-time-time").injecttimespinner();
|
||||
|
||||
var repeattype = "none";
|
||||
if (this.repeat != "" && this.repeat != 0) {
|
||||
repeattype = "interval";
|
||||
@@ -446,7 +428,7 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
var count = $("#inject-time-interval-time-units").val();
|
||||
var startTime = Number($("#inject-time-interval-time-start").val());
|
||||
var endTime = Number($("#inject-time-interval-time-end").val());
|
||||
var days = $('#inject-time-interval-time-days input[type=checkbox]:checked').map(function(_, el) {
|
||||
var days = $('#inject-time-interval-time-days input[type=checkbox]:checked').map(function(_, el) {
|
||||
return $(el).val()
|
||||
}).get();
|
||||
if (days.length == 0) {
|
||||
@@ -499,8 +481,13 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
days = days.join(",");
|
||||
}
|
||||
var parts = time.split(":");
|
||||
repeat = "";
|
||||
crontab = parts[1]+" "+parts[0]+" * * "+days;
|
||||
if (parts.length === 2) {
|
||||
repeat = "";
|
||||
parts[1] = ("00" + (parseInt(parts[1]) % 60)).substr(-2);
|
||||
parts[0] = ("00" + (parseInt(parts[0]) % 24)).substr(-2);
|
||||
crontab = parts[1]+" "+parts[0]+" * * "+days;
|
||||
}
|
||||
else { crontab = ""; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -26,27 +26,40 @@ module.exports = function(RED) {
|
||||
this.repeat = n.repeat;
|
||||
this.crontab = n.crontab;
|
||||
this.once = n.once;
|
||||
var node = this;
|
||||
this.onceDelay = (n.onceDelay || 0.1) * 1000;
|
||||
this.interval_id = null;
|
||||
this.cronjob = null;
|
||||
var node = this;
|
||||
|
||||
if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
|
||||
this.repeat = this.repeat * 1000;
|
||||
if (RED.settings.verbose) { this.log(RED._("inject.repeat",this)); }
|
||||
this.interval_id = setInterval( function() {
|
||||
node.emit("input",{});
|
||||
}, this.repeat );
|
||||
} else if (this.crontab) {
|
||||
if (RED.settings.verbose) { this.log(RED._("inject.crontab",this)); }
|
||||
this.cronjob = new cron.CronJob(this.crontab,
|
||||
function() {
|
||||
node.emit("input",{});
|
||||
},
|
||||
null,true);
|
||||
if (node.repeat > 2147483) {
|
||||
node.error(RED._("inject.errors.toolong", this));
|
||||
delete node.repeat;
|
||||
}
|
||||
|
||||
node.repeaterSetup = function () {
|
||||
if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
|
||||
this.repeat = this.repeat * 1000;
|
||||
if (RED.settings.verbose) {
|
||||
this.log(RED._("inject.repeat", this));
|
||||
}
|
||||
this.interval_id = setInterval(function() {
|
||||
node.emit("input", {});
|
||||
}, this.repeat);
|
||||
} else if (this.crontab) {
|
||||
if (RED.settings.verbose) {
|
||||
this.log(RED._("inject.crontab", this));
|
||||
}
|
||||
this.cronjob = new cron.CronJob(this.crontab, function() { node.emit("input", {}); }, null, true);
|
||||
}
|
||||
};
|
||||
|
||||
if (this.once) {
|
||||
setTimeout( function() { node.emit("input",{}); }, 100 );
|
||||
this.onceTimeout = setTimeout( function() {
|
||||
node.emit("input",{});
|
||||
node.repeaterSetup();
|
||||
}, this.onceDelay);
|
||||
} else {
|
||||
node.repeaterSetup();
|
||||
}
|
||||
|
||||
this.on("input",function(msg) {
|
||||
@@ -56,7 +69,7 @@ module.exports = function(RED) {
|
||||
msg.payload = Date.now();
|
||||
} else if (this.payloadType == null) {
|
||||
msg.payload = this.payload;
|
||||
} else if (this.payloadType == 'none') {
|
||||
} else if (this.payloadType === 'none') {
|
||||
msg.payload = "";
|
||||
} else {
|
||||
msg.payload = RED.util.evaluateNodeProperty(this.payload,this.payloadType,this,msg);
|
||||
@@ -72,6 +85,9 @@ module.exports = function(RED) {
|
||||
RED.nodes.registerType("inject",InjectNode);
|
||||
|
||||
InjectNode.prototype.close = function() {
|
||||
if (this.onceTimeout) {
|
||||
clearTimeout(this.onceTimeout);
|
||||
}
|
||||
if (this.interval_id != null) {
|
||||
clearInterval(this.interval_id);
|
||||
if (RED.settings.verbose) { this.log(RED._("inject.stopped")); }
|
||||
@@ -80,7 +96,7 @@ module.exports = function(RED) {
|
||||
if (RED.settings.verbose) { this.log(RED._("inject.stopped")); }
|
||||
delete this.cronjob;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RED.httpAdmin.post("/inject/:id", RED.auth.needsPermission("inject.write"), function(req,res) {
|
||||
var node = RED.nodes.getNode(req.params.id);
|
||||
|
@@ -6,11 +6,22 @@
|
||||
<input id="node-input-complete" type="hidden">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-console"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label>
|
||||
<select type="text" id="node-input-console" style="display: inline-block; width: 250px; vertical-align: top;">
|
||||
<option value="false" data-i18n="debug.debtab"></option>
|
||||
<option value="true" data-i18n="debug.tabcon"></option>
|
||||
</select>
|
||||
<label for="node-input-tosidebar"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label>
|
||||
<label for="node-input-tosidebar" style="width:70%">
|
||||
<input type="checkbox" id="node-input-tosidebar" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toSidebar"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-console"> </label>
|
||||
<label for="node-input-console" style="width:70%">
|
||||
<input type="checkbox" id="node-input-console" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toConsole"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-row" id="node-tostatus-line">
|
||||
<label for="node-input-tostatus"> </label>
|
||||
<label for="node-input-tostatus" style="width:70%">
|
||||
<input type="checkbox" id="node-input-tostatus" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toStatus"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
@@ -26,7 +37,7 @@
|
||||
<p>Alongside each message, the debug sidebar includes information about the time the message was received, the node that sent it and the type of the message.
|
||||
Clicking on the source node id will reveal that node within the workspace.</p>
|
||||
<p>The button on the node can be used to enable or disable its output. It is recommended to disable or remove any Debug nodes that are not being used.</p>
|
||||
<p>The node can also be configured to send all messages to the runtime log.</p>
|
||||
<p>The node can also be configured to send all messages to the runtime log, or to send short (32 characters) to the status text under the debug node.</p>
|
||||
</script>
|
||||
<script src="debug/view/debug-utils.js"></script>
|
||||
|
||||
@@ -38,7 +49,9 @@
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
active: {value:true},
|
||||
console: {value:"false"},
|
||||
tosidebar: {value:true},
|
||||
console: {value:false},
|
||||
tostatus: {value:false},
|
||||
complete: {value:"false", required:true}
|
||||
},
|
||||
label: function() {
|
||||
@@ -100,7 +113,6 @@
|
||||
}
|
||||
},
|
||||
onpaletteadd: function() {
|
||||
|
||||
var options = {
|
||||
messageMouseEnter: function(sourceId) {
|
||||
if (sourceId) {
|
||||
@@ -148,7 +160,7 @@
|
||||
|
||||
var that = this;
|
||||
RED._debug = function(msg) {
|
||||
that.handleDebugMessage("",{
|
||||
that.handleDebugMessage("", {
|
||||
name:"debug",
|
||||
msg:msg
|
||||
});
|
||||
@@ -170,7 +182,6 @@
|
||||
var sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z);
|
||||
if (sourceNode) {
|
||||
o._source = {id:sourceNode.id,z:sourceNode.z,name:sourceNode.name};
|
||||
|
||||
}
|
||||
RED.debug.handleDebugMessage(o);
|
||||
if (subWindow) {
|
||||
@@ -183,6 +194,18 @@
|
||||
};
|
||||
RED.comms.subscribe("debug",this.handleDebugMessage);
|
||||
|
||||
this.clearMessageList = function() {
|
||||
RED.debug.clearMessageList(true);
|
||||
if (subWindow) {
|
||||
try {
|
||||
subWindow.postMessage({event:"projectChange"},"*");
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
RED.events.on("project:change", this.clearMessageList);
|
||||
|
||||
$("#debug-tab-open").click(function(e) {
|
||||
e.preventDefault();
|
||||
subWindow = window.open(document.location.toString().replace(/[?#].*$/,"")+"debug/view/view.html"+document.location.search,"nodeREDDebugView","menubar=no,location=no,toolbar=no,chrome,height=500,width=600");
|
||||
@@ -225,6 +248,15 @@
|
||||
delete RED._debug;
|
||||
},
|
||||
oneditprepare: function() {
|
||||
if (this.tosidebar === undefined) {
|
||||
this.tosidebar = true;
|
||||
$("#node-input-tosidebar").prop('checked', true);
|
||||
}
|
||||
if (typeof this.console === "string") {
|
||||
this.console = (this.console == 'true');
|
||||
$("#node-input-console").prop('checked', this.console);
|
||||
$("#node-input-tosidebar").prop('checked', true);
|
||||
}
|
||||
$("#node-input-typed-complete").typedInput({types:['msg', {value:"full",label:RED._("node-red:debug.msgobj"),hasValue:false}]});
|
||||
if (this.complete === "true" || this.complete === true) {
|
||||
// show complete message object
|
||||
@@ -240,6 +272,16 @@
|
||||
) {
|
||||
$("#node-input-typed-complete").typedInput('value','payload');
|
||||
}
|
||||
if ($("#node-input-typed-complete").typedInput('type') === 'msg') {
|
||||
$("#node-tostatus-line").show();
|
||||
}
|
||||
else { $("#node-tostatus-line").hide(); }
|
||||
});
|
||||
$("#node-input-complete").on('change',function() {
|
||||
if ($("#node-input-typed-complete").typedInput('type') === 'msg') {
|
||||
$("#node-tostatus-line").show();
|
||||
}
|
||||
else { $("#node-tostatus-line").hide(); }
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
@@ -250,7 +292,6 @@
|
||||
$("#node-input-complete").val($("#node-input-typed-complete").typedInput('value'));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
@@ -5,7 +5,7 @@ module.exports = function(RED) {
|
||||
var events = require("events");
|
||||
var path = require("path");
|
||||
var safeJSONStringify = require("json-stringify-safe");
|
||||
var debuglength = RED.settings.debugMaxLength||1000;
|
||||
var debuglength = RED.settings.debugMaxLength || 1000;
|
||||
var useColors = RED.settings.debugUseColors || false;
|
||||
util.inspect.styles.boolean = "red";
|
||||
|
||||
@@ -13,26 +13,49 @@ module.exports = function(RED) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.name = n.name;
|
||||
this.complete = (n.complete||"payload").toString();
|
||||
|
||||
if (this.complete === "false") {
|
||||
this.complete = "payload";
|
||||
}
|
||||
|
||||
this.console = n.console;
|
||||
if (this.complete === "false") { this.complete = "payload"; }
|
||||
this.console = ""+(n.console || false);
|
||||
this.tostatus = n.tostatus || false;
|
||||
this.tosidebar = n.tosidebar;
|
||||
if (this.tosidebar === undefined) { this.tosidebar = true; }
|
||||
this.severity = n.severity || 40;
|
||||
this.active = (n.active === null || typeof n.active === "undefined") || n.active;
|
||||
this.status({});
|
||||
|
||||
var node = this;
|
||||
var levels = {
|
||||
off: 1,
|
||||
fatal: 10,
|
||||
error: 20,
|
||||
warn: 30,
|
||||
info: 40,
|
||||
debug: 50,
|
||||
trace: 60,
|
||||
audit: 98,
|
||||
metric: 99
|
||||
};
|
||||
var colors = {
|
||||
"0": "grey",
|
||||
"10": "grey",
|
||||
"20": "red",
|
||||
"30": "yellow",
|
||||
"40": "grey",
|
||||
"50": "green",
|
||||
"60": "blue"
|
||||
};
|
||||
|
||||
this.on("input",function(msg) {
|
||||
if (this.complete === "true") {
|
||||
// debug complete msg object
|
||||
// debug complete msg object
|
||||
if (this.console === "true") {
|
||||
node.log("\n"+util.inspect(msg, {colors:useColors, depth:10}));
|
||||
}
|
||||
if (this.active) {
|
||||
sendDebug({id:node.id,name:node.name,topic:msg.topic,msg:msg,_path:msg._path});
|
||||
if (this.active && this.tosidebar) {
|
||||
sendDebug({id:node.id, name:node.name, topic:msg.topic, msg:msg, _path:msg._path});
|
||||
}
|
||||
} else {
|
||||
// debug user defined msg property
|
||||
}
|
||||
else {
|
||||
// debug user defined msg property
|
||||
var property = "payload";
|
||||
var output = msg[property];
|
||||
if (this.complete !== "false" && typeof this.complete !== "undefined") {
|
||||
@@ -53,7 +76,15 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
if (this.active) {
|
||||
sendDebug({id:node.id,z:node.z,name:node.name,topic:msg.topic,property:property,msg:output,_path:msg._path});
|
||||
if (this.tosidebar == true) {
|
||||
sendDebug({id:node.id, z:node.z, name:node.name, topic:msg.topic, property:property, msg:output, _path:msg._path});
|
||||
}
|
||||
if (this.tostatus === true) {
|
||||
var st = util.inspect(output);
|
||||
if (st.length > 32) { st = st.substr(0,32) + "..."; }
|
||||
node.oldStatus = {fill:colors[node.severity], shape:"dot", text:st};
|
||||
node.status(node.oldStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -138,7 +169,7 @@ module.exports = function(RED) {
|
||||
value = value.substring(0,debuglength)+"...";
|
||||
}
|
||||
} else if (value && value.constructor) {
|
||||
if (value.constructor.name === "Buffer") {
|
||||
if (value.type === "Buffer") {
|
||||
value.__encoded__ = true;
|
||||
value.length = value.data.length;
|
||||
if (value.length > debuglength) {
|
||||
@@ -196,9 +227,14 @@ module.exports = function(RED) {
|
||||
if (state === "enable") {
|
||||
node.active = true;
|
||||
res.sendStatus(200);
|
||||
if (node.tostatus) { node.status({}); }
|
||||
} else if (state === "disable") {
|
||||
node.active = false;
|
||||
res.sendStatus(201);
|
||||
if (node.tostatus && node.hasOwnProperty("oldStatus")) {
|
||||
node.oldStatus.shape = "ring";
|
||||
node.status(node.oldStatus);
|
||||
}
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
}
|
||||
|
@@ -75,12 +75,20 @@
|
||||
<dt>payload <span class="property-type">string</span></dt>
|
||||
<dd>the standard output of the command.</dd>
|
||||
</dl>
|
||||
<dl class="message-properties">
|
||||
<dt>rc <span class="property-type">object</span></dt>
|
||||
<dd>exec mode only, a copy of the return code object (also available on port 3)</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li>Standard error
|
||||
<dl class="message-properties">
|
||||
<dt>payload <span class="property-type">string</span></dt>
|
||||
<dd>the standard error of the command.</dd>
|
||||
</dl>
|
||||
<dl class="message-properties">
|
||||
<dt>rc <span class="property-type">object</span></dt>
|
||||
<dd>exec mode only, a copy of the return code object (also available on port 3)</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li>Return code
|
||||
<dl class="message-properties">
|
||||
@@ -107,6 +115,7 @@
|
||||
the type of signal to be sent, for example, <code>SIGINT</code>, <code>SIGQUIT</code> or <code>SIGHUP</code>.
|
||||
Defaults to <code>SIGTERM</code> if set to an empty string.</p>
|
||||
<p>If the node has more than one process running then <code>msg.pid</code> must also be set with the value of the PID to be killed.</p>
|
||||
<p>If a value is provided in the <code>Timeout</code> field then, if the process has not completed when the specified number of seconds has elapsed, the process will be killed automatically</p>
|
||||
<p>Tip: if running a Python app you may need to use the <code>-u</code> parameter to stop the output being buffered.</p>
|
||||
</script>
|
||||
|
||||
|
@@ -125,14 +125,15 @@ module.exports = function(RED) {
|
||||
if (node.append.trim() !== "") { cl += " "+node.append; }
|
||||
/* istanbul ignore else */
|
||||
if (RED.settings.verbose) { node.log(cl); }
|
||||
child = exec(cl, {encoding: 'binary', maxBuffer:10000000}, function (error, stdout, stderr) {
|
||||
child = exec(cl, {encoding:'binary', maxBuffer:10000000}, function (error, stdout, stderr) {
|
||||
var msg2, msg3;
|
||||
delete msg.payload;
|
||||
if (stderr) {
|
||||
msg2 = RED.util.cloneMessage(msg);
|
||||
msg2.payload = stderr;
|
||||
}
|
||||
msg.payload = Buffer.from(stdout,"binary");
|
||||
if (isUtf8(msg.payload)) { msg.payload = msg.payload.toString(); }
|
||||
var msg2 = null;
|
||||
if (stderr) {
|
||||
msg2 = {payload: stderr};
|
||||
}
|
||||
var msg3 = null;
|
||||
node.status({});
|
||||
//console.log('[exec] stdout: ' + stdout);
|
||||
//console.log('[exec] stderr: ' + stderr);
|
||||
@@ -142,10 +143,15 @@ module.exports = function(RED) {
|
||||
if (error.code === null) { node.status({fill:"red",shape:"dot",text:"killed"}); }
|
||||
else { node.status({fill:"red",shape:"dot",text:"error:"+error.code}); }
|
||||
node.log('error:' + error);
|
||||
} else if (node.oldrc === "false") {
|
||||
}
|
||||
else if (node.oldrc === "false") {
|
||||
msg3 = {payload:{code:0}};
|
||||
}
|
||||
if (!msg3) { node.status({}); }
|
||||
else {
|
||||
msg.rc = msg3.payload;
|
||||
if (msg2) { msg2.rc = msg3.payload; }
|
||||
}
|
||||
node.send([msg,msg2,msg3]);
|
||||
if (child.tout) { clearTimeout(child.tout); }
|
||||
delete node.activeProcesses[child.pid];
|
||||
|
@@ -70,10 +70,19 @@
|
||||
label: function() {
|
||||
return this.name;
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
var that = this;
|
||||
$( "#node-input-outputs" ).spinner({
|
||||
min:1
|
||||
min:1,
|
||||
change: function(event, ui) {
|
||||
var value = this.value;
|
||||
if (!value.match(/^\d+$/)) { value = 1; }
|
||||
else if (value < this.min) { value = this.min; }
|
||||
if (value !== this.value) { $(this).spinner("value", value); }
|
||||
}
|
||||
});
|
||||
|
||||
this.editor = RED.editor.createEditor({
|
||||
|
@@ -187,6 +187,13 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
};
|
||||
if (util.hasOwnProperty('promisify')) {
|
||||
sandbox.setTimeout[util.promisify.custom] = function(after, value) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
sandbox.setTimeout(function(){ resolve(value) }, after);
|
||||
});
|
||||
}
|
||||
}
|
||||
var context = vm.createContext(sandbox);
|
||||
try {
|
||||
this.script = vm.createScript(functionText);
|
||||
|
@@ -42,6 +42,7 @@
|
||||
<select id="node-input-output" style="width:180px;">
|
||||
<option value="str" data-i18n="template.label.plain"></option>
|
||||
<option value="json" data-i18n="template.label.json"></option>
|
||||
<option value="yaml" data-i18n="template.label.yaml"></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -53,6 +54,9 @@
|
||||
<dl class="message-properties">
|
||||
<dt>msg <span class="property-type">object</span></dt>
|
||||
<dd>A msg object containing information to populate the template.</dd>
|
||||
<dt class="optional">template <span class="property-type">string</span></dt>
|
||||
<dd>A template to be populated from msg.payload. If not configured in the edit panel,
|
||||
this can be set as a property of msg.</dd>
|
||||
</dl>
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
@@ -97,6 +101,9 @@
|
||||
label: function() {
|
||||
return this.name;
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
var that = this;
|
||||
if (!this.fieldType) {
|
||||
|
@@ -17,14 +17,17 @@
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
var mustache = require("mustache");
|
||||
var yaml = require("js-yaml");
|
||||
|
||||
|
||||
/**
|
||||
* Custom Mustache Context capable to resolve message property and node
|
||||
* flow and global context
|
||||
*/
|
||||
function NodeContext(msg, nodeContext,parent) {
|
||||
function NodeContext(msg, nodeContext, parent, escapeStrings) {
|
||||
this.msgContext = new mustache.Context(msg,parent);
|
||||
this.nodeContext = nodeContext;
|
||||
this.escapeStrings = escapeStrings;
|
||||
}
|
||||
|
||||
NodeContext.prototype = new mustache.Context();
|
||||
@@ -34,6 +37,14 @@ module.exports = function(RED) {
|
||||
try {
|
||||
var value = this.msgContext.lookup(name);
|
||||
if (value !== undefined) {
|
||||
if (this.escapeStrings && typeof value === "string") {
|
||||
value = value.replace(/\\/g, "\\\\");
|
||||
value = value.replace(/\n/g, "\\n");
|
||||
value = value.replace(/\t/g, "\\t");
|
||||
value = value.replace(/\r/g, "\\r");
|
||||
value = value.replace(/\f/g, "\\f");
|
||||
value = value.replace(/[\b]/g, "\\b");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -72,14 +83,31 @@ module.exports = function(RED) {
|
||||
node.on("input", function(msg) {
|
||||
try {
|
||||
var value;
|
||||
/***
|
||||
* Allow template contents to be defined externally
|
||||
* through inbound msg.template IFF node.template empty
|
||||
*/
|
||||
if (msg.hasOwnProperty("template")) {
|
||||
if (node.template == "" || node.template === null) {
|
||||
node.template = msg.template;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.syntax === "mustache") {
|
||||
value = mustache.render(node.template,new NodeContext(msg, node.context()));
|
||||
if (node.outputFormat === "json") {
|
||||
value = mustache.render(node.template,new NodeContext(msg, node.context(), null, true));
|
||||
} else {
|
||||
value = mustache.render(node.template,new NodeContext(msg, node.context(), null, false));
|
||||
}
|
||||
} else {
|
||||
value = node.template;
|
||||
}
|
||||
if (node.outputFormat === "json") {
|
||||
value = JSON.parse(value);
|
||||
}
|
||||
if (node.outputFormat === "yaml") {
|
||||
value = yaml.load(value);
|
||||
}
|
||||
|
||||
if (node.fieldType === 'msg') {
|
||||
RED.util.setMessageProperty(msg,node.field,value);
|
||||
|
@@ -102,7 +102,7 @@
|
||||
<dt class="optional">delay <span class="property-type">number</span></dt>
|
||||
<dd>Sets the delay, in milliseconds, to be applied to the message. This
|
||||
option only applies if the node is configured to allow the message to
|
||||
provide the delay interval.</dd>
|
||||
override the configured default delay interval.</dd>
|
||||
<dt class="optional">reset</dt>
|
||||
<dd>If the received message has this property set to any value, all
|
||||
outstanding messages held by the node are cleared without being sent.</dd>
|
||||
@@ -129,13 +129,13 @@
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
pauseType: {value:"delay", required:true},
|
||||
timeout: {value:"5", required:true, validate:RED.validators.number()},
|
||||
timeout: {value:"5", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }},
|
||||
timeoutUnits: {value:"seconds"},
|
||||
rate: {value:"1", required:true, validate:RED.validators.number()},
|
||||
rate: {value:"1", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }},
|
||||
nbRateUnits: {value:"1", required:false, validate:RED.validators.regex(/\d+|/)},
|
||||
rateUnits: {value: "second"},
|
||||
randomFirst: {value:"1", required:true, validate:RED.validators.number()},
|
||||
randomLast: {value:"5", required:true, validate:RED.validators.number()},
|
||||
randomFirst: {value:"1", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }},
|
||||
randomLast: {value:"5", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }},
|
||||
randomUnits: {value: "seconds"},
|
||||
drop: {value:false}
|
||||
},
|
||||
@@ -260,7 +260,7 @@
|
||||
$("#delay-details-for").show();
|
||||
$("#random-details").hide();
|
||||
} else if (this.value === "delayv") {
|
||||
$("#delay-details-for").hide();
|
||||
$("#delay-details-for").show();
|
||||
$("#random-details").hide();
|
||||
} else if (this.value === "random") {
|
||||
$("#delay-details-for").hide();
|
||||
|
@@ -105,7 +105,10 @@ module.exports = function(RED) {
|
||||
}
|
||||
else if (node.pauseType === "delayv") {
|
||||
node.on("input", function(msg) {
|
||||
var delayvar = Number(msg.delay || 0);
|
||||
var delayvar = Number(node.timeout);
|
||||
if (msg.hasOwnProperty("delay") && !isNaN(parseFloat(msg.delay))) {
|
||||
delayvar = parseFloat(msg.delay);
|
||||
}
|
||||
if (delayvar < 0) { delayvar = 0; }
|
||||
var id = setTimeout(function() {
|
||||
node.idList.splice(node.idList.indexOf(id),1);
|
||||
@@ -113,7 +116,7 @@ module.exports = function(RED) {
|
||||
node.send(msg);
|
||||
}, delayvar);
|
||||
node.idList.push(id);
|
||||
if ((delayvar >= 1) && (node.idList.length !== 0)) {
|
||||
if ((delayvar >= 0) && (node.idList.length !== 0)) {
|
||||
node.status({fill:"blue",shape:"dot",text:delayvar/1000+"s"});
|
||||
}
|
||||
if (msg.hasOwnProperty("reset")) { clearDelayList(); }
|
||||
@@ -171,6 +174,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
if (msg.hasOwnProperty("reset")) {
|
||||
clearInterval(node.intervalID);
|
||||
node.intervalID = -1;
|
||||
node.buffer = [];
|
||||
node.status({text:"reset"});
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user