mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge branch 'dev'
This commit is contained in:
commit
7a3ead8f3b
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,3 +22,4 @@ packages/node_modules/@node-red/editor-client/public
|
|||||||
!test/**/node_modules
|
!test/**/node_modules
|
||||||
docs
|
docs
|
||||||
!packages/node_modules/**/docs
|
!packages/node_modules/**/docs
|
||||||
|
.vscode
|
@ -1,11 +1,15 @@
|
|||||||
sudo: false
|
sudo: false
|
||||||
|
addons:
|
||||||
|
chrome: stable
|
||||||
language: node_js
|
language: node_js
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
- node_js: "14"
|
||||||
- node_js: "12"
|
- node_js: "12"
|
||||||
- node_js: "10"
|
- node_js: "10"
|
||||||
script:
|
script:
|
||||||
- ./node_modules/.bin/grunt && istanbul report text && ( cat coverage/lcov.info | $(npm get prefix)/bin/coveralls || true ) && rm -rf coverage
|
- ./node_modules/.bin/grunt && istanbul report text && ( cat coverage/lcov.info | $(npm get prefix)/bin/coveralls || true ) && rm -rf coverage
|
||||||
|
- scripts/install-ui-test-dependencies.sh && grunt test-ui
|
||||||
before_script:
|
before_script:
|
||||||
- npm install -g istanbul coveralls
|
- npm install -g istanbul coveralls
|
||||||
- node_js: "8"
|
- node_js: "8"
|
||||||
|
194
CHANGELOG.md
194
CHANGELOG.md
@ -1,3 +1,195 @@
|
|||||||
|
### 1.1.0: Milestone Release
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Align node labels on FF
|
||||||
|
- Fix node toggle button initial opacity
|
||||||
|
- Make color/icon/label-pos pickers keyboard navigable
|
||||||
|
- Default group label to be shown and improve toggle button
|
||||||
|
- Fix clearing group label
|
||||||
|
- Remove hardcoded css Fixes #2603
|
||||||
|
- Fix node button mouse pointer css
|
||||||
|
- Change node linebreak handling to use "\n "
|
||||||
|
- Handle import of node with non-default number of outputs
|
||||||
|
- Improve display of focussed form element
|
||||||
|
- Fix typedInput error on empty subflow input types #2624 (@HiroyasuNishiyama)
|
||||||
|
- Update JP message catalogue for subflow input type #2471 (@HiroyasuNishiyama)
|
||||||
|
- Outliner - add empty item when last config node moved
|
||||||
|
- Update zh-CN/zh-TW translations #2626 (@JiyeYu)
|
||||||
|
- Add default shortcut for `core:show-help-tab`
|
||||||
|
- Clear outline focus on config node sidebar panel
|
||||||
|
- Tweak group margin to fit node status and look better
|
||||||
|
- Fix reparenting nodes in outliner when they change
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- Add developer options - permits npm run build-dev #2628 (@Steve-Mcl)
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
- Add example flows for lots of core nodes #2585 #2550 #2549 (@HiroyasuNishiyama)
|
||||||
|
- TCP: Fix tcp in node finishing packets when in streaming base64 receive mode.
|
||||||
|
- Join: Clear timeout when msg.reset received Fixes #2471
|
||||||
|
- Switch: JSONata expr does not require msg.parts.count
|
||||||
|
- Inject: fix backwards migration of inject without topic
|
||||||
|
|
||||||
|
#### 1.1.0-beta.3: Beta Release
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Fix wiring nodes from input back to output
|
||||||
|
- Fix sometimes unable to keyboard-move group to left/up
|
||||||
|
- Fix group position in outliner
|
||||||
|
- Handle unknown nodes with no icon
|
||||||
|
- Prevent node creep when switching tabs
|
||||||
|
|
||||||
|
#### 1.1.0-beta.2: Beta Release
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Add UI tests to travis build #2593 #2616 #2617 #2619 (@kazuhitoyokoi)
|
||||||
|
- Add Japanese translations for outliner, jsonata and runtime #2618 (@kazuhitoyokoi)
|
||||||
|
- Fix deleting node in group after changing selection
|
||||||
|
- Fixup padding of quick-add search box
|
||||||
|
- Move config nodes under type-level hierarchy in outline
|
||||||
|
- Emit nodes:change event for config node users list modified
|
||||||
|
- Increase group margin to avoid clash with status text
|
||||||
|
- Fix event order when quick-adding node to group
|
||||||
|
- Switch RED.events.DEBUG messages to warn to get stacktraces
|
||||||
|
- Fix empty item handling for subflows/config in outliner
|
||||||
|
- Fix search indexing of group nodes
|
||||||
|
- Avoid regenerating every node label on redraw
|
||||||
|
- Fix handling of multi-line node label
|
||||||
|
- Disable merge group menu for single item or non-group item #2611 (@HiroyasuNishiyama)
|
||||||
|
- Merge pull request #2609 from node-red-hitachi/fix-remove-from-group
|
||||||
|
- Fix position of empty group with multi-line label #2612 (@HiroyasuNishiyama)
|
||||||
|
- Make treelist of subflow/config nodes initially have empty placeholder
|
||||||
|
- Fix empty placeholder not shown on remove from group #2609 (@HiroyasuNishiyama)
|
||||||
|
- Prevent conversion of circular structure #2607 (@HiroyasuNishiyama)
|
||||||
|
- Handle null status text in the editor Fixes #2606
|
||||||
|
- Massively reduce our dependency on d3 to render the view
|
||||||
|
- EditableList/TreeList - defer adding elements to DOM
|
||||||
|
- Prevent RED.stop being called multiple times if >1 signal received
|
||||||
|
- Flag a node as removed when it is disabled
|
||||||
|
- Some performance improvements for TreeList
|
||||||
|
- Resize info/help sidebars whenever sidebar is opened
|
||||||
|
- Add search defaults to outliner searchBox
|
||||||
|
- Add search presets option to searchBox widget
|
||||||
|
- Add RED.popover.menu as a new type of menu widget
|
||||||
|
- Add support for is:XYZ search flags
|
||||||
|
- Track subflow instances on the subflow node itself
|
||||||
|
- Refresh outline filter whenever something changes Fixes #2601
|
||||||
|
- Fix Help tab search box appearance
|
||||||
|
- Rename Node Information to Information in sidebar
|
||||||
|
- Do a sync-redraw after clearing to ensure clean state
|
||||||
|
- Make catch/status/complete/link filter case-insensitive
|
||||||
|
- Add 'add' option to touch radialMenu for quick-add dialog
|
||||||
|
- Merge branch 'dev' of https://github.com/node-red/node-red into dev
|
||||||
|
- ensure trigger node detects changes to number of outputs
|
||||||
|
- Ignore whitespace when checking function setup/close code
|
||||||
|
- Preserve event handlers when moving outliner items
|
||||||
|
- Add tooltips to outliner buttons
|
||||||
|
- Only validate nodes once they have all been imported
|
||||||
|
- Ensure configNode.users is updated properly on import
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- Bump node-red-admin 0.2.6
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- WebSocket: Prevent charAt call on websocket listener #2610 ()
|
||||||
|
- Debug: fix status to migrate old nodes to correct default mode.
|
||||||
|
- Link: Fix Link node filter Fixes #2600
|
||||||
|
|
||||||
|
|
||||||
|
#### 1.1.0-beta.1: Beta Release
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- Allow HTTPS settings to be refreshed #2551 (@bartbutenaers)
|
||||||
|
- Add support for moment in JSONata expressions #2583 (@dxdc)
|
||||||
|
- Add httpAdminMiddleware for admin routes #2555
|
||||||
|
- Add admin api authentication function #2479 (@KazuhiroItoh)
|
||||||
|
- Add option support for overwriting settings.js #2463 (@HiroyasuNishiyama)
|
||||||
|
- Add support for credential-stored env var in subflow #2368
|
||||||
|
- Add node installation from other than public site #2378 (@KazuhiroItoh)
|
||||||
|
- Catch more signals to allow clean context flush on shutdown #2447
|
||||||
|
- Add `node-red admin` command #2592
|
||||||
|
- Move to `lodash.clonedeep` #2396 (@amodelbello)
|
||||||
|
- Tidy up unhandledRejection warning from context unit tests
|
||||||
|
- Add test cases for setMessageProperty with non-object properties
|
||||||
|
- Fix for settings.set subsequent updates #2584 (@sammachin)
|
||||||
|
- Turn off installer funding messages
|
||||||
|
- Remove unused \_info/\_type subflow env var magic values
|
||||||
|
- Add #! lines to project shell scripts #2548
|
||||||
|
- Add nodejs14 to Travis test matrix
|
||||||
|
- Remove duplicate NLS message #2516 (@alexk111)
|
||||||
|
- Let setMessageProperty return success flag #2439
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- Add ability to group nodes #2493
|
||||||
|
- Add loading progress bar #2558
|
||||||
|
- Add Outliner to Info sidebar and add help sidebar #2556
|
||||||
|
- Add action to toggle node label visibility #2569
|
||||||
|
- Add show-examples-import-dialog action
|
||||||
|
- Add more consistent events in the editor #2543
|
||||||
|
- Save the node description property to the library #2490 (@kazuhitoyokoi)
|
||||||
|
- Add credential type to TypedInput #2367
|
||||||
|
- Scroll the view with WASD/Cursor keys when nothing selected #2381
|
||||||
|
- Bump jquery/migrate to latest versions
|
||||||
|
- Fix editor underscore visibility on Linux systems #2579 (@ristomatti)
|
||||||
|
- Support setting title on typedInput multi-option #2586 (@Steve-Mcl)
|
||||||
|
- Projects: Allow remote branch dialog to create non-default remote branches
|
||||||
|
- Ensure auth failure on project fetch identifies the remote #2545
|
||||||
|
- Make all dialogs handle smaller height screens better
|
||||||
|
- Add basic Array.from polyfill for IE11
|
||||||
|
- Add some more trap form elements to workaround Chrome autofill
|
||||||
|
- [info-sidebar] Handle node/group/flows with \n in their name
|
||||||
|
- [popover] Allow hover-type popovers to contain buttons
|
||||||
|
- Modify RED.panels to use flexbox position
|
||||||
|
- Allow node edit dialog to be opened on a non-default tab
|
||||||
|
- Add createNodeIcon and getDarkerColor to RED.utils
|
||||||
|
- [search] Refactor search to use editor events to generate index
|
||||||
|
- Allow RED.notify.popover to have a position offset
|
||||||
|
- Make selected list item more distinct
|
||||||
|
- Allow node button to be clicked via api call
|
||||||
|
- Reorder initial load so projects:load event emits before any nodes:add
|
||||||
|
- Add polyfills for IE11
|
||||||
|
- Activate project menu after initial clone #2547 (@HiroyasuNishiyama)
|
||||||
|
- Fix replacement of unknown node in workspace when module installed #2524 (@HiroyasuNishiyama)
|
||||||
|
- Fix appearance of subflow template panel #2506 (@HiroyasuNishiyama)
|
||||||
|
- Fix workspace CSS properties syntax #2487 (@bonanitech)
|
||||||
|
- Consolidate duplicate selectors #2488 (@bonanitech)
|
||||||
|
- Update message catalogue for subflow UI #2466 (@HiroyasuNishiyama)
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- Batch: Add reset feature to batch node #2553 (@HiroyasuNishiyama)
|
||||||
|
- Catch/Complete/Link/Status: #2588 Add compact searchBox to filter node lists
|
||||||
|
- Catch/Complete/Link/Status: Allow searchBox filter to filter on node type #2595 (@jeancarl)
|
||||||
|
- CSV: Add warn when unpaired quotes detected on input.
|
||||||
|
- CSV: allow node to only send headers once
|
||||||
|
- CSV: Allow CR and LF control chars to be a part of the value #2526 (@tmdoit)
|
||||||
|
- CSV: Add support for parsing empty strings and null values #2510 (@tmdoit)
|
||||||
|
- CSV: Update Japanese translations for CSV node #2562 (@kazuhitoyokoi)
|
||||||
|
- Debug: Add bulk-activate/deactive actions for debug node #2570 (@cinhcet)
|
||||||
|
- Debug: Show status independently of main output #2564
|
||||||
|
- Delay: Ensure delay node rate limit timer is cleared on reset
|
||||||
|
- Function: Make the function node top-level async
|
||||||
|
- Function: Add support of initialization & finalization to function node #2498 (@HiroyasuNishiyama)
|
||||||
|
- HTTP In: Remove nodejs deprecation warning #2540 (@vladimir-kazan)
|
||||||
|
- HTTP Request: Support sending body in GET requests #2478 (@hardillb)
|
||||||
|
- Inject: Adding user definable properties to inject node #2435 (@PaulWieland)
|
||||||
|
- TCP: Allow to know particular session from status node #2413 (@dvv)
|
||||||
|
- Trigger: Add optional second output
|
||||||
|
- Trigger: Ensure trigger sends complete 2nd msg if set to send latest msg
|
||||||
|
- Trigger: Allow trigger node to use other than msg.topic to separate streams
|
||||||
|
- XML: Moved XML options documentation property from Outputs to Inputs section #2572 (@jeancarl)
|
||||||
|
- Add some core node example flows #2455 (@HiroyasuNishiyama)
|
||||||
|
- Change types from text/x-red to text/html in node html files #2425 (@kazuhitoyokoi)
|
||||||
|
|
||||||
|
|
||||||
#### 1.0.6: Maintenance Release
|
#### 1.0.6: Maintenance Release
|
||||||
|
|
||||||
Runtime
|
Runtime
|
||||||
@ -119,7 +311,7 @@ Runtime
|
|||||||
- #2332 Fix error handling of nodes with multiple input handlers
|
- #2332 Fix error handling of nodes with multiple input handlers
|
||||||
- Add script to generate npm publish script
|
- Add script to generate npm publish script
|
||||||
- #2371 Ensure folder is present before write (e.g. flows file not in user folder)
|
- #2371 Ensure folder is present before write (e.g. flows file not in user folder)
|
||||||
- #2371 Handle windows UNC '\\' paths
|
- #2371 Handle windows UNC '\' paths
|
||||||
- #2366 Handle logging of non-JSON encodable objects
|
- #2366 Handle logging of non-JSON encodable objects
|
||||||
|
|
||||||
Editor
|
Editor
|
||||||
|
@ -125,6 +125,7 @@ module.exports = function(grunt) {
|
|||||||
src: [
|
src: [
|
||||||
// Ensure editor source files are concatenated in
|
// Ensure editor source files are concatenated in
|
||||||
// the right order
|
// the right order
|
||||||
|
"packages/node_modules/@node-red/editor-client/src/js/polyfills.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js",
|
"packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/red.js",
|
"packages/node_modules/@node-red/editor-client/src/js/red.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/events.js",
|
"packages/node_modules/@node-red/editor-client/src/js/events.js",
|
||||||
@ -151,6 +152,7 @@ module.exports = function(grunt) {
|
|||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js",
|
||||||
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/colorPicker.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/actions.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/actions.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/diff.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/diff.js",
|
||||||
@ -163,6 +165,8 @@ module.exports = function(grunt) {
|
|||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/palette.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/palette.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js",
|
||||||
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js",
|
||||||
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-help.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js",
|
||||||
@ -177,6 +181,7 @@ module.exports = function(grunt) {
|
|||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js",
|
||||||
|
"packages/node_modules/@node-red/editor-client/src/js/ui/group.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js",
|
||||||
@ -619,6 +624,10 @@ module.exports = function(grunt) {
|
|||||||
'Builds editor content',
|
'Builds editor content',
|
||||||
['clean:build','jsonlint','concat:build','concat:vendor','copy:build','uglify:build','sass:build','attachCopyright']);
|
['clean:build','jsonlint','concat:build','concat:vendor','copy:build','uglify:build','sass:build','attachCopyright']);
|
||||||
|
|
||||||
|
grunt.registerTask('build-dev',
|
||||||
|
'Developer mode: build dev version',
|
||||||
|
['clean:build','concat:build','concat:vendor','copy:build','sass:build','setDevEnv']);
|
||||||
|
|
||||||
grunt.registerTask('dev',
|
grunt.registerTask('dev',
|
||||||
'Developer mode: run node-red, watch for source changes and build/restart',
|
'Developer mode: run node-red, watch for source changes and build/restart',
|
||||||
['build','setDevEnv','concurrent:dev']);
|
['build','setDevEnv','concurrent:dev']);
|
||||||
|
29
package.json
29
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "1.0.6",
|
"version": "1.1.0",
|
||||||
"description": "Low-code programming for event-driven applications",
|
"description": "Low-code programming for event-driven applications",
|
||||||
"homepage": "http://nodered.org",
|
"homepage": "http://nodered.org",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@ -13,6 +13,8 @@
|
|||||||
"start": "node packages/node_modules/node-red/red.js",
|
"start": "node packages/node_modules/node-red/red.js",
|
||||||
"test": "grunt",
|
"test": "grunt",
|
||||||
"build": "grunt build",
|
"build": "grunt build",
|
||||||
|
"dev": "grunt dev",
|
||||||
|
"build-dev": "grunt build-dev",
|
||||||
"docs": "grunt docs"
|
"docs": "grunt docs"
|
||||||
},
|
},
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@ -24,20 +26,20 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "6.12.0",
|
"ajv": "6.12.2",
|
||||||
"basic-auth": "2.0.1",
|
"basic-auth": "2.0.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"body-parser": "1.19.0",
|
"body-parser": "1.19.0",
|
||||||
"cheerio": "0.22.0",
|
"cheerio": "0.22.0",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"content-type": "1.0.4",
|
"content-type": "1.0.4",
|
||||||
"cookie": "0.4.0",
|
"cookie": "0.4.1",
|
||||||
"cookie-parser": "1.4.5",
|
"cookie-parser": "1.4.5",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"cron": "1.7.2",
|
"cron": "1.7.2",
|
||||||
"denque": "1.4.1",
|
"denque": "1.4.1",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"express-session": "1.17.0",
|
"express-session": "1.17.1",
|
||||||
"fs-extra": "8.1.0",
|
"fs-extra": "8.1.0",
|
||||||
"fs.notify": "0.0.4",
|
"fs.notify": "0.0.4",
|
||||||
"hash-sum": "2.0.0",
|
"hash-sum": "2.0.0",
|
||||||
@ -45,16 +47,19 @@
|
|||||||
"i18next": "15.1.2",
|
"i18next": "15.1.2",
|
||||||
"iconv-lite": "0.5.1",
|
"iconv-lite": "0.5.1",
|
||||||
"is-utf8": "0.2.1",
|
"is-utf8": "0.2.1",
|
||||||
"js-yaml": "3.13.1",
|
"js-yaml": "3.14.0",
|
||||||
"json-stringify-safe": "5.0.1",
|
"json-stringify-safe": "5.0.1",
|
||||||
"jsonata": "1.8.3",
|
"jsonata": "1.8.3",
|
||||||
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"media-typer": "1.1.0",
|
"media-typer": "1.1.0",
|
||||||
"memorystore": "1.6.2",
|
"memorystore": "1.6.2",
|
||||||
"mime": "2.4.4",
|
"mime": "2.4.6",
|
||||||
|
"moment-timezone": "^0.5.31",
|
||||||
"mqtt": "2.18.8",
|
"mqtt": "2.18.8",
|
||||||
"multer": "1.4.2",
|
"multer": "1.4.2",
|
||||||
"mustache": "4.0.1",
|
"mustache": "4.0.1",
|
||||||
"node-red-node-rbe": "^0.2.6",
|
"node-red-admin": "^0.2.6",
|
||||||
|
"node-red-node-rbe": "^0.2.9",
|
||||||
"node-red-node-sentiment": "^0.1.6",
|
"node-red-node-sentiment": "^0.1.6",
|
||||||
"node-red-node-tail": "^0.1.0",
|
"node-red-node-tail": "^0.1.0",
|
||||||
"nopt": "4.0.3",
|
"nopt": "4.0.3",
|
||||||
@ -66,7 +71,7 @@
|
|||||||
"raw-body": "2.4.1",
|
"raw-body": "2.4.1",
|
||||||
"request": "2.88.0",
|
"request": "2.88.0",
|
||||||
"semver": "6.3.0",
|
"semver": "6.3.0",
|
||||||
"uglify-js": "3.8.1",
|
"uglify-js": "3.9.4",
|
||||||
"when": "3.7.8",
|
"when": "3.7.8",
|
||||||
"ws": "6.2.1",
|
"ws": "6.2.1",
|
||||||
"xml2js": "0.4.23"
|
"xml2js": "0.4.23"
|
||||||
@ -76,7 +81,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"marked": "0.8.2",
|
"marked": "0.8.2",
|
||||||
"dompurify": "2.0.8",
|
"dompurify": "2.0.11",
|
||||||
"grunt": "~1.0.4",
|
"grunt": "~1.0.4",
|
||||||
"grunt-chmod": "~1.1.1",
|
"grunt-chmod": "~1.1.1",
|
||||||
"grunt-cli": "~1.3.2",
|
"grunt-cli": "~1.3.2",
|
||||||
@ -97,14 +102,14 @@
|
|||||||
"grunt-npm-command": "~0.1.2",
|
"grunt-npm-command": "~0.1.2",
|
||||||
"grunt-sass": "~3.1.0",
|
"grunt-sass": "~3.1.0",
|
||||||
"grunt-simple-mocha": "~0.4.1",
|
"grunt-simple-mocha": "~0.4.1",
|
||||||
"http-proxy": "1.18.0",
|
"http-proxy": "1.18.1",
|
||||||
"istanbul": "0.4.5",
|
"istanbul": "0.4.5",
|
||||||
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
||||||
"minami": "1.2.3",
|
"minami": "1.2.3",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"mosca": "^2.8.3",
|
"mosca": "^2.8.3",
|
||||||
"node-red-node-test-helper": "^0.2.3",
|
"node-red-node-test-helper": "^0.2.5",
|
||||||
"node-sass": "^4.13.1",
|
"node-sass": "^4.14.1",
|
||||||
"should": "^8.4.0",
|
"should": "^8.4.0",
|
||||||
"sinon": "1.17.7",
|
"sinon": "1.17.7",
|
||||||
"stoppable": "^1.1.0",
|
"stoppable": "^1.1.0",
|
||||||
|
@ -44,6 +44,7 @@ module.exports = {
|
|||||||
user: req.user,
|
user: req.user,
|
||||||
module: req.body.module,
|
module: req.body.module,
|
||||||
version: req.body.version,
|
version: req.body.version,
|
||||||
|
url: req.body.url,
|
||||||
req: apiUtils.getRequestLogObject(req)
|
req: apiUtils.getRequestLogObject(req)
|
||||||
}
|
}
|
||||||
runtimeAPI.nodes.addModule(opts).then(function(info) {
|
runtimeAPI.nodes.addModule(opts).then(function(info) {
|
||||||
|
@ -36,6 +36,7 @@ var log = require("@node-red/util").log; // TODO: separate module
|
|||||||
passport.use(strategies.bearerStrategy.BearerStrategy);
|
passport.use(strategies.bearerStrategy.BearerStrategy);
|
||||||
passport.use(strategies.clientPasswordStrategy.ClientPasswordStrategy);
|
passport.use(strategies.clientPasswordStrategy.ClientPasswordStrategy);
|
||||||
passport.use(strategies.anonymousStrategy);
|
passport.use(strategies.anonymousStrategy);
|
||||||
|
passport.use(strategies.tokensStrategy);
|
||||||
|
|
||||||
var server = oauth2orize.createServer();
|
var server = oauth2orize.createServer();
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ function init(_settings,storage) {
|
|||||||
function needsPermission(permission) {
|
function needsPermission(permission) {
|
||||||
return function(req,res,next) {
|
return function(req,res,next) {
|
||||||
if (settings && settings.adminAuth) {
|
if (settings && settings.adminAuth) {
|
||||||
return passport.authenticate(['bearer','anon'],{ session: false })(req,res,function() {
|
return passport.authenticate(['bearer','tokens','anon'],{ session: false })(req,res,function() {
|
||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
@ -123,9 +123,38 @@ AnonymousStrategy.prototype.authenticate = function(req) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function TokensStrategy() {
|
||||||
|
passport.Strategy.call(this);
|
||||||
|
this.name = 'tokens';
|
||||||
|
}
|
||||||
|
util.inherits(TokensStrategy, passport.Strategy);
|
||||||
|
TokensStrategy.prototype.authenticate = function(req) {
|
||||||
|
var self = this;
|
||||||
|
var token = null;
|
||||||
|
if (Users.tokenHeader() === 'authorization') {
|
||||||
|
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
|
||||||
|
token = req.headers.authorization.split(' ')[1];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
token = req.headers[Users.tokenHeader()];
|
||||||
|
}
|
||||||
|
if (token) {
|
||||||
|
Users.tokens(token).then(function(admin) {
|
||||||
|
if (admin) {
|
||||||
|
self.success(admin,{scope:admin.permissions});
|
||||||
|
} else {
|
||||||
|
self.fail(401);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.fail(401);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
bearerStrategy: bearerStrategy,
|
bearerStrategy: bearerStrategy,
|
||||||
clientPasswordStrategy: clientPasswordStrategy,
|
clientPasswordStrategy: clientPasswordStrategy,
|
||||||
passwordTokenExchange: passwordTokenExchange,
|
passwordTokenExchange: passwordTokenExchange,
|
||||||
anonymousStrategy: new AnonymousStrategy()
|
anonymousStrategy: new AnonymousStrategy(),
|
||||||
|
tokensStrategy: new TokensStrategy()
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,9 @@ function getDefaultUser() {
|
|||||||
var api = {
|
var api = {
|
||||||
get: get,
|
get: get,
|
||||||
authenticate: authenticate,
|
authenticate: authenticate,
|
||||||
default: getDefaultUser
|
default: getDefaultUser,
|
||||||
|
tokens: getDefaultUser,
|
||||||
|
tokenHeader: "authorization"
|
||||||
}
|
}
|
||||||
|
|
||||||
function init(config) {
|
function init(config) {
|
||||||
@ -105,6 +107,12 @@ function init(config) {
|
|||||||
} else {
|
} else {
|
||||||
api.default = getDefaultUser;
|
api.default = getDefaultUser;
|
||||||
}
|
}
|
||||||
|
if (config.tokens && typeof config.tokens === "function") {
|
||||||
|
api.tokens = config.tokens;
|
||||||
|
if (config.tokenHeader && typeof config.tokenHeader === "string") {
|
||||||
|
api.tokenHeader = config.tokenHeader.toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function cleanUser(user) {
|
function cleanUser(user) {
|
||||||
if (user && user.hasOwnProperty('password')) {
|
if (user && user.hasOwnProperty('password')) {
|
||||||
@ -118,5 +126,7 @@ module.exports = {
|
|||||||
init: init,
|
init: init,
|
||||||
get: function(username) { return api.get(username).then(cleanUser)},
|
get: function(username) { return api.get(username).then(cleanUser)},
|
||||||
authenticate: function() { return api.authenticate.apply(null, arguments) },
|
authenticate: function() { return api.authenticate.apply(null, arguments) },
|
||||||
default: function() { return api.default(); }
|
default: function() { return api.default(); },
|
||||||
|
tokens: function(token) { return api.tokens(token); },
|
||||||
|
tokenHeader: function() { return api.tokenHeader }
|
||||||
};
|
};
|
||||||
|
@ -59,6 +59,12 @@ function init(settings,_server,storage,runtimeAPI) {
|
|||||||
});
|
});
|
||||||
adminApp.use(corsHandler);
|
adminApp.use(corsHandler);
|
||||||
|
|
||||||
|
if (settings.httpAdminMiddleware) {
|
||||||
|
if (typeof settings.httpAdminMiddleware === "function") {
|
||||||
|
adminApp.use(settings.httpAdminMiddleware)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auth.init(settings,storage);
|
auth.init(settings,storage);
|
||||||
|
|
||||||
var maxApiRequestSize = settings.apiMaxLength || '5mb';
|
var maxApiRequestSize = settings.apiMaxLength || '5mb';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-api",
|
"name": "@node-red/editor-api",
|
||||||
"version": "1.0.6",
|
"version": "1.1.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -16,16 +16,16 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/util": "1.0.6",
|
"@node-red/util": "1.1.0",
|
||||||
"@node-red/editor-client": "1.0.6",
|
"@node-red/editor-client": "1.1.0",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"body-parser": "1.19.0",
|
"body-parser": "1.19.0",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"express-session": "1.17.0",
|
"express-session": "1.17.1",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"memorystore": "1.6.2",
|
"memorystore": "1.6.2",
|
||||||
"mime": "2.4.4",
|
"mime": "2.4.6",
|
||||||
"mustache": "4.0.1",
|
"mustache": "4.0.1",
|
||||||
"oauth2orize": "1.11.0",
|
"oauth2orize": "1.11.0",
|
||||||
"passport-http-bearer": "1.0.1",
|
"passport-http-bearer": "1.0.1",
|
||||||
|
@ -14,7 +14,15 @@
|
|||||||
"back": "Back",
|
"back": "Back",
|
||||||
"next": "Next",
|
"next": "Next",
|
||||||
"clone": "Clone project",
|
"clone": "Clone project",
|
||||||
"cont": "Continue"
|
"cont": "Continue",
|
||||||
|
"style": "Style",
|
||||||
|
"line": "Outline",
|
||||||
|
"fill": "Fill",
|
||||||
|
"label": "Label",
|
||||||
|
"color": "Color",
|
||||||
|
"position": "Position",
|
||||||
|
"enable": "Enable",
|
||||||
|
"disable": "Disable"
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"string": "string",
|
"string": "string",
|
||||||
@ -28,6 +36,13 @@
|
|||||||
"null": "null"
|
"null": "null"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"event": {
|
||||||
|
"loadPalette": "Loading Palette",
|
||||||
|
"loadNodeCatalogs": "Loading Node catalogs",
|
||||||
|
"loadNodes": "Loading Nodes __count__",
|
||||||
|
"loadFlows": "Loading Flows",
|
||||||
|
"importFlows": "Adding Flows to workspace"
|
||||||
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"defaultName": "Flow __number__",
|
"defaultName": "Flow __number__",
|
||||||
"editFlow": "Edit flow: __name__",
|
"editFlow": "Edit flow: __name__",
|
||||||
@ -91,7 +106,12 @@
|
|||||||
"projects-new": "New",
|
"projects-new": "New",
|
||||||
"projects-open": "Open",
|
"projects-open": "Open",
|
||||||
"projects-settings": "Project Settings",
|
"projects-settings": "Project Settings",
|
||||||
"showNodeLabelDefault": "Show label of newly added nodes"
|
"showNodeLabelDefault": "Show label of newly added nodes",
|
||||||
|
"groups": "Groups",
|
||||||
|
"groupSelection": "Group selection",
|
||||||
|
"ungroupSelection": "Ungroup selection",
|
||||||
|
"groupMergeSelection": "Merge selection",
|
||||||
|
"groupRemoveSelection": "Remove from group"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@ -171,6 +191,8 @@
|
|||||||
"node_plural": "__count__ nodes",
|
"node_plural": "__count__ nodes",
|
||||||
"configNode": "__count__ configuration node",
|
"configNode": "__count__ configuration node",
|
||||||
"configNode_plural": "__count__ configuration nodes",
|
"configNode_plural": "__count__ configuration nodes",
|
||||||
|
"group": "__count__ group",
|
||||||
|
"group_plural": "__count__ groups",
|
||||||
"flow": "__count__ flow",
|
"flow": "__count__ flow",
|
||||||
"flow_plural": "__count__ flows",
|
"flow_plural": "__count__ flows",
|
||||||
"subflow": "__count__ subflow",
|
"subflow": "__count__ subflow",
|
||||||
@ -186,6 +208,9 @@
|
|||||||
"nodesImported": "Imported:",
|
"nodesImported": "Imported:",
|
||||||
"nodeCopied": "__count__ node copied",
|
"nodeCopied": "__count__ node copied",
|
||||||
"nodeCopied_plural": "__count__ nodes copied",
|
"nodeCopied_plural": "__count__ nodes copied",
|
||||||
|
"groupCopied": "__count__ group copied",
|
||||||
|
"groupCopied_plural": "__count__ groups copied",
|
||||||
|
"groupStyleCopied": "Group style copied",
|
||||||
"invalidFlow": "Invalid flow: __message__",
|
"invalidFlow": "Invalid flow: __message__",
|
||||||
"export": {
|
"export": {
|
||||||
"selected":"selected nodes",
|
"selected":"selected nodes",
|
||||||
@ -308,6 +333,13 @@
|
|||||||
"multipleInputsToSelection": "<strong>Cannot create subflow</strong>: multiple inputs to selection"
|
"multipleInputsToSelection": "<strong>Cannot create subflow</strong>: multiple inputs to selection"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"group": {
|
||||||
|
"editGroup": "Edit group: __name__",
|
||||||
|
"errors": {
|
||||||
|
"cannotCreateDiffGroups": "Cannot create group using nodes from different groups",
|
||||||
|
"cannotAddSubflowPorts": "Cannot add subflow ports to a group"
|
||||||
|
}
|
||||||
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"configEdit": "Edit",
|
"configEdit": "Edit",
|
||||||
"configAdd": "Add",
|
"configAdd": "Add",
|
||||||
@ -337,6 +369,7 @@
|
|||||||
"locale": "Select UI Language",
|
"locale": "Select UI Language",
|
||||||
"icon": "Icon",
|
"icon": "Icon",
|
||||||
"inputType": "Input type",
|
"inputType": "Input type",
|
||||||
|
"selectType": "select types...",
|
||||||
"inputs" : {
|
"inputs" : {
|
||||||
"input": "input",
|
"input": "input",
|
||||||
"select": "select",
|
"select": "select",
|
||||||
@ -351,7 +384,8 @@
|
|||||||
"bool": "bool",
|
"bool": "bool",
|
||||||
"json": "JSON",
|
"json": "JSON",
|
||||||
"bin": "buffer",
|
"bin": "buffer",
|
||||||
"env": "env variable"
|
"env": "env variable",
|
||||||
|
"cred": "credential"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"input": "input",
|
"input": "input",
|
||||||
@ -533,11 +567,12 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"info": {
|
"info": {
|
||||||
"name": "Node information",
|
"name": "Information",
|
||||||
"tabName": "Name",
|
"tabName": "Name",
|
||||||
"label": "info",
|
"label": "info",
|
||||||
"node": "Node",
|
"node": "Node",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
|
"group": "Group",
|
||||||
"module": "Module",
|
"module": "Module",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
@ -560,7 +595,29 @@
|
|||||||
"nodeHelp": "Node Help",
|
"nodeHelp": "Node Help",
|
||||||
"none":"None",
|
"none":"None",
|
||||||
"arrayItems": "__count__ items",
|
"arrayItems": "__count__ items",
|
||||||
"showTips":"You can open the tips from the settings panel"
|
"showTips":"You can open the tips from the settings panel",
|
||||||
|
"outline": "Outline",
|
||||||
|
"empty": "empty",
|
||||||
|
"globalConfig": "Global Configuration Nodes",
|
||||||
|
"triggerAction": "Trigger action",
|
||||||
|
"find": "Find in workspace",
|
||||||
|
"search": {
|
||||||
|
"configNodes": "Configuration nodes",
|
||||||
|
"unusedConfigNodes": "Unused configuration nodes",
|
||||||
|
"invalidNodes": "Invalid nodes",
|
||||||
|
"uknownNodes": "Unknown nodes",
|
||||||
|
"unusedSubflows": "Unused subflows"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"name": "Help",
|
||||||
|
"label": "help",
|
||||||
|
"search": "Search help",
|
||||||
|
"nodeHelp": "Node Help",
|
||||||
|
"showHelp": "Show help",
|
||||||
|
"showInOutline": "Show in outline",
|
||||||
|
"showTopics": "Show topics",
|
||||||
|
"noHelp": "No help topic selected"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"name": "Configuration nodes",
|
"name": "Configuration nodes",
|
||||||
@ -613,7 +670,6 @@
|
|||||||
"removeFromProject": "remove from project",
|
"removeFromProject": "remove from project",
|
||||||
"addToProject": "add to project",
|
"addToProject": "add to project",
|
||||||
"files": "Files",
|
"files": "Files",
|
||||||
"package": "Package",
|
|
||||||
"flow": "Flow",
|
"flow": "Flow",
|
||||||
"credentials": "Credentials",
|
"credentials": "Credentials",
|
||||||
"package":"Package",
|
"package":"Package",
|
||||||
@ -757,7 +813,8 @@
|
|||||||
"bin": "buffer",
|
"bin": "buffer",
|
||||||
"date": "timestamp",
|
"date": "timestamp",
|
||||||
"jsonata": "expression",
|
"jsonata": "expression",
|
||||||
"env": "env variable"
|
"env": "env variable",
|
||||||
|
"cred": "credential"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"editableList": {
|
"editableList": {
|
||||||
@ -804,9 +861,9 @@
|
|||||||
"expandItems": "Expand items",
|
"expandItems": "Expand items",
|
||||||
"collapseItems": "Collapse items",
|
"collapseItems": "Collapse items",
|
||||||
"duplicate": "Duplicate",
|
"duplicate": "Duplicate",
|
||||||
"error": {
|
"error": {
|
||||||
"invalidJSON": "Invalid JSON: "
|
"invalidJSON": "Invalid JSON: "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"markdownEditor": {
|
"markdownEditor": {
|
||||||
"title": "Markdown editor",
|
"title": "Markdown editor",
|
||||||
@ -978,7 +1035,7 @@
|
|||||||
"retry": "Retry",
|
"retry": "Retry",
|
||||||
"update-failed": "Failed to update auth",
|
"update-failed": "Failed to update auth",
|
||||||
"unhandled": "Unhandled error response",
|
"unhandled": "Unhandled error response",
|
||||||
"host-key-verify-failed": "<p>Host key verification failed.</p><p>The repository host key could not be verified. Please update your <code>known_hosts</code> file and try again."
|
"host-key-verify-failed": "<p>Host key verification failed.</p><p>The repository host key could not be verified. Please update your <code>known_hosts</code> file and try again.</p>"
|
||||||
},
|
},
|
||||||
"create-branch-list": {
|
"create-branch-list": {
|
||||||
"invalid": "Invalid branch",
|
"invalid": "Invalid branch",
|
||||||
|
@ -266,5 +266,9 @@
|
|||||||
"$type": {
|
"$type": {
|
||||||
"args": "value",
|
"args": "value",
|
||||||
"desc": "Returns the type of `value` as a string. If `value` is undefined, this will return `undefined`"
|
"desc": "Returns the type of `value` as a string. If `value` is undefined, this will return `undefined`"
|
||||||
|
},
|
||||||
|
"$moment": {
|
||||||
|
"args": "[str]",
|
||||||
|
"desc": "Gets a date object using the Moment library."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
75
packages/node_modules/@node-red/editor-client/locales/ja/editor.json
vendored
Executable file → Normal file
75
packages/node_modules/@node-red/editor-client/locales/ja/editor.json
vendored
Executable file → Normal file
@ -14,7 +14,15 @@
|
|||||||
"back": "戻る",
|
"back": "戻る",
|
||||||
"next": "進む",
|
"next": "進む",
|
||||||
"clone": "プロジェクトをクローン",
|
"clone": "プロジェクトをクローン",
|
||||||
"cont": "続ける"
|
"cont": "続ける",
|
||||||
|
"style": "形式",
|
||||||
|
"line": "線",
|
||||||
|
"fill": "塗りつぶし",
|
||||||
|
"label": "ラベル",
|
||||||
|
"color": "色",
|
||||||
|
"position": "配置",
|
||||||
|
"enable": "有効",
|
||||||
|
"disable": "無効"
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"string": "文字列",
|
"string": "文字列",
|
||||||
@ -28,6 +36,13 @@
|
|||||||
"null": "null"
|
"null": "null"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"event": {
|
||||||
|
"loadPalette": "パレットを読み込み中",
|
||||||
|
"loadNodeCatalogs": "ノードカタログを読み込み中",
|
||||||
|
"loadNodes": "ノードを読み込み中 __count__",
|
||||||
|
"loadFlows": "フローを読み込み中",
|
||||||
|
"importFlows": "ワークスペースにフローを追加中"
|
||||||
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"defaultName": "フロー __number__",
|
"defaultName": "フロー __number__",
|
||||||
"editFlow": "フローを編集: __name__",
|
"editFlow": "フローを編集: __name__",
|
||||||
@ -67,7 +82,7 @@
|
|||||||
"settings": "設定",
|
"settings": "設定",
|
||||||
"userSettings": "ユーザ設定",
|
"userSettings": "ユーザ設定",
|
||||||
"nodes": "ノード",
|
"nodes": "ノード",
|
||||||
"displayStatus": "ノードの状態を表示",
|
"displayStatus": "ノードのステータスを表示",
|
||||||
"displayConfig": "ノードの設定",
|
"displayConfig": "ノードの設定",
|
||||||
"import": "読み込み",
|
"import": "読み込み",
|
||||||
"export": "書き出し",
|
"export": "書き出し",
|
||||||
@ -91,7 +106,12 @@
|
|||||||
"projects-new": "新規",
|
"projects-new": "新規",
|
||||||
"projects-open": "開く",
|
"projects-open": "開く",
|
||||||
"projects-settings": "設定",
|
"projects-settings": "設定",
|
||||||
"showNodeLabelDefault": "追加したノードのラベルを表示"
|
"showNodeLabelDefault": "追加したノードのラベルを表示",
|
||||||
|
"groups": "グループ",
|
||||||
|
"groupSelection": "選択部分をグループ化",
|
||||||
|
"ungroupSelection": "選択部分をグループ解除",
|
||||||
|
"groupMergeSelection": "選択部分をマージ",
|
||||||
|
"groupRemoveSelection": "グループから削除"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@ -171,6 +191,8 @@
|
|||||||
"node_plural": "__count__ 個のノード",
|
"node_plural": "__count__ 個のノード",
|
||||||
"configNode": "__count__ 個の設定ノード",
|
"configNode": "__count__ 個の設定ノード",
|
||||||
"configNode_plural": "__count__ 個の設定ノード",
|
"configNode_plural": "__count__ 個の設定ノード",
|
||||||
|
"group": "__count__ 個のグループ",
|
||||||
|
"group_plural": "__count__ 個のグループ",
|
||||||
"flow": "__count__ 個のフロー",
|
"flow": "__count__ 個のフロー",
|
||||||
"flow_plural": "__count__ 個のフロー",
|
"flow_plural": "__count__ 個のフロー",
|
||||||
"subflow": "__count__ 個のサブフロー",
|
"subflow": "__count__ 個のサブフロー",
|
||||||
@ -186,6 +208,9 @@
|
|||||||
"nodesImported": "読み込みました:",
|
"nodesImported": "読み込みました:",
|
||||||
"nodeCopied": "__count__ 個のノードをコピーしました",
|
"nodeCopied": "__count__ 個のノードをコピーしました",
|
||||||
"nodeCopied_plural": "__count__ 個のノードをコピーしました",
|
"nodeCopied_plural": "__count__ 個のノードをコピーしました",
|
||||||
|
"groupCopied": "__count__ 個のグループをコピーしました",
|
||||||
|
"groupCopied_plural": "__count__ 個のグループをコピーしました",
|
||||||
|
"groupStyleCopied": "グループの形式をコピーしました",
|
||||||
"invalidFlow": "不正なフロー: __message__",
|
"invalidFlow": "不正なフロー: __message__",
|
||||||
"export": {
|
"export": {
|
||||||
"selected": "選択したフロー",
|
"selected": "選択したフロー",
|
||||||
@ -308,6 +333,13 @@
|
|||||||
"multipleInputsToSelection": "<strong>サブフローを作成できません</strong>: 複数の入力が選択されています"
|
"multipleInputsToSelection": "<strong>サブフローを作成できません</strong>: 複数の入力が選択されています"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"group": {
|
||||||
|
"editGroup": "__name__ グループを編集",
|
||||||
|
"errors": {
|
||||||
|
"cannotCreateDiffGroups": "異なるグループのノードを使用してグループを作成することはできません",
|
||||||
|
"cannotAddSubflowPorts": "グループにサブフローの端子を追加できません"
|
||||||
|
}
|
||||||
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"configEdit": "編集",
|
"configEdit": "編集",
|
||||||
"configAdd": "追加",
|
"configAdd": "追加",
|
||||||
@ -337,6 +369,7 @@
|
|||||||
"locale": "UI言語の選択",
|
"locale": "UI言語の選択",
|
||||||
"icon": "記号",
|
"icon": "記号",
|
||||||
"inputType": "入力形式",
|
"inputType": "入力形式",
|
||||||
|
"selectType": "形式選択...",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"input": "入力",
|
"input": "入力",
|
||||||
"select": "メニュー",
|
"select": "メニュー",
|
||||||
@ -351,7 +384,8 @@
|
|||||||
"bool": "真偽",
|
"bool": "真偽",
|
||||||
"json": "JSON",
|
"json": "JSON",
|
||||||
"bin": "バッファ",
|
"bin": "バッファ",
|
||||||
"env": "環境変数"
|
"env": "環境変数",
|
||||||
|
"cred": "認証情報"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"input": "入力",
|
"input": "入力",
|
||||||
@ -538,6 +572,7 @@
|
|||||||
"label": "情報",
|
"label": "情報",
|
||||||
"node": "ノード",
|
"node": "ノード",
|
||||||
"type": "型",
|
"type": "型",
|
||||||
|
"group": "グループ",
|
||||||
"module": "モジュール",
|
"module": "モジュール",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"status": "状態",
|
"status": "状態",
|
||||||
@ -560,7 +595,29 @@
|
|||||||
"nodeHelp": "ノードのヘルプ",
|
"nodeHelp": "ノードのヘルプ",
|
||||||
"none": "なし",
|
"none": "なし",
|
||||||
"arrayItems": "__count__ 要素",
|
"arrayItems": "__count__ 要素",
|
||||||
"showTips": "設定からヒントを表示できます"
|
"showTips": "設定からヒントを表示できます",
|
||||||
|
"outline": "アウトライン",
|
||||||
|
"empty": "空",
|
||||||
|
"globalConfig": "グローバル設定ノード",
|
||||||
|
"triggerAction": "アクションを実行",
|
||||||
|
"find": "ワークスペース内を検索",
|
||||||
|
"search": {
|
||||||
|
"configNodes": "設定ノード",
|
||||||
|
"unusedConfigNodes": "未使用の設定ノード",
|
||||||
|
"invalidNodes": "不正なノード",
|
||||||
|
"uknownNodes": "未知のノード",
|
||||||
|
"unusedSubflows": "未使用のサブフロー"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"name": "ヘルプ",
|
||||||
|
"label": "ヘルプ",
|
||||||
|
"search": "ヘルプを検索",
|
||||||
|
"nodeHelp": "ノードヘルプ",
|
||||||
|
"showHelp": "ヘルプを表示",
|
||||||
|
"showInOutline": "アウトラインに表示",
|
||||||
|
"showTopics": "トピックを表示",
|
||||||
|
"noHelp": "ヘルプのトピックが未選択"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"name": "ノードの設定を表示",
|
"name": "ノードの設定を表示",
|
||||||
@ -613,9 +670,9 @@
|
|||||||
"removeFromProject": "プロジェクトから削除",
|
"removeFromProject": "プロジェクトから削除",
|
||||||
"addToProject": "プロジェクトへ追加",
|
"addToProject": "プロジェクトへ追加",
|
||||||
"files": "ファイル",
|
"files": "ファイル",
|
||||||
"package": "パッケージ",
|
|
||||||
"flow": "フロー",
|
"flow": "フロー",
|
||||||
"credentials": "認証情報",
|
"credentials": "認証情報",
|
||||||
|
"package": "パッケージ",
|
||||||
"packageCreate": "変更が保存された時にファイルが作成されます",
|
"packageCreate": "変更が保存された時にファイルが作成されます",
|
||||||
"fileNotExist": "ファイルが存在しません",
|
"fileNotExist": "ファイルが存在しません",
|
||||||
"selectFile": "ファイルを選択",
|
"selectFile": "ファイルを選択",
|
||||||
@ -756,7 +813,8 @@
|
|||||||
"bin": "バッファ",
|
"bin": "バッファ",
|
||||||
"date": "日時",
|
"date": "日時",
|
||||||
"jsonata": "JSONata式",
|
"jsonata": "JSONata式",
|
||||||
"env": "環境変数"
|
"env": "環境変数",
|
||||||
|
"cred": "認証情報"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"editableList": {
|
"editableList": {
|
||||||
@ -976,7 +1034,8 @@
|
|||||||
"passphrase": "パスフレーズ",
|
"passphrase": "パスフレーズ",
|
||||||
"retry": "リトライ",
|
"retry": "リトライ",
|
||||||
"update-failed": "認証の更新に失敗しました",
|
"update-failed": "認証の更新に失敗しました",
|
||||||
"unhandled": "エラー応答が処理されませんでした"
|
"unhandled": "エラー応答が処理されませんでした",
|
||||||
|
"host-key-verify-failed": "<p>ホストキーの検証に失敗</p><p>リポジトリのホストキーを検証できませんでした。<code>known_hosts</code>ファイルを更新して、もう一度試してください。</p>"
|
||||||
},
|
},
|
||||||
"create-branch-list": {
|
"create-branch-list": {
|
||||||
"invalid": "不正なブランチ",
|
"invalid": "不正なブランチ",
|
||||||
|
4
packages/node_modules/@node-red/editor-client/locales/ja/jsonata.json
vendored
Executable file → Normal file
4
packages/node_modules/@node-red/editor-client/locales/ja/jsonata.json
vendored
Executable file → Normal file
@ -266,5 +266,9 @@
|
|||||||
"$type": {
|
"$type": {
|
||||||
"args": "value",
|
"args": "value",
|
||||||
"desc": "`value` の型を文字列として返します。もし `value` が未定義の場合、 `undefined` が返されます。"
|
"desc": "`value` の型を文字列として返します。もし `value` が未定義の場合、 `undefined` が返されます。"
|
||||||
|
},
|
||||||
|
"$moment": {
|
||||||
|
"args": "[str]",
|
||||||
|
"desc": "Momentライブラリを使用して日付オブジェクトを取得します。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,15 @@
|
|||||||
"back": "后退",
|
"back": "后退",
|
||||||
"next": "下一个",
|
"next": "下一个",
|
||||||
"clone": "克隆项目",
|
"clone": "克隆项目",
|
||||||
"cont": "继续"
|
"cont": "继续",
|
||||||
|
"style": "风格",
|
||||||
|
"line": "大纲",
|
||||||
|
"fill": "填充",
|
||||||
|
"label": "标签",
|
||||||
|
"color": "颜色",
|
||||||
|
"position": "位置",
|
||||||
|
"enable": "启用",
|
||||||
|
"disable": "禁用"
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"string": "字符串",
|
"string": "字符串",
|
||||||
@ -28,11 +36,18 @@
|
|||||||
"null": "空"
|
"null": "空"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"event": {
|
||||||
|
"loadPalette": "加载控制板",
|
||||||
|
"loadNodeCatalogs": "加载节点目录",
|
||||||
|
"loadNodes": "加载 __count__ 个节点",
|
||||||
|
"loadFlows": "加载流程",
|
||||||
|
"importFlows": "往工作区中加载流程"
|
||||||
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"defaultName": "流程__number__",
|
"defaultName": "流程 __number__",
|
||||||
"editFlow": "编辑流程: __name__",
|
"editFlow": "编辑流程: __name__",
|
||||||
"confirmDelete": "确认删除",
|
"confirmDelete": "确认删除",
|
||||||
"delete": "你确定想删除 '__label__'?",
|
"delete": "你确定要删除 __label__ ?",
|
||||||
"dropFlowHere": "把流程放到这里",
|
"dropFlowHere": "把流程放到这里",
|
||||||
"addFlow": "添加流程",
|
"addFlow": "添加流程",
|
||||||
"listFlows": "流程一览",
|
"listFlows": "流程一览",
|
||||||
@ -91,7 +106,12 @@
|
|||||||
"projects-new": "新建",
|
"projects-new": "新建",
|
||||||
"projects-open": "打开",
|
"projects-open": "打开",
|
||||||
"projects-settings": "项目设定",
|
"projects-settings": "项目设定",
|
||||||
"showNodeLabelDefault": "显示新添加的节点的标签"
|
"showNodeLabelDefault": "显示新添加的节点的标签",
|
||||||
|
"groups": "组",
|
||||||
|
"groupSelection": "选择组",
|
||||||
|
"ungroupSelection": "取消选择组",
|
||||||
|
"groupMergeSelection": "合并选择",
|
||||||
|
"groupRemoveSelection": "从组中移除"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@ -101,7 +121,7 @@
|
|||||||
"zoom-in": "放大"
|
"zoom-in": "放大"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"loggedInAs": "作为__name__登陆",
|
"loggedInAs": "作为 __name__ 登陆",
|
||||||
"username": "账号",
|
"username": "账号",
|
||||||
"password": "密码",
|
"password": "密码",
|
||||||
"login": "登陆",
|
"login": "登陆",
|
||||||
@ -127,13 +147,13 @@
|
|||||||
"missing_flow_file": "<p>找不到项目流程文件。</p><p>该项目未配置流程文件。</p>",
|
"missing_flow_file": "<p>找不到项目流程文件。</p><p>该项目未配置流程文件。</p>",
|
||||||
"missing_package_file": "<p>找不到项目包文件。</p><p>项目缺少package.json文件。</p>",
|
"missing_package_file": "<p>找不到项目包文件。</p><p>项目缺少package.json文件。</p>",
|
||||||
"project_empty": "<p>该项目为空。</p><p>是否要创建一组默认的项目文件?<br/>否则,您将必须在编辑器外部手动将文件添加到项目中。</p>",
|
"project_empty": "<p>该项目为空。</p><p>是否要创建一组默认的项目文件?<br/>否则,您将必须在编辑器外部手动将文件添加到项目中。</p>",
|
||||||
"project_not_found": "<p>未找到项目'__project__'。</p>",
|
"project_not_found": "<p>未找到项目 __project__ 。</p>",
|
||||||
"git_merge_conflict": "<p>自动合并更改失败。</p><p>修复未合并的冲突,然后提交结果。</p>"
|
"git_merge_conflict": "<p>自动合并更改失败。</p><p>修复未合并的冲突,然后提交结果。</p>"
|
||||||
},
|
},
|
||||||
"error": "<strong>错误</strong>: __message__",
|
"error": "<strong>错误</strong>: __message__",
|
||||||
"errors": {
|
"errors": {
|
||||||
"lostConnection": "丢失与服务器的连接,重新连接...",
|
"lostConnection": "丢失与服务器的连接,重新连接...",
|
||||||
"lostConnectionReconnect": "丢失与服务器的连接,__time__秒后重新连接",
|
"lostConnectionReconnect": "丢失与服务器的连接, __time__ 秒后重新连接",
|
||||||
"lostConnectionTry": "现在尝试",
|
"lostConnectionTry": "现在尝试",
|
||||||
"cannotAddSubflowToItself": "无法向其自身添加子流程",
|
"cannotAddSubflowToItself": "无法向其自身添加子流程",
|
||||||
"cannotAddCircularReference": "无法添加子流程 - 循环引用",
|
"cannotAddCircularReference": "无法添加子流程 - 循环引用",
|
||||||
@ -167,14 +187,16 @@
|
|||||||
"clipboard": {
|
"clipboard": {
|
||||||
"clipboard": "剪贴板",
|
"clipboard": "剪贴板",
|
||||||
"nodes": "节点",
|
"nodes": "节点",
|
||||||
"node": "__count__节点",
|
"node": "__count__ 个节点",
|
||||||
"node_plural": "__count__节点",
|
"node_plural": "__count__ 个节点",
|
||||||
"configNode": "__count__配置节点",
|
"configNode": "__count__ 个配置节点",
|
||||||
"configNode_plural": "__count__配置节点",
|
"configNode_plural": "__count__ 个配置节点",
|
||||||
"flow": "__count__流程",
|
"group": "__count__ 个组",
|
||||||
"flow_plural": "__count__流程",
|
"group_plural": "__count__ 个组",
|
||||||
"subflow": "__count__子流程",
|
"flow": "__count__ 个流程",
|
||||||
"subflow_plural": "__count__子流程",
|
"flow_plural": "__count__ 个流程",
|
||||||
|
"subflow": "__count__ 个子流程",
|
||||||
|
"subflow_plural": "__count__ 子流程",
|
||||||
"pasteNodes": "在这里粘贴节点",
|
"pasteNodes": "在这里粘贴节点",
|
||||||
"selectFile": "选择要导入的文件",
|
"selectFile": "选择要导入的文件",
|
||||||
"importNodes": "导入节点",
|
"importNodes": "导入节点",
|
||||||
@ -184,8 +206,11 @@
|
|||||||
"importUnrecognised_plural": "导入了无法识别的类型:",
|
"importUnrecognised_plural": "导入了无法识别的类型:",
|
||||||
"nodesExported": "节点导出到了剪贴板",
|
"nodesExported": "节点导出到了剪贴板",
|
||||||
"nodesImported": "导入:",
|
"nodesImported": "导入:",
|
||||||
"nodeCopied": "已复制__count__个节点",
|
"nodeCopied": "已复制 __count__ 个节点",
|
||||||
"nodeCopied_plural": "已复制__count__个节点",
|
"nodeCopied_plural": "已复制 __count__ 个节点",
|
||||||
|
"groupCopied": "复制 __count__ 个组",
|
||||||
|
"groupCopied_plural": "已复制 __count__ 个groups",
|
||||||
|
"groupStyleCopied": "已复制组风格",
|
||||||
"invalidFlow": "无效的流程: __message__",
|
"invalidFlow": "无效的流程: __message__",
|
||||||
"export": {
|
"export": {
|
||||||
"selected": "已选择的节点",
|
"selected": "已选择的节点",
|
||||||
@ -204,9 +229,9 @@
|
|||||||
"newFlow": "新流程",
|
"newFlow": "新流程",
|
||||||
"errors": {
|
"errors": {
|
||||||
"notArray": "输入的不是JSON数组",
|
"notArray": "输入的不是JSON数组",
|
||||||
"itemNotObject": "输入的流无效 - 项目__index__不是节点对象",
|
"itemNotObject": "输入的流无效 - 项目 __index__ 不是节点对象",
|
||||||
"missingId": "输入的流无效-项 __index__ 缺少'id'属性",
|
"missingId": "输入的流无效-项 __index__ 缺少'id'属性",
|
||||||
"missingType": "输入的流程无效-项__index__缺少'类型'属性"
|
"missingType": "输入的流程无效-项 __index__ 缺少'类型'属性"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"copyMessagePath": "已复制路径",
|
"copyMessagePath": "已复制路径",
|
||||||
@ -250,7 +275,7 @@
|
|||||||
"conflictChecking": "检查是否可以自动合并更改",
|
"conflictChecking": "检查是否可以自动合并更改",
|
||||||
"conflictAutoMerge": "此更改不包括冲突,可以自动合并",
|
"conflictAutoMerge": "此更改不包括冲突,可以自动合并",
|
||||||
"conflictManualMerge": "这些更改包括了在部署之前必须解决的冲突。",
|
"conflictManualMerge": "这些更改包括了在部署之前必须解决的冲突。",
|
||||||
"plusNMore": "+ __count__更多"
|
"plusNMore": "+ __count__ 更多"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eventLog": {
|
"eventLog": {
|
||||||
@ -287,11 +312,11 @@
|
|||||||
"newVersionError": "新版本不包含有效的JSON:"
|
"newVersionError": "新版本不包含有效的JSON:"
|
||||||
},
|
},
|
||||||
"subflow": {
|
"subflow": {
|
||||||
"editSubflowInstance": "编辑子流实例:__name__",
|
"editSubflowInstance": "编辑子流实例: __name__",
|
||||||
"editSubflow": "编辑流程模板: __name__",
|
"editSubflow": "编辑流程模板: __name__",
|
||||||
"edit": "编辑流程模板",
|
"edit": "编辑流程模板",
|
||||||
"subflowInstances": "这个子流程模板有__count__个实例",
|
"subflowInstances": "这个子流程模板有 __count__ 个实例",
|
||||||
"subflowInstances_plural": "这个子流程模板有__count__个实例",
|
"subflowInstances_plural": "这个子流程模板有 __count__ 个实例",
|
||||||
"editSubflowProperties": "编辑属性",
|
"editSubflowProperties": "编辑属性",
|
||||||
"input": "输入:",
|
"input": "输入:",
|
||||||
"output": "输出:",
|
"output": "输出:",
|
||||||
@ -308,17 +333,24 @@
|
|||||||
"multipleInputsToSelection": "<strong>无法创建子流程</strong>: 多个输入到了选择"
|
"multipleInputsToSelection": "<strong>无法创建子流程</strong>: 多个输入到了选择"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"group": {
|
||||||
|
"editGroup": "编辑组: __name__",
|
||||||
|
"errors": {
|
||||||
|
"cannotCreateDiffGroups": "无法使用来自不同组的节点创建组",
|
||||||
|
"cannotAddSubflowPorts": "无法将子流程的端口添加到组"
|
||||||
|
}
|
||||||
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"configEdit": "编辑",
|
"configEdit": "编辑",
|
||||||
"configAdd": "添加",
|
"configAdd": "添加",
|
||||||
"configUpdate": "更新",
|
"configUpdate": "更新",
|
||||||
"configDelete": "删除",
|
"configDelete": "删除",
|
||||||
"nodesUse": "__count__个节点使用此配置",
|
"nodesUse": "__count__ 个节点使用此配置",
|
||||||
"nodesUse_plural": "__count__个节点使用此配置",
|
"nodesUse_plural": "__count__ 个节点使用此配置",
|
||||||
"addNewConfig": "添加新的__type__配置",
|
"addNewConfig": "添加新的 __type__ 配置",
|
||||||
"editNode": "编辑__type__节点",
|
"editNode": "编辑 __type__ 节点",
|
||||||
"editConfig": "编辑__type__配置",
|
"editConfig": "编辑 __type__ 配置",
|
||||||
"addNewType": "添加新的__type__节点",
|
"addNewType": "添加新的 __type__ 节点",
|
||||||
"nodeProperties": "节点属性",
|
"nodeProperties": "节点属性",
|
||||||
"label": "标签",
|
"label": "标签",
|
||||||
"color": "颜色",
|
"color": "颜色",
|
||||||
@ -337,6 +369,7 @@
|
|||||||
"locale": "选择界面语言",
|
"locale": "选择界面语言",
|
||||||
"icon": "图标",
|
"icon": "图标",
|
||||||
"inputType": "输入类型",
|
"inputType": "输入类型",
|
||||||
|
"selectType": "选择类型...",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"input": "输入",
|
"input": "输入",
|
||||||
"select": "选择",
|
"select": "选择",
|
||||||
@ -351,7 +384,8 @@
|
|||||||
"bool": "布尔",
|
"bool": "布尔",
|
||||||
"json": "JSON",
|
"json": "JSON",
|
||||||
"bin": "buffer",
|
"bin": "buffer",
|
||||||
"env": "环境变量"
|
"env": "环境变量",
|
||||||
|
"cred": "证书"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"input": "输入",
|
"input": "输入",
|
||||||
@ -381,7 +415,7 @@
|
|||||||
"scope": "范围",
|
"scope": "范围",
|
||||||
"unassigned": "未分配",
|
"unassigned": "未分配",
|
||||||
"global": "全局",
|
"global": "全局",
|
||||||
"workspace": "工作组",
|
"workspace": "工作区",
|
||||||
"selectAll": "选择所有节点",
|
"selectAll": "选择所有节点",
|
||||||
"selectAllConnected": "选择所有连接的节点",
|
"selectAllConnected": "选择所有连接的节点",
|
||||||
"addRemoveNode": "从选择中添加/删除节点",
|
"addRemoveNode": "从选择中添加/删除节点",
|
||||||
@ -460,33 +494,33 @@
|
|||||||
"times": {
|
"times": {
|
||||||
"seconds": "秒前",
|
"seconds": "秒前",
|
||||||
"minutes": "分前",
|
"minutes": "分前",
|
||||||
"minutesV": "__count__分前",
|
"minutesV": "__count__ 分前",
|
||||||
"hoursV": "__count__小时前",
|
"hoursV": "__count__ 小时前",
|
||||||
"hoursV_plural": "__count__小时前",
|
"hoursV_plural": "__count__ 小时前",
|
||||||
"daysV": "__count__天前",
|
"daysV": "__count__ 天前",
|
||||||
"daysV_plural": "__count__天前",
|
"daysV_plural": "__count__ 天前",
|
||||||
"weeksV": "__count__周前",
|
"weeksV": "__count__ 周前",
|
||||||
"weeksV_plural": "__count__周前",
|
"weeksV_plural": "__count__ 周前",
|
||||||
"monthsV": "__count__月前",
|
"monthsV": "__count__ 月前",
|
||||||
"monthsV_plural": "__count__月前",
|
"monthsV_plural": "__count__ 月前",
|
||||||
"yearsV": "__count__年前",
|
"yearsV": "__count__ 年前",
|
||||||
"yearsV_plural": "__count__年前",
|
"yearsV_plural": "__count__ 年前",
|
||||||
"yearMonthsV": "__y__年, __count__月前",
|
"yearMonthsV": "__y__ 年, __count__ 月前",
|
||||||
"yearMonthsV_plural": "__y__年, __count__月前",
|
"yearMonthsV_plural": "__y__ 年, __count__ 月前",
|
||||||
"yearsMonthsV": "__y__年, __count__月前",
|
"yearsMonthsV": "__y__ 年, __count__ 月前",
|
||||||
"yearsMonthsV_plural": "__y__年, __count__月前"
|
"yearsMonthsV_plural": "__y__ 年, __count__ 月前"
|
||||||
},
|
},
|
||||||
"nodeCount": "__label__个节点",
|
"nodeCount": "__label__ 个节点",
|
||||||
"nodeCount_plural": "__label__个节点",
|
"nodeCount_plural": "__label__ 个节点",
|
||||||
"moduleCount": "__count__个可用模块",
|
"moduleCount": "__count__ 个可用模块",
|
||||||
"moduleCount_plural": "__count__个可用模块",
|
"moduleCount_plural": "__count__ 个可用模块",
|
||||||
"inuse": "使用中",
|
"inuse": "使用中",
|
||||||
"enableall": "全部启用",
|
"enableall": "全部启用",
|
||||||
"disableall": "全部禁用",
|
"disableall": "全部禁用",
|
||||||
"enable": "启用",
|
"enable": "启用",
|
||||||
"disable": "禁用",
|
"disable": "禁用",
|
||||||
"remove": "移除",
|
"remove": "移除",
|
||||||
"update": "更新至__version__版本",
|
"update": "更新至 __version__ 版本",
|
||||||
"updated": "已更新",
|
"updated": "已更新",
|
||||||
"install": "安装",
|
"install": "安装",
|
||||||
"installed": "已安装",
|
"installed": "已安装",
|
||||||
@ -498,7 +532,7 @@
|
|||||||
"sort": "排序:",
|
"sort": "排序:",
|
||||||
"sortAZ": "a-z顺序",
|
"sortAZ": "a-z顺序",
|
||||||
"sortRecent": "日期顺序",
|
"sortRecent": "日期顺序",
|
||||||
"more": "增加__count__个",
|
"more": "增加 __count__ 个",
|
||||||
"errors": {
|
"errors": {
|
||||||
"catalogLoadFailed": "无法加载节点目录。<br>查看浏览器控制台了解更多信息",
|
"catalogLoadFailed": "无法加载节点目录。<br>查看浏览器控制台了解更多信息",
|
||||||
"installFailed": "无法安装: __module__<br>__message__<br>查看日志了解更多信息",
|
"installFailed": "无法安装: __module__<br>__message__<br>查看日志了解更多信息",
|
||||||
@ -539,6 +573,7 @@
|
|||||||
"label": "信息",
|
"label": "信息",
|
||||||
"node": "节点",
|
"node": "节点",
|
||||||
"type": "类型",
|
"type": "类型",
|
||||||
|
"group": "组",
|
||||||
"module": "模组",
|
"module": "模组",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"status": "状态",
|
"status": "状态",
|
||||||
@ -560,8 +595,30 @@
|
|||||||
"subflowDesc": "子流程描述",
|
"subflowDesc": "子流程描述",
|
||||||
"nodeHelp": "节点帮助",
|
"nodeHelp": "节点帮助",
|
||||||
"none": "无",
|
"none": "无",
|
||||||
"arrayItems": "__count__个项目",
|
"arrayItems": "__count__ 个项目",
|
||||||
"showTips": "您可以从设置面板启用提示信息"
|
"showTips": "您可以从设置面板启用提示信息",
|
||||||
|
"outline": "大纲",
|
||||||
|
"empty": "空的",
|
||||||
|
"globalConfig": "全局配置节点",
|
||||||
|
"triggerAction": "触发动作",
|
||||||
|
"find": "在工作区中查找",
|
||||||
|
"search": {
|
||||||
|
"configNodes": "配置节点",
|
||||||
|
"unusedConfigNodes": "未使用的配置节点",
|
||||||
|
"invalidNodes": "无效的节点",
|
||||||
|
"uknownNodes": "未知的节点",
|
||||||
|
"unusedSubflows": "未使用的子流程"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"name": "帮助",
|
||||||
|
"label": "帮助",
|
||||||
|
"search": "搜索帮助",
|
||||||
|
"nodeHelp": "节点帮助",
|
||||||
|
"showHelp": "显示帮助",
|
||||||
|
"showInOutline": "在大纲中显示",
|
||||||
|
"showTopics": "显示主题",
|
||||||
|
"noHelp": "未选择帮助主题"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"name": "配置节点",
|
"name": "配置节点",
|
||||||
@ -614,9 +671,9 @@
|
|||||||
"removeFromProject": "从项目中删除",
|
"removeFromProject": "从项目中删除",
|
||||||
"addToProject": "添加到项目",
|
"addToProject": "添加到项目",
|
||||||
"files": "文件",
|
"files": "文件",
|
||||||
"package": "包",
|
|
||||||
"flow": "流程",
|
"flow": "流程",
|
||||||
"credentials": "证书",
|
"credentials": "证书",
|
||||||
|
"package": "包",
|
||||||
"packageCreate": "保存更改后将创建文件",
|
"packageCreate": "保存更改后将创建文件",
|
||||||
"fileNotExist": "文件不存在",
|
"fileNotExist": "文件不存在",
|
||||||
"selectFile": "选择文件",
|
"selectFile": "选择文件",
|
||||||
@ -628,7 +685,7 @@
|
|||||||
"changeTheEncryptionKey": "更改加密密钥",
|
"changeTheEncryptionKey": "更改加密密钥",
|
||||||
"currentKey": "当前密钥",
|
"currentKey": "当前密钥",
|
||||||
"newKey": "新密钥",
|
"newKey": "新密钥",
|
||||||
"credentialsAlert": "这将删除所有现有凭证",
|
"credentialsAlert": "这将删除所有现有证书",
|
||||||
"versionControl": "版本控制",
|
"versionControl": "版本控制",
|
||||||
"branches": "分支",
|
"branches": "分支",
|
||||||
"noBranches": "没有分支",
|
"noBranches": "没有分支",
|
||||||
@ -668,7 +725,7 @@
|
|||||||
"copyPublicKey": "将公钥复制到剪贴板",
|
"copyPublicKey": "将公钥复制到剪贴板",
|
||||||
"delete": "删除密钥",
|
"delete": "删除密钥",
|
||||||
"gitConfig": "Git配置",
|
"gitConfig": "Git配置",
|
||||||
"deleteConfirm": "您确定要删除SSH密钥__name__吗?这不能被撤消。"
|
"deleteConfirm": "您确定要删除SSH密钥 __name__ 吗?这不能被撤消。"
|
||||||
},
|
},
|
||||||
"versionControl": {
|
"versionControl": {
|
||||||
"unstagedChanges": "未暂存的变更",
|
"unstagedChanges": "未暂存的变更",
|
||||||
@ -722,24 +779,24 @@
|
|||||||
"pullChanges": "拉取更改",
|
"pullChanges": "拉取更改",
|
||||||
"history": "历史",
|
"history": "历史",
|
||||||
"projectHistory": "项目历史",
|
"projectHistory": "项目历史",
|
||||||
"daysAgo": "__count__天前",
|
"daysAgo": "__count__ 天前",
|
||||||
"daysAgo_plural": "__count__天前",
|
"daysAgo_plural": "__count__ 天前",
|
||||||
"hoursAgo": "__count__小时前",
|
"hoursAgo": "__count__ 小时前",
|
||||||
"hoursAgo_plural": "__count__小时前",
|
"hoursAgo_plural": "__count__ 小时前",
|
||||||
"minsAgo": "__count__分钟前",
|
"minsAgo": "__count__ 分钟前",
|
||||||
"minsAgo_plural": "__count__分钟前",
|
"minsAgo_plural": "__count__ 分钟前",
|
||||||
"secondsAgo": "秒前",
|
"secondsAgo": "秒前",
|
||||||
"notTracking": "您的本地分支当前未跟踪一个远程分支。",
|
"notTracking": "您的本地分支当前未跟踪一个远程分支。",
|
||||||
"statusUnmergedChanged": "您的仓库中有未合并的更改。您需要解决冲突并提交结果。",
|
"statusUnmergedChanged": "您的仓库中有未合并的更改。您需要解决冲突并提交结果。",
|
||||||
"repositoryUpToDate": "您的仓库是最新的。",
|
"repositoryUpToDate": "您的仓库是最新的。",
|
||||||
"commitsAhead": "您的存储库领先远程仓库__count__次提交。您现在可以推送这些提交。",
|
"commitsAhead": "您的存储库领先远程仓库 __count__ 次提交。您现在可以推送这些提交。",
|
||||||
"commitsAhead_plural": "您的存储库领先远程仓库__count__次提交。您现在可以推送这些提交。",
|
"commitsAhead_plural": "您的存储库领先远程仓库 __count__ 次提交。您现在可以推送这些提交。",
|
||||||
"commitsBehind": "您的存储库落后远程仓库__count__次提交。您现在可以拉取这些提交。",
|
"commitsBehind": "您的存储库落后远程仓库 __count__ 次提交。您现在可以拉取这些提交。",
|
||||||
"commitsBehind_plural": "您的存储库落后远程仓库__count__次提交。您现在可以拉取这些提交。",
|
"commitsBehind_plural": "您的存储库落后远程仓库 __count__ 次提交。您现在可以拉取这些提交。",
|
||||||
"commitsAheadAndBehind1": "您的存储库落后远程仓库__count__次提交",
|
"commitsAheadAndBehind1": "您的存储库落后远程仓库 __count__ 次提交",
|
||||||
"commitsAheadAndBehind1_plural": "您的存储库落后远程仓库__count__次提交",
|
"commitsAheadAndBehind1_plural": "您的存储库落后远程仓库 __count__ 次提交",
|
||||||
"commitsAheadAndBehind2": "领先远程仓库__count__次提交。",
|
"commitsAheadAndBehind2": "领先远程仓库 __count__ 次提交。",
|
||||||
"commitsAheadAndBehind2_plural": "领先远程仓库__count__次提交。",
|
"commitsAheadAndBehind2_plural": "领先远程仓库 __count__ 次提交。",
|
||||||
"commitsAheadAndBehind3": "您必须先拉取远程提交,然后才能进行推送。",
|
"commitsAheadAndBehind3": "您必须先拉取远程提交,然后才能进行推送。",
|
||||||
"commitsAheadAndBehind3_plural": "您必须先拉取远程提交,然后才能进行推送。",
|
"commitsAheadAndBehind3_plural": "您必须先拉取远程提交,然后才能进行推送。",
|
||||||
"refreshCommitHistory": "刷新提交历史",
|
"refreshCommitHistory": "刷新提交历史",
|
||||||
@ -757,7 +814,8 @@
|
|||||||
"bin": "二进制流",
|
"bin": "二进制流",
|
||||||
"date": "时间戳",
|
"date": "时间戳",
|
||||||
"jsonata": "表达式",
|
"jsonata": "表达式",
|
||||||
"env": "环境变量"
|
"env": "环境变量",
|
||||||
|
"cred": "证书"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"editableList": {
|
"editableList": {
|
||||||
@ -977,7 +1035,8 @@
|
|||||||
"passphrase": "密码短语",
|
"passphrase": "密码短语",
|
||||||
"retry": "重试",
|
"retry": "重试",
|
||||||
"update-failed": "无法更新身份验证",
|
"update-failed": "无法更新身份验证",
|
||||||
"unhandled": "未处理的错误响应"
|
"unhandled": "未处理的错误响应",
|
||||||
|
"host-key-verify-failed": "<p>主机密钥验证失败。</p><p>无法验证存储库主机密钥。请更新您的<code>known_hosts</code>文件,然后重试。</p>"
|
||||||
},
|
},
|
||||||
"create-branch-list": {
|
"create-branch-list": {
|
||||||
"invalid": "无效的分支",
|
"invalid": "无效的分支",
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"$string": {
|
"$string": {
|
||||||
"args": "arg",
|
"args": "arg",
|
||||||
"desc": "通过以下的类型转换规则将参数*arg*转换成字符串:\n\n - 字符串不转换。\n -函数转换成空的字符串。\n - JSON的值无法用数字表示所以用无限大或者NaN(非数)表示。\n - 用’JSON.stringify’函数将其他值转换成JSON字符串。"
|
"desc": "通过以下的类型转换规则将参数 *arg* 转换成字符串:\n\n - 字符串不转换。\n -函数转换成空的字符串。\n - JSON的值无法用数字表示所以用无限大或者NaN(非数)表示。\n - 用 `JSON.stringify` 函数将其他值转换成JSON字符串。"
|
||||||
},
|
},
|
||||||
"$length": {
|
"$length": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "输出字符串’str’的字数。如果’str’不是字符串,抛出错误。"
|
"desc": "输出字符串 `str` 的字数。如果 `str` 不是字符串,抛出错误。"
|
||||||
},
|
},
|
||||||
"$substring": {
|
"$substring": {
|
||||||
"args": "str, start[, length]",
|
"args": "str, start[, length]",
|
||||||
"desc": "输出`start`位置后的的首次出现的包括`str`的子字符串。 如果`length`被指定,那么的字符串中将只包括前`length`个文字。如果`start`是负数则输出从`str`末尾开始的`length`个文字"
|
"desc": "输出 `start` 位置后的的首次出现的包括 `str` 的子字符串。 如果 `length` 被指定,那么的字符串中将只包括前 `length` 个文字。如果 `start` 是负数则输出从 `str` 末尾开始的 `length` 个文字"
|
||||||
},
|
},
|
||||||
"$substringBefore": {
|
"$substringBefore": {
|
||||||
"args": "str, chars",
|
"args": "str, chars",
|
||||||
@ -17,11 +17,11 @@
|
|||||||
},
|
},
|
||||||
"$substringAfter": {
|
"$substringAfter": {
|
||||||
"args": "str, chars",
|
"args": "str, chars",
|
||||||
"desc": "输出’str’中首次出现的’chars’之后的子字符串,如果’str’中不包括’chars’则输出’str’。"
|
"desc": "输出 `str` 中首次出现的 `chars` 之后的子字符串,如果 `str` 中不包括 `chars` 则输出 `str` 。"
|
||||||
},
|
},
|
||||||
"$uppercase": {
|
"$uppercase": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "`将’str’中的所有字母变为大写后输出。"
|
"desc": "将 `str` 中的所有字母变为大写后输出。"
|
||||||
},
|
},
|
||||||
"$lowercase": {
|
"$lowercase": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
@ -29,27 +29,27 @@
|
|||||||
},
|
},
|
||||||
"$trim": {
|
"$trim": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "将以下步骤应用于`str`来去除所有空白文字并实现标准化。\n\n – 将全部tab制表符、回车键、换行字符用空白代替。\n- 将连续的空白文字变成一个空白文字。\n- 消除开头和末尾的空白文字。\n\n如果`str`没有被指定(即在无输入参数的情况下调用本函数),将上下文的值作为`str`来使用。 如果`str` 不是字符串则抛出错误。"
|
"desc": "将以下步骤应用于 `str` 来去除所有空白文字并实现标准化。\n\n – 将全部tab制表符、回车键、换行字符用空白代替。\n- 将连续的空白文字变成一个空白文字。\n- 消除开头和末尾的空白文字。\n\n如果 `str` 没有被指定(即在无输入参数的情况下调用本函数),将上下文的值作为 `str` 来使用。 如果 `str` 不是字符串则抛出错误。"
|
||||||
},
|
},
|
||||||
"$contains": {
|
"$contains": {
|
||||||
"args": "str, pattern",
|
"args": "str, pattern",
|
||||||
"desc": "字符串`str` 和 `pattern`匹配的话输出`true`,不匹配的情况下输出 `false`。 不指定`str`的情况下(比如用一个参数调用本函数时)、将上下文的值作为`str`来使用。参数 `pattern`可以为字符串或正则表达。"
|
"desc": "字符串 `str` 和 `pattern` 匹配的话输出 `true` ,不匹配的情况下输出 `false` 。 不指定 `str` 的情况下(比如用一个参数调用本函数时)、将上下文的值作为 `str` 来使用。参数 `pattern` 可以为字符串或正则表达。"
|
||||||
},
|
},
|
||||||
"$split": {
|
"$split": {
|
||||||
"args": "str[, separator][, limit]",
|
"args": "str[, separator][, limit]",
|
||||||
"desc": "将参数`str`分解成由子字符串组成的数组。 如果`str`不是字符串抛出错误。可以省略的参数 `separator`中指定字符串`str`的分隔符。分隔符可以是文字或正则表达式。在不指定`separator`的情况下、将分隔符看作空的字符串并把`str`拆分成由单个字母组成的数组。如果`separator`不是字符串则抛出错误。在可省略的参数`limit`中指定分割后的子字符串的最大个数。超出个数的子字符串将被舍弃。如果`limit`没有被指定,`str` 将不考虑子字符串的个数而将字符串完全分隔。如果`limit`是负数则抛出错误。"
|
"desc": "将参数 `str` 分解成由子字符串组成的数组。 如果 `str` 不是字符串抛出错误。可以省略的参数 `separator` 中指定字符串 `str` 的分隔符。分隔符可以是文字或正则表达式。在不指定 `separator` 的情况下、将分隔符看作空的字符串并把 `str` 拆分成由单个字母组成的数组。如果 `separator` 不是字符串则抛出错误。在可省略的参数 `limit` 中指定分割后的子字符串的最大个数。超出个数的子字符串将被舍弃。如果 `limit` 没有被指定,`str` 将不考虑子字符串的个数而将字符串完全分隔。如果 `limit` 是负数则抛出错误。"
|
||||||
},
|
},
|
||||||
"$join": {
|
"$join": {
|
||||||
"args": "array[, separator]",
|
"args": "array[, separator]",
|
||||||
"desc": "用可以省略的参数 `separator`来把多个字符串连接。如果`array`不是字符串则抛出错误。 如果没有指定`separator`,则用空字符串来连接字符(即字符串之间没有`separator`)。 如果`separator`不是字符则抛出错误。"
|
"desc": "用可以省略的参数 `separator` 来把多个字符串连接。如果 `array` 不是字符串则抛出错误。 如果没有指定 `separator` ,则用空字符串来连接字符(即字符串之间没有 `separator` )。 如果 `separator` 不是字符则抛出错误。"
|
||||||
},
|
},
|
||||||
"$match": {
|
"$match": {
|
||||||
"args": "str, pattern [, limit]",
|
"args": "str, pattern [, limit]",
|
||||||
"desc": "对字符串`str`使用正则表达式`pattern`并输出与`str`相匹配的部分信息。"
|
"desc": "对字符串 `str` 使用正则表达式 `pattern` 并输出与 `str` 相匹配的部分信息。"
|
||||||
},
|
},
|
||||||
"$replace": {
|
"$replace": {
|
||||||
"args": "str, pattern, replacement [, limit]",
|
"args": "str, pattern, replacement [, limit]",
|
||||||
"desc": "在字符串`str`中搜索`pattern`并用`replacement`来替换。\n\n可选参数`limit`用来指定替换次数的上限。"
|
"desc": "在字符串 `str` 中搜索 `pattern` 并用 `replacement` 来替换。\n\n可选参数 `limit` 用来指定替换次数的上限。"
|
||||||
},
|
},
|
||||||
"$now": {
|
"$now": {
|
||||||
"args": "",
|
"args": "",
|
||||||
@ -65,31 +65,31 @@
|
|||||||
},
|
},
|
||||||
"$number": {
|
"$number": {
|
||||||
"args": "arg",
|
"args": "arg",
|
||||||
"desc": "用下述的规则将参数 `arg`转换为数值。:\n\n – 数值不做转换。\n – 将字符串中合法的JSON数値表示转换成数値。\n – 其他形式的值则抛出错误。"
|
"desc": "用下述的规则将参数 `arg` 转换为数值。:\n\n – 数值不做转换。\n – 将字符串中合法的JSON数値表示转换成数値。\n – 其他形式的值则抛出错误。"
|
||||||
},
|
},
|
||||||
"$abs": {
|
"$abs": {
|
||||||
"args": "number",
|
"args": "number",
|
||||||
"desc": "输出参数`number`的绝对值。"
|
"desc": "输出参数 `number` 的绝对值。"
|
||||||
},
|
},
|
||||||
"$floor": {
|
"$floor": {
|
||||||
"args": "number",
|
"args": "number",
|
||||||
"desc": "输出比`number`的值小的最大整数。"
|
"desc": "输出比 `number` 的值小的最大整数。"
|
||||||
},
|
},
|
||||||
"$ceil": {
|
"$ceil": {
|
||||||
"args": "number",
|
"args": "number",
|
||||||
"desc": "输出比`number`的值大的最小整数。"
|
"desc": "输出比 `number` 的值大的最小整数。"
|
||||||
},
|
},
|
||||||
"$round": {
|
"$round": {
|
||||||
"args": "number [, precision]",
|
"args": "number [, precision]",
|
||||||
"desc": "输出四舍五入后的参数`number`。可省略的参数 `precision`指定四舍五入后小数点下的位数。"
|
"desc": "输出四舍五入后的参数 `number` 。可省略的参数 `precision` 指定四舍五入后小数点下的位数。"
|
||||||
},
|
},
|
||||||
"$power": {
|
"$power": {
|
||||||
"args": "base, exponent",
|
"args": "base, exponent",
|
||||||
"desc": "输出底数`base`的`exponent`次幂。"
|
"desc": "输出底数 `base` 的 `exponent` 次幂。"
|
||||||
},
|
},
|
||||||
"$sqrt": {
|
"$sqrt": {
|
||||||
"args": "number",
|
"args": "number",
|
||||||
"desc": "输出参数 `number`的平方根。"
|
"desc": "输出参数 `number` 的平方根。"
|
||||||
},
|
},
|
||||||
"$random": {
|
"$random": {
|
||||||
"args": "",
|
"args": "",
|
||||||
@ -97,35 +97,35 @@
|
|||||||
},
|
},
|
||||||
"$millis": {
|
"$millis": {
|
||||||
"args": "",
|
"args": "",
|
||||||
"desc": "返回从UNIX时间 (1970年1月1日 UTC/GMT的午夜)开始到现在的毫秒数。在同一个表达式的测试中所有对`$millis()`的调用将会返回相同的值。"
|
"desc": "返回从UNIX时间 (1970年1月1日 UTC/GMT的午夜)开始到现在的毫秒数。在同一个表达式的测试中所有对 `$millis()` 的调用将会返回相同的值。"
|
||||||
},
|
},
|
||||||
"$sum": {
|
"$sum": {
|
||||||
"args": "array",
|
"args": "array",
|
||||||
"desc": "输出数组`array`的总和。如果`array`不是数值则抛出错误。"
|
"desc": "输出数组 `array` 的总和。如果 `array` 不是数值则抛出错误。"
|
||||||
},
|
},
|
||||||
"$max": {
|
"$max": {
|
||||||
"args": "array",
|
"args": "array",
|
||||||
"desc": "输出数组`array`的最大值。如果`array`不是数值则抛出错误。"
|
"desc": "输出数组 `array` 的最大值。如果 `array` 不是数值则抛出错误。"
|
||||||
},
|
},
|
||||||
"$min": {
|
"$min": {
|
||||||
"args": "array",
|
"args": "array",
|
||||||
"desc": "输出数组`array`的最小值。如果`array`不是数值则抛出错误。。"
|
"desc": "输出数组 `array` 的最小值。如果 `array` 不是数值则抛出错误。。"
|
||||||
},
|
},
|
||||||
"$average": {
|
"$average": {
|
||||||
"args": "array",
|
"args": "array",
|
||||||
"desc": "输出数组`array`的平均数。如果`array`不是数值则抛出错误。。"
|
"desc": "输出数组 `array` 的平均数。如果 `array` 不是数值则抛出错误。。"
|
||||||
},
|
},
|
||||||
"$boolean": {
|
"$boolean": {
|
||||||
"args": "arg",
|
"args": "arg",
|
||||||
"desc": "用下述规则将数据转换成布尔值。:\n\n - 不转换布尔值`Boolean`。\n – 将空的字符串`string`转换为`false`\n – 将不为空的字符串`string`转换为`true`\n – 将为0的数字`number`转换成`false`\n –将不为0的数字`number`转换成`true`\n –将`null`转换成`false`\n –将空的数组`array`转换成`false`\n –如果数组`array`中含有可以转换成`true`的要素则转换成`true`\n –如果`array`中没有可转换成`true`的要素则转换成`false`\n – 空的对象`object`转换成`false`\n – 非空的对象`object`转换成`true`\n –将函数`function`转换成`false`"
|
"desc": "用下述规则将数据转换成布尔值。:\n\n - 不转换布尔值 `Boolean` 。\n – 将空的字符串 `string` 转换为 `false` \n – 将不为空的字符串 `string` 转换为 `true` \n – 将为0的数字 `number` 转换成 `false` \n –将不为0的数字 `number` 转换成 `true` \n –将 `null` 转换成 `false` \n –将空的数组 `array` 转换成 `false` \n –如果数组 `array` 中含有可以转换成 `true` 的要素则转换成 `true` \n –如果 `array` 中没有可转换成 `true` 的要素则转换成 `false` \n – 空的对象 `object` 转换成 `false` \n – 非空的对象 `object` 转换成 `true` \n –将函数 `function` 转换成 `false` "
|
||||||
},
|
},
|
||||||
"$not": {
|
"$not": {
|
||||||
"args": "arg",
|
"args": "arg",
|
||||||
"desc": "输出做取反运算后的布尔值。首先将`arg`转换为布尔值。"
|
"desc": "输出做取反运算后的布尔值。首先将 `arg` 转换为布尔值。"
|
||||||
},
|
},
|
||||||
"$exists": {
|
"$exists": {
|
||||||
"args": "arg",
|
"args": "arg",
|
||||||
"desc": "如果算式`arg`的值存在则输出`true`。如果算式的值不存在(比如指向不存在区域的引用)则输出`false`。"
|
"desc": "如果算式 `arg` 的值存在则输出 `true` 。如果算式的值不存在(比如指向不存在区域的引用)则输出 `false` 。"
|
||||||
},
|
},
|
||||||
"$count": {
|
"$count": {
|
||||||
"args": "array",
|
"args": "array",
|
||||||
@ -137,15 +137,15 @@
|
|||||||
},
|
},
|
||||||
"$sort": {
|
"$sort": {
|
||||||
"args": "array [, function]",
|
"args": "array [, function]",
|
||||||
"desc": "输出排序后的数组`array`。\n\n如果使用了比较函数`function`,则下述两个参数需要被指定。\n\n`function(left, right)`\n\n该比较函数是为了比较left和right两个值而被排序算法调用的。如果用户希望left的值被置于right的值之后,那么该函数必须输出布尔值`true`来表示位置交换。而在不需要位置交换时函数必须输出`false`。"
|
"desc": "输出排序后的数组 `array` 。\n\n如果使用了比较函数 `function` ,则下述两个参数需要被指定。\n\n `function(left, right)` \n\n该比较函数是为了比较left和right两个值而被排序算法调用的。如果用户希望left的值被置于right的值之后,那么该函数必须输出布尔值 `true` 来表示位置交换。而在不需要位置交换时函数必须输出 `false` 。"
|
||||||
},
|
},
|
||||||
"$reverse": {
|
"$reverse": {
|
||||||
"args": "array",
|
"args": "array",
|
||||||
"desc": "输出倒序后的数组`array`。"
|
"desc": "输出倒序后的数组 `array` 。"
|
||||||
},
|
},
|
||||||
"$shuffle": {
|
"$shuffle": {
|
||||||
"args": "array",
|
"args": "array",
|
||||||
"desc": "输出随机排序后的数组 `array`。"
|
"desc": "输出随机排序后的数组 `array` 。"
|
||||||
},
|
},
|
||||||
"$zip": {
|
"$zip": {
|
||||||
"args": "array, ...",
|
"args": "array, ...",
|
||||||
@ -157,35 +157,35 @@
|
|||||||
},
|
},
|
||||||
"$lookup": {
|
"$lookup": {
|
||||||
"args": "object, key",
|
"args": "object, key",
|
||||||
"desc": "输出对象中与参数`key`对应的值。如果第一个参数`object`是数组,那么数组中所有的对象都将被搜索并输出这些对象中与参数`key`对应的值。"
|
"desc": "输出对象中与参数 `key` 对应的值。如果第一个参数 `object` 是数组,那么数组中所有的对象都将被搜索并输出这些对象中与参数 `key` 对应的值。"
|
||||||
},
|
},
|
||||||
"$spread": {
|
"$spread": {
|
||||||
"args": "object",
|
"args": "object",
|
||||||
"desc": "将对象中的键值对分隔成每个要素中只含有一个键值对的数组。如果参数`object`是数组,那么返回值的数组中包含所有对象中的键值对。"
|
"desc": "将对象中的键值对分隔成每个要素中只含有一个键值对的数组。如果参数 `object` 是数组,那么返回值的数组中包含所有对象中的键值对。"
|
||||||
},
|
},
|
||||||
"$merge": {
|
"$merge": {
|
||||||
"args": "array<object>",
|
"args": "array<object>",
|
||||||
"desc": "将输入数组`objects`中所有的键值对合并到一个`object`中并返回。如果输入数组的要素中含有重复的键,则返回的`object`中将只包含数组中最后出现要素的值。如果输入数组中包括对象以外的元素,则抛出错误。"
|
"desc": "将输入数组 `objects` 中所有的键值对合并到一个 `object` 中并返回。如果输入数组的要素中含有重复的键,则返回的 `object` 中将只包含数组中最后出现要素的值。如果输入数组中包括对象以外的元素,则抛出错误。"
|
||||||
},
|
},
|
||||||
"$sift": {
|
"$sift": {
|
||||||
"args": "object, function",
|
"args": "object, function",
|
||||||
"desc": "输出参数`object`中符合`function`的键值对。\n\n`function`必须含有下述参数。\n\n`function(value [, key [, object]])`"
|
"desc": "输出参数 `object` 中符合 `function` 的键值对。\n\n `function` 必须含有下述参数。\n\n `function(value [, key [, object]])` "
|
||||||
},
|
},
|
||||||
"$each": {
|
"$each": {
|
||||||
"args": "object, function",
|
"args": "object, function",
|
||||||
"desc": "将函数`function`应用于`object`中的所有键值对并输出由所有返回值组成的数组。"
|
"desc": "将函数 `function` 应用于 `object` 中的所有键值对并输出由所有返回值组成的数组。"
|
||||||
},
|
},
|
||||||
"$map": {
|
"$map": {
|
||||||
"args": "array, function",
|
"args": "array, function",
|
||||||
"desc": "将函数`function`应用于数组`array`中所有的值并输出由返回值组成的数组。\n\n`function`中必须含有下述参数。\n\n`function(value [, index [, array]])`"
|
"desc": "将函数 `function` 应用于数组 `array` 中所有的值并输出由返回值组成的数组。\n\n `function` 中必须含有下述参数。\n\n`function(value [, index [, array]])` "
|
||||||
},
|
},
|
||||||
"$filter": {
|
"$filter": {
|
||||||
"args": "array, function",
|
"args": "array, function",
|
||||||
"desc": "输出数组`array`中符合函数`function`条件的值组成的数组。\n\n`function`必须包括下述参数。\n\n`function(value [, index [, array]])`"
|
"desc": "输出数组 `array` 中符合函数 `function` 条件的值组成的数组。\n\n `function` 必须包括下述参数。\n\n `function(value [, index [, array]])`"
|
||||||
},
|
},
|
||||||
"$reduce": {
|
"$reduce": {
|
||||||
"args": "array, function [, init]",
|
"args": "array, function [, init]",
|
||||||
"desc": "将`function`依次应用于数组中的各要素值。 其中,前一个要素值的计算结果将参与到下一次的函数运算中。。\n\n函数`function`接受两个参数并作为中缀表示法中的操作符。\n\n可省略的参数`init`将作为运算的初始值。"
|
"desc": "将 `function` 依次应用于数组中的各要素值。 其中,前一个要素值的计算结果将参与到下一次的函数运算中。。\n\n函数 `function` 接受两个参数并作为中缀表示法中的操作符。\n\n可省略的参数 `init` 将作为运算的初始值。"
|
||||||
},
|
},
|
||||||
"$flowContext": {
|
"$flowContext": {
|
||||||
"args": "string",
|
"args": "string",
|
||||||
@ -197,7 +197,7 @@
|
|||||||
},
|
},
|
||||||
"$pad": {
|
"$pad": {
|
||||||
"args": "string, width [, char]",
|
"args": "string, width [, char]",
|
||||||
"desc": "根据需要,向字符串`string`的副本中填充文字使该字符串的字数达到`width`的绝对值并返回填充文字后的字符串。\n\n如果`width`的值为正,则向字符串`string`的右侧填充文字,如果`width`为负,则向字符串`string`的左侧填充文字。\n\n可选参数`char`用来指定填充的文字。如果未指定该参数,则填充空白文字。"
|
"desc": "根据需要,向字符串 `string` 的副本中填充文字使该字符串的字数达到 `width` 的绝对值并返回填充文字后的字符串。\n\n如果 `width` 的值为正,则向字符串 `string` 的右侧填充文字,如果 `width` 为负,则向字符串 `string` 的左侧填充文字。\n\n可选参数 `char` 用来指定填充的文字。如果未指定该参数,则填充空白文字。"
|
||||||
},
|
},
|
||||||
"$fromMillis": {
|
"$fromMillis": {
|
||||||
"args": "number",
|
"args": "number",
|
||||||
@ -205,15 +205,15 @@
|
|||||||
},
|
},
|
||||||
"$formatNumber": {
|
"$formatNumber": {
|
||||||
"args": "number, picture [, options]",
|
"args": "number, picture [, options]",
|
||||||
"desc": "将`number`转换成具有`picture`所指定的数值格式的字符串。\n\n此函数的功能与XPath F&O 3.1规格中定义的XPath/XQuery函数的fn:format-number功能相一致。参数`picture`用于指定数值的转换格式,其语法与fn:format-number中的定义一致。\n\n可选的第三参数`options`用来覆盖默认的局部环境格式,如小数点分隔符。如果指定该参数,那么该参数必须是包含name/value对的对象,并且name/value对必须符合XPath F&O 3.1规格中记述的数值格式。"
|
"desc": "将 `number` 转换成具有 `picture` 所指定的数值格式的字符串。\n\n此函数的功能与XPath F&O 3.1规格中定义的XPath/XQuery函数的fn:format-number功能相一致。参数 `picture` 用于指定数值的转换格式,其语法与fn:format-number中的定义一致。\n\n可选的第三参数 `options` 用来覆盖默认的局部环境格式,如小数点分隔符。如果指定该参数,那么该参数必须是包含name/value对的对象,并且name/value对必须符合XPath F&O 3.1规格中记述的数值格式。"
|
||||||
},
|
},
|
||||||
"$formatBase": {
|
"$formatBase": {
|
||||||
"args": "number [, radix]",
|
"args": "number [, radix]",
|
||||||
"desc": "将`number`变换为以参数`radix`的值为基数形式的字符串。如果不指定`radix`的值,则默认基数为10。指定的`radix`值必须在2~36之间,否则抛出错误。"
|
"desc": "将 `number` 变换为以参数 `radix` 的值为基数形式的字符串。如果不指定 `radix` 的值,则默认基数为10。指定的 `radix` 值必须在2~36之间,否则抛出错误。"
|
||||||
},
|
},
|
||||||
"$toMillis": {
|
"$toMillis": {
|
||||||
"args": "timestamp",
|
"args": "timestamp",
|
||||||
"desc": "将ISO 8601格式的字符串`timestamp`转换为从UNIX时间 (1970年1月1日 UTC/GMT的午夜)开始到现在的毫秒数。如果该字符串的格式不正确,则抛出错误。"
|
"desc": "将ISO 8601格式的字符串 `timestamp` 转换为从UNIX时间 (1970年1月1日 UTC/GMT的午夜)开始到现在的毫秒数。如果该字符串的格式不正确,则抛出错误。"
|
||||||
},
|
},
|
||||||
"$env": {
|
"$env": {
|
||||||
"args": "arg",
|
"args": "arg",
|
||||||
@ -221,7 +221,7 @@
|
|||||||
},
|
},
|
||||||
"$eval": {
|
"$eval": {
|
||||||
"args": "expr [, context]",
|
"args": "expr [, context]",
|
||||||
"desc": "使用当前上下文来作为评估依据,分析并评估字符串`expr`,其中包含文字JSON或JSONata表达式。"
|
"desc": "使用当前上下文来作为评估依据,分析并评估字符串 `expr` ,其中包含文字JSON或JSONata表达式。"
|
||||||
},
|
},
|
||||||
"$formatInteger": {
|
"$formatInteger": {
|
||||||
"args": "number, picture",
|
"args": "number, picture",
|
||||||
@ -233,19 +233,19 @@
|
|||||||
},
|
},
|
||||||
"$error": {
|
"$error": {
|
||||||
"args": "[str]",
|
"args": "[str]",
|
||||||
"desc": "引发错误并显示一条消息。 可选的`str`将替代$error()函数评估的默认消息。"
|
"desc": "引发错误并显示一条消息。 可选的 `str` 将替代$error()函数评估的默认消息。"
|
||||||
},
|
},
|
||||||
"$assert": {
|
"$assert": {
|
||||||
"args": "arg, str",
|
"args": "arg, str",
|
||||||
"desc": "如果`arg`为真,则该函数返回。 如果arg为假,则抛出带有str的异常作为异常消息。"
|
"desc": "如果 `arg` 为真,则该函数返回。 如果arg为假,则抛出带有str的异常作为异常消息。"
|
||||||
},
|
},
|
||||||
"$single": {
|
"$single": {
|
||||||
"args": "array, function",
|
"args": "array, function",
|
||||||
"desc": "返回满足参数function谓语的array参数中的唯一值 (比如:传递值时,函数返回布尔值“true”)。如果匹配值的数量不唯一时,则抛出异常。\n\n应在以下签名中提供函数:`function(value [,index [,array []]])`其中value是数组的每个输入,index是该值的位置,整个数组作为第三个参数传递。"
|
"desc": "返回满足参数function谓语的array参数中的唯一值 (比如:传递值时,函数返回布尔值“true”)。如果匹配值的数量不唯一时,则抛出异常。\n\n应在以下签名中提供函数: `function(value [,index [,array []]])` 其中value是数组的每个输入,index是该值的位置,整个数组作为第三个参数传递。"
|
||||||
},
|
},
|
||||||
"$encodeUrl": {
|
"$encodeUrl": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
"desc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例,对统一资源定位符(URL)组件进行编码。\n\n示例:`$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
"desc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例,对统一资源定位符(URL)组件进行编码。\n\n示例: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||||
},
|
},
|
||||||
"$encodeUrlComponent": {
|
"$encodeUrlComponent": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
@ -261,10 +261,14 @@
|
|||||||
},
|
},
|
||||||
"$distinct": {
|
"$distinct": {
|
||||||
"args": "array",
|
"args": "array",
|
||||||
"desc": "返回一个数组,其中重复的值已从`数组`中删除"
|
"desc": "返回一个数组,其中重复的值已从 `数组` 中删除"
|
||||||
},
|
},
|
||||||
"$type": {
|
"$type": {
|
||||||
"args": "value",
|
"args": "value",
|
||||||
"desc": "以字符串形式返回`值`的类型。 如果该`值`未定义,则将返回`未定义`"
|
"desc": "以字符串形式返回 `值` 的类型。 如果该 `值` 未定义,则将返回 `未定义` "
|
||||||
|
},
|
||||||
|
"$moment": {
|
||||||
|
"args": "[str]",
|
||||||
|
"desc": "使用Moment库获取日期对象。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,15 @@
|
|||||||
"back": "返回",
|
"back": "返回",
|
||||||
"next": "下一步",
|
"next": "下一步",
|
||||||
"clone": "複製專案",
|
"clone": "複製專案",
|
||||||
"cont": "Continue"
|
"cont": "繼續",
|
||||||
|
"style": "風格",
|
||||||
|
"line": "大綱",
|
||||||
|
"fill": "填充",
|
||||||
|
"label": "標籤",
|
||||||
|
"color": "顏色",
|
||||||
|
"position": "位置",
|
||||||
|
"enable": "啟用",
|
||||||
|
"disable": "禁用"
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"string": "字符串",
|
"string": "字符串",
|
||||||
@ -28,6 +36,13 @@
|
|||||||
"null": "空"
|
"null": "空"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"event": {
|
||||||
|
"loadPalette": "加載控制板",
|
||||||
|
"loadNodeCatalogs": "加載節點目錄",
|
||||||
|
"loadNodes": "加載 __count__ 個節點",
|
||||||
|
"loadFlows": "加載流程",
|
||||||
|
"importFlows": "往工作區中加載流程"
|
||||||
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"defaultName": "流程__number__",
|
"defaultName": "流程__number__",
|
||||||
"editFlow": "編輯流程: __name__",
|
"editFlow": "編輯流程: __name__",
|
||||||
@ -91,7 +106,12 @@
|
|||||||
"projects-new": "新專案",
|
"projects-new": "新專案",
|
||||||
"projects-open": "開啟專案",
|
"projects-open": "開啟專案",
|
||||||
"projects-settings": "專案設定",
|
"projects-settings": "專案設定",
|
||||||
"showNodeLabelDefault": "顯示新添加節點的標籤"
|
"showNodeLabelDefault": "顯示新添加節點的標籤",
|
||||||
|
"groups": "組",
|
||||||
|
"groupSelection": "選擇組",
|
||||||
|
"ungroupSelection": "取消選擇組",
|
||||||
|
"groupMergeSelection": "合并選擇",
|
||||||
|
"groupRemoveSelection": "從組中移除"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@ -101,7 +121,7 @@
|
|||||||
"zoom-in": "放大"
|
"zoom-in": "放大"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"loggedInAs": "作為__name__登入",
|
"loggedInAs": "作為 __name__ 登入",
|
||||||
"username": "帳號",
|
"username": "帳號",
|
||||||
"password": "密碼",
|
"password": "密碼",
|
||||||
"login": "登入",
|
"login": "登入",
|
||||||
@ -133,7 +153,7 @@
|
|||||||
"error": "<strong>Error</strong>: __message__",
|
"error": "<strong>Error</strong>: __message__",
|
||||||
"errors": {
|
"errors": {
|
||||||
"lostConnection": "丟失與伺服器的連接,重新連接...",
|
"lostConnection": "丟失與伺服器的連接,重新連接...",
|
||||||
"lostConnectionReconnect": "丟失與伺服器的連接,__time__秒後重新連接",
|
"lostConnectionReconnect": "丟失與伺服器的連接,__time__ 秒後重新連接",
|
||||||
"lostConnectionTry": "現在嘗試",
|
"lostConnectionTry": "現在嘗試",
|
||||||
"cannotAddSubflowToItself": "無法向其自身添加子流程",
|
"cannotAddSubflowToItself": "無法向其自身添加子流程",
|
||||||
"cannotAddCircularReference": "無法添加子流程 - 迴圈引用",
|
"cannotAddCircularReference": "無法添加子流程 - 迴圈引用",
|
||||||
@ -146,7 +166,7 @@
|
|||||||
"loaded": "已加載項目'__project__'",
|
"loaded": "已加載項目'__project__'",
|
||||||
"updated": "已更新項目'__project__'",
|
"updated": "已更新項目'__project__'",
|
||||||
"pull": "已重新加載項目'__project__'",
|
"pull": "已重新加載項目'__project__'",
|
||||||
"revert": "項目“__project__”已還原",
|
"revert": "項目'__project__'已還原",
|
||||||
"merge-complete": "Git合併完成",
|
"merge-complete": "Git合併完成",
|
||||||
"setupCredentials": "設定證書",
|
"setupCredentials": "設定證書",
|
||||||
"setupProjectFiles": "設置項目文件",
|
"setupProjectFiles": "設置項目文件",
|
||||||
@ -171,6 +191,8 @@
|
|||||||
"node_plural": "__count__ 多個節點",
|
"node_plural": "__count__ 多個節點",
|
||||||
"configNode": "__count__ 節點組態",
|
"configNode": "__count__ 節點組態",
|
||||||
"configNode_plural": "__count__ 多節點組態",
|
"configNode_plural": "__count__ 多節點組態",
|
||||||
|
"group": "__count__ 個組",
|
||||||
|
"group_plural": "__count__ 個組",
|
||||||
"flow": "__count__ 流程",
|
"flow": "__count__ 流程",
|
||||||
"flow_plural": "__count__ 多流程",
|
"flow_plural": "__count__ 多流程",
|
||||||
"subflow": "__count__ 子流程",
|
"subflow": "__count__ 子流程",
|
||||||
@ -184,8 +206,11 @@
|
|||||||
"importUnrecognised_plural": "匯入了無法識別的類型:",
|
"importUnrecognised_plural": "匯入了無法識別的類型:",
|
||||||
"nodesExported": "節點匯出到了剪貼簿",
|
"nodesExported": "節點匯出到了剪貼簿",
|
||||||
"nodesImported": "已匯入:",
|
"nodesImported": "已匯入:",
|
||||||
"nodeCopied": "已複製__count__個節點",
|
"nodeCopied": "已複製 __count__ 個節點",
|
||||||
"nodeCopied_plural": "已複製__count__個節點",
|
"nodeCopied_plural": "已複製 __count__ 個節點",
|
||||||
|
"groupCopied": "複製 __count__ 個組",
|
||||||
|
"groupCopied_plural": "已複製 __count__ 個groups",
|
||||||
|
"groupStyleCopied": "已複製組風格",
|
||||||
"invalidFlow": "無效的流程: __message__",
|
"invalidFlow": "無效的流程: __message__",
|
||||||
"export": {
|
"export": {
|
||||||
"selected": "已選擇的節點",
|
"selected": "已選擇的節點",
|
||||||
@ -204,9 +229,9 @@
|
|||||||
"newFlow": "新流程",
|
"newFlow": "新流程",
|
||||||
"errors": {
|
"errors": {
|
||||||
"notArray": "輸入的不是JSON數組",
|
"notArray": "輸入的不是JSON數組",
|
||||||
"itemNotObject": "輸入的流程無效-項目__index__不是節點對象",
|
"itemNotObject": "輸入的流程無效-項目 __index__ 不是節點對象",
|
||||||
"missingId": "輸入的流程無效-項__index__缺少“ id”屬性",
|
"missingId": "輸入的流程無效-項 __index__ 缺少“ id”屬性",
|
||||||
"missingType": "輸入的流程無效-項__index__缺少“類型”屬性"
|
"missingType": "輸入的流程無效-項 __index__ 缺少“類型”屬性"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"copyMessagePath": "已複製路徑",
|
"copyMessagePath": "已複製路徑",
|
||||||
@ -250,7 +275,7 @@
|
|||||||
"conflictChecking": "檢查是否可以自動合併更改",
|
"conflictChecking": "檢查是否可以自動合併更改",
|
||||||
"conflictAutoMerge": "此更改不包括衝突,可以自動合併",
|
"conflictAutoMerge": "此更改不包括衝突,可以自動合併",
|
||||||
"conflictManualMerge": "這些更改包括了在部署之前必須解決的衝突。",
|
"conflictManualMerge": "這些更改包括了在部署之前必須解決的衝突。",
|
||||||
"plusNMore": "+更多的__count__"
|
"plusNMore": "+更多的 __count__"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eventLog": {
|
"eventLog": {
|
||||||
@ -258,8 +283,8 @@
|
|||||||
"view": "查看日誌"
|
"view": "查看日誌"
|
||||||
},
|
},
|
||||||
"diff": {
|
"diff": {
|
||||||
"unresolvedCount": "__count__個未解決的衝突",
|
"unresolvedCount": "__count__ 個未解決的衝突",
|
||||||
"unresolvedCount_plural": "__count__個未解決的衝突",
|
"unresolvedCount_plural": "__count__ 個未解決的衝突",
|
||||||
"globalNodes": "全局節點",
|
"globalNodes": "全局節點",
|
||||||
"flowProperties": "流程屬性",
|
"flowProperties": "流程屬性",
|
||||||
"type": {
|
"type": {
|
||||||
@ -269,11 +294,11 @@
|
|||||||
"deleted": "已刪除",
|
"deleted": "已刪除",
|
||||||
"flowDeleted": "已刪除流程",
|
"flowDeleted": "已刪除流程",
|
||||||
"flowAdded": "已添加流程",
|
"flowAdded": "已添加流程",
|
||||||
"movedTo": "移動至__id__",
|
"movedTo": "移動至 __id__",
|
||||||
"movedFrom": "從__id__移動"
|
"movedFrom": "從 __id__ 移動"
|
||||||
},
|
},
|
||||||
"nodeCount": "__count__個節點",
|
"nodeCount": "__count__ 個節點",
|
||||||
"nodeCount_plural": "__count__個節點",
|
"nodeCount_plural": "__count__ 個節點",
|
||||||
"local": "本地",
|
"local": "本地",
|
||||||
"remote": "遠端",
|
"remote": "遠端",
|
||||||
"reviewChanges": "查看變更",
|
"reviewChanges": "查看變更",
|
||||||
@ -287,11 +312,11 @@
|
|||||||
"newVersionError": "新版本不包含有效的JSON:"
|
"newVersionError": "新版本不包含有效的JSON:"
|
||||||
},
|
},
|
||||||
"subflow": {
|
"subflow": {
|
||||||
"editSubflowInstance": "編輯子流程實例:__name__",
|
"editSubflowInstance": "編輯子流程實例: __name__",
|
||||||
"editSubflow": "編輯流程範本: __name__",
|
"editSubflow": "編輯流程範本: __name__",
|
||||||
"edit": "編輯流程範本",
|
"edit": "編輯流程範本",
|
||||||
"subflowInstances": "這個子流程範本有__count__個實例",
|
"subflowInstances": "這個子流程範本有 __count__ 個實例",
|
||||||
"subflowInstances_plural": "這個子流程範本有__count__個實例",
|
"subflowInstances_plural": "這個子流程範本有 __count__ 個實例",
|
||||||
"editSubflowProperties": "編輯屬性",
|
"editSubflowProperties": "編輯屬性",
|
||||||
"input": "輸入:",
|
"input": "輸入:",
|
||||||
"output": "輸出:",
|
"output": "輸出:",
|
||||||
@ -308,17 +333,24 @@
|
|||||||
"multipleInputsToSelection": "<strong>無法創建子流程</strong>: 多個輸入到了選擇"
|
"multipleInputsToSelection": "<strong>無法創建子流程</strong>: 多個輸入到了選擇"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"group": {
|
||||||
|
"editGroup": "編輯組: __name__",
|
||||||
|
"errors": {
|
||||||
|
"cannotCreateDiffGroups": "無法使用來自不同組的節點創建組",
|
||||||
|
"cannotAddSubflowPorts": "無法將子流程的端口添加到組"
|
||||||
|
}
|
||||||
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"configEdit": "編輯",
|
"configEdit": "編輯",
|
||||||
"configAdd": "添加",
|
"configAdd": "添加",
|
||||||
"configUpdate": "更新",
|
"configUpdate": "更新",
|
||||||
"configDelete": "刪除",
|
"configDelete": "刪除",
|
||||||
"nodesUse": "__count__個節點使用此配置",
|
"nodesUse": "__count__ 個節點使用此配置",
|
||||||
"nodesUse_plural": "__count__個節點使用此配置",
|
"nodesUse_plural": "__count__ 個節點使用此配置",
|
||||||
"addNewConfig": "添加新的__type__配置",
|
"addNewConfig": "添加新的 __type__ 配置",
|
||||||
"editNode": "編輯__type__節點",
|
"editNode": "編輯 __type__ 節點",
|
||||||
"editConfig": "編輯__type__配置",
|
"editConfig": "編輯 __type__ 配置",
|
||||||
"addNewType": "添加新的__type__節點",
|
"addNewType": "添加新的 __type__ 節點",
|
||||||
"nodeProperties": "節點屬性",
|
"nodeProperties": "節點屬性",
|
||||||
"label": "Label",
|
"label": "Label",
|
||||||
"color": "顏色",
|
"color": "顏色",
|
||||||
@ -337,6 +369,7 @@
|
|||||||
"locale": "選擇界面語言",
|
"locale": "選擇界面語言",
|
||||||
"icon": "圖標",
|
"icon": "圖標",
|
||||||
"inputType": "輸入類型",
|
"inputType": "輸入類型",
|
||||||
|
"selectType": "選擇類型...",
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"input": "輸入",
|
"input": "輸入",
|
||||||
"select": "選擇",
|
"select": "選擇",
|
||||||
@ -351,7 +384,8 @@
|
|||||||
"bool": "布爾",
|
"bool": "布爾",
|
||||||
"json": "JSON",
|
"json": "JSON",
|
||||||
"bin": "buffer",
|
"bin": "buffer",
|
||||||
"env": "環境變量"
|
"env": "環境變量",
|
||||||
|
"cred": "證書"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"input": "輸入",
|
"input": "輸入",
|
||||||
@ -405,13 +439,13 @@
|
|||||||
"library": "庫",
|
"library": "庫",
|
||||||
"openLibrary": "打開庫...",
|
"openLibrary": "打開庫...",
|
||||||
"saveToLibrary": "保存到庫...",
|
"saveToLibrary": "保存到庫...",
|
||||||
"typeLibrary": "__type__型別程式庫",
|
"typeLibrary": "__type__ 型別程式庫",
|
||||||
"unnamedType": "無名__type__",
|
"unnamedType": "無名 __type__",
|
||||||
"exportedToLibrary": "節點導出到庫",
|
"exportedToLibrary": "節點導出到庫",
|
||||||
"dialogSaveOverwrite": "一個叫做__libraryName__的__libraryType__已經存在,您需要覆蓋麼?",
|
"dialogSaveOverwrite": "一個叫做 __libraryName__ 的 __libraryType__ 已經存在,您需要覆蓋麼?",
|
||||||
"invalidFilename": "無效的檔案名",
|
"invalidFilename": "無效的檔案名",
|
||||||
"savedNodes": "保存的節點",
|
"savedNodes": "保存的節點",
|
||||||
"savedType": "已保存__type__",
|
"savedType": "已保存 __type__",
|
||||||
"saveFailed": "保存失敗: __message__",
|
"saveFailed": "保存失敗: __message__",
|
||||||
"newFolder": "新文件夾",
|
"newFolder": "新文件夾",
|
||||||
"types": {
|
"types": {
|
||||||
@ -460,33 +494,33 @@
|
|||||||
"times": {
|
"times": {
|
||||||
"seconds": "秒前",
|
"seconds": "秒前",
|
||||||
"minutes": "分前",
|
"minutes": "分前",
|
||||||
"minutesV": "__count__分前",
|
"minutesV": "__count__ 分前",
|
||||||
"hoursV": "__count__小時前",
|
"hoursV": "__count__ 小時前",
|
||||||
"hoursV_plural": "__count__小時前",
|
"hoursV_plural": "__count__ 小時前",
|
||||||
"daysV": "__count__天前",
|
"daysV": "__count__ 天前",
|
||||||
"daysV_plural": "__count__天前",
|
"daysV_plural": "__count__ 天前",
|
||||||
"weeksV": "__count__周前",
|
"weeksV": "__count__ 周前",
|
||||||
"weeksV_plural": "__count__周前",
|
"weeksV_plural": "__count__ 周前",
|
||||||
"monthsV": "__count__月前",
|
"monthsV": "__count__ 月前",
|
||||||
"monthsV_plural": "__count__月前",
|
"monthsV_plural": "__count__ 月前",
|
||||||
"yearsV": "__count__年前",
|
"yearsV": "__count__ 年前",
|
||||||
"yearsV_plural": "__count__年前",
|
"yearsV_plural": "__count__ 年前",
|
||||||
"yearMonthsV": "__y__年, __count__月前",
|
"yearMonthsV": "__y__ 年, __count__ 月前",
|
||||||
"yearMonthsV_plural": "__y__年, __count__月前",
|
"yearMonthsV_plural": "__y__ 年, __count__ 月前",
|
||||||
"yearsMonthsV": "__y__年, __count__月前",
|
"yearsMonthsV": "__y__ 年, __count__ 月前",
|
||||||
"yearsMonthsV_plural": "__y__年, __count__月前"
|
"yearsMonthsV_plural": "__y__ 年, __count__ 月前"
|
||||||
},
|
},
|
||||||
"nodeCount": "__label__個節點",
|
"nodeCount": "__label__ 個節點",
|
||||||
"nodeCount_plural": "__label__個節點",
|
"nodeCount_plural": "__label__ 個節點",
|
||||||
"moduleCount": "__count__個可用模組",
|
"moduleCount": "__count__ 個可用模組",
|
||||||
"moduleCount_plural": "__count__個可用模組",
|
"moduleCount_plural": "__count__ 個可用模組",
|
||||||
"inuse": "使用中",
|
"inuse": "使用中",
|
||||||
"enableall": "全部啟用",
|
"enableall": "全部啟用",
|
||||||
"disableall": "全部禁用",
|
"disableall": "全部禁用",
|
||||||
"enable": "啟用",
|
"enable": "啟用",
|
||||||
"disable": "禁用",
|
"disable": "禁用",
|
||||||
"remove": "移除",
|
"remove": "移除",
|
||||||
"update": "更新至__version__版本",
|
"update": "更新至 __version__ 版本",
|
||||||
"updated": "已更新",
|
"updated": "已更新",
|
||||||
"install": "安裝",
|
"install": "安裝",
|
||||||
"installed": "已安裝",
|
"installed": "已安裝",
|
||||||
@ -498,7 +532,7 @@
|
|||||||
"sort": "排序:",
|
"sort": "排序:",
|
||||||
"sortAZ": "a-z順序",
|
"sortAZ": "a-z順序",
|
||||||
"sortRecent": "日期順序",
|
"sortRecent": "日期順序",
|
||||||
"more": "增加__count__個",
|
"more": "增加 __count__ 個",
|
||||||
"errors": {
|
"errors": {
|
||||||
"catalogLoadFailed": "無法載入節點目錄。<br>查看瀏覽器控制臺瞭解更多資訊",
|
"catalogLoadFailed": "無法載入節點目錄。<br>查看瀏覽器控制臺瞭解更多資訊",
|
||||||
"installFailed": "無法安裝: __module__<br>__message__<br>查看日誌瞭解更多資訊",
|
"installFailed": "無法安裝: __module__<br>__message__<br>查看日誌瞭解更多資訊",
|
||||||
@ -539,6 +573,7 @@
|
|||||||
"label": "信息",
|
"label": "信息",
|
||||||
"node": "節點",
|
"node": "節點",
|
||||||
"type": "類型",
|
"type": "類型",
|
||||||
|
"group": "組",
|
||||||
"module": "Module",
|
"module": "Module",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"status": "狀態",
|
"status": "狀態",
|
||||||
@ -560,8 +595,30 @@
|
|||||||
"subflowDesc": "子流程描述",
|
"subflowDesc": "子流程描述",
|
||||||
"nodeHelp": "節點幫助",
|
"nodeHelp": "節點幫助",
|
||||||
"none": "無",
|
"none": "無",
|
||||||
"arrayItems": "__count__個項目",
|
"arrayItems": "__count__ 個項目",
|
||||||
"showTips": "您可以從設置面板啟用提示資訊"
|
"showTips": "您可以從設置面板啟用提示資訊",
|
||||||
|
"outline": "大綱",
|
||||||
|
"empty": "空的",
|
||||||
|
"globalConfig": "全局配置節點",
|
||||||
|
"triggerAction": "觸發動作",
|
||||||
|
"find": "在工作區中查找",
|
||||||
|
"search": {
|
||||||
|
"configNodes": "配置節點",
|
||||||
|
"unusedConfigNodes": "未使用的配置節點",
|
||||||
|
"invalidNodes": "無效的節點",
|
||||||
|
"uknownNodes": "未知的節點",
|
||||||
|
"unusedSubflows": "未使用的子流程"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"name": "幫助",
|
||||||
|
"label": "幫助",
|
||||||
|
"search": "搜索幫助",
|
||||||
|
"nodeHelp": "節點幫助",
|
||||||
|
"showHelp": "顯示幫助",
|
||||||
|
"showInOutline": "在大綱中顯示",
|
||||||
|
"showTopics": "顯示主題",
|
||||||
|
"noHelp": "未選擇幫助主題"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"name": "配置節點",
|
"name": "配置節點",
|
||||||
@ -614,9 +671,9 @@
|
|||||||
"removeFromProject": "從項目中刪除",
|
"removeFromProject": "從項目中刪除",
|
||||||
"addToProject": "添加到項目",
|
"addToProject": "添加到項目",
|
||||||
"files": "文件",
|
"files": "文件",
|
||||||
"package": "包",
|
|
||||||
"flow": "流程",
|
"flow": "流程",
|
||||||
"credentials": "證書",
|
"credentials": "證書",
|
||||||
|
"package": "包",
|
||||||
"packageCreate": "保存更改後將創建文件",
|
"packageCreate": "保存更改後將創建文件",
|
||||||
"fileNotExist": "文件不存在",
|
"fileNotExist": "文件不存在",
|
||||||
"selectFile": "選擇文件",
|
"selectFile": "選擇文件",
|
||||||
@ -668,7 +725,7 @@
|
|||||||
"copyPublicKey": "將公鑰複製到剪貼板",
|
"copyPublicKey": "將公鑰複製到剪貼板",
|
||||||
"delete": "刪除密鑰",
|
"delete": "刪除密鑰",
|
||||||
"gitConfig": "Git配置",
|
"gitConfig": "Git配置",
|
||||||
"deleteConfirm": "您確定要刪除SSH密鑰__name__嗎? 這不能被撤消。"
|
"deleteConfirm": "您確定要刪除SSH密鑰 __name__ 嗎? 這不能被撤消。"
|
||||||
},
|
},
|
||||||
"versionControl": {
|
"versionControl": {
|
||||||
"unstagedChanges": "未暫存的更改",
|
"unstagedChanges": "未暫存的更改",
|
||||||
@ -722,24 +779,24 @@
|
|||||||
"pullChanges": "Pull變更",
|
"pullChanges": "Pull變更",
|
||||||
"history": "歷史",
|
"history": "歷史",
|
||||||
"projectHistory": "項目歷史",
|
"projectHistory": "項目歷史",
|
||||||
"daysAgo": "__count__天前",
|
"daysAgo": "__count__ 天前",
|
||||||
"daysAgo_plural": "__count__天前",
|
"daysAgo_plural": "__count__ 天前",
|
||||||
"hoursAgo": "__count__小時前",
|
"hoursAgo": "__count__ 小時前",
|
||||||
"hoursAgo_plural": "__count__小時前",
|
"hoursAgo_plural": "__count__ 小時前",
|
||||||
"minsAgo": "__count__分鐘前",
|
"minsAgo": "__count__ 分鐘前",
|
||||||
"minsAgo_plural": "__count__分鐘前",
|
"minsAgo_plural": "__count__ 分鐘前",
|
||||||
"secondsAgo": "秒前",
|
"secondsAgo": "秒前",
|
||||||
"notTracking": "您的本地分支當前未跟蹤遠程分支。",
|
"notTracking": "您的本地分支當前未跟蹤遠程分支。",
|
||||||
"statusUnmergedChanged": "您的存儲庫中有未合併的更改。您需要解決衝突並提交結果。",
|
"statusUnmergedChanged": "您的存儲庫中有未合併的更改。您需要解決衝突並提交結果。",
|
||||||
"repositoryUpToDate": "您的存儲庫是最新的。",
|
"repositoryUpToDate": "您的存儲庫是最新的。",
|
||||||
"commitsAhead": "您的倉庫領先遠程倉庫__count__次提交。您現在可以push這些提交。",
|
"commitsAhead": "您的倉庫領先遠程倉庫 __count__ 次提交。您現在可以push這些提交。",
|
||||||
"commitsAhead_plural": "您的倉庫領先遠程倉庫__count__次提交。您現在可以push這些提交。",
|
"commitsAhead_plural": "您的倉庫領先遠程倉庫 __count__ 次提交。您現在可以push這些提交。",
|
||||||
"commitsBehind": "您的倉庫落後遠程倉庫__count__次提交。您現在可以pull這些提交。",
|
"commitsBehind": "您的倉庫落後遠程倉庫 __count__ 次提交。您現在可以pull這些提交。",
|
||||||
"commitsBehind_plural": "您的倉庫落後遠程倉庫__count__次提交。您現在可以pull這些提交。",
|
"commitsBehind_plural": "您的倉庫落後遠程倉庫 __count__ 次提交。您現在可以pull這些提交。",
|
||||||
"commitsAheadAndBehind1": "您的倉庫落後遠程倉庫__count__次提交",
|
"commitsAheadAndBehind1": "您的倉庫落後遠程倉庫 __count__ 次提交",
|
||||||
"commitsAheadAndBehind1_plural": "您的倉庫落後遠程倉庫__count__次提交",
|
"commitsAheadAndBehind1_plural": "您的倉庫落後遠程倉庫 __count__ 次提交",
|
||||||
"commitsAheadAndBehind2": "領先遠程倉庫__count__次提交。",
|
"commitsAheadAndBehind2": "領先遠程倉庫 __count__ 次提交。",
|
||||||
"commitsAheadAndBehind2_plural": "領先遠程倉庫__count__次提交。",
|
"commitsAheadAndBehind2_plural": "領先遠程倉庫 __count__ 次提交。",
|
||||||
"commitsAheadAndBehind3": "您必須先pull遠程提交,然後再進行push。",
|
"commitsAheadAndBehind3": "您必須先pull遠程提交,然後再進行push。",
|
||||||
"commitsAheadAndBehind3_plural": "您必須先pull遠程提交,然後再進行push。",
|
"commitsAheadAndBehind3_plural": "您必須先pull遠程提交,然後再進行push。",
|
||||||
"refreshCommitHistory": "刷新提交歷史",
|
"refreshCommitHistory": "刷新提交歷史",
|
||||||
@ -757,7 +814,8 @@
|
|||||||
"bin": "二進位流",
|
"bin": "二進位流",
|
||||||
"date": "時間戳記",
|
"date": "時間戳記",
|
||||||
"jsonata": "expression",
|
"jsonata": "expression",
|
||||||
"env": "env variable"
|
"env": "env variable",
|
||||||
|
"cred": "證書"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"editableList": {
|
"editableList": {
|
||||||
@ -977,7 +1035,8 @@
|
|||||||
"passphrase": "密碼短語",
|
"passphrase": "密碼短語",
|
||||||
"retry": "重試",
|
"retry": "重試",
|
||||||
"update-failed": "無法更新身份驗證",
|
"update-failed": "無法更新身份驗證",
|
||||||
"unhandled": "未處理的錯誤響應"
|
"unhandled": "未處理的錯誤響應",
|
||||||
|
"host-key-verify-failed": "<p>主機密鑰驗證失敗。</p><p>無法驗證存儲庫主機密鑰。請更新您的<code>known_hosts</code>文件,然後重試。</p>"
|
||||||
},
|
},
|
||||||
"create-branch-list": {
|
"create-branch-list": {
|
||||||
"invalid": "無效的分支",
|
"invalid": "無效的分支",
|
||||||
|
@ -266,5 +266,9 @@
|
|||||||
"$type": {
|
"$type": {
|
||||||
"args": "value",
|
"args": "value",
|
||||||
"desc": "以字符串形式返回`值`的類型。 如果該`值`未定義,則將返回`未定義`"
|
"desc": "以字符串形式返回`值`的類型。 如果該`值`未定義,則將返回`未定義`"
|
||||||
|
},
|
||||||
|
"$moment": {
|
||||||
|
"args": "[str]",
|
||||||
|
"desc": "使用Moment庫獲取日期對象。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-client",
|
"name": "@node-red/editor-client",
|
||||||
"version": "1.0.6",
|
"version": "1.1.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -32,14 +32,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function emit(evt,arg) {
|
function emit() {
|
||||||
|
var evt = arguments[0]
|
||||||
|
var args = Array.prototype.slice.call(arguments,1);
|
||||||
|
if (RED.events.DEBUG) {
|
||||||
|
console.warn(evt,args);
|
||||||
|
}
|
||||||
if (handlers[evt]) {
|
if (handlers[evt]) {
|
||||||
for (var i=0;i<handlers[evt].length;i++) {
|
for (var i=0;i<handlers[evt].length;i++) {
|
||||||
try {
|
try {
|
||||||
handlers[evt][i](arg);
|
handlers[evt][i].apply(null, args);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log("RED.events.emit error: ["+evt+"] "+(err.toString()));
|
console.warn("RED.events.emit error: ["+evt+"] "+(err.toString()));
|
||||||
console.log(err);
|
console.warn(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ RED.history = (function() {
|
|||||||
var i;
|
var i;
|
||||||
var len;
|
var len;
|
||||||
var node;
|
var node;
|
||||||
|
var group;
|
||||||
var subflow;
|
var subflow;
|
||||||
var modifiedTabs = {};
|
var modifiedTabs = {};
|
||||||
var inverseEv;
|
var inverseEv;
|
||||||
@ -65,6 +66,14 @@ RED.history = (function() {
|
|||||||
}
|
}
|
||||||
inverseEv.nodes.push(node);
|
inverseEv.nodes.push(node);
|
||||||
RED.nodes.remove(ev.nodes[i]);
|
RED.nodes.remove(ev.nodes[i]);
|
||||||
|
if (node.g) {
|
||||||
|
var group = RED.nodes.group(node.g);
|
||||||
|
var index = group.nodes.indexOf(node);
|
||||||
|
if (index !== -1) {
|
||||||
|
group.nodes.splice(index,1);
|
||||||
|
RED.group.markDirty(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ev.links) {
|
if (ev.links) {
|
||||||
@ -74,6 +83,17 @@ RED.history = (function() {
|
|||||||
RED.nodes.removeLink(ev.links[i]);
|
RED.nodes.removeLink(ev.links[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ev.groups) {
|
||||||
|
inverseEv.groups = [];
|
||||||
|
for (i=0;i<ev.groups.length;i++) {
|
||||||
|
group = ev.groups[i];
|
||||||
|
modifiedTabs[group.z] = true;
|
||||||
|
// The order of groups is important
|
||||||
|
// - to invert the action, the order is reversed
|
||||||
|
inverseEv.groups.unshift(group);
|
||||||
|
RED.nodes.removeGroup(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ev.workspaces) {
|
if (ev.workspaces) {
|
||||||
inverseEv.workspaces = [];
|
inverseEv.workspaces = [];
|
||||||
for (i=0;i<ev.workspaces.length;i++) {
|
for (i=0;i<ev.workspaces.length;i++) {
|
||||||
@ -186,19 +206,46 @@ RED.history = (function() {
|
|||||||
RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) {
|
RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) {
|
||||||
n.inputs = subflow.in.length;
|
n.inputs = subflow.in.length;
|
||||||
n.outputs = subflow.out.length;
|
n.outputs = subflow.out.length;
|
||||||
while (n.outputs > n.ports.length) {
|
|
||||||
n.ports.push(n.ports.length);
|
|
||||||
}
|
|
||||||
n.resize = true;
|
n.resize = true;
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (ev.groups) {
|
||||||
|
inverseEv.groups = [];
|
||||||
|
var groupsToAdd = {};
|
||||||
|
ev.groups.forEach(function(g) { groupsToAdd[g.id] = g; });
|
||||||
|
for (i=0;i<ev.groups.length;i++) {
|
||||||
|
RED.nodes.addGroup(ev.groups[i])
|
||||||
|
modifiedTabs[ev.groups[i].z] = true;
|
||||||
|
// The order of groups is important
|
||||||
|
// - to invert the action, the order is reversed
|
||||||
|
inverseEv.groups.unshift(ev.groups[i]);
|
||||||
|
if (ev.groups[i].g) {
|
||||||
|
if (!groupsToAdd[ev.groups[i].g]) {
|
||||||
|
group = RED.nodes.group(ev.groups[i].g);
|
||||||
|
} else {
|
||||||
|
group = groupsToAdd[ev.groups[i].g];
|
||||||
|
}
|
||||||
|
if (group.nodes.indexOf(ev.groups[i]) === -1) {
|
||||||
|
group.nodes.push(ev.groups[i]);
|
||||||
|
}
|
||||||
|
RED.group.markDirty(ev.groups[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ev.nodes) {
|
if (ev.nodes) {
|
||||||
inverseEv.nodes = [];
|
inverseEv.nodes = [];
|
||||||
for (i=0;i<ev.nodes.length;i++) {
|
for (i=0;i<ev.nodes.length;i++) {
|
||||||
RED.nodes.add(ev.nodes[i]);
|
RED.nodes.add(ev.nodes[i]);
|
||||||
modifiedTabs[ev.nodes[i].z] = true;
|
modifiedTabs[ev.nodes[i].z] = true;
|
||||||
inverseEv.nodes.push(ev.nodes[i].id);
|
inverseEv.nodes.push(ev.nodes[i].id);
|
||||||
|
if (ev.nodes[i].g) {
|
||||||
|
group = RED.nodes.group(ev.nodes[i].g);
|
||||||
|
if (group.nodes.indexOf(ev.nodes[i]) === -1) {
|
||||||
|
group.nodes.push(ev.nodes[i]);
|
||||||
|
}
|
||||||
|
RED.group.markDirty(group)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ev.links) {
|
if (ev.links) {
|
||||||
@ -227,9 +274,12 @@ RED.history = (function() {
|
|||||||
}
|
}
|
||||||
node.dirty = true;
|
node.dirty = true;
|
||||||
}
|
}
|
||||||
|
RED.events.emit("nodes:change",node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (subflow) {
|
||||||
|
RED.events.emit("subflows:change", subflow);
|
||||||
}
|
}
|
||||||
} else if (ev.t == "move") {
|
} else if (ev.t == "move") {
|
||||||
inverseEv = {
|
inverseEv = {
|
||||||
@ -260,6 +310,13 @@ RED.history = (function() {
|
|||||||
RED.nodes.addLink(ev.removedLinks[i]);
|
RED.nodes.addLink(ev.removedLinks[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ev.addToGroup) {
|
||||||
|
RED.group.removeFromGroup(ev.addToGroup,ev.nodes.map(function(n) { return n.n }),false);
|
||||||
|
inverseEv.removeFromGroup = ev.addToGroup;
|
||||||
|
} else if (ev.removeFromGroup) {
|
||||||
|
RED.group.addToGroup(ev.removeFromGroup,ev.nodes.map(function(n) { return n.n }));
|
||||||
|
inverseEv.addToGroup = ev.removeFromGroup;
|
||||||
|
}
|
||||||
} else if (ev.t == "edit") {
|
} else if (ev.t == "edit") {
|
||||||
inverseEv = {
|
inverseEv = {
|
||||||
t: "edit",
|
t: "edit",
|
||||||
@ -274,15 +331,28 @@ RED.history = (function() {
|
|||||||
var currentConfigNode = RED.nodes.node(ev.node[i]);
|
var currentConfigNode = RED.nodes.node(ev.node[i]);
|
||||||
if (currentConfigNode) {
|
if (currentConfigNode) {
|
||||||
currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1);
|
currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1);
|
||||||
|
RED.events.emit("nodes:change",currentConfigNode);
|
||||||
}
|
}
|
||||||
var newConfigNode = RED.nodes.node(ev.changes[i]);
|
var newConfigNode = RED.nodes.node(ev.changes[i]);
|
||||||
if (newConfigNode) {
|
if (newConfigNode) {
|
||||||
newConfigNode.users.push(ev.node);
|
newConfigNode.users.push(ev.node);
|
||||||
|
RED.events.emit("nodes:change",newConfigNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ev.node[i] = ev.changes[i];
|
ev.node[i] = ev.changes[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var eventType;
|
||||||
|
switch(ev.node.type) {
|
||||||
|
case 'tab': eventType = "flows"; break;
|
||||||
|
case 'group': eventType = "groups"; break;
|
||||||
|
case 'subflow': eventType = "subflows"; break;
|
||||||
|
default: eventType = "nodes"; break;
|
||||||
|
}
|
||||||
|
eventType += ":change";
|
||||||
|
RED.events.emit(eventType,ev.node);
|
||||||
|
|
||||||
|
|
||||||
if (ev.node.type === 'tab' && ev.changes.hasOwnProperty('disabled')) {
|
if (ev.node.type === 'tab' && ev.changes.hasOwnProperty('disabled')) {
|
||||||
$("#red-ui-tab-"+(ev.node.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!ev.node.disabled);
|
$("#red-ui-tab-"+(ev.node.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!ev.node.disabled);
|
||||||
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!ev.node.disabled);
|
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!ev.node.disabled);
|
||||||
@ -342,6 +412,7 @@ RED.history = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ev.node.__outputs = inverseEv.changes.outputs;
|
||||||
RED.editor.updateNodeProperties(ev.node,outputMap);
|
RED.editor.updateNodeProperties(ev.node,outputMap);
|
||||||
RED.editor.validateNode(ev.node);
|
RED.editor.validateNode(ev.node);
|
||||||
}
|
}
|
||||||
@ -370,7 +441,9 @@ RED.history = (function() {
|
|||||||
if (ev.nodes) {
|
if (ev.nodes) {
|
||||||
inverseEv.movedNodes = [];
|
inverseEv.movedNodes = [];
|
||||||
var z = ev.activeWorkspace;
|
var z = ev.activeWorkspace;
|
||||||
RED.nodes.filterNodes({z:ev.subflow.subflow.id}).forEach(function(n) {
|
var fullNodeList = RED.nodes.filterNodes({z:ev.subflow.subflow.id});
|
||||||
|
fullNodeList = fullNodeList.concat(RED.nodes.groups(ev.subflow.subflow.id))
|
||||||
|
fullNodeList.forEach(function(n) {
|
||||||
n.x += ev.subflow.offsetX;
|
n.x += ev.subflow.offsetX;
|
||||||
n.y += ev.subflow.offsetY;
|
n.y += ev.subflow.offsetY;
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
@ -411,6 +484,9 @@ RED.history = (function() {
|
|||||||
if (ev.subflow) {
|
if (ev.subflow) {
|
||||||
RED.nodes.addSubflow(ev.subflow.subflow);
|
RED.nodes.addSubflow(ev.subflow.subflow);
|
||||||
inverseEv.subflow = ev.subflow;
|
inverseEv.subflow = ev.subflow;
|
||||||
|
if (ev.subflow.subflow.g) {
|
||||||
|
RED.group.addToGroup(RED.nodes.group(ev.subflow.subflow.g),ev.subflow.subflow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ev.subflows) {
|
if (ev.subflows) {
|
||||||
inverseEv.nodes = [];
|
inverseEv.nodes = [];
|
||||||
@ -422,6 +498,9 @@ RED.history = (function() {
|
|||||||
if (ev.movedNodes) {
|
if (ev.movedNodes) {
|
||||||
ev.movedNodes.forEach(function(nid) {
|
ev.movedNodes.forEach(function(nid) {
|
||||||
nn = RED.nodes.node(nid);
|
nn = RED.nodes.node(nid);
|
||||||
|
if (!nn) {
|
||||||
|
nn = RED.nodes.group(nid);
|
||||||
|
}
|
||||||
nn.x -= ev.subflow.offsetX;
|
nn.x -= ev.subflow.offsetX;
|
||||||
nn.y -= ev.subflow.offsetY;
|
nn.y -= ev.subflow.offsetY;
|
||||||
nn.dirty = true;
|
nn.dirty = true;
|
||||||
@ -435,7 +514,7 @@ RED.history = (function() {
|
|||||||
RED.nodes.addLink(ev.links[i]);
|
RED.nodes.addLink(ev.links[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ev.createdLinks) {
|
if (ev.createdLinks) {
|
||||||
inverseEv.removedLinks = [];
|
inverseEv.removedLinks = [];
|
||||||
for (i=0;i<ev.createdLinks.length;i++) {
|
for (i=0;i<ev.createdLinks.length;i++) {
|
||||||
inverseEv.removedLinks.push(ev.createdLinks[i]);
|
inverseEv.removedLinks.push(ev.createdLinks[i]);
|
||||||
@ -450,6 +529,60 @@ RED.history = (function() {
|
|||||||
if (ev.order) {
|
if (ev.order) {
|
||||||
RED.workspaces.order(ev.order);
|
RED.workspaces.order(ev.order);
|
||||||
}
|
}
|
||||||
|
} else if (ev.t == "createGroup") {
|
||||||
|
inverseEv = {
|
||||||
|
t: "ungroup",
|
||||||
|
dirty: RED.nodes.dirty(),
|
||||||
|
groups: []
|
||||||
|
}
|
||||||
|
if (ev.groups) {
|
||||||
|
for (i=0;i<ev.groups.length;i++) {
|
||||||
|
inverseEv.groups.push(ev.groups[i]);
|
||||||
|
RED.group.ungroup(ev.groups[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ev.t == "ungroup") {
|
||||||
|
inverseEv = {
|
||||||
|
t: "createGroup",
|
||||||
|
dirty: RED.nodes.dirty(),
|
||||||
|
groups: []
|
||||||
|
}
|
||||||
|
if (ev.groups) {
|
||||||
|
for (i=0;i<ev.groups.length;i++) {
|
||||||
|
inverseEv.groups.push(ev.groups[i]);
|
||||||
|
var nodes = ev.groups[i].nodes.slice();
|
||||||
|
ev.groups[i].nodes = [];
|
||||||
|
RED.nodes.addGroup(ev.groups[i]);
|
||||||
|
RED.group.addToGroup(ev.groups[i],nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ev.t == "addToGroup") {
|
||||||
|
inverseEv = {
|
||||||
|
t: "removeFromGroup",
|
||||||
|
dirty: RED.nodes.dirty(),
|
||||||
|
group: ev.group,
|
||||||
|
nodes: ev.nodes,
|
||||||
|
reparent: ev.reparent
|
||||||
|
}
|
||||||
|
if (ev.nodes) {
|
||||||
|
RED.group.removeFromGroup(ev.group,ev.nodes,(ev.hasOwnProperty('reparent')&&ev.hasOwnProperty('reparent')!==undefined)?ev.reparent:true);
|
||||||
|
}
|
||||||
|
} else if (ev.t == "removeFromGroup") {
|
||||||
|
inverseEv = {
|
||||||
|
t: "addToGroup",
|
||||||
|
dirty: RED.nodes.dirty(),
|
||||||
|
group: ev.group,
|
||||||
|
nodes: ev.nodes,
|
||||||
|
reparent: ev.reparent
|
||||||
|
}
|
||||||
|
if (ev.nodes) {
|
||||||
|
RED.group.addToGroup(ev.group,ev.nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ev.callback && typeof ev.callback === 'function') {
|
||||||
|
inverseEv.callback = ev.callback;
|
||||||
|
ev.callback(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(modifiedTabs).forEach(function(id) {
|
Object.keys(modifiedTabs).forEach(function(id) {
|
||||||
@ -460,9 +593,8 @@ RED.history = (function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
RED.nodes.dirty(ev.dirty);
|
RED.nodes.dirty(ev.dirty);
|
||||||
|
RED.view.updateActive();
|
||||||
RED.view.select(null);
|
RED.view.select(null);
|
||||||
RED.view.redraw(true);
|
|
||||||
RED.palette.refresh();
|
|
||||||
RED.workspaces.refresh();
|
RED.workspaces.refresh();
|
||||||
RED.sidebar.config.refresh();
|
RED.sidebar.config.refresh();
|
||||||
RED.subflow.refresh();
|
RED.subflow.refresh();
|
||||||
@ -482,6 +614,9 @@ RED.history = (function() {
|
|||||||
list: function() {
|
list: function() {
|
||||||
return undoHistory;
|
return undoHistory;
|
||||||
},
|
},
|
||||||
|
listRedo: function() {
|
||||||
|
return redoHistory;
|
||||||
|
},
|
||||||
depth: function() {
|
depth: function() {
|
||||||
return undoHistory.length;
|
return undoHistory.length;
|
||||||
},
|
},
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"ctrl-escape": "core:cancel-edit-tray",
|
"ctrl-escape": "core:cancel-edit-tray",
|
||||||
"ctrl-d": "core:deploy-flows",
|
"ctrl-d": "core:deploy-flows",
|
||||||
"ctrl-g i": "core:show-info-tab",
|
"ctrl-g i": "core:show-info-tab",
|
||||||
|
"ctrl-g h": "core:show-help-tab",
|
||||||
"ctrl-g d": "core:show-debug-tab",
|
"ctrl-g d": "core:show-debug-tab",
|
||||||
"ctrl-g c": "core:show-config-tab",
|
"ctrl-g c": "core:show-config-tab",
|
||||||
"ctrl-g x": "core:show-context-tab",
|
"ctrl-g x": "core:show-context-tab",
|
||||||
@ -44,6 +45,14 @@
|
|||||||
"ctrl-y": "core:redo",
|
"ctrl-y": "core:redo",
|
||||||
"ctrl-a": "core:select-all-nodes",
|
"ctrl-a": "core:select-all-nodes",
|
||||||
"shift-?": "core:show-help",
|
"shift-?": "core:show-help",
|
||||||
|
"w": "core:scroll-view-up",
|
||||||
|
"d": "core:scroll-view-right",
|
||||||
|
"s": "core:scroll-view-down",
|
||||||
|
"a": "core:scroll-view-left",
|
||||||
|
"shift-w": "core:step-view-up",
|
||||||
|
"shift-d": "core:step-view-right",
|
||||||
|
"shift-s": "core:step-view-down",
|
||||||
|
"shift-a": "core:step-view-left",
|
||||||
"up": "core:move-selection-up",
|
"up": "core:move-selection-up",
|
||||||
"right": "core:move-selection-right",
|
"right": "core:move-selection-right",
|
||||||
"down": "core:move-selection-down",
|
"down": "core:move-selection-down",
|
||||||
@ -53,6 +62,10 @@
|
|||||||
"shift-down": "core:step-selection-down",
|
"shift-down": "core:step-selection-down",
|
||||||
"shift-left": "core:step-selection-left",
|
"shift-left": "core:step-selection-left",
|
||||||
"ctrl-shift-j": "core:show-previous-tab",
|
"ctrl-shift-j": "core:show-previous-tab",
|
||||||
"ctrl-shift-k": "core:show-next-tab"
|
"ctrl-shift-k": "core:show-next-tab",
|
||||||
|
"ctrl-shift-g": "core:group-selection",
|
||||||
|
"ctrl-shift-u": "core:ungroup-selection",
|
||||||
|
"ctrl-shift-c": "core:copy-group-style",
|
||||||
|
"ctrl-shift-v": "core:paste-group-style"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,16 @@ RED.nodes = (function() {
|
|||||||
var subflows = {};
|
var subflows = {};
|
||||||
var loadedFlowVersion = null;
|
var loadedFlowVersion = null;
|
||||||
|
|
||||||
|
var groups = {};
|
||||||
|
var groupsByZ = {};
|
||||||
|
|
||||||
var initialLoad;
|
var initialLoad;
|
||||||
|
|
||||||
var dirty = false;
|
var dirty = false;
|
||||||
|
|
||||||
function setDirty(d) {
|
function setDirty(d) {
|
||||||
dirty = d;
|
dirty = d;
|
||||||
RED.events.emit("nodes:change",{dirty:dirty});
|
RED.events.emit("workspace:dirty",{dirty:dirty});
|
||||||
}
|
}
|
||||||
|
|
||||||
var registry = (function() {
|
var registry = (function() {
|
||||||
@ -193,18 +196,17 @@ RED.nodes = (function() {
|
|||||||
if (n.type.indexOf("subflow") !== 0) {
|
if (n.type.indexOf("subflow") !== 0) {
|
||||||
n["_"] = n._def._;
|
n["_"] = n._def._;
|
||||||
} else {
|
} else {
|
||||||
|
var subflowId = n.type.substring(8);
|
||||||
|
var sf = RED.nodes.subflow(subflowId);
|
||||||
|
if (sf) {
|
||||||
|
sf.instances.push(sf);
|
||||||
|
}
|
||||||
n["_"] = RED._;
|
n["_"] = RED._;
|
||||||
}
|
}
|
||||||
if (n._def.category == "config") {
|
if (n._def.category == "config") {
|
||||||
configNodes[n.id] = n;
|
configNodes[n.id] = n;
|
||||||
} else {
|
} else {
|
||||||
n.ports = [];
|
|
||||||
if (n.wires && (n.wires.length > n.outputs)) { n.outputs = n.wires.length; }
|
if (n.wires && (n.wires.length > n.outputs)) { n.outputs = n.wires.length; }
|
||||||
if (n.outputs) {
|
|
||||||
for (var i=0;i<n.outputs;i++) {
|
|
||||||
n.ports.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
updateConfigNodeUsers(n);
|
updateConfigNodeUsers(n);
|
||||||
if (n._def.category == "subflows" && typeof n.i === "undefined") {
|
if (n._def.category == "subflows" && typeof n.i === "undefined") {
|
||||||
@ -225,6 +227,7 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
function addLink(l) {
|
function addLink(l) {
|
||||||
links.push(l);
|
links.push(l);
|
||||||
|
RED.events.emit("links:add",l);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNode(id) {
|
function getNode(id) {
|
||||||
@ -257,7 +260,7 @@ RED.nodes = (function() {
|
|||||||
delete nodeTabMap[node.z][node.id];
|
delete nodeTabMap[node.z][node.id];
|
||||||
}
|
}
|
||||||
removedLinks = links.filter(function(l) { return (l.source === node) || (l.target === node); });
|
removedLinks = links.filter(function(l) { return (l.source === node) || (l.target === node); });
|
||||||
removedLinks.forEach(function(l) {links.splice(links.indexOf(l), 1); });
|
removedLinks.forEach(removeLink);
|
||||||
var updatedConfigNode = false;
|
var updatedConfigNode = false;
|
||||||
for (var d in node._def.defaults) {
|
for (var d in node._def.defaults) {
|
||||||
if (node._def.defaults.hasOwnProperty(d)) {
|
if (node._def.defaults.hasOwnProperty(d)) {
|
||||||
@ -280,6 +283,15 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (node.type.indexOf("subflow:") === 0) {
|
||||||
|
var subflowId = node.type.substring(8);
|
||||||
|
var sf = RED.nodes.subflow(subflowId);
|
||||||
|
if (sf) {
|
||||||
|
sf.instances.splice(sf.instances.indexOf(node),1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (updatedConfigNode) {
|
if (updatedConfigNode) {
|
||||||
RED.workspaces.refresh();
|
RED.workspaces.refresh();
|
||||||
}
|
}
|
||||||
@ -293,6 +305,9 @@ RED.nodes = (function() {
|
|||||||
RED.events.emit('nodes:remove',node);
|
RED.events.emit('nodes:remove',node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (node && node._def.onremove) {
|
if (node && node._def.onremove) {
|
||||||
// Deprecated: never documented but used by some early nodes
|
// 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");
|
console.log("Deprecated API warning: node type ",node.type," has an onremove function - should be oneditremove - please report");
|
||||||
@ -302,6 +317,10 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function moveNodeToTab(node, z) {
|
function moveNodeToTab(node, z) {
|
||||||
|
if (node.type === "group") {
|
||||||
|
moveGroupToTab(node,z);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (nodeTabMap[node.z]) {
|
if (nodeTabMap[node.z]) {
|
||||||
delete nodeTabMap[node.z][node.id];
|
delete nodeTabMap[node.z][node.id];
|
||||||
}
|
}
|
||||||
@ -310,6 +329,15 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
nodeTabMap[z][node.id] = node;
|
nodeTabMap[z][node.id] = node;
|
||||||
node.z = z;
|
node.z = z;
|
||||||
|
RED.events.emit("nodes:change",node);
|
||||||
|
}
|
||||||
|
function moveGroupToTab(group, z) {
|
||||||
|
var index = groupsByZ[group.z].indexOf(group);
|
||||||
|
groupsByZ[group.z].splice(index,1);
|
||||||
|
groupsByZ[z] = groupsByZ[z] || [];
|
||||||
|
groupsByZ[z].push(group);
|
||||||
|
group.z = z;
|
||||||
|
RED.events.emit("groups:change",group);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeLink(l) {
|
function removeLink(l) {
|
||||||
@ -317,6 +345,7 @@ RED.nodes = (function() {
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
links.splice(index,1);
|
links.splice(index,1);
|
||||||
}
|
}
|
||||||
|
RED.events.emit("links:remove",l);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWorkspace(ws,targetIndex) {
|
function addWorkspace(ws,targetIndex) {
|
||||||
@ -329,38 +358,63 @@ RED.nodes = (function() {
|
|||||||
} else {
|
} else {
|
||||||
workspacesOrder.splice(targetIndex,0,ws.id);
|
workspacesOrder.splice(targetIndex,0,ws.id);
|
||||||
}
|
}
|
||||||
|
RED.events.emit('flows:add',ws);
|
||||||
|
if (targetIndex !== undefined) {
|
||||||
|
RED.events.emit('flows:reorder',workspacesOrder)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function getWorkspace(id) {
|
function getWorkspace(id) {
|
||||||
return workspaces[id];
|
return workspaces[id];
|
||||||
}
|
}
|
||||||
function removeWorkspace(id) {
|
function removeWorkspace(id) {
|
||||||
delete workspaces[id];
|
var ws = workspaces[id];
|
||||||
delete nodeTabMap[id];
|
|
||||||
workspacesOrder.splice(workspacesOrder.indexOf(id),1);
|
|
||||||
|
|
||||||
var removedNodes = [];
|
var removedNodes = [];
|
||||||
var removedLinks = [];
|
var removedLinks = [];
|
||||||
var n;
|
var removedGroups = [];
|
||||||
var node;
|
if (ws) {
|
||||||
for (n=0;n<nodes.length;n++) {
|
delete workspaces[id];
|
||||||
node = nodes[n];
|
delete nodeTabMap[id];
|
||||||
if (node.z == id) {
|
workspacesOrder.splice(workspacesOrder.indexOf(id),1);
|
||||||
removedNodes.push(node);
|
var i;
|
||||||
}
|
var node;
|
||||||
}
|
for (i=0;i<nodes.length;i++) {
|
||||||
for(n in configNodes) {
|
node = nodes[i];
|
||||||
if (configNodes.hasOwnProperty(n)) {
|
|
||||||
node = configNodes[n];
|
|
||||||
if (node.z == id) {
|
if (node.z == id) {
|
||||||
removedNodes.push(node);
|
removedNodes.push(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for(i in configNodes) {
|
||||||
|
if (configNodes.hasOwnProperty(i)) {
|
||||||
|
node = configNodes[i];
|
||||||
|
if (node.z == id) {
|
||||||
|
removedNodes.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0;i<removedNodes.length;i++) {
|
||||||
|
var result = removeNode(removedNodes[i].id);
|
||||||
|
removedLinks = removedLinks.concat(result.links);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must get 'removedGroups' in the right order.
|
||||||
|
// - start with the top-most groups
|
||||||
|
// - then recurse into them
|
||||||
|
removedGroups = (groupsByZ[id] || []).filter(function(g) { return !g.g; });
|
||||||
|
for (i=0;i<removedGroups.length;i++) {
|
||||||
|
removedGroups[i].nodes.forEach(function(n) {
|
||||||
|
if (n.type === "group") {
|
||||||
|
removedGroups.push(n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Now remove them in the reverse order
|
||||||
|
for (i=removedGroups.length-1; i>=0; i--) {
|
||||||
|
removeGroup(removedGroups[i]);
|
||||||
|
}
|
||||||
|
RED.events.emit('flows:remove',ws);
|
||||||
}
|
}
|
||||||
for (n=0;n<removedNodes.length;n++) {
|
return {nodes:removedNodes,links:removedLinks, groups: removedGroups};
|
||||||
var result = removeNode(removedNodes[n].id);
|
|
||||||
removedLinks = removedLinks.concat(result.links);
|
|
||||||
}
|
|
||||||
return {nodes:removedNodes,links:removedLinks};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSubflow(sf, createNewIds) {
|
function addSubflow(sf, createNewIds) {
|
||||||
@ -398,6 +452,10 @@ RED.nodes = (function() {
|
|||||||
paletteLabel: function() { return RED.nodes.subflow(sf.id).name },
|
paletteLabel: function() { return RED.nodes.subflow(sf.id).name },
|
||||||
inputLabels: function(i) { return sf.inputLabels?sf.inputLabels[i]:null },
|
inputLabels: function(i) { return sf.inputLabels?sf.inputLabels[i]:null },
|
||||||
outputLabels: function(i) { return sf.outputLabels?sf.outputLabels[i]:null },
|
outputLabels: function(i) { return sf.outputLabels?sf.outputLabels[i]:null },
|
||||||
|
oneditprepare: function() {
|
||||||
|
RED.subflow.buildEditForm("subflow",this);
|
||||||
|
RED.subflow.buildPropertiesForm(this);
|
||||||
|
},
|
||||||
oneditresize: function(size) {
|
oneditresize: function(size) {
|
||||||
// var rows = $(".dialog-form>div:not(.node-input-env-container-row)");
|
// var rows = $(".dialog-form>div:not(.node-input-env-container-row)");
|
||||||
var height = size.height;
|
var height = size.height;
|
||||||
@ -412,15 +470,20 @@ RED.nodes = (function() {
|
|||||||
module: "node-red"
|
module: "node-red"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
sf.instances = [];
|
||||||
sf._def = RED.nodes.getType("subflow:"+sf.id);
|
sf._def = RED.nodes.getType("subflow:"+sf.id);
|
||||||
|
RED.events.emit("subflows:add",sf);
|
||||||
}
|
}
|
||||||
function getSubflow(id) {
|
function getSubflow(id) {
|
||||||
return subflows[id];
|
return subflows[id];
|
||||||
}
|
}
|
||||||
function removeSubflow(sf) {
|
function removeSubflow(sf) {
|
||||||
delete subflows[sf.id];
|
if (subflows[sf.id]) {
|
||||||
delete nodeTabMap[sf.id];
|
delete subflows[sf.id];
|
||||||
registry.removeNodeType("subflow:"+sf.id);
|
delete nodeTabMap[sf.id];
|
||||||
|
registry.removeNodeType("subflow:"+sf.id);
|
||||||
|
RED.events.emit("subflows:remove",sf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function subflowContains(sfid,nodeid) {
|
function subflowContains(sfid,nodeid) {
|
||||||
@ -493,6 +556,9 @@ RED.nodes = (function() {
|
|||||||
if (n.d === true) {
|
if (n.d === true) {
|
||||||
node.d = true;
|
node.d = true;
|
||||||
}
|
}
|
||||||
|
if (n.g) {
|
||||||
|
node.g = n.g;
|
||||||
|
}
|
||||||
if (node.type == "unknown") {
|
if (node.type == "unknown") {
|
||||||
for (var p in n._orig) {
|
for (var p in n._orig) {
|
||||||
if (n._orig.hasOwnProperty(p)) {
|
if (n._orig.hasOwnProperty(p)) {
|
||||||
@ -505,19 +571,33 @@ RED.nodes = (function() {
|
|||||||
node[d] = n[d];
|
node[d] = n[d];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(exportCreds && n.credentials) {
|
if (exportCreds) {
|
||||||
var credentialSet = {};
|
var credentialSet = {};
|
||||||
node.credentials = {};
|
if (/^subflow:/.test(node.type) && n.credentials) {
|
||||||
for (var cred in n._def.credentials) {
|
// A subflow instance node can have arbitrary creds
|
||||||
if (n._def.credentials.hasOwnProperty(cred)) {
|
for (var sfCred in n.credentials) {
|
||||||
if (n._def.credentials[cred].type == 'password') {
|
if (n.credentials.hasOwnProperty(sfCred)) {
|
||||||
if (!n.credentials._ ||
|
if (!n.credentials._ ||
|
||||||
n.credentials["has_"+cred] != n.credentials._["has_"+cred] ||
|
n.credentials["has_"+sfCred] != n.credentials._["has_"+sfCred] ||
|
||||||
(n.credentials["has_"+cred] && n.credentials[cred])) {
|
(n.credentials["has_"+sfCred] && n.credentials[sfCred])) {
|
||||||
|
credentialSet[sfCred] = n.credentials[sfCred];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (n.credentials) {
|
||||||
|
node.credentials = {};
|
||||||
|
// All other nodes have a well-defined list of possible credentials
|
||||||
|
for (var cred in n._def.credentials) {
|
||||||
|
if (n._def.credentials.hasOwnProperty(cred)) {
|
||||||
|
if (n._def.credentials[cred].type == 'password') {
|
||||||
|
if (!n.credentials._ ||
|
||||||
|
n.credentials["has_"+cred] != n.credentials._["has_"+cred] ||
|
||||||
|
(n.credentials["has_"+cred] && n.credentials[cred])) {
|
||||||
|
credentialSet[cred] = n.credentials[cred];
|
||||||
|
}
|
||||||
|
} else if (n.credentials[cred] != null && (!n.credentials._ || n.credentials[cred] != n.credentials._[cred])) {
|
||||||
credentialSet[cred] = n.credentials[cred];
|
credentialSet[cred] = n.credentials[cred];
|
||||||
}
|
}
|
||||||
} else if (n.credentials[cred] != null && (!n.credentials._ || n.credentials[cred] != n.credentials._[cred])) {
|
|
||||||
credentialSet[cred] = n.credentials[cred];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,6 +606,13 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (n.type === "group") {
|
||||||
|
node.x = n.x;
|
||||||
|
node.y = n.y;
|
||||||
|
node.w = n.w;
|
||||||
|
node.h = n.h;
|
||||||
|
node.nodes = node.nodes.map(function(n) { return n.id });
|
||||||
|
}
|
||||||
if (n._def.category != "config") {
|
if (n._def.category != "config") {
|
||||||
node.x = n.x;
|
node.x = n.x;
|
||||||
node.y = n.y;
|
node.y = n.y;
|
||||||
@ -568,7 +655,7 @@ RED.nodes = (function() {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertSubflow(n) {
|
function convertSubflow(n, exportCreds) {
|
||||||
var node = {};
|
var node = {};
|
||||||
node.id = n.id;
|
node.id = n.id;
|
||||||
node.type = n.type;
|
node.type = n.type;
|
||||||
@ -578,6 +665,24 @@ RED.nodes = (function() {
|
|||||||
node.in = [];
|
node.in = [];
|
||||||
node.out = [];
|
node.out = [];
|
||||||
node.env = n.env;
|
node.env = n.env;
|
||||||
|
|
||||||
|
if (exportCreds) {
|
||||||
|
var credentialSet = {};
|
||||||
|
// A subflow node can have arbitrary creds
|
||||||
|
for (var sfCred in n.credentials) {
|
||||||
|
if (n.credentials.hasOwnProperty(sfCred)) {
|
||||||
|
if (!n.credentials._ ||
|
||||||
|
n.credentials["has_"+sfCred] != n.credentials._["has_"+sfCred] ||
|
||||||
|
(n.credentials["has_"+sfCred] && n.credentials[sfCred])) {
|
||||||
|
credentialSet[sfCred] = n.credentials[sfCred];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Object.keys(credentialSet).length > 0) {
|
||||||
|
node.credentials = credentialSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
node.color = n.color;
|
node.color = n.color;
|
||||||
|
|
||||||
n.in.forEach(function(p) {
|
n.in.forEach(function(p) {
|
||||||
@ -633,8 +738,18 @@ RED.nodes = (function() {
|
|||||||
/**
|
/**
|
||||||
* Converts the current node selection to an exportable JSON Object
|
* Converts the current node selection to an exportable JSON Object
|
||||||
**/
|
**/
|
||||||
function createExportableNodeSet(set, exportedSubflows, exportedConfigNodes) {
|
function createExportableNodeSet(set, exportedIds, exportedSubflows, exportedConfigNodes) {
|
||||||
var nns = [];
|
var nns = [];
|
||||||
|
|
||||||
|
exportedIds = exportedIds || {};
|
||||||
|
set = set.filter(function(n) {
|
||||||
|
if (exportedIds[n.id]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
exportedIds[n.id] = true;
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
|
||||||
exportedConfigNodes = exportedConfigNodes || {};
|
exportedConfigNodes = exportedConfigNodes || {};
|
||||||
exportedSubflows = exportedSubflows || {};
|
exportedSubflows = exportedSubflows || {};
|
||||||
for (var n=0;n<set.length;n++) {
|
for (var n=0;n<set.length;n++) {
|
||||||
@ -650,11 +765,11 @@ RED.nodes = (function() {
|
|||||||
subflowSet.push(n);
|
subflowSet.push(n);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var exportableSubflow = createExportableNodeSet(subflowSet, exportedSubflows, exportedConfigNodes);
|
var exportableSubflow = createExportableNodeSet(subflowSet, exportedIds, exportedSubflows, exportedConfigNodes);
|
||||||
nns = exportableSubflow.concat(nns);
|
nns = exportableSubflow.concat(nns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node.type != "subflow") {
|
if (node.type !== "subflow") {
|
||||||
var convertedNode = RED.nodes.convertNode(node);
|
var convertedNode = RED.nodes.convertNode(node);
|
||||||
for (var d in node._def.defaults) {
|
for (var d in node._def.defaults) {
|
||||||
if (node._def.defaults[d].type && node[d] in configNodes) {
|
if (node._def.defaults[d].type && node[d] in configNodes) {
|
||||||
@ -671,6 +786,9 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
nns.push(convertedNode);
|
nns.push(convertedNode);
|
||||||
|
if (node.type === "group") {
|
||||||
|
nns = nns.concat(createExportableNodeSet(node.nodes, exportedIds, exportedSubflows, exportedConfigNodes));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
var convertedSubflow = convertSubflow(node);
|
var convertedSubflow = convertSubflow(node);
|
||||||
nns.push(convertedSubflow);
|
nns.push(convertedSubflow);
|
||||||
@ -693,7 +811,12 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
for (i in subflows) {
|
for (i in subflows) {
|
||||||
if (subflows.hasOwnProperty(i)) {
|
if (subflows.hasOwnProperty(i)) {
|
||||||
nns.push(convertSubflow(subflows[i]));
|
nns.push(convertSubflow(subflows[i], exportCredentials));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i in groups) {
|
||||||
|
if (groups.hasOwnProperty(i)) {
|
||||||
|
nns.push(convertNode(groups[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i in configNodes) {
|
for (i in configNodes) {
|
||||||
@ -822,6 +945,7 @@ RED.nodes = (function() {
|
|||||||
if (n.type != "workspace" &&
|
if (n.type != "workspace" &&
|
||||||
n.type != "tab" &&
|
n.type != "tab" &&
|
||||||
n.type != "subflow" &&
|
n.type != "subflow" &&
|
||||||
|
n.type != "group" &&
|
||||||
!registry.getNodeType(n.type) &&
|
!registry.getNodeType(n.type) &&
|
||||||
n.type.substring(0,8) != "subflow:" &&
|
n.type.substring(0,8) != "subflow:" &&
|
||||||
unknownTypes.indexOf(n.type)==-1) {
|
unknownTypes.indexOf(n.type)==-1) {
|
||||||
@ -871,6 +995,7 @@ RED.nodes = (function() {
|
|||||||
var node_map = {};
|
var node_map = {};
|
||||||
var new_nodes = [];
|
var new_nodes = [];
|
||||||
var new_links = [];
|
var new_links = [];
|
||||||
|
var new_groups = [];
|
||||||
var nid;
|
var nid;
|
||||||
var def;
|
var def;
|
||||||
var configNode;
|
var configNode;
|
||||||
@ -1021,7 +1146,6 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
node_map[n.id] = configNode;
|
node_map[n.id] = configNode;
|
||||||
new_nodes.push(configNode);
|
new_nodes.push(configNode);
|
||||||
RED.nodes.add(configNode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1038,20 +1162,25 @@ RED.nodes = (function() {
|
|||||||
y:parseFloat(n.y || 0),
|
y:parseFloat(n.y || 0),
|
||||||
z:n.z,
|
z:n.z,
|
||||||
type:0,
|
type:0,
|
||||||
wires:n.wires||[],
|
|
||||||
inputLabels: n.inputLabels,
|
|
||||||
outputLabels: n.outputLabels,
|
|
||||||
icon: n.icon,
|
|
||||||
info: n.info,
|
info: n.info,
|
||||||
changed:false,
|
changed:false,
|
||||||
_config:{}
|
_config:{}
|
||||||
};
|
}
|
||||||
|
if (n.type !== "group") {
|
||||||
|
node.wires = n.wires||[];
|
||||||
|
node.inputLabels = n.inputLabels;
|
||||||
|
node.outputLabels = n.outputLabels;
|
||||||
|
node.icon = n.icon;
|
||||||
|
}
|
||||||
if (n.hasOwnProperty('l')) {
|
if (n.hasOwnProperty('l')) {
|
||||||
node.l = n.l;
|
node.l = n.l;
|
||||||
}
|
}
|
||||||
if (n.hasOwnProperty('d')) {
|
if (n.hasOwnProperty('d')) {
|
||||||
node.d = n.d;
|
node.d = n.d;
|
||||||
}
|
}
|
||||||
|
if (n.hasOwnProperty('g')) {
|
||||||
|
node.g = n.g;
|
||||||
|
}
|
||||||
if (createNewIds) {
|
if (createNewIds) {
|
||||||
if (subflow_blacklist[n.z]) {
|
if (subflow_blacklist[n.z]) {
|
||||||
continue;
|
continue;
|
||||||
@ -1088,7 +1217,17 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
node.type = n.type;
|
node.type = n.type;
|
||||||
node._def = def;
|
node._def = def;
|
||||||
if (n.type.substring(0,7) === "subflow") {
|
if (node.type === "group") {
|
||||||
|
node._def = RED.group.def;
|
||||||
|
for (d in node._def.defaults) {
|
||||||
|
if (node._def.defaults.hasOwnProperty(d) && d !== 'inputs' && d !== 'outputs') {
|
||||||
|
node[d] = n[d];
|
||||||
|
node._config[d] = JSON.stringify(n[d]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node._config.x = node.x;
|
||||||
|
node._config.y = node.y;
|
||||||
|
} else if (n.type.substring(0,7) === "subflow") {
|
||||||
var parentId = n.type.split(":")[1];
|
var parentId = n.type.split(":")[1];
|
||||||
var subflow = subflow_blacklist[parentId]||subflow_map[parentId]||getSubflow(parentId);
|
var subflow = subflow_blacklist[parentId]||subflow_map[parentId]||getSubflow(parentId);
|
||||||
if (createNewIds) {
|
if (createNewIds) {
|
||||||
@ -1178,13 +1317,13 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addNode(node);
|
|
||||||
RED.editor.validateNode(node);
|
|
||||||
node_map[n.id] = node;
|
node_map[n.id] = node;
|
||||||
// If an 'unknown' config node, it will not have been caught by the
|
// If an 'unknown' config node, it will not have been caught by the
|
||||||
// proper config node handling, so needs adding to new_nodes here
|
// proper config node handling, so needs adding to new_nodes here
|
||||||
if (node.type === "unknown" || node._def.category !== "config") {
|
if (node.type === "unknown" || node._def.category !== "config") {
|
||||||
new_nodes.push(node);
|
new_nodes.push(node);
|
||||||
|
} else if (node.type === "group") {
|
||||||
|
new_groups.push(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1219,12 +1358,17 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
delete n.wires;
|
delete n.wires;
|
||||||
}
|
}
|
||||||
|
if (n.g && node_map[n.g]) {
|
||||||
|
n.g = node_map[n.g].id;
|
||||||
|
} else {
|
||||||
|
delete n.g
|
||||||
|
}
|
||||||
for (var d3 in n._def.defaults) {
|
for (var d3 in n._def.defaults) {
|
||||||
if (n._def.defaults.hasOwnProperty(d3)) {
|
if (n._def.defaults.hasOwnProperty(d3)) {
|
||||||
if (n._def.defaults[d3].type && node_map[n[d3]]) {
|
if (n._def.defaults[d3].type && node_map[n[d3]]) {
|
||||||
n[d3] = node_map[n[d3]].id;
|
configNode = node_map[n[d3]];
|
||||||
configNode = RED.nodes.node(n[d3]);
|
n[d3] = configNode.id;
|
||||||
if (configNode && configNode.users.indexOf(n) === -1) {
|
if (configNode.users.indexOf(n) === -1) {
|
||||||
configNode.users.push(n);
|
configNode.users.push(n);
|
||||||
}
|
}
|
||||||
} else if (nodeTypeArrayReferences.hasOwnProperty(n.type) && nodeTypeArrayReferences[n.type] === d3 && n[d3] !== undefined && n[d3] !== null) {
|
} else if (nodeTypeArrayReferences.hasOwnProperty(n.type) && nodeTypeArrayReferences[n.type] === d3 && n[d3] !== undefined && n[d3] !== null) {
|
||||||
@ -1245,10 +1389,6 @@ RED.nodes = (function() {
|
|||||||
return (otherNode && otherNode.z === activeWorkspace)
|
return (otherNode && otherNode.z === activeWorkspace)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// With all properties now remapped to point at valid nodes,
|
|
||||||
// we can validate the node
|
|
||||||
RED.editor.validateNode(n);
|
|
||||||
}
|
}
|
||||||
for (i=0;i<new_subflows.length;i++) {
|
for (i=0;i<new_subflows.length;i++) {
|
||||||
n = new_subflows[i];
|
n = new_subflows[i];
|
||||||
@ -1287,9 +1427,33 @@ RED.nodes = (function() {
|
|||||||
delete n.status.wires;
|
delete n.status.wires;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (i=0;i<new_groups.length;i++) {
|
||||||
|
n = new_groups[i];
|
||||||
|
if (n.g && node_map[n.g]) {
|
||||||
|
n.g = node_map[n.g].id;
|
||||||
|
} else {
|
||||||
|
delete n.g;
|
||||||
|
}
|
||||||
|
n.nodes = n.nodes.map(function(id) {
|
||||||
|
return node_map[id];
|
||||||
|
})
|
||||||
|
addGroup(n);
|
||||||
|
}
|
||||||
|
// Now the nodes have been fully updated, add them.
|
||||||
|
for (i=0;i<new_nodes.length;i++) {
|
||||||
|
var node = new_nodes[i];
|
||||||
|
addNode(node);
|
||||||
|
}
|
||||||
|
// Finally validate them all.
|
||||||
|
// This has to be done after everything is added so that any checks for
|
||||||
|
// dependent config nodes will pass
|
||||||
|
for (i=0;i<new_nodes.length;i++) {
|
||||||
|
var node = new_nodes[i];
|
||||||
|
RED.editor.validateNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
RED.workspaces.refresh();
|
RED.workspaces.refresh();
|
||||||
return [new_nodes,new_links,new_workspaces,new_subflows,missingWorkspace];
|
return [new_nodes,new_links,new_groups,new_workspaces,new_subflows,missingWorkspace];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: supports filter.z|type
|
// TODO: supports filter.z|type
|
||||||
@ -1380,6 +1544,9 @@ RED.nodes = (function() {
|
|||||||
nodeTabMap = {};
|
nodeTabMap = {};
|
||||||
configNodes = {};
|
configNodes = {};
|
||||||
workspacesOrder = [];
|
workspacesOrder = [];
|
||||||
|
groups = {};
|
||||||
|
groupsByZ = {};
|
||||||
|
|
||||||
var subflowIds = Object.keys(subflows);
|
var subflowIds = Object.keys(subflows);
|
||||||
subflowIds.forEach(function(id) {
|
subflowIds.forEach(function(id) {
|
||||||
RED.subflow.removeSubflow(id)
|
RED.subflow.removeSubflow(id)
|
||||||
@ -1391,12 +1558,14 @@ RED.nodes = (function() {
|
|||||||
defaultWorkspace = null;
|
defaultWorkspace = null;
|
||||||
initialLoad = null;
|
initialLoad = null;
|
||||||
RED.nodes.dirty(false);
|
RED.nodes.dirty(false);
|
||||||
RED.view.redraw(true);
|
RED.view.redraw(true, true);
|
||||||
RED.palette.refresh();
|
RED.palette.refresh();
|
||||||
RED.workspaces.refresh();
|
RED.workspaces.refresh();
|
||||||
RED.sidebar.config.refresh();
|
RED.sidebar.config.refresh();
|
||||||
RED.sidebar.info.refresh();
|
RED.sidebar.info.refresh();
|
||||||
|
|
||||||
|
RED.events.emit("workspace:clear");
|
||||||
|
|
||||||
// var node_defs = {};
|
// var node_defs = {};
|
||||||
// var nodes = [];
|
// var nodes = [];
|
||||||
// var configNodes = {};
|
// var configNodes = {};
|
||||||
@ -1408,6 +1577,31 @@ RED.nodes = (function() {
|
|||||||
// var loadedFlowVersion = null;
|
// var loadedFlowVersion = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addGroup(group) {
|
||||||
|
groupsByZ[group.z] = groupsByZ[group.z] || [];
|
||||||
|
groupsByZ[group.z].push(group);
|
||||||
|
groups[group.id] = group;
|
||||||
|
RED.events.emit("groups:add",group);
|
||||||
|
}
|
||||||
|
function removeGroup(group) {
|
||||||
|
var i = groupsByZ[group.z].indexOf(group);
|
||||||
|
groupsByZ[group.z].splice(i,1);
|
||||||
|
if (groupsByZ[group.z].length === 0) {
|
||||||
|
delete groupsByZ[group.z];
|
||||||
|
}
|
||||||
|
if (group.g) {
|
||||||
|
if (groups[group.g]) {
|
||||||
|
var index = groups[group.g].nodes.indexOf(group);
|
||||||
|
groups[group.g].nodes.splice(index,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RED.group.markDirty(group);
|
||||||
|
|
||||||
|
delete groups[group.id];
|
||||||
|
RED.events.emit("groups:remove",group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: function() {
|
init: function() {
|
||||||
RED.events.on("registry:node-type-added",function(type) {
|
RED.events.on("registry:node-type-added",function(type) {
|
||||||
@ -1451,8 +1645,9 @@ RED.nodes = (function() {
|
|||||||
});
|
});
|
||||||
removeLinks.forEach(removeLink);
|
removeLinks.forEach(removeLink);
|
||||||
|
|
||||||
|
// Force the redraw to be synchronous so the view updates
|
||||||
RED.view.redraw(true);
|
// *now* and removes the unknown node
|
||||||
|
RED.view.redraw(true, true);
|
||||||
var result = importNodes(reimportList,false);
|
var result = importNodes(reimportList,false);
|
||||||
var newNodeMap = {};
|
var newNodeMap = {};
|
||||||
result[0].forEach(function(n) {
|
result[0].forEach(function(n) {
|
||||||
@ -1506,6 +1701,11 @@ RED.nodes = (function() {
|
|||||||
subflow: getSubflow,
|
subflow: getSubflow,
|
||||||
subflowContains: subflowContains,
|
subflowContains: subflowContains,
|
||||||
|
|
||||||
|
addGroup: addGroup,
|
||||||
|
removeGroup: removeGroup,
|
||||||
|
group: function(id) { return groups[id] },
|
||||||
|
groups: function(z) { return groupsByZ[z]||[] },
|
||||||
|
|
||||||
eachNode: function(cb) {
|
eachNode: function(cb) {
|
||||||
for (var n=0;n<nodes.length;n++) {
|
for (var n=0;n<nodes.length;n++) {
|
||||||
if (cb(nodes[n]) === false) {
|
if (cb(nodes[n]) === false) {
|
||||||
|
41
packages/node_modules/@node-red/editor-client/src/js/polyfills.js
vendored
Normal file
41
packages/node_modules/@node-red/editor-client/src/js/polyfills.js
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
(function() {
|
||||||
|
var isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
|
||||||
|
|
||||||
|
if (isIE11) {
|
||||||
|
// IE11 DOMTokenList.toggle does not support the two-argument variety
|
||||||
|
window.DOMTokenList.prototype.toggle = function(cl,bo) {
|
||||||
|
if (arguments.length === 1) {
|
||||||
|
bo = !this.contains(cl);
|
||||||
|
}
|
||||||
|
this[!!bo?"add":"remove"](cl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IE11 does not provide classList on SVGElements
|
||||||
|
if (! ("classList" in SVGElement.prototype)) {
|
||||||
|
Object.defineProperty(SVGElement.prototype, 'classList', Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'classList'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// IE11 does not provide children on SVGElements
|
||||||
|
if (! ("children" in SVGElement.prototype)) {
|
||||||
|
Object.defineProperty(SVGElement.prototype, 'children', Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'children'));
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.from = function() {
|
||||||
|
if (arguments.length > 1) {
|
||||||
|
throw new Error("Node-RED's IE11 Array.from polyfill doesn't support multiple arguments");
|
||||||
|
}
|
||||||
|
var arrayLike = arguments[0]
|
||||||
|
var result = [];
|
||||||
|
if (arrayLike.forEach) {
|
||||||
|
arrayLike.forEach(function(i) {
|
||||||
|
result.push(i);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
for (var i=0;i<arrayLike.length;i++) {
|
||||||
|
result.push(arrayList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -75,6 +75,7 @@ var RED = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadNodeList() {
|
function loadNodeList() {
|
||||||
|
loader.reportProgress(RED._("event.loadPalette"), 20)
|
||||||
$.ajax({
|
$.ajax({
|
||||||
headers: {
|
headers: {
|
||||||
"Accept":"application/json"
|
"Accept":"application/json"
|
||||||
@ -83,6 +84,7 @@ var RED = (function() {
|
|||||||
url: 'nodes',
|
url: 'nodes',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
RED.nodes.setNodeList(data);
|
RED.nodes.setNodeList(data);
|
||||||
|
loader.reportProgress(RED._("event.loadNodeCatalogs"), 25)
|
||||||
RED.i18n.loadNodeCatalogs(function() {
|
RED.i18n.loadNodeCatalogs(function() {
|
||||||
loadIconList(loadNodes);
|
loadIconList(loadNodes);
|
||||||
});
|
});
|
||||||
@ -107,6 +109,7 @@ var RED = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadNodes() {
|
function loadNodes() {
|
||||||
|
loader.reportProgress(RED._("event.loadNodes",{count:""}), 30)
|
||||||
var lang = localStorage.getItem("editor-language")||i18n.detectLanguage();
|
var lang = localStorage.getItem("editor-language")||i18n.detectLanguage();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -118,15 +121,19 @@ var RED = (function() {
|
|||||||
url: 'nodes',
|
url: 'nodes',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var configs = data.trim().split(/(?=<!-- --- \[red-module:\S+\] --- -->)/);
|
var configs = data.trim().split(/(?=<!-- --- \[red-module:\S+\] --- -->)/);
|
||||||
|
var totalCount = configs.length;
|
||||||
|
|
||||||
var stepConfig = function() {
|
var stepConfig = function() {
|
||||||
|
loader.reportProgress(RED._("event.loadNodes",{count:(totalCount-configs.length)+"/"+totalCount}), 30 + ((totalCount-configs.length)/totalCount)*40 )
|
||||||
|
|
||||||
if (configs.length === 0) {
|
if (configs.length === 0) {
|
||||||
$("#red-ui-editor").i18n();
|
$("#red-ui-editor").i18n();
|
||||||
$("#red-ui-palette > .red-ui-palette-spinner").hide();
|
$("#red-ui-palette > .red-ui-palette-spinner").hide();
|
||||||
$(".red-ui-palette-scroll").removeClass("hide");
|
$(".red-ui-palette-scroll").removeClass("hide");
|
||||||
$("#red-ui-palette-search").removeClass("hide");
|
$("#red-ui-palette-search").removeClass("hide");
|
||||||
loadFlows(function() {
|
if (RED.settings.theme("projects.enabled",false)) {
|
||||||
if (RED.settings.theme("projects.enabled",false)) {
|
RED.projects.refresh(function(activeProject) {
|
||||||
RED.projects.refresh(function(activeProject) {
|
loadFlows(function() {
|
||||||
RED.sidebar.info.refresh()
|
RED.sidebar.info.refresh()
|
||||||
if (!activeProject) {
|
if (!activeProject) {
|
||||||
// Projects enabled but no active project
|
// Projects enabled but no active project
|
||||||
@ -140,12 +147,14 @@ var RED = (function() {
|
|||||||
}
|
}
|
||||||
completeLoad();
|
completeLoad();
|
||||||
});
|
});
|
||||||
} else {
|
});
|
||||||
|
} else {
|
||||||
|
loadFlows(function() {
|
||||||
// Projects disabled by the user
|
// Projects disabled by the user
|
||||||
RED.sidebar.info.refresh()
|
RED.sidebar.info.refresh()
|
||||||
completeLoad();
|
completeLoad();
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
} else {
|
} else {
|
||||||
var config = configs.shift();
|
var config = configs.shift();
|
||||||
appendNodeConfig(config,stepConfig);
|
appendNodeConfig(config,stepConfig);
|
||||||
@ -157,6 +166,7 @@ var RED = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadFlows(done) {
|
function loadFlows(done) {
|
||||||
|
loader.reportProgress(RED._("event.loadFlows"),80 )
|
||||||
$.ajax({
|
$.ajax({
|
||||||
headers: {
|
headers: {
|
||||||
"Accept":"application/json",
|
"Accept":"application/json",
|
||||||
@ -167,6 +177,7 @@ var RED = (function() {
|
|||||||
if (nodes) {
|
if (nodes) {
|
||||||
var currentHash = window.location.hash;
|
var currentHash = window.location.hash;
|
||||||
RED.nodes.version(nodes.rev);
|
RED.nodes.version(nodes.rev);
|
||||||
|
loader.reportProgress(RED._("event.importFlows"),90 )
|
||||||
RED.nodes.import(nodes.flows);
|
RED.nodes.import(nodes.flows);
|
||||||
RED.nodes.dirty(false);
|
RED.nodes.dirty(false);
|
||||||
RED.view.redraw(true);
|
RED.view.redraw(true);
|
||||||
@ -193,6 +204,7 @@ var RED = (function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (notificationId === "project-update") {
|
if (notificationId === "project-update") {
|
||||||
|
loader.start("Loading project",0)
|
||||||
RED.nodes.clear();
|
RED.nodes.clear();
|
||||||
RED.history.clear();
|
RED.history.clear();
|
||||||
RED.view.redraw(true);
|
RED.view.redraw(true);
|
||||||
@ -208,6 +220,7 @@ var RED = (function() {
|
|||||||
"revert": RED._("notification.project.revert", {project: msg.project}),
|
"revert": RED._("notification.project.revert", {project: msg.project}),
|
||||||
"merge-complete": RED._("notification.project.merge-complete")
|
"merge-complete": RED._("notification.project.merge-complete")
|
||||||
}[msg.action];
|
}[msg.action];
|
||||||
|
loader.end()
|
||||||
RED.notify("<p>"+message+"</p>");
|
RED.notify("<p>"+message+"</p>");
|
||||||
RED.sidebar.info.refresh()
|
RED.sidebar.info.refresh()
|
||||||
});
|
});
|
||||||
@ -353,7 +366,7 @@ var RED = (function() {
|
|||||||
var parts = topic.split("/");
|
var parts = topic.split("/");
|
||||||
var node = RED.nodes.node(parts[1]);
|
var node = RED.nodes.node(parts[1]);
|
||||||
if (node) {
|
if (node) {
|
||||||
if (msg.hasOwnProperty("text") && /^[a-zA-Z]/.test(msg.text)) {
|
if (msg.hasOwnProperty("text") && msg.text !== null && /^[a-zA-Z]/.test(msg.text)) {
|
||||||
msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()});
|
msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()});
|
||||||
}
|
}
|
||||||
node.status = msg;
|
node.status = msg;
|
||||||
@ -423,6 +436,12 @@ var RED = (function() {
|
|||||||
var id = topic.substring(9);
|
var id = topic.substring(9);
|
||||||
RED.eventLog.log(id,payload);
|
RED.eventLog.log(id,payload);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(".red-ui-header-toolbar").show();
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
loader.end();
|
||||||
|
},100);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAbout() {
|
function showAbout() {
|
||||||
@ -431,8 +450,7 @@ var RED = (function() {
|
|||||||
'<img width="50px" src="red/images/node-red-icon.svg" />'+
|
'<img width="50px" src="red/images/node-red-icon.svg" />'+
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
RED.sidebar.info.set(aboutHeader+RED.utils.renderMarkdown(data));
|
RED.sidebar.help.set(aboutHeader+RED.utils.renderMarkdown(data));
|
||||||
RED.sidebar.info.show();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,6 +490,14 @@ var RED = (function() {
|
|||||||
{id:"menu-item-subflow-create",label:RED._("menu.label.createSubflow"),onselect:"core:create-subflow"},
|
{id:"menu-item-subflow-create",label:RED._("menu.label.createSubflow"),onselect:"core:create-subflow"},
|
||||||
{id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:"core:convert-to-subflow"},
|
{id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:"core:convert-to-subflow"},
|
||||||
]});
|
]});
|
||||||
|
menuOptions.push({id:"menu-item-group",label:RED._("menu.label.groups"), options: [
|
||||||
|
{id:"menu-item-group-group",label:RED._("menu.label.groupSelection"),disabled:true,onselect:"core:group-selection"},
|
||||||
|
{id:"menu-item-group-ungroup",label:RED._("menu.label.ungroupSelection"),disabled:true,onselect:"core:ungroup-selection"},
|
||||||
|
null,
|
||||||
|
{id:"menu-item-group-merge",label:RED._("menu.label.groupMergeSelection"),disabled:true,onselect:"core:merge-selection-to-group"},
|
||||||
|
{id:"menu-item-group-remove",label:RED._("menu.label.groupRemoveSelection"),disabled:true,onselect:"core:remove-selection-from-group"}
|
||||||
|
]});
|
||||||
|
|
||||||
menuOptions.push(null);
|
menuOptions.push(null);
|
||||||
if (RED.settings.theme('palette.editable') !== false) {
|
if (RED.settings.theme('palette.editable') !== false) {
|
||||||
menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"});
|
menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"});
|
||||||
@ -497,7 +523,6 @@ var RED = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadEditor() {
|
function loadEditor() {
|
||||||
|
|
||||||
RED.workspaces.init();
|
RED.workspaces.init();
|
||||||
RED.statusBar.init();
|
RED.statusBar.init();
|
||||||
RED.view.init();
|
RED.view.init();
|
||||||
@ -524,6 +549,7 @@ var RED = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RED.subflow.init();
|
RED.subflow.init();
|
||||||
|
RED.group.init();
|
||||||
RED.clipboard.init();
|
RED.clipboard.init();
|
||||||
RED.search.init();
|
RED.search.init();
|
||||||
RED.actionList.init();
|
RED.actionList.init();
|
||||||
@ -539,13 +565,14 @@ var RED = (function() {
|
|||||||
RED.comms.connect();
|
RED.comms.connect();
|
||||||
|
|
||||||
$("#red-ui-main-container").show();
|
$("#red-ui-main-container").show();
|
||||||
$(".red-ui-header-toolbar").show();
|
|
||||||
|
|
||||||
RED.actions.add("core:show-about", showAbout);
|
RED.actions.add("core:show-about", showAbout);
|
||||||
|
|
||||||
loadNodeList();
|
loadNodeList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function buildEditor(options) {
|
function buildEditor(options) {
|
||||||
var header = $('<div id="red-ui-header"></div>').appendTo(options.target);
|
var header = $('<div id="red-ui-header"></div>').appendTo(options.target);
|
||||||
var logo = $('<span class="red-ui-header-logo"></span>').appendTo(header);
|
var logo = $('<span class="red-ui-header-logo"></span>').appendTo(header);
|
||||||
@ -560,6 +587,10 @@ var RED = (function() {
|
|||||||
'</div>').appendTo(options.target);
|
'</div>').appendTo(options.target);
|
||||||
$('<div id="red-ui-editor-node-configs"></div>').appendTo(options.target);
|
$('<div id="red-ui-editor-node-configs"></div>').appendTo(options.target);
|
||||||
$('<div id="red-ui-full-shade" class="hide"></div>').appendTo(options.target);
|
$('<div id="red-ui-full-shade" class="hide"></div>').appendTo(options.target);
|
||||||
|
|
||||||
|
loader.init().appendTo("#red-ui-main-container");
|
||||||
|
loader.start("...",0);
|
||||||
|
|
||||||
$.getJSON(options.apiRootUrl+"theme", function(theme) {
|
$.getJSON(options.apiRootUrl+"theme", function(theme) {
|
||||||
if (theme.header) {
|
if (theme.header) {
|
||||||
if (theme.header.url) {
|
if (theme.header.url) {
|
||||||
@ -592,12 +623,39 @@ var RED = (function() {
|
|||||||
options.target.addClass("red-ui-editor");
|
options.target.addClass("red-ui-editor");
|
||||||
|
|
||||||
buildEditor(options);
|
buildEditor(options);
|
||||||
|
|
||||||
RED.i18n.init(options, function() {
|
RED.i18n.init(options, function() {
|
||||||
RED.settings.init(options, loadEditor);
|
RED.settings.init(options, loadEditor);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var loader = {
|
||||||
|
init: function() {
|
||||||
|
var wrapper = $('<div id="red-ui-loading-progress"></div>').hide();
|
||||||
|
var container = $('<div>').appendTo(wrapper);
|
||||||
|
var label = $('<div>',{class:"red-ui-loading-bar-label"}).appendTo(container);
|
||||||
|
var bar = $('<div>',{class:"red-ui-loading-bar"}).appendTo(container);
|
||||||
|
var fill =$('<span>').appendTo(bar);
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
start: function(text, prcnt) {
|
||||||
|
if (text) {
|
||||||
|
loader.reportProgress(text,prcnt)
|
||||||
|
}
|
||||||
|
$("#red-ui-loading-progress").show();
|
||||||
|
},
|
||||||
|
reportProgress: function(text, prcnt) {
|
||||||
|
$(".red-ui-loading-bar-label").text(text);
|
||||||
|
$(".red-ui-loading-bar span").width(prcnt+"%")
|
||||||
|
},
|
||||||
|
end: function() {
|
||||||
|
$("#red-ui-loading-progress").hide();
|
||||||
|
loader.reportProgress("",0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init
|
init: init,
|
||||||
|
loader: loader
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -184,7 +184,7 @@ RED.clipboard = (function() {
|
|||||||
'</div>'+
|
'</div>'+
|
||||||
'<div id="red-ui-clipboard-dialog-export-tabs-content" class="red-ui-clipboard-dialog-tabs-content">'+
|
'<div id="red-ui-clipboard-dialog-export-tabs-content" class="red-ui-clipboard-dialog-tabs-content">'+
|
||||||
'<div id="red-ui-clipboard-dialog-export-tab-clipboard" class="red-ui-clipboard-dialog-tab-clipboard">'+
|
'<div id="red-ui-clipboard-dialog-export-tab-clipboard" class="red-ui-clipboard-dialog-tab-clipboard">'+
|
||||||
'<div class="form-row">'+
|
'<div class="form-row" style="height:calc(100% - 30px)">'+
|
||||||
'<textarea readonly id="red-ui-clipboard-dialog-export-text"></textarea>'+
|
'<textarea readonly id="red-ui-clipboard-dialog-export-text"></textarea>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'<div class="form-row" style="text-align: right;">'+
|
'<div class="form-row" style="text-align: right;">'+
|
||||||
@ -216,7 +216,7 @@ RED.clipboard = (function() {
|
|||||||
' <a class="red-ui-button" id="red-ui-clipboard-dialog-import-file-upload-btn"><i class="fa fa-upload"></i> <span data-i18n="clipboard.selectFile"></span></a>'+
|
' <a class="red-ui-button" id="red-ui-clipboard-dialog-import-file-upload-btn"><i class="fa fa-upload"></i> <span data-i18n="clipboard.selectFile"></span></a>'+
|
||||||
'<input type="file" id="red-ui-clipboard-dialog-import-file-upload" accept=".json" style="display:none">'+
|
'<input type="file" id="red-ui-clipboard-dialog-import-file-upload" accept=".json" style="display:none">'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'<div class="form-row">'+
|
'<div class="form-row" style="height:calc(100% - 47px)">'+
|
||||||
'<textarea id="red-ui-clipboard-dialog-import-text"></textarea>'+
|
'<textarea id="red-ui-clipboard-dialog-import-text"></textarea>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
@ -474,6 +474,12 @@ RED.clipboard = (function() {
|
|||||||
},100)
|
},100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dialogHeight = 400;
|
||||||
|
var winHeight = $(window).height();
|
||||||
|
if (winHeight < 600) {
|
||||||
|
dialogHeight = 400 - (600 - winHeight);
|
||||||
|
}
|
||||||
|
$(".red-ui-clipboard-dialog-box").height(dialogHeight);
|
||||||
|
|
||||||
dialog.dialog("option","title",RED._("clipboard.importNodes")).dialog("open");
|
dialog.dialog("option","title",RED._("clipboard.importNodes")).dialog("open");
|
||||||
popover = RED.popover.create({
|
popover = RED.popover.create({
|
||||||
@ -583,6 +589,7 @@ RED.clipboard = (function() {
|
|||||||
nodes = [];
|
nodes = [];
|
||||||
selection.forEach(function(n) {
|
selection.forEach(function(n) {
|
||||||
nodes.push(n);
|
nodes.push(n);
|
||||||
|
nodes = nodes.concat(RED.nodes.groups(n.id));
|
||||||
nodes = nodes.concat(RED.nodes.filterNodes({z:n.id}));
|
nodes = nodes.concat(RED.nodes.filterNodes({z:n.id}));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -592,7 +599,8 @@ RED.clipboard = (function() {
|
|||||||
nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'}));
|
nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'}));
|
||||||
} else if (type === 'red-ui-clipboard-dialog-export-rng-flow') {
|
} else if (type === 'red-ui-clipboard-dialog-export-rng-flow') {
|
||||||
var activeWorkspace = RED.workspaces.active();
|
var activeWorkspace = RED.workspaces.active();
|
||||||
nodes = RED.nodes.filterNodes({z:activeWorkspace});
|
nodes = RED.nodes.groups(activeWorkspace);
|
||||||
|
nodes = nodes.concat(RED.nodes.filterNodes({z:activeWorkspace}));
|
||||||
var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace);
|
var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace);
|
||||||
nodes.unshift(parentNode);
|
nodes.unshift(parentNode);
|
||||||
nodes = RED.nodes.createExportableNodeSet(nodes);
|
nodes = RED.nodes.createExportableNodeSet(nodes);
|
||||||
@ -637,6 +645,14 @@ RED.clipboard = (function() {
|
|||||||
$("#red-ui-clipboard-dialog-export-fmt-mini").trigger("click");
|
$("#red-ui-clipboard-dialog-export-fmt-mini").trigger("click");
|
||||||
}
|
}
|
||||||
tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+mode);
|
tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+mode);
|
||||||
|
|
||||||
|
var dialogHeight = 400;
|
||||||
|
var winHeight = $(window).height();
|
||||||
|
if (winHeight < 600) {
|
||||||
|
dialogHeight = 400 - (600 - winHeight);
|
||||||
|
}
|
||||||
|
$(".red-ui-clipboard-dialog-box").height(dialogHeight);
|
||||||
|
|
||||||
dialog.dialog("option","title",RED._("clipboard.exportNodes")).dialog( "open" );
|
dialog.dialog("option","title",RED._("clipboard.exportNodes")).dialog( "open" );
|
||||||
|
|
||||||
$("#red-ui-clipboard-dialog-export-text").trigger("focus");
|
$("#red-ui-clipboard-dialog-export-text").trigger("focus");
|
||||||
@ -738,6 +754,8 @@ RED.clipboard = (function() {
|
|||||||
RED.actions.add("core:show-library-export-dialog",function() { exportNodes('library') });
|
RED.actions.add("core:show-library-export-dialog",function() { exportNodes('library') });
|
||||||
RED.actions.add("core:show-library-import-dialog",function() { importNodes('library') });
|
RED.actions.add("core:show-library-import-dialog",function() { importNodes('library') });
|
||||||
|
|
||||||
|
RED.actions.add("core:show-examples-import-dialog",function() { importNodes('examples') });
|
||||||
|
|
||||||
RED.events.on("editor:open",function() { disabled = true; });
|
RED.events.on("editor:open",function() { disabled = true; });
|
||||||
RED.events.on("editor:close",function() { disabled = false; });
|
RED.events.on("editor:close",function() { disabled = false; });
|
||||||
RED.events.on("search:open",function() { disabled = true; });
|
RED.events.on("search:open",function() { disabled = true; });
|
||||||
|
209
packages/node_modules/@node-red/editor-client/src/js/ui/common/colorPicker.js
vendored
Normal file
209
packages/node_modules/@node-red/editor-client/src/js/ui/common/colorPicker.js
vendored
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
RED.colorPicker = (function() {
|
||||||
|
|
||||||
|
function create(options) {
|
||||||
|
var color = options.value;
|
||||||
|
var id = options.id;
|
||||||
|
var colorPalette = options.palette || [];
|
||||||
|
var width = options.cellWidth || 30;
|
||||||
|
var height = options.cellHeight || 30;
|
||||||
|
var margin = options.cellMargin || 2;
|
||||||
|
var perRow = options.cellPerRow || 6;
|
||||||
|
|
||||||
|
var container = $("<div>",{style:"display:inline-block"});
|
||||||
|
var colorHiddenInput = $("<input/>", { id: id, type: "hidden", value: color }).appendTo(container);
|
||||||
|
var opacityHiddenInput = $("<input/>", { id: id+"-opacity", type: "hidden", value: options.hasOwnProperty('opacity')?options.opacity:"1" }).appendTo(container);
|
||||||
|
|
||||||
|
var colorButton = $('<button type="button" class="red-ui-button red-ui-editor-node-appearance-button">').appendTo(container);
|
||||||
|
$('<i class="fa fa-caret-down"></i>').appendTo(colorButton);
|
||||||
|
|
||||||
|
var colorDispContainer = $('<div>',{class:"red-ui-search-result-node"}).appendTo(colorButton);
|
||||||
|
$('<div>',{class:"red-ui-color-picker-cell-none"}).appendTo(colorDispContainer);
|
||||||
|
var colorDisp = $('<div>',{class:"red-ui-color-picker-swatch"}).appendTo(colorDispContainer);
|
||||||
|
|
||||||
|
|
||||||
|
var refreshDisplay = function(color) {
|
||||||
|
if (color === "none") {
|
||||||
|
colorDisp.addClass('red-ui-color-picker-cell-none').css({
|
||||||
|
"background-color": "",
|
||||||
|
opacity: 1
|
||||||
|
});
|
||||||
|
colorDispContainer.css({
|
||||||
|
"border-color":""
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
var opacity = parseFloat(opacityHiddenInput.val())
|
||||||
|
colorDisp.removeClass('red-ui-color-picker-cell-none').css({
|
||||||
|
"background-color": color,
|
||||||
|
"opacity": opacity
|
||||||
|
});
|
||||||
|
var border = RED.utils.getDarkerColor(color);
|
||||||
|
if (border[0] === '#') {
|
||||||
|
border += Math.round(255*Math.floor(opacity*100)/100).toString(16);
|
||||||
|
} else {
|
||||||
|
border = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
colorDispContainer.css({
|
||||||
|
"border-color": border
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (options.hasOwnProperty('opacity')) {
|
||||||
|
$(".red-ui-color-picker-opacity-slider-overlay").css({
|
||||||
|
"background-image": "linear-gradient(90deg, transparent 0%, "+color+" 100%)"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
colorButton.on("click", function (e) {
|
||||||
|
var numColors = colorPalette.length;
|
||||||
|
|
||||||
|
var picker = $("<div/>", {
|
||||||
|
class: "red-ui-color-picker"
|
||||||
|
}).css({
|
||||||
|
width: ((width+margin+margin)*perRow)+"px",
|
||||||
|
height: Math.ceil(numColors/perRow)*(height+margin+margin)+"+px"
|
||||||
|
});
|
||||||
|
var count = 0;
|
||||||
|
var row = null;
|
||||||
|
row = $("<div/>").appendTo(picker);
|
||||||
|
|
||||||
|
var colorInput = $('<input>',{
|
||||||
|
type:"text",
|
||||||
|
value:colorHiddenInput.val()
|
||||||
|
}).appendTo(row);
|
||||||
|
var focusTarget = colorInput;
|
||||||
|
colorInput.on("change", function (e) {
|
||||||
|
var color = colorInput.val();
|
||||||
|
colorHiddenInput.val(color).trigger('change');
|
||||||
|
refreshDisplay(color);
|
||||||
|
});
|
||||||
|
// if (options.hasOwnProperty('opacity')) {
|
||||||
|
// var sliderContainer = $("<div>",{class:"red-ui-color-picker-opacity-slider"
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (options.none) {
|
||||||
|
row = $("<div/>").appendTo(picker);
|
||||||
|
var button = $("<button/>", {
|
||||||
|
class:"red-ui-color-picker-cell red-ui-color-picker-cell-none"
|
||||||
|
}).css({
|
||||||
|
width: width+"px",
|
||||||
|
height: height+"px",
|
||||||
|
margin: margin+"px"
|
||||||
|
}).appendTo(row);
|
||||||
|
button.on("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
colorInput.val("none");
|
||||||
|
colorInput.trigger("change");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colorPalette.forEach(function (col) {
|
||||||
|
if ((count % perRow) == 0) {
|
||||||
|
row = $("<div/>").appendTo(picker);
|
||||||
|
}
|
||||||
|
var button = $("<button/>", {
|
||||||
|
class:"red-ui-color-picker-cell"
|
||||||
|
}).css({
|
||||||
|
width: width+"px",
|
||||||
|
height: height+"px",
|
||||||
|
margin: margin+"px",
|
||||||
|
backgroundColor: col,
|
||||||
|
"border-color": RED.utils.getDarkerColor(col)
|
||||||
|
}).appendTo(row);
|
||||||
|
button.on("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// colorPanel.hide();
|
||||||
|
colorInput.val(col);
|
||||||
|
colorInput.trigger("change");
|
||||||
|
});
|
||||||
|
count++;
|
||||||
|
});
|
||||||
|
if (options.none || options.hasOwnProperty('opacity')) {
|
||||||
|
row = $("<div/>").appendTo(picker);
|
||||||
|
// if (options.none) {
|
||||||
|
// var button = $("<button/>", {
|
||||||
|
// class:"red-ui-color-picker-cell red-ui-color-picker-cell-none"
|
||||||
|
// }).css({
|
||||||
|
// width: width+"px",
|
||||||
|
// height: height+"px",
|
||||||
|
// margin: margin+"px"
|
||||||
|
// }).appendTo(row);
|
||||||
|
// button.on("click", function (e) {
|
||||||
|
// e.preventDefault();
|
||||||
|
// colorPanel.hide();
|
||||||
|
// selector.val("none");
|
||||||
|
// selector.trigger("change");
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
if (options.hasOwnProperty('opacity')) {
|
||||||
|
var sliderContainer = $("<div>",{class:"red-ui-color-picker-opacity-slider"}).appendTo(row);
|
||||||
|
sliderContainer.on("mousedown", function(evt) {
|
||||||
|
if (evt.target === sliderHandle[0]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var v = evt.offsetX/sliderContainer.width();
|
||||||
|
sliderHandle.css({
|
||||||
|
left: ( v*(sliderContainer.width() - sliderHandle.outerWidth()))+"px"
|
||||||
|
});
|
||||||
|
v = Math.floor(100*v)
|
||||||
|
opacityHiddenInput.val(v/100)
|
||||||
|
opacityLabel.text(v+"%");
|
||||||
|
refreshDisplay(colorHiddenInput.val());
|
||||||
|
})
|
||||||
|
$("<div>",{class:"red-ui-color-picker-opacity-slider-overlay"}).appendTo(sliderContainer);
|
||||||
|
var sliderHandle = $("<div>",{class:"red-ui-color-picker-opacity-slider-handle red-ui-button red-ui-button-small"}).appendTo(sliderContainer).draggable({
|
||||||
|
containment: "parent",
|
||||||
|
axis: "x",
|
||||||
|
drag: function( event, ui ) {
|
||||||
|
var v = Math.max(0,ui.position.left/($(this).parent().width()-$(this).outerWidth()));
|
||||||
|
// Odd bug that if it is loaded with a non-0 value, the first time
|
||||||
|
// it is dragged it ranges -1 to 99. But every other time, its 0 to 100.
|
||||||
|
// The Math.max above makes the -1 disappear. The follow hack ensures
|
||||||
|
// it always maxes out at a 100, at the cost of not allowing 99% exactly.
|
||||||
|
v = Math.floor(100*v)
|
||||||
|
if ( v === 99 ) {
|
||||||
|
v = 100;
|
||||||
|
}
|
||||||
|
// console.log("uip",ui.position.left);
|
||||||
|
opacityHiddenInput.val(v/100)
|
||||||
|
opacityLabel.text(v+"%");
|
||||||
|
refreshDisplay(colorHiddenInput.val());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var opacityLabel = $('<small></small>').appendTo(row);
|
||||||
|
setTimeout(function() {
|
||||||
|
sliderHandle.css({
|
||||||
|
left: (parseFloat(opacityHiddenInput.val())*(sliderContainer.width() - sliderHandle.outerWidth()))+"px"
|
||||||
|
})
|
||||||
|
opacityLabel.text(Math.floor(opacityHiddenInput.val()*100)+"%");
|
||||||
|
},50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var colorPanel = RED.popover.panel(picker);
|
||||||
|
setTimeout(function() {
|
||||||
|
refreshDisplay(colorHiddenInput.val())
|
||||||
|
},50);
|
||||||
|
colorPanel.show({
|
||||||
|
target: colorButton,
|
||||||
|
onclose: function() {
|
||||||
|
colorButton.focus();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (focusTarget) {
|
||||||
|
focusTarget.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setTimeout(function() {
|
||||||
|
refreshDisplay(colorHiddenInput.val())
|
||||||
|
},50);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
create: create
|
||||||
|
}
|
||||||
|
})();
|
@ -33,7 +33,7 @@
|
|||||||
* methods:
|
* methods:
|
||||||
* - addItem(itemData)
|
* - addItem(itemData)
|
||||||
* - insertItemAt : function(data,index) - add an item at the specified index
|
* - insertItemAt : function(data,index) - add an item at the specified index
|
||||||
* - removeItem(itemData)
|
* - removeItem(itemData, detach) - remove the item. Optionally detach to preserve any event handlers on the item's label
|
||||||
* - getItemAt(index)
|
* - getItemAt(index)
|
||||||
* - indexOf(itemData)
|
* - indexOf(itemData)
|
||||||
* - width(width)
|
* - width(width)
|
||||||
@ -183,7 +183,7 @@
|
|||||||
if (this.options.resizeItem) {
|
if (this.options.resizeItem) {
|
||||||
var that = this;
|
var that = this;
|
||||||
this.element.children().each(function(i) {
|
this.element.children().each(function(i) {
|
||||||
that.options.resizeItem($(this).find(".red-ui-editableList-item-content"),i);
|
that.options.resizeItem($(this).children(".red-ui-editableList-item-content"),i);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -223,7 +223,7 @@
|
|||||||
var items = this.element.children();
|
var items = this.element.children();
|
||||||
var that = this;
|
var that = this;
|
||||||
items.sort(function(A,B) {
|
items.sort(function(A,B) {
|
||||||
return that.activeSort($(A).find(".red-ui-editableList-item-content").data('data'),$(B).find(".red-ui-editableList-item-content").data('data'));
|
return that.activeSort($(A).children(".red-ui-editableList-item-content").data('data'),$(B).children(".red-ui-editableList-item-content").data('data'));
|
||||||
});
|
});
|
||||||
$.each(items,function(idx,li) {
|
$.each(items,function(idx,li) {
|
||||||
that.element.append(li);
|
that.element.append(li);
|
||||||
@ -259,28 +259,6 @@
|
|||||||
var that = this;
|
var that = this;
|
||||||
data = data || {};
|
data = data || {};
|
||||||
var li = $('<li>');
|
var li = $('<li>');
|
||||||
var added = false;
|
|
||||||
if (this.activeSort) {
|
|
||||||
var items = this.items();
|
|
||||||
var skip = false;
|
|
||||||
items.each(function(i,el) {
|
|
||||||
if (added) { return }
|
|
||||||
var itemData = el.data('data');
|
|
||||||
if (that.activeSort(data,itemData) < 0) {
|
|
||||||
li.insertBefore(el.closest("li"));
|
|
||||||
added = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!added) {
|
|
||||||
if (index <= 0) {
|
|
||||||
li.prependTo(this.element);
|
|
||||||
} else if (index > that.element.children().length-1) {
|
|
||||||
li.appendTo(this.element);
|
|
||||||
} else {
|
|
||||||
li.insertBefore(this.element.children().eq(index));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var row = $('<div/>').addClass("red-ui-editableList-item-content").appendTo(li);
|
var row = $('<div/>').addClass("red-ui-editableList-item-content").appendTo(li);
|
||||||
row.data('data',data);
|
row.data('data',data);
|
||||||
if (this.options.sortable === true) {
|
if (this.options.sortable === true) {
|
||||||
@ -303,9 +281,31 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
var added = false;
|
||||||
|
if (this.activeSort) {
|
||||||
|
var items = this.items();
|
||||||
|
var skip = false;
|
||||||
|
items.each(function(i,el) {
|
||||||
|
if (added) { return }
|
||||||
|
var itemData = el.data('data');
|
||||||
|
if (that.activeSort(data,itemData) < 0) {
|
||||||
|
li.insertBefore(el.closest("li"));
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!added) {
|
||||||
|
if (index <= 0) {
|
||||||
|
li.prependTo(this.element);
|
||||||
|
} else if (index > that.element.children().length-1) {
|
||||||
|
li.appendTo(this.element);
|
||||||
|
} else {
|
||||||
|
li.insertBefore(this.element.children().eq(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (this.options.addItem) {
|
if (this.options.addItem) {
|
||||||
var index = that.element.children().length-1;
|
var index = that.element.children().length-1;
|
||||||
setTimeout(function() {
|
// setTimeout(function() {
|
||||||
that.options.addItem(row,index,data);
|
that.options.addItem(row,index,data);
|
||||||
if (that.activeFilter) {
|
if (that.activeFilter) {
|
||||||
try {
|
try {
|
||||||
@ -321,7 +321,7 @@
|
|||||||
that.uiContainer.scrollTop(that.element.height());
|
that.uiContainer.scrollTop(that.element.height());
|
||||||
},0);
|
},0);
|
||||||
}
|
}
|
||||||
},0);
|
// },0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addItem: function(data) {
|
addItem: function(data) {
|
||||||
@ -332,17 +332,21 @@
|
|||||||
this.addItem(items[i]);
|
this.addItem(items[i]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeItem: function(data) {
|
removeItem: function(data,detach) {
|
||||||
var items = this.element.children().filter(function(f) {
|
var items = this.element.children().filter(function(f) {
|
||||||
return data === $(this).find(".red-ui-editableList-item-content").data('data');
|
return data === $(this).children(".red-ui-editableList-item-content").data('data');
|
||||||
});
|
});
|
||||||
items.remove();
|
if (detach) {
|
||||||
|
items.detach();
|
||||||
|
} else {
|
||||||
|
items.remove();
|
||||||
|
}
|
||||||
if (this.options.removeItem) {
|
if (this.options.removeItem) {
|
||||||
this.options.removeItem(data);
|
this.options.removeItem(data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
items: function() {
|
items: function() {
|
||||||
return this.element.children().map(function(i) { return $(this).find(".red-ui-editableList-item-content"); });
|
return this.element.children().map(function(i) { return $(this).children(".red-ui-editableList-item-content"); });
|
||||||
},
|
},
|
||||||
empty: function() {
|
empty: function() {
|
||||||
this.element.empty();
|
this.element.empty();
|
||||||
@ -365,14 +369,14 @@
|
|||||||
},
|
},
|
||||||
show: function(item) {
|
show: function(item) {
|
||||||
var items = this.element.children().filter(function(f) {
|
var items = this.element.children().filter(function(f) {
|
||||||
return item === $(this).find(".red-ui-editableList-item-content").data('data');
|
return item === $(this).children(".red-ui-editableList-item-content").data('data');
|
||||||
});
|
});
|
||||||
if (items.length > 0) {
|
if (items.length > 0) {
|
||||||
this.uiContainer.scrollTop(this.uiContainer.scrollTop()+items.position().top)
|
this.uiContainer.scrollTop(this.uiContainer.scrollTop()+items.position().top)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getItem: function(li) {
|
getItem: function(li) {
|
||||||
var el = li.find(".red-ui-editableList-item-content");
|
var el = li.children(".red-ui-editableList-item-content");
|
||||||
if (el.length) {
|
if (el.length) {
|
||||||
return el.data('data');
|
return el.data('data');
|
||||||
} else {
|
} else {
|
||||||
|
@ -158,7 +158,7 @@ RED.menu = (function() {
|
|||||||
activeMenu = null;
|
activeMenu = null;
|
||||||
topMenu.hide();
|
topMenu.hide();
|
||||||
});
|
});
|
||||||
$(".red-ui-menu").hide();
|
$(".red-ui-menu.red-ui-menu-dropdown").hide();
|
||||||
topMenu.show();
|
topMenu.show();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -29,6 +29,10 @@ RED.panels = (function() {
|
|||||||
if (!vertical) {
|
if (!vertical) {
|
||||||
container.addClass("red-ui-panels-horizontal");
|
container.addClass("red-ui-panels-horizontal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(children[0]).addClass("red-ui-panel");
|
||||||
|
$(children[1]).addClass("red-ui-panel");
|
||||||
|
|
||||||
var separator = $('<div class="red-ui-panels-separator"></div>').insertAfter(children[0]);
|
var separator = $('<div class="red-ui-panels-separator"></div>').insertAfter(children[0]);
|
||||||
var startPosition;
|
var startPosition;
|
||||||
var panelSizes = [];
|
var panelSizes = [];
|
||||||
@ -52,11 +56,11 @@ RED.panels = (function() {
|
|||||||
var newSizes = [panelSizes[0]+delta,panelSizes[1]-delta];
|
var newSizes = [panelSizes[0]+delta,panelSizes[1]-delta];
|
||||||
if (vertical) {
|
if (vertical) {
|
||||||
$(children[0]).height(newSizes[0]);
|
$(children[0]).height(newSizes[0]);
|
||||||
$(children[1]).height(newSizes[1]);
|
// $(children[1]).height(newSizes[1]);
|
||||||
ui.position.top -= delta;
|
ui.position.top -= delta;
|
||||||
} else {
|
} else {
|
||||||
$(children[0]).width(newSizes[0]);
|
$(children[0]).width(newSizes[0]);
|
||||||
$(children[1]).width(newSizes[1]);
|
// $(children[1]).width(newSizes[1]);
|
||||||
ui.position.left -= delta;
|
ui.position.left -= delta;
|
||||||
}
|
}
|
||||||
if (options.resize) {
|
if (options.resize) {
|
||||||
@ -71,6 +75,9 @@ RED.panels = (function() {
|
|||||||
|
|
||||||
var panel = {
|
var panel = {
|
||||||
ratio: function(ratio) {
|
ratio: function(ratio) {
|
||||||
|
if (ratio === undefined) {
|
||||||
|
return panelRatio;
|
||||||
|
}
|
||||||
panelRatio = ratio;
|
panelRatio = ratio;
|
||||||
modifiedSizes = true;
|
modifiedSizes = true;
|
||||||
if (ratio === 0 || ratio === 1) {
|
if (ratio === 0 || ratio === 1) {
|
||||||
@ -99,10 +106,10 @@ RED.panels = (function() {
|
|||||||
panelSizes = [topPanelSize,bottomPanelSize];
|
panelSizes = [topPanelSize,bottomPanelSize];
|
||||||
if (vertical) {
|
if (vertical) {
|
||||||
$(children[0]).outerHeight(panelSizes[0]);
|
$(children[0]).outerHeight(panelSizes[0]);
|
||||||
$(children[1]).outerHeight(panelSizes[1]);
|
// $(children[1]).outerHeight(panelSizes[1]);
|
||||||
} else {
|
} else {
|
||||||
$(children[0]).outerWidth(panelSizes[0]);
|
$(children[0]).outerWidth(panelSizes[0]);
|
||||||
$(children[1]).outerWidth(panelSizes[1]);
|
// $(children[1]).outerWidth(panelSizes[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options.resize) {
|
if (options.resize) {
|
||||||
|
@ -136,6 +136,23 @@ RED.popover = (function() {
|
|||||||
closePopup(true);
|
closePopup(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (trigger === 'hover' && options.interactive) {
|
||||||
|
div.on('mouseenter', function(e) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
active = true;
|
||||||
|
})
|
||||||
|
div.on('mouseleave', function(e) {
|
||||||
|
if (timer) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
}
|
||||||
|
if (active) {
|
||||||
|
timer = setTimeout(function() {
|
||||||
|
active = false;
|
||||||
|
closePopup();
|
||||||
|
},delay.hide);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
if (instant) {
|
if (instant) {
|
||||||
div.show();
|
div.show();
|
||||||
} else {
|
} else {
|
||||||
@ -163,8 +180,10 @@ RED.popover = (function() {
|
|||||||
if (trigger === 'hover') {
|
if (trigger === 'hover') {
|
||||||
target.on('mouseenter',function(e) {
|
target.on('mouseenter',function(e) {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
active = true;
|
if (!active) {
|
||||||
timer = setTimeout(openPopup,delay.show);
|
active = true;
|
||||||
|
timer = setTimeout(openPopup,delay.show);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
target.on('mouseleave disabled', function(e) {
|
target.on('mouseleave disabled', function(e) {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
@ -259,6 +278,85 @@ RED.popover = (function() {
|
|||||||
delay: { show: 750, hide: 50 }
|
delay: { show: 750, hide: 50 }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
menu: function(options) {
|
||||||
|
var list = $('<ul class="red-ui-menu"></ul>');
|
||||||
|
if (options.style === 'compact') {
|
||||||
|
list.addClass("red-ui-menu-compact");
|
||||||
|
}
|
||||||
|
var menuOptions = options.options || [];
|
||||||
|
var first;
|
||||||
|
menuOptions.forEach(function(opt) {
|
||||||
|
var item = $('<li>').appendTo(list);
|
||||||
|
var link = $('<a href="#"></a>').text(opt.label).appendTo(item);
|
||||||
|
link.on("click", function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
if (opt.onselect) {
|
||||||
|
opt.onselect();
|
||||||
|
}
|
||||||
|
menu.hide();
|
||||||
|
})
|
||||||
|
if (!first) { first = link}
|
||||||
|
})
|
||||||
|
var container = RED.popover.panel(list);
|
||||||
|
var menu = {
|
||||||
|
show: function(opts) {
|
||||||
|
$(document).on("keydown.red-ui-menu", function(evt) {
|
||||||
|
var currentItem = list.find(":focus").parent();
|
||||||
|
if (evt.keyCode === 40) {
|
||||||
|
evt.preventDefault();
|
||||||
|
// DOWN
|
||||||
|
if (currentItem.length > 0) {
|
||||||
|
if (currentItem.index() === menuOptions.length-1) {
|
||||||
|
console.log("WARP TO TOP")
|
||||||
|
// Wrap to top of list
|
||||||
|
list.children().first().children().first().focus();
|
||||||
|
} else {
|
||||||
|
console.log("GO DOWN ONE")
|
||||||
|
currentItem.next().children().first().focus();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
list.children().first().children().first().focus();
|
||||||
|
}
|
||||||
|
} else if (evt.keyCode === 38) {
|
||||||
|
evt.preventDefault();
|
||||||
|
// UP
|
||||||
|
if (currentItem.length > 0) {
|
||||||
|
if (currentItem.index() === 0) {
|
||||||
|
console.log("WARP TO BOTTOM")
|
||||||
|
// Wrap to bottom of list
|
||||||
|
list.children().last().children().first().focus();
|
||||||
|
} else {
|
||||||
|
console.log("GO UP ONE")
|
||||||
|
currentItem.prev().children().first().focus();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
list.children().last().children().first().focus();
|
||||||
|
}
|
||||||
|
} else if (evt.keyCode === 27) {
|
||||||
|
// ESCAPE
|
||||||
|
evt.preventDefault();
|
||||||
|
menu.hide(true);
|
||||||
|
}
|
||||||
|
evt.stopPropagation();
|
||||||
|
})
|
||||||
|
opts.onclose = function() {
|
||||||
|
$(document).off("keydown.red-ui-menu");
|
||||||
|
if (options.onclose) {
|
||||||
|
options.onclose(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container.show(opts);
|
||||||
|
},
|
||||||
|
hide: function(cancelled) {
|
||||||
|
$(document).off("keydown.red-ui-menu");
|
||||||
|
container.hide(options.disposeOnClose);
|
||||||
|
if (options.onclose) {
|
||||||
|
options.onclose(cancelled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return menu;
|
||||||
|
},
|
||||||
panel: function(content) {
|
panel: function(content) {
|
||||||
var panel = $('<div class="red-ui-editor-dialog red-ui-popover-panel"></div>');
|
var panel = $('<div class="red-ui-editor-dialog red-ui-popover-panel"></div>');
|
||||||
panel.css({ display: "none" });
|
panel.css({ display: "none" });
|
||||||
@ -266,18 +364,22 @@ RED.popover = (function() {
|
|||||||
content.appendTo(panel);
|
content.appendTo(panel);
|
||||||
var closeCallback;
|
var closeCallback;
|
||||||
|
|
||||||
function hide() {
|
function hide(dispose) {
|
||||||
$(document).off("mousedown.red-ui-popover-panel-close");
|
$(document).off("mousedown.red-ui-popover-panel-close");
|
||||||
|
$(document).off("keydown.red-ui-popover-panel-close");
|
||||||
panel.hide();
|
panel.hide();
|
||||||
panel.css({
|
panel.css({
|
||||||
height: "auto"
|
height: "auto"
|
||||||
});
|
});
|
||||||
panel.remove();
|
if (dispose !== false) {
|
||||||
|
panel.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function show(options) {
|
function show(options) {
|
||||||
var closeCallback = options.onclose;
|
var closeCallback = options.onclose;
|
||||||
var target = options.target;
|
var target = options.target;
|
||||||
var align = options.align || "left";
|
var align = options.align || "right";
|
||||||
|
var offset = options.offset || [0,0];
|
||||||
|
|
||||||
var pos = target.offset();
|
var pos = target.offset();
|
||||||
var targetWidth = target.width();
|
var targetWidth = target.width();
|
||||||
@ -285,7 +387,7 @@ RED.popover = (function() {
|
|||||||
var panelHeight = panel.height();
|
var panelHeight = panel.height();
|
||||||
var panelWidth = panel.width();
|
var panelWidth = panel.width();
|
||||||
|
|
||||||
var top = (targetHeight+pos.top);
|
var top = (targetHeight+pos.top) + offset[1];
|
||||||
if (top+panelHeight > $(window).height()) {
|
if (top+panelHeight > $(window).height()) {
|
||||||
top -= (top+panelHeight)-$(window).height() + 5;
|
top -= (top+panelHeight)-$(window).height() + 5;
|
||||||
}
|
}
|
||||||
@ -293,25 +395,35 @@ RED.popover = (function() {
|
|||||||
panelHeight.height(panelHeight+top)
|
panelHeight.height(panelHeight+top)
|
||||||
top = 0;
|
top = 0;
|
||||||
}
|
}
|
||||||
if (align === "left") {
|
if (align === "right") {
|
||||||
panel.css({
|
panel.css({
|
||||||
top: top+"px",
|
top: top+"px",
|
||||||
left: (pos.left)+"px",
|
left: (pos.left+offset[0])+"px",
|
||||||
});
|
});
|
||||||
} else if(align === "right") {
|
} else if (align === "left") {
|
||||||
panel.css({
|
panel.css({
|
||||||
top: top+"px",
|
top: top+"px",
|
||||||
left: (pos.left-panelWidth)+"px",
|
left: (pos.left-panelWidth+offset[0])+"px",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
panel.slideDown(100);
|
panel.slideDown(100);
|
||||||
|
|
||||||
|
$(document).on("keydown.red-ui-popover-panel-close", function(event) {
|
||||||
|
if (event.keyCode === 27) {
|
||||||
|
// ESCAPE
|
||||||
|
if (closeCallback) {
|
||||||
|
closeCallback();
|
||||||
|
}
|
||||||
|
hide(options.dispose);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$(document).on("mousedown.red-ui-popover-panel-close", function(event) {
|
$(document).on("mousedown.red-ui-popover-panel-close", function(event) {
|
||||||
if(!$(event.target).closest(panel).length && !$(event.target).closest(".red-ui-editor-dialog").length) {
|
if(!$(event.target).closest(panel).length && !$(event.target).closest(".red-ui-editor-dialog").length) {
|
||||||
if (closeCallback) {
|
if (closeCallback) {
|
||||||
closeCallback();
|
closeCallback();
|
||||||
}
|
}
|
||||||
hide();
|
hide(options.dispose);
|
||||||
}
|
}
|
||||||
// if ($(event.target).closest(target).length) {
|
// if ($(event.target).closest(target).length) {
|
||||||
// event.preventDefault();
|
// event.preventDefault();
|
||||||
|
@ -38,12 +38,17 @@
|
|||||||
this.element.addClass("red-ui-searchBox-input");
|
this.element.addClass("red-ui-searchBox-input");
|
||||||
this.uiContainer = this.element.wrap("<div>").parent();
|
this.uiContainer = this.element.wrap("<div>").parent();
|
||||||
this.uiContainer.addClass("red-ui-searchBox-container");
|
this.uiContainer.addClass("red-ui-searchBox-container");
|
||||||
|
|
||||||
|
if (this.options.style === "compact") {
|
||||||
|
this.uiContainer.addClass("red-ui-searchBox-compact");
|
||||||
|
}
|
||||||
|
|
||||||
if (this.element.parents("form").length === 0) {
|
if (this.element.parents("form").length === 0) {
|
||||||
var form = this.element.wrap("<form>").parent();
|
var form = this.element.wrap("<form>").parent();
|
||||||
form.addClass("red-ui-searchBox-form");
|
form.addClass("red-ui-searchBox-form");
|
||||||
}
|
}
|
||||||
$('<i class="fa fa-search"></i>').prependTo(this.uiContainer);
|
$('<i class="fa fa-search"></i>').prependTo(this.uiContainer);
|
||||||
this.clearButton = $('<a href="#"><i class="fa fa-times"></i></a>').appendTo(this.uiContainer);
|
this.clearButton = $('<a class="red-ui-searchBox-clear" href="#"><i class="fa fa-times"></i></a>').appendTo(this.uiContainer);
|
||||||
this.clearButton.on("click",function(e) {
|
this.clearButton.on("click",function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
that.element.val("");
|
that.element.val("");
|
||||||
@ -51,6 +56,62 @@
|
|||||||
that.element.trigger("focus");
|
that.element.trigger("focus");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.options.options) {
|
||||||
|
this.uiContainer.addClass("red-ui-searchBox-has-options");
|
||||||
|
this.optsButton = $('<a class="red-ui-searchBox-opts" href="#"><i class="fa fa-caret-down"></i></a>').appendTo(this.uiContainer);
|
||||||
|
var menuShown = false;
|
||||||
|
this.optsMenu = RED.popover.menu({
|
||||||
|
style: this.options.style,
|
||||||
|
options: this.options.options.map(function(opt) {
|
||||||
|
return {
|
||||||
|
label: opt.label,
|
||||||
|
onselect: function() {
|
||||||
|
that.element.val(opt.value+" ");
|
||||||
|
that._change(opt.value,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
onclose: function(cancelled) {
|
||||||
|
menuShown = false;
|
||||||
|
that.element.trigger("focus");
|
||||||
|
},
|
||||||
|
disposeOnClose: false
|
||||||
|
});
|
||||||
|
|
||||||
|
var showMenu = function() {
|
||||||
|
menuShown = true;
|
||||||
|
that.optsMenu.show({
|
||||||
|
target: that.optsButton,
|
||||||
|
align: "left",
|
||||||
|
offset: [that.optsButton.width()-2,-1],
|
||||||
|
dispose: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.optsButton.on("click",function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!menuShown) {
|
||||||
|
showMenu();
|
||||||
|
} else {
|
||||||
|
// TODO: This doesn't quite work because the panel's own
|
||||||
|
// mousedown handler triggers a close before this click
|
||||||
|
// handler fires.
|
||||||
|
that.optsMenu.hide(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.optsButton.on("keydown",function(e) {
|
||||||
|
if (!menuShown && e.keyCode === 40) {
|
||||||
|
//DOWN
|
||||||
|
showMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.element.on("keydown",function(e) {
|
||||||
|
if (!menuShown && e.keyCode === 40) {
|
||||||
|
//DOWN
|
||||||
|
showMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.resultCount = $('<span>',{class:"red-ui-searchBox-resultCount hide"}).appendTo(this.uiContainer);
|
this.resultCount = $('<span>',{class:"red-ui-searchBox-resultCount hide"}).appendTo(this.uiContainer);
|
||||||
|
|
||||||
this.element.val("");
|
this.element.val("");
|
||||||
|
@ -153,7 +153,7 @@ RED.tabs = (function() {
|
|||||||
if (collapsibleMenu.is(":visible")) {
|
if (collapsibleMenu.is(":visible")) {
|
||||||
$(document).off("click.red-ui-tabmenu");
|
$(document).off("click.red-ui-tabmenu");
|
||||||
} else {
|
} else {
|
||||||
$(".red-ui-menu").hide();
|
$(".red-ui-menu.red-ui-menu-dropdown").hide();
|
||||||
$(document).on("click.red-ui-tabmenu", function(evt) {
|
$(document).on("click.red-ui-tabmenu", function(evt) {
|
||||||
$(document).off("click.red-ui-tabmenu");
|
$(document).off("click.red-ui-tabmenu");
|
||||||
collapsibleMenu.hide();
|
collapsibleMenu.hide();
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
*
|
*
|
||||||
* methods:
|
* methods:
|
||||||
* - data(items) - clears existing items and replaces with new data
|
* - data(items) - clears existing items and replaces with new data
|
||||||
*
|
* - clearSelection - clears the selected items
|
||||||
|
* - filter(filterFunc) - filters the tree using the provided function
|
||||||
* events:
|
* events:
|
||||||
* - treelistselect : function(event, item) {}
|
* - treelistselect : function(event, item) {}
|
||||||
* - treelistconfirm : function(event,item) {}
|
* - treelistconfirm : function(event,item) {}
|
||||||
@ -39,7 +40,8 @@
|
|||||||
* label: 'Local', // label for the item
|
* label: 'Local', // label for the item
|
||||||
* sublabel: 'Local', // a sub-label for the item
|
* sublabel: 'Local', // a sub-label for the item
|
||||||
* icon: 'fa fa-rocket', // (optional) icon for the item
|
* icon: 'fa fa-rocket', // (optional) icon for the item
|
||||||
* selected: true/false, // (optional) if present, display checkbox accordingly
|
* checkbox: true/false, // (optional) if present, display checkbox accordingly
|
||||||
|
* selected: true/false, // (optional) whether the item is selected or not
|
||||||
* children: [] | function(done,item) // (optional) an array of child items, or a function
|
* children: [] | function(done,item) // (optional) an array of child items, or a function
|
||||||
* // that will call the `done` callback with an array
|
* // that will call the `done` callback with an array
|
||||||
* // of child items
|
* // of child items
|
||||||
@ -59,11 +61,11 @@
|
|||||||
* properties and functions:
|
* properties and functions:
|
||||||
*
|
*
|
||||||
* item.parent - set to the parent item
|
* item.parent - set to the parent item
|
||||||
|
* item.depth - the depth in the tree (0 == root)
|
||||||
* item.treeList.container
|
* item.treeList.container
|
||||||
* item.treeList.label - the label element for the item
|
* item.treeList.label - the label element for the item
|
||||||
* item.treeList.depth - the depth in the tree (0 == root)
|
|
||||||
* item.treeList.parentList - the editableList instance this item is in
|
* item.treeList.parentList - the editableList instance this item is in
|
||||||
* item.treeList.remove() - removes the item from the tree
|
* item.treeList.remove(detach) - removes the item from the tree. Optionally detach to preserve any event handlers on the item's label
|
||||||
* item.treeList.makeLeaf(detachChildElements) - turns an element with children into a leaf node,
|
* item.treeList.makeLeaf(detachChildElements) - turns an element with children into a leaf node,
|
||||||
* removing the UI decoration etc.
|
* removing the UI decoration etc.
|
||||||
* detachChildElements - any children with custom
|
* detachChildElements - any children with custom
|
||||||
@ -78,8 +80,8 @@
|
|||||||
* Optionally selects the item after adding.
|
* Optionally selects the item after adding.
|
||||||
* item.treeList.expand(done) - expands the parent item to show children. Optional 'done' callback.
|
* item.treeList.expand(done) - expands the parent item to show children. Optional 'done' callback.
|
||||||
* item.treeList.collapse() - collapse the parent item to hide children.
|
* item.treeList.collapse() - collapse the parent item to hide children.
|
||||||
*
|
* item.treeList.sortChildren(sortFunction) - does a one-time sort of the children using sortFunction
|
||||||
*
|
* item.treeList.replaceElement(element) - replace the custom element for the item
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -100,6 +102,8 @@
|
|||||||
var target;
|
var target;
|
||||||
switch(evt.keyCode) {
|
switch(evt.keyCode) {
|
||||||
case 13: // ENTER
|
case 13: // ENTER
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
if (selected.children) {
|
if (selected.children) {
|
||||||
if (selected.treeList.container.hasClass("expanded")) {
|
if (selected.treeList.container.hasClass("expanded")) {
|
||||||
selected.treeList.collapse()
|
selected.treeList.collapse()
|
||||||
@ -112,6 +116,8 @@
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case 37: // LEFT
|
case 37: // LEFT
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
if (selected.children&& selected.treeList.container.hasClass("expanded")) {
|
if (selected.children&& selected.treeList.container.hasClass("expanded")) {
|
||||||
selected.treeList.collapse()
|
selected.treeList.collapse()
|
||||||
} else if (selected.parent) {
|
} else if (selected.parent) {
|
||||||
@ -119,6 +125,8 @@
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 38: // UP
|
case 38: // UP
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
target = that._getPreviousSibling(selected);
|
target = that._getPreviousSibling(selected);
|
||||||
if (target) {
|
if (target) {
|
||||||
target = that._getLastDescendant(target);
|
target = that._getLastDescendant(target);
|
||||||
@ -128,6 +136,8 @@
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 39: // RIGHT
|
case 39: // RIGHT
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
if (selected.children) {
|
if (selected.children) {
|
||||||
if (!selected.treeList.container.hasClass("expanded")) {
|
if (!selected.treeList.container.hasClass("expanded")) {
|
||||||
selected.treeList.expand()
|
selected.treeList.expand()
|
||||||
@ -135,6 +145,8 @@
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 40: //DOWN
|
case 40: //DOWN
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
if (selected.children && Array.isArray(selected.children) && selected.children.length > 0 && selected.treeList.container.hasClass("expanded")) {
|
if (selected.children && Array.isArray(selected.children) && selected.children.length > 0 && selected.treeList.container.hasClass("expanded")) {
|
||||||
target = selected.children[0];
|
target = selected.children[0];
|
||||||
} else {
|
} else {
|
||||||
@ -151,7 +163,8 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this._data = [];
|
this._data = [];
|
||||||
|
this._items = {};
|
||||||
|
this._selected = new Set();
|
||||||
this._topList = $('<ol class="red-ui-treeList-list">').css({
|
this._topList = $('<ol class="red-ui-treeList-list">').css({
|
||||||
position:'absolute',
|
position:'absolute',
|
||||||
top: 0,
|
top: 0,
|
||||||
@ -215,7 +228,7 @@
|
|||||||
return candidates[index+1];
|
return candidates[index+1];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_addChildren: function(container,parent,children,depth) {
|
_addChildren: function(container,parent,children,depth,onCompleteChildren) {
|
||||||
var that = this;
|
var that = this;
|
||||||
var subtree = $('<ol class="red-ui-treeList-list">').appendTo(container).editableList({
|
var subtree = $('<ol class="red-ui-treeList-list">').appendTo(container).editableList({
|
||||||
connectWith: ".red-ui-treeList-sortable",
|
connectWith: ".red-ui-treeList-sortable",
|
||||||
@ -244,15 +257,38 @@
|
|||||||
that._trigger("changeparent",null,evt);
|
that._trigger("changeparent",null,evt);
|
||||||
});
|
});
|
||||||
that._trigger("sort",null,parent);
|
that._trigger("sort",null,parent);
|
||||||
}
|
},
|
||||||
|
filter: parent.treeList.childFilter
|
||||||
});
|
});
|
||||||
if (!!that.options.sortable) {
|
if (!!that.options.sortable) {
|
||||||
subtree.addClass('red-ui-treeList-sortable');
|
subtree.addClass('red-ui-treeList-sortable');
|
||||||
}
|
}
|
||||||
for (var i=0;i<children.length;i++) {
|
var sliceSize = 30;
|
||||||
children[i].parent = parent;
|
var index = 0;
|
||||||
subtree.editableList('addItem',children[i])
|
var addSlice = function() {
|
||||||
|
var start = index;
|
||||||
|
for (var i=0;i<sliceSize;i++) {
|
||||||
|
index = start+i;
|
||||||
|
if (index === children.length) {
|
||||||
|
setTimeout(function() {
|
||||||
|
if (onCompleteChildren) {
|
||||||
|
onCompleteChildren();
|
||||||
|
}
|
||||||
|
},10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
children[index].parent = parent;
|
||||||
|
subtree.editableList('addItem',children[index])
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
if (index < children.length) {
|
||||||
|
setTimeout(function() {
|
||||||
|
addSlice();
|
||||||
|
},10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
addSlice();
|
||||||
|
subtree.hide()
|
||||||
return subtree;
|
return subtree;
|
||||||
},
|
},
|
||||||
_fixDepths: function(parent,child) {
|
_fixDepths: function(parent,child) {
|
||||||
@ -289,23 +325,184 @@
|
|||||||
}
|
}
|
||||||
return reparentedEvent;
|
return reparentedEvent;
|
||||||
},
|
},
|
||||||
_addSubtree: function(parentList, container, item, depth) {
|
_initItem: function(item,depth) {
|
||||||
|
if (item.treeList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var that = this;
|
var that = this;
|
||||||
|
this._items[item.id] = item;
|
||||||
item.treeList = {};
|
item.treeList = {};
|
||||||
item.treeList.depth = depth;
|
item.depth = depth;
|
||||||
item.treeList.container = container;
|
item.treeList.remove = function(detach) {
|
||||||
|
if (item.treeList.parentList) {
|
||||||
item.treeList.parentList = parentList;
|
item.treeList.parentList.editableList('removeItem',item,detach);
|
||||||
item.treeList.remove = function() {
|
}
|
||||||
parentList.editableList('removeItem',item);
|
|
||||||
if (item.parent) {
|
if (item.parent) {
|
||||||
var index = item.parent.children.indexOf(item);
|
var index = item.parent.children.indexOf(item);
|
||||||
item.parent.children.splice(index,1)
|
item.parent.children.splice(index,1)
|
||||||
that._trigger("sort",null,item.parent);
|
that._trigger("sort",null,item.parent);
|
||||||
}
|
}
|
||||||
|
that._selected.delete(item);
|
||||||
|
delete item.treeList;
|
||||||
|
delete that._items[item.id];
|
||||||
|
}
|
||||||
|
item.treeList.insertChildAt = function(newItem,position,select) {
|
||||||
|
newItem.parent = item;
|
||||||
|
item.children.splice(position,0,newItem);
|
||||||
|
var processChildren = function(parent,i) {
|
||||||
|
that._initItem(i,parent.depth+1)
|
||||||
|
i.parent = parent;
|
||||||
|
if (i.children && typeof i.children !== 'function') {
|
||||||
|
i.children.forEach(function(item) {
|
||||||
|
processChildren(i, item, parent.depth+2)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processChildren(item,newItem);
|
||||||
|
|
||||||
|
if (!item.deferBuild && item.treeList.childList) {
|
||||||
|
item.treeList.childList.editableList('insertItemAt',newItem,position)
|
||||||
|
if (select) {
|
||||||
|
setTimeout(function() {
|
||||||
|
that.select(newItem)
|
||||||
|
},100);
|
||||||
|
}
|
||||||
|
that._trigger("sort",null,item);
|
||||||
|
|
||||||
|
if (that.activeFilter) {
|
||||||
|
that.filter(that.activeFilter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item.treeList.addChild = function(newItem,select) {
|
||||||
|
item.treeList.insertChildAt(newItem,item.children.length,select);
|
||||||
|
}
|
||||||
|
item.treeList.expand = function(done) {
|
||||||
|
if (!item.children) {
|
||||||
|
if (done) { done(false) }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!item.treeList.container) {
|
||||||
|
item.expanded = true;
|
||||||
|
if (done) { done(false) }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var container = item.treeList.container;
|
||||||
|
if (container.hasClass("expanded")) {
|
||||||
|
if (done) { done(false) }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!container.hasClass("built") && (item.deferBuild || typeof item.children === 'function')) {
|
||||||
|
container.addClass('built');
|
||||||
|
var childrenAdded = false;
|
||||||
|
var spinner;
|
||||||
|
var startTime = 0;
|
||||||
|
var started = Date.now();
|
||||||
|
var completeBuild = function(children) {
|
||||||
|
childrenAdded = true;
|
||||||
|
item.treeList.childList = that._addChildren(container,item,children,depth, function() {
|
||||||
|
if (done) { done(true) }
|
||||||
|
that._trigger("childrenloaded",null,item)
|
||||||
|
});
|
||||||
|
var delta = Date.now() - startTime;
|
||||||
|
if (delta < 400) {
|
||||||
|
setTimeout(function() {
|
||||||
|
item.treeList.childList.slideDown('fast');
|
||||||
|
if (spinner) {
|
||||||
|
spinner.remove();
|
||||||
|
}
|
||||||
|
},400-delta);
|
||||||
|
} else {
|
||||||
|
item.treeList.childList.slideDown('fast');
|
||||||
|
if (spinner) {
|
||||||
|
spinner.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item.expanded = true;
|
||||||
|
}
|
||||||
|
if (typeof item.children === 'function') {
|
||||||
|
item.children(completeBuild,item);
|
||||||
|
} else {
|
||||||
|
delete item.deferBuild;
|
||||||
|
completeBuild(item.children);
|
||||||
|
}
|
||||||
|
if (!childrenAdded) {
|
||||||
|
startTime = Date.now();
|
||||||
|
spinner = $('<div class="red-ui-treeList-spinner">').css({
|
||||||
|
"background-position": (35+depth*20)+'px 50%'
|
||||||
|
}).appendTo(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (that._loadingData || item.children.length > 20) {
|
||||||
|
item.treeList.childList.show();
|
||||||
|
} else {
|
||||||
|
item.treeList.childList.slideDown('fast');
|
||||||
|
}
|
||||||
|
item.expanded = true;
|
||||||
|
if (done) { done(!that._loadingData) }
|
||||||
|
}
|
||||||
|
container.addClass("expanded");
|
||||||
|
}
|
||||||
|
item.treeList.collapse = function() {
|
||||||
|
if (!item.children) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
item.expanded = false;
|
||||||
|
if (item.treeList.container) {
|
||||||
|
if (item.children.length < 20) {
|
||||||
|
item.treeList.childList.slideUp('fast');
|
||||||
|
} else {
|
||||||
|
item.treeList.childList.hide();
|
||||||
|
}
|
||||||
|
item.treeList.container.removeClass("expanded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item.treeList.sortChildren = function(sortFunc) {
|
||||||
|
if (!item.children) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
item.children.sort(sortFunc);
|
||||||
|
if (item.treeList.childList) {
|
||||||
|
// Do a one-off sort of the list, which means calling sort twice:
|
||||||
|
// 1. first with the desired sort function
|
||||||
|
item.treeList.childList.editableList('sort',sortFunc);
|
||||||
|
// 2. and then with null to remove it
|
||||||
|
item.treeList.childList.editableList('sort',null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item.treeList.replaceElement = function (element) {
|
||||||
|
if (item.element) {
|
||||||
|
if (item.treeList.container) {
|
||||||
|
$(item.element).remove();
|
||||||
|
$(element).appendTo(item.treeList.label);
|
||||||
|
var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(item.depth*20);
|
||||||
|
$(element).css({
|
||||||
|
width: "calc(100% - "+(labelPaddingWidth+20+(item.icon?20:0))+"px)"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
item.element = element;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var label = $("<div>",{class:"red-ui-treeList-label"}).appendTo(container);
|
if (item.children && typeof item.children !== "function") {
|
||||||
|
item.children.forEach(function(i) {
|
||||||
|
that._initItem(i,depth+1);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_addSubtree: function(parentList, container, item, depth) {
|
||||||
|
var that = this;
|
||||||
|
this._initItem(item,depth);
|
||||||
|
// item.treeList = {};
|
||||||
|
// item.treeList.depth = depth;
|
||||||
|
item.treeList.container = container;
|
||||||
|
|
||||||
|
item.treeList.parentList = parentList;
|
||||||
|
|
||||||
|
var label = $("<div>",{class:"red-ui-treeList-label"});
|
||||||
|
label.appendTo(container);
|
||||||
item.treeList.label = label;
|
item.treeList.label = label;
|
||||||
if (item.class) {
|
if (item.class) {
|
||||||
label.addClass(item.class);
|
label.addClass(item.class);
|
||||||
@ -357,6 +554,7 @@
|
|||||||
treeListIcon.off("click.red-ui-treeList-expand");
|
treeListIcon.off("click.red-ui-treeList-expand");
|
||||||
delete item.children;
|
delete item.children;
|
||||||
container.removeClass("expanded");
|
container.removeClass("expanded");
|
||||||
|
delete item.expanded;
|
||||||
}
|
}
|
||||||
item.treeList.makeParent = function(children) {
|
item.treeList.makeParent = function(children) {
|
||||||
if (treeListIcon.children().length) {
|
if (treeListIcon.children().length) {
|
||||||
@ -385,104 +583,28 @@
|
|||||||
})
|
})
|
||||||
if (!item.children) {
|
if (!item.children) {
|
||||||
item.children = children||[];
|
item.children = children||[];
|
||||||
item.treeList.childList = that._addChildren(container,item,item.children,depth).hide();
|
item.treeList.childList = that._addChildren(container,item,item.children,depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item.treeList.insertChildAt = function(newItem,position,select) {
|
|
||||||
newItem.parent = item;
|
|
||||||
item.children.splice(position,0,newItem);
|
|
||||||
|
|
||||||
if (!item.deferBuild) {
|
|
||||||
item.treeList.childList.editableList('insertItemAt',newItem,position)
|
|
||||||
if (select) {
|
|
||||||
setTimeout(function() {
|
|
||||||
that.select(newItem)
|
|
||||||
},100);
|
|
||||||
}
|
|
||||||
that._trigger("sort",null,item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item.treeList.addChild = function(newItem,select) {
|
|
||||||
item.treeList.insertChildAt(newItem,item.children.length,select);
|
|
||||||
}
|
|
||||||
item.treeList.expand = function(done) {
|
|
||||||
if (!item.children) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (container.hasClass("expanded")) {
|
|
||||||
if (done) { done() }
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!container.hasClass("built") && (item.deferBuild || typeof item.children === 'function')) {
|
|
||||||
container.addClass('built');
|
|
||||||
var childrenAdded = false;
|
|
||||||
var spinner;
|
|
||||||
var startTime = 0;
|
|
||||||
var completeBuild = function(children) {
|
|
||||||
childrenAdded = true;
|
|
||||||
item.treeList.childList = that._addChildren(container,item,children,depth).hide();
|
|
||||||
var delta = Date.now() - startTime;
|
|
||||||
if (delta < 400) {
|
|
||||||
setTimeout(function() {
|
|
||||||
item.treeList.childList.slideDown('fast');
|
|
||||||
if (spinner) {
|
|
||||||
spinner.remove();
|
|
||||||
}
|
|
||||||
},400-delta);
|
|
||||||
} else {
|
|
||||||
item.treeList.childList.slideDown('fast');
|
|
||||||
if (spinner) {
|
|
||||||
spinner.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (done) { done() }
|
|
||||||
that._trigger("childrenloaded",null,item)
|
|
||||||
}
|
|
||||||
if (typeof item.children === 'function') {
|
|
||||||
item.children(completeBuild,item);
|
|
||||||
} else {
|
|
||||||
delete item.deferBuild;
|
|
||||||
completeBuild(item.children);
|
|
||||||
}
|
|
||||||
if (!childrenAdded) {
|
|
||||||
startTime = Date.now();
|
|
||||||
spinner = $('<div class="red-ui-treeList-spinner">').css({
|
|
||||||
"background-position": (35+depth*20)+'px 50%'
|
|
||||||
}).appendTo(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (that._loadingData) {
|
|
||||||
item.treeList.childList.show();
|
|
||||||
} else {
|
|
||||||
item.treeList.childList.slideDown('fast');
|
|
||||||
}
|
|
||||||
if (done) { done() }
|
|
||||||
}
|
|
||||||
container.addClass("expanded");
|
|
||||||
}
|
|
||||||
item.treeList.collapse = function() {
|
|
||||||
if (!item.children) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
item.treeList.childList.slideUp('fast');
|
|
||||||
container.removeClass("expanded");
|
|
||||||
}
|
|
||||||
|
|
||||||
var treeListIcon = $('<span class="red-ui-treeList-icon"></span>').appendTo(label);
|
var treeListIcon = $('<span class="red-ui-treeList-icon"></span>').appendTo(label);
|
||||||
if (item.children) {
|
if (item.children) {
|
||||||
item.treeList.makeParent();
|
item.treeList.makeParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.hasOwnProperty('selected')) {
|
if (item.checkbox) {
|
||||||
var selectWrapper = $('<span class="red-ui-treeList-icon"></span>').appendTo(label);
|
var selectWrapper = $('<span class="red-ui-treeList-icon"></span>');
|
||||||
var cb = $('<input class="red-ui-treeList-checkbox" type="checkbox">').prop('checked',item.selected).appendTo(selectWrapper);
|
var cb = $('<input class="red-ui-treeList-checkbox" type="checkbox">').prop('checked',item.selected).appendTo(selectWrapper);
|
||||||
label.toggleClass("selected",item.selected);
|
|
||||||
cb.on('click', function(e) {
|
cb.on('click', function(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
});
|
});
|
||||||
cb.on('change', function(e) {
|
cb.on('change', function(e) {
|
||||||
item.selected = this.checked;
|
item.selected = this.checked;
|
||||||
|
if (item.selected) {
|
||||||
|
that._selected.add(item);
|
||||||
|
} else {
|
||||||
|
that._selected.delete(item);
|
||||||
|
}
|
||||||
label.toggleClass("selected",this.checked);
|
label.toggleClass("selected",this.checked);
|
||||||
that._trigger("select",e,item);
|
that._trigger("select",e,item);
|
||||||
})
|
})
|
||||||
@ -497,10 +619,15 @@
|
|||||||
cb.trigger("click");
|
cb.trigger("click");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
selectWrapper.appendTo(label)
|
||||||
} else {
|
} else {
|
||||||
label.on("click", function(e) {
|
label.on("click", function(e) {
|
||||||
that._topList.find(".selected").removeClass("selected");
|
if (!that.options.multi) {
|
||||||
|
that.clearSelection();
|
||||||
|
}
|
||||||
label.addClass("selected");
|
label.addClass("selected");
|
||||||
|
that._selected.add(item);
|
||||||
|
|
||||||
that._trigger("select",e,item)
|
that._trigger("select",e,item)
|
||||||
})
|
})
|
||||||
label.on("dblclick", function(e) {
|
label.on("dblclick", function(e) {
|
||||||
@ -508,9 +635,30 @@
|
|||||||
that._trigger("confirm",e,item);
|
that._trigger("confirm",e,item);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
item.treeList.select = function(v) {
|
||||||
|
if (!that.options.multi) {
|
||||||
|
that.clearSelection();
|
||||||
|
}
|
||||||
|
label.toggleClass("selected",v);
|
||||||
|
if (v) {
|
||||||
|
that._selected.add(item);
|
||||||
|
that._trigger("select",null,item)
|
||||||
|
} else {
|
||||||
|
that._selected.delete(item);
|
||||||
|
}
|
||||||
|
that.reveal(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label.toggleClass("selected",!!item.selected);
|
||||||
|
if (item.selected) {
|
||||||
|
that._selected.add(item);
|
||||||
}
|
}
|
||||||
if (item.icon) {
|
if (item.icon) {
|
||||||
$('<span class="red-ui-treeList-icon"><i class="'+item.icon+'" /></span>').appendTo(label);
|
if (typeof item.icon === "string") {
|
||||||
|
$('<span class="red-ui-treeList-icon"><i class="'+item.icon+'" /></span>').appendTo(label);
|
||||||
|
} else {
|
||||||
|
$('<span class="red-ui-treeList-icon">').appendTo(label).append(item.icon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (item.hasOwnProperty('label') || item.hasOwnProperty('sublabel')) {
|
if (item.hasOwnProperty('label') || item.hasOwnProperty('sublabel')) {
|
||||||
if (item.hasOwnProperty('label')) {
|
if (item.hasOwnProperty('label')) {
|
||||||
@ -528,12 +676,13 @@
|
|||||||
}
|
}
|
||||||
if (item.children) {
|
if (item.children) {
|
||||||
if (Array.isArray(item.children) && !item.deferBuild) {
|
if (Array.isArray(item.children) && !item.deferBuild) {
|
||||||
item.treeList.childList = that._addChildren(container,item,item.children,depth).hide();
|
item.treeList.childList = that._addChildren(container,item,item.children,depth);
|
||||||
}
|
}
|
||||||
if (item.expanded) {
|
if (item.expanded) {
|
||||||
item.treeList.expand();
|
item.treeList.expand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// label.appendTo(container);
|
||||||
},
|
},
|
||||||
empty: function() {
|
empty: function() {
|
||||||
this._topList.editableList('empty');
|
this._topList.editableList('empty');
|
||||||
@ -542,6 +691,7 @@
|
|||||||
var that = this;
|
var that = this;
|
||||||
if (items !== undefined) {
|
if (items !== undefined) {
|
||||||
this._data = items;
|
this._data = items;
|
||||||
|
this._items = {};
|
||||||
this._topList.editableList('empty');
|
this._topList.editableList('empty');
|
||||||
this._loadingData = true;
|
this._loadingData = true;
|
||||||
for (var i=0; i<items.length;i++) {
|
for (var i=0; i<items.length;i++) {
|
||||||
@ -556,33 +706,149 @@
|
|||||||
return this._data;
|
return this._data;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
show: function(id) {
|
show: function(item, done) {
|
||||||
for (var i=0;i<this._data.length;i++) {
|
if (typeof item === "string") {
|
||||||
if (this._data[i].id === id) {
|
item = this._items[item]
|
||||||
this._topList.editableList('show',this._data[i]);
|
}
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var that = this;
|
||||||
|
var stack = [];
|
||||||
|
var i = item;
|
||||||
|
while(i) {
|
||||||
|
stack.unshift(i);
|
||||||
|
i = i.parent;
|
||||||
|
}
|
||||||
|
var isOpening = false;
|
||||||
|
var handleStack = function(opening) {
|
||||||
|
isOpening = isOpening ||opening
|
||||||
|
var item = stack.shift();
|
||||||
|
if (stack.length === 0) {
|
||||||
|
setTimeout(function() {
|
||||||
|
that.reveal(item);
|
||||||
|
if (done) { done(); }
|
||||||
|
},isOpening?200:0);
|
||||||
|
} else {
|
||||||
|
item.treeList.expand(handleStack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
handleStack();
|
||||||
},
|
},
|
||||||
select: function(item) {
|
reveal: function(item) {
|
||||||
this._topList.find(".selected").removeClass("selected");
|
if (typeof item === "string") {
|
||||||
item.treeList.label.addClass("selected");
|
item = this._items[item]
|
||||||
this._trigger("select",null,item)
|
}
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var listOffset = this._topList.offset().top;
|
||||||
|
var itemOffset = item.treeList.label.offset().top;
|
||||||
|
var scrollTop = this._topList.parent().scrollTop();
|
||||||
|
itemOffset -= listOffset+scrollTop;
|
||||||
|
var treeHeight = this._topList.parent().height();
|
||||||
|
var itemHeight = item.treeList.label.outerHeight();
|
||||||
|
if (itemOffset < itemHeight/2) {
|
||||||
|
this._topList.parent().scrollTop(scrollTop+itemOffset-itemHeight/2-itemHeight)
|
||||||
|
} else if (itemOffset+itemHeight > treeHeight) {
|
||||||
|
this._topList.parent().scrollTop(scrollTop+((itemOffset+2.5*itemHeight)-treeHeight));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
select: function(item, triggerEvent, deselectExisting) {
|
||||||
|
var that = this;
|
||||||
|
if (!this.options.multi && deselectExisting !== false) {
|
||||||
|
this.clearSelection();
|
||||||
|
}
|
||||||
|
if (Array.isArray(item)) {
|
||||||
|
item.forEach(function(i) {
|
||||||
|
that.select(i,triggerEvent,false);
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof item === "string") {
|
||||||
|
item = this._items[item]
|
||||||
|
}
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// this.show(item.id);
|
||||||
|
item.selected = true;
|
||||||
|
this._selected.add(item);
|
||||||
|
|
||||||
|
if (item.treeList.label) {
|
||||||
|
item.treeList.label.addClass("selected");
|
||||||
|
}
|
||||||
|
if (triggerEvent !== false) {
|
||||||
|
this._trigger("select",null,item)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearSelection: function() {
|
||||||
|
this._selected.forEach(function(item) {
|
||||||
|
item.selected = false;
|
||||||
|
if (item.treeList.label) {
|
||||||
|
item.treeList.label.removeClass("selected")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this._selected.clear();
|
||||||
},
|
},
|
||||||
selected: function() {
|
selected: function() {
|
||||||
var s = this._topList.find(".selected");
|
var selected = [];
|
||||||
|
this._selected.forEach(function(item) {
|
||||||
|
selected.push(item);
|
||||||
|
})
|
||||||
if (this.options.multi) {
|
if (this.options.multi) {
|
||||||
var res = [];
|
return selected;
|
||||||
s.each(function() {
|
|
||||||
res.push($(this).parent().data('data'));
|
|
||||||
})
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
if (s.length) {
|
if (selected.length) {
|
||||||
return s.parent().data('data');
|
return selected[0]
|
||||||
} else {
|
} else {
|
||||||
|
// TODO: This may be a bug.. it causes the call to return itself
|
||||||
|
// not undefined.
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
filter: function(filterFunc) {
|
||||||
|
this.activeFilter = filterFunc;
|
||||||
|
var totalCount = 0;
|
||||||
|
var filter = function(item) {
|
||||||
|
var matchCount = 0;
|
||||||
|
if (filterFunc && filterFunc(item)) {
|
||||||
|
matchCount++;
|
||||||
|
totalCount++;
|
||||||
|
}
|
||||||
|
var childCount = 0;
|
||||||
|
if (item.children && typeof item.children !== "function") {
|
||||||
|
if (item.treeList.childList) {
|
||||||
|
childCount = item.treeList.childList.editableList('filter', filter);
|
||||||
|
} else {
|
||||||
|
item.treeList.childFilter = filter;
|
||||||
|
if (filterFunc) {
|
||||||
|
item.children.forEach(function(i) {
|
||||||
|
if (filter(i)) {
|
||||||
|
childCount++;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matchCount += childCount;
|
||||||
|
if (filterFunc && childCount > 0) {
|
||||||
|
setTimeout(function() {
|
||||||
|
item.treeList.expand();
|
||||||
|
},10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!filterFunc) {
|
||||||
|
totalCount++;
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return matchCount > 0
|
||||||
|
}
|
||||||
|
this._topList.editableList('filter', filter);
|
||||||
|
return totalCount;
|
||||||
|
},
|
||||||
|
get: function(id) {
|
||||||
|
return this._items[id] || null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -164,6 +164,84 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
cred:{
|
||||||
|
value:"cred",
|
||||||
|
label:"credential",
|
||||||
|
icon:"fa fa-lock",
|
||||||
|
inputType: "password",
|
||||||
|
valueLabel: function(container,value) {
|
||||||
|
var that = this;
|
||||||
|
container.css("pointer-events","none");
|
||||||
|
this.elementDiv.hide();
|
||||||
|
var buttons = $('<div>').css({
|
||||||
|
position: "absolute",
|
||||||
|
right:"6px",
|
||||||
|
top: "6px",
|
||||||
|
"pointer-events":"all"
|
||||||
|
}).appendTo(container);
|
||||||
|
var eyeButton = $('<button type="button" class="red-ui-button red-ui-button-small"></button>').css({
|
||||||
|
width:"20px"
|
||||||
|
}).appendTo(buttons).on("click", function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
var currentType = that.input.attr("type");
|
||||||
|
if (currentType === "text") {
|
||||||
|
that.input.attr("type","password");
|
||||||
|
eyeCon.removeClass("fa-eye-slash").addClass("fa-eye");
|
||||||
|
setTimeout(function() {
|
||||||
|
that.input.focus();
|
||||||
|
},50);
|
||||||
|
} else {
|
||||||
|
that.input.attr("type","text");
|
||||||
|
eyeCon.removeClass("fa-eye").addClass("fa-eye-slash");
|
||||||
|
setTimeout(function() {
|
||||||
|
that.input.focus();
|
||||||
|
},50);
|
||||||
|
}
|
||||||
|
}).hide();
|
||||||
|
var eyeCon = $('<i class="fa fa-eye"></i>').css("margin-left","-1px").appendTo(eyeButton);
|
||||||
|
|
||||||
|
if (value === "__PWRD__") {
|
||||||
|
var innerContainer = $('<div><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i></div>').css({
|
||||||
|
padding:"6px 6px",
|
||||||
|
borderRadius:"4px"
|
||||||
|
}).addClass("red-ui-typedInput-value-label-inactive").appendTo(container);
|
||||||
|
var editButton = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-pencil"></i></button>').appendTo(buttons).on("click", function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
innerContainer.hide();
|
||||||
|
container.css("background","none");
|
||||||
|
container.css("pointer-events","none");
|
||||||
|
that.input.val("");
|
||||||
|
that.element.val("");
|
||||||
|
that.elementDiv.show();
|
||||||
|
editButton.hide();
|
||||||
|
cancelButton.show();
|
||||||
|
eyeButton.show();
|
||||||
|
setTimeout(function() {
|
||||||
|
that.input.focus();
|
||||||
|
},50);
|
||||||
|
});
|
||||||
|
var cancelButton = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-times"></i></button>').css("margin-left","3px").appendTo(buttons).on("click", function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
innerContainer.show();
|
||||||
|
container.css("background","");
|
||||||
|
that.input.val("__PWRD__");
|
||||||
|
that.element.val("__PWRD__");
|
||||||
|
that.elementDiv.hide();
|
||||||
|
editButton.show();
|
||||||
|
cancelButton.hide();
|
||||||
|
eyeButton.hide();
|
||||||
|
that.input.attr("type","password");
|
||||||
|
eyeCon.removeClass("fa-eye-slash").addClass("fa-eye");
|
||||||
|
|
||||||
|
}).hide();
|
||||||
|
} else {
|
||||||
|
container.css("background","none");
|
||||||
|
container.css("pointer-events","none");
|
||||||
|
this.elementDiv.show();
|
||||||
|
eyeButton.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var nlsd = false;
|
var nlsd = false;
|
||||||
@ -220,6 +298,8 @@
|
|||||||
that.input.attr(d,m);
|
that.input.attr(d,m);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.defaultInputType = this.input.attr('type');
|
||||||
|
|
||||||
this.uiSelect.addClass("red-ui-typedInput-container");
|
this.uiSelect.addClass("red-ui-typedInput-container");
|
||||||
|
|
||||||
this.element.attr('type','hidden');
|
this.element.attr('type','hidden');
|
||||||
@ -369,6 +449,9 @@
|
|||||||
if (opt.label) {
|
if (opt.label) {
|
||||||
op.text(opt.label);
|
op.text(opt.label);
|
||||||
}
|
}
|
||||||
|
if (opt.title) {
|
||||||
|
op.prop('title', opt.title)
|
||||||
|
}
|
||||||
if (opt.icon) {
|
if (opt.icon) {
|
||||||
if (opt.icon.indexOf("<") === 0) {
|
if (opt.icon.indexOf("<") === 0) {
|
||||||
$(opt.icon).prependTo(op);
|
$(opt.icon).prependTo(op);
|
||||||
@ -635,7 +718,7 @@
|
|||||||
$('<img>',{src:mapDeprecatedIcon(opt.icon),style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel);
|
$('<img>',{src:mapDeprecatedIcon(opt.icon),style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$('<i>',{class:"red-ui-typedInput-icon "+opt.icon}).prependTo(this.selectLabel);
|
$('<i>',{class:"red-ui-typedInput-icon "+opt.icon,style:"min-width: 13px; margin-right: 4px;"}).prependTo(this.selectLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opt.hasValue === false || (opt.showLabel !== false && !opt.icon)) {
|
if (opt.hasValue === false || (opt.showLabel !== false && !opt.icon)) {
|
||||||
@ -778,6 +861,11 @@
|
|||||||
if (this.optionSelectTrigger) {
|
if (this.optionSelectTrigger) {
|
||||||
this.optionSelectTrigger.hide();
|
this.optionSelectTrigger.hide();
|
||||||
}
|
}
|
||||||
|
if (opt.inputType) {
|
||||||
|
this.input.attr('type',opt.inputType)
|
||||||
|
} else {
|
||||||
|
this.input.attr('type',this.defaultInputType)
|
||||||
|
}
|
||||||
if (opt.hasValue === false) {
|
if (opt.hasValue === false) {
|
||||||
this.oldValue = this.input.val();
|
this.oldValue = this.input.val();
|
||||||
this.input.val("");
|
this.input.val("");
|
||||||
@ -786,8 +874,8 @@
|
|||||||
} else if (opt.valueLabel) {
|
} else if (opt.valueLabel) {
|
||||||
this.valueLabelContainer.show();
|
this.valueLabelContainer.show();
|
||||||
this.valueLabelContainer.empty();
|
this.valueLabelContainer.empty();
|
||||||
opt.valueLabel.call(this,this.valueLabelContainer,this.input.val());
|
|
||||||
this.elementDiv.hide();
|
this.elementDiv.hide();
|
||||||
|
opt.valueLabel.call(this,this.valueLabelContainer,this.input.val());
|
||||||
} else {
|
} else {
|
||||||
if (this.oldValue !== undefined) {
|
if (this.oldValue !== undefined) {
|
||||||
this.input.val(this.oldValue);
|
this.input.val(this.oldValue);
|
||||||
@ -825,7 +913,7 @@
|
|||||||
panel.show({
|
panel.show({
|
||||||
target:that.optionExpandButton,
|
target:that.optionExpandButton,
|
||||||
onclose:content.onclose,
|
onclose:content.onclose,
|
||||||
align: "right"
|
align: "left"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -108,7 +108,7 @@ RED.deploy = (function() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
RED.events.on('nodes:change',function(state) {
|
RED.events.on('workspace:dirty',function(state) {
|
||||||
if (state.dirty) {
|
if (state.dirty) {
|
||||||
window.onbeforeunload = function() {
|
window.onbeforeunload = function() {
|
||||||
return RED._("deploy.confirm.undeployedChanges");
|
return RED._("deploy.confirm.undeployedChanges");
|
||||||
|
@ -204,32 +204,28 @@ RED.editor = (function() {
|
|||||||
node.dirty = true;
|
node.dirty = true;
|
||||||
node.dirtyStatus = true;
|
node.dirtyStatus = true;
|
||||||
var removedLinks = [];
|
var removedLinks = [];
|
||||||
if (node.ports) {
|
if (outputMap) {
|
||||||
if (outputMap) {
|
RED.nodes.eachLink(function(l) {
|
||||||
RED.nodes.eachLink(function(l) {
|
if (l.source === node) {
|
||||||
if (l.source === node && outputMap.hasOwnProperty(l.sourcePort)) {
|
if (outputMap.hasOwnProperty(l.sourcePort)) {
|
||||||
if (outputMap[l.sourcePort] === "-1") {
|
if (outputMap[l.sourcePort] === "-1") {
|
||||||
removedLinks.push(l);
|
removedLinks.push(l);
|
||||||
} else {
|
} else {
|
||||||
l.sourcePort = outputMap[l.sourcePort];
|
l.sourcePort = outputMap[l.sourcePort];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
if (node.outputs < node.ports.length) {
|
|
||||||
while (node.outputs < node.ports.length) {
|
|
||||||
node.ports.pop();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (node.hasOwnProperty("__outputs")) {
|
||||||
|
if (node.outputs < node.__outputs) {
|
||||||
RED.nodes.eachLink(function(l) {
|
RED.nodes.eachLink(function(l) {
|
||||||
if (l.source === node && l.sourcePort >= node.outputs && removedLinks.indexOf(l) === -1) {
|
if (l.source === node && l.sourcePort >= node.outputs && removedLinks.indexOf(l) === -1) {
|
||||||
removedLinks.push(l);
|
removedLinks.push(l);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (node.outputs > node.ports.length) {
|
|
||||||
while (node.outputs > node.ports.length) {
|
|
||||||
node.ports.push(node.ports.length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
delete node.__outputs;
|
||||||
}
|
}
|
||||||
node.inputs = Math.min(1,Math.max(0,parseInt(node.inputs)));
|
node.inputs = Math.min(1,Math.max(0,parseInt(node.inputs)));
|
||||||
if (isNaN(node.inputs)) {
|
if (isNaN(node.inputs)) {
|
||||||
@ -490,8 +486,7 @@ RED.editor = (function() {
|
|||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (definition.credentials || /^subflow:/.test(definition.type)) {
|
||||||
if (definition.credentials) {
|
|
||||||
if (node.credentials) {
|
if (node.credentials) {
|
||||||
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
||||||
completePrepare();
|
completePrepare();
|
||||||
@ -499,7 +494,9 @@ RED.editor = (function() {
|
|||||||
$.getJSON(getCredentialsURL(node.type, node.id), function (data) {
|
$.getJSON(getCredentialsURL(node.type, node.id), function (data) {
|
||||||
node.credentials = data;
|
node.credentials = data;
|
||||||
node.credentials._ = $.extend(true,{},data);
|
node.credentials._ = $.extend(true,{},data);
|
||||||
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
if (!/^subflow:/.test(definition.type)) {
|
||||||
|
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
||||||
|
}
|
||||||
completePrepare();
|
completePrepare();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -513,7 +510,9 @@ RED.editor = (function() {
|
|||||||
for (var i=editStack.length-1;i<editStack.length;i++) {
|
for (var i=editStack.length-1;i<editStack.length;i++) {
|
||||||
var node = editStack[i];
|
var node = editStack[i];
|
||||||
label = node.type;
|
label = node.type;
|
||||||
if (node.type === '_expression') {
|
if (node.type === 'group') {
|
||||||
|
label = RED._("group.editGroup",{name:RED.utils.sanitize(node.name||node.id)});
|
||||||
|
} else if (node.type === '_expression') {
|
||||||
label = RED._("expressionEditor.title");
|
label = RED._("expressionEditor.title");
|
||||||
} else if (node.type === '_js') {
|
} else if (node.type === '_js') {
|
||||||
label = RED._("jsEditor.title");
|
label = RED._("jsEditor.title");
|
||||||
@ -576,8 +575,11 @@ RED.editor = (function() {
|
|||||||
$(this).attr("data-i18n",keys.join(";"));
|
$(this).attr("data-i18n",keys.join(";"));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (type === "subflow-template" || type === "subflow") {
|
if (type === "subflow-template") {
|
||||||
RED.subflow.buildEditForm(dialogForm,type,node);
|
// This is the 'edit properties' dialog for a subflow template
|
||||||
|
// TODO: this needs to happen later in the dialog open sequence
|
||||||
|
// so that credentials can be loaded prior to building the form
|
||||||
|
RED.subflow.buildEditForm(type,node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add dummy fields to prevent 'Enter' submitting the form in some
|
// Add dummy fields to prevent 'Enter' submitting the form in some
|
||||||
@ -586,6 +588,7 @@ RED.editor = (function() {
|
|||||||
// - the elements need to have id's that imply password/username
|
// - the elements need to have id's that imply password/username
|
||||||
$('<span style="position: absolute; top: -2000px;"><input id="red-ui-trap-password" type="password"/></span>').prependTo(dialogForm);
|
$('<span style="position: absolute; top: -2000px;"><input id="red-ui-trap-password" type="password"/></span>').prependTo(dialogForm);
|
||||||
$('<span style="position: absolute; top: -2000px;"><input id="red-ui-trap-username" type="text"/></span>').prependTo(dialogForm);
|
$('<span style="position: absolute; top: -2000px;"><input id="red-ui-trap-username" type="text"/></span>').prependTo(dialogForm);
|
||||||
|
$('<span style="position: absolute; top: -2000px;"><input id="red-ui-trap-user" type="text"/></span>').prependTo(dialogForm);
|
||||||
dialogForm.on("submit", function(e) { e.preventDefault();});
|
dialogForm.on("submit", function(e) { e.preventDefault();});
|
||||||
dialogForm.find('input').attr("autocomplete","off");
|
dialogForm.find('input').attr("autocomplete","off");
|
||||||
return dialogForm;
|
return dialogForm;
|
||||||
@ -784,6 +787,11 @@ RED.editor = (function() {
|
|||||||
nodeDiv.css({
|
nodeDiv.css({
|
||||||
'backgroundColor': backgroundColor
|
'backgroundColor': backgroundColor
|
||||||
});
|
});
|
||||||
|
var borderColor = RED.utils.getDarkerColor(backgroundColor);
|
||||||
|
if (borderColor !== backgroundColor) {
|
||||||
|
nodeDiv.css('border-color',borderColor)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
||||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||||
@ -819,99 +827,6 @@ RED.editor = (function() {
|
|||||||
searchInput.trigger("focus");
|
searchInput.trigger("focus");
|
||||||
}
|
}
|
||||||
|
|
||||||
function createColorPicker(colorRow, color) {
|
|
||||||
|
|
||||||
var colorButton = $('<button type="button" class="red-ui-button red-ui-editor-node-appearance-button">').appendTo(colorRow);
|
|
||||||
$('<i class="fa fa-caret-down"></i>').appendTo(colorButton);
|
|
||||||
|
|
||||||
var colorDisp = $('<div>',{class:"red-ui-search-result-node"}).appendTo(colorButton);
|
|
||||||
|
|
||||||
var selector = $("<input/>", {
|
|
||||||
id: "red-ui-editor-node-color",
|
|
||||||
type: "text",
|
|
||||||
value: color
|
|
||||||
}).css({
|
|
||||||
marginLeft: "10px",
|
|
||||||
width: "150px",
|
|
||||||
}).appendTo(colorRow);
|
|
||||||
|
|
||||||
selector.on("change", function (e) {
|
|
||||||
var color = selector.val();
|
|
||||||
$(".red-ui-editor-node-appearance-button .red-ui-search-result-node").css({
|
|
||||||
"background-color": color
|
|
||||||
});
|
|
||||||
});
|
|
||||||
selector.trigger("change");
|
|
||||||
colorButton.on("click", function (e) {
|
|
||||||
var recommendedColors = [
|
|
||||||
"#DDAA99",
|
|
||||||
"#3FADB5", "#87A980", "#A6BBCF",
|
|
||||||
"#AAAA66", "#C0C0C0", "#C0DEED",
|
|
||||||
"#C7E9C0", "#D7D7A0", "#D8BFD8",
|
|
||||||
"#DAC4B4", "#DEB887", "#DEBD5C",
|
|
||||||
"#E2D96E", "#E6E0F8", "#E7E7AE",
|
|
||||||
"#E9967A", "#F3B567", "#FDD0A2",
|
|
||||||
"#FDF0C2", "#FFAAAA", "#FFCC66",
|
|
||||||
"#FFF0F0", "#FFFFFF"
|
|
||||||
].map(function(c) {
|
|
||||||
var r = parseInt(c.substring(1, 3), 16) / 255;
|
|
||||||
var g = parseInt(c.substring(3, 5), 16) / 255;
|
|
||||||
var b = parseInt(c.substring(5, 7), 16) / 255;
|
|
||||||
return {
|
|
||||||
hex: c,
|
|
||||||
r: r,
|
|
||||||
g: g,
|
|
||||||
b: b,
|
|
||||||
l: 0.3 * r + 0.59 * g + 0.11 * b
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Sort by luminosity.
|
|
||||||
recommendedColors.sort(function (a, b) {
|
|
||||||
return a.l - b.l;
|
|
||||||
});
|
|
||||||
|
|
||||||
var numColors = recommendedColors.length;
|
|
||||||
var width = 30;
|
|
||||||
var height = 30;
|
|
||||||
var margin = 2;
|
|
||||||
var perRow = 6;
|
|
||||||
var picker = $("<div/>", {
|
|
||||||
class: "red-ui-color-picker"
|
|
||||||
}).css({
|
|
||||||
width: ((width+margin+margin)*perRow)+"px",
|
|
||||||
height: Math.ceil(numColors/perRow)*(height+margin+margin)+"+px"
|
|
||||||
});
|
|
||||||
var count = 0;
|
|
||||||
var row = null;
|
|
||||||
recommendedColors.forEach(function (col) {
|
|
||||||
if ((count % perRow) == 0) {
|
|
||||||
row = $("<div/>").appendTo(picker);
|
|
||||||
}
|
|
||||||
var button = $("<button/>", {
|
|
||||||
}).css({
|
|
||||||
width: width+"px",
|
|
||||||
height: height+"px",
|
|
||||||
margin: margin+"px",
|
|
||||||
backgroundColor: col.hex,
|
|
||||||
"border-style": "solid",
|
|
||||||
"border-width": "1px",
|
|
||||||
"border-color": col.luma<0.92?col.hex:'#ccc'
|
|
||||||
}).appendTo(row);
|
|
||||||
button.on("click", function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
colorPanel.hide();
|
|
||||||
selector.val(col.hex);
|
|
||||||
selector.trigger("change");
|
|
||||||
});
|
|
||||||
count++;
|
|
||||||
});
|
|
||||||
var colorPanel = RED.popover.panel(picker);
|
|
||||||
colorPanel.show({
|
|
||||||
target: colorButton
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildAppearanceForm(container,node) {
|
function buildAppearanceForm(container,node) {
|
||||||
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
||||||
|
|
||||||
@ -964,13 +879,13 @@ RED.editor = (function() {
|
|||||||
var userCount = 0;
|
var userCount = 0;
|
||||||
var subflowType = "subflow:"+node.id;
|
var subflowType = "subflow:"+node.id;
|
||||||
|
|
||||||
RED.nodes.eachNode(function(n) {
|
// RED.nodes.eachNode(function(n) {
|
||||||
if (n.type === subflowType) {
|
// if (n.type === subflowType) {
|
||||||
userCount++;
|
// userCount++;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
$("#red-ui-editor-subflow-user-count")
|
$("#red-ui-editor-subflow-user-count")
|
||||||
.text(RED._("subflow.subflowInstances", {count:userCount})).show();
|
.text(RED._("subflow.subflowInstances", {count:node.instances.length})).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
$('<div class="form-row">'+
|
$('<div class="form-row">'+
|
||||||
@ -997,7 +912,35 @@ RED.editor = (function() {
|
|||||||
class: "form-row"
|
class: "form-row"
|
||||||
}).appendTo(dialogForm);
|
}).appendTo(dialogForm);
|
||||||
$("<label/>").text(RED._("editor.color")).appendTo(colorRow);
|
$("<label/>").text(RED._("editor.color")).appendTo(colorRow);
|
||||||
createColorPicker(colorRow, color);
|
|
||||||
|
var recommendedColors = [
|
||||||
|
"#DDAA99",
|
||||||
|
"#3FADB5", "#87A980", "#A6BBCF",
|
||||||
|
"#AAAA66", "#C0C0C0", "#C0DEED",
|
||||||
|
"#C7E9C0", "#D7D7A0", "#D8BFD8",
|
||||||
|
"#DAC4B4", "#DEB887", "#DEBD5C",
|
||||||
|
"#E2D96E", "#E6E0F8", "#E7E7AE",
|
||||||
|
"#E9967A", "#F3B567", "#FDD0A2",
|
||||||
|
"#FDF0C2", "#FFAAAA", "#FFCC66",
|
||||||
|
"#FFF0F0", "#FFFFFF"
|
||||||
|
]
|
||||||
|
|
||||||
|
RED.colorPicker.create({
|
||||||
|
id: "red-ui-editor-node-color",
|
||||||
|
value: color,
|
||||||
|
palette: recommendedColors,
|
||||||
|
sortPalette: function (a, b) {return a.l - b.l;}
|
||||||
|
}).appendTo(colorRow);
|
||||||
|
|
||||||
|
$("#red-ui-editor-node-color").on('change', function(ev) {
|
||||||
|
// Horribly out of scope...
|
||||||
|
var colour = $(this).val();
|
||||||
|
nodeDiv.css('backgroundColor',colour);
|
||||||
|
var borderColor = RED.utils.getDarkerColor(colour);
|
||||||
|
if (borderColor !== colour) {
|
||||||
|
nodeDiv.css('border-color',borderColor)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1012,6 +955,11 @@ RED.editor = (function() {
|
|||||||
var colour = RED.utils.getNodeColor(node.type, node._def);
|
var colour = RED.utils.getNodeColor(node.type, node._def);
|
||||||
var icon_url = RED.utils.getNodeIcon(node._def,node);
|
var icon_url = RED.utils.getNodeIcon(node._def,node);
|
||||||
nodeDiv.css('backgroundColor',colour);
|
nodeDiv.css('backgroundColor',colour);
|
||||||
|
var borderColor = RED.utils.getDarkerColor(colour);
|
||||||
|
if (borderColor !== colour) {
|
||||||
|
nodeDiv.css('border-color',borderColor)
|
||||||
|
}
|
||||||
|
|
||||||
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
||||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||||
|
|
||||||
@ -1132,15 +1080,17 @@ RED.editor = (function() {
|
|||||||
if (node.info) {
|
if (node.info) {
|
||||||
nodeInfoEditor.getSession().setValue(node.info, -1);
|
nodeInfoEditor.getSession().setValue(node.info, -1);
|
||||||
}
|
}
|
||||||
|
node.infoEditor = nodeInfoEditor;
|
||||||
return nodeInfoEditor;
|
return nodeInfoEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showEditDialog(node) {
|
function showEditDialog(node, defaultTab) {
|
||||||
var editing_node = node;
|
var editing_node = node;
|
||||||
var isDefaultIcon;
|
var isDefaultIcon;
|
||||||
var defaultIcon;
|
var defaultIcon;
|
||||||
var nodeInfoEditor;
|
var nodeInfoEditor;
|
||||||
var finishedBuilding = false;
|
var finishedBuilding = false;
|
||||||
|
var skipInfoRefreshOnClose = false;
|
||||||
|
|
||||||
editStack.push(node);
|
editStack.push(node);
|
||||||
RED.view.state(RED.state.EDITING);
|
RED.view.state(RED.state.EDITING);
|
||||||
@ -1333,10 +1283,12 @@ RED.editor = (function() {
|
|||||||
if (configNode) {
|
if (configNode) {
|
||||||
var users = configNode.users;
|
var users = configNode.users;
|
||||||
users.splice(users.indexOf(editing_node),1);
|
users.splice(users.indexOf(editing_node),1);
|
||||||
|
RED.events.emit("nodes:change",configNode);
|
||||||
}
|
}
|
||||||
configNode = RED.nodes.node(newValue);
|
configNode = RED.nodes.node(newValue);
|
||||||
if (configNode) {
|
if (configNode) {
|
||||||
configNode.users.push(editing_node);
|
configNode.users.push(editing_node);
|
||||||
|
RED.events.emit("nodes:change",configNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
changes[d] = editing_node[d];
|
changes[d] = editing_node[d];
|
||||||
@ -1471,6 +1423,19 @@ RED.editor = (function() {
|
|||||||
if (type === "subflow") {
|
if (type === "subflow") {
|
||||||
var old_env = editing_node.env;
|
var old_env = editing_node.env;
|
||||||
var new_env = RED.subflow.exportSubflowInstanceEnv(editing_node);
|
var new_env = RED.subflow.exportSubflowInstanceEnv(editing_node);
|
||||||
|
if (new_env && new_env.length > 0) {
|
||||||
|
new_env.forEach(function(prop) {
|
||||||
|
if (prop.type === "cred") {
|
||||||
|
editing_node.credentials = editing_node.credentials || {_:{}};
|
||||||
|
editing_node.credentials[prop.name] = prop.value;
|
||||||
|
editing_node.credentials['has_'+prop.name] = (prop.value !== "");
|
||||||
|
if (prop.value !== '__PWRD__') {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
delete prop.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
if (!isSameObj(old_env, new_env)) {
|
if (!isSameObj(old_env, new_env)) {
|
||||||
editing_node.env = new_env;
|
editing_node.env = new_env;
|
||||||
changes.env = editing_node.env;
|
changes.env = editing_node.env;
|
||||||
@ -1520,6 +1485,7 @@ RED.editor = (function() {
|
|||||||
editing_node.dirty = true;
|
editing_node.dirty = true;
|
||||||
validateNode(editing_node);
|
validateNode(editing_node);
|
||||||
RED.events.emit("editor:save",editing_node);
|
RED.events.emit("editor:save",editing_node);
|
||||||
|
RED.events.emit("nodes:change",editing_node);
|
||||||
RED.tray.close();
|
RED.tray.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1537,6 +1503,10 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
open: function(tray, done) {
|
open: function(tray, done) {
|
||||||
|
if (editing_node.hasOwnProperty('outputs')) {
|
||||||
|
editing_node.__outputs = editing_node.outputs;
|
||||||
|
}
|
||||||
|
|
||||||
var trayFooter = tray.find(".red-ui-tray-footer");
|
var trayFooter = tray.find(".red-ui-tray-footer");
|
||||||
var trayBody = tray.find('.red-ui-tray-body');
|
var trayBody = tray.find('.red-ui-tray-body');
|
||||||
trayBody.parent().css('overflow','hidden');
|
trayBody.parent().css('overflow','hidden');
|
||||||
@ -1567,9 +1537,6 @@ RED.editor = (function() {
|
|||||||
collapsible: true,
|
collapsible: true,
|
||||||
menu: false
|
menu: false
|
||||||
});
|
});
|
||||||
if (editing_node) {
|
|
||||||
RED.sidebar.info.refresh(editing_node);
|
|
||||||
}
|
|
||||||
var ns;
|
var ns;
|
||||||
if (node._def.set.module === "node-red") {
|
if (node._def.set.module === "node-red") {
|
||||||
ns = "node-red";
|
ns = "node-red";
|
||||||
@ -1599,12 +1566,13 @@ RED.editor = (function() {
|
|||||||
id: "editor-subflow-envProperties",
|
id: "editor-subflow-envProperties",
|
||||||
label: RED._("editor-tab.envProperties"),
|
label: RED._("editor-tab.envProperties"),
|
||||||
name: RED._("editor-tab.envProperties"),
|
name: RED._("editor-tab.envProperties"),
|
||||||
content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
content: $('<div>', {id:"editor-subflow-envProperties-content",class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
||||||
iconClass: "fa fa-list"
|
iconClass: "fa fa-list"
|
||||||
};
|
};
|
||||||
|
|
||||||
RED.subflow.buildPropertiesForm(subflowPropertiesTab.content,node);
|
|
||||||
editorTabs.addTab(subflowPropertiesTab);
|
editorTabs.addTab(subflowPropertiesTab);
|
||||||
|
// This tab is populated by the oneditprepare function of this
|
||||||
|
// subflow. That ensures it is done *after* any credentials
|
||||||
|
// have been loaded for the instance.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node._def.defaults || !node._def.defaults.hasOwnProperty('info')) {
|
if (!node._def.defaults || !node._def.defaults.hasOwnProperty('info')) {
|
||||||
@ -1638,6 +1606,9 @@ RED.editor = (function() {
|
|||||||
prepareEditDialog(node,node._def,"node-input", function() {
|
prepareEditDialog(node,node._def,"node-input", function() {
|
||||||
trayBody.i18n();
|
trayBody.i18n();
|
||||||
finishedBuilding = true;
|
finishedBuilding = true;
|
||||||
|
if (defaultTab) {
|
||||||
|
editorTabs.activateTab(defaultTab);
|
||||||
|
}
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1645,7 +1616,7 @@ RED.editor = (function() {
|
|||||||
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
||||||
RED.view.state(RED.state.DEFAULT);
|
RED.view.state(RED.state.DEFAULT);
|
||||||
}
|
}
|
||||||
if (editing_node) {
|
if (editing_node && !skipInfoRefreshOnClose) {
|
||||||
RED.sidebar.info.refresh(editing_node);
|
RED.sidebar.info.refresh(editing_node);
|
||||||
}
|
}
|
||||||
RED.workspaces.refresh();
|
RED.workspaces.refresh();
|
||||||
@ -1673,6 +1644,7 @@ RED.editor = (function() {
|
|||||||
text: RED._("subflow.edit"),
|
text: RED._("subflow.edit"),
|
||||||
click: function() {
|
click: function() {
|
||||||
RED.workspaces.show(id);
|
RED.workspaces.show(id);
|
||||||
|
skipInfoRefreshOnClose = true;
|
||||||
$("#node-dialog-ok").trigger("click");
|
$("#node-dialog-ok").trigger("click");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1941,10 +1913,12 @@ RED.editor = (function() {
|
|||||||
if (configNode) {
|
if (configNode) {
|
||||||
var users = configNode.users;
|
var users = configNode.users;
|
||||||
users.splice(users.indexOf(editing_config_node),1);
|
users.splice(users.indexOf(editing_config_node),1);
|
||||||
|
RED.events.emit("nodes:change",configNode);
|
||||||
}
|
}
|
||||||
configNode = RED.nodes.node(newValue);
|
configNode = RED.nodes.node(newValue);
|
||||||
if (configNode) {
|
if (configNode) {
|
||||||
configNode.users.push(editing_config_node);
|
configNode.users.push(editing_config_node);
|
||||||
|
RED.events.emit("nodes:change",configNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
editing_config_node[d] = newValue;
|
editing_config_node[d] = newValue;
|
||||||
@ -2039,6 +2013,7 @@ RED.editor = (function() {
|
|||||||
RED.view.redraw(true);
|
RED.view.redraw(true);
|
||||||
if (!configAdding) {
|
if (!configAdding) {
|
||||||
RED.events.emit("editor:save",editing_config_node);
|
RED.events.emit("editor:save",editing_config_node);
|
||||||
|
RED.events.emit("nodes:change",editing_config_node);
|
||||||
}
|
}
|
||||||
RED.tray.close(function() {
|
RED.tray.close(function() {
|
||||||
updateConfigNodeSelect(configProperty,configType,editing_config_node.id,prefix);
|
updateConfigNodeSelect(configProperty,configType,editing_config_node.id,prefix);
|
||||||
@ -2252,12 +2227,26 @@ RED.editor = (function() {
|
|||||||
|
|
||||||
var old_env = editing_node.env;
|
var old_env = editing_node.env;
|
||||||
var new_env = RED.subflow.exportSubflowTemplateEnv($("#node-input-env-container").editableList("items"));
|
var new_env = RED.subflow.exportSubflowTemplateEnv($("#node-input-env-container").editableList("items"));
|
||||||
|
|
||||||
|
if (new_env && new_env.length > 0) {
|
||||||
|
new_env.forEach(function(prop) {
|
||||||
|
if (prop.type === "cred") {
|
||||||
|
editing_node.credentials = editing_node.credentials || {_:{}};
|
||||||
|
editing_node.credentials[prop.name] = prop.value;
|
||||||
|
editing_node.credentials['has_'+prop.name] = (prop.value !== "");
|
||||||
|
if (prop.value !== '__PWRD__') {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
delete prop.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!isSameObj(old_env, new_env)) {
|
if (!isSameObj(old_env, new_env)) {
|
||||||
editing_node.env = new_env;
|
editing_node.env = new_env;
|
||||||
changes.env = editing_node.env;
|
changes.env = editing_node.env;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
RED.palette.refresh();
|
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
var wasChanged = editing_node.changed;
|
var wasChanged = editing_node.changed;
|
||||||
@ -2277,6 +2266,7 @@ RED.editor = (function() {
|
|||||||
validateNode(n);
|
validateNode(n);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
RED.events.emit("subflows:change",editing_node);
|
||||||
RED.nodes.dirty(true);
|
RED.nodes.dirty(true);
|
||||||
var historyEvent = {
|
var historyEvent = {
|
||||||
t:'edit',
|
t:'edit',
|
||||||
@ -2311,7 +2301,7 @@ RED.editor = (function() {
|
|||||||
$("#node-input-env-container").editableList('height',height-95);
|
$("#node-input-env-container").editableList('height',height-95);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
open: function(tray) {
|
open: function(tray, done) {
|
||||||
var trayFooter = tray.find(".red-ui-tray-footer");
|
var trayFooter = tray.find(".red-ui-tray-footer");
|
||||||
var trayFooterLeft = $("<div/>", {
|
var trayFooterLeft = $("<div/>", {
|
||||||
class: "red-ui-tray-footer-left"
|
class: "red-ui-tray-footer-left"
|
||||||
@ -2362,7 +2352,6 @@ RED.editor = (function() {
|
|||||||
content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
||||||
iconClass: "fa fa-cog"
|
iconClass: "fa fa-cog"
|
||||||
};
|
};
|
||||||
buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template", undefined, editing_node);
|
|
||||||
editorTabs.addTab(nodePropertiesTab);
|
editorTabs.addTab(nodePropertiesTab);
|
||||||
|
|
||||||
var descriptionTab = {
|
var descriptionTab = {
|
||||||
@ -2391,11 +2380,19 @@ RED.editor = (function() {
|
|||||||
buildAppearanceForm(appearanceTab.content,editing_node);
|
buildAppearanceForm(appearanceTab.content,editing_node);
|
||||||
editorTabs.addTab(appearanceTab);
|
editorTabs.addTab(appearanceTab);
|
||||||
|
|
||||||
$("#subflow-input-name").val(subflow.name);
|
buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template", undefined, editing_node);
|
||||||
RED.text.bidi.prepareInput($("#subflow-input-name"));
|
|
||||||
|
|
||||||
trayBody.i18n();
|
trayBody.i18n();
|
||||||
finishedBuilding = true;
|
|
||||||
|
$.getJSON(getCredentialsURL("subflow", subflow.id), function (data) {
|
||||||
|
subflow.credentials = data;
|
||||||
|
subflow.credentials._ = $.extend(true,{},data);
|
||||||
|
|
||||||
|
$("#subflow-input-name").val(subflow.name);
|
||||||
|
RED.text.bidi.prepareInput($("#subflow-input-name"));
|
||||||
|
|
||||||
|
finishedBuilding = true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
||||||
@ -2414,6 +2411,253 @@ RED.editor = (function() {
|
|||||||
RED.tray.show(trayOptions);
|
RED.tray.show(trayOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showEditGroupDialog(group) {
|
||||||
|
var editing_node = group;
|
||||||
|
editStack.push(group);
|
||||||
|
RED.view.state(RED.state.EDITING);
|
||||||
|
var nodeInfoEditor;
|
||||||
|
var finishedBuilding = false;
|
||||||
|
var trayOptions = {
|
||||||
|
title: getEditStackTitle(),
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
id: "node-dialog-cancel",
|
||||||
|
text: RED._("common.label.cancel"),
|
||||||
|
click: function() {
|
||||||
|
RED.tray.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "node-dialog-ok",
|
||||||
|
class: "primary",
|
||||||
|
text: RED._("common.label.done"),
|
||||||
|
click: function() {
|
||||||
|
var changes = {};
|
||||||
|
var changed = false;
|
||||||
|
var wasDirty = RED.nodes.dirty();
|
||||||
|
var d;
|
||||||
|
var outputMap;
|
||||||
|
|
||||||
|
if (editing_node._def.oneditsave) {
|
||||||
|
var oldValues = {};
|
||||||
|
for (d in editing_node._def.defaults) {
|
||||||
|
if (editing_node._def.defaults.hasOwnProperty(d)) {
|
||||||
|
if (typeof editing_node[d] === "string" || typeof editing_node[d] === "number") {
|
||||||
|
oldValues[d] = editing_node[d];
|
||||||
|
} else {
|
||||||
|
oldValues[d] = $.extend(true,{},{v:editing_node[d]}).v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var rc = editing_node._def.oneditsave.call(editing_node);
|
||||||
|
if (rc === true) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log("oneditsave",editing_node.id,editing_node.type,err.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (d in editing_node._def.defaults) {
|
||||||
|
if (editing_node._def.defaults.hasOwnProperty(d)) {
|
||||||
|
if (oldValues[d] === null || typeof oldValues[d] === "string" || typeof oldValues[d] === "number") {
|
||||||
|
if (oldValues[d] !== editing_node[d]) {
|
||||||
|
changes[d] = oldValues[d];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
} else if (d !== "nodes") {
|
||||||
|
if (JSON.stringify(oldValues[d]) !== JSON.stringify(editing_node[d])) {
|
||||||
|
changes[d] = oldValues[d];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var newValue;
|
||||||
|
if (editing_node._def.defaults) {
|
||||||
|
for (d in editing_node._def.defaults) {
|
||||||
|
if (editing_node._def.defaults.hasOwnProperty(d)) {
|
||||||
|
var input = $("#node-input-"+d);
|
||||||
|
if (input.attr('type') === "checkbox") {
|
||||||
|
newValue = input.prop('checked');
|
||||||
|
} else if (input.prop("nodeName") === "select" && input.attr("multiple") === "multiple") {
|
||||||
|
// An empty select-multiple box returns null.
|
||||||
|
// Need to treat that as an empty array.
|
||||||
|
newValue = input.val();
|
||||||
|
if (newValue == null) {
|
||||||
|
newValue = [];
|
||||||
|
}
|
||||||
|
} else if ("format" in editing_node._def.defaults[d] && editing_node._def.defaults[d].format !== "" && input[0].nodeName === "DIV") {
|
||||||
|
newValue = input.text();
|
||||||
|
} else {
|
||||||
|
newValue = input.val();
|
||||||
|
}
|
||||||
|
if (newValue != null) {
|
||||||
|
if (editing_node._def.defaults[d].type) {
|
||||||
|
if (newValue == "_ADD_") {
|
||||||
|
newValue = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (editing_node[d] != newValue) {
|
||||||
|
if (editing_node._def.defaults[d].type) {
|
||||||
|
// Change to a related config node
|
||||||
|
var configNode = RED.nodes.node(editing_node[d]);
|
||||||
|
if (configNode) {
|
||||||
|
var users = configNode.users;
|
||||||
|
users.splice(users.indexOf(editing_node),1);
|
||||||
|
RED.events.emit("nodes:change",configNode);
|
||||||
|
}
|
||||||
|
configNode = RED.nodes.node(newValue);
|
||||||
|
if (configNode) {
|
||||||
|
configNode.users.push(editing_node);
|
||||||
|
RED.events.emit("nodes:change",configNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changes[d] = editing_node[d];
|
||||||
|
editing_node[d] = newValue;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldInfo = editing_node.info;
|
||||||
|
if (nodeInfoEditor) {
|
||||||
|
var newInfo = nodeInfoEditor.getValue();
|
||||||
|
if (!!oldInfo) {
|
||||||
|
// Has existing info property
|
||||||
|
if (newInfo.trim() === "") {
|
||||||
|
// New value is blank - remove the property
|
||||||
|
changed = true;
|
||||||
|
changes.info = oldInfo;
|
||||||
|
delete editing_node.info;
|
||||||
|
} else if (newInfo !== oldInfo) {
|
||||||
|
// New value is different
|
||||||
|
changed = true;
|
||||||
|
changes.info = oldInfo;
|
||||||
|
editing_node.info = newInfo;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No existing info
|
||||||
|
if (newInfo.trim() !== "") {
|
||||||
|
// New value is not blank
|
||||||
|
changed = true;
|
||||||
|
changes.info = undefined;
|
||||||
|
editing_node.info = newInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
var wasChanged = editing_node.changed;
|
||||||
|
editing_node.changed = true;
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
var historyEvent = {
|
||||||
|
t:'edit',
|
||||||
|
node:editing_node,
|
||||||
|
changes:changes,
|
||||||
|
dirty:wasDirty,
|
||||||
|
changed:wasChanged
|
||||||
|
};
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
RED.events.emit("groups:change",editing_node);
|
||||||
|
}
|
||||||
|
editing_node.dirty = true;
|
||||||
|
RED.tray.close();
|
||||||
|
RED.view.redraw(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
resize: function(size) {
|
||||||
|
editTrayWidthCache['group'] = size.width;
|
||||||
|
$(".red-ui-tray-content").height(size.height - 50);
|
||||||
|
// var form = $(".red-ui-tray-content form").height(dimensions.height - 50 - 40);
|
||||||
|
// if (editing_node && editing_node._def.oneditresize) {
|
||||||
|
// try {
|
||||||
|
// editing_node._def.oneditresize.call(editing_node,{width:form.width(),height:form.height()});
|
||||||
|
// } catch(err) {
|
||||||
|
// console.log("oneditresize",editing_node.id,editing_node.type,err.toString());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
open: function(tray, done) {
|
||||||
|
var trayFooter = tray.find(".red-ui-tray-footer");
|
||||||
|
var trayFooterLeft = $("<div/>", {
|
||||||
|
class: "red-ui-tray-footer-left"
|
||||||
|
}).appendTo(trayFooter)
|
||||||
|
var trayBody = tray.find('.red-ui-tray-body');
|
||||||
|
trayBody.parent().css('overflow','hidden');
|
||||||
|
|
||||||
|
var editorTabEl = $('<ul></ul>').appendTo(trayBody);
|
||||||
|
var editorContent = $('<div></div>').appendTo(trayBody);
|
||||||
|
|
||||||
|
var editorTabs = RED.tabs.create({
|
||||||
|
element:editorTabEl,
|
||||||
|
onchange:function(tab) {
|
||||||
|
editorContent.children().hide();
|
||||||
|
if (tab.onchange) {
|
||||||
|
tab.onchange.call(tab);
|
||||||
|
}
|
||||||
|
tab.content.show();
|
||||||
|
if (finishedBuilding) {
|
||||||
|
RED.tray.resize();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collapsible: true,
|
||||||
|
menu: false
|
||||||
|
});
|
||||||
|
|
||||||
|
var nodePropertiesTab = {
|
||||||
|
id: "editor-tab-properties",
|
||||||
|
label: RED._("editor-tab.properties"),
|
||||||
|
name: RED._("editor-tab.properties"),
|
||||||
|
content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-cog"
|
||||||
|
};
|
||||||
|
buildEditForm(nodePropertiesTab.content,"dialog-form","group","node-red",group);
|
||||||
|
|
||||||
|
editorTabs.addTab(nodePropertiesTab);
|
||||||
|
|
||||||
|
var descriptionTab = {
|
||||||
|
id: "editor-tab-description",
|
||||||
|
label: RED._("editor-tab.description"),
|
||||||
|
name: RED._("editor-tab.description"),
|
||||||
|
content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-file-text-o",
|
||||||
|
onchange: function() {
|
||||||
|
nodeInfoEditor.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
editorTabs.addTab(descriptionTab);
|
||||||
|
nodeInfoEditor = buildDescriptionForm(descriptionTab.content,editing_node);
|
||||||
|
prepareEditDialog(group,group._def,"node-input", function() {
|
||||||
|
trayBody.i18n();
|
||||||
|
finishedBuilding = true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
close: function() {
|
||||||
|
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
||||||
|
RED.view.state(RED.state.DEFAULT);
|
||||||
|
}
|
||||||
|
RED.sidebar.info.refresh(editing_node);
|
||||||
|
nodeInfoEditor.destroy();
|
||||||
|
nodeInfoEditor = null;
|
||||||
|
editStack.pop();
|
||||||
|
editing_node = null;
|
||||||
|
},
|
||||||
|
show: function() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (editTrayWidthCache.hasOwnProperty('group')) {
|
||||||
|
trayOptions.width = editTrayWidthCache['group'];
|
||||||
|
}
|
||||||
|
RED.tray.show(trayOptions);
|
||||||
|
}
|
||||||
|
|
||||||
function showTypeEditor(type, options) {
|
function showTypeEditor(type, options) {
|
||||||
if (customEditTypes.hasOwnProperty(type)) {
|
if (customEditTypes.hasOwnProperty(type)) {
|
||||||
if (editStack.length > 0) {
|
if (editStack.length > 0) {
|
||||||
@ -2537,6 +2781,7 @@ RED.editor = (function() {
|
|||||||
edit: showEditDialog,
|
edit: showEditDialog,
|
||||||
editConfig: showEditConfigNodeDialog,
|
editConfig: showEditConfigNodeDialog,
|
||||||
editSubflow: showEditSubflowDialog,
|
editSubflow: showEditSubflowDialog,
|
||||||
|
editGroup: showEditGroupDialog,
|
||||||
editJavaScript: function(options) { showTypeEditor("_js",options) },
|
editJavaScript: function(options) { showTypeEditor("_js",options) },
|
||||||
editExpression: function(options) { showTypeEditor("_expression", options) },
|
editExpression: function(options) { showTypeEditor("_expression", options) },
|
||||||
editJSON: function(options) { showTypeEditor("_json", options) },
|
editJSON: function(options) { showTypeEditor("_json", options) },
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
**/
|
**/
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var template = '<script type="text/x-red" data-template-name="_buffer"><div id="red-ui-editor-type-buffer-panels"><div id="red-ui-editor-type-buffer-panel-str" class="red-ui-panel"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><button class="red-ui-editor-type-buffer-type red-ui-button red-ui-button-small"><i class="fa fa-exclamation-circle"></i> <span id="red-ui-editor-type-buffer-type-string" data-i18n="bufferEditor.modeString"></span><span id="red-ui-editor-type-buffer-type-array" data-i18n="bufferEditor.modeArray"></span></button></div><div class="form-row node-text-editor-row"><div class="node-text-editor" id="red-ui-editor-type-buffer-str"></div></div></div><div id="red-ui-editor-type-buffer-panel-bin" class="red-ui-panel"><div class="form-row node-text-editor-row" style="margin-top: 10px"><div class="node-text-editor" id="red-ui-editor-type-buffer-bin"></div></div></div></div></script>';
|
var template = '<script type="text/x-red" data-template-name="_buffer"><div id="red-ui-editor-type-buffer-panels"><div id="red-ui-editor-type-buffer-panel-str" class="red-ui-panel"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><button class="red-ui-editor-type-buffer-type red-ui-button red-ui-button-small"><i class="fa fa-exclamation-circle"></i> <span id="red-ui-editor-type-buffer-type-string" data-i18n="bufferEditor.modeString"></span><span id="red-ui-editor-type-buffer-type-array" data-i18n="bufferEditor.modeArray"></span></button></div><div class="form-row node-text-editor-row"><div class="node-text-editor" id="red-ui-editor-type-buffer-str"></div></div></div><div id="red-ui-editor-type-buffer-panel-bin" class="red-ui-panel"><div class="form-row node-text-editor-row" style="margin-top: 10px; margin-bottom:0;"><div class="node-text-editor" id="red-ui-editor-type-buffer-bin"></div></div></div></div></script>';
|
||||||
|
|
||||||
function stringToUTF8Array(str) {
|
function stringToUTF8Array(str) {
|
||||||
var data = [];
|
var data = [];
|
||||||
@ -187,8 +187,7 @@
|
|||||||
|
|
||||||
$(".red-ui-editor-type-buffer-type").on("click", function(e) {
|
$(".red-ui-editor-type-buffer-type").on("click", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
RED.sidebar.info.set(RED._("bufferEditor.modeDesc"));
|
RED.sidebar.help.set(RED._("bufferEditor.modeDesc"));
|
||||||
RED.sidebar.info.show();
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,8 +237,7 @@
|
|||||||
var changeTimer;
|
var changeTimer;
|
||||||
$(".red-ui-editor-type-expression-legacy").on("click", function(e) {
|
$(".red-ui-editor-type-expression-legacy").on("click", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
RED.sidebar.info.set(RED._("expressionEditor.compatModeDesc"));
|
RED.sidebar.help.set(RED._("expressionEditor.compatModeDesc"));
|
||||||
RED.sidebar.info.show();
|
|
||||||
})
|
})
|
||||||
var testExpression = function() {
|
var testExpression = function() {
|
||||||
var value = testDataEditor.getValue();
|
var value = testDataEditor.getValue();
|
||||||
@ -318,9 +317,9 @@
|
|||||||
var p2 = $("#red-ui-editor-type-expression-panel-info > .form-row > div:first-child");
|
var p2 = $("#red-ui-editor-type-expression-panel-info > .form-row > div:first-child");
|
||||||
p2Height -= p2.outerHeight(true) + 20;
|
p2Height -= p2.outerHeight(true) + 20;
|
||||||
$(".red-ui-editor-type-expression-tab-content").height(p2Height);
|
$(".red-ui-editor-type-expression-tab-content").height(p2Height);
|
||||||
$("#red-ui-editor-type-expression-test-data").css("height",(p2Height-5)+"px");
|
$("#red-ui-editor-type-expression-test-data").css("height",(p2Height-25)+"px");
|
||||||
testDataEditor.resize();
|
testDataEditor.resize();
|
||||||
$("#red-ui-editor-type-expression-test-result").css("height",(p2Height-5)+"px");
|
$("#red-ui-editor-type-expression-test-result").css("height",(p2Height-25)+"px");
|
||||||
testResultEditor.resize();
|
testResultEditor.resize();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -87,6 +87,9 @@
|
|||||||
expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
|
expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
|
||||||
}
|
}
|
||||||
dialogForm.i18n();
|
dialogForm.i18n();
|
||||||
|
setTimeout(function() {
|
||||||
|
expressionEditor.focus();
|
||||||
|
},300);
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
expressionEditor.destroy();
|
expressionEditor.destroy();
|
||||||
|
679
packages/node_modules/@node-red/editor-client/src/js/ui/group.js
vendored
Normal file
679
packages/node_modules/@node-red/editor-client/src/js/ui/group.js
vendored
Normal file
@ -0,0 +1,679 @@
|
|||||||
|
/**
|
||||||
|
* 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.group = (function() {
|
||||||
|
|
||||||
|
var _groupEditTemplate = '<script type="text/x-red" data-template-name="group">'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+
|
||||||
|
'<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">'+
|
||||||
|
'</div>'+
|
||||||
|
|
||||||
|
// '<div class="node-input-group-style-tools"><span class="button-group"><button class="red-ui-button red-ui-button-small">Use default style</button><button class="red-ui-button red-ui-button-small">Set as default style</button></span></div>'+
|
||||||
|
|
||||||
|
'<div class="form-row" id="node-input-row-style-stroke">'+
|
||||||
|
'<label data-i18n="editor:common.label.style"></label>'+
|
||||||
|
'<label style="width: 70px;margin-right:10px" for="node-input-style-stroke" data-i18n="editor:common.label.line"></label>'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row" style="padding-left: 100px;" id="node-input-row-style-fill">'+
|
||||||
|
'<label style="width: 70px;margin-right: 10px " for="node-input-style-fill" data-i18n="editor:common.label.fill"></label>'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="node-input-style-label" data-i18n="editor:common.label.label"></label>'+
|
||||||
|
'<input type="checkbox" id="node-input-style-label"/>'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row" id="node-input-row-style-label-options">'+
|
||||||
|
'<div style="margin-left: 100px; display: inline-block">'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<span style="display: inline-block; min-width: 140px" id="node-input-row-style-label-color">'+
|
||||||
|
'<label style="width: 70px;margin-right: 10px" for="node-input-style-fill" data-i18n="editor:common.label.color"></label>'+
|
||||||
|
'</span>'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<span style="display: inline-block; min-width: 140px;" id="node-input-row-style-label-position">'+
|
||||||
|
'<label style="width: 70px;margin-right: 10px " for="node-input-style-label-position" data-i18n="editor:common.label.position"></label>'+
|
||||||
|
'</span>'+
|
||||||
|
'</div>'+
|
||||||
|
'</div>'+
|
||||||
|
'</div>'+
|
||||||
|
|
||||||
|
'</script>';
|
||||||
|
|
||||||
|
var colorPalette = [
|
||||||
|
"#ff0000",
|
||||||
|
"#ffC000",
|
||||||
|
"#ffff00",
|
||||||
|
"#92d04f",
|
||||||
|
"#0070c0",
|
||||||
|
"#001f60",
|
||||||
|
"#6f2fa0",
|
||||||
|
"#000000",
|
||||||
|
"#777777"
|
||||||
|
]
|
||||||
|
var colorSteps = 3;
|
||||||
|
var colorCount = colorPalette.length;
|
||||||
|
for (var i=0,len=colorPalette.length*colorSteps;i<len;i++) {
|
||||||
|
var ci = i%colorCount;
|
||||||
|
var j = Math.floor(i/colorCount)+1;
|
||||||
|
var c = colorPalette[ci];
|
||||||
|
var r = parseInt(c.substring(1, 3), 16);
|
||||||
|
var g = parseInt(c.substring(3, 5), 16);
|
||||||
|
var b = parseInt(c.substring(5, 7), 16);
|
||||||
|
var dr = (255-r)/(colorSteps+((ci===colorCount-1) ?0:1));
|
||||||
|
var dg = (255-g)/(colorSteps+((ci===colorCount-1) ?0:1));
|
||||||
|
var db = (255-b)/(colorSteps+((ci===colorCount-1) ?0:1));
|
||||||
|
r = Math.min(255,Math.floor(r+j*dr));
|
||||||
|
g = Math.min(255,Math.floor(g+j*dg));
|
||||||
|
b = Math.min(255,Math.floor(b+j*db));
|
||||||
|
var s = ((r<<16) + (g<<8) + b).toString(16);
|
||||||
|
colorPalette.push('#'+'000000'.slice(0, 6-s.length)+s);
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultGroupStyle = {
|
||||||
|
label: true
|
||||||
|
};
|
||||||
|
|
||||||
|
var groupDef = {
|
||||||
|
defaults:{
|
||||||
|
name:{value:""},
|
||||||
|
style:{value:{label:true}},
|
||||||
|
nodes:{value:[]}
|
||||||
|
},
|
||||||
|
category: "config",
|
||||||
|
oneditprepare: function() {
|
||||||
|
var style = this.style || {};
|
||||||
|
RED.colorPicker.create({
|
||||||
|
id:"node-input-style-stroke",
|
||||||
|
value: style.stroke || "#a4a4a4",
|
||||||
|
palette: colorPalette,
|
||||||
|
cellPerRow: colorCount,
|
||||||
|
cellWidth: 16,
|
||||||
|
cellHeight: 16,
|
||||||
|
cellMargin: 3,
|
||||||
|
none: true,
|
||||||
|
opacity: style['stroke-opacity'] || 1.0
|
||||||
|
}).appendTo("#node-input-row-style-stroke");
|
||||||
|
RED.colorPicker.create({
|
||||||
|
id:"node-input-style-fill",
|
||||||
|
value: style.fill || "none",
|
||||||
|
palette: colorPalette,
|
||||||
|
cellPerRow: colorCount,
|
||||||
|
cellWidth: 16,
|
||||||
|
cellHeight: 16,
|
||||||
|
cellMargin: 3,
|
||||||
|
none: true,
|
||||||
|
opacity: style['fill-opacity'] || 1.0
|
||||||
|
}).appendTo("#node-input-row-style-fill");
|
||||||
|
|
||||||
|
createLayoutPicker({
|
||||||
|
id:"node-input-style-label-position",
|
||||||
|
value:style["label-position"] || "nw"
|
||||||
|
}).appendTo("#node-input-row-style-label-position");
|
||||||
|
|
||||||
|
RED.colorPicker.create({
|
||||||
|
id:"node-input-style-color",
|
||||||
|
value: style.color || "#a4a4a4",
|
||||||
|
palette: colorPalette,
|
||||||
|
cellPerRow: colorCount,
|
||||||
|
cellWidth: 16,
|
||||||
|
cellHeight: 16,
|
||||||
|
cellMargin: 3
|
||||||
|
}).appendTo("#node-input-row-style-label-color");
|
||||||
|
|
||||||
|
$("#node-input-style-label").toggleButton({
|
||||||
|
enabledLabel: RED._("editor.show"),
|
||||||
|
disabledLabel: RED._("editor.show"),
|
||||||
|
})
|
||||||
|
|
||||||
|
$("#node-input-style-label").on("change", function(evt) {
|
||||||
|
$("#node-input-row-style-label-options").toggle($(this).prop("checked"));
|
||||||
|
})
|
||||||
|
$("#node-input-style-label").prop("checked", this.style.label)
|
||||||
|
$("#node-input-style-label").trigger("change");
|
||||||
|
|
||||||
|
},
|
||||||
|
oneditresize: function(size) {
|
||||||
|
},
|
||||||
|
oneditsave: function() {
|
||||||
|
this.style.stroke = $("#node-input-style-stroke").val();
|
||||||
|
this.style.fill = $("#node-input-style-fill").val();
|
||||||
|
this.style["stroke-opacity"] = $("#node-input-style-stroke-opacity").val();
|
||||||
|
this.style["fill-opacity"] = $("#node-input-style-fill-opacity").val();
|
||||||
|
this.style.label = $("#node-input-style-label").prop("checked");
|
||||||
|
if (this.style.label) {
|
||||||
|
this.style["label-position"] = $("#node-input-style-label-position").val();
|
||||||
|
this.style.color = $("#node-input-style-color").val();
|
||||||
|
} else {
|
||||||
|
delete this.style["label-position"];
|
||||||
|
delete this.style.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.style["stroke-opacity"] === "1") {
|
||||||
|
delete this.style["stroke-opacity"]
|
||||||
|
}
|
||||||
|
if (this.style["fill-opacity"] === "1") {
|
||||||
|
delete this.style["fill-opacity"]
|
||||||
|
}
|
||||||
|
this.resize = true;
|
||||||
|
},
|
||||||
|
set:{
|
||||||
|
module: "node-red"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
|
||||||
|
RED.events.on("view:selection-changed",function(selection) {
|
||||||
|
var activateGroup = !!selection.nodes;
|
||||||
|
var activateUngroup = false;
|
||||||
|
var activateMerge = false;
|
||||||
|
var activateRemove = false;
|
||||||
|
if (activateGroup) {
|
||||||
|
selection.nodes.forEach(function (n) {
|
||||||
|
if (n.type === "group") {
|
||||||
|
activateUngroup = true;
|
||||||
|
}
|
||||||
|
if (!!n.g) {
|
||||||
|
activateRemove = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (activateUngroup) {
|
||||||
|
activateMerge = (selection.nodes.length > 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RED.menu.setDisabled("menu-item-group-group", !activateGroup);
|
||||||
|
RED.menu.setDisabled("menu-item-group-ungroup", !activateUngroup);
|
||||||
|
RED.menu.setDisabled("menu-item-group-merge", !activateMerge);
|
||||||
|
RED.menu.setDisabled("menu-item-group-remove", !activateRemove);
|
||||||
|
});
|
||||||
|
|
||||||
|
RED.actions.add("core:group-selection", function() { groupSelection() })
|
||||||
|
RED.actions.add("core:ungroup-selection", function() { ungroupSelection() })
|
||||||
|
RED.actions.add("core:merge-selection-to-group", function() { mergeSelection() })
|
||||||
|
RED.actions.add("core:remove-selection-from-group", function() { removeSelection() })
|
||||||
|
RED.actions.add("core:copy-group-style", function() { copyGroupStyle() });
|
||||||
|
RED.actions.add("core:paste-group-style", function() { pasteGroupStyle() });
|
||||||
|
|
||||||
|
$(_groupEditTemplate).appendTo("#red-ui-editor-node-configs");
|
||||||
|
|
||||||
|
var groupStyleDiv = $("<div>",{
|
||||||
|
class:"red-ui-flow-group-body",
|
||||||
|
style: "position: absolute; top: -1000px;"
|
||||||
|
}).appendTo(document.body);
|
||||||
|
var groupStyle = getComputedStyle(groupStyleDiv[0]);
|
||||||
|
defaultGroupStyle = {
|
||||||
|
stroke: convertColorToHex(groupStyle.stroke),
|
||||||
|
"stroke-opacity": groupStyle.strokeOpacity,
|
||||||
|
fill: convertColorToHex(groupStyle.fill),
|
||||||
|
"fill-opacity": groupStyle.fillOpacity,
|
||||||
|
label: true
|
||||||
|
}
|
||||||
|
groupStyleDiv.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertColorToHex(c) {
|
||||||
|
var m = /^rgb\((\d+), (\d+), (\d+)\)$/.exec(c);
|
||||||
|
if (m) {
|
||||||
|
var s = ((parseInt(m[1])<<16) + (parseInt(m[2])<<8) + parseInt(m[3])).toString(16)
|
||||||
|
return '#'+'000000'.slice(0, 6-s.length)+s;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var groupStyleClipboard;
|
||||||
|
|
||||||
|
function copyGroupStyle() {
|
||||||
|
var selection = RED.view.selection();
|
||||||
|
if (selection.nodes && selection.nodes.length === 1 && selection.nodes[0].type === 'group') {
|
||||||
|
groupStyleClipboard = JSON.parse(JSON.stringify(selection.nodes[0].style));
|
||||||
|
RED.notify(RED._("clipboard.groupStyleCopied"),{id:"clipboard"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function pasteGroupStyle() {
|
||||||
|
if (groupStyleClipboard) {
|
||||||
|
var selection = RED.view.selection();
|
||||||
|
if (selection.nodes) {
|
||||||
|
var historyEvent = {
|
||||||
|
t:'multi',
|
||||||
|
events:[],
|
||||||
|
dirty: RED.nodes.dirty()
|
||||||
|
}
|
||||||
|
selection.nodes.forEach(function(n) {
|
||||||
|
if (n.type === 'group') {
|
||||||
|
historyEvent.events.push({
|
||||||
|
t: "edit",
|
||||||
|
node: n,
|
||||||
|
changes: {
|
||||||
|
style: JSON.parse(JSON.stringify(n.style))
|
||||||
|
},
|
||||||
|
dirty: RED.nodes.dirty()
|
||||||
|
});
|
||||||
|
n.style = JSON.parse(JSON.stringify(groupStyleClipboard));
|
||||||
|
n.dirty = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (historyEvent.events.length > 0) {
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
RED.view.redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function groupSelection() {
|
||||||
|
var selection = RED.view.selection();
|
||||||
|
if (selection.nodes) {
|
||||||
|
var group = createGroup(selection.nodes);
|
||||||
|
if (group) {
|
||||||
|
var historyEvent = {
|
||||||
|
t:"createGroup",
|
||||||
|
groups: [ group ],
|
||||||
|
dirty: RED.nodes.dirty()
|
||||||
|
}
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
RED.view.select({nodes:[group]});
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function ungroupSelection() {
|
||||||
|
var selection = RED.view.selection();
|
||||||
|
if (selection.nodes) {
|
||||||
|
var newSelection = [];
|
||||||
|
groups = selection.nodes.filter(function(n) { return n.type === "group" });
|
||||||
|
|
||||||
|
var historyEvent = {
|
||||||
|
t:"ungroup",
|
||||||
|
groups: [ ],
|
||||||
|
dirty: RED.nodes.dirty()
|
||||||
|
}
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
|
||||||
|
|
||||||
|
groups.forEach(function(g) {
|
||||||
|
newSelection = newSelection.concat(ungroup(g))
|
||||||
|
historyEvent.groups.push(g);
|
||||||
|
})
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
RED.view.select({nodes:newSelection})
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ungroup(g) {
|
||||||
|
var nodes = [];
|
||||||
|
var parentGroup = RED.nodes.group(g.g);
|
||||||
|
g.nodes.forEach(function(n) {
|
||||||
|
nodes.push(n);
|
||||||
|
if (parentGroup) {
|
||||||
|
// Move nodes to parent group
|
||||||
|
n.g = parentGroup.id;
|
||||||
|
parentGroup.nodes.push(n);
|
||||||
|
parentGroup.dirty = true;
|
||||||
|
n.dirty = true;
|
||||||
|
} else {
|
||||||
|
delete n.g;
|
||||||
|
}
|
||||||
|
if (n.type === 'group') {
|
||||||
|
RED.events.emit("groups:change",n)
|
||||||
|
} else {
|
||||||
|
RED.events.emit("nodes:change",n)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
RED.nodes.removeGroup(g);
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeSelection() {
|
||||||
|
// TODO: this currently creates an entirely new group. Need to merge properties
|
||||||
|
// of any existing group
|
||||||
|
var selection = RED.view.selection();
|
||||||
|
if (selection.nodes) {
|
||||||
|
var nodes = [];
|
||||||
|
|
||||||
|
var historyEvent = {
|
||||||
|
t: "multi",
|
||||||
|
events: []
|
||||||
|
}
|
||||||
|
var ungroupHistoryEvent = {
|
||||||
|
t: "ungroup",
|
||||||
|
groups: []
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var n;
|
||||||
|
var parentGroup;
|
||||||
|
// First pass, check they are all in the same parent
|
||||||
|
// TODO: DRY mergeSelection,removeSelection,...
|
||||||
|
for (var i=0; i<selection.nodes.length; i++) {
|
||||||
|
n = selection.nodes[i];
|
||||||
|
if (i === 0) {
|
||||||
|
parentGroup = n.g;
|
||||||
|
} else if (n.g !== parentGroup) {
|
||||||
|
RED.notify(RED._("group.errors.cannotCreateDiffGroups"),"error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Second pass, ungroup any groups in the selection and add their contents
|
||||||
|
// to the selection
|
||||||
|
for (var i=0; i<selection.nodes.length; i++) {
|
||||||
|
n = selection.nodes[i];
|
||||||
|
if (n.type === "group") {
|
||||||
|
ungroupHistoryEvent.groups.push(n);
|
||||||
|
nodes = nodes.concat(ungroup(n));
|
||||||
|
} else {
|
||||||
|
nodes.push(n);
|
||||||
|
}
|
||||||
|
n.dirty = true;
|
||||||
|
}
|
||||||
|
if (ungroupHistoryEvent.groups.length > 0) {
|
||||||
|
historyEvent.events.push(ungroupHistoryEvent);
|
||||||
|
}
|
||||||
|
// Finally, create the new group
|
||||||
|
var group = createGroup(nodes);
|
||||||
|
if (group) {
|
||||||
|
RED.view.select({nodes:[group]})
|
||||||
|
}
|
||||||
|
historyEvent.events.push({
|
||||||
|
t:"createGroup",
|
||||||
|
groups: [ group ],
|
||||||
|
dirty: RED.nodes.dirty()
|
||||||
|
});
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeSelection() {
|
||||||
|
var selection = RED.view.selection();
|
||||||
|
if (selection.nodes) {
|
||||||
|
var nodes = [];
|
||||||
|
var n;
|
||||||
|
var parentGroup = RED.nodes.group(selection.nodes[0].g);
|
||||||
|
if (parentGroup) {
|
||||||
|
try {
|
||||||
|
removeFromGroup(parentGroup,selection.nodes,true);
|
||||||
|
var historyEvent = {
|
||||||
|
t: "removeFromGroup",
|
||||||
|
dirty: RED.nodes.dirty(),
|
||||||
|
group: parentGroup,
|
||||||
|
nodes: selection.nodes
|
||||||
|
}
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
} catch(err) {
|
||||||
|
RED.notify(err,"error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RED.view.select({nodes:selection.nodes})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function createGroup(nodes) {
|
||||||
|
if (nodes.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nodes.filter(function(n) { return n.type === "subflow" }).length > 0) {
|
||||||
|
RED.notify(RED._("group.errors.cannotAddSubflowPorts"),"error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// nodes is an array
|
||||||
|
// each node must be on the same tab (z)
|
||||||
|
var group = {
|
||||||
|
id: RED.nodes.id(),
|
||||||
|
type: 'group',
|
||||||
|
nodes: [],
|
||||||
|
style: JSON.parse(JSON.stringify(defaultGroupStyle)),
|
||||||
|
x: Number.POSITIVE_INFINITY,
|
||||||
|
y: Number.POSITIVE_INFINITY,
|
||||||
|
w: 0,
|
||||||
|
h: 0,
|
||||||
|
_def: RED.group.def
|
||||||
|
}
|
||||||
|
|
||||||
|
group.z = nodes[0].z;
|
||||||
|
RED.nodes.addGroup(group);
|
||||||
|
|
||||||
|
try {
|
||||||
|
addToGroup(group,nodes);
|
||||||
|
} catch(err) {
|
||||||
|
RED.notify(err,"error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
function addToGroup(group,nodes) {
|
||||||
|
if (!Array.isArray(nodes)) {
|
||||||
|
nodes = [nodes];
|
||||||
|
}
|
||||||
|
var i,n,z;
|
||||||
|
var g;
|
||||||
|
// First pass - validate we can safely add these nodes to the group
|
||||||
|
for (i=0;i<nodes.length;i++) {
|
||||||
|
n = nodes[i]
|
||||||
|
if (!n.z) {
|
||||||
|
throw new Error("Cannot add node without a z property to a group")
|
||||||
|
}
|
||||||
|
if (!z) {
|
||||||
|
z = n.z;
|
||||||
|
} else if (z !== n.z) {
|
||||||
|
throw new Error("Cannot add nooes with different z properties")
|
||||||
|
}
|
||||||
|
if (n.g) {
|
||||||
|
// This is already in a group.
|
||||||
|
// - check they are all in the same group
|
||||||
|
if (!g) {
|
||||||
|
if (i!==0) {
|
||||||
|
// TODO: this might be ok when merging groups
|
||||||
|
throw new Error(RED._("group.errors.cannotCreateDiffGroups"))
|
||||||
|
}
|
||||||
|
g = n.g
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (g !== n.g) {
|
||||||
|
throw new Error(RED._("group.errors.cannotCreateDiffGroups"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The nodes are already in a group. The assumption is they should be
|
||||||
|
// wrapped in the newly provided group, and that group added to in their
|
||||||
|
// place to the existing containing group.
|
||||||
|
if (g) {
|
||||||
|
g = RED.nodes.group(g);
|
||||||
|
g.nodes.push(group);
|
||||||
|
g.dirty = true;
|
||||||
|
group.g = g.id;
|
||||||
|
}
|
||||||
|
// Second pass - add them to the group
|
||||||
|
for (i=0;i<nodes.length;i++) {
|
||||||
|
n = nodes[i];
|
||||||
|
if (n.type !== "subflow") {
|
||||||
|
if (g && n.g === g.id) {
|
||||||
|
var ni = g.nodes.indexOf(n);
|
||||||
|
if (ni > -1) {
|
||||||
|
g.nodes.splice(ni,1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n.g = group.id;
|
||||||
|
n.dirty = true;
|
||||||
|
group.nodes.push(n);
|
||||||
|
group.x = Math.min(group.x,n.x-n.w/2-25-((n._def.button && n._def.align!=="right")?20:0));
|
||||||
|
group.y = Math.min(group.y,n.y-n.h/2-25);
|
||||||
|
group.w = Math.max(group.w,n.x+n.w/2+25+((n._def.button && n._def.align=="right")?20:0) - group.x);
|
||||||
|
group.h = Math.max(group.h,n.y+n.h/2+25-group.y);
|
||||||
|
if (n.type === 'group') {
|
||||||
|
RED.events.emit("groups:change",n)
|
||||||
|
} else {
|
||||||
|
RED.events.emit("nodes:change",n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (g) {
|
||||||
|
RED.events.emit("groups:change",group)
|
||||||
|
}
|
||||||
|
markDirty(group);
|
||||||
|
}
|
||||||
|
function removeFromGroup(group, nodes, reparent) {
|
||||||
|
if (!Array.isArray(nodes)) {
|
||||||
|
nodes = [nodes];
|
||||||
|
}
|
||||||
|
var n;
|
||||||
|
// First pass, check they are all in the same parent
|
||||||
|
// TODO: DRY mergeSelection,removeSelection,...
|
||||||
|
for (var i=0; i<nodes.length; i++) {
|
||||||
|
if (nodes[i].g !== group.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var parentGroup = RED.nodes.group(group.g);
|
||||||
|
for (var i=0; i<nodes.length; i++) {
|
||||||
|
n = nodes[i];
|
||||||
|
n.dirty = true;
|
||||||
|
var index = group.nodes.indexOf(n);
|
||||||
|
group.nodes.splice(index,1);
|
||||||
|
if (reparent && group.g) {
|
||||||
|
n.g = group.g
|
||||||
|
parentGroup.nodes.push(n);
|
||||||
|
} else {
|
||||||
|
delete n.g;
|
||||||
|
}
|
||||||
|
if (n.type === 'group') {
|
||||||
|
RED.events.emit("groups:change",n)
|
||||||
|
} else {
|
||||||
|
RED.events.emit("nodes:change",n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
markDirty(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNodes(group,recursive) {
|
||||||
|
var nodes = [];
|
||||||
|
group.nodes.forEach(function(n) {
|
||||||
|
nodes.push(n);
|
||||||
|
if (recursive && n.type === 'group') {
|
||||||
|
nodes = nodes.concat(getNodes(n,recursive))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function groupContains(group,item) {
|
||||||
|
if (item.g === group.id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (var i=0;i<group.nodes.length;i++) {
|
||||||
|
if (group.nodes[i].type === "group") {
|
||||||
|
if (groupContains(group.nodes[i],item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function getRootGroup(group) {
|
||||||
|
if (!group.g) {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
return getRootGroup(RED.nodes.group(group.g))
|
||||||
|
}
|
||||||
|
|
||||||
|
function createLayoutPicker(options) {
|
||||||
|
|
||||||
|
var container = $("<div>",{style:"display:inline-block"});
|
||||||
|
var layoutHiddenInput = $("<input/>", { id: options.id, type: "hidden", value: options.value }).appendTo(container);
|
||||||
|
|
||||||
|
var layoutButton = $('<button type="button" class="red-ui-button red-ui-editor-node-appearance-button">').appendTo(container);
|
||||||
|
$('<i class="fa fa-caret-down"></i>').appendTo(layoutButton);
|
||||||
|
|
||||||
|
var layoutDispContainer = $('<div>',{class:"red-ui-search-result-node"}).appendTo(layoutButton);
|
||||||
|
var layoutDisp = $('<div>',{class:"red-ui-group-layout-picker-cell-text red-ui-group-layout-text-pos-"}).appendTo(layoutDispContainer);
|
||||||
|
|
||||||
|
var refreshDisplay = function() {
|
||||||
|
var val = layoutHiddenInput.val();
|
||||||
|
layoutDisp.removeClass().addClass("red-ui-group-layout-picker-cell-text red-ui-group-layout-text-pos-"+val)
|
||||||
|
}
|
||||||
|
layoutButton.on("click", function(e) {
|
||||||
|
var picker = $("<div/>", {
|
||||||
|
class: "red-ui-group-layout-picker"
|
||||||
|
}).css({
|
||||||
|
width: "126px"
|
||||||
|
});
|
||||||
|
|
||||||
|
var row = null;
|
||||||
|
|
||||||
|
row = $("<div/>").appendTo(picker);
|
||||||
|
var currentButton;
|
||||||
|
for (var y=0;y<2;y++) { //red-ui-group-layout-text-pos
|
||||||
|
var yComponent= "ns"[y];
|
||||||
|
row = $("<div/>").appendTo(picker);
|
||||||
|
for (var x=0;x<3;x++) {
|
||||||
|
var xComponent = ["w","","e"][x];
|
||||||
|
var val = yComponent+xComponent;
|
||||||
|
var button = $("<button/>", { class:"red-ui-search-result-node red-ui-button","data-pos":val }).appendTo(row);
|
||||||
|
button.on("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
layoutHiddenInput.val($(this).data("pos"));
|
||||||
|
layoutPanel.hide()
|
||||||
|
refreshDisplay();
|
||||||
|
});
|
||||||
|
$('<div>',{class:"red-ui-group-layout-picker-cell-text red-ui-group-layout-text-pos-"+val}).appendTo(button);
|
||||||
|
if (val === layoutHiddenInput.val()) {
|
||||||
|
currentButton = button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
refreshDisplay();
|
||||||
|
var layoutPanel = RED.popover.panel(picker);
|
||||||
|
layoutPanel.show({
|
||||||
|
target: layoutButton,
|
||||||
|
onclose: function() {
|
||||||
|
layoutButton.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (currentButton) {
|
||||||
|
currentButton.focus();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
refreshDisplay();
|
||||||
|
|
||||||
|
return container;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function markDirty(group) {
|
||||||
|
group.dirty = true;
|
||||||
|
while(group) {
|
||||||
|
group.dirty = true;
|
||||||
|
group = RED.nodes.group(group.g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
def: groupDef,
|
||||||
|
init: init,
|
||||||
|
createGroup: createGroup,
|
||||||
|
ungroup: ungroup,
|
||||||
|
addToGroup: addToGroup,
|
||||||
|
removeFromGroup: removeFromGroup,
|
||||||
|
getNodes: getNodes,
|
||||||
|
contains: groupContains,
|
||||||
|
markDirty: markDirty
|
||||||
|
}
|
||||||
|
})();
|
@ -22,7 +22,7 @@ RED.library = (function() {
|
|||||||
|
|
||||||
var _libraryLookup = '<div id="red-ui-library-dialog-load" class="hide">'+
|
var _libraryLookup = '<div id="red-ui-library-dialog-load" class="hide">'+
|
||||||
'<form class="form-horizontal">'+
|
'<form class="form-horizontal">'+
|
||||||
'<div style="height: 400px; position:relative; ">'+
|
'<div class="red-ui-library-dialog-box" style="height: 400px; position:relative; ">'+
|
||||||
'<div id="red-ui-library-dialog-load-panes">'+
|
'<div id="red-ui-library-dialog-load-panes">'+
|
||||||
'<div class="red-ui-panel" id="red-ui-library-dialog-load-browser"></div>'+
|
'<div class="red-ui-panel" id="red-ui-library-dialog-load-browser"></div>'+
|
||||||
'<div class="red-ui-panel">'+
|
'<div class="red-ui-panel">'+
|
||||||
@ -41,7 +41,7 @@ RED.library = (function() {
|
|||||||
|
|
||||||
var _librarySave = '<div id="red-ui-library-dialog-save" class="hide">'+
|
var _librarySave = '<div id="red-ui-library-dialog-save" class="hide">'+
|
||||||
'<form class="form-horizontal">'+
|
'<form class="form-horizontal">'+
|
||||||
'<div style="height: 400px; position:relative; ">'+
|
'<div class="red-ui-library-dialog-box" style="height: 400px; position:relative; ">'+
|
||||||
'<div id="red-ui-library-dialog-save-browser"></div>'+
|
'<div id="red-ui-library-dialog-save-browser"></div>'+
|
||||||
'<div class="form-row">'+
|
'<div class="form-row">'+
|
||||||
'<label data-i18n="clipboard.export.exportAs"></label><input id="red-ui-library-dialog-save-filename" type="text">'+
|
'<label data-i18n="clipboard.export.exportAs"></label><input id="red-ui-library-dialog-save-filename" type="text">'+
|
||||||
@ -64,12 +64,14 @@ RED.library = (function() {
|
|||||||
|
|
||||||
var queryArgs = [];
|
var queryArgs = [];
|
||||||
var data = {};
|
var data = {};
|
||||||
for (var i=0; i<activeLibrary.fields.length; i++) {
|
for (var i=0; i < activeLibrary.fields.length; i++) {
|
||||||
var field = activeLibrary.fields[i];
|
var field = activeLibrary.fields[i];
|
||||||
if (field == "name") {
|
if (field === "name") {
|
||||||
data.name = name;
|
data.name = name;
|
||||||
|
} else if (typeof(field) === 'object') {
|
||||||
|
data[field.name] = field.get();
|
||||||
} else {
|
} else {
|
||||||
data[field] = $("#"+elementPrefix+field).val();
|
data[field] = $("#" + elementPrefix + field).val();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.text = activeLibrary.editor.getValue();
|
data.text = activeLibrary.editor.getValue();
|
||||||
@ -254,6 +256,13 @@ RED.library = (function() {
|
|||||||
libraryEditor.renderer.$cursorLayer.element.style.opacity=0;
|
libraryEditor.renderer.$cursorLayer.element.style.opacity=0;
|
||||||
libraryEditor.$blockScrolling = Infinity;
|
libraryEditor.$blockScrolling = Infinity;
|
||||||
|
|
||||||
|
var dialogHeight = 400;
|
||||||
|
var winHeight = $(window).height();
|
||||||
|
if (winHeight < 570) {
|
||||||
|
dialogHeight = 400 - (570 - winHeight);
|
||||||
|
}
|
||||||
|
$("#red-ui-library-dialog-load .red-ui-library-dialog-box").height(dialogHeight);
|
||||||
|
|
||||||
$( "#red-ui-library-dialog-load" ).dialog("option","title",RED._("library.typeLibrary", {type:options.type})).dialog( "open" );
|
$( "#red-ui-library-dialog-load" ).dialog("option","title",RED._("library.typeLibrary", {type:options.type})).dialog( "open" );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -293,6 +302,15 @@ RED.library = (function() {
|
|||||||
saveLibraryBrowser.select(listing[0].children[0]);
|
saveLibraryBrowser.select(listing[0].children[0]);
|
||||||
},200);
|
},200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var dialogHeight = 400;
|
||||||
|
var winHeight = $(window).height();
|
||||||
|
if (winHeight < 570) {
|
||||||
|
dialogHeight = 400 - (570 - winHeight);
|
||||||
|
}
|
||||||
|
$("#red-ui-library-dialog-save .red-ui-library-dialog-box").height(dialogHeight);
|
||||||
|
|
||||||
|
|
||||||
$( "#red-ui-library-dialog-save" ).dialog( "open" );
|
$( "#red-ui-library-dialog-save" ).dialog( "open" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,14 +536,20 @@ RED.library = (function() {
|
|||||||
{
|
{
|
||||||
text: RED._("common.label.load"),
|
text: RED._("common.label.load"),
|
||||||
class: "primary",
|
class: "primary",
|
||||||
click: function() {
|
click: function () {
|
||||||
if (selectedLibraryItem) {
|
if (selectedLibraryItem) {
|
||||||
var elementPrefix = activeLibrary.elementPrefix || "node-input-";
|
var elementPrefix = activeLibrary.elementPrefix || "node-input-";
|
||||||
for (var i=0; i<activeLibrary.fields.length; i++) {
|
for (var i = 0; i < activeLibrary.fields.length; i++) {
|
||||||
var field = activeLibrary.fields[i];
|
var field = activeLibrary.fields[i];
|
||||||
$("#"+elementPrefix+field).val(selectedLibraryItem[field]);
|
if (typeof(field) === 'object') {
|
||||||
|
var val = selectedLibraryItem[field.name];
|
||||||
|
field.set(val);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#"+elementPrefix+field).val(selectedLibraryItem[field]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
activeLibrary.editor.setValue(libraryEditor.getValue(),-1);
|
activeLibrary.editor.setValue(libraryEditor.getValue(), -1);
|
||||||
}
|
}
|
||||||
$( this ).dialog( "close" );
|
$( this ).dialog( "close" );
|
||||||
}
|
}
|
||||||
|
@ -75,13 +75,16 @@ RED.palette.editor = (function() {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function installNodeModule(id,version,callback) {
|
function installNodeModule(id,version,url,callback) {
|
||||||
var requestBody = {
|
var requestBody = {
|
||||||
module: id
|
module: id
|
||||||
};
|
};
|
||||||
if (version) {
|
if (version) {
|
||||||
requestBody.version = version;
|
requestBody.version = version;
|
||||||
}
|
}
|
||||||
|
if (url) {
|
||||||
|
requestBody.url = url;
|
||||||
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url:"nodes",
|
url:"nodes",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
@ -627,7 +630,7 @@ RED.palette.editor = (function() {
|
|||||||
if ($(this).hasClass('disabled')) {
|
if ($(this).hasClass('disabled')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
update(entry,loadedIndex[entry.name].version,container,function(err){});
|
update(entry,loadedIndex[entry.name].version,loadedIndex[entry.name].pkg_url,container,function(err){});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -877,7 +880,7 @@ RED.palette.editor = (function() {
|
|||||||
|
|
||||||
$('<div id="red-ui-palette-module-install-shade" class="red-ui-palette-module-shade hide"><div class="red-ui-palette-module-shade-status"></div><img src="red/images/spin.svg" class="red-ui-palette-spinner"/></div>').appendTo(installTab);
|
$('<div id="red-ui-palette-module-install-shade" class="red-ui-palette-module-shade hide"><div class="red-ui-palette-module-shade-status"></div><img src="red/images/spin.svg" class="red-ui-palette-spinner"/></div>').appendTo(installTab);
|
||||||
}
|
}
|
||||||
function update(entry,version,container,done) {
|
function update(entry,version,url,container,done) {
|
||||||
if (RED.settings.theme('palette.editable') === false) {
|
if (RED.settings.theme('palette.editable') === false) {
|
||||||
done(new Error('Palette not editable'));
|
done(new Error('Palette not editable'));
|
||||||
return;
|
return;
|
||||||
@ -903,7 +906,7 @@ RED.palette.editor = (function() {
|
|||||||
RED.actions.invoke("core:show-event-log");
|
RED.actions.invoke("core:show-event-log");
|
||||||
});
|
});
|
||||||
RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.name+" "+version);
|
RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.name+" "+version);
|
||||||
installNodeModule(entry.name,version,function(xhr) {
|
installNodeModule(entry.name,version,url,function(xhr) {
|
||||||
spinner.remove();
|
spinner.remove();
|
||||||
if (xhr) {
|
if (xhr) {
|
||||||
if (xhr.responseJSON) {
|
if (xhr.responseJSON) {
|
||||||
@ -1028,7 +1031,7 @@ RED.palette.editor = (function() {
|
|||||||
RED.actions.invoke("core:show-event-log");
|
RED.actions.invoke("core:show-event-log");
|
||||||
});
|
});
|
||||||
RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.id+" "+entry.version);
|
RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.id+" "+entry.version);
|
||||||
installNodeModule(entry.id,entry.version,function(xhr) {
|
installNodeModule(entry.id,entry.version,entry.pkg_url,function(xhr) {
|
||||||
spinner.remove();
|
spinner.remove();
|
||||||
if (xhr) {
|
if (xhr) {
|
||||||
if (xhr.responseJSON) {
|
if (xhr.responseJSON) {
|
||||||
|
@ -105,7 +105,7 @@ RED.palette = (function() {
|
|||||||
for (var i=0;i<words.length;i++) {
|
for (var i=0;i<words.length;i++) {
|
||||||
var word = words[i];
|
var word = words[i];
|
||||||
var sep = (i == 0) ? "" : " ";
|
var sep = (i == 0) ? "" : " ";
|
||||||
var newWidth = RED.view.calculateTextWidth(currentLine+sep+word, "red-ui-palette-label", 0);
|
var newWidth = RED.view.calculateTextWidth(currentLine+sep+word, "red-ui-palette-label");
|
||||||
if (newWidth < nodeWidth) {
|
if (newWidth < nodeWidth) {
|
||||||
currentLine += sep +word;
|
currentLine += sep +word;
|
||||||
} else {
|
} else {
|
||||||
@ -113,12 +113,12 @@ RED.palette = (function() {
|
|||||||
displayLines.push(currentLine);
|
displayLines.push(currentLine);
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
var wordWidth = RED.view.calculateTextWidth(word, "red-ui-palette-label", 0);
|
var wordWidth = RED.view.calculateTextWidth(word, "red-ui-palette-label");
|
||||||
if (wordWidth >= nodeWidth) {
|
if (wordWidth >= nodeWidth) {
|
||||||
// break word if too wide
|
// break word if too wide
|
||||||
for(var j = word.length; j > 0; j--) {
|
for(var j = word.length; j > 0; j--) {
|
||||||
var s = word.substring(0, j);
|
var s = word.substring(0, j);
|
||||||
var width = RED.view.calculateTextWidth(s, "red-ui-palette-label", 0);
|
var width = RED.view.calculateTextWidth(s, "red-ui-palette-label");
|
||||||
if (width < nodeWidth) {
|
if (width < nodeWidth) {
|
||||||
displayLines.push(s);
|
displayLines.push(s);
|
||||||
word = word.substring(j);
|
word = word.substring(j);
|
||||||
@ -165,6 +165,7 @@ RED.palette = (function() {
|
|||||||
metaData = typeInfo.set.module+" : ";
|
metaData = typeInfo.set.module+" : ";
|
||||||
}
|
}
|
||||||
metaData += type;
|
metaData += type;
|
||||||
|
$('<button type="button" onclick="RED.sidebar.help.show(\''+type+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right"><i class="fa fa-book"></i></button>').appendTo(popOverContent)
|
||||||
$('<p>',{style:"font-size: 0.8em"}).text(metaData).appendTo(popOverContent);
|
$('<p>',{style:"font-size: 0.8em"}).text(metaData).appendTo(popOverContent);
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@ -181,7 +182,11 @@ RED.palette = (function() {
|
|||||||
function setIcon(element,sf) {
|
function setIcon(element,sf) {
|
||||||
var icon_url = RED.utils.getNodeIcon(sf._def);
|
var icon_url = RED.utils.getNodeIcon(sf._def);
|
||||||
var iconContainer = element.find(".red-ui-palette-icon-container");
|
var iconContainer = element.find(".red-ui-palette-icon-container");
|
||||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
var currentIcon = iconContainer.attr("data-palette-icon");
|
||||||
|
if (currentIcon !== icon_url) {
|
||||||
|
iconContainer.attr("data-palette-icon", icon_url);
|
||||||
|
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPaletteNode(type) {
|
function getPaletteNode(type) {
|
||||||
@ -224,6 +229,7 @@ RED.palette = (function() {
|
|||||||
var iconContainer = $('<div/>', {
|
var iconContainer = $('<div/>', {
|
||||||
class: "red-ui-palette-icon-container"+(((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-icon-container-right" : "")
|
class: "red-ui-palette-icon-container"+(((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-icon-container-right" : "")
|
||||||
}).appendTo(d);
|
}).appendTo(d);
|
||||||
|
iconContainer.attr("data-palette-icon", icon_url);
|
||||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +256,7 @@ RED.palette = (function() {
|
|||||||
var popover = RED.popover.create({
|
var popover = RED.popover.create({
|
||||||
target:d,
|
target:d,
|
||||||
trigger: "hover",
|
trigger: "hover",
|
||||||
|
interactive: true,
|
||||||
width: "300px",
|
width: "300px",
|
||||||
content: "hi",
|
content: "hi",
|
||||||
delay: { show: 750, hide: 50 }
|
delay: { show: 750, hide: 50 }
|
||||||
@ -265,25 +272,28 @@ RED.palette = (function() {
|
|||||||
// html: true,
|
// html: true,
|
||||||
// container:'body'
|
// container:'body'
|
||||||
// });
|
// });
|
||||||
d.on("click", function() {
|
// d.on("click", function() {
|
||||||
RED.view.focus();
|
// RED.view.focus();
|
||||||
var helpText;
|
// var helpText;
|
||||||
if (nt.indexOf("subflow:") === 0) {
|
// if (nt.indexOf("subflow:") === 0) {
|
||||||
helpText = RED.utils.renderMarkdown(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
// helpText = RED.utils.renderMarkdown(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||||
} else {
|
// } else {
|
||||||
helpText = $("script[data-help-name='"+d.attr("data-palette-type")+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
// helpText = $("script[data-help-name='"+d.attr("data-palette-type")+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||||
}
|
// }
|
||||||
// Don't look too closely. RED.sidebar.info.set will set the 'Description'
|
// // Don't look too closely. RED.sidebar.info.set will set the 'Description'
|
||||||
// section of the sidebar. Pass in the title of the Help section so it looks
|
// // section of the sidebar. Pass in the title of the Help section so it looks
|
||||||
// right.
|
// // right.
|
||||||
RED.sidebar.info.set(helpText,RED._("sidebar.info.nodeHelp"));
|
// RED.sidebar.type.show(helpText,RED._("sidebar.info.nodeHelp"));
|
||||||
});
|
// });
|
||||||
var chart = $("#red-ui-workspace-chart");
|
var chart = $("#red-ui-workspace-chart");
|
||||||
var chartSVG = $("#red-ui-workspace-chart>svg").get(0);
|
var chartSVG = $("#red-ui-workspace-chart>svg").get(0);
|
||||||
var activeSpliceLink;
|
var activeSpliceLink;
|
||||||
var mouseX;
|
var mouseX;
|
||||||
var mouseY;
|
var mouseY;
|
||||||
var spliceTimer;
|
var spliceTimer;
|
||||||
|
var groupTimer;
|
||||||
|
var activeGroup;
|
||||||
|
var hoverGroup;
|
||||||
var paletteWidth;
|
var paletteWidth;
|
||||||
var paletteTop;
|
var paletteTop;
|
||||||
$(d).draggable({
|
$(d).draggable({
|
||||||
@ -295,16 +305,53 @@ RED.palette = (function() {
|
|||||||
start: function() {
|
start: function() {
|
||||||
paletteWidth = $("#red-ui-palette").width();
|
paletteWidth = $("#red-ui-palette").width();
|
||||||
paletteTop = $("#red-ui-palette").parent().position().top + $("#red-ui-palette-container").position().top;
|
paletteTop = $("#red-ui-palette").parent().position().top + $("#red-ui-palette-container").position().top;
|
||||||
|
hoverGroup = null;
|
||||||
|
activeGroup = RED.view.getActiveGroup();
|
||||||
|
if (activeGroup) {
|
||||||
|
document.getElementById("group_select_"+activeGroup.id).classList.add("red-ui-flow-group-active-hovered");
|
||||||
|
}
|
||||||
RED.view.focus();
|
RED.view.focus();
|
||||||
},
|
},
|
||||||
stop: function() { d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false); if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null;}},
|
stop: function() {
|
||||||
|
d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false);
|
||||||
|
if (hoverGroup) {
|
||||||
|
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
|
||||||
|
}
|
||||||
|
if (activeGroup) {
|
||||||
|
document.getElementById("group_select_"+activeGroup.id).classList.remove("red-ui-flow-group-active-hovered");
|
||||||
|
}
|
||||||
|
if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null; }
|
||||||
|
if (groupTimer) { clearTimeout(groupTimer); groupTimer = null; }
|
||||||
|
},
|
||||||
drag: function(e,ui) {
|
drag: function(e,ui) {
|
||||||
var paletteNode = getPaletteNode(nt);
|
var paletteNode = getPaletteNode(nt);
|
||||||
ui.originalPosition.left = paletteNode.offset().left;
|
ui.originalPosition.left = paletteNode.offset().left;
|
||||||
|
mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
|
||||||
|
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop();
|
||||||
|
if (!groupTimer) {
|
||||||
|
groupTimer = setTimeout(function() {
|
||||||
|
mouseX /= RED.view.scale();
|
||||||
|
mouseY /= RED.view.scale();
|
||||||
|
var group = RED.view.getGroupAtPoint(mouseX,mouseY);
|
||||||
|
if (group !== hoverGroup) {
|
||||||
|
if (hoverGroup) {
|
||||||
|
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
|
||||||
|
}
|
||||||
|
if (group) {
|
||||||
|
document.getElementById("group_select_"+group.id).classList.add("red-ui-flow-group-hovered");
|
||||||
|
}
|
||||||
|
hoverGroup = group;
|
||||||
|
if (hoverGroup) {
|
||||||
|
$(ui.helper).data('group',hoverGroup);
|
||||||
|
} else {
|
||||||
|
$(ui.helper).removeData('group');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groupTimer = null;
|
||||||
|
|
||||||
|
},200)
|
||||||
|
}
|
||||||
if (def.inputs > 0 && def.outputs > 0) {
|
if (def.inputs > 0 && def.outputs > 0) {
|
||||||
mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
|
|
||||||
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop();
|
|
||||||
if (!spliceTimer) {
|
if (!spliceTimer) {
|
||||||
spliceTimer = setTimeout(function() {
|
spliceTimer = setTimeout(function() {
|
||||||
var nodes = [];
|
var nodes = [];
|
||||||
@ -412,61 +459,67 @@ RED.palette = (function() {
|
|||||||
categoryNode.show();
|
categoryNode.show();
|
||||||
paletteNode.show();
|
paletteNode.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshNodeTypes() {
|
function refreshNodeTypes() {
|
||||||
RED.nodes.eachSubflow(function(sf) {
|
RED.nodes.eachSubflow(refreshSubflow)
|
||||||
var paletteNode = getPaletteNode('subflow:'+sf.id);
|
}
|
||||||
var portInput = paletteNode.find(".red-ui-palette-port-input");
|
function refreshSubflow(sf) {
|
||||||
var portOutput = paletteNode.find(".red-ui-palette-port-output");
|
var paletteNode = getPaletteNode('subflow:'+sf.id);
|
||||||
|
var portInput = paletteNode.find(".red-ui-palette-port-input");
|
||||||
|
var portOutput = paletteNode.find(".red-ui-palette-port-output");
|
||||||
|
|
||||||
var paletteLabel = paletteNode.find(".red-ui-palette-label");
|
var paletteLabel = paletteNode.find(".red-ui-palette-label");
|
||||||
paletteLabel.attr("class","red-ui-palette-label" + (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-label-right" : ""));
|
paletteLabel.attr("class","red-ui-palette-label" + (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-label-right" : ""));
|
||||||
|
|
||||||
var paletteIconContainer = paletteNode.find(".red-ui-palette-icon-container");
|
var paletteIconContainer = paletteNode.find(".red-ui-palette-icon-container");
|
||||||
paletteIconContainer.attr("class","red-ui-palette-icon-container" + (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-icon-container-right" : ""));
|
paletteIconContainer.attr("class","red-ui-palette-icon-container" + (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-icon-container-right" : ""));
|
||||||
|
|
||||||
if (portInput.length === 0 && sf.in.length > 0) {
|
if (portInput.length === 0 && sf.in.length > 0) {
|
||||||
var portIn = document.createElement("div");
|
var portIn = document.createElement("div");
|
||||||
portIn.className = "red-ui-palette-port red-ui-palette-port-input";
|
portIn.className = "red-ui-palette-port red-ui-palette-port-input";
|
||||||
paletteNode.append(portIn);
|
paletteNode.append(portIn);
|
||||||
} else if (portInput.length !== 0 && sf.in.length === 0) {
|
} else if (portInput.length !== 0 && sf.in.length === 0) {
|
||||||
portInput.remove();
|
portInput.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (portOutput.length === 0 && sf.out.length > 0) {
|
if (portOutput.length === 0 && sf.out.length > 0) {
|
||||||
var portOut = document.createElement("div");
|
var portOut = document.createElement("div");
|
||||||
portOut.className = "red-ui-palette-port red-ui-palette-port-output";
|
portOut.className = "red-ui-palette-port red-ui-palette-port-output";
|
||||||
paletteNode.append(portOut);
|
paletteNode.append(portOut);
|
||||||
} else if (portOutput.length !== 0 && sf.out.length === 0) {
|
} else if (portOutput.length !== 0 && sf.out.length === 0) {
|
||||||
portOutput.remove();
|
portOutput.remove();
|
||||||
}
|
}
|
||||||
|
var currentLabel = paletteNode.attr("data-palette-label");
|
||||||
|
var currentInfo = paletteNode.attr("data-palette-info");
|
||||||
|
|
||||||
|
if (currentLabel !== sf.name || currentInfo !== sf.info) {
|
||||||
|
paletteNode.attr("data-palette-info",sf.info);
|
||||||
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,RED.utils.renderMarkdown(sf.info||""));
|
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,RED.utils.renderMarkdown(sf.info||""));
|
||||||
setIcon(paletteNode,sf);
|
}
|
||||||
|
setIcon(paletteNode,sf);
|
||||||
|
|
||||||
var currentCategory = paletteNode.data('category');
|
var currentCategory = paletteNode.data('category');
|
||||||
var newCategory = (sf.category||"subflows");
|
var newCategory = (sf.category||"subflows");
|
||||||
if (currentCategory !== newCategory) {
|
if (currentCategory !== newCategory) {
|
||||||
var category = escapeCategory(newCategory);
|
var category = escapeCategory(newCategory);
|
||||||
createCategory(newCategory,category,category,"node-red");
|
createCategory(newCategory,category,category,"node-red");
|
||||||
|
|
||||||
var currentCategoryNode = paletteNode.closest(".red-ui-palette-category");
|
var currentCategoryNode = paletteNode.closest(".red-ui-palette-category");
|
||||||
var newCategoryNode = $("#red-ui-palette-"+category);
|
var newCategoryNode = $("#red-ui-palette-"+category);
|
||||||
newCategoryNode.append(paletteNode);
|
newCategoryNode.append(paletteNode);
|
||||||
if (newCategoryNode.find(".red-ui-palette-node").length === 1) {
|
if (newCategoryNode.find(".red-ui-palette-node").length === 1) {
|
||||||
categoryContainers[category].open();
|
categoryContainers[category].open();
|
||||||
}
|
|
||||||
|
|
||||||
paletteNode.data('category',newCategory);
|
|
||||||
if (currentCategoryNode.find(".red-ui-palette-node").length === 0) {
|
|
||||||
if (currentCategoryNode.find("i").hasClass("expanded")) {
|
|
||||||
currentCategoryNode.find(".red-ui-palette-content").slideToggle();
|
|
||||||
currentCategoryNode.find("i").toggleClass("expanded");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
paletteNode.css("backgroundColor", sf.color);
|
paletteNode.data('category',newCategory);
|
||||||
});
|
if (currentCategoryNode.find(".red-ui-palette-node").length === 0) {
|
||||||
|
if (currentCategoryNode.find("i").hasClass("expanded")) {
|
||||||
|
currentCategoryNode.find(".red-ui-palette-content").slideToggle();
|
||||||
|
currentCategoryNode.find("i").toggleClass("expanded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paletteNode.css("backgroundColor", sf.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterChange(val) {
|
function filterChange(val) {
|
||||||
@ -504,6 +557,8 @@ RED.palette = (function() {
|
|||||||
$('<div class="red-ui-component-footer"></div>').appendTo("#red-ui-palette");
|
$('<div class="red-ui-component-footer"></div>').appendTo("#red-ui-palette");
|
||||||
$('<div id="red-ui-palette-shade" class="hide"></div>').appendTo("#red-ui-palette");
|
$('<div id="red-ui-palette-shade" class="hide"></div>').appendTo("#red-ui-palette");
|
||||||
|
|
||||||
|
$("#red-ui-palette > .red-ui-palette-spinner").show();
|
||||||
|
|
||||||
|
|
||||||
RED.events.on('registry:node-type-added', function(nodeType) {
|
RED.events.on('registry:node-type-added', function(nodeType) {
|
||||||
var def = RED.nodes.getType(nodeType);
|
var def = RED.nodes.getType(nodeType);
|
||||||
@ -545,7 +600,8 @@ RED.palette = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#red-ui-palette > .red-ui-palette-spinner").show();
|
RED.events.on("subflows:change",refreshSubflow);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$("#red-ui-palette-search input").searchBox({
|
$("#red-ui-palette-search input").searchBox({
|
||||||
|
@ -685,6 +685,8 @@ RED.projects = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},projectData).then(function() {
|
},projectData).then(function() {
|
||||||
|
RED.menu.setDisabled('menu-item-projects-open',false);
|
||||||
|
RED.menu.setDisabled('menu-item-projects-settings',false);
|
||||||
RED.events.emit("project:change", {name:name});
|
RED.events.emit("project:change", {name:name});
|
||||||
}).always(function() {
|
}).always(function() {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
@ -1495,7 +1497,6 @@ RED.projects = (function() {
|
|||||||
}
|
}
|
||||||
} else if (projectType === 'open') {
|
} else if (projectType === 'open') {
|
||||||
return switchProject(selectedProject.name,function(err,data) {
|
return switchProject(selectedProject.name,function(err,data) {
|
||||||
dialog.dialog( "close" );
|
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.code !== 'credentials_load_failed') {
|
if (err.code !== 'credentials_load_failed') {
|
||||||
console.log(RED._("projects.create.unexpected_error"),err)
|
console.log(RED._("projects.create.unexpected_error"),err)
|
||||||
@ -1604,6 +1605,7 @@ RED.projects = (function() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},{active:true}).then(function() {
|
},{active:true}).then(function() {
|
||||||
|
dialog.dialog( "close" );
|
||||||
RED.events.emit("project:change", {name:name});
|
RED.events.emit("project:change", {name:name});
|
||||||
}).always(function() {
|
}).always(function() {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
@ -1613,25 +1615,16 @@ RED.projects = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deleteProject(row,name,done) {
|
function deleteProject(row,name,done) {
|
||||||
var cover = $('<div>').css({
|
var cover = $('<div class="red-ui-projects-dialog-project-list-entry-delete-confirm"></div>').on("click", function(evt) { evt.stopPropagation(); }).appendTo(row);
|
||||||
background:"white",
|
$('<span>').text(RED._("projects.delete.confirm")).appendTo(cover);
|
||||||
position:"absolute",
|
$('<button class="red-ui-button">'+RED._("common.label.cancel")+'</button>')
|
||||||
top:0,right:0,bottom:0,left:"100%",
|
|
||||||
overflow:"hidden",
|
|
||||||
padding: "5px 20px",
|
|
||||||
transition: "left 0.4s",
|
|
||||||
whitespace: "nowrap",
|
|
||||||
width:"1000px"
|
|
||||||
}).on("click", function(evt) { evt.stopPropagation(); }).appendTo(row);
|
|
||||||
$('<span>').css({"lineHeight":"40px"}).text(RED._("projects.delete.confirm")).appendTo(cover);
|
|
||||||
$('<button style="margin-left:20px" class="red-ui-button">'+RED._("common.label.cancel")+'</button>')
|
|
||||||
.appendTo(cover)
|
.appendTo(cover)
|
||||||
.on("click", function(e) {
|
.on("click", function(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
cover.remove();
|
cover.remove();
|
||||||
done(true);
|
done(true);
|
||||||
});
|
});
|
||||||
$('<button style="margin-left:20px" class="red-ui-button primary">'+RED._("common.label.delete")+'</button>')
|
$('<button class="red-ui-button primary">'+RED._("common.label.delete")+'</button>')
|
||||||
.appendTo(cover)
|
.appendTo(cover)
|
||||||
.on("click", function(e) {
|
.on("click", function(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -1671,16 +1664,27 @@ RED.projects = (function() {
|
|||||||
if (typeof buttons === 'function') {
|
if (typeof buttons === 'function') {
|
||||||
buttons = buttons(options||{});
|
buttons = buttons(options||{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dialog.dialog('option','buttons',buttons);
|
dialog.dialog('option','buttons',buttons);
|
||||||
dialogBody.append(container);
|
dialogBody.append(container);
|
||||||
|
|
||||||
|
|
||||||
|
var dialogHeight = 590;
|
||||||
|
var winHeight = $(window).height();
|
||||||
|
if (winHeight < 750) {
|
||||||
|
dialogHeight = 590 - (750 - winHeight);
|
||||||
|
}
|
||||||
|
$(".red-ui-projects-dialog-box").height(dialogHeight);
|
||||||
|
$(".red-ui-projects-dialog-project-list-inner-container").height(Math.max(500,dialogHeight) - 180);
|
||||||
dialog.dialog('option','title',screen.title||"");
|
dialog.dialog('option','title',screen.title||"");
|
||||||
dialog.dialog("open");
|
dialog.dialog("open");
|
||||||
dialog.dialog({position: { 'my': 'center top', 'at': 'center top+20', 'of': window }});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createProjectList(options) {
|
function createProjectList(options) {
|
||||||
options = options||{};
|
options = options||{};
|
||||||
var height = options.height || "300px";
|
var height = options.height || "200px";
|
||||||
var container = $('<div></div>',{class:"red-ui-projects-dialog-project-list-container" });
|
var container = $('<div></div>',{class:"red-ui-projects-dialog-project-list-container" });
|
||||||
var filterTerm = "";
|
var filterTerm = "";
|
||||||
|
|
||||||
@ -2252,7 +2256,7 @@ RED.projects = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
dialog = $('<div id="red-ui-projects-dialog" class="hide red-ui-projects-edit-form"><form class="form-horizontal"></form><div class="red-ui-component-spinner hide"><img src="red/images/spin.svg"/></div></div>')
|
dialog = $('<div id="red-ui-projects-dialog" class="hide red-ui-projects-edit-form"><div class="red-ui-projects-dialog-box"><form class="form-horizontal"></form><div class="red-ui-component-spinner hide"><img src="red/images/spin.svg"/></div></div></div>')
|
||||||
.appendTo("#red-ui-editor")
|
.appendTo("#red-ui-editor")
|
||||||
.dialog({
|
.dialog({
|
||||||
modal: true,
|
modal: true,
|
||||||
@ -2339,6 +2343,7 @@ RED.projects = (function() {
|
|||||||
if (data.active) {
|
if (data.active) {
|
||||||
$.getJSON("projects/"+data.active, function(project) {
|
$.getJSON("projects/"+data.active, function(project) {
|
||||||
activeProject = project;
|
activeProject = project;
|
||||||
|
RED.events.emit("projects:load",activeProject);
|
||||||
RED.sidebar.versionControl.refresh(true);
|
RED.sidebar.versionControl.refresh(true);
|
||||||
if (done) {
|
if (done) {
|
||||||
done(activeProject);
|
done(activeProject);
|
||||||
|
@ -23,11 +23,9 @@ RED.search = (function() {
|
|||||||
var visible = false;
|
var visible = false;
|
||||||
|
|
||||||
var index = {};
|
var index = {};
|
||||||
var keys = [];
|
var currentResults = [];
|
||||||
var results = [];
|
|
||||||
var previousActiveElement;
|
var previousActiveElement;
|
||||||
|
|
||||||
|
|
||||||
function indexProperty(node,label,property) {
|
function indexProperty(node,label,property) {
|
||||||
if (typeof property === 'string' || typeof property === 'number') {
|
if (typeof property === 'string' || typeof property === 'number') {
|
||||||
property = (""+property).toLowerCase();
|
property = (""+property).toLowerCase();
|
||||||
@ -61,53 +59,110 @@ RED.search = (function() {
|
|||||||
}
|
}
|
||||||
for (var i=0;i<properties.length;i++) {
|
for (var i=0;i<properties.length;i++) {
|
||||||
if (n.hasOwnProperty(properties[i])) {
|
if (n.hasOwnProperty(properties[i])) {
|
||||||
|
if (n.type === "group" && properties[i] === "nodes") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
indexProperty(n, l, n[properties[i]]);
|
indexProperty(n, l, n[properties[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function indexWorkspace() {
|
function extractFlag(val, flagName, flags) {
|
||||||
index = {};
|
// is:XYZ
|
||||||
RED.nodes.eachWorkspace(indexNode);
|
|
||||||
RED.nodes.eachSubflow(indexNode);
|
var regEx = new RegExp("(?:^| )is:"+flagName+"(?: |$)");
|
||||||
RED.nodes.eachConfig(indexNode);
|
var m = regEx.exec(val);
|
||||||
RED.nodes.eachNode(indexNode);
|
if (m) {
|
||||||
keys = Object.keys(index);
|
val = val.replace(regEx," ").trim();
|
||||||
keys.sort();
|
flags[flagName] = true;
|
||||||
keys.forEach(function(key) {
|
}
|
||||||
index[key] = Object.keys(index[key]).map(function(id) {
|
return val;
|
||||||
return index[key][id];
|
}
|
||||||
})
|
|
||||||
})
|
function extractValue(val, flagName, flags) {
|
||||||
|
// flagName:XYZ
|
||||||
|
var regEx = new RegExp("(?:^| )"+flagName+":([^ ]+)(?: |$)");
|
||||||
|
var m
|
||||||
|
while(!!(m = regEx.exec(val))) {
|
||||||
|
val = val.replace(regEx," ").trim();
|
||||||
|
flags[flagName] = flags[flagName] || [];
|
||||||
|
flags[flagName].push(m[1]);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(val) {
|
function search(val) {
|
||||||
searchResults.editableList('empty');
|
var results = [];
|
||||||
|
var keys = [];
|
||||||
var typeFilter;
|
var typeFilter;
|
||||||
var m = /(?:^| )type:([^ ]+)/.exec(val);
|
var m = /(?:^| )type:([^ ]+)/.exec(val);
|
||||||
if (m) {
|
if (m) {
|
||||||
val = val.replace(/(?:^| )type:[^ ]+/,"");
|
val = val.replace(/(?:^| )type:[^ ]+/,"");
|
||||||
typeFilter = m[1];
|
typeFilter = m[1];
|
||||||
}
|
}
|
||||||
|
var flags = {};
|
||||||
|
val = extractFlag(val,"invalid",flags);
|
||||||
|
val = extractFlag(val,"unused",flags);
|
||||||
|
val = extractFlag(val,"config",flags);
|
||||||
|
val = extractFlag(val,"subflow",flags);
|
||||||
|
// uses:<node-id>
|
||||||
|
val = extractValue(val,"uses",flags);
|
||||||
|
|
||||||
|
var hasFlags = Object.keys(flags).length > 0;
|
||||||
|
|
||||||
val = val.trim();
|
val = val.trim();
|
||||||
|
|
||||||
selected = -1;
|
if (val.length > 0 || typeFilter || hasFlags) {
|
||||||
results = [];
|
|
||||||
if (val.length > 0 || typeFilter) {
|
|
||||||
val = val.toLowerCase();
|
val = val.toLowerCase();
|
||||||
var i;
|
var i;
|
||||||
var j;
|
var j;
|
||||||
var list = [];
|
var list = [];
|
||||||
var nodes = {};
|
var nodes = {};
|
||||||
|
if (flags.uses) {
|
||||||
|
keys = flags.uses;
|
||||||
|
} else {
|
||||||
|
keys = Object.keys(index);
|
||||||
|
}
|
||||||
for (i=0;i<keys.length;i++) {
|
for (i=0;i<keys.length;i++) {
|
||||||
var key = keys[i];
|
var key = keys[i];
|
||||||
var kpos = keys[i].indexOf(val);
|
var kpos = keys[i].indexOf(val);
|
||||||
if (kpos > -1) {
|
if (kpos > -1) {
|
||||||
for (j=0;j<index[key].length;j++) {
|
var ids = Object.keys(index[key]);
|
||||||
var node = index[key][j];
|
for (j=0;j<ids.length;j++) {
|
||||||
|
var node = index[key][ids[j]];
|
||||||
|
var isConfigNode = node.node._def.category === "config" && node.node.type !== 'group';
|
||||||
|
if (flags.uses && key === node.node.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (flags.hasOwnProperty("invalid")) {
|
||||||
|
var nodeIsValid = !node.node.hasOwnProperty("valid") || node.node.valid;
|
||||||
|
if (flags.invalid === nodeIsValid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flags.hasOwnProperty("config")) {
|
||||||
|
if (flags.config !== isConfigNode) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flags.hasOwnProperty("subflow")) {
|
||||||
|
if (flags.subflow !== (node.node.type === 'subflow')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags.hasOwnProperty("unused")) {
|
||||||
|
var isUnused = (node.node.type === 'subflow' && node.node.instances.length === 0) ||
|
||||||
|
(isConfigNode && node.node.users.length === 0)
|
||||||
|
if (flags.unused !== isUnused) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!typeFilter || node.node.type === typeFilter) {
|
if (!typeFilter || node.node.type === typeFilter) {
|
||||||
nodes[node.node.id] = nodes[node.node.id] = node;
|
nodes[node.node.id] = nodes[node.node.id] = {
|
||||||
|
node: node.node,
|
||||||
|
label: node.label
|
||||||
|
};
|
||||||
nodes[node.node.id].index = Math.min(nodes[node.node.id].index||Infinity,kpos);
|
nodes[node.node.id].index = Math.min(nodes[node.node.id].index||Infinity,kpos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,22 +176,8 @@ RED.search = (function() {
|
|||||||
for (i=0;i<list.length;i++) {
|
for (i=0;i<list.length;i++) {
|
||||||
results.push(nodes[list[i]]);
|
results.push(nodes[list[i]]);
|
||||||
}
|
}
|
||||||
if (results.length > 0) {
|
|
||||||
for (i=0;i<Math.min(results.length,25);i++) {
|
|
||||||
searchResults.editableList('addItem',results[i])
|
|
||||||
}
|
|
||||||
if (results.length > 25) {
|
|
||||||
searchResults.editableList('addItem', {
|
|
||||||
more: {
|
|
||||||
results: results,
|
|
||||||
start: 25
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
searchResults.editableList('addItem',{});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureSelectedIsVisible() {
|
function ensureSelectedIsVisible() {
|
||||||
@ -161,13 +202,37 @@ RED.search = (function() {
|
|||||||
searchInput = $('<input type="text" data-i18n="[placeholder]menu.label.searchInput">').appendTo(searchDiv).searchBox({
|
searchInput = $('<input type="text" data-i18n="[placeholder]menu.label.searchInput">').appendTo(searchDiv).searchBox({
|
||||||
delay: 200,
|
delay: 200,
|
||||||
change: function() {
|
change: function() {
|
||||||
search($(this).val());
|
searchResults.editableList('empty');
|
||||||
|
selected = -1;
|
||||||
|
currentResults = search($(this).val());
|
||||||
|
if (currentResults.length > 0) {
|
||||||
|
for (i=0;i<Math.min(currentResults.length,25);i++) {
|
||||||
|
searchResults.editableList('addItem',currentResults[i])
|
||||||
|
}
|
||||||
|
if (currentResults.length > 25) {
|
||||||
|
searchResults.editableList('addItem', {
|
||||||
|
more: {
|
||||||
|
results: currentResults,
|
||||||
|
start: 25
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
searchResults.editableList('addItem',{});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
var copySearchContainer = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-caret-right"></button>').appendTo(searchDiv).on('click', function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
RED.sidebar.info.outliner.search(searchInput.val())
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
|
||||||
searchInput.on('keydown',function(evt) {
|
searchInput.on('keydown',function(evt) {
|
||||||
var children;
|
var children;
|
||||||
if (results.length > 0) {
|
if (currentResults.length > 0) {
|
||||||
if (evt.keyCode === 40) {
|
if (evt.keyCode === 40) {
|
||||||
// Down
|
// Down
|
||||||
children = searchResults.children();
|
children = searchResults.children();
|
||||||
@ -199,21 +264,21 @@ RED.search = (function() {
|
|||||||
var object = $(children[selected]).find(".red-ui-editableList-item-content").data('data');
|
var object = $(children[selected]).find(".red-ui-editableList-item-content").data('data');
|
||||||
if (object) {
|
if (object) {
|
||||||
searchResults.editableList('removeItem',object);
|
searchResults.editableList('removeItem',object);
|
||||||
for (i=object.more.start;i<Math.min(results.length,object.more.start+25);i++) {
|
for (i=object.more.start;i<Math.min(currentResults.length,object.more.start+25);i++) {
|
||||||
searchResults.editableList('addItem',results[i])
|
searchResults.editableList('addItem',currentResults[i])
|
||||||
}
|
}
|
||||||
if (results.length > object.more.start+25) {
|
if (currentResults.length > object.more.start+25) {
|
||||||
searchResults.editableList('addItem', {
|
searchResults.editableList('addItem', {
|
||||||
more: {
|
more: {
|
||||||
results: results,
|
results: currentResults,
|
||||||
start: object.more.start+25
|
start: object.more.start+25
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (results.length > 0) {
|
if (currentResults.length > 0) {
|
||||||
reveal(results[Math.max(0,selected)].node);
|
reveal(currentResults[Math.max(0,selected)].node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,13 +299,13 @@ RED.search = (function() {
|
|||||||
div.on("click", function(evt) {
|
div.on("click", function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
searchResults.editableList('removeItem',object);
|
searchResults.editableList('removeItem',object);
|
||||||
for (i=object.more.start;i<Math.min(results.length,object.more.start+25);i++) {
|
for (i=object.more.start;i<Math.min(currentResults.length,object.more.start+25);i++) {
|
||||||
searchResults.editableList('addItem',results[i])
|
searchResults.editableList('addItem',currentResults[i])
|
||||||
}
|
}
|
||||||
if (results.length > object.more.start+25) {
|
if (currentResults.length > object.more.start+25) {
|
||||||
searchResults.editableList('addItem', {
|
searchResults.editableList('addItem', {
|
||||||
more: {
|
more: {
|
||||||
results: results,
|
results: currentResults,
|
||||||
start: object.more.start+25
|
start: object.more.start+25
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -253,17 +318,7 @@ RED.search = (function() {
|
|||||||
var def = node._def;
|
var def = node._def;
|
||||||
div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container);
|
div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container);
|
||||||
|
|
||||||
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div);
|
RED.utils.createNodeIcon(node).appendTo(div);
|
||||||
var colour = RED.utils.getNodeColor(node.type,def);
|
|
||||||
var icon_url = RED.utils.getNodeIcon(def,node);
|
|
||||||
if (node.type === 'tab') {
|
|
||||||
colour = "#C0DEED";
|
|
||||||
}
|
|
||||||
nodeDiv.css('backgroundColor',colour);
|
|
||||||
|
|
||||||
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
|
||||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
|
||||||
|
|
||||||
var contentDiv = $('<div>',{class:"red-ui-search-result-node-description"}).appendTo(div);
|
var contentDiv = $('<div>',{class:"red-ui-search-result-node-description"}).appendTo(div);
|
||||||
if (node.z) {
|
if (node.z) {
|
||||||
var workspace = RED.nodes.workspace(node.z);
|
var workspace = RED.nodes.workspace(node.z);
|
||||||
@ -308,7 +363,7 @@ RED.search = (function() {
|
|||||||
$("#red-ui-palette-shade").show();
|
$("#red-ui-palette-shade").show();
|
||||||
$("#red-ui-sidebar-shade").show();
|
$("#red-ui-sidebar-shade").show();
|
||||||
$("#red-ui-sidebar-separator").hide();
|
$("#red-ui-sidebar-separator").hide();
|
||||||
indexWorkspace();
|
|
||||||
if (dialog === null) {
|
if (dialog === null) {
|
||||||
createDialog();
|
createDialog();
|
||||||
}
|
}
|
||||||
@ -342,6 +397,28 @@ RED.search = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearIndex() {
|
||||||
|
index = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function addItemToIndex(item) {
|
||||||
|
indexNode(item);
|
||||||
|
}
|
||||||
|
function removeItemFromIndex(item) {
|
||||||
|
var keys = Object.keys(index);
|
||||||
|
for (var i=0,l=keys.length;i<l;i++) {
|
||||||
|
delete index[keys[i]][item.id];
|
||||||
|
if (Object.keys(index[keys[i]]).length === 0) {
|
||||||
|
delete index[keys[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function updateItemOnIndex(item) {
|
||||||
|
removeItemFromIndex(item);
|
||||||
|
addItemToIndex(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
RED.actions.add("core:search",show);
|
RED.actions.add("core:search",show);
|
||||||
|
|
||||||
@ -358,12 +435,33 @@ RED.search = (function() {
|
|||||||
$("#red-ui-editor-shade").on('mousedown',hide);
|
$("#red-ui-editor-shade").on('mousedown',hide);
|
||||||
$("#red-ui-palette-shade").on('mousedown',hide);
|
$("#red-ui-palette-shade").on('mousedown',hide);
|
||||||
$("#red-ui-sidebar-shade").on('mousedown',hide);
|
$("#red-ui-sidebar-shade").on('mousedown',hide);
|
||||||
|
|
||||||
|
|
||||||
|
RED.events.on("workspace:clear", clearIndex);
|
||||||
|
|
||||||
|
RED.events.on("flows:add", addItemToIndex);
|
||||||
|
RED.events.on("flows:remove", removeItemFromIndex);
|
||||||
|
RED.events.on("flows:change", updateItemOnIndex);
|
||||||
|
|
||||||
|
RED.events.on("subflows:add", addItemToIndex);
|
||||||
|
RED.events.on("subflows:remove", removeItemFromIndex);
|
||||||
|
RED.events.on("subflows:change", updateItemOnIndex);
|
||||||
|
|
||||||
|
RED.events.on("nodes:add",addItemToIndex);
|
||||||
|
RED.events.on("nodes:remove",removeItemFromIndex);
|
||||||
|
RED.events.on("nodes:change",updateItemOnIndex);
|
||||||
|
|
||||||
|
RED.events.on("groups:add",addItemToIndex);
|
||||||
|
RED.events.on("groups:remove",removeItemFromIndex);
|
||||||
|
RED.events.on("groups:change",updateItemOnIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
show: show,
|
show: show,
|
||||||
hide: hide
|
hide: hide,
|
||||||
|
search: search
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -250,6 +250,7 @@ RED.sidebar = (function() {
|
|||||||
RED.popover.tooltip($("#red-ui-sidebar-separator").find(".red-ui-sidebar-control-right"),RED._("keyboard.toggleSidebar"),"core:toggle-sidebar");
|
RED.popover.tooltip($("#red-ui-sidebar-separator").find(".red-ui-sidebar-control-right"),RED._("keyboard.toggleSidebar"),"core:toggle-sidebar");
|
||||||
showSidebar();
|
showSidebar();
|
||||||
RED.sidebar.info.init();
|
RED.sidebar.info.init();
|
||||||
|
RED.sidebar.help.init();
|
||||||
RED.sidebar.config.init();
|
RED.sidebar.config.init();
|
||||||
RED.sidebar.context.init();
|
RED.sidebar.context.init();
|
||||||
// hide info bar at start if screen rather narrow...
|
// hide info bar at start if screen rather narrow...
|
||||||
|
@ -25,5 +25,7 @@ RED.state = {
|
|||||||
IMPORT_DRAGGING: 8,
|
IMPORT_DRAGGING: 8,
|
||||||
QUICK_JOINING: 9,
|
QUICK_JOINING: 9,
|
||||||
PANNING: 10,
|
PANNING: 10,
|
||||||
SELECTING_NODE: 11
|
SELECTING_NODE: 11,
|
||||||
|
GROUP_DRAGGING: 12,
|
||||||
|
GROUP_RESIZE: 13
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
334
packages/node_modules/@node-red/editor-client/src/js/ui/tab-help.js
vendored
Normal file
334
packages/node_modules/@node-red/editor-client/src/js/ui/tab-help.js
vendored
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
/**
|
||||||
|
* 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.sidebar.help = (function() {
|
||||||
|
|
||||||
|
var content;
|
||||||
|
var toolbar;
|
||||||
|
var helpSection;
|
||||||
|
var panels;
|
||||||
|
var panelRatio;
|
||||||
|
var helpTopics = [];
|
||||||
|
var treeList;
|
||||||
|
var tocPanel;
|
||||||
|
var helpIndex = {};
|
||||||
|
|
||||||
|
|
||||||
|
function resizeStack() {
|
||||||
|
var h = $(content).parent().height() - toolbar.outerHeight();
|
||||||
|
panels.resize(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
|
||||||
|
content = document.createElement("div");
|
||||||
|
content.className = "red-ui-sidebar-info"
|
||||||
|
|
||||||
|
toolbar = $("<div>", {class:"red-ui-sidebar-header red-ui-info-toolbar"}).appendTo(content);
|
||||||
|
$('<span class="button-group"><a id="red-ui-sidebar-help-show-toc" class="red-ui-button red-ui-button-small selected" href="#"><i class="fa fa-list-ul"></i></a></span>').appendTo(toolbar)
|
||||||
|
var showTOCButton = toolbar.find('#red-ui-sidebar-help-show-toc')
|
||||||
|
RED.popover.tooltip(showTOCButton,RED._("sidebar.help.showTopics"));
|
||||||
|
showTOCButton.on("click",function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if ($(this).hasClass('selected')) {
|
||||||
|
hideTOC();
|
||||||
|
} else {
|
||||||
|
showTOC();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var stackContainer = $("<div>",{class:"red-ui-sidebar-help-stack"}).appendTo(content);
|
||||||
|
|
||||||
|
tocPanel = $("<div>", {class: "red-ui-sidebar-help-toc"}).appendTo(stackContainer);
|
||||||
|
var helpPanel = $("<div>").css({
|
||||||
|
"overflow-y": "scroll"
|
||||||
|
}).appendTo(stackContainer);
|
||||||
|
|
||||||
|
panels = RED.panels.create({
|
||||||
|
container: stackContainer
|
||||||
|
})
|
||||||
|
panels.ratio(0.3);
|
||||||
|
|
||||||
|
helpSearch = $('<input type="text" data-i18n="[placeholder]sidebar.help.search">').appendTo(toolbar).searchBox({
|
||||||
|
style: "compact",
|
||||||
|
delay: 100,
|
||||||
|
change: function() {
|
||||||
|
var val = $(this).val().toLowerCase();
|
||||||
|
if (val) {
|
||||||
|
showTOC();
|
||||||
|
var c = treeList.treeList('filter',function(item) {
|
||||||
|
if (item.depth === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (item.nodeType && item.nodeType.indexOf(val) > -1) ||
|
||||||
|
(item.subflowLabel && item.subflowLabel.indexOf(val) > -1)
|
||||||
|
},true)
|
||||||
|
} else {
|
||||||
|
treeList.treeList('filter',null);
|
||||||
|
var selected = treeList.treeList('selected');
|
||||||
|
if (selected.id) {
|
||||||
|
treeList.treeList('show',selected.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
helpSection = $("<div>",{class:"red-ui-help"}).css({
|
||||||
|
"padding":"6px",
|
||||||
|
}).appendTo(helpPanel)
|
||||||
|
|
||||||
|
$('<span class="red-ui-help-info-none">'+RED._("sidebar.help.noHelp")+'</span>').appendTo(helpSection);
|
||||||
|
|
||||||
|
treeList = $("<div>").css({width: "100%"}).appendTo(tocPanel).treeList({data: []})
|
||||||
|
treeList.on('treelistselect', function(e,item) {
|
||||||
|
if (item.nodeType) {
|
||||||
|
showHelp(item.nodeType);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
RED.sidebar.addTab({
|
||||||
|
id: "help",
|
||||||
|
label: RED._("sidebar.help.label"),
|
||||||
|
name: RED._("sidebar.help.name"),
|
||||||
|
iconClass: "fa fa-book",
|
||||||
|
action:"core:show-help-tab",
|
||||||
|
content: content,
|
||||||
|
pinned: true,
|
||||||
|
enableOnEdit: true,
|
||||||
|
onchange: function() {
|
||||||
|
resizeStack()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).on("resize", resizeStack);
|
||||||
|
$(window).on("focus", resizeStack);
|
||||||
|
|
||||||
|
RED.events.on('registry:node-type-added', queueRefresh);
|
||||||
|
RED.events.on('registry:node-type-removed', queueRefresh);
|
||||||
|
RED.events.on('subflows:change', refreshSubflow);
|
||||||
|
|
||||||
|
RED.actions.add("core:show-help-tab",show);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var refreshTimer;
|
||||||
|
function queueRefresh() {
|
||||||
|
if (!refreshTimer) {
|
||||||
|
refreshTimer = setTimeout(function() {
|
||||||
|
refreshTimer = null;
|
||||||
|
refreshHelpIndex();
|
||||||
|
},500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshSubflow(sf) {
|
||||||
|
var item = treeList.treeList('get',"node-type:subflow:"+sf.id);
|
||||||
|
item.subflowLabel = sf._def.label().toLowerCase();
|
||||||
|
item.treeList.replaceElement(getNodeLabel({_def:sf._def,type:sf._def.label()}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideTOC() {
|
||||||
|
var tocButton = $('#red-ui-sidebar-help-show-toc')
|
||||||
|
if (tocButton.hasClass('selected')) {
|
||||||
|
tocButton.removeClass('selected');
|
||||||
|
panelRatio = panels.ratio();
|
||||||
|
tocPanel.css({"transition":"height 0.2s"})
|
||||||
|
panels.ratio(0)
|
||||||
|
setTimeout(function() {
|
||||||
|
tocPanel.css({"transition":""})
|
||||||
|
},250);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function showTOC() {
|
||||||
|
var tocButton = $('#red-ui-sidebar-help-show-toc')
|
||||||
|
if (!tocButton.hasClass('selected')) {
|
||||||
|
tocButton.addClass('selected');
|
||||||
|
tocPanel.css({"transition":"height 0.2s"})
|
||||||
|
panels.ratio(Math.max(0.3,Math.min(panelRatio,0.7)));
|
||||||
|
setTimeout(function() {
|
||||||
|
tocPanel.css({"transition":""})
|
||||||
|
var selected = treeList.treeList('selected');
|
||||||
|
if (selected.id) {
|
||||||
|
treeList.treeList('show',selected);
|
||||||
|
}
|
||||||
|
},250);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshHelpIndex() {
|
||||||
|
helpTopics = [];
|
||||||
|
var modules = RED.nodes.registry.getModuleList();
|
||||||
|
var moduleNames = Object.keys(modules);
|
||||||
|
moduleNames.sort();
|
||||||
|
|
||||||
|
var helpData = [{
|
||||||
|
label: RED._("sidebar.help.nodeHelp"),
|
||||||
|
children: [],
|
||||||
|
expanded: true
|
||||||
|
}]
|
||||||
|
|
||||||
|
var subflows = RED.nodes.registry.getNodeTypes().filter(function(t) {return /subflow/.test(t)});
|
||||||
|
if (subflows.length > 0) {
|
||||||
|
helpData[0].children.push({
|
||||||
|
label: RED._("menu.label.subflows"),
|
||||||
|
children: []
|
||||||
|
})
|
||||||
|
subflows.forEach(function(nodeType) {
|
||||||
|
var sf = RED.nodes.getType(nodeType);
|
||||||
|
helpData[0].children[0].children.push({
|
||||||
|
id:"node-type:"+nodeType,
|
||||||
|
nodeType: nodeType,
|
||||||
|
subflowLabel: sf.label().toLowerCase(),
|
||||||
|
element: getNodeLabel({_def:sf,type:sf.label()})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
moduleNames.forEach(function(moduleName) {
|
||||||
|
var module = modules[moduleName];
|
||||||
|
var nodeTypes = [];
|
||||||
|
|
||||||
|
var setNames = Object.keys(module.sets);
|
||||||
|
setNames.forEach(function(setName) {
|
||||||
|
module.sets[setName].types.forEach(function(nodeType) {
|
||||||
|
if ($("script[data-help-name='"+nodeType+"']").length) {
|
||||||
|
nodeTypes.push({
|
||||||
|
id: "node-type:"+nodeType,
|
||||||
|
nodeType: nodeType,
|
||||||
|
element:getNodeLabel({_def:RED.nodes.getType(nodeType),type:nodeType})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if (nodeTypes.length > 0) {
|
||||||
|
nodeTypes.sort(function(A,B) {
|
||||||
|
return A.nodeType.localeCompare(B.nodeType)
|
||||||
|
})
|
||||||
|
helpData[0].children.push({
|
||||||
|
id: moduleName,
|
||||||
|
icon: "fa fa-cube",
|
||||||
|
label: moduleName,
|
||||||
|
children: nodeTypes
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
treeList.treeList("data",helpData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNodeLabel(n) {
|
||||||
|
var div = $('<div>',{class:"red-ui-info-outline-item"});
|
||||||
|
RED.utils.createNodeIcon(n).appendTo(div);
|
||||||
|
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
|
||||||
|
$('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).text(n.name||n.type).appendTo(contentDiv);
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showHelp(nodeType) {
|
||||||
|
helpSection.empty();
|
||||||
|
var helpText;
|
||||||
|
var title;
|
||||||
|
var m = /^subflow(:(.+))?$/.exec(nodeType);
|
||||||
|
if (m && m[2]) {
|
||||||
|
var subflowNode = RED.nodes.subflow(m[2]);
|
||||||
|
helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
||||||
|
title = subflowNode.name || nodeType;
|
||||||
|
} else {
|
||||||
|
helpText = $("script[data-help-name='"+nodeType+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||||
|
title = nodeType;
|
||||||
|
}
|
||||||
|
setInfoText(title, helpText, helpSection);
|
||||||
|
|
||||||
|
var ratio = panels.ratio();
|
||||||
|
if (ratio > 0.7) {
|
||||||
|
panels.ratio(0.7)
|
||||||
|
}
|
||||||
|
treeList.treeList("show","node-type:"+nodeType)
|
||||||
|
treeList.treeList("select","node-type:"+nodeType, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function show(type) {
|
||||||
|
RED.sidebar.show("help");
|
||||||
|
if (type) {
|
||||||
|
hideTOC();
|
||||||
|
showHelp(type);
|
||||||
|
}
|
||||||
|
resizeStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: DRY - projects.js
|
||||||
|
function addTargetToExternalLinks(el) {
|
||||||
|
$(el).find("a").each(function(el) {
|
||||||
|
var href = $(this).attr('href');
|
||||||
|
if (/^https?:/.test(href)) {
|
||||||
|
$(this).attr('target','_blank');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setInfoText(title, infoText,target) {
|
||||||
|
if (title) {
|
||||||
|
$("<h1>",{class:"red-ui-help-title"}).text(title).appendTo(target);
|
||||||
|
}
|
||||||
|
var info = addTargetToExternalLinks($('<div class="red-ui-help"><span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(infoText)+'">'+infoText+'</span></div>')).appendTo(target);
|
||||||
|
info.find(".red-ui-text-bidi-aware").contents().filter(function() { return this.nodeType === 3 && this.textContent.trim() !== "" }).wrap( "<span></span>" );
|
||||||
|
var foldingHeader = "H3";
|
||||||
|
info.find(foldingHeader).wrapInner('<a class="red-ui-help-info-header expanded" href="#"></a>')
|
||||||
|
.find("a").prepend('<i class="fa fa-angle-right">').on("click", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var isExpanded = $(this).hasClass('expanded');
|
||||||
|
var el = $(this).parent().next();
|
||||||
|
while(el.length === 1 && el[0].nodeName !== foldingHeader) {
|
||||||
|
el.toggle(!isExpanded);
|
||||||
|
el = el.next();
|
||||||
|
}
|
||||||
|
$(this).toggleClass('expanded',!isExpanded);
|
||||||
|
})
|
||||||
|
target.parent().scrollTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(html,title) {
|
||||||
|
$(helpSection).empty();
|
||||||
|
setInfoText(title,html,helpSection);
|
||||||
|
hideTOC();
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshSelection(selection) {
|
||||||
|
if (selection === undefined) {
|
||||||
|
selection = RED.view.selection();
|
||||||
|
}
|
||||||
|
if (selection.nodes) {
|
||||||
|
if (selection.nodes.length == 1) {
|
||||||
|
var node = selection.nodes[0];
|
||||||
|
if (node.type === "subflow" && node.direction) {
|
||||||
|
// ignore subflow virtual ports
|
||||||
|
} else if (node.type !== 'group'){
|
||||||
|
showHelp(node.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RED.events.on("view:selection-changed",refreshSelection);
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: init,
|
||||||
|
show: show,
|
||||||
|
set: set
|
||||||
|
}
|
||||||
|
})();
|
629
packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js
vendored
Normal file
629
packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js
vendored
Normal file
@ -0,0 +1,629 @@
|
|||||||
|
RED.sidebar.info.outliner = (function() {
|
||||||
|
|
||||||
|
var treeList;
|
||||||
|
var searchInput;
|
||||||
|
var activeSearch;
|
||||||
|
var projectInfo;
|
||||||
|
var projectInfoLabel;
|
||||||
|
var flowList;
|
||||||
|
var subflowList;
|
||||||
|
var globalConfigNodes;
|
||||||
|
|
||||||
|
var objects = {};
|
||||||
|
var missingParents = {};
|
||||||
|
var configNodeTypes;
|
||||||
|
|
||||||
|
|
||||||
|
function getFlowData() {
|
||||||
|
var flowData = [
|
||||||
|
{
|
||||||
|
label: RED._("menu.label.flows"),
|
||||||
|
expanded: true,
|
||||||
|
children: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "__subflow__",
|
||||||
|
label: RED._("menu.label.subflows"),
|
||||||
|
children: [
|
||||||
|
getEmptyItem("__subflow__")
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "__global__",
|
||||||
|
flow: "__global__",
|
||||||
|
label: RED._("sidebar.info.globalConfig"),
|
||||||
|
types: {},
|
||||||
|
children: [
|
||||||
|
getEmptyItem("__global__")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
flowList = flowData[0];
|
||||||
|
subflowList = flowData[1];
|
||||||
|
globalConfigNodes = flowData[2];
|
||||||
|
configNodeTypes = { __global__: globalConfigNodes};
|
||||||
|
|
||||||
|
return flowData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProjectLabel(p) {
|
||||||
|
var div = $('<div>',{class:"red-ui-info-outline-item red-ui-info-outline-item-flow"});
|
||||||
|
div.css("width", "calc(100% - 40px)");
|
||||||
|
var contentDiv = $('<div>',{class:"red-ui-search-result-description red-ui-info-outline-item-label"}).appendTo(div);
|
||||||
|
contentDiv.text(p.name);
|
||||||
|
var controls = $('<div>',{class:"red-ui-info-outline-item-controls"}).appendTo(div);
|
||||||
|
var editProjectButton = $('<button class="red-ui-button red-ui-button-small" style="position:absolute;right:5px;top: 3px;"><i class="fa fa-ellipsis-h"></i></button>')
|
||||||
|
.appendTo(controls)
|
||||||
|
.on("click", function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
RED.projects.editProject();
|
||||||
|
});
|
||||||
|
RED.popover.tooltip(editProjectButton,RED._('sidebar.project.showProjectSettings'));
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
var empties = {};
|
||||||
|
function getEmptyItem(id) {
|
||||||
|
var item = {
|
||||||
|
empty: true,
|
||||||
|
element: $('<div class="red-ui-info-outline-item red-ui-info-outline-item-empty">').text(RED._("sidebar.info.empty")),
|
||||||
|
}
|
||||||
|
empties[id] = item;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNodeLabelText(n) {
|
||||||
|
var label = n.name || n.type+": "+n.id;
|
||||||
|
if (n._def.label) {
|
||||||
|
try {
|
||||||
|
label = (typeof n._def.label === "function" ? n._def.label.call(n) : n._def.label)||"";
|
||||||
|
} catch(err) {
|
||||||
|
console.log("Definition error: "+type+".label",err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var newlineIndex = label.indexOf("\\n");
|
||||||
|
if (newlineIndex > -1) {
|
||||||
|
label = label.substring(0,newlineIndex)+"...";
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNodeLabel(n) {
|
||||||
|
var div = $('<div>',{class:"red-ui-info-outline-item"});
|
||||||
|
RED.utils.createNodeIcon(n).appendTo(div);
|
||||||
|
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
|
||||||
|
var labelText = getNodeLabelText(n);
|
||||||
|
var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
|
||||||
|
if (labelText) {
|
||||||
|
label.text(labelText)
|
||||||
|
} else {
|
||||||
|
label.html(" ")
|
||||||
|
}
|
||||||
|
|
||||||
|
addControls(n, div);
|
||||||
|
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFlowLabel(n) {
|
||||||
|
var div = $('<div>',{class:"red-ui-info-outline-item red-ui-info-outline-item-flow"});
|
||||||
|
var contentDiv = $('<div>',{class:"red-ui-search-result-description red-ui-info-outline-item-label"}).appendTo(div);
|
||||||
|
var label = (typeof n === "string")? n : n.label;
|
||||||
|
var newlineIndex = label.indexOf("\\n");
|
||||||
|
if (newlineIndex > -1) {
|
||||||
|
label = label.substring(0,newlineIndex)+"...";
|
||||||
|
}
|
||||||
|
contentDiv.text(label);
|
||||||
|
addControls(n, div);
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubflowLabel(n) {
|
||||||
|
|
||||||
|
var div = $('<div>',{class:"red-ui-info-outline-item"});
|
||||||
|
RED.utils.createNodeIcon(n).appendTo(div);
|
||||||
|
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
|
||||||
|
var labelText = getNodeLabelText(n);
|
||||||
|
var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
|
||||||
|
if (labelText) {
|
||||||
|
label.text(labelText)
|
||||||
|
} else {
|
||||||
|
label.html(" ")
|
||||||
|
}
|
||||||
|
|
||||||
|
addControls(n, div);
|
||||||
|
|
||||||
|
return div;
|
||||||
|
|
||||||
|
|
||||||
|
// var div = $('<div>',{class:"red-ui-info-outline-item red-ui-info-outline-item-flow"});
|
||||||
|
// var contentDiv = $('<div>',{class:"red-ui-search-result-description red-ui-info-outline-item-label"}).appendTo(div);
|
||||||
|
// contentDiv.text(n.name || n.id);
|
||||||
|
// addControls(n, div);
|
||||||
|
// return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addControls(n,div) {
|
||||||
|
var controls = $('<div>',{class:"red-ui-info-outline-item-controls red-ui-info-outline-item-hover-controls"}).appendTo(div);
|
||||||
|
|
||||||
|
if (n._def.category === "config" && n.type !== "group") {
|
||||||
|
var userCountBadge = $('<button type="button" class="red-ui-info-outline-item-control-users red-ui-button red-ui-button-small"><i class="fa fa-toggle-right"></i></button>').text(n.users.length).appendTo(controls).on("click",function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
RED.search.show("uses:"+n.id);
|
||||||
|
})
|
||||||
|
RED.popover.tooltip(userCountBadge,function() { return RED._('editor.nodesUse',{count:n.users.length})});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n._def.button) {
|
||||||
|
var triggerButton = $('<button type="button" class="red-ui-info-outline-item-control-action red-ui-button red-ui-button-small"><i class="fa fa-toggle-right"></i></button>').appendTo(controls).on("click",function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
RED.view.clickNodeButton(n);
|
||||||
|
})
|
||||||
|
RED.popover.tooltip(triggerButton,RED._("sidebar.info.triggerAction"));
|
||||||
|
}
|
||||||
|
// $('<button type="button" class="red-ui-info-outline-item-control-reveal red-ui-button red-ui-button-small"><i class="fa fa-eye"></i></button>').appendTo(controls).on("click",function(evt) {
|
||||||
|
// evt.preventDefault();
|
||||||
|
// evt.stopPropagation();
|
||||||
|
// RED.view.reveal(n.id);
|
||||||
|
// })
|
||||||
|
if (n.type !== 'group' && n.type !== 'subflow') {
|
||||||
|
var toggleButton = $('<button type="button" class="red-ui-info-outline-item-control-disable red-ui-button red-ui-button-small"><i class="fa fa-circle-thin"></i><i class="fa fa-ban"></i></button>').appendTo(controls).on("click",function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
if (n.type === 'tab') {
|
||||||
|
if (n.disabled) {
|
||||||
|
RED.workspaces.enable(n.id)
|
||||||
|
} else {
|
||||||
|
RED.workspaces.disable(n.id)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: this ought to be a utility function in RED.nodes
|
||||||
|
var historyEvent = {
|
||||||
|
t: "edit",
|
||||||
|
node: n,
|
||||||
|
changed: n.changed,
|
||||||
|
changes: {
|
||||||
|
d: n.d
|
||||||
|
},
|
||||||
|
dirty:RED.nodes.dirty()
|
||||||
|
}
|
||||||
|
if (n.d) {
|
||||||
|
delete n.d;
|
||||||
|
} else {
|
||||||
|
n.d = true;
|
||||||
|
}
|
||||||
|
n.dirty = true;
|
||||||
|
n.changed = true;
|
||||||
|
RED.events.emit("nodes:change",n);
|
||||||
|
RED.nodes.dirty(true)
|
||||||
|
RED.view.redraw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RED.popover.tooltip(toggleButton,function() {
|
||||||
|
return RED._("common.label."+(((n.type==='tab' && n.disabled) || (n.type!=='tab' && n.d))?"enable":"disable"));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$('<div class="red-ui-info-outline-item-control-spacer">').appendTo(controls)
|
||||||
|
}
|
||||||
|
controls.find("button").on("dblclick", function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function onProjectLoad(activeProject) {
|
||||||
|
objects = {};
|
||||||
|
var newFlowData = getFlowData();
|
||||||
|
projectInfoLabel.empty();
|
||||||
|
getProjectLabel(activeProject).appendTo(projectInfoLabel);
|
||||||
|
projectInfo.show();
|
||||||
|
treeList.treeList('data',newFlowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function build() {
|
||||||
|
var container = $("<div>", {class:"red-ui-info-outline"}).css({'height': '100%'});
|
||||||
|
var toolbar = $("<div>", {class:"red-ui-sidebar-header red-ui-info-toolbar"}).appendTo(container);
|
||||||
|
|
||||||
|
searchInput = $('<input type="text" data-i18n="[placeholder]menu.label.search">').appendTo(toolbar).searchBox({
|
||||||
|
style: "compact",
|
||||||
|
delay: 500,
|
||||||
|
change: function() {
|
||||||
|
var val = $(this).val();
|
||||||
|
var searchResults = RED.search.search(val);
|
||||||
|
if (val) {
|
||||||
|
activeSearch = val;
|
||||||
|
var resultMap = {};
|
||||||
|
for (var i=0,l=searchResults.length;i<l;i++) {
|
||||||
|
resultMap[searchResults[i].node.id] = true;
|
||||||
|
}
|
||||||
|
var c = treeList.treeList('filter',function(item) {
|
||||||
|
if (item.depth === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return item.id && objects[item.id] && resultMap[item.id]
|
||||||
|
},true)
|
||||||
|
} else {
|
||||||
|
activeSearch = null;
|
||||||
|
treeList.treeList('filter',null);
|
||||||
|
var selected = treeList.treeList('selected');
|
||||||
|
if (selected.id) {
|
||||||
|
treeList.treeList('show',selected.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{label:RED._("sidebar.info.search.configNodes"), value:"is:config"},
|
||||||
|
{label:RED._("sidebar.info.search.unusedConfigNodes"), value:"is:config is:unused"},
|
||||||
|
{label:RED._("sidebar.info.search.invalidNodes"), value: "is:invalid"},
|
||||||
|
{label:RED._("sidebar.info.search.uknownNodes"), value: "type:unknown"},
|
||||||
|
{label:RED._("sidebar.info.search.unusedSubflows"), value:"is:subflow is:unused"},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
projectInfo = $('<div class="red-ui-treeList-label red-ui-info-outline-project"><span class="red-ui-treeList-icon"><i class="fa fa-archive"></i></span></div>').hide().appendTo(container)
|
||||||
|
projectInfoLabel = $('<span>').appendTo(projectInfo);
|
||||||
|
|
||||||
|
// <div class="red-ui-info-outline-item red-ui-info-outline-item-flow" style=";"><div class="red-ui-search-result-description red-ui-info-outline-item-label">Space Monkey</div><div class="red-ui-info-outline-item-controls"><button class="red-ui-button red-ui-button-small" style="position:absolute;right:5px;"><i class="fa fa-ellipsis-h"></i></button></div></div></div>').appendTo(container)
|
||||||
|
|
||||||
|
treeList = $("<div>").css({width: "100%"}).appendTo(container).treeList({
|
||||||
|
data:getFlowData()
|
||||||
|
})
|
||||||
|
treeList.on('treelistselect', function(e,item) {
|
||||||
|
var node = RED.nodes.node(item.id) || RED.nodes.group(item.id);
|
||||||
|
if (node) {
|
||||||
|
if (node.type === 'group' || node._def.category !== "config") {
|
||||||
|
RED.view.select({nodes:[node]})
|
||||||
|
} else {
|
||||||
|
RED.view.select({nodes:[]})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
treeList.on('treelistconfirm', function(e,item) {
|
||||||
|
var node = RED.nodes.node(item.id);
|
||||||
|
if (node) {
|
||||||
|
if (node._def.category === "config") {
|
||||||
|
RED.editor.editConfig("", node.type, node.id);
|
||||||
|
} else {
|
||||||
|
RED.editor.edit(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
RED.events.on("projects:load", onProjectLoad)
|
||||||
|
|
||||||
|
RED.events.on("flows:add", onFlowAdd)
|
||||||
|
RED.events.on("flows:remove", onObjectRemove)
|
||||||
|
RED.events.on("flows:change", onFlowChange)
|
||||||
|
RED.events.on("flows:reorder", onFlowsReorder)
|
||||||
|
|
||||||
|
RED.events.on("subflows:add", onSubflowAdd)
|
||||||
|
RED.events.on("subflows:remove", onObjectRemove)
|
||||||
|
RED.events.on("subflows:change", onSubflowChange)
|
||||||
|
|
||||||
|
RED.events.on("nodes:add",onNodeAdd);
|
||||||
|
RED.events.on("nodes:remove",onObjectRemove);
|
||||||
|
RED.events.on("nodes:change",onNodeChange);
|
||||||
|
|
||||||
|
RED.events.on("groups:add",onNodeAdd);
|
||||||
|
RED.events.on("groups:remove",onObjectRemove);
|
||||||
|
RED.events.on("groups:change",onNodeChange);
|
||||||
|
|
||||||
|
RED.events.on("workspace:clear", onWorkspaceClear)
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
function onWorkspaceClear() {
|
||||||
|
treeList.treeList('data',getFlowData());
|
||||||
|
}
|
||||||
|
function onFlowAdd(ws) {
|
||||||
|
objects[ws.id] = {
|
||||||
|
id: ws.id,
|
||||||
|
element: getFlowLabel(ws),
|
||||||
|
children:[],
|
||||||
|
deferBuild: true,
|
||||||
|
icon: "red-ui-icons red-ui-icons-flow",
|
||||||
|
gutter: getGutter(ws)
|
||||||
|
}
|
||||||
|
if (missingParents[ws.id]) {
|
||||||
|
objects[ws.id].children = missingParents[ws.id];
|
||||||
|
delete missingParents[ws.id]
|
||||||
|
} else {
|
||||||
|
objects[ws.id].children.push(getEmptyItem(ws.id));
|
||||||
|
}
|
||||||
|
flowList.treeList.addChild(objects[ws.id])
|
||||||
|
objects[ws.id].element.toggleClass("red-ui-info-outline-item-disabled", !!ws.disabled)
|
||||||
|
objects[ws.id].treeList.container.toggleClass("red-ui-info-outline-item-disabled", !!ws.disabled)
|
||||||
|
updateSearch();
|
||||||
|
|
||||||
|
}
|
||||||
|
function onFlowChange(n) {
|
||||||
|
var existingObject = objects[n.id];
|
||||||
|
|
||||||
|
var label = n.label || n.id;
|
||||||
|
var newlineIndex = label.indexOf("\\n");
|
||||||
|
if (newlineIndex > -1) {
|
||||||
|
label = label.substring(0,newlineIndex)+"...";
|
||||||
|
}
|
||||||
|
existingObject.element.find(".red-ui-info-outline-item-label").text(label);
|
||||||
|
existingObject.element.toggleClass("red-ui-info-outline-item-disabled", !!n.disabled)
|
||||||
|
existingObject.treeList.container.toggleClass("red-ui-info-outline-item-disabled", !!n.disabled)
|
||||||
|
updateSearch();
|
||||||
|
}
|
||||||
|
function onFlowsReorder(order) {
|
||||||
|
var indexMap = {};
|
||||||
|
order.forEach(function(id,index) {
|
||||||
|
indexMap[id] = index;
|
||||||
|
})
|
||||||
|
|
||||||
|
flowList.treeList.sortChildren(function(A,B) {
|
||||||
|
if (A.id === "__global__") { return -1 }
|
||||||
|
if (B.id === "__global__") { return 1 }
|
||||||
|
return indexMap[A.id] - indexMap[B.id]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function onSubflowAdd(sf) {
|
||||||
|
objects[sf.id] = {
|
||||||
|
id: sf.id,
|
||||||
|
element: getNodeLabel(sf),
|
||||||
|
children:[],
|
||||||
|
deferBuild: true,
|
||||||
|
gutter: getGutter(sf)
|
||||||
|
}
|
||||||
|
if (missingParents[sf.id]) {
|
||||||
|
objects[sf.id].children = missingParents[sf.id];
|
||||||
|
delete missingParents[sf.id]
|
||||||
|
} else {
|
||||||
|
objects[sf.id].children.push(getEmptyItem(sf.id));
|
||||||
|
}
|
||||||
|
if (empties["__subflow__"]) {
|
||||||
|
empties["__subflow__"].treeList.remove();
|
||||||
|
delete empties["__subflow__"];
|
||||||
|
}
|
||||||
|
subflowList.treeList.addChild(objects[sf.id])
|
||||||
|
updateSearch();
|
||||||
|
}
|
||||||
|
function onSubflowChange(sf) {
|
||||||
|
var existingObject = objects[sf.id];
|
||||||
|
existingObject.treeList.replaceElement(getNodeLabel(sf));
|
||||||
|
// existingObject.element.find(".red-ui-info-outline-item-label").text(n.name || n.id);
|
||||||
|
RED.nodes.eachNode(function(n) {
|
||||||
|
if (n.type == "subflow:"+sf.id) {
|
||||||
|
var sfInstance = objects[n.id];
|
||||||
|
sfInstance.treeList.replaceElement(getNodeLabel(n));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onNodeChange(n) {
|
||||||
|
var existingObject = objects[n.id];
|
||||||
|
var parent = n.g||n.z||"__global__";
|
||||||
|
|
||||||
|
var nodeLabelText = getNodeLabelText(n);
|
||||||
|
if (nodeLabelText) {
|
||||||
|
existingObject.element.find(".red-ui-info-outline-item-label").text(nodeLabelText);
|
||||||
|
} else {
|
||||||
|
existingObject.element.find(".red-ui-info-outline-item-label").html(" ");
|
||||||
|
}
|
||||||
|
var existingParent = existingObject.parent.id;
|
||||||
|
if (!existingParent) {
|
||||||
|
existingParent = existingObject.parent.parent.flow
|
||||||
|
}
|
||||||
|
if (parent !== existingParent) {
|
||||||
|
var parentItem = existingObject.parent;
|
||||||
|
existingObject.treeList.remove(true);
|
||||||
|
if (parentItem.children.length === 0) {
|
||||||
|
if (parentItem.config) {
|
||||||
|
// this is a config
|
||||||
|
parentItem.treeList.remove();
|
||||||
|
// console.log("Removing",n.type,"from",parentItem.parent.id||parentItem.parent.parent.id)
|
||||||
|
|
||||||
|
delete configNodeTypes[parentItem.parent.id||parentItem.parent.parent.id].types[n.type];
|
||||||
|
|
||||||
|
|
||||||
|
if (parentItem.parent.children.length === 0) {
|
||||||
|
if (parentItem.parent.id === "__global__") {
|
||||||
|
parentItem.parent.treeList.addChild(getEmptyItem(parentItem.parent.id));
|
||||||
|
} else {
|
||||||
|
delete configNodeTypes[parentItem.parent.parent.id];
|
||||||
|
parentItem.parent.treeList.remove();
|
||||||
|
if (parentItem.parent.parent.children.length === 0) {
|
||||||
|
parentItem.parent.parent.treeList.addChild(getEmptyItem(parentItem.parent.parent.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parentItem.treeList.addChild(getEmptyItem(parentItem.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n._def.category === 'config' && n.type !== 'group') {
|
||||||
|
// This must be a config node that has been rescoped
|
||||||
|
createFlowConfigNode(parent,n.type);
|
||||||
|
configNodeTypes[parent].types[n.type].treeList.addChild(objects[n.id]);
|
||||||
|
} else {
|
||||||
|
// This is a node that has moved groups
|
||||||
|
if (empties[parent]) {
|
||||||
|
empties[parent].treeList.remove();
|
||||||
|
delete empties[parent];
|
||||||
|
}
|
||||||
|
objects[parent].treeList.addChild(existingObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (parent === "__global__") {
|
||||||
|
// // Global always exists here
|
||||||
|
// if (!configNodeTypes[parent][n.type]) {
|
||||||
|
// configNodeTypes[parent][n.type] = {
|
||||||
|
// config: true,
|
||||||
|
// label: n.type,
|
||||||
|
// children: []
|
||||||
|
// }
|
||||||
|
// globalConfigNodes.treeList.addChild(configNodeTypes[parent][n.type])
|
||||||
|
// }
|
||||||
|
// configNodeTypes[parent][n.type].treeList.addChild(existingObject);
|
||||||
|
// } else {
|
||||||
|
// if (empties[parent]) {
|
||||||
|
// empties[parent].treeList.remove();
|
||||||
|
// delete empties[parent];
|
||||||
|
// }
|
||||||
|
// objects[parent].treeList.addChild(existingObject)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
existingObject.element.toggleClass("red-ui-info-outline-item-disabled", !!n.d)
|
||||||
|
|
||||||
|
if (n._def.category === "config" && n.type !== 'group') {
|
||||||
|
existingObject.element.find(".red-ui-info-outline-item-control-users").text(n.users.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSearch();
|
||||||
|
}
|
||||||
|
function onObjectRemove(n) {
|
||||||
|
var existingObject = objects[n.id];
|
||||||
|
existingObject.treeList.remove();
|
||||||
|
delete objects[n.id]
|
||||||
|
|
||||||
|
// If this is a group being removed, it may have an empty item
|
||||||
|
if (empties[n.id]) {
|
||||||
|
delete empties[n.id];
|
||||||
|
}
|
||||||
|
var parent = existingObject.parent;
|
||||||
|
if (parent.children.length === 0) {
|
||||||
|
if (parent.config) {
|
||||||
|
// this is a config
|
||||||
|
parent.treeList.remove();
|
||||||
|
delete configNodeTypes[parent.parent.id||n.z].types[n.type];
|
||||||
|
if (parent.parent.children.length === 0) {
|
||||||
|
if (parent.parent.id === "__global__") {
|
||||||
|
parent.parent.treeList.addChild(getEmptyItem(parent.parent.id));
|
||||||
|
} else {
|
||||||
|
delete configNodeTypes[n.z];
|
||||||
|
parent.parent.treeList.remove();
|
||||||
|
if (parent.parent.parent.children.length === 0) {
|
||||||
|
parent.parent.parent.treeList.addChild(getEmptyItem(parent.parent.parent.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parent.treeList.addChild(getEmptyItem(parent.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getGutter(n) {
|
||||||
|
var span = $("<span>",{class:"red-ui-info-outline-gutter"});
|
||||||
|
var revealButton = $('<button type="button" class="red-ui-info-outline-item-control-reveal red-ui-button red-ui-button-small"><i class="fa fa-search"></i></button>').appendTo(span).on("click",function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
RED.view.reveal(n.id);
|
||||||
|
})
|
||||||
|
RED.popover.tooltip(revealButton,RED._("sidebar.info.find"));
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFlowConfigNode(parent,type) {
|
||||||
|
// console.log("createFlowConfig",parent,type,configNodeTypes[parent]);
|
||||||
|
if (empties[parent]) {
|
||||||
|
empties[parent].treeList.remove();
|
||||||
|
delete empties[parent];
|
||||||
|
}
|
||||||
|
if (!configNodeTypes[parent]) {
|
||||||
|
// There is no 'config nodes' item in the parent flow
|
||||||
|
configNodeTypes[parent] = {
|
||||||
|
config: true,
|
||||||
|
flow: parent,
|
||||||
|
types: {},
|
||||||
|
label: RED._("menu.label.displayConfig"),
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
objects[parent].treeList.insertChildAt(configNodeTypes[parent],0);
|
||||||
|
// console.log("CREATED", parent)
|
||||||
|
}
|
||||||
|
if (!configNodeTypes[parent].types[type]) {
|
||||||
|
configNodeTypes[parent].types[type] = {
|
||||||
|
config: true,
|
||||||
|
label: type,
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
configNodeTypes[parent].treeList.addChild(configNodeTypes[parent].types[type]);
|
||||||
|
// console.log("CREATED", parent,type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function onNodeAdd(n) {
|
||||||
|
objects[n.id] = {
|
||||||
|
id: n.id,
|
||||||
|
element: getNodeLabel(n),
|
||||||
|
gutter: getGutter(n)
|
||||||
|
}
|
||||||
|
if (n.type === "group") {
|
||||||
|
objects[n.id].children = [];
|
||||||
|
objects[n.id].deferBuild = true;
|
||||||
|
if (missingParents[n.id]) {
|
||||||
|
objects[n.id].children = missingParents[n.id];
|
||||||
|
delete missingParents[n.id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var parent = n.g||n.z||"__global__";
|
||||||
|
|
||||||
|
if (n._def.category !== "config" || n.type === 'group') {
|
||||||
|
if (objects[parent]) {
|
||||||
|
if (empties[parent]) {
|
||||||
|
empties[parent].treeList.remove();
|
||||||
|
delete empties[parent];
|
||||||
|
}
|
||||||
|
if (objects[parent].treeList) {
|
||||||
|
objects[parent].treeList.addChild(objects[n.id]);
|
||||||
|
} else {
|
||||||
|
objects[parent].children.push(objects[n.id])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
missingParents[parent] = missingParents[parent]||[];
|
||||||
|
missingParents[parent].push(objects[n.id])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
createFlowConfigNode(parent,n.type);
|
||||||
|
configNodeTypes[parent].types[n.type].treeList.addChild(objects[n.id]);
|
||||||
|
}
|
||||||
|
objects[n.id].element.toggleClass("red-ui-info-outline-item-disabled", !!n.d)
|
||||||
|
updateSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateSearchTimer;
|
||||||
|
function updateSearch() {
|
||||||
|
if (updateSearchTimer) {
|
||||||
|
clearTimeout(updateSearchTimer)
|
||||||
|
}
|
||||||
|
if (activeSearch) {
|
||||||
|
updateSearchTimer = setTimeout(function() {
|
||||||
|
searchInput.searchBox("change");
|
||||||
|
},100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function onSelectionChanged(selection) {
|
||||||
|
// treeList.treeList('clearSelection');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
build: build,
|
||||||
|
search: function(val) {
|
||||||
|
searchInput.searchBox('value',val)
|
||||||
|
},
|
||||||
|
select: function(node) {
|
||||||
|
if (node) {
|
||||||
|
if (Array.isArray(node)) {
|
||||||
|
treeList.treeList('select', node.map(function(n) { return objects[n.id] }), false)
|
||||||
|
} else {
|
||||||
|
treeList.treeList('select', objects[node.id], false)
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
treeList.treeList('clearSelection')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reveal: function(node) {
|
||||||
|
treeList.treeList('show', objects[node.id])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -16,16 +16,32 @@
|
|||||||
RED.sidebar.info = (function() {
|
RED.sidebar.info = (function() {
|
||||||
|
|
||||||
var content;
|
var content;
|
||||||
var sections;
|
var panels;
|
||||||
var propertiesSection;
|
|
||||||
var infoSection;
|
var infoSection;
|
||||||
var helpSection;
|
|
||||||
|
var propertiesPanelContent;
|
||||||
|
var propertiesPanelHeader;
|
||||||
|
var propertiesPanelHeaderIcon;
|
||||||
|
var propertiesPanelHeaderLabel;
|
||||||
|
var propertiesPanelHeaderReveal;
|
||||||
|
var propertiesPanelHeaderHelp;
|
||||||
|
|
||||||
|
var selectedObject;
|
||||||
|
|
||||||
|
var tipContainer;
|
||||||
var tipBox;
|
var tipBox;
|
||||||
|
|
||||||
|
// TODO: remove this
|
||||||
var expandedSections = {
|
var expandedSections = {
|
||||||
"property": false
|
"property": false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function resizeStack() {
|
||||||
|
if (panels) {
|
||||||
|
var h = $(content).parent().height() - tipContainer.outerHeight();
|
||||||
|
panels.resize(h)
|
||||||
|
}
|
||||||
|
}
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
content = document.createElement("div");
|
content = document.createElement("div");
|
||||||
@ -35,31 +51,81 @@ RED.sidebar.info = (function() {
|
|||||||
|
|
||||||
var stackContainer = $("<div>",{class:"red-ui-sidebar-info-stack"}).appendTo(content);
|
var stackContainer = $("<div>",{class:"red-ui-sidebar-info-stack"}).appendTo(content);
|
||||||
|
|
||||||
sections = RED.stack.create({
|
var outlinerPanel = $("<div>").css({
|
||||||
container: stackContainer
|
"overflow": "hidden",
|
||||||
}).hide();
|
"height": "calc(70%)"
|
||||||
|
}).appendTo(stackContainer);
|
||||||
|
var propertiesPanel = $("<div>").css({
|
||||||
|
"overflow":"hidden",
|
||||||
|
"height":"100%",
|
||||||
|
"display": "flex",
|
||||||
|
"flex-direction": "column"
|
||||||
|
}).appendTo(stackContainer);
|
||||||
|
propertiesPanelHeader = $("<div>", {class:"red-ui-palette-header red-ui-info-header"}).css({
|
||||||
|
"flex":"0 0 auto"
|
||||||
|
}).appendTo(propertiesPanel);
|
||||||
|
|
||||||
propertiesSection = sections.add({
|
propertiesPanelHeaderIcon = $("<span>").appendTo(propertiesPanelHeader);
|
||||||
title: RED._("sidebar.info.info"),
|
propertiesPanelHeaderLabel = $("<span>").appendTo(propertiesPanelHeader);
|
||||||
collapsible: true
|
propertiesPanelHeaderHelp = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-book"></button>').css({
|
||||||
|
position: 'absolute',
|
||||||
|
top: '12px',
|
||||||
|
right: '32px'
|
||||||
|
}).on("click", function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
if (selectedObject) {
|
||||||
|
RED.sidebar.help.show(selectedObject.type);
|
||||||
|
}
|
||||||
|
}).appendTo(propertiesPanelHeader);
|
||||||
|
RED.popover.tooltip(propertiesPanelHeaderHelp,RED._("sidebar.help.showHelp"));
|
||||||
|
|
||||||
|
|
||||||
|
propertiesPanelHeaderReveal = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-search"></button>').css({
|
||||||
|
position: 'absolute',
|
||||||
|
top: '12px',
|
||||||
|
right: '8px'
|
||||||
|
}).on("click", function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
if (selectedObject) {
|
||||||
|
RED.sidebar.info.outliner.reveal(selectedObject);
|
||||||
|
RED.view.reveal(selectedObject.id);
|
||||||
|
}
|
||||||
|
}).appendTo(propertiesPanelHeader);
|
||||||
|
RED.popover.tooltip(propertiesPanelHeaderReveal,RED._("sidebar.help.showInOutline"));
|
||||||
|
|
||||||
|
|
||||||
|
propertiesPanelContent = $("<div>").css({
|
||||||
|
"flex":"1 1 auto",
|
||||||
|
"overflow-y":"scroll",
|
||||||
|
}).appendTo(propertiesPanel);
|
||||||
|
|
||||||
|
|
||||||
|
panels = RED.panels.create({container: stackContainer})
|
||||||
|
panels.ratio(0.6);
|
||||||
|
RED.sidebar.info.outliner.build().appendTo(outlinerPanel);
|
||||||
|
|
||||||
|
|
||||||
|
RED.sidebar.addTab({
|
||||||
|
id: "info",
|
||||||
|
label: RED._("sidebar.info.label"),
|
||||||
|
name: RED._("sidebar.info.name"),
|
||||||
|
iconClass: "fa fa-info",
|
||||||
|
action:"core:show-info-tab",
|
||||||
|
content: content,
|
||||||
|
pinned: true,
|
||||||
|
enableOnEdit: true
|
||||||
});
|
});
|
||||||
propertiesSection.expand();
|
|
||||||
|
|
||||||
infoSection = sections.add({
|
RED.events.on("sidebar:resize", resizeStack);
|
||||||
title: RED._("sidebar.info.desc"),
|
|
||||||
collapsible: true
|
|
||||||
});
|
|
||||||
infoSection.expand();
|
|
||||||
infoSection.content.css("padding","6px");
|
|
||||||
|
|
||||||
helpSection = sections.add({
|
$(window).on("resize", resizeStack);
|
||||||
title: RED._("sidebar.info.nodeHelp"),
|
$(window).on("focus", resizeStack);
|
||||||
collapsible: true
|
|
||||||
});
|
|
||||||
helpSection.expand();
|
|
||||||
helpSection.content.css("padding","6px");
|
|
||||||
|
|
||||||
var tipContainer = $('<div class="red-ui-help-tips"></div>').appendTo(content);
|
|
||||||
|
// Tip Box
|
||||||
|
tipContainer = $('<div class="red-ui-help-tips"></div>').appendTo(content);
|
||||||
tipBox = $('<div class="red-ui-help-tip"></div>').appendTo(tipContainer);
|
tipBox = $('<div class="red-ui-help-tip"></div>').appendTo(tipContainer);
|
||||||
var tipButtons = $('<div class="red-ui-help-tips-buttons"></div>').appendTo(tipContainer);
|
var tipButtons = $('<div class="red-ui-help-tips-buttons"></div>').appendTo(tipContainer);
|
||||||
|
|
||||||
@ -75,17 +141,6 @@ RED.sidebar.info = (function() {
|
|||||||
RED.actions.invoke("core:toggle-show-tips");
|
RED.actions.invoke("core:toggle-show-tips");
|
||||||
RED.notify(RED._("sidebar.info.showTips"));
|
RED.notify(RED._("sidebar.info.showTips"));
|
||||||
});
|
});
|
||||||
|
|
||||||
RED.sidebar.addTab({
|
|
||||||
id: "info",
|
|
||||||
label: RED._("sidebar.info.label"),
|
|
||||||
name: RED._("sidebar.info.name"),
|
|
||||||
iconClass: "fa fa-info",
|
|
||||||
action:"core:show-info-tab",
|
|
||||||
content: content,
|
|
||||||
pinned: true,
|
|
||||||
enableOnEdit: true
|
|
||||||
});
|
|
||||||
if (tips.enabled()) {
|
if (tips.enabled()) {
|
||||||
tips.start();
|
tips.start();
|
||||||
} else {
|
} else {
|
||||||
@ -113,46 +168,36 @@ RED.sidebar.info = (function() {
|
|||||||
refreshSelection();
|
refreshSelection();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sections.show();
|
$(propertiesPanelContent).empty();
|
||||||
$(propertiesSection.content).empty();
|
|
||||||
$(infoSection.content).empty();
|
|
||||||
$(helpSection.content).empty();
|
|
||||||
infoSection.title.text(RED._("sidebar.info.desc"));
|
|
||||||
|
|
||||||
var propRow;
|
var propRow;
|
||||||
|
|
||||||
var table = $('<table class="red-ui-info-table"></table>').appendTo(propertiesSection.content);
|
var table = $('<table class="red-ui-info-table"></table>').appendTo(propertiesPanelContent);
|
||||||
var tableBody = $('<tbody>').appendTo(table);
|
var tableBody = $('<tbody>').appendTo(table);
|
||||||
|
|
||||||
var subflowNode;
|
var subflowNode;
|
||||||
var subflowUserCount;
|
var subflowUserCount;
|
||||||
|
|
||||||
var activeProject = RED.projects.getActiveProject();
|
|
||||||
if (activeProject) {
|
|
||||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+ RED._("sidebar.project.name") + '</td><td></td></tr>').appendTo(tableBody);
|
|
||||||
$(propRow.children()[1]).text(activeProject.name||"");
|
|
||||||
$('<tr class="red-ui-help-property-expand blank"><td colspan="2"></td></tr>').appendTo(tableBody);
|
|
||||||
var editProjectButton = $('<button class="red-ui-button red-ui-button-small" style="position:absolute;right:2px;"><i class="fa fa-ellipsis-h"></i></button>')
|
|
||||||
.appendTo(propRow.children()[1])
|
|
||||||
.on("click", function(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
RED.projects.editProject();
|
|
||||||
});
|
|
||||||
RED.popover.tooltip(editProjectButton,RED._('sidebar.project.showProjectSettings'));
|
|
||||||
}
|
|
||||||
propertiesSection.container.show();
|
|
||||||
infoSection.container.show();
|
|
||||||
helpSection.container.show();
|
|
||||||
if (node === null) {
|
if (node === null) {
|
||||||
|
RED.sidebar.info.outliner.select(null);
|
||||||
return;
|
return;
|
||||||
} else if (Array.isArray(node)) {
|
} else if (Array.isArray(node)) {
|
||||||
// Multiple things selected
|
// Multiple things selected
|
||||||
// - hide help and info sections
|
// - hide help and info sections
|
||||||
|
RED.sidebar.info.outliner.select(node);
|
||||||
|
|
||||||
|
propertiesPanelHeaderIcon.empty();
|
||||||
|
RED.utils.createNodeIcon({type:"_selection_"}).appendTo(propertiesPanelHeaderIcon);
|
||||||
|
propertiesPanelHeaderLabel.text("Selection");
|
||||||
|
propertiesPanelHeaderReveal.hide();
|
||||||
|
propertiesPanelHeaderHelp.hide();
|
||||||
|
selectedObject = null;
|
||||||
|
|
||||||
var types = {
|
var types = {
|
||||||
nodes:0,
|
nodes:0,
|
||||||
flows:0,
|
flows:0,
|
||||||
subflows:0
|
subflows:0,
|
||||||
|
groups: 0
|
||||||
}
|
}
|
||||||
node.forEach(function(n) {
|
node.forEach(function(n) {
|
||||||
if (n.type === 'tab') {
|
if (n.type === 'tab') {
|
||||||
@ -160,12 +205,13 @@ RED.sidebar.info = (function() {
|
|||||||
types.nodes += RED.nodes.filterNodes({z:n.id}).length;
|
types.nodes += RED.nodes.filterNodes({z:n.id}).length;
|
||||||
} else if (n.type === 'subflow') {
|
} else if (n.type === 'subflow') {
|
||||||
types.subflows++;
|
types.subflows++;
|
||||||
|
} else if (n.type === 'group') {
|
||||||
|
types.groups++;
|
||||||
} else {
|
} else {
|
||||||
types.nodes++;
|
types.nodes++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
helpSection.container.hide();
|
// infoSection.container.hide();
|
||||||
infoSection.container.hide();
|
|
||||||
// - show the count of selected nodes
|
// - show the count of selected nodes
|
||||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.selection")+"</td><td></td></tr>").appendTo(tableBody);
|
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.selection")+"</td><td></td></tr>").appendTo(tableBody);
|
||||||
|
|
||||||
@ -179,53 +225,96 @@ RED.sidebar.info = (function() {
|
|||||||
if (types.nodes > 0) {
|
if (types.nodes > 0) {
|
||||||
$('<div>').text(RED._("clipboard.node",{count:types.nodes})).appendTo(counts);
|
$('<div>').text(RED._("clipboard.node",{count:types.nodes})).appendTo(counts);
|
||||||
}
|
}
|
||||||
|
if (types.groups > 0) {
|
||||||
|
$('<div>').text(RED._("clipboard.group",{count:types.groups})).appendTo(counts);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// A single 'thing' selected.
|
// A single 'thing' selected.
|
||||||
|
|
||||||
|
RED.sidebar.info.outliner.select(node);
|
||||||
|
|
||||||
// Check to see if this is a subflow or subflow instance
|
// Check to see if this is a subflow or subflow instance
|
||||||
var m = /^subflow(:(.+))?$/.exec(node.type);
|
var subflowRegex = /^subflow(:(.+))?$/.exec(node.type);
|
||||||
if (m) {
|
if (subflowRegex) {
|
||||||
if (m[2]) {
|
if (subflowRegex[2]) {
|
||||||
subflowNode = RED.nodes.subflow(m[2]);
|
subflowNode = RED.nodes.subflow(subflowRegex[2]);
|
||||||
} else {
|
} else {
|
||||||
subflowNode = node;
|
subflowNode = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
subflowUserCount = 0;
|
|
||||||
var subflowType = "subflow:"+subflowNode.id;
|
var subflowType = "subflow:"+subflowNode.id;
|
||||||
RED.nodes.eachNode(function(n) {
|
subflowUserCount = subflowNode.instances.length;
|
||||||
if (n.type === subflowType) {
|
|
||||||
subflowUserCount++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
propertiesPanelHeaderIcon.empty();
|
||||||
|
RED.utils.createNodeIcon(node).appendTo(propertiesPanelHeaderIcon);
|
||||||
|
var objectLabel = RED.utils.getNodeLabel(node, node.type+": "+node.id)
|
||||||
|
var newlineIndex = objectLabel.indexOf("\\n");
|
||||||
|
if (newlineIndex > -1) {
|
||||||
|
objectLabel = objectLabel.substring(0,newlineIndex)+"...";
|
||||||
|
}
|
||||||
|
propertiesPanelHeaderLabel.text(objectLabel);
|
||||||
|
propertiesPanelHeaderReveal.show();
|
||||||
|
selectedObject = node;
|
||||||
|
|
||||||
|
propRow = $('<tr class="red-ui-help-info-row"><td></td><td></td></tr>').appendTo(tableBody);
|
||||||
|
var objectType = "node";
|
||||||
|
if (node.type === "subflow" || subflowRegex) {
|
||||||
|
objectType = "subflow";
|
||||||
|
} else if (node.type === "tab") {
|
||||||
|
objectType = "flow";
|
||||||
|
}else if (node.type === "group") {
|
||||||
|
objectType = "group";
|
||||||
|
}
|
||||||
|
$(propRow.children()[0]).text(RED._("sidebar.info."+objectType))
|
||||||
|
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||||
|
|
||||||
if (node.type === "tab" || node.type === "subflow") {
|
if (node.type === "tab" || node.type === "subflow") {
|
||||||
// If nothing is selected, but we're on a flow or subflow tab.
|
// If nothing is selected, but we're on a flow or subflow tab.
|
||||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info."+(node.type==='tab'?'flow':'subflow'))+'</td><td></td></tr>').appendTo(tableBody);
|
propertiesPanelHeaderHelp.hide();
|
||||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
|
||||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.tabName")+"</td><td></td></tr>").appendTo(tableBody);
|
} else if (node.type === "group") {
|
||||||
$(propRow.children()[1]).text(node.label||node.name||"");
|
propertiesPanelHeaderHelp.hide();
|
||||||
if (node.type === "tab") {
|
|
||||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.status")+'</td><td></td></tr>').appendTo(tableBody);
|
propRow = $('<tr class="red-ui-help-info-row"><td> </td><td></td></tr>').appendTo(tableBody);
|
||||||
$(propRow.children()[1]).text((!!!node.disabled)?RED._("sidebar.info.enabled"):RED._("sidebar.info.disabled"))
|
|
||||||
|
var typeCounts = {
|
||||||
|
nodes:0,
|
||||||
|
groups: 0
|
||||||
}
|
}
|
||||||
|
var allNodes = RED.group.getNodes(node,true);
|
||||||
|
allNodes.forEach(function(n) {
|
||||||
|
if (n.type === "group") {
|
||||||
|
typeCounts.groups++;
|
||||||
|
} else {
|
||||||
|
typeCounts.nodes++
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var counts = $('<div>').appendTo($(propRow.children()[1]));
|
||||||
|
if (typeCounts.nodes > 0) {
|
||||||
|
$('<div>').text(RED._("clipboard.node",{count:typeCounts.nodes})).appendTo(counts);
|
||||||
|
}
|
||||||
|
if (typeCounts.groups > 0) {
|
||||||
|
$('<div>').text(RED._("clipboard.group",{count:typeCounts.groups})).appendTo(counts);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// An actual node is selected in the editor - build up its properties table
|
propertiesPanelHeaderHelp.show();
|
||||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.node")+"</td><td></td></tr>").appendTo(tableBody);
|
|
||||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
if (!subflowRegex) {
|
||||||
if (node.type !== "subflow" && node.type !== "unknown" && node.name) {
|
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.type")+'</td><td></td></tr>').appendTo(tableBody);
|
||||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("common.label.name")+'</td><td></td></tr>').appendTo(tableBody);
|
|
||||||
$('<span class="red-ui-text-bidi-aware" dir="'+RED.text.bidi.resolveBaseTextDir(node.name)+'"></span>').text(node.name).appendTo(propRow.children()[1]);
|
|
||||||
}
|
|
||||||
if (!m) {
|
|
||||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.type")+"</td><td></td></tr>").appendTo(tableBody);
|
|
||||||
$(propRow.children()[1]).text((node.type === "unknown")?node._orig.type:node.type);
|
$(propRow.children()[1]).text((node.type === "unknown")?node._orig.type:node.type);
|
||||||
if (node.type === "unknown") {
|
if (node.type === "unknown") {
|
||||||
$('<span style="float: right; font-size: 0.8em"><i class="fa fa-warning"></i></span>').prependTo($(propRow.children()[1]))
|
$('<span style="float: right; font-size: 0.8em"><i class="fa fa-warning"></i></span>').prependTo($(propRow.children()[1]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
if (!m && node.type != "subflow") {
|
if (!subflowRegex && node.type != "subflow" && node.type != "group") {
|
||||||
|
|
||||||
|
var blankRow = $('<tr class="red-ui-help-property-expand blank"><td colspan="2"></td></tr>').appendTo(tableBody);
|
||||||
|
|
||||||
var defaults;
|
var defaults;
|
||||||
if (node.type === 'unknown') {
|
if (node.type === 'unknown') {
|
||||||
defaults = {};
|
defaults = {};
|
||||||
@ -240,7 +329,6 @@ RED.sidebar.info = (function() {
|
|||||||
$(propRow.children()[1]).text(RED.nodes.getType(node.type).set.module);
|
$(propRow.children()[1]).text(RED.nodes.getType(node.type).set.module);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
$('<tr class="red-ui-help-property-expand red-ui-help-info-property-row blank'+(expandedSections.property?"":" hide")+'"><td colspan="2"></td></tr>').appendTo(tableBody);
|
|
||||||
|
|
||||||
if (defaults) {
|
if (defaults) {
|
||||||
for (var n in defaults) {
|
for (var n in defaults) {
|
||||||
@ -248,7 +336,8 @@ RED.sidebar.info = (function() {
|
|||||||
var val = node[n];
|
var val = node[n];
|
||||||
var type = typeof val;
|
var type = typeof val;
|
||||||
count++;
|
count++;
|
||||||
propRow = $('<tr class="red-ui-help-info-property-row'+(expandedSections.property?"":" hide")+'"><td>'+n+"</td><td></td></tr>").appendTo(tableBody);
|
propRow = $('<tr class="red-ui-help-info-property-row'+(expandedSections.property?"":" hide")+'"><td></td><td></td></tr>').appendTo(tableBody);
|
||||||
|
$(propRow.children()[0]).text(n);
|
||||||
if (defaults[n].type) {
|
if (defaults[n].type) {
|
||||||
var configNode = RED.nodes.node(val);
|
var configNode = RED.nodes.node(val);
|
||||||
if (!configNode) {
|
if (!configNode) {
|
||||||
@ -278,37 +367,35 @@ RED.sidebar.info = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
$('<tr class="red-ui-help-property-expand blank"><td colspan="2"><a href="#" class="node-info-property-header'+(expandedSections.property?" expanded":"")+'"><span class="red-ui-help-property-more">'+RED._("sidebar.info.showMore")+'</span><span class="red-ui-help-property-less">'+RED._("sidebar.info.showLess")+'</span> <i class="fa fa-caret-down"></i></a></td></tr>').appendTo(tableBody);
|
$('<a href="#" class="node-info-property-header'+(expandedSections.property?" expanded":"")+'"><span class="red-ui-help-property-more">'+RED._("sidebar.info.showMore")+'</span><span class="red-ui-help-property-less">'+RED._("sidebar.info.showLess")+'</span> <i class="fa fa-caret-down"></i></a>').appendTo(blankRow.children()[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node.type !== 'tab') {
|
if (node.type !== 'tab') {
|
||||||
if (m) {
|
if (subflowRegex) {
|
||||||
$('<tr class="blank"><th colspan="2">'+RED._("sidebar.info.subflow")+'</th></tr>').appendTo(tableBody);
|
$('<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="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(subflowNode.name)+'">'+RED.utils.sanitize(subflowNode.name)+'</span></td></tr>').appendTo(tableBody);
|
$('<tr class="node-info-subflow-row"><td>'+RED._("common.label.name")+'</td><td><span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(subflowNode.name)+'">'+RED.utils.sanitize(subflowNode.name)+'</span></td></tr>').appendTo(tableBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m) {
|
if (subflowRegex) {
|
||||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("subflow.category")+'</td><td></td></tr>').appendTo(tableBody);
|
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("subflow.category")+'</td><td></td></tr>').appendTo(tableBody);
|
||||||
var category = subflowNode.category||"subflows";
|
var category = subflowNode.category||"subflows";
|
||||||
$(propRow.children()[1]).text(RED._("palette.label."+category,{defaultValue:category}))
|
$(propRow.children()[1]).text(RED._("palette.label."+category,{defaultValue:category}))
|
||||||
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+subflowUserCount+'</td></tr>').appendTo(tableBody);
|
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+subflowUserCount+'</td></tr>').appendTo(tableBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
var helpText = "";
|
// var helpText = "";
|
||||||
if (node.type === "tab" || node.type === "subflow") {
|
// if (node.type === "tab" || node.type === "subflow") {
|
||||||
$(helpSection.container).hide();
|
// } else {
|
||||||
} else {
|
// if (subflowNode && node.type !== "subflow") {
|
||||||
$(helpSection.container).show();
|
// // Selected a subflow instance node.
|
||||||
if (subflowNode && node.type !== "subflow") {
|
// // - The subflow template info goes into help
|
||||||
// Selected a subflow instance node.
|
// helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
||||||
// - The subflow template info goes into help
|
// } else {
|
||||||
helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
// helpText = $("script[data-help-name='"+node.type+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||||
} else {
|
// }
|
||||||
helpText = $("script[data-help-name='"+node.type+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
// setInfoText(helpText, helpSection.content);
|
||||||
}
|
// }
|
||||||
setInfoText(helpText, helpSection.content);
|
|
||||||
}
|
|
||||||
|
|
||||||
var infoText = "";
|
var infoText = "";
|
||||||
|
|
||||||
@ -320,7 +407,26 @@ RED.sidebar.info = (function() {
|
|||||||
if (node.info) {
|
if (node.info) {
|
||||||
infoText = infoText + RED.utils.renderMarkdown(node.info || "")
|
infoText = infoText + RED.utils.renderMarkdown(node.info || "")
|
||||||
}
|
}
|
||||||
setInfoText(infoText, infoSection.content);
|
var infoSectionContainer = $("<div>").css("padding","0 6px 6px").appendTo(propertiesPanelContent)
|
||||||
|
|
||||||
|
// var editInfo = $('<button class="red-ui-button red-ui-button-small" style="float: right"><i class="fa fa-file-text-o"></button>').appendTo(infoSectionContainer).on("click", function(evt) {
|
||||||
|
// //.text(RED._("sidebar.info.editDescription"))
|
||||||
|
// evt.preventDefault();
|
||||||
|
// evt.stopPropagation();
|
||||||
|
// if (node.type === 'tab') {
|
||||||
|
//
|
||||||
|
// } else if (node.type === 'subflow') {
|
||||||
|
//
|
||||||
|
// } else if (node.type === 'group') {
|
||||||
|
//
|
||||||
|
// } else if (node._def.category !== 'config') {
|
||||||
|
// RED.editor.edit(node,"editor-tab-description");
|
||||||
|
// } else {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
setInfoText(infoText, infoSectionContainer);
|
||||||
|
|
||||||
$(".red-ui-sidebar-info-stack").scrollTop(0);
|
$(".red-ui-sidebar-info-stack").scrollTop(0);
|
||||||
$(".node-info-property-header").on("click", function(e) {
|
$(".node-info-property-header").on("click", function(e) {
|
||||||
@ -336,7 +442,7 @@ RED.sidebar.info = (function() {
|
|||||||
// propRow = $('<tr class="red-ui-help-info-row"><td>Actions</td><td></td></tr>').appendTo(tableBody);
|
// propRow = $('<tr class="red-ui-help-info-row"><td>Actions</td><td></td></tr>').appendTo(tableBody);
|
||||||
// var actionBar = $(propRow.children()[1]);
|
// var actionBar = $(propRow.children()[1]);
|
||||||
//
|
//
|
||||||
// // var actionBar = $('<div>',{style:"background: #fefefe; padding: 3px;"}).appendTo(propertiesSection.content);
|
// // var actionBar = $('<div>',{style:"background: #fefefe; padding: 3px;"}).appendTo(propertiesPanel);
|
||||||
// $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar);
|
// $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar);
|
||||||
// $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar);
|
// $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar);
|
||||||
// $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar);
|
// $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar);
|
||||||
@ -411,6 +517,7 @@ RED.sidebar.info = (function() {
|
|||||||
}
|
}
|
||||||
function startTips() {
|
function startTips() {
|
||||||
$(".red-ui-sidebar-info").addClass('show-tips');
|
$(".red-ui-sidebar-info").addClass('show-tips');
|
||||||
|
resizeStack();
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (!startTimeout && !refreshTimeout) {
|
if (!startTimeout && !refreshTimeout) {
|
||||||
if (tipCount === -1) {
|
if (tipCount === -1) {
|
||||||
@ -424,6 +531,7 @@ RED.sidebar.info = (function() {
|
|||||||
}
|
}
|
||||||
function stopTips() {
|
function stopTips() {
|
||||||
$(".red-ui-sidebar-info").removeClass('show-tips');
|
$(".red-ui-sidebar-info").removeClass('show-tips');
|
||||||
|
resizeStack();
|
||||||
clearInterval(refreshTimeout);
|
clearInterval(refreshTimeout);
|
||||||
clearTimeout(startTimeout);
|
clearTimeout(startTimeout);
|
||||||
refreshTimeout = null;
|
refreshTimeout = null;
|
||||||
@ -448,15 +556,8 @@ RED.sidebar.info = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function set(html,title) {
|
function set(html,title) {
|
||||||
// tips.stop();
|
console.warn("Deprecated use of RED.sidebar.info.set - use RED.sidebar.help.set instead")
|
||||||
// sections.show();
|
RED.sidebar.help.set(html,title);
|
||||||
refresh(null);
|
|
||||||
propertiesSection.container.hide();
|
|
||||||
helpSection.container.hide();
|
|
||||||
infoSection.container.show();
|
|
||||||
infoSection.title.text(title||RED._("sidebar.info.desc"));
|
|
||||||
setInfoText(html,infoSection.content);
|
|
||||||
$(".red-ui-sidebar-info-stack").scrollTop(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshSelection(selection) {
|
function refreshSelection(selection) {
|
||||||
|
@ -241,10 +241,13 @@ RED.typeSearch = (function() {
|
|||||||
$(document).off('mousedown.red-ui-type-search');
|
$(document).off('mousedown.red-ui-type-search');
|
||||||
$(document).off('mouseup.red-ui-type-search');
|
$(document).off('mouseup.red-ui-type-search');
|
||||||
$(document).off('click.red-ui-type-search');
|
$(document).off('click.red-ui-type-search');
|
||||||
|
$(document).off('touchstart.red-ui-type-search');
|
||||||
|
$(document).off('mousedown.red-ui-type-search');
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$(document).on('mousedown.red-ui-type-search',handleMouseActivity);
|
$(document).on('mousedown.red-ui-type-search',handleMouseActivity);
|
||||||
$(document).on('mouseup.red-ui-type-search',handleMouseActivity);
|
$(document).on('mouseup.red-ui-type-search',handleMouseActivity);
|
||||||
$(document).on('click.red-ui-type-search',handleMouseActivity);
|
$(document).on('click.red-ui-type-search',handleMouseActivity);
|
||||||
|
$(document).on('touchstart.red-ui-type-search',handleMouseActivity);
|
||||||
},200);
|
},200);
|
||||||
|
|
||||||
refreshTypeList(opts);
|
refreshTypeList(opts);
|
||||||
@ -260,7 +263,9 @@ RED.typeSearch = (function() {
|
|||||||
searchResultsDiv.slideDown(300);
|
searchResultsDiv.slideDown(300);
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
searchResultsDiv.find(".red-ui-editableList-container").scrollTop(0);
|
searchResultsDiv.find(".red-ui-editableList-container").scrollTop(0);
|
||||||
searchInput.trigger("focus");
|
if (!opts.disableFocus) {
|
||||||
|
searchInput.trigger("focus");
|
||||||
|
}
|
||||||
},100);
|
},100);
|
||||||
}
|
}
|
||||||
function hide(fast) {
|
function hide(fast) {
|
||||||
@ -279,6 +284,7 @@ RED.typeSearch = (function() {
|
|||||||
$(document).off('mousedown.red-ui-type-search');
|
$(document).off('mousedown.red-ui-type-search');
|
||||||
$(document).off('mouseup.red-ui-type-search');
|
$(document).off('mouseup.red-ui-type-search');
|
||||||
$(document).off('click.red-ui-type-search');
|
$(document).off('click.red-ui-type-search');
|
||||||
|
$(document).off('touchstart.red-ui-type-search');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getTypeLabel(type, def) {
|
function getTypeLabel(type, def) {
|
||||||
|
@ -806,9 +806,9 @@ RED.utils = (function() {
|
|||||||
function separateIconPath(icon) {
|
function separateIconPath(icon) {
|
||||||
var result = {module: "", file: ""};
|
var result = {module: "", file: ""};
|
||||||
if (icon) {
|
if (icon) {
|
||||||
var index = icon.indexOf('icons/');
|
var index = icon.indexOf(RED.settings.apiRootUrl+'icons/');
|
||||||
if (index !== -1) {
|
if (index === 0) {
|
||||||
icon = icon.substring(index+6);
|
icon = icon.substring((RED.settings.apiRootUrl+'icons/').length);
|
||||||
}
|
}
|
||||||
index = icon.indexOf('/');
|
index = icon.indexOf('/');
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
@ -859,10 +859,15 @@ RED.utils = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getNodeIcon(def,node) {
|
function getNodeIcon(def,node) {
|
||||||
if (def.category === 'config') {
|
if (node && node.type === '_selection_') {
|
||||||
|
return "font-awesome/fa-object-ungroup";
|
||||||
|
} else if (node && node.type === 'group') {
|
||||||
|
return "font-awesome/fa-object-group"
|
||||||
|
} else if (def.category === 'config') {
|
||||||
return RED.settings.apiRootUrl+"icons/node-red/cog.svg"
|
return RED.settings.apiRootUrl+"icons/node-red/cog.svg"
|
||||||
} else if (node && node.type === 'tab') {
|
} else if (node && node.type === 'tab') {
|
||||||
return RED.settings.apiRootUrl+"icons/node-red/subflow.svg"
|
return "red-ui-icons/red-ui-icons-flow"
|
||||||
|
// return RED.settings.apiRootUrl+"images/subflow_tab.svg"
|
||||||
} else if (node && node.type === 'unknown') {
|
} else if (node && node.type === 'unknown') {
|
||||||
return RED.settings.apiRootUrl+"icons/node-red/alert.svg"
|
return RED.settings.apiRootUrl+"icons/node-red/alert.svg"
|
||||||
} else if (node && node.icon) {
|
} else if (node && node.icon) {
|
||||||
@ -921,6 +926,8 @@ RED.utils = (function() {
|
|||||||
var l;
|
var l;
|
||||||
if (node.type === 'tab') {
|
if (node.type === 'tab') {
|
||||||
l = node.label || defaultLabel
|
l = node.label || defaultLabel
|
||||||
|
} else if (node.type === 'group') {
|
||||||
|
l = node.name || defaultLabel
|
||||||
} else {
|
} else {
|
||||||
l = node._def.label;
|
l = node._def.label;
|
||||||
try {
|
try {
|
||||||
@ -1054,11 +1061,63 @@ RED.utils = (function() {
|
|||||||
}
|
}
|
||||||
// If the specified name is not defined in font-awesome, show arrow-in icon.
|
// If the specified name is not defined in font-awesome, show arrow-in icon.
|
||||||
iconUrl = RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg"
|
iconUrl = RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg"
|
||||||
|
} else if (iconPath.module === "red-ui-icons") {
|
||||||
|
var redIconElement = $('<i/>').appendTo(iconContainer);
|
||||||
|
redIconElement.addClass("red-ui-palette-icon red-ui-icons " + iconPath.file);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
var imageIconElement = $('<div/>',{class:"red-ui-palette-icon"}).appendTo(iconContainer);
|
var imageIconElement = $('<div/>',{class:"red-ui-palette-icon"}).appendTo(iconContainer);
|
||||||
imageIconElement.css("backgroundImage", "url("+iconUrl+")");
|
imageIconElement.css("backgroundImage", "url("+iconUrl+")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createNodeIcon(node) {
|
||||||
|
var def = node._def;
|
||||||
|
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"})
|
||||||
|
if (node.type === "_selection_") {
|
||||||
|
nodeDiv.addClass("red-ui-palette-icon-selection");
|
||||||
|
} else if (node.type === "group") {
|
||||||
|
nodeDiv.addClass("red-ui-palette-icon-group");
|
||||||
|
} else if (node.type === 'tab') {
|
||||||
|
nodeDiv.addClass("red-ui-palette-icon-flow");
|
||||||
|
} else {
|
||||||
|
var colour = RED.utils.getNodeColor(node.type,def);
|
||||||
|
// if (node.type === 'tab') {
|
||||||
|
// colour = "#C0DEED";
|
||||||
|
// }
|
||||||
|
nodeDiv.css('backgroundColor',colour);
|
||||||
|
var borderColor = getDarkerColor(colour);
|
||||||
|
if (borderColor !== colour) {
|
||||||
|
nodeDiv.css('border-color',borderColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var icon_url = RED.utils.getNodeIcon(def,node);
|
||||||
|
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
||||||
|
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||||
|
return nodeDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDarkerColor(c) {
|
||||||
|
var r,g,b;
|
||||||
|
if (/^#[a-f0-9]{6}$/i.test(c)) {
|
||||||
|
r = parseInt(c.substring(1, 3), 16);
|
||||||
|
g = parseInt(c.substring(3, 5), 16);
|
||||||
|
b = parseInt(c.substring(5, 7), 16);
|
||||||
|
} else if (/^#[a-f0-9]{3}$/i.test(c)) {
|
||||||
|
r = parseInt(c.substring(1, 2)+c.substring(1, 2), 16);
|
||||||
|
g = parseInt(c.substring(2, 3)+c.substring(2, 3), 16);
|
||||||
|
b = parseInt(c.substring(3, 4)+c.substring(3, 4), 16);
|
||||||
|
} else {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
var l = 0.3 * r/255 + 0.59 * g/255 + 0.11 * b/255 ;
|
||||||
|
r = Math.max(0,r-50);
|
||||||
|
g = Math.max(0,g-50);
|
||||||
|
b = Math.max(0,b-50);
|
||||||
|
var s = ((r<<16) + (g<<8) + b).toString(16);
|
||||||
|
return '#'+'000000'.slice(0, 6-s.length)+s;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createObjectElement: buildMessageElement,
|
createObjectElement: buildMessageElement,
|
||||||
getMessageProperty: getMessageProperty,
|
getMessageProperty: getMessageProperty,
|
||||||
@ -1076,6 +1135,8 @@ RED.utils = (function() {
|
|||||||
parseContextKey: parseContextKey,
|
parseContextKey: parseContextKey,
|
||||||
createIconElement: createIconElement,
|
createIconElement: createIconElement,
|
||||||
sanitize: sanitize,
|
sanitize: sanitize,
|
||||||
renderMarkdown: renderMarkdown
|
renderMarkdown: renderMarkdown,
|
||||||
|
createNodeIcon: createNodeIcon,
|
||||||
|
getDarkerColor: getDarkerColor
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -67,9 +67,16 @@ RED.view.tools = (function() {
|
|||||||
|
|
||||||
function moveSelection(dx,dy) {
|
function moveSelection(dx,dy) {
|
||||||
if (moving_set === null) {
|
if (moving_set === null) {
|
||||||
|
moving_set = [];
|
||||||
var selection = RED.view.selection();
|
var selection = RED.view.selection();
|
||||||
if (selection.nodes) {
|
if (selection.nodes) {
|
||||||
moving_set = selection.nodes.map(function(n) { return {n:n}});
|
while (selection.nodes.length > 0) {
|
||||||
|
var n = selection.nodes.shift();
|
||||||
|
moving_set.push({n:n});
|
||||||
|
if (n.type === "group") {
|
||||||
|
selection.nodes = selection.nodes.concat(n.nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (moving_set && moving_set.length > 0) {
|
if (moving_set && moving_set.length > 0) {
|
||||||
@ -93,10 +100,15 @@ RED.view.tools = (function() {
|
|||||||
node.n.x += dx;
|
node.n.x += dx;
|
||||||
node.n.y += dy;
|
node.n.y += dy;
|
||||||
node.n.dirty = true;
|
node.n.dirty = true;
|
||||||
minX = Math.min(node.n.x-node.n.w/2-5,minX);
|
if (node.n.type === "group") {
|
||||||
minY = Math.min(node.n.y-node.n.h/2-5,minY);
|
RED.group.markDirty(node.n);
|
||||||
|
minX = Math.min(node.n.x - 5,minX);
|
||||||
|
minY = Math.min(node.n.y - 5,minY);
|
||||||
|
} else {
|
||||||
|
minX = Math.min(node.n.x-node.n.w/2-5,minX);
|
||||||
|
minY = Math.min(node.n.y-node.n.h/2-5,minY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minX !== 0 || minY !== 0) {
|
if (minX !== 0 || minY !== 0) {
|
||||||
for (var n = 0; n<moving_set.length; n++) {
|
for (var n = 0; n<moving_set.length; n++) {
|
||||||
node = moving_set[n];
|
node = moving_set[n];
|
||||||
@ -105,13 +117,86 @@ RED.view.tools = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
RED.view.redraw();
|
RED.view.redraw();
|
||||||
|
} else {
|
||||||
|
RED.view.scroll(dx*10,dy*10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSelectedNodeLabelState(labelShown) {
|
||||||
|
var selection = RED.view.selection();
|
||||||
|
var historyEvents = [];
|
||||||
|
var nodes = [];
|
||||||
|
if (selection.nodes) {
|
||||||
|
selection.nodes.forEach(function(n) {
|
||||||
|
if (n.type !== 'subflow' && n.type !== 'group') {
|
||||||
|
nodes.push(n);
|
||||||
|
} else if (n.type === 'group') {
|
||||||
|
nodes = nodes.concat( RED.group.getNodes(n,true));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
nodes.forEach(function(n) {
|
||||||
|
var modified = false;
|
||||||
|
var oldValue = n.l === undefined?true:n.l;
|
||||||
|
var isLink = /^link (in|out)$/.test(n._def.type);
|
||||||
|
|
||||||
|
if (labelShown) {
|
||||||
|
if (n.l === false || (isLink && !n.hasOwnProperty('l'))) {
|
||||||
|
n.l = true;
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((!isLink && (!n.hasOwnProperty('l') || n.l === true)) || (isLink && n.l === true) ) {
|
||||||
|
n.l = false;
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (modified) {
|
||||||
|
historyEvents.push({
|
||||||
|
t: "edit",
|
||||||
|
node: n,
|
||||||
|
changed: n.changed,
|
||||||
|
changes: {
|
||||||
|
l: oldValue
|
||||||
|
}
|
||||||
|
})
|
||||||
|
n.changed = true;
|
||||||
|
n.dirty = true;
|
||||||
|
n.resize = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (historyEvents.length > 0) {
|
||||||
|
RED.history.push({
|
||||||
|
t: "multi",
|
||||||
|
events: historyEvents,
|
||||||
|
dirty: RED.nodes.dirty()
|
||||||
|
})
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RED.view.redraw();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: function() {
|
init: function() {
|
||||||
|
RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); })
|
||||||
|
RED.actions.add("core:hide-selected-node-labels", function() { setSelectedNodeLabelState(false); })
|
||||||
|
|
||||||
RED.actions.add("core:align-selection-to-grid", alignToGrid);
|
RED.actions.add("core:align-selection-to-grid", alignToGrid);
|
||||||
|
|
||||||
|
RED.actions.add("core:scroll-view-up", function() { RED.view.scroll(0,-RED.view.gridSize());});
|
||||||
|
RED.actions.add("core:scroll-view-right", function() { RED.view.scroll(RED.view.gridSize(),0);});
|
||||||
|
RED.actions.add("core:scroll-view-down", function() { RED.view.scroll(0,RED.view.gridSize());});
|
||||||
|
RED.actions.add("core:scroll-view-left", function() { RED.view.scroll(-RED.view.gridSize(),0);});
|
||||||
|
|
||||||
|
RED.actions.add("core:step-view-up", function() { RED.view.scroll(0,-5*RED.view.gridSize());});
|
||||||
|
RED.actions.add("core:step-view-right", function() { RED.view.scroll(5*RED.view.gridSize(),0);});
|
||||||
|
RED.actions.add("core:step-view-down", function() { RED.view.scroll(0,5*RED.view.gridSize());});
|
||||||
|
RED.actions.add("core:step-view-left", function() { RED.view.scroll(-5*RED.view.gridSize(),0);});
|
||||||
|
|
||||||
RED.actions.add("core:move-selection-up", function() { moveSelection(0,-1);});
|
RED.actions.add("core:move-selection-up", function() { moveSelection(0,-1);});
|
||||||
RED.actions.add("core:move-selection-right", function() { moveSelection(1,0);});
|
RED.actions.add("core:move-selection-right", function() { moveSelection(1,0);});
|
||||||
RED.actions.add("core:move-selection-down", function() { moveSelection(0,1);});
|
RED.actions.add("core:move-selection-down", function() { moveSelection(0,1);});
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -128,10 +128,6 @@ RED.workspaces = (function() {
|
|||||||
RED.history.push(historyEvent);
|
RED.history.push(historyEvent);
|
||||||
RED.nodes.dirty(true);
|
RED.nodes.dirty(true);
|
||||||
RED.sidebar.config.refresh();
|
RED.sidebar.config.refresh();
|
||||||
var selection = RED.view.selection();
|
|
||||||
if (!selection.nodes && !selection.links) {
|
|
||||||
RED.sidebar.info.refresh(workspace);
|
|
||||||
}
|
|
||||||
if (changes.hasOwnProperty('disabled')) {
|
if (changes.hasOwnProperty('disabled')) {
|
||||||
RED.nodes.eachNode(function(n) {
|
RED.nodes.eachNode(function(n) {
|
||||||
if (n.z === workspace.id) {
|
if (n.z === workspace.id) {
|
||||||
@ -140,6 +136,7 @@ RED.workspaces = (function() {
|
|||||||
});
|
});
|
||||||
RED.view.redraw();
|
RED.view.redraw();
|
||||||
}
|
}
|
||||||
|
RED.events.emit("flows:change",workspace);
|
||||||
}
|
}
|
||||||
RED.tray.close();
|
RED.tray.close();
|
||||||
}
|
}
|
||||||
@ -219,7 +216,10 @@ RED.workspaces = (function() {
|
|||||||
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
||||||
RED.view.state(RED.state.DEFAULT);
|
RED.view.state(RED.state.DEFAULT);
|
||||||
}
|
}
|
||||||
RED.sidebar.info.refresh(workspace);
|
var selection = RED.view.selection();
|
||||||
|
if (!selection.nodes && !selection.links && workspace.id === activeWorkspace) {
|
||||||
|
RED.sidebar.info.refresh(workspace);
|
||||||
|
}
|
||||||
tabflowEditor.destroy();
|
tabflowEditor.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,7 +371,9 @@ RED.workspaces = (function() {
|
|||||||
var changes = { disabled: workspace.disabled };
|
var changes = { disabled: workspace.disabled };
|
||||||
workspace.disabled = disabled;
|
workspace.disabled = disabled;
|
||||||
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
|
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
|
||||||
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
|
if (id === activeWorkspace) {
|
||||||
|
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
|
||||||
|
}
|
||||||
var historyEvent = {
|
var historyEvent = {
|
||||||
t: "edit",
|
t: "edit",
|
||||||
changes:changes,
|
changes:changes,
|
||||||
@ -380,10 +382,11 @@ RED.workspaces = (function() {
|
|||||||
}
|
}
|
||||||
workspace.changed = true;
|
workspace.changed = true;
|
||||||
RED.history.push(historyEvent);
|
RED.history.push(historyEvent);
|
||||||
|
RED.events.emit("flows:change",workspace);
|
||||||
RED.nodes.dirty(true);
|
RED.nodes.dirty(true);
|
||||||
RED.sidebar.config.refresh();
|
RED.sidebar.config.refresh();
|
||||||
var selection = RED.view.selection();
|
var selection = RED.view.selection();
|
||||||
if (!selection.nodes && !selection.links) {
|
if (!selection.nodes && !selection.links && workspace.id === activeWorkspace) {
|
||||||
RED.sidebar.info.refresh(workspace);
|
RED.sidebar.info.refresh(workspace);
|
||||||
}
|
}
|
||||||
if (changes.hasOwnProperty('disabled')) {
|
if (changes.hasOwnProperty('disabled')) {
|
||||||
@ -412,9 +415,14 @@ RED.workspaces = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setWorkspaceOrder(order) {
|
function setWorkspaceOrder(order) {
|
||||||
RED.nodes.setWorkspaceOrder(order.filter(function(id) {
|
var newOrder = order.filter(function(id) {
|
||||||
return RED.nodes.workspace(id) !== undefined;
|
return RED.nodes.workspace(id) !== undefined;
|
||||||
}));
|
})
|
||||||
|
var currentOrder = RED.nodes.getWorkspaceOrder();
|
||||||
|
if (JSON.stringify(newOrder) !== JSON.stringify(currentOrder)) {
|
||||||
|
RED.nodes.setWorkspaceOrder(newOrder);
|
||||||
|
RED.events.emit("flows:reorder",newOrder);
|
||||||
|
}
|
||||||
workspace_tabs.order(order);
|
workspace_tabs.order(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,19 +9,15 @@
|
|||||||
color: transparent !important;
|
color: transparent !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.ace_gutter {
|
.ace_gutter {
|
||||||
|
background: $text-editor-gutter-background;
|
||||||
border-top-left-radius: 4px;
|
border-top-left-radius: 4px;
|
||||||
border-bottom-left-radius: 4px;
|
border-bottom-left-radius: 4px;
|
||||||
}
|
}
|
||||||
.ace_scroller {
|
.ace_scroller {
|
||||||
|
background: $text-editor-background;
|
||||||
border-top-right-radius: 4px;
|
border-top-right-radius: 4px;
|
||||||
border-bottom-right-radius: 4px;
|
border-bottom-right-radius: 4px;
|
||||||
}
|
|
||||||
|
|
||||||
.ace_scroller {
|
|
||||||
background: $text-editor-background;
|
|
||||||
color: $text-editor-color;
|
color: $text-editor-color;
|
||||||
}
|
}
|
||||||
.ace_marker-layer .ace_active-line {
|
.ace_marker-layer .ace_active-line {
|
||||||
@ -37,9 +33,6 @@
|
|||||||
.ace_gutter-active-line {
|
.ace_gutter-active-line {
|
||||||
background: $text-editor-gutter-active-line-background;
|
background: $text-editor-gutter-active-line-background;
|
||||||
}
|
}
|
||||||
.ace_gutter {
|
|
||||||
background: $text-editor-gutter-background;
|
|
||||||
}
|
|
||||||
.ace_tooltip {
|
.ace_tooltip {
|
||||||
font-family: $primary-font;
|
font-family: $primary-font;
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
|
@ -67,6 +67,9 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: $primary-text-color;
|
color: $primary-text-color;
|
||||||
}
|
}
|
||||||
|
a:focus {
|
||||||
|
outline: 1px solid $form-input-focus-color;
|
||||||
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
|
@ -23,7 +23,7 @@ $primary-background: #f3f3f3;//#0ff;
|
|||||||
$secondary-background: #fff;//#ff0;
|
$secondary-background: #fff;//#ff0;
|
||||||
$secondary-background-selected: #efefef;//#e9e900;
|
$secondary-background-selected: #efefef;//#e9e900;
|
||||||
$secondary-background-inactive: #f0f0f0;//#f0f000;
|
$secondary-background-inactive: #f0f0f0;//#f0f000;
|
||||||
$secondary-background-hover: #ddd;//#dd0;
|
$secondary-background-hover: #e6e6e6;//#dd0;
|
||||||
$secondary-background-disabled: #f9f9f9;//#fafa0;
|
$secondary-background-disabled: #f9f9f9;//#fafa0;
|
||||||
|
|
||||||
$tertiary-background: #f7f7f7;//#f0f;
|
$tertiary-background: #f7f7f7;//#f0f;
|
||||||
@ -94,7 +94,7 @@ $list-item-secondary-color: $secondary-text-color;
|
|||||||
$list-item-background: $secondary-background;
|
$list-item-background: $secondary-background;
|
||||||
$list-item-background-disabled: $secondary-background-inactive;
|
$list-item-background-disabled: $secondary-background-inactive;
|
||||||
$list-item-background-hover: $secondary-background-hover;
|
$list-item-background-hover: $secondary-background-hover;
|
||||||
$list-item-background-selected: $secondary-background-selected;
|
$list-item-background-selected: #ffebc7; // #fff1e5;
|
||||||
$list-item-border-selected: $secondary-text-color-selected;
|
$list-item-border-selected: $secondary-text-color-selected;
|
||||||
|
|
||||||
$tab-text-color-active: $header-text-color;
|
$tab-text-color-active: $header-text-color;
|
||||||
@ -129,7 +129,7 @@ $workspace-button-color-primary: #eee;
|
|||||||
$workspace-button-background-primary: #AD1625;
|
$workspace-button-background-primary: #AD1625;
|
||||||
$workspace-button-background-primary-hover: #6E0A1E;
|
$workspace-button-background-primary-hover: #6E0A1E;
|
||||||
|
|
||||||
$workspace-button-color-focus-outline: $form-input-border-color;
|
$workspace-button-color-focus-outline: $form-input-focus-color;
|
||||||
|
|
||||||
$shade-color: rgba(160,160,160,0.5);
|
$shade-color: rgba(160,160,160,0.5);
|
||||||
|
|
||||||
@ -284,3 +284,8 @@ $debug-message-border: #eee;
|
|||||||
$debug-message-border-hover: #999;
|
$debug-message-border-hover: #999;
|
||||||
$debug-message-border-warning: #ffdf9d;
|
$debug-message-border-warning: #ffdf9d;
|
||||||
$debug-message-border-error: #f99;
|
$debug-message-border-error: #f99;
|
||||||
|
|
||||||
|
$group-default-fill: none;
|
||||||
|
$group-default-fill-opacity: 1;
|
||||||
|
$group-default-stroke: #999;
|
||||||
|
$group-default-stroke-opacity: 1;
|
||||||
|
@ -175,3 +175,38 @@
|
|||||||
.red-ui-menu-dropdown-submenu.disabled > a:before {
|
.red-ui-menu-dropdown-submenu.disabled > a:before {
|
||||||
border-right-color: $menuCaret;
|
border-right-color: $menuCaret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Menu NG
|
||||||
|
ul.red-ui-menu:not(.red-ui-menu-dropdown) {
|
||||||
|
font-family: $primary-font;
|
||||||
|
font-size: 12px;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
li a {
|
||||||
|
display: block;
|
||||||
|
padding: 4px 8px 4px 16px;
|
||||||
|
clear: both;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 20px;
|
||||||
|
color: $menuColor;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover,&:focus {
|
||||||
|
color: $menuHoverColor;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: $menuHoverBackground;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.red-ui-menu-compact {
|
||||||
|
font-size: 12px;
|
||||||
|
li a {
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -304,9 +304,6 @@ button.red-ui-button-small
|
|||||||
&:first-child {
|
&:first-child {
|
||||||
padding: 20px 20px 0;
|
padding: 20px 20px 0;
|
||||||
}
|
}
|
||||||
&:last-child {
|
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.red-ui-editor-type-expression-tab-content {
|
.red-ui-editor-type-expression-tab-content {
|
||||||
@ -411,6 +408,133 @@ button.red-ui-button.red-ui-editor-node-appearance-button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red-ui-group-layout-picker {
|
||||||
|
padding: 5px;
|
||||||
|
background: $secondary-background;
|
||||||
|
}
|
||||||
|
.red-ui-group-layout-picker-cell-text {
|
||||||
|
position: absolute;
|
||||||
|
width: 14px;
|
||||||
|
height: 2px;
|
||||||
|
border-top: 2px solid $secondary-text-color;
|
||||||
|
border-bottom: 2px solid $secondary-text-color;
|
||||||
|
margin: 2px;
|
||||||
|
|
||||||
|
&.red-ui-group-layout-text-pos-nw { top: 0; left: 0; }
|
||||||
|
&.red-ui-group-layout-text-pos-n { top: 0; left: calc(50% - 9px); }
|
||||||
|
&.red-ui-group-layout-text-pos-ne { top: 0; right: 0; }
|
||||||
|
&.red-ui-group-layout-text-pos-sw { bottom: 0; left: 0; }
|
||||||
|
&.red-ui-group-layout-text-pos-s { bottom: 0; left: calc(50% - 9px); }
|
||||||
|
&.red-ui-group-layout-text-pos-se { bottom: 0; right: 0; }
|
||||||
|
&.red-ui-group-layout-text-pos- {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 0;
|
||||||
|
background-color: #FFF;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0, 50% 50%;
|
||||||
|
background-image: linear-gradient(45deg, transparent 45%, $secondary-border-color 45%, $secondary-border-color 55%, transparent 55%, transparent),linear-gradient(-45deg, transparent 45%, $secondary-border-color 45%, $secondary-border-color 55%, transparent 55%, transparent);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-group-layout-picker button.red-ui-search-result-node {
|
||||||
|
float: none;
|
||||||
|
position: relative;
|
||||||
|
padding: 0;
|
||||||
|
margin: 5px;
|
||||||
|
width: 32px;
|
||||||
|
height: 27px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.red-ui-group-layout-picker-none {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-color-picker {
|
||||||
|
input[type="text"] {
|
||||||
|
border-radius:0;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid $form-input-border-color;
|
||||||
|
}
|
||||||
|
small {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 35px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
background: $primary-background;
|
||||||
|
}
|
||||||
|
.red-ui-editor-node-appearance-button {
|
||||||
|
.red-ui-search-result-node {
|
||||||
|
overflow: hidden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-color-picker-cell {
|
||||||
|
padding: 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: $secondary-border-color;
|
||||||
|
}
|
||||||
|
.red-ui-color-picker-swatch {
|
||||||
|
position: absolute;
|
||||||
|
top:-1px;right:-1px;left:-1px;bottom:-1px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-color-picker-cell-none {
|
||||||
|
height: 100%;
|
||||||
|
background-color: #FFF;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: 0 0, 50% 50%;
|
||||||
|
background-image: linear-gradient(45deg, transparent 45%, $secondary-border-color 45%, $secondary-border-color 55%, transparent 55%, transparent),linear-gradient(-45deg, transparent 45%, $secondary-border-color 45%, $secondary-border-color 55%, transparent 55%, transparent)
|
||||||
|
}
|
||||||
|
.red-ui-search-result-node .red-ui-color-picker-cell-none {
|
||||||
|
border-radius: 4px;
|
||||||
|
background-size: 50% 50%;
|
||||||
|
background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee), linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee);
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-color-picker-opacity-slider {
|
||||||
|
position:relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
height: 14px;
|
||||||
|
margin: 6px 3px 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: white;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 25%),
|
||||||
|
linear-gradient(-45deg, #eee 25%, transparent 25%, transparent 75%, #eee 25%);
|
||||||
|
background-size: 6px 6px;
|
||||||
|
}
|
||||||
|
.red-ui-color-picker-opacity-slider-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top:0;right:0;left:0;bottom:0;
|
||||||
|
background-image:linear-gradient(90deg, transparent 0%, #f00 100%);
|
||||||
|
background-size: 100% 100%;
|
||||||
|
border: 1px solid $primary-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.red-ui-button-small.red-ui-color-picker-opacity-slider-handle {
|
||||||
|
z-Index: 10;
|
||||||
|
top: -4px;
|
||||||
|
cursor: pointer;
|
||||||
|
min-width: 0;
|
||||||
|
width: 10px;
|
||||||
|
height: 22px;
|
||||||
|
padding: 0;
|
||||||
|
border: 1px solid $primary-border-color;
|
||||||
|
border-radius: 1px;
|
||||||
|
background: $secondary-background;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
.red-ui-icon-picker {
|
.red-ui-icon-picker {
|
||||||
select {
|
select {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -591,6 +715,9 @@ button.red-ui-button.red-ui-editor-node-appearance-button {
|
|||||||
|
|
||||||
button.red-ui-toggleButton.toggle {
|
button.red-ui-toggleButton.toggle {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
i {
|
||||||
|
min-width: 15px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -704,8 +831,18 @@ span.red-ui-editor-subflow-env-lang-icon {
|
|||||||
right: 4px;
|
right: 4px;
|
||||||
border-top-right-radius: 4px;
|
border-top-right-radius: 4px;
|
||||||
border-bottom-right-radius: 4px;
|
border-bottom-right-radius: 4px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red-ui-editor-subflow-env-input-type {
|
||||||
|
background: $secondary-background;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.red-ui-editor-subflow-env-input-type-placeholder {
|
||||||
|
color: $tertiary-text-color;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
// .red-ui-editor-subflow-ui-grid {
|
// .red-ui-editor-subflow-ui-grid {
|
||||||
// width: 100%;
|
// width: 100%;
|
||||||
// .red-ui-editableList-container {
|
// .red-ui-editableList-container {
|
||||||
|
@ -35,13 +35,21 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
@include disable-selection;
|
@include disable-selection;
|
||||||
|
|
||||||
|
.red-ui-flow-node-label-text {
|
||||||
|
dominant-baseline: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.red-ui-flow-node-label-right .red-ui-flow-node-label-text {
|
||||||
|
text-anchor: end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-flow-port-label {
|
.red-ui-flow-port-label {
|
||||||
stroke-width: 0;
|
stroke-width: 0;
|
||||||
fill: $secondary-text-color;
|
fill: $secondary-text-color;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
alignment-baseline: middle;
|
dominant-baseline: middle;
|
||||||
text-anchor: middle;
|
text-anchor: middle;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
@ -71,6 +79,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red-ui-flow-group {
|
||||||
|
&.red-ui-flow-group-hovered {
|
||||||
|
.red-ui-flow-group-outline-select {
|
||||||
|
stroke-opacity: 0.8 !important;
|
||||||
|
stroke-dasharray: 10 4 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.red-ui-flow-group-active-hovered:not(.red-ui-flow-group-hovered) {
|
||||||
|
.red-ui-flow-group-outline-select {
|
||||||
|
stroke: $link-link-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-flow-group-outline {
|
||||||
|
fill: none;
|
||||||
|
stroke: $node-selected-color;
|
||||||
|
stroke-opacity: 0;
|
||||||
|
stroke-width: 12;
|
||||||
|
pointer-events: stroke;
|
||||||
|
}
|
||||||
|
.red-ui-flow-group-outline-select {
|
||||||
|
fill: none;
|
||||||
|
stroke: $node-selected-color;
|
||||||
|
pointer-events: stroke;
|
||||||
|
stroke-opacity: 0;
|
||||||
|
stroke-width: 3;
|
||||||
|
}
|
||||||
|
.red-ui-flow-group-body {
|
||||||
|
pointer-events: none;
|
||||||
|
fill: $group-default-fill;
|
||||||
|
fill-opacity: $group-default-fill-opacity;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke: $group-default-stroke;
|
||||||
|
stroke-opacity: $group-default-stroke-opacity;
|
||||||
|
}
|
||||||
|
.red-ui-flow-group-label {
|
||||||
|
@include disable-selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.red-ui-flow-node-unknown {
|
.red-ui-flow-node-unknown {
|
||||||
stroke-dasharray:10,4;
|
stroke-dasharray:10,4;
|
||||||
stroke: $node-border-unknown;
|
stroke: $node-border-unknown;
|
||||||
@ -103,6 +153,15 @@
|
|||||||
|
|
||||||
.red-ui-flow-node-button {
|
.red-ui-flow-node-button {
|
||||||
fill: inherit;
|
fill: inherit;
|
||||||
|
&.red-ui-flow-node-button-disabled {
|
||||||
|
opacity: 0.4;
|
||||||
|
.red-ui-flow-node-button-button {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-flow-node-button-button {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.red-ui-flow-node-button-background {
|
.red-ui-flow-node-button-background {
|
||||||
fill: $node-background-placeholder;
|
fill: $node-background-placeholder;
|
||||||
@ -166,6 +225,9 @@ g.red-ui-flow-node-selected {
|
|||||||
fill-opacity: 1;
|
fill-opacity: 1;
|
||||||
stroke-dasharray: none;
|
stroke-dasharray: none;
|
||||||
}
|
}
|
||||||
|
.red-ui-flow-group, .red-ui-flow-group-body {
|
||||||
|
stroke-dasharray: 8, 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.red-ui-flow-node-disabled {
|
.red-ui-flow-node-disabled {
|
||||||
&.red-ui-flow-node, .red-ui-flow-node {
|
&.red-ui-flow-node, .red-ui-flow-node {
|
||||||
@ -248,6 +310,7 @@ g.red-ui-flow-node-selected {
|
|||||||
|
|
||||||
.red-ui-flow-link-outline {
|
.red-ui-flow-link-outline {
|
||||||
stroke: $view-background;
|
stroke: $view-background;
|
||||||
|
stroke-opacity: 0.4;
|
||||||
stroke-width: 5;
|
stroke-width: 5;
|
||||||
cursor: crosshair;
|
cursor: crosshair;
|
||||||
fill: none;
|
fill: none;
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-family: $monospace-font !important;
|
font-family: $monospace-font !important;
|
||||||
font-size: 13px !important;
|
font-size: 13px !important;
|
||||||
height: 300px;
|
height: 100%;
|
||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
background: $clipboard-textarea-background;
|
background: $clipboard-textarea-background;
|
||||||
@ -62,6 +62,7 @@
|
|||||||
background: $form-input-background;
|
background: $form-input-background;
|
||||||
&>div {
|
&>div {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.red-ui-clipboard-dialog-box {
|
.red-ui-clipboard-dialog-box {
|
||||||
|
@ -186,6 +186,21 @@
|
|||||||
background-size: contain;
|
background-size: contain;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
.red-ui-search-result-node {
|
||||||
|
&.red-ui-palette-icon-flow,
|
||||||
|
&.red-ui-palette-icon-group,
|
||||||
|
&.red-ui-palette-icon-selection {
|
||||||
|
background: none;
|
||||||
|
border-color: transparent;
|
||||||
|
.red-ui-palette-icon-container {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
.red-ui-palette-icon-fa {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.red-ui-palette-icon-fa {
|
.red-ui-palette-icon-fa {
|
||||||
color: white;
|
color: white;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -22,9 +22,19 @@
|
|||||||
// border: 1px solid red;
|
// border: 1px solid red;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
>.red-ui-panel:first-child {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
>.red-ui-panel:last-child {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-panels-separator {
|
.red-ui-panels-separator {
|
||||||
|
flex: 0 0 auto;
|
||||||
border-top: 1px solid $secondary-border-color;
|
border-top: 1px solid $secondary-border-color;
|
||||||
border-bottom: 1px solid $secondary-border-color;
|
border-bottom: 1px solid $secondary-border-color;
|
||||||
height: 7px;
|
height: 7px;
|
||||||
@ -37,10 +47,13 @@
|
|||||||
.red-ui-panel {
|
.red-ui-panel {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
height: calc(50% - 4px);
|
height: calc(50% - 4px);
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-panels.red-ui-panels-horizontal {
|
.red-ui-panels.red-ui-panels-horizontal {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
&>.red-ui-panel {
|
&>.red-ui-panel {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -150,6 +150,16 @@
|
|||||||
|
|
||||||
.red-ui-popover a.red-ui-button,
|
.red-ui-popover a.red-ui-button,
|
||||||
.red-ui-popover button.red-ui-button {
|
.red-ui-popover button.red-ui-button {
|
||||||
|
&:not(.primary) {
|
||||||
|
border-color: $popover-button-border-color;
|
||||||
|
background: $popover-background;
|
||||||
|
color: $popover-color !important;
|
||||||
|
}
|
||||||
|
&:not(.primary):not(.disabled):not(.ui-button-disabled):hover {
|
||||||
|
border-color: $popover-button-border-color-hover;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
&.primary {
|
&.primary {
|
||||||
border-color: $popover-button-border-color;
|
border-color: $popover-button-border-color;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,12 @@
|
|||||||
.red-ui-editableList-container {
|
.red-ui-editableList-container {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
padding: 0;
|
||||||
|
.red-ui-projects-dialog-box {
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 25px 25px 10px 25px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#red-ui-project-settings-tab-settings {
|
#red-ui-project-settings-tab-settings {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
@ -99,6 +104,7 @@
|
|||||||
.red-ui-projects-dialog-screen-create {
|
.red-ui-projects-dialog-screen-create {
|
||||||
min-height: 500px;
|
min-height: 500px;
|
||||||
button.red-ui-projects-dialog-screen-create-type {
|
button.red-ui-projects-dialog-screen-create-type {
|
||||||
|
position: relative;
|
||||||
height: auto;
|
height: auto;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
@ -169,9 +175,14 @@
|
|||||||
.red-ui-projects-dialog-project-list-container {
|
.red-ui-projects-dialog-project-list-container {
|
||||||
border: 1px solid $secondary-border-color;
|
border: 1px solid $secondary-border-color;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.red-ui-search-container {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.red-ui-projects-dialog-project-list-inner-container {
|
.red-ui-projects-dialog-project-list-inner-container {
|
||||||
height: 300px;
|
flex-grow: 1 ;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
position:relative;
|
position:relative;
|
||||||
.red-ui-editableList-border {
|
.red-ui-editableList-border {
|
||||||
@ -254,6 +265,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.red-ui-projects-dialog-project-list-entry-delete-confirm {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 100%;
|
||||||
|
width: 1000px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 5px 20px;
|
||||||
|
background: $secondary-background;
|
||||||
|
transition: left 0.4s;
|
||||||
|
white-space: nowrap;
|
||||||
|
> span {
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-projects-dialog-screen-create-type {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
.red-ui-projects-dialog-screen-create-type.red-ui-button.toggle.selected:not(.disabled):not(:disabled) {
|
.red-ui-projects-dialog-screen-create-type.red-ui-button.toggle.selected:not(.disabled):not(:disabled) {
|
||||||
color: $secondary-text-color-active !important;
|
color: $secondary-text-color-active !important;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,17 @@
|
|||||||
top: 0px;
|
top: 0px;
|
||||||
border: 1px solid $primary-border-color;
|
border: 1px solid $primary-border-color;
|
||||||
box-shadow: 0 0 10px $shadow;
|
box-shadow: 0 0 10px $shadow;
|
||||||
|
background: $secondary-background;
|
||||||
|
|
||||||
|
.red-ui-searchBox-container {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 6px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.red-ui-type-search) .red-ui-searchBox-container {
|
||||||
|
width: calc(100% - 30px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-type-search {
|
.red-ui-type-search {
|
||||||
@ -39,6 +50,7 @@
|
|||||||
border: 1px dashed $primary-border-color;
|
border: 1px dashed $primary-border-color;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.red-ui-search-results-container {
|
.red-ui-search-results-container {
|
||||||
display: none;
|
display: none;
|
||||||
@ -87,6 +99,8 @@
|
|||||||
}
|
}
|
||||||
.red-ui-palette-icon {
|
.red-ui-palette-icon {
|
||||||
width: 15px;
|
width: 15px;
|
||||||
|
position:relative;
|
||||||
|
left: -1px;
|
||||||
}
|
}
|
||||||
.red-ui-search-result-description {
|
.red-ui-search-result-description {
|
||||||
margin-left:28px;
|
margin-left:28px;
|
||||||
@ -153,7 +167,7 @@
|
|||||||
width: 30px;
|
width: 30px;
|
||||||
float:left;
|
float:left;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
border-radius: 5px;
|
border-radius: 3px;
|
||||||
border: 1px solid $node-border;
|
border: 1px solid $node-border;
|
||||||
background-position: 5% 50%;
|
background-position: 5% 50%;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
@import "tab-config";
|
@import "tab-config";
|
||||||
@import "tab-context";
|
@import "tab-context";
|
||||||
@import "tab-info";
|
@import "tab-info";
|
||||||
|
@import "tab-help";
|
||||||
@import "popover";
|
@import "popover";
|
||||||
@import "flow";
|
@import "flow";
|
||||||
@import "palette-editor";
|
@import "palette-editor";
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y:auto;
|
overflow-y:auto;
|
||||||
@include disable-selection;
|
@include disable-selection;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.red-ui-sidebar-node-config-list {
|
ul.red-ui-sidebar-node-config-list {
|
||||||
|
27
packages/node_modules/@node-red/editor-client/src/sass/tab-help.scss
vendored
Normal file
27
packages/node_modules/@node-red/editor-client/src/sass/tab-help.scss
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
.red-ui-sidebar-help-stack {
|
||||||
|
// height: calc(100% - 39px);
|
||||||
|
}
|
||||||
|
.red-ui-help-search {
|
||||||
|
border-bottom: 1px solid $secondary-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-sidebar-help-toc {
|
||||||
|
.red-ui-treeList-label {
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 2px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#red-ui-sidebar-help-show-toc {
|
||||||
|
i.fa-angle-right {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
&.selected {
|
||||||
|
i.fa-angle-right {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,9 +14,25 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
.red-ui-sidebar-info {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
.red-ui-sidebar-info hr {
|
.red-ui-sidebar-info hr {
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
.red-ui-info-header {
|
||||||
|
padding-left: 9px;
|
||||||
|
line-height: 21px;
|
||||||
|
cursor: default;
|
||||||
|
> * {
|
||||||
|
vertical-align: middle
|
||||||
|
}
|
||||||
|
> span {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
border-bottom: 1px solid $secondary-border-color;
|
||||||
|
}
|
||||||
table.red-ui-info-table {
|
table.red-ui-info-table {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
@ -125,6 +141,9 @@ div.red-ui-info-table {
|
|||||||
font-size: 1.296em;
|
font-size: 1.296em;
|
||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
margin: 8px auto;
|
margin: 8px auto;
|
||||||
|
&.red-ui-help-title {
|
||||||
|
border-bottom: 1px solid $tertiary-border-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@ -214,12 +233,13 @@ div.red-ui-info-table {
|
|||||||
|
|
||||||
}
|
}
|
||||||
.red-ui-sidebar-info-stack {
|
.red-ui-sidebar-info-stack {
|
||||||
position: absolute;
|
height: 100%;
|
||||||
top: 0;
|
// position: absolute;
|
||||||
bottom: 0;
|
// top: 0;
|
||||||
left: 0;
|
// bottom: 0;
|
||||||
right: 0;
|
// left: 0;
|
||||||
overflow-y: scroll;
|
// right: 0;
|
||||||
|
// overflow-y: scroll;
|
||||||
}
|
}
|
||||||
.red-ui-help-tips {
|
.red-ui-help-tips {
|
||||||
display: none;
|
display: none;
|
||||||
@ -227,20 +247,23 @@ div.red-ui-info-table {
|
|||||||
left:0;
|
left:0;
|
||||||
right:0;
|
right:0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
height: 150px;
|
height: 0;
|
||||||
|
transition: height 0.2s, padding 0.2s;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-top: 1px solid $secondary-border-color;
|
border-top: 1px solid $secondary-border-color;
|
||||||
background-color: $secondary-background;
|
background-color: $secondary-background;
|
||||||
padding: 20px;
|
padding: 0;
|
||||||
box-shadow: 0 5px 20px 0px $shadow;
|
box-shadow: 0 5px 20px 0px $shadow;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.red-ui-sidebar-info.show-tips {
|
.red-ui-sidebar-info.show-tips {
|
||||||
.red-ui-sidebar-info-stack {
|
.red-ui-sidebar-info-stack {
|
||||||
bottom: 150px;
|
height: calc(100% - 150px);
|
||||||
}
|
}
|
||||||
.red-ui-help-tips {
|
.red-ui-help-tips {
|
||||||
display: block;
|
display: block;
|
||||||
|
height: 150px;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,3 +302,208 @@ div.red-ui-info-table {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 2px 4px 2px;
|
padding: 2px 4px 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red-ui-info-outline,.red-ui-sidebar-help-toc {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.red-ui-treeList {
|
||||||
|
flex-grow: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.red-ui-treeList-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-treeList-container,.red-ui-editableList-border {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
.red-ui-treeList-label {
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 2px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.red-ui-info-outline-project {
|
||||||
|
border-bottom: 1px solid $secondary-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-info-outline-item {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
border: none;
|
||||||
|
.red-ui-palette-icon-fa {
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
&.red-ui-info-outline-item-flow {
|
||||||
|
.red-ui-search-result-description {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.red-ui-info-outline-item-group .red-ui-search-result-node {
|
||||||
|
background: none;
|
||||||
|
border-color: transparent;
|
||||||
|
.red-ui-palette-icon-container {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
.red-ui-palette-icon-fa {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.red-ui-info-outline-item-empty {
|
||||||
|
font-style: italic;
|
||||||
|
color: $form-placeholder-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-search-result-node {
|
||||||
|
width: 24px;
|
||||||
|
height: 20px;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-palette-icon-container {
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
.red-ui-palette-icon {
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
.red-ui-search-result-description {
|
||||||
|
margin-left: 32px;
|
||||||
|
line-height: 22px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.red-ui-search-result-node-label {
|
||||||
|
color: $secondary-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-info-outline-item-control-spacer {
|
||||||
|
display: inline-block;
|
||||||
|
width: 23px;
|
||||||
|
}
|
||||||
|
.red-ui-info-outline-gutter {
|
||||||
|
display:none;
|
||||||
|
button {
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
.red-ui-treeList-label:hover & {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-info-outline-item-controls {
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0px;
|
||||||
|
padding: 2px 3px 0 1px;
|
||||||
|
text-align: right;
|
||||||
|
background: $list-item-background;
|
||||||
|
|
||||||
|
.red-ui-treeList-label:hover & {
|
||||||
|
background: $list-item-background-hover;
|
||||||
|
}
|
||||||
|
.red-ui-treeList-label.selected & {
|
||||||
|
background: $list-item-background-selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&.red-ui-info-outline-item-hover-controls button {
|
||||||
|
min-width: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-treeList-label:not(:hover) &.red-ui-info-outline-item-hover-controls {
|
||||||
|
button {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-info-outline-item-control-reveal,
|
||||||
|
.red-ui-info-outline-item-control-action {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.red-ui-treeList-label:hover & {
|
||||||
|
.red-ui-info-outline-item-control-reveal,
|
||||||
|
.red-ui-info-outline-item-control-action {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-ban {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.red-ui-info-outline-item.red-ui-info-outline-item-disabled & {
|
||||||
|
.fa-ban {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.fa-circle-thin {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
margin-right: 3px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-info-outline-item-disabled {
|
||||||
|
.red-ui-search-result-node {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
.red-ui-info-outline-item-label {
|
||||||
|
font-style: italic;
|
||||||
|
color: $secondary-text-color-disabled;
|
||||||
|
}
|
||||||
|
.red-ui-icons-flow {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.red-ui-icons {
|
||||||
|
display: inline-block;
|
||||||
|
width: 18px;
|
||||||
|
&:before {
|
||||||
|
white-space: pre;
|
||||||
|
content: ' '
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-icons-flow {
|
||||||
|
background-image: url('images/subflow_tab.svg');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
filter: brightness(2.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-ui-info-toolbar {
|
||||||
|
min-height: 39px;
|
||||||
|
height: 39px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: left;
|
||||||
|
// padding-left: 9px;
|
||||||
|
// box-sizing: border-box;
|
||||||
|
// background: $palette-header-background;
|
||||||
|
// border-bottom: 1px solid $secondary-border-color;
|
||||||
|
|
||||||
|
.red-ui-searchBox-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 6px;
|
||||||
|
right: 8px;
|
||||||
|
width: calc(100% - 130px);
|
||||||
|
max-width: 250px;
|
||||||
|
background: $palette-header-background;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -18,23 +18,32 @@
|
|||||||
.red-ui-searchBox-container {
|
.red-ui-searchBox-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
i {
|
i {
|
||||||
|
position: absolute;
|
||||||
|
top: 9px;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
color: $secondary-text-color;
|
color: $secondary-text-color;
|
||||||
}
|
}
|
||||||
i.fa-search {
|
i.fa-search {
|
||||||
position: absolute;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
left: 8px;
|
left: 8px;
|
||||||
top: 9px;
|
}
|
||||||
|
i.fa-caret-down {
|
||||||
|
position: absolute;
|
||||||
|
right: 6px;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
i.fa-times {
|
i.fa-times {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 5px;
|
right: 4px;
|
||||||
top: 9px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
form.red-ui-searchBox-form {
|
form.red-ui-searchBox-form {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
a.red-ui-searchBox-opts:hover {
|
||||||
|
color: $workspace-button-color-hover;
|
||||||
|
background: $workspace-button-background-hover;
|
||||||
|
}
|
||||||
input.red-ui-searchBox-input {
|
input.red-ui-searchBox-input {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
border: none;
|
border: none;
|
||||||
@ -57,9 +66,12 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 20px;
|
width: 16px;
|
||||||
|
}
|
||||||
|
a.red-ui-searchBox-clear {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-searchBox-resultCount {
|
.red-ui-searchBox-resultCount {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 18px;
|
right: 18px;
|
||||||
@ -70,4 +82,36 @@
|
|||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
&.red-ui-searchBox-has-options {
|
||||||
|
a.red-ui-searchBox-clear {
|
||||||
|
right: 16px;
|
||||||
|
}
|
||||||
|
.red-ui-searchBox-resultCount {
|
||||||
|
right: 33px;
|
||||||
|
}
|
||||||
|
input.red-ui-searchBox-input {
|
||||||
|
padding-right: 33px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-searchBox-compact {
|
||||||
|
|
||||||
|
input:focus.red-ui-searchBox-input {
|
||||||
|
outline: 1px solid $form-input-focus-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input.red-ui-searchBox-input,input:focus.red-ui-searchBox-input {
|
||||||
|
border: 1px solid $secondary-border-color;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
height: 26px;
|
||||||
|
}
|
||||||
|
i.fa-times,i.fa-search, i.fa-caret-down {
|
||||||
|
top: 7px;
|
||||||
|
}
|
||||||
|
.red-ui-searchBox-resultCount {
|
||||||
|
top: 3px;
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
}
|
}
|
@ -51,7 +51,10 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
.red-ui-typedInput-value-label-inactive {
|
||||||
|
background: $secondary-background-disabled;
|
||||||
|
color: $secondary-text-color-disabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.red-ui-typedInput-options {
|
.red-ui-typedInput-options {
|
||||||
@ -117,7 +120,7 @@ button.red-ui-typedInput-option-trigger
|
|||||||
}
|
}
|
||||||
&.disabled {
|
&.disabled {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
i.red-ui-typedInput-icon {
|
> i.red-ui-typedInput-icon {
|
||||||
color: $secondary-text-color-disabled;
|
color: $secondary-text-color-disabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right:0;
|
right:0;
|
||||||
zIndex: 101;
|
z-index: 101;
|
||||||
border-left: 1px solid $primary-border-color;
|
border-left: 1px solid $primary-border-color;
|
||||||
border-top: 1px solid $primary-border-color;
|
border-top: 1px solid $primary-border-color;
|
||||||
background: $view-navigator-background;
|
background: $view-navigator-background;
|
||||||
@ -122,7 +122,7 @@
|
|||||||
stroke-dasharray: 5,5;
|
stroke-dasharray: 5,5;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
stroke: $secondary-border-color;
|
stroke: $secondary-border-color;
|
||||||
strokeWidth: 1;
|
stroke-width: 1;
|
||||||
fill: $view-background;
|
fill: $view-background;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,3 +172,44 @@ button.red-ui-footer-button-toggle {
|
|||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#red-ui-loading-progress {
|
||||||
|
position: absolute;
|
||||||
|
background: $primary-background;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 200;
|
||||||
|
& > div {
|
||||||
|
position: absolute;
|
||||||
|
top: 30%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 300px;
|
||||||
|
height:80px;
|
||||||
|
text-align: center;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-loading-bar {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 300px;
|
||||||
|
height: 30px;
|
||||||
|
border: 2px solid $primary-border-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
background: $secondary-border-color;
|
||||||
|
transition: width 0.2s;
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.red-ui-loading-bar-label {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
@ -191,6 +191,7 @@
|
|||||||
'$merge':{ args:[ 'array' ]},
|
'$merge':{ args:[ 'array' ]},
|
||||||
'$millis':{ args:[ ]},
|
'$millis':{ args:[ ]},
|
||||||
'$min':{ args:[ 'array' ]},
|
'$min':{ args:[ 'array' ]},
|
||||||
|
'$moment':{ args:[ ]},
|
||||||
'$not':{ args:[ 'arg' ]},
|
'$not':{ args:[ 'arg' ]},
|
||||||
'$now':{ args:[ ]},
|
'$now':{ args:[ ]},
|
||||||
'$number':{ args:[ 'arg' ]},
|
'$number':{ args:[ 'arg' ]},
|
||||||
|
@ -14,16 +14,14 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<script type="text/x-red" data-template-name="inject">
|
<script type="text/html" data-template-name="inject">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-payload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-payload" style="width:70%">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
<input type="hidden" id="node-input-payloadType">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row node-input-property-container-row">
|
||||||
<label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
|
<ol id="node-input-property-container"></ol>
|
||||||
<input type="text" id="node-input-topic">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row" id="node-once">
|
<div class="form-row" id="node-once">
|
||||||
@ -114,12 +112,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-tips" data-i18n="[html]inject.tip"></div>
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.inject-time-row {
|
.inject-time-row {
|
||||||
@ -155,37 +148,76 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
function resizeDialog(size) {
|
||||||
|
size = size || { height: $(".red-ui-tray-content form").height() }
|
||||||
|
var rows = $("#dialog-form>div:not(.node-input-property-container-row):visible");
|
||||||
|
var height = size.height;
|
||||||
|
for (var i=0; i<rows.length; i++) {
|
||||||
|
height -= $(rows[i]).outerHeight(true);
|
||||||
|
}
|
||||||
|
var editorRow = $("#dialog-form>div.node-input-property-container-row");
|
||||||
|
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
|
||||||
|
height += 16;
|
||||||
|
$("#node-input-property-container").editableList('height',height);
|
||||||
|
}
|
||||||
|
|
||||||
RED.nodes.registerType('inject',{
|
RED.nodes.registerType('inject',{
|
||||||
category: 'common',
|
category: 'common',
|
||||||
color:"#a6bbcf",
|
color:"#a6bbcf",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
topic: {value:""},
|
props:{value:[{p:"payload"},{p:"topic",vt:"str"}]},
|
||||||
payload: {value:"", validate: RED.validators.typedInput("payloadType")},
|
|
||||||
payloadType: {value:"date"},
|
|
||||||
repeat: {value:"", validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 2147483))) }},
|
repeat: {value:"", validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 2147483))) }},
|
||||||
crontab: {value:""},
|
crontab: {value:""},
|
||||||
once: {value:false},
|
once: {value:false},
|
||||||
onceDelay: {value:0.1}
|
onceDelay: {value:0.1},
|
||||||
|
topic: {value:""},
|
||||||
|
payload: {value:"", validate: RED.validators.typedInput("payloadType")},
|
||||||
|
payloadType: {value:"date"},
|
||||||
},
|
},
|
||||||
icon: "inject.svg",
|
icon: "inject.svg",
|
||||||
inputs:0,
|
inputs:0,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
outputLabels: function(index) {
|
outputLabels: function(index) {
|
||||||
var lab = this.payloadType;
|
var lab = '';
|
||||||
if (lab === "json") {
|
|
||||||
try {
|
// if only payload and topic - display payload type
|
||||||
lab = typeof JSON.parse(this.payload);
|
// if only one property - show it's type
|
||||||
if (lab === "object") {
|
// if more than one property (other than payload and topic) - show "x properties" where x is the number of properties.
|
||||||
if (Array.isArray(JSON.parse(this.payload))) { lab = "Array"; }
|
// this.props will not be an array for legacy inject nodes until they are re-deployed
|
||||||
}
|
//
|
||||||
} catch(e) {
|
var props = this.props;
|
||||||
return this._("inject.label.invalid"); }
|
if (!Array.isArray(props)) {
|
||||||
|
props = [
|
||||||
|
{ p:"payload", v: this.payload, vt: this.payloadType },
|
||||||
|
{ p:"topic", v: this.topic, vt: "str" }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
var name = "inject.label."+lab;
|
if (props) {
|
||||||
var label = this._(name);
|
for (var i=0,l=props.length; i<l; i++) {
|
||||||
if (name !== label) {
|
if (i > 0) lab += "\n";
|
||||||
return label;
|
if (i === 5) {
|
||||||
|
lab += " + "+(props.length-4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lab += props[i].p+": ";
|
||||||
|
|
||||||
|
var propType = props[i].p === "payload"? this.payloadType : props[i].vt;
|
||||||
|
if (propType === "json") {
|
||||||
|
try {
|
||||||
|
var parsedProp = JSON.parse(props[i].p === "payload"? this.payload : props[i].v);
|
||||||
|
propType = typeof parsedProp;
|
||||||
|
if (propType === "object" && Array.isArray(parsedProp)) {
|
||||||
|
propType = "Array";
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
propType = "invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lab += this._("inject.label."+propType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return lab;
|
return lab;
|
||||||
},
|
},
|
||||||
@ -201,27 +233,33 @@
|
|||||||
}
|
}
|
||||||
if (this.name) {
|
if (this.name) {
|
||||||
return this.name+suffix;
|
return this.name+suffix;
|
||||||
} else if (this.payloadType === "string" ||
|
}
|
||||||
this.payloadType === "str" ||
|
|
||||||
this.payloadType === "num" ||
|
var payload = this.payload || "";
|
||||||
this.payloadType === "bool" ||
|
var payloadType = this.payloadType || "str";
|
||||||
this.payloadType === "json") {
|
var topic = this.topic || "";
|
||||||
if ((this.topic !== "") && ((this.topic.length + this.payload.length) <= 32)) {
|
|
||||||
return this.topic + ":" + this.payload+suffix;
|
if (payloadType === "string" ||
|
||||||
} else if (this.payload.length > 0 && this.payload.length < 24) {
|
payloadType === "str" ||
|
||||||
return this.payload+suffix;
|
payloadType === "num" ||
|
||||||
|
payloadType === "bool" ||
|
||||||
|
payloadType === "json") {
|
||||||
|
if ((topic !== "") && ((topic.length + payload.length) <= 32)) {
|
||||||
|
return topic + ":" + payload+suffix;
|
||||||
|
} else if (payload.length > 0 && payload.length < 24) {
|
||||||
|
return payload+suffix;
|
||||||
} else {
|
} else {
|
||||||
return this._("inject.inject")+suffix;
|
return this._("inject.inject")+suffix;
|
||||||
}
|
}
|
||||||
} else if (this.payloadType === 'date') {
|
} else if (payloadType === 'date' || payloadType === 'bin' || payloadType === 'env') {
|
||||||
if ((this.topic !== "") && (this.topic.length <= 16)) {
|
if ((topic !== "") && (topic.length <= 16)) {
|
||||||
return this.topic + ":" + this._("inject.timestamp")+suffix;
|
return topic + ":" + this._('inject.label.'+payloadType)+suffix;
|
||||||
} else {
|
} else {
|
||||||
return this._("inject.timestamp")+suffix;
|
return this._('inject.label.'+payloadType)+suffix;
|
||||||
}
|
}
|
||||||
} else if (this.payloadType === 'flow' || this.payloadType === 'global') {
|
} else if (payloadType === 'flow' || payloadType === 'global') {
|
||||||
var key = RED.utils.parseContextKey(this.payload);
|
var key = RED.utils.parseContextKey(payload);
|
||||||
return this.payloadType+"."+key.key+suffix;
|
return payloadType+"."+key.key+suffix;
|
||||||
} else {
|
} else {
|
||||||
return this._("inject.inject")+suffix;
|
return this._("inject.inject")+suffix;
|
||||||
}
|
}
|
||||||
@ -239,13 +277,6 @@
|
|||||||
} else if (this.payloadType === 'string' || this.payloadType === 'none') {
|
} else if (this.payloadType === 'string' || this.payloadType === 'none') {
|
||||||
this.payloadType = "str";
|
this.payloadType = "str";
|
||||||
}
|
}
|
||||||
$("#node-input-payloadType").val(this.payloadType);
|
|
||||||
|
|
||||||
$("#node-input-payload").typedInput({
|
|
||||||
default: 'str',
|
|
||||||
typeField: $("#node-input-payloadType"),
|
|
||||||
types:['flow','global','str','num','bool','json','bin','date','env']
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#inject-time-type-select").on("change", function() {
|
$("#inject-time-type-select").on("change", function() {
|
||||||
$("#node-input-crontab").val('');
|
$("#node-input-crontab").val('');
|
||||||
@ -259,6 +290,11 @@
|
|||||||
$("#node-once").hide();
|
$("#node-once").hide();
|
||||||
$("#node-input-once").prop('checked', false);
|
$("#node-input-once").prop('checked', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scroll down
|
||||||
|
var scrollDiv = $("#dialog-form").parent();
|
||||||
|
scrollDiv.scrollTop(scrollDiv.prop('scrollHeight'));
|
||||||
|
resizeDialog();
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#node-input-once").on("change", function() {
|
$("#node-input-once").on("change", function() {
|
||||||
@ -378,7 +414,70 @@
|
|||||||
$("#inject-time-type-select").val(repeattype);
|
$("#inject-time-type-select").val(repeattype);
|
||||||
$("#inject-time-row-"+repeattype).show();
|
$("#inject-time-row-"+repeattype).show();
|
||||||
|
|
||||||
$("#node-input-payload").typedInput('type',this.payloadType);
|
/* */
|
||||||
|
|
||||||
|
$('#node-input-property-container').css('min-height','120px').css('min-width','450px').editableList({
|
||||||
|
addItem: function(container,i,opt) {
|
||||||
|
var prop = opt;
|
||||||
|
if (!prop.hasOwnProperty('p')) {
|
||||||
|
prop = {p:"",v:"",vt:"str"};
|
||||||
|
}
|
||||||
|
container.css({
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
|
});
|
||||||
|
var row = $('<div/>').appendTo(container);
|
||||||
|
|
||||||
|
var propertyName = $('<input/>',{class:"node-input-prop-property-name",type:"text"})
|
||||||
|
.css("width","30%")
|
||||||
|
.appendTo(row)
|
||||||
|
.typedInput({types:['msg']});
|
||||||
|
|
||||||
|
$('<div/>',{style: 'display:inline-block; padding:0px 6px;'})
|
||||||
|
.text('=')
|
||||||
|
.appendTo(row);
|
||||||
|
|
||||||
|
var propertyValue = $('<input/>',{class:"node-input-prop-property-value",type:"text"})
|
||||||
|
.css("width","calc(70% - 30px)")
|
||||||
|
.appendTo(row)
|
||||||
|
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']});
|
||||||
|
|
||||||
|
propertyName.typedInput('value',prop.p);
|
||||||
|
|
||||||
|
propertyValue.typedInput('value',prop.v);
|
||||||
|
propertyValue.typedInput('type',prop.vt);
|
||||||
|
},
|
||||||
|
removable: true,
|
||||||
|
sortable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!this.props) {
|
||||||
|
var payload = {
|
||||||
|
p:'payload',
|
||||||
|
v: this.payload ? this.payload : '',
|
||||||
|
vt:this.payloadType ? this.payloadType : 'date'
|
||||||
|
};
|
||||||
|
var topic = {
|
||||||
|
p:'topic',
|
||||||
|
v: this.topic ? this.topic : '',
|
||||||
|
vt:'string'
|
||||||
|
}
|
||||||
|
this.props = [payload,topic];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0; i<this.props.length; i++) {
|
||||||
|
var prop = this.props[i];
|
||||||
|
var newProp = { p: prop.p, v: prop.v, vt: prop.vt };
|
||||||
|
if (newProp.v === undefined) {
|
||||||
|
if (prop.p === 'payload') {
|
||||||
|
newProp.v = this.payload ? this.payload : '';
|
||||||
|
newProp.vt = this.payloadType ? this.payloadType : 'date';
|
||||||
|
} else if (prop.p === 'topic' && prop.vt === "str") {
|
||||||
|
newProp.v = this.topic ? this.topic : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$("#node-input-property-container").editableList('addItem',newProp);
|
||||||
|
}
|
||||||
|
|
||||||
$("#inject-time-type-select").trigger("change");
|
$("#inject-time-type-select").trigger("change");
|
||||||
$("#inject-time-interval-time-start").trigger("change");
|
$("#inject-time-interval-time-start").trigger("change");
|
||||||
@ -474,6 +573,34 @@
|
|||||||
|
|
||||||
$("#node-input-repeat").val(repeat);
|
$("#node-input-repeat").val(repeat);
|
||||||
$("#node-input-crontab").val(crontab);
|
$("#node-input-crontab").val(crontab);
|
||||||
|
|
||||||
|
/* Gather the injected properties of the msg object */
|
||||||
|
var props = $("#node-input-property-container").editableList('items');
|
||||||
|
var node = this;
|
||||||
|
node.props= [];
|
||||||
|
delete node.payloadType;
|
||||||
|
delete node.payload;
|
||||||
|
node.topic = "";
|
||||||
|
props.each(function(i) {
|
||||||
|
var prop = $(this);
|
||||||
|
var p = {
|
||||||
|
p:prop.find(".node-input-prop-property-name").typedInput('value')
|
||||||
|
};
|
||||||
|
if (p.p) {
|
||||||
|
p.v = prop.find(".node-input-prop-property-value").typedInput('value');
|
||||||
|
p.vt = prop.find(".node-input-prop-property-value").typedInput('type');
|
||||||
|
if (p.p === "payload") { // save payload to old "legacy" property
|
||||||
|
node.payloadType = p.vt;
|
||||||
|
node.payload = p.v;
|
||||||
|
delete p.v;
|
||||||
|
delete p.vt;
|
||||||
|
} else if (p.p === "topic" && p.vt === "str") {
|
||||||
|
node.topic = p.v;
|
||||||
|
delete p.v;
|
||||||
|
}
|
||||||
|
node.props.push(p);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
enabled: function() {
|
enabled: function() {
|
||||||
@ -483,12 +610,7 @@
|
|||||||
if (this.changed) {
|
if (this.changed) {
|
||||||
return RED.notify(RED._("notification.warning", {message:RED._("notification.warnings.undeployedChanges")}),"warning");
|
return RED.notify(RED._("notification.warning", {message:RED._("notification.warnings.undeployedChanges")}),"warning");
|
||||||
}
|
}
|
||||||
var payload = this.payload;
|
|
||||||
if ((this.payloadType === 'flow') ||
|
|
||||||
(this.payloadType === 'global')) {
|
|
||||||
var key = RED.utils.parseContextKey(payload);
|
|
||||||
payload = this.payloadType+"."+key.key;
|
|
||||||
}
|
|
||||||
var label = this._def.label.call(this);
|
var label = this._def.label.call(this);
|
||||||
if (label.length > 30) {
|
if (label.length > 30) {
|
||||||
label = label.substring(0,50)+"...";
|
label = label.substring(0,50)+"...";
|
||||||
@ -514,7 +636,8 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
oneditresize: resizeDialog
|
||||||
});
|
});
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
@ -20,9 +20,32 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
function InjectNode(n) {
|
function InjectNode(n) {
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
this.topic = n.topic;
|
|
||||||
this.payload = n.payload;
|
/* Handle legacy */
|
||||||
this.payloadType = n.payloadType;
|
if(!Array.isArray(n.props)){
|
||||||
|
n.props = [];
|
||||||
|
n.props.push({
|
||||||
|
p:'payload',
|
||||||
|
v:n.payload,
|
||||||
|
vt:n.payloadType
|
||||||
|
});
|
||||||
|
n.props.push({
|
||||||
|
p:'topic',
|
||||||
|
v:n.topic,
|
||||||
|
vt:'str'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
for (var i=0,l=n.props.length; i<l; i++) {
|
||||||
|
if (n.props[i].p === 'payload' && !n.props[i].hasOwnProperty('v')) {
|
||||||
|
n.props[i].v = n.payload;
|
||||||
|
n.props[i].vt = n.payloadType;
|
||||||
|
} else if (n.props[i].p === 'topic' && n.props[i].vt === 'str' && !n.props[i].hasOwnProperty('v')) {
|
||||||
|
n.props[i].v = n.topic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props = n.props;
|
||||||
this.repeat = n.repeat;
|
this.repeat = n.repeat;
|
||||||
this.crontab = n.crontab;
|
this.crontab = n.crontab;
|
||||||
this.once = n.once;
|
this.once = n.once;
|
||||||
@ -31,65 +54,83 @@ module.exports = function(RED) {
|
|||||||
this.cronjob = null;
|
this.cronjob = null;
|
||||||
var node = this;
|
var node = this;
|
||||||
|
|
||||||
|
node.props.forEach(function (prop) {
|
||||||
|
if (prop.vt === "jsonata") {
|
||||||
|
try {
|
||||||
|
var val = prop.v ? prop.v : "";
|
||||||
|
prop.exp = RED.util.prepareJSONataExpression(val, node);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
node.error(RED._("inject.errors.invalid-expr", {error:err.message}));
|
||||||
|
prop.exp = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (node.repeat > 2147483) {
|
if (node.repeat > 2147483) {
|
||||||
node.error(RED._("inject.errors.toolong", this));
|
node.error(RED._("inject.errors.toolong", this));
|
||||||
delete node.repeat;
|
delete node.repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.repeaterSetup = function () {
|
node.repeaterSetup = function () {
|
||||||
if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
|
if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
|
||||||
this.repeat = this.repeat * 1000;
|
this.repeat = this.repeat * 1000;
|
||||||
if (RED.settings.verbose) {
|
if (RED.settings.verbose) {
|
||||||
this.log(RED._("inject.repeat", this));
|
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);
|
||||||
}
|
}
|
||||||
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) {
|
if (this.once) {
|
||||||
this.onceTimeout = setTimeout( function() {
|
this.onceTimeout = setTimeout( function() {
|
||||||
node.emit("input",{});
|
node.emit("input",{});
|
||||||
node.repeaterSetup();
|
node.repeaterSetup();
|
||||||
}, this.onceDelay);
|
}, this.onceDelay);
|
||||||
} else {
|
} else {
|
||||||
node.repeaterSetup();
|
node.repeaterSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.on("input",function(msg) {
|
this.on("input", function(msg) {
|
||||||
msg.topic = this.topic;
|
var errors = [];
|
||||||
if (this.payloadType !== 'flow' && this.payloadType !== 'global') {
|
|
||||||
try {
|
|
||||||
if ( (this.payloadType == null && this.payload === "") || this.payloadType === "date") {
|
|
||||||
msg.payload = Date.now();
|
|
||||||
} else if (this.payloadType == null) {
|
|
||||||
msg.payload = this.payload;
|
|
||||||
} else if (this.payloadType === 'none') {
|
|
||||||
msg.payload = "";
|
|
||||||
} else {
|
|
||||||
msg.payload = RED.util.evaluateNodeProperty(this.payload,this.payloadType,this,msg);
|
|
||||||
}
|
|
||||||
this.send(msg);
|
|
||||||
msg = null;
|
|
||||||
} catch(err) {
|
|
||||||
this.error(err,msg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
RED.util.evaluateNodeProperty(this.payload,this.payloadType,this,msg, function(err,res) {
|
|
||||||
if (err) {
|
|
||||||
node.error(err,msg);
|
|
||||||
} else {
|
|
||||||
msg.payload = res;
|
|
||||||
node.send(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
this.props.forEach(p => {
|
||||||
|
var property = p.p;
|
||||||
|
var value = p.v ? p.v : '';
|
||||||
|
var valueType = p.vt ? p.vt : 'str';
|
||||||
|
|
||||||
|
if (!property) return;
|
||||||
|
|
||||||
|
if (valueType === "jsonata") {
|
||||||
|
if (p.exp) {
|
||||||
|
try {
|
||||||
|
var val = RED.util.evaluateJSONataExpression(p.exp, msg);
|
||||||
|
RED.util.setMessageProperty(msg, property, val, true);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
errors.push(err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
RED.util.setMessageProperty(msg,property,RED.util.evaluateNodeProperty(value, valueType, this, msg),true);
|
||||||
|
} catch (err) {
|
||||||
|
errors.push(err.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (errors.length) {
|
||||||
|
node.error(errors.join('; '), msg);
|
||||||
|
} else {
|
||||||
|
node.send(msg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,35 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="debug">
|
<script type="text/html" data-template-name="debug">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-typed-complete"><i class="fa fa-list"></i> <span data-i18n="debug.output"></span></label>
|
<label for="node-input-typed-complete"><i class="fa fa-list"></i> <span data-i18n="debug.output"></span></label>
|
||||||
<input id="node-input-typed-complete" type="text" style="width: 70%">
|
<input id="node-input-typed-complete" type="text" style="width: 70%">
|
||||||
<input id="node-input-complete" type="hidden">
|
<input id="node-input-complete" type="hidden">
|
||||||
<input id="node-input-targetType" type="hidden">
|
<input id="node-input-targetType" type="hidden">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-tosidebar"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label>
|
<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%">
|
<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>
|
<input type="checkbox" id="node-input-tosidebar" style="display:inline-block; width:22px; vertical-align:top;"><span data-i18n="debug.toSidebar"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-console"> </label>
|
<label for="node-input-console"> </label>
|
||||||
<label for="node-input-console" style="width:70%">
|
<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>
|
<input type="checkbox" id="node-input-console" style="display:inline-block; width:22px; vertical-align:top;"><span data-i18n="debug.toConsole"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row" id="node-tostatus-line">
|
<div class="form-row">
|
||||||
<label for="node-input-tostatus"> </label>
|
<label for="node-input-tostatus"> </label>
|
||||||
<label for="node-input-tostatus" style="width:70%">
|
<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>
|
<input type="checkbox" id="node-input-tostatus" style="display:inline-block; width:22px; vertical-align:top;"><span data-i18n="debug.toStatus"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row" id="node-tostatus-line">
|
||||||
|
<label for="node-input-typed-status"><i class="fa fa-ellipsis-h"></i> <span data-i18n="debug.status"></span></label>
|
||||||
|
<input id="node-input-typed-status" type="text" style="width: 70%">
|
||||||
|
<input id="node-input-statusVal" type="hidden">
|
||||||
|
<input id="node-input-statusType" type="hidden">
|
||||||
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
@ -36,6 +41,36 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
(function() {
|
(function() {
|
||||||
var subWindow = null;
|
var subWindow = null;
|
||||||
|
|
||||||
|
function activateAjaxCall(node, active, successCallback) {
|
||||||
|
var url;
|
||||||
|
var body;
|
||||||
|
|
||||||
|
if (Array.isArray(node)) {
|
||||||
|
url = "debug/"+(active?"enable":"disable");
|
||||||
|
body = {nodes: node.map(function(n) { return n.id})}
|
||||||
|
node = node[0];
|
||||||
|
} else {
|
||||||
|
url = "debug/"+node.id+"/"+(active?"enable":"disable");
|
||||||
|
}
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
type: "POST",
|
||||||
|
data: body,
|
||||||
|
success: successCallback,
|
||||||
|
error: function(jqXHR,textStatus,errorThrown) {
|
||||||
|
if (jqXHR.status == 404) {
|
||||||
|
RED.notify(node._("common.notification.error", {message: node._("common.notification.errors.not-deployed")}),"error");
|
||||||
|
} else if (jqXHR.status === 0) {
|
||||||
|
RED.notify(node._("common.notification.error", {message: node._("common.notification.errors.no-response")}),"error");
|
||||||
|
} else {
|
||||||
|
// TODO where is the err.status comming from?
|
||||||
|
RED.notify(node._("common.notification.error",{message:node._("common.notification.errors.unexpected",{status:err.status,message:err.response})}),"error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
RED.nodes.registerType('debug',{
|
RED.nodes.registerType('debug',{
|
||||||
category: 'common',
|
category: 'common',
|
||||||
defaults: {
|
defaults: {
|
||||||
@ -45,7 +80,9 @@
|
|||||||
console: {value:false},
|
console: {value:false},
|
||||||
tostatus: {value:false},
|
tostatus: {value:false},
|
||||||
complete: {value:"false", required:true},
|
complete: {value:"false", required:true},
|
||||||
targetType: {value:undefined}
|
targetType: {value:undefined},
|
||||||
|
statusVal: {value:""},
|
||||||
|
statusType: {value:"auto"}
|
||||||
},
|
},
|
||||||
label: function() {
|
label: function() {
|
||||||
var suffix = "";
|
var suffix = "";
|
||||||
@ -73,38 +110,28 @@
|
|||||||
onclick: function() {
|
onclick: function() {
|
||||||
var label = this.name||"debug";
|
var label = this.name||"debug";
|
||||||
var node = this;
|
var node = this;
|
||||||
$.ajax({
|
activateAjaxCall(node, node.active, function(resp, textStatus, xhr) {
|
||||||
url: "debug/"+this.id+"/"+(this.active?"enable":"disable"),
|
var historyEvent = {
|
||||||
type: "POST",
|
t:'edit',
|
||||||
success: function(resp, textStatus, xhr) {
|
node:node,
|
||||||
var historyEvent = {
|
changes:{
|
||||||
t:'edit',
|
active:!node.active
|
||||||
node:node,
|
},
|
||||||
changes:{
|
dirty:node.dirty,
|
||||||
active:!node.active
|
changed:node.changed,
|
||||||
},
|
callback: function(ev) {
|
||||||
dirty:node.dirty,
|
activateAjaxCall(ev.node, ev.node.active);
|
||||||
changed:node.changed
|
|
||||||
};
|
|
||||||
node.changed = true;
|
|
||||||
node.dirty = true;
|
|
||||||
RED.nodes.dirty(true);
|
|
||||||
RED.history.push(historyEvent);
|
|
||||||
RED.view.redraw();
|
|
||||||
if (xhr.status == 200) {
|
|
||||||
RED.notify(node._("debug.notification.activated",{label:label}),"success");
|
|
||||||
} else if (xhr.status == 201) {
|
|
||||||
RED.notify(node._("debug.notification.deactivated",{label:label}),"success");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(jqXHR,textStatus,errorThrown) {
|
|
||||||
if (jqXHR.status == 404) {
|
|
||||||
RED.notify(node._("common.notification.error", {message: node._("common.notification.errors.not-deployed")}),"error");
|
|
||||||
} else if (jqXHR.status === 0) {
|
|
||||||
RED.notify(node._("common.notification.error", {message: node._("common.notification.errors.no-response")}),"error");
|
|
||||||
} else {
|
|
||||||
RED.notify(node._("common.notification.error",{message:node._("common.notification.errors.unexpected",{status:err.status,message:err.response})}),"error");
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
node.changed = true;
|
||||||
|
node.dirty = true;
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
RED.view.redraw();
|
||||||
|
if (xhr.status == 200) {
|
||||||
|
RED.notify(node._("debug.notification.activated",{label:label}),"success");
|
||||||
|
} else if (xhr.status == 201) {
|
||||||
|
RED.notify(node._("debug.notification.deactivated",{label:label}),"success");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -266,6 +293,78 @@
|
|||||||
RED.events.on("project:change", this.clearMessageList);
|
RED.events.on("project:change", this.clearMessageList);
|
||||||
RED.actions.add("core:clear-debug-messages", function() { RED.debug.clearMessageList(true) });
|
RED.actions.add("core:clear-debug-messages", function() { RED.debug.clearMessageList(true) });
|
||||||
|
|
||||||
|
RED.actions.add("core:activate-selected-debug-nodes", function() { setDebugNodeState(getSelectedDebugNodes(true), true); });
|
||||||
|
RED.actions.add("core:activate-all-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(true, true),true); });
|
||||||
|
RED.actions.add("core:activate-all-flow-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(true, false),true); });
|
||||||
|
|
||||||
|
RED.actions.add("core:deactivate-selected-debug-nodes", function() { setDebugNodeState(getSelectedDebugNodes(false), false); });
|
||||||
|
RED.actions.add("core:deactivate-all-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(false, true),false); });
|
||||||
|
RED.actions.add("core:deactivate-all-flow-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(false, false),false); });
|
||||||
|
|
||||||
|
function getSelectedDebugNodes(state) {
|
||||||
|
var nodes = [];
|
||||||
|
var selection = RED.view.selection();
|
||||||
|
if (selection.nodes) {
|
||||||
|
selection.nodes.forEach(function(n) {
|
||||||
|
if (RED.nodes.subflow(n.z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (n.type === 'debug' && n.active !== state) {
|
||||||
|
nodes.push(n);
|
||||||
|
} else if (n.type === 'group') {
|
||||||
|
nodes = nodes.concat( RED.group.getNodes(n,true).filter(function(n) {
|
||||||
|
return n.type === 'debug' && n.active !== state
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return nodes;
|
||||||
|
|
||||||
|
}
|
||||||
|
function getMatchingDebugNodes(state,globally) {
|
||||||
|
var nodes = [];
|
||||||
|
var filter = {type:"debug"};
|
||||||
|
if (!globally) {
|
||||||
|
filter.z = RED.workspaces.active();
|
||||||
|
}
|
||||||
|
var candidateNodes = RED.nodes.filterNodes(filter);
|
||||||
|
nodes = candidateNodes.filter(function(n) {
|
||||||
|
return n.active !== state && !RED.nodes.subflow(n.z)
|
||||||
|
})
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDebugNodeState(nodes,state) {
|
||||||
|
var historyEvents = [];
|
||||||
|
if (nodes.length > 0) {
|
||||||
|
activateAjaxCall(nodes,false, function(resp, textStatus, xhr) {
|
||||||
|
nodes.forEach(function(n) {
|
||||||
|
historyEvents.push({
|
||||||
|
t: "edit",
|
||||||
|
node: n,
|
||||||
|
changed: n.changed,
|
||||||
|
changes: {
|
||||||
|
active: n.active
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n.active = state;
|
||||||
|
n.changed = true;
|
||||||
|
n.dirty = true;
|
||||||
|
})
|
||||||
|
RED.history.push({
|
||||||
|
t: "multi",
|
||||||
|
events: historyEvents,
|
||||||
|
dirty: RED.nodes.dirty(),
|
||||||
|
callback: function() {
|
||||||
|
activateAjaxCall(nodes,nodes[0].active);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
RED.view.redraw();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$("#red-ui-sidebar-debug-open").on("click", function(e) {
|
$("#red-ui-sidebar-debug-open").on("click", function(e) {
|
||||||
e.preventDefault();
|
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");
|
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");
|
||||||
@ -308,10 +407,20 @@
|
|||||||
window.removeEventListener("message",this.handleWindowMessage);
|
window.removeEventListener("message",this.handleWindowMessage);
|
||||||
RED.actions.remove("core:show-debug-tab");
|
RED.actions.remove("core:show-debug-tab");
|
||||||
RED.actions.remove("core:clear-debug-messages");
|
RED.actions.remove("core:clear-debug-messages");
|
||||||
|
|
||||||
delete RED._debug;
|
delete RED._debug;
|
||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
|
var autoType = {
|
||||||
|
value: "auto",
|
||||||
|
label: RED._("node-red:debug.autostatus"),
|
||||||
|
hasValue: false
|
||||||
|
};
|
||||||
|
$("#node-input-typed-status").typedInput({
|
||||||
|
default: "auto",
|
||||||
|
types:[autoType, "msg", "jsonata"],
|
||||||
|
typeField: $("#node-input-statusType")
|
||||||
|
});
|
||||||
|
var that = this;
|
||||||
var none = {
|
var none = {
|
||||||
value: "none",
|
value: "none",
|
||||||
label: RED._("node-red:debug.none"),
|
label: RED._("node-red:debug.none"),
|
||||||
@ -321,6 +430,14 @@
|
|||||||
this.tosidebar = true;
|
this.tosidebar = true;
|
||||||
$("#node-input-tosidebar").prop('checked', true);
|
$("#node-input-tosidebar").prop('checked', true);
|
||||||
}
|
}
|
||||||
|
if (this.statusVal === undefined) {
|
||||||
|
this.statusVal = (this.complete === "false") ? "payload" : ((this.complete === "true") ? "payload" : this.complete+"");
|
||||||
|
$("#node-input-typed-status").typedInput('value',this.statusVal || "");
|
||||||
|
}
|
||||||
|
if (this.statusType === undefined) {
|
||||||
|
this.statusType = this.targetType;
|
||||||
|
$("#node-input-typed-status").typedInput('type',this.statusType || "auto");
|
||||||
|
}
|
||||||
if (typeof this.console === "string") {
|
if (typeof this.console === "string") {
|
||||||
this.console = (this.console == 'true');
|
this.console = (this.console == 'true');
|
||||||
$("#node-input-console").prop('checked', this.console);
|
$("#node-input-console").prop('checked', this.console);
|
||||||
@ -331,6 +448,7 @@
|
|||||||
label: RED._("node-red:debug.msgobj"),
|
label: RED._("node-red:debug.msgobj"),
|
||||||
hasValue: false
|
hasValue: false
|
||||||
};
|
};
|
||||||
|
|
||||||
$("#node-input-typed-complete").typedInput({
|
$("#node-input-typed-complete").typedInput({
|
||||||
default: "msg",
|
default: "msg",
|
||||||
types:['msg', fullType, "jsonata"],
|
types:['msg', fullType, "jsonata"],
|
||||||
@ -354,17 +472,29 @@
|
|||||||
) {
|
) {
|
||||||
$("#node-input-typed-complete").typedInput('value','payload');
|
$("#node-input-typed-complete").typedInput('value','payload');
|
||||||
}
|
}
|
||||||
if ($("#node-input-typed-complete").typedInput('type') === 'full') {
|
});
|
||||||
$("#node-tostatus-line").hide();
|
|
||||||
} else {
|
$("#node-input-tostatus").on('change',function() {
|
||||||
|
if ($(this).is(":checked")) {
|
||||||
|
if (!that.hasOwnProperty("statusVal") || that.statusVal === "") {
|
||||||
|
var type = $("#node-input-typed-complete").typedInput('type');
|
||||||
|
var comp = "payload";
|
||||||
|
if (type !== 'full') {
|
||||||
|
comp = $("#node-input-typed-complete").typedInput('value');
|
||||||
|
}
|
||||||
|
that.statusType = "auto";
|
||||||
|
that.statusVal = comp;
|
||||||
|
}
|
||||||
|
$("#node-input-typed-status").typedInput('type',that.statusType);
|
||||||
|
$("#node-input-typed-status").typedInput('value',that.statusVal);
|
||||||
$("#node-tostatus-line").show();
|
$("#node-tostatus-line").show();
|
||||||
}
|
}
|
||||||
});
|
else {
|
||||||
$("#node-input-complete").on('change',function() {
|
|
||||||
if ($("#node-input-typed-complete").typedInput('type') === 'full') {
|
|
||||||
$("#node-tostatus-line").hide();
|
$("#node-tostatus-line").hide();
|
||||||
} else {
|
that.statusType = "auto";
|
||||||
$("#node-tostatus-line").show();
|
that.statusVal = "";
|
||||||
|
$("#node-input-typed-status").typedInput('type',that.statusType);
|
||||||
|
$("#node-input-typed-status").typedInput('value',that.statusVal);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -375,6 +505,7 @@
|
|||||||
} else {
|
} else {
|
||||||
$("#node-input-complete").val($("#node-input-typed-complete").typedInput('value'));
|
$("#node-input-complete").val($("#node-input-typed-complete").typedInput('value'));
|
||||||
}
|
}
|
||||||
|
$("#node-input-statusVal").val($("#node-input-typed-status").typedInput('value'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
@ -2,7 +2,7 @@ module.exports = function(RED) {
|
|||||||
"use strict";
|
"use strict";
|
||||||
var util = require("util");
|
var util = require("util");
|
||||||
var events = require("events");
|
var events = require("events");
|
||||||
var path = require("path");
|
//var path = require("path");
|
||||||
var debuglength = RED.settings.debugMaxLength || 1000;
|
var debuglength = RED.settings.debugMaxLength || 1000;
|
||||||
var useColors = RED.settings.debugUseColors || false;
|
var useColors = RED.settings.debugUseColors || false;
|
||||||
util.inspect.styles.boolean = "red";
|
util.inspect.styles.boolean = "red";
|
||||||
@ -15,36 +15,20 @@ module.exports = function(RED) {
|
|||||||
this.complete = hasEditExpression ? null : (n.complete||"payload").toString();
|
this.complete = hasEditExpression ? null : (n.complete||"payload").toString();
|
||||||
if (this.complete === "false") { this.complete = "payload"; }
|
if (this.complete === "false") { this.complete = "payload"; }
|
||||||
this.console = ""+(n.console || false);
|
this.console = ""+(n.console || false);
|
||||||
this.tostatus = (this.complete !== "true") && (n.tostatus || false);
|
this.tostatus = n.tostatus || false;
|
||||||
|
this.statusType = n.statusType || "auto";
|
||||||
|
this.statusVal = n.statusVal || this.complete;
|
||||||
this.tosidebar = n.tosidebar;
|
this.tosidebar = n.tosidebar;
|
||||||
if (this.tosidebar === undefined) { this.tosidebar = true; }
|
if (this.tosidebar === undefined) { this.tosidebar = true; }
|
||||||
this.severity = n.severity || 40;
|
|
||||||
this.active = (n.active === null || typeof n.active === "undefined") || n.active;
|
this.active = (n.active === null || typeof n.active === "undefined") || n.active;
|
||||||
if (this.tostatus) { this.status({fill:"grey", shape:"ring"}); }
|
if (this.tostatus) { this.status({fill:"grey", shape:"ring"}); }
|
||||||
else { this.status({}); }
|
else { this.status({}); }
|
||||||
|
var hasStatExpression = (n.statusType === "jsonata");
|
||||||
|
var statExpression = hasStatExpression ? n.statusVal : null;
|
||||||
|
|
||||||
var node = this;
|
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"
|
|
||||||
};
|
|
||||||
var preparedEditExpression = null;
|
var preparedEditExpression = null;
|
||||||
|
var preparedStatExpression = null;
|
||||||
if (editExpression) {
|
if (editExpression) {
|
||||||
try {
|
try {
|
||||||
preparedEditExpression = RED.util.prepareJSONataExpression(editExpression, this);
|
preparedEditExpression = RED.util.prepareJSONataExpression(editExpression, this);
|
||||||
@ -54,16 +38,22 @@ module.exports = function(RED) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (statExpression) {
|
||||||
|
try {
|
||||||
|
preparedStatExpression = RED.util.prepareJSONataExpression(statExpression, this);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
node.error(RED._("debug.invalid-exp", {error: editExpression}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function prepareValue(msg, done) {
|
function prepareValue(msg, done) {
|
||||||
// Either apply the jsonata expression or...
|
// Either apply the jsonata expression or...
|
||||||
if (preparedEditExpression) {
|
if (preparedEditExpression) {
|
||||||
RED.util.evaluateJSONataExpression(preparedEditExpression, msg, (err, value) => {
|
RED.util.evaluateJSONataExpression(preparedEditExpression, msg, (err, value) => {
|
||||||
if (err) {
|
if (err) { done(RED._("debug.invalid-exp", {error: editExpression})); }
|
||||||
done(RED._("debug.invalid-exp", {error: editExpression}));
|
else { done(null,{id:node.id, z:node.z, _alias: node._alias, path:node._flow.path, name:node.name, topic:msg.topic, msg:value}); }
|
||||||
} else {
|
|
||||||
done(null,{id:node.id, z:node.z, _alias: node._alias, path:node._flow.path, name:node.name, topic:msg.topic, msg:value});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Extract the required message property
|
// Extract the required message property
|
||||||
@ -71,17 +61,67 @@ module.exports = function(RED) {
|
|||||||
var output = msg[property];
|
var output = msg[property];
|
||||||
if (node.complete !== "false" && typeof node.complete !== "undefined") {
|
if (node.complete !== "false" && typeof node.complete !== "undefined") {
|
||||||
property = node.complete;
|
property = node.complete;
|
||||||
try {
|
try { output = RED.util.getMessageProperty(msg,node.complete); }
|
||||||
output = RED.util.getMessageProperty(msg,node.complete);
|
catch(err) { output = undefined; }
|
||||||
} catch(err) {
|
|
||||||
output = undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
done(null,{id:node.id, z:node.z, _alias: node._alias, path:node._flow.path, name:node.name, topic:msg.topic, property:property, msg:output});
|
done(null,{id:node.id, z:node.z, _alias: node._alias, path:node._flow.path, name:node.name, topic:msg.topic, property:property, msg:output});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function prepareStatus(msg, done) {
|
||||||
|
if (node.statusType === "auto") {
|
||||||
|
if (node.complete === "true") {
|
||||||
|
done(null,{msg:msg.payload});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prepareValue(msg,function(err,debugMsg) {
|
||||||
|
if (err) { node.error(err); return; }
|
||||||
|
done(null,{msg:debugMsg.msg});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Either apply the jsonata expression or...
|
||||||
|
if (preparedStatExpression) {
|
||||||
|
RED.util.evaluateJSONataExpression(preparedStatExpression, msg, (err, value) => {
|
||||||
|
if (err) { done(RED._("debug.invalid-exp", {error:editExpression})); }
|
||||||
|
else { done(null,{msg:value}); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Extract the required message property
|
||||||
|
var output;
|
||||||
|
try { output = RED.util.getMessageProperty(msg,node.statusVal); }
|
||||||
|
catch(err) { output = undefined; }
|
||||||
|
done(null,{msg:output});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.on("input", function(msg, send, done) {
|
this.on("input", function(msg, send, done) {
|
||||||
|
if (node.tostatus === true) {
|
||||||
|
prepareStatus(msg, function(err,debugMsg) {
|
||||||
|
if (err) { node.error(err); return; }
|
||||||
|
var output = debugMsg.msg;
|
||||||
|
var st = (typeof output === 'string') ? output : util.inspect(output);
|
||||||
|
var fill = "grey";
|
||||||
|
var shape = "dot";
|
||||||
|
if (node.statusType === "auto") {
|
||||||
|
if (msg.hasOwnProperty("error")) {
|
||||||
|
fill = "red";
|
||||||
|
st = msg.error.message;
|
||||||
|
}
|
||||||
|
if (msg.hasOwnProperty("status")) {
|
||||||
|
if (msg.status.hasOwnProperty("fill")) { fill = msg.status.fill; }
|
||||||
|
if (msg.status.hasOwnProperty("shape")) { shape = msg.status.shape; }
|
||||||
|
if (msg.status.hasOwnProperty("text")) { st = msg.status.text; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (st.length > 32) { st = st.substr(0,32) + "..."; }
|
||||||
|
node.status({fill:fill, shape:shape, text:st});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (this.complete === "true") {
|
if (this.complete === "true") {
|
||||||
// debug complete msg object
|
// debug complete msg object
|
||||||
if (this.console === "true") {
|
if (this.console === "true") {
|
||||||
@ -91,7 +131,8 @@ module.exports = function(RED) {
|
|||||||
sendDebug({id:node.id, z:node.z, _alias: node._alias, path:node._flow.path, name:node.name, topic:msg.topic, msg:msg});
|
sendDebug({id:node.id, z:node.z, _alias: node._alias, path:node._flow.path, name:node.name, topic:msg.topic, msg:msg});
|
||||||
}
|
}
|
||||||
done();
|
done();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
prepareValue(msg,function(err,debugMsg) {
|
prepareValue(msg,function(err,debugMsg) {
|
||||||
if (err) {
|
if (err) {
|
||||||
node.error(err);
|
node.error(err);
|
||||||
@ -107,12 +148,6 @@ module.exports = function(RED) {
|
|||||||
node.log(util.inspect(output, {colors:useColors}));
|
node.log(util.inspect(output, {colors:useColors}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node.tostatus === true) {
|
|
||||||
var st = (typeof output === 'string')?output:util.inspect(output);
|
|
||||||
var severity = node.severity;
|
|
||||||
if (st.length > 32) { st = st.substr(0,32) + "..."; }
|
|
||||||
node.status({fill:colors[severity], shape:"dot", text:st});
|
|
||||||
}
|
|
||||||
if (node.active) {
|
if (node.active) {
|
||||||
if (node.tosidebar == true) {
|
if (node.tosidebar == true) {
|
||||||
sendDebug(debugMsg);
|
sendDebug(debugMsg);
|
||||||
@ -150,24 +185,49 @@ module.exports = function(RED) {
|
|||||||
});
|
});
|
||||||
RED.log.addHandler(DebugNode.logHandler);
|
RED.log.addHandler(DebugNode.logHandler);
|
||||||
|
|
||||||
RED.httpAdmin.post("/debug/:id/:state", RED.auth.needsPermission("debug.write"), function(req,res) {
|
function setNodeState(node,state) {
|
||||||
var node = RED.nodes.getNode(req.params.id);
|
if (state) {
|
||||||
var state = req.params.state;
|
node.active = true;
|
||||||
if (node !== null && typeof node !== "undefined" ) {
|
if (node.tostatus) { node.status({fill:"grey", shape:"dot"}); }
|
||||||
if (state === "enable") {
|
} else {
|
||||||
node.active = true;
|
node.active = false;
|
||||||
res.sendStatus(200);
|
if (node.tostatus && node.hasOwnProperty("oldStatus")) {
|
||||||
if (node.tostatus) { node.status({fill:"grey", shape:"dot"}); }
|
node.oldStatus.shape = "dot";
|
||||||
} else if (state === "disable") {
|
node.status(node.oldStatus);
|
||||||
node.active = false;
|
|
||||||
res.sendStatus(201);
|
|
||||||
if (node.tostatus && node.hasOwnProperty("oldStatus")) {
|
|
||||||
node.oldStatus.shape = "dot";
|
|
||||||
node.status(node.oldStatus);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.sendStatus(404);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RED.httpAdmin.post("/debug/:state", RED.auth.needsPermission("debug.write"), function(req,res) {
|
||||||
|
var state = req.params.state;
|
||||||
|
if (state !== 'enable' && state !== 'disable') {
|
||||||
|
res.sendStatus(404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var nodes = req.body && req.body.nodes;
|
||||||
|
if (Array.isArray(nodes)) {
|
||||||
|
nodes.forEach(function(id) {
|
||||||
|
var node = RED.nodes.getNode(id);
|
||||||
|
if (node !== null && typeof node !== "undefined" ) {
|
||||||
|
setNodeState(node, state === "enable");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res.sendStatus(state === "enable" ? 200 : 201);
|
||||||
|
} else {
|
||||||
|
res.sendStatus(400);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
RED.httpAdmin.post("/debug/:id/:state", RED.auth.needsPermission("debug.write"), function(req,res) {
|
||||||
|
var state = req.params.state;
|
||||||
|
if (state !== 'enable' && state !== 'disable') {
|
||||||
|
res.sendStatus(404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var node = RED.nodes.getNode(req.params.id);
|
||||||
|
if (node !== null && typeof node !== "undefined" ) {
|
||||||
|
setNodeState(node,state === "enable");
|
||||||
|
res.sendStatus(state === "enable" ? 200 : 201);
|
||||||
} else {
|
} else {
|
||||||
res.sendStatus(404);
|
res.sendStatus(404);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
<script type="text/x-red" data-template-name="complete">
|
<script type="text/html" data-template-name="complete">
|
||||||
<div class="form-row node-input-target-row">
|
<div class="form-row node-input-target-row">
|
||||||
<button id="node-input-complete-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
|
<button id="node-input-complete-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row node-input-target-row node-input-target-list-row" style="min-height: 100px">
|
<div class="form-row node-input-target-row node-input-target-list-row" style="position: relative; min-height: 100px">
|
||||||
|
<div style="position: absolute; top: -30px; right: 0;"><input type="text" id="node-input-complete-target-filter"></div>
|
||||||
<div id="node-input-complete-target-container-div"></div>
|
<div id="node-input-complete-target-container-div"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -45,6 +46,22 @@
|
|||||||
var editorRow = $("#dialog-form>div.node-input-target-list-row");
|
var editorRow = $("#dialog-form>div.node-input-target-list-row");
|
||||||
editorRow.css("height",height+"px");
|
editorRow.css("height",height+"px");
|
||||||
};
|
};
|
||||||
|
var search = $("#node-input-complete-target-filter").searchBox({
|
||||||
|
style: "compact",
|
||||||
|
delay: 300,
|
||||||
|
change: function() {
|
||||||
|
var val = $(this).val().trim().toLowerCase();
|
||||||
|
if (val === "") {
|
||||||
|
dirList.treeList("filter", null);
|
||||||
|
search.searchBox("count","");
|
||||||
|
} else {
|
||||||
|
var count = dirList.treeList("filter", function(item) {
|
||||||
|
return item.label.toLowerCase().indexOf(val) > -1 || item.node.type.toLowerCase().indexOf(val) > -1
|
||||||
|
});
|
||||||
|
search.searchBox("count",count+" / "+candidateNodes.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var dirList = $("#node-input-complete-target-container-div").css({width: "100%", height: "100%"})
|
var dirList = $("#node-input-complete-target-container-div").css({width: "100%", height: "100%"})
|
||||||
.treeList({multi:true}).on("treelistitemmouseover", function(e, item) {
|
.treeList({multi:true}).on("treelistitemmouseover", function(e, item) {
|
||||||
@ -89,7 +106,8 @@
|
|||||||
node: n,
|
node: n,
|
||||||
label: label,
|
label: label,
|
||||||
sublabel: sublabel,
|
sublabel: sublabel,
|
||||||
selected: isChecked
|
selected: isChecked,
|
||||||
|
checkbox: true
|
||||||
};
|
};
|
||||||
items.push(nodeItemMap[n.id]);
|
items.push(nodeItemMap[n.id]);
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="catch">
|
<script type="text/html" data-template-name="catch">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label style="width: auto" for="node-input-scope" data-i18n="catch.label.source"></label>
|
<label style="width: auto" for="node-input-scope" data-i18n="catch.label.source"></label>
|
||||||
<select id="node-input-scope-select">
|
<select id="node-input-scope-select">
|
||||||
@ -14,7 +14,8 @@
|
|||||||
<div class="form-row node-input-target-row">
|
<div class="form-row node-input-target-row">
|
||||||
<button id="node-input-catch-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
|
<button id="node-input-catch-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row node-input-target-row node-input-target-list-row" style="min-height: 100px">
|
<div class="form-row node-input-target-row node-input-target-list-row" style="position: relative; min-height: 100px">
|
||||||
|
<div style="position: absolute; top: -30px; right: 0;"><input type="text" id="node-input-catch-target-filter"></div>
|
||||||
<div id="node-input-catch-target-container-div"></div>
|
<div id="node-input-catch-target-container-div"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -60,7 +61,22 @@
|
|||||||
var editorRow = $("#dialog-form>div.node-input-target-list-row");
|
var editorRow = $("#dialog-form>div.node-input-target-list-row");
|
||||||
editorRow.css("height",height+"px");
|
editorRow.css("height",height+"px");
|
||||||
};
|
};
|
||||||
|
var search = $("#node-input-catch-target-filter").searchBox({
|
||||||
|
style: "compact",
|
||||||
|
delay: 300,
|
||||||
|
change: function() {
|
||||||
|
var val = $(this).val().trim().toLowerCase();
|
||||||
|
if (val === "") {
|
||||||
|
dirList.treeList("filter", null);
|
||||||
|
search.searchBox("count","");
|
||||||
|
} else {
|
||||||
|
var count = dirList.treeList("filter", function(item) {
|
||||||
|
return item.label.toLowerCase().indexOf(val) > -1 || item.node.type.toLowerCase().indexOf(val) > -1
|
||||||
|
});
|
||||||
|
search.searchBox("count",count+" / "+candidateNodes.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
var dirList = $("#node-input-catch-target-container-div").css({width: "100%", height: "100%"})
|
var dirList = $("#node-input-catch-target-container-div").css({width: "100%", height: "100%"})
|
||||||
.treeList({multi:true}).on("treelistitemmouseover", function(e, item) {
|
.treeList({multi:true}).on("treelistitemmouseover", function(e, item) {
|
||||||
item.node.highlighted = true;
|
item.node.highlighted = true;
|
||||||
@ -104,7 +120,8 @@
|
|||||||
node: n,
|
node: n,
|
||||||
label: label,
|
label: label,
|
||||||
sublabel: sublabel,
|
sublabel: sublabel,
|
||||||
selected: isChecked
|
selected: isChecked,
|
||||||
|
checkbox: true
|
||||||
};
|
};
|
||||||
items.push(nodeItemMap[n.id]);
|
items.push(nodeItemMap[n.id]);
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="status">
|
<script type="text/html" data-template-name="status">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label style="width: auto" for="node-input-scope" data-i18n="status.label.source"></label>
|
<label style="width: auto" for="node-input-scope" data-i18n="status.label.source"></label>
|
||||||
<select id="node-input-scope-select">
|
<select id="node-input-scope-select">
|
||||||
@ -10,7 +10,8 @@
|
|||||||
<div class="form-row node-input-target-row">
|
<div class="form-row node-input-target-row">
|
||||||
<button id="node-input-status-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
|
<button id="node-input-status-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row node-input-target-row node-input-target-list-row" style="min-height: 100px">
|
<div class="form-row node-input-target-row node-input-target-list-row" style="position: relative; min-height: 100px">
|
||||||
|
<div style="position: absolute; top: -30px; right: 0;"><input type="text" id="node-input-status-target-filter"></div>
|
||||||
<div id="node-input-status-target-container-div"></div>
|
<div id="node-input-status-target-container-div"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -48,6 +49,22 @@
|
|||||||
var editorRow = $("#dialog-form>div.node-input-target-list-row");
|
var editorRow = $("#dialog-form>div.node-input-target-list-row");
|
||||||
editorRow.css("height",height+"px");
|
editorRow.css("height",height+"px");
|
||||||
};
|
};
|
||||||
|
var search = $("#node-input-status-target-filter").searchBox({
|
||||||
|
style: "compact",
|
||||||
|
delay: 300,
|
||||||
|
change: function() {
|
||||||
|
var val = $(this).val().trim().toLowerCase();
|
||||||
|
if (val === "") {
|
||||||
|
dirList.treeList("filter", null);
|
||||||
|
search.searchBox("count","");
|
||||||
|
} else {
|
||||||
|
var count = dirList.treeList("filter", function(item) {
|
||||||
|
return item.label.toLowerCase().indexOf(val) > -1 || item.node.type.toLowerCase().indexOf(val) > -1
|
||||||
|
});
|
||||||
|
search.searchBox("count",count+" / "+candidateNodes.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var dirList = $("#node-input-status-target-container-div").css({width: "100%", height: "100%"})
|
var dirList = $("#node-input-status-target-container-div").css({width: "100%", height: "100%"})
|
||||||
.treeList({multi:true}).on("treelistitemmouseover", function(e, item) {
|
.treeList({multi:true}).on("treelistitemmouseover", function(e, item) {
|
||||||
@ -92,7 +109,8 @@
|
|||||||
node: n,
|
node: n,
|
||||||
label: label,
|
label: label,
|
||||||
sublabel: sublabel,
|
sublabel: sublabel,
|
||||||
selected: isChecked
|
selected: isChecked,
|
||||||
|
checkbox: true
|
||||||
};
|
};
|
||||||
items.push(nodeItemMap[n.id]);
|
items.push(nodeItemMap[n.id]);
|
||||||
});
|
});
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="link in">
|
<script type="text/html" data-template-name="link in">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
</div>
|
</div>
|
||||||
|
<div style="position:relative; height: 30px; text-align: right;"><div style="display:inline-block"><input type="text" id="node-input-link-target-filter"></div></div>
|
||||||
<div class="form-row node-input-link-row"></div>
|
<div class="form-row node-input-link-row"></div>
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-red" data-template-name="link out">
|
<script type="text/html" data-template-name="link out">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
</div>
|
</div>
|
||||||
|
<div style="position:relative; height: 30px; text-align: right;"><div style="display:inline-block"><input type="text" id="node-input-link-target-filter"></div></div>
|
||||||
<div class="form-row node-input-link-row"></div>
|
<div class="form-row node-input-link-row"></div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -47,6 +49,24 @@
|
|||||||
});
|
});
|
||||||
var candidateNodes = RED.nodes.filterNodes({type:targetType});
|
var candidateNodes = RED.nodes.filterNodes({type:targetType});
|
||||||
|
|
||||||
|
var search = $("#node-input-link-target-filter").searchBox({
|
||||||
|
style: "compact",
|
||||||
|
delay: 300,
|
||||||
|
change: function() {
|
||||||
|
var val = $(this).val().trim().toLowerCase();
|
||||||
|
if (val === "") {
|
||||||
|
treeList.treeList("filter", null);
|
||||||
|
search.searchBox("count","");
|
||||||
|
} else {
|
||||||
|
var count = treeList.treeList("filter", function(item) {
|
||||||
|
return item.label.toLowerCase().indexOf(val) > -1 || (item.node && item.node.type.toLowerCase().indexOf(val) > -1)
|
||||||
|
});
|
||||||
|
search.searchBox("count",count+" / "+candidateNodes.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
var flows = [];
|
var flows = [];
|
||||||
var flowMap = {};
|
var flowMap = {};
|
||||||
|
|
||||||
@ -83,7 +103,8 @@
|
|||||||
id: n.id,
|
id: n.id,
|
||||||
node: n,
|
node: n,
|
||||||
label: n.name||n.id,
|
label: n.name||n.id,
|
||||||
selected: isChecked
|
selected: isChecked,
|
||||||
|
checkbox: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="comment">
|
<script type="text/html" data-template-name="comment">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="unknown">
|
<script type="text/html" data-template-name="unknown">
|
||||||
<div class="form-tips"><span data-i18n="[html]unknown.tip"></span></div>
|
<div class="form-tips"><span data-i18n="[html]unknown.tip"></span></div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,22 +1,57 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="function">
|
<script type="text/html" data-template-name="function">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<div style="display: inline-block; width: calc(100% - 105px)"><input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></div>
|
<div style="display: inline-block; width: calc(100% - 105px)"><input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row" style="margin-bottom: 0px;">
|
|
||||||
<label for="node-input-func"><i class="fa fa-wrench"></i> <span data-i18n="function.label.function"></span></label>
|
<div class="form-row">
|
||||||
<input type="hidden" id="node-input-func" autofocus="autofocus">
|
<ul style="min-width: 600px; margin-bottom: 20px;" id="func-tabs"></ul>
|
||||||
<input type="hidden" id="node-input-noerr">
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row node-text-editor-row" style="position:relative">
|
|
||||||
<div style="position: absolute; right:0; bottom:calc(100% + 3px);"><button id="node-function-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
|
<div id="func-tabs-content" style="min-height: calc(100% - 95px);">
|
||||||
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-func-editor" ></div>
|
|
||||||
</div>
|
<div id="func-tab-init" style="display:none">
|
||||||
<div class="form-row" style="margin-bottom: 0px">
|
<div class="form-row" style="margin-bottom: 0px;">
|
||||||
<label for="node-input-outputs"><i class="fa fa-random"></i> <span data-i18n="function.label.outputs"></span></label>
|
<input type="hidden" id="node-input-initialize" autofocus="autofocus">
|
||||||
<input id="node-input-outputs" style="width: 60px;" value="1">
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row node-text-editor-row" style="position:relative">
|
||||||
|
<div style="position: absolute; right:0; bottom: calc(100% + 3px);"><button id="node-init-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
|
||||||
|
<div style="height: 250px; min-height:150px; margin-top: 30px;" class="node-text-editor" id="node-input-init-editor" ></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="func-tab-body" style="display:none">
|
||||||
|
<div class="form-row" style="margin-bottom: 0px;">
|
||||||
|
<input type="hidden" id="node-input-func" autofocus="autofocus">
|
||||||
|
<input type="hidden" id="node-input-noerr">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row node-text-editor-row" style="position:relative">
|
||||||
|
<div style="position: absolute; right:0; bottom: calc(100% + 3px);"><button id="node-function-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
|
||||||
|
<div style="height: 220px; min-height:120px; margin-top: 30px;" class="node-text-editor" id="node-input-func-editor" ></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row" style="margin-bottom: 0px">
|
||||||
|
<label for="node-input-outputs"><i class="fa fa-random"></i> <span data-i18n="function.label.outputs"></span></label>
|
||||||
|
<input id="node-input-outputs" style="width: 60px;" value="1">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="func-tab-finalize" style="display:none">
|
||||||
|
<div class="form-row" style="margin-bottom: 0px;">
|
||||||
|
<input type="hidden" id="node-input-finalize" autofocus="autofocus">
|
||||||
|
</div>
|
||||||
|
<div class="form-row node-text-editor-row" style="position:relative">
|
||||||
|
<div style="position: absolute; right:0; bottom: calc(100% + 3px);"><button id="node-finalize-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div>
|
||||||
|
<div style="height: 250px; min-height:150px; margin-top: 30px;" class="node-text-editor" id="node-input-finalize-editor" ></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@ -27,7 +62,9 @@
|
|||||||
name: {value:""},
|
name: {value:""},
|
||||||
func: {value:"\nreturn msg;"},
|
func: {value:"\nreturn msg;"},
|
||||||
outputs: {value:1},
|
outputs: {value:1},
|
||||||
noerr: {value:0,required:true,validate:function(v) { return !v; }}
|
noerr: {value:0,required:true,validate:function(v) { return !v; }},
|
||||||
|
initialize: {value:""},
|
||||||
|
finalize: {value:""}
|
||||||
},
|
},
|
||||||
inputs:1,
|
inputs:1,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
@ -40,6 +77,28 @@
|
|||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
|
var tabs = RED.tabs.create({
|
||||||
|
id: "func-tabs",
|
||||||
|
onchange: function(tab) {
|
||||||
|
$("#func-tabs-content").children().hide();
|
||||||
|
$("#" + tab.id).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tabs.addTab({
|
||||||
|
id: "func-tab-init",
|
||||||
|
label: that._("function.label.initialize")
|
||||||
|
});
|
||||||
|
tabs.addTab({
|
||||||
|
id: "func-tab-body",
|
||||||
|
label: that._("function.label.function")
|
||||||
|
});
|
||||||
|
tabs.addTab({
|
||||||
|
id: "func-tab-finalize",
|
||||||
|
label: that._("function.label.finalize")
|
||||||
|
});
|
||||||
|
tabs.activateTab("func-tab-body");
|
||||||
|
|
||||||
$( "#node-input-outputs" ).spinner({
|
$( "#node-input-outputs" ).spinner({
|
||||||
min:0,
|
min:0,
|
||||||
change: function(event, ui) {
|
change: function(event, ui) {
|
||||||
@ -50,74 +109,147 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor = RED.editor.createEditor({
|
var buildEditor = function(id, value, defaultValue) {
|
||||||
id: 'node-input-func-editor',
|
var editor = RED.editor.createEditor({
|
||||||
mode: 'ace/mode/nrjavascript',
|
id: id,
|
||||||
value: $("#node-input-func").val(),
|
mode: 'ace/mode/nrjavascript',
|
||||||
globals: {
|
value: value || defaultValue || "",
|
||||||
msg:true,
|
globals: {
|
||||||
context:true,
|
msg:true,
|
||||||
RED: true,
|
context:true,
|
||||||
util: true,
|
RED: true,
|
||||||
flow: true,
|
util: true,
|
||||||
global: true,
|
flow: true,
|
||||||
console: true,
|
global: true,
|
||||||
Buffer: true,
|
console: true,
|
||||||
setTimeout: true,
|
Buffer: true,
|
||||||
clearTimeout: true,
|
setTimeout: true,
|
||||||
setInterval: true,
|
clearTimeout: true,
|
||||||
clearInterval: true
|
setInterval: true,
|
||||||
|
clearInterval: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (defaultValue && value === "") {
|
||||||
|
editor.moveCursorTo(defaultValue.split("\n").length - 1, 0);
|
||||||
}
|
}
|
||||||
});
|
return editor;
|
||||||
|
}
|
||||||
|
this.initEditor = buildEditor('node-input-init-editor',$("#node-input-initialize").val(),RED._("node-red:function.text.initialize"))
|
||||||
|
this.editor = buildEditor('node-input-func-editor',$("#node-input-func").val())
|
||||||
|
this.finalizeEditor = buildEditor('node-input-finalize-editor',$("#node-input-finalize").val(),RED._("node-red:function.text.finalize"))
|
||||||
|
|
||||||
RED.library.create({
|
RED.library.create({
|
||||||
url:"functions", // where to get the data from
|
url:"functions", // where to get the data from
|
||||||
type:"function", // the type of object the library is for
|
type:"function", // the type of object the library is for
|
||||||
editor:this.editor, // the field name the main text body goes to
|
editor:this.editor, // the field name the main text body goes to
|
||||||
mode:"ace/mode/nrjavascript",
|
mode:"ace/mode/nrjavascript",
|
||||||
fields:['name','outputs'],
|
fields:[
|
||||||
|
'name', 'outputs',
|
||||||
|
{
|
||||||
|
name: 'initialize',
|
||||||
|
get: function() {
|
||||||
|
return that.initEditor.getValue();
|
||||||
|
},
|
||||||
|
set: function(v) {
|
||||||
|
that.initEditor.setValue(v||RED._("node-red:function.text.initialize"), -1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'finalize',
|
||||||
|
get: function() {
|
||||||
|
return that.finalizeEditor.getValue();
|
||||||
|
},
|
||||||
|
set: function(v) {
|
||||||
|
that.finalizeEditor.setValue(v||RED._("node-red:function.text.finalize"), -1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'info',
|
||||||
|
get: function() {
|
||||||
|
return that.infoEditor.getValue();
|
||||||
|
},
|
||||||
|
set: function(v) {
|
||||||
|
that.infoEditor.setValue(v||"", -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
ext:"js"
|
ext:"js"
|
||||||
});
|
});
|
||||||
this.editor.focus();
|
this.editor.focus();
|
||||||
|
|
||||||
RED.popover.tooltip($("#node-function-expand-js"), RED._("node-red:common.label.expand"));
|
|
||||||
|
|
||||||
$("#node-function-expand-js").on("click", function(e) {
|
var expandButtonClickHandler = function(editor) {
|
||||||
e.preventDefault();
|
return function(e) {
|
||||||
var value = that.editor.getValue();
|
e.preventDefault();
|
||||||
RED.editor.editJavaScript({
|
var value = editor.getValue();
|
||||||
value: value,
|
RED.editor.editJavaScript({
|
||||||
width: "Infinity",
|
value: value,
|
||||||
cursor: that.editor.getCursorPosition(),
|
width: "Infinity",
|
||||||
mode: "ace/mode/nrjavascript",
|
cursor: editor.getCursorPosition(),
|
||||||
complete: function(v,cursor) {
|
mode: "ace/mode/nrjavascript",
|
||||||
that.editor.setValue(v, -1);
|
complete: function(v,cursor) {
|
||||||
that.editor.gotoLine(cursor.row+1,cursor.column,false);
|
editor.setValue(v, -1);
|
||||||
setTimeout(function() {
|
editor.gotoLine(cursor.row+1,cursor.column,false);
|
||||||
that.editor.focus();
|
setTimeout(function() {
|
||||||
},300);
|
editor.focus();
|
||||||
}
|
},300);
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
},
|
|
||||||
oneditsave: function() {
|
|
||||||
var annot = this.editor.getSession().getAnnotations();
|
|
||||||
this.noerr = 0;
|
|
||||||
$("#node-input-noerr").val(0);
|
|
||||||
for (var k=0; k < annot.length; k++) {
|
|
||||||
//console.log(annot[k].type,":",annot[k].text, "on line", annot[k].row);
|
|
||||||
if (annot[k].type === "error") {
|
|
||||||
$("#node-input-noerr").val(annot.length);
|
|
||||||
this.noerr = annot.length;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$("#node-input-func").val(this.editor.getValue());
|
$("#node-init-expand-js").on("click", expandButtonClickHandler(this.initEditor));
|
||||||
this.editor.destroy();
|
$("#node-function-expand-js").on("click", expandButtonClickHandler(this.editor));
|
||||||
delete this.editor;
|
$("#node-finalize-expand-js").on("click", expandButtonClickHandler(this.finalizeEditor));
|
||||||
|
|
||||||
|
RED.popover.tooltip($("#node-init-expand-js"), RED._("node-red:common.label.expand"));
|
||||||
|
RED.popover.tooltip($("#node-function-expand-js"), RED._("node-red:common.label.expand"));
|
||||||
|
RED.popover.tooltip($("#node-finalize-expand-js"), RED._("node-red:common.label.expand"));
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
oneditsave: function() {
|
||||||
|
var node = this;
|
||||||
|
var noerr = 0;
|
||||||
|
$("#node-input-noerr").val(0);
|
||||||
|
|
||||||
|
var disposeEditor = function(editorName,targetName,defaultValue) {
|
||||||
|
var editor = node[editorName];
|
||||||
|
var annot = editor.getSession().getAnnotations();
|
||||||
|
for (var k=0; k < annot.length; k++) {
|
||||||
|
if (annot[k].type === "error") {
|
||||||
|
noerr += annot.length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var val = editor.getValue();
|
||||||
|
if (defaultValue) {
|
||||||
|
if (val.trim() == defaultValue.trim()) {
|
||||||
|
val = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editor.destroy();
|
||||||
|
delete node[editorName];
|
||||||
|
$("#"+targetName).val(val);
|
||||||
|
}
|
||||||
|
disposeEditor("editor","node-input-func");
|
||||||
|
disposeEditor("initEditor","node-input-initialize", RED._("node-red:function.text.initialize"));
|
||||||
|
disposeEditor("finalizeEditor","node-input-finalize", RED._("node-red:function.text.finalize"));
|
||||||
|
|
||||||
|
$("#node-input-noerr").val(noerr);
|
||||||
|
this.noerr = noerr;
|
||||||
|
|
||||||
},
|
},
|
||||||
oneditcancel: function() {
|
oneditcancel: function() {
|
||||||
this.editor.destroy();
|
var node = this;
|
||||||
delete this.editor;
|
|
||||||
|
node.editor.destroy();
|
||||||
|
delete node.editor;
|
||||||
|
|
||||||
|
node.initEditor.destroy();
|
||||||
|
delete node.initEditor;
|
||||||
|
|
||||||
|
node.finalizeEditor.destroy();
|
||||||
|
delete node.finalizeEditor;
|
||||||
},
|
},
|
||||||
oneditresize: function(size) {
|
oneditresize: function(size) {
|
||||||
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
|
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
|
||||||
@ -129,6 +261,16 @@
|
|||||||
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
|
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
|
||||||
$(".node-text-editor").css("height",height+"px");
|
$(".node-text-editor").css("height",height+"px");
|
||||||
this.editor.resize();
|
this.editor.resize();
|
||||||
|
|
||||||
|
var height = size.height;
|
||||||
|
$("#node-input-init-editor").css("height", (height -105)+"px");
|
||||||
|
$("#node-input-func-editor").css("height", (height -145)+"px");
|
||||||
|
$("#node-input-finalize-editor").css("height", (height -105)+"px");
|
||||||
|
|
||||||
|
this.initEditor.resize();
|
||||||
|
this.editor.resize();
|
||||||
|
this.finalizeEditor.resize();
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -57,22 +57,55 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createVMOpt(node, kind) {
|
||||||
|
var opt = {
|
||||||
|
filename: 'Function node'+kind+':'+node.id+(node.name?' ['+node.name+']':''), // filename for stack traces
|
||||||
|
displayErrors: true
|
||||||
|
// Using the following options causes node 4/6 to not include the line number
|
||||||
|
// in the stack output. So don't use them.
|
||||||
|
// lineOffset: -11, // line number offset to be used for stack traces
|
||||||
|
// columnOffset: 0, // column number offset to be used for stack traces
|
||||||
|
};
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateErrorInfo(err) {
|
||||||
|
if (err.stack) {
|
||||||
|
var stack = err.stack.toString();
|
||||||
|
var m = /^([^:]+):([^:]+):(\d+).*/.exec(stack);
|
||||||
|
if (m) {
|
||||||
|
var line = parseInt(m[3]) -1;
|
||||||
|
var kind = "body:";
|
||||||
|
if (/setup/.exec(m[1])) {
|
||||||
|
kind = "setup:";
|
||||||
|
}
|
||||||
|
if (/cleanup/.exec(m[1])) {
|
||||||
|
kind = "cleanup:";
|
||||||
|
}
|
||||||
|
err.message += " ("+kind+"line "+line+")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function FunctionNode(n) {
|
function FunctionNode(n) {
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
var node = this;
|
var node = this;
|
||||||
this.name = n.name;
|
node.name = n.name;
|
||||||
this.func = n.func;
|
node.func = n.func;
|
||||||
|
node.ini = n.initialize ? n.initialize.trim() : "";
|
||||||
|
node.fin = n.finalize ? n.finalize.trim() : "";
|
||||||
|
|
||||||
var handleNodeDoneCall = true;
|
var handleNodeDoneCall = true;
|
||||||
|
|
||||||
// Check to see if the Function appears to call `node.done()`. If so,
|
// Check to see if the Function appears to call `node.done()`. If so,
|
||||||
// we will assume it is well written and does actually call node.done().
|
// we will assume it is well written and does actually call node.done().
|
||||||
// Otherwise, we will call node.done() after the function returns regardless.
|
// Otherwise, we will call node.done() after the function returns regardless.
|
||||||
if (/node\.done\s*\(\s*\)/.test(this.func)) {
|
if (/node\.done\s*\(\s*\)/.test(node.func)) {
|
||||||
handleNodeDoneCall = false;
|
handleNodeDoneCall = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var functionText = "var results = null;"+
|
var functionText = "var results = null;"+
|
||||||
"results = (function(msg,__send__,__done__){ "+
|
"results = (async function(msg,__send__,__done__){ "+
|
||||||
"var __msgid__ = msg._msgid;"+
|
"var __msgid__ = msg._msgid;"+
|
||||||
"var node = {"+
|
"var node = {"+
|
||||||
"id:__node__.id,"+
|
"id:__node__.id,"+
|
||||||
@ -87,11 +120,13 @@ module.exports = function(RED) {
|
|||||||
"send:function(msgs,cloneMsg){ __node__.send(__send__,__msgid__,msgs,cloneMsg);},"+
|
"send:function(msgs,cloneMsg){ __node__.send(__send__,__msgid__,msgs,cloneMsg);},"+
|
||||||
"done:__done__"+
|
"done:__done__"+
|
||||||
"};\n"+
|
"};\n"+
|
||||||
this.func+"\n"+
|
node.func+"\n"+
|
||||||
"})(msg,send,done);";
|
"})(msg,send,done);";
|
||||||
this.topic = n.topic;
|
var finScript = null;
|
||||||
this.outstandingTimers = [];
|
var finOpt = null;
|
||||||
this.outstandingIntervals = [];
|
node.topic = n.topic;
|
||||||
|
node.outstandingTimers = [];
|
||||||
|
node.outstandingIntervals = [];
|
||||||
var sandbox = {
|
var sandbox = {
|
||||||
console:console,
|
console:console,
|
||||||
util:util,
|
util:util,
|
||||||
@ -182,12 +217,12 @@ module.exports = function(RED) {
|
|||||||
arguments[0] = function() {
|
arguments[0] = function() {
|
||||||
sandbox.clearTimeout(timerId);
|
sandbox.clearTimeout(timerId);
|
||||||
try {
|
try {
|
||||||
func.apply(this,arguments);
|
func.apply(node,arguments);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
node.error(err,{});
|
node.error(err,{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
timerId = setTimeout.apply(this,arguments);
|
timerId = setTimeout.apply(node,arguments);
|
||||||
node.outstandingTimers.push(timerId);
|
node.outstandingTimers.push(timerId);
|
||||||
return timerId;
|
return timerId;
|
||||||
},
|
},
|
||||||
@ -203,12 +238,12 @@ module.exports = function(RED) {
|
|||||||
var timerId;
|
var timerId;
|
||||||
arguments[0] = function() {
|
arguments[0] = function() {
|
||||||
try {
|
try {
|
||||||
func.apply(this,arguments);
|
func.apply(node,arguments);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
node.error(err,{});
|
node.error(err,{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
timerId = setInterval.apply(this,arguments);
|
timerId = setInterval.apply(node,arguments);
|
||||||
node.outstandingIntervals.push(timerId);
|
node.outstandingIntervals.push(timerId);
|
||||||
return timerId;
|
return timerId;
|
||||||
},
|
},
|
||||||
@ -226,37 +261,48 @@ module.exports = function(RED) {
|
|||||||
sandbox.setTimeout(function(){ resolve(value); }, after);
|
sandbox.setTimeout(function(){ resolve(value); }, after);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
sandbox.promisify = util.promisify;
|
||||||
}
|
}
|
||||||
var context = vm.createContext(sandbox);
|
var context = vm.createContext(sandbox);
|
||||||
try {
|
try {
|
||||||
this.script = vm.createScript(functionText, {
|
var iniScript = null;
|
||||||
filename: 'Function node:'+this.id+(this.name?' ['+this.name+']':''), // filename for stack traces
|
var iniOpt = null;
|
||||||
displayErrors: true
|
if (node.ini && (node.ini !== "")) {
|
||||||
// Using the following options causes node 4/6 to not include the line number
|
var iniText = "(async function () {\n"+node.ini +"\n})();";
|
||||||
// in the stack output. So don't use them.
|
iniOpt = createVMOpt(node, " setup");
|
||||||
// lineOffset: -11, // line number offset to be used for stack traces
|
iniScript = new vm.Script(iniText, iniOpt);
|
||||||
// columnOffset: 0, // column number offset to be used for stack traces
|
}
|
||||||
});
|
node.script = vm.createScript(functionText, createVMOpt(node, ""));
|
||||||
this.on("input", function(msg,send,done) {
|
if (node.fin && (node.fin !== "")) {
|
||||||
try {
|
var finText = "(function () {\n"+node.fin +"\n})();";
|
||||||
var start = process.hrtime();
|
finOpt = createVMOpt(node, " cleanup");
|
||||||
context.msg = msg;
|
finScript = new vm.Script(finText, finOpt);
|
||||||
context.send = send;
|
}
|
||||||
context.done = done;
|
var promise = Promise.resolve();
|
||||||
|
if (iniScript) {
|
||||||
|
promise = iniScript.runInContext(context, iniOpt);
|
||||||
|
}
|
||||||
|
|
||||||
this.script.runInContext(context);
|
function processMessage(msg, send, done) {
|
||||||
sendResults(this,send,msg._msgid,context.results,false);
|
var start = process.hrtime();
|
||||||
|
context.msg = msg;
|
||||||
|
context.send = send;
|
||||||
|
context.done = done;
|
||||||
|
|
||||||
|
node.script.runInContext(context);
|
||||||
|
context.results.then(function(results) {
|
||||||
|
sendResults(node,send,msg._msgid,results,false);
|
||||||
if (handleNodeDoneCall) {
|
if (handleNodeDoneCall) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
var duration = process.hrtime(start);
|
var duration = process.hrtime(start);
|
||||||
var converted = Math.floor((duration[0] * 1e9 + duration[1])/10000)/100;
|
var converted = Math.floor((duration[0] * 1e9 + duration[1])/10000)/100;
|
||||||
this.metric("duration", msg, converted);
|
node.metric("duration", msg, converted);
|
||||||
if (process.env.NODE_RED_FUNCTION_TIME) {
|
if (process.env.NODE_RED_FUNCTION_TIME) {
|
||||||
this.status({fill:"yellow",shape:"dot",text:""+converted});
|
node.status({fill:"yellow",shape:"dot",text:""+converted});
|
||||||
}
|
}
|
||||||
} catch(err) {
|
}).catch(err => {
|
||||||
if ((typeof err === "object") && err.hasOwnProperty("stack")) {
|
if ((typeof err === "object") && err.hasOwnProperty("stack")) {
|
||||||
//remove unwanted part
|
//remove unwanted part
|
||||||
var index = err.stack.search(/\n\s*at ContextifyScript.Script.runInContext/);
|
var index = err.stack.search(/\n\s*at ContextifyScript.Script.runInContext/);
|
||||||
@ -294,23 +340,67 @@ module.exports = function(RED) {
|
|||||||
else {
|
else {
|
||||||
done(JSON.stringify(err));
|
done(JSON.stringify(err));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const RESOLVING = 0;
|
||||||
|
const RESOLVED = 1;
|
||||||
|
const ERROR = 2;
|
||||||
|
var state = RESOLVING;
|
||||||
|
var messages = [];
|
||||||
|
|
||||||
|
node.on("input", function(msg,send,done) {
|
||||||
|
if(state === RESOLVING) {
|
||||||
|
messages.push({msg:msg, send:send, done:done});
|
||||||
|
}
|
||||||
|
else if(state === RESOLVED) {
|
||||||
|
processMessage(msg, send, done);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.on("close", function() {
|
node.on("close", function() {
|
||||||
|
if (finScript) {
|
||||||
|
try {
|
||||||
|
finScript.runInContext(context, finOpt);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
node.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
while (node.outstandingTimers.length > 0) {
|
while (node.outstandingTimers.length > 0) {
|
||||||
clearTimeout(node.outstandingTimers.pop());
|
clearTimeout(node.outstandingTimers.pop());
|
||||||
}
|
}
|
||||||
while (node.outstandingIntervals.length > 0) {
|
while (node.outstandingIntervals.length > 0) {
|
||||||
clearInterval(node.outstandingIntervals.pop());
|
clearInterval(node.outstandingIntervals.pop());
|
||||||
}
|
}
|
||||||
this.status({});
|
node.status({});
|
||||||
});
|
});
|
||||||
} catch(err) {
|
|
||||||
|
promise.then(function (v) {
|
||||||
|
var msgs = messages;
|
||||||
|
messages = [];
|
||||||
|
while (msgs.length > 0) {
|
||||||
|
msgs.forEach(function (s) {
|
||||||
|
processMessage(s.msg, s.send, s.done);
|
||||||
|
});
|
||||||
|
msgs = messages;
|
||||||
|
messages = [];
|
||||||
|
}
|
||||||
|
state = RESOLVED;
|
||||||
|
}).catch((error) => {
|
||||||
|
messages = [];
|
||||||
|
state = ERROR;
|
||||||
|
node.error(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
// eg SyntaxError - which v8 doesn't include line number information
|
// eg SyntaxError - which v8 doesn't include line number information
|
||||||
// so we can't do better than this
|
// so we can't do better than this
|
||||||
this.error(err);
|
updateErrorInfo(err);
|
||||||
|
node.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RED.nodes.registerType("function",FunctionNode);
|
RED.nodes.registerType("function",FunctionNode);
|
||||||
RED.library.register("functions");
|
RED.library.register("functions");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
for (var i=0; i<this.rules.length; i+=1) {
|
for (var i=0; i<this.rules.length; i+=1) {
|
||||||
var rule = this.rules[i];
|
var rule = this.rules[i];
|
||||||
needsCount = needsCount || ((rule.t === "tail") || (rule.t === "jsonata_exp"));
|
needsCount = needsCount || ((rule.t === "tail"));
|
||||||
if (!rule.vt) {
|
if (!rule.vt) {
|
||||||
if (!isNaN(Number(rule.v))) {
|
if (!isNaN(Number(rule.v))) {
|
||||||
rule.vt = 'num';
|
rule.vt = 'num';
|
||||||
|
@ -215,7 +215,9 @@ module.exports = function(RED) {
|
|||||||
if (rule.t === 'delete') {
|
if (rule.t === 'delete') {
|
||||||
RED.util.setMessageProperty(msg,property,undefined);
|
RED.util.setMessageProperty(msg,property,undefined);
|
||||||
} else if (rule.t === 'set') {
|
} else if (rule.t === 'set') {
|
||||||
RED.util.setMessageProperty(msg,property,value);
|
if (!RED.util.setMessageProperty(msg,property,value)) {
|
||||||
|
node.warn(RED._("change.errors.no-override",{property:property}));
|
||||||
|
}
|
||||||
} else if (rule.t === 'change') {
|
} else if (rule.t === 'change') {
|
||||||
current = RED.util.getMessageProperty(msg,property);
|
current = RED.util.getMessageProperty(msg,property);
|
||||||
if (typeof current === 'string') {
|
if (typeof current === 'string') {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="range">
|
<script type="text/html" data-template-name="range">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="common.label.property"></span></label>
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="common.label.property"></span></label>
|
||||||
<input type="text" id="node-input-property" style="width:calc(70% - 1px)"/>
|
<input type="text" id="node-input-property" style="width:calc(70% - 1px)"/>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="template">
|
<script type="text/html" data-template-name="template">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<div style="display: inline-block; width: calc(100% - 105px)"><input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></div>
|
<div style="display: inline-block; width: calc(100% - 105px)"><input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></div>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<script type="text/x-red" data-template-name="delay">
|
<script type="text/html" data-template-name="delay">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-delay-action"><i class="fa fa-tasks"></i> <span data-i18n="delay.action"></span></label>
|
<label for="node-input-delay-action"><i class="fa fa-tasks"></i> <span data-i18n="delay.action"></span></label>
|
||||||
<select id="node-input-delay-action" style="width:270px !important">
|
<select id="node-input-delay-action" style="width:270px !important">
|
||||||
|
@ -158,6 +158,7 @@ module.exports = function(RED) {
|
|||||||
clearInterval(node.intervalID);
|
clearInterval(node.intervalID);
|
||||||
node.intervalID = -1;
|
node.intervalID = -1;
|
||||||
}
|
}
|
||||||
|
delete node.lastSent;
|
||||||
node.buffer = [];
|
node.buffer = [];
|
||||||
node.status({text:"reset"});
|
node.status({text:"reset"});
|
||||||
return;
|
return;
|
||||||
|
@ -47,6 +47,10 @@
|
|||||||
<input type="hidden" id="node-input-op2type">
|
<input type="hidden" id="node-input-op2type">
|
||||||
<input style="width:70%" type="text" id="node-input-op2" placeholder="0">
|
<input style="width:70%" type="text" id="node-input-op2" placeholder="0">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row" id="node-second-output">
|
||||||
|
<label></label>
|
||||||
|
<input type="checkbox" id="node-input-second" style="margin-left: 0px; vertical-align: top; width: auto !important;"> <label style="width:auto !important;" for="node-input-second" data-i18n="trigger.second"></label>
|
||||||
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label data-i18n="trigger.label.reset" style="width:auto"></label>
|
<label data-i18n="trigger.label.reset" style="width:auto"></label>
|
||||||
<div style="display:inline-block; width:70%;vertical-align:top">
|
<div style="display:inline-block; width:70%;vertical-align:top">
|
||||||
@ -58,14 +62,18 @@
|
|||||||
<br/>
|
<br/>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label data-i18n="trigger.for" for="node-input-bytopic"></label>
|
<label data-i18n="trigger.for" for="node-input-bytopic"></label>
|
||||||
<select id="node-input-bytopic">
|
<select id="node-input-bytopic" style="width:120px;">
|
||||||
<option value="all" data-i18n="trigger.alltopics"></option>
|
<option value="all" data-i18n="trigger.alltopics"></option>
|
||||||
<option value="topic" data-i18n="trigger.bytopics"></option>
|
<option value="topic" data-i18n="trigger.bytopics"></option>
|
||||||
</select>
|
</select>
|
||||||
|
<span class="form-row" id="node-stream-topic">
|
||||||
|
<input type="text" id="node-input-topic" style="width:46%;"/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></input>
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></input>
|
||||||
|
<input type="hidden" id="node-input-outputs" value="1">
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -74,6 +82,7 @@
|
|||||||
category: 'function',
|
category: 'function',
|
||||||
color:"#E6E0F8",
|
color:"#E6E0F8",
|
||||||
defaults: {
|
defaults: {
|
||||||
|
name: {value:""},
|
||||||
op1: {value:"1", validate: RED.validators.typedInput("op1type")},
|
op1: {value:"1", validate: RED.validators.typedInput("op1type")},
|
||||||
op2: {value:"0", validate: RED.validators.typedInput("op2type")},
|
op2: {value:"0", validate: RED.validators.typedInput("op2type")},
|
||||||
op1type: {value:"val"},
|
op1type: {value:"val"},
|
||||||
@ -82,8 +91,9 @@
|
|||||||
extend: {value:"false"},
|
extend: {value:"false"},
|
||||||
units: {value:"ms"},
|
units: {value:"ms"},
|
||||||
reset: {value:""},
|
reset: {value:""},
|
||||||
bytopic: {value: "all"},
|
bytopic: {value:"all"},
|
||||||
name: {value:""}
|
topic: {value:"topic",required:true},
|
||||||
|
outputs: {value:1}
|
||||||
},
|
},
|
||||||
inputs:1,
|
inputs:1,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
@ -103,19 +113,48 @@
|
|||||||
return this.name?"node_label_italic":"";
|
return this.name?"node_label_italic":"";
|
||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
|
var that = this;
|
||||||
|
if (this.topic === undefined) { $("#node-input-topic").val("topic"); }
|
||||||
|
$("#node-input-topic").typedInput({default:'msg',types:['msg']});
|
||||||
|
$("#node-input-bytopic").on("change", function() {
|
||||||
|
if ($("#node-input-bytopic").val() === "all") {
|
||||||
|
$("#node-stream-topic").hide();
|
||||||
|
} else {
|
||||||
|
$("#node-stream-topic").show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.outputs == 2) { $("#node-input-second").prop('checked', true) }
|
||||||
|
else { $("#node-input-second").prop('checked', false) }
|
||||||
|
|
||||||
|
$("#node-input-second").change(function() {
|
||||||
|
if ($("#node-input-second").is(":checked")) {
|
||||||
|
$("#node-input-outputs").val(2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#node-input-outputs").val(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
$("#node-then-type").on("change", function() {
|
$("#node-then-type").on("change", function() {
|
||||||
if ($(this).val() == "block") {
|
if ($(this).val() == "block") {
|
||||||
$(".node-type-wait").hide();
|
$(".node-type-wait").hide();
|
||||||
$(".node-type-duration").hide();
|
$(".node-type-duration").hide();
|
||||||
|
$("#node-second-output").hide();
|
||||||
|
$("#node-input-second").prop('checked', false);
|
||||||
|
$("#node-input-outputs").val(1);
|
||||||
}
|
}
|
||||||
else if ($(this).val() == "loop") {
|
else if ($(this).val() == "loop") {
|
||||||
if ($("#node-input-duration").val() == 0) { $("#node-input-duration").val(250); }
|
if ($("#node-input-duration").val() == 0) { $("#node-input-duration").val(250); }
|
||||||
$(".node-type-wait").hide();
|
$(".node-type-wait").hide();
|
||||||
$(".node-type-duration").show();
|
$(".node-type-duration").show();
|
||||||
|
$("#node-second-output").hide();
|
||||||
|
$("#node-input-second").prop('checked', false);
|
||||||
|
$("#node-input-outputs").val(1);
|
||||||
} else {
|
} else {
|
||||||
if ($("#node-input-duration").val() == 0) { $("#node-input-duration").val(250); }
|
if ($("#node-input-duration").val() == 0) { $("#node-input-duration").val(250); }
|
||||||
$(".node-type-wait").show();
|
$(".node-type-wait").show();
|
||||||
$(".node-type-duration").show();
|
$(".node-type-duration").show();
|
||||||
|
$("#node-second-output").show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ module.exports = function(RED) {
|
|||||||
this.op2 = n.op2 || "0";
|
this.op2 = n.op2 || "0";
|
||||||
this.op1type = n.op1type || "str";
|
this.op1type = n.op1type || "str";
|
||||||
this.op2type = n.op2type || "str";
|
this.op2type = n.op2type || "str";
|
||||||
|
this.second = (n.outputs == 2) ? true : false;
|
||||||
|
this.topic = n.topic || "topic";
|
||||||
|
|
||||||
if (this.op1type === 'val') {
|
if (this.op1type === 'val') {
|
||||||
if (this.op1 === 'true' || this.op1 === 'false') {
|
if (this.op1 === 'true' || this.op1 === 'false') {
|
||||||
@ -111,8 +113,15 @@ module.exports = function(RED) {
|
|||||||
processMessageQueue(msg);
|
processMessageQueue(msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var stat = function() {
|
||||||
|
var l = Object.keys(node.topics).length;
|
||||||
|
if (l === 0) { return {} }
|
||||||
|
else if (l === 1) { return {fill:"blue",shape:"dot"} }
|
||||||
|
else return {fill:"blue",shape:"dot",text:l};
|
||||||
|
}
|
||||||
|
|
||||||
var processMessage = function(msg) {
|
var processMessage = function(msg) {
|
||||||
var topic = msg.topic || "_none";
|
var topic = RED.util.getMessageProperty(msg,node.topic) || "_none";
|
||||||
var promise;
|
var promise;
|
||||||
if (node.bytopic === "all") { topic = "_none"; }
|
if (node.bytopic === "all") { topic = "_none"; }
|
||||||
node.topics[topic] = node.topics[topic] || {};
|
node.topics[topic] = node.topics[topic] || {};
|
||||||
@ -120,7 +129,7 @@ module.exports = function(RED) {
|
|||||||
if (node.loop === true) { clearInterval(node.topics[topic].tout); }
|
if (node.loop === true) { clearInterval(node.topics[topic].tout); }
|
||||||
else { clearTimeout(node.topics[topic].tout); }
|
else { clearTimeout(node.topics[topic].tout); }
|
||||||
delete node.topics[topic];
|
delete node.topics[topic];
|
||||||
node.status({});
|
node.status(stat());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (node.op2type === "payl") { npay[topic] = RED.util.cloneMessage(msg); }
|
if (node.op2type === "payl") { npay[topic] = RED.util.cloneMessage(msg); }
|
||||||
@ -189,27 +198,29 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
promise.then(() => {
|
promise.then(() => {
|
||||||
if (node.op2type === "payl") {
|
if (node.op2type === "payl") {
|
||||||
node.send(npay[topic]);
|
if (node.second === true) { node.send([null,npay[topic]]); }
|
||||||
|
else { node.send(npay[topic]); }
|
||||||
delete npay[topic];
|
delete npay[topic];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg2.payload = node.topics[topic].m2;
|
msg2.payload = node.topics[topic].m2;
|
||||||
node.send(msg2);
|
if (node.second === true) { node.send([null,msg2]); }
|
||||||
|
else { node.send(msg2); }
|
||||||
}
|
}
|
||||||
delete node.topics[topic];
|
delete node.topics[topic];
|
||||||
node.status({});
|
node.status(stat());
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
node.error(err);
|
node.error(err);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
delete node.topics[topic];
|
delete node.topics[topic];
|
||||||
node.status({});
|
node.status(stat());
|
||||||
}
|
}
|
||||||
|
|
||||||
}, node.duration);
|
}, node.duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.status({fill:"blue",shape:"dot",text:" "});
|
node.status(stat());
|
||||||
if (node.op1type !== "nul") { node.send(RED.util.cloneMessage(msg)); }
|
if (node.op1type !== "nul") { node.send(RED.util.cloneMessage(msg)); }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -245,13 +256,17 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete node.topics[topic];
|
delete node.topics[topic];
|
||||||
node.status({});
|
node.status(stat());
|
||||||
node.send(msg2);
|
if (node.second === true) { node.send([null,msg2]); }
|
||||||
|
else { node.send(msg2); }
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
node.error(err);
|
node.error(err);
|
||||||
});
|
});
|
||||||
}, node.duration);
|
}, node.duration);
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// if (node.op2type === "payl") {node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
@ -264,7 +279,7 @@ module.exports = function(RED) {
|
|||||||
delete node.topics[t];
|
delete node.topics[t];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.status({});
|
node.status(stat());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
RED.nodes.registerType("trigger",TriggerNode);
|
RED.nodes.registerType("trigger",TriggerNode);
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<script type="text/x-red" data-template-name="exec">
|
<script type="text/html" data-template-name="exec">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-command"><i class="fa fa-file"></i> <span data-i18n="exec.label.command"></span></label>
|
<label for="node-input-command"><i class="fa fa-file"></i> <span data-i18n="exec.label.command"></span></label>
|
||||||
<input type="text" id="node-input-command" data-i18n="[placeholder]exec.label.command">
|
<input type="text" id="node-input-command" data-i18n="[placeholder]exec.label.command">
|
||||||
@ -70,7 +70,7 @@
|
|||||||
},
|
},
|
||||||
icon: "cog.svg",
|
icon: "cog.svg",
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.name||this.command||(this.useSpawn=="true"?this._("exec.spawn"):this._("exec.exec"));
|
return this.name||this.command.replace(/\\n /g,"\\\\n ")||(this.useSpawn=="true"?this._("exec.spawn"):this._("exec.exec"));
|
||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
return this.name?"node_label_italic":"";
|
return this.name?"node_label_italic":"";
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<script type="text/x-red" data-template-name="tls-config">
|
<script type="text/html" data-template-name="tls-config">
|
||||||
<div class="form-row" class="hide" id="node-config-row-uselocalfiles">
|
<div class="form-row" class="hide" id="node-config-row-uselocalfiles">
|
||||||
<input type="checkbox" id="node-config-input-uselocalfiles" style="display: inline-block; width: auto; vertical-align: top;">
|
<input type="checkbox" id="node-config-input-uselocalfiles" style="display: inline-block; width: auto; vertical-align: top;">
|
||||||
<label for="node-config-input-uselocalfiles" style="width: 70%;"><span data-i18n="tls.label.use-local-files"></label>
|
<label for="node-config-input-uselocalfiles" style="width: 70%;"><span data-i18n="tls.label.use-local-files"></label>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user